diff options
author | Jack Lloyd <[email protected]> | 2016-10-28 14:14:16 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2016-10-28 14:14:16 -0400 |
commit | 8863848ad3b21ad6e2cf626b75e991484be61a9f (patch) | |
tree | 342d79736b971a14413f07a952b349f19e49c9d2 | |
parent | 9ad816a5d8d74105558640b2f37baec50d8b920f (diff) |
Add MAC::start_msg, update GMAC
GMAC needs a per-message nonce specified with `start`, and other
MACs are capable of using nonces (Skein-MAC, for instance) so move
this API up to MAC class.
Change GMAC::clone to clone the owned cipher.
-rw-r--r-- | src/lib/mac/gmac/gmac.cpp | 14 | ||||
-rw-r--r-- | src/lib/mac/gmac/gmac.h | 4 | ||||
-rw-r--r-- | src/lib/mac/mac.h | 49 | ||||
-rw-r--r-- | src/tests/test_mac.cpp | 39 |
4 files changed, 59 insertions, 47 deletions
diff --git a/src/lib/mac/gmac/gmac.cpp b/src/lib/mac/gmac/gmac.cpp index 946e22cf0..4461cf370 100644 --- a/src/lib/mac/gmac/gmac.cpp +++ b/src/lib/mac/gmac/gmac.cpp @@ -64,17 +64,7 @@ void GMAC::key_schedule(const byte key[], size_t size) m_cipher->encrypt(m_H_ad.data(), m_H.data()); } -void GMAC::start(const std::vector<byte>& nonce) - { - start(nonce.data(), nonce.size()); - } - -void GMAC::start(const secure_vector<byte>& nonce) - { - start(nonce.data(), nonce.size()); - } - -void GMAC::start(const byte nonce[], size_t nonce_len) +void GMAC::start_msg(const byte nonce[], size_t nonce_len) { secure_vector<byte> y0(GCM_BS); @@ -118,6 +108,6 @@ void GMAC::final_result(byte mac[]) MessageAuthenticationCode* GMAC::clone() const { - return new GMAC(BlockCipher::create(m_cipher->name()).release()); + return new GMAC(m_cipher->clone()); } } diff --git a/src/lib/mac/gmac/gmac.h b/src/lib/mac/gmac/gmac.h index b651c2e11..b05c5451f 100644 --- a/src/lib/mac/gmac/gmac.h +++ b/src/lib/mac/gmac/gmac.h @@ -53,7 +53,7 @@ class BOTAN_DLL GMAC : public MessageAuthenticationCode, */ void start(const std::vector<byte>& nonce); - Key_Length_Specification key_spec() const + Key_Length_Specification key_spec() const override { return m_cipher->key_spec(); } @@ -71,7 +71,7 @@ class BOTAN_DLL GMAC : public MessageAuthenticationCode, private: void add_data(const byte[], size_t) override; void final_result(byte[]) override; - void start_msg(const byte nonce[], size_t nonce_len); + void start_msg(const byte nonce[], size_t nonce_len) override; void key_schedule(const byte key[], size_t size) override; static const size_t GCM_BS = 16; diff --git a/src/lib/mac/mac.h b/src/lib/mac/mac.h index 9c3614f33..d7808c1bf 100644 --- a/src/lib/mac/mac.h +++ b/src/lib/mac/mac.h @@ -51,6 +51,55 @@ class BOTAN_DLL MessageAuthenticationCode : public Buffered_Computation, virtual ~MessageAuthenticationCode() {} /** + * Prepare for processing a message under the specified nonce + * + * Most MACs neither require nor support a nonce; for these algorithms + * calling `start_msg` is optional and calling it with anything other than + * an empty string is an error. One MAC which *requires* a per-message + * nonce be specified is GMAC. + * + * @param nonce the message nonce bytes + * @param nonce_len the size of len in bytes + * Default implementation simply rejects all non-empty nonces + * since most hash/MAC algorithms do not support randomization + */ + virtual void start_msg(const byte nonce[], size_t nonce_len) + { + BOTAN_UNUSED(nonce); + if(nonce_len > 0) + throw Invalid_IV_Length(name(), nonce_len); + } + + /** + * Begin processing a message with a nonce + * + * @param nonce the per message nonce + */ + template<typename Alloc> + void start(const std::vector<byte, Alloc>& nonce) + { + start_msg(nonce.data(), nonce.size()); + } + + /** + * Begin processing a message. + * @param nonce the per message nonce + * @param nonce_len length of nonce + */ + void start(const byte nonce[], size_t nonce_len) + { + start_msg(nonce, nonce_len); + } + + /** + * Begin processing a message. + */ + void start() + { + return start_msg(nullptr, 0); + } + + /** * Verify a MAC. * @param in the MAC to verify as a byte array * @param length the length of param in diff --git a/src/tests/test_mac.cpp b/src/tests/test_mac.cpp index 43b19b14e..33972fabc 100644 --- a/src/tests/test_mac.cpp +++ b/src/tests/test_mac.cpp @@ -11,10 +11,6 @@ #include <botan/mac.h> #endif -#if defined(BOTAN_HAS_GMAC) - #include <botan/gmac.h> -#endif - namespace Botan_Tests { namespace { @@ -60,14 +56,7 @@ class Message_Auth_Tests : public Text_Based_Test result.test_eq(provider, mac->name(), algo); mac->set_key(key); - -#if defined(BOTAN_HAS_GMAC) - // GMAC needs to set an IV - if(Botan::GMAC* gmac = dynamic_cast<Botan::GMAC*>(mac.get())) - { - gmac->start(iv); - } -#endif + mac->start(iv); mac->update(input); @@ -80,13 +69,7 @@ class Message_Auth_Tests : public Text_Based_Test // do the same to test verify_mac() mac->set_key(key); -#if defined(BOTAN_HAS_GMAC) - // GMAC needs to set an IV - if(Botan::GMAC* gmac = dynamic_cast<Botan::GMAC*>(mac.get())) - { - gmac->start(iv); - } -#endif + mac->start(iv); mac->update(input); result.test_eq(provider + " correct mac", mac->verify_mac(expected.data(), expected.size()), true); @@ -94,13 +77,8 @@ class Message_Auth_Tests : public Text_Based_Test if(input.size() > 2) { mac->set_key(key); // Poly1305 requires the re-key -#if defined(BOTAN_HAS_GMAC) - // GMAC needs to set an IV - if(Botan::GMAC* gmac = dynamic_cast<Botan::GMAC*>(mac.get())) - { - gmac->start(iv); - } -#endif + mac->start(iv); + mac->update(input[0]); mac->update(&input[1], input.size() - 2); mac->update(input[input.size()-1]); @@ -109,13 +87,8 @@ class Message_Auth_Tests : public Text_Based_Test // do the same to test verify_mac() mac->set_key(key); -#if defined(BOTAN_HAS_GMAC) - // GMAC needs to set an IV - if(Botan::GMAC* gmac = dynamic_cast<Botan::GMAC*>(mac.get())) - { - gmac->start(iv); - } -#endif + mac->start(iv); + mac->update(input[ 0 ]); mac->update(&input[ 1 ], input.size() - 2); mac->update(input[ input.size() - 1 ]); |