• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 24063525848

06 Apr 2026 10:36PM UTC coverage: 89.448% (-0.007%) from 89.455%
24063525848

push

github

web-flow
Merge pull request #5521 from randombit/jack/fix-rollup

Rollup of small fixes

105878 of 118368 relevant lines covered (89.45%)

11475460.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.61
/src/lib/ffi/ffi_kdf.cpp
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

19
extern "C" {
20

21
using namespace Botan_FFI;
22

23
int botan_pbkdf(const char* algo,
1✔
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);
1✔
31
}
32

33
int botan_pbkdf_timed(const char* algo,
2✔
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,
2✔
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);
2✔
52
}
53

54
int botan_pwdhash(const char* algo,
9✔
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) {
9✔
65
      return BOTAN_FFI_ERROR_NULL_POINTER;
66
   }
67

68
   if(password_len == 0) {
9✔
69
      password_len = std::strlen(password);
4✔
70
   }
71

72
   return ffi_guard_thunk(__func__, [=]() -> int {
9✔
73
      auto pwdhash_fam = Botan::PasswordHashFamily::create(algo);
9✔
74

75
      if(!pwdhash_fam) {
9✔
76
         return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
77
      }
78

79
      auto pwdhash = pwdhash_fam->from_params(param1, param2, param3);
9✔
80

81
      pwdhash->derive_key(out, out_len, password, password_len, salt, salt_len);
9✔
82

83
      return BOTAN_FFI_SUCCESS;
9✔
84
   });
27✔
85
}
86

87
int botan_pwdhash_timed(const char* algo,
4✔
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) {
4✔
99
      return BOTAN_FFI_ERROR_NULL_POINTER;
100
   }
101

102
   if(password_len == 0) {
4✔
103
      password_len = std::strlen(password);
2✔
104
   }
105

106
   return ffi_guard_thunk(__func__, [=]() -> int {
4✔
107
      auto pwdhash_fam = Botan::PasswordHashFamily::create(algo);
4✔
108

109
      if(!pwdhash_fam) {
4✔
110
         return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
111
      }
112

113
      auto pwdhash = pwdhash_fam->tune_params(out_len, msec);
4✔
114

115
      if(param1 != nullptr) {
4✔
116
         *param1 = pwdhash->iterations();
4✔
117
      }
118
      if(param2 != nullptr) {
4✔
119
         *param2 = pwdhash->parallelism();
1✔
120
      }
121
      if(param3 != nullptr) {
4✔
122
         *param3 = pwdhash->memory_param();
1✔
123
      }
124

125
      pwdhash->derive_key(out, out_len, password, password_len, salt, salt_len);
4✔
126

127
      return BOTAN_FFI_SUCCESS;
4✔
128
   });
12✔
129
}
130

131
int botan_kdf(const char* kdf_algo,
2✔
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
   if(kdf_algo == nullptr) {
2✔
141
      return BOTAN_FFI_ERROR_NULL_POINTER;
142
   }
143
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
144
      auto kdf = Botan::KDF::create_or_throw(kdf_algo);
2✔
145
      kdf->kdf(out, out_len, secret, secret_len, salt, salt_len, label, label_len);
2✔
146
      return BOTAN_FFI_SUCCESS;
2✔
147
   });
4✔
148
}
149

150
int botan_scrypt(uint8_t out[],
1✔
151
                 size_t out_len,
152
                 const char* password,
153
                 const uint8_t salt[],
154
                 size_t salt_len,
155
                 size_t N,
156
                 size_t r,
157
                 size_t p) {
158
   return botan_pwdhash("Scrypt", N, r, p, out, out_len, password, 0, salt, salt_len);
1✔
159
}
160

161
int botan_bcrypt_generate(
2✔
162
   uint8_t* out, size_t* out_len, const char* pass, botan_rng_t rng_obj, size_t wf, uint32_t flags) {
163
#if defined(BOTAN_HAS_BCRYPT)
164
   return ffi_guard_thunk(__func__, [=]() -> int {
2✔
165
      if(out == nullptr || out_len == nullptr || pass == nullptr) {
2✔
166
         return BOTAN_FFI_ERROR_NULL_POINTER;
167
      }
168

169
      if(flags != 0) {
2✔
170
         return BOTAN_FFI_ERROR_BAD_FLAG;
171
      }
172

173
      if(wf < 4 || wf > 18) {
2✔
174
         return BOTAN_FFI_ERROR_BAD_PARAMETER;
175
      }
176

177
      if(*out_len < 61) {
2✔
178
         *out_len = 61;
×
179
         return BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE;
×
180
      }
181

182
      Botan::RandomNumberGenerator& rng = safe_get(rng_obj);
2✔
183
      const std::string bcrypt = Botan::generate_bcrypt(pass, rng, static_cast<uint16_t>(wf));
2✔
184
      // TODO(Botan4) change the type of out and remove this cast
185
      return write_str_output(reinterpret_cast<char*>(out), out_len, bcrypt);
2✔
186
   });
2✔
187
#else
188
   BOTAN_UNUSED(out, out_len, pass, rng_obj, wf, flags);
189
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
190
#endif
191
}
192

193
int botan_bcrypt_is_valid(const char* pass, const char* hash) {
5✔
194
   if(any_null_pointers(pass, hash)) {
5✔
195
      return BOTAN_FFI_ERROR_NULL_POINTER;
196
   }
197
#if defined(BOTAN_HAS_BCRYPT)
198
   return ffi_guard_thunk(__func__, [=]() -> int {
5✔
199
      return Botan::check_bcrypt(pass, hash) ? BOTAN_FFI_SUCCESS : BOTAN_FFI_INVALID_VERIFIER;
5✔
200
   });
5✔
201
#else
202
   BOTAN_UNUSED(pass, hash);
203
   return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
204
#endif
205
}
206
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc