Coverage Report

Created: 2024-11-21 07:03

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