diff options
author | Jack Lloyd <[email protected]> | 2018-12-08 06:58:34 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-12-08 07:01:11 -0500 |
commit | 2d2488701e197b04f1ffc0275c13c672b550991f (patch) | |
tree | c0eb9e037acf33e322dd8cc0e692db92a7ca0842 /src | |
parent | 0c2da7d179bd029a6abaafb6f9b54bf5b079df52 (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.cpp | 34 | ||||
-rw-r--r-- | src/lib/hash/mdx_hash/mdx_hash.h | 5 |
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; |