/src/Botan-3.4.0/src/lib/ffi/ffi_kdf.cpp
Line | Count | Source |
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 | | |
18 | | extern "C" { |
19 | | |
20 | | using namespace Botan_FFI; |
21 | | |
22 | | int 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 | 0 | size_t iterations) { |
29 | 0 | return botan_pwdhash(algo, iterations, 0, 0, out, out_len, pass, 0, salt, salt_len); |
30 | 0 | } |
31 | | |
32 | | int 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 | 0 | size_t* iterations_used) { |
40 | 0 | return botan_pwdhash_timed(algo, |
41 | 0 | static_cast<uint32_t>(ms_to_run), |
42 | 0 | iterations_used, |
43 | 0 | nullptr, |
44 | 0 | nullptr, |
45 | 0 | out, |
46 | 0 | out_len, |
47 | 0 | password, |
48 | 0 | 0, |
49 | 0 | salt, |
50 | 0 | salt_len); |
51 | 0 | } |
52 | | |
53 | | int 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 | 0 | size_t salt_len) { |
63 | 0 | if(algo == nullptr || password == nullptr) { |
64 | 0 | return BOTAN_FFI_ERROR_NULL_POINTER; |
65 | 0 | } |
66 | | |
67 | 0 | if(password_len == 0) { |
68 | 0 | password_len = std::strlen(password); |
69 | 0 | } |
70 | |
|
71 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
72 | 0 | auto pwdhash_fam = Botan::PasswordHashFamily::create(algo); |
73 | |
|
74 | 0 | if(!pwdhash_fam) { |
75 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
76 | 0 | } |
77 | | |
78 | 0 | auto pwdhash = pwdhash_fam->from_params(param1, param2, param3); |
79 | |
|
80 | 0 | pwdhash->derive_key(out, out_len, password, password_len, salt, salt_len); |
81 | |
|
82 | 0 | return BOTAN_FFI_SUCCESS; |
83 | 0 | }); |
84 | 0 | } |
85 | | |
86 | | int 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 | 0 | size_t salt_len) { |
97 | 0 | if(algo == nullptr || password == nullptr) { |
98 | 0 | return BOTAN_FFI_ERROR_NULL_POINTER; |
99 | 0 | } |
100 | | |
101 | 0 | if(password_len == 0) { |
102 | 0 | password_len = std::strlen(password); |
103 | 0 | } |
104 | |
|
105 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
106 | 0 | auto pwdhash_fam = Botan::PasswordHashFamily::create(algo); |
107 | |
|
108 | 0 | if(!pwdhash_fam) { |
109 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
110 | 0 | } |
111 | | |
112 | 0 | auto pwdhash = pwdhash_fam->tune(out_len, std::chrono::milliseconds(msec)); |
113 | |
|
114 | 0 | if(param1) { |
115 | 0 | *param1 = pwdhash->iterations(); |
116 | 0 | } |
117 | 0 | if(param2) { |
118 | 0 | *param2 = pwdhash->parallelism(); |
119 | 0 | } |
120 | 0 | if(param3) { |
121 | 0 | *param3 = pwdhash->memory_param(); |
122 | 0 | } |
123 | |
|
124 | 0 | pwdhash->derive_key(out, out_len, password, password_len, salt, salt_len); |
125 | |
|
126 | 0 | return BOTAN_FFI_SUCCESS; |
127 | 0 | }); |
128 | 0 | } |
129 | | |
130 | | int 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 | 0 | size_t label_len) { |
139 | 0 | return ffi_guard_thunk(__func__, [=]() -> int { |
140 | 0 | auto kdf = Botan::KDF::create_or_throw(kdf_algo); |
141 | 0 | kdf->kdf(out, out_len, secret, secret_len, salt, salt_len, label, label_len); |
142 | 0 | return BOTAN_FFI_SUCCESS; |
143 | 0 | }); |
144 | 0 | } |
145 | | |
146 | | int 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 | 0 | size_t p) { |
154 | 0 | return botan_pwdhash("Scrypt", N, r, p, out, out_len, password, 0, salt, salt_len); |
155 | 0 | } |
156 | | |
157 | | int botan_bcrypt_generate( |
158 | 0 | 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) { |
162 | | return BOTAN_FFI_ERROR_NULL_POINTER; |
163 | | } |
164 | | |
165 | | if(flags != 0) { |
166 | | return BOTAN_FFI_ERROR_BAD_FLAG; |
167 | | } |
168 | | |
169 | | if(wf < 4 || wf > 18) { |
170 | | return BOTAN_FFI_ERROR_BAD_PARAMETER; |
171 | | } |
172 | | |
173 | | if(*out_len < 61) { |
174 | | *out_len = 61; |
175 | | return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE; |
176 | | } |
177 | | |
178 | | Botan::RandomNumberGenerator& rng = safe_get(rng_obj); |
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 | 0 | BOTAN_UNUSED(out, out_len, pass, rng_obj, wf, flags); |
184 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
185 | 0 | #endif |
186 | 0 | } |
187 | | |
188 | 0 | int botan_bcrypt_is_valid(const char* pass, const char* hash) { |
189 | | #if defined(BOTAN_HAS_BCRYPT) |
190 | | return ffi_guard_thunk(__func__, [=]() -> int { |
191 | | return Botan::check_bcrypt(pass, hash) ? BOTAN_FFI_SUCCESS : BOTAN_FFI_INVALID_VERIFIER; |
192 | | }); |
193 | | #else |
194 | 0 | BOTAN_UNUSED(pass, hash); |
195 | 0 | return BOTAN_FFI_ERROR_NOT_IMPLEMENTED; |
196 | 0 | #endif |
197 | 0 | } |
198 | | } |