Botan 3.4.0
Crypto and TLS for C&
pwdhash.cpp
Go to the documentation of this file.
1/*
2* (C) 2018 Ribose Inc
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/pwdhash.h>
8
9#include <botan/exceptn.h>
10#include <botan/internal/scan_name.h>
11
12#if defined(BOTAN_HAS_PBKDF2)
13 #include <botan/pbkdf2.h>
14#endif
15
16#if defined(BOTAN_HAS_PGP_S2K)
17 #include <botan/pgp_s2k.h>
18#endif
19
20#if defined(BOTAN_HAS_SCRYPT)
21 #include <botan/scrypt.h>
22#endif
23
24#if defined(BOTAN_HAS_ARGON2)
25 #include <botan/argon2.h>
26#endif
27
28#if defined(BOTAN_HAS_PBKDF_BCRYPT)
29 #include <botan/bcrypt_pbkdf.h>
30#endif
31
32namespace Botan {
33
34void PasswordHash::derive_key(uint8_t out[],
35 size_t out_len,
36 const char* password,
37 size_t password_len,
38 const uint8_t salt[],
39 size_t salt_len,
40 const uint8_t ad[],
41 size_t ad_len,
42 const uint8_t key[],
43 size_t key_len) const {
44 BOTAN_UNUSED(ad, key);
45
46 if(ad_len == 0 && key_len == 0) {
47 return this->derive_key(out, out_len, password, password_len, salt, salt_len);
48 } else {
49 throw Not_Implemented("PasswordHash " + this->to_string() + " does not support AD or key");
50 }
51}
52
53std::unique_ptr<PasswordHashFamily> PasswordHashFamily::create(std::string_view algo_spec, std::string_view provider) {
54 const SCAN_Name req(algo_spec);
55
56#if defined(BOTAN_HAS_PBKDF2)
57 if(req.algo_name() == "PBKDF2") {
58 if(provider.empty() || provider == "base") {
59 if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")")) {
60 return std::make_unique<PBKDF2_Family>(std::move(mac));
61 }
62
63 if(auto mac = MessageAuthenticationCode::create(req.arg(0))) {
64 return std::make_unique<PBKDF2_Family>(std::move(mac));
65 }
66 }
67
68 return nullptr;
69 }
70#endif
71
72#if defined(BOTAN_HAS_SCRYPT)
73 if(req.algo_name() == "Scrypt") {
74 return std::make_unique<Scrypt_Family>();
75 }
76#endif
77
78#if defined(BOTAN_HAS_ARGON2)
79 if(req.algo_name() == "Argon2d") {
80 return std::make_unique<Argon2_Family>(static_cast<uint8_t>(0));
81 } else if(req.algo_name() == "Argon2i") {
82 return std::make_unique<Argon2_Family>(static_cast<uint8_t>(1));
83 } else if(req.algo_name() == "Argon2id") {
84 return std::make_unique<Argon2_Family>(static_cast<uint8_t>(2));
85 }
86#endif
87
88#if defined(BOTAN_HAS_PBKDF_BCRYPT)
89 if(req.algo_name() == "Bcrypt-PBKDF") {
90 return std::make_unique<Bcrypt_PBKDF_Family>();
91 }
92#endif
93
94#if defined(BOTAN_HAS_PGP_S2K)
95 if(req.algo_name() == "OpenPGP-S2K" && req.arg_count() == 1) {
96 if(auto hash = HashFunction::create(req.arg(0))) {
97 return std::make_unique<RFC4880_S2K_Family>(std::move(hash));
98 }
99 }
100#endif
101
102 BOTAN_UNUSED(req);
103 BOTAN_UNUSED(provider);
104
105 return nullptr;
106}
107
108//static
109std::unique_ptr<PasswordHashFamily> PasswordHashFamily::create_or_throw(std::string_view algo,
110 std::string_view provider) {
111 if(auto pbkdf = PasswordHashFamily::create(algo, provider)) {
112 return pbkdf;
113 }
114 throw Lookup_Error("PasswordHashFamily", algo, provider);
115}
116
117std::vector<std::string> PasswordHashFamily::providers(std::string_view algo_spec) {
118 return probe_providers_of<PasswordHashFamily>(algo_spec);
119}
120
121} // namespace Botan
#define BOTAN_UNUSED
Definition assert.h:118
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::unique_ptr< PasswordHashFamily > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition pwdhash.cpp:109
static std::vector< std::string > providers(std::string_view algo_spec)
Definition pwdhash.cpp:117
static std::unique_ptr< PasswordHashFamily > create(std::string_view algo_spec, std::string_view provider="")
Definition pwdhash.cpp:53
virtual void derive_key(uint8_t out[], size_t out_len, const char *password, size_t password_len, const uint8_t salt[], size_t salt_len) const =0
virtual std::string to_string() const =0
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