aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/block
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/block')
-rw-r--r--src/lib/block/aes/aes.cpp149
-rw-r--r--src/lib/block/aes/aes.h40
-rw-r--r--src/lib/block/aes_ni/aes_ni.cpp48
-rw-r--r--src/lib/block/aes_ni/aes_ni.h77
-rw-r--r--src/lib/block/aes_ssse3/aes_ssse3.cpp39
-rw-r--r--src/lib/block/aes_ssse3/aes_ssse3.h71
-rw-r--r--src/lib/block/block_cipher.cpp68
-rw-r--r--src/lib/block/block_cipher.h7
-rw-r--r--src/lib/block/idea/idea.cpp39
-rw-r--r--src/lib/block/idea/idea.h19
-rw-r--r--src/lib/block/idea_sse2/idea_sse2.cpp49
-rw-r--r--src/lib/block/idea_sse2/idea_sse2.h31
-rw-r--r--src/lib/block/noekeon/noekeon.cpp52
-rw-r--r--src/lib/block/noekeon/noekeon.h21
-rw-r--r--src/lib/block/noekeon_simd/info.txt2
-rw-r--r--src/lib/block/noekeon_simd/noekeon_simd.cpp142
-rw-r--r--src/lib/block/noekeon_simd/noekeon_simd.h31
-rw-r--r--src/lib/block/serpent/serpent.cpp42
-rw-r--r--src/lib/block/serpent/serpent.h21
-rw-r--r--src/lib/block/serpent_simd/info.txt10
-rw-r--r--src/lib/block/serpent_simd/serp_simd.cpp60
-rw-r--r--src/lib/block/serpent_simd/serp_simd.h31
-rw-r--r--src/lib/block/threefish/threefish.cpp29
-rw-r--r--src/lib/block/threefish/threefish.h9
-rw-r--r--src/lib/block/threefish_avx2/info.txt2
-rw-r--r--src/lib/block/threefish_avx2/threefish_avx2.cpp10
-rw-r--r--src/lib/block/threefish_avx2/threefish_avx2.h34
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