Coverage Report

Created: 2026-04-01 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/botan/src/lib/pbkdf/pwdhash.cpp
Line
Count
Source
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
33
namespace Botan {
34
35
void 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
0
                              size_t key_len) const {
45
0
   BOTAN_UNUSED(ad, key);
46
47
0
   if(ad_len == 0 && key_len == 0) {
48
0
      return this->derive_key(out, out_len, password, password_len, salt, salt_len);
49
0
   } else {
50
0
      throw Not_Implemented("PasswordHash " + this->to_string() + " does not support AD or key");
51
0
   }
52
0
}
53
54
0
std::unique_ptr<PasswordHashFamily> PasswordHashFamily::create(std::string_view algo_spec, std::string_view provider) {
55
0
   const SCAN_Name req(algo_spec);
56
57
0
#if defined(BOTAN_HAS_PBKDF2)
58
0
   if(req.algo_name() == "PBKDF2") {
59
0
      if(provider.empty() || provider == "base") {
60
0
         if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")")) {
61
0
            return std::make_unique<PBKDF2_Family>(std::move(mac));
62
0
         }
63
64
0
         if(auto mac = MessageAuthenticationCode::create(req.arg(0))) {
65
0
            return std::make_unique<PBKDF2_Family>(std::move(mac));
66
0
         }
67
0
      }
68
69
0
      return nullptr;
70
0
   }
71
0
#endif
72
73
0
#if defined(BOTAN_HAS_SCRYPT)
74
0
   if(req.algo_name() == "Scrypt") {
75
0
      return std::make_unique<Scrypt_Family>();
76
0
   }
77
0
#endif
78
79
0
#if defined(BOTAN_HAS_ARGON2)
80
0
   if(req.algo_name() == "Argon2d") {
81
0
      return std::make_unique<Argon2_Family>(static_cast<uint8_t>(0));
82
0
   } else if(req.algo_name() == "Argon2i") {
83
0
      return std::make_unique<Argon2_Family>(static_cast<uint8_t>(1));
84
0
   } else if(req.algo_name() == "Argon2id") {
85
0
      return std::make_unique<Argon2_Family>(static_cast<uint8_t>(2));
86
0
   }
87
0
#endif
88
89
0
#if defined(BOTAN_HAS_PBKDF_BCRYPT)
90
0
   if(req.algo_name() == "Bcrypt-PBKDF") {
91
0
      return std::make_unique<Bcrypt_PBKDF_Family>();
92
0
   }
93
0
#endif
94
95
0
#if defined(BOTAN_HAS_PGP_S2K)
96
0
   if(req.algo_name() == "OpenPGP-S2K" && req.arg_count() == 1) {
97
0
      if(auto hash = HashFunction::create(req.arg(0))) {
98
0
         return std::make_unique<RFC4880_S2K_Family>(std::move(hash));
99
0
      }
100
0
   }
101
0
#endif
102
103
0
   BOTAN_UNUSED(req);
104
0
   BOTAN_UNUSED(provider);
105
106
0
   return nullptr;
107
0
}
108
109
//static
110
std::unique_ptr<PasswordHashFamily> PasswordHashFamily::create_or_throw(std::string_view algo,
111
0
                                                                        std::string_view provider) {
112
0
   if(auto pbkdf = PasswordHashFamily::create(algo, provider)) {
113
0
      return pbkdf;
114
0
   }
115
0
   throw Lookup_Error("PasswordHashFamily", algo, provider);
116
0
}
117
118
0
std::vector<std::string> PasswordHashFamily::providers(std::string_view algo_spec) {
119
0
   return probe_providers_of<PasswordHashFamily>(algo_spec);
120
0
}
121
122
}  // namespace Botan