Botan 3.4.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
10#include <botan/der_enc.h>
11#include <botan/hash.h>
12#include <botan/internal/loadstor.h>
13#include <algorithm>
14
15namespace Botan {
16
17namespace {
18
19/*
20* Encode an integer as an OCTET STRING
21*/
22std::vector<uint8_t> encode_x942_int(uint32_t n) {
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} // namespace
32
33void 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 size_t label_len) const {
41 if(key_len == 0) {
42 return;
43 }
44
45 const size_t blocks_required = key_len / 20; // Fixed to use SHA-1
46
47 if(blocks_required >= 0xFFFFFFFE) {
48 throw Invalid_Argument("X942_PRF maximum output length exceeeded");
49 }
50
51 auto hash = HashFunction::create("SHA-1");
52
55 size_t offset = 0;
56 uint32_t counter = 1;
57
58 in.reserve(salt_len + label_len);
59 in += std::make_pair(label, label_len);
60 in += std::make_pair(salt, salt_len);
61
62 while(offset != key_len && counter) {
63 hash->update(secret, secret_len);
64
65 hash->update(
67 .start_sequence()
68
69 .start_sequence()
70 .encode(m_key_wrap_oid)
71 .raw_bytes(encode_x942_int(counter))
72 .end_cons()
73
74 .encode_if(salt_len != 0, DER_Encoder().start_explicit(0).encode(in, ASN1_Type::OctetString).end_explicit())
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()
81 .get_contents());
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 return "X9.42-PRF(" + m_key_wrap_oid.to_formatted_string() + ")";
95}
96
97} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
static std::unique_ptr< HashFunction > create(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:107
std::string to_formatted_string() const
Definition asn1_oid.cpp:114
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
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:146
constexpr auto store_be(ParamTs &&... params)
Definition loadstor.h:711