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