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> 845d40bdaSValerii Chubar #include <mbedtls/nist_kw.h> 9*e02f17f3SAlexandre Marechal #include <string_ext.h> 10fb279d8bSVesa Jääskeläinen #include <tee_api_defines.h> 11fb279d8bSVesa Jääskeläinen #include <tee_internal_api.h> 12fb279d8bSVesa Jääskeläinen #include <tee_internal_api_extensions.h> 13fb279d8bSVesa Jääskeläinen 14fb279d8bSVesa Jääskeläinen #include "attributes.h" 15fb279d8bSVesa Jääskeläinen #include "pkcs11_helpers.h" 16fb279d8bSVesa Jääskeläinen #include "pkcs11_token.h" 17fb279d8bSVesa Jääskeläinen #include "processing.h" 18fb279d8bSVesa Jääskeläinen #include "serializer.h" 19fb279d8bSVesa Jääskeläinen 20fb279d8bSVesa Jääskeläinen bool processing_is_tee_asymm(uint32_t proc_id) 21fb279d8bSVesa Jääskeläinen { 22fb279d8bSVesa Jääskeläinen switch (proc_id) { 230442c956SVesa Jääskeläinen /* RSA flavors */ 2445d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 250442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 26*e02f17f3SAlexandre Marechal case PKCS11_CKM_RSA_X_509: 27dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 28d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 290442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 300442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 310442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 320442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 330442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 340442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 35d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 36d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 37d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 38d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 39d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 40fb279d8bSVesa Jääskeläinen /* EC flavors */ 4103e07432SValerii Chubar case PKCS11_CKM_EDDSA: 42fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 43cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 44fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 45fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 46fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 47fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 48fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 49fb279d8bSVesa Jääskeläinen return true; 50fb279d8bSVesa Jääskeläinen default: 51fb279d8bSVesa Jääskeläinen return false; 52fb279d8bSVesa Jääskeläinen } 53fb279d8bSVesa Jääskeläinen } 54fb279d8bSVesa Jääskeläinen 55fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 56fb279d8bSVesa Jääskeläinen pkcs2tee_algorithm(uint32_t *tee_id, uint32_t *tee_hash_id, 57fb279d8bSVesa Jääskeläinen enum processing_func function __unused, 58fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 59fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 60fb279d8bSVesa Jääskeläinen { 61fb279d8bSVesa Jääskeläinen static const struct { 62fb279d8bSVesa Jääskeläinen enum pkcs11_mechanism_id mech_id; 63fb279d8bSVesa Jääskeläinen uint32_t tee_id; 64fb279d8bSVesa Jääskeläinen uint32_t tee_hash_id; 65fb279d8bSVesa Jääskeläinen } pkcs2tee_algo[] = { 660442c956SVesa Jääskeläinen /* RSA flavors */ 6745d40bdaSValerii Chubar { PKCS11_CKM_RSA_AES_KEY_WRAP, 1, 0 }, 680442c956SVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS, TEE_ALG_RSAES_PKCS1_V1_5, 0 }, 69dc8c77fcSVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS_OAEP, 1, 0 }, 70d9af50bcSVesa Jääskeläinen { PKCS11_CKM_RSA_PKCS_PSS, 1, 0 }, 71*e02f17f3SAlexandre Marechal { PKCS11_CKM_RSA_X_509, TEE_ALG_RSA_NOPAD, 0 }, 720442c956SVesa Jääskeläinen { PKCS11_CKM_MD5_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_MD5, 730442c956SVesa Jääskeläinen TEE_ALG_MD5 }, 740442c956SVesa Jääskeläinen { PKCS11_CKM_SHA1_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA1, 750442c956SVesa Jääskeläinen TEE_ALG_SHA1 }, 760442c956SVesa Jääskeläinen { PKCS11_CKM_SHA224_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA224, 770442c956SVesa Jääskeläinen TEE_ALG_SHA224 }, 780442c956SVesa Jääskeläinen { PKCS11_CKM_SHA256_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA256, 790442c956SVesa Jääskeläinen TEE_ALG_SHA256 }, 800442c956SVesa Jääskeläinen { PKCS11_CKM_SHA384_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA384, 810442c956SVesa Jääskeläinen TEE_ALG_SHA384 }, 820442c956SVesa Jääskeläinen { PKCS11_CKM_SHA512_RSA_PKCS, TEE_ALG_RSASSA_PKCS1_V1_5_SHA512, 830442c956SVesa Jääskeläinen TEE_ALG_SHA512 }, 84d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA1_RSA_PKCS_PSS, 85d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1, TEE_ALG_SHA1 }, 86d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA224_RSA_PKCS_PSS, 87d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224, TEE_ALG_SHA224 }, 88d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA256_RSA_PKCS_PSS, 89d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256, TEE_ALG_SHA256 }, 90d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA384_RSA_PKCS_PSS, 91d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384, TEE_ALG_SHA384 }, 92d9af50bcSVesa Jääskeläinen { PKCS11_CKM_SHA512_RSA_PKCS_PSS, 93d9af50bcSVesa Jääskeläinen TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512, TEE_ALG_SHA512 }, 94fb279d8bSVesa Jääskeläinen /* EC flavors (Must find key size from the object) */ 95fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA, 1, 0 }, 96fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA1, 1, TEE_ALG_SHA1 }, 97fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA224, 1, TEE_ALG_SHA224 }, 98fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA256, 1, TEE_ALG_SHA256 }, 99fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA384, 1, TEE_ALG_SHA384 }, 100fb279d8bSVesa Jääskeläinen { PKCS11_CKM_ECDSA_SHA512, 1, TEE_ALG_SHA512 }, 101cc062b46SJorge Ramirez-Ortiz { PKCS11_CKM_ECDH1_DERIVE, 1, 0 }, 10203e07432SValerii Chubar { PKCS11_CKM_EDDSA, TEE_ALG_ED25519, 0 }, 103fb279d8bSVesa Jääskeläinen }; 104fb279d8bSVesa Jääskeläinen size_t n = 0; 105fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 106fb279d8bSVesa Jääskeläinen 107fb279d8bSVesa Jääskeläinen for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) { 108fb279d8bSVesa Jääskeläinen if (pkcs2tee_algo[n].mech_id == proc_params->id) { 109fb279d8bSVesa Jääskeläinen *tee_id = pkcs2tee_algo[n].tee_id; 110fb279d8bSVesa Jääskeläinen *tee_hash_id = pkcs2tee_algo[n].tee_hash_id; 111fb279d8bSVesa Jääskeläinen break; 112fb279d8bSVesa Jääskeläinen } 113fb279d8bSVesa Jääskeläinen } 114fb279d8bSVesa Jääskeläinen 115fb279d8bSVesa Jääskeläinen if (n == ARRAY_SIZE(pkcs2tee_algo)) 116fb279d8bSVesa Jääskeläinen return PKCS11_RV_NOT_IMPLEMENTED; 117fb279d8bSVesa Jääskeläinen 118fb279d8bSVesa Jääskeläinen switch (proc_params->id) { 119d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 120d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 121d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 122d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 123d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 124d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 125d9af50bcSVesa Jääskeläinen rc = pkcs2tee_algo_rsa_pss(tee_id, proc_params); 126d9af50bcSVesa Jääskeläinen break; 127dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 128dc8c77fcSVesa Jääskeläinen rc = pkcs2tee_algo_rsa_oaep(tee_id, tee_hash_id, proc_params); 129dc8c77fcSVesa Jääskeläinen break; 13045d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 13145d40bdaSValerii Chubar rc = pkcs2tee_algo_rsa_aes_wrap(tee_id, tee_hash_id, 13245d40bdaSValerii Chubar proc_params); 13345d40bdaSValerii Chubar break; 134fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 135fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 136fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 137fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 138fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 139fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 140fb279d8bSVesa Jääskeläinen rc = pkcs2tee_algo_ecdsa(tee_id, proc_params, obj); 141fb279d8bSVesa Jääskeläinen break; 142cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 143cc062b46SJorge Ramirez-Ortiz rc = pkcs2tee_algo_ecdh(tee_id, proc_params, obj); 144cc062b46SJorge Ramirez-Ortiz break; 145fb279d8bSVesa Jääskeläinen default: 146fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_OK; 147fb279d8bSVesa Jääskeläinen break; 148fb279d8bSVesa Jääskeläinen } 149fb279d8bSVesa Jääskeläinen 1500442c956SVesa Jääskeläinen /* 1510442c956SVesa Jääskeläinen * PKCS#11 uses single mechanism CKM_RSA_PKCS for both ciphering and 1520442c956SVesa Jääskeläinen * authentication whereas GPD TEE expects TEE_ALG_RSAES_PKCS1_V1_5 for 1530442c956SVesa Jääskeläinen * ciphering and TEE_ALG_RSASSA_PKCS1_V1_5 for authentication. 1540442c956SVesa Jääskeläinen */ 1550442c956SVesa Jääskeläinen if (*tee_id == TEE_ALG_RSAES_PKCS1_V1_5 && 1560442c956SVesa Jääskeläinen (function == PKCS11_FUNCTION_SIGN || 1570442c956SVesa Jääskeläinen function == PKCS11_FUNCTION_VERIFY)) 1580442c956SVesa Jääskeläinen *tee_id = TEE_ALG_RSASSA_PKCS1_V1_5; 1590442c956SVesa Jääskeläinen 160fb279d8bSVesa Jääskeläinen return rc; 161fb279d8bSVesa Jääskeläinen } 162fb279d8bSVesa Jääskeläinen 163fb279d8bSVesa Jääskeläinen static enum pkcs11_rc pkcs2tee_key_type(uint32_t *tee_type, 164fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj, 165fb279d8bSVesa Jääskeläinen enum processing_func function) 166fb279d8bSVesa Jääskeläinen { 167fb279d8bSVesa Jääskeläinen enum pkcs11_class_id class = get_class(obj->attributes); 168fb279d8bSVesa Jääskeläinen enum pkcs11_key_type type = get_key_type(obj->attributes); 169fb279d8bSVesa Jääskeläinen 170fb279d8bSVesa Jääskeläinen switch (class) { 171fb279d8bSVesa Jääskeläinen case PKCS11_CKO_PUBLIC_KEY: 172fb279d8bSVesa Jääskeläinen case PKCS11_CKO_PRIVATE_KEY: 173fb279d8bSVesa Jääskeläinen break; 174fb279d8bSVesa Jääskeläinen default: 175fb279d8bSVesa Jääskeläinen TEE_Panic(class); 176fb279d8bSVesa Jääskeläinen break; 177fb279d8bSVesa Jääskeläinen } 178fb279d8bSVesa Jääskeläinen 179fb279d8bSVesa Jääskeläinen switch (type) { 180fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 181cc062b46SJorge Ramirez-Ortiz if (class == PKCS11_CKO_PRIVATE_KEY) { 182cc062b46SJorge Ramirez-Ortiz if (function == PKCS11_FUNCTION_DERIVE) 183cc062b46SJorge Ramirez-Ortiz *tee_type = TEE_TYPE_ECDH_KEYPAIR; 184cc062b46SJorge Ramirez-Ortiz else 185fb279d8bSVesa Jääskeläinen *tee_type = TEE_TYPE_ECDSA_KEYPAIR; 186cc062b46SJorge Ramirez-Ortiz } else { 187cc062b46SJorge Ramirez-Ortiz if (function == PKCS11_FUNCTION_DERIVE) 188cc062b46SJorge Ramirez-Ortiz *tee_type = TEE_TYPE_ECDH_PUBLIC_KEY; 189fb279d8bSVesa Jääskeläinen else 190fb279d8bSVesa Jääskeläinen *tee_type = TEE_TYPE_ECDSA_PUBLIC_KEY; 191cc062b46SJorge Ramirez-Ortiz } 192fb279d8bSVesa Jääskeläinen break; 1930442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 1940442c956SVesa Jääskeläinen if (class == PKCS11_CKO_PRIVATE_KEY) 1950442c956SVesa Jääskeläinen *tee_type = TEE_TYPE_RSA_KEYPAIR; 1960442c956SVesa Jääskeläinen else 1970442c956SVesa Jääskeläinen *tee_type = TEE_TYPE_RSA_PUBLIC_KEY; 1980442c956SVesa Jääskeläinen break; 19903e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 20003e07432SValerii Chubar if (class == PKCS11_CKO_PRIVATE_KEY) 20103e07432SValerii Chubar *tee_type = TEE_TYPE_ED25519_KEYPAIR; 20203e07432SValerii Chubar else 20303e07432SValerii Chubar *tee_type = TEE_TYPE_ED25519_PUBLIC_KEY; 20403e07432SValerii Chubar break; 205fb279d8bSVesa Jääskeläinen default: 206fb279d8bSVesa Jääskeläinen TEE_Panic(type); 207fb279d8bSVesa Jääskeläinen break; 208fb279d8bSVesa Jääskeläinen } 209fb279d8bSVesa Jääskeläinen 210fb279d8bSVesa Jääskeläinen return PKCS11_CKR_OK; 211fb279d8bSVesa Jääskeläinen } 212fb279d8bSVesa Jääskeläinen 213fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 214fb279d8bSVesa Jääskeläinen allocate_tee_operation(struct pkcs11_session *session, 215fb279d8bSVesa Jääskeläinen enum processing_func function, 216fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *params, 217fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 218fb279d8bSVesa Jääskeläinen { 219fb279d8bSVesa Jääskeläinen uint32_t size = (uint32_t)get_object_key_bit_size(obj); 220fb279d8bSVesa Jääskeläinen uint32_t algo = 0; 221fb279d8bSVesa Jääskeläinen uint32_t hash_algo = 0; 222fb279d8bSVesa Jääskeläinen uint32_t mode = 0; 223fb279d8bSVesa Jääskeläinen uint32_t hash_mode = 0; 224fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 225fb279d8bSVesa Jääskeläinen struct active_processing *processing = session->processing; 226fb279d8bSVesa Jääskeläinen 227fb279d8bSVesa Jääskeläinen assert(processing->tee_op_handle == TEE_HANDLE_NULL); 228571857c0SEtienne Carriere assert(processing->tee_op_handle2 == TEE_HANDLE_NULL); 229fb279d8bSVesa Jääskeläinen 230fb279d8bSVesa Jääskeläinen if (pkcs2tee_algorithm(&algo, &hash_algo, function, params, obj)) 231fb279d8bSVesa Jääskeläinen return PKCS11_CKR_FUNCTION_FAILED; 232fb279d8bSVesa Jääskeläinen 233*e02f17f3SAlexandre Marechal /* 234*e02f17f3SAlexandre Marechal * PKCS#11 allows Sign/Verify with CKM_RSA_X_509 while GP TEE API 235*e02f17f3SAlexandre Marechal * only permits Encrypt/Decrypt with TEE_ALG_RSA_NOPAD. 236*e02f17f3SAlexandre Marechal * For other algorithm, use simple 1-to-1 ID conversion pkcs2tee_mode(). 237*e02f17f3SAlexandre Marechal */ 238*e02f17f3SAlexandre Marechal if (params->id == PKCS11_CKM_RSA_X_509) { 239*e02f17f3SAlexandre Marechal assert(!hash_algo); 240*e02f17f3SAlexandre Marechal switch (function) { 241*e02f17f3SAlexandre Marechal case PKCS11_FUNCTION_VERIFY: 242*e02f17f3SAlexandre Marechal mode = TEE_MODE_ENCRYPT; 243*e02f17f3SAlexandre Marechal break; 244*e02f17f3SAlexandre Marechal case PKCS11_FUNCTION_SIGN: 245*e02f17f3SAlexandre Marechal mode = TEE_MODE_DECRYPT; 246*e02f17f3SAlexandre Marechal break; 247*e02f17f3SAlexandre Marechal default: 248*e02f17f3SAlexandre Marechal TEE_Panic(0); 249*e02f17f3SAlexandre Marechal } 250*e02f17f3SAlexandre Marechal } else { 251fb279d8bSVesa Jääskeläinen pkcs2tee_mode(&mode, function); 252*e02f17f3SAlexandre Marechal } 253fb279d8bSVesa Jääskeläinen 254fb279d8bSVesa Jääskeläinen if (hash_algo) { 255fb279d8bSVesa Jääskeläinen pkcs2tee_mode(&hash_mode, PKCS11_FUNCTION_DIGEST); 256fb279d8bSVesa Jääskeläinen 257571857c0SEtienne Carriere res = TEE_AllocateOperation(&processing->tee_op_handle2, 258fb279d8bSVesa Jääskeläinen hash_algo, hash_mode, 0); 259fb279d8bSVesa Jääskeläinen if (res) { 260fb279d8bSVesa Jääskeläinen EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32, 261fb279d8bSVesa Jääskeläinen hash_algo, hash_mode); 262fb279d8bSVesa Jääskeläinen 263fb279d8bSVesa Jääskeläinen if (res == TEE_ERROR_NOT_SUPPORTED) 264fb279d8bSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_INVALID; 265fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 266fb279d8bSVesa Jääskeläinen } 267fb279d8bSVesa Jääskeläinen processing->tee_hash_algo = hash_algo; 268fb279d8bSVesa Jääskeläinen } 269fb279d8bSVesa Jääskeläinen 270fb279d8bSVesa Jääskeläinen res = TEE_AllocateOperation(&processing->tee_op_handle, 271fb279d8bSVesa Jääskeläinen algo, mode, size); 272fb279d8bSVesa Jääskeläinen if (res) 273fb279d8bSVesa Jääskeläinen EMSG("TEE_AllocateOp. failed %#"PRIx32" %#"PRIx32" %#"PRIx32, 274fb279d8bSVesa Jääskeläinen algo, mode, size); 275fb279d8bSVesa Jääskeläinen 276fb279d8bSVesa Jääskeläinen if (res == TEE_ERROR_NOT_SUPPORTED) 277fb279d8bSVesa Jääskeläinen return PKCS11_CKR_MECHANISM_INVALID; 278fb279d8bSVesa Jääskeläinen 279fb279d8bSVesa Jääskeläinen if (res != TEE_SUCCESS && 280571857c0SEtienne Carriere processing->tee_op_handle2 != TEE_HANDLE_NULL) { 281571857c0SEtienne Carriere TEE_FreeOperation(session->processing->tee_op_handle2); 282571857c0SEtienne Carriere processing->tee_op_handle2 = TEE_HANDLE_NULL; 283fb279d8bSVesa Jääskeläinen processing->tee_hash_algo = 0; 284fb279d8bSVesa Jääskeläinen } 285fb279d8bSVesa Jääskeläinen 286fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 287fb279d8bSVesa Jääskeläinen } 288fb279d8bSVesa Jääskeläinen 289fb279d8bSVesa Jääskeläinen static enum pkcs11_rc load_tee_key(struct pkcs11_session *session, 290fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj, 291fb279d8bSVesa Jääskeläinen enum processing_func function) 292fb279d8bSVesa Jääskeläinen { 293fb279d8bSVesa Jääskeläinen TEE_Attribute *tee_attrs = NULL; 294fb279d8bSVesa Jääskeläinen size_t tee_attrs_count = 0; 295fb279d8bSVesa Jääskeläinen size_t object_size = 0; 296fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 297fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 298fb279d8bSVesa Jääskeläinen enum pkcs11_class_id __maybe_unused class = get_class(obj->attributes); 299fb279d8bSVesa Jääskeläinen enum pkcs11_key_type type = get_key_type(obj->attributes); 300fb279d8bSVesa Jääskeläinen 301fb279d8bSVesa Jääskeläinen assert(class == PKCS11_CKO_PUBLIC_KEY || 302fb279d8bSVesa Jääskeläinen class == PKCS11_CKO_PRIVATE_KEY); 303fb279d8bSVesa Jääskeläinen 304fb279d8bSVesa Jääskeläinen if (obj->key_handle != TEE_HANDLE_NULL) { 305fb279d8bSVesa Jääskeläinen switch (type) { 3060442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 3070442c956SVesa Jääskeläinen /* RSA loaded keys can be reused */ 3080442c956SVesa Jääskeläinen assert((obj->key_type == TEE_TYPE_RSA_PUBLIC_KEY && 3090442c956SVesa Jääskeläinen class == PKCS11_CKO_PUBLIC_KEY) || 3100442c956SVesa Jääskeläinen (obj->key_type == TEE_TYPE_RSA_KEYPAIR && 3110442c956SVesa Jääskeläinen class == PKCS11_CKO_PRIVATE_KEY)); 3120442c956SVesa Jääskeläinen goto key_ready; 313fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 314fb279d8bSVesa Jääskeläinen /* Reuse EC TEE key only if already DSA or DH */ 315fb279d8bSVesa Jääskeläinen switch (obj->key_type) { 316fb279d8bSVesa Jääskeläinen case TEE_TYPE_ECDSA_PUBLIC_KEY: 317fb279d8bSVesa Jääskeläinen case TEE_TYPE_ECDSA_KEYPAIR: 318fb279d8bSVesa Jääskeläinen if (function != PKCS11_FUNCTION_DERIVE) 319fb279d8bSVesa Jääskeläinen goto key_ready; 320fb279d8bSVesa Jääskeläinen break; 321cc062b46SJorge Ramirez-Ortiz case TEE_TYPE_ECDH_PUBLIC_KEY: 322cc062b46SJorge Ramirez-Ortiz case TEE_TYPE_ECDH_KEYPAIR: 323cc062b46SJorge Ramirez-Ortiz if (function == PKCS11_FUNCTION_DERIVE) 324cc062b46SJorge Ramirez-Ortiz goto key_ready; 325cc062b46SJorge Ramirez-Ortiz break; 326fb279d8bSVesa Jääskeläinen default: 327fb279d8bSVesa Jääskeläinen assert(0); 328fb279d8bSVesa Jääskeläinen break; 329fb279d8bSVesa Jääskeläinen } 330fb279d8bSVesa Jääskeläinen break; 331fb279d8bSVesa Jääskeläinen default: 332fb279d8bSVesa Jääskeläinen assert(0); 333fb279d8bSVesa Jääskeläinen break; 334fb279d8bSVesa Jääskeläinen } 335fb279d8bSVesa Jääskeläinen 336fb279d8bSVesa Jääskeläinen TEE_CloseObject(obj->key_handle); 337fb279d8bSVesa Jääskeläinen obj->key_handle = TEE_HANDLE_NULL; 338fb279d8bSVesa Jääskeläinen } 339fb279d8bSVesa Jääskeläinen 340fb279d8bSVesa Jääskeläinen rc = pkcs2tee_key_type(&obj->key_type, obj, function); 341fb279d8bSVesa Jääskeläinen if (rc) 342fb279d8bSVesa Jääskeläinen return rc; 343fb279d8bSVesa Jääskeläinen 344fb279d8bSVesa Jääskeläinen object_size = get_object_key_bit_size(obj); 345fb279d8bSVesa Jääskeläinen if (!object_size) 346fb279d8bSVesa Jääskeläinen return PKCS11_CKR_GENERAL_ERROR; 347fb279d8bSVesa Jääskeläinen 348fb279d8bSVesa Jääskeläinen switch (type) { 3490442c956SVesa Jääskeläinen case PKCS11_CKK_RSA: 3500442c956SVesa Jääskeläinen rc = load_tee_rsa_key_attrs(&tee_attrs, &tee_attrs_count, obj); 3510442c956SVesa Jääskeläinen break; 352fb279d8bSVesa Jääskeläinen case PKCS11_CKK_EC: 353fb279d8bSVesa Jääskeläinen rc = load_tee_ec_key_attrs(&tee_attrs, &tee_attrs_count, obj); 354fb279d8bSVesa Jääskeläinen break; 35503e07432SValerii Chubar case PKCS11_CKK_EC_EDWARDS: 35603e07432SValerii Chubar rc = load_tee_eddsa_key_attrs(&tee_attrs, &tee_attrs_count, 35703e07432SValerii Chubar obj); 35803e07432SValerii Chubar break; 359fb279d8bSVesa Jääskeläinen default: 360fb279d8bSVesa Jääskeläinen break; 361fb279d8bSVesa Jääskeläinen } 362fb279d8bSVesa Jääskeläinen if (rc) 363fb279d8bSVesa Jääskeläinen return rc; 364fb279d8bSVesa Jääskeläinen 365fb279d8bSVesa Jääskeläinen res = TEE_AllocateTransientObject(obj->key_type, object_size, 366fb279d8bSVesa Jääskeläinen &obj->key_handle); 367fb279d8bSVesa Jääskeläinen if (res) { 368fb279d8bSVesa Jääskeläinen DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 369fb279d8bSVesa Jääskeläinen 370fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 371fb279d8bSVesa Jääskeläinen } 372fb279d8bSVesa Jääskeläinen 373fb279d8bSVesa Jääskeläinen res = TEE_PopulateTransientObject(obj->key_handle, 374fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count); 375fb279d8bSVesa Jääskeläinen 376fb279d8bSVesa Jääskeläinen TEE_Free(tee_attrs); 377fb279d8bSVesa Jääskeläinen 378fb279d8bSVesa Jääskeläinen if (res) { 379fb279d8bSVesa Jääskeläinen DMSG("TEE_PopulateTransientObject failed, %#"PRIx32, res); 380fb279d8bSVesa Jääskeläinen 381fb279d8bSVesa Jääskeläinen goto error; 382fb279d8bSVesa Jääskeläinen } 383fb279d8bSVesa Jääskeläinen 384fb279d8bSVesa Jääskeläinen key_ready: 385fb279d8bSVesa Jääskeläinen res = TEE_SetOperationKey(session->processing->tee_op_handle, 386fb279d8bSVesa Jääskeläinen obj->key_handle); 387fb279d8bSVesa Jääskeläinen if (res) { 388fb279d8bSVesa Jääskeläinen DMSG("TEE_SetOperationKey failed, %#"PRIx32, res); 389fb279d8bSVesa Jääskeläinen 390fb279d8bSVesa Jääskeläinen goto error; 391fb279d8bSVesa Jääskeläinen } 392fb279d8bSVesa Jääskeläinen 393fb279d8bSVesa Jääskeläinen return PKCS11_CKR_OK; 394fb279d8bSVesa Jääskeläinen 395fb279d8bSVesa Jääskeläinen error: 396fb279d8bSVesa Jääskeläinen TEE_FreeTransientObject(obj->key_handle); 397fb279d8bSVesa Jääskeläinen obj->key_handle = TEE_HANDLE_NULL; 398fb279d8bSVesa Jääskeläinen return tee2pkcs_error(res); 399fb279d8bSVesa Jääskeläinen } 400fb279d8bSVesa Jääskeläinen 401fb279d8bSVesa Jääskeläinen static enum pkcs11_rc 402d9af50bcSVesa Jääskeläinen init_tee_operation(struct pkcs11_session *session, 403d9af50bcSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 404d9af50bcSVesa Jääskeläinen struct pkcs11_object *obj) 405fb279d8bSVesa Jääskeläinen { 406d9af50bcSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_OK; 407d9af50bcSVesa Jääskeläinen struct active_processing *proc = session->processing; 408d9af50bcSVesa Jääskeläinen 409d9af50bcSVesa Jääskeläinen switch (proc_params->id) { 410*e02f17f3SAlexandre Marechal case PKCS11_CKM_RSA_X_509: 411*e02f17f3SAlexandre Marechal rc = pkcs2tee_rsa_nopad_context(proc); 412*e02f17f3SAlexandre Marechal break; 413d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 414d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 415d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 416d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 417d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 418d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 419d9af50bcSVesa Jääskeläinen rc = pkcs2tee_proc_params_rsa_pss(proc, proc_params); 420d9af50bcSVesa Jääskeläinen if (rc) 421d9af50bcSVesa Jääskeläinen break; 422d9af50bcSVesa Jääskeläinen 423d9af50bcSVesa Jääskeläinen rc = pkcs2tee_validate_rsa_pss(proc, obj); 424d9af50bcSVesa Jääskeläinen break; 425dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 426dc8c77fcSVesa Jääskeläinen rc = pkcs2tee_proc_params_rsa_oaep(proc, proc_params); 427dc8c77fcSVesa Jääskeläinen break; 42803e07432SValerii Chubar case PKCS11_CKM_EDDSA: 42903e07432SValerii Chubar rc = pkcs2tee_proc_params_eddsa(proc, proc_params); 43003e07432SValerii Chubar break; 43145d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 43245d40bdaSValerii Chubar rc = pkcs2tee_proc_params_rsa_aes_wrap(proc, proc_params); 43345d40bdaSValerii Chubar break; 434d9af50bcSVesa Jääskeläinen default: 435d9af50bcSVesa Jääskeläinen break; 436d9af50bcSVesa Jääskeläinen } 437d9af50bcSVesa Jääskeläinen 438d9af50bcSVesa Jääskeläinen return rc; 439fb279d8bSVesa Jääskeläinen } 440fb279d8bSVesa Jääskeläinen 441fb279d8bSVesa Jääskeläinen enum pkcs11_rc init_asymm_operation(struct pkcs11_session *session, 442fb279d8bSVesa Jääskeläinen enum processing_func function, 443fb279d8bSVesa Jääskeläinen struct pkcs11_attribute_head *proc_params, 444fb279d8bSVesa Jääskeläinen struct pkcs11_object *obj) 445fb279d8bSVesa Jääskeläinen { 446fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 447fb279d8bSVesa Jääskeläinen 448fb279d8bSVesa Jääskeläinen assert(processing_is_tee_asymm(proc_params->id)); 449fb279d8bSVesa Jääskeläinen 450fb279d8bSVesa Jääskeläinen rc = allocate_tee_operation(session, function, proc_params, obj); 451fb279d8bSVesa Jääskeläinen if (rc) 452fb279d8bSVesa Jääskeläinen return rc; 453fb279d8bSVesa Jääskeläinen 454fb279d8bSVesa Jääskeläinen rc = load_tee_key(session, obj, function); 455fb279d8bSVesa Jääskeläinen if (rc) 456fb279d8bSVesa Jääskeläinen return rc; 457fb279d8bSVesa Jääskeläinen 458909efccbSEtienne Carriere rc = init_tee_operation(session, proc_params, obj); 459909efccbSEtienne Carriere if (!rc) 460909efccbSEtienne Carriere session->processing->mecha_type = proc_params->id; 461909efccbSEtienne Carriere 462909efccbSEtienne Carriere return rc; 463fb279d8bSVesa Jääskeläinen } 464fb279d8bSVesa Jääskeläinen 465fb279d8bSVesa Jääskeläinen /* 466fb279d8bSVesa Jääskeläinen * step_sym_step - step (update/oneshot/final) on a symmetric crypto operation 467fb279d8bSVesa Jääskeläinen * 468fb279d8bSVesa Jääskeläinen * @session - current session 469fb279d8bSVesa Jääskeläinen * @function - processing function (encrypt, decrypt, sign, ...) 470fb279d8bSVesa Jääskeläinen * @step - step ID in the processing (oneshot, update, final) 471fb279d8bSVesa Jääskeläinen * @ptypes - invocation parameter types 472fb279d8bSVesa Jääskeläinen * @params - invocation parameter references 473fb279d8bSVesa Jääskeläinen */ 474fb279d8bSVesa Jääskeläinen enum pkcs11_rc step_asymm_operation(struct pkcs11_session *session, 475fb279d8bSVesa Jääskeläinen enum processing_func function, 476fb279d8bSVesa Jääskeläinen enum processing_step step, 477fb279d8bSVesa Jääskeläinen uint32_t ptypes, TEE_Param *params) 478fb279d8bSVesa Jääskeläinen { 479fb279d8bSVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 480fb279d8bSVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 481fb279d8bSVesa Jääskeläinen void *in_buf = NULL; 482fb279d8bSVesa Jääskeläinen void *in2_buf = NULL; 483fb279d8bSVesa Jääskeläinen void *out_buf = NULL; 484fb279d8bSVesa Jääskeläinen void *hash_buf = NULL; 485*e02f17f3SAlexandre Marechal void *temp_buf = NULL; 486fb279d8bSVesa Jääskeläinen uint32_t in_size = 0; 487fb279d8bSVesa Jääskeläinen uint32_t in2_size = 0; 488c7f1b4f7SJens Wiklander size_t out_size = 0; 489c7f1b4f7SJens Wiklander size_t hash_size = 0; 490*e02f17f3SAlexandre Marechal size_t temp_size = 0; 491fb279d8bSVesa Jääskeläinen TEE_Attribute *tee_attrs = NULL; 492fb279d8bSVesa Jääskeläinen size_t tee_attrs_count = 0; 493fb279d8bSVesa Jääskeläinen bool output_data = false; 494fb279d8bSVesa Jääskeläinen struct active_processing *proc = session->processing; 49545d40bdaSValerii Chubar struct rsa_aes_key_wrap_processing_ctx *rsa_aes_ctx = NULL; 496dc8c77fcSVesa Jääskeläinen struct rsa_oaep_processing_ctx *rsa_oaep_ctx = NULL; 497d9af50bcSVesa Jääskeläinen struct rsa_pss_processing_ctx *rsa_pss_ctx = NULL; 49803e07432SValerii Chubar struct eddsa_processing_ctx *eddsa_ctx = NULL; 499fb279d8bSVesa Jääskeläinen size_t sz = 0; 500fb279d8bSVesa Jääskeläinen 501fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 502fb279d8bSVesa Jääskeläinen in_buf = params[1].memref.buffer; 503fb279d8bSVesa Jääskeläinen in_size = params[1].memref.size; 504fb279d8bSVesa Jääskeläinen if (in_size && !in_buf) 505fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 506fb279d8bSVesa Jääskeläinen } 507fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_INPUT) { 508fb279d8bSVesa Jääskeläinen in2_buf = params[2].memref.buffer; 509fb279d8bSVesa Jääskeläinen in2_size = params[2].memref.size; 510fb279d8bSVesa Jääskeläinen if (in2_size && !in2_buf) 511fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 512fb279d8bSVesa Jääskeläinen } 513fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 514fb279d8bSVesa Jääskeläinen out_buf = params[2].memref.buffer; 515fb279d8bSVesa Jääskeläinen out_size = params[2].memref.size; 516fb279d8bSVesa Jääskeläinen if (out_size && !out_buf) 517fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 518fb279d8bSVesa Jääskeläinen } 519fb279d8bSVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 520fb279d8bSVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 521fb279d8bSVesa Jääskeläinen 522fb279d8bSVesa Jääskeläinen switch (step) { 523fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_ONESHOT: 524fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE: 525fb279d8bSVesa Jääskeläinen case PKCS11_FUNC_STEP_FINAL: 526fb279d8bSVesa Jääskeläinen break; 527fb279d8bSVesa Jääskeläinen default: 528fb279d8bSVesa Jääskeläinen return PKCS11_CKR_GENERAL_ERROR; 529fb279d8bSVesa Jääskeläinen } 530fb279d8bSVesa Jääskeläinen 531d9af50bcSVesa Jääskeläinen /* TEE attribute(s) required by the operation */ 532d9af50bcSVesa Jääskeläinen switch (proc->mecha_type) { 533d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 534d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 535d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 536d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 537d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 538d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 539d9af50bcSVesa Jääskeläinen tee_attrs = TEE_Malloc(sizeof(TEE_Attribute), 540d9af50bcSVesa Jääskeläinen TEE_USER_MEM_HINT_NO_FILL_ZERO); 541d9af50bcSVesa Jääskeläinen if (!tee_attrs) { 542d9af50bcSVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY; 543d9af50bcSVesa Jääskeläinen goto out; 544d9af50bcSVesa Jääskeläinen } 545d9af50bcSVesa Jääskeläinen 546d9af50bcSVesa Jääskeläinen rsa_pss_ctx = proc->extra_ctx; 547d9af50bcSVesa Jääskeläinen 548d9af50bcSVesa Jääskeläinen TEE_InitValueAttribute(&tee_attrs[tee_attrs_count], 549d9af50bcSVesa Jääskeläinen TEE_ATTR_RSA_PSS_SALT_LENGTH, 550d9af50bcSVesa Jääskeläinen rsa_pss_ctx->salt_len, 0); 551d9af50bcSVesa Jääskeläinen tee_attrs_count++; 552d9af50bcSVesa Jääskeläinen break; 55303e07432SValerii Chubar case PKCS11_CKM_EDDSA: 55403e07432SValerii Chubar eddsa_ctx = proc->extra_ctx; 55503e07432SValerii Chubar 55603e07432SValerii Chubar tee_attrs = TEE_Malloc(2 * sizeof(TEE_Attribute), 55703e07432SValerii Chubar TEE_USER_MEM_HINT_NO_FILL_ZERO); 55803e07432SValerii Chubar if (!tee_attrs) { 55903e07432SValerii Chubar rc = PKCS11_CKR_DEVICE_MEMORY; 56003e07432SValerii Chubar goto out; 56103e07432SValerii Chubar } 56203e07432SValerii Chubar 56303e07432SValerii Chubar if (eddsa_ctx->flag) { 56403e07432SValerii Chubar TEE_InitValueAttribute(&tee_attrs[tee_attrs_count], 56503e07432SValerii Chubar TEE_ATTR_EDDSA_PREHASH, 0, 0); 56603e07432SValerii Chubar tee_attrs_count++; 56703e07432SValerii Chubar } 56803e07432SValerii Chubar 56903e07432SValerii Chubar if (eddsa_ctx->ctx_len > 0) { 57003e07432SValerii Chubar TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 57103e07432SValerii Chubar TEE_ATTR_EDDSA_CTX, eddsa_ctx->ctx, 57203e07432SValerii Chubar eddsa_ctx->ctx_len); 57303e07432SValerii Chubar tee_attrs_count++; 57403e07432SValerii Chubar } 57503e07432SValerii Chubar break; 576dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 577dc8c77fcSVesa Jääskeläinen rsa_oaep_ctx = proc->extra_ctx; 578dc8c77fcSVesa Jääskeläinen 579dc8c77fcSVesa Jääskeläinen if (!rsa_oaep_ctx->source_data_len) 580dc8c77fcSVesa Jääskeläinen break; 581dc8c77fcSVesa Jääskeläinen 582dc8c77fcSVesa Jääskeläinen tee_attrs = TEE_Malloc(sizeof(TEE_Attribute), 583dc8c77fcSVesa Jääskeläinen TEE_USER_MEM_HINT_NO_FILL_ZERO); 584dc8c77fcSVesa Jääskeläinen if (!tee_attrs) { 585dc8c77fcSVesa Jääskeläinen rc = PKCS11_CKR_DEVICE_MEMORY; 586dc8c77fcSVesa Jääskeläinen goto out; 587dc8c77fcSVesa Jääskeläinen } 588dc8c77fcSVesa Jääskeläinen 589dc8c77fcSVesa Jääskeläinen TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 590dc8c77fcSVesa Jääskeläinen TEE_ATTR_RSA_OAEP_LABEL, 591dc8c77fcSVesa Jääskeläinen rsa_oaep_ctx->source_data, 592dc8c77fcSVesa Jääskeläinen rsa_oaep_ctx->source_data_len); 593dc8c77fcSVesa Jääskeläinen tee_attrs_count++; 594dc8c77fcSVesa Jääskeläinen break; 59545d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 59645d40bdaSValerii Chubar rsa_aes_ctx = proc->extra_ctx; 59745d40bdaSValerii Chubar 59845d40bdaSValerii Chubar if (!rsa_aes_ctx->source_data_len) 59945d40bdaSValerii Chubar break; 60045d40bdaSValerii Chubar 60145d40bdaSValerii Chubar tee_attrs = TEE_Malloc(sizeof(TEE_Attribute), 60245d40bdaSValerii Chubar TEE_USER_MEM_HINT_NO_FILL_ZERO); 60345d40bdaSValerii Chubar if (!tee_attrs) { 60445d40bdaSValerii Chubar rc = PKCS11_CKR_DEVICE_MEMORY; 60545d40bdaSValerii Chubar goto out; 60645d40bdaSValerii Chubar } 60745d40bdaSValerii Chubar 60845d40bdaSValerii Chubar TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 60945d40bdaSValerii Chubar TEE_ATTR_RSA_OAEP_LABEL, 61045d40bdaSValerii Chubar rsa_aes_ctx->source_data, 61145d40bdaSValerii Chubar rsa_aes_ctx->source_data_len); 61245d40bdaSValerii Chubar tee_attrs_count++; 61345d40bdaSValerii Chubar break; 614d9af50bcSVesa Jääskeläinen default: 615d9af50bcSVesa Jääskeläinen break; 616d9af50bcSVesa Jääskeläinen } 617d9af50bcSVesa Jääskeläinen 618fb279d8bSVesa Jääskeläinen /* 619fb279d8bSVesa Jääskeläinen * Handle multi stage update step for mechas needing hash 620fb279d8bSVesa Jääskeläinen * calculation 621fb279d8bSVesa Jääskeläinen */ 622fb279d8bSVesa Jääskeläinen if (step == PKCS11_FUNC_STEP_UPDATE) { 623fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 624fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 625fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 626fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 627fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 628fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 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_SHA1_RSA_PKCS_PSS: 636d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 637d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 638d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 639d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 640571857c0SEtienne Carriere assert(proc->tee_op_handle2 != TEE_HANDLE_NULL); 641fb279d8bSVesa Jääskeläinen 642571857c0SEtienne Carriere TEE_DigestUpdate(proc->tee_op_handle2, in_buf, in_size); 6439df68186SEtienne Carriere rc = PKCS11_CKR_OK; 644fb279d8bSVesa Jääskeläinen break; 645fb279d8bSVesa Jääskeläinen default: 646fb279d8bSVesa Jääskeläinen /* 647fb279d8bSVesa Jääskeläinen * Other mechanism do not expect multi stage 648fb279d8bSVesa Jääskeläinen * operation 649fb279d8bSVesa Jääskeläinen */ 650fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_GENERAL_ERROR; 651fb279d8bSVesa Jääskeläinen break; 652fb279d8bSVesa Jääskeläinen } 653fb279d8bSVesa Jääskeläinen 654fb279d8bSVesa Jääskeläinen goto out; 655fb279d8bSVesa Jääskeläinen } 656fb279d8bSVesa Jääskeläinen 657fb279d8bSVesa Jääskeläinen /* 658fb279d8bSVesa Jääskeläinen * Handle multi stage one shot and final steps for mechas needing hash 659fb279d8bSVesa Jääskeläinen * calculation 660fb279d8bSVesa Jääskeläinen */ 661fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 662fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 663fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 664fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 665fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 666fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 6670442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 6680442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 6690442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 6700442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 6710442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 6720442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 673d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 674d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 675d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 676d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 677d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 678571857c0SEtienne Carriere assert(proc->tee_op_handle2 != TEE_HANDLE_NULL); 679fb279d8bSVesa Jääskeläinen 680fb279d8bSVesa Jääskeläinen hash_size = TEE_ALG_GET_DIGEST_SIZE(proc->tee_hash_algo); 681fb279d8bSVesa Jääskeläinen hash_buf = TEE_Malloc(hash_size, 0); 682fb279d8bSVesa Jääskeläinen if (!hash_buf) 683fb279d8bSVesa Jääskeläinen return PKCS11_CKR_DEVICE_MEMORY; 684fb279d8bSVesa Jääskeläinen 685571857c0SEtienne Carriere res = TEE_DigestDoFinal(proc->tee_op_handle2, in_buf, in_size, 686571857c0SEtienne Carriere hash_buf, &hash_size); 687fb279d8bSVesa Jääskeläinen 688fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 689fb279d8bSVesa Jääskeläinen if (rc != PKCS11_CKR_OK) 690fb279d8bSVesa Jääskeläinen goto out; 691fb279d8bSVesa Jääskeläinen 692fb279d8bSVesa Jääskeläinen break; 693fb279d8bSVesa Jääskeläinen default: 694fb279d8bSVesa Jääskeläinen break; 695fb279d8bSVesa Jääskeläinen } 696fb279d8bSVesa Jääskeläinen 697fb279d8bSVesa Jääskeläinen /* 698fb279d8bSVesa Jääskeläinen * Finalize either provided hash or calculated hash with signing 699fb279d8bSVesa Jääskeläinen * operation 700fb279d8bSVesa Jääskeläinen */ 701fb279d8bSVesa Jääskeläinen 702fb279d8bSVesa Jääskeläinen /* First determine amount of bytes for signing operation */ 703fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 704fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 705fb279d8bSVesa Jääskeläinen sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle); 706fb279d8bSVesa Jääskeläinen if (!in_size || !sz) { 707fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 708fb279d8bSVesa Jääskeläinen goto out; 709fb279d8bSVesa Jääskeläinen } 710fb279d8bSVesa Jääskeläinen 711fb279d8bSVesa Jääskeläinen /* 712fb279d8bSVesa Jääskeläinen * Note 3) Input the entire raw digest. Internally, this will 713fb279d8bSVesa Jääskeläinen * be truncated to the appropriate number of bits. 714fb279d8bSVesa Jääskeläinen */ 715fb279d8bSVesa Jääskeläinen if (in_size > sz) 716fb279d8bSVesa Jääskeläinen in_size = sz; 717fb279d8bSVesa Jääskeläinen 718fb279d8bSVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && in2_size != 2 * sz) { 719fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 720fb279d8bSVesa Jääskeläinen goto out; 721fb279d8bSVesa Jääskeläinen } 722fb279d8bSVesa Jääskeläinen break; 723fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 724fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 725fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 726fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 727fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 728fb279d8bSVesa Jääskeläinen /* Get key size in bytes */ 729fb279d8bSVesa Jääskeläinen sz = ecdsa_get_input_max_byte_size(proc->tee_op_handle); 730fb279d8bSVesa Jääskeläinen if (!sz) { 731fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 732fb279d8bSVesa Jääskeläinen goto out; 733fb279d8bSVesa Jääskeläinen } 734fb279d8bSVesa Jääskeläinen 735fb279d8bSVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && 736fb279d8bSVesa Jääskeläinen in2_size != 2 * sz) { 737fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 738fb279d8bSVesa Jääskeläinen goto out; 739fb279d8bSVesa Jääskeläinen } 740fb279d8bSVesa Jääskeläinen break; 7410442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 742*e02f17f3SAlexandre Marechal case PKCS11_CKM_RSA_X_509: 7430442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 7440442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 7450442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 7460442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 7470442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 7480442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 749d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 750d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 751d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 752d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 753d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 754d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 7550442c956SVesa Jääskeläinen /* Get key size in bytes */ 7560442c956SVesa Jääskeläinen sz = rsa_get_input_max_byte_size(proc->tee_op_handle); 7570442c956SVesa Jääskeläinen if (!sz) { 7580442c956SVesa Jääskeläinen rc = PKCS11_CKR_FUNCTION_FAILED; 7590442c956SVesa Jääskeläinen goto out; 7600442c956SVesa Jääskeläinen } 7610442c956SVesa Jääskeläinen 7620442c956SVesa Jääskeläinen if (function == PKCS11_FUNCTION_VERIFY && in2_size != sz) { 7630442c956SVesa Jääskeläinen rc = PKCS11_CKR_SIGNATURE_LEN_RANGE; 7640442c956SVesa Jääskeläinen goto out; 7650442c956SVesa Jääskeläinen } 7660442c956SVesa Jääskeläinen break; 767fb279d8bSVesa Jääskeläinen default: 768fb279d8bSVesa Jääskeläinen break; 769fb279d8bSVesa Jääskeläinen } 770fb279d8bSVesa Jääskeläinen 771fb279d8bSVesa Jääskeläinen /* Next perform actual signing operation */ 772fb279d8bSVesa Jääskeläinen switch (proc->mecha_type) { 773fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA: 77403e07432SValerii Chubar case PKCS11_CKM_EDDSA: 7750442c956SVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS: 776dc8c77fcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_OAEP: 777d9af50bcSVesa Jääskeläinen case PKCS11_CKM_RSA_PKCS_PSS: 778fb279d8bSVesa Jääskeläinen /* For operations using provided input data */ 779fb279d8bSVesa Jääskeläinen switch (function) { 780fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_ENCRYPT: 781fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricEncrypt(proc->tee_op_handle, 782fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count, 783fb279d8bSVesa Jääskeläinen in_buf, in_size, 784fb279d8bSVesa Jääskeläinen out_buf, &out_size); 785fb279d8bSVesa Jääskeläinen output_data = true; 786fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 7876a6299fbSVesa Jääskeläinen if (rc == PKCS11_CKR_ARGUMENTS_BAD) 7886a6299fbSVesa Jääskeläinen rc = PKCS11_CKR_DATA_LEN_RANGE; 789fb279d8bSVesa Jääskeläinen break; 790fb279d8bSVesa Jääskeläinen 791fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_DECRYPT: 792fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricDecrypt(proc->tee_op_handle, 793fb279d8bSVesa Jääskeläinen tee_attrs, tee_attrs_count, 794fb279d8bSVesa Jääskeläinen in_buf, in_size, 795fb279d8bSVesa Jääskeläinen out_buf, &out_size); 796fb279d8bSVesa Jääskeläinen output_data = true; 797fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 798f27310a5SVesa Jääskeläinen if (rc == PKCS11_CKR_ARGUMENTS_BAD) 799f27310a5SVesa Jääskeläinen rc = PKCS11_CKR_ENCRYPTED_DATA_LEN_RANGE; 800fb279d8bSVesa Jääskeläinen break; 801fb279d8bSVesa Jääskeläinen 802fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_SIGN: 803fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricSignDigest(proc->tee_op_handle, 804fb279d8bSVesa Jääskeläinen tee_attrs, 805fb279d8bSVesa Jääskeläinen tee_attrs_count, 806fb279d8bSVesa Jääskeläinen in_buf, in_size, 807fb279d8bSVesa Jääskeläinen out_buf, &out_size); 808fb279d8bSVesa Jääskeläinen output_data = true; 809fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 810fb279d8bSVesa Jääskeläinen break; 811fb279d8bSVesa Jääskeläinen 812fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_VERIFY: 813fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle, 814fb279d8bSVesa Jääskeläinen tee_attrs, 815fb279d8bSVesa Jääskeläinen tee_attrs_count, 816fb279d8bSVesa Jääskeläinen in_buf, in_size, 817fb279d8bSVesa Jääskeläinen in2_buf, in2_size); 818fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 819fb279d8bSVesa Jääskeläinen break; 820fb279d8bSVesa Jääskeläinen 821fb279d8bSVesa Jääskeläinen default: 822fb279d8bSVesa Jääskeläinen TEE_Panic(function); 823fb279d8bSVesa Jääskeläinen break; 824fb279d8bSVesa Jääskeläinen } 825fb279d8bSVesa Jääskeläinen break; 826*e02f17f3SAlexandre Marechal 827*e02f17f3SAlexandre Marechal case PKCS11_CKM_RSA_X_509: 828*e02f17f3SAlexandre Marechal switch (function) { 829*e02f17f3SAlexandre Marechal case PKCS11_FUNCTION_SIGN: 830*e02f17f3SAlexandre Marechal /* 831*e02f17f3SAlexandre Marechal * GP TEE API only allows Decrypt, not Verify operation, 832*e02f17f3SAlexandre Marechal * on TEE_ALG_RSA_NOPAD. Be a bit strict on the size and 833*e02f17f3SAlexandre Marechal * content of the message and ensure the generate 834*e02f17f3SAlexandre Marechal * signature as the size of the modulus (@sz here). 835*e02f17f3SAlexandre Marechal * 836*e02f17f3SAlexandre Marechal * It remains the responsibility of the client to have 837*e02f17f3SAlexandre Marechal * a safe padding scheme for the provided message data. 838*e02f17f3SAlexandre Marechal */ 839*e02f17f3SAlexandre Marechal if (in_size != sz) { 840*e02f17f3SAlexandre Marechal EMSG("Invalid data size %"PRIu32" != %zu", 841*e02f17f3SAlexandre Marechal in_size, sz); 842*e02f17f3SAlexandre Marechal rc = PKCS11_CKR_DATA_LEN_RANGE; 843*e02f17f3SAlexandre Marechal break; 844*e02f17f3SAlexandre Marechal } 845*e02f17f3SAlexandre Marechal 846*e02f17f3SAlexandre Marechal if (out_size < sz) { 847*e02f17f3SAlexandre Marechal rc = PKCS11_CKR_BUFFER_TOO_SMALL; 848*e02f17f3SAlexandre Marechal out_size = sz; 849*e02f17f3SAlexandre Marechal output_data = true; 850*e02f17f3SAlexandre Marechal break; 851*e02f17f3SAlexandre Marechal } 852*e02f17f3SAlexandre Marechal 853*e02f17f3SAlexandre Marechal temp_size = sz; 854*e02f17f3SAlexandre Marechal temp_buf = proc->extra_ctx; 855*e02f17f3SAlexandre Marechal res = TEE_AsymmetricDecrypt(proc->tee_op_handle, 856*e02f17f3SAlexandre Marechal tee_attrs, tee_attrs_count, 857*e02f17f3SAlexandre Marechal in_buf, in_size, 858*e02f17f3SAlexandre Marechal temp_buf, &temp_size); 859*e02f17f3SAlexandre Marechal if (!res && temp_size != sz) { 860*e02f17f3SAlexandre Marechal EMSG("CMK_RSA_X509: signature size %zu != %zu", 861*e02f17f3SAlexandre Marechal temp_size, sz); 862*e02f17f3SAlexandre Marechal rc = PKCS11_CKR_DATA_INVALID; 863*e02f17f3SAlexandre Marechal break; 864*e02f17f3SAlexandre Marechal } 865*e02f17f3SAlexandre Marechal if (!res) { 866*e02f17f3SAlexandre Marechal TEE_MemMove(out_buf, temp_buf, sz); 867*e02f17f3SAlexandre Marechal TEE_MemFill(temp_buf, 0xa5, sz); 868*e02f17f3SAlexandre Marechal } 869*e02f17f3SAlexandre Marechal output_data = true; 870*e02f17f3SAlexandre Marechal rc = tee2pkcs_error(res); 871*e02f17f3SAlexandre Marechal out_size = sz; 872*e02f17f3SAlexandre Marechal break; 873*e02f17f3SAlexandre Marechal case PKCS11_FUNCTION_VERIFY: 874*e02f17f3SAlexandre Marechal /* 875*e02f17f3SAlexandre Marechal * GP TEE API only allows Encrypt, not Verify operation, 876*e02f17f3SAlexandre Marechal * on TEE_ALG_RSA_NOPAD. Encrypt signature in 877*e02f17f3SAlexandre Marechal * temporary buffer preallocated to the size of the key. 878*e02f17f3SAlexandre Marechal */ 879*e02f17f3SAlexandre Marechal temp_size = sz; 880*e02f17f3SAlexandre Marechal temp_buf = proc->extra_ctx; 881*e02f17f3SAlexandre Marechal res = TEE_AsymmetricEncrypt(proc->tee_op_handle, 882*e02f17f3SAlexandre Marechal tee_attrs, tee_attrs_count, 883*e02f17f3SAlexandre Marechal in2_buf, in2_size, 884*e02f17f3SAlexandre Marechal temp_buf, &temp_size); 885*e02f17f3SAlexandre Marechal rc = tee2pkcs_error(res); 886*e02f17f3SAlexandre Marechal if (rc == PKCS11_CKR_OK) { 887*e02f17f3SAlexandre Marechal /* 888*e02f17f3SAlexandre Marechal * Skip nul bytes heading message before 889*e02f17f3SAlexandre Marechal * comparing encrypted signature. 890*e02f17f3SAlexandre Marechal */ 891*e02f17f3SAlexandre Marechal char *ptr = in_buf; 892*e02f17f3SAlexandre Marechal size_t n = 0; 893*e02f17f3SAlexandre Marechal 894*e02f17f3SAlexandre Marechal for (n = 0; n < in_size; n++) 895*e02f17f3SAlexandre Marechal if (ptr[n]) 896*e02f17f3SAlexandre Marechal break; 897*e02f17f3SAlexandre Marechal in_size -= n; 898*e02f17f3SAlexandre Marechal ptr += n; 899*e02f17f3SAlexandre Marechal if (n > 1) 900*e02f17f3SAlexandre Marechal IMSG("Unsafe signature: skip %zu bytes", 901*e02f17f3SAlexandre Marechal n); 902*e02f17f3SAlexandre Marechal 903*e02f17f3SAlexandre Marechal if (temp_size != in_size || 904*e02f17f3SAlexandre Marechal consttime_memcmp(temp_buf, ptr, in_size)) 905*e02f17f3SAlexandre Marechal rc = PKCS11_CKR_SIGNATURE_INVALID; 906*e02f17f3SAlexandre Marechal } 907*e02f17f3SAlexandre Marechal break; 908*e02f17f3SAlexandre Marechal default: 909*e02f17f3SAlexandre Marechal TEE_Panic(function); 910*e02f17f3SAlexandre Marechal break; 911*e02f17f3SAlexandre Marechal } 912*e02f17f3SAlexandre Marechal break; 913*e02f17f3SAlexandre Marechal 914fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA1: 915fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA224: 916fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA256: 917fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA384: 918fb279d8bSVesa Jääskeläinen case PKCS11_CKM_ECDSA_SHA512: 9190442c956SVesa Jääskeläinen case PKCS11_CKM_MD5_RSA_PKCS: 9200442c956SVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS: 9210442c956SVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS: 9220442c956SVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS: 9230442c956SVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS: 9240442c956SVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS: 925d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA1_RSA_PKCS_PSS: 926d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA224_RSA_PKCS_PSS: 927d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA256_RSA_PKCS_PSS: 928d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA384_RSA_PKCS_PSS: 929d9af50bcSVesa Jääskeläinen case PKCS11_CKM_SHA512_RSA_PKCS_PSS: 930fb279d8bSVesa Jääskeläinen /* For operations having hash operation use calculated hash */ 931fb279d8bSVesa Jääskeläinen switch (function) { 932fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_SIGN: 933fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricSignDigest(proc->tee_op_handle, 934fb279d8bSVesa Jääskeläinen tee_attrs, 935fb279d8bSVesa Jääskeläinen tee_attrs_count, 936fb279d8bSVesa Jääskeläinen hash_buf, hash_size, 937fb279d8bSVesa Jääskeläinen out_buf, &out_size); 938fb279d8bSVesa Jääskeläinen output_data = true; 939fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 940fb279d8bSVesa Jääskeläinen break; 941fb279d8bSVesa Jääskeläinen 942fb279d8bSVesa Jääskeläinen case PKCS11_FUNCTION_VERIFY: 943fb279d8bSVesa Jääskeläinen res = TEE_AsymmetricVerifyDigest(proc->tee_op_handle, 944fb279d8bSVesa Jääskeläinen tee_attrs, 945fb279d8bSVesa Jääskeläinen tee_attrs_count, 946fb279d8bSVesa Jääskeläinen hash_buf, hash_size, 947fb279d8bSVesa Jääskeläinen in2_buf, in2_size); 948fb279d8bSVesa Jääskeläinen rc = tee2pkcs_error(res); 949fb279d8bSVesa Jääskeläinen break; 950fb279d8bSVesa Jääskeläinen 951fb279d8bSVesa Jääskeläinen default: 952fb279d8bSVesa Jääskeläinen TEE_Panic(function); 953fb279d8bSVesa Jääskeläinen break; 954fb279d8bSVesa Jääskeläinen } 955fb279d8bSVesa Jääskeläinen break; 956fb279d8bSVesa Jääskeläinen default: 957fb279d8bSVesa Jääskeläinen TEE_Panic(proc->mecha_type); 958fb279d8bSVesa Jääskeläinen break; 959fb279d8bSVesa Jääskeläinen } 960fb279d8bSVesa Jääskeläinen 961fb279d8bSVesa Jääskeläinen out: 962fb279d8bSVesa Jääskeläinen if (output_data && 963fb279d8bSVesa Jääskeläinen (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL)) { 964fb279d8bSVesa Jääskeläinen switch (TEE_PARAM_TYPE_GET(ptypes, 2)) { 965fb279d8bSVesa Jääskeläinen case TEE_PARAM_TYPE_MEMREF_OUTPUT: 966fb279d8bSVesa Jääskeläinen case TEE_PARAM_TYPE_MEMREF_INOUT: 967fb279d8bSVesa Jääskeläinen params[2].memref.size = out_size; 968fb279d8bSVesa Jääskeläinen break; 969fb279d8bSVesa Jääskeläinen default: 970fb279d8bSVesa Jääskeläinen rc = PKCS11_CKR_GENERAL_ERROR; 971fb279d8bSVesa Jääskeläinen break; 972fb279d8bSVesa Jääskeläinen } 973fb279d8bSVesa Jääskeläinen } 974fb279d8bSVesa Jääskeläinen 975fb279d8bSVesa Jääskeläinen TEE_Free(hash_buf); 976fb279d8bSVesa Jääskeläinen TEE_Free(tee_attrs); 977fb279d8bSVesa Jääskeläinen 978fb279d8bSVesa Jääskeläinen return rc; 979fb279d8bSVesa Jääskeläinen } 980cc062b46SJorge Ramirez-Ortiz 981cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc do_asymm_derivation(struct pkcs11_session *session, 982cc062b46SJorge Ramirez-Ortiz struct pkcs11_attribute_head *proc_params, 983cc062b46SJorge Ramirez-Ortiz struct obj_attrs **head) 984cc062b46SJorge Ramirez-Ortiz { 985cc062b46SJorge Ramirez-Ortiz enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 986cc062b46SJorge Ramirez-Ortiz TEE_ObjectHandle out_handle = TEE_HANDLE_NULL; 987cc062b46SJorge Ramirez-Ortiz TEE_Result res = TEE_ERROR_GENERIC; 988cc062b46SJorge Ramirez-Ortiz TEE_Attribute tee_attrs[2] = { }; 989cc062b46SJorge Ramirez-Ortiz size_t tee_attrs_count = 0; 990cc062b46SJorge Ramirez-Ortiz uint32_t key_byte_size = 0; 991cc062b46SJorge Ramirez-Ortiz uint32_t key_bit_size = 0; 992cc062b46SJorge Ramirez-Ortiz void *a_ptr = NULL; 993cc062b46SJorge Ramirez-Ortiz size_t a_size = 0; 994cc062b46SJorge Ramirez-Ortiz 995cc062b46SJorge Ramirez-Ortiz /* Remove default attribute set at template sanitization */ 996cc062b46SJorge Ramirez-Ortiz if (remove_empty_attribute(head, PKCS11_CKA_VALUE)) 997cc062b46SJorge Ramirez-Ortiz return PKCS11_CKR_FUNCTION_FAILED; 998cc062b46SJorge Ramirez-Ortiz 999cc062b46SJorge Ramirez-Ortiz rc = get_u32_attribute(*head, PKCS11_CKA_VALUE_LEN, &key_bit_size); 1000cc062b46SJorge Ramirez-Ortiz if (rc) 1001cc062b46SJorge Ramirez-Ortiz return rc; 1002cc062b46SJorge Ramirez-Ortiz 1003cc062b46SJorge Ramirez-Ortiz key_bit_size *= 8; 1004cc062b46SJorge Ramirez-Ortiz key_byte_size = (key_bit_size + 7) / 8; 1005cc062b46SJorge Ramirez-Ortiz 1006cc062b46SJorge Ramirez-Ortiz res = TEE_AllocateTransientObject(TEE_TYPE_GENERIC_SECRET, 1007cc062b46SJorge Ramirez-Ortiz key_byte_size * 8, &out_handle); 1008cc062b46SJorge Ramirez-Ortiz if (res) { 1009cc062b46SJorge Ramirez-Ortiz DMSG("TEE_AllocateTransientObject failed, %#"PRIx32, res); 1010cc062b46SJorge Ramirez-Ortiz return tee2pkcs_error(res); 1011cc062b46SJorge Ramirez-Ortiz } 1012cc062b46SJorge Ramirez-Ortiz 1013cc062b46SJorge Ramirez-Ortiz switch (proc_params->id) { 1014cc062b46SJorge Ramirez-Ortiz case PKCS11_CKM_ECDH1_DERIVE: 1015cc062b46SJorge Ramirez-Ortiz rc = pkcs2tee_param_ecdh(proc_params, &a_ptr, &a_size); 1016cc062b46SJorge Ramirez-Ortiz if (rc) 1017cc062b46SJorge Ramirez-Ortiz goto out; 1018cc062b46SJorge Ramirez-Ortiz 1019cc062b46SJorge Ramirez-Ortiz TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 1020cc062b46SJorge Ramirez-Ortiz TEE_ATTR_ECC_PUBLIC_VALUE_X, 1021cc062b46SJorge Ramirez-Ortiz a_ptr, a_size / 2); 1022cc062b46SJorge Ramirez-Ortiz tee_attrs_count++; 1023cc062b46SJorge Ramirez-Ortiz TEE_InitRefAttribute(&tee_attrs[tee_attrs_count], 1024cc062b46SJorge Ramirez-Ortiz TEE_ATTR_ECC_PUBLIC_VALUE_Y, 1025cc062b46SJorge Ramirez-Ortiz (char *)a_ptr + a_size / 2, 1026cc062b46SJorge Ramirez-Ortiz a_size / 2); 1027cc062b46SJorge Ramirez-Ortiz tee_attrs_count++; 1028cc062b46SJorge Ramirez-Ortiz break; 1029cc062b46SJorge Ramirez-Ortiz default: 1030cc062b46SJorge Ramirez-Ortiz TEE_Panic(proc_params->id); 1031cc062b46SJorge Ramirez-Ortiz break; 1032cc062b46SJorge Ramirez-Ortiz } 1033cc062b46SJorge Ramirez-Ortiz 1034cc062b46SJorge Ramirez-Ortiz TEE_DeriveKey(session->processing->tee_op_handle, &tee_attrs[0], 1035cc062b46SJorge Ramirez-Ortiz tee_attrs_count, out_handle); 1036cc062b46SJorge Ramirez-Ortiz 1037cc062b46SJorge Ramirez-Ortiz rc = alloc_get_tee_attribute_data(out_handle, TEE_ATTR_SECRET_VALUE, 1038cc062b46SJorge Ramirez-Ortiz &a_ptr, &a_size); 1039cc062b46SJorge Ramirez-Ortiz if (rc) 1040cc062b46SJorge Ramirez-Ortiz goto out; 1041cc062b46SJorge Ramirez-Ortiz 1042cc062b46SJorge Ramirez-Ortiz if (a_size * 8 < key_bit_size) 1043cc062b46SJorge Ramirez-Ortiz rc = PKCS11_CKR_KEY_SIZE_RANGE; 1044cc062b46SJorge Ramirez-Ortiz else 1045cc062b46SJorge Ramirez-Ortiz rc = add_attribute(head, PKCS11_CKA_VALUE, a_ptr, 1046cc062b46SJorge Ramirez-Ortiz key_byte_size); 1047cc062b46SJorge Ramirez-Ortiz TEE_Free(a_ptr); 1048cc062b46SJorge Ramirez-Ortiz out: 1049cc062b46SJorge Ramirez-Ortiz release_active_processing(session); 1050cc062b46SJorge Ramirez-Ortiz TEE_FreeTransientObject(out_handle); 1051cc062b46SJorge Ramirez-Ortiz 1052cc062b46SJorge Ramirez-Ortiz return rc; 1053cc062b46SJorge Ramirez-Ortiz } 105445d40bdaSValerii Chubar 105545d40bdaSValerii Chubar static enum pkcs11_rc wrap_rsa_aes_key(struct active_processing *proc, 105645d40bdaSValerii Chubar void *data, uint32_t data_sz, 105745d40bdaSValerii Chubar void *out_buf, uint32_t *out_sz) 105845d40bdaSValerii Chubar { 105945d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_OK; 106045d40bdaSValerii Chubar TEE_Result res = TEE_ERROR_GENERIC; 106145d40bdaSValerii Chubar int mbedtls_rc = 0; 106245d40bdaSValerii Chubar struct rsa_aes_key_wrap_processing_ctx *ctx = proc->extra_ctx; 106345d40bdaSValerii Chubar mbedtls_nist_kw_context kw_ctx = { }; 106445d40bdaSValerii Chubar uint8_t aes_key_value[32] = { }; 106545d40bdaSValerii Chubar uint32_t aes_key_size = ctx->aes_key_bits / 8; 1066c7f1b4f7SJens Wiklander size_t aes_wrapped_size = *out_sz; 106745d40bdaSValerii Chubar uint32_t expected_size = 0; 106845d40bdaSValerii Chubar size_t target_key_size = 0; 106945d40bdaSValerii Chubar const size_t kw_semiblock_len = 8; 107045d40bdaSValerii Chubar 107145d40bdaSValerii Chubar if (ctx->aes_key_bits != 128 && 107245d40bdaSValerii Chubar ctx->aes_key_bits != 192 && 107345d40bdaSValerii Chubar ctx->aes_key_bits != 256) 107445d40bdaSValerii Chubar return PKCS11_CKR_ARGUMENTS_BAD; 107545d40bdaSValerii Chubar 107645d40bdaSValerii Chubar mbedtls_nist_kw_init(&kw_ctx); 107745d40bdaSValerii Chubar TEE_GenerateRandom(aes_key_value, aes_key_size); 107845d40bdaSValerii Chubar res = TEE_AsymmetricEncrypt(proc->tee_op_handle, 107945d40bdaSValerii Chubar NULL, 0, 108045d40bdaSValerii Chubar aes_key_value, aes_key_size, 108145d40bdaSValerii Chubar out_buf, &aes_wrapped_size); 108245d40bdaSValerii Chubar expected_size = aes_wrapped_size + data_sz + kw_semiblock_len; 108345d40bdaSValerii Chubar if (res) { 108445d40bdaSValerii Chubar if (res == TEE_ERROR_SHORT_BUFFER) 108545d40bdaSValerii Chubar *out_sz = expected_size; 108645d40bdaSValerii Chubar 108745d40bdaSValerii Chubar rc = tee2pkcs_error(res); 108845d40bdaSValerii Chubar goto out; 108945d40bdaSValerii Chubar } 109045d40bdaSValerii Chubar 109145d40bdaSValerii Chubar if (*out_sz < expected_size) { 109245d40bdaSValerii Chubar rc = PKCS11_CKR_BUFFER_TOO_SMALL; 109345d40bdaSValerii Chubar *out_sz = expected_size; 109445d40bdaSValerii Chubar goto out; 109545d40bdaSValerii Chubar } 109645d40bdaSValerii Chubar 109745d40bdaSValerii Chubar mbedtls_rc = mbedtls_nist_kw_setkey(&kw_ctx, MBEDTLS_CIPHER_ID_AES, 109845d40bdaSValerii Chubar aes_key_value, ctx->aes_key_bits, 109945d40bdaSValerii Chubar true); 110045d40bdaSValerii Chubar if (mbedtls_rc) { 110145d40bdaSValerii Chubar if (mbedtls_rc == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) 110245d40bdaSValerii Chubar rc = PKCS11_CKR_KEY_SIZE_RANGE; 110345d40bdaSValerii Chubar else 110445d40bdaSValerii Chubar rc = PKCS11_CKR_FUNCTION_FAILED; 110545d40bdaSValerii Chubar 110645d40bdaSValerii Chubar goto out; 110745d40bdaSValerii Chubar } 110845d40bdaSValerii Chubar 110945d40bdaSValerii Chubar mbedtls_rc = mbedtls_nist_kw_wrap(&kw_ctx, MBEDTLS_KW_MODE_KWP, 111045d40bdaSValerii Chubar data, data_sz, 111145d40bdaSValerii Chubar (uint8_t *)out_buf + aes_wrapped_size, 111245d40bdaSValerii Chubar &target_key_size, 111345d40bdaSValerii Chubar *out_sz - aes_wrapped_size); 111445d40bdaSValerii Chubar if (mbedtls_rc) { 111545d40bdaSValerii Chubar rc = PKCS11_CKR_ARGUMENTS_BAD; 111645d40bdaSValerii Chubar goto out; 111745d40bdaSValerii Chubar } 111845d40bdaSValerii Chubar 111945d40bdaSValerii Chubar assert(*out_sz >= target_key_size + aes_wrapped_size); 112045d40bdaSValerii Chubar *out_sz = target_key_size + aes_wrapped_size; 112145d40bdaSValerii Chubar 112245d40bdaSValerii Chubar out: 112345d40bdaSValerii Chubar mbedtls_nist_kw_free(&kw_ctx); 112445d40bdaSValerii Chubar TEE_MemFill(aes_key_value, 0, aes_key_size); 112545d40bdaSValerii Chubar return rc; 112645d40bdaSValerii Chubar } 112745d40bdaSValerii Chubar 112845d40bdaSValerii Chubar static enum pkcs11_rc unwrap_rsa_aes_key(struct active_processing *proc, 112945d40bdaSValerii Chubar void *data, uint32_t data_sz, 113045d40bdaSValerii Chubar void **out_buf, uint32_t *out_sz) 113145d40bdaSValerii Chubar { 113245d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_OK; 113345d40bdaSValerii Chubar int mbedtls_rc = 0; 113445d40bdaSValerii Chubar TEE_Result res = TEE_ERROR_GENERIC; 113545d40bdaSValerii Chubar TEE_OperationInfo info = { }; 113645d40bdaSValerii Chubar struct rsa_aes_key_wrap_processing_ctx *ctx = proc->extra_ctx; 113745d40bdaSValerii Chubar mbedtls_nist_kw_context kw_ctx = { }; 113845d40bdaSValerii Chubar uint8_t aes_key_value[32] = { }; 1139c7f1b4f7SJens Wiklander size_t aes_key_size = ctx->aes_key_bits / 8; 114045d40bdaSValerii Chubar uint32_t wrapped_key_size = 0; 114145d40bdaSValerii Chubar uint32_t rsa_key_size = 0; 114245d40bdaSValerii Chubar size_t target_key_size = 0; 114345d40bdaSValerii Chubar 114445d40bdaSValerii Chubar if (ctx->aes_key_bits != 128 && 114545d40bdaSValerii Chubar ctx->aes_key_bits != 192 && 114645d40bdaSValerii Chubar ctx->aes_key_bits != 256) 114745d40bdaSValerii Chubar return PKCS11_CKR_ARGUMENTS_BAD; 114845d40bdaSValerii Chubar 114945d40bdaSValerii Chubar TEE_GetOperationInfo(proc->tee_op_handle, &info); 115045d40bdaSValerii Chubar rsa_key_size = info.keySize / 8; 115145d40bdaSValerii Chubar wrapped_key_size = data_sz - rsa_key_size; 115245d40bdaSValerii Chubar target_key_size = wrapped_key_size - 8; 115345d40bdaSValerii Chubar 115445d40bdaSValerii Chubar *out_buf = TEE_Malloc(target_key_size, TEE_MALLOC_FILL_ZERO); 115545d40bdaSValerii Chubar if (!*out_buf) 115645d40bdaSValerii Chubar return PKCS11_CKR_DEVICE_MEMORY; 115745d40bdaSValerii Chubar 115845d40bdaSValerii Chubar mbedtls_nist_kw_init(&kw_ctx); 115945d40bdaSValerii Chubar res = TEE_AsymmetricDecrypt(proc->tee_op_handle, 116045d40bdaSValerii Chubar NULL, 0, 116145d40bdaSValerii Chubar data, rsa_key_size, 116245d40bdaSValerii Chubar aes_key_value, &aes_key_size); 116345d40bdaSValerii Chubar if (res) { 116445d40bdaSValerii Chubar rc = tee2pkcs_error(res); 116545d40bdaSValerii Chubar goto out; 116645d40bdaSValerii Chubar } 116745d40bdaSValerii Chubar 116845d40bdaSValerii Chubar mbedtls_rc = mbedtls_nist_kw_setkey(&kw_ctx, MBEDTLS_CIPHER_ID_AES, 116945d40bdaSValerii Chubar aes_key_value, ctx->aes_key_bits, 117045d40bdaSValerii Chubar false); 117145d40bdaSValerii Chubar if (mbedtls_rc) { 117245d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 117345d40bdaSValerii Chubar goto out; 117445d40bdaSValerii Chubar } 117545d40bdaSValerii Chubar 117645d40bdaSValerii Chubar mbedtls_rc = mbedtls_nist_kw_unwrap(&kw_ctx, MBEDTLS_KW_MODE_KWP, 117745d40bdaSValerii Chubar (uint8_t *)data + rsa_key_size, 117845d40bdaSValerii Chubar wrapped_key_size, *out_buf, 117945d40bdaSValerii Chubar &target_key_size, target_key_size); 118045d40bdaSValerii Chubar if (mbedtls_rc) { 118145d40bdaSValerii Chubar rc = PKCS11_CKR_WRAPPED_KEY_INVALID; 118245d40bdaSValerii Chubar goto out; 118345d40bdaSValerii Chubar } 118445d40bdaSValerii Chubar 118545d40bdaSValerii Chubar *out_sz = target_key_size; 118645d40bdaSValerii Chubar out: 118745d40bdaSValerii Chubar TEE_MemFill(aes_key_value, 0, aes_key_size); 118845d40bdaSValerii Chubar mbedtls_nist_kw_free(&kw_ctx); 118945d40bdaSValerii Chubar return rc; 119045d40bdaSValerii Chubar } 119145d40bdaSValerii Chubar 119245d40bdaSValerii Chubar enum pkcs11_rc wrap_data_by_asymm_enc(struct pkcs11_session *session, 119345d40bdaSValerii Chubar void *data, uint32_t data_sz, 119445d40bdaSValerii Chubar void *out_buf, uint32_t *out_sz) 119545d40bdaSValerii Chubar { 119645d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 119745d40bdaSValerii Chubar struct active_processing *proc = session->processing; 119845d40bdaSValerii Chubar 119945d40bdaSValerii Chubar switch (proc->mecha_type) { 120045d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 120145d40bdaSValerii Chubar rc = wrap_rsa_aes_key(proc, data, data_sz, out_buf, out_sz); 120245d40bdaSValerii Chubar break; 120345d40bdaSValerii Chubar default: 120445d40bdaSValerii Chubar return PKCS11_CKR_MECHANISM_INVALID; 120545d40bdaSValerii Chubar } 120645d40bdaSValerii Chubar 120745d40bdaSValerii Chubar return rc; 120845d40bdaSValerii Chubar } 120945d40bdaSValerii Chubar 121045d40bdaSValerii Chubar enum pkcs11_rc unwrap_key_by_asymm(struct pkcs11_session *session, 121145d40bdaSValerii Chubar void *data, uint32_t data_sz, 121245d40bdaSValerii Chubar void **out_buf, uint32_t *out_sz) 121345d40bdaSValerii Chubar { 121445d40bdaSValerii Chubar enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 121545d40bdaSValerii Chubar struct active_processing *proc = session->processing; 121645d40bdaSValerii Chubar 121745d40bdaSValerii Chubar switch (proc->mecha_type) { 121845d40bdaSValerii Chubar case PKCS11_CKM_RSA_AES_KEY_WRAP: 121945d40bdaSValerii Chubar rc = unwrap_rsa_aes_key(proc, data, data_sz, out_buf, out_sz); 122045d40bdaSValerii Chubar break; 122145d40bdaSValerii Chubar default: 122245d40bdaSValerii Chubar return PKCS11_CKR_MECHANISM_INVALID; 122345d40bdaSValerii Chubar } 122445d40bdaSValerii Chubar 122545d40bdaSValerii Chubar return rc; 122645d40bdaSValerii Chubar } 1227