1*8849c126SEtienne Carriere // SPDX-License-Identifier: BSD-2-Clause 2*8849c126SEtienne Carriere /* 3*8849c126SEtienne Carriere * Copyright (c) 2017-2020, Linaro Limited 4*8849c126SEtienne Carriere */ 5*8849c126SEtienne Carriere 6*8849c126SEtienne Carriere #include <assert.h> 7*8849c126SEtienne Carriere #include <pkcs11_ta.h> 8*8849c126SEtienne Carriere #include <string.h> 9*8849c126SEtienne Carriere #include <util.h> 10*8849c126SEtienne Carriere #include <tee_api.h> 11*8849c126SEtienne Carriere #include <tee_internal_api_extensions.h> 12*8849c126SEtienne Carriere 13*8849c126SEtienne Carriere #include "pkcs11_helpers.h" 14*8849c126SEtienne Carriere #include "token_capabilities.h" 15*8849c126SEtienne Carriere 16*8849c126SEtienne Carriere #define ALLOWED_PKCS11_CKFM \ 17*8849c126SEtienne Carriere (PKCS11_CKFM_ENCRYPT | PKCS11_CKFM_DECRYPT | \ 18*8849c126SEtienne Carriere PKCS11_CKFM_DERIVE | PKCS11_CKFM_DIGEST | \ 19*8849c126SEtienne Carriere PKCS11_CKFM_SIGN | PKCS11_CKFM_SIGN_RECOVER | \ 20*8849c126SEtienne Carriere PKCS11_CKFM_VERIFY | PKCS11_CKFM_VERIFY_RECOVER | \ 21*8849c126SEtienne Carriere PKCS11_CKFM_GENERATE | PKCS11_CKFM_GENERATE_KEY_PAIR | \ 22*8849c126SEtienne Carriere PKCS11_CKFM_WRAP | PKCS11_CKFM_UNWRAP) 23*8849c126SEtienne Carriere 24*8849c126SEtienne Carriere /* 25*8849c126SEtienne Carriere * Definition of supported processings for a PKCS#11 mechanisms 26*8849c126SEtienne Carriere * @id: Mechanism ID 27*8849c126SEtienne Carriere * @flags: Valid PKCS11_CKFM_* for a mechanism as per PKCS#11 28*8849c126SEtienne Carriere * @one_shot: true of mechanism can be used for a one-short processing 29*8849c126SEtienne Carriere * @string: Helper string of the mechanism ID for debug purpose 30*8849c126SEtienne Carriere */ 31*8849c126SEtienne Carriere struct pkcs11_mechachism_modes { 32*8849c126SEtienne Carriere uint32_t id; 33*8849c126SEtienne Carriere uint32_t flags; 34*8849c126SEtienne Carriere bool one_shot; 35*8849c126SEtienne Carriere #if CFG_TEE_TA_LOG_LEVEL > 0 36*8849c126SEtienne Carriere const char *string; 37*8849c126SEtienne Carriere #endif 38*8849c126SEtienne Carriere }; 39*8849c126SEtienne Carriere 40*8849c126SEtienne Carriere #if CFG_TEE_TA_LOG_LEVEL > 0 41*8849c126SEtienne Carriere #define MECHANISM(_label, _flags, _single_part) \ 42*8849c126SEtienne Carriere { \ 43*8849c126SEtienne Carriere .id = _label, \ 44*8849c126SEtienne Carriere .one_shot = (_single_part), \ 45*8849c126SEtienne Carriere .flags = (_flags), \ 46*8849c126SEtienne Carriere .string = #_label, \ 47*8849c126SEtienne Carriere } 48*8849c126SEtienne Carriere #else 49*8849c126SEtienne Carriere #define MECHANISM(_label, _flags, _single_part) \ 50*8849c126SEtienne Carriere { \ 51*8849c126SEtienne Carriere .id = _label, \ 52*8849c126SEtienne Carriere .one_shot = (_single_part), \ 53*8849c126SEtienne Carriere .flags = (_flags), \ 54*8849c126SEtienne Carriere } 55*8849c126SEtienne Carriere #endif 56*8849c126SEtienne Carriere 57*8849c126SEtienne Carriere #define SINGLE_PART_ONLY true 58*8849c126SEtienne Carriere #define ANY_PART false 59*8849c126SEtienne Carriere 60*8849c126SEtienne Carriere /* PKCS#11 specificies permitted operation for each mechanism */ 61*8849c126SEtienne Carriere static const struct pkcs11_mechachism_modes pkcs11_modes[] = { 62*8849c126SEtienne Carriere MECHANISM(PKCS11_CKM_AES_ECB, 63*8849c126SEtienne Carriere PKCS11_CKFM_ENCRYPT | PKCS11_CKFM_DECRYPT | 64*8849c126SEtienne Carriere PKCS11_CKFM_DERIVE | 65*8849c126SEtienne Carriere PKCS11_CKFM_WRAP | PKCS11_CKFM_UNWRAP, 66*8849c126SEtienne Carriere ANY_PART), 67*8849c126SEtienne Carriere }; 68*8849c126SEtienne Carriere 69*8849c126SEtienne Carriere #if CFG_TEE_TA_LOG_LEVEL > 0 70*8849c126SEtienne Carriere const char *mechanism_string_id(enum pkcs11_mechanism_id id) 71*8849c126SEtienne Carriere { 72*8849c126SEtienne Carriere const size_t offset = sizeof("PKCS11_CKM_") - 1; 73*8849c126SEtienne Carriere size_t n = 0; 74*8849c126SEtienne Carriere 75*8849c126SEtienne Carriere for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++) 76*8849c126SEtienne Carriere if (pkcs11_modes[n].id == id) 77*8849c126SEtienne Carriere return pkcs11_modes[n].string + offset; 78*8849c126SEtienne Carriere 79*8849c126SEtienne Carriere return "Unknown ID"; 80*8849c126SEtienne Carriere } 81*8849c126SEtienne Carriere #endif /*CFG_TEE_TA_LOG_LEVEL*/ 82*8849c126SEtienne Carriere 83*8849c126SEtienne Carriere /* 84*8849c126SEtienne Carriere * Return true if @id is a valid mechanism ID 85*8849c126SEtienne Carriere */ 86*8849c126SEtienne Carriere bool mechanism_is_valid(enum pkcs11_mechanism_id id) 87*8849c126SEtienne Carriere { 88*8849c126SEtienne Carriere size_t n = 0; 89*8849c126SEtienne Carriere 90*8849c126SEtienne Carriere for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++) 91*8849c126SEtienne Carriere if (id == pkcs11_modes[n].id) 92*8849c126SEtienne Carriere return true; 93*8849c126SEtienne Carriere 94*8849c126SEtienne Carriere return false; 95*8849c126SEtienne Carriere } 96*8849c126SEtienne Carriere 97*8849c126SEtienne Carriere /* 98*8849c126SEtienne Carriere * Return true if mechanism ID is valid and flags matches PKCS#11 compliancy 99*8849c126SEtienne Carriere */ 100*8849c126SEtienne Carriere bool __maybe_unused mechanism_flags_complies_pkcs11(uint32_t mechanism_type, 101*8849c126SEtienne Carriere uint32_t flags) 102*8849c126SEtienne Carriere { 103*8849c126SEtienne Carriere size_t n = 0; 104*8849c126SEtienne Carriere 105*8849c126SEtienne Carriere assert((flags & ~ALLOWED_PKCS11_CKFM) == 0); 106*8849c126SEtienne Carriere 107*8849c126SEtienne Carriere for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++) { 108*8849c126SEtienne Carriere if (pkcs11_modes[n].id == mechanism_type) { 109*8849c126SEtienne Carriere if (flags & ~pkcs11_modes[n].flags) 110*8849c126SEtienne Carriere EMSG("%s flags: 0x%"PRIx32" vs 0x%"PRIx32, 111*8849c126SEtienne Carriere id2str_mechanism(mechanism_type), 112*8849c126SEtienne Carriere flags, pkcs11_modes[n].flags); 113*8849c126SEtienne Carriere 114*8849c126SEtienne Carriere return (flags & ~pkcs11_modes[n].flags) == 0; 115*8849c126SEtienne Carriere } 116*8849c126SEtienne Carriere } 117*8849c126SEtienne Carriere 118*8849c126SEtienne Carriere /* Mechanism ID unexpectedly not found */ 119*8849c126SEtienne Carriere return false; 120*8849c126SEtienne Carriere } 121*8849c126SEtienne Carriere 122*8849c126SEtienne Carriere /* 123*8849c126SEtienne Carriere * Arrays that centralizes the IDs and processing flags for mechanisms 124*8849c126SEtienne Carriere * supported by each embedded token. Currently none. 125*8849c126SEtienne Carriere */ 126*8849c126SEtienne Carriere const struct pkcs11_mechachism_modes token_mechanism[] = { 127*8849c126SEtienne Carriere MECHANISM(PKCS11_CKM_AES_ECB, 0, 0), 128*8849c126SEtienne Carriere }; 129*8849c126SEtienne Carriere 130*8849c126SEtienne Carriere /* 131*8849c126SEtienne Carriere * tee_malloc_mechanism_array - Allocate and fill array of supported mechanisms 132*8849c126SEtienne Carriere * @count: [in] [out] Pointer to number of mechanism IDs in client resource 133*8849c126SEtienne Carriere * Return allocated array of the supported mechanism IDs 134*8849c126SEtienne Carriere * 135*8849c126SEtienne Carriere * Allocates array with 32bit cells mechanism IDs for the supported ones only 136*8849c126SEtienne Carriere * if *@count covers number mechanism IDs exposed. 137*8849c126SEtienne Carriere */ 138*8849c126SEtienne Carriere uint32_t *tee_malloc_mechanism_list(size_t *out_count) 139*8849c126SEtienne Carriere { 140*8849c126SEtienne Carriere size_t n = 0; 141*8849c126SEtienne Carriere size_t count = 0; 142*8849c126SEtienne Carriere uint32_t *array = NULL; 143*8849c126SEtienne Carriere 144*8849c126SEtienne Carriere for (n = 0; n < ARRAY_SIZE(token_mechanism); n++) 145*8849c126SEtienne Carriere if (token_mechanism[n].flags) 146*8849c126SEtienne Carriere count++; 147*8849c126SEtienne Carriere 148*8849c126SEtienne Carriere if (*out_count >= count) 149*8849c126SEtienne Carriere array = TEE_Malloc(count * sizeof(*array), 150*8849c126SEtienne Carriere TEE_USER_MEM_HINT_NO_FILL_ZERO); 151*8849c126SEtienne Carriere 152*8849c126SEtienne Carriere *out_count = count; 153*8849c126SEtienne Carriere 154*8849c126SEtienne Carriere if (!array) 155*8849c126SEtienne Carriere return NULL; 156*8849c126SEtienne Carriere 157*8849c126SEtienne Carriere for (n = 0; n < ARRAY_SIZE(token_mechanism); n++) { 158*8849c126SEtienne Carriere if (token_mechanism[n].flags) { 159*8849c126SEtienne Carriere count--; 160*8849c126SEtienne Carriere array[count] = token_mechanism[n].id; 161*8849c126SEtienne Carriere } 162*8849c126SEtienne Carriere } 163*8849c126SEtienne Carriere assert(!count); 164*8849c126SEtienne Carriere 165*8849c126SEtienne Carriere return array; 166*8849c126SEtienne Carriere } 167*8849c126SEtienne Carriere 168*8849c126SEtienne Carriere uint32_t mechanism_supported_flags(enum pkcs11_mechanism_id id) 169*8849c126SEtienne Carriere { 170*8849c126SEtienne Carriere size_t n = 0; 171*8849c126SEtienne Carriere 172*8849c126SEtienne Carriere for (n = 0; n < ARRAY_SIZE(token_mechanism); n++) { 173*8849c126SEtienne Carriere if (id == token_mechanism[n].id) { 174*8849c126SEtienne Carriere uint32_t flags = token_mechanism[n].flags; 175*8849c126SEtienne Carriere 176*8849c126SEtienne Carriere assert(mechanism_flags_complies_pkcs11(id, flags)); 177*8849c126SEtienne Carriere return flags; 178*8849c126SEtienne Carriere } 179*8849c126SEtienne Carriere } 180*8849c126SEtienne Carriere 181*8849c126SEtienne Carriere return 0; 182*8849c126SEtienne Carriere } 183