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 */ 6*24ea7613SJens 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 */ 24*24ea7613SJens Wiklander 25*24ea7613SJens Wiklander /* 26*24ea7613SJens Wiklander * buffer to collect complete blocks or to keep a complete digest 27*24ea7613SJens Wiklander * for TEE_DigestExtract(). 28*24ea7613SJens Wiklander */ 29*24ea7613SJens 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 135cf5c060cSJens Wiklander /* Check algorithm mode (and maxKeySize for digests) */ 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: 178b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1: 179b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224: 180b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256: 181b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384: 182b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512: 183b0104773SPascal Brand case TEE_ALG_DSA_SHA1: 184218d9055SCedric Chaumont case TEE_ALG_DSA_SHA224: 185218d9055SCedric Chaumont case TEE_ALG_DSA_SHA256: 186fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA1: 187fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA224: 188fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA256: 189fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA384: 190fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA512: 191fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P192: 192fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P224: 193fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P256: 194fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P384: 195fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P521: 1960f151943SJerome Forissier case TEE_ALG_SM2_DSA_SM3: 197e1f9cee7SSergiy Kibrik case TEE_ALG_ED25519: 198b0104773SPascal Brand if (mode == TEE_MODE_SIGN) { 199b0104773SPascal Brand with_private_key = true; 200b0104773SPascal Brand req_key_usage = TEE_USAGE_SIGN; 201b0104773SPascal Brand } else if (mode == TEE_MODE_VERIFY) { 202b0104773SPascal Brand req_key_usage = TEE_USAGE_VERIFY; 203b0104773SPascal Brand } else { 204b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 205b0104773SPascal Brand } 206b0104773SPascal Brand break; 207b0104773SPascal Brand 208b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_V1_5: 209b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1: 210b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224: 211b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256: 212b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384: 213b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512: 21491fc6bd8SJerome Forissier case TEE_ALG_SM2_PKE: 215b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) { 216b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT; 217b0104773SPascal Brand } else if (mode == TEE_MODE_DECRYPT) { 218b0104773SPascal Brand with_private_key = true; 219b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT; 220b0104773SPascal Brand } else { 221b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 222b0104773SPascal Brand } 223b0104773SPascal Brand break; 224b0104773SPascal Brand 225b0104773SPascal Brand case TEE_ALG_RSA_NOPAD: 226b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) { 227b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT | TEE_USAGE_VERIFY; 228b0104773SPascal Brand } else if (mode == TEE_MODE_DECRYPT) { 229b0104773SPascal Brand with_private_key = true; 230b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT | TEE_USAGE_SIGN; 231b0104773SPascal Brand } else { 232b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 233b0104773SPascal Brand } 234b0104773SPascal Brand break; 235b0104773SPascal Brand 236b0104773SPascal Brand case TEE_ALG_DH_DERIVE_SHARED_SECRET: 237fe2fd3ffSJens Wiklander case TEE_ALG_ECDH_DERIVE_SHARED_SECRET: 238fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P192: 239fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P224: 240fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P256: 241fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P384: 242fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P521: 243cdb198a7SJerome Forissier case TEE_ALG_HKDF_MD5_DERIVE_KEY: 244cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA1_DERIVE_KEY: 245cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA224_DERIVE_KEY: 246cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA256_DERIVE_KEY: 247cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA384_DERIVE_KEY: 248cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA512_DERIVE_KEY: 2498854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA1_DERIVE_KEY: 2508854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA224_DERIVE_KEY: 2518854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA256_DERIVE_KEY: 2528854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA384_DERIVE_KEY: 2538854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA512_DERIVE_KEY: 2540f2293b7SJerome Forissier case TEE_ALG_PBKDF2_HMAC_SHA1_DERIVE_KEY: 2555b385b3fSJerome Forissier case TEE_ALG_SM2_KEP: 2563f61056dSSohaib ul Hassan case TEE_ALG_X25519: 257b0104773SPascal Brand if (mode != TEE_MODE_DERIVE) 258b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 259b0104773SPascal Brand with_private_key = true; 260b0104773SPascal Brand req_key_usage = TEE_USAGE_DERIVE; 261b0104773SPascal Brand break; 262b0104773SPascal Brand 263b0104773SPascal Brand case TEE_ALG_MD5: 264b0104773SPascal Brand case TEE_ALG_SHA1: 265b0104773SPascal Brand case TEE_ALG_SHA224: 266b0104773SPascal Brand case TEE_ALG_SHA256: 267b0104773SPascal Brand case TEE_ALG_SHA384: 268b0104773SPascal Brand case TEE_ALG_SHA512: 269*24ea7613SJens Wiklander case TEE_ALG_SHA3_224: 270*24ea7613SJens Wiklander case TEE_ALG_SHA3_256: 271*24ea7613SJens Wiklander case TEE_ALG_SHA3_384: 272*24ea7613SJens Wiklander case TEE_ALG_SHA3_512: 273*24ea7613SJens Wiklander case TEE_ALG_SHAKE128: 274*24ea7613SJens Wiklander case TEE_ALG_SHAKE256: 27547645577SJerome Forissier case TEE_ALG_SM3: 276b0104773SPascal Brand if (mode != TEE_MODE_DIGEST) 277b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED; 278cf5c060cSJens Wiklander if (maxKeySize) 279cf5c060cSJens Wiklander 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 329*24ea7613SJens Wiklander /* 330*24ea7613SJens Wiklander * Needed to buffer the digest if TEE_DigestExtract() doesn't 331*24ea7613SJens Wiklander * retrieve the entire digest in one go. 332*24ea7613SJens Wiklander */ 333*24ea7613SJens Wiklander if (op->info.operationClass == TEE_OPERATION_DIGEST) 334*24ea7613SJens Wiklander block_size = op->info.digestLength; 335*24ea7613SJens 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 563b0104773SPascal Brand void TEE_ResetOperation(TEE_OperationHandle operation) 564b0104773SPascal Brand { 565b0104773SPascal Brand TEE_Result res; 566b0104773SPascal Brand 567b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 568b0104773SPascal Brand TEE_Panic(0); 569bf80076aSCedric Chaumont 570642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET)) 571bf80076aSCedric Chaumont TEE_Panic(0); 572bf80076aSCedric Chaumont 573642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 574642a1607SCedric Chaumont 575b0104773SPascal Brand if (operation->info.operationClass == TEE_OPERATION_DIGEST) { 5762c028fdeSJerome Forissier res = _utee_hash_init(operation->state, NULL, 0); 577b0104773SPascal Brand if (res != TEE_SUCCESS) 578b0104773SPascal Brand TEE_Panic(res); 57905304565SCedric Chaumont operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 58005304565SCedric Chaumont } else { 581b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 582b0104773SPascal Brand } 58305304565SCedric Chaumont } 584b0104773SPascal Brand 585b0104773SPascal Brand TEE_Result TEE_SetOperationKey(TEE_OperationHandle operation, 586b0104773SPascal Brand TEE_ObjectHandle key) 587b0104773SPascal Brand { 5887583c59eSCedric Chaumont TEE_Result res; 589b0104773SPascal Brand uint32_t key_size = 0; 590b0104773SPascal Brand TEE_ObjectInfo key_info; 591b0104773SPascal Brand 592a57c1e2eSCedric Chaumont if (operation == TEE_HANDLE_NULL) { 593a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 594a57c1e2eSCedric Chaumont goto out; 595a57c1e2eSCedric Chaumont } 596a57c1e2eSCedric Chaumont 597642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) { 598642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 599642a1607SCedric Chaumont goto out; 600642a1607SCedric Chaumont } 601642a1607SCedric Chaumont 602a57c1e2eSCedric Chaumont if (key == TEE_HANDLE_NULL) { 603a57c1e2eSCedric Chaumont /* Operation key cleared */ 604a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key1); 6056c4ea258SJens Wiklander operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 6066c4ea258SJens Wiklander return TEE_SUCCESS; 607a57c1e2eSCedric Chaumont } 608a57c1e2eSCedric Chaumont 609a57c1e2eSCedric Chaumont /* No key for digest operation */ 610a57c1e2eSCedric Chaumont if (operation->info.operationClass == TEE_OPERATION_DIGEST) { 611a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 612a57c1e2eSCedric Chaumont goto out; 613a57c1e2eSCedric Chaumont } 614a57c1e2eSCedric Chaumont 615a57c1e2eSCedric Chaumont /* Two keys flag not expected (TEE_ALG_AES_XTS excluded) */ 616a57c1e2eSCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) != 617a57c1e2eSCedric Chaumont 0) { 618a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 619a57c1e2eSCedric Chaumont goto out; 620a57c1e2eSCedric Chaumont } 621a57c1e2eSCedric Chaumont 6227583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key, &key_info); 623a57c1e2eSCedric Chaumont /* Key is not a valid handle */ 6247583c59eSCedric Chaumont if (res != TEE_SUCCESS) 625a57c1e2eSCedric Chaumont goto out; 6267583c59eSCedric Chaumont 627b0104773SPascal Brand /* Supplied key has to meet required usage */ 628b0104773SPascal Brand if ((key_info.objectUsage & operation->info.requiredKeyUsage) != 629b0104773SPascal Brand operation->info.requiredKeyUsage) { 630a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 631a57c1e2eSCedric Chaumont goto out; 632b0104773SPascal Brand } 633b0104773SPascal Brand 634d372a47cSJens Wiklander if (operation->info.maxKeySize < key_info.objectSize) { 635a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 636a57c1e2eSCedric Chaumont goto out; 637a57c1e2eSCedric Chaumont } 638b0104773SPascal Brand 639d372a47cSJens Wiklander key_size = key_info.objectSize; 640b0104773SPascal Brand 641b0104773SPascal Brand TEE_ResetTransientObject(operation->key1); 642b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 643b0104773SPascal Brand 6447583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key1, key); 6457583c59eSCedric Chaumont if (res != TEE_SUCCESS) 646a57c1e2eSCedric Chaumont goto out; 6477583c59eSCedric Chaumont 648b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET; 649b0104773SPascal Brand 650b0104773SPascal Brand operation->info.keySize = key_size; 651b0104773SPascal Brand 6527583c59eSCedric Chaumont out: 653a57c1e2eSCedric Chaumont if (res != TEE_SUCCESS && 654a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 655a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 656b36311adSJerome Forissier TEE_Panic(res); 657a57c1e2eSCedric Chaumont 658a57c1e2eSCedric Chaumont return res; 659b0104773SPascal Brand } 660b0104773SPascal Brand 661b0104773SPascal Brand TEE_Result TEE_SetOperationKey2(TEE_OperationHandle operation, 662b0104773SPascal Brand TEE_ObjectHandle key1, TEE_ObjectHandle key2) 663b0104773SPascal Brand { 6647583c59eSCedric Chaumont TEE_Result res; 665b0104773SPascal Brand uint32_t key_size = 0; 666b0104773SPascal Brand TEE_ObjectInfo key_info1; 667b0104773SPascal Brand TEE_ObjectInfo key_info2; 668b0104773SPascal Brand 669a57c1e2eSCedric Chaumont if (operation == TEE_HANDLE_NULL) { 670a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 671a57c1e2eSCedric Chaumont goto out; 672a57c1e2eSCedric Chaumont } 673a57c1e2eSCedric Chaumont 674642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) { 675642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 676642a1607SCedric Chaumont goto out; 677642a1607SCedric Chaumont } 678642a1607SCedric Chaumont 679a57c1e2eSCedric Chaumont /* 680a57c1e2eSCedric Chaumont * Key1/Key2 and/or are not initialized and 681a57c1e2eSCedric Chaumont * Either both keys are NULL or both are not NULL 682a57c1e2eSCedric Chaumont */ 6836c4ea258SJens Wiklander if (!key1 && !key2) { 6846c4ea258SJens Wiklander /* Clear the keys */ 685a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key1); 686a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key2); 6876c4ea258SJens Wiklander operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 6886c4ea258SJens Wiklander return TEE_SUCCESS; 6896c4ea258SJens Wiklander } else if (!key1 || !key2) { 6906c4ea258SJens Wiklander /* Both keys are obviously not valid. */ 691a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 692a57c1e2eSCedric Chaumont goto out; 693a57c1e2eSCedric Chaumont } 694a57c1e2eSCedric Chaumont 695a57c1e2eSCedric Chaumont /* No key for digest operation */ 696a57c1e2eSCedric Chaumont if (operation->info.operationClass == TEE_OPERATION_DIGEST) { 697a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 698a57c1e2eSCedric Chaumont goto out; 699a57c1e2eSCedric Chaumont } 700a57c1e2eSCedric Chaumont 7015b385b3fSJerome Forissier /* Two keys flag expected (TEE_ALG_AES_XTS and TEE_ALG_SM2_KEP only) */ 702a57c1e2eSCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 703a57c1e2eSCedric Chaumont 0) { 704a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 705a57c1e2eSCedric Chaumont goto out; 706a57c1e2eSCedric Chaumont } 707a57c1e2eSCedric Chaumont 7087583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key1, &key_info1); 709a57c1e2eSCedric Chaumont /* Key1 is not a valid handle */ 7107583c59eSCedric Chaumont if (res != TEE_SUCCESS) 711a57c1e2eSCedric Chaumont goto out; 7127583c59eSCedric Chaumont 713b0104773SPascal Brand /* Supplied key has to meet required usage */ 714b0104773SPascal Brand if ((key_info1.objectUsage & operation->info. 715b0104773SPascal Brand requiredKeyUsage) != operation->info.requiredKeyUsage) { 716a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 717a57c1e2eSCedric Chaumont goto out; 718b0104773SPascal Brand } 719b0104773SPascal Brand 7207583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key2, &key_info2); 721a57c1e2eSCedric Chaumont /* Key2 is not a valid handle */ 7227583c59eSCedric Chaumont if (res != TEE_SUCCESS) { 7237583c59eSCedric Chaumont if (res == TEE_ERROR_CORRUPT_OBJECT) 7247583c59eSCedric Chaumont res = TEE_ERROR_CORRUPT_OBJECT_2; 725a57c1e2eSCedric Chaumont goto out; 7267583c59eSCedric Chaumont } 7277583c59eSCedric Chaumont 728b0104773SPascal Brand /* Supplied key has to meet required usage */ 729b0104773SPascal Brand if ((key_info2.objectUsage & operation->info. 730b0104773SPascal Brand requiredKeyUsage) != operation->info.requiredKeyUsage) { 731a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 732a57c1e2eSCedric Chaumont goto out; 733b0104773SPascal Brand } 734b0104773SPascal Brand 735b0104773SPascal Brand /* 7365b385b3fSJerome Forissier * All the multi key algorithm currently supported requires the keys to 7375b385b3fSJerome Forissier * be of equal size. 738b0104773SPascal Brand */ 739d372a47cSJens Wiklander if (key_info1.objectSize != key_info2.objectSize) { 740a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 741a57c1e2eSCedric Chaumont goto out; 742b0104773SPascal Brand 743a57c1e2eSCedric Chaumont } 744a57c1e2eSCedric Chaumont 745d372a47cSJens Wiklander if (operation->info.maxKeySize < key_info1.objectSize) { 746a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 747a57c1e2eSCedric Chaumont goto out; 748a57c1e2eSCedric Chaumont } 749b0104773SPascal Brand 750b0104773SPascal Brand /* 751b0104773SPascal Brand * Odd that only the size of one key should be reported while 752b0104773SPascal Brand * size of two key are used when allocating the operation. 753b0104773SPascal Brand */ 754d372a47cSJens Wiklander key_size = key_info1.objectSize; 755b0104773SPascal Brand 756b0104773SPascal Brand TEE_ResetTransientObject(operation->key1); 757b0104773SPascal Brand TEE_ResetTransientObject(operation->key2); 758b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET; 759b0104773SPascal Brand 7607583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key1, key1); 7617583c59eSCedric Chaumont if (res != TEE_SUCCESS) 762a57c1e2eSCedric Chaumont goto out; 7637583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key2, key2); 7647583c59eSCedric Chaumont if (res != TEE_SUCCESS) { 7657583c59eSCedric Chaumont if (res == TEE_ERROR_CORRUPT_OBJECT) 7667583c59eSCedric Chaumont res = TEE_ERROR_CORRUPT_OBJECT_2; 767a57c1e2eSCedric Chaumont goto out; 7687583c59eSCedric Chaumont } 7697583c59eSCedric Chaumont 770b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET; 771b0104773SPascal Brand 772b0104773SPascal Brand operation->info.keySize = key_size; 773b0104773SPascal Brand 7747583c59eSCedric Chaumont out: 775a57c1e2eSCedric Chaumont if (res != TEE_SUCCESS && 776a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT && 777a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT_2 && 778a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE && 779a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE_2) 780b36311adSJerome Forissier TEE_Panic(res); 781a57c1e2eSCedric Chaumont 782a57c1e2eSCedric Chaumont return res; 783b0104773SPascal Brand } 784b0104773SPascal Brand 785b0104773SPascal Brand void TEE_CopyOperation(TEE_OperationHandle dst_op, TEE_OperationHandle src_op) 786b0104773SPascal Brand { 787b0104773SPascal Brand TEE_Result res; 788b0104773SPascal Brand 789b0104773SPascal Brand if (dst_op == TEE_HANDLE_NULL || src_op == TEE_HANDLE_NULL) 790b0104773SPascal Brand TEE_Panic(0); 791b0104773SPascal Brand if (dst_op->info.algorithm != src_op->info.algorithm) 792b0104773SPascal Brand TEE_Panic(0); 7938734de30SJens Wiklander if (dst_op->info.mode != src_op->info.mode) 7948734de30SJens Wiklander TEE_Panic(0); 795b0104773SPascal Brand if (src_op->info.operationClass != TEE_OPERATION_DIGEST) { 796b0104773SPascal Brand TEE_ObjectHandle key1 = TEE_HANDLE_NULL; 797b0104773SPascal Brand TEE_ObjectHandle key2 = TEE_HANDLE_NULL; 798b0104773SPascal Brand 799b0104773SPascal Brand if (src_op->info.handleState & TEE_HANDLE_FLAG_KEY_SET) { 800b0104773SPascal Brand key1 = src_op->key1; 801b0104773SPascal Brand key2 = src_op->key2; 802b0104773SPascal Brand } 803b0104773SPascal Brand 804b0104773SPascal Brand if ((src_op->info.handleState & 805b0104773SPascal Brand TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 0) { 806b0104773SPascal Brand TEE_SetOperationKey(dst_op, key1); 807b0104773SPascal Brand } else { 808b0104773SPascal Brand TEE_SetOperationKey2(dst_op, key1, key2); 809b0104773SPascal Brand } 810b0104773SPascal Brand } 811b0104773SPascal Brand dst_op->info.handleState = src_op->info.handleState; 812b0104773SPascal Brand dst_op->info.keySize = src_op->info.keySize; 8138e07702eSJens Wiklander dst_op->info.digestLength = src_op->info.digestLength; 814642a1607SCedric Chaumont dst_op->operationState = src_op->operationState; 815b0104773SPascal Brand 816b0104773SPascal Brand if (dst_op->buffer_two_blocks != src_op->buffer_two_blocks || 817b0104773SPascal Brand dst_op->block_size != src_op->block_size) 818b0104773SPascal Brand TEE_Panic(0); 819b0104773SPascal Brand 820b0104773SPascal Brand if (dst_op->buffer != NULL) { 821*24ea7613SJens Wiklander size_t sz = src_op->block_size; 822*24ea7613SJens Wiklander 823b0104773SPascal Brand if (src_op->buffer == NULL) 824b0104773SPascal Brand TEE_Panic(0); 825b0104773SPascal Brand 826*24ea7613SJens Wiklander if (src_op->buffer_two_blocks) 827*24ea7613SJens Wiklander sz *= 2; 828*24ea7613SJens Wiklander memcpy(dst_op->buffer, src_op->buffer, sz); 829b0104773SPascal Brand dst_op->buffer_offs = src_op->buffer_offs; 830b0104773SPascal Brand } else if (src_op->buffer != NULL) { 831b0104773SPascal Brand TEE_Panic(0); 832b0104773SPascal Brand } 833b0104773SPascal Brand 8342c028fdeSJerome Forissier res = _utee_cryp_state_copy(dst_op->state, src_op->state); 835b0104773SPascal Brand if (res != TEE_SUCCESS) 836b0104773SPascal Brand TEE_Panic(res); 837b0104773SPascal Brand } 838b0104773SPascal Brand 839b0104773SPascal Brand /* Cryptographic Operations API - Message Digest Functions */ 840b0104773SPascal Brand 8418f07fe6fSJerome Forissier static void init_hash_operation(TEE_OperationHandle operation, const void *IV, 8426d15db08SJerome Forissier uint32_t IVLen) 8436d15db08SJerome Forissier { 8446d15db08SJerome Forissier TEE_Result res; 8456d15db08SJerome Forissier 8466d15db08SJerome Forissier /* 8476d15db08SJerome Forissier * Note : IV and IVLen are never used in current implementation 8486d15db08SJerome Forissier * This is why coherent values of IV and IVLen are not checked 8496d15db08SJerome Forissier */ 8502c028fdeSJerome Forissier res = _utee_hash_init(operation->state, IV, IVLen); 8516d15db08SJerome Forissier if (res != TEE_SUCCESS) 8526d15db08SJerome Forissier TEE_Panic(res); 8536d15db08SJerome Forissier operation->buffer_offs = 0; 8546d15db08SJerome Forissier operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 8556d15db08SJerome Forissier } 8566d15db08SJerome Forissier 857b0104773SPascal Brand void TEE_DigestUpdate(TEE_OperationHandle operation, 858185bf58cSJens Wiklander const void *chunk, size_t chunkSize) 859b0104773SPascal Brand { 86073d6c3baSJoakim Bech TEE_Result res = TEE_ERROR_GENERIC; 861b0104773SPascal Brand 86273d6c3baSJoakim Bech if (operation == TEE_HANDLE_NULL || 86373d6c3baSJoakim Bech operation->info.operationClass != TEE_OPERATION_DIGEST) 864b0104773SPascal Brand TEE_Panic(0); 86573d6c3baSJoakim Bech 866642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 867642a1607SCedric Chaumont 8682c028fdeSJerome Forissier res = _utee_hash_update(operation->state, chunk, chunkSize); 869b0104773SPascal Brand if (res != TEE_SUCCESS) 870b0104773SPascal Brand TEE_Panic(res); 871b0104773SPascal Brand } 872b0104773SPascal Brand 873185bf58cSJens Wiklander void __GP11_TEE_DigestUpdate(TEE_OperationHandle operation, 874185bf58cSJens Wiklander const void *chunk, uint32_t chunkSize) 875185bf58cSJens Wiklander { 876185bf58cSJens Wiklander return TEE_DigestUpdate(operation, chunk, chunkSize); 877185bf58cSJens Wiklander } 878185bf58cSJens Wiklander 8798f07fe6fSJerome Forissier TEE_Result TEE_DigestDoFinal(TEE_OperationHandle operation, const void *chunk, 880185bf58cSJens Wiklander size_t chunkLen, void *hash, size_t *hashLen) 881b0104773SPascal Brand { 882*24ea7613SJens Wiklander TEE_Result res = TEE_SUCCESS; 883*24ea7613SJens Wiklander uint64_t hl = 0; 884*24ea7613SJens Wiklander size_t len = 0; 88587c2f6b6SCedric Chaumont 88687c2f6b6SCedric Chaumont if ((operation == TEE_HANDLE_NULL) || 88787c2f6b6SCedric Chaumont (!chunk && chunkLen) || 88887c2f6b6SCedric Chaumont (operation->info.operationClass != TEE_OPERATION_DIGEST)) { 88987c2f6b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 89087c2f6b6SCedric Chaumont goto out; 89187c2f6b6SCedric Chaumont } 892*24ea7613SJens Wiklander if (operation->operationState == TEE_OPERATION_STATE_EXTRACTING && 893*24ea7613SJens Wiklander chunkLen) { 894*24ea7613SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 895*24ea7613SJens Wiklander goto out; 896*24ea7613SJens Wiklander } 8976915bbbbSJens Wiklander __utee_check_inout_annotation(hashLen, sizeof(*hashLen)); 89887c2f6b6SCedric Chaumont 899*24ea7613SJens Wiklander if (operation->operationState == TEE_OPERATION_STATE_EXTRACTING && 900*24ea7613SJens Wiklander operation->buffer) { 901*24ea7613SJens Wiklander /* 902*24ea7613SJens Wiklander * This is not an Extendable-Output Function and we have 903*24ea7613SJens Wiklander * already started extracting 904*24ea7613SJens Wiklander */ 905*24ea7613SJens Wiklander len = MIN(operation->block_size - operation->buffer_offs, 906*24ea7613SJens Wiklander *hashLen); 907*24ea7613SJens Wiklander memcpy(hash, operation->buffer + operation->buffer_offs, len); 908*24ea7613SJens Wiklander *hashLen = len; 909*24ea7613SJens Wiklander } else { 910e86f1266SJens Wiklander hl = *hashLen; 911*24ea7613SJens Wiklander res = _utee_hash_final(operation->state, chunk, chunkLen, hash, 912*24ea7613SJens Wiklander &hl); 913e86f1266SJens Wiklander *hashLen = hl; 914*24ea7613SJens Wiklander if (res) 9156d15db08SJerome Forissier goto out; 916*24ea7613SJens Wiklander } 9176d15db08SJerome Forissier 9186d15db08SJerome Forissier /* Reset operation state */ 9196d15db08SJerome Forissier init_hash_operation(operation, NULL, 0); 92087c2f6b6SCedric Chaumont 921642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 922642a1607SCedric Chaumont 92387c2f6b6SCedric Chaumont out: 92487c2f6b6SCedric Chaumont if (res != TEE_SUCCESS && 92587c2f6b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 926b36311adSJerome Forissier TEE_Panic(res); 92773d6c3baSJoakim Bech 92887c2f6b6SCedric Chaumont return res; 929b0104773SPascal Brand } 930b0104773SPascal Brand 931185bf58cSJens Wiklander TEE_Result __GP11_TEE_DigestDoFinal(TEE_OperationHandle operation, 932185bf58cSJens Wiklander const void *chunk, uint32_t chunkLen, 933185bf58cSJens Wiklander void *hash, uint32_t *hashLen) 934185bf58cSJens Wiklander { 935185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 936185bf58cSJens Wiklander size_t l = 0; 937185bf58cSJens Wiklander 938185bf58cSJens Wiklander __utee_check_inout_annotation(hashLen, sizeof(*hashLen)); 939185bf58cSJens Wiklander l = *hashLen; 940185bf58cSJens Wiklander res = TEE_DigestDoFinal(operation, chunk, chunkLen, hash, &l); 941185bf58cSJens Wiklander *hashLen = l; 942185bf58cSJens Wiklander return res; 943185bf58cSJens Wiklander } 944185bf58cSJens Wiklander 945*24ea7613SJens Wiklander TEE_Result TEE_DigestExtract(TEE_OperationHandle operation, void *hash, 946*24ea7613SJens Wiklander size_t *hashLen) 947*24ea7613SJens Wiklander { 948*24ea7613SJens Wiklander TEE_Result res = TEE_SUCCESS; 949*24ea7613SJens Wiklander uint64_t hl = 0; 950*24ea7613SJens Wiklander size_t len = 0; 951*24ea7613SJens Wiklander 952*24ea7613SJens Wiklander if (operation == TEE_HANDLE_NULL || 953*24ea7613SJens Wiklander operation->info.operationClass != TEE_OPERATION_DIGEST) 954*24ea7613SJens Wiklander TEE_Panic(0); 955*24ea7613SJens Wiklander __utee_check_inout_annotation(hashLen, sizeof(*hashLen)); 956*24ea7613SJens Wiklander 957*24ea7613SJens Wiklander if (!operation->buffer) { 958*24ea7613SJens Wiklander /* This is an Extendable-Output Function */ 959*24ea7613SJens Wiklander operation->info.handleState |= TEE_HANDLE_FLAG_EXTRACTING; 960*24ea7613SJens Wiklander operation->operationState = TEE_OPERATION_STATE_EXTRACTING; 961*24ea7613SJens Wiklander hl = *hashLen; 962*24ea7613SJens Wiklander res = _utee_hash_final(operation->state, NULL, 0, hash, &hl); 963*24ea7613SJens Wiklander if (res) 964*24ea7613SJens Wiklander TEE_Panic(0); 965*24ea7613SJens Wiklander *hashLen = hl; 966*24ea7613SJens Wiklander 967*24ea7613SJens Wiklander return TEE_SUCCESS; 968*24ea7613SJens Wiklander } 969*24ea7613SJens Wiklander 970*24ea7613SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_EXTRACTING) { 971*24ea7613SJens Wiklander hl = operation->block_size; 972*24ea7613SJens Wiklander res = _utee_hash_final(operation->state, NULL, 0, 973*24ea7613SJens Wiklander operation->buffer, &hl); 974*24ea7613SJens Wiklander if (res) 975*24ea7613SJens Wiklander TEE_Panic(0); 976*24ea7613SJens Wiklander if (hl != operation->block_size) 977*24ea7613SJens Wiklander TEE_Panic(0); 978*24ea7613SJens Wiklander assert(!operation->buffer_offs); 979*24ea7613SJens Wiklander operation->info.handleState |= TEE_HANDLE_FLAG_EXTRACTING; 980*24ea7613SJens Wiklander operation->operationState = TEE_OPERATION_STATE_EXTRACTING; 981*24ea7613SJens Wiklander } 982*24ea7613SJens Wiklander 983*24ea7613SJens Wiklander len = MIN(operation->block_size - operation->buffer_offs, *hashLen); 984*24ea7613SJens Wiklander memcpy(hash, operation->buffer + operation->buffer_offs, len); 985*24ea7613SJens Wiklander *hashLen = len; 986*24ea7613SJens Wiklander operation->buffer_offs += len; 987*24ea7613SJens Wiklander 988*24ea7613SJens Wiklander return TEE_SUCCESS; 989*24ea7613SJens Wiklander } 990*24ea7613SJens Wiklander 991b0104773SPascal Brand /* Cryptographic Operations API - Symmetric Cipher Functions */ 992b0104773SPascal Brand 9938f07fe6fSJerome Forissier void TEE_CipherInit(TEE_OperationHandle operation, const void *IV, 994185bf58cSJens Wiklander size_t IVLen) 995b0104773SPascal Brand { 996b0104773SPascal Brand TEE_Result res; 997b0104773SPascal Brand 998b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 999b0104773SPascal Brand TEE_Panic(0); 1000642a1607SCedric Chaumont 1001b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_CIPHER) 1002b0104773SPascal Brand TEE_Panic(0); 1003642a1607SCedric Chaumont 1004642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) || 1005642a1607SCedric Chaumont !(operation->key1)) 1006642a1607SCedric Chaumont TEE_Panic(0); 1007642a1607SCedric Chaumont 1008642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 1009642a1607SCedric Chaumont TEE_ResetOperation(operation); 1010642a1607SCedric Chaumont 1011ad7aa2a5SSadiq Hussain if (IV && IVLen) { 1012ad7aa2a5SSadiq Hussain if (operation->info.algorithm == TEE_ALG_AES_ECB_NOPAD || 1013ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_DES_ECB_NOPAD || 1014ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_DES3_ECB_NOPAD || 1015ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_SM4_ECB_NOPAD) 1016ad7aa2a5SSadiq Hussain TEE_Panic(0); 1017ad7aa2a5SSadiq Hussain } 1018ad7aa2a5SSadiq Hussain 1019642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1020642a1607SCedric Chaumont 10212c028fdeSJerome Forissier res = _utee_cipher_init(operation->state, IV, IVLen); 1022b0104773SPascal Brand if (res != TEE_SUCCESS) 1023b0104773SPascal Brand TEE_Panic(res); 1024642a1607SCedric Chaumont 1025b0104773SPascal Brand operation->buffer_offs = 0; 1026b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 1027b0104773SPascal Brand } 1028b0104773SPascal Brand 1029185bf58cSJens Wiklander void __GP11_TEE_CipherInit(TEE_OperationHandle operation, const void *IV, 1030185bf58cSJens Wiklander uint32_t IVLen) 1031185bf58cSJens Wiklander { 1032185bf58cSJens Wiklander return TEE_CipherInit(operation, IV, IVLen); 1033185bf58cSJens Wiklander } 1034185bf58cSJens Wiklander 1035b0104773SPascal Brand static TEE_Result tee_buffer_update( 1036b0104773SPascal Brand TEE_OperationHandle op, 1037e86f1266SJens Wiklander TEE_Result(*update_func)(unsigned long state, const void *src, 1038e86f1266SJens Wiklander size_t slen, void *dst, uint64_t *dlen), 1039b0104773SPascal Brand const void *src_data, size_t src_len, 1040e86f1266SJens Wiklander void *dest_data, uint64_t *dest_len) 1041b0104773SPascal Brand { 1042b0104773SPascal Brand TEE_Result res; 1043b0104773SPascal Brand const uint8_t *src = src_data; 1044b0104773SPascal Brand size_t slen = src_len; 1045b0104773SPascal Brand uint8_t *dst = dest_data; 1046b0104773SPascal Brand size_t dlen = *dest_len; 1047b0104773SPascal Brand size_t acc_dlen = 0; 1048e86f1266SJens Wiklander uint64_t tmp_dlen; 1049b0104773SPascal Brand size_t l; 1050b0104773SPascal Brand size_t buffer_size; 1051d3588802SPascal Brand size_t buffer_left; 1052b0104773SPascal Brand 1053090268f5SJens Wiklander if (!src) { 1054090268f5SJens Wiklander if (slen) 1055090268f5SJens Wiklander TEE_Panic(0); 1056090268f5SJens Wiklander goto out; 1057090268f5SJens Wiklander } 1058090268f5SJens Wiklander 1059d3588802SPascal Brand if (op->buffer_two_blocks) { 1060b0104773SPascal Brand buffer_size = op->block_size * 2; 1061d3588802SPascal Brand buffer_left = 1; 1062d3588802SPascal Brand } else { 1063b0104773SPascal Brand buffer_size = op->block_size; 1064d3588802SPascal Brand buffer_left = 0; 1065d3588802SPascal Brand } 1066b0104773SPascal Brand 1067b0104773SPascal Brand if (op->buffer_offs > 0) { 1068b0104773SPascal Brand /* Fill up complete block */ 1069b0104773SPascal Brand if (op->buffer_offs < op->block_size) 1070b0104773SPascal Brand l = MIN(slen, op->block_size - op->buffer_offs); 1071b0104773SPascal Brand else 1072b0104773SPascal Brand l = MIN(slen, buffer_size - op->buffer_offs); 1073b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, l); 1074b0104773SPascal Brand op->buffer_offs += l; 1075b0104773SPascal Brand src += l; 1076b0104773SPascal Brand slen -= l; 1077b0104773SPascal Brand if ((op->buffer_offs % op->block_size) != 0) 1078b0104773SPascal Brand goto out; /* Nothing left to do */ 1079b0104773SPascal Brand } 1080b0104773SPascal Brand 1081b0104773SPascal Brand /* If we can feed from buffer */ 1082d3588802SPascal Brand if ((op->buffer_offs > 0) && 1083d3588802SPascal Brand ((op->buffer_offs + slen) >= (buffer_size + buffer_left))) { 10842ff3fdbbSPascal Brand l = ROUNDUP(op->buffer_offs + slen - buffer_size, 1085b0104773SPascal Brand op->block_size); 1086b0104773SPascal Brand l = MIN(op->buffer_offs, l); 1087b0104773SPascal Brand tmp_dlen = dlen; 1088b0104773SPascal Brand res = update_func(op->state, op->buffer, l, dst, &tmp_dlen); 1089b0104773SPascal Brand if (res != TEE_SUCCESS) 1090b0104773SPascal Brand TEE_Panic(res); 1091b0104773SPascal Brand dst += tmp_dlen; 1092b0104773SPascal Brand dlen -= tmp_dlen; 1093b0104773SPascal Brand acc_dlen += tmp_dlen; 1094b0104773SPascal Brand op->buffer_offs -= l; 1095b0104773SPascal Brand if (op->buffer_offs > 0) { 1096b0104773SPascal Brand /* 1097b0104773SPascal Brand * Slen is small enough to be contained in rest buffer. 1098b0104773SPascal Brand */ 1099b0104773SPascal Brand memcpy(op->buffer, op->buffer + l, buffer_size - l); 1100b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, slen); 1101b0104773SPascal Brand op->buffer_offs += slen; 1102b0104773SPascal Brand goto out; /* Nothing left to do */ 1103b0104773SPascal Brand } 1104b0104773SPascal Brand } 1105b0104773SPascal Brand 1106d3588802SPascal Brand if (slen >= (buffer_size + buffer_left)) { 1107b0104773SPascal Brand /* Buffer is empty, feed as much as possible from src */ 1108bf7a587fSJerome Forissier if (op->info.algorithm == TEE_ALG_AES_CTS) 1109b1ecda78SJerome Forissier l = ROUNDUP(slen - buffer_size, op->block_size); 1110bf7a587fSJerome Forissier else 1111bf7a587fSJerome Forissier l = ROUNDUP(slen - buffer_size + 1, op->block_size); 1112b0104773SPascal Brand 1113b0104773SPascal Brand tmp_dlen = dlen; 1114b0104773SPascal Brand res = update_func(op->state, src, l, dst, &tmp_dlen); 1115b0104773SPascal Brand if (res != TEE_SUCCESS) 1116b0104773SPascal Brand TEE_Panic(res); 1117b0104773SPascal Brand src += l; 1118b0104773SPascal Brand slen -= l; 1119b0104773SPascal Brand dst += tmp_dlen; 1120b0104773SPascal Brand dlen -= tmp_dlen; 1121b0104773SPascal Brand acc_dlen += tmp_dlen; 1122b0104773SPascal Brand } 1123b0104773SPascal Brand 1124b0104773SPascal Brand /* Slen is small enough to be contained in buffer. */ 1125b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, slen); 1126b0104773SPascal Brand op->buffer_offs += slen; 1127b0104773SPascal Brand 1128b0104773SPascal Brand out: 1129b0104773SPascal Brand *dest_len = acc_dlen; 1130b0104773SPascal Brand return TEE_SUCCESS; 1131b0104773SPascal Brand } 1132b0104773SPascal Brand 11338f07fe6fSJerome Forissier TEE_Result TEE_CipherUpdate(TEE_OperationHandle operation, const void *srcData, 1134185bf58cSJens Wiklander size_t srcLen, void *destData, size_t *destLen) 1135b0104773SPascal Brand { 1136dea1f2b6SCedric Chaumont TEE_Result res; 1137b0104773SPascal Brand size_t req_dlen; 1138e86f1266SJens Wiklander uint64_t dl; 1139b0104773SPascal Brand 11406915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1141dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1142dea1f2b6SCedric Chaumont goto out; 1143dea1f2b6SCedric Chaumont } 11446915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1145dea1f2b6SCedric Chaumont 1146642a1607SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_CIPHER) { 1147dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1148dea1f2b6SCedric Chaumont goto out; 1149dea1f2b6SCedric Chaumont } 1150dea1f2b6SCedric Chaumont 1151642a1607SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1152642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1153642a1607SCedric Chaumont goto out; 1154642a1607SCedric Chaumont } 1155642a1607SCedric Chaumont 1156642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1157dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1158dea1f2b6SCedric Chaumont goto out; 1159dea1f2b6SCedric Chaumont } 1160b0104773SPascal Brand 1161e32c5ddfSJerome Forissier if (!srcData && !srcLen) { 1162090268f5SJens Wiklander *destLen = 0; 1163e32c5ddfSJerome Forissier res = TEE_SUCCESS; 1164e32c5ddfSJerome Forissier goto out; 1165e32c5ddfSJerome Forissier } 1166e32c5ddfSJerome Forissier 1167b0104773SPascal Brand /* Calculate required dlen */ 116857aabac5SBogdan Liulko if (operation->block_size > 1) { 116957aabac5SBogdan Liulko req_dlen = ((operation->buffer_offs + srcLen) / 117057aabac5SBogdan Liulko operation->block_size) * operation->block_size; 117157aabac5SBogdan Liulko } else { 117257aabac5SBogdan Liulko req_dlen = srcLen; 117357aabac5SBogdan Liulko } 1174642a1607SCedric Chaumont if (operation->buffer_two_blocks) { 1175642a1607SCedric Chaumont if (req_dlen > operation->block_size * 2) 1176642a1607SCedric Chaumont req_dlen -= operation->block_size * 2; 1177b0104773SPascal Brand else 1178b0104773SPascal Brand req_dlen = 0; 1179b0104773SPascal Brand } 1180b0104773SPascal Brand /* 1181b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1182b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1183b0104773SPascal Brand * can't restore sync with this API. 1184b0104773SPascal Brand */ 1185b0104773SPascal Brand if (*destLen < req_dlen) { 1186b0104773SPascal Brand *destLen = req_dlen; 1187dea1f2b6SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1188dea1f2b6SCedric Chaumont goto out; 1189b0104773SPascal Brand } 1190b0104773SPascal Brand 1191e86f1266SJens Wiklander dl = *destLen; 119257aabac5SBogdan Liulko if (operation->block_size > 1) { 11932c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_cipher_update, srcData, 119457aabac5SBogdan Liulko srcLen, destData, &dl); 119557aabac5SBogdan Liulko } else { 119657aabac5SBogdan Liulko if (srcLen > 0) { 11972c028fdeSJerome Forissier res = _utee_cipher_update(operation->state, srcData, 119857aabac5SBogdan Liulko srcLen, destData, &dl); 119957aabac5SBogdan Liulko } else { 120057aabac5SBogdan Liulko res = TEE_SUCCESS; 120157aabac5SBogdan Liulko dl = 0; 120257aabac5SBogdan Liulko } 120357aabac5SBogdan Liulko } 1204e86f1266SJens Wiklander *destLen = dl; 1205b0104773SPascal Brand 1206dea1f2b6SCedric Chaumont out: 1207dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS && 1208dea1f2b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1209b36311adSJerome Forissier TEE_Panic(res); 1210dea1f2b6SCedric Chaumont 1211dea1f2b6SCedric Chaumont return res; 1212b0104773SPascal Brand } 1213b0104773SPascal Brand 1214185bf58cSJens Wiklander TEE_Result __GP11_TEE_CipherUpdate(TEE_OperationHandle operation, 12158f07fe6fSJerome Forissier const void *srcData, uint32_t srcLen, 12168f07fe6fSJerome Forissier void *destData, uint32_t *destLen) 1217b0104773SPascal Brand { 12186915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 1219185bf58cSJens Wiklander size_t dl = 0; 1220185bf58cSJens Wiklander 1221185bf58cSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1222185bf58cSJens Wiklander dl = *destLen; 1223185bf58cSJens Wiklander res = TEE_CipherUpdate(operation, srcData, srcLen, destData, &dl); 1224185bf58cSJens Wiklander *destLen = dl; 1225185bf58cSJens Wiklander return res; 1226185bf58cSJens Wiklander } 1227185bf58cSJens Wiklander 1228185bf58cSJens Wiklander TEE_Result TEE_CipherDoFinal(TEE_OperationHandle operation, 1229185bf58cSJens Wiklander const void *srcData, size_t srcLen, 1230185bf58cSJens Wiklander void *destData, size_t *destLen) 1231185bf58cSJens Wiklander { 1232185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 1233b0104773SPascal Brand uint8_t *dst = destData; 1234b0104773SPascal Brand size_t acc_dlen = 0; 12356915bbbbSJens Wiklander uint64_t tmp_dlen = 0; 12366915bbbbSJens Wiklander size_t req_dlen = 0; 1237b0104773SPascal Brand 12386915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1239dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1240dea1f2b6SCedric Chaumont goto out; 1241dea1f2b6SCedric Chaumont } 12426915bbbbSJens Wiklander if (destLen) 12436915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1244dea1f2b6SCedric Chaumont 1245642a1607SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_CIPHER) { 1246dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1247dea1f2b6SCedric Chaumont goto out; 1248dea1f2b6SCedric Chaumont } 1249dea1f2b6SCedric Chaumont 1250642a1607SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1251642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1252642a1607SCedric Chaumont goto out; 1253642a1607SCedric Chaumont } 1254642a1607SCedric Chaumont 1255642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1256dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1257dea1f2b6SCedric Chaumont goto out; 1258dea1f2b6SCedric Chaumont } 1259b0104773SPascal Brand 1260b0104773SPascal Brand /* 1261b0104773SPascal Brand * Check that the final block doesn't require padding for those 1262b0104773SPascal Brand * algorithms that requires client to supply padding. 1263b0104773SPascal Brand */ 1264642a1607SCedric Chaumont if (operation->info.algorithm == TEE_ALG_AES_ECB_NOPAD || 1265642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_AES_CBC_NOPAD || 1266642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES_ECB_NOPAD || 1267642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES_CBC_NOPAD || 1268642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES3_ECB_NOPAD || 1269ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_DES3_CBC_NOPAD || 1270ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_SM4_ECB_NOPAD || 1271ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_SM4_CBC_NOPAD) { 1272642a1607SCedric Chaumont if (((operation->buffer_offs + srcLen) % operation->block_size) 1273642a1607SCedric Chaumont != 0) { 1274dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1275dea1f2b6SCedric Chaumont goto out; 1276dea1f2b6SCedric Chaumont } 1277b0104773SPascal Brand } 1278b0104773SPascal Brand 1279b0104773SPascal Brand /* 1280b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1281b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1282b0104773SPascal Brand * can't restore sync with this API. 1283b0104773SPascal Brand */ 128457aabac5SBogdan Liulko if (operation->block_size > 1) { 1285642a1607SCedric Chaumont req_dlen = operation->buffer_offs + srcLen; 128657aabac5SBogdan Liulko } else { 128757aabac5SBogdan Liulko req_dlen = srcLen; 128857aabac5SBogdan Liulko } 12896915bbbbSJens Wiklander if (destLen) 12906915bbbbSJens Wiklander tmp_dlen = *destLen; 12916915bbbbSJens Wiklander if (tmp_dlen < req_dlen) { 12926915bbbbSJens Wiklander if (destLen) 1293b0104773SPascal Brand *destLen = req_dlen; 1294dea1f2b6SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1295dea1f2b6SCedric Chaumont goto out; 1296b0104773SPascal Brand } 1297b0104773SPascal Brand 129857aabac5SBogdan Liulko if (operation->block_size > 1) { 1299dea9063eSJens Wiklander if (srcLen) { 13002c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_cipher_update, 1301dea9063eSJens Wiklander srcData, srcLen, dst, 1302dea9063eSJens Wiklander &tmp_dlen); 1303dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS) 1304dea1f2b6SCedric Chaumont goto out; 1305dea1f2b6SCedric Chaumont 1306b0104773SPascal Brand dst += tmp_dlen; 1307b0104773SPascal Brand acc_dlen += tmp_dlen; 1308b0104773SPascal Brand 1309b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 1310dea9063eSJens Wiklander } 13112c028fdeSJerome Forissier res = _utee_cipher_final(operation->state, operation->buffer, 13122c028fdeSJerome Forissier operation->buffer_offs, dst, 13132c028fdeSJerome Forissier &tmp_dlen); 131457aabac5SBogdan Liulko } else { 13152c028fdeSJerome Forissier res = _utee_cipher_final(operation->state, srcData, srcLen, dst, 13162c028fdeSJerome Forissier &tmp_dlen); 131757aabac5SBogdan Liulko } 1318b0104773SPascal Brand if (res != TEE_SUCCESS) 1319dea1f2b6SCedric Chaumont goto out; 1320dea1f2b6SCedric Chaumont 1321b0104773SPascal Brand acc_dlen += tmp_dlen; 13226915bbbbSJens Wiklander if (destLen) 1323b0104773SPascal Brand *destLen = acc_dlen; 1324dea1f2b6SCedric Chaumont 1325642a1607SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 1326642a1607SCedric Chaumont 1327642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1328642a1607SCedric Chaumont 1329dea1f2b6SCedric Chaumont out: 1330dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS && 1331dea1f2b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1332b36311adSJerome Forissier TEE_Panic(res); 1333dea1f2b6SCedric Chaumont 1334dea1f2b6SCedric Chaumont return res; 1335b0104773SPascal Brand } 1336b0104773SPascal Brand 1337185bf58cSJens Wiklander TEE_Result __GP11_TEE_CipherDoFinal(TEE_OperationHandle operation, 1338185bf58cSJens Wiklander const void *srcData, uint32_t srcLen, 1339185bf58cSJens Wiklander void *destData, uint32_t *destLen) 1340185bf58cSJens Wiklander { 1341185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 1342185bf58cSJens Wiklander size_t dl = 0; 1343185bf58cSJens Wiklander 1344185bf58cSJens Wiklander if (destLen) { 1345185bf58cSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1346185bf58cSJens Wiklander dl = *destLen; 1347185bf58cSJens Wiklander } 1348185bf58cSJens Wiklander res = TEE_CipherDoFinal(operation, srcData, srcLen, destData, &dl); 1349185bf58cSJens Wiklander if (destLen) 1350185bf58cSJens Wiklander *destLen = dl; 1351185bf58cSJens Wiklander return res; 1352185bf58cSJens Wiklander } 1353185bf58cSJens Wiklander 1354b0104773SPascal Brand /* Cryptographic Operations API - MAC Functions */ 1355b0104773SPascal Brand 1356185bf58cSJens Wiklander void TEE_MACInit(TEE_OperationHandle operation, const void *IV, size_t IVLen) 1357b0104773SPascal Brand { 1358b0104773SPascal Brand if (operation == TEE_HANDLE_NULL) 1359b0104773SPascal Brand TEE_Panic(0); 1360642a1607SCedric Chaumont 1361b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_MAC) 1362b0104773SPascal Brand TEE_Panic(0); 1363642a1607SCedric Chaumont 1364642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) || 1365642a1607SCedric Chaumont !(operation->key1)) 1366642a1607SCedric Chaumont TEE_Panic(0); 1367642a1607SCedric Chaumont 1368642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 1369642a1607SCedric Chaumont TEE_ResetOperation(operation); 1370642a1607SCedric Chaumont 1371642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1372642a1607SCedric Chaumont 13736d15db08SJerome Forissier init_hash_operation(operation, IV, IVLen); 1374b0104773SPascal Brand } 1375b0104773SPascal Brand 1376185bf58cSJens Wiklander void __GP11_TEE_MACInit(TEE_OperationHandle operation, const void *IV, 1377185bf58cSJens Wiklander uint32_t IVLen) 1378185bf58cSJens Wiklander { 1379185bf58cSJens Wiklander return TEE_MACInit(operation, IV, IVLen); 1380185bf58cSJens Wiklander } 1381185bf58cSJens Wiklander 13828f07fe6fSJerome Forissier void TEE_MACUpdate(TEE_OperationHandle operation, const void *chunk, 1383185bf58cSJens Wiklander size_t chunkSize) 1384b0104773SPascal Brand { 1385b0104773SPascal Brand TEE_Result res; 1386b0104773SPascal Brand 138728e0efc6SCedric Chaumont if (operation == TEE_HANDLE_NULL || (chunk == NULL && chunkSize != 0)) 1388b0104773SPascal Brand TEE_Panic(0); 1389642a1607SCedric Chaumont 139028e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) 1391b0104773SPascal Brand TEE_Panic(0); 1392642a1607SCedric Chaumont 139328e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 1394b0104773SPascal Brand TEE_Panic(0); 1395b0104773SPascal Brand 1396642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) 1397642a1607SCedric Chaumont TEE_Panic(0); 1398642a1607SCedric Chaumont 13992c028fdeSJerome Forissier res = _utee_hash_update(operation->state, chunk, chunkSize); 1400b0104773SPascal Brand if (res != TEE_SUCCESS) 1401b0104773SPascal Brand TEE_Panic(res); 1402b0104773SPascal Brand } 1403b0104773SPascal Brand 1404185bf58cSJens Wiklander void __GP11_TEE_MACUpdate(TEE_OperationHandle operation, const void *chunk, 1405185bf58cSJens Wiklander uint32_t chunkSize) 1406185bf58cSJens Wiklander { 1407185bf58cSJens Wiklander return TEE_MACUpdate(operation, chunk, chunkSize); 1408185bf58cSJens Wiklander } 1409185bf58cSJens Wiklander 141028e0efc6SCedric Chaumont TEE_Result TEE_MACComputeFinal(TEE_OperationHandle operation, 1411185bf58cSJens Wiklander const void *message, size_t messageLen, 1412185bf58cSJens Wiklander void *mac, size_t *macLen) 1413b0104773SPascal Brand { 1414b0104773SPascal Brand TEE_Result res; 1415e86f1266SJens Wiklander uint64_t ml; 1416b0104773SPascal Brand 14176915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!message && messageLen)) { 141828e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 141928e0efc6SCedric Chaumont goto out; 142028e0efc6SCedric Chaumont } 14216915bbbbSJens Wiklander __utee_check_inout_annotation(macLen, sizeof(*macLen)); 1422b0104773SPascal Brand 142328e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) { 142428e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 142528e0efc6SCedric Chaumont goto out; 142628e0efc6SCedric Chaumont } 142728e0efc6SCedric Chaumont 142828e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 142928e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 143028e0efc6SCedric Chaumont goto out; 143128e0efc6SCedric Chaumont } 143228e0efc6SCedric Chaumont 1433642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1434642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1435642a1607SCedric Chaumont goto out; 1436642a1607SCedric Chaumont } 1437642a1607SCedric Chaumont 1438e86f1266SJens Wiklander ml = *macLen; 14392c028fdeSJerome Forissier res = _utee_hash_final(operation->state, message, messageLen, mac, &ml); 1440e86f1266SJens Wiklander *macLen = ml; 144128e0efc6SCedric Chaumont if (res != TEE_SUCCESS) 144228e0efc6SCedric Chaumont goto out; 144328e0efc6SCedric Chaumont 144428e0efc6SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 144528e0efc6SCedric Chaumont 1446642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1447642a1607SCedric Chaumont 144828e0efc6SCedric Chaumont out: 144928e0efc6SCedric Chaumont if (res != TEE_SUCCESS && 145028e0efc6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 145128e0efc6SCedric Chaumont TEE_Panic(res); 145228e0efc6SCedric Chaumont 1453b0104773SPascal Brand return res; 1454b0104773SPascal Brand } 1455b0104773SPascal Brand 1456185bf58cSJens Wiklander TEE_Result __GP11_TEE_MACComputeFinal(TEE_OperationHandle operation, 14578f07fe6fSJerome Forissier const void *message, uint32_t messageLen, 1458185bf58cSJens Wiklander void *mac, uint32_t *macLen) 1459185bf58cSJens Wiklander { 1460185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS; 1461185bf58cSJens Wiklander size_t ml = 0; 1462185bf58cSJens Wiklander 1463185bf58cSJens Wiklander __utee_check_inout_annotation(macLen, sizeof(*macLen)); 1464185bf58cSJens Wiklander ml = *macLen; 1465185bf58cSJens Wiklander res = TEE_MACComputeFinal(operation, message, messageLen, mac, &ml); 1466185bf58cSJens Wiklander *macLen = ml; 1467185bf58cSJens Wiklander return res; 1468185bf58cSJens Wiklander } 1469185bf58cSJens Wiklander 1470185bf58cSJens Wiklander TEE_Result TEE_MACCompareFinal(TEE_OperationHandle operation, 1471185bf58cSJens Wiklander const void *message, size_t messageLen, 1472185bf58cSJens Wiklander const void *mac, size_t macLen) 1473b0104773SPascal Brand { 1474b0104773SPascal Brand TEE_Result res; 1475ee4ba3d1SVictor Chong uint8_t computed_mac[TEE_MAX_HASH_SIZE] = { 0 }; 1476185bf58cSJens Wiklander size_t computed_mac_size = TEE_MAX_HASH_SIZE; 1477b0104773SPascal Brand 147828e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) { 147928e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 148028e0efc6SCedric Chaumont goto out; 148128e0efc6SCedric Chaumont } 148228e0efc6SCedric Chaumont 148328e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 148428e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 148528e0efc6SCedric Chaumont goto out; 148628e0efc6SCedric Chaumont } 148728e0efc6SCedric Chaumont 1488642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) { 1489642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1490642a1607SCedric Chaumont goto out; 1491642a1607SCedric Chaumont } 1492642a1607SCedric Chaumont 1493b0104773SPascal Brand res = TEE_MACComputeFinal(operation, message, messageLen, computed_mac, 1494b0104773SPascal Brand &computed_mac_size); 1495b0104773SPascal Brand if (res != TEE_SUCCESS) 149628e0efc6SCedric Chaumont goto out; 149728e0efc6SCedric Chaumont 149828e0efc6SCedric Chaumont if (computed_mac_size != macLen) { 149928e0efc6SCedric Chaumont res = TEE_ERROR_MAC_INVALID; 150028e0efc6SCedric Chaumont goto out; 150128e0efc6SCedric Chaumont } 150228e0efc6SCedric Chaumont 150348e10604SJerome Forissier if (consttime_memcmp(mac, computed_mac, computed_mac_size) != 0) { 150428e0efc6SCedric Chaumont res = TEE_ERROR_MAC_INVALID; 150528e0efc6SCedric Chaumont goto out; 150628e0efc6SCedric Chaumont } 150728e0efc6SCedric Chaumont 1508642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1509642a1607SCedric Chaumont 151028e0efc6SCedric Chaumont out: 151128e0efc6SCedric Chaumont if (res != TEE_SUCCESS && 151228e0efc6SCedric Chaumont res != TEE_ERROR_MAC_INVALID) 151328e0efc6SCedric Chaumont TEE_Panic(res); 151428e0efc6SCedric Chaumont 1515b0104773SPascal Brand return res; 1516b0104773SPascal Brand } 1517b0104773SPascal Brand 1518185bf58cSJens Wiklander TEE_Result __GP11_TEE_MACCompareFinal(TEE_OperationHandle operation, 1519185bf58cSJens Wiklander const void *message, uint32_t messageLen, 1520185bf58cSJens Wiklander const void *mac, uint32_t macLen) 1521185bf58cSJens Wiklander { 1522185bf58cSJens Wiklander return TEE_MACCompareFinal(operation, message, messageLen, mac, macLen); 1523185bf58cSJens Wiklander } 1524185bf58cSJens Wiklander 1525b0104773SPascal Brand /* Cryptographic Operations API - Authenticated Encryption Functions */ 1526b0104773SPascal Brand 15278f07fe6fSJerome Forissier TEE_Result TEE_AEInit(TEE_OperationHandle operation, const void *nonce, 1528d9096215SJens Wiklander size_t nonceLen, uint32_t tagLen, size_t AADLen, 1529d9096215SJens Wiklander size_t payloadLen) 1530b0104773SPascal Brand { 1531b0104773SPascal Brand TEE_Result res; 1532b0104773SPascal Brand 1533b5816c88SCedric Chaumont if (operation == TEE_HANDLE_NULL || nonce == NULL) { 1534b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1535b5816c88SCedric Chaumont goto out; 1536b5816c88SCedric Chaumont } 1537b5816c88SCedric Chaumont 1538b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1539b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1540b5816c88SCedric Chaumont goto out; 1541b5816c88SCedric Chaumont } 1542b0104773SPascal Brand 1543642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) { 1544642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1545642a1607SCedric Chaumont goto out; 1546642a1607SCedric Chaumont } 1547642a1607SCedric Chaumont 1548b0104773SPascal Brand /* 1549b0104773SPascal Brand * AES-CCM tag len is specified by AES-CCM spec and handled in TEE Core 1550b0104773SPascal Brand * in the implementation. But AES-GCM spec doesn't specify the tag len 1551b0104773SPascal Brand * according to the same principle so we have to check here instead to 1552b0104773SPascal Brand * be GP compliant. 1553b0104773SPascal Brand */ 1554b5816c88SCedric Chaumont if (operation->info.algorithm == TEE_ALG_AES_GCM) { 1555b0104773SPascal Brand /* 1556b0104773SPascal Brand * From GP spec: For AES-GCM, can be 128, 120, 112, 104, or 96 1557b0104773SPascal Brand */ 1558b5816c88SCedric Chaumont if (tagLen < 96 || tagLen > 128 || (tagLen % 8 != 0)) { 1559b5816c88SCedric Chaumont res = TEE_ERROR_NOT_SUPPORTED; 1560b5816c88SCedric Chaumont goto out; 1561b5816c88SCedric Chaumont } 1562b0104773SPascal Brand } 1563b0104773SPascal Brand 15642c028fdeSJerome Forissier res = _utee_authenc_init(operation->state, nonce, nonceLen, tagLen / 8, 15652c028fdeSJerome Forissier AADLen, payloadLen); 1566b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1567b5816c88SCedric Chaumont goto out; 1568b5816c88SCedric Chaumont 15697acaf5adSAlbert Schwarzkopf operation->info.digestLength = tagLen / 8; 1570f2674567SSumit Garg operation->buffer_offs = 0; 1571b5816c88SCedric Chaumont operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED; 1572b5816c88SCedric Chaumont 1573b5816c88SCedric Chaumont out: 1574b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1575b5816c88SCedric Chaumont res != TEE_ERROR_NOT_SUPPORTED) 1576b0104773SPascal Brand TEE_Panic(res); 1577b5816c88SCedric Chaumont 1578b0104773SPascal Brand return res; 1579b0104773SPascal Brand } 1580b0104773SPascal Brand 1581d9096215SJens Wiklander TEE_Result __GP11_TEE_AEInit(TEE_OperationHandle operation, const void *nonce, 1582d9096215SJens Wiklander uint32_t nonceLen, uint32_t tagLen, 1583d9096215SJens Wiklander uint32_t AADLen, uint32_t payloadLen) 1584d9096215SJens Wiklander { 1585d9096215SJens Wiklander return TEE_AEInit(operation, nonce, nonceLen, tagLen, AADLen, 1586d9096215SJens Wiklander payloadLen); 1587d9096215SJens Wiklander } 1588d9096215SJens Wiklander 15898f07fe6fSJerome Forissier void TEE_AEUpdateAAD(TEE_OperationHandle operation, const void *AADdata, 1590d9096215SJens Wiklander size_t AADdataLen) 1591d9096215SJens Wiklander { 1592d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1593d9096215SJens Wiklander 1594d9096215SJens Wiklander if (operation == TEE_HANDLE_NULL || (!AADdata && AADdataLen)) 1595d9096215SJens Wiklander TEE_Panic(0); 1596d9096215SJens Wiklander 1597d9096215SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_AE) 1598d9096215SJens Wiklander TEE_Panic(0); 1599d9096215SJens Wiklander 1600d9096215SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_INITIAL) 1601d9096215SJens Wiklander TEE_Panic(0); 1602d9096215SJens Wiklander 1603d9096215SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 1604d9096215SJens Wiklander TEE_Panic(0); 1605d9096215SJens Wiklander 1606d9096215SJens Wiklander res = _utee_authenc_update_aad(operation->state, AADdata, AADdataLen); 1607d9096215SJens Wiklander if (res != TEE_SUCCESS) 1608d9096215SJens Wiklander TEE_Panic(res); 1609d9096215SJens Wiklander } 1610d9096215SJens Wiklander 1611d9096215SJens Wiklander void __GP11_TEE_AEUpdateAAD(TEE_OperationHandle operation, const void *AADdata, 161279a3c601SCedric Chaumont uint32_t AADdataLen) 1613b0104773SPascal Brand { 1614d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1615b0104773SPascal Brand 1616b5816c88SCedric Chaumont if (operation == TEE_HANDLE_NULL || 1617b5816c88SCedric Chaumont (AADdata == NULL && AADdataLen != 0)) 1618b0104773SPascal Brand TEE_Panic(0); 1619642a1607SCedric Chaumont 1620b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) 1621b0104773SPascal Brand TEE_Panic(0); 1622642a1607SCedric Chaumont 1623b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) 1624b0104773SPascal Brand TEE_Panic(0); 1625b0104773SPascal Brand 16262c028fdeSJerome Forissier res = _utee_authenc_update_aad(operation->state, AADdata, AADdataLen); 1627642a1607SCedric Chaumont 1628642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1629642a1607SCedric Chaumont 1630b0104773SPascal Brand if (res != TEE_SUCCESS) 1631b0104773SPascal Brand TEE_Panic(res); 1632b0104773SPascal Brand } 1633b0104773SPascal Brand 1634d9096215SJens Wiklander static TEE_Result ae_update_helper(TEE_OperationHandle operation, 1635d9096215SJens Wiklander const void *src, size_t slen, void *dst, 1636d9096215SJens Wiklander size_t *dlen) 1637b0104773SPascal Brand { 16386915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 16396915bbbbSJens Wiklander size_t req_dlen = 0; 16406915bbbbSJens Wiklander uint64_t dl = 0; 1641b0104773SPascal Brand 1642d9096215SJens Wiklander if (!src && !slen) { 1643d9096215SJens Wiklander *dlen = 0; 1644d9096215SJens Wiklander return TEE_SUCCESS; 1645d9096215SJens Wiklander } 1646d9096215SJens Wiklander 1647d9096215SJens Wiklander /* 1648d9096215SJens Wiklander * Check that required destLen is big enough before starting to feed 1649d9096215SJens Wiklander * data to the algorithm. Errors during feeding of data are fatal as we 1650d9096215SJens Wiklander * can't restore sync with this API. 1651d9096215SJens Wiklander */ 1652d9096215SJens Wiklander if (operation->block_size > 1) { 1653d9096215SJens Wiklander req_dlen = ROUNDDOWN(operation->buffer_offs + slen, 1654d9096215SJens Wiklander operation->block_size); 1655d9096215SJens Wiklander } else { 1656d9096215SJens Wiklander req_dlen = slen; 1657d9096215SJens Wiklander } 1658d9096215SJens Wiklander 1659d9096215SJens Wiklander dl = *dlen; 1660d9096215SJens Wiklander if (dl < req_dlen) { 1661d9096215SJens Wiklander *dlen = req_dlen; 1662d9096215SJens Wiklander return TEE_ERROR_SHORT_BUFFER; 1663d9096215SJens Wiklander } 1664d9096215SJens Wiklander 1665d9096215SJens Wiklander if (operation->block_size > 1) { 1666d9096215SJens Wiklander res = tee_buffer_update(operation, _utee_authenc_update_payload, 1667d9096215SJens Wiklander src, slen, dst, &dl); 1668d9096215SJens Wiklander } else { 1669d9096215SJens Wiklander if (slen > 0) { 1670d9096215SJens Wiklander res = _utee_authenc_update_payload(operation->state, 1671d9096215SJens Wiklander src, slen, dst, &dl); 1672d9096215SJens Wiklander } else { 1673d9096215SJens Wiklander dl = 0; 1674d9096215SJens Wiklander res = TEE_SUCCESS; 1675d9096215SJens Wiklander } 1676d9096215SJens Wiklander } 1677d9096215SJens Wiklander 1678d9096215SJens Wiklander if (!res) 1679d9096215SJens Wiklander *dlen = dl; 1680d9096215SJens Wiklander 1681d9096215SJens Wiklander return res; 1682d9096215SJens Wiklander } 1683d9096215SJens Wiklander 1684d9096215SJens Wiklander TEE_Result TEE_AEUpdate(TEE_OperationHandle operation, const void *srcData, 1685d9096215SJens Wiklander size_t srcLen, void *destData, size_t *destLen) 1686d9096215SJens Wiklander { 1687d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1688d9096215SJens Wiklander 16896915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1690b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1691b5816c88SCedric Chaumont goto out; 1692b5816c88SCedric Chaumont } 1693d9096215SJens Wiklander __utee_check_outbuf_annotation(destData, destLen); 1694b5816c88SCedric Chaumont 1695b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1696b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1697b5816c88SCedric Chaumont goto out; 1698b5816c88SCedric Chaumont } 1699b5816c88SCedric Chaumont 1700b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1701b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1702b5816c88SCedric Chaumont goto out; 1703b5816c88SCedric Chaumont } 1704b0104773SPascal Brand 1705d9096215SJens Wiklander res = ae_update_helper(operation, srcData, srcLen, destData, destLen); 1706d9096215SJens Wiklander if (res != TEE_ERROR_SHORT_BUFFER && srcLen) 1707d9096215SJens Wiklander operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1708d9096215SJens Wiklander 1709d9096215SJens Wiklander out: 1710d9096215SJens Wiklander if (res != TEE_SUCCESS && 1711d9096215SJens Wiklander res != TEE_ERROR_SHORT_BUFFER) 1712d9096215SJens Wiklander TEE_Panic(res); 1713d9096215SJens Wiklander 1714d9096215SJens Wiklander return res; 1715d9096215SJens Wiklander } 1716d9096215SJens Wiklander 1717d9096215SJens Wiklander TEE_Result __GP11_TEE_AEUpdate(TEE_OperationHandle operation, 1718d9096215SJens Wiklander const void *srcData, uint32_t srcLen, 1719d9096215SJens Wiklander void *destData, uint32_t *destLen) 1720d9096215SJens Wiklander { 1721d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1722d9096215SJens Wiklander size_t dl = 0; 1723d9096215SJens Wiklander 1724d9096215SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1725d9096215SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1726d9096215SJens Wiklander goto out; 1727d9096215SJens Wiklander } 1728d9096215SJens Wiklander __utee_check_gp11_outbuf_annotation(destData, destLen); 1729d9096215SJens Wiklander 1730d9096215SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_AE) { 1731d9096215SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1732827308b8SJerome Forissier goto out; 1733827308b8SJerome Forissier } 1734827308b8SJerome Forissier 1735d9096215SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1736d9096215SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS; 1737d9096215SJens Wiklander goto out; 1738afc0c182SBogdan Liulko } 1739afc0c182SBogdan Liulko 17406915bbbbSJens Wiklander dl = *destLen; 1741d9096215SJens Wiklander res = ae_update_helper(operation, srcData, srcLen, destData, &dl); 1742d9096215SJens Wiklander *destLen = dl; 1743b0104773SPascal Brand 1744afc0c182SBogdan Liulko if (res != TEE_SUCCESS) 1745afc0c182SBogdan Liulko goto out; 1746afc0c182SBogdan Liulko 1747642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE; 1748642a1607SCedric Chaumont 1749b5816c88SCedric Chaumont out: 1750b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1751b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1752b5816c88SCedric Chaumont TEE_Panic(res); 1753b5816c88SCedric Chaumont 1754b5816c88SCedric Chaumont return res; 1755b0104773SPascal Brand } 1756b0104773SPascal Brand 1757b5816c88SCedric Chaumont TEE_Result TEE_AEEncryptFinal(TEE_OperationHandle operation, 1758d9096215SJens Wiklander const void *srcData, size_t srcLen, 1759d9096215SJens Wiklander void *destData, size_t *destLen, void *tag, 1760d9096215SJens Wiklander size_t *tagLen) 1761b0104773SPascal Brand { 1762d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1763b0104773SPascal Brand uint8_t *dst = destData; 1764b0104773SPascal Brand size_t acc_dlen = 0; 1765d9096215SJens Wiklander uint64_t tmp_dlen = 0; 1766d9096215SJens Wiklander size_t req_dlen = 0; 1767d9096215SJens Wiklander uint64_t tl = 0; 1768b0104773SPascal Brand 17696915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1770b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1771b5816c88SCedric Chaumont goto out; 1772b5816c88SCedric Chaumont } 17736915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 17746915bbbbSJens Wiklander __utee_check_inout_annotation(tagLen, sizeof(*tagLen)); 1775b5816c88SCedric Chaumont 1776b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1777b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1778b5816c88SCedric Chaumont goto out; 1779b5816c88SCedric Chaumont } 1780b5816c88SCedric Chaumont 1781b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1782b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1783b5816c88SCedric Chaumont goto out; 1784b5816c88SCedric Chaumont } 1785b0104773SPascal Brand 1786b0104773SPascal Brand /* 1787b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1788b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1789b0104773SPascal Brand * can't restore sync with this API. 17902733280aSEtienne Carriere * 17912733280aSEtienne Carriere * Need to check this before update_payload since sync would be lost if 17922733280aSEtienne Carriere * we return short buffer after that. 1793b0104773SPascal Brand */ 17942733280aSEtienne Carriere res = TEE_ERROR_GENERIC; 17952733280aSEtienne Carriere 1796b5816c88SCedric Chaumont req_dlen = operation->buffer_offs + srcLen; 1797b0104773SPascal Brand if (*destLen < req_dlen) { 1798b0104773SPascal Brand *destLen = req_dlen; 1799b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1800b0104773SPascal Brand } 1801b0104773SPascal Brand 18027acaf5adSAlbert Schwarzkopf if (*tagLen < operation->info.digestLength) { 18037acaf5adSAlbert Schwarzkopf *tagLen = operation->info.digestLength; 1804b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1805b0104773SPascal Brand } 1806b0104773SPascal Brand 18072733280aSEtienne Carriere if (res == TEE_ERROR_SHORT_BUFFER) 18082733280aSEtienne Carriere goto out; 18092733280aSEtienne Carriere 1810afc0c182SBogdan Liulko tl = *tagLen; 1811b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 1812afc0c182SBogdan Liulko if (operation->block_size > 1) { 18132c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_authenc_update_payload, 1814afc0c182SBogdan Liulko srcData, srcLen, dst, &tmp_dlen); 1815b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1816b5816c88SCedric Chaumont goto out; 1817b5816c88SCedric Chaumont 1818b0104773SPascal Brand dst += tmp_dlen; 1819b0104773SPascal Brand acc_dlen += tmp_dlen; 1820b0104773SPascal Brand 1821b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 18222c028fdeSJerome Forissier res = _utee_authenc_enc_final(operation->state, 1823afc0c182SBogdan Liulko operation->buffer, 1824afc0c182SBogdan Liulko operation->buffer_offs, dst, 1825afc0c182SBogdan Liulko &tmp_dlen, tag, &tl); 1826afc0c182SBogdan Liulko } else { 18272c028fdeSJerome Forissier res = _utee_authenc_enc_final(operation->state, srcData, 1828afc0c182SBogdan Liulko srcLen, dst, &tmp_dlen, 1829e86f1266SJens Wiklander tag, &tl); 1830afc0c182SBogdan Liulko } 1831e86f1266SJens Wiklander *tagLen = tl; 1832b0104773SPascal Brand if (res != TEE_SUCCESS) 1833b5816c88SCedric Chaumont goto out; 1834b0104773SPascal Brand 1835b5816c88SCedric Chaumont acc_dlen += tmp_dlen; 1836b0104773SPascal Brand *destLen = acc_dlen; 1837642a1607SCedric Chaumont 1838b5816c88SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 1839b5816c88SCedric Chaumont 1840642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1841642a1607SCedric Chaumont 1842b5816c88SCedric Chaumont out: 1843b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1844b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER) 1845b5816c88SCedric Chaumont TEE_Panic(res); 1846b0104773SPascal Brand 1847b0104773SPascal Brand return res; 1848b0104773SPascal Brand } 1849b0104773SPascal Brand 1850d9096215SJens Wiklander TEE_Result __GP11_TEE_AEEncryptFinal(TEE_OperationHandle operation, 18518f07fe6fSJerome Forissier const void *srcData, uint32_t srcLen, 1852d9096215SJens Wiklander void *destData, uint32_t *destLen, 1853d9096215SJens Wiklander void *tag, uint32_t *tagLen) 1854b0104773SPascal Brand { 1855d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1856d9096215SJens Wiklander size_t dl = 0; 1857d9096215SJens Wiklander size_t tl = 0; 1858d9096215SJens Wiklander 1859d9096215SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1860d9096215SJens Wiklander __utee_check_inout_annotation(tagLen, sizeof(*tagLen)); 1861d9096215SJens Wiklander dl = *destLen; 1862d9096215SJens Wiklander tl = *tagLen; 1863d9096215SJens Wiklander res = TEE_AEEncryptFinal(operation, srcData, srcLen, destData, &dl, 1864d9096215SJens Wiklander tag, &tl); 1865d9096215SJens Wiklander *destLen = dl; 1866d9096215SJens Wiklander *tagLen = tl; 1867d9096215SJens Wiklander return res; 1868d9096215SJens Wiklander } 1869d9096215SJens Wiklander 1870d9096215SJens Wiklander TEE_Result TEE_AEDecryptFinal(TEE_OperationHandle operation, 1871d9096215SJens Wiklander const void *srcData, size_t srcLen, 1872d9096215SJens Wiklander void *destData, size_t *destLen, void *tag, 1873d9096215SJens Wiklander size_t tagLen) 1874d9096215SJens Wiklander { 1875d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1876b0104773SPascal Brand uint8_t *dst = destData; 1877b0104773SPascal Brand size_t acc_dlen = 0; 1878d9096215SJens Wiklander uint64_t tmp_dlen = 0; 1879d9096215SJens Wiklander size_t req_dlen = 0; 1880b0104773SPascal Brand 18816915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) { 1882b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1883b5816c88SCedric Chaumont goto out; 1884b5816c88SCedric Chaumont } 18856915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1886b5816c88SCedric Chaumont 1887b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) { 1888b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1889b5816c88SCedric Chaumont goto out; 1890b5816c88SCedric Chaumont } 1891b5816c88SCedric Chaumont 1892b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) { 1893b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS; 1894b5816c88SCedric Chaumont goto out; 1895b5816c88SCedric Chaumont } 1896b0104773SPascal Brand 1897b0104773SPascal Brand /* 1898b0104773SPascal Brand * Check that required destLen is big enough before starting to feed 1899b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we 1900b0104773SPascal Brand * can't restore sync with this API. 1901b0104773SPascal Brand */ 1902b5816c88SCedric Chaumont req_dlen = operation->buffer_offs + srcLen; 1903b0104773SPascal Brand if (*destLen < req_dlen) { 1904b0104773SPascal Brand *destLen = req_dlen; 1905b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER; 1906b5816c88SCedric Chaumont goto out; 1907b0104773SPascal Brand } 1908b0104773SPascal Brand 1909b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 1910afc0c182SBogdan Liulko if (operation->block_size > 1) { 19112c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_authenc_update_payload, 1912afc0c182SBogdan Liulko srcData, srcLen, dst, &tmp_dlen); 1913b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1914b5816c88SCedric Chaumont goto out; 1915b5816c88SCedric Chaumont 1916b0104773SPascal Brand dst += tmp_dlen; 1917b0104773SPascal Brand acc_dlen += tmp_dlen; 1918b0104773SPascal Brand 1919b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen; 19202c028fdeSJerome Forissier res = _utee_authenc_dec_final(operation->state, 1921afc0c182SBogdan Liulko operation->buffer, 1922afc0c182SBogdan Liulko operation->buffer_offs, dst, 1923afc0c182SBogdan Liulko &tmp_dlen, tag, tagLen); 1924afc0c182SBogdan Liulko } else { 19252c028fdeSJerome Forissier res = _utee_authenc_dec_final(operation->state, srcData, 1926afc0c182SBogdan Liulko srcLen, dst, &tmp_dlen, 1927b5816c88SCedric Chaumont tag, tagLen); 1928afc0c182SBogdan Liulko } 1929b5816c88SCedric Chaumont if (res != TEE_SUCCESS) 1930b5816c88SCedric Chaumont goto out; 1931b5816c88SCedric Chaumont 1932b0104773SPascal Brand /* Supplied tagLen should match what we initiated with */ 19337acaf5adSAlbert Schwarzkopf if (tagLen != operation->info.digestLength) 1934b0104773SPascal Brand res = TEE_ERROR_MAC_INVALID; 1935b0104773SPascal Brand 1936b0104773SPascal Brand acc_dlen += tmp_dlen; 1937b0104773SPascal Brand *destLen = acc_dlen; 1938642a1607SCedric Chaumont 1939b5816c88SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED; 1940b5816c88SCedric Chaumont 1941642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL; 1942642a1607SCedric Chaumont 1943b5816c88SCedric Chaumont out: 1944b5816c88SCedric Chaumont if (res != TEE_SUCCESS && 1945b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER && 1946b5816c88SCedric Chaumont res != TEE_ERROR_MAC_INVALID) 1947b5816c88SCedric Chaumont TEE_Panic(res); 1948b0104773SPascal Brand 1949b0104773SPascal Brand return res; 1950b0104773SPascal Brand } 1951b0104773SPascal Brand 1952d9096215SJens Wiklander TEE_Result __GP11_TEE_AEDecryptFinal(TEE_OperationHandle operation, 1953d9096215SJens Wiklander const void *srcData, uint32_t srcLen, 1954d9096215SJens Wiklander void *destData, uint32_t *destLen, 1955d9096215SJens Wiklander void *tag, uint32_t tagLen) 1956d9096215SJens Wiklander { 1957d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS; 1958d9096215SJens Wiklander size_t dl = 0; 1959d9096215SJens Wiklander 1960d9096215SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 1961d9096215SJens Wiklander dl = *destLen; 1962d9096215SJens Wiklander res = TEE_AEDecryptFinal(operation, srcData, srcLen, destData, &dl, 1963d9096215SJens Wiklander tag, tagLen); 1964d9096215SJens Wiklander *destLen = dl; 1965d9096215SJens Wiklander return res; 1966d9096215SJens Wiklander } 1967d9096215SJens Wiklander 1968b0104773SPascal Brand /* Cryptographic Operations API - Asymmetric Functions */ 1969b0104773SPascal Brand 197012e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricEncrypt(TEE_OperationHandle operation, 19718f07fe6fSJerome Forissier const TEE_Attribute *params, 19728f07fe6fSJerome Forissier uint32_t paramCount, const void *srcData, 1973999b69d0SJens Wiklander size_t srcLen, void *destData, 1974999b69d0SJens Wiklander size_t *destLen) 1975b0104773SPascal Brand { 19766915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 1977e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 19786915bbbbSJens Wiklander uint64_t dl = 0; 1979b0104773SPascal Brand 19806915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 1981b0104773SPascal Brand TEE_Panic(0); 19826915bbbbSJens Wiklander 19836915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 19846915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 19856915bbbbSJens Wiklander 198612e66b6fSCedric Chaumont if (!operation->key1) 1987b0104773SPascal Brand TEE_Panic(0); 198812e66b6fSCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 198912e66b6fSCedric Chaumont TEE_Panic(0); 199012e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_ENCRYPT) 1991b0104773SPascal Brand TEE_Panic(0); 1992b0104773SPascal Brand 1993e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 1994e86f1266SJens Wiklander dl = *destLen; 19952c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 1996e86f1266SJens Wiklander srcLen, destData, &dl); 1997e86f1266SJens Wiklander *destLen = dl; 199812e66b6fSCedric Chaumont 19998844ebfcSPascal Brand if (res != TEE_SUCCESS && 20008844ebfcSPascal Brand res != TEE_ERROR_SHORT_BUFFER && 20018844ebfcSPascal Brand res != TEE_ERROR_BAD_PARAMETERS) 2002b0104773SPascal Brand TEE_Panic(res); 200312e66b6fSCedric Chaumont 2004b0104773SPascal Brand return res; 2005b0104773SPascal Brand } 2006b0104773SPascal Brand 20074f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricEncrypt(TEE_OperationHandle operation, 20084f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 20094f4374c8SJens Wiklander uint32_t paramCount, 20104f4374c8SJens Wiklander const void *srcData, uint32_t srcLen, 20114f4374c8SJens Wiklander void *destData, uint32_t *destLen) 20124f4374c8SJens Wiklander { 20134f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 20144f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 20154f4374c8SJens Wiklander uint64_t dl = 0; 20164f4374c8SJens Wiklander 20174f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 20184f4374c8SJens Wiklander TEE_Panic(0); 20194f4374c8SJens Wiklander 20204f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 20214f4374c8SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 20224f4374c8SJens Wiklander 20234f4374c8SJens Wiklander if (!operation->key1) 20244f4374c8SJens Wiklander TEE_Panic(0); 20254f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 20264f4374c8SJens Wiklander TEE_Panic(0); 20274f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_ENCRYPT) 20284f4374c8SJens Wiklander TEE_Panic(0); 20294f4374c8SJens Wiklander 20304f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 20314f4374c8SJens Wiklander dl = *destLen; 20324f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 20334f4374c8SJens Wiklander srcLen, destData, &dl); 20344f4374c8SJens Wiklander *destLen = dl; 20354f4374c8SJens Wiklander 20364f4374c8SJens Wiklander if (res != TEE_SUCCESS && 20374f4374c8SJens Wiklander res != TEE_ERROR_SHORT_BUFFER && 20384f4374c8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS) 20394f4374c8SJens Wiklander TEE_Panic(res); 20404f4374c8SJens Wiklander 20414f4374c8SJens Wiklander return res; 20424f4374c8SJens Wiklander } 20434f4374c8SJens Wiklander 204412e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricDecrypt(TEE_OperationHandle operation, 20458f07fe6fSJerome Forissier const TEE_Attribute *params, 20468f07fe6fSJerome Forissier uint32_t paramCount, const void *srcData, 2047999b69d0SJens Wiklander size_t srcLen, void *destData, 2048999b69d0SJens Wiklander size_t *destLen) 2049b0104773SPascal Brand { 20506915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 2051e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 20526915bbbbSJens Wiklander uint64_t dl = 0; 2053b0104773SPascal Brand 20546915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 2055b0104773SPascal Brand TEE_Panic(0); 20566915bbbbSJens Wiklander 20576915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 20586915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 20596915bbbbSJens Wiklander 206012e66b6fSCedric Chaumont if (!operation->key1) 2061b0104773SPascal Brand TEE_Panic(0); 206212e66b6fSCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 206312e66b6fSCedric Chaumont TEE_Panic(0); 206412e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_DECRYPT) 2065b0104773SPascal Brand TEE_Panic(0); 2066b0104773SPascal Brand 2067e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 2068e86f1266SJens Wiklander dl = *destLen; 20692c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 2070e86f1266SJens Wiklander srcLen, destData, &dl); 2071e86f1266SJens Wiklander *destLen = dl; 207212e66b6fSCedric Chaumont 20738844ebfcSPascal Brand if (res != TEE_SUCCESS && 20748844ebfcSPascal Brand res != TEE_ERROR_SHORT_BUFFER && 20758844ebfcSPascal Brand res != TEE_ERROR_BAD_PARAMETERS) 2076b0104773SPascal Brand TEE_Panic(res); 207712e66b6fSCedric Chaumont 2078b0104773SPascal Brand return res; 2079b0104773SPascal Brand } 2080b0104773SPascal Brand 20814f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricDecrypt(TEE_OperationHandle operation, 20824f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 20834f4374c8SJens Wiklander uint32_t paramCount, 20844f4374c8SJens Wiklander const void *srcData, uint32_t srcLen, 20854f4374c8SJens Wiklander void *destData, uint32_t *destLen) 20864f4374c8SJens Wiklander { 20874f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 20884f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 20894f4374c8SJens Wiklander uint64_t dl = 0; 20904f4374c8SJens Wiklander 20914f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) 20924f4374c8SJens Wiklander TEE_Panic(0); 20934f4374c8SJens Wiklander 20944f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 20954f4374c8SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen)); 20964f4374c8SJens Wiklander 20974f4374c8SJens Wiklander if (!operation->key1) 20984f4374c8SJens Wiklander TEE_Panic(0); 20994f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER) 21004f4374c8SJens Wiklander TEE_Panic(0); 21014f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_DECRYPT) 21024f4374c8SJens Wiklander TEE_Panic(0); 21034f4374c8SJens Wiklander 21044f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 21054f4374c8SJens Wiklander dl = *destLen; 21064f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, srcData, 21074f4374c8SJens Wiklander srcLen, destData, &dl); 21084f4374c8SJens Wiklander *destLen = dl; 21094f4374c8SJens Wiklander 21104f4374c8SJens Wiklander if (res != TEE_SUCCESS && 21114f4374c8SJens Wiklander res != TEE_ERROR_SHORT_BUFFER && 21124f4374c8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS) 21134f4374c8SJens Wiklander TEE_Panic(res); 21144f4374c8SJens Wiklander 21154f4374c8SJens Wiklander return res; 21164f4374c8SJens Wiklander } 21174f4374c8SJens Wiklander 211812e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricSignDigest(TEE_OperationHandle operation, 21198f07fe6fSJerome Forissier const TEE_Attribute *params, 21208f07fe6fSJerome Forissier uint32_t paramCount, const void *digest, 21210b354ec8SJens Wiklander size_t digestLen, void *signature, 21220b354ec8SJens Wiklander size_t *signatureLen) 2123b0104773SPascal Brand { 21246915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS; 2125e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 21266915bbbbSJens Wiklander uint64_t sl = 0; 2127b0104773SPascal Brand 21286915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen)) 2129b0104773SPascal Brand TEE_Panic(0); 21306915bbbbSJens Wiklander 21316915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 21326915bbbbSJens Wiklander __utee_check_inout_annotation(signatureLen, sizeof(*signatureLen)); 21336915bbbbSJens Wiklander 213412e66b6fSCedric Chaumont if (!operation->key1) 2135b0104773SPascal Brand TEE_Panic(0); 213612e66b6fSCedric Chaumont if (operation->info.operationClass != 213712e66b6fSCedric Chaumont TEE_OPERATION_ASYMMETRIC_SIGNATURE) 213812e66b6fSCedric Chaumont TEE_Panic(0); 213912e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_SIGN) 2140b0104773SPascal Brand TEE_Panic(0); 2141b0104773SPascal Brand 2142e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 2143e86f1266SJens Wiklander sl = *signatureLen; 21442c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, digest, 2145e86f1266SJens Wiklander digestLen, signature, &sl); 2146e86f1266SJens Wiklander *signatureLen = sl; 214712e66b6fSCedric Chaumont 2148b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER) 2149b0104773SPascal Brand TEE_Panic(res); 215012e66b6fSCedric Chaumont 2151b0104773SPascal Brand return res; 2152b0104773SPascal Brand } 2153b0104773SPascal Brand 21544f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricSignDigest(TEE_OperationHandle operation, 21554f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 21564f4374c8SJens Wiklander uint32_t paramCount, 21574f4374c8SJens Wiklander const void *digest, 21584f4374c8SJens Wiklander uint32_t digestLen, void *signature, 21594f4374c8SJens Wiklander uint32_t *signatureLen) 21604f4374c8SJens Wiklander { 21614f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 21624f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 21634f4374c8SJens Wiklander uint64_t sl = 0; 21644f4374c8SJens Wiklander 21654f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen)) 21664f4374c8SJens Wiklander TEE_Panic(0); 21674f4374c8SJens Wiklander 21684f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 21694f4374c8SJens Wiklander __utee_check_inout_annotation(signatureLen, sizeof(*signatureLen)); 21704f4374c8SJens Wiklander 21714f4374c8SJens Wiklander if (!operation->key1) 21724f4374c8SJens Wiklander TEE_Panic(0); 21734f4374c8SJens Wiklander if (operation->info.operationClass != 21744f4374c8SJens Wiklander TEE_OPERATION_ASYMMETRIC_SIGNATURE) 21754f4374c8SJens Wiklander TEE_Panic(0); 21764f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_SIGN) 21774f4374c8SJens Wiklander TEE_Panic(0); 21784f4374c8SJens Wiklander 21794f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 21804f4374c8SJens Wiklander sl = *signatureLen; 21814f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, digest, 21824f4374c8SJens Wiklander digestLen, signature, &sl); 21834f4374c8SJens Wiklander *signatureLen = sl; 21844f4374c8SJens Wiklander 21854f4374c8SJens Wiklander if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER) 21864f4374c8SJens Wiklander TEE_Panic(res); 21874f4374c8SJens Wiklander 21884f4374c8SJens Wiklander return res; 21894f4374c8SJens Wiklander } 21904f4374c8SJens Wiklander 219112e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation, 21928f07fe6fSJerome Forissier const TEE_Attribute *params, 21938f07fe6fSJerome Forissier uint32_t paramCount, const void *digest, 21940b354ec8SJens Wiklander size_t digestLen, 21958f07fe6fSJerome Forissier const void *signature, 21960b354ec8SJens Wiklander size_t signatureLen) 2197b0104773SPascal Brand { 2198b0104773SPascal Brand TEE_Result res; 2199e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 2200b0104773SPascal Brand 220112e66b6fSCedric Chaumont if (operation == TEE_HANDLE_NULL || 220212e66b6fSCedric Chaumont (digest == NULL && digestLen != 0) || 2203b0104773SPascal Brand (signature == NULL && signatureLen != 0)) 2204b0104773SPascal Brand TEE_Panic(0); 22056915bbbbSJens Wiklander 22066915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 22076915bbbbSJens Wiklander 220812e66b6fSCedric Chaumont if (!operation->key1) 2209b0104773SPascal Brand TEE_Panic(0); 221012e66b6fSCedric Chaumont if (operation->info.operationClass != 221112e66b6fSCedric Chaumont TEE_OPERATION_ASYMMETRIC_SIGNATURE) 221212e66b6fSCedric Chaumont TEE_Panic(0); 221312e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_VERIFY) 2214b0104773SPascal Brand TEE_Panic(0); 2215b0104773SPascal Brand 2216e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 22172c028fdeSJerome Forissier res = _utee_asymm_verify(operation->state, ua, paramCount, digest, 221812e66b6fSCedric Chaumont digestLen, signature, signatureLen); 221912e66b6fSCedric Chaumont 2220b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID) 2221b0104773SPascal Brand TEE_Panic(res); 222212e66b6fSCedric Chaumont 2223b0104773SPascal Brand return res; 2224b0104773SPascal Brand } 2225b0104773SPascal Brand 22264f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation, 22274f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 22284f4374c8SJens Wiklander uint32_t paramCount, 22294f4374c8SJens Wiklander const void *digest, 22304f4374c8SJens Wiklander uint32_t digestLen, 22314f4374c8SJens Wiklander const void *signature, 22324f4374c8SJens Wiklander uint32_t signatureLen) 22334f4374c8SJens Wiklander { 22344f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 22354f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 22364f4374c8SJens Wiklander 22374f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen) || 22384f4374c8SJens Wiklander (!signature && signatureLen)) 22394f4374c8SJens Wiklander TEE_Panic(0); 22404f4374c8SJens Wiklander 22414f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 22424f4374c8SJens Wiklander 22434f4374c8SJens Wiklander if (!operation->key1) 22444f4374c8SJens Wiklander TEE_Panic(0); 22454f4374c8SJens Wiklander if (operation->info.operationClass != 22464f4374c8SJens Wiklander TEE_OPERATION_ASYMMETRIC_SIGNATURE) 22474f4374c8SJens Wiklander TEE_Panic(0); 22484f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_VERIFY) 22494f4374c8SJens Wiklander TEE_Panic(0); 22504f4374c8SJens Wiklander 22514f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 22524f4374c8SJens Wiklander res = _utee_asymm_verify(operation->state, ua, paramCount, digest, 22534f4374c8SJens Wiklander digestLen, signature, signatureLen); 22544f4374c8SJens Wiklander 22554f4374c8SJens Wiklander if (res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID) 22564f4374c8SJens Wiklander TEE_Panic(res); 22574f4374c8SJens Wiklander 22584f4374c8SJens Wiklander return res; 22594f4374c8SJens Wiklander } 22604f4374c8SJens Wiklander 2261b0104773SPascal Brand /* Cryptographic Operations API - Key Derivation Functions */ 2262b0104773SPascal Brand 2263b0104773SPascal Brand void TEE_DeriveKey(TEE_OperationHandle operation, 2264b0104773SPascal Brand const TEE_Attribute *params, uint32_t paramCount, 2265b0104773SPascal Brand TEE_ObjectHandle derivedKey) 2266b0104773SPascal Brand { 2267e86f1266SJens Wiklander struct utee_attribute ua[paramCount]; 226875d6a373SJens Wiklander struct utee_object_info key_info = { }; 226975d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS; 2270b0104773SPascal Brand 2271b0104773SPascal Brand if (operation == TEE_HANDLE_NULL || derivedKey == 0) 2272b0104773SPascal Brand TEE_Panic(0); 22736915bbbbSJens Wiklander 22746915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount); 22756915bbbbSJens Wiklander 22768854d3c6SJerome Forissier if (TEE_ALG_GET_CLASS(operation->info.algorithm) != 22778854d3c6SJerome Forissier TEE_OPERATION_KEY_DERIVATION) 2278b0104773SPascal Brand TEE_Panic(0); 2279b0104773SPascal Brand 2280b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_KEY_DERIVATION) 2281b0104773SPascal Brand TEE_Panic(0); 228284fa9467SCedric Chaumont if (!operation->key1) 228384fa9467SCedric Chaumont TEE_Panic(0); 2284b0104773SPascal Brand if (operation->info.mode != TEE_MODE_DERIVE) 2285b0104773SPascal Brand TEE_Panic(0); 2286b0104773SPascal Brand if ((operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0) 2287b0104773SPascal Brand TEE_Panic(0); 2288b0104773SPascal Brand 22892c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)derivedKey, &key_info); 2290b0104773SPascal Brand if (res != TEE_SUCCESS) 2291b36311adSJerome Forissier TEE_Panic(res); 2292b0104773SPascal Brand 229375d6a373SJens Wiklander if (key_info.obj_type != TEE_TYPE_GENERIC_SECRET) 2294b0104773SPascal Brand TEE_Panic(0); 229575d6a373SJens Wiklander if ((key_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 2296b0104773SPascal Brand TEE_Panic(0); 2297b0104773SPascal Brand 2298e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount); 22992c028fdeSJerome Forissier res = _utee_cryp_derive_key(operation->state, ua, paramCount, 2300e86f1266SJens Wiklander (unsigned long)derivedKey); 2301b0104773SPascal Brand if (res != TEE_SUCCESS) 2302b0104773SPascal Brand TEE_Panic(res); 2303b0104773SPascal Brand } 2304b0104773SPascal Brand 23054f4374c8SJens Wiklander void __GP11_TEE_DeriveKey(TEE_OperationHandle operation, 23064f4374c8SJens Wiklander const __GP11_TEE_Attribute *params, 23074f4374c8SJens Wiklander uint32_t paramCount, TEE_ObjectHandle derivedKey) 23084f4374c8SJens Wiklander { 23094f4374c8SJens Wiklander struct utee_attribute ua[paramCount]; 23104f4374c8SJens Wiklander struct utee_object_info key_info = { }; 23114f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS; 23124f4374c8SJens Wiklander 23134f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || derivedKey == 0) 23144f4374c8SJens Wiklander TEE_Panic(0); 23154f4374c8SJens Wiklander 23164f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount); 23174f4374c8SJens Wiklander 23184f4374c8SJens Wiklander if (TEE_ALG_GET_CLASS(operation->info.algorithm) != 23194f4374c8SJens Wiklander TEE_OPERATION_KEY_DERIVATION) 23204f4374c8SJens Wiklander TEE_Panic(0); 23214f4374c8SJens Wiklander 23224f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_KEY_DERIVATION) 23234f4374c8SJens Wiklander TEE_Panic(0); 23244f4374c8SJens Wiklander if (!operation->key1) 23254f4374c8SJens Wiklander TEE_Panic(0); 23264f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_DERIVE) 23274f4374c8SJens Wiklander TEE_Panic(0); 23284f4374c8SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0) 23294f4374c8SJens Wiklander TEE_Panic(0); 23304f4374c8SJens Wiklander 23314f4374c8SJens Wiklander res = _utee_cryp_obj_get_info((unsigned long)derivedKey, &key_info); 23324f4374c8SJens Wiklander if (res != TEE_SUCCESS) 23334f4374c8SJens Wiklander TEE_Panic(res); 23344f4374c8SJens Wiklander 23354f4374c8SJens Wiklander if (key_info.obj_type != TEE_TYPE_GENERIC_SECRET) 23364f4374c8SJens Wiklander TEE_Panic(0); 23374f4374c8SJens Wiklander if ((key_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0) 23384f4374c8SJens Wiklander TEE_Panic(0); 23394f4374c8SJens Wiklander 23404f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount); 23414f4374c8SJens Wiklander res = _utee_cryp_derive_key(operation->state, ua, paramCount, 23424f4374c8SJens Wiklander (unsigned long)derivedKey); 23434f4374c8SJens Wiklander if (res != TEE_SUCCESS) 23444f4374c8SJens Wiklander TEE_Panic(res); 23454f4374c8SJens Wiklander } 23464f4374c8SJens Wiklander 2347b0104773SPascal Brand /* Cryptographic Operations API - Random Number Generation Functions */ 2348b0104773SPascal Brand 2349411a488aSJens Wiklander void TEE_GenerateRandom(void *randomBuffer, size_t randomBufferLen) 2350b0104773SPascal Brand { 2351b0104773SPascal Brand TEE_Result res; 2352b0104773SPascal Brand 23532c028fdeSJerome Forissier res = _utee_cryp_random_number_generate(randomBuffer, randomBufferLen); 2354b0104773SPascal Brand if (res != TEE_SUCCESS) 2355b0104773SPascal Brand TEE_Panic(res); 2356b0104773SPascal Brand } 2357433c4257SJens Wiklander 2358411a488aSJens Wiklander void __GP11_TEE_GenerateRandom(void *randomBuffer, uint32_t randomBufferLen) 2359411a488aSJens Wiklander { 2360411a488aSJens Wiklander TEE_GenerateRandom(randomBuffer, randomBufferLen); 2361411a488aSJens Wiklander } 2362411a488aSJens Wiklander 2363433c4257SJens Wiklander int rand(void) 2364433c4257SJens Wiklander { 2365433c4257SJens Wiklander int rc; 2366433c4257SJens Wiklander 2367433c4257SJens Wiklander TEE_GenerateRandom(&rc, sizeof(rc)); 2368433c4257SJens Wiklander 2369433c4257SJens Wiklander /* 2370433c4257SJens Wiklander * RAND_MAX is the larges int, INT_MAX which is all bits but the 2371433c4257SJens Wiklander * highest bit set. 2372433c4257SJens Wiklander */ 2373433c4257SJens Wiklander return rc & RAND_MAX; 2374433c4257SJens Wiklander } 237579170ce0SJerome Forissier 237679170ce0SJerome Forissier TEE_Result TEE_IsAlgorithmSupported(uint32_t alg, uint32_t element) 237779170ce0SJerome Forissier { 237879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_AES)) { 237979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) { 238079170ce0SJerome Forissier if (alg == TEE_ALG_AES_ECB_NOPAD) 238179170ce0SJerome Forissier goto check_element_none; 238279170ce0SJerome Forissier } 238379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) { 238479170ce0SJerome Forissier if (alg == TEE_ALG_AES_CBC_NOPAD) 238579170ce0SJerome Forissier goto check_element_none; 238679170ce0SJerome Forissier } 238779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTR)) { 238879170ce0SJerome Forissier if (alg == TEE_ALG_AES_CTR) 238979170ce0SJerome Forissier goto check_element_none; 239079170ce0SJerome Forissier } 239179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTS)) { 239279170ce0SJerome Forissier if (alg == TEE_ALG_AES_CTS) 239379170ce0SJerome Forissier goto check_element_none; 239479170ce0SJerome Forissier } 239579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_XTS)) { 239679170ce0SJerome Forissier if (alg == TEE_ALG_AES_XTS) 239779170ce0SJerome Forissier goto check_element_none; 239879170ce0SJerome Forissier } 239979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC_MAC)) { 240079170ce0SJerome Forissier if (alg == TEE_ALG_AES_CBC_MAC_NOPAD || 240179170ce0SJerome Forissier alg == TEE_ALG_AES_CBC_MAC_PKCS5) 240279170ce0SJerome Forissier goto check_element_none; 240379170ce0SJerome Forissier } 240479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CMAC)) { 240579170ce0SJerome Forissier if (alg == TEE_ALG_AES_CMAC) 240679170ce0SJerome Forissier goto check_element_none; 240779170ce0SJerome Forissier } 240879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CCM)) { 240979170ce0SJerome Forissier if (alg == TEE_ALG_AES_CCM) 241079170ce0SJerome Forissier goto check_element_none; 241179170ce0SJerome Forissier } 241279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_GCM)) { 241379170ce0SJerome Forissier if (alg == TEE_ALG_AES_GCM) 241479170ce0SJerome Forissier goto check_element_none; 241579170ce0SJerome Forissier } 241679170ce0SJerome Forissier } 241779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DES)) { 241879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) { 241979170ce0SJerome Forissier if (alg == TEE_ALG_DES_ECB_NOPAD || 242079170ce0SJerome Forissier alg == TEE_ALG_DES3_ECB_NOPAD) 242179170ce0SJerome Forissier goto check_element_none; 242279170ce0SJerome Forissier } 242379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) { 242479170ce0SJerome Forissier if (alg == TEE_ALG_DES_CBC_NOPAD || 242579170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_NOPAD) 242679170ce0SJerome Forissier goto check_element_none; 242779170ce0SJerome Forissier } 242879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC_MAC)) { 242979170ce0SJerome Forissier if (alg == TEE_ALG_DES_CBC_MAC_NOPAD || 243079170ce0SJerome Forissier alg == TEE_ALG_DES_CBC_MAC_PKCS5 || 243179170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_MAC_NOPAD || 243279170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_MAC_PKCS5) 243379170ce0SJerome Forissier goto check_element_none; 243479170ce0SJerome Forissier } 243579170ce0SJerome Forissier } 243679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) { 243779170ce0SJerome Forissier if (alg == TEE_ALG_MD5) 243879170ce0SJerome Forissier goto check_element_none; 243979170ce0SJerome Forissier } 244079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 244179170ce0SJerome Forissier if (alg == TEE_ALG_SHA1) 244279170ce0SJerome Forissier goto check_element_none; 244379170ce0SJerome Forissier } 244479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 244579170ce0SJerome Forissier if (alg == TEE_ALG_SHA224) 244679170ce0SJerome Forissier goto check_element_none; 244779170ce0SJerome Forissier } 244879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 244979170ce0SJerome Forissier if (alg == TEE_ALG_SHA256) 245079170ce0SJerome Forissier goto check_element_none; 245179170ce0SJerome Forissier } 245279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) { 245379170ce0SJerome Forissier if (alg == TEE_ALG_SHA384) 245479170ce0SJerome Forissier goto check_element_none; 245579170ce0SJerome Forissier } 245679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) { 245779170ce0SJerome Forissier if (alg == TEE_ALG_SHA512) 245879170ce0SJerome Forissier goto check_element_none; 245979170ce0SJerome Forissier } 2460260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_224)) { 2461260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_224) 2462260b4028SJens Wiklander goto check_element_none; 2463260b4028SJens Wiklander } 2464260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_256)) { 2465260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_256) 2466260b4028SJens Wiklander goto check_element_none; 2467260b4028SJens Wiklander } 2468260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_384)) { 2469260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_384) 2470260b4028SJens Wiklander goto check_element_none; 2471260b4028SJens Wiklander } 2472260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_512)) { 2473260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_512) 2474260b4028SJens Wiklander goto check_element_none; 2475260b4028SJens Wiklander } 247679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5) && IS_ENABLED(CFG_CRYPTO_SHA1)) { 247779170ce0SJerome Forissier if (alg == TEE_ALG_MD5SHA1) 247879170ce0SJerome Forissier goto check_element_none; 247979170ce0SJerome Forissier } 248079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_HMAC)) { 248179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) { 248279170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_MD5) 248379170ce0SJerome Forissier goto check_element_none; 248479170ce0SJerome Forissier } 248579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 248679170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA1) 248779170ce0SJerome Forissier goto check_element_none; 248879170ce0SJerome Forissier } 248979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 249079170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA224) 249179170ce0SJerome Forissier goto check_element_none; 249279170ce0SJerome Forissier } 249379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 249479170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA256) 249579170ce0SJerome Forissier goto check_element_none; 249679170ce0SJerome Forissier } 249779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) { 249879170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA384) 249979170ce0SJerome Forissier goto check_element_none; 250079170ce0SJerome Forissier } 250179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) { 250279170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA512) 250379170ce0SJerome Forissier goto check_element_none; 250479170ce0SJerome Forissier } 2505260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_224)) { 2506260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_224) 2507260b4028SJens Wiklander goto check_element_none; 2508260b4028SJens Wiklander } 2509260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_256)) { 2510260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_256) 2511260b4028SJens Wiklander goto check_element_none; 2512260b4028SJens Wiklander } 2513260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_384)) { 2514260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_384) 2515260b4028SJens Wiklander goto check_element_none; 2516260b4028SJens Wiklander } 2517260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_512)) { 2518260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_512) 2519260b4028SJens Wiklander goto check_element_none; 2520260b4028SJens Wiklander } 252179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM3)) { 252279170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SM3) 252379170ce0SJerome Forissier goto check_element_none; 252479170ce0SJerome Forissier } 252579170ce0SJerome Forissier } 252679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM3)) { 252779170ce0SJerome Forissier if (alg == TEE_ALG_SM3) 252879170ce0SJerome Forissier goto check_element_none; 252979170ce0SJerome Forissier } 253079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM4)) { 253179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) { 253279170ce0SJerome Forissier if (alg == TEE_ALG_SM4_ECB_NOPAD) 253379170ce0SJerome Forissier goto check_element_none; 253479170ce0SJerome Forissier } 253579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) { 253679170ce0SJerome Forissier if (alg == TEE_ALG_SM4_CBC_NOPAD) 253779170ce0SJerome Forissier goto check_element_none; 253879170ce0SJerome Forissier } 253979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTR)) { 254079170ce0SJerome Forissier if (alg == TEE_ALG_SM4_CTR) 254179170ce0SJerome Forissier goto check_element_none; 254279170ce0SJerome Forissier } 2543696f56acSPingan Xie if (IS_ENABLED(CFG_CRYPTO_XTS)) { 2544696f56acSPingan Xie if (alg == TEE_ALG_SM4_XTS) 2545696f56acSPingan Xie goto check_element_none; 2546696f56acSPingan Xie } 254779170ce0SJerome Forissier } 254879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_RSA)) { 254979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) { 255079170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5) 255179170ce0SJerome Forissier goto check_element_none; 255279170ce0SJerome Forissier } 255379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 255479170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA1 || 255579170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1 || 255679170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1) 255779170ce0SJerome Forissier goto check_element_none; 255879170ce0SJerome Forissier } 255979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5) && IS_ENABLED(CFG_CRYPTO_SHA1)) { 256079170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5SHA1) 256179170ce0SJerome Forissier goto check_element_none; 256279170ce0SJerome Forissier } 256379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 256479170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA224 || 256579170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224 || 256679170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224) 256779170ce0SJerome Forissier goto check_element_none; 256879170ce0SJerome Forissier } 256979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 257079170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA256 || 257179170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 || 257279170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256) 257379170ce0SJerome Forissier goto check_element_none; 257479170ce0SJerome Forissier } 257579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) { 257679170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA384 || 257779170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384 || 257879170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384) 257979170ce0SJerome Forissier goto check_element_none; 258079170ce0SJerome Forissier } 258179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) { 258279170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA512 || 258379170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512 || 258479170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512) 258579170ce0SJerome Forissier goto check_element_none; 258679170ce0SJerome Forissier } 258779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_RSASSA_NA1)) { 258879170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5) 258979170ce0SJerome Forissier goto check_element_none; 259079170ce0SJerome Forissier } 259179170ce0SJerome Forissier if (alg == TEE_ALG_RSA_NOPAD) 259279170ce0SJerome Forissier goto check_element_none; 259379170ce0SJerome Forissier } 259479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DSA)) { 259579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) { 259679170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA1) 259779170ce0SJerome Forissier goto check_element_none; 259879170ce0SJerome Forissier } 259979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) { 260079170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA224) 260179170ce0SJerome Forissier goto check_element_none; 260279170ce0SJerome Forissier } 260379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) { 260479170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA256) 260579170ce0SJerome Forissier goto check_element_none; 260679170ce0SJerome Forissier } 260779170ce0SJerome Forissier } 260879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DH)) { 260979170ce0SJerome Forissier if (alg == TEE_ALG_DH_DERIVE_SHARED_SECRET) 261079170ce0SJerome Forissier goto check_element_none; 261179170ce0SJerome Forissier } 261279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECC)) { 2613fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P192 || 2614fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P192 || 2615fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2616fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA1) && 261779170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P192) 261879170ce0SJerome Forissier return TEE_SUCCESS; 2619fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P224 || 2620fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P224 || 2621fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2622fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA224) && 262379170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P224) 262479170ce0SJerome Forissier return TEE_SUCCESS; 2625fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P256 || 2626fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P256 || 2627fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2628fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA256) && 262979170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P256) 263079170ce0SJerome Forissier return TEE_SUCCESS; 2631fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P384 || 2632fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P384 || 2633fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2634fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA384) && 263579170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P384) 263679170ce0SJerome Forissier return TEE_SUCCESS; 2637fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P521 || 2638fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P521 || 2639fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET || 2640fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA512) && 264179170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P521) 264279170ce0SJerome Forissier return TEE_SUCCESS; 264379170ce0SJerome Forissier } 264479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_DSA)) { 264579170ce0SJerome Forissier if (alg == TEE_ALG_SM2_DSA_SM3 && element == TEE_ECC_CURVE_SM2) 264679170ce0SJerome Forissier return TEE_SUCCESS; 264779170ce0SJerome Forissier } 264879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_KEP)) { 264979170ce0SJerome Forissier if (alg == TEE_ALG_SM2_KEP && element == TEE_ECC_CURVE_SM2) 265079170ce0SJerome Forissier return TEE_SUCCESS; 265179170ce0SJerome Forissier } 265279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_PKE)) { 265379170ce0SJerome Forissier if (alg == TEE_ALG_SM2_PKE && element == TEE_ECC_CURVE_SM2) 265479170ce0SJerome Forissier return TEE_SUCCESS; 265579170ce0SJerome Forissier } 26563f61056dSSohaib ul Hassan if (IS_ENABLED(CFG_CRYPTO_X25519)) { 26573f61056dSSohaib ul Hassan if (alg == TEE_ALG_X25519 && element == TEE_ECC_CURVE_25519) 26583f61056dSSohaib ul Hassan return TEE_SUCCESS; 26593f61056dSSohaib ul Hassan } 2660e1f9cee7SSergiy Kibrik if (IS_ENABLED(CFG_CRYPTO_ED25519)) { 2661e1f9cee7SSergiy Kibrik if (alg == TEE_ALG_ED25519 && element == TEE_ECC_CURVE_25519) 2662e1f9cee7SSergiy Kibrik return TEE_SUCCESS; 2663e1f9cee7SSergiy Kibrik } 266479170ce0SJerome Forissier 266579170ce0SJerome Forissier return TEE_ERROR_NOT_SUPPORTED; 266679170ce0SJerome Forissier check_element_none: 266779170ce0SJerome Forissier if (element == TEE_CRYPTO_ELEMENT_NONE) 266879170ce0SJerome Forissier return TEE_SUCCESS; 266979170ce0SJerome Forissier return TEE_ERROR_NOT_SUPPORTED; 267079170ce0SJerome Forissier } 2671