xref: /optee_os/ta/pkcs11/src/processing_asymm.c (revision cc062b4691e67702556da35e57d526d447ed211c)
1fb279d8bSVesa Jääskeläinen // SPDX-License-Identifier: BSD-2-Clause
2fb279d8bSVesa Jääskeläinen /*
3fb279d8bSVesa Jääskeläinen  * Copyright (c) 2018-2020, Linaro Limited
4fb279d8bSVesa Jääskeläinen  */
5fb279d8bSVesa Jääskeläinen 
6fb279d8bSVesa Jääskeläinen #include <assert.h>
7fb279d8bSVesa Jääskeläinen #include <compiler.h>
8fb279d8bSVesa Jääskeläinen #include <tee_api_defines.h>
9fb279d8bSVesa Jääskeläinen #include <tee_internal_api.h>
10fb279d8bSVesa Jääskeläinen #include <tee_internal_api_extensions.h>
11fb279d8bSVesa Jääskeläinen 
12fb279d8bSVesa Jääskeläinen #include "attributes.h"
13fb279d8bSVesa Jääskeläinen #include "pkcs11_helpers.h"
14fb279d8bSVesa Jääskeläinen #include "pkcs11_token.h"
15fb279d8bSVesa Jääskeläinen #include "processing.h"
16fb279d8bSVesa Jääskeläinen #include "serializer.h"
17fb279d8bSVesa Jääskeläinen 
18fb279d8bSVesa Jääskeläinen bool processing_is_tee_asymm(uint32_t proc_id)
19fb279d8bSVesa Jääskeläinen {
20fb279d8bSVesa Jääskeläinen 	switch (proc_id) {
210442c956SVesa Jääskeläinen 	/* RSA flavors */
220442c956SVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS:
23dc8c77fcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_OAEP:
24d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_PSS:
250442c956SVesa Jääskeläinen 	case PKCS11_CKM_MD5_RSA_PKCS:
260442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS:
270442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS:
280442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS:
290442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS:
300442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS:
31d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
32d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
33d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
34d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
35d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
36fb279d8bSVesa Jääskeläinen 	/* EC flavors */
37fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA:
38*cc062b46SJorge Ramirez-Ortiz 	case PKCS11_CKM_ECDH1_DERIVE:
39fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
40fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
41fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
42fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
43fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
44fb279d8bSVesa Jääskeläinen 		return true;
45fb279d8bSVesa Jääskeläinen 	default:
46fb279d8bSVesa Jääskeläinen 		return false;
47fb279d8bSVesa Jääskeläinen 	}
48fb279d8bSVesa Jääskeläinen }
49fb279d8bSVesa Jääskeläinen 
50fb279d8bSVesa Jääskeläinen static enum pkcs11_rc
51fb279d8bSVesa Jääskeläinen pkcs2tee_algorithm(uint32_t *tee_id, uint32_t *tee_hash_id,
52fb279d8bSVesa Jääskeläinen 		   enum processing_func function __unused,
53fb279d8bSVesa Jääskeläinen 		   struct pkcs11_attribute_head *proc_params,
54fb279d8bSVesa Jääskeläinen 		   struct pkcs11_object *obj)
55fb279d8bSVesa Jääskeläinen {
56fb279d8bSVesa Jääskeläinen 	static const struct {
57fb279d8bSVesa Jääskeläinen 		enum pkcs11_mechanism_id mech_id;
58fb279d8bSVesa Jääskeläinen 		uint32_t tee_id;
59fb279d8bSVesa Jääskeläinen 		uint32_t tee_hash_id;
60fb279d8bSVesa Jääskeläinen 	} pkcs2tee_algo[] = {
610442c956SVesa Jääskeläinen 		/* RSA flavors */
620442c956SVesa Jääskeläinen 		{ PKCS11_CKM_RSA_PKCS, TEE_ALG_RSAES_PKCS1_V1_5, 0 },
63dc8c77fcSVesa Jääskeläinen 		{ PKCS11_CKM_RSA_PKCS_OAEP, 1, 0 },
64d9af50bcSVesa Jääskeläinen 		{ PKCS11_CKM_RSA_PKCS_PSS, 1, 0 },
650442c956SVesa Jääskeläinen 		{ PKCS11_CKM_MD5_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_MD5,
660442c956SVesa Jääskeläinen 		  TEE_ALG_MD5 },
670442c956SVesa Jääskeläinen 		{ PKCS11_CKM_SHA1_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA1,
680442c956SVesa Jääskeläinen 		  TEE_ALG_SHA1 },
690442c956SVesa Jääskeläinen 		{ PKCS11_CKM_SHA224_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA224,
700442c956SVesa Jääskeläinen 		  TEE_ALG_SHA224 },
710442c956SVesa Jääskeläinen 		{ PKCS11_CKM_SHA256_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA256,
720442c956SVesa Jääskeläinen 		  TEE_ALG_SHA256 },
730442c956SVesa Jääskeläinen 		{ PKCS11_CKM_SHA384_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA384,
740442c956SVesa Jääskeläinen 		  TEE_ALG_SHA384 },
750442c956SVesa Jääskeläinen 		{ PKCS11_CKM_SHA512_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA512,
760442c956SVesa Jääskeläinen 		  TEE_ALG_SHA512 },
77d9af50bcSVesa Jääskeläinen 		{ PKCS11_CKM_SHA1_RSA_PKCS_PSS,
78d9af50bcSVesa Jääskeläinen 		  TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1, TEE_ALG_SHA1 },
79d9af50bcSVesa Jääskeläinen 		{ PKCS11_CKM_SHA224_RSA_PKCS_PSS,
80d9af50bcSVesa Jääskeläinen 		  TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224, TEE_ALG_SHA224 },
81d9af50bcSVesa Jääskeläinen 		{ PKCS11_CKM_SHA256_RSA_PKCS_PSS,
82d9af50bcSVesa Jääskeläinen 		  TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256, TEE_ALG_SHA256 },
83d9af50bcSVesa Jääskeläinen 		{ PKCS11_CKM_SHA384_RSA_PKCS_PSS,
84d9af50bcSVesa Jääskeläinen 		  TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384, TEE_ALG_SHA384 },
85d9af50bcSVesa Jääskeläinen 		{ PKCS11_CKM_SHA512_RSA_PKCS_PSS,
86d9af50bcSVesa Jääskeläinen 		  TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512, TEE_ALG_SHA512 },
87fb279d8bSVesa Jääskeläinen 		/* EC flavors (Must find key size from the object) */
88fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA, 1, 0 },
89fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA_SHA1, 1, TEE_ALG_SHA1 },
90fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA_SHA224, 1, TEE_ALG_SHA224 },
91fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA_SHA256, 1, TEE_ALG_SHA256 },
92fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA_SHA384, 1, TEE_ALG_SHA384 },
93fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA_SHA512, 1, TEE_ALG_SHA512 },
94*cc062b46SJorge Ramirez-Ortiz 		{ PKCS11_CKM_ECDH1_DERIVE, 1, 0 },
95fb279d8bSVesa Jääskeläinen 	};
96fb279d8bSVesa Jääskeläinen 	size_t n = 0;
97fb279d8bSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
98fb279d8bSVesa Jääskeläinen 
99fb279d8bSVesa Jääskeläinen 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) {
100fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_algo[n].mech_id == proc_params->id) {
101fb279d8bSVesa Jääskeläinen 			*tee_id = pkcs2tee_algo[n].tee_id;
102fb279d8bSVesa Jääskeläinen 			*tee_hash_id = pkcs2tee_algo[n].tee_hash_id;
103fb279d8bSVesa Jääskeläinen 			break;
104fb279d8bSVesa Jääskeläinen 		}
105fb279d8bSVesa Jääskeläinen 	}
106fb279d8bSVesa Jääskeläinen 
107fb279d8bSVesa Jääskeläinen 	if (n == ARRAY_SIZE(pkcs2tee_algo))
108fb279d8bSVesa Jääskeläinen 		return PKCS11_RV_NOT_IMPLEMENTED;
109fb279d8bSVesa Jääskeläinen 
110fb279d8bSVesa Jääskeläinen 	switch (proc_params->id) {
111d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_PSS:
112d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
113d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
114d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
115d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
116d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
117d9af50bcSVesa Jääskeläinen 		rc = pkcs2tee_algo_rsa_pss(tee_id, proc_params);
118d9af50bcSVesa Jääskeläinen 		break;
119dc8c77fcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_OAEP:
120dc8c77fcSVesa Jääskeläinen 		rc = pkcs2tee_algo_rsa_oaep(tee_id, tee_hash_id, proc_params);
121dc8c77fcSVesa Jääskeläinen 		break;
122fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA:
123fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
124fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
125fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
126fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
127fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
128fb279d8bSVesa Jääskeläinen 		rc = pkcs2tee_algo_ecdsa(tee_id, proc_params, obj);
129fb279d8bSVesa Jääskeläinen 		break;
130*cc062b46SJorge Ramirez-Ortiz 	case PKCS11_CKM_ECDH1_DERIVE:
131*cc062b46SJorge Ramirez-Ortiz 		rc = pkcs2tee_algo_ecdh(tee_id, proc_params, obj);
132*cc062b46SJorge Ramirez-Ortiz 		break;
133fb279d8bSVesa Jääskeläinen 	default:
134fb279d8bSVesa Jääskeläinen 		rc = PKCS11_CKR_OK;
135fb279d8bSVesa Jääskeläinen 		break;
136fb279d8bSVesa Jääskeläinen 	}
137fb279d8bSVesa Jääskeläinen 
1380442c956SVesa Jääskeläinen 	/*
1390442c956SVesa Jääskeläinen 	 * PKCS#11 uses single mechanism CKM_RSA_PKCS for both ciphering and
1400442c956SVesa Jääskeläinen 	 * authentication whereas GPD TEE expects TEE_ALG_RSAES_PKCS1_V1_5 for
1410442c956SVesa Jääskeläinen 	 * ciphering and TEE_ALG_RSASSA_PKCS1_V1_5 for authentication.
1420442c956SVesa Jääskeläinen 	 */
1430442c956SVesa Jääskeläinen 	if (*tee_id == TEE_ALG_RSAES_PKCS1_V1_5 &&
1440442c956SVesa Jääskeläinen 	    (function == PKCS11_FUNCTION_SIGN ||
1450442c956SVesa Jääskeläinen 	     function == PKCS11_FUNCTION_VERIFY))
1460442c956SVesa Jääskeläinen 		*tee_id = TEE_ALG_RSASSA_PKCS1_V1_5;
1470442c956SVesa Jääskeläinen 
148fb279d8bSVesa Jääskeläinen 	return rc;
149fb279d8bSVesa Jääskeläinen }
150fb279d8bSVesa Jääskeläinen 
151fb279d8bSVesa Jääskeläinen static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type,
152fb279d8bSVesa Jääskeläinen 					struct pkcs11_object *obj,
153fb279d8bSVesa Jääskeläinen 					enum processing_func function)
154fb279d8bSVesa Jääskeläinen {
155fb279d8bSVesa Jääskeläinen 	enum pkcs11_class_id class = get_class(obj->attributes);
156fb279d8bSVesa Jääskeläinen 	enum pkcs11_key_type type = get_key_type(obj->attributes);
157fb279d8bSVesa Jääskeläinen 
158fb279d8bSVesa Jääskeläinen 	switch (class) {
159fb279d8bSVesa Jääskeläinen 	case PKCS11_CKO_PUBLIC_KEY:
160fb279d8bSVesa Jääskeläinen 	case PKCS11_CKO_PRIVATE_KEY:
161fb279d8bSVesa Jääskeläinen 		break;
162fb279d8bSVesa Jääskeläinen 	default:
163fb279d8bSVesa Jääskeläinen 		TEE_Panic(class);
164fb279d8bSVesa Jääskeläinen 		break;
165fb279d8bSVesa Jääskeläinen 	}
166fb279d8bSVesa Jääskeläinen 
167fb279d8bSVesa Jääskeläinen 	switch (type) {
168fb279d8bSVesa Jääskeläinen 	case PKCS11_CKK_EC:
169*cc062b46SJorge Ramirez-Ortiz 		if (class == PKCS11_CKO_PRIVATE_KEY) {
170*cc062b46SJorge Ramirez-Ortiz 			if (function == PKCS11_FUNCTION_DERIVE)
171*cc062b46SJorge Ramirez-Ortiz 				*tee_type = TEE_TYPE_ECDH_KEYPAIR;
172*cc062b46SJorge Ramirez-Ortiz 			else
173fb279d8bSVesa Jääskeläinen 				*tee_type = TEE_TYPE_ECDSA_KEYPAIR;
174*cc062b46SJorge Ramirez-Ortiz 		} else {
175*cc062b46SJorge Ramirez-Ortiz 			if (function == PKCS11_FUNCTION_DERIVE)
176*cc062b46SJorge Ramirez-Ortiz 				*tee_type = TEE_TYPE_ECDH_PUBLIC_KEY;
177fb279d8bSVesa Jääskeläinen 			else
178fb279d8bSVesa Jääskeläinen 				*tee_type = TEE_TYPE_ECDSA_PUBLIC_KEY;
179*cc062b46SJorge Ramirez-Ortiz 		}
180fb279d8bSVesa Jääskeläinen 		break;
1810442c956SVesa Jääskeläinen 	case PKCS11_CKK_RSA:
1820442c956SVesa Jääskeläinen 		if (class == PKCS11_CKO_PRIVATE_KEY)
1830442c956SVesa Jääskeläinen 			*tee_type = TEE_TYPE_RSA_KEYPAIR;
1840442c956SVesa Jääskeläinen 		else
1850442c956SVesa Jääskeläinen 			*tee_type = TEE_TYPE_RSA_PUBLIC_KEY;
1860442c956SVesa Jääskeläinen 		break;
187fb279d8bSVesa Jääskeläinen 	default:
188fb279d8bSVesa Jääskeläinen 		TEE_Panic(type);
189fb279d8bSVesa Jääskeläinen 		break;
190fb279d8bSVesa Jääskeläinen 	}
191fb279d8bSVesa Jääskeläinen 
192fb279d8bSVesa Jääskeläinen 	return PKCS11_CKR_OK;
193fb279d8bSVesa Jääskeläinen }
194fb279d8bSVesa Jääskeläinen 
195fb279d8bSVesa Jääskeläinen static enum pkcs11_rc
196fb279d8bSVesa Jääskeläinen allocate_tee_operation(struct pkcs11_session *session,
197fb279d8bSVesa Jääskeläinen 		       enum processing_func function,
198fb279d8bSVesa Jääskeläinen 		       struct pkcs11_attribute_head *params,
199fb279d8bSVesa Jääskeläinen 		       struct pkcs11_object *obj)
200fb279d8bSVesa Jääskeläinen {
201fb279d8bSVesa Jääskeläinen 	uint32_t size = (uint32_t)get_object_key_bit_size(obj);
202fb279d8bSVesa Jääskeläinen 	uint32_t algo = 0;
203fb279d8bSVesa Jääskeläinen 	uint32_t hash_algo = 0;
204fb279d8bSVesa Jääskeläinen 	uint32_t mode = 0;
205fb279d8bSVesa Jääskeläinen 	uint32_t hash_mode = 0;
206fb279d8bSVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
207fb279d8bSVesa Jääskeläinen 	struct active_processing *processing = session->processing;
208fb279d8bSVesa Jääskeläinen 
209fb279d8bSVesa Jääskeläinen 	assert(processing->tee_op_handle == TEE_HANDLE_NULL);
210fb279d8bSVesa Jääskeläinen 	assert(processing->tee_hash_op_handle == TEE_HANDLE_NULL);
211fb279d8bSVesa Jääskeläinen 
212fb279d8bSVesa Jääskeläinen 	if (pkcs2tee_algorithm(&algo, &hash_algo, function, params, obj))
213fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_FUNCTION_FAILED;
214fb279d8bSVesa Jääskeläinen 
215fb279d8bSVesa Jääskeläinen 	pkcs2tee_mode(&mode, function);
216fb279d8bSVesa Jääskeläinen 
217fb279d8bSVesa Jääskeläinen 	if (hash_algo) {
218fb279d8bSVesa Jääskeläinen 		pkcs2tee_mode(&hash_mode, PKCS11_FUNCTION_DIGEST);
219fb279d8bSVesa Jääskeläinen 
220fb279d8bSVesa Jääskeläinen 		res = TEE_AllocateOperation(&processing->tee_hash_op_handle,
221fb279d8bSVesa Jääskeläinen 					    hash_algo, hash_mode, 0);
222fb279d8bSVesa Jääskeläinen 		if (res) {
223fb279d8bSVesa Jääskeläinen 			EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32,
224fb279d8bSVesa Jääskeläinen 			     hash_algo, hash_mode);
225fb279d8bSVesa Jääskeläinen 
226fb279d8bSVesa Jääskeläinen 			if (res == TEE_ERROR_NOT_SUPPORTED)
227fb279d8bSVesa Jääskeläinen 				return PKCS11_CKR_MECHANISM_INVALID;
228fb279d8bSVesa Jääskeläinen 			return tee2pkcs_error(res);
229fb279d8bSVesa Jääskeläinen 		}
230fb279d8bSVesa Jääskeläinen 		processing->tee_hash_algo = hash_algo;
231fb279d8bSVesa Jääskeläinen 	}
232fb279d8bSVesa Jääskeläinen 
233fb279d8bSVesa Jääskeläinen 	res = TEE_AllocateOperation(&processing->tee_op_handle,
234fb279d8bSVesa Jääskeläinen 				    algo, mode, size);
235fb279d8bSVesa Jääskeläinen 	if (res)
236fb279d8bSVesa Jääskeläinen 		EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32,
237fb279d8bSVesa Jääskeläinen 		     algo, mode, size);
238fb279d8bSVesa Jääskeläinen 
239fb279d8bSVesa Jääskeläinen 	if (res == TEE_ERROR_NOT_SUPPORTED)
240fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_MECHANISM_INVALID;
241fb279d8bSVesa Jääskeläinen 
242fb279d8bSVesa Jääskeläinen 	if (res != TEE_SUCCESS &&
243fb279d8bSVesa Jääskeläinen 	    processing->tee_hash_op_handle != TEE_HANDLE_NULL) {
244fb279d8bSVesa Jääskeläinen 		TEE_FreeOperation(session->processing->tee_hash_op_handle);
245fb279d8bSVesa Jääskeläinen 		processing->tee_hash_op_handle = TEE_HANDLE_NULL;
246fb279d8bSVesa Jääskeläinen 		processing->tee_hash_algo = 0;
247fb279d8bSVesa Jääskeläinen 	}
248fb279d8bSVesa Jääskeläinen 
249fb279d8bSVesa Jääskeläinen 	return tee2pkcs_error(res);
250fb279d8bSVesa Jääskeläinen }
251fb279d8bSVesa Jääskeläinen 
252fb279d8bSVesa Jääskeläinen static enum pkcs11_rc load_tee_key(struct pkcs11_session *session,
253fb279d8bSVesa Jääskeläinen 				   struct pkcs11_object *obj,
254fb279d8bSVesa Jääskeläinen 				   enum processing_func function)
255fb279d8bSVesa Jääskeläinen {
256fb279d8bSVesa Jääskeläinen 	TEE_Attribute *tee_attrs = NULL;
257fb279d8bSVesa Jääskeläinen 	size_t tee_attrs_count = 0;
258fb279d8bSVesa Jääskeläinen 	size_t object_size = 0;
259fb279d8bSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
260fb279d8bSVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
261fb279d8bSVesa Jääskeläinen 	enum pkcs11_class_id __maybe_unused class = get_class(obj->attributes);
262fb279d8bSVesa Jääskeläinen 	enum pkcs11_key_type type = get_key_type(obj->attributes);
263fb279d8bSVesa Jääskeläinen 
264fb279d8bSVesa Jääskeläinen 	assert(class == PKCS11_CKO_PUBLIC_KEY ||
265fb279d8bSVesa Jääskeläinen 	       class == PKCS11_CKO_PRIVATE_KEY);
266fb279d8bSVesa Jääskeläinen 
267fb279d8bSVesa Jääskeläinen 	if (obj->key_handle != TEE_HANDLE_NULL) {
268fb279d8bSVesa Jääskeläinen 		switch (type) {
2690442c956SVesa Jääskeläinen 		case PKCS11_CKK_RSA:
2700442c956SVesa Jääskeläinen 			/* RSA loaded keys can be reused */
2710442c956SVesa Jääskeläinen 			assert((obj->key_type == TEE_TYPE_RSA_PUBLIC_KEY &&
2720442c956SVesa Jääskeläinen 				class == PKCS11_CKO_PUBLIC_KEY) ||
2730442c956SVesa Jääskeläinen 			       (obj->key_type == TEE_TYPE_RSA_KEYPAIR &&
2740442c956SVesa Jääskeläinen 				class == PKCS11_CKO_PRIVATE_KEY));
2750442c956SVesa Jääskeläinen 			goto key_ready;
276fb279d8bSVesa Jääskeläinen 		case PKCS11_CKK_EC:
277fb279d8bSVesa Jääskeläinen 			/* Reuse EC TEE key only if already DSA or DH */
278fb279d8bSVesa Jääskeläinen 			switch (obj->key_type) {
279fb279d8bSVesa Jääskeläinen 			case TEE_TYPE_ECDSA_PUBLIC_KEY:
280fb279d8bSVesa Jääskeläinen 			case TEE_TYPE_ECDSA_KEYPAIR:
281fb279d8bSVesa Jääskeläinen 				if (function != PKCS11_FUNCTION_DERIVE)
282fb279d8bSVesa Jääskeläinen 					goto key_ready;
283fb279d8bSVesa Jääskeläinen 				break;
284*cc062b46SJorge Ramirez-Ortiz 			case TEE_TYPE_ECDH_PUBLIC_KEY:
285*cc062b46SJorge Ramirez-Ortiz 			case TEE_TYPE_ECDH_KEYPAIR:
286*cc062b46SJorge Ramirez-Ortiz 				if (function == PKCS11_FUNCTION_DERIVE)
287*cc062b46SJorge Ramirez-Ortiz 					goto key_ready;
288*cc062b46SJorge Ramirez-Ortiz 				break;
289fb279d8bSVesa Jääskeläinen 			default:
290fb279d8bSVesa Jääskeläinen 				assert(0);
291fb279d8bSVesa Jääskeläinen 				break;
292fb279d8bSVesa Jääskeläinen 			}
293fb279d8bSVesa Jääskeläinen 			break;
294fb279d8bSVesa Jääskeläinen 		default:
295fb279d8bSVesa Jääskeläinen 			assert(0);
296fb279d8bSVesa Jääskeläinen 			break;
297fb279d8bSVesa Jääskeläinen 		}
298fb279d8bSVesa Jääskeläinen 
299fb279d8bSVesa Jääskeläinen 		TEE_CloseObject(obj->key_handle);
300fb279d8bSVesa Jääskeläinen 		obj->key_handle = TEE_HANDLE_NULL;
301fb279d8bSVesa Jääskeläinen 	}
302fb279d8bSVesa Jääskeläinen 
303fb279d8bSVesa Jääskeläinen 	rc = pkcs2tee_key_type(&obj->key_type, obj, function);
304fb279d8bSVesa Jääskeläinen 	if (rc)
305fb279d8bSVesa Jääskeläinen 		return rc;
306fb279d8bSVesa Jääskeläinen 
307fb279d8bSVesa Jääskeläinen 	object_size = get_object_key_bit_size(obj);
308fb279d8bSVesa Jääskeläinen 	if (!object_size)
309fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_GENERAL_ERROR;
310fb279d8bSVesa Jääskeläinen 
311fb279d8bSVesa Jääskeläinen 	switch (type) {
3120442c956SVesa Jääskeläinen 	case PKCS11_CKK_RSA:
3130442c956SVesa Jääskeläinen 		rc = load_tee_rsa_key_attrs(&tee_attrs, &tee_attrs_count, obj);
3140442c956SVesa Jääskeläinen 		break;
315fb279d8bSVesa Jääskeläinen 	case PKCS11_CKK_EC:
316fb279d8bSVesa Jääskeläinen 		rc = load_tee_ec_key_attrs(&tee_attrs, &tee_attrs_count, obj);
317fb279d8bSVesa Jääskeläinen 		break;
318fb279d8bSVesa Jääskeläinen 	default:
319fb279d8bSVesa Jääskeläinen 		break;
320fb279d8bSVesa Jääskeläinen 	}
321fb279d8bSVesa Jääskeläinen 	if (rc)
322fb279d8bSVesa Jääskeläinen 		return rc;
323fb279d8bSVesa Jääskeläinen 
324fb279d8bSVesa Jääskeläinen 	res = TEE_AllocateTransientObject(obj->key_type, object_size,
325fb279d8bSVesa Jääskeläinen 					  &obj->key_handle);
326fb279d8bSVesa Jääskeläinen 	if (res) {
327fb279d8bSVesa Jääskeläinen 		DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res);
328fb279d8bSVesa Jääskeläinen 
329fb279d8bSVesa Jääskeläinen 		return tee2pkcs_error(res);
330fb279d8bSVesa Jääskeläinen 	}
331fb279d8bSVesa Jääskeläinen 
332fb279d8bSVesa Jääskeläinen 	res = TEE_PopulateTransientObject(obj->key_handle,
333fb279d8bSVesa Jääskeläinen 					  tee_attrs, tee_attrs_count);
334fb279d8bSVesa Jääskeläinen 
335fb279d8bSVesa Jääskeläinen 	TEE_Free(tee_attrs);
336fb279d8bSVesa Jääskeläinen 
337fb279d8bSVesa Jääskeläinen 	if (res) {
338fb279d8bSVesa Jääskeläinen 		DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res);
339fb279d8bSVesa Jääskeläinen 
340fb279d8bSVesa Jääskeläinen 		goto error;
341fb279d8bSVesa Jääskeläinen 	}
342fb279d8bSVesa Jääskeläinen 
343fb279d8bSVesa Jääskeläinen key_ready:
344fb279d8bSVesa Jääskeläinen 	res = TEE_SetOperationKey(session->processing->tee_op_handle,
345fb279d8bSVesa Jääskeläinen 				  obj->key_handle);
346fb279d8bSVesa Jääskeläinen 	if (res) {
347fb279d8bSVesa Jääskeläinen 		DMSG("TEE_SetOperationKey failed, %#"PRIx32, res);
348fb279d8bSVesa Jääskeläinen 
349fb279d8bSVesa Jääskeläinen 		goto error;
350fb279d8bSVesa Jääskeläinen 	}
351fb279d8bSVesa Jääskeläinen 
352fb279d8bSVesa Jääskeläinen 	return PKCS11_CKR_OK;
353fb279d8bSVesa Jääskeläinen 
354fb279d8bSVesa Jääskeläinen error:
355fb279d8bSVesa Jääskeläinen 	TEE_FreeTransientObject(obj->key_handle);
356fb279d8bSVesa Jääskeläinen 	obj->key_handle = TEE_HANDLE_NULL;
357fb279d8bSVesa Jääskeläinen 	return tee2pkcs_error(res);
358fb279d8bSVesa Jääskeläinen }
359fb279d8bSVesa Jääskeläinen 
360fb279d8bSVesa Jääskeläinen static enum pkcs11_rc
361d9af50bcSVesa Jääskeläinen init_tee_operation(struct pkcs11_session *session,
362d9af50bcSVesa Jääskeläinen 		   struct pkcs11_attribute_head *proc_params,
363d9af50bcSVesa Jääskeläinen 		   struct pkcs11_object *obj)
364fb279d8bSVesa Jääskeläinen {
365d9af50bcSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_OK;
366d9af50bcSVesa Jääskeläinen 	struct active_processing *proc = session->processing;
367d9af50bcSVesa Jääskeläinen 
368d9af50bcSVesa Jääskeläinen 	switch (proc_params->id) {
369d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_PSS:
370d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
371d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
372d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
373d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
374d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
375d9af50bcSVesa Jääskeläinen 		rc = pkcs2tee_proc_params_rsa_pss(proc, proc_params);
376d9af50bcSVesa Jääskeläinen 		if (rc)
377d9af50bcSVesa Jääskeläinen 			break;
378d9af50bcSVesa Jääskeläinen 
379d9af50bcSVesa Jääskeläinen 		rc = pkcs2tee_validate_rsa_pss(proc, obj);
380d9af50bcSVesa Jääskeläinen 		break;
381dc8c77fcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_OAEP:
382dc8c77fcSVesa Jääskeläinen 		rc = pkcs2tee_proc_params_rsa_oaep(proc, proc_params);
383dc8c77fcSVesa Jääskeläinen 		break;
384d9af50bcSVesa Jääskeläinen 	default:
385d9af50bcSVesa Jääskeläinen 		break;
386d9af50bcSVesa Jääskeläinen 	}
387d9af50bcSVesa Jääskeläinen 
388d9af50bcSVesa Jääskeläinen 	return rc;
389fb279d8bSVesa Jääskeläinen }
390fb279d8bSVesa Jääskeläinen 
391fb279d8bSVesa Jääskeläinen enum pkcs11_rc init_asymm_operation(struct pkcs11_session *session,
392fb279d8bSVesa Jääskeläinen 				    enum processing_func function,
393fb279d8bSVesa Jääskeläinen 				    struct pkcs11_attribute_head *proc_params,
394fb279d8bSVesa Jääskeläinen 				    struct pkcs11_object *obj)
395fb279d8bSVesa Jääskeläinen {
396fb279d8bSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
397fb279d8bSVesa Jääskeläinen 
398fb279d8bSVesa Jääskeläinen 	assert(processing_is_tee_asymm(proc_params->id));
399fb279d8bSVesa Jääskeläinen 
400fb279d8bSVesa Jääskeläinen 	rc = allocate_tee_operation(session, function, proc_params, obj);
401fb279d8bSVesa Jääskeläinen 	if (rc)
402fb279d8bSVesa Jääskeläinen 		return rc;
403fb279d8bSVesa Jääskeläinen 
404fb279d8bSVesa Jääskeläinen 	rc = load_tee_key(session, obj, function);
405fb279d8bSVesa Jääskeläinen 	if (rc)
406fb279d8bSVesa Jääskeläinen 		return rc;
407fb279d8bSVesa Jääskeläinen 
408d9af50bcSVesa Jääskeläinen 	return init_tee_operation(session, proc_params, obj);
409fb279d8bSVesa Jääskeläinen }
410fb279d8bSVesa Jääskeläinen 
411fb279d8bSVesa Jääskeläinen /*
412fb279d8bSVesa Jääskeläinen  * step_sym_step - step (update/oneshot/final) on a symmetric crypto operation
413fb279d8bSVesa Jääskeläinen  *
414fb279d8bSVesa Jääskeläinen  * @session - current session
415fb279d8bSVesa Jääskeläinen  * @function - processing function (encrypt, decrypt, sign, ...)
416fb279d8bSVesa Jääskeläinen  * @step - step ID in the processing (oneshot, update, final)
417fb279d8bSVesa Jääskeläinen  * @ptypes - invocation parameter types
418fb279d8bSVesa Jääskeläinen  * @params - invocation parameter references
419fb279d8bSVesa Jääskeläinen  */
420fb279d8bSVesa Jääskeläinen enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session,
421fb279d8bSVesa Jääskeläinen 				    enum processing_func function,
422fb279d8bSVesa Jääskeläinen 				    enum processing_step step,
423fb279d8bSVesa Jääskeläinen 				    uint32_t ptypes, TEE_Param *params)
424fb279d8bSVesa Jääskeläinen {
425fb279d8bSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
426fb279d8bSVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
427fb279d8bSVesa Jääskeläinen 	void *in_buf = NULL;
428fb279d8bSVesa Jääskeläinen 	void *in2_buf = NULL;
429fb279d8bSVesa Jääskeläinen 	void *out_buf = NULL;
430fb279d8bSVesa Jääskeläinen 	void *hash_buf = NULL;
431fb279d8bSVesa Jääskeläinen 	uint32_t in_size = 0;
432fb279d8bSVesa Jääskeläinen 	uint32_t in2_size = 0;
433fb279d8bSVesa Jääskeläinen 	uint32_t out_size = 0;
434fb279d8bSVesa Jääskeläinen 	uint32_t hash_size = 0;
435fb279d8bSVesa Jääskeläinen 	TEE_Attribute *tee_attrs = NULL;
436fb279d8bSVesa Jääskeläinen 	size_t tee_attrs_count = 0;
437fb279d8bSVesa Jääskeläinen 	bool output_data = false;
438fb279d8bSVesa Jääskeläinen 	struct active_processing *proc = session->processing;
439dc8c77fcSVesa Jääskeläinen 	struct rsa_oaep_processing_ctx *rsa_oaep_ctx = NULL;
440d9af50bcSVesa Jääskeläinen 	struct rsa_pss_processing_ctx *rsa_pss_ctx = NULL;
441fb279d8bSVesa Jääskeläinen 	size_t sz = 0;
442fb279d8bSVesa Jääskeläinen 
443fb279d8bSVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) {
444fb279d8bSVesa Jääskeläinen 		in_buf = params[1].memref.buffer;
445fb279d8bSVesa Jääskeläinen 		in_size = params[1].memref.size;
446fb279d8bSVesa Jääskeläinen 		if (in_size && !in_buf)
447fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
448fb279d8bSVesa Jääskeläinen 	}
449fb279d8bSVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) {
450fb279d8bSVesa Jääskeläinen 		in2_buf = params[2].memref.buffer;
451fb279d8bSVesa Jääskeläinen 		in2_size = params[2].memref.size;
452fb279d8bSVesa Jääskeläinen 		if (in2_size && !in2_buf)
453fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
454fb279d8bSVesa Jääskeläinen 	}
455fb279d8bSVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) {
456fb279d8bSVesa Jääskeläinen 		out_buf = params[2].memref.buffer;
457fb279d8bSVesa Jääskeläinen 		out_size = params[2].memref.size;
458fb279d8bSVesa Jääskeläinen 		if (out_size && !out_buf)
459fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
460fb279d8bSVesa Jääskeläinen 	}
461fb279d8bSVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE)
462fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_ARGUMENTS_BAD;
463fb279d8bSVesa Jääskeläinen 
464fb279d8bSVesa Jääskeläinen 	switch (step) {
465fb279d8bSVesa Jääskeläinen 	case PKCS11_FUNC_STEP_ONESHOT:
466fb279d8bSVesa Jääskeläinen 	case PKCS11_FUNC_STEP_UPDATE:
467fb279d8bSVesa Jääskeläinen 	case PKCS11_FUNC_STEP_FINAL:
468fb279d8bSVesa Jääskeläinen 		break;
469fb279d8bSVesa Jääskeläinen 	default:
470fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_GENERAL_ERROR;
471fb279d8bSVesa Jääskeläinen 	}
472fb279d8bSVesa Jääskeläinen 
473d9af50bcSVesa Jääskeläinen 	/* TEE attribute(s) required by the operation */
474d9af50bcSVesa Jääskeläinen 	switch (proc->mecha_type) {
475d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_PSS:
476d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
477d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
478d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
479d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
480d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
481d9af50bcSVesa Jääskeläinen 		tee_attrs = TEE_Malloc(sizeof(TEE_Attribute),
482d9af50bcSVesa Jääskeläinen 				       TEE_USER_MEM_HINT_NO_FILL_ZERO);
483d9af50bcSVesa Jääskeläinen 		if (!tee_attrs) {
484d9af50bcSVesa Jääskeläinen 			rc = PKCS11_CKR_DEVICE_MEMORY;
485d9af50bcSVesa Jääskeläinen 			goto out;
486d9af50bcSVesa Jääskeläinen 		}
487d9af50bcSVesa Jääskeläinen 
488d9af50bcSVesa Jääskeläinen 		rsa_pss_ctx = proc->extra_ctx;
489d9af50bcSVesa Jääskeläinen 
490d9af50bcSVesa Jääskeläinen 		TEE_InitValueAttribute(&tee_attrs[tee_attrs_count],
491d9af50bcSVesa Jääskeläinen 				       TEE_ATTR_RSA_PSS_SALT_LENGTH,
492d9af50bcSVesa Jääskeläinen 				       rsa_pss_ctx->salt_len, 0);
493d9af50bcSVesa Jääskeläinen 		tee_attrs_count++;
494d9af50bcSVesa Jääskeläinen 		break;
495dc8c77fcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_OAEP:
496dc8c77fcSVesa Jääskeläinen 		rsa_oaep_ctx = proc->extra_ctx;
497dc8c77fcSVesa Jääskeläinen 
498dc8c77fcSVesa Jääskeläinen 		if (!rsa_oaep_ctx->source_data_len)
499dc8c77fcSVesa Jääskeläinen 			break;
500dc8c77fcSVesa Jääskeläinen 
501dc8c77fcSVesa Jääskeläinen 		tee_attrs = TEE_Malloc(sizeof(TEE_Attribute),
502dc8c77fcSVesa Jääskeläinen 				       TEE_USER_MEM_HINT_NO_FILL_ZERO);
503dc8c77fcSVesa Jääskeläinen 		if (!tee_attrs) {
504dc8c77fcSVesa Jääskeläinen 			rc = PKCS11_CKR_DEVICE_MEMORY;
505dc8c77fcSVesa Jääskeläinen 			goto out;
506dc8c77fcSVesa Jääskeläinen 		}
507dc8c77fcSVesa Jääskeläinen 
508dc8c77fcSVesa Jääskeläinen 		TEE_InitRefAttribute(&tee_attrs[tee_attrs_count],
509dc8c77fcSVesa Jääskeläinen 				     TEE_ATTR_RSA_OAEP_LABEL,
510dc8c77fcSVesa Jääskeläinen 				     rsa_oaep_ctx->source_data,
511dc8c77fcSVesa Jääskeläinen 				     rsa_oaep_ctx->source_data_len);
512dc8c77fcSVesa Jääskeläinen 		tee_attrs_count++;
513dc8c77fcSVesa Jääskeläinen 		break;
514d9af50bcSVesa Jääskeläinen 	default:
515d9af50bcSVesa Jääskeläinen 		break;
516d9af50bcSVesa Jääskeläinen 	}
517d9af50bcSVesa Jääskeläinen 
518fb279d8bSVesa Jääskeläinen 	/*
519fb279d8bSVesa Jääskeläinen 	 * Handle multi stage update step for mechas needing hash
520fb279d8bSVesa Jääskeläinen 	 * calculation
521fb279d8bSVesa Jääskeläinen 	 */
522fb279d8bSVesa Jääskeläinen 	if (step == PKCS11_FUNC_STEP_UPDATE) {
523fb279d8bSVesa Jääskeläinen 		switch (proc->mecha_type) {
524fb279d8bSVesa Jääskeläinen 		case PKCS11_CKM_ECDSA_SHA1:
525fb279d8bSVesa Jääskeläinen 		case PKCS11_CKM_ECDSA_SHA224:
526fb279d8bSVesa Jääskeläinen 		case PKCS11_CKM_ECDSA_SHA256:
527fb279d8bSVesa Jääskeläinen 		case PKCS11_CKM_ECDSA_SHA384:
528fb279d8bSVesa Jääskeläinen 		case PKCS11_CKM_ECDSA_SHA512:
5290442c956SVesa Jääskeläinen 		case PKCS11_CKM_MD5_RSA_PKCS:
5300442c956SVesa Jääskeläinen 		case PKCS11_CKM_SHA1_RSA_PKCS:
5310442c956SVesa Jääskeläinen 		case PKCS11_CKM_SHA224_RSA_PKCS:
5320442c956SVesa Jääskeläinen 		case PKCS11_CKM_SHA256_RSA_PKCS:
5330442c956SVesa Jääskeläinen 		case PKCS11_CKM_SHA384_RSA_PKCS:
5340442c956SVesa Jääskeläinen 		case PKCS11_CKM_SHA512_RSA_PKCS:
535d9af50bcSVesa Jääskeläinen 		case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
536d9af50bcSVesa Jääskeläinen 		case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
537d9af50bcSVesa Jääskeläinen 		case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
538d9af50bcSVesa Jääskeläinen 		case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
539d9af50bcSVesa Jääskeläinen 		case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
540fb279d8bSVesa Jääskeläinen 			assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL);
541fb279d8bSVesa Jääskeläinen 
542fb279d8bSVesa Jääskeläinen 			TEE_DigestUpdate(proc->tee_hash_op_handle, in_buf,
543fb279d8bSVesa Jääskeläinen 					 in_size);
5449df68186SEtienne Carriere 			rc = PKCS11_CKR_OK;
545fb279d8bSVesa Jääskeläinen 			break;
546fb279d8bSVesa Jääskeläinen 		default:
547fb279d8bSVesa Jääskeläinen 			/*
548fb279d8bSVesa Jääskeläinen 			 * Other mechanism do not expect multi stage
549fb279d8bSVesa Jääskeläinen 			 * operation
550fb279d8bSVesa Jääskeläinen 			 */
551fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_GENERAL_ERROR;
552fb279d8bSVesa Jääskeläinen 			break;
553fb279d8bSVesa Jääskeläinen 		}
554fb279d8bSVesa Jääskeläinen 
555fb279d8bSVesa Jääskeläinen 		goto out;
556fb279d8bSVesa Jääskeläinen 	}
557fb279d8bSVesa Jääskeläinen 
558fb279d8bSVesa Jääskeläinen 	/*
559fb279d8bSVesa Jääskeläinen 	 * Handle multi stage one shot and final steps for mechas needing hash
560fb279d8bSVesa Jääskeläinen 	 * calculation
561fb279d8bSVesa Jääskeläinen 	 */
562fb279d8bSVesa Jääskeläinen 	switch (proc->mecha_type) {
563fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
564fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
565fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
566fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
567fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
5680442c956SVesa Jääskeläinen 	case PKCS11_CKM_MD5_RSA_PKCS:
5690442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS:
5700442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS:
5710442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS:
5720442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS:
5730442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS:
574d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
575d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
576d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
577d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
578d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
579fb279d8bSVesa Jääskeläinen 		assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL);
580fb279d8bSVesa Jääskeläinen 
581fb279d8bSVesa Jääskeläinen 		hash_size = TEE_ALG_GET_DIGEST_SIZE(proc->tee_hash_algo);
582fb279d8bSVesa Jääskeläinen 		hash_buf = TEE_Malloc(hash_size, 0);
583fb279d8bSVesa Jääskeläinen 		if (!hash_buf)
584fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
585fb279d8bSVesa Jääskeläinen 
586fb279d8bSVesa Jääskeläinen 		res = TEE_DigestDoFinal(proc->tee_hash_op_handle,
587fb279d8bSVesa Jääskeläinen 					in_buf, in_size, hash_buf,
588fb279d8bSVesa Jääskeläinen 					&hash_size);
589fb279d8bSVesa Jääskeläinen 
590fb279d8bSVesa Jääskeläinen 		rc = tee2pkcs_error(res);
591fb279d8bSVesa Jääskeläinen 		if (rc != PKCS11_CKR_OK)
592fb279d8bSVesa Jääskeläinen 			goto out;
593fb279d8bSVesa Jääskeläinen 
594fb279d8bSVesa Jääskeläinen 		break;
595fb279d8bSVesa Jääskeläinen 	default:
596fb279d8bSVesa Jääskeläinen 		break;
597fb279d8bSVesa Jääskeläinen 	}
598fb279d8bSVesa Jääskeläinen 
599fb279d8bSVesa Jääskeläinen 	/*
600fb279d8bSVesa Jääskeläinen 	 * Finalize either provided hash or calculated hash with signing
601fb279d8bSVesa Jääskeläinen 	 * operation
602fb279d8bSVesa Jääskeläinen 	 */
603fb279d8bSVesa Jääskeläinen 
604fb279d8bSVesa Jääskeläinen 	/* First determine amount of bytes for signing operation */
605fb279d8bSVesa Jääskeläinen 	switch (proc->mecha_type) {
606fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA:
607fb279d8bSVesa Jääskeläinen 		sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle);
608fb279d8bSVesa Jääskeläinen 		if (!in_size || !sz) {
609fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_FUNCTION_FAILED;
610fb279d8bSVesa Jääskeläinen 			goto out;
611fb279d8bSVesa Jääskeläinen 		}
612fb279d8bSVesa Jääskeläinen 
613fb279d8bSVesa Jääskeläinen 		/*
614fb279d8bSVesa Jääskeläinen 		 * Note 3) Input the entire raw digest. Internally, this will
615fb279d8bSVesa Jääskeläinen 		 * be truncated to the appropriate number of bits.
616fb279d8bSVesa Jääskeläinen 		 */
617fb279d8bSVesa Jääskeläinen 		if (in_size > sz)
618fb279d8bSVesa Jääskeläinen 			in_size = sz;
619fb279d8bSVesa Jääskeläinen 
620fb279d8bSVesa Jääskeläinen 		if (function == PKCS11_FUNCTION_VERIFY && in2_size != 2 * sz) {
621fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_SIGNATURE_LEN_RANGE;
622fb279d8bSVesa Jääskeläinen 			goto out;
623fb279d8bSVesa Jääskeläinen 		}
624fb279d8bSVesa Jääskeläinen 		break;
625fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
626fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
627fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
628fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
629fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
630fb279d8bSVesa Jääskeläinen 		/* Get key size in bytes */
631fb279d8bSVesa Jääskeläinen 		sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle);
632fb279d8bSVesa Jääskeläinen 		if (!sz) {
633fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_FUNCTION_FAILED;
634fb279d8bSVesa Jääskeläinen 			goto out;
635fb279d8bSVesa Jääskeläinen 		}
636fb279d8bSVesa Jääskeläinen 
637fb279d8bSVesa Jääskeläinen 		if (function == PKCS11_FUNCTION_VERIFY &&
638fb279d8bSVesa Jääskeläinen 		    in2_size != 2 * sz) {
639fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_SIGNATURE_LEN_RANGE;
640fb279d8bSVesa Jääskeläinen 			goto out;
641fb279d8bSVesa Jääskeläinen 		}
642fb279d8bSVesa Jääskeläinen 		break;
6430442c956SVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS:
6440442c956SVesa Jääskeläinen 	case PKCS11_CKM_MD5_RSA_PKCS:
6450442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS:
6460442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS:
6470442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS:
6480442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS:
6490442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS:
650d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_PSS:
651d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
652d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
653d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
654d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
655d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
6560442c956SVesa Jääskeläinen 		/* Get key size in bytes */
6570442c956SVesa Jääskeläinen 		sz = rsa_get_input_max_byte_size(proc->tee_op_handle);
6580442c956SVesa Jääskeläinen 		if (!sz) {
6590442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_FUNCTION_FAILED;
6600442c956SVesa Jääskeläinen 			goto out;
6610442c956SVesa Jääskeläinen 		}
6620442c956SVesa Jääskeläinen 
6630442c956SVesa Jääskeläinen 		if (function == PKCS11_FUNCTION_VERIFY && in2_size != sz) {
6640442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_SIGNATURE_LEN_RANGE;
6650442c956SVesa Jääskeläinen 			goto out;
6660442c956SVesa Jääskeläinen 		}
6670442c956SVesa Jääskeläinen 		break;
668fb279d8bSVesa Jääskeläinen 	default:
669fb279d8bSVesa Jääskeläinen 		break;
670fb279d8bSVesa Jääskeläinen 	}
671fb279d8bSVesa Jääskeläinen 
672fb279d8bSVesa Jääskeläinen 	/* Next perform actual signing operation */
673fb279d8bSVesa Jääskeläinen 	switch (proc->mecha_type) {
674fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA:
6750442c956SVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS:
676dc8c77fcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_OAEP:
677d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_PSS:
678fb279d8bSVesa Jääskeläinen 		/* For operations using provided input data */
679fb279d8bSVesa Jääskeläinen 		switch (function) {
680fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_ENCRYPT:
681fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricEncrypt(proc->tee_op_handle,
682fb279d8bSVesa Jääskeläinen 						    tee_attrs, tee_attrs_count,
683fb279d8bSVesa Jääskeläinen 						    in_buf, in_size,
684fb279d8bSVesa Jääskeläinen 						    out_buf, &out_size);
685fb279d8bSVesa Jääskeläinen 			output_data = true;
686fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
6876a6299fbSVesa Jääskeläinen 			if (rc == PKCS11_CKR_ARGUMENTS_BAD)
6886a6299fbSVesa Jääskeläinen 				rc = PKCS11_CKR_DATA_LEN_RANGE;
689fb279d8bSVesa Jääskeläinen 			break;
690fb279d8bSVesa Jääskeläinen 
691fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_DECRYPT:
692fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricDecrypt(proc->tee_op_handle,
693fb279d8bSVesa Jääskeläinen 						    tee_attrs, tee_attrs_count,
694fb279d8bSVesa Jääskeläinen 						    in_buf, in_size,
695fb279d8bSVesa Jääskeläinen 						    out_buf, &out_size);
696fb279d8bSVesa Jääskeläinen 			output_data = true;
697fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
698f27310a5SVesa Jääskeläinen 			if (rc == PKCS11_CKR_ARGUMENTS_BAD)
699f27310a5SVesa Jääskeläinen 				rc = PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
700fb279d8bSVesa Jääskeläinen 			break;
701fb279d8bSVesa Jääskeläinen 
702fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_SIGN:
703fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricSignDigest(proc->tee_op_handle,
704fb279d8bSVesa Jääskeläinen 						       tee_attrs,
705fb279d8bSVesa Jääskeläinen 						       tee_attrs_count,
706fb279d8bSVesa Jääskeläinen 						       in_buf, in_size,
707fb279d8bSVesa Jääskeläinen 						       out_buf, &out_size);
708fb279d8bSVesa Jääskeläinen 			output_data = true;
709fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
710fb279d8bSVesa Jääskeläinen 			break;
711fb279d8bSVesa Jääskeläinen 
712fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_VERIFY:
713fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle,
714fb279d8bSVesa Jääskeläinen 							 tee_attrs,
715fb279d8bSVesa Jääskeläinen 							 tee_attrs_count,
716fb279d8bSVesa Jääskeläinen 							 in_buf, in_size,
717fb279d8bSVesa Jääskeläinen 							 in2_buf, in2_size);
718fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
719fb279d8bSVesa Jääskeläinen 			break;
720fb279d8bSVesa Jääskeläinen 
721fb279d8bSVesa Jääskeläinen 		default:
722fb279d8bSVesa Jääskeläinen 			TEE_Panic(function);
723fb279d8bSVesa Jääskeläinen 			break;
724fb279d8bSVesa Jääskeläinen 		}
725fb279d8bSVesa Jääskeläinen 		break;
726fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
727fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
728fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
729fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
730fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
7310442c956SVesa Jääskeläinen 	case PKCS11_CKM_MD5_RSA_PKCS:
7320442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS:
7330442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS:
7340442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS:
7350442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS:
7360442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS:
737d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
738d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
739d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
740d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
741d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
742fb279d8bSVesa Jääskeläinen 		/* For operations having hash operation use calculated hash */
743fb279d8bSVesa Jääskeläinen 		switch (function) {
744fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_SIGN:
745fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricSignDigest(proc->tee_op_handle,
746fb279d8bSVesa Jääskeläinen 						       tee_attrs,
747fb279d8bSVesa Jääskeläinen 						       tee_attrs_count,
748fb279d8bSVesa Jääskeläinen 						       hash_buf, hash_size,
749fb279d8bSVesa Jääskeläinen 						       out_buf, &out_size);
750fb279d8bSVesa Jääskeläinen 			output_data = true;
751fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
752fb279d8bSVesa Jääskeläinen 			break;
753fb279d8bSVesa Jääskeläinen 
754fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_VERIFY:
755fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle,
756fb279d8bSVesa Jääskeläinen 							 tee_attrs,
757fb279d8bSVesa Jääskeläinen 							 tee_attrs_count,
758fb279d8bSVesa Jääskeläinen 							 hash_buf, hash_size,
759fb279d8bSVesa Jääskeläinen 							 in2_buf, in2_size);
760fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
761fb279d8bSVesa Jääskeläinen 			break;
762fb279d8bSVesa Jääskeläinen 
763fb279d8bSVesa Jääskeläinen 		default:
764fb279d8bSVesa Jääskeläinen 			TEE_Panic(function);
765fb279d8bSVesa Jääskeläinen 			break;
766fb279d8bSVesa Jääskeläinen 		}
767fb279d8bSVesa Jääskeläinen 		break;
768fb279d8bSVesa Jääskeläinen 	default:
769fb279d8bSVesa Jääskeläinen 		TEE_Panic(proc->mecha_type);
770fb279d8bSVesa Jääskeläinen 		break;
771fb279d8bSVesa Jääskeläinen 	}
772fb279d8bSVesa Jääskeläinen 
773fb279d8bSVesa Jääskeläinen out:
774fb279d8bSVesa Jääskeläinen 	if (output_data &&
775fb279d8bSVesa Jääskeläinen 	    (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) {
776fb279d8bSVesa Jääskeläinen 		switch (TEE_PARAM_TYPE_GET(ptypes, 2)) {
777fb279d8bSVesa Jääskeläinen 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
778fb279d8bSVesa Jääskeläinen 		case TEE_PARAM_TYPE_MEMREF_INOUT:
779fb279d8bSVesa Jääskeläinen 			params[2].memref.size = out_size;
780fb279d8bSVesa Jääskeläinen 			break;
781fb279d8bSVesa Jääskeläinen 		default:
782fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_GENERAL_ERROR;
783fb279d8bSVesa Jääskeläinen 			break;
784fb279d8bSVesa Jääskeläinen 		}
785fb279d8bSVesa Jääskeläinen 	}
786fb279d8bSVesa Jääskeläinen 
787fb279d8bSVesa Jääskeläinen 	TEE_Free(hash_buf);
788fb279d8bSVesa Jääskeläinen 	TEE_Free(tee_attrs);
789fb279d8bSVesa Jääskeläinen 
790fb279d8bSVesa Jääskeläinen 	return rc;
791fb279d8bSVesa Jääskeläinen }
792*cc062b46SJorge Ramirez-Ortiz 
793*cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc do_asymm_derivation(struct pkcs11_session *session,
794*cc062b46SJorge Ramirez-Ortiz 				   struct pkcs11_attribute_head *proc_params,
795*cc062b46SJorge Ramirez-Ortiz 				   struct obj_attrs **head)
796*cc062b46SJorge Ramirez-Ortiz {
797*cc062b46SJorge Ramirez-Ortiz 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
798*cc062b46SJorge Ramirez-Ortiz 	TEE_ObjectHandle out_handle = TEE_HANDLE_NULL;
799*cc062b46SJorge Ramirez-Ortiz 	TEE_Result res = TEE_ERROR_GENERIC;
800*cc062b46SJorge Ramirez-Ortiz 	TEE_Attribute tee_attrs[2] = { };
801*cc062b46SJorge Ramirez-Ortiz 	size_t tee_attrs_count = 0;
802*cc062b46SJorge Ramirez-Ortiz 	uint32_t key_byte_size = 0;
803*cc062b46SJorge Ramirez-Ortiz 	uint32_t key_bit_size = 0;
804*cc062b46SJorge Ramirez-Ortiz 	void *a_ptr = NULL;
805*cc062b46SJorge Ramirez-Ortiz 	size_t a_size = 0;
806*cc062b46SJorge Ramirez-Ortiz 
807*cc062b46SJorge Ramirez-Ortiz 	/* Remove default attribute set at template sanitization */
808*cc062b46SJorge Ramirez-Ortiz 	if (remove_empty_attribute(head, PKCS11_CKA_VALUE))
809*cc062b46SJorge Ramirez-Ortiz 		return PKCS11_CKR_FUNCTION_FAILED;
810*cc062b46SJorge Ramirez-Ortiz 
811*cc062b46SJorge Ramirez-Ortiz 	rc = get_u32_attribute(*head, PKCS11_CKA_VALUE_LEN, &key_bit_size);
812*cc062b46SJorge Ramirez-Ortiz 	if (rc)
813*cc062b46SJorge Ramirez-Ortiz 		return rc;
814*cc062b46SJorge Ramirez-Ortiz 
815*cc062b46SJorge Ramirez-Ortiz 	key_bit_size *= 8;
816*cc062b46SJorge Ramirez-Ortiz 	key_byte_size = (key_bit_size + 7) / 8;
817*cc062b46SJorge Ramirez-Ortiz 
818*cc062b46SJorge Ramirez-Ortiz 	res = TEE_AllocateTransientObject(TEE_TYPE_GENERIC_SECRET,
819*cc062b46SJorge Ramirez-Ortiz 					  key_byte_size * 8, &out_handle);
820*cc062b46SJorge Ramirez-Ortiz 	if (res) {
821*cc062b46SJorge Ramirez-Ortiz 		DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res);
822*cc062b46SJorge Ramirez-Ortiz 		return tee2pkcs_error(res);
823*cc062b46SJorge Ramirez-Ortiz 	}
824*cc062b46SJorge Ramirez-Ortiz 
825*cc062b46SJorge Ramirez-Ortiz 	switch (proc_params->id) {
826*cc062b46SJorge Ramirez-Ortiz 	case PKCS11_CKM_ECDH1_DERIVE:
827*cc062b46SJorge Ramirez-Ortiz 		rc = pkcs2tee_param_ecdh(proc_params, &a_ptr, &a_size);
828*cc062b46SJorge Ramirez-Ortiz 		if (rc)
829*cc062b46SJorge Ramirez-Ortiz 			goto out;
830*cc062b46SJorge Ramirez-Ortiz 
831*cc062b46SJorge Ramirez-Ortiz 		TEE_InitRefAttribute(&tee_attrs[tee_attrs_count],
832*cc062b46SJorge Ramirez-Ortiz 				     TEE_ATTR_ECC_PUBLIC_VALUE_X,
833*cc062b46SJorge Ramirez-Ortiz 				     a_ptr, a_size / 2);
834*cc062b46SJorge Ramirez-Ortiz 		tee_attrs_count++;
835*cc062b46SJorge Ramirez-Ortiz 		TEE_InitRefAttribute(&tee_attrs[tee_attrs_count],
836*cc062b46SJorge Ramirez-Ortiz 				     TEE_ATTR_ECC_PUBLIC_VALUE_Y,
837*cc062b46SJorge Ramirez-Ortiz 				     (char *)a_ptr + a_size / 2,
838*cc062b46SJorge Ramirez-Ortiz 				     a_size / 2);
839*cc062b46SJorge Ramirez-Ortiz 		tee_attrs_count++;
840*cc062b46SJorge Ramirez-Ortiz 		break;
841*cc062b46SJorge Ramirez-Ortiz 	default:
842*cc062b46SJorge Ramirez-Ortiz 		TEE_Panic(proc_params->id);
843*cc062b46SJorge Ramirez-Ortiz 		break;
844*cc062b46SJorge Ramirez-Ortiz 	}
845*cc062b46SJorge Ramirez-Ortiz 
846*cc062b46SJorge Ramirez-Ortiz 	TEE_DeriveKey(session->processing->tee_op_handle, &tee_attrs[0],
847*cc062b46SJorge Ramirez-Ortiz 		      tee_attrs_count, out_handle);
848*cc062b46SJorge Ramirez-Ortiz 
849*cc062b46SJorge Ramirez-Ortiz 	rc = alloc_get_tee_attribute_data(out_handle, TEE_ATTR_SECRET_VALUE,
850*cc062b46SJorge Ramirez-Ortiz 					  &a_ptr, &a_size);
851*cc062b46SJorge Ramirez-Ortiz 	if (rc)
852*cc062b46SJorge Ramirez-Ortiz 		goto out;
853*cc062b46SJorge Ramirez-Ortiz 
854*cc062b46SJorge Ramirez-Ortiz 	if (a_size * 8 < key_bit_size)
855*cc062b46SJorge Ramirez-Ortiz 		rc = PKCS11_CKR_KEY_SIZE_RANGE;
856*cc062b46SJorge Ramirez-Ortiz 	else
857*cc062b46SJorge Ramirez-Ortiz 		rc = add_attribute(head, PKCS11_CKA_VALUE, a_ptr,
858*cc062b46SJorge Ramirez-Ortiz 				   key_byte_size);
859*cc062b46SJorge Ramirez-Ortiz 	TEE_Free(a_ptr);
860*cc062b46SJorge Ramirez-Ortiz out:
861*cc062b46SJorge Ramirez-Ortiz 	release_active_processing(session);
862*cc062b46SJorge Ramirez-Ortiz 	TEE_FreeTransientObject(out_handle);
863*cc062b46SJorge Ramirez-Ortiz 
864*cc062b46SJorge Ramirez-Ortiz 	return rc;
865*cc062b46SJorge Ramirez-Ortiz }
866