diff options
author | lloyd <[email protected]> | 2014-01-01 21:20:55 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2014-01-01 21:20:55 +0000 |
commit | 197dc467dec28a04c3b2f30da7cef122dfbb13e9 (patch) | |
tree | cdbd3ddaec051c72f0a757db461973d90c37b97a /src/modes/aead/gcm | |
parent | 62faac373c07cfe10bc8c309e89ebdd30d8e5eaa (diff) |
Shuffle things around. Add NIST X.509 test to build.
Diffstat (limited to 'src/modes/aead/gcm')
-rw-r--r-- | src/modes/aead/gcm/clmul/clmul.cpp | 76 | ||||
-rw-r--r-- | src/modes/aead/gcm/clmul/clmul.h | 14 | ||||
-rw-r--r-- | src/modes/aead/gcm/clmul/info.txt | 8 | ||||
-rw-r--r-- | src/modes/aead/gcm/gcm.cpp | 290 | ||||
-rw-r--r-- | src/modes/aead/gcm/gcm.h | 150 | ||||
-rw-r--r-- | src/modes/aead/gcm/info.txt | 6 |
6 files changed, 0 insertions, 544 deletions
diff --git a/src/modes/aead/gcm/clmul/clmul.cpp b/src/modes/aead/gcm/clmul/clmul.cpp deleted file mode 100644 index cc6d581e3..000000000 --- a/src/modes/aead/gcm/clmul/clmul.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* -* CLMUL hook -* (C) 2013 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/internal/clmul.h> -#include <immintrin.h> - -namespace Botan { - -void gcm_multiply_clmul(byte x[16], const byte H[16]) - { - /* - * Algorithms 1 and 5 from Intel's CLMUL guide - */ - const __m128i BSWAP_MASK = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); - - __m128i a = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&x[0])); - __m128i b = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&H[0])); - - a = _mm_shuffle_epi8(a, BSWAP_MASK); - b = _mm_shuffle_epi8(b, BSWAP_MASK); - - __m128i T0, T1, T2, T3, T4, T5; - - T0 = _mm_clmulepi64_si128(a, b, 0x00); - T1 = _mm_clmulepi64_si128(a, b, 0x01); - T2 = _mm_clmulepi64_si128(a, b, 0x10); - T3 = _mm_clmulepi64_si128(a, b, 0x11); - - T1 = _mm_xor_si128(T1, T2); - T2 = _mm_slli_si128(T1, 8); - T1 = _mm_srli_si128(T1, 8); - T0 = _mm_xor_si128(T0, T2); - T3 = _mm_xor_si128(T3, T1); - - T4 = _mm_srli_epi32(T0, 31); - T0 = _mm_slli_epi32(T0, 1); - - T5 = _mm_srli_epi32(T3, 31); - T3 = _mm_slli_epi32(T3, 1); - - T2 = _mm_srli_si128(T4, 12); - T5 = _mm_slli_si128(T5, 4); - T4 = _mm_slli_si128(T4, 4); - T0 = _mm_or_si128(T0, T4); - T3 = _mm_or_si128(T3, T5); - T3 = _mm_or_si128(T3, T2); - - T4 = _mm_slli_epi32(T0, 31); - T5 = _mm_slli_epi32(T0, 30); - T2 = _mm_slli_epi32(T0, 25); - - T4 = _mm_xor_si128(T4, T5); - T4 = _mm_xor_si128(T4, T2); - T5 = _mm_srli_si128(T4, 4); - T3 = _mm_xor_si128(T3, T5); - T4 = _mm_slli_si128(T4, 12); - T0 = _mm_xor_si128(T0, T4); - T3 = _mm_xor_si128(T3, T0); - - T4 = _mm_srli_epi32(T0, 1); - T1 = _mm_srli_epi32(T0, 2); - T2 = _mm_srli_epi32(T0, 7); - T3 = _mm_xor_si128(T3, T1); - T3 = _mm_xor_si128(T3, T2); - T3 = _mm_xor_si128(T3, T4); - - T3 = _mm_shuffle_epi8(T3, BSWAP_MASK); - - _mm_storeu_si128(reinterpret_cast<__m128i*>(&x[0]), T3); - } - -} diff --git a/src/modes/aead/gcm/clmul/clmul.h b/src/modes/aead/gcm/clmul/clmul.h deleted file mode 100644 index ba197f2f7..000000000 --- a/src/modes/aead/gcm/clmul/clmul.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -* CLMUL hook -* (C) 2013 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/types.h> - -namespace Botan { - -void gcm_multiply_clmul(byte x[16], const byte H[16]); - -} diff --git a/src/modes/aead/gcm/clmul/info.txt b/src/modes/aead/gcm/clmul/info.txt deleted file mode 100644 index 8a21b6ac2..000000000 --- a/src/modes/aead/gcm/clmul/info.txt +++ /dev/null @@ -1,8 +0,0 @@ - -define GCM_CLMUL 20131227 - -need_isa clmul,ssse3 - -<header:internal> -clmul.h -</header:internal> diff --git a/src/modes/aead/gcm/gcm.cpp b/src/modes/aead/gcm/gcm.cpp deleted file mode 100644 index b39e6ac92..000000000 --- a/src/modes/aead/gcm/gcm.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/* -* GCM Mode Encryption -* (C) 2013 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/gcm.h> -#include <botan/ctr.h> -#include <botan/internal/xor_buf.h> -#include <botan/loadstor.h> - -#if defined(BOTAN_HAS_GCM_CLMUL) - #include <botan/internal/clmul.h> - #include <botan/cpuid.h> -#endif - -namespace Botan { - -void GHASH::gcm_multiply(secure_vector<byte>& x) const - { -#if defined(BOTAN_HAS_GCM_CLMUL) - if(CPUID::has_clmul()) - return gcm_multiply_clmul(&x[0], &m_H[0]); -#endif - - static const u64bit R = 0xE100000000000000; - - u64bit H[2] = { - load_be<u64bit>(&m_H[0], 0), - load_be<u64bit>(&m_H[0], 1) - }; - - u64bit Z[2] = { 0, 0 }; - - // SSE2 might be useful here - - for(size_t i = 0; i != 2; ++i) - { - const u64bit X = load_be<u64bit>(&x[0], i); - - for(size_t j = 0; j != 64; ++j) - { - if((X >> (63-j)) & 1) - { - Z[0] ^= H[0]; - Z[1] ^= H[1]; - } - - const u64bit r = (H[1] & 1) ? R : 0; - - H[1] = (H[0] << 63) | (H[1] >> 1); - H[0] = (H[0] >> 1) ^ r; - } - } - - store_be<u64bit>(&x[0], Z[0], Z[1]); - } - -void GHASH::ghash_update(secure_vector<byte>& ghash, - const byte input[], size_t length) - { - const size_t BS = 16; - - /* - This assumes if less than block size input then we're just on the - final block and should pad with zeros - */ - while(length) - { - const size_t to_proc = std::min(length, BS); - - xor_buf(&ghash[0], &input[0], to_proc); - - gcm_multiply(ghash); - - input += to_proc; - length -= to_proc; - } - } - -void GHASH::key_schedule(const byte key[], size_t length) - { - m_H.assign(key, key+length); - m_H_ad.resize(16); - m_ad_len = 0; - m_text_len = 0; - } - -void GHASH::start(const byte nonce[], size_t len) - { - m_nonce.assign(nonce, nonce + len); - m_ghash = m_H_ad; - } - -void GHASH::set_associated_data(const byte input[], size_t length) - { - zeroise(m_H_ad); - - ghash_update(m_H_ad, input, length); - m_ad_len = length; - } - -void GHASH::update(const byte input[], size_t length) - { - BOTAN_ASSERT(m_ghash.size() == 16, "Key was set"); - - m_text_len += length; - - ghash_update(m_ghash, input, length); - } - -void GHASH::add_final_block(secure_vector<byte>& hash, - size_t ad_len, size_t text_len) - { - secure_vector<byte> final_block(16); - store_be<u64bit>(&final_block[0], 8*ad_len, 8*text_len); - ghash_update(hash, &final_block[0], final_block.size()); - } - -secure_vector<byte> GHASH::final() - { - add_final_block(m_ghash, m_ad_len, m_text_len); - - secure_vector<byte> mac; - mac.swap(m_ghash); - - mac ^= m_nonce; - m_text_len = 0; - return mac; - } - -secure_vector<byte> GHASH::nonce_hash(const byte nonce[], size_t nonce_len) - { - BOTAN_ASSERT(m_ghash.size() == 0, "nonce_hash called during wrong time"); - secure_vector<byte> y0(16); - - ghash_update(y0, nonce, nonce_len); - add_final_block(y0, 0, nonce_len); - - return y0; - } - -void GHASH::clear() - { - zeroise(m_H); - zeroise(m_H_ad); - m_ghash.clear(); - m_text_len = m_ad_len = 0; - } - -/* -* GCM_Mode Constructor -*/ -GCM_Mode::GCM_Mode(BlockCipher* cipher, size_t tag_size) : - m_tag_size(tag_size), - m_cipher_name(cipher->name()) - { - if(cipher->block_size() != BS) - throw std::invalid_argument("GCM requires a 128 bit cipher so cannot be used with " + - cipher->name()); - - m_ghash.reset(new GHASH); - - m_ctr.reset(new CTR_BE(cipher)); // CTR_BE takes ownership of cipher - - if(m_tag_size != 8 && m_tag_size != 16) - throw Invalid_Argument(name() + ": Bad tag size " + std::to_string(m_tag_size)); - } - -void GCM_Mode::clear() - { - m_ctr->clear(); - m_ghash->clear(); - } - -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()); - - secure_vector<byte> H(BS); - m_ctr->encipher(H); - m_ghash->set_key(H); - } - -void GCM_Mode::set_associated_data(const byte ad[], size_t ad_len) - { - m_ghash->set_associated_data(ad, ad_len); - } - -secure_vector<byte> GCM_Mode::start(const byte nonce[], size_t nonce_len) - { - if(!valid_nonce_length(nonce_len)) - throw Invalid_IV_Length(name(), nonce_len); - - secure_vector<byte> y0(BS); - - if(nonce_len == 12) - { - copy_mem(&y0[0], nonce, nonce_len); - y0[15] = 1; - } - else - { - y0 = m_ghash->nonce_hash(nonce, nonce_len); - } - - m_ctr->set_iv(&y0[0], y0.size()); - - secure_vector<byte> m_enc_y0(BS); - m_ctr->encipher(m_enc_y0); - - m_ghash->start(&m_enc_y0[0], m_enc_y0.size()); - - return secure_vector<byte>(); - } - -void GCM_Encryption::update(secure_vector<byte>& buffer, size_t offset) - { - BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); - const size_t sz = buffer.size() - offset; - byte* buf = &buffer[offset]; - - m_ctr->cipher(buf, buf, sz); - m_ghash->update(buf, sz); - } - -void GCM_Encryption::finish(secure_vector<byte>& buffer, size_t offset) - { - update(buffer, offset); - auto mac = m_ghash->final(); - buffer += std::make_pair(&mac[0], tag_size()); - } - -void GCM_Decryption::update(secure_vector<byte>& buffer, size_t offset) - { - BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); - const size_t sz = buffer.size() - offset; - byte* buf = &buffer[offset]; - - m_ghash->update(buf, sz); - m_ctr->cipher(buf, buf, sz); - } - -void GCM_Decryption::finish(secure_vector<byte>& buffer, size_t offset) - { - BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane"); - const size_t sz = buffer.size() - offset; - byte* buf = &buffer[offset]; - - BOTAN_ASSERT(sz >= tag_size(), "Have the tag as part of final input"); - - const size_t remaining = sz - tag_size(); - - // handle any final input before the tag - if(remaining) - { - m_ghash->update(buf, remaining); - m_ctr->cipher(buf, buf, remaining); - } - - auto mac = m_ghash->final(); - - const byte* included_tag = &buffer[remaining]; - - if(!same_mem(&mac[0], included_tag, tag_size())) - throw Integrity_Failure("GCM tag check failed"); - - buffer.resize(offset + remaining); - } - -} diff --git a/src/modes/aead/gcm/gcm.h b/src/modes/aead/gcm/gcm.h deleted file mode 100644 index 12d66a3d1..000000000 --- a/src/modes/aead/gcm/gcm.h +++ /dev/null @@ -1,150 +0,0 @@ -/* -* GCM Mode -* (C) 2013 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_AEAD_GCM_H__ -#define BOTAN_AEAD_GCM_H__ - -#include <botan/aead.h> -#include <botan/block_cipher.h> -#include <botan/stream_cipher.h> -#include <memory> - -namespace Botan { - -class GHASH; - -/** -* 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; } - - size_t tag_size() const { return m_tag_size; } - - void clear(); - protected: - void key_schedule(const byte key[], size_t length) override; - - GCM_Mode(BlockCipher* cipher, size_t tag_size); - - const size_t BS = 16; - - const size_t m_tag_size; - const std::string m_cipher_name; - - std::unique_ptr<StreamCipher> m_ctr; - std::unique_ptr<GHASH> m_ghash; - }; - -/** -* 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 output_length(size_t input_length) const override - { return input_length + tag_size(); } - - size_t minimum_final_size() const override { return 0; } - - void update(secure_vector<byte>& blocks, size_t offset = 0) override; - - void finish(secure_vector<byte>& final_block, size_t offset = 0) 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 output_length(size_t input_length) const override - { - BOTAN_ASSERT(input_length > tag_size(), "Sufficient input"); - return input_length - tag_size(); - } - - size_t minimum_final_size() const override { return tag_size(); } - - void update(secure_vector<byte>& blocks, size_t offset = 0) override; - - 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 { return Key_Length_Specification(16); } - - void clear(); - - std::string name() const { 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 diff --git a/src/modes/aead/gcm/info.txt b/src/modes/aead/gcm/info.txt deleted file mode 100644 index cf5f68bb5..000000000 --- a/src/modes/aead/gcm/info.txt +++ /dev/null @@ -1,6 +0,0 @@ -define AEAD_GCM 20131128 - -<requires> -block -ctr -</requires> |