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