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