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