xref: /optee_os/ta/pkcs11/src/processing_symm.c (revision 42765f8253ca53211cfc00d4a2dc177ad6cf0433)
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 */
32689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
33689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
34689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
35689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
36689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
37689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
386f6d5e75SVictor Chong 	/* Ciphering */
39512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
40512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
41512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC_PAD:
42512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
43512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
4448799892SRuchika Gupta 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
4548799892SRuchika Gupta 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
46512cbf1dSJens Wiklander 		return true;
47512cbf1dSJens Wiklander 	default:
48512cbf1dSJens Wiklander 		return false;
49512cbf1dSJens Wiklander 	}
50512cbf1dSJens Wiklander }
51512cbf1dSJens Wiklander 
52512cbf1dSJens Wiklander static enum pkcs11_rc
53512cbf1dSJens Wiklander pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params)
54512cbf1dSJens Wiklander {
55512cbf1dSJens Wiklander 	static const struct {
56512cbf1dSJens Wiklander 		enum pkcs11_mechanism_id mech_id;
57512cbf1dSJens Wiklander 		uint32_t tee_id;
58512cbf1dSJens Wiklander 	} pkcs2tee_algo[] = {
59512cbf1dSJens Wiklander 		/* AES flavors */
60512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_ECB, TEE_ALG_AES_ECB_NOPAD },
61512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_CBC, TEE_ALG_AES_CBC_NOPAD },
62512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_CBC_PAD, TEE_ALG_AES_CBC_NOPAD },
6348799892SRuchika Gupta 		{ PKCS11_CKM_AES_ECB_ENCRYPT_DATA, TEE_ALG_AES_ECB_NOPAD },
6448799892SRuchika Gupta 		{ PKCS11_CKM_AES_CBC_ENCRYPT_DATA, TEE_ALG_AES_CBC_NOPAD },
65512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_CTR, TEE_ALG_AES_CTR },
66512cbf1dSJens Wiklander 		{ PKCS11_CKM_AES_CTS, TEE_ALG_AES_CTS },
67689f4e5bSRuchika Gupta 		/* HMAC flavors */
68689f4e5bSRuchika Gupta 		{ PKCS11_CKM_MD5_HMAC, TEE_ALG_HMAC_MD5 },
69689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA_1_HMAC, TEE_ALG_HMAC_SHA1 },
70689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA224_HMAC, TEE_ALG_HMAC_SHA224 },
71689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA256_HMAC, TEE_ALG_HMAC_SHA256 },
72689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA384_HMAC, TEE_ALG_HMAC_SHA384 },
73689f4e5bSRuchika Gupta 		{ PKCS11_CKM_SHA512_HMAC, TEE_ALG_HMAC_SHA512 },
74512cbf1dSJens Wiklander 	};
75512cbf1dSJens Wiklander 	size_t n = 0;
76512cbf1dSJens Wiklander 
77512cbf1dSJens Wiklander 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) {
78512cbf1dSJens Wiklander 		if (proc_params->id == pkcs2tee_algo[n].mech_id) {
79512cbf1dSJens Wiklander 			*tee_id = pkcs2tee_algo[n].tee_id;
80512cbf1dSJens Wiklander 			return PKCS11_CKR_OK;
81512cbf1dSJens Wiklander 		}
82512cbf1dSJens Wiklander 	}
83512cbf1dSJens Wiklander 
84512cbf1dSJens Wiklander 	return PKCS11_RV_NOT_IMPLEMENTED;
85512cbf1dSJens Wiklander }
86512cbf1dSJens Wiklander 
87512cbf1dSJens Wiklander static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type,
88512cbf1dSJens Wiklander 					struct pkcs11_object *obj)
89512cbf1dSJens Wiklander {
90512cbf1dSJens Wiklander 	static const struct {
91512cbf1dSJens Wiklander 		enum pkcs11_key_type key_type;
92512cbf1dSJens Wiklander 		uint32_t tee_id;
93512cbf1dSJens Wiklander 	} pkcs2tee_key_type[] = {
94512cbf1dSJens Wiklander 		{ PKCS11_CKK_AES, TEE_TYPE_AES },
95512cbf1dSJens Wiklander 		{ PKCS11_CKK_GENERIC_SECRET, TEE_TYPE_GENERIC_SECRET },
96512cbf1dSJens Wiklander 		{ PKCS11_CKK_MD5_HMAC, TEE_TYPE_HMAC_MD5 },
97512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 },
98512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 },
99512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 },
100512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 },
101512cbf1dSJens Wiklander 		{ PKCS11_CKK_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 },
102512cbf1dSJens Wiklander 	};
103512cbf1dSJens Wiklander 	size_t n = 0;
104512cbf1dSJens Wiklander 	enum pkcs11_key_type key_type = get_key_type(obj->attributes);
105512cbf1dSJens Wiklander 
106512cbf1dSJens Wiklander 	assert(get_class(obj->attributes) == PKCS11_CKO_SECRET_KEY);
107512cbf1dSJens Wiklander 
108512cbf1dSJens Wiklander 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) {
109512cbf1dSJens Wiklander 		if (pkcs2tee_key_type[n].key_type == key_type) {
110512cbf1dSJens Wiklander 			*tee_type = pkcs2tee_key_type[n].tee_id;
111512cbf1dSJens Wiklander 			return PKCS11_CKR_OK;
112512cbf1dSJens Wiklander 		}
113512cbf1dSJens Wiklander 	}
114512cbf1dSJens Wiklander 
115512cbf1dSJens Wiklander 	return PKCS11_RV_NOT_FOUND;
116512cbf1dSJens Wiklander }
117512cbf1dSJens Wiklander 
118de94d6f8SRuchika Gupta static enum pkcs11_rc pkcsmech2tee_key_type(uint32_t *tee_type,
119de94d6f8SRuchika Gupta 					    enum pkcs11_mechanism_id mech_id)
120de94d6f8SRuchika Gupta {
121de94d6f8SRuchika Gupta 	static const struct {
122de94d6f8SRuchika Gupta 		enum pkcs11_mechanism_id mech;
123de94d6f8SRuchika Gupta 		uint32_t tee_id;
124de94d6f8SRuchika Gupta 	} pkcs2tee_key_type[] = {
125de94d6f8SRuchika Gupta 		{ PKCS11_CKM_MD5_HMAC, TEE_TYPE_HMAC_MD5 },
126de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA_1_HMAC, TEE_TYPE_HMAC_SHA1 },
127de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA224_HMAC, TEE_TYPE_HMAC_SHA224 },
128de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA256_HMAC, TEE_TYPE_HMAC_SHA256 },
129de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA384_HMAC, TEE_TYPE_HMAC_SHA384 },
130de94d6f8SRuchika Gupta 		{ PKCS11_CKM_SHA512_HMAC, TEE_TYPE_HMAC_SHA512 },
131de94d6f8SRuchika Gupta 	};
132de94d6f8SRuchika Gupta 	size_t n = 0;
133de94d6f8SRuchika Gupta 
134de94d6f8SRuchika Gupta 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_key_type); n++) {
135de94d6f8SRuchika Gupta 		if (pkcs2tee_key_type[n].mech == mech_id) {
136de94d6f8SRuchika Gupta 			*tee_type = pkcs2tee_key_type[n].tee_id;
137de94d6f8SRuchika Gupta 			return PKCS11_CKR_OK;
138de94d6f8SRuchika Gupta 		}
139de94d6f8SRuchika Gupta 	}
140de94d6f8SRuchika Gupta 
141de94d6f8SRuchika Gupta 	return PKCS11_RV_NOT_FOUND;
142de94d6f8SRuchika Gupta }
143de94d6f8SRuchika Gupta 
1442158ea6cSRuchika Gupta static enum pkcs11_rc hmac_to_tee_hash(uint32_t *algo,
1452158ea6cSRuchika Gupta 				       enum pkcs11_mechanism_id mech_id)
1462158ea6cSRuchika Gupta {
1472158ea6cSRuchika Gupta 	static const struct {
1482158ea6cSRuchika Gupta 		enum pkcs11_mechanism_id mech;
1492158ea6cSRuchika Gupta 		uint32_t tee_id;
1502158ea6cSRuchika Gupta 	} hmac_hash[] = {
1512158ea6cSRuchika Gupta 		{ PKCS11_CKM_MD5_HMAC, TEE_ALG_MD5 },
1522158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA_1_HMAC, TEE_ALG_SHA1 },
1532158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA224_HMAC, TEE_ALG_SHA224 },
1542158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA256_HMAC, TEE_ALG_SHA256 },
1552158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA384_HMAC, TEE_ALG_SHA384 },
1562158ea6cSRuchika Gupta 		{ PKCS11_CKM_SHA512_HMAC, TEE_ALG_SHA512 },
1572158ea6cSRuchika Gupta 	};
1582158ea6cSRuchika Gupta 	size_t n = 0;
1592158ea6cSRuchika Gupta 
1602158ea6cSRuchika Gupta 	for (n = 0; n < ARRAY_SIZE(hmac_hash); n++) {
1612158ea6cSRuchika Gupta 		if (hmac_hash[n].mech == mech_id) {
1622158ea6cSRuchika Gupta 			*algo = hmac_hash[n].tee_id;
1632158ea6cSRuchika Gupta 			return PKCS11_CKR_OK;
1642158ea6cSRuchika Gupta 		}
1652158ea6cSRuchika Gupta 	}
1662158ea6cSRuchika Gupta 
1672158ea6cSRuchika Gupta 	return PKCS11_RV_NOT_FOUND;
1682158ea6cSRuchika Gupta }
1692158ea6cSRuchika Gupta 
170512cbf1dSJens Wiklander static enum pkcs11_rc
171512cbf1dSJens Wiklander allocate_tee_operation(struct pkcs11_session *session,
172512cbf1dSJens Wiklander 		       enum processing_func function,
173512cbf1dSJens Wiklander 		       struct pkcs11_attribute_head *params,
174512cbf1dSJens Wiklander 		       struct pkcs11_object *obj)
175512cbf1dSJens Wiklander {
176512cbf1dSJens Wiklander 	uint32_t size = (uint32_t)get_object_key_bit_size(obj);
177460ba621SRuchika Gupta 	uint32_t key_size = size / 8;
178512cbf1dSJens Wiklander 	uint32_t algo = 0;
179512cbf1dSJens Wiklander 	uint32_t mode = 0;
180460ba621SRuchika Gupta 	uint32_t max_key_size = 0;
181460ba621SRuchika Gupta 	uint32_t min_key_size = 0;
182512cbf1dSJens Wiklander 	TEE_Result res = TEE_ERROR_GENERIC;
183512cbf1dSJens Wiklander 
184512cbf1dSJens Wiklander 	assert(session->processing->tee_op_handle == TEE_HANDLE_NULL);
185512cbf1dSJens Wiklander 
186512cbf1dSJens Wiklander 	if (pkcs2tee_algorithm(&algo, params))
187512cbf1dSJens Wiklander 		return PKCS11_CKR_FUNCTION_FAILED;
188512cbf1dSJens Wiklander 
189512cbf1dSJens Wiklander 	/* Sign/Verify with AES or generic key relate to TEE MAC operation */
190689f4e5bSRuchika Gupta 	switch (params->id) {
191689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
192689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
193689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
194689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
195689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
196689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
1972d0cd829SRuchika Gupta 		mechanism_supported_key_sizes_bytes(params->id, &min_key_size,
198460ba621SRuchika Gupta 						    &max_key_size);
199460ba621SRuchika Gupta 		if (key_size < min_key_size)
200460ba621SRuchika Gupta 			return PKCS11_CKR_KEY_SIZE_RANGE;
2012158ea6cSRuchika Gupta 
2022158ea6cSRuchika Gupta 		/*
2032158ea6cSRuchika Gupta 		 * If size of generic key is greater than the size
2042158ea6cSRuchika Gupta 		 * supported by TEE API, this is not considered an
2052158ea6cSRuchika Gupta 		 * error. When loading TEE key, we will hash the key
2062158ea6cSRuchika Gupta 		 * to generate the appropriate key for HMAC operation.
2072158ea6cSRuchika Gupta 		 * This key size will not be greater than the
2082158ea6cSRuchika Gupta 		 * max_key_size. So we can use max_key_size for
2092158ea6cSRuchika Gupta 		 * TEE_AllocateOperation().
2102158ea6cSRuchika Gupta 		 */
2112158ea6cSRuchika Gupta 		if (key_size > max_key_size)
2122158ea6cSRuchika Gupta 			size = max_key_size * 8;
2132158ea6cSRuchika Gupta 
214689f4e5bSRuchika Gupta 		mode = TEE_MODE_MAC;
215689f4e5bSRuchika Gupta 		break;
216689f4e5bSRuchika Gupta 	default:
217512cbf1dSJens Wiklander 		pkcs2tee_mode(&mode, function);
218689f4e5bSRuchika Gupta 		break;
219689f4e5bSRuchika Gupta 	}
220512cbf1dSJens Wiklander 
221512cbf1dSJens Wiklander 	res = TEE_AllocateOperation(&session->processing->tee_op_handle,
222512cbf1dSJens Wiklander 				    algo, mode, size);
223512cbf1dSJens Wiklander 	if (res)
224512cbf1dSJens Wiklander 		EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32,
225512cbf1dSJens Wiklander 		     algo, mode, size);
226512cbf1dSJens Wiklander 
227512cbf1dSJens Wiklander 	if (res == TEE_ERROR_NOT_SUPPORTED)
228512cbf1dSJens Wiklander 		return PKCS11_CKR_MECHANISM_INVALID;
229512cbf1dSJens Wiklander 
230512cbf1dSJens Wiklander 	return tee2pkcs_error(res);
231512cbf1dSJens Wiklander }
232512cbf1dSJens Wiklander 
2332158ea6cSRuchika Gupta static enum pkcs11_rc hash_secret_helper(enum pkcs11_mechanism_id mech_id,
2342158ea6cSRuchika Gupta 					 struct pkcs11_object *obj,
2352158ea6cSRuchika Gupta 					 TEE_Attribute *tee_attr,
2362158ea6cSRuchika Gupta 					 void **ctx,
2372158ea6cSRuchika Gupta 					 size_t *object_size_bits)
2382158ea6cSRuchika Gupta {
2392158ea6cSRuchika Gupta 	uint32_t algo = 0;
2402158ea6cSRuchika Gupta 	void *hash_ptr = NULL;
2412158ea6cSRuchika Gupta 	uint32_t hash_size = 0;
2422158ea6cSRuchika Gupta 	enum pkcs11_rc rc = PKCS11_CKR_OK;
2432158ea6cSRuchika Gupta 
2442158ea6cSRuchika Gupta 	rc = hmac_to_tee_hash(&algo, mech_id);
2452158ea6cSRuchika Gupta 	if (rc)
2462158ea6cSRuchika Gupta 		return rc;
2472158ea6cSRuchika Gupta 
2482158ea6cSRuchika Gupta 	hash_size = TEE_ALG_GET_DIGEST_SIZE(algo);
2492158ea6cSRuchika Gupta 	hash_ptr = TEE_Malloc(hash_size, 0);
2502158ea6cSRuchika Gupta 	if (!hash_ptr)
2512158ea6cSRuchika Gupta 		return PKCS11_CKR_DEVICE_MEMORY;
2522158ea6cSRuchika Gupta 
2532158ea6cSRuchika Gupta 	rc = pkcs2tee_load_hashed_attr(tee_attr, TEE_ATTR_SECRET_VALUE, obj,
2542158ea6cSRuchika Gupta 				       PKCS11_CKA_VALUE, algo, hash_ptr,
2552158ea6cSRuchika Gupta 				       &hash_size);
2562158ea6cSRuchika Gupta 	if (rc) {
2572158ea6cSRuchika Gupta 		EMSG("No secret/hash error");
2582158ea6cSRuchika Gupta 		TEE_Free(hash_ptr);
2592158ea6cSRuchika Gupta 		return rc;
2602158ea6cSRuchika Gupta 	}
2612158ea6cSRuchika Gupta 
2622158ea6cSRuchika Gupta 	*ctx = hash_ptr;
2632158ea6cSRuchika Gupta 
2642158ea6cSRuchika Gupta 	*object_size_bits = hash_size * 8;
2652158ea6cSRuchika Gupta 
2662158ea6cSRuchika Gupta 	return PKCS11_CKR_OK;
2672158ea6cSRuchika Gupta }
2682158ea6cSRuchika Gupta 
269512cbf1dSJens Wiklander static enum pkcs11_rc load_tee_key(struct pkcs11_session *session,
270de94d6f8SRuchika Gupta 				   struct pkcs11_object *obj,
271de94d6f8SRuchika Gupta 				   struct pkcs11_attribute_head *proc_params)
272512cbf1dSJens Wiklander {
273512cbf1dSJens Wiklander 	TEE_Attribute tee_attr = { };
274512cbf1dSJens Wiklander 	size_t object_size = 0;
275512cbf1dSJens Wiklander 	uint32_t tee_key_type = 0;
276de94d6f8SRuchika Gupta 	enum pkcs11_key_type key_type = 0;
277512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
278512cbf1dSJens Wiklander 	TEE_Result res = TEE_ERROR_GENERIC;
2792158ea6cSRuchika Gupta 	uint32_t max_key_size = 0;
2802158ea6cSRuchika Gupta 	uint32_t min_key_size = 0;
281512cbf1dSJens Wiklander 
282512cbf1dSJens Wiklander 	if (obj->key_handle != TEE_HANDLE_NULL) {
283512cbf1dSJens Wiklander 		/* Key was already loaded and fits current need */
284512cbf1dSJens Wiklander 		goto key_ready;
285512cbf1dSJens Wiklander 	}
286512cbf1dSJens Wiklander 
2872158ea6cSRuchika Gupta 	object_size = get_object_key_bit_size(obj);
2882158ea6cSRuchika Gupta 	if (!object_size)
2892158ea6cSRuchika Gupta 		return PKCS11_CKR_GENERAL_ERROR;
290512cbf1dSJens Wiklander 
291de94d6f8SRuchika Gupta 	switch (proc_params->id) {
292de94d6f8SRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
293de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
294de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
295de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
296de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
297de94d6f8SRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
298de94d6f8SRuchika Gupta 		key_type = get_key_type(obj->attributes);
299de94d6f8SRuchika Gupta 		/*
300de94d6f8SRuchika Gupta 		 * If Object Key type is PKCS11_CKK_GENERIC_SECRET,
301de94d6f8SRuchika Gupta 		 * determine the tee_key_type using the
302de94d6f8SRuchika Gupta 		 * mechanism instead of object key_type.
303de94d6f8SRuchika Gupta 		 */
304de94d6f8SRuchika Gupta 		if (key_type == PKCS11_CKK_GENERIC_SECRET)
305de94d6f8SRuchika Gupta 			rc = pkcsmech2tee_key_type(&tee_key_type,
306de94d6f8SRuchika Gupta 						   proc_params->id);
307de94d6f8SRuchika Gupta 		else
308512cbf1dSJens Wiklander 			rc = pkcs2tee_key_type(&tee_key_type, obj);
309de94d6f8SRuchika Gupta 
310512cbf1dSJens Wiklander 		if (rc)
311512cbf1dSJens Wiklander 			return rc;
312512cbf1dSJens Wiklander 
3132d0cd829SRuchika Gupta 		mechanism_supported_key_sizes_bytes(proc_params->id,
3142158ea6cSRuchika Gupta 						    &min_key_size,
3152158ea6cSRuchika Gupta 						    &max_key_size);
3162158ea6cSRuchika Gupta 
3172158ea6cSRuchika Gupta 		if ((object_size / 8) > max_key_size) {
3182158ea6cSRuchika Gupta 			rc = hash_secret_helper(proc_params->id, obj, &tee_attr,
3192158ea6cSRuchika Gupta 						&session->processing->extra_ctx,
3202158ea6cSRuchika Gupta 						&object_size);
3212158ea6cSRuchika Gupta 			if (rc)
3222158ea6cSRuchika Gupta 				return rc;
3232158ea6cSRuchika Gupta 		} else {
3242158ea6cSRuchika Gupta 			if (!pkcs2tee_load_attr(&tee_attr,
3252158ea6cSRuchika Gupta 						TEE_ATTR_SECRET_VALUE,
3262158ea6cSRuchika Gupta 						obj,
3272158ea6cSRuchika Gupta 						PKCS11_CKA_VALUE)) {
3282158ea6cSRuchika Gupta 				EMSG("No secret found");
3292158ea6cSRuchika Gupta 				return PKCS11_CKR_FUNCTION_FAILED;
3302158ea6cSRuchika Gupta 			}
3312158ea6cSRuchika Gupta 		}
3322158ea6cSRuchika Gupta 		break;
3332158ea6cSRuchika Gupta 
3342158ea6cSRuchika Gupta 	default:
3352158ea6cSRuchika Gupta 		rc = pkcs2tee_key_type(&tee_key_type, obj);
3362158ea6cSRuchika Gupta 		if (rc)
3372158ea6cSRuchika Gupta 			return rc;
3382158ea6cSRuchika Gupta 
3392158ea6cSRuchika Gupta 		if (!pkcs2tee_load_attr(&tee_attr, TEE_ATTR_SECRET_VALUE,
3402158ea6cSRuchika Gupta 					obj, PKCS11_CKA_VALUE)) {
3412158ea6cSRuchika Gupta 			EMSG("No secret found");
3422158ea6cSRuchika Gupta 			return PKCS11_CKR_FUNCTION_FAILED;
3432158ea6cSRuchika Gupta 		}
3442158ea6cSRuchika Gupta 		break;
3452158ea6cSRuchika Gupta 	}
346512cbf1dSJens Wiklander 
347512cbf1dSJens Wiklander 	res = TEE_AllocateTransientObject(tee_key_type, object_size,
348512cbf1dSJens Wiklander 					  &obj->key_handle);
349512cbf1dSJens Wiklander 	if (res) {
350512cbf1dSJens Wiklander 		DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res);
351512cbf1dSJens Wiklander 		return tee2pkcs_error(res);
352512cbf1dSJens Wiklander 	}
353512cbf1dSJens Wiklander 
354512cbf1dSJens Wiklander 	res = TEE_PopulateTransientObject(obj->key_handle, &tee_attr, 1);
355512cbf1dSJens Wiklander 	if (res) {
356512cbf1dSJens Wiklander 		DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res);
357512cbf1dSJens Wiklander 		goto error;
358512cbf1dSJens Wiklander 	}
359512cbf1dSJens Wiklander 
360512cbf1dSJens Wiklander key_ready:
361512cbf1dSJens Wiklander 	res = TEE_SetOperationKey(session->processing->tee_op_handle,
362512cbf1dSJens Wiklander 				  obj->key_handle);
363512cbf1dSJens Wiklander 	if (res) {
364512cbf1dSJens Wiklander 		DMSG("TEE_SetOperationKey failed, %#"PRIx32, res);
365512cbf1dSJens Wiklander 		goto error;
366512cbf1dSJens Wiklander 	}
367512cbf1dSJens Wiklander 
368512cbf1dSJens Wiklander 	return PKCS11_CKR_OK;
369512cbf1dSJens Wiklander 
370512cbf1dSJens Wiklander error:
371512cbf1dSJens Wiklander 	TEE_FreeTransientObject(obj->key_handle);
372512cbf1dSJens Wiklander 	obj->key_handle = TEE_HANDLE_NULL;
373512cbf1dSJens Wiklander 
374512cbf1dSJens Wiklander 	return tee2pkcs_error(res);
375512cbf1dSJens Wiklander }
376512cbf1dSJens Wiklander 
377512cbf1dSJens Wiklander static enum pkcs11_rc
37848799892SRuchika Gupta tee_init_derive_symm(struct active_processing *processing,
37948799892SRuchika Gupta 		     struct pkcs11_attribute_head *proc_params)
38048799892SRuchika Gupta {
38148799892SRuchika Gupta 	struct serialargs args = { };
38248799892SRuchika Gupta 	enum pkcs11_rc rc = PKCS11_CKR_OK;
38348799892SRuchika Gupta 	struct input_data_ref *param = NULL;
38448799892SRuchika Gupta 	void *iv = NULL;
38548799892SRuchika Gupta 
38648799892SRuchika Gupta 	if (!proc_params)
38748799892SRuchika Gupta 		return PKCS11_CKR_ARGUMENTS_BAD;
38848799892SRuchika Gupta 
38948799892SRuchika Gupta 	param =	TEE_Malloc(sizeof(struct input_data_ref), TEE_MALLOC_FILL_ZERO);
39048799892SRuchika Gupta 	if (!param)
39148799892SRuchika Gupta 		return PKCS11_CKR_DEVICE_MEMORY;
39248799892SRuchika Gupta 
39348799892SRuchika Gupta 	serialargs_init(&args, proc_params->data, proc_params->size);
39448799892SRuchika Gupta 
39548799892SRuchika Gupta 	switch (proc_params->id) {
39648799892SRuchika Gupta 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
39748799892SRuchika Gupta 		rc = serialargs_get_ptr(&args, &iv, 16);
39848799892SRuchika Gupta 		if (rc)
39948799892SRuchika Gupta 			goto err;
40048799892SRuchika Gupta 		break;
40148799892SRuchika Gupta 	default:
40248799892SRuchika Gupta 		break;
40348799892SRuchika Gupta 	}
40448799892SRuchika Gupta 
40548799892SRuchika Gupta 	rc = serialargs_get(&args, &param->size, sizeof(uint32_t));
40648799892SRuchika Gupta 	if (rc)
40748799892SRuchika Gupta 		goto err;
40848799892SRuchika Gupta 
40948799892SRuchika Gupta 	rc = serialargs_get_ptr(&args, &param->data, param->size);
41048799892SRuchika Gupta 	if (rc)
41148799892SRuchika Gupta 		goto err;
41248799892SRuchika Gupta 
41348799892SRuchika Gupta 	if (serialargs_remaining_bytes(&args)) {
41448799892SRuchika Gupta 		rc = PKCS11_CKR_ARGUMENTS_BAD;
41548799892SRuchika Gupta 		goto err;
41648799892SRuchika Gupta 	}
41748799892SRuchika Gupta 
41848799892SRuchika Gupta 	processing->extra_ctx = param;
41948799892SRuchika Gupta 
42048799892SRuchika Gupta 	switch (proc_params->id) {
42148799892SRuchika Gupta 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
42248799892SRuchika Gupta 		if (param->size % TEE_AES_BLOCK_SIZE) {
42348799892SRuchika Gupta 			rc = PKCS11_CKR_DATA_LEN_RANGE;
42448799892SRuchika Gupta 			goto err;
42548799892SRuchika Gupta 		}
42648799892SRuchika Gupta 		TEE_CipherInit(processing->tee_op_handle, NULL, 0);
42748799892SRuchika Gupta 		break;
42848799892SRuchika Gupta 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
42948799892SRuchika Gupta 		if (param->size % TEE_AES_BLOCK_SIZE) {
43048799892SRuchika Gupta 			rc = PKCS11_CKR_DATA_LEN_RANGE;
43148799892SRuchika Gupta 			goto err;
43248799892SRuchika Gupta 		}
43348799892SRuchika Gupta 		TEE_CipherInit(processing->tee_op_handle, iv, 16);
43448799892SRuchika Gupta 		break;
43548799892SRuchika Gupta 	default:
43648799892SRuchika Gupta 		TEE_Panic(proc_params->id);
43748799892SRuchika Gupta 		break;
43848799892SRuchika Gupta 	}
43948799892SRuchika Gupta 
44048799892SRuchika Gupta 	return PKCS11_CKR_OK;
44148799892SRuchika Gupta 
44248799892SRuchika Gupta err:
44348799892SRuchika Gupta 	processing->extra_ctx = NULL;
44448799892SRuchika Gupta 	TEE_Free(param);
44548799892SRuchika Gupta 	return rc;
44648799892SRuchika Gupta }
44748799892SRuchika Gupta 
44848799892SRuchika Gupta static enum pkcs11_rc
449512cbf1dSJens Wiklander init_tee_operation(struct pkcs11_session *session,
450512cbf1dSJens Wiklander 		   struct pkcs11_attribute_head *proc_params)
451512cbf1dSJens Wiklander {
452512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
453512cbf1dSJens Wiklander 
454512cbf1dSJens Wiklander 	switch (proc_params->id) {
455689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
456689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
457689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
458689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
459689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
460689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
461689f4e5bSRuchika Gupta 		if (proc_params->size)
462689f4e5bSRuchika Gupta 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
463689f4e5bSRuchika Gupta 
464689f4e5bSRuchika Gupta 		TEE_MACInit(session->processing->tee_op_handle, NULL, 0);
465689f4e5bSRuchika Gupta 		rc = PKCS11_CKR_OK;
466689f4e5bSRuchika Gupta 		break;
467512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
468512cbf1dSJens Wiklander 		if (proc_params->size)
469512cbf1dSJens Wiklander 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
470512cbf1dSJens Wiklander 
471512cbf1dSJens Wiklander 		TEE_CipherInit(session->processing->tee_op_handle, NULL, 0);
472512cbf1dSJens Wiklander 		rc = PKCS11_CKR_OK;
473512cbf1dSJens Wiklander 		break;
474512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
475512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC_PAD:
476512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
477512cbf1dSJens Wiklander 		if (proc_params->size != 16)
478512cbf1dSJens Wiklander 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
479512cbf1dSJens Wiklander 
480512cbf1dSJens Wiklander 		TEE_CipherInit(session->processing->tee_op_handle,
481512cbf1dSJens Wiklander 			       proc_params->data, 16);
482512cbf1dSJens Wiklander 		rc = PKCS11_CKR_OK;
483512cbf1dSJens Wiklander 		break;
484512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
485512cbf1dSJens Wiklander 		rc = tee_init_ctr_operation(session->processing,
486512cbf1dSJens Wiklander 					    proc_params->data,
487512cbf1dSJens Wiklander 					    proc_params->size);
488512cbf1dSJens Wiklander 		break;
48948799892SRuchika Gupta 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
49048799892SRuchika Gupta 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
49148799892SRuchika Gupta 		rc = tee_init_derive_symm(session->processing, proc_params);
49248799892SRuchika Gupta 		break;
493512cbf1dSJens Wiklander 	default:
494512cbf1dSJens Wiklander 		TEE_Panic(proc_params->id);
495512cbf1dSJens Wiklander 		break;
496512cbf1dSJens Wiklander 	}
497512cbf1dSJens Wiklander 
498512cbf1dSJens Wiklander 	return rc;
499512cbf1dSJens Wiklander }
500512cbf1dSJens Wiklander 
501512cbf1dSJens Wiklander enum pkcs11_rc init_symm_operation(struct pkcs11_session *session,
502512cbf1dSJens Wiklander 				   enum processing_func function,
503512cbf1dSJens Wiklander 				   struct pkcs11_attribute_head *proc_params,
504512cbf1dSJens Wiklander 				   struct pkcs11_object *obj)
505512cbf1dSJens Wiklander {
506512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_OK;
507512cbf1dSJens Wiklander 
508512cbf1dSJens Wiklander 	assert(processing_is_tee_symm(proc_params->id));
509512cbf1dSJens Wiklander 
510512cbf1dSJens Wiklander 	rc = allocate_tee_operation(session, function, proc_params, obj);
511512cbf1dSJens Wiklander 	if (rc)
512512cbf1dSJens Wiklander 		return rc;
513512cbf1dSJens Wiklander 
514de94d6f8SRuchika Gupta 	rc = load_tee_key(session, obj, proc_params);
515512cbf1dSJens Wiklander 	if (rc)
516512cbf1dSJens Wiklander 		return rc;
517512cbf1dSJens Wiklander 
518512cbf1dSJens Wiklander 	return init_tee_operation(session, proc_params);
519512cbf1dSJens Wiklander }
520512cbf1dSJens Wiklander 
521512cbf1dSJens Wiklander /* Validate input buffer size as per PKCS#11 constraints */
522512cbf1dSJens Wiklander static enum pkcs11_rc input_data_size_is_valid(struct active_processing *proc,
523512cbf1dSJens Wiklander 					       enum processing_func function,
524512cbf1dSJens Wiklander 					       size_t in_size)
525512cbf1dSJens Wiklander {
526512cbf1dSJens Wiklander 	switch (proc->mecha_type) {
527512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
528512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
529512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_ENCRYPT &&
530512cbf1dSJens Wiklander 		    in_size % TEE_AES_BLOCK_SIZE)
531512cbf1dSJens Wiklander 			return PKCS11_CKR_DATA_LEN_RANGE;
532512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_DECRYPT &&
533512cbf1dSJens Wiklander 		    in_size % TEE_AES_BLOCK_SIZE)
534512cbf1dSJens Wiklander 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
535512cbf1dSJens Wiklander 		break;
536512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC_PAD:
537512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_DECRYPT &&
538512cbf1dSJens Wiklander 		    in_size % TEE_AES_BLOCK_SIZE)
539512cbf1dSJens Wiklander 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
540512cbf1dSJens Wiklander 		break;
541512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
542512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_ENCRYPT &&
543512cbf1dSJens Wiklander 		    in_size < TEE_AES_BLOCK_SIZE)
544512cbf1dSJens Wiklander 			return PKCS11_CKR_DATA_LEN_RANGE;
545512cbf1dSJens Wiklander 		if (function == PKCS11_FUNCTION_DECRYPT &&
546512cbf1dSJens Wiklander 		    in_size < TEE_AES_BLOCK_SIZE)
547512cbf1dSJens Wiklander 			return PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
548512cbf1dSJens Wiklander 		break;
549512cbf1dSJens Wiklander 	default:
550512cbf1dSJens Wiklander 		break;
551512cbf1dSJens Wiklander 	}
552512cbf1dSJens Wiklander 
553512cbf1dSJens Wiklander 	return PKCS11_CKR_OK;
554512cbf1dSJens Wiklander }
555512cbf1dSJens Wiklander 
556689f4e5bSRuchika Gupta /* Validate input buffer size as per PKCS#11 constraints */
557689f4e5bSRuchika Gupta static enum pkcs11_rc input_sign_size_is_valid(struct active_processing *proc,
558689f4e5bSRuchika Gupta 					       size_t in_size)
559689f4e5bSRuchika Gupta {
560689f4e5bSRuchika Gupta 	size_t sign_sz = 0;
561689f4e5bSRuchika Gupta 
562689f4e5bSRuchika Gupta 	switch (proc->mecha_type) {
563689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
564689f4e5bSRuchika Gupta 		sign_sz = TEE_MD5_HASH_SIZE;
565689f4e5bSRuchika Gupta 		break;
566689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
567689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA1_HASH_SIZE;
568689f4e5bSRuchika Gupta 		break;
569689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
570689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA224_HASH_SIZE;
571689f4e5bSRuchika Gupta 		break;
572689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
573689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA256_HASH_SIZE;
574689f4e5bSRuchika Gupta 		break;
575689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
576689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA384_HASH_SIZE;
577689f4e5bSRuchika Gupta 		break;
578689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
579689f4e5bSRuchika Gupta 		sign_sz = TEE_SHA512_HASH_SIZE;
580689f4e5bSRuchika Gupta 		break;
581689f4e5bSRuchika Gupta 	default:
582689f4e5bSRuchika Gupta 		return PKCS11_CKR_GENERAL_ERROR;
583689f4e5bSRuchika Gupta 	}
584689f4e5bSRuchika Gupta 
585*42765f82SVictor Chong 	if (in_size != sign_sz)
586689f4e5bSRuchika Gupta 		return PKCS11_CKR_SIGNATURE_LEN_RANGE;
587689f4e5bSRuchika Gupta 
588689f4e5bSRuchika Gupta 	return PKCS11_CKR_OK;
589689f4e5bSRuchika Gupta }
590689f4e5bSRuchika Gupta 
591512cbf1dSJens Wiklander /*
592512cbf1dSJens Wiklander  * step_sym_cipher - processing symmetric (and related) cipher operation step
593512cbf1dSJens Wiklander  *
594512cbf1dSJens Wiklander  * @session - current session
595512cbf1dSJens Wiklander  * @function - processing function (encrypt, decrypt, sign, ...)
596512cbf1dSJens Wiklander  * @step - step ID in the processing (oneshot, update, final)
597512cbf1dSJens Wiklander  * @ptype - invocation parameter types
598512cbf1dSJens Wiklander  * @params - invocation parameter references
599512cbf1dSJens Wiklander  */
600512cbf1dSJens Wiklander enum pkcs11_rc step_symm_operation(struct pkcs11_session *session,
601512cbf1dSJens Wiklander 				   enum processing_func function,
602512cbf1dSJens Wiklander 				   enum processing_step step,
603512cbf1dSJens Wiklander 				   uint32_t ptypes, TEE_Param *params)
604512cbf1dSJens Wiklander {
605512cbf1dSJens Wiklander 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
606512cbf1dSJens Wiklander 	TEE_Result res = TEE_ERROR_GENERIC;
607512cbf1dSJens Wiklander 	void *in_buf = NULL;
608512cbf1dSJens Wiklander 	size_t in_size = 0;
609512cbf1dSJens Wiklander 	void *out_buf = NULL;
610512cbf1dSJens Wiklander 	uint32_t out_size = 0;
611512cbf1dSJens Wiklander 	void *in2_buf = NULL;
612512cbf1dSJens Wiklander 	uint32_t in2_size = 0;
613512cbf1dSJens Wiklander 	bool output_data = false;
614512cbf1dSJens Wiklander 	struct active_processing *proc = session->processing;
615512cbf1dSJens Wiklander 
616512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) {
617512cbf1dSJens Wiklander 		in_buf = params[1].memref.buffer;
618512cbf1dSJens Wiklander 		in_size = params[1].memref.size;
619512cbf1dSJens Wiklander 		if (in_size && !in_buf)
620512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
621512cbf1dSJens Wiklander 	}
622512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) {
623512cbf1dSJens Wiklander 		in2_buf = params[2].memref.buffer;
624512cbf1dSJens Wiklander 		in2_size = params[2].memref.size;
625512cbf1dSJens Wiklander 		if (in2_size && !in2_buf)
626512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
627512cbf1dSJens Wiklander 	}
628512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) {
629512cbf1dSJens Wiklander 		out_buf = params[2].memref.buffer;
630512cbf1dSJens Wiklander 		out_size = params[2].memref.size;
631512cbf1dSJens Wiklander 		if (out_size && !out_buf)
632512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
633512cbf1dSJens Wiklander 	}
634512cbf1dSJens Wiklander 	if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE)
635512cbf1dSJens Wiklander 		return PKCS11_CKR_ARGUMENTS_BAD;
636512cbf1dSJens Wiklander 
637512cbf1dSJens Wiklander 	switch (step) {
638512cbf1dSJens Wiklander 	case PKCS11_FUNC_STEP_ONESHOT:
639512cbf1dSJens Wiklander 	case PKCS11_FUNC_STEP_UPDATE:
640512cbf1dSJens Wiklander 	case PKCS11_FUNC_STEP_FINAL:
641512cbf1dSJens Wiklander 		break;
642512cbf1dSJens Wiklander 	default:
643512cbf1dSJens Wiklander 		return PKCS11_CKR_GENERAL_ERROR;
644512cbf1dSJens Wiklander 	}
645512cbf1dSJens Wiklander 
646512cbf1dSJens Wiklander 	if (step != PKCS11_FUNC_STEP_FINAL) {
647512cbf1dSJens Wiklander 		rc = input_data_size_is_valid(proc, function, in_size);
648512cbf1dSJens Wiklander 		if (rc)
649512cbf1dSJens Wiklander 			return rc;
650512cbf1dSJens Wiklander 	}
651512cbf1dSJens Wiklander 
652512cbf1dSJens Wiklander 	/*
653512cbf1dSJens Wiklander 	 * Feed active operation with data
654512cbf1dSJens Wiklander 	 */
655512cbf1dSJens Wiklander 	switch (proc->mecha_type) {
656689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
657689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
658689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
659689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
660689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
661689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
662689f4e5bSRuchika Gupta 		if (step == PKCS11_FUNC_STEP_FINAL ||
663689f4e5bSRuchika Gupta 		    step == PKCS11_FUNC_STEP_ONESHOT)
664689f4e5bSRuchika Gupta 			break;
665689f4e5bSRuchika Gupta 
666689f4e5bSRuchika Gupta 		if (!in_buf) {
667689f4e5bSRuchika Gupta 			DMSG("No input data");
668689f4e5bSRuchika Gupta 			return PKCS11_CKR_ARGUMENTS_BAD;
669689f4e5bSRuchika Gupta 		}
670689f4e5bSRuchika Gupta 
671689f4e5bSRuchika Gupta 		switch (function) {
672689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_SIGN:
673689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_VERIFY:
674689f4e5bSRuchika Gupta 			TEE_MACUpdate(proc->tee_op_handle, in_buf, in_size);
675689f4e5bSRuchika Gupta 			rc = PKCS11_CKR_OK;
676689f4e5bSRuchika Gupta 			break;
677689f4e5bSRuchika Gupta 		default:
678689f4e5bSRuchika Gupta 			TEE_Panic(function);
679689f4e5bSRuchika Gupta 			break;
680689f4e5bSRuchika Gupta 		}
681689f4e5bSRuchika Gupta 		break;
682689f4e5bSRuchika Gupta 
683512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
684512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
685512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC_PAD:
686512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
687512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
688512cbf1dSJens Wiklander 		if (step == PKCS11_FUNC_STEP_FINAL ||
689512cbf1dSJens Wiklander 		    step == PKCS11_FUNC_STEP_ONESHOT)
690512cbf1dSJens Wiklander 			break;
691512cbf1dSJens Wiklander 
692512cbf1dSJens Wiklander 		if (!in_buf) {
693512cbf1dSJens Wiklander 			EMSG("No input data");
694512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
695512cbf1dSJens Wiklander 		}
696512cbf1dSJens Wiklander 
697512cbf1dSJens Wiklander 		switch (function) {
698512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_ENCRYPT:
699512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_DECRYPT:
700512cbf1dSJens Wiklander 			res = TEE_CipherUpdate(proc->tee_op_handle,
701512cbf1dSJens Wiklander 					       in_buf, in_size,
702512cbf1dSJens Wiklander 						out_buf, &out_size);
703512cbf1dSJens Wiklander 			output_data = true;
704512cbf1dSJens Wiklander 			rc = tee2pkcs_error(res);
705512cbf1dSJens Wiklander 			break;
706512cbf1dSJens Wiklander 		default:
707512cbf1dSJens Wiklander 			TEE_Panic(function);
708512cbf1dSJens Wiklander 			break;
709512cbf1dSJens Wiklander 		}
710512cbf1dSJens Wiklander 		break;
711512cbf1dSJens Wiklander 
712512cbf1dSJens Wiklander 	default:
713512cbf1dSJens Wiklander 		TEE_Panic(proc->mecha_type);
714512cbf1dSJens Wiklander 		break;
715512cbf1dSJens Wiklander 	}
716512cbf1dSJens Wiklander 
717512cbf1dSJens Wiklander 	if (step == PKCS11_FUNC_STEP_UPDATE)
718512cbf1dSJens Wiklander 		goto out;
719512cbf1dSJens Wiklander 
720512cbf1dSJens Wiklander 	/*
721512cbf1dSJens Wiklander 	 * Finalize (PKCS11_FUNC_STEP_ONESHOT/_FINAL) operation
722512cbf1dSJens Wiklander 	 */
723512cbf1dSJens Wiklander 	switch (session->processing->mecha_type) {
724689f4e5bSRuchika Gupta 	case PKCS11_CKM_MD5_HMAC:
725689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA_1_HMAC:
726689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA224_HMAC:
727689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA256_HMAC:
728689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA384_HMAC:
729689f4e5bSRuchika Gupta 	case PKCS11_CKM_SHA512_HMAC:
730689f4e5bSRuchika Gupta 		switch (function) {
731689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_SIGN:
732689f4e5bSRuchika Gupta 			res = TEE_MACComputeFinal(proc->tee_op_handle,
733689f4e5bSRuchika Gupta 						  in_buf, in_size, out_buf,
734689f4e5bSRuchika Gupta 						  &out_size);
735689f4e5bSRuchika Gupta 			output_data = true;
736689f4e5bSRuchika Gupta 			rc = tee2pkcs_error(res);
737689f4e5bSRuchika Gupta 			break;
738689f4e5bSRuchika Gupta 		case PKCS11_FUNCTION_VERIFY:
739689f4e5bSRuchika Gupta 			rc = input_sign_size_is_valid(proc, in2_size);
740689f4e5bSRuchika Gupta 			if (rc)
741689f4e5bSRuchika Gupta 				return rc;
742689f4e5bSRuchika Gupta 			res = TEE_MACCompareFinal(proc->tee_op_handle,
743689f4e5bSRuchika Gupta 						  in_buf, in_size, in2_buf,
744689f4e5bSRuchika Gupta 						  in2_size);
745689f4e5bSRuchika Gupta 			rc = tee2pkcs_error(res);
746689f4e5bSRuchika Gupta 			break;
747689f4e5bSRuchika Gupta 		default:
748689f4e5bSRuchika Gupta 			TEE_Panic(function);
749689f4e5bSRuchika Gupta 			break;
750689f4e5bSRuchika Gupta 		}
7512158ea6cSRuchika Gupta 
752689f4e5bSRuchika Gupta 		break;
753689f4e5bSRuchika Gupta 
754512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_ECB:
755512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC:
756512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CBC_PAD:
757512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTS:
758512cbf1dSJens Wiklander 	case PKCS11_CKM_AES_CTR:
759512cbf1dSJens Wiklander 		if (step == PKCS11_FUNC_STEP_ONESHOT && !in_buf) {
760512cbf1dSJens Wiklander 			EMSG("No input data");
761512cbf1dSJens Wiklander 			return PKCS11_CKR_ARGUMENTS_BAD;
762512cbf1dSJens Wiklander 		}
763512cbf1dSJens Wiklander 
764512cbf1dSJens Wiklander 		switch (function) {
765512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_ENCRYPT:
766512cbf1dSJens Wiklander 		case PKCS11_FUNCTION_DECRYPT:
767512cbf1dSJens Wiklander 			res = TEE_CipherDoFinal(proc->tee_op_handle,
768512cbf1dSJens Wiklander 						in_buf, in_size,
769512cbf1dSJens Wiklander 						out_buf, &out_size);
770512cbf1dSJens Wiklander 			output_data = true;
771512cbf1dSJens Wiklander 			rc = tee2pkcs_error(res);
772512cbf1dSJens Wiklander 			break;
773512cbf1dSJens Wiklander 		default:
774512cbf1dSJens Wiklander 			TEE_Panic(function);
775512cbf1dSJens Wiklander 			break;
776512cbf1dSJens Wiklander 		}
777512cbf1dSJens Wiklander 		break;
778512cbf1dSJens Wiklander 	default:
779512cbf1dSJens Wiklander 		TEE_Panic(proc->mecha_type);
780512cbf1dSJens Wiklander 		break;
781512cbf1dSJens Wiklander 	}
782512cbf1dSJens Wiklander 
783512cbf1dSJens Wiklander out:
784512cbf1dSJens Wiklander 	if (output_data &&
785512cbf1dSJens Wiklander 	    (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) {
786512cbf1dSJens Wiklander 		switch (TEE_PARAM_TYPE_GET(ptypes, 2)) {
787512cbf1dSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
788512cbf1dSJens Wiklander 		case TEE_PARAM_TYPE_MEMREF_INOUT:
789512cbf1dSJens Wiklander 			params[2].memref.size = out_size;
790512cbf1dSJens Wiklander 			break;
791512cbf1dSJens Wiklander 		default:
792512cbf1dSJens Wiklander 			rc = PKCS11_CKR_ARGUMENTS_BAD;
793512cbf1dSJens Wiklander 			break;
794512cbf1dSJens Wiklander 		}
795512cbf1dSJens Wiklander 	}
796512cbf1dSJens Wiklander 
797512cbf1dSJens Wiklander 	return rc;
798512cbf1dSJens Wiklander }
79948799892SRuchika Gupta 
80048799892SRuchika Gupta enum pkcs11_rc derive_key_by_symm_enc(struct pkcs11_session *session,
8018c499324SRuchika Gupta 				      void **out_buf, uint32_t *out_size)
80248799892SRuchika Gupta {
80348799892SRuchika Gupta 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
80448799892SRuchika Gupta 	TEE_Result res = TEE_ERROR_GENERIC;
80548799892SRuchika Gupta 	struct active_processing *proc = session->processing;
80648799892SRuchika Gupta 	struct input_data_ref *input = proc->extra_ctx;
80748799892SRuchika Gupta 	void *in_buf = NULL;
80848799892SRuchika Gupta 	uint32_t in_size = 0;
80948799892SRuchika Gupta 
8108c499324SRuchika Gupta 	switch (proc->mecha_type) {
8118c499324SRuchika Gupta 	case PKCS11_CKM_AES_ECB_ENCRYPT_DATA:
8128c499324SRuchika Gupta 	case PKCS11_CKM_AES_CBC_ENCRYPT_DATA:
81348799892SRuchika Gupta 		if (!proc->extra_ctx)
81448799892SRuchika Gupta 			return PKCS11_CKR_ARGUMENTS_BAD;
81548799892SRuchika Gupta 
81648799892SRuchika Gupta 		in_buf = input->data;
81748799892SRuchika Gupta 		in_size = input->size;
81848799892SRuchika Gupta 
8198c499324SRuchika Gupta 		*out_size = in_size;
8208c499324SRuchika Gupta 		*out_buf = TEE_Malloc(*out_size, 0);
8218c499324SRuchika Gupta 		if (!*out_buf)
82248799892SRuchika Gupta 			return PKCS11_CKR_DEVICE_MEMORY;
82348799892SRuchika Gupta 
8248c499324SRuchika Gupta 		res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_size,
8258c499324SRuchika Gupta 					*out_buf, out_size);
82648799892SRuchika Gupta 		rc = tee2pkcs_error(res);
82748799892SRuchika Gupta 		if (rc)
8288c499324SRuchika Gupta 			TEE_Free(*out_buf);
8298c499324SRuchika Gupta 		break;
8308c499324SRuchika Gupta 	default:
8318c499324SRuchika Gupta 		return PKCS11_CKR_MECHANISM_INVALID;
83248799892SRuchika Gupta 	}
83348799892SRuchika Gupta 
83448799892SRuchika Gupta 	return rc;
83548799892SRuchika Gupta }
8365f80f270SRuchika Gupta 
8375f80f270SRuchika Gupta enum pkcs11_rc wrap_data_by_symm_enc(struct pkcs11_session *session,
8385f80f270SRuchika Gupta 				     void *data, uint32_t data_sz,
8395f80f270SRuchika Gupta 				     void *out_buf, uint32_t *out_sz)
8405f80f270SRuchika Gupta {
8415f80f270SRuchika Gupta 	TEE_Result res = TEE_ERROR_GENERIC;
8425f80f270SRuchika Gupta 	struct active_processing *proc = session->processing;
8435f80f270SRuchika Gupta 	void *in_buf = NULL;
8445f80f270SRuchika Gupta 	uint32_t align = 0;
8455f80f270SRuchika Gupta 	uint32_t in_sz = data_sz;
8465f80f270SRuchika Gupta 	uint32_t tmp_sz = *out_sz;
8475f80f270SRuchika Gupta 	uint8_t *tmp_buf = out_buf;
8485f80f270SRuchika Gupta 
8495f80f270SRuchika Gupta 	switch (proc->mecha_type) {
8505f80f270SRuchika Gupta 	case PKCS11_CKM_AES_ECB:
8515f80f270SRuchika Gupta 	case PKCS11_CKM_AES_CBC:
8525f80f270SRuchika Gupta 		align = data_sz % TEE_AES_BLOCK_SIZE;
8535f80f270SRuchika Gupta 		if (align)
8545f80f270SRuchika Gupta 			in_sz = data_sz + (TEE_AES_BLOCK_SIZE - align);
8555f80f270SRuchika Gupta 
8565f80f270SRuchika Gupta 		if (*out_sz < in_sz) {
8575f80f270SRuchika Gupta 			*out_sz = in_sz;
8585f80f270SRuchika Gupta 			return PKCS11_CKR_BUFFER_TOO_SMALL;
8595f80f270SRuchika Gupta 		}
8605f80f270SRuchika Gupta 
8615f80f270SRuchika Gupta 		if (align) {
8625f80f270SRuchika Gupta 			if (data_sz > TEE_AES_BLOCK_SIZE) {
8635f80f270SRuchika Gupta 				in_sz = data_sz - align;
8645f80f270SRuchika Gupta 				res = TEE_CipherUpdate(proc->tee_op_handle,
8655f80f270SRuchika Gupta 						       data, in_sz, tmp_buf,
8665f80f270SRuchika Gupta 						       &tmp_sz);
8675f80f270SRuchika Gupta 				if (res) {
8685f80f270SRuchika Gupta 					assert(res != TEE_ERROR_SHORT_BUFFER);
8695f80f270SRuchika Gupta 					return tee2pkcs_error(res);
8705f80f270SRuchika Gupta 				}
8715f80f270SRuchika Gupta 				tmp_buf += tmp_sz;
8725f80f270SRuchika Gupta 				tmp_sz = *out_sz - tmp_sz;
8735f80f270SRuchika Gupta 			} else {
8745f80f270SRuchika Gupta 				in_sz = 0;
8755f80f270SRuchika Gupta 			}
8765f80f270SRuchika Gupta 
8775f80f270SRuchika Gupta 			in_buf = TEE_Malloc(TEE_AES_BLOCK_SIZE,
8785f80f270SRuchika Gupta 					    TEE_MALLOC_FILL_ZERO);
8795f80f270SRuchika Gupta 			if (!in_buf)
8805f80f270SRuchika Gupta 				return PKCS11_CKR_DEVICE_MEMORY;
8815f80f270SRuchika Gupta 
8825f80f270SRuchika Gupta 			TEE_MemMove(in_buf, (uint8_t *)data + in_sz, align);
8835f80f270SRuchika Gupta 			in_sz = TEE_AES_BLOCK_SIZE;
8845f80f270SRuchika Gupta 		} else {
8855f80f270SRuchika Gupta 			in_buf = data;
8865f80f270SRuchika Gupta 			in_sz = data_sz;
8875f80f270SRuchika Gupta 		}
8885f80f270SRuchika Gupta 
8895f80f270SRuchika Gupta 		res = TEE_CipherDoFinal(proc->tee_op_handle, in_buf, in_sz,
8905f80f270SRuchika Gupta 					tmp_buf, &tmp_sz);
8915f80f270SRuchika Gupta 		if (res == TEE_SUCCESS || res == TEE_ERROR_SHORT_BUFFER) {
8925f80f270SRuchika Gupta 			*out_sz = tmp_sz;
8935f80f270SRuchika Gupta 			if (align)
8945f80f270SRuchika Gupta 				*out_sz += tmp_buf - (uint8_t *)out_buf;
8955f80f270SRuchika Gupta 		}
8965f80f270SRuchika Gupta 
8975f80f270SRuchika Gupta 		if (align)
8985f80f270SRuchika Gupta 			TEE_Free(in_buf);
8995f80f270SRuchika Gupta 
9005f80f270SRuchika Gupta 		return tee2pkcs_error(res);
9015f80f270SRuchika Gupta 	default:
9025f80f270SRuchika Gupta 		return PKCS11_CKR_MECHANISM_INVALID;
9035f80f270SRuchika Gupta 	}
9045f80f270SRuchika Gupta 
9055f80f270SRuchika Gupta 	return PKCS11_CKR_GENERAL_ERROR;
9065f80f270SRuchika Gupta }
9073668310bSRuchika Gupta 
9083668310bSRuchika Gupta enum pkcs11_rc unwrap_key_by_symm(struct pkcs11_session *session, void *data,
9093668310bSRuchika Gupta 				  uint32_t data_sz, void **out_buf,
9103668310bSRuchika Gupta 				  uint32_t *out_sz)
9113668310bSRuchika Gupta {
9123668310bSRuchika Gupta 	TEE_Result res = TEE_ERROR_GENERIC;
9133668310bSRuchika Gupta 	struct active_processing *proc = session->processing;
9143668310bSRuchika Gupta 
9153668310bSRuchika Gupta 	if (input_data_size_is_valid(proc, PKCS11_FUNCTION_DECRYPT, data_sz))
9163668310bSRuchika Gupta 		return PKCS11_CKR_WRAPPED_KEY_LEN_RANGE;
9173668310bSRuchika Gupta 
9183668310bSRuchika Gupta 	switch (proc->mecha_type) {
9193668310bSRuchika Gupta 	case PKCS11_CKM_AES_ECB:
9203668310bSRuchika Gupta 	case PKCS11_CKM_AES_CBC:
9213668310bSRuchika Gupta 		*out_sz = 0;
9223668310bSRuchika Gupta 		res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz,
9233668310bSRuchika Gupta 					NULL, out_sz);
9243668310bSRuchika Gupta 		if (res != TEE_ERROR_SHORT_BUFFER) {
9253668310bSRuchika Gupta 			DMSG("TEE_CipherDoFinal() issue: %#"PRIx32, res);
9263668310bSRuchika Gupta 			return PKCS11_CKR_GENERAL_ERROR;
9273668310bSRuchika Gupta 		}
9283668310bSRuchika Gupta 
9293668310bSRuchika Gupta 		*out_buf = TEE_Malloc(*out_sz, TEE_MALLOC_FILL_ZERO);
9303668310bSRuchika Gupta 		if (!*out_buf)
9313668310bSRuchika Gupta 			return PKCS11_CKR_DEVICE_MEMORY;
9323668310bSRuchika Gupta 
9333668310bSRuchika Gupta 		res = TEE_CipherDoFinal(proc->tee_op_handle, data, data_sz,
9343668310bSRuchika Gupta 				        *out_buf, out_sz);
9353668310bSRuchika Gupta 		if (tee2pkcs_error(res)) {
9363668310bSRuchika Gupta 			TEE_Free(*out_buf);
9373668310bSRuchika Gupta 			*out_buf = NULL;
9383668310bSRuchika Gupta 			return PKCS11_CKR_WRAPPED_KEY_INVALID;
9393668310bSRuchika Gupta 		}
9403668310bSRuchika Gupta 		break;
9413668310bSRuchika Gupta 	default:
9423668310bSRuchika Gupta 		return PKCS11_CKR_MECHANISM_INVALID;
9433668310bSRuchika Gupta 	}
9443668310bSRuchika Gupta 
9453668310bSRuchika Gupta 	return PKCS11_CKR_OK;
9463668310bSRuchika Gupta }
947