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