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: 287*260b4028SJens Wiklander case TEE_ALG_HMAC_SHA3_224: 288*260b4028SJens Wiklander case TEE_ALG_HMAC_SHA3_256: 289*260b4028SJens Wiklander case TEE_ALG_HMAC_SHA3_384: 290*260b4028SJens Wiklander case TEE_ALG_HMAC_SHA3_512: 29147645577SJerome Forissier case TEE_ALG_HMAC_SM3: 292b0104773SPascal Brand if (mode != TEE_MODE_MAC) 293b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 294b0104773SPascal Brand req_key_usage = TEE_USAGE_MAC; 295b0104773SPascal Brand break; 296b0104773SPascal Brand 297b0104773SPascal Brand default: 298b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 299b0104773SPascal Brand } 300b0104773SPascal Brand 301b66f219bSJens Wiklander op = TEE_Malloc(sizeof(*op), TEE_MALLOC_FILL_ZERO); 3029b52c538SCedric Chaumont if (!op) 303b0104773SPascal Brand return TEE_ERROR_OUT_OF_MEMORY; 304b0104773SPascal Brand 305b0104773SPascal Brand op->info.algorithm = algorithm; 306b0104773SPascal Brand op->info.operationClass = TEE_ALG_GET_CLASS(algorithm); 3076a2e0a9fSGabor Szekely #ifdef CFG_CRYPTO_RSASSA_NA1 3086a2e0a9fSGabor Szekely if (algorithm == TEE_ALG_RSASSA_PKCS1_V1_5) 3096a2e0a9fSGabor Szekely op->info.operationClass = TEE_OPERATION_ASYMMETRIC_SIGNATURE; 3106a2e0a9fSGabor Szekely #endif 311b0104773SPascal Brand op->info.mode = mode; 3122e5e6460SAlbert Schwarzkopf op->info.digestLength = TEE_ALG_GET_DIGEST_SIZE(algorithm); 313b0104773SPascal Brand op->info.maxKeySize = maxKeySize; 314b0104773SPascal Brand op->info.requiredKeyUsage = req_key_usage; 315b0104773SPascal Brand op->info.handleState = handle_state; 316b0104773SPascal Brand 317b0104773SPascal Brand if (block_size > 1) { 318b0104773SPascal Brand size_t buffer_size = block_size; 319b0104773SPascal Brand 320b0104773SPascal Brand if (buffer_two_blocks) 321b0104773SPascal Brand buffer_size *= 2; 322b0104773SPascal Brand 3239b52c538SCedric Chaumont op->buffer = TEE_Malloc(buffer_size, 3249b52c538SCedric Chaumont TEE_USER_MEM_HINT_NO_FILL_ZERO); 325b0104773SPascal Brand if (op->buffer == NULL) { 326b0104773SPascal Brand res = TEE_ERROR_OUT_OF_MEMORY; 327b66f219bSJens Wiklander goto out; 328b0104773SPascal Brand } 329b0104773SPascal Brand } 330b0104773SPascal Brand op->block_size = block_size; 331b0104773SPascal Brand op->buffer_two_blocks = buffer_two_blocks; 332b0104773SPascal Brand 333b0104773SPascal Brand if (TEE_ALG_GET_CLASS(algorithm) != TEE_OPERATION_DIGEST) { 334b0104773SPascal Brand uint32_t mks = maxKeySize; 335b0104773SPascal Brand TEE_ObjectType key_type = TEE_ALG_GET_KEY_TYPE(algorithm, 336b0104773SPascal Brand with_private_key); 337b0104773SPascal Brand 338b0104773SPascal Brand /* 339b0104773SPascal Brand * If two keys are expected the max key size is the sum of 340b0104773SPascal Brand * the size of both keys. 341b0104773SPascal Brand */ 342b0104773SPascal Brand if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) 343b0104773SPascal Brand mks /= 2; 344b0104773SPascal Brand 345b0104773SPascal Brand res = TEE_AllocateTransientObject(key_type, mks, &op->key1); 346b0104773SPascal Brand if (res != TEE_SUCCESS) 347b66f219bSJens Wiklander goto out; 348b0104773SPascal Brand 34905304565SCedric Chaumont if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) { 3509b52c538SCedric Chaumont res = TEE_AllocateTransientObject(key_type, mks, 351b0104773SPascal Brand &op->key2); 352b0104773SPascal Brand if (res != TEE_SUCCESS) 353b66f219bSJens Wiklander goto out; 354b0104773SPascal Brand } 355b0104773SPascal Brand } 356b0104773SPascal Brand 3572c028fdeSJerome Forissier res = _utee_cryp_state_alloc(algorithm, mode, (unsigned long)op->key1, 358e86f1266SJens Wiklander (unsigned long)op->key2, &op->state); 359b66f219bSJens Wiklander if (res != TEE_SUCCESS) 360b66f219bSJens Wiklander goto out; 361b0104773SPascal Brand 36205304565SCedric Chaumont /* 36305304565SCedric Chaumont * Initialize digest operations 36405304565SCedric Chaumont * Other multi-stage operations initialized w/ TEE_xxxInit functions 36505304565SCedric Chaumont * Non-applicable on asymmetric operations 36605304565SCedric Chaumont */ 36705304565SCedric Chaumont if (TEE_ALG_GET_CLASS(algorithm) == TEE_OPERATION_DIGEST) { 3682c028fdeSJerome Forissier res = _utee_hash_init(op->state, NULL, 0); 36905304565SCedric Chaumont if (res != TEE_SUCCESS) 370b66f219bSJens Wiklander goto out; 37105304565SCedric Chaumont /* v1.1: flags always set for digest operations */ 37205304565SCedric Chaumont op->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 37305304565SCedric Chaumont } 37405304565SCedric Chaumont 375642a1607SCedric Chaumont op->operationState = TEE_OPERATION_STATE_INITIAL; 376642a1607SCedric Chaumont 377b0104773SPascal Brand *operation = op; 378b0104773SPascal Brand 379b66f219bSJens Wiklander out: 380b66f219bSJens Wiklander if (res != TEE_SUCCESS) { 381b66f219bSJens Wiklander if (res != TEE_ERROR_OUT_OF_MEMORY && 3829b52c538SCedric Chaumont res != TEE_ERROR_NOT_SUPPORTED) 383b36311adSJerome Forissier TEE_Panic(res); 384b66f219bSJens Wiklander if (op) { 385b66f219bSJens Wiklander if (op->state) { 386b66f219bSJens Wiklander TEE_FreeOperation(op); 387b66f219bSJens Wiklander } else { 388b66f219bSJens Wiklander TEE_Free(op->buffer); 389b66f219bSJens Wiklander TEE_FreeTransientObject(op->key1); 390b66f219bSJens Wiklander TEE_FreeTransientObject(op->key2); 391b66f219bSJens Wiklander TEE_Free(op); 392b66f219bSJens Wiklander } 393b66f219bSJens Wiklander } 394b66f219bSJens Wiklander } 395b66f219bSJens Wiklander 396b0104773SPascal Brand return res; 397b0104773SPascal Brand } 398b0104773SPascal Brand 399b0104773SPascal Brand void TEE_FreeOperation(TEE_OperationHandle operation) 400b0104773SPascal Brand { 401e889e80bSCedric Chaumont TEE_Result res; 402e889e80bSCedric Chaumont 403e889e80bSCedric Chaumont if (operation == TEE_HANDLE_NULL) 404c036e912SJens Wiklander return; 405e889e80bSCedric Chaumont 406b0104773SPascal Brand /* 407b0104773SPascal Brand * Note that keys should not be freed here, since they are 408b0104773SPascal Brand * claimed by the operation they will be freed by 409b0104773SPascal Brand * utee_cryp_state_free(). 410b0104773SPascal Brand */ 4112c028fdeSJerome Forissier res = _utee_cryp_state_free(operation->state); 412e889e80bSCedric Chaumont if (res != TEE_SUCCESS) 413b36311adSJerome Forissier TEE_Panic(res); 414e889e80bSCedric Chaumont 415b0104773SPascal Brand TEE_Free(operation->buffer); 416b0104773SPascal Brand TEE_Free(operation); 417b0104773SPascal Brand } 418b0104773SPascal Brand 419c036e912SJens Wiklander void __GP11_TEE_FreeOperation(TEE_OperationHandle operation) 420c036e912SJens Wiklander { 421c036e912SJens Wiklander if (operation == TEE_HANDLE_NULL) 422c036e912SJens Wiklander TEE_Panic(0); 423c036e912SJens Wiklander TEE_FreeOperation(operation); 424c036e912SJens Wiklander } 425c036e912SJens Wiklander 426b0104773SPascal Brand void TEE_GetOperationInfo(TEE_OperationHandle operation, 427b0104773SPascal Brand TEE_OperationInfo *operationInfo) 428b0104773SPascal Brand { 429b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 430b0104773SPascal Brand TEE_Panic(0); 431b0104773SPascal Brand 4326915bbbbSJens Wiklander __utee_check_out_annotation(operationInfo, sizeof(*operationInfo)); 433b0104773SPascal Brand 434b0104773SPascal Brand *operationInfo = operation->info; 435bac3a8a7SJens Wiklander if (operationInfo->handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) { 436bac3a8a7SJens Wiklander operationInfo->keySize = 0; 437bac3a8a7SJens Wiklander operationInfo->requiredKeyUsage = 0; 438bac3a8a7SJens Wiklander } 439b0104773SPascal Brand } 440b0104773SPascal Brand 441ee2f75afSJens Wiklander TEE_Result TEE_GetOperationInfoMultiple(TEE_OperationHandle op, 442ee2f75afSJens Wiklander TEE_OperationInfoMultiple *op_info, 443cb98b7b2SJens Wiklander size_t *size) 44405304565SCedric Chaumont { 44505304565SCedric Chaumont TEE_Result res = TEE_SUCCESS; 446ee2f75afSJens Wiklander TEE_ObjectInfo kinfo = { }; 447ee2f75afSJens Wiklander size_t max_key_count = 0; 448ee2f75afSJens Wiklander bool two_keys = false; 44905304565SCedric Chaumont 450ee2f75afSJens Wiklander if (op == TEE_HANDLE_NULL) { 45105304565SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 45205304565SCedric Chaumont goto out; 45305304565SCedric Chaumont } 45405304565SCedric Chaumont 455cb98b7b2SJens Wiklander __utee_check_outbuf_annotation(op_info, size); 45605304565SCedric Chaumont 457ee2f75afSJens Wiklander if (*size < sizeof(*op_info)) { 458ee2f75afSJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 459ee2f75afSJens Wiklander goto out; 460ee2f75afSJens Wiklander } 461ee2f75afSJens Wiklander max_key_count = (*size - sizeof(*op_info)) / 46205304565SCedric Chaumont sizeof(TEE_OperationInfoKey); 46305304565SCedric Chaumont 464ee2f75afSJens Wiklander TEE_MemFill(op_info, 0, *size); 46505304565SCedric Chaumont 46605304565SCedric Chaumont /* Two keys flag (TEE_ALG_AES_XTS only) */ 467ee2f75afSJens Wiklander two_keys = op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS; 468ee2f75afSJens Wiklander 469ee2f75afSJens Wiklander if (op->info.mode == TEE_MODE_DIGEST) { 470ee2f75afSJens Wiklander op_info->numberOfKeys = 0; 471ee2f75afSJens Wiklander } else if (!two_keys) { 472ee2f75afSJens Wiklander if (max_key_count < 1) { 47305304565SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 47405304565SCedric Chaumont goto out; 47505304565SCedric Chaumont } 47605304565SCedric Chaumont 477ee2f75afSJens Wiklander res = TEE_GetObjectInfo1(op->key1, &kinfo); 478ee2f75afSJens Wiklander /* Key1 is not a valid handle, "can't happen". */ 479ee2f75afSJens Wiklander if (res) 48005304565SCedric Chaumont goto out; 48105304565SCedric Chaumont 482d372a47cSJens Wiklander op_info->keyInformation[0].keySize = kinfo.objectSize; 483ee2f75afSJens Wiklander op_info->keyInformation[0].requiredKeyUsage = 484ee2f75afSJens Wiklander op->info.requiredKeyUsage; 485ee2f75afSJens Wiklander op_info->numberOfKeys = 1; 486ee2f75afSJens Wiklander } else { 487ee2f75afSJens Wiklander if (max_key_count < 2) { 488ee2f75afSJens Wiklander res = TEE_ERROR_SHORT_BUFFER; 48905304565SCedric Chaumont goto out; 49005304565SCedric Chaumont } 49105304565SCedric Chaumont 492ee2f75afSJens Wiklander res = TEE_GetObjectInfo1(op->key1, &kinfo); 493ee2f75afSJens Wiklander /* Key1 is not a valid handle, "can't happen". */ 494ee2f75afSJens Wiklander if (res) 495ee2f75afSJens Wiklander goto out; 496ee2f75afSJens Wiklander 497d372a47cSJens Wiklander op_info->keyInformation[0].keySize = kinfo.objectSize; 498ee2f75afSJens Wiklander op_info->keyInformation[0].requiredKeyUsage = 499ee2f75afSJens Wiklander op->info.requiredKeyUsage; 500ee2f75afSJens Wiklander 501ee2f75afSJens Wiklander res = TEE_GetObjectInfo1(op->key2, &kinfo); 502ee2f75afSJens Wiklander /* Key2 is not a valid handle, "can't happen". */ 503ee2f75afSJens Wiklander if (res) 504ee2f75afSJens Wiklander goto out; 505ee2f75afSJens Wiklander 506d372a47cSJens Wiklander op_info->keyInformation[1].keySize = kinfo.objectSize; 507ee2f75afSJens Wiklander op_info->keyInformation[1].requiredKeyUsage = 508ee2f75afSJens Wiklander op->info.requiredKeyUsage; 509ee2f75afSJens Wiklander 510ee2f75afSJens Wiklander op_info->numberOfKeys = 2; 51105304565SCedric Chaumont } 51205304565SCedric Chaumont 513ee2f75afSJens Wiklander op_info->algorithm = op->info.algorithm; 514ee2f75afSJens Wiklander op_info->operationClass = op->info.operationClass; 515ee2f75afSJens Wiklander op_info->mode = op->info.mode; 516ee2f75afSJens Wiklander op_info->digestLength = op->info.digestLength; 517ee2f75afSJens Wiklander op_info->maxKeySize = op->info.maxKeySize; 518ee2f75afSJens Wiklander op_info->handleState = op->info.handleState; 519ee2f75afSJens Wiklander op_info->operationState = op->operationState; 52005304565SCedric Chaumont 52105304565SCedric Chaumont out: 52205304565SCedric Chaumont if (res != TEE_SUCCESS && 52305304565SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 524b36311adSJerome Forissier TEE_Panic(res); 52505304565SCedric Chaumont 52605304565SCedric Chaumont return res; 52705304565SCedric Chaumont } 52805304565SCedric Chaumont 529cb98b7b2SJens Wiklander TEE_Result 530cb98b7b2SJens Wiklander __GP11_TEE_GetOperationInfoMultiple(TEE_OperationHandle operation, 531cb98b7b2SJens Wiklander TEE_OperationInfoMultiple *info, 532cb98b7b2SJens Wiklander uint32_t *operationSize) 533cb98b7b2SJens Wiklander { 534cb98b7b2SJens Wiklander TEE_Result res = TEE_SUCCESS; 535cb98b7b2SJens Wiklander size_t s = 0; 536cb98b7b2SJens Wiklander 537cb98b7b2SJens Wiklander __utee_check_gp11_outbuf_annotation(info, operationSize); 538cb98b7b2SJens Wiklander s = *operationSize; 539cb98b7b2SJens Wiklander res = TEE_GetOperationInfoMultiple(operation, info, &s); 540cb98b7b2SJens Wiklander *operationSize = s; 541cb98b7b2SJens Wiklander return res; 542cb98b7b2SJens Wiklander } 543cb98b7b2SJens Wiklander 544b0104773SPascal Brand void TEE_ResetOperation(TEE_OperationHandle operation) 545b0104773SPascal Brand { 546b0104773SPascal Brand TEE_Result res; 547b0104773SPascal Brand 548b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 549b0104773SPascal Brand TEE_Panic(0); 550bf80076aSCedric Chaumont 551642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET)) 552bf80076aSCedric Chaumont TEE_Panic(0); 553bf80076aSCedric Chaumont 554642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 555642a1607SCedric Chaumont 556b0104773SPascal Brand if (operation->info.operationClass == TEE_OPERATION_DIGEST) { 5572c028fdeSJerome Forissier res = _utee_hash_init(operation->state, NULL, 0); 558b0104773SPascal Brand if (res != TEE_SUCCESS) 559b0104773SPascal Brand TEE_Panic(res); 56005304565SCedric Chaumont operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 56105304565SCedric Chaumont } else { 562b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 563b0104773SPascal Brand } 56405304565SCedric Chaumont } 565b0104773SPascal Brand 566b0104773SPascal Brand TEE_Result TEE_SetOperationKey(TEE_OperationHandle operation, 567b0104773SPascal Brand TEE_ObjectHandle key) 568b0104773SPascal Brand { 5697583c59eSCedric Chaumont TEE_Result res; 570b0104773SPascal Brand uint32_t key_size = 0; 571b0104773SPascal Brand TEE_ObjectInfo key_info; 572b0104773SPascal Brand 573a57c1e2eSCedric Chaumont if (operation == TEE_HANDLE_NULL) { 574a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 575a57c1e2eSCedric Chaumont goto out; 576a57c1e2eSCedric Chaumont } 577a57c1e2eSCedric Chaumont 578642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) { 579642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 580642a1607SCedric Chaumont goto out; 581642a1607SCedric Chaumont } 582642a1607SCedric Chaumont 583a57c1e2eSCedric Chaumont if (key == TEE_HANDLE_NULL) { 584a57c1e2eSCedric Chaumont /* Operation key cleared */ 585a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key1); 5866c4ea258SJens Wiklander operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 5876c4ea258SJens Wiklander return TEE_SUCCESS; 588a57c1e2eSCedric Chaumont } 589a57c1e2eSCedric Chaumont 590a57c1e2eSCedric Chaumont /* No key for digest operation */ 591a57c1e2eSCedric Chaumont if (operation->info.operationClass == TEE_OPERATION_DIGEST) { 592a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 593a57c1e2eSCedric Chaumont goto out; 594a57c1e2eSCedric Chaumont } 595a57c1e2eSCedric Chaumont 596a57c1e2eSCedric Chaumont /* Two keys flag not expected (TEE_ALG_AES_XTS excluded) */ 597a57c1e2eSCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) != 598a57c1e2eSCedric Chaumont 0) { 599a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 600a57c1e2eSCedric Chaumont goto out; 601a57c1e2eSCedric Chaumont } 602a57c1e2eSCedric Chaumont 6037583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key, &key_info); 604a57c1e2eSCedric Chaumont /* Key is not a valid handle */ 6057583c59eSCedric Chaumont if (res != TEE_SUCCESS) 606a57c1e2eSCedric Chaumont goto out; 6077583c59eSCedric Chaumont 608b0104773SPascal Brand /* Supplied key has to meet required usage */ 609b0104773SPascal Brand if ((key_info.objectUsage & operation->info.requiredKeyUsage) != 610b0104773SPascal Brand operation->info.requiredKeyUsage) { 611a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 612a57c1e2eSCedric Chaumont goto out; 613b0104773SPascal Brand } 614b0104773SPascal Brand 615d372a47cSJens Wiklander if (operation->info.maxKeySize < key_info.objectSize) { 616a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 617a57c1e2eSCedric Chaumont goto out; 618a57c1e2eSCedric Chaumont } 619b0104773SPascal Brand 620d372a47cSJens Wiklander key_size = key_info.objectSize; 621b0104773SPascal Brand 622b0104773SPascal Brand TEE_ResetTransientObject(operation->key1); 623b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 624b0104773SPascal Brand 6257583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key1, key); 6267583c59eSCedric Chaumont if (res != TEE_SUCCESS) 627a57c1e2eSCedric Chaumont goto out; 6287583c59eSCedric Chaumont 629b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET; 630b0104773SPascal Brand 631b0104773SPascal Brand operation->info.keySize = key_size; 632b0104773SPascal Brand 6337583c59eSCedric Chaumont out: 634a57c1e2eSCedric Chaumont if (res != TEE_SUCCESS && 635a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 636a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 637b36311adSJerome Forissier TEE_Panic(res); 638a57c1e2eSCedric Chaumont 639a57c1e2eSCedric Chaumont return res; 640b0104773SPascal Brand } 641b0104773SPascal Brand 642b0104773SPascal Brand TEE_Result TEE_SetOperationKey2(TEE_OperationHandle operation, 643b0104773SPascal Brand TEE_ObjectHandle key1, TEE_ObjectHandle key2) 644b0104773SPascal Brand { 6457583c59eSCedric Chaumont TEE_Result res; 646b0104773SPascal Brand uint32_t key_size = 0; 647b0104773SPascal Brand TEE_ObjectInfo key_info1; 648b0104773SPascal Brand TEE_ObjectInfo key_info2; 649b0104773SPascal Brand 650a57c1e2eSCedric Chaumont if (operation == TEE_HANDLE_NULL) { 651a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 652a57c1e2eSCedric Chaumont goto out; 653a57c1e2eSCedric Chaumont } 654a57c1e2eSCedric Chaumont 655642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) { 656642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 657642a1607SCedric Chaumont goto out; 658642a1607SCedric Chaumont } 659642a1607SCedric Chaumont 660a57c1e2eSCedric Chaumont /* 661a57c1e2eSCedric Chaumont * Key1/Key2 and/or are not initialized and 662a57c1e2eSCedric Chaumont * Either both keys are NULL or both are not NULL 663a57c1e2eSCedric Chaumont */ 6646c4ea258SJens Wiklander if (!key1 && !key2) { 6656c4ea258SJens Wiklander /* Clear the keys */ 666a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key1); 667a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key2); 6686c4ea258SJens Wiklander operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 6696c4ea258SJens Wiklander return TEE_SUCCESS; 6706c4ea258SJens Wiklander } else if (!key1 || !key2) { 6716c4ea258SJens Wiklander /* Both keys are obviously not valid. */ 672a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 673a57c1e2eSCedric Chaumont goto out; 674a57c1e2eSCedric Chaumont } 675a57c1e2eSCedric Chaumont 676a57c1e2eSCedric Chaumont /* No key for digest operation */ 677a57c1e2eSCedric Chaumont if (operation->info.operationClass == TEE_OPERATION_DIGEST) { 678a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 679a57c1e2eSCedric Chaumont goto out; 680a57c1e2eSCedric Chaumont } 681a57c1e2eSCedric Chaumont 6825b385b3fSJerome Forissier /* Two keys flag expected (TEE_ALG_AES_XTS and TEE_ALG_SM2_KEP only) */ 683a57c1e2eSCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 684a57c1e2eSCedric Chaumont 0) { 685a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 686a57c1e2eSCedric Chaumont goto out; 687a57c1e2eSCedric Chaumont } 688a57c1e2eSCedric Chaumont 6897583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key1, &key_info1); 690a57c1e2eSCedric Chaumont /* Key1 is not a valid handle */ 6917583c59eSCedric Chaumont if (res != TEE_SUCCESS) 692a57c1e2eSCedric Chaumont goto out; 6937583c59eSCedric Chaumont 694b0104773SPascal Brand /* Supplied key has to meet required usage */ 695b0104773SPascal Brand if ((key_info1.objectUsage & operation->info. 696b0104773SPascal Brand requiredKeyUsage) != operation->info.requiredKeyUsage) { 697a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 698a57c1e2eSCedric Chaumont goto out; 699b0104773SPascal Brand } 700b0104773SPascal Brand 7017583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key2, &key_info2); 702a57c1e2eSCedric Chaumont /* Key2 is not a valid handle */ 7037583c59eSCedric Chaumont if (res != TEE_SUCCESS) { 7047583c59eSCedric Chaumont if (res == TEE_ERROR_CORRUPT_OBJECT) 7057583c59eSCedric Chaumont res = TEE_ERROR_CORRUPT_OBJECT_2; 706a57c1e2eSCedric Chaumont goto out; 7077583c59eSCedric Chaumont } 7087583c59eSCedric Chaumont 709b0104773SPascal Brand /* Supplied key has to meet required usage */ 710b0104773SPascal Brand if ((key_info2.objectUsage & operation->info. 711b0104773SPascal Brand requiredKeyUsage) != operation->info.requiredKeyUsage) { 712a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 713a57c1e2eSCedric Chaumont goto out; 714b0104773SPascal Brand } 715b0104773SPascal Brand 716b0104773SPascal Brand /* 7175b385b3fSJerome Forissier * All the multi key algorithm currently supported requires the keys to 7185b385b3fSJerome Forissier * be of equal size. 719b0104773SPascal Brand */ 720d372a47cSJens Wiklander if (key_info1.objectSize != key_info2.objectSize) { 721a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 722a57c1e2eSCedric Chaumont goto out; 723b0104773SPascal Brand 724a57c1e2eSCedric Chaumont } 725a57c1e2eSCedric Chaumont 726d372a47cSJens Wiklander if (operation->info.maxKeySize < key_info1.objectSize) { 727a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 728a57c1e2eSCedric Chaumont goto out; 729a57c1e2eSCedric Chaumont } 730b0104773SPascal Brand 731b0104773SPascal Brand /* 732b0104773SPascal Brand * Odd that only the size of one key should be reported while 733b0104773SPascal Brand * size of two key are used when allocating the operation. 734b0104773SPascal Brand */ 735d372a47cSJens Wiklander key_size = key_info1.objectSize; 736b0104773SPascal Brand 737b0104773SPascal Brand TEE_ResetTransientObject(operation->key1); 738b0104773SPascal Brand TEE_ResetTransientObject(operation->key2); 739b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 740b0104773SPascal Brand 7417583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key1, key1); 7427583c59eSCedric Chaumont if (res != TEE_SUCCESS) 743a57c1e2eSCedric Chaumont goto out; 7447583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key2, key2); 7457583c59eSCedric Chaumont if (res != TEE_SUCCESS) { 7467583c59eSCedric Chaumont if (res == TEE_ERROR_CORRUPT_OBJECT) 7477583c59eSCedric Chaumont res = TEE_ERROR_CORRUPT_OBJECT_2; 748a57c1e2eSCedric Chaumont goto out; 7497583c59eSCedric Chaumont } 7507583c59eSCedric Chaumont 751b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET; 752b0104773SPascal Brand 753b0104773SPascal Brand operation->info.keySize = key_size; 754b0104773SPascal Brand 7557583c59eSCedric Chaumont out: 756a57c1e2eSCedric Chaumont if (res != TEE_SUCCESS && 757a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 758a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT_2 && 759a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE && 760a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE_2) 761b36311adSJerome Forissier TEE_Panic(res); 762a57c1e2eSCedric Chaumont 763a57c1e2eSCedric Chaumont return res; 764b0104773SPascal Brand } 765b0104773SPascal Brand 766b0104773SPascal Brand void TEE_CopyOperation(TEE_OperationHandle dst_op, TEE_OperationHandle src_op) 767b0104773SPascal Brand { 768b0104773SPascal Brand TEE_Result res; 769b0104773SPascal Brand 770b0104773SPascal Brand if (dst_op == TEE_HANDLE_NULL || src_op == TEE_HANDLE_NULL) 771b0104773SPascal Brand TEE_Panic(0); 772b0104773SPascal Brand if (dst_op->info.algorithm != src_op->info.algorithm) 773b0104773SPascal Brand TEE_Panic(0); 7748734de30SJens Wiklander if (dst_op->info.mode != src_op->info.mode) 7758734de30SJens Wiklander TEE_Panic(0); 776b0104773SPascal Brand if (src_op->info.operationClass != TEE_OPERATION_DIGEST) { 777b0104773SPascal Brand TEE_ObjectHandle key1 = TEE_HANDLE_NULL; 778b0104773SPascal Brand TEE_ObjectHandle key2 = TEE_HANDLE_NULL; 779b0104773SPascal Brand 780b0104773SPascal Brand if (src_op->info.handleState & TEE_HANDLE_FLAG_KEY_SET) { 781b0104773SPascal Brand key1 = src_op->key1; 782b0104773SPascal Brand key2 = src_op->key2; 783b0104773SPascal Brand } 784b0104773SPascal Brand 785b0104773SPascal Brand if ((src_op->info.handleState & 786b0104773SPascal Brand TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 0) { 787b0104773SPascal Brand TEE_SetOperationKey(dst_op, key1); 788b0104773SPascal Brand } else { 789b0104773SPascal Brand TEE_SetOperationKey2(dst_op, key1, key2); 790b0104773SPascal Brand } 791b0104773SPascal Brand } 792b0104773SPascal Brand dst_op->info.handleState = src_op->info.handleState; 793b0104773SPascal Brand dst_op->info.keySize = src_op->info.keySize; 7948e07702eSJens Wiklander dst_op->info.digestLength = src_op->info.digestLength; 795642a1607SCedric Chaumont dst_op->operationState = src_op->operationState; 796b0104773SPascal Brand 797b0104773SPascal Brand if (dst_op->buffer_two_blocks != src_op->buffer_two_blocks || 798b0104773SPascal Brand dst_op->block_size != src_op->block_size) 799b0104773SPascal Brand TEE_Panic(0); 800b0104773SPascal Brand 801b0104773SPascal Brand if (dst_op->buffer != NULL) { 802b0104773SPascal Brand if (src_op->buffer == NULL) 803b0104773SPascal Brand TEE_Panic(0); 804b0104773SPascal Brand 805b0104773SPascal Brand memcpy(dst_op->buffer, src_op->buffer, src_op->buffer_offs); 806b0104773SPascal Brand dst_op->buffer_offs = src_op->buffer_offs; 807b0104773SPascal Brand } else if (src_op->buffer != NULL) { 808b0104773SPascal Brand TEE_Panic(0); 809b0104773SPascal Brand } 810b0104773SPascal Brand 8112c028fdeSJerome Forissier res = _utee_cryp_state_copy(dst_op->state, src_op->state); 812b0104773SPascal Brand if (res != TEE_SUCCESS) 813b0104773SPascal Brand TEE_Panic(res); 814b0104773SPascal Brand } 815b0104773SPascal Brand 816b0104773SPascal Brand /* Cryptographic Operations API - Message Digest Functions */ 817b0104773SPascal Brand 8188f07fe6fSJerome Forissier static void init_hash_operation(TEE_OperationHandle operation, const void *IV, 8196d15db08SJerome Forissier uint32_t IVLen) 8206d15db08SJerome Forissier { 8216d15db08SJerome Forissier TEE_Result res; 8226d15db08SJerome Forissier 8236d15db08SJerome Forissier /* 8246d15db08SJerome Forissier * Note : IV and IVLen are never used in current implementation 8256d15db08SJerome Forissier * This is why coherent values of IV and IVLen are not checked 8266d15db08SJerome Forissier */ 8272c028fdeSJerome Forissier res = _utee_hash_init(operation->state, IV, IVLen); 8286d15db08SJerome Forissier if (res != TEE_SUCCESS) 8296d15db08SJerome Forissier TEE_Panic(res); 8306d15db08SJerome Forissier operation->buffer_offs = 0; 8316d15db08SJerome Forissier operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 8326d15db08SJerome Forissier } 8336d15db08SJerome Forissier 834b0104773SPascal Brand void TEE_DigestUpdate(TEE_OperationHandle operation, 835185bf58cSJens Wiklander const void *chunk, size_t chunkSize) 836b0104773SPascal Brand { 83773d6c3baSJoakim Bech TEE_Result res = TEE_ERROR_GENERIC; 838b0104773SPascal Brand 83973d6c3baSJoakim Bech if (operation == TEE_HANDLE_NULL || 84073d6c3baSJoakim Bech operation->info.operationClass != TEE_OPERATION_DIGEST) 841b0104773SPascal Brand TEE_Panic(0); 84273d6c3baSJoakim Bech 843642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 844642a1607SCedric Chaumont 8452c028fdeSJerome Forissier res = _utee_hash_update(operation->state, chunk, chunkSize); 846b0104773SPascal Brand if (res != TEE_SUCCESS) 847b0104773SPascal Brand TEE_Panic(res); 848b0104773SPascal Brand } 849b0104773SPascal Brand 850185bf58cSJens Wiklander void __GP11_TEE_DigestUpdate(TEE_OperationHandle operation, 851185bf58cSJens Wiklander const void *chunk, uint32_t chunkSize) 852185bf58cSJens Wiklander { 853185bf58cSJens Wiklander return TEE_DigestUpdate(operation, chunk, chunkSize); 854185bf58cSJens Wiklander } 855185bf58cSJens Wiklander 8568f07fe6fSJerome Forissier TEE_Result TEE_DigestDoFinal(TEE_OperationHandle operation, const void *chunk, 857185bf58cSJens Wiklander size_t chunkLen, void *hash, size_t *hashLen) 858b0104773SPascal Brand { 85987c2f6b6SCedric Chaumont TEE_Result res; 860e86f1266SJens Wiklander uint64_t hl; 86187c2f6b6SCedric Chaumont 86287c2f6b6SCedric Chaumont if ((operation == TEE_HANDLE_NULL) || 86387c2f6b6SCedric Chaumont (!chunk && chunkLen) || 86487c2f6b6SCedric Chaumont (operation->info.operationClass != TEE_OPERATION_DIGEST)) { 86587c2f6b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 86687c2f6b6SCedric Chaumont goto out; 86787c2f6b6SCedric Chaumont } 8686915bbbbSJens Wiklander __utee_check_inout_annotation(hashLen, sizeof(*hashLen)); 86987c2f6b6SCedric Chaumont 870e86f1266SJens Wiklander hl = *hashLen; 8712c028fdeSJerome Forissier res = _utee_hash_final(operation->state, chunk, chunkLen, hash, &hl); 872e86f1266SJens Wiklander *hashLen = hl; 8736d15db08SJerome Forissier if (res != TEE_SUCCESS) 8746d15db08SJerome Forissier goto out; 8756d15db08SJerome Forissier 8766d15db08SJerome Forissier /* Reset operation state */ 8776d15db08SJerome Forissier init_hash_operation(operation, NULL, 0); 87887c2f6b6SCedric Chaumont 879642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 880642a1607SCedric Chaumont 88187c2f6b6SCedric Chaumont out: 88287c2f6b6SCedric Chaumont if (res != TEE_SUCCESS && 88387c2f6b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 884b36311adSJerome Forissier TEE_Panic(res); 88573d6c3baSJoakim Bech 88687c2f6b6SCedric Chaumont return res; 887b0104773SPascal Brand } 888b0104773SPascal Brand 889185bf58cSJens Wiklander TEE_Result __GP11_TEE_DigestDoFinal(TEE_OperationHandle operation, 890185bf58cSJens Wiklander const void *chunk, uint32_t chunkLen, 891185bf58cSJens Wiklander void *hash, uint32_t *hashLen) 892185bf58cSJens Wiklander { 893185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 894185bf58cSJens Wiklander size_t l = 0; 895185bf58cSJens Wiklander 896185bf58cSJens Wiklander __utee_check_inout_annotation(hashLen, sizeof(*hashLen)); 897185bf58cSJens Wiklander l = *hashLen; 898185bf58cSJens Wiklander res = TEE_DigestDoFinal(operation, chunk, chunkLen, hash, &l); 899185bf58cSJens Wiklander *hashLen = l; 900185bf58cSJens Wiklander return res; 901185bf58cSJens Wiklander } 902185bf58cSJens Wiklander 903b0104773SPascal Brand /* Cryptographic Operations API - Symmetric Cipher Functions */ 904b0104773SPascal Brand 9058f07fe6fSJerome Forissier void TEE_CipherInit(TEE_OperationHandle operation, const void *IV, 906185bf58cSJens Wiklander size_t IVLen) 907b0104773SPascal Brand { 908b0104773SPascal Brand TEE_Result res; 909b0104773SPascal Brand 910b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 911b0104773SPascal Brand TEE_Panic(0); 912642a1607SCedric Chaumont 913b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_CIPHER) 914b0104773SPascal Brand TEE_Panic(0); 915642a1607SCedric Chaumont 916642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) || 917642a1607SCedric Chaumont !(operation->key1)) 918642a1607SCedric Chaumont TEE_Panic(0); 919642a1607SCedric Chaumont 920642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 921642a1607SCedric Chaumont TEE_ResetOperation(operation); 922642a1607SCedric Chaumont 923ad7aa2a5SSadiq Hussain if (IV && IVLen) { 924ad7aa2a5SSadiq Hussain if (operation->info.algorithm == TEE_ALG_AES_ECB_NOPAD || 925ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_DES_ECB_NOPAD || 926ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_DES3_ECB_NOPAD || 927ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_SM4_ECB_NOPAD) 928ad7aa2a5SSadiq Hussain TEE_Panic(0); 929ad7aa2a5SSadiq Hussain } 930ad7aa2a5SSadiq Hussain 931642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 932642a1607SCedric Chaumont 9332c028fdeSJerome Forissier res = _utee_cipher_init(operation->state, IV, IVLen); 934b0104773SPascal Brand if (res != TEE_SUCCESS) 935b0104773SPascal Brand TEE_Panic(res); 936642a1607SCedric Chaumont 937b0104773SPascal Brand operation->buffer_offs = 0; 938b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 939b0104773SPascal Brand } 940b0104773SPascal Brand 941185bf58cSJens Wiklander void __GP11_TEE_CipherInit(TEE_OperationHandle operation, const void *IV, 942185bf58cSJens Wiklander uint32_t IVLen) 943185bf58cSJens Wiklander { 944185bf58cSJens Wiklander return TEE_CipherInit(operation, IV, IVLen); 945185bf58cSJens Wiklander } 946185bf58cSJens Wiklander 947b0104773SPascal Brand static TEE_Result tee_buffer_update( 948b0104773SPascal Brand TEE_OperationHandle op, 949e86f1266SJens Wiklander TEE_Result(*update_func)(unsigned long state, const void *src, 950e86f1266SJens Wiklander size_t slen, void *dst, uint64_t *dlen), 951b0104773SPascal Brand const void *src_data, size_t src_len, 952e86f1266SJens Wiklander void *dest_data, uint64_t *dest_len) 953b0104773SPascal Brand { 954b0104773SPascal Brand TEE_Result res; 955b0104773SPascal Brand const uint8_t *src = src_data; 956b0104773SPascal Brand size_t slen = src_len; 957b0104773SPascal Brand uint8_t *dst = dest_data; 958b0104773SPascal Brand size_t dlen = *dest_len; 959b0104773SPascal Brand size_t acc_dlen = 0; 960e86f1266SJens Wiklander uint64_t tmp_dlen; 961b0104773SPascal Brand size_t l; 962b0104773SPascal Brand size_t buffer_size; 963d3588802SPascal Brand size_t buffer_left; 964b0104773SPascal Brand 965090268f5SJens Wiklander if (!src) { 966090268f5SJens Wiklander if (slen) 967090268f5SJens Wiklander TEE_Panic(0); 968090268f5SJens Wiklander goto out; 969090268f5SJens Wiklander } 970090268f5SJens Wiklander 971d3588802SPascal Brand if (op->buffer_two_blocks) { 972b0104773SPascal Brand buffer_size = op->block_size * 2; 973d3588802SPascal Brand buffer_left = 1; 974d3588802SPascal Brand } else { 975b0104773SPascal Brand buffer_size = op->block_size; 976d3588802SPascal Brand buffer_left = 0; 977d3588802SPascal Brand } 978b0104773SPascal Brand 979b0104773SPascal Brand if (op->buffer_offs > 0) { 980b0104773SPascal Brand /* Fill up complete block */ 981b0104773SPascal Brand if (op->buffer_offs < op->block_size) 982b0104773SPascal Brand l = MIN(slen, op->block_size - op->buffer_offs); 983b0104773SPascal Brand else 984b0104773SPascal Brand l = MIN(slen, buffer_size - op->buffer_offs); 985b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, l); 986b0104773SPascal Brand op->buffer_offs += l; 987b0104773SPascal Brand src += l; 988b0104773SPascal Brand slen -= l; 989b0104773SPascal Brand if ((op->buffer_offs % op->block_size) != 0) 990b0104773SPascal Brand goto out; /* Nothing left to do */ 991b0104773SPascal Brand } 992b0104773SPascal Brand 993b0104773SPascal Brand /* If we can feed from buffer */ 994d3588802SPascal Brand if ((op->buffer_offs > 0) && 995d3588802SPascal Brand ((op->buffer_offs + slen) >= (buffer_size + buffer_left))) { 9962ff3fdbbSPascal Brand l = ROUNDUP(op->buffer_offs + slen - buffer_size, 997b0104773SPascal Brand op->block_size); 998b0104773SPascal Brand l = MIN(op->buffer_offs, l); 999b0104773SPascal Brand tmp_dlen = dlen; 1000b0104773SPascal Brand res = update_func(op->state, op->buffer, l, dst, &tmp_dlen); 1001b0104773SPascal Brand if (res != TEE_SUCCESS) 1002b0104773SPascal Brand TEE_Panic(res); 1003b0104773SPascal Brand dst += tmp_dlen; 1004b0104773SPascal Brand dlen -= tmp_dlen; 1005b0104773SPascal Brand acc_dlen += tmp_dlen; 1006b0104773SPascal Brand op->buffer_offs -= l; 1007b0104773SPascal Brand if (op->buffer_offs > 0) { 1008b0104773SPascal Brand /* 1009b0104773SPascal Brand * Slen is small enough to be contained in rest buffer. 1010b0104773SPascal Brand */ 1011b0104773SPascal Brand memcpy(op->buffer, op->buffer + l, buffer_size - l); 1012b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, slen); 1013b0104773SPascal Brand op->buffer_offs += slen; 1014b0104773SPascal Brand goto out; /* Nothing left to do */ 1015b0104773SPascal Brand } 1016b0104773SPascal Brand } 1017b0104773SPascal Brand 1018d3588802SPascal Brand if (slen >= (buffer_size + buffer_left)) { 1019b0104773SPascal Brand /* Buffer is empty, feed as much as possible from src */ 1020bf7a587fSJerome Forissier if (op->info.algorithm == TEE_ALG_AES_CTS) 1021b1ecda78SJerome Forissier l = ROUNDUP(slen - buffer_size, op->block_size); 1022bf7a587fSJerome Forissier else 1023bf7a587fSJerome Forissier l = ROUNDUP(slen - buffer_size + 1, op->block_size); 1024b0104773SPascal Brand 1025b0104773SPascal Brand tmp_dlen = dlen; 1026b0104773SPascal Brand res = update_func(op->state, src, l, dst, &tmp_dlen); 1027b0104773SPascal Brand if (res != TEE_SUCCESS) 1028b0104773SPascal Brand TEE_Panic(res); 1029b0104773SPascal Brand src += l; 1030b0104773SPascal Brand slen -= l; 1031b0104773SPascal Brand dst += tmp_dlen; 1032b0104773SPascal Brand dlen -= tmp_dlen; 1033b0104773SPascal Brand acc_dlen += tmp_dlen; 1034b0104773SPascal Brand } 1035b0104773SPascal Brand 1036b0104773SPascal Brand /* Slen is small enough to be contained in buffer. */ 1037b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, slen); 1038b0104773SPascal Brand op->buffer_offs += slen; 1039b0104773SPascal Brand 1040b0104773SPascal Brand out: 1041b0104773SPascal Brand *dest_len = acc_dlen; 1042b0104773SPascal Brand return TEE_SUCCESS; 1043b0104773SPascal Brand } 1044b0104773SPascal Brand 10458f07fe6fSJerome Forissier TEE_Result TEE_CipherUpdate(TEE_OperationHandle operation, const void *srcData, 1046185bf58cSJens Wiklander size_t srcLen, void *destData, size_t *destLen) 1047b0104773SPascal Brand { 1048dea1f2b6SCedric Chaumont TEE_Result res; 1049b0104773SPascal Brand size_t req_dlen; 1050e86f1266SJens Wiklander uint64_t dl; 1051b0104773SPascal Brand 10526915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1053dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1054dea1f2b6SCedric Chaumont goto out; 1055dea1f2b6SCedric Chaumont } 10566915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1057dea1f2b6SCedric Chaumont 1058642a1607SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_CIPHER) { 1059dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1060dea1f2b6SCedric Chaumont goto out; 1061dea1f2b6SCedric Chaumont } 1062dea1f2b6SCedric Chaumont 1063642a1607SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1064642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1065642a1607SCedric Chaumont goto out; 1066642a1607SCedric Chaumont } 1067642a1607SCedric Chaumont 1068642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1069dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1070dea1f2b6SCedric Chaumont goto out; 1071dea1f2b6SCedric Chaumont } 1072b0104773SPascal Brand 1073e32c5ddfSJerome Forissier if (!srcData && !srcLen) { 1074090268f5SJens Wiklander *destLen = 0; 1075e32c5ddfSJerome Forissier res = TEE_SUCCESS; 1076e32c5ddfSJerome Forissier goto out; 1077e32c5ddfSJerome Forissier } 1078e32c5ddfSJerome Forissier 1079b0104773SPascal Brand /* Calculate required dlen */ 108057aabac5SBogdan Liulko if (operation->block_size > 1) { 108157aabac5SBogdan Liulko req_dlen = ((operation->buffer_offs + srcLen) / 108257aabac5SBogdan Liulko operation->block_size) * operation->block_size; 108357aabac5SBogdan Liulko } else { 108457aabac5SBogdan Liulko req_dlen = srcLen; 108557aabac5SBogdan Liulko } 1086642a1607SCedric Chaumont if (operation->buffer_two_blocks) { 1087642a1607SCedric Chaumont if (req_dlen > operation->block_size * 2) 1088642a1607SCedric Chaumont req_dlen -= operation->block_size * 2; 1089b0104773SPascal Brand else 1090b0104773SPascal Brand req_dlen = 0; 1091b0104773SPascal Brand } 1092b0104773SPascal Brand /* 1093b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1094b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1095b0104773SPascal Brand * can't restore sync with this API. 1096b0104773SPascal Brand */ 1097b0104773SPascal Brand if (*destLen < req_dlen) { 1098b0104773SPascal Brand *destLen = req_dlen; 1099dea1f2b6SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1100dea1f2b6SCedric Chaumont goto out; 1101b0104773SPascal Brand } 1102b0104773SPascal Brand 1103e86f1266SJens Wiklander dl = *destLen; 110457aabac5SBogdan Liulko if (operation->block_size > 1) { 11052c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_cipher_update, srcData, 110657aabac5SBogdan Liulko srcLen, destData, &dl); 110757aabac5SBogdan Liulko } else { 110857aabac5SBogdan Liulko if (srcLen > 0) { 11092c028fdeSJerome Forissier res = _utee_cipher_update(operation->state, srcData, 111057aabac5SBogdan Liulko srcLen, destData, &dl); 111157aabac5SBogdan Liulko } else { 111257aabac5SBogdan Liulko res = TEE_SUCCESS; 111357aabac5SBogdan Liulko dl = 0; 111457aabac5SBogdan Liulko } 111557aabac5SBogdan Liulko } 1116e86f1266SJens Wiklander *destLen = dl; 1117b0104773SPascal Brand 1118dea1f2b6SCedric Chaumont out: 1119dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS && 1120dea1f2b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1121b36311adSJerome Forissier TEE_Panic(res); 1122dea1f2b6SCedric Chaumont 1123dea1f2b6SCedric Chaumont return res; 1124b0104773SPascal Brand } 1125b0104773SPascal Brand 1126185bf58cSJens Wiklander TEE_Result __GP11_TEE_CipherUpdate(TEE_OperationHandle operation, 11278f07fe6fSJerome Forissier const void *srcData, uint32_t srcLen, 11288f07fe6fSJerome Forissier void *destData, uint32_t *destLen) 1129b0104773SPascal Brand { 11306915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 1131185bf58cSJens Wiklander size_t dl = 0; 1132185bf58cSJens Wiklander 1133185bf58cSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1134185bf58cSJens Wiklander dl = *destLen; 1135185bf58cSJens Wiklander res = TEE_CipherUpdate(operation, srcData, srcLen, destData, &dl); 1136185bf58cSJens Wiklander *destLen = dl; 1137185bf58cSJens Wiklander return res; 1138185bf58cSJens Wiklander } 1139185bf58cSJens Wiklander 1140185bf58cSJens Wiklander TEE_Result TEE_CipherDoFinal(TEE_OperationHandle operation, 1141185bf58cSJens Wiklander const void *srcData, size_t srcLen, 1142185bf58cSJens Wiklander void *destData, size_t *destLen) 1143185bf58cSJens Wiklander { 1144185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 1145b0104773SPascal Brand uint8_t *dst = destData; 1146b0104773SPascal Brand size_t acc_dlen = 0; 11476915bbbbSJens Wiklander uint64_t tmp_dlen = 0; 11486915bbbbSJens Wiklander size_t req_dlen = 0; 1149b0104773SPascal Brand 11506915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1151dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1152dea1f2b6SCedric Chaumont goto out; 1153dea1f2b6SCedric Chaumont } 11546915bbbbSJens Wiklander if (destLen) 11556915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1156dea1f2b6SCedric Chaumont 1157642a1607SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_CIPHER) { 1158dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1159dea1f2b6SCedric Chaumont goto out; 1160dea1f2b6SCedric Chaumont } 1161dea1f2b6SCedric Chaumont 1162642a1607SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1163642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1164642a1607SCedric Chaumont goto out; 1165642a1607SCedric Chaumont } 1166642a1607SCedric Chaumont 1167642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1168dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1169dea1f2b6SCedric Chaumont goto out; 1170dea1f2b6SCedric Chaumont } 1171b0104773SPascal Brand 1172b0104773SPascal Brand /* 1173b0104773SPascal Brand * Check that the final block doesn't require padding for those 1174b0104773SPascal Brand * algorithms that requires client to supply padding. 1175b0104773SPascal Brand */ 1176642a1607SCedric Chaumont if (operation->info.algorithm == TEE_ALG_AES_ECB_NOPAD || 1177642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_AES_CBC_NOPAD || 1178642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES_ECB_NOPAD || 1179642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES_CBC_NOPAD || 1180642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES3_ECB_NOPAD || 1181ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_DES3_CBC_NOPAD || 1182ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_SM4_ECB_NOPAD || 1183ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_SM4_CBC_NOPAD) { 1184642a1607SCedric Chaumont if (((operation->buffer_offs + srcLen) % operation->block_size) 1185642a1607SCedric Chaumont != 0) { 1186dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1187dea1f2b6SCedric Chaumont goto out; 1188dea1f2b6SCedric Chaumont } 1189b0104773SPascal Brand } 1190b0104773SPascal Brand 1191b0104773SPascal Brand /* 1192b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1193b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1194b0104773SPascal Brand * can't restore sync with this API. 1195b0104773SPascal Brand */ 119657aabac5SBogdan Liulko if (operation->block_size > 1) { 1197642a1607SCedric Chaumont req_dlen = operation->buffer_offs + srcLen; 119857aabac5SBogdan Liulko } else { 119957aabac5SBogdan Liulko req_dlen = srcLen; 120057aabac5SBogdan Liulko } 12016915bbbbSJens Wiklander if (destLen) 12026915bbbbSJens Wiklander tmp_dlen = *destLen; 12036915bbbbSJens Wiklander if (tmp_dlen < req_dlen) { 12046915bbbbSJens Wiklander if (destLen) 1205b0104773SPascal Brand *destLen = req_dlen; 1206dea1f2b6SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1207dea1f2b6SCedric Chaumont goto out; 1208b0104773SPascal Brand } 1209b0104773SPascal Brand 121057aabac5SBogdan Liulko if (operation->block_size > 1) { 1211dea9063eSJens Wiklander if (srcLen) { 12122c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_cipher_update, 1213dea9063eSJens Wiklander srcData, srcLen, dst, 1214dea9063eSJens Wiklander &tmp_dlen); 1215dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS) 1216dea1f2b6SCedric Chaumont goto out; 1217dea1f2b6SCedric Chaumont 1218b0104773SPascal Brand dst += tmp_dlen; 1219b0104773SPascal Brand acc_dlen += tmp_dlen; 1220b0104773SPascal Brand 1221b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 1222dea9063eSJens Wiklander } 12232c028fdeSJerome Forissier res = _utee_cipher_final(operation->state, operation->buffer, 12242c028fdeSJerome Forissier operation->buffer_offs, dst, 12252c028fdeSJerome Forissier &tmp_dlen); 122657aabac5SBogdan Liulko } else { 12272c028fdeSJerome Forissier res = _utee_cipher_final(operation->state, srcData, srcLen, dst, 12282c028fdeSJerome Forissier &tmp_dlen); 122957aabac5SBogdan Liulko } 1230b0104773SPascal Brand if (res != TEE_SUCCESS) 1231dea1f2b6SCedric Chaumont goto out; 1232dea1f2b6SCedric Chaumont 1233b0104773SPascal Brand acc_dlen += tmp_dlen; 12346915bbbbSJens Wiklander if (destLen) 1235b0104773SPascal Brand *destLen = acc_dlen; 1236dea1f2b6SCedric Chaumont 1237642a1607SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 1238642a1607SCedric Chaumont 1239642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1240642a1607SCedric Chaumont 1241dea1f2b6SCedric Chaumont out: 1242dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS && 1243dea1f2b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1244b36311adSJerome Forissier TEE_Panic(res); 1245dea1f2b6SCedric Chaumont 1246dea1f2b6SCedric Chaumont return res; 1247b0104773SPascal Brand } 1248b0104773SPascal Brand 1249185bf58cSJens Wiklander TEE_Result __GP11_TEE_CipherDoFinal(TEE_OperationHandle operation, 1250185bf58cSJens Wiklander const void *srcData, uint32_t srcLen, 1251185bf58cSJens Wiklander void *destData, uint32_t *destLen) 1252185bf58cSJens Wiklander { 1253185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 1254185bf58cSJens Wiklander size_t dl = 0; 1255185bf58cSJens Wiklander 1256185bf58cSJens Wiklander if (destLen) { 1257185bf58cSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1258185bf58cSJens Wiklander dl = *destLen; 1259185bf58cSJens Wiklander } 1260185bf58cSJens Wiklander res = TEE_CipherDoFinal(operation, srcData, srcLen, destData, &dl); 1261185bf58cSJens Wiklander if (destLen) 1262185bf58cSJens Wiklander *destLen = dl; 1263185bf58cSJens Wiklander return res; 1264185bf58cSJens Wiklander } 1265185bf58cSJens Wiklander 1266b0104773SPascal Brand /* Cryptographic Operations API - MAC Functions */ 1267b0104773SPascal Brand 1268185bf58cSJens Wiklander void TEE_MACInit(TEE_OperationHandle operation, const void *IV, size_t IVLen) 1269b0104773SPascal Brand { 1270b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 1271b0104773SPascal Brand TEE_Panic(0); 1272642a1607SCedric Chaumont 1273b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_MAC) 1274b0104773SPascal Brand TEE_Panic(0); 1275642a1607SCedric Chaumont 1276642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) || 1277642a1607SCedric Chaumont !(operation->key1)) 1278642a1607SCedric Chaumont TEE_Panic(0); 1279642a1607SCedric Chaumont 1280642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 1281642a1607SCedric Chaumont TEE_ResetOperation(operation); 1282642a1607SCedric Chaumont 1283642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1284642a1607SCedric Chaumont 12856d15db08SJerome Forissier init_hash_operation(operation, IV, IVLen); 1286b0104773SPascal Brand } 1287b0104773SPascal Brand 1288185bf58cSJens Wiklander void __GP11_TEE_MACInit(TEE_OperationHandle operation, const void *IV, 1289185bf58cSJens Wiklander uint32_t IVLen) 1290185bf58cSJens Wiklander { 1291185bf58cSJens Wiklander return TEE_MACInit(operation, IV, IVLen); 1292185bf58cSJens Wiklander } 1293185bf58cSJens Wiklander 12948f07fe6fSJerome Forissier void TEE_MACUpdate(TEE_OperationHandle operation, const void *chunk, 1295185bf58cSJens Wiklander size_t chunkSize) 1296b0104773SPascal Brand { 1297b0104773SPascal Brand TEE_Result res; 1298b0104773SPascal Brand 129928e0efc6SCedric Chaumont if (operation == TEE_HANDLE_NULL || (chunk == NULL && chunkSize != 0)) 1300b0104773SPascal Brand TEE_Panic(0); 1301642a1607SCedric Chaumont 130228e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) 1303b0104773SPascal Brand TEE_Panic(0); 1304642a1607SCedric Chaumont 130528e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 1306b0104773SPascal Brand TEE_Panic(0); 1307b0104773SPascal Brand 1308642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) 1309642a1607SCedric Chaumont TEE_Panic(0); 1310642a1607SCedric Chaumont 13112c028fdeSJerome Forissier res = _utee_hash_update(operation->state, chunk, chunkSize); 1312b0104773SPascal Brand if (res != TEE_SUCCESS) 1313b0104773SPascal Brand TEE_Panic(res); 1314b0104773SPascal Brand } 1315b0104773SPascal Brand 1316185bf58cSJens Wiklander void __GP11_TEE_MACUpdate(TEE_OperationHandle operation, const void *chunk, 1317185bf58cSJens Wiklander uint32_t chunkSize) 1318185bf58cSJens Wiklander { 1319185bf58cSJens Wiklander return TEE_MACUpdate(operation, chunk, chunkSize); 1320185bf58cSJens Wiklander } 1321185bf58cSJens Wiklander 132228e0efc6SCedric Chaumont TEE_Result TEE_MACComputeFinal(TEE_OperationHandle operation, 1323185bf58cSJens Wiklander const void *message, size_t messageLen, 1324185bf58cSJens Wiklander void *mac, size_t *macLen) 1325b0104773SPascal Brand { 1326b0104773SPascal Brand TEE_Result res; 1327e86f1266SJens Wiklander uint64_t ml; 1328b0104773SPascal Brand 13296915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!message && messageLen)) { 133028e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 133128e0efc6SCedric Chaumont goto out; 133228e0efc6SCedric Chaumont } 13336915bbbbSJens Wiklander __utee_check_inout_annotation(macLen, sizeof(*macLen)); 1334b0104773SPascal Brand 133528e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) { 133628e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 133728e0efc6SCedric Chaumont goto out; 133828e0efc6SCedric Chaumont } 133928e0efc6SCedric Chaumont 134028e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 134128e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 134228e0efc6SCedric Chaumont goto out; 134328e0efc6SCedric Chaumont } 134428e0efc6SCedric Chaumont 1345642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1346642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1347642a1607SCedric Chaumont goto out; 1348642a1607SCedric Chaumont } 1349642a1607SCedric Chaumont 1350e86f1266SJens Wiklander ml = *macLen; 13512c028fdeSJerome Forissier res = _utee_hash_final(operation->state, message, messageLen, mac, &ml); 1352e86f1266SJens Wiklander *macLen = ml; 135328e0efc6SCedric Chaumont if (res != TEE_SUCCESS) 135428e0efc6SCedric Chaumont goto out; 135528e0efc6SCedric Chaumont 135628e0efc6SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 135728e0efc6SCedric Chaumont 1358642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1359642a1607SCedric Chaumont 136028e0efc6SCedric Chaumont out: 136128e0efc6SCedric Chaumont if (res != TEE_SUCCESS && 136228e0efc6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 136328e0efc6SCedric Chaumont TEE_Panic(res); 136428e0efc6SCedric Chaumont 1365b0104773SPascal Brand return res; 1366b0104773SPascal Brand } 1367b0104773SPascal Brand 1368185bf58cSJens Wiklander TEE_Result __GP11_TEE_MACComputeFinal(TEE_OperationHandle operation, 13698f07fe6fSJerome Forissier const void *message, uint32_t messageLen, 1370185bf58cSJens Wiklander void *mac, uint32_t *macLen) 1371185bf58cSJens Wiklander { 1372185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 1373185bf58cSJens Wiklander size_t ml = 0; 1374185bf58cSJens Wiklander 1375185bf58cSJens Wiklander __utee_check_inout_annotation(macLen, sizeof(*macLen)); 1376185bf58cSJens Wiklander ml = *macLen; 1377185bf58cSJens Wiklander res = TEE_MACComputeFinal(operation, message, messageLen, mac, &ml); 1378185bf58cSJens Wiklander *macLen = ml; 1379185bf58cSJens Wiklander return res; 1380185bf58cSJens Wiklander } 1381185bf58cSJens Wiklander 1382185bf58cSJens Wiklander TEE_Result TEE_MACCompareFinal(TEE_OperationHandle operation, 1383185bf58cSJens Wiklander const void *message, size_t messageLen, 1384185bf58cSJens Wiklander const void *mac, size_t macLen) 1385b0104773SPascal Brand { 1386b0104773SPascal Brand TEE_Result res; 1387ee4ba3d1SVictor Chong uint8_t computed_mac[TEE_MAX_HASH_SIZE] = { 0 }; 1388185bf58cSJens Wiklander size_t computed_mac_size = TEE_MAX_HASH_SIZE; 1389b0104773SPascal Brand 139028e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) { 139128e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 139228e0efc6SCedric Chaumont goto out; 139328e0efc6SCedric Chaumont } 139428e0efc6SCedric Chaumont 139528e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 139628e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 139728e0efc6SCedric Chaumont goto out; 139828e0efc6SCedric Chaumont } 139928e0efc6SCedric Chaumont 1400642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1401642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1402642a1607SCedric Chaumont goto out; 1403642a1607SCedric Chaumont } 1404642a1607SCedric Chaumont 1405b0104773SPascal Brand res = TEE_MACComputeFinal(operation, message, messageLen, computed_mac, 1406b0104773SPascal Brand &computed_mac_size); 1407b0104773SPascal Brand if (res != TEE_SUCCESS) 140828e0efc6SCedric Chaumont goto out; 140928e0efc6SCedric Chaumont 141028e0efc6SCedric Chaumont if (computed_mac_size != macLen) { 141128e0efc6SCedric Chaumont res = TEE_ERROR_MAC_INVALID; 141228e0efc6SCedric Chaumont goto out; 141328e0efc6SCedric Chaumont } 141428e0efc6SCedric Chaumont 141548e10604SJerome Forissier if (consttime_memcmp(mac, computed_mac, computed_mac_size) != 0) { 141628e0efc6SCedric Chaumont res = TEE_ERROR_MAC_INVALID; 141728e0efc6SCedric Chaumont goto out; 141828e0efc6SCedric Chaumont } 141928e0efc6SCedric Chaumont 1420642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1421642a1607SCedric Chaumont 142228e0efc6SCedric Chaumont out: 142328e0efc6SCedric Chaumont if (res != TEE_SUCCESS && 142428e0efc6SCedric Chaumont res != TEE_ERROR_MAC_INVALID) 142528e0efc6SCedric Chaumont TEE_Panic(res); 142628e0efc6SCedric Chaumont 1427b0104773SPascal Brand return res; 1428b0104773SPascal Brand } 1429b0104773SPascal Brand 1430185bf58cSJens Wiklander TEE_Result __GP11_TEE_MACCompareFinal(TEE_OperationHandle operation, 1431185bf58cSJens Wiklander const void *message, uint32_t messageLen, 1432185bf58cSJens Wiklander const void *mac, uint32_t macLen) 1433185bf58cSJens Wiklander { 1434185bf58cSJens Wiklander return TEE_MACCompareFinal(operation, message, messageLen, mac, macLen); 1435185bf58cSJens Wiklander } 1436185bf58cSJens Wiklander 1437b0104773SPascal Brand /* Cryptographic Operations API - Authenticated Encryption Functions */ 1438b0104773SPascal Brand 14398f07fe6fSJerome Forissier TEE_Result TEE_AEInit(TEE_OperationHandle operation, const void *nonce, 1440d9096215SJens Wiklander size_t nonceLen, uint32_t tagLen, size_t AADLen, 1441d9096215SJens Wiklander size_t payloadLen) 1442b0104773SPascal Brand { 1443b0104773SPascal Brand TEE_Result res; 1444b0104773SPascal Brand 1445b5816c88SCedric Chaumont if (operation == TEE_HANDLE_NULL || nonce == NULL) { 1446b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1447b5816c88SCedric Chaumont goto out; 1448b5816c88SCedric Chaumont } 1449b5816c88SCedric Chaumont 1450b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1451b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1452b5816c88SCedric Chaumont goto out; 1453b5816c88SCedric Chaumont } 1454b0104773SPascal Brand 1455642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) { 1456642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1457642a1607SCedric Chaumont goto out; 1458642a1607SCedric Chaumont } 1459642a1607SCedric Chaumont 1460b0104773SPascal Brand /* 1461b0104773SPascal Brand * AES-CCM tag len is specified by AES-CCM spec and handled in TEE Core 1462b0104773SPascal Brand * in the implementation. But AES-GCM spec doesn't specify the tag len 1463b0104773SPascal Brand * according to the same principle so we have to check here instead to 1464b0104773SPascal Brand * be GP compliant. 1465b0104773SPascal Brand */ 1466b5816c88SCedric Chaumont if (operation->info.algorithm == TEE_ALG_AES_GCM) { 1467b0104773SPascal Brand /* 1468b0104773SPascal Brand * From GP spec: For AES-GCM, can be 128, 120, 112, 104, or 96 1469b0104773SPascal Brand */ 1470b5816c88SCedric Chaumont if (tagLen < 96 || tagLen > 128 || (tagLen % 8 != 0)) { 1471b5816c88SCedric Chaumont res = TEE_ERROR_NOT_SUPPORTED; 1472b5816c88SCedric Chaumont goto out; 1473b5816c88SCedric Chaumont } 1474b0104773SPascal Brand } 1475b0104773SPascal Brand 14762c028fdeSJerome Forissier res = _utee_authenc_init(operation->state, nonce, nonceLen, tagLen / 8, 14772c028fdeSJerome Forissier AADLen, payloadLen); 1478b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1479b5816c88SCedric Chaumont goto out; 1480b5816c88SCedric Chaumont 14817acaf5adSAlbert Schwarzkopf operation->info.digestLength = tagLen / 8; 1482f2674567SSumit Garg operation->buffer_offs = 0; 1483b5816c88SCedric Chaumont operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 1484b5816c88SCedric Chaumont 1485b5816c88SCedric Chaumont out: 1486b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1487b5816c88SCedric Chaumont res != TEE_ERROR_NOT_SUPPORTED) 1488b0104773SPascal Brand TEE_Panic(res); 1489b5816c88SCedric Chaumont 1490b0104773SPascal Brand return res; 1491b0104773SPascal Brand } 1492b0104773SPascal Brand 1493d9096215SJens Wiklander TEE_Result __GP11_TEE_AEInit(TEE_OperationHandle operation, const void *nonce, 1494d9096215SJens Wiklander uint32_t nonceLen, uint32_t tagLen, 1495d9096215SJens Wiklander uint32_t AADLen, uint32_t payloadLen) 1496d9096215SJens Wiklander { 1497d9096215SJens Wiklander return TEE_AEInit(operation, nonce, nonceLen, tagLen, AADLen, 1498d9096215SJens Wiklander payloadLen); 1499d9096215SJens Wiklander } 1500d9096215SJens Wiklander 15018f07fe6fSJerome Forissier void TEE_AEUpdateAAD(TEE_OperationHandle operation, const void *AADdata, 1502d9096215SJens Wiklander size_t AADdataLen) 1503d9096215SJens Wiklander { 1504d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1505d9096215SJens Wiklander 1506d9096215SJens Wiklander if (operation == TEE_HANDLE_NULL || (!AADdata && AADdataLen)) 1507d9096215SJens Wiklander TEE_Panic(0); 1508d9096215SJens Wiklander 1509d9096215SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_AE) 1510d9096215SJens Wiklander TEE_Panic(0); 1511d9096215SJens Wiklander 1512d9096215SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 1513d9096215SJens Wiklander TEE_Panic(0); 1514d9096215SJens Wiklander 1515d9096215SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 1516d9096215SJens Wiklander TEE_Panic(0); 1517d9096215SJens Wiklander 1518d9096215SJens Wiklander res = _utee_authenc_update_aad(operation->state, AADdata, AADdataLen); 1519d9096215SJens Wiklander if (res != TEE_SUCCESS) 1520d9096215SJens Wiklander TEE_Panic(res); 1521d9096215SJens Wiklander } 1522d9096215SJens Wiklander 1523d9096215SJens Wiklander void __GP11_TEE_AEUpdateAAD(TEE_OperationHandle operation, const void *AADdata, 152479a3c601SCedric Chaumont uint32_t AADdataLen) 1525b0104773SPascal Brand { 1526d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1527b0104773SPascal Brand 1528b5816c88SCedric Chaumont if (operation == TEE_HANDLE_NULL || 1529b5816c88SCedric Chaumont (AADdata == NULL && AADdataLen != 0)) 1530b0104773SPascal Brand TEE_Panic(0); 1531642a1607SCedric Chaumont 1532b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) 1533b0104773SPascal Brand TEE_Panic(0); 1534642a1607SCedric Chaumont 1535b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 1536b0104773SPascal Brand TEE_Panic(0); 1537b0104773SPascal Brand 15382c028fdeSJerome Forissier res = _utee_authenc_update_aad(operation->state, AADdata, AADdataLen); 1539642a1607SCedric Chaumont 1540642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1541642a1607SCedric Chaumont 1542b0104773SPascal Brand if (res != TEE_SUCCESS) 1543b0104773SPascal Brand TEE_Panic(res); 1544b0104773SPascal Brand } 1545b0104773SPascal Brand 1546d9096215SJens Wiklander static TEE_Result ae_update_helper(TEE_OperationHandle operation, 1547d9096215SJens Wiklander const void *src, size_t slen, void *dst, 1548d9096215SJens Wiklander size_t *dlen) 1549b0104773SPascal Brand { 15506915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 15516915bbbbSJens Wiklander size_t req_dlen = 0; 15526915bbbbSJens Wiklander uint64_t dl = 0; 1553b0104773SPascal Brand 1554d9096215SJens Wiklander if (!src && !slen) { 1555d9096215SJens Wiklander *dlen = 0; 1556d9096215SJens Wiklander return TEE_SUCCESS; 1557d9096215SJens Wiklander } 1558d9096215SJens Wiklander 1559d9096215SJens Wiklander /* 1560d9096215SJens Wiklander * Check that required destLen is big enough before starting to feed 1561d9096215SJens Wiklander * data to the algorithm. Errors during feeding of data are fatal as we 1562d9096215SJens Wiklander * can't restore sync with this API. 1563d9096215SJens Wiklander */ 1564d9096215SJens Wiklander if (operation->block_size > 1) { 1565d9096215SJens Wiklander req_dlen = ROUNDDOWN(operation->buffer_offs + slen, 1566d9096215SJens Wiklander operation->block_size); 1567d9096215SJens Wiklander } else { 1568d9096215SJens Wiklander req_dlen = slen; 1569d9096215SJens Wiklander } 1570d9096215SJens Wiklander 1571d9096215SJens Wiklander dl = *dlen; 1572d9096215SJens Wiklander if (dl < req_dlen) { 1573d9096215SJens Wiklander *dlen = req_dlen; 1574d9096215SJens Wiklander return TEE_ERROR_SHORT_BUFFER; 1575d9096215SJens Wiklander } 1576d9096215SJens Wiklander 1577d9096215SJens Wiklander if (operation->block_size > 1) { 1578d9096215SJens Wiklander res = tee_buffer_update(operation, _utee_authenc_update_payload, 1579d9096215SJens Wiklander src, slen, dst, &dl); 1580d9096215SJens Wiklander } else { 1581d9096215SJens Wiklander if (slen > 0) { 1582d9096215SJens Wiklander res = _utee_authenc_update_payload(operation->state, 1583d9096215SJens Wiklander src, slen, dst, &dl); 1584d9096215SJens Wiklander } else { 1585d9096215SJens Wiklander dl = 0; 1586d9096215SJens Wiklander res = TEE_SUCCESS; 1587d9096215SJens Wiklander } 1588d9096215SJens Wiklander } 1589d9096215SJens Wiklander 1590d9096215SJens Wiklander if (!res) 1591d9096215SJens Wiklander *dlen = dl; 1592d9096215SJens Wiklander 1593d9096215SJens Wiklander return res; 1594d9096215SJens Wiklander } 1595d9096215SJens Wiklander 1596d9096215SJens Wiklander TEE_Result TEE_AEUpdate(TEE_OperationHandle operation, const void *srcData, 1597d9096215SJens Wiklander size_t srcLen, void *destData, size_t *destLen) 1598d9096215SJens Wiklander { 1599d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1600d9096215SJens Wiklander 16016915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1602b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1603b5816c88SCedric Chaumont goto out; 1604b5816c88SCedric Chaumont } 1605d9096215SJens Wiklander __utee_check_outbuf_annotation(destData, destLen); 1606b5816c88SCedric Chaumont 1607b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1608b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1609b5816c88SCedric Chaumont goto out; 1610b5816c88SCedric Chaumont } 1611b5816c88SCedric Chaumont 1612b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1613b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1614b5816c88SCedric Chaumont goto out; 1615b5816c88SCedric Chaumont } 1616b0104773SPascal Brand 1617d9096215SJens Wiklander res = ae_update_helper(operation, srcData, srcLen, destData, destLen); 1618d9096215SJens Wiklander if (res != TEE_ERROR_SHORT_BUFFER && srcLen) 1619d9096215SJens Wiklander operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1620d9096215SJens Wiklander 1621d9096215SJens Wiklander out: 1622d9096215SJens Wiklander if (res != TEE_SUCCESS && 1623d9096215SJens Wiklander res != TEE_ERROR_SHORT_BUFFER) 1624d9096215SJens Wiklander TEE_Panic(res); 1625d9096215SJens Wiklander 1626d9096215SJens Wiklander return res; 1627d9096215SJens Wiklander } 1628d9096215SJens Wiklander 1629d9096215SJens Wiklander TEE_Result __GP11_TEE_AEUpdate(TEE_OperationHandle operation, 1630d9096215SJens Wiklander const void *srcData, uint32_t srcLen, 1631d9096215SJens Wiklander void *destData, uint32_t *destLen) 1632d9096215SJens Wiklander { 1633d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1634d9096215SJens Wiklander size_t dl = 0; 1635d9096215SJens Wiklander 1636d9096215SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1637d9096215SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1638d9096215SJens Wiklander goto out; 1639d9096215SJens Wiklander } 1640d9096215SJens Wiklander __utee_check_gp11_outbuf_annotation(destData, destLen); 1641d9096215SJens Wiklander 1642d9096215SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_AE) { 1643d9096215SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1644827308b8SJerome Forissier goto out; 1645827308b8SJerome Forissier } 1646827308b8SJerome Forissier 1647d9096215SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1648d9096215SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1649d9096215SJens Wiklander goto out; 1650afc0c182SBogdan Liulko } 1651afc0c182SBogdan Liulko 16526915bbbbSJens Wiklander dl = *destLen; 1653d9096215SJens Wiklander res = ae_update_helper(operation, srcData, srcLen, destData, &dl); 1654d9096215SJens Wiklander *destLen = dl; 1655b0104773SPascal Brand 1656afc0c182SBogdan Liulko if (res != TEE_SUCCESS) 1657afc0c182SBogdan Liulko goto out; 1658afc0c182SBogdan Liulko 1659642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1660642a1607SCedric Chaumont 1661b5816c88SCedric Chaumont out: 1662b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1663b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1664b5816c88SCedric Chaumont TEE_Panic(res); 1665b5816c88SCedric Chaumont 1666b5816c88SCedric Chaumont return res; 1667b0104773SPascal Brand } 1668b0104773SPascal Brand 1669b5816c88SCedric Chaumont TEE_Result TEE_AEEncryptFinal(TEE_OperationHandle operation, 1670d9096215SJens Wiklander const void *srcData, size_t srcLen, 1671d9096215SJens Wiklander void *destData, size_t *destLen, void *tag, 1672d9096215SJens Wiklander size_t *tagLen) 1673b0104773SPascal Brand { 1674d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1675b0104773SPascal Brand uint8_t *dst = destData; 1676b0104773SPascal Brand size_t acc_dlen = 0; 1677d9096215SJens Wiklander uint64_t tmp_dlen = 0; 1678d9096215SJens Wiklander size_t req_dlen = 0; 1679d9096215SJens Wiklander uint64_t tl = 0; 1680b0104773SPascal Brand 16816915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1682b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1683b5816c88SCedric Chaumont goto out; 1684b5816c88SCedric Chaumont } 16856915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 16866915bbbbSJens Wiklander __utee_check_inout_annotation(tagLen, sizeof(*tagLen)); 1687b5816c88SCedric Chaumont 1688b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1689b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1690b5816c88SCedric Chaumont goto out; 1691b5816c88SCedric Chaumont } 1692b5816c88SCedric Chaumont 1693b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1694b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1695b5816c88SCedric Chaumont goto out; 1696b5816c88SCedric Chaumont } 1697b0104773SPascal Brand 1698b0104773SPascal Brand /* 1699b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1700b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1701b0104773SPascal Brand * can't restore sync with this API. 17022733280aSEtienne Carriere * 17032733280aSEtienne Carriere * Need to check this before update_payload since sync would be lost if 17042733280aSEtienne Carriere * we return short buffer after that. 1705b0104773SPascal Brand */ 17062733280aSEtienne Carriere res = TEE_ERROR_GENERIC; 17072733280aSEtienne Carriere 1708b5816c88SCedric Chaumont req_dlen = operation->buffer_offs + srcLen; 1709b0104773SPascal Brand if (*destLen < req_dlen) { 1710b0104773SPascal Brand *destLen = req_dlen; 1711b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1712b0104773SPascal Brand } 1713b0104773SPascal Brand 17147acaf5adSAlbert Schwarzkopf if (*tagLen < operation->info.digestLength) { 17157acaf5adSAlbert Schwarzkopf *tagLen = operation->info.digestLength; 1716b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1717b0104773SPascal Brand } 1718b0104773SPascal Brand 17192733280aSEtienne Carriere if (res == TEE_ERROR_SHORT_BUFFER) 17202733280aSEtienne Carriere goto out; 17212733280aSEtienne Carriere 1722afc0c182SBogdan Liulko tl = *tagLen; 1723b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 1724afc0c182SBogdan Liulko if (operation->block_size > 1) { 17252c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_authenc_update_payload, 1726afc0c182SBogdan Liulko srcData, srcLen, dst, &tmp_dlen); 1727b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1728b5816c88SCedric Chaumont goto out; 1729b5816c88SCedric Chaumont 1730b0104773SPascal Brand dst += tmp_dlen; 1731b0104773SPascal Brand acc_dlen += tmp_dlen; 1732b0104773SPascal Brand 1733b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 17342c028fdeSJerome Forissier res = _utee_authenc_enc_final(operation->state, 1735afc0c182SBogdan Liulko operation->buffer, 1736afc0c182SBogdan Liulko operation->buffer_offs, dst, 1737afc0c182SBogdan Liulko &tmp_dlen, tag, &tl); 1738afc0c182SBogdan Liulko } else { 17392c028fdeSJerome Forissier res = _utee_authenc_enc_final(operation->state, srcData, 1740afc0c182SBogdan Liulko srcLen, dst, &tmp_dlen, 1741e86f1266SJens Wiklander tag, &tl); 1742afc0c182SBogdan Liulko } 1743e86f1266SJens Wiklander *tagLen = tl; 1744b0104773SPascal Brand if (res != TEE_SUCCESS) 1745b5816c88SCedric Chaumont goto out; 1746b0104773SPascal Brand 1747b5816c88SCedric Chaumont acc_dlen += tmp_dlen; 1748b0104773SPascal Brand *destLen = acc_dlen; 1749642a1607SCedric Chaumont 1750b5816c88SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 1751b5816c88SCedric Chaumont 1752642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1753642a1607SCedric Chaumont 1754b5816c88SCedric Chaumont out: 1755b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1756b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1757b5816c88SCedric Chaumont TEE_Panic(res); 1758b0104773SPascal Brand 1759b0104773SPascal Brand return res; 1760b0104773SPascal Brand } 1761b0104773SPascal Brand 1762d9096215SJens Wiklander TEE_Result __GP11_TEE_AEEncryptFinal(TEE_OperationHandle operation, 17638f07fe6fSJerome Forissier const void *srcData, uint32_t srcLen, 1764d9096215SJens Wiklander void *destData, uint32_t *destLen, 1765d9096215SJens Wiklander void *tag, uint32_t *tagLen) 1766b0104773SPascal Brand { 1767d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1768d9096215SJens Wiklander size_t dl = 0; 1769d9096215SJens Wiklander size_t tl = 0; 1770d9096215SJens Wiklander 1771d9096215SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1772d9096215SJens Wiklander __utee_check_inout_annotation(tagLen, sizeof(*tagLen)); 1773d9096215SJens Wiklander dl = *destLen; 1774d9096215SJens Wiklander tl = *tagLen; 1775d9096215SJens Wiklander res = TEE_AEEncryptFinal(operation, srcData, srcLen, destData, &dl, 1776d9096215SJens Wiklander tag, &tl); 1777d9096215SJens Wiklander *destLen = dl; 1778d9096215SJens Wiklander *tagLen = tl; 1779d9096215SJens Wiklander return res; 1780d9096215SJens Wiklander } 1781d9096215SJens Wiklander 1782d9096215SJens Wiklander TEE_Result TEE_AEDecryptFinal(TEE_OperationHandle operation, 1783d9096215SJens Wiklander const void *srcData, size_t srcLen, 1784d9096215SJens Wiklander void *destData, size_t *destLen, void *tag, 1785d9096215SJens Wiklander size_t tagLen) 1786d9096215SJens Wiklander { 1787d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1788b0104773SPascal Brand uint8_t *dst = destData; 1789b0104773SPascal Brand size_t acc_dlen = 0; 1790d9096215SJens Wiklander uint64_t tmp_dlen = 0; 1791d9096215SJens Wiklander size_t req_dlen = 0; 1792b0104773SPascal Brand 17936915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1794b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1795b5816c88SCedric Chaumont goto out; 1796b5816c88SCedric Chaumont } 17976915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1798b5816c88SCedric Chaumont 1799b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1800b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1801b5816c88SCedric Chaumont goto out; 1802b5816c88SCedric Chaumont } 1803b5816c88SCedric Chaumont 1804b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1805b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1806b5816c88SCedric Chaumont goto out; 1807b5816c88SCedric Chaumont } 1808b0104773SPascal Brand 1809b0104773SPascal Brand /* 1810b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1811b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1812b0104773SPascal Brand * can't restore sync with this API. 1813b0104773SPascal Brand */ 1814b5816c88SCedric Chaumont req_dlen = operation->buffer_offs + srcLen; 1815b0104773SPascal Brand if (*destLen < req_dlen) { 1816b0104773SPascal Brand *destLen = req_dlen; 1817b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1818b5816c88SCedric Chaumont goto out; 1819b0104773SPascal Brand } 1820b0104773SPascal Brand 1821b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 1822afc0c182SBogdan Liulko if (operation->block_size > 1) { 18232c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_authenc_update_payload, 1824afc0c182SBogdan Liulko srcData, srcLen, dst, &tmp_dlen); 1825b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1826b5816c88SCedric Chaumont goto out; 1827b5816c88SCedric Chaumont 1828b0104773SPascal Brand dst += tmp_dlen; 1829b0104773SPascal Brand acc_dlen += tmp_dlen; 1830b0104773SPascal Brand 1831b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 18322c028fdeSJerome Forissier res = _utee_authenc_dec_final(operation->state, 1833afc0c182SBogdan Liulko operation->buffer, 1834afc0c182SBogdan Liulko operation->buffer_offs, dst, 1835afc0c182SBogdan Liulko &tmp_dlen, tag, tagLen); 1836afc0c182SBogdan Liulko } else { 18372c028fdeSJerome Forissier res = _utee_authenc_dec_final(operation->state, srcData, 1838afc0c182SBogdan Liulko srcLen, dst, &tmp_dlen, 1839b5816c88SCedric Chaumont tag, tagLen); 1840afc0c182SBogdan Liulko } 1841b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1842b5816c88SCedric Chaumont goto out; 1843b5816c88SCedric Chaumont 1844b0104773SPascal Brand /* Supplied tagLen should match what we initiated with */ 18457acaf5adSAlbert Schwarzkopf if (tagLen != operation->info.digestLength) 1846b0104773SPascal Brand res = TEE_ERROR_MAC_INVALID; 1847b0104773SPascal Brand 1848b0104773SPascal Brand acc_dlen += tmp_dlen; 1849b0104773SPascal Brand *destLen = acc_dlen; 1850642a1607SCedric Chaumont 1851b5816c88SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 1852b5816c88SCedric Chaumont 1853642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1854642a1607SCedric Chaumont 1855b5816c88SCedric Chaumont out: 1856b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1857b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER && 1858b5816c88SCedric Chaumont res != TEE_ERROR_MAC_INVALID) 1859b5816c88SCedric Chaumont TEE_Panic(res); 1860b0104773SPascal Brand 1861b0104773SPascal Brand return res; 1862b0104773SPascal Brand } 1863b0104773SPascal Brand 1864d9096215SJens Wiklander TEE_Result __GP11_TEE_AEDecryptFinal(TEE_OperationHandle operation, 1865d9096215SJens Wiklander const void *srcData, uint32_t srcLen, 1866d9096215SJens Wiklander void *destData, uint32_t *destLen, 1867d9096215SJens Wiklander void *tag, uint32_t tagLen) 1868d9096215SJens Wiklander { 1869d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1870d9096215SJens Wiklander size_t dl = 0; 1871d9096215SJens Wiklander 1872d9096215SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1873d9096215SJens Wiklander dl = *destLen; 1874d9096215SJens Wiklander res = TEE_AEDecryptFinal(operation, srcData, srcLen, destData, &dl, 1875d9096215SJens Wiklander tag, tagLen); 1876d9096215SJens Wiklander *destLen = dl; 1877d9096215SJens Wiklander return res; 1878d9096215SJens Wiklander } 1879d9096215SJens Wiklander 1880b0104773SPascal Brand /* Cryptographic Operations API - Asymmetric Functions */ 1881b0104773SPascal Brand 188212e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricEncrypt(TEE_OperationHandle operation, 18838f07fe6fSJerome Forissier const TEE_Attribute *params, 18848f07fe6fSJerome Forissier uint32_t paramCount, const void *srcData, 1885999b69d0SJens Wiklander size_t srcLen, void *destData, 1886999b69d0SJens Wiklander size_t *destLen) 1887b0104773SPascal Brand { 18886915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 1889e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 18906915bbbbSJens Wiklander uint64_t dl = 0; 1891b0104773SPascal Brand 18926915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 1893b0104773SPascal Brand TEE_Panic(0); 18946915bbbbSJens Wiklander 18956915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 18966915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 18976915bbbbSJens Wiklander 189812e66b6fSCedric Chaumont if (!operation->key1) 1899b0104773SPascal Brand TEE_Panic(0); 190012e66b6fSCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 190112e66b6fSCedric Chaumont TEE_Panic(0); 190212e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_ENCRYPT) 1903b0104773SPascal Brand TEE_Panic(0); 1904b0104773SPascal Brand 1905e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 1906e86f1266SJens Wiklander dl = *destLen; 19072c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 1908e86f1266SJens Wiklander srcLen, destData, &dl); 1909e86f1266SJens Wiklander *destLen = dl; 191012e66b6fSCedric Chaumont 19118844ebfcSPascal Brand if (res != TEE_SUCCESS && 19128844ebfcSPascal Brand res != TEE_ERROR_SHORT_BUFFER && 19138844ebfcSPascal Brand res != TEE_ERROR_BAD_PARAMETERS) 1914b0104773SPascal Brand TEE_Panic(res); 191512e66b6fSCedric Chaumont 1916b0104773SPascal Brand return res; 1917b0104773SPascal Brand } 1918b0104773SPascal Brand 19194f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricEncrypt(TEE_OperationHandle operation, 19204f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 19214f4374c8SJens Wiklander uint32_t paramCount, 19224f4374c8SJens Wiklander const void *srcData, uint32_t srcLen, 19234f4374c8SJens Wiklander void *destData, uint32_t *destLen) 19244f4374c8SJens Wiklander { 19254f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 19264f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 19274f4374c8SJens Wiklander uint64_t dl = 0; 19284f4374c8SJens Wiklander 19294f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 19304f4374c8SJens Wiklander TEE_Panic(0); 19314f4374c8SJens Wiklander 19324f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 19334f4374c8SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 19344f4374c8SJens Wiklander 19354f4374c8SJens Wiklander if (!operation->key1) 19364f4374c8SJens Wiklander TEE_Panic(0); 19374f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 19384f4374c8SJens Wiklander TEE_Panic(0); 19394f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_ENCRYPT) 19404f4374c8SJens Wiklander TEE_Panic(0); 19414f4374c8SJens Wiklander 19424f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 19434f4374c8SJens Wiklander dl = *destLen; 19444f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 19454f4374c8SJens Wiklander srcLen, destData, &dl); 19464f4374c8SJens Wiklander *destLen = dl; 19474f4374c8SJens Wiklander 19484f4374c8SJens Wiklander if (res != TEE_SUCCESS && 19494f4374c8SJens Wiklander res != TEE_ERROR_SHORT_BUFFER && 19504f4374c8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS) 19514f4374c8SJens Wiklander TEE_Panic(res); 19524f4374c8SJens Wiklander 19534f4374c8SJens Wiklander return res; 19544f4374c8SJens Wiklander } 19554f4374c8SJens Wiklander 195612e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricDecrypt(TEE_OperationHandle operation, 19578f07fe6fSJerome Forissier const TEE_Attribute *params, 19588f07fe6fSJerome Forissier uint32_t paramCount, const void *srcData, 1959999b69d0SJens Wiklander size_t srcLen, void *destData, 1960999b69d0SJens Wiklander size_t *destLen) 1961b0104773SPascal Brand { 19626915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 1963e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 19646915bbbbSJens Wiklander uint64_t dl = 0; 1965b0104773SPascal Brand 19666915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 1967b0104773SPascal Brand TEE_Panic(0); 19686915bbbbSJens Wiklander 19696915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 19706915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 19716915bbbbSJens Wiklander 197212e66b6fSCedric Chaumont if (!operation->key1) 1973b0104773SPascal Brand TEE_Panic(0); 197412e66b6fSCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 197512e66b6fSCedric Chaumont TEE_Panic(0); 197612e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_DECRYPT) 1977b0104773SPascal Brand TEE_Panic(0); 1978b0104773SPascal Brand 1979e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 1980e86f1266SJens Wiklander dl = *destLen; 19812c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 1982e86f1266SJens Wiklander srcLen, destData, &dl); 1983e86f1266SJens Wiklander *destLen = dl; 198412e66b6fSCedric Chaumont 19858844ebfcSPascal Brand if (res != TEE_SUCCESS && 19868844ebfcSPascal Brand res != TEE_ERROR_SHORT_BUFFER && 19878844ebfcSPascal Brand res != TEE_ERROR_BAD_PARAMETERS) 1988b0104773SPascal Brand TEE_Panic(res); 198912e66b6fSCedric Chaumont 1990b0104773SPascal Brand return res; 1991b0104773SPascal Brand } 1992b0104773SPascal Brand 19934f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricDecrypt(TEE_OperationHandle operation, 19944f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 19954f4374c8SJens Wiklander uint32_t paramCount, 19964f4374c8SJens Wiklander const void *srcData, uint32_t srcLen, 19974f4374c8SJens Wiklander void *destData, uint32_t *destLen) 19984f4374c8SJens Wiklander { 19994f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 20004f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 20014f4374c8SJens Wiklander uint64_t dl = 0; 20024f4374c8SJens Wiklander 20034f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 20044f4374c8SJens Wiklander TEE_Panic(0); 20054f4374c8SJens Wiklander 20064f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 20074f4374c8SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 20084f4374c8SJens Wiklander 20094f4374c8SJens Wiklander if (!operation->key1) 20104f4374c8SJens Wiklander TEE_Panic(0); 20114f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 20124f4374c8SJens Wiklander TEE_Panic(0); 20134f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_DECRYPT) 20144f4374c8SJens Wiklander TEE_Panic(0); 20154f4374c8SJens Wiklander 20164f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 20174f4374c8SJens Wiklander dl = *destLen; 20184f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 20194f4374c8SJens Wiklander srcLen, destData, &dl); 20204f4374c8SJens Wiklander *destLen = dl; 20214f4374c8SJens Wiklander 20224f4374c8SJens Wiklander if (res != TEE_SUCCESS && 20234f4374c8SJens Wiklander res != TEE_ERROR_SHORT_BUFFER && 20244f4374c8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS) 20254f4374c8SJens Wiklander TEE_Panic(res); 20264f4374c8SJens Wiklander 20274f4374c8SJens Wiklander return res; 20284f4374c8SJens Wiklander } 20294f4374c8SJens Wiklander 203012e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricSignDigest(TEE_OperationHandle operation, 20318f07fe6fSJerome Forissier const TEE_Attribute *params, 20328f07fe6fSJerome Forissier uint32_t paramCount, const void *digest, 20330b354ec8SJens Wiklander size_t digestLen, void *signature, 20340b354ec8SJens Wiklander size_t *signatureLen) 2035b0104773SPascal Brand { 20366915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 2037e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 20386915bbbbSJens Wiklander uint64_t sl = 0; 2039b0104773SPascal Brand 20406915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen)) 2041b0104773SPascal Brand TEE_Panic(0); 20426915bbbbSJens Wiklander 20436915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 20446915bbbbSJens Wiklander __utee_check_inout_annotation(signatureLen, sizeof(*signatureLen)); 20456915bbbbSJens Wiklander 204612e66b6fSCedric Chaumont if (!operation->key1) 2047b0104773SPascal Brand TEE_Panic(0); 204812e66b6fSCedric Chaumont if (operation->info.operationClass != 204912e66b6fSCedric Chaumont TEE_OPERATION_ASYMMETRIC_SIGNATURE) 205012e66b6fSCedric Chaumont TEE_Panic(0); 205112e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_SIGN) 2052b0104773SPascal Brand TEE_Panic(0); 2053b0104773SPascal Brand 2054e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 2055e86f1266SJens Wiklander sl = *signatureLen; 20562c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, digest, 2057e86f1266SJens Wiklander digestLen, signature, &sl); 2058e86f1266SJens Wiklander *signatureLen = sl; 205912e66b6fSCedric Chaumont 2060b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER) 2061b0104773SPascal Brand TEE_Panic(res); 206212e66b6fSCedric Chaumont 2063b0104773SPascal Brand return res; 2064b0104773SPascal Brand } 2065b0104773SPascal Brand 20664f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricSignDigest(TEE_OperationHandle operation, 20674f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 20684f4374c8SJens Wiklander uint32_t paramCount, 20694f4374c8SJens Wiklander const void *digest, 20704f4374c8SJens Wiklander uint32_t digestLen, void *signature, 20714f4374c8SJens Wiklander uint32_t *signatureLen) 20724f4374c8SJens Wiklander { 20734f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 20744f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 20754f4374c8SJens Wiklander uint64_t sl = 0; 20764f4374c8SJens Wiklander 20774f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen)) 20784f4374c8SJens Wiklander TEE_Panic(0); 20794f4374c8SJens Wiklander 20804f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 20814f4374c8SJens Wiklander __utee_check_inout_annotation(signatureLen, sizeof(*signatureLen)); 20824f4374c8SJens Wiklander 20834f4374c8SJens Wiklander if (!operation->key1) 20844f4374c8SJens Wiklander TEE_Panic(0); 20854f4374c8SJens Wiklander if (operation->info.operationClass != 20864f4374c8SJens Wiklander TEE_OPERATION_ASYMMETRIC_SIGNATURE) 20874f4374c8SJens Wiklander TEE_Panic(0); 20884f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_SIGN) 20894f4374c8SJens Wiklander TEE_Panic(0); 20904f4374c8SJens Wiklander 20914f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 20924f4374c8SJens Wiklander sl = *signatureLen; 20934f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, digest, 20944f4374c8SJens Wiklander digestLen, signature, &sl); 20954f4374c8SJens Wiklander *signatureLen = sl; 20964f4374c8SJens Wiklander 20974f4374c8SJens Wiklander if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER) 20984f4374c8SJens Wiklander TEE_Panic(res); 20994f4374c8SJens Wiklander 21004f4374c8SJens Wiklander return res; 21014f4374c8SJens Wiklander } 21024f4374c8SJens Wiklander 210312e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation, 21048f07fe6fSJerome Forissier const TEE_Attribute *params, 21058f07fe6fSJerome Forissier uint32_t paramCount, const void *digest, 21060b354ec8SJens Wiklander size_t digestLen, 21078f07fe6fSJerome Forissier const void *signature, 21080b354ec8SJens Wiklander size_t signatureLen) 2109b0104773SPascal Brand { 2110b0104773SPascal Brand TEE_Result res; 2111e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 2112b0104773SPascal Brand 211312e66b6fSCedric Chaumont if (operation == TEE_HANDLE_NULL || 211412e66b6fSCedric Chaumont (digest == NULL && digestLen != 0) || 2115b0104773SPascal Brand (signature == NULL && signatureLen != 0)) 2116b0104773SPascal Brand TEE_Panic(0); 21176915bbbbSJens Wiklander 21186915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 21196915bbbbSJens Wiklander 212012e66b6fSCedric Chaumont if (!operation->key1) 2121b0104773SPascal Brand TEE_Panic(0); 212212e66b6fSCedric Chaumont if (operation->info.operationClass != 212312e66b6fSCedric Chaumont TEE_OPERATION_ASYMMETRIC_SIGNATURE) 212412e66b6fSCedric Chaumont TEE_Panic(0); 212512e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_VERIFY) 2126b0104773SPascal Brand TEE_Panic(0); 2127b0104773SPascal Brand 2128e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 21292c028fdeSJerome Forissier res = _utee_asymm_verify(operation->state, ua, paramCount, digest, 213012e66b6fSCedric Chaumont digestLen, signature, signatureLen); 213112e66b6fSCedric Chaumont 2132b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID) 2133b0104773SPascal Brand TEE_Panic(res); 213412e66b6fSCedric Chaumont 2135b0104773SPascal Brand return res; 2136b0104773SPascal Brand } 2137b0104773SPascal Brand 21384f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation, 21394f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 21404f4374c8SJens Wiklander uint32_t paramCount, 21414f4374c8SJens Wiklander const void *digest, 21424f4374c8SJens Wiklander uint32_t digestLen, 21434f4374c8SJens Wiklander const void *signature, 21444f4374c8SJens Wiklander uint32_t signatureLen) 21454f4374c8SJens Wiklander { 21464f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 21474f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 21484f4374c8SJens Wiklander 21494f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen) || 21504f4374c8SJens Wiklander (!signature && signatureLen)) 21514f4374c8SJens Wiklander TEE_Panic(0); 21524f4374c8SJens Wiklander 21534f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 21544f4374c8SJens Wiklander 21554f4374c8SJens Wiklander if (!operation->key1) 21564f4374c8SJens Wiklander TEE_Panic(0); 21574f4374c8SJens Wiklander if (operation->info.operationClass != 21584f4374c8SJens Wiklander TEE_OPERATION_ASYMMETRIC_SIGNATURE) 21594f4374c8SJens Wiklander TEE_Panic(0); 21604f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_VERIFY) 21614f4374c8SJens Wiklander TEE_Panic(0); 21624f4374c8SJens Wiklander 21634f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 21644f4374c8SJens Wiklander res = _utee_asymm_verify(operation->state, ua, paramCount, digest, 21654f4374c8SJens Wiklander digestLen, signature, signatureLen); 21664f4374c8SJens Wiklander 21674f4374c8SJens Wiklander if (res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID) 21684f4374c8SJens Wiklander TEE_Panic(res); 21694f4374c8SJens Wiklander 21704f4374c8SJens Wiklander return res; 21714f4374c8SJens Wiklander } 21724f4374c8SJens Wiklander 2173b0104773SPascal Brand /* Cryptographic Operations API - Key Derivation Functions */ 2174b0104773SPascal Brand 2175b0104773SPascal Brand void TEE_DeriveKey(TEE_OperationHandle operation, 2176b0104773SPascal Brand const TEE_Attribute *params, uint32_t paramCount, 2177b0104773SPascal Brand TEE_ObjectHandle derivedKey) 2178b0104773SPascal Brand { 2179e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 218075d6a373SJens Wiklander struct utee_object_info key_info = { }; 218175d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 2182b0104773SPascal Brand 2183b0104773SPascal Brand if (operation == TEE_HANDLE_NULL || derivedKey == 0) 2184b0104773SPascal Brand TEE_Panic(0); 21856915bbbbSJens Wiklander 21866915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 21876915bbbbSJens Wiklander 21888854d3c6SJerome Forissier if (TEE_ALG_GET_CLASS(operation->info.algorithm) != 21898854d3c6SJerome Forissier TEE_OPERATION_KEY_DERIVATION) 2190b0104773SPascal Brand TEE_Panic(0); 2191b0104773SPascal Brand 2192b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_KEY_DERIVATION) 2193b0104773SPascal Brand TEE_Panic(0); 219484fa9467SCedric Chaumont if (!operation->key1) 219584fa9467SCedric Chaumont TEE_Panic(0); 2196b0104773SPascal Brand if (operation->info.mode != TEE_MODE_DERIVE) 2197b0104773SPascal Brand TEE_Panic(0); 2198b0104773SPascal Brand if ((operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0) 2199b0104773SPascal Brand TEE_Panic(0); 2200b0104773SPascal Brand 22012c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)derivedKey, &key_info); 2202b0104773SPascal Brand if (res != TEE_SUCCESS) 2203b36311adSJerome Forissier TEE_Panic(res); 2204b0104773SPascal Brand 220575d6a373SJens Wiklander if (key_info.obj_type != TEE_TYPE_GENERIC_SECRET) 2206b0104773SPascal Brand TEE_Panic(0); 220775d6a373SJens Wiklander if ((key_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 2208b0104773SPascal Brand TEE_Panic(0); 2209b0104773SPascal Brand 2210e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 22112c028fdeSJerome Forissier res = _utee_cryp_derive_key(operation->state, ua, paramCount, 2212e86f1266SJens Wiklander (unsigned long)derivedKey); 2213b0104773SPascal Brand if (res != TEE_SUCCESS) 2214b0104773SPascal Brand TEE_Panic(res); 2215b0104773SPascal Brand } 2216b0104773SPascal Brand 22174f4374c8SJens Wiklander void __GP11_TEE_DeriveKey(TEE_OperationHandle operation, 22184f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 22194f4374c8SJens Wiklander uint32_t paramCount, TEE_ObjectHandle derivedKey) 22204f4374c8SJens Wiklander { 22214f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 22224f4374c8SJens Wiklander struct utee_object_info key_info = { }; 22234f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 22244f4374c8SJens Wiklander 22254f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || derivedKey == 0) 22264f4374c8SJens Wiklander TEE_Panic(0); 22274f4374c8SJens Wiklander 22284f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 22294f4374c8SJens Wiklander 22304f4374c8SJens Wiklander if (TEE_ALG_GET_CLASS(operation->info.algorithm) != 22314f4374c8SJens Wiklander TEE_OPERATION_KEY_DERIVATION) 22324f4374c8SJens Wiklander TEE_Panic(0); 22334f4374c8SJens Wiklander 22344f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_KEY_DERIVATION) 22354f4374c8SJens Wiklander TEE_Panic(0); 22364f4374c8SJens Wiklander if (!operation->key1) 22374f4374c8SJens Wiklander TEE_Panic(0); 22384f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_DERIVE) 22394f4374c8SJens Wiklander TEE_Panic(0); 22404f4374c8SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0) 22414f4374c8SJens Wiklander TEE_Panic(0); 22424f4374c8SJens Wiklander 22434f4374c8SJens Wiklander res = _utee_cryp_obj_get_info((unsigned long)derivedKey, &key_info); 22444f4374c8SJens Wiklander if (res != TEE_SUCCESS) 22454f4374c8SJens Wiklander TEE_Panic(res); 22464f4374c8SJens Wiklander 22474f4374c8SJens Wiklander if (key_info.obj_type != TEE_TYPE_GENERIC_SECRET) 22484f4374c8SJens Wiklander TEE_Panic(0); 22494f4374c8SJens Wiklander if ((key_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 22504f4374c8SJens Wiklander TEE_Panic(0); 22514f4374c8SJens Wiklander 22524f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 22534f4374c8SJens Wiklander res = _utee_cryp_derive_key(operation->state, ua, paramCount, 22544f4374c8SJens Wiklander (unsigned long)derivedKey); 22554f4374c8SJens Wiklander if (res != TEE_SUCCESS) 22564f4374c8SJens Wiklander TEE_Panic(res); 22574f4374c8SJens Wiklander } 22584f4374c8SJens Wiklander 2259b0104773SPascal Brand /* Cryptographic Operations API - Random Number Generation Functions */ 2260b0104773SPascal Brand 2261411a488aSJens Wiklander void TEE_GenerateRandom(void *randomBuffer, size_t randomBufferLen) 2262b0104773SPascal Brand { 2263b0104773SPascal Brand TEE_Result res; 2264b0104773SPascal Brand 22652c028fdeSJerome Forissier res = _utee_cryp_random_number_generate(randomBuffer, randomBufferLen); 2266b0104773SPascal Brand if (res != TEE_SUCCESS) 2267b0104773SPascal Brand TEE_Panic(res); 2268b0104773SPascal Brand } 2269433c4257SJens Wiklander 2270411a488aSJens Wiklander void __GP11_TEE_GenerateRandom(void *randomBuffer, uint32_t randomBufferLen) 2271411a488aSJens Wiklander { 2272411a488aSJens Wiklander TEE_GenerateRandom(randomBuffer, randomBufferLen); 2273411a488aSJens Wiklander } 2274411a488aSJens Wiklander 2275433c4257SJens Wiklander int rand(void) 2276433c4257SJens Wiklander { 2277433c4257SJens Wiklander int rc; 2278433c4257SJens Wiklander 2279433c4257SJens Wiklander TEE_GenerateRandom(&rc, sizeof(rc)); 2280433c4257SJens Wiklander 2281433c4257SJens Wiklander /* 2282433c4257SJens Wiklander * RAND_MAX is the larges int, INT_MAX which is all bits but the 2283433c4257SJens Wiklander * highest bit set. 2284433c4257SJens Wiklander */ 2285433c4257SJens Wiklander return rc & RAND_MAX; 2286433c4257SJens Wiklander } 228779170ce0SJerome Forissier 228879170ce0SJerome Forissier TEE_Result TEE_IsAlgorithmSupported(uint32_t alg, uint32_t element) 228979170ce0SJerome Forissier { 229079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_AES)) { 229179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) { 229279170ce0SJerome Forissier if (alg == TEE_ALG_AES_ECB_NOPAD) 229379170ce0SJerome Forissier goto check_element_none; 229479170ce0SJerome Forissier } 229579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) { 229679170ce0SJerome Forissier if (alg == TEE_ALG_AES_CBC_NOPAD) 229779170ce0SJerome Forissier goto check_element_none; 229879170ce0SJerome Forissier } 229979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTR)) { 230079170ce0SJerome Forissier if (alg == TEE_ALG_AES_CTR) 230179170ce0SJerome Forissier goto check_element_none; 230279170ce0SJerome Forissier } 230379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTS)) { 230479170ce0SJerome Forissier if (alg == TEE_ALG_AES_CTS) 230579170ce0SJerome Forissier goto check_element_none; 230679170ce0SJerome Forissier } 230779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_XTS)) { 230879170ce0SJerome Forissier if (alg == TEE_ALG_AES_XTS) 230979170ce0SJerome Forissier goto check_element_none; 231079170ce0SJerome Forissier } 231179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC_MAC)) { 231279170ce0SJerome Forissier if (alg == TEE_ALG_AES_CBC_MAC_NOPAD || 231379170ce0SJerome Forissier alg == TEE_ALG_AES_CBC_MAC_PKCS5) 231479170ce0SJerome Forissier goto check_element_none; 231579170ce0SJerome Forissier } 231679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CMAC)) { 231779170ce0SJerome Forissier if (alg == TEE_ALG_AES_CMAC) 231879170ce0SJerome Forissier goto check_element_none; 231979170ce0SJerome Forissier } 232079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CCM)) { 232179170ce0SJerome Forissier if (alg == TEE_ALG_AES_CCM) 232279170ce0SJerome Forissier goto check_element_none; 232379170ce0SJerome Forissier } 232479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_GCM)) { 232579170ce0SJerome Forissier if (alg == TEE_ALG_AES_GCM) 232679170ce0SJerome Forissier goto check_element_none; 232779170ce0SJerome Forissier } 232879170ce0SJerome Forissier } 232979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DES)) { 233079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) { 233179170ce0SJerome Forissier if (alg == TEE_ALG_DES_ECB_NOPAD || 233279170ce0SJerome Forissier alg == TEE_ALG_DES3_ECB_NOPAD) 233379170ce0SJerome Forissier goto check_element_none; 233479170ce0SJerome Forissier } 233579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) { 233679170ce0SJerome Forissier if (alg == TEE_ALG_DES_CBC_NOPAD || 233779170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_NOPAD) 233879170ce0SJerome Forissier goto check_element_none; 233979170ce0SJerome Forissier } 234079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC_MAC)) { 234179170ce0SJerome Forissier if (alg == TEE_ALG_DES_CBC_MAC_NOPAD || 234279170ce0SJerome Forissier alg == TEE_ALG_DES_CBC_MAC_PKCS5 || 234379170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_MAC_NOPAD || 234479170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_MAC_PKCS5) 234579170ce0SJerome Forissier goto check_element_none; 234679170ce0SJerome Forissier } 234779170ce0SJerome Forissier } 234879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) { 234979170ce0SJerome Forissier if (alg == TEE_ALG_MD5) 235079170ce0SJerome Forissier goto check_element_none; 235179170ce0SJerome Forissier } 235279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 235379170ce0SJerome Forissier if (alg == TEE_ALG_SHA1) 235479170ce0SJerome Forissier goto check_element_none; 235579170ce0SJerome Forissier } 235679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 235779170ce0SJerome Forissier if (alg == TEE_ALG_SHA224) 235879170ce0SJerome Forissier goto check_element_none; 235979170ce0SJerome Forissier } 236079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 236179170ce0SJerome Forissier if (alg == TEE_ALG_SHA256) 236279170ce0SJerome Forissier goto check_element_none; 236379170ce0SJerome Forissier } 236479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) { 236579170ce0SJerome Forissier if (alg == TEE_ALG_SHA384) 236679170ce0SJerome Forissier goto check_element_none; 236779170ce0SJerome Forissier } 236879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) { 236979170ce0SJerome Forissier if (alg == TEE_ALG_SHA512) 237079170ce0SJerome Forissier goto check_element_none; 237179170ce0SJerome Forissier } 2372*260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_224)) { 2373*260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_224) 2374*260b4028SJens Wiklander goto check_element_none; 2375*260b4028SJens Wiklander } 2376*260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_256)) { 2377*260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_256) 2378*260b4028SJens Wiklander goto check_element_none; 2379*260b4028SJens Wiklander } 2380*260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_384)) { 2381*260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_384) 2382*260b4028SJens Wiklander goto check_element_none; 2383*260b4028SJens Wiklander } 2384*260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_512)) { 2385*260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_512) 2386*260b4028SJens Wiklander goto check_element_none; 2387*260b4028SJens Wiklander } 238879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5) && IS_ENABLED(CFG_CRYPTO_SHA1)) { 238979170ce0SJerome Forissier if (alg == TEE_ALG_MD5SHA1) 239079170ce0SJerome Forissier goto check_element_none; 239179170ce0SJerome Forissier } 239279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_HMAC)) { 239379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) { 239479170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_MD5) 239579170ce0SJerome Forissier goto check_element_none; 239679170ce0SJerome Forissier } 239779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 239879170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA1) 239979170ce0SJerome Forissier goto check_element_none; 240079170ce0SJerome Forissier } 240179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 240279170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA224) 240379170ce0SJerome Forissier goto check_element_none; 240479170ce0SJerome Forissier } 240579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 240679170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA256) 240779170ce0SJerome Forissier goto check_element_none; 240879170ce0SJerome Forissier } 240979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) { 241079170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA384) 241179170ce0SJerome Forissier goto check_element_none; 241279170ce0SJerome Forissier } 241379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) { 241479170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA512) 241579170ce0SJerome Forissier goto check_element_none; 241679170ce0SJerome Forissier } 2417*260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_224)) { 2418*260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_224) 2419*260b4028SJens Wiklander goto check_element_none; 2420*260b4028SJens Wiklander } 2421*260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_256)) { 2422*260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_256) 2423*260b4028SJens Wiklander goto check_element_none; 2424*260b4028SJens Wiklander } 2425*260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_384)) { 2426*260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_384) 2427*260b4028SJens Wiklander goto check_element_none; 2428*260b4028SJens Wiklander } 2429*260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_512)) { 2430*260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_512) 2431*260b4028SJens Wiklander goto check_element_none; 2432*260b4028SJens Wiklander } 243379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM3)) { 243479170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SM3) 243579170ce0SJerome Forissier goto check_element_none; 243679170ce0SJerome Forissier } 243779170ce0SJerome Forissier } 243879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM3)) { 243979170ce0SJerome Forissier if (alg == TEE_ALG_SM3) 244079170ce0SJerome Forissier goto check_element_none; 244179170ce0SJerome Forissier } 244279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM4)) { 244379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) { 244479170ce0SJerome Forissier if (alg == TEE_ALG_SM4_ECB_NOPAD) 244579170ce0SJerome Forissier goto check_element_none; 244679170ce0SJerome Forissier } 244779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) { 244879170ce0SJerome Forissier if (alg == TEE_ALG_SM4_CBC_NOPAD) 244979170ce0SJerome Forissier goto check_element_none; 245079170ce0SJerome Forissier } 245179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTR)) { 245279170ce0SJerome Forissier if (alg == TEE_ALG_SM4_CTR) 245379170ce0SJerome Forissier goto check_element_none; 245479170ce0SJerome Forissier } 2455696f56acSPingan Xie if (IS_ENABLED(CFG_CRYPTO_XTS)) { 2456696f56acSPingan Xie if (alg == TEE_ALG_SM4_XTS) 2457696f56acSPingan Xie goto check_element_none; 2458696f56acSPingan Xie } 245979170ce0SJerome Forissier } 246079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_RSA)) { 246179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) { 246279170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5) 246379170ce0SJerome Forissier goto check_element_none; 246479170ce0SJerome Forissier } 246579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 246679170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA1 || 246779170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1 || 246879170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1) 246979170ce0SJerome Forissier goto check_element_none; 247079170ce0SJerome Forissier } 247179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5) && IS_ENABLED(CFG_CRYPTO_SHA1)) { 247279170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5SHA1) 247379170ce0SJerome Forissier goto check_element_none; 247479170ce0SJerome Forissier } 247579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 247679170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA224 || 247779170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224 || 247879170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224) 247979170ce0SJerome Forissier goto check_element_none; 248079170ce0SJerome Forissier } 248179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 248279170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA256 || 248379170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 || 248479170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256) 248579170ce0SJerome Forissier goto check_element_none; 248679170ce0SJerome Forissier } 248779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) { 248879170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA384 || 248979170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384 || 249079170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384) 249179170ce0SJerome Forissier goto check_element_none; 249279170ce0SJerome Forissier } 249379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) { 249479170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA512 || 249579170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512 || 249679170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512) 249779170ce0SJerome Forissier goto check_element_none; 249879170ce0SJerome Forissier } 249979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_RSASSA_NA1)) { 250079170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5) 250179170ce0SJerome Forissier goto check_element_none; 250279170ce0SJerome Forissier } 250379170ce0SJerome Forissier if (alg == TEE_ALG_RSA_NOPAD) 250479170ce0SJerome Forissier goto check_element_none; 250579170ce0SJerome Forissier } 250679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DSA)) { 250779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 250879170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA1) 250979170ce0SJerome Forissier goto check_element_none; 251079170ce0SJerome Forissier } 251179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 251279170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA224) 251379170ce0SJerome Forissier goto check_element_none; 251479170ce0SJerome Forissier } 251579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 251679170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA256) 251779170ce0SJerome Forissier goto check_element_none; 251879170ce0SJerome Forissier } 251979170ce0SJerome Forissier } 252079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DH)) { 252179170ce0SJerome Forissier if (alg == TEE_ALG_DH_DERIVE_SHARED_SECRET) 252279170ce0SJerome Forissier goto check_element_none; 252379170ce0SJerome Forissier } 252479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECC)) { 2525fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P192 || 2526fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P192 || 2527fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2528fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA1) && 252979170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P192) 253079170ce0SJerome Forissier return TEE_SUCCESS; 2531fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P224 || 2532fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P224 || 2533fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2534fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA224) && 253579170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P224) 253679170ce0SJerome Forissier return TEE_SUCCESS; 2537fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P256 || 2538fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P256 || 2539fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2540fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA256) && 254179170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P256) 254279170ce0SJerome Forissier return TEE_SUCCESS; 2543fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P384 || 2544fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P384 || 2545fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2546fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA384) && 254779170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P384) 254879170ce0SJerome Forissier return TEE_SUCCESS; 2549fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P521 || 2550fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P521 || 2551fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2552fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA512) && 255379170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P521) 255479170ce0SJerome Forissier return TEE_SUCCESS; 255579170ce0SJerome Forissier } 255679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_DSA)) { 255779170ce0SJerome Forissier if (alg == TEE_ALG_SM2_DSA_SM3 && element == TEE_ECC_CURVE_SM2) 255879170ce0SJerome Forissier return TEE_SUCCESS; 255979170ce0SJerome Forissier } 256079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_KEP)) { 256179170ce0SJerome Forissier if (alg == TEE_ALG_SM2_KEP && element == TEE_ECC_CURVE_SM2) 256279170ce0SJerome Forissier return TEE_SUCCESS; 256379170ce0SJerome Forissier } 256479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_PKE)) { 256579170ce0SJerome Forissier if (alg == TEE_ALG_SM2_PKE && element == TEE_ECC_CURVE_SM2) 256679170ce0SJerome Forissier return TEE_SUCCESS; 256779170ce0SJerome Forissier } 25683f61056dSSohaib ul Hassan if (IS_ENABLED(CFG_CRYPTO_X25519)) { 25693f61056dSSohaib ul Hassan if (alg == TEE_ALG_X25519 && element == TEE_ECC_CURVE_25519) 25703f61056dSSohaib ul Hassan return TEE_SUCCESS; 25713f61056dSSohaib ul Hassan } 2572e1f9cee7SSergiy Kibrik if (IS_ENABLED(CFG_CRYPTO_ED25519)) { 2573e1f9cee7SSergiy Kibrik if (alg == TEE_ALG_ED25519 && element == TEE_ECC_CURVE_25519) 2574e1f9cee7SSergiy Kibrik return TEE_SUCCESS; 2575e1f9cee7SSergiy Kibrik } 257679170ce0SJerome Forissier 257779170ce0SJerome Forissier return TEE_ERROR_NOT_SUPPORTED; 257879170ce0SJerome Forissier check_element_none: 257979170ce0SJerome Forissier if (element == TEE_CRYPTO_ELEMENT_NONE) 258079170ce0SJerome Forissier return TEE_SUCCESS; 258179170ce0SJerome Forissier return TEE_ERROR_NOT_SUPPORTED; 258279170ce0SJerome Forissier } 2583