Coverage Report

Created: 2024-11-29 06:10

/src/botan/src/lib/kdf/prf_x942/prf_x942.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* X9.42 PRF
3
* (C) 1999-2007 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/internal/prf_x942.h>
9
10
#include <botan/der_enc.h>
11
#include <botan/hash.h>
12
#include <botan/internal/loadstor.h>
13
#include <algorithm>
14
15
namespace Botan {
16
17
namespace {
18
19
/*
20
* Encode an integer as an OCTET STRING
21
*/
22
0
std::vector<uint8_t> encode_x942_int(uint32_t n) {
23
0
   uint8_t n_buf[4] = {0};
24
0
   store_be(n, n_buf);
25
26
0
   std::vector<uint8_t> output;
27
0
   DER_Encoder(output).encode(n_buf, 4, ASN1_Type::OctetString);
28
0
   return output;
29
0
}
30
31
}  // namespace
32
33
void X942_PRF::kdf(uint8_t key[],
34
                   size_t key_len,
35
                   const uint8_t secret[],
36
                   size_t secret_len,
37
                   const uint8_t salt[],
38
                   size_t salt_len,
39
                   const uint8_t label[],
40
0
                   size_t label_len) const {
41
0
   if(key_len == 0) {
42
0
      return;
43
0
   }
44
45
0
   const size_t blocks_required = key_len / 20;  // Fixed to use SHA-1
46
47
0
   if(blocks_required >= 0xFFFFFFFE) {
48
0
      throw Invalid_Argument("X942_PRF maximum output length exceeeded");
49
0
   }
50
51
0
   auto hash = HashFunction::create("SHA-1");
52
53
0
   secure_vector<uint8_t> h;
54
0
   secure_vector<uint8_t> in;
55
0
   size_t offset = 0;
56
0
   uint32_t counter = 1;
57
58
0
   in.reserve(salt_len + label_len);
59
0
   in += std::make_pair(label, label_len);
60
0
   in += std::make_pair(salt, salt_len);
61
62
0
   while(offset != key_len && counter) {
63
0
      hash->update(secret, secret_len);
64
65
0
      hash->update(
66
0
         DER_Encoder()
67
0
            .start_sequence()
68
69
0
            .start_sequence()
70
0
            .encode(m_key_wrap_oid)
71
0
            .raw_bytes(encode_x942_int(counter))
72
0
            .end_cons()
73
74
0
            .encode_if(salt_len != 0, DER_Encoder().start_explicit(0).encode(in, ASN1_Type::OctetString).end_explicit())
75
76
0
            .start_explicit(2)
77
0
            .raw_bytes(encode_x942_int(static_cast<uint32_t>(8 * key_len)))
78
0
            .end_explicit()
79
80
0
            .end_cons()
81
0
            .get_contents());
82
83
0
      hash->final(h);
84
0
      const size_t copied = std::min(h.size(), key_len - offset);
85
0
      copy_mem(&key[offset], h.data(), copied);
86
0
      offset += copied;
87
88
0
      ++counter;
89
0
      BOTAN_ASSERT_NOMSG(counter != 0);
90
0
   }
91
0
}
92
93
0
std::string X942_PRF::name() const {
94
0
   return "X9.42-PRF(" + m_key_wrap_oid.to_formatted_string() + ")";
95
0
}
96
97
}  // namespace Botan