1 /** 2 * Memory Operations 3 * 4 * Copyright: 5 * (C) 1999-2009,2012 Jack Lloyd 6 * (C) 2014-2015 Etienne Cimon 7 * 8 * License: 9 * Botan is released under the Simplified BSD License (see LICENSE.md) 10 */ 11 module botan.utils.mem_ops; 12 import botan.utils.types; 13 public import botan_math.mem_ops; 14 import std.algorithm : min; 15 import std.traits : isPointer; 16 17 18 Vector!T unlock(T, ALLOC)(auto const ref Vector!(T, ALLOC) input) 19 if (is(ALLOC == SecureMem)) 20 { 21 return Vector!T(input.ptr[0 .. input.length]); 22 } 23 24 RefCounted!(Vector!T) unlock(T, ALLOC)(auto const ref RefCounted!(Vector!(T, ALLOC), ALLOC) input) 25 if (is(ALLOC == SecureMem)) 26 { 27 return RefCounted!(Vector!T)(input[]); 28 } 29 30 /** 31 * Zeroise the values then free the memory 32 * Params: 33 * vec = the vector to zeroise and free 34 */ 35 void zap(T, Alloc)(ref Vector!(T, Alloc) vec) 36 { 37 import std.traits : hasIndirections; 38 static if (!hasIndirections!T && !is(Alloc == SecureMem)) 39 zeroise(vec); 40 vec.destroy(); 41 } 42 43 size_t bufferInsert(T, Alloc)(ref Vector!(T, Alloc) buf, size_t buf_offset, in T* input, size_t input_length) 44 { 45 import std.algorithm : max; 46 const size_t to_copy = min(input_length, buf.length - buf_offset); 47 buf.resize(max(buf.length, buf_offset + to_copy)); 48 copyMem(buf.ptr + buf_offset, input, to_copy); 49 return to_copy; 50 } 51 52 size_t bufferInsert(T, Alloc, Alloc2)(ref Vector!(T, Alloc) buf, size_t buf_offset, const ref Vector!(T, Alloc2) input) 53 { 54 import std.algorithm : max; 55 const size_t to_copy = min(input.length, buf.length - buf_offset); 56 buf.resize(max(buf.length, buf_offset + to_copy)); 57 copyMem(&buf[buf_offset], input.ptr, to_copy); 58 return to_copy; 59 } 60 61 pure: 62 63 /** 64 * Set memory to a fixed value 65 * Params: 66 * ptr = a pointer to an array 67 * n = the number of Ts pointed to by ptr 68 * val = the value to set each ubyte to 69 */ 70 void setMem(T)(T* ptr, size_t n, ubyte val) 71 if (!isPointer!T) 72 { 73 import core.stdc..string : memset; 74 //logDebug("memset ops: ", cast(void*)ptr, " L:", T.sizeof*n); 75 memset(ptr, val, T.sizeof*n); 76 } 77 78 /** 79 * Memory comparison, input insensitive 80 * Params: 81 * p1 = a pointer to an array 82 * p2 = a pointer to another array 83 * n = the number of Ts in p1 and p2 84 * Returns: true iff p1[i] == p2[i] forall i in [0...n$(RPAREN) 85 */ 86 bool sameMem(T)(in T* p1, in T* p2, in size_t n) 87 if (!isPointer!T) 88 { 89 return ((cast(const(ubyte)*)p1)[0 .. n] == (cast(const(ubyte)*)p2)[0 .. n]); 90 } 91 92 93 /** 94 * Zeroise the values; length remains unchanged 95 * Params: 96 * vec = the vector to zeroise 97 */ 98 void zeroise(T, Alloc)(ref Vector!(T, Alloc) vec) 99 { 100 clearMem(vec.ptr, vec.length); 101 } 102 103 void zeroise(T)(T[] mem) { 104 clearMem(mem.ptr, mem.length); 105 } 106