17e05ec25SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 27e05ec25SJerome Forissier /* 37e05ec25SJerome Forissier * Copyright (C) 2021, Huawei Technologies Co., Ltd 47e05ec25SJerome Forissier */ 57e05ec25SJerome Forissier 67e05ec25SJerome Forissier #include <config.h> 77e05ec25SJerome Forissier #include <crypto/crypto.h> 87e05ec25SJerome Forissier #include <kernel/linker.h> 97e05ec25SJerome Forissier #include <kernel/pseudo_ta.h> 107e05ec25SJerome Forissier #include <kernel/ts_store.h> 117e05ec25SJerome Forissier #include <kernel/user_mode_ctx.h> 127e05ec25SJerome Forissier #include <mm/file.h> 137e05ec25SJerome Forissier #include <pta_attestation.h> 147e05ec25SJerome Forissier #include <stdlib.h> 157e05ec25SJerome Forissier #include <string.h> 167e05ec25SJerome Forissier #include <tee/entry_std.h> 177e05ec25SJerome Forissier #include <tee/tee_fs.h> 187e05ec25SJerome Forissier #include <tee/tee_pobj.h> 197e05ec25SJerome Forissier #include <tee/uuid.h> 207e05ec25SJerome Forissier #include <utee_defines.h> 217e05ec25SJerome Forissier 227e05ec25SJerome Forissier #define PTA_NAME "attestation.pta" 237e05ec25SJerome Forissier 247e05ec25SJerome Forissier #define MAX_KEY_SIZE 4096 257e05ec25SJerome Forissier 267e05ec25SJerome Forissier static TEE_UUID pta_uuid = PTA_ATTESTATION_UUID; 277e05ec25SJerome Forissier 287e05ec25SJerome Forissier static struct rsa_keypair *key; 297e05ec25SJerome Forissier 307e05ec25SJerome Forissier static const uint8_t key_file_name[] = "key"; 317e05ec25SJerome Forissier 327e05ec25SJerome Forissier static TEE_Result allocate_key(void) 337e05ec25SJerome Forissier { 347e05ec25SJerome Forissier assert(!key); 357e05ec25SJerome Forissier 367e05ec25SJerome Forissier key = calloc(1, sizeof(*key)); 377e05ec25SJerome Forissier if (!key) 387e05ec25SJerome Forissier return TEE_ERROR_OUT_OF_MEMORY; 397e05ec25SJerome Forissier 407e05ec25SJerome Forissier COMPILE_TIME_ASSERT(CFG_ATTESTATION_PTA_KEY_SIZE <= MAX_KEY_SIZE); 417e05ec25SJerome Forissier return crypto_acipher_alloc_rsa_keypair(key, MAX_KEY_SIZE); 427e05ec25SJerome Forissier } 437e05ec25SJerome Forissier 447e05ec25SJerome Forissier static void free_key(void) 457e05ec25SJerome Forissier { 467e05ec25SJerome Forissier crypto_acipher_free_rsa_keypair(key); 477e05ec25SJerome Forissier free(key); 487e05ec25SJerome Forissier key = NULL; 497e05ec25SJerome Forissier } 507e05ec25SJerome Forissier 517e05ec25SJerome Forissier static TEE_Result generate_key(void) 527e05ec25SJerome Forissier { 537e05ec25SJerome Forissier uint32_t e = TEE_U32_TO_BIG_ENDIAN(65537); 547e05ec25SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 557e05ec25SJerome Forissier 567e05ec25SJerome Forissier res = allocate_key(); 577e05ec25SJerome Forissier if (res) 587e05ec25SJerome Forissier return res; 597e05ec25SJerome Forissier 607e05ec25SJerome Forissier crypto_bignum_bin2bn((uint8_t *)&e, sizeof(e), key->e); 617e05ec25SJerome Forissier 627e05ec25SJerome Forissier /* 637e05ec25SJerome Forissier * For security reasons, the RSA modulus size has to be at least the 647e05ec25SJerome Forissier * size of the data to be signed. 657e05ec25SJerome Forissier */ 667e05ec25SJerome Forissier DMSG("Generating %u bit RSA key pair", CFG_ATTESTATION_PTA_KEY_SIZE); 677e05ec25SJerome Forissier COMPILE_TIME_ASSERT(CFG_ATTESTATION_PTA_KEY_SIZE >= 687e05ec25SJerome Forissier TEE_SHA256_HASH_SIZE); 697e05ec25SJerome Forissier res = crypto_acipher_gen_rsa_key(key, CFG_ATTESTATION_PTA_KEY_SIZE); 707e05ec25SJerome Forissier if (res) 717e05ec25SJerome Forissier free_key(); 727e05ec25SJerome Forissier 737e05ec25SJerome Forissier return res; 747e05ec25SJerome Forissier } 757e05ec25SJerome Forissier 767e05ec25SJerome Forissier /* 777e05ec25SJerome Forissier * Return values: 787e05ec25SJerome Forissier * > 0 : Number of bytes written to buf 797e05ec25SJerome Forissier * 0 : @sz too large (> UINT16_MAX) or @buf_sz too small 807e05ec25SJerome Forissier */ 817e05ec25SJerome Forissier static size_t serialize_bignum(uint8_t *buf, size_t buf_sz, struct bignum *bn) 827e05ec25SJerome Forissier { 837e05ec25SJerome Forissier uint8_t *p = buf; 847e05ec25SJerome Forissier size_t sz = crypto_bignum_num_bytes(bn); 857e05ec25SJerome Forissier uint16_t val = TEE_U16_TO_BIG_ENDIAN(sz); 867e05ec25SJerome Forissier size_t total_sz = sizeof(val) + sz; 877e05ec25SJerome Forissier 887e05ec25SJerome Forissier if (sz > UINT16_MAX || total_sz > buf_sz) 897e05ec25SJerome Forissier return 0; 907e05ec25SJerome Forissier 917e05ec25SJerome Forissier memcpy(p, &val, sizeof(val)); 927e05ec25SJerome Forissier p += sizeof(val); 937e05ec25SJerome Forissier 947e05ec25SJerome Forissier crypto_bignum_bn2bin(bn, p); 957e05ec25SJerome Forissier 967e05ec25SJerome Forissier return total_sz; 977e05ec25SJerome Forissier } 987e05ec25SJerome Forissier 997e05ec25SJerome Forissier static size_t bufsize(size_t e_sz, size_t d_sz, size_t n_sz) 1007e05ec25SJerome Forissier { 1017e05ec25SJerome Forissier /* 1027e05ec25SJerome Forissier * Serialized key pair is 3 bignums (e, p and n) plus their sizes 1037e05ec25SJerome Forissier * encoded as uint16_t. 1047e05ec25SJerome Forissier */ 1057e05ec25SJerome Forissier return e_sz + d_sz + n_sz + 3 * sizeof(uint16_t); 1067e05ec25SJerome Forissier } 1077e05ec25SJerome Forissier 1087e05ec25SJerome Forissier static TEE_Result serialize_key(uint8_t *buf, size_t size) 1097e05ec25SJerome Forissier { 1107e05ec25SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 1117e05ec25SJerome Forissier uint8_t *p = buf; 1127e05ec25SJerome Forissier size_t needed_sz = 0; 1137e05ec25SJerome Forissier size_t e_sz = 0; 1147e05ec25SJerome Forissier size_t d_sz = 0; 1157e05ec25SJerome Forissier size_t n_sz = 0; 1167e05ec25SJerome Forissier size_t sz = 0; 1177e05ec25SJerome Forissier 1187e05ec25SJerome Forissier assert(key); 1197e05ec25SJerome Forissier 1207e05ec25SJerome Forissier e_sz = crypto_bignum_num_bytes(key->e); 1217e05ec25SJerome Forissier d_sz = crypto_bignum_num_bytes(key->d); 1227e05ec25SJerome Forissier n_sz = crypto_bignum_num_bytes(key->n); 1237e05ec25SJerome Forissier if (e_sz > UINT16_MAX || d_sz > UINT16_MAX || n_sz > UINT16_MAX) 1247e05ec25SJerome Forissier goto err; 1257e05ec25SJerome Forissier 1267e05ec25SJerome Forissier needed_sz = bufsize(e_sz, d_sz, n_sz); 1277e05ec25SJerome Forissier if (size < needed_sz) 1287e05ec25SJerome Forissier goto err; 1297e05ec25SJerome Forissier 1307e05ec25SJerome Forissier sz = serialize_bignum(p, needed_sz, key->e); 1317e05ec25SJerome Forissier if (!sz) 1327e05ec25SJerome Forissier goto err; 1337e05ec25SJerome Forissier p += sz; 1347e05ec25SJerome Forissier needed_sz -= sz; 1357e05ec25SJerome Forissier sz = serialize_bignum(p, needed_sz, key->d); 1367e05ec25SJerome Forissier if (!sz) 1377e05ec25SJerome Forissier goto err; 1387e05ec25SJerome Forissier p += sz; 1397e05ec25SJerome Forissier needed_sz -= sz; 1407e05ec25SJerome Forissier sz = serialize_bignum(p, needed_sz, key->n); 1417e05ec25SJerome Forissier if (!sz) 1427e05ec25SJerome Forissier goto err; 1437e05ec25SJerome Forissier needed_sz -= sz; 1447e05ec25SJerome Forissier assert(!needed_sz); 1457e05ec25SJerome Forissier 1467e05ec25SJerome Forissier return TEE_SUCCESS; 1477e05ec25SJerome Forissier err: 1487e05ec25SJerome Forissier return res; 1497e05ec25SJerome Forissier } 1507e05ec25SJerome Forissier 1517e05ec25SJerome Forissier static size_t deserialize_bignum(uint8_t *buf, size_t max_sz, struct bignum *bn) 1527e05ec25SJerome Forissier { 1537e05ec25SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 1547e05ec25SJerome Forissier uint8_t *p = buf; 1557e05ec25SJerome Forissier uint16_t val = 0; 1567e05ec25SJerome Forissier size_t sz = 0; 1577e05ec25SJerome Forissier 1587e05ec25SJerome Forissier if (max_sz < sizeof(val)) 1597e05ec25SJerome Forissier return 0; 1607e05ec25SJerome Forissier 1617e05ec25SJerome Forissier memcpy(&val, p, sizeof(val)); 1627e05ec25SJerome Forissier sz = TEE_U16_FROM_BIG_ENDIAN(val); 1637e05ec25SJerome Forissier p += sizeof(val); 1647e05ec25SJerome Forissier max_sz -= sizeof(val); 1657e05ec25SJerome Forissier if (max_sz < sz) 1667e05ec25SJerome Forissier return 0; 1677e05ec25SJerome Forissier 1687e05ec25SJerome Forissier res = crypto_bignum_bin2bn(p, sz, bn); 1697e05ec25SJerome Forissier if (res) 1707e05ec25SJerome Forissier return 0; 1717e05ec25SJerome Forissier 1727e05ec25SJerome Forissier return sizeof(val) + sz; 1737e05ec25SJerome Forissier } 1747e05ec25SJerome Forissier 1757e05ec25SJerome Forissier static TEE_Result deserialize_key(uint8_t *buf, size_t buf_sz) 1767e05ec25SJerome Forissier { 1777e05ec25SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 1787e05ec25SJerome Forissier uint8_t *p = buf; 1797e05ec25SJerome Forissier size_t sz = 0; 1807e05ec25SJerome Forissier 1817e05ec25SJerome Forissier res = allocate_key(); 1827e05ec25SJerome Forissier if (res) 183*e2cac47bSClement Faure return res; 1847e05ec25SJerome Forissier 1857e05ec25SJerome Forissier sz = deserialize_bignum(p, buf_sz, key->e); 1867e05ec25SJerome Forissier if (!sz) 187*e2cac47bSClement Faure goto err; 1887e05ec25SJerome Forissier p += sz; 1897e05ec25SJerome Forissier buf_sz -= sz; 1907e05ec25SJerome Forissier sz = deserialize_bignum(p, buf_sz, key->d); 1917e05ec25SJerome Forissier if (!sz) 192*e2cac47bSClement Faure goto err; 1937e05ec25SJerome Forissier p += sz; 1947e05ec25SJerome Forissier buf_sz -= sz; 1957e05ec25SJerome Forissier sz = deserialize_bignum(p, buf_sz, key->n); 1967e05ec25SJerome Forissier if (!sz) 197*e2cac47bSClement Faure goto err; 198*e2cac47bSClement Faure 199*e2cac47bSClement Faure return TEE_SUCCESS; 200*e2cac47bSClement Faure err: 201*e2cac47bSClement Faure free_key(); 202*e2cac47bSClement Faure return TEE_ERROR_GENERIC; 2037e05ec25SJerome Forissier } 2047e05ec25SJerome Forissier 2057e05ec25SJerome Forissier static TEE_Result sec_storage_obj_read(TEE_UUID *uuid, uint32_t storage_id, 2067e05ec25SJerome Forissier const uint8_t *obj_id, 2077e05ec25SJerome Forissier size_t obj_id_len, 2087e05ec25SJerome Forissier uint8_t *data, size_t *len, 2097e05ec25SJerome Forissier size_t offset, uint32_t flags) 2107e05ec25SJerome Forissier { 2117e05ec25SJerome Forissier const struct tee_file_operations *fops = NULL; 2127e05ec25SJerome Forissier TEE_Result res = TEE_ERROR_BAD_STATE; 2137e05ec25SJerome Forissier struct tee_file_handle *fh = NULL; 2147e05ec25SJerome Forissier struct tee_pobj *po = NULL; 2157e05ec25SJerome Forissier size_t file_size = 0; 2167e05ec25SJerome Forissier size_t read_len = 0; 2177e05ec25SJerome Forissier 2187e05ec25SJerome Forissier fops = tee_svc_storage_file_ops(storage_id); 2197e05ec25SJerome Forissier if (!fops) 2207e05ec25SJerome Forissier return TEE_ERROR_NOT_IMPLEMENTED; 2217e05ec25SJerome Forissier 2227e05ec25SJerome Forissier if (obj_id_len > TEE_OBJECT_ID_MAX_LEN) 2237e05ec25SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 2247e05ec25SJerome Forissier 2257e05ec25SJerome Forissier res = tee_pobj_get(uuid, (void *)obj_id, obj_id_len, flags, false, fops, 2267e05ec25SJerome Forissier &po); 2277e05ec25SJerome Forissier if (res) 2287e05ec25SJerome Forissier return res; 2297e05ec25SJerome Forissier 2307e05ec25SJerome Forissier res = po->fops->open(po, &file_size, &fh); 2317e05ec25SJerome Forissier if (res) 2327e05ec25SJerome Forissier goto out; 2337e05ec25SJerome Forissier 2347e05ec25SJerome Forissier read_len = *len; 2357e05ec25SJerome Forissier res = po->fops->read(fh, offset, data, &read_len); 2367e05ec25SJerome Forissier if (res == TEE_ERROR_CORRUPT_OBJECT) { 2377e05ec25SJerome Forissier EMSG("Object corrupt"); 2387e05ec25SJerome Forissier po->fops->remove(po); 2397e05ec25SJerome Forissier } else if (!res) { 2407e05ec25SJerome Forissier *len = read_len; 2417e05ec25SJerome Forissier } 2427e05ec25SJerome Forissier 2437e05ec25SJerome Forissier po->fops->close(&fh); 2447e05ec25SJerome Forissier out: 2457e05ec25SJerome Forissier tee_pobj_release(po); 2467e05ec25SJerome Forissier 2477e05ec25SJerome Forissier return res; 2487e05ec25SJerome Forissier } 2497e05ec25SJerome Forissier 2507e05ec25SJerome Forissier static TEE_Result sec_storage_obj_write(TEE_UUID *uuid, uint32_t storage_id, 2517e05ec25SJerome Forissier const uint8_t *obj_id, 2527e05ec25SJerome Forissier size_t obj_id_len, 2537e05ec25SJerome Forissier const uint8_t *data, size_t len, 2547e05ec25SJerome Forissier size_t offset, uint32_t flags) 2557e05ec25SJerome Forissier 2567e05ec25SJerome Forissier { 2577e05ec25SJerome Forissier const struct tee_file_operations *fops = NULL; 2587e05ec25SJerome Forissier struct tee_file_handle *fh = NULL; 2597e05ec25SJerome Forissier TEE_Result res = TEE_SUCCESS; 2607e05ec25SJerome Forissier struct tee_pobj *po = NULL; 2617e05ec25SJerome Forissier 2627e05ec25SJerome Forissier fops = tee_svc_storage_file_ops(storage_id); 2637e05ec25SJerome Forissier if (!fops) 2647e05ec25SJerome Forissier return TEE_ERROR_NOT_IMPLEMENTED; 2657e05ec25SJerome Forissier 2667e05ec25SJerome Forissier if (obj_id_len > TEE_OBJECT_ID_MAX_LEN) 2677e05ec25SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 2687e05ec25SJerome Forissier 2697e05ec25SJerome Forissier res = tee_pobj_get(uuid, (void *)obj_id, obj_id_len, flags, false, 2707e05ec25SJerome Forissier fops, &po); 2717e05ec25SJerome Forissier if (res) 2727e05ec25SJerome Forissier return res; 2737e05ec25SJerome Forissier 2747e05ec25SJerome Forissier res = po->fops->open(po, NULL, &fh); 2757e05ec25SJerome Forissier if (res == TEE_ERROR_ITEM_NOT_FOUND) 2767e05ec25SJerome Forissier res = po->fops->create(po, false, NULL, 0, NULL, 0, NULL, 0, 2777e05ec25SJerome Forissier &fh); 2787e05ec25SJerome Forissier if (!res) { 2797e05ec25SJerome Forissier res = po->fops->write(fh, offset, data, len); 2807e05ec25SJerome Forissier po->fops->close(&fh); 2817e05ec25SJerome Forissier } 2827e05ec25SJerome Forissier 2837e05ec25SJerome Forissier tee_pobj_release(po); 2847e05ec25SJerome Forissier 2857e05ec25SJerome Forissier return res; 2867e05ec25SJerome Forissier } 2877e05ec25SJerome Forissier 2887e05ec25SJerome Forissier static TEE_Result load_key(uint8_t *buf, size_t size) 2897e05ec25SJerome Forissier { 2907e05ec25SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 2917e05ec25SJerome Forissier 2927e05ec25SJerome Forissier DMSG("Loading RSA key pair from secure storage"); 2937e05ec25SJerome Forissier res = sec_storage_obj_read(&pta_uuid, TEE_STORAGE_PRIVATE, 2947e05ec25SJerome Forissier key_file_name, sizeof(key_file_name) - 1, 2957e05ec25SJerome Forissier buf, &size, 0, TEE_DATA_FLAG_ACCESS_READ); 2967e05ec25SJerome Forissier if (res) 2977e05ec25SJerome Forissier return res; 2987e05ec25SJerome Forissier DMSG("Read %zu bytes", size); 2997e05ec25SJerome Forissier res = deserialize_key(buf, size); 3007e05ec25SJerome Forissier if (!res) 3017e05ec25SJerome Forissier DMSG("Loaded %zu bit key pair", crypto_bignum_num_bits(key->n)); 3027e05ec25SJerome Forissier 3037e05ec25SJerome Forissier return res; 3047e05ec25SJerome Forissier } 3057e05ec25SJerome Forissier 3067e05ec25SJerome Forissier static TEE_Result write_key(uint8_t *buf, size_t size) 3077e05ec25SJerome Forissier { 3087e05ec25SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 3097e05ec25SJerome Forissier 3107e05ec25SJerome Forissier DMSG("Saving key pair"); 3117e05ec25SJerome Forissier res = serialize_key(buf, size); 3127e05ec25SJerome Forissier if (res) 3137e05ec25SJerome Forissier return res; 3147e05ec25SJerome Forissier 3157e05ec25SJerome Forissier res = sec_storage_obj_write(&pta_uuid, TEE_STORAGE_PRIVATE, 3167e05ec25SJerome Forissier key_file_name, sizeof(key_file_name) - 1, 3177e05ec25SJerome Forissier buf, size, 0, TEE_DATA_FLAG_ACCESS_WRITE); 3187e05ec25SJerome Forissier if (!res) 3197e05ec25SJerome Forissier DMSG("Wrote %zu bytes", size); 3207e05ec25SJerome Forissier return res; 3217e05ec25SJerome Forissier } 3227e05ec25SJerome Forissier 3237e05ec25SJerome Forissier static TEE_Result init_key(void) 3247e05ec25SJerome Forissier { 3257e05ec25SJerome Forissier TEE_Result res = TEE_SUCCESS; 3267e05ec25SJerome Forissier uint8_t *buf = NULL; 3277e05ec25SJerome Forissier size_t size = 0; 3287e05ec25SJerome Forissier 3297e05ec25SJerome Forissier if (!key) { 3307e05ec25SJerome Forissier /* 3317e05ec25SJerome Forissier * e is 65537 so its bignum size is 3 bytes. d and n can be up 3327e05ec25SJerome Forissier * to MAX_KEY_SIZE bits. 3337e05ec25SJerome Forissier */ 3347e05ec25SJerome Forissier size = bufsize(3, MAX_KEY_SIZE / 8, MAX_KEY_SIZE / 8); 3357e05ec25SJerome Forissier buf = calloc(1, size); 3367e05ec25SJerome Forissier if (!buf) { 3377e05ec25SJerome Forissier res = TEE_ERROR_OUT_OF_MEMORY; 3387e05ec25SJerome Forissier goto out; 3397e05ec25SJerome Forissier } 3407e05ec25SJerome Forissier res = load_key(buf, size); 3417e05ec25SJerome Forissier if (res == TEE_ERROR_ITEM_NOT_FOUND) { 3427e05ec25SJerome Forissier res = generate_key(); 3437e05ec25SJerome Forissier if (res) 3447e05ec25SJerome Forissier goto out; 3457e05ec25SJerome Forissier res = write_key(buf, size); 3467e05ec25SJerome Forissier } 3477e05ec25SJerome Forissier } 3487e05ec25SJerome Forissier out: 3497e05ec25SJerome Forissier free(buf); 3507e05ec25SJerome Forissier return res; 3517e05ec25SJerome Forissier } 3527e05ec25SJerome Forissier 3537e05ec25SJerome Forissier static TEE_Result cmd_get_pubkey(uint32_t param_types, 3547e05ec25SJerome Forissier TEE_Param params[TEE_NUM_PARAMS]) 3557e05ec25SJerome Forissier { 3567e05ec25SJerome Forissier TEE_Result res = TEE_ERROR_GENERIC; 3577e05ec25SJerome Forissier uint8_t *e = params[0].memref.buffer; 3587e05ec25SJerome Forissier uint32_t *e_out_sz = ¶ms[0].memref.size; 3597e05ec25SJerome Forissier uint8_t *n = params[1].memref.buffer; 3607e05ec25SJerome Forissier uint32_t *n_out_sz = ¶ms[1].memref.size; 3617e05ec25SJerome Forissier size_t sz = 0; 3627e05ec25SJerome Forissier 3637e05ec25SJerome Forissier if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT, 3647e05ec25SJerome Forissier TEE_PARAM_TYPE_MEMREF_OUTPUT, 3657e05ec25SJerome Forissier TEE_PARAM_TYPE_VALUE_OUTPUT, 3667e05ec25SJerome Forissier TEE_PARAM_TYPE_NONE)) 3677e05ec25SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 3687e05ec25SJerome Forissier 3697e05ec25SJerome Forissier res = init_key(); 3707e05ec25SJerome Forissier if (res) 3717e05ec25SJerome Forissier return res; 3727e05ec25SJerome Forissier 3737e05ec25SJerome Forissier sz = crypto_bignum_num_bytes(key->e); 3747e05ec25SJerome Forissier if (*e_out_sz >= sz) 3757e05ec25SJerome Forissier crypto_bignum_bn2bin(key->e, e); 3767e05ec25SJerome Forissier else 3777e05ec25SJerome Forissier res = TEE_ERROR_SHORT_BUFFER; 3787e05ec25SJerome Forissier *e_out_sz = sz; 3797e05ec25SJerome Forissier 3807e05ec25SJerome Forissier sz = crypto_bignum_num_bytes(key->n); 3817e05ec25SJerome Forissier if (*n_out_sz >= sz) 3827e05ec25SJerome Forissier crypto_bignum_bn2bin(key->n, n); 3837e05ec25SJerome Forissier else 3847e05ec25SJerome Forissier res = TEE_ERROR_SHORT_BUFFER; 3857e05ec25SJerome Forissier *n_out_sz = sz; 3867e05ec25SJerome Forissier 3877e05ec25SJerome Forissier params[2].value.a = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256; 3887e05ec25SJerome Forissier 3897e05ec25SJerome Forissier return res; 3907e05ec25SJerome Forissier } 3917e05ec25SJerome Forissier 3927e05ec25SJerome Forissier static TEE_Result hash_binary(const TEE_UUID *uuid, uint8_t *hash) 3937e05ec25SJerome Forissier { 3947e05ec25SJerome Forissier TEE_Result res = TEE_ERROR_ITEM_NOT_FOUND; 3957e05ec25SJerome Forissier unsigned int tag_len = FILE_TAG_SIZE; 3967e05ec25SJerome Forissier const struct ts_store_ops *ops = NULL; 3977e05ec25SJerome Forissier struct ts_store_handle *h = NULL; 3987e05ec25SJerome Forissier 3997e05ec25SJerome Forissier SCATTERED_ARRAY_FOREACH(ops, ta_stores, struct ts_store_ops) { 4007e05ec25SJerome Forissier res = ops->open(uuid, &h); 4017e05ec25SJerome Forissier if (!res) 4027e05ec25SJerome Forissier break; /* TA found */ 4037e05ec25SJerome Forissier } 4047e05ec25SJerome Forissier if (res) 4057e05ec25SJerome Forissier return res; 4067e05ec25SJerome Forissier 4077e05ec25SJerome Forissier /* 4087e05ec25SJerome Forissier * Output hash size is assumed to be the same size as the file tag 4097e05ec25SJerome Forissier * size which is the size of the digest in the TA shdr. If one or the 4107e05ec25SJerome Forissier * other changes, additional hashing will be needed. 4117e05ec25SJerome Forissier */ 4127e05ec25SJerome Forissier COMPILE_TIME_ASSERT(FILE_TAG_SIZE == TEE_SHA256_HASH_SIZE); 4137e05ec25SJerome Forissier assert(ops); 4147e05ec25SJerome Forissier res = ops->get_tag(h, hash, &tag_len); 4157e05ec25SJerome Forissier if (res) 4167e05ec25SJerome Forissier goto out; 4177e05ec25SJerome Forissier 4187e05ec25SJerome Forissier DMSG("TA %pUl hash:", uuid); 4197e05ec25SJerome Forissier DHEXDUMP(hash, TEE_SHA256_HASH_SIZE); 4207e05ec25SJerome Forissier out: 4217e05ec25SJerome Forissier ops->close(h); 4227e05ec25SJerome Forissier return res; 4237e05ec25SJerome Forissier } 4247e05ec25SJerome Forissier 4257e05ec25SJerome Forissier /* Hash @nonce and @hash into @digest */ 4267e05ec25SJerome Forissier static TEE_Result digest_nonce_and_hash(uint8_t *digest, uint8_t *nonce, 4277e05ec25SJerome Forissier size_t nonce_sz, uint8_t *hash) 4287e05ec25SJerome Forissier { 4297e05ec25SJerome Forissier TEE_Result res = TEE_SUCCESS; 4307e05ec25SJerome Forissier void *ctx = NULL; 4317e05ec25SJerome Forissier 4327e05ec25SJerome Forissier res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA256); 4337e05ec25SJerome Forissier if (res) 4347e05ec25SJerome Forissier return res; 4357e05ec25SJerome Forissier res = crypto_hash_init(ctx); 4367e05ec25SJerome Forissier if (res) 4377e05ec25SJerome Forissier goto out; 4387e05ec25SJerome Forissier res = crypto_hash_update(ctx, nonce, nonce_sz); 4397e05ec25SJerome Forissier if (res) 4407e05ec25SJerome Forissier goto out; 4417e05ec25SJerome Forissier res = crypto_hash_update(ctx, hash, TEE_SHA256_HASH_SIZE); 4427e05ec25SJerome Forissier if (res) 4437e05ec25SJerome Forissier goto out; 4447e05ec25SJerome Forissier res = crypto_hash_final(ctx, digest, TEE_SHA256_HASH_SIZE); 4457e05ec25SJerome Forissier out: 4467e05ec25SJerome Forissier crypto_hash_free_ctx(ctx); 4477e05ec25SJerome Forissier return res; 4487e05ec25SJerome Forissier } 4497e05ec25SJerome Forissier 4507e05ec25SJerome Forissier static TEE_Result sign_digest(uint8_t *sig, size_t sig_len, 4517e05ec25SJerome Forissier const uint8_t *digest) 4527e05ec25SJerome Forissier { 4537e05ec25SJerome Forissier return crypto_acipher_rsassa_sign(TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256, 4547e05ec25SJerome Forissier key, 4557e05ec25SJerome Forissier TEE_SHA256_HASH_SIZE, /* salt len */ 4567e05ec25SJerome Forissier digest, TEE_SHA256_HASH_SIZE, 4577e05ec25SJerome Forissier sig, &sig_len); 4587e05ec25SJerome Forissier } 4597e05ec25SJerome Forissier 4607e05ec25SJerome Forissier /* 4617e05ec25SJerome Forissier * Sign the first 32 bytes contained in @buf and append signature 4627e05ec25SJerome Forissier * out = [ hash | sig(sha256(nonce | hash)) ] 4637e05ec25SJerome Forissier * ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ 4647e05ec25SJerome Forissier * 32B modulus size 4657e05ec25SJerome Forissier */ 4667e05ec25SJerome Forissier static TEE_Result sign_buffer(uint8_t *buf, size_t buf_sz, uint8_t *nonce, 4677e05ec25SJerome Forissier size_t nonce_sz) 4687e05ec25SJerome Forissier { 4697e05ec25SJerome Forissier uint8_t digest[TEE_SHA256_HASH_SIZE] = { }; 4707e05ec25SJerome Forissier TEE_Result res = TEE_SUCCESS; 4717e05ec25SJerome Forissier 4727e05ec25SJerome Forissier res = digest_nonce_and_hash(digest, nonce, nonce_sz, buf); 4737e05ec25SJerome Forissier if (res) 4747e05ec25SJerome Forissier return res; 4757e05ec25SJerome Forissier return sign_digest(buf + TEE_SHA256_HASH_SIZE, 4767e05ec25SJerome Forissier buf_sz - TEE_SHA256_HASH_SIZE, digest); 4777e05ec25SJerome Forissier } 4787e05ec25SJerome Forissier 4797e05ec25SJerome Forissier /* 4807e05ec25SJerome Forissier * Is region valid for hashing? 4817e05ec25SJerome Forissier * Exclude writable regions as well as those that are not specific to the TA 4827e05ec25SJerome Forissier * (ldelf, kernel or temporary mappings). 4837e05ec25SJerome Forissier */ 4847e05ec25SJerome Forissier static bool is_region_valid(struct vm_region *r) 4857e05ec25SJerome Forissier { 4867e05ec25SJerome Forissier uint32_t skip_flags = VM_FLAG_EPHEMERAL | VM_FLAG_PERMANENT | 4877e05ec25SJerome Forissier VM_FLAG_LDELF; 4887e05ec25SJerome Forissier 4897e05ec25SJerome Forissier return !(r->flags & skip_flags || r->attr & TEE_MATTR_UW); 4907e05ec25SJerome Forissier } 4917e05ec25SJerome Forissier 4927e05ec25SJerome Forissier /* 4937e05ec25SJerome Forissier * With this comparison function, we're hashing the smaller regions first. 4947e05ec25SJerome Forissier * Regions of equal size are ordered based on their content (memcmp()). 4957e05ec25SJerome Forissier * Identical regions can be in any order since they will yield the same hash 4967e05ec25SJerome Forissier * anyways. 4977e05ec25SJerome Forissier */ 4987e05ec25SJerome Forissier static int cmp_regions(const void *a, const void *b) 4997e05ec25SJerome Forissier { 5007e05ec25SJerome Forissier const struct vm_region *r1 = *(const struct vm_region **)a; 5017e05ec25SJerome Forissier const struct vm_region *r2 = *(const struct vm_region **)b; 5027e05ec25SJerome Forissier 5037e05ec25SJerome Forissier if (r1->size < r2->size) 5047e05ec25SJerome Forissier return -1; 5057e05ec25SJerome Forissier 5067e05ec25SJerome Forissier if (r1->size > r2->size) 5077e05ec25SJerome Forissier return 1; 5087e05ec25SJerome Forissier 5097e05ec25SJerome Forissier return memcmp((void *)r1->va, (void *)r2->va, r1->size); 5107e05ec25SJerome Forissier } 5117e05ec25SJerome Forissier 5127e05ec25SJerome Forissier static TEE_Result hash_regions(struct vm_info *vm_info, uint8_t *hash) 5137e05ec25SJerome Forissier { 5147e05ec25SJerome Forissier TEE_Result res = TEE_SUCCESS; 5157e05ec25SJerome Forissier struct vm_region *r = NULL; 5167e05ec25SJerome Forissier struct vm_region **regions = NULL; 5177e05ec25SJerome Forissier size_t nregions = 0; 5187e05ec25SJerome Forissier void *ctx = NULL; 5197e05ec25SJerome Forissier size_t i = 0; 5207e05ec25SJerome Forissier 5217e05ec25SJerome Forissier res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA256); 5227e05ec25SJerome Forissier if (res) 5237e05ec25SJerome Forissier return res; 5247e05ec25SJerome Forissier 5257e05ec25SJerome Forissier res = crypto_hash_init(ctx); 5267e05ec25SJerome Forissier if (res) 5277e05ec25SJerome Forissier goto out; 5287e05ec25SJerome Forissier 5297e05ec25SJerome Forissier /* 5307e05ec25SJerome Forissier * Make an array of region pointers so we can use qsort() to order it. 5317e05ec25SJerome Forissier */ 5327e05ec25SJerome Forissier 5337e05ec25SJerome Forissier TAILQ_FOREACH(r, &vm_info->regions, link) 5347e05ec25SJerome Forissier if (is_region_valid(r)) 5357e05ec25SJerome Forissier nregions++; 5367e05ec25SJerome Forissier 5377e05ec25SJerome Forissier regions = malloc(nregions * sizeof(*regions)); 5387e05ec25SJerome Forissier if (!regions) { 5397e05ec25SJerome Forissier res = TEE_ERROR_OUT_OF_MEMORY; 5407e05ec25SJerome Forissier goto out; 5417e05ec25SJerome Forissier } 5427e05ec25SJerome Forissier 5437e05ec25SJerome Forissier TAILQ_FOREACH(r, &vm_info->regions, link) 5447e05ec25SJerome Forissier if (is_region_valid(r)) 5457e05ec25SJerome Forissier regions[i++] = r; 5467e05ec25SJerome Forissier 5477e05ec25SJerome Forissier /* 5487e05ec25SJerome Forissier * Sort regions so that they are in a consistent order even when TA ASLR 5497e05ec25SJerome Forissier * is enabled. 5507e05ec25SJerome Forissier */ 5517e05ec25SJerome Forissier qsort(regions, nregions, sizeof(*regions), cmp_regions); 5527e05ec25SJerome Forissier 5537e05ec25SJerome Forissier /* Hash regions in order */ 5547e05ec25SJerome Forissier for (i = 0; i < nregions; i++) { 5557e05ec25SJerome Forissier r = regions[i]; 5567e05ec25SJerome Forissier DMSG("va %p size %zu", (void *)r->va, r->size); 5577e05ec25SJerome Forissier res = crypto_hash_update(ctx, (uint8_t *)r->va, r->size); 5587e05ec25SJerome Forissier if (res) 5597e05ec25SJerome Forissier goto out; 5607e05ec25SJerome Forissier } 5617e05ec25SJerome Forissier 5627e05ec25SJerome Forissier res = crypto_hash_final(ctx, hash, TEE_SHA256_HASH_SIZE); 5637e05ec25SJerome Forissier out: 5647e05ec25SJerome Forissier free(regions); 5657e05ec25SJerome Forissier crypto_hash_free_ctx(ctx); 5667e05ec25SJerome Forissier return res; 5677e05ec25SJerome Forissier } 5687e05ec25SJerome Forissier 5697e05ec25SJerome Forissier static TEE_Result cmd_get_ta_shdr_digest(uint32_t param_types, 5707e05ec25SJerome Forissier TEE_Param params[TEE_NUM_PARAMS]) 5717e05ec25SJerome Forissier { 5727e05ec25SJerome Forissier TEE_UUID *uuid = params[0].memref.buffer; 5737e05ec25SJerome Forissier size_t uuid_sz = params[0].memref.size; 5747e05ec25SJerome Forissier uint8_t *nonce = params[1].memref.buffer; 5757e05ec25SJerome Forissier size_t nonce_sz = params[1].memref.size; 5767e05ec25SJerome Forissier uint8_t *out = params[2].memref.buffer; 5777e05ec25SJerome Forissier size_t out_sz = params[2].memref.size; 5787e05ec25SJerome Forissier size_t min_out_sz = 0; 5797e05ec25SJerome Forissier TEE_Result res = TEE_SUCCESS; 5807e05ec25SJerome Forissier 5817e05ec25SJerome Forissier if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 5827e05ec25SJerome Forissier TEE_PARAM_TYPE_MEMREF_INPUT, 5837e05ec25SJerome Forissier TEE_PARAM_TYPE_MEMREF_OUTPUT, 5847e05ec25SJerome Forissier TEE_PARAM_TYPE_NONE)) 5857e05ec25SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 5867e05ec25SJerome Forissier 5877e05ec25SJerome Forissier if (uuid_sz != sizeof(*uuid)) 5887e05ec25SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 5897e05ec25SJerome Forissier 5907e05ec25SJerome Forissier if (!nonce || !nonce_sz) 5917e05ec25SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 5927e05ec25SJerome Forissier 5937e05ec25SJerome Forissier if (!out && out_sz) 5947e05ec25SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 5957e05ec25SJerome Forissier 5967e05ec25SJerome Forissier res = init_key(); 5977e05ec25SJerome Forissier if (res) 5987e05ec25SJerome Forissier return res; 5997e05ec25SJerome Forissier 6007e05ec25SJerome Forissier min_out_sz = TEE_SHA256_HASH_SIZE + crypto_bignum_num_bytes(key->n); 6017e05ec25SJerome Forissier params[2].memref.size = min_out_sz; 6027e05ec25SJerome Forissier if (out_sz < min_out_sz) 6037e05ec25SJerome Forissier return TEE_ERROR_SHORT_BUFFER; 6047e05ec25SJerome Forissier out_sz = min_out_sz; 6057e05ec25SJerome Forissier 6067e05ec25SJerome Forissier res = hash_binary(uuid, out); 6077e05ec25SJerome Forissier if (res) 6087e05ec25SJerome Forissier return res; 6097e05ec25SJerome Forissier return sign_buffer(out, out_sz, nonce, nonce_sz); 6107e05ec25SJerome Forissier } 6117e05ec25SJerome Forissier 6127e05ec25SJerome Forissier static TEE_Result cmd_hash_ta_memory(uint32_t param_types, 6137e05ec25SJerome Forissier TEE_Param params[TEE_NUM_PARAMS]) 6147e05ec25SJerome Forissier { 6157e05ec25SJerome Forissier uint8_t *nonce = params[0].memref.buffer; 6167e05ec25SJerome Forissier size_t nonce_sz = params[0].memref.size; 6177e05ec25SJerome Forissier uint8_t *out = params[1].memref.buffer; 6187e05ec25SJerome Forissier size_t out_sz = params[1].memref.size; 6197e05ec25SJerome Forissier struct user_mode_ctx *uctx = NULL; 6207e05ec25SJerome Forissier TEE_Result res = TEE_SUCCESS; 6217e05ec25SJerome Forissier struct ts_session *s = NULL; 6227e05ec25SJerome Forissier size_t min_out_sz = 0; 6237e05ec25SJerome Forissier 6247e05ec25SJerome Forissier if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 6257e05ec25SJerome Forissier TEE_PARAM_TYPE_MEMREF_OUTPUT, 6267e05ec25SJerome Forissier TEE_PARAM_TYPE_NONE, 6277e05ec25SJerome Forissier TEE_PARAM_TYPE_NONE)) 6287e05ec25SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 6297e05ec25SJerome Forissier 6307e05ec25SJerome Forissier if (!nonce || !nonce_sz) 6317e05ec25SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 6327e05ec25SJerome Forissier 6337e05ec25SJerome Forissier if (!out && out_sz) 6347e05ec25SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 6357e05ec25SJerome Forissier 6367e05ec25SJerome Forissier /* Check that we're called from a user TA */ 6377e05ec25SJerome Forissier s = ts_get_calling_session(); 6387e05ec25SJerome Forissier if (!s) 6397e05ec25SJerome Forissier return TEE_ERROR_ACCESS_DENIED; 6407e05ec25SJerome Forissier uctx = to_user_mode_ctx(s->ctx); 6417e05ec25SJerome Forissier if (!uctx) 6427e05ec25SJerome Forissier return TEE_ERROR_ACCESS_DENIED; 6437e05ec25SJerome Forissier 6447e05ec25SJerome Forissier res = init_key(); 6457e05ec25SJerome Forissier if (res) 6467e05ec25SJerome Forissier return res; 6477e05ec25SJerome Forissier 6487e05ec25SJerome Forissier min_out_sz = TEE_SHA256_HASH_SIZE + crypto_bignum_num_bytes(key->n); 6497e05ec25SJerome Forissier params[1].memref.size = min_out_sz; 6507e05ec25SJerome Forissier if (out_sz < min_out_sz) 6517e05ec25SJerome Forissier return TEE_ERROR_SHORT_BUFFER; 6527e05ec25SJerome Forissier out_sz = min_out_sz; 6537e05ec25SJerome Forissier 6547e05ec25SJerome Forissier s = ts_pop_current_session(); 6557e05ec25SJerome Forissier res = hash_regions(&uctx->vm_info, out); 6567e05ec25SJerome Forissier ts_push_current_session(s); 6577e05ec25SJerome Forissier if (res) 6587e05ec25SJerome Forissier return res; 6597e05ec25SJerome Forissier 6607e05ec25SJerome Forissier return sign_buffer(out, out_sz, nonce, nonce_sz); 6617e05ec25SJerome Forissier } 6627e05ec25SJerome Forissier 6637e05ec25SJerome Forissier static TEE_Result cmd_hash_tee_memory(uint32_t param_types, 6647e05ec25SJerome Forissier TEE_Param params[TEE_NUM_PARAMS]) 6657e05ec25SJerome Forissier { 6667e05ec25SJerome Forissier uint8_t *nonce = params[0].memref.buffer; 6677e05ec25SJerome Forissier size_t nonce_sz = params[0].memref.size; 6687e05ec25SJerome Forissier uint8_t *out = params[1].memref.buffer; 6697e05ec25SJerome Forissier size_t out_sz = params[1].memref.size; 6707e05ec25SJerome Forissier TEE_Result res = TEE_SUCCESS; 6717e05ec25SJerome Forissier size_t min_out_sz = 0; 6727e05ec25SJerome Forissier void *ctx = NULL; 6737e05ec25SJerome Forissier 6747e05ec25SJerome Forissier if (param_types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 6757e05ec25SJerome Forissier TEE_PARAM_TYPE_MEMREF_OUTPUT, 6767e05ec25SJerome Forissier TEE_PARAM_TYPE_NONE, 6777e05ec25SJerome Forissier TEE_PARAM_TYPE_NONE)) 6787e05ec25SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 6797e05ec25SJerome Forissier 6807e05ec25SJerome Forissier if (!nonce || !nonce_sz) 6817e05ec25SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 6827e05ec25SJerome Forissier 6837e05ec25SJerome Forissier if (!out && out_sz) 6847e05ec25SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 6857e05ec25SJerome Forissier 6867e05ec25SJerome Forissier res = init_key(); 6877e05ec25SJerome Forissier if (res) 6887e05ec25SJerome Forissier return res; 6897e05ec25SJerome Forissier 6907e05ec25SJerome Forissier min_out_sz = TEE_SHA256_HASH_SIZE + crypto_bignum_num_bytes(key->n); 6917e05ec25SJerome Forissier params[1].memref.size = min_out_sz; 6927e05ec25SJerome Forissier if (out_sz < min_out_sz) 6937e05ec25SJerome Forissier return TEE_ERROR_SHORT_BUFFER; 6947e05ec25SJerome Forissier out_sz = min_out_sz; 6957e05ec25SJerome Forissier 6967e05ec25SJerome Forissier res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SHA256); 6977e05ec25SJerome Forissier if (res) 6987e05ec25SJerome Forissier return res; 6997e05ec25SJerome Forissier res = crypto_hash_init(ctx); 7007e05ec25SJerome Forissier if (res) 7017e05ec25SJerome Forissier goto out; 7027e05ec25SJerome Forissier res = crypto_hash_update(ctx, __text_start, 7037e05ec25SJerome Forissier __text_data_start - __text_start); 7047e05ec25SJerome Forissier if (res) 7057e05ec25SJerome Forissier goto out; 7067e05ec25SJerome Forissier res = crypto_hash_update(ctx, __text_data_end, 7077e05ec25SJerome Forissier __text_end - __text_data_end); 7087e05ec25SJerome Forissier if (IS_ENABLED(CFG_WITH_PAGER)) { 7097e05ec25SJerome Forissier res = crypto_hash_update(ctx, __text_init_start, 7107e05ec25SJerome Forissier __text_init_end - __text_init_start); 7117e05ec25SJerome Forissier if (res) 7127e05ec25SJerome Forissier goto out; 7137e05ec25SJerome Forissier res = crypto_hash_update(ctx, __text_pageable_start, 7147e05ec25SJerome Forissier __text_pageable_end - 7157e05ec25SJerome Forissier __text_pageable_start); 7167e05ec25SJerome Forissier if (res) 7177e05ec25SJerome Forissier goto out; 7187e05ec25SJerome Forissier } 7197e05ec25SJerome Forissier if (res) 7207e05ec25SJerome Forissier goto out; 7217e05ec25SJerome Forissier res = crypto_hash_update(ctx, __rodata_start, 7227e05ec25SJerome Forissier __rodata_end - __rodata_start); 7237e05ec25SJerome Forissier if (res) 7247e05ec25SJerome Forissier goto out; 7257e05ec25SJerome Forissier if (IS_ENABLED(CFG_WITH_PAGER)) { 7267e05ec25SJerome Forissier res = crypto_hash_update(ctx, __rodata_init_start, 7277e05ec25SJerome Forissier __rodata_init_end - 7287e05ec25SJerome Forissier __rodata_init_start); 7297e05ec25SJerome Forissier if (res) 7307e05ec25SJerome Forissier goto out; 7317e05ec25SJerome Forissier res = crypto_hash_update(ctx, __rodata_pageable_start, 7327e05ec25SJerome Forissier __rodata_pageable_end - 7337e05ec25SJerome Forissier __rodata_pageable_start); 7347e05ec25SJerome Forissier if (res) 7357e05ec25SJerome Forissier goto out; 7367e05ec25SJerome Forissier } 7377e05ec25SJerome Forissier res = crypto_hash_final(ctx, out, TEE_SHA256_HASH_SIZE); 7387e05ec25SJerome Forissier if (res) 7397e05ec25SJerome Forissier goto out; 7407e05ec25SJerome Forissier 7417e05ec25SJerome Forissier DHEXDUMP(out, TEE_SHA256_HASH_SIZE); 7427e05ec25SJerome Forissier 7437e05ec25SJerome Forissier res = sign_buffer(out, out_sz, nonce, nonce_sz); 7447e05ec25SJerome Forissier out: 7457e05ec25SJerome Forissier crypto_hash_free_ctx(ctx); 7467e05ec25SJerome Forissier return res; 7477e05ec25SJerome Forissier } 7487e05ec25SJerome Forissier 7497e05ec25SJerome Forissier static TEE_Result invoke_command(void *sess_ctx __unused, uint32_t cmd_id, 7507e05ec25SJerome Forissier uint32_t param_types, 7517e05ec25SJerome Forissier TEE_Param params[TEE_NUM_PARAMS]) 7527e05ec25SJerome Forissier { 7537e05ec25SJerome Forissier switch (cmd_id) { 7547e05ec25SJerome Forissier case PTA_ATTESTATION_GET_PUBKEY: 7557e05ec25SJerome Forissier return cmd_get_pubkey(param_types, params); 7567e05ec25SJerome Forissier case PTA_ATTESTATION_GET_TA_SHDR_DIGEST: 7577e05ec25SJerome Forissier return cmd_get_ta_shdr_digest(param_types, params); 7587e05ec25SJerome Forissier case PTA_ATTESTATION_HASH_TA_MEMORY: 7597e05ec25SJerome Forissier return cmd_hash_ta_memory(param_types, params); 7607e05ec25SJerome Forissier case PTA_ATTESTATION_HASH_TEE_MEMORY: 7617e05ec25SJerome Forissier return cmd_hash_tee_memory(param_types, params); 7627e05ec25SJerome Forissier default: 7637e05ec25SJerome Forissier break; 7647e05ec25SJerome Forissier } 7657e05ec25SJerome Forissier return TEE_ERROR_BAD_PARAMETERS; 7667e05ec25SJerome Forissier } 7677e05ec25SJerome Forissier 7687e05ec25SJerome Forissier pseudo_ta_register(.uuid = PTA_ATTESTATION_UUID, .name = PTA_NAME, 7697e05ec25SJerome Forissier .flags = PTA_DEFAULT_FLAGS, 7707e05ec25SJerome Forissier .invoke_command_entry_point = invoke_command); 771