aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-09-15 09:16:46 -0400
committerJack Lloyd <[email protected]>2016-09-15 09:25:49 -0400
commit04bf8dc51861bab37d6260de8b318dc71ea4bba7 (patch)
tree03cf4b8d607607444049bc2b9880abc4c1fc6a8e
parenta7eba3629cc0d76444f5241fb4b9e8793ddb61cd (diff)
Add T::provider() to allow user to inquire about implementation used
For block ciphers, stream ciphers, hashes, MACs, and cipher modes. Cipher_Mode already had it, with a slightly different usage.
-rw-r--r--src/lib/block/aes/aes.cpp23
-rw-r--r--src/lib/block/aes/aes.h4
-rw-r--r--src/lib/block/block_cipher.h8
-rw-r--r--src/lib/block/idea/idea.cpp12
-rw-r--r--src/lib/block/idea/idea.h2
-rw-r--r--src/lib/block/noekeon/noekeon.cpp12
-rw-r--r--src/lib/block/noekeon/noekeon.h1
-rw-r--r--src/lib/block/serpent/serpent.cpp12
-rw-r--r--src/lib/block/serpent/serpent.h1
-rw-r--r--src/lib/block/threefish/threefish.cpp12
-rw-r--r--src/lib/block/threefish/threefish.h1
-rw-r--r--src/lib/hash/hash.h7
-rw-r--r--src/lib/mac/mac.h8
-rw-r--r--src/lib/modes/aead/gcm/gcm.cpp10
-rw-r--r--src/lib/modes/aead/gcm/gcm.h2
-rw-r--r--src/lib/modes/cipher_mode.h15
-rw-r--r--src/lib/prov/openssl/openssl_block.cpp1
-rw-r--r--src/lib/prov/openssl/openssl_hash.cpp1
-rw-r--r--src/lib/prov/openssl/openssl_rc4.cpp2
-rw-r--r--src/lib/stream/chacha/chacha.cpp12
-rw-r--r--src/lib/stream/chacha/chacha.h2
-rw-r--r--src/lib/stream/stream_cipher.h7
-rw-r--r--src/tests/test_block.cpp8
-rw-r--r--src/tests/test_hash.cpp8
-rw-r--r--src/tests/test_mac.cpp9
-rw-r--r--src/tests/test_modes.cpp1
-rw-r--r--src/tests/test_stream.cpp8
-rw-r--r--src/tests/tests.cpp7
-rw-r--r--src/tests/tests.h2
29 files changed, 178 insertions, 20 deletions
diff --git a/src/lib/block/aes/aes.cpp b/src/lib/block/aes/aes.cpp
index eb24ce5a3..9483dc0eb 100644
--- a/src/lib/block/aes/aes.cpp
+++ b/src/lib/block/aes/aes.cpp
@@ -416,8 +416,31 @@ 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";
+ }
+
}
+const char* AES_128::provider() const { return aes_provider(); }
+const char* AES_192::provider() const { return aes_provider(); }
+const char* 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)
diff --git a/src/lib/block/aes/aes.h b/src/lib/block/aes/aes.h
index d6b334d3c..e22e96e00 100644
--- a/src/lib/block/aes/aes.h
+++ b/src/lib/block/aes/aes.h
@@ -23,6 +23,7 @@ class BOTAN_DLL AES_128 final : public Block_Cipher_Fixed_Params<16, 16>
void clear() override;
+ const char* provider() const override;
std::string name() const override { return "AES-128"; }
BlockCipher* clone() const override { return new AES_128; }
private:
@@ -55,6 +56,7 @@ class BOTAN_DLL AES_192 final : public Block_Cipher_Fixed_Params<16, 24>
void clear() override;
+ const char* provider() const override;
std::string name() const override { return "AES-192"; }
BlockCipher* clone() const override { return new AES_192; }
private:
@@ -87,6 +89,8 @@ class BOTAN_DLL AES_256 final : public Block_Cipher_Fixed_Params<16, 32>
void clear() override;
+ const char* provider() const override;
+
std::string name() const override { return "AES-256"; }
BlockCipher* clone() const override { return new AES_256; }
private:
diff --git a/src/lib/block/block_cipher.h b/src/lib/block/block_cipher.h
index 0f4c2c1c5..68fc0f487 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,13 @@ 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.
+ * The return value is guaranteed to point to a string literal constant.
+ */
+ virtual const char* 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 db55c5c26..8616b7765 100644
--- a/src/lib/block/idea/idea.cpp
+++ b/src/lib/block/idea/idea.cpp
@@ -109,6 +109,18 @@ void idea_op(const byte in[], byte out[], size_t blocks, const u16bit K[52])
}
+const char* IDEA::provider() const
+ {
+#if defined(BOTAN_HAS_IDEA_SSE2)
+ if(CPUID::has_sse2())
+ {
+ return "sse2";
+ }
+#endif
+
+ return "base";
+ }
+
/*
* IDEA Encryption
*/
diff --git a/src/lib/block/idea/idea.h b/src/lib/block/idea/idea.h
index 063ec65c4..4a72685c8 100644
--- a/src/lib/block/idea/idea.h
+++ b/src/lib/block/idea/idea.h
@@ -22,6 +22,8 @@ class BOTAN_DLL IDEA final : public Block_Cipher_Fixed_Params<8, 16>
void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
void clear() override;
+
+ const char* provider() const override;
std::string name() const override { return "IDEA"; }
BlockCipher* clone() const override { return new IDEA; }
private:
diff --git a/src/lib/block/noekeon/noekeon.cpp b/src/lib/block/noekeon/noekeon.cpp
index 5e7c0229e..fbafe092e 100644
--- a/src/lib/block/noekeon/noekeon.cpp
+++ b/src/lib/block/noekeon/noekeon.cpp
@@ -73,6 +73,18 @@ inline void gamma(u32bit& A0, u32bit& A1, u32bit& A2, u32bit& A3)
}
+const char* Noekeon::provider() const
+ {
+#if defined(BOTAN_HAS_NOEKEON_SIMD)
+ if(CPUID::has_simd_32())
+ {
+ return "simd";
+ }
+#endif
+
+ return "base";
+ }
+
/*
* Noekeon Round Constants
*/
diff --git a/src/lib/block/noekeon/noekeon.h b/src/lib/block/noekeon/noekeon.h
index 30c15a001..31069eb75 100644
--- a/src/lib/block/noekeon/noekeon.h
+++ b/src/lib/block/noekeon/noekeon.h
@@ -21,6 +21,7 @@ class BOTAN_DLL Noekeon final : public Block_Cipher_Fixed_Params<16, 16>
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;
+ const char* provider() const override;
void clear() override;
std::string name() const override { return "Noekeon"; }
BlockCipher* clone() const override { return new Noekeon; }
diff --git a/src/lib/block/serpent/serpent.cpp b/src/lib/block/serpent/serpent.cpp
index 1e3699914..f2a6035f1 100644
--- a/src/lib/block/serpent/serpent.cpp
+++ b/src/lib/block/serpent/serpent.cpp
@@ -231,4 +231,16 @@ void Serpent::clear()
zap(m_round_key);
}
+const char* 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 8f854678a..72c26d452 100644
--- a/src/lib/block/serpent/serpent.h
+++ b/src/lib/block/serpent/serpent.h
@@ -23,6 +23,7 @@ class BOTAN_DLL Serpent final : public Block_Cipher_Fixed_Params<16, 16, 32, 8>
void decrypt_n(const byte in[], byte out[], size_t blocks) const override;
void clear() override;
+ const char* provider() const override;
std::string name() const override { return "Serpent"; }
BlockCipher* clone() const override { return new Serpent; }
diff --git a/src/lib/block/threefish/threefish.cpp b/src/lib/block/threefish/threefish.cpp
index 33b3e25c8..4ba834c94 100644
--- a/src/lib/block/threefish/threefish.cpp
+++ b/src/lib/block/threefish/threefish.cpp
@@ -98,6 +98,18 @@ void Threefish_512::skein_feedfwd(const secure_vector<u64bit>& M,
m_K[4] ^ m_K[5] ^ m_K[6] ^ m_K[7] ^ 0x1BD11BDAA9FC1A22;
}
+const char* 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");
diff --git a/src/lib/block/threefish/threefish.h b/src/lib/block/threefish/threefish.h
index 270e71354..230c742f3 100644
--- a/src/lib/block/threefish/threefish.h
+++ b/src/lib/block/threefish/threefish.h
@@ -24,6 +24,7 @@ class BOTAN_DLL Threefish_512 final : public Block_Cipher_Fixed_Params<64, 64>
void set_tweak(const byte tweak[], size_t len);
void clear() override;
+ const char* provider() const override;
std::string name() const override { return "Threefish-512"; }
BlockCipher* clone() const override { return new Threefish_512; }
protected:
diff --git a/src/lib/hash/hash.h b/src/lib/hash/hash.h
index ac1c22a65..0f35685d4 100644
--- a/src/lib/hash/hash.h
+++ b/src/lib/hash/hash.h
@@ -40,6 +40,13 @@ class BOTAN_DLL HashFunction : public Buffered_Computation
*/
virtual HashFunction* clone() const = 0;
+ /**
+ * @return provider information about this implementation. Default is "base",
+ * might also return "sse2", "avx2", "openssl", or some other arbitrary string.
+ * The return value is guaranteed to point to a string literal constant.
+ */
+ virtual const char* provider() const { return "base"; }
+
HashFunction();
virtual ~HashFunction();
diff --git a/src/lib/mac/mac.h b/src/lib/mac/mac.h
index fe3388f3b..1fbb36824 100644
--- a/src/lib/mac/mac.h
+++ b/src/lib/mac/mac.h
@@ -51,6 +51,14 @@ class BOTAN_DLL MessageAuthenticationCode : public Buffered_Computation,
* Get a new object representing the same algorithm as *this
*/
virtual MessageAuthenticationCode* clone() const = 0;
+
+ /**
+ * @return provider information about this implementation. Default is "base",
+ * might also return "sse2", "avx2", "openssl", or some other arbitrary string.
+ * The return value is guaranteed to point to a string literal constant.
+ */
+ virtual const char* provider() const { return "base"; }
+
};
typedef MessageAuthenticationCode MAC;
diff --git a/src/lib/modes/aead/gcm/gcm.cpp b/src/lib/modes/aead/gcm/gcm.cpp
index e23551cb4..590c0d0ce 100644
--- a/src/lib/modes/aead/gcm/gcm.cpp
+++ b/src/lib/modes/aead/gcm/gcm.cpp
@@ -185,6 +185,16 @@ std::string GCM_Mode::name() const
return (m_cipher_name + "/GCM");
}
+const char* GCM_Mode::provider() const
+ {
+#if defined(BOTAN_HAS_GCM_CLMUL)
+ if(CPUID::has_clmul())
+ return "clmul";
+#endif
+
+ return "base";
+ }
+
size_t GCM_Mode::update_granularity() const
{
return m_BS;
diff --git a/src/lib/modes/aead/gcm/gcm.h b/src/lib/modes/aead/gcm/gcm.h
index ba0d6cad8..f0176f36a 100644
--- a/src/lib/modes/aead/gcm/gcm.h
+++ b/src/lib/modes/aead/gcm/gcm.h
@@ -36,6 +36,8 @@ class BOTAN_DLL GCM_Mode : public AEAD_Mode
size_t tag_size() const override { return m_tag_size; }
void clear() override;
+
+ const char* provider() const override;
protected:
GCM_Mode(BlockCipher* cipher, size_t tag_size);
diff --git a/src/lib/modes/cipher_mode.h b/src/lib/modes/cipher_mode.h
index 73a5f7d96..fa4c0aa8d 100644
--- a/src/lib/modes/cipher_mode.h
+++ b/src/lib/modes/cipher_mode.h
@@ -113,14 +113,6 @@ class BOTAN_DLL Cipher_Mode
*/
virtual bool valid_nonce_length(size_t nonce_len) const = 0;
- /**
- * Return some short name describing the provider of this tranformation.
- * Useful in cases where multiple implementations are available (eg,
- * different implementations of AES). Default "core" is used for the
- * 'standard' implementation included in the library.
- */
- virtual std::string provider() const { return "core"; }
-
virtual std::string name() const = 0;
virtual void clear() = 0;
@@ -174,6 +166,13 @@ class BOTAN_DLL Cipher_Mode
key_schedule(key, length);
}
+ /**
+ * @return provider information about this implementation. Default is "base",
+ * might also return "sse2", "avx2", "openssl", or some other arbitrary string.
+ * The return value is guaranteed to point to a string literal constant.
+ */
+ virtual const char* provider() const { return "base"; }
+
private:
virtual void key_schedule(const byte key[], size_t length) = 0;
};
diff --git a/src/lib/prov/openssl/openssl_block.cpp b/src/lib/prov/openssl/openssl_block.cpp
index c868e8977..d09fdb82b 100644
--- a/src/lib/prov/openssl/openssl_block.cpp
+++ b/src/lib/prov/openssl/openssl_block.cpp
@@ -25,6 +25,7 @@ class OpenSSL_BlockCipher : public BlockCipher
~OpenSSL_BlockCipher();
void clear() override;
+ const char* provider() const override { return "openssl"; }
std::string name() const override { return m_cipher_name; }
BlockCipher* clone() const override;
diff --git a/src/lib/prov/openssl/openssl_hash.cpp b/src/lib/prov/openssl/openssl_hash.cpp
index c14c551e4..fa31d36c8 100644
--- a/src/lib/prov/openssl/openssl_hash.cpp
+++ b/src/lib/prov/openssl/openssl_hash.cpp
@@ -23,6 +23,7 @@ class OpenSSL_HashFunction : public HashFunction
EVP_DigestInit_ex(&m_md, algo, nullptr);
}
+ const char* provider() const override { return "openssl"; }
std::string name() const override { return m_name; }
HashFunction* clone() const override
diff --git a/src/lib/prov/openssl/openssl_rc4.cpp b/src/lib/prov/openssl/openssl_rc4.cpp
index d6246e4ab..50148f09a 100644
--- a/src/lib/prov/openssl/openssl_rc4.cpp
+++ b/src/lib/prov/openssl/openssl_rc4.cpp
@@ -24,6 +24,8 @@ class OpenSSL_RC4 : public StreamCipher
public:
void clear() override { clear_mem(&m_rc4, 1); }
+ const char* provider() const override { return "openssl"; }
+
std::string name() const override
{
switch(m_skip)
diff --git a/src/lib/stream/chacha/chacha.cpp b/src/lib/stream/chacha/chacha.cpp
index c35363112..66d7ad90d 100644
--- a/src/lib/stream/chacha/chacha.cpp
+++ b/src/lib/stream/chacha/chacha.cpp
@@ -17,6 +17,18 @@ ChaCha::ChaCha(size_t rounds) : m_rounds(rounds)
throw Invalid_Argument("ChaCha only supports 8, 12 or 20 rounds");
}
+const char* ChaCha::provider() const
+ {
+#if defined(BOTAN_HAS_CHACHA_SSE2)
+ if(CPUID::has_sse2())
+ {
+ return "sse2";
+ }
+#endif
+
+ return "base";
+ }
+
//static
void ChaCha::chacha_x4(byte output[64*4], u32bit input[16], size_t rounds)
{
diff --git a/src/lib/stream/chacha/chacha.h b/src/lib/stream/chacha/chacha.h
index 7e9e54768..19ed6d25f 100644
--- a/src/lib/stream/chacha/chacha.h
+++ b/src/lib/stream/chacha/chacha.h
@@ -26,6 +26,8 @@ class BOTAN_DLL ChaCha final : public StreamCipher
*/
ChaCha(size_t rounds = 20);
+ const char* provider() const override;
+
void cipher(const byte in[], byte out[], size_t length) override;
void set_iv(const byte iv[], size_t iv_len) override;
diff --git a/src/lib/stream/stream_cipher.h b/src/lib/stream/stream_cipher.h
index e08bee0ce..e41cdaa6d 100644
--- a/src/lib/stream/stream_cipher.h
+++ b/src/lib/stream/stream_cipher.h
@@ -86,6 +86,13 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm
*/
virtual void seek(u64bit offset) = 0;
+ /**
+ * @return provider information about this implementation. Default is "base",
+ * might also return "sse2", "avx2", "openssl", or some other arbitrary string.
+ * The return value is guaranteed to point to a string literal constant.
+ */
+ virtual const char* provider() const { return "base"; }
+
StreamCipher();
virtual ~StreamCipher();
};
diff --git a/src/tests/test_block.cpp b/src/tests/test_block.cpp
index 0863cb891..acbe6702b 100644
--- a/src/tests/test_block.cpp
+++ b/src/tests/test_block.cpp
@@ -30,16 +30,18 @@ class Block_Cipher_Tests : public Text_Based_Test
return result;
}
- for(auto&& provider: providers)
+ for(auto&& provider_ask : providers)
{
- std::unique_ptr<Botan::BlockCipher> cipher(Botan::BlockCipher::create(algo, provider));
+ std::unique_ptr<Botan::BlockCipher> cipher(Botan::BlockCipher::create(algo, provider_ask));
if(!cipher)
{
- result.note_missing(algo + " from " + provider);
+ result.note_missing(algo + " from " + provider_ask);
continue;
}
+ const std::string provider(cipher->provider());
+ result.test_is_nonempty("provider", provider);
result.test_eq(provider, cipher->name(), algo);
result.test_gte(provider, cipher->parallelism(), 1);
result.test_gte(provider, cipher->block_size(), 8);
diff --git a/src/tests/test_hash.cpp b/src/tests/test_hash.cpp
index 811e95727..aca9d7ef6 100644
--- a/src/tests/test_hash.cpp
+++ b/src/tests/test_hash.cpp
@@ -36,16 +36,18 @@ class Hash_Function_Tests : public Text_Based_Test
return result;
}
- for(auto&& provider: providers)
+ for(auto&& provider_ask : providers)
{
- std::unique_ptr<Botan::HashFunction> hash(Botan::HashFunction::create(algo, provider));
+ std::unique_ptr<Botan::HashFunction> hash(Botan::HashFunction::create(algo, provider_ask));
if(!hash)
{
- result.note_missing(algo + " from " + provider);
+ result.note_missing(algo + " from " + provider_ask);
continue;
}
+ const std::string provider(hash->provider());
+ result.test_is_nonempty("provider", provider);
result.test_eq(provider, hash->name(), algo);
hash->update(input);
diff --git a/src/tests/test_mac.cpp b/src/tests/test_mac.cpp
index c7efb7f08..6183e88f7 100644
--- a/src/tests/test_mac.cpp
+++ b/src/tests/test_mac.cpp
@@ -38,16 +38,19 @@ class Message_Auth_Tests : public Text_Based_Test
return result;
}
- for(auto&& provider: providers)
+ for(auto&& provider_ask : providers)
{
- std::unique_ptr<Botan::MessageAuthenticationCode> mac(Botan::MessageAuthenticationCode::create(algo, provider));
+ std::unique_ptr<Botan::MessageAuthenticationCode> mac(Botan::MessageAuthenticationCode::create(algo, provider_ask));
if(!mac)
{
- result.note_missing(algo + " from " + provider);
+ result.note_missing(algo + " from " + provider_ask);
continue;
}
+ const std::string provider(mac->provider());
+
+ result.test_is_nonempty("provider", provider);
result.test_eq(provider, mac->name(), algo);
mac->set_key(key);
diff --git a/src/tests/test_modes.cpp b/src/tests/test_modes.cpp
index 66f537346..ada4d5b82 100644
--- a/src/tests/test_modes.cpp
+++ b/src/tests/test_modes.cpp
@@ -39,6 +39,7 @@ class Cipher_Mode_Tests : public Text_Based_Test
return result;
}
+ result.test_is_nonempty("provider", enc->provider());
result.test_eq("name", enc->name(), algo);
result.test_eq("mode not authenticated", enc->authenticated(), false);
diff --git a/src/tests/test_stream.cpp b/src/tests/test_stream.cpp
index be7b9a548..6097fd3e8 100644
--- a/src/tests/test_stream.cpp
+++ b/src/tests/test_stream.cpp
@@ -41,16 +41,18 @@ class Stream_Cipher_Tests : public Text_Based_Test
return result;
}
- for(auto&& provider: providers)
+ for(auto&& provider_ask : providers)
{
- std::unique_ptr<Botan::StreamCipher> cipher(Botan::StreamCipher::create(algo, provider));
+ std::unique_ptr<Botan::StreamCipher> cipher(Botan::StreamCipher::create(algo, provider_ask));
if(!cipher)
{
- result.note_missing(algo + " from " + provider);
+ result.note_missing(algo + " from " + provider_ask);
continue;
}
+ const std::string provider(cipher->provider());
+ result.test_is_nonempty("provider", provider);
result.test_eq(provider, cipher->name(), algo);
cipher->set_key(key);
diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp
index 2e8a1e4de..b47f2a7ab 100644
--- a/src/tests/tests.cpp
+++ b/src/tests/tests.cpp
@@ -175,6 +175,13 @@ bool Test::Result::test_eq(const char* producer, const std::string& what,
return test_failure(err.str());
}
+bool Test::Result::test_is_nonempty(const std::string& what_is_it, const std::string& to_examine)
+ {
+ if(to_examine.empty())
+ return test_failure(what_is_it + " was empty");
+ return test_success();
+ }
+
bool Test::Result::test_eq(const std::string& what, const std::string& produced, const std::string& expected)
{
return test_is_eq(what, produced, expected);
diff --git a/src/tests/tests.h b/src/tests/tests.h
index 43b9e0d3a..1ceb24f48 100644
--- a/src/tests/tests.h
+++ b/src/tests/tests.h
@@ -171,6 +171,8 @@ class Test
bool test_eq(const std::string& what, const char* produced, const char* expected);
+ bool test_is_nonempty(const std::string& what_is_it, const std::string& to_examine);
+
bool test_eq(const std::string& what,
const std::string& produced,
const std::string& expected);