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