1160814Ssimon/* crypto/ecdh/ecdhtest.c */ 2160814Ssimon/* ==================================================================== 3160814Ssimon * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 4160814Ssimon * 5160814Ssimon * The Elliptic Curve Public-Key Crypto Library (ECC Code) included 6160814Ssimon * herein is developed by SUN MICROSYSTEMS, INC., and is contributed 7160814Ssimon * to the OpenSSL project. 8160814Ssimon * 9160814Ssimon * The ECC Code is licensed pursuant to the OpenSSL open source 10160814Ssimon * license provided below. 11160814Ssimon * 12160814Ssimon * The ECDH software is originally written by Douglas Stebila of 13160814Ssimon * Sun Microsystems Laboratories. 14160814Ssimon * 15160814Ssimon */ 16160814Ssimon/* ==================================================================== 17160814Ssimon * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 18160814Ssimon * 19160814Ssimon * Redistribution and use in source and binary forms, with or without 20160814Ssimon * modification, are permitted provided that the following conditions 21160814Ssimon * are met: 22160814Ssimon * 23160814Ssimon * 1. Redistributions of source code must retain the above copyright 24280304Sjkim * notice, this list of conditions and the following disclaimer. 25160814Ssimon * 26160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 27160814Ssimon * notice, this list of conditions and the following disclaimer in 28160814Ssimon * the documentation and/or other materials provided with the 29160814Ssimon * distribution. 30160814Ssimon * 31160814Ssimon * 3. All advertising materials mentioning features or use of this 32160814Ssimon * software must display the following acknowledgment: 33160814Ssimon * "This product includes software developed by the OpenSSL Project 34160814Ssimon * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 35160814Ssimon * 36160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 37160814Ssimon * endorse or promote products derived from this software without 38160814Ssimon * prior written permission. For written permission, please contact 39160814Ssimon * openssl-core@openssl.org. 40160814Ssimon * 41160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 42160814Ssimon * nor may "OpenSSL" appear in their names without prior written 43160814Ssimon * permission of the OpenSSL Project. 44160814Ssimon * 45160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 46160814Ssimon * acknowledgment: 47160814Ssimon * "This product includes software developed by the OpenSSL Project 48160814Ssimon * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 49160814Ssimon * 50160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 51160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 53160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 54160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 55160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 56160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 57160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 59160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 61160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 62160814Ssimon * ==================================================================== 63160814Ssimon * 64160814Ssimon * This product includes cryptographic software written by Eric Young 65160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 66160814Ssimon * Hudson (tjh@cryptsoft.com). 67160814Ssimon * 68160814Ssimon */ 69160814Ssimon 70160814Ssimon#include <stdio.h> 71160814Ssimon#include <stdlib.h> 72160814Ssimon#include <string.h> 73160814Ssimon 74160814Ssimon#include "../e_os.h" 75160814Ssimon 76280304Sjkim#include <openssl/opensslconf.h> /* for OPENSSL_NO_ECDH */ 77160814Ssimon#include <openssl/crypto.h> 78160814Ssimon#include <openssl/bio.h> 79160814Ssimon#include <openssl/bn.h> 80160814Ssimon#include <openssl/objects.h> 81160814Ssimon#include <openssl/rand.h> 82160814Ssimon#include <openssl/sha.h> 83160814Ssimon#include <openssl/err.h> 84160814Ssimon 85160814Ssimon#ifdef OPENSSL_NO_ECDH 86160814Ssimonint main(int argc, char *argv[]) 87160814Ssimon{ 88160814Ssimon printf("No ECDH support\n"); 89280304Sjkim return (0); 90160814Ssimon} 91160814Ssimon#else 92280304Sjkim# include <openssl/ec.h> 93280304Sjkim# include <openssl/ecdh.h> 94160814Ssimon 95280304Sjkim# ifdef OPENSSL_SYS_WIN16 96280304Sjkim# define MS_CALLBACK _far _loadds 97280304Sjkim# else 98280304Sjkim# define MS_CALLBACK 99280304Sjkim# endif 100160814Ssimon 101280304Sjkim# if 0 102160814Ssimonstatic void MS_CALLBACK cb(int p, int n, void *arg); 103280304Sjkim# endif 104160814Ssimon 105280304Sjkimstatic const char rnd_seed[] = 106280304Sjkim "string to make the random number generator think it has entropy"; 107160814Ssimon 108160814Ssimonstatic const int KDF1_SHA1_len = 20; 109280304Sjkimstatic void *KDF1_SHA1(const void *in, size_t inlen, void *out, 110280304Sjkim size_t *outlen) 111280304Sjkim{ 112280304Sjkim# ifndef OPENSSL_NO_SHA 113280304Sjkim if (*outlen < SHA_DIGEST_LENGTH) 114280304Sjkim return NULL; 115280304Sjkim else 116280304Sjkim *outlen = SHA_DIGEST_LENGTH; 117280304Sjkim return SHA1(in, inlen, out); 118280304Sjkim# else 119280304Sjkim return NULL; 120280304Sjkim# endif 121280304Sjkim} 122160814Ssimon 123160814Ssimonstatic int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out) 124280304Sjkim{ 125280304Sjkim EC_KEY *a = NULL; 126280304Sjkim EC_KEY *b = NULL; 127280304Sjkim BIGNUM *x_a = NULL, *y_a = NULL, *x_b = NULL, *y_b = NULL; 128280304Sjkim char buf[12]; 129280304Sjkim unsigned char *abuf = NULL, *bbuf = NULL; 130280304Sjkim int i, alen, blen, aout, bout, ret = 0; 131280304Sjkim const EC_GROUP *group; 132160814Ssimon 133280304Sjkim a = EC_KEY_new_by_curve_name(nid); 134280304Sjkim b = EC_KEY_new_by_curve_name(nid); 135280304Sjkim if (a == NULL || b == NULL) 136280304Sjkim goto err; 137160814Ssimon 138280304Sjkim group = EC_KEY_get0_group(a); 139160814Ssimon 140280304Sjkim if ((x_a = BN_new()) == NULL) 141280304Sjkim goto err; 142280304Sjkim if ((y_a = BN_new()) == NULL) 143280304Sjkim goto err; 144280304Sjkim if ((x_b = BN_new()) == NULL) 145280304Sjkim goto err; 146280304Sjkim if ((y_b = BN_new()) == NULL) 147280304Sjkim goto err; 148160814Ssimon 149280304Sjkim BIO_puts(out, "Testing key generation with "); 150280304Sjkim BIO_puts(out, text); 151280304Sjkim# ifdef NOISY 152280304Sjkim BIO_puts(out, "\n"); 153280304Sjkim# else 154280304Sjkim (void)BIO_flush(out); 155280304Sjkim# endif 156160814Ssimon 157280304Sjkim if (!EC_KEY_generate_key(a)) 158280304Sjkim goto err; 159160814Ssimon 160280304Sjkim if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == 161280304Sjkim NID_X9_62_prime_field) { 162280304Sjkim if (!EC_POINT_get_affine_coordinates_GFp 163280304Sjkim (group, EC_KEY_get0_public_key(a), x_a, y_a, ctx)) 164280304Sjkim goto err; 165280304Sjkim } 166280304Sjkim# ifndef OPENSSL_NO_EC2M 167280304Sjkim else { 168280304Sjkim if (!EC_POINT_get_affine_coordinates_GF2m(group, 169280304Sjkim EC_KEY_get0_public_key(a), 170280304Sjkim x_a, y_a, ctx)) 171280304Sjkim goto err; 172280304Sjkim } 173280304Sjkim# endif 174280304Sjkim# ifdef NOISY 175280304Sjkim BIO_puts(out, " pri 1="); 176280304Sjkim BN_print(out, a->priv_key); 177280304Sjkim BIO_puts(out, "\n pub 1="); 178280304Sjkim BN_print(out, x_a); 179280304Sjkim BIO_puts(out, ","); 180280304Sjkim BN_print(out, y_a); 181280304Sjkim BIO_puts(out, "\n"); 182280304Sjkim# else 183280304Sjkim BIO_printf(out, " ."); 184280304Sjkim (void)BIO_flush(out); 185280304Sjkim# endif 186160814Ssimon 187280304Sjkim if (!EC_KEY_generate_key(b)) 188280304Sjkim goto err; 189160814Ssimon 190280304Sjkim if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == 191280304Sjkim NID_X9_62_prime_field) { 192280304Sjkim if (!EC_POINT_get_affine_coordinates_GFp 193280304Sjkim (group, EC_KEY_get0_public_key(b), x_b, y_b, ctx)) 194280304Sjkim goto err; 195280304Sjkim } 196280304Sjkim# ifndef OPENSSL_NO_EC2M 197280304Sjkim else { 198280304Sjkim if (!EC_POINT_get_affine_coordinates_GF2m(group, 199280304Sjkim EC_KEY_get0_public_key(b), 200280304Sjkim x_b, y_b, ctx)) 201280304Sjkim goto err; 202280304Sjkim } 203280304Sjkim# endif 204160814Ssimon 205280304Sjkim# ifdef NOISY 206280304Sjkim BIO_puts(out, " pri 2="); 207280304Sjkim BN_print(out, b->priv_key); 208280304Sjkim BIO_puts(out, "\n pub 2="); 209280304Sjkim BN_print(out, x_b); 210280304Sjkim BIO_puts(out, ","); 211280304Sjkim BN_print(out, y_b); 212280304Sjkim BIO_puts(out, "\n"); 213280304Sjkim# else 214280304Sjkim BIO_printf(out, "."); 215280304Sjkim (void)BIO_flush(out); 216280304Sjkim# endif 217160814Ssimon 218280304Sjkim alen = KDF1_SHA1_len; 219280304Sjkim abuf = (unsigned char *)OPENSSL_malloc(alen); 220280304Sjkim aout = 221280304Sjkim ECDH_compute_key(abuf, alen, EC_KEY_get0_public_key(b), a, KDF1_SHA1); 222160814Ssimon 223280304Sjkim# ifdef NOISY 224280304Sjkim BIO_puts(out, " key1 ="); 225280304Sjkim for (i = 0; i < aout; i++) { 226280304Sjkim sprintf(buf, "%02X", abuf[i]); 227280304Sjkim BIO_puts(out, buf); 228280304Sjkim } 229280304Sjkim BIO_puts(out, "\n"); 230280304Sjkim# else 231280304Sjkim BIO_printf(out, "."); 232280304Sjkim (void)BIO_flush(out); 233280304Sjkim# endif 234160814Ssimon 235280304Sjkim blen = KDF1_SHA1_len; 236280304Sjkim bbuf = (unsigned char *)OPENSSL_malloc(blen); 237280304Sjkim bout = 238280304Sjkim ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(a), b, KDF1_SHA1); 239160814Ssimon 240280304Sjkim# ifdef NOISY 241280304Sjkim BIO_puts(out, " key2 ="); 242280304Sjkim for (i = 0; i < bout; i++) { 243280304Sjkim sprintf(buf, "%02X", bbuf[i]); 244280304Sjkim BIO_puts(out, buf); 245280304Sjkim } 246280304Sjkim BIO_puts(out, "\n"); 247280304Sjkim# else 248280304Sjkim BIO_printf(out, "."); 249280304Sjkim (void)BIO_flush(out); 250280304Sjkim# endif 251160814Ssimon 252280304Sjkim if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) { 253280304Sjkim# ifndef NOISY 254280304Sjkim BIO_printf(out, " failed\n\n"); 255280304Sjkim BIO_printf(out, "key a:\n"); 256280304Sjkim BIO_printf(out, "private key: "); 257280304Sjkim BN_print(out, EC_KEY_get0_private_key(a)); 258280304Sjkim BIO_printf(out, "\n"); 259280304Sjkim BIO_printf(out, "public key (x,y): "); 260280304Sjkim BN_print(out, x_a); 261280304Sjkim BIO_printf(out, ","); 262280304Sjkim BN_print(out, y_a); 263280304Sjkim BIO_printf(out, "\nkey b:\n"); 264280304Sjkim BIO_printf(out, "private key: "); 265280304Sjkim BN_print(out, EC_KEY_get0_private_key(b)); 266280304Sjkim BIO_printf(out, "\n"); 267280304Sjkim BIO_printf(out, "public key (x,y): "); 268280304Sjkim BN_print(out, x_b); 269280304Sjkim BIO_printf(out, ","); 270280304Sjkim BN_print(out, y_b); 271280304Sjkim BIO_printf(out, "\n"); 272280304Sjkim BIO_printf(out, "generated key a: "); 273280304Sjkim for (i = 0; i < bout; i++) { 274280304Sjkim sprintf(buf, "%02X", bbuf[i]); 275280304Sjkim BIO_puts(out, buf); 276280304Sjkim } 277280304Sjkim BIO_printf(out, "\n"); 278280304Sjkim BIO_printf(out, "generated key b: "); 279280304Sjkim for (i = 0; i < aout; i++) { 280280304Sjkim sprintf(buf, "%02X", abuf[i]); 281280304Sjkim BIO_puts(out, buf); 282280304Sjkim } 283280304Sjkim BIO_printf(out, "\n"); 284280304Sjkim# endif 285280304Sjkim fprintf(stderr, "Error in ECDH routines\n"); 286280304Sjkim ret = 0; 287280304Sjkim } else { 288280304Sjkim# ifndef NOISY 289280304Sjkim BIO_printf(out, " ok\n"); 290280304Sjkim# endif 291280304Sjkim ret = 1; 292280304Sjkim } 293280304Sjkim err: 294280304Sjkim ERR_print_errors_fp(stderr); 295160814Ssimon 296280304Sjkim if (abuf != NULL) 297280304Sjkim OPENSSL_free(abuf); 298280304Sjkim if (bbuf != NULL) 299280304Sjkim OPENSSL_free(bbuf); 300280304Sjkim if (x_a) 301280304Sjkim BN_free(x_a); 302280304Sjkim if (y_a) 303280304Sjkim BN_free(y_a); 304280304Sjkim if (x_b) 305280304Sjkim BN_free(x_b); 306280304Sjkim if (y_b) 307280304Sjkim BN_free(y_b); 308280304Sjkim if (b) 309280304Sjkim EC_KEY_free(b); 310280304Sjkim if (a) 311280304Sjkim EC_KEY_free(a); 312280304Sjkim return (ret); 313280304Sjkim} 314280304Sjkim 315160814Ssimonint main(int argc, char *argv[]) 316280304Sjkim{ 317280304Sjkim BN_CTX *ctx = NULL; 318280304Sjkim int ret = 1; 319280304Sjkim BIO *out; 320160814Ssimon 321280304Sjkim CRYPTO_malloc_debug_init(); 322280304Sjkim CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); 323280304Sjkim CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 324160814Ssimon 325280304Sjkim# ifdef OPENSSL_SYS_WIN32 326280304Sjkim CRYPTO_malloc_init(); 327280304Sjkim# endif 328160814Ssimon 329280304Sjkim RAND_seed(rnd_seed, sizeof rnd_seed); 330160814Ssimon 331280304Sjkim out = BIO_new(BIO_s_file()); 332280304Sjkim if (out == NULL) 333280304Sjkim EXIT(1); 334280304Sjkim BIO_set_fp(out, stdout, BIO_NOCLOSE); 335160814Ssimon 336280304Sjkim if ((ctx = BN_CTX_new()) == NULL) 337280304Sjkim goto err; 338160814Ssimon 339280304Sjkim /* NIST PRIME CURVES TESTS */ 340280304Sjkim if (!test_ecdh_curve 341280304Sjkim (NID_X9_62_prime192v1, "NIST Prime-Curve P-192", ctx, out)) 342280304Sjkim goto err; 343280304Sjkim if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out)) 344280304Sjkim goto err; 345280304Sjkim if (!test_ecdh_curve 346280304Sjkim (NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out)) 347280304Sjkim goto err; 348280304Sjkim if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out)) 349280304Sjkim goto err; 350280304Sjkim if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out)) 351280304Sjkim goto err; 352280304Sjkim# ifndef OPENSSL_NO_EC2M 353280304Sjkim /* NIST BINARY CURVES TESTS */ 354280304Sjkim if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out)) 355280304Sjkim goto err; 356280304Sjkim if (!test_ecdh_curve(NID_sect163r2, "NIST Binary-Curve B-163", ctx, out)) 357280304Sjkim goto err; 358280304Sjkim if (!test_ecdh_curve(NID_sect233k1, "NIST Binary-Curve K-233", ctx, out)) 359280304Sjkim goto err; 360280304Sjkim if (!test_ecdh_curve(NID_sect233r1, "NIST Binary-Curve B-233", ctx, out)) 361280304Sjkim goto err; 362280304Sjkim if (!test_ecdh_curve(NID_sect283k1, "NIST Binary-Curve K-283", ctx, out)) 363280304Sjkim goto err; 364280304Sjkim if (!test_ecdh_curve(NID_sect283r1, "NIST Binary-Curve B-283", ctx, out)) 365280304Sjkim goto err; 366280304Sjkim if (!test_ecdh_curve(NID_sect409k1, "NIST Binary-Curve K-409", ctx, out)) 367280304Sjkim goto err; 368280304Sjkim if (!test_ecdh_curve(NID_sect409r1, "NIST Binary-Curve B-409", ctx, out)) 369280304Sjkim goto err; 370280304Sjkim if (!test_ecdh_curve(NID_sect571k1, "NIST Binary-Curve K-571", ctx, out)) 371280304Sjkim goto err; 372280304Sjkim if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out)) 373280304Sjkim goto err; 374280304Sjkim# endif 375160814Ssimon 376280304Sjkim ret = 0; 377160814Ssimon 378280304Sjkim err: 379280304Sjkim ERR_print_errors_fp(stderr); 380280304Sjkim if (ctx) 381280304Sjkim BN_CTX_free(ctx); 382280304Sjkim BIO_free(out); 383280304Sjkim CRYPTO_cleanup_all_ex_data(); 384280304Sjkim ERR_remove_thread_state(NULL); 385280304Sjkim CRYPTO_mem_leaks_fp(stderr); 386280304Sjkim EXIT(ret); 387280304Sjkim return (ret); 388280304Sjkim} 389160814Ssimon 390280304Sjkim# if 0 391160814Ssimonstatic void MS_CALLBACK cb(int p, int n, void *arg) 392280304Sjkim{ 393280304Sjkim char c = '*'; 394160814Ssimon 395280304Sjkim if (p == 0) 396280304Sjkim c = '.'; 397280304Sjkim if (p == 1) 398280304Sjkim c = '+'; 399280304Sjkim if (p == 2) 400280304Sjkim c = '*'; 401280304Sjkim if (p == 3) 402280304Sjkim c = '\n'; 403280304Sjkim BIO_write((BIO *)arg, &c, 1); 404280304Sjkim (void)BIO_flush((BIO *)arg); 405280304Sjkim# ifdef LINT 406280304Sjkim p = n; 407280304Sjkim# endif 408280304Sjkim} 409280304Sjkim# endif 410160814Ssimon#endif 411