xref: /optee_os/ta/pkcs11/src/processing_symm.c (revision c7f1b4f7881fded88ca7b5bffc8cc47b94c07dd5)
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 
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:
5148799892SRuchika Gupta 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
5248799892SRuchika Gupta 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
53512cbf1dSJens Wiklander 		return true;
54512cbf1dSJens Wiklander 	default:
55512cbf1dSJens Wiklander 		return false;
56512cbf1dSJens Wiklander 	}
57512cbf1dSJens Wiklander }
58512cbf1dSJens Wiklander 
59512cbf1dSJens Wiklander static enum pkcs11_rc
60512cbf1dSJens Wiklander pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params)
61512cbf1dSJens Wiklander {
62512cbf1dSJens Wiklander 	static const struct {
63512cbf1dSJens Wiklander 		enum pkcs11_mechanism_id mech_id;
64512cbf1dSJens Wiklander 		uint32_t tee_id;
65512cbf1dSJens Wiklander 	} pkcs2tee_algo[] = {
66512cbf1dSJens Wiklander 		/* AES flavors */
67512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_ECB, TEE_ALG_AES_ECB_NOPAD },
68512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_CBC, TEE_ALG_AES_CBC_NOPAD },
6948799892SRuchika Gupta 		{ PKCS11_CKM_AES_ECB_ENCRYPT_DATA, TEE_ALG_AES_ECB_NOPAD },
7048799892SRuchika Gupta 		{ PKCS11_CKM_AES_CBC_ENCRYPT_DATA, TEE_ALG_AES_CBC_NOPAD },
71512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_CTR, TEE_ALG_AES_CTR },
72512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_CTS, TEE_ALG_AES_CTS },
730ef6b144SVictor Chong 		{ PKCS11_CKM_AES_CMAC, TEE_ALG_AES_CMAC },
740ef6b144SVictor Chong 		{ PKCS11_CKM_AES_CMAC_GENERAL, TEE_ALG_AES_CMAC },
75689f4e5bSRuchika Gupta 		/* HMAC flavors */
76689f4e5bSRuchika Gupta 		{ PKCS11_CKM_MD5_HMAC, TEE_ALG_HMAC_MD5 },
77689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA_1_HMAC, TEE_ALG_HMAC_SHA1 },
78689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA224_HMAC, TEE_ALG_HMAC_SHA224 },
79689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA256_HMAC, TEE_ALG_HMAC_SHA256 },
80689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA384_HMAC, TEE_ALG_HMAC_SHA384 },
81689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA512_HMAC, TEE_ALG_HMAC_SHA512 },
8270b6683bSVictor Chong 		{ PKCS11_CKM_MD5_HMAC_GENERAL, TEE_ALG_HMAC_MD5 },
8370b6683bSVictor Chong 		{ PKCS11_CKM_SHA_1_HMAC_GENERAL, TEE_ALG_HMAC_SHA1 },
8470b6683bSVictor Chong 		{ PKCS11_CKM_SHA224_HMAC_GENERAL, TEE_ALG_HMAC_SHA224 },
8570b6683bSVictor Chong 		{ PKCS11_CKM_SHA256_HMAC_GENERAL, TEE_ALG_HMAC_SHA256 },
8670b6683bSVictor Chong 		{ PKCS11_CKM_SHA384_HMAC_GENERAL, TEE_ALG_HMAC_SHA384 },
8770b6683bSVictor Chong 		{ PKCS11_CKM_SHA512_HMAC_GENERAL, TEE_ALG_HMAC_SHA512 },
88512cbf1dSJens Wiklander 	};
89512cbf1dSJens Wiklander 	size_t n = 0;
90512cbf1dSJens Wiklander 
91512cbf1dSJens Wiklander 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) {
92512cbf1dSJens Wiklander 		if (proc_params->id == pkcs2tee_algo[n].mech_id) {
93512cbf1dSJens Wiklander 			*tee_id = pkcs2tee_algo[n].tee_id;
94512cbf1dSJens Wiklander 			return PKCS11_CKR_OK;
95512cbf1dSJens Wiklander 		}
96512cbf1dSJens Wiklander 	}
97512cbf1dSJens Wiklander 
98512cbf1dSJens Wiklander 	return PKCS11_RV_NOT_IMPLEMENTED;
99512cbf1dSJens Wiklander }
100512cbf1dSJens Wiklander 
101512cbf1dSJens Wiklander static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type,
102512cbf1dSJens Wiklander 					struct pkcs11_object *obj)
103512cbf1dSJens Wiklander {
104512cbf1dSJens Wiklander 	static const struct {
105512cbf1dSJens Wiklander 		enum pkcs11_key_type key_type;
106512cbf1dSJens Wiklander 		uint32_t tee_id;
107512cbf1dSJens Wiklander 	} pkcs2tee_key_type[] = {
108512cbf1dSJens Wiklander 		{ PKCS11_CKK_AES, TEE_TYPE_AES },
109512cbf1dSJens Wiklander 		{ PKCS11_CKK_GENERIC_SECRET, TEE_TYPE_GENERIC_SECRET },
110512cbf1dSJens Wiklander 		{ PKCS11_CKK_MD5_HMAC, TEE_TYPE_HMAC_MD5 },
111512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 },
112512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 },
113512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 },
114512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 },
115512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 },
116512cbf1dSJens Wiklander 	};
117512cbf1dSJens Wiklander 	size_t n = 0;
118512cbf1dSJens Wiklander 	enum pkcs11_key_type key_type = get_key_type(obj->attributes);
119512cbf1dSJens Wiklander 
120512cbf1dSJens Wiklander 	assert(get_class(obj->attributes) == PKCS11_CKO_SECRET_KEY);
121512cbf1dSJens Wiklander 
122512cbf1dSJens Wiklander 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) {
123512cbf1dSJens Wiklander 		if (pkcs2tee_key_type[n].key_type == key_type) {
124512cbf1dSJens Wiklander 			*tee_type = pkcs2tee_key_type[n].tee_id;
125512cbf1dSJens Wiklander 			return PKCS11_CKR_OK;
126512cbf1dSJens Wiklander 		}
127512cbf1dSJens Wiklander 	}
128512cbf1dSJens Wiklander 
129512cbf1dSJens Wiklander 	return PKCS11_RV_NOT_FOUND;
130512cbf1dSJens Wiklander }
131512cbf1dSJens Wiklander 
132de94d6f8SRuchika Gupta static enum pkcs11_rc pkcsmech2tee_key_type(uint32_t *tee_type,
133de94d6f8SRuchika Gupta 					    enum pkcs11_mechanism_id mech_id)
134de94d6f8SRuchika Gupta {
135de94d6f8SRuchika Gupta 	static const struct {
136de94d6f8SRuchika Gupta 		enum pkcs11_mechanism_id mech;
137de94d6f8SRuchika Gupta 		uint32_t tee_id;
138de94d6f8SRuchika Gupta 	} pkcs2tee_key_type[] = {
139de94d6f8SRuchika Gupta 		{ PKCS11_CKM_MD5_HMAC, TEE_TYPE_HMAC_MD5 },
140de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 },
141de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 },
142de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 },
143de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 },
144de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 },
14570b6683bSVictor Chong 		{ PKCS11_CKM_MD5_HMAC_GENERAL, TEE_TYPE_HMAC_MD5 },
14670b6683bSVictor Chong 		{ PKCS11_CKM_SHA_1_HMAC_GENERAL, TEE_TYPE_HMAC_SHA1 },
14770b6683bSVictor Chong 		{ PKCS11_CKM_SHA224_HMAC_GENERAL, TEE_TYPE_HMAC_SHA224 },
14870b6683bSVictor Chong 		{ PKCS11_CKM_SHA256_HMAC_GENERAL, TEE_TYPE_HMAC_SHA256 },
14970b6683bSVictor Chong 		{ PKCS11_CKM_SHA384_HMAC_GENERAL, TEE_TYPE_HMAC_SHA384 },
15070b6683bSVictor Chong 		{ PKCS11_CKM_SHA512_HMAC_GENERAL, TEE_TYPE_HMAC_SHA512 },
151de94d6f8SRuchika Gupta 	};
152de94d6f8SRuchika Gupta 	size_t n = 0;
153de94d6f8SRuchika Gupta 
154de94d6f8SRuchika Gupta 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) {
155de94d6f8SRuchika Gupta 		if (pkcs2tee_key_type[n].mech == mech_id) {
156de94d6f8SRuchika Gupta 			*tee_type = pkcs2tee_key_type[n].tee_id;
157de94d6f8SRuchika Gupta 			return PKCS11_CKR_OK;
158de94d6f8SRuchika Gupta 		}
159de94d6f8SRuchika Gupta 	}
160de94d6f8SRuchika Gupta 
161de94d6f8SRuchika Gupta 	return PKCS11_RV_NOT_FOUND;
162de94d6f8SRuchika Gupta }
163de94d6f8SRuchika Gupta 
1642158ea6cSRuchika Gupta static enum pkcs11_rc hmac_to_tee_hash(uint32_t *algo,
1652158ea6cSRuchika Gupta 				       enum pkcs11_mechanism_id mech_id)
1662158ea6cSRuchika Gupta {
1672158ea6cSRuchika Gupta 	static const struct {
1682158ea6cSRuchika Gupta 		enum pkcs11_mechanism_id mech;
1692158ea6cSRuchika Gupta 		uint32_t tee_id;
1702158ea6cSRuchika Gupta 	} hmac_hash[] = {
1712158ea6cSRuchika Gupta 		{ PKCS11_CKM_MD5_HMAC, TEE_ALG_MD5 },
1722158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA_1_HMAC, TEE_ALG_SHA1 },
1732158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA224_HMAC, TEE_ALG_SHA224 },
1742158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA256_HMAC, TEE_ALG_SHA256 },
1752158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA384_HMAC, TEE_ALG_SHA384 },
1762158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA512_HMAC, TEE_ALG_SHA512 },
17770b6683bSVictor Chong 		{ PKCS11_CKM_MD5_HMAC_GENERAL, TEE_ALG_MD5 },
17870b6683bSVictor Chong 		{ PKCS11_CKM_SHA_1_HMAC_GENERAL, TEE_ALG_SHA1 },
17970b6683bSVictor Chong 		{ PKCS11_CKM_SHA224_HMAC_GENERAL, TEE_ALG_SHA224 },
18070b6683bSVictor Chong 		{ PKCS11_CKM_SHA256_HMAC_GENERAL, TEE_ALG_SHA256 },
18170b6683bSVictor Chong 		{ PKCS11_CKM_SHA384_HMAC_GENERAL, TEE_ALG_SHA384 },
18270b6683bSVictor Chong 		{ PKCS11_CKM_SHA512_HMAC_GENERAL, TEE_ALG_SHA512 },
1832158ea6cSRuchika Gupta 	};
1842158ea6cSRuchika Gupta 	size_t n = 0;
1852158ea6cSRuchika Gupta 
1862158ea6cSRuchika Gupta 	for (n = 0; n < ARRAY_SIZE(hmac_hash); n++) {
1872158ea6cSRuchika Gupta 		if (hmac_hash[n].mech == mech_id) {
1882158ea6cSRuchika Gupta 			*algo = hmac_hash[n].tee_id;
1892158ea6cSRuchika Gupta 			return PKCS11_CKR_OK;
1902158ea6cSRuchika Gupta 		}
1912158ea6cSRuchika Gupta 	}
1922158ea6cSRuchika Gupta 
1932158ea6cSRuchika Gupta 	return PKCS11_RV_NOT_FOUND;
1942158ea6cSRuchika Gupta }
1952158ea6cSRuchika Gupta 
196512cbf1dSJens Wiklander static enum pkcs11_rc
197512cbf1dSJens Wiklander allocate_tee_operation(struct pkcs11_session *session,
198512cbf1dSJens Wiklander 		       enum processing_func function,
199512cbf1dSJens Wiklander 		       struct pkcs11_attribute_head *params,
200512cbf1dSJens Wiklander 		       struct pkcs11_object *obj)
201512cbf1dSJens Wiklander {
202512cbf1dSJens Wiklander 	uint32_t size = (uint32_t)get_object_key_bit_size(obj);
203460ba621SRuchika Gupta 	uint32_t key_size = size / 8;
204512cbf1dSJens Wiklander 	uint32_t algo = 0;
205512cbf1dSJens Wiklander 	uint32_t mode = 0;
206460ba621SRuchika Gupta 	uint32_t max_key_size = 0;
207460ba621SRuchika Gupta 	uint32_t min_key_size = 0;
208512cbf1dSJens Wiklander 	TEE_Result res = TEE_ERROR_GENERIC;
209512cbf1dSJens Wiklander 
210512cbf1dSJens Wiklander 	assert(session->processing->tee_op_handle == TEE_HANDLE_NULL);
211512cbf1dSJens Wiklander 
212512cbf1dSJens Wiklander 	if (pkcs2tee_algorithm(&algo, params))
213512cbf1dSJens Wiklander 		return PKCS11_CKR_FUNCTION_FAILED;
214512cbf1dSJens Wiklander 
215512cbf1dSJens Wiklander 	/* Sign/Verify with AES or generic key relate to TEE MAC operation */
216689f4e5bSRuchika Gupta 	switch (params->id) {
217689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
218689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
219689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
220689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
221689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
222689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
22370b6683bSVictor Chong 	case PKCS11_CKM_MD5_HMAC_GENERAL:
22470b6683bSVictor Chong 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
22570b6683bSVictor Chong 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
22670b6683bSVictor Chong 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
22770b6683bSVictor Chong 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
22870b6683bSVictor Chong 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
2292d0cd829SRuchika Gupta 		mechanism_supported_key_sizes_bytes(params->id, &min_key_size,
230460ba621SRuchika Gupta 						    &max_key_size);
231460ba621SRuchika Gupta 		if (key_size < min_key_size)
232460ba621SRuchika Gupta 			return PKCS11_CKR_KEY_SIZE_RANGE;
2332158ea6cSRuchika Gupta 
2342158ea6cSRuchika Gupta 		/*
2352158ea6cSRuchika Gupta 		 * If size of generic key is greater than the size
2362158ea6cSRuchika Gupta 		 * supported by TEE API, this is not considered an
2372158ea6cSRuchika Gupta 		 * error. When loading TEE key, we will hash the key
2382158ea6cSRuchika Gupta 		 * to generate the appropriate key for HMAC operation.
2392158ea6cSRuchika Gupta 		 * This key size will not be greater than the
2402158ea6cSRuchika Gupta 		 * max_key_size. So we can use max_key_size for
2412158ea6cSRuchika Gupta 		 * TEE_AllocateOperation().
2422158ea6cSRuchika Gupta 		 */
2432158ea6cSRuchika Gupta 		if (key_size > max_key_size)
2442158ea6cSRuchika Gupta 			size = max_key_size * 8;
2452158ea6cSRuchika Gupta 
246689f4e5bSRuchika Gupta 		mode = TEE_MODE_MAC;
247689f4e5bSRuchika Gupta 		break;
2480ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC:
2490ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC_GENERAL:
2500ef6b144SVictor Chong 		mode = TEE_MODE_MAC;
2510ef6b144SVictor Chong 		break;
252689f4e5bSRuchika Gupta 	default:
253512cbf1dSJens Wiklander 		pkcs2tee_mode(&mode, function);
254689f4e5bSRuchika Gupta 		break;
255689f4e5bSRuchika Gupta 	}
256512cbf1dSJens Wiklander 
257512cbf1dSJens Wiklander 	res = TEE_AllocateOperation(&session->processing->tee_op_handle,
258512cbf1dSJens Wiklander 				    algo, mode, size);
259512cbf1dSJens Wiklander 	if (res)
260512cbf1dSJens Wiklander 		EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32,
261512cbf1dSJens Wiklander 		     algo, mode, size);
262512cbf1dSJens Wiklander 
263512cbf1dSJens Wiklander 	if (res == TEE_ERROR_NOT_SUPPORTED)
264512cbf1dSJens Wiklander 		return PKCS11_CKR_MECHANISM_INVALID;
265512cbf1dSJens Wiklander 
266512cbf1dSJens Wiklander 	return tee2pkcs_error(res);
267512cbf1dSJens Wiklander }
268512cbf1dSJens Wiklander 
2692158ea6cSRuchika Gupta static enum pkcs11_rc hash_secret_helper(enum pkcs11_mechanism_id mech_id,
2702158ea6cSRuchika Gupta 					 struct pkcs11_object *obj,
2712158ea6cSRuchika Gupta 					 TEE_Attribute *tee_attr,
2722158ea6cSRuchika Gupta 					 void **ctx,
2732158ea6cSRuchika Gupta 					 size_t *object_size_bits)
2742158ea6cSRuchika Gupta {
2752158ea6cSRuchika Gupta 	uint32_t algo = 0;
2762158ea6cSRuchika Gupta 	void *hash_ptr = NULL;
2772158ea6cSRuchika Gupta 	uint32_t hash_size = 0;
2782158ea6cSRuchika Gupta 	enum pkcs11_rc rc = PKCS11_CKR_OK;
2792158ea6cSRuchika Gupta 
2802158ea6cSRuchika Gupta 	rc = hmac_to_tee_hash(&algo, mech_id);
2812158ea6cSRuchika Gupta 	if (rc)
2822158ea6cSRuchika Gupta 		return rc;
2832158ea6cSRuchika Gupta 
2842158ea6cSRuchika Gupta 	hash_size = TEE_ALG_GET_DIGEST_SIZE(algo);
2852158ea6cSRuchika Gupta 	hash_ptr = TEE_Malloc(hash_size, 0);
2862158ea6cSRuchika Gupta 	if (!hash_ptr)
2872158ea6cSRuchika Gupta 		return PKCS11_CKR_DEVICE_MEMORY;
2882158ea6cSRuchika Gupta 
2892158ea6cSRuchika Gupta 	rc = pkcs2tee_load_hashed_attr(tee_attr, TEE_ATTR_SECRET_VALUE, obj,
2902158ea6cSRuchika Gupta 				       PKCS11_CKA_VALUE, algo, hash_ptr,
2912158ea6cSRuchika Gupta 				       &hash_size);
2922158ea6cSRuchika Gupta 	if (rc) {
2932158ea6cSRuchika Gupta 		EMSG("No secret/hash error");
2942158ea6cSRuchika Gupta 		TEE_Free(hash_ptr);
2952158ea6cSRuchika Gupta 		return rc;
2962158ea6cSRuchika Gupta 	}
2972158ea6cSRuchika Gupta 
2982158ea6cSRuchika Gupta 	*ctx = hash_ptr;
2992158ea6cSRuchika Gupta 
3002158ea6cSRuchika Gupta 	*object_size_bits = hash_size * 8;
3012158ea6cSRuchika Gupta 
3022158ea6cSRuchika Gupta 	return PKCS11_CKR_OK;
3032158ea6cSRuchika Gupta }
3042158ea6cSRuchika Gupta 
305512cbf1dSJens Wiklander static enum pkcs11_rc load_tee_key(struct pkcs11_session *session,
306de94d6f8SRuchika Gupta 				   struct pkcs11_object *obj,
307de94d6f8SRuchika Gupta 				   struct pkcs11_attribute_head *proc_params)
308512cbf1dSJens Wiklander {
309512cbf1dSJens Wiklander 	TEE_Attribute tee_attr = { };
310512cbf1dSJens Wiklander 	size_t object_size = 0;
311512cbf1dSJens Wiklander 	uint32_t tee_key_type = 0;
312de94d6f8SRuchika Gupta 	enum pkcs11_key_type key_type = 0;
313512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
314512cbf1dSJens Wiklander 	TEE_Result res = TEE_ERROR_GENERIC;
3152158ea6cSRuchika Gupta 	uint32_t max_key_size = 0;
3162158ea6cSRuchika Gupta 	uint32_t min_key_size = 0;
317512cbf1dSJens Wiklander 
318512cbf1dSJens Wiklander 	if (obj->key_handle != TEE_HANDLE_NULL) {
319512cbf1dSJens Wiklander 		/* Key was already loaded and fits current need */
320512cbf1dSJens Wiklander 		goto key_ready;
321512cbf1dSJens Wiklander 	}
322512cbf1dSJens Wiklander 
3232158ea6cSRuchika Gupta 	object_size = get_object_key_bit_size(obj);
3242158ea6cSRuchika Gupta 	if (!object_size)
3252158ea6cSRuchika Gupta 		return PKCS11_CKR_GENERAL_ERROR;
326512cbf1dSJens Wiklander 
327de94d6f8SRuchika Gupta 	switch (proc_params->id) {
328de94d6f8SRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
329de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
330de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
331de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
332de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
333de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
33470b6683bSVictor Chong 	case PKCS11_CKM_MD5_HMAC_GENERAL:
33570b6683bSVictor Chong 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
33670b6683bSVictor Chong 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
33770b6683bSVictor Chong 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
33870b6683bSVictor Chong 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
33970b6683bSVictor Chong 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
340de94d6f8SRuchika Gupta 		key_type = get_key_type(obj->attributes);
341de94d6f8SRuchika Gupta 		/*
342de94d6f8SRuchika Gupta 		 * If Object Key type is PKCS11_CKK_GENERIC_SECRET,
343de94d6f8SRuchika Gupta 		 * determine the tee_key_type using the
344de94d6f8SRuchika Gupta 		 * mechanism instead of object key_type.
345de94d6f8SRuchika Gupta 		 */
346de94d6f8SRuchika Gupta 		if (key_type == PKCS11_CKK_GENERIC_SECRET)
347de94d6f8SRuchika Gupta 			rc = pkcsmech2tee_key_type(&tee_key_type,
348de94d6f8SRuchika Gupta 						   proc_params->id);
349de94d6f8SRuchika Gupta 		else
350512cbf1dSJens Wiklander 			rc = pkcs2tee_key_type(&tee_key_type, obj);
351de94d6f8SRuchika Gupta 
352512cbf1dSJens Wiklander 		if (rc)
353512cbf1dSJens Wiklander 			return rc;
354512cbf1dSJens Wiklander 
3552d0cd829SRuchika Gupta 		mechanism_supported_key_sizes_bytes(proc_params->id,
3562158ea6cSRuchika Gupta 						    &min_key_size,
3572158ea6cSRuchika Gupta 						    &max_key_size);
3582158ea6cSRuchika Gupta 
3592158ea6cSRuchika Gupta 		if ((object_size / 8) > max_key_size) {
3602158ea6cSRuchika Gupta 			rc = hash_secret_helper(proc_params->id, obj, &tee_attr,
3612158ea6cSRuchika Gupta 						&session->processing->extra_ctx,
3622158ea6cSRuchika Gupta 						&object_size);
3632158ea6cSRuchika Gupta 			if (rc)
3642158ea6cSRuchika Gupta 				return rc;
3652158ea6cSRuchika Gupta 		} else {
3662158ea6cSRuchika Gupta 			if (!pkcs2tee_load_attr(&tee_attr,
3672158ea6cSRuchika Gupta 						TEE_ATTR_SECRET_VALUE,
3682158ea6cSRuchika Gupta 						obj,
3692158ea6cSRuchika Gupta 						PKCS11_CKA_VALUE)) {
3702158ea6cSRuchika Gupta 				EMSG("No secret found");
3712158ea6cSRuchika Gupta 				return PKCS11_CKR_FUNCTION_FAILED;
3722158ea6cSRuchika Gupta 			}
3732158ea6cSRuchika Gupta 		}
3742158ea6cSRuchika Gupta 		break;
3752158ea6cSRuchika Gupta 
3762158ea6cSRuchika Gupta 	default:
3772158ea6cSRuchika Gupta 		rc = pkcs2tee_key_type(&tee_key_type, obj);
3782158ea6cSRuchika Gupta 		if (rc)
3792158ea6cSRuchika Gupta 			return rc;
3802158ea6cSRuchika Gupta 
3812158ea6cSRuchika Gupta 		if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE,
3822158ea6cSRuchika Gupta 					obj, PKCS11_CKA_VALUE)) {
3832158ea6cSRuchika Gupta 			EMSG("No secret found");
3842158ea6cSRuchika Gupta 			return PKCS11_CKR_FUNCTION_FAILED;
3852158ea6cSRuchika Gupta 		}
3862158ea6cSRuchika Gupta 		break;
3872158ea6cSRuchika Gupta 	}
388512cbf1dSJens Wiklander 
389512cbf1dSJens Wiklander 	res = TEE_AllocateTransientObject(tee_key_type, object_size,
390512cbf1dSJens Wiklander 					  &obj->key_handle);
391512cbf1dSJens Wiklander 	if (res) {
392512cbf1dSJens Wiklander 		DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res);
393512cbf1dSJens Wiklander 		return tee2pkcs_error(res);
394512cbf1dSJens Wiklander 	}
395512cbf1dSJens Wiklander 
396512cbf1dSJens Wiklander 	res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1);
397512cbf1dSJens Wiklander 	if (res) {
398512cbf1dSJens Wiklander 		DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res);
399512cbf1dSJens Wiklander 		goto error;
400512cbf1dSJens Wiklander 	}
401512cbf1dSJens Wiklander 
402512cbf1dSJens Wiklander key_ready:
403512cbf1dSJens Wiklander 	res = TEE_SetOperationKey(session->processing->tee_op_handle,
404512cbf1dSJens Wiklander 				  obj->key_handle);
405512cbf1dSJens Wiklander 	if (res) {
406512cbf1dSJens Wiklander 		DMSG("TEE_SetOperationKey failed, %#"PRIx32, res);
407512cbf1dSJens Wiklander 		goto error;
408512cbf1dSJens Wiklander 	}
409512cbf1dSJens Wiklander 
410512cbf1dSJens Wiklander 	return PKCS11_CKR_OK;
411512cbf1dSJens Wiklander 
412512cbf1dSJens Wiklander error:
413512cbf1dSJens Wiklander 	TEE_FreeTransientObject(obj->key_handle);
414512cbf1dSJens Wiklander 	obj->key_handle = TEE_HANDLE_NULL;
415512cbf1dSJens Wiklander 
416512cbf1dSJens Wiklander 	return tee2pkcs_error(res);
417512cbf1dSJens Wiklander }
418512cbf1dSJens Wiklander 
419512cbf1dSJens Wiklander static enum pkcs11_rc
42048799892SRuchika Gupta tee_init_derive_symm(struct active_processing *processing,
42148799892SRuchika Gupta 		     struct pkcs11_attribute_head *proc_params)
42248799892SRuchika Gupta {
42348799892SRuchika Gupta 	struct serialargs args = { };
42448799892SRuchika Gupta 	enum pkcs11_rc rc = PKCS11_CKR_OK;
42548799892SRuchika Gupta 	struct input_data_ref *param = NULL;
42648799892SRuchika Gupta 	void *iv = NULL;
42748799892SRuchika Gupta 
42848799892SRuchika Gupta 	if (!proc_params)
42948799892SRuchika Gupta 		return PKCS11_CKR_ARGUMENTS_BAD;
43048799892SRuchika Gupta 
43148799892SRuchika Gupta 	param =	TEE_Malloc(sizeof(struct input_data_ref), TEE_MALLOC_FILL_ZERO);
43248799892SRuchika Gupta 	if (!param)
43348799892SRuchika Gupta 		return PKCS11_CKR_DEVICE_MEMORY;
43448799892SRuchika Gupta 
43548799892SRuchika Gupta 	serialargs_init(&args, proc_params->data, proc_params->size);
43648799892SRuchika Gupta 
43748799892SRuchika Gupta 	switch (proc_params->id) {
43848799892SRuchika Gupta 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
43948799892SRuchika Gupta 		rc = serialargs_get_ptr(&args, &iv, 16);
44048799892SRuchika Gupta 		if (rc)
44148799892SRuchika Gupta 			goto err;
44248799892SRuchika Gupta 		break;
44348799892SRuchika Gupta 	default:
44448799892SRuchika Gupta 		break;
44548799892SRuchika Gupta 	}
44648799892SRuchika Gupta 
44748799892SRuchika Gupta 	rc = serialargs_get(&args, &param->size, sizeof(uint32_t));
44848799892SRuchika Gupta 	if (rc)
44948799892SRuchika Gupta 		goto err;
45048799892SRuchika Gupta 
45148799892SRuchika Gupta 	rc = serialargs_get_ptr(&args, &param->data, param->size);
45248799892SRuchika Gupta 	if (rc)
45348799892SRuchika Gupta 		goto err;
45448799892SRuchika Gupta 
45548799892SRuchika Gupta 	if (serialargs_remaining_bytes(&args)) {
45648799892SRuchika Gupta 		rc = PKCS11_CKR_ARGUMENTS_BAD;
45748799892SRuchika Gupta 		goto err;
45848799892SRuchika Gupta 	}
45948799892SRuchika Gupta 
46048799892SRuchika Gupta 	processing->extra_ctx = param;
46148799892SRuchika Gupta 
46248799892SRuchika Gupta 	switch (proc_params->id) {
46348799892SRuchika Gupta 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
46448799892SRuchika Gupta 		if (param->size % TEE_AES_BLOCK_SIZE) {
46548799892SRuchika Gupta 			rc = PKCS11_CKR_DATA_LEN_RANGE;
46648799892SRuchika Gupta 			goto err;
46748799892SRuchika Gupta 		}
46848799892SRuchika Gupta 		TEE_CipherInit(processing->tee_op_handle, NULL, 0);
46948799892SRuchika Gupta 		break;
47048799892SRuchika Gupta 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
47148799892SRuchika Gupta 		if (param->size % TEE_AES_BLOCK_SIZE) {
47248799892SRuchika Gupta 			rc = PKCS11_CKR_DATA_LEN_RANGE;
47348799892SRuchika Gupta 			goto err;
47448799892SRuchika Gupta 		}
47548799892SRuchika Gupta 		TEE_CipherInit(processing->tee_op_handle, iv, 16);
47648799892SRuchika Gupta 		break;
47748799892SRuchika Gupta 	default:
47848799892SRuchika Gupta 		TEE_Panic(proc_params->id);
47948799892SRuchika Gupta 		break;
48048799892SRuchika Gupta 	}
48148799892SRuchika Gupta 
48248799892SRuchika Gupta 	return PKCS11_CKR_OK;
48348799892SRuchika Gupta 
48448799892SRuchika Gupta err:
48548799892SRuchika Gupta 	processing->extra_ctx = NULL;
48648799892SRuchika Gupta 	TEE_Free(param);
48748799892SRuchika Gupta 	return rc;
48848799892SRuchika Gupta }
48948799892SRuchika Gupta 
49048799892SRuchika Gupta static enum pkcs11_rc
49170b6683bSVictor Chong input_hmac_len_is_valid(struct pkcs11_attribute_head *proc_params,
49270b6683bSVictor Chong 			uint32_t hmac_len)
49370b6683bSVictor Chong {
49470b6683bSVictor Chong 	uint32_t sign_sz = 0;
49570b6683bSVictor Chong 
49670b6683bSVictor Chong 	switch (proc_params->id) {
49770b6683bSVictor Chong 	case PKCS11_CKM_MD5_HMAC_GENERAL:
49870b6683bSVictor Chong 		sign_sz = TEE_MD5_HASH_SIZE;
49970b6683bSVictor Chong 		break;
50070b6683bSVictor Chong 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
50170b6683bSVictor Chong 		sign_sz = TEE_SHA1_HASH_SIZE;
50270b6683bSVictor Chong 		break;
50370b6683bSVictor Chong 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
50470b6683bSVictor Chong 		sign_sz = TEE_SHA224_HASH_SIZE;
50570b6683bSVictor Chong 		break;
50670b6683bSVictor Chong 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
50770b6683bSVictor Chong 		sign_sz = TEE_SHA256_HASH_SIZE;
50870b6683bSVictor Chong 		break;
50970b6683bSVictor Chong 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
51070b6683bSVictor Chong 		sign_sz = TEE_SHA384_HASH_SIZE;
51170b6683bSVictor Chong 		break;
51270b6683bSVictor Chong 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
51370b6683bSVictor Chong 		sign_sz = TEE_SHA512_HASH_SIZE;
51470b6683bSVictor Chong 		break;
5150ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC_GENERAL:
5160ef6b144SVictor Chong 		sign_sz = TEE_AES_BLOCK_SIZE;
5170ef6b144SVictor Chong 		break;
51870b6683bSVictor Chong 	default:
51970b6683bSVictor Chong 		return PKCS11_CKR_MECHANISM_INVALID;
52070b6683bSVictor Chong 	}
52170b6683bSVictor Chong 
52270b6683bSVictor Chong 	if (!hmac_len || hmac_len > sign_sz)
52370b6683bSVictor Chong 		return PKCS11_CKR_SIGNATURE_LEN_RANGE;
52470b6683bSVictor Chong 
52570b6683bSVictor Chong 	return PKCS11_CKR_OK;
52670b6683bSVictor Chong }
52770b6683bSVictor Chong 
52870b6683bSVictor Chong static enum pkcs11_rc
529512cbf1dSJens Wiklander init_tee_operation(struct pkcs11_session *session,
530512cbf1dSJens Wiklander 		   struct pkcs11_attribute_head *proc_params)
531512cbf1dSJens Wiklander {
532512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
53370b6683bSVictor Chong 	uint32_t *pkcs11_data = NULL;
534512cbf1dSJens Wiklander 
535512cbf1dSJens Wiklander 	switch (proc_params->id) {
5360ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC:
537689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
538689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
539689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
540689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
541689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
542689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
543689f4e5bSRuchika Gupta 		if (proc_params->size)
544689f4e5bSRuchika Gupta 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
545689f4e5bSRuchika Gupta 
546689f4e5bSRuchika Gupta 		TEE_MACInit(session->processing->tee_op_handle, NULL, 0);
547689f4e5bSRuchika Gupta 		rc = PKCS11_CKR_OK;
548689f4e5bSRuchika Gupta 		break;
5490ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC_GENERAL:
55070b6683bSVictor Chong 	case PKCS11_CKM_MD5_HMAC_GENERAL:
55170b6683bSVictor Chong 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
55270b6683bSVictor Chong 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
55370b6683bSVictor Chong 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
55470b6683bSVictor Chong 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
55570b6683bSVictor Chong 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
55670b6683bSVictor Chong 		if (proc_params->size != sizeof(uint32_t))
55770b6683bSVictor Chong 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
55870b6683bSVictor Chong 
55970b6683bSVictor Chong 		pkcs11_data = TEE_Malloc(sizeof(uint32_t),
56070b6683bSVictor Chong 					 TEE_MALLOC_FILL_ZERO);
56170b6683bSVictor Chong 		if (!pkcs11_data)
56270b6683bSVictor Chong 			return PKCS11_CKR_DEVICE_MEMORY;
56370b6683bSVictor Chong 
56470b6683bSVictor Chong 		TEE_MemMove(pkcs11_data, proc_params->data, sizeof(uint32_t));
56570b6683bSVictor Chong 
56670b6683bSVictor Chong 		rc = input_hmac_len_is_valid(proc_params, *pkcs11_data);
56770b6683bSVictor Chong 		if (rc) {
56870b6683bSVictor Chong 			TEE_Free(pkcs11_data);
56970b6683bSVictor Chong 			return rc;
57070b6683bSVictor Chong 		}
57170b6683bSVictor Chong 
57270b6683bSVictor Chong 		session->processing->extra_ctx = (void *)pkcs11_data;
57370b6683bSVictor Chong 
57470b6683bSVictor Chong 		TEE_MACInit(session->processing->tee_op_handle, NULL, 0);
57570b6683bSVictor Chong 		rc = PKCS11_CKR_OK;
57670b6683bSVictor Chong 		break;
577512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
578512cbf1dSJens Wiklander 		if (proc_params->size)
579512cbf1dSJens Wiklander 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
580512cbf1dSJens Wiklander 
581512cbf1dSJens Wiklander 		TEE_CipherInit(session->processing->tee_op_handle, NULL, 0);
582512cbf1dSJens Wiklander 		rc = PKCS11_CKR_OK;
583512cbf1dSJens Wiklander 		break;
584512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
585512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
586512cbf1dSJens Wiklander 		if (proc_params->size != 16)
587512cbf1dSJens Wiklander 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
588512cbf1dSJens Wiklander 
589512cbf1dSJens Wiklander 		TEE_CipherInit(session->processing->tee_op_handle,
590512cbf1dSJens Wiklander 			       proc_params->data, 16);
591512cbf1dSJens Wiklander 		rc = PKCS11_CKR_OK;
592512cbf1dSJens Wiklander 		break;
593512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
594512cbf1dSJens Wiklander 		rc = tee_init_ctr_operation(session->processing,
595512cbf1dSJens Wiklander 					    proc_params->data,
596512cbf1dSJens Wiklander 					    proc_params->size);
597512cbf1dSJens Wiklander 		break;
59848799892SRuchika Gupta 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
59948799892SRuchika Gupta 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
60048799892SRuchika Gupta 		rc = tee_init_derive_symm(session->processing, proc_params);
60148799892SRuchika Gupta 		break;
602512cbf1dSJens Wiklander 	default:
603512cbf1dSJens Wiklander 		TEE_Panic(proc_params->id);
604512cbf1dSJens Wiklander 		break;
605512cbf1dSJens Wiklander 	}
606512cbf1dSJens Wiklander 
607512cbf1dSJens Wiklander 	return rc;
608512cbf1dSJens Wiklander }
609512cbf1dSJens Wiklander 
610512cbf1dSJens Wiklander enum pkcs11_rc init_symm_operation(struct pkcs11_session *session,
611512cbf1dSJens Wiklander 				   enum processing_func function,
612512cbf1dSJens Wiklander 				   struct pkcs11_attribute_head *proc_params,
613512cbf1dSJens Wiklander 				   struct pkcs11_object *obj)
614512cbf1dSJens Wiklander {
615512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
616512cbf1dSJens Wiklander 
617512cbf1dSJens Wiklander 	assert(processing_is_tee_symm(proc_params->id));
618512cbf1dSJens Wiklander 
619512cbf1dSJens Wiklander 	rc = allocate_tee_operation(session, function, proc_params, obj);
620512cbf1dSJens Wiklander 	if (rc)
621512cbf1dSJens Wiklander 		return rc;
622512cbf1dSJens Wiklander 
623de94d6f8SRuchika Gupta 	rc = load_tee_key(session, obj, proc_params);
624512cbf1dSJens Wiklander 	if (rc)
625512cbf1dSJens Wiklander 		return rc;
626512cbf1dSJens Wiklander 
627909efccbSEtienne Carriere 	rc = init_tee_operation(session, proc_params);
628909efccbSEtienne Carriere 	if (!rc)
629909efccbSEtienne Carriere 		session->processing->mecha_type = proc_params->id;
630909efccbSEtienne Carriere 
631909efccbSEtienne Carriere 	return rc;
632512cbf1dSJens Wiklander }
633512cbf1dSJens Wiklander 
634512cbf1dSJens Wiklander /* Validate input buffer size as per PKCS#11 constraints */
635512cbf1dSJens Wiklander static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc,
636512cbf1dSJens Wiklander 					       enum processing_func function,
637512cbf1dSJens Wiklander 					       size_t in_size)
638512cbf1dSJens Wiklander {
639512cbf1dSJens Wiklander 	switch (proc->mecha_type) {
640512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
641512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
642512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_ENCRYPT &&
643512cbf1dSJens Wiklander 		    in_size % TEE_AES_BLOCK_SIZE)
644512cbf1dSJens Wiklander 			return PKCS11_CKR_DATA_LEN_RANGE;
645512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_DECRYPT &&
646512cbf1dSJens Wiklander 		    in_size % TEE_AES_BLOCK_SIZE)
647512cbf1dSJens Wiklander 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
648512cbf1dSJens Wiklander 		break;
649512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
650512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_ENCRYPT &&
651512cbf1dSJens Wiklander 		    in_size < TEE_AES_BLOCK_SIZE)
652512cbf1dSJens Wiklander 			return PKCS11_CKR_DATA_LEN_RANGE;
653512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_DECRYPT &&
654512cbf1dSJens Wiklander 		    in_size < TEE_AES_BLOCK_SIZE)
655512cbf1dSJens Wiklander 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
656512cbf1dSJens Wiklander 		break;
657512cbf1dSJens Wiklander 	default:
658512cbf1dSJens Wiklander 		break;
659512cbf1dSJens Wiklander 	}
660512cbf1dSJens Wiklander 
661512cbf1dSJens Wiklander 	return PKCS11_CKR_OK;
662512cbf1dSJens Wiklander }
663512cbf1dSJens Wiklander 
664689f4e5bSRuchika Gupta /* Validate input buffer size as per PKCS#11 constraints */
665689f4e5bSRuchika Gupta static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc,
666689f4e5bSRuchika Gupta 					       size_t in_size)
667689f4e5bSRuchika Gupta {
668689f4e5bSRuchika Gupta 	size_t sign_sz = 0;
669689f4e5bSRuchika Gupta 
670689f4e5bSRuchika Gupta 	switch (proc->mecha_type) {
671689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
672689f4e5bSRuchika Gupta 		sign_sz = TEE_MD5_HASH_SIZE;
673689f4e5bSRuchika Gupta 		break;
674689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
675689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA1_HASH_SIZE;
676689f4e5bSRuchika Gupta 		break;
677689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
678689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA224_HASH_SIZE;
679689f4e5bSRuchika Gupta 		break;
680689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
681689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA256_HASH_SIZE;
682689f4e5bSRuchika Gupta 		break;
683689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
684689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA384_HASH_SIZE;
685689f4e5bSRuchika Gupta 		break;
686689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
687689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA512_HASH_SIZE;
688689f4e5bSRuchika Gupta 		break;
6890ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC:
6900ef6b144SVictor Chong 		sign_sz = TEE_AES_BLOCK_SIZE;
6910ef6b144SVictor Chong 		break;
692689f4e5bSRuchika Gupta 	default:
693689f4e5bSRuchika Gupta 		return PKCS11_CKR_GENERAL_ERROR;
694689f4e5bSRuchika Gupta 	}
695689f4e5bSRuchika Gupta 
69642765f82SVictor Chong 	if (in_size != sign_sz)
697689f4e5bSRuchika Gupta 		return PKCS11_CKR_SIGNATURE_LEN_RANGE;
698689f4e5bSRuchika Gupta 
699689f4e5bSRuchika Gupta 	return PKCS11_CKR_OK;
700689f4e5bSRuchika Gupta }
701689f4e5bSRuchika Gupta 
702512cbf1dSJens Wiklander /*
703512cbf1dSJens Wiklander  * step_sym_cipher - processing symmetric (and related) cipher operation step
704512cbf1dSJens Wiklander  *
705512cbf1dSJens Wiklander  * @session - current session
706512cbf1dSJens Wiklander  * @function - processing function (encrypt, decrypt, sign, ...)
707512cbf1dSJens Wiklander  * @step - step ID in the processing (oneshot, update, final)
708512cbf1dSJens Wiklander  * @ptype - invocation parameter types
709512cbf1dSJens Wiklander  * @params - invocation parameter references
710512cbf1dSJens Wiklander  */
711512cbf1dSJens Wiklander enum pkcs11_rc step_symm_operation(struct pkcs11_session *session,
712512cbf1dSJens Wiklander 				   enum processing_func function,
713512cbf1dSJens Wiklander 				   enum processing_step step,
714512cbf1dSJens Wiklander 				   uint32_t ptypes, TEE_Param *params)
715512cbf1dSJens Wiklander {
716512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
717512cbf1dSJens Wiklander 	TEE_Result res = TEE_ERROR_GENERIC;
718512cbf1dSJens Wiklander 	void *in_buf = NULL;
719512cbf1dSJens Wiklander 	size_t in_size = 0;
720512cbf1dSJens Wiklander 	void *out_buf = NULL;
721*c7f1b4f7SJens Wiklander 	size_t out_size = 0;
722512cbf1dSJens Wiklander 	void *in2_buf = NULL;
723512cbf1dSJens Wiklander 	uint32_t in2_size = 0;
724512cbf1dSJens Wiklander 	bool output_data = false;
725512cbf1dSJens Wiklander 	struct active_processing *proc = session->processing;
72670b6683bSVictor Chong 	uint32_t hmac_len = 0;
72770b6683bSVictor Chong 	uint8_t computed_mac[TEE_MAX_HASH_SIZE] = { 0 };
728*c7f1b4f7SJens Wiklander 	size_t computed_mac_size = TEE_MAX_HASH_SIZE;
729512cbf1dSJens Wiklander 
730512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) {
731512cbf1dSJens Wiklander 		in_buf = params[1].memref.buffer;
732512cbf1dSJens Wiklander 		in_size = params[1].memref.size;
733512cbf1dSJens Wiklander 		if (in_size && !in_buf)
734512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
735512cbf1dSJens Wiklander 	}
736512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) {
737512cbf1dSJens Wiklander 		in2_buf = params[2].memref.buffer;
738512cbf1dSJens Wiklander 		in2_size = params[2].memref.size;
739512cbf1dSJens Wiklander 		if (in2_size && !in2_buf)
740512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
741512cbf1dSJens Wiklander 	}
742512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) {
743512cbf1dSJens Wiklander 		out_buf = params[2].memref.buffer;
744512cbf1dSJens Wiklander 		out_size = params[2].memref.size;
745512cbf1dSJens Wiklander 		if (out_size && !out_buf)
746512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
747512cbf1dSJens Wiklander 	}
748512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE)
749512cbf1dSJens Wiklander 		return PKCS11_CKR_ARGUMENTS_BAD;
750512cbf1dSJens Wiklander 
751512cbf1dSJens Wiklander 	switch (step) {
752512cbf1dSJens Wiklander 	case PKCS11_FUNC_STEP_ONESHOT:
753512cbf1dSJens Wiklander 	case PKCS11_FUNC_STEP_UPDATE:
754512cbf1dSJens Wiklander 	case PKCS11_FUNC_STEP_FINAL:
755512cbf1dSJens Wiklander 		break;
756512cbf1dSJens Wiklander 	default:
757512cbf1dSJens Wiklander 		return PKCS11_CKR_GENERAL_ERROR;
758512cbf1dSJens Wiklander 	}
759512cbf1dSJens Wiklander 
760512cbf1dSJens Wiklander 	if (step != PKCS11_FUNC_STEP_FINAL) {
761512cbf1dSJens Wiklander 		rc = input_data_size_is_valid(proc, function, in_size);
762512cbf1dSJens Wiklander 		if (rc)
763512cbf1dSJens Wiklander 			return rc;
764512cbf1dSJens Wiklander 	}
765512cbf1dSJens Wiklander 
766512cbf1dSJens Wiklander 	/*
767512cbf1dSJens Wiklander 	 * Feed active operation with data
768512cbf1dSJens Wiklander 	 */
769512cbf1dSJens Wiklander 	switch (proc->mecha_type) {
7700ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC:
771689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
772689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
773689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
774689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
775689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
776689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
7770ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC_GENERAL:
77870b6683bSVictor Chong 	case PKCS11_CKM_MD5_HMAC_GENERAL:
77970b6683bSVictor Chong 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
78070b6683bSVictor Chong 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
78170b6683bSVictor Chong 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
78270b6683bSVictor Chong 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
78370b6683bSVictor Chong 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
784689f4e5bSRuchika Gupta 		if (step == PKCS11_FUNC_STEP_FINAL ||
785689f4e5bSRuchika Gupta 		    step == PKCS11_FUNC_STEP_ONESHOT)
786689f4e5bSRuchika Gupta 			break;
787689f4e5bSRuchika Gupta 
788689f4e5bSRuchika Gupta 		if (!in_buf) {
789689f4e5bSRuchika Gupta 			DMSG("No input data");
790689f4e5bSRuchika Gupta 			return PKCS11_CKR_ARGUMENTS_BAD;
791689f4e5bSRuchika Gupta 		}
792689f4e5bSRuchika Gupta 
793689f4e5bSRuchika Gupta 		switch (function) {
794689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_SIGN:
795689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_VERIFY:
796689f4e5bSRuchika Gupta 			TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size);
797689f4e5bSRuchika Gupta 			rc = PKCS11_CKR_OK;
798689f4e5bSRuchika Gupta 			break;
799689f4e5bSRuchika Gupta 		default:
800689f4e5bSRuchika Gupta 			TEE_Panic(function);
801689f4e5bSRuchika Gupta 			break;
802689f4e5bSRuchika Gupta 		}
803689f4e5bSRuchika Gupta 		break;
804689f4e5bSRuchika Gupta 
805512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
806512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
807512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
808512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
809512cbf1dSJens Wiklander 		if (step == PKCS11_FUNC_STEP_FINAL ||
810512cbf1dSJens Wiklander 		    step == PKCS11_FUNC_STEP_ONESHOT)
811512cbf1dSJens Wiklander 			break;
812512cbf1dSJens Wiklander 
813512cbf1dSJens Wiklander 		if (!in_buf) {
814512cbf1dSJens Wiklander 			EMSG("No input data");
815512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
816512cbf1dSJens Wiklander 		}
817512cbf1dSJens Wiklander 
818512cbf1dSJens Wiklander 		switch (function) {
819512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_ENCRYPT:
820512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_DECRYPT:
821512cbf1dSJens Wiklander 			res = TEE_CipherUpdate(proc->tee_op_handle,
822512cbf1dSJens Wiklander 					       in_buf, in_size,
823512cbf1dSJens Wiklander 						out_buf, &out_size);
824512cbf1dSJens Wiklander 			output_data = true;
825512cbf1dSJens Wiklander 			rc = tee2pkcs_error(res);
826512cbf1dSJens Wiklander 			break;
827512cbf1dSJens Wiklander 		default:
828512cbf1dSJens Wiklander 			TEE_Panic(function);
829512cbf1dSJens Wiklander 			break;
830512cbf1dSJens Wiklander 		}
831512cbf1dSJens Wiklander 		break;
832512cbf1dSJens Wiklander 
833512cbf1dSJens Wiklander 	default:
834512cbf1dSJens Wiklander 		TEE_Panic(proc->mecha_type);
835512cbf1dSJens Wiklander 		break;
836512cbf1dSJens Wiklander 	}
837512cbf1dSJens Wiklander 
838512cbf1dSJens Wiklander 	if (step == PKCS11_FUNC_STEP_UPDATE)
839512cbf1dSJens Wiklander 		goto out;
840512cbf1dSJens Wiklander 
841512cbf1dSJens Wiklander 	/*
842512cbf1dSJens Wiklander 	 * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation
843512cbf1dSJens Wiklander 	 */
844512cbf1dSJens Wiklander 	switch (session->processing->mecha_type) {
8450ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC:
846689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
847689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
848689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
849689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
850689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
851689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
852689f4e5bSRuchika Gupta 		switch (function) {
853689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_SIGN:
854689f4e5bSRuchika Gupta 			res = TEE_MACComputeFinal(proc->tee_op_handle,
855689f4e5bSRuchika Gupta 						  in_buf, in_size, out_buf,
856689f4e5bSRuchika Gupta 						  &out_size);
857689f4e5bSRuchika Gupta 			output_data = true;
858689f4e5bSRuchika Gupta 			rc = tee2pkcs_error(res);
859689f4e5bSRuchika Gupta 			break;
860689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_VERIFY:
861689f4e5bSRuchika Gupta 			rc = input_sign_size_is_valid(proc, in2_size);
862689f4e5bSRuchika Gupta 			if (rc)
863689f4e5bSRuchika Gupta 				return rc;
864689f4e5bSRuchika Gupta 			res = TEE_MACCompareFinal(proc->tee_op_handle,
865689f4e5bSRuchika Gupta 						  in_buf, in_size, in2_buf,
866689f4e5bSRuchika Gupta 						  in2_size);
867689f4e5bSRuchika Gupta 			rc = tee2pkcs_error(res);
868689f4e5bSRuchika Gupta 			break;
869689f4e5bSRuchika Gupta 		default:
870689f4e5bSRuchika Gupta 			TEE_Panic(function);
871689f4e5bSRuchika Gupta 			break;
872689f4e5bSRuchika Gupta 		}
8732158ea6cSRuchika Gupta 
874689f4e5bSRuchika Gupta 		break;
875689f4e5bSRuchika Gupta 
8760ef6b144SVictor Chong 	case PKCS11_CKM_AES_CMAC_GENERAL:
87770b6683bSVictor Chong 	case PKCS11_CKM_MD5_HMAC_GENERAL:
87870b6683bSVictor Chong 	case PKCS11_CKM_SHA_1_HMAC_GENERAL:
87970b6683bSVictor Chong 	case PKCS11_CKM_SHA224_HMAC_GENERAL:
88070b6683bSVictor Chong 	case PKCS11_CKM_SHA256_HMAC_GENERAL:
88170b6683bSVictor Chong 	case PKCS11_CKM_SHA384_HMAC_GENERAL:
88270b6683bSVictor Chong 	case PKCS11_CKM_SHA512_HMAC_GENERAL:
88370b6683bSVictor Chong 		assert(session->processing->extra_ctx);
88470b6683bSVictor Chong 		hmac_len = *(uint32_t *)session->processing->extra_ctx;
88570b6683bSVictor Chong 
88670b6683bSVictor Chong 		switch (function) {
88770b6683bSVictor Chong 		case PKCS11_FUNCTION_SIGN:
88870b6683bSVictor Chong 			if (out_size < hmac_len) {
88970b6683bSVictor Chong 				/* inform client of required size */
89070b6683bSVictor Chong 				out_size = hmac_len;
89170b6683bSVictor Chong 				output_data = true;
89270b6683bSVictor Chong 				rc = PKCS11_CKR_BUFFER_TOO_SMALL;
89370b6683bSVictor Chong 				goto out;
89470b6683bSVictor Chong 			}
89570b6683bSVictor Chong 
89670b6683bSVictor Chong 			res = TEE_MACComputeFinal(proc->tee_op_handle,
89770b6683bSVictor Chong 						  in_buf, in_size,
89870b6683bSVictor Chong 						  computed_mac,
89970b6683bSVictor Chong 						  &computed_mac_size);
90070b6683bSVictor Chong 			if (res == TEE_SUCCESS) {
90170b6683bSVictor Chong 				/* truncate to hmac_len */
90270b6683bSVictor Chong 				TEE_MemMove(out_buf, computed_mac, hmac_len);
90370b6683bSVictor Chong 				output_data = true;
90470b6683bSVictor Chong 			}
90570b6683bSVictor Chong 
90670b6683bSVictor Chong 			/* inform client of required size */
90770b6683bSVictor Chong 			out_size = hmac_len;
90870b6683bSVictor Chong 			rc = tee2pkcs_error(res);
90970b6683bSVictor Chong 			break;
91070b6683bSVictor Chong 		case PKCS11_FUNCTION_VERIFY:
91170b6683bSVictor Chong 			/* must compute full MAC before comparing partial */
91270b6683bSVictor Chong 			res = TEE_MACComputeFinal(proc->tee_op_handle, in_buf,
91370b6683bSVictor Chong 						  in_size, computed_mac,
91470b6683bSVictor Chong 						  &computed_mac_size);
91570b6683bSVictor Chong 
91670b6683bSVictor Chong 			if (!in2_size || in2_size > computed_mac_size) {
91770b6683bSVictor Chong 				EMSG("Invalid signature size: %"PRIu32,
91870b6683bSVictor Chong 				     in2_size);
91970b6683bSVictor Chong 				return PKCS11_CKR_SIGNATURE_LEN_RANGE;
92070b6683bSVictor Chong 			}
92170b6683bSVictor Chong 
92270b6683bSVictor Chong 			if (res == TEE_SUCCESS) {
92370b6683bSVictor Chong 				/*
92470b6683bSVictor Chong 				 * Only the first in2_size bytes of the
92570b6683bSVictor Chong 				 * signature to be verified is passed in from
92670b6683bSVictor Chong 				 * caller
92770b6683bSVictor Chong 				 */
92870b6683bSVictor Chong 				if (TEE_MemCompare(in2_buf, computed_mac,
92970b6683bSVictor Chong 						   in2_size)) {
93070b6683bSVictor Chong 					res = TEE_ERROR_MAC_INVALID;
93170b6683bSVictor Chong 				}
93270b6683bSVictor Chong 			}
93370b6683bSVictor Chong 
93470b6683bSVictor Chong 			rc = tee2pkcs_error(res);
93570b6683bSVictor Chong 			break;
93670b6683bSVictor Chong 		default:
93770b6683bSVictor Chong 			TEE_Panic(function);
93870b6683bSVictor Chong 			break;
93970b6683bSVictor Chong 		}
94070b6683bSVictor Chong 
94170b6683bSVictor Chong 		break;
94270b6683bSVictor Chong 
943512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
944512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
945512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
946512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
947512cbf1dSJens Wiklander 		if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) {
948512cbf1dSJens Wiklander 			EMSG("No input data");
949512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
950512cbf1dSJens Wiklander 		}
951512cbf1dSJens Wiklander 
952512cbf1dSJens Wiklander 		switch (function) {
953512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_ENCRYPT:
954512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_DECRYPT:
955512cbf1dSJens Wiklander 			res = TEE_CipherDoFinal(proc->tee_op_handle,
956512cbf1dSJens Wiklander 						in_buf, in_size,
957512cbf1dSJens Wiklander 						out_buf, &out_size);
958512cbf1dSJens Wiklander 			output_data = true;
959512cbf1dSJens Wiklander 			rc = tee2pkcs_error(res);
960512cbf1dSJens Wiklander 			break;
961512cbf1dSJens Wiklander 		default:
962512cbf1dSJens Wiklander 			TEE_Panic(function);
963512cbf1dSJens Wiklander 			break;
964512cbf1dSJens Wiklander 		}
965512cbf1dSJens Wiklander 		break;
966512cbf1dSJens Wiklander 	default:
967512cbf1dSJens Wiklander 		TEE_Panic(proc->mecha_type);
968512cbf1dSJens Wiklander 		break;
969512cbf1dSJens Wiklander 	}
970512cbf1dSJens Wiklander 
971512cbf1dSJens Wiklander out:
972512cbf1dSJens Wiklander 	if (output_data &&
973512cbf1dSJens Wiklander 	    (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) {
974512cbf1dSJens Wiklander 		switch (TEE_PARAM_TYPE_GET(ptypes, 2)) {
975512cbf1dSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
976512cbf1dSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
977512cbf1dSJens Wiklander 			params[2].memref.size = out_size;
978512cbf1dSJens Wiklander 			break;
979512cbf1dSJens Wiklander 		default:
980512cbf1dSJens Wiklander 			rc = PKCS11_CKR_ARGUMENTS_BAD;
981512cbf1dSJens Wiklander 			break;
982512cbf1dSJens Wiklander 		}
983512cbf1dSJens Wiklander 	}
984512cbf1dSJens Wiklander 
985512cbf1dSJens Wiklander 	return rc;
986512cbf1dSJens Wiklander }
98748799892SRuchika Gupta 
98848799892SRuchika Gupta enum pkcs11_rc derive_key_by_symm_enc(struct pkcs11_session *session,
9898c499324SRuchika Gupta 				      void **out_buf, uint32_t *out_size)
99048799892SRuchika Gupta {
99148799892SRuchika Gupta 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
99248799892SRuchika Gupta 	TEE_Result res = TEE_ERROR_GENERIC;
99348799892SRuchika Gupta 	struct active_processing *proc = session->processing;
99448799892SRuchika Gupta 	struct input_data_ref *input = proc->extra_ctx;
99548799892SRuchika Gupta 	void *in_buf = NULL;
996a5ea52c2SElvira Khabirova 	void *dest_buf = NULL;
99748799892SRuchika Gupta 	uint32_t in_size = 0;
998*c7f1b4f7SJens Wiklander 	size_t tmp_sz = 0;
99948799892SRuchika Gupta 
10008c499324SRuchika Gupta 	switch (proc->mecha_type) {
10018c499324SRuchika Gupta 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
10028c499324SRuchika Gupta 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
100348799892SRuchika Gupta 		if (!proc->extra_ctx)
100448799892SRuchika Gupta 			return PKCS11_CKR_ARGUMENTS_BAD;
100548799892SRuchika Gupta 
100648799892SRuchika Gupta 		in_buf = input->data;
100748799892SRuchika Gupta 		in_size = input->size;
100848799892SRuchika Gupta 
10098c499324SRuchika Gupta 		*out_size = in_size;
1010a5ea52c2SElvira Khabirova 		dest_buf = TEE_Malloc(*out_size, 0);
1011a5ea52c2SElvira Khabirova 		if (!dest_buf)
101248799892SRuchika Gupta 			return PKCS11_CKR_DEVICE_MEMORY;
101348799892SRuchika Gupta 
1014*c7f1b4f7SJens Wiklander 		tmp_sz = *out_size;
10158c499324SRuchika Gupta 		res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_size,
1016*c7f1b4f7SJens Wiklander 					dest_buf, &tmp_sz);
1017*c7f1b4f7SJens Wiklander 		*out_size = tmp_sz;
101848799892SRuchika Gupta 		rc = tee2pkcs_error(res);
1019a5ea52c2SElvira Khabirova 		if (rc) {
1020a5ea52c2SElvira Khabirova 			TEE_Free(dest_buf);
1021a5ea52c2SElvira Khabirova 			return rc;
1022a5ea52c2SElvira Khabirova 		}
1023a5ea52c2SElvira Khabirova 
1024a5ea52c2SElvira Khabirova 		*out_buf = dest_buf;
10258c499324SRuchika Gupta 		break;
10268c499324SRuchika Gupta 	default:
10278c499324SRuchika Gupta 		return PKCS11_CKR_MECHANISM_INVALID;
102848799892SRuchika Gupta 	}
102948799892SRuchika Gupta 
103048799892SRuchika Gupta 	return rc;
103148799892SRuchika Gupta }
10325f80f270SRuchika Gupta 
10335f80f270SRuchika Gupta enum pkcs11_rc wrap_data_by_symm_enc(struct pkcs11_session *session,
10345f80f270SRuchika Gupta 				     void *data, uint32_t data_sz,
10355f80f270SRuchika Gupta 				     void *out_buf, uint32_t *out_sz)
10365f80f270SRuchika Gupta {
10375f80f270SRuchika Gupta 	TEE_Result res = TEE_ERROR_GENERIC;
10385f80f270SRuchika Gupta 	struct active_processing *proc = session->processing;
10395f80f270SRuchika Gupta 	void *in_buf = NULL;
10405f80f270SRuchika Gupta 	uint32_t align = 0;
10415f80f270SRuchika Gupta 	uint32_t in_sz = data_sz;
1042*c7f1b4f7SJens Wiklander 	size_t tmp_sz = *out_sz;
10435f80f270SRuchika Gupta 	uint8_t *tmp_buf = out_buf;
10445f80f270SRuchika Gupta 
10455f80f270SRuchika Gupta 	switch (proc->mecha_type) {
10465f80f270SRuchika Gupta 	case PKCS11_CKM_AES_ECB:
10475f80f270SRuchika Gupta 	case PKCS11_CKM_AES_CBC:
10485f80f270SRuchika Gupta 		align = data_sz % TEE_AES_BLOCK_SIZE;
10495f80f270SRuchika Gupta 		if (align)
10505f80f270SRuchika Gupta 			in_sz = data_sz + (TEE_AES_BLOCK_SIZE - align);
10515f80f270SRuchika Gupta 
10525f80f270SRuchika Gupta 		if (*out_sz < in_sz) {
10535f80f270SRuchika Gupta 			*out_sz = in_sz;
10545f80f270SRuchika Gupta 			return PKCS11_CKR_BUFFER_TOO_SMALL;
10555f80f270SRuchika Gupta 		}
10565f80f270SRuchika Gupta 
10575f80f270SRuchika Gupta 		if (align) {
10585f80f270SRuchika Gupta 			if (data_sz > TEE_AES_BLOCK_SIZE) {
10595f80f270SRuchika Gupta 				in_sz = data_sz - align;
10605f80f270SRuchika Gupta 				res = TEE_CipherUpdate(proc->tee_op_handle,
10615f80f270SRuchika Gupta 						       data, in_sz, tmp_buf,
10625f80f270SRuchika Gupta 						       &tmp_sz);
10635f80f270SRuchika Gupta 				if (res) {
10645f80f270SRuchika Gupta 					assert(res != TEE_ERROR_SHORT_BUFFER);
10655f80f270SRuchika Gupta 					return tee2pkcs_error(res);
10665f80f270SRuchika Gupta 				}
10675f80f270SRuchika Gupta 				tmp_buf += tmp_sz;
10685f80f270SRuchika Gupta 				tmp_sz = *out_sz - tmp_sz;
10695f80f270SRuchika Gupta 			} else {
10705f80f270SRuchika Gupta 				in_sz = 0;
10715f80f270SRuchika Gupta 			}
10725f80f270SRuchika Gupta 
10735f80f270SRuchika Gupta 			in_buf = TEE_Malloc(TEE_AES_BLOCK_SIZE,
10745f80f270SRuchika Gupta 					    TEE_MALLOC_FILL_ZERO);
10755f80f270SRuchika Gupta 			if (!in_buf)
10765f80f270SRuchika Gupta 				return PKCS11_CKR_DEVICE_MEMORY;
10775f80f270SRuchika Gupta 
10785f80f270SRuchika Gupta 			TEE_MemMove(in_buf, (uint8_t *)data + in_sz, align);
10795f80f270SRuchika Gupta 			in_sz = TEE_AES_BLOCK_SIZE;
10805f80f270SRuchika Gupta 		} else {
10815f80f270SRuchika Gupta 			in_buf = data;
10825f80f270SRuchika Gupta 			in_sz = data_sz;
10835f80f270SRuchika Gupta 		}
10845f80f270SRuchika Gupta 
10855f80f270SRuchika Gupta 		res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_sz,
10865f80f270SRuchika Gupta 					tmp_buf, &tmp_sz);
10875f80f270SRuchika Gupta 		if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
10885f80f270SRuchika Gupta 			*out_sz = tmp_sz;
10895f80f270SRuchika Gupta 			if (align)
10905f80f270SRuchika Gupta 				*out_sz += tmp_buf - (uint8_t *)out_buf;
10915f80f270SRuchika Gupta 		}
10925f80f270SRuchika Gupta 
10935f80f270SRuchika Gupta 		if (align)
10945f80f270SRuchika Gupta 			TEE_Free(in_buf);
10955f80f270SRuchika Gupta 
10965f80f270SRuchika Gupta 		return tee2pkcs_error(res);
10975f80f270SRuchika Gupta 	default:
10985f80f270SRuchika Gupta 		return PKCS11_CKR_MECHANISM_INVALID;
10995f80f270SRuchika Gupta 	}
11005f80f270SRuchika Gupta 
11015f80f270SRuchika Gupta 	return PKCS11_CKR_GENERAL_ERROR;
11025f80f270SRuchika Gupta }
11033668310bSRuchika Gupta 
11043668310bSRuchika Gupta enum pkcs11_rc unwrap_key_by_symm(struct pkcs11_session *session, void *data,
11053668310bSRuchika Gupta 				  uint32_t data_sz, void **out_buf,
11063668310bSRuchika Gupta 				  uint32_t *out_sz)
11073668310bSRuchika Gupta {
11083668310bSRuchika Gupta 	TEE_Result res = TEE_ERROR_GENERIC;
11093668310bSRuchika Gupta 	struct active_processing *proc = session->processing;
1110*c7f1b4f7SJens Wiklander 	size_t tmp_sz = 0;
11113668310bSRuchika Gupta 
11123668310bSRuchika Gupta 	if (input_data_size_is_valid(proc, PKCS11_FUNCTION_DECRYPT, data_sz))
11133668310bSRuchika Gupta 		return PKCS11_CKR_WRAPPED_KEY_LEN_RANGE;
11143668310bSRuchika Gupta 
11153668310bSRuchika Gupta 	switch (proc->mecha_type) {
11163668310bSRuchika Gupta 	case PKCS11_CKM_AES_ECB:
11173668310bSRuchika Gupta 	case PKCS11_CKM_AES_CBC:
11183668310bSRuchika Gupta 		*out_sz = 0;
11193668310bSRuchika Gupta 		res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz,
1120*c7f1b4f7SJens Wiklander 					NULL, &tmp_sz);
1121*c7f1b4f7SJens Wiklander 		*out_sz = tmp_sz;
11223668310bSRuchika Gupta 		if (res != TEE_ERROR_SHORT_BUFFER) {
11233668310bSRuchika Gupta 			DMSG("TEE_CipherDoFinal() issue: %#"PRIx32, res);
11243668310bSRuchika Gupta 			return PKCS11_CKR_GENERAL_ERROR;
11253668310bSRuchika Gupta 		}
11263668310bSRuchika Gupta 
11273668310bSRuchika Gupta 		*out_buf = TEE_Malloc(*out_sz, TEE_MALLOC_FILL_ZERO);
11283668310bSRuchika Gupta 		if (!*out_buf)
11293668310bSRuchika Gupta 			return PKCS11_CKR_DEVICE_MEMORY;
11303668310bSRuchika Gupta 
11313668310bSRuchika Gupta 		res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz,
1132*c7f1b4f7SJens Wiklander 					*out_buf, &tmp_sz);
1133*c7f1b4f7SJens Wiklander 		*out_sz = tmp_sz;
11343668310bSRuchika Gupta 		if (tee2pkcs_error(res)) {
11353668310bSRuchika Gupta 			TEE_Free(*out_buf);
11363668310bSRuchika Gupta 			*out_buf = NULL;
11373668310bSRuchika Gupta 			return PKCS11_CKR_WRAPPED_KEY_INVALID;
11383668310bSRuchika Gupta 		}
11393668310bSRuchika Gupta 		break;
11403668310bSRuchika Gupta 	default:
11413668310bSRuchika Gupta 		return PKCS11_CKR_MECHANISM_INVALID;
11423668310bSRuchika Gupta 	}
11433668310bSRuchika Gupta 
11443668310bSRuchika Gupta 	return PKCS11_CKR_OK;
11453668310bSRuchika Gupta }
1146