summaryrefslogtreecommitdiffstats
path: root/crypto/mem_sec.c
diff options
context:
space:
mode:
authorJeremiah Gowdy <jeremiah@gowdy.me>2020-10-18 14:12:35 -0700
committerPauli <paul.dale@oracle.com>2020-10-22 12:11:35 +1000
commitf31ac320012c9aa1540034288ea94f6c80924aa3 (patch)
treed2d8fe1277101793a728f2493ac34aff9b1fc16f /crypto/mem_sec.c
parent0934cf4834059cf2d6e3b7e4106d5e04f50ed7f5 (diff)
Implement OpenSSL secure memory for Windows
Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/13172)
Diffstat (limited to 'crypto/mem_sec.c')
-rw-r--r--crypto/mem_sec.c50
1 files changed, 45 insertions, 5 deletions
diff --git a/crypto/mem_sec.c b/crypto/mem_sec.c
index ddc0a370e6..ee3750725c 100644
--- a/crypto/mem_sec.c
+++ b/crypto/mem_sec.c
@@ -21,11 +21,18 @@
#include <string.h>
#ifndef OPENSSL_NO_SECURE_MEMORY
+# if defined(_WIN32)
+# include <windows.h>
+# endif
# include <stdlib.h>
# include <assert.h>
-# include <unistd.h>
+# if defined(OPENSSL_SYS_UNIX)
+# include <unistd.h>
+# endif
# include <sys/types.h>
-# include <sys/mman.h>
+# if defined(OPENSSL_SYS_UNIX)
+# include <sys/mman.h>
+# endif
# if defined(OPENSSL_SYS_LINUX)
# include <sys/syscall.h>
# if defined(SYS_mlock2)
@@ -375,6 +382,10 @@ static int sh_init(size_t size, size_t minsize)
size_t i;
size_t pgsize;
size_t aligned;
+#if defined(_WIN32)
+ DWORD flOldProtect;
+ SYSTEM_INFO systemInfo;
+#endif
memset(&sh, 0, sizeof(sh));
@@ -446,15 +457,19 @@ static int sh_init(size_t size, size_t minsize)
else
pgsize = (size_t)tmppgsize;
}
+#elif defined(_WIN32)
+ GetSystemInfo(&systemInfo);
+ pgsize = (size_t)systemInfo.dwPageSize;
#else
pgsize = PAGE_SIZE;
#endif
sh.map_size = pgsize + sh.arena_size + pgsize;
-#ifdef MAP_ANON
+#if !defined(_WIN32)
+# ifdef MAP_ANON
sh.map_result = mmap(NULL, sh.map_size,
PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-#else
+# else
{
int fd;
@@ -465,9 +480,16 @@ static int sh_init(size_t size, size_t minsize)
close(fd);
}
}
-#endif
+# endif
if (sh.map_result == MAP_FAILED)
goto err;
+#else
+ sh.map_result = VirtualAlloc(NULL, sh.map_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+
+ if (sh.map_result == NULL)
+ goto err;
+#endif
+
sh.arena = (char *)(sh.map_result + pgsize);
sh_setbit(sh.arena, 0, sh.bittable);
sh_add_to_list(&sh.freelist[0], sh.arena);
@@ -475,14 +497,24 @@ static int sh_init(size_t size, size_t minsize)
/* Now try to add guard pages and lock into memory. */
ret = 1;
+#if !defined(_WIN32)
/* Starting guard is already aligned from mmap. */
if (mprotect(sh.map_result, pgsize, PROT_NONE) < 0)
ret = 2;
+#else
+ if (VirtualProtect(sh.map_result, pgsize, PAGE_NOACCESS, &flOldProtect) == FALSE)
+ ret = 2;
+#endif
/* Ending guard page - need to round up to page boundary */
aligned = (pgsize + sh.arena_size + (pgsize - 1)) & ~(pgsize - 1);
+#if !defined(_WIN32)
if (mprotect(sh.map_result + aligned, pgsize, PROT_NONE) < 0)
ret = 2;
+#else
+ if (VirtualProtect(sh.map_result + aligned, pgsize, PAGE_NOACCESS, &flOldProtect) == FALSE)
+ ret = 2;
+#endif
#if defined(OPENSSL_SYS_LINUX) && defined(MLOCK_ONFAULT) && defined(SYS_mlock2)
if (syscall(SYS_mlock2, sh.arena, sh.arena_size, MLOCK_ONFAULT) < 0) {
@@ -493,6 +525,9 @@ static int sh_init(size_t size, size_t minsize)
ret = 2;
}
}
+#elif defined(_WIN32)
+ if (VirtualLock(sh.arena, sh.arena_size) == FALSE)
+ ret = 2;
#else
if (mlock(sh.arena, sh.arena_size) < 0)
ret = 2;
@@ -514,8 +549,13 @@ static void sh_done(void)
OPENSSL_free(sh.freelist);
OPENSSL_free(sh.bittable);
OPENSSL_free(sh.bitmalloc);
+#if !defined(_WIN32)
if (sh.map_result != MAP_FAILED && sh.map_size)
munmap(sh.map_result, sh.map_size);
+#else
+ if (sh.map_result != NULL && sh.map_size)
+ VirtualFree(sh.map_result, 0, MEM_RELEASE);
+#endif
memset(&sh, 0, sizeof(sh));
}