diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt --- a/src/crypto/CMakeLists.txt +++ b/src/crypto/CMakeLists.txt @@ -6,6 +6,7 @@ add_library(crypto aes.cpp chacha20.cpp + hkdf_sha256_32.cpp hmac_sha256.cpp hmac_sha512.cpp ripemd160.cpp diff --git a/src/crypto/hkdf_sha256_32.h b/src/crypto/hkdf_sha256_32.h new file mode 100644 --- /dev/null +++ b/src/crypto/hkdf_sha256_32.h @@ -0,0 +1,28 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_CRYPTO_HKDF_SHA256_32_H +#define BITCOIN_CRYPTO_HKDF_SHA256_32_H + +#include + +#include +#include + +/** + * A rfc5869 HKDF implementation with HMAC_SHA256 and fixed key output length + * of 32 bytes (L=32) + */ +class CHKDF_HMAC_SHA256_L32 { +private: + uint8_t m_prk[32]; + static const size_t OUTPUT_SIZE = 32; + +public: + CHKDF_HMAC_SHA256_L32(const uint8_t *ikm, size_t ikmlen, + const std::string &salt); + void Expand32(const std::string &info, uint8_t hash[OUTPUT_SIZE]); +}; + +#endif // BITCOIN_CRYPTO_HKDF_SHA256_32_H diff --git a/src/crypto/hkdf_sha256_32.cpp b/src/crypto/hkdf_sha256_32.cpp new file mode 100644 --- /dev/null +++ b/src/crypto/hkdf_sha256_32.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include + +CHKDF_HMAC_SHA256_L32::CHKDF_HMAC_SHA256_L32(const uint8_t *ikm, size_t ikmlen, + const std::string &salt) { + CHMAC_SHA256((const uint8_t *)salt.c_str(), salt.size()) + .Write(ikm, ikmlen) + .Finalize(m_prk); +} + +void CHKDF_HMAC_SHA256_L32::Expand32(const std::string &info, + uint8_t hash[OUTPUT_SIZE]) { + // expand a 32byte key (single round) + assert(info.size() <= 128); + static const uint8_t one[1] = {1}; + CHMAC_SHA256(m_prk, 32) + .Write((const uint8_t *)info.data(), info.size()) + .Write(one, 1) + .Finalize(hash); +}