aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/hash/mdx_hash
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/hash/mdx_hash')
-rw-r--r--src/lib/hash/mdx_hash/info.txt3
-rw-r--r--src/lib/hash/mdx_hash/mdx_hash.cpp108
-rw-r--r--src/lib/hash/mdx_hash/mdx_hash.h68
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