xref: /optee_os/ta/pkcs11/src/processing_rsa.c (revision c2c23cd49c9f9d88d4fb25917fbb6b237a95f270)
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
pkcs2tee_proc_params_rsa_pss(struct active_processing * proc,struct pkcs11_attribute_head * proc_params)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 
pkcs2tee_validate_rsa_pss(struct active_processing * proc,struct pkcs11_object * obj)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
10404e46975SEtienne Carriere 		k = ROUNDUP_DIV(modulus_size, 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  */
pkcs2tee_algo_rsa_pss(uint32_t * tee_id,struct pkcs11_attribute_head * proc_params)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
pkcs2tee_proc_params_rsa_oaep(struct active_processing * proc,struct pkcs11_attribute_head * proc_params)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
pkcs2tee_proc_params_rsa_aes_wrap(struct active_processing * proc,struct pkcs11_attribute_head * proc_params)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
pkcs2tee_algo_rsa_oaep(uint32_t * tee_id,uint32_t * tee_hash_id,struct pkcs11_attribute_head * proc_params)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
pkcs2tee_algo_rsa_aes_wrap(uint32_t * tee_id,uint32_t * tee_hash_id,struct pkcs11_attribute_head * proc_params)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 
contains_all_rsa_crt_parameters(struct pkcs11_object * obj)507*c2c23cd4SEtienne Carriere static enum pkcs11_rc contains_all_rsa_crt_parameters(struct pkcs11_object *obj)
508*c2c23cd4SEtienne Carriere {
509*c2c23cd4SEtienne Carriere 	const uint32_t crt_attr[] = {
510*c2c23cd4SEtienne Carriere 		PKCS11_CKA_PRIME_1, PKCS11_CKA_PRIME_2, PKCS11_CKA_EXPONENT_1,
511*c2c23cd4SEtienne Carriere 		PKCS11_CKA_EXPONENT_2, PKCS11_CKA_COEFFICIENT,
512*c2c23cd4SEtienne Carriere 	};
513*c2c23cd4SEtienne Carriere 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
514*c2c23cd4SEtienne Carriere 	uint32_t a_size = 0;
515*c2c23cd4SEtienne Carriere 	void *a_ptr = NULL;
516*c2c23cd4SEtienne Carriere 	size_t count = 0;
517*c2c23cd4SEtienne Carriere 	size_t n = 0;
518*c2c23cd4SEtienne Carriere 
519*c2c23cd4SEtienne Carriere 	for (n = 0; n < ARRAY_SIZE(crt_attr); n++) {
520*c2c23cd4SEtienne Carriere 		rc = get_attribute_ptr(obj->attributes, crt_attr[n], &a_ptr,
521*c2c23cd4SEtienne Carriere 				       &a_size);
522*c2c23cd4SEtienne Carriere 		if (rc != PKCS11_CKR_OK)
523*c2c23cd4SEtienne Carriere 			return rc;
524*c2c23cd4SEtienne Carriere 		if (a_ptr && a_size)
525*c2c23cd4SEtienne Carriere 			count++;
526*c2c23cd4SEtienne Carriere 	}
527*c2c23cd4SEtienne Carriere 
528*c2c23cd4SEtienne Carriere 	if (count != ARRAY_SIZE(crt_attr))
529*c2c23cd4SEtienne Carriere 		return PKCS11_RV_NOT_FOUND;
530*c2c23cd4SEtienne Carriere 
531*c2c23cd4SEtienne Carriere 	return PKCS11_CKR_OK;
532*c2c23cd4SEtienne Carriere }
533*c2c23cd4SEtienne Carriere 
load_tee_rsa_key_attrs(TEE_Attribute ** tee_attrs,size_t * tee_count,struct pkcs11_object * obj)5340442c956SVesa Jääskeläinen enum pkcs11_rc load_tee_rsa_key_attrs(TEE_Attribute **tee_attrs,
5350442c956SVesa Jääskeläinen 				      size_t *tee_count,
5360442c956SVesa Jääskeläinen 				      struct pkcs11_object *obj)
5370442c956SVesa Jääskeläinen {
5380442c956SVesa Jääskeläinen 	TEE_Attribute *attrs = NULL;
5390442c956SVesa Jääskeläinen 	size_t count = 0;
5400442c956SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
5410442c956SVesa Jääskeläinen 
5420442c956SVesa Jääskeläinen 	assert(get_key_type(obj->attributes) == PKCS11_CKK_RSA);
5430442c956SVesa Jääskeläinen 
5440442c956SVesa Jääskeläinen 	switch (get_class(obj->attributes)) {
5450442c956SVesa Jääskeläinen 	case PKCS11_CKO_PUBLIC_KEY:
5460442c956SVesa Jääskeläinen 		attrs = TEE_Malloc(2 * sizeof(TEE_Attribute),
5470442c956SVesa Jääskeläinen 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
5480442c956SVesa Jääskeläinen 		if (!attrs)
5490442c956SVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
5500442c956SVesa Jääskeläinen 
5510442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS,
5520442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_MODULUS))
5530442c956SVesa Jääskeläinen 			count++;
5540442c956SVesa Jääskeläinen 
5550442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
5560442c956SVesa Jääskeläinen 				       TEE_ATTR_RSA_PUBLIC_EXPONENT, obj,
5570442c956SVesa Jääskeläinen 				       PKCS11_CKA_PUBLIC_EXPONENT))
5580442c956SVesa Jääskeläinen 			count++;
5590442c956SVesa Jääskeläinen 
5600442c956SVesa Jääskeläinen 		if (count == 2)
5610442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
5620442c956SVesa Jääskeläinen 
5630442c956SVesa Jääskeläinen 		break;
5640442c956SVesa Jääskeläinen 
5650442c956SVesa Jääskeläinen 	case PKCS11_CKO_PRIVATE_KEY:
5660442c956SVesa Jääskeläinen 		attrs = TEE_Malloc(8 * sizeof(TEE_Attribute),
5670442c956SVesa Jääskeläinen 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
5680442c956SVesa Jääskeläinen 		if (!attrs)
5690442c956SVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
5700442c956SVesa Jääskeläinen 
5710442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS,
5720442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_MODULUS))
5730442c956SVesa Jääskeläinen 			count++;
5740442c956SVesa Jääskeläinen 
5750442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
5760442c956SVesa Jääskeläinen 				       TEE_ATTR_RSA_PUBLIC_EXPONENT, obj,
5770442c956SVesa Jääskeläinen 				       PKCS11_CKA_PUBLIC_EXPONENT))
5780442c956SVesa Jääskeläinen 			count++;
5790442c956SVesa Jääskeläinen 
5800442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
5810442c956SVesa Jääskeläinen 				       TEE_ATTR_RSA_PRIVATE_EXPONENT, obj,
5820442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIVATE_EXPONENT))
5830442c956SVesa Jääskeläinen 			count++;
5840442c956SVesa Jääskeläinen 
5850442c956SVesa Jääskeläinen 		if (count != 3)
5860442c956SVesa Jääskeläinen 			break;
5870442c956SVesa Jääskeläinen 
588*c2c23cd4SEtienne Carriere 		/*
589*c2c23cd4SEtienne Carriere 		 * If the pre-computed CRT parameters are present load them
590*c2c23cd4SEtienne Carriere 		 * but only if they are all present since the GP TEE
591*c2c23cd4SEtienne Carriere 		 * specification expects either the 5 are present
592*c2c23cd4SEtienne Carriere 		 * or none is present.
593*c2c23cd4SEtienne Carriere 		 */
594*c2c23cd4SEtienne Carriere 		rc = contains_all_rsa_crt_parameters(obj);
595*c2c23cd4SEtienne Carriere 		if (rc != PKCS11_CKR_OK) {
596*c2c23cd4SEtienne Carriere 			if (rc == PKCS11_RV_NOT_FOUND)
5970442c956SVesa Jääskeläinen 				rc = PKCS11_CKR_OK;
5980442c956SVesa Jääskeläinen 			break;
5990442c956SVesa Jääskeläinen 		}
6000442c956SVesa Jääskeläinen 
6013dc4089aSEtienne Carriere 		rc = PKCS11_CKR_GENERAL_ERROR;
6023dc4089aSEtienne Carriere 
6030442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME1, obj,
6040442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIME_1))
6050442c956SVesa Jääskeläinen 			count++;
6060442c956SVesa Jääskeläinen 
6070442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME2, obj,
6080442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIME_2))
6090442c956SVesa Jääskeläinen 			count++;
6100442c956SVesa Jääskeläinen 
6110442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT1,
6120442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_EXPONENT_1))
6130442c956SVesa Jääskeläinen 			count++;
6140442c956SVesa Jääskeläinen 
6150442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT2,
6160442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_EXPONENT_2))
6170442c956SVesa Jääskeläinen 			count++;
6180442c956SVesa Jääskeläinen 
6190442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_COEFFICIENT,
6200442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_COEFFICIENT))
6210442c956SVesa Jääskeläinen 			count++;
6220442c956SVesa Jääskeläinen 
6230442c956SVesa Jääskeläinen 		if (count == 8)
6240442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
6250442c956SVesa Jääskeläinen 
6260442c956SVesa Jääskeläinen 		break;
6270442c956SVesa Jääskeläinen 
6280442c956SVesa Jääskeläinen 	default:
6290442c956SVesa Jääskeläinen 		assert(0);
6300442c956SVesa Jääskeläinen 		break;
6310442c956SVesa Jääskeläinen 	}
6320442c956SVesa Jääskeläinen 
6330442c956SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK) {
6340442c956SVesa Jääskeläinen 		*tee_attrs = attrs;
6350442c956SVesa Jääskeläinen 		*tee_count = count;
6360442c956SVesa Jääskeläinen 	} else {
6370442c956SVesa Jääskeläinen 		TEE_Free(attrs);
6380442c956SVesa Jääskeläinen 	}
6390442c956SVesa Jääskeläinen 
6400442c956SVesa Jääskeläinen 	return rc;
6410442c956SVesa Jääskeläinen }
6420442c956SVesa Jääskeläinen 
tee2pkcs_rsa_attributes(struct obj_attrs ** pub_head,struct obj_attrs ** priv_head,TEE_ObjectHandle tee_obj)64386922832SVesa Jääskeläinen static enum pkcs11_rc tee2pkcs_rsa_attributes(struct obj_attrs **pub_head,
64486922832SVesa Jääskeläinen 					      struct obj_attrs **priv_head,
64586922832SVesa Jääskeläinen 					      TEE_ObjectHandle tee_obj)
64686922832SVesa Jääskeläinen {
64786922832SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
64886922832SVesa Jääskeläinen 	void *a_ptr = NULL;
64986922832SVesa Jääskeläinen 
65086922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_MODULUS, tee_obj,
65186922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_MODULUS);
65286922832SVesa Jääskeläinen 	if (rc)
65386922832SVesa Jääskeläinen 		goto out;
65486922832SVesa Jääskeläinen 
65586922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
65686922832SVesa Jääskeläinen 			       NULL);
65786922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
65886922832SVesa Jääskeläinen 		goto out;
65986922832SVesa Jääskeläinen 
66086922832SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK && !a_ptr) {
66186922832SVesa Jääskeläinen 		rc = remove_empty_attribute(pub_head,
66286922832SVesa Jääskeläinen 					    PKCS11_CKA_PUBLIC_EXPONENT);
66386922832SVesa Jääskeläinen 		if (rc)
66486922832SVesa Jääskeläinen 			goto out;
66586922832SVesa Jääskeläinen 		rc = PKCS11_RV_NOT_FOUND;
66686922832SVesa Jääskeläinen 	}
66786922832SVesa Jääskeläinen 
66886922832SVesa Jääskeläinen 	if (rc == PKCS11_RV_NOT_FOUND) {
66986922832SVesa Jääskeläinen 		rc = tee2pkcs_add_attribute(pub_head,
67086922832SVesa Jääskeläinen 					    PKCS11_CKA_PUBLIC_EXPONENT,
67186922832SVesa Jääskeläinen 					    tee_obj,
67286922832SVesa Jääskeläinen 					    TEE_ATTR_RSA_PUBLIC_EXPONENT);
67386922832SVesa Jääskeläinen 		if (rc)
67486922832SVesa Jääskeläinen 			goto out;
67586922832SVesa Jääskeläinen 	}
67686922832SVesa Jääskeläinen 
67786922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_MODULUS, tee_obj,
67886922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_MODULUS);
67986922832SVesa Jääskeläinen 	if (rc)
68086922832SVesa Jääskeläinen 		goto out;
68186922832SVesa Jääskeläinen 
68286922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT,
68386922832SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_RSA_PUBLIC_EXPONENT);
68486922832SVesa Jääskeläinen 	if (rc)
68586922832SVesa Jääskeläinen 		goto out;
68686922832SVesa Jääskeläinen 
68786922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT,
68886922832SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_RSA_PRIVATE_EXPONENT);
68986922832SVesa Jääskeläinen 	if (rc)
69086922832SVesa Jääskeläinen 		goto out;
69186922832SVesa Jääskeläinen 
69286922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_1, tee_obj,
69386922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_PRIME1);
69486922832SVesa Jääskeläinen 	if (rc)
69586922832SVesa Jääskeläinen 		goto out;
69686922832SVesa Jääskeläinen 
69786922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_2, tee_obj,
69886922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_PRIME2);
69986922832SVesa Jääskeläinen 	if (rc)
70086922832SVesa Jääskeläinen 		goto out;
70186922832SVesa Jääskeläinen 
70286922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_1, tee_obj,
70386922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_EXPONENT1);
70486922832SVesa Jääskeläinen 	if (rc)
70586922832SVesa Jääskeläinen 		goto out;
70686922832SVesa Jääskeläinen 
70786922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_2, tee_obj,
70886922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_EXPONENT2);
70986922832SVesa Jääskeläinen 	if (rc)
71086922832SVesa Jääskeläinen 		goto out;
71186922832SVesa Jääskeläinen 
71286922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_COEFFICIENT, tee_obj,
71386922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_COEFFICIENT);
71486922832SVesa Jääskeläinen out:
71586922832SVesa Jääskeläinen 	return rc;
71686922832SVesa Jääskeläinen }
71786922832SVesa Jääskeläinen 
generate_rsa_keys(struct pkcs11_attribute_head * proc_params,struct obj_attrs ** pub_head,struct obj_attrs ** priv_head)71886922832SVesa Jääskeläinen enum pkcs11_rc generate_rsa_keys(struct pkcs11_attribute_head *proc_params,
71986922832SVesa Jääskeläinen 				 struct obj_attrs **pub_head,
72086922832SVesa Jääskeläinen 				 struct obj_attrs **priv_head)
72186922832SVesa Jääskeläinen {
72286922832SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
72386922832SVesa Jääskeläinen 	void *a_ptr = NULL;
72486922832SVesa Jääskeläinen 	uint32_t a_size = 0;
72586922832SVesa Jääskeläinen 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
72686922832SVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
72786922832SVesa Jääskeläinen 	uint32_t modulus_bits = 0;
72886922832SVesa Jääskeläinen 	TEE_Attribute tee_attrs[1] = { };
72986922832SVesa Jääskeläinen 	uint32_t tee_count = 0;
73086922832SVesa Jääskeläinen 
73186922832SVesa Jääskeläinen 	if (!proc_params || !*pub_head || !*priv_head)
73286922832SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
73386922832SVesa Jääskeläinen 
73486922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_MODULUS_BITS, &a_ptr,
73586922832SVesa Jääskeläinen 			       &a_size);
73686922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK || a_size != sizeof(uint32_t))
73786922832SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
73886922832SVesa Jääskeläinen 
73986922832SVesa Jääskeläinen 	TEE_MemMove(&modulus_bits, a_ptr, sizeof(uint32_t));
74086922832SVesa Jääskeläinen 
74186922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
74286922832SVesa Jääskeläinen 			       &a_size);
74386922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
74486922832SVesa Jääskeläinen 		return rc;
74586922832SVesa Jääskeläinen 
74686922832SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK && a_ptr) {
74786922832SVesa Jääskeläinen 		TEE_InitRefAttribute(&tee_attrs[tee_count],
74886922832SVesa Jääskeläinen 				     TEE_ATTR_RSA_PUBLIC_EXPONENT,
74986922832SVesa Jääskeläinen 				     a_ptr, a_size);
75086922832SVesa Jääskeläinen 		tee_count++;
75186922832SVesa Jääskeläinen 	}
75286922832SVesa Jääskeläinen 
75386922832SVesa Jääskeläinen 	if (remove_empty_attribute(priv_head, PKCS11_CKA_MODULUS) ||
75486922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT) ||
75586922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT) ||
75686922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_1) ||
75786922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_2) ||
75886922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_1) ||
75986922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_2) ||
76086922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_COEFFICIENT)) {
76186922832SVesa Jääskeläinen 		EMSG("Unexpected attribute(s) found");
76286922832SVesa Jääskeläinen 		rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
76386922832SVesa Jääskeläinen 		goto out;
76486922832SVesa Jääskeläinen 	}
76586922832SVesa Jääskeläinen 
76686922832SVesa Jääskeläinen 	/* Create an RSA TEE key */
76786922832SVesa Jääskeläinen 	res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, modulus_bits,
76886922832SVesa Jääskeläinen 					  &tee_obj);
76986922832SVesa Jääskeläinen 	if (res) {
77086922832SVesa Jääskeläinen 		DMSG("TEE_AllocateTransientObject failed %#"PRIx32, res);
77186922832SVesa Jääskeläinen 
77286922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
77386922832SVesa Jääskeläinen 		goto out;
77486922832SVesa Jääskeläinen 	}
77586922832SVesa Jääskeläinen 
77686922832SVesa Jääskeläinen 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
77786922832SVesa Jääskeläinen 	if (res) {
77886922832SVesa Jääskeläinen 		DMSG("TEE_RestrictObjectUsage1 failed %#"PRIx32, res);
77986922832SVesa Jääskeläinen 
78086922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
78186922832SVesa Jääskeläinen 		goto out;
78286922832SVesa Jääskeläinen 	}
78386922832SVesa Jääskeläinen 
78486922832SVesa Jääskeläinen 	res = TEE_GenerateKey(tee_obj, modulus_bits, tee_attrs, tee_count);
78586922832SVesa Jääskeläinen 	if (res) {
78686922832SVesa Jääskeläinen 		DMSG("TEE_GenerateKey failed %#"PRIx32, res);
78786922832SVesa Jääskeläinen 
78886922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
78986922832SVesa Jääskeläinen 		goto out;
79086922832SVesa Jääskeläinen 	}
79186922832SVesa Jääskeläinen 
79286922832SVesa Jääskeläinen 	rc = tee2pkcs_rsa_attributes(pub_head, priv_head, tee_obj);
79386922832SVesa Jääskeläinen 
79486922832SVesa Jääskeläinen out:
79586922832SVesa Jääskeläinen 	if (tee_obj != TEE_HANDLE_NULL)
79686922832SVesa Jääskeläinen 		TEE_CloseObject(tee_obj);
79786922832SVesa Jääskeläinen 
79886922832SVesa Jääskeläinen 	return rc;
79986922832SVesa Jääskeläinen }
8000442c956SVesa Jääskeläinen 
rsa_get_input_max_byte_size(TEE_OperationHandle op)8010442c956SVesa Jääskeläinen size_t rsa_get_input_max_byte_size(TEE_OperationHandle op)
8020442c956SVesa Jääskeläinen {
8030442c956SVesa Jääskeläinen 	TEE_OperationInfo info = { };
8040442c956SVesa Jääskeläinen 
8050442c956SVesa Jääskeläinen 	TEE_GetOperationInfo(op, &info);
8060442c956SVesa Jääskeläinen 
8070442c956SVesa Jääskeläinen 	return info.maxKeySize / 8;
8080442c956SVesa Jääskeläinen }
809e02f17f3SAlexandre Marechal 
pkcs2tee_rsa_nopad_context(struct active_processing * proc)810e02f17f3SAlexandre Marechal enum pkcs11_rc pkcs2tee_rsa_nopad_context(struct active_processing *proc)
811e02f17f3SAlexandre Marechal {
812e02f17f3SAlexandre Marechal 	size_t key_size = 0;
813e02f17f3SAlexandre Marechal 
814e02f17f3SAlexandre Marechal 	/*
815e02f17f3SAlexandre Marechal 	 * RSA no-pad (CKM_RSA_X_509) verify needs a buffer of the size
816e02f17f3SAlexandre Marechal 	 * of the key to safely run.
817e02f17f3SAlexandre Marechal 	 */
818e02f17f3SAlexandre Marechal 	key_size = rsa_get_input_max_byte_size(proc->tee_op_handle);
819e02f17f3SAlexandre Marechal 	if (!key_size)
820e02f17f3SAlexandre Marechal 		return PKCS11_CKR_GENERAL_ERROR;
821e02f17f3SAlexandre Marechal 
822e02f17f3SAlexandre Marechal 	proc->extra_ctx = TEE_Malloc(key_size, TEE_USER_MEM_HINT_NO_FILL_ZERO);
823e02f17f3SAlexandre Marechal 	if (!proc->extra_ctx)
824e02f17f3SAlexandre Marechal 		return PKCS11_CKR_DEVICE_MEMORY;
825e02f17f3SAlexandre Marechal 
826e02f17f3SAlexandre Marechal 	return PKCS11_CKR_OK;
827e02f17f3SAlexandre Marechal }
828