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