1*b0104773SPascal Brand /* 2*b0104773SPascal Brand * Copyright (c) 2014, STMicroelectronics International N.V. 3*b0104773SPascal Brand * All rights reserved. 4*b0104773SPascal Brand * 5*b0104773SPascal Brand * Redistribution and use in source and binary forms, with or without 6*b0104773SPascal Brand * modification, are permitted provided that the following conditions are met: 7*b0104773SPascal Brand * 8*b0104773SPascal Brand * 1. Redistributions of source code must retain the above copyright notice, 9*b0104773SPascal Brand * this list of conditions and the following disclaimer. 10*b0104773SPascal Brand * 11*b0104773SPascal Brand * 2. Redistributions in binary form must reproduce the above copyright notice, 12*b0104773SPascal Brand * this list of conditions and the following disclaimer in the documentation 13*b0104773SPascal Brand * and/or other materials provided with the distribution. 14*b0104773SPascal Brand * 15*b0104773SPascal Brand * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16*b0104773SPascal Brand * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*b0104773SPascal Brand * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*b0104773SPascal Brand * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19*b0104773SPascal Brand * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20*b0104773SPascal Brand * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21*b0104773SPascal Brand * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22*b0104773SPascal Brand * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23*b0104773SPascal Brand * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24*b0104773SPascal Brand * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25*b0104773SPascal Brand * POSSIBILITY OF SUCH DAMAGE. 26*b0104773SPascal Brand */ 27*b0104773SPascal Brand #include <stdlib.h> 28*b0104773SPascal Brand #include <string.h> 29*b0104773SPascal Brand 30*b0104773SPascal Brand #include <tee_api.h> 31*b0104773SPascal Brand #include <tee_internal_api_extensions.h> 32*b0104773SPascal Brand #include <utee_syscalls.h> 33*b0104773SPascal Brand #include <utee_defines.h> 34*b0104773SPascal Brand 35*b0104773SPascal Brand struct __TEE_OperationHandle { 36*b0104773SPascal Brand TEE_OperationInfo info; 37*b0104773SPascal Brand TEE_ObjectHandle key1; 38*b0104773SPascal Brand TEE_ObjectHandle key2; 39*b0104773SPascal Brand uint8_t *buffer; /* buffer to collect complete blocks */ 40*b0104773SPascal Brand bool buffer_two_blocks; /* True if two blocks need to be buffered */ 41*b0104773SPascal Brand size_t block_size; /* Block size of cipher */ 42*b0104773SPascal Brand size_t buffer_offs; /* Offset in buffer */ 43*b0104773SPascal Brand uint32_t state; /* Handle to state in TEE Core */ 44*b0104773SPascal Brand uint32_t ae_tag_len; /* 45*b0104773SPascal Brand * tag_len in bytes for AE operation else unused 46*b0104773SPascal Brand */ 47*b0104773SPascal Brand }; 48*b0104773SPascal Brand 49*b0104773SPascal Brand /* Cryptographic Operations API - Generic Operation Functions */ 50*b0104773SPascal Brand 51*b0104773SPascal Brand TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation, 52*b0104773SPascal Brand uint32_t algorithm, uint32_t mode, 53*b0104773SPascal Brand uint32_t maxKeySize) 54*b0104773SPascal Brand { 55*b0104773SPascal Brand TEE_Result res; 56*b0104773SPascal Brand TEE_OperationHandle op = TEE_HANDLE_NULL; 57*b0104773SPascal Brand uint32_t handle_state = 0; 58*b0104773SPascal Brand size_t block_size = 1; 59*b0104773SPascal Brand uint32_t req_key_usage; 60*b0104773SPascal Brand bool with_private_key = false; 61*b0104773SPascal Brand bool buffer_two_blocks = false; 62*b0104773SPascal Brand 63*b0104773SPascal Brand if (operation == NULL) 64*b0104773SPascal Brand TEE_Panic(0); 65*b0104773SPascal Brand 66*b0104773SPascal Brand if (algorithm == TEE_ALG_AES_XTS) 67*b0104773SPascal Brand handle_state = TEE_HANDLE_FLAG_EXPECT_TWO_KEYS; 68*b0104773SPascal Brand 69*b0104773SPascal Brand switch (algorithm) { 70*b0104773SPascal Brand case TEE_ALG_AES_CTS: 71*b0104773SPascal Brand case TEE_ALG_AES_XTS: 72*b0104773SPascal Brand buffer_two_blocks = true; 73*b0104773SPascal Brand /*FALLTHROUGH*/ case TEE_ALG_AES_ECB_NOPAD: 74*b0104773SPascal Brand case TEE_ALG_AES_CBC_NOPAD: 75*b0104773SPascal Brand case TEE_ALG_AES_CTR: 76*b0104773SPascal Brand case TEE_ALG_AES_CCM: 77*b0104773SPascal Brand case TEE_ALG_AES_GCM: 78*b0104773SPascal Brand case TEE_ALG_DES_ECB_NOPAD: 79*b0104773SPascal Brand case TEE_ALG_DES_CBC_NOPAD: 80*b0104773SPascal Brand case TEE_ALG_DES3_ECB_NOPAD: 81*b0104773SPascal Brand case TEE_ALG_DES3_CBC_NOPAD: 82*b0104773SPascal Brand if (TEE_ALG_GET_MAIN_ALG(algorithm) == TEE_MAIN_ALGO_AES) 83*b0104773SPascal Brand block_size = TEE_AES_BLOCK_SIZE; 84*b0104773SPascal Brand else 85*b0104773SPascal Brand block_size = TEE_DES_BLOCK_SIZE; 86*b0104773SPascal Brand 87*b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) 88*b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT; 89*b0104773SPascal Brand else if (mode == TEE_MODE_DECRYPT) 90*b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT; 91*b0104773SPascal Brand else 92*b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 93*b0104773SPascal Brand break; 94*b0104773SPascal Brand 95*b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_MD5: 96*b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1: 97*b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224: 98*b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256: 99*b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384: 100*b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512: 101*b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: 102*b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: 103*b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: 104*b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: 105*b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: 106*b0104773SPascal Brand case TEE_ALG_DSA_SHA1: 107*b0104773SPascal Brand if (mode == TEE_MODE_SIGN) { 108*b0104773SPascal Brand with_private_key = true; 109*b0104773SPascal Brand req_key_usage = TEE_USAGE_SIGN; 110*b0104773SPascal Brand } else if (mode == TEE_MODE_VERIFY) { 111*b0104773SPascal Brand req_key_usage = TEE_USAGE_VERIFY; 112*b0104773SPascal Brand } else { 113*b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 114*b0104773SPascal Brand } 115*b0104773SPascal Brand break; 116*b0104773SPascal Brand 117*b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_V1_5: 118*b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1: 119*b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224: 120*b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256: 121*b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384: 122*b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512: 123*b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) { 124*b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT; 125*b0104773SPascal Brand } else if (mode == TEE_MODE_DECRYPT) { 126*b0104773SPascal Brand with_private_key = true; 127*b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT; 128*b0104773SPascal Brand } else { 129*b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 130*b0104773SPascal Brand } 131*b0104773SPascal Brand break; 132*b0104773SPascal Brand 133*b0104773SPascal Brand case TEE_ALG_RSA_NOPAD: 134*b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) { 135*b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT | TEE_USAGE_VERIFY; 136*b0104773SPascal Brand } else if (mode == TEE_MODE_DECRYPT) { 137*b0104773SPascal Brand with_private_key = true; 138*b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT | TEE_USAGE_SIGN; 139*b0104773SPascal Brand } else { 140*b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 141*b0104773SPascal Brand } 142*b0104773SPascal Brand break; 143*b0104773SPascal Brand 144*b0104773SPascal Brand case TEE_ALG_DH_DERIVE_SHARED_SECRET: 145*b0104773SPascal Brand if (mode != TEE_MODE_DERIVE) 146*b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 147*b0104773SPascal Brand with_private_key = true; 148*b0104773SPascal Brand req_key_usage = TEE_USAGE_DERIVE; 149*b0104773SPascal Brand break; 150*b0104773SPascal Brand 151*b0104773SPascal Brand case TEE_ALG_MD5: 152*b0104773SPascal Brand case TEE_ALG_SHA1: 153*b0104773SPascal Brand case TEE_ALG_SHA224: 154*b0104773SPascal Brand case TEE_ALG_SHA256: 155*b0104773SPascal Brand case TEE_ALG_SHA384: 156*b0104773SPascal Brand case TEE_ALG_SHA512: 157*b0104773SPascal Brand if (mode != TEE_MODE_DIGEST) 158*b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 159*b0104773SPascal Brand handle_state |= TEE_HANDLE_FLAG_KEY_SET; 160*b0104773SPascal Brand req_key_usage = 0; 161*b0104773SPascal Brand break; 162*b0104773SPascal Brand 163*b0104773SPascal Brand case TEE_ALG_DES_CBC_MAC_NOPAD: 164*b0104773SPascal Brand case TEE_ALG_AES_CBC_MAC_NOPAD: 165*b0104773SPascal Brand case TEE_ALG_AES_CBC_MAC_PKCS5: 166*b0104773SPascal Brand case TEE_ALG_AES_CMAC: 167*b0104773SPascal Brand case TEE_ALG_DES_CBC_MAC_PKCS5: 168*b0104773SPascal Brand case TEE_ALG_DES3_CBC_MAC_NOPAD: 169*b0104773SPascal Brand case TEE_ALG_DES3_CBC_MAC_PKCS5: 170*b0104773SPascal Brand case TEE_ALG_HMAC_MD5: 171*b0104773SPascal Brand case TEE_ALG_HMAC_SHA1: 172*b0104773SPascal Brand case TEE_ALG_HMAC_SHA224: 173*b0104773SPascal Brand case TEE_ALG_HMAC_SHA256: 174*b0104773SPascal Brand case TEE_ALG_HMAC_SHA384: 175*b0104773SPascal Brand case TEE_ALG_HMAC_SHA512: 176*b0104773SPascal Brand if (mode != TEE_MODE_MAC) 177*b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 178*b0104773SPascal Brand req_key_usage = TEE_USAGE_MAC; 179*b0104773SPascal Brand break; 180*b0104773SPascal Brand 181*b0104773SPascal Brand default: 182*b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 183*b0104773SPascal Brand } 184*b0104773SPascal Brand 185*b0104773SPascal Brand op = TEE_Malloc(sizeof(*op), 0); 186*b0104773SPascal Brand if (op == NULL) 187*b0104773SPascal Brand return TEE_ERROR_OUT_OF_MEMORY; 188*b0104773SPascal Brand 189*b0104773SPascal Brand op->info.algorithm = algorithm; 190*b0104773SPascal Brand op->info.operationClass = TEE_ALG_GET_CLASS(algorithm); 191*b0104773SPascal Brand op->info.mode = mode; 192*b0104773SPascal Brand op->info.maxKeySize = maxKeySize; 193*b0104773SPascal Brand op->info.requiredKeyUsage = req_key_usage; 194*b0104773SPascal Brand op->info.handleState = handle_state; 195*b0104773SPascal Brand 196*b0104773SPascal Brand if (block_size > 1) { 197*b0104773SPascal Brand size_t buffer_size = block_size; 198*b0104773SPascal Brand 199*b0104773SPascal Brand if (buffer_two_blocks) 200*b0104773SPascal Brand buffer_size *= 2; 201*b0104773SPascal Brand 202*b0104773SPascal Brand op->buffer = 203*b0104773SPascal Brand TEE_Malloc(buffer_size, TEE_USER_MEM_HINT_NO_FILL_ZERO); 204*b0104773SPascal Brand if (op->buffer == NULL) { 205*b0104773SPascal Brand res = TEE_ERROR_OUT_OF_MEMORY; 206*b0104773SPascal Brand goto out; 207*b0104773SPascal Brand } 208*b0104773SPascal Brand } 209*b0104773SPascal Brand op->block_size = block_size; 210*b0104773SPascal Brand op->buffer_two_blocks = buffer_two_blocks; 211*b0104773SPascal Brand 212*b0104773SPascal Brand if (TEE_ALG_GET_CLASS(algorithm) != TEE_OPERATION_DIGEST) { 213*b0104773SPascal Brand uint32_t mks = maxKeySize; 214*b0104773SPascal Brand TEE_ObjectType key_type = TEE_ALG_GET_KEY_TYPE(algorithm, 215*b0104773SPascal Brand with_private_key); 216*b0104773SPascal Brand 217*b0104773SPascal Brand /* 218*b0104773SPascal Brand * If two keys are expected the max key size is the sum of 219*b0104773SPascal Brand * the size of both keys. 220*b0104773SPascal Brand */ 221*b0104773SPascal Brand if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) 222*b0104773SPascal Brand mks /= 2; 223*b0104773SPascal Brand 224*b0104773SPascal Brand res = TEE_AllocateTransientObject(key_type, mks, &op->key1); 225*b0104773SPascal Brand if (res != TEE_SUCCESS) 226*b0104773SPascal Brand goto out; 227*b0104773SPascal Brand 228*b0104773SPascal Brand if ((op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) != 229*b0104773SPascal Brand 0) { 230*b0104773SPascal Brand res = 231*b0104773SPascal Brand TEE_AllocateTransientObject(key_type, mks, 232*b0104773SPascal Brand &op->key2); 233*b0104773SPascal Brand if (res != TEE_SUCCESS) 234*b0104773SPascal Brand goto out; 235*b0104773SPascal Brand } 236*b0104773SPascal Brand } 237*b0104773SPascal Brand 238*b0104773SPascal Brand res = utee_cryp_state_alloc(algorithm, mode, (uint32_t) op->key1, 239*b0104773SPascal Brand (uint32_t) op->key2, &op->state); 240*b0104773SPascal Brand if (res != TEE_SUCCESS) 241*b0104773SPascal Brand goto out; 242*b0104773SPascal Brand 243*b0104773SPascal Brand /* For multi-stage operation do an "init". */ 244*b0104773SPascal Brand TEE_ResetOperation(op); 245*b0104773SPascal Brand *operation = op; 246*b0104773SPascal Brand 247*b0104773SPascal Brand out: 248*b0104773SPascal Brand if (res != TEE_SUCCESS) { 249*b0104773SPascal Brand TEE_FreeTransientObject(op->key1); 250*b0104773SPascal Brand TEE_FreeTransientObject(op->key2); 251*b0104773SPascal Brand TEE_FreeOperation(op); 252*b0104773SPascal Brand } 253*b0104773SPascal Brand 254*b0104773SPascal Brand return res; 255*b0104773SPascal Brand } 256*b0104773SPascal Brand 257*b0104773SPascal Brand void TEE_FreeOperation(TEE_OperationHandle operation) 258*b0104773SPascal Brand { 259*b0104773SPascal Brand if (operation != TEE_HANDLE_NULL) { 260*b0104773SPascal Brand /* 261*b0104773SPascal Brand * Note that keys should not be freed here, since they are 262*b0104773SPascal Brand * claimed by the operation they will be freed by 263*b0104773SPascal Brand * utee_cryp_state_free(). 264*b0104773SPascal Brand */ 265*b0104773SPascal Brand utee_cryp_state_free(operation->state); 266*b0104773SPascal Brand TEE_Free(operation->buffer); 267*b0104773SPascal Brand TEE_Free(operation); 268*b0104773SPascal Brand } 269*b0104773SPascal Brand } 270*b0104773SPascal Brand 271*b0104773SPascal Brand void TEE_GetOperationInfo(TEE_OperationHandle operation, 272*b0104773SPascal Brand TEE_OperationInfo *operationInfo) 273*b0104773SPascal Brand { 274*b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 275*b0104773SPascal Brand TEE_Panic(0); 276*b0104773SPascal Brand 277*b0104773SPascal Brand if (operationInfo == NULL) 278*b0104773SPascal Brand TEE_Panic(0); 279*b0104773SPascal Brand 280*b0104773SPascal Brand *operationInfo = operation->info; 281*b0104773SPascal Brand } 282*b0104773SPascal Brand 283*b0104773SPascal Brand void TEE_ResetOperation(TEE_OperationHandle operation) 284*b0104773SPascal Brand { 285*b0104773SPascal Brand TEE_Result res; 286*b0104773SPascal Brand 287*b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 288*b0104773SPascal Brand TEE_Panic(0); 289*b0104773SPascal Brand if (operation->info.operationClass == TEE_OPERATION_DIGEST) { 290*b0104773SPascal Brand res = utee_hash_init(operation->state, NULL, 0); 291*b0104773SPascal Brand if (res != TEE_SUCCESS) 292*b0104773SPascal Brand TEE_Panic(res); 293*b0104773SPascal Brand } 294*b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 295*b0104773SPascal Brand } 296*b0104773SPascal Brand 297*b0104773SPascal Brand TEE_Result TEE_SetOperationKey(TEE_OperationHandle operation, 298*b0104773SPascal Brand TEE_ObjectHandle key) 299*b0104773SPascal Brand { 300*b0104773SPascal Brand uint32_t key_size = 0; 301*b0104773SPascal Brand 302*b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 303*b0104773SPascal Brand TEE_Panic(0); 304*b0104773SPascal Brand 305*b0104773SPascal Brand /* No key for digests */ 306*b0104773SPascal Brand if (operation->info.operationClass == TEE_OPERATION_DIGEST) 307*b0104773SPascal Brand TEE_Panic(0); 308*b0104773SPascal Brand 309*b0104773SPascal Brand /* Two keys expected */ 310*b0104773SPascal Brand if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) != 311*b0104773SPascal Brand 0) 312*b0104773SPascal Brand TEE_Panic(0); 313*b0104773SPascal Brand 314*b0104773SPascal Brand if (key != TEE_HANDLE_NULL) { 315*b0104773SPascal Brand TEE_ObjectInfo key_info; 316*b0104773SPascal Brand 317*b0104773SPascal Brand TEE_GetObjectInfo(key, &key_info); 318*b0104773SPascal Brand /* Supplied key has to meet required usage */ 319*b0104773SPascal Brand if ((key_info.objectUsage & operation->info.requiredKeyUsage) != 320*b0104773SPascal Brand operation->info.requiredKeyUsage) { 321*b0104773SPascal Brand TEE_Panic(0); 322*b0104773SPascal Brand } 323*b0104773SPascal Brand 324*b0104773SPascal Brand if (operation->info.maxKeySize < key_info.objectSize) 325*b0104773SPascal Brand TEE_Panic(0); 326*b0104773SPascal Brand 327*b0104773SPascal Brand key_size = key_info.objectSize; 328*b0104773SPascal Brand } 329*b0104773SPascal Brand 330*b0104773SPascal Brand TEE_ResetTransientObject(operation->key1); 331*b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 332*b0104773SPascal Brand 333*b0104773SPascal Brand if (key != TEE_HANDLE_NULL) { 334*b0104773SPascal Brand TEE_CopyObjectAttributes(operation->key1, key); 335*b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET; 336*b0104773SPascal Brand } 337*b0104773SPascal Brand 338*b0104773SPascal Brand operation->info.keySize = key_size; 339*b0104773SPascal Brand 340*b0104773SPascal Brand return TEE_SUCCESS; 341*b0104773SPascal Brand } 342*b0104773SPascal Brand 343*b0104773SPascal Brand TEE_Result TEE_SetOperationKey2(TEE_OperationHandle operation, 344*b0104773SPascal Brand TEE_ObjectHandle key1, TEE_ObjectHandle key2) 345*b0104773SPascal Brand { 346*b0104773SPascal Brand uint32_t key_size = 0; 347*b0104773SPascal Brand 348*b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 349*b0104773SPascal Brand TEE_Panic(0); 350*b0104773SPascal Brand 351*b0104773SPascal Brand /* Two keys not expected */ 352*b0104773SPascal Brand if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 353*b0104773SPascal Brand 0) 354*b0104773SPascal Brand TEE_Panic(0); 355*b0104773SPascal Brand 356*b0104773SPascal Brand /* Either both keys are NULL or both are not NULL */ 357*b0104773SPascal Brand if ((key1 == TEE_HANDLE_NULL || key2 == TEE_HANDLE_NULL) && 358*b0104773SPascal Brand key1 != key2) 359*b0104773SPascal Brand TEE_Panic(0); 360*b0104773SPascal Brand 361*b0104773SPascal Brand if (key1 != TEE_HANDLE_NULL) { 362*b0104773SPascal Brand TEE_ObjectInfo key_info1; 363*b0104773SPascal Brand TEE_ObjectInfo key_info2; 364*b0104773SPascal Brand 365*b0104773SPascal Brand TEE_GetObjectInfo(key1, &key_info1); 366*b0104773SPascal Brand /* Supplied key has to meet required usage */ 367*b0104773SPascal Brand if ((key_info1.objectUsage & operation->info. 368*b0104773SPascal Brand requiredKeyUsage) != operation->info.requiredKeyUsage) { 369*b0104773SPascal Brand TEE_Panic(0); 370*b0104773SPascal Brand } 371*b0104773SPascal Brand 372*b0104773SPascal Brand TEE_GetObjectInfo(key2, &key_info2); 373*b0104773SPascal Brand /* Supplied key has to meet required usage */ 374*b0104773SPascal Brand if ((key_info2.objectUsage & operation->info. 375*b0104773SPascal Brand requiredKeyUsage) != operation->info.requiredKeyUsage) { 376*b0104773SPascal Brand TEE_Panic(0); 377*b0104773SPascal Brand } 378*b0104773SPascal Brand 379*b0104773SPascal Brand /* 380*b0104773SPascal Brand * AES-XTS (the only multi key algorithm supported, requires the 381*b0104773SPascal Brand * keys to be of equal size. 382*b0104773SPascal Brand */ 383*b0104773SPascal Brand if (operation->info.algorithm == TEE_ALG_AES_XTS && 384*b0104773SPascal Brand key_info1.objectSize != key_info2.objectSize) 385*b0104773SPascal Brand TEE_Panic(0); 386*b0104773SPascal Brand 387*b0104773SPascal Brand if (operation->info.maxKeySize < key_info1.objectSize) 388*b0104773SPascal Brand TEE_Panic(0); 389*b0104773SPascal Brand 390*b0104773SPascal Brand /* 391*b0104773SPascal Brand * Odd that only the size of one key should be reported while 392*b0104773SPascal Brand * size of two key are used when allocating the operation. 393*b0104773SPascal Brand */ 394*b0104773SPascal Brand key_size = key_info1.objectSize; 395*b0104773SPascal Brand } 396*b0104773SPascal Brand 397*b0104773SPascal Brand TEE_ResetTransientObject(operation->key1); 398*b0104773SPascal Brand TEE_ResetTransientObject(operation->key2); 399*b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 400*b0104773SPascal Brand 401*b0104773SPascal Brand if (key1 != TEE_HANDLE_NULL) { 402*b0104773SPascal Brand TEE_CopyObjectAttributes(operation->key1, key1); 403*b0104773SPascal Brand TEE_CopyObjectAttributes(operation->key2, key2); 404*b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET; 405*b0104773SPascal Brand } 406*b0104773SPascal Brand 407*b0104773SPascal Brand operation->info.keySize = key_size; 408*b0104773SPascal Brand 409*b0104773SPascal Brand return TEE_SUCCESS; 410*b0104773SPascal Brand } 411*b0104773SPascal Brand 412*b0104773SPascal Brand void TEE_CopyOperation(TEE_OperationHandle dst_op, TEE_OperationHandle src_op) 413*b0104773SPascal Brand { 414*b0104773SPascal Brand TEE_Result res; 415*b0104773SPascal Brand 416*b0104773SPascal Brand if (dst_op == TEE_HANDLE_NULL || src_op == TEE_HANDLE_NULL) 417*b0104773SPascal Brand TEE_Panic(0); 418*b0104773SPascal Brand if (dst_op->info.algorithm != src_op->info.algorithm) 419*b0104773SPascal Brand TEE_Panic(0); 420*b0104773SPascal Brand if (src_op->info.operationClass != TEE_OPERATION_DIGEST) { 421*b0104773SPascal Brand TEE_ObjectHandle key1 = TEE_HANDLE_NULL; 422*b0104773SPascal Brand TEE_ObjectHandle key2 = TEE_HANDLE_NULL; 423*b0104773SPascal Brand 424*b0104773SPascal Brand if (src_op->info.handleState & TEE_HANDLE_FLAG_KEY_SET) { 425*b0104773SPascal Brand key1 = src_op->key1; 426*b0104773SPascal Brand key2 = src_op->key2; 427*b0104773SPascal Brand } 428*b0104773SPascal Brand 429*b0104773SPascal Brand if ((src_op->info.handleState & 430*b0104773SPascal Brand TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 0) { 431*b0104773SPascal Brand TEE_SetOperationKey(dst_op, key1); 432*b0104773SPascal Brand } else { 433*b0104773SPascal Brand TEE_SetOperationKey2(dst_op, key1, key2); 434*b0104773SPascal Brand } 435*b0104773SPascal Brand } 436*b0104773SPascal Brand dst_op->info.handleState = src_op->info.handleState; 437*b0104773SPascal Brand dst_op->info.keySize = src_op->info.keySize; 438*b0104773SPascal Brand 439*b0104773SPascal Brand if (dst_op->buffer_two_blocks != src_op->buffer_two_blocks || 440*b0104773SPascal Brand dst_op->block_size != src_op->block_size) 441*b0104773SPascal Brand TEE_Panic(0); 442*b0104773SPascal Brand 443*b0104773SPascal Brand if (dst_op->buffer != NULL) { 444*b0104773SPascal Brand if (src_op->buffer == NULL) 445*b0104773SPascal Brand TEE_Panic(0); 446*b0104773SPascal Brand 447*b0104773SPascal Brand memcpy(dst_op->buffer, src_op->buffer, src_op->buffer_offs); 448*b0104773SPascal Brand dst_op->buffer_offs = src_op->buffer_offs; 449*b0104773SPascal Brand } else if (src_op->buffer != NULL) { 450*b0104773SPascal Brand TEE_Panic(0); 451*b0104773SPascal Brand } 452*b0104773SPascal Brand 453*b0104773SPascal Brand res = utee_cryp_state_copy(dst_op->state, src_op->state); 454*b0104773SPascal Brand if (res != TEE_SUCCESS) 455*b0104773SPascal Brand TEE_Panic(res); 456*b0104773SPascal Brand } 457*b0104773SPascal Brand 458*b0104773SPascal Brand /* Cryptographic Operations API - Message Digest Functions */ 459*b0104773SPascal Brand 460*b0104773SPascal Brand void TEE_DigestUpdate(TEE_OperationHandle operation, 461*b0104773SPascal Brand void *chunk, size_t chunkSize) 462*b0104773SPascal Brand { 463*b0104773SPascal Brand TEE_Result res; 464*b0104773SPascal Brand 465*b0104773SPascal Brand if (operation == TEE_HANDLE_NULL || chunk == NULL) 466*b0104773SPascal Brand TEE_Panic(0); 467*b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_DIGEST) 468*b0104773SPascal Brand TEE_Panic(0); 469*b0104773SPascal Brand res = utee_hash_update(operation->state, chunk, chunkSize); 470*b0104773SPascal Brand if (res != TEE_SUCCESS) 471*b0104773SPascal Brand TEE_Panic(res); 472*b0104773SPascal Brand } 473*b0104773SPascal Brand 474*b0104773SPascal Brand TEE_Result TEE_DigestDoFinal(TEE_OperationHandle operation, const void *chunk, 475*b0104773SPascal Brand size_t chunkLen, void *hash, size_t *hashLen) 476*b0104773SPascal Brand { 477*b0104773SPascal Brand if (operation == TEE_HANDLE_NULL || (chunk == NULL && chunkLen != 0) || 478*b0104773SPascal Brand hash == NULL || hashLen == NULL) 479*b0104773SPascal Brand TEE_Panic(0); 480*b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_DIGEST) 481*b0104773SPascal Brand TEE_Panic(0); 482*b0104773SPascal Brand return utee_hash_final(operation->state, chunk, chunkLen, hash, 483*b0104773SPascal Brand hashLen); 484*b0104773SPascal Brand } 485*b0104773SPascal Brand 486*b0104773SPascal Brand /* Cryptographic Operations API - Symmetric Cipher Functions */ 487*b0104773SPascal Brand 488*b0104773SPascal Brand void TEE_CipherInit(TEE_OperationHandle operation, const void *IV, size_t IVLen) 489*b0104773SPascal Brand { 490*b0104773SPascal Brand TEE_Result res; 491*b0104773SPascal Brand 492*b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 493*b0104773SPascal Brand TEE_Panic(0); 494*b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_CIPHER) 495*b0104773SPascal Brand TEE_Panic(0); 496*b0104773SPascal Brand res = utee_cipher_init(operation->state, IV, IVLen); 497*b0104773SPascal Brand if (res != TEE_SUCCESS) 498*b0104773SPascal Brand TEE_Panic(res); 499*b0104773SPascal Brand operation->buffer_offs = 0; 500*b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 501*b0104773SPascal Brand } 502*b0104773SPascal Brand 503*b0104773SPascal Brand static TEE_Result tee_buffer_update( 504*b0104773SPascal Brand TEE_OperationHandle op, 505*b0104773SPascal Brand TEE_Result(*update_func) (uint32_t state, const void *src, 506*b0104773SPascal Brand size_t slen, void *dst, size_t *dlen), 507*b0104773SPascal Brand const void *src_data, size_t src_len, 508*b0104773SPascal Brand void *dest_data, size_t *dest_len) 509*b0104773SPascal Brand { 510*b0104773SPascal Brand TEE_Result res; 511*b0104773SPascal Brand const uint8_t *src = src_data; 512*b0104773SPascal Brand size_t slen = src_len; 513*b0104773SPascal Brand uint8_t *dst = dest_data; 514*b0104773SPascal Brand size_t dlen = *dest_len; 515*b0104773SPascal Brand size_t acc_dlen = 0; 516*b0104773SPascal Brand size_t tmp_dlen; 517*b0104773SPascal Brand size_t l; 518*b0104773SPascal Brand size_t buffer_size; 519*b0104773SPascal Brand 520*b0104773SPascal Brand if (op->buffer_two_blocks) 521*b0104773SPascal Brand buffer_size = op->block_size * 2; 522*b0104773SPascal Brand else 523*b0104773SPascal Brand buffer_size = op->block_size; 524*b0104773SPascal Brand 525*b0104773SPascal Brand if (op->buffer_offs > 0) { 526*b0104773SPascal Brand /* Fill up complete block */ 527*b0104773SPascal Brand if (op->buffer_offs < op->block_size) 528*b0104773SPascal Brand l = MIN(slen, op->block_size - op->buffer_offs); 529*b0104773SPascal Brand else 530*b0104773SPascal Brand l = MIN(slen, buffer_size - op->buffer_offs); 531*b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, l); 532*b0104773SPascal Brand op->buffer_offs += l; 533*b0104773SPascal Brand src += l; 534*b0104773SPascal Brand slen -= l; 535*b0104773SPascal Brand if ((op->buffer_offs % op->block_size) != 0) 536*b0104773SPascal Brand goto out; /* Nothing left to do */ 537*b0104773SPascal Brand } 538*b0104773SPascal Brand 539*b0104773SPascal Brand /* If we can feed from buffer */ 540*b0104773SPascal Brand if (op->buffer_offs > 0 && (op->buffer_offs + slen) > buffer_size) { 541*b0104773SPascal Brand l = TEE_ROUNDUP(op->buffer_offs + slen - buffer_size, 542*b0104773SPascal Brand op->block_size); 543*b0104773SPascal Brand l = MIN(op->buffer_offs, l); 544*b0104773SPascal Brand tmp_dlen = dlen; 545*b0104773SPascal Brand res = update_func(op->state, op->buffer, l, dst, &tmp_dlen); 546*b0104773SPascal Brand if (res != TEE_SUCCESS) 547*b0104773SPascal Brand TEE_Panic(res); 548*b0104773SPascal Brand dst += tmp_dlen; 549*b0104773SPascal Brand dlen -= tmp_dlen; 550*b0104773SPascal Brand acc_dlen += tmp_dlen; 551*b0104773SPascal Brand op->buffer_offs -= l; 552*b0104773SPascal Brand if (op->buffer_offs > 0) { 553*b0104773SPascal Brand /* 554*b0104773SPascal Brand * Slen is small enough to be contained in rest buffer. 555*b0104773SPascal Brand */ 556*b0104773SPascal Brand memcpy(op->buffer, op->buffer + l, buffer_size - l); 557*b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, slen); 558*b0104773SPascal Brand op->buffer_offs += slen; 559*b0104773SPascal Brand goto out; /* Nothing left to do */ 560*b0104773SPascal Brand } 561*b0104773SPascal Brand } 562*b0104773SPascal Brand 563*b0104773SPascal Brand if (slen > buffer_size) { 564*b0104773SPascal Brand /* Buffer is empty, feed as much as possible from src */ 565*b0104773SPascal Brand if (TEE_ALIGNMENT_IS_OK(src, uint32_t)) { 566*b0104773SPascal Brand l = TEE_ROUNDUP(slen - buffer_size + 1, op->block_size); 567*b0104773SPascal Brand 568*b0104773SPascal Brand tmp_dlen = dlen; 569*b0104773SPascal Brand res = update_func(op->state, src, l, dst, &tmp_dlen); 570*b0104773SPascal Brand if (res != TEE_SUCCESS) 571*b0104773SPascal Brand TEE_Panic(res); 572*b0104773SPascal Brand src += l; 573*b0104773SPascal Brand slen -= l; 574*b0104773SPascal Brand dst += tmp_dlen; 575*b0104773SPascal Brand dlen -= tmp_dlen; 576*b0104773SPascal Brand acc_dlen += tmp_dlen; 577*b0104773SPascal Brand } else { 578*b0104773SPascal Brand /* 579*b0104773SPascal Brand * Supplied data isn't well aligned, we're forced to 580*b0104773SPascal Brand * feed through the buffer. 581*b0104773SPascal Brand */ 582*b0104773SPascal Brand while (slen >= op->block_size) { 583*b0104773SPascal Brand memcpy(op->buffer, src, op->block_size); 584*b0104773SPascal Brand 585*b0104773SPascal Brand tmp_dlen = dlen; 586*b0104773SPascal Brand res = 587*b0104773SPascal Brand update_func(op->state, op->buffer, 588*b0104773SPascal Brand op->block_size, dst, &tmp_dlen); 589*b0104773SPascal Brand if (res != TEE_SUCCESS) 590*b0104773SPascal Brand TEE_Panic(res); 591*b0104773SPascal Brand src += op->block_size; 592*b0104773SPascal Brand slen -= op->block_size; 593*b0104773SPascal Brand dst += tmp_dlen; 594*b0104773SPascal Brand dlen -= tmp_dlen; 595*b0104773SPascal Brand acc_dlen += tmp_dlen; 596*b0104773SPascal Brand } 597*b0104773SPascal Brand } 598*b0104773SPascal Brand } 599*b0104773SPascal Brand 600*b0104773SPascal Brand /* Slen is small enough to be contained in buffer. */ 601*b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, slen); 602*b0104773SPascal Brand op->buffer_offs += slen; 603*b0104773SPascal Brand 604*b0104773SPascal Brand out: 605*b0104773SPascal Brand *dest_len = acc_dlen; 606*b0104773SPascal Brand return TEE_SUCCESS; 607*b0104773SPascal Brand } 608*b0104773SPascal Brand 609*b0104773SPascal Brand TEE_Result TEE_CipherUpdate(TEE_OperationHandle op, const void *srcData, 610*b0104773SPascal Brand size_t srcLen, void *destData, size_t *destLen) 611*b0104773SPascal Brand { 612*b0104773SPascal Brand size_t req_dlen; 613*b0104773SPascal Brand 614*b0104773SPascal Brand if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) || 615*b0104773SPascal Brand destLen == NULL || (destData == NULL && *destLen != 0)) 616*b0104773SPascal Brand TEE_Panic(0); 617*b0104773SPascal Brand if (op->info.operationClass != TEE_OPERATION_CIPHER) 618*b0104773SPascal Brand TEE_Panic(0); 619*b0104773SPascal Brand if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 620*b0104773SPascal Brand TEE_Panic(0); 621*b0104773SPascal Brand 622*b0104773SPascal Brand /* Calculate required dlen */ 623*b0104773SPascal Brand req_dlen = ((op->buffer_offs + srcLen) / op->block_size) * 624*b0104773SPascal Brand op->block_size; 625*b0104773SPascal Brand if (op->buffer_two_blocks) { 626*b0104773SPascal Brand if (req_dlen > op->block_size * 2) 627*b0104773SPascal Brand req_dlen -= op->block_size * 2; 628*b0104773SPascal Brand else 629*b0104773SPascal Brand req_dlen = 0; 630*b0104773SPascal Brand } 631*b0104773SPascal Brand /* 632*b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 633*b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 634*b0104773SPascal Brand * can't restore sync with this API. 635*b0104773SPascal Brand */ 636*b0104773SPascal Brand if (*destLen < req_dlen) { 637*b0104773SPascal Brand *destLen = req_dlen; 638*b0104773SPascal Brand return TEE_ERROR_SHORT_BUFFER; 639*b0104773SPascal Brand } 640*b0104773SPascal Brand 641*b0104773SPascal Brand tee_buffer_update(op, utee_cipher_update, srcData, srcLen, destData, 642*b0104773SPascal Brand destLen); 643*b0104773SPascal Brand 644*b0104773SPascal Brand return TEE_SUCCESS; 645*b0104773SPascal Brand } 646*b0104773SPascal Brand 647*b0104773SPascal Brand TEE_Result TEE_CipherDoFinal(TEE_OperationHandle op, 648*b0104773SPascal Brand const void *srcData, size_t srcLen, void *destData, 649*b0104773SPascal Brand size_t *destLen) 650*b0104773SPascal Brand { 651*b0104773SPascal Brand TEE_Result res; 652*b0104773SPascal Brand uint8_t *dst = destData; 653*b0104773SPascal Brand size_t acc_dlen = 0; 654*b0104773SPascal Brand size_t tmp_dlen; 655*b0104773SPascal Brand size_t req_dlen; 656*b0104773SPascal Brand 657*b0104773SPascal Brand if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) || 658*b0104773SPascal Brand destLen == NULL || (destData == NULL && *destLen != 0)) 659*b0104773SPascal Brand TEE_Panic(0); 660*b0104773SPascal Brand if (op->info.operationClass != TEE_OPERATION_CIPHER) 661*b0104773SPascal Brand TEE_Panic(0); 662*b0104773SPascal Brand if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 663*b0104773SPascal Brand TEE_Panic(0); 664*b0104773SPascal Brand 665*b0104773SPascal Brand /* 666*b0104773SPascal Brand * Check that the final block doesn't require padding for those 667*b0104773SPascal Brand * algorithms that requires client to supply padding. 668*b0104773SPascal Brand */ 669*b0104773SPascal Brand if (op->info.algorithm == TEE_ALG_AES_ECB_NOPAD || 670*b0104773SPascal Brand op->info.algorithm == TEE_ALG_AES_CBC_NOPAD || 671*b0104773SPascal Brand op->info.algorithm == TEE_ALG_DES_ECB_NOPAD || 672*b0104773SPascal Brand op->info.algorithm == TEE_ALG_DES_CBC_NOPAD || 673*b0104773SPascal Brand op->info.algorithm == TEE_ALG_DES3_ECB_NOPAD || 674*b0104773SPascal Brand op->info.algorithm == TEE_ALG_DES3_CBC_NOPAD) { 675*b0104773SPascal Brand if (((op->buffer_offs + srcLen) % op->block_size) != 0) 676*b0104773SPascal Brand return TEE_ERROR_BAD_PARAMETERS; 677*b0104773SPascal Brand } 678*b0104773SPascal Brand 679*b0104773SPascal Brand /* 680*b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 681*b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 682*b0104773SPascal Brand * can't restore sync with this API. 683*b0104773SPascal Brand */ 684*b0104773SPascal Brand req_dlen = op->buffer_offs + srcLen; 685*b0104773SPascal Brand if (*destLen < req_dlen) { 686*b0104773SPascal Brand *destLen = req_dlen; 687*b0104773SPascal Brand return TEE_ERROR_SHORT_BUFFER; 688*b0104773SPascal Brand } 689*b0104773SPascal Brand 690*b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 691*b0104773SPascal Brand tee_buffer_update(op, utee_cipher_update, srcData, srcLen, dst, 692*b0104773SPascal Brand &tmp_dlen); 693*b0104773SPascal Brand dst += tmp_dlen; 694*b0104773SPascal Brand acc_dlen += tmp_dlen; 695*b0104773SPascal Brand 696*b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 697*b0104773SPascal Brand res = utee_cipher_final(op->state, op->buffer, op->buffer_offs, 698*b0104773SPascal Brand dst, &tmp_dlen); 699*b0104773SPascal Brand if (res != TEE_SUCCESS) 700*b0104773SPascal Brand TEE_Panic(res); 701*b0104773SPascal Brand acc_dlen += tmp_dlen; 702*b0104773SPascal Brand 703*b0104773SPascal Brand op->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 704*b0104773SPascal Brand *destLen = acc_dlen; 705*b0104773SPascal Brand return TEE_SUCCESS; 706*b0104773SPascal Brand } 707*b0104773SPascal Brand 708*b0104773SPascal Brand /* Cryptographic Operations API - MAC Functions */ 709*b0104773SPascal Brand 710*b0104773SPascal Brand void TEE_MACInit(TEE_OperationHandle operation, const void *IV, size_t IVLen) 711*b0104773SPascal Brand { 712*b0104773SPascal Brand TEE_Result res; 713*b0104773SPascal Brand 714*b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 715*b0104773SPascal Brand TEE_Panic(0); 716*b0104773SPascal Brand if (IV == NULL && IVLen != 0) 717*b0104773SPascal Brand TEE_Panic(0); 718*b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_MAC) 719*b0104773SPascal Brand TEE_Panic(0); 720*b0104773SPascal Brand res = utee_hash_init(operation->state, IV, IVLen); 721*b0104773SPascal Brand if (res != TEE_SUCCESS) 722*b0104773SPascal Brand TEE_Panic(res); 723*b0104773SPascal Brand operation->buffer_offs = 0; 724*b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 725*b0104773SPascal Brand } 726*b0104773SPascal Brand 727*b0104773SPascal Brand void TEE_MACUpdate(TEE_OperationHandle op, const void *chunk, size_t chunkSize) 728*b0104773SPascal Brand { 729*b0104773SPascal Brand TEE_Result res; 730*b0104773SPascal Brand 731*b0104773SPascal Brand if (op == TEE_HANDLE_NULL || (chunk == NULL && chunkSize != 0)) 732*b0104773SPascal Brand TEE_Panic(0); 733*b0104773SPascal Brand if (op->info.operationClass != TEE_OPERATION_MAC) 734*b0104773SPascal Brand TEE_Panic(0); 735*b0104773SPascal Brand if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 736*b0104773SPascal Brand TEE_Panic(0); 737*b0104773SPascal Brand 738*b0104773SPascal Brand res = utee_hash_update(op->state, chunk, chunkSize); 739*b0104773SPascal Brand if (res != TEE_SUCCESS) 740*b0104773SPascal Brand TEE_Panic(res); 741*b0104773SPascal Brand } 742*b0104773SPascal Brand 743*b0104773SPascal Brand TEE_Result TEE_MACComputeFinal(TEE_OperationHandle op, 744*b0104773SPascal Brand const void *message, size_t messageLen, 745*b0104773SPascal Brand void *mac, size_t *macLen) 746*b0104773SPascal Brand { 747*b0104773SPascal Brand TEE_Result res; 748*b0104773SPascal Brand 749*b0104773SPascal Brand if (op == TEE_HANDLE_NULL || (message == NULL && messageLen != 0) || 750*b0104773SPascal Brand mac == NULL || macLen == NULL) 751*b0104773SPascal Brand TEE_Panic(0); 752*b0104773SPascal Brand if (op->info.operationClass != TEE_OPERATION_MAC) 753*b0104773SPascal Brand TEE_Panic(0); 754*b0104773SPascal Brand if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 755*b0104773SPascal Brand TEE_Panic(0); 756*b0104773SPascal Brand 757*b0104773SPascal Brand res = utee_hash_final(op->state, message, messageLen, mac, macLen); 758*b0104773SPascal Brand op->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 759*b0104773SPascal Brand return res; 760*b0104773SPascal Brand } 761*b0104773SPascal Brand 762*b0104773SPascal Brand TEE_Result TEE_MACCompareFinal(TEE_OperationHandle operation, 763*b0104773SPascal Brand const void *message, size_t messageLen, 764*b0104773SPascal Brand const void *mac, size_t macLen) 765*b0104773SPascal Brand { 766*b0104773SPascal Brand TEE_Result res; 767*b0104773SPascal Brand uint8_t computed_mac[TEE_MAX_HASH_SIZE]; 768*b0104773SPascal Brand size_t computed_mac_size = TEE_MAX_HASH_SIZE; 769*b0104773SPascal Brand 770*b0104773SPascal Brand res = TEE_MACComputeFinal(operation, message, messageLen, computed_mac, 771*b0104773SPascal Brand &computed_mac_size); 772*b0104773SPascal Brand if (res != TEE_SUCCESS) 773*b0104773SPascal Brand return res; 774*b0104773SPascal Brand if (computed_mac_size != macLen) 775*b0104773SPascal Brand return TEE_ERROR_MAC_INVALID; 776*b0104773SPascal Brand if (memcmp(mac, computed_mac, computed_mac_size) != 0) 777*b0104773SPascal Brand return TEE_ERROR_MAC_INVALID; 778*b0104773SPascal Brand /* don't leave this on stack */ 779*b0104773SPascal Brand memset(computed_mac, 0, computed_mac_size); 780*b0104773SPascal Brand return TEE_SUCCESS; 781*b0104773SPascal Brand } 782*b0104773SPascal Brand 783*b0104773SPascal Brand /* Cryptographic Operations API - Authenticated Encryption Functions */ 784*b0104773SPascal Brand 785*b0104773SPascal Brand TEE_Result TEE_AEInit(TEE_OperationHandle op, const void *nonce, 786*b0104773SPascal Brand size_t nonceLen, uint32_t tagLen, uint32_t AADLen, 787*b0104773SPascal Brand uint32_t payloadLen) 788*b0104773SPascal Brand { 789*b0104773SPascal Brand TEE_Result res; 790*b0104773SPascal Brand 791*b0104773SPascal Brand if (op == TEE_HANDLE_NULL || nonce == NULL) 792*b0104773SPascal Brand TEE_Panic(0); 793*b0104773SPascal Brand if (op->info.operationClass != TEE_OPERATION_AE) 794*b0104773SPascal Brand TEE_Panic(0); 795*b0104773SPascal Brand 796*b0104773SPascal Brand /* 797*b0104773SPascal Brand * AES-CCM tag len is specified by AES-CCM spec and handled in TEE Core 798*b0104773SPascal Brand * in the implementation. But AES-GCM spec doesn't specify the tag len 799*b0104773SPascal Brand * according to the same principle so we have to check here instead to 800*b0104773SPascal Brand * be GP compliant. 801*b0104773SPascal Brand */ 802*b0104773SPascal Brand if (op->info.algorithm == TEE_ALG_AES_GCM) { 803*b0104773SPascal Brand /* 804*b0104773SPascal Brand * From GP spec: For AES-GCM, can be 128, 120, 112, 104, or 96 805*b0104773SPascal Brand */ 806*b0104773SPascal Brand if (tagLen < 96 || tagLen > 128 || (tagLen % 8 != 0)) 807*b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 808*b0104773SPascal Brand } 809*b0104773SPascal Brand 810*b0104773SPascal Brand res = utee_authenc_init(op->state, nonce, nonceLen, tagLen / 8, AADLen, 811*b0104773SPascal Brand payloadLen); 812*b0104773SPascal Brand if (res != TEE_SUCCESS) { 813*b0104773SPascal Brand if (res != TEE_ERROR_NOT_SUPPORTED) 814*b0104773SPascal Brand TEE_Panic(res); 815*b0104773SPascal Brand return res; 816*b0104773SPascal Brand } 817*b0104773SPascal Brand op->ae_tag_len = tagLen / 8; 818*b0104773SPascal Brand 819*b0104773SPascal Brand op->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 820*b0104773SPascal Brand return TEE_SUCCESS; 821*b0104773SPascal Brand } 822*b0104773SPascal Brand 823*b0104773SPascal Brand void TEE_AEUpdateAAD(TEE_OperationHandle op, const void *AADdata, 824*b0104773SPascal Brand size_t AADdataLen) 825*b0104773SPascal Brand { 826*b0104773SPascal Brand TEE_Result res; 827*b0104773SPascal Brand 828*b0104773SPascal Brand if (op == TEE_HANDLE_NULL || (AADdata == NULL && AADdataLen != 0)) 829*b0104773SPascal Brand TEE_Panic(0); 830*b0104773SPascal Brand if (op->info.operationClass != TEE_OPERATION_AE) 831*b0104773SPascal Brand TEE_Panic(0); 832*b0104773SPascal Brand if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 833*b0104773SPascal Brand TEE_Panic(0); 834*b0104773SPascal Brand 835*b0104773SPascal Brand res = utee_authenc_update_aad(op->state, AADdata, AADdataLen); 836*b0104773SPascal Brand if (res != TEE_SUCCESS) 837*b0104773SPascal Brand TEE_Panic(res); 838*b0104773SPascal Brand } 839*b0104773SPascal Brand 840*b0104773SPascal Brand TEE_Result TEE_AEUpdate(TEE_OperationHandle op, const void *srcData, 841*b0104773SPascal Brand size_t srcLen, void *destData, size_t *destLen) 842*b0104773SPascal Brand { 843*b0104773SPascal Brand size_t req_dlen; 844*b0104773SPascal Brand 845*b0104773SPascal Brand if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) || 846*b0104773SPascal Brand destLen == NULL || (destData == NULL && *destLen != 0)) 847*b0104773SPascal Brand TEE_Panic(0); 848*b0104773SPascal Brand if (op->info.operationClass != TEE_OPERATION_AE) 849*b0104773SPascal Brand TEE_Panic(0); 850*b0104773SPascal Brand if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 851*b0104773SPascal Brand TEE_Panic(0); 852*b0104773SPascal Brand 853*b0104773SPascal Brand /* 854*b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 855*b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 856*b0104773SPascal Brand * can't restore sync with this API. 857*b0104773SPascal Brand */ 858*b0104773SPascal Brand req_dlen = TEE_ROUNDDOWN(op->buffer_offs + srcLen, op->block_size); 859*b0104773SPascal Brand if (*destLen < req_dlen) { 860*b0104773SPascal Brand *destLen = req_dlen; 861*b0104773SPascal Brand return TEE_ERROR_SHORT_BUFFER; 862*b0104773SPascal Brand } 863*b0104773SPascal Brand 864*b0104773SPascal Brand tee_buffer_update(op, utee_authenc_update_payload, srcData, srcLen, 865*b0104773SPascal Brand destData, destLen); 866*b0104773SPascal Brand 867*b0104773SPascal Brand return TEE_SUCCESS; 868*b0104773SPascal Brand } 869*b0104773SPascal Brand 870*b0104773SPascal Brand TEE_Result TEE_AEEncryptFinal(TEE_OperationHandle op, 871*b0104773SPascal Brand const void *srcData, size_t srcLen, 872*b0104773SPascal Brand void *destData, size_t *destLen, void *tag, 873*b0104773SPascal Brand size_t *tagLen) 874*b0104773SPascal Brand { 875*b0104773SPascal Brand TEE_Result res; 876*b0104773SPascal Brand uint8_t *dst = destData; 877*b0104773SPascal Brand size_t acc_dlen = 0; 878*b0104773SPascal Brand size_t tmp_dlen; 879*b0104773SPascal Brand size_t req_dlen; 880*b0104773SPascal Brand 881*b0104773SPascal Brand if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) || 882*b0104773SPascal Brand destLen == NULL || (destData == NULL && *destLen != 0) || 883*b0104773SPascal Brand tag == NULL || tagLen == NULL) 884*b0104773SPascal Brand TEE_Panic(0); 885*b0104773SPascal Brand if (op->info.operationClass != TEE_OPERATION_AE) 886*b0104773SPascal Brand TEE_Panic(0); 887*b0104773SPascal Brand if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 888*b0104773SPascal Brand TEE_Panic(0); 889*b0104773SPascal Brand 890*b0104773SPascal Brand /* 891*b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 892*b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 893*b0104773SPascal Brand * can't restore sync with this API. 894*b0104773SPascal Brand */ 895*b0104773SPascal Brand req_dlen = op->buffer_offs + srcLen; 896*b0104773SPascal Brand if (*destLen < req_dlen) { 897*b0104773SPascal Brand *destLen = req_dlen; 898*b0104773SPascal Brand return TEE_ERROR_SHORT_BUFFER; 899*b0104773SPascal Brand } 900*b0104773SPascal Brand 901*b0104773SPascal Brand /* 902*b0104773SPascal Brand * Need to check this before update_payload since sync would be lost if 903*b0104773SPascal Brand * we return short buffer after that. 904*b0104773SPascal Brand */ 905*b0104773SPascal Brand if (*tagLen < op->ae_tag_len) { 906*b0104773SPascal Brand *tagLen = op->ae_tag_len; 907*b0104773SPascal Brand return TEE_ERROR_SHORT_BUFFER; 908*b0104773SPascal Brand } 909*b0104773SPascal Brand 910*b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 911*b0104773SPascal Brand tee_buffer_update(op, utee_authenc_update_payload, srcData, srcLen, 912*b0104773SPascal Brand dst, &tmp_dlen); 913*b0104773SPascal Brand dst += tmp_dlen; 914*b0104773SPascal Brand acc_dlen += tmp_dlen; 915*b0104773SPascal Brand 916*b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 917*b0104773SPascal Brand res = 918*b0104773SPascal Brand utee_authenc_enc_final(op->state, op->buffer, op->buffer_offs, dst, 919*b0104773SPascal Brand &tmp_dlen, tag, tagLen); 920*b0104773SPascal Brand if (res != TEE_SUCCESS) 921*b0104773SPascal Brand TEE_Panic(res); 922*b0104773SPascal Brand acc_dlen += tmp_dlen; 923*b0104773SPascal Brand 924*b0104773SPascal Brand *destLen = acc_dlen; 925*b0104773SPascal Brand op->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 926*b0104773SPascal Brand 927*b0104773SPascal Brand return res; 928*b0104773SPascal Brand } 929*b0104773SPascal Brand 930*b0104773SPascal Brand TEE_Result TEE_AEDecryptFinal(TEE_OperationHandle op, 931*b0104773SPascal Brand const void *srcData, size_t srcLen, 932*b0104773SPascal Brand void *destData, size_t *destLen, const void *tag, 933*b0104773SPascal Brand size_t tagLen) 934*b0104773SPascal Brand { 935*b0104773SPascal Brand TEE_Result res; 936*b0104773SPascal Brand uint8_t *dst = destData; 937*b0104773SPascal Brand size_t acc_dlen = 0; 938*b0104773SPascal Brand size_t tmp_dlen; 939*b0104773SPascal Brand size_t req_dlen; 940*b0104773SPascal Brand 941*b0104773SPascal Brand if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) || 942*b0104773SPascal Brand destLen == NULL || (destData == NULL && *destLen != 0) || 943*b0104773SPascal Brand (tag == NULL && tagLen != 0)) 944*b0104773SPascal Brand TEE_Panic(0); 945*b0104773SPascal Brand if (op->info.operationClass != TEE_OPERATION_AE) 946*b0104773SPascal Brand TEE_Panic(0); 947*b0104773SPascal Brand if ((op->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 948*b0104773SPascal Brand TEE_Panic(0); 949*b0104773SPascal Brand 950*b0104773SPascal Brand /* 951*b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 952*b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 953*b0104773SPascal Brand * can't restore sync with this API. 954*b0104773SPascal Brand */ 955*b0104773SPascal Brand req_dlen = op->buffer_offs + srcLen; 956*b0104773SPascal Brand if (*destLen < req_dlen) { 957*b0104773SPascal Brand *destLen = req_dlen; 958*b0104773SPascal Brand return TEE_ERROR_SHORT_BUFFER; 959*b0104773SPascal Brand } 960*b0104773SPascal Brand 961*b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 962*b0104773SPascal Brand tee_buffer_update(op, utee_authenc_update_payload, srcData, srcLen, 963*b0104773SPascal Brand dst, &tmp_dlen); 964*b0104773SPascal Brand dst += tmp_dlen; 965*b0104773SPascal Brand acc_dlen += tmp_dlen; 966*b0104773SPascal Brand 967*b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 968*b0104773SPascal Brand res = 969*b0104773SPascal Brand utee_authenc_dec_final(op->state, op->buffer, op->buffer_offs, dst, 970*b0104773SPascal Brand &tmp_dlen, tag, tagLen); 971*b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_MAC_INVALID) 972*b0104773SPascal Brand TEE_Panic(res); 973*b0104773SPascal Brand /* Supplied tagLen should match what we initiated with */ 974*b0104773SPascal Brand if (tagLen != op->ae_tag_len) 975*b0104773SPascal Brand res = TEE_ERROR_MAC_INVALID; 976*b0104773SPascal Brand 977*b0104773SPascal Brand acc_dlen += tmp_dlen; 978*b0104773SPascal Brand 979*b0104773SPascal Brand *destLen = acc_dlen; 980*b0104773SPascal Brand op->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 981*b0104773SPascal Brand 982*b0104773SPascal Brand return res; 983*b0104773SPascal Brand } 984*b0104773SPascal Brand 985*b0104773SPascal Brand /* Cryptographic Operations API - Asymmetric Functions */ 986*b0104773SPascal Brand 987*b0104773SPascal Brand TEE_Result TEE_AsymmetricEncrypt(TEE_OperationHandle op, 988*b0104773SPascal Brand const TEE_Attribute *params, 989*b0104773SPascal Brand uint32_t paramCount, const void *srcData, 990*b0104773SPascal Brand size_t srcLen, void *destData, 991*b0104773SPascal Brand size_t *destLen) 992*b0104773SPascal Brand { 993*b0104773SPascal Brand TEE_Result res; 994*b0104773SPascal Brand 995*b0104773SPascal Brand if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) || 996*b0104773SPascal Brand destLen == NULL || (destData == NULL && *destLen != 0)) 997*b0104773SPascal Brand TEE_Panic(0); 998*b0104773SPascal Brand if (paramCount != 0 && params == NULL) 999*b0104773SPascal Brand TEE_Panic(0); 1000*b0104773SPascal Brand if (op->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 1001*b0104773SPascal Brand TEE_Panic(0); 1002*b0104773SPascal Brand if (op->info.mode != TEE_MODE_ENCRYPT) 1003*b0104773SPascal Brand TEE_Panic(0); 1004*b0104773SPascal Brand 1005*b0104773SPascal Brand res = utee_asymm_operate(op->state, params, paramCount, srcData, srcLen, 1006*b0104773SPascal Brand destData, destLen); 1007*b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER) 1008*b0104773SPascal Brand TEE_Panic(res); 1009*b0104773SPascal Brand return res; 1010*b0104773SPascal Brand } 1011*b0104773SPascal Brand 1012*b0104773SPascal Brand TEE_Result TEE_AsymmetricDecrypt(TEE_OperationHandle op, 1013*b0104773SPascal Brand const TEE_Attribute *params, 1014*b0104773SPascal Brand uint32_t paramCount, const void *srcData, 1015*b0104773SPascal Brand size_t srcLen, void *destData, 1016*b0104773SPascal Brand size_t *destLen) 1017*b0104773SPascal Brand { 1018*b0104773SPascal Brand TEE_Result res; 1019*b0104773SPascal Brand 1020*b0104773SPascal Brand if (op == TEE_HANDLE_NULL || (srcData == NULL && srcLen != 0) || 1021*b0104773SPascal Brand destLen == NULL || (destData == NULL && *destLen != 0)) 1022*b0104773SPascal Brand TEE_Panic(0); 1023*b0104773SPascal Brand if (paramCount != 0 && params == NULL) 1024*b0104773SPascal Brand TEE_Panic(0); 1025*b0104773SPascal Brand if (op->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 1026*b0104773SPascal Brand TEE_Panic(0); 1027*b0104773SPascal Brand if (op->info.mode != TEE_MODE_DECRYPT) 1028*b0104773SPascal Brand TEE_Panic(0); 1029*b0104773SPascal Brand 1030*b0104773SPascal Brand res = utee_asymm_operate(op->state, params, paramCount, srcData, srcLen, 1031*b0104773SPascal Brand destData, destLen); 1032*b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER) 1033*b0104773SPascal Brand TEE_Panic(res); 1034*b0104773SPascal Brand return res; 1035*b0104773SPascal Brand } 1036*b0104773SPascal Brand 1037*b0104773SPascal Brand TEE_Result TEE_AsymmetricSignDigest(TEE_OperationHandle op, 1038*b0104773SPascal Brand const TEE_Attribute *params, 1039*b0104773SPascal Brand uint32_t paramCount, const void *digest, 1040*b0104773SPascal Brand size_t digestLen, void *signature, 1041*b0104773SPascal Brand size_t *signatureLen) 1042*b0104773SPascal Brand { 1043*b0104773SPascal Brand TEE_Result res; 1044*b0104773SPascal Brand 1045*b0104773SPascal Brand if (op == TEE_HANDLE_NULL || (digest == NULL && digestLen != 0) || 1046*b0104773SPascal Brand signature == NULL || signatureLen == NULL) 1047*b0104773SPascal Brand TEE_Panic(0); 1048*b0104773SPascal Brand if (paramCount != 0 && params == NULL) 1049*b0104773SPascal Brand TEE_Panic(0); 1050*b0104773SPascal Brand if (op->info.operationClass != TEE_OPERATION_ASYMMETRIC_SIGNATURE) 1051*b0104773SPascal Brand TEE_Panic(0); 1052*b0104773SPascal Brand if (op->info.mode != TEE_MODE_SIGN) 1053*b0104773SPascal Brand TEE_Panic(0); 1054*b0104773SPascal Brand 1055*b0104773SPascal Brand res = 1056*b0104773SPascal Brand utee_asymm_operate(op->state, params, paramCount, digest, digestLen, 1057*b0104773SPascal Brand signature, signatureLen); 1058*b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER) 1059*b0104773SPascal Brand TEE_Panic(res); 1060*b0104773SPascal Brand return res; 1061*b0104773SPascal Brand } 1062*b0104773SPascal Brand 1063*b0104773SPascal Brand TEE_Result TEE_AsymmetricVerifyDigest(TEE_OperationHandle op, 1064*b0104773SPascal Brand const TEE_Attribute *params, 1065*b0104773SPascal Brand uint32_t paramCount, const void *digest, 1066*b0104773SPascal Brand size_t digestLen, const void *signature, 1067*b0104773SPascal Brand size_t signatureLen) 1068*b0104773SPascal Brand { 1069*b0104773SPascal Brand TEE_Result res; 1070*b0104773SPascal Brand 1071*b0104773SPascal Brand if (op == TEE_HANDLE_NULL || (digest == NULL && digestLen != 0) || 1072*b0104773SPascal Brand (signature == NULL && signatureLen != 0)) 1073*b0104773SPascal Brand TEE_Panic(0); 1074*b0104773SPascal Brand if (paramCount != 0 && params == NULL) 1075*b0104773SPascal Brand TEE_Panic(0); 1076*b0104773SPascal Brand if (op->info.operationClass != TEE_OPERATION_ASYMMETRIC_SIGNATURE) 1077*b0104773SPascal Brand TEE_Panic(0); 1078*b0104773SPascal Brand if (op->info.mode != TEE_MODE_VERIFY) 1079*b0104773SPascal Brand TEE_Panic(0); 1080*b0104773SPascal Brand 1081*b0104773SPascal Brand res = 1082*b0104773SPascal Brand utee_asymm_verify(op->state, params, paramCount, digest, digestLen, 1083*b0104773SPascal Brand signature, signatureLen); 1084*b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID) 1085*b0104773SPascal Brand TEE_Panic(res); 1086*b0104773SPascal Brand return res; 1087*b0104773SPascal Brand } 1088*b0104773SPascal Brand 1089*b0104773SPascal Brand /* Cryptographic Operations API - Key Derivation Functions */ 1090*b0104773SPascal Brand 1091*b0104773SPascal Brand void TEE_DeriveKey(TEE_OperationHandle operation, 1092*b0104773SPascal Brand const TEE_Attribute *params, uint32_t paramCount, 1093*b0104773SPascal Brand TEE_ObjectHandle derivedKey) 1094*b0104773SPascal Brand { 1095*b0104773SPascal Brand TEE_Result res; 1096*b0104773SPascal Brand TEE_ObjectInfo key_info; 1097*b0104773SPascal Brand 1098*b0104773SPascal Brand if (operation == TEE_HANDLE_NULL || derivedKey == 0) 1099*b0104773SPascal Brand TEE_Panic(0); 1100*b0104773SPascal Brand if (paramCount != 0 && params == NULL) 1101*b0104773SPascal Brand TEE_Panic(0); 1102*b0104773SPascal Brand 1103*b0104773SPascal Brand if (operation->info.algorithm != TEE_ALG_DH_DERIVE_SHARED_SECRET) 1104*b0104773SPascal Brand TEE_Panic(0); 1105*b0104773SPascal Brand 1106*b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_KEY_DERIVATION) 1107*b0104773SPascal Brand TEE_Panic(0); 1108*b0104773SPascal Brand if (operation->info.mode != TEE_MODE_DERIVE) 1109*b0104773SPascal Brand TEE_Panic(0); 1110*b0104773SPascal Brand if ((operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0) 1111*b0104773SPascal Brand TEE_Panic(0); 1112*b0104773SPascal Brand 1113*b0104773SPascal Brand res = utee_cryp_obj_get_info((uint32_t) derivedKey, &key_info); 1114*b0104773SPascal Brand if (res != TEE_SUCCESS) 1115*b0104773SPascal Brand TEE_Panic(0); 1116*b0104773SPascal Brand 1117*b0104773SPascal Brand if (key_info.objectType != TEE_TYPE_GENERIC_SECRET) 1118*b0104773SPascal Brand TEE_Panic(0); 1119*b0104773SPascal Brand if ((key_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 1120*b0104773SPascal Brand TEE_Panic(0); 1121*b0104773SPascal Brand 1122*b0104773SPascal Brand if ((operation->info.algorithm == TEE_ALG_DH_DERIVE_SHARED_SECRET) && 1123*b0104773SPascal Brand (paramCount != 1 || 1124*b0104773SPascal Brand params[0].attributeID != TEE_ATTR_DH_PUBLIC_VALUE)) 1125*b0104773SPascal Brand TEE_Panic(0); 1126*b0104773SPascal Brand 1127*b0104773SPascal Brand res = utee_cryp_derive_key(operation->state, params, paramCount, 1128*b0104773SPascal Brand (uint32_t) derivedKey); 1129*b0104773SPascal Brand if (res != TEE_SUCCESS) 1130*b0104773SPascal Brand TEE_Panic(res); 1131*b0104773SPascal Brand } 1132*b0104773SPascal Brand 1133*b0104773SPascal Brand /* Cryptographic Operations API - Random Number Generation Functions */ 1134*b0104773SPascal Brand 1135*b0104773SPascal Brand void TEE_GenerateRandom(void *randomBuffer, size_t randomBufferLen) 1136*b0104773SPascal Brand { 1137*b0104773SPascal Brand TEE_Result res; 1138*b0104773SPascal Brand 1139*b0104773SPascal Brand res = utee_cryp_random_number_generate(randomBuffer, randomBufferLen); 1140*b0104773SPascal Brand if (res != TEE_SUCCESS) 1141*b0104773SPascal Brand TEE_Panic(res); 1142*b0104773SPascal Brand } 1143