41725f6a8deef62b9e96871d58cc14a3bcee31a5
[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 static const char rnd_seed[] =
96     "string to make the random number generator think it has entropy";
97
98 static const int KDF1_SHA1_len = 20;
99 static void *KDF1_SHA1(const void *in, size_t inlen, void *out,
100                        size_t *outlen)
101 {
102     if (*outlen < SHA_DIGEST_LENGTH)
103         return NULL;
104     *outlen = SHA_DIGEST_LENGTH;
105     return SHA1(in, inlen, out);
106 }
107
108 static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out)
109 {
110     EC_KEY *a = NULL;
111     EC_KEY *b = NULL;
112     BIGNUM *x_a = NULL, *y_a = NULL, *x_b = NULL, *y_b = NULL;
113     char buf[12];
114     unsigned char *abuf = NULL, *bbuf = NULL;
115     int i, alen, blen, aout, bout, ret = 0;
116     const EC_GROUP *group;
117
118     a = EC_KEY_new_by_curve_name(nid);
119     b = EC_KEY_new_by_curve_name(nid);
120     if (a == NULL || b == NULL)
121         goto err;
122
123     group = EC_KEY_get0_group(a);
124
125     if ((x_a = BN_new()) == NULL)
126         goto err;
127     if ((y_a = BN_new()) == NULL)
128         goto err;
129     if ((x_b = BN_new()) == NULL)
130         goto err;
131     if ((y_b = BN_new()) == NULL)
132         goto err;
133
134     BIO_puts(out, "Testing key generation with ");
135     BIO_puts(out, text);
136 # ifdef NOISY
137     BIO_puts(out, "\n");
138 # else
139     (void)BIO_flush(out);
140 # endif
141
142     if (!EC_KEY_generate_key(a))
143         goto err;
144
145     if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
146         NID_X9_62_prime_field) {
147         if (!EC_POINT_get_affine_coordinates_GFp
148             (group, EC_KEY_get0_public_key(a), x_a, y_a, ctx))
149             goto err;
150     }
151 # ifndef OPENSSL_NO_EC2M
152     else {
153         if (!EC_POINT_get_affine_coordinates_GF2m(group,
154                                                   EC_KEY_get0_public_key(a),
155                                                   x_a, y_a, ctx))
156             goto err;
157     }
158 # endif
159 # ifdef NOISY
160     BIO_puts(out, "  pri 1=");
161     BN_print(out, a->priv_key);
162     BIO_puts(out, "\n  pub 1=");
163     BN_print(out, x_a);
164     BIO_puts(out, ",");
165     BN_print(out, y_a);
166     BIO_puts(out, "\n");
167 # else
168     BIO_printf(out, " .");
169     (void)BIO_flush(out);
170 # endif
171
172     if (!EC_KEY_generate_key(b))
173         goto err;
174
175     if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
176         NID_X9_62_prime_field) {
177         if (!EC_POINT_get_affine_coordinates_GFp
178             (group, EC_KEY_get0_public_key(b), x_b, y_b, ctx))
179             goto err;
180     }
181 # ifndef OPENSSL_NO_EC2M
182     else {
183         if (!EC_POINT_get_affine_coordinates_GF2m(group,
184                                                   EC_KEY_get0_public_key(b),
185                                                   x_b, y_b, ctx))
186             goto err;
187     }
188 # endif
189
190 # ifdef NOISY
191     BIO_puts(out, "  pri 2=");
192     BN_print(out, b->priv_key);
193     BIO_puts(out, "\n  pub 2=");
194     BN_print(out, x_b);
195     BIO_puts(out, ",");
196     BN_print(out, y_b);
197     BIO_puts(out, "\n");
198 # else
199     BIO_printf(out, ".");
200     (void)BIO_flush(out);
201 # endif
202
203     alen = KDF1_SHA1_len;
204     abuf = (unsigned char *)OPENSSL_malloc(alen);
205     aout =
206         ECDH_compute_key(abuf, alen, EC_KEY_get0_public_key(b), a, KDF1_SHA1);
207
208 # ifdef NOISY
209     BIO_puts(out, "  key1 =");
210     for (i = 0; i < aout; i++) {
211         sprintf(buf, "%02X", abuf[i]);
212         BIO_puts(out, buf);
213     }
214     BIO_puts(out, "\n");
215 # else
216     BIO_printf(out, ".");
217     (void)BIO_flush(out);
218 # endif
219
220     blen = KDF1_SHA1_len;
221     bbuf = (unsigned char *)OPENSSL_malloc(blen);
222     bout =
223         ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(a), b, KDF1_SHA1);
224
225 # ifdef NOISY
226     BIO_puts(out, "  key2 =");
227     for (i = 0; i < bout; i++) {
228         sprintf(buf, "%02X", bbuf[i]);
229         BIO_puts(out, buf);
230     }
231     BIO_puts(out, "\n");
232 # else
233     BIO_printf(out, ".");
234     (void)BIO_flush(out);
235 # endif
236
237     if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) {
238 # ifndef NOISY
239         BIO_printf(out, " failed\n\n");
240         BIO_printf(out, "key a:\n");
241         BIO_printf(out, "private key: ");
242         BN_print(out, EC_KEY_get0_private_key(a));
243         BIO_printf(out, "\n");
244         BIO_printf(out, "public key (x,y): ");
245         BN_print(out, x_a);
246         BIO_printf(out, ",");
247         BN_print(out, y_a);
248         BIO_printf(out, "\nkey b:\n");
249         BIO_printf(out, "private key: ");
250         BN_print(out, EC_KEY_get0_private_key(b));
251         BIO_printf(out, "\n");
252         BIO_printf(out, "public key (x,y): ");
253         BN_print(out, x_b);
254         BIO_printf(out, ",");
255         BN_print(out, y_b);
256         BIO_printf(out, "\n");
257         BIO_printf(out, "generated key a: ");
258         for (i = 0; i < bout; i++) {
259             sprintf(buf, "%02X", bbuf[i]);
260             BIO_puts(out, buf);
261         }
262         BIO_printf(out, "\n");
263         BIO_printf(out, "generated key b: ");
264         for (i = 0; i < aout; i++) {
265             sprintf(buf, "%02X", abuf[i]);
266             BIO_puts(out, buf);
267         }
268         BIO_printf(out, "\n");
269 # endif
270         fprintf(stderr, "Error in ECDH routines\n");
271         ret = 0;
272     } else {
273 # ifndef NOISY
274         BIO_printf(out, " ok\n");
275 # endif
276         ret = 1;
277     }
278  err:
279     ERR_print_errors_fp(stderr);
280
281     if (abuf != NULL)
282         OPENSSL_free(abuf);
283     if (bbuf != NULL)
284         OPENSSL_free(bbuf);
285     if (x_a)
286         BN_free(x_a);
287     if (y_a)
288         BN_free(y_a);
289     if (x_b)
290         BN_free(x_b);
291     if (y_b)
292         BN_free(y_b);
293     if (b)
294         EC_KEY_free(b);
295     if (a)
296         EC_KEY_free(a);
297     return (ret);
298 }
299
300 /* Keys and shared secrets from RFC 7027 */
301
302 static const unsigned char bp256_da[] = {
303     0x81, 0xDB, 0x1E, 0xE1, 0x00, 0x15, 0x0F, 0xF2, 0xEA, 0x33, 0x8D, 0x70,
304     0x82, 0x71, 0xBE, 0x38, 0x30, 0x0C, 0xB5, 0x42, 0x41, 0xD7, 0x99, 0x50,
305     0xF7, 0x7B, 0x06, 0x30, 0x39, 0x80, 0x4F, 0x1D
306 };
307
308 static const unsigned char bp256_db[] = {
309     0x55, 0xE4, 0x0B, 0xC4, 0x1E, 0x37, 0xE3, 0xE2, 0xAD, 0x25, 0xC3, 0xC6,
310     0x65, 0x45, 0x11, 0xFF, 0xA8, 0x47, 0x4A, 0x91, 0xA0, 0x03, 0x20, 0x87,
311     0x59, 0x38, 0x52, 0xD3, 0xE7, 0xD7, 0x6B, 0xD3
312 };
313
314 static const unsigned char bp256_Z[] = {
315     0x89, 0xAF, 0xC3, 0x9D, 0x41, 0xD3, 0xB3, 0x27, 0x81, 0x4B, 0x80, 0x94,
316     0x0B, 0x04, 0x25, 0x90, 0xF9, 0x65, 0x56, 0xEC, 0x91, 0xE6, 0xAE, 0x79,
317     0x39, 0xBC, 0xE3, 0x1F, 0x3A, 0x18, 0xBF, 0x2B
318 };
319
320 static const unsigned char bp384_da[] = {
321     0x1E, 0x20, 0xF5, 0xE0, 0x48, 0xA5, 0x88, 0x6F, 0x1F, 0x15, 0x7C, 0x74,
322     0xE9, 0x1B, 0xDE, 0x2B, 0x98, 0xC8, 0xB5, 0x2D, 0x58, 0xE5, 0x00, 0x3D,
323     0x57, 0x05, 0x3F, 0xC4, 0xB0, 0xBD, 0x65, 0xD6, 0xF1, 0x5E, 0xB5, 0xD1,
324     0xEE, 0x16, 0x10, 0xDF, 0x87, 0x07, 0x95, 0x14, 0x36, 0x27, 0xD0, 0x42
325 };
326
327 static const unsigned char bp384_db[] = {
328     0x03, 0x26, 0x40, 0xBC, 0x60, 0x03, 0xC5, 0x92, 0x60, 0xF7, 0x25, 0x0C,
329     0x3D, 0xB5, 0x8C, 0xE6, 0x47, 0xF9, 0x8E, 0x12, 0x60, 0xAC, 0xCE, 0x4A,
330     0xCD, 0xA3, 0xDD, 0x86, 0x9F, 0x74, 0xE0, 0x1F, 0x8B, 0xA5, 0xE0, 0x32,
331     0x43, 0x09, 0xDB, 0x6A, 0x98, 0x31, 0x49, 0x7A, 0xBA, 0xC9, 0x66, 0x70
332 };
333
334 static const unsigned char bp384_Z[] = {
335     0x0B, 0xD9, 0xD3, 0xA7, 0xEA, 0x0B, 0x3D, 0x51, 0x9D, 0x09, 0xD8, 0xE4,
336     0x8D, 0x07, 0x85, 0xFB, 0x74, 0x4A, 0x6B, 0x35, 0x5E, 0x63, 0x04, 0xBC,
337     0x51, 0xC2, 0x29, 0xFB, 0xBC, 0xE2, 0x39, 0xBB, 0xAD, 0xF6, 0x40, 0x37,
338     0x15, 0xC3, 0x5D, 0x4F, 0xB2, 0xA5, 0x44, 0x4F, 0x57, 0x5D, 0x4F, 0x42
339 };
340
341 static const unsigned char bp512_da[] = {
342     0x16, 0x30, 0x2F, 0xF0, 0xDB, 0xBB, 0x5A, 0x8D, 0x73, 0x3D, 0xAB, 0x71,
343     0x41, 0xC1, 0xB4, 0x5A, 0xCB, 0xC8, 0x71, 0x59, 0x39, 0x67, 0x7F, 0x6A,
344     0x56, 0x85, 0x0A, 0x38, 0xBD, 0x87, 0xBD, 0x59, 0xB0, 0x9E, 0x80, 0x27,
345     0x96, 0x09, 0xFF, 0x33, 0x3E, 0xB9, 0xD4, 0xC0, 0x61, 0x23, 0x1F, 0xB2,
346     0x6F, 0x92, 0xEE, 0xB0, 0x49, 0x82, 0xA5, 0xF1, 0xD1, 0x76, 0x4C, 0xAD,
347     0x57, 0x66, 0x54, 0x22
348 };
349
350 static const unsigned char bp512_db[] = {
351     0x23, 0x0E, 0x18, 0xE1, 0xBC, 0xC8, 0x8A, 0x36, 0x2F, 0xA5, 0x4E, 0x4E,
352     0xA3, 0x90, 0x20, 0x09, 0x29, 0x2F, 0x7F, 0x80, 0x33, 0x62, 0x4F, 0xD4,
353     0x71, 0xB5, 0xD8, 0xAC, 0xE4, 0x9D, 0x12, 0xCF, 0xAB, 0xBC, 0x19, 0x96,
354     0x3D, 0xAB, 0x8E, 0x2F, 0x1E, 0xBA, 0x00, 0xBF, 0xFB, 0x29, 0xE4, 0xD7,
355     0x2D, 0x13, 0xF2, 0x22, 0x45, 0x62, 0xF4, 0x05, 0xCB, 0x80, 0x50, 0x36,
356     0x66, 0xB2, 0x54, 0x29
357 };
358
359 static const unsigned char bp512_Z[] = {
360     0xA7, 0x92, 0x70, 0x98, 0x65, 0x5F, 0x1F, 0x99, 0x76, 0xFA, 0x50, 0xA9,
361     0xD5, 0x66, 0x86, 0x5D, 0xC5, 0x30, 0x33, 0x18, 0x46, 0x38, 0x1C, 0x87,
362     0x25, 0x6B, 0xAF, 0x32, 0x26, 0x24, 0x4B, 0x76, 0xD3, 0x64, 0x03, 0xC0,
363     0x24, 0xD7, 0xBB, 0xF0, 0xAA, 0x08, 0x03, 0xEA, 0xFF, 0x40, 0x5D, 0x3D,
364     0x24, 0xF1, 0x1A, 0x9B, 0x5C, 0x0B, 0xEF, 0x67, 0x9F, 0xE1, 0x45, 0x4B,
365     0x21, 0xC4, 0xCD, 0x1F
366 };
367
368 /* Given private value and NID, create EC_KEY structure */
369
370 static EC_KEY *mk_eckey(int nid, const unsigned char *p, size_t plen)
371 {
372     int ok = 0;
373     EC_KEY *k = NULL;
374     BIGNUM *priv = NULL;
375     EC_POINT *pub = NULL;
376     const EC_GROUP *grp;
377     k = EC_KEY_new_by_curve_name(nid);
378     if (!k)
379         goto err;
380     priv = BN_bin2bn(p, plen, NULL);
381     if (!priv)
382         goto err;
383     if (!EC_KEY_set_private_key(k, priv))
384         goto err;
385     grp = EC_KEY_get0_group(k);
386     pub = EC_POINT_new(grp);
387     if (!pub)
388         goto err;
389     if (!EC_POINT_mul(grp, pub, priv, NULL, NULL, NULL))
390         goto err;
391     if (!EC_KEY_set_public_key(k, pub))
392         goto err;
393     ok = 1;
394  err:
395     if (priv)
396         BN_clear_free(priv);
397     if (pub)
398         EC_POINT_free(pub);
399     if (ok)
400         return k;
401     else if (k)
402         EC_KEY_free(k);
403     return NULL;
404 }
405
406 /*
407  * Known answer test: compute shared secret and check it matches expected
408  * value.
409  */
410
411 static int ecdh_kat(BIO *out, const char *cname, int nid,
412                     const unsigned char *k1, size_t k1_len,
413                     const unsigned char *k2, size_t k2_len,
414                     const unsigned char *Z, size_t Zlen)
415 {
416     int rv = 0;
417     EC_KEY *key1 = NULL, *key2 = NULL;
418     unsigned char *Ztmp = NULL;
419     size_t Ztmplen;
420     BIO_puts(out, "Testing ECDH shared secret with ");
421     BIO_puts(out, cname);
422     key1 = mk_eckey(nid, k1, k1_len);
423     key2 = mk_eckey(nid, k2, k2_len);
424     if (!key1 || !key2)
425         goto err;
426     Ztmplen = (EC_GROUP_get_degree(EC_KEY_get0_group(key1)) + 7) / 8;
427     if (Ztmplen != Zlen)
428         goto err;
429     Ztmp = OPENSSL_malloc(Ztmplen);
430     if (!ECDH_compute_key(Ztmp, Ztmplen,
431                           EC_KEY_get0_public_key(key2), key1, 0))
432         goto err;
433     if (memcmp(Ztmp, Z, Zlen))
434         goto err;
435     memset(Ztmp, 0, Zlen);
436     if (!ECDH_compute_key(Ztmp, Ztmplen,
437                           EC_KEY_get0_public_key(key1), key2, 0))
438         goto err;
439     if (memcmp(Ztmp, Z, Zlen))
440         goto err;
441     rv = 1;
442  err:
443     if (key1)
444         EC_KEY_free(key1);
445     if (key2)
446         EC_KEY_free(key2);
447     if (Ztmp)
448         OPENSSL_free(Ztmp);
449     if (rv)
450         BIO_puts(out, " ok\n");
451     else {
452         fprintf(stderr, "Error in ECDH routines\n");
453         ERR_print_errors_fp(stderr);
454     }
455     return rv;
456 }
457
458 # define test_ecdh_kat(bio, curve, bits) \
459         ecdh_kat(bio, curve, NID_brainpoolP##bits##r1, \
460                 bp##bits##_da, sizeof(bp##bits##_da), \
461                 bp##bits##_db, sizeof(bp##bits##_db), \
462                 bp##bits##_Z, sizeof(bp##bits##_Z))
463
464 int main(int argc, char *argv[])
465 {
466     BN_CTX *ctx = NULL;
467     int ret = 1;
468     BIO *out;
469
470     CRYPTO_malloc_debug_init();
471     CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
472     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
473
474 # ifdef OPENSSL_SYS_WIN32
475     CRYPTO_malloc_init();
476 # endif
477
478     RAND_seed(rnd_seed, sizeof rnd_seed);
479
480     out = BIO_new(BIO_s_file());
481     if (out == NULL)
482         EXIT(1);
483     BIO_set_fp(out, stdout, BIO_NOCLOSE);
484
485     if ((ctx = BN_CTX_new()) == NULL)
486         goto err;
487
488     /* NIST PRIME CURVES TESTS */
489     if (!test_ecdh_curve
490         (NID_X9_62_prime192v1, "NIST Prime-Curve P-192", ctx, out))
491         goto err;
492     if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out))
493         goto err;
494     if (!test_ecdh_curve
495         (NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out))
496         goto err;
497     if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out))
498         goto err;
499     if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out))
500         goto err;
501 # ifndef OPENSSL_NO_EC2M
502     /* NIST BINARY CURVES TESTS */
503     if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out))
504         goto err;
505     if (!test_ecdh_curve(NID_sect163r2, "NIST Binary-Curve B-163", ctx, out))
506         goto err;
507     if (!test_ecdh_curve(NID_sect233k1, "NIST Binary-Curve K-233", ctx, out))
508         goto err;
509     if (!test_ecdh_curve(NID_sect233r1, "NIST Binary-Curve B-233", ctx, out))
510         goto err;
511     if (!test_ecdh_curve(NID_sect283k1, "NIST Binary-Curve K-283", ctx, out))
512         goto err;
513     if (!test_ecdh_curve(NID_sect283r1, "NIST Binary-Curve B-283", ctx, out))
514         goto err;
515     if (!test_ecdh_curve(NID_sect409k1, "NIST Binary-Curve K-409", ctx, out))
516         goto err;
517     if (!test_ecdh_curve(NID_sect409r1, "NIST Binary-Curve B-409", ctx, out))
518         goto err;
519     if (!test_ecdh_curve(NID_sect571k1, "NIST Binary-Curve K-571", ctx, out))
520         goto err;
521     if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out))
522         goto err;
523 # endif
524     if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP256r1", 256))
525         goto err;
526     if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP384r1", 384))
527         goto err;
528     if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP512r1", 512))
529         goto err;
530
531     ret = 0;
532
533  err:
534     ERR_print_errors_fp(stderr);
535     if (ctx)
536         BN_CTX_free(ctx);
537     BIO_free(out);
538     CRYPTO_cleanup_all_ex_data();
539     ERR_remove_thread_state(NULL);
540     CRYPTO_mem_leaks_fp(stderr);
541     EXIT(ret);
542 }
543 #endif