1*f86ab8e7SSumit Garg // SPDX-License-Identifier: BSD-2-Clause 2*f86ab8e7SSumit Garg /* 3*f86ab8e7SSumit Garg * Copyright (C) 2019-2020, Linaro Limited 4*f86ab8e7SSumit Garg */ 5*f86ab8e7SSumit Garg 6*f86ab8e7SSumit Garg #include <assert.h> 7*f86ab8e7SSumit Garg #include <pta_system.h> 8*f86ab8e7SSumit Garg #include <string.h> 9*f86ab8e7SSumit Garg #include <string_ext.h> 10*f86ab8e7SSumit Garg #include <tee_internal_api.h> 11*f86ab8e7SSumit Garg #include <tee_internal_api_extensions.h> 12*f86ab8e7SSumit Garg #include <trusted_keys.h> 13*f86ab8e7SSumit Garg #include <util.h> 14*f86ab8e7SSumit Garg 15*f86ab8e7SSumit Garg #define IV_SIZE 16 16*f86ab8e7SSumit Garg #define TAG_SIZE 16 17*f86ab8e7SSumit Garg #define MAX_BUF_SIZE 512 18*f86ab8e7SSumit Garg 19*f86ab8e7SSumit Garg /* 20*f86ab8e7SSumit Garg * Acronym: 21*f86ab8e7SSumit Garg * 22*f86ab8e7SSumit Garg * TK - Trusted Key 23*f86ab8e7SSumit Garg */ 24*f86ab8e7SSumit Garg 25*f86ab8e7SSumit Garg struct tk_blob_hdr { 26*f86ab8e7SSumit Garg uint8_t reserved; 27*f86ab8e7SSumit Garg uint8_t iv[IV_SIZE]; 28*f86ab8e7SSumit Garg uint8_t tag[TAG_SIZE]; 29*f86ab8e7SSumit Garg uint8_t enc_key[]; 30*f86ab8e7SSumit Garg }; 31*f86ab8e7SSumit Garg 32*f86ab8e7SSumit Garg static TEE_Result get_random(uint32_t types, TEE_Param params[TEE_NUM_PARAMS]) 33*f86ab8e7SSumit Garg { 34*f86ab8e7SSumit Garg DMSG("Invoked TA_CMD_GET_RANDOM"); 35*f86ab8e7SSumit Garg 36*f86ab8e7SSumit Garg if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT, 37*f86ab8e7SSumit Garg TEE_PARAM_TYPE_NONE, 38*f86ab8e7SSumit Garg TEE_PARAM_TYPE_NONE, 39*f86ab8e7SSumit Garg TEE_PARAM_TYPE_NONE)) 40*f86ab8e7SSumit Garg return TEE_ERROR_BAD_PARAMETERS; 41*f86ab8e7SSumit Garg 42*f86ab8e7SSumit Garg if (!params[0].memref.buffer || !params[0].memref.size) 43*f86ab8e7SSumit Garg return TEE_ERROR_BAD_PARAMETERS; 44*f86ab8e7SSumit Garg 45*f86ab8e7SSumit Garg TEE_GenerateRandom(params[0].memref.buffer, params[0].memref.size); 46*f86ab8e7SSumit Garg 47*f86ab8e7SSumit Garg return TEE_SUCCESS; 48*f86ab8e7SSumit Garg } 49*f86ab8e7SSumit Garg 50*f86ab8e7SSumit Garg static TEE_Result derive_unique_key(uint8_t *key, uint16_t key_size, 51*f86ab8e7SSumit Garg uint8_t *extra, uint16_t extra_size) 52*f86ab8e7SSumit Garg { 53*f86ab8e7SSumit Garg TEE_TASessionHandle sess = TEE_HANDLE_NULL; 54*f86ab8e7SSumit Garg TEE_Param params[TEE_NUM_PARAMS] = { }; 55*f86ab8e7SSumit Garg TEE_Result res = TEE_ERROR_GENERIC; 56*f86ab8e7SSumit Garg uint32_t ret_orig = 0; 57*f86ab8e7SSumit Garg uint32_t param_types = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 58*f86ab8e7SSumit Garg TEE_PARAM_TYPE_MEMREF_OUTPUT, 59*f86ab8e7SSumit Garg TEE_PARAM_TYPE_NONE, 60*f86ab8e7SSumit Garg TEE_PARAM_TYPE_NONE); 61*f86ab8e7SSumit Garg 62*f86ab8e7SSumit Garg res = TEE_OpenTASession(&(const TEE_UUID)PTA_SYSTEM_UUID, 63*f86ab8e7SSumit Garg TEE_TIMEOUT_INFINITE, 0, NULL, &sess, 64*f86ab8e7SSumit Garg &ret_orig); 65*f86ab8e7SSumit Garg if (res) 66*f86ab8e7SSumit Garg return res; 67*f86ab8e7SSumit Garg 68*f86ab8e7SSumit Garg if (extra && extra_size) { 69*f86ab8e7SSumit Garg params[0].memref.buffer = extra; 70*f86ab8e7SSumit Garg params[0].memref.size = extra_size; 71*f86ab8e7SSumit Garg } 72*f86ab8e7SSumit Garg 73*f86ab8e7SSumit Garg params[1].memref.buffer = key; 74*f86ab8e7SSumit Garg params[1].memref.size = key_size; 75*f86ab8e7SSumit Garg 76*f86ab8e7SSumit Garg res = TEE_InvokeTACommand(sess, TEE_TIMEOUT_INFINITE, 77*f86ab8e7SSumit Garg PTA_SYSTEM_DERIVE_TA_UNIQUE_KEY, 78*f86ab8e7SSumit Garg param_types, params, &ret_orig); 79*f86ab8e7SSumit Garg 80*f86ab8e7SSumit Garg TEE_CloseTASession(sess); 81*f86ab8e7SSumit Garg 82*f86ab8e7SSumit Garg return res; 83*f86ab8e7SSumit Garg } 84*f86ab8e7SSumit Garg 85*f86ab8e7SSumit Garg static TEE_Result huk_ae_encrypt(TEE_OperationHandle crypto_op, uint8_t *in, 86*f86ab8e7SSumit Garg uint32_t in_sz, uint8_t *out, uint32_t *out_sz) 87*f86ab8e7SSumit Garg { 88*f86ab8e7SSumit Garg TEE_Result res = TEE_ERROR_GENERIC; 89*f86ab8e7SSumit Garg struct tk_blob_hdr *hdr = (struct tk_blob_hdr *)out; 90*f86ab8e7SSumit Garg uint32_t enc_key_len = in_sz; 91*f86ab8e7SSumit Garg uint32_t tag_len = TAG_SIZE; 92*f86ab8e7SSumit Garg 93*f86ab8e7SSumit Garg hdr->reserved = 0; 94*f86ab8e7SSumit Garg TEE_GenerateRandom(hdr->iv, IV_SIZE); 95*f86ab8e7SSumit Garg 96*f86ab8e7SSumit Garg res = TEE_AEInit(crypto_op, hdr->iv, IV_SIZE, TAG_SIZE * 8, 0, 0); 97*f86ab8e7SSumit Garg if (res) 98*f86ab8e7SSumit Garg return res; 99*f86ab8e7SSumit Garg 100*f86ab8e7SSumit Garg res = TEE_AEEncryptFinal(crypto_op, in, in_sz, hdr->enc_key, 101*f86ab8e7SSumit Garg &enc_key_len, hdr->tag, &tag_len); 102*f86ab8e7SSumit Garg if (res || tag_len != TAG_SIZE) 103*f86ab8e7SSumit Garg return TEE_ERROR_SECURITY; 104*f86ab8e7SSumit Garg 105*f86ab8e7SSumit Garg if (ADD_OVERFLOW(enc_key_len, sizeof(*hdr), out_sz)) 106*f86ab8e7SSumit Garg return TEE_ERROR_SECURITY; 107*f86ab8e7SSumit Garg 108*f86ab8e7SSumit Garg return res; 109*f86ab8e7SSumit Garg } 110*f86ab8e7SSumit Garg 111*f86ab8e7SSumit Garg static TEE_Result huk_ae_decrypt(TEE_OperationHandle crypto_op, uint8_t *in, 112*f86ab8e7SSumit Garg uint32_t in_sz, uint8_t *out, uint32_t *out_sz) 113*f86ab8e7SSumit Garg { 114*f86ab8e7SSumit Garg TEE_Result res = TEE_ERROR_GENERIC; 115*f86ab8e7SSumit Garg struct tk_blob_hdr *hdr = (struct tk_blob_hdr *)in; 116*f86ab8e7SSumit Garg uint32_t enc_key_len = 0; 117*f86ab8e7SSumit Garg 118*f86ab8e7SSumit Garg if (SUB_OVERFLOW(in_sz, sizeof(*hdr), &enc_key_len)) 119*f86ab8e7SSumit Garg return TEE_ERROR_SECURITY; 120*f86ab8e7SSumit Garg 121*f86ab8e7SSumit Garg res = TEE_AEInit(crypto_op, hdr->iv, IV_SIZE, TAG_SIZE * 8, 0, 0); 122*f86ab8e7SSumit Garg if (res) 123*f86ab8e7SSumit Garg return res; 124*f86ab8e7SSumit Garg 125*f86ab8e7SSumit Garg res = TEE_AEDecryptFinal(crypto_op, hdr->enc_key, enc_key_len, out, 126*f86ab8e7SSumit Garg out_sz, hdr->tag, TAG_SIZE); 127*f86ab8e7SSumit Garg if (res) 128*f86ab8e7SSumit Garg res = TEE_ERROR_SECURITY; 129*f86ab8e7SSumit Garg 130*f86ab8e7SSumit Garg return res; 131*f86ab8e7SSumit Garg } 132*f86ab8e7SSumit Garg 133*f86ab8e7SSumit Garg static TEE_Result huk_crypt(TEE_OperationMode mode, uint8_t *in, uint32_t in_sz, 134*f86ab8e7SSumit Garg uint8_t *out, uint32_t *out_sz) 135*f86ab8e7SSumit Garg { 136*f86ab8e7SSumit Garg TEE_Result res = TEE_ERROR_GENERIC; 137*f86ab8e7SSumit Garg TEE_OperationHandle crypto_op = TEE_HANDLE_NULL; 138*f86ab8e7SSumit Garg TEE_ObjectHandle hkey = TEE_HANDLE_NULL; 139*f86ab8e7SSumit Garg uint8_t huk_key[TA_DERIVED_KEY_MAX_SIZE] = { }; 140*f86ab8e7SSumit Garg TEE_Attribute attr = { }; 141*f86ab8e7SSumit Garg 142*f86ab8e7SSumit Garg res = TEE_AllocateOperation(&crypto_op, TEE_ALG_AES_GCM, mode, 143*f86ab8e7SSumit Garg sizeof(huk_key) * 8); 144*f86ab8e7SSumit Garg if (res) 145*f86ab8e7SSumit Garg return res; 146*f86ab8e7SSumit Garg 147*f86ab8e7SSumit Garg res = derive_unique_key(huk_key, sizeof(huk_key), NULL, 0); 148*f86ab8e7SSumit Garg if (res) { 149*f86ab8e7SSumit Garg EMSG("derive_unique_key failed: returned %#"PRIx32, res); 150*f86ab8e7SSumit Garg goto out_op; 151*f86ab8e7SSumit Garg } 152*f86ab8e7SSumit Garg 153*f86ab8e7SSumit Garg res = TEE_AllocateTransientObject(TEE_TYPE_AES, sizeof(huk_key) * 8, 154*f86ab8e7SSumit Garg &hkey); 155*f86ab8e7SSumit Garg if (res) 156*f86ab8e7SSumit Garg goto out_op; 157*f86ab8e7SSumit Garg 158*f86ab8e7SSumit Garg attr.attributeID = TEE_ATTR_SECRET_VALUE; 159*f86ab8e7SSumit Garg attr.content.ref.buffer = huk_key; 160*f86ab8e7SSumit Garg attr.content.ref.length = sizeof(huk_key); 161*f86ab8e7SSumit Garg 162*f86ab8e7SSumit Garg res = TEE_PopulateTransientObject(hkey, &attr, 1); 163*f86ab8e7SSumit Garg if (res) 164*f86ab8e7SSumit Garg goto out_key; 165*f86ab8e7SSumit Garg 166*f86ab8e7SSumit Garg res = TEE_SetOperationKey(crypto_op, hkey); 167*f86ab8e7SSumit Garg if (res) 168*f86ab8e7SSumit Garg goto out_key; 169*f86ab8e7SSumit Garg 170*f86ab8e7SSumit Garg if (mode == TEE_MODE_ENCRYPT) { 171*f86ab8e7SSumit Garg res = huk_ae_encrypt(crypto_op, in, in_sz, out, out_sz); 172*f86ab8e7SSumit Garg if (res) 173*f86ab8e7SSumit Garg EMSG("huk_AE_encrypt failed: returned %#"PRIx32, res); 174*f86ab8e7SSumit Garg } else if (mode == TEE_MODE_DECRYPT) { 175*f86ab8e7SSumit Garg res = huk_ae_decrypt(crypto_op, in, in_sz, out, out_sz); 176*f86ab8e7SSumit Garg if (res) 177*f86ab8e7SSumit Garg EMSG("huk_AE_decrypt failed: returned %#"PRIx32, res); 178*f86ab8e7SSumit Garg } else { 179*f86ab8e7SSumit Garg TEE_Panic(0); 180*f86ab8e7SSumit Garg } 181*f86ab8e7SSumit Garg 182*f86ab8e7SSumit Garg out_key: 183*f86ab8e7SSumit Garg TEE_FreeTransientObject(hkey); 184*f86ab8e7SSumit Garg out_op: 185*f86ab8e7SSumit Garg TEE_FreeOperation(crypto_op); 186*f86ab8e7SSumit Garg memzero_explicit(huk_key, sizeof(huk_key)); 187*f86ab8e7SSumit Garg return res; 188*f86ab8e7SSumit Garg } 189*f86ab8e7SSumit Garg 190*f86ab8e7SSumit Garg static TEE_Result seal_trusted_key(uint32_t types, 191*f86ab8e7SSumit Garg TEE_Param params[TEE_NUM_PARAMS]) 192*f86ab8e7SSumit Garg { 193*f86ab8e7SSumit Garg TEE_Result res = TEE_SUCCESS; 194*f86ab8e7SSumit Garg uint8_t *in = NULL; 195*f86ab8e7SSumit Garg uint32_t in_sz = 0; 196*f86ab8e7SSumit Garg uint8_t *out = NULL; 197*f86ab8e7SSumit Garg uint32_t out_sz = 0; 198*f86ab8e7SSumit Garg 199*f86ab8e7SSumit Garg DMSG("Invoked TA_CMD_SEAL"); 200*f86ab8e7SSumit Garg 201*f86ab8e7SSumit Garg if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 202*f86ab8e7SSumit Garg TEE_PARAM_TYPE_MEMREF_OUTPUT, 203*f86ab8e7SSumit Garg TEE_PARAM_TYPE_NONE, 204*f86ab8e7SSumit Garg TEE_PARAM_TYPE_NONE)) 205*f86ab8e7SSumit Garg return TEE_ERROR_BAD_PARAMETERS; 206*f86ab8e7SSumit Garg 207*f86ab8e7SSumit Garg in = params[0].memref.buffer; 208*f86ab8e7SSumit Garg in_sz = params[0].memref.size; 209*f86ab8e7SSumit Garg out = params[1].memref.buffer; 210*f86ab8e7SSumit Garg out_sz = params[1].memref.size; 211*f86ab8e7SSumit Garg 212*f86ab8e7SSumit Garg if (!in || !in_sz || in_sz > MAX_BUF_SIZE) 213*f86ab8e7SSumit Garg return TEE_ERROR_BAD_PARAMETERS; 214*f86ab8e7SSumit Garg if ((!out && out_sz) || 215*f86ab8e7SSumit Garg (out && !ALIGNMENT_IS_OK(out, struct tk_blob_hdr)) || 216*f86ab8e7SSumit Garg out_sz > MAX_BUF_SIZE) 217*f86ab8e7SSumit Garg return TEE_ERROR_BAD_PARAMETERS; 218*f86ab8e7SSumit Garg 219*f86ab8e7SSumit Garg if ((in_sz + sizeof(struct tk_blob_hdr)) > out_sz) { 220*f86ab8e7SSumit Garg params[1].memref.size = in_sz + sizeof(struct tk_blob_hdr); 221*f86ab8e7SSumit Garg return TEE_ERROR_SHORT_BUFFER; 222*f86ab8e7SSumit Garg } 223*f86ab8e7SSumit Garg 224*f86ab8e7SSumit Garg res = huk_crypt(TEE_MODE_ENCRYPT, in, in_sz, out, &out_sz); 225*f86ab8e7SSumit Garg if (res == TEE_SUCCESS) { 226*f86ab8e7SSumit Garg assert(out_sz == in_sz + sizeof(struct tk_blob_hdr)); 227*f86ab8e7SSumit Garg params[1].memref.size = out_sz; 228*f86ab8e7SSumit Garg } 229*f86ab8e7SSumit Garg 230*f86ab8e7SSumit Garg return res; 231*f86ab8e7SSumit Garg } 232*f86ab8e7SSumit Garg 233*f86ab8e7SSumit Garg static TEE_Result unseal_trusted_key(uint32_t types, 234*f86ab8e7SSumit Garg TEE_Param params[TEE_NUM_PARAMS]) 235*f86ab8e7SSumit Garg { 236*f86ab8e7SSumit Garg TEE_Result res = TEE_SUCCESS; 237*f86ab8e7SSumit Garg uint8_t *in = NULL; 238*f86ab8e7SSumit Garg uint32_t in_sz = 0; 239*f86ab8e7SSumit Garg uint8_t *out = NULL; 240*f86ab8e7SSumit Garg uint32_t out_sz = 0; 241*f86ab8e7SSumit Garg 242*f86ab8e7SSumit Garg DMSG("Invoked TA_CMD_UNSEAL"); 243*f86ab8e7SSumit Garg 244*f86ab8e7SSumit Garg if (types != TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 245*f86ab8e7SSumit Garg TEE_PARAM_TYPE_MEMREF_OUTPUT, 246*f86ab8e7SSumit Garg TEE_PARAM_TYPE_NONE, 247*f86ab8e7SSumit Garg TEE_PARAM_TYPE_NONE)) 248*f86ab8e7SSumit Garg return TEE_ERROR_BAD_PARAMETERS; 249*f86ab8e7SSumit Garg 250*f86ab8e7SSumit Garg in = params[0].memref.buffer; 251*f86ab8e7SSumit Garg in_sz = params[0].memref.size; 252*f86ab8e7SSumit Garg out = params[1].memref.buffer; 253*f86ab8e7SSumit Garg out_sz = params[1].memref.size; 254*f86ab8e7SSumit Garg 255*f86ab8e7SSumit Garg if (!in || !ALIGNMENT_IS_OK(in, struct tk_blob_hdr) || 256*f86ab8e7SSumit Garg in_sz <= sizeof(struct tk_blob_hdr) || in_sz > MAX_BUF_SIZE) 257*f86ab8e7SSumit Garg return TEE_ERROR_BAD_PARAMETERS; 258*f86ab8e7SSumit Garg if ((!out && out_sz) || out_sz > MAX_BUF_SIZE) 259*f86ab8e7SSumit Garg return TEE_ERROR_BAD_PARAMETERS; 260*f86ab8e7SSumit Garg 261*f86ab8e7SSumit Garg if (in_sz > (out_sz + sizeof(struct tk_blob_hdr))) { 262*f86ab8e7SSumit Garg params[1].memref.size = in_sz - sizeof(struct tk_blob_hdr); 263*f86ab8e7SSumit Garg return TEE_ERROR_SHORT_BUFFER; 264*f86ab8e7SSumit Garg } 265*f86ab8e7SSumit Garg 266*f86ab8e7SSumit Garg res = huk_crypt(TEE_MODE_DECRYPT, in, in_sz, out, &out_sz); 267*f86ab8e7SSumit Garg if (res == TEE_SUCCESS) { 268*f86ab8e7SSumit Garg assert(out_sz == in_sz - sizeof(struct tk_blob_hdr)); 269*f86ab8e7SSumit Garg params[1].memref.size = out_sz; 270*f86ab8e7SSumit Garg } 271*f86ab8e7SSumit Garg 272*f86ab8e7SSumit Garg return res; 273*f86ab8e7SSumit Garg } 274*f86ab8e7SSumit Garg 275*f86ab8e7SSumit Garg TEE_Result TA_CreateEntryPoint(void) 276*f86ab8e7SSumit Garg { 277*f86ab8e7SSumit Garg return TEE_SUCCESS; 278*f86ab8e7SSumit Garg } 279*f86ab8e7SSumit Garg 280*f86ab8e7SSumit Garg void TA_DestroyEntryPoint(void) 281*f86ab8e7SSumit Garg { 282*f86ab8e7SSumit Garg } 283*f86ab8e7SSumit Garg 284*f86ab8e7SSumit Garg TEE_Result TA_OpenSessionEntryPoint(uint32_t pt __unused, 285*f86ab8e7SSumit Garg TEE_Param params[TEE_NUM_PARAMS] __unused, 286*f86ab8e7SSumit Garg void **session __unused) 287*f86ab8e7SSumit Garg { 288*f86ab8e7SSumit Garg TEE_Result res = TEE_ERROR_GENERIC; 289*f86ab8e7SSumit Garg TEE_PropSetHandle h = TEE_HANDLE_NULL; 290*f86ab8e7SSumit Garg TEE_Identity id = { }; 291*f86ab8e7SSumit Garg 292*f86ab8e7SSumit Garg res = TEE_AllocatePropertyEnumerator(&h); 293*f86ab8e7SSumit Garg if (res) 294*f86ab8e7SSumit Garg goto out; 295*f86ab8e7SSumit Garg 296*f86ab8e7SSumit Garg TEE_StartPropertyEnumerator(h, TEE_PROPSET_CURRENT_CLIENT); 297*f86ab8e7SSumit Garg 298*f86ab8e7SSumit Garg res = TEE_GetPropertyAsIdentity(h, NULL, &id); 299*f86ab8e7SSumit Garg if (res) 300*f86ab8e7SSumit Garg goto out; 301*f86ab8e7SSumit Garg 302*f86ab8e7SSumit Garg if (id.login != TEE_LOGIN_REE_KERNEL) 303*f86ab8e7SSumit Garg res = TEE_ERROR_ACCESS_DENIED; 304*f86ab8e7SSumit Garg 305*f86ab8e7SSumit Garg out: 306*f86ab8e7SSumit Garg if (h) 307*f86ab8e7SSumit Garg TEE_FreePropertyEnumerator(h); 308*f86ab8e7SSumit Garg return res; 309*f86ab8e7SSumit Garg } 310*f86ab8e7SSumit Garg 311*f86ab8e7SSumit Garg void TA_CloseSessionEntryPoint(void *sess __unused) 312*f86ab8e7SSumit Garg { 313*f86ab8e7SSumit Garg } 314*f86ab8e7SSumit Garg 315*f86ab8e7SSumit Garg TEE_Result TA_InvokeCommandEntryPoint(void *sess __unused, uint32_t cmd, 316*f86ab8e7SSumit Garg uint32_t pt, 317*f86ab8e7SSumit Garg TEE_Param params[TEE_NUM_PARAMS]) 318*f86ab8e7SSumit Garg { 319*f86ab8e7SSumit Garg switch (cmd) { 320*f86ab8e7SSumit Garg case TA_CMD_GET_RANDOM: 321*f86ab8e7SSumit Garg return get_random(pt, params); 322*f86ab8e7SSumit Garg case TA_CMD_SEAL: 323*f86ab8e7SSumit Garg return seal_trusted_key(pt, params); 324*f86ab8e7SSumit Garg case TA_CMD_UNSEAL: 325*f86ab8e7SSumit Garg return unseal_trusted_key(pt, params); 326*f86ab8e7SSumit Garg default: 327*f86ab8e7SSumit Garg EMSG("Command ID %#"PRIx32" is not supported", cmd); 328*f86ab8e7SSumit Garg return TEE_ERROR_NOT_SUPPORTED; 329*f86ab8e7SSumit Garg } 330*f86ab8e7SSumit Garg } 331