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