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 = ¶ms[0].memref.size;
359 uint8_t *n = params[1].memref.buffer;
360 uint32_t *n_out_sz = ¶ms[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