11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
2b0104773SPascal Brand /*
3b0104773SPascal Brand * Copyright (c) 2014, STMicroelectronics International N.V.
4eee637e7SAlexander Zakharov * Copyright (c) 2021, SumUp Services GmbH
5b0104773SPascal Brand */
624ea7613SJens Wiklander #include <assert.h>
779170ce0SJerome Forissier #include <config.h>
8b0104773SPascal Brand #include <stdlib.h>
9b0104773SPascal Brand #include <string.h>
10b796ebf3SJerome Forissier #include <string_ext.h>
11b0104773SPascal Brand #include <tee_api.h>
128854d3c6SJerome Forissier #include <tee_api_defines_extensions.h>
13b0104773SPascal Brand #include <tee_internal_api_extensions.h>
14b0104773SPascal Brand #include <utee_syscalls.h>
15b0104773SPascal Brand #include <utee_defines.h>
16fc26c92aSJens Wiklander #include <util.h>
17e86f1266SJens Wiklander #include "tee_api_private.h"
18b0104773SPascal Brand
19b0104773SPascal Brand struct __TEE_OperationHandle {
20b0104773SPascal Brand TEE_OperationInfo info;
21b0104773SPascal Brand TEE_ObjectHandle key1;
22b0104773SPascal Brand TEE_ObjectHandle key2;
23642a1607SCedric Chaumont uint32_t operationState;/* Operation state : INITIAL or ACTIVE */
2424ea7613SJens Wiklander
2524ea7613SJens Wiklander /*
2624ea7613SJens Wiklander * buffer to collect complete blocks or to keep a complete digest
2724ea7613SJens Wiklander * for TEE_DigestExtract().
2824ea7613SJens Wiklander */
2924ea7613SJens Wiklander uint8_t *buffer;
30b0104773SPascal Brand bool buffer_two_blocks; /* True if two blocks need to be buffered */
31b0104773SPascal Brand size_t block_size; /* Block size of cipher */
32b0104773SPascal Brand size_t buffer_offs; /* Offset in buffer */
33b0104773SPascal Brand uint32_t state; /* Handle to state in TEE Core */
34b0104773SPascal Brand };
35b0104773SPascal Brand
36b0104773SPascal Brand /* Cryptographic Operations API - Generic Operation Functions */
37b0104773SPascal Brand
TEE_AllocateOperation(TEE_OperationHandle * operation,uint32_t algorithm,uint32_t mode,uint32_t maxKeySize)38b0104773SPascal Brand TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation,
39b0104773SPascal Brand uint32_t algorithm, uint32_t mode,
40b0104773SPascal Brand uint32_t maxKeySize)
41b0104773SPascal Brand {
42b0104773SPascal Brand TEE_Result res;
43b0104773SPascal Brand TEE_OperationHandle op = TEE_HANDLE_NULL;
44b0104773SPascal Brand uint32_t handle_state = 0;
45b0104773SPascal Brand size_t block_size = 1;
46b0104773SPascal Brand uint32_t req_key_usage;
47b0104773SPascal Brand bool with_private_key = false;
48b0104773SPascal Brand bool buffer_two_blocks = false;
49b0104773SPascal Brand
509b52c538SCedric Chaumont if (!operation)
51b0104773SPascal Brand TEE_Panic(0);
52b0104773SPascal Brand
53696f56acSPingan Xie if (algorithm == TEE_ALG_AES_XTS || algorithm == TEE_ALG_SM2_KEP ||
54696f56acSPingan Xie algorithm == TEE_ALG_SM4_XTS)
55b0104773SPascal Brand handle_state = TEE_HANDLE_FLAG_EXPECT_TWO_KEYS;
56b0104773SPascal Brand
57218d9055SCedric Chaumont /* Check algorithm max key size */
58218d9055SCedric Chaumont switch (algorithm) {
59218d9055SCedric Chaumont case TEE_ALG_DSA_SHA1:
60218d9055SCedric Chaumont if (maxKeySize < 512)
61218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED;
62218d9055SCedric Chaumont if (maxKeySize > 1024)
63218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED;
64218d9055SCedric Chaumont if (maxKeySize % 64 != 0)
65218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED;
66218d9055SCedric Chaumont break;
67218d9055SCedric Chaumont
68218d9055SCedric Chaumont case TEE_ALG_DSA_SHA224:
69218d9055SCedric Chaumont if (maxKeySize != 2048)
70218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED;
71218d9055SCedric Chaumont break;
72218d9055SCedric Chaumont
73218d9055SCedric Chaumont case TEE_ALG_DSA_SHA256:
74218d9055SCedric Chaumont if (maxKeySize != 2048 && maxKeySize != 3072)
75218d9055SCedric Chaumont return TEE_ERROR_NOT_SUPPORTED;
76218d9055SCedric Chaumont break;
77218d9055SCedric Chaumont
78fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA1:
79fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P192:
80fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P192:
811220586eSCedric Chaumont if (maxKeySize != 192)
821220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED;
831220586eSCedric Chaumont break;
841220586eSCedric Chaumont
85fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA224:
86fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P224:
87fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P224:
881220586eSCedric Chaumont if (maxKeySize != 224)
891220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED;
901220586eSCedric Chaumont break;
911220586eSCedric Chaumont
92fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA256:
93fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P256:
94fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P256:
9591fc6bd8SJerome Forissier case TEE_ALG_SM2_PKE:
960f151943SJerome Forissier case TEE_ALG_SM2_DSA_SM3:
971220586eSCedric Chaumont if (maxKeySize != 256)
981220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED;
991220586eSCedric Chaumont break;
1001220586eSCedric Chaumont
1015b385b3fSJerome Forissier case TEE_ALG_SM2_KEP:
1025b385b3fSJerome Forissier /* Two 256-bit keys */
1035b385b3fSJerome Forissier if (maxKeySize != 512)
1045b385b3fSJerome Forissier return TEE_ERROR_NOT_SUPPORTED;
1055b385b3fSJerome Forissier break;
1065b385b3fSJerome Forissier
107fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA384:
108fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P384:
109fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P384:
1101220586eSCedric Chaumont if (maxKeySize != 384)
1111220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED;
1121220586eSCedric Chaumont break;
1131220586eSCedric Chaumont
114fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA512:
115fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P521:
116fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P521:
1171220586eSCedric Chaumont if (maxKeySize != 521)
1181220586eSCedric Chaumont return TEE_ERROR_NOT_SUPPORTED;
1191220586eSCedric Chaumont break;
120fe2fd3ffSJens Wiklander
121fe2fd3ffSJens Wiklander case TEE_ALG_ECDH_DERIVE_SHARED_SECRET:
122fe2fd3ffSJens Wiklander if (maxKeySize > 521)
123fe2fd3ffSJens Wiklander return TEE_ERROR_NOT_SUPPORTED;
124fe2fd3ffSJens Wiklander break;
125fe2fd3ffSJens Wiklander
126e1f9cee7SSergiy Kibrik case TEE_ALG_ED25519:
1273f61056dSSohaib ul Hassan case TEE_ALG_X25519:
1283f61056dSSohaib ul Hassan if (maxKeySize != 256)
1293f61056dSSohaib ul Hassan return TEE_ERROR_NOT_SUPPORTED;
1303f61056dSSohaib ul Hassan break;
131218d9055SCedric Chaumont default:
132218d9055SCedric Chaumont break;
133218d9055SCedric Chaumont }
134218d9055SCedric Chaumont
135b291c8ecSVincent Mailhol /* Check algorithm mode */
136b0104773SPascal Brand switch (algorithm) {
137b0104773SPascal Brand case TEE_ALG_AES_CTS:
138b0104773SPascal Brand case TEE_ALG_AES_XTS:
139696f56acSPingan Xie case TEE_ALG_SM4_XTS:
140b0104773SPascal Brand buffer_two_blocks = true;
141919a5a68SJerome Forissier fallthrough;
1424bd53c54SJerome Forissier case TEE_ALG_AES_ECB_NOPAD:
143b0104773SPascal Brand case TEE_ALG_AES_CBC_NOPAD:
144b0104773SPascal Brand case TEE_ALG_AES_CCM:
145b0104773SPascal Brand case TEE_ALG_DES_ECB_NOPAD:
146b0104773SPascal Brand case TEE_ALG_DES_CBC_NOPAD:
147b0104773SPascal Brand case TEE_ALG_DES3_ECB_NOPAD:
148b0104773SPascal Brand case TEE_ALG_DES3_CBC_NOPAD:
149ade6f848SJerome Forissier case TEE_ALG_SM4_ECB_NOPAD:
150ade6f848SJerome Forissier case TEE_ALG_SM4_CBC_NOPAD:
151ade6f848SJerome Forissier case TEE_ALG_SM4_CTR:
152b0104773SPascal Brand if (TEE_ALG_GET_MAIN_ALG(algorithm) == TEE_MAIN_ALGO_AES)
153b0104773SPascal Brand block_size = TEE_AES_BLOCK_SIZE;
154ade6f848SJerome Forissier else if (TEE_ALG_GET_MAIN_ALG(algorithm) == TEE_MAIN_ALGO_SM4)
155ade6f848SJerome Forissier block_size = TEE_SM4_BLOCK_SIZE;
156b0104773SPascal Brand else
157b0104773SPascal Brand block_size = TEE_DES_BLOCK_SIZE;
158919a5a68SJerome Forissier fallthrough;
15957aabac5SBogdan Liulko case TEE_ALG_AES_CTR:
160afc0c182SBogdan Liulko case TEE_ALG_AES_GCM:
161b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT)
162b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT;
163b0104773SPascal Brand else if (mode == TEE_MODE_DECRYPT)
164b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT;
165b0104773SPascal Brand else
166b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED;
167b0104773SPascal Brand break;
168b0104773SPascal Brand
1696a2e0a9fSGabor Szekely #if defined(CFG_CRYPTO_RSASSA_NA1)
1706a2e0a9fSGabor Szekely case TEE_ALG_RSASSA_PKCS1_V1_5:
1716a2e0a9fSGabor Szekely #endif
172b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_MD5:
173b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA1:
174b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA224:
175b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA256:
176b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA384:
177b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_V1_5_SHA512:
178f5c3d85aSJulien Masson case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_MD5:
179b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
180b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
181b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
182b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
183b0104773SPascal Brand case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
184b0104773SPascal Brand case TEE_ALG_DSA_SHA1:
185218d9055SCedric Chaumont case TEE_ALG_DSA_SHA224:
186218d9055SCedric Chaumont case TEE_ALG_DSA_SHA256:
187fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA1:
188fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA224:
189fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA256:
190fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA384:
191fe2fd3ffSJens Wiklander case TEE_ALG_ECDSA_SHA512:
192fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P192:
193fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P224:
194fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P256:
195fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P384:
196fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDSA_P521:
1970f151943SJerome Forissier case TEE_ALG_SM2_DSA_SM3:
198e1f9cee7SSergiy Kibrik case TEE_ALG_ED25519:
199b0104773SPascal Brand if (mode == TEE_MODE_SIGN) {
200b0104773SPascal Brand with_private_key = true;
201b0104773SPascal Brand req_key_usage = TEE_USAGE_SIGN;
202b0104773SPascal Brand } else if (mode == TEE_MODE_VERIFY) {
203b0104773SPascal Brand req_key_usage = TEE_USAGE_VERIFY;
204b0104773SPascal Brand } else {
205b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED;
206b0104773SPascal Brand }
207b0104773SPascal Brand break;
208b0104773SPascal Brand
209b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_V1_5:
210f5c3d85aSJulien Masson case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_MD5:
211b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1:
212b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224:
213b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256:
214b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384:
215b0104773SPascal Brand case TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512:
21691fc6bd8SJerome Forissier case TEE_ALG_SM2_PKE:
217b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) {
218b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT;
219b0104773SPascal Brand } else if (mode == TEE_MODE_DECRYPT) {
220b0104773SPascal Brand with_private_key = true;
221b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT;
222b0104773SPascal Brand } else {
223b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED;
224b0104773SPascal Brand }
225b0104773SPascal Brand break;
226b0104773SPascal Brand
227b0104773SPascal Brand case TEE_ALG_RSA_NOPAD:
228b0104773SPascal Brand if (mode == TEE_MODE_ENCRYPT) {
229b0104773SPascal Brand req_key_usage = TEE_USAGE_ENCRYPT | TEE_USAGE_VERIFY;
230b0104773SPascal Brand } else if (mode == TEE_MODE_DECRYPT) {
231b0104773SPascal Brand with_private_key = true;
232b0104773SPascal Brand req_key_usage = TEE_USAGE_DECRYPT | TEE_USAGE_SIGN;
233b0104773SPascal Brand } else {
234b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED;
235b0104773SPascal Brand }
236b0104773SPascal Brand break;
237b0104773SPascal Brand
238b0104773SPascal Brand case TEE_ALG_DH_DERIVE_SHARED_SECRET:
239fe2fd3ffSJens Wiklander case TEE_ALG_ECDH_DERIVE_SHARED_SECRET:
240fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P192:
241fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P224:
242fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P256:
243fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P384:
244fe2fd3ffSJens Wiklander case __OPTEE_ALG_ECDH_P521:
245cdb198a7SJerome Forissier case TEE_ALG_HKDF_MD5_DERIVE_KEY:
246cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA1_DERIVE_KEY:
247cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA224_DERIVE_KEY:
248cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA256_DERIVE_KEY:
249cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA384_DERIVE_KEY:
250cdb198a7SJerome Forissier case TEE_ALG_HKDF_SHA512_DERIVE_KEY:
2518854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA1_DERIVE_KEY:
2528854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA224_DERIVE_KEY:
2538854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA256_DERIVE_KEY:
2548854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA384_DERIVE_KEY:
2558854d3c6SJerome Forissier case TEE_ALG_CONCAT_KDF_SHA512_DERIVE_KEY:
2560f2293b7SJerome Forissier case TEE_ALG_PBKDF2_HMAC_SHA1_DERIVE_KEY:
2575b385b3fSJerome Forissier case TEE_ALG_SM2_KEP:
2583f61056dSSohaib ul Hassan case TEE_ALG_X25519:
259b0104773SPascal Brand if (mode != TEE_MODE_DERIVE)
260b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED;
261b0104773SPascal Brand with_private_key = true;
262b0104773SPascal Brand req_key_usage = TEE_USAGE_DERIVE;
263b0104773SPascal Brand break;
264b0104773SPascal Brand
265b0104773SPascal Brand case TEE_ALG_MD5:
266b0104773SPascal Brand case TEE_ALG_SHA1:
267b0104773SPascal Brand case TEE_ALG_SHA224:
268b0104773SPascal Brand case TEE_ALG_SHA256:
269b0104773SPascal Brand case TEE_ALG_SHA384:
270b0104773SPascal Brand case TEE_ALG_SHA512:
27124ea7613SJens Wiklander case TEE_ALG_SHA3_224:
27224ea7613SJens Wiklander case TEE_ALG_SHA3_256:
27324ea7613SJens Wiklander case TEE_ALG_SHA3_384:
27424ea7613SJens Wiklander case TEE_ALG_SHA3_512:
27524ea7613SJens Wiklander case TEE_ALG_SHAKE128:
27624ea7613SJens Wiklander case TEE_ALG_SHAKE256:
27747645577SJerome Forissier case TEE_ALG_SM3:
278b0104773SPascal Brand if (mode != TEE_MODE_DIGEST)
279b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED;
28005304565SCedric Chaumont /* v1.1: flags always set for digest operations */
281b0104773SPascal Brand handle_state |= TEE_HANDLE_FLAG_KEY_SET;
282b0104773SPascal Brand req_key_usage = 0;
283b0104773SPascal Brand break;
284b0104773SPascal Brand
285b0104773SPascal Brand case TEE_ALG_DES_CBC_MAC_NOPAD:
286b0104773SPascal Brand case TEE_ALG_AES_CBC_MAC_NOPAD:
287b0104773SPascal Brand case TEE_ALG_AES_CBC_MAC_PKCS5:
288b0104773SPascal Brand case TEE_ALG_AES_CMAC:
289b0104773SPascal Brand case TEE_ALG_DES_CBC_MAC_PKCS5:
290b0104773SPascal Brand case TEE_ALG_DES3_CBC_MAC_NOPAD:
291b0104773SPascal Brand case TEE_ALG_DES3_CBC_MAC_PKCS5:
292eee637e7SAlexander Zakharov case TEE_ALG_DES3_CMAC:
293b0104773SPascal Brand case TEE_ALG_HMAC_MD5:
294b0104773SPascal Brand case TEE_ALG_HMAC_SHA1:
295b0104773SPascal Brand case TEE_ALG_HMAC_SHA224:
296b0104773SPascal Brand case TEE_ALG_HMAC_SHA256:
297b0104773SPascal Brand case TEE_ALG_HMAC_SHA384:
298b0104773SPascal Brand case TEE_ALG_HMAC_SHA512:
299260b4028SJens Wiklander case TEE_ALG_HMAC_SHA3_224:
300260b4028SJens Wiklander case TEE_ALG_HMAC_SHA3_256:
301260b4028SJens Wiklander case TEE_ALG_HMAC_SHA3_384:
302260b4028SJens Wiklander case TEE_ALG_HMAC_SHA3_512:
30347645577SJerome Forissier case TEE_ALG_HMAC_SM3:
304b0104773SPascal Brand if (mode != TEE_MODE_MAC)
305b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED;
306b0104773SPascal Brand req_key_usage = TEE_USAGE_MAC;
307b0104773SPascal Brand break;
308b0104773SPascal Brand
309b0104773SPascal Brand default:
310b0104773SPascal Brand return TEE_ERROR_NOT_SUPPORTED;
311b0104773SPascal Brand }
312b0104773SPascal Brand
313b66f219bSJens Wiklander op = TEE_Malloc(sizeof(*op), TEE_MALLOC_FILL_ZERO);
3149b52c538SCedric Chaumont if (!op)
315b0104773SPascal Brand return TEE_ERROR_OUT_OF_MEMORY;
316b0104773SPascal Brand
317b0104773SPascal Brand op->info.algorithm = algorithm;
318b0104773SPascal Brand op->info.operationClass = TEE_ALG_GET_CLASS(algorithm);
3196a2e0a9fSGabor Szekely #ifdef CFG_CRYPTO_RSASSA_NA1
3206a2e0a9fSGabor Szekely if (algorithm == TEE_ALG_RSASSA_PKCS1_V1_5)
3216a2e0a9fSGabor Szekely op->info.operationClass = TEE_OPERATION_ASYMMETRIC_SIGNATURE;
3226a2e0a9fSGabor Szekely #endif
323b0104773SPascal Brand op->info.mode = mode;
3242e5e6460SAlbert Schwarzkopf op->info.digestLength = TEE_ALG_GET_DIGEST_SIZE(algorithm);
325b0104773SPascal Brand op->info.maxKeySize = maxKeySize;
326b0104773SPascal Brand op->info.requiredKeyUsage = req_key_usage;
327b0104773SPascal Brand op->info.handleState = handle_state;
328b0104773SPascal Brand
32924ea7613SJens Wiklander /*
33024ea7613SJens Wiklander * Needed to buffer the digest if TEE_DigestExtract() doesn't
33124ea7613SJens Wiklander * retrieve the entire digest in one go.
33224ea7613SJens Wiklander */
33324ea7613SJens Wiklander if (op->info.operationClass == TEE_OPERATION_DIGEST)
33424ea7613SJens Wiklander block_size = op->info.digestLength;
33524ea7613SJens Wiklander
336b0104773SPascal Brand if (block_size > 1) {
337b0104773SPascal Brand size_t buffer_size = block_size;
338b0104773SPascal Brand
339b0104773SPascal Brand if (buffer_two_blocks)
340b0104773SPascal Brand buffer_size *= 2;
341b0104773SPascal Brand
3429b52c538SCedric Chaumont op->buffer = TEE_Malloc(buffer_size,
3439b52c538SCedric Chaumont TEE_USER_MEM_HINT_NO_FILL_ZERO);
344b0104773SPascal Brand if (op->buffer == NULL) {
345b0104773SPascal Brand res = TEE_ERROR_OUT_OF_MEMORY;
346b66f219bSJens Wiklander goto out;
347b0104773SPascal Brand }
348b0104773SPascal Brand }
349b0104773SPascal Brand op->block_size = block_size;
350b0104773SPascal Brand op->buffer_two_blocks = buffer_two_blocks;
351b0104773SPascal Brand
352b0104773SPascal Brand if (TEE_ALG_GET_CLASS(algorithm) != TEE_OPERATION_DIGEST) {
353b0104773SPascal Brand uint32_t mks = maxKeySize;
354b0104773SPascal Brand TEE_ObjectType key_type = TEE_ALG_GET_KEY_TYPE(algorithm,
355b0104773SPascal Brand with_private_key);
356b0104773SPascal Brand
357b0104773SPascal Brand /*
358b0104773SPascal Brand * If two keys are expected the max key size is the sum of
359b0104773SPascal Brand * the size of both keys.
360b0104773SPascal Brand */
361b0104773SPascal Brand if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS)
362b0104773SPascal Brand mks /= 2;
363b0104773SPascal Brand
364b0104773SPascal Brand res = TEE_AllocateTransientObject(key_type, mks, &op->key1);
365b0104773SPascal Brand if (res != TEE_SUCCESS)
366b66f219bSJens Wiklander goto out;
367b0104773SPascal Brand
36805304565SCedric Chaumont if (op->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) {
3699b52c538SCedric Chaumont res = TEE_AllocateTransientObject(key_type, mks,
370b0104773SPascal Brand &op->key2);
371b0104773SPascal Brand if (res != TEE_SUCCESS)
372b66f219bSJens Wiklander goto out;
373b0104773SPascal Brand }
374b0104773SPascal Brand }
375b0104773SPascal Brand
3762c028fdeSJerome Forissier res = _utee_cryp_state_alloc(algorithm, mode, (unsigned long)op->key1,
377e86f1266SJens Wiklander (unsigned long)op->key2, &op->state);
378b66f219bSJens Wiklander if (res != TEE_SUCCESS)
379b66f219bSJens Wiklander goto out;
380b0104773SPascal Brand
38105304565SCedric Chaumont /*
38205304565SCedric Chaumont * Initialize digest operations
38305304565SCedric Chaumont * Other multi-stage operations initialized w/ TEE_xxxInit functions
38405304565SCedric Chaumont * Non-applicable on asymmetric operations
38505304565SCedric Chaumont */
38605304565SCedric Chaumont if (TEE_ALG_GET_CLASS(algorithm) == TEE_OPERATION_DIGEST) {
3872c028fdeSJerome Forissier res = _utee_hash_init(op->state, NULL, 0);
38805304565SCedric Chaumont if (res != TEE_SUCCESS)
389b66f219bSJens Wiklander goto out;
39005304565SCedric Chaumont /* v1.1: flags always set for digest operations */
39105304565SCedric Chaumont op->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
39205304565SCedric Chaumont }
39305304565SCedric Chaumont
394642a1607SCedric Chaumont op->operationState = TEE_OPERATION_STATE_INITIAL;
395642a1607SCedric Chaumont
396b0104773SPascal Brand *operation = op;
397b0104773SPascal Brand
398b66f219bSJens Wiklander out:
399b66f219bSJens Wiklander if (res != TEE_SUCCESS) {
400b66f219bSJens Wiklander if (res != TEE_ERROR_OUT_OF_MEMORY &&
4019b52c538SCedric Chaumont res != TEE_ERROR_NOT_SUPPORTED)
402b36311adSJerome Forissier TEE_Panic(res);
403b66f219bSJens Wiklander if (op) {
404b66f219bSJens Wiklander if (op->state) {
405b66f219bSJens Wiklander TEE_FreeOperation(op);
406b66f219bSJens Wiklander } else {
407b66f219bSJens Wiklander TEE_Free(op->buffer);
408b66f219bSJens Wiklander TEE_FreeTransientObject(op->key1);
409b66f219bSJens Wiklander TEE_FreeTransientObject(op->key2);
410b66f219bSJens Wiklander TEE_Free(op);
411b66f219bSJens Wiklander }
412b66f219bSJens Wiklander }
413b66f219bSJens Wiklander }
414b66f219bSJens Wiklander
415b0104773SPascal Brand return res;
416b0104773SPascal Brand }
417b0104773SPascal Brand
TEE_FreeOperation(TEE_OperationHandle operation)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
__GP11_TEE_FreeOperation(TEE_OperationHandle operation)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
TEE_GetOperationInfo(TEE_OperationHandle operation,TEE_OperationInfo * operationInfo)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
TEE_GetOperationInfoMultiple(TEE_OperationHandle op,TEE_OperationInfoMultiple * op_info,size_t * size)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
__GP11_TEE_GetOperationInfoMultiple(TEE_OperationHandle operation,TEE_OperationInfoMultiple * info,uint32_t * operationSize)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
reset_operation_state(TEE_OperationHandle op)563287a6182SJens Wiklander static void reset_operation_state(TEE_OperationHandle op)
564287a6182SJens Wiklander {
565287a6182SJens Wiklander op->operationState = TEE_OPERATION_STATE_INITIAL;
566287a6182SJens Wiklander
567287a6182SJens Wiklander if (op->info.operationClass == TEE_OPERATION_DIGEST) {
568287a6182SJens Wiklander TEE_Result res = _utee_hash_init(op->state, NULL, 0);
569287a6182SJens Wiklander
570287a6182SJens Wiklander if (res != TEE_SUCCESS)
571287a6182SJens Wiklander TEE_Panic(res);
572287a6182SJens Wiklander op->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
573287a6182SJens Wiklander } else {
574287a6182SJens Wiklander op->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
575287a6182SJens Wiklander }
576287a6182SJens Wiklander }
577287a6182SJens Wiklander
TEE_ResetOperation(TEE_OperationHandle operation)578b0104773SPascal Brand void TEE_ResetOperation(TEE_OperationHandle operation)
579b0104773SPascal Brand {
580b0104773SPascal Brand if (operation == TEE_HANDLE_NULL)
581b0104773SPascal Brand TEE_Panic(0);
582bf80076aSCedric Chaumont
583642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET))
584bf80076aSCedric Chaumont TEE_Panic(0);
585bf80076aSCedric Chaumont
586287a6182SJens Wiklander reset_operation_state(operation);
58705304565SCedric Chaumont }
588b0104773SPascal Brand
TEE_SetOperationKey(TEE_OperationHandle operation,TEE_ObjectHandle key)589b0104773SPascal Brand TEE_Result TEE_SetOperationKey(TEE_OperationHandle operation,
590b0104773SPascal Brand TEE_ObjectHandle key)
591b0104773SPascal Brand {
5927583c59eSCedric Chaumont TEE_Result res;
593b0104773SPascal Brand uint32_t key_size = 0;
594b0104773SPascal Brand TEE_ObjectInfo key_info;
595b0104773SPascal Brand
596a57c1e2eSCedric Chaumont if (operation == TEE_HANDLE_NULL) {
597a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
598a57c1e2eSCedric Chaumont goto out;
599a57c1e2eSCedric Chaumont }
600a57c1e2eSCedric Chaumont
601a57c1e2eSCedric Chaumont if (key == TEE_HANDLE_NULL) {
602a57c1e2eSCedric Chaumont /* Operation key cleared */
603a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key1);
6046c4ea258SJens Wiklander operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET;
605287a6182SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_INITIAL)
606287a6182SJens Wiklander reset_operation_state(operation);
6076c4ea258SJens Wiklander return TEE_SUCCESS;
608a57c1e2eSCedric Chaumont }
609a57c1e2eSCedric Chaumont
610a57c1e2eSCedric Chaumont /* No key for digest operation */
611a57c1e2eSCedric Chaumont if (operation->info.operationClass == TEE_OPERATION_DIGEST) {
612a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
613a57c1e2eSCedric Chaumont goto out;
614a57c1e2eSCedric Chaumont }
615a57c1e2eSCedric Chaumont
616a57c1e2eSCedric Chaumont /* Two keys flag not expected (TEE_ALG_AES_XTS excluded) */
617a57c1e2eSCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) !=
618a57c1e2eSCedric Chaumont 0) {
619a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
620a57c1e2eSCedric Chaumont goto out;
621a57c1e2eSCedric Chaumont }
622a57c1e2eSCedric Chaumont
6237583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key, &key_info);
624a57c1e2eSCedric Chaumont /* Key is not a valid handle */
6257583c59eSCedric Chaumont if (res != TEE_SUCCESS)
626a57c1e2eSCedric Chaumont goto out;
6277583c59eSCedric Chaumont
628b0104773SPascal Brand /* Supplied key has to meet required usage */
629b0104773SPascal Brand if ((key_info.objectUsage & operation->info.requiredKeyUsage) !=
630b0104773SPascal Brand operation->info.requiredKeyUsage) {
631a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
632a57c1e2eSCedric Chaumont goto out;
633b0104773SPascal Brand }
634b0104773SPascal Brand
635d372a47cSJens Wiklander if (operation->info.maxKeySize < key_info.objectSize) {
636a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
637a57c1e2eSCedric Chaumont goto out;
638a57c1e2eSCedric Chaumont }
639b0104773SPascal Brand
640d372a47cSJens Wiklander key_size = key_info.objectSize;
641b0104773SPascal Brand
642b0104773SPascal Brand TEE_ResetTransientObject(operation->key1);
643b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET;
644b0104773SPascal Brand
6457583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key1, key);
6467583c59eSCedric Chaumont if (res != TEE_SUCCESS)
647a57c1e2eSCedric Chaumont goto out;
6487583c59eSCedric Chaumont
649b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET;
650b0104773SPascal Brand
651b0104773SPascal Brand operation->info.keySize = key_size;
652b0104773SPascal Brand
653287a6182SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_INITIAL)
654287a6182SJens Wiklander reset_operation_state(operation);
655287a6182SJens Wiklander
6567583c59eSCedric Chaumont out:
657a57c1e2eSCedric Chaumont if (res != TEE_SUCCESS &&
658a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT &&
659a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
660b36311adSJerome Forissier TEE_Panic(res);
661a57c1e2eSCedric Chaumont
662a57c1e2eSCedric Chaumont return res;
663b0104773SPascal Brand }
664b0104773SPascal Brand
__GP11_TEE_SetOperationKey(TEE_OperationHandle operation,TEE_ObjectHandle key)665287a6182SJens Wiklander TEE_Result __GP11_TEE_SetOperationKey(TEE_OperationHandle operation,
666287a6182SJens Wiklander TEE_ObjectHandle key)
667287a6182SJens Wiklander {
668287a6182SJens Wiklander if (operation == TEE_HANDLE_NULL ||
669287a6182SJens Wiklander operation->operationState != TEE_OPERATION_STATE_INITIAL)
670287a6182SJens Wiklander TEE_Panic(0);
671287a6182SJens Wiklander
672287a6182SJens Wiklander return TEE_SetOperationKey(operation, key);
673287a6182SJens Wiklander }
674287a6182SJens Wiklander
set_operation_key2(TEE_OperationHandle operation,TEE_ObjectHandle key1,TEE_ObjectHandle key2)675287a6182SJens Wiklander static TEE_Result set_operation_key2(TEE_OperationHandle operation,
676287a6182SJens Wiklander TEE_ObjectHandle key1,
677287a6182SJens Wiklander TEE_ObjectHandle key2)
678b0104773SPascal Brand {
6797583c59eSCedric Chaumont TEE_Result res;
680b0104773SPascal Brand uint32_t key_size = 0;
681b0104773SPascal Brand TEE_ObjectInfo key_info1;
682b0104773SPascal Brand TEE_ObjectInfo key_info2;
683b0104773SPascal Brand
684a57c1e2eSCedric Chaumont if (operation == TEE_HANDLE_NULL) {
685a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
686a57c1e2eSCedric Chaumont goto out;
687a57c1e2eSCedric Chaumont }
688a57c1e2eSCedric Chaumont
689a57c1e2eSCedric Chaumont /*
690a57c1e2eSCedric Chaumont * Key1/Key2 and/or are not initialized and
691a57c1e2eSCedric Chaumont * Either both keys are NULL or both are not NULL
692a57c1e2eSCedric Chaumont */
6936c4ea258SJens Wiklander if (!key1 && !key2) {
6946c4ea258SJens Wiklander /* Clear the keys */
695a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key1);
696a57c1e2eSCedric Chaumont TEE_ResetTransientObject(operation->key2);
6976c4ea258SJens Wiklander operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET;
698287a6182SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_INITIAL)
699287a6182SJens Wiklander reset_operation_state(operation);
7006c4ea258SJens Wiklander return TEE_SUCCESS;
7016c4ea258SJens Wiklander } else if (!key1 || !key2) {
7026c4ea258SJens Wiklander /* Both keys are obviously not valid. */
703a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
704a57c1e2eSCedric Chaumont goto out;
705a57c1e2eSCedric Chaumont }
706a57c1e2eSCedric Chaumont
707a57c1e2eSCedric Chaumont /* No key for digest operation */
708a57c1e2eSCedric Chaumont if (operation->info.operationClass == TEE_OPERATION_DIGEST) {
709a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
710a57c1e2eSCedric Chaumont goto out;
711a57c1e2eSCedric Chaumont }
712a57c1e2eSCedric Chaumont
7135b385b3fSJerome Forissier /* Two keys flag expected (TEE_ALG_AES_XTS and TEE_ALG_SM2_KEP only) */
714a57c1e2eSCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) ==
715a57c1e2eSCedric Chaumont 0) {
716a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
717a57c1e2eSCedric Chaumont goto out;
718a57c1e2eSCedric Chaumont }
719a57c1e2eSCedric Chaumont
7207583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key1, &key_info1);
721a57c1e2eSCedric Chaumont /* Key1 is not a valid handle */
7227583c59eSCedric Chaumont if (res != TEE_SUCCESS)
723a57c1e2eSCedric Chaumont goto out;
7247583c59eSCedric Chaumont
725b0104773SPascal Brand /* Supplied key has to meet required usage */
726b0104773SPascal Brand if ((key_info1.objectUsage & operation->info.
727b0104773SPascal Brand requiredKeyUsage) != operation->info.requiredKeyUsage) {
728a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
729a57c1e2eSCedric Chaumont goto out;
730b0104773SPascal Brand }
731b0104773SPascal Brand
7327583c59eSCedric Chaumont res = TEE_GetObjectInfo1(key2, &key_info2);
733a57c1e2eSCedric Chaumont /* Key2 is not a valid handle */
7347583c59eSCedric Chaumont if (res != TEE_SUCCESS) {
7357583c59eSCedric Chaumont if (res == TEE_ERROR_CORRUPT_OBJECT)
7367583c59eSCedric Chaumont res = TEE_ERROR_CORRUPT_OBJECT_2;
737a57c1e2eSCedric Chaumont goto out;
7387583c59eSCedric Chaumont }
7397583c59eSCedric Chaumont
740b0104773SPascal Brand /* Supplied key has to meet required usage */
741b0104773SPascal Brand if ((key_info2.objectUsage & operation->info.
742b0104773SPascal Brand requiredKeyUsage) != operation->info.requiredKeyUsage) {
743a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
744a57c1e2eSCedric Chaumont goto out;
745b0104773SPascal Brand }
746b0104773SPascal Brand
747b0104773SPascal Brand /*
7485b385b3fSJerome Forissier * All the multi key algorithm currently supported requires the keys to
7495b385b3fSJerome Forissier * be of equal size.
750b0104773SPascal Brand */
751d372a47cSJens Wiklander if (key_info1.objectSize != key_info2.objectSize) {
752a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
753a57c1e2eSCedric Chaumont goto out;
754b0104773SPascal Brand
755a57c1e2eSCedric Chaumont }
756a57c1e2eSCedric Chaumont
757d372a47cSJens Wiklander if (operation->info.maxKeySize < key_info1.objectSize) {
758a57c1e2eSCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
759a57c1e2eSCedric Chaumont goto out;
760a57c1e2eSCedric Chaumont }
761b0104773SPascal Brand
762b0104773SPascal Brand /*
763b0104773SPascal Brand * Odd that only the size of one key should be reported while
764b0104773SPascal Brand * size of two key are used when allocating the operation.
765b0104773SPascal Brand */
766d372a47cSJens Wiklander key_size = key_info1.objectSize;
767b0104773SPascal Brand
768b0104773SPascal Brand TEE_ResetTransientObject(operation->key1);
769b0104773SPascal Brand TEE_ResetTransientObject(operation->key2);
770b0104773SPascal Brand operation->info.handleState &= ~TEE_HANDLE_FLAG_KEY_SET;
771b0104773SPascal Brand
7727583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key1, key1);
7737583c59eSCedric Chaumont if (res != TEE_SUCCESS)
774a57c1e2eSCedric Chaumont goto out;
7757583c59eSCedric Chaumont res = TEE_CopyObjectAttributes1(operation->key2, key2);
7767583c59eSCedric Chaumont if (res != TEE_SUCCESS) {
7777583c59eSCedric Chaumont if (res == TEE_ERROR_CORRUPT_OBJECT)
7787583c59eSCedric Chaumont res = TEE_ERROR_CORRUPT_OBJECT_2;
779a57c1e2eSCedric Chaumont goto out;
7807583c59eSCedric Chaumont }
7817583c59eSCedric Chaumont
782b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_KEY_SET;
783b0104773SPascal Brand
784b0104773SPascal Brand operation->info.keySize = key_size;
785b0104773SPascal Brand
786287a6182SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_INITIAL)
787287a6182SJens Wiklander reset_operation_state(operation);
7887583c59eSCedric Chaumont out:
789a57c1e2eSCedric Chaumont if (res != TEE_SUCCESS &&
790a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT &&
791a57c1e2eSCedric Chaumont res != TEE_ERROR_CORRUPT_OBJECT_2 &&
792a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE &&
793a57c1e2eSCedric Chaumont res != TEE_ERROR_STORAGE_NOT_AVAILABLE_2)
794b36311adSJerome Forissier TEE_Panic(res);
795a57c1e2eSCedric Chaumont
796a57c1e2eSCedric Chaumont return res;
797b0104773SPascal Brand }
798b0104773SPascal Brand
TEE_SetOperationKey2(TEE_OperationHandle operation,TEE_ObjectHandle key1,TEE_ObjectHandle key2)799287a6182SJens Wiklander TEE_Result TEE_SetOperationKey2(TEE_OperationHandle operation,
800287a6182SJens Wiklander TEE_ObjectHandle key1, TEE_ObjectHandle key2)
801287a6182SJens Wiklander {
802287a6182SJens Wiklander if (operation != TEE_HANDLE_NULL && key1 && key1 == key2)
803287a6182SJens Wiklander return TEE_ERROR_SECURITY;
804287a6182SJens Wiklander
805287a6182SJens Wiklander return set_operation_key2(operation, key1, key2);
806287a6182SJens Wiklander }
807287a6182SJens Wiklander
__GP11_TEE_SetOperationKey2(TEE_OperationHandle operation,TEE_ObjectHandle key1,TEE_ObjectHandle key2)808287a6182SJens Wiklander TEE_Result __GP11_TEE_SetOperationKey2(TEE_OperationHandle operation,
809287a6182SJens Wiklander TEE_ObjectHandle key1,
810287a6182SJens Wiklander TEE_ObjectHandle key2)
811287a6182SJens Wiklander {
812287a6182SJens Wiklander if (operation == TEE_HANDLE_NULL ||
813287a6182SJens Wiklander operation->operationState != TEE_OPERATION_STATE_INITIAL)
814287a6182SJens Wiklander TEE_Panic(0);
815287a6182SJens Wiklander
816287a6182SJens Wiklander return set_operation_key2(operation, key1, key2);
817287a6182SJens Wiklander }
818287a6182SJens Wiklander
TEE_CopyOperation(TEE_OperationHandle dst_op,TEE_OperationHandle src_op)819b0104773SPascal Brand void TEE_CopyOperation(TEE_OperationHandle dst_op, TEE_OperationHandle src_op)
820b0104773SPascal Brand {
821b0104773SPascal Brand TEE_Result res;
822b0104773SPascal Brand
823b0104773SPascal Brand if (dst_op == TEE_HANDLE_NULL || src_op == TEE_HANDLE_NULL)
824b0104773SPascal Brand TEE_Panic(0);
825b0104773SPascal Brand if (dst_op->info.algorithm != src_op->info.algorithm)
826b0104773SPascal Brand TEE_Panic(0);
8278734de30SJens Wiklander if (dst_op->info.mode != src_op->info.mode)
8288734de30SJens Wiklander TEE_Panic(0);
829b0104773SPascal Brand if (src_op->info.operationClass != TEE_OPERATION_DIGEST) {
830b0104773SPascal Brand TEE_ObjectHandle key1 = TEE_HANDLE_NULL;
831b0104773SPascal Brand TEE_ObjectHandle key2 = TEE_HANDLE_NULL;
832b0104773SPascal Brand
833b0104773SPascal Brand if (src_op->info.handleState & TEE_HANDLE_FLAG_KEY_SET) {
834b0104773SPascal Brand key1 = src_op->key1;
835b0104773SPascal Brand key2 = src_op->key2;
836b0104773SPascal Brand }
837b0104773SPascal Brand
838b0104773SPascal Brand if ((src_op->info.handleState &
839b0104773SPascal Brand TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 0) {
840b0104773SPascal Brand TEE_SetOperationKey(dst_op, key1);
841b0104773SPascal Brand } else {
842b0104773SPascal Brand TEE_SetOperationKey2(dst_op, key1, key2);
843b0104773SPascal Brand }
844b0104773SPascal Brand }
845b0104773SPascal Brand dst_op->info.handleState = src_op->info.handleState;
846b0104773SPascal Brand dst_op->info.keySize = src_op->info.keySize;
8478e07702eSJens Wiklander dst_op->info.digestLength = src_op->info.digestLength;
848642a1607SCedric Chaumont dst_op->operationState = src_op->operationState;
849b0104773SPascal Brand
850b0104773SPascal Brand if (dst_op->buffer_two_blocks != src_op->buffer_two_blocks ||
851b0104773SPascal Brand dst_op->block_size != src_op->block_size)
852b0104773SPascal Brand TEE_Panic(0);
853b0104773SPascal Brand
854b0104773SPascal Brand if (dst_op->buffer != NULL) {
85524ea7613SJens Wiklander size_t sz = src_op->block_size;
85624ea7613SJens Wiklander
857b0104773SPascal Brand if (src_op->buffer == NULL)
858b0104773SPascal Brand TEE_Panic(0);
859b0104773SPascal Brand
86024ea7613SJens Wiklander if (src_op->buffer_two_blocks)
86124ea7613SJens Wiklander sz *= 2;
86224ea7613SJens Wiklander memcpy(dst_op->buffer, src_op->buffer, sz);
863b0104773SPascal Brand dst_op->buffer_offs = src_op->buffer_offs;
864b0104773SPascal Brand } else if (src_op->buffer != NULL) {
865b0104773SPascal Brand TEE_Panic(0);
866b0104773SPascal Brand }
867b0104773SPascal Brand
8682c028fdeSJerome Forissier res = _utee_cryp_state_copy(dst_op->state, src_op->state);
869b0104773SPascal Brand if (res != TEE_SUCCESS)
870b0104773SPascal Brand TEE_Panic(res);
871b0104773SPascal Brand }
872b0104773SPascal Brand
873b0104773SPascal Brand /* Cryptographic Operations API - Message Digest Functions */
874b0104773SPascal Brand
init_hash_operation(TEE_OperationHandle operation,const void * IV,uint32_t IVLen)8758f07fe6fSJerome Forissier static void init_hash_operation(TEE_OperationHandle operation, const void *IV,
8766d15db08SJerome Forissier uint32_t IVLen)
8776d15db08SJerome Forissier {
8786d15db08SJerome Forissier TEE_Result res;
8796d15db08SJerome Forissier
8806d15db08SJerome Forissier /*
8816d15db08SJerome Forissier * Note : IV and IVLen are never used in current implementation
8826d15db08SJerome Forissier * This is why coherent values of IV and IVLen are not checked
8836d15db08SJerome Forissier */
8842c028fdeSJerome Forissier res = _utee_hash_init(operation->state, IV, IVLen);
8856d15db08SJerome Forissier if (res != TEE_SUCCESS)
8866d15db08SJerome Forissier TEE_Panic(res);
8876d15db08SJerome Forissier operation->buffer_offs = 0;
8886d15db08SJerome Forissier operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
8896d15db08SJerome Forissier }
8906d15db08SJerome Forissier
TEE_DigestUpdate(TEE_OperationHandle operation,const void * chunk,size_t chunkSize)891b0104773SPascal Brand void TEE_DigestUpdate(TEE_OperationHandle operation,
892185bf58cSJens Wiklander const void *chunk, size_t chunkSize)
893b0104773SPascal Brand {
89473d6c3baSJoakim Bech TEE_Result res = TEE_ERROR_GENERIC;
895b0104773SPascal Brand
89673d6c3baSJoakim Bech if (operation == TEE_HANDLE_NULL ||
89773d6c3baSJoakim Bech operation->info.operationClass != TEE_OPERATION_DIGEST)
898b0104773SPascal Brand TEE_Panic(0);
89973d6c3baSJoakim Bech
900642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE;
901642a1607SCedric Chaumont
9022c028fdeSJerome Forissier res = _utee_hash_update(operation->state, chunk, chunkSize);
903b0104773SPascal Brand if (res != TEE_SUCCESS)
904b0104773SPascal Brand TEE_Panic(res);
905b0104773SPascal Brand }
906b0104773SPascal Brand
__GP11_TEE_DigestUpdate(TEE_OperationHandle operation,const void * chunk,uint32_t chunkSize)907185bf58cSJens Wiklander void __GP11_TEE_DigestUpdate(TEE_OperationHandle operation,
908185bf58cSJens Wiklander const void *chunk, uint32_t chunkSize)
909185bf58cSJens Wiklander {
910185bf58cSJens Wiklander return TEE_DigestUpdate(operation, chunk, chunkSize);
911185bf58cSJens Wiklander }
912185bf58cSJens Wiklander
TEE_DigestDoFinal(TEE_OperationHandle operation,const void * chunk,size_t chunkLen,void * hash,size_t * hashLen)9138f07fe6fSJerome Forissier TEE_Result TEE_DigestDoFinal(TEE_OperationHandle operation, const void *chunk,
914185bf58cSJens Wiklander size_t chunkLen, void *hash, size_t *hashLen)
915b0104773SPascal Brand {
91624ea7613SJens Wiklander TEE_Result res = TEE_SUCCESS;
91724ea7613SJens Wiklander uint64_t hl = 0;
91824ea7613SJens Wiklander size_t len = 0;
91987c2f6b6SCedric Chaumont
92087c2f6b6SCedric Chaumont if ((operation == TEE_HANDLE_NULL) ||
92187c2f6b6SCedric Chaumont (!chunk && chunkLen) ||
92287c2f6b6SCedric Chaumont (operation->info.operationClass != TEE_OPERATION_DIGEST)) {
92387c2f6b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
92487c2f6b6SCedric Chaumont goto out;
92587c2f6b6SCedric Chaumont }
92624ea7613SJens Wiklander if (operation->operationState == TEE_OPERATION_STATE_EXTRACTING &&
92724ea7613SJens Wiklander chunkLen) {
92824ea7613SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
92924ea7613SJens Wiklander goto out;
93024ea7613SJens Wiklander }
9316915bbbbSJens Wiklander __utee_check_inout_annotation(hashLen, sizeof(*hashLen));
93287c2f6b6SCedric Chaumont
93324ea7613SJens Wiklander if (operation->operationState == TEE_OPERATION_STATE_EXTRACTING &&
93424ea7613SJens Wiklander operation->buffer) {
93524ea7613SJens Wiklander /*
93624ea7613SJens Wiklander * This is not an Extendable-Output Function and we have
93724ea7613SJens Wiklander * already started extracting
93824ea7613SJens Wiklander */
93924ea7613SJens Wiklander len = MIN(operation->block_size - operation->buffer_offs,
94024ea7613SJens Wiklander *hashLen);
94124ea7613SJens Wiklander memcpy(hash, operation->buffer + operation->buffer_offs, len);
94224ea7613SJens Wiklander *hashLen = len;
94324ea7613SJens Wiklander } else {
944e86f1266SJens Wiklander hl = *hashLen;
94524ea7613SJens Wiklander res = _utee_hash_final(operation->state, chunk, chunkLen, hash,
94624ea7613SJens Wiklander &hl);
947e86f1266SJens Wiklander *hashLen = hl;
94824ea7613SJens Wiklander if (res)
9496d15db08SJerome Forissier goto out;
95024ea7613SJens Wiklander }
9516d15db08SJerome Forissier
9526d15db08SJerome Forissier /* Reset operation state */
9536d15db08SJerome Forissier init_hash_operation(operation, NULL, 0);
95487c2f6b6SCedric Chaumont
955642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL;
956642a1607SCedric Chaumont
95787c2f6b6SCedric Chaumont out:
95887c2f6b6SCedric Chaumont if (res != TEE_SUCCESS &&
95987c2f6b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER)
960b36311adSJerome Forissier TEE_Panic(res);
96173d6c3baSJoakim Bech
96287c2f6b6SCedric Chaumont return res;
963b0104773SPascal Brand }
964b0104773SPascal Brand
__GP11_TEE_DigestDoFinal(TEE_OperationHandle operation,const void * chunk,uint32_t chunkLen,void * hash,uint32_t * hashLen)965185bf58cSJens Wiklander TEE_Result __GP11_TEE_DigestDoFinal(TEE_OperationHandle operation,
966185bf58cSJens Wiklander const void *chunk, uint32_t chunkLen,
967185bf58cSJens Wiklander void *hash, uint32_t *hashLen)
968185bf58cSJens Wiklander {
969185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS;
970185bf58cSJens Wiklander size_t l = 0;
971185bf58cSJens Wiklander
972185bf58cSJens Wiklander __utee_check_inout_annotation(hashLen, sizeof(*hashLen));
973185bf58cSJens Wiklander l = *hashLen;
974185bf58cSJens Wiklander res = TEE_DigestDoFinal(operation, chunk, chunkLen, hash, &l);
975185bf58cSJens Wiklander *hashLen = l;
976185bf58cSJens Wiklander return res;
977185bf58cSJens Wiklander }
978185bf58cSJens Wiklander
TEE_DigestExtract(TEE_OperationHandle operation,void * hash,size_t * hashLen)97924ea7613SJens Wiklander TEE_Result TEE_DigestExtract(TEE_OperationHandle operation, void *hash,
98024ea7613SJens Wiklander size_t *hashLen)
98124ea7613SJens Wiklander {
98224ea7613SJens Wiklander TEE_Result res = TEE_SUCCESS;
98324ea7613SJens Wiklander uint64_t hl = 0;
98424ea7613SJens Wiklander size_t len = 0;
98524ea7613SJens Wiklander
98624ea7613SJens Wiklander if (operation == TEE_HANDLE_NULL ||
98724ea7613SJens Wiklander operation->info.operationClass != TEE_OPERATION_DIGEST)
98824ea7613SJens Wiklander TEE_Panic(0);
98924ea7613SJens Wiklander __utee_check_inout_annotation(hashLen, sizeof(*hashLen));
99024ea7613SJens Wiklander
99124ea7613SJens Wiklander if (!operation->buffer) {
99224ea7613SJens Wiklander /* This is an Extendable-Output Function */
99324ea7613SJens Wiklander operation->info.handleState |= TEE_HANDLE_FLAG_EXTRACTING;
99424ea7613SJens Wiklander operation->operationState = TEE_OPERATION_STATE_EXTRACTING;
99524ea7613SJens Wiklander hl = *hashLen;
99624ea7613SJens Wiklander res = _utee_hash_final(operation->state, NULL, 0, hash, &hl);
99724ea7613SJens Wiklander if (res)
99824ea7613SJens Wiklander TEE_Panic(0);
99924ea7613SJens Wiklander *hashLen = hl;
100024ea7613SJens Wiklander
100124ea7613SJens Wiklander return TEE_SUCCESS;
100224ea7613SJens Wiklander }
100324ea7613SJens Wiklander
100424ea7613SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_EXTRACTING) {
100524ea7613SJens Wiklander hl = operation->block_size;
100624ea7613SJens Wiklander res = _utee_hash_final(operation->state, NULL, 0,
100724ea7613SJens Wiklander operation->buffer, &hl);
100824ea7613SJens Wiklander if (res)
100924ea7613SJens Wiklander TEE_Panic(0);
101024ea7613SJens Wiklander if (hl != operation->block_size)
101124ea7613SJens Wiklander TEE_Panic(0);
101224ea7613SJens Wiklander assert(!operation->buffer_offs);
101324ea7613SJens Wiklander operation->info.handleState |= TEE_HANDLE_FLAG_EXTRACTING;
101424ea7613SJens Wiklander operation->operationState = TEE_OPERATION_STATE_EXTRACTING;
101524ea7613SJens Wiklander }
101624ea7613SJens Wiklander
101724ea7613SJens Wiklander len = MIN(operation->block_size - operation->buffer_offs, *hashLen);
101824ea7613SJens Wiklander memcpy(hash, operation->buffer + operation->buffer_offs, len);
101924ea7613SJens Wiklander *hashLen = len;
102024ea7613SJens Wiklander operation->buffer_offs += len;
102124ea7613SJens Wiklander
102224ea7613SJens Wiklander return TEE_SUCCESS;
102324ea7613SJens Wiklander }
102424ea7613SJens Wiklander
1025b0104773SPascal Brand /* Cryptographic Operations API - Symmetric Cipher Functions */
1026b0104773SPascal Brand
TEE_CipherInit(TEE_OperationHandle operation,const void * IV,size_t IVLen)10278f07fe6fSJerome Forissier void TEE_CipherInit(TEE_OperationHandle operation, const void *IV,
1028185bf58cSJens Wiklander size_t IVLen)
1029b0104773SPascal Brand {
1030b0104773SPascal Brand TEE_Result res;
1031b0104773SPascal Brand
1032b0104773SPascal Brand if (operation == TEE_HANDLE_NULL)
1033b0104773SPascal Brand TEE_Panic(0);
1034642a1607SCedric Chaumont
1035b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_CIPHER)
1036b0104773SPascal Brand TEE_Panic(0);
1037642a1607SCedric Chaumont
1038642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) ||
1039642a1607SCedric Chaumont !(operation->key1))
1040642a1607SCedric Chaumont TEE_Panic(0);
1041642a1607SCedric Chaumont
1042642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL)
1043642a1607SCedric Chaumont TEE_ResetOperation(operation);
1044642a1607SCedric Chaumont
1045ad7aa2a5SSadiq Hussain if (IV && IVLen) {
1046ad7aa2a5SSadiq Hussain if (operation->info.algorithm == TEE_ALG_AES_ECB_NOPAD ||
1047ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_DES_ECB_NOPAD ||
1048ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_DES3_ECB_NOPAD ||
1049ad7aa2a5SSadiq Hussain operation->info.algorithm == TEE_ALG_SM4_ECB_NOPAD)
1050ad7aa2a5SSadiq Hussain TEE_Panic(0);
1051ad7aa2a5SSadiq Hussain }
1052ad7aa2a5SSadiq Hussain
1053642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE;
1054642a1607SCedric Chaumont
10552c028fdeSJerome Forissier res = _utee_cipher_init(operation->state, IV, IVLen);
1056b0104773SPascal Brand if (res != TEE_SUCCESS)
1057b0104773SPascal Brand TEE_Panic(res);
1058642a1607SCedric Chaumont
1059b0104773SPascal Brand operation->buffer_offs = 0;
1060b0104773SPascal Brand operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
1061b0104773SPascal Brand }
1062b0104773SPascal Brand
__GP11_TEE_CipherInit(TEE_OperationHandle operation,const void * IV,uint32_t IVLen)1063185bf58cSJens Wiklander void __GP11_TEE_CipherInit(TEE_OperationHandle operation, const void *IV,
1064185bf58cSJens Wiklander uint32_t IVLen)
1065185bf58cSJens Wiklander {
1066185bf58cSJens Wiklander return TEE_CipherInit(operation, IV, IVLen);
1067185bf58cSJens Wiklander }
1068185bf58cSJens Wiklander
tee_buffer_update(TEE_OperationHandle op,TEE_Result (* update_func)(unsigned long state,const void * src,size_t slen,void * dst,uint64_t * dlen),const void * src_data,size_t src_len,void * dest_data,uint64_t * dest_len)1069b0104773SPascal Brand static TEE_Result tee_buffer_update(
1070b0104773SPascal Brand TEE_OperationHandle op,
1071e86f1266SJens Wiklander TEE_Result(*update_func)(unsigned long state, const void *src,
1072e86f1266SJens Wiklander size_t slen, void *dst, uint64_t *dlen),
1073b0104773SPascal Brand const void *src_data, size_t src_len,
1074e86f1266SJens Wiklander void *dest_data, uint64_t *dest_len)
1075b0104773SPascal Brand {
1076b0104773SPascal Brand TEE_Result res;
1077b0104773SPascal Brand const uint8_t *src = src_data;
1078b0104773SPascal Brand size_t slen = src_len;
1079b0104773SPascal Brand uint8_t *dst = dest_data;
1080b0104773SPascal Brand size_t dlen = *dest_len;
1081b0104773SPascal Brand size_t acc_dlen = 0;
1082e86f1266SJens Wiklander uint64_t tmp_dlen;
1083b0104773SPascal Brand size_t l;
1084b0104773SPascal Brand size_t buffer_size;
1085d3588802SPascal Brand size_t buffer_left;
1086b0104773SPascal Brand
1087090268f5SJens Wiklander if (!src) {
1088090268f5SJens Wiklander if (slen)
1089090268f5SJens Wiklander TEE_Panic(0);
1090090268f5SJens Wiklander goto out;
1091090268f5SJens Wiklander }
1092090268f5SJens Wiklander
1093d3588802SPascal Brand if (op->buffer_two_blocks) {
1094b0104773SPascal Brand buffer_size = op->block_size * 2;
1095d3588802SPascal Brand buffer_left = 1;
1096d3588802SPascal Brand } else {
1097b0104773SPascal Brand buffer_size = op->block_size;
1098d3588802SPascal Brand buffer_left = 0;
1099d3588802SPascal Brand }
1100b0104773SPascal Brand
1101b0104773SPascal Brand if (op->buffer_offs > 0) {
1102b0104773SPascal Brand /* Fill up complete block */
1103b0104773SPascal Brand if (op->buffer_offs < op->block_size)
1104b0104773SPascal Brand l = MIN(slen, op->block_size - op->buffer_offs);
1105b0104773SPascal Brand else
1106b0104773SPascal Brand l = MIN(slen, buffer_size - op->buffer_offs);
1107b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, l);
1108b0104773SPascal Brand op->buffer_offs += l;
1109b0104773SPascal Brand src += l;
1110b0104773SPascal Brand slen -= l;
1111b0104773SPascal Brand if ((op->buffer_offs % op->block_size) != 0)
1112b0104773SPascal Brand goto out; /* Nothing left to do */
1113b0104773SPascal Brand }
1114b0104773SPascal Brand
1115b0104773SPascal Brand /* If we can feed from buffer */
1116d3588802SPascal Brand if ((op->buffer_offs > 0) &&
1117d3588802SPascal Brand ((op->buffer_offs + slen) >= (buffer_size + buffer_left))) {
1118*76d6685eSEtienne Carriere l = ROUNDUP2(op->buffer_offs + slen - buffer_size,
1119b0104773SPascal Brand op->block_size);
1120b0104773SPascal Brand l = MIN(op->buffer_offs, l);
1121aeb530a5SSami Tolvanen /*
1122aeb530a5SSami Tolvanen * If we're buffering only a single block, process it
1123aeb530a5SSami Tolvanen * immediately.
1124aeb530a5SSami Tolvanen */
1125aeb530a5SSami Tolvanen if (!op->buffer_two_blocks)
1126aeb530a5SSami Tolvanen l = op->block_size;
1127b0104773SPascal Brand tmp_dlen = dlen;
1128b0104773SPascal Brand res = update_func(op->state, op->buffer, l, dst, &tmp_dlen);
1129b0104773SPascal Brand if (res != TEE_SUCCESS)
1130b0104773SPascal Brand TEE_Panic(res);
1131b0104773SPascal Brand dst += tmp_dlen;
1132b0104773SPascal Brand dlen -= tmp_dlen;
1133b0104773SPascal Brand acc_dlen += tmp_dlen;
1134b0104773SPascal Brand op->buffer_offs -= l;
1135b0104773SPascal Brand if (op->buffer_offs > 0) {
1136b0104773SPascal Brand /*
1137b0104773SPascal Brand * Slen is small enough to be contained in rest buffer.
1138b0104773SPascal Brand */
1139b0104773SPascal Brand memcpy(op->buffer, op->buffer + l, buffer_size - l);
1140b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, slen);
1141b0104773SPascal Brand op->buffer_offs += slen;
1142b0104773SPascal Brand goto out; /* Nothing left to do */
1143b0104773SPascal Brand }
1144b0104773SPascal Brand }
1145b0104773SPascal Brand
1146d3588802SPascal Brand if (slen >= (buffer_size + buffer_left)) {
1147b0104773SPascal Brand /* Buffer is empty, feed as much as possible from src */
11485957a0bdSJens Wiklander if (op->buffer_two_blocks)
1149*76d6685eSEtienne Carriere l = ROUNDUP2(slen - buffer_size, op->block_size);
1150bf7a587fSJerome Forissier else
1151*76d6685eSEtienne Carriere l = ROUNDUP2(slen - buffer_size + 1, op->block_size);
1152b0104773SPascal Brand
1153b0104773SPascal Brand tmp_dlen = dlen;
1154b0104773SPascal Brand res = update_func(op->state, src, l, dst, &tmp_dlen);
1155b0104773SPascal Brand if (res != TEE_SUCCESS)
1156b0104773SPascal Brand TEE_Panic(res);
1157b0104773SPascal Brand src += l;
1158b0104773SPascal Brand slen -= l;
1159b0104773SPascal Brand dst += tmp_dlen;
1160b0104773SPascal Brand dlen -= tmp_dlen;
1161b0104773SPascal Brand acc_dlen += tmp_dlen;
1162b0104773SPascal Brand }
1163b0104773SPascal Brand
1164b0104773SPascal Brand /* Slen is small enough to be contained in buffer. */
1165b0104773SPascal Brand memcpy(op->buffer + op->buffer_offs, src, slen);
1166b0104773SPascal Brand op->buffer_offs += slen;
1167b0104773SPascal Brand
1168b0104773SPascal Brand out:
1169b0104773SPascal Brand *dest_len = acc_dlen;
1170b0104773SPascal Brand return TEE_SUCCESS;
1171b0104773SPascal Brand }
1172b0104773SPascal Brand
TEE_CipherUpdate(TEE_OperationHandle operation,const void * srcData,size_t srcLen,void * destData,size_t * destLen)11738f07fe6fSJerome Forissier TEE_Result TEE_CipherUpdate(TEE_OperationHandle operation, const void *srcData,
1174185bf58cSJens Wiklander size_t srcLen, void *destData, size_t *destLen)
1175b0104773SPascal Brand {
1176dea1f2b6SCedric Chaumont TEE_Result res;
1177b0104773SPascal Brand size_t req_dlen;
1178e86f1266SJens Wiklander uint64_t dl;
1179b0104773SPascal Brand
11806915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) {
1181dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1182dea1f2b6SCedric Chaumont goto out;
1183dea1f2b6SCedric Chaumont }
11846915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen));
1185dea1f2b6SCedric Chaumont
1186642a1607SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_CIPHER) {
1187dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1188dea1f2b6SCedric Chaumont goto out;
1189dea1f2b6SCedric Chaumont }
1190dea1f2b6SCedric Chaumont
1191642a1607SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
1192642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1193642a1607SCedric Chaumont goto out;
1194642a1607SCedric Chaumont }
1195642a1607SCedric Chaumont
1196642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) {
1197dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1198dea1f2b6SCedric Chaumont goto out;
1199dea1f2b6SCedric Chaumont }
1200b0104773SPascal Brand
1201e32c5ddfSJerome Forissier if (!srcData && !srcLen) {
1202090268f5SJens Wiklander *destLen = 0;
1203e32c5ddfSJerome Forissier res = TEE_SUCCESS;
1204e32c5ddfSJerome Forissier goto out;
1205e32c5ddfSJerome Forissier }
1206e32c5ddfSJerome Forissier
1207b0104773SPascal Brand /* Calculate required dlen */
120857aabac5SBogdan Liulko if (operation->block_size > 1) {
120957aabac5SBogdan Liulko req_dlen = ((operation->buffer_offs + srcLen) /
121057aabac5SBogdan Liulko operation->block_size) * operation->block_size;
121157aabac5SBogdan Liulko } else {
121257aabac5SBogdan Liulko req_dlen = srcLen;
121357aabac5SBogdan Liulko }
1214642a1607SCedric Chaumont if (operation->buffer_two_blocks) {
12155957a0bdSJens Wiklander if (operation->buffer_offs + srcLen >
12165957a0bdSJens Wiklander operation->block_size * 2) {
12175957a0bdSJens Wiklander req_dlen = operation->buffer_offs + srcLen -
12185957a0bdSJens Wiklander operation->block_size * 2;
1219*76d6685eSEtienne Carriere req_dlen = ROUNDUP2(req_dlen, operation->block_size);
12205957a0bdSJens Wiklander } else {
1221b0104773SPascal Brand req_dlen = 0;
1222b0104773SPascal Brand }
12235957a0bdSJens Wiklander }
1224b0104773SPascal Brand /*
1225b0104773SPascal Brand * Check that required destLen is big enough before starting to feed
1226b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we
1227b0104773SPascal Brand * can't restore sync with this API.
1228b0104773SPascal Brand */
1229b0104773SPascal Brand if (*destLen < req_dlen) {
1230b0104773SPascal Brand *destLen = req_dlen;
1231dea1f2b6SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER;
1232dea1f2b6SCedric Chaumont goto out;
1233b0104773SPascal Brand }
1234b0104773SPascal Brand
1235e86f1266SJens Wiklander dl = *destLen;
123657aabac5SBogdan Liulko if (operation->block_size > 1) {
12372c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_cipher_update, srcData,
123857aabac5SBogdan Liulko srcLen, destData, &dl);
123957aabac5SBogdan Liulko } else {
124057aabac5SBogdan Liulko if (srcLen > 0) {
12412c028fdeSJerome Forissier res = _utee_cipher_update(operation->state, srcData,
124257aabac5SBogdan Liulko srcLen, destData, &dl);
124357aabac5SBogdan Liulko } else {
124457aabac5SBogdan Liulko res = TEE_SUCCESS;
124557aabac5SBogdan Liulko dl = 0;
124657aabac5SBogdan Liulko }
124757aabac5SBogdan Liulko }
1248e86f1266SJens Wiklander *destLen = dl;
1249b0104773SPascal Brand
1250dea1f2b6SCedric Chaumont out:
1251dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS &&
1252dea1f2b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER)
1253b36311adSJerome Forissier TEE_Panic(res);
1254dea1f2b6SCedric Chaumont
1255dea1f2b6SCedric Chaumont return res;
1256b0104773SPascal Brand }
1257b0104773SPascal Brand
__GP11_TEE_CipherUpdate(TEE_OperationHandle operation,const void * srcData,uint32_t srcLen,void * destData,uint32_t * destLen)1258185bf58cSJens Wiklander TEE_Result __GP11_TEE_CipherUpdate(TEE_OperationHandle operation,
12598f07fe6fSJerome Forissier const void *srcData, uint32_t srcLen,
12608f07fe6fSJerome Forissier void *destData, uint32_t *destLen)
1261b0104773SPascal Brand {
12626915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS;
1263185bf58cSJens Wiklander size_t dl = 0;
1264185bf58cSJens Wiklander
1265185bf58cSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen));
1266185bf58cSJens Wiklander dl = *destLen;
1267185bf58cSJens Wiklander res = TEE_CipherUpdate(operation, srcData, srcLen, destData, &dl);
1268185bf58cSJens Wiklander *destLen = dl;
1269185bf58cSJens Wiklander return res;
1270185bf58cSJens Wiklander }
1271185bf58cSJens Wiklander
TEE_CipherDoFinal(TEE_OperationHandle operation,const void * srcData,size_t srcLen,void * destData,size_t * destLen)1272185bf58cSJens Wiklander TEE_Result TEE_CipherDoFinal(TEE_OperationHandle operation,
1273185bf58cSJens Wiklander const void *srcData, size_t srcLen,
1274185bf58cSJens Wiklander void *destData, size_t *destLen)
1275185bf58cSJens Wiklander {
1276185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS;
1277b0104773SPascal Brand uint8_t *dst = destData;
1278b0104773SPascal Brand size_t acc_dlen = 0;
12796915bbbbSJens Wiklander uint64_t tmp_dlen = 0;
12806915bbbbSJens Wiklander size_t req_dlen = 0;
1281b0104773SPascal Brand
12826915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) {
1283dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1284dea1f2b6SCedric Chaumont goto out;
1285dea1f2b6SCedric Chaumont }
12866915bbbbSJens Wiklander if (destLen)
12876915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen));
1288dea1f2b6SCedric Chaumont
1289642a1607SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_CIPHER) {
1290dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1291dea1f2b6SCedric Chaumont goto out;
1292dea1f2b6SCedric Chaumont }
1293dea1f2b6SCedric Chaumont
1294642a1607SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
1295642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1296642a1607SCedric Chaumont goto out;
1297642a1607SCedric Chaumont }
1298642a1607SCedric Chaumont
1299642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) {
1300dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1301dea1f2b6SCedric Chaumont goto out;
1302dea1f2b6SCedric Chaumont }
1303b0104773SPascal Brand
1304b0104773SPascal Brand /*
1305b0104773SPascal Brand * Check that the final block doesn't require padding for those
1306b0104773SPascal Brand * algorithms that requires client to supply padding.
1307b0104773SPascal Brand */
1308642a1607SCedric Chaumont if (operation->info.algorithm == TEE_ALG_AES_ECB_NOPAD ||
1309642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_AES_CBC_NOPAD ||
1310642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES_ECB_NOPAD ||
1311642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES_CBC_NOPAD ||
1312642a1607SCedric Chaumont operation->info.algorithm == TEE_ALG_DES3_ECB_NOPAD ||
1313ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_DES3_CBC_NOPAD ||
1314ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_SM4_ECB_NOPAD ||
1315ade6f848SJerome Forissier operation->info.algorithm == TEE_ALG_SM4_CBC_NOPAD) {
1316642a1607SCedric Chaumont if (((operation->buffer_offs + srcLen) % operation->block_size)
1317642a1607SCedric Chaumont != 0) {
1318dea1f2b6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1319dea1f2b6SCedric Chaumont goto out;
1320dea1f2b6SCedric Chaumont }
1321b0104773SPascal Brand }
1322b0104773SPascal Brand
1323b0104773SPascal Brand /*
1324b0104773SPascal Brand * Check that required destLen is big enough before starting to feed
1325b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we
1326b0104773SPascal Brand * can't restore sync with this API.
1327b0104773SPascal Brand */
132857aabac5SBogdan Liulko if (operation->block_size > 1) {
1329642a1607SCedric Chaumont req_dlen = operation->buffer_offs + srcLen;
133057aabac5SBogdan Liulko } else {
133157aabac5SBogdan Liulko req_dlen = srcLen;
133257aabac5SBogdan Liulko }
13336915bbbbSJens Wiklander if (destLen)
13346915bbbbSJens Wiklander tmp_dlen = *destLen;
13356915bbbbSJens Wiklander if (tmp_dlen < req_dlen) {
13366915bbbbSJens Wiklander if (destLen)
1337b0104773SPascal Brand *destLen = req_dlen;
1338dea1f2b6SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER;
1339dea1f2b6SCedric Chaumont goto out;
1340b0104773SPascal Brand }
1341b0104773SPascal Brand
134257aabac5SBogdan Liulko if (operation->block_size > 1) {
1343dea9063eSJens Wiklander if (srcLen) {
13442c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_cipher_update,
1345dea9063eSJens Wiklander srcData, srcLen, dst,
1346dea9063eSJens Wiklander &tmp_dlen);
1347dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS)
1348dea1f2b6SCedric Chaumont goto out;
1349dea1f2b6SCedric Chaumont
1350b0104773SPascal Brand dst += tmp_dlen;
1351b0104773SPascal Brand acc_dlen += tmp_dlen;
1352b0104773SPascal Brand
1353b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen;
1354dea9063eSJens Wiklander }
13552c028fdeSJerome Forissier res = _utee_cipher_final(operation->state, operation->buffer,
13562c028fdeSJerome Forissier operation->buffer_offs, dst,
13572c028fdeSJerome Forissier &tmp_dlen);
135857aabac5SBogdan Liulko } else {
13592c028fdeSJerome Forissier res = _utee_cipher_final(operation->state, srcData, srcLen, dst,
13602c028fdeSJerome Forissier &tmp_dlen);
136157aabac5SBogdan Liulko }
1362b0104773SPascal Brand if (res != TEE_SUCCESS)
1363dea1f2b6SCedric Chaumont goto out;
1364dea1f2b6SCedric Chaumont
1365b0104773SPascal Brand acc_dlen += tmp_dlen;
13666915bbbbSJens Wiklander if (destLen)
1367b0104773SPascal Brand *destLen = acc_dlen;
1368dea1f2b6SCedric Chaumont
1369642a1607SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
1370642a1607SCedric Chaumont
1371642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL;
1372642a1607SCedric Chaumont
1373dea1f2b6SCedric Chaumont out:
1374dea1f2b6SCedric Chaumont if (res != TEE_SUCCESS &&
1375dea1f2b6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER)
1376b36311adSJerome Forissier TEE_Panic(res);
1377dea1f2b6SCedric Chaumont
1378dea1f2b6SCedric Chaumont return res;
1379b0104773SPascal Brand }
1380b0104773SPascal Brand
__GP11_TEE_CipherDoFinal(TEE_OperationHandle operation,const void * srcData,uint32_t srcLen,void * destData,uint32_t * destLen)1381185bf58cSJens Wiklander TEE_Result __GP11_TEE_CipherDoFinal(TEE_OperationHandle operation,
1382185bf58cSJens Wiklander const void *srcData, uint32_t srcLen,
1383185bf58cSJens Wiklander void *destData, uint32_t *destLen)
1384185bf58cSJens Wiklander {
1385185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS;
1386185bf58cSJens Wiklander size_t dl = 0;
1387185bf58cSJens Wiklander
1388185bf58cSJens Wiklander if (destLen) {
1389185bf58cSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen));
1390185bf58cSJens Wiklander dl = *destLen;
1391185bf58cSJens Wiklander }
1392185bf58cSJens Wiklander res = TEE_CipherDoFinal(operation, srcData, srcLen, destData, &dl);
1393185bf58cSJens Wiklander if (destLen)
1394185bf58cSJens Wiklander *destLen = dl;
1395185bf58cSJens Wiklander return res;
1396185bf58cSJens Wiklander }
1397185bf58cSJens Wiklander
1398b0104773SPascal Brand /* Cryptographic Operations API - MAC Functions */
1399b0104773SPascal Brand
TEE_MACInit(TEE_OperationHandle operation,const void * IV,size_t IVLen)1400185bf58cSJens Wiklander void TEE_MACInit(TEE_OperationHandle operation, const void *IV, size_t IVLen)
1401b0104773SPascal Brand {
1402b0104773SPascal Brand if (operation == TEE_HANDLE_NULL)
1403b0104773SPascal Brand TEE_Panic(0);
1404642a1607SCedric Chaumont
1405b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_MAC)
1406b0104773SPascal Brand TEE_Panic(0);
1407642a1607SCedric Chaumont
1408642a1607SCedric Chaumont if (!(operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) ||
1409642a1607SCedric Chaumont !(operation->key1))
1410642a1607SCedric Chaumont TEE_Panic(0);
1411642a1607SCedric Chaumont
1412642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL)
1413642a1607SCedric Chaumont TEE_ResetOperation(operation);
1414642a1607SCedric Chaumont
1415642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE;
1416642a1607SCedric Chaumont
14176d15db08SJerome Forissier init_hash_operation(operation, IV, IVLen);
1418b0104773SPascal Brand }
1419b0104773SPascal Brand
__GP11_TEE_MACInit(TEE_OperationHandle operation,const void * IV,uint32_t IVLen)1420185bf58cSJens Wiklander void __GP11_TEE_MACInit(TEE_OperationHandle operation, const void *IV,
1421185bf58cSJens Wiklander uint32_t IVLen)
1422185bf58cSJens Wiklander {
1423185bf58cSJens Wiklander return TEE_MACInit(operation, IV, IVLen);
1424185bf58cSJens Wiklander }
1425185bf58cSJens Wiklander
TEE_MACUpdate(TEE_OperationHandle operation,const void * chunk,size_t chunkSize)14268f07fe6fSJerome Forissier void TEE_MACUpdate(TEE_OperationHandle operation, const void *chunk,
1427185bf58cSJens Wiklander size_t chunkSize)
1428b0104773SPascal Brand {
1429b0104773SPascal Brand TEE_Result res;
1430b0104773SPascal Brand
143128e0efc6SCedric Chaumont if (operation == TEE_HANDLE_NULL || (chunk == NULL && chunkSize != 0))
1432b0104773SPascal Brand TEE_Panic(0);
1433642a1607SCedric Chaumont
143428e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC)
1435b0104773SPascal Brand TEE_Panic(0);
1436642a1607SCedric Chaumont
143728e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0)
1438b0104773SPascal Brand TEE_Panic(0);
1439b0104773SPascal Brand
1440642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE)
1441642a1607SCedric Chaumont TEE_Panic(0);
1442642a1607SCedric Chaumont
14432c028fdeSJerome Forissier res = _utee_hash_update(operation->state, chunk, chunkSize);
1444b0104773SPascal Brand if (res != TEE_SUCCESS)
1445b0104773SPascal Brand TEE_Panic(res);
1446b0104773SPascal Brand }
1447b0104773SPascal Brand
__GP11_TEE_MACUpdate(TEE_OperationHandle operation,const void * chunk,uint32_t chunkSize)1448185bf58cSJens Wiklander void __GP11_TEE_MACUpdate(TEE_OperationHandle operation, const void *chunk,
1449185bf58cSJens Wiklander uint32_t chunkSize)
1450185bf58cSJens Wiklander {
1451185bf58cSJens Wiklander return TEE_MACUpdate(operation, chunk, chunkSize);
1452185bf58cSJens Wiklander }
1453185bf58cSJens Wiklander
TEE_MACComputeFinal(TEE_OperationHandle operation,const void * message,size_t messageLen,void * mac,size_t * macLen)145428e0efc6SCedric Chaumont TEE_Result TEE_MACComputeFinal(TEE_OperationHandle operation,
1455185bf58cSJens Wiklander const void *message, size_t messageLen,
1456185bf58cSJens Wiklander void *mac, size_t *macLen)
1457b0104773SPascal Brand {
1458b0104773SPascal Brand TEE_Result res;
1459e86f1266SJens Wiklander uint64_t ml;
1460b0104773SPascal Brand
14616915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!message && messageLen)) {
146228e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
146328e0efc6SCedric Chaumont goto out;
146428e0efc6SCedric Chaumont }
14656915bbbbSJens Wiklander __utee_check_inout_annotation(macLen, sizeof(*macLen));
1466b0104773SPascal Brand
146728e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) {
146828e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
146928e0efc6SCedric Chaumont goto out;
147028e0efc6SCedric Chaumont }
147128e0efc6SCedric Chaumont
147228e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
147328e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
147428e0efc6SCedric Chaumont goto out;
147528e0efc6SCedric Chaumont }
147628e0efc6SCedric Chaumont
1477642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) {
1478642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1479642a1607SCedric Chaumont goto out;
1480642a1607SCedric Chaumont }
1481642a1607SCedric Chaumont
1482e86f1266SJens Wiklander ml = *macLen;
14832c028fdeSJerome Forissier res = _utee_hash_final(operation->state, message, messageLen, mac, &ml);
1484e86f1266SJens Wiklander *macLen = ml;
148528e0efc6SCedric Chaumont if (res != TEE_SUCCESS)
148628e0efc6SCedric Chaumont goto out;
148728e0efc6SCedric Chaumont
148828e0efc6SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
148928e0efc6SCedric Chaumont
1490642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL;
1491642a1607SCedric Chaumont
149228e0efc6SCedric Chaumont out:
149328e0efc6SCedric Chaumont if (res != TEE_SUCCESS &&
149428e0efc6SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER)
149528e0efc6SCedric Chaumont TEE_Panic(res);
149628e0efc6SCedric Chaumont
1497b0104773SPascal Brand return res;
1498b0104773SPascal Brand }
1499b0104773SPascal Brand
__GP11_TEE_MACComputeFinal(TEE_OperationHandle operation,const void * message,uint32_t messageLen,void * mac,uint32_t * macLen)1500185bf58cSJens Wiklander TEE_Result __GP11_TEE_MACComputeFinal(TEE_OperationHandle operation,
15018f07fe6fSJerome Forissier const void *message, uint32_t messageLen,
1502185bf58cSJens Wiklander void *mac, uint32_t *macLen)
1503185bf58cSJens Wiklander {
1504185bf58cSJens Wiklander TEE_Result res = TEE_SUCCESS;
1505185bf58cSJens Wiklander size_t ml = 0;
1506185bf58cSJens Wiklander
1507185bf58cSJens Wiklander __utee_check_inout_annotation(macLen, sizeof(*macLen));
1508185bf58cSJens Wiklander ml = *macLen;
1509185bf58cSJens Wiklander res = TEE_MACComputeFinal(operation, message, messageLen, mac, &ml);
1510185bf58cSJens Wiklander *macLen = ml;
1511185bf58cSJens Wiklander return res;
1512185bf58cSJens Wiklander }
1513185bf58cSJens Wiklander
TEE_MACCompareFinal(TEE_OperationHandle operation,const void * message,size_t messageLen,const void * mac,size_t macLen)1514185bf58cSJens Wiklander TEE_Result TEE_MACCompareFinal(TEE_OperationHandle operation,
1515185bf58cSJens Wiklander const void *message, size_t messageLen,
1516185bf58cSJens Wiklander const void *mac, size_t macLen)
1517b0104773SPascal Brand {
1518b0104773SPascal Brand TEE_Result res;
1519ee4ba3d1SVictor Chong uint8_t computed_mac[TEE_MAX_HASH_SIZE] = { 0 };
1520185bf58cSJens Wiklander size_t computed_mac_size = TEE_MAX_HASH_SIZE;
1521b0104773SPascal Brand
152228e0efc6SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_MAC) {
152328e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
152428e0efc6SCedric Chaumont goto out;
152528e0efc6SCedric Chaumont }
152628e0efc6SCedric Chaumont
152728e0efc6SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
152828e0efc6SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
152928e0efc6SCedric Chaumont goto out;
153028e0efc6SCedric Chaumont }
153128e0efc6SCedric Chaumont
1532642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_ACTIVE) {
1533642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1534642a1607SCedric Chaumont goto out;
1535642a1607SCedric Chaumont }
1536642a1607SCedric Chaumont
1537b0104773SPascal Brand res = TEE_MACComputeFinal(operation, message, messageLen, computed_mac,
1538b0104773SPascal Brand &computed_mac_size);
1539b0104773SPascal Brand if (res != TEE_SUCCESS)
154028e0efc6SCedric Chaumont goto out;
154128e0efc6SCedric Chaumont
154228e0efc6SCedric Chaumont if (computed_mac_size != macLen) {
154328e0efc6SCedric Chaumont res = TEE_ERROR_MAC_INVALID;
154428e0efc6SCedric Chaumont goto out;
154528e0efc6SCedric Chaumont }
154628e0efc6SCedric Chaumont
154748e10604SJerome Forissier if (consttime_memcmp(mac, computed_mac, computed_mac_size) != 0) {
154828e0efc6SCedric Chaumont res = TEE_ERROR_MAC_INVALID;
154928e0efc6SCedric Chaumont goto out;
155028e0efc6SCedric Chaumont }
155128e0efc6SCedric Chaumont
1552642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL;
1553642a1607SCedric Chaumont
155428e0efc6SCedric Chaumont out:
155528e0efc6SCedric Chaumont if (res != TEE_SUCCESS &&
155628e0efc6SCedric Chaumont res != TEE_ERROR_MAC_INVALID)
155728e0efc6SCedric Chaumont TEE_Panic(res);
155828e0efc6SCedric Chaumont
1559b0104773SPascal Brand return res;
1560b0104773SPascal Brand }
1561b0104773SPascal Brand
__GP11_TEE_MACCompareFinal(TEE_OperationHandle operation,const void * message,uint32_t messageLen,const void * mac,uint32_t macLen)1562185bf58cSJens Wiklander TEE_Result __GP11_TEE_MACCompareFinal(TEE_OperationHandle operation,
1563185bf58cSJens Wiklander const void *message, uint32_t messageLen,
1564185bf58cSJens Wiklander const void *mac, uint32_t macLen)
1565185bf58cSJens Wiklander {
1566185bf58cSJens Wiklander return TEE_MACCompareFinal(operation, message, messageLen, mac, macLen);
1567185bf58cSJens Wiklander }
1568185bf58cSJens Wiklander
1569b0104773SPascal Brand /* Cryptographic Operations API - Authenticated Encryption Functions */
1570b0104773SPascal Brand
TEE_AEInit(TEE_OperationHandle operation,const void * nonce,size_t nonceLen,uint32_t tagLen,size_t AADLen,size_t payloadLen)15718f07fe6fSJerome Forissier TEE_Result TEE_AEInit(TEE_OperationHandle operation, const void *nonce,
1572d9096215SJens Wiklander size_t nonceLen, uint32_t tagLen, size_t AADLen,
1573d9096215SJens Wiklander size_t payloadLen)
1574b0104773SPascal Brand {
1575b0104773SPascal Brand TEE_Result res;
1576b0104773SPascal Brand
1577b5816c88SCedric Chaumont if (operation == TEE_HANDLE_NULL || nonce == NULL) {
1578b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1579b5816c88SCedric Chaumont goto out;
1580b5816c88SCedric Chaumont }
1581b5816c88SCedric Chaumont
1582b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) {
1583b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1584b5816c88SCedric Chaumont goto out;
1585b5816c88SCedric Chaumont }
1586b0104773SPascal Brand
1587642a1607SCedric Chaumont if (operation->operationState != TEE_OPERATION_STATE_INITIAL) {
1588642a1607SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1589642a1607SCedric Chaumont goto out;
1590642a1607SCedric Chaumont }
1591642a1607SCedric Chaumont
1592b0104773SPascal Brand /*
1593b0104773SPascal Brand * AES-CCM tag len is specified by AES-CCM spec and handled in TEE Core
1594b0104773SPascal Brand * in the implementation. But AES-GCM spec doesn't specify the tag len
1595b0104773SPascal Brand * according to the same principle so we have to check here instead to
1596b0104773SPascal Brand * be GP compliant.
1597b0104773SPascal Brand */
1598b5816c88SCedric Chaumont if (operation->info.algorithm == TEE_ALG_AES_GCM) {
1599b0104773SPascal Brand /*
1600b0104773SPascal Brand * From GP spec: For AES-GCM, can be 128, 120, 112, 104, or 96
1601b0104773SPascal Brand */
1602b5816c88SCedric Chaumont if (tagLen < 96 || tagLen > 128 || (tagLen % 8 != 0)) {
1603b5816c88SCedric Chaumont res = TEE_ERROR_NOT_SUPPORTED;
1604b5816c88SCedric Chaumont goto out;
1605b5816c88SCedric Chaumont }
1606b0104773SPascal Brand }
1607b0104773SPascal Brand
16082c028fdeSJerome Forissier res = _utee_authenc_init(operation->state, nonce, nonceLen, tagLen / 8,
16092c028fdeSJerome Forissier AADLen, payloadLen);
1610b5816c88SCedric Chaumont if (res != TEE_SUCCESS)
1611b5816c88SCedric Chaumont goto out;
1612b5816c88SCedric Chaumont
16137acaf5adSAlbert Schwarzkopf operation->info.digestLength = tagLen / 8;
1614f2674567SSumit Garg operation->buffer_offs = 0;
1615b5816c88SCedric Chaumont operation->info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
1616b5816c88SCedric Chaumont
1617b5816c88SCedric Chaumont out:
1618b5816c88SCedric Chaumont if (res != TEE_SUCCESS &&
1619b5816c88SCedric Chaumont res != TEE_ERROR_NOT_SUPPORTED)
1620b0104773SPascal Brand TEE_Panic(res);
1621b5816c88SCedric Chaumont
1622b0104773SPascal Brand return res;
1623b0104773SPascal Brand }
1624b0104773SPascal Brand
__GP11_TEE_AEInit(TEE_OperationHandle operation,const void * nonce,uint32_t nonceLen,uint32_t tagLen,uint32_t AADLen,uint32_t payloadLen)1625d9096215SJens Wiklander TEE_Result __GP11_TEE_AEInit(TEE_OperationHandle operation, const void *nonce,
1626d9096215SJens Wiklander uint32_t nonceLen, uint32_t tagLen,
1627d9096215SJens Wiklander uint32_t AADLen, uint32_t payloadLen)
1628d9096215SJens Wiklander {
1629d9096215SJens Wiklander return TEE_AEInit(operation, nonce, nonceLen, tagLen, AADLen,
1630d9096215SJens Wiklander payloadLen);
1631d9096215SJens Wiklander }
1632d9096215SJens Wiklander
TEE_AEUpdateAAD(TEE_OperationHandle operation,const void * AADdata,size_t AADdataLen)16338f07fe6fSJerome Forissier void TEE_AEUpdateAAD(TEE_OperationHandle operation, const void *AADdata,
1634d9096215SJens Wiklander size_t AADdataLen)
1635d9096215SJens Wiklander {
1636d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS;
1637d9096215SJens Wiklander
1638d9096215SJens Wiklander if (operation == TEE_HANDLE_NULL || (!AADdata && AADdataLen))
1639d9096215SJens Wiklander TEE_Panic(0);
1640d9096215SJens Wiklander
1641d9096215SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_AE)
1642d9096215SJens Wiklander TEE_Panic(0);
1643d9096215SJens Wiklander
1644d9096215SJens Wiklander if (operation->operationState != TEE_OPERATION_STATE_INITIAL)
1645d9096215SJens Wiklander TEE_Panic(0);
1646d9096215SJens Wiklander
1647d9096215SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0)
1648d9096215SJens Wiklander TEE_Panic(0);
1649d9096215SJens Wiklander
1650d9096215SJens Wiklander res = _utee_authenc_update_aad(operation->state, AADdata, AADdataLen);
1651d9096215SJens Wiklander if (res != TEE_SUCCESS)
1652d9096215SJens Wiklander TEE_Panic(res);
1653d9096215SJens Wiklander }
1654d9096215SJens Wiklander
__GP11_TEE_AEUpdateAAD(TEE_OperationHandle operation,const void * AADdata,uint32_t AADdataLen)1655d9096215SJens Wiklander void __GP11_TEE_AEUpdateAAD(TEE_OperationHandle operation, const void *AADdata,
165679a3c601SCedric Chaumont uint32_t AADdataLen)
1657b0104773SPascal Brand {
1658d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS;
1659b0104773SPascal Brand
1660b5816c88SCedric Chaumont if (operation == TEE_HANDLE_NULL ||
1661b5816c88SCedric Chaumont (AADdata == NULL && AADdataLen != 0))
1662b0104773SPascal Brand TEE_Panic(0);
1663642a1607SCedric Chaumont
1664b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE)
1665b0104773SPascal Brand TEE_Panic(0);
1666642a1607SCedric Chaumont
1667b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0)
1668b0104773SPascal Brand TEE_Panic(0);
1669b0104773SPascal Brand
16702c028fdeSJerome Forissier res = _utee_authenc_update_aad(operation->state, AADdata, AADdataLen);
1671642a1607SCedric Chaumont
1672642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE;
1673642a1607SCedric Chaumont
1674b0104773SPascal Brand if (res != TEE_SUCCESS)
1675b0104773SPascal Brand TEE_Panic(res);
1676b0104773SPascal Brand }
1677b0104773SPascal Brand
ae_update_helper(TEE_OperationHandle operation,const void * src,size_t slen,void * dst,size_t * dlen)1678d9096215SJens Wiklander static TEE_Result ae_update_helper(TEE_OperationHandle operation,
1679d9096215SJens Wiklander const void *src, size_t slen, void *dst,
1680d9096215SJens Wiklander size_t *dlen)
1681b0104773SPascal Brand {
16826915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS;
16836915bbbbSJens Wiklander size_t req_dlen = 0;
16846915bbbbSJens Wiklander uint64_t dl = 0;
1685b0104773SPascal Brand
1686d9096215SJens Wiklander if (!src && !slen) {
1687d9096215SJens Wiklander *dlen = 0;
1688d9096215SJens Wiklander return TEE_SUCCESS;
1689d9096215SJens Wiklander }
1690d9096215SJens Wiklander
1691d9096215SJens Wiklander /*
1692d9096215SJens Wiklander * Check that required destLen is big enough before starting to feed
1693d9096215SJens Wiklander * data to the algorithm. Errors during feeding of data are fatal as we
1694d9096215SJens Wiklander * can't restore sync with this API.
1695d9096215SJens Wiklander */
1696d9096215SJens Wiklander if (operation->block_size > 1) {
1697*76d6685eSEtienne Carriere req_dlen = ROUNDDOWN2(operation->buffer_offs + slen,
1698d9096215SJens Wiklander operation->block_size);
1699d9096215SJens Wiklander } else {
1700d9096215SJens Wiklander req_dlen = slen;
1701d9096215SJens Wiklander }
1702d9096215SJens Wiklander
1703d9096215SJens Wiklander dl = *dlen;
1704d9096215SJens Wiklander if (dl < req_dlen) {
1705d9096215SJens Wiklander *dlen = req_dlen;
1706d9096215SJens Wiklander return TEE_ERROR_SHORT_BUFFER;
1707d9096215SJens Wiklander }
1708d9096215SJens Wiklander
1709d9096215SJens Wiklander if (operation->block_size > 1) {
1710d9096215SJens Wiklander res = tee_buffer_update(operation, _utee_authenc_update_payload,
1711d9096215SJens Wiklander src, slen, dst, &dl);
1712d9096215SJens Wiklander } else {
1713d9096215SJens Wiklander if (slen > 0) {
1714d9096215SJens Wiklander res = _utee_authenc_update_payload(operation->state,
1715d9096215SJens Wiklander src, slen, dst, &dl);
1716d9096215SJens Wiklander } else {
1717d9096215SJens Wiklander dl = 0;
1718d9096215SJens Wiklander res = TEE_SUCCESS;
1719d9096215SJens Wiklander }
1720d9096215SJens Wiklander }
1721d9096215SJens Wiklander
1722d9096215SJens Wiklander if (!res)
1723d9096215SJens Wiklander *dlen = dl;
1724d9096215SJens Wiklander
1725d9096215SJens Wiklander return res;
1726d9096215SJens Wiklander }
1727d9096215SJens Wiklander
TEE_AEUpdate(TEE_OperationHandle operation,const void * srcData,size_t srcLen,void * destData,size_t * destLen)1728d9096215SJens Wiklander TEE_Result TEE_AEUpdate(TEE_OperationHandle operation, const void *srcData,
1729d9096215SJens Wiklander size_t srcLen, void *destData, size_t *destLen)
1730d9096215SJens Wiklander {
1731d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS;
1732d9096215SJens Wiklander
17336915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) {
1734b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1735b5816c88SCedric Chaumont goto out;
1736b5816c88SCedric Chaumont }
1737d9096215SJens Wiklander __utee_check_outbuf_annotation(destData, destLen);
1738b5816c88SCedric Chaumont
1739b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) {
1740b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1741b5816c88SCedric Chaumont goto out;
1742b5816c88SCedric Chaumont }
1743b5816c88SCedric Chaumont
1744b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
1745b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1746b5816c88SCedric Chaumont goto out;
1747b5816c88SCedric Chaumont }
1748b0104773SPascal Brand
1749d9096215SJens Wiklander res = ae_update_helper(operation, srcData, srcLen, destData, destLen);
1750d9096215SJens Wiklander if (res != TEE_ERROR_SHORT_BUFFER && srcLen)
1751d9096215SJens Wiklander operation->operationState = TEE_OPERATION_STATE_ACTIVE;
1752d9096215SJens Wiklander
1753d9096215SJens Wiklander out:
1754d9096215SJens Wiklander if (res != TEE_SUCCESS &&
1755d9096215SJens Wiklander res != TEE_ERROR_SHORT_BUFFER)
1756d9096215SJens Wiklander TEE_Panic(res);
1757d9096215SJens Wiklander
1758d9096215SJens Wiklander return res;
1759d9096215SJens Wiklander }
1760d9096215SJens Wiklander
__GP11_TEE_AEUpdate(TEE_OperationHandle operation,const void * srcData,uint32_t srcLen,void * destData,uint32_t * destLen)1761d9096215SJens Wiklander TEE_Result __GP11_TEE_AEUpdate(TEE_OperationHandle operation,
1762d9096215SJens Wiklander const void *srcData, uint32_t srcLen,
1763d9096215SJens Wiklander void *destData, uint32_t *destLen)
1764d9096215SJens Wiklander {
1765d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS;
1766d9096215SJens Wiklander size_t dl = 0;
1767d9096215SJens Wiklander
1768d9096215SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) {
1769d9096215SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
1770d9096215SJens Wiklander goto out;
1771d9096215SJens Wiklander }
1772d9096215SJens Wiklander __utee_check_gp11_outbuf_annotation(destData, destLen);
1773d9096215SJens Wiklander
1774d9096215SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_AE) {
1775d9096215SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
1776827308b8SJerome Forissier goto out;
1777827308b8SJerome Forissier }
1778827308b8SJerome Forissier
1779d9096215SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
1780d9096215SJens Wiklander res = TEE_ERROR_BAD_PARAMETERS;
1781d9096215SJens Wiklander goto out;
1782afc0c182SBogdan Liulko }
1783afc0c182SBogdan Liulko
17846915bbbbSJens Wiklander dl = *destLen;
1785d9096215SJens Wiklander res = ae_update_helper(operation, srcData, srcLen, destData, &dl);
1786d9096215SJens Wiklander *destLen = dl;
1787b0104773SPascal Brand
1788afc0c182SBogdan Liulko if (res != TEE_SUCCESS)
1789afc0c182SBogdan Liulko goto out;
1790afc0c182SBogdan Liulko
1791642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_ACTIVE;
1792642a1607SCedric Chaumont
1793b5816c88SCedric Chaumont out:
1794b5816c88SCedric Chaumont if (res != TEE_SUCCESS &&
1795b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER)
1796b5816c88SCedric Chaumont TEE_Panic(res);
1797b5816c88SCedric Chaumont
1798b5816c88SCedric Chaumont return res;
1799b0104773SPascal Brand }
1800b0104773SPascal Brand
TEE_AEEncryptFinal(TEE_OperationHandle operation,const void * srcData,size_t srcLen,void * destData,size_t * destLen,void * tag,size_t * tagLen)1801b5816c88SCedric Chaumont TEE_Result TEE_AEEncryptFinal(TEE_OperationHandle operation,
1802d9096215SJens Wiklander const void *srcData, size_t srcLen,
1803d9096215SJens Wiklander void *destData, size_t *destLen, void *tag,
1804d9096215SJens Wiklander size_t *tagLen)
1805b0104773SPascal Brand {
1806d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS;
1807b0104773SPascal Brand uint8_t *dst = destData;
1808b0104773SPascal Brand size_t acc_dlen = 0;
1809d9096215SJens Wiklander uint64_t tmp_dlen = 0;
1810d9096215SJens Wiklander size_t req_dlen = 0;
1811d9096215SJens Wiklander uint64_t tl = 0;
1812b0104773SPascal Brand
18136915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) {
1814b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1815b5816c88SCedric Chaumont goto out;
1816b5816c88SCedric Chaumont }
18176915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen));
18186915bbbbSJens Wiklander __utee_check_inout_annotation(tagLen, sizeof(*tagLen));
1819b5816c88SCedric Chaumont
1820b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) {
1821b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1822b5816c88SCedric Chaumont goto out;
1823b5816c88SCedric Chaumont }
1824b5816c88SCedric Chaumont
1825b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
1826b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1827b5816c88SCedric Chaumont goto out;
1828b5816c88SCedric Chaumont }
1829b0104773SPascal Brand
1830b0104773SPascal Brand /*
1831b0104773SPascal Brand * Check that required destLen is big enough before starting to feed
1832b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we
1833b0104773SPascal Brand * can't restore sync with this API.
18342733280aSEtienne Carriere *
18352733280aSEtienne Carriere * Need to check this before update_payload since sync would be lost if
18362733280aSEtienne Carriere * we return short buffer after that.
1837b0104773SPascal Brand */
18382733280aSEtienne Carriere res = TEE_ERROR_GENERIC;
18392733280aSEtienne Carriere
1840b5816c88SCedric Chaumont req_dlen = operation->buffer_offs + srcLen;
1841b0104773SPascal Brand if (*destLen < req_dlen) {
1842b0104773SPascal Brand *destLen = req_dlen;
1843b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER;
1844b0104773SPascal Brand }
1845b0104773SPascal Brand
18467acaf5adSAlbert Schwarzkopf if (*tagLen < operation->info.digestLength) {
18477acaf5adSAlbert Schwarzkopf *tagLen = operation->info.digestLength;
1848b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER;
1849b0104773SPascal Brand }
1850b0104773SPascal Brand
18512733280aSEtienne Carriere if (res == TEE_ERROR_SHORT_BUFFER)
18522733280aSEtienne Carriere goto out;
18532733280aSEtienne Carriere
1854afc0c182SBogdan Liulko tl = *tagLen;
1855b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen;
1856afc0c182SBogdan Liulko if (operation->block_size > 1) {
18572c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_authenc_update_payload,
1858afc0c182SBogdan Liulko srcData, srcLen, dst, &tmp_dlen);
1859b5816c88SCedric Chaumont if (res != TEE_SUCCESS)
1860b5816c88SCedric Chaumont goto out;
1861b5816c88SCedric Chaumont
1862b0104773SPascal Brand dst += tmp_dlen;
1863b0104773SPascal Brand acc_dlen += tmp_dlen;
1864b0104773SPascal Brand
1865b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen;
18662c028fdeSJerome Forissier res = _utee_authenc_enc_final(operation->state,
1867afc0c182SBogdan Liulko operation->buffer,
1868afc0c182SBogdan Liulko operation->buffer_offs, dst,
1869afc0c182SBogdan Liulko &tmp_dlen, tag, &tl);
1870afc0c182SBogdan Liulko } else {
18712c028fdeSJerome Forissier res = _utee_authenc_enc_final(operation->state, srcData,
1872afc0c182SBogdan Liulko srcLen, dst, &tmp_dlen,
1873e86f1266SJens Wiklander tag, &tl);
1874afc0c182SBogdan Liulko }
1875e86f1266SJens Wiklander *tagLen = tl;
1876b0104773SPascal Brand if (res != TEE_SUCCESS)
1877b5816c88SCedric Chaumont goto out;
1878b0104773SPascal Brand
1879b5816c88SCedric Chaumont acc_dlen += tmp_dlen;
1880b0104773SPascal Brand *destLen = acc_dlen;
1881642a1607SCedric Chaumont
1882b5816c88SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
1883b5816c88SCedric Chaumont
1884642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL;
1885642a1607SCedric Chaumont
1886b5816c88SCedric Chaumont out:
1887b5816c88SCedric Chaumont if (res != TEE_SUCCESS &&
1888b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER)
1889b5816c88SCedric Chaumont TEE_Panic(res);
1890b0104773SPascal Brand
1891b0104773SPascal Brand return res;
1892b0104773SPascal Brand }
1893b0104773SPascal Brand
__GP11_TEE_AEEncryptFinal(TEE_OperationHandle operation,const void * srcData,uint32_t srcLen,void * destData,uint32_t * destLen,void * tag,uint32_t * tagLen)1894d9096215SJens Wiklander TEE_Result __GP11_TEE_AEEncryptFinal(TEE_OperationHandle operation,
18958f07fe6fSJerome Forissier const void *srcData, uint32_t srcLen,
1896d9096215SJens Wiklander void *destData, uint32_t *destLen,
1897d9096215SJens Wiklander void *tag, uint32_t *tagLen)
1898b0104773SPascal Brand {
1899d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS;
1900d9096215SJens Wiklander size_t dl = 0;
1901d9096215SJens Wiklander size_t tl = 0;
1902d9096215SJens Wiklander
1903d9096215SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen));
1904d9096215SJens Wiklander __utee_check_inout_annotation(tagLen, sizeof(*tagLen));
1905d9096215SJens Wiklander dl = *destLen;
1906d9096215SJens Wiklander tl = *tagLen;
1907d9096215SJens Wiklander res = TEE_AEEncryptFinal(operation, srcData, srcLen, destData, &dl,
1908d9096215SJens Wiklander tag, &tl);
1909d9096215SJens Wiklander *destLen = dl;
1910d9096215SJens Wiklander *tagLen = tl;
1911d9096215SJens Wiklander return res;
1912d9096215SJens Wiklander }
1913d9096215SJens Wiklander
TEE_AEDecryptFinal(TEE_OperationHandle operation,const void * srcData,size_t srcLen,void * destData,size_t * destLen,void * tag,size_t tagLen)1914d9096215SJens Wiklander TEE_Result TEE_AEDecryptFinal(TEE_OperationHandle operation,
1915d9096215SJens Wiklander const void *srcData, size_t srcLen,
1916d9096215SJens Wiklander void *destData, size_t *destLen, void *tag,
1917d9096215SJens Wiklander size_t tagLen)
1918d9096215SJens Wiklander {
1919d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS;
1920b0104773SPascal Brand uint8_t *dst = destData;
1921b0104773SPascal Brand size_t acc_dlen = 0;
1922d9096215SJens Wiklander uint64_t tmp_dlen = 0;
1923d9096215SJens Wiklander size_t req_dlen = 0;
1924b0104773SPascal Brand
19256915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen)) {
1926b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1927b5816c88SCedric Chaumont goto out;
1928b5816c88SCedric Chaumont }
19296915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen));
1930b5816c88SCedric Chaumont
1931b5816c88SCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_AE) {
1932b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1933b5816c88SCedric Chaumont goto out;
1934b5816c88SCedric Chaumont }
1935b5816c88SCedric Chaumont
1936b5816c88SCedric Chaumont if ((operation->info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0) {
1937b5816c88SCedric Chaumont res = TEE_ERROR_BAD_PARAMETERS;
1938b5816c88SCedric Chaumont goto out;
1939b5816c88SCedric Chaumont }
1940b0104773SPascal Brand
1941b0104773SPascal Brand /*
1942b0104773SPascal Brand * Check that required destLen is big enough before starting to feed
1943b0104773SPascal Brand * data to the algorithm. Errors during feeding of data are fatal as we
1944b0104773SPascal Brand * can't restore sync with this API.
1945b0104773SPascal Brand */
1946b5816c88SCedric Chaumont req_dlen = operation->buffer_offs + srcLen;
1947b0104773SPascal Brand if (*destLen < req_dlen) {
1948b0104773SPascal Brand *destLen = req_dlen;
1949b5816c88SCedric Chaumont res = TEE_ERROR_SHORT_BUFFER;
1950b5816c88SCedric Chaumont goto out;
1951b0104773SPascal Brand }
1952b0104773SPascal Brand
1953b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen;
1954afc0c182SBogdan Liulko if (operation->block_size > 1) {
19552c028fdeSJerome Forissier res = tee_buffer_update(operation, _utee_authenc_update_payload,
1956afc0c182SBogdan Liulko srcData, srcLen, dst, &tmp_dlen);
1957b5816c88SCedric Chaumont if (res != TEE_SUCCESS)
1958b5816c88SCedric Chaumont goto out;
1959b5816c88SCedric Chaumont
1960b0104773SPascal Brand dst += tmp_dlen;
1961b0104773SPascal Brand acc_dlen += tmp_dlen;
1962b0104773SPascal Brand
1963b0104773SPascal Brand tmp_dlen = *destLen - acc_dlen;
19642c028fdeSJerome Forissier res = _utee_authenc_dec_final(operation->state,
1965afc0c182SBogdan Liulko operation->buffer,
1966afc0c182SBogdan Liulko operation->buffer_offs, dst,
1967afc0c182SBogdan Liulko &tmp_dlen, tag, tagLen);
1968afc0c182SBogdan Liulko } else {
19692c028fdeSJerome Forissier res = _utee_authenc_dec_final(operation->state, srcData,
1970afc0c182SBogdan Liulko srcLen, dst, &tmp_dlen,
1971b5816c88SCedric Chaumont tag, tagLen);
1972afc0c182SBogdan Liulko }
1973b5816c88SCedric Chaumont if (res != TEE_SUCCESS)
1974b5816c88SCedric Chaumont goto out;
1975b5816c88SCedric Chaumont
1976b0104773SPascal Brand /* Supplied tagLen should match what we initiated with */
19777acaf5adSAlbert Schwarzkopf if (tagLen != operation->info.digestLength)
1978b0104773SPascal Brand res = TEE_ERROR_MAC_INVALID;
1979b0104773SPascal Brand
1980b0104773SPascal Brand acc_dlen += tmp_dlen;
1981b0104773SPascal Brand *destLen = acc_dlen;
1982642a1607SCedric Chaumont
1983b5816c88SCedric Chaumont operation->info.handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
1984b5816c88SCedric Chaumont
1985642a1607SCedric Chaumont operation->operationState = TEE_OPERATION_STATE_INITIAL;
1986642a1607SCedric Chaumont
1987b5816c88SCedric Chaumont out:
1988b5816c88SCedric Chaumont if (res != TEE_SUCCESS &&
1989b5816c88SCedric Chaumont res != TEE_ERROR_SHORT_BUFFER &&
1990b5816c88SCedric Chaumont res != TEE_ERROR_MAC_INVALID)
1991b5816c88SCedric Chaumont TEE_Panic(res);
1992b0104773SPascal Brand
1993b0104773SPascal Brand return res;
1994b0104773SPascal Brand }
1995b0104773SPascal Brand
__GP11_TEE_AEDecryptFinal(TEE_OperationHandle operation,const void * srcData,uint32_t srcLen,void * destData,uint32_t * destLen,void * tag,uint32_t tagLen)1996d9096215SJens Wiklander TEE_Result __GP11_TEE_AEDecryptFinal(TEE_OperationHandle operation,
1997d9096215SJens Wiklander const void *srcData, uint32_t srcLen,
1998d9096215SJens Wiklander void *destData, uint32_t *destLen,
1999d9096215SJens Wiklander void *tag, uint32_t tagLen)
2000d9096215SJens Wiklander {
2001d9096215SJens Wiklander TEE_Result res = TEE_SUCCESS;
2002d9096215SJens Wiklander size_t dl = 0;
2003d9096215SJens Wiklander
2004d9096215SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen));
2005d9096215SJens Wiklander dl = *destLen;
2006d9096215SJens Wiklander res = TEE_AEDecryptFinal(operation, srcData, srcLen, destData, &dl,
2007d9096215SJens Wiklander tag, tagLen);
2008d9096215SJens Wiklander *destLen = dl;
2009d9096215SJens Wiklander return res;
2010d9096215SJens Wiklander }
2011d9096215SJens Wiklander
2012b0104773SPascal Brand /* Cryptographic Operations API - Asymmetric Functions */
2013b0104773SPascal Brand
TEE_AsymmetricEncrypt(TEE_OperationHandle operation,const TEE_Attribute * params,uint32_t paramCount,const void * srcData,size_t srcLen,void * destData,size_t * destLen)201412e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricEncrypt(TEE_OperationHandle operation,
20158f07fe6fSJerome Forissier const TEE_Attribute *params,
20168f07fe6fSJerome Forissier uint32_t paramCount, const void *srcData,
2017999b69d0SJens Wiklander size_t srcLen, void *destData,
2018999b69d0SJens Wiklander size_t *destLen)
2019b0104773SPascal Brand {
20206915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS;
2021e86f1266SJens Wiklander struct utee_attribute ua[paramCount];
20226915bbbbSJens Wiklander uint64_t dl = 0;
2023b0104773SPascal Brand
20246915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen))
2025b0104773SPascal Brand TEE_Panic(0);
20266915bbbbSJens Wiklander
20276915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount);
20286915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen));
20296915bbbbSJens Wiklander
203012e66b6fSCedric Chaumont if (!operation->key1)
2031b0104773SPascal Brand TEE_Panic(0);
203212e66b6fSCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER)
203312e66b6fSCedric Chaumont TEE_Panic(0);
203412e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_ENCRYPT)
2035b0104773SPascal Brand TEE_Panic(0);
2036b0104773SPascal Brand
2037e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount);
2038e86f1266SJens Wiklander dl = *destLen;
20392c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, srcData,
2040e86f1266SJens Wiklander srcLen, destData, &dl);
2041e86f1266SJens Wiklander *destLen = dl;
204212e66b6fSCedric Chaumont
20438844ebfcSPascal Brand if (res != TEE_SUCCESS &&
20448844ebfcSPascal Brand res != TEE_ERROR_SHORT_BUFFER &&
20451bc176d8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS &&
20461bc176d8SJens Wiklander res != TEE_ERROR_CIPHERTEXT_INVALID &&
20471bc176d8SJens Wiklander res != TEE_ERROR_NOT_SUPPORTED)
2048b0104773SPascal Brand TEE_Panic(res);
204912e66b6fSCedric Chaumont
2050b0104773SPascal Brand return res;
2051b0104773SPascal Brand }
2052b0104773SPascal Brand
__GP11_TEE_AsymmetricEncrypt(TEE_OperationHandle operation,const __GP11_TEE_Attribute * params,uint32_t paramCount,const void * srcData,uint32_t srcLen,void * destData,uint32_t * destLen)20534f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricEncrypt(TEE_OperationHandle operation,
20544f4374c8SJens Wiklander const __GP11_TEE_Attribute *params,
20554f4374c8SJens Wiklander uint32_t paramCount,
20564f4374c8SJens Wiklander const void *srcData, uint32_t srcLen,
20574f4374c8SJens Wiklander void *destData, uint32_t *destLen)
20584f4374c8SJens Wiklander {
20594f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS;
20604f4374c8SJens Wiklander struct utee_attribute ua[paramCount];
20614f4374c8SJens Wiklander uint64_t dl = 0;
20624f4374c8SJens Wiklander
20634f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen))
20644f4374c8SJens Wiklander TEE_Panic(0);
20654f4374c8SJens Wiklander
20664f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount);
20674f4374c8SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen));
20684f4374c8SJens Wiklander
20694f4374c8SJens Wiklander if (!operation->key1)
20704f4374c8SJens Wiklander TEE_Panic(0);
20714f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER)
20724f4374c8SJens Wiklander TEE_Panic(0);
20734f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_ENCRYPT)
20744f4374c8SJens Wiklander TEE_Panic(0);
20754f4374c8SJens Wiklander
20764f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount);
20774f4374c8SJens Wiklander dl = *destLen;
20784f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, srcData,
20794f4374c8SJens Wiklander srcLen, destData, &dl);
20804f4374c8SJens Wiklander *destLen = dl;
20814f4374c8SJens Wiklander
20824f4374c8SJens Wiklander if (res != TEE_SUCCESS &&
20834f4374c8SJens Wiklander res != TEE_ERROR_SHORT_BUFFER &&
20844f4374c8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS)
20854f4374c8SJens Wiklander TEE_Panic(res);
20864f4374c8SJens Wiklander
20874f4374c8SJens Wiklander return res;
20884f4374c8SJens Wiklander }
20894f4374c8SJens Wiklander
TEE_AsymmetricDecrypt(TEE_OperationHandle operation,const TEE_Attribute * params,uint32_t paramCount,const void * srcData,size_t srcLen,void * destData,size_t * destLen)209012e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricDecrypt(TEE_OperationHandle operation,
20918f07fe6fSJerome Forissier const TEE_Attribute *params,
20928f07fe6fSJerome Forissier uint32_t paramCount, const void *srcData,
2093999b69d0SJens Wiklander size_t srcLen, void *destData,
2094999b69d0SJens Wiklander size_t *destLen)
2095b0104773SPascal Brand {
20966915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS;
2097e86f1266SJens Wiklander struct utee_attribute ua[paramCount];
20986915bbbbSJens Wiklander uint64_t dl = 0;
2099b0104773SPascal Brand
21006915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen))
2101b0104773SPascal Brand TEE_Panic(0);
21026915bbbbSJens Wiklander
21036915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount);
21046915bbbbSJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen));
21056915bbbbSJens Wiklander
210612e66b6fSCedric Chaumont if (!operation->key1)
2107b0104773SPascal Brand TEE_Panic(0);
210812e66b6fSCedric Chaumont if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER)
210912e66b6fSCedric Chaumont TEE_Panic(0);
211012e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_DECRYPT)
2111b0104773SPascal Brand TEE_Panic(0);
2112b0104773SPascal Brand
2113e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount);
2114e86f1266SJens Wiklander dl = *destLen;
21152c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, srcData,
2116e86f1266SJens Wiklander srcLen, destData, &dl);
2117e86f1266SJens Wiklander *destLen = dl;
211812e66b6fSCedric Chaumont
21198844ebfcSPascal Brand if (res != TEE_SUCCESS &&
21208844ebfcSPascal Brand res != TEE_ERROR_SHORT_BUFFER &&
21211bc176d8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS &&
21221bc176d8SJens Wiklander res != TEE_ERROR_CIPHERTEXT_INVALID &&
21231bc176d8SJens Wiklander res != TEE_ERROR_NOT_SUPPORTED)
2124b0104773SPascal Brand TEE_Panic(res);
212512e66b6fSCedric Chaumont
2126b0104773SPascal Brand return res;
2127b0104773SPascal Brand }
2128b0104773SPascal Brand
__GP11_TEE_AsymmetricDecrypt(TEE_OperationHandle operation,const __GP11_TEE_Attribute * params,uint32_t paramCount,const void * srcData,uint32_t srcLen,void * destData,uint32_t * destLen)21294f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricDecrypt(TEE_OperationHandle operation,
21304f4374c8SJens Wiklander const __GP11_TEE_Attribute *params,
21314f4374c8SJens Wiklander uint32_t paramCount,
21324f4374c8SJens Wiklander const void *srcData, uint32_t srcLen,
21334f4374c8SJens Wiklander void *destData, uint32_t *destLen)
21344f4374c8SJens Wiklander {
21354f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS;
21364f4374c8SJens Wiklander struct utee_attribute ua[paramCount];
21374f4374c8SJens Wiklander uint64_t dl = 0;
21384f4374c8SJens Wiklander
21394f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!srcData && srcLen))
21404f4374c8SJens Wiklander TEE_Panic(0);
21414f4374c8SJens Wiklander
21424f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount);
21434f4374c8SJens Wiklander __utee_check_inout_annotation(destLen, sizeof(*destLen));
21444f4374c8SJens Wiklander
21454f4374c8SJens Wiklander if (!operation->key1)
21464f4374c8SJens Wiklander TEE_Panic(0);
21474f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER)
21484f4374c8SJens Wiklander TEE_Panic(0);
21494f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_DECRYPT)
21504f4374c8SJens Wiklander TEE_Panic(0);
21514f4374c8SJens Wiklander
21524f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount);
21534f4374c8SJens Wiklander dl = *destLen;
21544f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, srcData,
21554f4374c8SJens Wiklander srcLen, destData, &dl);
21564f4374c8SJens Wiklander *destLen = dl;
21574f4374c8SJens Wiklander
21584f4374c8SJens Wiklander if (res != TEE_SUCCESS &&
21594f4374c8SJens Wiklander res != TEE_ERROR_SHORT_BUFFER &&
21604f4374c8SJens Wiklander res != TEE_ERROR_BAD_PARAMETERS)
21614f4374c8SJens Wiklander TEE_Panic(res);
21624f4374c8SJens Wiklander
21634f4374c8SJens Wiklander return res;
21644f4374c8SJens Wiklander }
21654f4374c8SJens Wiklander
TEE_AsymmetricSignDigest(TEE_OperationHandle operation,const TEE_Attribute * params,uint32_t paramCount,const void * digest,size_t digestLen,void * signature,size_t * signatureLen)216612e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricSignDigest(TEE_OperationHandle operation,
21678f07fe6fSJerome Forissier const TEE_Attribute *params,
21688f07fe6fSJerome Forissier uint32_t paramCount, const void *digest,
21690b354ec8SJens Wiklander size_t digestLen, void *signature,
21700b354ec8SJens Wiklander size_t *signatureLen)
2171b0104773SPascal Brand {
21726915bbbbSJens Wiklander TEE_Result res = TEE_SUCCESS;
2173e86f1266SJens Wiklander struct utee_attribute ua[paramCount];
21746915bbbbSJens Wiklander uint64_t sl = 0;
2175b0104773SPascal Brand
21766915bbbbSJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen))
2177b0104773SPascal Brand TEE_Panic(0);
21786915bbbbSJens Wiklander
21796915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount);
21806915bbbbSJens Wiklander __utee_check_inout_annotation(signatureLen, sizeof(*signatureLen));
21816915bbbbSJens Wiklander
218212e66b6fSCedric Chaumont if (!operation->key1)
2183b0104773SPascal Brand TEE_Panic(0);
218412e66b6fSCedric Chaumont if (operation->info.operationClass !=
218512e66b6fSCedric Chaumont TEE_OPERATION_ASYMMETRIC_SIGNATURE)
218612e66b6fSCedric Chaumont TEE_Panic(0);
218712e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_SIGN)
2188b0104773SPascal Brand TEE_Panic(0);
2189b0104773SPascal Brand
2190e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount);
2191e86f1266SJens Wiklander sl = *signatureLen;
21922c028fdeSJerome Forissier res = _utee_asymm_operate(operation->state, ua, paramCount, digest,
2193e86f1266SJens Wiklander digestLen, signature, &sl);
2194e86f1266SJens Wiklander *signatureLen = sl;
219512e66b6fSCedric Chaumont
2196b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER)
2197b0104773SPascal Brand TEE_Panic(res);
219812e66b6fSCedric Chaumont
2199b0104773SPascal Brand return res;
2200b0104773SPascal Brand }
2201b0104773SPascal Brand
__GP11_TEE_AsymmetricSignDigest(TEE_OperationHandle operation,const __GP11_TEE_Attribute * params,uint32_t paramCount,const void * digest,uint32_t digestLen,void * signature,uint32_t * signatureLen)22024f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricSignDigest(TEE_OperationHandle operation,
22034f4374c8SJens Wiklander const __GP11_TEE_Attribute *params,
22044f4374c8SJens Wiklander uint32_t paramCount,
22054f4374c8SJens Wiklander const void *digest,
22064f4374c8SJens Wiklander uint32_t digestLen, void *signature,
22074f4374c8SJens Wiklander uint32_t *signatureLen)
22084f4374c8SJens Wiklander {
22094f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS;
22104f4374c8SJens Wiklander struct utee_attribute ua[paramCount];
22114f4374c8SJens Wiklander uint64_t sl = 0;
22124f4374c8SJens Wiklander
22134f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen))
22144f4374c8SJens Wiklander TEE_Panic(0);
22154f4374c8SJens Wiklander
22164f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount);
22174f4374c8SJens Wiklander __utee_check_inout_annotation(signatureLen, sizeof(*signatureLen));
22184f4374c8SJens Wiklander
22194f4374c8SJens Wiklander if (!operation->key1)
22204f4374c8SJens Wiklander TEE_Panic(0);
22214f4374c8SJens Wiklander if (operation->info.operationClass !=
22224f4374c8SJens Wiklander TEE_OPERATION_ASYMMETRIC_SIGNATURE)
22234f4374c8SJens Wiklander TEE_Panic(0);
22244f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_SIGN)
22254f4374c8SJens Wiklander TEE_Panic(0);
22264f4374c8SJens Wiklander
22274f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount);
22284f4374c8SJens Wiklander sl = *signatureLen;
22294f4374c8SJens Wiklander res = _utee_asymm_operate(operation->state, ua, paramCount, digest,
22304f4374c8SJens Wiklander digestLen, signature, &sl);
22314f4374c8SJens Wiklander *signatureLen = sl;
22324f4374c8SJens Wiklander
22334f4374c8SJens Wiklander if (res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER)
22344f4374c8SJens Wiklander TEE_Panic(res);
22354f4374c8SJens Wiklander
22364f4374c8SJens Wiklander return res;
22374f4374c8SJens Wiklander }
22384f4374c8SJens Wiklander
TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation,const TEE_Attribute * params,uint32_t paramCount,const void * digest,size_t digestLen,const void * signature,size_t signatureLen)223912e66b6fSCedric Chaumont TEE_Result TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation,
22408f07fe6fSJerome Forissier const TEE_Attribute *params,
22418f07fe6fSJerome Forissier uint32_t paramCount, const void *digest,
22420b354ec8SJens Wiklander size_t digestLen,
22438f07fe6fSJerome Forissier const void *signature,
22440b354ec8SJens Wiklander size_t signatureLen)
2245b0104773SPascal Brand {
2246b0104773SPascal Brand TEE_Result res;
2247e86f1266SJens Wiklander struct utee_attribute ua[paramCount];
2248b0104773SPascal Brand
224912e66b6fSCedric Chaumont if (operation == TEE_HANDLE_NULL ||
225012e66b6fSCedric Chaumont (digest == NULL && digestLen != 0) ||
2251b0104773SPascal Brand (signature == NULL && signatureLen != 0))
2252b0104773SPascal Brand TEE_Panic(0);
22536915bbbbSJens Wiklander
22546915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount);
22556915bbbbSJens Wiklander
225612e66b6fSCedric Chaumont if (!operation->key1)
2257b0104773SPascal Brand TEE_Panic(0);
225812e66b6fSCedric Chaumont if (operation->info.operationClass !=
225912e66b6fSCedric Chaumont TEE_OPERATION_ASYMMETRIC_SIGNATURE)
226012e66b6fSCedric Chaumont TEE_Panic(0);
226112e66b6fSCedric Chaumont if (operation->info.mode != TEE_MODE_VERIFY)
2262b0104773SPascal Brand TEE_Panic(0);
2263b0104773SPascal Brand
2264e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount);
22652c028fdeSJerome Forissier res = _utee_asymm_verify(operation->state, ua, paramCount, digest,
226612e66b6fSCedric Chaumont digestLen, signature, signatureLen);
226712e66b6fSCedric Chaumont
2268b0104773SPascal Brand if (res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID)
2269b0104773SPascal Brand TEE_Panic(res);
227012e66b6fSCedric Chaumont
2271b0104773SPascal Brand return res;
2272b0104773SPascal Brand }
2273b0104773SPascal Brand
__GP11_TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation,const __GP11_TEE_Attribute * params,uint32_t paramCount,const void * digest,uint32_t digestLen,const void * signature,uint32_t signatureLen)22744f4374c8SJens Wiklander TEE_Result __GP11_TEE_AsymmetricVerifyDigest(TEE_OperationHandle operation,
22754f4374c8SJens Wiklander const __GP11_TEE_Attribute *params,
22764f4374c8SJens Wiklander uint32_t paramCount,
22774f4374c8SJens Wiklander const void *digest,
22784f4374c8SJens Wiklander uint32_t digestLen,
22794f4374c8SJens Wiklander const void *signature,
22804f4374c8SJens Wiklander uint32_t signatureLen)
22814f4374c8SJens Wiklander {
22824f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS;
22834f4374c8SJens Wiklander struct utee_attribute ua[paramCount];
22844f4374c8SJens Wiklander
22854f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || (!digest && digestLen) ||
22864f4374c8SJens Wiklander (!signature && signatureLen))
22874f4374c8SJens Wiklander TEE_Panic(0);
22884f4374c8SJens Wiklander
22894f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount);
22904f4374c8SJens Wiklander
22914f4374c8SJens Wiklander if (!operation->key1)
22924f4374c8SJens Wiklander TEE_Panic(0);
22934f4374c8SJens Wiklander if (operation->info.operationClass !=
22944f4374c8SJens Wiklander TEE_OPERATION_ASYMMETRIC_SIGNATURE)
22954f4374c8SJens Wiklander TEE_Panic(0);
22964f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_VERIFY)
22974f4374c8SJens Wiklander TEE_Panic(0);
22984f4374c8SJens Wiklander
22994f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount);
23004f4374c8SJens Wiklander res = _utee_asymm_verify(operation->state, ua, paramCount, digest,
23014f4374c8SJens Wiklander digestLen, signature, signatureLen);
23024f4374c8SJens Wiklander
23034f4374c8SJens Wiklander if (res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID)
23044f4374c8SJens Wiklander TEE_Panic(res);
23054f4374c8SJens Wiklander
23064f4374c8SJens Wiklander return res;
23074f4374c8SJens Wiklander }
23084f4374c8SJens Wiklander
2309b0104773SPascal Brand /* Cryptographic Operations API - Key Derivation Functions */
2310b0104773SPascal Brand
TEE_DeriveKey(TEE_OperationHandle operation,const TEE_Attribute * params,uint32_t paramCount,TEE_ObjectHandle derivedKey)2311b0104773SPascal Brand void TEE_DeriveKey(TEE_OperationHandle operation,
2312b0104773SPascal Brand const TEE_Attribute *params, uint32_t paramCount,
2313b0104773SPascal Brand TEE_ObjectHandle derivedKey)
2314b0104773SPascal Brand {
2315e86f1266SJens Wiklander struct utee_attribute ua[paramCount];
231675d6a373SJens Wiklander struct utee_object_info key_info = { };
231775d6a373SJens Wiklander TEE_Result res = TEE_SUCCESS;
2318b0104773SPascal Brand
2319b0104773SPascal Brand if (operation == TEE_HANDLE_NULL || derivedKey == 0)
2320b0104773SPascal Brand TEE_Panic(0);
23216915bbbbSJens Wiklander
23226915bbbbSJens Wiklander __utee_check_attr_in_annotation(params, paramCount);
23236915bbbbSJens Wiklander
23248854d3c6SJerome Forissier if (TEE_ALG_GET_CLASS(operation->info.algorithm) !=
23258854d3c6SJerome Forissier TEE_OPERATION_KEY_DERIVATION)
2326b0104773SPascal Brand TEE_Panic(0);
2327b0104773SPascal Brand
2328b0104773SPascal Brand if (operation->info.operationClass != TEE_OPERATION_KEY_DERIVATION)
2329b0104773SPascal Brand TEE_Panic(0);
233084fa9467SCedric Chaumont if (!operation->key1)
233184fa9467SCedric Chaumont TEE_Panic(0);
2332b0104773SPascal Brand if (operation->info.mode != TEE_MODE_DERIVE)
2333b0104773SPascal Brand TEE_Panic(0);
2334b0104773SPascal Brand if ((operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0)
2335b0104773SPascal Brand TEE_Panic(0);
2336b0104773SPascal Brand
23372c028fdeSJerome Forissier res = _utee_cryp_obj_get_info((unsigned long)derivedKey, &key_info);
2338b0104773SPascal Brand if (res != TEE_SUCCESS)
2339b36311adSJerome Forissier TEE_Panic(res);
2340b0104773SPascal Brand
234175d6a373SJens Wiklander if (key_info.obj_type != TEE_TYPE_GENERIC_SECRET)
2342b0104773SPascal Brand TEE_Panic(0);
234375d6a373SJens Wiklander if ((key_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
2344b0104773SPascal Brand TEE_Panic(0);
2345b0104773SPascal Brand
2346e86f1266SJens Wiklander __utee_from_attr(ua, params, paramCount);
23472c028fdeSJerome Forissier res = _utee_cryp_derive_key(operation->state, ua, paramCount,
2348e86f1266SJens Wiklander (unsigned long)derivedKey);
2349b0104773SPascal Brand if (res != TEE_SUCCESS)
2350b0104773SPascal Brand TEE_Panic(res);
2351b0104773SPascal Brand }
2352b0104773SPascal Brand
__GP11_TEE_DeriveKey(TEE_OperationHandle operation,const __GP11_TEE_Attribute * params,uint32_t paramCount,TEE_ObjectHandle derivedKey)23534f4374c8SJens Wiklander void __GP11_TEE_DeriveKey(TEE_OperationHandle operation,
23544f4374c8SJens Wiklander const __GP11_TEE_Attribute *params,
23554f4374c8SJens Wiklander uint32_t paramCount, TEE_ObjectHandle derivedKey)
23564f4374c8SJens Wiklander {
23574f4374c8SJens Wiklander struct utee_attribute ua[paramCount];
23584f4374c8SJens Wiklander struct utee_object_info key_info = { };
23594f4374c8SJens Wiklander TEE_Result res = TEE_SUCCESS;
23604f4374c8SJens Wiklander
23614f4374c8SJens Wiklander if (operation == TEE_HANDLE_NULL || derivedKey == 0)
23624f4374c8SJens Wiklander TEE_Panic(0);
23634f4374c8SJens Wiklander
23644f4374c8SJens Wiklander __utee_check_gp11_attr_in_annotation(params, paramCount);
23654f4374c8SJens Wiklander
23664f4374c8SJens Wiklander if (TEE_ALG_GET_CLASS(operation->info.algorithm) !=
23674f4374c8SJens Wiklander TEE_OPERATION_KEY_DERIVATION)
23684f4374c8SJens Wiklander TEE_Panic(0);
23694f4374c8SJens Wiklander
23704f4374c8SJens Wiklander if (operation->info.operationClass != TEE_OPERATION_KEY_DERIVATION)
23714f4374c8SJens Wiklander TEE_Panic(0);
23724f4374c8SJens Wiklander if (!operation->key1)
23734f4374c8SJens Wiklander TEE_Panic(0);
23744f4374c8SJens Wiklander if (operation->info.mode != TEE_MODE_DERIVE)
23754f4374c8SJens Wiklander TEE_Panic(0);
23764f4374c8SJens Wiklander if ((operation->info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0)
23774f4374c8SJens Wiklander TEE_Panic(0);
23784f4374c8SJens Wiklander
23794f4374c8SJens Wiklander res = _utee_cryp_obj_get_info((unsigned long)derivedKey, &key_info);
23804f4374c8SJens Wiklander if (res != TEE_SUCCESS)
23814f4374c8SJens Wiklander TEE_Panic(res);
23824f4374c8SJens Wiklander
23834f4374c8SJens Wiklander if (key_info.obj_type != TEE_TYPE_GENERIC_SECRET)
23844f4374c8SJens Wiklander TEE_Panic(0);
23854f4374c8SJens Wiklander if ((key_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
23864f4374c8SJens Wiklander TEE_Panic(0);
23874f4374c8SJens Wiklander
23884f4374c8SJens Wiklander __utee_from_gp11_attr(ua, params, paramCount);
23894f4374c8SJens Wiklander res = _utee_cryp_derive_key(operation->state, ua, paramCount,
23904f4374c8SJens Wiklander (unsigned long)derivedKey);
23914f4374c8SJens Wiklander if (res != TEE_SUCCESS)
23924f4374c8SJens Wiklander TEE_Panic(res);
23934f4374c8SJens Wiklander }
23944f4374c8SJens Wiklander
2395b0104773SPascal Brand /* Cryptographic Operations API - Random Number Generation Functions */
2396b0104773SPascal Brand
TEE_GenerateRandom(void * randomBuffer,size_t randomBufferLen)2397411a488aSJens Wiklander void TEE_GenerateRandom(void *randomBuffer, size_t randomBufferLen)
2398b0104773SPascal Brand {
2399b0104773SPascal Brand TEE_Result res;
2400b0104773SPascal Brand
24012c028fdeSJerome Forissier res = _utee_cryp_random_number_generate(randomBuffer, randomBufferLen);
2402b0104773SPascal Brand if (res != TEE_SUCCESS)
2403b0104773SPascal Brand TEE_Panic(res);
2404b0104773SPascal Brand }
2405433c4257SJens Wiklander
__GP11_TEE_GenerateRandom(void * randomBuffer,uint32_t randomBufferLen)2406411a488aSJens Wiklander void __GP11_TEE_GenerateRandom(void *randomBuffer, uint32_t randomBufferLen)
2407411a488aSJens Wiklander {
2408411a488aSJens Wiklander TEE_GenerateRandom(randomBuffer, randomBufferLen);
2409411a488aSJens Wiklander }
2410411a488aSJens Wiklander
rand(void)2411433c4257SJens Wiklander int rand(void)
2412433c4257SJens Wiklander {
2413433c4257SJens Wiklander int rc;
2414433c4257SJens Wiklander
2415433c4257SJens Wiklander TEE_GenerateRandom(&rc, sizeof(rc));
2416433c4257SJens Wiklander
2417433c4257SJens Wiklander /*
2418433c4257SJens Wiklander * RAND_MAX is the larges int, INT_MAX which is all bits but the
2419433c4257SJens Wiklander * highest bit set.
2420433c4257SJens Wiklander */
2421433c4257SJens Wiklander return rc & RAND_MAX;
2422433c4257SJens Wiklander }
242379170ce0SJerome Forissier
TEE_IsAlgorithmSupported(uint32_t alg,uint32_t element)242479170ce0SJerome Forissier TEE_Result TEE_IsAlgorithmSupported(uint32_t alg, uint32_t element)
242579170ce0SJerome Forissier {
242679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_AES)) {
242779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) {
242879170ce0SJerome Forissier if (alg == TEE_ALG_AES_ECB_NOPAD)
242979170ce0SJerome Forissier goto check_element_none;
243079170ce0SJerome Forissier }
243179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) {
243279170ce0SJerome Forissier if (alg == TEE_ALG_AES_CBC_NOPAD)
243379170ce0SJerome Forissier goto check_element_none;
243479170ce0SJerome Forissier }
243579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTR)) {
243679170ce0SJerome Forissier if (alg == TEE_ALG_AES_CTR)
243779170ce0SJerome Forissier goto check_element_none;
243879170ce0SJerome Forissier }
243979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTS)) {
244079170ce0SJerome Forissier if (alg == TEE_ALG_AES_CTS)
244179170ce0SJerome Forissier goto check_element_none;
244279170ce0SJerome Forissier }
244379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_XTS)) {
244479170ce0SJerome Forissier if (alg == TEE_ALG_AES_XTS)
244579170ce0SJerome Forissier goto check_element_none;
244679170ce0SJerome Forissier }
244779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC_MAC)) {
244879170ce0SJerome Forissier if (alg == TEE_ALG_AES_CBC_MAC_NOPAD ||
244979170ce0SJerome Forissier alg == TEE_ALG_AES_CBC_MAC_PKCS5)
245079170ce0SJerome Forissier goto check_element_none;
245179170ce0SJerome Forissier }
245279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CMAC)) {
245379170ce0SJerome Forissier if (alg == TEE_ALG_AES_CMAC)
245479170ce0SJerome Forissier goto check_element_none;
245579170ce0SJerome Forissier }
245679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CCM)) {
245779170ce0SJerome Forissier if (alg == TEE_ALG_AES_CCM)
245879170ce0SJerome Forissier goto check_element_none;
245979170ce0SJerome Forissier }
246079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_GCM)) {
246179170ce0SJerome Forissier if (alg == TEE_ALG_AES_GCM)
246279170ce0SJerome Forissier goto check_element_none;
246379170ce0SJerome Forissier }
246479170ce0SJerome Forissier }
246579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DES)) {
246679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) {
246779170ce0SJerome Forissier if (alg == TEE_ALG_DES_ECB_NOPAD ||
246879170ce0SJerome Forissier alg == TEE_ALG_DES3_ECB_NOPAD)
246979170ce0SJerome Forissier goto check_element_none;
247079170ce0SJerome Forissier }
247179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) {
247279170ce0SJerome Forissier if (alg == TEE_ALG_DES_CBC_NOPAD ||
247379170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_NOPAD)
247479170ce0SJerome Forissier goto check_element_none;
247579170ce0SJerome Forissier }
247679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC_MAC)) {
247779170ce0SJerome Forissier if (alg == TEE_ALG_DES_CBC_MAC_NOPAD ||
247879170ce0SJerome Forissier alg == TEE_ALG_DES_CBC_MAC_PKCS5 ||
247979170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_MAC_NOPAD ||
248079170ce0SJerome Forissier alg == TEE_ALG_DES3_CBC_MAC_PKCS5)
248179170ce0SJerome Forissier goto check_element_none;
248279170ce0SJerome Forissier }
248379170ce0SJerome Forissier }
248479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) {
248579170ce0SJerome Forissier if (alg == TEE_ALG_MD5)
248679170ce0SJerome Forissier goto check_element_none;
248779170ce0SJerome Forissier }
248879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) {
248979170ce0SJerome Forissier if (alg == TEE_ALG_SHA1)
249079170ce0SJerome Forissier goto check_element_none;
249179170ce0SJerome Forissier }
249279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) {
249379170ce0SJerome Forissier if (alg == TEE_ALG_SHA224)
249479170ce0SJerome Forissier goto check_element_none;
249579170ce0SJerome Forissier }
249679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) {
249779170ce0SJerome Forissier if (alg == TEE_ALG_SHA256)
249879170ce0SJerome Forissier goto check_element_none;
249979170ce0SJerome Forissier }
250079170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) {
250179170ce0SJerome Forissier if (alg == TEE_ALG_SHA384)
250279170ce0SJerome Forissier goto check_element_none;
250379170ce0SJerome Forissier }
250479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) {
250579170ce0SJerome Forissier if (alg == TEE_ALG_SHA512)
250679170ce0SJerome Forissier goto check_element_none;
250779170ce0SJerome Forissier }
2508260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_224)) {
2509260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_224)
2510260b4028SJens Wiklander goto check_element_none;
2511260b4028SJens Wiklander }
2512260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_256)) {
2513260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_256)
2514260b4028SJens Wiklander goto check_element_none;
2515260b4028SJens Wiklander }
2516260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_384)) {
2517260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_384)
2518260b4028SJens Wiklander goto check_element_none;
2519260b4028SJens Wiklander }
2520260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_512)) {
2521260b4028SJens Wiklander if (alg == TEE_ALG_SHA3_512)
2522260b4028SJens Wiklander goto check_element_none;
2523260b4028SJens Wiklander }
252479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5) && IS_ENABLED(CFG_CRYPTO_SHA1)) {
252579170ce0SJerome Forissier if (alg == TEE_ALG_MD5SHA1)
252679170ce0SJerome Forissier goto check_element_none;
252779170ce0SJerome Forissier }
252879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_HMAC)) {
252979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) {
253079170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_MD5)
253179170ce0SJerome Forissier goto check_element_none;
253279170ce0SJerome Forissier }
253379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) {
253479170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA1)
253579170ce0SJerome Forissier goto check_element_none;
253679170ce0SJerome Forissier }
253779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) {
253879170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA224)
253979170ce0SJerome Forissier goto check_element_none;
254079170ce0SJerome Forissier }
254179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) {
254279170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA256)
254379170ce0SJerome Forissier goto check_element_none;
254479170ce0SJerome Forissier }
254579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) {
254679170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA384)
254779170ce0SJerome Forissier goto check_element_none;
254879170ce0SJerome Forissier }
254979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) {
255079170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SHA512)
255179170ce0SJerome Forissier goto check_element_none;
255279170ce0SJerome Forissier }
2553260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_224)) {
2554260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_224)
2555260b4028SJens Wiklander goto check_element_none;
2556260b4028SJens Wiklander }
2557260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_256)) {
2558260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_256)
2559260b4028SJens Wiklander goto check_element_none;
2560260b4028SJens Wiklander }
2561260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_384)) {
2562260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_384)
2563260b4028SJens Wiklander goto check_element_none;
2564260b4028SJens Wiklander }
2565260b4028SJens Wiklander if (IS_ENABLED(CFG_CRYPTO_SHA3_512)) {
2566260b4028SJens Wiklander if (alg == TEE_ALG_HMAC_SHA3_512)
2567260b4028SJens Wiklander goto check_element_none;
2568260b4028SJens Wiklander }
256979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM3)) {
257079170ce0SJerome Forissier if (alg == TEE_ALG_HMAC_SM3)
257179170ce0SJerome Forissier goto check_element_none;
257279170ce0SJerome Forissier }
257379170ce0SJerome Forissier }
257479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM3)) {
257579170ce0SJerome Forissier if (alg == TEE_ALG_SM3)
257679170ce0SJerome Forissier goto check_element_none;
257779170ce0SJerome Forissier }
257879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM4)) {
257979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECB)) {
258079170ce0SJerome Forissier if (alg == TEE_ALG_SM4_ECB_NOPAD)
258179170ce0SJerome Forissier goto check_element_none;
258279170ce0SJerome Forissier }
258379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CBC)) {
258479170ce0SJerome Forissier if (alg == TEE_ALG_SM4_CBC_NOPAD)
258579170ce0SJerome Forissier goto check_element_none;
258679170ce0SJerome Forissier }
258779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_CTR)) {
258879170ce0SJerome Forissier if (alg == TEE_ALG_SM4_CTR)
258979170ce0SJerome Forissier goto check_element_none;
259079170ce0SJerome Forissier }
2591696f56acSPingan Xie if (IS_ENABLED(CFG_CRYPTO_XTS)) {
2592696f56acSPingan Xie if (alg == TEE_ALG_SM4_XTS)
2593696f56acSPingan Xie goto check_element_none;
2594696f56acSPingan Xie }
259579170ce0SJerome Forissier }
259679170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_RSA)) {
259779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5)) {
2598f5c3d85aSJulien Masson if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5 ||
2599f5c3d85aSJulien Masson alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_MD5 ||
2600f5c3d85aSJulien Masson alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_MD5)
260179170ce0SJerome Forissier goto check_element_none;
260279170ce0SJerome Forissier }
260379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) {
260479170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA1 ||
260579170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1 ||
260679170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1)
260779170ce0SJerome Forissier goto check_element_none;
260879170ce0SJerome Forissier }
260979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_MD5) && IS_ENABLED(CFG_CRYPTO_SHA1)) {
261079170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5SHA1)
261179170ce0SJerome Forissier goto check_element_none;
261279170ce0SJerome Forissier }
261379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) {
261479170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA224 ||
261579170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224 ||
261679170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224)
261779170ce0SJerome Forissier goto check_element_none;
261879170ce0SJerome Forissier }
261979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) {
262079170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA256 ||
262179170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256 ||
262279170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256)
262379170ce0SJerome Forissier goto check_element_none;
262479170ce0SJerome Forissier }
262579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA384)) {
262679170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA384 ||
262779170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384 ||
262879170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384)
262979170ce0SJerome Forissier goto check_element_none;
263079170ce0SJerome Forissier }
263179170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA512)) {
263279170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA512 ||
263379170ce0SJerome Forissier alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512 ||
263479170ce0SJerome Forissier alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512)
263579170ce0SJerome Forissier goto check_element_none;
263679170ce0SJerome Forissier }
263779170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_RSASSA_NA1)) {
263879170ce0SJerome Forissier if (alg == TEE_ALG_RSASSA_PKCS1_V1_5)
263979170ce0SJerome Forissier goto check_element_none;
264079170ce0SJerome Forissier }
264179170ce0SJerome Forissier if (alg == TEE_ALG_RSA_NOPAD)
264279170ce0SJerome Forissier goto check_element_none;
264379170ce0SJerome Forissier }
264479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DSA)) {
264579170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA1)) {
264679170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA1)
264779170ce0SJerome Forissier goto check_element_none;
264879170ce0SJerome Forissier }
264979170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA224)) {
265079170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA224)
265179170ce0SJerome Forissier goto check_element_none;
265279170ce0SJerome Forissier }
265379170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SHA256)) {
265479170ce0SJerome Forissier if (alg == TEE_ALG_DSA_SHA256)
265579170ce0SJerome Forissier goto check_element_none;
265679170ce0SJerome Forissier }
265779170ce0SJerome Forissier }
265879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_DH)) {
265979170ce0SJerome Forissier if (alg == TEE_ALG_DH_DERIVE_SHARED_SECRET)
266079170ce0SJerome Forissier goto check_element_none;
266179170ce0SJerome Forissier }
266279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_ECC)) {
2663fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P192 ||
2664fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P192 ||
2665fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET ||
2666fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA1) &&
266779170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P192)
266879170ce0SJerome Forissier return TEE_SUCCESS;
2669fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P224 ||
2670fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P224 ||
2671fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET ||
2672fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA224) &&
267379170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P224)
267479170ce0SJerome Forissier return TEE_SUCCESS;
2675fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P256 ||
2676fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P256 ||
2677fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET ||
2678fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA256) &&
267979170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P256)
268079170ce0SJerome Forissier return TEE_SUCCESS;
2681fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P384 ||
2682fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P384 ||
2683fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET ||
2684fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA384) &&
268579170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P384)
268679170ce0SJerome Forissier return TEE_SUCCESS;
2687fe2fd3ffSJens Wiklander if ((alg == __OPTEE_ALG_ECDH_P521 ||
2688fe2fd3ffSJens Wiklander alg == __OPTEE_ALG_ECDSA_P521 ||
2689fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDH_DERIVE_SHARED_SECRET ||
2690fe2fd3ffSJens Wiklander alg == TEE_ALG_ECDSA_SHA512) &&
269179170ce0SJerome Forissier element == TEE_ECC_CURVE_NIST_P521)
269279170ce0SJerome Forissier return TEE_SUCCESS;
269379170ce0SJerome Forissier }
269479170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_DSA)) {
269579170ce0SJerome Forissier if (alg == TEE_ALG_SM2_DSA_SM3 && element == TEE_ECC_CURVE_SM2)
269679170ce0SJerome Forissier return TEE_SUCCESS;
269779170ce0SJerome Forissier }
269879170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_KEP)) {
269979170ce0SJerome Forissier if (alg == TEE_ALG_SM2_KEP && element == TEE_ECC_CURVE_SM2)
270079170ce0SJerome Forissier return TEE_SUCCESS;
270179170ce0SJerome Forissier }
270279170ce0SJerome Forissier if (IS_ENABLED(CFG_CRYPTO_SM2_PKE)) {
270379170ce0SJerome Forissier if (alg == TEE_ALG_SM2_PKE && element == TEE_ECC_CURVE_SM2)
270479170ce0SJerome Forissier return TEE_SUCCESS;
270579170ce0SJerome Forissier }
27063f61056dSSohaib ul Hassan if (IS_ENABLED(CFG_CRYPTO_X25519)) {
27073f61056dSSohaib ul Hassan if (alg == TEE_ALG_X25519 && element == TEE_ECC_CURVE_25519)
27083f61056dSSohaib ul Hassan return TEE_SUCCESS;
27093f61056dSSohaib ul Hassan }
2710e1f9cee7SSergiy Kibrik if (IS_ENABLED(CFG_CRYPTO_ED25519)) {
2711e1f9cee7SSergiy Kibrik if (alg == TEE_ALG_ED25519 && element == TEE_ECC_CURVE_25519)
2712e1f9cee7SSergiy Kibrik return TEE_SUCCESS;
2713e1f9cee7SSergiy Kibrik }
271479170ce0SJerome Forissier
271579170ce0SJerome Forissier return TEE_ERROR_NOT_SUPPORTED;
271679170ce0SJerome Forissier check_element_none:
271779170ce0SJerome Forissier if (element == TEE_CRYPTO_ELEMENT_NONE)
271879170ce0SJerome Forissier return TEE_SUCCESS;
271979170ce0SJerome Forissier return TEE_ERROR_NOT_SUPPORTED;
272079170ce0SJerome Forissier }
2721