Botan 3.0.0
Crypto and TLS for C&
Public Member Functions | Static Public Member Functions | List of all members
Botan::SP800_108_Pipeline Class Referencefinal

#include <sp800_108.h>

Inheritance diagram for Botan::SP800_108_Pipeline:
Botan::KDF

Public Member Functions

KDFclone () const
 
template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T derive_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[]=nullptr, size_t label_len=0) const
 
template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T derive_key (size_t key_len, const uint8_t secret[], size_t secret_len, std::string_view salt="", std::string_view label="") const
 
template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T derive_key (size_t key_len, std::span< const uint8_t > secret, const uint8_t salt[], size_t salt_len, std::string_view label="") const
 
template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T derive_key (size_t key_len, std::span< const uint8_t > secret, std::span< const uint8_t > salt, std::span< const uint8_t > label) const
 
template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T derive_key (size_t key_len, std::span< const uint8_t > secret, std::string_view salt="", std::string_view label="") const
 
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
 
std::string name () const override
 
std::unique_ptr< KDFnew_object () const override
 
 SP800_108_Pipeline (std::unique_ptr< MessageAuthenticationCode > mac)
 

Static Public Member Functions

static std::unique_ptr< KDFcreate (std::string_view algo_spec, std::string_view provider="")
 
static std::unique_ptr< KDFcreate_or_throw (std::string_view algo_spec, std::string_view provider="")
 
static std::vector< std::string > providers (std::string_view algo_spec)
 

Detailed Description

NIST SP 800-108 KDF in Double Pipeline Mode (5.3)

Definition at line 96 of file sp800_108.h.

Constructor & Destructor Documentation

◆ SP800_108_Pipeline()

Botan::SP800_108_Pipeline::SP800_108_Pipeline ( std::unique_ptr< MessageAuthenticationCode mac)
inlineexplicit

Definition at line 125 of file sp800_108.h.

125: m_prf(std::move(mac)) {}

Member Function Documentation

◆ clone()

KDF * Botan::KDF::clone ( ) const
inlineinherited
Returns
new object representing the same algorithm as *this

Definition at line 190 of file kdf.h.

191 {
192 return this->new_object().release();
193 }
virtual std::unique_ptr< KDF > new_object() const =0

◆ create()

std::unique_ptr< KDF > Botan::KDF::create ( std::string_view  algo_spec,
std::string_view  provider = "" 
)
staticinherited

Create an instance based on a name If provider is empty then best available is chosen.

Parameters
algo_specalgorithm name
providerprovider implementation to choose
Returns
a null pointer if the algo/provider combination cannot be found

Definition at line 70 of file kdf.cpp.

