aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/block/aes
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-09-03 14:17:33 -0400
committerJack Lloyd <[email protected]>2016-09-15 09:23:22 -0400
commitbe4655148cfc8cb048fd53de0965cc5e939c4cbc (patch)
treed441a6a5941d968fce80dd50a5f6010855714a77 /src/lib/block/aes
parent272fcf00572432f64085b10132e364740d7eb093 (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.cpp126
-rw-r--r--src/lib/block/aes/aes.h36
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;