Crypto++  5.6.3
Free C++ class library of cryptographic schemes
hkdf.h
1 // hkdf.h - written and placed in public domain by Jeffrey Walton. Copyright assigned to Crypto++ project.
2 
3 #ifndef CRYPTOPP_HASH_KEY_DERIVATION_FUNCTION_H
4 #define CRYPTOPP_HASH_KEY_DERIVATION_FUNCTION_H
5 
6 #include "cryptlib.h"
7 #include "hrtimer.h"
8 #include "secblock.h"
9 #include "hmac.h"
10 
11 NAMESPACE_BEGIN(CryptoPP)
12 
13 //! abstract base class for key derivation function
15 {
16 public:
17  //! maximum number of bytes which can be produced under a secuirty context
18  virtual size_t MaxDerivedKeyLength() const =0;
19  virtual bool Usesinfo() const =0;
20  //! derive a key from secret
21  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;
22 
23  virtual ~KeyDerivationFunction() {}
24 };
25 
26 //! General, multipurpose KDF from RFC 5869. T should be a HashTransformation class
27 //! https://eprint.iacr.org/2010/264 and https://tools.ietf.org/html/rfc5869
28 template <class T>
30 {
31 public:
32  static const char* StaticAlgorithmName () {
33  static const std::string name(std::string("HKDF(") + std::string(T::StaticAlgorithmName()) + std::string(")"));
34  return name.c_str();
35  }
36  size_t MaxDerivedKeyLength() const {return static_cast<size_t>(T::DIGESTSIZE) * 255;}
37  bool Usesinfo() const {return true;}
38  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;
39 
40 protected:
41  // If salt is missing (NULL), then use the NULL vector. Missing is different than EMPTY (0 length). The length
42  // of s_NullVector used depends on the Hash function. SHA-256 will use 32 bytes of s_NullVector.
43  typedef byte NullVectorType[T::DIGESTSIZE];
44  static const NullVectorType& GetNullVector() {
45  static const NullVectorType s_NullVector = {0};
46  return s_NullVector;
47  }
48 };
49 
50 template <class T>
51 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
52 {
53  static const size_t DIGEST_SIZE = static_cast<size_t>(T::DIGESTSIZE);
54  const unsigned int req = static_cast<unsigned int>(derivedLen);
55 
56  assert(secret && secretLen);
57  assert(derived && derivedLen);
58  assert(derivedLen <= MaxDerivedKeyLength());
59 
60  if (derivedLen > MaxDerivedKeyLength())
61  throw InvalidArgument("HKDF: derivedLen must be less than or equal to MaxDerivedKeyLength");
62 
63  HMAC<T> hmac;
65 
66  // Extract
67  const byte* key = (salt ? salt : GetNullVector());
68  const size_t klen = (salt ? saltLen : DIGEST_SIZE);
69 
70  hmac.SetKey(key, klen);
71  hmac.CalculateDigest(prk, secret, secretLen);
72 
73  // Expand
74  hmac.SetKey(prk.data(), prk.size());
75  byte block = 0;
76 
77  while (derivedLen > 0)
78  {
79  if (block++) {hmac.Update(buffer, buffer.size());}
80  if (info && infoLen) {hmac.Update(info, infoLen);}
81  hmac.CalculateDigest(buffer, &block, 1);
82 
83 #if CRYPTOPP_MSC_VERSION
84  const size_t segmentLen = STDMIN(derivedLen, DIGEST_SIZE);
85  memcpy_s(derived, segmentLen, buffer, segmentLen);
86 #else
87  const size_t segmentLen = STDMIN(derivedLen, DIGEST_SIZE);
88  std::memcpy(derived, buffer, segmentLen);
89 #endif
90 
91  derived += segmentLen;
92  derivedLen -= segmentLen;
93  }
94 
95  return req;
96 }
97 
98 NAMESPACE_END
99 
100 #endif // CRYPTOPP_HASH_KEY_DERIVATION_FUNCTION_H
An invalid argument was detected.
Definition: cryptlib.h:166
virtual void SetKey(const byte *key, size_t length, const NameValuePairs &params=g_nullNameValuePairs)
Sets or reset the key of this object.
Definition: cryptlib.cpp:100
General, multipurpose KDF from RFC 5869.
Definition: hkdf.h:29
Abstract base classes that provide a uniform interface to this library.
void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
Bounds checking replacement for memcpy()
Definition: misc.h:296
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:509
Classes and functions for secure memory allocations.
Classes for HMAC message authentication codes.
A::pointer data()
Provides a pointer to the first element in the memory block.
Definition: secblock.h:501
size_t MaxDerivedKeyLength() const
maximum number of bytes which can be produced under a secuirty context
Definition: hkdf.h:36
void Update(const byte *input, size_t length)
Updates a hash with additional input.
Definition: hmac.cpp:60
Fixed size stack-based SecBlock.
Definition: secblock.h:741
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:386
virtual void CalculateDigest(byte *digest, const byte *input, size_t length)
Updates the hash with additional input and computes the hash of the current message.
Definition: cryptlib.h:927
HMAC
Definition: hmac.h:43
Crypto++ library namespace.
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
derive a key from secret
Definition: hkdf.h:51
abstract base class for key derivation function
Definition: hkdf.h:14