af124764c832cc26547b317bce42359c53775e56
[openssl.git] / test / 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_EC */
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_EC
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 = 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 = 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     BN_free(x_a);
286     BN_free(y_a);
287     BN_free(x_b);
288     BN_free(y_b);
289     EC_KEY_free(b);
290     EC_KEY_free(a);
291     return (ret);
292 }
293
294 /* Keys and shared secrets from RFC 7027 */
295
296 static const unsigned char bp256_da[] = {
297     0x81, 0xDB, 0x1E, 0xE1, 0x00, 0x15, 0x0F, 0xF2, 0xEA, 0x33, 0x8D, 0x70,
298     0x82, 0x71, 0xBE, 0x38, 0x30, 0x0C, 0xB5, 0x42, 0x41, 0xD7, 0x99, 0x50,
299     0xF7, 0x7B, 0x06, 0x30, 0x39, 0x80, 0x4F, 0x1D
300 };
301
302 static const unsigned char bp256_db[] = {
303     0x55, 0xE4, 0x0B, 0xC4, 0x1E, 0x37, 0xE3, 0xE2, 0xAD, 0x25, 0xC3, 0xC6,
304     0x65, 0x45, 0x11, 0xFF, 0xA8, 0x47, 0x4A, 0x91, 0xA0, 0x03, 0x20, 0x87,
305     0x59, 0x38, 0x52, 0xD3, 0xE7, 0xD7, 0x6B, 0xD3
306 };
307
308 static const unsigned char bp256_Z[] = {
309     0x89, 0xAF, 0xC3, 0x9D, 0x41, 0xD3, 0xB3, 0x27, 0x81, 0x4B, 0x80, 0x94,
310     0x0B, 0x04, 0x25, 0x90, 0xF9, 0x65, 0x56, 0xEC, 0x91, 0xE6, 0xAE, 0x79,
311     0x39, 0xBC, 0xE3, 0x1F, 0x3A, 0x18, 0xBF, 0x2B
312 };
313
314 static const unsigned char bp384_da[] = {
315     0x1E, 0x20, 0xF5, 0xE0, 0x48, 0xA5, 0x88, 0x6F, 0x1F, 0x15, 0x7C, 0x74,
316     0xE9, 0x1B, 0xDE, 0x2B, 0x98, 0xC8, 0xB5, 0x2D, 0x58, 0xE5, 0x00, 0x3D,
317     0x57, 0x05, 0x3F, 0xC4, 0xB0, 0xBD, 0x65, 0xD6, 0xF1, 0x5E, 0xB5, 0xD1,
318     0xEE, 0x16, 0x10, 0xDF, 0x87, 0x07, 0x95, 0x14, 0x36, 0x27, 0xD0, 0x42
319 };
320
321 static const unsigned char bp384_db[] = {
322     0x03, 0x26, 0x40, 0xBC, 0x60, 0x03, 0xC5, 0x92, 0x60, 0xF7, 0x25, 0x0C,
323     0x3D, 0xB5, 0x8C, 0xE6, 0x47, 0xF9, 0x8E, 0x12, 0x60, 0xAC, 0xCE, 0x4A,
324     0xCD, 0xA3, 0xDD, 0x86, 0x9F, 0x74, 0xE0, 0x1F, 0x8B, 0xA5, 0xE0, 0x32,
325     0x43, 0x09, 0xDB, 0x6A, 0x98, 0x31, 0x49, 0x7A, 0xBA, 0xC9, 0x66, 0x70
326 };
327
328 static const unsigned char bp384_Z[] = {
329     0x0B, 0xD9, 0xD3, 0xA7, 0xEA, 0x0B, 0x3D, 0x51, 0x9D, 0x09, 0xD8, 0xE4,
330     0x8D, 0x07, 0x85, 0xFB, 0x74, 0x4A, 0x6B, 0x35, 0x5E, 0x63, 0x04, 0xBC,
331     0x51, 0xC2, 0x29, 0xFB, 0xBC, 0xE2, 0x39, 0xBB, 0xAD, 0xF6, 0x40, 0x37,
332     0x15, 0xC3, 0x5D, 0x4F, 0xB2, 0xA5, 0x44, 0x4F, 0x57, 0x5D, 0x4F, 0x42
333 };
334
335 static const unsigned char bp512_da[] = {
336     0x16, 0x30, 0x2F, 0xF0, 0xDB, 0xBB, 0x5A, 0x8D, 0x73, 0x3D, 0xAB, 0x71,
337     0x41, 0xC1, 0xB4, 0x5A, 0xCB, 0xC8, 0x71, 0x59, 0x39, 0x67, 0x7F, 0x6A,
338     0x56, 0x85, 0x0A, 0x38, 0xBD, 0x87, 0xBD, 0x59, 0xB0, 0x9E, 0x80, 0x27,
339     0x96, 0x09, 0xFF, 0x33, 0x3E, 0xB9, 0xD4, 0xC0, 0x61, 0x23, 0x1F, 0xB2,
340     0x6F, 0x92, 0xEE, 0xB0, 0x49, 0x82, 0xA5, 0xF1, 0xD1, 0x76, 0x4C, 0xAD,
341     0x57, 0x66, 0x54, 0x22
342 };
343
344 static const unsigned char bp512_db[] = {
345     0x23, 0x0E, 0x18, 0xE1, 0xBC, 0xC8, 0x8A, 0x36, 0x2F, 0xA5, 0x4E, 0x4E,
346     0xA3, 0x90, 0x20, 0x09, 0x29, 0x2F, 0x7F, 0x80, 0x33, 0x62, 0x4F, 0xD4,
347     0x71, 0xB5, 0xD8, 0xAC, 0xE4, 0x9D, 0x12, 0xCF, 0xAB, 0xBC, 0x19, 0x96,
348     0x3D, 0xAB, 0x8E, 0x2F, 0x1E, 0xBA, 0x00, 0xBF, 0xFB, 0x29, 0xE4, 0xD7,
349     0x2D, 0x13, 0xF2, 0x22, 0x45, 0x62, 0xF4, 0x05, 0xCB, 0x80, 0x50, 0x36,
350     0x66, 0xB2, 0x54, 0x29
351 };
352
353 static const unsigned char bp512_Z[] = {
354     0xA7, 0x92, 0x70, 0x98, 0x65, 0x5F, 0x1F, 0x99, 0x76, 0xFA, 0x50, 0xA9,
355     0xD5, 0x66, 0x86, 0x5D, 0xC5, 0x30, 0x33, 0x18, 0x46, 0x38, 0x1C, 0x87,
356     0x25, 0x6B, 0xAF, 0x32, 0x26, 0x24, 0x4B, 0x76, 0xD3, 0x64, 0x03, 0xC0,
357     0x24, 0xD7, 0xBB, 0xF0, 0xAA, 0x08, 0x03, 0xEA, 0xFF, 0x40, 0x5D, 0x3D,
358     0x24, 0xF1, 0x1A, 0x9B, 0x5C, 0x0B, 0xEF, 0x67, 0x9F, 0xE1, 0x45, 0x4B,
359     0x21, 0xC4, 0xCD, 0x1F
360 };
361
362 /* Given private value and NID, create EC_KEY structure */
363
364 static EC_KEY *mk_eckey(int nid, const unsigned char *p, size_t plen)
365 {
366     int ok = 0;
367     EC_KEY *k = NULL;
368     BIGNUM *priv = NULL;
369     EC_POINT *pub = NULL;
370     const EC_GROUP *grp;
371     k = EC_KEY_new_by_curve_name(nid);
372     if (!k)
373         goto err;
374     priv = BN_bin2bn(p, plen, NULL);
375     if (!priv)
376         goto err;
377     if (!EC_KEY_set_private_key(k, priv))
378         goto err;
379     grp = EC_KEY_get0_group(k);
380     pub = EC_POINT_new(grp);
381     if (!pub)
382         goto err;
383     if (!EC_POINT_mul(grp, pub, priv, NULL, NULL, NULL))
384         goto err;
385     if (!EC_KEY_set_public_key(k, pub))
386         goto err;
387     ok = 1;
388  err:
389     BN_clear_free(priv);
390     EC_POINT_free(pub);
391     if (ok)
392         return k;
393     EC_KEY_free(k);
394     return NULL;
395 }
396
397 /*
398  * Known answer test: compute shared secret and check it matches expected
399  * value.
400  */
401
402 static int ecdh_kat(BIO *out, const char *cname, int nid,
403                     const unsigned char *k1, size_t k1_len,
404                     const unsigned char *k2, size_t k2_len,
405                     const unsigned char *Z, size_t Zlen)
406 {
407     int rv = 0;
408     EC_KEY *key1 = NULL, *key2 = NULL;
409     unsigned char *Ztmp = NULL;
410     size_t Ztmplen;
411     BIO_puts(out, "Testing ECDH shared secret with ");
412     BIO_puts(out, cname);
413     key1 = mk_eckey(nid, k1, k1_len);
414     key2 = mk_eckey(nid, k2, k2_len);
415     if (!key1 || !key2)
416         goto err;
417     Ztmplen = (EC_GROUP_get_degree(EC_KEY_get0_group(key1)) + 7) / 8;
418     if (Ztmplen != Zlen)
419         goto err;
420     Ztmp = OPENSSL_malloc(Ztmplen);
421     if (!ECDH_compute_key(Ztmp, Ztmplen,
422                           EC_KEY_get0_public_key(key2), key1, 0))
423         goto err;
424     if (memcmp(Ztmp, Z, Zlen))
425         goto err;
426     memset(Ztmp, 0, Zlen);
427     if (!ECDH_compute_key(Ztmp, Ztmplen,
428                           EC_KEY_get0_public_key(key1), key2, 0))
429         goto err;
430     if (memcmp(Ztmp, Z, Zlen))
431         goto err;
432     rv = 1;
433  err:
434     EC_KEY_free(key1);
435     EC_KEY_free(key2);
436     if (Ztmp)
437         OPENSSL_free(Ztmp);
438     if (rv)
439         BIO_puts(out, " ok\n");
440     else {
441         fprintf(stderr, "Error in ECDH routines\n");
442         ERR_print_errors_fp(stderr);
443     }
444     return rv;
445 }
446
447 # define test_ecdh_kat(bio, curve, bits) \
448         ecdh_kat(bio, curve, NID_brainpoolP##bits##r1, \
449                 bp##bits##_da, sizeof(bp##bits##_da), \
450                 bp##bits##_db, sizeof(bp##bits##_db), \
451                 bp##bits##_Z, sizeof(bp##bits##_Z))
452
453 int main(int argc, char *argv[])
454 {
455     BN_CTX *ctx = NULL;
456     int ret = 1;
457     BIO *out;
458
459     CRYPTO_malloc_debug_init();
460     CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
461     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
462
463 # ifdef OPENSSL_SYS_WIN32
464     CRYPTO_malloc_init();
465 # endif
466
467     RAND_seed(rnd_seed, sizeof rnd_seed);
468
469     out = BIO_new(BIO_s_file());
470     if (out == NULL)
471         EXIT(1);
472     BIO_set_fp(out, stdout, BIO_NOCLOSE);
473
474     if ((ctx = BN_CTX_new()) == NULL)
475         goto err;
476
477     /* NIST PRIME CURVES TESTS */
478     if (!test_ecdh_curve
479         (NID_X9_62_prime192v1, "NIST Prime-Curve P-192", ctx, out))
480         goto err;
481     if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out))
482         goto err;
483     if (!test_ecdh_curve
484         (NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out))
485         goto err;
486     if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out))
487         goto err;
488     if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out))
489         goto err;
490 # ifndef OPENSSL_NO_EC2M
491     /* NIST BINARY CURVES TESTS */
492     if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out))
493         goto err;
494     if (!test_ecdh_curve(NID_sect163r2, "NIST Binary-Curve B-163", ctx, out))
495         goto err;
496     if (!test_ecdh_curve(NID_sect233k1, "NIST Binary-Curve K-233", ctx, out))
497         goto err;
498     if (!test_ecdh_curve(NID_sect233r1, "NIST Binary-Curve B-233", ctx, out))
499         goto err;
500     if (!test_ecdh_curve(NID_sect283k1, "NIST Binary-Curve K-283", ctx, out))
501         goto err;
502     if (!test_ecdh_curve(NID_sect283r1, "NIST Binary-Curve B-283", ctx, out))
503         goto err;
504     if (!test_ecdh_curve(NID_sect409k1, "NIST Binary-Curve K-409", ctx, out))
505         goto err;
506     if (!test_ecdh_curve(NID_sect409r1, "NIST Binary-Curve B-409", ctx, out))
507         goto err;
508     if (!test_ecdh_curve(NID_sect571k1, "NIST Binary-Curve K-571", ctx, out))
509         goto err;
510     if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out))
511         goto err;
512 # endif
513     if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP256r1", 256))
514         goto err;
515     if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP384r1", 384))
516         goto err;
517     if (!test_ecdh_kat(out, "Brainpool Prime-Curve brainpoolP512r1", 512))
518         goto err;
519
520     ret = 0;
521
522  err:
523     ERR_print_errors_fp(stderr);
524     BN_CTX_free(ctx);
525     BIO_free(out);
526     CRYPTO_cleanup_all_ex_data();
527     ERR_remove_thread_state(NULL);
528     CRYPTO_mem_leaks_fp(stderr);
529     EXIT(ret);
530 }
531 #endif