• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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