blob: dd19677c4b0fd2bb20c0009a076678a02b0cd32d [file] [log] [blame]
Gilles Peskine029b5d62018-07-16 23:13:37 +02001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "psa/crypto.h"
6
Darryl Green608e0912018-10-17 14:48:27 +01007/* This block is present to support Visual Studio builds prior to 2015 */
8#if defined(_MSC_VER) && _MSC_VER < 1900
9#include <stdarg.h>
10int snprintf( char *s, size_t n, const char *fmt, ... )
11{
12 int ret;
13 va_list argp;
14
15 /* Avoid calling the invalid parameter handler by checking ourselves */
16 if( s == NULL || n == 0 || fmt == NULL )
17 return( -1 );
18
19 va_start( argp, fmt );
20#if defined(_TRUNCATE) && !defined(__MINGW32__)
21 ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp );
22#else
23 ret = _vsnprintf( s, n, fmt, argp );
24 if( ret < 0 || (size_t) ret == n )
25 {
26 s[n-1] = '\0';
27 ret = -1;
28 }
29#endif
30 va_end( argp );
31
32 return( ret );
33}
34#endif
35
Gilles Peskine029b5d62018-07-16 23:13:37 +020036/* There are different GET_HASH macros for different kinds of algorithms
37 * built from hashes, but the values are all constructed on the
38 * same model. */
39#define PSA_ALG_GET_HASH(alg) \
40 (((alg) & PSA_ALG_HASH_MASK) | PSA_ALG_CATEGORY_HASH)
41
42static void append(char **buffer, size_t buffer_size,
43 size_t *required_size,
44 const char *string, size_t length)
45{
46 *required_size += length;
47 if (*required_size < buffer_size) {
48 memcpy(*buffer, string, length);
49 *buffer += length;
50 }
51}
52
Gilles Peskine0deaf3d2018-08-20 15:06:39 +020053static void append_integer(char **buffer, size_t buffer_size,
54 size_t *required_size,
55 const char *format /*printf format for value*/,
56 unsigned long value)
57{
58 size_t n = snprintf(*buffer, buffer_size - *required_size, format, value);
59 if (n < buffer_size - *required_size) *buffer += n;
60 *required_size += n;
61}
62
Gilles Peskine029b5d62018-07-16 23:13:37 +020063/* The code of these function is automatically generated and included below. */
64static const char *psa_ecc_curve_name(psa_ecc_curve_t curve);
65static const char *psa_hash_algorithm_name(psa_algorithm_t hash_alg);
66
67static void append_with_curve(char **buffer, size_t buffer_size,
68 size_t *required_size,
69 const char *string, size_t length,
70 psa_ecc_curve_t curve)
71{
72 const char *curve_name = psa_ecc_curve_name(curve);
73 append(buffer, buffer_size, required_size, string, length);
74 append(buffer, buffer_size, required_size, "(", 1);
75 if (curve_name != NULL) {
76 append(buffer, buffer_size, required_size,
77 curve_name, strlen(curve_name));
78 } else {
Gilles Peskine0deaf3d2018-08-20 15:06:39 +020079 append_integer(buffer, buffer_size, required_size,
80 "0x%04x", curve);
Gilles Peskine029b5d62018-07-16 23:13:37 +020081 }
82 append(buffer, buffer_size, required_size, ")", 1);
83}
84
85static void append_with_hash(char **buffer, size_t buffer_size,
86 size_t *required_size,
87 const char *string, size_t length,
88 psa_algorithm_t hash_alg)
89{
90 const char *hash_name = psa_hash_algorithm_name(hash_alg);
91 append(buffer, buffer_size, required_size, string, length);
92 append(buffer, buffer_size, required_size, "(", 1);
93 if (hash_name != NULL) {
94 append(buffer, buffer_size, required_size,
95 hash_name, strlen(hash_name));
96 } else {
Gilles Peskine0deaf3d2018-08-20 15:06:39 +020097 append_integer(buffer, buffer_size, required_size,
98 "0x%08lx", hash_alg);
Gilles Peskine029b5d62018-07-16 23:13:37 +020099 }
100 append(buffer, buffer_size, required_size, ")", 1);
101}
102
103#include "psa_constant_names_generated.c"
104
105static int psa_snprint_status(char *buffer, size_t buffer_size,
106 psa_status_t status)
107{
108 const char *name = psa_strerror(status);
109 if (name == NULL) {
110 return snprintf(buffer, buffer_size, "%ld", (long) status);
111 } else {
112 size_t length = strlen(name);
113 if (length < buffer_size) {
114 memcpy(buffer, name, length + 1);
Darryl Green18246962018-10-17 15:01:45 +0100115 return (int) length;
Gilles Peskine029b5d62018-07-16 23:13:37 +0200116 } else {
Darryl Green18246962018-10-17 15:01:45 +0100117 return (int) buffer_size;
Gilles Peskine029b5d62018-07-16 23:13:37 +0200118 }
119 }
120}
121
122static int psa_snprint_ecc_curve(char *buffer, size_t buffer_size,
123 psa_ecc_curve_t curve)
124{
125 const char *name = psa_ecc_curve_name(curve);
126 if (name == NULL) {
127 return snprintf(buffer, buffer_size, "0x%04x", (unsigned) curve);
128 } else {
129 size_t length = strlen(name);
130 if (length < buffer_size) {
131 memcpy(buffer, name, length + 1);
Darryl Green18246962018-10-17 15:01:45 +0100132 return (int) length;
Gilles Peskine029b5d62018-07-16 23:13:37 +0200133 } else {
Darryl Green18246962018-10-17 15:01:45 +0100134 return (int) buffer_size;
Gilles Peskine029b5d62018-07-16 23:13:37 +0200135 }
136 }
137}
138
139static void usage(const char *program_name)
140{
141 printf("Usage: %s TYPE VALUE\n",
142 program_name == NULL ? "psa_constant_names" : program_name);
143 printf("Print the symbolic name whose numerical value is VALUE in TYPE.\n");
144 printf("Supported types (with = between aliases):\n");
Gilles Peskine38808fa2018-08-20 15:07:37 +0200145 printf(" alg=algorithm Algorithm (psa_algorithm_t)\n");
Gilles Peskine029b5d62018-07-16 23:13:37 +0200146 printf(" curve=ecc_curve Elliptic curve identifier (psa_ecc_curve_t)\n");
Gilles Peskine38808fa2018-08-20 15:07:37 +0200147 printf(" type=key_type Key type (psa_key_type_t)\n");
Gilles Peskine029b5d62018-07-16 23:13:37 +0200148 printf(" usage=key_usage Key usage (psa_key_usage_t)\n");
149 printf(" error=status Status code (psa_status_t)\n");
150}
151
152int main(int argc, char *argv[])
153{
154 char buffer[200];
155 unsigned long value;
156 char *end;
157
158 if (argc <= 1 ||
159 !strcmp(argv[1], "help") ||
160 !strcmp(argv[1], "--help"))
161 {
162 usage(argv[0]);
163 return EXIT_FAILURE;
164 }
165 if (argc != 3) {
166 usage(argv[0]);
167 return EXIT_FAILURE;
168 }
169 value = strtoul(argv[2], &end, 0);
170 if (*end) {
171 printf("Non-numeric value: %s\n", argv[2]);
172 return EXIT_FAILURE;
173 }
174
175 if (!strcmp(argv[1], "error") || !strcmp(argv[1], "status"))
Darryl Green18246962018-10-17 15:01:45 +0100176 psa_snprint_status(buffer, sizeof(buffer), (psa_status_t) value);
Gilles Peskine029b5d62018-07-16 23:13:37 +0200177 else if (!strcmp(argv[1], "alg") || !strcmp(argv[1], "algorithm"))
Darryl Green18246962018-10-17 15:01:45 +0100178 psa_snprint_algorithm(buffer, sizeof(buffer), (psa_algorithm_t) value);
Gilles Peskine029b5d62018-07-16 23:13:37 +0200179 else if (!strcmp(argv[1], "curve") || !strcmp(argv[1], "ecc_curve"))
Darryl Green18246962018-10-17 15:01:45 +0100180 psa_snprint_ecc_curve(buffer, sizeof(buffer), (psa_ecc_curve_t) value);
Gilles Peskine029b5d62018-07-16 23:13:37 +0200181 else if (!strcmp(argv[1], "type") || !strcmp(argv[1], "key_type"))
Darryl Green18246962018-10-17 15:01:45 +0100182 psa_snprint_key_type(buffer, sizeof(buffer), (psa_key_type_t) value);
Gilles Peskine029b5d62018-07-16 23:13:37 +0200183 else if (!strcmp(argv[1], "usage") || !strcmp(argv[1], "key_usage"))
Darryl Green18246962018-10-17 15:01:45 +0100184 psa_snprint_key_usage(buffer, sizeof(buffer), (psa_key_usage_t) value);
Gilles Peskine029b5d62018-07-16 23:13:37 +0200185 else {
186 printf("Unknown type: %s\n", argv[1]);
187 return EXIT_FAILURE;
188 }
189
190 puts(buffer);
191 return EXIT_SUCCESS;
192}