aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-09-17 14:20:03 -0400
committerJack Lloyd <[email protected]>2016-09-17 14:20:03 -0400
commitd734198074d0290631e27d1fb27dce45f0676d58 (patch)
treefaed46aaae836e44e972a4e6d5bdea06b0729034 /src/tests
parent272fcf00572432f64085b10132e364740d7eb093 (diff)
parent2b7f2d52d032ad56526d38e7f65bd966ac59325a (diff)
Merge GH #623 Merge algorithm impl types
If CPU specific optimizations are available they are always used, without requiring the application to use the application registry to ensure they get the optimal type. See also GH #477
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/data/aead/gcm.vec3
-rw-r--r--src/tests/data/block/aes.vec3
-rw-r--r--src/tests/data/block/idea.vec3
-rw-r--r--src/tests/data/block/noekeon.vec3
-rw-r--r--src/tests/data/block/serpent.vec3
-rw-r--r--src/tests/data/block/threefish.vec3
-rw-r--r--src/tests/data/hash/sha1.vec2
-rw-r--r--src/tests/data/stream/chacha.vec3
-rw-r--r--src/tests/main.cpp20
-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.cpp117
-rw-r--r--src/tests/tests.h5
16 files changed, 169 insertions, 30 deletions
diff --git a/src/tests/data/aead/gcm.vec b/src/tests/data/aead/gcm.vec
index 516e828ec..be8250792 100644
--- a/src/tests/data/aead/gcm.vec
+++ b/src/tests/data/aead/gcm.vec
@@ -1,3 +1,6 @@
+
+#test cpuid aesni ssse3 clmul
+
[AES-128/GCM]
# Nist | Test Case 1
Key = 00000000000000000000000000000000
diff --git a/src/tests/data/block/aes.vec b/src/tests/data/block/aes.vec
index 4e0b7399c..50d9cc469 100644
--- a/src/tests/data/block/aes.vec
+++ b/src/tests/data/block/aes.vec
@@ -1,3 +1,6 @@
+
+#test cpuid aesni ssse3
+
[AES-128]
Key = 000102030405060708090A0B0C0D0E0F
In = 00112233445566778899AABBCCDDEEFF
diff --git a/src/tests/data/block/idea.vec b/src/tests/data/block/idea.vec
index 705d02d68..eee5ef5e9 100644
--- a/src/tests/data/block/idea.vec
+++ b/src/tests/data/block/idea.vec
@@ -1,3 +1,6 @@
+
+#test cpuid sse2
+
[IDEA]
Key = ED1BCC9E9267925F3132BA3A8CF9B764
In = 7409000000000000
diff --git a/src/tests/data/block/noekeon.vec b/src/tests/data/block/noekeon.vec
index 2921301c1..08e7cabf3 100644
--- a/src/tests/data/block/noekeon.vec
+++ b/src/tests/data/block/noekeon.vec
@@ -1,3 +1,6 @@
+
+#cpuid simd32
+
[Noekeon]
Key = 00000000000000000000000000000000
In = 00000000000000000000000000000000
diff --git a/src/tests/data/block/serpent.vec b/src/tests/data/block/serpent.vec
index 623ee6be8..8a40c54b7 100644
--- a/src/tests/data/block/serpent.vec
+++ b/src/tests/data/block/serpent.vec
@@ -1,3 +1,6 @@
+
+#test cpuid simd
+
[Serpent]
Key = 00000000000000000000000000000000
In = D29D576FCEA3A3A7ED9099F29273D78E2D62A890CEA3A3A7ED9099F29273D78ED29D576F315C5C58ED9099F29273D78E2D62A890315C5C58ED9099F29273D78ED29D576FCEA3A3A7126F660D9273D78E2D62A890CEA3A3A7126F660D9273D78ED29D576F315C5C58126F660D9273D78E2D62A890315C5C58126F660D9273D78ED29D576FCEA3A3A7ED9099F26D8C28712D62A890CEA3A3A7ED9099F26D8C2871D29D576F315C5C58ED9099F26D8C28712D62A890315C5C58ED9099F26D8C2871D29D576FCEA3A3A7126F660D6D8C28712D62A890CEA3A3A7126F660D6D8C2871D29D576F315C5C58126F660D6D8C2871
diff --git a/src/tests/data/block/threefish.vec b/src/tests/data/block/threefish.vec
index b4e9d8229..dfaccb7ff 100644
--- a/src/tests/data/block/threefish.vec
+++ b/src/tests/data/block/threefish.vec
@@ -1,3 +1,6 @@
+
+#test cpuid avx2
+
[Threefish-512]
Key = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/src/tests/data/hash/sha1.vec b/src/tests/data/hash/sha1.vec
index f5fd82340..e86650f30 100644
--- a/src/tests/data/hash/sha1.vec
+++ b/src/tests/data/hash/sha1.vec
@@ -1,3 +1,5 @@
+#test cpuid sse2
+
[SHA-160]
In =
Out = DA39A3EE5E6B4B0D3255BFEF95601890AFD80709
diff --git a/src/tests/data/stream/chacha.vec b/src/tests/data/stream/chacha.vec
index 47d3aa7fe..f7ba701ba 100644
--- a/src/tests/data/stream/chacha.vec
+++ b/src/tests/data/stream/chacha.vec
@@ -1,3 +1,6 @@
+
+#test cpuid sse2
+
[ChaCha(8)]
# Tests got from the original implementation of Daniel J. Bernstein
diff --git a/src/tests/main.cpp b/src/tests/main.cpp
index 07aaac519..b771d9614 100644
--- a/src/tests/main.cpp
+++ b/src/tests/main.cpp
@@ -228,8 +228,14 @@ class Test_Runner : public Botan_CLI::Command
{
for(auto&& test_name : tests_to_run)
{
- const auto results = Botan_Tests::Test::run_test(test_name, false);
- out << report_out(results, tests_failed, tests_ran) << std::flush;
+ try {
+ const auto results = Botan_Tests::Test::run_test(test_name, false);
+ out << report_out(results, tests_failed, tests_ran) << std::flush;
+ }
+ catch(std::exception& e)
+ {
+ out << "Test " << test_name << " failed with exception " << e.what() << std::flush;
+ }
}
}
else
@@ -250,7 +256,15 @@ class Test_Runner : public Botan_CLI::Command
for(auto&& test_name : tests_to_run)
{
auto run_it = [test_name] {
- return Botan_Tests::Test::run_test(test_name, false);
+ try {
+ return Botan_Tests::Test::run_test(test_name, false);
+ }
+ catch(std::exception& e)
+ {
+ Botan_Tests::Test::Result r(test_name);
+ r.test_failure("Exception thrown", e.what());
+ return std::vector<Botan_Tests::Test::Result>{r};
+ }
};
fut_results.push_back(std::async(std::launch::async, run_it));
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 a6f96144c..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);
@@ -527,21 +534,21 @@ Text_Based_Test::Text_Based_Test(const std::string& algo,
std::vector<uint8_t> Text_Based_Test::get_req_bin(const VarMap& vars,
const std::string& key) const
- {
- auto i = vars.find(key);
- if(i == vars.end())
- throw Test_Error("Test missing variable " + key);
+ {
+ auto i = vars.find(key);
+ if(i == vars.end())
+ throw Test_Error("Test missing variable " + key);
- try
- {
- return Botan::hex_decode(i->second);
- }
- catch(std::exception&)
- {
- throw Test_Error("Test invalid hex input '" + i->second + "'" +
- + " for key " + key);
- }
+ try
+ {
+ return Botan::hex_decode(i->second);
}
+ catch(std::exception&)
+ {
+ throw Test_Error("Test invalid hex input '" + i->second + "'" +
+ + " for key " + key);
+ }
+ }
std::string Text_Based_Test::get_opt_str(const VarMap& vars,
const std::string& key, const std::string& def_value) const
@@ -646,9 +653,17 @@ std::string Text_Based_Test::get_next_line()
}
m_cur.reset(new std::ifstream(m_srcs[0]));
+ m_cur_src_name = m_srcs[0];
+
+ // Reinit cpuid on new file if needed
+ if(m_cpu_flags.empty() == false)
+ {
+ m_cpu_flags.clear();
+ Botan::CPUID::initialize();
+ }
if(!m_cur->good())
- throw Test_Error("Could not open input file '" + m_srcs[0]);
+ throw Test_Error("Could not open input file '" + m_cur_src_name);
m_srcs.pop_front();
}
@@ -662,7 +677,12 @@ std::string Text_Based_Test::get_next_line()
continue;
if(line[0] == '#')
- continue;
+ {
+ if(line.compare(0, 6, "#test ") == 0)
+ return line;
+ else
+ continue;
+ }
return line;
}
@@ -685,6 +705,42 @@ std::string strip_ws(const std::string& in)
return in.substr(first_c, last_c - first_c + 1);
}
+std::vector<Botan::CPUID::CPUID_bits> map_cpuid_string(const std::string& tok)
+ {
+#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
+ if(tok == "sse2" || tok == "simd")
+ return {Botan::CPUID::CPUID_SSE2_BIT};
+ if(tok == "ssse3")
+ return {Botan::CPUID::CPUID_SSSE3_BIT};
+ if(tok == "aesni")
+ return {Botan::CPUID::CPUID_AESNI_BIT};
+ if(tok == "clmul")
+ return {Botan::CPUID::CPUID_CLMUL_BIT};
+ if(tok == "avx2")
+ return {Botan::CPUID::CPUID_AVX2_BIT};
+#endif
+
+#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
+ if(tok == "altivec" || tok == "simd")
+ return {Botan::CPUID::CPUID_ALTIVEC_BIT};
+#endif
+
+ return {};
+ }
+
+std::vector<Botan::CPUID::CPUID_bits>
+parse_cpuid_bits(const std::vector<std::string>& tok)
+ {
+ std::vector<Botan::CPUID::CPUID_bits> bits;
+ for(size_t i = 1; i < tok.size(); ++i)
+ {
+ const std::vector<Botan::CPUID::CPUID_bits> more = map_cpuid_string(tok[i]);
+ bits.insert(bits.end(), more.begin(), more.end());
+ }
+
+ return bits;
+ }
+
}
std::vector<Test::Result> Text_Based_Test::run()
@@ -701,6 +757,23 @@ std::vector<Test::Result> Text_Based_Test::run()
if(line.empty()) // EOF
break;
+ if(line.compare(0, 6, "#test ") == 0)
+ {
+ std::vector<std::string> pragma_tokens = Botan::split_on(line.substr(6), ' ');
+
+ if(pragma_tokens.empty())
+ throw Test_Error("Empty pragma found in " + m_cur_src_name);
+
+ if(pragma_tokens[0] != "cpuid")
+ throw Test_Error("Unknown test pragma '" + line + "' in " + m_cur_src_name);
+
+ m_cpu_flags = parse_cpuid_bits(pragma_tokens);
+
+ continue;
+ }
+ else if(line[0] == '#')
+ throw Test_Error("Unknown test pragma '" + line + "' in " + m_cur_src_name);
+
if(line[0] == '[' && line[line.size()-1] == ']')
{
header = line.substr(1, line.size() - 2);
@@ -736,7 +809,21 @@ std::vector<Test::Result> Text_Based_Test::run()
++test_cnt;
uint64_t start = Test::timestamp();
+
Test::Result result = run_one_test(header, vars);
+ if(m_cpu_flags.size() > 0)
+ {
+ for(auto&& cpuid_bit : m_cpu_flags)
+ {
+ if(Botan::CPUID::has_cpuid_bit(cpuid_bit))
+ {
+ Botan::CPUID::clear_cpuid_bit(cpuid_bit);
+ // now re-run the test
+ result.merge(run_one_test(header, vars));
+ }
+ }
+ Botan::CPUID::initialize();
+ }
result.set_ns_consumed(Test::timestamp() - start);
if(result.tests_failed())
diff --git a/src/tests/tests.h b/src/tests/tests.h
index 39aaf67cd..1ceb24f48 100644
--- a/src/tests/tests.h
+++ b/src/tests/tests.h
@@ -12,6 +12,7 @@
#include <botan/rng.h>
#include <botan/hex.h>
#include <botan/symkey.h>
+#include <botan/cpuid.h>
#if defined(BOTAN_HAS_BIGINT)
#include <botan/bigint.h>
@@ -170,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);
@@ -442,7 +445,9 @@ class Text_Based_Test : public Test
bool m_first = true;
std::unique_ptr<std::ifstream> m_cur;
+ std::string m_cur_src_name;
std::deque<std::string> m_srcs;
+ std::vector<Botan::CPUID::CPUID_bits> m_cpu_flags;
};
}