1*9e91a619SVesa Jääskeläinen // SPDX-License-Identifier: BSD-2-Clause 2*9e91a619SVesa Jääskeläinen /* 3*9e91a619SVesa Jääskeläinen * Copyright (c) 2021, Vaisala Oyj 4*9e91a619SVesa Jääskeläinen */ 5*9e91a619SVesa Jääskeläinen 6*9e91a619SVesa Jääskeläinen #include <assert.h> 7*9e91a619SVesa Jääskeläinen #include <pkcs11_ta.h> 8*9e91a619SVesa Jääskeläinen #include <string.h> 9*9e91a619SVesa Jääskeläinen #include <tee_api_defines.h> 10*9e91a619SVesa Jääskeläinen #include <tee_internal_api.h> 11*9e91a619SVesa Jääskeläinen #include <tee_internal_api_extensions.h> 12*9e91a619SVesa Jääskeläinen #include <utee_defines.h> 13*9e91a619SVesa Jääskeläinen #include <util.h> 14*9e91a619SVesa Jääskeläinen 15*9e91a619SVesa Jääskeläinen #include "attributes.h" 16*9e91a619SVesa Jääskeläinen #include "object.h" 17*9e91a619SVesa Jääskeläinen #include "pkcs11_attributes.h" 18*9e91a619SVesa Jääskeläinen #include "pkcs11_helpers.h" 19*9e91a619SVesa Jääskeläinen #include "pkcs11_token.h" 20*9e91a619SVesa Jääskeläinen #include "processing.h" 21*9e91a619SVesa Jääskeläinen #include "serializer.h" 22*9e91a619SVesa Jääskeläinen 23*9e91a619SVesa Jääskeläinen bool processing_is_tee_digest(enum pkcs11_mechanism_id mecha_id) 24*9e91a619SVesa Jääskeläinen { 25*9e91a619SVesa Jääskeläinen switch (mecha_id) { 26*9e91a619SVesa Jääskeläinen case PKCS11_CKM_MD5: 27*9e91a619SVesa Jääskeläinen case PKCS11_CKM_SHA_1: 28*9e91a619SVesa Jääskeläinen case PKCS11_CKM_SHA224: 29*9e91a619SVesa Jääskeläinen case PKCS11_CKM_SHA256: 30*9e91a619SVesa Jääskeläinen case PKCS11_CKM_SHA384: 31*9e91a619SVesa Jääskeläinen case PKCS11_CKM_SHA512: 32*9e91a619SVesa Jääskeläinen return true; 33*9e91a619SVesa Jääskeläinen default: 34*9e91a619SVesa Jääskeläinen return false; 35*9e91a619SVesa Jääskeläinen } 36*9e91a619SVesa Jääskeläinen } 37*9e91a619SVesa Jääskeläinen 38*9e91a619SVesa Jääskeläinen static enum pkcs11_rc 39*9e91a619SVesa Jääskeläinen pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params) 40*9e91a619SVesa Jääskeläinen { 41*9e91a619SVesa Jääskeläinen static const struct { 42*9e91a619SVesa Jääskeläinen enum pkcs11_mechanism_id mech_id; 43*9e91a619SVesa Jääskeläinen uint32_t tee_id; 44*9e91a619SVesa Jääskeläinen } pkcs2tee_algo[] = { 45*9e91a619SVesa Jääskeläinen { PKCS11_CKM_MD5, TEE_ALG_MD5 }, 46*9e91a619SVesa Jääskeläinen { PKCS11_CKM_SHA_1, TEE_ALG_SHA1 }, 47*9e91a619SVesa Jääskeläinen { PKCS11_CKM_SHA224, TEE_ALG_SHA224 }, 48*9e91a619SVesa Jääskeläinen { PKCS11_CKM_SHA256, TEE_ALG_SHA256 }, 49*9e91a619SVesa Jääskeläinen { PKCS11_CKM_SHA384, TEE_ALG_SHA384 }, 50*9e91a619SVesa Jääskeläinen { PKCS11_CKM_SHA512, TEE_ALG_SHA512 }, 51*9e91a619SVesa Jääskeläinen }; 52*9e91a619SVesa Jääskeläinen size_t n = 0; 53*9e91a619SVesa Jääskeläinen 54*9e91a619SVesa Jääskeläinen for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) { 55*9e91a619SVesa Jääskeläinen if (proc_params->id == pkcs2tee_algo[n].mech_id) { 56*9e91a619SVesa Jääskeläinen *tee_id = pkcs2tee_algo[n].tee_id; 57*9e91a619SVesa Jääskeläinen return PKCS11_CKR_OK; 58*9e91a619SVesa Jääskeläinen } 59*9e91a619SVesa Jääskeläinen } 60*9e91a619SVesa Jääskeläinen 61*9e91a619SVesa Jääskeläinen return PKCS11_RV_NOT_IMPLEMENTED; 62*9e91a619SVesa Jääskeläinen } 63*9e91a619SVesa Jääskeläinen 64*9e91a619SVesa Jääskeläinen static enum pkcs11_rc 65*9e91a619SVesa Jääskeläinen allocate_tee_operation(struct pkcs11_session *session, 66*9e91a619SVesa Jääskeläinen struct pkcs11_attribute_head *params) 67*9e91a619SVesa Jääskeläinen { 68*9e91a619SVesa Jääskeläinen uint32_t algo = 0; 69*9e91a619SVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 70*9e91a619SVesa Jääskeläinen 71*9e91a619SVesa Jääskeläinen assert(session->processing->tee_op_handle == TEE_HANDLE_NULL); 72*9e91a619SVesa Jääskeläinen 73*9e91a619SVesa Jääskeläinen if (pkcs2tee_algorithm(&algo, params)) 74*9e91a619SVesa Jääskeläinen return PKCS11_CKR_FUNCTION_FAILED; 75*9e91a619SVesa Jääskeläinen 76*9e91a619SVesa Jääskeläinen res = TEE_AllocateOperation(&session->processing->tee_op_handle, 77*9e91a619SVesa Jääskeläinen algo, TEE_MODE_DIGEST, 0); 78*9e91a619SVesa Jääskeläinen if (res) 79*9e91a619SVesa Jääskeläinen EMSG("TEE_AllocateOp. failed %#"PRIx32, algo); 80*9e91a619SVesa Jääskeläinen 81*9e91a619SVesa Jääskeläinen if (res == TEE_ERROR_NOT_SUPPORTED) 82*9e91a619SVesa Jääskeläinen return PKCS11_CKR_MECHANISM_INVALID; 83*9e91a619SVesa Jääskeläinen 84*9e91a619SVesa Jääskeläinen return tee2pkcs_error(res); 85*9e91a619SVesa Jääskeläinen } 86*9e91a619SVesa Jääskeläinen 87*9e91a619SVesa Jääskeläinen enum pkcs11_rc init_digest_operation(struct pkcs11_session *session, 88*9e91a619SVesa Jääskeläinen struct pkcs11_attribute_head *proc_params) 89*9e91a619SVesa Jääskeläinen { 90*9e91a619SVesa Jääskeläinen assert(processing_is_tee_digest(proc_params->id)); 91*9e91a619SVesa Jääskeläinen 92*9e91a619SVesa Jääskeläinen return allocate_tee_operation(session, proc_params); 93*9e91a619SVesa Jääskeläinen } 94*9e91a619SVesa Jääskeläinen 95*9e91a619SVesa Jääskeläinen /* 96*9e91a619SVesa Jääskeläinen * step_digest_operation - processing digest operation step 97*9e91a619SVesa Jääskeläinen * 98*9e91a619SVesa Jääskeläinen * @session - current session 99*9e91a619SVesa Jääskeläinen * @step - step ID in the processing (oneshot, update, final) 100*9e91a619SVesa Jääskeläinen * @obj - PKCS#11 object for key based operations 101*9e91a619SVesa Jääskeläinen * @ptype - invocation parameter types 102*9e91a619SVesa Jääskeläinen * @params - invocation parameter references 103*9e91a619SVesa Jääskeläinen */ 104*9e91a619SVesa Jääskeläinen enum pkcs11_rc step_digest_operation(struct pkcs11_session *session, 105*9e91a619SVesa Jääskeläinen enum processing_step step, 106*9e91a619SVesa Jääskeläinen struct pkcs11_object *obj, 107*9e91a619SVesa Jääskeläinen uint32_t ptypes, TEE_Param *params) 108*9e91a619SVesa Jääskeläinen { 109*9e91a619SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 110*9e91a619SVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 111*9e91a619SVesa Jääskeläinen void *in_buf = NULL; 112*9e91a619SVesa Jääskeläinen size_t in_size = 0; 113*9e91a619SVesa Jääskeläinen void *out_buf = NULL; 114*9e91a619SVesa Jääskeläinen uint32_t out_size = 0; 115*9e91a619SVesa Jääskeläinen void *secret_value = NULL; 116*9e91a619SVesa Jääskeläinen uint32_t secret_value_size = 0; 117*9e91a619SVesa Jääskeläinen enum pkcs11_key_type key_type = PKCS11_CKK_UNDEFINED_ID; 118*9e91a619SVesa Jääskeläinen struct active_processing *proc = session->processing; 119*9e91a619SVesa Jääskeläinen 120*9e91a619SVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 121*9e91a619SVesa Jääskeläinen in_buf = params[1].memref.buffer; 122*9e91a619SVesa Jääskeläinen in_size = params[1].memref.size; 123*9e91a619SVesa Jääskeläinen if (in_size && !in_buf) 124*9e91a619SVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 125*9e91a619SVesa Jääskeläinen } 126*9e91a619SVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 127*9e91a619SVesa Jääskeläinen out_buf = params[2].memref.buffer; 128*9e91a619SVesa Jääskeläinen out_size = params[2].memref.size; 129*9e91a619SVesa Jääskeläinen if (out_size && !out_buf) 130*9e91a619SVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 131*9e91a619SVesa Jääskeläinen } 132*9e91a619SVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 133*9e91a619SVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 134*9e91a619SVesa Jääskeläinen 135*9e91a619SVesa Jääskeläinen switch (step) { 136*9e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_ONESHOT: 137*9e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE: 138*9e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE_KEY: 139*9e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_FINAL: 140*9e91a619SVesa Jääskeläinen break; 141*9e91a619SVesa Jääskeläinen default: 142*9e91a619SVesa Jääskeläinen TEE_Panic(step); 143*9e91a619SVesa Jääskeläinen break; 144*9e91a619SVesa Jääskeläinen } 145*9e91a619SVesa Jääskeläinen 146*9e91a619SVesa Jääskeläinen assert(proc->tee_op_handle != TEE_HANDLE_NULL); 147*9e91a619SVesa Jääskeläinen 148*9e91a619SVesa Jääskeläinen assert(processing_is_tee_digest(proc->mecha_type)); 149*9e91a619SVesa Jääskeläinen 150*9e91a619SVesa Jääskeläinen /* 151*9e91a619SVesa Jääskeläinen * Feed active operation with data 152*9e91a619SVesa Jääskeläinen */ 153*9e91a619SVesa Jääskeläinen 154*9e91a619SVesa Jääskeläinen switch (step) { 155*9e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE_KEY: 156*9e91a619SVesa Jääskeläinen assert(obj); 157*9e91a619SVesa Jääskeläinen 158*9e91a619SVesa Jääskeläinen if (get_class(obj->attributes) != PKCS11_CKO_SECRET_KEY) 159*9e91a619SVesa Jääskeläinen return PKCS11_CKR_KEY_INDIGESTIBLE; 160*9e91a619SVesa Jääskeläinen 161*9e91a619SVesa Jääskeläinen key_type = get_key_type(obj->attributes); 162*9e91a619SVesa Jääskeläinen 163*9e91a619SVesa Jääskeläinen if (key_type != PKCS11_CKK_GENERIC_SECRET && 164*9e91a619SVesa Jääskeläinen key_type != PKCS11_CKK_AES) 165*9e91a619SVesa Jääskeläinen return PKCS11_CKR_KEY_INDIGESTIBLE; 166*9e91a619SVesa Jääskeläinen 167*9e91a619SVesa Jääskeläinen rc = get_attribute_ptr(obj->attributes, PKCS11_CKA_VALUE, 168*9e91a619SVesa Jääskeläinen &secret_value, &secret_value_size); 169*9e91a619SVesa Jääskeläinen assert(!rc && secret_value && secret_value_size); 170*9e91a619SVesa Jääskeläinen 171*9e91a619SVesa Jääskeläinen TEE_DigestUpdate(proc->tee_op_handle, secret_value, 172*9e91a619SVesa Jääskeläinen secret_value_size); 173*9e91a619SVesa Jääskeläinen return PKCS11_CKR_OK; 174*9e91a619SVesa Jääskeläinen 175*9e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE: 176*9e91a619SVesa Jääskeläinen if (!in_buf || !in_size) 177*9e91a619SVesa Jääskeläinen return PKCS11_CKR_OK; 178*9e91a619SVesa Jääskeläinen 179*9e91a619SVesa Jääskeläinen TEE_DigestUpdate(proc->tee_op_handle, in_buf, in_size); 180*9e91a619SVesa Jääskeläinen return PKCS11_CKR_OK; 181*9e91a619SVesa Jääskeläinen 182*9e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_ONESHOT: 183*9e91a619SVesa Jääskeläinen if (!out_buf) 184*9e91a619SVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 185*9e91a619SVesa Jääskeläinen 186*9e91a619SVesa Jääskeläinen goto do_final; 187*9e91a619SVesa Jääskeläinen 188*9e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_FINAL: 189*9e91a619SVesa Jääskeläinen if (in_buf || !out_buf) 190*9e91a619SVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 191*9e91a619SVesa Jääskeläinen 192*9e91a619SVesa Jääskeläinen goto do_final; 193*9e91a619SVesa Jääskeläinen 194*9e91a619SVesa Jääskeläinen default: 195*9e91a619SVesa Jääskeläinen TEE_Panic(step); 196*9e91a619SVesa Jääskeläinen break; 197*9e91a619SVesa Jääskeläinen } 198*9e91a619SVesa Jääskeläinen 199*9e91a619SVesa Jääskeläinen do_final: 200*9e91a619SVesa Jääskeläinen res = TEE_DigestDoFinal(proc->tee_op_handle, 201*9e91a619SVesa Jääskeläinen in_buf, in_size, out_buf, 202*9e91a619SVesa Jääskeläinen &out_size); 203*9e91a619SVesa Jääskeläinen rc = tee2pkcs_error(res); 204*9e91a619SVesa Jääskeläinen 205*9e91a619SVesa Jääskeläinen if (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL) 206*9e91a619SVesa Jääskeläinen params[2].memref.size = out_size; 207*9e91a619SVesa Jääskeläinen 208*9e91a619SVesa Jääskeläinen return rc; 209*9e91a619SVesa Jääskeläinen } 210