ecdhtest.c revision 1.1 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