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