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