xref: /optee_os/ta/pkcs11/src/processing_asymm.c (revision 0442c956edfb70be378634fd51dbec6e21550a5a)
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) {
21*0442c956SVesa Jääskeläinen 	/* RSA flavors */
22*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS:
23*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_MD5_RSA_PKCS:
24*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS:
25*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS:
26*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS:
27*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS:
28*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS:
29fb279d8bSVesa Jääskeläinen 	/* EC flavors */
30fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA:
31fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
32fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
33fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
34fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
35fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
36fb279d8bSVesa Jääskeläinen 		return true;
37fb279d8bSVesa Jääskeläinen 	default:
38fb279d8bSVesa Jääskeläinen 		return false;
39fb279d8bSVesa Jääskeläinen 	}
40fb279d8bSVesa Jääskeläinen }
41fb279d8bSVesa Jääskeläinen 
42fb279d8bSVesa Jääskeläinen static enum pkcs11_rc
43fb279d8bSVesa Jääskeläinen pkcs2tee_algorithm(uint32_t *tee_id, uint32_t *tee_hash_id,
44fb279d8bSVesa Jääskeläinen 		   enum processing_func function __unused,
45fb279d8bSVesa Jääskeläinen 		   struct pkcs11_attribute_head *proc_params,
46fb279d8bSVesa Jääskeläinen 		   struct pkcs11_object *obj)
47fb279d8bSVesa Jääskeläinen {
48fb279d8bSVesa Jääskeläinen 	static const struct {
49fb279d8bSVesa Jääskeläinen 		enum pkcs11_mechanism_id mech_id;
50fb279d8bSVesa Jääskeläinen 		uint32_t tee_id;
51fb279d8bSVesa Jääskeläinen 		uint32_t tee_hash_id;
52fb279d8bSVesa Jääskeläinen 	} pkcs2tee_algo[] = {
53*0442c956SVesa Jääskeläinen 		/* RSA flavors */
54*0442c956SVesa Jääskeläinen 		{ PKCS11_CKM_RSA_PKCS, TEE_ALG_RSAES_PKCS1_V1_5, 0 },
55*0442c956SVesa Jääskeläinen 		{ PKCS11_CKM_MD5_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_MD5,
56*0442c956SVesa Jääskeläinen 		  TEE_ALG_MD5 },
57*0442c956SVesa Jääskeläinen 		{ PKCS11_CKM_SHA1_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA1,
58*0442c956SVesa Jääskeläinen 		  TEE_ALG_SHA1 },
59*0442c956SVesa Jääskeläinen 		{ PKCS11_CKM_SHA224_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA224,
60*0442c956SVesa Jääskeläinen 		  TEE_ALG_SHA224 },
61*0442c956SVesa Jääskeläinen 		{ PKCS11_CKM_SHA256_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA256,
62*0442c956SVesa Jääskeläinen 		  TEE_ALG_SHA256 },
63*0442c956SVesa Jääskeläinen 		{ PKCS11_CKM_SHA384_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA384,
64*0442c956SVesa Jääskeläinen 		  TEE_ALG_SHA384 },
65*0442c956SVesa Jääskeläinen 		{ PKCS11_CKM_SHA512_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA512,
66*0442c956SVesa Jääskeläinen 		  TEE_ALG_SHA512 },
67fb279d8bSVesa Jääskeläinen 		/* EC flavors (Must find key size from the object) */
68fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA, 1, 0 },
69fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA_SHA1, 1, TEE_ALG_SHA1 },
70fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA_SHA224, 1, TEE_ALG_SHA224 },
71fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA_SHA256, 1, TEE_ALG_SHA256 },
72fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA_SHA384, 1, TEE_ALG_SHA384 },
73fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA_SHA512, 1, TEE_ALG_SHA512 },
74fb279d8bSVesa Jääskeläinen 	};
75fb279d8bSVesa Jääskeläinen 	size_t n = 0;
76fb279d8bSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
77fb279d8bSVesa Jääskeläinen 
78fb279d8bSVesa Jääskeläinen 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) {
79fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_algo[n].mech_id == proc_params->id) {
80fb279d8bSVesa Jääskeläinen 			*tee_id = pkcs2tee_algo[n].tee_id;
81fb279d8bSVesa Jääskeläinen 			*tee_hash_id = pkcs2tee_algo[n].tee_hash_id;
82fb279d8bSVesa Jääskeläinen 			break;
83fb279d8bSVesa Jääskeläinen 		}
84fb279d8bSVesa Jääskeläinen 	}
85fb279d8bSVesa Jääskeläinen 
86fb279d8bSVesa Jääskeläinen 	if (n == ARRAY_SIZE(pkcs2tee_algo))
87fb279d8bSVesa Jääskeläinen 		return PKCS11_RV_NOT_IMPLEMENTED;
88fb279d8bSVesa Jääskeläinen 
89fb279d8bSVesa Jääskeläinen 	switch (proc_params->id) {
90fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA:
91fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
92fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
93fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
94fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
95fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
96fb279d8bSVesa Jääskeläinen 		rc = pkcs2tee_algo_ecdsa(tee_id, proc_params, obj);
97fb279d8bSVesa Jääskeläinen 		break;
98fb279d8bSVesa Jääskeläinen 	default:
99fb279d8bSVesa Jääskeläinen 		rc = PKCS11_CKR_OK;
100fb279d8bSVesa Jääskeläinen 		break;
101fb279d8bSVesa Jääskeläinen 	}
102fb279d8bSVesa Jääskeläinen 
103*0442c956SVesa Jääskeläinen 	/*
104*0442c956SVesa Jääskeläinen 	 * PKCS#11 uses single mechanism CKM_RSA_PKCS for both ciphering and
105*0442c956SVesa Jääskeläinen 	 * authentication whereas GPD TEE expects TEE_ALG_RSAES_PKCS1_V1_5 for
106*0442c956SVesa Jääskeläinen 	 * ciphering and TEE_ALG_RSASSA_PKCS1_V1_5 for authentication.
107*0442c956SVesa Jääskeläinen 	 */
108*0442c956SVesa Jääskeläinen 	if (*tee_id == TEE_ALG_RSAES_PKCS1_V1_5 &&
109*0442c956SVesa Jääskeläinen 	    (function == PKCS11_FUNCTION_SIGN ||
110*0442c956SVesa Jääskeläinen 	     function == PKCS11_FUNCTION_VERIFY))
111*0442c956SVesa Jääskeläinen 		*tee_id = TEE_ALG_RSASSA_PKCS1_V1_5;
112*0442c956SVesa Jääskeläinen 
113fb279d8bSVesa Jääskeläinen 	return rc;
114fb279d8bSVesa Jääskeläinen }
115fb279d8bSVesa Jääskeläinen 
116fb279d8bSVesa Jääskeläinen static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type,
117fb279d8bSVesa Jääskeläinen 					struct pkcs11_object *obj,
118fb279d8bSVesa Jääskeläinen 					enum processing_func function)
119fb279d8bSVesa Jääskeläinen {
120fb279d8bSVesa Jääskeläinen 	enum pkcs11_class_id class = get_class(obj->attributes);
121fb279d8bSVesa Jääskeläinen 	enum pkcs11_key_type type = get_key_type(obj->attributes);
122fb279d8bSVesa Jääskeläinen 
123fb279d8bSVesa Jääskeläinen 	switch (class) {
124fb279d8bSVesa Jääskeläinen 	case PKCS11_CKO_PUBLIC_KEY:
125fb279d8bSVesa Jääskeläinen 	case PKCS11_CKO_PRIVATE_KEY:
126fb279d8bSVesa Jääskeläinen 		break;
127fb279d8bSVesa Jääskeläinen 	default:
128fb279d8bSVesa Jääskeläinen 		TEE_Panic(class);
129fb279d8bSVesa Jääskeläinen 		break;
130fb279d8bSVesa Jääskeläinen 	}
131fb279d8bSVesa Jääskeläinen 
132fb279d8bSVesa Jääskeläinen 	switch (type) {
133fb279d8bSVesa Jääskeläinen 	case PKCS11_CKK_EC:
134fb279d8bSVesa Jääskeläinen 		assert(function != PKCS11_FUNCTION_DERIVE);
135fb279d8bSVesa Jääskeläinen 
136fb279d8bSVesa Jääskeläinen 		if (class == PKCS11_CKO_PRIVATE_KEY)
137fb279d8bSVesa Jääskeläinen 			*tee_type = TEE_TYPE_ECDSA_KEYPAIR;
138fb279d8bSVesa Jääskeläinen 		else
139fb279d8bSVesa Jääskeläinen 			*tee_type = TEE_TYPE_ECDSA_PUBLIC_KEY;
140fb279d8bSVesa Jääskeläinen 		break;
141*0442c956SVesa Jääskeläinen 	case PKCS11_CKK_RSA:
142*0442c956SVesa Jääskeläinen 		if (class == PKCS11_CKO_PRIVATE_KEY)
143*0442c956SVesa Jääskeläinen 			*tee_type = TEE_TYPE_RSA_KEYPAIR;
144*0442c956SVesa Jääskeläinen 		else
145*0442c956SVesa Jääskeläinen 			*tee_type = TEE_TYPE_RSA_PUBLIC_KEY;
146*0442c956SVesa Jääskeläinen 		break;
147fb279d8bSVesa Jääskeläinen 	default:
148fb279d8bSVesa Jääskeläinen 		TEE_Panic(type);
149fb279d8bSVesa Jääskeläinen 		break;
150fb279d8bSVesa Jääskeläinen 	}
151fb279d8bSVesa Jääskeläinen 
152fb279d8bSVesa Jääskeläinen 	return PKCS11_CKR_OK;
153fb279d8bSVesa Jääskeläinen }
154fb279d8bSVesa Jääskeläinen 
155fb279d8bSVesa Jääskeläinen static enum pkcs11_rc
156fb279d8bSVesa Jääskeläinen allocate_tee_operation(struct pkcs11_session *session,
157fb279d8bSVesa Jääskeläinen 		       enum processing_func function,
158fb279d8bSVesa Jääskeläinen 		       struct pkcs11_attribute_head *params,
159fb279d8bSVesa Jääskeläinen 		       struct pkcs11_object *obj)
160fb279d8bSVesa Jääskeläinen {
161fb279d8bSVesa Jääskeläinen 	uint32_t size = (uint32_t)get_object_key_bit_size(obj);
162fb279d8bSVesa Jääskeläinen 	uint32_t algo = 0;
163fb279d8bSVesa Jääskeläinen 	uint32_t hash_algo = 0;
164fb279d8bSVesa Jääskeläinen 	uint32_t mode = 0;
165fb279d8bSVesa Jääskeläinen 	uint32_t hash_mode = 0;
166fb279d8bSVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
167fb279d8bSVesa Jääskeläinen 	struct active_processing *processing = session->processing;
168fb279d8bSVesa Jääskeläinen 
169fb279d8bSVesa Jääskeläinen 	assert(processing->tee_op_handle == TEE_HANDLE_NULL);
170fb279d8bSVesa Jääskeläinen 	assert(processing->tee_hash_op_handle == TEE_HANDLE_NULL);
171fb279d8bSVesa Jääskeläinen 
172fb279d8bSVesa Jääskeläinen 	if (pkcs2tee_algorithm(&algo, &hash_algo, function, params, obj))
173fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_FUNCTION_FAILED;
174fb279d8bSVesa Jääskeläinen 
175fb279d8bSVesa Jääskeläinen 	pkcs2tee_mode(&mode, function);
176fb279d8bSVesa Jääskeläinen 
177fb279d8bSVesa Jääskeläinen 	if (hash_algo) {
178fb279d8bSVesa Jääskeläinen 		pkcs2tee_mode(&hash_mode, PKCS11_FUNCTION_DIGEST);
179fb279d8bSVesa Jääskeläinen 
180fb279d8bSVesa Jääskeläinen 		res = TEE_AllocateOperation(&processing->tee_hash_op_handle,
181fb279d8bSVesa Jääskeläinen 					    hash_algo, hash_mode, 0);
182fb279d8bSVesa Jääskeläinen 		if (res) {
183fb279d8bSVesa Jääskeläinen 			EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32,
184fb279d8bSVesa Jääskeläinen 			     hash_algo, hash_mode);
185fb279d8bSVesa Jääskeläinen 
186fb279d8bSVesa Jääskeläinen 			if (res == TEE_ERROR_NOT_SUPPORTED)
187fb279d8bSVesa Jääskeläinen 				return PKCS11_CKR_MECHANISM_INVALID;
188fb279d8bSVesa Jääskeläinen 			return tee2pkcs_error(res);
189fb279d8bSVesa Jääskeläinen 		}
190fb279d8bSVesa Jääskeläinen 		processing->tee_hash_algo = hash_algo;
191fb279d8bSVesa Jääskeläinen 	}
192fb279d8bSVesa Jääskeläinen 
193fb279d8bSVesa Jääskeläinen 	res = TEE_AllocateOperation(&processing->tee_op_handle,
194fb279d8bSVesa Jääskeläinen 				    algo, mode, size);
195fb279d8bSVesa Jääskeläinen 	if (res)
196fb279d8bSVesa Jääskeläinen 		EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32,
197fb279d8bSVesa Jääskeläinen 		     algo, mode, size);
198fb279d8bSVesa Jääskeläinen 
199fb279d8bSVesa Jääskeläinen 	if (res == TEE_ERROR_NOT_SUPPORTED)
200fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_MECHANISM_INVALID;
201fb279d8bSVesa Jääskeläinen 
202fb279d8bSVesa Jääskeläinen 	if (res != TEE_SUCCESS &&
203fb279d8bSVesa Jääskeläinen 	    processing->tee_hash_op_handle != TEE_HANDLE_NULL) {
204fb279d8bSVesa Jääskeläinen 		TEE_FreeOperation(session->processing->tee_hash_op_handle);
205fb279d8bSVesa Jääskeläinen 		processing->tee_hash_op_handle = TEE_HANDLE_NULL;
206fb279d8bSVesa Jääskeläinen 		processing->tee_hash_algo = 0;
207fb279d8bSVesa Jääskeläinen 	}
208fb279d8bSVesa Jääskeläinen 
209fb279d8bSVesa Jääskeläinen 	return tee2pkcs_error(res);
210fb279d8bSVesa Jääskeläinen }
211fb279d8bSVesa Jääskeläinen 
212fb279d8bSVesa Jääskeläinen static enum pkcs11_rc load_tee_key(struct pkcs11_session *session,
213fb279d8bSVesa Jääskeläinen 				   struct pkcs11_object *obj,
214fb279d8bSVesa Jääskeläinen 				   enum processing_func function)
215fb279d8bSVesa Jääskeläinen {
216fb279d8bSVesa Jääskeläinen 	TEE_Attribute *tee_attrs = NULL;
217fb279d8bSVesa Jääskeläinen 	size_t tee_attrs_count = 0;
218fb279d8bSVesa Jääskeläinen 	size_t object_size = 0;
219fb279d8bSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
220fb279d8bSVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
221fb279d8bSVesa Jääskeläinen 	enum pkcs11_class_id __maybe_unused class = get_class(obj->attributes);
222fb279d8bSVesa Jääskeläinen 	enum pkcs11_key_type type = get_key_type(obj->attributes);
223fb279d8bSVesa Jääskeläinen 
224fb279d8bSVesa Jääskeläinen 	assert(class == PKCS11_CKO_PUBLIC_KEY ||
225fb279d8bSVesa Jääskeläinen 	       class == PKCS11_CKO_PRIVATE_KEY);
226fb279d8bSVesa Jääskeläinen 
227fb279d8bSVesa Jääskeläinen 	if (obj->key_handle != TEE_HANDLE_NULL) {
228fb279d8bSVesa Jääskeläinen 		switch (type) {
229*0442c956SVesa Jääskeläinen 		case PKCS11_CKK_RSA:
230*0442c956SVesa Jääskeläinen 			/* RSA loaded keys can be reused */
231*0442c956SVesa Jääskeläinen 			assert((obj->key_type == TEE_TYPE_RSA_PUBLIC_KEY &&
232*0442c956SVesa Jääskeläinen 				class == PKCS11_CKO_PUBLIC_KEY) ||
233*0442c956SVesa Jääskeläinen 			       (obj->key_type == TEE_TYPE_RSA_KEYPAIR &&
234*0442c956SVesa Jääskeläinen 				class == PKCS11_CKO_PRIVATE_KEY));
235*0442c956SVesa Jääskeläinen 			goto key_ready;
236fb279d8bSVesa Jääskeläinen 		case PKCS11_CKK_EC:
237fb279d8bSVesa Jääskeläinen 			/* Reuse EC TEE key only if already DSA or DH */
238fb279d8bSVesa Jääskeläinen 			switch (obj->key_type) {
239fb279d8bSVesa Jääskeläinen 			case TEE_TYPE_ECDSA_PUBLIC_KEY:
240fb279d8bSVesa Jääskeläinen 			case TEE_TYPE_ECDSA_KEYPAIR:
241fb279d8bSVesa Jääskeläinen 				if (function != PKCS11_FUNCTION_DERIVE)
242fb279d8bSVesa Jääskeläinen 					goto key_ready;
243fb279d8bSVesa Jääskeläinen 				break;
244fb279d8bSVesa Jääskeläinen 			default:
245fb279d8bSVesa Jääskeläinen 				assert(0);
246fb279d8bSVesa Jääskeläinen 				break;
247fb279d8bSVesa Jääskeläinen 			}
248fb279d8bSVesa Jääskeläinen 			break;
249fb279d8bSVesa Jääskeläinen 		default:
250fb279d8bSVesa Jääskeläinen 			assert(0);
251fb279d8bSVesa Jääskeläinen 			break;
252fb279d8bSVesa Jääskeläinen 		}
253fb279d8bSVesa Jääskeläinen 
254fb279d8bSVesa Jääskeläinen 		TEE_CloseObject(obj->key_handle);
255fb279d8bSVesa Jääskeläinen 		obj->key_handle = TEE_HANDLE_NULL;
256fb279d8bSVesa Jääskeläinen 	}
257fb279d8bSVesa Jääskeläinen 
258fb279d8bSVesa Jääskeläinen 	rc = pkcs2tee_key_type(&obj->key_type, obj, function);
259fb279d8bSVesa Jääskeläinen 	if (rc)
260fb279d8bSVesa Jääskeläinen 		return rc;
261fb279d8bSVesa Jääskeläinen 
262fb279d8bSVesa Jääskeläinen 	object_size = get_object_key_bit_size(obj);
263fb279d8bSVesa Jääskeläinen 	if (!object_size)
264fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_GENERAL_ERROR;
265fb279d8bSVesa Jääskeläinen 
266fb279d8bSVesa Jääskeläinen 	switch (type) {
267*0442c956SVesa Jääskeläinen 	case PKCS11_CKK_RSA:
268*0442c956SVesa Jääskeläinen 		rc = load_tee_rsa_key_attrs(&tee_attrs, &tee_attrs_count, obj);
269*0442c956SVesa Jääskeläinen 		break;
270fb279d8bSVesa Jääskeläinen 	case PKCS11_CKK_EC:
271fb279d8bSVesa Jääskeläinen 		rc = load_tee_ec_key_attrs(&tee_attrs, &tee_attrs_count, obj);
272fb279d8bSVesa Jääskeläinen 		break;
273fb279d8bSVesa Jääskeläinen 	default:
274fb279d8bSVesa Jääskeläinen 		break;
275fb279d8bSVesa Jääskeläinen 	}
276fb279d8bSVesa Jääskeläinen 	if (rc)
277fb279d8bSVesa Jääskeläinen 		return rc;
278fb279d8bSVesa Jääskeläinen 
279fb279d8bSVesa Jääskeläinen 	res = TEE_AllocateTransientObject(obj->key_type, object_size,
280fb279d8bSVesa Jääskeläinen 					  &obj->key_handle);
281fb279d8bSVesa Jääskeläinen 	if (res) {
282fb279d8bSVesa Jääskeläinen 		DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res);
283fb279d8bSVesa Jääskeläinen 
284fb279d8bSVesa Jääskeläinen 		return tee2pkcs_error(res);
285fb279d8bSVesa Jääskeläinen 	}
286fb279d8bSVesa Jääskeläinen 
287fb279d8bSVesa Jääskeläinen 	res = TEE_PopulateTransientObject(obj->key_handle,
288fb279d8bSVesa Jääskeläinen 					  tee_attrs, tee_attrs_count);
289fb279d8bSVesa Jääskeläinen 
290fb279d8bSVesa Jääskeläinen 	TEE_Free(tee_attrs);
291fb279d8bSVesa Jääskeläinen 
292fb279d8bSVesa Jääskeläinen 	if (res) {
293fb279d8bSVesa Jääskeläinen 		DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res);
294fb279d8bSVesa Jääskeläinen 
295fb279d8bSVesa Jääskeläinen 		goto error;
296fb279d8bSVesa Jääskeläinen 	}
297fb279d8bSVesa Jääskeläinen 
298fb279d8bSVesa Jääskeläinen key_ready:
299fb279d8bSVesa Jääskeläinen 	res = TEE_SetOperationKey(session->processing->tee_op_handle,
300fb279d8bSVesa Jääskeläinen 				  obj->key_handle);
301fb279d8bSVesa Jääskeläinen 	if (res) {
302fb279d8bSVesa Jääskeläinen 		DMSG("TEE_SetOperationKey failed, %#"PRIx32, res);
303fb279d8bSVesa Jääskeläinen 
304fb279d8bSVesa Jääskeläinen 		goto error;
305fb279d8bSVesa Jääskeläinen 	}
306fb279d8bSVesa Jääskeläinen 
307fb279d8bSVesa Jääskeläinen 	return PKCS11_CKR_OK;
308fb279d8bSVesa Jääskeläinen 
309fb279d8bSVesa Jääskeläinen error:
310fb279d8bSVesa Jääskeläinen 	TEE_FreeTransientObject(obj->key_handle);
311fb279d8bSVesa Jääskeläinen 	obj->key_handle = TEE_HANDLE_NULL;
312fb279d8bSVesa Jääskeläinen 	return tee2pkcs_error(res);
313fb279d8bSVesa Jääskeläinen }
314fb279d8bSVesa Jääskeläinen 
315fb279d8bSVesa Jääskeläinen static enum pkcs11_rc
316fb279d8bSVesa Jääskeläinen init_tee_operation(struct pkcs11_session *session __unused,
317fb279d8bSVesa Jääskeläinen 		   struct pkcs11_attribute_head *proc_params __unused)
318fb279d8bSVesa Jääskeläinen {
319fb279d8bSVesa Jääskeläinen 	return PKCS11_CKR_OK;
320fb279d8bSVesa Jääskeläinen }
321fb279d8bSVesa Jääskeläinen 
322fb279d8bSVesa Jääskeläinen enum pkcs11_rc init_asymm_operation(struct pkcs11_session *session,
323fb279d8bSVesa Jääskeläinen 				    enum processing_func function,
324fb279d8bSVesa Jääskeläinen 				    struct pkcs11_attribute_head *proc_params,
325fb279d8bSVesa Jääskeläinen 				    struct pkcs11_object *obj)
326fb279d8bSVesa Jääskeläinen {
327fb279d8bSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
328fb279d8bSVesa Jääskeläinen 
329fb279d8bSVesa Jääskeläinen 	assert(processing_is_tee_asymm(proc_params->id));
330fb279d8bSVesa Jääskeläinen 
331fb279d8bSVesa Jääskeläinen 	rc = allocate_tee_operation(session, function, proc_params, obj);
332fb279d8bSVesa Jääskeläinen 	if (rc)
333fb279d8bSVesa Jääskeläinen 		return rc;
334fb279d8bSVesa Jääskeläinen 
335fb279d8bSVesa Jääskeläinen 	rc = load_tee_key(session, obj, function);
336fb279d8bSVesa Jääskeläinen 	if (rc)
337fb279d8bSVesa Jääskeläinen 		return rc;
338fb279d8bSVesa Jääskeläinen 
339fb279d8bSVesa Jääskeläinen 	return init_tee_operation(session, proc_params);
340fb279d8bSVesa Jääskeläinen }
341fb279d8bSVesa Jääskeläinen 
342fb279d8bSVesa Jääskeläinen /*
343fb279d8bSVesa Jääskeläinen  * step_sym_step - step (update/oneshot/final) on a symmetric crypto operation
344fb279d8bSVesa Jääskeläinen  *
345fb279d8bSVesa Jääskeläinen  * @session - current session
346fb279d8bSVesa Jääskeläinen  * @function - processing function (encrypt, decrypt, sign, ...)
347fb279d8bSVesa Jääskeläinen  * @step - step ID in the processing (oneshot, update, final)
348fb279d8bSVesa Jääskeläinen  * @ptypes - invocation parameter types
349fb279d8bSVesa Jääskeläinen  * @params - invocation parameter references
350fb279d8bSVesa Jääskeläinen  */
351fb279d8bSVesa Jääskeläinen enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session,
352fb279d8bSVesa Jääskeläinen 				    enum processing_func function,
353fb279d8bSVesa Jääskeläinen 				    enum processing_step step,
354fb279d8bSVesa Jääskeläinen 				    uint32_t ptypes, TEE_Param *params)
355fb279d8bSVesa Jääskeläinen {
356fb279d8bSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
357fb279d8bSVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
358fb279d8bSVesa Jääskeläinen 	void *in_buf = NULL;
359fb279d8bSVesa Jääskeläinen 	void *in2_buf = NULL;
360fb279d8bSVesa Jääskeläinen 	void *out_buf = NULL;
361fb279d8bSVesa Jääskeläinen 	void *hash_buf = NULL;
362fb279d8bSVesa Jääskeläinen 	uint32_t in_size = 0;
363fb279d8bSVesa Jääskeläinen 	uint32_t in2_size = 0;
364fb279d8bSVesa Jääskeläinen 	uint32_t out_size = 0;
365fb279d8bSVesa Jääskeläinen 	uint32_t hash_size = 0;
366fb279d8bSVesa Jääskeläinen 	TEE_Attribute *tee_attrs = NULL;
367fb279d8bSVesa Jääskeläinen 	size_t tee_attrs_count = 0;
368fb279d8bSVesa Jääskeläinen 	bool output_data = false;
369fb279d8bSVesa Jääskeläinen 	struct active_processing *proc = session->processing;
370fb279d8bSVesa Jääskeläinen 	size_t sz = 0;
371fb279d8bSVesa Jääskeläinen 
372fb279d8bSVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) {
373fb279d8bSVesa Jääskeläinen 		in_buf = params[1].memref.buffer;
374fb279d8bSVesa Jääskeläinen 		in_size = params[1].memref.size;
375fb279d8bSVesa Jääskeläinen 		if (in_size && !in_buf)
376fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
377fb279d8bSVesa Jääskeläinen 	}
378fb279d8bSVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) {
379fb279d8bSVesa Jääskeläinen 		in2_buf = params[2].memref.buffer;
380fb279d8bSVesa Jääskeläinen 		in2_size = params[2].memref.size;
381fb279d8bSVesa Jääskeläinen 		if (in2_size && !in2_buf)
382fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
383fb279d8bSVesa Jääskeläinen 	}
384fb279d8bSVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) {
385fb279d8bSVesa Jääskeläinen 		out_buf = params[2].memref.buffer;
386fb279d8bSVesa Jääskeläinen 		out_size = params[2].memref.size;
387fb279d8bSVesa Jääskeläinen 		if (out_size && !out_buf)
388fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
389fb279d8bSVesa Jääskeläinen 	}
390fb279d8bSVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE)
391fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_ARGUMENTS_BAD;
392fb279d8bSVesa Jääskeläinen 
393fb279d8bSVesa Jääskeläinen 	switch (step) {
394fb279d8bSVesa Jääskeläinen 	case PKCS11_FUNC_STEP_ONESHOT:
395fb279d8bSVesa Jääskeläinen 	case PKCS11_FUNC_STEP_UPDATE:
396fb279d8bSVesa Jääskeläinen 	case PKCS11_FUNC_STEP_FINAL:
397fb279d8bSVesa Jääskeläinen 		break;
398fb279d8bSVesa Jääskeläinen 	default:
399fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_GENERAL_ERROR;
400fb279d8bSVesa Jääskeläinen 	}
401fb279d8bSVesa Jääskeläinen 
402fb279d8bSVesa Jääskeläinen 	/*
403fb279d8bSVesa Jääskeläinen 	 * Handle multi stage update step for mechas needing hash
404fb279d8bSVesa Jääskeläinen 	 * calculation
405fb279d8bSVesa Jääskeläinen 	 */
406fb279d8bSVesa Jääskeläinen 	if (step == PKCS11_FUNC_STEP_UPDATE) {
407fb279d8bSVesa Jääskeläinen 		switch (proc->mecha_type) {
408fb279d8bSVesa Jääskeläinen 		case PKCS11_CKM_ECDSA_SHA1:
409fb279d8bSVesa Jääskeläinen 		case PKCS11_CKM_ECDSA_SHA224:
410fb279d8bSVesa Jääskeläinen 		case PKCS11_CKM_ECDSA_SHA256:
411fb279d8bSVesa Jääskeläinen 		case PKCS11_CKM_ECDSA_SHA384:
412fb279d8bSVesa Jääskeläinen 		case PKCS11_CKM_ECDSA_SHA512:
413*0442c956SVesa Jääskeläinen 		case PKCS11_CKM_MD5_RSA_PKCS:
414*0442c956SVesa Jääskeläinen 		case PKCS11_CKM_SHA1_RSA_PKCS:
415*0442c956SVesa Jääskeläinen 		case PKCS11_CKM_SHA224_RSA_PKCS:
416*0442c956SVesa Jääskeläinen 		case PKCS11_CKM_SHA256_RSA_PKCS:
417*0442c956SVesa Jääskeläinen 		case PKCS11_CKM_SHA384_RSA_PKCS:
418*0442c956SVesa Jääskeläinen 		case PKCS11_CKM_SHA512_RSA_PKCS:
419fb279d8bSVesa Jääskeläinen 			assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL);
420fb279d8bSVesa Jääskeläinen 
421fb279d8bSVesa Jääskeläinen 			TEE_DigestUpdate(proc->tee_hash_op_handle, in_buf,
422fb279d8bSVesa Jääskeläinen 					 in_size);
423fb279d8bSVesa Jääskeläinen 			break;
424fb279d8bSVesa Jääskeläinen 		default:
425fb279d8bSVesa Jääskeläinen 			/*
426fb279d8bSVesa Jääskeläinen 			 * Other mechanism do not expect multi stage
427fb279d8bSVesa Jääskeläinen 			 * operation
428fb279d8bSVesa Jääskeläinen 			 */
429fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_GENERAL_ERROR;
430fb279d8bSVesa Jääskeläinen 			break;
431fb279d8bSVesa Jääskeläinen 		}
432fb279d8bSVesa Jääskeläinen 
433fb279d8bSVesa Jääskeläinen 		goto out;
434fb279d8bSVesa Jääskeläinen 	}
435fb279d8bSVesa Jääskeläinen 
436fb279d8bSVesa Jääskeläinen 	/*
437fb279d8bSVesa Jääskeläinen 	 * Handle multi stage one shot and final steps for mechas needing hash
438fb279d8bSVesa Jääskeläinen 	 * calculation
439fb279d8bSVesa Jääskeläinen 	 */
440fb279d8bSVesa Jääskeläinen 	switch (proc->mecha_type) {
441fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
442fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
443fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
444fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
445fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
446*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_MD5_RSA_PKCS:
447*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS:
448*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS:
449*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS:
450*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS:
451*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS:
452fb279d8bSVesa Jääskeläinen 		assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL);
453fb279d8bSVesa Jääskeläinen 
454fb279d8bSVesa Jääskeläinen 		hash_size = TEE_ALG_GET_DIGEST_SIZE(proc->tee_hash_algo);
455fb279d8bSVesa Jääskeläinen 		hash_buf = TEE_Malloc(hash_size, 0);
456fb279d8bSVesa Jääskeläinen 		if (!hash_buf)
457fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
458fb279d8bSVesa Jääskeläinen 
459fb279d8bSVesa Jääskeläinen 		res = TEE_DigestDoFinal(proc->tee_hash_op_handle,
460fb279d8bSVesa Jääskeläinen 					in_buf, in_size, hash_buf,
461fb279d8bSVesa Jääskeläinen 					&hash_size);
462fb279d8bSVesa Jääskeläinen 
463fb279d8bSVesa Jääskeläinen 		rc = tee2pkcs_error(res);
464fb279d8bSVesa Jääskeläinen 		if (rc != PKCS11_CKR_OK)
465fb279d8bSVesa Jääskeläinen 			goto out;
466fb279d8bSVesa Jääskeläinen 
467fb279d8bSVesa Jääskeläinen 		break;
468fb279d8bSVesa Jääskeläinen 	default:
469fb279d8bSVesa Jääskeläinen 		break;
470fb279d8bSVesa Jääskeläinen 	}
471fb279d8bSVesa Jääskeläinen 
472fb279d8bSVesa Jääskeläinen 	/*
473fb279d8bSVesa Jääskeläinen 	 * Finalize either provided hash or calculated hash with signing
474fb279d8bSVesa Jääskeläinen 	 * operation
475fb279d8bSVesa Jääskeläinen 	 */
476fb279d8bSVesa Jääskeläinen 
477fb279d8bSVesa Jääskeläinen 	/* First determine amount of bytes for signing operation */
478fb279d8bSVesa Jääskeläinen 	switch (proc->mecha_type) {
479fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA:
480fb279d8bSVesa Jääskeläinen 		sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle);
481fb279d8bSVesa Jääskeläinen 		if (!in_size || !sz) {
482fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_FUNCTION_FAILED;
483fb279d8bSVesa Jääskeläinen 			goto out;
484fb279d8bSVesa Jääskeläinen 		}
485fb279d8bSVesa Jääskeläinen 
486fb279d8bSVesa Jääskeläinen 		/*
487fb279d8bSVesa Jääskeläinen 		 * Note 3) Input the entire raw digest. Internally, this will
488fb279d8bSVesa Jääskeläinen 		 * be truncated to the appropriate number of bits.
489fb279d8bSVesa Jääskeläinen 		 */
490fb279d8bSVesa Jääskeläinen 		if (in_size > sz)
491fb279d8bSVesa Jääskeläinen 			in_size = sz;
492fb279d8bSVesa Jääskeläinen 
493fb279d8bSVesa Jääskeläinen 		if (function == PKCS11_FUNCTION_VERIFY && in2_size != 2 * sz) {
494fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_SIGNATURE_LEN_RANGE;
495fb279d8bSVesa Jääskeläinen 			goto out;
496fb279d8bSVesa Jääskeläinen 		}
497fb279d8bSVesa Jääskeläinen 		break;
498fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
499fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
500fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
501fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
502fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
503fb279d8bSVesa Jääskeläinen 		/* Get key size in bytes */
504fb279d8bSVesa Jääskeläinen 		sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle);
505fb279d8bSVesa Jääskeläinen 		if (!sz) {
506fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_FUNCTION_FAILED;
507fb279d8bSVesa Jääskeläinen 			goto out;
508fb279d8bSVesa Jääskeläinen 		}
509fb279d8bSVesa Jääskeläinen 
510fb279d8bSVesa Jääskeläinen 		if (function == PKCS11_FUNCTION_VERIFY &&
511fb279d8bSVesa Jääskeläinen 		    in2_size != 2 * sz) {
512fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_SIGNATURE_LEN_RANGE;
513fb279d8bSVesa Jääskeläinen 			goto out;
514fb279d8bSVesa Jääskeläinen 		}
515fb279d8bSVesa Jääskeläinen 		break;
516*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS:
517*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_MD5_RSA_PKCS:
518*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS:
519*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS:
520*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS:
521*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS:
522*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS:
523*0442c956SVesa Jääskeläinen 		/* Get key size in bytes */
524*0442c956SVesa Jääskeläinen 		sz = rsa_get_input_max_byte_size(proc->tee_op_handle);
525*0442c956SVesa Jääskeläinen 		if (!sz) {
526*0442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_FUNCTION_FAILED;
527*0442c956SVesa Jääskeläinen 			goto out;
528*0442c956SVesa Jääskeläinen 		}
529*0442c956SVesa Jääskeläinen 
530*0442c956SVesa Jääskeläinen 		if (function == PKCS11_FUNCTION_VERIFY && in2_size != sz) {
531*0442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_SIGNATURE_LEN_RANGE;
532*0442c956SVesa Jääskeläinen 			goto out;
533*0442c956SVesa Jääskeläinen 		}
534*0442c956SVesa Jääskeläinen 		break;
535fb279d8bSVesa Jääskeläinen 	default:
536fb279d8bSVesa Jääskeläinen 		break;
537fb279d8bSVesa Jääskeläinen 	}
538fb279d8bSVesa Jääskeläinen 
539fb279d8bSVesa Jääskeläinen 	/* Next perform actual signing operation */
540fb279d8bSVesa Jääskeläinen 	switch (proc->mecha_type) {
541fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA:
542*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS:
543fb279d8bSVesa Jääskeläinen 		/* For operations using provided input data */
544fb279d8bSVesa Jääskeläinen 		switch (function) {
545fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_ENCRYPT:
546fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricEncrypt(proc->tee_op_handle,
547fb279d8bSVesa Jääskeläinen 						    tee_attrs, tee_attrs_count,
548fb279d8bSVesa Jääskeläinen 						    in_buf, in_size,
549fb279d8bSVesa Jääskeläinen 						    out_buf, &out_size);
550fb279d8bSVesa Jääskeläinen 			output_data = true;
551fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
552fb279d8bSVesa Jääskeläinen 			break;
553fb279d8bSVesa Jääskeläinen 
554fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_DECRYPT:
555fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricDecrypt(proc->tee_op_handle,
556fb279d8bSVesa Jääskeläinen 						    tee_attrs, tee_attrs_count,
557fb279d8bSVesa Jääskeläinen 						    in_buf, in_size,
558fb279d8bSVesa Jääskeläinen 						    out_buf, &out_size);
559fb279d8bSVesa Jääskeläinen 			output_data = true;
560fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
561fb279d8bSVesa Jääskeläinen 			break;
562fb279d8bSVesa Jääskeläinen 
563fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_SIGN:
564fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricSignDigest(proc->tee_op_handle,
565fb279d8bSVesa Jääskeläinen 						       tee_attrs,
566fb279d8bSVesa Jääskeläinen 						       tee_attrs_count,
567fb279d8bSVesa Jääskeläinen 						       in_buf, in_size,
568fb279d8bSVesa Jääskeläinen 						       out_buf, &out_size);
569fb279d8bSVesa Jääskeläinen 			output_data = true;
570fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
571fb279d8bSVesa Jääskeläinen 			break;
572fb279d8bSVesa Jääskeläinen 
573fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_VERIFY:
574fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle,
575fb279d8bSVesa Jääskeläinen 							 tee_attrs,
576fb279d8bSVesa Jääskeläinen 							 tee_attrs_count,
577fb279d8bSVesa Jääskeläinen 							 in_buf, in_size,
578fb279d8bSVesa Jääskeläinen 							 in2_buf, in2_size);
579fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
580fb279d8bSVesa Jääskeläinen 			break;
581fb279d8bSVesa Jääskeläinen 
582fb279d8bSVesa Jääskeläinen 		default:
583fb279d8bSVesa Jääskeläinen 			TEE_Panic(function);
584fb279d8bSVesa Jääskeläinen 			break;
585fb279d8bSVesa Jääskeläinen 		}
586fb279d8bSVesa Jääskeläinen 		break;
587fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
588fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
589fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
590fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
591fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
592*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_MD5_RSA_PKCS:
593*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS:
594*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS:
595*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS:
596*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS:
597*0442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS:
598fb279d8bSVesa Jääskeläinen 		/* For operations having hash operation use calculated hash */
599fb279d8bSVesa Jääskeläinen 		switch (function) {
600fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_SIGN:
601fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricSignDigest(proc->tee_op_handle,
602fb279d8bSVesa Jääskeläinen 						       tee_attrs,
603fb279d8bSVesa Jääskeläinen 						       tee_attrs_count,
604fb279d8bSVesa Jääskeläinen 						       hash_buf, hash_size,
605fb279d8bSVesa Jääskeläinen 						       out_buf, &out_size);
606fb279d8bSVesa Jääskeläinen 			output_data = true;
607fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
608fb279d8bSVesa Jääskeläinen 			break;
609fb279d8bSVesa Jääskeläinen 
610fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_VERIFY:
611fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle,
612fb279d8bSVesa Jääskeläinen 							 tee_attrs,
613fb279d8bSVesa Jääskeläinen 							 tee_attrs_count,
614fb279d8bSVesa Jääskeläinen 							 hash_buf, hash_size,
615fb279d8bSVesa Jääskeläinen 							 in2_buf, in2_size);
616fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
617fb279d8bSVesa Jääskeläinen 			break;
618fb279d8bSVesa Jääskeläinen 
619fb279d8bSVesa Jääskeläinen 		default:
620fb279d8bSVesa Jääskeläinen 			TEE_Panic(function);
621fb279d8bSVesa Jääskeläinen 			break;
622fb279d8bSVesa Jääskeläinen 		}
623fb279d8bSVesa Jääskeläinen 		break;
624fb279d8bSVesa Jääskeläinen 	default:
625fb279d8bSVesa Jääskeläinen 		TEE_Panic(proc->mecha_type);
626fb279d8bSVesa Jääskeläinen 		break;
627fb279d8bSVesa Jääskeläinen 	}
628fb279d8bSVesa Jääskeläinen 
629fb279d8bSVesa Jääskeläinen out:
630fb279d8bSVesa Jääskeläinen 	if (output_data &&
631fb279d8bSVesa Jääskeläinen 	    (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) {
632fb279d8bSVesa Jääskeläinen 		switch (TEE_PARAM_TYPE_GET(ptypes, 2)) {
633fb279d8bSVesa Jääskeläinen 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
634fb279d8bSVesa Jääskeläinen 		case TEE_PARAM_TYPE_MEMREF_INOUT:
635fb279d8bSVesa Jääskeläinen 			params[2].memref.size = out_size;
636fb279d8bSVesa Jääskeläinen 			break;
637fb279d8bSVesa Jääskeläinen 		default:
638fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_GENERAL_ERROR;
639fb279d8bSVesa Jääskeläinen 			break;
640fb279d8bSVesa Jääskeläinen 		}
641fb279d8bSVesa Jääskeläinen 	}
642fb279d8bSVesa Jääskeläinen 
643fb279d8bSVesa Jääskeläinen 	TEE_Free(hash_buf);
644fb279d8bSVesa Jääskeläinen 	TEE_Free(tee_attrs);
645fb279d8bSVesa Jääskeläinen 
646fb279d8bSVesa Jääskeläinen 	return rc;
647fb279d8bSVesa Jääskeläinen }
648