• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2016, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include <openssl/ssl.h>
16 
17 #include <assert.h>
18 #include <string.h>
19 
20 #include <algorithm>
21 #include <utility>
22 
23 #include <openssl/aead.h>
24 #include <openssl/aes.h>
25 #include <openssl/bytestring.h>
26 #include <openssl/chacha.h>
27 #include <openssl/digest.h>
28 #include <openssl/hkdf.h>
29 #include <openssl/hmac.h>
30 #include <openssl/mem.h>
31 
32 #include "../crypto/fipsmodule/tls/internal.h"
33 #include "../crypto/internal.h"
34 #include "internal.h"
35 
36 
37 BSSL_NAMESPACE_BEGIN
38 
init_key_schedule(SSL_HANDSHAKE * hs,SSLTranscript * transcript,uint16_t version,const SSL_CIPHER * cipher)39 static bool init_key_schedule(SSL_HANDSHAKE *hs, SSLTranscript *transcript,
40                               uint16_t version, const SSL_CIPHER *cipher) {
41   if (!transcript->InitHash(version, cipher)) {
42     return false;
43   }
44 
45   // Initialize the secret to the zero key.
46   hs->secret.clear();
47   hs->secret.Resize(transcript->DigestLen());
48   return true;
49 }
50 
hkdf_extract_to_secret(SSL_HANDSHAKE * hs,const SSLTranscript & transcript,Span<const uint8_t> in)51 static bool hkdf_extract_to_secret(SSL_HANDSHAKE *hs,
52                                    const SSLTranscript &transcript,
53                                    Span<const uint8_t> in) {
54   size_t len;
55   if (!HKDF_extract(hs->secret.data(), &len, transcript.Digest(), in.data(),
56                     in.size(), hs->secret.data(), hs->secret.size())) {
57     return false;
58   }
59   assert(len == hs->secret.size());
60   return true;
61 }
62 
tls13_init_key_schedule(SSL_HANDSHAKE * hs,Span<const uint8_t> psk)63 bool tls13_init_key_schedule(SSL_HANDSHAKE *hs, Span<const uint8_t> psk) {
64   if (!init_key_schedule(hs, &hs->transcript, ssl_protocol_version(hs->ssl),
65                          hs->new_cipher)) {
66     return false;
67   }
68 
69   // Handback includes the whole handshake transcript, so we cannot free the
70   // transcript buffer in the handback case.
71   if (!hs->handback) {
72     hs->transcript.FreeBuffer();
73   }
74   return hkdf_extract_to_secret(hs, hs->transcript, psk);
75 }
76 
tls13_init_early_key_schedule(SSL_HANDSHAKE * hs,const SSL_SESSION * session)77 bool tls13_init_early_key_schedule(SSL_HANDSHAKE *hs,
78                                    const SSL_SESSION *session) {
79   assert(!hs->ssl->server);
80   // When offering ECH, early data is associated with ClientHelloInner, not
81   // ClientHelloOuter.
82   SSLTranscript *transcript =
83       hs->selected_ech_config ? &hs->inner_transcript : &hs->transcript;
84   return init_key_schedule(hs, transcript,
85                            ssl_session_protocol_version(session),
86                            session->cipher) &&
87          hkdf_extract_to_secret(hs, *transcript, session->secret);
88 }
89 
label_to_span(const char * label)90 static Span<const char> label_to_span(const char *label) {
91   return MakeConstSpan(label, strlen(label));
92 }
93 
hkdf_expand_label_with_prefix(Span<uint8_t> out,const EVP_MD * digest,Span<const uint8_t> secret,Span<const uint8_t> label_prefix,Span<const char> label,Span<const uint8_t> hash)94 static bool hkdf_expand_label_with_prefix(Span<uint8_t> out,
95                                           const EVP_MD *digest,
96                                           Span<const uint8_t> secret,
97                                           Span<const uint8_t> label_prefix,
98                                           Span<const char> label,
99                                           Span<const uint8_t> hash) {
100   // This is a copy of CRYPTO_tls13_hkdf_expand_label, but modified to take an
101   // arbitrary prefix for the label instead of using the hardcoded "tls13 "
102   // prefix.
103   CBB cbb, child;
104   uint8_t *hkdf_label = NULL;
105   size_t hkdf_label_len;
106   CBB_zero(&cbb);
107   if (!CBB_init(&cbb,
108                 2 + 1 + label_prefix.size() + label.size() + 1 + hash.size()) ||
109       !CBB_add_u16(&cbb, out.size()) ||
110       !CBB_add_u8_length_prefixed(&cbb, &child) ||
111       !CBB_add_bytes(&child, label_prefix.data(), label_prefix.size()) ||
112       !CBB_add_bytes(&child, reinterpret_cast<const uint8_t *>(label.data()),
113                      label.size()) ||
114       !CBB_add_u8_length_prefixed(&cbb, &child) ||
115       !CBB_add_bytes(&child, hash.data(), hash.size()) ||
116       !CBB_finish(&cbb, &hkdf_label, &hkdf_label_len)) {
117     CBB_cleanup(&cbb);
118     return false;
119   }
120 
121   const int ret = HKDF_expand(out.data(), out.size(), digest, secret.data(),
122                               secret.size(), hkdf_label, hkdf_label_len);
123   OPENSSL_free(hkdf_label);
124   return ret == 1;
125 }
126 
hkdf_expand_label(Span<uint8_t> out,const EVP_MD * digest,Span<const uint8_t> secret,Span<const char> label,Span<const uint8_t> hash,bool is_dtls)127 static bool hkdf_expand_label(Span<uint8_t> out, const EVP_MD *digest,
128                               Span<const uint8_t> secret,
129                               Span<const char> label, Span<const uint8_t> hash,
130                               bool is_dtls) {
131   if (is_dtls) {
132     static const uint8_t kDTLS13LabelPrefix[] = "dtls13";
133     return hkdf_expand_label_with_prefix(
134         out, digest, secret,
135         MakeConstSpan(kDTLS13LabelPrefix, sizeof(kDTLS13LabelPrefix) - 1),
136         label, hash);
137   }
138   return CRYPTO_tls13_hkdf_expand_label(
139              out.data(), out.size(), digest, secret.data(), secret.size(),
140              reinterpret_cast<const uint8_t *>(label.data()), label.size(),
141              hash.data(), hash.size()) == 1;
142 }
143 
144 static const char kTLS13LabelDerived[] = "derived";
145 
tls13_advance_key_schedule(SSL_HANDSHAKE * hs,Span<const uint8_t> in)146 bool tls13_advance_key_schedule(SSL_HANDSHAKE *hs, Span<const uint8_t> in) {
147   uint8_t derive_context[EVP_MAX_MD_SIZE];
148   unsigned derive_context_len;
149   return EVP_Digest(nullptr, 0, derive_context, &derive_context_len,
150                     hs->transcript.Digest(), nullptr) &&
151          hkdf_expand_label(MakeSpan(hs->secret), hs->transcript.Digest(),
152                            hs->secret, label_to_span(kTLS13LabelDerived),
153                            MakeConstSpan(derive_context, derive_context_len),
154                            SSL_is_dtls(hs->ssl)) &&
155          hkdf_extract_to_secret(hs, hs->transcript, in);
156 }
157 
158 // derive_secret_with_transcript derives a secret of length
159 // |transcript.DigestLen()| and writes the result in |out| with the given label,
160 // the current base secret, and the state of |transcript|. It returns true on
161 // success and false on error.
derive_secret_with_transcript(const SSL_HANDSHAKE * hs,InplaceVector<uint8_t,SSL_MAX_MD_SIZE> * out,const SSLTranscript & transcript,Span<const char> label)162 static bool derive_secret_with_transcript(
163     const SSL_HANDSHAKE *hs, InplaceVector<uint8_t, SSL_MAX_MD_SIZE> *out,
164     const SSLTranscript &transcript, Span<const char> label) {
165   uint8_t context_hash[EVP_MAX_MD_SIZE];
166   size_t context_hash_len;
167   if (!transcript.GetHash(context_hash, &context_hash_len)) {
168     return false;
169   }
170 
171   out->ResizeForOverwrite(transcript.DigestLen());
172   return hkdf_expand_label(MakeSpan(*out), transcript.Digest(), hs->secret,
173                            label, MakeConstSpan(context_hash, context_hash_len),
174                            SSL_is_dtls(hs->ssl));
175 }
176 
derive_secret(SSL_HANDSHAKE * hs,InplaceVector<uint8_t,SSL_MAX_MD_SIZE> * out,Span<const char> label)177 static bool derive_secret(SSL_HANDSHAKE *hs,
178                           InplaceVector<uint8_t, SSL_MAX_MD_SIZE> *out,
179                           Span<const char> label) {
180   return derive_secret_with_transcript(hs, out, hs->transcript, label);
181 }
182 
tls13_set_traffic_key(SSL * ssl,enum ssl_encryption_level_t level,enum evp_aead_direction_t direction,const SSL_SESSION * session,Span<const uint8_t> traffic_secret)183 bool tls13_set_traffic_key(SSL *ssl, enum ssl_encryption_level_t level,
184                            enum evp_aead_direction_t direction,
185                            const SSL_SESSION *session,
186                            Span<const uint8_t> traffic_secret) {
187   uint16_t version = ssl_session_protocol_version(session);
188   const EVP_MD *digest = ssl_session_get_digest(session);
189   bool is_dtls = SSL_is_dtls(ssl);
190   UniquePtr<SSLAEADContext> traffic_aead;
191   if (ssl->quic_method != nullptr) {
192     // Install a placeholder SSLAEADContext so that SSL accessors work. The
193     // encryption itself will be handled by the SSL_QUIC_METHOD.
194     traffic_aead = SSLAEADContext::CreatePlaceholderForQUIC(session->cipher);
195   } else {
196     // Look up cipher suite properties.
197     const EVP_AEAD *aead;
198     size_t discard;
199     if (!ssl_cipher_get_evp_aead(&aead, &discard, &discard, session->cipher,
200                                  version)) {
201       return false;
202     }
203 
204     // Derive the key and IV.
205     uint8_t key_buf[EVP_AEAD_MAX_KEY_LENGTH], iv_buf[EVP_AEAD_MAX_NONCE_LENGTH];
206     auto key = MakeSpan(key_buf).first(EVP_AEAD_key_length(aead));
207     auto iv = MakeSpan(iv_buf).first(EVP_AEAD_nonce_length(aead));
208     if (!hkdf_expand_label(key, digest, traffic_secret, label_to_span("key"),
209                            {}, is_dtls) ||
210         !hkdf_expand_label(iv, digest, traffic_secret, label_to_span("iv"), {},
211                            is_dtls)) {
212       return false;
213     }
214 
215     traffic_aead = SSLAEADContext::Create(direction, session->ssl_version,
216                                           session->cipher, key, {}, iv);
217   }
218 
219   if (!traffic_aead) {
220     return false;
221   }
222 
223   if (direction == evp_aead_open) {
224     if (!ssl->method->set_read_state(ssl, level, std::move(traffic_aead),
225                                      traffic_secret)) {
226       return false;
227     }
228     ssl->s3->read_traffic_secret.CopyFrom(traffic_secret);
229   } else {
230     if (!ssl->method->set_write_state(ssl, level, std::move(traffic_aead),
231                                       traffic_secret)) {
232       return false;
233     }
234     ssl->s3->write_traffic_secret.CopyFrom(traffic_secret);
235   }
236 
237   return true;
238 }
239 
240 namespace {
241 
242 class AESRecordNumberEncrypter : public RecordNumberEncrypter {
243  public:
SetKey(Span<const uint8_t> key)244   bool SetKey(Span<const uint8_t> key) override {
245     return AES_set_encrypt_key(key.data(), key.size() * 8, &key_) == 0;
246   }
247 
GenerateMask(Span<uint8_t> out,Span<const uint8_t> sample)248   bool GenerateMask(Span<uint8_t> out, Span<const uint8_t> sample) override {
249     if (sample.size() < AES_BLOCK_SIZE || out.size() > AES_BLOCK_SIZE) {
250       return false;
251     }
252     uint8_t mask[AES_BLOCK_SIZE];
253     AES_encrypt(sample.data(), mask, &key_);
254     OPENSSL_memcpy(out.data(), mask, out.size());
255     return true;
256   }
257 
258  private:
259   AES_KEY key_;
260 };
261 
262 class AES128RecordNumberEncrypter : public AESRecordNumberEncrypter {
263  public:
KeySize()264   size_t KeySize() override { return 16; }
265 };
266 
267 class AES256RecordNumberEncrypter : public AESRecordNumberEncrypter {
268  public:
KeySize()269   size_t KeySize() override { return 32; }
270 };
271 
272 class ChaChaRecordNumberEncrypter : public RecordNumberEncrypter {
273  public:
KeySize()274   size_t KeySize() override { return kKeySize; }
275 
SetKey(Span<const uint8_t> key)276   bool SetKey(Span<const uint8_t> key) override {
277     if (key.size() != kKeySize) {
278       return false;
279     }
280     OPENSSL_memcpy(key_, key.data(), key.size());
281     return true;
282   }
283 
GenerateMask(Span<uint8_t> out,Span<const uint8_t> sample)284   bool GenerateMask(Span<uint8_t> out, Span<const uint8_t> sample) override {
285     // RFC 9147 section 4.2.3 uses the first 4 bytes of the sample as the
286     // counter and the next 12 bytes as the nonce. If we have less than 4+12=16
287     // bytes in the sample, then we'll read past the end of the |sample| buffer.
288     // The counter is interpreted as little-endian per RFC 8439.
289     if (sample.size() < 16) {
290       return false;
291     }
292     uint32_t counter = CRYPTO_load_u32_le(sample.data());
293     Span<const uint8_t> nonce = sample.subspan(4);
294     OPENSSL_memset(out.data(), 0, out.size());
295     CRYPTO_chacha_20(out.data(), out.data(), out.size(), key_, nonce.data(),
296                      counter);
297     return true;
298   }
299 
300  private:
301   static constexpr size_t kKeySize = 32;
302   uint8_t key_[kKeySize];
303 };
304 
305 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
306 class NullRecordNumberEncrypter : public RecordNumberEncrypter {
307  public:
KeySize()308   size_t KeySize() override { return 0; }
SetKey(Span<const uint8_t> key)309   bool SetKey(Span<const uint8_t> key) override { return true; }
GenerateMask(Span<uint8_t> out,Span<const uint8_t> sample)310   bool GenerateMask(Span<uint8_t> out, Span<const uint8_t> sample) override {
311     OPENSSL_memset(out.data(), 0, out.size());
312     return true;
313   }
314 };
315 #endif  // BORINGSSL_UNSAFE_FUZZER_MODE
316 
317 }  // namespace
318 
Create(const SSL_CIPHER * cipher,Span<const uint8_t> traffic_secret)319 UniquePtr<RecordNumberEncrypter> RecordNumberEncrypter::Create(
320     const SSL_CIPHER *cipher, Span<const uint8_t> traffic_secret) {
321   const EVP_MD *digest = ssl_get_handshake_digest(TLS1_3_VERSION, cipher);
322   UniquePtr<RecordNumberEncrypter> ret;
323 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
324   ret = MakeUnique<NullRecordNumberEncrypter>();
325 #else
326   if (cipher->algorithm_enc == SSL_AES128GCM) {
327     ret = MakeUnique<AES128RecordNumberEncrypter>();
328   } else if (cipher->algorithm_enc == SSL_AES256GCM) {
329     ret = MakeUnique<AES256RecordNumberEncrypter>();
330   } else if (cipher->algorithm_enc == SSL_CHACHA20POLY1305) {
331     ret = MakeUnique<ChaChaRecordNumberEncrypter>();
332   } else {
333     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
334   }
335 #endif  // BORINGSSL_UNSAFE_FUZZER_MODE
336   if (ret == nullptr) {
337     return nullptr;
338   }
339 
340   uint8_t rne_key_buf[RecordNumberEncrypter::kMaxKeySize];
341   auto rne_key = MakeSpan(rne_key_buf).first(ret->KeySize());
342   if (!hkdf_expand_label(rne_key, digest, traffic_secret, label_to_span("sn"),
343                          {}, /*is_dtls=*/true) ||
344       !ret->SetKey(rne_key)) {
345     return nullptr;
346   }
347   return ret;
348 }
349 
350 static const char kTLS13LabelExporter[] = "exp master";
351 
352 static const char kTLS13LabelClientEarlyTraffic[] = "c e traffic";
353 static const char kTLS13LabelClientHandshakeTraffic[] = "c hs traffic";
354 static const char kTLS13LabelServerHandshakeTraffic[] = "s hs traffic";
355 static const char kTLS13LabelClientApplicationTraffic[] = "c ap traffic";
356 static const char kTLS13LabelServerApplicationTraffic[] = "s ap traffic";
357 
tls13_derive_early_secret(SSL_HANDSHAKE * hs)358 bool tls13_derive_early_secret(SSL_HANDSHAKE *hs) {
359   SSL *const ssl = hs->ssl;
360   // When offering ECH on the client, early data is associated with
361   // ClientHelloInner, not ClientHelloOuter.
362   const SSLTranscript &transcript = (!ssl->server && hs->selected_ech_config)
363                                         ? hs->inner_transcript
364                                         : hs->transcript;
365   if (!derive_secret_with_transcript(
366           hs, &hs->early_traffic_secret, transcript,
367           label_to_span(kTLS13LabelClientEarlyTraffic)) ||
368       !ssl_log_secret(ssl, "CLIENT_EARLY_TRAFFIC_SECRET",
369                       hs->early_traffic_secret)) {
370     return false;
371   }
372   return true;
373 }
374 
tls13_derive_handshake_secrets(SSL_HANDSHAKE * hs)375 bool tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs) {
376   SSL *const ssl = hs->ssl;
377   if (!derive_secret(hs, &hs->client_handshake_secret,
378                      label_to_span(kTLS13LabelClientHandshakeTraffic)) ||
379       !ssl_log_secret(ssl, "CLIENT_HANDSHAKE_TRAFFIC_SECRET",
380                       hs->client_handshake_secret) ||
381       !derive_secret(hs, &hs->server_handshake_secret,
382                      label_to_span(kTLS13LabelServerHandshakeTraffic)) ||
383       !ssl_log_secret(ssl, "SERVER_HANDSHAKE_TRAFFIC_SECRET",
384                       hs->server_handshake_secret)) {
385     return false;
386   }
387 
388   return true;
389 }
390 
tls13_derive_application_secrets(SSL_HANDSHAKE * hs)391 bool tls13_derive_application_secrets(SSL_HANDSHAKE *hs) {
392   SSL *const ssl = hs->ssl;
393   if (!derive_secret(hs, &hs->client_traffic_secret_0,
394                      label_to_span(kTLS13LabelClientApplicationTraffic)) ||
395       !ssl_log_secret(ssl, "CLIENT_TRAFFIC_SECRET_0",
396                       hs->client_traffic_secret_0) ||
397       !derive_secret(hs, &hs->server_traffic_secret_0,
398                      label_to_span(kTLS13LabelServerApplicationTraffic)) ||
399       !ssl_log_secret(ssl, "SERVER_TRAFFIC_SECRET_0",
400                       hs->server_traffic_secret_0) ||
401       !derive_secret(hs, &ssl->s3->exporter_secret,
402                      label_to_span(kTLS13LabelExporter)) ||
403       !ssl_log_secret(ssl, "EXPORTER_SECRET", ssl->s3->exporter_secret)) {
404     return false;
405   }
406 
407   return true;
408 }
409 
410 static const char kTLS13LabelApplicationTraffic[] = "traffic upd";
411 
tls13_rotate_traffic_key(SSL * ssl,enum evp_aead_direction_t direction)412 bool tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction) {
413   Span<uint8_t> secret = direction == evp_aead_open
414                              ? MakeSpan(ssl->s3->read_traffic_secret)
415                              : MakeSpan(ssl->s3->write_traffic_secret);
416 
417   const SSL_SESSION *session = SSL_get_session(ssl);
418   const EVP_MD *digest = ssl_session_get_digest(session);
419   return hkdf_expand_label(secret, digest, secret,
420                            label_to_span(kTLS13LabelApplicationTraffic), {},
421                            SSL_is_dtls(ssl)) &&
422          tls13_set_traffic_key(ssl, ssl_encryption_application, direction,
423                                session, secret);
424 }
425 
426 static const char kTLS13LabelResumption[] = "res master";
427 
tls13_derive_resumption_secret(SSL_HANDSHAKE * hs)428 bool tls13_derive_resumption_secret(SSL_HANDSHAKE *hs) {
429   return derive_secret(hs, &hs->new_session->secret,
430                        label_to_span(kTLS13LabelResumption));
431 }
432 
433 static const char kTLS13LabelFinished[] = "finished";
434 
435 // tls13_verify_data sets |out| to be the HMAC of |context| using a derived
436 // Finished key for both Finished messages and the PSK binder. |out| must have
437 // space available for |EVP_MAX_MD_SIZE| bytes.
tls13_verify_data(uint8_t * out,size_t * out_len,const EVP_MD * digest,uint16_t version,Span<const uint8_t> secret,Span<const uint8_t> context,bool is_dtls)438 static bool tls13_verify_data(uint8_t *out, size_t *out_len,
439                               const EVP_MD *digest, uint16_t version,
440                               Span<const uint8_t> secret,
441                               Span<const uint8_t> context, bool is_dtls) {
442   uint8_t key_buf[EVP_MAX_MD_SIZE];
443   auto key = MakeSpan(key_buf, EVP_MD_size(digest));
444   unsigned len;
445   if (!hkdf_expand_label(key, digest, secret,
446                          label_to_span(kTLS13LabelFinished), {}, is_dtls) ||
447       HMAC(digest, key.data(), key.size(), context.data(), context.size(), out,
448            &len) == nullptr) {
449     return false;
450   }
451   *out_len = len;
452   return true;
453 }
454 
tls13_finished_mac(SSL_HANDSHAKE * hs,uint8_t * out,size_t * out_len,bool is_server)455 bool tls13_finished_mac(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len,
456                         bool is_server) {
457   Span<const uint8_t> traffic_secret =
458       is_server ? hs->server_handshake_secret : hs->client_handshake_secret;
459 
460   uint8_t context_hash[EVP_MAX_MD_SIZE];
461   size_t context_hash_len;
462   if (!hs->transcript.GetHash(context_hash, &context_hash_len) ||
463       !tls13_verify_data(out, out_len, hs->transcript.Digest(),
464                          hs->ssl->s3->version, traffic_secret,
465                          MakeConstSpan(context_hash, context_hash_len),
466                          SSL_is_dtls(hs->ssl))) {
467     return false;
468   }
469   return true;
470 }
471 
472 static const char kTLS13LabelResumptionPSK[] = "resumption";
473 
tls13_derive_session_psk(SSL_SESSION * session,Span<const uint8_t> nonce,bool is_dtls)474 bool tls13_derive_session_psk(SSL_SESSION *session, Span<const uint8_t> nonce,
475                               bool is_dtls) {
476   const EVP_MD *digest = ssl_session_get_digest(session);
477   // The session initially stores the resumption_master_secret, which we
478   // override with the PSK.
479   assert(session->secret.size() == EVP_MD_size(digest));
480   return hkdf_expand_label(MakeSpan(session->secret), digest, session->secret,
481                            label_to_span(kTLS13LabelResumptionPSK), nonce,
482                            is_dtls);
483 }
484 
485 static const char kTLS13LabelExportKeying[] = "exporter";
486 
tls13_export_keying_material(SSL * ssl,Span<uint8_t> out,Span<const uint8_t> secret,Span<const char> label,Span<const uint8_t> context)487 bool tls13_export_keying_material(SSL *ssl, Span<uint8_t> out,
488                                   Span<const uint8_t> secret,
489                                   Span<const char> label,
490                                   Span<const uint8_t> context) {
491   if (secret.empty()) {
492     assert(0);
493     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
494     return false;
495   }
496 
497   const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl));
498 
499   uint8_t hash_buf[EVP_MAX_MD_SIZE];
500   uint8_t export_context_buf[EVP_MAX_MD_SIZE];
501   unsigned hash_len;
502   unsigned export_context_len;
503   if (!EVP_Digest(context.data(), context.size(), hash_buf, &hash_len, digest,
504                   nullptr) ||
505       !EVP_Digest(nullptr, 0, export_context_buf, &export_context_len, digest,
506                   nullptr)) {
507     return false;
508   }
509 
510   auto hash = MakeConstSpan(hash_buf, hash_len);
511   auto export_context = MakeConstSpan(export_context_buf, export_context_len);
512   uint8_t derived_secret_buf[EVP_MAX_MD_SIZE];
513   auto derived_secret = MakeSpan(derived_secret_buf, EVP_MD_size(digest));
514   return hkdf_expand_label(derived_secret, digest, secret, label,
515                            export_context, SSL_is_dtls(ssl)) &&
516          hkdf_expand_label(out, digest, derived_secret,
517                            label_to_span(kTLS13LabelExportKeying), hash,
518                            SSL_is_dtls(ssl));
519 }
520 
521 static const char kTLS13LabelPSKBinder[] = "res binder";
522 
tls13_psk_binder(uint8_t * out,size_t * out_len,const SSL_SESSION * session,const SSLTranscript & transcript,Span<const uint8_t> client_hello,size_t binders_len,bool is_dtls)523 static bool tls13_psk_binder(uint8_t *out, size_t *out_len,
524                              const SSL_SESSION *session,
525                              const SSLTranscript &transcript,
526                              Span<const uint8_t> client_hello,
527                              size_t binders_len, bool is_dtls) {
528   const EVP_MD *digest = ssl_session_get_digest(session);
529 
530   // Compute the binder key.
531   //
532   // TODO(davidben): Ideally we wouldn't recompute early secret and the binder
533   // key each time.
534   uint8_t binder_context[EVP_MAX_MD_SIZE];
535   unsigned binder_context_len;
536   uint8_t early_secret[EVP_MAX_MD_SIZE] = {0};
537   size_t early_secret_len;
538   uint8_t binder_key_buf[EVP_MAX_MD_SIZE] = {0};
539   auto binder_key = MakeSpan(binder_key_buf, EVP_MD_size(digest));
540   if (!EVP_Digest(nullptr, 0, binder_context, &binder_context_len, digest,
541                   nullptr) ||
542       !HKDF_extract(early_secret, &early_secret_len, digest,
543                     session->secret.data(), session->secret.size(), nullptr,
544                     0) ||
545       !hkdf_expand_label(
546           binder_key, digest, MakeConstSpan(early_secret, early_secret_len),
547           label_to_span(kTLS13LabelPSKBinder),
548           MakeConstSpan(binder_context, binder_context_len), is_dtls)) {
549     return false;
550   }
551 
552   // Hash the transcript and truncated ClientHello.
553   if (client_hello.size() < binders_len) {
554     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
555     return false;
556   }
557   auto truncated = client_hello.subspan(0, client_hello.size() - binders_len);
558   uint8_t context[EVP_MAX_MD_SIZE];
559   unsigned context_len;
560   ScopedEVP_MD_CTX ctx;
561   if (!is_dtls) {
562     if (!transcript.CopyToHashContext(ctx.get(), digest) ||
563         !EVP_DigestUpdate(ctx.get(), truncated.data(), truncated.size()) ||
564         !EVP_DigestFinal_ex(ctx.get(), context, &context_len)) {
565       return false;
566     }
567   } else {
568     // In DTLS 1.3, the transcript hash is computed over only the TLS 1.3
569     // handshake messages (i.e. only type and length in the header), not the
570     // full DTLSHandshake messages that are in |truncated|. This code pulls
571     // the header and body out of the truncated ClientHello and writes those
572     // to the hash context so the correct binder value is computed.
573     if (truncated.size() < DTLS1_HM_HEADER_LENGTH) {
574       return false;
575     }
576     auto header = truncated.subspan(0, 4);
577     auto body = truncated.subspan(12);
578     if (!transcript.CopyToHashContext(ctx.get(), digest) ||
579         !EVP_DigestUpdate(ctx.get(), header.data(), header.size()) ||
580         !EVP_DigestUpdate(ctx.get(), body.data(), body.size()) ||
581         !EVP_DigestFinal_ex(ctx.get(), context, &context_len)) {
582       return false;
583     }
584   }
585 
586   if (!tls13_verify_data(out, out_len, digest, session->ssl_version, binder_key,
587                          MakeConstSpan(context, context_len), is_dtls)) {
588     return false;
589   }
590 
591   assert(*out_len == EVP_MD_size(digest));
592   return true;
593 }
594 
tls13_write_psk_binder(const SSL_HANDSHAKE * hs,const SSLTranscript & transcript,Span<uint8_t> msg,size_t * out_binder_len)595 bool tls13_write_psk_binder(const SSL_HANDSHAKE *hs,
596                             const SSLTranscript &transcript, Span<uint8_t> msg,
597                             size_t *out_binder_len) {
598   const SSL *const ssl = hs->ssl;
599   const EVP_MD *digest = ssl_session_get_digest(ssl->session.get());
600   const size_t hash_len = EVP_MD_size(digest);
601   // We only offer one PSK, so the binders are a u16 and u8 length
602   // prefix, followed by the binder. The caller is assumed to have constructed
603   // |msg| with placeholder binders.
604   const size_t binders_len = 3 + hash_len;
605   uint8_t verify_data[EVP_MAX_MD_SIZE];
606   size_t verify_data_len;
607   if (!tls13_psk_binder(verify_data, &verify_data_len, ssl->session.get(),
608                         transcript, msg, binders_len, SSL_is_dtls(hs->ssl)) ||
609       verify_data_len != hash_len) {
610     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
611     return false;
612   }
613 
614   auto msg_binder = msg.last(verify_data_len);
615   OPENSSL_memcpy(msg_binder.data(), verify_data, verify_data_len);
616   if (out_binder_len != nullptr) {
617     *out_binder_len = verify_data_len;
618   }
619   return true;
620 }
621 
tls13_verify_psk_binder(const SSL_HANDSHAKE * hs,const SSL_SESSION * session,const SSLMessage & msg,CBS * binders)622 bool tls13_verify_psk_binder(const SSL_HANDSHAKE *hs,
623                              const SSL_SESSION *session, const SSLMessage &msg,
624                              CBS *binders) {
625   uint8_t verify_data[EVP_MAX_MD_SIZE];
626   size_t verify_data_len;
627   CBS binder;
628   // The binders are computed over |msg| with |binders| and its u16 length
629   // prefix removed. The caller is assumed to have parsed |msg|, extracted
630   // |binders|, and verified the PSK extension is last.
631   if (!tls13_psk_binder(verify_data, &verify_data_len, session, hs->transcript,
632                         msg.raw, 2 + CBS_len(binders), SSL_is_dtls(hs->ssl)) ||
633       // We only consider the first PSK, so compare against the first binder.
634       !CBS_get_u8_length_prefixed(binders, &binder)) {
635     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
636     return false;
637   }
638 
639   bool binder_ok =
640       CBS_len(&binder) == verify_data_len &&
641       CRYPTO_memcmp(CBS_data(&binder), verify_data, verify_data_len) == 0;
642 #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
643   binder_ok = true;
644 #endif
645   if (!binder_ok) {
646     OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
647     return false;
648   }
649 
650   return true;
651 }
652 
ssl_ech_confirmation_signal_hello_offset(const SSL * ssl)653 size_t ssl_ech_confirmation_signal_hello_offset(const SSL *ssl) {
654   static_assert(ECH_CONFIRMATION_SIGNAL_LEN < SSL3_RANDOM_SIZE,
655                 "the confirmation signal is a suffix of the random");
656   const size_t header_len =
657       SSL_is_dtls(ssl) ? DTLS1_HM_HEADER_LENGTH : SSL3_HM_HEADER_LENGTH;
658   return header_len + 2 /* version */ + SSL3_RANDOM_SIZE -
659          ECH_CONFIRMATION_SIGNAL_LEN;
660 }
661 
ssl_ech_accept_confirmation(const SSL_HANDSHAKE * hs,Span<uint8_t> out,Span<const uint8_t> client_random,const SSLTranscript & transcript,bool is_hrr,Span<const uint8_t> msg,size_t offset)662 bool ssl_ech_accept_confirmation(const SSL_HANDSHAKE *hs, Span<uint8_t> out,
663                                  Span<const uint8_t> client_random,
664                                  const SSLTranscript &transcript, bool is_hrr,
665                                  Span<const uint8_t> msg, size_t offset) {
666   // See draft-ietf-tls-esni-13, sections 7.2 and 7.2.1.
667   static const uint8_t kZeros[EVP_MAX_MD_SIZE] = {0};
668 
669   // We hash |msg|, with bytes from |offset| zeroed.
670   if (msg.size() < offset + ECH_CONFIRMATION_SIGNAL_LEN) {
671     OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
672     return false;
673   }
674 
675   auto before_zeros = msg.subspan(0, offset);
676   auto after_zeros = msg.subspan(offset + ECH_CONFIRMATION_SIGNAL_LEN);
677   uint8_t context[EVP_MAX_MD_SIZE];
678   unsigned context_len;
679   ScopedEVP_MD_CTX ctx;
680   if (!transcript.CopyToHashContext(ctx.get(), transcript.Digest()) ||
681       !EVP_DigestUpdate(ctx.get(), before_zeros.data(), before_zeros.size()) ||
682       !EVP_DigestUpdate(ctx.get(), kZeros, ECH_CONFIRMATION_SIGNAL_LEN) ||
683       !EVP_DigestUpdate(ctx.get(), after_zeros.data(), after_zeros.size()) ||
684       !EVP_DigestFinal_ex(ctx.get(), context, &context_len)) {
685     return false;
686   }
687 
688   uint8_t secret[EVP_MAX_MD_SIZE];
689   size_t secret_len;
690   if (!HKDF_extract(secret, &secret_len, transcript.Digest(),
691                     client_random.data(), client_random.size(), kZeros,
692                     transcript.DigestLen())) {
693     return false;
694   }
695 
696   assert(out.size() == ECH_CONFIRMATION_SIGNAL_LEN);
697   return hkdf_expand_label(
698       out, transcript.Digest(), MakeConstSpan(secret, secret_len),
699       is_hrr ? label_to_span("hrr ech accept confirmation")
700              : label_to_span("ech accept confirmation"),
701       MakeConstSpan(context, context_len), SSL_is_dtls(hs->ssl));
702 }
703 
704 BSSL_NAMESPACE_END
705