72 {
73 const SCAN_Name req(algo_spec);
74
75#if defined(BOTAN_HAS_HKDF)
76 if(req.algo_name() == "HKDF" && req.arg_count() == 1)
77 {
78 if(provider.empty() || provider == "base")
79 {
80 return kdf_create_mac_or_hash<HKDF>(req.arg(0));
81 }
82 }
83
84 if(req.algo_name() == "HKDF-Extract" && req.arg_count() == 1)
85 {
86 if(provider.empty() || provider == "base")
87 {
88 return kdf_create_mac_or_hash<HKDF_Extract>(req.arg(0));
89 }
90 }
91
92 if(req.algo_name() == "HKDF-Expand" && req.arg_count() == 1)
93 {
94 if(provider.empty() || provider == "base")
95 {
96 return kdf_create_mac_or_hash<HKDF_Expand>(req.arg(0));
97 }
98 }
99#endif
100
101#if defined(BOTAN_HAS_KDF2)
102 if(req.algo_name() == "KDF2" && req.arg_count() == 1)
103 {
104 if(provider.empty() || provider == "base")
105 {
106 if(auto hash = HashFunction::create(req.arg(0)))
107 return std::make_unique<KDF2>(std::move(hash));
108 }
109 }
110#endif
111
112#if defined(BOTAN_HAS_KDF1_18033)
113 if(req.algo_name() == "KDF1-18033" && req.arg_count() == 1)
114 {
115 if(provider.empty() || provider == "base")
116 {
117 if(auto hash = HashFunction::create(req.arg(0)))
118 return std::make_unique<KDF1_18033>(std::move(hash));
119 }
120 }
121#endif
122
123#if defined(BOTAN_HAS_KDF1)
124 if(req.algo_name() == "KDF1" && req.arg_count() == 1)
125 {
126 if(provider.empty() || provider == "base")
127 {
128 if(auto hash = HashFunction::create(req.arg(0)))
129 return std::make_unique<KDF1>(std::move(hash));
130 }
131 }
132#endif
133
134#if defined(BOTAN_HAS_TLS_V12_PRF)
135 if(req.algo_name() == "TLS-12-PRF" && req.arg_count() == 1)
136 {
137 if(provider.empty() || provider == "base")
138 {
139 return kdf_create_mac_or_hash<TLS_12_PRF>(req.arg(0));
140 }
141 }
142#endif
143
144#if defined(BOTAN_HAS_X942_PRF)
145 if(req.algo_name() == "X9.42-PRF" && req.arg_count() == 1)
146 {
147 if(provider.empty() || provider == "base")
148 {
149 return std::make_unique<X942_PRF>(req.arg(0));
150 }
151 }
152#endif
153
154#if defined(BOTAN_HAS_SP800_108)
155 if(req.algo_name() == "SP800-108-Counter" && req.arg_count() == 1)
156 {
157 if(provider.empty() || provider == "base")
158 {
159 return kdf_create_mac_or_hash<SP800_108_Counter>(req.arg(0));
160 }
161 }
162
163 if(req.algo_name() == "SP800-108-Feedback" && req.arg_count() == 1)
164 {
165 if(provider.empty() || provider == "base")
166 {
167 return kdf_create_mac_or_hash<SP800_108_Feedback>(req.arg(0));
168 }
169 }
170
171 if(req.algo_name() == "SP800-108-Pipeline" && req.arg_count() == 1)
172 {
173 if(provider.empty() || provider == "base")
174 {
175 return kdf_create_mac_or_hash<SP800_108_Pipeline>(req.arg(0));
176 }
177 }
178#endif
179
180#if defined(BOTAN_HAS_SP800_56A)
181 if(req.algo_name() == "SP800-56A" && req.arg_count() == 1)
182 {
183 if(auto hash = HashFunction::create(req.arg(0)))
184 return std::make_unique<SP800_56A_Hash>(std::move(hash));
185 if(auto mac = MessageAuthenticationCode::create(req.arg(0)))
186 return std::make_unique<SP800_56A_HMAC>(std::move(mac));
187 }
188#endif
189
190#if defined(BOTAN_HAS_SP800_56C)
191 if(req.algo_name() == "SP800-56C" && req.arg_count() == 1)
192 {
193 std::unique_ptr<KDF> exp(kdf_create_mac_or_hash<SP800_108_Feedback>(req.arg(0)));
194 if(exp)
195 {
196 if(auto mac = MessageAuthenticationCode::create(req.arg(0)))
197 return std::make_unique<SP800_56C>(std::move(mac), std::move(exp));
198
199 if(auto mac = MessageAuthenticationCode::create(fmt("HMAC({})", req.arg(0))))
200 return std::make_unique<SP800_56C>(std::move(mac), std::move(exp));
201 }
202 }
203#endif
204
205 BOTAN_UNUSED(req);
206 BOTAN_UNUSED(provider);
207
208 return nullptr;
209 }
#define BOTAN_UNUSED(...)
Definition: assert.h:141
static std::unique_ptr< HashFunction > create(std::string_view algo_spec, std::string_view provider="")
Definition: hash.cpp:102
static std::unique_ptr< MessageAuthenticationCode > create(std::string_view algo_spec, std::string_view provider="")
Definition: mac.cpp:46
std::string fmt(std::string_view format, const T &... args)
Definition: fmt.h:60

References Botan::SCAN_Name::algo_name(), Botan::SCAN_Name::arg(), Botan::SCAN_Name::arg_count(), BOTAN_UNUSED, Botan::HashFunction::create(), Botan::MessageAuthenticationCode::create(), and Botan::fmt().

Referenced by Botan::KDF::create_or_throw(), and Botan::get_kdf().

