diff options
author | Jack Lloyd <[email protected]> | 2019-01-31 18:04:19 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2019-01-31 18:04:19 -0500 |
commit | 85321dbcc0ca97846213ef6eb245c3e1159078e2 (patch) | |
tree | e8493bc9bda7305309102ef27fa1c53552be5e2e /src/lib | |
parent | d05239be44536057c150fd5aff925ccc226b5c5a (diff) |
Minor HMAC optimizations
Most importantly, avoid an allocation when the key is larger than a
block size. Also avoid some virtual calls that can be cached.
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/mac/hmac/hmac.cpp | 42 | ||||
-rw-r--r-- | src/lib/mac/hmac/hmac.h | 4 |
2 files changed, 31 insertions, 15 deletions
diff --git a/src/lib/mac/hmac/hmac.cpp b/src/lib/mac/hmac/hmac.cpp index 72c617c5b..2552a87f5 100644 --- a/src/lib/mac/hmac/hmac.cpp +++ b/src/lib/mac/hmac/hmac.cpp @@ -27,7 +27,7 @@ void HMAC::final_result(uint8_t mac[]) verify_key_set(m_okey.empty() == false); m_hash->final(mac); m_hash->update(m_okey); - m_hash->update(mac, output_length()); + m_hash->update(mac, m_hash_output_length); m_hash->final(mac); m_hash->update(m_ikey); } @@ -38,27 +38,38 @@ Key_Length_Specification HMAC::key_spec() const return Key_Length_Specification(0, 4096); } +size_t HMAC::output_length() const + { + return m_hash_output_length; + } + /* * HMAC Key Schedule */ void HMAC::key_schedule(const uint8_t key[], size_t length) { - m_hash->clear(); - - m_ikey.resize(m_hash->hash_block_size()); - m_okey.resize(m_hash->hash_block_size()); - const uint8_t ipad = 0x36; const uint8_t opad = 0x5C; - std::fill(m_ikey.begin(), m_ikey.end(), ipad); - std::fill(m_okey.begin(), m_okey.end(), opad); + m_hash->clear(); + + m_ikey.resize(m_hash_block_size); + set_mem(m_ikey.data(), m_hash_block_size, ipad); + + m_okey.resize(m_hash_block_size); + set_mem(m_okey.data(), m_hash_block_size, opad); - if(length > m_hash->hash_block_size()) + if(length > m_hash_block_size) { - secure_vector<uint8_t> hmac_key = m_hash->process(key, length); - xor_buf(m_ikey, hmac_key, hmac_key.size()); - xor_buf(m_okey, hmac_key, hmac_key.size()); + m_hash->update(key, length); + m_hash->final(m_ikey.data()); + + xor_buf(m_okey.data(), m_ikey.data(), m_hash_output_length); + + for(size_t i = 0; i != m_hash_output_length; ++i) + { + m_ikey[i] ^= ipad; + } } else { @@ -98,9 +109,12 @@ MessageAuthenticationCode* HMAC::clone() const /* * HMAC Constructor */ -HMAC::HMAC(HashFunction* hash) : m_hash(hash) +HMAC::HMAC(HashFunction* hash) : + m_hash(hash), + m_hash_output_length(m_hash->output_length()), + m_hash_block_size(m_hash->hash_block_size()) { - BOTAN_ARG_CHECK(m_hash->hash_block_size() > 0, + BOTAN_ARG_CHECK(m_hash_block_size >= m_hash_output_length, "HMAC is not compatible with this hash function"); } diff --git a/src/lib/mac/hmac/hmac.h b/src/lib/mac/hmac/hmac.h index 800159432..1a6bcd6a0 100644 --- a/src/lib/mac/hmac/hmac.h +++ b/src/lib/mac/hmac/hmac.h @@ -23,7 +23,7 @@ class BOTAN_PUBLIC_API(2,0) HMAC final : public MessageAuthenticationCode std::string name() const override; MessageAuthenticationCode* clone() const override; - size_t output_length() const override { return m_hash->output_length(); } + size_t output_length() const override; Key_Length_Specification key_spec() const override; @@ -41,6 +41,8 @@ class BOTAN_PUBLIC_API(2,0) HMAC final : public MessageAuthenticationCode std::unique_ptr<HashFunction> m_hash; secure_vector<uint8_t> m_ikey, m_okey; + size_t m_hash_output_length; + size_t m_hash_block_size; }; } |