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 */ 37fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 38*cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 39fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 40fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 41fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 42fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 43fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 44fb279d8bSVesa Jääskeläinen return true; 45fb279d8bSVesa Jääskeläinen default: 46fb279d8bSVesa Jääskeläinen return false; 47fb279d8bSVesa Jääskeläinen } 48fb279d8bSVesa Jääskeläinen } 49fb279d8bSVesa Jääskeläinen 50fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 51fb279d8bSVesa Jääskeläinen pkcs2tee_algorithm(uint32_t *tee_id, uint32_t *tee_hash_id, 52fb279d8bSVesa Jääskeläinen enum processing_func function __unused, 53fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 54fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 55fb279d8bSVesa Jääskeläinen { 56fb279d8bSVesa Jääskeläinen static const struct { 57fb279d8bSVesa Jääskeläinen enum pkcs11_mechanism_id mech_id; 58fb279d8bSVesa Jääskeläinen uint32_t tee_id; 59fb279d8bSVesa Jääskeläinen uint32_t tee_hash_id; 60fb279d8bSVesa Jääskeläinen } pkcs2tee_algo[] = { 610442c956SVesa Jääskeläinen /* RSA flavors */ 620442c956SVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS, TEE_ALG_RSAES_PKCS1_V1_5, 0 }, 63dc8c77fcSVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS_OAEP, 1, 0 }, 64d9af50bcSVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS_PSS, 1, 0 }, 650442c956SVesa Jääskeläinen { PKCS11_CKM_MD5_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_MD5, 660442c956SVesa Jääskeläinen TEE_ALG_MD5 }, 670442c956SVesa Jääskeläinen { PKCS11_CKM_SHA1_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA1, 680442c956SVesa Jääskeläinen TEE_ALG_SHA1 }, 690442c956SVesa Jääskeläinen { PKCS11_CKM_SHA224_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA224, 700442c956SVesa Jääskeläinen TEE_ALG_SHA224 }, 710442c956SVesa Jääskeläinen { PKCS11_CKM_SHA256_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA256, 720442c956SVesa Jääskeläinen TEE_ALG_SHA256 }, 730442c956SVesa Jääskeläinen { PKCS11_CKM_SHA384_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA384, 740442c956SVesa Jääskeläinen TEE_ALG_SHA384 }, 750442c956SVesa Jääskeläinen { PKCS11_CKM_SHA512_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA512, 760442c956SVesa Jääskeläinen TEE_ALG_SHA512 }, 77d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA1_RSA_PKCS_PSS, 78d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1, TEE_ALG_SHA1 }, 79d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA224_RSA_PKCS_PSS, 80d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224, TEE_ALG_SHA224 }, 81d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA256_RSA_PKCS_PSS, 82d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256, TEE_ALG_SHA256 }, 83d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA384_RSA_PKCS_PSS, 84d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384, TEE_ALG_SHA384 }, 85d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA512_RSA_PKCS_PSS, 86d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512, TEE_ALG_SHA512 }, 87fb279d8bSVesa Jääskeläinen /* EC flavors (Must find key size from the object) */ 88fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA, 1, 0 }, 89fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA1, 1, TEE_ALG_SHA1 }, 90fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA224, 1, TEE_ALG_SHA224 }, 91fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA256, 1, TEE_ALG_SHA256 }, 92fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA384, 1, TEE_ALG_SHA384 }, 93fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA512, 1, TEE_ALG_SHA512 }, 94*cc062b46SJorge Ramirez-Ortiz { PKCS11_CKM_ECDH1_DERIVE, 1, 0 }, 95fb279d8bSVesa Jääskeläinen }; 96fb279d8bSVesa Jääskeläinen size_t n = 0; 97fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 98fb279d8bSVesa Jääskeläinen 99fb279d8bSVesa Jääskeläinen for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) { 100fb279d8bSVesa Jääskeläinen if (pkcs2tee_algo[n].mech_id == proc_params->id) { 101fb279d8bSVesa Jääskeläinen *tee_id = pkcs2tee_algo[n].tee_id; 102fb279d8bSVesa Jääskeläinen *tee_hash_id = pkcs2tee_algo[n].tee_hash_id; 103fb279d8bSVesa Jääskeläinen break; 104fb279d8bSVesa Jääskeläinen } 105fb279d8bSVesa Jääskeläinen } 106fb279d8bSVesa Jääskeläinen 107fb279d8bSVesa Jääskeläinen if (n == ARRAY_SIZE(pkcs2tee_algo)) 108fb279d8bSVesa Jääskeläinen return PKCS11_RV_NOT_IMPLEMENTED; 109fb279d8bSVesa Jääskeläinen 110fb279d8bSVesa Jääskeläinen switch (proc_params->id) { 111d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 112d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 113d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 114d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 115d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 116d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 117d9af50bcSVesa Jääskeläinen rc = pkcs2tee_algo_rsa_pss(tee_id, proc_params); 118d9af50bcSVesa Jääskeläinen break; 119dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 120dc8c77fcSVesa Jääskeläinen rc = pkcs2tee_algo_rsa_oaep(tee_id, tee_hash_id, proc_params); 121dc8c77fcSVesa Jääskeläinen break; 122fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 123fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 124fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 125fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 126fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 127fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 128fb279d8bSVesa Jääskeläinen rc = pkcs2tee_algo_ecdsa(tee_id, proc_params, obj); 129fb279d8bSVesa Jääskeläinen break; 130*cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 131*cc062b46SJorge Ramirez-Ortiz rc = pkcs2tee_algo_ecdh(tee_id, proc_params, obj); 132*cc062b46SJorge Ramirez-Ortiz break; 133fb279d8bSVesa Jääskeläinen default: 134fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_OK; 135fb279d8bSVesa Jääskeläinen break; 136fb279d8bSVesa Jääskeläinen } 137fb279d8bSVesa Jääskeläinen 1380442c956SVesa Jääskeläinen /* 1390442c956SVesa Jääskeläinen * PKCS#11 uses single mechanism CKM_RSA_PKCS for both ciphering and 1400442c956SVesa Jääskeläinen * authentication whereas GPD TEE expects TEE_ALG_RSAES_PKCS1_V1_5 for 1410442c956SVesa Jääskeläinen * ciphering and TEE_ALG_RSASSA_PKCS1_V1_5 for authentication. 1420442c956SVesa Jääskeläinen */ 1430442c956SVesa Jääskeläinen if (*tee_id == TEE_ALG_RSAES_PKCS1_V1_5 && 1440442c956SVesa Jääskeläinen (function == PKCS11_FUNCTION_SIGN || 1450442c956SVesa Jääskeläinen function == PKCS11_FUNCTION_VERIFY)) 1460442c956SVesa Jääskeläinen *tee_id = TEE_ALG_RSASSA_PKCS1_V1_5; 1470442c956SVesa Jääskeläinen 148fb279d8bSVesa Jääskeläinen return rc; 149fb279d8bSVesa Jääskeläinen } 150fb279d8bSVesa Jääskeläinen 151fb279d8bSVesa Jääskeläinen static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type, 152fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj, 153fb279d8bSVesa Jääskeläinen enum processing_func function) 154fb279d8bSVesa Jääskeläinen { 155fb279d8bSVesa Jääskeläinen enum pkcs11_class_id class = get_class(obj->attributes); 156fb279d8bSVesa Jääskeläinen enum pkcs11_key_type type = get_key_type(obj->attributes); 157fb279d8bSVesa Jääskeläinen 158fb279d8bSVesa Jääskeläinen switch (class) { 159fb279d8bSVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 160fb279d8bSVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 161fb279d8bSVesa Jääskeläinen break; 162fb279d8bSVesa Jääskeläinen default: 163fb279d8bSVesa Jääskeläinen TEE_Panic(class); 164fb279d8bSVesa Jääskeläinen break; 165fb279d8bSVesa Jääskeläinen } 166fb279d8bSVesa Jääskeläinen 167fb279d8bSVesa Jääskeläinen switch (type) { 168fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 169*cc062b46SJorge Ramirez-Ortiz if (class == PKCS11_CKO_PRIVATE_KEY) { 170*cc062b46SJorge Ramirez-Ortiz if (function == PKCS11_FUNCTION_DERIVE) 171*cc062b46SJorge Ramirez-Ortiz *tee_type = TEE_TYPE_ECDH_KEYPAIR; 172*cc062b46SJorge Ramirez-Ortiz else 173fb279d8bSVesa Jääskeläinen *tee_type = TEE_TYPE_ECDSA_KEYPAIR; 174*cc062b46SJorge Ramirez-Ortiz } else { 175*cc062b46SJorge Ramirez-Ortiz if (function == PKCS11_FUNCTION_DERIVE) 176*cc062b46SJorge Ramirez-Ortiz *tee_type = TEE_TYPE_ECDH_PUBLIC_KEY; 177fb279d8bSVesa Jääskeläinen else 178fb279d8bSVesa Jääskeläinen *tee_type = TEE_TYPE_ECDSA_PUBLIC_KEY; 179*cc062b46SJorge Ramirez-Ortiz } 180fb279d8bSVesa Jääskeläinen break; 1810442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 1820442c956SVesa Jääskeläinen if (class == PKCS11_CKO_PRIVATE_KEY) 1830442c956SVesa Jääskeläinen *tee_type = TEE_TYPE_RSA_KEYPAIR; 1840442c956SVesa Jääskeläinen else 1850442c956SVesa Jääskeläinen *tee_type = TEE_TYPE_RSA_PUBLIC_KEY; 1860442c956SVesa Jääskeläinen break; 187fb279d8bSVesa Jääskeläinen default: 188fb279d8bSVesa Jääskeläinen TEE_Panic(type); 189fb279d8bSVesa Jääskeläinen break; 190fb279d8bSVesa Jääskeläinen } 191fb279d8bSVesa Jääskeläinen 192fb279d8bSVesa Jääskeläinen return PKCS11_CKR_OK; 193fb279d8bSVesa Jääskeläinen } 194fb279d8bSVesa Jääskeläinen 195fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 196fb279d8bSVesa Jääskeläinen allocate_tee_operation(struct pkcs11_session *session, 197fb279d8bSVesa Jääskeläinen enum processing_func function, 198fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *params, 199fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 200fb279d8bSVesa Jääskeläinen { 201fb279d8bSVesa Jääskeläinen uint32_t size = (uint32_t)get_object_key_bit_size(obj); 202fb279d8bSVesa Jääskeläinen uint32_t algo = 0; 203fb279d8bSVesa Jääskeläinen uint32_t hash_algo = 0; 204fb279d8bSVesa Jääskeläinen uint32_t mode = 0; 205fb279d8bSVesa Jääskeläinen uint32_t hash_mode = 0; 206fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 207fb279d8bSVesa Jääskeläinen struct active_processing *processing = session->processing; 208fb279d8bSVesa Jääskeläinen 209fb279d8bSVesa Jääskeläinen assert(processing->tee_op_handle == TEE_HANDLE_NULL); 210fb279d8bSVesa Jääskeläinen assert(processing->tee_hash_op_handle == TEE_HANDLE_NULL); 211fb279d8bSVesa Jääskeläinen 212fb279d8bSVesa Jääskeläinen if (pkcs2tee_algorithm(&algo, &hash_algo, function, params, obj)) 213fb279d8bSVesa Jääskeläinen return PKCS11_CKR_FUNCTION_FAILED; 214fb279d8bSVesa Jääskeläinen 215fb279d8bSVesa Jääskeläinen pkcs2tee_mode(&mode, function); 216fb279d8bSVesa Jääskeläinen 217fb279d8bSVesa Jääskeläinen if (hash_algo) { 218fb279d8bSVesa Jääskeläinen pkcs2tee_mode(&hash_mode, PKCS11_FUNCTION_DIGEST); 219fb279d8bSVesa Jääskeläinen 220fb279d8bSVesa Jääskeläinen res = TEE_AllocateOperation(&processing->tee_hash_op_handle, 221fb279d8bSVesa Jääskeläinen hash_algo, hash_mode, 0); 222fb279d8bSVesa Jääskeläinen if (res) { 223fb279d8bSVesa Jääskeläinen EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32, 224fb279d8bSVesa Jääskeläinen hash_algo, hash_mode); 225fb279d8bSVesa Jääskeläinen 226fb279d8bSVesa Jääskeläinen if (res == TEE_ERROR_NOT_SUPPORTED) 227fb279d8bSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_INVALID; 228fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 229fb279d8bSVesa Jääskeläinen } 230fb279d8bSVesa Jääskeläinen processing->tee_hash_algo = hash_algo; 231fb279d8bSVesa Jääskeläinen } 232fb279d8bSVesa Jääskeläinen 233fb279d8bSVesa Jääskeläinen res = TEE_AllocateOperation(&processing->tee_op_handle, 234fb279d8bSVesa Jääskeläinen algo, mode, size); 235fb279d8bSVesa Jääskeläinen if (res) 236fb279d8bSVesa Jääskeläinen EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 237fb279d8bSVesa Jääskeläinen algo, mode, size); 238fb279d8bSVesa Jääskeläinen 239fb279d8bSVesa Jääskeläinen if (res == TEE_ERROR_NOT_SUPPORTED) 240fb279d8bSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_INVALID; 241fb279d8bSVesa Jääskeläinen 242fb279d8bSVesa Jääskeläinen if (res != TEE_SUCCESS && 243fb279d8bSVesa Jääskeläinen processing->tee_hash_op_handle != TEE_HANDLE_NULL) { 244fb279d8bSVesa Jääskeläinen TEE_FreeOperation(session->processing->tee_hash_op_handle); 245fb279d8bSVesa Jääskeläinen processing->tee_hash_op_handle = TEE_HANDLE_NULL; 246fb279d8bSVesa Jääskeläinen processing->tee_hash_algo = 0; 247fb279d8bSVesa Jääskeläinen } 248fb279d8bSVesa Jääskeläinen 249fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 250fb279d8bSVesa Jääskeläinen } 251fb279d8bSVesa Jääskeläinen 252fb279d8bSVesa Jääskeläinen static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 253fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj, 254fb279d8bSVesa Jääskeläinen enum processing_func function) 255fb279d8bSVesa Jääskeläinen { 256fb279d8bSVesa Jääskeläinen TEE_Attribute *tee_attrs = NULL; 257fb279d8bSVesa Jääskeläinen size_t tee_attrs_count = 0; 258fb279d8bSVesa Jääskeläinen size_t object_size = 0; 259fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 260fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 261fb279d8bSVesa Jääskeläinen enum pkcs11_class_id __maybe_unused class = get_class(obj->attributes); 262fb279d8bSVesa Jääskeläinen enum pkcs11_key_type type = get_key_type(obj->attributes); 263fb279d8bSVesa Jääskeläinen 264fb279d8bSVesa Jääskeläinen assert(class == PKCS11_CKO_PUBLIC_KEY || 265fb279d8bSVesa Jääskeläinen class == PKCS11_CKO_PRIVATE_KEY); 266fb279d8bSVesa Jääskeläinen 267fb279d8bSVesa Jääskeläinen if (obj->key_handle != TEE_HANDLE_NULL) { 268fb279d8bSVesa Jääskeläinen switch (type) { 2690442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 2700442c956SVesa Jääskeläinen /* RSA loaded keys can be reused */ 2710442c956SVesa Jääskeläinen assert((obj->key_type == TEE_TYPE_RSA_PUBLIC_KEY && 2720442c956SVesa Jääskeläinen class == PKCS11_CKO_PUBLIC_KEY) || 2730442c956SVesa Jääskeläinen (obj->key_type == TEE_TYPE_RSA_KEYPAIR && 2740442c956SVesa Jääskeläinen class == PKCS11_CKO_PRIVATE_KEY)); 2750442c956SVesa Jääskeläinen goto key_ready; 276fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 277fb279d8bSVesa Jääskeläinen /* Reuse EC TEE key only if already DSA or DH */ 278fb279d8bSVesa Jääskeläinen switch (obj->key_type) { 279fb279d8bSVesa Jääskeläinen case TEE_TYPE_ECDSA_PUBLIC_KEY: 280fb279d8bSVesa Jääskeläinen case TEE_TYPE_ECDSA_KEYPAIR: 281fb279d8bSVesa Jääskeläinen if (function != PKCS11_FUNCTION_DERIVE) 282fb279d8bSVesa Jääskeläinen goto key_ready; 283fb279d8bSVesa Jääskeläinen break; 284*cc062b46SJorge Ramirez-Ortiz case TEE_TYPE_ECDH_PUBLIC_KEY: 285*cc062b46SJorge Ramirez-Ortiz case TEE_TYPE_ECDH_KEYPAIR: 286*cc062b46SJorge Ramirez-Ortiz if (function == PKCS11_FUNCTION_DERIVE) 287*cc062b46SJorge Ramirez-Ortiz goto key_ready; 288*cc062b46SJorge Ramirez-Ortiz break; 289fb279d8bSVesa Jääskeläinen default: 290fb279d8bSVesa Jääskeläinen assert(0); 291fb279d8bSVesa Jääskeläinen break; 292fb279d8bSVesa Jääskeläinen } 293fb279d8bSVesa Jääskeläinen break; 294fb279d8bSVesa Jääskeläinen default: 295fb279d8bSVesa Jääskeläinen assert(0); 296fb279d8bSVesa Jääskeläinen break; 297fb279d8bSVesa Jääskeläinen } 298fb279d8bSVesa Jääskeläinen 299fb279d8bSVesa Jääskeläinen TEE_CloseObject(obj->key_handle); 300fb279d8bSVesa Jääskeläinen obj->key_handle = TEE_HANDLE_NULL; 301fb279d8bSVesa Jääskeläinen } 302fb279d8bSVesa Jääskeläinen 303fb279d8bSVesa Jääskeläinen rc = pkcs2tee_key_type(&obj->key_type, obj, function); 304fb279d8bSVesa Jääskeläinen if (rc) 305fb279d8bSVesa Jääskeläinen return rc; 306fb279d8bSVesa Jääskeläinen 307fb279d8bSVesa Jääskeläinen object_size = get_object_key_bit_size(obj); 308fb279d8bSVesa Jääskeläinen if (!object_size) 309fb279d8bSVesa Jääskeläinen return PKCS11_CKR_GENERAL_ERROR; 310fb279d8bSVesa Jääskeläinen 311fb279d8bSVesa Jääskeläinen switch (type) { 3120442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 3130442c956SVesa Jääskeläinen rc = load_tee_rsa_key_attrs(&tee_attrs, &tee_attrs_count, obj); 3140442c956SVesa Jääskeläinen break; 315fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 316fb279d8bSVesa Jääskeläinen rc = load_tee_ec_key_attrs(&tee_attrs, &tee_attrs_count, obj); 317fb279d8bSVesa Jääskeläinen break; 318fb279d8bSVesa Jääskeläinen default: 319fb279d8bSVesa Jääskeläinen break; 320fb279d8bSVesa Jääskeläinen } 321fb279d8bSVesa Jääskeläinen if (rc) 322fb279d8bSVesa Jääskeläinen return rc; 323fb279d8bSVesa Jääskeläinen 324fb279d8bSVesa Jääskeläinen res = TEE_AllocateTransientObject(obj->key_type, object_size, 325fb279d8bSVesa Jääskeläinen &obj->key_handle); 326fb279d8bSVesa Jääskeläinen if (res) { 327fb279d8bSVesa Jääskeläinen DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 328fb279d8bSVesa Jääskeläinen 329fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 330fb279d8bSVesa Jääskeläinen } 331fb279d8bSVesa Jääskeläinen 332fb279d8bSVesa Jääskeläinen res = TEE_PopulateTransientObject(obj->key_handle, 333fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count); 334fb279d8bSVesa Jääskeläinen 335fb279d8bSVesa Jääskeläinen TEE_Free(tee_attrs); 336fb279d8bSVesa Jääskeläinen 337fb279d8bSVesa Jääskeläinen if (res) { 338fb279d8bSVesa Jääskeläinen DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 339fb279d8bSVesa Jääskeläinen 340fb279d8bSVesa Jääskeläinen goto error; 341fb279d8bSVesa Jääskeläinen } 342fb279d8bSVesa Jääskeläinen 343fb279d8bSVesa Jääskeläinen key_ready: 344fb279d8bSVesa Jääskeläinen res = TEE_SetOperationKey(session->processing->tee_op_handle, 345fb279d8bSVesa Jääskeläinen obj->key_handle); 346fb279d8bSVesa Jääskeläinen if (res) { 347fb279d8bSVesa Jääskeläinen DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 348fb279d8bSVesa Jääskeläinen 349fb279d8bSVesa Jääskeläinen goto error; 350fb279d8bSVesa Jääskeläinen } 351fb279d8bSVesa Jääskeläinen 352fb279d8bSVesa Jääskeläinen return PKCS11_CKR_OK; 353fb279d8bSVesa Jääskeläinen 354fb279d8bSVesa Jääskeläinen error: 355fb279d8bSVesa Jääskeläinen TEE_FreeTransientObject(obj->key_handle); 356fb279d8bSVesa Jääskeläinen obj->key_handle = TEE_HANDLE_NULL; 357fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 358fb279d8bSVesa Jääskeläinen } 359fb279d8bSVesa Jääskeläinen 360fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 361d9af50bcSVesa Jääskeläinen init_tee_operation(struct pkcs11_session *session, 362d9af50bcSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 363d9af50bcSVesa Jääskeläinen struct pkcs11_object *obj) 364fb279d8bSVesa Jääskeläinen { 365d9af50bcSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK; 366d9af50bcSVesa Jääskeläinen struct active_processing *proc = session->processing; 367d9af50bcSVesa Jääskeläinen 368d9af50bcSVesa Jääskeläinen switch (proc_params->id) { 369d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 370d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 371d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 372d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 373d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 374d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 375d9af50bcSVesa Jääskeläinen rc = pkcs2tee_proc_params_rsa_pss(proc, proc_params); 376d9af50bcSVesa Jääskeläinen if (rc) 377d9af50bcSVesa Jääskeläinen break; 378d9af50bcSVesa Jääskeläinen 379d9af50bcSVesa Jääskeläinen rc = pkcs2tee_validate_rsa_pss(proc, obj); 380d9af50bcSVesa Jääskeläinen break; 381dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 382dc8c77fcSVesa Jääskeläinen rc = pkcs2tee_proc_params_rsa_oaep(proc, proc_params); 383dc8c77fcSVesa Jääskeläinen break; 384d9af50bcSVesa Jääskeläinen default: 385d9af50bcSVesa Jääskeläinen break; 386d9af50bcSVesa Jääskeläinen } 387d9af50bcSVesa Jääskeläinen 388d9af50bcSVesa Jääskeläinen return rc; 389fb279d8bSVesa Jääskeläinen } 390fb279d8bSVesa Jääskeläinen 391fb279d8bSVesa Jääskeläinen enum pkcs11_rc init_asymm_operation(struct pkcs11_session *session, 392fb279d8bSVesa Jääskeläinen enum processing_func function, 393fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 394fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 395fb279d8bSVesa Jääskeläinen { 396fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 397fb279d8bSVesa Jääskeläinen 398fb279d8bSVesa Jääskeläinen assert(processing_is_tee_asymm(proc_params->id)); 399fb279d8bSVesa Jääskeläinen 400fb279d8bSVesa Jääskeläinen rc = allocate_tee_operation(session, function, proc_params, obj); 401fb279d8bSVesa Jääskeläinen if (rc) 402fb279d8bSVesa Jääskeläinen return rc; 403fb279d8bSVesa Jääskeläinen 404fb279d8bSVesa Jääskeläinen rc = load_tee_key(session, obj, function); 405fb279d8bSVesa Jääskeläinen if (rc) 406fb279d8bSVesa Jääskeläinen return rc; 407fb279d8bSVesa Jääskeläinen 408d9af50bcSVesa Jääskeläinen return init_tee_operation(session, proc_params, obj); 409fb279d8bSVesa Jääskeläinen } 410fb279d8bSVesa Jääskeläinen 411fb279d8bSVesa Jääskeläinen /* 412fb279d8bSVesa Jääskeläinen * step_sym_step - step (update/oneshot/final) on a symmetric crypto operation 413fb279d8bSVesa Jääskeläinen * 414fb279d8bSVesa Jääskeläinen * @session - current session 415fb279d8bSVesa Jääskeläinen * @function - processing function (encrypt, decrypt, sign, ...) 416fb279d8bSVesa Jääskeläinen * @step - step ID in the processing (oneshot, update, final) 417fb279d8bSVesa Jääskeläinen * @ptypes - invocation parameter types 418fb279d8bSVesa Jääskeläinen * @params - invocation parameter references 419fb279d8bSVesa Jääskeläinen */ 420fb279d8bSVesa Jääskeläinen enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session, 421fb279d8bSVesa Jääskeläinen enum processing_func function, 422fb279d8bSVesa Jääskeläinen enum processing_step step, 423fb279d8bSVesa Jääskeläinen uint32_t ptypes, TEE_Param *params) 424fb279d8bSVesa Jääskeläinen { 425fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 426fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 427fb279d8bSVesa Jääskeläinen void *in_buf = NULL; 428fb279d8bSVesa Jääskeläinen void *in2_buf = NULL; 429fb279d8bSVesa Jääskeläinen void *out_buf = NULL; 430fb279d8bSVesa Jääskeläinen void *hash_buf = NULL; 431fb279d8bSVesa Jääskeläinen uint32_t in_size = 0; 432fb279d8bSVesa Jääskeläinen uint32_t in2_size = 0; 433fb279d8bSVesa Jääskeläinen uint32_t out_size = 0; 434fb279d8bSVesa Jääskeläinen uint32_t hash_size = 0; 435fb279d8bSVesa Jääskeläinen TEE_Attribute *tee_attrs = NULL; 436fb279d8bSVesa Jääskeläinen size_t tee_attrs_count = 0; 437fb279d8bSVesa Jääskeläinen bool output_data = false; 438fb279d8bSVesa Jääskeläinen struct active_processing *proc = session->processing; 439dc8c77fcSVesa Jääskeläinen struct rsa_oaep_processing_ctx *rsa_oaep_ctx = NULL; 440d9af50bcSVesa Jääskeläinen struct rsa_pss_processing_ctx *rsa_pss_ctx = NULL; 441fb279d8bSVesa Jääskeläinen size_t sz = 0; 442fb279d8bSVesa Jääskeläinen 443fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 444fb279d8bSVesa Jääskeläinen in_buf = params[1].memref.buffer; 445fb279d8bSVesa Jääskeläinen in_size = params[1].memref.size; 446fb279d8bSVesa Jääskeläinen if (in_size && !in_buf) 447fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 448fb279d8bSVesa Jääskeläinen } 449fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 450fb279d8bSVesa Jääskeläinen in2_buf = params[2].memref.buffer; 451fb279d8bSVesa Jääskeläinen in2_size = params[2].memref.size; 452fb279d8bSVesa Jääskeläinen if (in2_size && !in2_buf) 453fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 454fb279d8bSVesa Jääskeläinen } 455fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 456fb279d8bSVesa Jääskeläinen out_buf = params[2].memref.buffer; 457fb279d8bSVesa Jääskeläinen out_size = params[2].memref.size; 458fb279d8bSVesa Jääskeläinen if (out_size && !out_buf) 459fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 460fb279d8bSVesa Jääskeläinen } 461fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 462fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 463fb279d8bSVesa Jääskeläinen 464fb279d8bSVesa Jääskeläinen switch (step) { 465fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_ONESHOT: 466fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE: 467fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_FINAL: 468fb279d8bSVesa Jääskeläinen break; 469fb279d8bSVesa Jääskeläinen default: 470fb279d8bSVesa Jääskeläinen return PKCS11_CKR_GENERAL_ERROR; 471fb279d8bSVesa Jääskeläinen } 472fb279d8bSVesa Jääskeläinen 473d9af50bcSVesa Jääskeläinen /* TEE attribute(s) required by the operation */ 474d9af50bcSVesa Jääskeläinen switch (proc->mecha_type) { 475d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 476d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 477d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 478d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 479d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 480d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 481d9af50bcSVesa Jääskeläinen tee_attrs = TEE_Malloc(sizeof(TEE_Attribute), 482d9af50bcSVesa Jääskeläinen TEE_USER_MEM_HINT_NO_FILL_ZERO); 483d9af50bcSVesa Jääskeläinen if (!tee_attrs) { 484d9af50bcSVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY; 485d9af50bcSVesa Jääskeläinen goto out; 486d9af50bcSVesa Jääskeläinen } 487d9af50bcSVesa Jääskeläinen 488d9af50bcSVesa Jääskeläinen rsa_pss_ctx = proc->extra_ctx; 489d9af50bcSVesa Jääskeläinen 490d9af50bcSVesa Jääskeläinen TEE_InitValueAttribute(&tee_attrs[tee_attrs_count], 491d9af50bcSVesa Jääskeläinen TEE_ATTR_RSA_PSS_SALT_LENGTH, 492d9af50bcSVesa Jääskeläinen rsa_pss_ctx->salt_len, 0); 493d9af50bcSVesa Jääskeläinen tee_attrs_count++; 494d9af50bcSVesa Jääskeläinen break; 495dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 496dc8c77fcSVesa Jääskeläinen rsa_oaep_ctx = proc->extra_ctx; 497dc8c77fcSVesa Jääskeläinen 498dc8c77fcSVesa Jääskeläinen if (!rsa_oaep_ctx->source_data_len) 499dc8c77fcSVesa Jääskeläinen break; 500dc8c77fcSVesa Jääskeläinen 501dc8c77fcSVesa Jääskeläinen tee_attrs = TEE_Malloc(sizeof(TEE_Attribute), 502dc8c77fcSVesa Jääskeläinen TEE_USER_MEM_HINT_NO_FILL_ZERO); 503dc8c77fcSVesa Jääskeläinen if (!tee_attrs) { 504dc8c77fcSVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY; 505dc8c77fcSVesa Jääskeläinen goto out; 506dc8c77fcSVesa Jääskeläinen } 507dc8c77fcSVesa Jääskeläinen 508dc8c77fcSVesa Jääskeläinen TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 509dc8c77fcSVesa Jääskeläinen TEE_ATTR_RSA_OAEP_LABEL, 510dc8c77fcSVesa Jääskeläinen rsa_oaep_ctx->source_data, 511dc8c77fcSVesa Jääskeläinen rsa_oaep_ctx->source_data_len); 512dc8c77fcSVesa Jääskeläinen tee_attrs_count++; 513dc8c77fcSVesa Jääskeläinen break; 514d9af50bcSVesa Jääskeläinen default: 515d9af50bcSVesa Jääskeläinen break; 516d9af50bcSVesa Jääskeläinen } 517d9af50bcSVesa Jääskeläinen 518fb279d8bSVesa Jääskeläinen /* 519fb279d8bSVesa Jääskeläinen * Handle multi stage update step for mechas needing hash 520fb279d8bSVesa Jääskeläinen * calculation 521fb279d8bSVesa Jääskeläinen */ 522fb279d8bSVesa Jääskeläinen if (step == PKCS11_FUNC_STEP_UPDATE) { 523fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 524fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 525fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 526fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 527fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 528fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 5290442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 5300442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 5310442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 5320442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 5330442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 5340442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 535d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 536d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 537d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 538d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 539d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 540fb279d8bSVesa Jääskeläinen assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL); 541fb279d8bSVesa Jääskeläinen 542fb279d8bSVesa Jääskeläinen TEE_DigestUpdate(proc->tee_hash_op_handle, in_buf, 543fb279d8bSVesa Jääskeläinen in_size); 5449df68186SEtienne Carriere rc = PKCS11_CKR_OK; 545fb279d8bSVesa Jääskeläinen break; 546fb279d8bSVesa Jääskeläinen default: 547fb279d8bSVesa Jääskeläinen /* 548fb279d8bSVesa Jääskeläinen * Other mechanism do not expect multi stage 549fb279d8bSVesa Jääskeläinen * operation 550fb279d8bSVesa Jääskeläinen */ 551fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_GENERAL_ERROR; 552fb279d8bSVesa Jääskeläinen break; 553fb279d8bSVesa Jääskeläinen } 554fb279d8bSVesa Jääskeläinen 555fb279d8bSVesa Jääskeläinen goto out; 556fb279d8bSVesa Jääskeläinen } 557fb279d8bSVesa Jääskeläinen 558fb279d8bSVesa Jääskeläinen /* 559fb279d8bSVesa Jääskeläinen * Handle multi stage one shot and final steps for mechas needing hash 560fb279d8bSVesa Jääskeläinen * calculation 561fb279d8bSVesa Jääskeläinen */ 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 hash_size = TEE_ALG_GET_DIGEST_SIZE(proc->tee_hash_algo); 582fb279d8bSVesa Jääskeläinen hash_buf = TEE_Malloc(hash_size, 0); 583fb279d8bSVesa Jääskeläinen if (!hash_buf) 584fb279d8bSVesa Jääskeläinen return PKCS11_CKR_DEVICE_MEMORY; 585fb279d8bSVesa Jääskeläinen 586fb279d8bSVesa Jääskeläinen res = TEE_DigestDoFinal(proc->tee_hash_op_handle, 587fb279d8bSVesa Jääskeläinen in_buf, in_size, hash_buf, 588fb279d8bSVesa Jääskeläinen &hash_size); 589fb279d8bSVesa Jääskeläinen 590fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 591fb279d8bSVesa Jääskeläinen if (rc != PKCS11_CKR_OK) 592fb279d8bSVesa Jääskeläinen goto out; 593fb279d8bSVesa Jääskeläinen 594fb279d8bSVesa Jääskeläinen break; 595fb279d8bSVesa Jääskeläinen default: 596fb279d8bSVesa Jääskeläinen break; 597fb279d8bSVesa Jääskeläinen } 598fb279d8bSVesa Jääskeläinen 599fb279d8bSVesa Jääskeläinen /* 600fb279d8bSVesa Jääskeläinen * Finalize either provided hash or calculated hash with signing 601fb279d8bSVesa Jääskeläinen * operation 602fb279d8bSVesa Jääskeläinen */ 603fb279d8bSVesa Jääskeläinen 604fb279d8bSVesa Jääskeläinen /* First determine amount of bytes for signing operation */ 605fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 606fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 607fb279d8bSVesa Jääskeläinen sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle); 608fb279d8bSVesa Jääskeläinen if (!in_size || !sz) { 609fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 610fb279d8bSVesa Jääskeläinen goto out; 611fb279d8bSVesa Jääskeläinen } 612fb279d8bSVesa Jääskeläinen 613fb279d8bSVesa Jääskeläinen /* 614fb279d8bSVesa Jääskeläinen * Note 3) Input the entire raw digest. Internally, this will 615fb279d8bSVesa Jääskeläinen * be truncated to the appropriate number of bits. 616fb279d8bSVesa Jääskeläinen */ 617fb279d8bSVesa Jääskeläinen if (in_size > sz) 618fb279d8bSVesa Jääskeläinen in_size = sz; 619fb279d8bSVesa Jääskeläinen 620fb279d8bSVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && in2_size != 2 * sz) { 621fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 622fb279d8bSVesa Jääskeläinen goto out; 623fb279d8bSVesa Jääskeläinen } 624fb279d8bSVesa Jääskeläinen break; 625fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 626fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 627fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 628fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 629fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 630fb279d8bSVesa Jääskeläinen /* Get key size in bytes */ 631fb279d8bSVesa Jääskeläinen sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle); 632fb279d8bSVesa Jääskeläinen if (!sz) { 633fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 634fb279d8bSVesa Jääskeläinen goto out; 635fb279d8bSVesa Jääskeläinen } 636fb279d8bSVesa Jääskeläinen 637fb279d8bSVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && 638fb279d8bSVesa Jääskeläinen in2_size != 2 * sz) { 639fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 640fb279d8bSVesa Jääskeläinen goto out; 641fb279d8bSVesa Jääskeläinen } 642fb279d8bSVesa Jääskeläinen break; 6430442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 6440442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 6450442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 6460442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 6470442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 6480442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 6490442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 650d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 651d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 652d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 653d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 654d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 655d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 6560442c956SVesa Jääskeläinen /* Get key size in bytes */ 6570442c956SVesa Jääskeläinen sz = rsa_get_input_max_byte_size(proc->tee_op_handle); 6580442c956SVesa Jääskeläinen if (!sz) { 6590442c956SVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 6600442c956SVesa Jääskeläinen goto out; 6610442c956SVesa Jääskeläinen } 6620442c956SVesa Jääskeläinen 6630442c956SVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && in2_size != sz) { 6640442c956SVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 6650442c956SVesa Jääskeläinen goto out; 6660442c956SVesa Jääskeläinen } 6670442c956SVesa Jääskeläinen break; 668fb279d8bSVesa Jääskeläinen default: 669fb279d8bSVesa Jääskeläinen break; 670fb279d8bSVesa Jääskeläinen } 671fb279d8bSVesa Jääskeläinen 672fb279d8bSVesa Jääskeläinen /* Next perform actual signing operation */ 673fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 674fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 6750442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 676dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 677d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 678fb279d8bSVesa Jääskeläinen /* For operations using provided input data */ 679fb279d8bSVesa Jääskeläinen switch (function) { 680fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_ENCRYPT: 681fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricEncrypt(proc->tee_op_handle, 682fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count, 683fb279d8bSVesa Jääskeläinen in_buf, in_size, 684fb279d8bSVesa Jääskeläinen out_buf, &out_size); 685fb279d8bSVesa Jääskeläinen output_data = true; 686fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 6876a6299fbSVesa Jääskeläinen if (rc == PKCS11_CKR_ARGUMENTS_BAD) 6886a6299fbSVesa Jääskeläinen rc = PKCS11_CKR_DATA_LEN_RANGE; 689fb279d8bSVesa Jääskeläinen break; 690fb279d8bSVesa Jääskeläinen 691fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_DECRYPT: 692fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricDecrypt(proc->tee_op_handle, 693fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count, 694fb279d8bSVesa Jääskeläinen in_buf, in_size, 695fb279d8bSVesa Jääskeläinen out_buf, &out_size); 696fb279d8bSVesa Jääskeläinen output_data = true; 697fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 698f27310a5SVesa Jääskeläinen if (rc == PKCS11_CKR_ARGUMENTS_BAD) 699f27310a5SVesa Jääskeläinen rc = PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 700fb279d8bSVesa Jääskeläinen break; 701fb279d8bSVesa Jääskeläinen 702fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_SIGN: 703fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricSignDigest(proc->tee_op_handle, 704fb279d8bSVesa Jääskeläinen tee_attrs, 705fb279d8bSVesa Jääskeläinen tee_attrs_count, 706fb279d8bSVesa Jääskeläinen in_buf, in_size, 707fb279d8bSVesa Jääskeläinen out_buf, &out_size); 708fb279d8bSVesa Jääskeläinen output_data = true; 709fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 710fb279d8bSVesa Jääskeläinen break; 711fb279d8bSVesa Jääskeläinen 712fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_VERIFY: 713fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle, 714fb279d8bSVesa Jääskeläinen tee_attrs, 715fb279d8bSVesa Jääskeläinen tee_attrs_count, 716fb279d8bSVesa Jääskeläinen in_buf, in_size, 717fb279d8bSVesa Jääskeläinen in2_buf, in2_size); 718fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 719fb279d8bSVesa Jääskeläinen break; 720fb279d8bSVesa Jääskeläinen 721fb279d8bSVesa Jääskeläinen default: 722fb279d8bSVesa Jääskeläinen TEE_Panic(function); 723fb279d8bSVesa Jääskeläinen break; 724fb279d8bSVesa Jääskeläinen } 725fb279d8bSVesa Jääskeläinen break; 726fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 727fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 728fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 729fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 730fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 7310442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 7320442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 7330442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 7340442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 7350442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 7360442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 737d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 738d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 739d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 740d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 741d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 742fb279d8bSVesa Jääskeläinen /* For operations having hash operation use calculated hash */ 743fb279d8bSVesa Jääskeläinen switch (function) { 744fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_SIGN: 745fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricSignDigest(proc->tee_op_handle, 746fb279d8bSVesa Jääskeläinen tee_attrs, 747fb279d8bSVesa Jääskeläinen tee_attrs_count, 748fb279d8bSVesa Jääskeläinen hash_buf, hash_size, 749fb279d8bSVesa Jääskeläinen out_buf, &out_size); 750fb279d8bSVesa Jääskeläinen output_data = true; 751fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 752fb279d8bSVesa Jääskeläinen break; 753fb279d8bSVesa Jääskeläinen 754fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_VERIFY: 755fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle, 756fb279d8bSVesa Jääskeläinen tee_attrs, 757fb279d8bSVesa Jääskeläinen tee_attrs_count, 758fb279d8bSVesa Jääskeläinen hash_buf, hash_size, 759fb279d8bSVesa Jääskeläinen in2_buf, in2_size); 760fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 761fb279d8bSVesa Jääskeläinen break; 762fb279d8bSVesa Jääskeläinen 763fb279d8bSVesa Jääskeläinen default: 764fb279d8bSVesa Jääskeläinen TEE_Panic(function); 765fb279d8bSVesa Jääskeläinen break; 766fb279d8bSVesa Jääskeläinen } 767fb279d8bSVesa Jääskeläinen break; 768fb279d8bSVesa Jääskeläinen default: 769fb279d8bSVesa Jääskeläinen TEE_Panic(proc->mecha_type); 770fb279d8bSVesa Jääskeläinen break; 771fb279d8bSVesa Jääskeläinen } 772fb279d8bSVesa Jääskeläinen 773fb279d8bSVesa Jääskeläinen out: 774fb279d8bSVesa Jääskeläinen if (output_data && 775fb279d8bSVesa Jääskeläinen (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 776fb279d8bSVesa Jääskeläinen switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 777fb279d8bSVesa Jääskeläinen case TEE_PARAM_TYPE_MEMREF_OUTPUT: 778fb279d8bSVesa Jääskeläinen case TEE_PARAM_TYPE_MEMREF_INOUT: 779fb279d8bSVesa Jääskeläinen params[2].memref.size = out_size; 780fb279d8bSVesa Jääskeläinen break; 781fb279d8bSVesa Jääskeläinen default: 782fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_GENERAL_ERROR; 783fb279d8bSVesa Jääskeläinen break; 784fb279d8bSVesa Jääskeläinen } 785fb279d8bSVesa Jääskeläinen } 786fb279d8bSVesa Jääskeläinen 787fb279d8bSVesa Jääskeläinen TEE_Free(hash_buf); 788fb279d8bSVesa Jääskeläinen TEE_Free(tee_attrs); 789fb279d8bSVesa Jääskeläinen 790fb279d8bSVesa Jääskeläinen return rc; 791fb279d8bSVesa Jääskeläinen } 792*cc062b46SJorge Ramirez-Ortiz 793*cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc do_asymm_derivation(struct pkcs11_session *session, 794*cc062b46SJorge Ramirez-Ortiz struct pkcs11_attribute_head *proc_params, 795*cc062b46SJorge Ramirez-Ortiz struct obj_attrs **head) 796*cc062b46SJorge Ramirez-Ortiz { 797*cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 798*cc062b46SJorge Ramirez-Ortiz TEE_ObjectHandle out_handle = TEE_HANDLE_NULL; 799*cc062b46SJorge Ramirez-Ortiz TEE_Result res = TEE_ERROR_GENERIC; 800*cc062b46SJorge Ramirez-Ortiz TEE_Attribute tee_attrs[2] = { }; 801*cc062b46SJorge Ramirez-Ortiz size_t tee_attrs_count = 0; 802*cc062b46SJorge Ramirez-Ortiz uint32_t key_byte_size = 0; 803*cc062b46SJorge Ramirez-Ortiz uint32_t key_bit_size = 0; 804*cc062b46SJorge Ramirez-Ortiz void *a_ptr = NULL; 805*cc062b46SJorge Ramirez-Ortiz size_t a_size = 0; 806*cc062b46SJorge Ramirez-Ortiz 807*cc062b46SJorge Ramirez-Ortiz /* Remove default attribute set at template sanitization */ 808*cc062b46SJorge Ramirez-Ortiz if (remove_empty_attribute(head, PKCS11_CKA_VALUE)) 809*cc062b46SJorge Ramirez-Ortiz return PKCS11_CKR_FUNCTION_FAILED; 810*cc062b46SJorge Ramirez-Ortiz 811*cc062b46SJorge Ramirez-Ortiz rc = get_u32_attribute(*head, PKCS11_CKA_VALUE_LEN, &key_bit_size); 812*cc062b46SJorge Ramirez-Ortiz if (rc) 813*cc062b46SJorge Ramirez-Ortiz return rc; 814*cc062b46SJorge Ramirez-Ortiz 815*cc062b46SJorge Ramirez-Ortiz key_bit_size *= 8; 816*cc062b46SJorge Ramirez-Ortiz key_byte_size = (key_bit_size + 7) / 8; 817*cc062b46SJorge Ramirez-Ortiz 818*cc062b46SJorge Ramirez-Ortiz res = TEE_AllocateTransientObject(TEE_TYPE_GENERIC_SECRET, 819*cc062b46SJorge Ramirez-Ortiz key_byte_size * 8, &out_handle); 820*cc062b46SJorge Ramirez-Ortiz if (res) { 821*cc062b46SJorge Ramirez-Ortiz DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 822*cc062b46SJorge Ramirez-Ortiz return tee2pkcs_error(res); 823*cc062b46SJorge Ramirez-Ortiz } 824*cc062b46SJorge Ramirez-Ortiz 825*cc062b46SJorge Ramirez-Ortiz switch (proc_params->id) { 826*cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 827*cc062b46SJorge Ramirez-Ortiz rc = pkcs2tee_param_ecdh(proc_params, &a_ptr, &a_size); 828*cc062b46SJorge Ramirez-Ortiz if (rc) 829*cc062b46SJorge Ramirez-Ortiz goto out; 830*cc062b46SJorge Ramirez-Ortiz 831*cc062b46SJorge Ramirez-Ortiz TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 832*cc062b46SJorge Ramirez-Ortiz TEE_ATTR_ECC_PUBLIC_VALUE_X, 833*cc062b46SJorge Ramirez-Ortiz a_ptr, a_size / 2); 834*cc062b46SJorge Ramirez-Ortiz tee_attrs_count++; 835*cc062b46SJorge Ramirez-Ortiz TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 836*cc062b46SJorge Ramirez-Ortiz TEE_ATTR_ECC_PUBLIC_VALUE_Y, 837*cc062b46SJorge Ramirez-Ortiz (char *)a_ptr + a_size / 2, 838*cc062b46SJorge Ramirez-Ortiz a_size / 2); 839*cc062b46SJorge Ramirez-Ortiz tee_attrs_count++; 840*cc062b46SJorge Ramirez-Ortiz break; 841*cc062b46SJorge Ramirez-Ortiz default: 842*cc062b46SJorge Ramirez-Ortiz TEE_Panic(proc_params->id); 843*cc062b46SJorge Ramirez-Ortiz break; 844*cc062b46SJorge Ramirez-Ortiz } 845*cc062b46SJorge Ramirez-Ortiz 846*cc062b46SJorge Ramirez-Ortiz TEE_DeriveKey(session->processing->tee_op_handle, &tee_attrs[0], 847*cc062b46SJorge Ramirez-Ortiz tee_attrs_count, out_handle); 848*cc062b46SJorge Ramirez-Ortiz 849*cc062b46SJorge Ramirez-Ortiz rc = alloc_get_tee_attribute_data(out_handle, TEE_ATTR_SECRET_VALUE, 850*cc062b46SJorge Ramirez-Ortiz &a_ptr, &a_size); 851*cc062b46SJorge Ramirez-Ortiz if (rc) 852*cc062b46SJorge Ramirez-Ortiz goto out; 853*cc062b46SJorge Ramirez-Ortiz 854*cc062b46SJorge Ramirez-Ortiz if (a_size * 8 < key_bit_size) 855*cc062b46SJorge Ramirez-Ortiz rc = PKCS11_CKR_KEY_SIZE_RANGE; 856*cc062b46SJorge Ramirez-Ortiz else 857*cc062b46SJorge Ramirez-Ortiz rc = add_attribute(head, PKCS11_CKA_VALUE, a_ptr, 858*cc062b46SJorge Ramirez-Ortiz key_byte_size); 859*cc062b46SJorge Ramirez-Ortiz TEE_Free(a_ptr); 860*cc062b46SJorge Ramirez-Ortiz out: 861*cc062b46SJorge Ramirez-Ortiz release_active_processing(session); 862*cc062b46SJorge Ramirez-Ortiz TEE_FreeTransientObject(out_handle); 863*cc062b46SJorge Ramirez-Ortiz 864*cc062b46SJorge Ramirez-Ortiz return rc; 865*cc062b46SJorge Ramirez-Ortiz } 866