1 /* 2 * Derived from Botan's Mlock Allocator 3 * 4 * This is a more advanced base allocator. 5 * 6 * (C) 2012,2014 Jack Lloyd 7 * (C) 2014-2015 Etienne Cimon 8 * (C) 2014,2015 Etienne Cimon 9 * 10 * Distributed under the terms of the Simplified BSD License (see Botan's license.txt) 11 */ 12 module memutils.cryptosafe; 13 import memutils.constants; 14 static if (HasBotan || HasCryptoSafe): 15 pragma(msg, "Enhanced memory security is enabled."); 16 17 import memutils.allocators; 18 import memutils.securepool; 19 import memutils.debugger; 20 21 final class SecureAllocator(Base : Allocator) : Allocator 22 { 23 private: 24 Base m_secondary; 25 static if (HasBotan || HasSecurePool) { 26 27 __gshared SecurePool ms_zeroise; 28 shared static this() { 29 //logDebug("Shared static this() SecurePool"); 30 if (!ms_zeroise) ms_zeroise = new SecurePool(); 31 } 32 shared static ~this() { 33 if (ms_zeroise) destroy(ms_zeroise); 34 } 35 } 36 37 public: 38 this() { 39 m_secondary = getAllocator!Base(); 40 } 41 42 void[] alloc(size_t n) 43 { 44 static if (HasBotan || HasSecurePool) { 45 //logDebug("CryptoSafe alloc ", n); 46 if (void[] p = ms_zeroise.alloc(n)) { 47 //logDebug("alloc P: ", p.length, " & ", p.ptr); 48 return p; 49 } 50 } 51 //logDebug("secondary alloc"); 52 void[] p = m_secondary.alloc(n); 53 54 //logDebug("FALLBACK alloc P: ", p.length, " & ", p.ptr); 55 return p; 56 } 57 58 void[] realloc(void[] mem, size_t n) 59 { 60 //logTrace("realloc P: ", mem.length, " & ", mem.ptr); 61 if (n <= mem.length) 62 return mem; 63 import std.c.string : memmove, memset; 64 65 static if (HasBotan || HasSecurePool) { 66 if (ms_zeroise.has(mem)) { 67 void[] p = ms_zeroise.alloc(n); 68 if (!p) 69 p = m_secondary.alloc(n); 70 memmove(p.ptr, mem.ptr, mem.length); 71 memset(mem.ptr, 0, mem.length); 72 ms_zeroise.free(mem); 73 return p; 74 } 75 } 76 77 return m_secondary.realloc(mem, n); 78 } 79 80 void free(void[] mem) 81 { 82 //logTrace("free P: ", mem.length, " & ", mem.ptr); 83 import std.c.string : memset; 84 memset(mem.ptr, 0, mem.length); 85 static if (HasBotan || HasSecurePool) 86 if (ms_zeroise.free(mem)) 87 return; 88 m_secondary.free(mem); 89 } 90 91 }