Coverage Report

Created: 2026-06-09 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/Botan-3.4.0/src/lib/pbkdf/pbkdf.cpp
Line
Count
Source
1
/*
2
* PBKDF
3
* (C) 2012 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/pbkdf.h>
9
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
namespace Botan {
22
23
0
std::unique_ptr<PBKDF> PBKDF::create(std::string_view algo_spec, std::string_view provider) {
24
0
   const SCAN_Name req(algo_spec);
25
26
#if defined(BOTAN_HAS_PBKDF2)
27
   if(req.algo_name() == "PBKDF2") {
28
      // TODO OpenSSL
29
30
      if(provider.empty() || provider == "base") {
31
         if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")")) {
32
            return std::make_unique<PKCS5_PBKDF2>(std::move(mac));
33
         }
34
35
         if(auto mac = MessageAuthenticationCode::create(req.arg(0))) {
36
            return std::make_unique<PKCS5_PBKDF2>(std::move(mac));
37
         }
38
      }
39
40
      return nullptr;
41
   }
42
#endif
43
44
0
#if defined(BOTAN_HAS_PGP_S2K)
45
0
   if(req.algo_name() == "OpenPGP-S2K" && req.arg_count() == 1) {
46
0
      if(auto hash = HashFunction::create(req.arg(0))) {
47
0
         return std::make_unique<OpenPGP_S2K>(std::move(hash));
48
0
      }
49
0
   }
50
0
#endif
51
52
0
   BOTAN_UNUSED(req);
53
0
   BOTAN_UNUSED(provider);
54
55
0
   return nullptr;
56
0
}
57
58
//static
59
0
std::unique_ptr<PBKDF> PBKDF::create_or_throw(std::string_view algo, std::string_view provider) {
60
0
   if(auto pbkdf = PBKDF::create(algo, provider)) {
61
0
      return pbkdf;
62
0
   }
63
0
   throw Lookup_Error("PBKDF", algo, provider);
64
0
}
65
66
0
std::vector<std::string> PBKDF::providers(std::string_view algo_spec) {
67
0
   return probe_providers_of<PBKDF>(algo_spec);
68
0
}
69
70
void PBKDF::pbkdf_timed(uint8_t out[],
71
                        size_t out_len,
72
                        std::string_view passphrase,
73
                        const uint8_t salt[],
74
                        size_t salt_len,
75
                        std::chrono::milliseconds msec,
76
0
                        size_t& iterations) const {
77
0
   iterations = pbkdf(out, out_len, passphrase, salt, salt_len, 0, msec);
78
0
}
79
80
void PBKDF::pbkdf_iterations(uint8_t out[],
81
                             size_t out_len,
82
                             std::string_view passphrase,
83
                             const uint8_t salt[],
84
                             size_t salt_len,
85
0
                             size_t iterations) const {
86
0
   if(iterations == 0) {
87
0
      throw Invalid_Argument(name() + ": Invalid iteration count");
88
0
   }
89
90
0
   const size_t iterations_run =
91
0
      pbkdf(out, out_len, passphrase, salt, salt_len, iterations, std::chrono::milliseconds(0));
92
0
   BOTAN_ASSERT_EQUAL(iterations, iterations_run, "Expected PBKDF iterations");
93
0
}
94
95
secure_vector<uint8_t> PBKDF::pbkdf_iterations(
96
0
   size_t out_len, std::string_view passphrase, const uint8_t salt[], size_t salt_len, size_t iterations) const {
97
0
   secure_vector<uint8_t> out(out_len);
98
0
   pbkdf_iterations(out.data(), out_len, passphrase, salt, salt_len, iterations);
99
0
   return out;
100
0
}
101
102
secure_vector<uint8_t> PBKDF::pbkdf_timed(size_t out_len,
103
                                          std::string_view passphrase,
104
                                          const uint8_t salt[],
105
                                          size_t salt_len,
106
                                          std::chrono::milliseconds msec,
107
0
                                          size_t& iterations) const {
108
0
   secure_vector<uint8_t> out(out_len);
109
0
   pbkdf_timed(out.data(), out_len, passphrase, salt, salt_len, msec, iterations);
110
0
   return out;
111
0
}
112
113
}  // namespace Botan