xref: /optee_os/ta/pkcs11/src/processing_rsa.c (revision e02f17f374b6ce856b8569543e2066bfbaa64c59)
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 
25445d40bdaSValerii Chubar enum pkcs11_rc
25545d40bdaSValerii Chubar pkcs2tee_proc_params_rsa_aes_wrap(struct active_processing *proc,
25645d40bdaSValerii Chubar 				  struct pkcs11_attribute_head *proc_params)
25745d40bdaSValerii Chubar {
25845d40bdaSValerii Chubar 	struct serialargs args = { };
25945d40bdaSValerii Chubar 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
26045d40bdaSValerii Chubar 	struct rsa_aes_key_wrap_processing_ctx *ctx = NULL;
26145d40bdaSValerii Chubar 	uint32_t aes_key_bits = 0;
26245d40bdaSValerii Chubar 	uint32_t hash = 0;
26345d40bdaSValerii Chubar 	uint32_t mgf = 0;
26445d40bdaSValerii Chubar 	uint32_t source_type = 0;
26545d40bdaSValerii Chubar 	void *source_data = NULL;
26645d40bdaSValerii Chubar 	uint32_t source_size = 0;
26745d40bdaSValerii Chubar 
26845d40bdaSValerii Chubar 	serialargs_init(&args, proc_params->data, proc_params->size);
26945d40bdaSValerii Chubar 
27045d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &aes_key_bits);
27145d40bdaSValerii Chubar 	if (rc)
27245d40bdaSValerii Chubar 		return rc;
27345d40bdaSValerii Chubar 
27445d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &hash);
27545d40bdaSValerii Chubar 	if (rc)
27645d40bdaSValerii Chubar 		return rc;
27745d40bdaSValerii Chubar 
27845d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &mgf);
27945d40bdaSValerii Chubar 	if (rc)
28045d40bdaSValerii Chubar 		return rc;
28145d40bdaSValerii Chubar 
28245d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &source_type);
28345d40bdaSValerii Chubar 	if (rc)
28445d40bdaSValerii Chubar 		return rc;
28545d40bdaSValerii Chubar 
28645d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &source_size);
28745d40bdaSValerii Chubar 	if (rc)
28845d40bdaSValerii Chubar 		return rc;
28945d40bdaSValerii Chubar 
29045d40bdaSValerii Chubar 	rc = serialargs_get_ptr(&args, &source_data, source_size);
29145d40bdaSValerii Chubar 	if (rc)
29245d40bdaSValerii Chubar 		return rc;
29345d40bdaSValerii Chubar 
29445d40bdaSValerii Chubar 	if (serialargs_remaining_bytes(&args))
29545d40bdaSValerii Chubar 		return PKCS11_CKR_ARGUMENTS_BAD;
29645d40bdaSValerii Chubar 
29745d40bdaSValerii Chubar 	proc->extra_ctx =
29845d40bdaSValerii Chubar 		TEE_Malloc(sizeof(struct rsa_aes_key_wrap_processing_ctx) +
29945d40bdaSValerii Chubar 			   source_size,
30045d40bdaSValerii Chubar 			   TEE_USER_MEM_HINT_NO_FILL_ZERO);
30145d40bdaSValerii Chubar 	if (!proc->extra_ctx)
30245d40bdaSValerii Chubar 		return PKCS11_CKR_DEVICE_MEMORY;
30345d40bdaSValerii Chubar 
30445d40bdaSValerii Chubar 	ctx = proc->extra_ctx;
30545d40bdaSValerii Chubar 
30645d40bdaSValerii Chubar 	ctx->aes_key_bits = aes_key_bits;
30745d40bdaSValerii Chubar 	ctx->hash_alg = hash;
30845d40bdaSValerii Chubar 	ctx->mgf_type = mgf;
30945d40bdaSValerii Chubar 	ctx->source_type = source_type;
31045d40bdaSValerii Chubar 	ctx->source_data_len = source_size;
31145d40bdaSValerii Chubar 	TEE_MemMove(ctx->source_data, source_data, source_size);
31245d40bdaSValerii Chubar 
31345d40bdaSValerii Chubar 	return PKCS11_CKR_OK;
31445d40bdaSValerii Chubar }
31545d40bdaSValerii 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 
41245d40bdaSValerii Chubar enum pkcs11_rc
41345d40bdaSValerii Chubar pkcs2tee_algo_rsa_aes_wrap(uint32_t *tee_id, uint32_t *tee_hash_id,
41445d40bdaSValerii Chubar 			   struct pkcs11_attribute_head *proc_params)
41545d40bdaSValerii Chubar {
41645d40bdaSValerii Chubar 	struct serialargs args = { };
41745d40bdaSValerii Chubar 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
41845d40bdaSValerii Chubar 	uint32_t aes_key_bits = 0;
41945d40bdaSValerii Chubar 	uint32_t hash = 0;
42045d40bdaSValerii Chubar 	uint32_t mgf = 0;
42145d40bdaSValerii Chubar 	uint32_t source_type = 0;
42245d40bdaSValerii Chubar 	void *source_data = NULL;
42345d40bdaSValerii Chubar 	uint32_t source_size = 0;
42445d40bdaSValerii Chubar 
42545d40bdaSValerii Chubar 	serialargs_init(&args, proc_params->data, proc_params->size);
42645d40bdaSValerii Chubar 
42745d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &aes_key_bits);
42845d40bdaSValerii Chubar 	if (rc)
42945d40bdaSValerii Chubar 		return rc;
43045d40bdaSValerii Chubar 
43145d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &hash);
43245d40bdaSValerii Chubar 	if (rc)
43345d40bdaSValerii Chubar 		return rc;
43445d40bdaSValerii Chubar 
43545d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &mgf);
43645d40bdaSValerii Chubar 	if (rc)
43745d40bdaSValerii Chubar 		return rc;
43845d40bdaSValerii Chubar 
43945d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &source_type);
44045d40bdaSValerii Chubar 	if (rc)
44145d40bdaSValerii Chubar 		return rc;
44245d40bdaSValerii Chubar 
44345d40bdaSValerii Chubar 	rc = serialargs_get_u32(&args, &source_size);
44445d40bdaSValerii Chubar 	if (rc)
44545d40bdaSValerii Chubar 		return rc;
44645d40bdaSValerii Chubar 
44745d40bdaSValerii Chubar 	rc = serialargs_get_ptr(&args, &source_data, source_size);
44845d40bdaSValerii Chubar 	if (rc)
44945d40bdaSValerii Chubar 		return rc;
45045d40bdaSValerii Chubar 
45145d40bdaSValerii Chubar 	if (serialargs_remaining_bytes(&args))
45245d40bdaSValerii Chubar 		return PKCS11_CKR_ARGUMENTS_BAD;
45345d40bdaSValerii Chubar 
45445d40bdaSValerii Chubar 	if (source_type != PKCS11_CKZ_DATA_SPECIFIED)
45545d40bdaSValerii Chubar 		return PKCS11_CKR_MECHANISM_PARAM_INVALID;
45645d40bdaSValerii Chubar 
45745d40bdaSValerii Chubar 	switch (proc_params->id) {
45845d40bdaSValerii Chubar 	case PKCS11_CKM_RSA_AES_KEY_WRAP:
45945d40bdaSValerii Chubar 		switch (hash) {
46045d40bdaSValerii Chubar 		case PKCS11_CKM_SHA_1:
46145d40bdaSValerii Chubar 			if (mgf != PKCS11_CKG_MGF1_SHA1)
46245d40bdaSValerii Chubar 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
46345d40bdaSValerii Chubar 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1;
46445d40bdaSValerii Chubar 			*tee_hash_id = TEE_ALG_SHA1;
46545d40bdaSValerii Chubar 			break;
46645d40bdaSValerii Chubar 		case PKCS11_CKM_SHA224:
46745d40bdaSValerii Chubar 			if (mgf != PKCS11_CKG_MGF1_SHA224)
46845d40bdaSValerii Chubar 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
46945d40bdaSValerii Chubar 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224;
47045d40bdaSValerii Chubar 			*tee_hash_id = TEE_ALG_SHA224;
47145d40bdaSValerii Chubar 			break;
47245d40bdaSValerii Chubar 		case PKCS11_CKM_SHA256:
47345d40bdaSValerii Chubar 			if (mgf != PKCS11_CKG_MGF1_SHA256)
47445d40bdaSValerii Chubar 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
47545d40bdaSValerii Chubar 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256;
47645d40bdaSValerii Chubar 			*tee_hash_id = TEE_ALG_SHA256;
47745d40bdaSValerii Chubar 			break;
47845d40bdaSValerii Chubar 		case PKCS11_CKM_SHA384:
47945d40bdaSValerii Chubar 			if (mgf != PKCS11_CKG_MGF1_SHA384)
48045d40bdaSValerii Chubar 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
48145d40bdaSValerii Chubar 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384;
48245d40bdaSValerii Chubar 			*tee_hash_id = TEE_ALG_SHA384;
48345d40bdaSValerii Chubar 			break;
48445d40bdaSValerii Chubar 		case PKCS11_CKM_SHA512:
48545d40bdaSValerii Chubar 			if (mgf != PKCS11_CKG_MGF1_SHA512)
48645d40bdaSValerii Chubar 				return PKCS11_CKR_MECHANISM_PARAM_INVALID;
48745d40bdaSValerii Chubar 			*tee_id = TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512;
48845d40bdaSValerii Chubar 			*tee_hash_id = TEE_ALG_SHA512;
48945d40bdaSValerii Chubar 			break;
49045d40bdaSValerii Chubar 		default:
49145d40bdaSValerii Chubar 			EMSG("Unexpected %#"PRIx32"/%s", hash,
49245d40bdaSValerii Chubar 			     id2str_proc(hash));
49345d40bdaSValerii Chubar 
49445d40bdaSValerii Chubar 			return PKCS11_CKR_GENERAL_ERROR;
49545d40bdaSValerii Chubar 		}
49645d40bdaSValerii Chubar 		break;
49745d40bdaSValerii Chubar 	default:
49845d40bdaSValerii Chubar 		EMSG("Unexpected mechanism %#"PRIx32"/%s", proc_params->id,
49945d40bdaSValerii Chubar 		     id2str_proc(proc_params->id));
50045d40bdaSValerii Chubar 
50145d40bdaSValerii Chubar 		return PKCS11_CKR_GENERAL_ERROR;
50245d40bdaSValerii Chubar 	}
50345d40bdaSValerii Chubar 
50445d40bdaSValerii Chubar 	return PKCS11_CKR_OK;
50545d40bdaSValerii Chubar }
50645d40bdaSValerii 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 
5723dc4089aSEtienne Carriere 		rc = PKCS11_CKR_GENERAL_ERROR;
5733dc4089aSEtienne Carriere 
5740442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME1, obj,
5750442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIME_1))
5760442c956SVesa Jääskeläinen 			count++;
5770442c956SVesa Jääskeläinen 
5780442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME2, obj,
5790442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIME_2))
5800442c956SVesa Jääskeläinen 			count++;
5810442c956SVesa Jääskeläinen 
5820442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT1,
5830442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_EXPONENT_1))
5840442c956SVesa Jääskeläinen 			count++;
5850442c956SVesa Jääskeläinen 
5860442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT2,
5870442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_EXPONENT_2))
5880442c956SVesa Jääskeläinen 			count++;
5890442c956SVesa Jääskeläinen 
5900442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_COEFFICIENT,
5910442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_COEFFICIENT))
5920442c956SVesa Jääskeläinen 			count++;
5930442c956SVesa Jääskeläinen 
5940442c956SVesa Jääskeläinen 		if (count == 8)
5950442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
5960442c956SVesa Jääskeläinen 
5970442c956SVesa Jääskeläinen 		break;
5980442c956SVesa Jääskeläinen 
5990442c956SVesa Jääskeläinen 	default:
6000442c956SVesa Jääskeläinen 		assert(0);
6010442c956SVesa Jääskeläinen 		break;
6020442c956SVesa Jääskeläinen 	}
6030442c956SVesa Jääskeläinen 
6040442c956SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK) {
6050442c956SVesa Jääskeläinen 		*tee_attrs = attrs;
6060442c956SVesa Jääskeläinen 		*tee_count = count;
6070442c956SVesa Jääskeläinen 	} else {
6080442c956SVesa Jääskeläinen 		TEE_Free(attrs);
6090442c956SVesa Jääskeläinen 	}
6100442c956SVesa Jääskeläinen 
6110442c956SVesa Jääskeläinen 	return rc;
6120442c956SVesa Jääskeläinen }
6130442c956SVesa Jääskeläinen 
61486922832SVesa Jääskeläinen static enum pkcs11_rc tee2pkcs_rsa_attributes(struct obj_attrs **pub_head,
61586922832SVesa Jääskeläinen 					      struct obj_attrs **priv_head,
61686922832SVesa Jääskeläinen 					      TEE_ObjectHandle tee_obj)
61786922832SVesa Jääskeläinen {
61886922832SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
61986922832SVesa Jääskeläinen 	void *a_ptr = NULL;
62086922832SVesa Jääskeläinen 
62186922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_MODULUS, tee_obj,
62286922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_MODULUS);
62386922832SVesa Jääskeläinen 	if (rc)
62486922832SVesa Jääskeläinen 		goto out;
62586922832SVesa Jääskeläinen 
62686922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
62786922832SVesa Jääskeläinen 			       NULL);
62886922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
62986922832SVesa Jääskeläinen 		goto out;
63086922832SVesa Jääskeläinen 
63186922832SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK && !a_ptr) {
63286922832SVesa Jääskeläinen 		rc = remove_empty_attribute(pub_head,
63386922832SVesa Jääskeläinen 					    PKCS11_CKA_PUBLIC_EXPONENT);
63486922832SVesa Jääskeläinen 		if (rc)
63586922832SVesa Jääskeläinen 			goto out;
63686922832SVesa Jääskeläinen 		rc = PKCS11_RV_NOT_FOUND;
63786922832SVesa Jääskeläinen 	}
63886922832SVesa Jääskeläinen 
63986922832SVesa Jääskeläinen 	if (rc == PKCS11_RV_NOT_FOUND) {
64086922832SVesa Jääskeläinen 		rc = tee2pkcs_add_attribute(pub_head,
64186922832SVesa Jääskeläinen 					    PKCS11_CKA_PUBLIC_EXPONENT,
64286922832SVesa Jääskeläinen 					    tee_obj,
64386922832SVesa Jääskeläinen 					    TEE_ATTR_RSA_PUBLIC_EXPONENT);
64486922832SVesa Jääskeläinen 		if (rc)
64586922832SVesa Jääskeläinen 			goto out;
64686922832SVesa Jääskeläinen 	}
64786922832SVesa Jääskeläinen 
64886922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_MODULUS, tee_obj,
64986922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_MODULUS);
65086922832SVesa Jääskeläinen 	if (rc)
65186922832SVesa Jääskeläinen 		goto out;
65286922832SVesa Jääskeläinen 
65386922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT,
65486922832SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_RSA_PUBLIC_EXPONENT);
65586922832SVesa Jääskeläinen 	if (rc)
65686922832SVesa Jääskeläinen 		goto out;
65786922832SVesa Jääskeläinen 
65886922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT,
65986922832SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_RSA_PRIVATE_EXPONENT);
66086922832SVesa Jääskeläinen 	if (rc)
66186922832SVesa Jääskeläinen 		goto out;
66286922832SVesa Jääskeläinen 
66386922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_1, tee_obj,
66486922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_PRIME1);
66586922832SVesa Jääskeläinen 	if (rc)
66686922832SVesa Jääskeläinen 		goto out;
66786922832SVesa Jääskeläinen 
66886922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_2, tee_obj,
66986922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_PRIME2);
67086922832SVesa Jääskeläinen 	if (rc)
67186922832SVesa Jääskeläinen 		goto out;
67286922832SVesa Jääskeläinen 
67386922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_1, tee_obj,
67486922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_EXPONENT1);
67586922832SVesa Jääskeläinen 	if (rc)
67686922832SVesa Jääskeläinen 		goto out;
67786922832SVesa Jääskeläinen 
67886922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_2, tee_obj,
67986922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_EXPONENT2);
68086922832SVesa Jääskeläinen 	if (rc)
68186922832SVesa Jääskeläinen 		goto out;
68286922832SVesa Jääskeläinen 
68386922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_COEFFICIENT, tee_obj,
68486922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_COEFFICIENT);
68586922832SVesa Jääskeläinen out:
68686922832SVesa Jääskeläinen 	return rc;
68786922832SVesa Jääskeläinen }
68886922832SVesa Jääskeläinen 
68986922832SVesa Jääskeläinen enum pkcs11_rc generate_rsa_keys(struct pkcs11_attribute_head *proc_params,
69086922832SVesa Jääskeläinen 				 struct obj_attrs **pub_head,
69186922832SVesa Jääskeläinen 				 struct obj_attrs **priv_head)
69286922832SVesa Jääskeläinen {
69386922832SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
69486922832SVesa Jääskeläinen 	void *a_ptr = NULL;
69586922832SVesa Jääskeläinen 	uint32_t a_size = 0;
69686922832SVesa Jääskeläinen 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
69786922832SVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
69886922832SVesa Jääskeläinen 	uint32_t modulus_bits = 0;
69986922832SVesa Jääskeläinen 	TEE_Attribute tee_attrs[1] = { };
70086922832SVesa Jääskeläinen 	uint32_t tee_count = 0;
70186922832SVesa Jääskeläinen 
70286922832SVesa Jääskeläinen 	if (!proc_params || !*pub_head || !*priv_head)
70386922832SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
70486922832SVesa Jääskeläinen 
70586922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_MODULUS_BITS, &a_ptr,
70686922832SVesa Jääskeläinen 			       &a_size);
70786922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK || a_size != sizeof(uint32_t))
70886922832SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
70986922832SVesa Jääskeläinen 
71086922832SVesa Jääskeläinen 	TEE_MemMove(&modulus_bits, a_ptr, sizeof(uint32_t));
71186922832SVesa Jääskeläinen 
71286922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
71386922832SVesa Jääskeläinen 			       &a_size);
71486922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
71586922832SVesa Jääskeläinen 		return rc;
71686922832SVesa Jääskeläinen 
71786922832SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK && a_ptr) {
71886922832SVesa Jääskeläinen 		TEE_InitRefAttribute(&tee_attrs[tee_count],
71986922832SVesa Jääskeläinen 				     TEE_ATTR_RSA_PUBLIC_EXPONENT,
72086922832SVesa Jääskeläinen 				     a_ptr, a_size);
72186922832SVesa Jääskeläinen 		tee_count++;
72286922832SVesa Jääskeläinen 	}
72386922832SVesa Jääskeläinen 
72486922832SVesa Jääskeläinen 	if (remove_empty_attribute(priv_head, PKCS11_CKA_MODULUS) ||
72586922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT) ||
72686922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT) ||
72786922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_1) ||
72886922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_2) ||
72986922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_1) ||
73086922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_2) ||
73186922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_COEFFICIENT)) {
73286922832SVesa Jääskeläinen 		EMSG("Unexpected attribute(s) found");
73386922832SVesa Jääskeläinen 		rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
73486922832SVesa Jääskeläinen 		goto out;
73586922832SVesa Jääskeläinen 	}
73686922832SVesa Jääskeläinen 
73786922832SVesa Jääskeläinen 	/* Create an RSA TEE key */
73886922832SVesa Jääskeläinen 	res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, modulus_bits,
73986922832SVesa Jääskeläinen 					  &tee_obj);
74086922832SVesa Jääskeläinen 	if (res) {
74186922832SVesa Jääskeläinen 		DMSG("TEE_AllocateTransientObject failed %#"PRIx32, res);
74286922832SVesa Jääskeläinen 
74386922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
74486922832SVesa Jääskeläinen 		goto out;
74586922832SVesa Jääskeläinen 	}
74686922832SVesa Jääskeläinen 
74786922832SVesa Jääskeläinen 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
74886922832SVesa Jääskeläinen 	if (res) {
74986922832SVesa Jääskeläinen 		DMSG("TEE_RestrictObjectUsage1 failed %#"PRIx32, res);
75086922832SVesa Jääskeläinen 
75186922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
75286922832SVesa Jääskeläinen 		goto out;
75386922832SVesa Jääskeläinen 	}
75486922832SVesa Jääskeläinen 
75586922832SVesa Jääskeläinen 	res = TEE_GenerateKey(tee_obj, modulus_bits, tee_attrs, tee_count);
75686922832SVesa Jääskeläinen 	if (res) {
75786922832SVesa Jääskeläinen 		DMSG("TEE_GenerateKey failed %#"PRIx32, res);
75886922832SVesa Jääskeläinen 
75986922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
76086922832SVesa Jääskeläinen 		goto out;
76186922832SVesa Jääskeläinen 	}
76286922832SVesa Jääskeläinen 
76386922832SVesa Jääskeläinen 	rc = tee2pkcs_rsa_attributes(pub_head, priv_head, tee_obj);
76486922832SVesa Jääskeläinen 
76586922832SVesa Jääskeläinen out:
76686922832SVesa Jääskeläinen 	if (tee_obj != TEE_HANDLE_NULL)
76786922832SVesa Jääskeläinen 		TEE_CloseObject(tee_obj);
76886922832SVesa Jääskeläinen 
76986922832SVesa Jääskeläinen 	return rc;
77086922832SVesa Jääskeläinen }
7710442c956SVesa Jääskeläinen 
7720442c956SVesa Jääskeläinen size_t rsa_get_input_max_byte_size(TEE_OperationHandle op)
7730442c956SVesa Jääskeläinen {
7740442c956SVesa Jääskeläinen 	TEE_OperationInfo info = { };
7750442c956SVesa Jääskeläinen 
7760442c956SVesa Jääskeläinen 	TEE_GetOperationInfo(op, &info);
7770442c956SVesa Jääskeläinen 
7780442c956SVesa Jääskeläinen 	return info.maxKeySize / 8;
7790442c956SVesa Jääskeläinen }
780*e02f17f3SAlexandre Marechal 
781*e02f17f3SAlexandre Marechal enum pkcs11_rc pkcs2tee_rsa_nopad_context(struct active_processing *proc)
782*e02f17f3SAlexandre Marechal {
783*e02f17f3SAlexandre Marechal 	size_t key_size = 0;
784*e02f17f3SAlexandre Marechal 
785*e02f17f3SAlexandre Marechal 	/*
786*e02f17f3SAlexandre Marechal 	 * RSA no-pad (CKM_RSA_X_509) verify needs a buffer of the size
787*e02f17f3SAlexandre Marechal 	 * of the key to safely run.
788*e02f17f3SAlexandre Marechal 	 */
789*e02f17f3SAlexandre Marechal 	key_size = rsa_get_input_max_byte_size(proc->tee_op_handle);
790*e02f17f3SAlexandre Marechal 	if (!key_size)
791*e02f17f3SAlexandre Marechal 		return PKCS11_CKR_GENERAL_ERROR;
792*e02f17f3SAlexandre Marechal 
793*e02f17f3SAlexandre Marechal 	proc->extra_ctx = TEE_Malloc(key_size, TEE_USER_MEM_HINT_NO_FILL_ZERO);
794*e02f17f3SAlexandre Marechal 	if (!proc->extra_ctx)
795*e02f17f3SAlexandre Marechal 		return PKCS11_CKR_DEVICE_MEMORY;
796*e02f17f3SAlexandre Marechal 
797*e02f17f3SAlexandre Marechal 	return PKCS11_CKR_OK;
798*e02f17f3SAlexandre Marechal }
799