[openssl-commits] [openssl] master update

bernd.edlinger at hotmail.de bernd.edlinger at hotmail.de
Sat Jul 29 17:34:19 UTC 2017


The branch master has been updated
       via  8bf2d93057a8b2a9f3851b3b42065c84d1202fa9 (commit)
       via  358d446f259cd8acb13b2919bce12ed34bf6ce56 (commit)
       via  2ca8bbe55084253eb954caa440e469961b981f79 (commit)
       via  2928b29b2fdb41866671e2a62ad2127d0b5f260e (commit)
       via  5d8f1b13890df51bce97b1a4c2a31f5228bb4744 (commit)
       via  4dae7cd3f0f074e01b2fe73ffff0dfbf032fa566 (commit)
      from  0443b1171da43696a2cd67cfcb0624be1e3ee25b (commit)


- Log -----------------------------------------------------------------
commit 8bf2d93057a8b2a9f3851b3b42065c84d1202fa9
Author: Bernd Edlinger <bernd.edlinger at hotmail.de>
Date:   Sat Jul 29 17:47:43 2017 +0200

    Add some test coverage for OPENSSL_secure_clear_free
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4044)

commit 358d446f259cd8acb13b2919bce12ed34bf6ce56
Author: Bernd Edlinger <bernd.edlinger at hotmail.de>
Date:   Sat Jul 29 15:15:11 2017 +0200

    Use OPENSSL_secure_clear_free in STORE file_load
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4044)

commit 2ca8bbe55084253eb954caa440e469961b981f79
Author: Bernd Edlinger <bernd.edlinger at hotmail.de>
Date:   Sat Jul 29 14:07:25 2017 +0200

    Use OPENSSL_secure_clear_free in PEM_read_bio_PrivateKey and PEM_read_bio_ex
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4044)

commit 2928b29b2fdb41866671e2a62ad2127d0b5f260e
Author: Bernd Edlinger <bernd.edlinger at hotmail.de>
Date:   Sat Jul 29 13:07:33 2017 +0200

    Document OPENSSL_secure_clear_free
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4044)

commit 5d8f1b13890df51bce97b1a4c2a31f5228bb4744
Author: Bernd Edlinger <bernd.edlinger at hotmail.de>
Date:   Fri Jul 28 21:59:07 2017 +0200

    Use OPENSSL_secure_clear_free for secure mem BIOs and X25519 private keys
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4044)

commit 4dae7cd3f0f074e01b2fe73ffff0dfbf032fa566
Author: Bernd Edlinger <bernd.edlinger at hotmail.de>
Date:   Fri Jul 28 21:24:02 2017 +0200

    Implement the CRYPTO_secure_clear_free function
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4044)

-----------------------------------------------------------------------

Summary of changes:
 crypto/buffer/buffer.c             |  4 ++--
 crypto/ec/ecx_meth.c               |  2 +-
 crypto/mem_sec.c                   | 27 +++++++++++++++++++++++++++
 crypto/pem/pem_lib.c               | 28 ++++++++++++++--------------
 crypto/pem/pem_pkey.c              |  2 +-
 crypto/store/loader_file.c         | 10 +++++-----
 doc/man3/OPENSSL_secure_malloc.pod | 18 ++++++++++++++++--
 include/openssl/crypto.h           |  4 ++++
 test/secmemtest.c                  | 14 ++++++++++----
 util/libcrypto.num                 |  1 +
 util/private.num                   |  1 +
 11 files changed, 82 insertions(+), 29 deletions(-)

diff --git a/crypto/buffer/buffer.c b/crypto/buffer/buffer.c
index ad7128a..f3f8a1b 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 b001196..4f7cfec 100644
--- a/crypto/ec/ecx_meth.c
+++ b/crypto/ec/ecx_meth.c
@@ -220,7 +220,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 11e95c4..04aa94e 100644
--- a/crypto/mem_sec.c
+++ b/crypto/mem_sec.c
@@ -157,6 +157,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/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c
index 2a52aca..cfe2fa6 100644
--- a/crypto/pem/pem_lib.c
+++ b/crypto/pem/pem_lib.c
@@ -220,10 +220,10 @@ static int check_pem(const char *nm, const char *name)
     return 0;
 }
 
-static void pem_free(void *p, unsigned int flags)
+static void pem_free(void *p, unsigned int flags, size_t num)
 {
     if (flags & PEM_FLAG_SECURE)
-        OPENSSL_secure_free(p);
+        OPENSSL_secure_clear_free(p, num);
     else
         OPENSSL_free(p);
 }
