diff options
Diffstat (limited to 'src/lib/hash/mdx_hash')
-rw-r--r-- | src/lib/hash/mdx_hash/info.txt | 3 | ||||
-rw-r--r-- | src/lib/hash/mdx_hash/mdx_hash.cpp | 108 | ||||
-rw-r--r-- | src/lib/hash/mdx_hash/mdx_hash.h | 68 |
3 files changed, 179 insertions, 0 deletions
diff --git a/src/lib/hash/mdx_hash/info.txt b/src/lib/hash/mdx_hash/info.txt new file mode 100644 index 000000000..d9a24c621 --- /dev/null +++ b/src/lib/hash/mdx_hash/info.txt @@ -0,0 +1,3 @@ +define MDX_HASH_FUNCTION 20131128 + +load_on dep diff --git a/src/lib/hash/mdx_hash/mdx_hash.cpp b/src/lib/hash/mdx_hash/mdx_hash.cpp new file mode 100644 index 000000000..81042c1fa --- /dev/null +++ b/src/lib/hash/mdx_hash/mdx_hash.cpp @@ -0,0 +1,108 @@ +/* +* Merkle-Damgard Hash Function +* (C) 1999-2008 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/mdx_hash.h> +#include <botan/exceptn.h> +#include <botan/loadstor.h> + +namespace Botan { + +/* +* MDx_HashFunction Constructor +*/ +MDx_HashFunction::MDx_HashFunction(size_t block_len, + bool byte_end, + bool bit_end, + size_t cnt_size) : + buffer(block_len), + BIG_BYTE_ENDIAN(byte_end), + BIG_BIT_ENDIAN(bit_end), + COUNT_SIZE(cnt_size) + { + count = position = 0; + } + +/* +* Clear memory of sensitive data +*/ +void MDx_HashFunction::clear() + { + zeroise(buffer); + count = position = 0; + } + +/* +* Update the hash +*/ +void MDx_HashFunction::add_data(const byte input[], size_t length) + { + count += length; + + if(position) + { + buffer_insert(buffer, position, input, length); + + if(position + length >= buffer.size()) + { + compress_n(&buffer[0], 1); + input += (buffer.size() - position); + length -= (buffer.size() - position); + position = 0; + } + } + + const size_t full_blocks = length / buffer.size(); + const size_t remaining = length % buffer.size(); + + if(full_blocks) + compress_n(input, full_blocks); + + buffer_insert(buffer, position, input + full_blocks * buffer.size(), remaining); + position += remaining; + } + +/* +* Finalize a hash +*/ +void MDx_HashFunction::final_result(byte output[]) + { + buffer[position] = (BIG_BIT_ENDIAN ? 0x80 : 0x01); + for(size_t i = position+1; i != buffer.size(); ++i) + buffer[i] = 0; + + if(position >= buffer.size() - COUNT_SIZE) + { + compress_n(&buffer[0], 1); + zeroise(buffer); + } + + write_count(&buffer[buffer.size() - COUNT_SIZE]); + + compress_n(&buffer[0], 1); + copy_out(output); + clear(); + } + +/* +* Write the count bits to the buffer +*/ +void MDx_HashFunction::write_count(byte out[]) + { + if(COUNT_SIZE < 8) + throw Invalid_State("MDx_HashFunction::write_count: COUNT_SIZE < 8"); + if(COUNT_SIZE >= output_length() || COUNT_SIZE >= hash_block_size()) + throw Invalid_Argument("MDx_HashFunction: COUNT_SIZE is too big"); + + const u64bit bit_count = count * 8; + + if(BIG_BYTE_ENDIAN) + store_be(bit_count, out + COUNT_SIZE - 8); + else + store_le(bit_count, out + COUNT_SIZE - 8); + } + +} diff --git a/src/lib/hash/mdx_hash/mdx_hash.h b/src/lib/hash/mdx_hash/mdx_hash.h new file mode 100644 index 000000000..14d3c27a0 --- /dev/null +++ b/src/lib/hash/mdx_hash/mdx_hash.h @@ -0,0 +1,68 @@ +/* +* MDx Hash Function +* (C) 1999-2008 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_MDX_BASE_H__ +#define BOTAN_MDX_BASE_H__ + +#include <botan/hash.h> + +namespace Botan { + +/** +* MDx Hash Function Base Class +*/ +class BOTAN_DLL MDx_HashFunction : public HashFunction + { + public: + /** + * @param block_length is the number of bytes per block + * @param big_byte_endian specifies if the hash uses big-endian bytes + * @param big_bit_endian specifies if the hash uses big-endian bits + * @param counter_size specifies the size of the counter var in bytes + */ + MDx_HashFunction(size_t block_length, + bool big_byte_endian, + bool big_bit_endian, + size_t counter_size = 8); + + size_t hash_block_size() const { return buffer.size(); } + protected: + void add_data(const byte input[], size_t length); + void final_result(byte output[]); + + /** + * Run the hash's compression function over a set of blocks + * @param blocks the input + * @param block_n the number of blocks + */ + virtual void compress_n(const byte blocks[], size_t block_n) = 0; + + void clear(); + + /** + * Copy the output to the buffer + * @param buffer to put the output into + */ + virtual void copy_out(byte buffer[]) = 0; + + /** + * Write the count, if used, to this spot + * @param out where to write the counter to + */ + virtual void write_count(byte out[]); + private: + secure_vector<byte> buffer; + u64bit count; + size_t position; + + const bool BIG_BYTE_ENDIAN, BIG_BIT_ENDIAN; + const size_t COUNT_SIZE; + }; + +} + +#endif |