1fb279d8bSVesa Jääskeläinen // SPDX-License-Identifier: BSD-2-Clause 2fb279d8bSVesa Jääskeläinen /* 3fb279d8bSVesa Jääskeläinen * Copyright (c) 2018-2020, Linaro Limited 4fb279d8bSVesa Jääskeläinen */ 5fb279d8bSVesa Jääskeläinen 6fb279d8bSVesa Jääskeläinen #include <assert.h> 7fb279d8bSVesa Jääskeläinen #include <compiler.h> 8fb279d8bSVesa Jääskeläinen #include <tee_api_defines.h> 9fb279d8bSVesa Jääskeläinen #include <tee_internal_api.h> 10fb279d8bSVesa Jääskeläinen #include <tee_internal_api_extensions.h> 11fb279d8bSVesa Jääskeläinen 12fb279d8bSVesa Jääskeläinen #include "attributes.h" 13fb279d8bSVesa Jääskeläinen #include "pkcs11_helpers.h" 14fb279d8bSVesa Jääskeläinen #include "pkcs11_token.h" 15fb279d8bSVesa Jääskeläinen #include "processing.h" 16fb279d8bSVesa Jääskeläinen #include "serializer.h" 17fb279d8bSVesa Jääskeläinen 18fb279d8bSVesa Jääskeläinen bool processing_is_tee_asymm(uint32_t proc_id) 19fb279d8bSVesa Jääskeläinen { 20fb279d8bSVesa Jääskeläinen switch (proc_id) { 210442c956SVesa Jääskeläinen /* RSA flavors */ 220442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 23dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 24d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 250442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 260442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 270442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 280442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 290442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 300442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 31d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 32d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 33d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 34d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 35d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 36fb279d8bSVesa Jääskeläinen /* EC flavors */ 37*03e07432SValerii Chubar case PKCS11_CKM_EDDSA: 38fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 39cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 40fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 41fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 42fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 43fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 44fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 45fb279d8bSVesa Jääskeläinen return true; 46fb279d8bSVesa Jääskeläinen default: 47fb279d8bSVesa Jääskeläinen return false; 48fb279d8bSVesa Jääskeläinen } 49fb279d8bSVesa Jääskeläinen } 50fb279d8bSVesa Jääskeläinen 51fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 52fb279d8bSVesa Jääskeläinen pkcs2tee_algorithm(uint32_t *tee_id, uint32_t *tee_hash_id, 53fb279d8bSVesa Jääskeläinen enum processing_func function __unused, 54fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 55fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 56fb279d8bSVesa Jääskeläinen { 57fb279d8bSVesa Jääskeläinen static const struct { 58fb279d8bSVesa Jääskeläinen enum pkcs11_mechanism_id mech_id; 59fb279d8bSVesa Jääskeläinen uint32_t tee_id; 60fb279d8bSVesa Jääskeläinen uint32_t tee_hash_id; 61fb279d8bSVesa Jääskeläinen } pkcs2tee_algo[] = { 620442c956SVesa Jääskeläinen /* RSA flavors */ 630442c956SVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS, TEE_ALG_RSAES_PKCS1_V1_5, 0 }, 64dc8c77fcSVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS_OAEP, 1, 0 }, 65d9af50bcSVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS_PSS, 1, 0 }, 660442c956SVesa Jääskeläinen { PKCS11_CKM_MD5_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_MD5, 670442c956SVesa Jääskeläinen TEE_ALG_MD5 }, 680442c956SVesa Jääskeläinen { PKCS11_CKM_SHA1_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA1, 690442c956SVesa Jääskeläinen TEE_ALG_SHA1 }, 700442c956SVesa Jääskeläinen { PKCS11_CKM_SHA224_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA224, 710442c956SVesa Jääskeläinen TEE_ALG_SHA224 }, 720442c956SVesa Jääskeläinen { PKCS11_CKM_SHA256_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA256, 730442c956SVesa Jääskeläinen TEE_ALG_SHA256 }, 740442c956SVesa Jääskeläinen { PKCS11_CKM_SHA384_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA384, 750442c956SVesa Jääskeläinen TEE_ALG_SHA384 }, 760442c956SVesa Jääskeläinen { PKCS11_CKM_SHA512_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA512, 770442c956SVesa Jääskeläinen TEE_ALG_SHA512 }, 78d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA1_RSA_PKCS_PSS, 79d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1, TEE_ALG_SHA1 }, 80d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA224_RSA_PKCS_PSS, 81d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224, TEE_ALG_SHA224 }, 82d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA256_RSA_PKCS_PSS, 83d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256, TEE_ALG_SHA256 }, 84d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA384_RSA_PKCS_PSS, 85d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384, TEE_ALG_SHA384 }, 86d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA512_RSA_PKCS_PSS, 87d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512, TEE_ALG_SHA512 }, 88fb279d8bSVesa Jääskeläinen /* EC flavors (Must find key size from the object) */ 89fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA, 1, 0 }, 90fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA1, 1, TEE_ALG_SHA1 }, 91fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA224, 1, TEE_ALG_SHA224 }, 92fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA256, 1, TEE_ALG_SHA256 }, 93fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA384, 1, TEE_ALG_SHA384 }, 94fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA512, 1, TEE_ALG_SHA512 }, 95cc062b46SJorge Ramirez-Ortiz { PKCS11_CKM_ECDH1_DERIVE, 1, 0 }, 96*03e07432SValerii Chubar { PKCS11_CKM_EDDSA, TEE_ALG_ED25519, 0 }, 97fb279d8bSVesa Jääskeläinen }; 98fb279d8bSVesa Jääskeläinen size_t n = 0; 99fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 100fb279d8bSVesa Jääskeläinen 101fb279d8bSVesa Jääskeläinen for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) { 102fb279d8bSVesa Jääskeläinen if (pkcs2tee_algo[n].mech_id == proc_params->id) { 103fb279d8bSVesa Jääskeläinen *tee_id = pkcs2tee_algo[n].tee_id; 104fb279d8bSVesa Jääskeläinen *tee_hash_id = pkcs2tee_algo[n].tee_hash_id; 105fb279d8bSVesa Jääskeläinen break; 106fb279d8bSVesa Jääskeläinen } 107fb279d8bSVesa Jääskeläinen } 108fb279d8bSVesa Jääskeläinen 109fb279d8bSVesa Jääskeläinen if (n == ARRAY_SIZE(pkcs2tee_algo)) 110fb279d8bSVesa Jääskeläinen return PKCS11_RV_NOT_IMPLEMENTED; 111fb279d8bSVesa Jääskeläinen 112fb279d8bSVesa Jääskeläinen switch (proc_params->id) { 113d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 114d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 115d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 116d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 117d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 118d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 119d9af50bcSVesa Jääskeläinen rc = pkcs2tee_algo_rsa_pss(tee_id, proc_params); 120d9af50bcSVesa Jääskeläinen break; 121dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 122dc8c77fcSVesa Jääskeläinen rc = pkcs2tee_algo_rsa_oaep(tee_id, tee_hash_id, proc_params); 123dc8c77fcSVesa Jääskeläinen break; 124fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 125fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 126fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 127fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 128fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 129fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 130fb279d8bSVesa Jääskeläinen rc = pkcs2tee_algo_ecdsa(tee_id, proc_params, obj); 131fb279d8bSVesa Jääskeläinen break; 132cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 133cc062b46SJorge Ramirez-Ortiz rc = pkcs2tee_algo_ecdh(tee_id, proc_params, obj); 134cc062b46SJorge Ramirez-Ortiz break; 135fb279d8bSVesa Jääskeläinen default: 136fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_OK; 137fb279d8bSVesa Jääskeläinen break; 138fb279d8bSVesa Jääskeläinen } 139fb279d8bSVesa Jääskeläinen 1400442c956SVesa Jääskeläinen /* 1410442c956SVesa Jääskeläinen * PKCS#11 uses single mechanism CKM_RSA_PKCS for both ciphering and 1420442c956SVesa Jääskeläinen * authentication whereas GPD TEE expects TEE_ALG_RSAES_PKCS1_V1_5 for 1430442c956SVesa Jääskeläinen * ciphering and TEE_ALG_RSASSA_PKCS1_V1_5 for authentication. 1440442c956SVesa Jääskeläinen */ 1450442c956SVesa Jääskeläinen if (*tee_id == TEE_ALG_RSAES_PKCS1_V1_5 && 1460442c956SVesa Jääskeläinen (function == PKCS11_FUNCTION_SIGN || 1470442c956SVesa Jääskeläinen function == PKCS11_FUNCTION_VERIFY)) 1480442c956SVesa Jääskeläinen *tee_id = TEE_ALG_RSASSA_PKCS1_V1_5; 1490442c956SVesa Jääskeläinen 150fb279d8bSVesa Jääskeläinen return rc; 151fb279d8bSVesa Jääskeläinen } 152fb279d8bSVesa Jääskeläinen 153fb279d8bSVesa Jääskeläinen static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type, 154fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj, 155fb279d8bSVesa Jääskeläinen enum processing_func function) 156fb279d8bSVesa Jääskeläinen { 157fb279d8bSVesa Jääskeläinen enum pkcs11_class_id class = get_class(obj->attributes); 158fb279d8bSVesa Jääskeläinen enum pkcs11_key_type type = get_key_type(obj->attributes); 159fb279d8bSVesa Jääskeläinen 160fb279d8bSVesa Jääskeläinen switch (class) { 161fb279d8bSVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 162fb279d8bSVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 163fb279d8bSVesa Jääskeläinen break; 164fb279d8bSVesa Jääskeläinen default: 165fb279d8bSVesa Jääskeläinen TEE_Panic(class); 166fb279d8bSVesa Jääskeläinen break; 167fb279d8bSVesa Jääskeläinen } 168fb279d8bSVesa Jääskeläinen 169fb279d8bSVesa Jääskeläinen switch (type) { 170fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 171cc062b46SJorge Ramirez-Ortiz if (class == PKCS11_CKO_PRIVATE_KEY) { 172cc062b46SJorge Ramirez-Ortiz if (function == PKCS11_FUNCTION_DERIVE) 173cc062b46SJorge Ramirez-Ortiz *tee_type = TEE_TYPE_ECDH_KEYPAIR; 174cc062b46SJorge Ramirez-Ortiz else 175fb279d8bSVesa Jääskeläinen *tee_type = TEE_TYPE_ECDSA_KEYPAIR; 176cc062b46SJorge Ramirez-Ortiz } else { 177cc062b46SJorge Ramirez-Ortiz if (function == PKCS11_FUNCTION_DERIVE) 178cc062b46SJorge Ramirez-Ortiz *tee_type = TEE_TYPE_ECDH_PUBLIC_KEY; 179fb279d8bSVesa Jääskeläinen else 180fb279d8bSVesa Jääskeläinen *tee_type = TEE_TYPE_ECDSA_PUBLIC_KEY; 181cc062b46SJorge Ramirez-Ortiz } 182fb279d8bSVesa Jääskeläinen break; 1830442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 1840442c956SVesa Jääskeläinen if (class == PKCS11_CKO_PRIVATE_KEY) 1850442c956SVesa Jääskeläinen *tee_type = TEE_TYPE_RSA_KEYPAIR; 1860442c956SVesa Jääskeläinen else 1870442c956SVesa Jääskeläinen *tee_type = TEE_TYPE_RSA_PUBLIC_KEY; 1880442c956SVesa Jääskeläinen break; 189*03e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 190*03e07432SValerii Chubar if (class == PKCS11_CKO_PRIVATE_KEY) 191*03e07432SValerii Chubar *tee_type = TEE_TYPE_ED25519_KEYPAIR; 192*03e07432SValerii Chubar else 193*03e07432SValerii Chubar *tee_type = TEE_TYPE_ED25519_PUBLIC_KEY; 194*03e07432SValerii Chubar break; 195fb279d8bSVesa Jääskeläinen default: 196fb279d8bSVesa Jääskeläinen TEE_Panic(type); 197fb279d8bSVesa Jääskeläinen break; 198fb279d8bSVesa Jääskeläinen } 199fb279d8bSVesa Jääskeläinen 200fb279d8bSVesa Jääskeläinen return PKCS11_CKR_OK; 201fb279d8bSVesa Jääskeläinen } 202fb279d8bSVesa Jääskeläinen 203fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 204fb279d8bSVesa Jääskeläinen allocate_tee_operation(struct pkcs11_session *session, 205fb279d8bSVesa Jääskeläinen enum processing_func function, 206fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *params, 207fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 208fb279d8bSVesa Jääskeläinen { 209fb279d8bSVesa Jääskeläinen uint32_t size = (uint32_t)get_object_key_bit_size(obj); 210fb279d8bSVesa Jääskeläinen uint32_t algo = 0; 211fb279d8bSVesa Jääskeläinen uint32_t hash_algo = 0; 212fb279d8bSVesa Jääskeläinen uint32_t mode = 0; 213fb279d8bSVesa Jääskeläinen uint32_t hash_mode = 0; 214fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 215fb279d8bSVesa Jääskeläinen struct active_processing *processing = session->processing; 216fb279d8bSVesa Jääskeläinen 217fb279d8bSVesa Jääskeläinen assert(processing->tee_op_handle == TEE_HANDLE_NULL); 218fb279d8bSVesa Jääskeläinen assert(processing->tee_hash_op_handle == TEE_HANDLE_NULL); 219fb279d8bSVesa Jääskeläinen 220fb279d8bSVesa Jääskeläinen if (pkcs2tee_algorithm(&algo, &hash_algo, function, params, obj)) 221fb279d8bSVesa Jääskeläinen return PKCS11_CKR_FUNCTION_FAILED; 222fb279d8bSVesa Jääskeläinen 223fb279d8bSVesa Jääskeläinen pkcs2tee_mode(&mode, function); 224fb279d8bSVesa Jääskeläinen 225fb279d8bSVesa Jääskeläinen if (hash_algo) { 226fb279d8bSVesa Jääskeläinen pkcs2tee_mode(&hash_mode, PKCS11_FUNCTION_DIGEST); 227fb279d8bSVesa Jääskeläinen 228fb279d8bSVesa Jääskeläinen res = TEE_AllocateOperation(&processing->tee_hash_op_handle, 229fb279d8bSVesa Jääskeläinen hash_algo, hash_mode, 0); 230fb279d8bSVesa Jääskeläinen if (res) { 231fb279d8bSVesa Jääskeläinen EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32, 232fb279d8bSVesa Jääskeläinen hash_algo, hash_mode); 233fb279d8bSVesa Jääskeläinen 234fb279d8bSVesa Jääskeläinen if (res == TEE_ERROR_NOT_SUPPORTED) 235fb279d8bSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_INVALID; 236fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 237fb279d8bSVesa Jääskeläinen } 238fb279d8bSVesa Jääskeläinen processing->tee_hash_algo = hash_algo; 239fb279d8bSVesa Jääskeläinen } 240fb279d8bSVesa Jääskeläinen 241fb279d8bSVesa Jääskeläinen res = TEE_AllocateOperation(&processing->tee_op_handle, 242fb279d8bSVesa Jääskeläinen algo, mode, size); 243fb279d8bSVesa Jääskeläinen if (res) 244fb279d8bSVesa Jääskeläinen EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 245fb279d8bSVesa Jääskeläinen algo, mode, size); 246fb279d8bSVesa Jääskeläinen 247fb279d8bSVesa Jääskeläinen if (res == TEE_ERROR_NOT_SUPPORTED) 248fb279d8bSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_INVALID; 249fb279d8bSVesa Jääskeläinen 250fb279d8bSVesa Jääskeläinen if (res != TEE_SUCCESS && 251fb279d8bSVesa Jääskeläinen processing->tee_hash_op_handle != TEE_HANDLE_NULL) { 252fb279d8bSVesa Jääskeläinen TEE_FreeOperation(session->processing->tee_hash_op_handle); 253fb279d8bSVesa Jääskeläinen processing->tee_hash_op_handle = TEE_HANDLE_NULL; 254fb279d8bSVesa Jääskeläinen processing->tee_hash_algo = 0; 255fb279d8bSVesa Jääskeläinen } 256fb279d8bSVesa Jääskeläinen 257fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 258fb279d8bSVesa Jääskeläinen } 259fb279d8bSVesa Jääskeläinen 260fb279d8bSVesa Jääskeläinen static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 261fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj, 262fb279d8bSVesa Jääskeläinen enum processing_func function) 263fb279d8bSVesa Jääskeläinen { 264fb279d8bSVesa Jääskeläinen TEE_Attribute *tee_attrs = NULL; 265fb279d8bSVesa Jääskeläinen size_t tee_attrs_count = 0; 266fb279d8bSVesa Jääskeläinen size_t object_size = 0; 267fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 268fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 269fb279d8bSVesa Jääskeläinen enum pkcs11_class_id __maybe_unused class = get_class(obj->attributes); 270fb279d8bSVesa Jääskeläinen enum pkcs11_key_type type = get_key_type(obj->attributes); 271fb279d8bSVesa Jääskeläinen 272fb279d8bSVesa Jääskeläinen assert(class == PKCS11_CKO_PUBLIC_KEY || 273fb279d8bSVesa Jääskeläinen class == PKCS11_CKO_PRIVATE_KEY); 274fb279d8bSVesa Jääskeläinen 275fb279d8bSVesa Jääskeläinen if (obj->key_handle != TEE_HANDLE_NULL) { 276fb279d8bSVesa Jääskeläinen switch (type) { 2770442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 2780442c956SVesa Jääskeläinen /* RSA loaded keys can be reused */ 2790442c956SVesa Jääskeläinen assert((obj->key_type == TEE_TYPE_RSA_PUBLIC_KEY && 2800442c956SVesa Jääskeläinen class == PKCS11_CKO_PUBLIC_KEY) || 2810442c956SVesa Jääskeläinen (obj->key_type == TEE_TYPE_RSA_KEYPAIR && 2820442c956SVesa Jääskeläinen class == PKCS11_CKO_PRIVATE_KEY)); 2830442c956SVesa Jääskeläinen goto key_ready; 284fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 285fb279d8bSVesa Jääskeläinen /* Reuse EC TEE key only if already DSA or DH */ 286fb279d8bSVesa Jääskeläinen switch (obj->key_type) { 287fb279d8bSVesa Jääskeläinen case TEE_TYPE_ECDSA_PUBLIC_KEY: 288fb279d8bSVesa Jääskeläinen case TEE_TYPE_ECDSA_KEYPAIR: 289fb279d8bSVesa Jääskeläinen if (function != PKCS11_FUNCTION_DERIVE) 290fb279d8bSVesa Jääskeläinen goto key_ready; 291fb279d8bSVesa Jääskeläinen break; 292cc062b46SJorge Ramirez-Ortiz case TEE_TYPE_ECDH_PUBLIC_KEY: 293cc062b46SJorge Ramirez-Ortiz case TEE_TYPE_ECDH_KEYPAIR: 294cc062b46SJorge Ramirez-Ortiz if (function == PKCS11_FUNCTION_DERIVE) 295cc062b46SJorge Ramirez-Ortiz goto key_ready; 296cc062b46SJorge Ramirez-Ortiz break; 297fb279d8bSVesa Jääskeläinen default: 298fb279d8bSVesa Jääskeläinen assert(0); 299fb279d8bSVesa Jääskeläinen break; 300fb279d8bSVesa Jääskeläinen } 301fb279d8bSVesa Jääskeläinen break; 302fb279d8bSVesa Jääskeläinen default: 303fb279d8bSVesa Jääskeläinen assert(0); 304fb279d8bSVesa Jääskeläinen break; 305fb279d8bSVesa Jääskeläinen } 306fb279d8bSVesa Jääskeläinen 307fb279d8bSVesa Jääskeläinen TEE_CloseObject(obj->key_handle); 308fb279d8bSVesa Jääskeläinen obj->key_handle = TEE_HANDLE_NULL; 309fb279d8bSVesa Jääskeläinen } 310fb279d8bSVesa Jääskeläinen 311fb279d8bSVesa Jääskeläinen rc = pkcs2tee_key_type(&obj->key_type, obj, function); 312fb279d8bSVesa Jääskeläinen if (rc) 313fb279d8bSVesa Jääskeläinen return rc; 314fb279d8bSVesa Jääskeläinen 315fb279d8bSVesa Jääskeläinen object_size = get_object_key_bit_size(obj); 316fb279d8bSVesa Jääskeläinen if (!object_size) 317fb279d8bSVesa Jääskeläinen return PKCS11_CKR_GENERAL_ERROR; 318fb279d8bSVesa Jääskeläinen 319fb279d8bSVesa Jääskeläinen switch (type) { 3200442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 3210442c956SVesa Jääskeläinen rc = load_tee_rsa_key_attrs(&tee_attrs, &tee_attrs_count, obj); 3220442c956SVesa Jääskeläinen break; 323fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 324fb279d8bSVesa Jääskeläinen rc = load_tee_ec_key_attrs(&tee_attrs, &tee_attrs_count, obj); 325fb279d8bSVesa Jääskeläinen break; 326*03e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 327*03e07432SValerii Chubar rc = load_tee_eddsa_key_attrs(&tee_attrs, &tee_attrs_count, 328*03e07432SValerii Chubar obj); 329*03e07432SValerii Chubar break; 330fb279d8bSVesa Jääskeläinen default: 331fb279d8bSVesa Jääskeläinen break; 332fb279d8bSVesa Jääskeläinen } 333fb279d8bSVesa Jääskeläinen if (rc) 334fb279d8bSVesa Jääskeläinen return rc; 335fb279d8bSVesa Jääskeläinen 336fb279d8bSVesa Jääskeläinen res = TEE_AllocateTransientObject(obj->key_type, object_size, 337fb279d8bSVesa Jääskeläinen &obj->key_handle); 338fb279d8bSVesa Jääskeläinen if (res) { 339fb279d8bSVesa Jääskeläinen DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 340fb279d8bSVesa Jääskeläinen 341fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 342fb279d8bSVesa Jääskeläinen } 343fb279d8bSVesa Jääskeläinen 344fb279d8bSVesa Jääskeläinen res = TEE_PopulateTransientObject(obj->key_handle, 345fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count); 346fb279d8bSVesa Jääskeläinen 347fb279d8bSVesa Jääskeläinen TEE_Free(tee_attrs); 348fb279d8bSVesa Jääskeläinen 349fb279d8bSVesa Jääskeläinen if (res) { 350fb279d8bSVesa Jääskeläinen DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 351fb279d8bSVesa Jääskeläinen 352fb279d8bSVesa Jääskeläinen goto error; 353fb279d8bSVesa Jääskeläinen } 354fb279d8bSVesa Jääskeläinen 355fb279d8bSVesa Jääskeläinen key_ready: 356fb279d8bSVesa Jääskeläinen res = TEE_SetOperationKey(session->processing->tee_op_handle, 357fb279d8bSVesa Jääskeläinen obj->key_handle); 358fb279d8bSVesa Jääskeläinen if (res) { 359fb279d8bSVesa Jääskeläinen DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 360fb279d8bSVesa Jääskeläinen 361fb279d8bSVesa Jääskeläinen goto error; 362fb279d8bSVesa Jääskeläinen } 363fb279d8bSVesa Jääskeläinen 364fb279d8bSVesa Jääskeläinen return PKCS11_CKR_OK; 365fb279d8bSVesa Jääskeläinen 366fb279d8bSVesa Jääskeläinen error: 367fb279d8bSVesa Jääskeläinen TEE_FreeTransientObject(obj->key_handle); 368fb279d8bSVesa Jääskeläinen obj->key_handle = TEE_HANDLE_NULL; 369fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 370fb279d8bSVesa Jääskeläinen } 371fb279d8bSVesa Jääskeläinen 372fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 373d9af50bcSVesa Jääskeläinen init_tee_operation(struct pkcs11_session *session, 374d9af50bcSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 375d9af50bcSVesa Jääskeläinen struct pkcs11_object *obj) 376fb279d8bSVesa Jääskeläinen { 377d9af50bcSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK; 378d9af50bcSVesa Jääskeläinen struct active_processing *proc = session->processing; 379d9af50bcSVesa Jääskeläinen 380d9af50bcSVesa Jääskeläinen switch (proc_params->id) { 381d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 382d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 383d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 384d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 385d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 386d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 387d9af50bcSVesa Jääskeläinen rc = pkcs2tee_proc_params_rsa_pss(proc, proc_params); 388d9af50bcSVesa Jääskeläinen if (rc) 389d9af50bcSVesa Jääskeläinen break; 390d9af50bcSVesa Jääskeläinen 391d9af50bcSVesa Jääskeläinen rc = pkcs2tee_validate_rsa_pss(proc, obj); 392d9af50bcSVesa Jääskeläinen break; 393dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 394dc8c77fcSVesa Jääskeläinen rc = pkcs2tee_proc_params_rsa_oaep(proc, proc_params); 395dc8c77fcSVesa Jääskeläinen break; 396*03e07432SValerii Chubar case PKCS11_CKM_EDDSA: 397*03e07432SValerii Chubar rc = pkcs2tee_proc_params_eddsa(proc, proc_params); 398*03e07432SValerii Chubar break; 399d9af50bcSVesa Jääskeläinen default: 400d9af50bcSVesa Jääskeläinen break; 401d9af50bcSVesa Jääskeläinen } 402d9af50bcSVesa Jääskeläinen 403d9af50bcSVesa Jääskeläinen return rc; 404fb279d8bSVesa Jääskeläinen } 405fb279d8bSVesa Jääskeläinen 406fb279d8bSVesa Jääskeläinen enum pkcs11_rc init_asymm_operation(struct pkcs11_session *session, 407fb279d8bSVesa Jääskeläinen enum processing_func function, 408fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 409fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 410fb279d8bSVesa Jääskeläinen { 411fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 412fb279d8bSVesa Jääskeläinen 413fb279d8bSVesa Jääskeläinen assert(processing_is_tee_asymm(proc_params->id)); 414fb279d8bSVesa Jääskeläinen 415fb279d8bSVesa Jääskeläinen rc = allocate_tee_operation(session, function, proc_params, obj); 416fb279d8bSVesa Jääskeläinen if (rc) 417fb279d8bSVesa Jääskeläinen return rc; 418fb279d8bSVesa Jääskeläinen 419fb279d8bSVesa Jääskeläinen rc = load_tee_key(session, obj, function); 420fb279d8bSVesa Jääskeläinen if (rc) 421fb279d8bSVesa Jääskeläinen return rc; 422fb279d8bSVesa Jääskeläinen 423d9af50bcSVesa Jääskeläinen return init_tee_operation(session, proc_params, obj); 424fb279d8bSVesa Jääskeläinen } 425fb279d8bSVesa Jääskeläinen 426fb279d8bSVesa Jääskeläinen /* 427fb279d8bSVesa Jääskeläinen * step_sym_step - step (update/oneshot/final) on a symmetric crypto operation 428fb279d8bSVesa Jääskeläinen * 429fb279d8bSVesa Jääskeläinen * @session - current session 430fb279d8bSVesa Jääskeläinen * @function - processing function (encrypt, decrypt, sign, ...) 431fb279d8bSVesa Jääskeläinen * @step - step ID in the processing (oneshot, update, final) 432fb279d8bSVesa Jääskeläinen * @ptypes - invocation parameter types 433fb279d8bSVesa Jääskeläinen * @params - invocation parameter references 434fb279d8bSVesa Jääskeläinen */ 435fb279d8bSVesa Jääskeläinen enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session, 436fb279d8bSVesa Jääskeläinen enum processing_func function, 437fb279d8bSVesa Jääskeläinen enum processing_step step, 438fb279d8bSVesa Jääskeläinen uint32_t ptypes, TEE_Param *params) 439fb279d8bSVesa Jääskeläinen { 440fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 441fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 442fb279d8bSVesa Jääskeläinen void *in_buf = NULL; 443fb279d8bSVesa Jääskeläinen void *in2_buf = NULL; 444fb279d8bSVesa Jääskeläinen void *out_buf = NULL; 445fb279d8bSVesa Jääskeläinen void *hash_buf = NULL; 446fb279d8bSVesa Jääskeläinen uint32_t in_size = 0; 447fb279d8bSVesa Jääskeläinen uint32_t in2_size = 0; 448fb279d8bSVesa Jääskeläinen uint32_t out_size = 0; 449fb279d8bSVesa Jääskeläinen uint32_t hash_size = 0; 450fb279d8bSVesa Jääskeläinen TEE_Attribute *tee_attrs = NULL; 451fb279d8bSVesa Jääskeläinen size_t tee_attrs_count = 0; 452fb279d8bSVesa Jääskeläinen bool output_data = false; 453fb279d8bSVesa Jääskeläinen struct active_processing *proc = session->processing; 454dc8c77fcSVesa Jääskeläinen struct rsa_oaep_processing_ctx *rsa_oaep_ctx = NULL; 455d9af50bcSVesa Jääskeläinen struct rsa_pss_processing_ctx *rsa_pss_ctx = NULL; 456*03e07432SValerii Chubar struct eddsa_processing_ctx *eddsa_ctx = NULL; 457fb279d8bSVesa Jääskeläinen size_t sz = 0; 458fb279d8bSVesa Jääskeläinen 459fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 460fb279d8bSVesa Jääskeläinen in_buf = params[1].memref.buffer; 461fb279d8bSVesa Jääskeläinen in_size = params[1].memref.size; 462fb279d8bSVesa Jääskeläinen if (in_size && !in_buf) 463fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 464fb279d8bSVesa Jääskeläinen } 465fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 466fb279d8bSVesa Jääskeläinen in2_buf = params[2].memref.buffer; 467fb279d8bSVesa Jääskeläinen in2_size = params[2].memref.size; 468fb279d8bSVesa Jääskeläinen if (in2_size && !in2_buf) 469fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 470fb279d8bSVesa Jääskeläinen } 471fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 472fb279d8bSVesa Jääskeläinen out_buf = params[2].memref.buffer; 473fb279d8bSVesa Jääskeläinen out_size = params[2].memref.size; 474fb279d8bSVesa Jääskeläinen if (out_size && !out_buf) 475fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 476fb279d8bSVesa Jääskeläinen } 477fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 478fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 479fb279d8bSVesa Jääskeläinen 480fb279d8bSVesa Jääskeläinen switch (step) { 481fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_ONESHOT: 482fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE: 483fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_FINAL: 484fb279d8bSVesa Jääskeläinen break; 485fb279d8bSVesa Jääskeläinen default: 486fb279d8bSVesa Jääskeläinen return PKCS11_CKR_GENERAL_ERROR; 487fb279d8bSVesa Jääskeläinen } 488fb279d8bSVesa Jääskeläinen 489d9af50bcSVesa Jääskeläinen /* TEE attribute(s) required by the operation */ 490d9af50bcSVesa Jääskeläinen switch (proc->mecha_type) { 491d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 492d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 493d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 494d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 495d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 496d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 497d9af50bcSVesa Jääskeläinen tee_attrs = TEE_Malloc(sizeof(TEE_Attribute), 498d9af50bcSVesa Jääskeläinen TEE_USER_MEM_HINT_NO_FILL_ZERO); 499d9af50bcSVesa Jääskeläinen if (!tee_attrs) { 500d9af50bcSVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY; 501d9af50bcSVesa Jääskeläinen goto out; 502d9af50bcSVesa Jääskeläinen } 503d9af50bcSVesa Jääskeläinen 504d9af50bcSVesa Jääskeläinen rsa_pss_ctx = proc->extra_ctx; 505d9af50bcSVesa Jääskeläinen 506d9af50bcSVesa Jääskeläinen TEE_InitValueAttribute(&tee_attrs[tee_attrs_count], 507d9af50bcSVesa Jääskeläinen TEE_ATTR_RSA_PSS_SALT_LENGTH, 508d9af50bcSVesa Jääskeläinen rsa_pss_ctx->salt_len, 0); 509d9af50bcSVesa Jääskeläinen tee_attrs_count++; 510d9af50bcSVesa Jääskeläinen break; 511*03e07432SValerii Chubar case PKCS11_CKM_EDDSA: 512*03e07432SValerii Chubar eddsa_ctx = proc->extra_ctx; 513*03e07432SValerii Chubar 514*03e07432SValerii Chubar tee_attrs = TEE_Malloc(2 * sizeof(TEE_Attribute), 515*03e07432SValerii Chubar TEE_USER_MEM_HINT_NO_FILL_ZERO); 516*03e07432SValerii Chubar if (!tee_attrs) { 517*03e07432SValerii Chubar rc = PKCS11_CKR_DEVICE_MEMORY; 518*03e07432SValerii Chubar goto out; 519*03e07432SValerii Chubar } 520*03e07432SValerii Chubar 521*03e07432SValerii Chubar if (eddsa_ctx->flag) { 522*03e07432SValerii Chubar TEE_InitValueAttribute(&tee_attrs[tee_attrs_count], 523*03e07432SValerii Chubar TEE_ATTR_EDDSA_PREHASH, 0, 0); 524*03e07432SValerii Chubar tee_attrs_count++; 525*03e07432SValerii Chubar } 526*03e07432SValerii Chubar 527*03e07432SValerii Chubar if (eddsa_ctx->ctx_len > 0) { 528*03e07432SValerii Chubar TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 529*03e07432SValerii Chubar TEE_ATTR_EDDSA_CTX, eddsa_ctx->ctx, 530*03e07432SValerii Chubar eddsa_ctx->ctx_len); 531*03e07432SValerii Chubar tee_attrs_count++; 532*03e07432SValerii Chubar } 533*03e07432SValerii Chubar break; 534dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 535dc8c77fcSVesa Jääskeläinen rsa_oaep_ctx = proc->extra_ctx; 536dc8c77fcSVesa Jääskeläinen 537dc8c77fcSVesa Jääskeläinen if (!rsa_oaep_ctx->source_data_len) 538dc8c77fcSVesa Jääskeläinen break; 539dc8c77fcSVesa Jääskeläinen 540dc8c77fcSVesa Jääskeläinen tee_attrs = TEE_Malloc(sizeof(TEE_Attribute), 541dc8c77fcSVesa Jääskeläinen TEE_USER_MEM_HINT_NO_FILL_ZERO); 542dc8c77fcSVesa Jääskeläinen if (!tee_attrs) { 543dc8c77fcSVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY; 544dc8c77fcSVesa Jääskeläinen goto out; 545dc8c77fcSVesa Jääskeläinen } 546dc8c77fcSVesa Jääskeläinen 547dc8c77fcSVesa Jääskeläinen TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 548dc8c77fcSVesa Jääskeläinen TEE_ATTR_RSA_OAEP_LABEL, 549dc8c77fcSVesa Jääskeläinen rsa_oaep_ctx->source_data, 550dc8c77fcSVesa Jääskeläinen rsa_oaep_ctx->source_data_len); 551dc8c77fcSVesa Jääskeläinen tee_attrs_count++; 552dc8c77fcSVesa Jääskeläinen break; 553d9af50bcSVesa Jääskeläinen default: 554d9af50bcSVesa Jääskeläinen break; 555d9af50bcSVesa Jääskeläinen } 556d9af50bcSVesa Jääskeläinen 557fb279d8bSVesa Jääskeläinen /* 558fb279d8bSVesa Jääskeläinen * Handle multi stage update step for mechas needing hash 559fb279d8bSVesa Jääskeläinen * calculation 560fb279d8bSVesa Jääskeläinen */ 561fb279d8bSVesa Jääskeläinen if (step == PKCS11_FUNC_STEP_UPDATE) { 562fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 563fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 564fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 565fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 566fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 567fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 5680442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 5690442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 5700442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 5710442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 5720442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 5730442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 574d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 575d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 576d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 577d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 578d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 579fb279d8bSVesa Jääskeläinen assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL); 580fb279d8bSVesa Jääskeläinen 581fb279d8bSVesa Jääskeläinen TEE_DigestUpdate(proc->tee_hash_op_handle, in_buf, 582fb279d8bSVesa Jääskeläinen in_size); 5839df68186SEtienne Carriere rc = PKCS11_CKR_OK; 584fb279d8bSVesa Jääskeläinen break; 585fb279d8bSVesa Jääskeläinen default: 586fb279d8bSVesa Jääskeläinen /* 587fb279d8bSVesa Jääskeläinen * Other mechanism do not expect multi stage 588fb279d8bSVesa Jääskeläinen * operation 589fb279d8bSVesa Jääskeläinen */ 590fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_GENERAL_ERROR; 591fb279d8bSVesa Jääskeläinen break; 592fb279d8bSVesa Jääskeläinen } 593fb279d8bSVesa Jääskeläinen 594fb279d8bSVesa Jääskeläinen goto out; 595fb279d8bSVesa Jääskeläinen } 596fb279d8bSVesa Jääskeläinen 597fb279d8bSVesa Jääskeläinen /* 598fb279d8bSVesa Jääskeläinen * Handle multi stage one shot and final steps for mechas needing hash 599fb279d8bSVesa Jääskeläinen * calculation 600fb279d8bSVesa Jääskeläinen */ 601fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 602fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 603fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 604fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 605fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 606fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 6070442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 6080442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 6090442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 6100442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 6110442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 6120442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 613d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 614d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 615d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 616d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 617d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 618fb279d8bSVesa Jääskeläinen assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL); 619fb279d8bSVesa Jääskeläinen 620fb279d8bSVesa Jääskeläinen hash_size = TEE_ALG_GET_DIGEST_SIZE(proc->tee_hash_algo); 621fb279d8bSVesa Jääskeläinen hash_buf = TEE_Malloc(hash_size, 0); 622fb279d8bSVesa Jääskeläinen if (!hash_buf) 623fb279d8bSVesa Jääskeläinen return PKCS11_CKR_DEVICE_MEMORY; 624fb279d8bSVesa Jääskeläinen 625fb279d8bSVesa Jääskeläinen res = TEE_DigestDoFinal(proc->tee_hash_op_handle, 626fb279d8bSVesa Jääskeläinen in_buf, in_size, hash_buf, 627fb279d8bSVesa Jääskeläinen &hash_size); 628fb279d8bSVesa Jääskeläinen 629fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 630fb279d8bSVesa Jääskeläinen if (rc != PKCS11_CKR_OK) 631fb279d8bSVesa Jääskeläinen goto out; 632fb279d8bSVesa Jääskeläinen 633fb279d8bSVesa Jääskeläinen break; 634fb279d8bSVesa Jääskeläinen default: 635fb279d8bSVesa Jääskeläinen break; 636fb279d8bSVesa Jääskeläinen } 637fb279d8bSVesa Jääskeläinen 638fb279d8bSVesa Jääskeläinen /* 639fb279d8bSVesa Jääskeläinen * Finalize either provided hash or calculated hash with signing 640fb279d8bSVesa Jääskeläinen * operation 641fb279d8bSVesa Jääskeläinen */ 642fb279d8bSVesa Jääskeläinen 643fb279d8bSVesa Jääskeläinen /* First determine amount of bytes for signing operation */ 644fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 645fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 646fb279d8bSVesa Jääskeläinen sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle); 647fb279d8bSVesa Jääskeläinen if (!in_size || !sz) { 648fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 649fb279d8bSVesa Jääskeläinen goto out; 650fb279d8bSVesa Jääskeläinen } 651fb279d8bSVesa Jääskeläinen 652fb279d8bSVesa Jääskeläinen /* 653fb279d8bSVesa Jääskeläinen * Note 3) Input the entire raw digest. Internally, this will 654fb279d8bSVesa Jääskeläinen * be truncated to the appropriate number of bits. 655fb279d8bSVesa Jääskeläinen */ 656fb279d8bSVesa Jääskeläinen if (in_size > sz) 657fb279d8bSVesa Jääskeläinen in_size = sz; 658fb279d8bSVesa Jääskeläinen 659fb279d8bSVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && in2_size != 2 * sz) { 660fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 661fb279d8bSVesa Jääskeläinen goto out; 662fb279d8bSVesa Jääskeläinen } 663fb279d8bSVesa Jääskeläinen break; 664fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 665fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 666fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 667fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 668fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 669fb279d8bSVesa Jääskeläinen /* Get key size in bytes */ 670fb279d8bSVesa Jääskeläinen sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle); 671fb279d8bSVesa Jääskeläinen if (!sz) { 672fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 673fb279d8bSVesa Jääskeläinen goto out; 674fb279d8bSVesa Jääskeläinen } 675fb279d8bSVesa Jääskeläinen 676fb279d8bSVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && 677fb279d8bSVesa Jääskeläinen in2_size != 2 * sz) { 678fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 679fb279d8bSVesa Jääskeläinen goto out; 680fb279d8bSVesa Jääskeläinen } 681fb279d8bSVesa Jääskeläinen break; 6820442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 6830442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 6840442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 6850442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 6860442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 6870442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 6880442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 689d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 690d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 691d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 692d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 693d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 694d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 6950442c956SVesa Jääskeläinen /* Get key size in bytes */ 6960442c956SVesa Jääskeläinen sz = rsa_get_input_max_byte_size(proc->tee_op_handle); 6970442c956SVesa Jääskeläinen if (!sz) { 6980442c956SVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 6990442c956SVesa Jääskeläinen goto out; 7000442c956SVesa Jääskeläinen } 7010442c956SVesa Jääskeläinen 7020442c956SVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && in2_size != sz) { 7030442c956SVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 7040442c956SVesa Jääskeläinen goto out; 7050442c956SVesa Jääskeläinen } 7060442c956SVesa Jääskeläinen break; 707fb279d8bSVesa Jääskeläinen default: 708fb279d8bSVesa Jääskeläinen break; 709fb279d8bSVesa Jääskeläinen } 710fb279d8bSVesa Jääskeläinen 711fb279d8bSVesa Jääskeläinen /* Next perform actual signing operation */ 712fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 713fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 714*03e07432SValerii Chubar case PKCS11_CKM_EDDSA: 7150442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 716dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 717d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 718fb279d8bSVesa Jääskeläinen /* For operations using provided input data */ 719fb279d8bSVesa Jääskeläinen switch (function) { 720fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_ENCRYPT: 721fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricEncrypt(proc->tee_op_handle, 722fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count, 723fb279d8bSVesa Jääskeläinen in_buf, in_size, 724fb279d8bSVesa Jääskeläinen out_buf, &out_size); 725fb279d8bSVesa Jääskeläinen output_data = true; 726fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 7276a6299fbSVesa Jääskeläinen if (rc == PKCS11_CKR_ARGUMENTS_BAD) 7286a6299fbSVesa Jääskeläinen rc = PKCS11_CKR_DATA_LEN_RANGE; 729fb279d8bSVesa Jääskeläinen break; 730fb279d8bSVesa Jääskeläinen 731fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_DECRYPT: 732fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricDecrypt(proc->tee_op_handle, 733fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count, 734fb279d8bSVesa Jääskeläinen in_buf, in_size, 735fb279d8bSVesa Jääskeläinen out_buf, &out_size); 736fb279d8bSVesa Jääskeläinen output_data = true; 737fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 738f27310a5SVesa Jääskeläinen if (rc == PKCS11_CKR_ARGUMENTS_BAD) 739f27310a5SVesa Jääskeläinen rc = PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 740fb279d8bSVesa Jääskeläinen break; 741fb279d8bSVesa Jääskeläinen 742fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_SIGN: 743fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricSignDigest(proc->tee_op_handle, 744fb279d8bSVesa Jääskeläinen tee_attrs, 745fb279d8bSVesa Jääskeläinen tee_attrs_count, 746fb279d8bSVesa Jääskeläinen in_buf, in_size, 747fb279d8bSVesa Jääskeläinen out_buf, &out_size); 748fb279d8bSVesa Jääskeläinen output_data = true; 749fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 750fb279d8bSVesa Jääskeläinen break; 751fb279d8bSVesa Jääskeläinen 752fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_VERIFY: 753fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle, 754fb279d8bSVesa Jääskeläinen tee_attrs, 755fb279d8bSVesa Jääskeläinen tee_attrs_count, 756fb279d8bSVesa Jääskeläinen in_buf, in_size, 757fb279d8bSVesa Jääskeläinen in2_buf, in2_size); 758fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 759fb279d8bSVesa Jääskeläinen break; 760fb279d8bSVesa Jääskeläinen 761fb279d8bSVesa Jääskeläinen default: 762fb279d8bSVesa Jääskeläinen TEE_Panic(function); 763fb279d8bSVesa Jääskeläinen break; 764fb279d8bSVesa Jääskeläinen } 765fb279d8bSVesa Jääskeläinen break; 766fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 767fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 768fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 769fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 770fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 7710442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 7720442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 7730442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 7740442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 7750442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 7760442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 777d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 778d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 779d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 780d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 781d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 782fb279d8bSVesa Jääskeläinen /* For operations having hash operation use calculated hash */ 783fb279d8bSVesa Jääskeläinen switch (function) { 784fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_SIGN: 785fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricSignDigest(proc->tee_op_handle, 786fb279d8bSVesa Jääskeläinen tee_attrs, 787fb279d8bSVesa Jääskeläinen tee_attrs_count, 788fb279d8bSVesa Jääskeläinen hash_buf, hash_size, 789fb279d8bSVesa Jääskeläinen out_buf, &out_size); 790fb279d8bSVesa Jääskeläinen output_data = true; 791fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 792fb279d8bSVesa Jääskeläinen break; 793fb279d8bSVesa Jääskeläinen 794fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_VERIFY: 795fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle, 796fb279d8bSVesa Jääskeläinen tee_attrs, 797fb279d8bSVesa Jääskeläinen tee_attrs_count, 798fb279d8bSVesa Jääskeläinen hash_buf, hash_size, 799fb279d8bSVesa Jääskeläinen in2_buf, in2_size); 800fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 801fb279d8bSVesa Jääskeläinen break; 802fb279d8bSVesa Jääskeläinen 803fb279d8bSVesa Jääskeläinen default: 804fb279d8bSVesa Jääskeläinen TEE_Panic(function); 805fb279d8bSVesa Jääskeläinen break; 806fb279d8bSVesa Jääskeläinen } 807fb279d8bSVesa Jääskeläinen break; 808fb279d8bSVesa Jääskeläinen default: 809fb279d8bSVesa Jääskeläinen TEE_Panic(proc->mecha_type); 810fb279d8bSVesa Jääskeläinen break; 811fb279d8bSVesa Jääskeläinen } 812fb279d8bSVesa Jääskeläinen 813fb279d8bSVesa Jääskeläinen out: 814fb279d8bSVesa Jääskeläinen if (output_data && 815fb279d8bSVesa Jääskeläinen (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 816fb279d8bSVesa Jääskeläinen switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 817fb279d8bSVesa Jääskeläinen case TEE_PARAM_TYPE_MEMREF_OUTPUT: 818fb279d8bSVesa Jääskeläinen case TEE_PARAM_TYPE_MEMREF_INOUT: 819fb279d8bSVesa Jääskeläinen params[2].memref.size = out_size; 820fb279d8bSVesa Jääskeläinen break; 821fb279d8bSVesa Jääskeläinen default: 822fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_GENERAL_ERROR; 823fb279d8bSVesa Jääskeläinen break; 824fb279d8bSVesa Jääskeläinen } 825fb279d8bSVesa Jääskeläinen } 826fb279d8bSVesa Jääskeläinen 827fb279d8bSVesa Jääskeläinen TEE_Free(hash_buf); 828fb279d8bSVesa Jääskeläinen TEE_Free(tee_attrs); 829fb279d8bSVesa Jääskeläinen 830fb279d8bSVesa Jääskeläinen return rc; 831fb279d8bSVesa Jääskeläinen } 832cc062b46SJorge Ramirez-Ortiz 833cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc do_asymm_derivation(struct pkcs11_session *session, 834cc062b46SJorge Ramirez-Ortiz struct pkcs11_attribute_head *proc_params, 835cc062b46SJorge Ramirez-Ortiz struct obj_attrs **head) 836cc062b46SJorge Ramirez-Ortiz { 837cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 838cc062b46SJorge Ramirez-Ortiz TEE_ObjectHandle out_handle = TEE_HANDLE_NULL; 839cc062b46SJorge Ramirez-Ortiz TEE_Result res = TEE_ERROR_GENERIC; 840cc062b46SJorge Ramirez-Ortiz TEE_Attribute tee_attrs[2] = { }; 841cc062b46SJorge Ramirez-Ortiz size_t tee_attrs_count = 0; 842cc062b46SJorge Ramirez-Ortiz uint32_t key_byte_size = 0; 843cc062b46SJorge Ramirez-Ortiz uint32_t key_bit_size = 0; 844cc062b46SJorge Ramirez-Ortiz void *a_ptr = NULL; 845cc062b46SJorge Ramirez-Ortiz size_t a_size = 0; 846cc062b46SJorge Ramirez-Ortiz 847cc062b46SJorge Ramirez-Ortiz /* Remove default attribute set at template sanitization */ 848cc062b46SJorge Ramirez-Ortiz if (remove_empty_attribute(head, PKCS11_CKA_VALUE)) 849cc062b46SJorge Ramirez-Ortiz return PKCS11_CKR_FUNCTION_FAILED; 850cc062b46SJorge Ramirez-Ortiz 851cc062b46SJorge Ramirez-Ortiz rc = get_u32_attribute(*head, PKCS11_CKA_VALUE_LEN, &key_bit_size); 852cc062b46SJorge Ramirez-Ortiz if (rc) 853cc062b46SJorge Ramirez-Ortiz return rc; 854cc062b46SJorge Ramirez-Ortiz 855cc062b46SJorge Ramirez-Ortiz key_bit_size *= 8; 856cc062b46SJorge Ramirez-Ortiz key_byte_size = (key_bit_size + 7) / 8; 857cc062b46SJorge Ramirez-Ortiz 858cc062b46SJorge Ramirez-Ortiz res = TEE_AllocateTransientObject(TEE_TYPE_GENERIC_SECRET, 859cc062b46SJorge Ramirez-Ortiz key_byte_size * 8, &out_handle); 860cc062b46SJorge Ramirez-Ortiz if (res) { 861cc062b46SJorge Ramirez-Ortiz DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 862cc062b46SJorge Ramirez-Ortiz return tee2pkcs_error(res); 863cc062b46SJorge Ramirez-Ortiz } 864cc062b46SJorge Ramirez-Ortiz 865cc062b46SJorge Ramirez-Ortiz switch (proc_params->id) { 866cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 867cc062b46SJorge Ramirez-Ortiz rc = pkcs2tee_param_ecdh(proc_params, &a_ptr, &a_size); 868cc062b46SJorge Ramirez-Ortiz if (rc) 869cc062b46SJorge Ramirez-Ortiz goto out; 870cc062b46SJorge Ramirez-Ortiz 871cc062b46SJorge Ramirez-Ortiz TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 872cc062b46SJorge Ramirez-Ortiz TEE_ATTR_ECC_PUBLIC_VALUE_X, 873cc062b46SJorge Ramirez-Ortiz a_ptr, a_size / 2); 874cc062b46SJorge Ramirez-Ortiz tee_attrs_count++; 875cc062b46SJorge Ramirez-Ortiz TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 876cc062b46SJorge Ramirez-Ortiz TEE_ATTR_ECC_PUBLIC_VALUE_Y, 877cc062b46SJorge Ramirez-Ortiz (char *)a_ptr + a_size / 2, 878cc062b46SJorge Ramirez-Ortiz a_size / 2); 879cc062b46SJorge Ramirez-Ortiz tee_attrs_count++; 880cc062b46SJorge Ramirez-Ortiz break; 881cc062b46SJorge Ramirez-Ortiz default: 882cc062b46SJorge Ramirez-Ortiz TEE_Panic(proc_params->id); 883cc062b46SJorge Ramirez-Ortiz break; 884cc062b46SJorge Ramirez-Ortiz } 885cc062b46SJorge Ramirez-Ortiz 886cc062b46SJorge Ramirez-Ortiz TEE_DeriveKey(session->processing->tee_op_handle, &tee_attrs[0], 887cc062b46SJorge Ramirez-Ortiz tee_attrs_count, out_handle); 888cc062b46SJorge Ramirez-Ortiz 889cc062b46SJorge Ramirez-Ortiz rc = alloc_get_tee_attribute_data(out_handle, TEE_ATTR_SECRET_VALUE, 890cc062b46SJorge Ramirez-Ortiz &a_ptr, &a_size); 891cc062b46SJorge Ramirez-Ortiz if (rc) 892cc062b46SJorge Ramirez-Ortiz goto out; 893cc062b46SJorge Ramirez-Ortiz 894cc062b46SJorge Ramirez-Ortiz if (a_size * 8 < key_bit_size) 895cc062b46SJorge Ramirez-Ortiz rc = PKCS11_CKR_KEY_SIZE_RANGE; 896cc062b46SJorge Ramirez-Ortiz else 897cc062b46SJorge Ramirez-Ortiz rc = add_attribute(head, PKCS11_CKA_VALUE, a_ptr, 898cc062b46SJorge Ramirez-Ortiz key_byte_size); 899cc062b46SJorge Ramirez-Ortiz TEE_Free(a_ptr); 900cc062b46SJorge Ramirez-Ortiz out: 901cc062b46SJorge Ramirez-Ortiz release_active_processing(session); 902cc062b46SJorge Ramirez-Ortiz TEE_FreeTransientObject(out_handle); 903cc062b46SJorge Ramirez-Ortiz 904cc062b46SJorge Ramirez-Ortiz return rc; 905cc062b46SJorge Ramirez-Ortiz } 906