aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/ffi/ffi.cpp5
-rw-r--r--src/tests/test_ffi.cpp170
2 files changed, 174 insertions, 1 deletions
diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp
index 4a5ec13c1..18298b365 100644
--- a/src/lib/ffi/ffi.cpp
+++ b/src/lib/ffi/ffi.cpp
@@ -58,7 +58,7 @@ struct botan_struct
{
if(m_magic != MAGIC)
throw std::runtime_error("Bad magic " + std::to_string(m_magic) +
- " in ffi object expected" + std::to_string(MAGIC));
+ " in ffi object expected " + std::to_string(MAGIC));
return m_obj.get();
}
private:
@@ -583,6 +583,7 @@ int botan_pbkdf(const char* pbkdf_algo, uint8_t out[], size_t out_len,
{
std::unique_ptr<Botan::PBKDF> pbkdf(Botan::get_pbkdf(pbkdf_algo));
pbkdf->pbkdf_iterations(out, out_len, pass, salt, salt_len, iterations);
+ return 0;
}
catch(std::exception& e)
{
@@ -605,6 +606,7 @@ int botan_pbkdf_timed(const char* pbkdf_algo,
pbkdf->pbkdf_timed(out, out_len, password, salt, salt_len,
std::chrono::milliseconds(ms_to_run),
*iterations_used);
+ return 0;
}
catch(std::exception& e)
{
@@ -623,6 +625,7 @@ int botan_kdf(const char* kdf_algo,
{
std::unique_ptr<Botan::KDF> kdf(Botan::get_kdf(kdf_algo));
kdf->kdf(out, out_len, secret, secret_len, salt, salt_len);
+ return 0;
}
catch(std::exception& e)
{
diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp
new file mode 100644
index 000000000..9706f25ea
--- /dev/null
+++ b/src/tests/test_ffi.cpp
@@ -0,0 +1,170 @@
+/*
+* (C) 2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "catchy/catch.hpp"
+#include <botan/version.h>
+
+#if defined(BOTAN_HAS_FFI)
+
+#include <botan/hex.h>
+#include <botan/ffi.h>
+
+TEST_CASE("FFI versioning", "[ffi]")
+ {
+ CHECK(botan_ffi_api_version() == BOTAN_HAS_FFI);
+ CHECK(botan_version_major() == Botan::version_major());
+ CHECK(botan_version_minor() == Botan::version_minor());
+ CHECK(botan_version_patch() == Botan::version_patch());
+ }
+
+TEST_CASE("FFI hex", "[ffi]")
+ {
+ const std::vector<uint8_t> bin = { 0xAA, 0xDE, 0x01 };
+ std::string out;
+ out.resize(2*bin.size());
+
+ CHECK(botan_hex_encode(bin.data(), bin.size(), &out[0], 0) == 0);
+ CHECK(out == "AADE01");
+
+ CHECK(botan_hex_encode(bin.data(), bin.size(), &out[0], BOTAN_FFI_HEX_LOWER_CASE) == 0);
+ CHECK(out == "aade01");
+ }
+
+TEST_CASE("FFI RNG", "[ffi]")
+ {
+ botan_rng_t rng;
+ unsigned char buf[512];
+
+ CHECK(botan_rng_init(&rng, "bad_type") < 0);
+
+ const char* types[] = { "system", "user", nullptr };
+
+ for(size_t i = 0; types[i]; ++i)
+ {
+ REQUIRE(botan_rng_init(&rng, types[i]) == 0);
+ CHECK(botan_rng_get(rng, buf, sizeof(buf)) == 0);
+ CHECK(botan_rng_reseed(rng, 256) == 0);
+ CHECK(botan_rng_destroy(rng) == 0);
+ }
+ }
+
+TEST_CASE("FFI hash", "[ffi]")
+ {
+ botan_hash_t hash;
+ CHECK(botan_hash_init(&hash, "SHA-256", 1) < 0);
+ REQUIRE(botan_hash_init(&hash, "SHA-256", 0) == 0);
+
+ /*
+ char namebuf[32];
+ CHECK(botan_hash_name(hash, namebuf, 5) < 0);
+ CHECK(botan_hash_name(hash, namebuf, 31) == 0);
+ CHECK(std::string(namebuf) == "SHA-256");
+ */
+
+ size_t ol;
+ CHECK(botan_hash_output_length(hash, &ol) == 0);
+ CHECK(ol == 32);
+
+ const char* s = "ABC";
+
+ std::vector<uint8_t> outbuf(ol);
+ CHECK(botan_hash_update(hash, reinterpret_cast<const uint8_t*>(s), 3) == 0);
+ CHECK(botan_hash_final(hash, outbuf.data()) == 0);
+
+ //CHECK_ARRAY(outbuf, "B5D4045C3F466FA91FE2CC6ABE79232A1A57CDF104F7A26E716E0A1E2789DF78");
+ CHECK(Botan::hex_encode(outbuf) == "B5D4045C3F466FA91FE2CC6ABE79232A1A57CDF104F7A26E716E0A1E2789DF78");
+
+ CHECK(botan_hash_clear(hash) == 0);
+
+ CHECK(botan_hash_destroy(hash) == 0);
+ }
+
+TEST_CASE("FFI mac", "[ffi]")
+ {
+ botan_mac_t mac;
+ CHECK(botan_mac_init(&mac, "HMAC(SHA-256)", 1) < 0);
+ CHECK(botan_mac_init(&mac, "HMAC(SHA-256)", 0) == 0);
+
+ //char namebuf[32];
+ //CHECK(botan_mac_name(mac, namebuf, 10) < 0);
+ //CHECK(botan_mac_name(mac, namebuf, 31) == 0);
+ //CHECK(std::string(namebuf) == "HMAC(SHA-256)");
+
+ size_t ol;
+ CHECK(botan_mac_output_length(mac, &ol) == 0);
+ CHECK(ol == 32);
+
+ const uint8_t key[] = { 0xAA, 0xBB, 0xCC, 0xDD };
+
+ CHECK(botan_mac_set_key(mac, key, 4) == 0);
+ const char* s = "ABC";
+
+ std::vector<uint8_t> outbuf(ol);
+ CHECK(botan_mac_update(mac, reinterpret_cast<const uint8_t*>(s), 3) == 0);
+ CHECK(botan_mac_final(mac, outbuf.data()) == 0);
+
+ CHECK(Botan::hex_encode(outbuf) == "1A82EEA984BC4A7285617CC0D05F1FE1D6C96675924A81BC965EE8FF7B0697A7");
+
+ CHECK(botan_mac_clear(mac) == 0);
+ CHECK(botan_mac_destroy(mac) == 0);
+ }
+
+TEST_CASE("FFI PBKDF", "[ffi]")
+ {
+ const std::vector<uint8_t> salt = Botan::hex_decode("ED1F39A0A7F3889AAF7E60743B3BC1CC2C738E60");
+ const std::string passphrase = "ltexmfeyylmlbrsyikaw";
+ const size_t out_len = 10;
+ const size_t iterations = 1000;
+
+ std::vector<uint8_t> outbuf(out_len);
+
+ CHECK(botan_pbkdf("PBKDF2(SHA-1)", outbuf.data(), outbuf.size(),
+ passphrase.c_str(), salt.data(), salt.size(), iterations) == 0);
+
+ CHECK(Botan::hex_encode(outbuf) == "027AFADD48F4BE8DCC4F");
+
+ size_t iters_10ms, iters_100ms;
+ CHECK(botan_pbkdf_timed("PBKDF2(SHA-1)", outbuf.data(), outbuf.size(),
+ passphrase.c_str(), salt.data(), salt.size(), 10, &iters_10ms) == 0);
+ CHECK(botan_pbkdf_timed("PBKDF2(SHA-1)", outbuf.data(), outbuf.size(),
+ passphrase.c_str(), salt.data(), salt.size(), 100, &iters_100ms) == 0);
+
+ INFO("Iterations " << iters_10ms << " " << iters_100ms);
+ const double ratio = static_cast<double>(iters_100ms) / iters_10ms;
+ CHECK(ratio >= 5);
+ CHECK(ratio <= 15);
+ }
+
+TEST_CASE("FFI KDF", "[ffi]")
+ {
+ const std::vector<uint8_t> secret = Botan::hex_decode("92167440112E");
+ const std::vector<uint8_t> salt = Botan::hex_decode("45A9BEDED69163123D0348F5185F61ABFB1BF18D6AEA454F");
+ const size_t out_len = 18;
+ std::vector<uint8_t> out_buf(out_len);
+
+ REQUIRE(botan_kdf("KDF2(SHA-1)", out_buf.data(), out_len,
+ secret.data(), secret.size(), salt.data(), salt.size()) == 0);
+
+ CHECK(Botan::hex_encode(out_buf) == "3A5DC9AA1C872B4744515AC2702D6396FC2A");
+ }
+
+TEST_CASE("FFI bcrypt", "[ffi]")
+ {
+ std::vector<uint8_t> outbuf(62);
+ size_t ol = outbuf.size();
+
+ botan_rng_t rng;
+ botan_rng_init(&rng, "system");
+
+ CHECK(botan_bcrypt_generate(outbuf.data(), &ol, "password", rng, 10, 0) == 0);
+ botan_rng_destroy(rng);
+
+ CHECK(botan_bcrypt_is_valid("wrong", reinterpret_cast<const char*>(outbuf.data())) == 1);
+ CHECK(botan_bcrypt_is_valid("password", reinterpret_cast<const char*>(outbuf.data())) == 0);
+
+ }
+
+#endif