Botan 3.6.1
Crypto and TLS for C&
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 derive_key (std::span< uint8_t > key, std::span< const uint8_t > secret, std::span< const uint8_t > salt, std::span< const uint8_t > 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 104 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 136 of file sp800_108.h.

136: 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 203 of file kdf.h.

203{ return this->new_object().release(); }
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 71 of file kdf.cpp.

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

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 199 of file kdf.cpp.

199 {
200 if(auto kdf = KDF::create(algo, provider)) {
201 return kdf;
202 }
203 throw Lookup_Error("KDF", algo, provider);
204}
static std::unique_ptr< KDF > create(std::string_view algo_spec, std::string_view provider="")
Definition kdf.cpp:71
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/6]

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.

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

References T.

◆ derive_key() [2/6]

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 181 of file kdf.h.

185 {
186 return derive_key<T>(key_len,
187 secret,
188 secret_len,
189 cast_char_ptr_to_uint8(salt.data()),
190 salt.length(),
191 cast_char_ptr_to_uint8(label.data()),
192 label.length());
193 }
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
Definition kdf.h:86
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition mem_ops.h:273

References Botan::cast_char_ptr_to_uint8().

◆ derive_key() [3/6]

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 162 of file kdf.h.

166 {
167 return derive_key<T>(
168 key_len, secret.data(), secret.size(), salt, salt_len, cast_char_ptr_to_uint8(label.data()), label.size());
169 }

References Botan::cast_char_ptr_to_uint8().

◆ derive_key() [4/6]

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 144 of file kdf.h.

147 {
148 return derive_key<T>(
149 key_len, secret.data(), secret.size(), salt.data(), salt.size(), label.data(), label.size());
150 }

◆ derive_key() [5/6]

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 107 of file kdf.h.

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

References Botan::cast_char_ptr_to_uint8().

◆ derive_key() [6/6]

void Botan::KDF::derive_key ( std::span< uint8_t > key,
std::span< const uint8_t > secret,
std::span< const uint8_t > salt,
std::span< const uint8_t > label ) const
inlineinherited

Derive a key

Parameters
keythe output buffer for the to-be-derived key
secretthe secret input
salta diversifier
labelpurpose for the derived keying material

Definition at line 127 of file kdf.h.

130 {
131 return kdf(
132 key.data(), key.size(), secret.data(), secret.size(), salt.data(), salt.size(), label.data(), label.size());
133 }

◆ 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 140 of file sp800_108.cpp.

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

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 132 of file sp800_108.cpp.

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

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 136 of file sp800_108.cpp.

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

◆ 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 206 of file kdf.cpp.

206 {
207 return probe_providers_of<KDF>(algo_spec);
208}
std::vector< std::string > probe_providers_of(std::string_view algo_spec, const std::vector< std::string > &possible={"base"})
Definition scan_name.h:105

References Botan::probe_providers_of().


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