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: 38fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 39fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 40fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 41fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 42fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 43fb279d8bSVesa Jääskeläinen return true; 44fb279d8bSVesa Jääskeläinen default: 45fb279d8bSVesa Jääskeläinen return false; 46fb279d8bSVesa Jääskeläinen } 47fb279d8bSVesa Jääskeläinen } 48fb279d8bSVesa Jääskeläinen 49fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 50fb279d8bSVesa Jääskeläinen pkcs2tee_algorithm(uint32_t *tee_id, uint32_t *tee_hash_id, 51fb279d8bSVesa Jääskeläinen enum processing_func function __unused, 52fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 53fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 54fb279d8bSVesa Jääskeläinen { 55fb279d8bSVesa Jääskeläinen static const struct { 56fb279d8bSVesa Jääskeläinen enum pkcs11_mechanism_id mech_id; 57fb279d8bSVesa Jääskeläinen uint32_t tee_id; 58fb279d8bSVesa Jääskeläinen uint32_t tee_hash_id; 59fb279d8bSVesa Jääskeläinen } pkcs2tee_algo[] = { 600442c956SVesa Jääskeläinen /* RSA flavors */ 610442c956SVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS, TEE_ALG_RSAES_PKCS1_V1_5, 0 }, 62dc8c77fcSVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS_OAEP, 1, 0 }, 63d9af50bcSVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS_PSS, 1, 0 }, 640442c956SVesa Jääskeläinen { PKCS11_CKM_MD5_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_MD5, 650442c956SVesa Jääskeläinen TEE_ALG_MD5 }, 660442c956SVesa Jääskeläinen { PKCS11_CKM_SHA1_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA1, 670442c956SVesa Jääskeläinen TEE_ALG_SHA1 }, 680442c956SVesa Jääskeläinen { PKCS11_CKM_SHA224_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA224, 690442c956SVesa Jääskeläinen TEE_ALG_SHA224 }, 700442c956SVesa Jääskeläinen { PKCS11_CKM_SHA256_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA256, 710442c956SVesa Jääskeläinen TEE_ALG_SHA256 }, 720442c956SVesa Jääskeläinen { PKCS11_CKM_SHA384_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA384, 730442c956SVesa Jääskeläinen TEE_ALG_SHA384 }, 740442c956SVesa Jääskeläinen { PKCS11_CKM_SHA512_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA512, 750442c956SVesa Jääskeläinen TEE_ALG_SHA512 }, 76d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA1_RSA_PKCS_PSS, 77d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1, TEE_ALG_SHA1 }, 78d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA224_RSA_PKCS_PSS, 79d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224, TEE_ALG_SHA224 }, 80d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA256_RSA_PKCS_PSS, 81d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256, TEE_ALG_SHA256 }, 82d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA384_RSA_PKCS_PSS, 83d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384, TEE_ALG_SHA384 }, 84d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA512_RSA_PKCS_PSS, 85d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512, TEE_ALG_SHA512 }, 86fb279d8bSVesa Jääskeläinen /* EC flavors (Must find key size from the object) */ 87fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA, 1, 0 }, 88fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA1, 1, TEE_ALG_SHA1 }, 89fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA224, 1, TEE_ALG_SHA224 }, 90fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA256, 1, TEE_ALG_SHA256 }, 91fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA384, 1, TEE_ALG_SHA384 }, 92fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA512, 1, TEE_ALG_SHA512 }, 93fb279d8bSVesa Jääskeläinen }; 94fb279d8bSVesa Jääskeläinen size_t n = 0; 95fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 96fb279d8bSVesa Jääskeläinen 97fb279d8bSVesa Jääskeläinen for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) { 98fb279d8bSVesa Jääskeläinen if (pkcs2tee_algo[n].mech_id == proc_params->id) { 99fb279d8bSVesa Jääskeläinen *tee_id = pkcs2tee_algo[n].tee_id; 100fb279d8bSVesa Jääskeläinen *tee_hash_id = pkcs2tee_algo[n].tee_hash_id; 101fb279d8bSVesa Jääskeläinen break; 102fb279d8bSVesa Jääskeläinen } 103fb279d8bSVesa Jääskeläinen } 104fb279d8bSVesa Jääskeläinen 105fb279d8bSVesa Jääskeläinen if (n == ARRAY_SIZE(pkcs2tee_algo)) 106fb279d8bSVesa Jääskeläinen return PKCS11_RV_NOT_IMPLEMENTED; 107fb279d8bSVesa Jääskeläinen 108fb279d8bSVesa Jääskeläinen switch (proc_params->id) { 109d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 110d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 111d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 112d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 113d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 114d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 115d9af50bcSVesa Jääskeläinen rc = pkcs2tee_algo_rsa_pss(tee_id, proc_params); 116d9af50bcSVesa Jääskeläinen break; 117dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 118dc8c77fcSVesa Jääskeläinen rc = pkcs2tee_algo_rsa_oaep(tee_id, tee_hash_id, proc_params); 119dc8c77fcSVesa Jääskeläinen break; 120fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 121fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 122fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 123fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 124fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 125fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 126fb279d8bSVesa Jääskeläinen rc = pkcs2tee_algo_ecdsa(tee_id, proc_params, obj); 127fb279d8bSVesa Jääskeläinen break; 128fb279d8bSVesa Jääskeläinen default: 129fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_OK; 130fb279d8bSVesa Jääskeläinen break; 131fb279d8bSVesa Jääskeläinen } 132fb279d8bSVesa Jääskeläinen 1330442c956SVesa Jääskeläinen /* 1340442c956SVesa Jääskeläinen * PKCS#11 uses single mechanism CKM_RSA_PKCS for both ciphering and 1350442c956SVesa Jääskeläinen * authentication whereas GPD TEE expects TEE_ALG_RSAES_PKCS1_V1_5 for 1360442c956SVesa Jääskeläinen * ciphering and TEE_ALG_RSASSA_PKCS1_V1_5 for authentication. 1370442c956SVesa Jääskeläinen */ 1380442c956SVesa Jääskeläinen if (*tee_id == TEE_ALG_RSAES_PKCS1_V1_5 && 1390442c956SVesa Jääskeläinen (function == PKCS11_FUNCTION_SIGN || 1400442c956SVesa Jääskeläinen function == PKCS11_FUNCTION_VERIFY)) 1410442c956SVesa Jääskeläinen *tee_id = TEE_ALG_RSASSA_PKCS1_V1_5; 1420442c956SVesa Jääskeläinen 143fb279d8bSVesa Jääskeläinen return rc; 144fb279d8bSVesa Jääskeläinen } 145fb279d8bSVesa Jääskeläinen 146fb279d8bSVesa Jääskeläinen static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type, 147fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj, 148fb279d8bSVesa Jääskeläinen enum processing_func function) 149fb279d8bSVesa Jääskeläinen { 150fb279d8bSVesa Jääskeläinen enum pkcs11_class_id class = get_class(obj->attributes); 151fb279d8bSVesa Jääskeläinen enum pkcs11_key_type type = get_key_type(obj->attributes); 152fb279d8bSVesa Jääskeläinen 153fb279d8bSVesa Jääskeläinen switch (class) { 154fb279d8bSVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 155fb279d8bSVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 156fb279d8bSVesa Jääskeläinen break; 157fb279d8bSVesa Jääskeläinen default: 158fb279d8bSVesa Jääskeläinen TEE_Panic(class); 159fb279d8bSVesa Jääskeläinen break; 160fb279d8bSVesa Jääskeläinen } 161fb279d8bSVesa Jääskeläinen 162fb279d8bSVesa Jääskeläinen switch (type) { 163fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 164fb279d8bSVesa Jääskeläinen assert(function != PKCS11_FUNCTION_DERIVE); 165fb279d8bSVesa Jääskeläinen 166fb279d8bSVesa Jääskeläinen if (class == PKCS11_CKO_PRIVATE_KEY) 167fb279d8bSVesa Jääskeläinen *tee_type = TEE_TYPE_ECDSA_KEYPAIR; 168fb279d8bSVesa Jääskeläinen else 169fb279d8bSVesa Jääskeläinen *tee_type = TEE_TYPE_ECDSA_PUBLIC_KEY; 170fb279d8bSVesa Jääskeläinen break; 1710442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 1720442c956SVesa Jääskeläinen if (class == PKCS11_CKO_PRIVATE_KEY) 1730442c956SVesa Jääskeläinen *tee_type = TEE_TYPE_RSA_KEYPAIR; 1740442c956SVesa Jääskeläinen else 1750442c956SVesa Jääskeläinen *tee_type = TEE_TYPE_RSA_PUBLIC_KEY; 1760442c956SVesa Jääskeläinen break; 177fb279d8bSVesa Jääskeläinen default: 178fb279d8bSVesa Jääskeläinen TEE_Panic(type); 179fb279d8bSVesa Jääskeläinen break; 180fb279d8bSVesa Jääskeläinen } 181fb279d8bSVesa Jääskeläinen 182fb279d8bSVesa Jääskeläinen return PKCS11_CKR_OK; 183fb279d8bSVesa Jääskeläinen } 184fb279d8bSVesa Jääskeläinen 185fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 186fb279d8bSVesa Jääskeläinen allocate_tee_operation(struct pkcs11_session *session, 187fb279d8bSVesa Jääskeläinen enum processing_func function, 188fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *params, 189fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 190fb279d8bSVesa Jääskeläinen { 191fb279d8bSVesa Jääskeläinen uint32_t size = (uint32_t)get_object_key_bit_size(obj); 192fb279d8bSVesa Jääskeläinen uint32_t algo = 0; 193fb279d8bSVesa Jääskeläinen uint32_t hash_algo = 0; 194fb279d8bSVesa Jääskeläinen uint32_t mode = 0; 195fb279d8bSVesa Jääskeläinen uint32_t hash_mode = 0; 196fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 197fb279d8bSVesa Jääskeläinen struct active_processing *processing = session->processing; 198fb279d8bSVesa Jääskeläinen 199fb279d8bSVesa Jääskeläinen assert(processing->tee_op_handle == TEE_HANDLE_NULL); 200fb279d8bSVesa Jääskeläinen assert(processing->tee_hash_op_handle == TEE_HANDLE_NULL); 201fb279d8bSVesa Jääskeläinen 202fb279d8bSVesa Jääskeläinen if (pkcs2tee_algorithm(&algo, &hash_algo, function, params, obj)) 203fb279d8bSVesa Jääskeläinen return PKCS11_CKR_FUNCTION_FAILED; 204fb279d8bSVesa Jääskeläinen 205fb279d8bSVesa Jääskeläinen pkcs2tee_mode(&mode, function); 206fb279d8bSVesa Jääskeläinen 207fb279d8bSVesa Jääskeläinen if (hash_algo) { 208fb279d8bSVesa Jääskeläinen pkcs2tee_mode(&hash_mode, PKCS11_FUNCTION_DIGEST); 209fb279d8bSVesa Jääskeläinen 210fb279d8bSVesa Jääskeläinen res = TEE_AllocateOperation(&processing->tee_hash_op_handle, 211fb279d8bSVesa Jääskeläinen hash_algo, hash_mode, 0); 212fb279d8bSVesa Jääskeläinen if (res) { 213fb279d8bSVesa Jääskeläinen EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32, 214fb279d8bSVesa Jääskeläinen hash_algo, hash_mode); 215fb279d8bSVesa Jääskeläinen 216fb279d8bSVesa Jääskeläinen if (res == TEE_ERROR_NOT_SUPPORTED) 217fb279d8bSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_INVALID; 218fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 219fb279d8bSVesa Jääskeläinen } 220fb279d8bSVesa Jääskeläinen processing->tee_hash_algo = hash_algo; 221fb279d8bSVesa Jääskeläinen } 222fb279d8bSVesa Jääskeläinen 223fb279d8bSVesa Jääskeläinen res = TEE_AllocateOperation(&processing->tee_op_handle, 224fb279d8bSVesa Jääskeläinen algo, mode, size); 225fb279d8bSVesa Jääskeläinen if (res) 226fb279d8bSVesa Jääskeläinen EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 227fb279d8bSVesa Jääskeläinen algo, mode, size); 228fb279d8bSVesa Jääskeläinen 229fb279d8bSVesa Jääskeläinen if (res == TEE_ERROR_NOT_SUPPORTED) 230fb279d8bSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_INVALID; 231fb279d8bSVesa Jääskeläinen 232fb279d8bSVesa Jääskeläinen if (res != TEE_SUCCESS && 233fb279d8bSVesa Jääskeläinen processing->tee_hash_op_handle != TEE_HANDLE_NULL) { 234fb279d8bSVesa Jääskeläinen TEE_FreeOperation(session->processing->tee_hash_op_handle); 235fb279d8bSVesa Jääskeläinen processing->tee_hash_op_handle = TEE_HANDLE_NULL; 236fb279d8bSVesa Jääskeläinen processing->tee_hash_algo = 0; 237fb279d8bSVesa Jääskeläinen } 238fb279d8bSVesa Jääskeläinen 239fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 240fb279d8bSVesa Jääskeläinen } 241fb279d8bSVesa Jääskeläinen 242fb279d8bSVesa Jääskeläinen static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 243fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj, 244fb279d8bSVesa Jääskeläinen enum processing_func function) 245fb279d8bSVesa Jääskeläinen { 246fb279d8bSVesa Jääskeläinen TEE_Attribute *tee_attrs = NULL; 247fb279d8bSVesa Jääskeläinen size_t tee_attrs_count = 0; 248fb279d8bSVesa Jääskeläinen size_t object_size = 0; 249fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 250fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 251fb279d8bSVesa Jääskeläinen enum pkcs11_class_id __maybe_unused class = get_class(obj->attributes); 252fb279d8bSVesa Jääskeläinen enum pkcs11_key_type type = get_key_type(obj->attributes); 253fb279d8bSVesa Jääskeläinen 254fb279d8bSVesa Jääskeläinen assert(class == PKCS11_CKO_PUBLIC_KEY || 255fb279d8bSVesa Jääskeläinen class == PKCS11_CKO_PRIVATE_KEY); 256fb279d8bSVesa Jääskeläinen 257fb279d8bSVesa Jääskeläinen if (obj->key_handle != TEE_HANDLE_NULL) { 258fb279d8bSVesa Jääskeläinen switch (type) { 2590442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 2600442c956SVesa Jääskeläinen /* RSA loaded keys can be reused */ 2610442c956SVesa Jääskeläinen assert((obj->key_type == TEE_TYPE_RSA_PUBLIC_KEY && 2620442c956SVesa Jääskeläinen class == PKCS11_CKO_PUBLIC_KEY) || 2630442c956SVesa Jääskeläinen (obj->key_type == TEE_TYPE_RSA_KEYPAIR && 2640442c956SVesa Jääskeläinen class == PKCS11_CKO_PRIVATE_KEY)); 2650442c956SVesa Jääskeläinen goto key_ready; 266fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 267fb279d8bSVesa Jääskeläinen /* Reuse EC TEE key only if already DSA or DH */ 268fb279d8bSVesa Jääskeläinen switch (obj->key_type) { 269fb279d8bSVesa Jääskeläinen case TEE_TYPE_ECDSA_PUBLIC_KEY: 270fb279d8bSVesa Jääskeläinen case TEE_TYPE_ECDSA_KEYPAIR: 271fb279d8bSVesa Jääskeläinen if (function != PKCS11_FUNCTION_DERIVE) 272fb279d8bSVesa Jääskeläinen goto key_ready; 273fb279d8bSVesa Jääskeläinen break; 274fb279d8bSVesa Jääskeläinen default: 275fb279d8bSVesa Jääskeläinen assert(0); 276fb279d8bSVesa Jääskeläinen break; 277fb279d8bSVesa Jääskeläinen } 278fb279d8bSVesa Jääskeläinen break; 279fb279d8bSVesa Jääskeläinen default: 280fb279d8bSVesa Jääskeläinen assert(0); 281fb279d8bSVesa Jääskeläinen break; 282fb279d8bSVesa Jääskeläinen } 283fb279d8bSVesa Jääskeläinen 284fb279d8bSVesa Jääskeläinen TEE_CloseObject(obj->key_handle); 285fb279d8bSVesa Jääskeläinen obj->key_handle = TEE_HANDLE_NULL; 286fb279d8bSVesa Jääskeläinen } 287fb279d8bSVesa Jääskeläinen 288fb279d8bSVesa Jääskeläinen rc = pkcs2tee_key_type(&obj->key_type, obj, function); 289fb279d8bSVesa Jääskeläinen if (rc) 290fb279d8bSVesa Jääskeläinen return rc; 291fb279d8bSVesa Jääskeläinen 292fb279d8bSVesa Jääskeläinen object_size = get_object_key_bit_size(obj); 293fb279d8bSVesa Jääskeläinen if (!object_size) 294fb279d8bSVesa Jääskeläinen return PKCS11_CKR_GENERAL_ERROR; 295fb279d8bSVesa Jääskeläinen 296fb279d8bSVesa Jääskeläinen switch (type) { 2970442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 2980442c956SVesa Jääskeläinen rc = load_tee_rsa_key_attrs(&tee_attrs, &tee_attrs_count, obj); 2990442c956SVesa Jääskeläinen break; 300fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 301fb279d8bSVesa Jääskeläinen rc = load_tee_ec_key_attrs(&tee_attrs, &tee_attrs_count, obj); 302fb279d8bSVesa Jääskeläinen break; 303fb279d8bSVesa Jääskeläinen default: 304fb279d8bSVesa Jääskeläinen break; 305fb279d8bSVesa Jääskeläinen } 306fb279d8bSVesa Jääskeläinen if (rc) 307fb279d8bSVesa Jääskeläinen return rc; 308fb279d8bSVesa Jääskeläinen 309fb279d8bSVesa Jääskeläinen res = TEE_AllocateTransientObject(obj->key_type, object_size, 310fb279d8bSVesa Jääskeläinen &obj->key_handle); 311fb279d8bSVesa Jääskeläinen if (res) { 312fb279d8bSVesa Jääskeläinen DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 313fb279d8bSVesa Jääskeläinen 314fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 315fb279d8bSVesa Jääskeläinen } 316fb279d8bSVesa Jääskeläinen 317fb279d8bSVesa Jääskeläinen res = TEE_PopulateTransientObject(obj->key_handle, 318fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count); 319fb279d8bSVesa Jääskeläinen 320fb279d8bSVesa Jääskeläinen TEE_Free(tee_attrs); 321fb279d8bSVesa Jääskeläinen 322fb279d8bSVesa Jääskeläinen if (res) { 323fb279d8bSVesa Jääskeläinen DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 324fb279d8bSVesa Jääskeläinen 325fb279d8bSVesa Jääskeläinen goto error; 326fb279d8bSVesa Jääskeläinen } 327fb279d8bSVesa Jääskeläinen 328fb279d8bSVesa Jääskeläinen key_ready: 329fb279d8bSVesa Jääskeläinen res = TEE_SetOperationKey(session->processing->tee_op_handle, 330fb279d8bSVesa Jääskeläinen obj->key_handle); 331fb279d8bSVesa Jääskeläinen if (res) { 332fb279d8bSVesa Jääskeläinen DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 333fb279d8bSVesa Jääskeläinen 334fb279d8bSVesa Jääskeläinen goto error; 335fb279d8bSVesa Jääskeläinen } 336fb279d8bSVesa Jääskeläinen 337fb279d8bSVesa Jääskeläinen return PKCS11_CKR_OK; 338fb279d8bSVesa Jääskeläinen 339fb279d8bSVesa Jääskeläinen error: 340fb279d8bSVesa Jääskeläinen TEE_FreeTransientObject(obj->key_handle); 341fb279d8bSVesa Jääskeläinen obj->key_handle = TEE_HANDLE_NULL; 342fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 343fb279d8bSVesa Jääskeläinen } 344fb279d8bSVesa Jääskeläinen 345fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 346d9af50bcSVesa Jääskeläinen init_tee_operation(struct pkcs11_session *session, 347d9af50bcSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 348d9af50bcSVesa Jääskeläinen struct pkcs11_object *obj) 349fb279d8bSVesa Jääskeläinen { 350d9af50bcSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK; 351d9af50bcSVesa Jääskeläinen struct active_processing *proc = session->processing; 352d9af50bcSVesa Jääskeläinen 353d9af50bcSVesa Jääskeläinen switch (proc_params->id) { 354d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 355d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 356d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 357d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 358d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 359d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 360d9af50bcSVesa Jääskeläinen rc = pkcs2tee_proc_params_rsa_pss(proc, proc_params); 361d9af50bcSVesa Jääskeläinen if (rc) 362d9af50bcSVesa Jääskeläinen break; 363d9af50bcSVesa Jääskeläinen 364d9af50bcSVesa Jääskeläinen rc = pkcs2tee_validate_rsa_pss(proc, obj); 365d9af50bcSVesa Jääskeläinen break; 366dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 367dc8c77fcSVesa Jääskeläinen rc = pkcs2tee_proc_params_rsa_oaep(proc, proc_params); 368dc8c77fcSVesa Jääskeläinen break; 369d9af50bcSVesa Jääskeläinen default: 370d9af50bcSVesa Jääskeläinen break; 371d9af50bcSVesa Jääskeläinen } 372d9af50bcSVesa Jääskeläinen 373d9af50bcSVesa Jääskeläinen return rc; 374fb279d8bSVesa Jääskeläinen } 375fb279d8bSVesa Jääskeläinen 376fb279d8bSVesa Jääskeläinen enum pkcs11_rc init_asymm_operation(struct pkcs11_session *session, 377fb279d8bSVesa Jääskeläinen enum processing_func function, 378fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 379fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 380fb279d8bSVesa Jääskeläinen { 381fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 382fb279d8bSVesa Jääskeläinen 383fb279d8bSVesa Jääskeläinen assert(processing_is_tee_asymm(proc_params->id)); 384fb279d8bSVesa Jääskeläinen 385fb279d8bSVesa Jääskeläinen rc = allocate_tee_operation(session, function, proc_params, obj); 386fb279d8bSVesa Jääskeläinen if (rc) 387fb279d8bSVesa Jääskeläinen return rc; 388fb279d8bSVesa Jääskeläinen 389fb279d8bSVesa Jääskeläinen rc = load_tee_key(session, obj, function); 390fb279d8bSVesa Jääskeläinen if (rc) 391fb279d8bSVesa Jääskeläinen return rc; 392fb279d8bSVesa Jääskeläinen 393d9af50bcSVesa Jääskeläinen return init_tee_operation(session, proc_params, obj); 394fb279d8bSVesa Jääskeläinen } 395fb279d8bSVesa Jääskeläinen 396fb279d8bSVesa Jääskeläinen /* 397fb279d8bSVesa Jääskeläinen * step_sym_step - step (update/oneshot/final) on a symmetric crypto operation 398fb279d8bSVesa Jääskeläinen * 399fb279d8bSVesa Jääskeläinen * @session - current session 400fb279d8bSVesa Jääskeläinen * @function - processing function (encrypt, decrypt, sign, ...) 401fb279d8bSVesa Jääskeläinen * @step - step ID in the processing (oneshot, update, final) 402fb279d8bSVesa Jääskeläinen * @ptypes - invocation parameter types 403fb279d8bSVesa Jääskeläinen * @params - invocation parameter references 404fb279d8bSVesa Jääskeläinen */ 405fb279d8bSVesa Jääskeläinen enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session, 406fb279d8bSVesa Jääskeläinen enum processing_func function, 407fb279d8bSVesa Jääskeläinen enum processing_step step, 408fb279d8bSVesa Jääskeläinen uint32_t ptypes, TEE_Param *params) 409fb279d8bSVesa Jääskeläinen { 410fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 411fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 412fb279d8bSVesa Jääskeläinen void *in_buf = NULL; 413fb279d8bSVesa Jääskeläinen void *in2_buf = NULL; 414fb279d8bSVesa Jääskeläinen void *out_buf = NULL; 415fb279d8bSVesa Jääskeläinen void *hash_buf = NULL; 416fb279d8bSVesa Jääskeläinen uint32_t in_size = 0; 417fb279d8bSVesa Jääskeläinen uint32_t in2_size = 0; 418fb279d8bSVesa Jääskeläinen uint32_t out_size = 0; 419fb279d8bSVesa Jääskeläinen uint32_t hash_size = 0; 420fb279d8bSVesa Jääskeläinen TEE_Attribute *tee_attrs = NULL; 421fb279d8bSVesa Jääskeläinen size_t tee_attrs_count = 0; 422fb279d8bSVesa Jääskeläinen bool output_data = false; 423fb279d8bSVesa Jääskeläinen struct active_processing *proc = session->processing; 424dc8c77fcSVesa Jääskeläinen struct rsa_oaep_processing_ctx *rsa_oaep_ctx = NULL; 425d9af50bcSVesa Jääskeläinen struct rsa_pss_processing_ctx *rsa_pss_ctx = NULL; 426fb279d8bSVesa Jääskeläinen size_t sz = 0; 427fb279d8bSVesa Jääskeläinen 428fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 429fb279d8bSVesa Jääskeläinen in_buf = params[1].memref.buffer; 430fb279d8bSVesa Jääskeläinen in_size = params[1].memref.size; 431fb279d8bSVesa Jääskeläinen if (in_size && !in_buf) 432fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 433fb279d8bSVesa Jääskeläinen } 434fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 435fb279d8bSVesa Jääskeläinen in2_buf = params[2].memref.buffer; 436fb279d8bSVesa Jääskeläinen in2_size = params[2].memref.size; 437fb279d8bSVesa Jääskeläinen if (in2_size && !in2_buf) 438fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 439fb279d8bSVesa Jääskeläinen } 440fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 441fb279d8bSVesa Jääskeläinen out_buf = params[2].memref.buffer; 442fb279d8bSVesa Jääskeläinen out_size = params[2].memref.size; 443fb279d8bSVesa Jääskeläinen if (out_size && !out_buf) 444fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 445fb279d8bSVesa Jääskeläinen } 446fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 447fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 448fb279d8bSVesa Jääskeläinen 449fb279d8bSVesa Jääskeläinen switch (step) { 450fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_ONESHOT: 451fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE: 452fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_FINAL: 453fb279d8bSVesa Jääskeläinen break; 454fb279d8bSVesa Jääskeläinen default: 455fb279d8bSVesa Jääskeläinen return PKCS11_CKR_GENERAL_ERROR; 456fb279d8bSVesa Jääskeläinen } 457fb279d8bSVesa Jääskeläinen 458d9af50bcSVesa Jääskeläinen /* TEE attribute(s) required by the operation */ 459d9af50bcSVesa Jääskeläinen switch (proc->mecha_type) { 460d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 461d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 462d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 463d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 464d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 465d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 466d9af50bcSVesa Jääskeläinen tee_attrs = TEE_Malloc(sizeof(TEE_Attribute), 467d9af50bcSVesa Jääskeläinen TEE_USER_MEM_HINT_NO_FILL_ZERO); 468d9af50bcSVesa Jääskeläinen if (!tee_attrs) { 469d9af50bcSVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY; 470d9af50bcSVesa Jääskeläinen goto out; 471d9af50bcSVesa Jääskeläinen } 472d9af50bcSVesa Jääskeläinen 473d9af50bcSVesa Jääskeläinen rsa_pss_ctx = proc->extra_ctx; 474d9af50bcSVesa Jääskeläinen 475d9af50bcSVesa Jääskeläinen TEE_InitValueAttribute(&tee_attrs[tee_attrs_count], 476d9af50bcSVesa Jääskeläinen TEE_ATTR_RSA_PSS_SALT_LENGTH, 477d9af50bcSVesa Jääskeläinen rsa_pss_ctx->salt_len, 0); 478d9af50bcSVesa Jääskeläinen tee_attrs_count++; 479d9af50bcSVesa Jääskeläinen break; 480dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 481dc8c77fcSVesa Jääskeläinen rsa_oaep_ctx = proc->extra_ctx; 482dc8c77fcSVesa Jääskeläinen 483dc8c77fcSVesa Jääskeläinen if (!rsa_oaep_ctx->source_data_len) 484dc8c77fcSVesa Jääskeläinen break; 485dc8c77fcSVesa Jääskeläinen 486dc8c77fcSVesa Jääskeläinen tee_attrs = TEE_Malloc(sizeof(TEE_Attribute), 487dc8c77fcSVesa Jääskeläinen TEE_USER_MEM_HINT_NO_FILL_ZERO); 488dc8c77fcSVesa Jääskeläinen if (!tee_attrs) { 489dc8c77fcSVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY; 490dc8c77fcSVesa Jääskeläinen goto out; 491dc8c77fcSVesa Jääskeläinen } 492dc8c77fcSVesa Jääskeläinen 493dc8c77fcSVesa Jääskeläinen TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 494dc8c77fcSVesa Jääskeläinen TEE_ATTR_RSA_OAEP_LABEL, 495dc8c77fcSVesa Jääskeläinen rsa_oaep_ctx->source_data, 496dc8c77fcSVesa Jääskeläinen rsa_oaep_ctx->source_data_len); 497dc8c77fcSVesa Jääskeläinen tee_attrs_count++; 498dc8c77fcSVesa Jääskeläinen break; 499d9af50bcSVesa Jääskeläinen default: 500d9af50bcSVesa Jääskeläinen break; 501d9af50bcSVesa Jääskeläinen } 502d9af50bcSVesa Jääskeläinen 503fb279d8bSVesa Jääskeläinen /* 504fb279d8bSVesa Jääskeläinen * Handle multi stage update step for mechas needing hash 505fb279d8bSVesa Jääskeläinen * calculation 506fb279d8bSVesa Jääskeläinen */ 507fb279d8bSVesa Jääskeläinen if (step == PKCS11_FUNC_STEP_UPDATE) { 508fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 509fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 510fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 511fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 512fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 513fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 5140442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 5150442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 5160442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 5170442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 5180442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 5190442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 520d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 521d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 522d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 523d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 524d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 525fb279d8bSVesa Jääskeläinen assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL); 526fb279d8bSVesa Jääskeläinen 527fb279d8bSVesa Jääskeläinen TEE_DigestUpdate(proc->tee_hash_op_handle, in_buf, 528fb279d8bSVesa Jääskeläinen in_size); 529*9df68186SEtienne Carriere rc = PKCS11_CKR_OK; 530fb279d8bSVesa Jääskeläinen break; 531fb279d8bSVesa Jääskeläinen default: 532fb279d8bSVesa Jääskeläinen /* 533fb279d8bSVesa Jääskeläinen * Other mechanism do not expect multi stage 534fb279d8bSVesa Jääskeläinen * operation 535fb279d8bSVesa Jääskeläinen */ 536fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_GENERAL_ERROR; 537fb279d8bSVesa Jääskeläinen break; 538fb279d8bSVesa Jääskeläinen } 539fb279d8bSVesa Jääskeläinen 540fb279d8bSVesa Jääskeläinen goto out; 541fb279d8bSVesa Jääskeläinen } 542fb279d8bSVesa Jääskeläinen 543fb279d8bSVesa Jääskeläinen /* 544fb279d8bSVesa Jääskeläinen * Handle multi stage one shot and final steps for mechas needing hash 545fb279d8bSVesa Jääskeläinen * calculation 546fb279d8bSVesa Jääskeläinen */ 547fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 548fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 549fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 550fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 551fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 552fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 5530442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 5540442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 5550442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 5560442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 5570442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 5580442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 559d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 560d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 561d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 562d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 563d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 564fb279d8bSVesa Jääskeläinen assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL); 565fb279d8bSVesa Jääskeläinen 566fb279d8bSVesa Jääskeläinen hash_size = TEE_ALG_GET_DIGEST_SIZE(proc->tee_hash_algo); 567fb279d8bSVesa Jääskeläinen hash_buf = TEE_Malloc(hash_size, 0); 568fb279d8bSVesa Jääskeläinen if (!hash_buf) 569fb279d8bSVesa Jääskeläinen return PKCS11_CKR_DEVICE_MEMORY; 570fb279d8bSVesa Jääskeläinen 571fb279d8bSVesa Jääskeläinen res = TEE_DigestDoFinal(proc->tee_hash_op_handle, 572fb279d8bSVesa Jääskeläinen in_buf, in_size, hash_buf, 573fb279d8bSVesa Jääskeläinen &hash_size); 574fb279d8bSVesa Jääskeläinen 575fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 576fb279d8bSVesa Jääskeläinen if (rc != PKCS11_CKR_OK) 577fb279d8bSVesa Jääskeläinen goto out; 578fb279d8bSVesa Jääskeläinen 579fb279d8bSVesa Jääskeläinen break; 580fb279d8bSVesa Jääskeläinen default: 581fb279d8bSVesa Jääskeläinen break; 582fb279d8bSVesa Jääskeläinen } 583fb279d8bSVesa Jääskeläinen 584fb279d8bSVesa Jääskeläinen /* 585fb279d8bSVesa Jääskeläinen * Finalize either provided hash or calculated hash with signing 586fb279d8bSVesa Jääskeläinen * operation 587fb279d8bSVesa Jääskeläinen */ 588fb279d8bSVesa Jääskeläinen 589fb279d8bSVesa Jääskeläinen /* First determine amount of bytes for signing operation */ 590fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 591fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 592fb279d8bSVesa Jääskeläinen sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle); 593fb279d8bSVesa Jääskeläinen if (!in_size || !sz) { 594fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 595fb279d8bSVesa Jääskeläinen goto out; 596fb279d8bSVesa Jääskeläinen } 597fb279d8bSVesa Jääskeläinen 598fb279d8bSVesa Jääskeläinen /* 599fb279d8bSVesa Jääskeläinen * Note 3) Input the entire raw digest. Internally, this will 600fb279d8bSVesa Jääskeläinen * be truncated to the appropriate number of bits. 601fb279d8bSVesa Jääskeläinen */ 602fb279d8bSVesa Jääskeläinen if (in_size > sz) 603fb279d8bSVesa Jääskeläinen in_size = sz; 604fb279d8bSVesa Jääskeläinen 605fb279d8bSVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && in2_size != 2 * sz) { 606fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 607fb279d8bSVesa Jääskeläinen goto out; 608fb279d8bSVesa Jääskeläinen } 609fb279d8bSVesa Jääskeläinen break; 610fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 611fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 612fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 613fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 614fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 615fb279d8bSVesa Jääskeläinen /* Get key size in bytes */ 616fb279d8bSVesa Jääskeläinen sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle); 617fb279d8bSVesa Jääskeläinen if (!sz) { 618fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 619fb279d8bSVesa Jääskeläinen goto out; 620fb279d8bSVesa Jääskeläinen } 621fb279d8bSVesa Jääskeläinen 622fb279d8bSVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && 623fb279d8bSVesa Jääskeläinen in2_size != 2 * sz) { 624fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 625fb279d8bSVesa Jääskeläinen goto out; 626fb279d8bSVesa Jääskeläinen } 627fb279d8bSVesa Jääskeläinen break; 6280442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 6290442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 6300442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 6310442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 6320442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 6330442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 6340442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 635d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 636d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 637d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 638d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 639d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 640d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 6410442c956SVesa Jääskeläinen /* Get key size in bytes */ 6420442c956SVesa Jääskeläinen sz = rsa_get_input_max_byte_size(proc->tee_op_handle); 6430442c956SVesa Jääskeläinen if (!sz) { 6440442c956SVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 6450442c956SVesa Jääskeläinen goto out; 6460442c956SVesa Jääskeläinen } 6470442c956SVesa Jääskeläinen 6480442c956SVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && in2_size != sz) { 6490442c956SVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 6500442c956SVesa Jääskeläinen goto out; 6510442c956SVesa Jääskeläinen } 6520442c956SVesa Jääskeläinen break; 653fb279d8bSVesa Jääskeläinen default: 654fb279d8bSVesa Jääskeläinen break; 655fb279d8bSVesa Jääskeläinen } 656fb279d8bSVesa Jääskeläinen 657fb279d8bSVesa Jääskeläinen /* Next perform actual signing operation */ 658fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 659fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 6600442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 661dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 662d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 663fb279d8bSVesa Jääskeläinen /* For operations using provided input data */ 664fb279d8bSVesa Jääskeläinen switch (function) { 665fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_ENCRYPT: 666fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricEncrypt(proc->tee_op_handle, 667fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count, 668fb279d8bSVesa Jääskeläinen in_buf, in_size, 669fb279d8bSVesa Jääskeläinen out_buf, &out_size); 670fb279d8bSVesa Jääskeläinen output_data = true; 671fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 6726a6299fbSVesa Jääskeläinen if (rc == PKCS11_CKR_ARGUMENTS_BAD) 6736a6299fbSVesa Jääskeläinen rc = PKCS11_CKR_DATA_LEN_RANGE; 674fb279d8bSVesa Jääskeläinen break; 675fb279d8bSVesa Jääskeläinen 676fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_DECRYPT: 677fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricDecrypt(proc->tee_op_handle, 678fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count, 679fb279d8bSVesa Jääskeläinen in_buf, in_size, 680fb279d8bSVesa Jääskeläinen out_buf, &out_size); 681fb279d8bSVesa Jääskeläinen output_data = true; 682fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 683f27310a5SVesa Jääskeläinen if (rc == PKCS11_CKR_ARGUMENTS_BAD) 684f27310a5SVesa Jääskeläinen rc = PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 685fb279d8bSVesa Jääskeläinen break; 686fb279d8bSVesa Jääskeläinen 687fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_SIGN: 688fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricSignDigest(proc->tee_op_handle, 689fb279d8bSVesa Jääskeläinen tee_attrs, 690fb279d8bSVesa Jääskeläinen tee_attrs_count, 691fb279d8bSVesa Jääskeläinen in_buf, in_size, 692fb279d8bSVesa Jääskeläinen out_buf, &out_size); 693fb279d8bSVesa Jääskeläinen output_data = true; 694fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 695fb279d8bSVesa Jääskeläinen break; 696fb279d8bSVesa Jääskeläinen 697fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_VERIFY: 698fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle, 699fb279d8bSVesa Jääskeläinen tee_attrs, 700fb279d8bSVesa Jääskeläinen tee_attrs_count, 701fb279d8bSVesa Jääskeläinen in_buf, in_size, 702fb279d8bSVesa Jääskeläinen in2_buf, in2_size); 703fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 704fb279d8bSVesa Jääskeläinen break; 705fb279d8bSVesa Jääskeläinen 706fb279d8bSVesa Jääskeläinen default: 707fb279d8bSVesa Jääskeläinen TEE_Panic(function); 708fb279d8bSVesa Jääskeläinen break; 709fb279d8bSVesa Jääskeläinen } 710fb279d8bSVesa Jääskeläinen break; 711fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 712fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 713fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 714fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 715fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 7160442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 7170442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 7180442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 7190442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 7200442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 7210442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 722d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 723d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 724d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 725d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 726d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 727fb279d8bSVesa Jääskeläinen /* For operations having hash operation use calculated hash */ 728fb279d8bSVesa Jääskeläinen switch (function) { 729fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_SIGN: 730fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricSignDigest(proc->tee_op_handle, 731fb279d8bSVesa Jääskeläinen tee_attrs, 732fb279d8bSVesa Jääskeläinen tee_attrs_count, 733fb279d8bSVesa Jääskeläinen hash_buf, hash_size, 734fb279d8bSVesa Jääskeläinen out_buf, &out_size); 735fb279d8bSVesa Jääskeläinen output_data = true; 736fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 737fb279d8bSVesa Jääskeläinen break; 738fb279d8bSVesa Jääskeläinen 739fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_VERIFY: 740fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle, 741fb279d8bSVesa Jääskeläinen tee_attrs, 742fb279d8bSVesa Jääskeläinen tee_attrs_count, 743fb279d8bSVesa Jääskeläinen hash_buf, hash_size, 744fb279d8bSVesa Jääskeläinen in2_buf, in2_size); 745fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 746fb279d8bSVesa Jääskeläinen break; 747fb279d8bSVesa Jääskeläinen 748fb279d8bSVesa Jääskeläinen default: 749fb279d8bSVesa Jääskeläinen TEE_Panic(function); 750fb279d8bSVesa Jääskeläinen break; 751fb279d8bSVesa Jääskeläinen } 752fb279d8bSVesa Jääskeläinen break; 753fb279d8bSVesa Jääskeläinen default: 754fb279d8bSVesa Jääskeläinen TEE_Panic(proc->mecha_type); 755fb279d8bSVesa Jääskeläinen break; 756fb279d8bSVesa Jääskeläinen } 757fb279d8bSVesa Jääskeläinen 758fb279d8bSVesa Jääskeläinen out: 759fb279d8bSVesa Jääskeläinen if (output_data && 760fb279d8bSVesa Jääskeläinen (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 761fb279d8bSVesa Jääskeläinen switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 762fb279d8bSVesa Jääskeläinen case TEE_PARAM_TYPE_MEMREF_OUTPUT: 763fb279d8bSVesa Jääskeläinen case TEE_PARAM_TYPE_MEMREF_INOUT: 764fb279d8bSVesa Jääskeläinen params[2].memref.size = out_size; 765fb279d8bSVesa Jääskeläinen break; 766fb279d8bSVesa Jääskeläinen default: 767fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_GENERAL_ERROR; 768fb279d8bSVesa Jääskeläinen break; 769fb279d8bSVesa Jääskeläinen } 770fb279d8bSVesa Jääskeläinen } 771fb279d8bSVesa Jääskeläinen 772fb279d8bSVesa Jääskeläinen TEE_Free(hash_buf); 773fb279d8bSVesa Jääskeläinen TEE_Free(tee_attrs); 774fb279d8bSVesa Jääskeläinen 775fb279d8bSVesa Jääskeläinen return rc; 776fb279d8bSVesa Jääskeläinen } 777