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