xref: /optee_os/ta/pkcs11/src/processing_rsa.c (revision 869228321d7a92cbf5cb502d55edf3d7beb4b519)
1*86922832SVesa Jääskeläinen // SPDX-License-Identifier: BSD-2-Clause
2*86922832SVesa Jääskeläinen /*
3*86922832SVesa Jääskeläinen  * Copyright (c) 2018-2021, Linaro Limited
4*86922832SVesa Jääskeläinen  */
5*86922832SVesa Jääskeläinen 
6*86922832SVesa Jääskeläinen #include <assert.h>
7*86922832SVesa Jääskeläinen #include <pkcs11_ta.h>
8*86922832SVesa Jääskeläinen #include <tee_api_defines.h>
9*86922832SVesa Jääskeläinen #include <tee_internal_api.h>
10*86922832SVesa Jääskeläinen #include <tee_internal_api_extensions.h>
11*86922832SVesa Jääskeläinen 
12*86922832SVesa Jääskeläinen #include "attributes.h"
13*86922832SVesa Jääskeläinen #include "processing.h"
14*86922832SVesa Jääskeläinen 
15*86922832SVesa Jääskeläinen static enum pkcs11_rc tee2pkcs_rsa_attributes(struct obj_attrs **pub_head,
16*86922832SVesa Jääskeläinen 					      struct obj_attrs **priv_head,
17*86922832SVesa Jääskeläinen 					      TEE_ObjectHandle tee_obj)
18*86922832SVesa Jääskeläinen {
19*86922832SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
20*86922832SVesa Jääskeläinen 	void *a_ptr = NULL;
21*86922832SVesa Jääskeläinen 
22*86922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_MODULUS, tee_obj,
23*86922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_MODULUS);
24*86922832SVesa Jääskeläinen 	if (rc)
25*86922832SVesa Jääskeläinen 		goto out;
26*86922832SVesa Jääskeläinen 
27*86922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
28*86922832SVesa Jääskeläinen 			       NULL);
29*86922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
30*86922832SVesa Jääskeläinen 		goto out;
31*86922832SVesa Jääskeläinen 
32*86922832SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK && !a_ptr) {
33*86922832SVesa Jääskeläinen 		rc = remove_empty_attribute(pub_head,
34*86922832SVesa Jääskeläinen 					    PKCS11_CKA_PUBLIC_EXPONENT);
35*86922832SVesa Jääskeläinen 		if (rc)
36*86922832SVesa Jääskeläinen 			goto out;
37*86922832SVesa Jääskeläinen 		rc = PKCS11_RV_NOT_FOUND;
38*86922832SVesa Jääskeläinen 	}
39*86922832SVesa Jääskeläinen 
40*86922832SVesa Jääskeläinen 	if (rc == PKCS11_RV_NOT_FOUND) {
41*86922832SVesa Jääskeläinen 		rc = tee2pkcs_add_attribute(pub_head,
42*86922832SVesa Jääskeläinen 					    PKCS11_CKA_PUBLIC_EXPONENT,
43*86922832SVesa Jääskeläinen 					    tee_obj,
44*86922832SVesa Jääskeläinen 					    TEE_ATTR_RSA_PUBLIC_EXPONENT);
45*86922832SVesa Jääskeläinen 		if (rc)
46*86922832SVesa Jääskeläinen 			goto out;
47*86922832SVesa Jääskeläinen 	}
48*86922832SVesa Jääskeläinen 
49*86922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_MODULUS, tee_obj,
50*86922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_MODULUS);
51*86922832SVesa Jääskeläinen 	if (rc)
52*86922832SVesa Jääskeläinen 		goto out;
53*86922832SVesa Jääskeläinen 
54*86922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT,
55*86922832SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_RSA_PUBLIC_EXPONENT);
56*86922832SVesa Jääskeläinen 	if (rc)
57*86922832SVesa Jääskeläinen 		goto out;
58*86922832SVesa Jääskeläinen 
59*86922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT,
60*86922832SVesa Jääskeläinen 				    tee_obj, TEE_ATTR_RSA_PRIVATE_EXPONENT);
61*86922832SVesa Jääskeläinen 	if (rc)
62*86922832SVesa Jääskeläinen 		goto out;
63*86922832SVesa Jääskeläinen 
64*86922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_1, tee_obj,
65*86922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_PRIME1);
66*86922832SVesa Jääskeläinen 	if (rc)
67*86922832SVesa Jääskeläinen 		goto out;
68*86922832SVesa Jääskeläinen 
69*86922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_2, tee_obj,
70*86922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_PRIME2);
71*86922832SVesa Jääskeläinen 	if (rc)
72*86922832SVesa Jääskeläinen 		goto out;
73*86922832SVesa Jääskeläinen 
74*86922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_1, tee_obj,
75*86922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_EXPONENT1);
76*86922832SVesa Jääskeläinen 	if (rc)
77*86922832SVesa Jääskeläinen 		goto out;
78*86922832SVesa Jääskeläinen 
79*86922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_2, tee_obj,
80*86922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_EXPONENT2);
81*86922832SVesa Jääskeläinen 	if (rc)
82*86922832SVesa Jääskeläinen 		goto out;
83*86922832SVesa Jääskeläinen 
84*86922832SVesa Jääskeläinen 	rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_COEFFICIENT, tee_obj,
85*86922832SVesa Jääskeläinen 				    TEE_ATTR_RSA_COEFFICIENT);
86*86922832SVesa Jääskeläinen out:
87*86922832SVesa Jääskeläinen 	return rc;
88*86922832SVesa Jääskeläinen }
89*86922832SVesa Jääskeläinen 
90*86922832SVesa Jääskeläinen enum pkcs11_rc generate_rsa_keys(struct pkcs11_attribute_head *proc_params,
91*86922832SVesa Jääskeläinen 				 struct obj_attrs **pub_head,
92*86922832SVesa Jääskeläinen 				 struct obj_attrs **priv_head)
93*86922832SVesa Jääskeläinen {
94*86922832SVesa Jääskeläinen 	enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR;
95*86922832SVesa Jääskeläinen 	void *a_ptr = NULL;
96*86922832SVesa Jääskeläinen 	uint32_t a_size = 0;
97*86922832SVesa Jääskeläinen 	TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL;
98*86922832SVesa Jääskeläinen 	TEE_Result res = TEE_ERROR_GENERIC;
99*86922832SVesa Jääskeläinen 	uint32_t modulus_bits = 0;
100*86922832SVesa Jääskeläinen 	TEE_Attribute tee_attrs[1] = { };
101*86922832SVesa Jääskeläinen 	uint32_t tee_count = 0;
102*86922832SVesa Jääskeläinen 
103*86922832SVesa Jääskeläinen 	if (!proc_params || !*pub_head || !*priv_head)
104*86922832SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
105*86922832SVesa Jääskeläinen 
106*86922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_MODULUS_BITS, &a_ptr,
107*86922832SVesa Jääskeläinen 			       &a_size);
108*86922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK || a_size != sizeof(uint32_t))
109*86922832SVesa Jääskeläinen 		return PKCS11_CKR_TEMPLATE_INCONSISTENT;
110*86922832SVesa Jääskeläinen 
111*86922832SVesa Jääskeläinen 	TEE_MemMove(&modulus_bits, a_ptr, sizeof(uint32_t));
112*86922832SVesa Jääskeläinen 
113*86922832SVesa Jääskeläinen 	rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr,
114*86922832SVesa Jääskeläinen 			       &a_size);
115*86922832SVesa Jääskeläinen 	if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND)
116*86922832SVesa Jääskeläinen 		return rc;
117*86922832SVesa Jääskeläinen 
118*86922832SVesa Jääskeläinen 	if (rc == PKCS11_CKR_OK && a_ptr) {
119*86922832SVesa Jääskeläinen 		TEE_InitRefAttribute(&tee_attrs[tee_count],
120*86922832SVesa Jääskeläinen 				     TEE_ATTR_RSA_PUBLIC_EXPONENT,
121*86922832SVesa Jääskeläinen 				     a_ptr, a_size);
122*86922832SVesa Jääskeläinen 		tee_count++;
123*86922832SVesa Jääskeläinen 	}
124*86922832SVesa Jääskeläinen 
125*86922832SVesa Jääskeläinen 	if (remove_empty_attribute(priv_head, PKCS11_CKA_MODULUS) ||
126*86922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT) ||
127*86922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT) ||
128*86922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_1) ||
129*86922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_2) ||
130*86922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_1) ||
131*86922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_2) ||
132*86922832SVesa Jääskeläinen 	    remove_empty_attribute(priv_head, PKCS11_CKA_COEFFICIENT)) {
133*86922832SVesa Jääskeläinen 		EMSG("Unexpected attribute(s) found");
134*86922832SVesa Jääskeläinen 		rc = PKCS11_CKR_TEMPLATE_INCONSISTENT;
135*86922832SVesa Jääskeläinen 		goto out;
136*86922832SVesa Jääskeläinen 	}
137*86922832SVesa Jääskeläinen 
138*86922832SVesa Jääskeläinen 	/* Create an RSA TEE key */
139*86922832SVesa Jääskeläinen 	res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, modulus_bits,
140*86922832SVesa Jääskeläinen 					  &tee_obj);
141*86922832SVesa Jääskeläinen 	if (res) {
142*86922832SVesa Jääskeläinen 		DMSG("TEE_AllocateTransientObject failed %#"PRIx32, res);
143*86922832SVesa Jääskeläinen 
144*86922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
145*86922832SVesa Jääskeläinen 		goto out;
146*86922832SVesa Jääskeläinen 	}
147*86922832SVesa Jääskeläinen 
148*86922832SVesa Jääskeläinen 	res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE);
149*86922832SVesa Jääskeläinen 	if (res) {
150*86922832SVesa Jääskeläinen 		DMSG("TEE_RestrictObjectUsage1 failed %#"PRIx32, res);
151*86922832SVesa Jääskeläinen 
152*86922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
153*86922832SVesa Jääskeläinen 		goto out;
154*86922832SVesa Jääskeläinen 	}
155*86922832SVesa Jääskeläinen 
156*86922832SVesa Jääskeläinen 	res = TEE_GenerateKey(tee_obj, modulus_bits, tee_attrs, tee_count);
157*86922832SVesa Jääskeläinen 	if (res) {
158*86922832SVesa Jääskeläinen 		DMSG("TEE_GenerateKey failed %#"PRIx32, res);
159*86922832SVesa Jääskeläinen 
160*86922832SVesa Jääskeläinen 		rc = tee2pkcs_error(res);
161*86922832SVesa Jääskeläinen 		goto out;
162*86922832SVesa Jääskeläinen 	}
163*86922832SVesa Jääskeläinen 
164*86922832SVesa Jääskeläinen 	rc = tee2pkcs_rsa_attributes(pub_head, priv_head, tee_obj);
165*86922832SVesa Jääskeläinen 
166*86922832SVesa Jääskeläinen out:
167*86922832SVesa Jääskeläinen 	if (tee_obj != TEE_HANDLE_NULL)
168*86922832SVesa Jääskeläinen 		TEE_CloseObject(tee_obj);
169*86922832SVesa Jääskeläinen 
170*86922832SVesa Jääskeläinen 	return rc;
171*86922832SVesa Jääskeläinen }
172