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