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