Coverage Report

Created: 2022-01-14 08:07

/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
#include <botan/der_enc.h>
10
#include <botan/hash.h>
11
#include <botan/internal/loadstor.h>
12
#include <algorithm>
13
14
namespace Botan {
15
16
namespace {
17
18
/*
19
* Encode an integer as an OCTET STRING
20
*/
21
std::vector<uint8_t> encode_x942_int(uint32_t n)
22
0
   {
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
}
32
33
void X942_PRF::kdf(uint8_t key[], size_t key_len,
34
                   const uint8_t secret[], size_t secret_len,
35
                   const uint8_t salt[], size_t salt_len,
36
                   const uint8_t label[], size_t label_len) const
37
0
   {
38
0
   if(key_len == 0)
39
0
      return;
40
41
0
   const size_t blocks_required = key_len / 20; // Fixed to use SHA-1
42
43
0
   if(blocks_required >= 0xFFFFFFFE)
44
0
      throw Invalid_Argument("X942_PRF maximum output length exceeeded");
45
46
0
   std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-160"));
47
48
0
   secure_vector<uint8_t> h;
49
0
   secure_vector<uint8_t> in;
50
0
   size_t offset = 0;
51
0
   uint32_t counter = 1;
52
53
0
   in.reserve(salt_len + label_len);
54
0
   in += std::make_pair(label,label_len);
55
0
   in += std::make_pair(salt,salt_len);
56
57
0
   while(offset != key_len && counter)
58
0
      {
59
0
      hash->update(secret, secret_len);
60
61
0
      hash->update(
62
0
         DER_Encoder().start_sequence()
63
64
0
            .start_sequence()
65
0
               .encode(m_key_wrap_oid)
66
0
               .raw_bytes(encode_x942_int(counter))
67
0
            .end_cons()
68
69
0
            .encode_if(salt_len != 0,
70
0
               DER_Encoder()
71
0
                  .start_explicit(0)
72
0
                    .encode(in, ASN1_Type::OctetString)
73
0
                  .end_explicit()
74
0
               )
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().get_contents()
81
0
         );
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
std::string X942_PRF::name() const
94
0
   {
95
0
   return "X9.42-PRF(" + m_key_wrap_oid.to_formatted_string() + ")";
96
0
   }
97
98
}