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 16 17 Vector!T unlock(T, ALLOC)(auto const ref Vector!(T, ALLOC) input) 18 if (is(ALLOC == SecureMem)) 19 { 20 return Vector!T(input.ptr[0 .. input.length]); 21 } 22 23 RefCounted!(Vector!T) unlock(T, ALLOC)(auto const ref RefCounted!(Vector!(T, ALLOC), ALLOC) input) 24 if (is(ALLOC == SecureMem)) 25 { 26 return RefCounted!(Vector!T)(input[]); 27 } 28 29 /** 30 * Zeroise the values then free the memory 31 * Params: 32 * vec = the vector to zeroise and free 33 */ 34 void zap(T, Alloc)(ref Vector!(T, Alloc) vec) 35 { 36 import std.traits : hasIndirections; 37 static if (!hasIndirections!T && !is(Alloc == SecureMem)) 38 zeroise(vec); 39 vec.destroy(); 40 } 41 42 size_t bufferInsert(T, Alloc)(ref Vector!(T, Alloc) buf, size_t buf_offset, in T* input, size_t input_length) 43 { 44 import std.algorithm : max; 45 const size_t to_copy = min(input_length, buf.length - buf_offset); 46 buf.resize(max(buf.length, buf_offset + to_copy)); 47 copyMem(buf.ptr + buf_offset, input, to_copy); 48 return to_copy; 49 } 50 51 size_t bufferInsert(T, Alloc, Alloc2)(ref Vector!(T, Alloc) buf, size_t buf_offset, const ref Vector!(T, Alloc2) input) 52 { 53 import std.algorithm : max; 54 const size_t to_copy = min(input.length, buf.length - buf_offset); 55 buf.resize(max(buf.length, buf_offset + to_copy)); 56 copyMem(&buf[buf_offset], input.ptr, to_copy); 57 return to_copy; 58 } 59 60 pure: 61 62 /** 63 * Set memory to a fixed value 64 * Params: 65 * ptr = a pointer to an array 66 * n = the number of Ts pointed to by ptr 67 * val = the value to set each ubyte to 68 */ 69 void setMem(T)(T* ptr, size_t n, ubyte val) 70 { 71 import core.stdc..string : memset; 72 //logDebug("memset ops: ", cast(void*)ptr, " L:", T.sizeof*n); 73 memset(ptr, val, T.sizeof*n); 74 } 75 76 /** 77 * Memory comparison, input insensitive 78 * Params: 79 * p1 = a pointer to an array 80 * p2 = a pointer to another array 81 * n = the number of Ts in p1 and p2 82 * Returns: true iff p1[i] == p2[i] forall i in [0...n$(RPAREN) 83 */ 84 bool sameMem(T)(in T* p1, in T* p2, in size_t n) 85 { 86 return ((cast(const(ubyte)*)p1)[0 .. n] == (cast(const(ubyte)*)p2)[0 .. n]); 87 } 88 89 90 /** 91 * Zeroise the values; length remains unchanged 92 * Params: 93 * vec = the vector to zeroise 94 */ 95 void zeroise(T, Alloc)(ref Vector!(T, Alloc) vec) 96 { 97 clearMem(vec.ptr, vec.length); 98 } 99 100 void zeroise(T)(T[] mem) { 101 clearMem(mem.ptr, mem.length); 102 } 103