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