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

randombit / botan / 23949924622

03 Apr 2026 02:35PM UTC coverage: 89.531% (+0.05%) from 89.479%
23949924622

Pull #5478

github

web-flow
Merge 543049103 into eaf12915e
Pull Request #5478: Add PKCS#12 KDF

105670 of 118026 relevant lines covered (89.53%)

11548366.4 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/internal/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,324✔
59
   const SCAN_Name req(algo_spec);
2,324✔
60

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

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

73
      return nullptr;
×
74
   }
75
#endif
76

77
#if defined(BOTAN_HAS_SCRYPT)
78
   if(req.algo_name() == "Scrypt") {
1,661✔
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,164✔
85
      return std::make_unique<Argon2_Family>(static_cast<uint8_t>(0));
40✔
86
   } else if(req.algo_name() == "Argon2i") {
1,124✔
87
      return std::make_unique<Argon2_Family>(static_cast<uint8_t>(1));
49✔
88
   } else if(req.algo_name() == "Argon2id") {
1,075✔
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") {
73✔
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) {
36✔
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)) {
22✔
109
      if(HashFunction::create(req.arg(0))) {
44✔
110
         const auto id_param = req.arg_as_integer(1, 1);
22✔
111
         if(id_param < 1 || id_param > 3) {
22✔
112
            return nullptr;
×
113
         }
114
         return std::make_unique<PKCS12_KDF_Family>(req.arg(0), static_cast<uint8_t>(id_param));
22✔
115
      }
116
   }
117
#endif
118

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

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

125
//static
126
std::unique_ptr<PasswordHashFamily> PasswordHashFamily::create_or_throw(std::string_view algo,
828✔
127
                                                                        std::string_view provider) {
128
   if(auto pbkdf = PasswordHashFamily::create(algo, provider)) {
828✔
129
      return pbkdf;
828✔
130
   }
828✔
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