diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /external/crypto++-5.6.3/hkdf.h | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'external/crypto++-5.6.3/hkdf.h')
| -rw-r--r-- | external/crypto++-5.6.3/hkdf.h | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/external/crypto++-5.6.3/hkdf.h b/external/crypto++-5.6.3/hkdf.h new file mode 100644 index 0000000..3222bad --- /dev/null +++ b/external/crypto++-5.6.3/hkdf.h @@ -0,0 +1,100 @@ +// hkdf.h - written and placed in public domain by Jeffrey Walton. Copyright assigned to Crypto++ project. + +#ifndef CRYPTOPP_HASH_KEY_DERIVATION_FUNCTION_H +#define CRYPTOPP_HASH_KEY_DERIVATION_FUNCTION_H + +#include "cryptlib.h" +#include "hrtimer.h" +#include "secblock.h" +#include "hmac.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! abstract base class for key derivation function +class KeyDerivationFunction +{ +public: + //! maximum number of bytes which can be produced under a secuirty context + virtual size_t MaxDerivedKeyLength() const =0; + virtual bool Usesinfo() const =0; + //! derive a key from secret + virtual unsigned int DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, const byte *salt, size_t saltLen, const byte* info=NULL, size_t infoLen=0) const =0; + + virtual ~KeyDerivationFunction() {} +}; + +//! General, multipurpose KDF from RFC 5869. T should be a HashTransformation class +//! https://eprint.iacr.org/2010/264 and https://tools.ietf.org/html/rfc5869 +template <class T> +class HKDF : public KeyDerivationFunction +{ +public: + static const char* StaticAlgorithmName () { + static const std::string name(std::string("HKDF(") + std::string(T::StaticAlgorithmName()) + std::string(")")); + return name.c_str(); + } + size_t MaxDerivedKeyLength() const {return static_cast<size_t>(T::DIGESTSIZE) * 255;} + bool Usesinfo() const {return true;} + unsigned int DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, const byte *salt, size_t saltLen, const byte* info, size_t infoLen) const; + +protected: + // If salt is missing (NULL), then use the NULL vector. Missing is different than EMPTY (0 length). The length + // of s_NullVector used depends on the Hash function. SHA-256 will use 32 bytes of s_NullVector. + typedef byte NullVectorType[T::DIGESTSIZE]; + static const NullVectorType& GetNullVector() { + static const NullVectorType s_NullVector = {0}; + return s_NullVector; + } +}; + +template <class T> +unsigned int HKDF<T>::DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, const byte *salt, size_t saltLen, const byte* info, size_t infoLen) const +{ + static const size_t DIGEST_SIZE = static_cast<size_t>(T::DIGESTSIZE); + const unsigned int req = static_cast<unsigned int>(derivedLen); + + assert(secret && secretLen); + assert(derived && derivedLen); + assert(derivedLen <= MaxDerivedKeyLength()); + + if (derivedLen > MaxDerivedKeyLength()) + throw InvalidArgument("HKDF: derivedLen must be less than or equal to MaxDerivedKeyLength"); + + HMAC<T> hmac; + FixedSizeSecBlock<byte, DIGEST_SIZE> prk, buffer; + + // Extract + const byte* key = (salt ? salt : GetNullVector()); + const size_t klen = (salt ? saltLen : DIGEST_SIZE); + + hmac.SetKey(key, klen); + hmac.CalculateDigest(prk, secret, secretLen); + + // Expand + hmac.SetKey(prk.data(), prk.size()); + byte block = 0; + + while (derivedLen > 0) + { + if (block++) {hmac.Update(buffer, buffer.size());} + if (info && infoLen) {hmac.Update(info, infoLen);} + hmac.CalculateDigest(buffer, &block, 1); + +#if CRYPTOPP_MSC_VERSION + const size_t segmentLen = STDMIN(derivedLen, DIGEST_SIZE); + memcpy_s(derived, segmentLen, buffer, segmentLen); +#else + const size_t segmentLen = STDMIN(derivedLen, DIGEST_SIZE); + std::memcpy(derived, buffer, segmentLen); +#endif + + derived += segmentLen; + derivedLen -= segmentLen; + } + + return req; +} + +NAMESPACE_END + +#endif // CRYPTOPP_HASH_KEY_DERIVATION_FUNCTION_H |