Botan 3.3.0
Crypto and TLS for C&
ffi_kdf.cpp
Go to the documentation of this file.
1/*
2* (C) 2015,2017 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/ffi.h>
8
9#include <botan/kdf.h>
10#include <botan/pwdhash.h>
11#include <botan/internal/ffi_rng.h>
12#include <botan/internal/ffi_util.h>
13
14#if defined(BOTAN_HAS_BCRYPT)
15 #include <botan/bcrypt.h>
16#endif
17
18extern "C" {
19
20using namespace Botan_FFI;
21
22int botan_pbkdf(const char* algo,
23 uint8_t out[],
24 size_t out_len,
25 const char* pass,
26 const uint8_t salt[],
27 size_t salt_len,
28 size_t iterations) {
29 return botan_pwdhash(algo, iterations, 0, 0, out, out_len, pass, 0, salt, salt_len);
30}
31
32int botan_pbkdf_timed(const char* algo,
33 uint8_t out[],
34 size_t out_len,
35 const char* password,
36 const uint8_t salt[],
37 size_t salt_len,
38 size_t ms_to_run,
39 size_t* iterations_used) {
40 return botan_pwdhash_timed(algo,
41 static_cast<uint32_t>(ms_to_run),
42 iterations_used,
43 nullptr,
44 nullptr,
45 out,
46 out_len,
47 password,
48 0,
49 salt,
50 salt_len);
51}
52
53int botan_pwdhash(const char* algo,
54 size_t param1,
55 size_t param2,
56 size_t param3,
57 uint8_t out[],
58 size_t out_len,
59 const char* password,
60 size_t password_len,
61 const uint8_t salt[],
62 size_t salt_len) {
63 if(algo == nullptr || password == nullptr) {
65 }
66
67 if(password_len == 0) {
68 password_len = std::strlen(password);
69 }
70
71 return ffi_guard_thunk(__func__, [=]() -> int {
72 auto pwdhash_fam = Botan::PasswordHashFamily::create(algo);
73
74 if(!pwdhash_fam) {
76 }
77
78 auto pwdhash = pwdhash_fam->from_params(param1, param2, param3);
79
80 pwdhash->derive_key(out, out_len, password, password_len, salt, salt_len);
81
82 return BOTAN_FFI_SUCCESS;
83 });
84}
85
86int botan_pwdhash_timed(const char* algo,
87 uint32_t msec,
88 size_t* param1,
89 size_t* param2,
90 size_t* param3,
91 uint8_t out[],
92 size_t out_len,
93 const char* password,
94 size_t password_len,
95 const uint8_t salt[],
96 size_t salt_len) {
97 if(algo == nullptr || password == nullptr) {
99 }
100
101 if(password_len == 0) {
102 password_len = std::strlen(password);
103 }
104
105 return ffi_guard_thunk(__func__, [=]() -> int {
106 auto pwdhash_fam = Botan::PasswordHashFamily::create(algo);
107
108 if(!pwdhash_fam) {
110 }
111
112 auto pwdhash = pwdhash_fam->tune(out_len, std::chrono::milliseconds(msec));
113
114 if(param1) {
115 *param1 = pwdhash->iterations();
116 }
117 if(param2) {
118 *param2 = pwdhash->parallelism();
119 }
120 if(param3) {
121 *param3 = pwdhash->memory_param();
122 }
123
124 pwdhash->derive_key(out, out_len, password, password_len, salt, salt_len);
125
126 return BOTAN_FFI_SUCCESS;
127 });
128}
129
130int botan_kdf(const char* kdf_algo,
131 uint8_t out[],
132 size_t out_len,
133 const uint8_t secret[],
134 size_t secret_len,
135 const uint8_t salt[],
136 size_t salt_len,
137 const uint8_t label[],
138 size_t label_len) {
139 return ffi_guard_thunk(__func__, [=]() -> int {
140 auto kdf = Botan::KDF::create_or_throw(kdf_algo);
141 kdf->kdf(out, out_len, secret, secret_len, salt, salt_len, label, label_len);
142 return BOTAN_FFI_SUCCESS;
143 });
144}
145
146int botan_scrypt(uint8_t out[],
147 size_t out_len,
148 const char* password,
149 const uint8_t salt[],
150 size_t salt_len,
151 size_t N,
152 size_t r,
153 size_t p) {
154 return botan_pwdhash("Scrypt", N, r, p, out, out_len, password, 0, salt, salt_len);
155}
156
158 uint8_t* out, size_t* out_len, const char* pass, botan_rng_t rng_obj, size_t wf, uint32_t flags) {
159#if defined(BOTAN_HAS_BCRYPT)
160 return ffi_guard_thunk(__func__, [=]() -> int {
161 if(out == nullptr || out_len == nullptr || pass == nullptr) {
163 }
164
165 if(flags != 0) {
167 }
168
169 if(wf < 4 || wf > 18) {
171 }
172
173 if(*out_len < 61) {
174 *out_len = 61;
176 }
177
179 const std::string bcrypt = Botan::generate_bcrypt(pass, rng, static_cast<uint16_t>(wf));
180 return write_str_output(out, out_len, bcrypt);
181 });
182#else
183 BOTAN_UNUSED(out, out_len, pass, rng_obj, wf, flags);
185#endif
186}
187
188int botan_bcrypt_is_valid(const char* pass, const char* hash) {
189#if defined(BOTAN_HAS_BCRYPT)
190 return ffi_guard_thunk(__func__, [=]() -> int {
192 });
193#else
194 BOTAN_UNUSED(pass, hash);
196#endif
197}
198}
#define BOTAN_UNUSED
Definition assert.h:118
static std::unique_ptr< KDF > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition kdf.cpp:193
static std::unique_ptr< PasswordHashFamily > create(std::string_view algo_spec, std::string_view provider="")
Definition pwdhash.cpp:53
struct botan_rng_struct * botan_rng_t
Definition ffi.h:246
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
Definition ffi.h:110
@ BOTAN_FFI_INVALID_VERIFIER
Definition ffi.h:90
@ BOTAN_FFI_ERROR_BAD_FLAG
Definition ffi.h:103
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition ffi.h:104
@ BOTAN_FFI_SUCCESS
Definition ffi.h:89
@ BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE
Definition ffi.h:95
@ BOTAN_FFI_ERROR_BAD_PARAMETER
Definition ffi.h:105
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)
Definition ffi_kdf.cpp:22
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)
Definition ffi_kdf.cpp:86
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)
Definition ffi_kdf.cpp:32
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)
Definition ffi_kdf.cpp:146
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)
Definition ffi_kdf.cpp:157
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)
Definition ffi_kdf.cpp:130
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)
Definition ffi_kdf.cpp:53
int botan_bcrypt_is_valid(const char *pass, const char *hash)
Definition ffi_kdf.cpp:188
int write_str_output(uint8_t out[], size_t *out_len, std::string_view str)
Definition ffi_util.h:205
T & safe_get(botan_struct< T, M > *p)
Definition ffi_util.h:63
int ffi_guard_thunk(const char *func_name, const std::function< int()> &thunk)
Definition ffi.cpp:116
std::string generate_bcrypt(std::string_view pass, RandomNumberGenerator &rng, uint16_t work_factor, char version)
Definition bcrypt.cpp:144
bool check_bcrypt(std::string_view pass, std::string_view hash)
Definition bcrypt.cpp:159