xref: /optee_os/ta/pkcs11/src/processing_symm.c (revision 2158ea6c997a50729b2fd99d35f003d8d7877ba1)
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 
23512cbf1dSJens Wiklander bool processing_is_tee_symm(enum pkcs11_mechanism_id proc_id)
24512cbf1dSJens Wiklander {
25512cbf1dSJens Wiklander 	switch (proc_id) {
26689f4e5bSRuchika Gupta 	/* Authentication */
27689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
28689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
29689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
30689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
31689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
32689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
33512cbf1dSJens Wiklander 	/* Cipherering */
34512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
35512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
36512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC_PAD:
37512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
38512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
39512cbf1dSJens Wiklander 		return true;
40512cbf1dSJens Wiklander 	default:
41512cbf1dSJens Wiklander 		return false;
42512cbf1dSJens Wiklander 	}
43512cbf1dSJens Wiklander }
44512cbf1dSJens Wiklander 
45512cbf1dSJens Wiklander static enum pkcs11_rc
46512cbf1dSJens Wiklander pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params)
47512cbf1dSJens Wiklander {
48512cbf1dSJens Wiklander 	static const struct {
49512cbf1dSJens Wiklander 		enum pkcs11_mechanism_id mech_id;
50512cbf1dSJens Wiklander 		uint32_t tee_id;
51512cbf1dSJens Wiklander 	} pkcs2tee_algo[] = {
52512cbf1dSJens Wiklander 		/* AES flavors */
53512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_ECB, TEE_ALG_AES_ECB_NOPAD },
54512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_CBC, TEE_ALG_AES_CBC_NOPAD },
55512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_CBC_PAD, TEE_ALG_AES_CBC_NOPAD },
56512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_CTR, TEE_ALG_AES_CTR },
57512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_CTS, TEE_ALG_AES_CTS },
58689f4e5bSRuchika Gupta 		/* HMAC flavors */
59689f4e5bSRuchika Gupta 		{ PKCS11_CKM_MD5_HMAC, TEE_ALG_HMAC_MD5 },
60689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA_1_HMAC, TEE_ALG_HMAC_SHA1 },
61689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA224_HMAC, TEE_ALG_HMAC_SHA224 },
62689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA256_HMAC, TEE_ALG_HMAC_SHA256 },
63689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA384_HMAC, TEE_ALG_HMAC_SHA384 },
64689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA512_HMAC, TEE_ALG_HMAC_SHA512 },
65512cbf1dSJens Wiklander 	};
66512cbf1dSJens Wiklander 	size_t n = 0;
67512cbf1dSJens Wiklander 
68512cbf1dSJens Wiklander 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) {
69512cbf1dSJens Wiklander 		if (proc_params->id == pkcs2tee_algo[n].mech_id) {
70512cbf1dSJens Wiklander 			*tee_id = pkcs2tee_algo[n].tee_id;
71512cbf1dSJens Wiklander 			return PKCS11_CKR_OK;
72512cbf1dSJens Wiklander 		}
73512cbf1dSJens Wiklander 	}
74512cbf1dSJens Wiklander 
75512cbf1dSJens Wiklander 	return PKCS11_RV_NOT_IMPLEMENTED;
76512cbf1dSJens Wiklander }
77512cbf1dSJens Wiklander 
78512cbf1dSJens Wiklander static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type,
79512cbf1dSJens Wiklander 					struct pkcs11_object *obj)
80512cbf1dSJens Wiklander {
81512cbf1dSJens Wiklander 	static const struct {
82512cbf1dSJens Wiklander 		enum pkcs11_key_type key_type;
83512cbf1dSJens Wiklander 		uint32_t tee_id;
84512cbf1dSJens Wiklander 	} pkcs2tee_key_type[] = {
85512cbf1dSJens Wiklander 		{ PKCS11_CKK_AES, TEE_TYPE_AES },
86512cbf1dSJens Wiklander 		{ PKCS11_CKK_GENERIC_SECRET, TEE_TYPE_GENERIC_SECRET },
87512cbf1dSJens Wiklander 		{ PKCS11_CKK_MD5_HMAC, TEE_TYPE_HMAC_MD5 },
88512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 },
89512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 },
90512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 },
91512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 },
92512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 },
93512cbf1dSJens Wiklander 	};
94512cbf1dSJens Wiklander 	size_t n = 0;
95512cbf1dSJens Wiklander 	enum pkcs11_key_type key_type = get_key_type(obj->attributes);
96512cbf1dSJens Wiklander 
97512cbf1dSJens Wiklander 	assert(get_class(obj->attributes) == PKCS11_CKO_SECRET_KEY);
98512cbf1dSJens Wiklander 
99512cbf1dSJens Wiklander 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) {
100512cbf1dSJens Wiklander 		if (pkcs2tee_key_type[n].key_type == key_type) {
101512cbf1dSJens Wiklander 			*tee_type = pkcs2tee_key_type[n].tee_id;
102512cbf1dSJens Wiklander 			return PKCS11_CKR_OK;
103512cbf1dSJens Wiklander 		}
104512cbf1dSJens Wiklander 	}
105512cbf1dSJens Wiklander 
106512cbf1dSJens Wiklander 	return PKCS11_RV_NOT_FOUND;
107512cbf1dSJens Wiklander }
108512cbf1dSJens Wiklander 
109de94d6f8SRuchika Gupta static enum pkcs11_rc pkcsmech2tee_key_type(uint32_t *tee_type,
110de94d6f8SRuchika Gupta 					    enum pkcs11_mechanism_id mech_id)
111de94d6f8SRuchika Gupta {
112de94d6f8SRuchika Gupta 	static const struct {
113de94d6f8SRuchika Gupta 		enum pkcs11_mechanism_id mech;
114de94d6f8SRuchika Gupta 		uint32_t tee_id;
115de94d6f8SRuchika Gupta 	} pkcs2tee_key_type[] = {
116de94d6f8SRuchika Gupta 		{ PKCS11_CKM_MD5_HMAC, TEE_TYPE_HMAC_MD5 },
117de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 },
118de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 },
119de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 },
120de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 },
121de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 },
122de94d6f8SRuchika Gupta 	};
123de94d6f8SRuchika Gupta 	size_t n = 0;
124de94d6f8SRuchika Gupta 
125de94d6f8SRuchika Gupta 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) {
126de94d6f8SRuchika Gupta 		if (pkcs2tee_key_type[n].mech == mech_id) {
127de94d6f8SRuchika Gupta 			*tee_type = pkcs2tee_key_type[n].tee_id;
128de94d6f8SRuchika Gupta 			return PKCS11_CKR_OK;
129de94d6f8SRuchika Gupta 		}
130de94d6f8SRuchika Gupta 	}
131de94d6f8SRuchika Gupta 
132de94d6f8SRuchika Gupta 	return PKCS11_RV_NOT_FOUND;
133de94d6f8SRuchika Gupta }
134de94d6f8SRuchika Gupta 
135*2158ea6cSRuchika Gupta static enum pkcs11_rc hmac_to_tee_hash(uint32_t *algo,
136*2158ea6cSRuchika Gupta 				       enum pkcs11_mechanism_id mech_id)
137*2158ea6cSRuchika Gupta {
138*2158ea6cSRuchika Gupta 	static const struct {
139*2158ea6cSRuchika Gupta 		enum pkcs11_mechanism_id mech;
140*2158ea6cSRuchika Gupta 		uint32_t tee_id;
141*2158ea6cSRuchika Gupta 	} hmac_hash[] = {
142*2158ea6cSRuchika Gupta 		{ PKCS11_CKM_MD5_HMAC, TEE_ALG_MD5 },
143*2158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA_1_HMAC, TEE_ALG_SHA1 },
144*2158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA224_HMAC, TEE_ALG_SHA224 },
145*2158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA256_HMAC, TEE_ALG_SHA256 },
146*2158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA384_HMAC, TEE_ALG_SHA384 },
147*2158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA512_HMAC, TEE_ALG_SHA512 },
148*2158ea6cSRuchika Gupta 	};
149*2158ea6cSRuchika Gupta 	size_t n = 0;
150*2158ea6cSRuchika Gupta 
151*2158ea6cSRuchika Gupta 	for (n = 0; n < ARRAY_SIZE(hmac_hash); n++) {
152*2158ea6cSRuchika Gupta 		if (hmac_hash[n].mech == mech_id) {
153*2158ea6cSRuchika Gupta 			*algo = hmac_hash[n].tee_id;
154*2158ea6cSRuchika Gupta 			return PKCS11_CKR_OK;
155*2158ea6cSRuchika Gupta 		}
156*2158ea6cSRuchika Gupta 	}
157*2158ea6cSRuchika Gupta 
158*2158ea6cSRuchika Gupta 	return PKCS11_RV_NOT_FOUND;
159*2158ea6cSRuchika Gupta }
160*2158ea6cSRuchika Gupta 
161512cbf1dSJens Wiklander static enum pkcs11_rc
162512cbf1dSJens Wiklander allocate_tee_operation(struct pkcs11_session *session,
163512cbf1dSJens Wiklander 		       enum processing_func function,
164512cbf1dSJens Wiklander 		       struct pkcs11_attribute_head *params,
165512cbf1dSJens Wiklander 		       struct pkcs11_object *obj)
166512cbf1dSJens Wiklander {
167512cbf1dSJens Wiklander 	uint32_t size = (uint32_t)get_object_key_bit_size(obj);
168460ba621SRuchika Gupta 	uint32_t key_size = size / 8;
169512cbf1dSJens Wiklander 	uint32_t algo = 0;
170512cbf1dSJens Wiklander 	uint32_t mode = 0;
171460ba621SRuchika Gupta 	uint32_t max_key_size = 0;
172460ba621SRuchika Gupta 	uint32_t min_key_size = 0;
173512cbf1dSJens Wiklander 	TEE_Result res = TEE_ERROR_GENERIC;
174512cbf1dSJens Wiklander 
175512cbf1dSJens Wiklander 	assert(session->processing->tee_op_handle == TEE_HANDLE_NULL);
176512cbf1dSJens Wiklander 
177512cbf1dSJens Wiklander 	if (pkcs2tee_algorithm(&algo, params))
178512cbf1dSJens Wiklander 		return PKCS11_CKR_FUNCTION_FAILED;
179512cbf1dSJens Wiklander 
180512cbf1dSJens Wiklander 	/* Sign/Verify with AES or generic key relate to TEE MAC operation */
181689f4e5bSRuchika Gupta 	switch (params->id) {
182689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
183689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
184689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
185689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
186689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
187689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
188460ba621SRuchika Gupta 		mechanism_supported_key_sizes(params->id,
189460ba621SRuchika Gupta 					      &min_key_size,
190460ba621SRuchika Gupta 					      &max_key_size);
191460ba621SRuchika Gupta 		if (key_size < min_key_size)
192460ba621SRuchika Gupta 			return PKCS11_CKR_KEY_SIZE_RANGE;
193*2158ea6cSRuchika Gupta 
194*2158ea6cSRuchika Gupta 		/*
195*2158ea6cSRuchika Gupta 		 * If size of generic key is greater than the size
196*2158ea6cSRuchika Gupta 		 * supported by TEE API, this is not considered an
197*2158ea6cSRuchika Gupta 		 * error. When loading TEE key, we will hash the key
198*2158ea6cSRuchika Gupta 		 * to generate the appropriate key for HMAC operation.
199*2158ea6cSRuchika Gupta 		 * This key size will not be greater than the
200*2158ea6cSRuchika Gupta 		 * max_key_size. So we can use max_key_size for
201*2158ea6cSRuchika Gupta 		 * TEE_AllocateOperation().
202*2158ea6cSRuchika Gupta 		 */
203*2158ea6cSRuchika Gupta 		if (key_size > max_key_size)
204*2158ea6cSRuchika Gupta 			size = max_key_size * 8;
205*2158ea6cSRuchika Gupta 
206689f4e5bSRuchika Gupta 		mode = TEE_MODE_MAC;
207689f4e5bSRuchika Gupta 		break;
208689f4e5bSRuchika Gupta 	default:
209512cbf1dSJens Wiklander 		pkcs2tee_mode(&mode, function);
210689f4e5bSRuchika Gupta 		break;
211689f4e5bSRuchika Gupta 	}
212512cbf1dSJens Wiklander 
213512cbf1dSJens Wiklander 	res = TEE_AllocateOperation(&session->processing->tee_op_handle,
214512cbf1dSJens Wiklander 				    algo, mode, size);
215512cbf1dSJens Wiklander 	if (res)
216512cbf1dSJens Wiklander 		EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32,
217512cbf1dSJens Wiklander 		     algo, mode, size);
218512cbf1dSJens Wiklander 
219512cbf1dSJens Wiklander 	if (res == TEE_ERROR_NOT_SUPPORTED)
220512cbf1dSJens Wiklander 		return PKCS11_CKR_MECHANISM_INVALID;
221512cbf1dSJens Wiklander 
222512cbf1dSJens Wiklander 	return tee2pkcs_error(res);
223512cbf1dSJens Wiklander }
224512cbf1dSJens Wiklander 
225*2158ea6cSRuchika Gupta static enum pkcs11_rc hash_secret_helper(enum pkcs11_mechanism_id mech_id,
226*2158ea6cSRuchika Gupta 					 struct pkcs11_object *obj,
227*2158ea6cSRuchika Gupta 					 TEE_Attribute *tee_attr,
228*2158ea6cSRuchika Gupta 					 void **ctx,
229*2158ea6cSRuchika Gupta 					 size_t *object_size_bits)
230*2158ea6cSRuchika Gupta {
231*2158ea6cSRuchika Gupta 	uint32_t algo = 0;
232*2158ea6cSRuchika Gupta 	void *hash_ptr = NULL;
233*2158ea6cSRuchika Gupta 	uint32_t hash_size = 0;
234*2158ea6cSRuchika Gupta 	enum pkcs11_rc rc = PKCS11_CKR_OK;
235*2158ea6cSRuchika Gupta 
236*2158ea6cSRuchika Gupta 	rc = hmac_to_tee_hash(&algo, mech_id);
237*2158ea6cSRuchika Gupta 	if (rc)
238*2158ea6cSRuchika Gupta 		return rc;
239*2158ea6cSRuchika Gupta 
240*2158ea6cSRuchika Gupta 	hash_size = TEE_ALG_GET_DIGEST_SIZE(algo);
241*2158ea6cSRuchika Gupta 	hash_ptr = TEE_Malloc(hash_size, 0);
242*2158ea6cSRuchika Gupta 	if (!hash_ptr)
243*2158ea6cSRuchika Gupta 		return PKCS11_CKR_DEVICE_MEMORY;
244*2158ea6cSRuchika Gupta 
245*2158ea6cSRuchika Gupta 	rc = pkcs2tee_load_hashed_attr(tee_attr, TEE_ATTR_SECRET_VALUE, obj,
246*2158ea6cSRuchika Gupta 				       PKCS11_CKA_VALUE, algo, hash_ptr,
247*2158ea6cSRuchika Gupta 				       &hash_size);
248*2158ea6cSRuchika Gupta 	if (rc) {
249*2158ea6cSRuchika Gupta 		EMSG("No secret/hash error");
250*2158ea6cSRuchika Gupta 		TEE_Free(hash_ptr);
251*2158ea6cSRuchika Gupta 		return rc;
252*2158ea6cSRuchika Gupta 	}
253*2158ea6cSRuchika Gupta 
254*2158ea6cSRuchika Gupta 	*ctx = hash_ptr;
255*2158ea6cSRuchika Gupta 
256*2158ea6cSRuchika Gupta 	*object_size_bits = hash_size * 8;
257*2158ea6cSRuchika Gupta 
258*2158ea6cSRuchika Gupta 	return PKCS11_CKR_OK;
259*2158ea6cSRuchika Gupta }
260*2158ea6cSRuchika Gupta 
261512cbf1dSJens Wiklander static enum pkcs11_rc load_tee_key(struct pkcs11_session *session,
262de94d6f8SRuchika Gupta 				   struct pkcs11_object *obj,
263de94d6f8SRuchika Gupta 				   struct pkcs11_attribute_head *proc_params)
264512cbf1dSJens Wiklander {
265512cbf1dSJens Wiklander 	TEE_Attribute tee_attr = { };
266512cbf1dSJens Wiklander 	size_t object_size = 0;
267512cbf1dSJens Wiklander 	uint32_t tee_key_type = 0;
268de94d6f8SRuchika Gupta 	enum pkcs11_key_type key_type = 0;
269512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
270512cbf1dSJens Wiklander 	TEE_Result res = TEE_ERROR_GENERIC;
271*2158ea6cSRuchika Gupta 	uint32_t max_key_size = 0;
272*2158ea6cSRuchika Gupta 	uint32_t min_key_size = 0;
273512cbf1dSJens Wiklander 
274512cbf1dSJens Wiklander 	if (obj->key_handle != TEE_HANDLE_NULL) {
275512cbf1dSJens Wiklander 		/* Key was already loaded and fits current need */
276512cbf1dSJens Wiklander 		goto key_ready;
277512cbf1dSJens Wiklander 	}
278512cbf1dSJens Wiklander 
279*2158ea6cSRuchika Gupta 	object_size = get_object_key_bit_size(obj);
280*2158ea6cSRuchika Gupta 	if (!object_size)
281*2158ea6cSRuchika Gupta 		return PKCS11_CKR_GENERAL_ERROR;
282512cbf1dSJens Wiklander 
283de94d6f8SRuchika Gupta 	switch (proc_params->id) {
284de94d6f8SRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
285de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
286de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
287de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
288de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
289de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
290de94d6f8SRuchika Gupta 		key_type = get_key_type(obj->attributes);
291de94d6f8SRuchika Gupta 		/*
292de94d6f8SRuchika Gupta 		 * If Object Key type is PKCS11_CKK_GENERIC_SECRET,
293de94d6f8SRuchika Gupta 		 * determine the tee_key_type using the
294de94d6f8SRuchika Gupta 		 * mechanism instead of object key_type.
295de94d6f8SRuchika Gupta 		 */
296de94d6f8SRuchika Gupta 		if (key_type == PKCS11_CKK_GENERIC_SECRET)
297de94d6f8SRuchika Gupta 			rc = pkcsmech2tee_key_type(&tee_key_type,
298de94d6f8SRuchika Gupta 						   proc_params->id);
299de94d6f8SRuchika Gupta 		else
300512cbf1dSJens Wiklander 			rc = pkcs2tee_key_type(&tee_key_type, obj);
301de94d6f8SRuchika Gupta 
302512cbf1dSJens Wiklander 		if (rc)
303512cbf1dSJens Wiklander 			return rc;
304512cbf1dSJens Wiklander 
305*2158ea6cSRuchika Gupta 		mechanism_supported_key_sizes(proc_params->id,
306*2158ea6cSRuchika Gupta 					      &min_key_size,
307*2158ea6cSRuchika Gupta 					      &max_key_size);
308*2158ea6cSRuchika Gupta 
309*2158ea6cSRuchika Gupta 		if ((object_size / 8) > max_key_size) {
310*2158ea6cSRuchika Gupta 			rc = hash_secret_helper(proc_params->id, obj, &tee_attr,
311*2158ea6cSRuchika Gupta 						&session->processing->extra_ctx,
312*2158ea6cSRuchika Gupta 						&object_size);
313*2158ea6cSRuchika Gupta 			if (rc)
314*2158ea6cSRuchika Gupta 				return rc;
315*2158ea6cSRuchika Gupta 		} else {
316*2158ea6cSRuchika Gupta 			if (!pkcs2tee_load_attr(&tee_attr,
317*2158ea6cSRuchika Gupta 						TEE_ATTR_SECRET_VALUE,
318*2158ea6cSRuchika Gupta 						obj,
319*2158ea6cSRuchika Gupta 						PKCS11_CKA_VALUE)) {
320*2158ea6cSRuchika Gupta 				EMSG("No secret found");
321*2158ea6cSRuchika Gupta 				return PKCS11_CKR_FUNCTION_FAILED;
322*2158ea6cSRuchika Gupta 			}
323*2158ea6cSRuchika Gupta 		}
324*2158ea6cSRuchika Gupta 		break;
325*2158ea6cSRuchika Gupta 
326*2158ea6cSRuchika Gupta 	default:
327*2158ea6cSRuchika Gupta 		rc = pkcs2tee_key_type(&tee_key_type, obj);
328*2158ea6cSRuchika Gupta 		if (rc)
329*2158ea6cSRuchika Gupta 			return rc;
330*2158ea6cSRuchika Gupta 
331*2158ea6cSRuchika Gupta 		if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE,
332*2158ea6cSRuchika Gupta 					obj, PKCS11_CKA_VALUE)) {
333*2158ea6cSRuchika Gupta 			EMSG("No secret found");
334*2158ea6cSRuchika Gupta 			return PKCS11_CKR_FUNCTION_FAILED;
335*2158ea6cSRuchika Gupta 		}
336*2158ea6cSRuchika Gupta 		break;
337*2158ea6cSRuchika Gupta 	}
338512cbf1dSJens Wiklander 
339512cbf1dSJens Wiklander 	res = TEE_AllocateTransientObject(tee_key_type, object_size,
340512cbf1dSJens Wiklander 					  &obj->key_handle);
341512cbf1dSJens Wiklander 	if (res) {
342512cbf1dSJens Wiklander 		DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res);
343512cbf1dSJens Wiklander 		return tee2pkcs_error(res);
344512cbf1dSJens Wiklander 	}
345512cbf1dSJens Wiklander 
346512cbf1dSJens Wiklander 	res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1);
347512cbf1dSJens Wiklander 	if (res) {
348512cbf1dSJens Wiklander 		DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res);
349512cbf1dSJens Wiklander 		goto error;
350512cbf1dSJens Wiklander 	}
351512cbf1dSJens Wiklander 
352512cbf1dSJens Wiklander key_ready:
353512cbf1dSJens Wiklander 	res = TEE_SetOperationKey(session->processing->tee_op_handle,
354512cbf1dSJens Wiklander 				  obj->key_handle);
355512cbf1dSJens Wiklander 	if (res) {
356512cbf1dSJens Wiklander 		DMSG("TEE_SetOperationKey failed, %#"PRIx32, res);
357512cbf1dSJens Wiklander 		goto error;
358512cbf1dSJens Wiklander 	}
359512cbf1dSJens Wiklander 
360512cbf1dSJens Wiklander 	return PKCS11_CKR_OK;
361512cbf1dSJens Wiklander 
362512cbf1dSJens Wiklander error:
363512cbf1dSJens Wiklander 	TEE_FreeTransientObject(obj->key_handle);
364512cbf1dSJens Wiklander 	obj->key_handle = TEE_HANDLE_NULL;
365512cbf1dSJens Wiklander 
366512cbf1dSJens Wiklander 	return tee2pkcs_error(res);
367512cbf1dSJens Wiklander }
368512cbf1dSJens Wiklander 
369512cbf1dSJens Wiklander static enum pkcs11_rc
370512cbf1dSJens Wiklander init_tee_operation(struct pkcs11_session *session,
371512cbf1dSJens Wiklander 		   struct pkcs11_attribute_head *proc_params)
372512cbf1dSJens Wiklander {
373512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
374512cbf1dSJens Wiklander 
375512cbf1dSJens Wiklander 	switch (proc_params->id) {
376689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
377689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
378689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
379689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
380689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
381689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
382689f4e5bSRuchika Gupta 		if (proc_params->size)
383689f4e5bSRuchika Gupta 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
384689f4e5bSRuchika Gupta 
385689f4e5bSRuchika Gupta 		TEE_MACInit(session->processing->tee_op_handle, NULL, 0);
386689f4e5bSRuchika Gupta 		rc = PKCS11_CKR_OK;
387689f4e5bSRuchika Gupta 		break;
388512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
389512cbf1dSJens Wiklander 		if (proc_params->size)
390512cbf1dSJens Wiklander 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
391512cbf1dSJens Wiklander 
392512cbf1dSJens Wiklander 		TEE_CipherInit(session->processing->tee_op_handle, NULL, 0);
393512cbf1dSJens Wiklander 		rc = PKCS11_CKR_OK;
394512cbf1dSJens Wiklander 		break;
395512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
396512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC_PAD:
397512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
398512cbf1dSJens Wiklander 		if (proc_params->size != 16)
399512cbf1dSJens Wiklander 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
400512cbf1dSJens Wiklander 
401512cbf1dSJens Wiklander 		TEE_CipherInit(session->processing->tee_op_handle,
402512cbf1dSJens Wiklander 			       proc_params->data, 16);
403512cbf1dSJens Wiklander 		rc = PKCS11_CKR_OK;
404512cbf1dSJens Wiklander 		break;
405512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
406512cbf1dSJens Wiklander 		rc = tee_init_ctr_operation(session->processing,
407512cbf1dSJens Wiklander 					    proc_params->data,
408512cbf1dSJens Wiklander 					    proc_params->size);
409512cbf1dSJens Wiklander 		break;
410512cbf1dSJens Wiklander 	default:
411512cbf1dSJens Wiklander 		TEE_Panic(proc_params->id);
412512cbf1dSJens Wiklander 		break;
413512cbf1dSJens Wiklander 	}
414512cbf1dSJens Wiklander 
415512cbf1dSJens Wiklander 	return rc;
416512cbf1dSJens Wiklander }
417512cbf1dSJens Wiklander 
418512cbf1dSJens Wiklander enum pkcs11_rc init_symm_operation(struct pkcs11_session *session,
419512cbf1dSJens Wiklander 				   enum processing_func function,
420512cbf1dSJens Wiklander 				   struct pkcs11_attribute_head *proc_params,
421512cbf1dSJens Wiklander 				   struct pkcs11_object *obj)
422512cbf1dSJens Wiklander {
423512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
424512cbf1dSJens Wiklander 
425512cbf1dSJens Wiklander 	assert(processing_is_tee_symm(proc_params->id));
426512cbf1dSJens Wiklander 
427512cbf1dSJens Wiklander 	rc = allocate_tee_operation(session, function, proc_params, obj);
428512cbf1dSJens Wiklander 	if (rc)
429512cbf1dSJens Wiklander 		return rc;
430512cbf1dSJens Wiklander 
431de94d6f8SRuchika Gupta 	rc = load_tee_key(session, obj, proc_params);
432512cbf1dSJens Wiklander 	if (rc)
433512cbf1dSJens Wiklander 		return rc;
434512cbf1dSJens Wiklander 
435512cbf1dSJens Wiklander 	return init_tee_operation(session, proc_params);
436512cbf1dSJens Wiklander }
437512cbf1dSJens Wiklander 
438512cbf1dSJens Wiklander /* Validate input buffer size as per PKCS#11 constraints */
439512cbf1dSJens Wiklander static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc,
440512cbf1dSJens Wiklander 					       enum processing_func function,
441512cbf1dSJens Wiklander 					       size_t in_size)
442512cbf1dSJens Wiklander {
443512cbf1dSJens Wiklander 	switch (proc->mecha_type) {
444512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
445512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
446512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_ENCRYPT &&
447512cbf1dSJens Wiklander 		    in_size % TEE_AES_BLOCK_SIZE)
448512cbf1dSJens Wiklander 			return PKCS11_CKR_DATA_LEN_RANGE;
449512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_DECRYPT &&
450512cbf1dSJens Wiklander 		    in_size % TEE_AES_BLOCK_SIZE)
451512cbf1dSJens Wiklander 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
452512cbf1dSJens Wiklander 		break;
453512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC_PAD:
454512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_DECRYPT &&
455512cbf1dSJens Wiklander 		    in_size % TEE_AES_BLOCK_SIZE)
456512cbf1dSJens Wiklander 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
457512cbf1dSJens Wiklander 		break;
458512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
459512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_ENCRYPT &&
460512cbf1dSJens Wiklander 		    in_size < TEE_AES_BLOCK_SIZE)
461512cbf1dSJens Wiklander 			return PKCS11_CKR_DATA_LEN_RANGE;
462512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_DECRYPT &&
463512cbf1dSJens Wiklander 		    in_size < TEE_AES_BLOCK_SIZE)
464512cbf1dSJens Wiklander 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
465512cbf1dSJens Wiklander 		break;
466512cbf1dSJens Wiklander 	default:
467512cbf1dSJens Wiklander 		break;
468512cbf1dSJens Wiklander 	}
469512cbf1dSJens Wiklander 
470512cbf1dSJens Wiklander 	return PKCS11_CKR_OK;
471512cbf1dSJens Wiklander }
472512cbf1dSJens Wiklander 
473689f4e5bSRuchika Gupta /* Validate input buffer size as per PKCS#11 constraints */
474689f4e5bSRuchika Gupta static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc,
475689f4e5bSRuchika Gupta 					       size_t in_size)
476689f4e5bSRuchika Gupta {
477689f4e5bSRuchika Gupta 	size_t sign_sz = 0;
478689f4e5bSRuchika Gupta 
479689f4e5bSRuchika Gupta 	switch (proc->mecha_type) {
480689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
481689f4e5bSRuchika Gupta 		sign_sz = TEE_MD5_HASH_SIZE;
482689f4e5bSRuchika Gupta 		break;
483689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
484689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA1_HASH_SIZE;
485689f4e5bSRuchika Gupta 		break;
486689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
487689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA224_HASH_SIZE;
488689f4e5bSRuchika Gupta 		break;
489689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
490689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA256_HASH_SIZE;
491689f4e5bSRuchika Gupta 		break;
492689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
493689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA384_HASH_SIZE;
494689f4e5bSRuchika Gupta 		break;
495689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
496689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA512_HASH_SIZE;
497689f4e5bSRuchika Gupta 		break;
498689f4e5bSRuchika Gupta 	default:
499689f4e5bSRuchika Gupta 		return PKCS11_CKR_GENERAL_ERROR;
500689f4e5bSRuchika Gupta 	}
501689f4e5bSRuchika Gupta 
502689f4e5bSRuchika Gupta 	if (in_size < sign_sz)
503689f4e5bSRuchika Gupta 		return PKCS11_CKR_SIGNATURE_LEN_RANGE;
504689f4e5bSRuchika Gupta 
505689f4e5bSRuchika Gupta 	return PKCS11_CKR_OK;
506689f4e5bSRuchika Gupta }
507689f4e5bSRuchika Gupta 
508512cbf1dSJens Wiklander /*
509512cbf1dSJens Wiklander  * step_sym_cipher - processing symmetric (and related) cipher operation step
510512cbf1dSJens Wiklander  *
511512cbf1dSJens Wiklander  * @session - current session
512512cbf1dSJens Wiklander  * @function - processing function (encrypt, decrypt, sign, ...)
513512cbf1dSJens Wiklander  * @step - step ID in the processing (oneshot, update, final)
514512cbf1dSJens Wiklander  * @ptype - invocation parameter types
515512cbf1dSJens Wiklander  * @params - invocation parameter references
516512cbf1dSJens Wiklander  */
517512cbf1dSJens Wiklander enum pkcs11_rc step_symm_operation(struct pkcs11_session *session,
518512cbf1dSJens Wiklander 				   enum processing_func function,
519512cbf1dSJens Wiklander 				   enum processing_step step,
520512cbf1dSJens Wiklander 				   uint32_t ptypes, TEE_Param *params)
521512cbf1dSJens Wiklander {
522512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
523512cbf1dSJens Wiklander 	TEE_Result res = TEE_ERROR_GENERIC;
524512cbf1dSJens Wiklander 	void *in_buf = NULL;
525512cbf1dSJens Wiklander 	size_t in_size = 0;
526512cbf1dSJens Wiklander 	void *out_buf = NULL;
527512cbf1dSJens Wiklander 	uint32_t out_size = 0;
528512cbf1dSJens Wiklander 	void *in2_buf = NULL;
529512cbf1dSJens Wiklander 	uint32_t in2_size = 0;
530512cbf1dSJens Wiklander 	bool output_data = false;
531512cbf1dSJens Wiklander 	struct active_processing *proc = session->processing;
532512cbf1dSJens Wiklander 
533512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) {
534512cbf1dSJens Wiklander 		in_buf = params[1].memref.buffer;
535512cbf1dSJens Wiklander 		in_size = params[1].memref.size;
536512cbf1dSJens Wiklander 		if (in_size && !in_buf)
537512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
538512cbf1dSJens Wiklander 	}
539512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) {
540512cbf1dSJens Wiklander 		in2_buf = params[2].memref.buffer;
541512cbf1dSJens Wiklander 		in2_size = params[2].memref.size;
542512cbf1dSJens Wiklander 		if (in2_size && !in2_buf)
543512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
544512cbf1dSJens Wiklander 	}
545512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) {
546512cbf1dSJens Wiklander 		out_buf = params[2].memref.buffer;
547512cbf1dSJens Wiklander 		out_size = params[2].memref.size;
548512cbf1dSJens Wiklander 		if (out_size && !out_buf)
549512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
550512cbf1dSJens Wiklander 	}
551512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE)
552512cbf1dSJens Wiklander 		return PKCS11_CKR_ARGUMENTS_BAD;
553512cbf1dSJens Wiklander 
554512cbf1dSJens Wiklander 	switch (step) {
555512cbf1dSJens Wiklander 	case PKCS11_FUNC_STEP_ONESHOT:
556512cbf1dSJens Wiklander 	case PKCS11_FUNC_STEP_UPDATE:
557512cbf1dSJens Wiklander 	case PKCS11_FUNC_STEP_FINAL:
558512cbf1dSJens Wiklander 		break;
559512cbf1dSJens Wiklander 	default:
560512cbf1dSJens Wiklander 		return PKCS11_CKR_GENERAL_ERROR;
561512cbf1dSJens Wiklander 	}
562512cbf1dSJens Wiklander 
563512cbf1dSJens Wiklander 	if (step != PKCS11_FUNC_STEP_FINAL) {
564512cbf1dSJens Wiklander 		rc = input_data_size_is_valid(proc, function, in_size);
565512cbf1dSJens Wiklander 		if (rc)
566512cbf1dSJens Wiklander 			return rc;
567512cbf1dSJens Wiklander 	}
568512cbf1dSJens Wiklander 
569512cbf1dSJens Wiklander 	/*
570512cbf1dSJens Wiklander 	 * Feed active operation with data
571512cbf1dSJens Wiklander 	 */
572512cbf1dSJens Wiklander 	switch (proc->mecha_type) {
573689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
574689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
575689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
576689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
577689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
578689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
579689f4e5bSRuchika Gupta 		if (step == PKCS11_FUNC_STEP_FINAL ||
580689f4e5bSRuchika Gupta 		    step == PKCS11_FUNC_STEP_ONESHOT)
581689f4e5bSRuchika Gupta 			break;
582689f4e5bSRuchika Gupta 
583689f4e5bSRuchika Gupta 		if (!in_buf) {
584689f4e5bSRuchika Gupta 			DMSG("No input data");
585689f4e5bSRuchika Gupta 			return PKCS11_CKR_ARGUMENTS_BAD;
586689f4e5bSRuchika Gupta 		}
587689f4e5bSRuchika Gupta 
588689f4e5bSRuchika Gupta 		switch (function) {
589689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_SIGN:
590689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_VERIFY:
591689f4e5bSRuchika Gupta 			TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size);
592689f4e5bSRuchika Gupta 			rc = PKCS11_CKR_OK;
593689f4e5bSRuchika Gupta 			break;
594689f4e5bSRuchika Gupta 		default:
595689f4e5bSRuchika Gupta 			TEE_Panic(function);
596689f4e5bSRuchika Gupta 			break;
597689f4e5bSRuchika Gupta 		}
598689f4e5bSRuchika Gupta 		break;
599689f4e5bSRuchika Gupta 
600512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
601512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
602512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC_PAD:
603512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
604512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
605512cbf1dSJens Wiklander 		if (step == PKCS11_FUNC_STEP_FINAL ||
606512cbf1dSJens Wiklander 		    step == PKCS11_FUNC_STEP_ONESHOT)
607512cbf1dSJens Wiklander 			break;
608512cbf1dSJens Wiklander 
609512cbf1dSJens Wiklander 		if (!in_buf) {
610512cbf1dSJens Wiklander 			EMSG("No input data");
611512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
612512cbf1dSJens Wiklander 		}
613512cbf1dSJens Wiklander 
614512cbf1dSJens Wiklander 		switch (function) {
615512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_ENCRYPT:
616512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_DECRYPT:
617512cbf1dSJens Wiklander 			res = TEE_CipherUpdate(proc->tee_op_handle,
618512cbf1dSJens Wiklander 					       in_buf, in_size,
619512cbf1dSJens Wiklander 						out_buf, &out_size);
620512cbf1dSJens Wiklander 			output_data = true;
621512cbf1dSJens Wiklander 			rc = tee2pkcs_error(res);
622512cbf1dSJens Wiklander 			break;
623512cbf1dSJens Wiklander 		default:
624512cbf1dSJens Wiklander 			TEE_Panic(function);
625512cbf1dSJens Wiklander 			break;
626512cbf1dSJens Wiklander 		}
627512cbf1dSJens Wiklander 		break;
628512cbf1dSJens Wiklander 
629512cbf1dSJens Wiklander 	default:
630512cbf1dSJens Wiklander 		TEE_Panic(proc->mecha_type);
631512cbf1dSJens Wiklander 		break;
632512cbf1dSJens Wiklander 	}
633512cbf1dSJens Wiklander 
634512cbf1dSJens Wiklander 	if (step == PKCS11_FUNC_STEP_UPDATE)
635512cbf1dSJens Wiklander 		goto out;
636512cbf1dSJens Wiklander 
637512cbf1dSJens Wiklander 	/*
638512cbf1dSJens Wiklander 	 * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation
639512cbf1dSJens Wiklander 	 */
640512cbf1dSJens Wiklander 	switch (session->processing->mecha_type) {
641689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
642689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
643689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
644689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
645689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
646689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
647689f4e5bSRuchika Gupta 		switch (function) {
648689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_SIGN:
649689f4e5bSRuchika Gupta 			res = TEE_MACComputeFinal(proc->tee_op_handle,
650689f4e5bSRuchika Gupta 						  in_buf, in_size, out_buf,
651689f4e5bSRuchika Gupta 						  &out_size);
652689f4e5bSRuchika Gupta 			output_data = true;
653689f4e5bSRuchika Gupta 			rc = tee2pkcs_error(res);
654689f4e5bSRuchika Gupta 			break;
655689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_VERIFY:
656689f4e5bSRuchika Gupta 			rc = input_sign_size_is_valid(proc, in2_size);
657689f4e5bSRuchika Gupta 			if (rc)
658689f4e5bSRuchika Gupta 				return rc;
659689f4e5bSRuchika Gupta 			res = TEE_MACCompareFinal(proc->tee_op_handle,
660689f4e5bSRuchika Gupta 						  in_buf, in_size, in2_buf,
661689f4e5bSRuchika Gupta 						  in2_size);
662689f4e5bSRuchika Gupta 			rc = tee2pkcs_error(res);
663689f4e5bSRuchika Gupta 			break;
664689f4e5bSRuchika Gupta 		default:
665689f4e5bSRuchika Gupta 			TEE_Panic(function);
666689f4e5bSRuchika Gupta 			break;
667689f4e5bSRuchika Gupta 		}
668*2158ea6cSRuchika Gupta 
669689f4e5bSRuchika Gupta 		break;
670689f4e5bSRuchika Gupta 
671512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
672512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
673512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC_PAD:
674512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
675512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
676512cbf1dSJens Wiklander 		if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) {
677512cbf1dSJens Wiklander 			EMSG("No input data");
678512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
679512cbf1dSJens Wiklander 		}
680512cbf1dSJens Wiklander 
681512cbf1dSJens Wiklander 		switch (function) {
682512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_ENCRYPT:
683512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_DECRYPT:
684512cbf1dSJens Wiklander 			res = TEE_CipherDoFinal(proc->tee_op_handle,
685512cbf1dSJens Wiklander 						in_buf, in_size,
686512cbf1dSJens Wiklander 						out_buf, &out_size);
687512cbf1dSJens Wiklander 			output_data = true;
688512cbf1dSJens Wiklander 			rc = tee2pkcs_error(res);
689512cbf1dSJens Wiklander 			break;
690512cbf1dSJens Wiklander 		default:
691512cbf1dSJens Wiklander 			TEE_Panic(function);
692512cbf1dSJens Wiklander 			break;
693512cbf1dSJens Wiklander 		}
694512cbf1dSJens Wiklander 		break;
695512cbf1dSJens Wiklander 	default:
696512cbf1dSJens Wiklander 		TEE_Panic(proc->mecha_type);
697512cbf1dSJens Wiklander 		break;
698512cbf1dSJens Wiklander 	}
699512cbf1dSJens Wiklander 
700512cbf1dSJens Wiklander out:
701512cbf1dSJens Wiklander 	if (output_data &&
702512cbf1dSJens Wiklander 	    (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) {
703512cbf1dSJens Wiklander 		switch (TEE_PARAM_TYPE_GET(ptypes, 2)) {
704512cbf1dSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
705512cbf1dSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
706512cbf1dSJens Wiklander 			params[2].memref.size = out_size;
707512cbf1dSJens Wiklander 			break;
708512cbf1dSJens Wiklander 		default:
709512cbf1dSJens Wiklander 			rc = PKCS11_CKR_ARGUMENTS_BAD;
710512cbf1dSJens Wiklander 			break;
711512cbf1dSJens Wiklander 		}
712512cbf1dSJens Wiklander 	}
713512cbf1dSJens Wiklander 
714512cbf1dSJens Wiklander 	return rc;
715512cbf1dSJens Wiklander }
716