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