/ tools / names.c
names.c
   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  }