diff options
Diffstat (limited to 'src/lib/block')
27 files changed, 500 insertions, 633 deletions
diff --git a/src/lib/block/aes/aes.cpp b/src/lib/block/aes/aes.cpp index 6ec21cb0c..39f5bd0db 100644 --- a/src/lib/block/aes/aes.cpp +++ b/src/lib/block/aes/aes.cpp @@ -416,20 +416,85 @@ void aes_key_schedule(const byte key[], size_t length, copy_mem(DK.data(), XDK.data(), DK.size()); } +const char* aes_provider() + { +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return "aesni"; + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return "ssse3"; + } +#endif + + return "base"; + } + } +std::string AES_128::provider() const { return aes_provider(); } +std::string AES_192::provider() const { return aes_provider(); } +std::string AES_256::provider() const { return aes_provider(); } + void AES_128::encrypt_n(const byte in[], byte out[], size_t blocks) const { +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_encrypt_n(in, out, blocks); + } +#endif + aes_encrypt_n(in, out, blocks, m_EK, m_ME); } void AES_128::decrypt_n(const byte in[], byte out[], size_t blocks) const { +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_decrypt_n(in, out, blocks); + } +#endif + aes_decrypt_n(in, out, blocks, m_DK, m_MD); } void AES_128::key_schedule(const byte key[], size_t length) { +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_key_schedule(key, length); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_key_schedule(key, length); + } +#endif + aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); } @@ -443,16 +508,58 @@ void AES_128::clear() void AES_192::encrypt_n(const byte in[], byte out[], size_t blocks) const { +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_encrypt_n(in, out, blocks); + } +#endif + aes_encrypt_n(in, out, blocks, m_EK, m_ME); } void AES_192::decrypt_n(const byte in[], byte out[], size_t blocks) const { +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_decrypt_n(in, out, blocks); + } +#endif + aes_decrypt_n(in, out, blocks, m_DK, m_MD); } void AES_192::key_schedule(const byte key[], size_t length) { +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_key_schedule(key, length); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_key_schedule(key, length); + } +#endif + aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); } @@ -466,16 +573,58 @@ void AES_192::clear() void AES_256::encrypt_n(const byte in[], byte out[], size_t blocks) const { +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_encrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_encrypt_n(in, out, blocks); + } +#endif + aes_encrypt_n(in, out, blocks, m_EK, m_ME); } void AES_256::decrypt_n(const byte in[], byte out[], size_t blocks) const { +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_decrypt_n(in, out, blocks); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_decrypt_n(in, out, blocks); + } +#endif + aes_decrypt_n(in, out, blocks, m_DK, m_MD); } void AES_256::key_schedule(const byte key[], size_t length) { +#if defined(BOTAN_HAS_AES_NI) + if(CPUID::has_aes_ni()) + { + return aesni_key_schedule(key, length); + } +#endif + +#if defined(BOTAN_HAS_AES_SSSE3) + if(CPUID::has_ssse3()) + { + return ssse3_key_schedule(key, length); + } +#endif + aes_key_schedule(key, length, m_EK, m_DK, m_ME, m_MD); } diff --git a/src/lib/block/aes/aes.h b/src/lib/block/aes/aes.h index a058adcf1..6bd38cada 100644 --- a/src/lib/block/aes/aes.h +++ b/src/lib/block/aes/aes.h @@ -23,11 +23,24 @@ class BOTAN_DLL AES_128 final : public Block_Cipher_Fixed_Params<16, 16> void clear() override; + std::string provider() const override; std::string name() const override { return "AES-128"; } BlockCipher* clone() const override { return new AES_128; } private: void key_schedule(const byte key[], size_t length) override; +#if defined(BOTAN_HAS_AES_SSSE3) + void ssse3_encrypt_n(const byte in[], byte out[], size_t blocks) const; + void ssse3_decrypt_n(const byte in[], byte out[], size_t blocks) const; + void ssse3_key_schedule(const byte key[], size_t length); +#endif + +#if defined(BOTAN_HAS_AES_NI) + void aesni_encrypt_n(const byte in[], byte out[], size_t blocks) const; + void aesni_decrypt_n(const byte in[], byte out[], size_t blocks) const; + void aesni_key_schedule(const byte key[], size_t length); +#endif + secure_vector<u32bit> m_EK, m_DK; secure_vector<byte> m_ME, m_MD; }; @@ -43,9 +56,22 @@ class BOTAN_DLL AES_192 final : public Block_Cipher_Fixed_Params<16, 24> void clear() override; + std::string provider() const override; std::string name() const override { return "AES-192"; } BlockCipher* clone() const override { return new AES_192; } private: +#if defined(BOTAN_HAS_AES_SSSE3) + void ssse3_encrypt_n(const byte in[], byte out[], size_t blocks) const; + void ssse3_decrypt_n(const byte in[], byte out[], size_t blocks) const; + void ssse3_key_schedule(const byte key[], size_t length); +#endif + +#if defined(BOTAN_HAS_AES_NI) + void aesni_encrypt_n(const byte in[], byte out[], size_t blocks) const; + void aesni_decrypt_n(const byte in[], byte out[], size_t blocks) const; + void aesni_key_schedule(const byte key[], size_t length); +#endif + void key_schedule(const byte key[], size_t length) override; secure_vector<u32bit> m_EK, m_DK; @@ -63,9 +89,23 @@ class BOTAN_DLL AES_256 final : public Block_Cipher_Fixed_Params<16, 32> void clear() override; + std::string provider() const override; + std::string name() const override { return "AES-256"; } BlockCipher* clone() const override { return new AES_256; } private: +#if defined(BOTAN_HAS_AES_SSSE3) + void ssse3_encrypt_n(const byte in[], byte out[], size_t blocks) const; + void ssse3_decrypt_n(const byte in[], byte out[], size_t blocks) const; + void ssse3_key_schedule(const byte key[], size_t length); +#endif + +#if defined(BOTAN_HAS_AES_NI) + void aesni_encrypt_n(const byte in[], byte out[], size_t blocks) const; + void aesni_decrypt_n(const byte in[], byte out[], size_t blocks) const; + void aesni_key_schedule(const byte key[], size_t length); +#endif + void key_schedule(const byte key[], size_t length) override; secure_vector<u32bit> m_EK, m_DK; diff --git a/src/lib/block/aes_ni/aes_ni.cpp b/src/lib/block/aes_ni/aes_ni.cpp index 51b30881f..3377f9d61 100644 --- a/src/lib/block/aes_ni/aes_ni.cpp +++ b/src/lib/block/aes_ni/aes_ni.cpp @@ -5,9 +5,8 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/aes_ni.h> +#include <botan/aes.h> #include <botan/loadstor.h> -#include <botan/cpuid.h> #include <wmmintrin.h> namespace Botan { @@ -104,7 +103,7 @@ __m128i aes_256_key_expansion(__m128i key, __m128i key2) /* * AES-128 Encryption */ -void AES_128_NI::encrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_128::aesni_encrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); __m128i* out_mm = reinterpret_cast<__m128i*>(out); @@ -180,7 +179,7 @@ void AES_128_NI::encrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-128 Decryption */ -void AES_128_NI::decrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_128::aesni_decrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); __m128i* out_mm = reinterpret_cast<__m128i*>(out); @@ -256,7 +255,7 @@ void AES_128_NI::decrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-128 Key Schedule */ -void AES_128_NI::key_schedule(const byte key[], size_t) +void AES_128::aesni_key_schedule(const byte key[], size_t) { m_EK.resize(44); m_DK.resize(44); @@ -306,18 +305,9 @@ void AES_128_NI::key_schedule(const byte key[], size_t) } /* -* Clear memory of sensitive data -*/ -void AES_128_NI::clear() - { - zap(m_EK); - zap(m_DK); - } - -/* * AES-192 Encryption */ -void AES_192_NI::encrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_192::aesni_encrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); __m128i* out_mm = reinterpret_cast<__m128i*>(out); @@ -399,7 +389,7 @@ void AES_192_NI::encrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-192 Decryption */ -void AES_192_NI::decrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_192::aesni_decrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); __m128i* out_mm = reinterpret_cast<__m128i*>(out); @@ -481,7 +471,7 @@ void AES_192_NI::decrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-192 Key Schedule */ -void AES_192_NI::key_schedule(const byte key[], size_t) +void AES_192::aesni_key_schedule(const byte key[], size_t) { m_EK.resize(52); m_DK.resize(52); @@ -528,18 +518,9 @@ void AES_192_NI::key_schedule(const byte key[], size_t) } /* -* Clear memory of sensitive data -*/ -void AES_192_NI::clear() - { - zap(m_EK); - zap(m_DK); - } - -/* * AES-256 Encryption */ -void AES_256_NI::encrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_256::aesni_encrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); __m128i* out_mm = reinterpret_cast<__m128i*>(out); @@ -627,7 +608,7 @@ void AES_256_NI::encrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-256 Decryption */ -void AES_256_NI::decrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_256::aesni_decrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); __m128i* out_mm = reinterpret_cast<__m128i*>(out); @@ -715,7 +696,7 @@ void AES_256_NI::decrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-256 Key Schedule */ -void AES_256_NI::key_schedule(const byte key[], size_t) +void AES_256::aesni_key_schedule(const byte key[], size_t) { m_EK.resize(60); m_DK.resize(60); @@ -779,15 +760,6 @@ void AES_256_NI::key_schedule(const byte key[], size_t) _mm_storeu_si128(DK_mm + 14, K0); } -/* -* Clear memory of sensitive data -*/ -void AES_256_NI::clear() - { - zap(m_EK); - zap(m_DK); - } - #undef AES_ENC_4_ROUNDS #undef AES_ENC_4_LAST_ROUNDS #undef AES_DEC_4_ROUNDS diff --git a/src/lib/block/aes_ni/aes_ni.h b/src/lib/block/aes_ni/aes_ni.h deleted file mode 100644 index 296fd7fcc..000000000 --- a/src/lib/block/aes_ni/aes_ni.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -* AES using AES-NI instructions -* (C) 2009 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_AES_NI_H__ -#define BOTAN_AES_NI_H__ - -#include <botan/block_cipher.h> - -namespace Botan { - -/** -* AES-128 using AES-NI -*/ -class BOTAN_DLL AES_128_NI final : public Block_Cipher_Fixed_Params<16, 16> - { - public: - size_t parallelism() const override { return 4; } - - void encrypt_n(const byte in[], byte out[], size_t blocks) const override; - void decrypt_n(const byte in[], byte out[], size_t blocks) const override; - - void clear() override; - std::string name() const override { return "AES-128"; } - BlockCipher* clone() const override { return new AES_128_NI; } - private: - void key_schedule(const byte[], size_t) override; - - secure_vector<u32bit> m_EK, m_DK; - }; - -/** -* AES-192 using AES-NI -*/ -class BOTAN_DLL AES_192_NI final : public Block_Cipher_Fixed_Params<16, 24> - { - public: - size_t parallelism() const override { return 4; } - - void encrypt_n(const byte in[], byte out[], size_t blocks) const override; - void decrypt_n(const byte in[], byte out[], size_t blocks) const override; - - void clear() override; - std::string name() const override { return "AES-192"; } - BlockCipher* clone() const override { return new AES_192_NI; } - private: - void key_schedule(const byte[], size_t) override; - - secure_vector<u32bit> m_EK, m_DK; - }; - -/** -* AES-256 using AES-NI -*/ -class BOTAN_DLL AES_256_NI final : public Block_Cipher_Fixed_Params<16, 32> - { - public: - size_t parallelism() const override { return 4; } - - void encrypt_n(const byte in[], byte out[], size_t blocks) const override; - void decrypt_n(const byte in[], byte out[], size_t blocks) const override; - - void clear() override; - std::string name() const override { return "AES-256"; } - BlockCipher* clone() const override { return new AES_256_NI; } - private: - void key_schedule(const byte[], size_t) override; - - secure_vector<u32bit> m_EK, m_DK; - }; - -} - -#endif diff --git a/src/lib/block/aes_ssse3/aes_ssse3.cpp b/src/lib/block/aes_ssse3/aes_ssse3.cpp index 54e8fcbd8..eda39a7cc 100644 --- a/src/lib/block/aes_ssse3/aes_ssse3.cpp +++ b/src/lib/block/aes_ssse3/aes_ssse3.cpp @@ -10,8 +10,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/aes_ssse3.h> -#include <botan/cpuid.h> +#include <botan/aes.h> #include <botan/internal/ct_utils.h> #include <tmmintrin.h> @@ -337,7 +336,7 @@ __m128i aes_ssse3_decrypt(__m128i B, const __m128i* keys, size_t rounds) /* * AES-128 Encryption */ -void AES_128_SSSE3::encrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_128::ssse3_encrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); __m128i* out_mm = reinterpret_cast<__m128i*>(out); @@ -359,7 +358,7 @@ void AES_128_SSSE3::encrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-128 Decryption */ -void AES_128_SSSE3::decrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_128::ssse3_decrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); __m128i* out_mm = reinterpret_cast<__m128i*>(out); @@ -381,7 +380,7 @@ void AES_128_SSSE3::decrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-128 Key Schedule */ -void AES_128_SSSE3::key_schedule(const byte keyb[], size_t) +void AES_128::ssse3_key_schedule(const byte keyb[], size_t) { __m128i rcon = _mm_set_epi32(0x702A9808, 0x4D7C7D81, 0x1F8391B9, 0xAF9DEEB6); @@ -416,16 +415,10 @@ void AES_128_SSSE3::key_schedule(const byte keyb[], size_t) _mm_storeu_si128(DK_mm, aes_schedule_mangle_last_dec(key)); } -void AES_128_SSSE3::clear() - { - zap(m_EK); - zap(m_DK); - } - /* * AES-192 Encryption */ -void AES_192_SSSE3::encrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_192::ssse3_encrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); __m128i* out_mm = reinterpret_cast<__m128i*>(out); @@ -447,7 +440,7 @@ void AES_192_SSSE3::encrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-192 Decryption */ -void AES_192_SSSE3::decrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_192::ssse3_decrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); __m128i* out_mm = reinterpret_cast<__m128i*>(out); @@ -469,7 +462,7 @@ void AES_192_SSSE3::decrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-192 Key Schedule */ -void AES_192_SSSE3::key_schedule(const byte keyb[], size_t) +void AES_192::ssse3_key_schedule(const byte keyb[], size_t) { __m128i rcon = _mm_set_epi32(0x702A9808, 0x4D7C7D81, 0x1F8391B9, 0xAF9DEEB6); @@ -533,16 +526,10 @@ void AES_192_SSSE3::key_schedule(const byte keyb[], size_t) } } -void AES_192_SSSE3::clear() - { - zap(m_EK); - zap(m_DK); - } - /* * AES-256 Encryption */ -void AES_256_SSSE3::encrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_256::ssse3_encrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); __m128i* out_mm = reinterpret_cast<__m128i*>(out); @@ -564,7 +551,7 @@ void AES_256_SSSE3::encrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-256 Decryption */ -void AES_256_SSSE3::decrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_256::ssse3_decrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); __m128i* out_mm = reinterpret_cast<__m128i*>(out); @@ -586,7 +573,7 @@ void AES_256_SSSE3::decrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-256 Key Schedule */ -void AES_256_SSSE3::key_schedule(const byte keyb[], size_t) +void AES_256::ssse3_key_schedule(const byte keyb[], size_t) { __m128i rcon = _mm_set_epi32(0x702A9808, 0x4D7C7D81, 0x1F8391B9, 0xAF9DEEB6); @@ -629,10 +616,4 @@ void AES_256_SSSE3::key_schedule(const byte keyb[], size_t) _mm_storeu_si128(DK_mm + 0, aes_schedule_mangle_last_dec(key2)); } -void AES_256_SSSE3::clear() - { - zap(m_EK); - zap(m_DK); - } - } diff --git a/src/lib/block/aes_ssse3/aes_ssse3.h b/src/lib/block/aes_ssse3/aes_ssse3.h deleted file mode 100644 index 8e6c40dcd..000000000 --- a/src/lib/block/aes_ssse3/aes_ssse3.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -* AES using SSSE3 -* (C) 2010 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_AES_SSSE3_H__ -#define BOTAN_AES_SSSE3_H__ - -#include <botan/block_cipher.h> - -namespace Botan { - -/** -* AES-128 using SSSE3 -*/ -class BOTAN_DLL AES_128_SSSE3 final : public Block_Cipher_Fixed_Params<16, 16> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const override; - void decrypt_n(const byte in[], byte out[], size_t blocks) const override; - - void clear() override; - std::string name() const override { return "AES-128"; } - BlockCipher* clone() const override { return new AES_128_SSSE3; } - private: - void key_schedule(const byte[], size_t) override; - - secure_vector<u32bit> m_EK, m_DK; - }; - -/** -* AES-192 using SSSE3 -*/ -class BOTAN_DLL AES_192_SSSE3 final : public Block_Cipher_Fixed_Params<16, 24> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const override; - void decrypt_n(const byte in[], byte out[], size_t blocks) const override; - - void clear() override; - std::string name() const override { return "AES-192"; } - BlockCipher* clone() const override { return new AES_192_SSSE3; } - private: - void key_schedule(const byte[], size_t) override; - - secure_vector<u32bit> m_EK, m_DK; - }; - -/** -* AES-256 using SSSE3 -*/ -class BOTAN_DLL AES_256_SSSE3 final : public Block_Cipher_Fixed_Params<16, 32> - { - public: - void encrypt_n(const byte in[], byte out[], size_t blocks) const override; - void decrypt_n(const byte in[], byte out[], size_t blocks) const override; - - void clear() override; - std::string name() const override { return "AES-256"; } - BlockCipher* clone() const override { return new AES_256_SSSE3; } - private: - void key_schedule(const byte[], size_t) override; - - secure_vector<u32bit> m_EK, m_DK; - }; - -} - -#endif diff --git a/src/lib/block/block_cipher.cpp b/src/lib/block/block_cipher.cpp index 230d9e3a0..2388057c6 100644 --- a/src/lib/block/block_cipher.cpp +++ b/src/lib/block/block_cipher.cpp @@ -13,14 +13,6 @@ #include <botan/aes.h> #endif -#if defined(BOTAN_HAS_AES_SSSE3) - #include <botan/aes_ssse3.h> -#endif - -#if defined(BOTAN_HAS_AES_NI) - #include <botan/aes_ni.h> -#endif - #if defined(BOTAN_HAS_BLOWFISH) #include <botan/blowfish.h> #endif @@ -51,10 +43,6 @@ #include <botan/idea.h> #endif -#if defined(BOTAN_HAS_IDEA_SSE2) - #include <botan/idea_sse2.h> -#endif - #if defined(BOTAN_HAS_KASUMI) #include <botan/kasumi.h> #endif @@ -71,10 +59,6 @@ #include <botan/noekeon.h> #endif -#if defined(BOTAN_HAS_NOEKEON_SIMD) - #include <botan/noekeon_simd.h> -#endif - #if defined(BOTAN_HAS_SEED) #include <botan/seed.h> #endif @@ -83,10 +67,6 @@ #include <botan/serpent.h> #endif -#if defined(BOTAN_HAS_SERPENT_SIMD) - #include <botan/serp_simd.h> -#endif - #if defined(BOTAN_HAS_TWOFISH) #include <botan/twofish.h> #endif @@ -95,18 +75,10 @@ #include <botan/threefish.h> #endif -#if defined(BOTAN_HAS_THREEFISH_512_AVX2) - #include <botan/threefish_avx2.h> -#endif - #if defined(BOTAN_HAS_XTEA) #include <botan/xtea.h> #endif -#if defined(BOTAN_HAS_XTEA_SIMD) - #include <botan/xtea_simd.h> -#endif - namespace Botan { BlockCipher::~BlockCipher() {} @@ -143,21 +115,6 @@ BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(AES_192, "AES-192"); BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(AES_256, "AES-256"); #endif -#if defined(BOTAN_HAS_AES_NI) -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_aes_ni(), AES_128_NI, "AES-128", "aes_ni", 200); -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_aes_ni(), AES_192_NI, "AES-192", "aes_ni", 200); -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_aes_ni(), AES_256_NI, "AES-256", "aes_ni", 200); -#endif - -#if defined(BOTAN_HAS_AES_SSSE3) -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_ssse3(), AES_128_SSSE3, "AES-128", - "ssse3", BOTAN_SIMD_ALGORITHM_PRIO); -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_ssse3(), AES_192_SSSE3, "AES-192", - "ssse3", BOTAN_SIMD_ALGORITHM_PRIO); -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_ssse3(), AES_256_SSSE3, "AES-256", - "ssse3", BOTAN_SIMD_ALGORITHM_PRIO); -#endif - #if defined(BOTAN_HAS_BLOWFISH) BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Blowfish); #endif @@ -187,11 +144,6 @@ BOTAN_REGISTER_BLOCK_CIPHER_NAMED_1STR(GOST_28147_89, "GOST-28147-89", "R3411_94 BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(IDEA); #endif -#if defined(BOTAN_HAS_IDEA_SSE2) -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_sse2(), IDEA_SSE2, "IDEA", - "sse2", BOTAN_SIMD_ALGORITHM_PRIO); -#endif - #if defined(BOTAN_HAS_KASUMI) BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(KASUMI); #endif @@ -204,11 +156,6 @@ BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(MISTY1); BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Noekeon); #endif -#if defined(BOTAN_HAS_NOEKEON_SIMD) -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_simd_32(), Noekeon_SIMD, "Noekeon", - "simd32", BOTAN_SIMD_ALGORITHM_PRIO); -#endif - #if defined(BOTAN_HAS_SEED) BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(SEED); #endif @@ -217,11 +164,6 @@ BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(SEED); BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Serpent); #endif -#if defined(BOTAN_HAS_SERPENT_SIMD) -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_simd_32(), Serpent_SIMD, "Serpent", - "simd32", BOTAN_SIMD_ALGORITHM_PRIO); -#endif - #if defined(BOTAN_HAS_TWOFISH) BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Twofish); #endif @@ -230,20 +172,10 @@ BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(Twofish); BOTAN_REGISTER_BLOCK_CIPHER_NAMED_NOARGS(Threefish_512, "Threefish-512"); #endif -#if defined(BOTAN_HAS_THREEFISH_512_AVX2) -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_avx2(), Threefish_512_AVX2, "Threefish-512", - "avx2", BOTAN_SIMD_ALGORITHM_PRIO); -#endif - #if defined(BOTAN_HAS_XTEA) BOTAN_REGISTER_BLOCK_CIPHER_NOARGS(XTEA); #endif -#if defined(BOTAN_HAS_XTEA_SIMD) -BOTAN_REGISTER_BLOCK_CIPHER_NOARGS_IF(CPUID::has_simd_32(), XTEA_SIMD, "XTEA", - "simd32", BOTAN_SIMD_ALGORITHM_PRIO); -#endif - #if defined(BOTAN_HAS_CASCADE) BOTAN_REGISTER_NAMED_T(BlockCipher, "Cascade", Cascade_Cipher, Cascade_Cipher::make); #endif diff --git a/src/lib/block/block_cipher.h b/src/lib/block/block_cipher.h index 0f4c2c1c5..b16468958 100644 --- a/src/lib/block/block_cipher.h +++ b/src/lib/block/block_cipher.h @@ -10,6 +10,7 @@ #include <botan/scan_name.h> #include <botan/sym_algo.h> +#include <string> namespace Botan { @@ -53,6 +54,12 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm } /** + * @return provider information about this implementation. Default is "base", + * might also return "sse2", "avx2", "openssl", or some other arbitrary string. + */ + virtual std::string provider() const { return "base"; } + + /** * Encrypt a block. * @param in The plaintext block to be encrypted as a byte array. * Must be of length block_size(). diff --git a/src/lib/block/idea/idea.cpp b/src/lib/block/idea/idea.cpp index 4182c59a7..85cc5e757 100644 --- a/src/lib/block/idea/idea.cpp +++ b/src/lib/block/idea/idea.cpp @@ -7,6 +7,7 @@ #include <botan/idea.h> #include <botan/loadstor.h> +#include <botan/cpuid.h> #include <botan/internal/ct_utils.h> namespace Botan { @@ -108,11 +109,36 @@ void idea_op(const byte in[], byte out[], size_t blocks, const u16bit K[52]) } +std::string IDEA::provider() const + { +#if defined(BOTAN_HAS_IDEA_SSE2) + if(CPUID::has_sse2()) + { + return "sse2"; + } +#endif + + return "base"; + } + /* * IDEA Encryption */ void IDEA::encrypt_n(const byte in[], byte out[], size_t blocks) const { +#if defined(BOTAN_HAS_IDEA_SSE2) + if(CPUID::has_sse2()) + { + while(blocks >= 8) + { + sse2_idea_op_8(in, out, m_EK.data()); + in += 8 * BLOCK_SIZE; + out += 8 * BLOCK_SIZE; + blocks -= 8; + } + } +#endif + idea_op(in, out, blocks, m_EK.data()); } @@ -121,6 +147,19 @@ void IDEA::encrypt_n(const byte in[], byte out[], size_t blocks) const */ void IDEA::decrypt_n(const byte in[], byte out[], size_t blocks) const { +#if defined(BOTAN_HAS_IDEA_SSE2) + if(CPUID::has_sse2()) + { + while(blocks >= 8) + { + sse2_idea_op_8(in, out, m_DK.data()); + in += 8 * BLOCK_SIZE; + out += 8 * BLOCK_SIZE; + blocks -= 8; + } + } +#endif + idea_op(in, out, blocks, m_DK.data()); } diff --git a/src/lib/block/idea/idea.h b/src/lib/block/idea/idea.h index 59f98da9e..eb391a0c8 100644 --- a/src/lib/block/idea/idea.h +++ b/src/lib/block/idea/idea.h @@ -15,27 +15,22 @@ namespace Botan { /** * IDEA */ -class BOTAN_DLL IDEA : public Block_Cipher_Fixed_Params<8, 16> +class BOTAN_DLL IDEA final : public Block_Cipher_Fixed_Params<8, 16> { public: void encrypt_n(const byte in[], byte out[], size_t blocks) const override; void decrypt_n(const byte in[], byte out[], size_t blocks) const override; void clear() override; + + std::string provider() const override; std::string name() const override { return "IDEA"; } BlockCipher* clone() const override { return new IDEA; } - protected: - /** - * @return const reference to encryption subkeys - */ - const secure_vector<u16bit>& get_EK() const { return m_EK; } - - /** - * @return const reference to decryption subkeys - */ - const secure_vector<u16bit>& get_DK() const { return m_DK; } - private: +#if defined(BOTAN_HAS_IDEA_SSE2) + void sse2_idea_op_8(const byte in[64], byte out[64], const u16bit EK[52]) const; +#endif + void key_schedule(const byte[], size_t) override; secure_vector<u16bit> m_EK, m_DK; diff --git a/src/lib/block/idea_sse2/idea_sse2.cpp b/src/lib/block/idea_sse2/idea_sse2.cpp index c7d846e8b..4debfc95a 100644 --- a/src/lib/block/idea_sse2/idea_sse2.cpp +++ b/src/lib/block/idea_sse2/idea_sse2.cpp @@ -5,8 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/idea_sse2.h> -#include <botan/cpuid.h> +#include <botan/idea.h> #include <botan/internal/ct_utils.h> #include <emmintrin.h> @@ -126,10 +125,12 @@ void transpose_out(__m128i& B0, __m128i& B1, __m128i& B2, __m128i& B3) B3 = _mm_unpackhi_epi32(T2, T3); } +} + /* -* IDEA encryption/decryption in SSE2 +* 8 wide IDEA encryption/decryption in SSE2 */ -void idea_op_8(const byte in[64], byte out[64], const u16bit EK[52]) +void IDEA::sse2_idea_op_8(const byte in[64], byte out[64], const u16bit EK[52]) const { CT::poison(in, 64); CT::poison(out, 64); @@ -201,43 +202,3 @@ void idea_op_8(const byte in[64], byte out[64], const u16bit EK[52]) } } - -/* -* IDEA Encryption -*/ -void IDEA_SSE2::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - const u16bit* KS = &this->get_EK()[0]; - - while(blocks >= 8) - { - idea_op_8(in, out, KS); - in += 8 * BLOCK_SIZE; - out += 8 * BLOCK_SIZE; - blocks -= 8; - } - - if(blocks) - IDEA::encrypt_n(in, out, blocks); - } - -/* -* IDEA Decryption -*/ -void IDEA_SSE2::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - const u16bit* KS = &this->get_DK()[0]; - - while(blocks >= 8) - { - idea_op_8(in, out, KS); - in += 8 * BLOCK_SIZE; - out += 8 * BLOCK_SIZE; - blocks -= 8; - } - - if(blocks) - IDEA::decrypt_n(in, out, blocks); - } - -} diff --git a/src/lib/block/idea_sse2/idea_sse2.h b/src/lib/block/idea_sse2/idea_sse2.h deleted file mode 100644 index 9e0df9925..000000000 --- a/src/lib/block/idea_sse2/idea_sse2.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* IDEA in SSE2 -* (C) 2009 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_IDEA_SSE2_H__ -#define BOTAN_IDEA_SSE2_H__ - -#include <botan/idea.h> - -namespace Botan { - -/** -* IDEA in SSE2 -*/ -class BOTAN_DLL IDEA_SSE2 final : public IDEA - { - public: - size_t parallelism() const override { return 8; } - - void encrypt_n(const byte in[], byte out[], size_t blocks) const override; - void decrypt_n(const byte in[], byte out[], size_t blocks) const override; - - BlockCipher* clone() const override { return new IDEA_SSE2; } - }; - -} - -#endif diff --git a/src/lib/block/noekeon/noekeon.cpp b/src/lib/block/noekeon/noekeon.cpp index 01f7491f3..eac0979a4 100644 --- a/src/lib/block/noekeon/noekeon.cpp +++ b/src/lib/block/noekeon/noekeon.cpp @@ -7,6 +7,7 @@ #include <botan/noekeon.h> #include <botan/loadstor.h> +#include <botan/cpuid.h> namespace Botan { @@ -72,6 +73,18 @@ inline void gamma(u32bit& A0, u32bit& A1, u32bit& A2, u32bit& A3) } +std::string Noekeon::provider() const + { +#if defined(BOTAN_HAS_NOEKEON_SIMD) + if(CPUID::has_simd_32()) + { + return "simd"; + } +#endif + + return "base"; + } + /* * Noekeon Round Constants */ @@ -85,6 +98,19 @@ const byte Noekeon::RC[] = { */ void Noekeon::encrypt_n(const byte in[], byte out[], size_t blocks) const { +#if defined(BOTAN_HAS_NOEKEON_SIMD) + if(CPUID::has_simd_32()) + { + while(blocks >= 4) + { + simd_encrypt_4(in, out); + in += 4 * BLOCK_SIZE; + out += 4 * BLOCK_SIZE; + blocks -= 4; + } + } +#endif + for(size_t i = 0; i != blocks; ++i) { u32bit A0 = load_be<u32bit>(in, 0); @@ -123,6 +149,32 @@ void Noekeon::encrypt_n(const byte in[], byte out[], size_t blocks) const */ void Noekeon::decrypt_n(const byte in[], byte out[], size_t blocks) const { +#if defined(BOTAN_HAS_NOEKEON_SIMD) + if(CPUID::has_simd_32()) + { + /* + const size_t blocks4 = blocks / 4; + const size_t blocks_left = blocks % 4; + + in += blocks4 * BLOCK_SIZE; + out += blocks4 * BLOCK_SIZE; + blocks = blocks % 4; + + BOTAN_PARALLEL_FOR(size_t i = 0; i < blocks4; ++i) + { + simd_encrypt_4(in + i*4*BLOCK_SIZE, out + i*4*BLOCK_SIZE); + } + */ + while(blocks >= 4) + { + simd_decrypt_4(in, out); + in += 4 * BLOCK_SIZE; + out += 4 * BLOCK_SIZE; + blocks -= 4; + } + } +#endif + for(size_t i = 0; i != blocks; ++i) { u32bit A0 = load_be<u32bit>(in, 0); diff --git a/src/lib/block/noekeon/noekeon.h b/src/lib/block/noekeon/noekeon.h index 4a3b9de0c..b0aa4218c 100644 --- a/src/lib/block/noekeon/noekeon.h +++ b/src/lib/block/noekeon/noekeon.h @@ -15,32 +15,27 @@ namespace Botan { /** * Noekeon */ -class BOTAN_DLL Noekeon : public Block_Cipher_Fixed_Params<16, 16> +class BOTAN_DLL Noekeon final : public Block_Cipher_Fixed_Params<16, 16> { public: void encrypt_n(const byte in[], byte out[], size_t blocks) const override; void decrypt_n(const byte in[], byte out[], size_t blocks) const override; + std::string provider() const override; void clear() override; std::string name() const override { return "Noekeon"; } BlockCipher* clone() const override { return new Noekeon; } - protected: + private: +#if defined(BOTAN_HAS_NOEKEON_SIMD) + void simd_encrypt_4(const byte in[], byte out[]) const; + void simd_decrypt_4(const byte in[], byte out[]) const; +#endif + /** * The Noekeon round constants */ static const byte RC[17]; - /** - * @return const reference to encryption subkeys - */ - const secure_vector<u32bit>& get_EK() const { return m_EK; } - - /** - * @return const reference to decryption subkeys - */ - const secure_vector<u32bit>& get_DK() const { return m_DK; } - - private: void key_schedule(const byte[], size_t) override; secure_vector<u32bit> m_EK, m_DK; }; diff --git a/src/lib/block/noekeon_simd/info.txt b/src/lib/block/noekeon_simd/info.txt index 3b92eb206..45ff93467 100644 --- a/src/lib/block/noekeon_simd/info.txt +++ b/src/lib/block/noekeon_simd/info.txt @@ -1,4 +1,4 @@ -define NOEKEON_SIMD 20131128 +define NOEKEON_SIMD 20160903 <requires> noekeon diff --git a/src/lib/block/noekeon_simd/noekeon_simd.cpp b/src/lib/block/noekeon_simd/noekeon_simd.cpp index 07fcf19ff..e37412b5f 100644 --- a/src/lib/block/noekeon_simd/noekeon_simd.cpp +++ b/src/lib/block/noekeon_simd/noekeon_simd.cpp @@ -5,7 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/noekeon_simd.h> +#include <botan/noekeon.h> #include <botan/internal/simd_32.h> namespace Botan { @@ -63,115 +63,91 @@ namespace Botan { /* * Noekeon Encryption */ -void Noekeon_SIMD::encrypt_n(const byte in[], byte out[], size_t blocks) const +void Noekeon::simd_encrypt_4(const byte in[], byte out[]) const { - const secure_vector<u32bit>& EK = this->get_EK(); + const SIMD_32 K0 = SIMD_32(m_EK[0]); + const SIMD_32 K1 = SIMD_32(m_EK[1]); + const SIMD_32 K2 = SIMD_32(m_EK[2]); + const SIMD_32 K3 = SIMD_32(m_EK[3]); - SIMD_32 K0 = SIMD_32(EK[0]); - SIMD_32 K1 = SIMD_32(EK[1]); - SIMD_32 K2 = SIMD_32(EK[2]); - SIMD_32 K3 = SIMD_32(EK[3]); + SIMD_32 A0 = SIMD_32::load_be(in ); + SIMD_32 A1 = SIMD_32::load_be(in + 16); + SIMD_32 A2 = SIMD_32::load_be(in + 32); + SIMD_32 A3 = SIMD_32::load_be(in + 48); - while(blocks >= 4) - { - SIMD_32 A0 = SIMD_32::load_be(in ); - SIMD_32 A1 = SIMD_32::load_be(in + 16); - SIMD_32 A2 = SIMD_32::load_be(in + 32); - SIMD_32 A3 = SIMD_32::load_be(in + 48); - - SIMD_32::transpose(A0, A1, A2, A3); - - for(size_t i = 0; i != 16; ++i) - { - A0 ^= SIMD_32(RC[i]); - - NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3); - - A1.rotate_left(1); - A2.rotate_left(5); - A3.rotate_left(2); + SIMD_32::transpose(A0, A1, A2, A3); - NOK_SIMD_GAMMA(A0, A1, A2, A3); - - A1.rotate_right(1); - A2.rotate_right(5); - A3.rotate_right(2); - } + for(size_t i = 0; i != 16; ++i) + { + A0 ^= SIMD_32(RC[i]); - A0 ^= SIMD_32(RC[16]); NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3); - SIMD_32::transpose(A0, A1, A2, A3); + A1.rotate_left(1); + A2.rotate_left(5); + A3.rotate_left(2); - A0.store_be(out); - A1.store_be(out + 16); - A2.store_be(out + 32); - A3.store_be(out + 48); + NOK_SIMD_GAMMA(A0, A1, A2, A3); - in += 64; - out += 64; - blocks -= 4; + A1.rotate_right(1); + A2.rotate_right(5); + A3.rotate_right(2); } - if(blocks) - Noekeon::encrypt_n(in, out, blocks); + A0 ^= SIMD_32(RC[16]); + NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3); + + SIMD_32::transpose(A0, A1, A2, A3); + + A0.store_be(out); + A1.store_be(out + 16); + A2.store_be(out + 32); + A3.store_be(out + 48); } /* * Noekeon Encryption */ -void Noekeon_SIMD::decrypt_n(const byte in[], byte out[], size_t blocks) const +void Noekeon::simd_decrypt_4(const byte in[], byte out[]) const { - const secure_vector<u32bit>& DK = this->get_DK(); + const SIMD_32 K0 = SIMD_32(m_DK[0]); + const SIMD_32 K1 = SIMD_32(m_DK[1]); + const SIMD_32 K2 = SIMD_32(m_DK[2]); + const SIMD_32 K3 = SIMD_32(m_DK[3]); - SIMD_32 K0 = SIMD_32(DK[0]); - SIMD_32 K1 = SIMD_32(DK[1]); - SIMD_32 K2 = SIMD_32(DK[2]); - SIMD_32 K3 = SIMD_32(DK[3]); + SIMD_32 A0 = SIMD_32::load_be(in ); + SIMD_32 A1 = SIMD_32::load_be(in + 16); + SIMD_32 A2 = SIMD_32::load_be(in + 32); + SIMD_32 A3 = SIMD_32::load_be(in + 48); - while(blocks >= 4) - { - SIMD_32 A0 = SIMD_32::load_be(in ); - SIMD_32 A1 = SIMD_32::load_be(in + 16); - SIMD_32 A2 = SIMD_32::load_be(in + 32); - SIMD_32 A3 = SIMD_32::load_be(in + 48); - - SIMD_32::transpose(A0, A1, A2, A3); - - for(size_t i = 0; i != 16; ++i) - { - NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3); + SIMD_32::transpose(A0, A1, A2, A3); - A0 ^= SIMD_32(RC[16-i]); - - A1.rotate_left(1); - A2.rotate_left(5); - A3.rotate_left(2); + for(size_t i = 0; i != 16; ++i) + { + NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3); - NOK_SIMD_GAMMA(A0, A1, A2, A3); + A0 ^= SIMD_32(RC[16-i]); - A1.rotate_right(1); - A2.rotate_right(5); - A3.rotate_right(2); - } + A1.rotate_left(1); + A2.rotate_left(5); + A3.rotate_left(2); - NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3); - A0 ^= SIMD_32(RC[0]); + NOK_SIMD_GAMMA(A0, A1, A2, A3); - SIMD_32::transpose(A0, A1, A2, A3); + A1.rotate_right(1); + A2.rotate_right(5); + A3.rotate_right(2); + } - A0.store_be(out); - A1.store_be(out + 16); - A2.store_be(out + 32); - A3.store_be(out + 48); + NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3); + A0 ^= SIMD_32(RC[0]); - in += 64; - out += 64; - blocks -= 4; - } + SIMD_32::transpose(A0, A1, A2, A3); - if(blocks) - Noekeon::decrypt_n(in, out, blocks); + A0.store_be(out); + A1.store_be(out + 16); + A2.store_be(out + 32); + A3.store_be(out + 48); } } diff --git a/src/lib/block/noekeon_simd/noekeon_simd.h b/src/lib/block/noekeon_simd/noekeon_simd.h deleted file mode 100644 index 7907fc4ca..000000000 --- a/src/lib/block/noekeon_simd/noekeon_simd.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* Noekeon in SIMD -* (C) 2010 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_NOEKEON_SIMD_H__ -#define BOTAN_NOEKEON_SIMD_H__ - -#include <botan/noekeon.h> - -namespace Botan { - -/** -* Noekeon implementation using SIMD operations -*/ -class BOTAN_DLL Noekeon_SIMD final : public Noekeon - { - public: - size_t parallelism() const override { return 4; } - - void encrypt_n(const byte in[], byte out[], size_t blocks) const override; - void decrypt_n(const byte in[], byte out[], size_t blocks) const override; - - BlockCipher* clone() const override { return new Noekeon_SIMD; } - }; - -} - -#endif diff --git a/src/lib/block/serpent/serpent.cpp b/src/lib/block/serpent/serpent.cpp index c35e3e338..07088211d 100644 --- a/src/lib/block/serpent/serpent.cpp +++ b/src/lib/block/serpent/serpent.cpp @@ -9,6 +9,10 @@ #include <botan/loadstor.h> #include <botan/internal/serpent_sbox.h> +#if defined(BOTAN_HAS_SERPENT_SIMD) + #include <botan/cpuid.h> +#endif + namespace Botan { namespace { @@ -53,6 +57,19 @@ inline void i_transform(u32bit& B0, u32bit& B1, u32bit& B2, u32bit& B3) */ void Serpent::encrypt_n(const byte in[], byte out[], size_t blocks) const { +#if defined(BOTAN_HAS_SERPENT_SIMD) + if(CPUID::has_simd_32()) + { + while(blocks >= 4) + { + simd_encrypt_4(in, out); + in += 4 * BLOCK_SIZE; + out += 4 * BLOCK_SIZE; + blocks -= 4; + } + } +#endif + for(size_t i = 0; i != blocks; ++i) { u32bit B0 = load_le<u32bit>(in, 0); @@ -105,6 +122,19 @@ void Serpent::encrypt_n(const byte in[], byte out[], size_t blocks) const */ void Serpent::decrypt_n(const byte in[], byte out[], size_t blocks) const { +#if defined(BOTAN_HAS_SERPENT_SIMD) + if(CPUID::has_simd_32()) + { + while(blocks >= 4) + { + simd_decrypt_4(in, out); + in += 4 * BLOCK_SIZE; + out += 4 * BLOCK_SIZE; + blocks -= 4; + } + } +#endif + for(size_t i = 0; i != blocks; ++i) { u32bit B0 = load_le<u32bit>(in, 0); @@ -201,4 +231,16 @@ void Serpent::clear() zap(m_round_key); } +std::string Serpent::provider() const + { +#if defined(BOTAN_HAS_SERPENT_SIMD) + if(CPUID::has_simd_32()) + { + return "simd"; + } +#endif + + return "base"; + } + } diff --git a/src/lib/block/serpent/serpent.h b/src/lib/block/serpent/serpent.h index b9864cf89..218772e0c 100644 --- a/src/lib/block/serpent/serpent.h +++ b/src/lib/block/serpent/serpent.h @@ -13,18 +13,35 @@ namespace Botan { /** -* Serpent, an AES finalist +* Serpent is the most conservative of the AES finalists +* http://www.cl.cam.ac.uk/~rja14/serpent.html */ -class BOTAN_DLL Serpent : public Block_Cipher_Fixed_Params<16, 16, 32, 8> +class BOTAN_DLL Serpent final : public Block_Cipher_Fixed_Params<16, 16, 32, 8> { public: void encrypt_n(const byte in[], byte out[], size_t blocks) const override; void decrypt_n(const byte in[], byte out[], size_t blocks) const override; void clear() override; + std::string provider() const override; std::string name() const override { return "Serpent"; } BlockCipher* clone() const override { return new Serpent; } + + size_t parallelism() const override { return 4; } + protected: +#if defined(BOTAN_HAS_SERPENT_SIMD) + /** + * Encrypt 4 blocks in parallel using SSE2 or AltiVec + */ + void simd_encrypt_4(const byte in[64], byte out[64]) const; + + /** + * Decrypt 4 blocks in parallel using SSE2 or AltiVec + */ + void simd_decrypt_4(const byte in[64], byte out[64]) const; +#endif + /** * For use by subclasses using SIMD, asm, etc * @return const reference to the key schedule diff --git a/src/lib/block/serpent_simd/info.txt b/src/lib/block/serpent_simd/info.txt index acb0b76d8..eedc92757 100644 --- a/src/lib/block/serpent_simd/info.txt +++ b/src/lib/block/serpent_simd/info.txt @@ -1,14 +1,6 @@ -define SERPENT_SIMD 20131128 +define SERPENT_SIMD 20160903 <requires> serpent simd </requires> - -<source> -serp_simd.cpp -</source> - -<header:public> -serp_simd.h -</header:public> diff --git a/src/lib/block/serpent_simd/serp_simd.cpp b/src/lib/block/serpent_simd/serp_simd.cpp index 02fe7d6d9..7571e5511 100644 --- a/src/lib/block/serpent_simd/serp_simd.cpp +++ b/src/lib/block/serpent_simd/serp_simd.cpp @@ -5,7 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/serp_simd.h> +#include <botan/serpent.h> #include <botan/internal/serpent_sbox.h> #include <botan/internal/simd_32.h> @@ -15,10 +15,10 @@ namespace { #define key_xor(round, B0, B1, B2, B3) \ do { \ - B0 ^= SIMD_32(keys[4*round ]); \ - B1 ^= SIMD_32(keys[4*round+1]); \ - B2 ^= SIMD_32(keys[4*round+2]); \ - B3 ^= SIMD_32(keys[4*round+3]); \ + B0 ^= SIMD_32(m_round_key[4*round ]); \ + B1 ^= SIMD_32(m_round_key[4*round+1]); \ + B2 ^= SIMD_32(m_round_key[4*round+2]); \ + B3 ^= SIMD_32(m_round_key[4*round+3]); \ } while(0); /* @@ -52,12 +52,12 @@ namespace { B0.rotate_right(13); \ } while(0); +} + /* * SIMD Serpent Encryption of 4 blocks in parallel */ -void serpent_encrypt_4(const byte in[64], - byte out[64], - const u32bit keys[132]) +void Serpent::simd_encrypt_4(const byte in[64], byte out[64]) const { SIMD_32 B0 = SIMD_32::load_le(in); SIMD_32 B1 = SIMD_32::load_le(in + 16); @@ -113,9 +113,7 @@ void serpent_encrypt_4(const byte in[64], /* * SIMD Serpent Decryption of 4 blocks in parallel */ -void serpent_decrypt_4(const byte in[64], - byte out[64], - const u32bit keys[132]) +void Serpent::simd_decrypt_4(const byte in[64], byte out[64]) const { SIMD_32 B0 = SIMD_32::load_le(in); SIMD_32 B1 = SIMD_32::load_le(in + 16); @@ -168,48 +166,8 @@ void serpent_decrypt_4(const byte in[64], B3.store_le(out + 48); } -} - #undef key_xor #undef transform #undef i_transform -/* -* Serpent Encryption -*/ -void Serpent_SIMD::encrypt_n(const byte in[], byte out[], size_t blocks) const - { - const u32bit* KS = &(this->get_round_keys()[0]); - - while(blocks >= 4) - { - serpent_encrypt_4(in, out, KS); - in += 4 * BLOCK_SIZE; - out += 4 * BLOCK_SIZE; - blocks -= 4; - } - - if(blocks) - Serpent::encrypt_n(in, out, blocks); - } - -/* -* Serpent Decryption -*/ -void Serpent_SIMD::decrypt_n(const byte in[], byte out[], size_t blocks) const - { - const u32bit* KS = &(this->get_round_keys()[0]); - - while(blocks >= 4) - { - serpent_decrypt_4(in, out, KS); - in += 4 * BLOCK_SIZE; - out += 4 * BLOCK_SIZE; - blocks -= 4; - } - - if(blocks) - Serpent::decrypt_n(in, out, blocks); - } - } diff --git a/src/lib/block/serpent_simd/serp_simd.h b/src/lib/block/serpent_simd/serp_simd.h deleted file mode 100644 index e10d4cfe2..000000000 --- a/src/lib/block/serpent_simd/serp_simd.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* Serpent (SIMD) -* (C) 2009 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_SERPENT_SIMD_H__ -#define BOTAN_SERPENT_SIMD_H__ - -#include <botan/serpent.h> - -namespace Botan { - -/** -* Serpent implementation using SIMD -*/ -class BOTAN_DLL Serpent_SIMD final : public Serpent - { - public: - size_t parallelism() const override { return 4; } - - void encrypt_n(const byte in[], byte out[], size_t blocks) const override; - void decrypt_n(const byte in[], byte out[], size_t blocks) const override; - - BlockCipher* clone() const override { return new Serpent_SIMD; } - }; - -} - -#endif diff --git a/src/lib/block/threefish/threefish.cpp b/src/lib/block/threefish/threefish.cpp index c8e2aff85..f592021fb 100644 --- a/src/lib/block/threefish/threefish.cpp +++ b/src/lib/block/threefish/threefish.cpp @@ -1,12 +1,13 @@ /* * Threefish-512 -* (C) 2013,2014 Jack Lloyd +* (C) 2013,2014,2016 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #include <botan/threefish.h> #include <botan/loadstor.h> +#include <botan/cpuid.h> namespace Botan { @@ -97,11 +98,30 @@ void Threefish_512::skein_feedfwd(const secure_vector<u64bit>& M, m_K[4] ^ m_K[5] ^ m_K[6] ^ m_K[7] ^ 0x1BD11BDAA9FC1A22; } +std::string Threefish_512::provider() const + { +#if defined(BOTAN_HAS_THREEFISH_512_AVX2) + if(CPUID::has_avx2()) + { + return "avx2"; + } +#endif + + return "base"; + } + void Threefish_512::encrypt_n(const byte in[], byte out[], size_t blocks) const { BOTAN_ASSERT(m_K.size() == 9, "Key was set"); BOTAN_ASSERT(m_T.size() == 3, "Tweak was set"); +#if defined(BOTAN_HAS_THREEFISH_512_AVX2) + if(CPUID::has_avx2()) + { + return avx2_encrypt_n(in, out, blocks); + } +#endif + for(size_t i = 0; i != blocks; ++i) { u64bit X0 = load_le<u64bit>(in, 0); @@ -141,6 +161,13 @@ void Threefish_512::decrypt_n(const byte in[], byte out[], size_t blocks) const BOTAN_ASSERT(m_K.size() == 9, "Key was set"); BOTAN_ASSERT(m_T.size() == 3, "Tweak was set"); +#if defined(BOTAN_HAS_THREEFISH_512_AVX2) + if(CPUID::has_avx2()) + { + return avx2_decrypt_n(in, out, blocks); + } +#endif + #define THREEFISH_ROUND(X0,X1,X2,X3,X4,X5,X6,X7,ROT1,ROT2,ROT3,ROT4) \ do { \ X4 ^= X0; \ diff --git a/src/lib/block/threefish/threefish.h b/src/lib/block/threefish/threefish.h index 373600885..b02239c93 100644 --- a/src/lib/block/threefish/threefish.h +++ b/src/lib/block/threefish/threefish.h @@ -15,7 +15,7 @@ namespace Botan { /** * Threefish-512 */ -class BOTAN_DLL Threefish_512 : public Block_Cipher_Fixed_Params<64, 64> +class BOTAN_DLL Threefish_512 final : public Block_Cipher_Fixed_Params<64, 64> { public: void encrypt_n(const byte in[], byte out[], size_t blocks) const override; @@ -24,12 +24,19 @@ class BOTAN_DLL Threefish_512 : public Block_Cipher_Fixed_Params<64, 64> void set_tweak(const byte tweak[], size_t len); void clear() override; + std::string provider() const override; std::string name() const override { return "Threefish-512"; } BlockCipher* clone() const override { return new Threefish_512; } protected: const secure_vector<u64bit>& get_T() const { return m_T; } const secure_vector<u64bit>& get_K() const { return m_K; } private: + +#if defined(BOTAN_HAS_THREEFISH_512_AVX2) + void avx2_encrypt_n(const byte in[], byte out[], size_t blocks) const; + void avx2_decrypt_n(const byte in[], byte out[], size_t blocks) const; +#endif + void key_schedule(const byte key[], size_t key_len) override; // Interface for Skein diff --git a/src/lib/block/threefish_avx2/info.txt b/src/lib/block/threefish_avx2/info.txt index 4a3275092..907253c64 100644 --- a/src/lib/block/threefish_avx2/info.txt +++ b/src/lib/block/threefish_avx2/info.txt @@ -1,4 +1,4 @@ -define THREEFISH_512_AVX2 20131224 +define THREEFISH_512_AVX2 20160903 need_isa avx2 diff --git a/src/lib/block/threefish_avx2/threefish_avx2.cpp b/src/lib/block/threefish_avx2/threefish_avx2.cpp index 9b808a221..e0321812a 100644 --- a/src/lib/block/threefish_avx2/threefish_avx2.cpp +++ b/src/lib/block/threefish_avx2/threefish_avx2.cpp @@ -5,8 +5,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/threefish_avx2.h> -#include <botan/cpuid.h> +#include <botan/threefish.h> #include <immintrin.h> namespace Botan { @@ -38,7 +37,8 @@ inline void rotate_keys(__m256i& R0, __m256i& R1, __m256i R2) { /* Behold. The key schedule progresses like so. The values - loop back to the originals after the rounds are complete. + loop back to the originals after the rounds are complete + so we don't need to reload for starting the next block. R0 R1 R2 K1,K2,K3 (7,5,3,1),(8,6,4,2),(0,7,5,3) @@ -71,7 +71,7 @@ inline void rotate_keys(__m256i& R0, __m256i& R1, __m256i R2) } -void Threefish_512_AVX2::encrypt_n(const byte in[], byte out[], size_t blocks) const +void Threefish_512::avx2_encrypt_n(const byte in[], byte out[], size_t blocks) const { const u64bit* K = &get_K()[0]; const u64bit* T_64 = &get_T()[0]; @@ -245,7 +245,7 @@ void Threefish_512_AVX2::encrypt_n(const byte in[], byte out[], size_t blocks) c #undef THREEFISH_INJECT_KEY_2 } -void Threefish_512_AVX2::decrypt_n(const byte in[], byte out[], size_t blocks) const +void Threefish_512::avx2_decrypt_n(const byte in[], byte out[], size_t blocks) const { const u64bit* K = &get_K()[0]; const u64bit* T_64 = &get_T()[0]; diff --git a/src/lib/block/threefish_avx2/threefish_avx2.h b/src/lib/block/threefish_avx2/threefish_avx2.h deleted file mode 100644 index fbf2f9d8a..000000000 --- a/src/lib/block/threefish_avx2/threefish_avx2.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* Threefish-512 in AVX2 -* (C) 2013 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_THREEFISH_AVX2_H__ -#define BOTAN_THREEFISH_AVX2_H__ - -#include <botan/threefish.h> - -namespace Botan { - -/** -* Threefish-512 -*/ -class BOTAN_DLL Threefish_512_AVX2 final : public Threefish_512 - { - private: - void encrypt_n(const byte in[], byte out[], size_t blocks) const override; - void decrypt_n(const byte in[], byte out[], size_t blocks) const override; - - /* TODO: - void skein_feedfwd(const secure_vector<u64bit>& M, - const secure_vector<u64bit>& T) override; - */ - - BlockCipher* clone() const override { return new Threefish_512_AVX2; } - }; - -} - -#endif |