xref: /optee_os/ta/pkcs11/src/processing_rsa.c (revision d9af50bc47024ff71fcd6a980d2503bd8cd9545b)
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"
14*d9af50bcSVesa Jääskeläinen #include "pkcs11_token.h"
1586922832SVesa Jääskeläinen #include "processing.h"
1686922832SVesa Jääskeläinen 
17*d9af50bcSVesa Jääskeläinen enum pkcs11_rc
18*d9af50bcSVesa Jääskeläinen pkcs2tee_proc_params_rsa_pss(struct active_processing *proc,
19*d9af50bcSVesa Jääskeläinen 			     struct pkcs11_attribute_head *proc_params)
20*d9af50bcSVesa Jääskeläinen {
21*d9af50bcSVesa Jääskeläinen 	struct serialargs args = { };
22*d9af50bcSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
23*d9af50bcSVesa Jääskeläinen 	struct rsa_pss_processing_ctx *ctx = NULL;
24*d9af50bcSVesa Jääskeläinen 	uint32_t hash = 0;
25*d9af50bcSVesa Jääskeläinen 	uint32_t mgf = 0;
26*d9af50bcSVesa Jääskeläinen 	uint32_t salt_len = 0;
27*d9af50bcSVesa Jääskeläinen 
28*d9af50bcSVesa Jääskeläinen 	serialargs_init(&args, proc_params->data, proc_params->size);
29*d9af50bcSVesa Jääskeläinen 
30*d9af50bcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &hash);
31*d9af50bcSVesa Jääskeläinen 	if (rc)
32*d9af50bcSVesa Jääskeläinen 		return rc;
33*d9af50bcSVesa Jääskeläinen 
34*d9af50bcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &mgf);
35*d9af50bcSVesa Jääskeläinen 	if (rc)
36*d9af50bcSVesa Jääskeläinen 		return rc;
37*d9af50bcSVesa Jääskeläinen 
38*d9af50bcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &salt_len);
39*d9af50bcSVesa Jääskeläinen 	if (rc)
40*d9af50bcSVesa Jääskeläinen 		return rc;
41*d9af50bcSVesa Jääskeläinen 
42*d9af50bcSVesa Jääskeläinen 	if (serialargs_remaining_bytes(&args))
43*d9af50bcSVesa Jääskeläinen 		return PKCS11_CKR_ARGUMENTS_BAD;
44*d9af50bcSVesa Jääskeläinen 
45*d9af50bcSVesa Jääskeläinen 	proc->extra_ctx = TEE_Malloc(sizeof(struct rsa_pss_processing_ctx),
46*d9af50bcSVesa Jääskeläinen 				     TEE_USER_MEM_HINT_NO_FILL_ZERO);
47*d9af50bcSVesa Jääskeläinen 	if (!proc->extra_ctx)
48*d9af50bcSVesa Jääskeläinen 		return PKCS11_CKR_DEVICE_MEMORY;
49*d9af50bcSVesa Jääskeläinen 
50*d9af50bcSVesa Jääskeläinen 	ctx = proc->extra_ctx;
51*d9af50bcSVesa Jääskeläinen 
52*d9af50bcSVesa Jääskeläinen 	ctx->hash_alg = hash;
53*d9af50bcSVesa Jääskeläinen 	ctx->mgf_type = mgf;
54*d9af50bcSVesa Jääskeläinen 	ctx->salt_len = salt_len;
55*d9af50bcSVesa Jääskeläinen 
56*d9af50bcSVesa Jääskeläinen 	return PKCS11_CKR_OK;
57*d9af50bcSVesa Jääskeläinen }
58*d9af50bcSVesa Jääskeläinen 
59*d9af50bcSVesa Jääskeläinen enum pkcs11_rc pkcs2tee_validate_rsa_pss(struct active_processing *proc,
60*d9af50bcSVesa Jääskeläinen 					 struct pkcs11_object *obj)
61*d9af50bcSVesa Jääskeläinen {
62*d9af50bcSVesa Jääskeläinen 	struct rsa_pss_processing_ctx *rsa_pss_ctx = NULL;
63*d9af50bcSVesa Jääskeläinen 	size_t modulus_size = 0;
64*d9af50bcSVesa Jääskeläinen 	size_t hash_size = 0;
65*d9af50bcSVesa Jääskeläinen 	uint32_t k = 0;
66*d9af50bcSVesa Jääskeläinen 
67*d9af50bcSVesa Jääskeläinen 	rsa_pss_ctx = proc->extra_ctx;
68*d9af50bcSVesa Jääskeläinen 	assert(rsa_pss_ctx);
69*d9af50bcSVesa Jääskeläinen 
70*d9af50bcSVesa Jääskeläinen 	switch (rsa_pss_ctx->hash_alg) {
71*d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA_1:
72*d9af50bcSVesa Jääskeläinen 		hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA1);
73*d9af50bcSVesa Jääskeläinen 		break;
74*d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA224:
75*d9af50bcSVesa Jääskeläinen 		hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA224);
76*d9af50bcSVesa Jääskeläinen 		break;
77*d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA256:
78*d9af50bcSVesa Jääskeläinen 		hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA256);
79*d9af50bcSVesa Jääskeläinen 		break;
80*d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA384:
81*d9af50bcSVesa Jääskeläinen 		hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA384);
82*d9af50bcSVesa Jääskeläinen 		break;
83*d9af50bcSVesa Jääskeläinen 	case PKCS11_CKM_SHA512:
84*d9af50bcSVesa Jääskeläinen 		hash_size = TEE_ALG_GET_DIGEST_SIZE(TEE_ALG_SHA512);
85*d9af50bcSVesa Jääskeläinen 		break;
86*d9af50bcSVesa Jääskeläinen 	default:
87*d9af50bcSVesa Jääskeläinen 		assert(0);
88*d9af50bcSVesa Jääskeläinen 		break;
89*d9af50bcSVesa Jääskeläinen 	}
90*d9af50bcSVesa Jääskeläinen 
91*d9af50bcSVesa Jääskeläinen 	modulus_size = get_object_key_bit_size(obj);
92*d9af50bcSVesa Jääskeläinen 
93*d9af50bcSVesa Jääskeläinen 	/**
94*d9af50bcSVesa Jääskeläinen 	 * The sLen field must be less than or equal to k*-2-hLen where
95*d9af50bcSVesa Jääskeläinen 	 * hLen is the length in bytes of the hash value. k* is the
96*d9af50bcSVesa Jääskeläinen 	 * length in bytes of the RSA modulus, except if the length in
97*d9af50bcSVesa Jääskeläinen 	 * bits of the RSA modulus is one more than a multiple of 8, in
98*d9af50bcSVesa Jääskeläinen 	 * which case k* is one less than the length in bytes of the
99*d9af50bcSVesa Jääskeläinen 	 * RSA modulus.
100*d9af50bcSVesa Jääskeläinen 	 */
101*d9af50bcSVesa Jääskeläinen 	if ((modulus_size % 8) == 1)
102*d9af50bcSVesa Jääskeläinen 		k = modulus_size / 8;
103*d9af50bcSVesa Jääskeläinen 	else
104*d9af50bcSVesa Jääskeläinen 		k = ROUNDUP(modulus_size, 8) / 8;
105*d9af50bcSVesa Jääskeläinen 
106*d9af50bcSVesa Jääskeläinen 	if (rsa_pss_ctx->salt_len > (k - 2 - hash_size))
107*d9af50bcSVesa Jääskeläinen 		return PKCS11_CKR_KEY_SIZE_RANGE;
108*d9af50bcSVesa Jääskeläinen 
109*d9af50bcSVesa Jääskeläinen 	return PKCS11_CKR_OK;
110*d9af50bcSVesa Jääskeläinen }
111*d9af50bcSVesa Jääskeläinen 
112*d9af50bcSVesa Jääskeläinen /*
113*d9af50bcSVesa Jääskeläinen  * Check or set TEE algorithm identifier upon PKCS11 mechanism parameters
114*d9af50bcSVesa Jääskeläinen  * @tee_id: Input and/or output TEE algorithm identifier
115*d9af50bcSVesa Jääskeläinen  * @proc_params: PKCS11 processing parameters
116*d9af50bcSVesa Jääskeläinen  */
117*d9af50bcSVesa Jääskeläinen enum pkcs11_rc pkcs2tee_algo_rsa_pss(uint32_t *tee_id,
118*d9af50bcSVesa Jääskeläinen 				     struct pkcs11_attribute_head *proc_params)
119*d9af50bcSVesa Jääskeläinen {
120*d9af50bcSVesa Jääskeläinen 	struct serialargs args = { };
121*d9af50bcSVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
122*d9af50bcSVesa Jääskeläinen 	uint32_t hash = 0;
123*d9af50bcSVesa Jääskeläinen 	uint32_t mgf = 0;
124*d9af50bcSVesa Jääskeläinen 	uint32_t salt_len = 0;
125*d9af50bcSVesa Jääskeläinen 
126*d9af50bcSVesa Jääskeläinen 	serialargs_init(&args, proc_params->data, proc_params->size);
127*d9af50bcSVesa Jääskeläinen 
128*d9af50bcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &hash);
129*d9af50bcSVesa Jääskeläinen 	if (rc)
130*d9af50bcSVesa Jääskeläinen 		return rc;
131*d9af50bcSVesa Jääskeläinen 
132*d9af50bcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &mgf);
133*d9af50bcSVesa Jääskeläinen 	if (rc)
134*d9af50bcSVesa Jääskeläinen 		return rc;
135*d9af50bcSVesa Jääskeläinen 
136*d9af50bcSVesa Jääskeläinen 	rc = serialargs_get_u32(&args, &salt_len);
137*d9af50bcSVesa Jääskeläinen 	if (rc)
138*d9af50bcSVesa Jääskeläinen 		return rc;
139*d9af50bcSVesa Jääskeläinen 
140*d9af50bcSVesa Jääskeläinen 	if (serialargs_remaining_bytes(&args))
141*d9af50bcSVesa Jääskeläinen 		return PKCS11_CKR_ARGUMENTS_BAD;
142*d9af50bcSVesa Jääskeläinen 
143*d9af50bcSVesa Jääskeläinen 	if (proc_params->id == PKCS11_CKM_RSA_PKCS_PSS) {
144*d9af50bcSVesa Jääskeläinen 		if (hash == PKCS11_CKM_SHA_1 && mgf == PKCS11_CKG_MGF1_SHA1) {
145*d9af50bcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1;
146*d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_OK;
147*d9af50bcSVesa Jääskeläinen 		}
148*d9af50bcSVesa Jääskeläinen 		if (hash == PKCS11_CKM_SHA224 &&
149*d9af50bcSVesa Jääskeläinen 		    mgf == PKCS11_CKG_MGF1_SHA224) {
150*d9af50bcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224;
151*d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_OK;
152*d9af50bcSVesa Jääskeläinen 		}
153*d9af50bcSVesa Jääskeläinen 		if (hash == PKCS11_CKM_SHA256 &&
154*d9af50bcSVesa Jääskeläinen 		    mgf == PKCS11_CKG_MGF1_SHA256) {
155*d9af50bcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256;
156*d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_OK;
157*d9af50bcSVesa Jääskeläinen 		}
158*d9af50bcSVesa Jääskeläinen 		if (hash == PKCS11_CKM_SHA384 &&
159*d9af50bcSVesa Jääskeläinen 		    mgf == PKCS11_CKG_MGF1_SHA384) {
160*d9af50bcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384;
161*d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_OK;
162*d9af50bcSVesa Jääskeläinen 		}
163*d9af50bcSVesa Jääskeläinen 		if (hash == PKCS11_CKM_SHA512 &&
164*d9af50bcSVesa Jääskeläinen 		    mgf == PKCS11_CKG_MGF1_SHA512) {
165*d9af50bcSVesa Jääskeläinen 			*tee_id = TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512;
166*d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_OK;
167*d9af50bcSVesa Jääskeläinen 		}
168*d9af50bcSVesa Jääskeläinen 		return PKCS11_CKR_MECHANISM_PARAM_INVALID;
169*d9af50bcSVesa Jääskeläinen 	}
170*d9af50bcSVesa Jääskeläinen 
171*d9af50bcSVesa Jääskeläinen 	switch (*tee_id) {
172*d9af50bcSVesa Jääskeläinen 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1:
173*d9af50bcSVesa Jääskeläinen 		if (hash != PKCS11_CKM_SHA_1 || mgf != PKCS11_CKG_MGF1_SHA1)
174*d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
175*d9af50bcSVesa Jääskeläinen 		break;
176*d9af50bcSVesa Jääskeläinen 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224:
177*d9af50bcSVesa Jääskeläinen 		if (hash != PKCS11_CKM_SHA224 || mgf != PKCS11_CKG_MGF1_SHA224)
178*d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
179*d9af50bcSVesa Jääskeläinen 		break;
180*d9af50bcSVesa Jääskeläinen 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256:
181*d9af50bcSVesa Jääskeläinen 		if (hash != PKCS11_CKM_SHA256 || mgf != PKCS11_CKG_MGF1_SHA256)
182*d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
183*d9af50bcSVesa Jääskeläinen 		break;
184*d9af50bcSVesa Jääskeläinen 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384:
185*d9af50bcSVesa Jääskeläinen 		if (hash != PKCS11_CKM_SHA384 || mgf != PKCS11_CKG_MGF1_SHA384)
186*d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
187*d9af50bcSVesa Jääskeläinen 		break;
188*d9af50bcSVesa Jääskeläinen 	case TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512:
189*d9af50bcSVesa Jääskeläinen 		if (hash != PKCS11_CKM_SHA512 || mgf != PKCS11_CKG_MGF1_SHA512)
190*d9af50bcSVesa Jääskeläinen 			return PKCS11_CKR_MECHANISM_PARAM_INVALID;
191*d9af50bcSVesa Jääskeläinen 		break;
192*d9af50bcSVesa Jääskeläinen 	default:
193*d9af50bcSVesa Jääskeläinen 		return PKCS11_CKR_GENERAL_ERROR;
194*d9af50bcSVesa Jääskeläinen 	}
195*d9af50bcSVesa Jääskeläinen 
196*d9af50bcSVesa Jääskeläinen 	return PKCS11_CKR_OK;
197*d9af50bcSVesa Jääskeläinen }
198*d9af50bcSVesa Jääskeläinen 
1990442c956SVesa Jääskeläinen enum pkcs11_rc load_tee_rsa_key_attrs(TEE_Attribute **tee_attrs,
2000442c956SVesa Jääskeläinen 				      size_t *tee_count,
2010442c956SVesa Jääskeläinen 				      struct pkcs11_object *obj)
2020442c956SVesa Jääskeläinen {
2030442c956SVesa Jääskeläinen 	TEE_Attribute *attrs = NULL;
2040442c956SVesa Jääskeläinen 	size_t count = 0;
2050442c956SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
2060442c956SVesa Jääskeläinen 	void *a_ptr = NULL;
2070442c956SVesa Jääskeläinen 
2080442c956SVesa Jääskeläinen 	assert(get_key_type(obj->attributes) == PKCS11_CKK_RSA);
2090442c956SVesa Jääskeläinen 
2100442c956SVesa Jääskeläinen 	switch (get_class(obj->attributes)) {
2110442c956SVesa Jääskeläinen 	case PKCS11_CKO_PUBLIC_KEY:
2120442c956SVesa Jääskeläinen 		attrs = TEE_Malloc(2 * sizeof(TEE_Attribute),
2130442c956SVesa Jääskeläinen 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
2140442c956SVesa Jääskeläinen 		if (!attrs)
2150442c956SVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
2160442c956SVesa Jääskeläinen 
2170442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS,
2180442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_MODULUS))
2190442c956SVesa Jääskeläinen 			count++;
2200442c956SVesa Jääskeläinen 
2210442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
2220442c956SVesa Jääskeläinen 				       TEE_ATTR_RSA_PUBLIC_EXPONENT, obj,
2230442c956SVesa Jääskeläinen 				       PKCS11_CKA_PUBLIC_EXPONENT))
2240442c956SVesa Jääskeläinen 			count++;
2250442c956SVesa Jääskeläinen 
2260442c956SVesa Jääskeläinen 		if (count == 2)
2270442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
2280442c956SVesa Jääskeläinen 
2290442c956SVesa Jääskeläinen 		break;
2300442c956SVesa Jääskeläinen 
2310442c956SVesa Jääskeläinen 	case PKCS11_CKO_PRIVATE_KEY:
2320442c956SVesa Jääskeläinen 		attrs = TEE_Malloc(8 * sizeof(TEE_Attribute),
2330442c956SVesa Jääskeläinen 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
2340442c956SVesa Jääskeläinen 		if (!attrs)
2350442c956SVesa Jääskeläinen 			return PKCS11_CKR_DEVICE_MEMORY;
2360442c956SVesa Jääskeläinen 
2370442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS,
2380442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_MODULUS))
2390442c956SVesa Jääskeläinen 			count++;
2400442c956SVesa Jääskeläinen 
2410442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
2420442c956SVesa Jääskeläinen 				       TEE_ATTR_RSA_PUBLIC_EXPONENT, obj,
2430442c956SVesa Jääskeläinen 				       PKCS11_CKA_PUBLIC_EXPONENT))
2440442c956SVesa Jääskeläinen 			count++;
2450442c956SVesa Jääskeläinen 
2460442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count],
2470442c956SVesa Jääskeläinen 				       TEE_ATTR_RSA_PRIVATE_EXPONENT, obj,
2480442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIVATE_EXPONENT))
2490442c956SVesa Jääskeläinen 			count++;
2500442c956SVesa Jääskeläinen 
2510442c956SVesa Jääskeläinen 		if (count != 3)
2520442c956SVesa Jääskeläinen 			break;
2530442c956SVesa Jääskeläinen 
2540442c956SVesa Jääskeläinen 		/* If pre-computed values are present load those */
2550442c956SVesa Jääskeläinen 		rc = get_attribute_ptr(obj->attributes, PKCS11_CKA_PRIME_1,
2560442c956SVesa Jääskeläinen 				       &a_ptr, NULL);
2570442c956SVesa Jääskeläinen 		if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
2580442c956SVesa Jääskeläinen 			break;
2590442c956SVesa Jääskeläinen 		if (rc == PKCS11_RV_NOT_FOUND || !a_ptr) {
2600442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
2610442c956SVesa Jääskeläinen 			break;
2620442c956SVesa Jääskeläinen 		}
2630442c956SVesa Jääskeläinen 
2640442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME1, obj,
2650442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIME_1))
2660442c956SVesa Jääskeläinen 			count++;
2670442c956SVesa Jääskeläinen 
2680442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME2, obj,
2690442c956SVesa Jääskeläinen 				       PKCS11_CKA_PRIME_2))
2700442c956SVesa Jääskeläinen 			count++;
2710442c956SVesa Jääskeläinen 
2720442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT1,
2730442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_EXPONENT_1))
2740442c956SVesa Jääskeläinen 			count++;
2750442c956SVesa Jääskeläinen 
2760442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT2,
2770442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_EXPONENT_2))
2780442c956SVesa Jääskeläinen 			count++;
2790442c956SVesa Jääskeläinen 
2800442c956SVesa Jääskeläinen 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_COEFFICIENT,
2810442c956SVesa Jääskeläinen 				       obj, PKCS11_CKA_COEFFICIENT))
2820442c956SVesa Jääskeläinen 			count++;
2830442c956SVesa Jääskeläinen 
2840442c956SVesa Jääskeläinen 		if (count == 8)
2850442c956SVesa Jääskeläinen 			rc = PKCS11_CKR_OK;
2860442c956SVesa Jääskeläinen 
2870442c956SVesa Jääskeläinen 		break;
2880442c956SVesa Jääskeläinen 
2890442c956SVesa Jääskeläinen 	default:
2900442c956SVesa Jääskeläinen 		assert(0);
2910442c956SVesa Jääskeläinen 		break;
2920442c956SVesa Jääskeläinen 	}
2930442c956SVesa Jääskeläinen 
2940442c956SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK) {
2950442c956SVesa Jääskeläinen 		*tee_attrs = attrs;
2960442c956SVesa Jääskeläinen 		*tee_count = count;
2970442c956SVesa Jääskeläinen 	} else {
2980442c956SVesa Jääskeläinen 		TEE_Free(attrs);
2990442c956SVesa Jääskeläinen 	}
3000442c956SVesa Jääskeläinen 
3010442c956SVesa Jääskeläinen 	return rc;
3020442c956SVesa Jääskeläinen }
3030442c956SVesa Jääskeläinen 
30486922832SVesa Jääskeläinen static enum pkcs11_rc tee2pkcs_rsa_attributes(struct obj_attrs **pub_head,
30586922832SVesa Jääskeläinen 					      struct obj_attrs **priv_head,
30686922832SVesa Jääskeläinen 					      TEE_ObjectHandle tee_obj)
30786922832SVesa Jääskeläinen {
30886922832SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
30986922832SVesa Jääskeläinen 	void *a_ptr = NULL;
31086922832SVesa Jääskeläinen 
31186922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_MODULUS, tee_obj,
31286922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_MODULUS);
31386922832SVesa Jääskeläinen 	if (rc)
31486922832SVesa Jääskeläinen 		goto out;
31586922832SVesa Jääskeläinen 
31686922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
31786922832SVesa Jääskeläinen 			       NULL);
31886922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
31986922832SVesa Jääskeläinen 		goto out;
32086922832SVesa Jääskeläinen 
32186922832SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK && !a_ptr) {
32286922832SVesa Jääskeläinen 		rc = remove_empty_attribute(pub_head,
32386922832SVesa Jääskeläinen 					    PKCS11_CKA_PUBLIC_EXPONENT);
32486922832SVesa Jääskeläinen 		if (rc)
32586922832SVesa Jääskeläinen 			goto out;
32686922832SVesa Jääskeläinen 		rc = PKCS11_RV_NOT_FOUND;
32786922832SVesa Jääskeläinen 	}
32886922832SVesa Jääskeläinen 
32986922832SVesa Jääskeläinen 	if (rc == PKCS11_RV_NOT_FOUND) {
33086922832SVesa Jääskeläinen 		rc = tee2pkcs_add_attribute(pub_head,
33186922832SVesa Jääskeläinen 					    PKCS11_CKA_PUBLIC_EXPONENT,
33286922832SVesa Jääskeläinen 					    tee_obj,
33386922832SVesa Jääskeläinen 					    TEE_ATTR_RSA_PUBLIC_EXPONENT);
33486922832SVesa Jääskeläinen 		if (rc)
33586922832SVesa Jääskeläinen 			goto out;
33686922832SVesa Jääskeläinen 	}
33786922832SVesa Jääskeläinen 
33886922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_MODULUS, tee_obj,
33986922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_MODULUS);
34086922832SVesa Jääskeläinen 	if (rc)
34186922832SVesa Jääskeläinen 		goto out;
34286922832SVesa Jääskeläinen 
34386922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT,
34486922832SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_RSA_PUBLIC_EXPONENT);
34586922832SVesa Jääskeläinen 	if (rc)
34686922832SVesa Jääskeläinen 		goto out;
34786922832SVesa Jääskeläinen 
34886922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT,
34986922832SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_RSA_PRIVATE_EXPONENT);
35086922832SVesa Jääskeläinen 	if (rc)
35186922832SVesa Jääskeläinen 		goto out;
35286922832SVesa Jääskeläinen 
35386922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_1, tee_obj,
35486922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_PRIME1);
35586922832SVesa Jääskeläinen 	if (rc)
35686922832SVesa Jääskeläinen 		goto out;
35786922832SVesa Jääskeläinen 
35886922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_2, tee_obj,
35986922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_PRIME2);
36086922832SVesa Jääskeläinen 	if (rc)
36186922832SVesa Jääskeläinen 		goto out;
36286922832SVesa Jääskeläinen 
36386922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_1, tee_obj,
36486922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_EXPONENT1);
36586922832SVesa Jääskeläinen 	if (rc)
36686922832SVesa Jääskeläinen 		goto out;
36786922832SVesa Jääskeläinen 
36886922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_2, tee_obj,
36986922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_EXPONENT2);
37086922832SVesa Jääskeläinen 	if (rc)
37186922832SVesa Jääskeläinen 		goto out;
37286922832SVesa Jääskeläinen 
37386922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_COEFFICIENT, tee_obj,
37486922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_COEFFICIENT);
37586922832SVesa Jääskeläinen out:
37686922832SVesa Jääskeläinen 	return rc;
37786922832SVesa Jääskeläinen }
37886922832SVesa Jääskeläinen 
37986922832SVesa Jääskeläinen enum pkcs11_rc generate_rsa_keys(struct pkcs11_attribute_head *proc_params,
38086922832SVesa Jääskeläinen 				 struct obj_attrs **pub_head,
38186922832SVesa Jääskeläinen 				 struct obj_attrs **priv_head)
38286922832SVesa Jääskeläinen {
38386922832SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
38486922832SVesa Jääskeläinen 	void *a_ptr = NULL;
38586922832SVesa Jääskeläinen 	uint32_t a_size = 0;
38686922832SVesa Jääskeläinen 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
38786922832SVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
38886922832SVesa Jääskeläinen 	uint32_t modulus_bits = 0;
38986922832SVesa Jääskeläinen 	TEE_Attribute tee_attrs[1] = { };
39086922832SVesa Jääskeläinen 	uint32_t tee_count = 0;
39186922832SVesa Jääskeläinen 
39286922832SVesa Jääskeläinen 	if (!proc_params || !*pub_head || !*priv_head)
39386922832SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
39486922832SVesa Jääskeläinen 
39586922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_MODULUS_BITS, &a_ptr,
39686922832SVesa Jääskeläinen 			       &a_size);
39786922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK || a_size != sizeof(uint32_t))
39886922832SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
39986922832SVesa Jääskeläinen 
40086922832SVesa Jääskeläinen 	TEE_MemMove(&modulus_bits, a_ptr, sizeof(uint32_t));
40186922832SVesa Jääskeläinen 
40286922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
40386922832SVesa Jääskeläinen 			       &a_size);
40486922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
40586922832SVesa Jääskeläinen 		return rc;
40686922832SVesa Jääskeläinen 
40786922832SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK && a_ptr) {
40886922832SVesa Jääskeläinen 		TEE_InitRefAttribute(&tee_attrs[tee_count],
40986922832SVesa Jääskeläinen 				     TEE_ATTR_RSA_PUBLIC_EXPONENT,
41086922832SVesa Jääskeläinen 				     a_ptr, a_size);
41186922832SVesa Jääskeläinen 		tee_count++;
41286922832SVesa Jääskeläinen 	}
41386922832SVesa Jääskeläinen 
41486922832SVesa Jääskeläinen 	if (remove_empty_attribute(priv_head, PKCS11_CKA_MODULUS) ||
41586922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT) ||
41686922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT) ||
41786922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_1) ||
41886922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_2) ||
41986922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_1) ||
42086922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_2) ||
42186922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_COEFFICIENT)) {
42286922832SVesa Jääskeläinen 		EMSG("Unexpected attribute(s) found");
42386922832SVesa Jääskeläinen 		rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
42486922832SVesa Jääskeläinen 		goto out;
42586922832SVesa Jääskeläinen 	}
42686922832SVesa Jääskeläinen 
42786922832SVesa Jääskeläinen 	/* Create an RSA TEE key */
42886922832SVesa Jääskeläinen 	res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, modulus_bits,
42986922832SVesa Jääskeläinen 					  &tee_obj);
43086922832SVesa Jääskeläinen 	if (res) {
43186922832SVesa Jääskeläinen 		DMSG("TEE_AllocateTransientObject failed %#"PRIx32, res);
43286922832SVesa Jääskeläinen 
43386922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
43486922832SVesa Jääskeläinen 		goto out;
43586922832SVesa Jääskeläinen 	}
43686922832SVesa Jääskeläinen 
43786922832SVesa Jääskeläinen 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
43886922832SVesa Jääskeläinen 	if (res) {
43986922832SVesa Jääskeläinen 		DMSG("TEE_RestrictObjectUsage1 failed %#"PRIx32, res);
44086922832SVesa Jääskeläinen 
44186922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
44286922832SVesa Jääskeläinen 		goto out;
44386922832SVesa Jääskeläinen 	}
44486922832SVesa Jääskeläinen 
44586922832SVesa Jääskeläinen 	res = TEE_GenerateKey(tee_obj, modulus_bits, tee_attrs, tee_count);
44686922832SVesa Jääskeläinen 	if (res) {
44786922832SVesa Jääskeläinen 		DMSG("TEE_GenerateKey failed %#"PRIx32, res);
44886922832SVesa Jääskeläinen 
44986922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
45086922832SVesa Jääskeläinen 		goto out;
45186922832SVesa Jääskeläinen 	}
45286922832SVesa Jääskeläinen 
45386922832SVesa Jääskeläinen 	rc = tee2pkcs_rsa_attributes(pub_head, priv_head, tee_obj);
45486922832SVesa Jääskeläinen 
45586922832SVesa Jääskeläinen out:
45686922832SVesa Jääskeläinen 	if (tee_obj != TEE_HANDLE_NULL)
45786922832SVesa Jääskeläinen 		TEE_CloseObject(tee_obj);
45886922832SVesa Jääskeläinen 
45986922832SVesa Jääskeläinen 	return rc;
46086922832SVesa Jääskeläinen }
4610442c956SVesa Jääskeläinen 
4620442c956SVesa Jääskeläinen size_t rsa_get_input_max_byte_size(TEE_OperationHandle op)
4630442c956SVesa Jääskeläinen {
4640442c956SVesa Jääskeläinen 	TEE_OperationInfo info = { };
4650442c956SVesa Jääskeläinen 
4660442c956SVesa Jääskeläinen 	TEE_GetOperationInfo(op, &info);
4670442c956SVesa Jääskeläinen 
4680442c956SVesa Jääskeläinen 	return info.maxKeySize / 8;
4690442c956SVesa Jääskeläinen }
470