1/* crypto/ecdh/ecdhtest.c */ 2/* ==================================================================== 3 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 4 * 5 * The Elliptic Curve Public-Key Crypto Library (ECC Code) included 6 * herein is developed by SUN MICROSYSTEMS, INC., and is contributed 7 * to the OpenSSL project. 8 * 9 * The ECC Code is licensed pursuant to the OpenSSL open source 10 * license provided below. 11 * 12 * The ECDH software is originally written by Douglas Stebila of 13 * Sun Microsystems Laboratories. 14 * 15 */ 16/* ==================================================================== 17 * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 18 * 19 * Redistribution and use in source and binary forms, with or without 20 * modification, are permitted provided that the following conditions 21 * are met: 22 * 23 * 1. Redistributions of source code must retain the above copyright 24 * notice, this list of conditions and the following disclaimer. 25 * 26 * 2. Redistributions in binary form must reproduce the above copyright 27 * notice, this list of conditions and the following disclaimer in 28 * the documentation and/or other materials provided with the 29 * distribution. 30 * 31 * 3. All advertising materials mentioning features or use of this 32 * software must display the following acknowledgment: 33 * "This product includes software developed by the OpenSSL Project 34 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 35 * 36 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 37 * endorse or promote products derived from this software without 38 * prior written permission. For written permission, please contact 39 * openssl-core@openssl.org. 40 * 41 * 5. Products derived from this software may not be called "OpenSSL" 42 * nor may "OpenSSL" appear in their names without prior written 43 * permission of the OpenSSL Project. 44 * 45 * 6. Redistributions of any form whatsoever must retain the following 46 * acknowledgment: 47 * "This product includes software developed by the OpenSSL Project 48 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 49 * 50 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 51 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 54 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 59 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 61 * OF THE POSSIBILITY OF SUCH DAMAGE. 62 * ==================================================================== 63 * 64 * This product includes cryptographic software written by Eric Young 65 * (eay@cryptsoft.com). This product includes software written by Tim 66 * Hudson (tjh@cryptsoft.com). 67 * 68 */ 69 70#include <stdio.h> 71#include <stdlib.h> 72#include <string.h> 73 74#include "../e_os.h" 75 76#include <openssl/opensslconf.h> /* for OPENSSL_NO_ECDH */ 77#include <openssl/crypto.h> 78#include <openssl/bio.h> 79#include <openssl/bn.h> 80#include <openssl/objects.h> 81#include <openssl/rand.h> 82#include <openssl/sha.h> 83#include <openssl/err.h> 84 85#ifdef OPENSSL_NO_ECDH 86int main(int argc, char *argv[]) 87{ 88 printf("No ECDH support\n"); 89 return (0); 90} 91#else 92# include <openssl/ec.h> 93# include <openssl/ecdh.h> 94 95# ifdef OPENSSL_SYS_WIN16 96# define MS_CALLBACK _far _loadds 97# else 98# define MS_CALLBACK 99# endif 100 101# if 0 102static void MS_CALLBACK cb(int p, int n, void *arg); 103# endif 104 105static const char rnd_seed[] = 106 "string to make the random number generator think it has entropy"; 107 108static const int KDF1_SHA1_len = 20; 109static void *KDF1_SHA1(const void *in, size_t inlen, void *out, 110 size_t *outlen) 111{ 112# ifndef OPENSSL_NO_SHA 113 if (*outlen < SHA_DIGEST_LENGTH) 114 return NULL; 115 else 116 *outlen = SHA_DIGEST_LENGTH; 117 return SHA1(in, inlen, out); 118# else 119 return NULL; 120# endif 121} 122 123static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out) 124{ 125 EC_KEY *a = NULL; 126 EC_KEY *b = NULL; 127 BIGNUM *x_a = NULL, *y_a = NULL, *x_b = NULL, *y_b = NULL; 128 char buf[12]; 129 unsigned char *abuf = NULL, *bbuf = NULL; 130 int i, alen, blen, aout, bout, ret = 0; 131 const EC_GROUP *group; 132 133 a = EC_KEY_new_by_curve_name(nid); 134 b = EC_KEY_new_by_curve_name(nid); 135 if (a == NULL || b == NULL) 136 goto err; 137 138 group = EC_KEY_get0_group(a); 139 140 if ((x_a = BN_new()) == NULL) 141 goto err; 142 if ((y_a = BN_new()) == NULL) 143 goto err; 144 if ((x_b = BN_new()) == NULL) 145 goto err; 146 if ((y_b = BN_new()) == NULL) 147 goto err; 148 149 BIO_puts(out, "Testing key generation with "); 150 BIO_puts(out, text); 151# ifdef NOISY 152 BIO_puts(out, "\n"); 153# else 154 (void)BIO_flush(out); 155# endif 156 157 if (!EC_KEY_generate_key(a)) 158 goto err; 159 160 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == 161 NID_X9_62_prime_field) { 162 if (!EC_POINT_get_affine_coordinates_GFp 163 (group, EC_KEY_get0_public_key(a), x_a, y_a, ctx)) 164 goto err; 165 } 166# ifndef OPENSSL_NO_EC2M 167 else { 168 if (!EC_POINT_get_affine_coordinates_GF2m(group, 169 EC_KEY_get0_public_key(a), 170 x_a, y_a, ctx)) 171 goto err; 172 } 173# endif 174# ifdef NOISY 175 BIO_puts(out, " pri 1="); 176 BN_print(out, a->priv_key); 177 BIO_puts(out, "\n pub 1="); 178 BN_print(out, x_a); 179 BIO_puts(out, ","); 180 BN_print(out, y_a); 181 BIO_puts(out, "\n"); 182# else 183 BIO_printf(out, " ."); 184 (void)BIO_flush(out); 185# endif 186 187 if (!EC_KEY_generate_key(b)) 188 goto err; 189 190 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == 191 NID_X9_62_prime_field) { 192 if (!EC_POINT_get_affine_coordinates_GFp 193 (group, EC_KEY_get0_public_key(b), x_b, y_b, ctx)) 194 goto err; 195 } 196# ifndef OPENSSL_NO_EC2M 197 else { 198 if (!EC_POINT_get_affine_coordinates_GF2m(group, 199 EC_KEY_get0_public_key(b), 200 x_b, y_b, ctx)) 201 goto err; 202 } 203# endif 204 205# ifdef NOISY 206 BIO_puts(out, " pri 2="); 207 BN_print(out, b->priv_key); 208 BIO_puts(out, "\n pub 2="); 209 BN_print(out, x_b); 210 BIO_puts(out, ","); 211 BN_print(out, y_b); 212 BIO_puts(out, "\n"); 213# else 214 BIO_printf(out, "."); 215 (void)BIO_flush(out); 216# endif 217 218 alen = KDF1_SHA1_len; 219 abuf = (unsigned char *)OPENSSL_malloc(alen); 220 aout = 221 ECDH_compute_key(abuf, alen, EC_KEY_get0_public_key(b), a, KDF1_SHA1); 222 223# ifdef NOISY 224 BIO_puts(out, " key1 ="); 225 for (i = 0; i < aout; i++) { 226 sprintf(buf, "%02X", abuf[i]); 227 BIO_puts(out, buf); 228 } 229 BIO_puts(out, "\n"); 230# else 231 BIO_printf(out, "."); 232 (void)BIO_flush(out); 233# endif 234 235 blen = KDF1_SHA1_len; 236 bbuf = (unsigned char *)OPENSSL_malloc(blen); 237 bout = 238 ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(a), b, KDF1_SHA1); 239 240# ifdef NOISY 241 BIO_puts(out, " key2 ="); 242 for (i = 0; i < bout; i++) { 243 sprintf(buf, "%02X", bbuf[i]); 244 BIO_puts(out, buf); 245 } 246 BIO_puts(out, "\n"); 247# else 248 BIO_printf(out, "."); 249 (void)BIO_flush(out); 250# endif 251 252 if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) { 253# ifndef NOISY 254 BIO_printf(out, " failed\n\n"); 255 BIO_printf(out, "key a:\n"); 256 BIO_printf(out, "private key: "); 257 BN_print(out, EC_KEY_get0_private_key(a)); 258 BIO_printf(out, "\n"); 259 BIO_printf(out, "public key (x,y): "); 260 BN_print(out, x_a); 261 BIO_printf(out, ","); 262 BN_print(out, y_a); 263 BIO_printf(out, "\nkey b:\n"); 264 BIO_printf(out, "private key: "); 265 BN_print(out, EC_KEY_get0_private_key(b)); 266 BIO_printf(out, "\n"); 267 BIO_printf(out, "public key (x,y): "); 268 BN_print(out, x_b); 269 BIO_printf(out, ","); 270 BN_print(out, y_b); 271 BIO_printf(out, "\n"); 272 BIO_printf(out, "generated key a: "); 273 for (i = 0; i < bout; i++) { 274 sprintf(buf, "%02X", bbuf[i]); 275 BIO_puts(out, buf); 276 } 277 BIO_printf(out, "\n"); 278 BIO_printf(out, "generated key b: "); 279 for (i = 0; i < aout; i++) { 280 sprintf(buf, "%02X", abuf[i]); 281 BIO_puts(out, buf); 282 } 283 BIO_printf(out, "\n"); 284# endif 285 fprintf(stderr, "Error in ECDH routines\n"); 286 ret = 0; 287 } else { 288# ifndef NOISY 289 BIO_printf(out, " ok\n"); 290# endif 291 ret = 1; 292 } 293 err: 294 ERR_print_errors_fp(stderr); 295 296 if (abuf != NULL) 297 OPENSSL_free(abuf); 298 if (bbuf != NULL) 299 OPENSSL_free(bbuf); 300 if (x_a) 301 BN_free(x_a); 302 if (y_a) 303 BN_free(y_a); 304 if (x_b) 305 BN_free(x_b); 306 if (y_b) 307 BN_free(y_b); 308 if (b) 309 EC_KEY_free(b); 310 if (a) 311 EC_KEY_free(a); 312 return (ret); 313} 314 315/* Keys and shared secrets from RFC 7027 */ 316 317static const unsigned char bp256_da[] = { 318 0x81, 0xDB, 0x1E, 0xE1, 0x00, 0x15, 0x0F, 0xF2, 0xEA, 0x33, 0x8D, 0x70, 319 0x82, 0x71, 0xBE, 0x38, 0x30, 0x0C, 0xB5, 0x42, 0x41, 0xD7, 0x99, 0x50, 320 0xF7, 0x7B, 0x06, 0x30, 0x39, 0x80, 0x4F, 0x1D 321}; 322 323static const unsigned char bp256_db[] = { 324 0x55, 0xE4, 0x0B, 0xC4, 0x1E, 0x37, 0xE3, 0xE2, 0xAD, 0x25, 0xC3, 0xC6, 325 0x65, 0x45, 0x11, 0xFF, 0xA8, 0x47, 0x4A, 0x91, 0xA0, 0x03, 0x20, 0x87, 326 0x59, 0x38, 0x52, 0xD3, 0xE7, 0xD7, 0x6B, 0xD3 327}; 328 329static const unsigned char bp256_Z[] = { 330 0x89, 0xAF, 0xC3, 0x9D, 0x41, 0xD3, 0xB3, 0x27, 0x81, 0x4B, 0x80, 0x94, 331 0x0B, 0x04, 0x25, 0x90, 0xF9, 0x65, 0x56, 0xEC, 0x91, 0xE6, 0xAE, 0x79, 332 0x39, 0xBC, 0xE3, 0x1F, 0x3A, 0x18, 0xBF, 0x2B 333}; 334 335static const unsigned char bp384_da[] = { 336 0x1E, 0x20, 0xF5, 0xE0, 0x48, 0xA5, 0x88, 0x6F, 0x1F, 0x15, 0x7C, 0x74, 337 0xE9, 0x1B, 0xDE, 0x2B, 0x98, 0xC8, 0xB5, 0x2D, 0x58, 0xE5, 0x00, 0x3D, 338 0x57, 0x05, 0x3F, 0xC4, 0xB0, 0xBD, 0x65, 0xD6, 0xF1, 0x5E, 0xB5, 0xD1, 339 0xEE, 0x16, 0x10, 0xDF, 0x87, 0x07, 0x95, 0x14, 0x36, 0x27, 0xD0, 0x42 340}; 341 342static const unsigned char bp384_db[] = { 343 0x03, 0x26, 0x40, 0xBC, 0x60, 0x03, 0xC5, 0x92, 0x60, 0xF7, 0x25, 0x0C, 344 0x3D, 0xB5, 0x8C, 0xE6, 0x47, 0xF9, 0x8E, 0x12, 0x60, 0xAC, 0xCE, 0x4A, 345 0xCD, 0xA3, 0xDD, 0x86, 0x9F, 0x74, 0xE0, 0x1F, 0x8B, 0xA5, 0xE0, 0x32, 346 0x43, 0x09, 0xDB, 0x6A, 0x98, 0x31, 0x49, 0x7A, 0xBA, 0xC9, 0x66, 0x70 347}; 348 349static const unsigned char bp384_Z[] = { 350 0x0B, 0xD9, 0xD3, 0xA7, 0xEA, 0x0B, 0x3D, 0x51, 0x9D, 0x09, 0xD8, 0xE4, 351 0x8D, 0x07, 0x85, 0xFB, 0x74, 0x4A, 0x6B, 0x35, 0x5E, 0x63, 0x04, 0xBC, 352 0x51, 0xC2, 0x29, 0xFB, 0xBC, 0xE2, 0x39, 0xBB, 0xAD, 0xF6, 0x40, 0x37, 353 0x15, 0xC3, 0x5D, 0x4F, 0xB2, 0xA5, 0x44, 0x4F, 0x57, 0x5D, 0x4F, 0x42 354}; 355 356static const unsigned char bp512_da[] = { 357 0x16, 0x30, 0x2F, 0xF0, 0xDB, 0xBB, 0x5A, 0x8D, 0x73, 0x3D, 0xAB, 0x71, 358 0x41, 0xC1, 0xB4, 0x5A, 0xCB, 0xC8, 0x71, 0x59, 0x39, 0x67, 0x7F, 0x6A, 359 0x56, 0x85, 0x0A, 0x38, 0xBD, 0x87, 0xBD, 0x59, 0xB0, 0x9E, 0x80, 0x27, 360 0x96, 0x09, 0xFF, 0x33, 0x3E, 0xB9, 0xD4, 0xC0, 0x61, 0x23, 0x1F, 0xB2, 361 0x6F, 0x92, 0xEE, 0xB0, 0x49, 0x82, 0xA5, 0xF1, 0xD1, 0x76, 0x4C, 0xAD, 362 0x57, 0x66, 0x54, 0x22 363}; 364 365static const unsigned char bp512_db[] = { 366 0x23, 0x0E, 0x18, 0xE1, 0xBC, 0xC8, 0x8A, 0x36, 0x2F, 0xA5, 0x4E, 0x4E, 367 0xA3, 0x90, 0x20, 0x09, 0x29, 0x2F, 0x7F, 0x80, 0x33, 0x62, 0x4F, 0xD4, 368 0x71, 0xB5, 0xD8, 0xAC, 0xE4, 0x9D, 0x12, 0xCF, 0xAB, 0xBC, 0x19, 0x96, 369 0x3D, 0xAB, 0x8E, 0x2F, 0x1E, 0xBA, 0x00, 0xBF, 0xFB, 0x29, 0xE4, 0xD7, 370 0x2D, 0x13, 0xF2, 0x22, 0x45, 0x62, 0xF4, 0x05, 0xCB, 0x80, 0x50, 0x36, 371 0x66, 0xB2, 0x54, 0x29 372}; 373 374static const unsigned char bp512_Z[] = { 375 0xA7, 0x92, 0x70, 0x98, 0x65, 0x5F, 0x1F, 0x99, 0x76, 0xFA, 0x50, 0xA9, 376 0xD5, 0x66, 0x86, 0x5D, 0xC5, 0x30, 0x33, 0x18, 0x46, 0x38, 0x1C, 0x87, 377 0x25, 0x6B, 0xAF, 0x32, 0x26, 0x24, 0x4B, 0x76, 0xD3, 0x64, 0x03, 0xC0, 378 0x24, 0xD7, 0xBB, 0xF0, 0xAA, 0x08, 0x03, 0xEA, 0xFF, 0x40, 0x5D, 0x3D, 379 0x24, 0xF1, 0x1A, 0x9B, 0x5C, 0x0B, 0xEF, 0x67, 0x9F, 0xE1, 0x45, 0x4B, 380 0x21, 0xC4, 0xCD, 0x1F 381}; 382 383/* Given private value and NID, create EC_KEY structure */ 384 385static EC_KEY *mk_eckey(int nid, const unsigned char *p, size_t plen) 386{ 387 int ok = 0; 388 EC_KEY *k = NULL; 389 BIGNUM *priv = NULL; 390 EC_POINT *pub = NULL; 391 const EC_GROUP *grp; 392 k = EC_KEY_new_by_curve_name(nid); 393 if (!k) 394 goto err; 395 priv = BN_bin2bn(p, plen, NULL); 396 if (!priv) 397 goto err; 398 if (!EC_KEY_set_private_key(k, priv)) 399 goto err; 400 grp = EC_KEY_get0_group(k); 401 pub = EC_POINT_new(grp); 402 if (!pub) 403 goto err; 404 if (!EC_POINT_mul(grp, pub, priv, NULL, NULL, NULL)) 405 goto err; 406 if (!EC_KEY_set_public_key(k, pub)) 407 goto err; 408 ok = 1; 409 err: 410 if (priv) 411 BN_clear_free(priv); 412 if (pub) 413 EC_POINT_free(pub); 414 if (ok) 415 return k; 416 else if (k) 417 EC_KEY_free(k); 418 return NULL; 419} 420 421/* 422 * Known answer test: compute shared secret and check it matches expected 423 * value. 424 */ 425 426static int ecdh_kat(BIO *out, const char *cname, int nid, 427 const unsigned char *k1, size_t k1_len, 428 const unsigned char *k2, size_t k2_len, 429 const unsigned char *Z, size_t Zlen) 430{ 431 int rv = 0; 432 EC_KEY *key1 = NULL, *key2 = NULL; 433 unsigned char *Ztmp = NULL; 434 size_t Ztmplen; 435 BIO_puts(out, "Testing ECDH shared secret with "); 436 BIO_puts(out, cname); 437 key1 = mk_eckey(nid, k1, k1_len); 438 key2 = mk_eckey(nid, k2, k2_len); 439 if (!key1 || !key2) 440 goto err; 441 Ztmplen = (EC_GROUP_get_degree(EC_KEY_get0_group(key1)) + 7) / 8; 442 if (Ztmplen != Zlen) 443 goto err; 444 Ztmp = OPENSSL_malloc(Ztmplen); 445 if (!ECDH_compute_key(Ztmp, Ztmplen, 446 EC_KEY_get0_public_key(key2), key1, 0)) 447 goto err; 448 if (memcmp(Ztmp, Z, Zlen)) 449 goto err; 450 memset(Ztmp, 0, Zlen); 451 if (!ECDH_compute_key(Ztmp, Ztmplen, 452 EC_KEY_get0_public_key(key1), key2, 0)) 453 goto err; 454 if (memcmp(Ztmp, Z, Zlen)) 455 goto err; 456 rv = 1; 457 err: 458 if (key1) 459 EC_KEY_free(key1); 460 if (key2) 461 EC_KEY_free(key2); 462 if (Ztmp) 463 OPENSSL_free(Ztmp); 464 if (rv) 465 BIO_puts(out, " ok\n"); 466 else { 467 fprintf(stderr, "Error in ECDH routines\n"); 468 ERR_print_errors_fp(stderr); 469 } 470 return rv; 471} 472 473# define test_ecdh_kat(bio, curve, bits) \ 474 ecdh_kat(bio, curve, NID_brainpoolP##bits##r1, \ 475 bp##bits##_da, sizeof(bp##bits##_da), \ 476 bp##bits##_db, sizeof(bp##bits##_db), \ 477 bp##bits##_Z, sizeof(bp##bits##_Z)) 478 479int main(int argc, char *argv[]) 480{ 481 BN_CTX *ctx = NULL; 482 int ret = 1; 483 BIO *out; 484 485 CRYPTO_malloc_debug_init(); 486 CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); 487 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 488 489# ifdef OPENSSL_SYS_WIN32 490 CRYPTO_malloc_init(); 491# endif 492 493 RAND_seed(rnd_seed, sizeof rnd_seed); 494 495 out = BIO_new(BIO_s_file()); 496 if (out == NULL) 497 EXIT(1); 498 BIO_set_fp(out, stdout, BIO_NOCLOSE); 499 500 if ((ctx = BN_CTX_new()) == NULL) 501 goto err; 502 503 /* NIST PRIME CURVES TESTS */ 504 if (!test_ecdh_curve 505 (NID_X9_62_prime192v1, "NIST Prime-Curve P-192", ctx, out)) 506 goto err; 507 if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out)) 508 goto err; 509 if (!test_ecdh_curve 510 (NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out)) 511 goto err; 512 if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out)) 513 goto err; 514 if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out)) 515 goto err; 516# ifndef OPENSSL_NO_EC2M 517 /* NIST BINARY CURVES TESTS */ 518 if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out)) 519 goto err; 520 if (!test_ecdh_curve(NID_sect163r2, "NIST Binary-Curve B-163", ctx, out)) 521 goto err; 522 if (!test_ecdh_curve(NID_sect233k1, "NIST Binary-Curve K-233", ctx, out)) 523 goto err; 524 if (!test_ecdh_curve(NID_sect233r1, "NIST Binary-Curve B-233", ctx, out)) 525 goto err; 526 if (!test_ecdh_curve(NID_sect283k1, "NIST Binary-Curve K-283", ctx, out)) 527 goto err; 528 if (!test_ecdh_curve(NID_sect283r1, "NIST Binary-Curve B-283", ctx, out)) 529 goto err; 530 if (!test_ecdh_curve(NID_sect409k1, "NIST Binary-Curve K-409", ctx, out)) 531 goto err; 532 if (!test_ecdh_curve(NID_sect409r1, "NIST Binary-Curve B-409", ctx, out)) 533 goto err; 534 if (!test_ecdh_curve(NID_sect571k1, "NIST Binary-Curve K-571", ctx, out)) 535 goto err; 536 if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out)) 537 goto err; 538# endif 539 if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP256r1", 256)) 540 goto err; 541 if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP384r1", 384)) 542 goto err; 543 if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP512r1", 512)) 544 goto err; 545 546 ret = 0; 547 548 err: 549 ERR_print_errors_fp(stderr); 550 if (ctx) 551 BN_CTX_free(ctx); 552 BIO_free(out); 553 CRYPTO_cleanup_all_ex_data(); 554 ERR_remove_thread_state(NULL); 555 CRYPTO_mem_leaks_fp(stderr); 556 EXIT(ret); 557 return (ret); 558} 559 560# if 0 561static void MS_CALLBACK cb(int p, int n, void *arg) 562{ 563 char c = '*'; 564 565 if (p == 0) 566 c = '.'; 567 if (p == 1) 568 c = '+'; 569 if (p == 2) 570 c = '*'; 571 if (p == 3) 572 c = '\n'; 573 BIO_write((BIO *)arg, &c, 1); 574 (void)BIO_flush((BIO *)arg); 575# ifdef LINT 576 p = n; 577# endif 578} 579# endif 580#endif 581