summaryrefslogtreecommitdiffstats
path: root/botan/src/hash/mdx_hash
diff options
context:
space:
mode:
Diffstat (limited to 'botan/src/hash/mdx_hash')
-rw-r--r--botan/src/hash/mdx_hash/info.txt10
-rw-r--r--botan/src/hash/mdx_hash/mdx_hash.cpp105
-rw-r--r--botan/src/hash/mdx_hash/mdx_hash.h42
3 files changed, 157 insertions, 0 deletions
diff --git a/botan/src/hash/mdx_hash/info.txt b/botan/src/hash/mdx_hash/info.txt
new file mode 100644
index 0000000..412c933
--- /dev/null
+++ b/botan/src/hash/mdx_hash/info.txt
@@ -0,0 +1,10 @@
+realname "MDx Hash Base"
+
+define MDX_HASH_FUNCTION
+
+load_on dep
+
+<add>
+mdx_hash.cpp
+mdx_hash.h
+</add>
diff --git a/botan/src/hash/mdx_hash/mdx_hash.cpp b/botan/src/hash/mdx_hash/mdx_hash.cpp
new file mode 100644
index 0000000..b630ec2
--- /dev/null
+++ b/botan/src/hash/mdx_hash/mdx_hash.cpp
@@ -0,0 +1,105 @@
+/**
+* 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(u32bit hash_len, u32bit block_len,
+ bool byte_end, bool bit_end,
+ u32bit cnt_size) :
+ HashFunction(hash_len, block_len), buffer(block_len),
+ BIG_BYTE_ENDIAN(byte_end), BIG_BIT_ENDIAN(bit_end), COUNT_SIZE(cnt_size)
+ {
+ if(COUNT_SIZE >= OUTPUT_LENGTH || COUNT_SIZE >= HASH_BLOCK_SIZE)
+ throw Invalid_Argument("MDx_HashFunction: COUNT_SIZE is too big");
+ count = position = 0;
+ }
+
+/**
+* Clear memory of sensitive data
+*/
+void MDx_HashFunction::clear() throw()
+ {
+ buffer.clear();
+ count = position = 0;
+ }
+
+/**
+* Update the hash
+*/
+void MDx_HashFunction::add_data(const byte input[], u32bit length)
+ {
+ count += length;
+
+ if(position)
+ {
+ buffer.copy(position, input, length);
+
+ if(position + length >= HASH_BLOCK_SIZE)
+ {
+ compress_n(buffer.begin(), 1);
+ input += (HASH_BLOCK_SIZE - position);
+ length -= (HASH_BLOCK_SIZE - position);
+ position = 0;
+ }
+ }
+
+ const u32bit full_blocks = length / HASH_BLOCK_SIZE;
+ const u32bit remaining = length % HASH_BLOCK_SIZE;
+
+ if(full_blocks)
+ compress_n(input, full_blocks);
+
+ buffer.copy(position, input + full_blocks * HASH_BLOCK_SIZE, remaining);
+ position += remaining;
+ }
+
+/**
+* Finalize a hash
+*/
+void MDx_HashFunction::final_result(byte output[])
+ {
+ buffer[position] = (BIG_BIT_ENDIAN ? 0x80 : 0x01);
+ for(u32bit j = position+1; j != HASH_BLOCK_SIZE; ++j)
+ buffer[j] = 0;
+
+ if(position >= HASH_BLOCK_SIZE - COUNT_SIZE)
+ {
+ compress_n(buffer, 1);
+ buffer.clear();
+ }
+
+ write_count(buffer + HASH_BLOCK_SIZE - COUNT_SIZE);
+
+ compress_n(buffer, 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");
+
+ 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/botan/src/hash/mdx_hash/mdx_hash.h b/botan/src/hash/mdx_hash/mdx_hash.h
new file mode 100644
index 0000000..0c3aa78
--- /dev/null
+++ b/botan/src/hash/mdx_hash/mdx_hash.h
@@ -0,0 +1,42 @@
+/**
+* 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:
+ MDx_HashFunction(u32bit, u32bit, bool, bool, u32bit = 8);
+ virtual ~MDx_HashFunction() {}
+ protected:
+ void add_data(const byte[], u32bit);
+ void final_result(byte output[]);
+ virtual void compress_n(const byte block[], u32bit block_n) = 0;
+
+ void clear() throw();
+ virtual void copy_out(byte[]) = 0;
+ virtual void write_count(byte[]);
+ private:
+ SecureVector<byte> buffer;
+ u64bit count;
+ u32bit position;
+
+ const bool BIG_BYTE_ENDIAN, BIG_BIT_ENDIAN;
+ const u32bit COUNT_SIZE;
+ };
+
+}
+
+#endif