aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cli/speed.cpp21
-rwxr-xr-xsrc/scripts/test_cli.py29
-rw-r--r--src/tests/test_ffi.cpp11
-rw-r--r--src/tests/test_pbkdf.cpp106
4 files changed, 148 insertions, 19 deletions
diff --git a/src/cli/speed.cpp b/src/cli/speed.cpp
index 3ba6da24f..f7e9da1cf 100644
--- a/src/cli/speed.cpp
+++ b/src/cli/speed.cpp
@@ -1636,11 +1636,11 @@ class Speed final : public Command
}
}
- void bench_pk_sig(const Botan::Private_Key& key,
- const std::string& nm,
- const std::string& provider,
- const std::string& padding,
- std::chrono::milliseconds msec)
+ size_t bench_pk_sig(const Botan::Private_Key& key,
+ const std::string& nm,
+ const std::string& provider,
+ const std::string& padding,
+ std::chrono::milliseconds msec)
{
std::vector<uint8_t> message, signature, bad_signature;
@@ -1690,8 +1690,12 @@ class Speed final : public Command
}
}
+ const size_t events = std::min(sig_timer->events(), ver_timer->events());
+
record_result(sig_timer);
record_result(ver_timer);
+
+ return events;
}
#endif
@@ -1925,7 +1929,8 @@ class Speed final : public Command
}));
record_result(keygen_timer);
- bench_pk_sig(*key, params, provider, "", msec);
+ if(bench_pk_sig(*key, params, provider, "", msec) == 1)
+ break;
}
}
#endif
@@ -1981,7 +1986,7 @@ class Speed final : public Command
std::chrono::milliseconds msec)
{
- for(size_t N : { 8192, 16384, 32768, 65536, 1 << 17, 1 << 18, 1 << 19 })
+ for(size_t N : { 8192, 16384, 32768, 65536 })
{
for(size_t r : { 1, 8, 16 })
{
@@ -2006,10 +2011,8 @@ class Speed final : public Command
record_result(scrypt_timer);
- /*
if(scrypt_timer->events() == 1)
break;
- */
}
}
}
diff --git a/src/scripts/test_cli.py b/src/scripts/test_cli.py
index 2f5e5bba4..d38a990d9 100755
--- a/src/scripts/test_cli.py
+++ b/src/scripts/test_cli.py
@@ -46,8 +46,6 @@ def test_cli(cmd, cmd_options, expected_output=None, cmd_input=None):
TESTS_RUN += 1
- logging.debug("Running %s %s", cmd, cmd_options)
-
fixed_drbg_seed = "802" * 32
opt_list = []
@@ -60,6 +58,8 @@ def test_cli(cmd, cmd_options, expected_output=None, cmd_input=None):
drbg_options = ['--rng-type=drbg', '--drbg-seed=' + fixed_drbg_seed]
cmdline = [CLI_PATH, cmd] + drbg_options + opt_list
+ logging.debug("Executing '%s'" % (' '.join([CLI_PATH, cmd] + opt_list)))
+
stdout = None
stderr = None
@@ -283,6 +283,26 @@ mlLtJ5JvZ0/p6zP3x+Y9yPIrAR8L/acG5ItSrAKXzzuqQQZMv4aN
shutil.rmtree(tmp_dir)
+def cli_pbkdf_tune_tests():
+ if not check_for_command("pbkdf_tune"):
+ return
+
+ expected = re.compile(r'For (default|[1-9][0-9]*) ms selected Scrypt\([0-9]+,[0-9]+,[0-9]+\) using [0-9]+ MiB')
+
+ output = test_cli("pbkdf_tune", ["--check", "1", "10", "50", "default"], None).split('\n')
+
+ for line in output:
+ if expected.match(line) is None:
+ logging.error("Unexpected line '%s'" % (line))
+
+ expected_pbkdf2 = re.compile(r'For (default|[1-9][0-9]*) ms selected PBKDF2\(HMAC\(SHA-256\),[0-9]+\)')
+
+ output = test_cli("pbkdf_tune", ["--algo=PBKDF2(SHA-256)", "--check", "1", "10", "50", "default"], None).split('\n')
+
+ for line in output:
+ if expected_pbkdf2.match(line) is None:
+ logging.error("Unexpected line '%s'" % (line))
+
def cli_psk_db_tests():
if not check_for_command("psk_get"):
return
@@ -601,7 +621,7 @@ def cli_speed_tests():
output = test_cli("speed", ["--msec=%d" % (msec), "scrypt"], None).split('\n')
- format_re = re.compile(r'^scrypt-[0-9]+-[0-9]+-[0-9]+ [0-9]+ /sec; [0-9]+\.[0-9]+ ms/op .*\([0-9]+ (op|ops) in [0-9]+ ms\)')
+ format_re = re.compile(r'^scrypt-[0-9]+-[0-9]+-[0-9]+ \([0-9]+ MiB\) [0-9]+ /sec; [0-9]+\.[0-9]+ ms/op .*\([0-9]+ (op|ops) in [0-9]+ ms\)')
for line in output:
if format_re.match(line) is None:
@@ -688,6 +708,7 @@ def main(args=None):
cli_pk_encrypt_tests,
cli_pk_workfactor_tests,
cli_psk_db_tests,
+ cli_pbkdf_tune_tests,
cli_rng_tests,
cli_speed_tests,
cli_timing_test_tests,
@@ -701,7 +722,7 @@ def main(args=None):
fn_name = fn.__name__
if test_regex is not None:
- if test_regex.match(fn_name) is None:
+ if test_regex.search(fn_name) is None:
continue
start = time.time()
diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp
index ba941be95..e2c50b4e9 100644
--- a/src/tests/test_ffi.cpp
+++ b/src/tests/test_ffi.cpp
@@ -2,6 +2,7 @@
* (C) 2015 Jack Lloyd
* (C) 2016 René Korthaus
* (C) 2018 Ribose Inc, Krzysztof Kwiatkowski
+* (C) 2018 Ribose Inc
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -924,6 +925,16 @@ class FFI_Unit_Tests final : public Test
TEST_FFI_OK(botan_scrypt, (output.data(), output.size(), pass, salt, sizeof(salt), 8, 1, 1));
result.test_eq("scrypt output", output, "4B9B888D695288E002CC4F9D90808A4D296A45CE4471AFBB");
+
+ size_t N, r, p;
+ TEST_FFI_OK(botan_pwdhash_timed, ("Scrypt", 50, &r, &p, &N, output.data(), output.size(),
+ "bunny", 5, salt, sizeof(salt)));
+
+ std::vector<uint8_t> cmp(output.size());
+
+ TEST_FFI_OK(botan_pwdhash, ("Scrypt", N, r, p, cmp.data(), cmp.size(),
+ "bunny", 5, salt, sizeof(salt)));
+ result.test_eq("recomputed scrypt", cmp, output);
#else
TEST_FFI_RC(BOTAN_FFI_ERROR_NOT_IMPLEMENTED,
botan_scrypt, (output.data(), output.size(), pass, salt, sizeof(salt), 8, 1, 1));
diff --git a/src/tests/test_pbkdf.cpp b/src/tests/test_pbkdf.cpp
index eb344b2ea..20a25165b 100644
--- a/src/tests/test_pbkdf.cpp
+++ b/src/tests/test_pbkdf.cpp
@@ -1,5 +1,6 @@
/*
* (C) 2014,2015 Jack Lloyd
+* (C) 2018 Ribose Inc
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -8,6 +9,7 @@
#if defined(BOTAN_HAS_PBKDF)
#include <botan/pbkdf.h>
+ #include <botan/pwdhash.h>
#endif
#if defined(BOTAN_HAS_PGP_S2K)
@@ -49,9 +51,25 @@ class PBKDF_KAT_Tests final : public Text_Based_Test
const Botan::secure_vector<uint8_t> derived =
pbkdf->derive_key(outlen, passphrase, salt.data(), salt.size(), iterations).bits_of();
-
result.test_eq("derived key", derived, expected);
+ auto pwdhash_fam = Botan::PasswordHashFamily::create(pbkdf_name);
+
+ if(!pwdhash_fam)
+ {
+ result.note_missing("No PasswordHashFamily for " + pbkdf_name);
+ return result;
+ }
+
+ auto pwdhash = pwdhash_fam->from_params(iterations);
+
+ std::vector<uint8_t> pwdhash_derived(outlen);
+ pwdhash->derive_key(pwdhash_derived.data(), pwdhash_derived.size(),
+ passphrase.c_str(), passphrase.size(),
+ salt.data(), salt.size());
+
+ result.test_eq("pwdhash derived key", pwdhash_derived, expected);
+
return result;
}
@@ -59,6 +77,65 @@ class PBKDF_KAT_Tests final : public Text_Based_Test
BOTAN_REGISTER_TEST("pbkdf", PBKDF_KAT_Tests);
+class Pwdhash_Tests : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override
+ {
+ std::vector<Test::Result> results;
+
+ for(std::string pwdhash : { "Scrypt", "PBKDF2(SHA-256)", "OpenPGP-S2K(SHA-384)"})
+ {
+ Test::Result result("Pwdhash " + pwdhash);
+ auto pwdhash_fam = Botan::PasswordHashFamily::create(pwdhash);
+
+ if(pwdhash_fam)
+ {
+ const std::vector<uint8_t> salt(8);
+ const std::string password = "test";
+
+ auto pwdhash_tune = pwdhash_fam->tune(32, std::chrono::milliseconds(50));
+
+ std::vector<uint8_t> output1(32);
+ pwdhash_tune->derive_key(output1.data(), output1.size(),
+ password.c_str(), password.size(),
+ salt.data(), salt.size());
+
+ std::unique_ptr<Botan::PasswordHash> pwhash;
+
+ if(pwdhash_fam->name() == "Scrypt")
+ {
+ pwhash = pwdhash_fam->from_params(pwdhash_tune->memory_param(),
+ pwdhash_tune->iterations(),
+ pwdhash_tune->parallelism());
+ }
+ else
+ {
+ pwhash = pwdhash_fam->from_params(pwdhash_tune->iterations());
+ }
+
+ std::vector<uint8_t> output2(32);
+ pwdhash_tune->derive_key(output2.data(), output2.size(),
+ password.c_str(), password.size(),
+ salt.data(), salt.size());
+
+ result.test_eq("PasswordHash produced same output when run with same params",
+ output1, output2);
+
+
+ //auto pwdhash_tuned = pwdhash_fam->tune(32, std::chrono::milliseconds(150));
+
+ }
+
+ results.push_back(result);
+ }
+
+ return results;
+ }
+ };
+
+BOTAN_REGISTER_TEST("pwdhash", Pwdhash_Tests);
+
#endif
#if defined(BOTAN_HAS_SCRYPT)
@@ -89,6 +166,23 @@ class Scrypt_KAT_Tests final : public Text_Based_Test
result.test_eq("derived key", output, expected);
+ auto pwdhash_fam = Botan::PasswordHashFamily::create("Scrypt");
+
+ if(!pwdhash_fam)
+ {
+ result.test_failure("Scrypt is missing PasswordHashFamily");
+ return result;
+ }
+
+ auto pwdhash = pwdhash_fam->from_params(N, R, P);
+
+ std::vector<uint8_t> pwdhash_derived(expected.size());
+ pwdhash->derive_key(pwdhash_derived.data(), pwdhash_derived.size(),
+ passphrase.c_str(), passphrase.size(),
+ salt.data(), salt.size());
+
+ result.test_eq("pwdhash derived key", pwdhash_derived, expected);
+
return result;
}
@@ -111,13 +205,13 @@ class PGP_S2K_Iter_Test final : public Test
const size_t max_iter = 65011712;
result.test_eq("Encoding of large value accepted",
- Botan::OpenPGP_S2K::encode_count(max_iter * 2), size_t(255));
+ Botan::RFC4880_encode_count(max_iter * 2), size_t(255));
result.test_eq("Encoding of small value accepted",
- Botan::OpenPGP_S2K::encode_count(0), size_t(0));
+ Botan::RFC4880_encode_count(0), size_t(0));
for(size_t c = 0; c != 256; ++c)
{
- const size_t dec = Botan::OpenPGP_S2K::decode_count(static_cast<uint8_t>(c));
+ const size_t dec = Botan::RFC4880_decode_count(static_cast<uint8_t>(c));
const size_t comp_dec = (16 + (c & 0x0F)) << ((c >> 4) + 6);
result.test_eq("Decoded value matches PGP formula", dec, comp_dec);
}
@@ -126,14 +220,14 @@ class PGP_S2K_Iter_Test final : public Test
for(size_t i = 0; i <= max_iter; i += 64)
{
- const uint8_t enc = Botan::OpenPGP_S2K::encode_count(i);
+ const uint8_t enc = Botan::RFC4880_encode_count(i);
result.test_lte("Encoded value non-decreasing", last_enc, enc);
/*
The iteration count as encoded may not be exactly the
value requested, but should never be less
*/
- const size_t dec = Botan::OpenPGP_S2K::decode_count(enc);
+ const size_t dec = Botan::RFC4880_decode_count(enc);
result.test_gte("Decoded value is >= requested", dec, i);
last_enc = enc;