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