• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 23429162741

23 Mar 2026 08:57AM UTC coverage: 89.429% (+0.001%) from 89.428%
23429162741

Pull #5478

github

web-flow
Merge ad264b826 into c868150bc
Pull Request #5478: Add PKCS#12 KDF

104928 of 117331 relevant lines covered (89.43%)

11861377.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.34
/src/lib/pbkdf/pwdhash.cpp
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
#if defined(BOTAN_HAS_PKCS12_KDF)
34
   #include <botan/pkcs12_kdf.h>
35
#endif
36

37
namespace Botan {
38

39
void PasswordHash::derive_key(uint8_t out[],
×
40
                              size_t out_len,
41
                              const char* password,
42
                              size_t password_len,
43
                              const uint8_t salt[],
44
                              size_t salt_len,
45
                              const uint8_t ad[],
46
                              size_t ad_len,
47
                              const uint8_t key[],
48
                              size_t key_len) const {
49
   BOTAN_UNUSED(ad, key);
×
50

51
   if(ad_len == 0 && key_len == 0) {
×
52
      return this->derive_key(out, out_len, password, password_len, salt, salt_len);
×
53
   } else {
54
      throw Not_Implemented("PasswordHash " + this->to_string() + " does not support AD or key");
×
55
   }
56
}
57

58
std::unique_ptr<PasswordHashFamily> PasswordHashFamily::create(std::string_view algo_spec, std::string_view provider) {
2,313✔
59
   const SCAN_Name req(algo_spec);
2,313✔
60

61
#if defined(BOTAN_HAS_PBKDF2)
62
   if(req.algo_name() == "PBKDF2") {
2,313✔
63
      if(provider.empty() || provider == "base") {
662✔
64
         if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")")) {
2,648✔
65
            return std::make_unique<PBKDF2_Family>(std::move(mac));
30✔
66
         }
30✔
67

68
         if(auto mac = MessageAuthenticationCode::create(req.arg(0))) {
1,264✔
69
            return std::make_unique<PBKDF2_Family>(std::move(mac));
632✔
70
         }
632✔
71
      }
72

73
      return nullptr;
×
74
   }
75
#endif
76

77
#if defined(BOTAN_HAS_SCRYPT)
78
   if(req.algo_name() == "Scrypt") {
1,651✔
79
      return std::make_unique<Scrypt_Family>();
497✔
80
   }
81
#endif
82

83
#if defined(BOTAN_HAS_ARGON2)
84
   if(req.algo_name() == "Argon2d") {
1,154✔
85
      return std::make_unique<Argon2_Family>(static_cast<uint8_t>(0));
40✔
86
   } else if(req.algo_name() == "Argon2i") {
1,114✔
87
      return std::make_unique<Argon2_Family>(static_cast<uint8_t>(1));
49✔
88
   } else if(req.algo_name() == "Argon2id") {
1,065✔
89
      return std::make_unique<Argon2_Family>(static_cast<uint8_t>(2));
1,002✔
90
   }
91
#endif
92

93
#if defined(BOTAN_HAS_PBKDF_BCRYPT)
94
   if(req.algo_name() == "Bcrypt-PBKDF") {
63✔
95
      return std::make_unique<Bcrypt_PBKDF_Family>();
37✔
96
   }
97
#endif
98

99
#if defined(BOTAN_HAS_PGP_S2K)
100
   if(req.algo_name() == "OpenPGP-S2K" && req.arg_count() == 1) {
26✔
101
      if(auto hash = HashFunction::create(req.arg(0))) {
28✔
102
         return std::make_unique<RFC4880_S2K_Family>(std::move(hash));
14✔
103
      }
14✔
104
   }
105
#endif
106

107
#if defined(BOTAN_HAS_PKCS12_KDF)
108
   if(req.algo_name() == "PKCS12-KDF" && req.arg_count_between(1, 2)) {
12✔
109
      if(HashFunction::create(req.arg(0))) {
24✔
110
         const auto id_param = req.arg_as_integer(1, 1);
12✔
111
         if(id_param < 1 || id_param > 3) {
12✔
112
            return nullptr;
×
113
         }
114
         return std::make_unique<PKCS12_KDF_Family>(req.arg(0), static_cast<uint8_t>(id_param));
12✔
115
      }
116
   }
117
#endif
118

119
   BOTAN_UNUSED(req);
×
120
   BOTAN_UNUSED(provider);
×
121

122
   return nullptr;
×
123
}
2,313✔
124

125
//static
126
std::unique_ptr<PasswordHashFamily> PasswordHashFamily::create_or_throw(std::string_view algo,
827✔
127
                                                                        std::string_view provider) {
128
   if(auto pbkdf = PasswordHashFamily::create(algo, provider)) {
827✔
129
      return pbkdf;
827✔
130
   }
827✔
131
   throw Lookup_Error("PasswordHashFamily", algo, provider);
×
132
}
133

134
std::vector<std::string> PasswordHashFamily::providers(std::string_view algo_spec) {
×
135
   return probe_providers_of<PasswordHashFamily>(algo_spec);
×
136
}
137

138
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc