xref: /optee_os/ta/pkcs11/src/processing_rsa.c (revision d9af50bc47024ff71fcd6a980d2503bd8cd9545b)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2018-2021, Linaro Limited
4  */
5 
6 #include <assert.h>
7 #include <pkcs11_ta.h>
8 #include <tee_api_defines.h>
9 #include <tee_internal_api.h>
10 #include <tee_internal_api_extensions.h>
11 
12 #include "attributes.h"
13 #include "object.h"
14 #include "pkcs11_token.h"
15 #include "processing.h"
16 
17 enum pkcs11_rc
18 pkcs2tee_proc_params_rsa_pss(struct active_processing *proc,
19 			     struct pkcs11_attribute_head *proc_params)
20 {
21 	struct serialargs args = { };
22 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
23 	struct rsa_pss_processing_ctx *ctx = NULL;
24 	uint32_t hash = 0;
25 	uint32_t mgf = 0;
26 	uint32_t salt_len = 0;
27 
28 	serialargs_init(&args, proc_params->data, proc_params->size);
29 
30 	rc = serialargs_get_u32(&args, &hash);
31 	if (rc)
32 		return rc;
33 
34 	rc = serialargs_get_u32(&args, &mgf);
35 	if (rc)
36 		return rc;
37 
38 	rc = serialargs_get_u32(&args, &salt_len);
39 	if (rc)
40 		return rc;
41 
42 	if (serialargs_remaining_bytes(&args))
43 		return PKCS11_CKR_ARGUMENTS_BAD;
44 
45 	proc->extra_ctx = TEE_Malloc(sizeof(struct rsa_pss_processing_ctx),
46 				     TEE_USER_MEM_HINT_NO_FILL_ZERO);
47 	if (!proc->extra_ctx)
48 		return PKCS11_CKR_DEVICE_MEMORY;
49 
50 	ctx = proc->extra_ctx;
51 
52 	ctx->hash_alg = hash;
53 	ctx->mgf_type = mgf;
54 	ctx->salt_len = salt_len;
55 
56 	return PKCS11_CKR_OK;
57 }
58 
59 enum pkcs11_rc pkcs2tee_validate_rsa_pss(struct active_processing *proc,
60 					 struct pkcs11_object *obj)
61 {
62 	struct rsa_pss_processing_ctx *rsa_pss_ctx = NULL;
63 	size_t modulus_size = 0;
64 	size_t hash_size = 0;
65 	uint32_t k = 0;
66 
67 	rsa_pss_ctx = proc->extra_ctx;
68 	assert(rsa_pss_ctx);
69 
70 	switch (rsa_pss_ctx->hash_alg) {
71 	case PKCS11_CKM_SHA_1:
72 		hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA1);
73 		break;
74 	case PKCS11_CKM_SHA224:
75 		hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA224);
76 		break;
77 	case PKCS11_CKM_SHA256:
78 		hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA256);
79 		break;
80 	case PKCS11_CKM_SHA384:
81 		hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA384);
82 		break;
83 	case PKCS11_CKM_SHA512:
84 		hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA512);
85 		break;
86 	default:
87 		assert(0);
88 		break;
89 	}
90 
91 	modulus_size = get_object_key_bit_size(obj);
92 
93 	/**
94 	 * The sLen field must be less than or equal to k*-2-hLen where
95 	 * hLen is the length in bytes of the hash value. k* is the
96 	 * length in bytes of the RSA modulus, except if the length in
97 	 * bits of the RSA modulus is one more than a multiple of 8, in
98 	 * which case k* is one less than the length in bytes of the
99 	 * RSA modulus.
100 	 */
101 	if ((modulus_size % 8) == 1)
102 		k = modulus_size / 8;
103 	else
104 		k = ROUNDUP(modulus_size, 8) / 8;
105 
106 	if (rsa_pss_ctx->salt_len > (k - 2 - hash_size))
107 		return PKCS11_CKR_KEY_SIZE_RANGE;
108 
109 	return PKCS11_CKR_OK;
110 }
111 
112 /*
113  * Check or set TEE algorithm identifier upon PKCS11 mechanism parameters
114  * @tee_id: Input and/or output TEE algorithm identifier
115  * @proc_params: PKCS11 processing parameters
116  */
117 enum pkcs11_rc pkcs2tee_algo_rsa_pss(uint32_t *tee_id,
118 				     struct pkcs11_attribute_head *proc_params)
119 {
120 	struct serialargs args = { };
121 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
122 	uint32_t hash = 0;
123 	uint32_t mgf = 0;
124 	uint32_t salt_len = 0;
125 
126 	serialargs_init(&args, proc_params->data, proc_params->size);
127 
128 	rc = serialargs_get_u32(&args, &hash);
129 	if (rc)
130 		return rc;
131 
132 	rc = serialargs_get_u32(&args, &mgf);
133 	if (rc)
134 		return rc;
135 
136 	rc = serialargs_get_u32(&args, &salt_len);
137 	if (rc)
138 		return rc;
139 
140 	if (serialargs_remaining_bytes(&args))
141 		return PKCS11_CKR_ARGUMENTS_BAD;
142 
143 	if (proc_params->id == PKCS11_CKM_RSA_PKCS_PSS) {
144 		if (hash == PKCS11_CKM_SHA_1 && mgf == PKCS11_CKG_MGF1_SHA1) {
145 			*tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1;
146 			return PKCS11_CKR_OK;
147 		}
148 		if (hash == PKCS11_CKM_SHA224 &&
149 		    mgf == PKCS11_CKG_MGF1_SHA224) {
150 			*tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224;
151 			return PKCS11_CKR_OK;
152 		}
153 		if (hash == PKCS11_CKM_SHA256 &&
154 		    mgf == PKCS11_CKG_MGF1_SHA256) {
155 			*tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256;
156 			return PKCS11_CKR_OK;
157 		}
158 		if (hash == PKCS11_CKM_SHA384 &&
159 		    mgf == PKCS11_CKG_MGF1_SHA384) {
160 			*tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384;
161 			return PKCS11_CKR_OK;
162 		}
163 		if (hash == PKCS11_CKM_SHA512 &&
164 		    mgf == PKCS11_CKG_MGF1_SHA512) {
165 			*tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512;
166 			return PKCS11_CKR_OK;
167 		}
168 		return PKCS11_CKR_MECHANISM_PARAM_INVALID;
169 	}
170 
171 	switch (*tee_id) {
172 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
173 		if (hash != PKCS11_CKM_SHA_1 || mgf != PKCS11_CKG_MGF1_SHA1)
174 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
175 		break;
176 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
177 		if (hash != PKCS11_CKM_SHA224 || mgf != PKCS11_CKG_MGF1_SHA224)
178 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
179 		break;
180 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
181 		if (hash != PKCS11_CKM_SHA256 || mgf != PKCS11_CKG_MGF1_SHA256)
182 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
183 		break;
184 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
185 		if (hash != PKCS11_CKM_SHA384 || mgf != PKCS11_CKG_MGF1_SHA384)
186 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
187 		break;
188 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
189 		if (hash != PKCS11_CKM_SHA512 || mgf != PKCS11_CKG_MGF1_SHA512)
190 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
191 		break;
192 	default:
193 		return PKCS11_CKR_GENERAL_ERROR;
194 	}
195 
196 	return PKCS11_CKR_OK;
197 }
198 
199 enum pkcs11_rc load_tee_rsa_key_attrs(TEE_Attribute **tee_attrs,
200 				      size_t *tee_count,
201 				      struct pkcs11_object *obj)
202 {
203 	TEE_Attribute *attrs = NULL;
204 	size_t count = 0;
205 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
206 	void *a_ptr = NULL;
207 
208 	assert(get_key_type(obj->attributes) == PKCS11_CKK_RSA);
209 
210 	switch (get_class(obj->attributes)) {
211 	case PKCS11_CKO_PUBLIC_KEY:
212 		attrs = TEE_Malloc(2 * sizeof(TEE_Attribute),
213 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
214 		if (!attrs)
215 			return PKCS11_CKR_DEVICE_MEMORY;
216 
217 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS,
218 				       obj, PKCS11_CKA_MODULUS))
219 			count++;
220 
221 		if (pkcs2tee_load_attr(&attrs[count],
222 				       TEE_ATTR_RSA_PUBLIC_EXPONENT, obj,
223 				       PKCS11_CKA_PUBLIC_EXPONENT))
224 			count++;
225 
226 		if (count == 2)
227 			rc = PKCS11_CKR_OK;
228 
229 		break;
230 
231 	case PKCS11_CKO_PRIVATE_KEY:
232 		attrs = TEE_Malloc(8 * sizeof(TEE_Attribute),
233 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
234 		if (!attrs)
235 			return PKCS11_CKR_DEVICE_MEMORY;
236 
237 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS,
238 				       obj, PKCS11_CKA_MODULUS))
239 			count++;
240 
241 		if (pkcs2tee_load_attr(&attrs[count],
242 				       TEE_ATTR_RSA_PUBLIC_EXPONENT, obj,
243 				       PKCS11_CKA_PUBLIC_EXPONENT))
244 			count++;
245 
246 		if (pkcs2tee_load_attr(&attrs[count],
247 				       TEE_ATTR_RSA_PRIVATE_EXPONENT, obj,
248 				       PKCS11_CKA_PRIVATE_EXPONENT))
249 			count++;
250 
251 		if (count != 3)
252 			break;
253 
254 		/* If pre-computed values are present load those */
255 		rc = get_attribute_ptr(obj->attributes, PKCS11_CKA_PRIME_1,
256 				       &a_ptr, NULL);
257 		if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
258 			break;
259 		if (rc == PKCS11_RV_NOT_FOUND || !a_ptr) {
260 			rc = PKCS11_CKR_OK;
261 			break;
262 		}
263 
264 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME1, obj,
265 				       PKCS11_CKA_PRIME_1))
266 			count++;
267 
268 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME2, obj,
269 				       PKCS11_CKA_PRIME_2))
270 			count++;
271 
272 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT1,
273 				       obj, PKCS11_CKA_EXPONENT_1))
274 			count++;
275 
276 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT2,
277 				       obj, PKCS11_CKA_EXPONENT_2))
278 			count++;
279 
280 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_COEFFICIENT,
281 				       obj, PKCS11_CKA_COEFFICIENT))
282 			count++;
283 
284 		if (count == 8)
285 			rc = PKCS11_CKR_OK;
286 
287 		break;
288 
289 	default:
290 		assert(0);
291 		break;
292 	}
293 
294 	if (rc == PKCS11_CKR_OK) {
295 		*tee_attrs = attrs;
296 		*tee_count = count;
297 	} else {
298 		TEE_Free(attrs);
299 	}
300 
301 	return rc;
302 }
303 
304 static enum pkcs11_rc tee2pkcs_rsa_attributes(struct obj_attrs **pub_head,
305 					      struct obj_attrs **priv_head,
306 					      TEE_ObjectHandle tee_obj)
307 {
308 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
309 	void *a_ptr = NULL;
310 
311 	rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_MODULUS, tee_obj,
312 				    TEE_ATTR_RSA_MODULUS);
313 	if (rc)
314 		goto out;
315 
316 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
317 			       NULL);
318 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
319 		goto out;
320 
321 	if (rc == PKCS11_CKR_OK && !a_ptr) {
322 		rc = remove_empty_attribute(pub_head,
323 					    PKCS11_CKA_PUBLIC_EXPONENT);
324 		if (rc)
325 			goto out;
326 		rc = PKCS11_RV_NOT_FOUND;
327 	}
328 
329 	if (rc == PKCS11_RV_NOT_FOUND) {
330 		rc = tee2pkcs_add_attribute(pub_head,
331 					    PKCS11_CKA_PUBLIC_EXPONENT,
332 					    tee_obj,
333 					    TEE_ATTR_RSA_PUBLIC_EXPONENT);
334 		if (rc)
335 			goto out;
336 	}
337 
338 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_MODULUS, tee_obj,
339 				    TEE_ATTR_RSA_MODULUS);
340 	if (rc)
341 		goto out;
342 
343 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT,
344 				    tee_obj, TEE_ATTR_RSA_PUBLIC_EXPONENT);
345 	if (rc)
346 		goto out;
347 
348 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT,
349 				    tee_obj, TEE_ATTR_RSA_PRIVATE_EXPONENT);
350 	if (rc)
351 		goto out;
352 
353 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_1, tee_obj,
354 				    TEE_ATTR_RSA_PRIME1);
355 	if (rc)
356 		goto out;
357 
358 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_2, tee_obj,
359 				    TEE_ATTR_RSA_PRIME2);
360 	if (rc)
361 		goto out;
362 
363 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_1, tee_obj,
364 				    TEE_ATTR_RSA_EXPONENT1);
365 	if (rc)
366 		goto out;
367 
368 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_2, tee_obj,
369 				    TEE_ATTR_RSA_EXPONENT2);
370 	if (rc)
371 		goto out;
372 
373 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_COEFFICIENT, tee_obj,
374 				    TEE_ATTR_RSA_COEFFICIENT);
375 out:
376 	return rc;
377 }
378 
379 enum pkcs11_rc generate_rsa_keys(struct pkcs11_attribute_head *proc_params,
380 				 struct obj_attrs **pub_head,
381 				 struct obj_attrs **priv_head)
382 {
383 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
384 	void *a_ptr = NULL;
385 	uint32_t a_size = 0;
386 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
387 	TEE_Result res = TEE_ERROR_GENERIC;
388 	uint32_t modulus_bits = 0;
389 	TEE_Attribute tee_attrs[1] = { };
390 	uint32_t tee_count = 0;
391 
392 	if (!proc_params || !*pub_head || !*priv_head)
393 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
394 
395 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_MODULUS_BITS, &a_ptr,
396 			       &a_size);
397 	if (rc != PKCS11_CKR_OK || a_size != sizeof(uint32_t))
398 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
399 
400 	TEE_MemMove(&modulus_bits, a_ptr, sizeof(uint32_t));
401 
402 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
403 			       &a_size);
404 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
405 		return rc;
406 
407 	if (rc == PKCS11_CKR_OK && a_ptr) {
408 		TEE_InitRefAttribute(&tee_attrs[tee_count],
409 				     TEE_ATTR_RSA_PUBLIC_EXPONENT,
410 				     a_ptr, a_size);
411 		tee_count++;
412 	}
413 
414 	if (remove_empty_attribute(priv_head, PKCS11_CKA_MODULUS) ||
415 	    remove_empty_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT) ||
416 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT) ||
417 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_1) ||
418 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_2) ||
419 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_1) ||
420 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_2) ||
421 	    remove_empty_attribute(priv_head, PKCS11_CKA_COEFFICIENT)) {
422 		EMSG("Unexpected attribute(s) found");
423 		rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
424 		goto out;
425 	}
426 
427 	/* Create an RSA TEE key */
428 	res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, modulus_bits,
429 					  &tee_obj);
430 	if (res) {
431 		DMSG("TEE_AllocateTransientObject failed %#"PRIx32, res);
432 
433 		rc = tee2pkcs_error(res);
434 		goto out;
435 	}
436 
437 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
438 	if (res) {
439 		DMSG("TEE_RestrictObjectUsage1 failed %#"PRIx32, res);
440 
441 		rc = tee2pkcs_error(res);
442 		goto out;
443 	}
444 
445 	res = TEE_GenerateKey(tee_obj, modulus_bits, tee_attrs, tee_count);
446 	if (res) {
447 		DMSG("TEE_GenerateKey failed %#"PRIx32, res);
448 
449 		rc = tee2pkcs_error(res);
450 		goto out;
451 	}
452 
453 	rc = tee2pkcs_rsa_attributes(pub_head, priv_head, tee_obj);
454 
455 out:
456 	if (tee_obj != TEE_HANDLE_NULL)
457 		TEE_CloseObject(tee_obj);
458 
459 	return rc;
460 }
461 
462 size_t rsa_get_input_max_byte_size(TEE_OperationHandle op)
463 {
464 	TEE_OperationInfo info = { };
465 
466 	TEE_GetOperationInfo(op, &info);
467 
468 	return info.maxKeySize / 8;
469 }
470