static void pem_free_flag(void *pem_data, int secure, size_t num) { if (secure) OPENSSL_secure_clear_free(pem_data, num); else OPENSSL_free(pem_data); }
static void pem_free(void *p, unsigned int flags, size_t num) { if (flags & PEM_FLAG_SECURE) OPENSSL_secure_clear_free(p, num); else OPENSSL_free(p); }
/* * Generates |outlen| random bytes and stores them in |out|. It will * using the given |drbg| to generate the bytes. * * Requires that drbg->lock is already locked for write, if non-null. * * Returns 1 on success 0 on failure. */ int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen) { unsigned char *additional = NULL; size_t additional_len; size_t chunk; size_t ret; additional_len = rand_drbg_get_additional_data(&additional, drbg->max_adinlen); for ( ; outlen > 0; outlen -= chunk, out += chunk) { chunk = outlen; if (chunk > drbg->max_request) chunk = drbg->max_request; ret = RAND_DRBG_generate(drbg, out, chunk, 0, additional, additional_len); if (!ret) goto err; } ret = 1; err: if (additional_len != 0) OPENSSL_secure_clear_free(additional, additional_len); return ret; }
void drbg_release_entropy(RAND_DRBG *drbg, unsigned char *out, size_t outlen) { if (drbg->secure) OPENSSL_secure_clear_free(out, outlen); else OPENSSL_clear_free(out, outlen); }
/* * Free |pool|, securely erasing its buffer. */ void RAND_POOL_free(RAND_POOL *pool) { if (pool == NULL) return; OPENSSL_secure_clear_free(pool->buffer, pool->max_len); OPENSSL_free(pool); }
/* Cleans up the given global DRBG */ static void drbg_cleanup(RAND_DRBG *drbg) { if (drbg != NULL) { RAND_DRBG_uninstantiate(drbg); CRYPTO_THREAD_lock_free(drbg->lock); OPENSSL_secure_clear_free(drbg, sizeof(RAND_DRBG)); } }
static void free_drbg(RAND_DRBG *drbg) { CRYPTO_THREAD_lock_free(drbg->lock); if (drbg->secure) OPENSSL_secure_clear_free(drbg->randomness, drbg->size); else OPENSSL_clear_free(drbg->randomness, drbg->size); RAND_DRBG_uninstantiate(drbg); }
void drbg_release_entropy(RAND_DRBG *drbg, unsigned char *out) { drbg->filled = 0; if (drbg->secure) OPENSSL_secure_clear_free(drbg->randomness, drbg->size); else OPENSSL_clear_free(drbg->randomness, drbg->size); drbg->randomness = NULL; }
/* * Uninstantiate |drbg| and free all memory. */ void RAND_DRBG_free(RAND_DRBG *drbg) { if (drbg == NULL) return; if (drbg->meth != NULL) drbg->meth->uninstantiate(drbg); CRYPTO_THREAD_lock_free(drbg->lock); CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data); if (drbg->secure) OPENSSL_secure_clear_free(drbg, sizeof(*drbg)); else OPENSSL_clear_free(drbg, sizeof(*drbg)); }
void rand_cleanup_int(void) { const RAND_METHOD *meth = default_RAND_meth; if (meth != NULL && meth->cleanup != NULL) meth->cleanup(); RAND_set_rand_method(NULL); #ifndef OPENSSL_NO_ENGINE CRYPTO_THREAD_lock_free(rand_engine_lock); #endif CRYPTO_THREAD_lock_free(rand_meth_lock); CRYPTO_THREAD_lock_free(rand_bytes.lock); if (rand_bytes.secure) OPENSSL_secure_clear_free(rand_bytes.buff, rand_bytes.size); else OPENSSL_clear_free(rand_bytes.buff, rand_bytes.size); }
static int test_sec_mem(void) { #if defined(OPENSSL_SYS_LINUX) || defined(OPENSSL_SYS_UNIX) int testresult = 0; char *p = NULL, *q = NULL, *r = NULL, *s = NULL; s = OPENSSL_secure_malloc(20); /* s = non-secure 20 */ if (!TEST_ptr(s) || !TEST_false(CRYPTO_secure_allocated(s))) goto end; r = OPENSSL_secure_malloc(20); /* r = non-secure 20, s = non-secure 20 */ if (!TEST_ptr(r) || !TEST_true(CRYPTO_secure_malloc_init(4096, 32)) || !TEST_false(CRYPTO_secure_allocated(r))) goto end; p = OPENSSL_secure_malloc(20); if (!TEST_ptr(p) /* r = non-secure 20, p = secure 20, s = non-secure 20 */ || !TEST_true(CRYPTO_secure_allocated(p)) /* 20 secure -> 32-byte minimum allocation unit */ || !TEST_size_t_eq(CRYPTO_secure_used(), 32)) goto end; q = OPENSSL_malloc(20); if (!TEST_ptr(q)) goto end; /* r = non-secure 20, p = secure 20, q = non-secure 20, s = non-secure 20 */ if (!TEST_false(CRYPTO_secure_allocated(q))) goto end; OPENSSL_secure_clear_free(s, 20); s = OPENSSL_secure_malloc(20); if (!TEST_ptr(s) /* r = non-secure 20, p = secure 20, q = non-secure 20, s = secure 20 */ || !TEST_true(CRYPTO_secure_allocated(s)) /* 2 * 20 secure -> 64 bytes allocated */ || !TEST_size_t_eq(CRYPTO_secure_used(), 64)) goto end; OPENSSL_secure_clear_free(p, 20); p = NULL; /* 20 secure -> 32 bytes allocated */ if (!TEST_size_t_eq(CRYPTO_secure_used(), 32)) goto end; OPENSSL_free(q); q = NULL; /* should not complete, as secure memory is still allocated */ if (!TEST_false(CRYPTO_secure_malloc_done()) || !TEST_true(CRYPTO_secure_malloc_initialized())) goto end; OPENSSL_secure_free(s); s = NULL; /* secure memory should now be 0, so done should complete */ if (!TEST_size_t_eq(CRYPTO_secure_used(), 0) || !TEST_true(CRYPTO_secure_malloc_done()) || !TEST_false(CRYPTO_secure_malloc_initialized())) goto end; TEST_info("Possible infinite loop: allocate more than available"); if (!TEST_true(CRYPTO_secure_malloc_init(32768, 16))) goto end; TEST_ptr_null(OPENSSL_secure_malloc((size_t)-1)); TEST_true(CRYPTO_secure_malloc_done()); /* * If init fails, then initialized should be false, if not, this * could cause an infinite loop secure_malloc, but we don't test it */ if (TEST_false(CRYPTO_secure_malloc_init(16, 16)) && !TEST_false(CRYPTO_secure_malloc_initialized())) { TEST_true(CRYPTO_secure_malloc_done()); goto end; } /*- * There was also a possible infinite loop when the number of * elements was 1<<31, as |int i| was set to that, which is a * negative number. However, it requires minimum input values: * * CRYPTO_secure_malloc_init((size_t)1<<34, (size_t)1<<4); * * Which really only works on 64-bit systems, since it took 16 GB * secure memory arena to trigger the problem. It naturally takes * corresponding amount of available virtual and physical memory * for test to be feasible/representative. Since we can't assume * that every system is equipped with that much memory, the test * remains disabled. If the reader of this comment really wants * to make sure that infinite loop is fixed, they can enable the * code below. */ # if 0 /*- * On Linux and BSD this test has a chance to complete in minimal * time and with minimum side effects, because mlock is likely to * fail because of RLIMIT_MEMLOCK, which is customarily [much] * smaller than 16GB. In other words Linux and BSD users can be * limited by virtual space alone... */ if (sizeof(size_t) > 4) { TEST_info("Possible infinite loop: 1<<31 limit"); if (TEST_true(CRYPTO_secure_malloc_init((size_t)1<<34, (size_t)1<<4) != 0)) TEST_true(CRYPTO_secure_malloc_done()); } # endif /* this can complete - it was not really secure */ testresult = 1; end: OPENSSL_secure_free(p); OPENSSL_free(q); OPENSSL_secure_free(r); OPENSSL_secure_free(s); return testresult; #else /* Should fail. */ return TEST_false(CRYPTO_secure_malloc_init(4096, 32)); #endif }
/* * Implements the cleanup_entropy() callback (see RAND_DRBG_set_callbacks()) * */ void rand_drbg_cleanup_entropy(RAND_DRBG *drbg, unsigned char *out, size_t outlen) { OPENSSL_secure_clear_free(out, outlen); }
static void ecx_free(EVP_PKEY *pkey) { if (pkey->pkey.ecx != NULL) OPENSSL_secure_clear_free(pkey->pkey.ecx->privkey, KEYLEN(pkey)); OPENSSL_free(pkey->pkey.ecx); }