xref: /optee_os/ta/pkcs11/src/processing_rsa.c (revision 45d40bda652aece0c348d316b0170992f781c99a)
186922832SVesa Jääskeläinen // SPDX-License-Identifier: BSD-2-Clause
286922832SVesa Jääskeläinen /*
386922832SVesa Jääskeläinen  * Copyright (c) 2018-2021, Linaro Limited
486922832SVesa Jääskeläinen  */
586922832SVesa Jääskeläinen 
686922832SVesa Jääskeläinen #include <assert.h>
786922832SVesa Jääskeläinen #include <pkcs11_ta.h>
886922832SVesa Jääskeläinen #include <tee_api_defines.h>
986922832SVesa Jääskeläinen #include <tee_internal_api.h>
1086922832SVesa Jääskeläinen #include <tee_internal_api_extensions.h>
1186922832SVesa Jääskeläinen 
1286922832SVesa Jääskeläinen #include "attributes.h"
130442c956SVesa Jääskeläinen #include "object.h"
14d9af50bcSVesa Jääskeläinen #include "pkcs11_token.h"
1586922832SVesa Jääskeläinen #include "processing.h"
1686922832SVesa Jääskeläinen 
17d9af50bcSVesa Jääskeläinen enum pkcs11_rc
18d9af50bcSVesa Jääskeläinen pkcs2tee_proc_params_rsa_pss(struct active_processing *proc,
19d9af50bcSVesa Jääskeläinen 			     struct pkcs11_attribute_head *proc_params)
20d9af50bcSVesa Jääskeläinen {
21d9af50bcSVesa Jääskeläinen 	struct serialargs args = { };
22d9af50bcSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
23d9af50bcSVesa Jääskeläinen 	struct rsa_pss_processing_ctx *ctx = NULL;
24d9af50bcSVesa Jääskeläinen 	uint32_t hash = 0;
25d9af50bcSVesa Jääskeläinen 	uint32_t mgf = 0;
26d9af50bcSVesa Jääskeläinen 	uint32_t salt_len = 0;
27d9af50bcSVesa Jääskeläinen 
28d9af50bcSVesa Jääskeläinen 	serialargs_init(&args, proc_params->data, proc_params->size);
29d9af50bcSVesa Jääskeläinen 
30d9af50bcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &hash);
31d9af50bcSVesa Jääskeläinen 	if (rc)
32d9af50bcSVesa Jääskeläinen 		return rc;
33d9af50bcSVesa Jääskeläinen 
34d9af50bcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &mgf);
35d9af50bcSVesa Jääskeläinen 	if (rc)
36d9af50bcSVesa Jääskeläinen 		return rc;
37d9af50bcSVesa Jääskeläinen 
38d9af50bcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &salt_len);
39d9af50bcSVesa Jääskeläinen 	if (rc)
40d9af50bcSVesa Jääskeläinen 		return rc;
41d9af50bcSVesa Jääskeläinen 
42d9af50bcSVesa Jääskeläinen 	if (serialargs_remaining_bytes(&args))
43d9af50bcSVesa Jääskeläinen 		return PKCS11_CKR_ARGUMENTS_BAD;
44d9af50bcSVesa Jääskeläinen 
45d9af50bcSVesa Jääskeläinen 	proc->extra_ctx = TEE_Malloc(sizeof(struct rsa_pss_processing_ctx),
46d9af50bcSVesa Jääskeläinen 				     TEE_USER_MEM_HINT_NO_FILL_ZERO);
47d9af50bcSVesa Jääskeläinen 	if (!proc->extra_ctx)
48d9af50bcSVesa Jääskeläinen 		return PKCS11_CKR_DEVICE_MEMORY;
49d9af50bcSVesa Jääskeläinen 
50d9af50bcSVesa Jääskeläinen 	ctx = proc->extra_ctx;
51d9af50bcSVesa Jääskeläinen 
52d9af50bcSVesa Jääskeläinen 	ctx->hash_alg = hash;
53d9af50bcSVesa Jääskeläinen 	ctx->mgf_type = mgf;
54d9af50bcSVesa Jääskeläinen 	ctx->salt_len = salt_len;
55d9af50bcSVesa Jääskeläinen 
56d9af50bcSVesa Jääskeläinen 	return PKCS11_CKR_OK;
57d9af50bcSVesa Jääskeläinen }
58d9af50bcSVesa Jääskeläinen 
59d9af50bcSVesa Jääskeläinen enum pkcs11_rc pkcs2tee_validate_rsa_pss(struct active_processing *proc,
60d9af50bcSVesa Jääskeläinen 					 struct pkcs11_object *obj)
61d9af50bcSVesa Jääskeläinen {
62d9af50bcSVesa Jääskeläinen 	struct rsa_pss_processing_ctx *rsa_pss_ctx = NULL;
63d9af50bcSVesa Jääskeläinen 	size_t modulus_size = 0;
64d9af50bcSVesa Jääskeläinen 	size_t hash_size = 0;
65d9af50bcSVesa Jääskeläinen 	uint32_t k = 0;
66d9af50bcSVesa Jääskeläinen 
67d9af50bcSVesa Jääskeläinen 	rsa_pss_ctx = proc->extra_ctx;
68d9af50bcSVesa Jääskeläinen 	assert(rsa_pss_ctx);
69d9af50bcSVesa Jääskeläinen 
70d9af50bcSVesa Jääskeläinen 	switch (rsa_pss_ctx->hash_alg) {
71d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA_1:
72d9af50bcSVesa Jääskeläinen 		hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA1);
73d9af50bcSVesa Jääskeläinen 		break;
74d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA224:
75d9af50bcSVesa Jääskeläinen 		hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA224);
76d9af50bcSVesa Jääskeläinen 		break;
77d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA256:
78d9af50bcSVesa Jääskeläinen 		hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA256);
79d9af50bcSVesa Jääskeläinen 		break;
80d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA384:
81d9af50bcSVesa Jääskeläinen 		hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA384);
82d9af50bcSVesa Jääskeläinen 		break;
83d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA512:
84d9af50bcSVesa Jääskeläinen 		hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA512);
85d9af50bcSVesa Jääskeläinen 		break;
86d9af50bcSVesa Jääskeläinen 	default:
87d9af50bcSVesa Jääskeläinen 		assert(0);
88d9af50bcSVesa Jääskeläinen 		break;
89d9af50bcSVesa Jääskeläinen 	}
90d9af50bcSVesa Jääskeläinen 
91d9af50bcSVesa Jääskeläinen 	modulus_size = get_object_key_bit_size(obj);
92d9af50bcSVesa Jääskeläinen 
93d9af50bcSVesa Jääskeläinen 	/**
94d9af50bcSVesa Jääskeläinen 	 * The sLen field must be less than or equal to k*-2-hLen where
95d9af50bcSVesa Jääskeläinen 	 * hLen is the length in bytes of the hash value. k* is the
96d9af50bcSVesa Jääskeläinen 	 * length in bytes of the RSA modulus, except if the length in
97d9af50bcSVesa Jääskeläinen 	 * bits of the RSA modulus is one more than a multiple of 8, in
98d9af50bcSVesa Jääskeläinen 	 * which case k* is one less than the length in bytes of the
99d9af50bcSVesa Jääskeläinen 	 * RSA modulus.
100d9af50bcSVesa Jääskeläinen 	 */
101d9af50bcSVesa Jääskeläinen 	if ((modulus_size % 8) == 1)
102d9af50bcSVesa Jääskeläinen 		k = modulus_size / 8;
103d9af50bcSVesa Jääskeläinen 	else
104d9af50bcSVesa Jääskeläinen 		k = ROUNDUP(modulus_size, 8) / 8;
105d9af50bcSVesa Jääskeläinen 
106d9af50bcSVesa Jääskeläinen 	if (rsa_pss_ctx->salt_len > (k - 2 - hash_size))
107d9af50bcSVesa Jääskeläinen 		return PKCS11_CKR_KEY_SIZE_RANGE;
108d9af50bcSVesa Jääskeläinen 
109d9af50bcSVesa Jääskeläinen 	return PKCS11_CKR_OK;
110d9af50bcSVesa Jääskeläinen }
111d9af50bcSVesa Jääskeläinen 
112d9af50bcSVesa Jääskeläinen /*
113d9af50bcSVesa Jääskeläinen  * Check or set TEE algorithm identifier upon PKCS11 mechanism parameters
114d9af50bcSVesa Jääskeläinen  * @tee_id: Input and/or output TEE algorithm identifier
115d9af50bcSVesa Jääskeläinen  * @proc_params: PKCS11 processing parameters
116d9af50bcSVesa Jääskeläinen  */
117d9af50bcSVesa Jääskeläinen enum pkcs11_rc pkcs2tee_algo_rsa_pss(uint32_t *tee_id,
118d9af50bcSVesa Jääskeläinen 				     struct pkcs11_attribute_head *proc_params)
119d9af50bcSVesa Jääskeläinen {
120d9af50bcSVesa Jääskeläinen 	struct serialargs args = { };
121d9af50bcSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
122d9af50bcSVesa Jääskeläinen 	uint32_t hash = 0;
123d9af50bcSVesa Jääskeläinen 	uint32_t mgf = 0;
124d9af50bcSVesa Jääskeläinen 	uint32_t salt_len = 0;
125d9af50bcSVesa Jääskeläinen 
126d9af50bcSVesa Jääskeläinen 	serialargs_init(&args, proc_params->data, proc_params->size);
127d9af50bcSVesa Jääskeläinen 
128d9af50bcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &hash);
129d9af50bcSVesa Jääskeläinen 	if (rc)
130d9af50bcSVesa Jääskeläinen 		return rc;
131d9af50bcSVesa Jääskeläinen 
132d9af50bcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &mgf);
133d9af50bcSVesa Jääskeläinen 	if (rc)
134d9af50bcSVesa Jääskeläinen 		return rc;
135d9af50bcSVesa Jääskeläinen 
136d9af50bcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &salt_len);
137d9af50bcSVesa Jääskeläinen 	if (rc)
138d9af50bcSVesa Jääskeläinen 		return rc;
139d9af50bcSVesa Jääskeläinen 
140d9af50bcSVesa Jääskeläinen 	if (serialargs_remaining_bytes(&args))
141d9af50bcSVesa Jääskeläinen 		return PKCS11_CKR_ARGUMENTS_BAD;
142d9af50bcSVesa Jääskeläinen 
143d9af50bcSVesa Jääskeläinen 	if (proc_params->id == PKCS11_CKM_RSA_PKCS_PSS) {
144d9af50bcSVesa Jääskeläinen 		if (hash == PKCS11_CKM_SHA_1 && mgf == PKCS11_CKG_MGF1_SHA1) {
145d9af50bcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1;
146d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_OK;
147d9af50bcSVesa Jääskeläinen 		}
148d9af50bcSVesa Jääskeläinen 		if (hash == PKCS11_CKM_SHA224 &&
149d9af50bcSVesa Jääskeläinen 		    mgf == PKCS11_CKG_MGF1_SHA224) {
150d9af50bcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224;
151d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_OK;
152d9af50bcSVesa Jääskeläinen 		}
153d9af50bcSVesa Jääskeläinen 		if (hash == PKCS11_CKM_SHA256 &&
154d9af50bcSVesa Jääskeläinen 		    mgf == PKCS11_CKG_MGF1_SHA256) {
155d9af50bcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256;
156d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_OK;
157d9af50bcSVesa Jääskeläinen 		}
158d9af50bcSVesa Jääskeläinen 		if (hash == PKCS11_CKM_SHA384 &&
159d9af50bcSVesa Jääskeläinen 		    mgf == PKCS11_CKG_MGF1_SHA384) {
160d9af50bcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384;
161d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_OK;
162d9af50bcSVesa Jääskeläinen 		}
163d9af50bcSVesa Jääskeläinen 		if (hash == PKCS11_CKM_SHA512 &&
164d9af50bcSVesa Jääskeläinen 		    mgf == PKCS11_CKG_MGF1_SHA512) {
165d9af50bcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512;
166d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_OK;
167d9af50bcSVesa Jääskeläinen 		}
168d9af50bcSVesa Jääskeläinen 		return PKCS11_CKR_MECHANISM_PARAM_INVALID;
169d9af50bcSVesa Jääskeläinen 	}
170d9af50bcSVesa Jääskeläinen 
171d9af50bcSVesa Jääskeläinen 	switch (*tee_id) {
172d9af50bcSVesa Jääskeläinen 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
173d9af50bcSVesa Jääskeläinen 		if (hash != PKCS11_CKM_SHA_1 || mgf != PKCS11_CKG_MGF1_SHA1)
174d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
175d9af50bcSVesa Jääskeläinen 		break;
176d9af50bcSVesa Jääskeläinen 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
177d9af50bcSVesa Jääskeläinen 		if (hash != PKCS11_CKM_SHA224 || mgf != PKCS11_CKG_MGF1_SHA224)
178d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
179d9af50bcSVesa Jääskeläinen 		break;
180d9af50bcSVesa Jääskeläinen 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
181d9af50bcSVesa Jääskeläinen 		if (hash != PKCS11_CKM_SHA256 || mgf != PKCS11_CKG_MGF1_SHA256)
182d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
183d9af50bcSVesa Jääskeläinen 		break;
184d9af50bcSVesa Jääskeläinen 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
185d9af50bcSVesa Jääskeläinen 		if (hash != PKCS11_CKM_SHA384 || mgf != PKCS11_CKG_MGF1_SHA384)
186d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
187d9af50bcSVesa Jääskeläinen 		break;
188d9af50bcSVesa Jääskeläinen 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
189d9af50bcSVesa Jääskeläinen 		if (hash != PKCS11_CKM_SHA512 || mgf != PKCS11_CKG_MGF1_SHA512)
190d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
191d9af50bcSVesa Jääskeläinen 		break;
192d9af50bcSVesa Jääskeläinen 	default:
193d9af50bcSVesa Jääskeläinen 		return PKCS11_CKR_GENERAL_ERROR;
194d9af50bcSVesa Jääskeläinen 	}
195d9af50bcSVesa Jääskeläinen 
196d9af50bcSVesa Jääskeläinen 	return PKCS11_CKR_OK;
197d9af50bcSVesa Jääskeläinen }
198d9af50bcSVesa Jääskeläinen 
199dc8c77fcSVesa Jääskeläinen enum pkcs11_rc
200dc8c77fcSVesa Jääskeläinen pkcs2tee_proc_params_rsa_oaep(struct active_processing *proc,
201dc8c77fcSVesa Jääskeläinen 			      struct pkcs11_attribute_head *proc_params)
202dc8c77fcSVesa Jääskeläinen {
203dc8c77fcSVesa Jääskeläinen 	struct serialargs args = { };
204dc8c77fcSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
205dc8c77fcSVesa Jääskeläinen 	struct rsa_oaep_processing_ctx *ctx = NULL;
206dc8c77fcSVesa Jääskeläinen 	uint32_t hash = 0;
207dc8c77fcSVesa Jääskeläinen 	uint32_t mgf = 0;
208dc8c77fcSVesa Jääskeläinen 	uint32_t source_type = 0;
209dc8c77fcSVesa Jääskeläinen 	void *source_data = NULL;
210dc8c77fcSVesa Jääskeläinen 	uint32_t source_size = 0;
211dc8c77fcSVesa Jääskeläinen 
212dc8c77fcSVesa Jääskeläinen 	serialargs_init(&args, proc_params->data, proc_params->size);
213dc8c77fcSVesa Jääskeläinen 
214dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &hash);
215dc8c77fcSVesa Jääskeläinen 	if (rc)
216dc8c77fcSVesa Jääskeläinen 		return rc;
217dc8c77fcSVesa Jääskeläinen 
218dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &mgf);
219dc8c77fcSVesa Jääskeläinen 	if (rc)
220dc8c77fcSVesa Jääskeläinen 		return rc;
221dc8c77fcSVesa Jääskeläinen 
222dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &source_type);
223dc8c77fcSVesa Jääskeläinen 	if (rc)
224dc8c77fcSVesa Jääskeläinen 		return rc;
225dc8c77fcSVesa Jääskeläinen 
226dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &source_size);
227dc8c77fcSVesa Jääskeläinen 	if (rc)
228dc8c77fcSVesa Jääskeläinen 		return rc;
229dc8c77fcSVesa Jääskeläinen 
230dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_ptr(&args, &source_data, source_size);
231dc8c77fcSVesa Jääskeläinen 	if (rc)
232dc8c77fcSVesa Jääskeläinen 		return rc;
233dc8c77fcSVesa Jääskeläinen 
234dc8c77fcSVesa Jääskeläinen 	if (serialargs_remaining_bytes(&args))
235dc8c77fcSVesa Jääskeläinen 		return PKCS11_CKR_ARGUMENTS_BAD;
236dc8c77fcSVesa Jääskeläinen 
237dc8c77fcSVesa Jääskeläinen 	proc->extra_ctx = TEE_Malloc(sizeof(struct rsa_oaep_processing_ctx) +
238dc8c77fcSVesa Jääskeläinen 				     source_size,
239dc8c77fcSVesa Jääskeläinen 				     TEE_USER_MEM_HINT_NO_FILL_ZERO);
240dc8c77fcSVesa Jääskeläinen 	if (!proc->extra_ctx)
241dc8c77fcSVesa Jääskeläinen 		return PKCS11_CKR_DEVICE_MEMORY;
242dc8c77fcSVesa Jääskeläinen 
243dc8c77fcSVesa Jääskeläinen 	ctx = proc->extra_ctx;
244dc8c77fcSVesa Jääskeläinen 
245dc8c77fcSVesa Jääskeläinen 	ctx->hash_alg = hash;
246dc8c77fcSVesa Jääskeläinen 	ctx->mgf_type = mgf;
247dc8c77fcSVesa Jääskeläinen 	ctx->source_type = source_type;
248dc8c77fcSVesa Jääskeläinen 	ctx->source_data_len = source_size;
249dc8c77fcSVesa Jääskeläinen 	TEE_MemMove(ctx->source_data, source_data, source_size);
250dc8c77fcSVesa Jääskeläinen 
251dc8c77fcSVesa Jääskeläinen 	return PKCS11_CKR_OK;
252dc8c77fcSVesa Jääskeläinen }
253dc8c77fcSVesa Jääskeläinen 
254*45d40bdaSValerii Chubar enum pkcs11_rc
255*45d40bdaSValerii Chubar pkcs2tee_proc_params_rsa_aes_wrap(struct active_processing *proc,
256*45d40bdaSValerii Chubar 				  struct pkcs11_attribute_head *proc_params)
257*45d40bdaSValerii Chubar {
258*45d40bdaSValerii Chubar 	struct serialargs args = { };
259*45d40bdaSValerii Chubar 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
260*45d40bdaSValerii Chubar 	struct rsa_aes_key_wrap_processing_ctx *ctx = NULL;
261*45d40bdaSValerii Chubar 	uint32_t aes_key_bits = 0;
262*45d40bdaSValerii Chubar 	uint32_t hash = 0;
263*45d40bdaSValerii Chubar 	uint32_t mgf = 0;
264*45d40bdaSValerii Chubar 	uint32_t source_type = 0;
265*45d40bdaSValerii Chubar 	void *source_data = NULL;
266*45d40bdaSValerii Chubar 	uint32_t source_size = 0;
267*45d40bdaSValerii Chubar 
268*45d40bdaSValerii Chubar 	serialargs_init(&args, proc_params->data, proc_params->size);
269*45d40bdaSValerii Chubar 
270*45d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &aes_key_bits);
271*45d40bdaSValerii Chubar 	if (rc)
272*45d40bdaSValerii Chubar 		return rc;
273*45d40bdaSValerii Chubar 
274*45d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &hash);
275*45d40bdaSValerii Chubar 	if (rc)
276*45d40bdaSValerii Chubar 		return rc;
277*45d40bdaSValerii Chubar 
278*45d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &mgf);
279*45d40bdaSValerii Chubar 	if (rc)
280*45d40bdaSValerii Chubar 		return rc;
281*45d40bdaSValerii Chubar 
282*45d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &source_type);
283*45d40bdaSValerii Chubar 	if (rc)
284*45d40bdaSValerii Chubar 		return rc;
285*45d40bdaSValerii Chubar 
286*45d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &source_size);
287*45d40bdaSValerii Chubar 	if (rc)
288*45d40bdaSValerii Chubar 		return rc;
289*45d40bdaSValerii Chubar 
290*45d40bdaSValerii Chubar 	rc = serialargs_get_ptr(&args, &source_data, source_size);
291*45d40bdaSValerii Chubar 	if (rc)
292*45d40bdaSValerii Chubar 		return rc;
293*45d40bdaSValerii Chubar 
294*45d40bdaSValerii Chubar 	if (serialargs_remaining_bytes(&args))
295*45d40bdaSValerii Chubar 		return PKCS11_CKR_ARGUMENTS_BAD;
296*45d40bdaSValerii Chubar 
297*45d40bdaSValerii Chubar 	proc->extra_ctx =
298*45d40bdaSValerii Chubar 		TEE_Malloc(sizeof(struct rsa_aes_key_wrap_processing_ctx) +
299*45d40bdaSValerii Chubar 			   source_size,
300*45d40bdaSValerii Chubar 			   TEE_USER_MEM_HINT_NO_FILL_ZERO);
301*45d40bdaSValerii Chubar 	if (!proc->extra_ctx)
302*45d40bdaSValerii Chubar 		return PKCS11_CKR_DEVICE_MEMORY;
303*45d40bdaSValerii Chubar 
304*45d40bdaSValerii Chubar 	ctx = proc->extra_ctx;
305*45d40bdaSValerii Chubar 
306*45d40bdaSValerii Chubar 	ctx->aes_key_bits = aes_key_bits;
307*45d40bdaSValerii Chubar 	ctx->hash_alg = hash;
308*45d40bdaSValerii Chubar 	ctx->mgf_type = mgf;
309*45d40bdaSValerii Chubar 	ctx->source_type = source_type;
310*45d40bdaSValerii Chubar 	ctx->source_data_len = source_size;
311*45d40bdaSValerii Chubar 	TEE_MemMove(ctx->source_data, source_data, source_size);
312*45d40bdaSValerii Chubar 
313*45d40bdaSValerii Chubar 	return PKCS11_CKR_OK;
314*45d40bdaSValerii Chubar }
315*45d40bdaSValerii Chubar 
316dc8c77fcSVesa Jääskeläinen /*
317dc8c77fcSVesa Jääskeläinen  * Set TEE RSA OAEP algorithm identifier upon PKCS11 mechanism parameters
318dc8c77fcSVesa Jääskeläinen  * @tee_id: output TEE RSA OAEP algorithm identifier
319dc8c77fcSVesa Jääskeläinen  * @tee_hash_id: output TEE hash algorithm identifier
320dc8c77fcSVesa Jääskeläinen  * @proc_params: PKCS11 processing parameters
321dc8c77fcSVesa Jääskeläinen  */
322dc8c77fcSVesa Jääskeläinen enum pkcs11_rc
323dc8c77fcSVesa Jääskeläinen pkcs2tee_algo_rsa_oaep(uint32_t *tee_id, uint32_t *tee_hash_id,
324dc8c77fcSVesa Jääskeläinen 		       struct pkcs11_attribute_head *proc_params)
325dc8c77fcSVesa Jääskeläinen {
326dc8c77fcSVesa Jääskeläinen 	struct serialargs args = { };
327dc8c77fcSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
328dc8c77fcSVesa Jääskeläinen 	uint32_t hash = 0;
329dc8c77fcSVesa Jääskeläinen 	uint32_t mgf = 0;
330dc8c77fcSVesa Jääskeläinen 	uint32_t source_type = 0;
331dc8c77fcSVesa Jääskeläinen 	void *source_data = NULL;
332dc8c77fcSVesa Jääskeläinen 	uint32_t source_size = 0;
333dc8c77fcSVesa Jääskeläinen 
334dc8c77fcSVesa Jääskeläinen 	serialargs_init(&args, proc_params->data, proc_params->size);
335dc8c77fcSVesa Jääskeläinen 
336dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &hash);
337dc8c77fcSVesa Jääskeläinen 	if (rc)
338dc8c77fcSVesa Jääskeläinen 		return rc;
339dc8c77fcSVesa Jääskeläinen 
340dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &mgf);
341dc8c77fcSVesa Jääskeläinen 	if (rc)
342dc8c77fcSVesa Jääskeläinen 		return rc;
343dc8c77fcSVesa Jääskeläinen 
344dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &source_type);
345dc8c77fcSVesa Jääskeläinen 	if (rc)
346dc8c77fcSVesa Jääskeläinen 		return rc;
347dc8c77fcSVesa Jääskeläinen 
348dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &source_size);
349dc8c77fcSVesa Jääskeläinen 	if (rc)
350dc8c77fcSVesa Jääskeläinen 		return rc;
351dc8c77fcSVesa Jääskeläinen 
352dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_ptr(&args, &source_data, source_size);
353dc8c77fcSVesa Jääskeläinen 	if (rc)
354dc8c77fcSVesa Jääskeläinen 		return rc;
355dc8c77fcSVesa Jääskeläinen 
356dc8c77fcSVesa Jääskeläinen 	if (serialargs_remaining_bytes(&args))
357dc8c77fcSVesa Jääskeläinen 		return PKCS11_CKR_ARGUMENTS_BAD;
358dc8c77fcSVesa Jääskeläinen 
359dc8c77fcSVesa Jääskeläinen 	if (source_type != PKCS11_CKZ_DATA_SPECIFIED)
360dc8c77fcSVesa Jääskeläinen 		return PKCS11_CKR_MECHANISM_PARAM_INVALID;
361dc8c77fcSVesa Jääskeläinen 
362dc8c77fcSVesa Jääskeläinen 	switch (proc_params->id) {
363dc8c77fcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_OAEP:
364dc8c77fcSVesa Jääskeläinen 		switch (hash) {
365dc8c77fcSVesa Jääskeläinen 		case PKCS11_CKM_SHA_1:
366dc8c77fcSVesa Jääskeläinen 			if (mgf != PKCS11_CKG_MGF1_SHA1)
367dc8c77fcSVesa Jääskeläinen 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
368dc8c77fcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1;
369dc8c77fcSVesa Jääskeläinen 			*tee_hash_id = TEE_ALG_SHA1;
370dc8c77fcSVesa Jääskeläinen 			break;
371dc8c77fcSVesa Jääskeläinen 		case PKCS11_CKM_SHA224:
372dc8c77fcSVesa Jääskeläinen 			if (mgf != PKCS11_CKG_MGF1_SHA224)
373dc8c77fcSVesa Jääskeläinen 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
374dc8c77fcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224;
375dc8c77fcSVesa Jääskeläinen 			*tee_hash_id = TEE_ALG_SHA224;
376dc8c77fcSVesa Jääskeläinen 			break;
377dc8c77fcSVesa Jääskeläinen 		case PKCS11_CKM_SHA256:
378dc8c77fcSVesa Jääskeläinen 			if (mgf != PKCS11_CKG_MGF1_SHA256)
379dc8c77fcSVesa Jääskeläinen 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
380dc8c77fcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256;
381dc8c77fcSVesa Jääskeläinen 			*tee_hash_id = TEE_ALG_SHA256;
382dc8c77fcSVesa Jääskeläinen 			break;
383dc8c77fcSVesa Jääskeläinen 		case PKCS11_CKM_SHA384:
384dc8c77fcSVesa Jääskeläinen 			if (mgf != PKCS11_CKG_MGF1_SHA384)
385dc8c77fcSVesa Jääskeläinen 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
386dc8c77fcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384;
387dc8c77fcSVesa Jääskeläinen 			*tee_hash_id = TEE_ALG_SHA384;
388dc8c77fcSVesa Jääskeläinen 			break;
389dc8c77fcSVesa Jääskeläinen 		case PKCS11_CKM_SHA512:
390dc8c77fcSVesa Jääskeläinen 			if (mgf != PKCS11_CKG_MGF1_SHA512)
391dc8c77fcSVesa Jääskeläinen 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
392dc8c77fcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512;
393dc8c77fcSVesa Jääskeläinen 			*tee_hash_id = TEE_ALG_SHA512;
394dc8c77fcSVesa Jääskeläinen 			break;
395dc8c77fcSVesa Jääskeläinen 		default:
396dc8c77fcSVesa Jääskeläinen 			EMSG("Unexpected %#"PRIx32"/%s", hash,
397dc8c77fcSVesa Jääskeläinen 			     id2str_proc(hash));
398dc8c77fcSVesa Jääskeläinen 
399dc8c77fcSVesa Jääskeläinen 			return PKCS11_CKR_GENERAL_ERROR;
400dc8c77fcSVesa Jääskeläinen 		}
401dc8c77fcSVesa Jääskeläinen 		break;
402dc8c77fcSVesa Jääskeläinen 	default:
403dc8c77fcSVesa Jääskeläinen 		EMSG("Unexpected mechanism %#"PRIx32"/%s", proc_params->id,
404dc8c77fcSVesa Jääskeläinen 		     id2str_proc(proc_params->id));
405dc8c77fcSVesa Jääskeläinen 
406dc8c77fcSVesa Jääskeläinen 		return PKCS11_CKR_GENERAL_ERROR;
407dc8c77fcSVesa Jääskeläinen 	}
408dc8c77fcSVesa Jääskeläinen 
409dc8c77fcSVesa Jääskeläinen 	return PKCS11_CKR_OK;
410dc8c77fcSVesa Jääskeläinen }
411dc8c77fcSVesa Jääskeläinen 
412*45d40bdaSValerii Chubar enum pkcs11_rc
413*45d40bdaSValerii Chubar pkcs2tee_algo_rsa_aes_wrap(uint32_t *tee_id, uint32_t *tee_hash_id,
414*45d40bdaSValerii Chubar 			   struct pkcs11_attribute_head *proc_params)
415*45d40bdaSValerii Chubar {
416*45d40bdaSValerii Chubar 	struct serialargs args = { };
417*45d40bdaSValerii Chubar 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
418*45d40bdaSValerii Chubar 	uint32_t aes_key_bits = 0;
419*45d40bdaSValerii Chubar 	uint32_t hash = 0;
420*45d40bdaSValerii Chubar 	uint32_t mgf = 0;
421*45d40bdaSValerii Chubar 	uint32_t source_type = 0;
422*45d40bdaSValerii Chubar 	void *source_data = NULL;
423*45d40bdaSValerii Chubar 	uint32_t source_size = 0;
424*45d40bdaSValerii Chubar 
425*45d40bdaSValerii Chubar 	serialargs_init(&args, proc_params->data, proc_params->size);
426*45d40bdaSValerii Chubar 
427*45d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &aes_key_bits);
428*45d40bdaSValerii Chubar 	if (rc)
429*45d40bdaSValerii Chubar 		return rc;
430*45d40bdaSValerii Chubar 
431*45d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &hash);
432*45d40bdaSValerii Chubar 	if (rc)
433*45d40bdaSValerii Chubar 		return rc;
434*45d40bdaSValerii Chubar 
435*45d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &mgf);
436*45d40bdaSValerii Chubar 	if (rc)
437*45d40bdaSValerii Chubar 		return rc;
438*45d40bdaSValerii Chubar 
439*45d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &source_type);
440*45d40bdaSValerii Chubar 	if (rc)
441*45d40bdaSValerii Chubar 		return rc;
442*45d40bdaSValerii Chubar 
443*45d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &source_size);
444*45d40bdaSValerii Chubar 	if (rc)
445*45d40bdaSValerii Chubar 		return rc;
446*45d40bdaSValerii Chubar 
447*45d40bdaSValerii Chubar 	rc = serialargs_get_ptr(&args, &source_data, source_size);
448*45d40bdaSValerii Chubar 	if (rc)
449*45d40bdaSValerii Chubar 		return rc;
450*45d40bdaSValerii Chubar 
451*45d40bdaSValerii Chubar 	if (serialargs_remaining_bytes(&args))
452*45d40bdaSValerii Chubar 		return PKCS11_CKR_ARGUMENTS_BAD;
453*45d40bdaSValerii Chubar 
454*45d40bdaSValerii Chubar 	if (source_type != PKCS11_CKZ_DATA_SPECIFIED)
455*45d40bdaSValerii Chubar 		return PKCS11_CKR_MECHANISM_PARAM_INVALID;
456*45d40bdaSValerii Chubar 
457*45d40bdaSValerii Chubar 	switch (proc_params->id) {
458*45d40bdaSValerii Chubar 	case PKCS11_CKM_RSA_AES_KEY_WRAP:
459*45d40bdaSValerii Chubar 		switch (hash) {
460*45d40bdaSValerii Chubar 		case PKCS11_CKM_SHA_1:
461*45d40bdaSValerii Chubar 			if (mgf != PKCS11_CKG_MGF1_SHA1)
462*45d40bdaSValerii Chubar 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
463*45d40bdaSValerii Chubar 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1;
464*45d40bdaSValerii Chubar 			*tee_hash_id = TEE_ALG_SHA1;
465*45d40bdaSValerii Chubar 			break;
466*45d40bdaSValerii Chubar 		case PKCS11_CKM_SHA224:
467*45d40bdaSValerii Chubar 			if (mgf != PKCS11_CKG_MGF1_SHA224)
468*45d40bdaSValerii Chubar 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
469*45d40bdaSValerii Chubar 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224;
470*45d40bdaSValerii Chubar 			*tee_hash_id = TEE_ALG_SHA224;
471*45d40bdaSValerii Chubar 			break;
472*45d40bdaSValerii Chubar 		case PKCS11_CKM_SHA256:
473*45d40bdaSValerii Chubar 			if (mgf != PKCS11_CKG_MGF1_SHA256)
474*45d40bdaSValerii Chubar 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
475*45d40bdaSValerii Chubar 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256;
476*45d40bdaSValerii Chubar 			*tee_hash_id = TEE_ALG_SHA256;
477*45d40bdaSValerii Chubar 			break;
478*45d40bdaSValerii Chubar 		case PKCS11_CKM_SHA384:
479*45d40bdaSValerii Chubar 			if (mgf != PKCS11_CKG_MGF1_SHA384)
480*45d40bdaSValerii Chubar 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
481*45d40bdaSValerii Chubar 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384;
482*45d40bdaSValerii Chubar 			*tee_hash_id = TEE_ALG_SHA384;
483*45d40bdaSValerii Chubar 			break;
484*45d40bdaSValerii Chubar 		case PKCS11_CKM_SHA512:
485*45d40bdaSValerii Chubar 			if (mgf != PKCS11_CKG_MGF1_SHA512)
486*45d40bdaSValerii Chubar 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
487*45d40bdaSValerii Chubar 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512;
488*45d40bdaSValerii Chubar 			*tee_hash_id = TEE_ALG_SHA512;
489*45d40bdaSValerii Chubar 			break;
490*45d40bdaSValerii Chubar 		default:
491*45d40bdaSValerii Chubar 			EMSG("Unexpected %#"PRIx32"/%s", hash,
492*45d40bdaSValerii Chubar 			     id2str_proc(hash));
493*45d40bdaSValerii Chubar 
494*45d40bdaSValerii Chubar 			return PKCS11_CKR_GENERAL_ERROR;
495*45d40bdaSValerii Chubar 		}
496*45d40bdaSValerii Chubar 		break;
497*45d40bdaSValerii Chubar 	default:
498*45d40bdaSValerii Chubar 		EMSG("Unexpected mechanism %#"PRIx32"/%s", proc_params->id,
499*45d40bdaSValerii Chubar 		     id2str_proc(proc_params->id));
500*45d40bdaSValerii Chubar 
501*45d40bdaSValerii Chubar 		return PKCS11_CKR_GENERAL_ERROR;
502*45d40bdaSValerii Chubar 	}
503*45d40bdaSValerii Chubar 
504*45d40bdaSValerii Chubar 	return PKCS11_CKR_OK;
505*45d40bdaSValerii Chubar }
506*45d40bdaSValerii Chubar 
5070442c956SVesa Jääskeläinen enum pkcs11_rc load_tee_rsa_key_attrs(TEE_Attribute **tee_attrs,
5080442c956SVesa Jääskeläinen 				      size_t *tee_count,
5090442c956SVesa Jääskeläinen 				      struct pkcs11_object *obj)
5100442c956SVesa Jääskeläinen {
5110442c956SVesa Jääskeläinen 	TEE_Attribute *attrs = NULL;
5120442c956SVesa Jääskeläinen 	size_t count = 0;
5130442c956SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
5140442c956SVesa Jääskeläinen 	void *a_ptr = NULL;
5150442c956SVesa Jääskeläinen 
5160442c956SVesa Jääskeläinen 	assert(get_key_type(obj->attributes) == PKCS11_CKK_RSA);
5170442c956SVesa Jääskeläinen 
5180442c956SVesa Jääskeläinen 	switch (get_class(obj->attributes)) {
5190442c956SVesa Jääskeläinen 	case PKCS11_CKO_PUBLIC_KEY:
5200442c956SVesa Jääskeläinen 		attrs = TEE_Malloc(2 * sizeof(TEE_Attribute),
5210442c956SVesa Jääskeläinen 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
5220442c956SVesa Jääskeläinen 		if (!attrs)
5230442c956SVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
5240442c956SVesa Jääskeläinen 
5250442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS,
5260442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_MODULUS))
5270442c956SVesa Jääskeläinen 			count++;
5280442c956SVesa Jääskeläinen 
5290442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
5300442c956SVesa Jääskeläinen 				       TEE_ATTR_RSA_PUBLIC_EXPONENT, obj,
5310442c956SVesa Jääskeläinen 				       PKCS11_CKA_PUBLIC_EXPONENT))
5320442c956SVesa Jääskeläinen 			count++;
5330442c956SVesa Jääskeläinen 
5340442c956SVesa Jääskeläinen 		if (count == 2)
5350442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
5360442c956SVesa Jääskeläinen 
5370442c956SVesa Jääskeläinen 		break;
5380442c956SVesa Jääskeläinen 
5390442c956SVesa Jääskeläinen 	case PKCS11_CKO_PRIVATE_KEY:
5400442c956SVesa Jääskeläinen 		attrs = TEE_Malloc(8 * sizeof(TEE_Attribute),
5410442c956SVesa Jääskeläinen 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
5420442c956SVesa Jääskeläinen 		if (!attrs)
5430442c956SVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
5440442c956SVesa Jääskeläinen 
5450442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS,
5460442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_MODULUS))
5470442c956SVesa Jääskeläinen 			count++;
5480442c956SVesa Jääskeläinen 
5490442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
5500442c956SVesa Jääskeläinen 				       TEE_ATTR_RSA_PUBLIC_EXPONENT, obj,
5510442c956SVesa Jääskeläinen 				       PKCS11_CKA_PUBLIC_EXPONENT))
5520442c956SVesa Jääskeläinen 			count++;
5530442c956SVesa Jääskeläinen 
5540442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
5550442c956SVesa Jääskeläinen 				       TEE_ATTR_RSA_PRIVATE_EXPONENT, obj,
5560442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIVATE_EXPONENT))
5570442c956SVesa Jääskeläinen 			count++;
5580442c956SVesa Jääskeläinen 
5590442c956SVesa Jääskeläinen 		if (count != 3)
5600442c956SVesa Jääskeläinen 			break;
5610442c956SVesa Jääskeläinen 
5620442c956SVesa Jääskeläinen 		/* If pre-computed values are present load those */
5630442c956SVesa Jääskeläinen 		rc = get_attribute_ptr(obj->attributes, PKCS11_CKA_PRIME_1,
5640442c956SVesa Jääskeläinen 				       &a_ptr, NULL);
5650442c956SVesa Jääskeläinen 		if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
5660442c956SVesa Jääskeläinen 			break;
5670442c956SVesa Jääskeläinen 		if (rc == PKCS11_RV_NOT_FOUND || !a_ptr) {
5680442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
5690442c956SVesa Jääskeläinen 			break;
5700442c956SVesa Jääskeläinen 		}
5710442c956SVesa Jääskeläinen 
5720442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME1, obj,
5730442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIME_1))
5740442c956SVesa Jääskeläinen 			count++;
5750442c956SVesa Jääskeläinen 
5760442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME2, obj,
5770442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIME_2))
5780442c956SVesa Jääskeläinen 			count++;
5790442c956SVesa Jääskeläinen 
5800442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT1,
5810442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_EXPONENT_1))
5820442c956SVesa Jääskeläinen 			count++;
5830442c956SVesa Jääskeläinen 
5840442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT2,
5850442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_EXPONENT_2))
5860442c956SVesa Jääskeläinen 			count++;
5870442c956SVesa Jääskeläinen 
5880442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_COEFFICIENT,
5890442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_COEFFICIENT))
5900442c956SVesa Jääskeläinen 			count++;
5910442c956SVesa Jääskeläinen 
5920442c956SVesa Jääskeläinen 		if (count == 8)
5930442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
5940442c956SVesa Jääskeläinen 
5950442c956SVesa Jääskeläinen 		break;
5960442c956SVesa Jääskeläinen 
5970442c956SVesa Jääskeläinen 	default:
5980442c956SVesa Jääskeläinen 		assert(0);
5990442c956SVesa Jääskeläinen 		break;
6000442c956SVesa Jääskeläinen 	}
6010442c956SVesa Jääskeläinen 
6020442c956SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK) {
6030442c956SVesa Jääskeläinen 		*tee_attrs = attrs;
6040442c956SVesa Jääskeläinen 		*tee_count = count;
6050442c956SVesa Jääskeläinen 	} else {
6060442c956SVesa Jääskeläinen 		TEE_Free(attrs);
6070442c956SVesa Jääskeläinen 	}
6080442c956SVesa Jääskeläinen 
6090442c956SVesa Jääskeläinen 	return rc;
6100442c956SVesa Jääskeläinen }
6110442c956SVesa Jääskeläinen 
61286922832SVesa Jääskeläinen static enum pkcs11_rc tee2pkcs_rsa_attributes(struct obj_attrs **pub_head,
61386922832SVesa Jääskeläinen 					      struct obj_attrs **priv_head,
61486922832SVesa Jääskeläinen 					      TEE_ObjectHandle tee_obj)
61586922832SVesa Jääskeläinen {
61686922832SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
61786922832SVesa Jääskeläinen 	void *a_ptr = NULL;
61886922832SVesa Jääskeläinen 
61986922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_MODULUS, tee_obj,
62086922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_MODULUS);
62186922832SVesa Jääskeläinen 	if (rc)
62286922832SVesa Jääskeläinen 		goto out;
62386922832SVesa Jääskeläinen 
62486922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
62586922832SVesa Jääskeläinen 			       NULL);
62686922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
62786922832SVesa Jääskeläinen 		goto out;
62886922832SVesa Jääskeläinen 
62986922832SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK && !a_ptr) {
63086922832SVesa Jääskeläinen 		rc = remove_empty_attribute(pub_head,
63186922832SVesa Jääskeläinen 					    PKCS11_CKA_PUBLIC_EXPONENT);
63286922832SVesa Jääskeläinen 		if (rc)
63386922832SVesa Jääskeläinen 			goto out;
63486922832SVesa Jääskeläinen 		rc = PKCS11_RV_NOT_FOUND;
63586922832SVesa Jääskeläinen 	}
63686922832SVesa Jääskeläinen 
63786922832SVesa Jääskeläinen 	if (rc == PKCS11_RV_NOT_FOUND) {
63886922832SVesa Jääskeläinen 		rc = tee2pkcs_add_attribute(pub_head,
63986922832SVesa Jääskeläinen 					    PKCS11_CKA_PUBLIC_EXPONENT,
64086922832SVesa Jääskeläinen 					    tee_obj,
64186922832SVesa Jääskeläinen 					    TEE_ATTR_RSA_PUBLIC_EXPONENT);
64286922832SVesa Jääskeläinen 		if (rc)
64386922832SVesa Jääskeläinen 			goto out;
64486922832SVesa Jääskeläinen 	}
64586922832SVesa Jääskeläinen 
64686922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_MODULUS, tee_obj,
64786922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_MODULUS);
64886922832SVesa Jääskeläinen 	if (rc)
64986922832SVesa Jääskeläinen 		goto out;
65086922832SVesa Jääskeläinen 
65186922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT,
65286922832SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_RSA_PUBLIC_EXPONENT);
65386922832SVesa Jääskeläinen 	if (rc)
65486922832SVesa Jääskeläinen 		goto out;
65586922832SVesa Jääskeläinen 
65686922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT,
65786922832SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_RSA_PRIVATE_EXPONENT);
65886922832SVesa Jääskeläinen 	if (rc)
65986922832SVesa Jääskeläinen 		goto out;
66086922832SVesa Jääskeläinen 
66186922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_1, tee_obj,
66286922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_PRIME1);
66386922832SVesa Jääskeläinen 	if (rc)
66486922832SVesa Jääskeläinen 		goto out;
66586922832SVesa Jääskeläinen 
66686922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_2, tee_obj,
66786922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_PRIME2);
66886922832SVesa Jääskeläinen 	if (rc)
66986922832SVesa Jääskeläinen 		goto out;
67086922832SVesa Jääskeläinen 
67186922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_1, tee_obj,
67286922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_EXPONENT1);
67386922832SVesa Jääskeläinen 	if (rc)
67486922832SVesa Jääskeläinen 		goto out;
67586922832SVesa Jääskeläinen 
67686922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_2, tee_obj,
67786922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_EXPONENT2);
67886922832SVesa Jääskeläinen 	if (rc)
67986922832SVesa Jääskeläinen 		goto out;
68086922832SVesa Jääskeläinen 
68186922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_COEFFICIENT, tee_obj,
68286922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_COEFFICIENT);
68386922832SVesa Jääskeläinen out:
68486922832SVesa Jääskeläinen 	return rc;
68586922832SVesa Jääskeläinen }
68686922832SVesa Jääskeläinen 
68786922832SVesa Jääskeläinen enum pkcs11_rc generate_rsa_keys(struct pkcs11_attribute_head *proc_params,
68886922832SVesa Jääskeläinen 				 struct obj_attrs **pub_head,
68986922832SVesa Jääskeläinen 				 struct obj_attrs **priv_head)
69086922832SVesa Jääskeläinen {
69186922832SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
69286922832SVesa Jääskeläinen 	void *a_ptr = NULL;
69386922832SVesa Jääskeläinen 	uint32_t a_size = 0;
69486922832SVesa Jääskeläinen 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
69586922832SVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
69686922832SVesa Jääskeläinen 	uint32_t modulus_bits = 0;
69786922832SVesa Jääskeläinen 	TEE_Attribute tee_attrs[1] = { };
69886922832SVesa Jääskeläinen 	uint32_t tee_count = 0;
69986922832SVesa Jääskeläinen 
70086922832SVesa Jääskeläinen 	if (!proc_params || !*pub_head || !*priv_head)
70186922832SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
70286922832SVesa Jääskeläinen 
70386922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_MODULUS_BITS, &a_ptr,
70486922832SVesa Jääskeläinen 			       &a_size);
70586922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK || a_size != sizeof(uint32_t))
70686922832SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
70786922832SVesa Jääskeläinen 
70886922832SVesa Jääskeläinen 	TEE_MemMove(&modulus_bits, a_ptr, sizeof(uint32_t));
70986922832SVesa Jääskeläinen 
71086922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
71186922832SVesa Jääskeläinen 			       &a_size);
71286922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
71386922832SVesa Jääskeläinen 		return rc;
71486922832SVesa Jääskeläinen 
71586922832SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK && a_ptr) {
71686922832SVesa Jääskeläinen 		TEE_InitRefAttribute(&tee_attrs[tee_count],
71786922832SVesa Jääskeläinen 				     TEE_ATTR_RSA_PUBLIC_EXPONENT,
71886922832SVesa Jääskeläinen 				     a_ptr, a_size);
71986922832SVesa Jääskeläinen 		tee_count++;
72086922832SVesa Jääskeläinen 	}
72186922832SVesa Jääskeläinen 
72286922832SVesa Jääskeläinen 	if (remove_empty_attribute(priv_head, PKCS11_CKA_MODULUS) ||
72386922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT) ||
72486922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT) ||
72586922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_1) ||
72686922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_2) ||
72786922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_1) ||
72886922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_2) ||
72986922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_COEFFICIENT)) {
73086922832SVesa Jääskeläinen 		EMSG("Unexpected attribute(s) found");
73186922832SVesa Jääskeläinen 		rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
73286922832SVesa Jääskeläinen 		goto out;
73386922832SVesa Jääskeläinen 	}
73486922832SVesa Jääskeläinen 
73586922832SVesa Jääskeläinen 	/* Create an RSA TEE key */
73686922832SVesa Jääskeläinen 	res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, modulus_bits,
73786922832SVesa Jääskeläinen 					  &tee_obj);
73886922832SVesa Jääskeläinen 	if (res) {
73986922832SVesa Jääskeläinen 		DMSG("TEE_AllocateTransientObject failed %#"PRIx32, res);
74086922832SVesa Jääskeläinen 
74186922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
74286922832SVesa Jääskeläinen 		goto out;
74386922832SVesa Jääskeläinen 	}
74486922832SVesa Jääskeläinen 
74586922832SVesa Jääskeläinen 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
74686922832SVesa Jääskeläinen 	if (res) {
74786922832SVesa Jääskeläinen 		DMSG("TEE_RestrictObjectUsage1 failed %#"PRIx32, res);
74886922832SVesa Jääskeläinen 
74986922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
75086922832SVesa Jääskeläinen 		goto out;
75186922832SVesa Jääskeläinen 	}
75286922832SVesa Jääskeläinen 
75386922832SVesa Jääskeläinen 	res = TEE_GenerateKey(tee_obj, modulus_bits, tee_attrs, tee_count);
75486922832SVesa Jääskeläinen 	if (res) {
75586922832SVesa Jääskeläinen 		DMSG("TEE_GenerateKey failed %#"PRIx32, res);
75686922832SVesa Jääskeläinen 
75786922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
75886922832SVesa Jääskeläinen 		goto out;
75986922832SVesa Jääskeläinen 	}
76086922832SVesa Jääskeläinen 
76186922832SVesa Jääskeläinen 	rc = tee2pkcs_rsa_attributes(pub_head, priv_head, tee_obj);
76286922832SVesa Jääskeläinen 
76386922832SVesa Jääskeläinen out:
76486922832SVesa Jääskeläinen 	if (tee_obj != TEE_HANDLE_NULL)
76586922832SVesa Jääskeläinen 		TEE_CloseObject(tee_obj);
76686922832SVesa Jääskeläinen 
76786922832SVesa Jääskeläinen 	return rc;
76886922832SVesa Jääskeläinen }
7690442c956SVesa Jääskeläinen 
7700442c956SVesa Jääskeläinen size_t rsa_get_input_max_byte_size(TEE_OperationHandle op)
7710442c956SVesa Jääskeläinen {
7720442c956SVesa Jääskeläinen 	TEE_OperationInfo info = { };
7730442c956SVesa Jääskeläinen 
7740442c956SVesa Jääskeläinen 	TEE_GetOperationInfo(op, &info);
7750442c956SVesa Jääskeläinen 
7760442c956SVesa Jääskeläinen 	return info.maxKeySize / 8;
7770442c956SVesa Jääskeläinen }
778