Src/lib/kdf/hkdf/hkdf.cpp Source File - Botan

Botan 3.10.0 Crypto and TLS for C&
  • src
  • lib
  • kdf
  • hkdf
hkdf.cpp Go to the documentation of this file. 1/* 2* HKDF 3* (C) 2013,2015,2017 Jack Lloyd 4* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity 5* (C) 2024 René Meusel, Rohde & Schwarz Cybersecurity 6* 7* Botan is released under the Simplified BSD License (see license.txt) 8*/ 9 10#include <botan/internal/hkdf.h> 11 12#include <botan/internal/fmt.h> 13#include <botan/internal/loadstor.h> 14#include <botan/internal/mem_utils.h> 15#include <botan/internal/stl_util.h> 16 17namespace Botan { 18 19std::unique_ptr<KDF> HKDF::new_object() const { 20 return std::make_unique<HKDF>(m_prf->new_object()); 21} 22 23std::string HKDF::name() const { 24 return fmt("HKDF({})", m_prf->name()); 25} 26 27void HKDF::perform_kdf(std::span<uint8_t> key, 28 std::span<const uint8_t> secret, 29 std::span<const uint8_t> salt, 30 std::span<const uint8_t> label) const { 31 HKDF_Extract extract(m_prf->new_object()); 32 HKDF_Expand expand(m_prf->new_object()); 33 secure_vector<uint8_t> prk(m_prf->output_length()); 34 35 extract.derive_key(prk, secret, salt, {}); 36 expand.derive_key(key, prk, {}, label); 37} 38 39std::unique_ptr<KDF> HKDF_Extract::new_object() const { 40 return std::make_unique<HKDF_Extract>(m_prf->new_object()); 41} 42 43std::string HKDF_Extract::name() const { 44 return fmt("HKDF-Extract({})", m_prf->name()); 45} 46 47void HKDF_Extract::perform_kdf(std::span<uint8_t> key, 48 std::span<const uint8_t> secret, 49 std::span<const uint8_t> salt, 50 std::span<const uint8_t> label) const { 51 const size_t prf_output_len = m_prf->output_length(); 52 BOTAN_ARG_CHECK(key.size() <= prf_output_len, "HKDF-Extract maximum output length exceeded"); 53 BOTAN_ARG_CHECK(label.empty(), "HKDF-Extract does not support a label input"); 54 55 if(key.empty()) { 56 return; 57 } 58 59 if(salt.empty()) { 60 m_prf->set_key(std::vector<uint8_t>(prf_output_len)); 61 } else { 62 m_prf->set_key(salt); 63 } 64 65 m_prf->update(secret); 66 67 if(key.size() == prf_output_len) { 68 m_prf->final(key); 69 } else { 70 const auto prk = m_prf->final(); 71 copy_mem(key, std::span{prk}.first(key.size())); 72 } 73} 74 75std::unique_ptr<KDF> HKDF_Expand::new_object() const { 76 return std::make_unique<HKDF_Expand>(m_prf->new_object()); 77} 78 79std::string HKDF_Expand::name() const { 80 return fmt("HKDF-Expand({})", m_prf->name()); 81} 82 83void HKDF_Expand::perform_kdf(std::span<uint8_t> key, 84 std::span<const uint8_t> secret, 85 std::span<const uint8_t> salt, 86 std::span<const uint8_t> label) const { 87 const auto prf_output_length = m_prf->output_length(); 88 BOTAN_ARG_CHECK(key.size() <= prf_output_length * 255, "HKDF-Expand maximum output length exceeded"); 89 90 if(key.empty()) { 91 return; 92 } 93 94 // Keep a reference to the previous PRF output (empty by default). 95 std::span<uint8_t> h = {}; 96 97 BufferStuffer k(key); 98 m_prf->set_key(secret); 99 for(uint8_t counter = 1; !k.full(); ++counter) { 100 m_prf->update(h); 101 m_prf->update(label); 102 m_prf->update(salt); 103 m_prf->update(counter); 104 105 // Write straight into the output buffer, except if the PRF output needs 106 // a truncation in the final iteration. 107 if(k.remaining_capacity() >= prf_output_length) { 108 h = k.next(prf_output_length); 109 m_prf->final(h); 110 } else { 111 const auto full_prf_output = m_prf->final(); 112 h = {}; // this is the final iteration! 113 k.append(std::span{full_prf_output}.first(k.remaining_capacity())); 114 } 115 } 116} 117 118secure_vector<uint8_t> hkdf_expand_label(std::string_view hash_fn, 119 std::span<const uint8_t> secret, 120 std::string_view label, 121 std::span<const uint8_t> hash_val, 122 size_t length) { 123 BOTAN_ARG_CHECK(length <= 0xFFFF, "HKDF-Expand-Label requested output too large"); 124 BOTAN_ARG_CHECK(label.size() <= 0xFF, "HKDF-Expand-Label label too long"); 125 BOTAN_ARG_CHECK(hash_val.size() <= 0xFF, "HKDF-Expand-Label hash too long"); 126 127 HKDF_Expand hkdf(MessageAuthenticationCode::create_or_throw(fmt("HMAC({})", hash_fn))); 128 129 const auto prefix = concat<std::vector<uint8_t>>(store_be(static_cast<uint16_t>(length)), 130 store_be(static_cast<uint8_t>(label.size())), 131 as_span_of_bytes(label), 132 store_be(static_cast<uint8_t>(hash_val.size()))); 133 134 /* 135 * We do something a little dirty here to avoid copying the hash_val, 136 * making use of the fact that Botan's KDF interface supports label+salt, 137 * and knowing that our HKDF hashes first param label then param salt. 138 */ 139 return hkdf.derive_key(length, secret, hash_val, prefix); 140} 141 142} // namespace Botan BOTAN_ARG_CHECK#define BOTAN_ARG_CHECK(expr, msg)Definition assert.h:33 Botan::HKDF_ExpandDefinition hkdf.h:68 Botan::HKDF_Expand::namestd::string name() const overrideDefinition hkdf.cpp:79 Botan::HKDF_Expand::new_objectstd::unique_ptr< KDF > new_object() const overrideDefinition hkdf.cpp:75 Botan::HKDF_ExtractDefinition hkdf.h:44 Botan::HKDF_Extract::new_objectstd::unique_ptr< KDF > new_object() const overrideDefinition hkdf.cpp:39 Botan::HKDF_Extract::namestd::string name() const overrideDefinition hkdf.cpp:43 Botan::HKDF::namestd::string name() const overrideDefinition hkdf.cpp:23 Botan::HKDF::new_objectstd::unique_ptr< KDF > new_object() const overrideDefinition hkdf.cpp:19 Botan::KDF::derive_keyT 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) constDefinition kdf.h:91 Botan::MessageAuthenticationCode::create_or_throwstatic std::unique_ptr< MessageAuthenticationCode > create_or_throw(std::string_view algo_spec, std::string_view provider="")Definition mac.cpp:147 BotanDefinition alg_id.cpp:13 Botan::as_span_of_bytesstd::span< const uint8_t > as_span_of_bytes(const char *s, size_t len)Definition mem_utils.h:28 Botan::copy_memconstexpr void copy_mem(T *out, const T *in, size_t n)Definition mem_ops.h:145 Botan::fmtstd::string fmt(std::string_view format, const T &... args)Definition fmt.h:53 Botan::hkdf_expand_labelsecure_vector< uint8_t > hkdf_expand_label(std::string_view hash_fn, std::span< const uint8_t > secret, std::string_view label, std::span< const uint8_t > hash_val, size_t length)Definition hkdf.cpp:118 Botan::concatconstexpr auto concat(Rs &&... ranges)Definition stl_util.h:254 Botan::secure_vectorstd::vector< T, secure_allocator< T > > secure_vectorDefinition secmem.h:69 Botan::store_beconstexpr auto store_be(ParamTs &&... params)Definition loadstor.h:745 Generated by doxygen 1.15.0

Từ khóa » C Hkdf