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 */ 624ea7613SJens Wiklander #include <assert.h> 779170ce0SJerome Forissier #include <config.h> 8b0104773SPascal Brand #include <stdlib.h> 9b0104773SPascal Brand #include <string.h> 10b796ebf3SJerome Forissier #include <string_ext.h> 11b0104773SPascal Brand #include <tee_api.h> 128854d3c6SJerome Forissier #include <tee_api_defines_extensions.h> 13b0104773SPascal Brand #include <tee_internal_api_extensions.h> 14b0104773SPascal Brand #include <utee_syscalls.h> 15b0104773SPascal Brand #include <utee_defines.h> 16fc26c92aSJens Wiklander #include <util.h> 17e86f1266SJens Wiklander #include "tee_api_private.h" 18b0104773SPascal Brand 19b0104773SPascal Brand struct __TEE_OperationHandle { 20b0104773SPascal Brand TEE_OperationInfo info; 21b0104773SPascal Brand TEE_ObjectHandle key1; 22b0104773SPascal Brand TEE_ObjectHandle key2; 23642a1607SCedric Chaumont uint32_t operationState;/* Operation state : INITIAL or ACTIVE */ 2424ea7613SJens Wiklander 2524ea7613SJens Wiklander /* 2624ea7613SJens Wiklander * buffer to collect complete blocks or to keep a complete digest 2724ea7613SJens Wiklander * for TEE_DigestExtract(). 2824ea7613SJens Wiklander */ 2924ea7613SJens Wiklander uint8_t *buffer; 30b0104773SPascal Brand bool buffer_two_blocks; /* True if two blocks need to be buffered */ 31b0104773SPascal Brand size_t block_size; /* Block size of cipher */ 32b0104773SPascal Brand size_t buffer_offs; /* Offset in buffer */ 33b0104773SPascal Brand uint32_t state; /* Handle to state in TEE Core */ 34b0104773SPascal Brand }; 35b0104773SPascal Brand 36b0104773SPascal Brand /* Cryptographic Operations API - Generic Operation Functions */ 37b0104773SPascal Brand 38b0104773SPascal Brand TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation, 39b0104773SPascal Brand uint32_t algorithm, uint32_t mode, 40b0104773SPascal Brand uint32_t maxKeySize) 41b0104773SPascal Brand { 42b0104773SPascal Brand TEE_Result res; 43b0104773SPascal Brand TEE_OperationHandle op = TEE_HANDLE_NULL; 44b0104773SPascal Brand uint32_t handle_state = 0; 45b0104773SPascal Brand size_t block_size = 1; 46b0104773SPascal Brand uint32_t req_key_usage; 47b0104773SPascal Brand bool with_private_key = false; 48b0104773SPascal Brand bool buffer_two_blocks = false; 49b0104773SPascal Brand 509b52c538SCedric Chaumont if (!operation) 51b0104773SPascal Brand TEE_Panic(0); 52b0104773SPascal Brand 53696f56acSPingan Xie if (algorithm == TEE_ALG_AES_XTS || algorithm == TEE_ALG_SM2_KEP || 54696f56acSPingan Xie algorithm == TEE_ALG_SM4_XTS) 55b0104773SPascal Brand handle_state = TEE_HANDLE_FLAG_EXPECT_TWO_KEYS; 56b0104773SPascal Brand 57218d9055SCedric Chaumont /* Check algorithm max key size */ 58218d9055SCedric Chaumont switch (algorithm) { 59218d9055SCedric Chaumont case TEE_ALG_DSA_SHA1: 60218d9055SCedric Chaumont if (maxKeySize < 512) 61218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 62218d9055SCedric Chaumont if (maxKeySize > 1024) 63218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 64218d9055SCedric Chaumont if (maxKeySize % 64 != 0) 65218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 66218d9055SCedric Chaumont break; 67218d9055SCedric Chaumont 68218d9055SCedric Chaumont case TEE_ALG_DSA_SHA224: 69218d9055SCedric Chaumont if (maxKeySize != 2048) 70218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 71218d9055SCedric Chaumont break; 72218d9055SCedric Chaumont 73218d9055SCedric Chaumont case TEE_ALG_DSA_SHA256: 74218d9055SCedric Chaumont if (maxKeySize != 2048 && maxKeySize != 3072) 75218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 76218d9055SCedric Chaumont break; 77218d9055SCedric Chaumont 78fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA1: 79fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P192: 80fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P192: 811220586eSCedric Chaumont if (maxKeySize != 192) 821220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 831220586eSCedric Chaumont break; 841220586eSCedric Chaumont 85fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA224: 86fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P224: 87fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P224: 881220586eSCedric Chaumont if (maxKeySize != 224) 891220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 901220586eSCedric Chaumont break; 911220586eSCedric Chaumont 92fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA256: 93fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P256: 94fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P256: 9591fc6bd8SJerome Forissier case TEE_ALG_SM2_PKE: 960f151943SJerome Forissier case TEE_ALG_SM2_DSA_SM3: 971220586eSCedric Chaumont if (maxKeySize != 256) 981220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 991220586eSCedric Chaumont break; 1001220586eSCedric Chaumont 1015b385b3fSJerome Forissier case TEE_ALG_SM2_KEP: 1025b385b3fSJerome Forissier /* Two 256-bit keys */ 1035b385b3fSJerome Forissier if (maxKeySize != 512) 1045b385b3fSJerome Forissier return TEE_ERROR_NOT_SUPPORTED; 1055b385b3fSJerome Forissier break; 1065b385b3fSJerome Forissier 107fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA384: 108fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P384: 109fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P384: 1101220586eSCedric Chaumont if (maxKeySize != 384) 1111220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 1121220586eSCedric Chaumont break; 1131220586eSCedric Chaumont 114fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA512: 115fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P521: 116fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P521: 1171220586eSCedric Chaumont if (maxKeySize != 521) 1181220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED; 1191220586eSCedric Chaumont break; 120fe2fd3ffSJens Wiklander 121fe2fd3ffSJens Wiklander case TEE_ALG_ECDH_DERIVE_SHARED_SECRET: 122fe2fd3ffSJens Wiklander if (maxKeySize > 521) 123fe2fd3ffSJens Wiklander return TEE_ERROR_NOT_SUPPORTED; 124fe2fd3ffSJens Wiklander break; 125fe2fd3ffSJens Wiklander 126e1f9cee7SSergiy Kibrik case TEE_ALG_ED25519: 1273f61056dSSohaib ul Hassan case TEE_ALG_X25519: 1283f61056dSSohaib ul Hassan if (maxKeySize != 256) 1293f61056dSSohaib ul Hassan return TEE_ERROR_NOT_SUPPORTED; 1303f61056dSSohaib ul Hassan break; 131218d9055SCedric Chaumont default: 132218d9055SCedric Chaumont break; 133218d9055SCedric Chaumont } 134218d9055SCedric Chaumont 135b291c8ecSVincent Mailhol /* Check algorithm mode */ 136b0104773SPascal Brand switch (algorithm) { 137b0104773SPascal Brand case TEE_ALG_AES_CTS: 138b0104773SPascal Brand case TEE_ALG_AES_XTS: 139696f56acSPingan Xie case TEE_ALG_SM4_XTS: 140b0104773SPascal Brand buffer_two_blocks = true; 141919a5a68SJerome Forissier fallthrough; 1424bd53c54SJerome Forissier case TEE_ALG_AES_ECB_NOPAD: 143b0104773SPascal Brand case TEE_ALG_AES_CBC_NOPAD: 144b0104773SPascal Brand case TEE_ALG_AES_CCM: 145b0104773SPascal Brand case TEE_ALG_DES_ECB_NOPAD: 146b0104773SPascal Brand case TEE_ALG_DES_CBC_NOPAD: 147b0104773SPascal Brand case TEE_ALG_DES3_ECB_NOPAD: 148b0104773SPascal Brand case TEE_ALG_DES3_CBC_NOPAD: 149ade6f848SJerome Forissier case TEE_ALG_SM4_ECB_NOPAD: 150ade6f848SJerome Forissier case TEE_ALG_SM4_CBC_NOPAD: 151ade6f848SJerome Forissier case TEE_ALG_SM4_CTR: 152b0104773SPascal Brand if (TEE_ALG_GET_MAIN_ALG(algorithm) == TEE_MAIN_ALGO_AES) 153b0104773SPascal Brand block_size = TEE_AES_BLOCK_SIZE; 154ade6f848SJerome Forissier else if (TEE_ALG_GET_MAIN_ALG(algorithm) == TEE_MAIN_ALGO_SM4) 155ade6f848SJerome Forissier block_size = TEE_SM4_BLOCK_SIZE; 156b0104773SPascal Brand else 157b0104773SPascal Brand block_size = TEE_DES_BLOCK_SIZE; 158919a5a68SJerome Forissier fallthrough; 15957aabac5SBogdan Liulko case TEE_ALG_AES_CTR: 160afc0c182SBogdan Liulko case TEE_ALG_AES_GCM: 161b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) 162b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT; 163b0104773SPascal Brand else if (mode == TEE_MODE_DECRYPT) 164b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT; 165b0104773SPascal Brand else 166b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 167b0104773SPascal Brand break; 168b0104773SPascal Brand 1696a2e0a9fSGabor Szekely #if defined(CFG_CRYPTO_RSASSA_NA1) 1706a2e0a9fSGabor Szekely case TEE_ALG_RSASSA_PKCS1_V1_5: 1716a2e0a9fSGabor Szekely #endif 172b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_MD5: 173b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1: 174b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224: 175b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256: 176b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384: 177b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512: 178f5c3d85aSJulien Masson case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_MD5: 179b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: 180b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: 181b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: 182b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: 183b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: 184b0104773SPascal Brand case TEE_ALG_DSA_SHA1: 185218d9055SCedric Chaumont case TEE_ALG_DSA_SHA224: 186218d9055SCedric Chaumont case TEE_ALG_DSA_SHA256: 187fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA1: 188fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA224: 189fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA256: 190fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA384: 191fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA512: 192fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P192: 193fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P224: 194fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P256: 195fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P384: 196fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P521: 1970f151943SJerome Forissier case TEE_ALG_SM2_DSA_SM3: 198e1f9cee7SSergiy Kibrik case TEE_ALG_ED25519: 199b0104773SPascal Brand if (mode == TEE_MODE_SIGN) { 200b0104773SPascal Brand with_private_key = true; 201b0104773SPascal Brand req_key_usage = TEE_USAGE_SIGN; 202b0104773SPascal Brand } else if (mode == TEE_MODE_VERIFY) { 203b0104773SPascal Brand req_key_usage = TEE_USAGE_VERIFY; 204b0104773SPascal Brand } else { 205b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 206b0104773SPascal Brand } 207b0104773SPascal Brand break; 208b0104773SPascal Brand 209b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_V1_5: 210f5c3d85aSJulien Masson case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_MD5: 211b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1: 212b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224: 213b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256: 214b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384: 215b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512: 21691fc6bd8SJerome Forissier case TEE_ALG_SM2_PKE: 217b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) { 218b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT; 219b0104773SPascal Brand } else if (mode == TEE_MODE_DECRYPT) { 220b0104773SPascal Brand with_private_key = true; 221b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT; 222b0104773SPascal Brand } else { 223b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 224b0104773SPascal Brand } 225b0104773SPascal Brand break; 226b0104773SPascal Brand 227b0104773SPascal Brand case TEE_ALG_RSA_NOPAD: 228b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) { 229b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT | TEE_USAGE_VERIFY; 230b0104773SPascal Brand } else if (mode == TEE_MODE_DECRYPT) { 231b0104773SPascal Brand with_private_key = true; 232b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT | TEE_USAGE_SIGN; 233b0104773SPascal Brand } else { 234b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 235b0104773SPascal Brand } 236b0104773SPascal Brand break; 237b0104773SPascal Brand 238b0104773SPascal Brand case TEE_ALG_DH_DERIVE_SHARED_SECRET: 239fe2fd3ffSJens Wiklander case TEE_ALG_ECDH_DERIVE_SHARED_SECRET: 240fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P192: 241fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P224: 242fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P256: 243fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P384: 244fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P521: 245cdb198a7SJerome Forissier case TEE_ALG_HKDF_MD5_DERIVE_KEY: 246cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA1_DERIVE_KEY: 247cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA224_DERIVE_KEY: 248cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA256_DERIVE_KEY: 249cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA384_DERIVE_KEY: 250cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA512_DERIVE_KEY: 2518854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA1_DERIVE_KEY: 2528854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA224_DERIVE_KEY: 2538854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA256_DERIVE_KEY: 2548854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA384_DERIVE_KEY: 2558854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA512_DERIVE_KEY: 2560f2293b7SJerome Forissier case TEE_ALG_PBKDF2_HMAC_SHA1_DERIVE_KEY: 2575b385b3fSJerome Forissier case TEE_ALG_SM2_KEP: 2583f61056dSSohaib ul Hassan case TEE_ALG_X25519: 259b0104773SPascal Brand if (mode != TEE_MODE_DERIVE) 260b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 261b0104773SPascal Brand with_private_key = true; 262b0104773SPascal Brand req_key_usage = TEE_USAGE_DERIVE; 263b0104773SPascal Brand break; 264b0104773SPascal Brand 265b0104773SPascal Brand case TEE_ALG_MD5: 266b0104773SPascal Brand case TEE_ALG_SHA1: 267b0104773SPascal Brand case TEE_ALG_SHA224: 268b0104773SPascal Brand case TEE_ALG_SHA256: 269b0104773SPascal Brand case TEE_ALG_SHA384: 270b0104773SPascal Brand case TEE_ALG_SHA512: 27124ea7613SJens Wiklander case TEE_ALG_SHA3_224: 27224ea7613SJens Wiklander case TEE_ALG_SHA3_256: 27324ea7613SJens Wiklander case TEE_ALG_SHA3_384: 27424ea7613SJens Wiklander case TEE_ALG_SHA3_512: 27524ea7613SJens Wiklander case TEE_ALG_SHAKE128: 27624ea7613SJens Wiklander case TEE_ALG_SHAKE256: 27747645577SJerome Forissier case TEE_ALG_SM3: 278b0104773SPascal Brand if (mode != TEE_MODE_DIGEST) 279b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 28005304565SCedric Chaumont /* v1.1: flags always set for digest operations */ 281b0104773SPascal Brand handle_state |= TEE_HANDLE_FLAG_KEY_SET; 282b0104773SPascal Brand req_key_usage = 0; 283b0104773SPascal Brand break; 284b0104773SPascal Brand 285b0104773SPascal Brand case TEE_ALG_DES_CBC_MAC_NOPAD: 286b0104773SPascal Brand case TEE_ALG_AES_CBC_MAC_NOPAD: 287b0104773SPascal Brand case TEE_ALG_AES_CBC_MAC_PKCS5: 288b0104773SPascal Brand case TEE_ALG_AES_CMAC: 289b0104773SPascal Brand case TEE_ALG_DES_CBC_MAC_PKCS5: 290b0104773SPascal Brand case TEE_ALG_DES3_CBC_MAC_NOPAD: 291b0104773SPascal Brand case TEE_ALG_DES3_CBC_MAC_PKCS5: 292eee637e7SAlexander Zakharov case TEE_ALG_DES3_CMAC: 293b0104773SPascal Brand case TEE_ALG_HMAC_MD5: 294b0104773SPascal Brand case TEE_ALG_HMAC_SHA1: 295b0104773SPascal Brand case TEE_ALG_HMAC_SHA224: 296b0104773SPascal Brand case TEE_ALG_HMAC_SHA256: 297b0104773SPascal Brand case TEE_ALG_HMAC_SHA384: 298b0104773SPascal Brand case TEE_ALG_HMAC_SHA512: 299260b4028SJens Wiklander case TEE_ALG_HMAC_SHA3_224: 300260b4028SJens Wiklander case TEE_ALG_HMAC_SHA3_256: 301260b4028SJens Wiklander case TEE_ALG_HMAC_SHA3_384: 302260b4028SJens Wiklander case TEE_ALG_HMAC_SHA3_512: 30347645577SJerome Forissier case TEE_ALG_HMAC_SM3: 304b0104773SPascal Brand if (mode != TEE_MODE_MAC) 305b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 306b0104773SPascal Brand req_key_usage = TEE_USAGE_MAC; 307b0104773SPascal Brand break; 308b0104773SPascal Brand 309b0104773SPascal Brand default: 310b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 311b0104773SPascal Brand } 312b0104773SPascal Brand 313b66f219bSJens Wiklander op = TEE_Malloc(sizeof(*op), TEE_MALLOC_FILL_ZERO); 3149b52c538SCedric Chaumont if (!op) 315b0104773SPascal Brand return TEE_ERROR_OUT_OF_MEMORY; 316b0104773SPascal Brand 317b0104773SPascal Brand op->info.algorithm = algorithm; 318b0104773SPascal Brand op->info.operationClass = TEE_ALG_GET_CLASS(algorithm); 3196a2e0a9fSGabor Szekely #ifdef CFG_CRYPTO_RSASSA_NA1 3206a2e0a9fSGabor Szekely if (algorithm == TEE_ALG_RSASSA_PKCS1_V1_5) 3216a2e0a9fSGabor Szekely op->info.operationClass = TEE_OPERATION_ASYMMETRIC_SIGNATURE; 3226a2e0a9fSGabor Szekely #endif 323b0104773SPascal Brand op->info.mode = mode; 3242e5e6460SAlbert Schwarzkopf op->info.digestLength = TEE_ALG_GET_DIGEST_SIZE(algorithm); 325b0104773SPascal Brand op->info.maxKeySize = maxKeySize; 326b0104773SPascal Brand op->info.requiredKeyUsage = req_key_usage; 327b0104773SPascal Brand op->info.handleState = handle_state; 328b0104773SPascal Brand 32924ea7613SJens Wiklander /* 33024ea7613SJens Wiklander * Needed to buffer the digest if TEE_DigestExtract() doesn't 33124ea7613SJens Wiklander * retrieve the entire digest in one go. 33224ea7613SJens Wiklander */ 33324ea7613SJens Wiklander if (op->info.operationClass == TEE_OPERATION_DIGEST) 33424ea7613SJens Wiklander block_size = op->info.digestLength; 33524ea7613SJens Wiklander 336b0104773SPascal Brand if (block_size > 1) { 337b0104773SPascal Brand size_t buffer_size = block_size; 338b0104773SPascal Brand 339b0104773SPascal Brand if (buffer_two_blocks) 340b0104773SPascal Brand buffer_size *= 2; 341b0104773SPascal Brand 3429b52c538SCedric Chaumont op->buffer = TEE_Malloc(buffer_size, 3439b52c538SCedric Chaumont TEE_USER_MEM_HINT_NO_FILL_ZERO); 344b0104773SPascal Brand if (op->buffer == NULL) { 345b0104773SPascal Brand res = TEE_ERROR_OUT_OF_MEMORY; 346b66f219bSJens Wiklander goto out; 347b0104773SPascal Brand } 348b0104773SPascal Brand } 349b0104773SPascal Brand op->block_size = block_size; 350b0104773SPascal Brand op->buffer_two_blocks = buffer_two_blocks; 351b0104773SPascal Brand 352b0104773SPascal Brand if (TEE_ALG_GET_CLASS(algorithm) != TEE_OPERATION_DIGEST) { 353b0104773SPascal Brand uint32_t mks = maxKeySize; 354b0104773SPascal Brand TEE_ObjectType key_type = TEE_ALG_GET_KEY_TYPE(algorithm, 355b0104773SPascal Brand with_private_key); 356b0104773SPascal Brand 357b0104773SPascal Brand /* 358b0104773SPascal Brand * If two keys are expected the max key size is the sum of 359b0104773SPascal Brand * the size of both keys. 360b0104773SPascal Brand */ 361b0104773SPascal Brand if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) 362b0104773SPascal Brand mks /= 2; 363b0104773SPascal Brand 364b0104773SPascal Brand res = TEE_AllocateTransientObject(key_type, mks, &op->key1); 365b0104773SPascal Brand if (res != TEE_SUCCESS) 366b66f219bSJens Wiklander goto out; 367b0104773SPascal Brand 36805304565SCedric Chaumont if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) { 3699b52c538SCedric Chaumont res = TEE_AllocateTransientObject(key_type, mks, 370b0104773SPascal Brand &op->key2); 371b0104773SPascal Brand if (res != TEE_SUCCESS) 372b66f219bSJens Wiklander goto out; 373b0104773SPascal Brand } 374b0104773SPascal Brand } 375b0104773SPascal Brand 3762c028fdeSJerome Forissier res = _utee_cryp_state_alloc(algorithm, mode, (unsigned long)op->key1, 377e86f1266SJens Wiklander (unsigned long)op->key2, &op->state); 378b66f219bSJens Wiklander if (res != TEE_SUCCESS) 379b66f219bSJens Wiklander goto out; 380b0104773SPascal Brand 38105304565SCedric Chaumont /* 38205304565SCedric Chaumont * Initialize digest operations 38305304565SCedric Chaumont * Other multi-stage operations initialized w/ TEE_xxxInit functions 38405304565SCedric Chaumont * Non-applicable on asymmetric operations 38505304565SCedric Chaumont */ 38605304565SCedric Chaumont if (TEE_ALG_GET_CLASS(algorithm) == TEE_OPERATION_DIGEST) { 3872c028fdeSJerome Forissier res = _utee_hash_init(op->state, NULL, 0); 38805304565SCedric Chaumont if (res != TEE_SUCCESS) 389b66f219bSJens Wiklander goto out; 39005304565SCedric Chaumont /* v1.1: flags always set for digest operations */ 39105304565SCedric Chaumont op->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 39205304565SCedric Chaumont } 39305304565SCedric Chaumont 394642a1607SCedric Chaumont op->operationState = TEE_OPERATION_STATE_INITIAL; 395642a1607SCedric Chaumont 396b0104773SPascal Brand *operation = op; 397b0104773SPascal Brand 398b66f219bSJens Wiklander out: 399b66f219bSJens Wiklander if (res != TEE_SUCCESS) { 400b66f219bSJens Wiklander if (res != TEE_ERROR_OUT_OF_MEMORY && 4019b52c538SCedric Chaumont res != TEE_ERROR_NOT_SUPPORTED) 402b36311adSJerome Forissier TEE_Panic(res); 403b66f219bSJens Wiklander if (op) { 404b66f219bSJens Wiklander if (op->state) { 405b66f219bSJens Wiklander TEE_FreeOperation(op); 406b66f219bSJens Wiklander } else { 407b66f219bSJens Wiklander TEE_Free(op->buffer); 408b66f219bSJens Wiklander TEE_FreeTransientObject(op->key1); 409b66f219bSJens Wiklander TEE_FreeTransientObject(op->key2); 410b66f219bSJens Wiklander TEE_Free(op); 411b66f219bSJens Wiklander } 412b66f219bSJens Wiklander } 413b66f219bSJens Wiklander } 414b66f219bSJens Wiklander 415b0104773SPascal Brand return res; 416b0104773SPascal Brand } 417b0104773SPascal Brand 418b0104773SPascal Brand void TEE_FreeOperation(TEE_OperationHandle operation) 419b0104773SPascal Brand { 420e889e80bSCedric Chaumont TEE_Result res; 421e889e80bSCedric Chaumont 422e889e80bSCedric Chaumont if (operation == TEE_HANDLE_NULL) 423c036e912SJens Wiklander return; 424e889e80bSCedric Chaumont 425b0104773SPascal Brand /* 426b0104773SPascal Brand * Note that keys should not be freed here, since they are 427b0104773SPascal Brand * claimed by the operation they will be freed by 428b0104773SPascal Brand * utee_cryp_state_free(). 429b0104773SPascal Brand */ 4302c028fdeSJerome Forissier res = _utee_cryp_state_free(operation->state); 431e889e80bSCedric Chaumont if (res != TEE_SUCCESS) 432b36311adSJerome Forissier TEE_Panic(res); 433e889e80bSCedric Chaumont 434b0104773SPascal Brand TEE_Free(operation->buffer); 435b0104773SPascal Brand TEE_Free(operation); 436b0104773SPascal Brand } 437b0104773SPascal Brand 438c036e912SJens Wiklander void __GP11_TEE_FreeOperation(TEE_OperationHandle operation) 439c036e912SJens Wiklander { 440c036e912SJens Wiklander if (operation == TEE_HANDLE_NULL) 441c036e912SJens Wiklander TEE_Panic(0); 442c036e912SJens Wiklander TEE_FreeOperation(operation); 443c036e912SJens Wiklander } 444c036e912SJens Wiklander 445b0104773SPascal Brand void TEE_GetOperationInfo(TEE_OperationHandle operation, 446b0104773SPascal Brand TEE_OperationInfo *operationInfo) 447b0104773SPascal Brand { 448b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 449b0104773SPascal Brand TEE_Panic(0); 450b0104773SPascal Brand 4516915bbbbSJens Wiklander __utee_check_out_annotation(operationInfo, sizeof(*operationInfo)); 452b0104773SPascal Brand 453b0104773SPascal Brand *operationInfo = operation->info; 454bac3a8a7SJens Wiklander if (operationInfo->handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) { 455bac3a8a7SJens Wiklander operationInfo->keySize = 0; 456bac3a8a7SJens Wiklander operationInfo->requiredKeyUsage = 0; 457bac3a8a7SJens Wiklander } 458b0104773SPascal Brand } 459b0104773SPascal Brand 460ee2f75afSJens Wiklander TEE_Result TEE_GetOperationInfoMultiple(TEE_OperationHandle op, 461ee2f75afSJens Wiklander TEE_OperationInfoMultiple *op_info, 462cb98b7b2SJens Wiklander size_t *size) 46305304565SCedric Chaumont { 46405304565SCedric Chaumont TEE_Result res = TEE_SUCCESS; 465ee2f75afSJens Wiklander TEE_ObjectInfo kinfo = { }; 466ee2f75afSJens Wiklander size_t max_key_count = 0; 467ee2f75afSJens Wiklander bool two_keys = false; 46805304565SCedric Chaumont 469ee2f75afSJens Wiklander if (op == TEE_HANDLE_NULL) { 47005304565SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 47105304565SCedric Chaumont goto out; 47205304565SCedric Chaumont } 47305304565SCedric Chaumont 474cb98b7b2SJens Wiklander __utee_check_outbuf_annotation(op_info, size); 47505304565SCedric Chaumont 476ee2f75afSJens Wiklander if (*size < sizeof(*op_info)) { 477ee2f75afSJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 478ee2f75afSJens Wiklander goto out; 479ee2f75afSJens Wiklander } 480ee2f75afSJens Wiklander max_key_count = (*size - sizeof(*op_info)) / 48105304565SCedric Chaumont sizeof(TEE_OperationInfoKey); 48205304565SCedric Chaumont 483ee2f75afSJens Wiklander TEE_MemFill(op_info, 0, *size); 48405304565SCedric Chaumont 48505304565SCedric Chaumont /* Two keys flag (TEE_ALG_AES_XTS only) */ 486ee2f75afSJens Wiklander two_keys = op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS; 487ee2f75afSJens Wiklander 488ee2f75afSJens Wiklander if (op->info.mode == TEE_MODE_DIGEST) { 489ee2f75afSJens Wiklander op_info->numberOfKeys = 0; 490ee2f75afSJens Wiklander } else if (!two_keys) { 491ee2f75afSJens Wiklander if (max_key_count < 1) { 49205304565SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 49305304565SCedric Chaumont goto out; 49405304565SCedric Chaumont } 49505304565SCedric Chaumont 496ee2f75afSJens Wiklander res = TEE_GetObjectInfo1(op->key1, &kinfo); 497ee2f75afSJens Wiklander /* Key1 is not a valid handle, "can't happen". */ 498ee2f75afSJens Wiklander if (res) 49905304565SCedric Chaumont goto out; 50005304565SCedric Chaumont 501d372a47cSJens Wiklander op_info->keyInformation[0].keySize = kinfo.objectSize; 502ee2f75afSJens Wiklander op_info->keyInformation[0].requiredKeyUsage = 503ee2f75afSJens Wiklander op->info.requiredKeyUsage; 504ee2f75afSJens Wiklander op_info->numberOfKeys = 1; 505ee2f75afSJens Wiklander } else { 506ee2f75afSJens Wiklander if (max_key_count < 2) { 507ee2f75afSJens Wiklander res = TEE_ERROR_SHORT_BUFFER; 50805304565SCedric Chaumont goto out; 50905304565SCedric Chaumont } 51005304565SCedric Chaumont 511ee2f75afSJens Wiklander res = TEE_GetObjectInfo1(op->key1, &kinfo); 512ee2f75afSJens Wiklander /* Key1 is not a valid handle, "can't happen". */ 513ee2f75afSJens Wiklander if (res) 514ee2f75afSJens Wiklander goto out; 515ee2f75afSJens Wiklander 516d372a47cSJens Wiklander op_info->keyInformation[0].keySize = kinfo.objectSize; 517ee2f75afSJens Wiklander op_info->keyInformation[0].requiredKeyUsage = 518ee2f75afSJens Wiklander op->info.requiredKeyUsage; 519ee2f75afSJens Wiklander 520ee2f75afSJens Wiklander res = TEE_GetObjectInfo1(op->key2, &kinfo); 521ee2f75afSJens Wiklander /* Key2 is not a valid handle, "can't happen". */ 522ee2f75afSJens Wiklander if (res) 523ee2f75afSJens Wiklander goto out; 524ee2f75afSJens Wiklander 525d372a47cSJens Wiklander op_info->keyInformation[1].keySize = kinfo.objectSize; 526ee2f75afSJens Wiklander op_info->keyInformation[1].requiredKeyUsage = 527ee2f75afSJens Wiklander op->info.requiredKeyUsage; 528ee2f75afSJens Wiklander 529ee2f75afSJens Wiklander op_info->numberOfKeys = 2; 53005304565SCedric Chaumont } 53105304565SCedric Chaumont 532ee2f75afSJens Wiklander op_info->algorithm = op->info.algorithm; 533ee2f75afSJens Wiklander op_info->operationClass = op->info.operationClass; 534ee2f75afSJens Wiklander op_info->mode = op->info.mode; 535ee2f75afSJens Wiklander op_info->digestLength = op->info.digestLength; 536ee2f75afSJens Wiklander op_info->maxKeySize = op->info.maxKeySize; 537ee2f75afSJens Wiklander op_info->handleState = op->info.handleState; 538ee2f75afSJens Wiklander op_info->operationState = op->operationState; 53905304565SCedric Chaumont 54005304565SCedric Chaumont out: 54105304565SCedric Chaumont if (res != TEE_SUCCESS && 54205304565SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 543b36311adSJerome Forissier TEE_Panic(res); 54405304565SCedric Chaumont 54505304565SCedric Chaumont return res; 54605304565SCedric Chaumont } 54705304565SCedric Chaumont 548cb98b7b2SJens Wiklander TEE_Result 549cb98b7b2SJens Wiklander __GP11_TEE_GetOperationInfoMultiple(TEE_OperationHandle operation, 550cb98b7b2SJens Wiklander TEE_OperationInfoMultiple *info, 551cb98b7b2SJens Wiklander uint32_t *operationSize) 552cb98b7b2SJens Wiklander { 553cb98b7b2SJens Wiklander TEE_Result res = TEE_SUCCESS; 554cb98b7b2SJens Wiklander size_t s = 0; 555cb98b7b2SJens Wiklander 556cb98b7b2SJens Wiklander __utee_check_gp11_outbuf_annotation(info, operationSize); 557cb98b7b2SJens Wiklander s = *operationSize; 558cb98b7b2SJens Wiklander res = TEE_GetOperationInfoMultiple(operation, info, &s); 559cb98b7b2SJens Wiklander *operationSize = s; 560cb98b7b2SJens Wiklander return res; 561cb98b7b2SJens Wiklander } 562cb98b7b2SJens Wiklander 563287a6182SJens Wiklander static void reset_operation_state(TEE_OperationHandle op) 564287a6182SJens Wiklander { 565287a6182SJens Wiklander op->operationState = TEE_OPERATION_STATE_INITIAL; 566287a6182SJens Wiklander 567287a6182SJens Wiklander if (op->info.operationClass == TEE_OPERATION_DIGEST) { 568287a6182SJens Wiklander TEE_Result res = _utee_hash_init(op->state, NULL, 0); 569287a6182SJens Wiklander 570287a6182SJens Wiklander if (res != TEE_SUCCESS) 571287a6182SJens Wiklander TEE_Panic(res); 572287a6182SJens Wiklander op->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 573287a6182SJens Wiklander } else { 574287a6182SJens Wiklander op->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 575287a6182SJens Wiklander } 576287a6182SJens Wiklander } 577287a6182SJens Wiklander 578b0104773SPascal Brand void TEE_ResetOperation(TEE_OperationHandle operation) 579b0104773SPascal Brand { 580b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 581b0104773SPascal Brand TEE_Panic(0); 582bf80076aSCedric Chaumont 583642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET)) 584bf80076aSCedric Chaumont TEE_Panic(0); 585bf80076aSCedric Chaumont 586287a6182SJens Wiklander reset_operation_state(operation); 58705304565SCedric Chaumont } 588b0104773SPascal Brand 589b0104773SPascal Brand TEE_Result TEE_SetOperationKey(TEE_OperationHandle operation, 590b0104773SPascal Brand TEE_ObjectHandle key) 591b0104773SPascal Brand { 5927583c59eSCedric Chaumont TEE_Result res; 593b0104773SPascal Brand uint32_t key_size = 0; 594b0104773SPascal Brand TEE_ObjectInfo key_info; 595b0104773SPascal Brand 596a57c1e2eSCedric Chaumont if (operation == TEE_HANDLE_NULL) { 597a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 598a57c1e2eSCedric Chaumont goto out; 599a57c1e2eSCedric Chaumont } 600a57c1e2eSCedric Chaumont 601a57c1e2eSCedric Chaumont if (key == TEE_HANDLE_NULL) { 602a57c1e2eSCedric Chaumont /* Operation key cleared */ 603a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key1); 6046c4ea258SJens Wiklander operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 605287a6182SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 606287a6182SJens Wiklander reset_operation_state(operation); 6076c4ea258SJens Wiklander return TEE_SUCCESS; 608a57c1e2eSCedric Chaumont } 609a57c1e2eSCedric Chaumont 610a57c1e2eSCedric Chaumont /* No key for digest operation */ 611a57c1e2eSCedric Chaumont if (operation->info.operationClass == TEE_OPERATION_DIGEST) { 612a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 613a57c1e2eSCedric Chaumont goto out; 614a57c1e2eSCedric Chaumont } 615a57c1e2eSCedric Chaumont 616a57c1e2eSCedric Chaumont /* Two keys flag not expected (TEE_ALG_AES_XTS excluded) */ 617a57c1e2eSCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) != 618a57c1e2eSCedric Chaumont 0) { 619a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 620a57c1e2eSCedric Chaumont goto out; 621a57c1e2eSCedric Chaumont } 622a57c1e2eSCedric Chaumont 6237583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key, &key_info); 624a57c1e2eSCedric Chaumont /* Key is not a valid handle */ 6257583c59eSCedric Chaumont if (res != TEE_SUCCESS) 626a57c1e2eSCedric Chaumont goto out; 6277583c59eSCedric Chaumont 628b0104773SPascal Brand /* Supplied key has to meet required usage */ 629b0104773SPascal Brand if ((key_info.objectUsage & operation->info.requiredKeyUsage) != 630b0104773SPascal Brand operation->info.requiredKeyUsage) { 631a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 632a57c1e2eSCedric Chaumont goto out; 633b0104773SPascal Brand } 634b0104773SPascal Brand 635d372a47cSJens Wiklander if (operation->info.maxKeySize < key_info.objectSize) { 636a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 637a57c1e2eSCedric Chaumont goto out; 638a57c1e2eSCedric Chaumont } 639b0104773SPascal Brand 640d372a47cSJens Wiklander key_size = key_info.objectSize; 641b0104773SPascal Brand 642b0104773SPascal Brand TEE_ResetTransientObject(operation->key1); 643b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 644b0104773SPascal Brand 6457583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key1, key); 6467583c59eSCedric Chaumont if (res != TEE_SUCCESS) 647a57c1e2eSCedric Chaumont goto out; 6487583c59eSCedric Chaumont 649b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET; 650b0104773SPascal Brand 651b0104773SPascal Brand operation->info.keySize = key_size; 652b0104773SPascal Brand 653287a6182SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 654287a6182SJens Wiklander reset_operation_state(operation); 655287a6182SJens Wiklander 6567583c59eSCedric Chaumont out: 657a57c1e2eSCedric Chaumont if (res != TEE_SUCCESS && 658a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 659a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 660b36311adSJerome Forissier TEE_Panic(res); 661a57c1e2eSCedric Chaumont 662a57c1e2eSCedric Chaumont return res; 663b0104773SPascal Brand } 664b0104773SPascal Brand 665287a6182SJens Wiklander TEE_Result __GP11_TEE_SetOperationKey(TEE_OperationHandle operation, 666287a6182SJens Wiklander TEE_ObjectHandle key) 667287a6182SJens Wiklander { 668287a6182SJens Wiklander if (operation == TEE_HANDLE_NULL || 669287a6182SJens Wiklander operation->operationState != TEE_OPERATION_STATE_INITIAL) 670287a6182SJens Wiklander TEE_Panic(0); 671287a6182SJens Wiklander 672287a6182SJens Wiklander return TEE_SetOperationKey(operation, key); 673287a6182SJens Wiklander } 674287a6182SJens Wiklander 675287a6182SJens Wiklander static TEE_Result set_operation_key2(TEE_OperationHandle operation, 676287a6182SJens Wiklander TEE_ObjectHandle key1, 677287a6182SJens Wiklander TEE_ObjectHandle key2) 678b0104773SPascal Brand { 6797583c59eSCedric Chaumont TEE_Result res; 680b0104773SPascal Brand uint32_t key_size = 0; 681b0104773SPascal Brand TEE_ObjectInfo key_info1; 682b0104773SPascal Brand TEE_ObjectInfo key_info2; 683b0104773SPascal Brand 684a57c1e2eSCedric Chaumont if (operation == TEE_HANDLE_NULL) { 685a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 686a57c1e2eSCedric Chaumont goto out; 687a57c1e2eSCedric Chaumont } 688a57c1e2eSCedric Chaumont 689a57c1e2eSCedric Chaumont /* 690a57c1e2eSCedric Chaumont * Key1/Key2 and/or are not initialized and 691a57c1e2eSCedric Chaumont * Either both keys are NULL or both are not NULL 692a57c1e2eSCedric Chaumont */ 6936c4ea258SJens Wiklander if (!key1 && !key2) { 6946c4ea258SJens Wiklander /* Clear the keys */ 695a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key1); 696a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key2); 6976c4ea258SJens Wiklander operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 698287a6182SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 699287a6182SJens Wiklander reset_operation_state(operation); 7006c4ea258SJens Wiklander return TEE_SUCCESS; 7016c4ea258SJens Wiklander } else if (!key1 || !key2) { 7026c4ea258SJens Wiklander /* Both keys are obviously not valid. */ 703a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 704a57c1e2eSCedric Chaumont goto out; 705a57c1e2eSCedric Chaumont } 706a57c1e2eSCedric Chaumont 707a57c1e2eSCedric Chaumont /* No key for digest operation */ 708a57c1e2eSCedric Chaumont if (operation->info.operationClass == TEE_OPERATION_DIGEST) { 709a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 710a57c1e2eSCedric Chaumont goto out; 711a57c1e2eSCedric Chaumont } 712a57c1e2eSCedric Chaumont 7135b385b3fSJerome Forissier /* Two keys flag expected (TEE_ALG_AES_XTS and TEE_ALG_SM2_KEP only) */ 714a57c1e2eSCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 715a57c1e2eSCedric Chaumont 0) { 716a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 717a57c1e2eSCedric Chaumont goto out; 718a57c1e2eSCedric Chaumont } 719a57c1e2eSCedric Chaumont 7207583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key1, &key_info1); 721a57c1e2eSCedric Chaumont /* Key1 is not a valid handle */ 7227583c59eSCedric Chaumont if (res != TEE_SUCCESS) 723a57c1e2eSCedric Chaumont goto out; 7247583c59eSCedric Chaumont 725b0104773SPascal Brand /* Supplied key has to meet required usage */ 726b0104773SPascal Brand if ((key_info1.objectUsage & operation->info. 727b0104773SPascal Brand requiredKeyUsage) != operation->info.requiredKeyUsage) { 728a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 729a57c1e2eSCedric Chaumont goto out; 730b0104773SPascal Brand } 731b0104773SPascal Brand 7327583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key2, &key_info2); 733a57c1e2eSCedric Chaumont /* Key2 is not a valid handle */ 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 /* Supplied key has to meet required usage */ 741b0104773SPascal Brand if ((key_info2.objectUsage & operation->info. 742b0104773SPascal Brand requiredKeyUsage) != operation->info.requiredKeyUsage) { 743a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 744a57c1e2eSCedric Chaumont goto out; 745b0104773SPascal Brand } 746b0104773SPascal Brand 747b0104773SPascal Brand /* 7485b385b3fSJerome Forissier * All the multi key algorithm currently supported requires the keys to 7495b385b3fSJerome Forissier * be of equal size. 750b0104773SPascal Brand */ 751d372a47cSJens Wiklander if (key_info1.objectSize != key_info2.objectSize) { 752a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 753a57c1e2eSCedric Chaumont goto out; 754b0104773SPascal Brand 755a57c1e2eSCedric Chaumont } 756a57c1e2eSCedric Chaumont 757d372a47cSJens Wiklander if (operation->info.maxKeySize < key_info1.objectSize) { 758a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 759a57c1e2eSCedric Chaumont goto out; 760a57c1e2eSCedric Chaumont } 761b0104773SPascal Brand 762b0104773SPascal Brand /* 763b0104773SPascal Brand * Odd that only the size of one key should be reported while 764b0104773SPascal Brand * size of two key are used when allocating the operation. 765b0104773SPascal Brand */ 766d372a47cSJens Wiklander key_size = key_info1.objectSize; 767b0104773SPascal Brand 768b0104773SPascal Brand TEE_ResetTransientObject(operation->key1); 769b0104773SPascal Brand TEE_ResetTransientObject(operation->key2); 770b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 771b0104773SPascal Brand 7727583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key1, key1); 7737583c59eSCedric Chaumont if (res != TEE_SUCCESS) 774a57c1e2eSCedric Chaumont goto out; 7757583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key2, key2); 7767583c59eSCedric Chaumont if (res != TEE_SUCCESS) { 7777583c59eSCedric Chaumont if (res == TEE_ERROR_CORRUPT_OBJECT) 7787583c59eSCedric Chaumont res = TEE_ERROR_CORRUPT_OBJECT_2; 779a57c1e2eSCedric Chaumont goto out; 7807583c59eSCedric Chaumont } 7817583c59eSCedric Chaumont 782b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET; 783b0104773SPascal Brand 784b0104773SPascal Brand operation->info.keySize = key_size; 785b0104773SPascal Brand 786287a6182SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 787287a6182SJens Wiklander reset_operation_state(operation); 7887583c59eSCedric Chaumont out: 789a57c1e2eSCedric Chaumont if (res != TEE_SUCCESS && 790a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 791a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT_2 && 792a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE && 793a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE_2) 794b36311adSJerome Forissier TEE_Panic(res); 795a57c1e2eSCedric Chaumont 796a57c1e2eSCedric Chaumont return res; 797b0104773SPascal Brand } 798b0104773SPascal Brand 799287a6182SJens Wiklander TEE_Result TEE_SetOperationKey2(TEE_OperationHandle operation, 800287a6182SJens Wiklander TEE_ObjectHandle key1, TEE_ObjectHandle key2) 801287a6182SJens Wiklander { 802287a6182SJens Wiklander if (operation != TEE_HANDLE_NULL && key1 && key1 == key2) 803287a6182SJens Wiklander return TEE_ERROR_SECURITY; 804287a6182SJens Wiklander 805287a6182SJens Wiklander return set_operation_key2(operation, key1, key2); 806287a6182SJens Wiklander } 807287a6182SJens Wiklander 808287a6182SJens Wiklander TEE_Result __GP11_TEE_SetOperationKey2(TEE_OperationHandle operation, 809287a6182SJens Wiklander TEE_ObjectHandle key1, 810287a6182SJens Wiklander TEE_ObjectHandle key2) 811287a6182SJens Wiklander { 812287a6182SJens Wiklander if (operation == TEE_HANDLE_NULL || 813287a6182SJens Wiklander operation->operationState != TEE_OPERATION_STATE_INITIAL) 814287a6182SJens Wiklander TEE_Panic(0); 815287a6182SJens Wiklander 816287a6182SJens Wiklander return set_operation_key2(operation, key1, key2); 817287a6182SJens Wiklander } 818287a6182SJens Wiklander 819b0104773SPascal Brand void TEE_CopyOperation(TEE_OperationHandle dst_op, TEE_OperationHandle src_op) 820b0104773SPascal Brand { 821b0104773SPascal Brand TEE_Result res; 822b0104773SPascal Brand 823b0104773SPascal Brand if (dst_op == TEE_HANDLE_NULL || src_op == TEE_HANDLE_NULL) 824b0104773SPascal Brand TEE_Panic(0); 825b0104773SPascal Brand if (dst_op->info.algorithm != src_op->info.algorithm) 826b0104773SPascal Brand TEE_Panic(0); 8278734de30SJens Wiklander if (dst_op->info.mode != src_op->info.mode) 8288734de30SJens Wiklander TEE_Panic(0); 829b0104773SPascal Brand if (src_op->info.operationClass != TEE_OPERATION_DIGEST) { 830b0104773SPascal Brand TEE_ObjectHandle key1 = TEE_HANDLE_NULL; 831b0104773SPascal Brand TEE_ObjectHandle key2 = TEE_HANDLE_NULL; 832b0104773SPascal Brand 833b0104773SPascal Brand if (src_op->info.handleState & TEE_HANDLE_FLAG_KEY_SET) { 834b0104773SPascal Brand key1 = src_op->key1; 835b0104773SPascal Brand key2 = src_op->key2; 836b0104773SPascal Brand } 837b0104773SPascal Brand 838b0104773SPascal Brand if ((src_op->info.handleState & 839b0104773SPascal Brand TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 0) { 840b0104773SPascal Brand TEE_SetOperationKey(dst_op, key1); 841b0104773SPascal Brand } else { 842b0104773SPascal Brand TEE_SetOperationKey2(dst_op, key1, key2); 843b0104773SPascal Brand } 844b0104773SPascal Brand } 845b0104773SPascal Brand dst_op->info.handleState = src_op->info.handleState; 846b0104773SPascal Brand dst_op->info.keySize = src_op->info.keySize; 8478e07702eSJens Wiklander dst_op->info.digestLength = src_op->info.digestLength; 848642a1607SCedric Chaumont dst_op->operationState = src_op->operationState; 849b0104773SPascal Brand 850b0104773SPascal Brand if (dst_op->buffer_two_blocks != src_op->buffer_two_blocks || 851b0104773SPascal Brand dst_op->block_size != src_op->block_size) 852b0104773SPascal Brand TEE_Panic(0); 853b0104773SPascal Brand 854b0104773SPascal Brand if (dst_op->buffer != NULL) { 85524ea7613SJens Wiklander size_t sz = src_op->block_size; 85624ea7613SJens Wiklander 857b0104773SPascal Brand if (src_op->buffer == NULL) 858b0104773SPascal Brand TEE_Panic(0); 859b0104773SPascal Brand 86024ea7613SJens Wiklander if (src_op->buffer_two_blocks) 86124ea7613SJens Wiklander sz *= 2; 86224ea7613SJens Wiklander memcpy(dst_op->buffer, src_op->buffer, sz); 863b0104773SPascal Brand dst_op->buffer_offs = src_op->buffer_offs; 864b0104773SPascal Brand } else if (src_op->buffer != NULL) { 865b0104773SPascal Brand TEE_Panic(0); 866b0104773SPascal Brand } 867b0104773SPascal Brand 8682c028fdeSJerome Forissier res = _utee_cryp_state_copy(dst_op->state, src_op->state); 869b0104773SPascal Brand if (res != TEE_SUCCESS) 870b0104773SPascal Brand TEE_Panic(res); 871b0104773SPascal Brand } 872b0104773SPascal Brand 873b0104773SPascal Brand /* Cryptographic Operations API - Message Digest Functions */ 874b0104773SPascal Brand 8758f07fe6fSJerome Forissier static void init_hash_operation(TEE_OperationHandle operation, const void *IV, 8766d15db08SJerome Forissier uint32_t IVLen) 8776d15db08SJerome Forissier { 8786d15db08SJerome Forissier TEE_Result res; 8796d15db08SJerome Forissier 8806d15db08SJerome Forissier /* 8816d15db08SJerome Forissier * Note : IV and IVLen are never used in current implementation 8826d15db08SJerome Forissier * This is why coherent values of IV and IVLen are not checked 8836d15db08SJerome Forissier */ 8842c028fdeSJerome Forissier res = _utee_hash_init(operation->state, IV, IVLen); 8856d15db08SJerome Forissier if (res != TEE_SUCCESS) 8866d15db08SJerome Forissier TEE_Panic(res); 8876d15db08SJerome Forissier operation->buffer_offs = 0; 8886d15db08SJerome Forissier operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 8896d15db08SJerome Forissier } 8906d15db08SJerome Forissier 891b0104773SPascal Brand void TEE_DigestUpdate(TEE_OperationHandle operation, 892185bf58cSJens Wiklander const void *chunk, size_t chunkSize) 893b0104773SPascal Brand { 89473d6c3baSJoakim Bech TEE_Result res = TEE_ERROR_GENERIC; 895b0104773SPascal Brand 89673d6c3baSJoakim Bech if (operation == TEE_HANDLE_NULL || 89773d6c3baSJoakim Bech operation->info.operationClass != TEE_OPERATION_DIGEST) 898b0104773SPascal Brand TEE_Panic(0); 89973d6c3baSJoakim Bech 900642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 901642a1607SCedric Chaumont 9022c028fdeSJerome Forissier res = _utee_hash_update(operation->state, chunk, chunkSize); 903b0104773SPascal Brand if (res != TEE_SUCCESS) 904b0104773SPascal Brand TEE_Panic(res); 905b0104773SPascal Brand } 906b0104773SPascal Brand 907185bf58cSJens Wiklander void __GP11_TEE_DigestUpdate(TEE_OperationHandle operation, 908185bf58cSJens Wiklander const void *chunk, uint32_t chunkSize) 909185bf58cSJens Wiklander { 910185bf58cSJens Wiklander return TEE_DigestUpdate(operation, chunk, chunkSize); 911185bf58cSJens Wiklander } 912185bf58cSJens Wiklander 9138f07fe6fSJerome Forissier TEE_Result TEE_DigestDoFinal(TEE_OperationHandle operation, const void *chunk, 914185bf58cSJens Wiklander size_t chunkLen, void *hash, size_t *hashLen) 915b0104773SPascal Brand { 91624ea7613SJens Wiklander TEE_Result res = TEE_SUCCESS; 91724ea7613SJens Wiklander uint64_t hl = 0; 91824ea7613SJens Wiklander size_t len = 0; 91987c2f6b6SCedric Chaumont 92087c2f6b6SCedric Chaumont if ((operation == TEE_HANDLE_NULL) || 92187c2f6b6SCedric Chaumont (!chunk && chunkLen) || 92287c2f6b6SCedric Chaumont (operation->info.operationClass != TEE_OPERATION_DIGEST)) { 92387c2f6b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 92487c2f6b6SCedric Chaumont goto out; 92587c2f6b6SCedric Chaumont } 92624ea7613SJens Wiklander if (operation->operationState == TEE_OPERATION_STATE_EXTRACTING && 92724ea7613SJens Wiklander chunkLen) { 92824ea7613SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 92924ea7613SJens Wiklander goto out; 93024ea7613SJens Wiklander } 9316915bbbbSJens Wiklander __utee_check_inout_annotation(hashLen, sizeof(*hashLen)); 93287c2f6b6SCedric Chaumont 93324ea7613SJens Wiklander if (operation->operationState == TEE_OPERATION_STATE_EXTRACTING && 93424ea7613SJens Wiklander operation->buffer) { 93524ea7613SJens Wiklander /* 93624ea7613SJens Wiklander * This is not an Extendable-Output Function and we have 93724ea7613SJens Wiklander * already started extracting 93824ea7613SJens Wiklander */ 93924ea7613SJens Wiklander len = MIN(operation->block_size - operation->buffer_offs, 94024ea7613SJens Wiklander *hashLen); 94124ea7613SJens Wiklander memcpy(hash, operation->buffer + operation->buffer_offs, len); 94224ea7613SJens Wiklander *hashLen = len; 94324ea7613SJens Wiklander } else { 944e86f1266SJens Wiklander hl = *hashLen; 94524ea7613SJens Wiklander res = _utee_hash_final(operation->state, chunk, chunkLen, hash, 94624ea7613SJens Wiklander &hl); 947e86f1266SJens Wiklander *hashLen = hl; 94824ea7613SJens Wiklander if (res) 9496d15db08SJerome Forissier goto out; 95024ea7613SJens Wiklander } 9516d15db08SJerome Forissier 9526d15db08SJerome Forissier /* Reset operation state */ 9536d15db08SJerome Forissier init_hash_operation(operation, NULL, 0); 95487c2f6b6SCedric Chaumont 955642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 956642a1607SCedric Chaumont 95787c2f6b6SCedric Chaumont out: 95887c2f6b6SCedric Chaumont if (res != TEE_SUCCESS && 95987c2f6b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 960b36311adSJerome Forissier TEE_Panic(res); 96173d6c3baSJoakim Bech 96287c2f6b6SCedric Chaumont return res; 963b0104773SPascal Brand } 964b0104773SPascal Brand 965185bf58cSJens Wiklander TEE_Result __GP11_TEE_DigestDoFinal(TEE_OperationHandle operation, 966185bf58cSJens Wiklander const void *chunk, uint32_t chunkLen, 967185bf58cSJens Wiklander void *hash, uint32_t *hashLen) 968185bf58cSJens Wiklander { 969185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 970185bf58cSJens Wiklander size_t l = 0; 971185bf58cSJens Wiklander 972185bf58cSJens Wiklander __utee_check_inout_annotation(hashLen, sizeof(*hashLen)); 973185bf58cSJens Wiklander l = *hashLen; 974185bf58cSJens Wiklander res = TEE_DigestDoFinal(operation, chunk, chunkLen, hash, &l); 975185bf58cSJens Wiklander *hashLen = l; 976185bf58cSJens Wiklander return res; 977185bf58cSJens Wiklander } 978185bf58cSJens Wiklander 97924ea7613SJens Wiklander TEE_Result TEE_DigestExtract(TEE_OperationHandle operation, void *hash, 98024ea7613SJens Wiklander size_t *hashLen) 98124ea7613SJens Wiklander { 98224ea7613SJens Wiklander TEE_Result res = TEE_SUCCESS; 98324ea7613SJens Wiklander uint64_t hl = 0; 98424ea7613SJens Wiklander size_t len = 0; 98524ea7613SJens Wiklander 98624ea7613SJens Wiklander if (operation == TEE_HANDLE_NULL || 98724ea7613SJens Wiklander operation->info.operationClass != TEE_OPERATION_DIGEST) 98824ea7613SJens Wiklander TEE_Panic(0); 98924ea7613SJens Wiklander __utee_check_inout_annotation(hashLen, sizeof(*hashLen)); 99024ea7613SJens Wiklander 99124ea7613SJens Wiklander if (!operation->buffer) { 99224ea7613SJens Wiklander /* This is an Extendable-Output Function */ 99324ea7613SJens Wiklander operation->info.handleState |= TEE_HANDLE_FLAG_EXTRACTING; 99424ea7613SJens Wiklander operation->operationState = TEE_OPERATION_STATE_EXTRACTING; 99524ea7613SJens Wiklander hl = *hashLen; 99624ea7613SJens Wiklander res = _utee_hash_final(operation->state, NULL, 0, hash, &hl); 99724ea7613SJens Wiklander if (res) 99824ea7613SJens Wiklander TEE_Panic(0); 99924ea7613SJens Wiklander *hashLen = hl; 100024ea7613SJens Wiklander 100124ea7613SJens Wiklander return TEE_SUCCESS; 100224ea7613SJens Wiklander } 100324ea7613SJens Wiklander 100424ea7613SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_EXTRACTING) { 100524ea7613SJens Wiklander hl = operation->block_size; 100624ea7613SJens Wiklander res = _utee_hash_final(operation->state, NULL, 0, 100724ea7613SJens Wiklander operation->buffer, &hl); 100824ea7613SJens Wiklander if (res) 100924ea7613SJens Wiklander TEE_Panic(0); 101024ea7613SJens Wiklander if (hl != operation->block_size) 101124ea7613SJens Wiklander TEE_Panic(0); 101224ea7613SJens Wiklander assert(!operation->buffer_offs); 101324ea7613SJens Wiklander operation->info.handleState |= TEE_HANDLE_FLAG_EXTRACTING; 101424ea7613SJens Wiklander operation->operationState = TEE_OPERATION_STATE_EXTRACTING; 101524ea7613SJens Wiklander } 101624ea7613SJens Wiklander 101724ea7613SJens Wiklander len = MIN(operation->block_size - operation->buffer_offs, *hashLen); 101824ea7613SJens Wiklander memcpy(hash, operation->buffer + operation->buffer_offs, len); 101924ea7613SJens Wiklander *hashLen = len; 102024ea7613SJens Wiklander operation->buffer_offs += len; 102124ea7613SJens Wiklander 102224ea7613SJens Wiklander return TEE_SUCCESS; 102324ea7613SJens Wiklander } 102424ea7613SJens Wiklander 1025b0104773SPascal Brand /* Cryptographic Operations API - Symmetric Cipher Functions */ 1026b0104773SPascal Brand 10278f07fe6fSJerome Forissier void TEE_CipherInit(TEE_OperationHandle operation, const void *IV, 1028185bf58cSJens Wiklander size_t IVLen) 1029b0104773SPascal Brand { 1030b0104773SPascal Brand TEE_Result res; 1031b0104773SPascal Brand 1032b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 1033b0104773SPascal Brand TEE_Panic(0); 1034642a1607SCedric Chaumont 1035b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_CIPHER) 1036b0104773SPascal Brand TEE_Panic(0); 1037642a1607SCedric Chaumont 1038642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) || 1039642a1607SCedric Chaumont !(operation->key1)) 1040642a1607SCedric Chaumont TEE_Panic(0); 1041642a1607SCedric Chaumont 1042642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 1043642a1607SCedric Chaumont TEE_ResetOperation(operation); 1044642a1607SCedric Chaumont 1045ad7aa2a5SSadiq Hussain if (IV && IVLen) { 1046ad7aa2a5SSadiq Hussain if (operation->info.algorithm == TEE_ALG_AES_ECB_NOPAD || 1047ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_DES_ECB_NOPAD || 1048ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_DES3_ECB_NOPAD || 1049ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_SM4_ECB_NOPAD) 1050ad7aa2a5SSadiq Hussain TEE_Panic(0); 1051ad7aa2a5SSadiq Hussain } 1052ad7aa2a5SSadiq Hussain 1053642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1054642a1607SCedric Chaumont 10552c028fdeSJerome Forissier res = _utee_cipher_init(operation->state, IV, IVLen); 1056b0104773SPascal Brand if (res != TEE_SUCCESS) 1057b0104773SPascal Brand TEE_Panic(res); 1058642a1607SCedric Chaumont 1059b0104773SPascal Brand operation->buffer_offs = 0; 1060b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 1061b0104773SPascal Brand } 1062b0104773SPascal Brand 1063185bf58cSJens Wiklander void __GP11_TEE_CipherInit(TEE_OperationHandle operation, const void *IV, 1064185bf58cSJens Wiklander uint32_t IVLen) 1065185bf58cSJens Wiklander { 1066185bf58cSJens Wiklander return TEE_CipherInit(operation, IV, IVLen); 1067185bf58cSJens Wiklander } 1068185bf58cSJens Wiklander 1069b0104773SPascal Brand static TEE_Result tee_buffer_update( 1070b0104773SPascal Brand TEE_OperationHandle op, 1071e86f1266SJens Wiklander TEE_Result(*update_func)(unsigned long state, const void *src, 1072e86f1266SJens Wiklander size_t slen, void *dst, uint64_t *dlen), 1073b0104773SPascal Brand const void *src_data, size_t src_len, 1074e86f1266SJens Wiklander void *dest_data, uint64_t *dest_len) 1075b0104773SPascal Brand { 1076b0104773SPascal Brand TEE_Result res; 1077b0104773SPascal Brand const uint8_t *src = src_data; 1078b0104773SPascal Brand size_t slen = src_len; 1079b0104773SPascal Brand uint8_t *dst = dest_data; 1080b0104773SPascal Brand size_t dlen = *dest_len; 1081b0104773SPascal Brand size_t acc_dlen = 0; 1082e86f1266SJens Wiklander uint64_t tmp_dlen; 1083b0104773SPascal Brand size_t l; 1084b0104773SPascal Brand size_t buffer_size; 1085d3588802SPascal Brand size_t buffer_left; 1086b0104773SPascal Brand 1087090268f5SJens Wiklander if (!src) { 1088090268f5SJens Wiklander if (slen) 1089090268f5SJens Wiklander TEE_Panic(0); 1090090268f5SJens Wiklander goto out; 1091090268f5SJens Wiklander } 1092090268f5SJens Wiklander 1093d3588802SPascal Brand if (op->buffer_two_blocks) { 1094b0104773SPascal Brand buffer_size = op->block_size * 2; 1095d3588802SPascal Brand buffer_left = 1; 1096d3588802SPascal Brand } else { 1097b0104773SPascal Brand buffer_size = op->block_size; 1098d3588802SPascal Brand buffer_left = 0; 1099d3588802SPascal Brand } 1100b0104773SPascal Brand 1101b0104773SPascal Brand if (op->buffer_offs > 0) { 1102b0104773SPascal Brand /* Fill up complete block */ 1103b0104773SPascal Brand if (op->buffer_offs < op->block_size) 1104b0104773SPascal Brand l = MIN(slen, op->block_size - op->buffer_offs); 1105b0104773SPascal Brand else 1106b0104773SPascal Brand l = MIN(slen, buffer_size - op->buffer_offs); 1107b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, l); 1108b0104773SPascal Brand op->buffer_offs += l; 1109b0104773SPascal Brand src += l; 1110b0104773SPascal Brand slen -= l; 1111b0104773SPascal Brand if ((op->buffer_offs % op->block_size) != 0) 1112b0104773SPascal Brand goto out; /* Nothing left to do */ 1113b0104773SPascal Brand } 1114b0104773SPascal Brand 1115b0104773SPascal Brand /* If we can feed from buffer */ 1116d3588802SPascal Brand if ((op->buffer_offs > 0) && 1117d3588802SPascal Brand ((op->buffer_offs + slen) >= (buffer_size + buffer_left))) { 11182ff3fdbbSPascal Brand l = ROUNDUP(op->buffer_offs + slen - buffer_size, 1119b0104773SPascal Brand op->block_size); 1120b0104773SPascal Brand l = MIN(op->buffer_offs, l); 1121*aeb530a5SSami Tolvanen /* 1122*aeb530a5SSami Tolvanen * If we're buffering only a single block, process it 1123*aeb530a5SSami Tolvanen * immediately. 1124*aeb530a5SSami Tolvanen */ 1125*aeb530a5SSami Tolvanen if (!op->buffer_two_blocks) 1126*aeb530a5SSami Tolvanen l = op->block_size; 1127b0104773SPascal Brand tmp_dlen = dlen; 1128b0104773SPascal Brand res = update_func(op->state, op->buffer, l, dst, &tmp_dlen); 1129b0104773SPascal Brand if (res != TEE_SUCCESS) 1130b0104773SPascal Brand TEE_Panic(res); 1131b0104773SPascal Brand dst += tmp_dlen; 1132b0104773SPascal Brand dlen -= tmp_dlen; 1133b0104773SPascal Brand acc_dlen += tmp_dlen; 1134b0104773SPascal Brand op->buffer_offs -= l; 1135b0104773SPascal Brand if (op->buffer_offs > 0) { 1136b0104773SPascal Brand /* 1137b0104773SPascal Brand * Slen is small enough to be contained in rest buffer. 1138b0104773SPascal Brand */ 1139b0104773SPascal Brand memcpy(op->buffer, op->buffer + l, buffer_size - l); 1140b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, slen); 1141b0104773SPascal Brand op->buffer_offs += slen; 1142b0104773SPascal Brand goto out; /* Nothing left to do */ 1143b0104773SPascal Brand } 1144b0104773SPascal Brand } 1145b0104773SPascal Brand 1146d3588802SPascal Brand if (slen >= (buffer_size + buffer_left)) { 1147b0104773SPascal Brand /* Buffer is empty, feed as much as possible from src */ 1148bf7a587fSJerome Forissier if (op->info.algorithm == TEE_ALG_AES_CTS) 1149b1ecda78SJerome Forissier l = ROUNDUP(slen - buffer_size, op->block_size); 1150bf7a587fSJerome Forissier else 1151bf7a587fSJerome Forissier l = ROUNDUP(slen - buffer_size + 1, op->block_size); 1152b0104773SPascal Brand 1153b0104773SPascal Brand tmp_dlen = dlen; 1154b0104773SPascal Brand res = update_func(op->state, src, l, dst, &tmp_dlen); 1155b0104773SPascal Brand if (res != TEE_SUCCESS) 1156b0104773SPascal Brand TEE_Panic(res); 1157b0104773SPascal Brand src += l; 1158b0104773SPascal Brand slen -= l; 1159b0104773SPascal Brand dst += tmp_dlen; 1160b0104773SPascal Brand dlen -= tmp_dlen; 1161b0104773SPascal Brand acc_dlen += tmp_dlen; 1162b0104773SPascal Brand } 1163b0104773SPascal Brand 1164b0104773SPascal Brand /* Slen is small enough to be contained in buffer. */ 1165b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, slen); 1166b0104773SPascal Brand op->buffer_offs += slen; 1167b0104773SPascal Brand 1168b0104773SPascal Brand out: 1169b0104773SPascal Brand *dest_len = acc_dlen; 1170b0104773SPascal Brand return TEE_SUCCESS; 1171b0104773SPascal Brand } 1172b0104773SPascal Brand 11738f07fe6fSJerome Forissier TEE_Result TEE_CipherUpdate(TEE_OperationHandle operation, const void *srcData, 1174185bf58cSJens Wiklander size_t srcLen, void *destData, size_t *destLen) 1175b0104773SPascal Brand { 1176dea1f2b6SCedric Chaumont TEE_Result res; 1177b0104773SPascal Brand size_t req_dlen; 1178e86f1266SJens Wiklander uint64_t dl; 1179b0104773SPascal Brand 11806915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1181dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1182dea1f2b6SCedric Chaumont goto out; 1183dea1f2b6SCedric Chaumont } 11846915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1185dea1f2b6SCedric Chaumont 1186642a1607SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_CIPHER) { 1187dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1188dea1f2b6SCedric Chaumont goto out; 1189dea1f2b6SCedric Chaumont } 1190dea1f2b6SCedric Chaumont 1191642a1607SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1192642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1193642a1607SCedric Chaumont goto out; 1194642a1607SCedric Chaumont } 1195642a1607SCedric Chaumont 1196642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1197dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1198dea1f2b6SCedric Chaumont goto out; 1199dea1f2b6SCedric Chaumont } 1200b0104773SPascal Brand 1201e32c5ddfSJerome Forissier if (!srcData && !srcLen) { 1202090268f5SJens Wiklander *destLen = 0; 1203e32c5ddfSJerome Forissier res = TEE_SUCCESS; 1204e32c5ddfSJerome Forissier goto out; 1205e32c5ddfSJerome Forissier } 1206e32c5ddfSJerome Forissier 1207b0104773SPascal Brand /* Calculate required dlen */ 120857aabac5SBogdan Liulko if (operation->block_size > 1) { 120957aabac5SBogdan Liulko req_dlen = ((operation->buffer_offs + srcLen) / 121057aabac5SBogdan Liulko operation->block_size) * operation->block_size; 121157aabac5SBogdan Liulko } else { 121257aabac5SBogdan Liulko req_dlen = srcLen; 121357aabac5SBogdan Liulko } 1214642a1607SCedric Chaumont if (operation->buffer_two_blocks) { 1215642a1607SCedric Chaumont if (req_dlen > operation->block_size * 2) 1216642a1607SCedric Chaumont req_dlen -= operation->block_size * 2; 1217b0104773SPascal Brand else 1218b0104773SPascal Brand req_dlen = 0; 1219b0104773SPascal Brand } 1220b0104773SPascal Brand /* 1221b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1222b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1223b0104773SPascal Brand * can't restore sync with this API. 1224b0104773SPascal Brand */ 1225b0104773SPascal Brand if (*destLen < req_dlen) { 1226b0104773SPascal Brand *destLen = req_dlen; 1227dea1f2b6SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1228dea1f2b6SCedric Chaumont goto out; 1229b0104773SPascal Brand } 1230b0104773SPascal Brand 1231e86f1266SJens Wiklander dl = *destLen; 123257aabac5SBogdan Liulko if (operation->block_size > 1) { 12332c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_cipher_update, srcData, 123457aabac5SBogdan Liulko srcLen, destData, &dl); 123557aabac5SBogdan Liulko } else { 123657aabac5SBogdan Liulko if (srcLen > 0) { 12372c028fdeSJerome Forissier res = _utee_cipher_update(operation->state, srcData, 123857aabac5SBogdan Liulko srcLen, destData, &dl); 123957aabac5SBogdan Liulko } else { 124057aabac5SBogdan Liulko res = TEE_SUCCESS; 124157aabac5SBogdan Liulko dl = 0; 124257aabac5SBogdan Liulko } 124357aabac5SBogdan Liulko } 1244e86f1266SJens Wiklander *destLen = dl; 1245b0104773SPascal Brand 1246dea1f2b6SCedric Chaumont out: 1247dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS && 1248dea1f2b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1249b36311adSJerome Forissier TEE_Panic(res); 1250dea1f2b6SCedric Chaumont 1251dea1f2b6SCedric Chaumont return res; 1252b0104773SPascal Brand } 1253b0104773SPascal Brand 1254185bf58cSJens Wiklander TEE_Result __GP11_TEE_CipherUpdate(TEE_OperationHandle operation, 12558f07fe6fSJerome Forissier const void *srcData, uint32_t srcLen, 12568f07fe6fSJerome Forissier void *destData, uint32_t *destLen) 1257b0104773SPascal Brand { 12586915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 1259185bf58cSJens Wiklander size_t dl = 0; 1260185bf58cSJens Wiklander 1261185bf58cSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1262185bf58cSJens Wiklander dl = *destLen; 1263185bf58cSJens Wiklander res = TEE_CipherUpdate(operation, srcData, srcLen, destData, &dl); 1264185bf58cSJens Wiklander *destLen = dl; 1265185bf58cSJens Wiklander return res; 1266185bf58cSJens Wiklander } 1267185bf58cSJens Wiklander 1268185bf58cSJens Wiklander TEE_Result TEE_CipherDoFinal(TEE_OperationHandle operation, 1269185bf58cSJens Wiklander const void *srcData, size_t srcLen, 1270185bf58cSJens Wiklander void *destData, size_t *destLen) 1271185bf58cSJens Wiklander { 1272185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 1273b0104773SPascal Brand uint8_t *dst = destData; 1274b0104773SPascal Brand size_t acc_dlen = 0; 12756915bbbbSJens Wiklander uint64_t tmp_dlen = 0; 12766915bbbbSJens Wiklander size_t req_dlen = 0; 1277b0104773SPascal Brand 12786915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1279dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1280dea1f2b6SCedric Chaumont goto out; 1281dea1f2b6SCedric Chaumont } 12826915bbbbSJens Wiklander if (destLen) 12836915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1284dea1f2b6SCedric Chaumont 1285642a1607SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_CIPHER) { 1286dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1287dea1f2b6SCedric Chaumont goto out; 1288dea1f2b6SCedric Chaumont } 1289dea1f2b6SCedric Chaumont 1290642a1607SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1291642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1292642a1607SCedric Chaumont goto out; 1293642a1607SCedric Chaumont } 1294642a1607SCedric Chaumont 1295642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1296dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1297dea1f2b6SCedric Chaumont goto out; 1298dea1f2b6SCedric Chaumont } 1299b0104773SPascal Brand 1300b0104773SPascal Brand /* 1301b0104773SPascal Brand * Check that the final block doesn't require padding for those 1302b0104773SPascal Brand * algorithms that requires client to supply padding. 1303b0104773SPascal Brand */ 1304642a1607SCedric Chaumont if (operation->info.algorithm == TEE_ALG_AES_ECB_NOPAD || 1305642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_AES_CBC_NOPAD || 1306642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES_ECB_NOPAD || 1307642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES_CBC_NOPAD || 1308642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES3_ECB_NOPAD || 1309ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_DES3_CBC_NOPAD || 1310ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_SM4_ECB_NOPAD || 1311ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_SM4_CBC_NOPAD) { 1312642a1607SCedric Chaumont if (((operation->buffer_offs + srcLen) % operation->block_size) 1313642a1607SCedric Chaumont != 0) { 1314dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1315dea1f2b6SCedric Chaumont goto out; 1316dea1f2b6SCedric Chaumont } 1317b0104773SPascal Brand } 1318b0104773SPascal Brand 1319b0104773SPascal Brand /* 1320b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1321b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1322b0104773SPascal Brand * can't restore sync with this API. 1323b0104773SPascal Brand */ 132457aabac5SBogdan Liulko if (operation->block_size > 1) { 1325642a1607SCedric Chaumont req_dlen = operation->buffer_offs + srcLen; 132657aabac5SBogdan Liulko } else { 132757aabac5SBogdan Liulko req_dlen = srcLen; 132857aabac5SBogdan Liulko } 13296915bbbbSJens Wiklander if (destLen) 13306915bbbbSJens Wiklander tmp_dlen = *destLen; 13316915bbbbSJens Wiklander if (tmp_dlen < req_dlen) { 13326915bbbbSJens Wiklander if (destLen) 1333b0104773SPascal Brand *destLen = req_dlen; 1334dea1f2b6SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1335dea1f2b6SCedric Chaumont goto out; 1336b0104773SPascal Brand } 1337b0104773SPascal Brand 133857aabac5SBogdan Liulko if (operation->block_size > 1) { 1339dea9063eSJens Wiklander if (srcLen) { 13402c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_cipher_update, 1341dea9063eSJens Wiklander srcData, srcLen, dst, 1342dea9063eSJens Wiklander &tmp_dlen); 1343dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS) 1344dea1f2b6SCedric Chaumont goto out; 1345dea1f2b6SCedric Chaumont 1346b0104773SPascal Brand dst += tmp_dlen; 1347b0104773SPascal Brand acc_dlen += tmp_dlen; 1348b0104773SPascal Brand 1349b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 1350dea9063eSJens Wiklander } 13512c028fdeSJerome Forissier res = _utee_cipher_final(operation->state, operation->buffer, 13522c028fdeSJerome Forissier operation->buffer_offs, dst, 13532c028fdeSJerome Forissier &tmp_dlen); 135457aabac5SBogdan Liulko } else { 13552c028fdeSJerome Forissier res = _utee_cipher_final(operation->state, srcData, srcLen, dst, 13562c028fdeSJerome Forissier &tmp_dlen); 135757aabac5SBogdan Liulko } 1358b0104773SPascal Brand if (res != TEE_SUCCESS) 1359dea1f2b6SCedric Chaumont goto out; 1360dea1f2b6SCedric Chaumont 1361b0104773SPascal Brand acc_dlen += tmp_dlen; 13626915bbbbSJens Wiklander if (destLen) 1363b0104773SPascal Brand *destLen = acc_dlen; 1364dea1f2b6SCedric Chaumont 1365642a1607SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 1366642a1607SCedric Chaumont 1367642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1368642a1607SCedric Chaumont 1369dea1f2b6SCedric Chaumont out: 1370dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS && 1371dea1f2b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1372b36311adSJerome Forissier TEE_Panic(res); 1373dea1f2b6SCedric Chaumont 1374dea1f2b6SCedric Chaumont return res; 1375b0104773SPascal Brand } 1376b0104773SPascal Brand 1377185bf58cSJens Wiklander TEE_Result __GP11_TEE_CipherDoFinal(TEE_OperationHandle operation, 1378185bf58cSJens Wiklander const void *srcData, uint32_t srcLen, 1379185bf58cSJens Wiklander void *destData, uint32_t *destLen) 1380185bf58cSJens Wiklander { 1381185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 1382185bf58cSJens Wiklander size_t dl = 0; 1383185bf58cSJens Wiklander 1384185bf58cSJens Wiklander if (destLen) { 1385185bf58cSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1386185bf58cSJens Wiklander dl = *destLen; 1387185bf58cSJens Wiklander } 1388185bf58cSJens Wiklander res = TEE_CipherDoFinal(operation, srcData, srcLen, destData, &dl); 1389185bf58cSJens Wiklander if (destLen) 1390185bf58cSJens Wiklander *destLen = dl; 1391185bf58cSJens Wiklander return res; 1392185bf58cSJens Wiklander } 1393185bf58cSJens Wiklander 1394b0104773SPascal Brand /* Cryptographic Operations API - MAC Functions */ 1395b0104773SPascal Brand 1396185bf58cSJens Wiklander void TEE_MACInit(TEE_OperationHandle operation, const void *IV, size_t IVLen) 1397b0104773SPascal Brand { 1398b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 1399b0104773SPascal Brand TEE_Panic(0); 1400642a1607SCedric Chaumont 1401b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_MAC) 1402b0104773SPascal Brand TEE_Panic(0); 1403642a1607SCedric Chaumont 1404642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) || 1405642a1607SCedric Chaumont !(operation->key1)) 1406642a1607SCedric Chaumont TEE_Panic(0); 1407642a1607SCedric Chaumont 1408642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 1409642a1607SCedric Chaumont TEE_ResetOperation(operation); 1410642a1607SCedric Chaumont 1411642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1412642a1607SCedric Chaumont 14136d15db08SJerome Forissier init_hash_operation(operation, IV, IVLen); 1414b0104773SPascal Brand } 1415b0104773SPascal Brand 1416185bf58cSJens Wiklander void __GP11_TEE_MACInit(TEE_OperationHandle operation, const void *IV, 1417185bf58cSJens Wiklander uint32_t IVLen) 1418185bf58cSJens Wiklander { 1419185bf58cSJens Wiklander return TEE_MACInit(operation, IV, IVLen); 1420185bf58cSJens Wiklander } 1421185bf58cSJens Wiklander 14228f07fe6fSJerome Forissier void TEE_MACUpdate(TEE_OperationHandle operation, const void *chunk, 1423185bf58cSJens Wiklander size_t chunkSize) 1424b0104773SPascal Brand { 1425b0104773SPascal Brand TEE_Result res; 1426b0104773SPascal Brand 142728e0efc6SCedric Chaumont if (operation == TEE_HANDLE_NULL || (chunk == NULL && chunkSize != 0)) 1428b0104773SPascal Brand TEE_Panic(0); 1429642a1607SCedric Chaumont 143028e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) 1431b0104773SPascal Brand TEE_Panic(0); 1432642a1607SCedric Chaumont 143328e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 1434b0104773SPascal Brand TEE_Panic(0); 1435b0104773SPascal Brand 1436642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) 1437642a1607SCedric Chaumont TEE_Panic(0); 1438642a1607SCedric Chaumont 14392c028fdeSJerome Forissier res = _utee_hash_update(operation->state, chunk, chunkSize); 1440b0104773SPascal Brand if (res != TEE_SUCCESS) 1441b0104773SPascal Brand TEE_Panic(res); 1442b0104773SPascal Brand } 1443b0104773SPascal Brand 1444185bf58cSJens Wiklander void __GP11_TEE_MACUpdate(TEE_OperationHandle operation, const void *chunk, 1445185bf58cSJens Wiklander uint32_t chunkSize) 1446185bf58cSJens Wiklander { 1447185bf58cSJens Wiklander return TEE_MACUpdate(operation, chunk, chunkSize); 1448185bf58cSJens Wiklander } 1449185bf58cSJens Wiklander 145028e0efc6SCedric Chaumont TEE_Result TEE_MACComputeFinal(TEE_OperationHandle operation, 1451185bf58cSJens Wiklander const void *message, size_t messageLen, 1452185bf58cSJens Wiklander void *mac, size_t *macLen) 1453b0104773SPascal Brand { 1454b0104773SPascal Brand TEE_Result res; 1455e86f1266SJens Wiklander uint64_t ml; 1456b0104773SPascal Brand 14576915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!message && messageLen)) { 145828e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 145928e0efc6SCedric Chaumont goto out; 146028e0efc6SCedric Chaumont } 14616915bbbbSJens Wiklander __utee_check_inout_annotation(macLen, sizeof(*macLen)); 1462b0104773SPascal Brand 146328e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) { 146428e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 146528e0efc6SCedric Chaumont goto out; 146628e0efc6SCedric Chaumont } 146728e0efc6SCedric Chaumont 146828e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 146928e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 147028e0efc6SCedric Chaumont goto out; 147128e0efc6SCedric Chaumont } 147228e0efc6SCedric Chaumont 1473642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1474642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1475642a1607SCedric Chaumont goto out; 1476642a1607SCedric Chaumont } 1477642a1607SCedric Chaumont 1478e86f1266SJens Wiklander ml = *macLen; 14792c028fdeSJerome Forissier res = _utee_hash_final(operation->state, message, messageLen, mac, &ml); 1480e86f1266SJens Wiklander *macLen = ml; 148128e0efc6SCedric Chaumont if (res != TEE_SUCCESS) 148228e0efc6SCedric Chaumont goto out; 148328e0efc6SCedric Chaumont 148428e0efc6SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 148528e0efc6SCedric Chaumont 1486642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1487642a1607SCedric Chaumont 148828e0efc6SCedric Chaumont out: 148928e0efc6SCedric Chaumont if (res != TEE_SUCCESS && 149028e0efc6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 149128e0efc6SCedric Chaumont TEE_Panic(res); 149228e0efc6SCedric Chaumont 1493b0104773SPascal Brand return res; 1494b0104773SPascal Brand } 1495b0104773SPascal Brand 1496185bf58cSJens Wiklander TEE_Result __GP11_TEE_MACComputeFinal(TEE_OperationHandle operation, 14978f07fe6fSJerome Forissier const void *message, uint32_t messageLen, 1498185bf58cSJens Wiklander void *mac, uint32_t *macLen) 1499185bf58cSJens Wiklander { 1500185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 1501185bf58cSJens Wiklander size_t ml = 0; 1502185bf58cSJens Wiklander 1503185bf58cSJens Wiklander __utee_check_inout_annotation(macLen, sizeof(*macLen)); 1504185bf58cSJens Wiklander ml = *macLen; 1505185bf58cSJens Wiklander res = TEE_MACComputeFinal(operation, message, messageLen, mac, &ml); 1506185bf58cSJens Wiklander *macLen = ml; 1507185bf58cSJens Wiklander return res; 1508185bf58cSJens Wiklander } 1509185bf58cSJens Wiklander 1510185bf58cSJens Wiklander TEE_Result TEE_MACCompareFinal(TEE_OperationHandle operation, 1511185bf58cSJens Wiklander const void *message, size_t messageLen, 1512185bf58cSJens Wiklander const void *mac, size_t macLen) 1513b0104773SPascal Brand { 1514b0104773SPascal Brand TEE_Result res; 1515ee4ba3d1SVictor Chong uint8_t computed_mac[TEE_MAX_HASH_SIZE] = { 0 }; 1516185bf58cSJens Wiklander size_t computed_mac_size = TEE_MAX_HASH_SIZE; 1517b0104773SPascal Brand 151828e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) { 151928e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 152028e0efc6SCedric Chaumont goto out; 152128e0efc6SCedric Chaumont } 152228e0efc6SCedric Chaumont 152328e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 152428e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 152528e0efc6SCedric Chaumont goto out; 152628e0efc6SCedric Chaumont } 152728e0efc6SCedric Chaumont 1528642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1529642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1530642a1607SCedric Chaumont goto out; 1531642a1607SCedric Chaumont } 1532642a1607SCedric Chaumont 1533b0104773SPascal Brand res = TEE_MACComputeFinal(operation, message, messageLen, computed_mac, 1534b0104773SPascal Brand &computed_mac_size); 1535b0104773SPascal Brand if (res != TEE_SUCCESS) 153628e0efc6SCedric Chaumont goto out; 153728e0efc6SCedric Chaumont 153828e0efc6SCedric Chaumont if (computed_mac_size != macLen) { 153928e0efc6SCedric Chaumont res = TEE_ERROR_MAC_INVALID; 154028e0efc6SCedric Chaumont goto out; 154128e0efc6SCedric Chaumont } 154228e0efc6SCedric Chaumont 154348e10604SJerome Forissier if (consttime_memcmp(mac, computed_mac, computed_mac_size) != 0) { 154428e0efc6SCedric Chaumont res = TEE_ERROR_MAC_INVALID; 154528e0efc6SCedric Chaumont goto out; 154628e0efc6SCedric Chaumont } 154728e0efc6SCedric Chaumont 1548642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1549642a1607SCedric Chaumont 155028e0efc6SCedric Chaumont out: 155128e0efc6SCedric Chaumont if (res != TEE_SUCCESS && 155228e0efc6SCedric Chaumont res != TEE_ERROR_MAC_INVALID) 155328e0efc6SCedric Chaumont TEE_Panic(res); 155428e0efc6SCedric Chaumont 1555b0104773SPascal Brand return res; 1556b0104773SPascal Brand } 1557b0104773SPascal Brand 1558185bf58cSJens Wiklander TEE_Result __GP11_TEE_MACCompareFinal(TEE_OperationHandle operation, 1559185bf58cSJens Wiklander const void *message, uint32_t messageLen, 1560185bf58cSJens Wiklander const void *mac, uint32_t macLen) 1561185bf58cSJens Wiklander { 1562185bf58cSJens Wiklander return TEE_MACCompareFinal(operation, message, messageLen, mac, macLen); 1563185bf58cSJens Wiklander } 1564185bf58cSJens Wiklander 1565b0104773SPascal Brand /* Cryptographic Operations API - Authenticated Encryption Functions */ 1566b0104773SPascal Brand 15678f07fe6fSJerome Forissier TEE_Result TEE_AEInit(TEE_OperationHandle operation, const void *nonce, 1568d9096215SJens Wiklander size_t nonceLen, uint32_t tagLen, size_t AADLen, 1569d9096215SJens Wiklander size_t payloadLen) 1570b0104773SPascal Brand { 1571b0104773SPascal Brand TEE_Result res; 1572b0104773SPascal Brand 1573b5816c88SCedric Chaumont if (operation == TEE_HANDLE_NULL || nonce == NULL) { 1574b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1575b5816c88SCedric Chaumont goto out; 1576b5816c88SCedric Chaumont } 1577b5816c88SCedric Chaumont 1578b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1579b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1580b5816c88SCedric Chaumont goto out; 1581b5816c88SCedric Chaumont } 1582b0104773SPascal Brand 1583642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) { 1584642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1585642a1607SCedric Chaumont goto out; 1586642a1607SCedric Chaumont } 1587642a1607SCedric Chaumont 1588b0104773SPascal Brand /* 1589b0104773SPascal Brand * AES-CCM tag len is specified by AES-CCM spec and handled in TEE Core 1590b0104773SPascal Brand * in the implementation. But AES-GCM spec doesn't specify the tag len 1591b0104773SPascal Brand * according to the same principle so we have to check here instead to 1592b0104773SPascal Brand * be GP compliant. 1593b0104773SPascal Brand */ 1594b5816c88SCedric Chaumont if (operation->info.algorithm == TEE_ALG_AES_GCM) { 1595b0104773SPascal Brand /* 1596b0104773SPascal Brand * From GP spec: For AES-GCM, can be 128, 120, 112, 104, or 96 1597b0104773SPascal Brand */ 1598b5816c88SCedric Chaumont if (tagLen < 96 || tagLen > 128 || (tagLen % 8 != 0)) { 1599b5816c88SCedric Chaumont res = TEE_ERROR_NOT_SUPPORTED; 1600b5816c88SCedric Chaumont goto out; 1601b5816c88SCedric Chaumont } 1602b0104773SPascal Brand } 1603b0104773SPascal Brand 16042c028fdeSJerome Forissier res = _utee_authenc_init(operation->state, nonce, nonceLen, tagLen / 8, 16052c028fdeSJerome Forissier AADLen, payloadLen); 1606b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1607b5816c88SCedric Chaumont goto out; 1608b5816c88SCedric Chaumont 16097acaf5adSAlbert Schwarzkopf operation->info.digestLength = tagLen / 8; 1610f2674567SSumit Garg operation->buffer_offs = 0; 1611b5816c88SCedric Chaumont operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 1612b5816c88SCedric Chaumont 1613b5816c88SCedric Chaumont out: 1614b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1615b5816c88SCedric Chaumont res != TEE_ERROR_NOT_SUPPORTED) 1616b0104773SPascal Brand TEE_Panic(res); 1617b5816c88SCedric Chaumont 1618b0104773SPascal Brand return res; 1619b0104773SPascal Brand } 1620b0104773SPascal Brand 1621d9096215SJens Wiklander TEE_Result __GP11_TEE_AEInit(TEE_OperationHandle operation, const void *nonce, 1622d9096215SJens Wiklander uint32_t nonceLen, uint32_t tagLen, 1623d9096215SJens Wiklander uint32_t AADLen, uint32_t payloadLen) 1624d9096215SJens Wiklander { 1625d9096215SJens Wiklander return TEE_AEInit(operation, nonce, nonceLen, tagLen, AADLen, 1626d9096215SJens Wiklander payloadLen); 1627d9096215SJens Wiklander } 1628d9096215SJens Wiklander 16298f07fe6fSJerome Forissier void TEE_AEUpdateAAD(TEE_OperationHandle operation, const void *AADdata, 1630d9096215SJens Wiklander size_t AADdataLen) 1631d9096215SJens Wiklander { 1632d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1633d9096215SJens Wiklander 1634d9096215SJens Wiklander if (operation == TEE_HANDLE_NULL || (!AADdata && AADdataLen)) 1635d9096215SJens Wiklander TEE_Panic(0); 1636d9096215SJens Wiklander 1637d9096215SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_AE) 1638d9096215SJens Wiklander TEE_Panic(0); 1639d9096215SJens Wiklander 1640d9096215SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 1641d9096215SJens Wiklander TEE_Panic(0); 1642d9096215SJens Wiklander 1643d9096215SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 1644d9096215SJens Wiklander TEE_Panic(0); 1645d9096215SJens Wiklander 1646d9096215SJens Wiklander res = _utee_authenc_update_aad(operation->state, AADdata, AADdataLen); 1647d9096215SJens Wiklander if (res != TEE_SUCCESS) 1648d9096215SJens Wiklander TEE_Panic(res); 1649d9096215SJens Wiklander } 1650d9096215SJens Wiklander 1651d9096215SJens Wiklander void __GP11_TEE_AEUpdateAAD(TEE_OperationHandle operation, const void *AADdata, 165279a3c601SCedric Chaumont uint32_t AADdataLen) 1653b0104773SPascal Brand { 1654d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1655b0104773SPascal Brand 1656b5816c88SCedric Chaumont if (operation == TEE_HANDLE_NULL || 1657b5816c88SCedric Chaumont (AADdata == NULL && AADdataLen != 0)) 1658b0104773SPascal Brand TEE_Panic(0); 1659642a1607SCedric Chaumont 1660b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) 1661b0104773SPascal Brand TEE_Panic(0); 1662642a1607SCedric Chaumont 1663b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 1664b0104773SPascal Brand TEE_Panic(0); 1665b0104773SPascal Brand 16662c028fdeSJerome Forissier res = _utee_authenc_update_aad(operation->state, AADdata, AADdataLen); 1667642a1607SCedric Chaumont 1668642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1669642a1607SCedric Chaumont 1670b0104773SPascal Brand if (res != TEE_SUCCESS) 1671b0104773SPascal Brand TEE_Panic(res); 1672b0104773SPascal Brand } 1673b0104773SPascal Brand 1674d9096215SJens Wiklander static TEE_Result ae_update_helper(TEE_OperationHandle operation, 1675d9096215SJens Wiklander const void *src, size_t slen, void *dst, 1676d9096215SJens Wiklander size_t *dlen) 1677b0104773SPascal Brand { 16786915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 16796915bbbbSJens Wiklander size_t req_dlen = 0; 16806915bbbbSJens Wiklander uint64_t dl = 0; 1681b0104773SPascal Brand 1682d9096215SJens Wiklander if (!src && !slen) { 1683d9096215SJens Wiklander *dlen = 0; 1684d9096215SJens Wiklander return TEE_SUCCESS; 1685d9096215SJens Wiklander } 1686d9096215SJens Wiklander 1687d9096215SJens Wiklander /* 1688d9096215SJens Wiklander * Check that required destLen is big enough before starting to feed 1689d9096215SJens Wiklander * data to the algorithm. Errors during feeding of data are fatal as we 1690d9096215SJens Wiklander * can't restore sync with this API. 1691d9096215SJens Wiklander */ 1692d9096215SJens Wiklander if (operation->block_size > 1) { 1693d9096215SJens Wiklander req_dlen = ROUNDDOWN(operation->buffer_offs + slen, 1694d9096215SJens Wiklander operation->block_size); 1695d9096215SJens Wiklander } else { 1696d9096215SJens Wiklander req_dlen = slen; 1697d9096215SJens Wiklander } 1698d9096215SJens Wiklander 1699d9096215SJens Wiklander dl = *dlen; 1700d9096215SJens Wiklander if (dl < req_dlen) { 1701d9096215SJens Wiklander *dlen = req_dlen; 1702d9096215SJens Wiklander return TEE_ERROR_SHORT_BUFFER; 1703d9096215SJens Wiklander } 1704d9096215SJens Wiklander 1705d9096215SJens Wiklander if (operation->block_size > 1) { 1706d9096215SJens Wiklander res = tee_buffer_update(operation, _utee_authenc_update_payload, 1707d9096215SJens Wiklander src, slen, dst, &dl); 1708d9096215SJens Wiklander } else { 1709d9096215SJens Wiklander if (slen > 0) { 1710d9096215SJens Wiklander res = _utee_authenc_update_payload(operation->state, 1711d9096215SJens Wiklander src, slen, dst, &dl); 1712d9096215SJens Wiklander } else { 1713d9096215SJens Wiklander dl = 0; 1714d9096215SJens Wiklander res = TEE_SUCCESS; 1715d9096215SJens Wiklander } 1716d9096215SJens Wiklander } 1717d9096215SJens Wiklander 1718d9096215SJens Wiklander if (!res) 1719d9096215SJens Wiklander *dlen = dl; 1720d9096215SJens Wiklander 1721d9096215SJens Wiklander return res; 1722d9096215SJens Wiklander } 1723d9096215SJens Wiklander 1724d9096215SJens Wiklander TEE_Result TEE_AEUpdate(TEE_OperationHandle operation, const void *srcData, 1725d9096215SJens Wiklander size_t srcLen, void *destData, size_t *destLen) 1726d9096215SJens Wiklander { 1727d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1728d9096215SJens Wiklander 17296915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1730b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1731b5816c88SCedric Chaumont goto out; 1732b5816c88SCedric Chaumont } 1733d9096215SJens Wiklander __utee_check_outbuf_annotation(destData, destLen); 1734b5816c88SCedric Chaumont 1735b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1736b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1737b5816c88SCedric Chaumont goto out; 1738b5816c88SCedric Chaumont } 1739b5816c88SCedric Chaumont 1740b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1741b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1742b5816c88SCedric Chaumont goto out; 1743b5816c88SCedric Chaumont } 1744b0104773SPascal Brand 1745d9096215SJens Wiklander res = ae_update_helper(operation, srcData, srcLen, destData, destLen); 1746d9096215SJens Wiklander if (res != TEE_ERROR_SHORT_BUFFER && srcLen) 1747d9096215SJens Wiklander operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1748d9096215SJens Wiklander 1749d9096215SJens Wiklander out: 1750d9096215SJens Wiklander if (res != TEE_SUCCESS && 1751d9096215SJens Wiklander res != TEE_ERROR_SHORT_BUFFER) 1752d9096215SJens Wiklander TEE_Panic(res); 1753d9096215SJens Wiklander 1754d9096215SJens Wiklander return res; 1755d9096215SJens Wiklander } 1756d9096215SJens Wiklander 1757d9096215SJens Wiklander TEE_Result __GP11_TEE_AEUpdate(TEE_OperationHandle operation, 1758d9096215SJens Wiklander const void *srcData, uint32_t srcLen, 1759d9096215SJens Wiklander void *destData, uint32_t *destLen) 1760d9096215SJens Wiklander { 1761d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1762d9096215SJens Wiklander size_t dl = 0; 1763d9096215SJens Wiklander 1764d9096215SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1765d9096215SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1766d9096215SJens Wiklander goto out; 1767d9096215SJens Wiklander } 1768d9096215SJens Wiklander __utee_check_gp11_outbuf_annotation(destData, destLen); 1769d9096215SJens Wiklander 1770d9096215SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_AE) { 1771d9096215SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1772827308b8SJerome Forissier goto out; 1773827308b8SJerome Forissier } 1774827308b8SJerome Forissier 1775d9096215SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1776d9096215SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1777d9096215SJens Wiklander goto out; 1778afc0c182SBogdan Liulko } 1779afc0c182SBogdan Liulko 17806915bbbbSJens Wiklander dl = *destLen; 1781d9096215SJens Wiklander res = ae_update_helper(operation, srcData, srcLen, destData, &dl); 1782d9096215SJens Wiklander *destLen = dl; 1783b0104773SPascal Brand 1784afc0c182SBogdan Liulko if (res != TEE_SUCCESS) 1785afc0c182SBogdan Liulko goto out; 1786afc0c182SBogdan Liulko 1787642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1788642a1607SCedric Chaumont 1789b5816c88SCedric Chaumont out: 1790b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1791b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1792b5816c88SCedric Chaumont TEE_Panic(res); 1793b5816c88SCedric Chaumont 1794b5816c88SCedric Chaumont return res; 1795b0104773SPascal Brand } 1796b0104773SPascal Brand 1797b5816c88SCedric Chaumont TEE_Result TEE_AEEncryptFinal(TEE_OperationHandle operation, 1798d9096215SJens Wiklander const void *srcData, size_t srcLen, 1799d9096215SJens Wiklander void *destData, size_t *destLen, void *tag, 1800d9096215SJens Wiklander size_t *tagLen) 1801b0104773SPascal Brand { 1802d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1803b0104773SPascal Brand uint8_t *dst = destData; 1804b0104773SPascal Brand size_t acc_dlen = 0; 1805d9096215SJens Wiklander uint64_t tmp_dlen = 0; 1806d9096215SJens Wiklander size_t req_dlen = 0; 1807d9096215SJens Wiklander uint64_t tl = 0; 1808b0104773SPascal Brand 18096915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1810b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1811b5816c88SCedric Chaumont goto out; 1812b5816c88SCedric Chaumont } 18136915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 18146915bbbbSJens Wiklander __utee_check_inout_annotation(tagLen, sizeof(*tagLen)); 1815b5816c88SCedric Chaumont 1816b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1817b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1818b5816c88SCedric Chaumont goto out; 1819b5816c88SCedric Chaumont } 1820b5816c88SCedric Chaumont 1821b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1822b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1823b5816c88SCedric Chaumont goto out; 1824b5816c88SCedric Chaumont } 1825b0104773SPascal Brand 1826b0104773SPascal Brand /* 1827b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1828b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1829b0104773SPascal Brand * can't restore sync with this API. 18302733280aSEtienne Carriere * 18312733280aSEtienne Carriere * Need to check this before update_payload since sync would be lost if 18322733280aSEtienne Carriere * we return short buffer after that. 1833b0104773SPascal Brand */ 18342733280aSEtienne Carriere res = TEE_ERROR_GENERIC; 18352733280aSEtienne Carriere 1836b5816c88SCedric Chaumont req_dlen = operation->buffer_offs + srcLen; 1837b0104773SPascal Brand if (*destLen < req_dlen) { 1838b0104773SPascal Brand *destLen = req_dlen; 1839b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1840b0104773SPascal Brand } 1841b0104773SPascal Brand 18427acaf5adSAlbert Schwarzkopf if (*tagLen < operation->info.digestLength) { 18437acaf5adSAlbert Schwarzkopf *tagLen = operation->info.digestLength; 1844b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1845b0104773SPascal Brand } 1846b0104773SPascal Brand 18472733280aSEtienne Carriere if (res == TEE_ERROR_SHORT_BUFFER) 18482733280aSEtienne Carriere goto out; 18492733280aSEtienne Carriere 1850afc0c182SBogdan Liulko tl = *tagLen; 1851b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 1852afc0c182SBogdan Liulko if (operation->block_size > 1) { 18532c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_authenc_update_payload, 1854afc0c182SBogdan Liulko srcData, srcLen, dst, &tmp_dlen); 1855b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1856b5816c88SCedric Chaumont goto out; 1857b5816c88SCedric Chaumont 1858b0104773SPascal Brand dst += tmp_dlen; 1859b0104773SPascal Brand acc_dlen += tmp_dlen; 1860b0104773SPascal Brand 1861b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 18622c028fdeSJerome Forissier res = _utee_authenc_enc_final(operation->state, 1863afc0c182SBogdan Liulko operation->buffer, 1864afc0c182SBogdan Liulko operation->buffer_offs, dst, 1865afc0c182SBogdan Liulko &tmp_dlen, tag, &tl); 1866afc0c182SBogdan Liulko } else { 18672c028fdeSJerome Forissier res = _utee_authenc_enc_final(operation->state, srcData, 1868afc0c182SBogdan Liulko srcLen, dst, &tmp_dlen, 1869e86f1266SJens Wiklander tag, &tl); 1870afc0c182SBogdan Liulko } 1871e86f1266SJens Wiklander *tagLen = tl; 1872b0104773SPascal Brand if (res != TEE_SUCCESS) 1873b5816c88SCedric Chaumont goto out; 1874b0104773SPascal Brand 1875b5816c88SCedric Chaumont acc_dlen += tmp_dlen; 1876b0104773SPascal Brand *destLen = acc_dlen; 1877642a1607SCedric Chaumont 1878b5816c88SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 1879b5816c88SCedric Chaumont 1880642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1881642a1607SCedric Chaumont 1882b5816c88SCedric Chaumont out: 1883b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1884b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1885b5816c88SCedric Chaumont TEE_Panic(res); 1886b0104773SPascal Brand 1887b0104773SPascal Brand return res; 1888b0104773SPascal Brand } 1889b0104773SPascal Brand 1890d9096215SJens Wiklander TEE_Result __GP11_TEE_AEEncryptFinal(TEE_OperationHandle operation, 18918f07fe6fSJerome Forissier const void *srcData, uint32_t srcLen, 1892d9096215SJens Wiklander void *destData, uint32_t *destLen, 1893d9096215SJens Wiklander void *tag, uint32_t *tagLen) 1894b0104773SPascal Brand { 1895d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1896d9096215SJens Wiklander size_t dl = 0; 1897d9096215SJens Wiklander size_t tl = 0; 1898d9096215SJens Wiklander 1899d9096215SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1900d9096215SJens Wiklander __utee_check_inout_annotation(tagLen, sizeof(*tagLen)); 1901d9096215SJens Wiklander dl = *destLen; 1902d9096215SJens Wiklander tl = *tagLen; 1903d9096215SJens Wiklander res = TEE_AEEncryptFinal(operation, srcData, srcLen, destData, &dl, 1904d9096215SJens Wiklander tag, &tl); 1905d9096215SJens Wiklander *destLen = dl; 1906d9096215SJens Wiklander *tagLen = tl; 1907d9096215SJens Wiklander return res; 1908d9096215SJens Wiklander } 1909d9096215SJens Wiklander 1910d9096215SJens Wiklander TEE_Result TEE_AEDecryptFinal(TEE_OperationHandle operation, 1911d9096215SJens Wiklander const void *srcData, size_t srcLen, 1912d9096215SJens Wiklander void *destData, size_t *destLen, void *tag, 1913d9096215SJens Wiklander size_t tagLen) 1914d9096215SJens Wiklander { 1915d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1916b0104773SPascal Brand uint8_t *dst = destData; 1917b0104773SPascal Brand size_t acc_dlen = 0; 1918d9096215SJens Wiklander uint64_t tmp_dlen = 0; 1919d9096215SJens Wiklander size_t req_dlen = 0; 1920b0104773SPascal Brand 19216915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1922b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1923b5816c88SCedric Chaumont goto out; 1924b5816c88SCedric Chaumont } 19256915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1926b5816c88SCedric Chaumont 1927b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1928b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1929b5816c88SCedric Chaumont goto out; 1930b5816c88SCedric Chaumont } 1931b5816c88SCedric Chaumont 1932b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1933b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1934b5816c88SCedric Chaumont goto out; 1935b5816c88SCedric Chaumont } 1936b0104773SPascal Brand 1937b0104773SPascal Brand /* 1938b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1939b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1940b0104773SPascal Brand * can't restore sync with this API. 1941b0104773SPascal Brand */ 1942b5816c88SCedric Chaumont req_dlen = operation->buffer_offs + srcLen; 1943b0104773SPascal Brand if (*destLen < req_dlen) { 1944b0104773SPascal Brand *destLen = req_dlen; 1945b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1946b5816c88SCedric Chaumont goto out; 1947b0104773SPascal Brand } 1948b0104773SPascal Brand 1949b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 1950afc0c182SBogdan Liulko if (operation->block_size > 1) { 19512c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_authenc_update_payload, 1952afc0c182SBogdan Liulko srcData, srcLen, dst, &tmp_dlen); 1953b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1954b5816c88SCedric Chaumont goto out; 1955b5816c88SCedric Chaumont 1956b0104773SPascal Brand dst += tmp_dlen; 1957b0104773SPascal Brand acc_dlen += tmp_dlen; 1958b0104773SPascal Brand 1959b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 19602c028fdeSJerome Forissier res = _utee_authenc_dec_final(operation->state, 1961afc0c182SBogdan Liulko operation->buffer, 1962afc0c182SBogdan Liulko operation->buffer_offs, dst, 1963afc0c182SBogdan Liulko &tmp_dlen, tag, tagLen); 1964afc0c182SBogdan Liulko } else { 19652c028fdeSJerome Forissier res = _utee_authenc_dec_final(operation->state, srcData, 1966afc0c182SBogdan Liulko srcLen, dst, &tmp_dlen, 1967b5816c88SCedric Chaumont tag, tagLen); 1968afc0c182SBogdan Liulko } 1969b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1970b5816c88SCedric Chaumont goto out; 1971b5816c88SCedric Chaumont 1972b0104773SPascal Brand /* Supplied tagLen should match what we initiated with */ 19737acaf5adSAlbert Schwarzkopf if (tagLen != operation->info.digestLength) 1974b0104773SPascal Brand res = TEE_ERROR_MAC_INVALID; 1975b0104773SPascal Brand 1976b0104773SPascal Brand acc_dlen += tmp_dlen; 1977b0104773SPascal Brand *destLen = acc_dlen; 1978642a1607SCedric Chaumont 1979b5816c88SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 1980b5816c88SCedric Chaumont 1981642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1982642a1607SCedric Chaumont 1983b5816c88SCedric Chaumont out: 1984b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1985b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER && 1986b5816c88SCedric Chaumont res != TEE_ERROR_MAC_INVALID) 1987b5816c88SCedric Chaumont TEE_Panic(res); 1988b0104773SPascal Brand 1989b0104773SPascal Brand return res; 1990b0104773SPascal Brand } 1991b0104773SPascal Brand 1992d9096215SJens Wiklander TEE_Result __GP11_TEE_AEDecryptFinal(TEE_OperationHandle operation, 1993d9096215SJens Wiklander const void *srcData, uint32_t srcLen, 1994d9096215SJens Wiklander void *destData, uint32_t *destLen, 1995d9096215SJens Wiklander void *tag, uint32_t tagLen) 1996d9096215SJens Wiklander { 1997d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1998d9096215SJens Wiklander size_t dl = 0; 1999d9096215SJens Wiklander 2000d9096215SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 2001d9096215SJens Wiklander dl = *destLen; 2002d9096215SJens Wiklander res = TEE_AEDecryptFinal(operation, srcData, srcLen, destData, &dl, 2003d9096215SJens Wiklander tag, tagLen); 2004d9096215SJens Wiklander *destLen = dl; 2005d9096215SJens Wiklander return res; 2006d9096215SJens Wiklander } 2007d9096215SJens Wiklander 2008b0104773SPascal Brand /* Cryptographic Operations API - Asymmetric Functions */ 2009b0104773SPascal Brand 201012e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricEncrypt(TEE_OperationHandle operation, 20118f07fe6fSJerome Forissier const TEE_Attribute *params, 20128f07fe6fSJerome Forissier uint32_t paramCount, const void *srcData, 2013999b69d0SJens Wiklander size_t srcLen, void *destData, 2014999b69d0SJens Wiklander size_t *destLen) 2015b0104773SPascal Brand { 20166915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 2017e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 20186915bbbbSJens Wiklander uint64_t dl = 0; 2019b0104773SPascal Brand 20206915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 2021b0104773SPascal Brand TEE_Panic(0); 20226915bbbbSJens Wiklander 20236915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 20246915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 20256915bbbbSJens Wiklander 202612e66b6fSCedric Chaumont if (!operation->key1) 2027b0104773SPascal Brand TEE_Panic(0); 202812e66b6fSCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 202912e66b6fSCedric Chaumont TEE_Panic(0); 203012e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_ENCRYPT) 2031b0104773SPascal Brand TEE_Panic(0); 2032b0104773SPascal Brand 2033e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 2034e86f1266SJens Wiklander dl = *destLen; 20352c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 2036e86f1266SJens Wiklander srcLen, destData, &dl); 2037e86f1266SJens Wiklander *destLen = dl; 203812e66b6fSCedric Chaumont 20398844ebfcSPascal Brand if (res != TEE_SUCCESS && 20408844ebfcSPascal Brand res != TEE_ERROR_SHORT_BUFFER && 20411bc176d8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS && 20421bc176d8SJens Wiklander res != TEE_ERROR_CIPHERTEXT_INVALID && 20431bc176d8SJens Wiklander res != TEE_ERROR_NOT_SUPPORTED) 2044b0104773SPascal Brand TEE_Panic(res); 204512e66b6fSCedric Chaumont 2046b0104773SPascal Brand return res; 2047b0104773SPascal Brand } 2048b0104773SPascal Brand 20494f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricEncrypt(TEE_OperationHandle operation, 20504f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 20514f4374c8SJens Wiklander uint32_t paramCount, 20524f4374c8SJens Wiklander const void *srcData, uint32_t srcLen, 20534f4374c8SJens Wiklander void *destData, uint32_t *destLen) 20544f4374c8SJens Wiklander { 20554f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 20564f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 20574f4374c8SJens Wiklander uint64_t dl = 0; 20584f4374c8SJens Wiklander 20594f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 20604f4374c8SJens Wiklander TEE_Panic(0); 20614f4374c8SJens Wiklander 20624f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 20634f4374c8SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 20644f4374c8SJens Wiklander 20654f4374c8SJens Wiklander if (!operation->key1) 20664f4374c8SJens Wiklander TEE_Panic(0); 20674f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 20684f4374c8SJens Wiklander TEE_Panic(0); 20694f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_ENCRYPT) 20704f4374c8SJens Wiklander TEE_Panic(0); 20714f4374c8SJens Wiklander 20724f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 20734f4374c8SJens Wiklander dl = *destLen; 20744f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 20754f4374c8SJens Wiklander srcLen, destData, &dl); 20764f4374c8SJens Wiklander *destLen = dl; 20774f4374c8SJens Wiklander 20784f4374c8SJens Wiklander if (res != TEE_SUCCESS && 20794f4374c8SJens Wiklander res != TEE_ERROR_SHORT_BUFFER && 20804f4374c8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS) 20814f4374c8SJens Wiklander TEE_Panic(res); 20824f4374c8SJens Wiklander 20834f4374c8SJens Wiklander return res; 20844f4374c8SJens Wiklander } 20854f4374c8SJens Wiklander 208612e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricDecrypt(TEE_OperationHandle operation, 20878f07fe6fSJerome Forissier const TEE_Attribute *params, 20888f07fe6fSJerome Forissier uint32_t paramCount, const void *srcData, 2089999b69d0SJens Wiklander size_t srcLen, void *destData, 2090999b69d0SJens Wiklander size_t *destLen) 2091b0104773SPascal Brand { 20926915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 2093e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 20946915bbbbSJens Wiklander uint64_t dl = 0; 2095b0104773SPascal Brand 20966915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 2097b0104773SPascal Brand TEE_Panic(0); 20986915bbbbSJens Wiklander 20996915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 21006915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 21016915bbbbSJens Wiklander 210212e66b6fSCedric Chaumont if (!operation->key1) 2103b0104773SPascal Brand TEE_Panic(0); 210412e66b6fSCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 210512e66b6fSCedric Chaumont TEE_Panic(0); 210612e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_DECRYPT) 2107b0104773SPascal Brand TEE_Panic(0); 2108b0104773SPascal Brand 2109e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 2110e86f1266SJens Wiklander dl = *destLen; 21112c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 2112e86f1266SJens Wiklander srcLen, destData, &dl); 2113e86f1266SJens Wiklander *destLen = dl; 211412e66b6fSCedric Chaumont 21158844ebfcSPascal Brand if (res != TEE_SUCCESS && 21168844ebfcSPascal Brand res != TEE_ERROR_SHORT_BUFFER && 21171bc176d8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS && 21181bc176d8SJens Wiklander res != TEE_ERROR_CIPHERTEXT_INVALID && 21191bc176d8SJens Wiklander res != TEE_ERROR_NOT_SUPPORTED) 2120b0104773SPascal Brand TEE_Panic(res); 212112e66b6fSCedric Chaumont 2122b0104773SPascal Brand return res; 2123b0104773SPascal Brand } 2124b0104773SPascal Brand 21254f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricDecrypt(TEE_OperationHandle operation, 21264f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 21274f4374c8SJens Wiklander uint32_t paramCount, 21284f4374c8SJens Wiklander const void *srcData, uint32_t srcLen, 21294f4374c8SJens Wiklander void *destData, uint32_t *destLen) 21304f4374c8SJens Wiklander { 21314f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 21324f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 21334f4374c8SJens Wiklander uint64_t dl = 0; 21344f4374c8SJens Wiklander 21354f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 21364f4374c8SJens Wiklander TEE_Panic(0); 21374f4374c8SJens Wiklander 21384f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 21394f4374c8SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 21404f4374c8SJens Wiklander 21414f4374c8SJens Wiklander if (!operation->key1) 21424f4374c8SJens Wiklander TEE_Panic(0); 21434f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 21444f4374c8SJens Wiklander TEE_Panic(0); 21454f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_DECRYPT) 21464f4374c8SJens Wiklander TEE_Panic(0); 21474f4374c8SJens Wiklander 21484f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 21494f4374c8SJens Wiklander dl = *destLen; 21504f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 21514f4374c8SJens Wiklander srcLen, destData, &dl); 21524f4374c8SJens Wiklander *destLen = dl; 21534f4374c8SJens Wiklander 21544f4374c8SJens Wiklander if (res != TEE_SUCCESS && 21554f4374c8SJens Wiklander res != TEE_ERROR_SHORT_BUFFER && 21564f4374c8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS) 21574f4374c8SJens Wiklander TEE_Panic(res); 21584f4374c8SJens Wiklander 21594f4374c8SJens Wiklander return res; 21604f4374c8SJens Wiklander } 21614f4374c8SJens Wiklander 216212e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricSignDigest(TEE_OperationHandle operation, 21638f07fe6fSJerome Forissier const TEE_Attribute *params, 21648f07fe6fSJerome Forissier uint32_t paramCount, const void *digest, 21650b354ec8SJens Wiklander size_t digestLen, void *signature, 21660b354ec8SJens Wiklander size_t *signatureLen) 2167b0104773SPascal Brand { 21686915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 2169e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 21706915bbbbSJens Wiklander uint64_t sl = 0; 2171b0104773SPascal Brand 21726915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen)) 2173b0104773SPascal Brand TEE_Panic(0); 21746915bbbbSJens Wiklander 21756915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 21766915bbbbSJens Wiklander __utee_check_inout_annotation(signatureLen, sizeof(*signatureLen)); 21776915bbbbSJens Wiklander 217812e66b6fSCedric Chaumont if (!operation->key1) 2179b0104773SPascal Brand TEE_Panic(0); 218012e66b6fSCedric Chaumont if (operation->info.operationClass != 218112e66b6fSCedric Chaumont TEE_OPERATION_ASYMMETRIC_SIGNATURE) 218212e66b6fSCedric Chaumont TEE_Panic(0); 218312e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_SIGN) 2184b0104773SPascal Brand TEE_Panic(0); 2185b0104773SPascal Brand 2186e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 2187e86f1266SJens Wiklander sl = *signatureLen; 21882c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, digest, 2189e86f1266SJens Wiklander digestLen, signature, &sl); 2190e86f1266SJens Wiklander *signatureLen = sl; 219112e66b6fSCedric Chaumont 2192b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER) 2193b0104773SPascal Brand TEE_Panic(res); 219412e66b6fSCedric Chaumont 2195b0104773SPascal Brand return res; 2196b0104773SPascal Brand } 2197b0104773SPascal Brand 21984f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricSignDigest(TEE_OperationHandle operation, 21994f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 22004f4374c8SJens Wiklander uint32_t paramCount, 22014f4374c8SJens Wiklander const void *digest, 22024f4374c8SJens Wiklander uint32_t digestLen, void *signature, 22034f4374c8SJens Wiklander uint32_t *signatureLen) 22044f4374c8SJens Wiklander { 22054f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 22064f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 22074f4374c8SJens Wiklander uint64_t sl = 0; 22084f4374c8SJens Wiklander 22094f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen)) 22104f4374c8SJens Wiklander TEE_Panic(0); 22114f4374c8SJens Wiklander 22124f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 22134f4374c8SJens Wiklander __utee_check_inout_annotation(signatureLen, sizeof(*signatureLen)); 22144f4374c8SJens Wiklander 22154f4374c8SJens Wiklander if (!operation->key1) 22164f4374c8SJens Wiklander TEE_Panic(0); 22174f4374c8SJens Wiklander if (operation->info.operationClass != 22184f4374c8SJens Wiklander TEE_OPERATION_ASYMMETRIC_SIGNATURE) 22194f4374c8SJens Wiklander TEE_Panic(0); 22204f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_SIGN) 22214f4374c8SJens Wiklander TEE_Panic(0); 22224f4374c8SJens Wiklander 22234f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 22244f4374c8SJens Wiklander sl = *signatureLen; 22254f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, digest, 22264f4374c8SJens Wiklander digestLen, signature, &sl); 22274f4374c8SJens Wiklander *signatureLen = sl; 22284f4374c8SJens Wiklander 22294f4374c8SJens Wiklander if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER) 22304f4374c8SJens Wiklander TEE_Panic(res); 22314f4374c8SJens Wiklander 22324f4374c8SJens Wiklander return res; 22334f4374c8SJens Wiklander } 22344f4374c8SJens Wiklander 223512e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation, 22368f07fe6fSJerome Forissier const TEE_Attribute *params, 22378f07fe6fSJerome Forissier uint32_t paramCount, const void *digest, 22380b354ec8SJens Wiklander size_t digestLen, 22398f07fe6fSJerome Forissier const void *signature, 22400b354ec8SJens Wiklander size_t signatureLen) 2241b0104773SPascal Brand { 2242b0104773SPascal Brand TEE_Result res; 2243e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 2244b0104773SPascal Brand 224512e66b6fSCedric Chaumont if (operation == TEE_HANDLE_NULL || 224612e66b6fSCedric Chaumont (digest == NULL && digestLen != 0) || 2247b0104773SPascal Brand (signature == NULL && signatureLen != 0)) 2248b0104773SPascal Brand TEE_Panic(0); 22496915bbbbSJens Wiklander 22506915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 22516915bbbbSJens Wiklander 225212e66b6fSCedric Chaumont if (!operation->key1) 2253b0104773SPascal Brand TEE_Panic(0); 225412e66b6fSCedric Chaumont if (operation->info.operationClass != 225512e66b6fSCedric Chaumont TEE_OPERATION_ASYMMETRIC_SIGNATURE) 225612e66b6fSCedric Chaumont TEE_Panic(0); 225712e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_VERIFY) 2258b0104773SPascal Brand TEE_Panic(0); 2259b0104773SPascal Brand 2260e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 22612c028fdeSJerome Forissier res = _utee_asymm_verify(operation->state, ua, paramCount, digest, 226212e66b6fSCedric Chaumont digestLen, signature, signatureLen); 226312e66b6fSCedric Chaumont 2264b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID) 2265b0104773SPascal Brand TEE_Panic(res); 226612e66b6fSCedric Chaumont 2267b0104773SPascal Brand return res; 2268b0104773SPascal Brand } 2269b0104773SPascal Brand 22704f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation, 22714f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 22724f4374c8SJens Wiklander uint32_t paramCount, 22734f4374c8SJens Wiklander const void *digest, 22744f4374c8SJens Wiklander uint32_t digestLen, 22754f4374c8SJens Wiklander const void *signature, 22764f4374c8SJens Wiklander uint32_t signatureLen) 22774f4374c8SJens Wiklander { 22784f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 22794f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 22804f4374c8SJens Wiklander 22814f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen) || 22824f4374c8SJens Wiklander (!signature && signatureLen)) 22834f4374c8SJens Wiklander TEE_Panic(0); 22844f4374c8SJens Wiklander 22854f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 22864f4374c8SJens Wiklander 22874f4374c8SJens Wiklander if (!operation->key1) 22884f4374c8SJens Wiklander TEE_Panic(0); 22894f4374c8SJens Wiklander if (operation->info.operationClass != 22904f4374c8SJens Wiklander TEE_OPERATION_ASYMMETRIC_SIGNATURE) 22914f4374c8SJens Wiklander TEE_Panic(0); 22924f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_VERIFY) 22934f4374c8SJens Wiklander TEE_Panic(0); 22944f4374c8SJens Wiklander 22954f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 22964f4374c8SJens Wiklander res = _utee_asymm_verify(operation->state, ua, paramCount, digest, 22974f4374c8SJens Wiklander digestLen, signature, signatureLen); 22984f4374c8SJens Wiklander 22994f4374c8SJens Wiklander if (res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID) 23004f4374c8SJens Wiklander TEE_Panic(res); 23014f4374c8SJens Wiklander 23024f4374c8SJens Wiklander return res; 23034f4374c8SJens Wiklander } 23044f4374c8SJens Wiklander 2305b0104773SPascal Brand /* Cryptographic Operations API - Key Derivation Functions */ 2306b0104773SPascal Brand 2307b0104773SPascal Brand void TEE_DeriveKey(TEE_OperationHandle operation, 2308b0104773SPascal Brand const TEE_Attribute *params, uint32_t paramCount, 2309b0104773SPascal Brand TEE_ObjectHandle derivedKey) 2310b0104773SPascal Brand { 2311e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 231275d6a373SJens Wiklander struct utee_object_info key_info = { }; 231375d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 2314b0104773SPascal Brand 2315b0104773SPascal Brand if (operation == TEE_HANDLE_NULL || derivedKey == 0) 2316b0104773SPascal Brand TEE_Panic(0); 23176915bbbbSJens Wiklander 23186915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 23196915bbbbSJens Wiklander 23208854d3c6SJerome Forissier if (TEE_ALG_GET_CLASS(operation->info.algorithm) != 23218854d3c6SJerome Forissier TEE_OPERATION_KEY_DERIVATION) 2322b0104773SPascal Brand TEE_Panic(0); 2323b0104773SPascal Brand 2324b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_KEY_DERIVATION) 2325b0104773SPascal Brand TEE_Panic(0); 232684fa9467SCedric Chaumont if (!operation->key1) 232784fa9467SCedric Chaumont TEE_Panic(0); 2328b0104773SPascal Brand if (operation->info.mode != TEE_MODE_DERIVE) 2329b0104773SPascal Brand TEE_Panic(0); 2330b0104773SPascal Brand if ((operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0) 2331b0104773SPascal Brand TEE_Panic(0); 2332b0104773SPascal Brand 23332c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)derivedKey, &key_info); 2334b0104773SPascal Brand if (res != TEE_SUCCESS) 2335b36311adSJerome Forissier TEE_Panic(res); 2336b0104773SPascal Brand 233775d6a373SJens Wiklander if (key_info.obj_type != TEE_TYPE_GENERIC_SECRET) 2338b0104773SPascal Brand TEE_Panic(0); 233975d6a373SJens Wiklander if ((key_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 2340b0104773SPascal Brand TEE_Panic(0); 2341b0104773SPascal Brand 2342e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 23432c028fdeSJerome Forissier res = _utee_cryp_derive_key(operation->state, ua, paramCount, 2344e86f1266SJens Wiklander (unsigned long)derivedKey); 2345b0104773SPascal Brand if (res != TEE_SUCCESS) 2346b0104773SPascal Brand TEE_Panic(res); 2347b0104773SPascal Brand } 2348b0104773SPascal Brand 23494f4374c8SJens Wiklander void __GP11_TEE_DeriveKey(TEE_OperationHandle operation, 23504f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 23514f4374c8SJens Wiklander uint32_t paramCount, TEE_ObjectHandle derivedKey) 23524f4374c8SJens Wiklander { 23534f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 23544f4374c8SJens Wiklander struct utee_object_info key_info = { }; 23554f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 23564f4374c8SJens Wiklander 23574f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || derivedKey == 0) 23584f4374c8SJens Wiklander TEE_Panic(0); 23594f4374c8SJens Wiklander 23604f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 23614f4374c8SJens Wiklander 23624f4374c8SJens Wiklander if (TEE_ALG_GET_CLASS(operation->info.algorithm) != 23634f4374c8SJens Wiklander TEE_OPERATION_KEY_DERIVATION) 23644f4374c8SJens Wiklander TEE_Panic(0); 23654f4374c8SJens Wiklander 23664f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_KEY_DERIVATION) 23674f4374c8SJens Wiklander TEE_Panic(0); 23684f4374c8SJens Wiklander if (!operation->key1) 23694f4374c8SJens Wiklander TEE_Panic(0); 23704f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_DERIVE) 23714f4374c8SJens Wiklander TEE_Panic(0); 23724f4374c8SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0) 23734f4374c8SJens Wiklander TEE_Panic(0); 23744f4374c8SJens Wiklander 23754f4374c8SJens Wiklander res = _utee_cryp_obj_get_info((unsigned long)derivedKey, &key_info); 23764f4374c8SJens Wiklander if (res != TEE_SUCCESS) 23774f4374c8SJens Wiklander TEE_Panic(res); 23784f4374c8SJens Wiklander 23794f4374c8SJens Wiklander if (key_info.obj_type != TEE_TYPE_GENERIC_SECRET) 23804f4374c8SJens Wiklander TEE_Panic(0); 23814f4374c8SJens Wiklander if ((key_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 23824f4374c8SJens Wiklander TEE_Panic(0); 23834f4374c8SJens Wiklander 23844f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 23854f4374c8SJens Wiklander res = _utee_cryp_derive_key(operation->state, ua, paramCount, 23864f4374c8SJens Wiklander (unsigned long)derivedKey); 23874f4374c8SJens Wiklander if (res != TEE_SUCCESS) 23884f4374c8SJens Wiklander TEE_Panic(res); 23894f4374c8SJens Wiklander } 23904f4374c8SJens Wiklander 2391b0104773SPascal Brand /* Cryptographic Operations API - Random Number Generation Functions */ 2392b0104773SPascal Brand 2393411a488aSJens Wiklander void TEE_GenerateRandom(void *randomBuffer, size_t randomBufferLen) 2394b0104773SPascal Brand { 2395b0104773SPascal Brand TEE_Result res; 2396b0104773SPascal Brand 23972c028fdeSJerome Forissier res = _utee_cryp_random_number_generate(randomBuffer, randomBufferLen); 2398b0104773SPascal Brand if (res != TEE_SUCCESS) 2399b0104773SPascal Brand TEE_Panic(res); 2400b0104773SPascal Brand } 2401433c4257SJens Wiklander 2402411a488aSJens Wiklander void __GP11_TEE_GenerateRandom(void *randomBuffer, uint32_t randomBufferLen) 2403411a488aSJens Wiklander { 2404411a488aSJens Wiklander TEE_GenerateRandom(randomBuffer, randomBufferLen); 2405411a488aSJens Wiklander } 2406411a488aSJens Wiklander 2407433c4257SJens Wiklander int rand(void) 2408433c4257SJens Wiklander { 2409433c4257SJens Wiklander int rc; 2410433c4257SJens Wiklander 2411433c4257SJens Wiklander TEE_GenerateRandom(&rc, sizeof(rc)); 2412433c4257SJens Wiklander 2413433c4257SJens Wiklander /* 2414433c4257SJens Wiklander * RAND_MAX is the larges int, INT_MAX which is all bits but the 2415433c4257SJens Wiklander * highest bit set. 2416433c4257SJens Wiklander */ 2417433c4257SJens Wiklander return rc & RAND_MAX; 2418433c4257SJens Wiklander } 241979170ce0SJerome Forissier 242079170ce0SJerome Forissier TEE_Result TEE_IsAlgorithmSupported(uint32_t alg, uint32_t element) 242179170ce0SJerome Forissier { 242279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_AES)) { 242379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) { 242479170ce0SJerome Forissier if (alg == TEE_ALG_AES_ECB_NOPAD) 242579170ce0SJerome Forissier goto check_element_none; 242679170ce0SJerome Forissier } 242779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) { 242879170ce0SJerome Forissier if (alg == TEE_ALG_AES_CBC_NOPAD) 242979170ce0SJerome Forissier goto check_element_none; 243079170ce0SJerome Forissier } 243179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTR)) { 243279170ce0SJerome Forissier if (alg == TEE_ALG_AES_CTR) 243379170ce0SJerome Forissier goto check_element_none; 243479170ce0SJerome Forissier } 243579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTS)) { 243679170ce0SJerome Forissier if (alg == TEE_ALG_AES_CTS) 243779170ce0SJerome Forissier goto check_element_none; 243879170ce0SJerome Forissier } 243979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_XTS)) { 244079170ce0SJerome Forissier if (alg == TEE_ALG_AES_XTS) 244179170ce0SJerome Forissier goto check_element_none; 244279170ce0SJerome Forissier } 244379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC_MAC)) { 244479170ce0SJerome Forissier if (alg == TEE_ALG_AES_CBC_MAC_NOPAD || 244579170ce0SJerome Forissier alg == TEE_ALG_AES_CBC_MAC_PKCS5) 244679170ce0SJerome Forissier goto check_element_none; 244779170ce0SJerome Forissier } 244879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CMAC)) { 244979170ce0SJerome Forissier if (alg == TEE_ALG_AES_CMAC) 245079170ce0SJerome Forissier goto check_element_none; 245179170ce0SJerome Forissier } 245279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CCM)) { 245379170ce0SJerome Forissier if (alg == TEE_ALG_AES_CCM) 245479170ce0SJerome Forissier goto check_element_none; 245579170ce0SJerome Forissier } 245679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_GCM)) { 245779170ce0SJerome Forissier if (alg == TEE_ALG_AES_GCM) 245879170ce0SJerome Forissier goto check_element_none; 245979170ce0SJerome Forissier } 246079170ce0SJerome Forissier } 246179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DES)) { 246279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) { 246379170ce0SJerome Forissier if (alg == TEE_ALG_DES_ECB_NOPAD || 246479170ce0SJerome Forissier alg == TEE_ALG_DES3_ECB_NOPAD) 246579170ce0SJerome Forissier goto check_element_none; 246679170ce0SJerome Forissier } 246779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) { 246879170ce0SJerome Forissier if (alg == TEE_ALG_DES_CBC_NOPAD || 246979170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_NOPAD) 247079170ce0SJerome Forissier goto check_element_none; 247179170ce0SJerome Forissier } 247279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC_MAC)) { 247379170ce0SJerome Forissier if (alg == TEE_ALG_DES_CBC_MAC_NOPAD || 247479170ce0SJerome Forissier alg == TEE_ALG_DES_CBC_MAC_PKCS5 || 247579170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_MAC_NOPAD || 247679170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_MAC_PKCS5) 247779170ce0SJerome Forissier goto check_element_none; 247879170ce0SJerome Forissier } 247979170ce0SJerome Forissier } 248079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) { 248179170ce0SJerome Forissier if (alg == TEE_ALG_MD5) 248279170ce0SJerome Forissier goto check_element_none; 248379170ce0SJerome Forissier } 248479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 248579170ce0SJerome Forissier if (alg == TEE_ALG_SHA1) 248679170ce0SJerome Forissier goto check_element_none; 248779170ce0SJerome Forissier } 248879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 248979170ce0SJerome Forissier if (alg == TEE_ALG_SHA224) 249079170ce0SJerome Forissier goto check_element_none; 249179170ce0SJerome Forissier } 249279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 249379170ce0SJerome Forissier if (alg == TEE_ALG_SHA256) 249479170ce0SJerome Forissier goto check_element_none; 249579170ce0SJerome Forissier } 249679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) { 249779170ce0SJerome Forissier if (alg == TEE_ALG_SHA384) 249879170ce0SJerome Forissier goto check_element_none; 249979170ce0SJerome Forissier } 250079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) { 250179170ce0SJerome Forissier if (alg == TEE_ALG_SHA512) 250279170ce0SJerome Forissier goto check_element_none; 250379170ce0SJerome Forissier } 2504260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_224)) { 2505260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_224) 2506260b4028SJens Wiklander goto check_element_none; 2507260b4028SJens Wiklander } 2508260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_256)) { 2509260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_256) 2510260b4028SJens Wiklander goto check_element_none; 2511260b4028SJens Wiklander } 2512260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_384)) { 2513260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_384) 2514260b4028SJens Wiklander goto check_element_none; 2515260b4028SJens Wiklander } 2516260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_512)) { 2517260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_512) 2518260b4028SJens Wiklander goto check_element_none; 2519260b4028SJens Wiklander } 252079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5) && IS_ENABLED(CFG_CRYPTO_SHA1)) { 252179170ce0SJerome Forissier if (alg == TEE_ALG_MD5SHA1) 252279170ce0SJerome Forissier goto check_element_none; 252379170ce0SJerome Forissier } 252479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_HMAC)) { 252579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) { 252679170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_MD5) 252779170ce0SJerome Forissier goto check_element_none; 252879170ce0SJerome Forissier } 252979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 253079170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA1) 253179170ce0SJerome Forissier goto check_element_none; 253279170ce0SJerome Forissier } 253379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 253479170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA224) 253579170ce0SJerome Forissier goto check_element_none; 253679170ce0SJerome Forissier } 253779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 253879170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA256) 253979170ce0SJerome Forissier goto check_element_none; 254079170ce0SJerome Forissier } 254179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) { 254279170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA384) 254379170ce0SJerome Forissier goto check_element_none; 254479170ce0SJerome Forissier } 254579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) { 254679170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA512) 254779170ce0SJerome Forissier goto check_element_none; 254879170ce0SJerome Forissier } 2549260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_224)) { 2550260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_224) 2551260b4028SJens Wiklander goto check_element_none; 2552260b4028SJens Wiklander } 2553260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_256)) { 2554260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_256) 2555260b4028SJens Wiklander goto check_element_none; 2556260b4028SJens Wiklander } 2557260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_384)) { 2558260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_384) 2559260b4028SJens Wiklander goto check_element_none; 2560260b4028SJens Wiklander } 2561260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_512)) { 2562260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_512) 2563260b4028SJens Wiklander goto check_element_none; 2564260b4028SJens Wiklander } 256579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM3)) { 256679170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SM3) 256779170ce0SJerome Forissier goto check_element_none; 256879170ce0SJerome Forissier } 256979170ce0SJerome Forissier } 257079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM3)) { 257179170ce0SJerome Forissier if (alg == TEE_ALG_SM3) 257279170ce0SJerome Forissier goto check_element_none; 257379170ce0SJerome Forissier } 257479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM4)) { 257579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) { 257679170ce0SJerome Forissier if (alg == TEE_ALG_SM4_ECB_NOPAD) 257779170ce0SJerome Forissier goto check_element_none; 257879170ce0SJerome Forissier } 257979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) { 258079170ce0SJerome Forissier if (alg == TEE_ALG_SM4_CBC_NOPAD) 258179170ce0SJerome Forissier goto check_element_none; 258279170ce0SJerome Forissier } 258379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTR)) { 258479170ce0SJerome Forissier if (alg == TEE_ALG_SM4_CTR) 258579170ce0SJerome Forissier goto check_element_none; 258679170ce0SJerome Forissier } 2587696f56acSPingan Xie if (IS_ENABLED(CFG_CRYPTO_XTS)) { 2588696f56acSPingan Xie if (alg == TEE_ALG_SM4_XTS) 2589696f56acSPingan Xie goto check_element_none; 2590696f56acSPingan Xie } 259179170ce0SJerome Forissier } 259279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_RSA)) { 259379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) { 2594f5c3d85aSJulien Masson if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5 || 2595f5c3d85aSJulien Masson alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_MD5 || 2596f5c3d85aSJulien Masson alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_MD5) 259779170ce0SJerome Forissier goto check_element_none; 259879170ce0SJerome Forissier } 259979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 260079170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA1 || 260179170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1 || 260279170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1) 260379170ce0SJerome Forissier goto check_element_none; 260479170ce0SJerome Forissier } 260579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5) && IS_ENABLED(CFG_CRYPTO_SHA1)) { 260679170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5SHA1) 260779170ce0SJerome Forissier goto check_element_none; 260879170ce0SJerome Forissier } 260979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 261079170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA224 || 261179170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224 || 261279170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224) 261379170ce0SJerome Forissier goto check_element_none; 261479170ce0SJerome Forissier } 261579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 261679170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA256 || 261779170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 || 261879170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256) 261979170ce0SJerome Forissier goto check_element_none; 262079170ce0SJerome Forissier } 262179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) { 262279170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA384 || 262379170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384 || 262479170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384) 262579170ce0SJerome Forissier goto check_element_none; 262679170ce0SJerome Forissier } 262779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) { 262879170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA512 || 262979170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512 || 263079170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512) 263179170ce0SJerome Forissier goto check_element_none; 263279170ce0SJerome Forissier } 263379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_RSASSA_NA1)) { 263479170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5) 263579170ce0SJerome Forissier goto check_element_none; 263679170ce0SJerome Forissier } 263779170ce0SJerome Forissier if (alg == TEE_ALG_RSA_NOPAD) 263879170ce0SJerome Forissier goto check_element_none; 263979170ce0SJerome Forissier } 264079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DSA)) { 264179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 264279170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA1) 264379170ce0SJerome Forissier goto check_element_none; 264479170ce0SJerome Forissier } 264579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 264679170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA224) 264779170ce0SJerome Forissier goto check_element_none; 264879170ce0SJerome Forissier } 264979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 265079170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA256) 265179170ce0SJerome Forissier goto check_element_none; 265279170ce0SJerome Forissier } 265379170ce0SJerome Forissier } 265479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DH)) { 265579170ce0SJerome Forissier if (alg == TEE_ALG_DH_DERIVE_SHARED_SECRET) 265679170ce0SJerome Forissier goto check_element_none; 265779170ce0SJerome Forissier } 265879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECC)) { 2659fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P192 || 2660fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P192 || 2661fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2662fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA1) && 266379170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P192) 266479170ce0SJerome Forissier return TEE_SUCCESS; 2665fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P224 || 2666fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P224 || 2667fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2668fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA224) && 266979170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P224) 267079170ce0SJerome Forissier return TEE_SUCCESS; 2671fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P256 || 2672fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P256 || 2673fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2674fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA256) && 267579170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P256) 267679170ce0SJerome Forissier return TEE_SUCCESS; 2677fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P384 || 2678fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P384 || 2679fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2680fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA384) && 268179170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P384) 268279170ce0SJerome Forissier return TEE_SUCCESS; 2683fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P521 || 2684fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P521 || 2685fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2686fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA512) && 268779170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P521) 268879170ce0SJerome Forissier return TEE_SUCCESS; 268979170ce0SJerome Forissier } 269079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_DSA)) { 269179170ce0SJerome Forissier if (alg == TEE_ALG_SM2_DSA_SM3 && element == TEE_ECC_CURVE_SM2) 269279170ce0SJerome Forissier return TEE_SUCCESS; 269379170ce0SJerome Forissier } 269479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_KEP)) { 269579170ce0SJerome Forissier if (alg == TEE_ALG_SM2_KEP && element == TEE_ECC_CURVE_SM2) 269679170ce0SJerome Forissier return TEE_SUCCESS; 269779170ce0SJerome Forissier } 269879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_PKE)) { 269979170ce0SJerome Forissier if (alg == TEE_ALG_SM2_PKE && element == TEE_ECC_CURVE_SM2) 270079170ce0SJerome Forissier return TEE_SUCCESS; 270179170ce0SJerome Forissier } 27023f61056dSSohaib ul Hassan if (IS_ENABLED(CFG_CRYPTO_X25519)) { 27033f61056dSSohaib ul Hassan if (alg == TEE_ALG_X25519 && element == TEE_ECC_CURVE_25519) 27043f61056dSSohaib ul Hassan return TEE_SUCCESS; 27053f61056dSSohaib ul Hassan } 2706e1f9cee7SSergiy Kibrik if (IS_ENABLED(CFG_CRYPTO_ED25519)) { 2707e1f9cee7SSergiy Kibrik if (alg == TEE_ALG_ED25519 && element == TEE_ECC_CURVE_25519) 2708e1f9cee7SSergiy Kibrik return TEE_SUCCESS; 2709e1f9cee7SSergiy Kibrik } 271079170ce0SJerome Forissier 271179170ce0SJerome Forissier return TEE_ERROR_NOT_SUPPORTED; 271279170ce0SJerome Forissier check_element_none: 271379170ce0SJerome Forissier if (element == TEE_CRYPTO_ELEMENT_NONE) 271479170ce0SJerome Forissier return TEE_SUCCESS; 271579170ce0SJerome Forissier return TEE_ERROR_NOT_SUPPORTED; 271679170ce0SJerome Forissier } 2717