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