psa_constant_names.c (10376B)
1 /* 2 * Copyright The Mbed TLS Contributors 3 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 4 */ 5 6 #include <errno.h> 7 #include <stdint.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 12 #include "psa/crypto.h" 13 14 /* This block is present to support Visual Studio builds prior to 2015 */ 15 #if defined(_MSC_VER) && _MSC_VER < 1900 16 #include <stdarg.h> 17 int snprintf(char *s, size_t n, const char *fmt, ...) 18 { 19 int ret; 20 va_list argp; 21 22 /* Avoid calling the invalid parameter handler by checking ourselves */ 23 if (s == NULL || n == 0 || fmt == NULL) { 24 return -1; 25 } 26 27 va_start(argp, fmt); 28 #if defined(_TRUNCATE) && !defined(__MINGW32__) 29 ret = _vsnprintf_s(s, n, _TRUNCATE, fmt, argp); 30 #else 31 ret = _vsnprintf(s, n, fmt, argp); 32 if (ret < 0 || (size_t) ret == n) { 33 s[n-1] = '\0'; 34 ret = -1; 35 } 36 #endif 37 va_end(argp); 38 39 return ret; 40 } 41 #endif 42 43 static void append(char **buffer, size_t buffer_size, 44 size_t *required_size, 45 const char *string, size_t length) 46 { 47 *required_size += length; 48 if (*required_size < buffer_size) { 49 memcpy(*buffer, string, length); 50 *buffer += length; 51 } 52 } 53 54 static void append_integer(char **buffer, size_t buffer_size, 55 size_t *required_size, 56 const char *format /*printf format for value*/, 57 unsigned long value) 58 { 59 size_t n = snprintf(*buffer, buffer_size - *required_size, format, value); 60 if (n < buffer_size - *required_size) { 61 *buffer += n; 62 } 63 *required_size += n; 64 } 65 66 /* The code of these function is automatically generated and included below. */ 67 static const char *psa_ecc_family_name(psa_ecc_family_t curve); 68 static const char *psa_dh_family_name(psa_dh_family_t group); 69 static const char *psa_hash_algorithm_name(psa_algorithm_t hash_alg); 70 71 static void append_with_curve(char **buffer, size_t buffer_size, 72 size_t *required_size, 73 const char *string, size_t length, 74 psa_ecc_family_t curve) 75 { 76 const char *family_name = psa_ecc_family_name(curve); 77 append(buffer, buffer_size, required_size, string, length); 78 append(buffer, buffer_size, required_size, "(", 1); 79 if (family_name != NULL) { 80 append(buffer, buffer_size, required_size, 81 family_name, strlen(family_name)); 82 } else { 83 append_integer(buffer, buffer_size, required_size, 84 "0x%02x", curve); 85 } 86 append(buffer, buffer_size, required_size, ")", 1); 87 } 88 89 static void append_with_group(char **buffer, size_t buffer_size, 90 size_t *required_size, 91 const char *string, size_t length, 92 psa_dh_family_t group) 93 { 94 const char *group_name = psa_dh_family_name(group); 95 append(buffer, buffer_size, required_size, string, length); 96 append(buffer, buffer_size, required_size, "(", 1); 97 if (group_name != NULL) { 98 append(buffer, buffer_size, required_size, 99 group_name, strlen(group_name)); 100 } else { 101 append_integer(buffer, buffer_size, required_size, 102 "0x%02x", group); 103 } 104 append(buffer, buffer_size, required_size, ")", 1); 105 } 106 107 typedef const char *(*psa_get_algorithm_name_func_ptr)(psa_algorithm_t alg); 108 109 static void append_with_alg(char **buffer, size_t buffer_size, 110 size_t *required_size, 111 psa_get_algorithm_name_func_ptr get_name, 112 psa_algorithm_t alg) 113 { 114 const char *name = get_name(alg); 115 if (name != NULL) { 116 append(buffer, buffer_size, required_size, 117 name, strlen(name)); 118 } else { 119 append_integer(buffer, buffer_size, required_size, 120 "0x%08lx", alg); 121 } 122 } 123 124 #include "psa_constant_names_generated.c" 125 126 static int psa_snprint_status(char *buffer, size_t buffer_size, 127 psa_status_t status) 128 { 129 const char *name = psa_strerror(status); 130 if (name == NULL) { 131 return snprintf(buffer, buffer_size, "%ld", (long) status); 132 } else { 133 size_t length = strlen(name); 134 if (length < buffer_size) { 135 memcpy(buffer, name, length + 1); 136 return (int) length; 137 } else { 138 return (int) buffer_size; 139 } 140 } 141 } 142 143 static int psa_snprint_ecc_curve(char *buffer, size_t buffer_size, 144 psa_ecc_family_t curve) 145 { 146 const char *name = psa_ecc_family_name(curve); 147 if (name == NULL) { 148 return snprintf(buffer, buffer_size, "0x%02x", (unsigned) curve); 149 } else { 150 size_t length = strlen(name); 151 if (length < buffer_size) { 152 memcpy(buffer, name, length + 1); 153 return (int) length; 154 } else { 155 return (int) buffer_size; 156 } 157 } 158 } 159 160 static int psa_snprint_dh_group(char *buffer, size_t buffer_size, 161 psa_dh_family_t group) 162 { 163 const char *name = psa_dh_family_name(group); 164 if (name == NULL) { 165 return snprintf(buffer, buffer_size, "0x%02x", (unsigned) group); 166 } else { 167 size_t length = strlen(name); 168 if (length < buffer_size) { 169 memcpy(buffer, name, length + 1); 170 return (int) length; 171 } else { 172 return (int) buffer_size; 173 } 174 } 175 } 176 177 static void usage(const char *program_name) 178 { 179 printf("Usage: %s TYPE VALUE [VALUE...]\n", 180 program_name == NULL ? "psa_constant_names" : program_name); 181 printf("Print the symbolic name whose numerical value is VALUE in TYPE.\n"); 182 printf("Supported types (with = between aliases):\n"); 183 printf(" alg=algorithm Algorithm (psa_algorithm_t)\n"); 184 printf(" curve=ecc_curve Elliptic curve identifier (psa_ecc_family_t)\n"); 185 printf(" group=dh_group Diffie-Hellman group identifier (psa_dh_family_t)\n"); 186 printf(" type=key_type Key type (psa_key_type_t)\n"); 187 printf(" usage=key_usage Key usage (psa_key_usage_t)\n"); 188 printf(" error=status Status code (psa_status_t)\n"); 189 } 190 191 typedef enum { 192 TYPE_STATUS, 193 } signed_value_type; 194 195 static int process_signed(signed_value_type type, long min, long max, char **argp) 196 { 197 for (; *argp != NULL; argp++) { 198 char buffer[200]; 199 char *end; 200 long value = strtol(*argp, &end, 0); 201 if (*end) { 202 printf("Non-numeric value: %s\n", *argp); 203 return EXIT_FAILURE; 204 } 205 if (value < min || (errno == ERANGE && value < 0)) { 206 printf("Value too small: %s\n", *argp); 207 return EXIT_FAILURE; 208 } 209 if (value > max || (errno == ERANGE && value > 0)) { 210 printf("Value too large: %s\n", *argp); 211 return EXIT_FAILURE; 212 } 213 214 switch (type) { 215 case TYPE_STATUS: 216 psa_snprint_status(buffer, sizeof(buffer), 217 (psa_status_t) value); 218 break; 219 } 220 puts(buffer); 221 } 222 223 return EXIT_SUCCESS; 224 } 225 226 typedef enum { 227 TYPE_ALGORITHM, 228 TYPE_ECC_CURVE, 229 TYPE_DH_GROUP, 230 TYPE_KEY_TYPE, 231 TYPE_KEY_USAGE, 232 } unsigned_value_type; 233 234 static int process_unsigned(unsigned_value_type type, unsigned long max, char **argp) 235 { 236 for (; *argp != NULL; argp++) { 237 char buffer[200]; 238 char *end; 239 unsigned long value = strtoul(*argp, &end, 0); 240 if (*end) { 241 printf("Non-numeric value: %s\n", *argp); 242 return EXIT_FAILURE; 243 } 244 if (value > max || errno == ERANGE) { 245 printf("Value out of range: %s\n", *argp); 246 return EXIT_FAILURE; 247 } 248 249 switch (type) { 250 case TYPE_ALGORITHM: 251 psa_snprint_algorithm(buffer, sizeof(buffer), 252 (psa_algorithm_t) value); 253 break; 254 case TYPE_ECC_CURVE: 255 psa_snprint_ecc_curve(buffer, sizeof(buffer), 256 (psa_ecc_family_t) value); 257 break; 258 case TYPE_DH_GROUP: 259 psa_snprint_dh_group(buffer, sizeof(buffer), 260 (psa_dh_family_t) value); 261 break; 262 case TYPE_KEY_TYPE: 263 psa_snprint_key_type(buffer, sizeof(buffer), 264 (psa_key_type_t) value); 265 break; 266 case TYPE_KEY_USAGE: 267 psa_snprint_key_usage(buffer, sizeof(buffer), 268 (psa_key_usage_t) value); 269 break; 270 } 271 puts(buffer); 272 } 273 274 return EXIT_SUCCESS; 275 } 276 277 int main(int argc, char *argv[]) 278 { 279 if (argc <= 1 || 280 !strcmp(argv[1], "help") || 281 !strcmp(argv[1], "--help")) { 282 usage(argv[0]); 283 return EXIT_FAILURE; 284 } 285 286 if (!strcmp(argv[1], "error") || !strcmp(argv[1], "status")) { 287 /* There's no way to obtain the actual range of a signed type, 288 * so hard-code it here: psa_status_t is int32_t. */ 289 return process_signed(TYPE_STATUS, INT32_MIN, INT32_MAX, 290 argv + 2); 291 } else if (!strcmp(argv[1], "alg") || !strcmp(argv[1], "algorithm")) { 292 return process_unsigned(TYPE_ALGORITHM, (psa_algorithm_t) (-1), 293 argv + 2); 294 } else if (!strcmp(argv[1], "curve") || !strcmp(argv[1], "ecc_curve")) { 295 return process_unsigned(TYPE_ECC_CURVE, (psa_ecc_family_t) (-1), 296 argv + 2); 297 } else if (!strcmp(argv[1], "group") || !strcmp(argv[1], "dh_group")) { 298 return process_unsigned(TYPE_DH_GROUP, (psa_dh_family_t) (-1), 299 argv + 2); 300 } else if (!strcmp(argv[1], "type") || !strcmp(argv[1], "key_type")) { 301 return process_unsigned(TYPE_KEY_TYPE, (psa_key_type_t) (-1), 302 argv + 2); 303 } else if (!strcmp(argv[1], "usage") || !strcmp(argv[1], "key_usage")) { 304 return process_unsigned(TYPE_KEY_USAGE, (psa_key_usage_t) (-1), 305 argv + 2); 306 } else { 307 printf("Unknown type: %s\n", argv[1]); 308 return EXIT_FAILURE; 309 } 310 }