xref: /optee_os/ta/pkcs11/src/processing_symm.c (revision 5d2d37cd756d2f5b2342bf7c74b5800b5ed60cc6)
1512cbf1dSJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
2512cbf1dSJens Wiklander /*
3512cbf1dSJens Wiklander  * Copyright (c) 2017-2020, Linaro Limited
4512cbf1dSJens Wiklander  */
5512cbf1dSJens Wiklander 
6512cbf1dSJens Wiklander #include <assert.h>
7512cbf1dSJens Wiklander #include <pkcs11_ta.h>
8512cbf1dSJens Wiklander #include <string.h>
9512cbf1dSJens Wiklander #include <tee_api_defines.h>
10512cbf1dSJens Wiklander #include <tee_internal_api.h>
11512cbf1dSJens Wiklander #include <tee_internal_api_extensions.h>
12512cbf1dSJens Wiklander #include <utee_defines.h>
13512cbf1dSJens Wiklander #include <util.h>
14512cbf1dSJens Wiklander 
15512cbf1dSJens Wiklander #include "attributes.h"
16512cbf1dSJens Wiklander #include "object.h"
17512cbf1dSJens Wiklander #include "pkcs11_attributes.h"
18512cbf1dSJens Wiklander #include "pkcs11_helpers.h"
19512cbf1dSJens Wiklander #include "pkcs11_token.h"
20512cbf1dSJens Wiklander #include "processing.h"
21512cbf1dSJens Wiklander #include "serializer.h"
22512cbf1dSJens Wiklander 
2348799892SRuchika Gupta struct input_data_ref {
2448799892SRuchika Gupta 	size_t size;
2548799892SRuchika Gupta 	void *data;
2648799892SRuchika Gupta };
2748799892SRuchika Gupta 
processing_is_tee_symm(enum pkcs11_mechanism_id proc_id)28512cbf1dSJens Wiklander bool processing_is_tee_symm(enum pkcs11_mechanism_id proc_id)
29512cbf1dSJens Wiklander {
30512cbf1dSJens Wiklander 	switch (proc_id) {
31689f4e5bSRuchika Gupta 	/* Authentication */
320ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC:
33689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
34689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
35689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
36689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
37689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
38689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
390ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC_GENERAL:
4070b6683bSVictor Chong 	case PKCS11_CKM_MD5_HMAC_GENERAL:
4170b6683bSVictor Chong 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
4270b6683bSVictor Chong 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
4370b6683bSVictor Chong 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
4470b6683bSVictor Chong 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
4570b6683bSVictor Chong 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
466f6d5e75SVictor Chong 	/* Ciphering */
47512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
48512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
49512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
50512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
5163778faaSEtienne Carriere 	case PKCS11_CKM_AES_GCM:
5248799892SRuchika Gupta 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
5348799892SRuchika Gupta 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
54512cbf1dSJens Wiklander 		return true;
55512cbf1dSJens Wiklander 	default:
56512cbf1dSJens Wiklander 		return false;
57512cbf1dSJens Wiklander 	}
58512cbf1dSJens Wiklander }
59512cbf1dSJens Wiklander 
60512cbf1dSJens Wiklander static enum pkcs11_rc
pkcs2tee_algorithm(uint32_t * tee_id,struct pkcs11_attribute_head * proc_params)61512cbf1dSJens Wiklander pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params)
62512cbf1dSJens Wiklander {
63512cbf1dSJens Wiklander 	static const struct {
64512cbf1dSJens Wiklander 		enum pkcs11_mechanism_id mech_id;
65512cbf1dSJens Wiklander 		uint32_t tee_id;
66512cbf1dSJens Wiklander 	} pkcs2tee_algo[] = {
67512cbf1dSJens Wiklander 		/* AES flavors */
68512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_ECB, TEE_ALG_AES_ECB_NOPAD },
69512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_CBC, TEE_ALG_AES_CBC_NOPAD },
7048799892SRuchika Gupta 		{ PKCS11_CKM_AES_ECB_ENCRYPT_DATA, TEE_ALG_AES_ECB_NOPAD },
7148799892SRuchika Gupta 		{ PKCS11_CKM_AES_CBC_ENCRYPT_DATA, TEE_ALG_AES_CBC_NOPAD },
72512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_CTR, TEE_ALG_AES_CTR },
73512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_CTS, TEE_ALG_AES_CTS },
7463778faaSEtienne Carriere 		{ PKCS11_CKM_AES_GCM, TEE_ALG_AES_GCM },
750ef6b144SVictor Chong 		{ PKCS11_CKM_AES_CMAC, TEE_ALG_AES_CMAC },
760ef6b144SVictor Chong 		{ PKCS11_CKM_AES_CMAC_GENERAL, TEE_ALG_AES_CMAC },
77689f4e5bSRuchika Gupta 		/* HMAC flavors */
78689f4e5bSRuchika Gupta 		{ PKCS11_CKM_MD5_HMAC, TEE_ALG_HMAC_MD5 },
79689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA_1_HMAC, TEE_ALG_HMAC_SHA1 },
80689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA224_HMAC, TEE_ALG_HMAC_SHA224 },
81689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA256_HMAC, TEE_ALG_HMAC_SHA256 },
82689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA384_HMAC, TEE_ALG_HMAC_SHA384 },
83689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA512_HMAC, TEE_ALG_HMAC_SHA512 },
8470b6683bSVictor Chong 		{ PKCS11_CKM_MD5_HMAC_GENERAL, TEE_ALG_HMAC_MD5 },
8570b6683bSVictor Chong 		{ PKCS11_CKM_SHA_1_HMAC_GENERAL, TEE_ALG_HMAC_SHA1 },
8670b6683bSVictor Chong 		{ PKCS11_CKM_SHA224_HMAC_GENERAL, TEE_ALG_HMAC_SHA224 },
8770b6683bSVictor Chong 		{ PKCS11_CKM_SHA256_HMAC_GENERAL, TEE_ALG_HMAC_SHA256 },
8870b6683bSVictor Chong 		{ PKCS11_CKM_SHA384_HMAC_GENERAL, TEE_ALG_HMAC_SHA384 },
8970b6683bSVictor Chong 		{ PKCS11_CKM_SHA512_HMAC_GENERAL, TEE_ALG_HMAC_SHA512 },
90512cbf1dSJens Wiklander 	};
91512cbf1dSJens Wiklander 	size_t n = 0;
92512cbf1dSJens Wiklander 
93512cbf1dSJens Wiklander 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) {
94512cbf1dSJens Wiklander 		if (proc_params->id == pkcs2tee_algo[n].mech_id) {
95512cbf1dSJens Wiklander 			*tee_id = pkcs2tee_algo[n].tee_id;
96512cbf1dSJens Wiklander 			return PKCS11_CKR_OK;
97512cbf1dSJens Wiklander 		}
98512cbf1dSJens Wiklander 	}
99512cbf1dSJens Wiklander 
100512cbf1dSJens Wiklander 	return PKCS11_RV_NOT_IMPLEMENTED;
101512cbf1dSJens Wiklander }
102512cbf1dSJens Wiklander 
pkcs2tee_key_type(uint32_t * tee_type,struct pkcs11_object * obj)103512cbf1dSJens Wiklander static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type,
104512cbf1dSJens Wiklander 					struct pkcs11_object *obj)
105512cbf1dSJens Wiklander {
106512cbf1dSJens Wiklander 	static const struct {
107512cbf1dSJens Wiklander 		enum pkcs11_key_type key_type;
108512cbf1dSJens Wiklander 		uint32_t tee_id;
109512cbf1dSJens Wiklander 	} pkcs2tee_key_type[] = {
110512cbf1dSJens Wiklander 		{ PKCS11_CKK_AES, TEE_TYPE_AES },
111512cbf1dSJens Wiklander 		{ PKCS11_CKK_GENERIC_SECRET, TEE_TYPE_GENERIC_SECRET },
112512cbf1dSJens Wiklander 		{ PKCS11_CKK_MD5_HMAC, TEE_TYPE_HMAC_MD5 },
113512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 },
114512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 },
115512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 },
116512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 },
117512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 },
118512cbf1dSJens Wiklander 	};
119512cbf1dSJens Wiklander 	size_t n = 0;
120512cbf1dSJens Wiklander 	enum pkcs11_key_type key_type = get_key_type(obj->attributes);
121512cbf1dSJens Wiklander 
122512cbf1dSJens Wiklander 	assert(get_class(obj->attributes) == PKCS11_CKO_SECRET_KEY);
123512cbf1dSJens Wiklander 
124512cbf1dSJens Wiklander 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) {
125512cbf1dSJens Wiklander 		if (pkcs2tee_key_type[n].key_type == key_type) {
126512cbf1dSJens Wiklander 			*tee_type = pkcs2tee_key_type[n].tee_id;
127512cbf1dSJens Wiklander 			return PKCS11_CKR_OK;
128512cbf1dSJens Wiklander 		}
129512cbf1dSJens Wiklander 	}
130512cbf1dSJens Wiklander 
131512cbf1dSJens Wiklander 	return PKCS11_RV_NOT_FOUND;
132512cbf1dSJens Wiklander }
133512cbf1dSJens Wiklander 
pkcsmech2tee_key_type(uint32_t * tee_type,enum pkcs11_mechanism_id mech_id)134de94d6f8SRuchika Gupta static enum pkcs11_rc pkcsmech2tee_key_type(uint32_t *tee_type,
135de94d6f8SRuchika Gupta 					    enum pkcs11_mechanism_id mech_id)
136de94d6f8SRuchika Gupta {
137de94d6f8SRuchika Gupta 	static const struct {
138de94d6f8SRuchika Gupta 		enum pkcs11_mechanism_id mech;
139de94d6f8SRuchika Gupta 		uint32_t tee_id;
140de94d6f8SRuchika Gupta 	} pkcs2tee_key_type[] = {
141de94d6f8SRuchika Gupta 		{ PKCS11_CKM_MD5_HMAC, TEE_TYPE_HMAC_MD5 },
142de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 },
143de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 },
144de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 },
145de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 },
146de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 },
14770b6683bSVictor Chong 		{ PKCS11_CKM_MD5_HMAC_GENERAL, TEE_TYPE_HMAC_MD5 },
14870b6683bSVictor Chong 		{ PKCS11_CKM_SHA_1_HMAC_GENERAL, TEE_TYPE_HMAC_SHA1 },
14970b6683bSVictor Chong 		{ PKCS11_CKM_SHA224_HMAC_GENERAL, TEE_TYPE_HMAC_SHA224 },
15070b6683bSVictor Chong 		{ PKCS11_CKM_SHA256_HMAC_GENERAL, TEE_TYPE_HMAC_SHA256 },
15170b6683bSVictor Chong 		{ PKCS11_CKM_SHA384_HMAC_GENERAL, TEE_TYPE_HMAC_SHA384 },
15270b6683bSVictor Chong 		{ PKCS11_CKM_SHA512_HMAC_GENERAL, TEE_TYPE_HMAC_SHA512 },
153de94d6f8SRuchika Gupta 	};
154de94d6f8SRuchika Gupta 	size_t n = 0;
155de94d6f8SRuchika Gupta 
156de94d6f8SRuchika Gupta 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) {
157de94d6f8SRuchika Gupta 		if (pkcs2tee_key_type[n].mech == mech_id) {
158de94d6f8SRuchika Gupta 			*tee_type = pkcs2tee_key_type[n].tee_id;
159de94d6f8SRuchika Gupta 			return PKCS11_CKR_OK;
160de94d6f8SRuchika Gupta 		}
161de94d6f8SRuchika Gupta 	}
162de94d6f8SRuchika Gupta 
163de94d6f8SRuchika Gupta 	return PKCS11_RV_NOT_FOUND;
164de94d6f8SRuchika Gupta }
165de94d6f8SRuchika Gupta 
hmac_to_tee_hash(uint32_t * algo,enum pkcs11_mechanism_id mech_id)1662158ea6cSRuchika Gupta static enum pkcs11_rc hmac_to_tee_hash(uint32_t *algo,
1672158ea6cSRuchika Gupta 				       enum pkcs11_mechanism_id mech_id)
1682158ea6cSRuchika Gupta {
1692158ea6cSRuchika Gupta 	static const struct {
1702158ea6cSRuchika Gupta 		enum pkcs11_mechanism_id mech;
1712158ea6cSRuchika Gupta 		uint32_t tee_id;
1722158ea6cSRuchika Gupta 	} hmac_hash[] = {
1732158ea6cSRuchika Gupta 		{ PKCS11_CKM_MD5_HMAC, TEE_ALG_MD5 },
1742158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA_1_HMAC, TEE_ALG_SHA1 },
1752158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA224_HMAC, TEE_ALG_SHA224 },
1762158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA256_HMAC, TEE_ALG_SHA256 },
1772158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA384_HMAC, TEE_ALG_SHA384 },
1782158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA512_HMAC, TEE_ALG_SHA512 },
17970b6683bSVictor Chong 		{ PKCS11_CKM_MD5_HMAC_GENERAL, TEE_ALG_MD5 },
18070b6683bSVictor Chong 		{ PKCS11_CKM_SHA_1_HMAC_GENERAL, TEE_ALG_SHA1 },
18170b6683bSVictor Chong 		{ PKCS11_CKM_SHA224_HMAC_GENERAL, TEE_ALG_SHA224 },
18270b6683bSVictor Chong 		{ PKCS11_CKM_SHA256_HMAC_GENERAL, TEE_ALG_SHA256 },
18370b6683bSVictor Chong 		{ PKCS11_CKM_SHA384_HMAC_GENERAL, TEE_ALG_SHA384 },
18470b6683bSVictor Chong 		{ PKCS11_CKM_SHA512_HMAC_GENERAL, TEE_ALG_SHA512 },
1852158ea6cSRuchika Gupta 	};
1862158ea6cSRuchika Gupta 	size_t n = 0;
1872158ea6cSRuchika Gupta 
1882158ea6cSRuchika Gupta 	for (n = 0; n < ARRAY_SIZE(hmac_hash); n++) {
1892158ea6cSRuchika Gupta 		if (hmac_hash[n].mech == mech_id) {
1902158ea6cSRuchika Gupta 			*algo = hmac_hash[n].tee_id;
1912158ea6cSRuchika Gupta 			return PKCS11_CKR_OK;
1922158ea6cSRuchika Gupta 		}
1932158ea6cSRuchika Gupta 	}
1942158ea6cSRuchika Gupta 
1952158ea6cSRuchika Gupta 	return PKCS11_RV_NOT_FOUND;
1962158ea6cSRuchika Gupta }
1972158ea6cSRuchika Gupta 
198512cbf1dSJens Wiklander static enum pkcs11_rc
allocate_tee_operation(struct pkcs11_session * session,enum processing_func function,struct pkcs11_attribute_head * params,struct pkcs11_object * obj)199512cbf1dSJens Wiklander allocate_tee_operation(struct pkcs11_session *session,
200512cbf1dSJens Wiklander 		       enum processing_func function,
201512cbf1dSJens Wiklander 		       struct pkcs11_attribute_head *params,
202512cbf1dSJens Wiklander 		       struct pkcs11_object *obj)
203512cbf1dSJens Wiklander {
204512cbf1dSJens Wiklander 	uint32_t size = (uint32_t)get_object_key_bit_size(obj);
205460ba621SRuchika Gupta 	uint32_t key_size = size / 8;
206512cbf1dSJens Wiklander 	uint32_t algo = 0;
207512cbf1dSJens Wiklander 	uint32_t mode = 0;
208460ba621SRuchika Gupta 	uint32_t max_key_size = 0;
209460ba621SRuchika Gupta 	uint32_t min_key_size = 0;
210512cbf1dSJens Wiklander 	TEE_Result res = TEE_ERROR_GENERIC;
211512cbf1dSJens Wiklander 
21263778faaSEtienne Carriere 	assert(session->processing->tee_op_handle == TEE_HANDLE_NULL &&
21363778faaSEtienne Carriere 	       session->processing->tee_op_handle2 == TEE_HANDLE_NULL);
214512cbf1dSJens Wiklander 
215512cbf1dSJens Wiklander 	if (pkcs2tee_algorithm(&algo, params))
216512cbf1dSJens Wiklander 		return PKCS11_CKR_FUNCTION_FAILED;
217512cbf1dSJens Wiklander 
218512cbf1dSJens Wiklander 	/* Sign/Verify with AES or generic key relate to TEE MAC operation */
219689f4e5bSRuchika Gupta 	switch (params->id) {
220689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
221689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
222689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
223689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
224689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
225689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
22670b6683bSVictor Chong 	case PKCS11_CKM_MD5_HMAC_GENERAL:
22770b6683bSVictor Chong 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
22870b6683bSVictor Chong 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
22970b6683bSVictor Chong 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
23070b6683bSVictor Chong 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
23170b6683bSVictor Chong 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
2322d0cd829SRuchika Gupta 		mechanism_supported_key_sizes_bytes(params->id, &min_key_size,
233460ba621SRuchika Gupta 						    &max_key_size);
234460ba621SRuchika Gupta 		if (key_size < min_key_size)
235460ba621SRuchika Gupta 			return PKCS11_CKR_KEY_SIZE_RANGE;
2362158ea6cSRuchika Gupta 
2372158ea6cSRuchika Gupta 		/*
2382158ea6cSRuchika Gupta 		 * If size of generic key is greater than the size
2392158ea6cSRuchika Gupta 		 * supported by TEE API, this is not considered an
2402158ea6cSRuchika Gupta 		 * error. When loading TEE key, we will hash the key
2412158ea6cSRuchika Gupta 		 * to generate the appropriate key for HMAC operation.
2422158ea6cSRuchika Gupta 		 * This key size will not be greater than the
2432158ea6cSRuchika Gupta 		 * max_key_size. So we can use max_key_size for
2442158ea6cSRuchika Gupta 		 * TEE_AllocateOperation().
2452158ea6cSRuchika Gupta 		 */
2462158ea6cSRuchika Gupta 		if (key_size > max_key_size)
2472158ea6cSRuchika Gupta 			size = max_key_size * 8;
2482158ea6cSRuchika Gupta 
249689f4e5bSRuchika Gupta 		mode = TEE_MODE_MAC;
250689f4e5bSRuchika Gupta 		break;
2510ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC:
2520ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC_GENERAL:
2530ef6b144SVictor Chong 		mode = TEE_MODE_MAC;
2540ef6b144SVictor Chong 		break;
255689f4e5bSRuchika Gupta 	default:
256512cbf1dSJens Wiklander 		pkcs2tee_mode(&mode, function);
257689f4e5bSRuchika Gupta 		break;
258689f4e5bSRuchika Gupta 	}
259512cbf1dSJens Wiklander 
260512cbf1dSJens Wiklander 	res = TEE_AllocateOperation(&session->processing->tee_op_handle,
261512cbf1dSJens Wiklander 				    algo, mode, size);
262512cbf1dSJens Wiklander 	if (res)
263512cbf1dSJens Wiklander 		EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32,
264512cbf1dSJens Wiklander 		     algo, mode, size);
265512cbf1dSJens Wiklander 
266512cbf1dSJens Wiklander 	if (res == TEE_ERROR_NOT_SUPPORTED)
267512cbf1dSJens Wiklander 		return PKCS11_CKR_MECHANISM_INVALID;
268512cbf1dSJens Wiklander 
26963778faaSEtienne Carriere 	if (res == TEE_SUCCESS || params->id == PKCS11_CKM_AES_GCM) {
27063778faaSEtienne Carriere 		/*
27163778faaSEtienne Carriere 		 * Allocate a 2nd operation handler to save the operation state
27263778faaSEtienne Carriere 		 * on AES GCM one-shot processing that queries the output
27363778faaSEtienne Carriere 		 * buffer size. This is needed as we will need to reset and
27463778faaSEtienne Carriere 		 * re-init the TEE operation once we report the expected output
27563778faaSEtienne Carriere 		 * buffer size to client that we call again the AE processing
27663778faaSEtienne Carriere 		 * function.
27763778faaSEtienne Carriere 		 */
27863778faaSEtienne Carriere 		TEE_OperationHandle *hdl = &session->processing->tee_op_handle2;
27963778faaSEtienne Carriere 
28063778faaSEtienne Carriere 		res = TEE_AllocateOperation(hdl, algo, mode, size);
28163778faaSEtienne Carriere 	}
28263778faaSEtienne Carriere 
283512cbf1dSJens Wiklander 	return tee2pkcs_error(res);
284512cbf1dSJens Wiklander }
285512cbf1dSJens Wiklander 
hash_secret_helper(enum pkcs11_mechanism_id mech_id,struct pkcs11_object * obj,TEE_Attribute * tee_attr,void ** ctx,size_t * object_size_bits)2862158ea6cSRuchika Gupta static enum pkcs11_rc hash_secret_helper(enum pkcs11_mechanism_id mech_id,
2872158ea6cSRuchika Gupta 					 struct pkcs11_object *obj,
2882158ea6cSRuchika Gupta 					 TEE_Attribute *tee_attr,
2892158ea6cSRuchika Gupta 					 void **ctx,
2902158ea6cSRuchika Gupta 					 size_t *object_size_bits)
2912158ea6cSRuchika Gupta {
2922158ea6cSRuchika Gupta 	uint32_t algo = 0;
2932158ea6cSRuchika Gupta 	void *hash_ptr = NULL;
2942158ea6cSRuchika Gupta 	uint32_t hash_size = 0;
2952158ea6cSRuchika Gupta 	enum pkcs11_rc rc = PKCS11_CKR_OK;
2962158ea6cSRuchika Gupta 
2972158ea6cSRuchika Gupta 	rc = hmac_to_tee_hash(&algo, mech_id);
2982158ea6cSRuchika Gupta 	if (rc)
2992158ea6cSRuchika Gupta 		return rc;
3002158ea6cSRuchika Gupta 
3012158ea6cSRuchika Gupta 	hash_size = TEE_ALG_GET_DIGEST_SIZE(algo);
3022158ea6cSRuchika Gupta 	hash_ptr = TEE_Malloc(hash_size, 0);
3032158ea6cSRuchika Gupta 	if (!hash_ptr)
3042158ea6cSRuchika Gupta 		return PKCS11_CKR_DEVICE_MEMORY;
3052158ea6cSRuchika Gupta 
3062158ea6cSRuchika Gupta 	rc = pkcs2tee_load_hashed_attr(tee_attr, TEE_ATTR_SECRET_VALUE, obj,
3072158ea6cSRuchika Gupta 				       PKCS11_CKA_VALUE, algo, hash_ptr,
3082158ea6cSRuchika Gupta 				       &hash_size);
3092158ea6cSRuchika Gupta 	if (rc) {
3102158ea6cSRuchika Gupta 		EMSG("No secret/hash error");
3112158ea6cSRuchika Gupta 		TEE_Free(hash_ptr);
3122158ea6cSRuchika Gupta 		return rc;
3132158ea6cSRuchika Gupta 	}
3142158ea6cSRuchika Gupta 
3152158ea6cSRuchika Gupta 	*ctx = hash_ptr;
3162158ea6cSRuchika Gupta 
3172158ea6cSRuchika Gupta 	*object_size_bits = hash_size * 8;
3182158ea6cSRuchika Gupta 
3192158ea6cSRuchika Gupta 	return PKCS11_CKR_OK;
3202158ea6cSRuchika Gupta }
3212158ea6cSRuchika Gupta 
load_tee_key(struct pkcs11_session * session,struct pkcs11_object * obj,struct pkcs11_attribute_head * proc_params)322512cbf1dSJens Wiklander static enum pkcs11_rc load_tee_key(struct pkcs11_session *session,
323de94d6f8SRuchika Gupta 				   struct pkcs11_object *obj,
324de94d6f8SRuchika Gupta 				   struct pkcs11_attribute_head *proc_params)
325512cbf1dSJens Wiklander {
326512cbf1dSJens Wiklander 	TEE_Attribute tee_attr = { };
327512cbf1dSJens Wiklander 	size_t object_size = 0;
328512cbf1dSJens Wiklander 	uint32_t tee_key_type = 0;
329de94d6f8SRuchika Gupta 	enum pkcs11_key_type key_type = 0;
330512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
331512cbf1dSJens Wiklander 	TEE_Result res = TEE_ERROR_GENERIC;
3322158ea6cSRuchika Gupta 	uint32_t max_key_size = 0;
3332158ea6cSRuchika Gupta 	uint32_t min_key_size = 0;
334512cbf1dSJens Wiklander 
335512cbf1dSJens Wiklander 	if (obj->key_handle != TEE_HANDLE_NULL) {
336512cbf1dSJens Wiklander 		/* Key was already loaded and fits current need */
337512cbf1dSJens Wiklander 		goto key_ready;
338512cbf1dSJens Wiklander 	}
339512cbf1dSJens Wiklander 
3402158ea6cSRuchika Gupta 	object_size = get_object_key_bit_size(obj);
3412158ea6cSRuchika Gupta 	if (!object_size)
3422158ea6cSRuchika Gupta 		return PKCS11_CKR_GENERAL_ERROR;
343512cbf1dSJens Wiklander 
344de94d6f8SRuchika Gupta 	switch (proc_params->id) {
345de94d6f8SRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
346de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
347de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
348de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
349de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
350de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
35170b6683bSVictor Chong 	case PKCS11_CKM_MD5_HMAC_GENERAL:
35270b6683bSVictor Chong 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
35370b6683bSVictor Chong 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
35470b6683bSVictor Chong 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
35570b6683bSVictor Chong 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
35670b6683bSVictor Chong 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
357de94d6f8SRuchika Gupta 		key_type = get_key_type(obj->attributes);
358de94d6f8SRuchika Gupta 		/*
359de94d6f8SRuchika Gupta 		 * If Object Key type is PKCS11_CKK_GENERIC_SECRET,
360de94d6f8SRuchika Gupta 		 * determine the tee_key_type using the
361de94d6f8SRuchika Gupta 		 * mechanism instead of object key_type.
362de94d6f8SRuchika Gupta 		 */
363de94d6f8SRuchika Gupta 		if (key_type == PKCS11_CKK_GENERIC_SECRET)
364de94d6f8SRuchika Gupta 			rc = pkcsmech2tee_key_type(&tee_key_type,
365de94d6f8SRuchika Gupta 						   proc_params->id);
366de94d6f8SRuchika Gupta 		else
367512cbf1dSJens Wiklander 			rc = pkcs2tee_key_type(&tee_key_type, obj);
368de94d6f8SRuchika Gupta 
369512cbf1dSJens Wiklander 		if (rc)
370512cbf1dSJens Wiklander 			return rc;
371512cbf1dSJens Wiklander 
3722d0cd829SRuchika Gupta 		mechanism_supported_key_sizes_bytes(proc_params->id,
3732158ea6cSRuchika Gupta 						    &min_key_size,
3742158ea6cSRuchika Gupta 						    &max_key_size);
3752158ea6cSRuchika Gupta 
3762158ea6cSRuchika Gupta 		if ((object_size / 8) > max_key_size) {
3772158ea6cSRuchika Gupta 			rc = hash_secret_helper(proc_params->id, obj, &tee_attr,
3782158ea6cSRuchika Gupta 						&session->processing->extra_ctx,
3792158ea6cSRuchika Gupta 						&object_size);
3802158ea6cSRuchika Gupta 			if (rc)
3812158ea6cSRuchika Gupta 				return rc;
3822158ea6cSRuchika Gupta 		} else {
3832158ea6cSRuchika Gupta 			if (!pkcs2tee_load_attr(&tee_attr,
3842158ea6cSRuchika Gupta 						TEE_ATTR_SECRET_VALUE,
3852158ea6cSRuchika Gupta 						obj,
3862158ea6cSRuchika Gupta 						PKCS11_CKA_VALUE)) {
3872158ea6cSRuchika Gupta 				EMSG("No secret found");
3882158ea6cSRuchika Gupta 				return PKCS11_CKR_FUNCTION_FAILED;
3892158ea6cSRuchika Gupta 			}
3902158ea6cSRuchika Gupta 		}
3912158ea6cSRuchika Gupta 		break;
3922158ea6cSRuchika Gupta 
3932158ea6cSRuchika Gupta 	default:
3942158ea6cSRuchika Gupta 		rc = pkcs2tee_key_type(&tee_key_type, obj);
3952158ea6cSRuchika Gupta 		if (rc)
3962158ea6cSRuchika Gupta 			return rc;
3972158ea6cSRuchika Gupta 
3982158ea6cSRuchika Gupta 		if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE,
3992158ea6cSRuchika Gupta 					obj, PKCS11_CKA_VALUE)) {
4002158ea6cSRuchika Gupta 			EMSG("No secret found");
4012158ea6cSRuchika Gupta 			return PKCS11_CKR_FUNCTION_FAILED;
4022158ea6cSRuchika Gupta 		}
4032158ea6cSRuchika Gupta 		break;
4042158ea6cSRuchika Gupta 	}
405512cbf1dSJens Wiklander 
406512cbf1dSJens Wiklander 	res = TEE_AllocateTransientObject(tee_key_type, object_size,
407512cbf1dSJens Wiklander 					  &obj->key_handle);
408512cbf1dSJens Wiklander 	if (res) {
409512cbf1dSJens Wiklander 		DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res);
410512cbf1dSJens Wiklander 		return tee2pkcs_error(res);
411512cbf1dSJens Wiklander 	}
412512cbf1dSJens Wiklander 
413512cbf1dSJens Wiklander 	res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1);
414512cbf1dSJens Wiklander 	if (res) {
415512cbf1dSJens Wiklander 		DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res);
416512cbf1dSJens Wiklander 		goto error;
417512cbf1dSJens Wiklander 	}
418512cbf1dSJens Wiklander 
419512cbf1dSJens Wiklander key_ready:
420512cbf1dSJens Wiklander 	res = TEE_SetOperationKey(session->processing->tee_op_handle,
421512cbf1dSJens Wiklander 				  obj->key_handle);
422512cbf1dSJens Wiklander 	if (res) {
423512cbf1dSJens Wiklander 		DMSG("TEE_SetOperationKey failed, %#"PRIx32, res);
424512cbf1dSJens Wiklander 		goto error;
425512cbf1dSJens Wiklander 	}
426512cbf1dSJens Wiklander 
427512cbf1dSJens Wiklander 	return PKCS11_CKR_OK;
428512cbf1dSJens Wiklander 
429512cbf1dSJens Wiklander error:
430512cbf1dSJens Wiklander 	TEE_FreeTransientObject(obj->key_handle);
431512cbf1dSJens Wiklander 	obj->key_handle = TEE_HANDLE_NULL;
432512cbf1dSJens Wiklander 
433512cbf1dSJens Wiklander 	return tee2pkcs_error(res);
434512cbf1dSJens Wiklander }
435512cbf1dSJens Wiklander 
436512cbf1dSJens Wiklander static enum pkcs11_rc
tee_init_derive_symm(struct active_processing * processing,struct pkcs11_attribute_head * proc_params)43748799892SRuchika Gupta tee_init_derive_symm(struct active_processing *processing,
43848799892SRuchika Gupta 		     struct pkcs11_attribute_head *proc_params)
43948799892SRuchika Gupta {
44048799892SRuchika Gupta 	struct serialargs args = { };
44148799892SRuchika Gupta 	enum pkcs11_rc rc = PKCS11_CKR_OK;
44248799892SRuchika Gupta 	struct input_data_ref *param = NULL;
44348799892SRuchika Gupta 	void *iv = NULL;
44448799892SRuchika Gupta 
44548799892SRuchika Gupta 	if (!proc_params)
44648799892SRuchika Gupta 		return PKCS11_CKR_ARGUMENTS_BAD;
44748799892SRuchika Gupta 
44848799892SRuchika Gupta 	param =	TEE_Malloc(sizeof(struct input_data_ref), TEE_MALLOC_FILL_ZERO);
44948799892SRuchika Gupta 	if (!param)
45048799892SRuchika Gupta 		return PKCS11_CKR_DEVICE_MEMORY;
45148799892SRuchika Gupta 
45248799892SRuchika Gupta 	serialargs_init(&args, proc_params->data, proc_params->size);
45348799892SRuchika Gupta 
45448799892SRuchika Gupta 	switch (proc_params->id) {
45548799892SRuchika Gupta 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
45648799892SRuchika Gupta 		rc = serialargs_get_ptr(&args, &iv, 16);
45748799892SRuchika Gupta 		if (rc)
45848799892SRuchika Gupta 			goto err;
45948799892SRuchika Gupta 		break;
46048799892SRuchika Gupta 	default:
46148799892SRuchika Gupta 		break;
46248799892SRuchika Gupta 	}
46348799892SRuchika Gupta 
46448799892SRuchika Gupta 	rc = serialargs_get(&args, &param->size, sizeof(uint32_t));
46548799892SRuchika Gupta 	if (rc)
46648799892SRuchika Gupta 		goto err;
46748799892SRuchika Gupta 
46848799892SRuchika Gupta 	rc = serialargs_get_ptr(&args, &param->data, param->size);
46948799892SRuchika Gupta 	if (rc)
47048799892SRuchika Gupta 		goto err;
47148799892SRuchika Gupta 
47248799892SRuchika Gupta 	if (serialargs_remaining_bytes(&args)) {
47348799892SRuchika Gupta 		rc = PKCS11_CKR_ARGUMENTS_BAD;
47448799892SRuchika Gupta 		goto err;
47548799892SRuchika Gupta 	}
47648799892SRuchika Gupta 
47748799892SRuchika Gupta 	processing->extra_ctx = param;
47848799892SRuchika Gupta 
47948799892SRuchika Gupta 	switch (proc_params->id) {
48048799892SRuchika Gupta 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
48148799892SRuchika Gupta 		if (param->size % TEE_AES_BLOCK_SIZE) {
48248799892SRuchika Gupta 			rc = PKCS11_CKR_DATA_LEN_RANGE;
48348799892SRuchika Gupta 			goto err;
48448799892SRuchika Gupta 		}
48548799892SRuchika Gupta 		TEE_CipherInit(processing->tee_op_handle, NULL, 0);
48648799892SRuchika Gupta 		break;
48748799892SRuchika Gupta 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
48848799892SRuchika Gupta 		if (param->size % TEE_AES_BLOCK_SIZE) {
48948799892SRuchika Gupta 			rc = PKCS11_CKR_DATA_LEN_RANGE;
49048799892SRuchika Gupta 			goto err;
49148799892SRuchika Gupta 		}
49248799892SRuchika Gupta 		TEE_CipherInit(processing->tee_op_handle, iv, 16);
49348799892SRuchika Gupta 		break;
49448799892SRuchika Gupta 	default:
49548799892SRuchika Gupta 		TEE_Panic(proc_params->id);
49648799892SRuchika Gupta 		break;
49748799892SRuchika Gupta 	}
49848799892SRuchika Gupta 
49948799892SRuchika Gupta 	return PKCS11_CKR_OK;
50048799892SRuchika Gupta 
50148799892SRuchika Gupta err:
50248799892SRuchika Gupta 	processing->extra_ctx = NULL;
50348799892SRuchika Gupta 	TEE_Free(param);
50448799892SRuchika Gupta 	return rc;
50548799892SRuchika Gupta }
50648799892SRuchika Gupta 
50748799892SRuchika Gupta static enum pkcs11_rc
input_hmac_len_is_valid(struct pkcs11_attribute_head * proc_params,uint32_t hmac_len)50870b6683bSVictor Chong input_hmac_len_is_valid(struct pkcs11_attribute_head *proc_params,
50970b6683bSVictor Chong 			uint32_t hmac_len)
51070b6683bSVictor Chong {
51170b6683bSVictor Chong 	uint32_t sign_sz = 0;
51270b6683bSVictor Chong 
51370b6683bSVictor Chong 	switch (proc_params->id) {
51470b6683bSVictor Chong 	case PKCS11_CKM_MD5_HMAC_GENERAL:
51570b6683bSVictor Chong 		sign_sz = TEE_MD5_HASH_SIZE;
51670b6683bSVictor Chong 		break;
51770b6683bSVictor Chong 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
51870b6683bSVictor Chong 		sign_sz = TEE_SHA1_HASH_SIZE;
51970b6683bSVictor Chong 		break;
52070b6683bSVictor Chong 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
52170b6683bSVictor Chong 		sign_sz = TEE_SHA224_HASH_SIZE;
52270b6683bSVictor Chong 		break;
52370b6683bSVictor Chong 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
52470b6683bSVictor Chong 		sign_sz = TEE_SHA256_HASH_SIZE;
52570b6683bSVictor Chong 		break;
52670b6683bSVictor Chong 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
52770b6683bSVictor Chong 		sign_sz = TEE_SHA384_HASH_SIZE;
52870b6683bSVictor Chong 		break;
52970b6683bSVictor Chong 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
53070b6683bSVictor Chong 		sign_sz = TEE_SHA512_HASH_SIZE;
53170b6683bSVictor Chong 		break;
5320ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC_GENERAL:
5330ef6b144SVictor Chong 		sign_sz = TEE_AES_BLOCK_SIZE;
5340ef6b144SVictor Chong 		break;
53570b6683bSVictor Chong 	default:
53670b6683bSVictor Chong 		return PKCS11_CKR_MECHANISM_INVALID;
53770b6683bSVictor Chong 	}
53870b6683bSVictor Chong 
53970b6683bSVictor Chong 	if (!hmac_len || hmac_len > sign_sz)
54070b6683bSVictor Chong 		return PKCS11_CKR_SIGNATURE_LEN_RANGE;
54170b6683bSVictor Chong 
54270b6683bSVictor Chong 	return PKCS11_CKR_OK;
54370b6683bSVictor Chong }
54470b6683bSVictor Chong 
54570b6683bSVictor Chong static enum pkcs11_rc
init_tee_operation(struct pkcs11_session * session,struct pkcs11_attribute_head * proc_params)546512cbf1dSJens Wiklander init_tee_operation(struct pkcs11_session *session,
547512cbf1dSJens Wiklander 		   struct pkcs11_attribute_head *proc_params)
548512cbf1dSJens Wiklander {
549512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
55070b6683bSVictor Chong 	uint32_t *pkcs11_data = NULL;
551512cbf1dSJens Wiklander 
552512cbf1dSJens Wiklander 	switch (proc_params->id) {
5530ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC:
554689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
555689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
556689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
557689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
558689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
559689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
560689f4e5bSRuchika Gupta 		if (proc_params->size)
561689f4e5bSRuchika Gupta 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
562689f4e5bSRuchika Gupta 
563689f4e5bSRuchika Gupta 		TEE_MACInit(session->processing->tee_op_handle, NULL, 0);
564689f4e5bSRuchika Gupta 		rc = PKCS11_CKR_OK;
565689f4e5bSRuchika Gupta 		break;
5660ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC_GENERAL:
56770b6683bSVictor Chong 	case PKCS11_CKM_MD5_HMAC_GENERAL:
56870b6683bSVictor Chong 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
56970b6683bSVictor Chong 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
57070b6683bSVictor Chong 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
57170b6683bSVictor Chong 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
57270b6683bSVictor Chong 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
57370b6683bSVictor Chong 		if (proc_params->size != sizeof(uint32_t))
57470b6683bSVictor Chong 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
57570b6683bSVictor Chong 
57670b6683bSVictor Chong 		pkcs11_data = TEE_Malloc(sizeof(uint32_t),
57770b6683bSVictor Chong 					 TEE_MALLOC_FILL_ZERO);
57870b6683bSVictor Chong 		if (!pkcs11_data)
57970b6683bSVictor Chong 			return PKCS11_CKR_DEVICE_MEMORY;
58070b6683bSVictor Chong 
58170b6683bSVictor Chong 		TEE_MemMove(pkcs11_data, proc_params->data, sizeof(uint32_t));
58270b6683bSVictor Chong 
58370b6683bSVictor Chong 		rc = input_hmac_len_is_valid(proc_params, *pkcs11_data);
58470b6683bSVictor Chong 		if (rc) {
58570b6683bSVictor Chong 			TEE_Free(pkcs11_data);
58670b6683bSVictor Chong 			return rc;
58770b6683bSVictor Chong 		}
58870b6683bSVictor Chong 
58970b6683bSVictor Chong 		session->processing->extra_ctx = (void *)pkcs11_data;
59070b6683bSVictor Chong 
59170b6683bSVictor Chong 		TEE_MACInit(session->processing->tee_op_handle, NULL, 0);
59270b6683bSVictor Chong 		rc = PKCS11_CKR_OK;
59370b6683bSVictor Chong 		break;
594512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
595512cbf1dSJens Wiklander 		if (proc_params->size)
596512cbf1dSJens Wiklander 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
597512cbf1dSJens Wiklander 
598512cbf1dSJens Wiklander 		TEE_CipherInit(session->processing->tee_op_handle, NULL, 0);
599512cbf1dSJens Wiklander 		rc = PKCS11_CKR_OK;
600512cbf1dSJens Wiklander 		break;
601512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
602512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
603512cbf1dSJens Wiklander 		if (proc_params->size != 16)
604512cbf1dSJens Wiklander 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
605512cbf1dSJens Wiklander 
606512cbf1dSJens Wiklander 		TEE_CipherInit(session->processing->tee_op_handle,
607512cbf1dSJens Wiklander 			       proc_params->data, 16);
608512cbf1dSJens Wiklander 		rc = PKCS11_CKR_OK;
609512cbf1dSJens Wiklander 		break;
610512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
611512cbf1dSJens Wiklander 		rc = tee_init_ctr_operation(session->processing,
612512cbf1dSJens Wiklander 					    proc_params->data,
613512cbf1dSJens Wiklander 					    proc_params->size);
614512cbf1dSJens Wiklander 		break;
61563778faaSEtienne Carriere 	case PKCS11_CKM_AES_GCM:
61663778faaSEtienne Carriere 		rc = tee_init_gcm_operation(session,
61763778faaSEtienne Carriere 					    proc_params->data,
61863778faaSEtienne Carriere 					    proc_params->size);
61963778faaSEtienne Carriere 		break;
62048799892SRuchika Gupta 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
62148799892SRuchika Gupta 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
62248799892SRuchika Gupta 		rc = tee_init_derive_symm(session->processing, proc_params);
62348799892SRuchika Gupta 		break;
624512cbf1dSJens Wiklander 	default:
625512cbf1dSJens Wiklander 		TEE_Panic(proc_params->id);
626512cbf1dSJens Wiklander 		break;
627512cbf1dSJens Wiklander 	}
628512cbf1dSJens Wiklander 
629512cbf1dSJens Wiklander 	return rc;
630512cbf1dSJens Wiklander }
631512cbf1dSJens Wiklander 
init_symm_operation(struct pkcs11_session * session,enum processing_func function,struct pkcs11_attribute_head * proc_params,struct pkcs11_object * obj)632512cbf1dSJens Wiklander enum pkcs11_rc init_symm_operation(struct pkcs11_session *session,
633512cbf1dSJens Wiklander 				   enum processing_func function,
634512cbf1dSJens Wiklander 				   struct pkcs11_attribute_head *proc_params,
635512cbf1dSJens Wiklander 				   struct pkcs11_object *obj)
636512cbf1dSJens Wiklander {
637512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
638512cbf1dSJens Wiklander 
639512cbf1dSJens Wiklander 	assert(processing_is_tee_symm(proc_params->id));
640512cbf1dSJens Wiklander 
641512cbf1dSJens Wiklander 	rc = allocate_tee_operation(session, function, proc_params, obj);
642512cbf1dSJens Wiklander 	if (rc)
643512cbf1dSJens Wiklander 		return rc;
644512cbf1dSJens Wiklander 
645de94d6f8SRuchika Gupta 	rc = load_tee_key(session, obj, proc_params);
646512cbf1dSJens Wiklander 	if (rc)
647512cbf1dSJens Wiklander 		return rc;
648512cbf1dSJens Wiklander 
649909efccbSEtienne Carriere 	rc = init_tee_operation(session, proc_params);
650909efccbSEtienne Carriere 	if (!rc)
651909efccbSEtienne Carriere 		session->processing->mecha_type = proc_params->id;
652909efccbSEtienne Carriere 
653909efccbSEtienne Carriere 	return rc;
654512cbf1dSJens Wiklander }
655512cbf1dSJens Wiklander 
656512cbf1dSJens Wiklander /* Validate input buffer size as per PKCS#11 constraints */
input_data_size_is_valid(struct active_processing * proc,enum processing_func function,size_t in_size)657512cbf1dSJens Wiklander static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc,
658512cbf1dSJens Wiklander 					       enum processing_func function,
659512cbf1dSJens Wiklander 					       size_t in_size)
660512cbf1dSJens Wiklander {
661512cbf1dSJens Wiklander 	switch (proc->mecha_type) {
662512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
663512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
664512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_ENCRYPT &&
665512cbf1dSJens Wiklander 		    in_size % TEE_AES_BLOCK_SIZE)
666512cbf1dSJens Wiklander 			return PKCS11_CKR_DATA_LEN_RANGE;
667512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_DECRYPT &&
668512cbf1dSJens Wiklander 		    in_size % TEE_AES_BLOCK_SIZE)
669512cbf1dSJens Wiklander 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
670512cbf1dSJens Wiklander 		break;
671512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
672512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_ENCRYPT &&
673512cbf1dSJens Wiklander 		    in_size < TEE_AES_BLOCK_SIZE)
674512cbf1dSJens Wiklander 			return PKCS11_CKR_DATA_LEN_RANGE;
675512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_DECRYPT &&
676512cbf1dSJens Wiklander 		    in_size < TEE_AES_BLOCK_SIZE)
677512cbf1dSJens Wiklander 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
678512cbf1dSJens Wiklander 		break;
679512cbf1dSJens Wiklander 	default:
680512cbf1dSJens Wiklander 		break;
681512cbf1dSJens Wiklander 	}
682512cbf1dSJens Wiklander 
683512cbf1dSJens Wiklander 	return PKCS11_CKR_OK;
684512cbf1dSJens Wiklander }
685512cbf1dSJens Wiklander 
686689f4e5bSRuchika Gupta /* Validate input buffer size as per PKCS#11 constraints */
input_sign_size_is_valid(struct active_processing * proc,size_t in_size)687689f4e5bSRuchika Gupta static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc,
688689f4e5bSRuchika Gupta 					       size_t in_size)
689689f4e5bSRuchika Gupta {
690689f4e5bSRuchika Gupta 	size_t sign_sz = 0;
691689f4e5bSRuchika Gupta 
692689f4e5bSRuchika Gupta 	switch (proc->mecha_type) {
693689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
694689f4e5bSRuchika Gupta 		sign_sz = TEE_MD5_HASH_SIZE;
695689f4e5bSRuchika Gupta 		break;
696689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
697689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA1_HASH_SIZE;
698689f4e5bSRuchika Gupta 		break;
699689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
700689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA224_HASH_SIZE;
701689f4e5bSRuchika Gupta 		break;
702689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
703689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA256_HASH_SIZE;
704689f4e5bSRuchika Gupta 		break;
705689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
706689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA384_HASH_SIZE;
707689f4e5bSRuchika Gupta 		break;
708689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
709689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA512_HASH_SIZE;
710689f4e5bSRuchika Gupta 		break;
7110ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC:
7120ef6b144SVictor Chong 		sign_sz = TEE_AES_BLOCK_SIZE;
7130ef6b144SVictor Chong 		break;
714689f4e5bSRuchika Gupta 	default:
715689f4e5bSRuchika Gupta 		return PKCS11_CKR_GENERAL_ERROR;
716689f4e5bSRuchika Gupta 	}
717689f4e5bSRuchika Gupta 
71842765f82SVictor Chong 	if (in_size != sign_sz)
719689f4e5bSRuchika Gupta 		return PKCS11_CKR_SIGNATURE_LEN_RANGE;
720689f4e5bSRuchika Gupta 
721689f4e5bSRuchika Gupta 	return PKCS11_CKR_OK;
722689f4e5bSRuchika Gupta }
723689f4e5bSRuchika Gupta 
724512cbf1dSJens Wiklander /*
725512cbf1dSJens Wiklander  * step_sym_cipher - processing symmetric (and related) cipher operation step
726512cbf1dSJens Wiklander  *
727512cbf1dSJens Wiklander  * @session - current session
728512cbf1dSJens Wiklander  * @function - processing function (encrypt, decrypt, sign, ...)
729512cbf1dSJens Wiklander  * @step - step ID in the processing (oneshot, update, final)
730512cbf1dSJens Wiklander  * @ptype - invocation parameter types
731512cbf1dSJens Wiklander  * @params - invocation parameter references
732512cbf1dSJens Wiklander  */
step_symm_operation(struct pkcs11_session * session,enum processing_func function,enum processing_step step,uint32_t ptypes,TEE_Param * params)733512cbf1dSJens Wiklander enum pkcs11_rc step_symm_operation(struct pkcs11_session *session,
734512cbf1dSJens Wiklander 				   enum processing_func function,
735512cbf1dSJens Wiklander 				   enum processing_step step,
736512cbf1dSJens Wiklander 				   uint32_t ptypes, TEE_Param *params)
737512cbf1dSJens Wiklander {
738512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
739512cbf1dSJens Wiklander 	TEE_Result res = TEE_ERROR_GENERIC;
740512cbf1dSJens Wiklander 	void *in_buf = NULL;
741512cbf1dSJens Wiklander 	size_t in_size = 0;
742512cbf1dSJens Wiklander 	void *out_buf = NULL;
743c7f1b4f7SJens Wiklander 	size_t out_size = 0;
744512cbf1dSJens Wiklander 	void *in2_buf = NULL;
745512cbf1dSJens Wiklander 	uint32_t in2_size = 0;
746512cbf1dSJens Wiklander 	bool output_data = false;
747512cbf1dSJens Wiklander 	struct active_processing *proc = session->processing;
74870b6683bSVictor Chong 	uint32_t hmac_len = 0;
74970b6683bSVictor Chong 	uint8_t computed_mac[TEE_MAX_HASH_SIZE] = { 0 };
750c7f1b4f7SJens Wiklander 	size_t computed_mac_size = TEE_MAX_HASH_SIZE;
75163778faaSEtienne Carriere 	size_t ae_out_size = 0;
752512cbf1dSJens Wiklander 
753512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) {
754512cbf1dSJens Wiklander 		in_buf = params[1].memref.buffer;
755512cbf1dSJens Wiklander 		in_size = params[1].memref.size;
756512cbf1dSJens Wiklander 		if (in_size && !in_buf)
757512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
758512cbf1dSJens Wiklander 	}
759512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) {
760512cbf1dSJens Wiklander 		in2_buf = params[2].memref.buffer;
761512cbf1dSJens Wiklander 		in2_size = params[2].memref.size;
762512cbf1dSJens Wiklander 		if (in2_size && !in2_buf)
763512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
764512cbf1dSJens Wiklander 	}
765512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) {
766512cbf1dSJens Wiklander 		out_buf = params[2].memref.buffer;
767512cbf1dSJens Wiklander 		out_size = params[2].memref.size;
76863778faaSEtienne Carriere 		ae_out_size = out_size;
769512cbf1dSJens Wiklander 		if (out_size && !out_buf)
770512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
771512cbf1dSJens Wiklander 	}
772512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE)
773512cbf1dSJens Wiklander 		return PKCS11_CKR_ARGUMENTS_BAD;
774512cbf1dSJens Wiklander 
775512cbf1dSJens Wiklander 	switch (step) {
776512cbf1dSJens Wiklander 	case PKCS11_FUNC_STEP_ONESHOT:
777512cbf1dSJens Wiklander 	case PKCS11_FUNC_STEP_UPDATE:
778512cbf1dSJens Wiklander 	case PKCS11_FUNC_STEP_FINAL:
779512cbf1dSJens Wiklander 		break;
780512cbf1dSJens Wiklander 	default:
781512cbf1dSJens Wiklander 		return PKCS11_CKR_GENERAL_ERROR;
782512cbf1dSJens Wiklander 	}
783512cbf1dSJens Wiklander 
784512cbf1dSJens Wiklander 	if (step != PKCS11_FUNC_STEP_FINAL) {
785512cbf1dSJens Wiklander 		rc = input_data_size_is_valid(proc, function, in_size);
786512cbf1dSJens Wiklander 		if (rc)
787512cbf1dSJens Wiklander 			return rc;
788512cbf1dSJens Wiklander 	}
789512cbf1dSJens Wiklander 
790512cbf1dSJens Wiklander 	/*
791512cbf1dSJens Wiklander 	 * Feed active operation with data
792512cbf1dSJens Wiklander 	 */
793512cbf1dSJens Wiklander 	switch (proc->mecha_type) {
7940ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC:
795689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
796689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
797689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
798689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
799689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
800689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
8010ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC_GENERAL:
80270b6683bSVictor Chong 	case PKCS11_CKM_MD5_HMAC_GENERAL:
80370b6683bSVictor Chong 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
80470b6683bSVictor Chong 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
80570b6683bSVictor Chong 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
80670b6683bSVictor Chong 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
80770b6683bSVictor Chong 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
808689f4e5bSRuchika Gupta 		if (step == PKCS11_FUNC_STEP_FINAL ||
809689f4e5bSRuchika Gupta 		    step == PKCS11_FUNC_STEP_ONESHOT)
810689f4e5bSRuchika Gupta 			break;
811689f4e5bSRuchika Gupta 
812689f4e5bSRuchika Gupta 		if (!in_buf) {
813689f4e5bSRuchika Gupta 			DMSG("No input data");
814689f4e5bSRuchika Gupta 			return PKCS11_CKR_ARGUMENTS_BAD;
815689f4e5bSRuchika Gupta 		}
816689f4e5bSRuchika Gupta 
817689f4e5bSRuchika Gupta 		switch (function) {
818689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_SIGN:
819689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_VERIFY:
820689f4e5bSRuchika Gupta 			TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size);
821689f4e5bSRuchika Gupta 			rc = PKCS11_CKR_OK;
822689f4e5bSRuchika Gupta 			break;
823689f4e5bSRuchika Gupta 		default:
824689f4e5bSRuchika Gupta 			TEE_Panic(function);
825689f4e5bSRuchika Gupta 			break;
826689f4e5bSRuchika Gupta 		}
827689f4e5bSRuchika Gupta 		break;
828689f4e5bSRuchika Gupta 
829512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
830512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
831512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
832512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
833512cbf1dSJens Wiklander 		if (step == PKCS11_FUNC_STEP_FINAL ||
834512cbf1dSJens Wiklander 		    step == PKCS11_FUNC_STEP_ONESHOT)
835512cbf1dSJens Wiklander 			break;
836512cbf1dSJens Wiklander 
837512cbf1dSJens Wiklander 		if (!in_buf) {
838512cbf1dSJens Wiklander 			EMSG("No input data");
839512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
840512cbf1dSJens Wiklander 		}
841512cbf1dSJens Wiklander 
842512cbf1dSJens Wiklander 		switch (function) {
843512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_ENCRYPT:
844512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_DECRYPT:
845512cbf1dSJens Wiklander 			res = TEE_CipherUpdate(proc->tee_op_handle,
846512cbf1dSJens Wiklander 					       in_buf, in_size,
847512cbf1dSJens Wiklander 						out_buf, &out_size);
848512cbf1dSJens Wiklander 			output_data = true;
849512cbf1dSJens Wiklander 			rc = tee2pkcs_error(res);
850512cbf1dSJens Wiklander 			break;
851512cbf1dSJens Wiklander 		default:
852512cbf1dSJens Wiklander 			TEE_Panic(function);
853512cbf1dSJens Wiklander 			break;
854512cbf1dSJens Wiklander 		}
855512cbf1dSJens Wiklander 		break;
85663778faaSEtienne Carriere 	case PKCS11_CKM_AES_GCM:
85763778faaSEtienne Carriere 		if (step == PKCS11_FUNC_STEP_FINAL)
85863778faaSEtienne Carriere 			break;
859512cbf1dSJens Wiklander 
86063778faaSEtienne Carriere 		switch (function) {
86163778faaSEtienne Carriere 		case PKCS11_FUNCTION_ENCRYPT:
86263778faaSEtienne Carriere 			res = TEE_AEUpdate(proc->tee_op_handle,
86363778faaSEtienne Carriere 					   in_buf, in_size, out_buf, &out_size);
86463778faaSEtienne Carriere 
86563778faaSEtienne Carriere 			output_data = true;
86663778faaSEtienne Carriere 			rc = tee2pkcs_error(res);
86763778faaSEtienne Carriere 			if (rc && rc != PKCS11_CKR_BUFFER_TOO_SMALL)
86863778faaSEtienne Carriere 				return rc;
86963778faaSEtienne Carriere 			if (step == PKCS11_FUNC_STEP_ONESHOT) {
87063778faaSEtienne Carriere 				if (rc == PKCS11_CKR_BUFFER_TOO_SMALL) {
87163778faaSEtienne Carriere 					/* Return output data size incl. tag*/
87263778faaSEtienne Carriere 					out_size += 16;
87363778faaSEtienne Carriere 					goto out;
87463778faaSEtienne Carriere 				}
87563778faaSEtienne Carriere 				out_buf = (char *)out_buf + out_size;
87663778faaSEtienne Carriere 				/* Remaining space for the tag data */
87763778faaSEtienne Carriere 				ae_out_size -= out_size;
87863778faaSEtienne Carriere 			}
87963778faaSEtienne Carriere 			break;
88063778faaSEtienne Carriere 		case PKCS11_FUNCTION_DECRYPT:
88163778faaSEtienne Carriere 			rc = tee_ae_decrypt_update(session, in_buf, in_size);
88263778faaSEtienne Carriere 			assert(rc != PKCS11_CKR_BUFFER_TOO_SMALL);
88363778faaSEtienne Carriere 			if (rc)
88463778faaSEtienne Carriere 				return rc;
88563778faaSEtienne Carriere 			/* Do not output decrypted data until tag is verified */
88663778faaSEtienne Carriere 			out_size = 0;
88763778faaSEtienne Carriere 			output_data = true;
88863778faaSEtienne Carriere 			break;
88963778faaSEtienne Carriere 		default:
89063778faaSEtienne Carriere 			TEE_Panic(function);
89163778faaSEtienne Carriere 			break;
89263778faaSEtienne Carriere 		}
89363778faaSEtienne Carriere 		break;
894512cbf1dSJens Wiklander 	default:
895512cbf1dSJens Wiklander 		TEE_Panic(proc->mecha_type);
896512cbf1dSJens Wiklander 		break;
897512cbf1dSJens Wiklander 	}
898512cbf1dSJens Wiklander 
899512cbf1dSJens Wiklander 	if (step == PKCS11_FUNC_STEP_UPDATE)
900512cbf1dSJens Wiklander 		goto out;
901512cbf1dSJens Wiklander 
902512cbf1dSJens Wiklander 	/*
903512cbf1dSJens Wiklander 	 * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation
904512cbf1dSJens Wiklander 	 */
905*5d2d37cdSEtienne Carriere 	switch (proc->mecha_type) {
9060ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC:
907689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
908689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
909689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
910689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
911689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
912689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
913689f4e5bSRuchika Gupta 		switch (function) {
914689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_SIGN:
915689f4e5bSRuchika Gupta 			res = TEE_MACComputeFinal(proc->tee_op_handle,
916689f4e5bSRuchika Gupta 						  in_buf, in_size, out_buf,
917689f4e5bSRuchika Gupta 						  &out_size);
918689f4e5bSRuchika Gupta 			output_data = true;
919689f4e5bSRuchika Gupta 			rc = tee2pkcs_error(res);
920689f4e5bSRuchika Gupta 			break;
921689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_VERIFY:
922689f4e5bSRuchika Gupta 			rc = input_sign_size_is_valid(proc, in2_size);
923689f4e5bSRuchika Gupta 			if (rc)
924689f4e5bSRuchika Gupta 				return rc;
925689f4e5bSRuchika Gupta 			res = TEE_MACCompareFinal(proc->tee_op_handle,
926689f4e5bSRuchika Gupta 						  in_buf, in_size, in2_buf,
927689f4e5bSRuchika Gupta 						  in2_size);
928689f4e5bSRuchika Gupta 			rc = tee2pkcs_error(res);
929689f4e5bSRuchika Gupta 			break;
930689f4e5bSRuchika Gupta 		default:
931689f4e5bSRuchika Gupta 			TEE_Panic(function);
932689f4e5bSRuchika Gupta 			break;
933689f4e5bSRuchika Gupta 		}
9342158ea6cSRuchika Gupta 
935689f4e5bSRuchika Gupta 		break;
936689f4e5bSRuchika Gupta 
9370ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC_GENERAL:
93870b6683bSVictor Chong 	case PKCS11_CKM_MD5_HMAC_GENERAL:
93970b6683bSVictor Chong 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
94070b6683bSVictor Chong 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
94170b6683bSVictor Chong 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
94270b6683bSVictor Chong 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
94370b6683bSVictor Chong 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
944*5d2d37cdSEtienne Carriere 		assert(proc->extra_ctx);
945*5d2d37cdSEtienne Carriere 		hmac_len = *(uint32_t *)proc->extra_ctx;
94670b6683bSVictor Chong 
94770b6683bSVictor Chong 		switch (function) {
94870b6683bSVictor Chong 		case PKCS11_FUNCTION_SIGN:
94970b6683bSVictor Chong 			if (out_size < hmac_len) {
95070b6683bSVictor Chong 				/* inform client of required size */
95170b6683bSVictor Chong 				out_size = hmac_len;
95270b6683bSVictor Chong 				output_data = true;
95370b6683bSVictor Chong 				rc = PKCS11_CKR_BUFFER_TOO_SMALL;
95470b6683bSVictor Chong 				goto out;
95570b6683bSVictor Chong 			}
95670b6683bSVictor Chong 
95770b6683bSVictor Chong 			res = TEE_MACComputeFinal(proc->tee_op_handle,
95870b6683bSVictor Chong 						  in_buf, in_size,
95970b6683bSVictor Chong 						  computed_mac,
96070b6683bSVictor Chong 						  &computed_mac_size);
96170b6683bSVictor Chong 			if (res == TEE_SUCCESS) {
96270b6683bSVictor Chong 				/* truncate to hmac_len */
96370b6683bSVictor Chong 				TEE_MemMove(out_buf, computed_mac, hmac_len);
96470b6683bSVictor Chong 				output_data = true;
96570b6683bSVictor Chong 			}
96670b6683bSVictor Chong 
96770b6683bSVictor Chong 			/* inform client of required size */
96870b6683bSVictor Chong 			out_size = hmac_len;
96970b6683bSVictor Chong 			rc = tee2pkcs_error(res);
97070b6683bSVictor Chong 			break;
97170b6683bSVictor Chong 		case PKCS11_FUNCTION_VERIFY:
97270b6683bSVictor Chong 			/* must compute full MAC before comparing partial */
97370b6683bSVictor Chong 			res = TEE_MACComputeFinal(proc->tee_op_handle, in_buf,
97470b6683bSVictor Chong 						  in_size, computed_mac,
97570b6683bSVictor Chong 						  &computed_mac_size);
97670b6683bSVictor Chong 
97770b6683bSVictor Chong 			if (!in2_size || in2_size > computed_mac_size) {
97870b6683bSVictor Chong 				EMSG("Invalid signature size: %"PRIu32,
97970b6683bSVictor Chong 				     in2_size);
98070b6683bSVictor Chong 				return PKCS11_CKR_SIGNATURE_LEN_RANGE;
98170b6683bSVictor Chong 			}
98270b6683bSVictor Chong 
98370b6683bSVictor Chong 			if (res == TEE_SUCCESS) {
98470b6683bSVictor Chong 				/*
98570b6683bSVictor Chong 				 * Only the first in2_size bytes of the
98670b6683bSVictor Chong 				 * signature to be verified is passed in from
98770b6683bSVictor Chong 				 * caller
98870b6683bSVictor Chong 				 */
98970b6683bSVictor Chong 				if (TEE_MemCompare(in2_buf, computed_mac,
99070b6683bSVictor Chong 						   in2_size)) {
99170b6683bSVictor Chong 					res = TEE_ERROR_MAC_INVALID;
99270b6683bSVictor Chong 				}
99370b6683bSVictor Chong 			}
99470b6683bSVictor Chong 
99570b6683bSVictor Chong 			rc = tee2pkcs_error(res);
99670b6683bSVictor Chong 			break;
99770b6683bSVictor Chong 		default:
99870b6683bSVictor Chong 			TEE_Panic(function);
99970b6683bSVictor Chong 			break;
100070b6683bSVictor Chong 		}
100170b6683bSVictor Chong 
100270b6683bSVictor Chong 		break;
100370b6683bSVictor Chong 
1004512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
1005512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
1006512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
1007512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
1008512cbf1dSJens Wiklander 		if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) {
1009512cbf1dSJens Wiklander 			EMSG("No input data");
1010512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
1011512cbf1dSJens Wiklander 		}
1012512cbf1dSJens Wiklander 
1013512cbf1dSJens Wiklander 		switch (function) {
1014512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_ENCRYPT:
1015512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_DECRYPT:
1016512cbf1dSJens Wiklander 			res = TEE_CipherDoFinal(proc->tee_op_handle,
1017512cbf1dSJens Wiklander 						in_buf, in_size,
1018512cbf1dSJens Wiklander 						out_buf, &out_size);
1019512cbf1dSJens Wiklander 			output_data = true;
1020512cbf1dSJens Wiklander 			rc = tee2pkcs_error(res);
1021512cbf1dSJens Wiklander 			break;
1022512cbf1dSJens Wiklander 		default:
1023512cbf1dSJens Wiklander 			TEE_Panic(function);
1024512cbf1dSJens Wiklander 			break;
1025512cbf1dSJens Wiklander 		}
1026512cbf1dSJens Wiklander 		break;
102763778faaSEtienne Carriere 	case PKCS11_CKM_AES_GCM:
102863778faaSEtienne Carriere 		switch (function) {
102963778faaSEtienne Carriere 		case PKCS11_FUNCTION_ENCRYPT:
103063778faaSEtienne Carriere 			rc = tee_ae_encrypt_final(session, out_buf,
103163778faaSEtienne Carriere 						  &ae_out_size);
103263778faaSEtienne Carriere 			output_data = true;
103363778faaSEtienne Carriere 			if (step == PKCS11_FUNC_STEP_ONESHOT)
103463778faaSEtienne Carriere 				out_size += ae_out_size;
103563778faaSEtienne Carriere 			else
103663778faaSEtienne Carriere 				out_size = ae_out_size;
103763778faaSEtienne Carriere 			break;
103863778faaSEtienne Carriere 		case PKCS11_FUNCTION_DECRYPT:
103963778faaSEtienne Carriere 			/* Now we're ready to reveal data */
104063778faaSEtienne Carriere 			out_size = ae_out_size;
104163778faaSEtienne Carriere 			rc = tee_ae_decrypt_final(session, out_buf, &out_size);
104263778faaSEtienne Carriere 			output_data = true;
104363778faaSEtienne Carriere 			break;
104463778faaSEtienne Carriere 		default:
104563778faaSEtienne Carriere 			TEE_Panic(function);
104663778faaSEtienne Carriere 			break;
104763778faaSEtienne Carriere 		}
104863778faaSEtienne Carriere 
104963778faaSEtienne Carriere 		if (step == PKCS11_FUNC_STEP_ONESHOT &&
105063778faaSEtienne Carriere 		    rc == PKCS11_CKR_BUFFER_TOO_SMALL) {
105163778faaSEtienne Carriere 			enum pkcs11_rc rc2 = PKCS11_CKR_OK;
105263778faaSEtienne Carriere 
105363778faaSEtienne Carriere 			/*
105463778faaSEtienne Carriere 			 * Change operation state to its initial state
105563778faaSEtienne Carriere 			 * as client will likely request again the
105663778faaSEtienne Carriere 			 * one-shot processing but possibly with
105763778faaSEtienne Carriere 			 * different input data.
105863778faaSEtienne Carriere 			 */
105963778faaSEtienne Carriere 			rc2 = tee_ae_reinit_gcm_operation(session);
106063778faaSEtienne Carriere 			if (rc2)
106163778faaSEtienne Carriere 				return rc2;
106263778faaSEtienne Carriere 		}
106363778faaSEtienne Carriere 		break;
1064512cbf1dSJens Wiklander 	default:
1065512cbf1dSJens Wiklander 		TEE_Panic(proc->mecha_type);
1066512cbf1dSJens Wiklander 		break;
1067512cbf1dSJens Wiklander 	}
1068512cbf1dSJens Wiklander 
1069512cbf1dSJens Wiklander out:
1070512cbf1dSJens Wiklander 	if (output_data &&
1071512cbf1dSJens Wiklander 	    (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) {
1072512cbf1dSJens Wiklander 		switch (TEE_PARAM_TYPE_GET(ptypes, 2)) {
1073512cbf1dSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
1074512cbf1dSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
1075512cbf1dSJens Wiklander 			params[2].memref.size = out_size;
1076512cbf1dSJens Wiklander 			break;
1077512cbf1dSJens Wiklander 		default:
1078512cbf1dSJens Wiklander 			rc = PKCS11_CKR_ARGUMENTS_BAD;
1079512cbf1dSJens Wiklander 			break;
1080512cbf1dSJens Wiklander 		}
1081512cbf1dSJens Wiklander 	}
1082512cbf1dSJens Wiklander 
1083512cbf1dSJens Wiklander 	return rc;
1084512cbf1dSJens Wiklander }
108548799892SRuchika Gupta 
derive_key_by_symm_enc(struct pkcs11_session * session,void ** out_buf,uint32_t * out_size)108648799892SRuchika Gupta enum pkcs11_rc derive_key_by_symm_enc(struct pkcs11_session *session,
10878c499324SRuchika Gupta 				      void **out_buf, uint32_t *out_size)
108848799892SRuchika Gupta {
108948799892SRuchika Gupta 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
109048799892SRuchika Gupta 	TEE_Result res = TEE_ERROR_GENERIC;
109148799892SRuchika Gupta 	struct active_processing *proc = session->processing;
109248799892SRuchika Gupta 	struct input_data_ref *input = proc->extra_ctx;
109348799892SRuchika Gupta 	void *in_buf = NULL;
1094a5ea52c2SElvira Khabirova 	void *dest_buf = NULL;
109548799892SRuchika Gupta 	uint32_t in_size = 0;
1096c7f1b4f7SJens Wiklander 	size_t tmp_sz = 0;
109748799892SRuchika Gupta 
10988c499324SRuchika Gupta 	switch (proc->mecha_type) {
10998c499324SRuchika Gupta 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
11008c499324SRuchika Gupta 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
110148799892SRuchika Gupta 		if (!proc->extra_ctx)
110248799892SRuchika Gupta 			return PKCS11_CKR_ARGUMENTS_BAD;
110348799892SRuchika Gupta 
110448799892SRuchika Gupta 		in_buf = input->data;
110548799892SRuchika Gupta 		in_size = input->size;
110648799892SRuchika Gupta 
11078c499324SRuchika Gupta 		*out_size = in_size;
1108a5ea52c2SElvira Khabirova 		dest_buf = TEE_Malloc(*out_size, 0);
1109a5ea52c2SElvira Khabirova 		if (!dest_buf)
111048799892SRuchika Gupta 			return PKCS11_CKR_DEVICE_MEMORY;
111148799892SRuchika Gupta 
1112c7f1b4f7SJens Wiklander 		tmp_sz = *out_size;
11138c499324SRuchika Gupta 		res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_size,
1114c7f1b4f7SJens Wiklander 					dest_buf, &tmp_sz);
1115c7f1b4f7SJens Wiklander 		*out_size = tmp_sz;
111648799892SRuchika Gupta 		rc = tee2pkcs_error(res);
1117a5ea52c2SElvira Khabirova 		if (rc) {
1118a5ea52c2SElvira Khabirova 			TEE_Free(dest_buf);
1119a5ea52c2SElvira Khabirova 			return rc;
1120a5ea52c2SElvira Khabirova 		}
1121a5ea52c2SElvira Khabirova 
1122a5ea52c2SElvira Khabirova 		*out_buf = dest_buf;
11238c499324SRuchika Gupta 		break;
11248c499324SRuchika Gupta 	default:
11258c499324SRuchika Gupta 		return PKCS11_CKR_MECHANISM_INVALID;
112648799892SRuchika Gupta 	}
112748799892SRuchika Gupta 
112848799892SRuchika Gupta 	return rc;
112948799892SRuchika Gupta }
11305f80f270SRuchika Gupta 
wrap_data_by_symm_enc(struct pkcs11_session * session,void * data,uint32_t data_sz,void * out_buf,uint32_t * out_sz)11315f80f270SRuchika Gupta enum pkcs11_rc wrap_data_by_symm_enc(struct pkcs11_session *session,
11325f80f270SRuchika Gupta 				     void *data, uint32_t data_sz,
11335f80f270SRuchika Gupta 				     void *out_buf, uint32_t *out_sz)
11345f80f270SRuchika Gupta {
11355f80f270SRuchika Gupta 	TEE_Result res = TEE_ERROR_GENERIC;
11365f80f270SRuchika Gupta 	struct active_processing *proc = session->processing;
11375f80f270SRuchika Gupta 	void *in_buf = NULL;
11385f80f270SRuchika Gupta 	uint32_t align = 0;
11395f80f270SRuchika Gupta 	uint32_t in_sz = data_sz;
1140c7f1b4f7SJens Wiklander 	size_t tmp_sz = *out_sz;
11415f80f270SRuchika Gupta 	uint8_t *tmp_buf = out_buf;
11425f80f270SRuchika Gupta 
11435f80f270SRuchika Gupta 	switch (proc->mecha_type) {
11445f80f270SRuchika Gupta 	case PKCS11_CKM_AES_ECB:
11455f80f270SRuchika Gupta 	case PKCS11_CKM_AES_CBC:
11465f80f270SRuchika Gupta 		align = data_sz % TEE_AES_BLOCK_SIZE;
11475f80f270SRuchika Gupta 		if (align)
11485f80f270SRuchika Gupta 			in_sz = data_sz + (TEE_AES_BLOCK_SIZE - align);
11495f80f270SRuchika Gupta 
11505f80f270SRuchika Gupta 		if (*out_sz < in_sz) {
11515f80f270SRuchika Gupta 			*out_sz = in_sz;
11525f80f270SRuchika Gupta 			return PKCS11_CKR_BUFFER_TOO_SMALL;
11535f80f270SRuchika Gupta 		}
11545f80f270SRuchika Gupta 
11555f80f270SRuchika Gupta 		if (align) {
11565f80f270SRuchika Gupta 			if (data_sz > TEE_AES_BLOCK_SIZE) {
11575f80f270SRuchika Gupta 				in_sz = data_sz - align;
11585f80f270SRuchika Gupta 				res = TEE_CipherUpdate(proc->tee_op_handle,
11595f80f270SRuchika Gupta 						       data, in_sz, tmp_buf,
11605f80f270SRuchika Gupta 						       &tmp_sz);
11615f80f270SRuchika Gupta 				if (res) {
11625f80f270SRuchika Gupta 					assert(res != TEE_ERROR_SHORT_BUFFER);
11635f80f270SRuchika Gupta 					return tee2pkcs_error(res);
11645f80f270SRuchika Gupta 				}
11655f80f270SRuchika Gupta 				tmp_buf += tmp_sz;
11665f80f270SRuchika Gupta 				tmp_sz = *out_sz - tmp_sz;
11675f80f270SRuchika Gupta 			} else {
11685f80f270SRuchika Gupta 				in_sz = 0;
11695f80f270SRuchika Gupta 			}
11705f80f270SRuchika Gupta 
11715f80f270SRuchika Gupta 			in_buf = TEE_Malloc(TEE_AES_BLOCK_SIZE,
11725f80f270SRuchika Gupta 					    TEE_MALLOC_FILL_ZERO);
11735f80f270SRuchika Gupta 			if (!in_buf)
11745f80f270SRuchika Gupta 				return PKCS11_CKR_DEVICE_MEMORY;
11755f80f270SRuchika Gupta 
11765f80f270SRuchika Gupta 			TEE_MemMove(in_buf, (uint8_t *)data + in_sz, align);
11775f80f270SRuchika Gupta 			in_sz = TEE_AES_BLOCK_SIZE;
11785f80f270SRuchika Gupta 		} else {
11795f80f270SRuchika Gupta 			in_buf = data;
11805f80f270SRuchika Gupta 			in_sz = data_sz;
11815f80f270SRuchika Gupta 		}
11825f80f270SRuchika Gupta 
11835f80f270SRuchika Gupta 		res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_sz,
11845f80f270SRuchika Gupta 					tmp_buf, &tmp_sz);
11855f80f270SRuchika Gupta 		if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
11865f80f270SRuchika Gupta 			*out_sz = tmp_sz;
11875f80f270SRuchika Gupta 			if (align)
11885f80f270SRuchika Gupta 				*out_sz += tmp_buf - (uint8_t *)out_buf;
11895f80f270SRuchika Gupta 		}
11905f80f270SRuchika Gupta 
11915f80f270SRuchika Gupta 		if (align)
11925f80f270SRuchika Gupta 			TEE_Free(in_buf);
11935f80f270SRuchika Gupta 
11945f80f270SRuchika Gupta 		return tee2pkcs_error(res);
11955f80f270SRuchika Gupta 	default:
11965f80f270SRuchika Gupta 		return PKCS11_CKR_MECHANISM_INVALID;
11975f80f270SRuchika Gupta 	}
11985f80f270SRuchika Gupta 
11995f80f270SRuchika Gupta 	return PKCS11_CKR_GENERAL_ERROR;
12005f80f270SRuchika Gupta }
12013668310bSRuchika Gupta 
unwrap_key_by_symm(struct pkcs11_session * session,void * data,uint32_t data_sz,void ** out_buf,uint32_t * out_sz)12023668310bSRuchika Gupta enum pkcs11_rc unwrap_key_by_symm(struct pkcs11_session *session, void *data,
12033668310bSRuchika Gupta 				  uint32_t data_sz, void **out_buf,
12043668310bSRuchika Gupta 				  uint32_t *out_sz)
12053668310bSRuchika Gupta {
12063668310bSRuchika Gupta 	TEE_Result res = TEE_ERROR_GENERIC;
12073668310bSRuchika Gupta 	struct active_processing *proc = session->processing;
1208c7f1b4f7SJens Wiklander 	size_t tmp_sz = 0;
12093668310bSRuchika Gupta 
12103668310bSRuchika Gupta 	if (input_data_size_is_valid(proc, PKCS11_FUNCTION_DECRYPT, data_sz))
12113668310bSRuchika Gupta 		return PKCS11_CKR_WRAPPED_KEY_LEN_RANGE;
12123668310bSRuchika Gupta 
12133668310bSRuchika Gupta 	switch (proc->mecha_type) {
12143668310bSRuchika Gupta 	case PKCS11_CKM_AES_ECB:
12153668310bSRuchika Gupta 	case PKCS11_CKM_AES_CBC:
12163668310bSRuchika Gupta 		*out_sz = 0;
12173668310bSRuchika Gupta 		res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz,
1218c7f1b4f7SJens Wiklander 					NULL, &tmp_sz);
1219c7f1b4f7SJens Wiklander 		*out_sz = tmp_sz;
12203668310bSRuchika Gupta 		if (res != TEE_ERROR_SHORT_BUFFER) {
12213668310bSRuchika Gupta 			DMSG("TEE_CipherDoFinal() issue: %#"PRIx32, res);
12223668310bSRuchika Gupta 			return PKCS11_CKR_GENERAL_ERROR;
12233668310bSRuchika Gupta 		}
12243668310bSRuchika Gupta 
12253668310bSRuchika Gupta 		*out_buf = TEE_Malloc(*out_sz, TEE_MALLOC_FILL_ZERO);
12263668310bSRuchika Gupta 		if (!*out_buf)
12273668310bSRuchika Gupta 			return PKCS11_CKR_DEVICE_MEMORY;
12283668310bSRuchika Gupta 
12293668310bSRuchika Gupta 		res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz,
1230c7f1b4f7SJens Wiklander 					*out_buf, &tmp_sz);
1231c7f1b4f7SJens Wiklander 		*out_sz = tmp_sz;
12323668310bSRuchika Gupta 		if (tee2pkcs_error(res)) {
12333668310bSRuchika Gupta 			TEE_Free(*out_buf);
12343668310bSRuchika Gupta 			*out_buf = NULL;
12353668310bSRuchika Gupta 			return PKCS11_CKR_WRAPPED_KEY_INVALID;
12363668310bSRuchika Gupta 		}
12373668310bSRuchika Gupta 		break;
12383668310bSRuchika Gupta 	default:
12393668310bSRuchika Gupta 		return PKCS11_CKR_MECHANISM_INVALID;
12403668310bSRuchika Gupta 	}
12413668310bSRuchika Gupta 
12423668310bSRuchika Gupta 	return PKCS11_CKR_OK;
12433668310bSRuchika Gupta }
1244