◆ create_or_throw()

std::unique_ptr< KDF > Botan::KDF::create_or_throw ( std::string_view  algo_spec,
std::string_view  provider = "" 
)
staticinherited

Create an instance based on a name, or throw if the algo/provider combination cannot be found. If provider is empty then best available is chosen.

Definition at line 213 of file kdf.cpp.

215 {
216 if(auto kdf = KDF::create(algo, provider))
217 {
218 return kdf;
219 }
220 throw Lookup_Error("KDF", algo, provider);
221 }
static std::unique_ptr< KDF > create(std::string_view algo_spec, std::string_view provider="")
Definition: kdf.cpp:70
virtual 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 =0

References Botan::KDF::create(), and Botan::KDF::kdf().

Referenced by botan_kdf(), Botan::ECIES_KA_Operation::derive_secret(), Botan::PK_Ops::KEM_Decryption_with_KDF::KEM_Decryption_with_KDF(), Botan::PK_Ops::KEM_Encryption_with_KDF::KEM_Encryption_with_KDF(), Botan::PK_Ops::Key_Agreement_with_KDF::Key_Agreement_with_KDF(), and Botan::TLS::Handshake_State::protocol_specific_prf().

◆ derive_key() [1/5]

template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T Botan::KDF::derive_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[] = nullptr,
size_t  label_len = 0 
) const
inlineinherited

Derive a key

Parameters
key_lenthe desired output length in bytes
secretthe secret input
secret_lensize of secret in bytes
salta diversifier
salt_lensize of salt in bytes
labelpurpose for the derived keying material
label_lensize of label in bytes
Returns
the derived key

Definition at line 86 of file kdf.h.

90 {
91 T key(key_len);
92 kdf(key.data(), key.size(), secret, secret_len, salt, salt_len, label, label_len);
93 return key;
94 }
FE_25519 T
Definition: ge.cpp:36

References T.

◆ derive_key() [2/5]

template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T Botan::KDF::derive_key ( size_t  key_len,
const uint8_t  secret[],
size_t  secret_len,
std::string_view  salt = "",
std::string_view  label = "" 
) const
inlineinherited

Derive a key

Parameters
key_lenthe desired output length in bytes
secretthe secret input
secret_lensize of secret in bytes
salta diversifier
labelpurpose for the derived keying material
Returns
the derived key

Definition at line 170 of file kdf.h.

174 {
175 return derive_key<T>(key_len, secret, secret_len,
176 cast_char_ptr_to_uint8(salt.data()),
177 salt.length(),
178 cast_char_ptr_to_uint8(label.data()),
179 label.length());
180 }
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:183

References Botan::cast_char_ptr_to_uint8().

◆ derive_key() [3/5]

template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T Botan::KDF::derive_key ( size_t  key_len,
std::span< const uint8_t >  secret,
const uint8_t  salt[],
size_t  salt_len,
std::string_view  label = "" 
) const
inlineinherited

Derive a key

Parameters
key_lenthe desired output length in bytes
secretthe secret input
salta diversifier
salt_lensize of salt in bytes
labelpurpose for the derived keying material
Returns
the derived key

Definition at line 148 of file kdf.h.

152 {
153 return derive_key<T>(key_len,
154 secret.data(), secret.size(),
155 salt, salt_len,
156 cast_char_ptr_to_uint8(label.data()),
157 label.size());
158 }

References Botan::cast_char_ptr_to_uint8().

◆ derive_key() [4/5]

template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T Botan::KDF::derive_key ( size_t  key_len,
std::span< const uint8_t >  secret,
std::span< const uint8_t >  salt,
std::span< const uint8_t >  label 
) const
inlineinherited

Derive a key

Parameters
key_lenthe desired output length in bytes
secretthe secret input
salta diversifier
labelpurpose for the derived keying material
Returns
the derived key

Definition at line 127 of file kdf.h.

131 {
132 return derive_key<T>(key_len,
133 secret.data(), secret.size(),
134 salt.data(), salt.size(),
135 label.data(), label.size());
136 }

◆ derive_key() [5/5]

