Botan  2.16.0
Crypto and TLS for C++11
Public Member Functions | Static Public Member Functions | List of all members
Botan::SP800_108_Feedback Class Referencefinal

#include <sp800_108.h>

Inheritance diagram for Botan::SP800_108_Feedback:
Botan::KDF

Public Member Functions

KDFclone () const override
 
secure_vector< uint8_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
 
secure_vector< uint8_t > derive_key (size_t key_len, const secure_vector< uint8_t > &secret, const std::string &salt="", const std::string &label="") const
 
template<typename Alloc , typename Alloc2 , typename Alloc3 >
secure_vector< uint8_t > derive_key (size_t key_len, const std::vector< uint8_t, Alloc > &secret, const std::vector< uint8_t, Alloc2 > &salt, const std::vector< uint8_t, Alloc3 > &label) const
 
secure_vector< uint8_t > derive_key (size_t key_len, const secure_vector< uint8_t > &secret, const uint8_t salt[], size_t salt_len, const std::string &label="") const
 
secure_vector< uint8_t > derive_key (size_t key_len, const uint8_t secret[], size_t secret_len, const std::string &salt="", const std::string &label="") const
 
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
 
std::string name () const override
 
 SP800_108_Feedback (MessageAuthenticationCode *mac)
 

Static Public Member Functions

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

Detailed Description

NIST SP 800-108 KDF in Feedback Mode (5.2)

Definition at line 61 of file sp800_108.h.

Constructor & Destructor Documentation

◆ SP800_108_Feedback()

Botan::SP800_108_Feedback::SP800_108_Feedback ( MessageAuthenticationCode mac)
inlineexplicit

Definition at line 90 of file sp800_108.h.

90 : m_prf(mac) {}

Member Function Documentation

◆ clone()

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

Implements Botan::KDF.

Definition at line 66 of file sp800_108.h.

66 { return new SP800_108_Feedback(m_prf->clone()); }
SP800_108_Feedback(MessageAuthenticationCode *mac)
Definition: sp800_108.h:90

◆ create()

