xref: /optee_os/ta/pkcs11/src/processing_asymm.c (revision 9df68186a76db7cf0a5c9d633cd08db69b7131a0)
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:
38fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
39fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
40fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
41fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
42fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
43fb279d8bSVesa Jääskeläinen 		return true;
44fb279d8bSVesa Jääskeläinen 	default:
45fb279d8bSVesa Jääskeläinen 		return false;
46fb279d8bSVesa Jääskeläinen 	}
47fb279d8bSVesa Jääskeläinen }
48fb279d8bSVesa Jääskeläinen 
49fb279d8bSVesa Jääskeläinen static enum pkcs11_rc
50fb279d8bSVesa Jääskeläinen pkcs2tee_algorithm(uint32_t *tee_id, uint32_t *tee_hash_id,
51fb279d8bSVesa Jääskeläinen 		   enum processing_func function __unused,
52fb279d8bSVesa Jääskeläinen 		   struct pkcs11_attribute_head *proc_params,
53fb279d8bSVesa Jääskeläinen 		   struct pkcs11_object *obj)
54fb279d8bSVesa Jääskeläinen {
55fb279d8bSVesa Jääskeläinen 	static const struct {
56fb279d8bSVesa Jääskeläinen 		enum pkcs11_mechanism_id mech_id;
57fb279d8bSVesa Jääskeläinen 		uint32_t tee_id;
58fb279d8bSVesa Jääskeläinen 		uint32_t tee_hash_id;
59fb279d8bSVesa Jääskeläinen 	} pkcs2tee_algo[] = {
600442c956SVesa Jääskeläinen 		/* RSA flavors */
610442c956SVesa Jääskeläinen 		{ PKCS11_CKM_RSA_PKCS, TEE_ALG_RSAES_PKCS1_V1_5, 0 },
62dc8c77fcSVesa Jääskeläinen 		{ PKCS11_CKM_RSA_PKCS_OAEP, 1, 0 },
63d9af50bcSVesa Jääskeläinen 		{ PKCS11_CKM_RSA_PKCS_PSS, 1, 0 },
640442c956SVesa Jääskeläinen 		{ PKCS11_CKM_MD5_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_MD5,
650442c956SVesa Jääskeläinen 		  TEE_ALG_MD5 },
660442c956SVesa Jääskeläinen 		{ PKCS11_CKM_SHA1_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA1,
670442c956SVesa Jääskeläinen 		  TEE_ALG_SHA1 },
680442c956SVesa Jääskeläinen 		{ PKCS11_CKM_SHA224_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA224,
690442c956SVesa Jääskeläinen 		  TEE_ALG_SHA224 },
700442c956SVesa Jääskeläinen 		{ PKCS11_CKM_SHA256_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA256,
710442c956SVesa Jääskeläinen 		  TEE_ALG_SHA256 },
720442c956SVesa Jääskeläinen 		{ PKCS11_CKM_SHA384_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA384,
730442c956SVesa Jääskeläinen 		  TEE_ALG_SHA384 },
740442c956SVesa Jääskeläinen 		{ PKCS11_CKM_SHA512_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA512,
750442c956SVesa Jääskeläinen 		  TEE_ALG_SHA512 },
76d9af50bcSVesa Jääskeläinen 		{ PKCS11_CKM_SHA1_RSA_PKCS_PSS,
77d9af50bcSVesa Jääskeläinen 		  TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1, TEE_ALG_SHA1 },
78d9af50bcSVesa Jääskeläinen 		{ PKCS11_CKM_SHA224_RSA_PKCS_PSS,
79d9af50bcSVesa Jääskeläinen 		  TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224, TEE_ALG_SHA224 },
80d9af50bcSVesa Jääskeläinen 		{ PKCS11_CKM_SHA256_RSA_PKCS_PSS,
81d9af50bcSVesa Jääskeläinen 		  TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256, TEE_ALG_SHA256 },
82d9af50bcSVesa Jääskeläinen 		{ PKCS11_CKM_SHA384_RSA_PKCS_PSS,
83d9af50bcSVesa Jääskeläinen 		  TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384, TEE_ALG_SHA384 },
84d9af50bcSVesa Jääskeläinen 		{ PKCS11_CKM_SHA512_RSA_PKCS_PSS,
85d9af50bcSVesa Jääskeläinen 		  TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512, TEE_ALG_SHA512 },
86fb279d8bSVesa Jääskeläinen 		/* EC flavors (Must find key size from the object) */
87fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA, 1, 0 },
88fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA_SHA1, 1, TEE_ALG_SHA1 },
89fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA_SHA224, 1, TEE_ALG_SHA224 },
90fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA_SHA256, 1, TEE_ALG_SHA256 },
91fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA_SHA384, 1, TEE_ALG_SHA384 },
92fb279d8bSVesa Jääskeläinen 		{ PKCS11_CKM_ECDSA_SHA512, 1, TEE_ALG_SHA512 },
93fb279d8bSVesa Jääskeläinen 	};
94fb279d8bSVesa Jääskeläinen 	size_t n = 0;
95fb279d8bSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
96fb279d8bSVesa Jääskeläinen 
97fb279d8bSVesa Jääskeläinen 	for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) {
98fb279d8bSVesa Jääskeläinen 		if (pkcs2tee_algo[n].mech_id == proc_params->id) {
99fb279d8bSVesa Jääskeläinen 			*tee_id = pkcs2tee_algo[n].tee_id;
100fb279d8bSVesa Jääskeläinen 			*tee_hash_id = pkcs2tee_algo[n].tee_hash_id;
101fb279d8bSVesa Jääskeläinen 			break;
102fb279d8bSVesa Jääskeläinen 		}
103fb279d8bSVesa Jääskeläinen 	}
104fb279d8bSVesa Jääskeläinen 
105fb279d8bSVesa Jääskeläinen 	if (n == ARRAY_SIZE(pkcs2tee_algo))
106fb279d8bSVesa Jääskeläinen 		return PKCS11_RV_NOT_IMPLEMENTED;
107fb279d8bSVesa Jääskeläinen 
108fb279d8bSVesa Jääskeläinen 	switch (proc_params->id) {
109d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_PSS:
110d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
111d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
112d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
113d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
114d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
115d9af50bcSVesa Jääskeläinen 		rc = pkcs2tee_algo_rsa_pss(tee_id, proc_params);
116d9af50bcSVesa Jääskeläinen 		break;
117dc8c77fcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_OAEP:
118dc8c77fcSVesa Jääskeläinen 		rc = pkcs2tee_algo_rsa_oaep(tee_id, tee_hash_id, proc_params);
119dc8c77fcSVesa Jääskeläinen 		break;
120fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA:
121fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
122fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
123fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
124fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
125fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
126fb279d8bSVesa Jääskeläinen 		rc = pkcs2tee_algo_ecdsa(tee_id, proc_params, obj);
127fb279d8bSVesa Jääskeläinen 		break;
128fb279d8bSVesa Jääskeläinen 	default:
129fb279d8bSVesa Jääskeläinen 		rc = PKCS11_CKR_OK;
130fb279d8bSVesa Jääskeläinen 		break;
131fb279d8bSVesa Jääskeläinen 	}
132fb279d8bSVesa Jääskeläinen 
1330442c956SVesa Jääskeläinen 	/*
1340442c956SVesa Jääskeläinen 	 * PKCS#11 uses single mechanism CKM_RSA_PKCS for both ciphering and
1350442c956SVesa Jääskeläinen 	 * authentication whereas GPD TEE expects TEE_ALG_RSAES_PKCS1_V1_5 for
1360442c956SVesa Jääskeläinen 	 * ciphering and TEE_ALG_RSASSA_PKCS1_V1_5 for authentication.
1370442c956SVesa Jääskeläinen 	 */
1380442c956SVesa Jääskeläinen 	if (*tee_id == TEE_ALG_RSAES_PKCS1_V1_5 &&
1390442c956SVesa Jääskeläinen 	    (function == PKCS11_FUNCTION_SIGN ||
1400442c956SVesa Jääskeläinen 	     function == PKCS11_FUNCTION_VERIFY))
1410442c956SVesa Jääskeläinen 		*tee_id = TEE_ALG_RSASSA_PKCS1_V1_5;
1420442c956SVesa Jääskeläinen 
143fb279d8bSVesa Jääskeläinen 	return rc;
144fb279d8bSVesa Jääskeläinen }
145fb279d8bSVesa Jääskeläinen 
146fb279d8bSVesa Jääskeläinen static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type,
147fb279d8bSVesa Jääskeläinen 					struct pkcs11_object *obj,
148fb279d8bSVesa Jääskeläinen 					enum processing_func function)
149fb279d8bSVesa Jääskeläinen {
150fb279d8bSVesa Jääskeläinen 	enum pkcs11_class_id class = get_class(obj->attributes);
151fb279d8bSVesa Jääskeläinen 	enum pkcs11_key_type type = get_key_type(obj->attributes);
152fb279d8bSVesa Jääskeläinen 
153fb279d8bSVesa Jääskeläinen 	switch (class) {
154fb279d8bSVesa Jääskeläinen 	case PKCS11_CKO_PUBLIC_KEY:
155fb279d8bSVesa Jääskeläinen 	case PKCS11_CKO_PRIVATE_KEY:
156fb279d8bSVesa Jääskeläinen 		break;
157fb279d8bSVesa Jääskeläinen 	default:
158fb279d8bSVesa Jääskeläinen 		TEE_Panic(class);
159fb279d8bSVesa Jääskeläinen 		break;
160fb279d8bSVesa Jääskeläinen 	}
161fb279d8bSVesa Jääskeläinen 
162fb279d8bSVesa Jääskeläinen 	switch (type) {
163fb279d8bSVesa Jääskeläinen 	case PKCS11_CKK_EC:
164fb279d8bSVesa Jääskeläinen 		assert(function != PKCS11_FUNCTION_DERIVE);
165fb279d8bSVesa Jääskeläinen 
166fb279d8bSVesa Jääskeläinen 		if (class == PKCS11_CKO_PRIVATE_KEY)
167fb279d8bSVesa Jääskeläinen 			*tee_type = TEE_TYPE_ECDSA_KEYPAIR;
168fb279d8bSVesa Jääskeläinen 		else
169fb279d8bSVesa Jääskeläinen 			*tee_type = TEE_TYPE_ECDSA_PUBLIC_KEY;
170fb279d8bSVesa Jääskeläinen 		break;
1710442c956SVesa Jääskeläinen 	case PKCS11_CKK_RSA:
1720442c956SVesa Jääskeläinen 		if (class == PKCS11_CKO_PRIVATE_KEY)
1730442c956SVesa Jääskeläinen 			*tee_type = TEE_TYPE_RSA_KEYPAIR;
1740442c956SVesa Jääskeläinen 		else
1750442c956SVesa Jääskeläinen 			*tee_type = TEE_TYPE_RSA_PUBLIC_KEY;
1760442c956SVesa Jääskeläinen 		break;
177fb279d8bSVesa Jääskeläinen 	default:
178fb279d8bSVesa Jääskeläinen 		TEE_Panic(type);
179fb279d8bSVesa Jääskeläinen 		break;
180fb279d8bSVesa Jääskeläinen 	}
181fb279d8bSVesa Jääskeläinen 
182fb279d8bSVesa Jääskeläinen 	return PKCS11_CKR_OK;
183fb279d8bSVesa Jääskeläinen }
184fb279d8bSVesa Jääskeläinen 
185fb279d8bSVesa Jääskeläinen static enum pkcs11_rc
186fb279d8bSVesa Jääskeläinen allocate_tee_operation(struct pkcs11_session *session,
187fb279d8bSVesa Jääskeläinen 		       enum processing_func function,
188fb279d8bSVesa Jääskeläinen 		       struct pkcs11_attribute_head *params,
189fb279d8bSVesa Jääskeläinen 		       struct pkcs11_object *obj)
190fb279d8bSVesa Jääskeläinen {
191fb279d8bSVesa Jääskeläinen 	uint32_t size = (uint32_t)get_object_key_bit_size(obj);
192fb279d8bSVesa Jääskeläinen 	uint32_t algo = 0;
193fb279d8bSVesa Jääskeläinen 	uint32_t hash_algo = 0;
194fb279d8bSVesa Jääskeläinen 	uint32_t mode = 0;
195fb279d8bSVesa Jääskeläinen 	uint32_t hash_mode = 0;
196fb279d8bSVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
197fb279d8bSVesa Jääskeläinen 	struct active_processing *processing = session->processing;
198fb279d8bSVesa Jääskeläinen 
199fb279d8bSVesa Jääskeläinen 	assert(processing->tee_op_handle == TEE_HANDLE_NULL);
200fb279d8bSVesa Jääskeläinen 	assert(processing->tee_hash_op_handle == TEE_HANDLE_NULL);
201fb279d8bSVesa Jääskeläinen 
202fb279d8bSVesa Jääskeläinen 	if (pkcs2tee_algorithm(&algo, &hash_algo, function, params, obj))
203fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_FUNCTION_FAILED;
204fb279d8bSVesa Jääskeläinen 
205fb279d8bSVesa Jääskeläinen 	pkcs2tee_mode(&mode, function);
206fb279d8bSVesa Jääskeläinen 
207fb279d8bSVesa Jääskeläinen 	if (hash_algo) {
208fb279d8bSVesa Jääskeläinen 		pkcs2tee_mode(&hash_mode, PKCS11_FUNCTION_DIGEST);
209fb279d8bSVesa Jääskeläinen 
210fb279d8bSVesa Jääskeläinen 		res = TEE_AllocateOperation(&processing->tee_hash_op_handle,
211fb279d8bSVesa Jääskeläinen 					    hash_algo, hash_mode, 0);
212fb279d8bSVesa Jääskeläinen 		if (res) {
213fb279d8bSVesa Jääskeläinen 			EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32,
214fb279d8bSVesa Jääskeläinen 			     hash_algo, hash_mode);
215fb279d8bSVesa Jääskeläinen 
216fb279d8bSVesa Jääskeläinen 			if (res == TEE_ERROR_NOT_SUPPORTED)
217fb279d8bSVesa Jääskeläinen 				return PKCS11_CKR_MECHANISM_INVALID;
218fb279d8bSVesa Jääskeläinen 			return tee2pkcs_error(res);
219fb279d8bSVesa Jääskeläinen 		}
220fb279d8bSVesa Jääskeläinen 		processing->tee_hash_algo = hash_algo;
221fb279d8bSVesa Jääskeläinen 	}
222fb279d8bSVesa Jääskeläinen 
223fb279d8bSVesa Jääskeläinen 	res = TEE_AllocateOperation(&processing->tee_op_handle,
224fb279d8bSVesa Jääskeläinen 				    algo, mode, size);
225fb279d8bSVesa Jääskeläinen 	if (res)
226fb279d8bSVesa Jääskeläinen 		EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32,
227fb279d8bSVesa Jääskeläinen 		     algo, mode, size);
228fb279d8bSVesa Jääskeläinen 
229fb279d8bSVesa Jääskeläinen 	if (res == TEE_ERROR_NOT_SUPPORTED)
230fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_MECHANISM_INVALID;
231fb279d8bSVesa Jääskeläinen 
232fb279d8bSVesa Jääskeläinen 	if (res != TEE_SUCCESS &&
233fb279d8bSVesa Jääskeläinen 	    processing->tee_hash_op_handle != TEE_HANDLE_NULL) {
234fb279d8bSVesa Jääskeläinen 		TEE_FreeOperation(session->processing->tee_hash_op_handle);
235fb279d8bSVesa Jääskeläinen 		processing->tee_hash_op_handle = TEE_HANDLE_NULL;
236fb279d8bSVesa Jääskeläinen 		processing->tee_hash_algo = 0;
237fb279d8bSVesa Jääskeläinen 	}
238fb279d8bSVesa Jääskeläinen 
239fb279d8bSVesa Jääskeläinen 	return tee2pkcs_error(res);
240fb279d8bSVesa Jääskeläinen }
241fb279d8bSVesa Jääskeläinen 
242fb279d8bSVesa Jääskeläinen static enum pkcs11_rc load_tee_key(struct pkcs11_session *session,
243fb279d8bSVesa Jääskeläinen 				   struct pkcs11_object *obj,
244fb279d8bSVesa Jääskeläinen 				   enum processing_func function)
245fb279d8bSVesa Jääskeläinen {
246fb279d8bSVesa Jääskeläinen 	TEE_Attribute *tee_attrs = NULL;
247fb279d8bSVesa Jääskeläinen 	size_t tee_attrs_count = 0;
248fb279d8bSVesa Jääskeläinen 	size_t object_size = 0;
249fb279d8bSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
250fb279d8bSVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
251fb279d8bSVesa Jääskeläinen 	enum pkcs11_class_id __maybe_unused class = get_class(obj->attributes);
252fb279d8bSVesa Jääskeläinen 	enum pkcs11_key_type type = get_key_type(obj->attributes);
253fb279d8bSVesa Jääskeläinen 
254fb279d8bSVesa Jääskeläinen 	assert(class == PKCS11_CKO_PUBLIC_KEY ||
255fb279d8bSVesa Jääskeläinen 	       class == PKCS11_CKO_PRIVATE_KEY);
256fb279d8bSVesa Jääskeläinen 
257fb279d8bSVesa Jääskeläinen 	if (obj->key_handle != TEE_HANDLE_NULL) {
258fb279d8bSVesa Jääskeläinen 		switch (type) {
2590442c956SVesa Jääskeläinen 		case PKCS11_CKK_RSA:
2600442c956SVesa Jääskeläinen 			/* RSA loaded keys can be reused */
2610442c956SVesa Jääskeläinen 			assert((obj->key_type == TEE_TYPE_RSA_PUBLIC_KEY &&
2620442c956SVesa Jääskeläinen 				class == PKCS11_CKO_PUBLIC_KEY) ||
2630442c956SVesa Jääskeläinen 			       (obj->key_type == TEE_TYPE_RSA_KEYPAIR &&
2640442c956SVesa Jääskeläinen 				class == PKCS11_CKO_PRIVATE_KEY));
2650442c956SVesa Jääskeläinen 			goto key_ready;
266fb279d8bSVesa Jääskeläinen 		case PKCS11_CKK_EC:
267fb279d8bSVesa Jääskeläinen 			/* Reuse EC TEE key only if already DSA or DH */
268fb279d8bSVesa Jääskeläinen 			switch (obj->key_type) {
269fb279d8bSVesa Jääskeläinen 			case TEE_TYPE_ECDSA_PUBLIC_KEY:
270fb279d8bSVesa Jääskeläinen 			case TEE_TYPE_ECDSA_KEYPAIR:
271fb279d8bSVesa Jääskeläinen 				if (function != PKCS11_FUNCTION_DERIVE)
272fb279d8bSVesa Jääskeläinen 					goto key_ready;
273fb279d8bSVesa Jääskeläinen 				break;
274fb279d8bSVesa Jääskeläinen 			default:
275fb279d8bSVesa Jääskeläinen 				assert(0);
276fb279d8bSVesa Jääskeläinen 				break;
277fb279d8bSVesa Jääskeläinen 			}
278fb279d8bSVesa Jääskeläinen 			break;
279fb279d8bSVesa Jääskeläinen 		default:
280fb279d8bSVesa Jääskeläinen 			assert(0);
281fb279d8bSVesa Jääskeläinen 			break;
282fb279d8bSVesa Jääskeläinen 		}
283fb279d8bSVesa Jääskeläinen 
284fb279d8bSVesa Jääskeläinen 		TEE_CloseObject(obj->key_handle);
285fb279d8bSVesa Jääskeläinen 		obj->key_handle = TEE_HANDLE_NULL;
286fb279d8bSVesa Jääskeläinen 	}
287fb279d8bSVesa Jääskeläinen 
288fb279d8bSVesa Jääskeläinen 	rc = pkcs2tee_key_type(&obj->key_type, obj, function);
289fb279d8bSVesa Jääskeläinen 	if (rc)
290fb279d8bSVesa Jääskeläinen 		return rc;
291fb279d8bSVesa Jääskeläinen 
292fb279d8bSVesa Jääskeläinen 	object_size = get_object_key_bit_size(obj);
293fb279d8bSVesa Jääskeläinen 	if (!object_size)
294fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_GENERAL_ERROR;
295fb279d8bSVesa Jääskeläinen 
296fb279d8bSVesa Jääskeläinen 	switch (type) {
2970442c956SVesa Jääskeläinen 	case PKCS11_CKK_RSA:
2980442c956SVesa Jääskeläinen 		rc = load_tee_rsa_key_attrs(&tee_attrs, &tee_attrs_count, obj);
2990442c956SVesa Jääskeläinen 		break;
300fb279d8bSVesa Jääskeläinen 	case PKCS11_CKK_EC:
301fb279d8bSVesa Jääskeläinen 		rc = load_tee_ec_key_attrs(&tee_attrs, &tee_attrs_count, obj);
302fb279d8bSVesa Jääskeläinen 		break;
303fb279d8bSVesa Jääskeläinen 	default:
304fb279d8bSVesa Jääskeläinen 		break;
305fb279d8bSVesa Jääskeläinen 	}
306fb279d8bSVesa Jääskeläinen 	if (rc)
307fb279d8bSVesa Jääskeläinen 		return rc;
308fb279d8bSVesa Jääskeläinen 
309fb279d8bSVesa Jääskeläinen 	res = TEE_AllocateTransientObject(obj->key_type, object_size,
310fb279d8bSVesa Jääskeläinen 					  &obj->key_handle);
311fb279d8bSVesa Jääskeläinen 	if (res) {
312fb279d8bSVesa Jääskeläinen 		DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res);
313fb279d8bSVesa Jääskeläinen 
314fb279d8bSVesa Jääskeläinen 		return tee2pkcs_error(res);
315fb279d8bSVesa Jääskeläinen 	}
316fb279d8bSVesa Jääskeläinen 
317fb279d8bSVesa Jääskeläinen 	res = TEE_PopulateTransientObject(obj->key_handle,
318fb279d8bSVesa Jääskeläinen 					  tee_attrs, tee_attrs_count);
319fb279d8bSVesa Jääskeläinen 
320fb279d8bSVesa Jääskeläinen 	TEE_Free(tee_attrs);
321fb279d8bSVesa Jääskeläinen 
322fb279d8bSVesa Jääskeläinen 	if (res) {
323fb279d8bSVesa Jääskeläinen 		DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res);
324fb279d8bSVesa Jääskeläinen 
325fb279d8bSVesa Jääskeläinen 		goto error;
326fb279d8bSVesa Jääskeläinen 	}
327fb279d8bSVesa Jääskeläinen 
328fb279d8bSVesa Jääskeläinen key_ready:
329fb279d8bSVesa Jääskeläinen 	res = TEE_SetOperationKey(session->processing->tee_op_handle,
330fb279d8bSVesa Jääskeläinen 				  obj->key_handle);
331fb279d8bSVesa Jääskeläinen 	if (res) {
332fb279d8bSVesa Jääskeläinen 		DMSG("TEE_SetOperationKey failed, %#"PRIx32, res);
333fb279d8bSVesa Jääskeläinen 
334fb279d8bSVesa Jääskeläinen 		goto error;
335fb279d8bSVesa Jääskeläinen 	}
336fb279d8bSVesa Jääskeläinen 
337fb279d8bSVesa Jääskeläinen 	return PKCS11_CKR_OK;
338fb279d8bSVesa Jääskeläinen 
339fb279d8bSVesa Jääskeläinen error:
340fb279d8bSVesa Jääskeläinen 	TEE_FreeTransientObject(obj->key_handle);
341fb279d8bSVesa Jääskeläinen 	obj->key_handle = TEE_HANDLE_NULL;
342fb279d8bSVesa Jääskeläinen 	return tee2pkcs_error(res);
343fb279d8bSVesa Jääskeläinen }
344fb279d8bSVesa Jääskeläinen 
345fb279d8bSVesa Jääskeläinen static enum pkcs11_rc
346d9af50bcSVesa Jääskeläinen init_tee_operation(struct pkcs11_session *session,
347d9af50bcSVesa Jääskeläinen 		   struct pkcs11_attribute_head *proc_params,
348d9af50bcSVesa Jääskeläinen 		   struct pkcs11_object *obj)
349fb279d8bSVesa Jääskeläinen {
350d9af50bcSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_OK;
351d9af50bcSVesa Jääskeläinen 	struct active_processing *proc = session->processing;
352d9af50bcSVesa Jääskeläinen 
353d9af50bcSVesa Jääskeläinen 	switch (proc_params->id) {
354d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_PSS:
355d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
356d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
357d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
358d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
359d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
360d9af50bcSVesa Jääskeläinen 		rc = pkcs2tee_proc_params_rsa_pss(proc, proc_params);
361d9af50bcSVesa Jääskeläinen 		if (rc)
362d9af50bcSVesa Jääskeläinen 			break;
363d9af50bcSVesa Jääskeläinen 
364d9af50bcSVesa Jääskeläinen 		rc = pkcs2tee_validate_rsa_pss(proc, obj);
365d9af50bcSVesa Jääskeläinen 		break;
366dc8c77fcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_OAEP:
367dc8c77fcSVesa Jääskeläinen 		rc = pkcs2tee_proc_params_rsa_oaep(proc, proc_params);
368dc8c77fcSVesa Jääskeläinen 		break;
369d9af50bcSVesa Jääskeläinen 	default:
370d9af50bcSVesa Jääskeläinen 		break;
371d9af50bcSVesa Jääskeläinen 	}
372d9af50bcSVesa Jääskeläinen 
373d9af50bcSVesa Jääskeläinen 	return rc;
374fb279d8bSVesa Jääskeläinen }
375fb279d8bSVesa Jääskeläinen 
376fb279d8bSVesa Jääskeläinen enum pkcs11_rc init_asymm_operation(struct pkcs11_session *session,
377fb279d8bSVesa Jääskeläinen 				    enum processing_func function,
378fb279d8bSVesa Jääskeläinen 				    struct pkcs11_attribute_head *proc_params,
379fb279d8bSVesa Jääskeläinen 				    struct pkcs11_object *obj)
380fb279d8bSVesa Jääskeläinen {
381fb279d8bSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
382fb279d8bSVesa Jääskeläinen 
383fb279d8bSVesa Jääskeläinen 	assert(processing_is_tee_asymm(proc_params->id));
384fb279d8bSVesa Jääskeläinen 
385fb279d8bSVesa Jääskeläinen 	rc = allocate_tee_operation(session, function, proc_params, obj);
386fb279d8bSVesa Jääskeläinen 	if (rc)
387fb279d8bSVesa Jääskeläinen 		return rc;
388fb279d8bSVesa Jääskeläinen 
389fb279d8bSVesa Jääskeläinen 	rc = load_tee_key(session, obj, function);
390fb279d8bSVesa Jääskeläinen 	if (rc)
391fb279d8bSVesa Jääskeläinen 		return rc;
392fb279d8bSVesa Jääskeläinen 
393d9af50bcSVesa Jääskeläinen 	return init_tee_operation(session, proc_params, obj);
394fb279d8bSVesa Jääskeläinen }
395fb279d8bSVesa Jääskeläinen 
396fb279d8bSVesa Jääskeläinen /*
397fb279d8bSVesa Jääskeläinen  * step_sym_step - step (update/oneshot/final) on a symmetric crypto operation
398fb279d8bSVesa Jääskeläinen  *
399fb279d8bSVesa Jääskeläinen  * @session - current session
400fb279d8bSVesa Jääskeläinen  * @function - processing function (encrypt, decrypt, sign, ...)
401fb279d8bSVesa Jääskeläinen  * @step - step ID in the processing (oneshot, update, final)
402fb279d8bSVesa Jääskeläinen  * @ptypes - invocation parameter types
403fb279d8bSVesa Jääskeläinen  * @params - invocation parameter references
404fb279d8bSVesa Jääskeläinen  */
405fb279d8bSVesa Jääskeläinen enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session,
406fb279d8bSVesa Jääskeläinen 				    enum processing_func function,
407fb279d8bSVesa Jääskeläinen 				    enum processing_step step,
408fb279d8bSVesa Jääskeläinen 				    uint32_t ptypes, TEE_Param *params)
409fb279d8bSVesa Jääskeläinen {
410fb279d8bSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
411fb279d8bSVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
412fb279d8bSVesa Jääskeläinen 	void *in_buf = NULL;
413fb279d8bSVesa Jääskeläinen 	void *in2_buf = NULL;
414fb279d8bSVesa Jääskeläinen 	void *out_buf = NULL;
415fb279d8bSVesa Jääskeläinen 	void *hash_buf = NULL;
416fb279d8bSVesa Jääskeläinen 	uint32_t in_size = 0;
417fb279d8bSVesa Jääskeläinen 	uint32_t in2_size = 0;
418fb279d8bSVesa Jääskeläinen 	uint32_t out_size = 0;
419fb279d8bSVesa Jääskeläinen 	uint32_t hash_size = 0;
420fb279d8bSVesa Jääskeläinen 	TEE_Attribute *tee_attrs = NULL;
421fb279d8bSVesa Jääskeläinen 	size_t tee_attrs_count = 0;
422fb279d8bSVesa Jääskeläinen 	bool output_data = false;
423fb279d8bSVesa Jääskeläinen 	struct active_processing *proc = session->processing;
424dc8c77fcSVesa Jääskeläinen 	struct rsa_oaep_processing_ctx *rsa_oaep_ctx = NULL;
425d9af50bcSVesa Jääskeläinen 	struct rsa_pss_processing_ctx *rsa_pss_ctx = NULL;
426fb279d8bSVesa Jääskeläinen 	size_t sz = 0;
427fb279d8bSVesa Jääskeläinen 
428fb279d8bSVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) {
429fb279d8bSVesa Jääskeläinen 		in_buf = params[1].memref.buffer;
430fb279d8bSVesa Jääskeläinen 		in_size = params[1].memref.size;
431fb279d8bSVesa Jääskeläinen 		if (in_size && !in_buf)
432fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
433fb279d8bSVesa Jääskeläinen 	}
434fb279d8bSVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) {
435fb279d8bSVesa Jääskeläinen 		in2_buf = params[2].memref.buffer;
436fb279d8bSVesa Jääskeläinen 		in2_size = params[2].memref.size;
437fb279d8bSVesa Jääskeläinen 		if (in2_size && !in2_buf)
438fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
439fb279d8bSVesa Jääskeläinen 	}
440fb279d8bSVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) {
441fb279d8bSVesa Jääskeläinen 		out_buf = params[2].memref.buffer;
442fb279d8bSVesa Jääskeläinen 		out_size = params[2].memref.size;
443fb279d8bSVesa Jääskeläinen 		if (out_size && !out_buf)
444fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_ARGUMENTS_BAD;
445fb279d8bSVesa Jääskeläinen 	}
446fb279d8bSVesa Jääskeläinen 	if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE)
447fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_ARGUMENTS_BAD;
448fb279d8bSVesa Jääskeläinen 
449fb279d8bSVesa Jääskeläinen 	switch (step) {
450fb279d8bSVesa Jääskeläinen 	case PKCS11_FUNC_STEP_ONESHOT:
451fb279d8bSVesa Jääskeläinen 	case PKCS11_FUNC_STEP_UPDATE:
452fb279d8bSVesa Jääskeläinen 	case PKCS11_FUNC_STEP_FINAL:
453fb279d8bSVesa Jääskeläinen 		break;
454fb279d8bSVesa Jääskeläinen 	default:
455fb279d8bSVesa Jääskeläinen 		return PKCS11_CKR_GENERAL_ERROR;
456fb279d8bSVesa Jääskeläinen 	}
457fb279d8bSVesa Jääskeläinen 
458d9af50bcSVesa Jääskeläinen 	/* TEE attribute(s) required by the operation */
459d9af50bcSVesa Jääskeläinen 	switch (proc->mecha_type) {
460d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_PSS:
461d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
462d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
463d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
464d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
465d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
466d9af50bcSVesa Jääskeläinen 		tee_attrs = TEE_Malloc(sizeof(TEE_Attribute),
467d9af50bcSVesa Jääskeläinen 				       TEE_USER_MEM_HINT_NO_FILL_ZERO);
468d9af50bcSVesa Jääskeläinen 		if (!tee_attrs) {
469d9af50bcSVesa Jääskeläinen 			rc = PKCS11_CKR_DEVICE_MEMORY;
470d9af50bcSVesa Jääskeläinen 			goto out;
471d9af50bcSVesa Jääskeläinen 		}
472d9af50bcSVesa Jääskeläinen 
473d9af50bcSVesa Jääskeläinen 		rsa_pss_ctx = proc->extra_ctx;
474d9af50bcSVesa Jääskeläinen 
475d9af50bcSVesa Jääskeläinen 		TEE_InitValueAttribute(&tee_attrs[tee_attrs_count],
476d9af50bcSVesa Jääskeläinen 				       TEE_ATTR_RSA_PSS_SALT_LENGTH,
477d9af50bcSVesa Jääskeläinen 				       rsa_pss_ctx->salt_len, 0);
478d9af50bcSVesa Jääskeläinen 		tee_attrs_count++;
479d9af50bcSVesa Jääskeläinen 		break;
480dc8c77fcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_OAEP:
481dc8c77fcSVesa Jääskeläinen 		rsa_oaep_ctx = proc->extra_ctx;
482dc8c77fcSVesa Jääskeläinen 
483dc8c77fcSVesa Jääskeläinen 		if (!rsa_oaep_ctx->source_data_len)
484dc8c77fcSVesa Jääskeläinen 			break;
485dc8c77fcSVesa Jääskeläinen 
486dc8c77fcSVesa Jääskeläinen 		tee_attrs = TEE_Malloc(sizeof(TEE_Attribute),
487dc8c77fcSVesa Jääskeläinen 				       TEE_USER_MEM_HINT_NO_FILL_ZERO);
488dc8c77fcSVesa Jääskeläinen 		if (!tee_attrs) {
489dc8c77fcSVesa Jääskeläinen 			rc = PKCS11_CKR_DEVICE_MEMORY;
490dc8c77fcSVesa Jääskeläinen 			goto out;
491dc8c77fcSVesa Jääskeläinen 		}
492dc8c77fcSVesa Jääskeläinen 
493dc8c77fcSVesa Jääskeläinen 		TEE_InitRefAttribute(&tee_attrs[tee_attrs_count],
494dc8c77fcSVesa Jääskeläinen 				     TEE_ATTR_RSA_OAEP_LABEL,
495dc8c77fcSVesa Jääskeläinen 				     rsa_oaep_ctx->source_data,
496dc8c77fcSVesa Jääskeläinen 				     rsa_oaep_ctx->source_data_len);
497dc8c77fcSVesa Jääskeläinen 		tee_attrs_count++;
498dc8c77fcSVesa Jääskeläinen 		break;
499d9af50bcSVesa Jääskeläinen 	default:
500d9af50bcSVesa Jääskeläinen 		break;
501d9af50bcSVesa Jääskeläinen 	}
502d9af50bcSVesa Jääskeläinen 
503fb279d8bSVesa Jääskeläinen 	/*
504fb279d8bSVesa Jääskeläinen 	 * Handle multi stage update step for mechas needing hash
505fb279d8bSVesa Jääskeläinen 	 * calculation
506fb279d8bSVesa Jääskeläinen 	 */
507fb279d8bSVesa Jääskeläinen 	if (step == PKCS11_FUNC_STEP_UPDATE) {
508fb279d8bSVesa Jääskeläinen 		switch (proc->mecha_type) {
509fb279d8bSVesa Jääskeläinen 		case PKCS11_CKM_ECDSA_SHA1:
510fb279d8bSVesa Jääskeläinen 		case PKCS11_CKM_ECDSA_SHA224:
511fb279d8bSVesa Jääskeläinen 		case PKCS11_CKM_ECDSA_SHA256:
512fb279d8bSVesa Jääskeläinen 		case PKCS11_CKM_ECDSA_SHA384:
513fb279d8bSVesa Jääskeläinen 		case PKCS11_CKM_ECDSA_SHA512:
5140442c956SVesa Jääskeläinen 		case PKCS11_CKM_MD5_RSA_PKCS:
5150442c956SVesa Jääskeläinen 		case PKCS11_CKM_SHA1_RSA_PKCS:
5160442c956SVesa Jääskeläinen 		case PKCS11_CKM_SHA224_RSA_PKCS:
5170442c956SVesa Jääskeläinen 		case PKCS11_CKM_SHA256_RSA_PKCS:
5180442c956SVesa Jääskeläinen 		case PKCS11_CKM_SHA384_RSA_PKCS:
5190442c956SVesa Jääskeläinen 		case PKCS11_CKM_SHA512_RSA_PKCS:
520d9af50bcSVesa Jääskeläinen 		case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
521d9af50bcSVesa Jääskeläinen 		case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
522d9af50bcSVesa Jääskeläinen 		case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
523d9af50bcSVesa Jääskeläinen 		case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
524d9af50bcSVesa Jääskeläinen 		case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
525fb279d8bSVesa Jääskeläinen 			assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL);
526fb279d8bSVesa Jääskeläinen 
527fb279d8bSVesa Jääskeläinen 			TEE_DigestUpdate(proc->tee_hash_op_handle, in_buf,
528fb279d8bSVesa Jääskeläinen 					 in_size);
529*9df68186SEtienne Carriere 			rc = PKCS11_CKR_OK;
530fb279d8bSVesa Jääskeläinen 			break;
531fb279d8bSVesa Jääskeläinen 		default:
532fb279d8bSVesa Jääskeläinen 			/*
533fb279d8bSVesa Jääskeläinen 			 * Other mechanism do not expect multi stage
534fb279d8bSVesa Jääskeläinen 			 * operation
535fb279d8bSVesa Jääskeläinen 			 */
536fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_GENERAL_ERROR;
537fb279d8bSVesa Jääskeläinen 			break;
538fb279d8bSVesa Jääskeläinen 		}
539fb279d8bSVesa Jääskeläinen 
540fb279d8bSVesa Jääskeläinen 		goto out;
541fb279d8bSVesa Jääskeläinen 	}
542fb279d8bSVesa Jääskeläinen 
543fb279d8bSVesa Jääskeläinen 	/*
544fb279d8bSVesa Jääskeläinen 	 * Handle multi stage one shot and final steps for mechas needing hash
545fb279d8bSVesa Jääskeläinen 	 * calculation
546fb279d8bSVesa Jääskeläinen 	 */
547fb279d8bSVesa Jääskeläinen 	switch (proc->mecha_type) {
548fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
549fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
550fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
551fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
552fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
5530442c956SVesa Jääskeläinen 	case PKCS11_CKM_MD5_RSA_PKCS:
5540442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS:
5550442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS:
5560442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS:
5570442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS:
5580442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS:
559d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
560d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
561d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
562d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
563d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
564fb279d8bSVesa Jääskeläinen 		assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL);
565fb279d8bSVesa Jääskeläinen 
566fb279d8bSVesa Jääskeläinen 		hash_size = TEE_ALG_GET_DIGEST_SIZE(proc->tee_hash_algo);
567fb279d8bSVesa Jääskeläinen 		hash_buf = TEE_Malloc(hash_size, 0);
568fb279d8bSVesa Jääskeläinen 		if (!hash_buf)
569fb279d8bSVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
570fb279d8bSVesa Jääskeläinen 
571fb279d8bSVesa Jääskeläinen 		res = TEE_DigestDoFinal(proc->tee_hash_op_handle,
572fb279d8bSVesa Jääskeläinen 					in_buf, in_size, hash_buf,
573fb279d8bSVesa Jääskeläinen 					&hash_size);
574fb279d8bSVesa Jääskeläinen 
575fb279d8bSVesa Jääskeläinen 		rc = tee2pkcs_error(res);
576fb279d8bSVesa Jääskeläinen 		if (rc != PKCS11_CKR_OK)
577fb279d8bSVesa Jääskeläinen 			goto out;
578fb279d8bSVesa Jääskeläinen 
579fb279d8bSVesa Jääskeläinen 		break;
580fb279d8bSVesa Jääskeläinen 	default:
581fb279d8bSVesa Jääskeläinen 		break;
582fb279d8bSVesa Jääskeläinen 	}
583fb279d8bSVesa Jääskeläinen 
584fb279d8bSVesa Jääskeläinen 	/*
585fb279d8bSVesa Jääskeläinen 	 * Finalize either provided hash or calculated hash with signing
586fb279d8bSVesa Jääskeläinen 	 * operation
587fb279d8bSVesa Jääskeläinen 	 */
588fb279d8bSVesa Jääskeläinen 
589fb279d8bSVesa Jääskeläinen 	/* First determine amount of bytes for signing operation */
590fb279d8bSVesa Jääskeläinen 	switch (proc->mecha_type) {
591fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA:
592fb279d8bSVesa Jääskeläinen 		sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle);
593fb279d8bSVesa Jääskeläinen 		if (!in_size || !sz) {
594fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_FUNCTION_FAILED;
595fb279d8bSVesa Jääskeläinen 			goto out;
596fb279d8bSVesa Jääskeläinen 		}
597fb279d8bSVesa Jääskeläinen 
598fb279d8bSVesa Jääskeläinen 		/*
599fb279d8bSVesa Jääskeläinen 		 * Note 3) Input the entire raw digest. Internally, this will
600fb279d8bSVesa Jääskeläinen 		 * be truncated to the appropriate number of bits.
601fb279d8bSVesa Jääskeläinen 		 */
602fb279d8bSVesa Jääskeläinen 		if (in_size > sz)
603fb279d8bSVesa Jääskeläinen 			in_size = sz;
604fb279d8bSVesa Jääskeläinen 
605fb279d8bSVesa Jääskeläinen 		if (function == PKCS11_FUNCTION_VERIFY && in2_size != 2 * sz) {
606fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_SIGNATURE_LEN_RANGE;
607fb279d8bSVesa Jääskeläinen 			goto out;
608fb279d8bSVesa Jääskeläinen 		}
609fb279d8bSVesa Jääskeläinen 		break;
610fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
611fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
612fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
613fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
614fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
615fb279d8bSVesa Jääskeläinen 		/* Get key size in bytes */
616fb279d8bSVesa Jääskeläinen 		sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle);
617fb279d8bSVesa Jääskeläinen 		if (!sz) {
618fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_FUNCTION_FAILED;
619fb279d8bSVesa Jääskeläinen 			goto out;
620fb279d8bSVesa Jääskeläinen 		}
621fb279d8bSVesa Jääskeläinen 
622fb279d8bSVesa Jääskeläinen 		if (function == PKCS11_FUNCTION_VERIFY &&
623fb279d8bSVesa Jääskeläinen 		    in2_size != 2 * sz) {
624fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_SIGNATURE_LEN_RANGE;
625fb279d8bSVesa Jääskeläinen 			goto out;
626fb279d8bSVesa Jääskeläinen 		}
627fb279d8bSVesa Jääskeläinen 		break;
6280442c956SVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS:
6290442c956SVesa Jääskeläinen 	case PKCS11_CKM_MD5_RSA_PKCS:
6300442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS:
6310442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS:
6320442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS:
6330442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS:
6340442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS:
635d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_PSS:
636d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
637d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
638d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
639d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
640d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
6410442c956SVesa Jääskeläinen 		/* Get key size in bytes */
6420442c956SVesa Jääskeläinen 		sz = rsa_get_input_max_byte_size(proc->tee_op_handle);
6430442c956SVesa Jääskeläinen 		if (!sz) {
6440442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_FUNCTION_FAILED;
6450442c956SVesa Jääskeläinen 			goto out;
6460442c956SVesa Jääskeläinen 		}
6470442c956SVesa Jääskeläinen 
6480442c956SVesa Jääskeläinen 		if (function == PKCS11_FUNCTION_VERIFY && in2_size != sz) {
6490442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_SIGNATURE_LEN_RANGE;
6500442c956SVesa Jääskeläinen 			goto out;
6510442c956SVesa Jääskeläinen 		}
6520442c956SVesa Jääskeläinen 		break;
653fb279d8bSVesa Jääskeläinen 	default:
654fb279d8bSVesa Jääskeläinen 		break;
655fb279d8bSVesa Jääskeläinen 	}
656fb279d8bSVesa Jääskeläinen 
657fb279d8bSVesa Jääskeläinen 	/* Next perform actual signing operation */
658fb279d8bSVesa Jääskeläinen 	switch (proc->mecha_type) {
659fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA:
6600442c956SVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS:
661dc8c77fcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_OAEP:
662d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_PSS:
663fb279d8bSVesa Jääskeläinen 		/* For operations using provided input data */
664fb279d8bSVesa Jääskeläinen 		switch (function) {
665fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_ENCRYPT:
666fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricEncrypt(proc->tee_op_handle,
667fb279d8bSVesa Jääskeläinen 						    tee_attrs, tee_attrs_count,
668fb279d8bSVesa Jääskeläinen 						    in_buf, in_size,
669fb279d8bSVesa Jääskeläinen 						    out_buf, &out_size);
670fb279d8bSVesa Jääskeläinen 			output_data = true;
671fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
6726a6299fbSVesa Jääskeläinen 			if (rc == PKCS11_CKR_ARGUMENTS_BAD)
6736a6299fbSVesa Jääskeläinen 				rc = PKCS11_CKR_DATA_LEN_RANGE;
674fb279d8bSVesa Jääskeläinen 			break;
675fb279d8bSVesa Jääskeläinen 
676fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_DECRYPT:
677fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricDecrypt(proc->tee_op_handle,
678fb279d8bSVesa Jääskeläinen 						    tee_attrs, tee_attrs_count,
679fb279d8bSVesa Jääskeläinen 						    in_buf, in_size,
680fb279d8bSVesa Jääskeläinen 						    out_buf, &out_size);
681fb279d8bSVesa Jääskeläinen 			output_data = true;
682fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
683f27310a5SVesa Jääskeläinen 			if (rc == PKCS11_CKR_ARGUMENTS_BAD)
684f27310a5SVesa Jääskeläinen 				rc = PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE;
685fb279d8bSVesa Jääskeläinen 			break;
686fb279d8bSVesa Jääskeläinen 
687fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_SIGN:
688fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricSignDigest(proc->tee_op_handle,
689fb279d8bSVesa Jääskeläinen 						       tee_attrs,
690fb279d8bSVesa Jääskeläinen 						       tee_attrs_count,
691fb279d8bSVesa Jääskeläinen 						       in_buf, in_size,
692fb279d8bSVesa Jääskeläinen 						       out_buf, &out_size);
693fb279d8bSVesa Jääskeläinen 			output_data = true;
694fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
695fb279d8bSVesa Jääskeläinen 			break;
696fb279d8bSVesa Jääskeläinen 
697fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_VERIFY:
698fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle,
699fb279d8bSVesa Jääskeläinen 							 tee_attrs,
700fb279d8bSVesa Jääskeläinen 							 tee_attrs_count,
701fb279d8bSVesa Jääskeläinen 							 in_buf, in_size,
702fb279d8bSVesa Jääskeläinen 							 in2_buf, in2_size);
703fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
704fb279d8bSVesa Jääskeläinen 			break;
705fb279d8bSVesa Jääskeläinen 
706fb279d8bSVesa Jääskeläinen 		default:
707fb279d8bSVesa Jääskeläinen 			TEE_Panic(function);
708fb279d8bSVesa Jääskeläinen 			break;
709fb279d8bSVesa Jääskeläinen 		}
710fb279d8bSVesa Jääskeläinen 		break;
711fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA1:
712fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA224:
713fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA256:
714fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA384:
715fb279d8bSVesa Jääskeläinen 	case PKCS11_CKM_ECDSA_SHA512:
7160442c956SVesa Jääskeläinen 	case PKCS11_CKM_MD5_RSA_PKCS:
7170442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS:
7180442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS:
7190442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS:
7200442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS:
7210442c956SVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS:
722d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA1_RSA_PKCS_PSS:
723d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA224_RSA_PKCS_PSS:
724d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA256_RSA_PKCS_PSS:
725d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA384_RSA_PKCS_PSS:
726d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA512_RSA_PKCS_PSS:
727fb279d8bSVesa Jääskeläinen 		/* For operations having hash operation use calculated hash */
728fb279d8bSVesa Jääskeläinen 		switch (function) {
729fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_SIGN:
730fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricSignDigest(proc->tee_op_handle,
731fb279d8bSVesa Jääskeläinen 						       tee_attrs,
732fb279d8bSVesa Jääskeläinen 						       tee_attrs_count,
733fb279d8bSVesa Jääskeläinen 						       hash_buf, hash_size,
734fb279d8bSVesa Jääskeläinen 						       out_buf, &out_size);
735fb279d8bSVesa Jääskeläinen 			output_data = true;
736fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
737fb279d8bSVesa Jääskeläinen 			break;
738fb279d8bSVesa Jääskeläinen 
739fb279d8bSVesa Jääskeläinen 		case PKCS11_FUNCTION_VERIFY:
740fb279d8bSVesa Jääskeläinen 			res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle,
741fb279d8bSVesa Jääskeläinen 							 tee_attrs,
742fb279d8bSVesa Jääskeläinen 							 tee_attrs_count,
743fb279d8bSVesa Jääskeläinen 							 hash_buf, hash_size,
744fb279d8bSVesa Jääskeläinen 							 in2_buf, in2_size);
745fb279d8bSVesa Jääskeläinen 			rc = tee2pkcs_error(res);
746fb279d8bSVesa Jääskeläinen 			break;
747fb279d8bSVesa Jääskeläinen 
748fb279d8bSVesa Jääskeläinen 		default:
749fb279d8bSVesa Jääskeläinen 			TEE_Panic(function);
750fb279d8bSVesa Jääskeläinen 			break;
751fb279d8bSVesa Jääskeläinen 		}
752fb279d8bSVesa Jääskeläinen 		break;
753fb279d8bSVesa Jääskeläinen 	default:
754fb279d8bSVesa Jääskeläinen 		TEE_Panic(proc->mecha_type);
755fb279d8bSVesa Jääskeläinen 		break;
756fb279d8bSVesa Jääskeläinen 	}
757fb279d8bSVesa Jääskeläinen 
758fb279d8bSVesa Jääskeläinen out:
759fb279d8bSVesa Jääskeläinen 	if (output_data &&
760fb279d8bSVesa Jääskeläinen 	    (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) {
761fb279d8bSVesa Jääskeläinen 		switch (TEE_PARAM_TYPE_GET(ptypes, 2)) {
762fb279d8bSVesa Jääskeläinen 		case TEE_PARAM_TYPE_MEMREF_OUTPUT:
763fb279d8bSVesa Jääskeläinen 		case TEE_PARAM_TYPE_MEMREF_INOUT:
764fb279d8bSVesa Jääskeläinen 			params[2].memref.size = out_size;
765fb279d8bSVesa Jääskeläinen 			break;
766fb279d8bSVesa Jääskeläinen 		default:
767fb279d8bSVesa Jääskeläinen 			rc = PKCS11_CKR_GENERAL_ERROR;
768fb279d8bSVesa Jääskeläinen 			break;
769fb279d8bSVesa Jääskeläinen 		}
770fb279d8bSVesa Jääskeläinen 	}
771fb279d8bSVesa Jääskeläinen 
772fb279d8bSVesa Jääskeläinen 	TEE_Free(hash_buf);
773fb279d8bSVesa Jääskeläinen 	TEE_Free(tee_attrs);
774fb279d8bSVesa Jääskeläinen 
775fb279d8bSVesa Jääskeläinen 	return rc;
776fb279d8bSVesa Jääskeläinen }
777