19e91a619SVesa Jääskeläinen // SPDX-License-Identifier: BSD-2-Clause 29e91a619SVesa Jääskeläinen /* 39e91a619SVesa Jääskeläinen * Copyright (c) 2021, Vaisala Oyj 49e91a619SVesa Jääskeläinen */ 59e91a619SVesa Jääskeläinen 69e91a619SVesa Jääskeläinen #include <assert.h> 7eb88d2deSVesa Jääskeläinen #include <config.h> 89e91a619SVesa Jääskeläinen #include <pkcs11_ta.h> 99e91a619SVesa Jääskeläinen #include <string.h> 109e91a619SVesa Jääskeläinen #include <tee_api_defines.h> 119e91a619SVesa Jääskeläinen #include <tee_internal_api.h> 129e91a619SVesa Jääskeläinen #include <tee_internal_api_extensions.h> 139e91a619SVesa Jääskeläinen #include <utee_defines.h> 149e91a619SVesa Jääskeläinen #include <util.h> 159e91a619SVesa Jääskeläinen 169e91a619SVesa Jääskeläinen #include "attributes.h" 179e91a619SVesa Jääskeläinen #include "object.h" 189e91a619SVesa Jääskeläinen #include "pkcs11_attributes.h" 199e91a619SVesa Jääskeläinen #include "pkcs11_helpers.h" 209e91a619SVesa Jääskeläinen #include "pkcs11_token.h" 219e91a619SVesa Jääskeläinen #include "processing.h" 229e91a619SVesa Jääskeläinen #include "serializer.h" 239e91a619SVesa Jääskeläinen 249e91a619SVesa Jääskeläinen bool processing_is_tee_digest(enum pkcs11_mechanism_id mecha_id) 259e91a619SVesa Jääskeläinen { 269e91a619SVesa Jääskeläinen switch (mecha_id) { 279e91a619SVesa Jääskeläinen case PKCS11_CKM_MD5: 289e91a619SVesa Jääskeläinen case PKCS11_CKM_SHA_1: 299e91a619SVesa Jääskeläinen case PKCS11_CKM_SHA224: 309e91a619SVesa Jääskeläinen case PKCS11_CKM_SHA256: 319e91a619SVesa Jääskeläinen case PKCS11_CKM_SHA384: 329e91a619SVesa Jääskeläinen case PKCS11_CKM_SHA512: 339e91a619SVesa Jääskeläinen return true; 349e91a619SVesa Jääskeläinen default: 359e91a619SVesa Jääskeläinen return false; 369e91a619SVesa Jääskeläinen } 379e91a619SVesa Jääskeläinen } 389e91a619SVesa Jääskeläinen 399e91a619SVesa Jääskeläinen static enum pkcs11_rc 409e91a619SVesa Jääskeläinen pkcs2tee_algorithm(uint32_t *tee_id, struct pkcs11_attribute_head *proc_params) 419e91a619SVesa Jääskeläinen { 429e91a619SVesa Jääskeläinen static const struct { 439e91a619SVesa Jääskeläinen enum pkcs11_mechanism_id mech_id; 449e91a619SVesa Jääskeläinen uint32_t tee_id; 459e91a619SVesa Jääskeläinen } pkcs2tee_algo[] = { 469e91a619SVesa Jääskeläinen { PKCS11_CKM_MD5, TEE_ALG_MD5 }, 479e91a619SVesa Jääskeläinen { PKCS11_CKM_SHA_1, TEE_ALG_SHA1 }, 489e91a619SVesa Jääskeläinen { PKCS11_CKM_SHA224, TEE_ALG_SHA224 }, 499e91a619SVesa Jääskeläinen { PKCS11_CKM_SHA256, TEE_ALG_SHA256 }, 509e91a619SVesa Jääskeläinen { PKCS11_CKM_SHA384, TEE_ALG_SHA384 }, 519e91a619SVesa Jääskeläinen { PKCS11_CKM_SHA512, TEE_ALG_SHA512 }, 529e91a619SVesa Jääskeläinen }; 539e91a619SVesa Jääskeläinen size_t n = 0; 549e91a619SVesa Jääskeläinen 559e91a619SVesa Jääskeläinen for (n = 0; n < ARRAY_SIZE(pkcs2tee_algo); n++) { 569e91a619SVesa Jääskeläinen if (proc_params->id == pkcs2tee_algo[n].mech_id) { 579e91a619SVesa Jääskeläinen *tee_id = pkcs2tee_algo[n].tee_id; 589e91a619SVesa Jääskeläinen return PKCS11_CKR_OK; 599e91a619SVesa Jääskeläinen } 609e91a619SVesa Jääskeläinen } 619e91a619SVesa Jääskeläinen 629e91a619SVesa Jääskeläinen return PKCS11_RV_NOT_IMPLEMENTED; 639e91a619SVesa Jääskeläinen } 649e91a619SVesa Jääskeläinen 659e91a619SVesa Jääskeläinen static enum pkcs11_rc 669e91a619SVesa Jääskeläinen allocate_tee_operation(struct pkcs11_session *session, 679e91a619SVesa Jääskeläinen struct pkcs11_attribute_head *params) 689e91a619SVesa Jääskeläinen { 699e91a619SVesa Jääskeläinen uint32_t algo = 0; 709e91a619SVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 719e91a619SVesa Jääskeläinen 729e91a619SVesa Jääskeläinen assert(session->processing->tee_op_handle == TEE_HANDLE_NULL); 739e91a619SVesa Jääskeläinen 749e91a619SVesa Jääskeläinen if (pkcs2tee_algorithm(&algo, params)) 759e91a619SVesa Jääskeläinen return PKCS11_CKR_FUNCTION_FAILED; 769e91a619SVesa Jääskeläinen 779e91a619SVesa Jääskeläinen res = TEE_AllocateOperation(&session->processing->tee_op_handle, 789e91a619SVesa Jääskeläinen algo, TEE_MODE_DIGEST, 0); 799e91a619SVesa Jääskeläinen if (res) 809e91a619SVesa Jääskeläinen EMSG("TEE_AllocateOp. failed %#"PRIx32, algo); 819e91a619SVesa Jääskeläinen 829e91a619SVesa Jääskeläinen if (res == TEE_ERROR_NOT_SUPPORTED) 839e91a619SVesa Jääskeläinen return PKCS11_CKR_MECHANISM_INVALID; 849e91a619SVesa Jääskeläinen 859e91a619SVesa Jääskeläinen return tee2pkcs_error(res); 869e91a619SVesa Jääskeläinen } 879e91a619SVesa Jääskeläinen 889e91a619SVesa Jääskeläinen enum pkcs11_rc init_digest_operation(struct pkcs11_session *session, 899e91a619SVesa Jääskeläinen struct pkcs11_attribute_head *proc_params) 909e91a619SVesa Jääskeläinen { 91*909efccbSEtienne Carriere enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 92*909efccbSEtienne Carriere 939e91a619SVesa Jääskeläinen assert(processing_is_tee_digest(proc_params->id)); 949e91a619SVesa Jääskeläinen 95*909efccbSEtienne Carriere rc = allocate_tee_operation(session, proc_params); 96*909efccbSEtienne Carriere if (!rc) 97*909efccbSEtienne Carriere session->processing->mecha_type = proc_params->id; 98*909efccbSEtienne Carriere 99*909efccbSEtienne Carriere return rc; 1009e91a619SVesa Jääskeläinen } 1019e91a619SVesa Jääskeläinen 1029e91a619SVesa Jääskeläinen /* 1039e91a619SVesa Jääskeläinen * step_digest_operation - processing digest operation step 1049e91a619SVesa Jääskeläinen * 1059e91a619SVesa Jääskeläinen * @session - current session 1069e91a619SVesa Jääskeläinen * @step - step ID in the processing (oneshot, update, final) 1079e91a619SVesa Jääskeläinen * @obj - PKCS#11 object for key based operations 1089e91a619SVesa Jääskeläinen * @ptype - invocation parameter types 1099e91a619SVesa Jääskeläinen * @params - invocation parameter references 1109e91a619SVesa Jääskeläinen */ 1119e91a619SVesa Jääskeläinen enum pkcs11_rc step_digest_operation(struct pkcs11_session *session, 1129e91a619SVesa Jääskeläinen enum processing_step step, 1139e91a619SVesa Jääskeläinen struct pkcs11_object *obj, 1149e91a619SVesa Jääskeläinen uint32_t ptypes, TEE_Param *params) 1159e91a619SVesa Jääskeläinen { 1169e91a619SVesa Jääskeläinen enum pkcs11_rc rc = PKCS11_CKR_GENERAL_ERROR; 1179e91a619SVesa Jääskeläinen TEE_Result res = TEE_ERROR_GENERIC; 1189e91a619SVesa Jääskeläinen void *in_buf = NULL; 1199e91a619SVesa Jääskeläinen size_t in_size = 0; 1209e91a619SVesa Jääskeläinen void *out_buf = NULL; 1219e91a619SVesa Jääskeläinen uint32_t out_size = 0; 1229e91a619SVesa Jääskeläinen void *secret_value = NULL; 1239e91a619SVesa Jääskeläinen uint32_t secret_value_size = 0; 1249e91a619SVesa Jääskeläinen enum pkcs11_key_type key_type = PKCS11_CKK_UNDEFINED_ID; 1259e91a619SVesa Jääskeläinen struct active_processing *proc = session->processing; 1269e91a619SVesa Jääskeläinen 1279e91a619SVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 1) == TEE_PARAM_TYPE_MEMREF_INPUT) { 1289e91a619SVesa Jääskeläinen in_buf = params[1].memref.buffer; 1299e91a619SVesa Jääskeläinen in_size = params[1].memref.size; 1309e91a619SVesa Jääskeläinen if (in_size && !in_buf) 1319e91a619SVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 1329e91a619SVesa Jääskeläinen } 1339e91a619SVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 2) == TEE_PARAM_TYPE_MEMREF_OUTPUT) { 1349e91a619SVesa Jääskeläinen out_buf = params[2].memref.buffer; 1359e91a619SVesa Jääskeläinen out_size = params[2].memref.size; 1369e91a619SVesa Jääskeläinen if (out_size && !out_buf) 1379e91a619SVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 1389e91a619SVesa Jääskeläinen } 1399e91a619SVesa Jääskeläinen if (TEE_PARAM_TYPE_GET(ptypes, 3) != TEE_PARAM_TYPE_NONE) 1409e91a619SVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 1419e91a619SVesa Jääskeläinen 1429e91a619SVesa Jääskeläinen switch (step) { 1439e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_ONESHOT: 1449e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE: 1459e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE_KEY: 1469e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_FINAL: 1479e91a619SVesa Jääskeläinen break; 1489e91a619SVesa Jääskeläinen default: 1499e91a619SVesa Jääskeläinen TEE_Panic(step); 1509e91a619SVesa Jääskeläinen break; 1519e91a619SVesa Jääskeläinen } 1529e91a619SVesa Jääskeläinen 1539e91a619SVesa Jääskeläinen assert(proc->tee_op_handle != TEE_HANDLE_NULL); 1549e91a619SVesa Jääskeläinen 1559e91a619SVesa Jääskeläinen assert(processing_is_tee_digest(proc->mecha_type)); 1569e91a619SVesa Jääskeläinen 1579e91a619SVesa Jääskeläinen /* 1589e91a619SVesa Jääskeläinen * Feed active operation with data 1599e91a619SVesa Jääskeläinen */ 1609e91a619SVesa Jääskeläinen 1619e91a619SVesa Jääskeläinen switch (step) { 1629e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE_KEY: 1639e91a619SVesa Jääskeläinen assert(obj); 1649e91a619SVesa Jääskeläinen 165eb88d2deSVesa Jääskeläinen if (!IS_ENABLED(CFG_PKCS11_TA_ALLOW_DIGEST_KEY)) 166eb88d2deSVesa Jääskeläinen return PKCS11_CKR_KEY_INDIGESTIBLE; 167eb88d2deSVesa Jääskeläinen 1689e91a619SVesa Jääskeläinen if (get_class(obj->attributes) != PKCS11_CKO_SECRET_KEY) 1699e91a619SVesa Jääskeläinen return PKCS11_CKR_KEY_INDIGESTIBLE; 1709e91a619SVesa Jääskeläinen 1719e91a619SVesa Jääskeläinen key_type = get_key_type(obj->attributes); 1729e91a619SVesa Jääskeläinen 1739e91a619SVesa Jääskeläinen if (key_type != PKCS11_CKK_GENERIC_SECRET && 1749e91a619SVesa Jääskeläinen key_type != PKCS11_CKK_AES) 1759e91a619SVesa Jääskeläinen return PKCS11_CKR_KEY_INDIGESTIBLE; 1769e91a619SVesa Jääskeläinen 1779e91a619SVesa Jääskeläinen rc = get_attribute_ptr(obj->attributes, PKCS11_CKA_VALUE, 1789e91a619SVesa Jääskeläinen &secret_value, &secret_value_size); 1799e91a619SVesa Jääskeläinen assert(!rc && secret_value && secret_value_size); 1809e91a619SVesa Jääskeläinen 1819e91a619SVesa Jääskeläinen TEE_DigestUpdate(proc->tee_op_handle, secret_value, 1829e91a619SVesa Jääskeläinen secret_value_size); 1839e91a619SVesa Jääskeläinen return PKCS11_CKR_OK; 1849e91a619SVesa Jääskeläinen 1859e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_UPDATE: 1869e91a619SVesa Jääskeläinen if (!in_buf || !in_size) 1879e91a619SVesa Jääskeläinen return PKCS11_CKR_OK; 1889e91a619SVesa Jääskeläinen 1899e91a619SVesa Jääskeläinen TEE_DigestUpdate(proc->tee_op_handle, in_buf, in_size); 1909e91a619SVesa Jääskeläinen return PKCS11_CKR_OK; 1919e91a619SVesa Jääskeläinen 1929e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_ONESHOT: 1939e91a619SVesa Jääskeläinen if (!out_buf) 1949e91a619SVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 1959e91a619SVesa Jääskeläinen 1969e91a619SVesa Jääskeläinen goto do_final; 1979e91a619SVesa Jääskeläinen 1989e91a619SVesa Jääskeläinen case PKCS11_FUNC_STEP_FINAL: 1999e91a619SVesa Jääskeläinen if (in_buf || !out_buf) 2009e91a619SVesa Jääskeläinen return PKCS11_CKR_ARGUMENTS_BAD; 2019e91a619SVesa Jääskeläinen 2029e91a619SVesa Jääskeläinen goto do_final; 2039e91a619SVesa Jääskeläinen 2049e91a619SVesa Jääskeläinen default: 2059e91a619SVesa Jääskeläinen TEE_Panic(step); 2069e91a619SVesa Jääskeläinen break; 2079e91a619SVesa Jääskeläinen } 2089e91a619SVesa Jääskeläinen 2099e91a619SVesa Jääskeläinen do_final: 2109e91a619SVesa Jääskeläinen res = TEE_DigestDoFinal(proc->tee_op_handle, 2119e91a619SVesa Jääskeläinen in_buf, in_size, out_buf, 2129e91a619SVesa Jääskeläinen &out_size); 2139e91a619SVesa Jääskeläinen rc = tee2pkcs_error(res); 2149e91a619SVesa Jääskeläinen 2159e91a619SVesa Jääskeläinen if (rc == PKCS11_CKR_OK || rc == PKCS11_CKR_BUFFER_TOO_SMALL) 2169e91a619SVesa Jääskeläinen params[2].memref.size = out_size; 2179e91a619SVesa Jääskeläinen 2189e91a619SVesa Jääskeläinen return rc; 2199e91a619SVesa Jääskeläinen } 220