proxygen
KeyScheduler.cpp
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 
10 
11 using folly::StringPiece;
12 
13 static constexpr StringPiece kTrafficKey{"key"};
14 static constexpr StringPiece kTrafficIv{"iv"};
15 
16 static constexpr StringPiece kExternalPskBinder{"ext binder"};
17 static constexpr StringPiece kResumptionPskBinder{"res binder"};
18 static constexpr StringPiece kClientEarlyTraffic{"c e traffic"};
19 static constexpr StringPiece kEarlyExporter{"e exp master"};
20 static constexpr StringPiece kClientHandshakeTraffic{"c hs traffic"};
21 static constexpr StringPiece kServerHandshakeTraffic{"s hs traffic"};
22 static constexpr StringPiece kClientAppTraffic{"c ap traffic"};
23 static constexpr StringPiece kServerAppTraffic{"s ap traffic"};
24 static constexpr StringPiece kExporterMaster{"exp master"};
25 static constexpr StringPiece kResumptionMaster{"res master"};
26 static constexpr StringPiece kDerivedSecret{"derived"};
27 static constexpr StringPiece kTrafficKeyUpdate{"traffic upd"};
28 static constexpr StringPiece kResumption{"resumption"};
29 
30 namespace fizz {
31 
33  if (secret_) {
34  throw std::runtime_error("secret already set");
35  }
36 
37  auto zeros = std::vector<uint8_t>(deriver_->hashLength(), 0);
38  secret_ = EarlySecret{deriver_->hkdfExtract(folly::range(zeros), psk)};
39 }
40 
42  auto& earlySecret = boost::get<EarlySecret>(*secret_);
43  auto zeros = std::vector<uint8_t>(deriver_->hashLength(), 0);
44  auto preSecret = deriver_->deriveSecret(
45  folly::range(earlySecret.secret), kDerivedSecret, deriver_->blankHash());
46  secret_ = HandshakeSecret{
47  deriver_->hkdfExtract(folly::range(preSecret), folly::range(zeros))};
48 }
49 
51  if (!secret_) {
52  auto zeros = std::vector<uint8_t>(deriver_->hashLength(), 0);
54  deriver_->hkdfExtract(folly::range(zeros), folly::range(zeros))};
55  }
56 
57  auto& earlySecret = boost::get<EarlySecret>(*secret_);
58  auto preSecret = deriver_->deriveSecret(
59  folly::range(earlySecret.secret), kDerivedSecret, deriver_->blankHash());
60  secret_ =
61  HandshakeSecret{deriver_->hkdfExtract(folly::range(preSecret), ecdhe)};
62 }
63 
65  auto zeros = std::vector<uint8_t>(deriver_->hashLength(), 0);
66  auto& handshakeSecret = boost::get<HandshakeSecret>(*secret_);
67  auto preSecret = deriver_->deriveSecret(
68  folly::range(handshakeSecret.secret),
70  deriver_->blankHash());
71  secret_ = MasterSecret{
72  deriver_->hkdfExtract(folly::range(preSecret), folly::range(zeros))};
73 }
74 
76  auto& masterSecret = boost::get<MasterSecret>(*secret_);
77  AppTrafficSecret trafficSecret;
78  trafficSecret.client = deriver_->deriveSecret(
79  folly::range(masterSecret.secret), kClientAppTraffic, transcript);
80  trafficSecret.server = deriver_->deriveSecret(
81  folly::range(masterSecret.secret), kServerAppTraffic, transcript);
82  appTrafficSecret_ = std::move(trafficSecret);
83 }
84 
86  boost::get<MasterSecret>(*secret_);
87  secret_ = folly::none;
88 }
89 
91  auto& appTrafficSecret = *appTrafficSecret_;
92  auto buf = deriver_->expandLabel(
93  folly::range(appTrafficSecret.client),
96  deriver_->hashLength());
97  buf->coalesce();
98  appTrafficSecret.client = std::vector<uint8_t>(buf->data(), buf->tail());
99  return ++appTrafficSecret.clientGeneration;
100 }
101 
103  auto& appTrafficSecret = *appTrafficSecret_;
104  auto buf = deriver_->expandLabel(
105  folly::range(appTrafficSecret.server),
108  deriver_->hashLength());
109  buf->coalesce();
110  appTrafficSecret.server = std::vector<uint8_t>(buf->data(), buf->tail());
111  return ++appTrafficSecret.serverGeneration;
112 }
113 
114 std::vector<uint8_t> KeyScheduler::getSecret(
115  EarlySecrets s,
116  folly::ByteRange transcript) const {
118  switch (s) {
120  label = kExternalPskBinder;
121  break;
123  label = kResumptionPskBinder;
124  break;
126  label = kClientEarlyTraffic;
127  break;
129  label = kEarlyExporter;
130  break;
131  default:
132  LOG(FATAL) << "unknown secret";
133  }
134 
135  auto& earlySecret = boost::get<EarlySecret>(*secret_);
136  return deriver_->deriveSecret(
137  folly::range(earlySecret.secret), label, transcript);
138 }
139 
140 std::vector<uint8_t> KeyScheduler::getSecret(
142  folly::ByteRange transcript) const {
144  switch (s) {
146  label = kClientHandshakeTraffic;
147  break;
149  label = kServerHandshakeTraffic;
150  break;
151  default:
152  LOG(FATAL) << "unknown secret";
153  }
154 
155  auto& handshakeSecret = boost::get<HandshakeSecret>(*secret_);
156  return deriver_->deriveSecret(
157  folly::range(handshakeSecret.secret), label, transcript);
158 }
159 
160 std::vector<uint8_t> KeyScheduler::getSecret(
162  folly::ByteRange transcript) const {
164  switch (s) {
166  label = kExporterMaster;
167  break;
169  label = kResumptionMaster;
170  break;
171  default:
172  LOG(FATAL) << "unknown secret";
173  }
174 
175  auto& masterSecret = boost::get<MasterSecret>(*secret_);
176  return deriver_->deriveSecret(
177  folly::range(masterSecret.secret), label, transcript);
178 }
179 
180 std::vector<uint8_t> KeyScheduler::getSecret(AppTrafficSecrets s) const {
181  auto& appTrafficSecret = *appTrafficSecret_;
182  switch (s) {
184  return appTrafficSecret.client;
186  return appTrafficSecret.server;
187  default:
188  LOG(FATAL) << "unknown secret";
189  }
190 }
191 
193  folly::ByteRange trafficSecret,
194  size_t keyLength,
195  size_t ivLength) const {
196  TrafficKey trafficKey;
197  trafficKey.key = deriver_->expandLabel(
198  trafficSecret, kTrafficKey, folly::IOBuf::create(0), keyLength);
199  trafficKey.iv = deriver_->expandLabel(
200  trafficSecret, kTrafficIv, folly::IOBuf::create(0), ivLength);
201  return trafficKey;
202 }
203 
205  folly::ByteRange resumptionMasterSecret,
206  folly::ByteRange ticketNonce) const {
207  return deriver_->expandLabel(
208  resumptionMasterSecret,
209  kResumption,
210  folly::IOBuf::wrapBuffer(ticketNonce),
211  deriver_->hashLength());
212 }
213 } // namespace fizz
AppTrafficSecrets
Definition: KeyScheduler.h:28
folly::Optional< boost::variant< EarlySecret, HandshakeSecret, MasterSecret > > secret_
Definition: KeyScheduler.h:131
virtual TrafficKey getTrafficKey(folly::ByteRange trafficSecret, size_t keyLength, size_t ivLength) const
folly::Optional< AppTrafficSecret > appTrafficSecret_
Definition: KeyScheduler.h:132
virtual void deriveEarlySecret(folly::ByteRange psk)
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
static std::unique_ptr< IOBuf > wrapBuffer(const void *buf, std::size_t capacity)
Definition: IOBuf.cpp:353
virtual std::vector< uint8_t > getSecret(EarlySecrets s, folly::ByteRange transcript) const
static constexpr StringPiece kServerAppTraffic
static constexpr StringPiece kExternalPskBinder
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static constexpr StringPiece kClientHandshakeTraffic
static constexpr StringPiece kExporterMaster
std::unique_ptr< folly::IOBuf > key
Definition: Aead.h:17
std::unique_ptr< folly::IOBuf > iv
Definition: Aead.h:18
static constexpr StringPiece kClientAppTraffic
static constexpr StringPiece kEarlyExporter
std::unique_ptr< KeyDerivation > deriver_
Definition: KeyScheduler.h:134
static constexpr StringPiece kTrafficKeyUpdate
EarlySecrets
Definition: KeyScheduler.h:17
MasterSecrets
Definition: KeyScheduler.h:26
virtual void deriveHandshakeSecret()
virtual uint32_t serverKeyUpdate()
virtual Buf getResumptionSecret(folly::ByteRange resumptionMasterSecret, folly::ByteRange ticketNonce) const
constexpr Range< Iter > range(Iter first, Iter last)
Definition: Range.h:1114
Definition: Actions.h:16
static constexpr StringPiece kResumption
HandshakeSecrets
Definition: KeyScheduler.h:24
static constexpr StringPiece kResumptionPskBinder
static constexpr StringPiece kTrafficKey
virtual void deriveAppTrafficSecrets(folly::ByteRange transcript)
virtual void clearMasterSecret()
std::unique_ptr< folly::IOBuf > Buf
Definition: Types.h:22
static constexpr StringPiece kResumptionMaster
static set< string > s
virtual void deriveMasterSecret()
static constexpr StringPiece kClientEarlyTraffic
static constexpr StringPiece kDerivedSecret
Range< const char * > StringPiece
static constexpr StringPiece kTrafficIv
constexpr None none
Definition: Optional.h:87
StringPiece label
static constexpr StringPiece kServerHandshakeTraffic
virtual uint32_t clientKeyUpdate()