std::unique_ptr< KDF > Botan::KDF::create ( const std::string &  algo_spec,
const std::string &  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 69 of file kdf.cpp.

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

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

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

◆ create_or_throw()

std::unique_ptr< KDF > Botan::KDF::create_or_throw ( const std::string &  algo_spec,
const std::string &  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 226 of file kdf.cpp.

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

Referenced by Botan::ECIES_KA_Operation::derive_secret().

228  {
229  if(auto kdf = KDF::create(algo, provider))
230  {
231  return kdf;
232  }
233  throw Lookup_Error("KDF", algo, provider);
234  }
static std::unique_ptr< KDF > create(const std::string &algo_spec, const std::string &provider="")
Definition: kdf.cpp:69
virtual 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 =0

◆ derive_key() [1/5]

secure_vector<uint8_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 83 of file kdf.h.

References salt_len.

90  {
91  secure_vector<uint8_t> key(key_len);
92  key.resize(kdf(key.data(), key.size(), secret, secret_len, salt, salt_len, label, label_len));
93  return key;
94  }
size_t salt_len
Definition: x509_obj.cpp:25
virtual 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 =0

◆ derive_key() [2/5]

secure_vector<uint8_t> Botan::KDF::derive_key ( size_t  key_len,
const secure_vector< uint8_t > &  secret,
const std::string &  salt = "",
const std::string &  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 104 of file kdf.h.

References Botan::cast_char_ptr_to_uint8().

108  {
109  return derive_key(key_len, secret.data(), secret.size(),
110  cast_char_ptr_to_uint8(salt.data()),
111  salt.length(),
112  cast_char_ptr_to_uint8(label.data()),
113  label.length());
114 
115  }
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:190
secure_vector< uint8_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:83

◆ derive_key() [3/5]

template<typename Alloc , typename Alloc2 , typename Alloc3 >
secure_vector<uint8_t> Botan::KDF::derive_key ( size_t  key_len,
const std::vector< uint8_t, Alloc > &  secret,
const std::vector< uint8_t, Alloc2 > &  salt,
const std::vector< uint8_t, Alloc3 > &  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 126 of file kdf.h.

130  {
131  return derive_key(key_len,
132  secret.data(), secret.size(),
133  salt.data(), salt.size(),
134  label.data(), label.size());
135  }
secure_vector< uint8_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:83

◆ derive_key() [4/5]

secure_vector<uint8_t> Botan::KDF::derive_key ( size_t  key_len,
const secure_vector< uint8_t > &  secret,
const uint8_t  salt[],
size_t  salt_len,
const std::string &  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 146 of file kdf.h.

References Botan::cast_char_ptr_to_uint8(), and salt_len.

151  {
152  return derive_key(key_len,
153  secret.data(), secret.size(),
154  salt, salt_len,
155  cast_char_ptr_to_uint8(label.data()),
156  label.size());
157  }
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:190
secure_vector< uint8_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:83
size_t salt_len
Definition: x509_obj.cpp:25

◆ derive_key() [5/5]

secure_vector<uint8_t> Botan::KDF::derive_key ( size_t  key_len,
const uint8_t  secret[],
size_t  secret_len,
const std::string &  salt = "",
const std::string &  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 168 of file kdf.h.

References Botan::cast_char_ptr_to_uint8().

173  {
174  return derive_key(key_len, secret, secret_len,
175  cast_char_ptr_to_uint8(salt.data()),
176  salt.length(),
177  cast_char_ptr_to_uint8(label.data()),
178  label.length());
179  }
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:190
secure_vector< uint8_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:83

◆ kdf()

size_t Botan::SP800_108_Feedback::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 Feedback 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
saltIV || Context
salt_lensize of Context plus IV in bytes
labelLabel
label_lensize of Label in bytes
Exceptions
Invalid_Argumentkey_len > 2^32

Implements Botan::KDF.

Definition at line 62 of file sp800_108.cpp.

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

66  {
67  const uint32_t length = static_cast<uint32_t>(key_len * 8);
68  const std::size_t prf_len = m_prf->output_length();
69  const std::size_t iv_len = (salt_len >= prf_len ? prf_len : 0);
70  const uint8_t delim = 0;
71 
72  const uint64_t blocks_required = (key_len + prf_len - 1) / prf_len;
73 
74  if(blocks_required > 0xFFFFFFFF)
75  throw Invalid_Argument("SP800_108_Feedback output size too large");
76 
77  uint8_t *p = key;
78  uint32_t counter = 1;
79  uint8_t be_len[4] = { 0 };
80  secure_vector< uint8_t > prev(salt, salt + iv_len);
81  secure_vector< uint8_t > ctx(salt + iv_len, salt + salt_len);
82 
83  store_be(length, be_len);
84  m_prf->set_key(secret, secret_len);
85 
86  while(p < key + key_len)
87  {
88  const std::size_t to_copy = std::min< std::size_t >(key + key_len - p, prf_len);
89  uint8_t be_cnt[4] = { 0 };
90 
91  store_be(counter, be_cnt);
92 
93  m_prf->update(prev);
94  m_prf->update(be_cnt,4);
95  m_prf->update(label,label_len);
96  m_prf->update(delim);
97  m_prf->update(ctx);
98  m_prf->update(be_len,4);
99  m_prf->final(prev);
100 
101  copy_mem(p, prev.data(), to_copy);
102  p += to_copy;
103 
104  ++counter;
105 
106  BOTAN_ASSERT(counter != 0, "No overflow");
107  }
108 
109  return key_len;
110  }
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:438
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:55
size_t salt_len
Definition: x509_obj.cpp:25
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:133

◆ name()

std::string Botan::SP800_108_Feedback::name ( ) const
inlineoverridevirtual
Returns
KDF name

Implements Botan::KDF.

Definition at line 64 of file sp800_108.h.

64 { return "SP800-108-Feedback(" + m_prf->name() + ")"; }

◆ providers()

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

Definition at line 236 of file kdf.cpp.

237  {
238  return probe_providers_of<KDF>(algo_spec, { "base" });
239  }

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