11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause 2b0104773SPascal Brand /* 3b0104773SPascal Brand * Copyright (c) 2014, STMicroelectronics International N.V. 4eee637e7SAlexander Zakharov * Copyright (c) 2021, SumUp Services GmbH 5b0104773SPascal Brand */ 679170ce0SJerome Forissier #include <config.h> 7b0104773SPascal Brand #include <stdlib.h> 8b0104773SPascal Brand #include <string.h> 9b796ebf3SJerome Forissier #include <string_ext.h> 10b0104773SPascal Brand #include <tee_api.h> 118854d3c6SJerome Forissier #include <tee_api_defines_extensions.h> 12b0104773SPascal Brand #include <tee_internal_api_extensions.h> 13b0104773SPascal Brand #include <utee_syscalls.h> 14b0104773SPascal Brand #include <utee_defines.h> 15fc26c92aSJens Wiklander #include <util.h> 16e86f1266SJens Wiklander #include "tee_api_private.h" 17b0104773SPascal Brand 18b0104773SPascal Brand struct __TEE_OperationHandle { 19b0104773SPascal Brand TEE_OperationInfo info; 20b0104773SPascal Brand TEE_ObjectHandle key1; 21b0104773SPascal Brand TEE_ObjectHandle key2; 22642a1607SCedric Chaumont uint32_t operationState;/* Operation state : INITIAL or ACTIVE */ 23b0104773SPascal Brand uint8_t *buffer; /* buffer to collect complete blocks */ 24b0104773SPascal Brand bool buffer_two_blocks; /* True if two blocks need to be buffered */ 25b0104773SPascal Brand size_t block_size; /* Block size of cipher */ 26b0104773SPascal Brand size_t buffer_offs; /* Offset in buffer */ 27b0104773SPascal Brand uint32_t state; /* Handle to state in TEE Core */ 28b0104773SPascal Brand }; 29b0104773SPascal Brand 30b0104773SPascal Brand /* Cryptographic Operations API - Generic Operation Functions */ 31b0104773SPascal Brand 32b0104773SPascal Brand TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation, 33b0104773SPascal Brand uint32_t algorithm, uint32_t mode, 34b0104773SPascal Brand uint32_t maxKeySize) 35b0104773SPascal Brand { 36b0104773SPascal Brand TEE_Result res; 37b0104773SPascal Brand TEE_OperationHandle op = TEE_HANDLE_NULL; 38b0104773SPascal Brand uint32_t handle_state = 0; 39b0104773SPascal Brand size_t block_size = 1; 40b0104773SPascal Brand uint32_t req_key_usage; 41b0104773SPascal Brand bool with_private_key = false; 42b0104773SPascal Brand bool buffer_two_blocks = false; 43b0104773SPascal Brand 449b52c538SCedric Chaumont if (!operation) 45b0104773SPascal Brand TEE_Panic(0); 46b0104773SPascal Brand 47696f56acSPingan Xie if (algorithm == TEE_ALG_AES_XTS || algorithm == TEE_ALG_SM2_KEP || 48696f56acSPingan Xie algorithm == TEE_ALG_SM4_XTS) 49b0104773SPascal Brand handle_state = TEE_HANDLE_FLAG_EXPECT_TWO_KEYS; 50b0104773SPascal Brand 51218d9055SCedric Chaumont /* Check algorithm max key size */ 52218d9055SCedric Chaumont switch (algorithm) { 53218d9055SCedric Chaumont case TEE_ALG_DSA_SHA1: 54218d9055SCedric Chaumont if (maxKeySize < 512) 55218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 56218d9055SCedric Chaumont if (maxKeySize > 1024) 57218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 58218d9055SCedric Chaumont if (maxKeySize % 64 != 0) 59218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 60218d9055SCedric Chaumont break; 61218d9055SCedric Chaumont 62218d9055SCedric Chaumont case TEE_ALG_DSA_SHA224: 63218d9055SCedric Chaumont if (maxKeySize != 2048) 64218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 65218d9055SCedric Chaumont break; 66218d9055SCedric Chaumont 67218d9055SCedric Chaumont case TEE_ALG_DSA_SHA256: 68218d9055SCedric Chaumont if (maxKeySize != 2048 && maxKeySize != 3072) 69218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 70218d9055SCedric Chaumont break; 71218d9055SCedric Chaumont 72fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA1: 73fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P192: 74fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P192: 751220586eSCedric Chaumont if (maxKeySize != 192) 761220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 771220586eSCedric Chaumont break; 781220586eSCedric Chaumont 79fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA224: 80fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P224: 81fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P224: 821220586eSCedric Chaumont if (maxKeySize != 224) 831220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 841220586eSCedric Chaumont break; 851220586eSCedric Chaumont 86fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA256: 87fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P256: 88fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P256: 8991fc6bd8SJerome Forissier case TEE_ALG_SM2_PKE: 900f151943SJerome Forissier case TEE_ALG_SM2_DSA_SM3: 911220586eSCedric Chaumont if (maxKeySize != 256) 921220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 931220586eSCedric Chaumont break; 941220586eSCedric Chaumont 955b385b3fSJerome Forissier case TEE_ALG_SM2_KEP: 965b385b3fSJerome Forissier /* Two 256-bit keys */ 975b385b3fSJerome Forissier if (maxKeySize != 512) 985b385b3fSJerome Forissier return TEE_ERROR_NOT_SUPPORTED; 995b385b3fSJerome Forissier break; 1005b385b3fSJerome Forissier 101fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA384: 102fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P384: 103fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P384: 1041220586eSCedric Chaumont if (maxKeySize != 384) 1051220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 1061220586eSCedric Chaumont break; 1071220586eSCedric Chaumont 108fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA512: 109fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P521: 110fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P521: 1111220586eSCedric Chaumont if (maxKeySize != 521) 1121220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 1131220586eSCedric Chaumont break; 114fe2fd3ffSJens Wiklander 115fe2fd3ffSJens Wiklander case TEE_ALG_ECDH_DERIVE_SHARED_SECRET: 116fe2fd3ffSJens Wiklander if (maxKeySize > 521) 117fe2fd3ffSJens Wiklander return TEE_ERROR_NOT_SUPPORTED; 118fe2fd3ffSJens Wiklander break; 119fe2fd3ffSJens Wiklander 120e1f9cee7SSergiy Kibrik case TEE_ALG_ED25519: 1213f61056dSSohaib ul Hassan case TEE_ALG_X25519: 1223f61056dSSohaib ul Hassan if (maxKeySize != 256) 1233f61056dSSohaib ul Hassan return TEE_ERROR_NOT_SUPPORTED; 1243f61056dSSohaib ul Hassan break; 125218d9055SCedric Chaumont default: 126218d9055SCedric Chaumont break; 127218d9055SCedric Chaumont } 128218d9055SCedric Chaumont 129cf5c060cSJens Wiklander /* Check algorithm mode (and maxKeySize for digests) */ 130b0104773SPascal Brand switch (algorithm) { 131b0104773SPascal Brand case TEE_ALG_AES_CTS: 132b0104773SPascal Brand case TEE_ALG_AES_XTS: 133696f56acSPingan Xie case TEE_ALG_SM4_XTS: 134b0104773SPascal Brand buffer_two_blocks = true; 135919a5a68SJerome Forissier fallthrough; 1364bd53c54SJerome Forissier case TEE_ALG_AES_ECB_NOPAD: 137b0104773SPascal Brand case TEE_ALG_AES_CBC_NOPAD: 138b0104773SPascal Brand case TEE_ALG_AES_CCM: 139b0104773SPascal Brand case TEE_ALG_DES_ECB_NOPAD: 140b0104773SPascal Brand case TEE_ALG_DES_CBC_NOPAD: 141b0104773SPascal Brand case TEE_ALG_DES3_ECB_NOPAD: 142b0104773SPascal Brand case TEE_ALG_DES3_CBC_NOPAD: 143ade6f848SJerome Forissier case TEE_ALG_SM4_ECB_NOPAD: 144ade6f848SJerome Forissier case TEE_ALG_SM4_CBC_NOPAD: 145ade6f848SJerome Forissier case TEE_ALG_SM4_CTR: 146b0104773SPascal Brand if (TEE_ALG_GET_MAIN_ALG(algorithm) == TEE_MAIN_ALGO_AES) 147b0104773SPascal Brand block_size = TEE_AES_BLOCK_SIZE; 148ade6f848SJerome Forissier else if (TEE_ALG_GET_MAIN_ALG(algorithm) == TEE_MAIN_ALGO_SM4) 149ade6f848SJerome Forissier block_size = TEE_SM4_BLOCK_SIZE; 150b0104773SPascal Brand else 151b0104773SPascal Brand block_size = TEE_DES_BLOCK_SIZE; 152919a5a68SJerome Forissier fallthrough; 15357aabac5SBogdan Liulko case TEE_ALG_AES_CTR: 154afc0c182SBogdan Liulko case TEE_ALG_AES_GCM: 155b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) 156b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT; 157b0104773SPascal Brand else if (mode == TEE_MODE_DECRYPT) 158b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT; 159b0104773SPascal Brand else 160b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 161b0104773SPascal Brand break; 162b0104773SPascal Brand 1636a2e0a9fSGabor Szekely #if defined(CFG_CRYPTO_RSASSA_NA1) 1646a2e0a9fSGabor Szekely case TEE_ALG_RSASSA_PKCS1_V1_5: 1656a2e0a9fSGabor Szekely #endif 166b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_MD5: 167b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1: 168b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224: 169b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256: 170b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384: 171b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512: 172b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: 173b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: 174b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: 175b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: 176b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: 177b0104773SPascal Brand case TEE_ALG_DSA_SHA1: 178218d9055SCedric Chaumont case TEE_ALG_DSA_SHA224: 179218d9055SCedric Chaumont case TEE_ALG_DSA_SHA256: 180fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA1: 181fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA224: 182fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA256: 183fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA384: 184fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA512: 185fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P192: 186fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P224: 187fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P256: 188fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P384: 189fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P521: 1900f151943SJerome Forissier case TEE_ALG_SM2_DSA_SM3: 191e1f9cee7SSergiy Kibrik case TEE_ALG_ED25519: 192b0104773SPascal Brand if (mode == TEE_MODE_SIGN) { 193b0104773SPascal Brand with_private_key = true; 194b0104773SPascal Brand req_key_usage = TEE_USAGE_SIGN; 195b0104773SPascal Brand } else if (mode == TEE_MODE_VERIFY) { 196b0104773SPascal Brand req_key_usage = TEE_USAGE_VERIFY; 197b0104773SPascal Brand } else { 198b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 199b0104773SPascal Brand } 200b0104773SPascal Brand break; 201b0104773SPascal Brand 202b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_V1_5: 203b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1: 204b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224: 205b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256: 206b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384: 207b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512: 20891fc6bd8SJerome Forissier case TEE_ALG_SM2_PKE: 209b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) { 210b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT; 211b0104773SPascal Brand } else if (mode == TEE_MODE_DECRYPT) { 212b0104773SPascal Brand with_private_key = true; 213b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT; 214b0104773SPascal Brand } else { 215b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 216b0104773SPascal Brand } 217b0104773SPascal Brand break; 218b0104773SPascal Brand 219b0104773SPascal Brand case TEE_ALG_RSA_NOPAD: 220b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) { 221b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT | TEE_USAGE_VERIFY; 222b0104773SPascal Brand } else if (mode == TEE_MODE_DECRYPT) { 223b0104773SPascal Brand with_private_key = true; 224b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT | TEE_USAGE_SIGN; 225b0104773SPascal Brand } else { 226b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 227b0104773SPascal Brand } 228b0104773SPascal Brand break; 229b0104773SPascal Brand 230b0104773SPascal Brand case TEE_ALG_DH_DERIVE_SHARED_SECRET: 231fe2fd3ffSJens Wiklander case TEE_ALG_ECDH_DERIVE_SHARED_SECRET: 232fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P192: 233fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P224: 234fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P256: 235fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P384: 236fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P521: 237cdb198a7SJerome Forissier case TEE_ALG_HKDF_MD5_DERIVE_KEY: 238cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA1_DERIVE_KEY: 239cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA224_DERIVE_KEY: 240cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA256_DERIVE_KEY: 241cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA384_DERIVE_KEY: 242cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA512_DERIVE_KEY: 2438854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA1_DERIVE_KEY: 2448854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA224_DERIVE_KEY: 2458854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA256_DERIVE_KEY: 2468854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA384_DERIVE_KEY: 2478854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA512_DERIVE_KEY: 2480f2293b7SJerome Forissier case TEE_ALG_PBKDF2_HMAC_SHA1_DERIVE_KEY: 2495b385b3fSJerome Forissier case TEE_ALG_SM2_KEP: 2503f61056dSSohaib ul Hassan case TEE_ALG_X25519: 251b0104773SPascal Brand if (mode != TEE_MODE_DERIVE) 252b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 253b0104773SPascal Brand with_private_key = true; 254b0104773SPascal Brand req_key_usage = TEE_USAGE_DERIVE; 255b0104773SPascal Brand break; 256b0104773SPascal Brand 257b0104773SPascal Brand case TEE_ALG_MD5: 258b0104773SPascal Brand case TEE_ALG_SHA1: 259b0104773SPascal Brand case TEE_ALG_SHA224: 260b0104773SPascal Brand case TEE_ALG_SHA256: 261b0104773SPascal Brand case TEE_ALG_SHA384: 262b0104773SPascal Brand case TEE_ALG_SHA512: 26347645577SJerome Forissier case TEE_ALG_SM3: 264b0104773SPascal Brand if (mode != TEE_MODE_DIGEST) 265b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 266cf5c060cSJens Wiklander if (maxKeySize) 267cf5c060cSJens Wiklander return TEE_ERROR_NOT_SUPPORTED; 26805304565SCedric Chaumont /* v1.1: flags always set for digest operations */ 269b0104773SPascal Brand handle_state |= TEE_HANDLE_FLAG_KEY_SET; 270b0104773SPascal Brand req_key_usage = 0; 271b0104773SPascal Brand break; 272b0104773SPascal Brand 273b0104773SPascal Brand case TEE_ALG_DES_CBC_MAC_NOPAD: 274b0104773SPascal Brand case TEE_ALG_AES_CBC_MAC_NOPAD: 275b0104773SPascal Brand case TEE_ALG_AES_CBC_MAC_PKCS5: 276b0104773SPascal Brand case TEE_ALG_AES_CMAC: 277b0104773SPascal Brand case TEE_ALG_DES_CBC_MAC_PKCS5: 278b0104773SPascal Brand case TEE_ALG_DES3_CBC_MAC_NOPAD: 279b0104773SPascal Brand case TEE_ALG_DES3_CBC_MAC_PKCS5: 280eee637e7SAlexander Zakharov case TEE_ALG_DES3_CMAC: 281b0104773SPascal Brand case TEE_ALG_HMAC_MD5: 282b0104773SPascal Brand case TEE_ALG_HMAC_SHA1: 283b0104773SPascal Brand case TEE_ALG_HMAC_SHA224: 284b0104773SPascal Brand case TEE_ALG_HMAC_SHA256: 285b0104773SPascal Brand case TEE_ALG_HMAC_SHA384: 286b0104773SPascal Brand case TEE_ALG_HMAC_SHA512: 28747645577SJerome Forissier case TEE_ALG_HMAC_SM3: 288b0104773SPascal Brand if (mode != TEE_MODE_MAC) 289b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 290b0104773SPascal Brand req_key_usage = TEE_USAGE_MAC; 291b0104773SPascal Brand break; 292b0104773SPascal Brand 293b0104773SPascal Brand default: 294b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 295b0104773SPascal Brand } 296b0104773SPascal Brand 297b66f219bSJens Wiklander op = TEE_Malloc(sizeof(*op), TEE_MALLOC_FILL_ZERO); 2989b52c538SCedric Chaumont if (!op) 299b0104773SPascal Brand return TEE_ERROR_OUT_OF_MEMORY; 300b0104773SPascal Brand 301b0104773SPascal Brand op->info.algorithm = algorithm; 302b0104773SPascal Brand op->info.operationClass = TEE_ALG_GET_CLASS(algorithm); 3036a2e0a9fSGabor Szekely #ifdef CFG_CRYPTO_RSASSA_NA1 3046a2e0a9fSGabor Szekely if (algorithm == TEE_ALG_RSASSA_PKCS1_V1_5) 3056a2e0a9fSGabor Szekely op->info.operationClass = TEE_OPERATION_ASYMMETRIC_SIGNATURE; 3066a2e0a9fSGabor Szekely #endif 307b0104773SPascal Brand op->info.mode = mode; 3082e5e6460SAlbert Schwarzkopf op->info.digestLength = TEE_ALG_GET_DIGEST_SIZE(algorithm); 309b0104773SPascal Brand op->info.maxKeySize = maxKeySize; 310b0104773SPascal Brand op->info.requiredKeyUsage = req_key_usage; 311b0104773SPascal Brand op->info.handleState = handle_state; 312b0104773SPascal Brand 313b0104773SPascal Brand if (block_size > 1) { 314b0104773SPascal Brand size_t buffer_size = block_size; 315b0104773SPascal Brand 316b0104773SPascal Brand if (buffer_two_blocks) 317b0104773SPascal Brand buffer_size *= 2; 318b0104773SPascal Brand 3199b52c538SCedric Chaumont op->buffer = TEE_Malloc(buffer_size, 3209b52c538SCedric Chaumont TEE_USER_MEM_HINT_NO_FILL_ZERO); 321b0104773SPascal Brand if (op->buffer == NULL) { 322b0104773SPascal Brand res = TEE_ERROR_OUT_OF_MEMORY; 323b66f219bSJens Wiklander goto out; 324b0104773SPascal Brand } 325b0104773SPascal Brand } 326b0104773SPascal Brand op->block_size = block_size; 327b0104773SPascal Brand op->buffer_two_blocks = buffer_two_blocks; 328b0104773SPascal Brand 329b0104773SPascal Brand if (TEE_ALG_GET_CLASS(algorithm) != TEE_OPERATION_DIGEST) { 330b0104773SPascal Brand uint32_t mks = maxKeySize; 331b0104773SPascal Brand TEE_ObjectType key_type = TEE_ALG_GET_KEY_TYPE(algorithm, 332b0104773SPascal Brand with_private_key); 333b0104773SPascal Brand 334b0104773SPascal Brand /* 335b0104773SPascal Brand * If two keys are expected the max key size is the sum of 336b0104773SPascal Brand * the size of both keys. 337b0104773SPascal Brand */ 338b0104773SPascal Brand if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) 339b0104773SPascal Brand mks /= 2; 340b0104773SPascal Brand 341b0104773SPascal Brand res = TEE_AllocateTransientObject(key_type, mks, &op->key1); 342b0104773SPascal Brand if (res != TEE_SUCCESS) 343b66f219bSJens Wiklander goto out; 344b0104773SPascal Brand 34505304565SCedric Chaumont if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) { 3469b52c538SCedric Chaumont res = TEE_AllocateTransientObject(key_type, mks, 347b0104773SPascal Brand &op->key2); 348b0104773SPascal Brand if (res != TEE_SUCCESS) 349b66f219bSJens Wiklander goto out; 350b0104773SPascal Brand } 351b0104773SPascal Brand } 352b0104773SPascal Brand 3532c028fdeSJerome Forissier res = _utee_cryp_state_alloc(algorithm, mode, (unsigned long)op->key1, 354e86f1266SJens Wiklander (unsigned long)op->key2, &op->state); 355b66f219bSJens Wiklander if (res != TEE_SUCCESS) 356b66f219bSJens Wiklander goto out; 357b0104773SPascal Brand 35805304565SCedric Chaumont /* 35905304565SCedric Chaumont * Initialize digest operations 36005304565SCedric Chaumont * Other multi-stage operations initialized w/ TEE_xxxInit functions 36105304565SCedric Chaumont * Non-applicable on asymmetric operations 36205304565SCedric Chaumont */ 36305304565SCedric Chaumont if (TEE_ALG_GET_CLASS(algorithm) == TEE_OPERATION_DIGEST) { 3642c028fdeSJerome Forissier res = _utee_hash_init(op->state, NULL, 0); 36505304565SCedric Chaumont if (res != TEE_SUCCESS) 366b66f219bSJens Wiklander goto out; 36705304565SCedric Chaumont /* v1.1: flags always set for digest operations */ 36805304565SCedric Chaumont op->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 36905304565SCedric Chaumont } 37005304565SCedric Chaumont 371642a1607SCedric Chaumont op->operationState = TEE_OPERATION_STATE_INITIAL; 372642a1607SCedric Chaumont 373b0104773SPascal Brand *operation = op; 374b0104773SPascal Brand 375b66f219bSJens Wiklander out: 376b66f219bSJens Wiklander if (res != TEE_SUCCESS) { 377b66f219bSJens Wiklander if (res != TEE_ERROR_OUT_OF_MEMORY && 3789b52c538SCedric Chaumont res != TEE_ERROR_NOT_SUPPORTED) 379b36311adSJerome Forissier TEE_Panic(res); 380b66f219bSJens Wiklander if (op) { 381b66f219bSJens Wiklander if (op->state) { 382b66f219bSJens Wiklander TEE_FreeOperation(op); 383b66f219bSJens Wiklander } else { 384b66f219bSJens Wiklander TEE_Free(op->buffer); 385b66f219bSJens Wiklander TEE_FreeTransientObject(op->key1); 386b66f219bSJens Wiklander TEE_FreeTransientObject(op->key2); 387b66f219bSJens Wiklander TEE_Free(op); 388b66f219bSJens Wiklander } 389b66f219bSJens Wiklander } 390b66f219bSJens Wiklander } 391b66f219bSJens Wiklander 392b0104773SPascal Brand return res; 393b0104773SPascal Brand } 394b0104773SPascal Brand 395b0104773SPascal Brand void TEE_FreeOperation(TEE_OperationHandle operation) 396b0104773SPascal Brand { 397e889e80bSCedric Chaumont TEE_Result res; 398e889e80bSCedric Chaumont 399e889e80bSCedric Chaumont if (operation == TEE_HANDLE_NULL) 400e889e80bSCedric Chaumont TEE_Panic(0); 401e889e80bSCedric Chaumont 402b0104773SPascal Brand /* 403b0104773SPascal Brand * Note that keys should not be freed here, since they are 404b0104773SPascal Brand * claimed by the operation they will be freed by 405b0104773SPascal Brand * utee_cryp_state_free(). 406b0104773SPascal Brand */ 4072c028fdeSJerome Forissier res = _utee_cryp_state_free(operation->state); 408e889e80bSCedric Chaumont if (res != TEE_SUCCESS) 409b36311adSJerome Forissier TEE_Panic(res); 410e889e80bSCedric Chaumont 411b0104773SPascal Brand TEE_Free(operation->buffer); 412b0104773SPascal Brand TEE_Free(operation); 413b0104773SPascal Brand } 414b0104773SPascal Brand 415b0104773SPascal Brand void TEE_GetOperationInfo(TEE_OperationHandle operation, 416b0104773SPascal Brand TEE_OperationInfo *operationInfo) 417b0104773SPascal Brand { 418b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 419b0104773SPascal Brand TEE_Panic(0); 420b0104773SPascal Brand 4216915bbbbSJens Wiklander __utee_check_out_annotation(operationInfo, sizeof(*operationInfo)); 422b0104773SPascal Brand 423b0104773SPascal Brand *operationInfo = operation->info; 424bac3a8a7SJens Wiklander if (operationInfo->handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) { 425bac3a8a7SJens Wiklander operationInfo->keySize = 0; 426bac3a8a7SJens Wiklander operationInfo->requiredKeyUsage = 0; 427bac3a8a7SJens Wiklander } 428b0104773SPascal Brand } 429b0104773SPascal Brand 430ee2f75afSJens Wiklander TEE_Result TEE_GetOperationInfoMultiple(TEE_OperationHandle op, 431ee2f75afSJens Wiklander TEE_OperationInfoMultiple *op_info, 432cb98b7b2SJens Wiklander size_t *size) 43305304565SCedric Chaumont { 43405304565SCedric Chaumont TEE_Result res = TEE_SUCCESS; 435ee2f75afSJens Wiklander TEE_ObjectInfo kinfo = { }; 436ee2f75afSJens Wiklander size_t max_key_count = 0; 437ee2f75afSJens Wiklander bool two_keys = false; 43805304565SCedric Chaumont 439ee2f75afSJens Wiklander if (op == TEE_HANDLE_NULL) { 44005304565SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 44105304565SCedric Chaumont goto out; 44205304565SCedric Chaumont } 44305304565SCedric Chaumont 444cb98b7b2SJens Wiklander __utee_check_outbuf_annotation(op_info, size); 44505304565SCedric Chaumont 446ee2f75afSJens Wiklander if (*size < sizeof(*op_info)) { 447ee2f75afSJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 448ee2f75afSJens Wiklander goto out; 449ee2f75afSJens Wiklander } 450ee2f75afSJens Wiklander max_key_count = (*size - sizeof(*op_info)) / 45105304565SCedric Chaumont sizeof(TEE_OperationInfoKey); 45205304565SCedric Chaumont 453ee2f75afSJens Wiklander TEE_MemFill(op_info, 0, *size); 45405304565SCedric Chaumont 45505304565SCedric Chaumont /* Two keys flag (TEE_ALG_AES_XTS only) */ 456ee2f75afSJens Wiklander two_keys = op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS; 457ee2f75afSJens Wiklander 458ee2f75afSJens Wiklander if (op->info.mode == TEE_MODE_DIGEST) { 459ee2f75afSJens Wiklander op_info->numberOfKeys = 0; 460ee2f75afSJens Wiklander } else if (!two_keys) { 461ee2f75afSJens Wiklander if (max_key_count < 1) { 46205304565SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 46305304565SCedric Chaumont goto out; 46405304565SCedric Chaumont } 46505304565SCedric Chaumont 466ee2f75afSJens Wiklander res = TEE_GetObjectInfo1(op->key1, &kinfo); 467ee2f75afSJens Wiklander /* Key1 is not a valid handle, "can't happen". */ 468ee2f75afSJens Wiklander if (res) 46905304565SCedric Chaumont goto out; 47005304565SCedric Chaumont 471d372a47cSJens Wiklander op_info->keyInformation[0].keySize = kinfo.objectSize; 472ee2f75afSJens Wiklander op_info->keyInformation[0].requiredKeyUsage = 473ee2f75afSJens Wiklander op->info.requiredKeyUsage; 474ee2f75afSJens Wiklander op_info->numberOfKeys = 1; 475ee2f75afSJens Wiklander } else { 476ee2f75afSJens Wiklander if (max_key_count < 2) { 477ee2f75afSJens Wiklander res = TEE_ERROR_SHORT_BUFFER; 47805304565SCedric Chaumont goto out; 47905304565SCedric Chaumont } 48005304565SCedric Chaumont 481ee2f75afSJens Wiklander res = TEE_GetObjectInfo1(op->key1, &kinfo); 482ee2f75afSJens Wiklander /* Key1 is not a valid handle, "can't happen". */ 483ee2f75afSJens Wiklander if (res) 484ee2f75afSJens Wiklander goto out; 485ee2f75afSJens Wiklander 486d372a47cSJens Wiklander op_info->keyInformation[0].keySize = kinfo.objectSize; 487ee2f75afSJens Wiklander op_info->keyInformation[0].requiredKeyUsage = 488ee2f75afSJens Wiklander op->info.requiredKeyUsage; 489ee2f75afSJens Wiklander 490ee2f75afSJens Wiklander res = TEE_GetObjectInfo1(op->key2, &kinfo); 491ee2f75afSJens Wiklander /* Key2 is not a valid handle, "can't happen". */ 492ee2f75afSJens Wiklander if (res) 493ee2f75afSJens Wiklander goto out; 494ee2f75afSJens Wiklander 495d372a47cSJens Wiklander op_info->keyInformation[1].keySize = kinfo.objectSize; 496ee2f75afSJens Wiklander op_info->keyInformation[1].requiredKeyUsage = 497ee2f75afSJens Wiklander op->info.requiredKeyUsage; 498ee2f75afSJens Wiklander 499ee2f75afSJens Wiklander op_info->numberOfKeys = 2; 50005304565SCedric Chaumont } 50105304565SCedric Chaumont 502ee2f75afSJens Wiklander op_info->algorithm = op->info.algorithm; 503ee2f75afSJens Wiklander op_info->operationClass = op->info.operationClass; 504ee2f75afSJens Wiklander op_info->mode = op->info.mode; 505ee2f75afSJens Wiklander op_info->digestLength = op->info.digestLength; 506ee2f75afSJens Wiklander op_info->maxKeySize = op->info.maxKeySize; 507ee2f75afSJens Wiklander op_info->handleState = op->info.handleState; 508ee2f75afSJens Wiklander op_info->operationState = op->operationState; 50905304565SCedric Chaumont 51005304565SCedric Chaumont out: 51105304565SCedric Chaumont if (res != TEE_SUCCESS && 51205304565SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 513b36311adSJerome Forissier TEE_Panic(res); 51405304565SCedric Chaumont 51505304565SCedric Chaumont return res; 51605304565SCedric Chaumont } 51705304565SCedric Chaumont 518cb98b7b2SJens Wiklander TEE_Result 519cb98b7b2SJens Wiklander __GP11_TEE_GetOperationInfoMultiple(TEE_OperationHandle operation, 520cb98b7b2SJens Wiklander TEE_OperationInfoMultiple *info, 521cb98b7b2SJens Wiklander uint32_t *operationSize) 522cb98b7b2SJens Wiklander { 523cb98b7b2SJens Wiklander TEE_Result res = TEE_SUCCESS; 524cb98b7b2SJens Wiklander size_t s = 0; 525cb98b7b2SJens Wiklander 526cb98b7b2SJens Wiklander __utee_check_gp11_outbuf_annotation(info, operationSize); 527cb98b7b2SJens Wiklander s = *operationSize; 528cb98b7b2SJens Wiklander res = TEE_GetOperationInfoMultiple(operation, info, &s); 529cb98b7b2SJens Wiklander *operationSize = s; 530cb98b7b2SJens Wiklander return res; 531cb98b7b2SJens Wiklander } 532cb98b7b2SJens Wiklander 533b0104773SPascal Brand void TEE_ResetOperation(TEE_OperationHandle operation) 534b0104773SPascal Brand { 535b0104773SPascal Brand TEE_Result res; 536b0104773SPascal Brand 537b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 538b0104773SPascal Brand TEE_Panic(0); 539bf80076aSCedric Chaumont 540642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET)) 541bf80076aSCedric Chaumont TEE_Panic(0); 542bf80076aSCedric Chaumont 543642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 544642a1607SCedric Chaumont 545b0104773SPascal Brand if (operation->info.operationClass == TEE_OPERATION_DIGEST) { 5462c028fdeSJerome Forissier res = _utee_hash_init(operation->state, NULL, 0); 547b0104773SPascal Brand if (res != TEE_SUCCESS) 548b0104773SPascal Brand TEE_Panic(res); 54905304565SCedric Chaumont operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 55005304565SCedric Chaumont } else { 551b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 552b0104773SPascal Brand } 55305304565SCedric Chaumont } 554b0104773SPascal Brand 555b0104773SPascal Brand TEE_Result TEE_SetOperationKey(TEE_OperationHandle operation, 556b0104773SPascal Brand TEE_ObjectHandle key) 557b0104773SPascal Brand { 5587583c59eSCedric Chaumont TEE_Result res; 559b0104773SPascal Brand uint32_t key_size = 0; 560b0104773SPascal Brand TEE_ObjectInfo key_info; 561b0104773SPascal Brand 562a57c1e2eSCedric Chaumont if (operation == TEE_HANDLE_NULL) { 563a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 564a57c1e2eSCedric Chaumont goto out; 565a57c1e2eSCedric Chaumont } 566a57c1e2eSCedric Chaumont 567642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) { 568642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 569642a1607SCedric Chaumont goto out; 570642a1607SCedric Chaumont } 571642a1607SCedric Chaumont 572a57c1e2eSCedric Chaumont if (key == TEE_HANDLE_NULL) { 573a57c1e2eSCedric Chaumont /* Operation key cleared */ 574a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key1); 5756c4ea258SJens Wiklander operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 5766c4ea258SJens Wiklander return TEE_SUCCESS; 577a57c1e2eSCedric Chaumont } 578a57c1e2eSCedric Chaumont 579a57c1e2eSCedric Chaumont /* No key for digest operation */ 580a57c1e2eSCedric Chaumont if (operation->info.operationClass == TEE_OPERATION_DIGEST) { 581a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 582a57c1e2eSCedric Chaumont goto out; 583a57c1e2eSCedric Chaumont } 584a57c1e2eSCedric Chaumont 585a57c1e2eSCedric Chaumont /* Two keys flag not expected (TEE_ALG_AES_XTS excluded) */ 586a57c1e2eSCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) != 587a57c1e2eSCedric Chaumont 0) { 588a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 589a57c1e2eSCedric Chaumont goto out; 590a57c1e2eSCedric Chaumont } 591a57c1e2eSCedric Chaumont 5927583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key, &key_info); 593a57c1e2eSCedric Chaumont /* Key is not a valid handle */ 5947583c59eSCedric Chaumont if (res != TEE_SUCCESS) 595a57c1e2eSCedric Chaumont goto out; 5967583c59eSCedric Chaumont 597b0104773SPascal Brand /* Supplied key has to meet required usage */ 598b0104773SPascal Brand if ((key_info.objectUsage & operation->info.requiredKeyUsage) != 599b0104773SPascal Brand operation->info.requiredKeyUsage) { 600a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 601a57c1e2eSCedric Chaumont goto out; 602b0104773SPascal Brand } 603b0104773SPascal Brand 604d372a47cSJens Wiklander if (operation->info.maxKeySize < key_info.objectSize) { 605a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 606a57c1e2eSCedric Chaumont goto out; 607a57c1e2eSCedric Chaumont } 608b0104773SPascal Brand 609d372a47cSJens Wiklander key_size = key_info.objectSize; 610b0104773SPascal Brand 611b0104773SPascal Brand TEE_ResetTransientObject(operation->key1); 612b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 613b0104773SPascal Brand 6147583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key1, key); 6157583c59eSCedric Chaumont if (res != TEE_SUCCESS) 616a57c1e2eSCedric Chaumont goto out; 6177583c59eSCedric Chaumont 618b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET; 619b0104773SPascal Brand 620b0104773SPascal Brand operation->info.keySize = key_size; 621b0104773SPascal Brand 6227583c59eSCedric Chaumont out: 623a57c1e2eSCedric Chaumont if (res != TEE_SUCCESS && 624a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 625a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 626b36311adSJerome Forissier TEE_Panic(res); 627a57c1e2eSCedric Chaumont 628a57c1e2eSCedric Chaumont return res; 629b0104773SPascal Brand } 630b0104773SPascal Brand 631b0104773SPascal Brand TEE_Result TEE_SetOperationKey2(TEE_OperationHandle operation, 632b0104773SPascal Brand TEE_ObjectHandle key1, TEE_ObjectHandle key2) 633b0104773SPascal Brand { 6347583c59eSCedric Chaumont TEE_Result res; 635b0104773SPascal Brand uint32_t key_size = 0; 636b0104773SPascal Brand TEE_ObjectInfo key_info1; 637b0104773SPascal Brand TEE_ObjectInfo key_info2; 638b0104773SPascal Brand 639a57c1e2eSCedric Chaumont if (operation == TEE_HANDLE_NULL) { 640a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 641a57c1e2eSCedric Chaumont goto out; 642a57c1e2eSCedric Chaumont } 643a57c1e2eSCedric Chaumont 644642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) { 645642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 646642a1607SCedric Chaumont goto out; 647642a1607SCedric Chaumont } 648642a1607SCedric Chaumont 649a57c1e2eSCedric Chaumont /* 650a57c1e2eSCedric Chaumont * Key1/Key2 and/or are not initialized and 651a57c1e2eSCedric Chaumont * Either both keys are NULL or both are not NULL 652a57c1e2eSCedric Chaumont */ 6536c4ea258SJens Wiklander if (!key1 && !key2) { 6546c4ea258SJens Wiklander /* Clear the keys */ 655a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key1); 656a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key2); 6576c4ea258SJens Wiklander operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 6586c4ea258SJens Wiklander return TEE_SUCCESS; 6596c4ea258SJens Wiklander } else if (!key1 || !key2) { 6606c4ea258SJens Wiklander /* Both keys are obviously not valid. */ 661a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 662a57c1e2eSCedric Chaumont goto out; 663a57c1e2eSCedric Chaumont } 664a57c1e2eSCedric Chaumont 665a57c1e2eSCedric Chaumont /* No key for digest operation */ 666a57c1e2eSCedric Chaumont if (operation->info.operationClass == TEE_OPERATION_DIGEST) { 667a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 668a57c1e2eSCedric Chaumont goto out; 669a57c1e2eSCedric Chaumont } 670a57c1e2eSCedric Chaumont 6715b385b3fSJerome Forissier /* Two keys flag expected (TEE_ALG_AES_XTS and TEE_ALG_SM2_KEP only) */ 672a57c1e2eSCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 673a57c1e2eSCedric Chaumont 0) { 674a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 675a57c1e2eSCedric Chaumont goto out; 676a57c1e2eSCedric Chaumont } 677a57c1e2eSCedric Chaumont 6787583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key1, &key_info1); 679a57c1e2eSCedric Chaumont /* Key1 is not a valid handle */ 6807583c59eSCedric Chaumont if (res != TEE_SUCCESS) 681a57c1e2eSCedric Chaumont goto out; 6827583c59eSCedric Chaumont 683b0104773SPascal Brand /* Supplied key has to meet required usage */ 684b0104773SPascal Brand if ((key_info1.objectUsage & operation->info. 685b0104773SPascal Brand requiredKeyUsage) != operation->info.requiredKeyUsage) { 686a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 687a57c1e2eSCedric Chaumont goto out; 688b0104773SPascal Brand } 689b0104773SPascal Brand 6907583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key2, &key_info2); 691a57c1e2eSCedric Chaumont /* Key2 is not a valid handle */ 6927583c59eSCedric Chaumont if (res != TEE_SUCCESS) { 6937583c59eSCedric Chaumont if (res == TEE_ERROR_CORRUPT_OBJECT) 6947583c59eSCedric Chaumont res = TEE_ERROR_CORRUPT_OBJECT_2; 695a57c1e2eSCedric Chaumont goto out; 6967583c59eSCedric Chaumont } 6977583c59eSCedric Chaumont 698b0104773SPascal Brand /* Supplied key has to meet required usage */ 699b0104773SPascal Brand if ((key_info2.objectUsage & operation->info. 700b0104773SPascal Brand requiredKeyUsage) != operation->info.requiredKeyUsage) { 701a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 702a57c1e2eSCedric Chaumont goto out; 703b0104773SPascal Brand } 704b0104773SPascal Brand 705b0104773SPascal Brand /* 7065b385b3fSJerome Forissier * All the multi key algorithm currently supported requires the keys to 7075b385b3fSJerome Forissier * be of equal size. 708b0104773SPascal Brand */ 709d372a47cSJens Wiklander if (key_info1.objectSize != key_info2.objectSize) { 710a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 711a57c1e2eSCedric Chaumont goto out; 712b0104773SPascal Brand 713a57c1e2eSCedric Chaumont } 714a57c1e2eSCedric Chaumont 715d372a47cSJens Wiklander if (operation->info.maxKeySize < key_info1.objectSize) { 716a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 717a57c1e2eSCedric Chaumont goto out; 718a57c1e2eSCedric Chaumont } 719b0104773SPascal Brand 720b0104773SPascal Brand /* 721b0104773SPascal Brand * Odd that only the size of one key should be reported while 722b0104773SPascal Brand * size of two key are used when allocating the operation. 723b0104773SPascal Brand */ 724d372a47cSJens Wiklander key_size = key_info1.objectSize; 725b0104773SPascal Brand 726b0104773SPascal Brand TEE_ResetTransientObject(operation->key1); 727b0104773SPascal Brand TEE_ResetTransientObject(operation->key2); 728b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 729b0104773SPascal Brand 7307583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key1, key1); 7317583c59eSCedric Chaumont if (res != TEE_SUCCESS) 732a57c1e2eSCedric Chaumont goto out; 7337583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key2, key2); 7347583c59eSCedric Chaumont if (res != TEE_SUCCESS) { 7357583c59eSCedric Chaumont if (res == TEE_ERROR_CORRUPT_OBJECT) 7367583c59eSCedric Chaumont res = TEE_ERROR_CORRUPT_OBJECT_2; 737a57c1e2eSCedric Chaumont goto out; 7387583c59eSCedric Chaumont } 7397583c59eSCedric Chaumont 740b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET; 741b0104773SPascal Brand 742b0104773SPascal Brand operation->info.keySize = key_size; 743b0104773SPascal Brand 7447583c59eSCedric Chaumont out: 745a57c1e2eSCedric Chaumont if (res != TEE_SUCCESS && 746a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 747a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT_2 && 748a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE && 749a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE_2) 750b36311adSJerome Forissier TEE_Panic(res); 751a57c1e2eSCedric Chaumont 752a57c1e2eSCedric Chaumont return res; 753b0104773SPascal Brand } 754b0104773SPascal Brand 755b0104773SPascal Brand void TEE_CopyOperation(TEE_OperationHandle dst_op, TEE_OperationHandle src_op) 756b0104773SPascal Brand { 757b0104773SPascal Brand TEE_Result res; 758b0104773SPascal Brand 759b0104773SPascal Brand if (dst_op == TEE_HANDLE_NULL || src_op == TEE_HANDLE_NULL) 760b0104773SPascal Brand TEE_Panic(0); 761b0104773SPascal Brand if (dst_op->info.algorithm != src_op->info.algorithm) 762b0104773SPascal Brand TEE_Panic(0); 7638734de30SJens Wiklander if (dst_op->info.mode != src_op->info.mode) 7648734de30SJens Wiklander TEE_Panic(0); 765b0104773SPascal Brand if (src_op->info.operationClass != TEE_OPERATION_DIGEST) { 766b0104773SPascal Brand TEE_ObjectHandle key1 = TEE_HANDLE_NULL; 767b0104773SPascal Brand TEE_ObjectHandle key2 = TEE_HANDLE_NULL; 768b0104773SPascal Brand 769b0104773SPascal Brand if (src_op->info.handleState & TEE_HANDLE_FLAG_KEY_SET) { 770b0104773SPascal Brand key1 = src_op->key1; 771b0104773SPascal Brand key2 = src_op->key2; 772b0104773SPascal Brand } 773b0104773SPascal Brand 774b0104773SPascal Brand if ((src_op->info.handleState & 775b0104773SPascal Brand TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 0) { 776b0104773SPascal Brand TEE_SetOperationKey(dst_op, key1); 777b0104773SPascal Brand } else { 778b0104773SPascal Brand TEE_SetOperationKey2(dst_op, key1, key2); 779b0104773SPascal Brand } 780b0104773SPascal Brand } 781b0104773SPascal Brand dst_op->info.handleState = src_op->info.handleState; 782b0104773SPascal Brand dst_op->info.keySize = src_op->info.keySize; 7838e07702eSJens Wiklander dst_op->info.digestLength = src_op->info.digestLength; 784642a1607SCedric Chaumont dst_op->operationState = src_op->operationState; 785b0104773SPascal Brand 786b0104773SPascal Brand if (dst_op->buffer_two_blocks != src_op->buffer_two_blocks || 787b0104773SPascal Brand dst_op->block_size != src_op->block_size) 788b0104773SPascal Brand TEE_Panic(0); 789b0104773SPascal Brand 790b0104773SPascal Brand if (dst_op->buffer != NULL) { 791b0104773SPascal Brand if (src_op->buffer == NULL) 792b0104773SPascal Brand TEE_Panic(0); 793b0104773SPascal Brand 794b0104773SPascal Brand memcpy(dst_op->buffer, src_op->buffer, src_op->buffer_offs); 795b0104773SPascal Brand dst_op->buffer_offs = src_op->buffer_offs; 796b0104773SPascal Brand } else if (src_op->buffer != NULL) { 797b0104773SPascal Brand TEE_Panic(0); 798b0104773SPascal Brand } 799b0104773SPascal Brand 8002c028fdeSJerome Forissier res = _utee_cryp_state_copy(dst_op->state, src_op->state); 801b0104773SPascal Brand if (res != TEE_SUCCESS) 802b0104773SPascal Brand TEE_Panic(res); 803b0104773SPascal Brand } 804b0104773SPascal Brand 805b0104773SPascal Brand /* Cryptographic Operations API - Message Digest Functions */ 806b0104773SPascal Brand 8078f07fe6fSJerome Forissier static void init_hash_operation(TEE_OperationHandle operation, const void *IV, 8086d15db08SJerome Forissier uint32_t IVLen) 8096d15db08SJerome Forissier { 8106d15db08SJerome Forissier TEE_Result res; 8116d15db08SJerome Forissier 8126d15db08SJerome Forissier /* 8136d15db08SJerome Forissier * Note : IV and IVLen are never used in current implementation 8146d15db08SJerome Forissier * This is why coherent values of IV and IVLen are not checked 8156d15db08SJerome Forissier */ 8162c028fdeSJerome Forissier res = _utee_hash_init(operation->state, IV, IVLen); 8176d15db08SJerome Forissier if (res != TEE_SUCCESS) 8186d15db08SJerome Forissier TEE_Panic(res); 8196d15db08SJerome Forissier operation->buffer_offs = 0; 8206d15db08SJerome Forissier operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 8216d15db08SJerome Forissier } 8226d15db08SJerome Forissier 823b0104773SPascal Brand void TEE_DigestUpdate(TEE_OperationHandle operation, 824*185bf58cSJens Wiklander const void *chunk, size_t chunkSize) 825b0104773SPascal Brand { 82673d6c3baSJoakim Bech TEE_Result res = TEE_ERROR_GENERIC; 827b0104773SPascal Brand 82873d6c3baSJoakim Bech if (operation == TEE_HANDLE_NULL || 82973d6c3baSJoakim Bech operation->info.operationClass != TEE_OPERATION_DIGEST) 830b0104773SPascal Brand TEE_Panic(0); 83173d6c3baSJoakim Bech 832642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 833642a1607SCedric Chaumont 8342c028fdeSJerome Forissier res = _utee_hash_update(operation->state, chunk, chunkSize); 835b0104773SPascal Brand if (res != TEE_SUCCESS) 836b0104773SPascal Brand TEE_Panic(res); 837b0104773SPascal Brand } 838b0104773SPascal Brand 839*185bf58cSJens Wiklander void __GP11_TEE_DigestUpdate(TEE_OperationHandle operation, 840*185bf58cSJens Wiklander const void *chunk, uint32_t chunkSize) 841*185bf58cSJens Wiklander { 842*185bf58cSJens Wiklander return TEE_DigestUpdate(operation, chunk, chunkSize); 843*185bf58cSJens Wiklander } 844*185bf58cSJens Wiklander 8458f07fe6fSJerome Forissier TEE_Result TEE_DigestDoFinal(TEE_OperationHandle operation, const void *chunk, 846*185bf58cSJens Wiklander size_t chunkLen, void *hash, size_t *hashLen) 847b0104773SPascal Brand { 84887c2f6b6SCedric Chaumont TEE_Result res; 849e86f1266SJens Wiklander uint64_t hl; 85087c2f6b6SCedric Chaumont 85187c2f6b6SCedric Chaumont if ((operation == TEE_HANDLE_NULL) || 85287c2f6b6SCedric Chaumont (!chunk && chunkLen) || 85387c2f6b6SCedric Chaumont (operation->info.operationClass != TEE_OPERATION_DIGEST)) { 85487c2f6b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 85587c2f6b6SCedric Chaumont goto out; 85687c2f6b6SCedric Chaumont } 8576915bbbbSJens Wiklander __utee_check_inout_annotation(hashLen, sizeof(*hashLen)); 85887c2f6b6SCedric Chaumont 859e86f1266SJens Wiklander hl = *hashLen; 8602c028fdeSJerome Forissier res = _utee_hash_final(operation->state, chunk, chunkLen, hash, &hl); 861e86f1266SJens Wiklander *hashLen = hl; 8626d15db08SJerome Forissier if (res != TEE_SUCCESS) 8636d15db08SJerome Forissier goto out; 8646d15db08SJerome Forissier 8656d15db08SJerome Forissier /* Reset operation state */ 8666d15db08SJerome Forissier init_hash_operation(operation, NULL, 0); 86787c2f6b6SCedric Chaumont 868642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 869642a1607SCedric Chaumont 87087c2f6b6SCedric Chaumont out: 87187c2f6b6SCedric Chaumont if (res != TEE_SUCCESS && 87287c2f6b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 873b36311adSJerome Forissier TEE_Panic(res); 87473d6c3baSJoakim Bech 87587c2f6b6SCedric Chaumont return res; 876b0104773SPascal Brand } 877b0104773SPascal Brand 878*185bf58cSJens Wiklander TEE_Result __GP11_TEE_DigestDoFinal(TEE_OperationHandle operation, 879*185bf58cSJens Wiklander const void *chunk, uint32_t chunkLen, 880*185bf58cSJens Wiklander void *hash, uint32_t *hashLen) 881*185bf58cSJens Wiklander { 882*185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 883*185bf58cSJens Wiklander size_t l = 0; 884*185bf58cSJens Wiklander 885*185bf58cSJens Wiklander __utee_check_inout_annotation(hashLen, sizeof(*hashLen)); 886*185bf58cSJens Wiklander l = *hashLen; 887*185bf58cSJens Wiklander res = TEE_DigestDoFinal(operation, chunk, chunkLen, hash, &l); 888*185bf58cSJens Wiklander *hashLen = l; 889*185bf58cSJens Wiklander return res; 890*185bf58cSJens Wiklander } 891*185bf58cSJens Wiklander 892b0104773SPascal Brand /* Cryptographic Operations API - Symmetric Cipher Functions */ 893b0104773SPascal Brand 8948f07fe6fSJerome Forissier void TEE_CipherInit(TEE_OperationHandle operation, const void *IV, 895*185bf58cSJens Wiklander size_t IVLen) 896b0104773SPascal Brand { 897b0104773SPascal Brand TEE_Result res; 898b0104773SPascal Brand 899b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 900b0104773SPascal Brand TEE_Panic(0); 901642a1607SCedric Chaumont 902b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_CIPHER) 903b0104773SPascal Brand TEE_Panic(0); 904642a1607SCedric Chaumont 905642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) || 906642a1607SCedric Chaumont !(operation->key1)) 907642a1607SCedric Chaumont TEE_Panic(0); 908642a1607SCedric Chaumont 909642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 910642a1607SCedric Chaumont TEE_ResetOperation(operation); 911642a1607SCedric Chaumont 912ad7aa2a5SSadiq Hussain if (IV && IVLen) { 913ad7aa2a5SSadiq Hussain if (operation->info.algorithm == TEE_ALG_AES_ECB_NOPAD || 914ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_DES_ECB_NOPAD || 915ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_DES3_ECB_NOPAD || 916ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_SM4_ECB_NOPAD) 917ad7aa2a5SSadiq Hussain TEE_Panic(0); 918ad7aa2a5SSadiq Hussain } 919ad7aa2a5SSadiq Hussain 920642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 921642a1607SCedric Chaumont 9222c028fdeSJerome Forissier res = _utee_cipher_init(operation->state, IV, IVLen); 923b0104773SPascal Brand if (res != TEE_SUCCESS) 924b0104773SPascal Brand TEE_Panic(res); 925642a1607SCedric Chaumont 926b0104773SPascal Brand operation->buffer_offs = 0; 927b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 928b0104773SPascal Brand } 929b0104773SPascal Brand 930*185bf58cSJens Wiklander void __GP11_TEE_CipherInit(TEE_OperationHandle operation, const void *IV, 931*185bf58cSJens Wiklander uint32_t IVLen) 932*185bf58cSJens Wiklander { 933*185bf58cSJens Wiklander return TEE_CipherInit(operation, IV, IVLen); 934*185bf58cSJens Wiklander } 935*185bf58cSJens Wiklander 936b0104773SPascal Brand static TEE_Result tee_buffer_update( 937b0104773SPascal Brand TEE_OperationHandle op, 938e86f1266SJens Wiklander TEE_Result(*update_func)(unsigned long state, const void *src, 939e86f1266SJens Wiklander size_t slen, void *dst, uint64_t *dlen), 940b0104773SPascal Brand const void *src_data, size_t src_len, 941e86f1266SJens Wiklander void *dest_data, uint64_t *dest_len) 942b0104773SPascal Brand { 943b0104773SPascal Brand TEE_Result res; 944b0104773SPascal Brand const uint8_t *src = src_data; 945b0104773SPascal Brand size_t slen = src_len; 946b0104773SPascal Brand uint8_t *dst = dest_data; 947b0104773SPascal Brand size_t dlen = *dest_len; 948b0104773SPascal Brand size_t acc_dlen = 0; 949e86f1266SJens Wiklander uint64_t tmp_dlen; 950b0104773SPascal Brand size_t l; 951b0104773SPascal Brand size_t buffer_size; 952d3588802SPascal Brand size_t buffer_left; 953b0104773SPascal Brand 954090268f5SJens Wiklander if (!src) { 955090268f5SJens Wiklander if (slen) 956090268f5SJens Wiklander TEE_Panic(0); 957090268f5SJens Wiklander goto out; 958090268f5SJens Wiklander } 959090268f5SJens Wiklander 960d3588802SPascal Brand if (op->buffer_two_blocks) { 961b0104773SPascal Brand buffer_size = op->block_size * 2; 962d3588802SPascal Brand buffer_left = 1; 963d3588802SPascal Brand } else { 964b0104773SPascal Brand buffer_size = op->block_size; 965d3588802SPascal Brand buffer_left = 0; 966d3588802SPascal Brand } 967b0104773SPascal Brand 968b0104773SPascal Brand if (op->buffer_offs > 0) { 969b0104773SPascal Brand /* Fill up complete block */ 970b0104773SPascal Brand if (op->buffer_offs < op->block_size) 971b0104773SPascal Brand l = MIN(slen, op->block_size - op->buffer_offs); 972b0104773SPascal Brand else 973b0104773SPascal Brand l = MIN(slen, buffer_size - op->buffer_offs); 974b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, l); 975b0104773SPascal Brand op->buffer_offs += l; 976b0104773SPascal Brand src += l; 977b0104773SPascal Brand slen -= l; 978b0104773SPascal Brand if ((op->buffer_offs % op->block_size) != 0) 979b0104773SPascal Brand goto out; /* Nothing left to do */ 980b0104773SPascal Brand } 981b0104773SPascal Brand 982b0104773SPascal Brand /* If we can feed from buffer */ 983d3588802SPascal Brand if ((op->buffer_offs > 0) && 984d3588802SPascal Brand ((op->buffer_offs + slen) >= (buffer_size + buffer_left))) { 9852ff3fdbbSPascal Brand l = ROUNDUP(op->buffer_offs + slen - buffer_size, 986b0104773SPascal Brand op->block_size); 987b0104773SPascal Brand l = MIN(op->buffer_offs, l); 988b0104773SPascal Brand tmp_dlen = dlen; 989b0104773SPascal Brand res = update_func(op->state, op->buffer, l, dst, &tmp_dlen); 990b0104773SPascal Brand if (res != TEE_SUCCESS) 991b0104773SPascal Brand TEE_Panic(res); 992b0104773SPascal Brand dst += tmp_dlen; 993b0104773SPascal Brand dlen -= tmp_dlen; 994b0104773SPascal Brand acc_dlen += tmp_dlen; 995b0104773SPascal Brand op->buffer_offs -= l; 996b0104773SPascal Brand if (op->buffer_offs > 0) { 997b0104773SPascal Brand /* 998b0104773SPascal Brand * Slen is small enough to be contained in rest buffer. 999b0104773SPascal Brand */ 1000b0104773SPascal Brand memcpy(op->buffer, op->buffer + l, buffer_size - l); 1001b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, slen); 1002b0104773SPascal Brand op->buffer_offs += slen; 1003b0104773SPascal Brand goto out; /* Nothing left to do */ 1004b0104773SPascal Brand } 1005b0104773SPascal Brand } 1006b0104773SPascal Brand 1007d3588802SPascal Brand if (slen >= (buffer_size + buffer_left)) { 1008b0104773SPascal Brand /* Buffer is empty, feed as much as possible from src */ 1009bf7a587fSJerome Forissier if (op->info.algorithm == TEE_ALG_AES_CTS) 1010b1ecda78SJerome Forissier l = ROUNDUP(slen - buffer_size, op->block_size); 1011bf7a587fSJerome Forissier else 1012bf7a587fSJerome Forissier l = ROUNDUP(slen - buffer_size + 1, op->block_size); 1013b0104773SPascal Brand 1014b0104773SPascal Brand tmp_dlen = dlen; 1015b0104773SPascal Brand res = update_func(op->state, src, l, dst, &tmp_dlen); 1016b0104773SPascal Brand if (res != TEE_SUCCESS) 1017b0104773SPascal Brand TEE_Panic(res); 1018b0104773SPascal Brand src += l; 1019b0104773SPascal Brand slen -= l; 1020b0104773SPascal Brand dst += tmp_dlen; 1021b0104773SPascal Brand dlen -= tmp_dlen; 1022b0104773SPascal Brand acc_dlen += tmp_dlen; 1023b0104773SPascal Brand } 1024b0104773SPascal Brand 1025b0104773SPascal Brand /* Slen is small enough to be contained in buffer. */ 1026b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, slen); 1027b0104773SPascal Brand op->buffer_offs += slen; 1028b0104773SPascal Brand 1029b0104773SPascal Brand out: 1030b0104773SPascal Brand *dest_len = acc_dlen; 1031b0104773SPascal Brand return TEE_SUCCESS; 1032b0104773SPascal Brand } 1033b0104773SPascal Brand 10348f07fe6fSJerome Forissier TEE_Result TEE_CipherUpdate(TEE_OperationHandle operation, const void *srcData, 1035*185bf58cSJens Wiklander size_t srcLen, void *destData, size_t *destLen) 1036b0104773SPascal Brand { 1037dea1f2b6SCedric Chaumont TEE_Result res; 1038b0104773SPascal Brand size_t req_dlen; 1039e86f1266SJens Wiklander uint64_t dl; 1040b0104773SPascal Brand 10416915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1042dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1043dea1f2b6SCedric Chaumont goto out; 1044dea1f2b6SCedric Chaumont } 10456915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1046dea1f2b6SCedric Chaumont 1047642a1607SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_CIPHER) { 1048dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1049dea1f2b6SCedric Chaumont goto out; 1050dea1f2b6SCedric Chaumont } 1051dea1f2b6SCedric Chaumont 1052642a1607SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1053642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1054642a1607SCedric Chaumont goto out; 1055642a1607SCedric Chaumont } 1056642a1607SCedric Chaumont 1057642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1058dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1059dea1f2b6SCedric Chaumont goto out; 1060dea1f2b6SCedric Chaumont } 1061b0104773SPascal Brand 1062e32c5ddfSJerome Forissier if (!srcData && !srcLen) { 1063090268f5SJens Wiklander *destLen = 0; 1064e32c5ddfSJerome Forissier res = TEE_SUCCESS; 1065e32c5ddfSJerome Forissier goto out; 1066e32c5ddfSJerome Forissier } 1067e32c5ddfSJerome Forissier 1068b0104773SPascal Brand /* Calculate required dlen */ 106957aabac5SBogdan Liulko if (operation->block_size > 1) { 107057aabac5SBogdan Liulko req_dlen = ((operation->buffer_offs + srcLen) / 107157aabac5SBogdan Liulko operation->block_size) * operation->block_size; 107257aabac5SBogdan Liulko } else { 107357aabac5SBogdan Liulko req_dlen = srcLen; 107457aabac5SBogdan Liulko } 1075642a1607SCedric Chaumont if (operation->buffer_two_blocks) { 1076642a1607SCedric Chaumont if (req_dlen > operation->block_size * 2) 1077642a1607SCedric Chaumont req_dlen -= operation->block_size * 2; 1078b0104773SPascal Brand else 1079b0104773SPascal Brand req_dlen = 0; 1080b0104773SPascal Brand } 1081b0104773SPascal Brand /* 1082b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1083b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1084b0104773SPascal Brand * can't restore sync with this API. 1085b0104773SPascal Brand */ 1086b0104773SPascal Brand if (*destLen < req_dlen) { 1087b0104773SPascal Brand *destLen = req_dlen; 1088dea1f2b6SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1089dea1f2b6SCedric Chaumont goto out; 1090b0104773SPascal Brand } 1091b0104773SPascal Brand 1092e86f1266SJens Wiklander dl = *destLen; 109357aabac5SBogdan Liulko if (operation->block_size > 1) { 10942c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_cipher_update, srcData, 109557aabac5SBogdan Liulko srcLen, destData, &dl); 109657aabac5SBogdan Liulko } else { 109757aabac5SBogdan Liulko if (srcLen > 0) { 10982c028fdeSJerome Forissier res = _utee_cipher_update(operation->state, srcData, 109957aabac5SBogdan Liulko srcLen, destData, &dl); 110057aabac5SBogdan Liulko } else { 110157aabac5SBogdan Liulko res = TEE_SUCCESS; 110257aabac5SBogdan Liulko dl = 0; 110357aabac5SBogdan Liulko } 110457aabac5SBogdan Liulko } 1105e86f1266SJens Wiklander *destLen = dl; 1106b0104773SPascal Brand 1107dea1f2b6SCedric Chaumont out: 1108dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS && 1109dea1f2b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1110b36311adSJerome Forissier TEE_Panic(res); 1111dea1f2b6SCedric Chaumont 1112dea1f2b6SCedric Chaumont return res; 1113b0104773SPascal Brand } 1114b0104773SPascal Brand 1115*185bf58cSJens Wiklander TEE_Result __GP11_TEE_CipherUpdate(TEE_OperationHandle operation, 11168f07fe6fSJerome Forissier const void *srcData, uint32_t srcLen, 11178f07fe6fSJerome Forissier void *destData, uint32_t *destLen) 1118b0104773SPascal Brand { 11196915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 1120*185bf58cSJens Wiklander size_t dl = 0; 1121*185bf58cSJens Wiklander 1122*185bf58cSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1123*185bf58cSJens Wiklander dl = *destLen; 1124*185bf58cSJens Wiklander res = TEE_CipherUpdate(operation, srcData, srcLen, destData, &dl); 1125*185bf58cSJens Wiklander *destLen = dl; 1126*185bf58cSJens Wiklander return res; 1127*185bf58cSJens Wiklander } 1128*185bf58cSJens Wiklander 1129*185bf58cSJens Wiklander TEE_Result TEE_CipherDoFinal(TEE_OperationHandle operation, 1130*185bf58cSJens Wiklander const void *srcData, size_t srcLen, 1131*185bf58cSJens Wiklander void *destData, size_t *destLen) 1132*185bf58cSJens Wiklander { 1133*185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 1134b0104773SPascal Brand uint8_t *dst = destData; 1135b0104773SPascal Brand size_t acc_dlen = 0; 11366915bbbbSJens Wiklander uint64_t tmp_dlen = 0; 11376915bbbbSJens Wiklander size_t req_dlen = 0; 1138b0104773SPascal Brand 11396915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1140dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1141dea1f2b6SCedric Chaumont goto out; 1142dea1f2b6SCedric Chaumont } 11436915bbbbSJens Wiklander if (destLen) 11446915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1145dea1f2b6SCedric Chaumont 1146642a1607SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_CIPHER) { 1147dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1148dea1f2b6SCedric Chaumont goto out; 1149dea1f2b6SCedric Chaumont } 1150dea1f2b6SCedric Chaumont 1151642a1607SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1152642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1153642a1607SCedric Chaumont goto out; 1154642a1607SCedric Chaumont } 1155642a1607SCedric Chaumont 1156642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1157dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1158dea1f2b6SCedric Chaumont goto out; 1159dea1f2b6SCedric Chaumont } 1160b0104773SPascal Brand 1161b0104773SPascal Brand /* 1162b0104773SPascal Brand * Check that the final block doesn't require padding for those 1163b0104773SPascal Brand * algorithms that requires client to supply padding. 1164b0104773SPascal Brand */ 1165642a1607SCedric Chaumont if (operation->info.algorithm == TEE_ALG_AES_ECB_NOPAD || 1166642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_AES_CBC_NOPAD || 1167642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES_ECB_NOPAD || 1168642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES_CBC_NOPAD || 1169642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES3_ECB_NOPAD || 1170ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_DES3_CBC_NOPAD || 1171ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_SM4_ECB_NOPAD || 1172ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_SM4_CBC_NOPAD) { 1173642a1607SCedric Chaumont if (((operation->buffer_offs + srcLen) % operation->block_size) 1174642a1607SCedric Chaumont != 0) { 1175dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1176dea1f2b6SCedric Chaumont goto out; 1177dea1f2b6SCedric Chaumont } 1178b0104773SPascal Brand } 1179b0104773SPascal Brand 1180b0104773SPascal Brand /* 1181b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1182b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1183b0104773SPascal Brand * can't restore sync with this API. 1184b0104773SPascal Brand */ 118557aabac5SBogdan Liulko if (operation->block_size > 1) { 1186642a1607SCedric Chaumont req_dlen = operation->buffer_offs + srcLen; 118757aabac5SBogdan Liulko } else { 118857aabac5SBogdan Liulko req_dlen = srcLen; 118957aabac5SBogdan Liulko } 11906915bbbbSJens Wiklander if (destLen) 11916915bbbbSJens Wiklander tmp_dlen = *destLen; 11926915bbbbSJens Wiklander if (tmp_dlen < req_dlen) { 11936915bbbbSJens Wiklander if (destLen) 1194b0104773SPascal Brand *destLen = req_dlen; 1195dea1f2b6SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1196dea1f2b6SCedric Chaumont goto out; 1197b0104773SPascal Brand } 1198b0104773SPascal Brand 119957aabac5SBogdan Liulko if (operation->block_size > 1) { 1200dea9063eSJens Wiklander if (srcLen) { 12012c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_cipher_update, 1202dea9063eSJens Wiklander srcData, srcLen, dst, 1203dea9063eSJens Wiklander &tmp_dlen); 1204dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS) 1205dea1f2b6SCedric Chaumont goto out; 1206dea1f2b6SCedric Chaumont 1207b0104773SPascal Brand dst += tmp_dlen; 1208b0104773SPascal Brand acc_dlen += tmp_dlen; 1209b0104773SPascal Brand 1210b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 1211dea9063eSJens Wiklander } 12122c028fdeSJerome Forissier res = _utee_cipher_final(operation->state, operation->buffer, 12132c028fdeSJerome Forissier operation->buffer_offs, dst, 12142c028fdeSJerome Forissier &tmp_dlen); 121557aabac5SBogdan Liulko } else { 12162c028fdeSJerome Forissier res = _utee_cipher_final(operation->state, srcData, srcLen, dst, 12172c028fdeSJerome Forissier &tmp_dlen); 121857aabac5SBogdan Liulko } 1219b0104773SPascal Brand if (res != TEE_SUCCESS) 1220dea1f2b6SCedric Chaumont goto out; 1221dea1f2b6SCedric Chaumont 1222b0104773SPascal Brand acc_dlen += tmp_dlen; 12236915bbbbSJens Wiklander if (destLen) 1224b0104773SPascal Brand *destLen = acc_dlen; 1225dea1f2b6SCedric Chaumont 1226642a1607SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 1227642a1607SCedric Chaumont 1228642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1229642a1607SCedric Chaumont 1230dea1f2b6SCedric Chaumont out: 1231dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS && 1232dea1f2b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1233b36311adSJerome Forissier TEE_Panic(res); 1234dea1f2b6SCedric Chaumont 1235dea1f2b6SCedric Chaumont return res; 1236b0104773SPascal Brand } 1237b0104773SPascal Brand 1238*185bf58cSJens Wiklander TEE_Result __GP11_TEE_CipherDoFinal(TEE_OperationHandle operation, 1239*185bf58cSJens Wiklander const void *srcData, uint32_t srcLen, 1240*185bf58cSJens Wiklander void *destData, uint32_t *destLen) 1241*185bf58cSJens Wiklander { 1242*185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 1243*185bf58cSJens Wiklander size_t dl = 0; 1244*185bf58cSJens Wiklander 1245*185bf58cSJens Wiklander if (destLen) { 1246*185bf58cSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1247*185bf58cSJens Wiklander dl = *destLen; 1248*185bf58cSJens Wiklander } 1249*185bf58cSJens Wiklander res = TEE_CipherDoFinal(operation, srcData, srcLen, destData, &dl); 1250*185bf58cSJens Wiklander if (destLen) 1251*185bf58cSJens Wiklander *destLen = dl; 1252*185bf58cSJens Wiklander return res; 1253*185bf58cSJens Wiklander } 1254*185bf58cSJens Wiklander 1255b0104773SPascal Brand /* Cryptographic Operations API - MAC Functions */ 1256b0104773SPascal Brand 1257*185bf58cSJens Wiklander void TEE_MACInit(TEE_OperationHandle operation, const void *IV, size_t IVLen) 1258b0104773SPascal Brand { 1259b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 1260b0104773SPascal Brand TEE_Panic(0); 1261642a1607SCedric Chaumont 1262b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_MAC) 1263b0104773SPascal Brand TEE_Panic(0); 1264642a1607SCedric Chaumont 1265642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) || 1266642a1607SCedric Chaumont !(operation->key1)) 1267642a1607SCedric Chaumont TEE_Panic(0); 1268642a1607SCedric Chaumont 1269642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 1270642a1607SCedric Chaumont TEE_ResetOperation(operation); 1271642a1607SCedric Chaumont 1272642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1273642a1607SCedric Chaumont 12746d15db08SJerome Forissier init_hash_operation(operation, IV, IVLen); 1275b0104773SPascal Brand } 1276b0104773SPascal Brand 1277*185bf58cSJens Wiklander void __GP11_TEE_MACInit(TEE_OperationHandle operation, const void *IV, 1278*185bf58cSJens Wiklander uint32_t IVLen) 1279*185bf58cSJens Wiklander { 1280*185bf58cSJens Wiklander return TEE_MACInit(operation, IV, IVLen); 1281*185bf58cSJens Wiklander } 1282*185bf58cSJens Wiklander 12838f07fe6fSJerome Forissier void TEE_MACUpdate(TEE_OperationHandle operation, const void *chunk, 1284*185bf58cSJens Wiklander size_t chunkSize) 1285b0104773SPascal Brand { 1286b0104773SPascal Brand TEE_Result res; 1287b0104773SPascal Brand 128828e0efc6SCedric Chaumont if (operation == TEE_HANDLE_NULL || (chunk == NULL && chunkSize != 0)) 1289b0104773SPascal Brand TEE_Panic(0); 1290642a1607SCedric Chaumont 129128e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) 1292b0104773SPascal Brand TEE_Panic(0); 1293642a1607SCedric Chaumont 129428e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 1295b0104773SPascal Brand TEE_Panic(0); 1296b0104773SPascal Brand 1297642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) 1298642a1607SCedric Chaumont TEE_Panic(0); 1299642a1607SCedric Chaumont 13002c028fdeSJerome Forissier res = _utee_hash_update(operation->state, chunk, chunkSize); 1301b0104773SPascal Brand if (res != TEE_SUCCESS) 1302b0104773SPascal Brand TEE_Panic(res); 1303b0104773SPascal Brand } 1304b0104773SPascal Brand 1305*185bf58cSJens Wiklander void __GP11_TEE_MACUpdate(TEE_OperationHandle operation, const void *chunk, 1306*185bf58cSJens Wiklander uint32_t chunkSize) 1307*185bf58cSJens Wiklander { 1308*185bf58cSJens Wiklander return TEE_MACUpdate(operation, chunk, chunkSize); 1309*185bf58cSJens Wiklander } 1310*185bf58cSJens Wiklander 131128e0efc6SCedric Chaumont TEE_Result TEE_MACComputeFinal(TEE_OperationHandle operation, 1312*185bf58cSJens Wiklander const void *message, size_t messageLen, 1313*185bf58cSJens Wiklander void *mac, size_t *macLen) 1314b0104773SPascal Brand { 1315b0104773SPascal Brand TEE_Result res; 1316e86f1266SJens Wiklander uint64_t ml; 1317b0104773SPascal Brand 13186915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!message && messageLen)) { 131928e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 132028e0efc6SCedric Chaumont goto out; 132128e0efc6SCedric Chaumont } 13226915bbbbSJens Wiklander __utee_check_inout_annotation(macLen, sizeof(*macLen)); 1323b0104773SPascal Brand 132428e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) { 132528e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 132628e0efc6SCedric Chaumont goto out; 132728e0efc6SCedric Chaumont } 132828e0efc6SCedric Chaumont 132928e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 133028e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 133128e0efc6SCedric Chaumont goto out; 133228e0efc6SCedric Chaumont } 133328e0efc6SCedric Chaumont 1334642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1335642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1336642a1607SCedric Chaumont goto out; 1337642a1607SCedric Chaumont } 1338642a1607SCedric Chaumont 1339e86f1266SJens Wiklander ml = *macLen; 13402c028fdeSJerome Forissier res = _utee_hash_final(operation->state, message, messageLen, mac, &ml); 1341e86f1266SJens Wiklander *macLen = ml; 134228e0efc6SCedric Chaumont if (res != TEE_SUCCESS) 134328e0efc6SCedric Chaumont goto out; 134428e0efc6SCedric Chaumont 134528e0efc6SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 134628e0efc6SCedric Chaumont 1347642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1348642a1607SCedric Chaumont 134928e0efc6SCedric Chaumont out: 135028e0efc6SCedric Chaumont if (res != TEE_SUCCESS && 135128e0efc6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 135228e0efc6SCedric Chaumont TEE_Panic(res); 135328e0efc6SCedric Chaumont 1354b0104773SPascal Brand return res; 1355b0104773SPascal Brand } 1356b0104773SPascal Brand 1357*185bf58cSJens Wiklander TEE_Result __GP11_TEE_MACComputeFinal(TEE_OperationHandle operation, 13588f07fe6fSJerome Forissier const void *message, uint32_t messageLen, 1359*185bf58cSJens Wiklander void *mac, uint32_t *macLen) 1360*185bf58cSJens Wiklander { 1361*185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 1362*185bf58cSJens Wiklander size_t ml = 0; 1363*185bf58cSJens Wiklander 1364*185bf58cSJens Wiklander __utee_check_inout_annotation(macLen, sizeof(*macLen)); 1365*185bf58cSJens Wiklander ml = *macLen; 1366*185bf58cSJens Wiklander res = TEE_MACComputeFinal(operation, message, messageLen, mac, &ml); 1367*185bf58cSJens Wiklander *macLen = ml; 1368*185bf58cSJens Wiklander return res; 1369*185bf58cSJens Wiklander } 1370*185bf58cSJens Wiklander 1371*185bf58cSJens Wiklander TEE_Result TEE_MACCompareFinal(TEE_OperationHandle operation, 1372*185bf58cSJens Wiklander const void *message, size_t messageLen, 1373*185bf58cSJens Wiklander const void *mac, size_t macLen) 1374b0104773SPascal Brand { 1375b0104773SPascal Brand TEE_Result res; 1376ee4ba3d1SVictor Chong uint8_t computed_mac[TEE_MAX_HASH_SIZE] = { 0 }; 1377*185bf58cSJens Wiklander size_t computed_mac_size = TEE_MAX_HASH_SIZE; 1378b0104773SPascal Brand 137928e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) { 138028e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 138128e0efc6SCedric Chaumont goto out; 138228e0efc6SCedric Chaumont } 138328e0efc6SCedric Chaumont 138428e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 138528e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 138628e0efc6SCedric Chaumont goto out; 138728e0efc6SCedric Chaumont } 138828e0efc6SCedric Chaumont 1389642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1390642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1391642a1607SCedric Chaumont goto out; 1392642a1607SCedric Chaumont } 1393642a1607SCedric Chaumont 1394b0104773SPascal Brand res = TEE_MACComputeFinal(operation, message, messageLen, computed_mac, 1395b0104773SPascal Brand &computed_mac_size); 1396b0104773SPascal Brand if (res != TEE_SUCCESS) 139728e0efc6SCedric Chaumont goto out; 139828e0efc6SCedric Chaumont 139928e0efc6SCedric Chaumont if (computed_mac_size != macLen) { 140028e0efc6SCedric Chaumont res = TEE_ERROR_MAC_INVALID; 140128e0efc6SCedric Chaumont goto out; 140228e0efc6SCedric Chaumont } 140328e0efc6SCedric Chaumont 140448e10604SJerome Forissier if (consttime_memcmp(mac, computed_mac, computed_mac_size) != 0) { 140528e0efc6SCedric Chaumont res = TEE_ERROR_MAC_INVALID; 140628e0efc6SCedric Chaumont goto out; 140728e0efc6SCedric Chaumont } 140828e0efc6SCedric Chaumont 1409642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1410642a1607SCedric Chaumont 141128e0efc6SCedric Chaumont out: 141228e0efc6SCedric Chaumont if (res != TEE_SUCCESS && 141328e0efc6SCedric Chaumont res != TEE_ERROR_MAC_INVALID) 141428e0efc6SCedric Chaumont TEE_Panic(res); 141528e0efc6SCedric Chaumont 1416b0104773SPascal Brand return res; 1417b0104773SPascal Brand } 1418b0104773SPascal Brand 1419*185bf58cSJens Wiklander TEE_Result __GP11_TEE_MACCompareFinal(TEE_OperationHandle operation, 1420*185bf58cSJens Wiklander const void *message, uint32_t messageLen, 1421*185bf58cSJens Wiklander const void *mac, uint32_t macLen) 1422*185bf58cSJens Wiklander { 1423*185bf58cSJens Wiklander return TEE_MACCompareFinal(operation, message, messageLen, mac, macLen); 1424*185bf58cSJens Wiklander } 1425*185bf58cSJens Wiklander 1426b0104773SPascal Brand /* Cryptographic Operations API - Authenticated Encryption Functions */ 1427b0104773SPascal Brand 14288f07fe6fSJerome Forissier TEE_Result TEE_AEInit(TEE_OperationHandle operation, const void *nonce, 142979a3c601SCedric Chaumont uint32_t nonceLen, uint32_t tagLen, uint32_t AADLen, 1430b0104773SPascal Brand uint32_t payloadLen) 1431b0104773SPascal Brand { 1432b0104773SPascal Brand TEE_Result res; 1433b0104773SPascal Brand 1434b5816c88SCedric Chaumont if (operation == TEE_HANDLE_NULL || nonce == NULL) { 1435b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1436b5816c88SCedric Chaumont goto out; 1437b5816c88SCedric Chaumont } 1438b5816c88SCedric Chaumont 1439b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1440b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1441b5816c88SCedric Chaumont goto out; 1442b5816c88SCedric Chaumont } 1443b0104773SPascal Brand 1444642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) { 1445642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1446642a1607SCedric Chaumont goto out; 1447642a1607SCedric Chaumont } 1448642a1607SCedric Chaumont 1449b0104773SPascal Brand /* 1450b0104773SPascal Brand * AES-CCM tag len is specified by AES-CCM spec and handled in TEE Core 1451b0104773SPascal Brand * in the implementation. But AES-GCM spec doesn't specify the tag len 1452b0104773SPascal Brand * according to the same principle so we have to check here instead to 1453b0104773SPascal Brand * be GP compliant. 1454b0104773SPascal Brand */ 1455b5816c88SCedric Chaumont if (operation->info.algorithm == TEE_ALG_AES_GCM) { 1456b0104773SPascal Brand /* 1457b0104773SPascal Brand * From GP spec: For AES-GCM, can be 128, 120, 112, 104, or 96 1458b0104773SPascal Brand */ 1459b5816c88SCedric Chaumont if (tagLen < 96 || tagLen > 128 || (tagLen % 8 != 0)) { 1460b5816c88SCedric Chaumont res = TEE_ERROR_NOT_SUPPORTED; 1461b5816c88SCedric Chaumont goto out; 1462b5816c88SCedric Chaumont } 1463b0104773SPascal Brand } 1464b0104773SPascal Brand 14652c028fdeSJerome Forissier res = _utee_authenc_init(operation->state, nonce, nonceLen, tagLen / 8, 14662c028fdeSJerome Forissier AADLen, payloadLen); 1467b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1468b5816c88SCedric Chaumont goto out; 1469b5816c88SCedric Chaumont 14707acaf5adSAlbert Schwarzkopf operation->info.digestLength = tagLen / 8; 1471f2674567SSumit Garg operation->buffer_offs = 0; 1472b5816c88SCedric Chaumont operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 1473b5816c88SCedric Chaumont 1474b5816c88SCedric Chaumont out: 1475b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1476b5816c88SCedric Chaumont res != TEE_ERROR_NOT_SUPPORTED) 1477b0104773SPascal Brand TEE_Panic(res); 1478b5816c88SCedric Chaumont 1479b0104773SPascal Brand return res; 1480b0104773SPascal Brand } 1481b0104773SPascal Brand 14828f07fe6fSJerome Forissier void TEE_AEUpdateAAD(TEE_OperationHandle operation, const void *AADdata, 148379a3c601SCedric Chaumont uint32_t AADdataLen) 1484b0104773SPascal Brand { 1485b0104773SPascal Brand TEE_Result res; 1486b0104773SPascal Brand 1487b5816c88SCedric Chaumont if (operation == TEE_HANDLE_NULL || 1488b5816c88SCedric Chaumont (AADdata == NULL && AADdataLen != 0)) 1489b0104773SPascal Brand TEE_Panic(0); 1490642a1607SCedric Chaumont 1491b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) 1492b0104773SPascal Brand TEE_Panic(0); 1493642a1607SCedric Chaumont 1494b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 1495b0104773SPascal Brand TEE_Panic(0); 1496b0104773SPascal Brand 14972c028fdeSJerome Forissier res = _utee_authenc_update_aad(operation->state, AADdata, AADdataLen); 1498642a1607SCedric Chaumont 1499642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1500642a1607SCedric Chaumont 1501b0104773SPascal Brand if (res != TEE_SUCCESS) 1502b0104773SPascal Brand TEE_Panic(res); 1503b0104773SPascal Brand } 1504b0104773SPascal Brand 15058f07fe6fSJerome Forissier TEE_Result TEE_AEUpdate(TEE_OperationHandle operation, const void *srcData, 150679a3c601SCedric Chaumont uint32_t srcLen, void *destData, uint32_t *destLen) 1507b0104773SPascal Brand { 15086915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 15096915bbbbSJens Wiklander size_t req_dlen = 0; 15106915bbbbSJens Wiklander uint64_t dl = 0; 1511b0104773SPascal Brand 15126915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1513b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1514b5816c88SCedric Chaumont goto out; 1515b5816c88SCedric Chaumont } 15166915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1517b5816c88SCedric Chaumont 1518b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1519b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1520b5816c88SCedric Chaumont goto out; 1521b5816c88SCedric Chaumont } 1522b5816c88SCedric Chaumont 1523b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1524b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1525b5816c88SCedric Chaumont goto out; 1526b5816c88SCedric Chaumont } 1527b0104773SPascal Brand 1528827308b8SJerome Forissier if (!srcData && !srcLen) { 1529090268f5SJens Wiklander *destLen = 0; 1530827308b8SJerome Forissier res = TEE_SUCCESS; 1531827308b8SJerome Forissier goto out; 1532827308b8SJerome Forissier } 1533827308b8SJerome Forissier 1534b0104773SPascal Brand /* 1535b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1536b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1537b0104773SPascal Brand * can't restore sync with this API. 1538b0104773SPascal Brand */ 1539afc0c182SBogdan Liulko if (operation->block_size > 1) { 1540b5816c88SCedric Chaumont req_dlen = ROUNDDOWN(operation->buffer_offs + srcLen, 1541b5816c88SCedric Chaumont operation->block_size); 1542afc0c182SBogdan Liulko } else { 1543afc0c182SBogdan Liulko req_dlen = srcLen; 1544afc0c182SBogdan Liulko } 1545afc0c182SBogdan Liulko 15466915bbbbSJens Wiklander dl = *destLen; 15476915bbbbSJens Wiklander if (dl < req_dlen) { 1548b0104773SPascal Brand *destLen = req_dlen; 1549b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1550b5816c88SCedric Chaumont goto out; 1551b0104773SPascal Brand } 1552b0104773SPascal Brand 1553afc0c182SBogdan Liulko if (operation->block_size > 1) { 15542c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_authenc_update_payload, 1555afc0c182SBogdan Liulko srcData, srcLen, destData, &dl); 1556afc0c182SBogdan Liulko } else { 1557afc0c182SBogdan Liulko if (srcLen > 0) { 15582c028fdeSJerome Forissier res = _utee_authenc_update_payload(operation->state, 1559afc0c182SBogdan Liulko srcData, srcLen, 1560afc0c182SBogdan Liulko destData, &dl); 1561afc0c182SBogdan Liulko } else { 1562afc0c182SBogdan Liulko dl = 0; 1563afc0c182SBogdan Liulko res = TEE_SUCCESS; 1564afc0c182SBogdan Liulko } 1565afc0c182SBogdan Liulko } 1566afc0c182SBogdan Liulko if (res != TEE_SUCCESS) 1567afc0c182SBogdan Liulko goto out; 1568afc0c182SBogdan Liulko 1569e86f1266SJens Wiklander *destLen = dl; 1570b0104773SPascal Brand 1571642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1572642a1607SCedric Chaumont 1573b5816c88SCedric Chaumont out: 1574b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1575b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1576b5816c88SCedric Chaumont TEE_Panic(res); 1577b5816c88SCedric Chaumont 1578b5816c88SCedric Chaumont return res; 1579b0104773SPascal Brand } 1580b0104773SPascal Brand 1581b5816c88SCedric Chaumont TEE_Result TEE_AEEncryptFinal(TEE_OperationHandle operation, 15828f07fe6fSJerome Forissier const void *srcData, uint32_t srcLen, 158379a3c601SCedric Chaumont void *destData, uint32_t *destLen, void *tag, 158479a3c601SCedric Chaumont uint32_t *tagLen) 1585b0104773SPascal Brand { 1586b0104773SPascal Brand TEE_Result res; 1587b0104773SPascal Brand uint8_t *dst = destData; 1588b0104773SPascal Brand size_t acc_dlen = 0; 1589e86f1266SJens Wiklander uint64_t tmp_dlen; 1590b0104773SPascal Brand size_t req_dlen; 1591e86f1266SJens Wiklander uint64_t tl; 1592b0104773SPascal Brand 15936915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1594b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1595b5816c88SCedric Chaumont goto out; 1596b5816c88SCedric Chaumont } 15976915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 15986915bbbbSJens Wiklander __utee_check_inout_annotation(tagLen, sizeof(*tagLen)); 1599b5816c88SCedric Chaumont 1600b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1601b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1602b5816c88SCedric Chaumont goto out; 1603b5816c88SCedric Chaumont } 1604b5816c88SCedric Chaumont 1605b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1606b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1607b5816c88SCedric Chaumont goto out; 1608b5816c88SCedric Chaumont } 1609b0104773SPascal Brand 1610b0104773SPascal Brand /* 1611b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1612b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1613b0104773SPascal Brand * can't restore sync with this API. 16142733280aSEtienne Carriere * 16152733280aSEtienne Carriere * Need to check this before update_payload since sync would be lost if 16162733280aSEtienne Carriere * we return short buffer after that. 1617b0104773SPascal Brand */ 16182733280aSEtienne Carriere res = TEE_ERROR_GENERIC; 16192733280aSEtienne Carriere 1620b5816c88SCedric Chaumont req_dlen = operation->buffer_offs + srcLen; 1621b0104773SPascal Brand if (*destLen < req_dlen) { 1622b0104773SPascal Brand *destLen = req_dlen; 1623b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1624b0104773SPascal Brand } 1625b0104773SPascal Brand 16267acaf5adSAlbert Schwarzkopf if (*tagLen < operation->info.digestLength) { 16277acaf5adSAlbert Schwarzkopf *tagLen = operation->info.digestLength; 1628b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1629b0104773SPascal Brand } 1630b0104773SPascal Brand 16312733280aSEtienne Carriere if (res == TEE_ERROR_SHORT_BUFFER) 16322733280aSEtienne Carriere goto out; 16332733280aSEtienne Carriere 1634afc0c182SBogdan Liulko tl = *tagLen; 1635b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 1636afc0c182SBogdan Liulko if (operation->block_size > 1) { 16372c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_authenc_update_payload, 1638afc0c182SBogdan Liulko srcData, srcLen, dst, &tmp_dlen); 1639b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1640b5816c88SCedric Chaumont goto out; 1641b5816c88SCedric Chaumont 1642b0104773SPascal Brand dst += tmp_dlen; 1643b0104773SPascal Brand acc_dlen += tmp_dlen; 1644b0104773SPascal Brand 1645b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 16462c028fdeSJerome Forissier res = _utee_authenc_enc_final(operation->state, 1647afc0c182SBogdan Liulko operation->buffer, 1648afc0c182SBogdan Liulko operation->buffer_offs, dst, 1649afc0c182SBogdan Liulko &tmp_dlen, tag, &tl); 1650afc0c182SBogdan Liulko } else { 16512c028fdeSJerome Forissier res = _utee_authenc_enc_final(operation->state, srcData, 1652afc0c182SBogdan Liulko srcLen, dst, &tmp_dlen, 1653e86f1266SJens Wiklander tag, &tl); 1654afc0c182SBogdan Liulko } 1655e86f1266SJens Wiklander *tagLen = tl; 1656b0104773SPascal Brand if (res != TEE_SUCCESS) 1657b5816c88SCedric Chaumont goto out; 1658b0104773SPascal Brand 1659b5816c88SCedric Chaumont acc_dlen += tmp_dlen; 1660b0104773SPascal Brand *destLen = acc_dlen; 1661642a1607SCedric Chaumont 1662b5816c88SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 1663b5816c88SCedric Chaumont 1664642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1665642a1607SCedric Chaumont 1666b5816c88SCedric Chaumont out: 1667b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1668b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1669b5816c88SCedric Chaumont TEE_Panic(res); 1670b0104773SPascal Brand 1671b0104773SPascal Brand return res; 1672b0104773SPascal Brand } 1673b0104773SPascal Brand 1674b5816c88SCedric Chaumont TEE_Result TEE_AEDecryptFinal(TEE_OperationHandle operation, 16758f07fe6fSJerome Forissier const void *srcData, uint32_t srcLen, 1676b5816c88SCedric Chaumont void *destData, uint32_t *destLen, void *tag, 167779a3c601SCedric Chaumont uint32_t tagLen) 1678b0104773SPascal Brand { 1679b0104773SPascal Brand TEE_Result res; 1680b0104773SPascal Brand uint8_t *dst = destData; 1681b0104773SPascal Brand size_t acc_dlen = 0; 1682e86f1266SJens Wiklander uint64_t tmp_dlen; 1683b0104773SPascal Brand size_t req_dlen; 1684b0104773SPascal Brand 16856915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1686b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1687b5816c88SCedric Chaumont goto out; 1688b5816c88SCedric Chaumont } 16896915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1690b5816c88SCedric Chaumont 1691b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1692b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1693b5816c88SCedric Chaumont goto out; 1694b5816c88SCedric Chaumont } 1695b5816c88SCedric Chaumont 1696b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1697b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1698b5816c88SCedric Chaumont goto out; 1699b5816c88SCedric Chaumont } 1700b0104773SPascal Brand 1701b0104773SPascal Brand /* 1702b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1703b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1704b0104773SPascal Brand * can't restore sync with this API. 1705b0104773SPascal Brand */ 1706b5816c88SCedric Chaumont req_dlen = operation->buffer_offs + srcLen; 1707b0104773SPascal Brand if (*destLen < req_dlen) { 1708b0104773SPascal Brand *destLen = req_dlen; 1709b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1710b5816c88SCedric Chaumont goto out; 1711b0104773SPascal Brand } 1712b0104773SPascal Brand 1713b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 1714afc0c182SBogdan Liulko if (operation->block_size > 1) { 17152c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_authenc_update_payload, 1716afc0c182SBogdan Liulko srcData, srcLen, dst, &tmp_dlen); 1717b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1718b5816c88SCedric Chaumont goto out; 1719b5816c88SCedric Chaumont 1720b0104773SPascal Brand dst += tmp_dlen; 1721b0104773SPascal Brand acc_dlen += tmp_dlen; 1722b0104773SPascal Brand 1723b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 17242c028fdeSJerome Forissier res = _utee_authenc_dec_final(operation->state, 1725afc0c182SBogdan Liulko operation->buffer, 1726afc0c182SBogdan Liulko operation->buffer_offs, dst, 1727afc0c182SBogdan Liulko &tmp_dlen, tag, tagLen); 1728afc0c182SBogdan Liulko } else { 17292c028fdeSJerome Forissier res = _utee_authenc_dec_final(operation->state, srcData, 1730afc0c182SBogdan Liulko srcLen, dst, &tmp_dlen, 1731b5816c88SCedric Chaumont tag, tagLen); 1732afc0c182SBogdan Liulko } 1733b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1734b5816c88SCedric Chaumont goto out; 1735b5816c88SCedric Chaumont 1736b0104773SPascal Brand /* Supplied tagLen should match what we initiated with */ 17377acaf5adSAlbert Schwarzkopf if (tagLen != operation->info.digestLength) 1738b0104773SPascal Brand res = TEE_ERROR_MAC_INVALID; 1739b0104773SPascal Brand 1740b0104773SPascal Brand acc_dlen += tmp_dlen; 1741b0104773SPascal Brand *destLen = acc_dlen; 1742642a1607SCedric Chaumont 1743b5816c88SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 1744b5816c88SCedric Chaumont 1745642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1746642a1607SCedric Chaumont 1747b5816c88SCedric Chaumont out: 1748b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1749b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER && 1750b5816c88SCedric Chaumont res != TEE_ERROR_MAC_INVALID) 1751b5816c88SCedric Chaumont TEE_Panic(res); 1752b0104773SPascal Brand 1753b0104773SPascal Brand return res; 1754b0104773SPascal Brand } 1755b0104773SPascal Brand 1756b0104773SPascal Brand /* Cryptographic Operations API - Asymmetric Functions */ 1757b0104773SPascal Brand 175812e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricEncrypt(TEE_OperationHandle operation, 17598f07fe6fSJerome Forissier const TEE_Attribute *params, 17608f07fe6fSJerome Forissier uint32_t paramCount, const void *srcData, 176179a3c601SCedric Chaumont uint32_t srcLen, void *destData, 176279a3c601SCedric Chaumont uint32_t *destLen) 1763b0104773SPascal Brand { 17646915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 1765e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 17666915bbbbSJens Wiklander uint64_t dl = 0; 1767b0104773SPascal Brand 17686915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 1769b0104773SPascal Brand TEE_Panic(0); 17706915bbbbSJens Wiklander 17716915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 17726915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 17736915bbbbSJens Wiklander 177412e66b6fSCedric Chaumont if (!operation->key1) 1775b0104773SPascal Brand TEE_Panic(0); 177612e66b6fSCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 177712e66b6fSCedric Chaumont TEE_Panic(0); 177812e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_ENCRYPT) 1779b0104773SPascal Brand TEE_Panic(0); 1780b0104773SPascal Brand 1781e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 1782e86f1266SJens Wiklander dl = *destLen; 17832c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 1784e86f1266SJens Wiklander srcLen, destData, &dl); 1785e86f1266SJens Wiklander *destLen = dl; 178612e66b6fSCedric Chaumont 17878844ebfcSPascal Brand if (res != TEE_SUCCESS && 17888844ebfcSPascal Brand res != TEE_ERROR_SHORT_BUFFER && 17898844ebfcSPascal Brand res != TEE_ERROR_BAD_PARAMETERS) 1790b0104773SPascal Brand TEE_Panic(res); 179112e66b6fSCedric Chaumont 1792b0104773SPascal Brand return res; 1793b0104773SPascal Brand } 1794b0104773SPascal Brand 17954f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricEncrypt(TEE_OperationHandle operation, 17964f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 17974f4374c8SJens Wiklander uint32_t paramCount, 17984f4374c8SJens Wiklander const void *srcData, uint32_t srcLen, 17994f4374c8SJens Wiklander void *destData, uint32_t *destLen) 18004f4374c8SJens Wiklander { 18014f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 18024f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 18034f4374c8SJens Wiklander uint64_t dl = 0; 18044f4374c8SJens Wiklander 18054f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 18064f4374c8SJens Wiklander TEE_Panic(0); 18074f4374c8SJens Wiklander 18084f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 18094f4374c8SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 18104f4374c8SJens Wiklander 18114f4374c8SJens Wiklander if (!operation->key1) 18124f4374c8SJens Wiklander TEE_Panic(0); 18134f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 18144f4374c8SJens Wiklander TEE_Panic(0); 18154f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_ENCRYPT) 18164f4374c8SJens Wiklander TEE_Panic(0); 18174f4374c8SJens Wiklander 18184f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 18194f4374c8SJens Wiklander dl = *destLen; 18204f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 18214f4374c8SJens Wiklander srcLen, destData, &dl); 18224f4374c8SJens Wiklander *destLen = dl; 18234f4374c8SJens Wiklander 18244f4374c8SJens Wiklander if (res != TEE_SUCCESS && 18254f4374c8SJens Wiklander res != TEE_ERROR_SHORT_BUFFER && 18264f4374c8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS) 18274f4374c8SJens Wiklander TEE_Panic(res); 18284f4374c8SJens Wiklander 18294f4374c8SJens Wiklander return res; 18304f4374c8SJens Wiklander } 18314f4374c8SJens Wiklander 183212e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricDecrypt(TEE_OperationHandle operation, 18338f07fe6fSJerome Forissier const TEE_Attribute *params, 18348f07fe6fSJerome Forissier uint32_t paramCount, const void *srcData, 183579a3c601SCedric Chaumont uint32_t srcLen, void *destData, 183679a3c601SCedric Chaumont uint32_t *destLen) 1837b0104773SPascal Brand { 18386915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 1839e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 18406915bbbbSJens Wiklander uint64_t dl = 0; 1841b0104773SPascal Brand 18426915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 1843b0104773SPascal Brand TEE_Panic(0); 18446915bbbbSJens Wiklander 18456915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 18466915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 18476915bbbbSJens Wiklander 184812e66b6fSCedric Chaumont if (!operation->key1) 1849b0104773SPascal Brand TEE_Panic(0); 185012e66b6fSCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 185112e66b6fSCedric Chaumont TEE_Panic(0); 185212e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_DECRYPT) 1853b0104773SPascal Brand TEE_Panic(0); 1854b0104773SPascal Brand 1855e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 1856e86f1266SJens Wiklander dl = *destLen; 18572c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 1858e86f1266SJens Wiklander srcLen, destData, &dl); 1859e86f1266SJens Wiklander *destLen = dl; 186012e66b6fSCedric Chaumont 18618844ebfcSPascal Brand if (res != TEE_SUCCESS && 18628844ebfcSPascal Brand res != TEE_ERROR_SHORT_BUFFER && 18638844ebfcSPascal Brand res != TEE_ERROR_BAD_PARAMETERS) 1864b0104773SPascal Brand TEE_Panic(res); 186512e66b6fSCedric Chaumont 1866b0104773SPascal Brand return res; 1867b0104773SPascal Brand } 1868b0104773SPascal Brand 18694f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricDecrypt(TEE_OperationHandle operation, 18704f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 18714f4374c8SJens Wiklander uint32_t paramCount, 18724f4374c8SJens Wiklander const void *srcData, uint32_t srcLen, 18734f4374c8SJens Wiklander void *destData, uint32_t *destLen) 18744f4374c8SJens Wiklander { 18754f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 18764f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 18774f4374c8SJens Wiklander uint64_t dl = 0; 18784f4374c8SJens Wiklander 18794f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 18804f4374c8SJens Wiklander TEE_Panic(0); 18814f4374c8SJens Wiklander 18824f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 18834f4374c8SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 18844f4374c8SJens Wiklander 18854f4374c8SJens Wiklander if (!operation->key1) 18864f4374c8SJens Wiklander TEE_Panic(0); 18874f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 18884f4374c8SJens Wiklander TEE_Panic(0); 18894f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_DECRYPT) 18904f4374c8SJens Wiklander TEE_Panic(0); 18914f4374c8SJens Wiklander 18924f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 18934f4374c8SJens Wiklander dl = *destLen; 18944f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 18954f4374c8SJens Wiklander srcLen, destData, &dl); 18964f4374c8SJens Wiklander *destLen = dl; 18974f4374c8SJens Wiklander 18984f4374c8SJens Wiklander if (res != TEE_SUCCESS && 18994f4374c8SJens Wiklander res != TEE_ERROR_SHORT_BUFFER && 19004f4374c8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS) 19014f4374c8SJens Wiklander TEE_Panic(res); 19024f4374c8SJens Wiklander 19034f4374c8SJens Wiklander return res; 19044f4374c8SJens Wiklander } 19054f4374c8SJens Wiklander 190612e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricSignDigest(TEE_OperationHandle operation, 19078f07fe6fSJerome Forissier const TEE_Attribute *params, 19088f07fe6fSJerome Forissier uint32_t paramCount, const void *digest, 190979a3c601SCedric Chaumont uint32_t digestLen, void *signature, 191079a3c601SCedric Chaumont uint32_t *signatureLen) 1911b0104773SPascal Brand { 19126915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 1913e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 19146915bbbbSJens Wiklander uint64_t sl = 0; 1915b0104773SPascal Brand 19166915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen)) 1917b0104773SPascal Brand TEE_Panic(0); 19186915bbbbSJens Wiklander 19196915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 19206915bbbbSJens Wiklander __utee_check_inout_annotation(signatureLen, sizeof(*signatureLen)); 19216915bbbbSJens Wiklander 192212e66b6fSCedric Chaumont if (!operation->key1) 1923b0104773SPascal Brand TEE_Panic(0); 192412e66b6fSCedric Chaumont if (operation->info.operationClass != 192512e66b6fSCedric Chaumont TEE_OPERATION_ASYMMETRIC_SIGNATURE) 192612e66b6fSCedric Chaumont TEE_Panic(0); 192712e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_SIGN) 1928b0104773SPascal Brand TEE_Panic(0); 1929b0104773SPascal Brand 1930e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 1931e86f1266SJens Wiklander sl = *signatureLen; 19322c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, digest, 1933e86f1266SJens Wiklander digestLen, signature, &sl); 1934e86f1266SJens Wiklander *signatureLen = sl; 193512e66b6fSCedric Chaumont 1936b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER) 1937b0104773SPascal Brand TEE_Panic(res); 193812e66b6fSCedric Chaumont 1939b0104773SPascal Brand return res; 1940b0104773SPascal Brand } 1941b0104773SPascal Brand 19424f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricSignDigest(TEE_OperationHandle operation, 19434f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 19444f4374c8SJens Wiklander uint32_t paramCount, 19454f4374c8SJens Wiklander const void *digest, 19464f4374c8SJens Wiklander uint32_t digestLen, void *signature, 19474f4374c8SJens Wiklander uint32_t *signatureLen) 19484f4374c8SJens Wiklander { 19494f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 19504f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 19514f4374c8SJens Wiklander uint64_t sl = 0; 19524f4374c8SJens Wiklander 19534f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen)) 19544f4374c8SJens Wiklander TEE_Panic(0); 19554f4374c8SJens Wiklander 19564f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 19574f4374c8SJens Wiklander __utee_check_inout_annotation(signatureLen, sizeof(*signatureLen)); 19584f4374c8SJens Wiklander 19594f4374c8SJens Wiklander if (!operation->key1) 19604f4374c8SJens Wiklander TEE_Panic(0); 19614f4374c8SJens Wiklander if (operation->info.operationClass != 19624f4374c8SJens Wiklander TEE_OPERATION_ASYMMETRIC_SIGNATURE) 19634f4374c8SJens Wiklander TEE_Panic(0); 19644f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_SIGN) 19654f4374c8SJens Wiklander TEE_Panic(0); 19664f4374c8SJens Wiklander 19674f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 19684f4374c8SJens Wiklander sl = *signatureLen; 19694f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, digest, 19704f4374c8SJens Wiklander digestLen, signature, &sl); 19714f4374c8SJens Wiklander *signatureLen = sl; 19724f4374c8SJens Wiklander 19734f4374c8SJens Wiklander if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER) 19744f4374c8SJens Wiklander TEE_Panic(res); 19754f4374c8SJens Wiklander 19764f4374c8SJens Wiklander return res; 19774f4374c8SJens Wiklander } 19784f4374c8SJens Wiklander 197912e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation, 19808f07fe6fSJerome Forissier const TEE_Attribute *params, 19818f07fe6fSJerome Forissier uint32_t paramCount, const void *digest, 19828f07fe6fSJerome Forissier uint32_t digestLen, 19838f07fe6fSJerome Forissier const void *signature, 198479a3c601SCedric Chaumont uint32_t signatureLen) 1985b0104773SPascal Brand { 1986b0104773SPascal Brand TEE_Result res; 1987e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 1988b0104773SPascal Brand 198912e66b6fSCedric Chaumont if (operation == TEE_HANDLE_NULL || 199012e66b6fSCedric Chaumont (digest == NULL && digestLen != 0) || 1991b0104773SPascal Brand (signature == NULL && signatureLen != 0)) 1992b0104773SPascal Brand TEE_Panic(0); 19936915bbbbSJens Wiklander 19946915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 19956915bbbbSJens Wiklander 199612e66b6fSCedric Chaumont if (!operation->key1) 1997b0104773SPascal Brand TEE_Panic(0); 199812e66b6fSCedric Chaumont if (operation->info.operationClass != 199912e66b6fSCedric Chaumont TEE_OPERATION_ASYMMETRIC_SIGNATURE) 200012e66b6fSCedric Chaumont TEE_Panic(0); 200112e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_VERIFY) 2002b0104773SPascal Brand TEE_Panic(0); 2003b0104773SPascal Brand 2004e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 20052c028fdeSJerome Forissier res = _utee_asymm_verify(operation->state, ua, paramCount, digest, 200612e66b6fSCedric Chaumont digestLen, signature, signatureLen); 200712e66b6fSCedric Chaumont 2008b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID) 2009b0104773SPascal Brand TEE_Panic(res); 201012e66b6fSCedric Chaumont 2011b0104773SPascal Brand return res; 2012b0104773SPascal Brand } 2013b0104773SPascal Brand 20144f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation, 20154f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 20164f4374c8SJens Wiklander uint32_t paramCount, 20174f4374c8SJens Wiklander const void *digest, 20184f4374c8SJens Wiklander uint32_t digestLen, 20194f4374c8SJens Wiklander const void *signature, 20204f4374c8SJens Wiklander uint32_t signatureLen) 20214f4374c8SJens Wiklander { 20224f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 20234f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 20244f4374c8SJens Wiklander 20254f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen) || 20264f4374c8SJens Wiklander (!signature && signatureLen)) 20274f4374c8SJens Wiklander TEE_Panic(0); 20284f4374c8SJens Wiklander 20294f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 20304f4374c8SJens Wiklander 20314f4374c8SJens Wiklander if (!operation->key1) 20324f4374c8SJens Wiklander TEE_Panic(0); 20334f4374c8SJens Wiklander if (operation->info.operationClass != 20344f4374c8SJens Wiklander TEE_OPERATION_ASYMMETRIC_SIGNATURE) 20354f4374c8SJens Wiklander TEE_Panic(0); 20364f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_VERIFY) 20374f4374c8SJens Wiklander TEE_Panic(0); 20384f4374c8SJens Wiklander 20394f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 20404f4374c8SJens Wiklander res = _utee_asymm_verify(operation->state, ua, paramCount, digest, 20414f4374c8SJens Wiklander digestLen, signature, signatureLen); 20424f4374c8SJens Wiklander 20434f4374c8SJens Wiklander if (res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID) 20444f4374c8SJens Wiklander TEE_Panic(res); 20454f4374c8SJens Wiklander 20464f4374c8SJens Wiklander return res; 20474f4374c8SJens Wiklander } 20484f4374c8SJens Wiklander 2049b0104773SPascal Brand /* Cryptographic Operations API - Key Derivation Functions */ 2050b0104773SPascal Brand 2051b0104773SPascal Brand void TEE_DeriveKey(TEE_OperationHandle operation, 2052b0104773SPascal Brand const TEE_Attribute *params, uint32_t paramCount, 2053b0104773SPascal Brand TEE_ObjectHandle derivedKey) 2054b0104773SPascal Brand { 2055e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 205675d6a373SJens Wiklander struct utee_object_info key_info = { }; 205775d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 2058b0104773SPascal Brand 2059b0104773SPascal Brand if (operation == TEE_HANDLE_NULL || derivedKey == 0) 2060b0104773SPascal Brand TEE_Panic(0); 20616915bbbbSJens Wiklander 20626915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 20636915bbbbSJens Wiklander 20648854d3c6SJerome Forissier if (TEE_ALG_GET_CLASS(operation->info.algorithm) != 20658854d3c6SJerome Forissier TEE_OPERATION_KEY_DERIVATION) 2066b0104773SPascal Brand TEE_Panic(0); 2067b0104773SPascal Brand 2068b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_KEY_DERIVATION) 2069b0104773SPascal Brand TEE_Panic(0); 207084fa9467SCedric Chaumont if (!operation->key1) 207184fa9467SCedric Chaumont TEE_Panic(0); 2072b0104773SPascal Brand if (operation->info.mode != TEE_MODE_DERIVE) 2073b0104773SPascal Brand TEE_Panic(0); 2074b0104773SPascal Brand if ((operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0) 2075b0104773SPascal Brand TEE_Panic(0); 2076b0104773SPascal Brand 20772c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)derivedKey, &key_info); 2078b0104773SPascal Brand if (res != TEE_SUCCESS) 2079b36311adSJerome Forissier TEE_Panic(res); 2080b0104773SPascal Brand 208175d6a373SJens Wiklander if (key_info.obj_type != TEE_TYPE_GENERIC_SECRET) 2082b0104773SPascal Brand TEE_Panic(0); 208375d6a373SJens Wiklander if ((key_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 2084b0104773SPascal Brand TEE_Panic(0); 2085b0104773SPascal Brand 2086e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 20872c028fdeSJerome Forissier res = _utee_cryp_derive_key(operation->state, ua, paramCount, 2088e86f1266SJens Wiklander (unsigned long)derivedKey); 2089b0104773SPascal Brand if (res != TEE_SUCCESS) 2090b0104773SPascal Brand TEE_Panic(res); 2091b0104773SPascal Brand } 2092b0104773SPascal Brand 20934f4374c8SJens Wiklander void __GP11_TEE_DeriveKey(TEE_OperationHandle operation, 20944f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 20954f4374c8SJens Wiklander uint32_t paramCount, TEE_ObjectHandle derivedKey) 20964f4374c8SJens Wiklander { 20974f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 20984f4374c8SJens Wiklander struct utee_object_info key_info = { }; 20994f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 21004f4374c8SJens Wiklander 21014f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || derivedKey == 0) 21024f4374c8SJens Wiklander TEE_Panic(0); 21034f4374c8SJens Wiklander 21044f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 21054f4374c8SJens Wiklander 21064f4374c8SJens Wiklander if (TEE_ALG_GET_CLASS(operation->info.algorithm) != 21074f4374c8SJens Wiklander TEE_OPERATION_KEY_DERIVATION) 21084f4374c8SJens Wiklander TEE_Panic(0); 21094f4374c8SJens Wiklander 21104f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_KEY_DERIVATION) 21114f4374c8SJens Wiklander TEE_Panic(0); 21124f4374c8SJens Wiklander if (!operation->key1) 21134f4374c8SJens Wiklander TEE_Panic(0); 21144f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_DERIVE) 21154f4374c8SJens Wiklander TEE_Panic(0); 21164f4374c8SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0) 21174f4374c8SJens Wiklander TEE_Panic(0); 21184f4374c8SJens Wiklander 21194f4374c8SJens Wiklander res = _utee_cryp_obj_get_info((unsigned long)derivedKey, &key_info); 21204f4374c8SJens Wiklander if (res != TEE_SUCCESS) 21214f4374c8SJens Wiklander TEE_Panic(res); 21224f4374c8SJens Wiklander 21234f4374c8SJens Wiklander if (key_info.obj_type != TEE_TYPE_GENERIC_SECRET) 21244f4374c8SJens Wiklander TEE_Panic(0); 21254f4374c8SJens Wiklander if ((key_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 21264f4374c8SJens Wiklander TEE_Panic(0); 21274f4374c8SJens Wiklander 21284f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 21294f4374c8SJens Wiklander res = _utee_cryp_derive_key(operation->state, ua, paramCount, 21304f4374c8SJens Wiklander (unsigned long)derivedKey); 21314f4374c8SJens Wiklander if (res != TEE_SUCCESS) 21324f4374c8SJens Wiklander TEE_Panic(res); 21334f4374c8SJens Wiklander } 21344f4374c8SJens Wiklander 2135b0104773SPascal Brand /* Cryptographic Operations API - Random Number Generation Functions */ 2136b0104773SPascal Brand 213779a3c601SCedric Chaumont void TEE_GenerateRandom(void *randomBuffer, uint32_t randomBufferLen) 2138b0104773SPascal Brand { 2139b0104773SPascal Brand TEE_Result res; 2140b0104773SPascal Brand 21412c028fdeSJerome Forissier res = _utee_cryp_random_number_generate(randomBuffer, randomBufferLen); 2142b0104773SPascal Brand if (res != TEE_SUCCESS) 2143b0104773SPascal Brand TEE_Panic(res); 2144b0104773SPascal Brand } 2145433c4257SJens Wiklander 2146433c4257SJens Wiklander int rand(void) 2147433c4257SJens Wiklander { 2148433c4257SJens Wiklander int rc; 2149433c4257SJens Wiklander 2150433c4257SJens Wiklander TEE_GenerateRandom(&rc, sizeof(rc)); 2151433c4257SJens Wiklander 2152433c4257SJens Wiklander /* 2153433c4257SJens Wiklander * RAND_MAX is the larges int, INT_MAX which is all bits but the 2154433c4257SJens Wiklander * highest bit set. 2155433c4257SJens Wiklander */ 2156433c4257SJens Wiklander return rc & RAND_MAX; 2157433c4257SJens Wiklander } 215879170ce0SJerome Forissier 215979170ce0SJerome Forissier TEE_Result TEE_IsAlgorithmSupported(uint32_t alg, uint32_t element) 216079170ce0SJerome Forissier { 216179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_AES)) { 216279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) { 216379170ce0SJerome Forissier if (alg == TEE_ALG_AES_ECB_NOPAD) 216479170ce0SJerome Forissier goto check_element_none; 216579170ce0SJerome Forissier } 216679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) { 216779170ce0SJerome Forissier if (alg == TEE_ALG_AES_CBC_NOPAD) 216879170ce0SJerome Forissier goto check_element_none; 216979170ce0SJerome Forissier } 217079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTR)) { 217179170ce0SJerome Forissier if (alg == TEE_ALG_AES_CTR) 217279170ce0SJerome Forissier goto check_element_none; 217379170ce0SJerome Forissier } 217479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTS)) { 217579170ce0SJerome Forissier if (alg == TEE_ALG_AES_CTS) 217679170ce0SJerome Forissier goto check_element_none; 217779170ce0SJerome Forissier } 217879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_XTS)) { 217979170ce0SJerome Forissier if (alg == TEE_ALG_AES_XTS) 218079170ce0SJerome Forissier goto check_element_none; 218179170ce0SJerome Forissier } 218279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC_MAC)) { 218379170ce0SJerome Forissier if (alg == TEE_ALG_AES_CBC_MAC_NOPAD || 218479170ce0SJerome Forissier alg == TEE_ALG_AES_CBC_MAC_PKCS5) 218579170ce0SJerome Forissier goto check_element_none; 218679170ce0SJerome Forissier } 218779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CMAC)) { 218879170ce0SJerome Forissier if (alg == TEE_ALG_AES_CMAC) 218979170ce0SJerome Forissier goto check_element_none; 219079170ce0SJerome Forissier } 219179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CCM)) { 219279170ce0SJerome Forissier if (alg == TEE_ALG_AES_CCM) 219379170ce0SJerome Forissier goto check_element_none; 219479170ce0SJerome Forissier } 219579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_GCM)) { 219679170ce0SJerome Forissier if (alg == TEE_ALG_AES_GCM) 219779170ce0SJerome Forissier goto check_element_none; 219879170ce0SJerome Forissier } 219979170ce0SJerome Forissier } 220079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DES)) { 220179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) { 220279170ce0SJerome Forissier if (alg == TEE_ALG_DES_ECB_NOPAD || 220379170ce0SJerome Forissier alg == TEE_ALG_DES3_ECB_NOPAD) 220479170ce0SJerome Forissier goto check_element_none; 220579170ce0SJerome Forissier } 220679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) { 220779170ce0SJerome Forissier if (alg == TEE_ALG_DES_CBC_NOPAD || 220879170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_NOPAD) 220979170ce0SJerome Forissier goto check_element_none; 221079170ce0SJerome Forissier } 221179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC_MAC)) { 221279170ce0SJerome Forissier if (alg == TEE_ALG_DES_CBC_MAC_NOPAD || 221379170ce0SJerome Forissier alg == TEE_ALG_DES_CBC_MAC_PKCS5 || 221479170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_MAC_NOPAD || 221579170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_MAC_PKCS5) 221679170ce0SJerome Forissier goto check_element_none; 221779170ce0SJerome Forissier } 221879170ce0SJerome Forissier } 221979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) { 222079170ce0SJerome Forissier if (alg == TEE_ALG_MD5) 222179170ce0SJerome Forissier goto check_element_none; 222279170ce0SJerome Forissier } 222379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 222479170ce0SJerome Forissier if (alg == TEE_ALG_SHA1) 222579170ce0SJerome Forissier goto check_element_none; 222679170ce0SJerome Forissier } 222779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 222879170ce0SJerome Forissier if (alg == TEE_ALG_SHA224) 222979170ce0SJerome Forissier goto check_element_none; 223079170ce0SJerome Forissier } 223179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 223279170ce0SJerome Forissier if (alg == TEE_ALG_SHA256) 223379170ce0SJerome Forissier goto check_element_none; 223479170ce0SJerome Forissier } 223579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) { 223679170ce0SJerome Forissier if (alg == TEE_ALG_SHA384) 223779170ce0SJerome Forissier goto check_element_none; 223879170ce0SJerome Forissier } 223979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) { 224079170ce0SJerome Forissier if (alg == TEE_ALG_SHA512) 224179170ce0SJerome Forissier goto check_element_none; 224279170ce0SJerome Forissier } 224379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5) && IS_ENABLED(CFG_CRYPTO_SHA1)) { 224479170ce0SJerome Forissier if (alg == TEE_ALG_MD5SHA1) 224579170ce0SJerome Forissier goto check_element_none; 224679170ce0SJerome Forissier } 224779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_HMAC)) { 224879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) { 224979170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_MD5) 225079170ce0SJerome Forissier goto check_element_none; 225179170ce0SJerome Forissier } 225279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 225379170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA1) 225479170ce0SJerome Forissier goto check_element_none; 225579170ce0SJerome Forissier } 225679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 225779170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA224) 225879170ce0SJerome Forissier goto check_element_none; 225979170ce0SJerome Forissier } 226079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 226179170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA256) 226279170ce0SJerome Forissier goto check_element_none; 226379170ce0SJerome Forissier } 226479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) { 226579170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA384) 226679170ce0SJerome Forissier goto check_element_none; 226779170ce0SJerome Forissier } 226879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) { 226979170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA512) 227079170ce0SJerome Forissier goto check_element_none; 227179170ce0SJerome Forissier } 227279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM3)) { 227379170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SM3) 227479170ce0SJerome Forissier goto check_element_none; 227579170ce0SJerome Forissier } 227679170ce0SJerome Forissier } 227779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM3)) { 227879170ce0SJerome Forissier if (alg == TEE_ALG_SM3) 227979170ce0SJerome Forissier goto check_element_none; 228079170ce0SJerome Forissier } 228179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM4)) { 228279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) { 228379170ce0SJerome Forissier if (alg == TEE_ALG_SM4_ECB_NOPAD) 228479170ce0SJerome Forissier goto check_element_none; 228579170ce0SJerome Forissier } 228679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) { 228779170ce0SJerome Forissier if (alg == TEE_ALG_SM4_CBC_NOPAD) 228879170ce0SJerome Forissier goto check_element_none; 228979170ce0SJerome Forissier } 229079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTR)) { 229179170ce0SJerome Forissier if (alg == TEE_ALG_SM4_CTR) 229279170ce0SJerome Forissier goto check_element_none; 229379170ce0SJerome Forissier } 2294696f56acSPingan Xie if (IS_ENABLED(CFG_CRYPTO_XTS)) { 2295696f56acSPingan Xie if (alg == TEE_ALG_SM4_XTS) 2296696f56acSPingan Xie goto check_element_none; 2297696f56acSPingan Xie } 229879170ce0SJerome Forissier } 229979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_RSA)) { 230079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) { 230179170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5) 230279170ce0SJerome Forissier goto check_element_none; 230379170ce0SJerome Forissier } 230479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 230579170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA1 || 230679170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1 || 230779170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1) 230879170ce0SJerome Forissier goto check_element_none; 230979170ce0SJerome Forissier } 231079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5) && IS_ENABLED(CFG_CRYPTO_SHA1)) { 231179170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5SHA1) 231279170ce0SJerome Forissier goto check_element_none; 231379170ce0SJerome Forissier } 231479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 231579170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA224 || 231679170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224 || 231779170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224) 231879170ce0SJerome Forissier goto check_element_none; 231979170ce0SJerome Forissier } 232079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 232179170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA256 || 232279170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 || 232379170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256) 232479170ce0SJerome Forissier goto check_element_none; 232579170ce0SJerome Forissier } 232679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) { 232779170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA384 || 232879170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384 || 232979170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384) 233079170ce0SJerome Forissier goto check_element_none; 233179170ce0SJerome Forissier } 233279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) { 233379170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA512 || 233479170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512 || 233579170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512) 233679170ce0SJerome Forissier goto check_element_none; 233779170ce0SJerome Forissier } 233879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_RSASSA_NA1)) { 233979170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5) 234079170ce0SJerome Forissier goto check_element_none; 234179170ce0SJerome Forissier } 234279170ce0SJerome Forissier if (alg == TEE_ALG_RSA_NOPAD) 234379170ce0SJerome Forissier goto check_element_none; 234479170ce0SJerome Forissier } 234579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DSA)) { 234679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 234779170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA1) 234879170ce0SJerome Forissier goto check_element_none; 234979170ce0SJerome Forissier } 235079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 235179170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA224) 235279170ce0SJerome Forissier goto check_element_none; 235379170ce0SJerome Forissier } 235479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 235579170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA256) 235679170ce0SJerome Forissier goto check_element_none; 235779170ce0SJerome Forissier } 235879170ce0SJerome Forissier } 235979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DH)) { 236079170ce0SJerome Forissier if (alg == TEE_ALG_DH_DERIVE_SHARED_SECRET) 236179170ce0SJerome Forissier goto check_element_none; 236279170ce0SJerome Forissier } 236379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECC)) { 2364fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P192 || 2365fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P192 || 2366fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2367fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA1) && 236879170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P192) 236979170ce0SJerome Forissier return TEE_SUCCESS; 2370fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P224 || 2371fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P224 || 2372fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2373fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA224) && 237479170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P224) 237579170ce0SJerome Forissier return TEE_SUCCESS; 2376fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P256 || 2377fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P256 || 2378fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2379fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA256) && 238079170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P256) 238179170ce0SJerome Forissier return TEE_SUCCESS; 2382fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P384 || 2383fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P384 || 2384fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2385fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA384) && 238679170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P384) 238779170ce0SJerome Forissier return TEE_SUCCESS; 2388fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P521 || 2389fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P521 || 2390fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2391fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA512) && 239279170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P521) 239379170ce0SJerome Forissier return TEE_SUCCESS; 239479170ce0SJerome Forissier } 239579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_DSA)) { 239679170ce0SJerome Forissier if (alg == TEE_ALG_SM2_DSA_SM3 && element == TEE_ECC_CURVE_SM2) 239779170ce0SJerome Forissier return TEE_SUCCESS; 239879170ce0SJerome Forissier } 239979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_KEP)) { 240079170ce0SJerome Forissier if (alg == TEE_ALG_SM2_KEP && element == TEE_ECC_CURVE_SM2) 240179170ce0SJerome Forissier return TEE_SUCCESS; 240279170ce0SJerome Forissier } 240379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_PKE)) { 240479170ce0SJerome Forissier if (alg == TEE_ALG_SM2_PKE && element == TEE_ECC_CURVE_SM2) 240579170ce0SJerome Forissier return TEE_SUCCESS; 240679170ce0SJerome Forissier } 24073f61056dSSohaib ul Hassan if (IS_ENABLED(CFG_CRYPTO_X25519)) { 24083f61056dSSohaib ul Hassan if (alg == TEE_ALG_X25519 && element == TEE_ECC_CURVE_25519) 24093f61056dSSohaib ul Hassan return TEE_SUCCESS; 24103f61056dSSohaib ul Hassan } 2411e1f9cee7SSergiy Kibrik if (IS_ENABLED(CFG_CRYPTO_ED25519)) { 2412e1f9cee7SSergiy Kibrik if (alg == TEE_ALG_ED25519 && element == TEE_ECC_CURVE_25519) 2413e1f9cee7SSergiy Kibrik return TEE_SUCCESS; 2414e1f9cee7SSergiy Kibrik } 241579170ce0SJerome Forissier 241679170ce0SJerome Forissier return TEE_ERROR_NOT_SUPPORTED; 241779170ce0SJerome Forissier check_element_none: 241879170ce0SJerome Forissier if (element == TEE_CRYPTO_ELEMENT_NONE) 241979170ce0SJerome Forissier return TEE_SUCCESS; 242079170ce0SJerome Forissier return TEE_ERROR_NOT_SUPPORTED; 242179170ce0SJerome Forissier } 2422