xref: /optee_os/ta/pkcs11/src/processing_rsa.c (revision 0442c956edfb70be378634fd51dbec6e21550a5a)
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 "processing.h"
15 
16 enum pkcs11_rc load_tee_rsa_key_attrs(TEE_Attribute **tee_attrs,
17 				      size_t *tee_count,
18 				      struct pkcs11_object *obj)
19 {
20 	TEE_Attribute *attrs = NULL;
21 	size_t count = 0;
22 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
23 	void *a_ptr = NULL;
24 
25 	assert(get_key_type(obj->attributes) == PKCS11_CKK_RSA);
26 
27 	switch (get_class(obj->attributes)) {
28 	case PKCS11_CKO_PUBLIC_KEY:
29 		attrs = TEE_Malloc(2 * sizeof(TEE_Attribute),
30 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
31 		if (!attrs)
32 			return PKCS11_CKR_DEVICE_MEMORY;
33 
34 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS,
35 				       obj, PKCS11_CKA_MODULUS))
36 			count++;
37 
38 		if (pkcs2tee_load_attr(&attrs[count],
39 				       TEE_ATTR_RSA_PUBLIC_EXPONENT, obj,
40 				       PKCS11_CKA_PUBLIC_EXPONENT))
41 			count++;
42 
43 		if (count == 2)
44 			rc = PKCS11_CKR_OK;
45 
46 		break;
47 
48 	case PKCS11_CKO_PRIVATE_KEY:
49 		attrs = TEE_Malloc(8 * sizeof(TEE_Attribute),
50 				   TEE_USER_MEM_HINT_NO_FILL_ZERO);
51 		if (!attrs)
52 			return PKCS11_CKR_DEVICE_MEMORY;
53 
54 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS,
55 				       obj, PKCS11_CKA_MODULUS))
56 			count++;
57 
58 		if (pkcs2tee_load_attr(&attrs[count],
59 				       TEE_ATTR_RSA_PUBLIC_EXPONENT, obj,
60 				       PKCS11_CKA_PUBLIC_EXPONENT))
61 			count++;
62 
63 		if (pkcs2tee_load_attr(&attrs[count],
64 				       TEE_ATTR_RSA_PRIVATE_EXPONENT, obj,
65 				       PKCS11_CKA_PRIVATE_EXPONENT))
66 			count++;
67 
68 		if (count != 3)
69 			break;
70 
71 		/* If pre-computed values are present load those */
72 		rc = get_attribute_ptr(obj->attributes, PKCS11_CKA_PRIME_1,
73 				       &a_ptr, NULL);
74 		if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
75 			break;
76 		if (rc == PKCS11_RV_NOT_FOUND || !a_ptr) {
77 			rc = PKCS11_CKR_OK;
78 			break;
79 		}
80 
81 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME1, obj,
82 				       PKCS11_CKA_PRIME_1))
83 			count++;
84 
85 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME2, obj,
86 				       PKCS11_CKA_PRIME_2))
87 			count++;
88 
89 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT1,
90 				       obj, PKCS11_CKA_EXPONENT_1))
91 			count++;
92 
93 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT2,
94 				       obj, PKCS11_CKA_EXPONENT_2))
95 			count++;
96 
97 		if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_COEFFICIENT,
98 				       obj, PKCS11_CKA_COEFFICIENT))
99 			count++;
100 
101 		if (count == 8)
102 			rc = PKCS11_CKR_OK;
103 
104 		break;
105 
106 	default:
107 		assert(0);
108 		break;
109 	}
110 
111 	if (rc == PKCS11_CKR_OK) {
112 		*tee_attrs = attrs;
113 		*tee_count = count;
114 	} else {
115 		TEE_Free(attrs);
116 	}
117 
118 	return rc;
119 }
120 
121 static enum pkcs11_rc tee2pkcs_rsa_attributes(struct obj_attrs **pub_head,
122 					      struct obj_attrs **priv_head,
123 					      TEE_ObjectHandle tee_obj)
124 {
125 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
126 	void *a_ptr = NULL;
127 
128 	rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_MODULUS, tee_obj,
129 				    TEE_ATTR_RSA_MODULUS);
130 	if (rc)
131 		goto out;
132 
133 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
134 			       NULL);
135 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
136 		goto out;
137 
138 	if (rc == PKCS11_CKR_OK && !a_ptr) {
139 		rc = remove_empty_attribute(pub_head,
140 					    PKCS11_CKA_PUBLIC_EXPONENT);
141 		if (rc)
142 			goto out;
143 		rc = PKCS11_RV_NOT_FOUND;
144 	}
145 
146 	if (rc == PKCS11_RV_NOT_FOUND) {
147 		rc = tee2pkcs_add_attribute(pub_head,
148 					    PKCS11_CKA_PUBLIC_EXPONENT,
149 					    tee_obj,
150 					    TEE_ATTR_RSA_PUBLIC_EXPONENT);
151 		if (rc)
152 			goto out;
153 	}
154 
155 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_MODULUS, tee_obj,
156 				    TEE_ATTR_RSA_MODULUS);
157 	if (rc)
158 		goto out;
159 
160 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT,
161 				    tee_obj, TEE_ATTR_RSA_PUBLIC_EXPONENT);
162 	if (rc)
163 		goto out;
164 
165 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT,
166 				    tee_obj, TEE_ATTR_RSA_PRIVATE_EXPONENT);
167 	if (rc)
168 		goto out;
169 
170 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_1, tee_obj,
171 				    TEE_ATTR_RSA_PRIME1);
172 	if (rc)
173 		goto out;
174 
175 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_2, tee_obj,
176 				    TEE_ATTR_RSA_PRIME2);
177 	if (rc)
178 		goto out;
179 
180 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_1, tee_obj,
181 				    TEE_ATTR_RSA_EXPONENT1);
182 	if (rc)
183 		goto out;
184 
185 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_2, tee_obj,
186 				    TEE_ATTR_RSA_EXPONENT2);
187 	if (rc)
188 		goto out;
189 
190 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_COEFFICIENT, tee_obj,
191 				    TEE_ATTR_RSA_COEFFICIENT);
192 out:
193 	return rc;
194 }
195 
196 enum pkcs11_rc generate_rsa_keys(struct pkcs11_attribute_head *proc_params,
197 				 struct obj_attrs **pub_head,
198 				 struct obj_attrs **priv_head)
199 {
200 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
201 	void *a_ptr = NULL;
202 	uint32_t a_size = 0;
203 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
204 	TEE_Result res = TEE_ERROR_GENERIC;
205 	uint32_t modulus_bits = 0;
206 	TEE_Attribute tee_attrs[1] = { };
207 	uint32_t tee_count = 0;
208 
209 	if (!proc_params || !*pub_head || !*priv_head)
210 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
211 
212 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_MODULUS_BITS, &a_ptr,
213 			       &a_size);
214 	if (rc != PKCS11_CKR_OK || a_size != sizeof(uint32_t))
215 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
216 
217 	TEE_MemMove(&modulus_bits, a_ptr, sizeof(uint32_t));
218 
219 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
220 			       &a_size);
221 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
222 		return rc;
223 
224 	if (rc == PKCS11_CKR_OK && a_ptr) {
225 		TEE_InitRefAttribute(&tee_attrs[tee_count],
226 				     TEE_ATTR_RSA_PUBLIC_EXPONENT,
227 				     a_ptr, a_size);
228 		tee_count++;
229 	}
230 
231 	if (remove_empty_attribute(priv_head, PKCS11_CKA_MODULUS) ||
232 	    remove_empty_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT) ||
233 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT) ||
234 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_1) ||
235 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_2) ||
236 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_1) ||
237 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_2) ||
238 	    remove_empty_attribute(priv_head, PKCS11_CKA_COEFFICIENT)) {
239 		EMSG("Unexpected attribute(s) found");
240 		rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
241 		goto out;
242 	}
243 
244 	/* Create an RSA TEE key */
245 	res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, modulus_bits,
246 					  &tee_obj);
247 	if (res) {
248 		DMSG("TEE_AllocateTransientObject failed %#"PRIx32, res);
249 
250 		rc = tee2pkcs_error(res);
251 		goto out;
252 	}
253 
254 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
255 	if (res) {
256 		DMSG("TEE_RestrictObjectUsage1 failed %#"PRIx32, res);
257 
258 		rc = tee2pkcs_error(res);
259 		goto out;
260 	}
261 
262 	res = TEE_GenerateKey(tee_obj, modulus_bits, tee_attrs, tee_count);
263 	if (res) {
264 		DMSG("TEE_GenerateKey failed %#"PRIx32, res);
265 
266 		rc = tee2pkcs_error(res);
267 		goto out;
268 	}
269 
270 	rc = tee2pkcs_rsa_attributes(pub_head, priv_head, tee_obj);
271 
272 out:
273 	if (tee_obj != TEE_HANDLE_NULL)
274 		TEE_CloseObject(tee_obj);
275 
276 	return rc;
277 }
278 
279 size_t rsa_get_input_max_byte_size(TEE_OperationHandle op)
280 {
281 	TEE_OperationInfo info = { };
282 
283 	TEE_GetOperationInfo(op, &info);
284 
285 	return info.maxKeySize / 8;
286 }
287