@@ -242,13 +242,13 @@ static int pem_bytes_read_bio_flags(unsigned char **pdata, long *plen,
     EVP_CIPHER_INFO cipher;
     char *nm = NULL, *header = NULL;
     unsigned char *data = NULL;
-    long len;
+    long len = 0;
     int ret = 0;
 
     do {
-        pem_free(nm, flags);
-        pem_free(header, flags);
-        pem_free(data, flags);
+        pem_free(nm, flags, 0);
+        pem_free(header, flags, 0);
+        pem_free(data, flags, len);
         if (!PEM_read_bio_ex(bp, &nm, &header, &data, &len, flags)) {
             if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE)
                 ERR_add_error_data(2, "Expecting: ", name);
@@ -270,10 +270,10 @@ static int pem_bytes_read_bio_flags(unsigned char **pdata, long *plen,
 
  err:
     if (!ret || pnm == NULL)
-        pem_free(nm, flags);
-    pem_free(header, flags);
+        pem_free(nm, flags, 0);
+    pem_free(header, flags, 0);
     if (!ret)
-        pem_free(data, flags);
+        pem_free(data, flags, len);
     return ret;
 }
 
@@ -767,7 +767,7 @@ static int get_name(BIO *bp, char **name, unsigned int flags)
     ret = 1;
 
 err:
-    pem_free(linebuf, flags);
+    pem_free(linebuf, flags, LINESIZE + 1);
     return ret;
 }
 
@@ -875,7 +875,7 @@ static int get_header_and_data(BIO *bp, BIO **header, BIO **data, char *name,
 
     ret = 1;
 err:
-    pem_free(linebuf, flags);
+    pem_free(linebuf, flags, LINESIZE + 1);
     return ret;
 }
 
@@ -943,8 +943,8 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header,
     *header = pem_malloc(headerlen + 1, flags);
     *data = pem_malloc(len, flags);
     if (*header == NULL || *data == NULL) {
-        pem_free(*header, flags);
-        pem_free(*data, flags);
+        pem_free(*header, flags, 0);
+        pem_free(*data, flags, 0);
         goto end;
     }
     BIO_read(headerB, *header, headerlen);
@@ -957,7 +957,7 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header,
 
 end:
     EVP_ENCODE_CTX_free(ctx);
-    pem_free(name, flags);
+    pem_free(name, flags, 0);
     BIO_free(headerB);
     BIO_free(dataB);
     return ret;
diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c
index 42ec933..ffceb69 100644
--- a/crypto/pem/pem_pkey.c
+++ b/crypto/pem/pem_pkey.c
@@ -88,7 +88,7 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
         PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB);
  err:
     OPENSSL_secure_free(nm);
-    OPENSSL_secure_free(data);
+    OPENSSL_secure_clear_free(data, len);
     return (ret);
 }
 
diff --git a/crypto/store/loader_file.c b/crypto/store/loader_file.c
index ca15065..99c9350 100644
--- a/crypto/store/loader_file.c
+++ b/crypto/store/loader_file.c
@@ -1037,10 +1037,10 @@ static OSSL_STORE_INFO *file_load_try_repeat(OSSL_STORE_LOADER_CTX *ctx,
     return result;
 }
 
-static void pem_free_flag(void *pem_data, int secure)
+static void pem_free_flag(void *pem_data, int secure, size_t num)
 {
     if (secure)
-        OPENSSL_secure_free(pem_data);
+        OPENSSL_secure_clear_free(pem_data, num);
     else
         OPENSSL_free(pem_data);
 }
@@ -1243,9 +1243,9 @@ static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
                 ctx->errcnt++;
 
          endloop:
-            pem_free_flag(pem_name, (ctx->flags & FILE_FLAG_SECMEM) != 0);
-            pem_free_flag(pem_header, (ctx->flags & FILE_FLAG_SECMEM) != 0);
-            pem_free_flag(data, (ctx->flags & FILE_FLAG_SECMEM) != 0);
+            pem_free_flag(pem_name, (ctx->flags & FILE_FLAG_SECMEM) != 0, 0);
+            pem_free_flag(pem_header, (ctx->flags & FILE_FLAG_SECMEM) != 0, 0);
+            pem_free_flag(data, (ctx->flags & FILE_FLAG_SECMEM) != 0, len);
         } while (matchcount == 0 && !file_eof(ctx) && !file_error(ctx));
 
         /* We bail out on ambiguity */
diff --git a/doc/man3/OPENSSL_secure_malloc.pod b/doc/man3/OPENSSL_secure_malloc.pod
index 29df6d0..5a01c82 100644
--- a/doc/man3/OPENSSL_secure_malloc.pod
+++ b/doc/man3/OPENSSL_secure_malloc.pod
@@ -5,7 +5,8 @@
 CRYPTO_secure_malloc_init, CRYPTO_secure_malloc_initialized,
 CRYPTO_secure_malloc_done, OPENSSL_secure_malloc, CRYPTO_secure_malloc,
 OPENSSL_secure_zalloc, CRYPTO_secure_zalloc, OPENSSL_secure_free,
-CRYPTO_secure_free, OPENSSL_secure_actual_size,
+CRYPTO_secure_free, OPENSSL_secure_clear_free,
+CRYPTO_secure_clear_free, OPENSSL_secure_actual_size,
 CRYPTO_secure_used - secure heap storage
 
 =head1 SYNOPSIS
@@ -27,6 +28,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);
 
  size_t CRYPTO_secure_used();
@@ -76,6 +80,12 @@ It exists for consistency with OPENSSL_secure_malloc() , and
 is a macro that expands to CRYPTO_secure_free() and adds the C<__FILE__>
 and C<__LINE__> parameters..
 
+OPENSSL_secure_clear_free() is similar to OPENSSL_secure_free() except
+that it has an additional C<num> parameter which is used to clear
+the memory if it was not allocated from the secure heap.
+If CRYPTO_secure_malloc_init() is not called, this is equivalent to
+calling OPENSSL_clear_free().
+
 OPENSSL_secure_actual_size() tells the actual size allocated to the
 pointer; implementations may allocate more space than initially
 requested, in order to "round up" and reduce secure heap fragmentation.
@@ -101,13 +111,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<OPENSSL_malloc(3)>,
 L<BN_new(3)>
 
+=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 f0bc98f..cebde97 100644
--- a/include/openssl/crypto.h
+++ b/include/openssl/crypto.h
@@ -144,6 +144,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)
 
@@ -283,6 +285,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/test/secmemtest.c b/test/secmemtest.c
index 5592ce7..a6ccc3b 100644
--- a/test/secmemtest.c
+++ b/test/secmemtest.c
@@ -17,15 +17,20 @@ static int test_sec_mem(void)
     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 */
+    /* 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 */
+        /* r = non-secure 20, p = secure 20, s = non-secure 20 */
         || !TEST_true(CRYPTO_secure_allocated(p))
         /* 20 secure -> 32-byte minimum allocaton unit */
         || !TEST_size_t_eq(CRYPTO_secure_used(), 32))
@@ -33,9 +38,10 @@ static int test_sec_mem(void)
     q = OPENSSL_malloc(20);
     if (!TEST_ptr(q))
         goto end;
-    /* r = non-secure 20, p = secure 20, q = non-secure 20 */
+    /* 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 */
@@ -43,7 +49,7 @@ static int test_sec_mem(void)
         /* 2 * 20 secure -> 64 bytes allocated */
         || !TEST_size_t_eq(CRYPTO_secure_used(), 64))
         goto end;
-    OPENSSL_secure_free(p);
+    OPENSSL_secure_clear_free(p, 20);
     p = NULL;
     /* 20 secure -> 32 bytes allocated */
     if (!TEST_size_t_eq(CRYPTO_secure_used(), 32))
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 1c754b4..4b00b00 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4370,3 +4370,4 @@ i2d_SCRYPT_PARAMS                       4312	1_1_1	EXIST::FUNCTION:SCRYPT
 d2i_SCRYPT_PARAMS                       4313	1_1_1	EXIST::FUNCTION:SCRYPT
 SCRYPT_PARAMS_it                        4314	1_1_1	EXIST:!EXPORT_VAR_AS_FUNCTION:VARIABLE:SCRYPT
 SCRYPT_PARAMS_it                        4314	1_1_1	EXIST:EXPORT_VAR_AS_FUNCTION:FUNCTION:SCRYPT
+CRYPTO_secure_clear_free                4315	1_1_0g	EXIST::FUNCTION:
diff --git a/util/private.num b/util/private.num
index f82a8f6..a586a9b 100644
--- a/util/private.num
+++ b/util/private.num
@@ -202,6 +202,7 @@ OPENSSL_memdup                          define
 OPENSSL_no_config                       define deprecated 1.1.0
 OPENSSL_realloc                         define
 OPENSSL_secure_actual_size              define
+OPENSSL_secure_clear_free               define
 OPENSSL_secure_free                     define
 OPENSSL_secure_malloc                   define
 OPENSSL_secure_zalloc                   define


More information about the openssl-commits mailing list