11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 2b0104773SPascal Brand /* 3b0104773SPascal Brand * Copyright (c) 2014, STMicroelectronics International N.V. 4eee637e7SAlexander Zakharov * Copyright (c) 2021, SumUp Services GmbH 5b0104773SPascal Brand */ 679170ce0SJerome Forissier #include <config.h> 7b0104773SPascal Brand #include <stdlib.h> 8b0104773SPascal Brand #include <string.h> 9b796ebf3SJerome Forissier #include <string_ext.h> 10b0104773SPascal Brand #include <tee_api.h> 118854d3c6SJerome Forissier #include <tee_api_defines_extensions.h> 12b0104773SPascal Brand #include <tee_internal_api_extensions.h> 13b0104773SPascal Brand #include <utee_syscalls.h> 14b0104773SPascal Brand #include <utee_defines.h> 15fc26c92aSJens Wiklander #include <util.h> 16e86f1266SJens Wiklander #include "tee_api_private.h" 17b0104773SPascal Brand 18b0104773SPascal Brand struct __TEE_OperationHandle { 19b0104773SPascal Brand TEE_OperationInfo info; 20b0104773SPascal Brand TEE_ObjectHandle key1; 21b0104773SPascal Brand TEE_ObjectHandle key2; 22642a1607SCedric Chaumont uint32_t operationState;/* Operation state : INITIAL or ACTIVE */ 23b0104773SPascal Brand uint8_t *buffer; /* buffer to collect complete blocks */ 24b0104773SPascal Brand bool buffer_two_blocks; /* True if two blocks need to be buffered */ 25b0104773SPascal Brand size_t block_size; /* Block size of cipher */ 26b0104773SPascal Brand size_t buffer_offs; /* Offset in buffer */ 27b0104773SPascal Brand uint32_t state; /* Handle to state in TEE Core */ 28b0104773SPascal Brand }; 29b0104773SPascal Brand 30b0104773SPascal Brand /* Cryptographic Operations API - Generic Operation Functions */ 31b0104773SPascal Brand 32b0104773SPascal Brand TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation, 33b0104773SPascal Brand uint32_t algorithm, uint32_t mode, 34b0104773SPascal Brand uint32_t maxKeySize) 35b0104773SPascal Brand { 36b0104773SPascal Brand TEE_Result res; 37b0104773SPascal Brand TEE_OperationHandle op = TEE_HANDLE_NULL; 38b0104773SPascal Brand uint32_t handle_state = 0; 39b0104773SPascal Brand size_t block_size = 1; 40b0104773SPascal Brand uint32_t req_key_usage; 41b0104773SPascal Brand bool with_private_key = false; 42b0104773SPascal Brand bool buffer_two_blocks = false; 43b0104773SPascal Brand 449b52c538SCedric Chaumont if (!operation) 45b0104773SPascal Brand TEE_Panic(0); 46b0104773SPascal Brand 47696f56acSPingan Xie if (algorithm == TEE_ALG_AES_XTS || algorithm == TEE_ALG_SM2_KEP || 48696f56acSPingan Xie algorithm == TEE_ALG_SM4_XTS) 49b0104773SPascal Brand handle_state = TEE_HANDLE_FLAG_EXPECT_TWO_KEYS; 50b0104773SPascal Brand 51218d9055SCedric Chaumont /* Check algorithm max key size */ 52218d9055SCedric Chaumont switch (algorithm) { 53218d9055SCedric Chaumont case TEE_ALG_DSA_SHA1: 54218d9055SCedric Chaumont if (maxKeySize < 512) 55218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 56218d9055SCedric Chaumont if (maxKeySize > 1024) 57218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 58218d9055SCedric Chaumont if (maxKeySize % 64 != 0) 59218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 60218d9055SCedric Chaumont break; 61218d9055SCedric Chaumont 62218d9055SCedric Chaumont case TEE_ALG_DSA_SHA224: 63218d9055SCedric Chaumont if (maxKeySize != 2048) 64218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 65218d9055SCedric Chaumont break; 66218d9055SCedric Chaumont 67218d9055SCedric Chaumont case TEE_ALG_DSA_SHA256: 68218d9055SCedric Chaumont if (maxKeySize != 2048 && maxKeySize != 3072) 69218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 70218d9055SCedric Chaumont break; 71218d9055SCedric Chaumont 72fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA1: 73fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P192: 74fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P192: 751220586eSCedric Chaumont if (maxKeySize != 192) 761220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 771220586eSCedric Chaumont break; 781220586eSCedric Chaumont 79fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA224: 80fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P224: 81fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P224: 821220586eSCedric Chaumont if (maxKeySize != 224) 831220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 841220586eSCedric Chaumont break; 851220586eSCedric Chaumont 86fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA256: 87fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P256: 88fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P256: 8991fc6bd8SJerome Forissier case TEE_ALG_SM2_PKE: 900f151943SJerome Forissier case TEE_ALG_SM2_DSA_SM3: 911220586eSCedric Chaumont if (maxKeySize != 256) 921220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 931220586eSCedric Chaumont break; 941220586eSCedric Chaumont 955b385b3fSJerome Forissier case TEE_ALG_SM2_KEP: 965b385b3fSJerome Forissier /* Two 256-bit keys */ 975b385b3fSJerome Forissier if (maxKeySize != 512) 985b385b3fSJerome Forissier return TEE_ERROR_NOT_SUPPORTED; 995b385b3fSJerome Forissier break; 1005b385b3fSJerome Forissier 101fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA384: 102fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P384: 103fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P384: 1041220586eSCedric Chaumont if (maxKeySize != 384) 1051220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 1061220586eSCedric Chaumont break; 1071220586eSCedric Chaumont 108fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA512: 109fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P521: 110fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P521: 1111220586eSCedric Chaumont if (maxKeySize != 521) 1121220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 1131220586eSCedric Chaumont break; 114fe2fd3ffSJens Wiklander 115fe2fd3ffSJens Wiklander case TEE_ALG_ECDH_DERIVE_SHARED_SECRET: 116fe2fd3ffSJens Wiklander if (maxKeySize > 521) 117fe2fd3ffSJens Wiklander return TEE_ERROR_NOT_SUPPORTED; 118fe2fd3ffSJens Wiklander break; 119fe2fd3ffSJens Wiklander 120e1f9cee7SSergiy Kibrik case TEE_ALG_ED25519: 1213f61056dSSohaib ul Hassan case TEE_ALG_X25519: 1223f61056dSSohaib ul Hassan if (maxKeySize != 256) 1233f61056dSSohaib ul Hassan return TEE_ERROR_NOT_SUPPORTED; 1243f61056dSSohaib ul Hassan break; 125218d9055SCedric Chaumont default: 126218d9055SCedric Chaumont break; 127218d9055SCedric Chaumont } 128218d9055SCedric Chaumont 129cf5c060cSJens Wiklander /* Check algorithm mode (and maxKeySize for digests) */ 130b0104773SPascal Brand switch (algorithm) { 131b0104773SPascal Brand case TEE_ALG_AES_CTS: 132b0104773SPascal Brand case TEE_ALG_AES_XTS: 133696f56acSPingan Xie case TEE_ALG_SM4_XTS: 134b0104773SPascal Brand buffer_two_blocks = true; 135919a5a68SJerome Forissier fallthrough; 1364bd53c54SJerome Forissier case TEE_ALG_AES_ECB_NOPAD: 137b0104773SPascal Brand case TEE_ALG_AES_CBC_NOPAD: 138b0104773SPascal Brand case TEE_ALG_AES_CCM: 139b0104773SPascal Brand case TEE_ALG_DES_ECB_NOPAD: 140b0104773SPascal Brand case TEE_ALG_DES_CBC_NOPAD: 141b0104773SPascal Brand case TEE_ALG_DES3_ECB_NOPAD: 142b0104773SPascal Brand case TEE_ALG_DES3_CBC_NOPAD: 143ade6f848SJerome Forissier case TEE_ALG_SM4_ECB_NOPAD: 144ade6f848SJerome Forissier case TEE_ALG_SM4_CBC_NOPAD: 145ade6f848SJerome Forissier case TEE_ALG_SM4_CTR: 146b0104773SPascal Brand if (TEE_ALG_GET_MAIN_ALG(algorithm) == TEE_MAIN_ALGO_AES) 147b0104773SPascal Brand block_size = TEE_AES_BLOCK_SIZE; 148ade6f848SJerome Forissier else if (TEE_ALG_GET_MAIN_ALG(algorithm) == TEE_MAIN_ALGO_SM4) 149ade6f848SJerome Forissier block_size = TEE_SM4_BLOCK_SIZE; 150b0104773SPascal Brand else 151b0104773SPascal Brand block_size = TEE_DES_BLOCK_SIZE; 152919a5a68SJerome Forissier fallthrough; 15357aabac5SBogdan Liulko case TEE_ALG_AES_CTR: 154afc0c182SBogdan Liulko case TEE_ALG_AES_GCM: 155b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) 156b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT; 157b0104773SPascal Brand else if (mode == TEE_MODE_DECRYPT) 158b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT; 159b0104773SPascal Brand else 160b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 161b0104773SPascal Brand break; 162b0104773SPascal Brand 1636a2e0a9fSGabor Szekely #if defined(CFG_CRYPTO_RSASSA_NA1) 1646a2e0a9fSGabor Szekely case TEE_ALG_RSASSA_PKCS1_V1_5: 1656a2e0a9fSGabor Szekely #endif 166b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_MD5: 167b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1: 168b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224: 169b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256: 170b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384: 171b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512: 172b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: 173b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: 174b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: 175b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: 176b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: 177b0104773SPascal Brand case TEE_ALG_DSA_SHA1: 178218d9055SCedric Chaumont case TEE_ALG_DSA_SHA224: 179218d9055SCedric Chaumont case TEE_ALG_DSA_SHA256: 180fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA1: 181fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA224: 182fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA256: 183fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA384: 184fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA512: 185fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P192: 186fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P224: 187fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P256: 188fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P384: 189fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P521: 1900f151943SJerome Forissier case TEE_ALG_SM2_DSA_SM3: 191e1f9cee7SSergiy Kibrik case TEE_ALG_ED25519: 192b0104773SPascal Brand if (mode == TEE_MODE_SIGN) { 193b0104773SPascal Brand with_private_key = true; 194b0104773SPascal Brand req_key_usage = TEE_USAGE_SIGN; 195b0104773SPascal Brand } else if (mode == TEE_MODE_VERIFY) { 196b0104773SPascal Brand req_key_usage = TEE_USAGE_VERIFY; 197b0104773SPascal Brand } else { 198b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 199b0104773SPascal Brand } 200b0104773SPascal Brand break; 201b0104773SPascal Brand 202b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_V1_5: 203b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1: 204b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224: 205b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256: 206b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384: 207b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512: 20891fc6bd8SJerome Forissier case TEE_ALG_SM2_PKE: 209b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) { 210b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT; 211b0104773SPascal Brand } else if (mode == TEE_MODE_DECRYPT) { 212b0104773SPascal Brand with_private_key = true; 213b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT; 214b0104773SPascal Brand } else { 215b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 216b0104773SPascal Brand } 217b0104773SPascal Brand break; 218b0104773SPascal Brand 219b0104773SPascal Brand case TEE_ALG_RSA_NOPAD: 220b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) { 221b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT | TEE_USAGE_VERIFY; 222b0104773SPascal Brand } else if (mode == TEE_MODE_DECRYPT) { 223b0104773SPascal Brand with_private_key = true; 224b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT | TEE_USAGE_SIGN; 225b0104773SPascal Brand } else { 226b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 227b0104773SPascal Brand } 228b0104773SPascal Brand break; 229b0104773SPascal Brand 230b0104773SPascal Brand case TEE_ALG_DH_DERIVE_SHARED_SECRET: 231fe2fd3ffSJens Wiklander case TEE_ALG_ECDH_DERIVE_SHARED_SECRET: 232fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P192: 233fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P224: 234fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P256: 235fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P384: 236fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P521: 237cdb198a7SJerome Forissier case TEE_ALG_HKDF_MD5_DERIVE_KEY: 238cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA1_DERIVE_KEY: 239cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA224_DERIVE_KEY: 240cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA256_DERIVE_KEY: 241cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA384_DERIVE_KEY: 242cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA512_DERIVE_KEY: 2438854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA1_DERIVE_KEY: 2448854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA224_DERIVE_KEY: 2458854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA256_DERIVE_KEY: 2468854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA384_DERIVE_KEY: 2478854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA512_DERIVE_KEY: 2480f2293b7SJerome Forissier case TEE_ALG_PBKDF2_HMAC_SHA1_DERIVE_KEY: 2495b385b3fSJerome Forissier case TEE_ALG_SM2_KEP: 2503f61056dSSohaib ul Hassan case TEE_ALG_X25519: 251b0104773SPascal Brand if (mode != TEE_MODE_DERIVE) 252b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 253b0104773SPascal Brand with_private_key = true; 254b0104773SPascal Brand req_key_usage = TEE_USAGE_DERIVE; 255b0104773SPascal Brand break; 256b0104773SPascal Brand 257b0104773SPascal Brand case TEE_ALG_MD5: 258b0104773SPascal Brand case TEE_ALG_SHA1: 259b0104773SPascal Brand case TEE_ALG_SHA224: 260b0104773SPascal Brand case TEE_ALG_SHA256: 261b0104773SPascal Brand case TEE_ALG_SHA384: 262b0104773SPascal Brand case TEE_ALG_SHA512: 26347645577SJerome Forissier case TEE_ALG_SM3: 264b0104773SPascal Brand if (mode != TEE_MODE_DIGEST) 265b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 266cf5c060cSJens Wiklander if (maxKeySize) 267cf5c060cSJens Wiklander return TEE_ERROR_NOT_SUPPORTED; 26805304565SCedric Chaumont /* v1.1: flags always set for digest operations */ 269b0104773SPascal Brand handle_state |= TEE_HANDLE_FLAG_KEY_SET; 270b0104773SPascal Brand req_key_usage = 0; 271b0104773SPascal Brand break; 272b0104773SPascal Brand 273b0104773SPascal Brand case TEE_ALG_DES_CBC_MAC_NOPAD: 274b0104773SPascal Brand case TEE_ALG_AES_CBC_MAC_NOPAD: 275b0104773SPascal Brand case TEE_ALG_AES_CBC_MAC_PKCS5: 276b0104773SPascal Brand case TEE_ALG_AES_CMAC: 277b0104773SPascal Brand case TEE_ALG_DES_CBC_MAC_PKCS5: 278b0104773SPascal Brand case TEE_ALG_DES3_CBC_MAC_NOPAD: 279b0104773SPascal Brand case TEE_ALG_DES3_CBC_MAC_PKCS5: 280eee637e7SAlexander Zakharov case TEE_ALG_DES3_CMAC: 281b0104773SPascal Brand case TEE_ALG_HMAC_MD5: 282b0104773SPascal Brand case TEE_ALG_HMAC_SHA1: 283b0104773SPascal Brand case TEE_ALG_HMAC_SHA224: 284b0104773SPascal Brand case TEE_ALG_HMAC_SHA256: 285b0104773SPascal Brand case TEE_ALG_HMAC_SHA384: 286b0104773SPascal Brand case TEE_ALG_HMAC_SHA512: 28747645577SJerome Forissier case TEE_ALG_HMAC_SM3: 288b0104773SPascal Brand if (mode != TEE_MODE_MAC) 289b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 290b0104773SPascal Brand req_key_usage = TEE_USAGE_MAC; 291b0104773SPascal Brand break; 292b0104773SPascal Brand 293b0104773SPascal Brand default: 294b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 295b0104773SPascal Brand } 296b0104773SPascal Brand 297b66f219bSJens Wiklander op = TEE_Malloc(sizeof(*op), TEE_MALLOC_FILL_ZERO); 2989b52c538SCedric Chaumont if (!op) 299b0104773SPascal Brand return TEE_ERROR_OUT_OF_MEMORY; 300b0104773SPascal Brand 301b0104773SPascal Brand op->info.algorithm = algorithm; 302b0104773SPascal Brand op->info.operationClass = TEE_ALG_GET_CLASS(algorithm); 3036a2e0a9fSGabor Szekely #ifdef CFG_CRYPTO_RSASSA_NA1 3046a2e0a9fSGabor Szekely if (algorithm == TEE_ALG_RSASSA_PKCS1_V1_5) 3056a2e0a9fSGabor Szekely op->info.operationClass = TEE_OPERATION_ASYMMETRIC_SIGNATURE; 3066a2e0a9fSGabor Szekely #endif 307b0104773SPascal Brand op->info.mode = mode; 3082e5e6460SAlbert Schwarzkopf op->info.digestLength = TEE_ALG_GET_DIGEST_SIZE(algorithm); 309b0104773SPascal Brand op->info.maxKeySize = maxKeySize; 310b0104773SPascal Brand op->info.requiredKeyUsage = req_key_usage; 311b0104773SPascal Brand op->info.handleState = handle_state; 312b0104773SPascal Brand 313b0104773SPascal Brand if (block_size > 1) { 314b0104773SPascal Brand size_t buffer_size = block_size; 315b0104773SPascal Brand 316b0104773SPascal Brand if (buffer_two_blocks) 317b0104773SPascal Brand buffer_size *= 2; 318b0104773SPascal Brand 3199b52c538SCedric Chaumont op->buffer = TEE_Malloc(buffer_size, 3209b52c538SCedric Chaumont TEE_USER_MEM_HINT_NO_FILL_ZERO); 321b0104773SPascal Brand if (op->buffer == NULL) { 322b0104773SPascal Brand res = TEE_ERROR_OUT_OF_MEMORY; 323b66f219bSJens Wiklander goto out; 324b0104773SPascal Brand } 325b0104773SPascal Brand } 326b0104773SPascal Brand op->block_size = block_size; 327b0104773SPascal Brand op->buffer_two_blocks = buffer_two_blocks; 328b0104773SPascal Brand 329b0104773SPascal Brand if (TEE_ALG_GET_CLASS(algorithm) != TEE_OPERATION_DIGEST) { 330b0104773SPascal Brand uint32_t mks = maxKeySize; 331b0104773SPascal Brand TEE_ObjectType key_type = TEE_ALG_GET_KEY_TYPE(algorithm, 332b0104773SPascal Brand with_private_key); 333b0104773SPascal Brand 334b0104773SPascal Brand /* 335b0104773SPascal Brand * If two keys are expected the max key size is the sum of 336b0104773SPascal Brand * the size of both keys. 337b0104773SPascal Brand */ 338b0104773SPascal Brand if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) 339b0104773SPascal Brand mks /= 2; 340b0104773SPascal Brand 341b0104773SPascal Brand res = TEE_AllocateTransientObject(key_type, mks, &op->key1); 342b0104773SPascal Brand if (res != TEE_SUCCESS) 343b66f219bSJens Wiklander goto out; 344b0104773SPascal Brand 34505304565SCedric Chaumont if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) { 3469b52c538SCedric Chaumont res = TEE_AllocateTransientObject(key_type, mks, 347b0104773SPascal Brand &op->key2); 348b0104773SPascal Brand if (res != TEE_SUCCESS) 349b66f219bSJens Wiklander goto out; 350b0104773SPascal Brand } 351b0104773SPascal Brand } 352b0104773SPascal Brand 3532c028fdeSJerome Forissier res = _utee_cryp_state_alloc(algorithm, mode, (unsigned long)op->key1, 354e86f1266SJens Wiklander (unsigned long)op->key2, &op->state); 355b66f219bSJens Wiklander if (res != TEE_SUCCESS) 356b66f219bSJens Wiklander goto out; 357b0104773SPascal Brand 35805304565SCedric Chaumont /* 35905304565SCedric Chaumont * Initialize digest operations 36005304565SCedric Chaumont * Other multi-stage operations initialized w/ TEE_xxxInit functions 36105304565SCedric Chaumont * Non-applicable on asymmetric operations 36205304565SCedric Chaumont */ 36305304565SCedric Chaumont if (TEE_ALG_GET_CLASS(algorithm) == TEE_OPERATION_DIGEST) { 3642c028fdeSJerome Forissier res = _utee_hash_init(op->state, NULL, 0); 36505304565SCedric Chaumont if (res != TEE_SUCCESS) 366b66f219bSJens Wiklander goto out; 36705304565SCedric Chaumont /* v1.1: flags always set for digest operations */ 36805304565SCedric Chaumont op->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 36905304565SCedric Chaumont } 37005304565SCedric Chaumont 371642a1607SCedric Chaumont op->operationState = TEE_OPERATION_STATE_INITIAL; 372642a1607SCedric Chaumont 373b0104773SPascal Brand *operation = op; 374b0104773SPascal Brand 375b66f219bSJens Wiklander out: 376b66f219bSJens Wiklander if (res != TEE_SUCCESS) { 377b66f219bSJens Wiklander if (res != TEE_ERROR_OUT_OF_MEMORY && 3789b52c538SCedric Chaumont res != TEE_ERROR_NOT_SUPPORTED) 379b36311adSJerome Forissier TEE_Panic(res); 380b66f219bSJens Wiklander if (op) { 381b66f219bSJens Wiklander if (op->state) { 382b66f219bSJens Wiklander TEE_FreeOperation(op); 383b66f219bSJens Wiklander } else { 384b66f219bSJens Wiklander TEE_Free(op->buffer); 385b66f219bSJens Wiklander TEE_FreeTransientObject(op->key1); 386b66f219bSJens Wiklander TEE_FreeTransientObject(op->key2); 387b66f219bSJens Wiklander TEE_Free(op); 388b66f219bSJens Wiklander } 389b66f219bSJens Wiklander } 390b66f219bSJens Wiklander } 391b66f219bSJens Wiklander 392b0104773SPascal Brand return res; 393b0104773SPascal Brand } 394b0104773SPascal Brand 395b0104773SPascal Brand void TEE_FreeOperation(TEE_OperationHandle operation) 396b0104773SPascal Brand { 397e889e80bSCedric Chaumont TEE_Result res; 398e889e80bSCedric Chaumont 399e889e80bSCedric Chaumont if (operation == TEE_HANDLE_NULL) 400*c036e912SJens Wiklander return; 401e889e80bSCedric Chaumont 402b0104773SPascal Brand /* 403b0104773SPascal Brand * Note that keys should not be freed here, since they are 404b0104773SPascal Brand * claimed by the operation they will be freed by 405b0104773SPascal Brand * utee_cryp_state_free(). 406b0104773SPascal Brand */ 4072c028fdeSJerome Forissier res = _utee_cryp_state_free(operation->state); 408e889e80bSCedric Chaumont if (res != TEE_SUCCESS) 409b36311adSJerome Forissier TEE_Panic(res); 410e889e80bSCedric Chaumont 411b0104773SPascal Brand TEE_Free(operation->buffer); 412b0104773SPascal Brand TEE_Free(operation); 413b0104773SPascal Brand } 414b0104773SPascal Brand 415*c036e912SJens Wiklander void __GP11_TEE_FreeOperation(TEE_OperationHandle operation) 416*c036e912SJens Wiklander { 417*c036e912SJens Wiklander if (operation == TEE_HANDLE_NULL) 418*c036e912SJens Wiklander TEE_Panic(0); 419*c036e912SJens Wiklander TEE_FreeOperation(operation); 420*c036e912SJens Wiklander } 421*c036e912SJens Wiklander 422b0104773SPascal Brand void TEE_GetOperationInfo(TEE_OperationHandle operation, 423b0104773SPascal Brand TEE_OperationInfo *operationInfo) 424b0104773SPascal Brand { 425b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 426b0104773SPascal Brand TEE_Panic(0); 427b0104773SPascal Brand 4286915bbbbSJens Wiklander __utee_check_out_annotation(operationInfo, sizeof(*operationInfo)); 429b0104773SPascal Brand 430b0104773SPascal Brand *operationInfo = operation->info; 431bac3a8a7SJens Wiklander if (operationInfo->handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) { 432bac3a8a7SJens Wiklander operationInfo->keySize = 0; 433bac3a8a7SJens Wiklander operationInfo->requiredKeyUsage = 0; 434bac3a8a7SJens Wiklander } 435b0104773SPascal Brand } 436b0104773SPascal Brand 437ee2f75afSJens Wiklander TEE_Result TEE_GetOperationInfoMultiple(TEE_OperationHandle op, 438ee2f75afSJens Wiklander TEE_OperationInfoMultiple *op_info, 439cb98b7b2SJens Wiklander size_t *size) 44005304565SCedric Chaumont { 44105304565SCedric Chaumont TEE_Result res = TEE_SUCCESS; 442ee2f75afSJens Wiklander TEE_ObjectInfo kinfo = { }; 443ee2f75afSJens Wiklander size_t max_key_count = 0; 444ee2f75afSJens Wiklander bool two_keys = false; 44505304565SCedric Chaumont 446ee2f75afSJens Wiklander if (op == TEE_HANDLE_NULL) { 44705304565SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 44805304565SCedric Chaumont goto out; 44905304565SCedric Chaumont } 45005304565SCedric Chaumont 451cb98b7b2SJens Wiklander __utee_check_outbuf_annotation(op_info, size); 45205304565SCedric Chaumont 453ee2f75afSJens Wiklander if (*size < sizeof(*op_info)) { 454ee2f75afSJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 455ee2f75afSJens Wiklander goto out; 456ee2f75afSJens Wiklander } 457ee2f75afSJens Wiklander max_key_count = (*size - sizeof(*op_info)) / 45805304565SCedric Chaumont sizeof(TEE_OperationInfoKey); 45905304565SCedric Chaumont 460ee2f75afSJens Wiklander TEE_MemFill(op_info, 0, *size); 46105304565SCedric Chaumont 46205304565SCedric Chaumont /* Two keys flag (TEE_ALG_AES_XTS only) */ 463ee2f75afSJens Wiklander two_keys = op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS; 464ee2f75afSJens Wiklander 465ee2f75afSJens Wiklander if (op->info.mode == TEE_MODE_DIGEST) { 466ee2f75afSJens Wiklander op_info->numberOfKeys = 0; 467ee2f75afSJens Wiklander } else if (!two_keys) { 468ee2f75afSJens Wiklander if (max_key_count < 1) { 46905304565SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 47005304565SCedric Chaumont goto out; 47105304565SCedric Chaumont } 47205304565SCedric Chaumont 473ee2f75afSJens Wiklander res = TEE_GetObjectInfo1(op->key1, &kinfo); 474ee2f75afSJens Wiklander /* Key1 is not a valid handle, "can't happen". */ 475ee2f75afSJens Wiklander if (res) 47605304565SCedric Chaumont goto out; 47705304565SCedric Chaumont 478d372a47cSJens Wiklander op_info->keyInformation[0].keySize = kinfo.objectSize; 479ee2f75afSJens Wiklander op_info->keyInformation[0].requiredKeyUsage = 480ee2f75afSJens Wiklander op->info.requiredKeyUsage; 481ee2f75afSJens Wiklander op_info->numberOfKeys = 1; 482ee2f75afSJens Wiklander } else { 483ee2f75afSJens Wiklander if (max_key_count < 2) { 484ee2f75afSJens Wiklander res = TEE_ERROR_SHORT_BUFFER; 48505304565SCedric Chaumont goto out; 48605304565SCedric Chaumont } 48705304565SCedric Chaumont 488ee2f75afSJens Wiklander res = TEE_GetObjectInfo1(op->key1, &kinfo); 489ee2f75afSJens Wiklander /* Key1 is not a valid handle, "can't happen". */ 490ee2f75afSJens Wiklander if (res) 491ee2f75afSJens Wiklander goto out; 492ee2f75afSJens Wiklander 493d372a47cSJens Wiklander op_info->keyInformation[0].keySize = kinfo.objectSize; 494ee2f75afSJens Wiklander op_info->keyInformation[0].requiredKeyUsage = 495ee2f75afSJens Wiklander op->info.requiredKeyUsage; 496ee2f75afSJens Wiklander 497ee2f75afSJens Wiklander res = TEE_GetObjectInfo1(op->key2, &kinfo); 498ee2f75afSJens Wiklander /* Key2 is not a valid handle, "can't happen". */ 499ee2f75afSJens Wiklander if (res) 500ee2f75afSJens Wiklander goto out; 501ee2f75afSJens Wiklander 502d372a47cSJens Wiklander op_info->keyInformation[1].keySize = kinfo.objectSize; 503ee2f75afSJens Wiklander op_info->keyInformation[1].requiredKeyUsage = 504ee2f75afSJens Wiklander op->info.requiredKeyUsage; 505ee2f75afSJens Wiklander 506ee2f75afSJens Wiklander op_info->numberOfKeys = 2; 50705304565SCedric Chaumont } 50805304565SCedric Chaumont 509ee2f75afSJens Wiklander op_info->algorithm = op->info.algorithm; 510ee2f75afSJens Wiklander op_info->operationClass = op->info.operationClass; 511ee2f75afSJens Wiklander op_info->mode = op->info.mode; 512ee2f75afSJens Wiklander op_info->digestLength = op->info.digestLength; 513ee2f75afSJens Wiklander op_info->maxKeySize = op->info.maxKeySize; 514ee2f75afSJens Wiklander op_info->handleState = op->info.handleState; 515ee2f75afSJens Wiklander op_info->operationState = op->operationState; 51605304565SCedric Chaumont 51705304565SCedric Chaumont out: 51805304565SCedric Chaumont if (res != TEE_SUCCESS && 51905304565SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 520b36311adSJerome Forissier TEE_Panic(res); 52105304565SCedric Chaumont 52205304565SCedric Chaumont return res; 52305304565SCedric Chaumont } 52405304565SCedric Chaumont 525cb98b7b2SJens Wiklander TEE_Result 526cb98b7b2SJens Wiklander __GP11_TEE_GetOperationInfoMultiple(TEE_OperationHandle operation, 527cb98b7b2SJens Wiklander TEE_OperationInfoMultiple *info, 528cb98b7b2SJens Wiklander uint32_t *operationSize) 529cb98b7b2SJens Wiklander { 530cb98b7b2SJens Wiklander TEE_Result res = TEE_SUCCESS; 531cb98b7b2SJens Wiklander size_t s = 0; 532cb98b7b2SJens Wiklander 533cb98b7b2SJens Wiklander __utee_check_gp11_outbuf_annotation(info, operationSize); 534cb98b7b2SJens Wiklander s = *operationSize; 535cb98b7b2SJens Wiklander res = TEE_GetOperationInfoMultiple(operation, info, &s); 536cb98b7b2SJens Wiklander *operationSize = s; 537cb98b7b2SJens Wiklander return res; 538cb98b7b2SJens Wiklander } 539cb98b7b2SJens Wiklander 540b0104773SPascal Brand void TEE_ResetOperation(TEE_OperationHandle operation) 541b0104773SPascal Brand { 542b0104773SPascal Brand TEE_Result res; 543b0104773SPascal Brand 544b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 545b0104773SPascal Brand TEE_Panic(0); 546bf80076aSCedric Chaumont 547642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET)) 548bf80076aSCedric Chaumont TEE_Panic(0); 549bf80076aSCedric Chaumont 550642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 551642a1607SCedric Chaumont 552b0104773SPascal Brand if (operation->info.operationClass == TEE_OPERATION_DIGEST) { 5532c028fdeSJerome Forissier res = _utee_hash_init(operation->state, NULL, 0); 554b0104773SPascal Brand if (res != TEE_SUCCESS) 555b0104773SPascal Brand TEE_Panic(res); 55605304565SCedric Chaumont operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 55705304565SCedric Chaumont } else { 558b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 559b0104773SPascal Brand } 56005304565SCedric Chaumont } 561b0104773SPascal Brand 562b0104773SPascal Brand TEE_Result TEE_SetOperationKey(TEE_OperationHandle operation, 563b0104773SPascal Brand TEE_ObjectHandle key) 564b0104773SPascal Brand { 5657583c59eSCedric Chaumont TEE_Result res; 566b0104773SPascal Brand uint32_t key_size = 0; 567b0104773SPascal Brand TEE_ObjectInfo key_info; 568b0104773SPascal Brand 569a57c1e2eSCedric Chaumont if (operation == TEE_HANDLE_NULL) { 570a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 571a57c1e2eSCedric Chaumont goto out; 572a57c1e2eSCedric Chaumont } 573a57c1e2eSCedric Chaumont 574642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) { 575642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 576642a1607SCedric Chaumont goto out; 577642a1607SCedric Chaumont } 578642a1607SCedric Chaumont 579a57c1e2eSCedric Chaumont if (key == TEE_HANDLE_NULL) { 580a57c1e2eSCedric Chaumont /* Operation key cleared */ 581a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key1); 5826c4ea258SJens Wiklander operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 5836c4ea258SJens Wiklander return TEE_SUCCESS; 584a57c1e2eSCedric Chaumont } 585a57c1e2eSCedric Chaumont 586a57c1e2eSCedric Chaumont /* No key for digest operation */ 587a57c1e2eSCedric Chaumont if (operation->info.operationClass == TEE_OPERATION_DIGEST) { 588a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 589a57c1e2eSCedric Chaumont goto out; 590a57c1e2eSCedric Chaumont } 591a57c1e2eSCedric Chaumont 592a57c1e2eSCedric Chaumont /* Two keys flag not expected (TEE_ALG_AES_XTS excluded) */ 593a57c1e2eSCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) != 594a57c1e2eSCedric Chaumont 0) { 595a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 596a57c1e2eSCedric Chaumont goto out; 597a57c1e2eSCedric Chaumont } 598a57c1e2eSCedric Chaumont 5997583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key, &key_info); 600a57c1e2eSCedric Chaumont /* Key is not a valid handle */ 6017583c59eSCedric Chaumont if (res != TEE_SUCCESS) 602a57c1e2eSCedric Chaumont goto out; 6037583c59eSCedric Chaumont 604b0104773SPascal Brand /* Supplied key has to meet required usage */ 605b0104773SPascal Brand if ((key_info.objectUsage & operation->info.requiredKeyUsage) != 606b0104773SPascal Brand operation->info.requiredKeyUsage) { 607a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 608a57c1e2eSCedric Chaumont goto out; 609b0104773SPascal Brand } 610b0104773SPascal Brand 611d372a47cSJens Wiklander if (operation->info.maxKeySize < key_info.objectSize) { 612a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 613a57c1e2eSCedric Chaumont goto out; 614a57c1e2eSCedric Chaumont } 615b0104773SPascal Brand 616d372a47cSJens Wiklander key_size = key_info.objectSize; 617b0104773SPascal Brand 618b0104773SPascal Brand TEE_ResetTransientObject(operation->key1); 619b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 620b0104773SPascal Brand 6217583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key1, key); 6227583c59eSCedric Chaumont if (res != TEE_SUCCESS) 623a57c1e2eSCedric Chaumont goto out; 6247583c59eSCedric Chaumont 625b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET; 626b0104773SPascal Brand 627b0104773SPascal Brand operation->info.keySize = key_size; 628b0104773SPascal Brand 6297583c59eSCedric Chaumont out: 630a57c1e2eSCedric Chaumont if (res != TEE_SUCCESS && 631a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 632a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 633b36311adSJerome Forissier TEE_Panic(res); 634a57c1e2eSCedric Chaumont 635a57c1e2eSCedric Chaumont return res; 636b0104773SPascal Brand } 637b0104773SPascal Brand 638b0104773SPascal Brand TEE_Result TEE_SetOperationKey2(TEE_OperationHandle operation, 639b0104773SPascal Brand TEE_ObjectHandle key1, TEE_ObjectHandle key2) 640b0104773SPascal Brand { 6417583c59eSCedric Chaumont TEE_Result res; 642b0104773SPascal Brand uint32_t key_size = 0; 643b0104773SPascal Brand TEE_ObjectInfo key_info1; 644b0104773SPascal Brand TEE_ObjectInfo key_info2; 645b0104773SPascal Brand 646a57c1e2eSCedric Chaumont if (operation == TEE_HANDLE_NULL) { 647a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 648a57c1e2eSCedric Chaumont goto out; 649a57c1e2eSCedric Chaumont } 650a57c1e2eSCedric Chaumont 651642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) { 652642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 653642a1607SCedric Chaumont goto out; 654642a1607SCedric Chaumont } 655642a1607SCedric Chaumont 656a57c1e2eSCedric Chaumont /* 657a57c1e2eSCedric Chaumont * Key1/Key2 and/or are not initialized and 658a57c1e2eSCedric Chaumont * Either both keys are NULL or both are not NULL 659a57c1e2eSCedric Chaumont */ 6606c4ea258SJens Wiklander if (!key1 && !key2) { 6616c4ea258SJens Wiklander /* Clear the keys */ 662a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key1); 663a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key2); 6646c4ea258SJens Wiklander operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 6656c4ea258SJens Wiklander return TEE_SUCCESS; 6666c4ea258SJens Wiklander } else if (!key1 || !key2) { 6676c4ea258SJens Wiklander /* Both keys are obviously not valid. */ 668a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 669a57c1e2eSCedric Chaumont goto out; 670a57c1e2eSCedric Chaumont } 671a57c1e2eSCedric Chaumont 672a57c1e2eSCedric Chaumont /* No key for digest operation */ 673a57c1e2eSCedric Chaumont if (operation->info.operationClass == TEE_OPERATION_DIGEST) { 674a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 675a57c1e2eSCedric Chaumont goto out; 676a57c1e2eSCedric Chaumont } 677a57c1e2eSCedric Chaumont 6785b385b3fSJerome Forissier /* Two keys flag expected (TEE_ALG_AES_XTS and TEE_ALG_SM2_KEP only) */ 679a57c1e2eSCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 680a57c1e2eSCedric Chaumont 0) { 681a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 682a57c1e2eSCedric Chaumont goto out; 683a57c1e2eSCedric Chaumont } 684a57c1e2eSCedric Chaumont 6857583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key1, &key_info1); 686a57c1e2eSCedric Chaumont /* Key1 is not a valid handle */ 6877583c59eSCedric Chaumont if (res != TEE_SUCCESS) 688a57c1e2eSCedric Chaumont goto out; 6897583c59eSCedric Chaumont 690b0104773SPascal Brand /* Supplied key has to meet required usage */ 691b0104773SPascal Brand if ((key_info1.objectUsage & operation->info. 692b0104773SPascal Brand requiredKeyUsage) != operation->info.requiredKeyUsage) { 693a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 694a57c1e2eSCedric Chaumont goto out; 695b0104773SPascal Brand } 696b0104773SPascal Brand 6977583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key2, &key_info2); 698a57c1e2eSCedric Chaumont /* Key2 is not a valid handle */ 6997583c59eSCedric Chaumont if (res != TEE_SUCCESS) { 7007583c59eSCedric Chaumont if (res == TEE_ERROR_CORRUPT_OBJECT) 7017583c59eSCedric Chaumont res = TEE_ERROR_CORRUPT_OBJECT_2; 702a57c1e2eSCedric Chaumont goto out; 7037583c59eSCedric Chaumont } 7047583c59eSCedric Chaumont 705b0104773SPascal Brand /* Supplied key has to meet required usage */ 706b0104773SPascal Brand if ((key_info2.objectUsage & operation->info. 707b0104773SPascal Brand requiredKeyUsage) != operation->info.requiredKeyUsage) { 708a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 709a57c1e2eSCedric Chaumont goto out; 710b0104773SPascal Brand } 711b0104773SPascal Brand 712b0104773SPascal Brand /* 7135b385b3fSJerome Forissier * All the multi key algorithm currently supported requires the keys to 7145b385b3fSJerome Forissier * be of equal size. 715b0104773SPascal Brand */ 716d372a47cSJens Wiklander if (key_info1.objectSize != key_info2.objectSize) { 717a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 718a57c1e2eSCedric Chaumont goto out; 719b0104773SPascal Brand 720a57c1e2eSCedric Chaumont } 721a57c1e2eSCedric Chaumont 722d372a47cSJens Wiklander if (operation->info.maxKeySize < key_info1.objectSize) { 723a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 724a57c1e2eSCedric Chaumont goto out; 725a57c1e2eSCedric Chaumont } 726b0104773SPascal Brand 727b0104773SPascal Brand /* 728b0104773SPascal Brand * Odd that only the size of one key should be reported while 729b0104773SPascal Brand * size of two key are used when allocating the operation. 730b0104773SPascal Brand */ 731d372a47cSJens Wiklander key_size = key_info1.objectSize; 732b0104773SPascal Brand 733b0104773SPascal Brand TEE_ResetTransientObject(operation->key1); 734b0104773SPascal Brand TEE_ResetTransientObject(operation->key2); 735b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 736b0104773SPascal Brand 7377583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key1, key1); 7387583c59eSCedric Chaumont if (res != TEE_SUCCESS) 739a57c1e2eSCedric Chaumont goto out; 7407583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key2, key2); 7417583c59eSCedric Chaumont if (res != TEE_SUCCESS) { 7427583c59eSCedric Chaumont if (res == TEE_ERROR_CORRUPT_OBJECT) 7437583c59eSCedric Chaumont res = TEE_ERROR_CORRUPT_OBJECT_2; 744a57c1e2eSCedric Chaumont goto out; 7457583c59eSCedric Chaumont } 7467583c59eSCedric Chaumont 747b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET; 748b0104773SPascal Brand 749b0104773SPascal Brand operation->info.keySize = key_size; 750b0104773SPascal Brand 7517583c59eSCedric Chaumont out: 752a57c1e2eSCedric Chaumont if (res != TEE_SUCCESS && 753a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 754a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT_2 && 755a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE && 756a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE_2) 757b36311adSJerome Forissier TEE_Panic(res); 758a57c1e2eSCedric Chaumont 759a57c1e2eSCedric Chaumont return res; 760b0104773SPascal Brand } 761b0104773SPascal Brand 762b0104773SPascal Brand void TEE_CopyOperation(TEE_OperationHandle dst_op, TEE_OperationHandle src_op) 763b0104773SPascal Brand { 764b0104773SPascal Brand TEE_Result res; 765b0104773SPascal Brand 766b0104773SPascal Brand if (dst_op == TEE_HANDLE_NULL || src_op == TEE_HANDLE_NULL) 767b0104773SPascal Brand TEE_Panic(0); 768b0104773SPascal Brand if (dst_op->info.algorithm != src_op->info.algorithm) 769b0104773SPascal Brand TEE_Panic(0); 7708734de30SJens Wiklander if (dst_op->info.mode != src_op->info.mode) 7718734de30SJens Wiklander TEE_Panic(0); 772b0104773SPascal Brand if (src_op->info.operationClass != TEE_OPERATION_DIGEST) { 773b0104773SPascal Brand TEE_ObjectHandle key1 = TEE_HANDLE_NULL; 774b0104773SPascal Brand TEE_ObjectHandle key2 = TEE_HANDLE_NULL; 775b0104773SPascal Brand 776b0104773SPascal Brand if (src_op->info.handleState & TEE_HANDLE_FLAG_KEY_SET) { 777b0104773SPascal Brand key1 = src_op->key1; 778b0104773SPascal Brand key2 = src_op->key2; 779b0104773SPascal Brand } 780b0104773SPascal Brand 781b0104773SPascal Brand if ((src_op->info.handleState & 782b0104773SPascal Brand TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 0) { 783b0104773SPascal Brand TEE_SetOperationKey(dst_op, key1); 784b0104773SPascal Brand } else { 785b0104773SPascal Brand TEE_SetOperationKey2(dst_op, key1, key2); 786b0104773SPascal Brand } 787b0104773SPascal Brand } 788b0104773SPascal Brand dst_op->info.handleState = src_op->info.handleState; 789b0104773SPascal Brand dst_op->info.keySize = src_op->info.keySize; 7908e07702eSJens Wiklander dst_op->info.digestLength = src_op->info.digestLength; 791642a1607SCedric Chaumont dst_op->operationState = src_op->operationState; 792b0104773SPascal Brand 793b0104773SPascal Brand if (dst_op->buffer_two_blocks != src_op->buffer_two_blocks || 794b0104773SPascal Brand dst_op->block_size != src_op->block_size) 795b0104773SPascal Brand TEE_Panic(0); 796b0104773SPascal Brand 797b0104773SPascal Brand if (dst_op->buffer != NULL) { 798b0104773SPascal Brand if (src_op->buffer == NULL) 799b0104773SPascal Brand TEE_Panic(0); 800b0104773SPascal Brand 801b0104773SPascal Brand memcpy(dst_op->buffer, src_op->buffer, src_op->buffer_offs); 802b0104773SPascal Brand dst_op->buffer_offs = src_op->buffer_offs; 803b0104773SPascal Brand } else if (src_op->buffer != NULL) { 804b0104773SPascal Brand TEE_Panic(0); 805b0104773SPascal Brand } 806b0104773SPascal Brand 8072c028fdeSJerome Forissier res = _utee_cryp_state_copy(dst_op->state, src_op->state); 808b0104773SPascal Brand if (res != TEE_SUCCESS) 809b0104773SPascal Brand TEE_Panic(res); 810b0104773SPascal Brand } 811b0104773SPascal Brand 812b0104773SPascal Brand /* Cryptographic Operations API - Message Digest Functions */ 813b0104773SPascal Brand 8148f07fe6fSJerome Forissier static void init_hash_operation(TEE_OperationHandle operation, const void *IV, 8156d15db08SJerome Forissier uint32_t IVLen) 8166d15db08SJerome Forissier { 8176d15db08SJerome Forissier TEE_Result res; 8186d15db08SJerome Forissier 8196d15db08SJerome Forissier /* 8206d15db08SJerome Forissier * Note : IV and IVLen are never used in current implementation 8216d15db08SJerome Forissier * This is why coherent values of IV and IVLen are not checked 8226d15db08SJerome Forissier */ 8232c028fdeSJerome Forissier res = _utee_hash_init(operation->state, IV, IVLen); 8246d15db08SJerome Forissier if (res != TEE_SUCCESS) 8256d15db08SJerome Forissier TEE_Panic(res); 8266d15db08SJerome Forissier operation->buffer_offs = 0; 8276d15db08SJerome Forissier operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 8286d15db08SJerome Forissier } 8296d15db08SJerome Forissier 830b0104773SPascal Brand void TEE_DigestUpdate(TEE_OperationHandle operation, 831185bf58cSJens Wiklander const void *chunk, size_t chunkSize) 832b0104773SPascal Brand { 83373d6c3baSJoakim Bech TEE_Result res = TEE_ERROR_GENERIC; 834b0104773SPascal Brand 83573d6c3baSJoakim Bech if (operation == TEE_HANDLE_NULL || 83673d6c3baSJoakim Bech operation->info.operationClass != TEE_OPERATION_DIGEST) 837b0104773SPascal Brand TEE_Panic(0); 83873d6c3baSJoakim Bech 839642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 840642a1607SCedric Chaumont 8412c028fdeSJerome Forissier res = _utee_hash_update(operation->state, chunk, chunkSize); 842b0104773SPascal Brand if (res != TEE_SUCCESS) 843b0104773SPascal Brand TEE_Panic(res); 844b0104773SPascal Brand } 845b0104773SPascal Brand 846185bf58cSJens Wiklander void __GP11_TEE_DigestUpdate(TEE_OperationHandle operation, 847185bf58cSJens Wiklander const void *chunk, uint32_t chunkSize) 848185bf58cSJens Wiklander { 849185bf58cSJens Wiklander return TEE_DigestUpdate(operation, chunk, chunkSize); 850185bf58cSJens Wiklander } 851185bf58cSJens Wiklander 8528f07fe6fSJerome Forissier TEE_Result TEE_DigestDoFinal(TEE_OperationHandle operation, const void *chunk, 853185bf58cSJens Wiklander size_t chunkLen, void *hash, size_t *hashLen) 854b0104773SPascal Brand { 85587c2f6b6SCedric Chaumont TEE_Result res; 856e86f1266SJens Wiklander uint64_t hl; 85787c2f6b6SCedric Chaumont 85887c2f6b6SCedric Chaumont if ((operation == TEE_HANDLE_NULL) || 85987c2f6b6SCedric Chaumont (!chunk && chunkLen) || 86087c2f6b6SCedric Chaumont (operation->info.operationClass != TEE_OPERATION_DIGEST)) { 86187c2f6b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 86287c2f6b6SCedric Chaumont goto out; 86387c2f6b6SCedric Chaumont } 8646915bbbbSJens Wiklander __utee_check_inout_annotation(hashLen, sizeof(*hashLen)); 86587c2f6b6SCedric Chaumont 866e86f1266SJens Wiklander hl = *hashLen; 8672c028fdeSJerome Forissier res = _utee_hash_final(operation->state, chunk, chunkLen, hash, &hl); 868e86f1266SJens Wiklander *hashLen = hl; 8696d15db08SJerome Forissier if (res != TEE_SUCCESS) 8706d15db08SJerome Forissier goto out; 8716d15db08SJerome Forissier 8726d15db08SJerome Forissier /* Reset operation state */ 8736d15db08SJerome Forissier init_hash_operation(operation, NULL, 0); 87487c2f6b6SCedric Chaumont 875642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 876642a1607SCedric Chaumont 87787c2f6b6SCedric Chaumont out: 87887c2f6b6SCedric Chaumont if (res != TEE_SUCCESS && 87987c2f6b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 880b36311adSJerome Forissier TEE_Panic(res); 88173d6c3baSJoakim Bech 88287c2f6b6SCedric Chaumont return res; 883b0104773SPascal Brand } 884b0104773SPascal Brand 885185bf58cSJens Wiklander TEE_Result __GP11_TEE_DigestDoFinal(TEE_OperationHandle operation, 886185bf58cSJens Wiklander const void *chunk, uint32_t chunkLen, 887185bf58cSJens Wiklander void *hash, uint32_t *hashLen) 888185bf58cSJens Wiklander { 889185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 890185bf58cSJens Wiklander size_t l = 0; 891185bf58cSJens Wiklander 892185bf58cSJens Wiklander __utee_check_inout_annotation(hashLen, sizeof(*hashLen)); 893185bf58cSJens Wiklander l = *hashLen; 894185bf58cSJens Wiklander res = TEE_DigestDoFinal(operation, chunk, chunkLen, hash, &l); 895185bf58cSJens Wiklander *hashLen = l; 896185bf58cSJens Wiklander return res; 897185bf58cSJens Wiklander } 898185bf58cSJens Wiklander 899b0104773SPascal Brand /* Cryptographic Operations API - Symmetric Cipher Functions */ 900b0104773SPascal Brand 9018f07fe6fSJerome Forissier void TEE_CipherInit(TEE_OperationHandle operation, const void *IV, 902185bf58cSJens Wiklander size_t IVLen) 903b0104773SPascal Brand { 904b0104773SPascal Brand TEE_Result res; 905b0104773SPascal Brand 906b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 907b0104773SPascal Brand TEE_Panic(0); 908642a1607SCedric Chaumont 909b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_CIPHER) 910b0104773SPascal Brand TEE_Panic(0); 911642a1607SCedric Chaumont 912642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) || 913642a1607SCedric Chaumont !(operation->key1)) 914642a1607SCedric Chaumont TEE_Panic(0); 915642a1607SCedric Chaumont 916642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 917642a1607SCedric Chaumont TEE_ResetOperation(operation); 918642a1607SCedric Chaumont 919ad7aa2a5SSadiq Hussain if (IV && IVLen) { 920ad7aa2a5SSadiq Hussain if (operation->info.algorithm == TEE_ALG_AES_ECB_NOPAD || 921ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_DES_ECB_NOPAD || 922ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_DES3_ECB_NOPAD || 923ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_SM4_ECB_NOPAD) 924ad7aa2a5SSadiq Hussain TEE_Panic(0); 925ad7aa2a5SSadiq Hussain } 926ad7aa2a5SSadiq Hussain 927642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 928642a1607SCedric Chaumont 9292c028fdeSJerome Forissier res = _utee_cipher_init(operation->state, IV, IVLen); 930b0104773SPascal Brand if (res != TEE_SUCCESS) 931b0104773SPascal Brand TEE_Panic(res); 932642a1607SCedric Chaumont 933b0104773SPascal Brand operation->buffer_offs = 0; 934b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 935b0104773SPascal Brand } 936b0104773SPascal Brand 937185bf58cSJens Wiklander void __GP11_TEE_CipherInit(TEE_OperationHandle operation, const void *IV, 938185bf58cSJens Wiklander uint32_t IVLen) 939185bf58cSJens Wiklander { 940185bf58cSJens Wiklander return TEE_CipherInit(operation, IV, IVLen); 941185bf58cSJens Wiklander } 942185bf58cSJens Wiklander 943b0104773SPascal Brand static TEE_Result tee_buffer_update( 944b0104773SPascal Brand TEE_OperationHandle op, 945e86f1266SJens Wiklander TEE_Result(*update_func)(unsigned long state, const void *src, 946e86f1266SJens Wiklander size_t slen, void *dst, uint64_t *dlen), 947b0104773SPascal Brand const void *src_data, size_t src_len, 948e86f1266SJens Wiklander void *dest_data, uint64_t *dest_len) 949b0104773SPascal Brand { 950b0104773SPascal Brand TEE_Result res; 951b0104773SPascal Brand const uint8_t *src = src_data; 952b0104773SPascal Brand size_t slen = src_len; 953b0104773SPascal Brand uint8_t *dst = dest_data; 954b0104773SPascal Brand size_t dlen = *dest_len; 955b0104773SPascal Brand size_t acc_dlen = 0; 956e86f1266SJens Wiklander uint64_t tmp_dlen; 957b0104773SPascal Brand size_t l; 958b0104773SPascal Brand size_t buffer_size; 959d3588802SPascal Brand size_t buffer_left; 960b0104773SPascal Brand 961090268f5SJens Wiklander if (!src) { 962090268f5SJens Wiklander if (slen) 963090268f5SJens Wiklander TEE_Panic(0); 964090268f5SJens Wiklander goto out; 965090268f5SJens Wiklander } 966090268f5SJens Wiklander 967d3588802SPascal Brand if (op->buffer_two_blocks) { 968b0104773SPascal Brand buffer_size = op->block_size * 2; 969d3588802SPascal Brand buffer_left = 1; 970d3588802SPascal Brand } else { 971b0104773SPascal Brand buffer_size = op->block_size; 972d3588802SPascal Brand buffer_left = 0; 973d3588802SPascal Brand } 974b0104773SPascal Brand 975b0104773SPascal Brand if (op->buffer_offs > 0) { 976b0104773SPascal Brand /* Fill up complete block */ 977b0104773SPascal Brand if (op->buffer_offs < op->block_size) 978b0104773SPascal Brand l = MIN(slen, op->block_size - op->buffer_offs); 979b0104773SPascal Brand else 980b0104773SPascal Brand l = MIN(slen, buffer_size - op->buffer_offs); 981b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, l); 982b0104773SPascal Brand op->buffer_offs += l; 983b0104773SPascal Brand src += l; 984b0104773SPascal Brand slen -= l; 985b0104773SPascal Brand if ((op->buffer_offs % op->block_size) != 0) 986b0104773SPascal Brand goto out; /* Nothing left to do */ 987b0104773SPascal Brand } 988b0104773SPascal Brand 989b0104773SPascal Brand /* If we can feed from buffer */ 990d3588802SPascal Brand if ((op->buffer_offs > 0) && 991d3588802SPascal Brand ((op->buffer_offs + slen) >= (buffer_size + buffer_left))) { 9922ff3fdbbSPascal Brand l = ROUNDUP(op->buffer_offs + slen - buffer_size, 993b0104773SPascal Brand op->block_size); 994b0104773SPascal Brand l = MIN(op->buffer_offs, l); 995b0104773SPascal Brand tmp_dlen = dlen; 996b0104773SPascal Brand res = update_func(op->state, op->buffer, l, dst, &tmp_dlen); 997b0104773SPascal Brand if (res != TEE_SUCCESS) 998b0104773SPascal Brand TEE_Panic(res); 999b0104773SPascal Brand dst += tmp_dlen; 1000b0104773SPascal Brand dlen -= tmp_dlen; 1001b0104773SPascal Brand acc_dlen += tmp_dlen; 1002b0104773SPascal Brand op->buffer_offs -= l; 1003b0104773SPascal Brand if (op->buffer_offs > 0) { 1004b0104773SPascal Brand /* 1005b0104773SPascal Brand * Slen is small enough to be contained in rest buffer. 1006b0104773SPascal Brand */ 1007b0104773SPascal Brand memcpy(op->buffer, op->buffer + l, buffer_size - l); 1008b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, slen); 1009b0104773SPascal Brand op->buffer_offs += slen; 1010b0104773SPascal Brand goto out; /* Nothing left to do */ 1011b0104773SPascal Brand } 1012b0104773SPascal Brand } 1013b0104773SPascal Brand 1014d3588802SPascal Brand if (slen >= (buffer_size + buffer_left)) { 1015b0104773SPascal Brand /* Buffer is empty, feed as much as possible from src */ 1016bf7a587fSJerome Forissier if (op->info.algorithm == TEE_ALG_AES_CTS) 1017b1ecda78SJerome Forissier l = ROUNDUP(slen - buffer_size, op->block_size); 1018bf7a587fSJerome Forissier else 1019bf7a587fSJerome Forissier l = ROUNDUP(slen - buffer_size + 1, op->block_size); 1020b0104773SPascal Brand 1021b0104773SPascal Brand tmp_dlen = dlen; 1022b0104773SPascal Brand res = update_func(op->state, src, l, dst, &tmp_dlen); 1023b0104773SPascal Brand if (res != TEE_SUCCESS) 1024b0104773SPascal Brand TEE_Panic(res); 1025b0104773SPascal Brand src += l; 1026b0104773SPascal Brand slen -= l; 1027b0104773SPascal Brand dst += tmp_dlen; 1028b0104773SPascal Brand dlen -= tmp_dlen; 1029b0104773SPascal Brand acc_dlen += tmp_dlen; 1030b0104773SPascal Brand } 1031b0104773SPascal Brand 1032b0104773SPascal Brand /* Slen is small enough to be contained in buffer. */ 1033b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, slen); 1034b0104773SPascal Brand op->buffer_offs += slen; 1035b0104773SPascal Brand 1036b0104773SPascal Brand out: 1037b0104773SPascal Brand *dest_len = acc_dlen; 1038b0104773SPascal Brand return TEE_SUCCESS; 1039b0104773SPascal Brand } 1040b0104773SPascal Brand 10418f07fe6fSJerome Forissier TEE_Result TEE_CipherUpdate(TEE_OperationHandle operation, const void *srcData, 1042185bf58cSJens Wiklander size_t srcLen, void *destData, size_t *destLen) 1043b0104773SPascal Brand { 1044dea1f2b6SCedric Chaumont TEE_Result res; 1045b0104773SPascal Brand size_t req_dlen; 1046e86f1266SJens Wiklander uint64_t dl; 1047b0104773SPascal Brand 10486915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1049dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1050dea1f2b6SCedric Chaumont goto out; 1051dea1f2b6SCedric Chaumont } 10526915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1053dea1f2b6SCedric Chaumont 1054642a1607SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_CIPHER) { 1055dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1056dea1f2b6SCedric Chaumont goto out; 1057dea1f2b6SCedric Chaumont } 1058dea1f2b6SCedric Chaumont 1059642a1607SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1060642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1061642a1607SCedric Chaumont goto out; 1062642a1607SCedric Chaumont } 1063642a1607SCedric Chaumont 1064642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1065dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1066dea1f2b6SCedric Chaumont goto out; 1067dea1f2b6SCedric Chaumont } 1068b0104773SPascal Brand 1069e32c5ddfSJerome Forissier if (!srcData && !srcLen) { 1070090268f5SJens Wiklander *destLen = 0; 1071e32c5ddfSJerome Forissier res = TEE_SUCCESS; 1072e32c5ddfSJerome Forissier goto out; 1073e32c5ddfSJerome Forissier } 1074e32c5ddfSJerome Forissier 1075b0104773SPascal Brand /* Calculate required dlen */ 107657aabac5SBogdan Liulko if (operation->block_size > 1) { 107757aabac5SBogdan Liulko req_dlen = ((operation->buffer_offs + srcLen) / 107857aabac5SBogdan Liulko operation->block_size) * operation->block_size; 107957aabac5SBogdan Liulko } else { 108057aabac5SBogdan Liulko req_dlen = srcLen; 108157aabac5SBogdan Liulko } 1082642a1607SCedric Chaumont if (operation->buffer_two_blocks) { 1083642a1607SCedric Chaumont if (req_dlen > operation->block_size * 2) 1084642a1607SCedric Chaumont req_dlen -= operation->block_size * 2; 1085b0104773SPascal Brand else 1086b0104773SPascal Brand req_dlen = 0; 1087b0104773SPascal Brand } 1088b0104773SPascal Brand /* 1089b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1090b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1091b0104773SPascal Brand * can't restore sync with this API. 1092b0104773SPascal Brand */ 1093b0104773SPascal Brand if (*destLen < req_dlen) { 1094b0104773SPascal Brand *destLen = req_dlen; 1095dea1f2b6SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1096dea1f2b6SCedric Chaumont goto out; 1097b0104773SPascal Brand } 1098b0104773SPascal Brand 1099e86f1266SJens Wiklander dl = *destLen; 110057aabac5SBogdan Liulko if (operation->block_size > 1) { 11012c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_cipher_update, srcData, 110257aabac5SBogdan Liulko srcLen, destData, &dl); 110357aabac5SBogdan Liulko } else { 110457aabac5SBogdan Liulko if (srcLen > 0) { 11052c028fdeSJerome Forissier res = _utee_cipher_update(operation->state, srcData, 110657aabac5SBogdan Liulko srcLen, destData, &dl); 110757aabac5SBogdan Liulko } else { 110857aabac5SBogdan Liulko res = TEE_SUCCESS; 110957aabac5SBogdan Liulko dl = 0; 111057aabac5SBogdan Liulko } 111157aabac5SBogdan Liulko } 1112e86f1266SJens Wiklander *destLen = dl; 1113b0104773SPascal Brand 1114dea1f2b6SCedric Chaumont out: 1115dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS && 1116dea1f2b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1117b36311adSJerome Forissier TEE_Panic(res); 1118dea1f2b6SCedric Chaumont 1119dea1f2b6SCedric Chaumont return res; 1120b0104773SPascal Brand } 1121b0104773SPascal Brand 1122185bf58cSJens Wiklander TEE_Result __GP11_TEE_CipherUpdate(TEE_OperationHandle operation, 11238f07fe6fSJerome Forissier const void *srcData, uint32_t srcLen, 11248f07fe6fSJerome Forissier void *destData, uint32_t *destLen) 1125b0104773SPascal Brand { 11266915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 1127185bf58cSJens Wiklander size_t dl = 0; 1128185bf58cSJens Wiklander 1129185bf58cSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1130185bf58cSJens Wiklander dl = *destLen; 1131185bf58cSJens Wiklander res = TEE_CipherUpdate(operation, srcData, srcLen, destData, &dl); 1132185bf58cSJens Wiklander *destLen = dl; 1133185bf58cSJens Wiklander return res; 1134185bf58cSJens Wiklander } 1135185bf58cSJens Wiklander 1136185bf58cSJens Wiklander TEE_Result TEE_CipherDoFinal(TEE_OperationHandle operation, 1137185bf58cSJens Wiklander const void *srcData, size_t srcLen, 1138185bf58cSJens Wiklander void *destData, size_t *destLen) 1139185bf58cSJens Wiklander { 1140185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 1141b0104773SPascal Brand uint8_t *dst = destData; 1142b0104773SPascal Brand size_t acc_dlen = 0; 11436915bbbbSJens Wiklander uint64_t tmp_dlen = 0; 11446915bbbbSJens Wiklander size_t req_dlen = 0; 1145b0104773SPascal Brand 11466915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1147dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1148dea1f2b6SCedric Chaumont goto out; 1149dea1f2b6SCedric Chaumont } 11506915bbbbSJens Wiklander if (destLen) 11516915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1152dea1f2b6SCedric Chaumont 1153642a1607SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_CIPHER) { 1154dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1155dea1f2b6SCedric Chaumont goto out; 1156dea1f2b6SCedric Chaumont } 1157dea1f2b6SCedric Chaumont 1158642a1607SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1159642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1160642a1607SCedric Chaumont goto out; 1161642a1607SCedric Chaumont } 1162642a1607SCedric Chaumont 1163642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1164dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1165dea1f2b6SCedric Chaumont goto out; 1166dea1f2b6SCedric Chaumont } 1167b0104773SPascal Brand 1168b0104773SPascal Brand /* 1169b0104773SPascal Brand * Check that the final block doesn't require padding for those 1170b0104773SPascal Brand * algorithms that requires client to supply padding. 1171b0104773SPascal Brand */ 1172642a1607SCedric Chaumont if (operation->info.algorithm == TEE_ALG_AES_ECB_NOPAD || 1173642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_AES_CBC_NOPAD || 1174642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES_ECB_NOPAD || 1175642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES_CBC_NOPAD || 1176642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES3_ECB_NOPAD || 1177ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_DES3_CBC_NOPAD || 1178ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_SM4_ECB_NOPAD || 1179ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_SM4_CBC_NOPAD) { 1180642a1607SCedric Chaumont if (((operation->buffer_offs + srcLen) % operation->block_size) 1181642a1607SCedric Chaumont != 0) { 1182dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1183dea1f2b6SCedric Chaumont goto out; 1184dea1f2b6SCedric Chaumont } 1185b0104773SPascal Brand } 1186b0104773SPascal Brand 1187b0104773SPascal Brand /* 1188b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1189b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1190b0104773SPascal Brand * can't restore sync with this API. 1191b0104773SPascal Brand */ 119257aabac5SBogdan Liulko if (operation->block_size > 1) { 1193642a1607SCedric Chaumont req_dlen = operation->buffer_offs + srcLen; 119457aabac5SBogdan Liulko } else { 119557aabac5SBogdan Liulko req_dlen = srcLen; 119657aabac5SBogdan Liulko } 11976915bbbbSJens Wiklander if (destLen) 11986915bbbbSJens Wiklander tmp_dlen = *destLen; 11996915bbbbSJens Wiklander if (tmp_dlen < req_dlen) { 12006915bbbbSJens Wiklander if (destLen) 1201b0104773SPascal Brand *destLen = req_dlen; 1202dea1f2b6SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1203dea1f2b6SCedric Chaumont goto out; 1204b0104773SPascal Brand } 1205b0104773SPascal Brand 120657aabac5SBogdan Liulko if (operation->block_size > 1) { 1207dea9063eSJens Wiklander if (srcLen) { 12082c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_cipher_update, 1209dea9063eSJens Wiklander srcData, srcLen, dst, 1210dea9063eSJens Wiklander &tmp_dlen); 1211dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS) 1212dea1f2b6SCedric Chaumont goto out; 1213dea1f2b6SCedric Chaumont 1214b0104773SPascal Brand dst += tmp_dlen; 1215b0104773SPascal Brand acc_dlen += tmp_dlen; 1216b0104773SPascal Brand 1217b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 1218dea9063eSJens Wiklander } 12192c028fdeSJerome Forissier res = _utee_cipher_final(operation->state, operation->buffer, 12202c028fdeSJerome Forissier operation->buffer_offs, dst, 12212c028fdeSJerome Forissier &tmp_dlen); 122257aabac5SBogdan Liulko } else { 12232c028fdeSJerome Forissier res = _utee_cipher_final(operation->state, srcData, srcLen, dst, 12242c028fdeSJerome Forissier &tmp_dlen); 122557aabac5SBogdan Liulko } 1226b0104773SPascal Brand if (res != TEE_SUCCESS) 1227dea1f2b6SCedric Chaumont goto out; 1228dea1f2b6SCedric Chaumont 1229b0104773SPascal Brand acc_dlen += tmp_dlen; 12306915bbbbSJens Wiklander if (destLen) 1231b0104773SPascal Brand *destLen = acc_dlen; 1232dea1f2b6SCedric Chaumont 1233642a1607SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 1234642a1607SCedric Chaumont 1235642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1236642a1607SCedric Chaumont 1237dea1f2b6SCedric Chaumont out: 1238dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS && 1239dea1f2b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1240b36311adSJerome Forissier TEE_Panic(res); 1241dea1f2b6SCedric Chaumont 1242dea1f2b6SCedric Chaumont return res; 1243b0104773SPascal Brand } 1244b0104773SPascal Brand 1245185bf58cSJens Wiklander TEE_Result __GP11_TEE_CipherDoFinal(TEE_OperationHandle operation, 1246185bf58cSJens Wiklander const void *srcData, uint32_t srcLen, 1247185bf58cSJens Wiklander void *destData, uint32_t *destLen) 1248185bf58cSJens Wiklander { 1249185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 1250185bf58cSJens Wiklander size_t dl = 0; 1251185bf58cSJens Wiklander 1252185bf58cSJens Wiklander if (destLen) { 1253185bf58cSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1254185bf58cSJens Wiklander dl = *destLen; 1255185bf58cSJens Wiklander } 1256185bf58cSJens Wiklander res = TEE_CipherDoFinal(operation, srcData, srcLen, destData, &dl); 1257185bf58cSJens Wiklander if (destLen) 1258185bf58cSJens Wiklander *destLen = dl; 1259185bf58cSJens Wiklander return res; 1260185bf58cSJens Wiklander } 1261185bf58cSJens Wiklander 1262b0104773SPascal Brand /* Cryptographic Operations API - MAC Functions */ 1263b0104773SPascal Brand 1264185bf58cSJens Wiklander void TEE_MACInit(TEE_OperationHandle operation, const void *IV, size_t IVLen) 1265b0104773SPascal Brand { 1266b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 1267b0104773SPascal Brand TEE_Panic(0); 1268642a1607SCedric Chaumont 1269b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_MAC) 1270b0104773SPascal Brand TEE_Panic(0); 1271642a1607SCedric Chaumont 1272642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) || 1273642a1607SCedric Chaumont !(operation->key1)) 1274642a1607SCedric Chaumont TEE_Panic(0); 1275642a1607SCedric Chaumont 1276642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 1277642a1607SCedric Chaumont TEE_ResetOperation(operation); 1278642a1607SCedric Chaumont 1279642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1280642a1607SCedric Chaumont 12816d15db08SJerome Forissier init_hash_operation(operation, IV, IVLen); 1282b0104773SPascal Brand } 1283b0104773SPascal Brand 1284185bf58cSJens Wiklander void __GP11_TEE_MACInit(TEE_OperationHandle operation, const void *IV, 1285185bf58cSJens Wiklander uint32_t IVLen) 1286185bf58cSJens Wiklander { 1287185bf58cSJens Wiklander return TEE_MACInit(operation, IV, IVLen); 1288185bf58cSJens Wiklander } 1289185bf58cSJens Wiklander 12908f07fe6fSJerome Forissier void TEE_MACUpdate(TEE_OperationHandle operation, const void *chunk, 1291185bf58cSJens Wiklander size_t chunkSize) 1292b0104773SPascal Brand { 1293b0104773SPascal Brand TEE_Result res; 1294b0104773SPascal Brand 129528e0efc6SCedric Chaumont if (operation == TEE_HANDLE_NULL || (chunk == NULL && chunkSize != 0)) 1296b0104773SPascal Brand TEE_Panic(0); 1297642a1607SCedric Chaumont 129828e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) 1299b0104773SPascal Brand TEE_Panic(0); 1300642a1607SCedric Chaumont 130128e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 1302b0104773SPascal Brand TEE_Panic(0); 1303b0104773SPascal Brand 1304642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) 1305642a1607SCedric Chaumont TEE_Panic(0); 1306642a1607SCedric Chaumont 13072c028fdeSJerome Forissier res = _utee_hash_update(operation->state, chunk, chunkSize); 1308b0104773SPascal Brand if (res != TEE_SUCCESS) 1309b0104773SPascal Brand TEE_Panic(res); 1310b0104773SPascal Brand } 1311b0104773SPascal Brand 1312185bf58cSJens Wiklander void __GP11_TEE_MACUpdate(TEE_OperationHandle operation, const void *chunk, 1313185bf58cSJens Wiklander uint32_t chunkSize) 1314185bf58cSJens Wiklander { 1315185bf58cSJens Wiklander return TEE_MACUpdate(operation, chunk, chunkSize); 1316185bf58cSJens Wiklander } 1317185bf58cSJens Wiklander 131828e0efc6SCedric Chaumont TEE_Result TEE_MACComputeFinal(TEE_OperationHandle operation, 1319185bf58cSJens Wiklander const void *message, size_t messageLen, 1320185bf58cSJens Wiklander void *mac, size_t *macLen) 1321b0104773SPascal Brand { 1322b0104773SPascal Brand TEE_Result res; 1323e86f1266SJens Wiklander uint64_t ml; 1324b0104773SPascal Brand 13256915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!message && messageLen)) { 132628e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 132728e0efc6SCedric Chaumont goto out; 132828e0efc6SCedric Chaumont } 13296915bbbbSJens Wiklander __utee_check_inout_annotation(macLen, sizeof(*macLen)); 1330b0104773SPascal Brand 133128e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) { 133228e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 133328e0efc6SCedric Chaumont goto out; 133428e0efc6SCedric Chaumont } 133528e0efc6SCedric Chaumont 133628e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 133728e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 133828e0efc6SCedric Chaumont goto out; 133928e0efc6SCedric Chaumont } 134028e0efc6SCedric Chaumont 1341642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1342642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1343642a1607SCedric Chaumont goto out; 1344642a1607SCedric Chaumont } 1345642a1607SCedric Chaumont 1346e86f1266SJens Wiklander ml = *macLen; 13472c028fdeSJerome Forissier res = _utee_hash_final(operation->state, message, messageLen, mac, &ml); 1348e86f1266SJens Wiklander *macLen = ml; 134928e0efc6SCedric Chaumont if (res != TEE_SUCCESS) 135028e0efc6SCedric Chaumont goto out; 135128e0efc6SCedric Chaumont 135228e0efc6SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 135328e0efc6SCedric Chaumont 1354642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1355642a1607SCedric Chaumont 135628e0efc6SCedric Chaumont out: 135728e0efc6SCedric Chaumont if (res != TEE_SUCCESS && 135828e0efc6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 135928e0efc6SCedric Chaumont TEE_Panic(res); 136028e0efc6SCedric Chaumont 1361b0104773SPascal Brand return res; 1362b0104773SPascal Brand } 1363b0104773SPascal Brand 1364185bf58cSJens Wiklander TEE_Result __GP11_TEE_MACComputeFinal(TEE_OperationHandle operation, 13658f07fe6fSJerome Forissier const void *message, uint32_t messageLen, 1366185bf58cSJens Wiklander void *mac, uint32_t *macLen) 1367185bf58cSJens Wiklander { 1368185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 1369185bf58cSJens Wiklander size_t ml = 0; 1370185bf58cSJens Wiklander 1371185bf58cSJens Wiklander __utee_check_inout_annotation(macLen, sizeof(*macLen)); 1372185bf58cSJens Wiklander ml = *macLen; 1373185bf58cSJens Wiklander res = TEE_MACComputeFinal(operation, message, messageLen, mac, &ml); 1374185bf58cSJens Wiklander *macLen = ml; 1375185bf58cSJens Wiklander return res; 1376185bf58cSJens Wiklander } 1377185bf58cSJens Wiklander 1378185bf58cSJens Wiklander TEE_Result TEE_MACCompareFinal(TEE_OperationHandle operation, 1379185bf58cSJens Wiklander const void *message, size_t messageLen, 1380185bf58cSJens Wiklander const void *mac, size_t macLen) 1381b0104773SPascal Brand { 1382b0104773SPascal Brand TEE_Result res; 1383ee4ba3d1SVictor Chong uint8_t computed_mac[TEE_MAX_HASH_SIZE] = { 0 }; 1384185bf58cSJens Wiklander size_t computed_mac_size = TEE_MAX_HASH_SIZE; 1385b0104773SPascal Brand 138628e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) { 138728e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 138828e0efc6SCedric Chaumont goto out; 138928e0efc6SCedric Chaumont } 139028e0efc6SCedric Chaumont 139128e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 139228e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 139328e0efc6SCedric Chaumont goto out; 139428e0efc6SCedric Chaumont } 139528e0efc6SCedric Chaumont 1396642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1397642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1398642a1607SCedric Chaumont goto out; 1399642a1607SCedric Chaumont } 1400642a1607SCedric Chaumont 1401b0104773SPascal Brand res = TEE_MACComputeFinal(operation, message, messageLen, computed_mac, 1402b0104773SPascal Brand &computed_mac_size); 1403b0104773SPascal Brand if (res != TEE_SUCCESS) 140428e0efc6SCedric Chaumont goto out; 140528e0efc6SCedric Chaumont 140628e0efc6SCedric Chaumont if (computed_mac_size != macLen) { 140728e0efc6SCedric Chaumont res = TEE_ERROR_MAC_INVALID; 140828e0efc6SCedric Chaumont goto out; 140928e0efc6SCedric Chaumont } 141028e0efc6SCedric Chaumont 141148e10604SJerome Forissier if (consttime_memcmp(mac, computed_mac, computed_mac_size) != 0) { 141228e0efc6SCedric Chaumont res = TEE_ERROR_MAC_INVALID; 141328e0efc6SCedric Chaumont goto out; 141428e0efc6SCedric Chaumont } 141528e0efc6SCedric Chaumont 1416642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1417642a1607SCedric Chaumont 141828e0efc6SCedric Chaumont out: 141928e0efc6SCedric Chaumont if (res != TEE_SUCCESS && 142028e0efc6SCedric Chaumont res != TEE_ERROR_MAC_INVALID) 142128e0efc6SCedric Chaumont TEE_Panic(res); 142228e0efc6SCedric Chaumont 1423b0104773SPascal Brand return res; 1424b0104773SPascal Brand } 1425b0104773SPascal Brand 1426185bf58cSJens Wiklander TEE_Result __GP11_TEE_MACCompareFinal(TEE_OperationHandle operation, 1427185bf58cSJens Wiklander const void *message, uint32_t messageLen, 1428185bf58cSJens Wiklander const void *mac, uint32_t macLen) 1429185bf58cSJens Wiklander { 1430185bf58cSJens Wiklander return TEE_MACCompareFinal(operation, message, messageLen, mac, macLen); 1431185bf58cSJens Wiklander } 1432185bf58cSJens Wiklander 1433b0104773SPascal Brand /* Cryptographic Operations API - Authenticated Encryption Functions */ 1434b0104773SPascal Brand 14358f07fe6fSJerome Forissier TEE_Result TEE_AEInit(TEE_OperationHandle operation, const void *nonce, 1436d9096215SJens Wiklander size_t nonceLen, uint32_t tagLen, size_t AADLen, 1437d9096215SJens Wiklander size_t payloadLen) 1438b0104773SPascal Brand { 1439b0104773SPascal Brand TEE_Result res; 1440b0104773SPascal Brand 1441b5816c88SCedric Chaumont if (operation == TEE_HANDLE_NULL || nonce == NULL) { 1442b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1443b5816c88SCedric Chaumont goto out; 1444b5816c88SCedric Chaumont } 1445b5816c88SCedric Chaumont 1446b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1447b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1448b5816c88SCedric Chaumont goto out; 1449b5816c88SCedric Chaumont } 1450b0104773SPascal Brand 1451642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) { 1452642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1453642a1607SCedric Chaumont goto out; 1454642a1607SCedric Chaumont } 1455642a1607SCedric Chaumont 1456b0104773SPascal Brand /* 1457b0104773SPascal Brand * AES-CCM tag len is specified by AES-CCM spec and handled in TEE Core 1458b0104773SPascal Brand * in the implementation. But AES-GCM spec doesn't specify the tag len 1459b0104773SPascal Brand * according to the same principle so we have to check here instead to 1460b0104773SPascal Brand * be GP compliant. 1461b0104773SPascal Brand */ 1462b5816c88SCedric Chaumont if (operation->info.algorithm == TEE_ALG_AES_GCM) { 1463b0104773SPascal Brand /* 1464b0104773SPascal Brand * From GP spec: For AES-GCM, can be 128, 120, 112, 104, or 96 1465b0104773SPascal Brand */ 1466b5816c88SCedric Chaumont if (tagLen < 96 || tagLen > 128 || (tagLen % 8 != 0)) { 1467b5816c88SCedric Chaumont res = TEE_ERROR_NOT_SUPPORTED; 1468b5816c88SCedric Chaumont goto out; 1469b5816c88SCedric Chaumont } 1470b0104773SPascal Brand } 1471b0104773SPascal Brand 14722c028fdeSJerome Forissier res = _utee_authenc_init(operation->state, nonce, nonceLen, tagLen / 8, 14732c028fdeSJerome Forissier AADLen, payloadLen); 1474b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1475b5816c88SCedric Chaumont goto out; 1476b5816c88SCedric Chaumont 14777acaf5adSAlbert Schwarzkopf operation->info.digestLength = tagLen / 8; 1478f2674567SSumit Garg operation->buffer_offs = 0; 1479b5816c88SCedric Chaumont operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 1480b5816c88SCedric Chaumont 1481b5816c88SCedric Chaumont out: 1482b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1483b5816c88SCedric Chaumont res != TEE_ERROR_NOT_SUPPORTED) 1484b0104773SPascal Brand TEE_Panic(res); 1485b5816c88SCedric Chaumont 1486b0104773SPascal Brand return res; 1487b0104773SPascal Brand } 1488b0104773SPascal Brand 1489d9096215SJens Wiklander TEE_Result __GP11_TEE_AEInit(TEE_OperationHandle operation, const void *nonce, 1490d9096215SJens Wiklander uint32_t nonceLen, uint32_t tagLen, 1491d9096215SJens Wiklander uint32_t AADLen, uint32_t payloadLen) 1492d9096215SJens Wiklander { 1493d9096215SJens Wiklander return TEE_AEInit(operation, nonce, nonceLen, tagLen, AADLen, 1494d9096215SJens Wiklander payloadLen); 1495d9096215SJens Wiklander } 1496d9096215SJens Wiklander 14978f07fe6fSJerome Forissier void TEE_AEUpdateAAD(TEE_OperationHandle operation, const void *AADdata, 1498d9096215SJens Wiklander size_t AADdataLen) 1499d9096215SJens Wiklander { 1500d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1501d9096215SJens Wiklander 1502d9096215SJens Wiklander if (operation == TEE_HANDLE_NULL || (!AADdata && AADdataLen)) 1503d9096215SJens Wiklander TEE_Panic(0); 1504d9096215SJens Wiklander 1505d9096215SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_AE) 1506d9096215SJens Wiklander TEE_Panic(0); 1507d9096215SJens Wiklander 1508d9096215SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 1509d9096215SJens Wiklander TEE_Panic(0); 1510d9096215SJens Wiklander 1511d9096215SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 1512d9096215SJens Wiklander TEE_Panic(0); 1513d9096215SJens Wiklander 1514d9096215SJens Wiklander res = _utee_authenc_update_aad(operation->state, AADdata, AADdataLen); 1515d9096215SJens Wiklander if (res != TEE_SUCCESS) 1516d9096215SJens Wiklander TEE_Panic(res); 1517d9096215SJens Wiklander } 1518d9096215SJens Wiklander 1519d9096215SJens Wiklander void __GP11_TEE_AEUpdateAAD(TEE_OperationHandle operation, const void *AADdata, 152079a3c601SCedric Chaumont uint32_t AADdataLen) 1521b0104773SPascal Brand { 1522d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1523b0104773SPascal Brand 1524b5816c88SCedric Chaumont if (operation == TEE_HANDLE_NULL || 1525b5816c88SCedric Chaumont (AADdata == NULL && AADdataLen != 0)) 1526b0104773SPascal Brand TEE_Panic(0); 1527642a1607SCedric Chaumont 1528b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) 1529b0104773SPascal Brand TEE_Panic(0); 1530642a1607SCedric Chaumont 1531b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 1532b0104773SPascal Brand TEE_Panic(0); 1533b0104773SPascal Brand 15342c028fdeSJerome Forissier res = _utee_authenc_update_aad(operation->state, AADdata, AADdataLen); 1535642a1607SCedric Chaumont 1536642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1537642a1607SCedric Chaumont 1538b0104773SPascal Brand if (res != TEE_SUCCESS) 1539b0104773SPascal Brand TEE_Panic(res); 1540b0104773SPascal Brand } 1541b0104773SPascal Brand 1542d9096215SJens Wiklander static TEE_Result ae_update_helper(TEE_OperationHandle operation, 1543d9096215SJens Wiklander const void *src, size_t slen, void *dst, 1544d9096215SJens Wiklander size_t *dlen) 1545b0104773SPascal Brand { 15466915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 15476915bbbbSJens Wiklander size_t req_dlen = 0; 15486915bbbbSJens Wiklander uint64_t dl = 0; 1549b0104773SPascal Brand 1550d9096215SJens Wiklander if (!src && !slen) { 1551d9096215SJens Wiklander *dlen = 0; 1552d9096215SJens Wiklander return TEE_SUCCESS; 1553d9096215SJens Wiklander } 1554d9096215SJens Wiklander 1555d9096215SJens Wiklander /* 1556d9096215SJens Wiklander * Check that required destLen is big enough before starting to feed 1557d9096215SJens Wiklander * data to the algorithm. Errors during feeding of data are fatal as we 1558d9096215SJens Wiklander * can't restore sync with this API. 1559d9096215SJens Wiklander */ 1560d9096215SJens Wiklander if (operation->block_size > 1) { 1561d9096215SJens Wiklander req_dlen = ROUNDDOWN(operation->buffer_offs + slen, 1562d9096215SJens Wiklander operation->block_size); 1563d9096215SJens Wiklander } else { 1564d9096215SJens Wiklander req_dlen = slen; 1565d9096215SJens Wiklander } 1566d9096215SJens Wiklander 1567d9096215SJens Wiklander dl = *dlen; 1568d9096215SJens Wiklander if (dl < req_dlen) { 1569d9096215SJens Wiklander *dlen = req_dlen; 1570d9096215SJens Wiklander return TEE_ERROR_SHORT_BUFFER; 1571d9096215SJens Wiklander } 1572d9096215SJens Wiklander 1573d9096215SJens Wiklander if (operation->block_size > 1) { 1574d9096215SJens Wiklander res = tee_buffer_update(operation, _utee_authenc_update_payload, 1575d9096215SJens Wiklander src, slen, dst, &dl); 1576d9096215SJens Wiklander } else { 1577d9096215SJens Wiklander if (slen > 0) { 1578d9096215SJens Wiklander res = _utee_authenc_update_payload(operation->state, 1579d9096215SJens Wiklander src, slen, dst, &dl); 1580d9096215SJens Wiklander } else { 1581d9096215SJens Wiklander dl = 0; 1582d9096215SJens Wiklander res = TEE_SUCCESS; 1583d9096215SJens Wiklander } 1584d9096215SJens Wiklander } 1585d9096215SJens Wiklander 1586d9096215SJens Wiklander if (!res) 1587d9096215SJens Wiklander *dlen = dl; 1588d9096215SJens Wiklander 1589d9096215SJens Wiklander return res; 1590d9096215SJens Wiklander } 1591d9096215SJens Wiklander 1592d9096215SJens Wiklander TEE_Result TEE_AEUpdate(TEE_OperationHandle operation, const void *srcData, 1593d9096215SJens Wiklander size_t srcLen, void *destData, size_t *destLen) 1594d9096215SJens Wiklander { 1595d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1596d9096215SJens Wiklander 15976915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1598b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1599b5816c88SCedric Chaumont goto out; 1600b5816c88SCedric Chaumont } 1601d9096215SJens Wiklander __utee_check_outbuf_annotation(destData, destLen); 1602b5816c88SCedric Chaumont 1603b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1604b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1605b5816c88SCedric Chaumont goto out; 1606b5816c88SCedric Chaumont } 1607b5816c88SCedric Chaumont 1608b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1609b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1610b5816c88SCedric Chaumont goto out; 1611b5816c88SCedric Chaumont } 1612b0104773SPascal Brand 1613d9096215SJens Wiklander res = ae_update_helper(operation, srcData, srcLen, destData, destLen); 1614d9096215SJens Wiklander if (res != TEE_ERROR_SHORT_BUFFER && srcLen) 1615d9096215SJens Wiklander operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1616d9096215SJens Wiklander 1617d9096215SJens Wiklander out: 1618d9096215SJens Wiklander if (res != TEE_SUCCESS && 1619d9096215SJens Wiklander res != TEE_ERROR_SHORT_BUFFER) 1620d9096215SJens Wiklander TEE_Panic(res); 1621d9096215SJens Wiklander 1622d9096215SJens Wiklander return res; 1623d9096215SJens Wiklander } 1624d9096215SJens Wiklander 1625d9096215SJens Wiklander TEE_Result __GP11_TEE_AEUpdate(TEE_OperationHandle operation, 1626d9096215SJens Wiklander const void *srcData, uint32_t srcLen, 1627d9096215SJens Wiklander void *destData, uint32_t *destLen) 1628d9096215SJens Wiklander { 1629d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1630d9096215SJens Wiklander size_t dl = 0; 1631d9096215SJens Wiklander 1632d9096215SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1633d9096215SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1634d9096215SJens Wiklander goto out; 1635d9096215SJens Wiklander } 1636d9096215SJens Wiklander __utee_check_gp11_outbuf_annotation(destData, destLen); 1637d9096215SJens Wiklander 1638d9096215SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_AE) { 1639d9096215SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1640827308b8SJerome Forissier goto out; 1641827308b8SJerome Forissier } 1642827308b8SJerome Forissier 1643d9096215SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1644d9096215SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1645d9096215SJens Wiklander goto out; 1646afc0c182SBogdan Liulko } 1647afc0c182SBogdan Liulko 16486915bbbbSJens Wiklander dl = *destLen; 1649d9096215SJens Wiklander res = ae_update_helper(operation, srcData, srcLen, destData, &dl); 1650d9096215SJens Wiklander *destLen = dl; 1651b0104773SPascal Brand 1652afc0c182SBogdan Liulko if (res != TEE_SUCCESS) 1653afc0c182SBogdan Liulko goto out; 1654afc0c182SBogdan Liulko 1655642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1656642a1607SCedric Chaumont 1657b5816c88SCedric Chaumont out: 1658b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1659b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1660b5816c88SCedric Chaumont TEE_Panic(res); 1661b5816c88SCedric Chaumont 1662b5816c88SCedric Chaumont return res; 1663b0104773SPascal Brand } 1664b0104773SPascal Brand 1665b5816c88SCedric Chaumont TEE_Result TEE_AEEncryptFinal(TEE_OperationHandle operation, 1666d9096215SJens Wiklander const void *srcData, size_t srcLen, 1667d9096215SJens Wiklander void *destData, size_t *destLen, void *tag, 1668d9096215SJens Wiklander size_t *tagLen) 1669b0104773SPascal Brand { 1670d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1671b0104773SPascal Brand uint8_t *dst = destData; 1672b0104773SPascal Brand size_t acc_dlen = 0; 1673d9096215SJens Wiklander uint64_t tmp_dlen = 0; 1674d9096215SJens Wiklander size_t req_dlen = 0; 1675d9096215SJens Wiklander uint64_t tl = 0; 1676b0104773SPascal Brand 16776915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1678b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1679b5816c88SCedric Chaumont goto out; 1680b5816c88SCedric Chaumont } 16816915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 16826915bbbbSJens Wiklander __utee_check_inout_annotation(tagLen, sizeof(*tagLen)); 1683b5816c88SCedric Chaumont 1684b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1685b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1686b5816c88SCedric Chaumont goto out; 1687b5816c88SCedric Chaumont } 1688b5816c88SCedric Chaumont 1689b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1690b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1691b5816c88SCedric Chaumont goto out; 1692b5816c88SCedric Chaumont } 1693b0104773SPascal Brand 1694b0104773SPascal Brand /* 1695b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1696b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1697b0104773SPascal Brand * can't restore sync with this API. 16982733280aSEtienne Carriere * 16992733280aSEtienne Carriere * Need to check this before update_payload since sync would be lost if 17002733280aSEtienne Carriere * we return short buffer after that. 1701b0104773SPascal Brand */ 17022733280aSEtienne Carriere res = TEE_ERROR_GENERIC; 17032733280aSEtienne Carriere 1704b5816c88SCedric Chaumont req_dlen = operation->buffer_offs + srcLen; 1705b0104773SPascal Brand if (*destLen < req_dlen) { 1706b0104773SPascal Brand *destLen = req_dlen; 1707b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1708b0104773SPascal Brand } 1709b0104773SPascal Brand 17107acaf5adSAlbert Schwarzkopf if (*tagLen < operation->info.digestLength) { 17117acaf5adSAlbert Schwarzkopf *tagLen = operation->info.digestLength; 1712b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1713b0104773SPascal Brand } 1714b0104773SPascal Brand 17152733280aSEtienne Carriere if (res == TEE_ERROR_SHORT_BUFFER) 17162733280aSEtienne Carriere goto out; 17172733280aSEtienne Carriere 1718afc0c182SBogdan Liulko tl = *tagLen; 1719b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 1720afc0c182SBogdan Liulko if (operation->block_size > 1) { 17212c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_authenc_update_payload, 1722afc0c182SBogdan Liulko srcData, srcLen, dst, &tmp_dlen); 1723b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1724b5816c88SCedric Chaumont goto out; 1725b5816c88SCedric Chaumont 1726b0104773SPascal Brand dst += tmp_dlen; 1727b0104773SPascal Brand acc_dlen += tmp_dlen; 1728b0104773SPascal Brand 1729b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 17302c028fdeSJerome Forissier res = _utee_authenc_enc_final(operation->state, 1731afc0c182SBogdan Liulko operation->buffer, 1732afc0c182SBogdan Liulko operation->buffer_offs, dst, 1733afc0c182SBogdan Liulko &tmp_dlen, tag, &tl); 1734afc0c182SBogdan Liulko } else { 17352c028fdeSJerome Forissier res = _utee_authenc_enc_final(operation->state, srcData, 1736afc0c182SBogdan Liulko srcLen, dst, &tmp_dlen, 1737e86f1266SJens Wiklander tag, &tl); 1738afc0c182SBogdan Liulko } 1739e86f1266SJens Wiklander *tagLen = tl; 1740b0104773SPascal Brand if (res != TEE_SUCCESS) 1741b5816c88SCedric Chaumont goto out; 1742b0104773SPascal Brand 1743b5816c88SCedric Chaumont acc_dlen += tmp_dlen; 1744b0104773SPascal Brand *destLen = acc_dlen; 1745642a1607SCedric Chaumont 1746b5816c88SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 1747b5816c88SCedric Chaumont 1748642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1749642a1607SCedric Chaumont 1750b5816c88SCedric Chaumont out: 1751b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1752b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1753b5816c88SCedric Chaumont TEE_Panic(res); 1754b0104773SPascal Brand 1755b0104773SPascal Brand return res; 1756b0104773SPascal Brand } 1757b0104773SPascal Brand 1758d9096215SJens Wiklander TEE_Result __GP11_TEE_AEEncryptFinal(TEE_OperationHandle operation, 17598f07fe6fSJerome Forissier const void *srcData, uint32_t srcLen, 1760d9096215SJens Wiklander void *destData, uint32_t *destLen, 1761d9096215SJens Wiklander void *tag, uint32_t *tagLen) 1762b0104773SPascal Brand { 1763d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1764d9096215SJens Wiklander size_t dl = 0; 1765d9096215SJens Wiklander size_t tl = 0; 1766d9096215SJens Wiklander 1767d9096215SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1768d9096215SJens Wiklander __utee_check_inout_annotation(tagLen, sizeof(*tagLen)); 1769d9096215SJens Wiklander dl = *destLen; 1770d9096215SJens Wiklander tl = *tagLen; 1771d9096215SJens Wiklander res = TEE_AEEncryptFinal(operation, srcData, srcLen, destData, &dl, 1772d9096215SJens Wiklander tag, &tl); 1773d9096215SJens Wiklander *destLen = dl; 1774d9096215SJens Wiklander *tagLen = tl; 1775d9096215SJens Wiklander return res; 1776d9096215SJens Wiklander } 1777d9096215SJens Wiklander 1778d9096215SJens Wiklander TEE_Result TEE_AEDecryptFinal(TEE_OperationHandle operation, 1779d9096215SJens Wiklander const void *srcData, size_t srcLen, 1780d9096215SJens Wiklander void *destData, size_t *destLen, void *tag, 1781d9096215SJens Wiklander size_t tagLen) 1782d9096215SJens Wiklander { 1783d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1784b0104773SPascal Brand uint8_t *dst = destData; 1785b0104773SPascal Brand size_t acc_dlen = 0; 1786d9096215SJens Wiklander uint64_t tmp_dlen = 0; 1787d9096215SJens Wiklander size_t req_dlen = 0; 1788b0104773SPascal Brand 17896915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1790b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1791b5816c88SCedric Chaumont goto out; 1792b5816c88SCedric Chaumont } 17936915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1794b5816c88SCedric Chaumont 1795b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1796b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1797b5816c88SCedric Chaumont goto out; 1798b5816c88SCedric Chaumont } 1799b5816c88SCedric Chaumont 1800b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1801b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1802b5816c88SCedric Chaumont goto out; 1803b5816c88SCedric Chaumont } 1804b0104773SPascal Brand 1805b0104773SPascal Brand /* 1806b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1807b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1808b0104773SPascal Brand * can't restore sync with this API. 1809b0104773SPascal Brand */ 1810b5816c88SCedric Chaumont req_dlen = operation->buffer_offs + srcLen; 1811b0104773SPascal Brand if (*destLen < req_dlen) { 1812b0104773SPascal Brand *destLen = req_dlen; 1813b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1814b5816c88SCedric Chaumont goto out; 1815b0104773SPascal Brand } 1816b0104773SPascal Brand 1817b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 1818afc0c182SBogdan Liulko if (operation->block_size > 1) { 18192c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_authenc_update_payload, 1820afc0c182SBogdan Liulko srcData, srcLen, dst, &tmp_dlen); 1821b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1822b5816c88SCedric Chaumont goto out; 1823b5816c88SCedric Chaumont 1824b0104773SPascal Brand dst += tmp_dlen; 1825b0104773SPascal Brand acc_dlen += tmp_dlen; 1826b0104773SPascal Brand 1827b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 18282c028fdeSJerome Forissier res = _utee_authenc_dec_final(operation->state, 1829afc0c182SBogdan Liulko operation->buffer, 1830afc0c182SBogdan Liulko operation->buffer_offs, dst, 1831afc0c182SBogdan Liulko &tmp_dlen, tag, tagLen); 1832afc0c182SBogdan Liulko } else { 18332c028fdeSJerome Forissier res = _utee_authenc_dec_final(operation->state, srcData, 1834afc0c182SBogdan Liulko srcLen, dst, &tmp_dlen, 1835b5816c88SCedric Chaumont tag, tagLen); 1836afc0c182SBogdan Liulko } 1837b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1838b5816c88SCedric Chaumont goto out; 1839b5816c88SCedric Chaumont 1840b0104773SPascal Brand /* Supplied tagLen should match what we initiated with */ 18417acaf5adSAlbert Schwarzkopf if (tagLen != operation->info.digestLength) 1842b0104773SPascal Brand res = TEE_ERROR_MAC_INVALID; 1843b0104773SPascal Brand 1844b0104773SPascal Brand acc_dlen += tmp_dlen; 1845b0104773SPascal Brand *destLen = acc_dlen; 1846642a1607SCedric Chaumont 1847b5816c88SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 1848b5816c88SCedric Chaumont 1849642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1850642a1607SCedric Chaumont 1851b5816c88SCedric Chaumont out: 1852b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1853b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER && 1854b5816c88SCedric Chaumont res != TEE_ERROR_MAC_INVALID) 1855b5816c88SCedric Chaumont TEE_Panic(res); 1856b0104773SPascal Brand 1857b0104773SPascal Brand return res; 1858b0104773SPascal Brand } 1859b0104773SPascal Brand 1860d9096215SJens Wiklander TEE_Result __GP11_TEE_AEDecryptFinal(TEE_OperationHandle operation, 1861d9096215SJens Wiklander const void *srcData, uint32_t srcLen, 1862d9096215SJens Wiklander void *destData, uint32_t *destLen, 1863d9096215SJens Wiklander void *tag, uint32_t tagLen) 1864d9096215SJens Wiklander { 1865d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1866d9096215SJens Wiklander size_t dl = 0; 1867d9096215SJens Wiklander 1868d9096215SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1869d9096215SJens Wiklander dl = *destLen; 1870d9096215SJens Wiklander res = TEE_AEDecryptFinal(operation, srcData, srcLen, destData, &dl, 1871d9096215SJens Wiklander tag, tagLen); 1872d9096215SJens Wiklander *destLen = dl; 1873d9096215SJens Wiklander return res; 1874d9096215SJens Wiklander } 1875d9096215SJens Wiklander 1876b0104773SPascal Brand /* Cryptographic Operations API - Asymmetric Functions */ 1877b0104773SPascal Brand 187812e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricEncrypt(TEE_OperationHandle operation, 18798f07fe6fSJerome Forissier const TEE_Attribute *params, 18808f07fe6fSJerome Forissier uint32_t paramCount, const void *srcData, 1881999b69d0SJens Wiklander size_t srcLen, void *destData, 1882999b69d0SJens Wiklander size_t *destLen) 1883b0104773SPascal Brand { 18846915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 1885e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 18866915bbbbSJens Wiklander uint64_t dl = 0; 1887b0104773SPascal Brand 18886915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 1889b0104773SPascal Brand TEE_Panic(0); 18906915bbbbSJens Wiklander 18916915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 18926915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 18936915bbbbSJens Wiklander 189412e66b6fSCedric Chaumont if (!operation->key1) 1895b0104773SPascal Brand TEE_Panic(0); 189612e66b6fSCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 189712e66b6fSCedric Chaumont TEE_Panic(0); 189812e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_ENCRYPT) 1899b0104773SPascal Brand TEE_Panic(0); 1900b0104773SPascal Brand 1901e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 1902e86f1266SJens Wiklander dl = *destLen; 19032c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 1904e86f1266SJens Wiklander srcLen, destData, &dl); 1905e86f1266SJens Wiklander *destLen = dl; 190612e66b6fSCedric Chaumont 19078844ebfcSPascal Brand if (res != TEE_SUCCESS && 19088844ebfcSPascal Brand res != TEE_ERROR_SHORT_BUFFER && 19098844ebfcSPascal Brand res != TEE_ERROR_BAD_PARAMETERS) 1910b0104773SPascal Brand TEE_Panic(res); 191112e66b6fSCedric Chaumont 1912b0104773SPascal Brand return res; 1913b0104773SPascal Brand } 1914b0104773SPascal Brand 19154f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricEncrypt(TEE_OperationHandle operation, 19164f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 19174f4374c8SJens Wiklander uint32_t paramCount, 19184f4374c8SJens Wiklander const void *srcData, uint32_t srcLen, 19194f4374c8SJens Wiklander void *destData, uint32_t *destLen) 19204f4374c8SJens Wiklander { 19214f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 19224f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 19234f4374c8SJens Wiklander uint64_t dl = 0; 19244f4374c8SJens Wiklander 19254f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 19264f4374c8SJens Wiklander TEE_Panic(0); 19274f4374c8SJens Wiklander 19284f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 19294f4374c8SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 19304f4374c8SJens Wiklander 19314f4374c8SJens Wiklander if (!operation->key1) 19324f4374c8SJens Wiklander TEE_Panic(0); 19334f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 19344f4374c8SJens Wiklander TEE_Panic(0); 19354f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_ENCRYPT) 19364f4374c8SJens Wiklander TEE_Panic(0); 19374f4374c8SJens Wiklander 19384f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 19394f4374c8SJens Wiklander dl = *destLen; 19404f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 19414f4374c8SJens Wiklander srcLen, destData, &dl); 19424f4374c8SJens Wiklander *destLen = dl; 19434f4374c8SJens Wiklander 19444f4374c8SJens Wiklander if (res != TEE_SUCCESS && 19454f4374c8SJens Wiklander res != TEE_ERROR_SHORT_BUFFER && 19464f4374c8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS) 19474f4374c8SJens Wiklander TEE_Panic(res); 19484f4374c8SJens Wiklander 19494f4374c8SJens Wiklander return res; 19504f4374c8SJens Wiklander } 19514f4374c8SJens Wiklander 195212e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricDecrypt(TEE_OperationHandle operation, 19538f07fe6fSJerome Forissier const TEE_Attribute *params, 19548f07fe6fSJerome Forissier uint32_t paramCount, const void *srcData, 1955999b69d0SJens Wiklander size_t srcLen, void *destData, 1956999b69d0SJens Wiklander size_t *destLen) 1957b0104773SPascal Brand { 19586915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 1959e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 19606915bbbbSJens Wiklander uint64_t dl = 0; 1961b0104773SPascal Brand 19626915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 1963b0104773SPascal Brand TEE_Panic(0); 19646915bbbbSJens Wiklander 19656915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 19666915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 19676915bbbbSJens Wiklander 196812e66b6fSCedric Chaumont if (!operation->key1) 1969b0104773SPascal Brand TEE_Panic(0); 197012e66b6fSCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 197112e66b6fSCedric Chaumont TEE_Panic(0); 197212e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_DECRYPT) 1973b0104773SPascal Brand TEE_Panic(0); 1974b0104773SPascal Brand 1975e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 1976e86f1266SJens Wiklander dl = *destLen; 19772c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 1978e86f1266SJens Wiklander srcLen, destData, &dl); 1979e86f1266SJens Wiklander *destLen = dl; 198012e66b6fSCedric Chaumont 19818844ebfcSPascal Brand if (res != TEE_SUCCESS && 19828844ebfcSPascal Brand res != TEE_ERROR_SHORT_BUFFER && 19838844ebfcSPascal Brand res != TEE_ERROR_BAD_PARAMETERS) 1984b0104773SPascal Brand TEE_Panic(res); 198512e66b6fSCedric Chaumont 1986b0104773SPascal Brand return res; 1987b0104773SPascal Brand } 1988b0104773SPascal Brand 19894f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricDecrypt(TEE_OperationHandle operation, 19904f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 19914f4374c8SJens Wiklander uint32_t paramCount, 19924f4374c8SJens Wiklander const void *srcData, uint32_t srcLen, 19934f4374c8SJens Wiklander void *destData, uint32_t *destLen) 19944f4374c8SJens Wiklander { 19954f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 19964f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 19974f4374c8SJens Wiklander uint64_t dl = 0; 19984f4374c8SJens Wiklander 19994f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 20004f4374c8SJens Wiklander TEE_Panic(0); 20014f4374c8SJens Wiklander 20024f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 20034f4374c8SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 20044f4374c8SJens Wiklander 20054f4374c8SJens Wiklander if (!operation->key1) 20064f4374c8SJens Wiklander TEE_Panic(0); 20074f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 20084f4374c8SJens Wiklander TEE_Panic(0); 20094f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_DECRYPT) 20104f4374c8SJens Wiklander TEE_Panic(0); 20114f4374c8SJens Wiklander 20124f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 20134f4374c8SJens Wiklander dl = *destLen; 20144f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 20154f4374c8SJens Wiklander srcLen, destData, &dl); 20164f4374c8SJens Wiklander *destLen = dl; 20174f4374c8SJens Wiklander 20184f4374c8SJens Wiklander if (res != TEE_SUCCESS && 20194f4374c8SJens Wiklander res != TEE_ERROR_SHORT_BUFFER && 20204f4374c8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS) 20214f4374c8SJens Wiklander TEE_Panic(res); 20224f4374c8SJens Wiklander 20234f4374c8SJens Wiklander return res; 20244f4374c8SJens Wiklander } 20254f4374c8SJens Wiklander 202612e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricSignDigest(TEE_OperationHandle operation, 20278f07fe6fSJerome Forissier const TEE_Attribute *params, 20288f07fe6fSJerome Forissier uint32_t paramCount, const void *digest, 20290b354ec8SJens Wiklander size_t digestLen, void *signature, 20300b354ec8SJens Wiklander size_t *signatureLen) 2031b0104773SPascal Brand { 20326915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 2033e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 20346915bbbbSJens Wiklander uint64_t sl = 0; 2035b0104773SPascal Brand 20366915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen)) 2037b0104773SPascal Brand TEE_Panic(0); 20386915bbbbSJens Wiklander 20396915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 20406915bbbbSJens Wiklander __utee_check_inout_annotation(signatureLen, sizeof(*signatureLen)); 20416915bbbbSJens Wiklander 204212e66b6fSCedric Chaumont if (!operation->key1) 2043b0104773SPascal Brand TEE_Panic(0); 204412e66b6fSCedric Chaumont if (operation->info.operationClass != 204512e66b6fSCedric Chaumont TEE_OPERATION_ASYMMETRIC_SIGNATURE) 204612e66b6fSCedric Chaumont TEE_Panic(0); 204712e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_SIGN) 2048b0104773SPascal Brand TEE_Panic(0); 2049b0104773SPascal Brand 2050e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 2051e86f1266SJens Wiklander sl = *signatureLen; 20522c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, digest, 2053e86f1266SJens Wiklander digestLen, signature, &sl); 2054e86f1266SJens Wiklander *signatureLen = sl; 205512e66b6fSCedric Chaumont 2056b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER) 2057b0104773SPascal Brand TEE_Panic(res); 205812e66b6fSCedric Chaumont 2059b0104773SPascal Brand return res; 2060b0104773SPascal Brand } 2061b0104773SPascal Brand 20624f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricSignDigest(TEE_OperationHandle operation, 20634f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 20644f4374c8SJens Wiklander uint32_t paramCount, 20654f4374c8SJens Wiklander const void *digest, 20664f4374c8SJens Wiklander uint32_t digestLen, void *signature, 20674f4374c8SJens Wiklander uint32_t *signatureLen) 20684f4374c8SJens Wiklander { 20694f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 20704f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 20714f4374c8SJens Wiklander uint64_t sl = 0; 20724f4374c8SJens Wiklander 20734f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen)) 20744f4374c8SJens Wiklander TEE_Panic(0); 20754f4374c8SJens Wiklander 20764f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 20774f4374c8SJens Wiklander __utee_check_inout_annotation(signatureLen, sizeof(*signatureLen)); 20784f4374c8SJens Wiklander 20794f4374c8SJens Wiklander if (!operation->key1) 20804f4374c8SJens Wiklander TEE_Panic(0); 20814f4374c8SJens Wiklander if (operation->info.operationClass != 20824f4374c8SJens Wiklander TEE_OPERATION_ASYMMETRIC_SIGNATURE) 20834f4374c8SJens Wiklander TEE_Panic(0); 20844f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_SIGN) 20854f4374c8SJens Wiklander TEE_Panic(0); 20864f4374c8SJens Wiklander 20874f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 20884f4374c8SJens Wiklander sl = *signatureLen; 20894f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, digest, 20904f4374c8SJens Wiklander digestLen, signature, &sl); 20914f4374c8SJens Wiklander *signatureLen = sl; 20924f4374c8SJens Wiklander 20934f4374c8SJens Wiklander if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER) 20944f4374c8SJens Wiklander TEE_Panic(res); 20954f4374c8SJens Wiklander 20964f4374c8SJens Wiklander return res; 20974f4374c8SJens Wiklander } 20984f4374c8SJens Wiklander 209912e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation, 21008f07fe6fSJerome Forissier const TEE_Attribute *params, 21018f07fe6fSJerome Forissier uint32_t paramCount, const void *digest, 21020b354ec8SJens Wiklander size_t digestLen, 21038f07fe6fSJerome Forissier const void *signature, 21040b354ec8SJens Wiklander size_t signatureLen) 2105b0104773SPascal Brand { 2106b0104773SPascal Brand TEE_Result res; 2107e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 2108b0104773SPascal Brand 210912e66b6fSCedric Chaumont if (operation == TEE_HANDLE_NULL || 211012e66b6fSCedric Chaumont (digest == NULL && digestLen != 0) || 2111b0104773SPascal Brand (signature == NULL && signatureLen != 0)) 2112b0104773SPascal Brand TEE_Panic(0); 21136915bbbbSJens Wiklander 21146915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 21156915bbbbSJens Wiklander 211612e66b6fSCedric Chaumont if (!operation->key1) 2117b0104773SPascal Brand TEE_Panic(0); 211812e66b6fSCedric Chaumont if (operation->info.operationClass != 211912e66b6fSCedric Chaumont TEE_OPERATION_ASYMMETRIC_SIGNATURE) 212012e66b6fSCedric Chaumont TEE_Panic(0); 212112e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_VERIFY) 2122b0104773SPascal Brand TEE_Panic(0); 2123b0104773SPascal Brand 2124e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 21252c028fdeSJerome Forissier res = _utee_asymm_verify(operation->state, ua, paramCount, digest, 212612e66b6fSCedric Chaumont digestLen, signature, signatureLen); 212712e66b6fSCedric Chaumont 2128b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID) 2129b0104773SPascal Brand TEE_Panic(res); 213012e66b6fSCedric Chaumont 2131b0104773SPascal Brand return res; 2132b0104773SPascal Brand } 2133b0104773SPascal Brand 21344f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation, 21354f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 21364f4374c8SJens Wiklander uint32_t paramCount, 21374f4374c8SJens Wiklander const void *digest, 21384f4374c8SJens Wiklander uint32_t digestLen, 21394f4374c8SJens Wiklander const void *signature, 21404f4374c8SJens Wiklander uint32_t signatureLen) 21414f4374c8SJens Wiklander { 21424f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 21434f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 21444f4374c8SJens Wiklander 21454f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen) || 21464f4374c8SJens Wiklander (!signature && signatureLen)) 21474f4374c8SJens Wiklander TEE_Panic(0); 21484f4374c8SJens Wiklander 21494f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 21504f4374c8SJens Wiklander 21514f4374c8SJens Wiklander if (!operation->key1) 21524f4374c8SJens Wiklander TEE_Panic(0); 21534f4374c8SJens Wiklander if (operation->info.operationClass != 21544f4374c8SJens Wiklander TEE_OPERATION_ASYMMETRIC_SIGNATURE) 21554f4374c8SJens Wiklander TEE_Panic(0); 21564f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_VERIFY) 21574f4374c8SJens Wiklander TEE_Panic(0); 21584f4374c8SJens Wiklander 21594f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 21604f4374c8SJens Wiklander res = _utee_asymm_verify(operation->state, ua, paramCount, digest, 21614f4374c8SJens Wiklander digestLen, signature, signatureLen); 21624f4374c8SJens Wiklander 21634f4374c8SJens Wiklander if (res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID) 21644f4374c8SJens Wiklander TEE_Panic(res); 21654f4374c8SJens Wiklander 21664f4374c8SJens Wiklander return res; 21674f4374c8SJens Wiklander } 21684f4374c8SJens Wiklander 2169b0104773SPascal Brand /* Cryptographic Operations API - Key Derivation Functions */ 2170b0104773SPascal Brand 2171b0104773SPascal Brand void TEE_DeriveKey(TEE_OperationHandle operation, 2172b0104773SPascal Brand const TEE_Attribute *params, uint32_t paramCount, 2173b0104773SPascal Brand TEE_ObjectHandle derivedKey) 2174b0104773SPascal Brand { 2175e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 217675d6a373SJens Wiklander struct utee_object_info key_info = { }; 217775d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 2178b0104773SPascal Brand 2179b0104773SPascal Brand if (operation == TEE_HANDLE_NULL || derivedKey == 0) 2180b0104773SPascal Brand TEE_Panic(0); 21816915bbbbSJens Wiklander 21826915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 21836915bbbbSJens Wiklander 21848854d3c6SJerome Forissier if (TEE_ALG_GET_CLASS(operation->info.algorithm) != 21858854d3c6SJerome Forissier TEE_OPERATION_KEY_DERIVATION) 2186b0104773SPascal Brand TEE_Panic(0); 2187b0104773SPascal Brand 2188b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_KEY_DERIVATION) 2189b0104773SPascal Brand TEE_Panic(0); 219084fa9467SCedric Chaumont if (!operation->key1) 219184fa9467SCedric Chaumont TEE_Panic(0); 2192b0104773SPascal Brand if (operation->info.mode != TEE_MODE_DERIVE) 2193b0104773SPascal Brand TEE_Panic(0); 2194b0104773SPascal Brand if ((operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0) 2195b0104773SPascal Brand TEE_Panic(0); 2196b0104773SPascal Brand 21972c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)derivedKey, &key_info); 2198b0104773SPascal Brand if (res != TEE_SUCCESS) 2199b36311adSJerome Forissier TEE_Panic(res); 2200b0104773SPascal Brand 220175d6a373SJens Wiklander if (key_info.obj_type != TEE_TYPE_GENERIC_SECRET) 2202b0104773SPascal Brand TEE_Panic(0); 220375d6a373SJens Wiklander if ((key_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 2204b0104773SPascal Brand TEE_Panic(0); 2205b0104773SPascal Brand 2206e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 22072c028fdeSJerome Forissier res = _utee_cryp_derive_key(operation->state, ua, paramCount, 2208e86f1266SJens Wiklander (unsigned long)derivedKey); 2209b0104773SPascal Brand if (res != TEE_SUCCESS) 2210b0104773SPascal Brand TEE_Panic(res); 2211b0104773SPascal Brand } 2212b0104773SPascal Brand 22134f4374c8SJens Wiklander void __GP11_TEE_DeriveKey(TEE_OperationHandle operation, 22144f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 22154f4374c8SJens Wiklander uint32_t paramCount, TEE_ObjectHandle derivedKey) 22164f4374c8SJens Wiklander { 22174f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 22184f4374c8SJens Wiklander struct utee_object_info key_info = { }; 22194f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 22204f4374c8SJens Wiklander 22214f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || derivedKey == 0) 22224f4374c8SJens Wiklander TEE_Panic(0); 22234f4374c8SJens Wiklander 22244f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 22254f4374c8SJens Wiklander 22264f4374c8SJens Wiklander if (TEE_ALG_GET_CLASS(operation->info.algorithm) != 22274f4374c8SJens Wiklander TEE_OPERATION_KEY_DERIVATION) 22284f4374c8SJens Wiklander TEE_Panic(0); 22294f4374c8SJens Wiklander 22304f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_KEY_DERIVATION) 22314f4374c8SJens Wiklander TEE_Panic(0); 22324f4374c8SJens Wiklander if (!operation->key1) 22334f4374c8SJens Wiklander TEE_Panic(0); 22344f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_DERIVE) 22354f4374c8SJens Wiklander TEE_Panic(0); 22364f4374c8SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0) 22374f4374c8SJens Wiklander TEE_Panic(0); 22384f4374c8SJens Wiklander 22394f4374c8SJens Wiklander res = _utee_cryp_obj_get_info((unsigned long)derivedKey, &key_info); 22404f4374c8SJens Wiklander if (res != TEE_SUCCESS) 22414f4374c8SJens Wiklander TEE_Panic(res); 22424f4374c8SJens Wiklander 22434f4374c8SJens Wiklander if (key_info.obj_type != TEE_TYPE_GENERIC_SECRET) 22444f4374c8SJens Wiklander TEE_Panic(0); 22454f4374c8SJens Wiklander if ((key_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 22464f4374c8SJens Wiklander TEE_Panic(0); 22474f4374c8SJens Wiklander 22484f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 22494f4374c8SJens Wiklander res = _utee_cryp_derive_key(operation->state, ua, paramCount, 22504f4374c8SJens Wiklander (unsigned long)derivedKey); 22514f4374c8SJens Wiklander if (res != TEE_SUCCESS) 22524f4374c8SJens Wiklander TEE_Panic(res); 22534f4374c8SJens Wiklander } 22544f4374c8SJens Wiklander 2255b0104773SPascal Brand /* Cryptographic Operations API - Random Number Generation Functions */ 2256b0104773SPascal Brand 2257411a488aSJens Wiklander void TEE_GenerateRandom(void *randomBuffer, size_t randomBufferLen) 2258b0104773SPascal Brand { 2259b0104773SPascal Brand TEE_Result res; 2260b0104773SPascal Brand 22612c028fdeSJerome Forissier res = _utee_cryp_random_number_generate(randomBuffer, randomBufferLen); 2262b0104773SPascal Brand if (res != TEE_SUCCESS) 2263b0104773SPascal Brand TEE_Panic(res); 2264b0104773SPascal Brand } 2265433c4257SJens Wiklander 2266411a488aSJens Wiklander void __GP11_TEE_GenerateRandom(void *randomBuffer, uint32_t randomBufferLen) 2267411a488aSJens Wiklander { 2268411a488aSJens Wiklander TEE_GenerateRandom(randomBuffer, randomBufferLen); 2269411a488aSJens Wiklander } 2270411a488aSJens Wiklander 2271433c4257SJens Wiklander int rand(void) 2272433c4257SJens Wiklander { 2273433c4257SJens Wiklander int rc; 2274433c4257SJens Wiklander 2275433c4257SJens Wiklander TEE_GenerateRandom(&rc, sizeof(rc)); 2276433c4257SJens Wiklander 2277433c4257SJens Wiklander /* 2278433c4257SJens Wiklander * RAND_MAX is the larges int, INT_MAX which is all bits but the 2279433c4257SJens Wiklander * highest bit set. 2280433c4257SJens Wiklander */ 2281433c4257SJens Wiklander return rc & RAND_MAX; 2282433c4257SJens Wiklander } 228379170ce0SJerome Forissier 228479170ce0SJerome Forissier TEE_Result TEE_IsAlgorithmSupported(uint32_t alg, uint32_t element) 228579170ce0SJerome Forissier { 228679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_AES)) { 228779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) { 228879170ce0SJerome Forissier if (alg == TEE_ALG_AES_ECB_NOPAD) 228979170ce0SJerome Forissier goto check_element_none; 229079170ce0SJerome Forissier } 229179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) { 229279170ce0SJerome Forissier if (alg == TEE_ALG_AES_CBC_NOPAD) 229379170ce0SJerome Forissier goto check_element_none; 229479170ce0SJerome Forissier } 229579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTR)) { 229679170ce0SJerome Forissier if (alg == TEE_ALG_AES_CTR) 229779170ce0SJerome Forissier goto check_element_none; 229879170ce0SJerome Forissier } 229979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTS)) { 230079170ce0SJerome Forissier if (alg == TEE_ALG_AES_CTS) 230179170ce0SJerome Forissier goto check_element_none; 230279170ce0SJerome Forissier } 230379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_XTS)) { 230479170ce0SJerome Forissier if (alg == TEE_ALG_AES_XTS) 230579170ce0SJerome Forissier goto check_element_none; 230679170ce0SJerome Forissier } 230779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC_MAC)) { 230879170ce0SJerome Forissier if (alg == TEE_ALG_AES_CBC_MAC_NOPAD || 230979170ce0SJerome Forissier alg == TEE_ALG_AES_CBC_MAC_PKCS5) 231079170ce0SJerome Forissier goto check_element_none; 231179170ce0SJerome Forissier } 231279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CMAC)) { 231379170ce0SJerome Forissier if (alg == TEE_ALG_AES_CMAC) 231479170ce0SJerome Forissier goto check_element_none; 231579170ce0SJerome Forissier } 231679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CCM)) { 231779170ce0SJerome Forissier if (alg == TEE_ALG_AES_CCM) 231879170ce0SJerome Forissier goto check_element_none; 231979170ce0SJerome Forissier } 232079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_GCM)) { 232179170ce0SJerome Forissier if (alg == TEE_ALG_AES_GCM) 232279170ce0SJerome Forissier goto check_element_none; 232379170ce0SJerome Forissier } 232479170ce0SJerome Forissier } 232579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DES)) { 232679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) { 232779170ce0SJerome Forissier if (alg == TEE_ALG_DES_ECB_NOPAD || 232879170ce0SJerome Forissier alg == TEE_ALG_DES3_ECB_NOPAD) 232979170ce0SJerome Forissier goto check_element_none; 233079170ce0SJerome Forissier } 233179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) { 233279170ce0SJerome Forissier if (alg == TEE_ALG_DES_CBC_NOPAD || 233379170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_NOPAD) 233479170ce0SJerome Forissier goto check_element_none; 233579170ce0SJerome Forissier } 233679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC_MAC)) { 233779170ce0SJerome Forissier if (alg == TEE_ALG_DES_CBC_MAC_NOPAD || 233879170ce0SJerome Forissier alg == TEE_ALG_DES_CBC_MAC_PKCS5 || 233979170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_MAC_NOPAD || 234079170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_MAC_PKCS5) 234179170ce0SJerome Forissier goto check_element_none; 234279170ce0SJerome Forissier } 234379170ce0SJerome Forissier } 234479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) { 234579170ce0SJerome Forissier if (alg == TEE_ALG_MD5) 234679170ce0SJerome Forissier goto check_element_none; 234779170ce0SJerome Forissier } 234879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 234979170ce0SJerome Forissier if (alg == TEE_ALG_SHA1) 235079170ce0SJerome Forissier goto check_element_none; 235179170ce0SJerome Forissier } 235279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 235379170ce0SJerome Forissier if (alg == TEE_ALG_SHA224) 235479170ce0SJerome Forissier goto check_element_none; 235579170ce0SJerome Forissier } 235679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 235779170ce0SJerome Forissier if (alg == TEE_ALG_SHA256) 235879170ce0SJerome Forissier goto check_element_none; 235979170ce0SJerome Forissier } 236079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) { 236179170ce0SJerome Forissier if (alg == TEE_ALG_SHA384) 236279170ce0SJerome Forissier goto check_element_none; 236379170ce0SJerome Forissier } 236479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) { 236579170ce0SJerome Forissier if (alg == TEE_ALG_SHA512) 236679170ce0SJerome Forissier goto check_element_none; 236779170ce0SJerome Forissier } 236879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5) && IS_ENABLED(CFG_CRYPTO_SHA1)) { 236979170ce0SJerome Forissier if (alg == TEE_ALG_MD5SHA1) 237079170ce0SJerome Forissier goto check_element_none; 237179170ce0SJerome Forissier } 237279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_HMAC)) { 237379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) { 237479170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_MD5) 237579170ce0SJerome Forissier goto check_element_none; 237679170ce0SJerome Forissier } 237779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 237879170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA1) 237979170ce0SJerome Forissier goto check_element_none; 238079170ce0SJerome Forissier } 238179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 238279170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA224) 238379170ce0SJerome Forissier goto check_element_none; 238479170ce0SJerome Forissier } 238579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 238679170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA256) 238779170ce0SJerome Forissier goto check_element_none; 238879170ce0SJerome Forissier } 238979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) { 239079170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA384) 239179170ce0SJerome Forissier goto check_element_none; 239279170ce0SJerome Forissier } 239379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) { 239479170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA512) 239579170ce0SJerome Forissier goto check_element_none; 239679170ce0SJerome Forissier } 239779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM3)) { 239879170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SM3) 239979170ce0SJerome Forissier goto check_element_none; 240079170ce0SJerome Forissier } 240179170ce0SJerome Forissier } 240279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM3)) { 240379170ce0SJerome Forissier if (alg == TEE_ALG_SM3) 240479170ce0SJerome Forissier goto check_element_none; 240579170ce0SJerome Forissier } 240679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM4)) { 240779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) { 240879170ce0SJerome Forissier if (alg == TEE_ALG_SM4_ECB_NOPAD) 240979170ce0SJerome Forissier goto check_element_none; 241079170ce0SJerome Forissier } 241179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) { 241279170ce0SJerome Forissier if (alg == TEE_ALG_SM4_CBC_NOPAD) 241379170ce0SJerome Forissier goto check_element_none; 241479170ce0SJerome Forissier } 241579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTR)) { 241679170ce0SJerome Forissier if (alg == TEE_ALG_SM4_CTR) 241779170ce0SJerome Forissier goto check_element_none; 241879170ce0SJerome Forissier } 2419696f56acSPingan Xie if (IS_ENABLED(CFG_CRYPTO_XTS)) { 2420696f56acSPingan Xie if (alg == TEE_ALG_SM4_XTS) 2421696f56acSPingan Xie goto check_element_none; 2422696f56acSPingan Xie } 242379170ce0SJerome Forissier } 242479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_RSA)) { 242579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) { 242679170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5) 242779170ce0SJerome Forissier goto check_element_none; 242879170ce0SJerome Forissier } 242979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 243079170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA1 || 243179170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1 || 243279170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1) 243379170ce0SJerome Forissier goto check_element_none; 243479170ce0SJerome Forissier } 243579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5) && IS_ENABLED(CFG_CRYPTO_SHA1)) { 243679170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5SHA1) 243779170ce0SJerome Forissier goto check_element_none; 243879170ce0SJerome Forissier } 243979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 244079170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA224 || 244179170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224 || 244279170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224) 244379170ce0SJerome Forissier goto check_element_none; 244479170ce0SJerome Forissier } 244579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 244679170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA256 || 244779170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 || 244879170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256) 244979170ce0SJerome Forissier goto check_element_none; 245079170ce0SJerome Forissier } 245179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) { 245279170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA384 || 245379170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384 || 245479170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384) 245579170ce0SJerome Forissier goto check_element_none; 245679170ce0SJerome Forissier } 245779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) { 245879170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA512 || 245979170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512 || 246079170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512) 246179170ce0SJerome Forissier goto check_element_none; 246279170ce0SJerome Forissier } 246379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_RSASSA_NA1)) { 246479170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5) 246579170ce0SJerome Forissier goto check_element_none; 246679170ce0SJerome Forissier } 246779170ce0SJerome Forissier if (alg == TEE_ALG_RSA_NOPAD) 246879170ce0SJerome Forissier goto check_element_none; 246979170ce0SJerome Forissier } 247079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DSA)) { 247179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 247279170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA1) 247379170ce0SJerome Forissier goto check_element_none; 247479170ce0SJerome Forissier } 247579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 247679170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA224) 247779170ce0SJerome Forissier goto check_element_none; 247879170ce0SJerome Forissier } 247979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 248079170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA256) 248179170ce0SJerome Forissier goto check_element_none; 248279170ce0SJerome Forissier } 248379170ce0SJerome Forissier } 248479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DH)) { 248579170ce0SJerome Forissier if (alg == TEE_ALG_DH_DERIVE_SHARED_SECRET) 248679170ce0SJerome Forissier goto check_element_none; 248779170ce0SJerome Forissier } 248879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECC)) { 2489fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P192 || 2490fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P192 || 2491fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2492fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA1) && 249379170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P192) 249479170ce0SJerome Forissier return TEE_SUCCESS; 2495fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P224 || 2496fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P224 || 2497fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2498fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA224) && 249979170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P224) 250079170ce0SJerome Forissier return TEE_SUCCESS; 2501fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P256 || 2502fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P256 || 2503fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2504fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA256) && 250579170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P256) 250679170ce0SJerome Forissier return TEE_SUCCESS; 2507fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P384 || 2508fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P384 || 2509fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2510fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA384) && 251179170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P384) 251279170ce0SJerome Forissier return TEE_SUCCESS; 2513fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P521 || 2514fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P521 || 2515fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2516fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA512) && 251779170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P521) 251879170ce0SJerome Forissier return TEE_SUCCESS; 251979170ce0SJerome Forissier } 252079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_DSA)) { 252179170ce0SJerome Forissier if (alg == TEE_ALG_SM2_DSA_SM3 && element == TEE_ECC_CURVE_SM2) 252279170ce0SJerome Forissier return TEE_SUCCESS; 252379170ce0SJerome Forissier } 252479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_KEP)) { 252579170ce0SJerome Forissier if (alg == TEE_ALG_SM2_KEP && element == TEE_ECC_CURVE_SM2) 252679170ce0SJerome Forissier return TEE_SUCCESS; 252779170ce0SJerome Forissier } 252879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_PKE)) { 252979170ce0SJerome Forissier if (alg == TEE_ALG_SM2_PKE && element == TEE_ECC_CURVE_SM2) 253079170ce0SJerome Forissier return TEE_SUCCESS; 253179170ce0SJerome Forissier } 25323f61056dSSohaib ul Hassan if (IS_ENABLED(CFG_CRYPTO_X25519)) { 25333f61056dSSohaib ul Hassan if (alg == TEE_ALG_X25519 && element == TEE_ECC_CURVE_25519) 25343f61056dSSohaib ul Hassan return TEE_SUCCESS; 25353f61056dSSohaib ul Hassan } 2536e1f9cee7SSergiy Kibrik if (IS_ENABLED(CFG_CRYPTO_ED25519)) { 2537e1f9cee7SSergiy Kibrik if (alg == TEE_ALG_ED25519 && element == TEE_ECC_CURVE_25519) 2538e1f9cee7SSergiy Kibrik return TEE_SUCCESS; 2539e1f9cee7SSergiy Kibrik } 254079170ce0SJerome Forissier 254179170ce0SJerome Forissier return TEE_ERROR_NOT_SUPPORTED; 254279170ce0SJerome Forissier check_element_none: 254379170ce0SJerome Forissier if (element == TEE_CRYPTO_ELEMENT_NONE) 254479170ce0SJerome Forissier return TEE_SUCCESS; 254579170ce0SJerome Forissier return TEE_ERROR_NOT_SUPPORTED; 254679170ce0SJerome Forissier } 2547