diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/mac/gmac/gmac.cpp | 76 | ||||
-rw-r--r-- | src/lib/mac/gmac/gmac.h | 77 | ||||
-rw-r--r-- | src/lib/mac/gmac/info.txt | 6 | ||||
-rw-r--r-- | src/lib/mac/mac.cpp | 4 | ||||
-rw-r--r-- | src/lib/mac/mac.h | 22 | ||||
-rw-r--r-- | src/lib/modes/aead/gcm/gcm.cpp | 4 | ||||
-rw-r--r-- | src/lib/modes/aead/gcm/gcm.h | 99 |
7 files changed, 238 insertions, 50 deletions
diff --git a/src/lib/mac/gmac/gmac.cpp b/src/lib/mac/gmac/gmac.cpp new file mode 100644 index 000000000..5d82456ae --- /dev/null +++ b/src/lib/mac/gmac/gmac.cpp @@ -0,0 +1,76 @@ +/* + * GMAC + * (C) 2016 Matthias Gierlings, René Korthaus + * + * Botan is released under the Simplified BSD License (see license.txt) + */ + +#include <botan/gmac.h> + +namespace Botan { + +GMAC* GMAC::make(const Spec& spec) + { + if(spec.arg_count() == 1) + { + if(auto bc = BlockCipher::create(spec.arg(0))) + return new GMAC(bc.release()); + } + return nullptr; + } + +GMAC::GMAC(BlockCipher* cipher) + : m_iv(), m_aad(), + m_gcm(GCM_Encryption(cipher)), m_cipher(cipher->clone()) + { + } + +void GMAC::clear() + { + m_gcm.clear(); + zeroise(m_iv); + zeroise(m_aad); + } + +std::string GMAC::name() const + { + return "GMAC(" + m_cipher->name() + ")"; + } + +size_t GMAC::output_length() const + { + return m_gcm.tag_size(); + } + +void GMAC::add_data(const byte input[], size_t length) + { + m_aad.insert(m_aad.end(), input, input + length); + } + +void GMAC::start(const std::vector<byte>& nonce) + { + m_iv.assign(nonce.begin(), nonce.end()); + } + +void GMAC::start(const secure_vector<byte>& nonce) + { + m_iv.assign(nonce.begin(), nonce.end()); + } + +void GMAC::final_result(byte mac[]) + { + secure_vector<byte> result; + m_gcm.set_associated_data(m_aad.data(), m_aad.size()); + m_gcm.start(m_iv); + m_gcm.finish(result); + std::copy(result.begin(), result.end(), mac); + + zeroise(m_aad); + m_aad.clear(); + } + +MessageAuthenticationCode* GMAC::clone() const + { + return new GMAC(m_cipher->clone()); + } +} diff --git a/src/lib/mac/gmac/gmac.h b/src/lib/mac/gmac/gmac.h new file mode 100644 index 000000000..d83236b32 --- /dev/null +++ b/src/lib/mac/gmac/gmac.h @@ -0,0 +1,77 @@ +/* + * GMAC + * (C) 2016 Matthias Gierlings, René Korthaus + * + * Botan is released under the Simplified BSD License (see license.txt) + */ + +#ifndef BOTAN_GMAC_H__ +#define BOTAN_GMAC_H__ + +#include <botan/types.h> +#include <botan/mac.h> +#include <botan/gcm.h> +#include <algorithm> + +namespace Botan { + +/** +* GMAC +*/ +class BOTAN_DLL GMAC : public MessageAuthenticationCode + { + public: + void clear() override; + std::string name() const override; + size_t output_length() const override; + MessageAuthenticationCode* clone() const override; + + /** + * Must be called to set the initialization vector prior to GMAC + * calculation. + * + * @param nonce Initialization vector. + */ + void start(const secure_vector<byte>& nonce); + + /** + * Must be called to set the initialization vector prior to GMAC + * calculation. + * + * @param nonce Initialization vector. + */ + void start(const std::vector<byte>& nonce); + + Key_Length_Specification key_spec() const + { + return m_gcm.key_spec(); + } + + /** + * Creates a new GMAC instance. + * + * @param cipher the underlying block cipher to use + */ + explicit GMAC(BlockCipher* cipher); + + static GMAC* make(const Spec& spec); + + GMAC(const GMAC&) = delete; + GMAC& operator=(const GMAC&) = delete; + private: + void add_data(const byte[], size_t) override; + void final_result(byte[]) override; + + void key_schedule(const byte key[], size_t size) override + { + m_gcm.set_key(key, size); + } + + secure_vector<byte> m_iv; + secure_vector<byte> m_aad; + GCM_Encryption m_gcm; + std::unique_ptr<BlockCipher> m_cipher; + }; + +} +#endif diff --git a/src/lib/mac/gmac/info.txt b/src/lib/mac/gmac/info.txt new file mode 100644 index 000000000..921690c93 --- /dev/null +++ b/src/lib/mac/gmac/info.txt @@ -0,0 +1,6 @@ +define GMAC 20160207 + +<requires> +gcm +mac +</requires> diff --git a/src/lib/mac/mac.cpp b/src/lib/mac/mac.cpp index 70807b39f..f2c5557c7 100644 --- a/src/lib/mac/mac.cpp +++ b/src/lib/mac/mac.cpp @@ -17,6 +17,10 @@ #include <botan/cmac.h> #endif +#if defined(BOTAN_HAS_GMAC) + #include <botan/gmac.h> +#endif + #if defined(BOTAN_HAS_HMAC) #include <botan/hmac.h> #endif diff --git a/src/lib/mac/mac.h b/src/lib/mac/mac.h index f3befc512..9c3614f33 100644 --- a/src/lib/mac/mac.h +++ b/src/lib/mac/mac.h @@ -59,7 +59,27 @@ class BOTAN_DLL MessageAuthenticationCode : public Buffered_Computation, virtual bool verify_mac(const byte in[], size_t length); /** - * @return a new object representing the same algorithm as *this + * Verify a MAC. + * @param in the MAC to verify as a byte array + * @return true if the MAC is valid, false otherwise + */ + virtual bool verify_mac(const std::vector<byte>& in) + { + return verify_mac(in.data(), in.size()); + } + + /** + * Verify a MAC. + * @param in the MAC to verify as a byte array + * @return true if the MAC is valid, false otherwise + */ + virtual bool verify_mac(const secure_vector<byte>& in) + { + return verify_mac(in.data(), in.size()); + } + + /** + * Get a new object representing the same algorithm as *this */ virtual MessageAuthenticationCode* clone() const = 0; diff --git a/src/lib/modes/aead/gcm/gcm.cpp b/src/lib/modes/aead/gcm/gcm.cpp index a73e5ee5b..6e1bd82f7 100644 --- a/src/lib/modes/aead/gcm/gcm.cpp +++ b/src/lib/modes/aead/gcm/gcm.cpp @@ -93,9 +93,9 @@ void GHASH::key_schedule(const byte key[], size_t length) m_text_len = 0; } -void GHASH::start(const byte nonce[], size_t len) +void GHASH::start(const secure_vector<byte>& nonce) { - m_nonce.assign(nonce, nonce + len); + m_nonce = nonce; m_ghash = m_H_ad; } diff --git a/src/lib/modes/aead/gcm/gcm.h b/src/lib/modes/aead/gcm/gcm.h index 6902bc1fa..964bd5062 100644 --- a/src/lib/modes/aead/gcm/gcm.h +++ b/src/lib/modes/aead/gcm/gcm.h @@ -14,7 +14,52 @@ namespace Botan { -class GHASH; +/** +* GCM's GHASH +* Maybe a Transform? +*/ +class BOTAN_DLL GHASH : public SymmetricAlgorithm + { + public: + void set_associated_data(const byte ad[], size_t ad_len); + + secure_vector<byte> nonce_hash(const byte nonce[], size_t len); + + void start(const secure_vector<byte>& nonce); + + /* + * Assumes input len is multiple of 16 + */ + void update(const byte in[], size_t len); + + secure_vector<byte> final(); + + Key_Length_Specification key_spec() const override + { return Key_Length_Specification(16); } + + size_t input_size() const { return m_text_len; } + + void clear() override; + + std::string name() const override { return "GHASH"; } + private: + void key_schedule(const byte key[], size_t key_len) override; + + void gcm_multiply(secure_vector<byte>& x) const; + + void ghash_update(secure_vector<byte>& x, + const byte input[], size_t input_len); + + void add_final_block(secure_vector<byte>& x, + size_t ad_len, size_t pt_len); + + secure_vector<byte> m_H; + secure_vector<byte> m_H_ad; + secure_vector<byte> m_nonce; + secure_vector<byte> m_ghash; + size_t m_ad_len = 0, m_text_len = 0; + }; + /** * GCM Mode @@ -28,6 +73,8 @@ class BOTAN_DLL GCM_Mode : public AEAD_Mode size_t update_granularity() const override; + void update(secure_vector<byte>& blocks, size_t offset = 0) override = 0; + Key_Length_Specification key_spec() const override; // GCM supports arbitrary nonce lengths @@ -35,6 +82,8 @@ class BOTAN_DLL GCM_Mode : public AEAD_Mode size_t tag_size() const override { return m_tag_size; } + size_t input_size() const { return m_ghash->input_size(); } + void clear() override; std::string provider() const override; @@ -51,7 +100,9 @@ class BOTAN_DLL GCM_Mode : public AEAD_Mode private: void start_msg(const byte nonce[], size_t nonce_len) override; + private: void key_schedule(const byte key[], size_t length) override; + secure_vector<byte> start_raw(const byte nonce[], size_t nonce_len) override; }; /** @@ -102,51 +153,5 @@ class BOTAN_DLL GCM_Decryption final : public GCM_Mode void finish(secure_vector<byte>& final_block, size_t offset = 0) override; }; - -/** -* GCM's GHASH -* Maybe a Transform? -*/ -class BOTAN_DLL GHASH : public SymmetricAlgorithm - { - public: - void set_associated_data(const byte ad[], size_t ad_len); - - secure_vector<byte> nonce_hash(const byte nonce[], size_t len); - - void start(const byte nonce[], size_t len); - - /* - * Assumes input len is multiple of 16 - */ - void update(const byte in[], size_t len); - - secure_vector<byte> final(); - - Key_Length_Specification key_spec() const override - { return Key_Length_Specification(16); } - - void clear() override; - - std::string name() const override { return "GHASH"; } - private: - void key_schedule(const byte key[], size_t key_len) override; - - void gcm_multiply(secure_vector<byte>& x) const; - - void ghash_update(secure_vector<byte>& x, - const byte input[], size_t input_len); - - void add_final_block(secure_vector<byte>& x, - size_t ad_len, size_t pt_len); - - secure_vector<byte> m_H; - secure_vector<byte> m_H_ad; - secure_vector<byte> m_nonce; - secure_vector<byte> m_ghash; - size_t m_ad_len = 0, m_text_len = 0; - }; - } - #endif |