aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/mac/gmac/gmac.cpp76
-rw-r--r--src/lib/mac/gmac/gmac.h77
-rw-r--r--src/lib/mac/gmac/info.txt6
-rw-r--r--src/lib/mac/mac.cpp4
-rw-r--r--src/lib/mac/mac.h22
-rw-r--r--src/lib/modes/aead/gcm/gcm.cpp4
-rw-r--r--src/lib/modes/aead/gcm/gcm.h99
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