diff options
Diffstat (limited to 'src/lib')
32 files changed, 460 insertions, 708 deletions
diff --git a/src/lib/block/aes/aes.cpp b/src/lib/block/aes/aes.cpp index 6ec21cb0c..eb24ce5a3 100644 --- a/src/lib/block/aes/aes.cpp +++ b/src/lib/block/aes/aes.cpp @@ -420,16 +420,58 @@ void aes_key_schedule(const byte key[], size_t length, 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 +485,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 +550,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..d6b334d3c 100644 --- a/src/lib/block/aes/aes.h +++ b/src/lib/block/aes/aes.h @@ -28,6 +28,18 @@ class BOTAN_DLL AES_128 final : public Block_Cipher_Fixed_Params<16, 16> 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; }; @@ -46,6 +58,18 @@ class BOTAN_DLL AES_192 final : public Block_Cipher_Fixed_Params<16, 24> 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; @@ -66,6 +90,18 @@ class BOTAN_DLL AES_256 final : public Block_Cipher_Fixed_Params<16, 32> 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/idea/idea.cpp b/src/lib/block/idea/idea.cpp index 4182c59a7..db55c5c26 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 { @@ -113,6 +114,19 @@ void idea_op(const byte in[], byte out[], size_t blocks, const u16bit K[52]) */ 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 +135,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..063ec65c4 100644 --- a/src/lib/block/idea/idea.h +++ b/src/lib/block/idea/idea.h @@ -15,7 +15,7 @@ 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; @@ -24,18 +24,11 @@ class BOTAN_DLL IDEA : public Block_Cipher_Fixed_Params<8, 16> void clear() 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..5e7c0229e 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 { @@ -85,6 +86,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 +137,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..30c15a001 100644 --- a/src/lib/block/noekeon/noekeon.h +++ b/src/lib/block/noekeon/noekeon.h @@ -15,7 +15,7 @@ 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; @@ -24,23 +24,17 @@ class BOTAN_DLL Noekeon : public Block_Cipher_Fixed_Params<16, 16> 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..1e3699914 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); diff --git a/src/lib/block/serpent/serpent.h b/src/lib/block/serpent/serpent.h index b9864cf89..8f854678a 100644 --- a/src/lib/block/serpent/serpent.h +++ b/src/lib/block/serpent/serpent.h @@ -13,9 +13,10 @@ 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; @@ -24,7 +25,22 @@ class BOTAN_DLL Serpent : public Block_Cipher_Fixed_Params<16, 16, 32, 8> void clear() 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..a4c99936c 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 { @@ -102,6 +103,13 @@ 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_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 +149,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_AVX2) + if(CPUID::has_avx2()) + { + return avx2_dencrypt_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..270e71354 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; @@ -30,6 +30,12 @@ class BOTAN_DLL Threefish_512 : public Block_Cipher_Fixed_Params<64, 64> 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 diff --git a/src/lib/hash/hash.cpp b/src/lib/hash/hash.cpp index 42a7666b6..5a31763d1 100644 --- a/src/lib/hash/hash.cpp +++ b/src/lib/hash/hash.cpp @@ -45,10 +45,6 @@ #include <botan/sha160.h> #endif -#if defined(BOTAN_HAS_SHA1_SSE2) - #include <botan/sha1_sse2.h> -#endif - #if defined(BOTAN_HAS_SHA2_32) #include <botan/sha2_32.h> #endif @@ -155,11 +151,6 @@ BOTAN_REGISTER_HASH_NAMED_NOARGS(RIPEMD_160, "RIPEMD-160"); BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_160, "SHA-160"); #endif -#if defined(BOTAN_HAS_SHA1_SSE2) -BOTAN_REGISTER_HASH_NOARGS_IF(CPUID::has_sse2(), SHA_160_SSE2, "SHA-160", - "sse2", BOTAN_SIMD_ALGORITHM_PRIO); -#endif - #if defined(BOTAN_HAS_SHA2_32) BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_224, "SHA-224"); BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_256, "SHA-256"); diff --git a/src/lib/hash/sha1/sha160.cpp b/src/lib/hash/sha1/sha160.cpp index 21e87465a..87738fb00 100644 --- a/src/lib/hash/sha1/sha160.cpp +++ b/src/lib/hash/sha1/sha160.cpp @@ -6,6 +6,7 @@ */ #include <botan/sha160.h> +#include <botan/cpuid.h> namespace Botan { @@ -60,9 +61,19 @@ void SHA_160::compress_n(const byte input[], size_t blocks) { using namespace SHA1_F; +#if defined(BOTAN_HAS_SHA1_SSE2) + if(CPUID::has_sse2()) + { + return sse2_compress_n(m_digest, input, blocks); + } + +#endif + u32bit A = m_digest[0], B = m_digest[1], C = m_digest[2], D = m_digest[3], E = m_digest[4]; + m_W.resize(80); + for(size_t i = 0; i != blocks; ++i) { load_be(m_W.data(), input, 16); diff --git a/src/lib/hash/sha1/sha160.h b/src/lib/hash/sha1/sha160.h index b4a161c14..d7860834f 100644 --- a/src/lib/hash/sha1/sha160.h +++ b/src/lib/hash/sha1/sha160.h @@ -1,6 +1,6 @@ /* * SHA-160 -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2007,2016 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -15,7 +15,7 @@ namespace Botan { /** * NIST's SHA-160 */ -class BOTAN_DLL SHA_160 : public MDx_HashFunction +class BOTAN_DLL SHA_160 final : public MDx_HashFunction { public: std::string name() const override { return "SHA-160"; } @@ -24,37 +24,36 @@ class BOTAN_DLL SHA_160 : public MDx_HashFunction void clear() override; - SHA_160() : MDx_HashFunction(64, true, true), m_digest(5), m_W(80) - { - clear(); - } - protected: - /** - * Set a custom size for the W array. Normally 80, but some - * subclasses need slightly more for best performance/internal - * constraints - * @param W_size how big to make W - */ - explicit SHA_160(size_t W_size) : - MDx_HashFunction(64, true, true), m_digest(5), m_W(W_size) + SHA_160() : MDx_HashFunction(64, true, true), m_digest(5) { clear(); } + private: void compress_n(const byte[], size_t blocks) override; + +#if defined(BOTAN_HAS_SHA1_SSE2) + static void sse2_compress_n(secure_vector<u32bit>& digest, + const byte blocks[], + size_t block_count); +#endif + + void copy_out(byte[]) override; /** - * The digest value, exposed for use by subclasses (asm, SSE2) + * The digest value */ secure_vector<u32bit> m_digest; /** - * The message buffer, exposed for use by subclasses (asm, SSE2) + * The message buffer */ secure_vector<u32bit> m_W; }; +typedef SHA_160 SHA_1; + } #endif diff --git a/src/lib/hash/sha1_sse2/info.txt b/src/lib/hash/sha1_sse2/info.txt index 78f5540e7..e352364ec 100644 --- a/src/lib/hash/sha1_sse2/info.txt +++ b/src/lib/hash/sha1_sse2/info.txt @@ -1,4 +1,4 @@ -define SHA1_SSE2 20131128 +define SHA1_SSE2 20160803 need_isa sse2 diff --git a/src/lib/hash/sha1_sse2/sha1_sse2.cpp b/src/lib/hash/sha1_sse2/sha1_sse2.cpp index 14ad88bc4..2ece541b0 100644 --- a/src/lib/hash/sha1_sse2/sha1_sse2.cpp +++ b/src/lib/hash/sha1_sse2/sha1_sse2.cpp @@ -7,8 +7,7 @@ * Botan is released under the Simplified BSD License (see license.txt) */ -#include <botan/sha1_sse2.h> -#include <botan/cpuid.h> +#include <botan/sha160.h> #include <emmintrin.h> namespace Botan { @@ -152,7 +151,8 @@ inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) /* * SHA-160 Compression Function using SSE for message expansion */ -void SHA_160_SSE2::compress_n(const byte input_bytes[], size_t blocks) +//static +void SHA_160::sse2_compress_n(secure_vector<uint32_t>& digest, const byte input[], size_t blocks) { using namespace SHA1_SSE2_F; @@ -161,13 +161,13 @@ void SHA_160_SSE2::compress_n(const byte input_bytes[], size_t blocks) const __m128i K40_59 = _mm_set1_epi32(0x8F1BBCDC); const __m128i K60_79 = _mm_set1_epi32(0xCA62C1D6); - u32bit A = m_digest[0], - B = m_digest[1], - C = m_digest[2], - D = m_digest[3], - E = m_digest[4]; + u32bit A = digest[0], + B = digest[1], + C = digest[2], + D = digest[3], + E = digest[4]; - const __m128i* input = reinterpret_cast<const __m128i*>(input_bytes); + const __m128i* input_mm = reinterpret_cast<const __m128i*>(input); for(size_t i = 0; i != blocks; ++i) { @@ -178,16 +178,16 @@ void SHA_160_SSE2::compress_n(const byte input_bytes[], size_t blocks) v4si P0, P1, P2, P3; - __m128i W0 = _mm_loadu_si128(&input[0]); + __m128i W0 = _mm_loadu_si128(&input_mm[0]); prep00_15(P0, W0); - __m128i W1 = _mm_loadu_si128(&input[1]); + __m128i W1 = _mm_loadu_si128(&input_mm[1]); prep00_15(P1, W1); - __m128i W2 = _mm_loadu_si128(&input[2]); + __m128i W2 = _mm_loadu_si128(&input_mm[2]); prep00_15(P2, W2); - __m128i W3 = _mm_loadu_si128(&input[3]); + __m128i W3 = _mm_loadu_si128(&input_mm[3]); prep00_15(P3, W3); /* @@ -316,13 +316,13 @@ void SHA_160_SSE2::compress_n(const byte input_bytes[], size_t blocks) F4(C, D, E, A, B, GET_P_32(P3, 2)); F4(B, C, D, E, A, GET_P_32(P3, 3)); - A = (m_digest[0] += A); - B = (m_digest[1] += B); - C = (m_digest[2] += C); - D = (m_digest[3] += D); - E = (m_digest[4] += E); + A = (digest[0] += A); + B = (digest[1] += B); + C = (digest[2] += C); + D = (digest[3] += D); + E = (digest[4] += E); - input += (hash_block_size() / 16); + input_mm += (64 / 16); } #undef GET_P_32 diff --git a/src/lib/hash/sha1_sse2/sha1_sse2.h b/src/lib/hash/sha1_sse2/sha1_sse2.h deleted file mode 100644 index a38600762..000000000 --- a/src/lib/hash/sha1_sse2/sha1_sse2.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -* SHA-160 -* (C) 1999-2007 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_SHA_160_SSE2_H__ -#define BOTAN_SHA_160_SSE2_H__ - -#include <botan/sha160.h> - -namespace Botan { - -/** -* SHA-160 using SSE2 for the message expansion -*/ -class BOTAN_DLL SHA_160_SSE2 final : public SHA_160 - { - public: - HashFunction* clone() const override { return new SHA_160_SSE2; } - SHA_160_SSE2() : SHA_160(0) {} // no W needed - private: - void compress_n(const byte[], size_t blocks) override; - }; - -} - -#endif |