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