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