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