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 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 44 static void free_key(void) 45 { 46 crypto_acipher_free_rsa_keypair(key); 47 free(key); 48 key = NULL; 49 } 50 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 */ 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 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 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 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 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 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, NULL, &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 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, 277 NULL, NULL, 0, &fh); 278 if (!res) { 279 res = po->fops->write(fh, offset, data, NULL, len); 280 po->fops->close(&fh); 281 } 282 283 tee_pobj_release(po); 284 285 return res; 286 } 287 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 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 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 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 size_t *e_out_sz = ¶ms[0].memref.size; 359 uint8_t *n = params[1].memref.buffer; 360 size_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 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 */ 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 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 */ 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 */ 484 static bool is_region_valid(struct vm_region *r) 485 { 486 uint32_t dontwant = VM_FLAG_EPHEMERAL | VM_FLAG_PERMANENT | 487 VM_FLAG_LDELF; 488 uint32_t want = VM_FLAG_READONLY; 489 490 return ((r->flags & want) == want && !(r->flags & dontwant)); 491 } 492 493 /* 494 * With this comparison function, we're hashing the smaller regions first. 495 * Regions of equal size are ordered based on their content (memcmp()). 496 * Identical regions can be in any order since they will yield the same hash 497 * anyways. 498 */ 499 static int cmp_regions(const void *a, const void *b) 500 { 501 const struct vm_region *r1 = *(const struct vm_region **)a; 502 const struct vm_region *r2 = *(const struct vm_region **)b; 503 504 if (r1->size < r2->size) 505 return -1; 506 507 if (r1->size > r2->size) 508 return 1; 509 510 return memcmp((void *)r1->va, (void *)r2->va, r1->size); 511 } 512 513 static TEE_Result hash_regions(struct vm_info *vm_info, uint8_t *hash) 514 { 515 TEE_Result res = TEE_SUCCESS; 516 struct vm_region *r = NULL; 517 struct vm_region **regions = NULL; 518 size_t nregions = 0; 519 void *ctx = NULL; 520 size_t i = 0; 521 522 res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA256); 523 if (res) 524 return res; 525 526 res = crypto_hash_init(ctx); 527 if (res) 528 goto out; 529 530 /* 531 * Make an array of region pointers so we can use qsort() to order it. 532 */ 533 534 TAILQ_FOREACH(r, &vm_info->regions, link) 535 if (is_region_valid(r)) 536 nregions++; 537 538 regions = malloc(nregions * sizeof(*regions)); 539 if (!regions) { 540 res = TEE_ERROR_OUT_OF_MEMORY; 541 goto out; 542 } 543 544 TAILQ_FOREACH(r, &vm_info->regions, link) 545 if (is_region_valid(r)) 546 regions[i++] = r; 547 548 /* 549 * Sort regions so that they are in a consistent order even when TA ASLR 550 * is enabled. 551 */ 552 qsort(regions, nregions, sizeof(*regions), cmp_regions); 553 554 /* Hash regions in order */ 555 for (i = 0; i < nregions; i++) { 556 r = regions[i]; 557 DMSG("va %p size %zu", (void *)r->va, r->size); 558 res = crypto_hash_update(ctx, (uint8_t *)r->va, r->size); 559 if (res) 560 goto out; 561 } 562 563 res = crypto_hash_final(ctx, hash, TEE_SHA256_HASH_SIZE); 564 out: 565 free(regions); 566 crypto_hash_free_ctx(ctx); 567 return res; 568 } 569 570 static TEE_Result cmd_get_ta_shdr_digest(uint32_t param_types, 571 TEE_Param params[TEE_NUM_PARAMS]) 572 { 573 TEE_UUID *uuid = params[0].memref.buffer; 574 size_t uuid_sz = params[0].memref.size; 575 uint8_t *nonce = params[1].memref.buffer; 576 size_t nonce_sz = params[1].memref.size; 577 uint8_t *out = params[2].memref.buffer; 578 size_t out_sz = params[2].memref.size; 579 size_t min_out_sz = 0; 580 TEE_Result res = TEE_SUCCESS; 581 582 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 583 TEE_PARAM_TYPE_MEMREF_INPUT, 584 TEE_PARAM_TYPE_MEMREF_OUTPUT, 585 TEE_PARAM_TYPE_NONE)) 586 return TEE_ERROR_BAD_PARAMETERS; 587 588 if (uuid_sz != sizeof(*uuid)) 589 return TEE_ERROR_BAD_PARAMETERS; 590 591 if (!nonce || !nonce_sz) 592 return TEE_ERROR_BAD_PARAMETERS; 593 594 if (!out && out_sz) 595 return TEE_ERROR_BAD_PARAMETERS; 596 597 res = init_key(); 598 if (res) 599 return res; 600 601 min_out_sz = TEE_SHA256_HASH_SIZE + crypto_bignum_num_bytes(key->n); 602 params[2].memref.size = min_out_sz; 603 if (out_sz < min_out_sz) 604 return TEE_ERROR_SHORT_BUFFER; 605 out_sz = min_out_sz; 606 607 res = hash_binary(uuid, out); 608 if (res) 609 return res; 610 return sign_buffer(out, out_sz, nonce, nonce_sz); 611 } 612 613 static TEE_Result cmd_hash_ta_memory(uint32_t param_types, 614 TEE_Param params[TEE_NUM_PARAMS]) 615 { 616 uint8_t *nonce = params[0].memref.buffer; 617 size_t nonce_sz = params[0].memref.size; 618 uint8_t *out = params[1].memref.buffer; 619 size_t out_sz = params[1].memref.size; 620 struct user_mode_ctx *uctx = NULL; 621 TEE_Result res = TEE_SUCCESS; 622 struct ts_session *s = NULL; 623 size_t min_out_sz = 0; 624 625 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 626 TEE_PARAM_TYPE_MEMREF_OUTPUT, 627 TEE_PARAM_TYPE_NONE, 628 TEE_PARAM_TYPE_NONE)) 629 return TEE_ERROR_BAD_PARAMETERS; 630 631 if (!nonce || !nonce_sz) 632 return TEE_ERROR_BAD_PARAMETERS; 633 634 if (!out && out_sz) 635 return TEE_ERROR_BAD_PARAMETERS; 636 637 /* Check that we're called from a user TA */ 638 s = ts_get_calling_session(); 639 if (!s) 640 return TEE_ERROR_ACCESS_DENIED; 641 uctx = to_user_mode_ctx(s->ctx); 642 if (!uctx) 643 return TEE_ERROR_ACCESS_DENIED; 644 645 res = init_key(); 646 if (res) 647 return res; 648 649 min_out_sz = TEE_SHA256_HASH_SIZE + crypto_bignum_num_bytes(key->n); 650 params[1].memref.size = min_out_sz; 651 if (out_sz < min_out_sz) 652 return TEE_ERROR_SHORT_BUFFER; 653 out_sz = min_out_sz; 654 655 s = ts_pop_current_session(); 656 res = hash_regions(&uctx->vm_info, out); 657 ts_push_current_session(s); 658 if (res) 659 return res; 660 661 return sign_buffer(out, out_sz, nonce, nonce_sz); 662 } 663 664 static TEE_Result cmd_hash_tee_memory(uint32_t param_types, 665 TEE_Param params[TEE_NUM_PARAMS]) 666 { 667 uint8_t *nonce = params[0].memref.buffer; 668 size_t nonce_sz = params[0].memref.size; 669 uint8_t *out = params[1].memref.buffer; 670 size_t out_sz = params[1].memref.size; 671 TEE_Result res = TEE_SUCCESS; 672 size_t min_out_sz = 0; 673 void *ctx = NULL; 674 675 if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 676 TEE_PARAM_TYPE_MEMREF_OUTPUT, 677 TEE_PARAM_TYPE_NONE, 678 TEE_PARAM_TYPE_NONE)) 679 return TEE_ERROR_BAD_PARAMETERS; 680 681 if (!nonce || !nonce_sz) 682 return TEE_ERROR_BAD_PARAMETERS; 683 684 if (!out && out_sz) 685 return TEE_ERROR_BAD_PARAMETERS; 686 687 res = init_key(); 688 if (res) 689 return res; 690 691 min_out_sz = TEE_SHA256_HASH_SIZE + crypto_bignum_num_bytes(key->n); 692 params[1].memref.size = min_out_sz; 693 if (out_sz < min_out_sz) 694 return TEE_ERROR_SHORT_BUFFER; 695 out_sz = min_out_sz; 696 697 res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA256); 698 if (res) 699 return res; 700 res = crypto_hash_init(ctx); 701 if (res) 702 goto out; 703 res = crypto_hash_update(ctx, __text_start, 704 __text_data_start - __text_start); 705 if (res) 706 goto out; 707 res = crypto_hash_update(ctx, __text_data_end, 708 __text_end - __text_data_end); 709 if (IS_ENABLED(CFG_WITH_PAGER)) { 710 res = crypto_hash_update(ctx, __text_init_start, 711 __text_init_end - __text_init_start); 712 if (res) 713 goto out; 714 res = crypto_hash_update(ctx, __text_pageable_start, 715 __text_pageable_end - 716 __text_pageable_start); 717 if (res) 718 goto out; 719 } 720 if (res) 721 goto out; 722 res = crypto_hash_update(ctx, __rodata_start, 723 __rodata_end - __rodata_start); 724 if (res) 725 goto out; 726 if (IS_ENABLED(CFG_WITH_PAGER)) { 727 res = crypto_hash_update(ctx, __rodata_init_start, 728 __rodata_init_end - 729 __rodata_init_start); 730 if (res) 731 goto out; 732 res = crypto_hash_update(ctx, __rodata_pageable_start, 733 __rodata_pageable_end - 734 __rodata_pageable_start); 735 if (res) 736 goto out; 737 } 738 res = crypto_hash_final(ctx, out, TEE_SHA256_HASH_SIZE); 739 if (res) 740 goto out; 741 742 DHEXDUMP(out, TEE_SHA256_HASH_SIZE); 743 744 res = sign_buffer(out, out_sz, nonce, nonce_sz); 745 out: 746 crypto_hash_free_ctx(ctx); 747 return res; 748 } 749 750 static TEE_Result invoke_command(void *sess_ctx __unused, uint32_t cmd_id, 751 uint32_t param_types, 752 TEE_Param params[TEE_NUM_PARAMS]) 753 { 754 switch (cmd_id) { 755 case PTA_ATTESTATION_GET_PUBKEY: 756 return cmd_get_pubkey(param_types, params); 757 case PTA_ATTESTATION_GET_TA_SHDR_DIGEST: 758 return cmd_get_ta_shdr_digest(param_types, params); 759 case PTA_ATTESTATION_HASH_TA_MEMORY: 760 return cmd_hash_ta_memory(param_types, params); 761 case PTA_ATTESTATION_HASH_TEE_MEMORY: 762 return cmd_hash_tee_memory(param_types, params); 763 default: 764 break; 765 } 766 return TEE_ERROR_BAD_PARAMETERS; 767 } 768 769 pseudo_ta_register(.uuid = PTA_ATTESTATION_UUID, .name = PTA_NAME, 770 .flags = PTA_DEFAULT_FLAGS, 771 .invoke_command_entry_point = invoke_command); 772