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) { 21*0442c956SVesa Jääskeläinen /* RSA flavors */ 22*0442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 23*0442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 24*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 25*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 26*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 27*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 28*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 29fb279d8bSVesa Jääskeläinen /* EC flavors */ 30fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 31fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 32fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 33fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 34fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 35fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 36fb279d8bSVesa Jääskeläinen return true; 37fb279d8bSVesa Jääskeläinen default: 38fb279d8bSVesa Jääskeläinen return false; 39fb279d8bSVesa Jääskeläinen } 40fb279d8bSVesa Jääskeläinen } 41fb279d8bSVesa Jääskeläinen 42fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 43fb279d8bSVesa Jääskeläinen pkcs2tee_algorithm(uint32_t *tee_id, uint32_t *tee_hash_id, 44fb279d8bSVesa Jääskeläinen enum processing_func function __unused, 45fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 46fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 47fb279d8bSVesa Jääskeläinen { 48fb279d8bSVesa Jääskeläinen static const struct { 49fb279d8bSVesa Jääskeläinen enum pkcs11_mechanism_id mech_id; 50fb279d8bSVesa Jääskeläinen uint32_t tee_id; 51fb279d8bSVesa Jääskeläinen uint32_t tee_hash_id; 52fb279d8bSVesa Jääskeläinen } pkcs2tee_algo[] = { 53*0442c956SVesa Jääskeläinen /* RSA flavors */ 54*0442c956SVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS, TEE_ALG_RSAES_PKCS1_V1_5, 0 }, 55*0442c956SVesa Jääskeläinen { PKCS11_CKM_MD5_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_MD5, 56*0442c956SVesa Jääskeläinen TEE_ALG_MD5 }, 57*0442c956SVesa Jääskeläinen { PKCS11_CKM_SHA1_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA1, 58*0442c956SVesa Jääskeläinen TEE_ALG_SHA1 }, 59*0442c956SVesa Jääskeläinen { PKCS11_CKM_SHA224_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA224, 60*0442c956SVesa Jääskeläinen TEE_ALG_SHA224 }, 61*0442c956SVesa Jääskeläinen { PKCS11_CKM_SHA256_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA256, 62*0442c956SVesa Jääskeläinen TEE_ALG_SHA256 }, 63*0442c956SVesa Jääskeläinen { PKCS11_CKM_SHA384_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA384, 64*0442c956SVesa Jääskeläinen TEE_ALG_SHA384 }, 65*0442c956SVesa Jääskeläinen { PKCS11_CKM_SHA512_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA512, 66*0442c956SVesa Jääskeläinen TEE_ALG_SHA512 }, 67fb279d8bSVesa Jääskeläinen /* EC flavors (Must find key size from the object) */ 68fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA, 1, 0 }, 69fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA1, 1, TEE_ALG_SHA1 }, 70fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA224, 1, TEE_ALG_SHA224 }, 71fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA256, 1, TEE_ALG_SHA256 }, 72fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA384, 1, TEE_ALG_SHA384 }, 73fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA512, 1, TEE_ALG_SHA512 }, 74fb279d8bSVesa Jääskeläinen }; 75fb279d8bSVesa Jääskeläinen size_t n = 0; 76fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 77fb279d8bSVesa Jääskeläinen 78fb279d8bSVesa Jääskeläinen for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) { 79fb279d8bSVesa Jääskeläinen if (pkcs2tee_algo[n].mech_id == proc_params->id) { 80fb279d8bSVesa Jääskeläinen *tee_id = pkcs2tee_algo[n].tee_id; 81fb279d8bSVesa Jääskeläinen *tee_hash_id = pkcs2tee_algo[n].tee_hash_id; 82fb279d8bSVesa Jääskeläinen break; 83fb279d8bSVesa Jääskeläinen } 84fb279d8bSVesa Jääskeläinen } 85fb279d8bSVesa Jääskeläinen 86fb279d8bSVesa Jääskeläinen if (n == ARRAY_SIZE(pkcs2tee_algo)) 87fb279d8bSVesa Jääskeläinen return PKCS11_RV_NOT_IMPLEMENTED; 88fb279d8bSVesa Jääskeläinen 89fb279d8bSVesa Jääskeläinen switch (proc_params->id) { 90fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 91fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 92fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 93fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 94fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 95fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 96fb279d8bSVesa Jääskeläinen rc = pkcs2tee_algo_ecdsa(tee_id, proc_params, obj); 97fb279d8bSVesa Jääskeläinen break; 98fb279d8bSVesa Jääskeläinen default: 99fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_OK; 100fb279d8bSVesa Jääskeläinen break; 101fb279d8bSVesa Jääskeläinen } 102fb279d8bSVesa Jääskeläinen 103*0442c956SVesa Jääskeläinen /* 104*0442c956SVesa Jääskeläinen * PKCS#11 uses single mechanism CKM_RSA_PKCS for both ciphering and 105*0442c956SVesa Jääskeläinen * authentication whereas GPD TEE expects TEE_ALG_RSAES_PKCS1_V1_5 for 106*0442c956SVesa Jääskeläinen * ciphering and TEE_ALG_RSASSA_PKCS1_V1_5 for authentication. 107*0442c956SVesa Jääskeläinen */ 108*0442c956SVesa Jääskeläinen if (*tee_id == TEE_ALG_RSAES_PKCS1_V1_5 && 109*0442c956SVesa Jääskeläinen (function == PKCS11_FUNCTION_SIGN || 110*0442c956SVesa Jääskeläinen function == PKCS11_FUNCTION_VERIFY)) 111*0442c956SVesa Jääskeläinen *tee_id = TEE_ALG_RSASSA_PKCS1_V1_5; 112*0442c956SVesa Jääskeläinen 113fb279d8bSVesa Jääskeläinen return rc; 114fb279d8bSVesa Jääskeläinen } 115fb279d8bSVesa Jääskeläinen 116fb279d8bSVesa Jääskeläinen static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type, 117fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj, 118fb279d8bSVesa Jääskeläinen enum processing_func function) 119fb279d8bSVesa Jääskeläinen { 120fb279d8bSVesa Jääskeläinen enum pkcs11_class_id class = get_class(obj->attributes); 121fb279d8bSVesa Jääskeläinen enum pkcs11_key_type type = get_key_type(obj->attributes); 122fb279d8bSVesa Jääskeläinen 123fb279d8bSVesa Jääskeläinen switch (class) { 124fb279d8bSVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 125fb279d8bSVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 126fb279d8bSVesa Jääskeläinen break; 127fb279d8bSVesa Jääskeläinen default: 128fb279d8bSVesa Jääskeläinen TEE_Panic(class); 129fb279d8bSVesa Jääskeläinen break; 130fb279d8bSVesa Jääskeläinen } 131fb279d8bSVesa Jääskeläinen 132fb279d8bSVesa Jääskeläinen switch (type) { 133fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 134fb279d8bSVesa Jääskeläinen assert(function != PKCS11_FUNCTION_DERIVE); 135fb279d8bSVesa Jääskeläinen 136fb279d8bSVesa Jääskeläinen if (class == PKCS11_CKO_PRIVATE_KEY) 137fb279d8bSVesa Jääskeläinen *tee_type = TEE_TYPE_ECDSA_KEYPAIR; 138fb279d8bSVesa Jääskeläinen else 139fb279d8bSVesa Jääskeläinen *tee_type = TEE_TYPE_ECDSA_PUBLIC_KEY; 140fb279d8bSVesa Jääskeläinen break; 141*0442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 142*0442c956SVesa Jääskeläinen if (class == PKCS11_CKO_PRIVATE_KEY) 143*0442c956SVesa Jääskeläinen *tee_type = TEE_TYPE_RSA_KEYPAIR; 144*0442c956SVesa Jääskeläinen else 145*0442c956SVesa Jääskeläinen *tee_type = TEE_TYPE_RSA_PUBLIC_KEY; 146*0442c956SVesa Jääskeläinen break; 147fb279d8bSVesa Jääskeläinen default: 148fb279d8bSVesa Jääskeläinen TEE_Panic(type); 149fb279d8bSVesa Jääskeläinen break; 150fb279d8bSVesa Jääskeläinen } 151fb279d8bSVesa Jääskeläinen 152fb279d8bSVesa Jääskeläinen return PKCS11_CKR_OK; 153fb279d8bSVesa Jääskeläinen } 154fb279d8bSVesa Jääskeläinen 155fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 156fb279d8bSVesa Jääskeläinen allocate_tee_operation(struct pkcs11_session *session, 157fb279d8bSVesa Jääskeläinen enum processing_func function, 158fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *params, 159fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 160fb279d8bSVesa Jääskeläinen { 161fb279d8bSVesa Jääskeläinen uint32_t size = (uint32_t)get_object_key_bit_size(obj); 162fb279d8bSVesa Jääskeläinen uint32_t algo = 0; 163fb279d8bSVesa Jääskeläinen uint32_t hash_algo = 0; 164fb279d8bSVesa Jääskeläinen uint32_t mode = 0; 165fb279d8bSVesa Jääskeläinen uint32_t hash_mode = 0; 166fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 167fb279d8bSVesa Jääskeläinen struct active_processing *processing = session->processing; 168fb279d8bSVesa Jääskeläinen 169fb279d8bSVesa Jääskeläinen assert(processing->tee_op_handle == TEE_HANDLE_NULL); 170fb279d8bSVesa Jääskeläinen assert(processing->tee_hash_op_handle == TEE_HANDLE_NULL); 171fb279d8bSVesa Jääskeläinen 172fb279d8bSVesa Jääskeläinen if (pkcs2tee_algorithm(&algo, &hash_algo, function, params, obj)) 173fb279d8bSVesa Jääskeläinen return PKCS11_CKR_FUNCTION_FAILED; 174fb279d8bSVesa Jääskeläinen 175fb279d8bSVesa Jääskeläinen pkcs2tee_mode(&mode, function); 176fb279d8bSVesa Jääskeläinen 177fb279d8bSVesa Jääskeläinen if (hash_algo) { 178fb279d8bSVesa Jääskeläinen pkcs2tee_mode(&hash_mode, PKCS11_FUNCTION_DIGEST); 179fb279d8bSVesa Jääskeläinen 180fb279d8bSVesa Jääskeläinen res = TEE_AllocateOperation(&processing->tee_hash_op_handle, 181fb279d8bSVesa Jääskeläinen hash_algo, hash_mode, 0); 182fb279d8bSVesa Jääskeläinen if (res) { 183fb279d8bSVesa Jääskeläinen EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32, 184fb279d8bSVesa Jääskeläinen hash_algo, hash_mode); 185fb279d8bSVesa Jääskeläinen 186fb279d8bSVesa Jääskeläinen if (res == TEE_ERROR_NOT_SUPPORTED) 187fb279d8bSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_INVALID; 188fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 189fb279d8bSVesa Jääskeläinen } 190fb279d8bSVesa Jääskeläinen processing->tee_hash_algo = hash_algo; 191fb279d8bSVesa Jääskeläinen } 192fb279d8bSVesa Jääskeläinen 193fb279d8bSVesa Jääskeläinen res = TEE_AllocateOperation(&processing->tee_op_handle, 194fb279d8bSVesa Jääskeläinen algo, mode, size); 195fb279d8bSVesa Jääskeläinen if (res) 196fb279d8bSVesa Jääskeläinen EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 197fb279d8bSVesa Jääskeläinen algo, mode, size); 198fb279d8bSVesa Jääskeläinen 199fb279d8bSVesa Jääskeläinen if (res == TEE_ERROR_NOT_SUPPORTED) 200fb279d8bSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_INVALID; 201fb279d8bSVesa Jääskeläinen 202fb279d8bSVesa Jääskeläinen if (res != TEE_SUCCESS && 203fb279d8bSVesa Jääskeläinen processing->tee_hash_op_handle != TEE_HANDLE_NULL) { 204fb279d8bSVesa Jääskeläinen TEE_FreeOperation(session->processing->tee_hash_op_handle); 205fb279d8bSVesa Jääskeläinen processing->tee_hash_op_handle = TEE_HANDLE_NULL; 206fb279d8bSVesa Jääskeläinen processing->tee_hash_algo = 0; 207fb279d8bSVesa Jääskeläinen } 208fb279d8bSVesa Jääskeläinen 209fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 210fb279d8bSVesa Jääskeläinen } 211fb279d8bSVesa Jääskeläinen 212fb279d8bSVesa Jääskeläinen static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 213fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj, 214fb279d8bSVesa Jääskeläinen enum processing_func function) 215fb279d8bSVesa Jääskeläinen { 216fb279d8bSVesa Jääskeläinen TEE_Attribute *tee_attrs = NULL; 217fb279d8bSVesa Jääskeläinen size_t tee_attrs_count = 0; 218fb279d8bSVesa Jääskeläinen size_t object_size = 0; 219fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 220fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 221fb279d8bSVesa Jääskeläinen enum pkcs11_class_id __maybe_unused class = get_class(obj->attributes); 222fb279d8bSVesa Jääskeläinen enum pkcs11_key_type type = get_key_type(obj->attributes); 223fb279d8bSVesa Jääskeläinen 224fb279d8bSVesa Jääskeläinen assert(class == PKCS11_CKO_PUBLIC_KEY || 225fb279d8bSVesa Jääskeläinen class == PKCS11_CKO_PRIVATE_KEY); 226fb279d8bSVesa Jääskeläinen 227fb279d8bSVesa Jääskeläinen if (obj->key_handle != TEE_HANDLE_NULL) { 228fb279d8bSVesa Jääskeläinen switch (type) { 229*0442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 230*0442c956SVesa Jääskeläinen /* RSA loaded keys can be reused */ 231*0442c956SVesa Jääskeläinen assert((obj->key_type == TEE_TYPE_RSA_PUBLIC_KEY && 232*0442c956SVesa Jääskeläinen class == PKCS11_CKO_PUBLIC_KEY) || 233*0442c956SVesa Jääskeläinen (obj->key_type == TEE_TYPE_RSA_KEYPAIR && 234*0442c956SVesa Jääskeläinen class == PKCS11_CKO_PRIVATE_KEY)); 235*0442c956SVesa Jääskeläinen goto key_ready; 236fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 237fb279d8bSVesa Jääskeläinen /* Reuse EC TEE key only if already DSA or DH */ 238fb279d8bSVesa Jääskeläinen switch (obj->key_type) { 239fb279d8bSVesa Jääskeläinen case TEE_TYPE_ECDSA_PUBLIC_KEY: 240fb279d8bSVesa Jääskeläinen case TEE_TYPE_ECDSA_KEYPAIR: 241fb279d8bSVesa Jääskeläinen if (function != PKCS11_FUNCTION_DERIVE) 242fb279d8bSVesa Jääskeläinen goto key_ready; 243fb279d8bSVesa Jääskeläinen break; 244fb279d8bSVesa Jääskeläinen default: 245fb279d8bSVesa Jääskeläinen assert(0); 246fb279d8bSVesa Jääskeläinen break; 247fb279d8bSVesa Jääskeläinen } 248fb279d8bSVesa Jääskeläinen break; 249fb279d8bSVesa Jääskeläinen default: 250fb279d8bSVesa Jääskeläinen assert(0); 251fb279d8bSVesa Jääskeläinen break; 252fb279d8bSVesa Jääskeläinen } 253fb279d8bSVesa Jääskeläinen 254fb279d8bSVesa Jääskeläinen TEE_CloseObject(obj->key_handle); 255fb279d8bSVesa Jääskeläinen obj->key_handle = TEE_HANDLE_NULL; 256fb279d8bSVesa Jääskeläinen } 257fb279d8bSVesa Jääskeläinen 258fb279d8bSVesa Jääskeläinen rc = pkcs2tee_key_type(&obj->key_type, obj, function); 259fb279d8bSVesa Jääskeläinen if (rc) 260fb279d8bSVesa Jääskeläinen return rc; 261fb279d8bSVesa Jääskeläinen 262fb279d8bSVesa Jääskeläinen object_size = get_object_key_bit_size(obj); 263fb279d8bSVesa Jääskeläinen if (!object_size) 264fb279d8bSVesa Jääskeläinen return PKCS11_CKR_GENERAL_ERROR; 265fb279d8bSVesa Jääskeläinen 266fb279d8bSVesa Jääskeläinen switch (type) { 267*0442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 268*0442c956SVesa Jääskeläinen rc = load_tee_rsa_key_attrs(&tee_attrs, &tee_attrs_count, obj); 269*0442c956SVesa Jääskeläinen break; 270fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 271fb279d8bSVesa Jääskeläinen rc = load_tee_ec_key_attrs(&tee_attrs, &tee_attrs_count, obj); 272fb279d8bSVesa Jääskeläinen break; 273fb279d8bSVesa Jääskeläinen default: 274fb279d8bSVesa Jääskeläinen break; 275fb279d8bSVesa Jääskeläinen } 276fb279d8bSVesa Jääskeläinen if (rc) 277fb279d8bSVesa Jääskeläinen return rc; 278fb279d8bSVesa Jääskeläinen 279fb279d8bSVesa Jääskeläinen res = TEE_AllocateTransientObject(obj->key_type, object_size, 280fb279d8bSVesa Jääskeläinen &obj->key_handle); 281fb279d8bSVesa Jääskeläinen if (res) { 282fb279d8bSVesa Jääskeläinen DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 283fb279d8bSVesa Jääskeläinen 284fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 285fb279d8bSVesa Jääskeläinen } 286fb279d8bSVesa Jääskeläinen 287fb279d8bSVesa Jääskeläinen res = TEE_PopulateTransientObject(obj->key_handle, 288fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count); 289fb279d8bSVesa Jääskeläinen 290fb279d8bSVesa Jääskeläinen TEE_Free(tee_attrs); 291fb279d8bSVesa Jääskeläinen 292fb279d8bSVesa Jääskeläinen if (res) { 293fb279d8bSVesa Jääskeläinen DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 294fb279d8bSVesa Jääskeläinen 295fb279d8bSVesa Jääskeläinen goto error; 296fb279d8bSVesa Jääskeläinen } 297fb279d8bSVesa Jääskeläinen 298fb279d8bSVesa Jääskeläinen key_ready: 299fb279d8bSVesa Jääskeläinen res = TEE_SetOperationKey(session->processing->tee_op_handle, 300fb279d8bSVesa Jääskeläinen obj->key_handle); 301fb279d8bSVesa Jääskeläinen if (res) { 302fb279d8bSVesa Jääskeläinen DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 303fb279d8bSVesa Jääskeläinen 304fb279d8bSVesa Jääskeläinen goto error; 305fb279d8bSVesa Jääskeläinen } 306fb279d8bSVesa Jääskeläinen 307fb279d8bSVesa Jääskeläinen return PKCS11_CKR_OK; 308fb279d8bSVesa Jääskeläinen 309fb279d8bSVesa Jääskeläinen error: 310fb279d8bSVesa Jääskeläinen TEE_FreeTransientObject(obj->key_handle); 311fb279d8bSVesa Jääskeläinen obj->key_handle = TEE_HANDLE_NULL; 312fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 313fb279d8bSVesa Jääskeläinen } 314fb279d8bSVesa Jääskeläinen 315fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 316fb279d8bSVesa Jääskeläinen init_tee_operation(struct pkcs11_session *session __unused, 317fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params __unused) 318fb279d8bSVesa Jääskeläinen { 319fb279d8bSVesa Jääskeläinen return PKCS11_CKR_OK; 320fb279d8bSVesa Jääskeläinen } 321fb279d8bSVesa Jääskeläinen 322fb279d8bSVesa Jääskeläinen enum pkcs11_rc init_asymm_operation(struct pkcs11_session *session, 323fb279d8bSVesa Jääskeläinen enum processing_func function, 324fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 325fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 326fb279d8bSVesa Jääskeläinen { 327fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 328fb279d8bSVesa Jääskeläinen 329fb279d8bSVesa Jääskeläinen assert(processing_is_tee_asymm(proc_params->id)); 330fb279d8bSVesa Jääskeläinen 331fb279d8bSVesa Jääskeläinen rc = allocate_tee_operation(session, function, proc_params, obj); 332fb279d8bSVesa Jääskeläinen if (rc) 333fb279d8bSVesa Jääskeläinen return rc; 334fb279d8bSVesa Jääskeläinen 335fb279d8bSVesa Jääskeläinen rc = load_tee_key(session, obj, function); 336fb279d8bSVesa Jääskeläinen if (rc) 337fb279d8bSVesa Jääskeläinen return rc; 338fb279d8bSVesa Jääskeläinen 339fb279d8bSVesa Jääskeläinen return init_tee_operation(session, proc_params); 340fb279d8bSVesa Jääskeläinen } 341fb279d8bSVesa Jääskeläinen 342fb279d8bSVesa Jääskeläinen /* 343fb279d8bSVesa Jääskeläinen * step_sym_step - step (update/oneshot/final) on a symmetric crypto operation 344fb279d8bSVesa Jääskeläinen * 345fb279d8bSVesa Jääskeläinen * @session - current session 346fb279d8bSVesa Jääskeläinen * @function - processing function (encrypt, decrypt, sign, ...) 347fb279d8bSVesa Jääskeläinen * @step - step ID in the processing (oneshot, update, final) 348fb279d8bSVesa Jääskeläinen * @ptypes - invocation parameter types 349fb279d8bSVesa Jääskeläinen * @params - invocation parameter references 350fb279d8bSVesa Jääskeläinen */ 351fb279d8bSVesa Jääskeläinen enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session, 352fb279d8bSVesa Jääskeläinen enum processing_func function, 353fb279d8bSVesa Jääskeläinen enum processing_step step, 354fb279d8bSVesa Jääskeläinen uint32_t ptypes, TEE_Param *params) 355fb279d8bSVesa Jääskeläinen { 356fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 357fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 358fb279d8bSVesa Jääskeläinen void *in_buf = NULL; 359fb279d8bSVesa Jääskeläinen void *in2_buf = NULL; 360fb279d8bSVesa Jääskeläinen void *out_buf = NULL; 361fb279d8bSVesa Jääskeläinen void *hash_buf = NULL; 362fb279d8bSVesa Jääskeläinen uint32_t in_size = 0; 363fb279d8bSVesa Jääskeläinen uint32_t in2_size = 0; 364fb279d8bSVesa Jääskeläinen uint32_t out_size = 0; 365fb279d8bSVesa Jääskeläinen uint32_t hash_size = 0; 366fb279d8bSVesa Jääskeläinen TEE_Attribute *tee_attrs = NULL; 367fb279d8bSVesa Jääskeläinen size_t tee_attrs_count = 0; 368fb279d8bSVesa Jääskeläinen bool output_data = false; 369fb279d8bSVesa Jääskeläinen struct active_processing *proc = session->processing; 370fb279d8bSVesa Jääskeläinen size_t sz = 0; 371fb279d8bSVesa Jääskeläinen 372fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 373fb279d8bSVesa Jääskeläinen in_buf = params[1].memref.buffer; 374fb279d8bSVesa Jääskeläinen in_size = params[1].memref.size; 375fb279d8bSVesa Jääskeläinen if (in_size && !in_buf) 376fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 377fb279d8bSVesa Jääskeläinen } 378fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 379fb279d8bSVesa Jääskeläinen in2_buf = params[2].memref.buffer; 380fb279d8bSVesa Jääskeläinen in2_size = params[2].memref.size; 381fb279d8bSVesa Jääskeläinen if (in2_size && !in2_buf) 382fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 383fb279d8bSVesa Jääskeläinen } 384fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 385fb279d8bSVesa Jääskeläinen out_buf = params[2].memref.buffer; 386fb279d8bSVesa Jääskeläinen out_size = params[2].memref.size; 387fb279d8bSVesa Jääskeläinen if (out_size && !out_buf) 388fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 389fb279d8bSVesa Jääskeläinen } 390fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 391fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 392fb279d8bSVesa Jääskeläinen 393fb279d8bSVesa Jääskeläinen switch (step) { 394fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_ONESHOT: 395fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE: 396fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_FINAL: 397fb279d8bSVesa Jääskeläinen break; 398fb279d8bSVesa Jääskeläinen default: 399fb279d8bSVesa Jääskeläinen return PKCS11_CKR_GENERAL_ERROR; 400fb279d8bSVesa Jääskeläinen } 401fb279d8bSVesa Jääskeläinen 402fb279d8bSVesa Jääskeläinen /* 403fb279d8bSVesa Jääskeläinen * Handle multi stage update step for mechas needing hash 404fb279d8bSVesa Jääskeläinen * calculation 405fb279d8bSVesa Jääskeläinen */ 406fb279d8bSVesa Jääskeläinen if (step == PKCS11_FUNC_STEP_UPDATE) { 407fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 408fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 409fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 410fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 411fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 412fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 413*0442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 414*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 415*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 416*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 417*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 418*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 419fb279d8bSVesa Jääskeläinen assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL); 420fb279d8bSVesa Jääskeläinen 421fb279d8bSVesa Jääskeläinen TEE_DigestUpdate(proc->tee_hash_op_handle, in_buf, 422fb279d8bSVesa Jääskeläinen in_size); 423fb279d8bSVesa Jääskeläinen break; 424fb279d8bSVesa Jääskeläinen default: 425fb279d8bSVesa Jääskeläinen /* 426fb279d8bSVesa Jääskeläinen * Other mechanism do not expect multi stage 427fb279d8bSVesa Jääskeläinen * operation 428fb279d8bSVesa Jääskeläinen */ 429fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_GENERAL_ERROR; 430fb279d8bSVesa Jääskeläinen break; 431fb279d8bSVesa Jääskeläinen } 432fb279d8bSVesa Jääskeläinen 433fb279d8bSVesa Jääskeläinen goto out; 434fb279d8bSVesa Jääskeläinen } 435fb279d8bSVesa Jääskeläinen 436fb279d8bSVesa Jääskeläinen /* 437fb279d8bSVesa Jääskeläinen * Handle multi stage one shot and final steps for mechas needing hash 438fb279d8bSVesa Jääskeläinen * calculation 439fb279d8bSVesa Jääskeläinen */ 440fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 441fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 442fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 443fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 444fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 445fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 446*0442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 447*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 448*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 449*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 450*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 451*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 452fb279d8bSVesa Jääskeläinen assert(proc->tee_hash_op_handle != TEE_HANDLE_NULL); 453fb279d8bSVesa Jääskeläinen 454fb279d8bSVesa Jääskeläinen hash_size = TEE_ALG_GET_DIGEST_SIZE(proc->tee_hash_algo); 455fb279d8bSVesa Jääskeläinen hash_buf = TEE_Malloc(hash_size, 0); 456fb279d8bSVesa Jääskeläinen if (!hash_buf) 457fb279d8bSVesa Jääskeläinen return PKCS11_CKR_DEVICE_MEMORY; 458fb279d8bSVesa Jääskeläinen 459fb279d8bSVesa Jääskeläinen res = TEE_DigestDoFinal(proc->tee_hash_op_handle, 460fb279d8bSVesa Jääskeläinen in_buf, in_size, hash_buf, 461fb279d8bSVesa Jääskeläinen &hash_size); 462fb279d8bSVesa Jääskeläinen 463fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 464fb279d8bSVesa Jääskeläinen if (rc != PKCS11_CKR_OK) 465fb279d8bSVesa Jääskeläinen goto out; 466fb279d8bSVesa Jääskeläinen 467fb279d8bSVesa Jääskeläinen break; 468fb279d8bSVesa Jääskeläinen default: 469fb279d8bSVesa Jääskeläinen break; 470fb279d8bSVesa Jääskeläinen } 471fb279d8bSVesa Jääskeläinen 472fb279d8bSVesa Jääskeläinen /* 473fb279d8bSVesa Jääskeläinen * Finalize either provided hash or calculated hash with signing 474fb279d8bSVesa Jääskeläinen * operation 475fb279d8bSVesa Jääskeläinen */ 476fb279d8bSVesa Jääskeläinen 477fb279d8bSVesa Jääskeläinen /* First determine amount of bytes for signing operation */ 478fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 479fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 480fb279d8bSVesa Jääskeläinen sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle); 481fb279d8bSVesa Jääskeläinen if (!in_size || !sz) { 482fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 483fb279d8bSVesa Jääskeläinen goto out; 484fb279d8bSVesa Jääskeläinen } 485fb279d8bSVesa Jääskeläinen 486fb279d8bSVesa Jääskeläinen /* 487fb279d8bSVesa Jääskeläinen * Note 3) Input the entire raw digest. Internally, this will 488fb279d8bSVesa Jääskeläinen * be truncated to the appropriate number of bits. 489fb279d8bSVesa Jääskeläinen */ 490fb279d8bSVesa Jääskeläinen if (in_size > sz) 491fb279d8bSVesa Jääskeläinen in_size = sz; 492fb279d8bSVesa Jääskeläinen 493fb279d8bSVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && in2_size != 2 * sz) { 494fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 495fb279d8bSVesa Jääskeläinen goto out; 496fb279d8bSVesa Jääskeläinen } 497fb279d8bSVesa Jääskeläinen break; 498fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 499fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 500fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 501fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 502fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 503fb279d8bSVesa Jääskeläinen /* Get key size in bytes */ 504fb279d8bSVesa Jääskeläinen sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle); 505fb279d8bSVesa Jääskeläinen if (!sz) { 506fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 507fb279d8bSVesa Jääskeläinen goto out; 508fb279d8bSVesa Jääskeläinen } 509fb279d8bSVesa Jääskeläinen 510fb279d8bSVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && 511fb279d8bSVesa Jääskeläinen in2_size != 2 * sz) { 512fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 513fb279d8bSVesa Jääskeläinen goto out; 514fb279d8bSVesa Jääskeläinen } 515fb279d8bSVesa Jääskeläinen break; 516*0442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 517*0442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 518*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 519*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 520*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 521*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 522*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 523*0442c956SVesa Jääskeläinen /* Get key size in bytes */ 524*0442c956SVesa Jääskeläinen sz = rsa_get_input_max_byte_size(proc->tee_op_handle); 525*0442c956SVesa Jääskeläinen if (!sz) { 526*0442c956SVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 527*0442c956SVesa Jääskeläinen goto out; 528*0442c956SVesa Jääskeläinen } 529*0442c956SVesa Jääskeläinen 530*0442c956SVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && in2_size != sz) { 531*0442c956SVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 532*0442c956SVesa Jääskeläinen goto out; 533*0442c956SVesa Jääskeläinen } 534*0442c956SVesa Jääskeläinen break; 535fb279d8bSVesa Jääskeläinen default: 536fb279d8bSVesa Jääskeläinen break; 537fb279d8bSVesa Jääskeläinen } 538fb279d8bSVesa Jääskeläinen 539fb279d8bSVesa Jääskeläinen /* Next perform actual signing operation */ 540fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 541fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 542*0442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 543fb279d8bSVesa Jääskeläinen /* For operations using provided input data */ 544fb279d8bSVesa Jääskeläinen switch (function) { 545fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_ENCRYPT: 546fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricEncrypt(proc->tee_op_handle, 547fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count, 548fb279d8bSVesa Jääskeläinen in_buf, in_size, 549fb279d8bSVesa Jääskeläinen out_buf, &out_size); 550fb279d8bSVesa Jääskeläinen output_data = true; 551fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 552fb279d8bSVesa Jääskeläinen break; 553fb279d8bSVesa Jääskeläinen 554fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_DECRYPT: 555fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricDecrypt(proc->tee_op_handle, 556fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count, 557fb279d8bSVesa Jääskeläinen in_buf, in_size, 558fb279d8bSVesa Jääskeläinen out_buf, &out_size); 559fb279d8bSVesa Jääskeläinen output_data = true; 560fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 561fb279d8bSVesa Jääskeläinen break; 562fb279d8bSVesa Jääskeläinen 563fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_SIGN: 564fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricSignDigest(proc->tee_op_handle, 565fb279d8bSVesa Jääskeläinen tee_attrs, 566fb279d8bSVesa Jääskeläinen tee_attrs_count, 567fb279d8bSVesa Jääskeläinen in_buf, in_size, 568fb279d8bSVesa Jääskeläinen out_buf, &out_size); 569fb279d8bSVesa Jääskeläinen output_data = true; 570fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 571fb279d8bSVesa Jääskeläinen break; 572fb279d8bSVesa Jääskeläinen 573fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_VERIFY: 574fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle, 575fb279d8bSVesa Jääskeläinen tee_attrs, 576fb279d8bSVesa Jääskeläinen tee_attrs_count, 577fb279d8bSVesa Jääskeläinen in_buf, in_size, 578fb279d8bSVesa Jääskeläinen in2_buf, in2_size); 579fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 580fb279d8bSVesa Jääskeläinen break; 581fb279d8bSVesa Jääskeläinen 582fb279d8bSVesa Jääskeläinen default: 583fb279d8bSVesa Jääskeläinen TEE_Panic(function); 584fb279d8bSVesa Jääskeläinen break; 585fb279d8bSVesa Jääskeläinen } 586fb279d8bSVesa Jääskeläinen break; 587fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 588fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 589fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 590fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 591fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 592*0442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 593*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 594*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 595*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 596*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 597*0442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 598fb279d8bSVesa Jääskeläinen /* For operations having hash operation use calculated hash */ 599fb279d8bSVesa Jääskeläinen switch (function) { 600fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_SIGN: 601fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricSignDigest(proc->tee_op_handle, 602fb279d8bSVesa Jääskeläinen tee_attrs, 603fb279d8bSVesa Jääskeläinen tee_attrs_count, 604fb279d8bSVesa Jääskeläinen hash_buf, hash_size, 605fb279d8bSVesa Jääskeläinen out_buf, &out_size); 606fb279d8bSVesa Jääskeläinen output_data = true; 607fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 608fb279d8bSVesa Jääskeläinen break; 609fb279d8bSVesa Jääskeläinen 610fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_VERIFY: 611fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle, 612fb279d8bSVesa Jääskeläinen tee_attrs, 613fb279d8bSVesa Jääskeläinen tee_attrs_count, 614fb279d8bSVesa Jääskeläinen hash_buf, hash_size, 615fb279d8bSVesa Jääskeläinen in2_buf, in2_size); 616fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 617fb279d8bSVesa Jääskeläinen break; 618fb279d8bSVesa Jääskeläinen 619fb279d8bSVesa Jääskeläinen default: 620fb279d8bSVesa Jääskeläinen TEE_Panic(function); 621fb279d8bSVesa Jääskeläinen break; 622fb279d8bSVesa Jääskeläinen } 623fb279d8bSVesa Jääskeläinen break; 624fb279d8bSVesa Jääskeläinen default: 625fb279d8bSVesa Jääskeläinen TEE_Panic(proc->mecha_type); 626fb279d8bSVesa Jääskeläinen break; 627fb279d8bSVesa Jääskeläinen } 628fb279d8bSVesa Jääskeläinen 629fb279d8bSVesa Jääskeläinen out: 630fb279d8bSVesa Jääskeläinen if (output_data && 631fb279d8bSVesa Jääskeläinen (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 632fb279d8bSVesa Jääskeläinen switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 633fb279d8bSVesa Jääskeläinen case TEE_PARAM_TYPE_MEMREF_OUTPUT: 634fb279d8bSVesa Jääskeläinen case TEE_PARAM_TYPE_MEMREF_INOUT: 635fb279d8bSVesa Jääskeläinen params[2].memref.size = out_size; 636fb279d8bSVesa Jääskeläinen break; 637fb279d8bSVesa Jääskeläinen default: 638fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_GENERAL_ERROR; 639fb279d8bSVesa Jääskeläinen break; 640fb279d8bSVesa Jääskeläinen } 641fb279d8bSVesa Jääskeläinen } 642fb279d8bSVesa Jääskeläinen 643fb279d8bSVesa Jääskeläinen TEE_Free(hash_buf); 644fb279d8bSVesa Jääskeläinen TEE_Free(tee_attrs); 645fb279d8bSVesa Jääskeläinen 646fb279d8bSVesa Jääskeläinen return rc; 647fb279d8bSVesa Jääskeläinen } 648