1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
/*
* (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/kdf.h>
#if defined(BOTAN_HAS_BCRYPT)
#include <botan/bcrypt.h>
#endif
#if defined(BOTAN_HAS_SCRYPT)
#include <botan/scrypt.h>
#endif
extern "C" {
using namespace Botan_FFI;
int botan_pbkdf(const char* pbkdf_algo, uint8_t out[], size_t out_len,
const char* pass, const uint8_t salt[], size_t salt_len,
size_t iterations)
{
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
std::unique_ptr<Botan::PBKDF> pbkdf(Botan::get_pbkdf(pbkdf_algo));
pbkdf->pbkdf_iterations(out, out_len, pass, salt, salt_len, iterations);
return BOTAN_FFI_SUCCESS;
});
}
int botan_pbkdf_timed(const char* pbkdf_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 ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
std::unique_ptr<Botan::PBKDF> pbkdf(Botan::get_pbkdf(pbkdf_algo));
pbkdf->pbkdf_timed(out, out_len, password, salt, salt_len,
std::chrono::milliseconds(ms_to_run),
*iterations_used);
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(BOTAN_CURRENT_FUNCTION, [=]() -> 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* passphrase,
const uint8_t salt[], size_t salt_len,
size_t N, size_t r, size_t p)
{
#if defined(BOTAN_HAS_SCRYPT)
return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
Botan::scrypt(out, out_len, passphrase, salt, salt_len, N, r, p);
return BOTAN_FFI_SUCCESS;
});
#else
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
}
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(BOTAN_CURRENT_FUNCTION, [=]() -> 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)
throw FFI_Error("Bad bcrypt work factor " + std::to_string(wf), 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(BOTAN_CURRENT_FUNCTION, [=]() -> int {
return Botan::check_bcrypt(pass, hash) ? BOTAN_FFI_SUCCESS : BOTAN_FFI_INVALID_VERIFIER;
});
#else
return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
#endif
}
}
|