• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ngtcp2
3  *
4  * Copyright (c) 2020 ngtcp2 contributors
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif /* HAVE_CONFIG_H */
28 
29 #include <assert.h>
30 #include <string.h>
31 
32 #include <ngtcp2/ngtcp2_crypto.h>
33 #include <ngtcp2/ngtcp2_crypto_boringssl.h>
34 
35 #include <openssl/ssl.h>
36 #include <openssl/evp.h>
37 #include <openssl/hkdf.h>
38 #include <openssl/aes.h>
39 #include <openssl/chacha.h>
40 #include <openssl/rand.h>
41 
42 #include "shared.h"
43 
44 typedef enum ngtcp2_crypto_boringssl_cipher_type {
45   NGTCP2_CRYPTO_BORINGSSL_CIPHER_TYPE_AES_128,
46   NGTCP2_CRYPTO_BORINGSSL_CIPHER_TYPE_AES_256,
47   NGTCP2_CRYPTO_BORINGSSL_CIPHER_TYPE_CHACHA20,
48 } ngtcp2_crypto_boringssl_cipher_type;
49 
50 typedef struct ngtcp2_crypto_boringssl_cipher {
51   ngtcp2_crypto_boringssl_cipher_type type;
52 } ngtcp2_crypto_boringssl_cipher;
53 
54 static ngtcp2_crypto_boringssl_cipher crypto_cipher_aes_128 = {
55     NGTCP2_CRYPTO_BORINGSSL_CIPHER_TYPE_AES_128,
56 };
57 
58 static ngtcp2_crypto_boringssl_cipher crypto_cipher_aes_256 = {
59     NGTCP2_CRYPTO_BORINGSSL_CIPHER_TYPE_AES_256,
60 };
61 
62 static ngtcp2_crypto_boringssl_cipher crypto_cipher_chacha20 = {
63     NGTCP2_CRYPTO_BORINGSSL_CIPHER_TYPE_CHACHA20,
64 };
65 
ngtcp2_crypto_aead_aes_128_gcm(ngtcp2_crypto_aead * aead)66 ngtcp2_crypto_aead *ngtcp2_crypto_aead_aes_128_gcm(ngtcp2_crypto_aead *aead) {
67   return ngtcp2_crypto_aead_init(aead, (void *)EVP_aead_aes_128_gcm());
68 }
69 
ngtcp2_crypto_md_sha256(ngtcp2_crypto_md * md)70 ngtcp2_crypto_md *ngtcp2_crypto_md_sha256(ngtcp2_crypto_md *md) {
71   md->native_handle = (void *)EVP_sha256();
72   return md;
73 }
74 
ngtcp2_crypto_ctx_initial(ngtcp2_crypto_ctx * ctx)75 ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_initial(ngtcp2_crypto_ctx *ctx) {
76   ngtcp2_crypto_aead_init(&ctx->aead, (void *)EVP_aead_aes_128_gcm());
77   ctx->md.native_handle = (void *)EVP_sha256();
78   ctx->hp.native_handle = (void *)&crypto_cipher_aes_128;
79   ctx->max_encryption = 0;
80   ctx->max_decryption_failure = 0;
81   return ctx;
82 }
83 
ngtcp2_crypto_aead_init(ngtcp2_crypto_aead * aead,void * aead_native_handle)84 ngtcp2_crypto_aead *ngtcp2_crypto_aead_init(ngtcp2_crypto_aead *aead,
85                                             void *aead_native_handle) {
86   aead->native_handle = aead_native_handle;
87   aead->max_overhead = EVP_AEAD_max_overhead(aead->native_handle);
88   return aead;
89 }
90 
ngtcp2_crypto_aead_retry(ngtcp2_crypto_aead * aead)91 ngtcp2_crypto_aead *ngtcp2_crypto_aead_retry(ngtcp2_crypto_aead *aead) {
92   return ngtcp2_crypto_aead_init(aead, (void *)EVP_aead_aes_128_gcm());
93 }
94 
crypto_ssl_get_aead(SSL * ssl)95 static const EVP_AEAD *crypto_ssl_get_aead(SSL *ssl) {
96   switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl))) {
97   case TLS1_CK_AES_128_GCM_SHA256:
98     return EVP_aead_aes_128_gcm();
99   case TLS1_CK_AES_256_GCM_SHA384:
100     return EVP_aead_aes_256_gcm();
101   case TLS1_CK_CHACHA20_POLY1305_SHA256:
102     return EVP_aead_chacha20_poly1305();
103   default:
104     return NULL;
105   }
106 }
107 
crypto_ssl_get_aead_max_encryption(SSL * ssl)108 static uint64_t crypto_ssl_get_aead_max_encryption(SSL *ssl) {
109   switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl))) {
110   case TLS1_CK_AES_128_GCM_SHA256:
111   case TLS1_CK_AES_256_GCM_SHA384:
112     return NGTCP2_CRYPTO_MAX_ENCRYPTION_AES_GCM;
113   case TLS1_CK_CHACHA20_POLY1305_SHA256:
114     return NGTCP2_CRYPTO_MAX_ENCRYPTION_CHACHA20_POLY1305;
115   default:
116     return 0;
117   }
118 }
119 
crypto_ssl_get_aead_max_decryption_failure(SSL * ssl)120 static uint64_t crypto_ssl_get_aead_max_decryption_failure(SSL *ssl) {
121   switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl))) {
122   case TLS1_CK_AES_128_GCM_SHA256:
123   case TLS1_CK_AES_256_GCM_SHA384:
124     return NGTCP2_CRYPTO_MAX_DECRYPTION_FAILURE_AES_GCM;
125   case TLS1_CK_CHACHA20_POLY1305_SHA256:
126     return NGTCP2_CRYPTO_MAX_DECRYPTION_FAILURE_CHACHA20_POLY1305;
127   default:
128     return 0;
129   }
130 }
131 
crypto_ssl_get_hp(SSL * ssl)132 static const ngtcp2_crypto_boringssl_cipher *crypto_ssl_get_hp(SSL *ssl) {
133   switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl))) {
134   case TLS1_CK_AES_128_GCM_SHA256:
135     return &crypto_cipher_aes_128;
136   case TLS1_CK_AES_256_GCM_SHA384:
137     return &crypto_cipher_aes_256;
138   case TLS1_CK_CHACHA20_POLY1305_SHA256:
139     return &crypto_cipher_chacha20;
140   default:
141     return NULL;
142   }
143 }
144 
crypto_ssl_get_md(SSL * ssl)145 static const EVP_MD *crypto_ssl_get_md(SSL *ssl) {
146   switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl))) {
147   case TLS1_CK_AES_128_GCM_SHA256:
148   case TLS1_CK_CHACHA20_POLY1305_SHA256:
149     return EVP_sha256();
150   case TLS1_CK_AES_256_GCM_SHA384:
151     return EVP_sha384();
152   default:
153     return NULL;
154   }
155 }
156 
ngtcp2_crypto_ctx_tls(ngtcp2_crypto_ctx * ctx,void * tls_native_handle)157 ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_tls(ngtcp2_crypto_ctx *ctx,
158                                          void *tls_native_handle) {
159   SSL *ssl = tls_native_handle;
160   ngtcp2_crypto_aead_init(&ctx->aead, (void *)crypto_ssl_get_aead(ssl));
161   ctx->md.native_handle = (void *)crypto_ssl_get_md(ssl);
162   ctx->hp.native_handle = (void *)crypto_ssl_get_hp(ssl);
163   ctx->max_encryption = crypto_ssl_get_aead_max_encryption(ssl);
164   ctx->max_decryption_failure = crypto_ssl_get_aead_max_decryption_failure(ssl);
165   return ctx;
166 }
167 
ngtcp2_crypto_ctx_tls_early(ngtcp2_crypto_ctx * ctx,void * tls_native_handle)168 ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_tls_early(ngtcp2_crypto_ctx *ctx,
169                                                void *tls_native_handle) {
170   return ngtcp2_crypto_ctx_tls(ctx, tls_native_handle);
171 }
172 
crypto_md_hashlen(const EVP_MD * md)173 static size_t crypto_md_hashlen(const EVP_MD *md) {
174   return (size_t)EVP_MD_size(md);
175 }
176 
ngtcp2_crypto_md_hashlen(const ngtcp2_crypto_md * md)177 size_t ngtcp2_crypto_md_hashlen(const ngtcp2_crypto_md *md) {
178   return crypto_md_hashlen(md->native_handle);
179 }
180 
crypto_aead_keylen(const EVP_AEAD * aead)181 static size_t crypto_aead_keylen(const EVP_AEAD *aead) {
182   return (size_t)EVP_AEAD_key_length(aead);
183 }
184 
ngtcp2_crypto_aead_keylen(const ngtcp2_crypto_aead * aead)185 size_t ngtcp2_crypto_aead_keylen(const ngtcp2_crypto_aead *aead) {
186   return crypto_aead_keylen(aead->native_handle);
187 }
188 
crypto_aead_noncelen(const EVP_AEAD * aead)189 static size_t crypto_aead_noncelen(const EVP_AEAD *aead) {
190   return (size_t)EVP_AEAD_nonce_length(aead);
191 }
192 
ngtcp2_crypto_aead_noncelen(const ngtcp2_crypto_aead * aead)193 size_t ngtcp2_crypto_aead_noncelen(const ngtcp2_crypto_aead *aead) {
194   return crypto_aead_noncelen(aead->native_handle);
195 }
196 
ngtcp2_crypto_aead_ctx_encrypt_init(ngtcp2_crypto_aead_ctx * aead_ctx,const ngtcp2_crypto_aead * aead,const uint8_t * key,size_t noncelen)197 int ngtcp2_crypto_aead_ctx_encrypt_init(ngtcp2_crypto_aead_ctx *aead_ctx,
198                                         const ngtcp2_crypto_aead *aead,
199                                         const uint8_t *key, size_t noncelen) {
200   const EVP_AEAD *cipher = aead->native_handle;
201   size_t keylen = crypto_aead_keylen(cipher);
202   EVP_AEAD_CTX *actx;
203 
204   (void)noncelen;
205 
206   actx = EVP_AEAD_CTX_new(cipher, key, keylen, EVP_AEAD_DEFAULT_TAG_LENGTH);
207   if (actx == NULL) {
208     return -1;
209   }
210 
211   aead_ctx->native_handle = actx;
212 
213   return 0;
214 }
215 
ngtcp2_crypto_aead_ctx_decrypt_init(ngtcp2_crypto_aead_ctx * aead_ctx,const ngtcp2_crypto_aead * aead,const uint8_t * key,size_t noncelen)216 int ngtcp2_crypto_aead_ctx_decrypt_init(ngtcp2_crypto_aead_ctx *aead_ctx,
217                                         const ngtcp2_crypto_aead *aead,
218                                         const uint8_t *key, size_t noncelen) {
219   return ngtcp2_crypto_aead_ctx_encrypt_init(aead_ctx, aead, key, noncelen);
220 }
221 
ngtcp2_crypto_aead_ctx_free(ngtcp2_crypto_aead_ctx * aead_ctx)222 void ngtcp2_crypto_aead_ctx_free(ngtcp2_crypto_aead_ctx *aead_ctx) {
223   if (aead_ctx->native_handle) {
224     EVP_AEAD_CTX_free(aead_ctx->native_handle);
225   }
226 }
227 
228 typedef struct ngtcp2_crypto_boringssl_cipher_ctx {
229   ngtcp2_crypto_boringssl_cipher_type type;
230   union {
231     /* aes_key is an encryption key when type is either
232        NGTCP2_CRYPTO_BORINGSSL_CIPHER_TYPE_AES_128 or
233        NGTCP2_CRYPTO_BORINGSSL_CIPHER_TYPE_AES_256. */
234     AES_KEY aes_key;
235     /* key contains an encryption key when type ==
236        NGTCP2_CRYPTO_BORINGSSL_CIPHER_TYPE_CHACHA20. */
237     uint8_t key[32];
238   };
239 } ngtcp2_crypto_boringssl_cipher_ctx;
240 
ngtcp2_crypto_cipher_ctx_encrypt_init(ngtcp2_crypto_cipher_ctx * cipher_ctx,const ngtcp2_crypto_cipher * cipher,const uint8_t * key)241 int ngtcp2_crypto_cipher_ctx_encrypt_init(ngtcp2_crypto_cipher_ctx *cipher_ctx,
242                                           const ngtcp2_crypto_cipher *cipher,
243                                           const uint8_t *key) {
244   ngtcp2_crypto_boringssl_cipher *hp_cipher = cipher->native_handle;
245   ngtcp2_crypto_boringssl_cipher_ctx *ctx;
246   int rv;
247   (void)rv;
248 
249   ctx = malloc(sizeof(*ctx));
250   if (ctx == NULL) {
251     return -1;
252   }
253 
254   ctx->type = hp_cipher->type;
255   cipher_ctx->native_handle = ctx;
256 
257   switch (hp_cipher->type) {
258   case NGTCP2_CRYPTO_BORINGSSL_CIPHER_TYPE_AES_128:
259     rv = AES_set_encrypt_key(key, 128, &ctx->aes_key);
260     assert(0 == rv);
261     return 0;
262   case NGTCP2_CRYPTO_BORINGSSL_CIPHER_TYPE_AES_256:
263     rv = AES_set_encrypt_key(key, 256, &ctx->aes_key);
264     assert(0 == rv);
265     return 0;
266   case NGTCP2_CRYPTO_BORINGSSL_CIPHER_TYPE_CHACHA20:
267     memcpy(ctx->key, key, sizeof(ctx->key));
268     return 0;
269   default:
270     assert(0);
271     abort();
272   };
273 }
274 
ngtcp2_crypto_cipher_ctx_free(ngtcp2_crypto_cipher_ctx * cipher_ctx)275 void ngtcp2_crypto_cipher_ctx_free(ngtcp2_crypto_cipher_ctx *cipher_ctx) {
276   if (!cipher_ctx->native_handle) {
277     return;
278   }
279 
280   free(cipher_ctx->native_handle);
281 }
282 
ngtcp2_crypto_hkdf_extract(uint8_t * dest,const ngtcp2_crypto_md * md,const uint8_t * secret,size_t secretlen,const uint8_t * salt,size_t saltlen)283 int ngtcp2_crypto_hkdf_extract(uint8_t *dest, const ngtcp2_crypto_md *md,
284                                const uint8_t *secret, size_t secretlen,
285                                const uint8_t *salt, size_t saltlen) {
286   const EVP_MD *prf = md->native_handle;
287   size_t destlen = (size_t)EVP_MD_size(prf);
288 
289   if (HKDF_extract(dest, &destlen, prf, secret, secretlen, salt, saltlen) !=
290       1) {
291     return -1;
292   }
293 
294   return 0;
295 }
296 
ngtcp2_crypto_hkdf_expand(uint8_t * dest,size_t destlen,const ngtcp2_crypto_md * md,const uint8_t * secret,size_t secretlen,const uint8_t * info,size_t infolen)297 int ngtcp2_crypto_hkdf_expand(uint8_t *dest, size_t destlen,
298                               const ngtcp2_crypto_md *md, const uint8_t *secret,
299                               size_t secretlen, const uint8_t *info,
300                               size_t infolen) {
301   const EVP_MD *prf = md->native_handle;
302 
303   if (HKDF_expand(dest, destlen, prf, secret, secretlen, info, infolen) != 1) {
304     return -1;
305   }
306 
307   return 0;
308 }
309 
ngtcp2_crypto_hkdf(uint8_t * dest,size_t destlen,const ngtcp2_crypto_md * md,const uint8_t * secret,size_t secretlen,const uint8_t * salt,size_t saltlen,const uint8_t * info,size_t infolen)310 int ngtcp2_crypto_hkdf(uint8_t *dest, size_t destlen,
311                        const ngtcp2_crypto_md *md, const uint8_t *secret,
312                        size_t secretlen, const uint8_t *salt, size_t saltlen,
313                        const uint8_t *info, size_t infolen) {
314   const EVP_MD *prf = md->native_handle;
315 
316   if (HKDF(dest, destlen, prf, secret, secretlen, salt, saltlen, info,
317            infolen) != 1) {
318     return -1;
319   }
320 
321   return 0;
322 }
323 
ngtcp2_crypto_encrypt(uint8_t * dest,const ngtcp2_crypto_aead * aead,const ngtcp2_crypto_aead_ctx * aead_ctx,const uint8_t * plaintext,size_t plaintextlen,const uint8_t * nonce,size_t noncelen,const uint8_t * aad,size_t aadlen)324 int ngtcp2_crypto_encrypt(uint8_t *dest, const ngtcp2_crypto_aead *aead,
325                           const ngtcp2_crypto_aead_ctx *aead_ctx,
326                           const uint8_t *plaintext, size_t plaintextlen,
327                           const uint8_t *nonce, size_t noncelen,
328                           const uint8_t *aad, size_t aadlen) {
329   const EVP_AEAD *cipher = aead->native_handle;
330   EVP_AEAD_CTX *actx = aead_ctx->native_handle;
331   size_t max_outlen = plaintextlen + EVP_AEAD_max_overhead(cipher);
332   size_t outlen;
333 
334   if (EVP_AEAD_CTX_seal(actx, dest, &outlen, max_outlen, nonce, noncelen,
335                         plaintext, plaintextlen, aad, aadlen) != 1) {
336     return -1;
337   }
338 
339   return 0;
340 }
341 
ngtcp2_crypto_decrypt(uint8_t * dest,const ngtcp2_crypto_aead * aead,const ngtcp2_crypto_aead_ctx * aead_ctx,const uint8_t * ciphertext,size_t ciphertextlen,const uint8_t * nonce,size_t noncelen,const uint8_t * aad,size_t aadlen)342 int ngtcp2_crypto_decrypt(uint8_t *dest, const ngtcp2_crypto_aead *aead,
343                           const ngtcp2_crypto_aead_ctx *aead_ctx,
344                           const uint8_t *ciphertext, size_t ciphertextlen,
345                           const uint8_t *nonce, size_t noncelen,
346                           const uint8_t *aad, size_t aadlen) {
347   const EVP_AEAD *cipher = aead->native_handle;
348   EVP_AEAD_CTX *actx = aead_ctx->native_handle;
349   size_t max_overhead = EVP_AEAD_max_overhead(cipher);
350   size_t max_outlen;
351   size_t outlen;
352 
353   if (ciphertextlen < max_overhead) {
354     return -1;
355   }
356 
357   max_outlen = ciphertextlen - max_overhead;
358 
359   if (EVP_AEAD_CTX_open(actx, dest, &outlen, max_outlen, nonce, noncelen,
360                         ciphertext, ciphertextlen, aad, aadlen) != 1) {
361     return -1;
362   }
363 
364   return 0;
365 }
366 
ngtcp2_crypto_hp_mask(uint8_t * dest,const ngtcp2_crypto_cipher * hp,const ngtcp2_crypto_cipher_ctx * hp_ctx,const uint8_t * sample)367 int ngtcp2_crypto_hp_mask(uint8_t *dest, const ngtcp2_crypto_cipher *hp,
368                           const ngtcp2_crypto_cipher_ctx *hp_ctx,
369                           const uint8_t *sample) {
370   static const uint8_t PLAINTEXT[] = "\x00\x00\x00\x00\x00";
371   ngtcp2_crypto_boringssl_cipher_ctx *ctx = hp_ctx->native_handle;
372   uint32_t counter;
373 
374   (void)hp;
375 
376   switch (ctx->type) {
377   case NGTCP2_CRYPTO_BORINGSSL_CIPHER_TYPE_AES_128:
378   case NGTCP2_CRYPTO_BORINGSSL_CIPHER_TYPE_AES_256:
379     AES_ecb_encrypt(sample, dest, &ctx->aes_key, 1);
380     return 0;
381   case NGTCP2_CRYPTO_BORINGSSL_CIPHER_TYPE_CHACHA20:
382 #if defined(WORDS_BIGENDIAN)
383     counter = (uint32_t)sample[0] + (uint32_t)(sample[1] << 8) +
384               (uint32_t)(sample[2] << 16) + (uint32_t)(sample[3] << 24);
385 #else  /* !WORDS_BIGENDIAN */
386     memcpy(&counter, sample, sizeof(counter));
387 #endif /* !WORDS_BIGENDIAN */
388     CRYPTO_chacha_20(dest, PLAINTEXT, sizeof(PLAINTEXT) - 1, ctx->key,
389                      sample + sizeof(counter), counter);
390     return 0;
391   default:
392     assert(0);
393     abort();
394   }
395 }
396 
ngtcp2_crypto_read_write_crypto_data(ngtcp2_conn * conn,ngtcp2_crypto_level crypto_level,const uint8_t * data,size_t datalen)397 int ngtcp2_crypto_read_write_crypto_data(ngtcp2_conn *conn,
398                                          ngtcp2_crypto_level crypto_level,
399                                          const uint8_t *data, size_t datalen) {
400   SSL *ssl = ngtcp2_conn_get_tls_native_handle(conn);
401   int rv;
402   int err;
403 
404   if (SSL_provide_quic_data(
405           ssl, ngtcp2_crypto_boringssl_from_ngtcp2_crypto_level(crypto_level),
406           data, datalen) != 1) {
407     return -1;
408   }
409 
410   if (!ngtcp2_conn_get_handshake_completed(conn)) {
411   retry:
412     rv = SSL_do_handshake(ssl);
413     if (rv <= 0) {
414       err = SSL_get_error(ssl, rv);
415       switch (err) {
416       case SSL_ERROR_WANT_READ:
417       case SSL_ERROR_WANT_WRITE:
418         return 0;
419       case SSL_ERROR_SSL:
420         return -1;
421       case SSL_ERROR_EARLY_DATA_REJECTED:
422         assert(!ngtcp2_conn_is_server(conn));
423 
424         SSL_reset_early_data_reject(ssl);
425 
426         ngtcp2_conn_early_data_rejected(conn);
427 
428         goto retry;
429       default:
430         return -1;
431       }
432     }
433 
434     if (SSL_in_early_data(ssl)) {
435       return 0;
436     }
437 
438     ngtcp2_conn_handshake_completed(conn);
439   }
440 
441   rv = SSL_process_quic_post_handshake(ssl);
442   if (rv != 1) {
443     err = SSL_get_error(ssl, rv);
444     switch (err) {
445     case SSL_ERROR_WANT_READ:
446     case SSL_ERROR_WANT_WRITE:
447       return 0;
448     case SSL_ERROR_SSL:
449     case SSL_ERROR_ZERO_RETURN:
450       return -1;
451     default:
452       return -1;
453     }
454   }
455 
456   return 0;
457 }
458 
ngtcp2_crypto_set_remote_transport_params(ngtcp2_conn * conn,void * tls)459 int ngtcp2_crypto_set_remote_transport_params(ngtcp2_conn *conn, void *tls) {
460   SSL *ssl = tls;
461   const uint8_t *tp;
462   size_t tplen;
463   int rv;
464 
465   SSL_get_peer_quic_transport_params(ssl, &tp, &tplen);
466 
467   rv = ngtcp2_conn_decode_remote_transport_params(conn, tp, tplen);
468   if (rv != 0) {
469     ngtcp2_conn_set_tls_error(conn, rv);
470     return -1;
471   }
472 
473   return 0;
474 }
475 
ngtcp2_crypto_set_local_transport_params(void * tls,const uint8_t * buf,size_t len)476 int ngtcp2_crypto_set_local_transport_params(void *tls, const uint8_t *buf,
477                                              size_t len) {
478   if (SSL_set_quic_transport_params(tls, buf, len) != 1) {
479     return -1;
480   }
481 
482   return 0;
483 }
484 
ngtcp2_crypto_boringssl_from_ssl_encryption_level(enum ssl_encryption_level_t ssl_level)485 ngtcp2_crypto_level ngtcp2_crypto_boringssl_from_ssl_encryption_level(
486     enum ssl_encryption_level_t ssl_level) {
487   switch (ssl_level) {
488   case ssl_encryption_initial:
489     return NGTCP2_CRYPTO_LEVEL_INITIAL;
490   case ssl_encryption_early_data:
491     return NGTCP2_CRYPTO_LEVEL_EARLY;
492   case ssl_encryption_handshake:
493     return NGTCP2_CRYPTO_LEVEL_HANDSHAKE;
494   case ssl_encryption_application:
495     return NGTCP2_CRYPTO_LEVEL_APPLICATION;
496   default:
497     assert(0);
498     abort();
499   }
500 }
501 
ngtcp2_crypto_boringssl_from_ngtcp2_crypto_level(ngtcp2_crypto_level crypto_level)502 enum ssl_encryption_level_t ngtcp2_crypto_boringssl_from_ngtcp2_crypto_level(
503     ngtcp2_crypto_level crypto_level) {
504   switch (crypto_level) {
505   case NGTCP2_CRYPTO_LEVEL_INITIAL:
506     return ssl_encryption_initial;
507   case NGTCP2_CRYPTO_LEVEL_HANDSHAKE:
508     return ssl_encryption_handshake;
509   case NGTCP2_CRYPTO_LEVEL_APPLICATION:
510     return ssl_encryption_application;
511   case NGTCP2_CRYPTO_LEVEL_EARLY:
512     return ssl_encryption_early_data;
513   default:
514     assert(0);
515     abort();
516   }
517 }
518 
ngtcp2_crypto_get_path_challenge_data_cb(ngtcp2_conn * conn,uint8_t * data,void * user_data)519 int ngtcp2_crypto_get_path_challenge_data_cb(ngtcp2_conn *conn, uint8_t *data,
520                                              void *user_data) {
521   (void)conn;
522   (void)user_data;
523 
524   if (RAND_bytes(data, NGTCP2_PATH_CHALLENGE_DATALEN) != 1) {
525     return NGTCP2_ERR_CALLBACK_FAILURE;
526   }
527 
528   return 0;
529 }
530 
ngtcp2_crypto_random(uint8_t * data,size_t datalen)531 int ngtcp2_crypto_random(uint8_t *data, size_t datalen) {
532   if (RAND_bytes(data, datalen) != 1) {
533     return -1;
534   }
535 
536   return 0;
537 }
538 
set_read_secret(SSL * ssl,enum ssl_encryption_level_t bssl_level,const SSL_CIPHER * cipher,const uint8_t * secret,size_t secretlen)539 static int set_read_secret(SSL *ssl, enum ssl_encryption_level_t bssl_level,
540                            const SSL_CIPHER *cipher, const uint8_t *secret,
541                            size_t secretlen) {
542   ngtcp2_crypto_conn_ref *conn_ref = SSL_get_app_data(ssl);
543   ngtcp2_conn *conn = conn_ref->get_conn(conn_ref);
544   ngtcp2_crypto_level level =
545       ngtcp2_crypto_boringssl_from_ssl_encryption_level(bssl_level);
546   (void)cipher;
547 
548   if (ngtcp2_crypto_derive_and_install_rx_key(conn, NULL, NULL, NULL, level,
549                                               secret, secretlen) != 0) {
550     return 0;
551   }
552 
553   return 1;
554 }
555 
set_write_secret(SSL * ssl,enum ssl_encryption_level_t bssl_level,const SSL_CIPHER * cipher,const uint8_t * secret,size_t secretlen)556 static int set_write_secret(SSL *ssl, enum ssl_encryption_level_t bssl_level,
557                             const SSL_CIPHER *cipher, const uint8_t *secret,
558                             size_t secretlen) {
559   ngtcp2_crypto_conn_ref *conn_ref = SSL_get_app_data(ssl);
560   ngtcp2_conn *conn = conn_ref->get_conn(conn_ref);
561   ngtcp2_crypto_level level =
562       ngtcp2_crypto_boringssl_from_ssl_encryption_level(bssl_level);
563   (void)cipher;
564 
565   if (ngtcp2_crypto_derive_and_install_tx_key(conn, NULL, NULL, NULL, level,
566                                               secret, secretlen) != 0) {
567     return 0;
568   }
569 
570   return 1;
571 }
572 
add_handshake_data(SSL * ssl,enum ssl_encryption_level_t bssl_level,const uint8_t * data,size_t datalen)573 static int add_handshake_data(SSL *ssl, enum ssl_encryption_level_t bssl_level,
574                               const uint8_t *data, size_t datalen) {
575   ngtcp2_crypto_conn_ref *conn_ref = SSL_get_app_data(ssl);
576   ngtcp2_conn *conn = conn_ref->get_conn(conn_ref);
577   ngtcp2_crypto_level level =
578       ngtcp2_crypto_boringssl_from_ssl_encryption_level(bssl_level);
579   int rv;
580 
581   rv = ngtcp2_conn_submit_crypto_data(conn, level, data, datalen);
582   if (rv != 0) {
583     ngtcp2_conn_set_tls_error(conn, rv);
584     return 0;
585   }
586 
587   return 1;
588 }
589 
flush_flight(SSL * ssl)590 static int flush_flight(SSL *ssl) {
591   (void)ssl;
592   return 1;
593 }
594 
send_alert(SSL * ssl,enum ssl_encryption_level_t bssl_level,uint8_t alert)595 static int send_alert(SSL *ssl, enum ssl_encryption_level_t bssl_level,
596                       uint8_t alert) {
597   ngtcp2_crypto_conn_ref *conn_ref = SSL_get_app_data(ssl);
598   ngtcp2_conn *conn = conn_ref->get_conn(conn_ref);
599   (void)bssl_level;
600 
601   ngtcp2_conn_set_tls_alert(conn, alert);
602 
603   return 1;
604 }
605 
606 static SSL_QUIC_METHOD quic_method = {
607     set_read_secret, set_write_secret, add_handshake_data,
608     flush_flight,    send_alert,
609 };
610 
crypto_boringssl_configure_context(SSL_CTX * ssl_ctx)611 static void crypto_boringssl_configure_context(SSL_CTX *ssl_ctx) {
612   SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
613   SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
614   SSL_CTX_set_quic_method(ssl_ctx, &quic_method);
615 }
616 
ngtcp2_crypto_boringssl_configure_server_context(SSL_CTX * ssl_ctx)617 int ngtcp2_crypto_boringssl_configure_server_context(SSL_CTX *ssl_ctx) {
618   crypto_boringssl_configure_context(ssl_ctx);
619 
620   return 0;
621 }
622 
ngtcp2_crypto_boringssl_configure_client_context(SSL_CTX * ssl_ctx)623 int ngtcp2_crypto_boringssl_configure_client_context(SSL_CTX *ssl_ctx) {
624   crypto_boringssl_configure_context(ssl_ctx);
625 
626   return 0;
627 }
628