template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
T Botan::KDF::derive_key ( size_t  key_len,
std::span< const uint8_t >  secret,
std::string_view  salt = "",
std::string_view  label = "" 
) const
inlineinherited

Derive a key

Parameters
key_lenthe desired output length in bytes
secretthe secret input
salta diversifier
labelpurpose for the derived keying material
Returns
the derived key

Definition at line 105 of file kdf.h.

109 {
110 return derive_key<T>(key_len, secret.data(), secret.size(),
111 cast_char_ptr_to_uint8(salt.data()),
112 salt.length(),
113 cast_char_ptr_to_uint8(label.data()),
114 label.length());
115
116 }

References Botan::cast_char_ptr_to_uint8().

◆ kdf()

void Botan::SP800_108_Pipeline::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
overridevirtual

Derive a key using the SP800-108 KDF in Double Pipeline mode.

The implementation uses the optional counter i and hard codes the length of [L]_2 and [i]_2 (the value r) to 32 bits.

Parameters
keyresulting keying material
key_lenthe desired output length in bytes
secretK_I
secret_lensize of K_I in bytes
saltContext
salt_lensize of Context in bytes
labelLabel
label_lensize of Label in bytes
Exceptions
Invalid_Argumentkey_len > 2^32

Implements Botan::KDF.

Definition at line 139 of file sp800_108.cpp.

143 {
144 const uint32_t length = static_cast<uint32_t>(key_len * 8);
145 const std::size_t prf_len = m_prf->output_length();
146 const uint8_t delim = 0;
147
148 const uint64_t blocks_required = (key_len + prf_len - 1) / prf_len;
149
150 if(blocks_required > 0xFFFFFFFF)
151 throw Invalid_Argument("SP800_108_Feedback output size too large");
152
153 uint8_t *p = key;
154 uint32_t counter = 1;
155 uint8_t be_len[4] = { 0 };
156 secure_vector<uint8_t> ai, ki;
157
158 store_be(length, be_len);
159 m_prf->set_key(secret,secret_len);
160
161 // A(0)
162 std::copy(label,label + label_len,std::back_inserter(ai));
163 ai.emplace_back(delim);
164 std::copy(salt,salt + salt_len,std::back_inserter(ai));
165 std::copy(be_len,be_len + 4,std::back_inserter(ai));
166
167 while(p < key + key_len)
168 {
169 // A(i)
170 m_prf->update(ai);
171 m_prf->final(ai);
172
173 // K(i)
174 const std::size_t to_copy = std::min< std::size_t >(key + key_len - p, prf_len);
175 uint8_t be_cnt[4] = { 0 };
176
177 store_be(counter, be_cnt);
178
179 m_prf->update(ai);
180 m_prf->update(be_cnt,4);
181 m_prf->update(label, label_len);
182 m_prf->update(delim);
183 m_prf->update(salt, salt_len);
184 m_prf->update(be_len,4);
185 m_prf->final(ki);
186
187 copy_mem(p, ki.data(), to_copy);
188 p += to_copy;
189
190 ++counter;
191
192 BOTAN_ASSERT(counter != 0, "No overflow");
193 }
194 }
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:54
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

References BOTAN_ASSERT, Botan::copy_mem(), and Botan::store_be().

◆ name()

std::string Botan::SP800_108_Pipeline::name ( ) const
overridevirtual
Returns
KDF name

Implements Botan::KDF.

Definition at line 129 of file sp800_108.cpp.

130 {
131 return fmt("SP800-108-Pipeline({})", m_prf->name());
132 }

References Botan::fmt().

◆ new_object()

std::unique_ptr< KDF > Botan::SP800_108_Pipeline::new_object ( ) const
overridevirtual
Returns
new object representing the same algorithm as *this

Implements Botan::KDF.

Definition at line 134 of file sp800_108.cpp.

135 {
136 return std::make_unique<SP800_108_Pipeline>(m_prf->new_object());
137 }

◆ providers()

std::vector< std::string > Botan::KDF::providers ( std::string_view  algo_spec)
staticinherited
Returns
list of available providers for this algorithm, empty if not available

Definition at line 223 of file kdf.cpp.

224 {
225 return probe_providers_of<KDF>(algo_spec);
226 }

The documentation for this class was generated from the following files: