1 /** 2 * Buffered Computation 3 * 4 * Copyright: 5 * (C) 1999-2007 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 12 module botan.algo_base.buf_comp; 13 14 import memutils.vector; 15 import botan.utils.get_byte; 16 import botan.utils.types; 17 18 /** 19 * This class represents any kind of computation which uses an internal 20 * state, such as hash functions or MACs 21 */ 22 interface BufferedComputation 23 { 24 public: 25 26 /** 27 * Add new input to process. 28 * 29 * Params: 30 * input = the input to process as a ubyte array 31 */ 32 final void update(in ubyte[] input) { addData(input.ptr, input.length); } 33 34 /** 35 * Add new input to process. 36 * 37 * Params: 38 * input = the input to process as a ubyte array 39 * length = of param in in bytes 40 */ 41 final void update(const(ubyte)* input, size_t length) { addData(input, length); } 42 43 /** 44 * Add new input to process. 45 * Params: 46 * input = the input to process as a reference type 47 */ 48 final void update(T, ALLOC)(auto const ref RefCounted!(Vector!(T, ALLOC)) input) 49 { 50 addData(input.ptr, input.length); 51 } 52 53 /** 54 * Add new input to process. 55 * 56 * Params: 57 * input = the input to process as a $(D Vector) 58 */ 59 final void update(T, ALLOC)(auto const ref Vector!(T, ALLOC) input) 60 { 61 addData(input.ptr, input.length); 62 } 63 64 /** 65 * Add an integer in big-endian order 66 * 67 * Params: 68 * input = the value 69 */ 70 final void updateBigEndian(T)(in T input) 71 { 72 foreach (size_t i; 0 .. T.sizeof) 73 { 74 ubyte b = get_byte(i, input); 75 addData(&b, 1); 76 } 77 } 78 79 /** 80 * Add new input to process. 81 * 82 * Params: 83 * str = The input to process as a string. 84 * 85 * Notes: Will be interpreted as a ubyte array based on the strings encoding. 86 */ 87 final void update(in string str) 88 { 89 addData(str.ptr, str.length); 90 } 91 92 /** 93 * Process a single ubyte. 94 * 95 * Params: 96 * input = the ubyte to process 97 */ 98 final void update(ubyte input) { addData(&input, 1); } 99 100 /** 101 * Complete the computation and retrieve the final result. 102 * 103 * Params: 104 * output = The ubyte array to be filled with the result. 105 * 106 * Notes: Must be of length outputLength() 107 */ 108 final void flushInto(ref ubyte[] output) 109 in { assert(output.length == outputLength); } 110 body { finalResult(output.ptr); } 111 112 /** 113 * Complete the computation and retrieve the 114 * final result. 115 * 116 * Params: 117 * output = The ubyte array to be filled with the result. 118 * 119 * Notes: Must be of length outputLength() 120 */ 121 final void flushInto(ubyte* output) { finalResult(output); } 122 123 /** 124 * Complete the computation and retrieve the final result. 125 * 126 * Returns: $(D SecureVector) holding the result 127 */ 128 final SecureVector!ubyte finished() 129 { 130 SecureVector!ubyte output = SecureVector!ubyte(outputLength()); 131 finalResult(output.ptr); 132 return output.move; 133 } 134 135 /** 136 * Update and finalize computation. Does the same as calling $(D update()) 137 * and $(D finished()) consecutively. 138 * 139 * Params: 140 * input = the input to process as a ubyte array 141 * 142 * Returns: The result of the call to $(D finished()) 143 */ 144 final SecureVector!ubyte process(in ubyte[] input) 145 { 146 addData(input.ptr, input.length); 147 return finished(); 148 } 149 150 /** 151 * Update and finalize computation. Does the same as calling $(D update()) 152 * and $(D finished()) consecutively. 153 * 154 * Params: 155 * input = the input to process as a ubyte array 156 * length = the length of the ubyte array 157 * 158 * Returns: The result of the call to $(D finished()) 159 */ 160 final SecureVector!ubyte process(const(ubyte)* input, size_t length) 161 { 162 addData(input, length); 163 return finished(); 164 } 165 166 /** 167 * Update and finalize computation. Does the same as calling $(D update()) 168 * and $(D finished()) consecutively. 169 * Params: 170 * input = the input to process 171 * 172 * Returns: The result of the call to $(D finished()) 173 */ 174 final SecureVector!ubyte process(ALLOC)(auto const ref RefCounted!(Vector!(ubyte, ALLOC), ALLOC) input) 175 { 176 addData(input.ptr, input.length); 177 return finished(); 178 } 179 180 /** 181 * Update and finalize computation. Does the same as calling $(D update()) 182 * and $(D finished()) consecutively. 183 * Params: 184 * input = the input to process 185 * 186 * Returns: The result of the call to $(D finished()) 187 */ 188 final SecureVector!ubyte process(ALLOC)(auto const ref Vector!(ubyte, ALLOC) input) 189 { 190 addData(input.ptr, input.length); 191 return finished(); 192 } 193 194 /** 195 * Update and finalize computation. Does the same as calling $(D update()) 196 * and $(D finished()) consecutively. 197 * Params: 198 * input = the input to process as a string 199 * 200 * Returns: The result of the call to $(D finished()) 201 */ 202 final SecureVector!ubyte process(in string input) 203 { 204 update(input); 205 return finished(); 206 } 207 208 final void addData(T)(in T input, size_t length) { 209 addData(cast(const(ubyte)*)input, length); 210 } 211 212 /** 213 * Returns: Length of the output of this function in bytes 214 */ 215 abstract @property size_t outputLength() const; 216 217 protected: 218 /** 219 * Add more data to the computation 220 * 221 * Params: 222 * input = is an input buffer 223 * length = is the length of input in bytes 224 */ 225 abstract void addData(const(ubyte)* input, size_t length); 226 227 /** 228 * Write the final output to out 229 * 230 * Params: 231 * output = An output buffer of size $(D outputLength()) 232 */ 233 abstract void finalResult(ubyte* output); 234 }