Botan  2.6.0
Crypto and TLS for C++11
prf_x942.cpp
Go to the documentation of this file.
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/prf_x942.h>
9 #include <botan/der_enc.h>
10 #include <botan/oids.h>
11 #include <botan/hash.h>
12 #include <botan/loadstor.h>
13 #include <algorithm>
14 
15 namespace Botan {
16 
17 namespace {
18 
19 /*
20 * Encode an integer as an OCTET STRING
21 */
22 std::vector<uint8_t> encode_x942_int(uint32_t n)
23  {
24  uint8_t n_buf[4] = { 0 };
25  store_be(n, n_buf);
26  return DER_Encoder().encode(n_buf, 4, OCTET_STRING).get_contents_unlocked();
27  }
28 
29 }
30 
31 size_t X942_PRF::kdf(uint8_t key[], size_t key_len,
32  const uint8_t secret[], size_t secret_len,
33  const uint8_t salt[], size_t salt_len,
34  const uint8_t label[], size_t label_len) const
35  {
36  std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-160"));
37  const OID kek_algo(m_key_wrap_oid);
38 
41  size_t offset = 0;
42  uint32_t counter = 1;
43 
44  in.reserve(salt_len + label_len);
45  in += std::make_pair(label,label_len);
46  in += std::make_pair(salt,salt_len);
47 
48  while(offset != key_len && counter)
49  {
50  hash->update(secret, secret_len);
51 
52  hash->update(
53  DER_Encoder().start_cons(SEQUENCE)
54 
55  .start_cons(SEQUENCE)
56  .encode(kek_algo)
57  .raw_bytes(encode_x942_int(counter))
58  .end_cons()
59 
60  .encode_if(salt_len != 0,
61  DER_Encoder()
62  .start_explicit(0)
63  .encode(in, OCTET_STRING)
64  .end_explicit()
65  )
66 
67  .start_explicit(2)
68  .raw_bytes(encode_x942_int(static_cast<uint32_t>(8 * key_len)))
69  .end_explicit()
70 
71  .end_cons().get_contents()
72  );
73 
74  hash->final(h);
75  const size_t copied = std::min(h.size(), key_len - offset);
76  copy_mem(&key[offset], h.data(), copied);
77  offset += copied;
78 
79  ++counter;
80  }
81 
82  return offset;
83  }
84 
85 /*
86 * X9.42 Constructor
87 */
88 X942_PRF::X942_PRF(const std::string& oid)
89  {
90  if(OIDS::have_oid(oid))
91  m_key_wrap_oid = OIDS::lookup(oid).as_string();
92  else
93  m_key_wrap_oid = oid;
94  }
95 
96 }
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:434
size_t kdf(uint8_t key[], size_t key_len, const uint8_t secret[], size_t secret_len, const uint8_t salt[], size_t salt_len, const uint8_t label[], size_t label_len) const override
Definition: prf_x942.cpp:31
bool have_oid(const std::string &name)
Definition: oids.cpp:123
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
static std::unique_ptr< HashFunction > create(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:106
X942_PRF(const std::string &oid)
Definition: prf_x942.cpp:88
size_t salt_len
Definition: x509_obj.cpp:26
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:108
Definition: alg_id.cpp:13
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
std::string lookup(const OID &oid)
Definition: oids.cpp:113
MechanismType hash