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 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 45 static void free_key(void) 46 { 47 crypto_acipher_free_rsa_keypair(key); 48 free(key); 49 key = NULL; 50 } 51 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 */ 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 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 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 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 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 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, false, fops, 232 &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 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, false, 276 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 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 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 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 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 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 */ 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 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 */ 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 */ 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 */ 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 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 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 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 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 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