]> git.ipfire.org Git - thirdparty/openssl.git/blob - providers/fips/fipsprov.c
Add fips provider code for handling self test data
[thirdparty/openssl.git] / providers / fips / fipsprov.c
1 /*
2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <string.h>
11 #include <stdio.h>
12 #include <openssl/core.h>
13 #include <openssl/core_numbers.h>
14 #include <openssl/core_names.h>
15 #include <openssl/params.h>
16 #include <openssl/err.h>
17 #include <openssl/evp.h>
18
19 /* TODO(3.0): Needed for dummy_evp_call(). To be removed */
20 #include <openssl/sha.h>
21 #include <openssl/rand_drbg.h>
22 #include <openssl/ec.h>
23 #include <openssl/fips_names.h>
24
25 #include "internal/cryptlib.h"
26 #include "internal/property.h"
27 #include "internal/evp_int.h"
28 #include "internal/provider_algs.h"
29 #include "internal/provider_ctx.h"
30 #include "internal/providercommon.h"
31 #include "selftest.h"
32
33 extern OSSL_core_thread_start_fn *c_thread_start;
34
35 /*
36 * TODO(3.0): Should these be stored in the provider side provctx? Could they
37 * ever be different from one init to the next? Unfortunately we can't do this
38 * at the moment because c_put_error/c_add_error_vdata do not provide
39 * us with the OPENSSL_CTX as a parameter.
40 */
41
42 static SELF_TEST_POST_PARAMS selftest_params;
43
44 /* Functions provided by the core */
45 static OSSL_core_gettable_params_fn *c_gettable_params;
46 static OSSL_core_get_params_fn *c_get_params;
47 OSSL_core_thread_start_fn *c_thread_start;
48 static OSSL_core_new_error_fn *c_new_error;
49 static OSSL_core_set_error_debug_fn *c_set_error_debug;
50 static OSSL_core_vset_error_fn *c_vset_error;
51 static OSSL_CRYPTO_malloc_fn *c_CRYPTO_malloc;
52 static OSSL_CRYPTO_zalloc_fn *c_CRYPTO_zalloc;
53 static OSSL_CRYPTO_free_fn *c_CRYPTO_free;
54 static OSSL_CRYPTO_clear_free_fn *c_CRYPTO_clear_free;
55 static OSSL_CRYPTO_realloc_fn *c_CRYPTO_realloc;
56 static OSSL_CRYPTO_clear_realloc_fn *c_CRYPTO_clear_realloc;
57 static OSSL_CRYPTO_secure_malloc_fn *c_CRYPTO_secure_malloc;
58 static OSSL_CRYPTO_secure_zalloc_fn *c_CRYPTO_secure_zalloc;
59 static OSSL_CRYPTO_secure_free_fn *c_CRYPTO_secure_free;
60 static OSSL_CRYPTO_secure_clear_free_fn *c_CRYPTO_secure_clear_free;
61 static OSSL_CRYPTO_secure_allocated_fn *c_CRYPTO_secure_allocated;
62
63 typedef struct fips_global_st {
64 const OSSL_PROVIDER *prov;
65 } FIPS_GLOBAL;
66
67 static void *fips_prov_ossl_ctx_new(OPENSSL_CTX *libctx)
68 {
69 FIPS_GLOBAL *fgbl = OPENSSL_zalloc(sizeof(*fgbl));
70
71 return fgbl;
72 }
73
74 static void fips_prov_ossl_ctx_free(void *fgbl)
75 {
76 OPENSSL_free(fgbl);
77 }
78
79 static const OPENSSL_CTX_METHOD fips_prov_ossl_ctx_method = {
80 fips_prov_ossl_ctx_new,
81 fips_prov_ossl_ctx_free,
82 };
83
84
85 /* Parameters we provide to the core */
86 static const OSSL_PARAM fips_param_types[] = {
87 OSSL_PARAM_DEFN(OSSL_PROV_PARAM_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0),
88 OSSL_PARAM_DEFN(OSSL_PROV_PARAM_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0),
89 OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0),
90 OSSL_PARAM_END
91 };
92
93 /*
94 * Parameters to retrieve from the core provider - required for self testing.
95 * NOTE: inside core_get_params() these will be loaded from config items
96 * stored inside prov->parameters (except for OSSL_PROV_PARAM_MODULE_FILENAME).
97 */
98 static OSSL_PARAM core_params[] =
99 {
100 OSSL_PARAM_utf8_ptr(OSSL_PROV_PARAM_MODULE_FILENAME,
101 selftest_params.module_filename,
102 sizeof(selftest_params.module_filename)),
103 OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_MODULE_MAC,
104 selftest_params.module_checksum_data,
105 sizeof(selftest_params.module_checksum_data)),
106 OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_INSTALL_MAC,
107 selftest_params.indicator_checksum_data,
108 sizeof(selftest_params.indicator_checksum_data)),
109 OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_INSTALL_STATUS,
110 selftest_params.indicator_data,
111 sizeof(selftest_params.indicator_data)),
112 OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_INSTALL_VERSION,
113 selftest_params.indicator_version,
114 sizeof(selftest_params.indicator_version)),
115 OSSL_PARAM_END
116 };
117
118 /* TODO(3.0): To be removed */
119 static int dummy_evp_call(void *provctx)
120 {
121 OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
122 EVP_MD_CTX *ctx = EVP_MD_CTX_new();
123 EVP_MD *sha256 = EVP_MD_fetch(libctx, "SHA256", NULL);
124 char msg[] = "Hello World!";
125 const unsigned char exptd[] = {
126 0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81,
127 0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28,
128 0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69
129 };
130 unsigned int dgstlen = 0;
131 unsigned char dgst[SHA256_DIGEST_LENGTH];
132 int ret = 0;
133 BN_CTX *bnctx = NULL;
134 BIGNUM *a = NULL, *b = NULL;
135 unsigned char randbuf[128];
136 RAND_DRBG *drbg = OPENSSL_CTX_get0_public_drbg(libctx);
137 #ifndef OPENSSL_NO_EC
138 EC_KEY *key = NULL;
139 #endif
140
141 if (ctx == NULL || sha256 == NULL || drbg == NULL)
142 goto err;
143
144 if (!EVP_DigestInit_ex(ctx, sha256, NULL))
145 goto err;
146 if (!EVP_DigestUpdate(ctx, msg, sizeof(msg) - 1))
147 goto err;
148 if (!EVP_DigestFinal(ctx, dgst, &dgstlen))
149 goto err;
150 if (dgstlen != sizeof(exptd) || memcmp(dgst, exptd, sizeof(exptd)) != 0)
151 goto err;
152
153 bnctx = BN_CTX_new_ex(libctx);
154 if (bnctx == NULL)
155 goto err;
156 BN_CTX_start(bnctx);
157 a = BN_CTX_get(bnctx);
158 b = BN_CTX_get(bnctx);
159 if (b == NULL)
160 goto err;
161 BN_zero(a);
162 if (!BN_one(b)
163 || !BN_add(a, a, b)
164 || BN_cmp(a, b) != 0)
165 goto err;
166
167 if (RAND_DRBG_bytes(drbg, randbuf, sizeof(randbuf)) <= 0)
168 goto err;
169
170 if (!BN_rand_ex(a, 256, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, bnctx))
171 goto err;
172
173 #ifndef OPENSSL_NO_EC
174 /* Do some dummy EC calls */
175 key = EC_KEY_new_by_curve_name_ex(libctx, NID_X9_62_prime256v1);
176 if (key == NULL)
177 goto err;
178
179 if (!EC_KEY_generate_key(key))
180 goto err;
181 #endif
182
183 ret = 1;
184 err:
185 BN_CTX_end(bnctx);
186 BN_CTX_free(bnctx);
187
188 EVP_MD_CTX_free(ctx);
189 EVP_MD_meth_free(sha256);
190
191 #ifndef OPENSSL_NO_EC
192 EC_KEY_free(key);
193 #endif
194 return ret;
195 }
196
197 static const OSSL_PARAM *fips_gettable_params(const OSSL_PROVIDER *prov)
198 {
199 return fips_param_types;
200 }
201
202 static int fips_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
203 {
204 OSSL_PARAM *p;
205
206 p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME);
207 if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "OpenSSL FIPS Provider"))
208 return 0;
209 p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_VERSION);
210 if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR))
211 return 0;
212 p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO);
213 if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_FULL_VERSION_STR))
214 return 0;
215
216 return 1;
217 }
218
219 /* FIPS specific version of the function of the same name in provlib.c */
220 const char *ossl_prov_util_nid_to_name(int nid)
221 {
222 /* We don't have OBJ_nid2n() in FIPS_MODE so we have an explicit list */
223
224 switch (nid) {
225 /* Digests */
226 case NID_sha1:
227 return "SHA224";
228 case NID_sha224:
229 return "SHA224";
230 case NID_sha256:
231 return "SHA256";
232 case NID_sha384:
233 return "SHA384";
234 case NID_sha512:
235 return "SHA512";
236 case NID_sha512_224:
237 return "SHA512-224";
238 case NID_sha512_256:
239 return "SHA512-256";
240 case NID_sha3_224:
241 return "SHA3-224";
242 case NID_sha3_256:
243 return "SHA3-256";
244 case NID_sha3_384:
245 return "SHA3-384";
246 case NID_sha3_512:
247 return "SHA3-512";
248
249 /* Ciphers */
250 case NID_aes_256_ecb:
251 return "AES-256-ECB";
252 case NID_aes_192_ecb:
253 return "AES-192-ECB";
254 case NID_aes_128_ecb:
255 return "AES-128-ECB";
256 case NID_aes_256_cbc:
257 return "AES-256-CBC";
258 case NID_aes_192_cbc:
259 return "AES-192-CBC";
260 case NID_aes_128_cbc:
261 return "AES-128-CBC";
262 case NID_aes_256_ctr:
263 return "AES-256-CTR";
264 case NID_aes_192_ctr:
265 return "AES-192-CTR";
266 case NID_aes_128_ctr:
267 return "AES-128-CTR";
268 }
269
270 return NULL;
271 }
272
273 static const OSSL_ALGORITHM fips_digests[] = {
274 { "SHA1", "fips=yes", sha1_functions },
275 { "SHA224", "fips=yes", sha224_functions },
276 { "SHA256", "fips=yes", sha256_functions },
277 { "SHA384", "fips=yes", sha384_functions },
278 { "SHA512", "fips=yes", sha512_functions },
279 { "SHA512-224", "fips=yes", sha512_224_functions },
280 { "SHA512-256", "fips=yes", sha512_256_functions },
281 { "SHA3-224", "fips=yes", sha3_224_functions },
282 { "SHA3-256", "fips=yes", sha3_256_functions },
283 { "SHA3-384", "fips=yes", sha3_384_functions },
284 { "SHA3-512", "fips=yes", sha3_512_functions },
285 /*
286 * KECCAK_KMAC128 and KECCAK_KMAC256 as hashes are mostly useful for
287 * the KMAC128 and KMAC256.
288 */
289 { "KECCAK_KMAC128", "fips=yes", keccak_kmac_128_functions },
290 { "KECCAK_KMAC256", "fips=yes", keccak_kmac_256_functions },
291
292 { NULL, NULL, NULL }
293 };
294
295 static const OSSL_ALGORITHM fips_ciphers[] = {
296 { "AES-256-ECB", "fips=yes", aes256ecb_functions },
297 { "AES-192-ECB", "fips=yes", aes192ecb_functions },
298 { "AES-128-ECB", "fips=yes", aes128ecb_functions },
299 { "AES-256-CBC", "fips=yes", aes256cbc_functions },
300 { "AES-192-CBC", "fips=yes", aes192cbc_functions },
301 { "AES-128-CBC", "fips=yes", aes128cbc_functions },
302 { "AES-256-CTR", "fips=yes", aes256ctr_functions },
303 { "AES-192-CTR", "fips=yes", aes192ctr_functions },
304 { "AES-128-CTR", "fips=yes", aes128ctr_functions },
305 { "id-aes256-GCM", "fips=yes", aes256gcm_functions },
306 { "id-aes192-GCM", "fips=yes", aes192gcm_functions },
307 { "id-aes128-GCM", "fips=yes", aes128gcm_functions },
308 { NULL, NULL, NULL }
309 };
310
311 static const OSSL_ALGORITHM fips_macs[] = {
312 { "CMAC", "fips=yes", cmac_functions },
313 { "GMAC", "fips=yes", gmac_functions },
314 { "HMAC", "fips=yes", hmac_functions },
315 { "KMAC128", "fips=yes", kmac128_functions },
316 { "KMAC256", "fips=yes", kmac256_functions },
317 { NULL, NULL, NULL }
318 };
319
320 static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov,
321 int operation_id,
322 int *no_cache)
323 {
324 *no_cache = 0;
325 switch (operation_id) {
326 case OSSL_OP_DIGEST:
327 return fips_digests;
328 case OSSL_OP_CIPHER:
329 return fips_ciphers;
330 case OSSL_OP_MAC:
331 return fips_macs;
332 }
333 return NULL;
334 }
335
336 /* Functions we provide to the core */
337 static const OSSL_DISPATCH fips_dispatch_table[] = {
338 /*
339 * To release our resources we just need to free the OPENSSL_CTX so we just
340 * use OPENSSL_CTX_free directly as our teardown function
341 */
342 { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))OPENSSL_CTX_free },
343 { OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))fips_gettable_params },
344 { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))fips_get_params },
345 { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query },
346 { 0, NULL }
347 };
348
349 /* Functions we provide to ourself */
350 static const OSSL_DISPATCH intern_dispatch_table[] = {
351 { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query },
352 { 0, NULL }
353 };
354
355
356 int OSSL_provider_init(const OSSL_PROVIDER *provider,
357 const OSSL_DISPATCH *in,
358 const OSSL_DISPATCH **out,
359 void **provctx)
360 {
361 FIPS_GLOBAL *fgbl;
362 OPENSSL_CTX *ctx;
363
364 for (; in->function_id != 0; in++) {
365 switch (in->function_id) {
366 case OSSL_FUNC_CORE_GETTABLE_PARAMS:
367 c_gettable_params = OSSL_get_core_gettable_params(in);
368 break;
369 case OSSL_FUNC_CORE_GET_PARAMS:
370 c_get_params = OSSL_get_core_get_params(in);
371 break;
372 case OSSL_FUNC_CORE_THREAD_START:
373 c_thread_start = OSSL_get_core_thread_start(in);
374 break;
375 case OSSL_FUNC_CORE_NEW_ERROR:
376 c_new_error = OSSL_get_core_new_error(in);
377 break;
378 case OSSL_FUNC_CORE_SET_ERROR_DEBUG:
379 c_set_error_debug = OSSL_get_core_set_error_debug(in);
380 break;
381 case OSSL_FUNC_CORE_VSET_ERROR:
382 c_vset_error = OSSL_get_core_vset_error(in);
383 break;
384 case OSSL_FUNC_CRYPTO_MALLOC:
385 c_CRYPTO_malloc = OSSL_get_CRYPTO_malloc(in);
386 break;
387 case OSSL_FUNC_CRYPTO_ZALLOC:
388 c_CRYPTO_zalloc = OSSL_get_CRYPTO_zalloc(in);
389 break;
390 case OSSL_FUNC_CRYPTO_FREE:
391 c_CRYPTO_free = OSSL_get_CRYPTO_free(in);
392 break;
393 case OSSL_FUNC_CRYPTO_CLEAR_FREE:
394 c_CRYPTO_clear_free = OSSL_get_CRYPTO_clear_free(in);
395 break;
396 case OSSL_FUNC_CRYPTO_REALLOC:
397 c_CRYPTO_realloc = OSSL_get_CRYPTO_realloc(in);
398 break;
399 case OSSL_FUNC_CRYPTO_CLEAR_REALLOC:
400 c_CRYPTO_clear_realloc = OSSL_get_CRYPTO_clear_realloc(in);
401 break;
402 case OSSL_FUNC_CRYPTO_SECURE_MALLOC:
403 c_CRYPTO_secure_malloc = OSSL_get_CRYPTO_secure_malloc(in);
404 break;
405 case OSSL_FUNC_CRYPTO_SECURE_ZALLOC:
406 c_CRYPTO_secure_zalloc = OSSL_get_CRYPTO_secure_zalloc(in);
407 break;
408 case OSSL_FUNC_CRYPTO_SECURE_FREE:
409 c_CRYPTO_secure_free = OSSL_get_CRYPTO_secure_free(in);
410 break;
411 case OSSL_FUNC_CRYPTO_SECURE_CLEAR_FREE:
412 c_CRYPTO_secure_clear_free = OSSL_get_CRYPTO_secure_clear_free(in);
413 break;
414 case OSSL_FUNC_CRYPTO_SECURE_ALLOCATED:
415 c_CRYPTO_secure_allocated = OSSL_get_CRYPTO_secure_allocated(in);
416 break;
417 case OSSL_FUNC_BIO_NEW_FILE:
418 selftest_params.bio_new_file_cb = OSSL_get_BIO_new_file(in);
419 break;
420 case OSSL_FUNC_BIO_NEW_MEMBUF:
421 selftest_params.bio_new_buffer_cb = OSSL_get_BIO_new_membuf(in);
422 break;
423 case OSSL_FUNC_BIO_READ:
424 selftest_params.bio_read_cb = OSSL_get_BIO_read(in);
425 break;
426 case OSSL_FUNC_BIO_FREE:
427 selftest_params.bio_free_cb = OSSL_get_BIO_free(in);
428 break;
429 default:
430 /* Just ignore anything we don't understand */
431 break;
432 }
433 }
434
435 if (!c_get_params(provider, core_params))
436 return 0;
437
438 /* Create a context. */
439 if ((ctx = OPENSSL_CTX_new()) == NULL)
440 return 0;
441 if ((fgbl = openssl_ctx_get_data(ctx, OPENSSL_CTX_FIPS_PROV_INDEX,
442 &fips_prov_ossl_ctx_method)) == NULL) {
443 OPENSSL_CTX_free(ctx);
444 return 0;
445 }
446 fgbl->prov = provider;
447 *out = fips_dispatch_table;
448 *provctx = ctx;
449
450 /*
451 * TODO(3.0): Remove me. This is just a dummy call to demonstrate making
452 * EVP calls from within the FIPS module.
453 */
454 if (!dummy_evp_call(*provctx)) {
455 OPENSSL_CTX_free(*provctx);
456 *provctx = NULL;
457 return 0;
458 }
459
460 return 1;
461 }
462
463 /*
464 * The internal init function used when the FIPS module uses EVP to call
465 * another algorithm also in the FIPS module. This is a recursive call that has
466 * been made from within the FIPS module itself. To make this work, we populate
467 * the provider context of this inner instance with the same library context
468 * that was used in the EVP call that initiated this recursive call.
469 */
470 OSSL_provider_init_fn fips_intern_provider_init;
471 int fips_intern_provider_init(const OSSL_PROVIDER *provider,
472 const OSSL_DISPATCH *in,
473 const OSSL_DISPATCH **out,
474 void **provctx)
475 {
476 OSSL_core_get_library_context_fn *c_get_libctx = NULL;
477
478 for (; in->function_id != 0; in++) {
479 switch (in->function_id) {
480 case OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT:
481 c_get_libctx = OSSL_get_core_get_library_context(in);
482 break;
483 default:
484 break;
485 }
486 }
487
488 if (c_get_libctx == NULL)
489 return 0;
490
491 *provctx = c_get_libctx(provider);
492
493 /*
494 * Safety measure... we should get the library context that was
495 * created up in OSSL_provider_init().
496 */
497 if (*provctx == NULL)
498 return 0;
499
500 *out = intern_dispatch_table;
501 return 1;
502 }
503
504 void ERR_new(void)
505 {
506 c_new_error(NULL);
507 }
508
509 void ERR_set_debug(const char *file, int line, const char *func)
510 {
511 c_set_error_debug(NULL, file, line, func);
512 }
513
514 void ERR_set_error(int lib, int reason, const char *fmt, ...)
515 {
516 va_list args;
517
518 va_start(args, fmt);
519 c_vset_error(NULL, ERR_PACK(lib, 0, reason), fmt, args);
520 va_end(args);
521 }
522
523 void ERR_vset_error(int lib, int reason, const char *fmt, va_list args)
524 {
525 c_vset_error(NULL, ERR_PACK(lib, 0, reason), fmt, args);
526 }
527
528 const OSSL_PROVIDER *FIPS_get_provider(OPENSSL_CTX *ctx)
529 {
530 FIPS_GLOBAL *fgbl = openssl_ctx_get_data(ctx, OPENSSL_CTX_FIPS_PROV_INDEX,
531 &fips_prov_ossl_ctx_method);
532
533 if (fgbl == NULL)
534 return NULL;
535
536 return fgbl->prov;
537 }
538
539 void *CRYPTO_malloc(size_t num, const char *file, int line)
540 {
541 return c_CRYPTO_malloc(num, file, line);
542 }
543
544 void *CRYPTO_zalloc(size_t num, const char *file, int line)
545 {
546 return c_CRYPTO_zalloc(num, file, line);
547 }
548
549 void CRYPTO_free(void *ptr, const char *file, int line)
550 {
551 c_CRYPTO_free(ptr, file, line);
552 }
553
554 void CRYPTO_clear_free(void *ptr, size_t num, const char *file, int line)
555 {
556 c_CRYPTO_clear_free(ptr, num, file, line);
557 }
558
559 void *CRYPTO_realloc(void *addr, size_t num, const char *file, int line)
560 {
561 return c_CRYPTO_realloc(addr, num, file, line);
562 }
563
564 void *CRYPTO_clear_realloc(void *addr, size_t old_num, size_t num,
565 const char *file, int line)
566 {
567 return c_CRYPTO_clear_realloc(addr, old_num, num, file, line);
568 }
569
570 void *CRYPTO_secure_malloc(size_t num, const char *file, int line)
571 {
572 return c_CRYPTO_secure_malloc(num, file, line);
573 }
574
575 void *CRYPTO_secure_zalloc(size_t num, const char *file, int line)
576 {
577 return c_CRYPTO_secure_zalloc(num, file, line);
578 }
579
580 void CRYPTO_secure_free(void *ptr, const char *file, int line)
581 {
582 c_CRYPTO_secure_free(ptr, file, line);
583 }
584
585 void CRYPTO_secure_clear_free(void *ptr, size_t num, const char *file, int line)
586 {
587 c_CRYPTO_secure_clear_free(ptr, num, file, line);
588 }
589
590 int CRYPTO_secure_allocated(const void *ptr)
591 {
592 return c_CRYPTO_secure_allocated(ptr);
593 }