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> 8*45d40bdaSValerii Chubar #include <mbedtls/nist_kw.h> 9fb279d8bSVesa Jääskeläinen #include <tee_api_defines.h> 10fb279d8bSVesa Jääskeläinen #include <tee_internal_api.h> 11fb279d8bSVesa Jääskeläinen #include <tee_internal_api_extensions.h> 12fb279d8bSVesa Jääskeläinen 13fb279d8bSVesa Jääskeläinen #include "attributes.h" 14fb279d8bSVesa Jääskeläinen #include "pkcs11_helpers.h" 15fb279d8bSVesa Jääskeläinen #include "pkcs11_token.h" 16fb279d8bSVesa Jääskeläinen #include "processing.h" 17fb279d8bSVesa Jääskeläinen #include "serializer.h" 18fb279d8bSVesa Jääskeläinen 19fb279d8bSVesa Jääskeläinen bool processing_is_tee_asymm(uint32_t proc_id) 20fb279d8bSVesa Jääskeläinen { 21fb279d8bSVesa Jääskeläinen switch (proc_id) { 220442c956SVesa Jääskeläinen /* RSA flavors */ 23*45d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 240442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 25dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 26d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 270442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 280442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 290442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 300442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 310442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 320442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 33d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 34d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 35d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 36d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 37d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 38fb279d8bSVesa Jääskeläinen /* EC flavors */ 3903e07432SValerii Chubar case PKCS11_CKM_EDDSA: 40fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 41cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 42fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 43fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 44fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 45fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 46fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 47fb279d8bSVesa Jääskeläinen return true; 48fb279d8bSVesa Jääskeläinen default: 49fb279d8bSVesa Jääskeläinen return false; 50fb279d8bSVesa Jääskeläinen } 51fb279d8bSVesa Jääskeläinen } 52fb279d8bSVesa Jääskeläinen 53fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 54fb279d8bSVesa Jääskeläinen pkcs2tee_algorithm(uint32_t *tee_id, uint32_t *tee_hash_id, 55fb279d8bSVesa Jääskeläinen enum processing_func function __unused, 56fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 57fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 58fb279d8bSVesa Jääskeläinen { 59fb279d8bSVesa Jääskeläinen static const struct { 60fb279d8bSVesa Jääskeläinen enum pkcs11_mechanism_id mech_id; 61fb279d8bSVesa Jääskeläinen uint32_t tee_id; 62fb279d8bSVesa Jääskeläinen uint32_t tee_hash_id; 63fb279d8bSVesa Jääskeläinen } pkcs2tee_algo[] = { 640442c956SVesa Jääskeläinen /* RSA flavors */ 65*45d40bdaSValerii Chubar { PKCS11_CKM_RSA_AES_KEY_WRAP, 1, 0 }, 660442c956SVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS, TEE_ALG_RSAES_PKCS1_V1_5, 0 }, 67dc8c77fcSVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS_OAEP, 1, 0 }, 68d9af50bcSVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS_PSS, 1, 0 }, 690442c956SVesa Jääskeläinen { PKCS11_CKM_MD5_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_MD5, 700442c956SVesa Jääskeläinen TEE_ALG_MD5 }, 710442c956SVesa Jääskeläinen { PKCS11_CKM_SHA1_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA1, 720442c956SVesa Jääskeläinen TEE_ALG_SHA1 }, 730442c956SVesa Jääskeläinen { PKCS11_CKM_SHA224_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA224, 740442c956SVesa Jääskeläinen TEE_ALG_SHA224 }, 750442c956SVesa Jääskeläinen { PKCS11_CKM_SHA256_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA256, 760442c956SVesa Jääskeläinen TEE_ALG_SHA256 }, 770442c956SVesa Jääskeläinen { PKCS11_CKM_SHA384_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA384, 780442c956SVesa Jääskeläinen TEE_ALG_SHA384 }, 790442c956SVesa Jääskeläinen { PKCS11_CKM_SHA512_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA512, 800442c956SVesa Jääskeläinen TEE_ALG_SHA512 }, 81d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA1_RSA_PKCS_PSS, 82d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1, TEE_ALG_SHA1 }, 83d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA224_RSA_PKCS_PSS, 84d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224, TEE_ALG_SHA224 }, 85d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA256_RSA_PKCS_PSS, 86d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256, TEE_ALG_SHA256 }, 87d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA384_RSA_PKCS_PSS, 88d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384, TEE_ALG_SHA384 }, 89d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA512_RSA_PKCS_PSS, 90d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512, TEE_ALG_SHA512 }, 91fb279d8bSVesa Jääskeläinen /* EC flavors (Must find key size from the object) */ 92fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA, 1, 0 }, 93fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA1, 1, TEE_ALG_SHA1 }, 94fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA224, 1, TEE_ALG_SHA224 }, 95fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA256, 1, TEE_ALG_SHA256 }, 96fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA384, 1, TEE_ALG_SHA384 }, 97fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA512, 1, TEE_ALG_SHA512 }, 98cc062b46SJorge Ramirez-Ortiz { PKCS11_CKM_ECDH1_DERIVE, 1, 0 }, 9903e07432SValerii Chubar { PKCS11_CKM_EDDSA, TEE_ALG_ED25519, 0 }, 100fb279d8bSVesa Jääskeläinen }; 101fb279d8bSVesa Jääskeläinen size_t n = 0; 102fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 103fb279d8bSVesa Jääskeläinen 104fb279d8bSVesa Jääskeläinen for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) { 105fb279d8bSVesa Jääskeläinen if (pkcs2tee_algo[n].mech_id == proc_params->id) { 106fb279d8bSVesa Jääskeläinen *tee_id = pkcs2tee_algo[n].tee_id; 107fb279d8bSVesa Jääskeläinen *tee_hash_id = pkcs2tee_algo[n].tee_hash_id; 108fb279d8bSVesa Jääskeläinen break; 109fb279d8bSVesa Jääskeläinen } 110fb279d8bSVesa Jääskeläinen } 111fb279d8bSVesa Jääskeläinen 112fb279d8bSVesa Jääskeläinen if (n == ARRAY_SIZE(pkcs2tee_algo)) 113fb279d8bSVesa Jääskeläinen return PKCS11_RV_NOT_IMPLEMENTED; 114fb279d8bSVesa Jääskeläinen 115fb279d8bSVesa Jääskeläinen switch (proc_params->id) { 116d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 117d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 118d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 119d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 120d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 121d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 122d9af50bcSVesa Jääskeläinen rc = pkcs2tee_algo_rsa_pss(tee_id, proc_params); 123d9af50bcSVesa Jääskeläinen break; 124dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 125dc8c77fcSVesa Jääskeläinen rc = pkcs2tee_algo_rsa_oaep(tee_id, tee_hash_id, proc_params); 126dc8c77fcSVesa Jääskeläinen break; 127*45d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 128*45d40bdaSValerii Chubar rc = pkcs2tee_algo_rsa_aes_wrap(tee_id, tee_hash_id, 129*45d40bdaSValerii Chubar proc_params); 130*45d40bdaSValerii Chubar break; 131fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 132fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 133fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 134fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 135fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 136fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 137fb279d8bSVesa Jääskeläinen rc = pkcs2tee_algo_ecdsa(tee_id, proc_params, obj); 138fb279d8bSVesa Jääskeläinen break; 139cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 140cc062b46SJorge Ramirez-Ortiz rc = pkcs2tee_algo_ecdh(tee_id, proc_params, obj); 141cc062b46SJorge Ramirez-Ortiz break; 142fb279d8bSVesa Jääskeläinen default: 143fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_OK; 144fb279d8bSVesa Jääskeläinen break; 145fb279d8bSVesa Jääskeläinen } 146fb279d8bSVesa Jääskeläinen 1470442c956SVesa Jääskeläinen /* 1480442c956SVesa Jääskeläinen * PKCS#11 uses single mechanism CKM_RSA_PKCS for both ciphering and 1490442c956SVesa Jääskeläinen * authentication whereas GPD TEE expects TEE_ALG_RSAES_PKCS1_V1_5 for 1500442c956SVesa Jääskeläinen * ciphering and TEE_ALG_RSASSA_PKCS1_V1_5 for authentication. 1510442c956SVesa Jääskeläinen */ 1520442c956SVesa Jääskeläinen if (*tee_id == TEE_ALG_RSAES_PKCS1_V1_5 && 1530442c956SVesa Jääskeläinen (function == PKCS11_FUNCTION_SIGN || 1540442c956SVesa Jääskeläinen function == PKCS11_FUNCTION_VERIFY)) 1550442c956SVesa Jääskeläinen *tee_id = TEE_ALG_RSASSA_PKCS1_V1_5; 1560442c956SVesa Jääskeläinen 157fb279d8bSVesa Jääskeläinen return rc; 158fb279d8bSVesa Jääskeläinen } 159fb279d8bSVesa Jääskeläinen 160fb279d8bSVesa Jääskeläinen static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type, 161fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj, 162fb279d8bSVesa Jääskeläinen enum processing_func function) 163fb279d8bSVesa Jääskeläinen { 164fb279d8bSVesa Jääskeläinen enum pkcs11_class_id class = get_class(obj->attributes); 165fb279d8bSVesa Jääskeläinen enum pkcs11_key_type type = get_key_type(obj->attributes); 166fb279d8bSVesa Jääskeläinen 167fb279d8bSVesa Jääskeläinen switch (class) { 168fb279d8bSVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 169fb279d8bSVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 170fb279d8bSVesa Jääskeläinen break; 171fb279d8bSVesa Jääskeläinen default: 172fb279d8bSVesa Jääskeläinen TEE_Panic(class); 173fb279d8bSVesa Jääskeläinen break; 174fb279d8bSVesa Jääskeläinen } 175fb279d8bSVesa Jääskeläinen 176fb279d8bSVesa Jääskeläinen switch (type) { 177fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 178cc062b46SJorge Ramirez-Ortiz if (class == PKCS11_CKO_PRIVATE_KEY) { 179cc062b46SJorge Ramirez-Ortiz if (function == PKCS11_FUNCTION_DERIVE) 180cc062b46SJorge Ramirez-Ortiz *tee_type = TEE_TYPE_ECDH_KEYPAIR; 181cc062b46SJorge Ramirez-Ortiz else 182fb279d8bSVesa Jääskeläinen *tee_type = TEE_TYPE_ECDSA_KEYPAIR; 183cc062b46SJorge Ramirez-Ortiz } else { 184cc062b46SJorge Ramirez-Ortiz if (function == PKCS11_FUNCTION_DERIVE) 185cc062b46SJorge Ramirez-Ortiz *tee_type = TEE_TYPE_ECDH_PUBLIC_KEY; 186fb279d8bSVesa Jääskeläinen else 187fb279d8bSVesa Jääskeläinen *tee_type = TEE_TYPE_ECDSA_PUBLIC_KEY; 188cc062b46SJorge Ramirez-Ortiz } 189fb279d8bSVesa Jääskeläinen break; 1900442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 1910442c956SVesa Jääskeläinen if (class == PKCS11_CKO_PRIVATE_KEY) 1920442c956SVesa Jääskeläinen *tee_type = TEE_TYPE_RSA_KEYPAIR; 1930442c956SVesa Jääskeläinen else 1940442c956SVesa Jääskeläinen *tee_type = TEE_TYPE_RSA_PUBLIC_KEY; 1950442c956SVesa Jääskeläinen break; 19603e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 19703e07432SValerii Chubar if (class == PKCS11_CKO_PRIVATE_KEY) 19803e07432SValerii Chubar *tee_type = TEE_TYPE_ED25519_KEYPAIR; 19903e07432SValerii Chubar else 20003e07432SValerii Chubar *tee_type = TEE_TYPE_ED25519_PUBLIC_KEY; 20103e07432SValerii Chubar break; 202fb279d8bSVesa Jääskeläinen default: 203fb279d8bSVesa Jääskeläinen TEE_Panic(type); 204fb279d8bSVesa Jääskeläinen break; 205fb279d8bSVesa Jääskeläinen } 206fb279d8bSVesa Jääskeläinen 207fb279d8bSVesa Jääskeläinen return PKCS11_CKR_OK; 208fb279d8bSVesa Jääskeläinen } 209fb279d8bSVesa Jääskeläinen 210fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 211fb279d8bSVesa Jääskeläinen allocate_tee_operation(struct pkcs11_session *session, 212fb279d8bSVesa Jääskeläinen enum processing_func function, 213fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *params, 214fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 215fb279d8bSVesa Jääskeläinen { 216fb279d8bSVesa Jääskeläinen uint32_t size = (uint32_t)get_object_key_bit_size(obj); 217fb279d8bSVesa Jääskeläinen uint32_t algo = 0; 218fb279d8bSVesa Jääskeläinen uint32_t hash_algo = 0; 219fb279d8bSVesa Jääskeläinen uint32_t mode = 0; 220fb279d8bSVesa Jääskeläinen uint32_t hash_mode = 0; 221fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 222fb279d8bSVesa Jääskeläinen struct active_processing *processing = session->processing; 223fb279d8bSVesa Jääskeläinen 224fb279d8bSVesa Jääskeläinen assert(processing->tee_op_handle == TEE_HANDLE_NULL); 225fb279d8bSVesa Jääskeläinen assert(processing->tee_hash_op_handle == TEE_HANDLE_NULL); 226fb279d8bSVesa Jääskeläinen 227fb279d8bSVesa Jääskeläinen if (pkcs2tee_algorithm(&algo, &hash_algo, function, params, obj)) 228fb279d8bSVesa Jääskeläinen return PKCS11_CKR_FUNCTION_FAILED; 229fb279d8bSVesa Jääskeläinen 230fb279d8bSVesa Jääskeläinen pkcs2tee_mode(&mode, function); 231fb279d8bSVesa Jääskeläinen 232fb279d8bSVesa Jääskeläinen if (hash_algo) { 233fb279d8bSVesa Jääskeläinen pkcs2tee_mode(&hash_mode, PKCS11_FUNCTION_DIGEST); 234fb279d8bSVesa Jääskeläinen 235fb279d8bSVesa Jääskeläinen res = TEE_AllocateOperation(&processing->tee_hash_op_handle, 236fb279d8bSVesa Jääskeläinen hash_algo, hash_mode, 0); 237fb279d8bSVesa Jääskeläinen if (res) { 238fb279d8bSVesa Jääskeläinen EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32, 239fb279d8bSVesa Jääskeläinen hash_algo, hash_mode); 240fb279d8bSVesa Jääskeläinen 241fb279d8bSVesa Jääskeläinen if (res == TEE_ERROR_NOT_SUPPORTED) 242fb279d8bSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_INVALID; 243fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 244fb279d8bSVesa Jääskeläinen } 245fb279d8bSVesa Jääskeläinen processing->tee_hash_algo = hash_algo; 246fb279d8bSVesa Jääskeläinen } 247fb279d8bSVesa Jääskeläinen 248fb279d8bSVesa Jääskeläinen res = TEE_AllocateOperation(&processing->tee_op_handle, 249fb279d8bSVesa Jääskeläinen algo, mode, size); 250fb279d8bSVesa Jääskeläinen if (res) 251fb279d8bSVesa Jääskeläinen EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 252fb279d8bSVesa Jääskeläinen algo, mode, size); 253fb279d8bSVesa Jääskeläinen 254fb279d8bSVesa Jääskeläinen if (res == TEE_ERROR_NOT_SUPPORTED) 255fb279d8bSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_INVALID; 256fb279d8bSVesa Jääskeläinen 257fb279d8bSVesa Jääskeläinen if (res != TEE_SUCCESS && 258fb279d8bSVesa Jääskeläinen processing->tee_hash_op_handle != TEE_HANDLE_NULL) { 259fb279d8bSVesa Jääskeläinen TEE_FreeOperation(session->processing->tee_hash_op_handle); 260fb279d8bSVesa Jääskeläinen processing->tee_hash_op_handle = TEE_HANDLE_NULL; 261fb279d8bSVesa Jääskeläinen processing->tee_hash_algo = 0; 262fb279d8bSVesa Jääskeläinen } 263fb279d8bSVesa Jääskeläinen 264fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 265fb279d8bSVesa Jääskeläinen } 266fb279d8bSVesa Jääskeläinen 267fb279d8bSVesa Jääskeläinen static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 268fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj, 269fb279d8bSVesa Jääskeläinen enum processing_func function) 270fb279d8bSVesa Jääskeläinen { 271fb279d8bSVesa Jääskeläinen TEE_Attribute *tee_attrs = NULL; 272fb279d8bSVesa Jääskeläinen size_t tee_attrs_count = 0; 273fb279d8bSVesa Jääskeläinen size_t object_size = 0; 274fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 275fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 276fb279d8bSVesa Jääskeläinen enum pkcs11_class_id __maybe_unused class = get_class(obj->attributes); 277fb279d8bSVesa Jääskeläinen enum pkcs11_key_type type = get_key_type(obj->attributes); 278fb279d8bSVesa Jääskeläinen 279fb279d8bSVesa Jääskeläinen assert(class == PKCS11_CKO_PUBLIC_KEY || 280fb279d8bSVesa Jääskeläinen class == PKCS11_CKO_PRIVATE_KEY); 281fb279d8bSVesa Jääskeläinen 282fb279d8bSVesa Jääskeläinen if (obj->key_handle != TEE_HANDLE_NULL) { 283fb279d8bSVesa Jääskeläinen switch (type) { 2840442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 2850442c956SVesa Jääskeläinen /* RSA loaded keys can be reused */ 2860442c956SVesa Jääskeläinen assert((obj->key_type == TEE_TYPE_RSA_PUBLIC_KEY && 2870442c956SVesa Jääskeläinen class == PKCS11_CKO_PUBLIC_KEY) || 2880442c956SVesa Jääskeläinen (obj->key_type == TEE_TYPE_RSA_KEYPAIR && 2890442c956SVesa Jääskeläinen class == PKCS11_CKO_PRIVATE_KEY)); 2900442c956SVesa Jääskeläinen goto key_ready; 291fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 292fb279d8bSVesa Jääskeläinen /* Reuse EC TEE key only if already DSA or DH */ 293fb279d8bSVesa Jääskeläinen switch (obj->key_type) { 294fb279d8bSVesa Jääskeläinen case TEE_TYPE_ECDSA_PUBLIC_KEY: 295fb279d8bSVesa Jääskeläinen case TEE_TYPE_ECDSA_KEYPAIR: 296fb279d8bSVesa Jääskeläinen if (function != PKCS11_FUNCTION_DERIVE) 297fb279d8bSVesa Jääskeläinen goto key_ready; 298fb279d8bSVesa Jääskeläinen break; 299cc062b46SJorge Ramirez-Ortiz case TEE_TYPE_ECDH_PUBLIC_KEY: 300cc062b46SJorge Ramirez-Ortiz case TEE_TYPE_ECDH_KEYPAIR: 301cc062b46SJorge Ramirez-Ortiz if (function == PKCS11_FUNCTION_DERIVE) 302cc062b46SJorge Ramirez-Ortiz goto key_ready; 303cc062b46SJorge Ramirez-Ortiz break; 304fb279d8bSVesa Jääskeläinen default: 305fb279d8bSVesa Jääskeläinen assert(0); 306fb279d8bSVesa Jääskeläinen break; 307fb279d8bSVesa Jääskeläinen } 308fb279d8bSVesa Jääskeläinen break; 309fb279d8bSVesa Jääskeläinen default: 310fb279d8bSVesa Jääskeläinen assert(0); 311fb279d8bSVesa Jääskeläinen break; 312fb279d8bSVesa Jääskeläinen } 313fb279d8bSVesa Jääskeläinen 314fb279d8bSVesa Jääskeläinen TEE_CloseObject(obj->key_handle); 315fb279d8bSVesa Jääskeläinen obj->key_handle = TEE_HANDLE_NULL; 316fb279d8bSVesa Jääskeläinen } 317fb279d8bSVesa Jääskeläinen 318fb279d8bSVesa Jääskeläinen rc = pkcs2tee_key_type(&obj->key_type, obj, function); 319fb279d8bSVesa Jääskeläinen if (rc) 320fb279d8bSVesa Jääskeläinen return rc; 321fb279d8bSVesa Jääskeläinen 322fb279d8bSVesa Jääskeläinen object_size = get_object_key_bit_size(obj); 323fb279d8bSVesa Jääskeläinen if (!object_size) 324fb279d8bSVesa Jääskeläinen return PKCS11_CKR_GENERAL_ERROR; 325fb279d8bSVesa Jääskeläinen 326fb279d8bSVesa Jääskeläinen switch (type) { 3270442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 3280442c956SVesa Jääskeläinen rc = load_tee_rsa_key_attrs(&tee_attrs, &tee_attrs_count, obj); 3290442c956SVesa Jääskeläinen break; 330fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 331fb279d8bSVesa Jääskeläinen rc = load_tee_ec_key_attrs(&tee_attrs, &tee_attrs_count, obj); 332fb279d8bSVesa Jääskeläinen break; 33303e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 33403e07432SValerii Chubar rc = load_tee_eddsa_key_attrs(&tee_attrs, &tee_attrs_count, 33503e07432SValerii Chubar obj); 33603e07432SValerii Chubar break; 337fb279d8bSVesa Jääskeläinen default: 338fb279d8bSVesa Jääskeläinen break; 339fb279d8bSVesa Jääskeläinen } 340fb279d8bSVesa Jääskeläinen if (rc) 341fb279d8bSVesa Jääskeläinen return rc; 342fb279d8bSVesa Jääskeläinen 343fb279d8bSVesa Jääskeläinen res = TEE_AllocateTransientObject(obj->key_type, object_size, 344fb279d8bSVesa Jääskeläinen &obj->key_handle); 345fb279d8bSVesa Jääskeläinen if (res) { 346fb279d8bSVesa Jääskeläinen DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 347fb279d8bSVesa Jääskeläinen 348fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 349fb279d8bSVesa Jääskeläinen } 350fb279d8bSVesa Jääskeläinen 351fb279d8bSVesa Jääskeläinen res = TEE_PopulateTransientObject(obj->key_handle, 352fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count); 353fb279d8bSVesa Jääskeläinen 354fb279d8bSVesa Jääskeläinen TEE_Free(tee_attrs); 355fb279d8bSVesa Jääskeläinen 356fb279d8bSVesa Jääskeläinen if (res) { 357fb279d8bSVesa Jääskeläinen DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 358fb279d8bSVesa Jääskeläinen 359fb279d8bSVesa Jääskeläinen goto error; 360fb279d8bSVesa Jääskeläinen } 361fb279d8bSVesa Jääskeläinen 362fb279d8bSVesa Jääskeläinen key_ready: 363fb279d8bSVesa Jääskeläinen res = TEE_SetOperationKey(session->processing->tee_op_handle, 364fb279d8bSVesa Jääskeläinen obj->key_handle); 365fb279d8bSVesa Jääskeläinen if (res) { 366fb279d8bSVesa Jääskeläinen DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 367fb279d8bSVesa Jääskeläinen 368fb279d8bSVesa Jääskeläinen goto error; 369fb279d8bSVesa Jääskeläinen } 370fb279d8bSVesa Jääskeläinen 371fb279d8bSVesa Jääskeläinen return PKCS11_CKR_OK; 372fb279d8bSVesa Jääskeläinen 373fb279d8bSVesa Jääskeläinen error: 374fb279d8bSVesa Jääskeläinen TEE_FreeTransientObject(obj->key_handle); 375fb279d8bSVesa Jääskeläinen obj->key_handle = TEE_HANDLE_NULL; 376fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 377fb279d8bSVesa Jääskeläinen } 378fb279d8bSVesa Jääskeläinen 379fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 380d9af50bcSVesa Jääskeläinen init_tee_operation(struct pkcs11_session *session, 381d9af50bcSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 382d9af50bcSVesa Jääskeläinen struct pkcs11_object *obj) 383fb279d8bSVesa Jääskeläinen { 384d9af50bcSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK; 385d9af50bcSVesa Jääskeläinen struct active_processing *proc = session->processing; 386d9af50bcSVesa Jääskeläinen 387d9af50bcSVesa Jääskeläinen switch (proc_params->id) { 388d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 389d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 390d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 391d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 392d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 393d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 394d9af50bcSVesa Jääskeläinen rc = pkcs2tee_proc_params_rsa_pss(proc, proc_params); 395d9af50bcSVesa Jääskeläinen if (rc) 396d9af50bcSVesa Jääskeläinen break; 397d9af50bcSVesa Jääskeläinen 398d9af50bcSVesa Jääskeläinen rc = pkcs2tee_validate_rsa_pss(proc, obj); 399d9af50bcSVesa Jääskeläinen break; 400dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 401dc8c77fcSVesa Jääskeläinen rc = pkcs2tee_proc_params_rsa_oaep(proc, proc_params); 402dc8c77fcSVesa Jääskeläinen break; 40303e07432SValerii Chubar case PKCS11_CKM_EDDSA: 40403e07432SValerii Chubar rc = pkcs2tee_proc_params_eddsa(proc, proc_params); 40503e07432SValerii Chubar break; 406*45d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 407*45d40bdaSValerii Chubar rc = pkcs2tee_proc_params_rsa_aes_wrap(proc, proc_params); 408*45d40bdaSValerii Chubar break; 409d9af50bcSVesa Jääskeläinen default: 410d9af50bcSVesa Jääskeläinen break; 411d9af50bcSVesa Jääskeläinen } 412d9af50bcSVesa Jääskeläinen 413d9af50bcSVesa Jääskeläinen return rc; 414fb279d8bSVesa Jääskeläinen } 415fb279d8bSVesa Jääskeläinen 416fb279d8bSVesa Jääskeläinen enum pkcs11_rc init_asymm_operation(struct pkcs11_session *session, 417fb279d8bSVesa Jääskeläinen enum processing_func function, 418fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 419fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 420fb279d8bSVesa Jääskeläinen { 421fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 422fb279d8bSVesa Jääskeläinen 423fb279d8bSVesa Jääskeläinen assert(processing_is_tee_asymm(proc_params->id)); 424fb279d8bSVesa Jääskeläinen 425fb279d8bSVesa Jääskeläinen rc = allocate_tee_operation(session, function, proc_params, obj); 426fb279d8bSVesa Jääskeläinen if (rc) 427fb279d8bSVesa Jääskeläinen return rc; 428fb279d8bSVesa Jääskeläinen 429fb279d8bSVesa Jääskeläinen rc = load_tee_key(session, obj, function); 430fb279d8bSVesa Jääskeläinen if (rc) 431fb279d8bSVesa Jääskeläinen return rc; 432fb279d8bSVesa Jääskeläinen 433d9af50bcSVesa Jääskeläinen return init_tee_operation(session, proc_params, obj); 434fb279d8bSVesa Jääskeläinen } 435fb279d8bSVesa Jääskeläinen 436fb279d8bSVesa Jääskeläinen /* 437fb279d8bSVesa Jääskeläinen * step_sym_step - step (update/oneshot/final) on a symmetric crypto operation 438fb279d8bSVesa Jääskeläinen * 439fb279d8bSVesa Jääskeläinen * @session - current session 440fb279d8bSVesa Jääskeläinen * @function - processing function (encrypt, decrypt, sign, ...) 441fb279d8bSVesa Jääskeläinen * @step - step ID in the processing (oneshot, update, final) 442fb279d8bSVesa Jääskeläinen * @ptypes - invocation parameter types 443fb279d8bSVesa Jääskeläinen * @params - invocation parameter references 444fb279d8bSVesa Jääskeläinen */ 445fb279d8bSVesa Jääskeläinen enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session, 446fb279d8bSVesa Jääskeläinen enum processing_func function, 447fb279d8bSVesa Jääskeläinen enum processing_step step, 448fb279d8bSVesa Jääskeläinen uint32_t ptypes, TEE_Param *params) 449fb279d8bSVesa Jääskeläinen { 450fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 451fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 452fb279d8bSVesa Jääskeläinen void *in_buf = NULL; 453fb279d8bSVesa Jääskeläinen void *in2_buf = NULL; 454fb279d8bSVesa Jääskeläinen void *out_buf = NULL; 455fb279d8bSVesa Jääskeläinen void *hash_buf = NULL; 456fb279d8bSVesa Jääskeläinen uint32_t in_size = 0; 457fb279d8bSVesa Jääskeläinen uint32_t in2_size = 0; 458fb279d8bSVesa Jääskeläinen uint32_t out_size = 0; 459fb279d8bSVesa Jääskeläinen uint32_t hash_size = 0; 460fb279d8bSVesa Jääskeläinen TEE_Attribute *tee_attrs = NULL; 461fb279d8bSVesa Jääskeläinen size_t tee_attrs_count = 0; 462fb279d8bSVesa Jääskeläinen bool output_data = false; 463fb279d8bSVesa Jääskeläinen struct active_processing *proc = session->processing; 464*45d40bdaSValerii Chubar struct rsa_aes_key_wrap_processing_ctx *rsa_aes_ctx = NULL; 465dc8c77fcSVesa Jääskeläinen struct rsa_oaep_processing_ctx *rsa_oaep_ctx = NULL; 466d9af50bcSVesa Jääskeläinen struct rsa_pss_processing_ctx *rsa_pss_ctx = NULL; 46703e07432SValerii Chubar struct eddsa_processing_ctx *eddsa_ctx = NULL; 468fb279d8bSVesa Jääskeläinen size_t sz = 0; 469fb279d8bSVesa Jääskeläinen 470fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 471fb279d8bSVesa Jääskeläinen in_buf = params[1].memref.buffer; 472fb279d8bSVesa Jääskeläinen in_size = params[1].memref.size; 473fb279d8bSVesa Jääskeläinen if (in_size && !in_buf) 474fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 475fb279d8bSVesa Jääskeläinen } 476fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 477fb279d8bSVesa Jääskeläinen in2_buf = params[2].memref.buffer; 478fb279d8bSVesa Jääskeläinen in2_size = params[2].memref.size; 479fb279d8bSVesa Jääskeläinen if (in2_size && !in2_buf) 480fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 481fb279d8bSVesa Jääskeläinen } 482fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 483fb279d8bSVesa Jääskeläinen out_buf = params[2].memref.buffer; 484fb279d8bSVesa Jääskeläinen out_size = params[2].memref.size; 485fb279d8bSVesa Jääskeläinen if (out_size && !out_buf) 486fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 487fb279d8bSVesa Jääskeläinen } 488fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 489fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 490fb279d8bSVesa Jääskeläinen 491fb279d8bSVesa Jääskeläinen switch (step) { 492fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_ONESHOT: 493fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE: 494fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_FINAL: 495fb279d8bSVesa Jääskeläinen break; 496fb279d8bSVesa Jääskeläinen default: 497fb279d8bSVesa Jääskeläinen return PKCS11_CKR_GENERAL_ERROR; 498fb279d8bSVesa Jääskeläinen } 499fb279d8bSVesa Jääskeläinen 500d9af50bcSVesa Jääskeläinen /* TEE attribute(s) required by the operation */ 501d9af50bcSVesa Jääskeläinen switch (proc->mecha_type) { 502d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 503d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 504d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 505d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 506d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 507d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 508d9af50bcSVesa Jääskeläinen tee_attrs = TEE_Malloc(sizeof(TEE_Attribute), 509d9af50bcSVesa Jääskeläinen TEE_USER_MEM_HINT_NO_FILL_ZERO); 510d9af50bcSVesa Jääskeläinen if (!tee_attrs) { 511d9af50bcSVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY; 512d9af50bcSVesa Jääskeläinen goto out; 513d9af50bcSVesa Jääskeläinen } 514d9af50bcSVesa Jääskeläinen 515d9af50bcSVesa Jääskeläinen rsa_pss_ctx = proc->extra_ctx; 516d9af50bcSVesa Jääskeläinen 517d9af50bcSVesa Jääskeläinen TEE_InitValueAttribute(&tee_attrs[tee_attrs_count], 518d9af50bcSVesa Jääskeläinen TEE_ATTR_RSA_PSS_SALT_LENGTH, 519d9af50bcSVesa Jääskeläinen rsa_pss_ctx->salt_len, 0); 520d9af50bcSVesa Jääskeläinen tee_attrs_count++; 521d9af50bcSVesa Jääskeläinen break; 52203e07432SValerii Chubar case PKCS11_CKM_EDDSA: 52303e07432SValerii Chubar eddsa_ctx = proc->extra_ctx; 52403e07432SValerii Chubar 52503e07432SValerii Chubar tee_attrs = TEE_Malloc(2 * sizeof(TEE_Attribute), 52603e07432SValerii Chubar TEE_USER_MEM_HINT_NO_FILL_ZERO); 52703e07432SValerii Chubar if (!tee_attrs) { 52803e07432SValerii Chubar rc = PKCS11_CKR_DEVICE_MEMORY; 52903e07432SValerii Chubar goto out; 53003e07432SValerii Chubar } 53103e07432SValerii Chubar 53203e07432SValerii Chubar if (eddsa_ctx->flag) { 53303e07432SValerii Chubar TEE_InitValueAttribute(&tee_attrs[tee_attrs_count], 53403e07432SValerii Chubar TEE_ATTR_EDDSA_PREHASH, 0, 0); 53503e07432SValerii Chubar tee_attrs_count++; 53603e07432SValerii Chubar } 53703e07432SValerii Chubar 53803e07432SValerii Chubar if (eddsa_ctx->ctx_len > 0) { 53903e07432SValerii Chubar TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 54003e07432SValerii Chubar TEE_ATTR_EDDSA_CTX, eddsa_ctx->ctx, 54103e07432SValerii Chubar eddsa_ctx->ctx_len); 54203e07432SValerii Chubar tee_attrs_count++; 54303e07432SValerii Chubar } 54403e07432SValerii Chubar break; 545dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 546dc8c77fcSVesa Jääskeläinen rsa_oaep_ctx = proc->extra_ctx; 547dc8c77fcSVesa Jääskeläinen 548dc8c77fcSVesa Jääskeläinen if (!rsa_oaep_ctx->source_data_len) 549dc8c77fcSVesa Jääskeläinen break; 550dc8c77fcSVesa Jääskeläinen 551dc8c77fcSVesa Jääskeläinen tee_attrs = TEE_Malloc(sizeof(TEE_Attribute), 552dc8c77fcSVesa Jääskeläinen TEE_USER_MEM_HINT_NO_FILL_ZERO); 553dc8c77fcSVesa Jääskeläinen if (!tee_attrs) { 554dc8c77fcSVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY; 555dc8c77fcSVesa Jääskeläinen goto out; 556dc8c77fcSVesa Jääskeläinen } 557dc8c77fcSVesa Jääskeläinen 558dc8c77fcSVesa Jääskeläinen TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 559dc8c77fcSVesa Jääskeläinen TEE_ATTR_RSA_OAEP_LABEL, 560dc8c77fcSVesa Jääskeläinen rsa_oaep_ctx->source_data, 561dc8c77fcSVesa Jääskeläinen rsa_oaep_ctx->source_data_len); 562dc8c77fcSVesa Jääskeläinen tee_attrs_count++; 563dc8c77fcSVesa Jääskeläinen break; 564*45d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 565*45d40bdaSValerii Chubar rsa_aes_ctx = proc->extra_ctx; 566*45d40bdaSValerii Chubar 567*45d40bdaSValerii Chubar if (!rsa_aes_ctx->source_data_len) 568*45d40bdaSValerii Chubar break; 569*45d40bdaSValerii Chubar 570*45d40bdaSValerii Chubar tee_attrs = TEE_Malloc(sizeof(TEE_Attribute), 571*45d40bdaSValerii Chubar TEE_USER_MEM_HINT_NO_FILL_ZERO); 572*45d40bdaSValerii Chubar if (!tee_attrs) { 573*45d40bdaSValerii Chubar rc = PKCS11_CKR_DEVICE_MEMORY; 574*45d40bdaSValerii Chubar goto out; 575*45d40bdaSValerii Chubar } 576*45d40bdaSValerii Chubar 577*45d40bdaSValerii Chubar TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 578*45d40bdaSValerii Chubar TEE_ATTR_RSA_OAEP_LABEL, 579*45d40bdaSValerii Chubar rsa_aes_ctx->source_data, 580*45d40bdaSValerii Chubar rsa_aes_ctx->source_data_len); 581*45d40bdaSValerii Chubar tee_attrs_count++; 582*45d40bdaSValerii Chubar break; 583d9af50bcSVesa Jääskeläinen default: 584d9af50bcSVesa Jääskeläinen break; 585d9af50bcSVesa Jääskeläinen } 586d9af50bcSVesa Jääskeläinen 587fb279d8bSVesa Jääskeläinen /* 588fb279d8bSVesa Jääskeläinen * Handle multi stage update step for mechas needing hash 589fb279d8bSVesa Jääskeläinen * calculation 590fb279d8bSVesa Jääskeläinen */ 591fb279d8bSVesa Jääskeläinen if (step == PKCS11_FUNC_STEP_UPDATE) { 592fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 593fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 594fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 595fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 596fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 597fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 5980442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 5990442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 6000442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 6010442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 6020442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 6030442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 604d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 605d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 606d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 607d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 608d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 609fb279d8bSVesa Jääskeläinen assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL); 610fb279d8bSVesa Jääskeläinen 611fb279d8bSVesa Jääskeläinen TEE_DigestUpdate(proc->tee_hash_op_handle, in_buf, 612fb279d8bSVesa Jääskeläinen in_size); 6139df68186SEtienne Carriere rc = PKCS11_CKR_OK; 614fb279d8bSVesa Jääskeläinen break; 615fb279d8bSVesa Jääskeläinen default: 616fb279d8bSVesa Jääskeläinen /* 617fb279d8bSVesa Jääskeläinen * Other mechanism do not expect multi stage 618fb279d8bSVesa Jääskeläinen * operation 619fb279d8bSVesa Jääskeläinen */ 620fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_GENERAL_ERROR; 621fb279d8bSVesa Jääskeläinen break; 622fb279d8bSVesa Jääskeläinen } 623fb279d8bSVesa Jääskeläinen 624fb279d8bSVesa Jääskeläinen goto out; 625fb279d8bSVesa Jääskeläinen } 626fb279d8bSVesa Jääskeläinen 627fb279d8bSVesa Jääskeläinen /* 628fb279d8bSVesa Jääskeläinen * Handle multi stage one shot and final steps for mechas needing hash 629fb279d8bSVesa Jääskeläinen * calculation 630fb279d8bSVesa Jääskeläinen */ 631fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 632fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 633fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 634fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 635fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 636fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 6370442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 6380442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 6390442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 6400442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 6410442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 6420442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 643d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 644d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 645d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 646d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 647d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 648fb279d8bSVesa Jääskeläinen assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL); 649fb279d8bSVesa Jääskeläinen 650fb279d8bSVesa Jääskeläinen hash_size = TEE_ALG_GET_DIGEST_SIZE(proc->tee_hash_algo); 651fb279d8bSVesa Jääskeläinen hash_buf = TEE_Malloc(hash_size, 0); 652fb279d8bSVesa Jääskeläinen if (!hash_buf) 653fb279d8bSVesa Jääskeläinen return PKCS11_CKR_DEVICE_MEMORY; 654fb279d8bSVesa Jääskeläinen 655fb279d8bSVesa Jääskeläinen res = TEE_DigestDoFinal(proc->tee_hash_op_handle, 656fb279d8bSVesa Jääskeläinen in_buf, in_size, hash_buf, 657fb279d8bSVesa Jääskeläinen &hash_size); 658fb279d8bSVesa Jääskeläinen 659fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 660fb279d8bSVesa Jääskeläinen if (rc != PKCS11_CKR_OK) 661fb279d8bSVesa Jääskeläinen goto out; 662fb279d8bSVesa Jääskeläinen 663fb279d8bSVesa Jääskeläinen break; 664fb279d8bSVesa Jääskeläinen default: 665fb279d8bSVesa Jääskeläinen break; 666fb279d8bSVesa Jääskeläinen } 667fb279d8bSVesa Jääskeläinen 668fb279d8bSVesa Jääskeläinen /* 669fb279d8bSVesa Jääskeläinen * Finalize either provided hash or calculated hash with signing 670fb279d8bSVesa Jääskeläinen * operation 671fb279d8bSVesa Jääskeläinen */ 672fb279d8bSVesa Jääskeläinen 673fb279d8bSVesa Jääskeläinen /* First determine amount of bytes for signing operation */ 674fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 675fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 676fb279d8bSVesa Jääskeläinen sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle); 677fb279d8bSVesa Jääskeläinen if (!in_size || !sz) { 678fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 679fb279d8bSVesa Jääskeläinen goto out; 680fb279d8bSVesa Jääskeläinen } 681fb279d8bSVesa Jääskeläinen 682fb279d8bSVesa Jääskeläinen /* 683fb279d8bSVesa Jääskeläinen * Note 3) Input the entire raw digest. Internally, this will 684fb279d8bSVesa Jääskeläinen * be truncated to the appropriate number of bits. 685fb279d8bSVesa Jääskeläinen */ 686fb279d8bSVesa Jääskeläinen if (in_size > sz) 687fb279d8bSVesa Jääskeläinen in_size = sz; 688fb279d8bSVesa Jääskeläinen 689fb279d8bSVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && in2_size != 2 * sz) { 690fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 691fb279d8bSVesa Jääskeläinen goto out; 692fb279d8bSVesa Jääskeläinen } 693fb279d8bSVesa Jääskeläinen break; 694fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 695fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 696fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 697fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 698fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 699fb279d8bSVesa Jääskeläinen /* Get key size in bytes */ 700fb279d8bSVesa Jääskeläinen sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle); 701fb279d8bSVesa Jääskeläinen if (!sz) { 702fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 703fb279d8bSVesa Jääskeläinen goto out; 704fb279d8bSVesa Jääskeläinen } 705fb279d8bSVesa Jääskeläinen 706fb279d8bSVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && 707fb279d8bSVesa Jääskeläinen in2_size != 2 * sz) { 708fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 709fb279d8bSVesa Jääskeläinen goto out; 710fb279d8bSVesa Jääskeläinen } 711fb279d8bSVesa Jääskeläinen break; 7120442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 7130442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 7140442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 7150442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 7160442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 7170442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 7180442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 719d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 720d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 721d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 722d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 723d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 724d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 7250442c956SVesa Jääskeläinen /* Get key size in bytes */ 7260442c956SVesa Jääskeläinen sz = rsa_get_input_max_byte_size(proc->tee_op_handle); 7270442c956SVesa Jääskeläinen if (!sz) { 7280442c956SVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 7290442c956SVesa Jääskeläinen goto out; 7300442c956SVesa Jääskeläinen } 7310442c956SVesa Jääskeläinen 7320442c956SVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && in2_size != sz) { 7330442c956SVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 7340442c956SVesa Jääskeläinen goto out; 7350442c956SVesa Jääskeläinen } 7360442c956SVesa Jääskeläinen break; 737fb279d8bSVesa Jääskeläinen default: 738fb279d8bSVesa Jääskeläinen break; 739fb279d8bSVesa Jääskeläinen } 740fb279d8bSVesa Jääskeläinen 741fb279d8bSVesa Jääskeläinen /* Next perform actual signing operation */ 742fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 743fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 74403e07432SValerii Chubar case PKCS11_CKM_EDDSA: 7450442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 746dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 747d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 748fb279d8bSVesa Jääskeläinen /* For operations using provided input data */ 749fb279d8bSVesa Jääskeläinen switch (function) { 750fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_ENCRYPT: 751fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricEncrypt(proc->tee_op_handle, 752fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count, 753fb279d8bSVesa Jääskeläinen in_buf, in_size, 754fb279d8bSVesa Jääskeläinen out_buf, &out_size); 755fb279d8bSVesa Jääskeläinen output_data = true; 756fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 7576a6299fbSVesa Jääskeläinen if (rc == PKCS11_CKR_ARGUMENTS_BAD) 7586a6299fbSVesa Jääskeläinen rc = PKCS11_CKR_DATA_LEN_RANGE; 759fb279d8bSVesa Jääskeläinen break; 760fb279d8bSVesa Jääskeläinen 761fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_DECRYPT: 762fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricDecrypt(proc->tee_op_handle, 763fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count, 764fb279d8bSVesa Jääskeläinen in_buf, in_size, 765fb279d8bSVesa Jääskeläinen out_buf, &out_size); 766fb279d8bSVesa Jääskeläinen output_data = true; 767fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 768f27310a5SVesa Jääskeläinen if (rc == PKCS11_CKR_ARGUMENTS_BAD) 769f27310a5SVesa Jääskeläinen rc = PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 770fb279d8bSVesa Jääskeläinen break; 771fb279d8bSVesa Jääskeläinen 772fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_SIGN: 773fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricSignDigest(proc->tee_op_handle, 774fb279d8bSVesa Jääskeläinen tee_attrs, 775fb279d8bSVesa Jääskeläinen tee_attrs_count, 776fb279d8bSVesa Jääskeläinen in_buf, in_size, 777fb279d8bSVesa Jääskeläinen out_buf, &out_size); 778fb279d8bSVesa Jääskeläinen output_data = true; 779fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 780fb279d8bSVesa Jääskeläinen break; 781fb279d8bSVesa Jääskeläinen 782fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_VERIFY: 783fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle, 784fb279d8bSVesa Jääskeläinen tee_attrs, 785fb279d8bSVesa Jääskeläinen tee_attrs_count, 786fb279d8bSVesa Jääskeläinen in_buf, in_size, 787fb279d8bSVesa Jääskeläinen in2_buf, in2_size); 788fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 789fb279d8bSVesa Jääskeläinen break; 790fb279d8bSVesa Jääskeläinen 791fb279d8bSVesa Jääskeläinen default: 792fb279d8bSVesa Jääskeläinen TEE_Panic(function); 793fb279d8bSVesa Jääskeläinen break; 794fb279d8bSVesa Jääskeläinen } 795fb279d8bSVesa Jääskeläinen break; 796fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 797fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 798fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 799fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 800fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 8010442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 8020442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 8030442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 8040442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 8050442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 8060442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 807d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 808d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 809d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 810d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 811d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 812fb279d8bSVesa Jääskeläinen /* For operations having hash operation use calculated hash */ 813fb279d8bSVesa Jääskeläinen switch (function) { 814fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_SIGN: 815fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricSignDigest(proc->tee_op_handle, 816fb279d8bSVesa Jääskeläinen tee_attrs, 817fb279d8bSVesa Jääskeläinen tee_attrs_count, 818fb279d8bSVesa Jääskeläinen hash_buf, hash_size, 819fb279d8bSVesa Jääskeläinen out_buf, &out_size); 820fb279d8bSVesa Jääskeläinen output_data = true; 821fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 822fb279d8bSVesa Jääskeläinen break; 823fb279d8bSVesa Jääskeläinen 824fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_VERIFY: 825fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle, 826fb279d8bSVesa Jääskeläinen tee_attrs, 827fb279d8bSVesa Jääskeläinen tee_attrs_count, 828fb279d8bSVesa Jääskeläinen hash_buf, hash_size, 829fb279d8bSVesa Jääskeläinen in2_buf, in2_size); 830fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 831fb279d8bSVesa Jääskeläinen break; 832fb279d8bSVesa Jääskeläinen 833fb279d8bSVesa Jääskeläinen default: 834fb279d8bSVesa Jääskeläinen TEE_Panic(function); 835fb279d8bSVesa Jääskeläinen break; 836fb279d8bSVesa Jääskeläinen } 837fb279d8bSVesa Jääskeläinen break; 838fb279d8bSVesa Jääskeläinen default: 839fb279d8bSVesa Jääskeläinen TEE_Panic(proc->mecha_type); 840fb279d8bSVesa Jääskeläinen break; 841fb279d8bSVesa Jääskeläinen } 842fb279d8bSVesa Jääskeläinen 843fb279d8bSVesa Jääskeläinen out: 844fb279d8bSVesa Jääskeläinen if (output_data && 845fb279d8bSVesa Jääskeläinen (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 846fb279d8bSVesa Jääskeläinen switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 847fb279d8bSVesa Jääskeläinen case TEE_PARAM_TYPE_MEMREF_OUTPUT: 848fb279d8bSVesa Jääskeläinen case TEE_PARAM_TYPE_MEMREF_INOUT: 849fb279d8bSVesa Jääskeläinen params[2].memref.size = out_size; 850fb279d8bSVesa Jääskeläinen break; 851fb279d8bSVesa Jääskeläinen default: 852fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_GENERAL_ERROR; 853fb279d8bSVesa Jääskeläinen break; 854fb279d8bSVesa Jääskeläinen } 855fb279d8bSVesa Jääskeläinen } 856fb279d8bSVesa Jääskeläinen 857fb279d8bSVesa Jääskeläinen TEE_Free(hash_buf); 858fb279d8bSVesa Jääskeläinen TEE_Free(tee_attrs); 859fb279d8bSVesa Jääskeläinen 860fb279d8bSVesa Jääskeläinen return rc; 861fb279d8bSVesa Jääskeläinen } 862cc062b46SJorge Ramirez-Ortiz 863cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc do_asymm_derivation(struct pkcs11_session *session, 864cc062b46SJorge Ramirez-Ortiz struct pkcs11_attribute_head *proc_params, 865cc062b46SJorge Ramirez-Ortiz struct obj_attrs **head) 866cc062b46SJorge Ramirez-Ortiz { 867cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 868cc062b46SJorge Ramirez-Ortiz TEE_ObjectHandle out_handle = TEE_HANDLE_NULL; 869cc062b46SJorge Ramirez-Ortiz TEE_Result res = TEE_ERROR_GENERIC; 870cc062b46SJorge Ramirez-Ortiz TEE_Attribute tee_attrs[2] = { }; 871cc062b46SJorge Ramirez-Ortiz size_t tee_attrs_count = 0; 872cc062b46SJorge Ramirez-Ortiz uint32_t key_byte_size = 0; 873cc062b46SJorge Ramirez-Ortiz uint32_t key_bit_size = 0; 874cc062b46SJorge Ramirez-Ortiz void *a_ptr = NULL; 875cc062b46SJorge Ramirez-Ortiz size_t a_size = 0; 876cc062b46SJorge Ramirez-Ortiz 877cc062b46SJorge Ramirez-Ortiz /* Remove default attribute set at template sanitization */ 878cc062b46SJorge Ramirez-Ortiz if (remove_empty_attribute(head, PKCS11_CKA_VALUE)) 879cc062b46SJorge Ramirez-Ortiz return PKCS11_CKR_FUNCTION_FAILED; 880cc062b46SJorge Ramirez-Ortiz 881cc062b46SJorge Ramirez-Ortiz rc = get_u32_attribute(*head, PKCS11_CKA_VALUE_LEN, &key_bit_size); 882cc062b46SJorge Ramirez-Ortiz if (rc) 883cc062b46SJorge Ramirez-Ortiz return rc; 884cc062b46SJorge Ramirez-Ortiz 885cc062b46SJorge Ramirez-Ortiz key_bit_size *= 8; 886cc062b46SJorge Ramirez-Ortiz key_byte_size = (key_bit_size + 7) / 8; 887cc062b46SJorge Ramirez-Ortiz 888cc062b46SJorge Ramirez-Ortiz res = TEE_AllocateTransientObject(TEE_TYPE_GENERIC_SECRET, 889cc062b46SJorge Ramirez-Ortiz key_byte_size * 8, &out_handle); 890cc062b46SJorge Ramirez-Ortiz if (res) { 891cc062b46SJorge Ramirez-Ortiz DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 892cc062b46SJorge Ramirez-Ortiz return tee2pkcs_error(res); 893cc062b46SJorge Ramirez-Ortiz } 894cc062b46SJorge Ramirez-Ortiz 895cc062b46SJorge Ramirez-Ortiz switch (proc_params->id) { 896cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 897cc062b46SJorge Ramirez-Ortiz rc = pkcs2tee_param_ecdh(proc_params, &a_ptr, &a_size); 898cc062b46SJorge Ramirez-Ortiz if (rc) 899cc062b46SJorge Ramirez-Ortiz goto out; 900cc062b46SJorge Ramirez-Ortiz 901cc062b46SJorge Ramirez-Ortiz TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 902cc062b46SJorge Ramirez-Ortiz TEE_ATTR_ECC_PUBLIC_VALUE_X, 903cc062b46SJorge Ramirez-Ortiz a_ptr, a_size / 2); 904cc062b46SJorge Ramirez-Ortiz tee_attrs_count++; 905cc062b46SJorge Ramirez-Ortiz TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 906cc062b46SJorge Ramirez-Ortiz TEE_ATTR_ECC_PUBLIC_VALUE_Y, 907cc062b46SJorge Ramirez-Ortiz (char *)a_ptr + a_size / 2, 908cc062b46SJorge Ramirez-Ortiz a_size / 2); 909cc062b46SJorge Ramirez-Ortiz tee_attrs_count++; 910cc062b46SJorge Ramirez-Ortiz break; 911cc062b46SJorge Ramirez-Ortiz default: 912cc062b46SJorge Ramirez-Ortiz TEE_Panic(proc_params->id); 913cc062b46SJorge Ramirez-Ortiz break; 914cc062b46SJorge Ramirez-Ortiz } 915cc062b46SJorge Ramirez-Ortiz 916cc062b46SJorge Ramirez-Ortiz TEE_DeriveKey(session->processing->tee_op_handle, &tee_attrs[0], 917cc062b46SJorge Ramirez-Ortiz tee_attrs_count, out_handle); 918cc062b46SJorge Ramirez-Ortiz 919cc062b46SJorge Ramirez-Ortiz rc = alloc_get_tee_attribute_data(out_handle, TEE_ATTR_SECRET_VALUE, 920cc062b46SJorge Ramirez-Ortiz &a_ptr, &a_size); 921cc062b46SJorge Ramirez-Ortiz if (rc) 922cc062b46SJorge Ramirez-Ortiz goto out; 923cc062b46SJorge Ramirez-Ortiz 924cc062b46SJorge Ramirez-Ortiz if (a_size * 8 < key_bit_size) 925cc062b46SJorge Ramirez-Ortiz rc = PKCS11_CKR_KEY_SIZE_RANGE; 926cc062b46SJorge Ramirez-Ortiz else 927cc062b46SJorge Ramirez-Ortiz rc = add_attribute(head, PKCS11_CKA_VALUE, a_ptr, 928cc062b46SJorge Ramirez-Ortiz key_byte_size); 929cc062b46SJorge Ramirez-Ortiz TEE_Free(a_ptr); 930cc062b46SJorge Ramirez-Ortiz out: 931cc062b46SJorge Ramirez-Ortiz release_active_processing(session); 932cc062b46SJorge Ramirez-Ortiz TEE_FreeTransientObject(out_handle); 933cc062b46SJorge Ramirez-Ortiz 934cc062b46SJorge Ramirez-Ortiz return rc; 935cc062b46SJorge Ramirez-Ortiz } 936*45d40bdaSValerii Chubar 937*45d40bdaSValerii Chubar static enum pkcs11_rc wrap_rsa_aes_key(struct active_processing *proc, 938*45d40bdaSValerii Chubar void *data, uint32_t data_sz, 939*45d40bdaSValerii Chubar void *out_buf, uint32_t *out_sz) 940*45d40bdaSValerii Chubar { 941*45d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_OK; 942*45d40bdaSValerii Chubar TEE_Result res = TEE_ERROR_GENERIC; 943*45d40bdaSValerii Chubar int mbedtls_rc = 0; 944*45d40bdaSValerii Chubar struct rsa_aes_key_wrap_processing_ctx *ctx = proc->extra_ctx; 945*45d40bdaSValerii Chubar mbedtls_nist_kw_context kw_ctx = { }; 946*45d40bdaSValerii Chubar uint8_t aes_key_value[32] = { }; 947*45d40bdaSValerii Chubar uint32_t aes_key_size = ctx->aes_key_bits / 8; 948*45d40bdaSValerii Chubar uint32_t aes_wrapped_size = *out_sz; 949*45d40bdaSValerii Chubar uint32_t expected_size = 0; 950*45d40bdaSValerii Chubar size_t target_key_size = 0; 951*45d40bdaSValerii Chubar const size_t kw_semiblock_len = 8; 952*45d40bdaSValerii Chubar 953*45d40bdaSValerii Chubar if (ctx->aes_key_bits != 128 && 954*45d40bdaSValerii Chubar ctx->aes_key_bits != 192 && 955*45d40bdaSValerii Chubar ctx->aes_key_bits != 256) 956*45d40bdaSValerii Chubar return PKCS11_CKR_ARGUMENTS_BAD; 957*45d40bdaSValerii Chubar 958*45d40bdaSValerii Chubar mbedtls_nist_kw_init(&kw_ctx); 959*45d40bdaSValerii Chubar TEE_GenerateRandom(aes_key_value, aes_key_size); 960*45d40bdaSValerii Chubar res = TEE_AsymmetricEncrypt(proc->tee_op_handle, 961*45d40bdaSValerii Chubar NULL, 0, 962*45d40bdaSValerii Chubar aes_key_value, aes_key_size, 963*45d40bdaSValerii Chubar out_buf, &aes_wrapped_size); 964*45d40bdaSValerii Chubar expected_size = aes_wrapped_size + data_sz + kw_semiblock_len; 965*45d40bdaSValerii Chubar if (res) { 966*45d40bdaSValerii Chubar if (res == TEE_ERROR_SHORT_BUFFER) 967*45d40bdaSValerii Chubar *out_sz = expected_size; 968*45d40bdaSValerii Chubar 969*45d40bdaSValerii Chubar rc = tee2pkcs_error(res); 970*45d40bdaSValerii Chubar goto out; 971*45d40bdaSValerii Chubar } 972*45d40bdaSValerii Chubar 973*45d40bdaSValerii Chubar if (*out_sz < expected_size) { 974*45d40bdaSValerii Chubar rc = PKCS11_CKR_BUFFER_TOO_SMALL; 975*45d40bdaSValerii Chubar *out_sz = expected_size; 976*45d40bdaSValerii Chubar goto out; 977*45d40bdaSValerii Chubar } 978*45d40bdaSValerii Chubar 979*45d40bdaSValerii Chubar mbedtls_rc = mbedtls_nist_kw_setkey(&kw_ctx, MBEDTLS_CIPHER_ID_AES, 980*45d40bdaSValerii Chubar aes_key_value, ctx->aes_key_bits, 981*45d40bdaSValerii Chubar true); 982*45d40bdaSValerii Chubar if (mbedtls_rc) { 983*45d40bdaSValerii Chubar if (mbedtls_rc == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) 984*45d40bdaSValerii Chubar rc = PKCS11_CKR_KEY_SIZE_RANGE; 985*45d40bdaSValerii Chubar else 986*45d40bdaSValerii Chubar rc = PKCS11_CKR_FUNCTION_FAILED; 987*45d40bdaSValerii Chubar 988*45d40bdaSValerii Chubar goto out; 989*45d40bdaSValerii Chubar } 990*45d40bdaSValerii Chubar 991*45d40bdaSValerii Chubar mbedtls_rc = mbedtls_nist_kw_wrap(&kw_ctx, MBEDTLS_KW_MODE_KWP, 992*45d40bdaSValerii Chubar data, data_sz, 993*45d40bdaSValerii Chubar (uint8_t *)out_buf + aes_wrapped_size, 994*45d40bdaSValerii Chubar &target_key_size, 995*45d40bdaSValerii Chubar *out_sz - aes_wrapped_size); 996*45d40bdaSValerii Chubar if (mbedtls_rc) { 997*45d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 998*45d40bdaSValerii Chubar goto out; 999*45d40bdaSValerii Chubar } 1000*45d40bdaSValerii Chubar 1001*45d40bdaSValerii Chubar assert(*out_sz >= target_key_size + aes_wrapped_size); 1002*45d40bdaSValerii Chubar *out_sz = target_key_size + aes_wrapped_size; 1003*45d40bdaSValerii Chubar 1004*45d40bdaSValerii Chubar out: 1005*45d40bdaSValerii Chubar mbedtls_nist_kw_free(&kw_ctx); 1006*45d40bdaSValerii Chubar TEE_MemFill(aes_key_value, 0, aes_key_size); 1007*45d40bdaSValerii Chubar return rc; 1008*45d40bdaSValerii Chubar } 1009*45d40bdaSValerii Chubar 1010*45d40bdaSValerii Chubar static enum pkcs11_rc unwrap_rsa_aes_key(struct active_processing *proc, 1011*45d40bdaSValerii Chubar void *data, uint32_t data_sz, 1012*45d40bdaSValerii Chubar void **out_buf, uint32_t *out_sz) 1013*45d40bdaSValerii Chubar { 1014*45d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_OK; 1015*45d40bdaSValerii Chubar int mbedtls_rc = 0; 1016*45d40bdaSValerii Chubar TEE_Result res = TEE_ERROR_GENERIC; 1017*45d40bdaSValerii Chubar TEE_OperationInfo info = { }; 1018*45d40bdaSValerii Chubar struct rsa_aes_key_wrap_processing_ctx *ctx = proc->extra_ctx; 1019*45d40bdaSValerii Chubar mbedtls_nist_kw_context kw_ctx = { }; 1020*45d40bdaSValerii Chubar uint8_t aes_key_value[32] = { }; 1021*45d40bdaSValerii Chubar uint32_t aes_key_size = ctx->aes_key_bits / 8; 1022*45d40bdaSValerii Chubar uint32_t wrapped_key_size = 0; 1023*45d40bdaSValerii Chubar uint32_t rsa_key_size = 0; 1024*45d40bdaSValerii Chubar size_t target_key_size = 0; 1025*45d40bdaSValerii Chubar 1026*45d40bdaSValerii Chubar if (ctx->aes_key_bits != 128 && 1027*45d40bdaSValerii Chubar ctx->aes_key_bits != 192 && 1028*45d40bdaSValerii Chubar ctx->aes_key_bits != 256) 1029*45d40bdaSValerii Chubar return PKCS11_CKR_ARGUMENTS_BAD; 1030*45d40bdaSValerii Chubar 1031*45d40bdaSValerii Chubar TEE_GetOperationInfo(proc->tee_op_handle, &info); 1032*45d40bdaSValerii Chubar rsa_key_size = info.keySize / 8; 1033*45d40bdaSValerii Chubar wrapped_key_size = data_sz - rsa_key_size; 1034*45d40bdaSValerii Chubar target_key_size = wrapped_key_size - 8; 1035*45d40bdaSValerii Chubar 1036*45d40bdaSValerii Chubar *out_buf = TEE_Malloc(target_key_size, TEE_MALLOC_FILL_ZERO); 1037*45d40bdaSValerii Chubar if (!*out_buf) 1038*45d40bdaSValerii Chubar return PKCS11_CKR_DEVICE_MEMORY; 1039*45d40bdaSValerii Chubar 1040*45d40bdaSValerii Chubar mbedtls_nist_kw_init(&kw_ctx); 1041*45d40bdaSValerii Chubar res = TEE_AsymmetricDecrypt(proc->tee_op_handle, 1042*45d40bdaSValerii Chubar NULL, 0, 1043*45d40bdaSValerii Chubar data, rsa_key_size, 1044*45d40bdaSValerii Chubar aes_key_value, &aes_key_size); 1045*45d40bdaSValerii Chubar if (res) { 1046*45d40bdaSValerii Chubar rc = tee2pkcs_error(res); 1047*45d40bdaSValerii Chubar goto out; 1048*45d40bdaSValerii Chubar } 1049*45d40bdaSValerii Chubar 1050*45d40bdaSValerii Chubar mbedtls_rc = mbedtls_nist_kw_setkey(&kw_ctx, MBEDTLS_CIPHER_ID_AES, 1051*45d40bdaSValerii Chubar aes_key_value, ctx->aes_key_bits, 1052*45d40bdaSValerii Chubar false); 1053*45d40bdaSValerii Chubar if (mbedtls_rc) { 1054*45d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 1055*45d40bdaSValerii Chubar goto out; 1056*45d40bdaSValerii Chubar } 1057*45d40bdaSValerii Chubar 1058*45d40bdaSValerii Chubar mbedtls_rc = mbedtls_nist_kw_unwrap(&kw_ctx, MBEDTLS_KW_MODE_KWP, 1059*45d40bdaSValerii Chubar (uint8_t *)data + rsa_key_size, 1060*45d40bdaSValerii Chubar wrapped_key_size, *out_buf, 1061*45d40bdaSValerii Chubar &target_key_size, target_key_size); 1062*45d40bdaSValerii Chubar if (mbedtls_rc) { 1063*45d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 1064*45d40bdaSValerii Chubar goto out; 1065*45d40bdaSValerii Chubar } 1066*45d40bdaSValerii Chubar 1067*45d40bdaSValerii Chubar *out_sz = target_key_size; 1068*45d40bdaSValerii Chubar out: 1069*45d40bdaSValerii Chubar TEE_MemFill(aes_key_value, 0, aes_key_size); 1070*45d40bdaSValerii Chubar mbedtls_nist_kw_free(&kw_ctx); 1071*45d40bdaSValerii Chubar return rc; 1072*45d40bdaSValerii Chubar } 1073*45d40bdaSValerii Chubar 1074*45d40bdaSValerii Chubar enum pkcs11_rc wrap_data_by_asymm_enc(struct pkcs11_session *session, 1075*45d40bdaSValerii Chubar void *data, uint32_t data_sz, 1076*45d40bdaSValerii Chubar void *out_buf, uint32_t *out_sz) 1077*45d40bdaSValerii Chubar { 1078*45d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1079*45d40bdaSValerii Chubar struct active_processing *proc = session->processing; 1080*45d40bdaSValerii Chubar 1081*45d40bdaSValerii Chubar switch (proc->mecha_type) { 1082*45d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 1083*45d40bdaSValerii Chubar rc = wrap_rsa_aes_key(proc, data, data_sz, out_buf, out_sz); 1084*45d40bdaSValerii Chubar break; 1085*45d40bdaSValerii Chubar default: 1086*45d40bdaSValerii Chubar return PKCS11_CKR_MECHANISM_INVALID; 1087*45d40bdaSValerii Chubar } 1088*45d40bdaSValerii Chubar 1089*45d40bdaSValerii Chubar return rc; 1090*45d40bdaSValerii Chubar } 1091*45d40bdaSValerii Chubar 1092*45d40bdaSValerii Chubar enum pkcs11_rc unwrap_key_by_asymm(struct pkcs11_session *session, 1093*45d40bdaSValerii Chubar void *data, uint32_t data_sz, 1094*45d40bdaSValerii Chubar void **out_buf, uint32_t *out_sz) 1095*45d40bdaSValerii Chubar { 1096*45d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1097*45d40bdaSValerii Chubar struct active_processing *proc = session->processing; 1098*45d40bdaSValerii Chubar 1099*45d40bdaSValerii Chubar switch (proc->mecha_type) { 1100*45d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 1101*45d40bdaSValerii Chubar rc = unwrap_rsa_aes_key(proc, data, data_sz, out_buf, out_sz); 1102*45d40bdaSValerii Chubar break; 1103*45d40bdaSValerii Chubar default: 1104*45d40bdaSValerii Chubar return PKCS11_CKR_MECHANISM_INVALID; 1105*45d40bdaSValerii Chubar } 1106*45d40bdaSValerii Chubar 1107*45d40bdaSValerii Chubar return rc; 1108*45d40bdaSValerii Chubar } 1109