diff options
author | Jack Lloyd <[email protected]> | 2016-09-03 14:17:33 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2016-09-15 09:23:22 -0400 |
commit | be4655148cfc8cb048fd53de0965cc5e939c4cbc (patch) | |
tree | d441a6a5941d968fce80dd50a5f6010855714a77 /src/lib/block/aes | |
parent | 272fcf00572432f64085b10132e364740d7eb093 (diff) |
Merge optimized implementations into base class
Various algorithms had an optimized implementation (for SSE2, AVX2, etc)
which was offered alongside the 'base' implementation. This is
admittedly very useful for testing, but it breaks user expectations in
bad ways. See GH #477 for background.
Now encrypting with `AES_128` (say) just runs whatever implementation
is best on the current processor/build.
Diffstat (limited to 'src/lib/block/aes')
-rw-r--r-- | src/lib/block/aes/aes.cpp | 126 | ||||
-rw-r--r-- | src/lib/block/aes/aes.h | 36 |
2 files changed, 162 insertions, 0 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; |