aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-12-08 06:58:34 -0500
committerJack Lloyd <[email protected]>2018-12-08 07:01:11 -0500
commit2d2488701e197b04f1ffc0275c13c672b550991f (patch)
treec0eb9e037acf33e322dd8cc0e692db92a7ca0842 /src
parent0c2da7d179bd029a6abaafb6f9b54bf5b079df52 (diff)
Require MDx_HashFunction block size to be a power of 2
Allows replacing div/mod by a variable with a shift/mask. Allows storing just the bit count, which saves a few bytes.
Diffstat (limited to 'src')
-rw-r--r--src/lib/hash/mdx_hash/mdx_hash.cpp34
-rw-r--r--src/lib/hash/mdx_hash/mdx_hash.h5
2 files changed, 25 insertions, 14 deletions
diff --git a/src/lib/hash/mdx_hash/mdx_hash.cpp b/src/lib/hash/mdx_hash/mdx_hash.cpp
index 75893d51a..64ae516a8 100644
--- a/src/lib/hash/mdx_hash/mdx_hash.cpp
+++ b/src/lib/hash/mdx_hash/mdx_hash.cpp
@@ -8,6 +8,7 @@
#include <botan/mdx_hash.h>
#include <botan/exceptn.h>
#include <botan/loadstor.h>
+#include <botan/internal/bit_ops.h>
namespace Botan {
@@ -20,13 +21,17 @@ MDx_HashFunction::MDx_HashFunction(size_t block_len,
uint8_t cnt_size) :
m_pad_char(bit_big_endian == true ? 0x80 : 0x01),
m_counter_size(cnt_size),
+ m_block_bits(ceil_log2(block_len)),
m_count_big_endian(byte_big_endian),
- m_block_len(block_len),
m_count(0),
- m_buffer(m_block_len),
+ m_buffer(block_len),
m_position(0)
{
- if(m_counter_size < 8 || m_counter_size > m_block_len)
+ if(!is_power_of_2(block_len))
+ throw Invalid_Argument("MDx_HashFunction block length must be a power of 2");
+ if(m_block_bits < 3 || m_block_bits > 16)
+ throw Invalid_Argument("MDx_HashFunction block size too large or too small");
+ if(m_counter_size < 8 || m_counter_size > block_len)
throw Invalid_State("MDx_HashFunction invalid counter length");
}
@@ -44,30 +49,33 @@ void MDx_HashFunction::clear()
*/
void MDx_HashFunction::add_data(const uint8_t input[], size_t length)
{
+ const size_t block_len = static_cast<size_t>(1) << m_block_bits;
+
m_count += length;
if(m_position)
{
buffer_insert(m_buffer, m_position, input, length);
- if(m_position + length >= m_block_len)
+ if(m_position + length >= block_len)
{
compress_n(m_buffer.data(), 1);
- input += (m_block_len - m_position);
- length -= (m_block_len - m_position);
+ input += (block_len - m_position);
+ length -= (block_len - m_position);
m_position = 0;
}
}
- const size_t full_blocks = length / m_block_len;
- const size_t remaining = length % m_block_len;
+ // Just in case the compiler can't figure out block_len is a power of 2
+ const size_t full_blocks = length >> m_block_bits;
+ const size_t remaining = length & (block_len - 1);
if(full_blocks > 0)
{
compress_n(input, full_blocks);
}
- buffer_insert(m_buffer, m_position, input + full_blocks * m_block_len, remaining);
+ buffer_insert(m_buffer, m_position, input + full_blocks * block_len, remaining);
m_position += remaining;
}
@@ -76,16 +84,18 @@ void MDx_HashFunction::add_data(const uint8_t input[], size_t length)
*/
void MDx_HashFunction::final_result(uint8_t output[])
{
- clear_mem(&m_buffer[m_position], m_block_len - m_position);
+ const size_t block_len = static_cast<size_t>(1) << m_block_bits;
+
+ clear_mem(&m_buffer[m_position], block_len - m_position);
m_buffer[m_position] = m_pad_char;
- if(m_position >= m_block_len - m_counter_size)
+ if(m_position >= block_len - m_counter_size)
{
compress_n(m_buffer.data(), 1);
zeroise(m_buffer);
}
- write_count(&m_buffer[m_block_len - m_counter_size]);
+ write_count(&m_buffer[block_len - m_counter_size]);
compress_n(m_buffer.data(), 1);
copy_out(output);
diff --git a/src/lib/hash/mdx_hash/mdx_hash.h b/src/lib/hash/mdx_hash/mdx_hash.h
index bd2752bef..b18c2e270 100644
--- a/src/lib/hash/mdx_hash/mdx_hash.h
+++ b/src/lib/hash/mdx_hash/mdx_hash.h
@@ -19,7 +19,8 @@ class BOTAN_PUBLIC_API(2,0) MDx_HashFunction : public HashFunction
{
public:
/**
- * @param block_length is the number of bytes per block
+ * @param block_length is the number of bytes per block, which must
+ * be a power of 2 and at least 8.
* @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
@@ -57,8 +58,8 @@ class BOTAN_PUBLIC_API(2,0) MDx_HashFunction : public HashFunction
private:
const uint8_t m_pad_char;
const uint8_t m_counter_size;
+ const uint8_t m_block_bits;
const bool m_count_big_endian;
- const size_t m_block_len;
uint64_t m_count;
secure_vector<uint8_t> m_buffer;