ecdhtest.c revision 296341
1154484Sjhb/* crypto/ecdh/ecdhtest.c */ 2154484Sjhb/* ==================================================================== 3154484Sjhb * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 4154484Sjhb * 5154484Sjhb * The Elliptic Curve Public-Key Crypto Library (ECC Code) included 6154484Sjhb * herein is developed by SUN MICROSYSTEMS, INC., and is contributed 7154484Sjhb * to the OpenSSL project. 8154484Sjhb * 9154484Sjhb * The ECC Code is licensed pursuant to the OpenSSL open source 10154484Sjhb * license provided below. 11154484Sjhb * 12154484Sjhb * The ECDH software is originally written by Douglas Stebila of 13154484Sjhb * Sun Microsystems Laboratories. 14154484Sjhb * 15154484Sjhb */ 16154484Sjhb/* ==================================================================== 17154484Sjhb * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 18154484Sjhb * 19154484Sjhb * Redistribution and use in source and binary forms, with or without 20154484Sjhb * modification, are permitted provided that the following conditions 21154484Sjhb * are met: 22154484Sjhb * 23154484Sjhb * 1. Redistributions of source code must retain the above copyright 24154484Sjhb * notice, this list of conditions and the following disclaimer. 25154484Sjhb * 26154484Sjhb * 2. Redistributions in binary form must reproduce the above copyright 27154484Sjhb * notice, this list of conditions and the following disclaimer in 28154484Sjhb * the documentation and/or other materials provided with the 29154484Sjhb * distribution. 30154484Sjhb * 31154484Sjhb * 3. All advertising materials mentioning features or use of this 32154484Sjhb * software must display the following acknowledgment: 33154484Sjhb * "This product includes software developed by the OpenSSL Project 34154484Sjhb * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 35154485Sjhb * 36164159Skmacy * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 37154485Sjhb * endorse or promote products derived from this software without 38154484Sjhb * prior written permission. For written permission, please contact 39154484Sjhb * openssl-core@openssl.org. 40174629Sjeff * 41154484Sjhb * 5. Products derived from this software may not be called "OpenSSL" 42154484Sjhb * nor may "OpenSSL" appear in their names without prior written 43174629Sjeff * permission of the OpenSSL Project. 44174629Sjeff * 45189845Sjeff * 6. Redistributions of any form whatsoever must retain the following 46174629Sjeff * acknowledgment: 47174629Sjeff * "This product includes software developed by the OpenSSL Project 48164159Skmacy * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 49189845Sjeff * 50174629Sjeff * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 51164159Skmacy * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52154484Sjhb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 53154484Sjhb * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 54154484Sjhb * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 55154484Sjhb * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 56154484Sjhb * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 57174629Sjeff * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58174629Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 59154484Sjhb * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60154484Sjhb * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 61154484Sjhb * OF THE POSSIBILITY OF SUCH DAMAGE. 62154484Sjhb * ==================================================================== 63154484Sjhb * 64154484Sjhb * This product includes cryptographic software written by Eric Young 65173444Sups * (eay@cryptsoft.com). This product includes software written by Tim 66256001Sjhb * Hudson (tjh@cryptsoft.com). 67154941Sjhb * 68164246Skmacy */ 69154484Sjhb 70154484Sjhb#include <stdio.h> 71154484Sjhb#include <stdlib.h> 72154484Sjhb#include <string.h> 73154484Sjhb 74154484Sjhb#include "../e_os.h" 75154484Sjhb 76154484Sjhb#include <openssl/opensslconf.h> /* for OPENSSL_NO_ECDH */ 77154484Sjhb#include <openssl/crypto.h> 78154484Sjhb#include <openssl/bio.h> 79154484Sjhb#include <openssl/bn.h> 80154484Sjhb#include <openssl/objects.h> 81154484Sjhb#include <openssl/rand.h> 82154484Sjhb#include <openssl/sha.h> 83154484Sjhb#include <openssl/err.h> 84154484Sjhb 85154484Sjhb#ifdef OPENSSL_NO_ECDH 86154484Sjhbint main(int argc, char *argv[]) 87154484Sjhb{ 88154484Sjhb printf("No ECDH support\n"); 89154484Sjhb return (0); 90154484Sjhb} 91154484Sjhb#else 92154484Sjhb# include <openssl/ec.h> 93179025Sattilio# include <openssl/ecdh.h> 94154484Sjhb 95154484Sjhb# ifdef OPENSSL_SYS_WIN16 96154484Sjhb# define MS_CALLBACK _far _loadds 97154484Sjhb# else 98154484Sjhb# define MS_CALLBACK 99154484Sjhb# endif 100154484Sjhb 101154484Sjhb# if 0 102154484Sjhbstatic void MS_CALLBACK cb(int p, int n, void *arg); 103154484Sjhb# endif 104154484Sjhb 105154484Sjhbstatic const char rnd_seed[] = 106154484Sjhb "string to make the random number generator think it has entropy"; 107154484Sjhb 108154484Sjhbstatic const int KDF1_SHA1_len = 20; 109154484Sjhbstatic void *KDF1_SHA1(const void *in, size_t inlen, void *out, 110154484Sjhb size_t *outlen) 111154484Sjhb{ 112154484Sjhb# ifndef OPENSSL_NO_SHA 113154484Sjhb if (*outlen < SHA_DIGEST_LENGTH) 114154484Sjhb return NULL; 115154484Sjhb else 116154484Sjhb *outlen = SHA_DIGEST_LENGTH; 117154484Sjhb return SHA1(in, inlen, out); 118154484Sjhb# else 119154484Sjhb return NULL; 120154484Sjhb# endif 121154484Sjhb} 122154484Sjhb 123154484Sjhbstatic int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out) 124154484Sjhb{ 125164159Skmacy EC_KEY *a = NULL; 126164159Skmacy EC_KEY *b = NULL; 127174629Sjeff BIGNUM *x_a = NULL, *y_a = NULL, *x_b = NULL, *y_b = NULL; 128174629Sjeff char buf[12]; 129174629Sjeff unsigned char *abuf = NULL, *bbuf = NULL; 130174629Sjeff int i, alen, blen, aout, bout, ret = 0; 131174629Sjeff const EC_GROUP *group; 132174629Sjeff 133174629Sjeff a = EC_KEY_new_by_curve_name(nid); 134174629Sjeff b = EC_KEY_new_by_curve_name(nid); 135174629Sjeff if (a == NULL || b == NULL) 136174629Sjeff goto err; 137174629Sjeff 138174629Sjeff group = EC_KEY_get0_group(a); 139209390Sed 140209390Sed if ((x_a = BN_new()) == NULL) 141174629Sjeff goto err; 142174629Sjeff if ((y_a = BN_new()) == NULL) 143174629Sjeff goto err; 144174629Sjeff if ((x_b = BN_new()) == NULL) 145174629Sjeff goto err; 146174629Sjeff if ((y_b = BN_new()) == NULL) 147174629Sjeff goto err; 148174629Sjeff 149175010Sjeff BIO_puts(out, "Testing key generation with "); 150174629Sjeff BIO_puts(out, text); 151174629Sjeff# ifdef NOISY 152174629Sjeff BIO_puts(out, "\n"); 153174629Sjeff# else 154180852Skmacy (void)BIO_flush(out); 155174629Sjeff# endif 156174629Sjeff 157174629Sjeff if (!EC_KEY_generate_key(a)) 158174629Sjeff goto err; 159174629Sjeff 160174629Sjeff if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == 161174629Sjeff NID_X9_62_prime_field) { 162174629Sjeff if (!EC_POINT_get_affine_coordinates_GFp 163174629Sjeff (group, EC_KEY_get0_public_key(a), x_a, y_a, ctx)) 164174629Sjeff goto err; 165174629Sjeff } 166174629Sjeff# ifndef OPENSSL_NO_EC2M 167174629Sjeff else { 168174629Sjeff if (!EC_POINT_get_affine_coordinates_GF2m(group, 169174629Sjeff EC_KEY_get0_public_key(a), 170215034Sbrucec x_a, y_a, ctx)) 171174629Sjeff goto err; 172174629Sjeff } 173174629Sjeff# endif 174174629Sjeff# ifdef NOISY 175174629Sjeff BIO_puts(out, " pri 1="); 176174629Sjeff BN_print(out, a->priv_key); 177174629Sjeff BIO_puts(out, "\n pub 1="); 178174629Sjeff BN_print(out, x_a); 179174629Sjeff BIO_puts(out, ","); 180174629Sjeff BN_print(out, y_a); 181174629Sjeff BIO_puts(out, "\n"); 182174629Sjeff# else 183174629Sjeff BIO_printf(out, " ."); 184174629Sjeff (void)BIO_flush(out); 185174629Sjeff# endif 186174629Sjeff 187174629Sjeff if (!EC_KEY_generate_key(b)) 188189845Sjeff goto err; 189189845Sjeff 190174629Sjeff if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == 191212750Smdf NID_X9_62_prime_field) { 192174629Sjeff if (!EC_POINT_get_affine_coordinates_GFp 193174629Sjeff (group, EC_KEY_get0_public_key(b), x_b, y_b, ctx)) 194174629Sjeff goto err; 195174629Sjeff } 196174629Sjeff# ifndef OPENSSL_NO_EC2M 197174629Sjeff else { 198209390Sed if (!EC_POINT_get_affine_coordinates_GF2m(group, 199174629Sjeff EC_KEY_get0_public_key(b), 200164159Skmacy x_b, y_b, ctx)) 201174629Sjeff goto err; 202209390Sed } 203164159Skmacy# endif 204174629Sjeff 205174629Sjeff# ifdef NOISY 206209390Sed BIO_puts(out, " pri 2="); 207174629Sjeff BN_print(out, b->priv_key); 208174629Sjeff BIO_puts(out, "\n pub 2="); 209174629Sjeff BN_print(out, x_b); 210174629Sjeff BIO_puts(out, ","); 211174629Sjeff BN_print(out, y_b); 212174629Sjeff BIO_puts(out, "\n"); 213174629Sjeff# else 214174629Sjeff BIO_printf(out, "."); 215174629Sjeff (void)BIO_flush(out); 216174629Sjeff# endif 217174629Sjeff 218174629Sjeff alen = KDF1_SHA1_len; 219174629Sjeff abuf = (unsigned char *)OPENSSL_malloc(alen); 220174629Sjeff aout = 221174629Sjeff ECDH_compute_key(abuf, alen, EC_KEY_get0_public_key(b), a, KDF1_SHA1); 222174629Sjeff 223174629Sjeff# ifdef NOISY 224174629Sjeff BIO_puts(out, " key1 ="); 225174629Sjeff for (i = 0; i < aout; i++) { 226174629Sjeff sprintf(buf, "%02X", abuf[i]); 227174629Sjeff BIO_puts(out, buf); 228174629Sjeff } 229174629Sjeff BIO_puts(out, "\n"); 230174629Sjeff# else 231174629Sjeff BIO_printf(out, "."); 232174629Sjeff (void)BIO_flush(out); 233174629Sjeff# endif 234174629Sjeff 235174629Sjeff blen = KDF1_SHA1_len; 236174629Sjeff bbuf = (unsigned char *)OPENSSL_malloc(blen); 237174629Sjeff bout = 238174629Sjeff ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(a), b, KDF1_SHA1); 239174629Sjeff 240174629Sjeff# ifdef NOISY 241189845Sjeff BIO_puts(out, " key2 ="); 242189845Sjeff for (i = 0; i < bout; i++) { 243189845Sjeff sprintf(buf, "%02X", bbuf[i]); 244189845Sjeff BIO_puts(out, buf); 245189845Sjeff } 246189845Sjeff BIO_puts(out, "\n"); 247174629Sjeff# else 248189845Sjeff BIO_printf(out, "."); 249189845Sjeff (void)BIO_flush(out); 250189845Sjeff# endif 251189845Sjeff 252189845Sjeff if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) { 253189845Sjeff# ifndef NOISY 254189845Sjeff BIO_printf(out, " failed\n\n"); 255209059Sjhb BIO_printf(out, "key a:\n"); 256189845Sjeff BIO_printf(out, "private key: "); 257189845Sjeff BN_print(out, EC_KEY_get0_private_key(a)); 258189845Sjeff BIO_printf(out, "\n"); 259189845Sjeff BIO_printf(out, "public key (x,y): "); 260189845Sjeff BN_print(out, x_a); 261189845Sjeff BIO_printf(out, ","); 262189845Sjeff BN_print(out, y_a); 263189845Sjeff BIO_printf(out, "\nkey b:\n"); 264189845Sjeff BIO_printf(out, "private key: "); 265189845Sjeff BN_print(out, EC_KEY_get0_private_key(b)); 266189845Sjeff BIO_printf(out, "\n"); 267189845Sjeff BIO_printf(out, "public key (x,y): "); 268189845Sjeff BN_print(out, x_b); 269189845Sjeff BIO_printf(out, ","); 270189845Sjeff BN_print(out, y_b); 271189845Sjeff BIO_printf(out, "\n"); 272189845Sjeff BIO_printf(out, "generated key a: "); 273189845Sjeff for (i = 0; i < bout; i++) { 274189845Sjeff sprintf(buf, "%02X", bbuf[i]); 275174629Sjeff BIO_puts(out, buf); 276174629Sjeff } 277174629Sjeff BIO_printf(out, "\n"); 278174629Sjeff BIO_printf(out, "generated key b: "); 279174629Sjeff for (i = 0; i < aout; i++) { 280189845Sjeff sprintf(buf, "%02X", abuf[i]); 281189845Sjeff BIO_puts(out, buf); 282189845Sjeff } 283189845Sjeff BIO_printf(out, "\n"); 284189845Sjeff# endif 285189845Sjeff fprintf(stderr, "Error in ECDH routines\n"); 286189845Sjeff ret = 0; 287189845Sjeff } else { 288174629Sjeff# ifndef NOISY 289174629Sjeff BIO_printf(out, " ok\n"); 290189845Sjeff# endif 291189845Sjeff ret = 1; 292189845Sjeff } 293189845Sjeff err: 294189845Sjeff ERR_print_errors_fp(stderr); 295189845Sjeff 296174629Sjeff if (abuf != NULL) 297174629Sjeff OPENSSL_free(abuf); 298174629Sjeff if (bbuf != NULL) 299174629Sjeff OPENSSL_free(bbuf); 300174629Sjeff if (x_a) 301174629Sjeff BN_free(x_a); 302189845Sjeff if (y_a) 303189845Sjeff BN_free(y_a); 304189845Sjeff if (x_b) 305174629Sjeff BN_free(x_b); 306174629Sjeff if (y_b) 307174629Sjeff BN_free(y_b); 308174629Sjeff if (b) 309189845Sjeff EC_KEY_free(b); 310174629Sjeff if (a) 311174629Sjeff EC_KEY_free(a); 312174629Sjeff return (ret); 313174629Sjeff} 314174629Sjeff 315174629Sjeffint main(int argc, char *argv[]) 316174629Sjeff{ 317174629Sjeff BN_CTX *ctx = NULL; 318174629Sjeff int ret = 1; 319174629Sjeff BIO *out; 320180852Skmacy 321180852Skmacy CRYPTO_malloc_debug_init(); 322174629Sjeff CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); 323174629Sjeff CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); 324174629Sjeff 325174629Sjeff# ifdef OPENSSL_SYS_WIN32 326174629Sjeff CRYPTO_malloc_init(); 327174629Sjeff# endif 328175010Sjeff 329174629Sjeff RAND_seed(rnd_seed, sizeof rnd_seed); 330174629Sjeff 331174629Sjeff out = BIO_new(BIO_s_file()); 332174629Sjeff if (out == NULL) 333174629Sjeff EXIT(1); 334174629Sjeff BIO_set_fp(out, stdout, BIO_NOCLOSE); 335174629Sjeff 336174629Sjeff if ((ctx = BN_CTX_new()) == NULL) 337174629Sjeff goto err; 338174629Sjeff 339174629Sjeff /* NIST PRIME CURVES TESTS */ 340174629Sjeff if (!test_ecdh_curve 341175010Sjeff (NID_X9_62_prime192v1, "NIST Prime-Curve P-192", ctx, out)) 342174629Sjeff goto err; 343174629Sjeff if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out)) 344174629Sjeff goto err; 345174629Sjeff if (!test_ecdh_curve 346174629Sjeff (NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out)) 347174629Sjeff goto err; 348174629Sjeff if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out)) 349174629Sjeff goto err; 350174629Sjeff if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out)) 351174629Sjeff goto err; 352175010Sjeff# ifndef OPENSSL_NO_EC2M 353174629Sjeff /* NIST BINARY CURVES TESTS */ 354174629Sjeff if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out)) 355174629Sjeff goto err; 356174629Sjeff if (!test_ecdh_curve(NID_sect163r2, "NIST Binary-Curve B-163", ctx, out)) 357180852Skmacy goto err; 358180852Skmacy if (!test_ecdh_curve(NID_sect233k1, "NIST Binary-Curve K-233", ctx, out)) 359174629Sjeff goto err; 360174629Sjeff if (!test_ecdh_curve(NID_sect233r1, "NIST Binary-Curve B-233", ctx, out)) 361174629Sjeff goto err; 362174629Sjeff if (!test_ecdh_curve(NID_sect283k1, "NIST Binary-Curve K-283", ctx, out)) 363174629Sjeff goto err; 364174629Sjeff if (!test_ecdh_curve(NID_sect283r1, "NIST Binary-Curve B-283", ctx, out)) 365167012Skmacy goto err; 366174629Sjeff if (!test_ecdh_curve(NID_sect409k1, "NIST Binary-Curve K-409", ctx, out)) 367174629Sjeff goto err; 368174629Sjeff if (!test_ecdh_curve(NID_sect409r1, "NIST Binary-Curve B-409", ctx, out)) 369174629Sjeff goto err; 370174629Sjeff if (!test_ecdh_curve(NID_sect571k1, "NIST Binary-Curve K-571", ctx, out)) 371174629Sjeff goto err; 372174629Sjeff if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out)) 373174629Sjeff goto err; 374174629Sjeff# endif 375174629Sjeff 376174629Sjeff ret = 0; 377174629Sjeff 378174629Sjeff err: 379174629Sjeff ERR_print_errors_fp(stderr); 380174629Sjeff if (ctx) 381174629Sjeff BN_CTX_free(ctx); 382174629Sjeff BIO_free(out); 383174629Sjeff CRYPTO_cleanup_all_ex_data(); 384174629Sjeff ERR_remove_thread_state(NULL); 385174629Sjeff CRYPTO_mem_leaks_fp(stderr); 386174629Sjeff EXIT(ret); 387174629Sjeff return (ret); 388174629Sjeff} 389174629Sjeff 390174629Sjeff# if 0 391174629Sjeffstatic void MS_CALLBACK cb(int p, int n, void *arg) 392175010Sjeff{ 393174629Sjeff char c = '*'; 394217916Smdf 395217916Smdf if (p == 0) 396217916Smdf c = '.'; 397212750Smdf if (p == 1) 398180852Skmacy c = '+'; 399180852Skmacy if (p == 2) 400175010Sjeff c = '*'; 401175010Sjeff if (p == 3) 402189845Sjeff c = '\n'; 403174629Sjeff BIO_write((BIO *)arg, &c, 1); 404174629Sjeff (void)BIO_flush((BIO *)arg); 405174629Sjeff# ifdef LINT 406174629Sjeff p = n; 407174629Sjeff# endif 408174629Sjeff} 409174629Sjeff# endif 410175010Sjeff#endif 411174629Sjeff