From ba8376b59ce803a512ffef30d5daace7489a3da0 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Sat, 29 Jul 2017 19:49:26 +0200 Subject: [PATCH] Implement the CRYPTO_secure_clear_free function. Use OPENSSL_secure_clear_free for secure mem BIOs and X25519 private keys. Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/4048) --- crypto/buffer/buffer.c | 4 ++-- crypto/ec/ecx_meth.c | 2 +- crypto/mem_sec.c | 27 +++++++++++++++++++++++++++ doc/crypto/OPENSSL_secure_malloc.pod | 9 ++++++++- include/openssl/crypto.h | 4 ++++ util/libcrypto.num | 1 + 6 files changed, 43 insertions(+), 4 deletions(-) diff --git a/crypto/buffer/buffer.c b/crypto/buffer/buffer.c index ad7128a732..f3f8a1b55c 100644 --- a/crypto/buffer/buffer.c +++ b/crypto/buffer/buffer.c @@ -47,7 +47,7 @@ void BUF_MEM_free(BUF_MEM *a) if (a->data != NULL) { if (a->flags & BUF_MEM_FLAG_SECURE) - OPENSSL_secure_free(a->data); + OPENSSL_secure_clear_free(a->data, a->max); else OPENSSL_clear_free(a->data, a->max); } @@ -64,7 +64,7 @@ static char *sec_alloc_realloc(BUF_MEM *str, size_t len) if (str->data != NULL) { if (ret != NULL) { memcpy(ret, str->data, str->length); - OPENSSL_secure_free(str->data); + OPENSSL_secure_clear_free(str->data, str->length); str->data = NULL; } } diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index 06e3911340..018a9419f0 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -212,7 +212,7 @@ static void ecx_free(EVP_PKEY *pkey) X25519_KEY *xkey = pkey->pkey.ptr; if (xkey) - OPENSSL_secure_free(xkey->privkey); + OPENSSL_secure_clear_free(xkey->privkey, X25519_KEYLEN); OPENSSL_free(xkey); } diff --git a/crypto/mem_sec.c b/crypto/mem_sec.c index 664b4ad1b5..2a08b21e6d 100644 --- a/crypto/mem_sec.c +++ b/crypto/mem_sec.c @@ -156,6 +156,33 @@ void CRYPTO_secure_free(void *ptr, const char *file, int line) #endif /* IMPLEMENTED */ } +void CRYPTO_secure_clear_free(void *ptr, size_t num, + const char *file, int line) +{ +#ifdef IMPLEMENTED + size_t actual_size; + + if (ptr == NULL) + return; + if (!CRYPTO_secure_allocated(ptr)) { + OPENSSL_cleanse(ptr, num); + CRYPTO_free(ptr, file, line); + return; + } + CRYPTO_THREAD_write_lock(sec_malloc_lock); + actual_size = sh_actual_size(ptr); + CLEAR(ptr, actual_size); + secure_mem_used -= actual_size; + sh_free(ptr); + CRYPTO_THREAD_unlock(sec_malloc_lock); +#else + if (ptr == NULL) + return; + OPENSSL_cleanse(ptr, num); + CRYPTO_free(ptr, file, line); +#endif /* IMPLEMENTED */ +} + int CRYPTO_secure_allocated(const void *ptr) { #ifdef IMPLEMENTED diff --git a/doc/crypto/OPENSSL_secure_malloc.pod b/doc/crypto/OPENSSL_secure_malloc.pod index 3f49abf6fc..75b5b3c1a3 100644 --- a/doc/crypto/OPENSSL_secure_malloc.pod +++ b/doc/crypto/OPENSSL_secure_malloc.pod @@ -27,6 +27,9 @@ CRYPTO_secure_used - secure heap storage void OPENSSL_secure_free(void* ptr); void CRYPTO_secure_free(void *ptr, const char *, int); + void OPENSSL_secure_clear_free(void* ptr, size_t num); + void CRYPTO_secure_clear_free(void *ptr, size_t num, const char *, int); + size_t OPENSSL_secure_actual_size(const void *ptr); int OPENSSL_secure_allocated(const void *ptr); @@ -104,13 +107,17 @@ CRYPTO_secure_allocated() returns 1 if the pointer is in the secure heap, or 0 i CRYPTO_secure_malloc_done() returns 1 if the secure memory area is released, or 0 if not. -OPENSSL_secure_free() returns no values. +OPENSSL_secure_free() and OPENSSL_secure_clear_free() return no values. =head1 SEE ALSO L, L +=head1 HISTORY + +OPENSSL_secure_clear_free() was added in OpenSSL 1.1.0g. + =head1 COPYRIGHT Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index 55e8020a9a..1ba7f25f01 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -146,6 +146,8 @@ int CRYPTO_mem_ctrl(int mode); CRYPTO_secure_zalloc(num, OPENSSL_FILE, OPENSSL_LINE) # define OPENSSL_secure_free(addr) \ CRYPTO_secure_free(addr, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_clear_free(addr, num) \ + CRYPTO_secure_clear_free(addr, num, OPENSSL_FILE, OPENSSL_LINE) # define OPENSSL_secure_actual_size(ptr) \ CRYPTO_secure_actual_size(ptr) @@ -285,6 +287,8 @@ int CRYPTO_secure_malloc_done(void); void *CRYPTO_secure_malloc(size_t num, const char *file, int line); void *CRYPTO_secure_zalloc(size_t num, const char *file, int line); void CRYPTO_secure_free(void *ptr, const char *file, int line); +void CRYPTO_secure_clear_free(void *ptr, size_t num, + const char *file, int line); int CRYPTO_secure_allocated(const void *ptr); int CRYPTO_secure_malloc_initialized(void); size_t CRYPTO_secure_actual_size(void *ptr); diff --git a/util/libcrypto.num b/util/libcrypto.num index 814926fd19..fddb49b0ac 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4230,3 +4230,4 @@ UINT32_it 4214 1_1_0f EXIST:!EXPORT_VAR_AS_FUNCTIO UINT32_it 4214 1_1_0f EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION: ZINT64_it 4215 1_1_0f EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE: ZINT64_it 4215 1_1_0f EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION: +CRYPTO_secure_clear_free 4315 1_1_0g EXIST::FUNCTION: -- 2.25.1