186922832SVesa Jääskeläinen // SPDX-License-Identifier: BSD-2-Clause 286922832SVesa Jääskeläinen /* 386922832SVesa Jääskeläinen * Copyright (c) 2018-2021, Linaro Limited 486922832SVesa Jääskeläinen */ 586922832SVesa Jääskeläinen 686922832SVesa Jääskeläinen #include <assert.h> 786922832SVesa Jääskeläinen #include <pkcs11_ta.h> 886922832SVesa Jääskeläinen #include <tee_api_defines.h> 986922832SVesa Jääskeläinen #include <tee_internal_api.h> 1086922832SVesa Jääskeläinen #include <tee_internal_api_extensions.h> 1186922832SVesa Jääskeläinen 1286922832SVesa Jääskeläinen #include "attributes.h" 13*0442c956SVesa Jääskeläinen #include "object.h" 1486922832SVesa Jääskeläinen #include "processing.h" 1586922832SVesa Jääskeläinen 16*0442c956SVesa Jääskeläinen enum pkcs11_rc load_tee_rsa_key_attrs(TEE_Attribute **tee_attrs, 17*0442c956SVesa Jääskeläinen size_t *tee_count, 18*0442c956SVesa Jääskeläinen struct pkcs11_object *obj) 19*0442c956SVesa Jääskeläinen { 20*0442c956SVesa Jääskeläinen TEE_Attribute *attrs = NULL; 21*0442c956SVesa Jääskeläinen size_t count = 0; 22*0442c956SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 23*0442c956SVesa Jääskeläinen void *a_ptr = NULL; 24*0442c956SVesa Jääskeläinen 25*0442c956SVesa Jääskeläinen assert(get_key_type(obj->attributes) == PKCS11_CKK_RSA); 26*0442c956SVesa Jääskeläinen 27*0442c956SVesa Jääskeläinen switch (get_class(obj->attributes)) { 28*0442c956SVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 29*0442c956SVesa Jääskeläinen attrs = TEE_Malloc(2 * sizeof(TEE_Attribute), 30*0442c956SVesa Jääskeläinen TEE_USER_MEM_HINT_NO_FILL_ZERO); 31*0442c956SVesa Jääskeläinen if (!attrs) 32*0442c956SVesa Jääskeläinen return PKCS11_CKR_DEVICE_MEMORY; 33*0442c956SVesa Jääskeläinen 34*0442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS, 35*0442c956SVesa Jääskeläinen obj, PKCS11_CKA_MODULUS)) 36*0442c956SVesa Jääskeläinen count++; 37*0442c956SVesa Jääskeläinen 38*0442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], 39*0442c956SVesa Jääskeläinen TEE_ATTR_RSA_PUBLIC_EXPONENT, obj, 40*0442c956SVesa Jääskeläinen PKCS11_CKA_PUBLIC_EXPONENT)) 41*0442c956SVesa Jääskeläinen count++; 42*0442c956SVesa Jääskeläinen 43*0442c956SVesa Jääskeläinen if (count == 2) 44*0442c956SVesa Jääskeläinen rc = PKCS11_CKR_OK; 45*0442c956SVesa Jääskeläinen 46*0442c956SVesa Jääskeläinen break; 47*0442c956SVesa Jääskeläinen 48*0442c956SVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 49*0442c956SVesa Jääskeläinen attrs = TEE_Malloc(8 * sizeof(TEE_Attribute), 50*0442c956SVesa Jääskeläinen TEE_USER_MEM_HINT_NO_FILL_ZERO); 51*0442c956SVesa Jääskeläinen if (!attrs) 52*0442c956SVesa Jääskeläinen return PKCS11_CKR_DEVICE_MEMORY; 53*0442c956SVesa Jääskeläinen 54*0442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_MODULUS, 55*0442c956SVesa Jääskeläinen obj, PKCS11_CKA_MODULUS)) 56*0442c956SVesa Jääskeläinen count++; 57*0442c956SVesa Jääskeläinen 58*0442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], 59*0442c956SVesa Jääskeläinen TEE_ATTR_RSA_PUBLIC_EXPONENT, obj, 60*0442c956SVesa Jääskeläinen PKCS11_CKA_PUBLIC_EXPONENT)) 61*0442c956SVesa Jääskeläinen count++; 62*0442c956SVesa Jääskeläinen 63*0442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], 64*0442c956SVesa Jääskeläinen TEE_ATTR_RSA_PRIVATE_EXPONENT, obj, 65*0442c956SVesa Jääskeläinen PKCS11_CKA_PRIVATE_EXPONENT)) 66*0442c956SVesa Jääskeläinen count++; 67*0442c956SVesa Jääskeläinen 68*0442c956SVesa Jääskeläinen if (count != 3) 69*0442c956SVesa Jääskeläinen break; 70*0442c956SVesa Jääskeläinen 71*0442c956SVesa Jääskeläinen /* If pre-computed values are present load those */ 72*0442c956SVesa Jääskeläinen rc = get_attribute_ptr(obj->attributes, PKCS11_CKA_PRIME_1, 73*0442c956SVesa Jääskeläinen &a_ptr, NULL); 74*0442c956SVesa Jääskeläinen if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 75*0442c956SVesa Jääskeläinen break; 76*0442c956SVesa Jääskeläinen if (rc == PKCS11_RV_NOT_FOUND || !a_ptr) { 77*0442c956SVesa Jääskeläinen rc = PKCS11_CKR_OK; 78*0442c956SVesa Jääskeläinen break; 79*0442c956SVesa Jääskeläinen } 80*0442c956SVesa Jääskeläinen 81*0442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME1, obj, 82*0442c956SVesa Jääskeläinen PKCS11_CKA_PRIME_1)) 83*0442c956SVesa Jääskeläinen count++; 84*0442c956SVesa Jääskeläinen 85*0442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_PRIME2, obj, 86*0442c956SVesa Jääskeläinen PKCS11_CKA_PRIME_2)) 87*0442c956SVesa Jääskeläinen count++; 88*0442c956SVesa Jääskeläinen 89*0442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT1, 90*0442c956SVesa Jääskeläinen obj, PKCS11_CKA_EXPONENT_1)) 91*0442c956SVesa Jääskeläinen count++; 92*0442c956SVesa Jääskeläinen 93*0442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_EXPONENT2, 94*0442c956SVesa Jääskeläinen obj, PKCS11_CKA_EXPONENT_2)) 95*0442c956SVesa Jääskeläinen count++; 96*0442c956SVesa Jääskeläinen 97*0442c956SVesa Jääskeläinen if (pkcs2tee_load_attr(&attrs[count], TEE_ATTR_RSA_COEFFICIENT, 98*0442c956SVesa Jääskeläinen obj, PKCS11_CKA_COEFFICIENT)) 99*0442c956SVesa Jääskeläinen count++; 100*0442c956SVesa Jääskeläinen 101*0442c956SVesa Jääskeläinen if (count == 8) 102*0442c956SVesa Jääskeläinen rc = PKCS11_CKR_OK; 103*0442c956SVesa Jääskeläinen 104*0442c956SVesa Jääskeläinen break; 105*0442c956SVesa Jääskeläinen 106*0442c956SVesa Jääskeläinen default: 107*0442c956SVesa Jääskeläinen assert(0); 108*0442c956SVesa Jääskeläinen break; 109*0442c956SVesa Jääskeläinen } 110*0442c956SVesa Jääskeläinen 111*0442c956SVesa Jääskeläinen if (rc == PKCS11_CKR_OK) { 112*0442c956SVesa Jääskeläinen *tee_attrs = attrs; 113*0442c956SVesa Jääskeläinen *tee_count = count; 114*0442c956SVesa Jääskeläinen } else { 115*0442c956SVesa Jääskeläinen TEE_Free(attrs); 116*0442c956SVesa Jääskeläinen } 117*0442c956SVesa Jääskeläinen 118*0442c956SVesa Jääskeläinen return rc; 119*0442c956SVesa Jääskeläinen } 120*0442c956SVesa Jääskeläinen 12186922832SVesa Jääskeläinen static enum pkcs11_rc tee2pkcs_rsa_attributes(struct obj_attrs **pub_head, 12286922832SVesa Jääskeläinen struct obj_attrs **priv_head, 12386922832SVesa Jääskeläinen TEE_ObjectHandle tee_obj) 12486922832SVesa Jääskeläinen { 12586922832SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 12686922832SVesa Jääskeläinen void *a_ptr = NULL; 12786922832SVesa Jääskeläinen 12886922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(pub_head, PKCS11_CKA_MODULUS, tee_obj, 12986922832SVesa Jääskeläinen TEE_ATTR_RSA_MODULUS); 13086922832SVesa Jääskeläinen if (rc) 13186922832SVesa Jääskeläinen goto out; 13286922832SVesa Jääskeläinen 13386922832SVesa Jääskeläinen rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr, 13486922832SVesa Jääskeläinen NULL); 13586922832SVesa Jääskeläinen if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 13686922832SVesa Jääskeläinen goto out; 13786922832SVesa Jääskeläinen 13886922832SVesa Jääskeläinen if (rc == PKCS11_CKR_OK && !a_ptr) { 13986922832SVesa Jääskeläinen rc = remove_empty_attribute(pub_head, 14086922832SVesa Jääskeläinen PKCS11_CKA_PUBLIC_EXPONENT); 14186922832SVesa Jääskeläinen if (rc) 14286922832SVesa Jääskeläinen goto out; 14386922832SVesa Jääskeläinen rc = PKCS11_RV_NOT_FOUND; 14486922832SVesa Jääskeläinen } 14586922832SVesa Jääskeläinen 14686922832SVesa Jääskeläinen if (rc == PKCS11_RV_NOT_FOUND) { 14786922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(pub_head, 14886922832SVesa Jääskeläinen PKCS11_CKA_PUBLIC_EXPONENT, 14986922832SVesa Jääskeläinen tee_obj, 15086922832SVesa Jääskeläinen TEE_ATTR_RSA_PUBLIC_EXPONENT); 15186922832SVesa Jääskeläinen if (rc) 15286922832SVesa Jääskeläinen goto out; 15386922832SVesa Jääskeläinen } 15486922832SVesa Jääskeläinen 15586922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_MODULUS, tee_obj, 15686922832SVesa Jääskeläinen TEE_ATTR_RSA_MODULUS); 15786922832SVesa Jääskeläinen if (rc) 15886922832SVesa Jääskeläinen goto out; 15986922832SVesa Jääskeläinen 16086922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT, 16186922832SVesa Jääskeläinen tee_obj, TEE_ATTR_RSA_PUBLIC_EXPONENT); 16286922832SVesa Jääskeläinen if (rc) 16386922832SVesa Jääskeläinen goto out; 16486922832SVesa Jääskeläinen 16586922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT, 16686922832SVesa Jääskeläinen tee_obj, TEE_ATTR_RSA_PRIVATE_EXPONENT); 16786922832SVesa Jääskeläinen if (rc) 16886922832SVesa Jääskeläinen goto out; 16986922832SVesa Jääskeläinen 17086922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_1, tee_obj, 17186922832SVesa Jääskeläinen TEE_ATTR_RSA_PRIME1); 17286922832SVesa Jääskeläinen if (rc) 17386922832SVesa Jääskeläinen goto out; 17486922832SVesa Jääskeläinen 17586922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_PRIME_2, tee_obj, 17686922832SVesa Jääskeläinen TEE_ATTR_RSA_PRIME2); 17786922832SVesa Jääskeläinen if (rc) 17886922832SVesa Jääskeläinen goto out; 17986922832SVesa Jääskeläinen 18086922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_1, tee_obj, 18186922832SVesa Jääskeläinen TEE_ATTR_RSA_EXPONENT1); 18286922832SVesa Jääskeläinen if (rc) 18386922832SVesa Jääskeläinen goto out; 18486922832SVesa Jääskeläinen 18586922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_EXPONENT_2, tee_obj, 18686922832SVesa Jääskeläinen TEE_ATTR_RSA_EXPONENT2); 18786922832SVesa Jääskeläinen if (rc) 18886922832SVesa Jääskeläinen goto out; 18986922832SVesa Jääskeläinen 19086922832SVesa Jääskeläinen rc = tee2pkcs_add_attribute(priv_head, PKCS11_CKA_COEFFICIENT, tee_obj, 19186922832SVesa Jääskeläinen TEE_ATTR_RSA_COEFFICIENT); 19286922832SVesa Jääskeläinen out: 19386922832SVesa Jääskeläinen return rc; 19486922832SVesa Jääskeläinen } 19586922832SVesa Jääskeläinen 19686922832SVesa Jääskeläinen enum pkcs11_rc generate_rsa_keys(struct pkcs11_attribute_head *proc_params, 19786922832SVesa Jääskeläinen struct obj_attrs **pub_head, 19886922832SVesa Jääskeläinen struct obj_attrs **priv_head) 19986922832SVesa Jääskeläinen { 20086922832SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 20186922832SVesa Jääskeläinen void *a_ptr = NULL; 20286922832SVesa Jääskeläinen uint32_t a_size = 0; 20386922832SVesa Jääskeläinen TEE_ObjectHandle tee_obj = TEE_HANDLE_NULL; 20486922832SVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 20586922832SVesa Jääskeläinen uint32_t modulus_bits = 0; 20686922832SVesa Jääskeläinen TEE_Attribute tee_attrs[1] = { }; 20786922832SVesa Jääskeläinen uint32_t tee_count = 0; 20886922832SVesa Jääskeläinen 20986922832SVesa Jääskeläinen if (!proc_params || !*pub_head || !*priv_head) 21086922832SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 21186922832SVesa Jääskeläinen 21286922832SVesa Jääskeläinen rc = get_attribute_ptr(*pub_head, PKCS11_CKA_MODULUS_BITS, &a_ptr, 21386922832SVesa Jääskeläinen &a_size); 21486922832SVesa Jääskeläinen if (rc != PKCS11_CKR_OK || a_size != sizeof(uint32_t)) 21586922832SVesa Jääskeläinen return PKCS11_CKR_TEMPLATE_INCONSISTENT; 21686922832SVesa Jääskeläinen 21786922832SVesa Jääskeläinen TEE_MemMove(&modulus_bits, a_ptr, sizeof(uint32_t)); 21886922832SVesa Jääskeläinen 21986922832SVesa Jääskeläinen rc = get_attribute_ptr(*pub_head, PKCS11_CKA_PUBLIC_EXPONENT, &a_ptr, 22086922832SVesa Jääskeläinen &a_size); 22186922832SVesa Jääskeläinen if (rc != PKCS11_CKR_OK && rc != PKCS11_RV_NOT_FOUND) 22286922832SVesa Jääskeläinen return rc; 22386922832SVesa Jääskeläinen 22486922832SVesa Jääskeläinen if (rc == PKCS11_CKR_OK && a_ptr) { 22586922832SVesa Jääskeläinen TEE_InitRefAttribute(&tee_attrs[tee_count], 22686922832SVesa Jääskeläinen TEE_ATTR_RSA_PUBLIC_EXPONENT, 22786922832SVesa Jääskeläinen a_ptr, a_size); 22886922832SVesa Jääskeläinen tee_count++; 22986922832SVesa Jääskeläinen } 23086922832SVesa Jääskeläinen 23186922832SVesa Jääskeläinen if (remove_empty_attribute(priv_head, PKCS11_CKA_MODULUS) || 23286922832SVesa Jääskeläinen remove_empty_attribute(priv_head, PKCS11_CKA_PUBLIC_EXPONENT) || 23386922832SVesa Jääskeläinen remove_empty_attribute(priv_head, PKCS11_CKA_PRIVATE_EXPONENT) || 23486922832SVesa Jääskeläinen remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_1) || 23586922832SVesa Jääskeläinen remove_empty_attribute(priv_head, PKCS11_CKA_PRIME_2) || 23686922832SVesa Jääskeläinen remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_1) || 23786922832SVesa Jääskeläinen remove_empty_attribute(priv_head, PKCS11_CKA_EXPONENT_2) || 23886922832SVesa Jääskeläinen remove_empty_attribute(priv_head, PKCS11_CKA_COEFFICIENT)) { 23986922832SVesa Jääskeläinen EMSG("Unexpected attribute(s) found"); 24086922832SVesa Jääskeläinen rc = PKCS11_CKR_TEMPLATE_INCONSISTENT; 24186922832SVesa Jääskeläinen goto out; 24286922832SVesa Jääskeläinen } 24386922832SVesa Jääskeläinen 24486922832SVesa Jääskeläinen /* Create an RSA TEE key */ 24586922832SVesa Jääskeläinen res = TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, modulus_bits, 24686922832SVesa Jääskeläinen &tee_obj); 24786922832SVesa Jääskeläinen if (res) { 24886922832SVesa Jääskeläinen DMSG("TEE_AllocateTransientObject failed %#"PRIx32, res); 24986922832SVesa Jääskeläinen 25086922832SVesa Jääskeläinen rc = tee2pkcs_error(res); 25186922832SVesa Jääskeläinen goto out; 25286922832SVesa Jääskeläinen } 25386922832SVesa Jääskeläinen 25486922832SVesa Jääskeläinen res = TEE_RestrictObjectUsage1(tee_obj, TEE_USAGE_EXTRACTABLE); 25586922832SVesa Jääskeläinen if (res) { 25686922832SVesa Jääskeläinen DMSG("TEE_RestrictObjectUsage1 failed %#"PRIx32, res); 25786922832SVesa Jääskeläinen 25886922832SVesa Jääskeläinen rc = tee2pkcs_error(res); 25986922832SVesa Jääskeläinen goto out; 26086922832SVesa Jääskeläinen } 26186922832SVesa Jääskeläinen 26286922832SVesa Jääskeläinen res = TEE_GenerateKey(tee_obj, modulus_bits, tee_attrs, tee_count); 26386922832SVesa Jääskeläinen if (res) { 26486922832SVesa Jääskeläinen DMSG("TEE_GenerateKey failed %#"PRIx32, res); 26586922832SVesa Jääskeläinen 26686922832SVesa Jääskeläinen rc = tee2pkcs_error(res); 26786922832SVesa Jääskeläinen goto out; 26886922832SVesa Jääskeläinen } 26986922832SVesa Jääskeläinen 27086922832SVesa Jääskeläinen rc = tee2pkcs_rsa_attributes(pub_head, priv_head, tee_obj); 27186922832SVesa Jääskeläinen 27286922832SVesa Jääskeläinen out: 27386922832SVesa Jääskeläinen if (tee_obj != TEE_HANDLE_NULL) 27486922832SVesa Jääskeläinen TEE_CloseObject(tee_obj); 27586922832SVesa Jääskeläinen 27686922832SVesa Jääskeläinen return rc; 27786922832SVesa Jääskeläinen } 278*0442c956SVesa Jääskeläinen 279*0442c956SVesa Jääskeläinen size_t rsa_get_input_max_byte_size(TEE_OperationHandle op) 280*0442c956SVesa Jääskeläinen { 281*0442c956SVesa Jääskeläinen TEE_OperationInfo info = { }; 282*0442c956SVesa Jääskeläinen 283*0442c956SVesa Jääskeläinen TEE_GetOperationInfo(op, &info); 284*0442c956SVesa Jääskeläinen 285*0442c956SVesa Jääskeläinen return info.maxKeySize / 8; 286*0442c956SVesa Jääskeläinen } 287