1 /*
2 * ngtcp2
3 *
4 * Copyright (c) 2022 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
31 #include <ngtcp2/ngtcp2_crypto.h>
32 #include <ngtcp2/ngtcp2_crypto_wolfssl.h>
33
34 #include <wolfssl/ssl.h>
35 #include <wolfssl/quic.h>
36
37 #include "shared.h"
38
39 #define PRINTF_DEBUG 0
40 #if PRINTF_DEBUG
41 # define DEBUG_MSG(...) fprintf(stderr, __VA_ARGS__)
42 #else
43 # define DEBUG_MSG(...) (void)0
44 #endif
45
ngtcp2_crypto_aead_aes_128_gcm(ngtcp2_crypto_aead * aead)46 ngtcp2_crypto_aead *ngtcp2_crypto_aead_aes_128_gcm(ngtcp2_crypto_aead *aead) {
47 return ngtcp2_crypto_aead_init(aead, (void *)wolfSSL_EVP_aes_128_gcm());
48 }
49
ngtcp2_crypto_md_sha256(ngtcp2_crypto_md * md)50 ngtcp2_crypto_md *ngtcp2_crypto_md_sha256(ngtcp2_crypto_md *md) {
51 md->native_handle = (void *)wolfSSL_EVP_sha256();
52 return md;
53 }
54
ngtcp2_crypto_ctx_initial(ngtcp2_crypto_ctx * ctx)55 ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_initial(ngtcp2_crypto_ctx *ctx) {
56 ngtcp2_crypto_aead_init(&ctx->aead, (void *)wolfSSL_EVP_aes_128_gcm());
57 ctx->md.native_handle = (void *)wolfSSL_EVP_sha256();
58 ctx->hp.native_handle = (void *)wolfSSL_EVP_aes_128_ctr();
59 ctx->max_encryption = 0;
60 ctx->max_decryption_failure = 0;
61 return ctx;
62 }
63
ngtcp2_crypto_aead_init(ngtcp2_crypto_aead * aead,void * aead_native_handle)64 ngtcp2_crypto_aead *ngtcp2_crypto_aead_init(ngtcp2_crypto_aead *aead,
65 void *aead_native_handle) {
66 aead->native_handle = aead_native_handle;
67 aead->max_overhead = wolfSSL_quic_get_aead_tag_len(
68 (const WOLFSSL_EVP_CIPHER *)(aead_native_handle));
69 return aead;
70 }
71
ngtcp2_crypto_aead_retry(ngtcp2_crypto_aead * aead)72 ngtcp2_crypto_aead *ngtcp2_crypto_aead_retry(ngtcp2_crypto_aead *aead) {
73 return ngtcp2_crypto_aead_init(aead, (void *)wolfSSL_EVP_aes_128_gcm());
74 }
75
crypto_wolfssl_get_aead_max_encryption(WOLFSSL * ssl)76 static uint64_t crypto_wolfssl_get_aead_max_encryption(WOLFSSL *ssl) {
77 const WOLFSSL_EVP_CIPHER *aead = wolfSSL_quic_get_aead(ssl);
78
79 if (wolfSSL_quic_aead_is_gcm(aead)) {
80 return NGTCP2_CRYPTO_MAX_ENCRYPTION_AES_GCM;
81 }
82 if (wolfSSL_quic_aead_is_chacha20(aead)) {
83 return NGTCP2_CRYPTO_MAX_ENCRYPTION_CHACHA20_POLY1305;
84 }
85 if (wolfSSL_quic_aead_is_ccm(aead)) {
86 return NGTCP2_CRYPTO_MAX_ENCRYPTION_AES_CCM;
87 }
88 return 0;
89 }
90
crypto_wolfssl_get_aead_max_decryption_failure(WOLFSSL * ssl)91 static uint64_t crypto_wolfssl_get_aead_max_decryption_failure(WOLFSSL *ssl) {
92 const WOLFSSL_EVP_CIPHER *aead = wolfSSL_quic_get_aead(ssl);
93
94 if (wolfSSL_quic_aead_is_gcm(aead)) {
95 return NGTCP2_CRYPTO_MAX_DECRYPTION_FAILURE_AES_GCM;
96 }
97 if (wolfSSL_quic_aead_is_chacha20(aead)) {
98 return NGTCP2_CRYPTO_MAX_DECRYPTION_FAILURE_CHACHA20_POLY1305;
99 }
100 if (wolfSSL_quic_aead_is_ccm(aead)) {
101 return NGTCP2_CRYPTO_MAX_DECRYPTION_FAILURE_AES_CCM;
102 }
103 return 0;
104 }
105
ngtcp2_crypto_ctx_tls(ngtcp2_crypto_ctx * ctx,void * tls_native_handle)106 ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_tls(ngtcp2_crypto_ctx *ctx,
107 void *tls_native_handle) {
108 WOLFSSL *ssl = tls_native_handle;
109
110 ngtcp2_crypto_aead_init(&ctx->aead, (void *)wolfSSL_quic_get_aead(ssl));
111 ctx->md.native_handle = (void *)wolfSSL_quic_get_md(ssl);
112 ctx->hp.native_handle = (void *)wolfSSL_quic_get_hp(ssl);
113 ctx->max_encryption = crypto_wolfssl_get_aead_max_encryption(ssl);
114 ctx->max_decryption_failure =
115 crypto_wolfssl_get_aead_max_decryption_failure(ssl);
116 return ctx;
117 }
118
ngtcp2_crypto_ctx_tls_early(ngtcp2_crypto_ctx * ctx,void * tls_native_handle)119 ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_tls_early(ngtcp2_crypto_ctx *ctx,
120 void *tls_native_handle) {
121 return ngtcp2_crypto_ctx_tls(ctx, tls_native_handle);
122 }
123
crypto_md_hashlen(const WOLFSSL_EVP_MD * md)124 static size_t crypto_md_hashlen(const WOLFSSL_EVP_MD *md) {
125 return (size_t)wolfSSL_EVP_MD_size(md);
126 }
127
ngtcp2_crypto_md_hashlen(const ngtcp2_crypto_md * md)128 size_t ngtcp2_crypto_md_hashlen(const ngtcp2_crypto_md *md) {
129 return crypto_md_hashlen(md->native_handle);
130 }
131
crypto_aead_keylen(const WOLFSSL_EVP_CIPHER * aead)132 static size_t crypto_aead_keylen(const WOLFSSL_EVP_CIPHER *aead) {
133 return (size_t)wolfSSL_EVP_Cipher_key_length(aead);
134 }
135
ngtcp2_crypto_aead_keylen(const ngtcp2_crypto_aead * aead)136 size_t ngtcp2_crypto_aead_keylen(const ngtcp2_crypto_aead *aead) {
137 return crypto_aead_keylen(aead->native_handle);
138 }
139
crypto_aead_noncelen(const WOLFSSL_EVP_CIPHER * aead)140 static size_t crypto_aead_noncelen(const WOLFSSL_EVP_CIPHER *aead) {
141 return (size_t)wolfSSL_EVP_CIPHER_iv_length(aead);
142 }
143
ngtcp2_crypto_aead_noncelen(const ngtcp2_crypto_aead * aead)144 size_t ngtcp2_crypto_aead_noncelen(const ngtcp2_crypto_aead *aead) {
145 return crypto_aead_noncelen(aead->native_handle);
146 }
147
ngtcp2_crypto_aead_ctx_encrypt_init(ngtcp2_crypto_aead_ctx * aead_ctx,const ngtcp2_crypto_aead * aead,const uint8_t * key,size_t noncelen)148 int ngtcp2_crypto_aead_ctx_encrypt_init(ngtcp2_crypto_aead_ctx *aead_ctx,
149 const ngtcp2_crypto_aead *aead,
150 const uint8_t *key, size_t noncelen) {
151 const WOLFSSL_EVP_CIPHER *cipher = aead->native_handle;
152 WOLFSSL_EVP_CIPHER_CTX *actx;
153 static const uint8_t iv[AES_BLOCK_SIZE] = {0};
154
155 (void)noncelen;
156 actx = wolfSSL_quic_crypt_new(cipher, key, iv, /* encrypt */ 1);
157 if (actx == NULL) {
158 return -1;
159 }
160
161 aead_ctx->native_handle = actx;
162 return 0;
163 }
164
ngtcp2_crypto_aead_ctx_decrypt_init(ngtcp2_crypto_aead_ctx * aead_ctx,const ngtcp2_crypto_aead * aead,const uint8_t * key,size_t noncelen)165 int ngtcp2_crypto_aead_ctx_decrypt_init(ngtcp2_crypto_aead_ctx *aead_ctx,
166 const ngtcp2_crypto_aead *aead,
167 const uint8_t *key, size_t noncelen) {
168 const WOLFSSL_EVP_CIPHER *cipher = aead->native_handle;
169 WOLFSSL_EVP_CIPHER_CTX *actx;
170 static const uint8_t iv[AES_BLOCK_SIZE] = {0};
171
172 (void)noncelen;
173 actx = wolfSSL_quic_crypt_new(cipher, key, iv, /* encrypt */ 0);
174 if (actx == NULL) {
175 return -1;
176 }
177
178 aead_ctx->native_handle = actx;
179 return 0;
180 }
181
ngtcp2_crypto_aead_ctx_free(ngtcp2_crypto_aead_ctx * aead_ctx)182 void ngtcp2_crypto_aead_ctx_free(ngtcp2_crypto_aead_ctx *aead_ctx) {
183 if (aead_ctx->native_handle) {
184 wolfSSL_EVP_CIPHER_CTX_free(aead_ctx->native_handle);
185 }
186 }
187
ngtcp2_crypto_cipher_ctx_encrypt_init(ngtcp2_crypto_cipher_ctx * cipher_ctx,const ngtcp2_crypto_cipher * cipher,const uint8_t * key)188 int ngtcp2_crypto_cipher_ctx_encrypt_init(ngtcp2_crypto_cipher_ctx *cipher_ctx,
189 const ngtcp2_crypto_cipher *cipher,
190 const uint8_t *key) {
191 WOLFSSL_EVP_CIPHER_CTX *actx;
192
193 actx =
194 wolfSSL_quic_crypt_new(cipher->native_handle, key, NULL, /* encrypt */ 1);
195 if (actx == NULL) {
196 return -1;
197 }
198
199 cipher_ctx->native_handle = actx;
200 return 0;
201 }
202
ngtcp2_crypto_cipher_ctx_free(ngtcp2_crypto_cipher_ctx * cipher_ctx)203 void ngtcp2_crypto_cipher_ctx_free(ngtcp2_crypto_cipher_ctx *cipher_ctx) {
204 if (cipher_ctx->native_handle) {
205 wolfSSL_EVP_CIPHER_CTX_free(cipher_ctx->native_handle);
206 }
207 }
208
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)209 int ngtcp2_crypto_hkdf_extract(uint8_t *dest, const ngtcp2_crypto_md *md,
210 const uint8_t *secret, size_t secretlen,
211 const uint8_t *salt, size_t saltlen) {
212 if (wolfSSL_quic_hkdf_extract(dest, md->native_handle, secret, secretlen,
213 salt, saltlen) != WOLFSSL_SUCCESS) {
214 return -1;
215 }
216 return 0;
217 }
218
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)219 int ngtcp2_crypto_hkdf_expand(uint8_t *dest, size_t destlen,
220 const ngtcp2_crypto_md *md, const uint8_t *secret,
221 size_t secretlen, const uint8_t *info,
222 size_t infolen) {
223 if (wolfSSL_quic_hkdf_expand(dest, destlen, md->native_handle, secret,
224 secretlen, info, infolen) != WOLFSSL_SUCCESS) {
225 return -1;
226 }
227 return 0;
228 }
229
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)230 int ngtcp2_crypto_hkdf(uint8_t *dest, size_t destlen,
231 const ngtcp2_crypto_md *md, const uint8_t *secret,
232 size_t secretlen, const uint8_t *salt, size_t saltlen,
233 const uint8_t *info, size_t infolen) {
234 if (wolfSSL_quic_hkdf(dest, destlen, md->native_handle, secret, secretlen,
235 salt, saltlen, info, infolen) != WOLFSSL_SUCCESS) {
236 return -1;
237 }
238 return 0;
239 }
240
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)241 int ngtcp2_crypto_encrypt(uint8_t *dest, const ngtcp2_crypto_aead *aead,
242 const ngtcp2_crypto_aead_ctx *aead_ctx,
243 const uint8_t *plaintext, size_t plaintextlen,
244 const uint8_t *nonce, size_t noncelen,
245 const uint8_t *aad, size_t aadlen) {
246 (void)aead;
247 (void)noncelen;
248 if (wolfSSL_quic_aead_encrypt(dest, aead_ctx->native_handle, plaintext,
249 plaintextlen, nonce, aad,
250 aadlen) != WOLFSSL_SUCCESS) {
251 DEBUG_MSG("WOLFSSL: encrypt FAILED\n");
252 return -1;
253 }
254 return 0;
255 }
256
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)257 int ngtcp2_crypto_decrypt(uint8_t *dest, const ngtcp2_crypto_aead *aead,
258 const ngtcp2_crypto_aead_ctx *aead_ctx,
259 const uint8_t *ciphertext, size_t ciphertextlen,
260 const uint8_t *nonce, size_t noncelen,
261 const uint8_t *aad, size_t aadlen) {
262 (void)aead;
263 (void)noncelen;
264 if (wolfSSL_quic_aead_decrypt(dest, aead_ctx->native_handle, ciphertext,
265 ciphertextlen, nonce, aad,
266 aadlen) != WOLFSSL_SUCCESS) {
267
268 DEBUG_MSG("WOLFSSL: decrypt FAILED\n");
269 return -1;
270 }
271 return 0;
272 }
273
ngtcp2_crypto_hp_mask(uint8_t * dest,const ngtcp2_crypto_cipher * hp,const ngtcp2_crypto_cipher_ctx * hp_ctx,const uint8_t * sample)274 int ngtcp2_crypto_hp_mask(uint8_t *dest, const ngtcp2_crypto_cipher *hp,
275 const ngtcp2_crypto_cipher_ctx *hp_ctx,
276 const uint8_t *sample) {
277 static const uint8_t PLAINTEXT[] = "\x00\x00\x00\x00\x00";
278 WOLFSSL_EVP_CIPHER_CTX *actx = hp_ctx->native_handle;
279 int len;
280
281 (void)hp;
282
283 if (wolfSSL_EVP_EncryptInit_ex(actx, NULL, NULL, NULL, sample) !=
284 WOLFSSL_SUCCESS ||
285 wolfSSL_EVP_CipherUpdate(actx, dest, &len, PLAINTEXT,
286 sizeof(PLAINTEXT) - 1) != WOLFSSL_SUCCESS ||
287 wolfSSL_EVP_EncryptFinal_ex(actx, dest + sizeof(PLAINTEXT) - 1, &len) !=
288 WOLFSSL_SUCCESS) {
289 return -1;
290 }
291
292 return 0;
293 }
294
ngtcp2_crypto_read_write_crypto_data(ngtcp2_conn * conn,ngtcp2_crypto_level crypto_level,const uint8_t * data,size_t datalen)295 int ngtcp2_crypto_read_write_crypto_data(ngtcp2_conn *conn,
296 ngtcp2_crypto_level crypto_level,
297 const uint8_t *data, size_t datalen) {
298 WOLFSSL *ssl = ngtcp2_conn_get_tls_native_handle(conn);
299 WOLFSSL_ENCRYPTION_LEVEL level =
300 ngtcp2_crypto_wolfssl_from_ngtcp2_crypto_level(crypto_level);
301 int rv;
302 int err;
303
304 DEBUG_MSG("WOLFSSL: read/write crypto data, level=%d len=%lu\n", level,
305 datalen);
306 if (datalen > 0) {
307 rv = wolfSSL_provide_quic_data(ssl, level, data, datalen);
308 if (rv != WOLFSSL_SUCCESS) {
309 DEBUG_MSG("WOLFSSL: read/write crypto data FAILED, rv=%d\n", rv);
310 return -1;
311 }
312 }
313
314 if (!ngtcp2_conn_get_handshake_completed(conn)) {
315 rv = wolfSSL_quic_do_handshake(ssl);
316 DEBUG_MSG("WOLFSSL: do_handshake, rv=%d\n", rv);
317 if (rv <= 0) {
318 err = wolfSSL_get_error(ssl, rv);
319 switch (err) {
320 case SSL_ERROR_WANT_READ:
321 case SSL_ERROR_WANT_WRITE:
322 return 0;
323 case SSL_ERROR_SSL:
324 return -1;
325 default:
326 return -1;
327 }
328 }
329
330 DEBUG_MSG("WOLFSSL: handshake done\n");
331 ngtcp2_conn_handshake_completed(conn);
332 }
333
334 rv = wolfSSL_process_quic_post_handshake(ssl);
335 DEBUG_MSG("WOLFSSL: process post handshake, rv=%d\n", rv);
336 if (rv != 1) {
337 err = wolfSSL_get_error(ssl, rv);
338 switch (err) {
339 case SSL_ERROR_WANT_READ:
340 case SSL_ERROR_WANT_WRITE:
341 return 0;
342 case SSL_ERROR_SSL:
343 case SSL_ERROR_ZERO_RETURN:
344 return -1;
345 default:
346 return -1;
347 }
348 }
349
350 return 0;
351 }
352
ngtcp2_crypto_set_remote_transport_params(ngtcp2_conn * conn,void * tls)353 int ngtcp2_crypto_set_remote_transport_params(ngtcp2_conn *conn, void *tls) {
354 WOLFSSL *ssl = tls;
355 const uint8_t *tp;
356 size_t tplen;
357 int rv;
358
359 wolfSSL_get_peer_quic_transport_params(ssl, &tp, &tplen);
360 DEBUG_MSG("WOLFSSL: get peer transport params, len=%lu\n", tplen);
361
362 rv = ngtcp2_conn_decode_remote_transport_params(conn, tp, tplen);
363 if (rv != 0) {
364 DEBUG_MSG("WOLFSSL: decode peer transport params failed, rv=%d\n", rv);
365 ngtcp2_conn_set_tls_error(conn, rv);
366 return -1;
367 }
368
369 return 0;
370 }
371
ngtcp2_crypto_set_local_transport_params(void * tls,const uint8_t * buf,size_t len)372 int ngtcp2_crypto_set_local_transport_params(void *tls, const uint8_t *buf,
373 size_t len) {
374 WOLFSSL *ssl = tls;
375 DEBUG_MSG("WOLFSSL: set local peer transport params, len=%lu\n", len);
376 if (wolfSSL_set_quic_transport_params(ssl, buf, len) != WOLFSSL_SUCCESS) {
377 return -1;
378 }
379
380 return 0;
381 }
382
ngtcp2_crypto_wolfssl_from_wolfssl_encryption_level(WOLFSSL_ENCRYPTION_LEVEL wolfssl_level)383 ngtcp2_crypto_level ngtcp2_crypto_wolfssl_from_wolfssl_encryption_level(
384 WOLFSSL_ENCRYPTION_LEVEL wolfssl_level) {
385 switch (wolfssl_level) {
386 case wolfssl_encryption_initial:
387 return NGTCP2_CRYPTO_LEVEL_INITIAL;
388 case wolfssl_encryption_early_data:
389 return NGTCP2_CRYPTO_LEVEL_EARLY;
390 case wolfssl_encryption_handshake:
391 return NGTCP2_CRYPTO_LEVEL_HANDSHAKE;
392 case wolfssl_encryption_application:
393 return NGTCP2_CRYPTO_LEVEL_APPLICATION;
394 default:
395 assert(0);
396 abort(); /* if NDEBUG is set */
397 }
398 }
399
400 WOLFSSL_ENCRYPTION_LEVEL
ngtcp2_crypto_wolfssl_from_ngtcp2_crypto_level(ngtcp2_crypto_level crypto_level)401 ngtcp2_crypto_wolfssl_from_ngtcp2_crypto_level(
402 ngtcp2_crypto_level crypto_level) {
403 switch (crypto_level) {
404 case NGTCP2_CRYPTO_LEVEL_INITIAL:
405 return wolfssl_encryption_initial;
406 case NGTCP2_CRYPTO_LEVEL_HANDSHAKE:
407 return wolfssl_encryption_handshake;
408 case NGTCP2_CRYPTO_LEVEL_APPLICATION:
409 return wolfssl_encryption_application;
410 case NGTCP2_CRYPTO_LEVEL_EARLY:
411 return wolfssl_encryption_early_data;
412 default:
413 assert(0);
414 abort(); /* if NDEBUG is set */
415 }
416 }
417
ngtcp2_crypto_get_path_challenge_data_cb(ngtcp2_conn * conn,uint8_t * data,void * user_data)418 int ngtcp2_crypto_get_path_challenge_data_cb(ngtcp2_conn *conn, uint8_t *data,
419 void *user_data) {
420 (void)conn;
421 (void)user_data;
422
423 DEBUG_MSG("WOLFSSL: get path challenge data\n");
424 if (wolfSSL_RAND_bytes(data, NGTCP2_PATH_CHALLENGE_DATALEN) != 1) {
425 return NGTCP2_ERR_CALLBACK_FAILURE;
426 }
427 return 0;
428 }
429
ngtcp2_crypto_random(uint8_t * data,size_t datalen)430 int ngtcp2_crypto_random(uint8_t *data, size_t datalen) {
431 DEBUG_MSG("WOLFSSL: get random\n");
432 if (wolfSSL_RAND_bytes(data, (int)datalen) != 1) {
433 return -1;
434 }
435 return 0;
436 }
437
set_encryption_secrets(WOLFSSL * ssl,WOLFSSL_ENCRYPTION_LEVEL wolfssl_level,const uint8_t * rx_secret,const uint8_t * tx_secret,size_t secretlen)438 static int set_encryption_secrets(WOLFSSL *ssl,
439 WOLFSSL_ENCRYPTION_LEVEL wolfssl_level,
440 const uint8_t *rx_secret,
441 const uint8_t *tx_secret, size_t secretlen) {
442 ngtcp2_crypto_conn_ref *conn_ref = SSL_get_app_data(ssl);
443 ngtcp2_conn *conn = conn_ref->get_conn(conn_ref);
444 ngtcp2_crypto_level level =
445 ngtcp2_crypto_wolfssl_from_wolfssl_encryption_level(wolfssl_level);
446
447 DEBUG_MSG("WOLFSSL: set encryption secrets, level=%d, rxlen=%lu, txlen=%lu\n",
448 wolfssl_level, rx_secret ? secretlen : 0,
449 tx_secret ? secretlen : 0);
450 if (rx_secret &&
451 ngtcp2_crypto_derive_and_install_rx_key(conn, NULL, NULL, NULL, level,
452 rx_secret, secretlen) != 0) {
453 return 0;
454 }
455
456 if (tx_secret &&
457 ngtcp2_crypto_derive_and_install_tx_key(conn, NULL, NULL, NULL, level,
458 tx_secret, secretlen) != 0) {
459 return 0;
460 }
461
462 return 1;
463 }
464
add_handshake_data(WOLFSSL * ssl,WOLFSSL_ENCRYPTION_LEVEL wolfssl_level,const uint8_t * data,size_t datalen)465 static int add_handshake_data(WOLFSSL *ssl,
466 WOLFSSL_ENCRYPTION_LEVEL wolfssl_level,
467 const uint8_t *data, size_t datalen) {
468 ngtcp2_crypto_conn_ref *conn_ref = SSL_get_app_data(ssl);
469 ngtcp2_conn *conn = conn_ref->get_conn(conn_ref);
470 ngtcp2_crypto_level level =
471 ngtcp2_crypto_wolfssl_from_wolfssl_encryption_level(wolfssl_level);
472 int rv;
473
474 DEBUG_MSG("WOLFSSL: add handshake data, level=%d len=%lu\n", wolfssl_level,
475 datalen);
476 rv = ngtcp2_conn_submit_crypto_data(conn, level, data, datalen);
477 if (rv != 0) {
478 ngtcp2_conn_set_tls_error(conn, rv);
479 return 0;
480 }
481
482 return 1;
483 }
484
flush_flight(WOLFSSL * ssl)485 static int flush_flight(WOLFSSL *ssl) {
486 (void)ssl;
487 return 1;
488 }
489
send_alert(WOLFSSL * ssl,enum wolfssl_encryption_level_t level,uint8_t alert)490 static int send_alert(WOLFSSL *ssl, enum wolfssl_encryption_level_t level,
491 uint8_t alert) {
492 ngtcp2_crypto_conn_ref *conn_ref = SSL_get_app_data(ssl);
493 ngtcp2_conn *conn = conn_ref->get_conn(conn_ref);
494 (void)level;
495
496 DEBUG_MSG("WOLFSSL: send alert, level=%d alert=%d\n", level, alert);
497 ngtcp2_conn_set_tls_alert(conn, alert);
498
499 return 1;
500 }
501
502 static WOLFSSL_QUIC_METHOD quic_method = {
503 set_encryption_secrets,
504 add_handshake_data,
505 flush_flight,
506 send_alert,
507 };
508
crypto_wolfssl_configure_context(WOLFSSL_CTX * ssl_ctx)509 static void crypto_wolfssl_configure_context(WOLFSSL_CTX *ssl_ctx) {
510 wolfSSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
511 wolfSSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION);
512 wolfSSL_CTX_set_quic_method(ssl_ctx, &quic_method);
513 }
514
ngtcp2_crypto_wolfssl_configure_server_context(WOLFSSL_CTX * ssl_ctx)515 int ngtcp2_crypto_wolfssl_configure_server_context(WOLFSSL_CTX *ssl_ctx) {
516 crypto_wolfssl_configure_context(ssl_ctx);
517 return 0;
518 }
519
ngtcp2_crypto_wolfssl_configure_client_context(WOLFSSL_CTX * ssl_ctx)520 int ngtcp2_crypto_wolfssl_configure_client_context(WOLFSSL_CTX *ssl_ctx) {
521 crypto_wolfssl_configure_context(ssl_ctx);
522 wolfSSL_CTX_UseSessionTicket(ssl_ctx);
523 return 0;
524 }
525