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