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