Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- Class List
- Class Index
- Class Hierarchy
- Class Members

Public Member Functions | Static Public Member Functions | List of all members
Botan::SP800_108_Pipeline Class Reference

`#include <sp800_108.h>`

Inheritance diagram for Botan::SP800_108_Pipeline:

## Public Member Functions
KDF * | clone () 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_Pipeline (MessageAuthenticationCode *mac)

## Static Public Member Functions
static std::unique_ptr< KDF > | create (const std::string &algo_spec, const std::string &provider="")
static std::unique_ptr< KDF > | create_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 Double Pipeline Mode (5.3)

Definition at line 96 of file sp800_108.h.

## Constructor & Destructor Documentation

Botan::SP800_108_Pipeline::SP800_108_Pipeline | ( | MessageAuthenticationCode * | mac | ) |
| inline

Definition at line 125 of file sp800_108.h.

125 : m_prf(mac) {}

## Member Function Documentation

KDF* Botan::SP800_108_Pipeline::clone | ( |  | ) | const
| inline override virtual

Returns
  new object representing the same algorithm as *this

Implements Botan::KDF.

Definition at line 101 of file sp800_108.h.

101 { return new SP800_108_Pipeline(m_prf->clone()); }
Botan::SP800_108_Pipeline::SP800_108_Pipeline
SP800_108_Pipeline(MessageAuthenticationCode *mac)
Definition: sp800_108.h:125

std::unique_ptr< KDF > Botan::KDF::create | ( | const std::string & | algo_spec,
|  | const std::string & | provider = `""`
| ) |  |
| static inherited

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

Parameters

  algo_spec | algorithm name
  provider | provider implementation to choose

Returns
  a null pointer if the algo/provider combination cannot be found

Definition at line 68 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().

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

std::unique_ptr< KDF > Botan::KDF::create_or_throw | ( | const std::string & | algo_spec,
|  | const std::string & | provider = `""`
| ) |  |
| static inherited

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

References Botan::KDF::create().

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

213 {
214 if(auto bc = KDF::create(algo, provider))
215 {
216 return bc;
217 }
218 throw Lookup_Error("KDF", algo, provider);
219 }
Botan::KDF::create
static std::unique_ptr< KDF > create(const std::string &algo_spec, const std::string &provider="")
Definition: kdf.cpp:68

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
| inline inherited

Derive a key

Parameters

  key_len | the desired output length in bytes
  secret | the secret input
  secret_len | size of secret in bytes
  salt | a diversifier
  salt_len | size of salt in bytes
  label | purpose for the derived keying material
  label_len | size of label in bytes

Returns
  the derived key

Definition at line 83 of file kdf.h.

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 }
Botan::KDF::kdf
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

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
| inline inherited

Derive a key

Parameters

  key_len | the desired output length in bytes
  secret | the secret input
  salt | a diversifier
  label | purpose for the derived keying material

Returns
  the derived key

Definition at line 104 of file kdf.h.

108 {
109 return derive_key(key_len, secret.data(), secret.size(),
110 reinterpret_cast<const uint8_t*>(salt.data()),
111 salt.length(),
112 reinterpret_cast<const uint8_t*>(label.data()),
113 label.length());
114
115 }
Botan::KDF::derive_key
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
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
| inline inherited

Derive a key

Parameters

  key_len | the desired output length in bytes
  secret | the secret input
  salt | a diversifier
  label | purpose 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 }
Botan::KDF::derive_key
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

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
| inline inherited

Derive a key

Parameters

  key_len | the desired output length in bytes
  secret | the secret input
  salt | a diversifier
  salt_len | size of salt in bytes
  label | purpose for the derived keying material

Returns
  the derived key

Definition at line 146 of file kdf.h.

151 {
152 return derive_key(key_len,
153 secret.data(), secret.size(),
154 salt, salt_len,
155 reinterpret_cast<const uint8_t*>(label.data()),
156 label.size());
157 }
Botan::KDF::derive_key
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

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
| inline inherited

Derive a key

Parameters

  key_len | the desired output length in bytes
  secret | the secret input
  secret_len | size of secret in bytes
  salt | a diversifier
  label | purpose for the derived keying material

Returns
  the derived key

Definition at line 168 of file kdf.h.

173 {
174 return derive_key(key_len, secret, secret_len,
175 reinterpret_cast<const uint8_t*>(salt.data()),
176 salt.length(),
177 reinterpret_cast<const uint8_t*>(label.data()),
178 label.length());
179 }
Botan::KDF::derive_key
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 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
| override virtual

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

  key | resulting keying material
  key_len | the desired output length in bytes
  secret | K_I
  secret_len | size of K_I in bytes
  salt | Context
  salt_len | size of Context in bytes
  label | Label
  label_len | size of Label in bytes

Exceptions

  Invalid_Argument | key_len > 2^32

Implements Botan::KDF.

Definition at line 103 of file sp800_108.cpp.

References Botan::store_be().

107 {
108 const std::size_t prf_len = m_prf->output_length();
109 const uint8_t delim = 0;
110
111 uint8_t *p = key;
112 uint32_t counter = 1;
113 uint32_t length = key_len * 8;
114 uint8_t be_len[4] = { 0 };
115 secure_vector<uint8_t> ai, ki;
116
117 store_be(length, be_len);
118 m_prf->set_key(secret,secret_len);
119
120 // A(0)
121 std::copy(label,label + label_len,std::back_inserter(ai));
122 ai.emplace_back(delim);
123 std::copy(salt,salt + salt_len,std::back_inserter(ai));
124 std::copy(be_len,be_len + 4,std::back_inserter(ai));
125
126 while(p < key + key_len && counter != 0)
127 {
128 // A(i)
129 m_prf->update(ai);
130 m_prf->final(ai);
131
132 // K(i)
133 const std::size_t to_copy = std::min< std::size_t >(key + key_len - p, prf_len);
134 uint8_t be_cnt[4] = { 0 };
135
136 store_be(counter, be_cnt);
137
138 m_prf->update(ai);
139 m_prf->update(be_cnt,4);
140 m_prf->update(label, label_len);
141 m_prf->update(delim);
142 m_prf->update(salt, salt_len);
143 m_prf->update(be_len,4);
144 m_prf->final(ki);
145
146 std::copy(ki.begin(), ki.begin() + to_copy, p);
147 ++counter;
148
149 if (counter == 0)
150 throw Invalid_Argument("Can't process more than 4GB");
151
152 p += to_copy;
153 }
154
155 return key_len;
156 }
Botan::store_be
void store_be(uint16_t in, uint8_t out[2])
Definition: loadstor.h:441

std::string Botan::SP800_108_Pipeline::name | ( |  | ) | const
| inline override virtual

Returns
  KDF name

Implements Botan::KDF.

Definition at line 99 of file sp800_108.h.

99 { return "SP800-108-Pipeline(" + m_prf->name() + ")"; }

std::vector< std::string > Botan::KDF::providers | ( | const std::string & | algo_spec | ) |
| static inherited

Returns
  list of available providers for this algorithm, empty if not available

Definition at line 221 of file kdf.cpp.

222 {
223 return probe_providers_of<KDF>(algo_spec, { "base" });
224 }

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

- src/lib/kdf/sp800_108/sp800_108.h
- src/lib/kdf/sp800_108/sp800_108.cpp