Botan 3.5.0
Crypto and TLS for C&
pbkdf.cpp
Go to the documentation of this file.
1/*
2* PBKDF
3* (C) 2012 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/pbkdf.h>
9
10#include <botan/exceptn.h>
11#include <botan/internal/scan_name.h>
12
13#if defined(BOTAN_HAS_PBKDF2)
14 #include <botan/pbkdf2.h>
15#endif
16
17#if defined(BOTAN_HAS_PGP_S2K)
18 #include <botan/pgp_s2k.h>
19#endif
20
21namespace Botan {
22
23std::unique_ptr<PBKDF> PBKDF::create(std::string_view algo_spec, std::string_view provider) {
24 const SCAN_Name req(algo_spec);
25
26#if defined(BOTAN_HAS_PBKDF2)
27 if(req.algo_name() == "PBKDF2") {
28 // TODO OpenSSL
29
30 if(provider.empty() || provider == "base") {
31 if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")")) {
32 return std::make_unique<PKCS5_PBKDF2>(std::move(mac));
33 }
34
35 if(auto mac = MessageAuthenticationCode::create(req.arg(0))) {
36 return std::make_unique<PKCS5_PBKDF2>(std::move(mac));
37 }
38 }
39
40 return nullptr;
41 }
42#endif
43
44#if defined(BOTAN_HAS_PGP_S2K)
45 if(req.algo_name() == "OpenPGP-S2K" && req.arg_count() == 1) {
46 if(auto hash = HashFunction::create(req.arg(0))) {
47 return std::make_unique<OpenPGP_S2K>(std::move(hash));
48 }
49 }
50#endif
51
52 BOTAN_UNUSED(req);
53 BOTAN_UNUSED(provider);
54
55 return nullptr;
56}
57
58//static
59std::unique_ptr<PBKDF> PBKDF::create_or_throw(std::string_view algo, std::string_view provider) {
60 if(auto pbkdf = PBKDF::create(algo, provider)) {
61 return pbkdf;
62 }
63 throw Lookup_Error("PBKDF", algo, provider);
64}
65
66std::vector<std::string> PBKDF::providers(std::string_view algo_spec) {
67 return probe_providers_of<PBKDF>(algo_spec);
68}
69
70void PBKDF::pbkdf_timed(uint8_t out[],
71 size_t out_len,
72 std::string_view passphrase,
73 const uint8_t salt[],
74 size_t salt_len,
75 std::chrono::milliseconds msec,
76 size_t& iterations) const {
77 iterations = pbkdf(out, out_len, passphrase, salt, salt_len, 0, msec);
78}
79
80void PBKDF::pbkdf_iterations(uint8_t out[],
81 size_t out_len,
82 std::string_view passphrase,
83 const uint8_t salt[],
84 size_t salt_len,
85 size_t iterations) const {
86 if(iterations == 0) {
87 throw Invalid_Argument(name() + ": Invalid iteration count");
88 }
89
90 const size_t iterations_run =
91 pbkdf(out, out_len, passphrase, salt, salt_len, iterations, std::chrono::milliseconds(0));
92 BOTAN_ASSERT_EQUAL(iterations, iterations_run, "Expected PBKDF iterations");
93}
94
96 size_t out_len, std::string_view passphrase, const uint8_t salt[], size_t salt_len, size_t iterations) const {
97 secure_vector<uint8_t> out(out_len);
98 pbkdf_iterations(out.data(), out_len, passphrase, salt, salt_len, iterations);
99 return out;
100}
101
103 std::string_view passphrase,
104 const uint8_t salt[],
105 size_t salt_len,
106 std::chrono::milliseconds msec,
107 size_t& iterations) const {
108 secure_vector<uint8_t> out(out_len);
109 pbkdf_timed(out.data(), out_len, passphrase, salt, salt_len, msec, iterations);
110 return out;
111}
112
113} // namespace Botan
#define BOTAN_UNUSED
Definition assert.h:118
#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made)
Definition assert.h:68
static std::unique_ptr< HashFunction > create(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:107
static std::unique_ptr< MessageAuthenticationCode > create(std::string_view algo_spec, std::string_view provider="")
Definition mac.cpp:51
static std::vector< std::string > providers(std::string_view algo_spec)
Definition pbkdf.cpp:66
static std::unique_ptr< PBKDF > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition pbkdf.cpp:59
virtual size_t pbkdf(uint8_t out[], size_t out_len, std::string_view passphrase, const uint8_t salt[], size_t salt_len, size_t iterations, std::chrono::milliseconds msec) const =0
void pbkdf_iterations(uint8_t out[], size_t out_len, std::string_view passphrase, const uint8_t salt[], size_t salt_len, size_t iterations) const
Definition pbkdf.cpp:80
void pbkdf_timed(uint8_t out[], size_t out_len, std::string_view passphrase, const uint8_t salt[], size_t salt_len, std::chrono::milliseconds msec, size_t &iterations) const
Definition pbkdf.cpp:70
virtual std::string name() const =0
static std::unique_ptr< PBKDF > create(std::string_view algo_spec, std::string_view provider="")
Definition pbkdf.cpp:23
std::string arg(size_t i) const
size_t arg_count() const
Definition scan_name.h:49
const std::string & algo_name() const
Definition scan_name.h:44
std::vector< std::string > probe_providers_of(std::string_view algo_spec, const std::vector< std::string > &possible={"base"})
Definition scan_name.h:105
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61