More secure storage of key material.
[openssl.git] / crypto / mem.c
index afdce778dc03779ba050caa5e6c18b8ad960cf5c..56c358586508c2a54617b27cc728f3e2c12c28dd 100644 (file)
@@ -59,7 +59,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <openssl/crypto.h>
-#include "cryptlib.h"
+#include "internal/cryptlib.h"
 
 static int allow_customize = 1; /* we provide flexible functions for */
 static int allow_customize_debug = 1; /* exchanging memory-related functions
@@ -94,6 +94,15 @@ static void *(*realloc_ex_func) (void *, size_t, const char *file, int line)
 
 static void (*free_func) (void *) = free;
 
+static void *(*malloc_secure_func)(size_t) = malloc;
+static void *default_malloc_secure_ex(size_t num, const char *file, int line)
+{
+    return malloc_secure_func(num);
+}
+static void *(*malloc_secure_ex_func)(size_t, const char *file, int line)
+    = default_malloc_secure_ex;
+static void (*free_secure_func)(void *) = free;
+
 static void *(*malloc_locked_func) (size_t) = malloc;
 static void *default_malloc_locked_ex(size_t num, const char *file, int line)
 {
@@ -145,6 +154,11 @@ int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t),
     realloc_func = r;
     realloc_ex_func = default_realloc_ex;
     free_func = f;
+    /* If user wants to intercept the secure or locked functions, do it
+     * after the basic functions. */
+    malloc_secure_func = m;
+    malloc_secure_ex_func = default_malloc_secure_ex;
+    free_secure_func = f;
     malloc_locked_func = m;
     malloc_locked_ex_func = default_malloc_locked_ex;
     free_locked_func = f;
@@ -164,6 +178,44 @@ int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
     realloc_func = 0;
     realloc_ex_func = r;
     free_func = f;
+    malloc_secure_func = 0;
+    malloc_secure_ex_func = m;
+    free_secure_func = f;
+    malloc_locked_func = 0;
+    malloc_locked_ex_func = m;
+    free_locked_func = f;
+    return 1;
+}
+
+int CRYPTO_set_secure_mem_functions(void *(*m)(size_t), void (*f)(void *))
+{
+    /* Dummy call just to ensure OPENSSL_init() gets linked in */
+    OPENSSL_init();
+    if (!allow_customize)
+        return 0;
+    if ((m == 0) || (f == 0))
+        return 0;
+    malloc_secure_func = m;
+    malloc_secure_ex_func = default_malloc_secure_ex;
+    free_secure_func = f;
+    /* If user wants to intercept the locked functions, do it after
+     * the secure functions. */
+    malloc_locked_func = m;
+    malloc_locked_ex_func = default_malloc_secure_ex;
+    free_locked_func = f;
+    return 1;
+}
+
+int CRYPTO_set_secure_mem_ex_functions(void *(*m)(size_t, const char *, int),
+                                       void (*f)(void *))
+{
+    if (!allow_customize)
+        return 0;
+    if ((m == NULL) || (f == NULL))
+        return 0;
+    malloc_secure_func = 0;
+    malloc_secure_ex_func = m;
+    free_secure_func = f;
     malloc_locked_func = 0;
     malloc_locked_ex_func = m;
     free_locked_func = f;
@@ -191,7 +243,7 @@ int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int),
         return 0;
     malloc_locked_func = 0;
     malloc_locked_ex_func = m;
-    free_func = f;
+    free_locked_func = f;
     return 1;
 }
 
@@ -236,6 +288,25 @@ void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int),
         *f = free_func;
 }
 
+void CRYPTO_get_secure_mem_functions(void *(**m)(size_t), void (**f)(void *))
+{
+    if (m != NULL)
+        *m = (malloc_secure_ex_func == default_malloc_secure_ex) ?
+            malloc_secure_func : 0;
+    if (f != NULL)
+        *f=free_secure_func;
+       }
+
+void CRYPTO_get_secure_mem_ex_functions(void *(**m)(size_t,const char *,int),
+                                        void (**f)(void *))
+{
+    if (m != NULL)
+        *m = (malloc_secure_ex_func != default_malloc_secure_ex) ?
+            malloc_secure_ex_func : 0;
+    if (f != NULL)
+        *f=free_secure_func;
+}
+
 void CRYPTO_get_locked_mem_functions(void *(**m) (size_t),
                                      void (**f) (void *))
 {
@@ -417,8 +488,7 @@ void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file,
     ret = malloc_ex_func(num, file, line);
     if (ret) {
         memcpy(ret, str, old_len);
-        OPENSSL_cleanse(str, old_len);
-        free_func(str);
+        OPENSSL_clear_free(str, old_len);
     }
 #ifdef LEVITTE_DEBUG_MEM
     fprintf(stderr,
@@ -443,10 +513,18 @@ void CRYPTO_free(void *str)
         free_debug_func(NULL, 1);
 }
 
+void CRYPTO_clear_free(void *str, size_t num)
+{
+    if (!str)
+        return;
+    if (num)
+        OPENSSL_cleanse(str, num);
+    CRYPTO_free(str);
+}
+
 void *CRYPTO_remalloc(void *a, int num, const char *file, int line)
 {
-    if (a != NULL)
-        OPENSSL_free(a);
+    OPENSSL_free(a);
     a = OPENSSL_malloc(num);
     return (a);
 }