proxygen
Hkdf-inl.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree.
7  */
8 
9 namespace fizz {
10 
11 template <typename Hash>
12 inline std::vector<uint8_t> HkdfImpl<Hash>::extract(
13  folly::ByteRange salt,
14  folly::ByteRange ikm) const {
15  auto zeros = std::vector<uint8_t>(Hash::HashLen, 0);
16  // Extraction step HMAC-HASH(salt, IKM)
17  std::vector<uint8_t> extractedKey(Hash::HashLen);
18  salt = salt.empty() ? folly::range(zeros) : salt;
19  Hash::hmac(
20  salt, folly::IOBuf::wrapBufferAsValue(ikm), folly::range(extractedKey));
21  return extractedKey;
22 }
23 
24 template <typename Hash>
25 inline std::unique_ptr<folly::IOBuf> HkdfImpl<Hash>::expand(
26  folly::ByteRange extractedKey,
27  const folly::IOBuf& info,
28  size_t outputBytes) const {
29  CHECK_EQ(extractedKey.size(), Hash::HashLen);
30  if (UNLIKELY(outputBytes > 255 * Hash::HashLen)) {
31  throw std::runtime_error("Output too long");
32  }
33  // HDKF expansion step.
34  size_t numRounds = (outputBytes + Hash::HashLen - 1) / Hash::HashLen;
35  auto expanded = folly::IOBuf::create(numRounds * Hash::HashLen);
36 
37  auto in = folly::IOBuf::create(0);
38  for (size_t round = 1; round <= numRounds; ++round) {
39  in->prependChain(info.clone());
40  // We're guaranteed that the round num will fit in
41  // one byte because of the check at the beginning of
42  // the method.
43  auto roundNum = folly::IOBuf::create(1);
44  roundNum->append(1);
45  roundNum->writableData()[0] = round;
46  in->prependChain(std::move(roundNum));
47 
48  size_t outputStartIdx = (round - 1) * Hash::HashLen;
49  Hash::hmac(
50  folly::range(extractedKey),
51  *in,
52  {expanded->writableData() + outputStartIdx, Hash::HashLen});
53  expanded->append(Hash::HashLen);
54 
55  in = expanded->clone();
56  in->trimStart(outputStartIdx);
57  }
58  expanded->trimEnd(numRounds * Hash::HashLen - outputBytes);
59  return expanded;
60 }
61 
62 template <typename Hash>
63 inline std::unique_ptr<folly::IOBuf> HkdfImpl<Hash>::hkdf(
64  folly::ByteRange ikm,
65  folly::ByteRange salt,
66  const folly::IOBuf& info,
67  size_t outputBytes) const {
68  return expand(folly::range(extract(salt, ikm)), info, outputBytes);
69 }
70 } // namespace fizz
def info()
Definition: deadlock.py:447
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
constexpr To round(std::chrono::duration< Rep, Period > const &d)
Definition: Chrono.h:139
std::unique_ptr< folly::IOBuf > hkdf(folly::ByteRange ikm, folly::ByteRange salt, const folly::IOBuf &info, size_t outputBytes) const override
Definition: Hkdf-inl.h:63
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
constexpr size_type size() const
Definition: Range.h:431
std::unique_ptr< IOBuf > clone() const
Definition: IOBuf.cpp:527
constexpr bool empty() const
Definition: Range.h:443
constexpr Range< Iter > range(Iter first, Iter last)
Definition: Range.h:1114
Definition: Actions.h:16
static IOBuf wrapBufferAsValue(const void *buf, std::size_t capacity) noexcept
Definition: IOBuf.cpp:357
std::unique_ptr< folly::IOBuf > expand(folly::ByteRange extractedKey, const folly::IOBuf &info, size_t outputBytes) const override
Definition: Hkdf-inl.h:25
std::vector< uint8_t > extract(folly::ByteRange salt, folly::ByteRange ikm) const override
Definition: Hkdf-inl.h:12
#define UNLIKELY(x)
Definition: Likely.h:48