Botan 3.0.0
Crypto and TLS for C&
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/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
14namespace Botan {
15
16namespace {
17
18/*
19* Encode an integer as an OCTET STRING
20*/
21std::vector<uint8_t> encode_x942_int(uint32_t n)
22 {
23 uint8_t n_buf[4] = { 0 };
24 store_be(n, n_buf);
25
26 std::vector<uint8_t> output;
27 DER_Encoder(output).encode(n_buf, 4, ASN1_Type::OctetString);
28 return output;
29 }
30
31}
32
33void 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 {
38 if(key_len == 0)
39 return;
40
41 const size_t blocks_required = key_len / 20; // Fixed to use SHA-1
42
43 if(blocks_required >= 0xFFFFFFFE)
44 throw Invalid_Argument("X942_PRF maximum output length exceeeded");
45
46 auto hash = HashFunction::create("SHA-1");
47
50 size_t offset = 0;
51 uint32_t counter = 1;
52
53 in.reserve(salt_len + label_len);
54 in += std::make_pair(label,label_len);
55 in += std::make_pair(salt,salt_len);
56
57 while(offset != key_len && counter)
58 {
59 hash->update(secret, secret_len);
60
61 hash->update(
62 DER_Encoder().start_sequence()
63
64 .start_sequence()
65 .encode(m_key_wrap_oid)
66 .raw_bytes(encode_x942_int(counter))
67 .end_cons()
68
69 .encode_if(salt_len != 0,
71 .start_explicit(0)
72 .encode(in, ASN1_Type::OctetString)
73 .end_explicit()
74 )
75
76 .start_explicit(2)
77 .raw_bytes(encode_x942_int(static_cast<uint32_t>(8 * key_len)))
78 .end_explicit()
79
80 .end_cons().get_contents()
81 );
82
83 hash->final(h);
84 const size_t copied = std::min(h.size(), key_len - offset);
85 copy_mem(&key[offset], h.data(), copied);
86 offset += copied;
87
88 ++counter;
89 BOTAN_ASSERT_NOMSG(counter != 0);
90 }
91 }
92
93std::string X942_PRF::name() const
94 {
95 return "X9.42-PRF(" + m_key_wrap_oid.to_formatted_string() + ")";
96 }
97
98}
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:67
static std::unique_ptr< HashFunction > create(std::string_view algo_spec, std::string_view provider="")
Definition: hash.cpp:102
std::string to_formatted_string() const
Definition: asn1_oid.cpp:120
std::string name() const override
Definition: prf_x942.cpp:93
void 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:33
Definition: alg_id.cpp:12
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:126
constexpr void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:449
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:64