xref: /optee_os/core/pta/attestation.c (revision 62e37796669c676f90536c2dca597410df4536c2)
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 out:
199 	return res;
200 }
201 
202 static TEE_Result sec_storage_obj_read(TEE_UUID *uuid, uint32_t storage_id,
203 				       const uint8_t *obj_id,
204 				       size_t obj_id_len,
205 				       uint8_t *data, size_t *len,
206 				       size_t offset, uint32_t flags)
207 {
208 	const struct tee_file_operations *fops = NULL;
209 	TEE_Result res = TEE_ERROR_BAD_STATE;
210 	struct tee_file_handle *fh = NULL;
211 	struct tee_pobj *po = NULL;
212 	size_t file_size = 0;
213 	size_t read_len = 0;
214 
215 	fops = tee_svc_storage_file_ops(storage_id);
216 	if (!fops)
217 		return TEE_ERROR_NOT_IMPLEMENTED;
218 
219 	if (obj_id_len > TEE_OBJECT_ID_MAX_LEN)
220 		return TEE_ERROR_BAD_PARAMETERS;
221 
222 	res = tee_pobj_get(uuid, (void *)obj_id, obj_id_len, flags, false, fops,
223 			   &po);
224 	if (res)
225 		return res;
226 
227 	res = po->fops->open(po, &file_size, &fh);
228 	if (res)
229 		goto out;
230 
231 	read_len = *len;
232 	res = po->fops->read(fh, offset, data, &read_len);
233 	if (res == TEE_ERROR_CORRUPT_OBJECT) {
234 		EMSG("Object corrupt");
235 		po->fops->remove(po);
236 	} else if (!res) {
237 		*len = read_len;
238 	}
239 
240 	po->fops->close(&fh);
241 out:
242 	tee_pobj_release(po);
243 
244 	return res;
245 }
246 
247 static TEE_Result sec_storage_obj_write(TEE_UUID *uuid, uint32_t storage_id,
248 					const uint8_t *obj_id,
249 					size_t obj_id_len,
250 					const uint8_t *data, size_t len,
251 					size_t offset, uint32_t flags)
252 
253 {
254 	const struct tee_file_operations *fops = NULL;
255 	struct tee_file_handle *fh = NULL;
256 	TEE_Result res = TEE_SUCCESS;
257 	struct tee_pobj *po = NULL;
258 
259 	fops = tee_svc_storage_file_ops(storage_id);
260 	if (!fops)
261 		return TEE_ERROR_NOT_IMPLEMENTED;
262 
263 	if (obj_id_len > TEE_OBJECT_ID_MAX_LEN)
264 		return TEE_ERROR_BAD_PARAMETERS;
265 
266 	res = tee_pobj_get(uuid, (void *)obj_id, obj_id_len, flags, false,
267 			   fops, &po);
268 	if (res)
269 		return res;
270 
271 	res = po->fops->open(po, NULL, &fh);
272 	if (res == TEE_ERROR_ITEM_NOT_FOUND)
273 		res = po->fops->create(po, false, NULL, 0, NULL, 0, NULL, 0,
274 				       &fh);
275 	if (!res) {
276 		res = po->fops->write(fh, offset, data, len);
277 		po->fops->close(&fh);
278 	}
279 
280 	tee_pobj_release(po);
281 
282 	return res;
283 }
284 
285 static TEE_Result load_key(uint8_t *buf, size_t size)
286 {
287 	TEE_Result res = TEE_ERROR_GENERIC;
288 
289 	DMSG("Loading RSA key pair from secure storage");
290 	res = sec_storage_obj_read(&pta_uuid, TEE_STORAGE_PRIVATE,
291 				   key_file_name, sizeof(key_file_name) - 1,
292 				   buf, &size, 0, TEE_DATA_FLAG_ACCESS_READ);
293 	if (res)
294 		return res;
295 	DMSG("Read %zu bytes", size);
296 	res = deserialize_key(buf, size);
297 	if (!res)
298 		DMSG("Loaded %zu bit key pair", crypto_bignum_num_bits(key->n));
299 
300 	return res;
301 }
302 
303 static TEE_Result write_key(uint8_t *buf, size_t size)
304 {
305 	TEE_Result res = TEE_ERROR_GENERIC;
306 
307 	DMSG("Saving key pair");
308 	res = serialize_key(buf, size);
309 	if (res)
310 		return res;
311 
312 	res = sec_storage_obj_write(&pta_uuid, TEE_STORAGE_PRIVATE,
313 				    key_file_name, sizeof(key_file_name) - 1,
314 				    buf, size, 0, TEE_DATA_FLAG_ACCESS_WRITE);
315 	if (!res)
316 		DMSG("Wrote %zu bytes", size);
317 	return res;
318 }
319 
320 static TEE_Result init_key(void)
321 {
322 	TEE_Result res = TEE_SUCCESS;
323 	uint8_t *buf = NULL;
324 	size_t size = 0;
325 
326 	if (!key) {
327 		/*
328 		 * e is 65537 so its bignum size is 3 bytes. d and n can be up
329 		 * to MAX_KEY_SIZE bits.
330 		 */
331 		size = bufsize(3, MAX_KEY_SIZE / 8, MAX_KEY_SIZE / 8);
332 		buf = calloc(1, size);
333 		if (!buf) {
334 			res = TEE_ERROR_OUT_OF_MEMORY;
335 			goto out;
336 		}
337 		res = load_key(buf, size);
338 		if (res == TEE_ERROR_ITEM_NOT_FOUND) {
339 			res = generate_key();
340 			if (res)
341 				goto out;
342 			res = write_key(buf, size);
343 		}
344 	}
345 out:
346 	free(buf);
347 	return res;
348 }
349 
350 static TEE_Result cmd_get_pubkey(uint32_t param_types,
351 				 TEE_Param params[TEE_NUM_PARAMS])
352 {
353 	TEE_Result res = TEE_ERROR_GENERIC;
354 	uint8_t *e = params[0].memref.buffer;
355 	uint32_t *e_out_sz = &params[0].memref.size;
356 	uint8_t *n = params[1].memref.buffer;
357 	uint32_t *n_out_sz = &params[1].memref.size;
358 	size_t sz = 0;
359 
360 	if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT,
361 					   TEE_PARAM_TYPE_MEMREF_OUTPUT,
362 					   TEE_PARAM_TYPE_VALUE_OUTPUT,
363 					   TEE_PARAM_TYPE_NONE))
364 		return TEE_ERROR_BAD_PARAMETERS;
365 
366 	res = init_key();
367 	if (res)
368 		return res;
369 
370 	sz = crypto_bignum_num_bytes(key->e);
371 	if (*e_out_sz >= sz)
372 		crypto_bignum_bn2bin(key->e, e);
373 	else
374 		res = TEE_ERROR_SHORT_BUFFER;
375 	*e_out_sz = sz;
376 
377 	sz = crypto_bignum_num_bytes(key->n);
378 	if (*n_out_sz >= sz)
379 		crypto_bignum_bn2bin(key->n, n);
380 	else
381 		res = TEE_ERROR_SHORT_BUFFER;
382 	*n_out_sz = sz;
383 
384 	params[2].value.a = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256;
385 
386 	return res;
387 }
388 
389 static TEE_Result hash_binary(const TEE_UUID *uuid, uint8_t *hash)
390 {
391 	TEE_Result res = TEE_ERROR_ITEM_NOT_FOUND;
392 	unsigned int tag_len = FILE_TAG_SIZE;
393 	const struct ts_store_ops *ops = NULL;
394 	struct ts_store_handle *h = NULL;
395 
396 	SCATTERED_ARRAY_FOREACH(ops, ta_stores, struct ts_store_ops) {
397 		res = ops->open(uuid, &h);
398 		if (!res)
399 			break;  /* TA found */
400 	}
401 	if (res)
402 		return res;
403 
404 	/*
405 	 * Output hash size is assumed to be the same size as the file tag
406 	 * size which is the size of the digest in the TA shdr. If one or the
407 	 * other changes, additional hashing will be needed.
408 	 */
409 	COMPILE_TIME_ASSERT(FILE_TAG_SIZE == TEE_SHA256_HASH_SIZE);
410 	assert(ops);
411 	res = ops->get_tag(h, hash, &tag_len);
412 	if (res)
413 		goto out;
414 
415 	DMSG("TA %pUl hash:", uuid);
416 	DHEXDUMP(hash, TEE_SHA256_HASH_SIZE);
417 out:
418 	ops->close(h);
419 	return res;
420 }
421 
422 /* Hash @nonce and @hash into @digest */
423 static TEE_Result digest_nonce_and_hash(uint8_t *digest, uint8_t *nonce,
424 					size_t nonce_sz, uint8_t *hash)
425 {
426 	TEE_Result res = TEE_SUCCESS;
427 	void *ctx = NULL;
428 
429 	res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA256);
430 	if (res)
431 		return res;
432 	res = crypto_hash_init(ctx);
433 	if (res)
434 		goto out;
435 	res = crypto_hash_update(ctx, nonce, nonce_sz);
436 	if (res)
437 		goto out;
438 	res = crypto_hash_update(ctx, hash, TEE_SHA256_HASH_SIZE);
439 	if (res)
440 		goto out;
441 	res = crypto_hash_final(ctx, digest, TEE_SHA256_HASH_SIZE);
442 out:
443 	crypto_hash_free_ctx(ctx);
444 	return res;
445 }
446 
447 static TEE_Result sign_digest(uint8_t *sig, size_t sig_len,
448 			      const uint8_t *digest)
449 {
450 	return crypto_acipher_rsassa_sign(TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256,
451 					  key,
452 					  TEE_SHA256_HASH_SIZE, /* salt len */
453 					  digest, TEE_SHA256_HASH_SIZE,
454 					  sig, &sig_len);
455 }
456 
457 /*
458  * Sign the first 32 bytes contained in @buf and append signature
459  * out = [ hash | sig(sha256(nonce | hash)) ]
460  *         ^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^
461  *          32B                modulus size
462  */
463 static TEE_Result sign_buffer(uint8_t *buf, size_t buf_sz, uint8_t *nonce,
464 			      size_t nonce_sz)
465 {
466 	uint8_t digest[TEE_SHA256_HASH_SIZE] = { };
467 	TEE_Result res = TEE_SUCCESS;
468 
469 	res = digest_nonce_and_hash(digest, nonce, nonce_sz, buf);
470 	if (res)
471 		return res;
472 	return sign_digest(buf + TEE_SHA256_HASH_SIZE,
473 			   buf_sz - TEE_SHA256_HASH_SIZE, digest);
474 }
475 
476 /*
477  * Is region valid for hashing?
478  * Exclude writable regions as well as those that are not specific to the TA
479  * (ldelf, kernel or temporary mappings).
480  */
481 static bool is_region_valid(struct vm_region *r)
482 {
483 	uint32_t skip_flags = VM_FLAG_EPHEMERAL | VM_FLAG_PERMANENT |
484 			      VM_FLAG_LDELF;
485 
486 	return !(r->flags & skip_flags || r->attr & TEE_MATTR_UW);
487 }
488 
489 /*
490  * With this comparison function, we're hashing the smaller regions first.
491  * Regions of equal size are ordered based on their content (memcmp()).
492  * Identical regions can be in any order since they will yield the same hash
493  * anyways.
494  */
495 static int cmp_regions(const void *a, const void *b)
496 {
497 	const struct vm_region *r1 = *(const struct vm_region **)a;
498 	const struct vm_region *r2 = *(const struct vm_region **)b;
499 
500 	if (r1->size < r2->size)
501 		return -1;
502 
503 	if (r1->size > r2->size)
504 		return 1;
505 
506 	return memcmp((void *)r1->va, (void *)r2->va, r1->size);
507 }
508 
509 static TEE_Result hash_regions(struct vm_info *vm_info, uint8_t *hash)
510 {
511 	TEE_Result res = TEE_SUCCESS;
512 	struct vm_region *r = NULL;
513 	struct vm_region **regions = NULL;
514 	size_t nregions = 0;
515 	void *ctx = NULL;
516 	size_t i = 0;
517 
518 	res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA256);
519 	if (res)
520 		return res;
521 
522 	res = crypto_hash_init(ctx);
523 	if (res)
524 		goto out;
525 
526 	/*
527 	 * Make an array of region pointers so we can use qsort() to order it.
528 	 */
529 
530 	TAILQ_FOREACH(r, &vm_info->regions, link)
531 		if (is_region_valid(r))
532 			nregions++;
533 
534 	regions = malloc(nregions * sizeof(*regions));
535 	if (!regions) {
536 		res = TEE_ERROR_OUT_OF_MEMORY;
537 		goto out;
538 	}
539 
540 	TAILQ_FOREACH(r, &vm_info->regions, link)
541 		if (is_region_valid(r))
542 			regions[i++] = r;
543 
544 	/*
545 	 * Sort regions so that they are in a consistent order even when TA ASLR
546 	 * is enabled.
547 	 */
548 	qsort(regions, nregions, sizeof(*regions), cmp_regions);
549 
550 	/* Hash regions in order */
551 	for (i = 0; i < nregions; i++) {
552 		r = regions[i];
553 		DMSG("va %p size %zu", (void *)r->va, r->size);
554 		res = crypto_hash_update(ctx, (uint8_t *)r->va, r->size);
555 		if (res)
556 			goto out;
557 	}
558 
559 	res = crypto_hash_final(ctx, hash, TEE_SHA256_HASH_SIZE);
560 out:
561 	free(regions);
562 	crypto_hash_free_ctx(ctx);
563 	return res;
564 }
565 
566 static TEE_Result cmd_get_ta_shdr_digest(uint32_t param_types,
567 					 TEE_Param params[TEE_NUM_PARAMS])
568 {
569 	TEE_UUID *uuid = params[0].memref.buffer;
570 	size_t uuid_sz = params[0].memref.size;
571 	uint8_t *nonce = params[1].memref.buffer;
572 	size_t nonce_sz = params[1].memref.size;
573 	uint8_t *out = params[2].memref.buffer;
574 	size_t out_sz = params[2].memref.size;
575 	size_t min_out_sz = 0;
576 	TEE_Result res = TEE_SUCCESS;
577 
578 	if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
579 					   TEE_PARAM_TYPE_MEMREF_INPUT,
580 					   TEE_PARAM_TYPE_MEMREF_OUTPUT,
581 					   TEE_PARAM_TYPE_NONE))
582 		return TEE_ERROR_BAD_PARAMETERS;
583 
584 	if (uuid_sz != sizeof(*uuid))
585 		return TEE_ERROR_BAD_PARAMETERS;
586 
587 	if (!nonce || !nonce_sz)
588 		return TEE_ERROR_BAD_PARAMETERS;
589 
590 	if (!out && out_sz)
591 		return TEE_ERROR_BAD_PARAMETERS;
592 
593 	res = init_key();
594 	if (res)
595 		return res;
596 
597 	min_out_sz = TEE_SHA256_HASH_SIZE + crypto_bignum_num_bytes(key->n);
598 	params[2].memref.size = min_out_sz;
599 	if (out_sz < min_out_sz)
600 		return TEE_ERROR_SHORT_BUFFER;
601 	out_sz = min_out_sz;
602 
603 	res = hash_binary(uuid, out);
604 	if (res)
605 		return res;
606 	return sign_buffer(out, out_sz, nonce, nonce_sz);
607 }
608 
609 static TEE_Result cmd_hash_ta_memory(uint32_t param_types,
610 				     TEE_Param params[TEE_NUM_PARAMS])
611 {
612 	uint8_t *nonce = params[0].memref.buffer;
613 	size_t nonce_sz = params[0].memref.size;
614 	uint8_t *out = params[1].memref.buffer;
615 	size_t out_sz = params[1].memref.size;
616 	struct user_mode_ctx *uctx = NULL;
617 	TEE_Result res = TEE_SUCCESS;
618 	struct ts_session *s = NULL;
619 	size_t min_out_sz = 0;
620 
621 	if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
622 					   TEE_PARAM_TYPE_MEMREF_OUTPUT,
623 					   TEE_PARAM_TYPE_NONE,
624 					   TEE_PARAM_TYPE_NONE))
625 		return TEE_ERROR_BAD_PARAMETERS;
626 
627 	if (!nonce || !nonce_sz)
628 		return TEE_ERROR_BAD_PARAMETERS;
629 
630 	if (!out && out_sz)
631 		return TEE_ERROR_BAD_PARAMETERS;
632 
633 	/* Check that we're called from a user TA */
634 	s = ts_get_calling_session();
635 	if (!s)
636 		return TEE_ERROR_ACCESS_DENIED;
637 	uctx = to_user_mode_ctx(s->ctx);
638 	if (!uctx)
639 		return TEE_ERROR_ACCESS_DENIED;
640 
641 	res = init_key();
642 	if (res)
643 		return res;
644 
645 	min_out_sz = TEE_SHA256_HASH_SIZE + crypto_bignum_num_bytes(key->n);
646 	params[1].memref.size = min_out_sz;
647 	if (out_sz < min_out_sz)
648 		return TEE_ERROR_SHORT_BUFFER;
649 	out_sz = min_out_sz;
650 
651 	s = ts_pop_current_session();
652 	res = hash_regions(&uctx->vm_info, out);
653 	ts_push_current_session(s);
654 	if (res)
655 		return res;
656 
657 	return sign_buffer(out, out_sz, nonce, nonce_sz);
658 }
659 
660 static TEE_Result cmd_hash_tee_memory(uint32_t param_types,
661 				      TEE_Param params[TEE_NUM_PARAMS])
662 {
663 	uint8_t *nonce = params[0].memref.buffer;
664 	size_t nonce_sz = params[0].memref.size;
665 	uint8_t *out = params[1].memref.buffer;
666 	size_t out_sz = params[1].memref.size;
667 	TEE_Result res = TEE_SUCCESS;
668 	size_t min_out_sz = 0;
669 	void *ctx = NULL;
670 
671 	if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT,
672 					   TEE_PARAM_TYPE_MEMREF_OUTPUT,
673 					   TEE_PARAM_TYPE_NONE,
674 					   TEE_PARAM_TYPE_NONE))
675 		return TEE_ERROR_BAD_PARAMETERS;
676 
677 	if (!nonce || !nonce_sz)
678 		return TEE_ERROR_BAD_PARAMETERS;
679 
680 	if (!out && out_sz)
681 		return TEE_ERROR_BAD_PARAMETERS;
682 
683 	res = init_key();
684 	if (res)
685 		return res;
686 
687 	min_out_sz = TEE_SHA256_HASH_SIZE + crypto_bignum_num_bytes(key->n);
688 	params[1].memref.size = min_out_sz;
689 	if (out_sz < min_out_sz)
690 		return TEE_ERROR_SHORT_BUFFER;
691 	out_sz = min_out_sz;
692 
693 	res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA256);
694 	if (res)
695 		return res;
696 	res = crypto_hash_init(ctx);
697 	if (res)
698 		goto out;
699 	res = crypto_hash_update(ctx, __text_start,
700 				 __text_data_start - __text_start);
701 	if (res)
702 		goto out;
703 	res = crypto_hash_update(ctx, __text_data_end,
704 				 __text_end - __text_data_end);
705 	if (IS_ENABLED(CFG_WITH_PAGER)) {
706 		res = crypto_hash_update(ctx, __text_init_start,
707 					 __text_init_end - __text_init_start);
708 		if (res)
709 			goto out;
710 		res = crypto_hash_update(ctx, __text_pageable_start,
711 					 __text_pageable_end -
712 						__text_pageable_start);
713 		if (res)
714 			goto out;
715 	}
716 	if (res)
717 		goto out;
718 	res = crypto_hash_update(ctx, __rodata_start,
719 				 __rodata_end - __rodata_start);
720 	if (res)
721 		goto out;
722 	if (IS_ENABLED(CFG_WITH_PAGER)) {
723 		res = crypto_hash_update(ctx, __rodata_init_start,
724 					 __rodata_init_end -
725 						__rodata_init_start);
726 		if (res)
727 			goto out;
728 		res = crypto_hash_update(ctx, __rodata_pageable_start,
729 					 __rodata_pageable_end -
730 						__rodata_pageable_start);
731 		if (res)
732 			goto out;
733 	}
734 	res = crypto_hash_final(ctx, out, TEE_SHA256_HASH_SIZE);
735 	if (res)
736 		goto out;
737 
738 	DHEXDUMP(out, TEE_SHA256_HASH_SIZE);
739 
740 	res = sign_buffer(out, out_sz, nonce, nonce_sz);
741 out:
742 	crypto_hash_free_ctx(ctx);
743 	return res;
744 }
745 
746 static TEE_Result invoke_command(void *sess_ctx __unused, uint32_t cmd_id,
747 				 uint32_t param_types,
748 				 TEE_Param params[TEE_NUM_PARAMS])
749 {
750 	switch (cmd_id) {
751 	case PTA_ATTESTATION_GET_PUBKEY:
752 		return cmd_get_pubkey(param_types, params);
753 	case PTA_ATTESTATION_GET_TA_SHDR_DIGEST:
754 		return cmd_get_ta_shdr_digest(param_types, params);
755 	case PTA_ATTESTATION_HASH_TA_MEMORY:
756 		return cmd_hash_ta_memory(param_types, params);
757 	case PTA_ATTESTATION_HASH_TEE_MEMORY:
758 		return cmd_hash_tee_memory(param_types, params);
759 	default:
760 		break;
761 	}
762 	return TEE_ERROR_BAD_PARAMETERS;
763 }
764 
765 pseudo_ta_register(.uuid = PTA_ATTESTATION_UUID, .name = PTA_NAME,
766 		   .flags = PTA_DEFAULT_FLAGS,
767 		   .invoke_command_entry_point = invoke_command);
768