Coverage Report

Created: 2026-06-07 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/botan/src/lib/kdf/kdf2/kdf2.cpp
Line
Count
Source
1
/*
2
* KDF2
3
* (C) 1999-2007 Jack Lloyd
4
* (C) 2024      René Meusel, Rohde & Schwarz Cybersecurity
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8
9
#include <botan/internal/kdf2.h>
10
11
#include <botan/exceptn.h>
12
#include <botan/internal/bit_ops.h>
13
#include <botan/internal/fmt.h>
14
#include <botan/internal/stl_util.h>
15
16
namespace Botan {
17
18
0
std::string KDF2::name() const {
19
0
   return fmt("KDF2({})", m_hash->name());
20
0
}
21
22
0
std::unique_ptr<KDF> KDF2::new_object() const {
23
0
   return std::make_unique<KDF2>(m_hash->new_object());
24
0
}
25
26
void KDF2::perform_kdf(std::span<uint8_t> key,
27
                       std::span<const uint8_t> secret,
28
                       std::span<const uint8_t> salt,
29
0
                       std::span<const uint8_t> label) const {
30
0
   if(key.empty()) {
31
0
      return;
32
0
   }
33
34
0
   const size_t hash_output_length = m_hash->output_length();
35
0
   const auto blocks_required = ceil_division<uint64_t /* for 32bit systems */>(key.size(), hash_output_length);
36
37
   // This KDF uses a 32-bit counter for the hash blocks, initialized at 1.
38
   // It will wrap around after 2^32 - 1 iterations limiting the theoretically
39
   // possible output to 2^32 - 1 blocks.
40
0
   BOTAN_ARG_CHECK(blocks_required <= 0xFFFFFFFE, "KDF2 maximum output length exceeeded");
41
42
0
   BufferStuffer k(key);
43
0
   for(uint32_t counter = 1; !k.full(); ++counter) {
44
0
      BOTAN_ASSERT_NOMSG(counter != 0);  // no overflow
45
46
0
      m_hash->update(secret);
47
0
      m_hash->update_be(counter);
48
0
      m_hash->update(label);
49
0
      m_hash->update(salt);
50
51
      // Write straight into the output buffer, except if the hash output needs
52
      // a truncation in the final iteration.
53
0
      if(k.remaining_capacity() >= hash_output_length) {
54
0
         m_hash->final(k.next(hash_output_length));
55
0
      } else {
56
0
         const auto h = m_hash->final();
57
0
         k.append(std::span{h}.first(k.remaining_capacity()));
58
0
      }
59
0
   }
60
0
}
61
62
}  // namespace Botan