xref: /optee_os/ta/pkcs11/src/processing_rsa.c (revision dc8c77fcab32549c070544dd4944d4c3f874def3)
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 
199*dc8c77fcSVesa Jääskeläinen enum pkcs11_rc
200*dc8c77fcSVesa Jääskeläinen pkcs2tee_proc_params_rsa_oaep(struct active_processing *proc,
201*dc8c77fcSVesa Jääskeläinen 			      struct pkcs11_attribute_head *proc_params)
202*dc8c77fcSVesa Jääskeläinen {
203*dc8c77fcSVesa Jääskeläinen 	struct serialargs args = { };
204*dc8c77fcSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
205*dc8c77fcSVesa Jääskeläinen 	struct rsa_oaep_processing_ctx *ctx = NULL;
206*dc8c77fcSVesa Jääskeläinen 	uint32_t hash = 0;
207*dc8c77fcSVesa Jääskeläinen 	uint32_t mgf = 0;
208*dc8c77fcSVesa Jääskeläinen 	uint32_t source_type = 0;
209*dc8c77fcSVesa Jääskeläinen 	void *source_data = NULL;
210*dc8c77fcSVesa Jääskeläinen 	uint32_t source_size = 0;
211*dc8c77fcSVesa Jääskeläinen 
212*dc8c77fcSVesa Jääskeläinen 	serialargs_init(&args, proc_params->data, proc_params->size);
213*dc8c77fcSVesa Jääskeläinen 
214*dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &hash);
215*dc8c77fcSVesa Jääskeläinen 	if (rc)
216*dc8c77fcSVesa Jääskeläinen 		return rc;
217*dc8c77fcSVesa Jääskeläinen 
218*dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &mgf);
219*dc8c77fcSVesa Jääskeläinen 	if (rc)
220*dc8c77fcSVesa Jääskeläinen 		return rc;
221*dc8c77fcSVesa Jääskeläinen 
222*dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &source_type);
223*dc8c77fcSVesa Jääskeläinen 	if (rc)
224*dc8c77fcSVesa Jääskeläinen 		return rc;
225*dc8c77fcSVesa Jääskeläinen 
226*dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &source_size);
227*dc8c77fcSVesa Jääskeläinen 	if (rc)
228*dc8c77fcSVesa Jääskeläinen 		return rc;
229*dc8c77fcSVesa Jääskeläinen 
230*dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_ptr(&args, &source_data, source_size);
231*dc8c77fcSVesa Jääskeläinen 	if (rc)
232*dc8c77fcSVesa Jääskeläinen 		return rc;
233*dc8c77fcSVesa Jääskeläinen 
234*dc8c77fcSVesa Jääskeläinen 	if (serialargs_remaining_bytes(&args))
235*dc8c77fcSVesa Jääskeläinen 		return PKCS11_CKR_ARGUMENTS_BAD;
236*dc8c77fcSVesa Jääskeläinen 
237*dc8c77fcSVesa Jääskeläinen 	proc->extra_ctx = TEE_Malloc(sizeof(struct rsa_oaep_processing_ctx) +
238*dc8c77fcSVesa Jääskeläinen 				     source_size,
239*dc8c77fcSVesa Jääskeläinen 				     TEE_USER_MEM_HINT_NO_FILL_ZERO);
240*dc8c77fcSVesa Jääskeläinen 	if (!proc->extra_ctx)
241*dc8c77fcSVesa Jääskeläinen 		return PKCS11_CKR_DEVICE_MEMORY;
242*dc8c77fcSVesa Jääskeläinen 
243*dc8c77fcSVesa Jääskeläinen 	ctx = proc->extra_ctx;
244*dc8c77fcSVesa Jääskeläinen 
245*dc8c77fcSVesa Jääskeläinen 	ctx->hash_alg = hash;
246*dc8c77fcSVesa Jääskeläinen 	ctx->mgf_type = mgf;
247*dc8c77fcSVesa Jääskeläinen 	ctx->source_type = source_type;
248*dc8c77fcSVesa Jääskeläinen 	ctx->source_data_len = source_size;
249*dc8c77fcSVesa Jääskeläinen 	TEE_MemMove(ctx->source_data, source_data, source_size);
250*dc8c77fcSVesa Jääskeläinen 
251*dc8c77fcSVesa Jääskeläinen 	return PKCS11_CKR_OK;
252*dc8c77fcSVesa Jääskeläinen }
253*dc8c77fcSVesa Jääskeläinen 
254*dc8c77fcSVesa Jääskeläinen /*
255*dc8c77fcSVesa Jääskeläinen  * Set TEE RSA OAEP algorithm identifier upon PKCS11 mechanism parameters
256*dc8c77fcSVesa Jääskeläinen  * @tee_id: output TEE RSA OAEP algorithm identifier
257*dc8c77fcSVesa Jääskeläinen  * @tee_hash_id: output TEE hash algorithm identifier
258*dc8c77fcSVesa Jääskeläinen  * @proc_params: PKCS11 processing parameters
259*dc8c77fcSVesa Jääskeläinen  */
260*dc8c77fcSVesa Jääskeläinen enum pkcs11_rc
261*dc8c77fcSVesa Jääskeläinen pkcs2tee_algo_rsa_oaep(uint32_t *tee_id, uint32_t *tee_hash_id,
262*dc8c77fcSVesa Jääskeläinen 		       struct pkcs11_attribute_head *proc_params)
263*dc8c77fcSVesa Jääskeläinen {
264*dc8c77fcSVesa Jääskeläinen 	struct serialargs args = { };
265*dc8c77fcSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
266*dc8c77fcSVesa Jääskeläinen 	uint32_t hash = 0;
267*dc8c77fcSVesa Jääskeläinen 	uint32_t mgf = 0;
268*dc8c77fcSVesa Jääskeläinen 	uint32_t source_type = 0;
269*dc8c77fcSVesa Jääskeläinen 	void *source_data = NULL;
270*dc8c77fcSVesa Jääskeläinen 	uint32_t source_size = 0;
271*dc8c77fcSVesa Jääskeläinen 
272*dc8c77fcSVesa Jääskeläinen 	serialargs_init(&args, proc_params->data, proc_params->size);
273*dc8c77fcSVesa Jääskeläinen 
274*dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &hash);
275*dc8c77fcSVesa Jääskeläinen 	if (rc)
276*dc8c77fcSVesa Jääskeläinen 		return rc;
277*dc8c77fcSVesa Jääskeläinen 
278*dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &mgf);
279*dc8c77fcSVesa Jääskeläinen 	if (rc)
280*dc8c77fcSVesa Jääskeläinen 		return rc;
281*dc8c77fcSVesa Jääskeläinen 
282*dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &source_type);
283*dc8c77fcSVesa Jääskeläinen 	if (rc)
284*dc8c77fcSVesa Jääskeläinen 		return rc;
285*dc8c77fcSVesa Jääskeläinen 
286*dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &source_size);
287*dc8c77fcSVesa Jääskeläinen 	if (rc)
288*dc8c77fcSVesa Jääskeläinen 		return rc;
289*dc8c77fcSVesa Jääskeläinen 
290*dc8c77fcSVesa Jääskeläinen 	rc = serialargs_get_ptr(&args, &source_data, source_size);
291*dc8c77fcSVesa Jääskeläinen 	if (rc)
292*dc8c77fcSVesa Jääskeläinen 		return rc;
293*dc8c77fcSVesa Jääskeläinen 
294*dc8c77fcSVesa Jääskeläinen 	if (serialargs_remaining_bytes(&args))
295*dc8c77fcSVesa Jääskeläinen 		return PKCS11_CKR_ARGUMENTS_BAD;
296*dc8c77fcSVesa Jääskeläinen 
297*dc8c77fcSVesa Jääskeläinen 	if (source_type != PKCS11_CKZ_DATA_SPECIFIED)
298*dc8c77fcSVesa Jääskeläinen 		return PKCS11_CKR_MECHANISM_PARAM_INVALID;
299*dc8c77fcSVesa Jääskeläinen 
300*dc8c77fcSVesa Jääskeläinen 	switch (proc_params->id) {
301*dc8c77fcSVesa Jääskeläinen 	case PKCS11_CKM_RSA_PKCS_OAEP:
302*dc8c77fcSVesa Jääskeläinen 		switch (hash) {
303*dc8c77fcSVesa Jääskeläinen 		case PKCS11_CKM_SHA_1:
304*dc8c77fcSVesa Jääskeläinen 			if (mgf != PKCS11_CKG_MGF1_SHA1)
305*dc8c77fcSVesa Jääskeläinen 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
306*dc8c77fcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1;
307*dc8c77fcSVesa Jääskeläinen 			*tee_hash_id = TEE_ALG_SHA1;
308*dc8c77fcSVesa Jääskeläinen 			break;
309*dc8c77fcSVesa Jääskeläinen 		case PKCS11_CKM_SHA224:
310*dc8c77fcSVesa Jääskeläinen 			if (mgf != PKCS11_CKG_MGF1_SHA224)
311*dc8c77fcSVesa Jääskeläinen 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
312*dc8c77fcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224;
313*dc8c77fcSVesa Jääskeläinen 			*tee_hash_id = TEE_ALG_SHA224;
314*dc8c77fcSVesa Jääskeläinen 			break;
315*dc8c77fcSVesa Jääskeläinen 		case PKCS11_CKM_SHA256:
316*dc8c77fcSVesa Jääskeläinen 			if (mgf != PKCS11_CKG_MGF1_SHA256)
317*dc8c77fcSVesa Jääskeläinen 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
318*dc8c77fcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256;
319*dc8c77fcSVesa Jääskeläinen 			*tee_hash_id = TEE_ALG_SHA256;
320*dc8c77fcSVesa Jääskeläinen 			break;
321*dc8c77fcSVesa Jääskeläinen 		case PKCS11_CKM_SHA384:
322*dc8c77fcSVesa Jääskeläinen 			if (mgf != PKCS11_CKG_MGF1_SHA384)
323*dc8c77fcSVesa Jääskeläinen 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
324*dc8c77fcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384;
325*dc8c77fcSVesa Jääskeläinen 			*tee_hash_id = TEE_ALG_SHA384;
326*dc8c77fcSVesa Jääskeläinen 			break;
327*dc8c77fcSVesa Jääskeläinen 		case PKCS11_CKM_SHA512:
328*dc8c77fcSVesa Jääskeläinen 			if (mgf != PKCS11_CKG_MGF1_SHA512)
329*dc8c77fcSVesa Jääskeläinen 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
330*dc8c77fcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512;
331*dc8c77fcSVesa Jääskeläinen 			*tee_hash_id = TEE_ALG_SHA512;
332*dc8c77fcSVesa Jääskeläinen 			break;
333*dc8c77fcSVesa Jääskeläinen 		default:
334*dc8c77fcSVesa Jääskeläinen 			EMSG("Unexpected %#"PRIx32"/%s", hash,
335*dc8c77fcSVesa Jääskeläinen 			     id2str_proc(hash));
336*dc8c77fcSVesa Jääskeläinen 
337*dc8c77fcSVesa Jääskeläinen 			return PKCS11_CKR_GENERAL_ERROR;
338*dc8c77fcSVesa Jääskeläinen 		}
339*dc8c77fcSVesa Jääskeläinen 		break;
340*dc8c77fcSVesa Jääskeläinen 	default:
341*dc8c77fcSVesa Jääskeläinen 		EMSG("Unexpected mechanism %#"PRIx32"/%s", proc_params->id,
342*dc8c77fcSVesa Jääskeläinen 		     id2str_proc(proc_params->id));
343*dc8c77fcSVesa Jääskeläinen 
344*dc8c77fcSVesa Jääskeläinen 		return PKCS11_CKR_GENERAL_ERROR;
345*dc8c77fcSVesa Jääskeläinen 	}
346*dc8c77fcSVesa Jääskeläinen 
347*dc8c77fcSVesa Jääskeläinen 	return PKCS11_CKR_OK;
348*dc8c77fcSVesa Jääskeläinen }
349*dc8c77fcSVesa Jääskeläinen 
3500442c956SVesa Jääskeläinen enum pkcs11_rc load_tee_rsa_key_attrs(TEE_Attribute **tee_attrs,
3510442c956SVesa Jääskeläinen 				      size_t *tee_count,
3520442c956SVesa Jääskeläinen 				      struct pkcs11_object *obj)
3530442c956SVesa Jääskeläinen {
3540442c956SVesa Jääskeläinen 	TEE_Attribute *attrs = NULL;
3550442c956SVesa Jääskeläinen 	size_t count = 0;
3560442c956SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
3570442c956SVesa Jääskeläinen 	void *a_ptr = NULL;
3580442c956SVesa Jääskeläinen 
3590442c956SVesa Jääskeläinen 	assert(get_key_type(obj->attributes) == PKCS11_CKK_RSA);
3600442c956SVesa Jääskeläinen 
3610442c956SVesa Jääskeläinen 	switch (get_class(obj->attributes)) {
3620442c956SVesa Jääskeläinen 	case PKCS11_CKO_PUBLIC_KEY:
3630442c956SVesa Jääskeläinen 		attrs = TEE_Malloc(2 * sizeof(TEE_Attribute),
3640442c956SVesa Jääskeläinen 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
3650442c956SVesa Jääskeläinen 		if (!attrs)
3660442c956SVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
3670442c956SVesa Jääskeläinen 
3680442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS,
3690442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_MODULUS))
3700442c956SVesa Jääskeläinen 			count++;
3710442c956SVesa Jääskeläinen 
3720442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
3730442c956SVesa Jääskeläinen 				       TEE_ATTR_RSA_PUBLIC_EXPONENT, obj,
3740442c956SVesa Jääskeläinen 				       PKCS11_CKA_PUBLIC_EXPONENT))
3750442c956SVesa Jääskeläinen 			count++;
3760442c956SVesa Jääskeläinen 
3770442c956SVesa Jääskeläinen 		if (count == 2)
3780442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
3790442c956SVesa Jääskeläinen 
3800442c956SVesa Jääskeläinen 		break;
3810442c956SVesa Jääskeläinen 
3820442c956SVesa Jääskeläinen 	case PKCS11_CKO_PRIVATE_KEY:
3830442c956SVesa Jääskeläinen 		attrs = TEE_Malloc(8 * sizeof(TEE_Attribute),
3840442c956SVesa Jääskeläinen 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
3850442c956SVesa Jääskeläinen 		if (!attrs)
3860442c956SVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
3870442c956SVesa Jääskeläinen 
3880442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS,
3890442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_MODULUS))
3900442c956SVesa Jääskeläinen 			count++;
3910442c956SVesa Jääskeläinen 
3920442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
3930442c956SVesa Jääskeläinen 				       TEE_ATTR_RSA_PUBLIC_EXPONENT, obj,
3940442c956SVesa Jääskeläinen 				       PKCS11_CKA_PUBLIC_EXPONENT))
3950442c956SVesa Jääskeläinen 			count++;
3960442c956SVesa Jääskeläinen 
3970442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
3980442c956SVesa Jääskeläinen 				       TEE_ATTR_RSA_PRIVATE_EXPONENT, obj,
3990442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIVATE_EXPONENT))
4000442c956SVesa Jääskeläinen 			count++;
4010442c956SVesa Jääskeläinen 
4020442c956SVesa Jääskeläinen 		if (count != 3)
4030442c956SVesa Jääskeläinen 			break;
4040442c956SVesa Jääskeläinen 
4050442c956SVesa Jääskeläinen 		/* If pre-computed values are present load those */
4060442c956SVesa Jääskeläinen 		rc = get_attribute_ptr(obj->attributes, PKCS11_CKA_PRIME_1,
4070442c956SVesa Jääskeläinen 				       &a_ptr, NULL);
4080442c956SVesa Jääskeläinen 		if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
4090442c956SVesa Jääskeläinen 			break;
4100442c956SVesa Jääskeläinen 		if (rc == PKCS11_RV_NOT_FOUND || !a_ptr) {
4110442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
4120442c956SVesa Jääskeläinen 			break;
4130442c956SVesa Jääskeläinen 		}
4140442c956SVesa Jääskeläinen 
4150442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME1, obj,
4160442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIME_1))
4170442c956SVesa Jääskeläinen 			count++;
4180442c956SVesa Jääskeläinen 
4190442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME2, obj,
4200442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIME_2))
4210442c956SVesa Jääskeläinen 			count++;
4220442c956SVesa Jääskeläinen 
4230442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT1,
4240442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_EXPONENT_1))
4250442c956SVesa Jääskeläinen 			count++;
4260442c956SVesa Jääskeläinen 
4270442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT2,
4280442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_EXPONENT_2))
4290442c956SVesa Jääskeläinen 			count++;
4300442c956SVesa Jääskeläinen 
4310442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_COEFFICIENT,
4320442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_COEFFICIENT))
4330442c956SVesa Jääskeläinen 			count++;
4340442c956SVesa Jääskeläinen 
4350442c956SVesa Jääskeläinen 		if (count == 8)
4360442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
4370442c956SVesa Jääskeläinen 
4380442c956SVesa Jääskeläinen 		break;
4390442c956SVesa Jääskeläinen 
4400442c956SVesa Jääskeläinen 	default:
4410442c956SVesa Jääskeläinen 		assert(0);
4420442c956SVesa Jääskeläinen 		break;
4430442c956SVesa Jääskeläinen 	}
4440442c956SVesa Jääskeläinen 
4450442c956SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK) {
4460442c956SVesa Jääskeläinen 		*tee_attrs = attrs;
4470442c956SVesa Jääskeläinen 		*tee_count = count;
4480442c956SVesa Jääskeläinen 	} else {
4490442c956SVesa Jääskeläinen 		TEE_Free(attrs);
4500442c956SVesa Jääskeläinen 	}
4510442c956SVesa Jääskeläinen 
4520442c956SVesa Jääskeläinen 	return rc;
4530442c956SVesa Jääskeläinen }
4540442c956SVesa Jääskeläinen 
45586922832SVesa Jääskeläinen static enum pkcs11_rc tee2pkcs_rsa_attributes(struct obj_attrs **pub_head,
45686922832SVesa Jääskeläinen 					      struct obj_attrs **priv_head,
45786922832SVesa Jääskeläinen 					      TEE_ObjectHandle tee_obj)
45886922832SVesa Jääskeläinen {
45986922832SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
46086922832SVesa Jääskeläinen 	void *a_ptr = NULL;
46186922832SVesa Jääskeläinen 
46286922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_MODULUS, tee_obj,
46386922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_MODULUS);
46486922832SVesa Jääskeläinen 	if (rc)
46586922832SVesa Jääskeläinen 		goto out;
46686922832SVesa Jääskeläinen 
46786922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
46886922832SVesa Jääskeläinen 			       NULL);
46986922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
47086922832SVesa Jääskeläinen 		goto out;
47186922832SVesa Jääskeläinen 
47286922832SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK && !a_ptr) {
47386922832SVesa Jääskeläinen 		rc = remove_empty_attribute(pub_head,
47486922832SVesa Jääskeläinen 					    PKCS11_CKA_PUBLIC_EXPONENT);
47586922832SVesa Jääskeläinen 		if (rc)
47686922832SVesa Jääskeläinen 			goto out;
47786922832SVesa Jääskeläinen 		rc = PKCS11_RV_NOT_FOUND;
47886922832SVesa Jääskeläinen 	}
47986922832SVesa Jääskeläinen 
48086922832SVesa Jääskeläinen 	if (rc == PKCS11_RV_NOT_FOUND) {
48186922832SVesa Jääskeläinen 		rc = tee2pkcs_add_attribute(pub_head,
48286922832SVesa Jääskeläinen 					    PKCS11_CKA_PUBLIC_EXPONENT,
48386922832SVesa Jääskeläinen 					    tee_obj,
48486922832SVesa Jääskeläinen 					    TEE_ATTR_RSA_PUBLIC_EXPONENT);
48586922832SVesa Jääskeläinen 		if (rc)
48686922832SVesa Jääskeläinen 			goto out;
48786922832SVesa Jääskeläinen 	}
48886922832SVesa Jääskeläinen 
48986922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_MODULUS, tee_obj,
49086922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_MODULUS);
49186922832SVesa Jääskeläinen 	if (rc)
49286922832SVesa Jääskeläinen 		goto out;
49386922832SVesa Jääskeläinen 
49486922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT,
49586922832SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_RSA_PUBLIC_EXPONENT);
49686922832SVesa Jääskeläinen 	if (rc)
49786922832SVesa Jääskeläinen 		goto out;
49886922832SVesa Jääskeläinen 
49986922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT,
50086922832SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_RSA_PRIVATE_EXPONENT);
50186922832SVesa Jääskeläinen 	if (rc)
50286922832SVesa Jääskeläinen 		goto out;
50386922832SVesa Jääskeläinen 
50486922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_1, tee_obj,
50586922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_PRIME1);
50686922832SVesa Jääskeläinen 	if (rc)
50786922832SVesa Jääskeläinen 		goto out;
50886922832SVesa Jääskeläinen 
50986922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_2, tee_obj,
51086922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_PRIME2);
51186922832SVesa Jääskeläinen 	if (rc)
51286922832SVesa Jääskeläinen 		goto out;
51386922832SVesa Jääskeläinen 
51486922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_1, tee_obj,
51586922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_EXPONENT1);
51686922832SVesa Jääskeläinen 	if (rc)
51786922832SVesa Jääskeläinen 		goto out;
51886922832SVesa Jääskeläinen 
51986922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_2, tee_obj,
52086922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_EXPONENT2);
52186922832SVesa Jääskeläinen 	if (rc)
52286922832SVesa Jääskeläinen 		goto out;
52386922832SVesa Jääskeläinen 
52486922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_COEFFICIENT, tee_obj,
52586922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_COEFFICIENT);
52686922832SVesa Jääskeläinen out:
52786922832SVesa Jääskeläinen 	return rc;
52886922832SVesa Jääskeläinen }
52986922832SVesa Jääskeläinen 
53086922832SVesa Jääskeläinen enum pkcs11_rc generate_rsa_keys(struct pkcs11_attribute_head *proc_params,
53186922832SVesa Jääskeläinen 				 struct obj_attrs **pub_head,
53286922832SVesa Jääskeläinen 				 struct obj_attrs **priv_head)
53386922832SVesa Jääskeläinen {
53486922832SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
53586922832SVesa Jääskeläinen 	void *a_ptr = NULL;
53686922832SVesa Jääskeläinen 	uint32_t a_size = 0;
53786922832SVesa Jääskeläinen 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
53886922832SVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
53986922832SVesa Jääskeläinen 	uint32_t modulus_bits = 0;
54086922832SVesa Jääskeläinen 	TEE_Attribute tee_attrs[1] = { };
54186922832SVesa Jääskeläinen 	uint32_t tee_count = 0;
54286922832SVesa Jääskeläinen 
54386922832SVesa Jääskeläinen 	if (!proc_params || !*pub_head || !*priv_head)
54486922832SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
54586922832SVesa Jääskeläinen 
54686922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_MODULUS_BITS, &a_ptr,
54786922832SVesa Jääskeläinen 			       &a_size);
54886922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK || a_size != sizeof(uint32_t))
54986922832SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
55086922832SVesa Jääskeläinen 
55186922832SVesa Jääskeläinen 	TEE_MemMove(&modulus_bits, a_ptr, sizeof(uint32_t));
55286922832SVesa Jääskeläinen 
55386922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
55486922832SVesa Jääskeläinen 			       &a_size);
55586922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
55686922832SVesa Jääskeläinen 		return rc;
55786922832SVesa Jääskeläinen 
55886922832SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK && a_ptr) {
55986922832SVesa Jääskeläinen 		TEE_InitRefAttribute(&tee_attrs[tee_count],
56086922832SVesa Jääskeläinen 				     TEE_ATTR_RSA_PUBLIC_EXPONENT,
56186922832SVesa Jääskeläinen 				     a_ptr, a_size);
56286922832SVesa Jääskeläinen 		tee_count++;
56386922832SVesa Jääskeläinen 	}
56486922832SVesa Jääskeläinen 
56586922832SVesa Jääskeläinen 	if (remove_empty_attribute(priv_head, PKCS11_CKA_MODULUS) ||
56686922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT) ||
56786922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT) ||
56886922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_1) ||
56986922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_2) ||
57086922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_1) ||
57186922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_2) ||
57286922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_COEFFICIENT)) {
57386922832SVesa Jääskeläinen 		EMSG("Unexpected attribute(s) found");
57486922832SVesa Jääskeläinen 		rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
57586922832SVesa Jääskeläinen 		goto out;
57686922832SVesa Jääskeläinen 	}
57786922832SVesa Jääskeläinen 
57886922832SVesa Jääskeläinen 	/* Create an RSA TEE key */
57986922832SVesa Jääskeläinen 	res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, modulus_bits,
58086922832SVesa Jääskeläinen 					  &tee_obj);
58186922832SVesa Jääskeläinen 	if (res) {
58286922832SVesa Jääskeläinen 		DMSG("TEE_AllocateTransientObject failed %#"PRIx32, res);
58386922832SVesa Jääskeläinen 
58486922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
58586922832SVesa Jääskeläinen 		goto out;
58686922832SVesa Jääskeläinen 	}
58786922832SVesa Jääskeläinen 
58886922832SVesa Jääskeläinen 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
58986922832SVesa Jääskeläinen 	if (res) {
59086922832SVesa Jääskeläinen 		DMSG("TEE_RestrictObjectUsage1 failed %#"PRIx32, res);
59186922832SVesa Jääskeläinen 
59286922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
59386922832SVesa Jääskeläinen 		goto out;
59486922832SVesa Jääskeläinen 	}
59586922832SVesa Jääskeläinen 
59686922832SVesa Jääskeläinen 	res = TEE_GenerateKey(tee_obj, modulus_bits, tee_attrs, tee_count);
59786922832SVesa Jääskeläinen 	if (res) {
59886922832SVesa Jääskeläinen 		DMSG("TEE_GenerateKey failed %#"PRIx32, res);
59986922832SVesa Jääskeläinen 
60086922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
60186922832SVesa Jääskeläinen 		goto out;
60286922832SVesa Jääskeläinen 	}
60386922832SVesa Jääskeläinen 
60486922832SVesa Jääskeläinen 	rc = tee2pkcs_rsa_attributes(pub_head, priv_head, tee_obj);
60586922832SVesa Jääskeläinen 
60686922832SVesa Jääskeläinen out:
60786922832SVesa Jääskeläinen 	if (tee_obj != TEE_HANDLE_NULL)
60886922832SVesa Jääskeläinen 		TEE_CloseObject(tee_obj);
60986922832SVesa Jääskeläinen 
61086922832SVesa Jääskeläinen 	return rc;
61186922832SVesa Jääskeläinen }
6120442c956SVesa Jääskeläinen 
6130442c956SVesa Jääskeläinen size_t rsa_get_input_max_byte_size(TEE_OperationHandle op)
6140442c956SVesa Jääskeläinen {
6150442c956SVesa Jääskeläinen 	TEE_OperationInfo info = { };
6160442c956SVesa Jääskeläinen 
6170442c956SVesa Jääskeläinen 	TEE_GetOperationInfo(op, &info);
6180442c956SVesa Jääskeläinen 
6190442c956SVesa Jääskeläinen 	return info.maxKeySize / 8;
6200442c956SVesa Jääskeläinen }
621