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