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