aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorlloyd <[email protected]>2013-03-27 14:03:58 +0000
committerlloyd <[email protected]>2013-03-27 14:03:58 +0000
commit7703ed769010f9ef4d037be1e9d1183a854f8348 (patch)
tree5766676f2c8c89d39b953c10466cb8d996bddf95 /src
parent86ecbb4fc9d4db13281a2cb689c604222900a6e7 (diff)
Move GCM to new AEAD interface
Diffstat (limited to 'src')
-rw-r--r--src/aead/eax/eax.cpp27
-rw-r--r--src/aead/eax/eax.h13
-rw-r--r--src/aead/eax/info.txt2
-rw-r--r--src/aead/gcm/gcm.cpp (renamed from src/filters/aead/gcm/gcm.cpp)134
-rw-r--r--src/aead/gcm/gcm.h100
-rw-r--r--src/aead/gcm/info.txt (renamed from src/filters/aead/gcm/info.txt)2
-rw-r--r--src/aead/info.txt2
-rw-r--r--src/filters/aead/gcm/gcm.h101
-rw-r--r--src/filters/aead_filt/aead_filt.h (renamed from src/filters/aead/aead_filt.h)0
-rw-r--r--src/filters/aead_filt/info.txt (renamed from src/filters/aead/info.txt)0
-rw-r--r--src/filters/aead_filt/ocb/info.txt (renamed from src/filters/aead/ocb/info.txt)0
-rw-r--r--src/filters/aead_filt/ocb/ocb.cpp (renamed from src/filters/aead/ocb/ocb.cpp)0
-rw-r--r--src/filters/aead_filt/ocb/ocb.h (renamed from src/filters/aead/ocb/ocb.h)0
13 files changed, 188 insertions, 193 deletions
diff --git a/src/aead/eax/eax.cpp b/src/aead/eax/eax.cpp
index d03d6ec5e..8a7287062 100644
--- a/src/aead/eax/eax.cpp
+++ b/src/aead/eax/eax.cpp
@@ -45,11 +45,30 @@ EAX_Mode::EAX_Mode(BlockCipher* cipher, size_t tag_size) :
throw Invalid_Argument(name() + ": Bad tag size " + std::to_string(tag_size));
}
+void EAX_Mode::clear()
+ {
+ m_cipher.reset();
+ m_ctr.reset();
+ m_cmac.reset();
+ zeroise(m_ad_mac);
+ zeroise(m_nonce_mac);
+ }
+
+std::string EAX_Mode::name() const
+ {
+ return (m_cipher->name() + "/EAX");
+ }
+
size_t EAX_Mode::update_granularity() const
{
return 8 * m_cipher->parallel_bytes();
}
+Key_Length_Specification EAX_Mode::key_spec() const
+ {
+ return m_cipher->key_spec();
+ }
+
/*
* Set the EAX key
*/
@@ -86,14 +105,6 @@ secure_vector<byte> EAX_Mode::start(const byte nonce[], size_t nonce_len)
return secure_vector<byte>();
}
-/*
-* Return the name of this cipher mode
-*/
-std::string EAX_Mode::name() const
- {
- return (m_cipher->name() + "/EAX");
- }
-
void EAX_Encryption::update(secure_vector<byte>& buffer)
{
m_ctr->cipher(&buffer[0], &buffer[0], buffer.size());
diff --git a/src/aead/eax/eax.h b/src/aead/eax/eax.h
index f7e1c6387..f3562f755 100644
--- a/src/aead/eax/eax.h
+++ b/src/aead/eax/eax.h
@@ -9,7 +9,6 @@
#define BOTAN_EAX_H__
#include <botan/aead.h>
-#include <botan/buf_filt.h>
#include <botan/block_cipher.h>
#include <botan/stream_cipher.h>
#include <botan/mac.h>
@@ -18,23 +17,25 @@
namespace Botan {
/**
-* EAX Mode
+* EAX base class
*/
class BOTAN_DLL EAX_Mode : public AEAD_Mode
{
public:
- size_t update_granularity() const;
-
secure_vector<byte> start(const byte nonce[], size_t nonce_len) override;
void set_associated_data(const byte ad[], size_t ad_len) override;
std::string name() const override;
- Key_Length_Specification key_spec() const override { return m_cipher->key_spec(); }
+ size_t update_granularity() const;
+
+ Key_Length_Specification key_spec() const override;
// EAX supports arbitrary nonce lengths
bool valid_nonce_length(size_t) const override { return true; }
+
+ void clear();
protected:
void key_schedule(const byte key[], size_t length) override;
@@ -72,6 +73,8 @@ class BOTAN_DLL EAX_Encryption : public EAX_Mode
EAX_Encryption(BlockCipher* cipher, size_t tag_size = 16) :
EAX_Mode(cipher, tag_size) {}
+ size_t minimum_final_size() const override { return 0; }
+
void update(secure_vector<byte>& blocks) override;
void finish(secure_vector<byte>& final_block) override;
diff --git a/src/aead/eax/info.txt b/src/aead/eax/info.txt
index 09d92e724..94924e682 100644
--- a/src/aead/eax/info.txt
+++ b/src/aead/eax/info.txt
@@ -1,4 +1,4 @@
-define EAX
+define AEAD_EAX
<requires>
block
diff --git a/src/filters/aead/gcm/gcm.cpp b/src/aead/gcm/gcm.cpp
index 32a763df7..0ff73b034 100644
--- a/src/filters/aead/gcm/gcm.cpp
+++ b/src/aead/gcm/gcm.cpp
@@ -90,12 +90,11 @@ void ghash_finalize(const secure_vector<byte>& H,
/*
* GCM_Mode Constructor
*/
-GCM_Mode::GCM_Mode(BlockCipher* cipher, size_t tag_size, bool decrypting) :
- Buffered_Filter(cipher->parallel_bytes(), decrypting ? tag_size : 0),
- m_tag_size(tag_size), m_cipher_name(cipher->name()),
+GCM_Mode::GCM_Mode(BlockCipher* cipher, size_t tag_size) :
+ m_tag_size(tag_size),
+ m_cipher_name(cipher->name()),
m_H(16), m_H_ad(16), m_mac(16),
- m_ad_len(0), m_text_len(0),
- m_ctr_buf(8 * cipher->parallel_bytes())
+ m_ad_len(0), m_text_len(0)
{
if(cipher->block_size() != BS)
throw std::invalid_argument("OCB requires a 128 bit cipher so cannot be used with " +
@@ -107,9 +106,35 @@ GCM_Mode::GCM_Mode(BlockCipher* cipher, size_t tag_size, bool decrypting) :
throw Invalid_Argument(name() + ": Bad tag size " + std::to_string(m_tag_size));
}
-void GCM_Mode::set_key(const SymmetricKey& key)
+void GCM_Mode::clear()
{
- m_ctr->set_key(key);
+ zeroise(m_H);
+ zeroise(m_H_ad);
+ zeroise(m_mac);
+ zeroise(m_enc_y0);
+ m_ad_len = 0;
+ m_text_len = 0;
+ m_ctr.reset();
+ }
+
+std::string GCM_Mode::name() const
+ {
+ return (m_cipher_name + "/GCM");
+ }
+
+size_t GCM_Mode::update_granularity() const
+ {
+ return 4096; // CTR-BE's internal block size
+ }
+
+Key_Length_Specification GCM_Mode::key_spec() const
+ {
+ return m_ctr->key_spec();
+ }
+
+void GCM_Mode::key_schedule(const byte key[], size_t keylen)
+ {
+ m_ctr->set_key(key, keylen);
const std::vector<byte> zeros(BS);
m_ctr->set_iv(&zeros[0], zeros.size());
@@ -118,9 +143,6 @@ void GCM_Mode::set_key(const SymmetricKey& key)
m_ctr->cipher(&m_H[0], &m_H[0], m_H.size());
}
-/*
-* Set the GCM associated data
-*/
void GCM_Mode::set_associated_data(const byte ad[], size_t ad_len)
{
zeroise(m_H_ad);
@@ -129,10 +151,7 @@ void GCM_Mode::set_associated_data(const byte ad[], size_t ad_len)
m_ad_len = ad_len;
}
-/*
-* Set the GCM nonce
-*/
-void GCM_Mode::set_nonce(const byte nonce[], size_t nonce_len)
+secure_vector<byte> GCM_Mode::start(const byte nonce[], size_t nonce_len)
{
secure_vector<byte> y0(BS);
@@ -151,95 +170,58 @@ void GCM_Mode::set_nonce(const byte nonce[], size_t nonce_len)
m_enc_y0.resize(BS);
m_ctr->encipher(m_enc_y0);
- }
-/*
-* Do setup at the start of each message
-*/
-void GCM_Mode::start_msg()
- {
m_text_len = 0;
m_mac = m_H_ad;
- }
-/*
-* Return the name of this cipher mode
-*/
-std::string GCM_Mode::name() const
- {
- return (m_cipher_name + "/GCM");
- }
-
-void GCM_Mode::write(const byte input[], size_t length)
- {
- Buffered_Filter::write(input, length);
+ return secure_vector<byte>();
}
-void GCM_Mode::end_msg()
+void GCM_Encryption::update(secure_vector<byte>& buffer)
{
- Buffered_Filter::end_msg();
- }
-
-void GCM_Encryption::buffered_block(const byte input[], size_t length)
- {
- while(length)
- {
- size_t copied = std::min<size_t>(length, m_ctr_buf.size());
-
- m_ctr->cipher(input, &m_ctr_buf[0], copied);
- ghash_update(m_H, m_mac, &m_ctr_buf[0], copied);
- m_text_len += copied;
-
- send(m_ctr_buf, copied);
-
- input += copied;
- length -= copied;
- }
+ m_ctr->cipher(&buffer[0], &buffer[0], buffer.size());
+ ghash_update(m_H, m_mac, &buffer[0], buffer.size());
+ m_text_len += buffer.size();
}
-void GCM_Encryption::buffered_final(const byte input[], size_t input_length)
+void GCM_Encryption::finish(secure_vector<byte>& buffer)
{
- buffered_block(input, input_length);
+ update(buffer);
ghash_finalize(m_H, m_mac, m_ad_len, m_text_len);
m_mac ^= m_enc_y0;
- send(m_mac, m_tag_size);
+ buffer += m_mac;
}
-void GCM_Decryption::buffered_block(const byte input[], size_t length)
+void GCM_Decryption::update(secure_vector<byte>& buffer)
{
- while(length)
- {
- size_t copied = std::min<size_t>(length, m_ctr_buf.size());
-
- ghash_update(m_H, m_mac, &input[0], copied);
- m_ctr->cipher(input, &m_ctr_buf[0], copied);
- m_text_len += copied;
-
- send(m_ctr_buf, copied);
-
- input += copied;
- length -= copied;
- }
+ ghash_update(m_H, m_mac, &buffer[0], buffer.size());
+ m_ctr->cipher(&buffer[0], &buffer[0], buffer.size());
+ m_text_len += buffer.size();
}
-void GCM_Decryption::buffered_final(const byte input[], size_t input_length)
+void GCM_Decryption::finish(secure_vector<byte>& buffer)
{
- BOTAN_ASSERT(input_length >= m_tag_size, "Have the tag as part of final input");
-
- const byte* included_tag = &input[input_length - m_tag_size];
- input_length -= m_tag_size;
+ BOTAN_ASSERT(buffer.size() >= tag_size(),
+ "Have the tag as part of final input");
- if(input_length) // handle any remaining input
- buffered_block(input, input_length);
+ // handle any final input before the tag
+ if(size_t input_length = buffer.size() - tag_size())
+ {
+ ghash_update(m_H, m_mac, &buffer[0], input_length);
+ m_ctr->cipher(&buffer[0], &buffer[0], input_length);
+ m_text_len += input_length;
+ }
ghash_finalize(m_H, m_mac, m_ad_len, m_text_len);
m_mac ^= m_enc_y0;
- if(!same_mem(&m_mac[0], included_tag, m_tag_size))
+ const byte* included_tag = &buffer[buffer.size() - tag_size()];
+
+ if(!same_mem(&m_mac[0], included_tag, tag_size()))
throw Integrity_Failure("GCM tag check failed");
}
diff --git a/src/aead/gcm/gcm.h b/src/aead/gcm/gcm.h
new file mode 100644
index 000000000..cf7d94ced
--- /dev/null
+++ b/src/aead/gcm/gcm.h
@@ -0,0 +1,100 @@
+/*
+* GCM Mode
+* (C) 2013 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_GCM_H__
+#define BOTAN_GCM_H__
+
+#include <botan/aead.h>
+#include <botan/block_cipher.h>
+#include <botan/stream_cipher.h>
+#include <memory>
+
+namespace Botan {
+
+/**
+* GCM Mode
+*/
+class BOTAN_DLL GCM_Mode : public AEAD_Mode
+ {
+ public:
+ secure_vector<byte> start(const byte nonce[], size_t nonce_len) override;
+
+ void set_associated_data(const byte ad[], size_t ad_len) override;
+
+ std::string name() const override;
+
+ size_t update_granularity() const;
+
+ Key_Length_Specification key_spec() const override;
+
+ // GCM supports arbitrary nonce lengths
+ bool valid_nonce_length(size_t) const override { return true; }
+
+ void clear();
+ protected:
+ void key_schedule(const byte key[], size_t length) override;
+
+ GCM_Mode(BlockCipher* cipher, size_t tag_size);
+
+ size_t tag_size() const { return m_tag_size; }
+
+ static const size_t BS = 16;
+
+ const size_t m_tag_size;
+ const std::string m_cipher_name;
+
+ std::unique_ptr<StreamCipher> m_ctr;
+ secure_vector<byte> m_H;
+ secure_vector<byte> m_H_ad;
+ secure_vector<byte> m_mac;
+ secure_vector<byte> m_enc_y0;
+ size_t m_ad_len, m_text_len;
+ };
+
+/**
+* GCM Encryption
+*/
+class BOTAN_DLL GCM_Encryption : public GCM_Mode
+ {
+ public:
+ /**
+ * @param cipher the 128 bit block cipher to use
+ * @param tag_size is how big the auth tag will be
+ */
+ GCM_Encryption(BlockCipher* cipher, size_t tag_size = 16) :
+ GCM_Mode(cipher, tag_size) {}
+
+ size_t minimum_final_size() const override { return 0; }
+
+ void update(secure_vector<byte>& blocks) override;
+
+ void finish(secure_vector<byte>& final_block) override;
+ };
+
+/**
+* GCM Decryption
+*/
+class BOTAN_DLL GCM_Decryption : public GCM_Mode
+ {
+ public:
+ /**
+ * @param cipher the 128 bit block cipher to use
+ * @param tag_size is how big the auth tag will be
+ */
+ GCM_Decryption(BlockCipher* cipher, size_t tag_size = 16) :
+ GCM_Mode(cipher, tag_size) {}
+
+ size_t minimum_final_size() const override { return tag_size(); }
+
+ void update(secure_vector<byte>& blocks) override;
+
+ void finish(secure_vector<byte>& final_block) override;
+ };
+
+}
+
+#endif
diff --git a/src/filters/aead/gcm/info.txt b/src/aead/gcm/info.txt
index 52e677a03..698cd0803 100644
--- a/src/filters/aead/gcm/info.txt
+++ b/src/aead/gcm/info.txt
@@ -1,4 +1,4 @@
-define GCM
+define AEAD_GCM
<requires>
block
diff --git a/src/aead/info.txt b/src/aead/info.txt
index eae4b4340..c2985ea85 100644
--- a/src/aead/info.txt
+++ b/src/aead/info.txt
@@ -1 +1 @@
-define AEAD_MODE
+define AEAD_MODES
diff --git a/src/filters/aead/gcm/gcm.h b/src/filters/aead/gcm/gcm.h
deleted file mode 100644
index a04a6b8c0..000000000
--- a/src/filters/aead/gcm/gcm.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-* GCM Mode
-* (C) 2013 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#ifndef BOTAN_GCM_H__
-#define BOTAN_GCM_H__
-
-#include <botan/aead_filt.h>
-#include <botan/buf_filt.h>
-#include <botan/block_cipher.h>
-#include <botan/stream_cipher.h>
-#include <memory>
-
-namespace Botan {
-
-/**
-* GCM Mode
-*/
-class BOTAN_DLL GCM_Mode : public AEAD_Filter,
- private Buffered_Filter
- {
- public:
- void set_key(const SymmetricKey& key) override;
-
- void set_nonce(const byte nonce[], size_t nonce_len) override;
-
- /**
- * @note must be called before start_msg or not at all
- */
- void set_associated_data(const byte ad[], size_t ad_len) override;
-
- Key_Length_Specification key_spec() const override { return m_ctr->key_spec(); }
-
- // GCM supports arbitrary IV lengths
- bool valid_iv_length(size_t) const override { return true; }
-
- std::string name() const override;
- protected:
- GCM_Mode(BlockCipher* cipher, size_t tag_size, bool decrypting);
-
- static const size_t BS = 16;
-
- const size_t m_tag_size;
- const std::string m_cipher_name;
-
- std::unique_ptr<StreamCipher> m_ctr;
- secure_vector<byte> m_H;
- secure_vector<byte> m_H_ad;
- secure_vector<byte> m_mac;
- secure_vector<byte> m_enc_y0;
- size_t m_ad_len, m_text_len;
- secure_vector<byte> m_ctr_buf;
-
- private:
- void write(const byte[], size_t);
- void start_msg();
- void end_msg();
- };
-
-/**
-* GCM Encryption
-*/
-class BOTAN_DLL GCM_Encryption : public GCM_Mode
- {
- public:
- /**
- * @param ciph the cipher to use
- * @param tag_size is how big the auth tag will be
- */
- GCM_Encryption(BlockCipher* ciph, size_t tag_size = 16) :
- GCM_Mode(ciph, tag_size, false) {}
-
- private:
- void buffered_block(const byte input[], size_t input_length) override;
- void buffered_final(const byte input[], size_t input_length) override;
- };
-
-/**
-* GCM Decryption
-*/
-class BOTAN_DLL GCM_Decryption : public GCM_Mode
- {
- public:
- /**
- * @param ciph the cipher to use
- * @param tag_size is how big the auth tag will be
- */
- GCM_Decryption(BlockCipher* cipher, size_t tag_size = 16) :
- GCM_Mode(cipher, tag_size, true) {}
-
- private:
- void buffered_block(const byte input[], size_t input_length) override;
- void buffered_final(const byte input[], size_t input_length) override;
- };
-
-}
-
-#endif
diff --git a/src/filters/aead/aead_filt.h b/src/filters/aead_filt/aead_filt.h
index 77818c17e..77818c17e 100644
--- a/src/filters/aead/aead_filt.h
+++ b/src/filters/aead_filt/aead_filt.h
diff --git a/src/filters/aead/info.txt b/src/filters/aead_filt/info.txt
index b43aab2f6..b43aab2f6 100644
--- a/src/filters/aead/info.txt
+++ b/src/filters/aead_filt/info.txt
diff --git a/src/filters/aead/ocb/info.txt b/src/filters/aead_filt/ocb/info.txt
index 0ee41681d..0ee41681d 100644
--- a/src/filters/aead/ocb/info.txt
+++ b/src/filters/aead_filt/ocb/info.txt
diff --git a/src/filters/aead/ocb/ocb.cpp b/src/filters/aead_filt/ocb/ocb.cpp
index eb10b6e9f..eb10b6e9f 100644
--- a/src/filters/aead/ocb/ocb.cpp
+++ b/src/filters/aead_filt/ocb/ocb.cpp
diff --git a/src/filters/aead/ocb/ocb.h b/src/filters/aead_filt/ocb/ocb.h
index 0a1cbcaff..0a1cbcaff 100644
--- a/src/filters/aead/ocb/ocb.h
+++ b/src/filters/aead_filt/ocb/ocb.h