xref: /optee_os/core/pta/attestation.c (revision e231582fca25178ed521995577f537580ed47a41)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (C) 2021, Huawei Technologies Co., Ltd
4  */
5 
6 #include <config.h>
7 #include <crypto/crypto.h>
8 #include <kernel/linker.h>
9 #include <kernel/pseudo_ta.h>
10 #include <kernel/ts_store.h>
11 #include <kernel/user_mode_ctx.h>
12 #include <mm/file.h>
13 #include <pta_attestation.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <tee/entry_std.h>
17 #include <tee/tee_fs.h>
18 #include <tee/tee_pobj.h>
19 #include <tee/uuid.h>
20 #include <utee_defines.h>
21 
22 #define PTA_NAME "attestation.pta"
23 
24 #define MAX_KEY_SIZE 4096
25 
26 static TEE_UUID pta_uuid = PTA_ATTESTATION_UUID;
27 
28 static struct rsa_keypair *key;
29 
30 static const uint8_t key_file_name[] = "key";
31 
32 static TEE_Result allocate_key(void)
33 {
34 	assert(!key);
35 
36 	key = calloc(1, sizeof(*key));
37 	if (!key)
38 		return TEE_ERROR_OUT_OF_MEMORY;
39 
40 	COMPILE_TIME_ASSERT(CFG_ATTESTATION_PTA_KEY_SIZE <= MAX_KEY_SIZE);
41 	return crypto_acipher_alloc_rsa_keypair(key, MAX_KEY_SIZE);
42 }
43 
44 static void free_key(void)
45 {
46 	crypto_acipher_free_rsa_keypair(key);
47 	free(key);
48 	key = NULL;
49 }
50 
51 static TEE_Result generate_key(void)
52 {
53 	uint32_t e = TEE_U32_TO_BIG_ENDIAN(65537);
54 	TEE_Result res = TEE_ERROR_GENERIC;
55 
56 	res = allocate_key();
57 	if (res)
58 		return res;
59 
60 	crypto_bignum_bin2bn((uint8_t *)&e, sizeof(e), key->e);
61 
62 	/*
63 	 * For security reasons, the RSA modulus size has to be at least the
64 	 * size of the data to be signed.
65 	 */
66 	DMSG("Generating %u bit RSA key pair", CFG_ATTESTATION_PTA_KEY_SIZE);
67 	COMPILE_TIME_ASSERT(CFG_ATTESTATION_PTA_KEY_SIZE >=
68 			    TEE_SHA256_HASH_SIZE);
69 	res = crypto_acipher_gen_rsa_key(key, CFG_ATTESTATION_PTA_KEY_SIZE);
70 	if (res)
71 		free_key();
72 
73 	return res;
74 }
75 
76 /*
77  * Return values:
78  * > 0 : Number of bytes written to buf
79  *   0 : @sz too large (> UINT16_MAX) or @buf_sz too small
80  */
81 static size_t serialize_bignum(uint8_t *buf, size_t buf_sz, struct bignum *bn)
82 {
83 	uint8_t *p = buf;
84 	size_t sz = crypto_bignum_num_bytes(bn);
85 	uint16_t val = TEE_U16_TO_BIG_ENDIAN(sz);
86 	size_t total_sz = sizeof(val) + sz;
87 
88 	if (sz > UINT16_MAX || total_sz > buf_sz)
89 		return 0;
90 
91 	memcpy(p, &val, sizeof(val));
92 	p += sizeof(val);
93 
94 	crypto_bignum_bn2bin(bn, p);
95 
96 	return total_sz;
97 }
98 
99 static size_t bufsize(size_t e_sz, size_t d_sz, size_t n_sz)
100 {
101 	/*
102 	 * Serialized key pair is 3 bignums (e, p and n) plus their sizes
103 	 * encoded as uint16_t.
104 	 */
105 	return e_sz + d_sz + n_sz + 3 * sizeof(uint16_t);
106 }
107 
108 static TEE_Result serialize_key(uint8_t *buf, size_t size)
109 {
110 	TEE_Result res = TEE_ERROR_GENERIC;
111 	uint8_t *p = buf;
112 	size_t needed_sz = 0;
113 	size_t e_sz = 0;
114 	size_t d_sz = 0;
115 	size_t n_sz = 0;
116 	size_t sz = 0;
117 
118 	assert(key);
119 
120 	e_sz = crypto_bignum_num_bytes(key->e);
121 	d_sz = crypto_bignum_num_bytes(key->d);
122 	n_sz = crypto_bignum_num_bytes(key->n);
123 	if (e_sz > UINT16_MAX || d_sz > UINT16_MAX || n_sz > UINT16_MAX)
124 		goto err;
125 
126 	needed_sz = bufsize(e_sz, d_sz, n_sz);
127 	if (size < needed_sz)
128 		goto err;
129 
130 	sz = serialize_bignum(p, needed_sz, key->e);
131 	if (!sz)
132 		goto err;
133 	p += sz;
134 	needed_sz -= sz;
135 	sz = serialize_bignum(p, needed_sz, key->d);
136 	if (!sz)
137 		goto err;
138 	p += sz;
139 	needed_sz -= sz;
140 	sz = serialize_bignum(p, needed_sz, key->n);
141 	if (!sz)
142 		goto err;
143 	needed_sz -= sz;
144 	assert(!needed_sz);
145 
146 	return TEE_SUCCESS;
147 err:
148 	return res;
149 }
150 
151 static size_t deserialize_bignum(uint8_t *buf, size_t max_sz, struct bignum *bn)
152 {
153 	TEE_Result res = TEE_ERROR_GENERIC;
154 	uint8_t *p = buf;
155 	uint16_t val = 0;
156 	size_t sz = 0;
157 
158 	if (max_sz < sizeof(val))
159 		return 0;
160 
161 	memcpy(&val, p, sizeof(val));
162 	sz = TEE_U16_FROM_BIG_ENDIAN(val);
163 	p += sizeof(val);
164 	max_sz -= sizeof(val);
165 	if (max_sz < sz)
166 		return 0;
167 
168 	res = crypto_bignum_bin2bn(p, sz, bn);
169 	if (res)
170 		return 0;
171 
172 	return sizeof(val) + sz;
173 }
174 
175 static TEE_Result deserialize_key(uint8_t *buf, size_t buf_sz)
176 {
177 	TEE_Result res = TEE_ERROR_GENERIC;
178 	uint8_t *p = buf;
179 	size_t sz = 0;
180 
181 	res = allocate_key();
182 	if (res)
183 		goto out;
184 
185 	sz = deserialize_bignum(p, buf_sz, key->e);
186 	if (!sz)
187 		goto out;
188 	p += sz;
189 	buf_sz -= sz;
190 	sz = deserialize_bignum(p, buf_sz, key->d);
191 	if (!sz)
192 		goto out;
193 	p += sz;
194 	buf_sz -= sz;
195 	sz = deserialize_bignum(p, buf_sz, key->n);
196 	if (!sz)
197 		goto out;
198 	buf_sz -= sz;
199 	assert(!buf_sz);
200 out:
201 	return res;
202 }
203 
204 static TEE_Result sec_storage_obj_read(TEE_UUID *uuid, uint32_t storage_id,
205 				       const uint8_t *obj_id,
206 				       size_t obj_id_len,
207 				       uint8_t *data, size_t *len,
208 				       size_t offset, uint32_t flags)
209 {
210 	const struct tee_file_operations *fops = NULL;
211 	TEE_Result res = TEE_ERROR_BAD_STATE;
212 	struct tee_file_handle *fh = NULL;
213 	struct tee_pobj *po = NULL;
214 	size_t file_size = 0;
215 	size_t read_len = 0;
216 
217 	fops = tee_svc_storage_file_ops(storage_id);
218 	if (!fops)
219 		return TEE_ERROR_NOT_IMPLEMENTED;
220 
221 	if (obj_id_len > TEE_OBJECT_ID_MAX_LEN)
222 		return TEE_ERROR_BAD_PARAMETERS;
223 
224 	res = tee_pobj_get(uuid, (void *)obj_id, obj_id_len, flags, false, fops,
225 			   &po);
226 	if (res)
227 		return res;
228 
229 	res = po->fops->open(po, &file_size, &fh);
230 	if (res)
231 		goto out;
232 
233 	read_len = *len;
234 	res = po->fops->read(fh, offset, data, &read_len);
235 	if (res == TEE_ERROR_CORRUPT_OBJECT) {
236 		EMSG("Object corrupt");
237 		po->fops->remove(po);
238 	} else if (!res) {
239 		*len = read_len;
240 	}
241 
242 	po->fops->close(&fh);
243 out:
244 	tee_pobj_release(po);
245 
246 	return res;
247 }
248 
249 static TEE_Result sec_storage_obj_write(TEE_UUID *uuid, uint32_t storage_id,
250 					const uint8_t *obj_id,
251 					size_t obj_id_len,
252 					const uint8_t *data, size_t len,
253 					size_t offset, uint32_t flags)
254 
255 {
256 	const struct tee_file_operations *fops = NULL;
257 	struct tee_file_handle *fh = NULL;
258 	TEE_Result res = TEE_SUCCESS;
259 	struct tee_pobj *po = NULL;
260 
261 	fops = tee_svc_storage_file_ops(storage_id);
262 	if (!fops)
263 		return TEE_ERROR_NOT_IMPLEMENTED;
264 
265 	if (obj_id_len > TEE_OBJECT_ID_MAX_LEN)
266 		return TEE_ERROR_BAD_PARAMETERS;
267 
268 	res = tee_pobj_get(uuid, (void *)obj_id, obj_id_len, flags, false,
269 			   fops, &po);
270 	if (res)
271 		return res;
272 
273 	res = po->fops->open(po, NULL, &fh);
274 	if (res == TEE_ERROR_ITEM_NOT_FOUND)
275 		res = po->fops->create(po, false, NULL, 0, NULL, 0, NULL, 0,
276 				       &fh);
277 	if (!res) {
278 		res = po->fops->write(fh, offset, data, len);
279 		po->fops->close(&fh);
280 	}
281 
282 	tee_pobj_release(po);
283 
284 	return res;
285 }
286 
287 static TEE_Result load_key(uint8_t *buf, size_t size)
288 {
289 	TEE_Result res = TEE_ERROR_GENERIC;
290 
291 	DMSG("Loading RSA key pair from secure storage");
292 	res = sec_storage_obj_read(&pta_uuid, TEE_STORAGE_PRIVATE,
293 				   key_file_name, sizeof(key_file_name) - 1,
294 				   buf, &size, 0, TEE_DATA_FLAG_ACCESS_READ);
295 	if (res)
296 		return res;
297 	DMSG("Read %zu bytes", size);
298 	res = deserialize_key(buf, size);
299 	if (!res)
300 		DMSG("Loaded %zu bit key pair", crypto_bignum_num_bits(key->n));
301 
302 	return res;
303 }
304 
305 static TEE_Result write_key(uint8_t *buf, size_t size)
306 {
307 	TEE_Result res = TEE_ERROR_GENERIC;
308 
309 	DMSG("Saving key pair");
310 	res = serialize_key(buf, size);
311 	if (res)
312 		return res;
313 
314 	res = sec_storage_obj_write(&pta_uuid, TEE_STORAGE_PRIVATE,
315 				    key_file_name, sizeof(key_file_name) - 1,
316 				    buf, size, 0, TEE_DATA_FLAG_ACCESS_WRITE);
317 	if (!res)
318 		DMSG("Wrote %zu bytes", size);
319 	return res;
320 }
321 
322 static TEE_Result init_key(void)
323 {
324 	TEE_Result res = TEE_SUCCESS;
325 	uint8_t *buf = NULL;
326 	size_t size = 0;
327 
328 	if (!key) {
329 		/*
330 		 * e is 65537 so its bignum size is 3 bytes. d and n can be up
331 		 * to MAX_KEY_SIZE bits.
332 		 */
333 		size = bufsize(3, MAX_KEY_SIZE / 8, MAX_KEY_SIZE / 8);
334 		buf = calloc(1, size);
335 		if (!buf) {
336 			res = TEE_ERROR_OUT_OF_MEMORY;
337 			goto out;
338 		}
339 		res = load_key(buf, size);
340 		if (res == TEE_ERROR_ITEM_NOT_FOUND) {
341 			res = generate_key();
342 			if (res)
343 				goto out;
344 			res = write_key(buf, size);
345 		}
346 	}
347 out:
348 	free(buf);
349 	return res;
350 }
351 
352 static TEE_Result cmd_get_pubkey(uint32_t param_types,
353 				 TEE_Param params[TEE_NUM_PARAMS])
354 {
355 	TEE_Result res = TEE_ERROR_GENERIC;
356 	uint8_t *e = params[0].memref.buffer;
357 	uint32_t *e_out_sz = &params[0].memref.size;
358 	uint8_t *n = params[1].memref.buffer;
359 	uint32_t *n_out_sz = &params[1].memref.size;
360 	size_t sz = 0;
361 
362 	if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT,
363 					   TEE_PARAM_TYPE_MEMREF_OUTPUT,
364 					   TEE_PARAM_TYPE_VALUE_OUTPUT,
365 					   TEE_PARAM_TYPE_NONE))
366 		return TEE_ERROR_BAD_PARAMETERS;
367 
368 	res = init_key();
369 	if (res)
370 		return res;
371 
372 	sz = crypto_bignum_num_bytes(key->e);
373 	if (*e_out_sz >= sz)
374 		crypto_bignum_bn2bin(key->e, e);
375 	else
376 		res = TEE_ERROR_SHORT_BUFFER;
377 	*e_out_sz = sz;
378 
379 	sz = crypto_bignum_num_bytes(key->n);
380 	if (*n_out_sz >= sz)
381 		crypto_bignum_bn2bin(key->n, n);
382 	else
383 		res = TEE_ERROR_SHORT_BUFFER;
384 	*n_out_sz = sz;
385 
386 	params[2].value.a = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256;
387 
388 	return res;
389 }
390 
391 static TEE_Result hash_binary(const TEE_UUID *uuid, uint8_t *hash)
392 {
393 	TEE_Result res = TEE_ERROR_ITEM_NOT_FOUND;
394 	unsigned int tag_len = FILE_TAG_SIZE;
395 	const struct ts_store_ops *ops = NULL;
396 	struct ts_store_handle *h = NULL;
397 
398 	SCATTERED_ARRAY_FOREACH(ops, ta_stores, struct ts_store_ops) {
399 		res = ops->open(uuid, &h);
400 		if (!res)
401 			break;  /* TA found */
402 	}
403 	if (res)
404 		return res;
405 
406 	/*
407 	 * Output hash size is assumed to be the same size as the file tag
408 	 * size which is the size of the digest in the TA shdr. If one or the
409 	 * other changes, additional hashing will be needed.
410 	 */
411 	COMPILE_TIME_ASSERT(FILE_TAG_SIZE == TEE_SHA256_HASH_SIZE);
412 	assert(ops);
413 	res = ops->get_tag(h, hash, &tag_len);
414 	if (res)
415 		goto out;
416 
417 	DMSG("TA %pUl hash:", uuid);
418 	DHEXDUMP(hash, TEE_SHA256_HASH_SIZE);
419 out:
420 	ops->close(h);
421 	return res;
422 }
423 
424 /* Hash @nonce and @hash into @digest */
425 static TEE_Result digest_nonce_and_hash(uint8_t *digest, uint8_t *nonce,
426 					size_t nonce_sz, uint8_t *hash)
427 {
428 	TEE_Result res = TEE_SUCCESS;
429 	void *ctx = NULL;
430 
431 	res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA256);
432 	if (res)
433 		return res;
434 	res = crypto_hash_init(ctx);
435 	if (res)
436 		goto out;
437 	res = crypto_hash_update(ctx, nonce, nonce_sz);
438 	if (res)
439 		goto out;
440 	res = crypto_hash_update(ctx, hash, TEE_SHA256_HASH_SIZE);
441 	if (res)
442 		goto out;
443 	res = crypto_hash_final(ctx, digest, TEE_SHA256_HASH_SIZE);
444 out:
445 	crypto_hash_free_ctx(ctx);
446 	return res;
447 }
448 
449 static TEE_Result sign_digest(uint8_t *sig, size_t sig_len,
450 			      const uint8_t *digest)
451 {
452 	return crypto_acipher_rsassa_sign(TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256,
453 					  key,
454 					  TEE_SHA256_HASH_SIZE, /* salt len */
455 					  digest, TEE_SHA256_HASH_SIZE,
456 					  sig, &sig_len);
457 }
458 
459 /*
460  * Sign the first 32 bytes contained in @buf and append signature
461  * out = [ hash | sig(sha256(nonce | hash)) ]
462  *         ^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^
463  *          32B                modulus size
464  */
465 static TEE_Result sign_buffer(uint8_t *buf, size_t buf_sz, uint8_t *nonce,
466 			      size_t nonce_sz)
467 {
468 	uint8_t digest[TEE_SHA256_HASH_SIZE] = { };
469 	TEE_Result res = TEE_SUCCESS;
470 
471 	res = digest_nonce_and_hash(digest, nonce, nonce_sz, buf);
472 	if (res)
473 		return res;
474 	return sign_digest(buf + TEE_SHA256_HASH_SIZE,
475 			   buf_sz - TEE_SHA256_HASH_SIZE, digest);
476 }
477 
478 /*
479  * Is region valid for hashing?
480  * Exclude writable regions as well as those that are not specific to the TA
481  * (ldelf, kernel or temporary mappings).
482  */
483 static bool is_region_valid(struct vm_region *r)
484 {
485 	uint32_t skip_flags = VM_FLAG_EPHEMERAL | VM_FLAG_PERMANENT |
486 			      VM_FLAG_LDELF;
487 
488 	return !(r->flags & skip_flags || r->attr & TEE_MATTR_UW);
489 }
490 
491 /*
492  * With this comparison function, we're hashing the smaller regions first.
493  * Regions of equal size are ordered based on their content (memcmp()).
494  * Identical regions can be in any order since they will yield the same hash
495  * anyways.
496  */
497 static int cmp_regions(const void *a, const void *b)
498 {
499 	const struct vm_region *r1 = *(const struct vm_region **)a;
500 	const struct vm_region *r2 = *(const struct vm_region **)b;
501 
502 	if (r1->size < r2->size)
503 		return -1;
504 
505 	if (r1->size > r2->size)
506 		return 1;
507 
508 	return memcmp((void *)r1->va, (void *)r2->va, r1->size);
509 }
510 
511 static TEE_Result hash_regions(struct vm_info *vm_info, uint8_t *hash)
512 {
513 	TEE_Result res = TEE_SUCCESS;
514 	struct vm_region *r = NULL;
515 	struct vm_region **regions = NULL;
516 	size_t nregions = 0;
517 	void *ctx = NULL;
518 	size_t i = 0;
519 
520 	res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA256);
521 	if (res)
522 		return res;
523 
524 	res = crypto_hash_init(ctx);
525 	if (res)
526 		goto out;
527 
528 	/*
529 	 * Make an array of region pointers so we can use qsort() to order it.
530 	 */
531 
532 	TAILQ_FOREACH(r, &vm_info->regions, link)
533 		if (is_region_valid(r))
534 			nregions++;
535 
536 	regions = malloc(nregions * sizeof(*regions));
537 	if (!regions) {
538 		res = TEE_ERROR_OUT_OF_MEMORY;
539 		goto out;
540 	}
541 
542 	TAILQ_FOREACH(r, &vm_info->regions, link)
543 		if (is_region_valid(r))
544 			regions[i++] = r;
545 
546 	/*
547 	 * Sort regions so that they are in a consistent order even when TA ASLR
548 	 * is enabled.
549 	 */
550 	qsort(regions, nregions, sizeof(*regions), cmp_regions);
551 
552 	/* Hash regions in order */
553 	for (i = 0; i < nregions; i++) {
554 		r = regions[i];
555 		DMSG("va %p size %zu", (void *)r->va, r->size);
556 		res = crypto_hash_update(ctx, (uint8_t *)r->va, r->size);
557 		if (res)
558 			goto out;
559 	}
560 
561 	res = crypto_hash_final(ctx, hash, TEE_SHA256_HASH_SIZE);
562 out:
563 	free(regions);
564 	crypto_hash_free_ctx(ctx);
565 	return res;
566 }
567 
568 static TEE_Result cmd_get_ta_shdr_digest(uint32_t param_types,
569 					 TEE_Param params[TEE_NUM_PARAMS])
570 {
571 	TEE_UUID *uuid = params[0].memref.buffer;
572 	size_t uuid_sz = params[0].memref.size;
573 	uint8_t *nonce = params[1].memref.buffer;
574 	size_t nonce_sz = params[1].memref.size;
575 	uint8_t *out = params[2].memref.buffer;
576 	size_t out_sz = params[2].memref.size;
577 	size_t min_out_sz = 0;
578 	TEE_Result res = TEE_SUCCESS;
579 
580 	if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
581 					   TEE_PARAM_TYPE_MEMREF_INPUT,
582 					   TEE_PARAM_TYPE_MEMREF_OUTPUT,
583 					   TEE_PARAM_TYPE_NONE))
584 		return TEE_ERROR_BAD_PARAMETERS;
585 
586 	if (uuid_sz != sizeof(*uuid))
587 		return TEE_ERROR_BAD_PARAMETERS;
588 
589 	if (!nonce || !nonce_sz)
590 		return TEE_ERROR_BAD_PARAMETERS;
591 
592 	if (!out && out_sz)
593 		return TEE_ERROR_BAD_PARAMETERS;
594 
595 	res = init_key();
596 	if (res)
597 		return res;
598 
599 	min_out_sz = TEE_SHA256_HASH_SIZE + crypto_bignum_num_bytes(key->n);
600 	params[2].memref.size = min_out_sz;
601 	if (out_sz < min_out_sz)
602 		return TEE_ERROR_SHORT_BUFFER;
603 	out_sz = min_out_sz;
604 
605 	res = hash_binary(uuid, out);
606 	if (res)
607 		return res;
608 	return sign_buffer(out, out_sz, nonce, nonce_sz);
609 }
610 
611 static TEE_Result cmd_hash_ta_memory(uint32_t param_types,
612 				     TEE_Param params[TEE_NUM_PARAMS])
613 {
614 	uint8_t *nonce = params[0].memref.buffer;
615 	size_t nonce_sz = params[0].memref.size;
616 	uint8_t *out = params[1].memref.buffer;
617 	size_t out_sz = params[1].memref.size;
618 	struct user_mode_ctx *uctx = NULL;
619 	TEE_Result res = TEE_SUCCESS;
620 	struct ts_session *s = NULL;
621 	size_t min_out_sz = 0;
622 
623 	if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
624 					   TEE_PARAM_TYPE_MEMREF_OUTPUT,
625 					   TEE_PARAM_TYPE_NONE,
626 					   TEE_PARAM_TYPE_NONE))
627 		return TEE_ERROR_BAD_PARAMETERS;
628 
629 	if (!nonce || !nonce_sz)
630 		return TEE_ERROR_BAD_PARAMETERS;
631 
632 	if (!out && out_sz)
633 		return TEE_ERROR_BAD_PARAMETERS;
634 
635 	/* Check that we're called from a user TA */
636 	s = ts_get_calling_session();
637 	if (!s)
638 		return TEE_ERROR_ACCESS_DENIED;
639 	uctx = to_user_mode_ctx(s->ctx);
640 	if (!uctx)
641 		return TEE_ERROR_ACCESS_DENIED;
642 
643 	res = init_key();
644 	if (res)
645 		return res;
646 
647 	min_out_sz = TEE_SHA256_HASH_SIZE + crypto_bignum_num_bytes(key->n);
648 	params[1].memref.size = min_out_sz;
649 	if (out_sz < min_out_sz)
650 		return TEE_ERROR_SHORT_BUFFER;
651 	out_sz = min_out_sz;
652 
653 	s = ts_pop_current_session();
654 	res = hash_regions(&uctx->vm_info, out);
655 	ts_push_current_session(s);
656 	if (res)
657 		return res;
658 
659 	return sign_buffer(out, out_sz, nonce, nonce_sz);
660 }
661 
662 static TEE_Result cmd_hash_tee_memory(uint32_t param_types,
663 				      TEE_Param params[TEE_NUM_PARAMS])
664 {
665 	uint8_t *nonce = params[0].memref.buffer;
666 	size_t nonce_sz = params[0].memref.size;
667 	uint8_t *out = params[1].memref.buffer;
668 	size_t out_sz = params[1].memref.size;
669 	TEE_Result res = TEE_SUCCESS;
670 	size_t min_out_sz = 0;
671 	void *ctx = NULL;
672 
673 	if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
674 					   TEE_PARAM_TYPE_MEMREF_OUTPUT,
675 					   TEE_PARAM_TYPE_NONE,
676 					   TEE_PARAM_TYPE_NONE))
677 		return TEE_ERROR_BAD_PARAMETERS;
678 
679 	if (!nonce || !nonce_sz)
680 		return TEE_ERROR_BAD_PARAMETERS;
681 
682 	if (!out && out_sz)
683 		return TEE_ERROR_BAD_PARAMETERS;
684 
685 	res = init_key();
686 	if (res)
687 		return res;
688 
689 	min_out_sz = TEE_SHA256_HASH_SIZE + crypto_bignum_num_bytes(key->n);
690 	params[1].memref.size = min_out_sz;
691 	if (out_sz < min_out_sz)
692 		return TEE_ERROR_SHORT_BUFFER;
693 	out_sz = min_out_sz;
694 
695 	res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA256);
696 	if (res)
697 		return res;
698 	res = crypto_hash_init(ctx);
699 	if (res)
700 		goto out;
701 	res = crypto_hash_update(ctx, __text_start,
702 				 __text_data_start - __text_start);
703 	if (res)
704 		goto out;
705 	res = crypto_hash_update(ctx, __text_data_end,
706 				 __text_end - __text_data_end);
707 	if (IS_ENABLED(CFG_WITH_PAGER)) {
708 		res = crypto_hash_update(ctx, __text_init_start,
709 					 __text_init_end - __text_init_start);
710 		if (res)
711 			goto out;
712 		res = crypto_hash_update(ctx, __text_pageable_start,
713 					 __text_pageable_end -
714 						__text_pageable_start);
715 		if (res)
716 			goto out;
717 	}
718 	if (res)
719 		goto out;
720 	res = crypto_hash_update(ctx, __rodata_start,
721 				 __rodata_end - __rodata_start);
722 	if (res)
723 		goto out;
724 	if (IS_ENABLED(CFG_WITH_PAGER)) {
725 		res = crypto_hash_update(ctx, __rodata_init_start,
726 					 __rodata_init_end -
727 						__rodata_init_start);
728 		if (res)
729 			goto out;
730 		res = crypto_hash_update(ctx, __rodata_pageable_start,
731 					 __rodata_pageable_end -
732 						__rodata_pageable_start);
733 		if (res)
734 			goto out;
735 	}
736 	res = crypto_hash_final(ctx, out, TEE_SHA256_HASH_SIZE);
737 	if (res)
738 		goto out;
739 
740 	DHEXDUMP(out, TEE_SHA256_HASH_SIZE);
741 
742 	res = sign_buffer(out, out_sz, nonce, nonce_sz);
743 out:
744 	crypto_hash_free_ctx(ctx);
745 	return res;
746 }
747 
748 static TEE_Result invoke_command(void *sess_ctx __unused, uint32_t cmd_id,
749 				 uint32_t param_types,
750 				 TEE_Param params[TEE_NUM_PARAMS])
751 {
752 	switch (cmd_id) {
753 	case PTA_ATTESTATION_GET_PUBKEY:
754 		return cmd_get_pubkey(param_types, params);
755 	case PTA_ATTESTATION_GET_TA_SHDR_DIGEST:
756 		return cmd_get_ta_shdr_digest(param_types, params);
757 	case PTA_ATTESTATION_HASH_TA_MEMORY:
758 		return cmd_hash_ta_memory(param_types, params);
759 	case PTA_ATTESTATION_HASH_TEE_MEMORY:
760 		return cmd_hash_tee_memory(param_types, params);
761 	default:
762 		break;
763 	}
764 	return TEE_ERROR_BAD_PARAMETERS;
765 }
766 
767 pseudo_ta_register(.uuid = PTA_ATTESTATION_UUID, .name = PTA_NAME,
768 		   .flags = PTA_DEFAULT_FLAGS,
769 		   .invoke_command_entry_point = invoke_command);
770