summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/lib/ffi/ffi_kdf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/botan/src/lib/ffi/ffi_kdf.cpp')
-rw-r--r--comm/third_party/botan/src/lib/ffi/ffi_kdf.cpp189
1 files changed, 189 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/lib/ffi/ffi_kdf.cpp b/comm/third_party/botan/src/lib/ffi/ffi_kdf.cpp
new file mode 100644
index 0000000000..d38dd594bd
--- /dev/null
+++ b/comm/third_party/botan/src/lib/ffi/ffi_kdf.cpp
@@ -0,0 +1,189 @@
+/*
+* (C) 2015,2017 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/ffi.h>
+#include <botan/internal/ffi_util.h>
+#include <botan/internal/ffi_rng.h>
+#include <botan/pbkdf.h>
+#include <botan/pwdhash.h>
+#include <botan/kdf.h>
+
+#if defined(BOTAN_HAS_BCRYPT)
+ #include <botan/bcrypt.h>
+#endif
+
+extern "C" {
+
+using namespace Botan_FFI;
+
+int botan_pbkdf(const char* algo, uint8_t out[], size_t out_len,
+ const char* pass, const uint8_t salt[], size_t salt_len,
+ size_t iterations)
+ {
+ return botan_pwdhash(algo,
+ iterations,
+ 0,
+ 0,
+ out, out_len,
+ pass, 0,
+ salt, salt_len);
+ }
+
+int botan_pbkdf_timed(const char* algo,
+ uint8_t out[], size_t out_len,
+ const char* password,
+ const uint8_t salt[], size_t salt_len,
+ size_t ms_to_run,
+ size_t* iterations_used)
+ {
+ return botan_pwdhash_timed(algo,
+ static_cast<uint32_t>(ms_to_run),
+ iterations_used,
+ nullptr,
+ nullptr,
+ out, out_len,
+ password, 0,
+ salt, salt_len);
+ }
+
+int botan_pwdhash(
+ const char* algo,
+ size_t param1,
+ size_t param2,
+ size_t param3,
+ uint8_t out[],
+ size_t out_len,
+ const char* password,
+ size_t password_len,
+ const uint8_t salt[],
+ size_t salt_len)
+ {
+ if(algo == nullptr || password == nullptr)
+ return BOTAN_FFI_ERROR_NULL_POINTER;
+
+ if(password_len == 0)
+ password_len = std::strlen(password);
+
+ return ffi_guard_thunk(__func__, [=]() -> int {
+ auto pwdhash_fam = Botan::PasswordHashFamily::create(algo);
+
+ if(!pwdhash_fam)
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+
+ auto pwdhash = pwdhash_fam->from_params(param1, param2, param3);
+
+ pwdhash->derive_key(out, out_len,
+ password, password_len,
+ salt, salt_len);
+
+ return BOTAN_FFI_SUCCESS;
+ });
+ }
+
+int botan_pwdhash_timed(
+ const char* algo,
+ uint32_t msec,
+ size_t* param1,
+ size_t* param2,
+ size_t* param3,
+ uint8_t out[],
+ size_t out_len,
+ const char* password,
+ size_t password_len,
+ const uint8_t salt[],
+ size_t salt_len)
+ {
+ if(algo == nullptr || password == nullptr)
+ return BOTAN_FFI_ERROR_NULL_POINTER;
+
+ if(password_len == 0)
+ password_len = std::strlen(password);
+
+ return ffi_guard_thunk(__func__, [=]() -> int {
+
+ auto pwdhash_fam = Botan::PasswordHashFamily::create(algo);
+
+ if(!pwdhash_fam)
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+
+ auto pwdhash = pwdhash_fam->tune(out_len, std::chrono::milliseconds(msec));
+
+ if(param1)
+ *param1 = pwdhash->iterations();
+ if(param2)
+ *param2 = pwdhash->parallelism();
+ if(param3)
+ *param3 = pwdhash->memory_param();
+
+ pwdhash->derive_key(out, out_len,
+ password, password_len,
+ salt, salt_len);
+
+ return BOTAN_FFI_SUCCESS;
+ });
+ }
+
+int botan_kdf(const char* kdf_algo,
+ uint8_t out[], size_t out_len,
+ const uint8_t secret[], size_t secret_len,
+ const uint8_t salt[], size_t salt_len,
+ const uint8_t label[], size_t label_len)
+ {
+ return ffi_guard_thunk(__func__, [=]() -> int {
+ std::unique_ptr<Botan::KDF> kdf(Botan::get_kdf(kdf_algo));
+ kdf->kdf(out, out_len, secret, secret_len, salt, salt_len, label, label_len);
+ return BOTAN_FFI_SUCCESS;
+ });
+ }
+
+int botan_scrypt(uint8_t out[], size_t out_len,
+ const char* password,
+ const uint8_t salt[], size_t salt_len,
+ size_t N, size_t r, size_t p)
+ {
+ return botan_pwdhash("Scrypt", N, r, p,
+ out, out_len,
+ password, 0,
+ salt, salt_len);
+ }
+
+int botan_bcrypt_generate(uint8_t* out, size_t* out_len,
+ const char* pass,
+ botan_rng_t rng_obj, size_t wf,
+ uint32_t flags)
+ {
+#if defined(BOTAN_HAS_BCRYPT)
+ return ffi_guard_thunk(__func__, [=]() -> int {
+ if(out == nullptr || out_len == nullptr || pass == nullptr)
+ return BOTAN_FFI_ERROR_NULL_POINTER;
+
+ if(flags != 0)
+ return BOTAN_FFI_ERROR_BAD_FLAG;
+
+ if(wf < 4 || wf > 18)
+ return BOTAN_FFI_ERROR_BAD_PARAMETER;
+
+ Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
+ const std::string bcrypt = Botan::generate_bcrypt(pass, rng, static_cast<uint16_t>(wf));
+ return write_str_output(out, out_len, bcrypt);
+ });
+#else
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+#endif
+ }
+
+int botan_bcrypt_is_valid(const char* pass, const char* hash)
+ {
+#if defined(BOTAN_HAS_BCRYPT)
+ return ffi_guard_thunk(__func__, [=]() -> int {
+ return Botan::check_bcrypt(pass, hash) ? BOTAN_FFI_SUCCESS : BOTAN_FFI_INVALID_VERIFIER;
+ });
+#else
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+#endif
+ }
+
+}