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_WRAP | PKCS11_CKFM_UNWRAP, 65 ANY_PART), 66 }; 67 68 #if CFG_TEE_TA_LOG_LEVEL > 0 69 const char *mechanism_string_id(enum pkcs11_mechanism_id id) 70 { 71 const size_t offset = sizeof("PKCS11_CKM_") - 1; 72 size_t n = 0; 73 74 for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++) 75 if (pkcs11_modes[n].id == id) 76 return pkcs11_modes[n].string + offset; 77 78 return "Unknown ID"; 79 } 80 #endif /*CFG_TEE_TA_LOG_LEVEL*/ 81 82 /* 83 * Return true if @id is a valid mechanism ID 84 */ 85 bool mechanism_is_valid(enum pkcs11_mechanism_id id) 86 { 87 size_t n = 0; 88 89 for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++) 90 if (id == pkcs11_modes[n].id) 91 return true; 92 93 return false; 94 } 95 96 /* 97 * Return true if mechanism ID is valid and flags matches PKCS#11 compliancy 98 */ 99 bool __maybe_unused mechanism_flags_complies_pkcs11(uint32_t mechanism_type, 100 uint32_t flags) 101 { 102 size_t n = 0; 103 104 assert((flags & ~ALLOWED_PKCS11_CKFM) == 0); 105 106 for (n = 0; n < ARRAY_SIZE(pkcs11_modes); n++) { 107 if (pkcs11_modes[n].id == mechanism_type) { 108 if (flags & ~pkcs11_modes[n].flags) 109 EMSG("%s flags: 0x%"PRIx32" vs 0x%"PRIx32, 110 id2str_mechanism(mechanism_type), 111 flags, pkcs11_modes[n].flags); 112 113 return (flags & ~pkcs11_modes[n].flags) == 0; 114 } 115 } 116 117 /* Mechanism ID unexpectedly not found */ 118 return false; 119 } 120 121 /* 122 * Arrays that centralizes the IDs and processing flags for mechanisms 123 * supported by each embedded token. Currently none. 124 */ 125 const struct pkcs11_mechachism_modes token_mechanism[] = { 126 MECHANISM(PKCS11_CKM_AES_ECB, 0, 0), 127 }; 128 129 /* 130 * tee_malloc_mechanism_array - Allocate and fill array of supported mechanisms 131 * @count: [in] [out] Pointer to number of mechanism IDs in client resource 132 * Return allocated array of the supported mechanism IDs 133 * 134 * Allocates array with 32bit cells mechanism IDs for the supported ones only 135 * if *@count covers number mechanism IDs exposed. 136 */ 137 uint32_t *tee_malloc_mechanism_list(size_t *out_count) 138 { 139 size_t n = 0; 140 size_t count = 0; 141 uint32_t *array = NULL; 142 143 for (n = 0; n < ARRAY_SIZE(token_mechanism); n++) 144 if (token_mechanism[n].flags) 145 count++; 146 147 if (*out_count >= count) 148 array = TEE_Malloc(count * sizeof(*array), 149 TEE_USER_MEM_HINT_NO_FILL_ZERO); 150 151 *out_count = count; 152 153 if (!array) 154 return NULL; 155 156 for (n = 0; n < ARRAY_SIZE(token_mechanism); n++) { 157 if (token_mechanism[n].flags) { 158 count--; 159 array[count] = token_mechanism[n].id; 160 } 161 } 162 assert(!count); 163 164 return array; 165 } 166 167 uint32_t mechanism_supported_flags(enum pkcs11_mechanism_id id) 168 { 169 size_t n = 0; 170 171 for (n = 0; n < ARRAY_SIZE(token_mechanism); n++) { 172 if (id == token_mechanism[n].id) { 173 uint32_t flags = token_mechanism[n].flags; 174 175 assert(mechanism_flags_complies_pkcs11(id, flags)); 176 return flags; 177 } 178 } 179 180 return 0; 181 } 182