xref: /freebsd/contrib/bearssl/tools/names.c (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1 /*
2  * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #include "brssl.h"
26 #include "bearssl.h"
27 
28 /* see brssl.h */
29 const protocol_version protocol_versions[] = {
30 	{ "tls10", BR_TLS10, "TLS 1.0" },
31 	{ "tls11", BR_TLS11, "TLS 1.1" },
32 	{ "tls12", BR_TLS12, "TLS 1.2" },
33 	{ NULL, 0, NULL }
34 };
35 
36 /* see brssl.h */
37 const hash_function hash_functions[] = {
38 	{ "md5",     &br_md5_vtable,     "MD5" },
39 	{ "sha1",    &br_sha1_vtable,    "SHA-1" },
40 	{ "sha224",  &br_sha224_vtable,  "SHA-224" },
41 	{ "sha256",  &br_sha256_vtable,  "SHA-256" },
42 	{ "sha384",  &br_sha384_vtable,  "SHA-384" },
43 	{ "sha512",  &br_sha512_vtable,  "SHA-512" },
44 	{ NULL, 0, NULL }
45 };
46 
47 /* see brssl.h */
48 const cipher_suite cipher_suites[] = {
49 	{
50 		"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
51 		BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
52 		REQ_ECDHE_ECDSA | REQ_CHAPOL | REQ_SHA256 | REQ_TLS12,
53 		"ECDHE with ECDSA, ChaCha20+Poly1305 encryption (TLS 1.2+)"
54 	},
55 	{
56 		"ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
57 		BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
58 		REQ_ECDHE_RSA | REQ_CHAPOL | REQ_SHA256 | REQ_TLS12,
59 		"ECDHE with RSA, ChaCha20+Poly1305 encryption (TLS 1.2+)"
60 	},
61 	{
62 		"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
63 		BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
64 		REQ_ECDHE_ECDSA | REQ_AESGCM | REQ_SHA256 | REQ_TLS12,
65 		"ECDHE with ECDSA, AES-128/GCM encryption (TLS 1.2+)"
66 	},
67 	{
68 		"ECDHE_RSA_WITH_AES_128_GCM_SHA256",
69 		BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
70 		REQ_ECDHE_RSA | REQ_AESGCM | REQ_SHA256 | REQ_TLS12,
71 		"ECDHE with RSA, AES-128/GCM encryption (TLS 1.2+)"
72 	},
73 	{
74 		"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
75 		BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
76 		REQ_ECDHE_ECDSA | REQ_AESGCM | REQ_SHA384 | REQ_TLS12,
77 		"ECDHE with ECDSA, AES-256/GCM encryption (TLS 1.2+)"
78 	},
79 	{
80 		"ECDHE_RSA_WITH_AES_256_GCM_SHA384",
81 		BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
82 		REQ_ECDHE_RSA | REQ_AESGCM | REQ_SHA384 | REQ_TLS12,
83 		"ECDHE with RSA, AES-256/GCM encryption (TLS 1.2+)"
84 	},
85 	{
86 		"ECDHE_ECDSA_WITH_AES_128_CCM",
87 		BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
88 		REQ_ECDHE_ECDSA | REQ_AESCCM | REQ_SHA256 | REQ_TLS12,
89 		"ECDHE with ECDSA, AES-128/CCM encryption (TLS 1.2+)"
90 	},
91 	{
92 		"ECDHE_ECDSA_WITH_AES_256_CCM",
93 		BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM,
94 		REQ_ECDHE_ECDSA | REQ_AESCCM | REQ_SHA256 | REQ_TLS12,
95 		"ECDHE with ECDSA, AES-256/CCM encryption (TLS 1.2+)"
96 	},
97 	{
98 		"ECDHE_ECDSA_WITH_AES_128_CCM_8",
99 		BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
100 		REQ_ECDHE_ECDSA | REQ_AESCCM | REQ_SHA256 | REQ_TLS12,
101 		"ECDHE with ECDSA, AES-128/CCM_8 encryption (TLS 1.2+)"
102 	},
103 	{
104 		"ECDHE_ECDSA_WITH_AES_256_CCM_8",
105 		BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8,
106 		REQ_ECDHE_ECDSA | REQ_AESCCM | REQ_SHA256 | REQ_TLS12,
107 		"ECDHE with ECDSA, AES-256/CCM_8 encryption (TLS 1.2+)"
108 	},
109 	{
110 		"ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
111 		BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
112 		REQ_ECDHE_ECDSA | REQ_AESCBC | REQ_SHA256 | REQ_TLS12,
113 		"ECDHE with ECDSA, AES-128/CBC + SHA-256 (TLS 1.2+)"
114 	},
115 	{
116 		"ECDHE_RSA_WITH_AES_128_CBC_SHA256",
117 		BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
118 		REQ_ECDHE_RSA | REQ_AESCBC | REQ_SHA256 | REQ_TLS12,
119 		"ECDHE with RSA, AES-128/CBC + SHA-256 (TLS 1.2+)"
120 	},
121 	{
122 		"ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
123 		BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
124 		REQ_ECDHE_ECDSA | REQ_AESCBC | REQ_SHA384 | REQ_TLS12,
125 		"ECDHE with ECDSA, AES-256/CBC + SHA-384 (TLS 1.2+)"
126 	},
127 	{
128 		"ECDHE_RSA_WITH_AES_256_CBC_SHA384",
129 		BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
130 		REQ_ECDHE_RSA | REQ_AESCBC | REQ_SHA384 | REQ_TLS12,
131 		"ECDHE with RSA, AES-256/CBC + SHA-384 (TLS 1.2+)"
132 	},
133 	{
134 		"ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
135 		BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
136 		REQ_ECDHE_ECDSA | REQ_AESCBC | REQ_SHA1,
137 		"ECDHE with ECDSA, AES-128/CBC + SHA-1"
138 	},
139 	{
140 		"ECDHE_RSA_WITH_AES_128_CBC_SHA",
141 		BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
142 		REQ_ECDHE_RSA | REQ_AESCBC | REQ_SHA1,
143 		"ECDHE with RSA, AES-128/CBC + SHA-1"
144 	},
145 	{
146 		"ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
147 		BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
148 		REQ_ECDHE_ECDSA | REQ_AESCBC | REQ_SHA1,
149 		"ECDHE with ECDSA, AES-256/CBC + SHA-1"
150 	},
151 	{
152 		"ECDHE_RSA_WITH_AES_256_CBC_SHA",
153 		BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
154 		REQ_ECDHE_RSA | REQ_AESCBC | REQ_SHA1,
155 		"ECDHE with RSA, AES-256/CBC + SHA-1"
156 	},
157 	{
158 		"ECDH_ECDSA_WITH_AES_128_GCM_SHA256",
159 		BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
160 		REQ_ECDH | REQ_AESGCM | REQ_SHA256 | REQ_TLS12,
161 		"ECDH key exchange (EC cert), AES-128/GCM (TLS 1.2+)"
162 	},
163 	{
164 		"ECDH_RSA_WITH_AES_128_GCM_SHA256",
165 		BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
166 		REQ_ECDH | REQ_AESGCM | REQ_SHA256 | REQ_TLS12,
167 		"ECDH key exchange (RSA cert), AES-128/GCM (TLS 1.2+)"
168 	},
169 	{
170 		"ECDH_ECDSA_WITH_AES_256_GCM_SHA384",
171 		BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
172 		REQ_ECDH | REQ_AESGCM | REQ_SHA384 | REQ_TLS12,
173 		"ECDH key exchange (EC cert), AES-256/GCM (TLS 1.2+)"
174 	},
175 	{
176 		"ECDH_RSA_WITH_AES_256_GCM_SHA384",
177 		BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
178 		REQ_ECDH | REQ_AESGCM | REQ_SHA384 | REQ_TLS12,
179 		"ECDH key exchange (RSA cert), AES-256/GCM (TLS 1.2+)"
180 	},
181 	{
182 		"ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
183 		BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
184 		REQ_ECDH | REQ_AESCBC | REQ_SHA256 | REQ_TLS12,
185 		"ECDH key exchange (EC cert), AES-128/CBC + HMAC/SHA-256 (TLS 1.2+)"
186 	},
187 	{
188 		"ECDH_RSA_WITH_AES_128_CBC_SHA256",
189 		BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
190 		REQ_ECDH | REQ_AESCBC | REQ_SHA256 | REQ_TLS12,
191 		"ECDH key exchange (RSA cert), AES-128/CBC + HMAC/SHA-256 (TLS 1.2+)"
192 	},
193 	{
194 		"ECDH_ECDSA_WITH_AES_256_CBC_SHA384",
195 		BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
196 		REQ_ECDH | REQ_AESCBC | REQ_SHA384 | REQ_TLS12,
197 		"ECDH key exchange (EC cert), AES-256/CBC + HMAC/SHA-384 (TLS 1.2+)"
198 	},
199 	{
200 		"ECDH_RSA_WITH_AES_256_CBC_SHA384",
201 		BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
202 		REQ_ECDH | REQ_AESCBC | REQ_SHA384 | REQ_TLS12,
203 		"ECDH key exchange (RSA cert), AES-256/CBC + HMAC/SHA-384 (TLS 1.2+)"
204 	},
205 	{
206 		"ECDH_ECDSA_WITH_AES_128_CBC_SHA",
207 		BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
208 		REQ_ECDH | REQ_AESCBC | REQ_SHA1,
209 		"ECDH key exchange (EC cert), AES-128/CBC + HMAC/SHA-1"
210 	},
211 	{
212 		"ECDH_RSA_WITH_AES_128_CBC_SHA",
213 		BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
214 		REQ_ECDH | REQ_AESCBC | REQ_SHA1,
215 		"ECDH key exchange (RSA cert), AES-128/CBC + HMAC/SHA-1"
216 	},
217 	{
218 		"ECDH_ECDSA_WITH_AES_256_CBC_SHA",
219 		BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
220 		REQ_ECDH | REQ_AESCBC | REQ_SHA1,
221 		"ECDH key exchange (EC cert), AES-256/CBC + HMAC/SHA-1"
222 	},
223 	{
224 		"ECDH_RSA_WITH_AES_256_CBC_SHA",
225 		BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
226 		REQ_ECDH | REQ_AESCBC | REQ_SHA1,
227 		"ECDH key exchange (RSA cert), AES-256/CBC + HMAC/SHA-1"
228 	},
229 	{
230 		"RSA_WITH_AES_128_GCM_SHA256",
231 		BR_TLS_RSA_WITH_AES_128_GCM_SHA256,
232 		REQ_RSAKEYX | REQ_AESGCM | REQ_SHA256 | REQ_TLS12,
233 		"RSA key exchange, AES-128/GCM encryption (TLS 1.2+)"
234 	},
235 	{
236 		"RSA_WITH_AES_256_GCM_SHA384",
237 		BR_TLS_RSA_WITH_AES_256_GCM_SHA384,
238 		REQ_RSAKEYX | REQ_AESGCM | REQ_SHA384 | REQ_TLS12,
239 		"RSA key exchange, AES-256/GCM encryption (TLS 1.2+)"
240 	},
241 	{
242 		"RSA_WITH_AES_128_CCM",
243 		BR_TLS_RSA_WITH_AES_128_CCM,
244 		REQ_RSAKEYX | REQ_AESCCM | REQ_SHA256 | REQ_TLS12,
245 		"RSA key exchange, AES-128/CCM encryption (TLS 1.2+)"
246 	},
247 	{
248 		"RSA_WITH_AES_256_CCM",
249 		BR_TLS_RSA_WITH_AES_256_CCM,
250 		REQ_RSAKEYX | REQ_AESCCM | REQ_SHA256 | REQ_TLS12,
251 		"RSA key exchange, AES-256/CCM encryption (TLS 1.2+)"
252 	},
253 	{
254 		"RSA_WITH_AES_128_CCM_8",
255 		BR_TLS_RSA_WITH_AES_128_CCM_8,
256 		REQ_RSAKEYX | REQ_AESCCM | REQ_SHA256 | REQ_TLS12,
257 		"RSA key exchange, AES-128/CCM_8 encryption (TLS 1.2+)"
258 	},
259 	{
260 		"RSA_WITH_AES_256_CCM_8",
261 		BR_TLS_RSA_WITH_AES_256_CCM_8,
262 		REQ_RSAKEYX | REQ_AESCCM | REQ_SHA256 | REQ_TLS12,
263 		"RSA key exchange, AES-256/CCM_8 encryption (TLS 1.2+)"
264 	},
265 	{
266 		"RSA_WITH_AES_128_CBC_SHA256",
267 		BR_TLS_RSA_WITH_AES_128_CBC_SHA256,
268 		REQ_RSAKEYX | REQ_AESCBC | REQ_SHA256 | REQ_TLS12,
269 		"RSA key exchange, AES-128/CBC + HMAC/SHA-256 (TLS 1.2+)"
270 	},
271 	{
272 		"RSA_WITH_AES_256_CBC_SHA256",
273 		BR_TLS_RSA_WITH_AES_256_CBC_SHA256,
274 		REQ_RSAKEYX | REQ_AESCBC | REQ_SHA256 | REQ_TLS12,
275 		"RSA key exchange, AES-256/CBC + HMAC/SHA-256 (TLS 1.2+)"
276 	},
277 	{
278 		"RSA_WITH_AES_128_CBC_SHA",
279 		BR_TLS_RSA_WITH_AES_128_CBC_SHA,
280 		REQ_RSAKEYX | REQ_AESCBC | REQ_SHA1,
281 		"RSA key exchange, AES-128/CBC + HMAC/SHA-1"
282 	},
283 	{
284 		"RSA_WITH_AES_256_CBC_SHA",
285 		BR_TLS_RSA_WITH_AES_256_CBC_SHA,
286 		REQ_RSAKEYX | REQ_AESCBC | REQ_SHA1,
287 		"RSA key exchange, AES-256/CBC + HMAC/SHA-1"
288 	},
289 	{
290 		"ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
291 		BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
292 		REQ_ECDHE_ECDSA | REQ_3DESCBC | REQ_SHA1,
293 		"ECDHE with ECDSA, 3DES/CBC + SHA-1"
294 	},
295 	{
296 		"ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
297 		BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
298 		REQ_ECDHE_RSA | REQ_3DESCBC | REQ_SHA1,
299 		"ECDHE with RSA, 3DES/CBC + SHA-1"
300 	},
301 	{
302 		"ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
303 		BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
304 		REQ_ECDH | REQ_3DESCBC | REQ_SHA1,
305 		"ECDH key exchange (EC cert), 3DES/CBC + HMAC/SHA-1"
306 	},
307 	{
308 		"ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
309 		BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
310 		REQ_ECDH | REQ_3DESCBC | REQ_SHA1,
311 		"ECDH key exchange (RSA cert), 3DES/CBC + HMAC/SHA-1"
312 	},
313 	{
314 		"RSA_WITH_3DES_EDE_CBC_SHA",
315 		BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
316 		REQ_RSAKEYX | REQ_3DESCBC | REQ_SHA1,
317 		"RSA key exchange, 3DES/CBC + HMAC/SHA-1"
318 	},
319 	{ NULL, 0, 0, NULL }
320 };
321 
322 static const struct {
323 	int id;
324 	const char *name;
325 	const char *sid[4];
326 } curves[] = {
327 	{ BR_EC_sect163k1,
328 	  "sect163k1",
329 	  { "sect163k1", "K-163", NULL, NULL } },
330 	{ BR_EC_sect163r1,
331 	  "sect163r1",
332 	  { "sect163r1", NULL, NULL, NULL } },
333 	{ BR_EC_sect163r2,
334 	  "sect163r2",
335 	  { "sect163r2", "B-163", NULL, NULL } },
336 	{ BR_EC_sect193r1,
337 	  "sect193r1",
338 	  { "sect193r1", NULL, NULL, NULL } },
339 	{ BR_EC_sect193r2,
340 	  "sect193r2",
341 	  { "sect193r2", NULL, NULL, NULL } },
342 	{ BR_EC_sect233k1,
343 	  "sect233k1",
344 	  { "sect233k1", "K-233", NULL, NULL } },
345 	{ BR_EC_sect233r1,
346 	  "sect233r1",
347 	  { "sect233r1", "B-233", NULL, NULL } },
348 	{ BR_EC_sect239k1,
349 	  "sect239k1",
350 	  { "sect239k1", NULL, NULL, NULL } },
351 	{ BR_EC_sect283k1,
352 	  "sect283k1",
353 	  { "sect283k1", "K-283", NULL, NULL } },
354 	{ BR_EC_sect283r1,
355 	  "sect283r1",
356 	  { "sect283r1", "B-283", NULL, NULL } },
357 	{ BR_EC_sect409k1,
358 	  "sect409k1",
359 	  { "sect409k1", "K-409", NULL, NULL } },
360 	{ BR_EC_sect409r1,
361 	  "sect409r1",
362 	  { "sect409r1", "B-409", NULL, NULL } },
363 	{ BR_EC_sect571k1,
364 	  "sect571k1",
365 	  { "sect571k1", "K-571", NULL, NULL } },
366 	{ BR_EC_sect571r1,
367 	  "sect571r1",
368 	  { "sect571r1", "B-571", NULL, NULL } },
369 	{ BR_EC_secp160k1,
370 	  "secp160k1",
371 	  { "secp160k1", NULL, NULL, NULL } },
372 	{ BR_EC_secp160r1,
373 	  "secp160r1",
374 	  { "secp160r1", NULL, NULL, NULL } },
375 	{ BR_EC_secp160r2,
376 	  "secp160r2",
377 	  { "secp160r2", NULL, NULL, NULL } },
378 	{ BR_EC_secp192k1,
379 	  "secp192k1",
380 	  { "secp192k1", NULL, NULL, NULL } },
381 	{ BR_EC_secp192r1,
382 	  "secp192r1",
383 	  { "secp192r1", "P-192", NULL, NULL } },
384 	{ BR_EC_secp224k1,
385 	  "secp224k1",
386 	  { "secp224k1", NULL, NULL, NULL } },
387 	{ BR_EC_secp224r1,
388 	  "secp224r1",
389 	  { "secp224r1", "P-224", NULL, NULL } },
390 	{ BR_EC_secp256k1,
391 	  "secp256k1",
392 	  { "secp256k1", NULL, NULL, NULL } },
393 	{ BR_EC_secp256r1,
394 	  "secp256r1 (P-256)",
395 	  { "secp256r1", "P-256", "prime256v1", NULL } },
396 	{ BR_EC_secp384r1,
397 	  "secp384r1 (P-384)",
398 	  { "secp384r1", "P-384", NULL, NULL } },
399 	{ BR_EC_secp521r1,
400 	  "secp521r1 (P-521)",
401 	  { "secp521r1", "P-521", NULL, NULL } },
402 	{ BR_EC_brainpoolP256r1,
403 	  "brainpoolP256r1",
404 	  { "brainpoolP256r1", NULL, NULL, NULL } },
405 	{ BR_EC_brainpoolP384r1,
406 	  "brainpoolP384r1",
407 	  { "brainpoolP384r1", NULL, NULL, NULL } },
408 	{ BR_EC_brainpoolP512r1,
409 	  "brainpoolP512r1",
410 	  { "brainpoolP512r1", NULL, NULL, NULL } },
411 	{ BR_EC_curve25519,
412 	  "Curve25519",
413 	  { "curve25519", "c25519", NULL, NULL } },
414 	{ BR_EC_curve448,
415 	  "Curve448",
416 	  { "curve448", "c448", NULL, NULL } },
417 	{ 0, 0, { 0, 0, 0, 0 } }
418 };
419 
420 static const struct {
421 	const char *long_name;
422 	const char *short_name;
423 	const void *impl;
424 } algo_names[] = {
425 	/* Block ciphers */
426 	{ "aes_big_cbcenc",    "big",         &br_aes_big_cbcenc_vtable },
427 	{ "aes_big_cbcdec",    "big",         &br_aes_big_cbcdec_vtable },
428 	{ "aes_big_ctr",       "big",         &br_aes_big_ctr_vtable },
429 	{ "aes_big_ctrcbc",    "big",         &br_aes_big_ctrcbc_vtable },
430 	{ "aes_small_cbcenc",  "small",       &br_aes_small_cbcenc_vtable },
431 	{ "aes_small_cbcdec",  "small",       &br_aes_small_cbcdec_vtable },
432 	{ "aes_small_ctr",     "small",       &br_aes_small_ctr_vtable },
433 	{ "aes_small_ctrcbc",  "small",       &br_aes_small_ctrcbc_vtable },
434 	{ "aes_ct_cbcenc",     "ct",          &br_aes_ct_cbcenc_vtable },
435 	{ "aes_ct_cbcdec",     "ct",          &br_aes_ct_cbcdec_vtable },
436 	{ "aes_ct_ctr",        "ct",          &br_aes_ct_ctr_vtable },
437 	{ "aes_ct_ctrcbc",     "ct",          &br_aes_ct_ctrcbc_vtable },
438 	{ "aes_ct64_cbcenc",   "ct64",        &br_aes_ct64_cbcenc_vtable },
439 	{ "aes_ct64_cbcdec",   "ct64",        &br_aes_ct64_cbcdec_vtable },
440 	{ "aes_ct64_ctr",      "ct64",        &br_aes_ct64_ctr_vtable },
441 	{ "aes_ct64_ctrcbc",   "ct64",        &br_aes_ct64_ctrcbc_vtable },
442 
443 	{ "des_tab_cbcenc",    "tab",         &br_des_tab_cbcenc_vtable },
444 	{ "des_tab_cbcdec",    "tab",         &br_des_tab_cbcdec_vtable },
445 	{ "des_ct_cbcenc",     "ct",          &br_des_ct_cbcenc_vtable },
446 	{ "des_ct_cbcdec",     "ct",          &br_des_ct_cbcdec_vtable },
447 
448 	{ "chacha20_ct",       "ct",          &br_chacha20_ct_run },
449 
450 	{ "ghash_ctmul",       "ctmul",       &br_ghash_ctmul },
451 	{ "ghash_ctmul32",     "ctmul32",     &br_ghash_ctmul32 },
452 	{ "ghash_ctmul64",     "ctmul64",     &br_ghash_ctmul64 },
453 
454 	{ "poly1305_ctmul",    "ctmul",       &br_poly1305_ctmul_run },
455 	{ "poly1305_ctmul32",  "ctmul32",     &br_poly1305_ctmul32_run },
456 
457 	{ "ec_all_m15",        "all_m15",     &br_ec_all_m15 },
458 	{ "ec_all_m31",        "all_m31",     &br_ec_all_m31 },
459 	{ "ec_c25519_i15",     "c25519_i15",  &br_ec_c25519_i15 },
460 	{ "ec_c25519_i31",     "c25519_i31",  &br_ec_c25519_i31 },
461 	{ "ec_c25519_m15",     "c25519_m15",  &br_ec_c25519_m15 },
462 	{ "ec_c25519_m31",     "c25519_m31",  &br_ec_c25519_m31 },
463 	{ "ec_p256_m15",       "p256_m15",    &br_ec_p256_m15 },
464 	{ "ec_p256_m31",       "p256_m31",    &br_ec_p256_m31 },
465 	{ "ec_prime_i15",      "prime_i15",   &br_ec_prime_i15 },
466 	{ "ec_prime_i31",      "prime_i31",   &br_ec_prime_i31 },
467 
468 	{ "ecdsa_i15_sign_asn1",  "i15_asn1",  &br_ecdsa_i15_sign_asn1 },
469 	{ "ecdsa_i15_sign_raw",   "i15_raw",   &br_ecdsa_i15_sign_raw },
470 	{ "ecdsa_i31_sign_asn1",  "i31_asn1",  &br_ecdsa_i31_sign_asn1 },
471 	{ "ecdsa_i31_sign_raw",   "i31_raw",   &br_ecdsa_i31_sign_raw },
472 	{ "ecdsa_i15_vrfy_asn1",  "i15_asn1",  &br_ecdsa_i15_vrfy_asn1 },
473 	{ "ecdsa_i15_vrfy_raw",   "i15_raw",   &br_ecdsa_i15_vrfy_raw },
474 	{ "ecdsa_i31_vrfy_asn1",  "i31_asn1",  &br_ecdsa_i31_vrfy_asn1 },
475 	{ "ecdsa_i31_vrfy_raw",   "i31_raw",   &br_ecdsa_i31_vrfy_raw },
476 
477 	{ "rsa_i15_pkcs1_sign",   "i15",       &br_rsa_i15_pkcs1_sign },
478 	{ "rsa_i31_pkcs1_sign",   "i31",       &br_rsa_i31_pkcs1_sign },
479 	{ "rsa_i32_pkcs1_sign",   "i32",       &br_rsa_i32_pkcs1_sign },
480 	{ "rsa_i15_pkcs1_vrfy",   "i15",       &br_rsa_i15_pkcs1_vrfy },
481 	{ "rsa_i31_pkcs1_vrfy",   "i31",       &br_rsa_i31_pkcs1_vrfy },
482 	{ "rsa_i32_pkcs1_vrfy",   "i32",       &br_rsa_i32_pkcs1_vrfy },
483 
484 	{ 0, 0, 0 }
485 };
486 
487 static const struct {
488 	const char *long_name;
489 	const char *short_name;
490 	const void *(*get)(void);
491 } algo_names_dyn[] = {
492 	{ "aes_pwr8_cbcenc",      "pwr8",
493 		(const void *(*)(void))&br_aes_pwr8_cbcenc_get_vtable },
494 	{ "aes_pwr8_cbcdec",      "pwr8",
495 		(const void *(*)(void))&br_aes_pwr8_cbcdec_get_vtable },
496 	{ "aes_pwr8_ctr",         "pwr8",
497 		(const void *(*)(void))&br_aes_pwr8_ctr_get_vtable },
498 	{ "aes_pwr8_ctrcbc",      "pwr8",
499 		(const void *(*)(void))&br_aes_pwr8_ctrcbc_get_vtable },
500 	{ "aes_x86ni_cbcenc",     "x86ni",
501 		(const void *(*)(void))&br_aes_x86ni_cbcenc_get_vtable },
502 	{ "aes_x86ni_cbcdec",     "x86ni",
503 		(const void *(*)(void))&br_aes_x86ni_cbcdec_get_vtable },
504 	{ "aes_x86ni_ctr",        "x86ni",
505 		(const void *(*)(void))&br_aes_x86ni_ctr_get_vtable },
506 	{ "aes_x86ni_ctrcbc",     "x86ni",
507 		(const void *(*)(void))&br_aes_x86ni_ctrcbc_get_vtable },
508 	{ "chacha20_sse2",        "sse2",
509 		(const void *(*)(void))&br_chacha20_sse2_get },
510 	{ "ghash_pclmul",         "pclmul",
511 		(const void *(*)(void))&br_ghash_pclmul_get },
512 	{ "ghash_pwr8",           "pwr8",
513 		(const void *(*)(void))&br_ghash_pwr8_get },
514 	{ "poly1305_ctmulq",      "ctmulq",
515 		(const void *(*)(void))&br_poly1305_ctmulq_get },
516 	{ "rsa_i62_pkcs1_sign",   "i62",
517 		(const void *(*)(void))&br_rsa_i62_pkcs1_sign_get },
518 	{ "rsa_i62_pkcs1_vrfy",   "i62",
519 		(const void *(*)(void))&br_rsa_i62_pkcs1_vrfy_get },
520 	{ "ec_c25519_m62",        "m62",
521 		(const void *(*)(void))&br_ec_c25519_m62_get },
522 	{ "ec_c25519_m64",        "m64",
523 		(const void *(*)(void))&br_ec_c25519_m64_get },
524 	{ "ec_p256_m62",          "m62",
525 		(const void *(*)(void))&br_ec_p256_m62_get },
526 	{ "ec_p256_m64",          "m64",
527 		(const void *(*)(void))&br_ec_p256_m64_get },
528 	{ 0, 0, 0, }
529 };
530 
531 /* see brssl.h */
532 const char *
533 get_algo_name(const void *impl, int long_name)
534 {
535 	size_t u;
536 
537 	for (u = 0; algo_names[u].long_name; u ++) {
538 		if (impl == algo_names[u].impl) {
539 			return long_name
540 				? algo_names[u].long_name
541 				: algo_names[u].short_name;
542 		}
543 	}
544 	for (u = 0; algo_names_dyn[u].long_name; u ++) {
545 		if (impl == algo_names_dyn[u].get()) {
546 			return long_name
547 				? algo_names_dyn[u].long_name
548 				: algo_names_dyn[u].short_name;
549 		}
550 	}
551 	return "UNKNOWN";
552 }
553 
554 /* see brssl.h */
555 const char *
556 get_curve_name(int id)
557 {
558 	size_t u;
559 
560 	for (u = 0; curves[u].name; u ++) {
561 		if (curves[u].id == id) {
562 			return curves[u].name;
563 		}
564 	}
565 	return NULL;
566 }
567 
568 /* see brssl.h */
569 int
570 get_curve_name_ext(int id, char *dst, size_t len)
571 {
572 	const char *name;
573 	char tmp[30];
574 	size_t n;
575 
576 	name = get_curve_name(id);
577 	if (name == NULL) {
578 		sprintf(tmp, "unknown (%d)", id);
579 		name = tmp;
580 	}
581 	n = 1 + strlen(name);
582 	if (n > len) {
583 		if (len > 0) {
584 			dst[0] = 0;
585 		}
586 		return -1;
587 	}
588 	memcpy(dst, name, n);
589 	return 0;
590 }
591 
592 /* see brssl.h */
593 const char *
594 get_suite_name(unsigned suite)
595 {
596 	size_t u;
597 
598 	for (u = 0; cipher_suites[u].name; u ++) {
599 		if (cipher_suites[u].suite == suite) {
600 			return cipher_suites[u].name;
601 		}
602 	}
603 	return NULL;
604 }
605 
606 /* see brssl.h */
607 int
608 get_suite_name_ext(unsigned suite, char *dst, size_t len)
609 {
610 	const char *name;
611 	char tmp[30];
612 	size_t n;
613 
614 	name = get_suite_name(suite);
615 	if (name == NULL) {
616 		sprintf(tmp, "unknown (0x%04X)", suite);
617 		name = tmp;
618 	}
619 	n = 1 + strlen(name);
620 	if (n > len) {
621 		if (len > 0) {
622 			dst[0] = 0;
623 		}
624 		return -1;
625 	}
626 	memcpy(dst, name, n);
627 	return 0;
628 }
629 
630 /* see brssl.h */
631 int
632 uses_ecdhe(unsigned suite)
633 {
634 	size_t u;
635 
636 	for (u = 0; cipher_suites[u].name; u ++) {
637 		if (cipher_suites[u].suite == suite) {
638 			return (cipher_suites[u].req
639 				& (REQ_ECDHE_RSA | REQ_ECDHE_ECDSA)) != 0;
640 		}
641 	}
642 	return 0;
643 }
644 
645 /* see brssl.h */
646 void
647 list_names(void)
648 {
649 	size_t u;
650 
651 	printf("Protocol versions:\n");
652 	for (u = 0; protocol_versions[u].name; u ++) {
653 		printf("   %-8s %s\n",
654 			protocol_versions[u].name,
655 			protocol_versions[u].comment);
656 	}
657 	printf("Hash functions:\n");
658 	for (u = 0; hash_functions[u].name; u ++) {
659 		printf("   %-8s %s\n",
660 			hash_functions[u].name,
661 			hash_functions[u].comment);
662 	}
663 	printf("Cipher suites:\n");
664 	for (u = 0; cipher_suites[u].name; u ++) {
665 		printf("   %s\n        %s\n",
666 			cipher_suites[u].name,
667 			cipher_suites[u].comment);
668 	}
669 }
670 
671 /* see brssl.h */
672 void
673 list_curves(void)
674 {
675 	size_t u;
676 	for (u = 0; curves[u].name; u ++) {
677 		size_t v;
678 
679 		for (v = 0; curves[u].sid[v]; v ++) {
680 			if (v == 0) {
681 				printf("   ");
682 			} else if (v == 1) {
683 				printf(" (");
684 			} else {
685 				printf(", ");
686 			}
687 			printf("%s", curves[u].sid[v]);
688 		}
689 		if (v > 1) {
690 			printf(")");
691 		}
692 		printf("\n");
693 	}
694 }
695 
696 static int
697 is_ign(int c)
698 {
699 	if (c == 0) {
700 		return 0;
701 	}
702 	if (c <= 32 || c == '-' || c == '_' || c == '.'
703 		|| c == '/' || c == '+' || c == ':')
704 	{
705 		return 1;
706 	}
707 	return 0;
708 }
709 
710 /*
711  * Get next non-ignored character, normalised:
712  *    ASCII letters are converted to lowercase
713  *    control characters, space, '-', '_', '.', '/', '+' and ':' are ignored
714  * A terminating zero is returned as 0.
715  */
716 static int
717 next_char(const char **ps, const char *limit)
718 {
719 	for (;;) {
720 		int c;
721 
722 		if (*ps == limit) {
723 			return 0;
724 		}
725 		c = *(*ps) ++;
726 		if (c == 0) {
727 			return 0;
728 		}
729 		if (c >= 'A' && c <= 'Z') {
730 			c += 'a' - 'A';
731 		}
732 		if (!is_ign(c)) {
733 			return c;
734 		}
735 	}
736 }
737 
738 /*
739  * Partial string equality comparison, with normalisation.
740  */
741 static int
742 eqstr_chunk(const char *s1, size_t s1_len, const char *s2, size_t s2_len)
743 {
744 	const char *lim1, *lim2;
745 
746 	lim1 = s1 + s1_len;
747 	lim2 = s2 + s2_len;
748 	for (;;) {
749 		int c1, c2;
750 
751 		c1 = next_char(&s1, lim1);
752 		c2 = next_char(&s2, lim2);
753 		if (c1 != c2) {
754 			return 0;
755 		}
756 		if (c1 == 0) {
757 			return 1;
758 		}
759 	}
760 }
761 
762 /* see brssl.h */
763 int
764 eqstr(const char *s1, const char *s2)
765 {
766 	return eqstr_chunk(s1, strlen(s1), s2, strlen(s2));
767 }
768 
769 static int
770 hexval(int c)
771 {
772 	if (c >= '0' && c <= '9') {
773 		return c - '0';
774 	} else if (c >= 'A' && c <= 'F') {
775 		return c - 'A' + 10;
776 	} else if (c >= 'a' && c <= 'f') {
777 		return c - 'a' + 10;
778 	} else {
779 		return -1;
780 	}
781 }
782 
783 /* see brssl.h */
784 size_t
785 parse_size(const char *s)
786 {
787 	int radix;
788 	size_t acc;
789 	const char *t;
790 
791 	t = s;
792 	if (t[0] == '0' && (t[1] == 'x' || t[1] == 'X')) {
793 		radix = 16;
794 		t += 2;
795 	} else {
796 		radix = 10;
797 	}
798 	acc = 0;
799 	for (;;) {
800 		int c, d;
801 		size_t z;
802 
803 		c = *t ++;
804 		if (c == 0) {
805 			return acc;
806 		}
807 		d = hexval(c);
808 		if (d < 0 || d >= radix) {
809 			fprintf(stderr, "ERROR: not a valid digit: '%c'\n", c);
810 			return (size_t)-1;
811 		}
812 		z = acc * (size_t)radix + (size_t)d;
813 		if (z < (size_t)d || (z / (size_t)radix) != acc
814 			|| z == (size_t)-1)
815 		{
816 			fprintf(stderr, "ERROR: value too large: %s\n", s);
817 			return (size_t)-1;
818 		}
819 		acc = z;
820 	}
821 }
822 
823 /*
824  * Comma-separated list enumeration. This returns a pointer to the first
825  * word in the string, skipping leading ignored characters. '*len' is
826  * set to the word length (not counting trailing ignored characters).
827  * '*str' is updated to point to immediately after the next comma, or to
828  * the terminating zero, whichever comes first.
829  *
830  * Empty words are skipped. If there is no next non-empty word, then this
831  * function returns NULL and sets *len to 0.
832  */
833 static const char *
834 next_word(const char **str, size_t *len)
835 {
836 	int c;
837 	const char *begin;
838 	size_t u;
839 
840 	/*
841 	 * Find next non-ignored character which is not a comma.
842 	 */
843 	for (;;) {
844 		c = **str;
845 		if (c == 0) {
846 			*len = 0;
847 			return NULL;
848 		}
849 		if (!is_ign(c) && c != ',') {
850 			break;
851 		}
852 		(*str) ++;
853 	}
854 
855 	/*
856 	 * Find next comma or terminator.
857 	 */
858 	begin = *str;
859 	for (;;) {
860 		c = *(*str);
861 		if (c == 0 || c == ',') {
862 			break;
863 		}
864 		(*str) ++;
865 	}
866 
867 	/*
868 	 * Remove trailing ignored characters.
869 	 */
870 	u = (size_t)(*str - begin);
871 	while (u > 0 && is_ign(begin[u - 1])) {
872 		u --;
873 	}
874 	if (c == ',') {
875 		(*str) ++;
876 	}
877 	*len = u;
878 	return begin;
879 }
880 
881 /* see brssl.h */
882 unsigned
883 parse_version(const char *name, size_t len)
884 {
885 	size_t u;
886 
887 	for (u = 0;; u ++) {
888 		const char *ref;
889 
890 		ref = protocol_versions[u].name;
891 		if (ref == NULL) {
892 			fprintf(stderr, "ERROR: unrecognised protocol"
893 				" version name: '%s'\n", name);
894 			return 0;
895 		}
896 		if (eqstr_chunk(ref, strlen(ref), name, len)) {
897 			return protocol_versions[u].version;
898 		}
899 	}
900 }
901 
902 /* see brssl.h */
903 unsigned
904 parse_hash_functions(const char *arg)
905 {
906 	unsigned r;
907 
908 	r = 0;
909 	for (;;) {
910 		const char *name;
911 		size_t len;
912 		size_t u;
913 
914 		name = next_word(&arg, &len);
915 		if (name == NULL) {
916 			break;
917 		}
918 		for (u = 0;; u ++) {
919 			const char *ref;
920 
921 			ref = hash_functions[u].name;
922 			if (ref == 0) {
923 				fprintf(stderr, "ERROR: unrecognised"
924 					" hash function name: '");
925 				fwrite(name, 1, len, stderr);
926 				fprintf(stderr, "'\n");
927 				return 0;
928 			}
929 			if (eqstr_chunk(ref, strlen(ref), name, len)) {
930 				int id;
931 
932 				id = (hash_functions[u].hclass->desc
933 					>> BR_HASHDESC_ID_OFF)
934 					& BR_HASHDESC_ID_MASK;
935 				r |= (unsigned)1 << id;
936 				break;
937 			}
938 		}
939 	}
940 	if (r == 0) {
941 		fprintf(stderr, "ERROR: no hash function name provided\n");
942 	}
943 	return r;
944 }
945 
946 /* see brssl.h */
947 cipher_suite *
948 parse_suites(const char *arg, size_t *num)
949 {
950 	VECTOR(cipher_suite) suites = VEC_INIT;
951 	cipher_suite *r;
952 
953 	for (;;) {
954 		const char *name;
955 		size_t u, len;
956 
957 		name = next_word(&arg, &len);
958 		if (name == NULL) {
959 			break;
960 		}
961 		for (u = 0;; u ++) {
962 			const char *ref;
963 
964 			ref = cipher_suites[u].name;
965 			if (ref == NULL) {
966 				fprintf(stderr, "ERROR: unrecognised"
967 					" cipher suite '");
968 				fwrite(name, 1, len, stderr);
969 				fprintf(stderr, "'\n");
970 				return 0;
971 			}
972 			if (eqstr_chunk(ref, strlen(ref), name, len)) {
973 				VEC_ADD(suites, cipher_suites[u]);
974 				break;
975 			}
976 		}
977 	}
978 	if (VEC_LEN(suites) == 0) {
979 		fprintf(stderr, "ERROR: no cipher suite provided\n");
980 	}
981 	r = VEC_TOARRAY(suites);
982 	*num = VEC_LEN(suites);
983 	VEC_CLEAR(suites);
984 	return r;
985 }
986 
987 /* see brssl.h */
988 const char *
989 ec_curve_name(int curve)
990 {
991 	switch (curve) {
992 	case BR_EC_sect163k1:        return "sect163k1";
993 	case BR_EC_sect163r1:        return "sect163r1";
994 	case BR_EC_sect163r2:        return "sect163r2";
995 	case BR_EC_sect193r1:        return "sect193r1";
996 	case BR_EC_sect193r2:        return "sect193r2";
997 	case BR_EC_sect233k1:        return "sect233k1";
998 	case BR_EC_sect233r1:        return "sect233r1";
999 	case BR_EC_sect239k1:        return "sect239k1";
1000 	case BR_EC_sect283k1:        return "sect283k1";
1001 	case BR_EC_sect283r1:        return "sect283r1";
1002 	case BR_EC_sect409k1:        return "sect409k1";
1003 	case BR_EC_sect409r1:        return "sect409r1";
1004 	case BR_EC_sect571k1:        return "sect571k1";
1005 	case BR_EC_sect571r1:        return "sect571r1";
1006 	case BR_EC_secp160k1:        return "secp160k1";
1007 	case BR_EC_secp160r1:        return "secp160r1";
1008 	case BR_EC_secp160r2:        return "secp160r2";
1009 	case BR_EC_secp192k1:        return "secp192k1";
1010 	case BR_EC_secp192r1:        return "secp192r1";
1011 	case BR_EC_secp224k1:        return "secp224k1";
1012 	case BR_EC_secp224r1:        return "secp224r1";
1013 	case BR_EC_secp256k1:        return "secp256k1";
1014 	case BR_EC_secp256r1:        return "secp256r1";
1015 	case BR_EC_secp384r1:        return "secp384r1";
1016 	case BR_EC_secp521r1:        return "secp521r1";
1017 	case BR_EC_brainpoolP256r1:  return "brainpoolP256r1";
1018 	case BR_EC_brainpoolP384r1:  return "brainpoolP384r1";
1019 	case BR_EC_brainpoolP512r1:  return "brainpoolP512r1";
1020 	default:
1021 		return "unknown";
1022 	}
1023 }
1024 
1025 /* see brssl.h */
1026 int
1027 get_curve_by_name(const char *str)
1028 {
1029 	size_t u, v;
1030 
1031 	for (u = 0; curves[u].name; u ++) {
1032 		for (v = 0; curves[u].sid[v]; v ++) {
1033 			if (eqstr(curves[u].sid[v], str)) {
1034 				return curves[u].id;
1035 			}
1036 		}
1037 	}
1038 	return -1;
1039 }
1040 
1041 /* see brssl.h */
1042 const char *
1043 hash_function_name(int id)
1044 {
1045 	switch (id) {
1046 	case br_md5sha1_ID:  return "MD5+SHA-1";
1047 	case br_md5_ID:      return "MD5";
1048 	case br_sha1_ID:     return "SHA-1";
1049 	case br_sha224_ID:   return "SHA-224";
1050 	case br_sha256_ID:   return "SHA-256";
1051 	case br_sha384_ID:   return "SHA-384";
1052 	case br_sha512_ID:   return "SHA-512";
1053 	default:
1054 		return "unknown";
1055 	}
1056 }
1057