• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ngtcp2
3  *
4  * Copyright (c) 2019 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 #include "shared.h"
26 
27 #ifdef WIN32
28 #  include <winsock2.h>
29 #  include <ws2tcpip.h>
30 #else
31 #  include <netinet/in.h>
32 #endif
33 
34 #include <string.h>
35 #include <assert.h>
36 
37 #include "ngtcp2_macro.h"
38 #include "ngtcp2_net.h"
39 
ngtcp2_crypto_md_init(ngtcp2_crypto_md * md,void * md_native_handle)40 ngtcp2_crypto_md *ngtcp2_crypto_md_init(ngtcp2_crypto_md *md,
41                                         void *md_native_handle) {
42   md->native_handle = md_native_handle;
43   return md;
44 }
45 
ngtcp2_crypto_hkdf_expand_label(uint8_t * dest,size_t destlen,const ngtcp2_crypto_md * md,const uint8_t * secret,size_t secretlen,const uint8_t * label,size_t labellen)46 int ngtcp2_crypto_hkdf_expand_label(uint8_t *dest, size_t destlen,
47                                     const ngtcp2_crypto_md *md,
48                                     const uint8_t *secret, size_t secretlen,
49                                     const uint8_t *label, size_t labellen) {
50   static const uint8_t LABEL[] = "tls13 ";
51   uint8_t info[256];
52   uint8_t *p = info;
53 
54   *p++ = (uint8_t)(destlen / 256);
55   *p++ = (uint8_t)(destlen % 256);
56   *p++ = (uint8_t)(sizeof(LABEL) - 1 + labellen);
57   memcpy(p, LABEL, sizeof(LABEL) - 1);
58   p += sizeof(LABEL) - 1;
59   memcpy(p, label, labellen);
60   p += labellen;
61   *p++ = 0;
62 
63   return ngtcp2_crypto_hkdf_expand(dest, destlen, md, secret, secretlen, info,
64                                    (size_t)(p - info));
65 }
66 
67 #define NGTCP2_CRYPTO_INITIAL_SECRETLEN 32
68 
ngtcp2_crypto_derive_initial_secrets(uint32_t version,uint8_t * rx_secret,uint8_t * tx_secret,uint8_t * initial_secret,const ngtcp2_cid * client_dcid,ngtcp2_crypto_side side)69 int ngtcp2_crypto_derive_initial_secrets(uint32_t version, uint8_t *rx_secret,
70                                          uint8_t *tx_secret,
71                                          uint8_t *initial_secret,
72                                          const ngtcp2_cid *client_dcid,
73                                          ngtcp2_crypto_side side) {
74   static const uint8_t CLABEL[] = "client in";
75   static const uint8_t SLABEL[] = "server in";
76   uint8_t initial_secret_buf[NGTCP2_CRYPTO_INITIAL_SECRETLEN];
77   uint8_t *client_secret;
78   uint8_t *server_secret;
79   ngtcp2_crypto_ctx ctx;
80   const uint8_t *salt;
81   size_t saltlen;
82 
83   if (!initial_secret) {
84     initial_secret = initial_secret_buf;
85   }
86 
87   ngtcp2_crypto_ctx_initial(&ctx);
88 
89   switch (version) {
90   case NGTCP2_PROTO_VER_V1:
91     salt = (const uint8_t *)NGTCP2_INITIAL_SALT_V1;
92     saltlen = sizeof(NGTCP2_INITIAL_SALT_V1) - 1;
93     break;
94   case NGTCP2_PROTO_VER_V2_DRAFT:
95     salt = (const uint8_t *)NGTCP2_INITIAL_SALT_V2_DRAFT;
96     saltlen = sizeof(NGTCP2_INITIAL_SALT_V2_DRAFT) - 1;
97     break;
98   default:
99     salt = (const uint8_t *)NGTCP2_INITIAL_SALT_DRAFT;
100     saltlen = sizeof(NGTCP2_INITIAL_SALT_DRAFT) - 1;
101   }
102 
103   if (ngtcp2_crypto_hkdf_extract(initial_secret, &ctx.md, client_dcid->data,
104                                  client_dcid->datalen, salt, saltlen) != 0) {
105     return -1;
106   }
107 
108   if (side == NGTCP2_CRYPTO_SIDE_SERVER) {
109     client_secret = rx_secret;
110     server_secret = tx_secret;
111   } else {
112     client_secret = tx_secret;
113     server_secret = rx_secret;
114   }
115 
116   if (ngtcp2_crypto_hkdf_expand_label(
117           client_secret, NGTCP2_CRYPTO_INITIAL_SECRETLEN, &ctx.md,
118           initial_secret, NGTCP2_CRYPTO_INITIAL_SECRETLEN, CLABEL,
119           sizeof(CLABEL) - 1) != 0 ||
120       ngtcp2_crypto_hkdf_expand_label(
121           server_secret, NGTCP2_CRYPTO_INITIAL_SECRETLEN, &ctx.md,
122           initial_secret, NGTCP2_CRYPTO_INITIAL_SECRETLEN, SLABEL,
123           sizeof(SLABEL) - 1) != 0) {
124     return -1;
125   }
126 
127   return 0;
128 }
129 
ngtcp2_crypto_packet_protection_ivlen(const ngtcp2_crypto_aead * aead)130 size_t ngtcp2_crypto_packet_protection_ivlen(const ngtcp2_crypto_aead *aead) {
131   size_t noncelen = ngtcp2_crypto_aead_noncelen(aead);
132   return ngtcp2_max(8, noncelen);
133 }
134 
ngtcp2_crypto_derive_packet_protection_key(uint8_t * key,uint8_t * iv,uint8_t * hp_key,uint32_t version,const ngtcp2_crypto_aead * aead,const ngtcp2_crypto_md * md,const uint8_t * secret,size_t secretlen)135 int ngtcp2_crypto_derive_packet_protection_key(
136     uint8_t *key, uint8_t *iv, uint8_t *hp_key, uint32_t version,
137     const ngtcp2_crypto_aead *aead, const ngtcp2_crypto_md *md,
138     const uint8_t *secret, size_t secretlen) {
139   static const uint8_t KEY_LABEL_V1[] = "quic key";
140   static const uint8_t IV_LABEL_V1[] = "quic iv";
141   static const uint8_t HP_KEY_LABEL_V1[] = "quic hp";
142   static const uint8_t KEY_LABEL_V2_DRAFT[] = "quicv2 key";
143   static const uint8_t IV_LABEL_V2_DRAFT[] = "quicv2 iv";
144   static const uint8_t HP_KEY_LABEL_V2_DRAFT[] = "quicv2 hp";
145   size_t keylen = ngtcp2_crypto_aead_keylen(aead);
146   size_t ivlen = ngtcp2_crypto_packet_protection_ivlen(aead);
147   const uint8_t *key_label;
148   size_t key_labellen;
149   const uint8_t *iv_label;
150   size_t iv_labellen;
151   const uint8_t *hp_key_label;
152   size_t hp_key_labellen;
153 
154   switch (version) {
155   case NGTCP2_PROTO_VER_V2_DRAFT:
156     key_label = KEY_LABEL_V2_DRAFT;
157     key_labellen = sizeof(KEY_LABEL_V2_DRAFT) - 1;
158     iv_label = IV_LABEL_V2_DRAFT;
159     iv_labellen = sizeof(IV_LABEL_V2_DRAFT) - 1;
160     hp_key_label = HP_KEY_LABEL_V2_DRAFT;
161     hp_key_labellen = sizeof(HP_KEY_LABEL_V2_DRAFT) - 1;
162     break;
163   default:
164     key_label = KEY_LABEL_V1;
165     key_labellen = sizeof(KEY_LABEL_V1) - 1;
166     iv_label = IV_LABEL_V1;
167     iv_labellen = sizeof(IV_LABEL_V1) - 1;
168     hp_key_label = HP_KEY_LABEL_V1;
169     hp_key_labellen = sizeof(HP_KEY_LABEL_V1) - 1;
170   }
171 
172   if (ngtcp2_crypto_hkdf_expand_label(key, keylen, md, secret, secretlen,
173                                       key_label, key_labellen) != 0) {
174     return -1;
175   }
176 
177   if (ngtcp2_crypto_hkdf_expand_label(iv, ivlen, md, secret, secretlen,
178                                       iv_label, iv_labellen) != 0) {
179     return -1;
180   }
181 
182   if (hp_key != NULL &&
183       ngtcp2_crypto_hkdf_expand_label(hp_key, keylen, md, secret, secretlen,
184                                       hp_key_label, hp_key_labellen) != 0) {
185     return -1;
186   }
187 
188   return 0;
189 }
190 
ngtcp2_crypto_update_traffic_secret(uint8_t * dest,const ngtcp2_crypto_md * md,const uint8_t * secret,size_t secretlen)191 int ngtcp2_crypto_update_traffic_secret(uint8_t *dest,
192                                         const ngtcp2_crypto_md *md,
193                                         const uint8_t *secret,
194                                         size_t secretlen) {
195   static const uint8_t LABEL[] = "quic ku";
196 
197   if (ngtcp2_crypto_hkdf_expand_label(dest, secretlen, md, secret, secretlen,
198                                       LABEL, sizeof(LABEL) - 1) != 0) {
199     return -1;
200   }
201 
202   return 0;
203 }
204 
ngtcp2_crypto_derive_and_install_rx_key(ngtcp2_conn * conn,uint8_t * key,uint8_t * iv,uint8_t * hp_key,ngtcp2_crypto_level level,const uint8_t * secret,size_t secretlen)205 int ngtcp2_crypto_derive_and_install_rx_key(ngtcp2_conn *conn, uint8_t *key,
206                                             uint8_t *iv, uint8_t *hp_key,
207                                             ngtcp2_crypto_level level,
208                                             const uint8_t *secret,
209                                             size_t secretlen) {
210   const ngtcp2_crypto_ctx *ctx;
211   const ngtcp2_crypto_aead *aead;
212   const ngtcp2_crypto_md *md;
213   const ngtcp2_crypto_cipher *hp;
214   ngtcp2_crypto_aead_ctx aead_ctx = {0};
215   ngtcp2_crypto_cipher_ctx hp_ctx = {0};
216   void *tls = ngtcp2_conn_get_tls_native_handle(conn);
217   uint8_t keybuf[64], ivbuf[64], hp_keybuf[64];
218   size_t ivlen;
219   int rv;
220   ngtcp2_crypto_ctx cctx;
221   uint32_t version;
222 
223   if (level == NGTCP2_CRYPTO_LEVEL_EARLY && !ngtcp2_conn_is_server(conn)) {
224     return 0;
225   }
226 
227   if (!key) {
228     key = keybuf;
229   }
230   if (!iv) {
231     iv = ivbuf;
232   }
233   if (!hp_key) {
234     hp_key = hp_keybuf;
235   }
236 
237   switch (level) {
238   case NGTCP2_CRYPTO_LEVEL_EARLY:
239     ngtcp2_crypto_ctx_tls_early(&cctx, tls);
240     ngtcp2_conn_set_early_crypto_ctx(conn, &cctx);
241     ctx = ngtcp2_conn_get_early_crypto_ctx(conn);
242     version = ngtcp2_conn_get_client_chosen_version(conn);
243     break;
244   case NGTCP2_CRYPTO_LEVEL_HANDSHAKE:
245     if (ngtcp2_conn_is_server(conn) &&
246         !ngtcp2_conn_get_negotiated_version(conn)) {
247       rv = ngtcp2_crypto_set_remote_transport_params(conn, tls);
248       if (rv != 0) {
249         return -1;
250       }
251     }
252     /* fall through */
253   default:
254     ctx = ngtcp2_conn_get_crypto_ctx(conn);
255     version = ngtcp2_conn_get_negotiated_version(conn);
256 
257     if (!ctx->aead.native_handle) {
258       ngtcp2_crypto_ctx_tls(&cctx, tls);
259       ngtcp2_conn_set_crypto_ctx(conn, &cctx);
260       ctx = ngtcp2_conn_get_crypto_ctx(conn);
261     }
262   }
263 
264   aead = &ctx->aead;
265   md = &ctx->md;
266   hp = &ctx->hp;
267   ivlen = ngtcp2_crypto_packet_protection_ivlen(aead);
268 
269   if (ngtcp2_crypto_derive_packet_protection_key(key, iv, hp_key, version, aead,
270                                                  md, secret, secretlen) != 0) {
271     return -1;
272   }
273 
274   if (ngtcp2_crypto_aead_ctx_decrypt_init(&aead_ctx, aead, key, ivlen) != 0) {
275     goto fail;
276   }
277 
278   if (ngtcp2_crypto_cipher_ctx_encrypt_init(&hp_ctx, hp, hp_key) != 0) {
279     goto fail;
280   }
281 
282   switch (level) {
283   case NGTCP2_CRYPTO_LEVEL_EARLY:
284     rv = ngtcp2_conn_install_early_key(conn, &aead_ctx, iv, ivlen, &hp_ctx);
285     if (rv != 0) {
286       goto fail;
287     }
288     break;
289   case NGTCP2_CRYPTO_LEVEL_HANDSHAKE:
290     rv = ngtcp2_conn_install_rx_handshake_key(conn, &aead_ctx, iv, ivlen,
291                                               &hp_ctx);
292     if (rv != 0) {
293       goto fail;
294     }
295     break;
296   case NGTCP2_CRYPTO_LEVEL_APPLICATION:
297     if (!ngtcp2_conn_is_server(conn)) {
298       rv = ngtcp2_crypto_set_remote_transport_params(conn, tls);
299       if (rv != 0) {
300         goto fail;
301       }
302     }
303 
304     rv = ngtcp2_conn_install_rx_key(conn, secret, secretlen, &aead_ctx, iv,
305                                     ivlen, &hp_ctx);
306     if (rv != 0) {
307       goto fail;
308     }
309 
310     break;
311   default:
312     goto fail;
313   }
314 
315   return 0;
316 
317 fail:
318   ngtcp2_crypto_cipher_ctx_free(&hp_ctx);
319   ngtcp2_crypto_aead_ctx_free(&aead_ctx);
320 
321   return -1;
322 }
323 
324 /*
325  * crypto_set_local_transport_params gets local QUIC transport
326  * parameters from |conn| and sets it to |tls|.
327  *
328  * This function returns 0 if it succeeds, or -1.
329  */
crypto_set_local_transport_params(ngtcp2_conn * conn,void * tls)330 static int crypto_set_local_transport_params(ngtcp2_conn *conn, void *tls) {
331   ngtcp2_ssize nwrite;
332   uint8_t buf[256];
333 
334   nwrite = ngtcp2_conn_encode_local_transport_params(conn, buf, sizeof(buf));
335   if (nwrite < 0) {
336     return -1;
337   }
338 
339   if (ngtcp2_crypto_set_local_transport_params(tls, buf, (size_t)nwrite) != 0) {
340     return -1;
341   }
342 
343   return 0;
344 }
345 
ngtcp2_crypto_derive_and_install_tx_key(ngtcp2_conn * conn,uint8_t * key,uint8_t * iv,uint8_t * hp_key,ngtcp2_crypto_level level,const uint8_t * secret,size_t secretlen)346 int ngtcp2_crypto_derive_and_install_tx_key(ngtcp2_conn *conn, uint8_t *key,
347                                             uint8_t *iv, uint8_t *hp_key,
348                                             ngtcp2_crypto_level level,
349                                             const uint8_t *secret,
350                                             size_t secretlen) {
351   const ngtcp2_crypto_ctx *ctx;
352   const ngtcp2_crypto_aead *aead;
353   const ngtcp2_crypto_md *md;
354   const ngtcp2_crypto_cipher *hp;
355   ngtcp2_crypto_aead_ctx aead_ctx = {0};
356   ngtcp2_crypto_cipher_ctx hp_ctx = {0};
357   void *tls = ngtcp2_conn_get_tls_native_handle(conn);
358   uint8_t keybuf[64], ivbuf[64], hp_keybuf[64];
359   size_t ivlen;
360   int rv;
361   ngtcp2_crypto_ctx cctx;
362   uint32_t version;
363 
364   if (level == NGTCP2_CRYPTO_LEVEL_EARLY && ngtcp2_conn_is_server(conn)) {
365     return 0;
366   }
367 
368   if (!key) {
369     key = keybuf;
370   }
371   if (!iv) {
372     iv = ivbuf;
373   }
374   if (!hp_key) {
375     hp_key = hp_keybuf;
376   }
377 
378   switch (level) {
379   case NGTCP2_CRYPTO_LEVEL_EARLY:
380     ngtcp2_crypto_ctx_tls_early(&cctx, tls);
381     ngtcp2_conn_set_early_crypto_ctx(conn, &cctx);
382     ctx = ngtcp2_conn_get_early_crypto_ctx(conn);
383     version = ngtcp2_conn_get_client_chosen_version(conn);
384     break;
385   case NGTCP2_CRYPTO_LEVEL_HANDSHAKE:
386     if (ngtcp2_conn_is_server(conn) &&
387         !ngtcp2_conn_get_negotiated_version(conn)) {
388       rv = ngtcp2_crypto_set_remote_transport_params(conn, tls);
389       if (rv != 0) {
390         return -1;
391       }
392     }
393     /* fall through */
394   default:
395     ctx = ngtcp2_conn_get_crypto_ctx(conn);
396     version = ngtcp2_conn_get_negotiated_version(conn);
397 
398     if (!ctx->aead.native_handle) {
399       ngtcp2_crypto_ctx_tls(&cctx, tls);
400       ngtcp2_conn_set_crypto_ctx(conn, &cctx);
401       ctx = ngtcp2_conn_get_crypto_ctx(conn);
402     }
403   }
404 
405   aead = &ctx->aead;
406   md = &ctx->md;
407   hp = &ctx->hp;
408   ivlen = ngtcp2_crypto_packet_protection_ivlen(aead);
409 
410   if (ngtcp2_crypto_derive_packet_protection_key(key, iv, hp_key, version, aead,
411                                                  md, secret, secretlen) != 0) {
412     return -1;
413   }
414 
415   if (ngtcp2_crypto_aead_ctx_encrypt_init(&aead_ctx, aead, key, ivlen) != 0) {
416     goto fail;
417   }
418 
419   if (ngtcp2_crypto_cipher_ctx_encrypt_init(&hp_ctx, hp, hp_key) != 0) {
420     goto fail;
421   }
422 
423   switch (level) {
424   case NGTCP2_CRYPTO_LEVEL_EARLY:
425     rv = ngtcp2_conn_install_early_key(conn, &aead_ctx, iv, ivlen, &hp_ctx);
426     if (rv != 0) {
427       goto fail;
428     }
429     break;
430   case NGTCP2_CRYPTO_LEVEL_HANDSHAKE:
431     rv = ngtcp2_conn_install_tx_handshake_key(conn, &aead_ctx, iv, ivlen,
432                                               &hp_ctx);
433     if (rv != 0) {
434       goto fail;
435     }
436 
437     if (ngtcp2_conn_is_server(conn) &&
438         crypto_set_local_transport_params(conn, tls) != 0) {
439       goto fail;
440     }
441 
442     break;
443   case NGTCP2_CRYPTO_LEVEL_APPLICATION:
444     rv = ngtcp2_conn_install_tx_key(conn, secret, secretlen, &aead_ctx, iv,
445                                     ivlen, &hp_ctx);
446     if (rv != 0) {
447       goto fail;
448     }
449 
450     break;
451   default:
452     goto fail;
453   }
454 
455   return 0;
456 
457 fail:
458   ngtcp2_crypto_cipher_ctx_free(&hp_ctx);
459   ngtcp2_crypto_aead_ctx_free(&aead_ctx);
460 
461   return -1;
462 }
463 
ngtcp2_crypto_derive_and_install_initial_key(ngtcp2_conn * conn,uint8_t * rx_secret,uint8_t * tx_secret,uint8_t * initial_secret,uint8_t * rx_key,uint8_t * rx_iv,uint8_t * rx_hp_key,uint8_t * tx_key,uint8_t * tx_iv,uint8_t * tx_hp_key,uint32_t version,const ngtcp2_cid * client_dcid)464 int ngtcp2_crypto_derive_and_install_initial_key(
465     ngtcp2_conn *conn, uint8_t *rx_secret, uint8_t *tx_secret,
466     uint8_t *initial_secret, uint8_t *rx_key, uint8_t *rx_iv,
467     uint8_t *rx_hp_key, uint8_t *tx_key, uint8_t *tx_iv, uint8_t *tx_hp_key,
468     uint32_t version, const ngtcp2_cid *client_dcid) {
469   uint8_t rx_secretbuf[NGTCP2_CRYPTO_INITIAL_SECRETLEN];
470   uint8_t tx_secretbuf[NGTCP2_CRYPTO_INITIAL_SECRETLEN];
471   uint8_t initial_secretbuf[NGTCP2_CRYPTO_INITIAL_SECRETLEN];
472   uint8_t rx_keybuf[NGTCP2_CRYPTO_INITIAL_KEYLEN];
473   uint8_t rx_ivbuf[NGTCP2_CRYPTO_INITIAL_IVLEN];
474   uint8_t rx_hp_keybuf[NGTCP2_CRYPTO_INITIAL_KEYLEN];
475   uint8_t tx_keybuf[NGTCP2_CRYPTO_INITIAL_KEYLEN];
476   uint8_t tx_ivbuf[NGTCP2_CRYPTO_INITIAL_IVLEN];
477   uint8_t tx_hp_keybuf[NGTCP2_CRYPTO_INITIAL_KEYLEN];
478   ngtcp2_crypto_ctx ctx;
479   ngtcp2_crypto_aead retry_aead;
480   ngtcp2_crypto_aead_ctx rx_aead_ctx = {0};
481   ngtcp2_crypto_cipher_ctx rx_hp_ctx = {0};
482   ngtcp2_crypto_aead_ctx tx_aead_ctx = {0};
483   ngtcp2_crypto_cipher_ctx tx_hp_ctx = {0};
484   ngtcp2_crypto_aead_ctx retry_aead_ctx = {0};
485   int rv;
486   int server = ngtcp2_conn_is_server(conn);
487   const uint8_t *retry_key;
488   size_t retry_noncelen;
489 
490   ngtcp2_crypto_ctx_initial(&ctx);
491 
492   if (!rx_secret) {
493     rx_secret = rx_secretbuf;
494   }
495   if (!tx_secret) {
496     tx_secret = tx_secretbuf;
497   }
498   if (!initial_secret) {
499     initial_secret = initial_secretbuf;
500   }
501 
502   if (!rx_key) {
503     rx_key = rx_keybuf;
504   }
505   if (!rx_iv) {
506     rx_iv = rx_ivbuf;
507   }
508   if (!rx_hp_key) {
509     rx_hp_key = rx_hp_keybuf;
510   }
511   if (!tx_key) {
512     tx_key = tx_keybuf;
513   }
514   if (!tx_iv) {
515     tx_iv = tx_ivbuf;
516   }
517   if (!tx_hp_key) {
518     tx_hp_key = tx_hp_keybuf;
519   }
520 
521   ngtcp2_conn_set_initial_crypto_ctx(conn, &ctx);
522 
523   if (ngtcp2_crypto_derive_initial_secrets(
524           version, rx_secret, tx_secret, initial_secret, client_dcid,
525           server ? NGTCP2_CRYPTO_SIDE_SERVER : NGTCP2_CRYPTO_SIDE_CLIENT) !=
526       0) {
527     return -1;
528   }
529 
530   if (ngtcp2_crypto_derive_packet_protection_key(
531           rx_key, rx_iv, rx_hp_key, version, &ctx.aead, &ctx.md, rx_secret,
532           NGTCP2_CRYPTO_INITIAL_SECRETLEN) != 0) {
533     return -1;
534   }
535 
536   if (ngtcp2_crypto_derive_packet_protection_key(
537           tx_key, tx_iv, tx_hp_key, version, &ctx.aead, &ctx.md, tx_secret,
538           NGTCP2_CRYPTO_INITIAL_SECRETLEN) != 0) {
539     return -1;
540   }
541 
542   if (ngtcp2_crypto_aead_ctx_decrypt_init(&rx_aead_ctx, &ctx.aead, rx_key,
543                                           NGTCP2_CRYPTO_INITIAL_IVLEN) != 0) {
544     goto fail;
545   }
546 
547   if (ngtcp2_crypto_cipher_ctx_encrypt_init(&rx_hp_ctx, &ctx.hp, rx_hp_key) !=
548       0) {
549     goto fail;
550   }
551 
552   if (ngtcp2_crypto_aead_ctx_encrypt_init(&tx_aead_ctx, &ctx.aead, tx_key,
553                                           NGTCP2_CRYPTO_INITIAL_IVLEN) != 0) {
554     goto fail;
555   }
556 
557   if (ngtcp2_crypto_cipher_ctx_encrypt_init(&tx_hp_ctx, &ctx.hp, tx_hp_key) !=
558       0) {
559     goto fail;
560   }
561 
562   if (!server && !ngtcp2_conn_after_retry(conn)) {
563     ngtcp2_crypto_aead_retry(&retry_aead);
564 
565     switch (version) {
566     case NGTCP2_PROTO_VER_V1:
567       retry_key = (const uint8_t *)NGTCP2_RETRY_KEY_V1;
568       retry_noncelen = sizeof(NGTCP2_RETRY_NONCE_V1) - 1;
569       break;
570     case NGTCP2_PROTO_VER_V2_DRAFT:
571       retry_key = (const uint8_t *)NGTCP2_RETRY_KEY_V2_DRAFT;
572       retry_noncelen = sizeof(NGTCP2_RETRY_NONCE_V2_DRAFT) - 1;
573       break;
574     default:
575       retry_key = (const uint8_t *)NGTCP2_RETRY_KEY_DRAFT;
576       retry_noncelen = sizeof(NGTCP2_RETRY_NONCE_DRAFT) - 1;
577     }
578 
579     if (ngtcp2_crypto_aead_ctx_encrypt_init(&retry_aead_ctx, &retry_aead,
580                                             retry_key, retry_noncelen) != 0) {
581       goto fail;
582     }
583   }
584 
585   rv = ngtcp2_conn_install_initial_key(conn, &rx_aead_ctx, rx_iv, &rx_hp_ctx,
586                                        &tx_aead_ctx, tx_iv, &tx_hp_ctx,
587                                        NGTCP2_CRYPTO_INITIAL_IVLEN);
588   if (rv != 0) {
589     goto fail;
590   }
591 
592   if (retry_aead_ctx.native_handle) {
593     ngtcp2_conn_set_retry_aead(conn, &retry_aead, &retry_aead_ctx);
594   }
595 
596   return 0;
597 
598 fail:
599   ngtcp2_crypto_aead_ctx_free(&retry_aead_ctx);
600   ngtcp2_crypto_cipher_ctx_free(&tx_hp_ctx);
601   ngtcp2_crypto_aead_ctx_free(&tx_aead_ctx);
602   ngtcp2_crypto_cipher_ctx_free(&rx_hp_ctx);
603   ngtcp2_crypto_aead_ctx_free(&rx_aead_ctx);
604 
605   return -1;
606 }
607 
ngtcp2_crypto_derive_and_install_vneg_initial_key(ngtcp2_conn * conn,uint8_t * rx_secret,uint8_t * tx_secret,uint8_t * initial_secret,uint8_t * rx_key,uint8_t * rx_iv,uint8_t * rx_hp_key,uint8_t * tx_key,uint8_t * tx_iv,uint8_t * tx_hp_key,uint32_t version,const ngtcp2_cid * client_dcid)608 int ngtcp2_crypto_derive_and_install_vneg_initial_key(
609     ngtcp2_conn *conn, uint8_t *rx_secret, uint8_t *tx_secret,
610     uint8_t *initial_secret, uint8_t *rx_key, uint8_t *rx_iv,
611     uint8_t *rx_hp_key, uint8_t *tx_key, uint8_t *tx_iv, uint8_t *tx_hp_key,
612     uint32_t version, const ngtcp2_cid *client_dcid) {
613   uint8_t rx_secretbuf[NGTCP2_CRYPTO_INITIAL_SECRETLEN];
614   uint8_t tx_secretbuf[NGTCP2_CRYPTO_INITIAL_SECRETLEN];
615   uint8_t initial_secretbuf[NGTCP2_CRYPTO_INITIAL_SECRETLEN];
616   uint8_t rx_keybuf[NGTCP2_CRYPTO_INITIAL_KEYLEN];
617   uint8_t rx_ivbuf[NGTCP2_CRYPTO_INITIAL_IVLEN];
618   uint8_t rx_hp_keybuf[NGTCP2_CRYPTO_INITIAL_KEYLEN];
619   uint8_t tx_keybuf[NGTCP2_CRYPTO_INITIAL_KEYLEN];
620   uint8_t tx_ivbuf[NGTCP2_CRYPTO_INITIAL_IVLEN];
621   uint8_t tx_hp_keybuf[NGTCP2_CRYPTO_INITIAL_KEYLEN];
622   const ngtcp2_crypto_ctx *ctx = ngtcp2_conn_get_initial_crypto_ctx(conn);
623   ngtcp2_crypto_aead_ctx rx_aead_ctx = {0};
624   ngtcp2_crypto_cipher_ctx rx_hp_ctx = {0};
625   ngtcp2_crypto_aead_ctx tx_aead_ctx = {0};
626   ngtcp2_crypto_cipher_ctx tx_hp_ctx = {0};
627   int rv;
628   int server = ngtcp2_conn_is_server(conn);
629 
630   if (!rx_secret) {
631     rx_secret = rx_secretbuf;
632   }
633   if (!tx_secret) {
634     tx_secret = tx_secretbuf;
635   }
636   if (!initial_secret) {
637     initial_secret = initial_secretbuf;
638   }
639 
640   if (!rx_key) {
641     rx_key = rx_keybuf;
642   }
643   if (!rx_iv) {
644     rx_iv = rx_ivbuf;
645   }
646   if (!rx_hp_key) {
647     rx_hp_key = rx_hp_keybuf;
648   }
649   if (!tx_key) {
650     tx_key = tx_keybuf;
651   }
652   if (!tx_iv) {
653     tx_iv = tx_ivbuf;
654   }
655   if (!tx_hp_key) {
656     tx_hp_key = tx_hp_keybuf;
657   }
658 
659   if (ngtcp2_crypto_derive_initial_secrets(
660           version, rx_secret, tx_secret, initial_secret, client_dcid,
661           server ? NGTCP2_CRYPTO_SIDE_SERVER : NGTCP2_CRYPTO_SIDE_CLIENT) !=
662       0) {
663     return -1;
664   }
665 
666   if (ngtcp2_crypto_derive_packet_protection_key(
667           rx_key, rx_iv, rx_hp_key, version, &ctx->aead, &ctx->md, rx_secret,
668           NGTCP2_CRYPTO_INITIAL_SECRETLEN) != 0) {
669     return -1;
670   }
671 
672   if (ngtcp2_crypto_derive_packet_protection_key(
673           tx_key, tx_iv, tx_hp_key, version, &ctx->aead, &ctx->md, tx_secret,
674           NGTCP2_CRYPTO_INITIAL_SECRETLEN) != 0) {
675     return -1;
676   }
677 
678   if (ngtcp2_crypto_aead_ctx_decrypt_init(&rx_aead_ctx, &ctx->aead, rx_key,
679                                           NGTCP2_CRYPTO_INITIAL_IVLEN) != 0) {
680     goto fail;
681   }
682 
683   if (ngtcp2_crypto_cipher_ctx_encrypt_init(&rx_hp_ctx, &ctx->hp, rx_hp_key) !=
684       0) {
685     goto fail;
686   }
687 
688   if (ngtcp2_crypto_aead_ctx_encrypt_init(&tx_aead_ctx, &ctx->aead, tx_key,
689                                           NGTCP2_CRYPTO_INITIAL_IVLEN) != 0) {
690     goto fail;
691   }
692 
693   if (ngtcp2_crypto_cipher_ctx_encrypt_init(&tx_hp_ctx, &ctx->hp, tx_hp_key) !=
694       0) {
695     goto fail;
696   }
697 
698   rv = ngtcp2_conn_install_vneg_initial_key(
699       conn, version, &rx_aead_ctx, rx_iv, &rx_hp_ctx, &tx_aead_ctx, tx_iv,
700       &tx_hp_ctx, NGTCP2_CRYPTO_INITIAL_IVLEN);
701   if (rv != 0) {
702     goto fail;
703   }
704 
705   return 0;
706 
707 fail:
708   ngtcp2_crypto_cipher_ctx_free(&tx_hp_ctx);
709   ngtcp2_crypto_aead_ctx_free(&tx_aead_ctx);
710   ngtcp2_crypto_cipher_ctx_free(&rx_hp_ctx);
711   ngtcp2_crypto_aead_ctx_free(&rx_aead_ctx);
712 
713   return -1;
714 }
715 
ngtcp2_crypto_update_key(ngtcp2_conn * conn,uint8_t * rx_secret,uint8_t * tx_secret,ngtcp2_crypto_aead_ctx * rx_aead_ctx,uint8_t * rx_key,uint8_t * rx_iv,ngtcp2_crypto_aead_ctx * tx_aead_ctx,uint8_t * tx_key,uint8_t * tx_iv,const uint8_t * current_rx_secret,const uint8_t * current_tx_secret,size_t secretlen)716 int ngtcp2_crypto_update_key(
717     ngtcp2_conn *conn, uint8_t *rx_secret, uint8_t *tx_secret,
718     ngtcp2_crypto_aead_ctx *rx_aead_ctx, uint8_t *rx_key, uint8_t *rx_iv,
719     ngtcp2_crypto_aead_ctx *tx_aead_ctx, uint8_t *tx_key, uint8_t *tx_iv,
720     const uint8_t *current_rx_secret, const uint8_t *current_tx_secret,
721     size_t secretlen) {
722   const ngtcp2_crypto_ctx *ctx = ngtcp2_conn_get_crypto_ctx(conn);
723   const ngtcp2_crypto_aead *aead = &ctx->aead;
724   const ngtcp2_crypto_md *md = &ctx->md;
725   size_t ivlen = ngtcp2_crypto_packet_protection_ivlen(aead);
726   uint32_t version = ngtcp2_conn_get_negotiated_version(conn);
727 
728   if (ngtcp2_crypto_update_traffic_secret(rx_secret, md, current_rx_secret,
729                                           secretlen) != 0) {
730     return -1;
731   }
732 
733   if (ngtcp2_crypto_derive_packet_protection_key(
734           rx_key, rx_iv, NULL, version, aead, md, rx_secret, secretlen) != 0) {
735     return -1;
736   }
737 
738   if (ngtcp2_crypto_update_traffic_secret(tx_secret, md, current_tx_secret,
739                                           secretlen) != 0) {
740     return -1;
741   }
742 
743   if (ngtcp2_crypto_derive_packet_protection_key(
744           tx_key, tx_iv, NULL, version, aead, md, tx_secret, secretlen) != 0) {
745     return -1;
746   }
747 
748   if (ngtcp2_crypto_aead_ctx_decrypt_init(rx_aead_ctx, aead, rx_key, ivlen) !=
749       0) {
750     return -1;
751   }
752 
753   if (ngtcp2_crypto_aead_ctx_encrypt_init(tx_aead_ctx, aead, tx_key, ivlen) !=
754       0) {
755     ngtcp2_crypto_aead_ctx_free(rx_aead_ctx);
756     rx_aead_ctx->native_handle = NULL;
757     return -1;
758   }
759 
760   return 0;
761 }
762 
ngtcp2_crypto_encrypt_cb(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)763 int ngtcp2_crypto_encrypt_cb(uint8_t *dest, const ngtcp2_crypto_aead *aead,
764                              const ngtcp2_crypto_aead_ctx *aead_ctx,
765                              const uint8_t *plaintext, size_t plaintextlen,
766                              const uint8_t *nonce, size_t noncelen,
767                              const uint8_t *aad, size_t aadlen) {
768   if (ngtcp2_crypto_encrypt(dest, aead, aead_ctx, plaintext, plaintextlen,
769                             nonce, noncelen, aad, aadlen) != 0) {
770     return NGTCP2_ERR_CALLBACK_FAILURE;
771   }
772   return 0;
773 }
774 
ngtcp2_crypto_decrypt_cb(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)775 int ngtcp2_crypto_decrypt_cb(uint8_t *dest, const ngtcp2_crypto_aead *aead,
776                              const ngtcp2_crypto_aead_ctx *aead_ctx,
777                              const uint8_t *ciphertext, size_t ciphertextlen,
778                              const uint8_t *nonce, size_t noncelen,
779                              const uint8_t *aad, size_t aadlen) {
780   if (ngtcp2_crypto_decrypt(dest, aead, aead_ctx, ciphertext, ciphertextlen,
781                             nonce, noncelen, aad, aadlen) != 0) {
782     return NGTCP2_ERR_DECRYPT;
783   }
784   return 0;
785 }
786 
ngtcp2_crypto_hp_mask_cb(uint8_t * dest,const ngtcp2_crypto_cipher * hp,const ngtcp2_crypto_cipher_ctx * hp_ctx,const uint8_t * sample)787 int ngtcp2_crypto_hp_mask_cb(uint8_t *dest, const ngtcp2_crypto_cipher *hp,
788                              const ngtcp2_crypto_cipher_ctx *hp_ctx,
789                              const uint8_t *sample) {
790   if (ngtcp2_crypto_hp_mask(dest, hp, hp_ctx, sample) != 0) {
791     return NGTCP2_ERR_CALLBACK_FAILURE;
792   }
793   return 0;
794 }
795 
ngtcp2_crypto_update_key_cb(ngtcp2_conn * conn,uint8_t * rx_secret,uint8_t * tx_secret,ngtcp2_crypto_aead_ctx * rx_aead_ctx,uint8_t * rx_iv,ngtcp2_crypto_aead_ctx * tx_aead_ctx,uint8_t * tx_iv,const uint8_t * current_rx_secret,const uint8_t * current_tx_secret,size_t secretlen,void * user_data)796 int ngtcp2_crypto_update_key_cb(
797     ngtcp2_conn *conn, uint8_t *rx_secret, uint8_t *tx_secret,
798     ngtcp2_crypto_aead_ctx *rx_aead_ctx, uint8_t *rx_iv,
799     ngtcp2_crypto_aead_ctx *tx_aead_ctx, uint8_t *tx_iv,
800     const uint8_t *current_rx_secret, const uint8_t *current_tx_secret,
801     size_t secretlen, void *user_data) {
802   uint8_t rx_key[64];
803   uint8_t tx_key[64];
804   (void)conn;
805   (void)user_data;
806 
807   if (ngtcp2_crypto_update_key(conn, rx_secret, tx_secret, rx_aead_ctx, rx_key,
808                                rx_iv, tx_aead_ctx, tx_key, tx_iv,
809                                current_rx_secret, current_tx_secret,
810                                secretlen) != 0) {
811     return NGTCP2_ERR_CALLBACK_FAILURE;
812   }
813   return 0;
814 }
815 
ngtcp2_crypto_generate_stateless_reset_token(uint8_t * token,const uint8_t * secret,size_t secretlen,const ngtcp2_cid * cid)816 int ngtcp2_crypto_generate_stateless_reset_token(uint8_t *token,
817                                                  const uint8_t *secret,
818                                                  size_t secretlen,
819                                                  const ngtcp2_cid *cid) {
820   static const uint8_t info[] = "stateless_reset";
821   ngtcp2_crypto_md md;
822 
823   if (ngtcp2_crypto_hkdf(token, NGTCP2_STATELESS_RESET_TOKENLEN,
824                          ngtcp2_crypto_md_sha256(&md), secret, secretlen,
825                          cid->data, cid->datalen, info,
826                          sizeof(info) - 1) != 0) {
827     return -1;
828   }
829 
830   return 0;
831 }
832 
crypto_derive_token_key(uint8_t * key,size_t keylen,uint8_t * iv,size_t ivlen,const ngtcp2_crypto_md * md,const uint8_t * secret,size_t secretlen,const uint8_t * salt,size_t saltlen,const uint8_t * info_prefix,size_t info_prefixlen)833 static int crypto_derive_token_key(uint8_t *key, size_t keylen, uint8_t *iv,
834                                    size_t ivlen, const ngtcp2_crypto_md *md,
835                                    const uint8_t *secret, size_t secretlen,
836                                    const uint8_t *salt, size_t saltlen,
837                                    const uint8_t *info_prefix,
838                                    size_t info_prefixlen) {
839   static const uint8_t key_info_suffix[] = " key";
840   static const uint8_t iv_info_suffix[] = " iv";
841   uint8_t intsecret[32];
842   uint8_t info[32];
843   uint8_t *p;
844 
845   assert(ngtcp2_crypto_md_hashlen(md) == sizeof(intsecret));
846   assert(info_prefixlen + sizeof(key_info_suffix) - 1 <= sizeof(info));
847   assert(info_prefixlen + sizeof(iv_info_suffix) - 1 <= sizeof(info));
848 
849   if (ngtcp2_crypto_hkdf_extract(intsecret, md, secret, secretlen, salt,
850                                  saltlen) != 0) {
851     return -1;
852   }
853 
854   memcpy(info, info_prefix, info_prefixlen);
855   p = info + info_prefixlen;
856 
857   memcpy(p, key_info_suffix, sizeof(key_info_suffix) - 1);
858   p += sizeof(key_info_suffix) - 1;
859 
860   if (ngtcp2_crypto_hkdf_expand(key, keylen, md, intsecret, sizeof(intsecret),
861                                 info, (size_t)(p - info)) != 0) {
862     return -1;
863   }
864 
865   p = info + info_prefixlen;
866 
867   memcpy(p, iv_info_suffix, sizeof(iv_info_suffix) - 1);
868   p += sizeof(iv_info_suffix) - 1;
869 
870   if (ngtcp2_crypto_hkdf_expand(iv, ivlen, md, intsecret, sizeof(intsecret),
871                                 info, (size_t)(p - info)) != 0) {
872     return -1;
873   }
874 
875   return 0;
876 }
877 
crypto_generate_retry_token_aad(uint8_t * dest,uint32_t version,const ngtcp2_sockaddr * sa,ngtcp2_socklen salen,const ngtcp2_cid * retry_scid)878 static size_t crypto_generate_retry_token_aad(uint8_t *dest, uint32_t version,
879                                               const ngtcp2_sockaddr *sa,
880                                               ngtcp2_socklen salen,
881                                               const ngtcp2_cid *retry_scid) {
882   uint8_t *p = dest;
883 
884   version = ngtcp2_htonl(version);
885   memcpy(p, &version, sizeof(version));
886   memcpy(p, sa, (size_t)salen);
887   p += salen;
888   memcpy(p, retry_scid->data, retry_scid->datalen);
889   p += retry_scid->datalen;
890 
891   return (size_t)(p - dest);
892 }
893 
894 static const uint8_t retry_token_info_prefix[] = "retry_token";
895 
ngtcp2_crypto_generate_retry_token(uint8_t * token,const uint8_t * secret,size_t secretlen,uint32_t version,const ngtcp2_sockaddr * remote_addr,ngtcp2_socklen remote_addrlen,const ngtcp2_cid * retry_scid,const ngtcp2_cid * odcid,ngtcp2_tstamp ts)896 ngtcp2_ssize ngtcp2_crypto_generate_retry_token(
897     uint8_t *token, const uint8_t *secret, size_t secretlen, uint32_t version,
898     const ngtcp2_sockaddr *remote_addr, ngtcp2_socklen remote_addrlen,
899     const ngtcp2_cid *retry_scid, const ngtcp2_cid *odcid, ngtcp2_tstamp ts) {
900   uint8_t plaintext[NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN];
901   uint8_t rand_data[NGTCP2_CRYPTO_TOKEN_RAND_DATALEN];
902   uint8_t key[32];
903   uint8_t iv[32];
904   size_t keylen;
905   size_t ivlen;
906   ngtcp2_crypto_aead aead;
907   ngtcp2_crypto_md md;
908   ngtcp2_crypto_aead_ctx aead_ctx;
909   size_t plaintextlen;
910   uint8_t aad[sizeof(version) + sizeof(ngtcp2_sockaddr_storage) +
911               NGTCP2_MAX_CIDLEN];
912   size_t aadlen;
913   uint8_t *p = plaintext;
914   ngtcp2_tstamp ts_be = ngtcp2_htonl64(ts);
915   int rv;
916 
917   memset(plaintext, 0, sizeof(plaintext));
918 
919   *p++ = (uint8_t)odcid->datalen;
920   memcpy(p, odcid->data, odcid->datalen);
921   p += NGTCP2_MAX_CIDLEN;
922   memcpy(p, &ts_be, sizeof(ts_be));
923   p += sizeof(ts_be);
924 
925   plaintextlen = (size_t)(p - plaintext);
926 
927   if (ngtcp2_crypto_random(rand_data, sizeof(rand_data)) != 0) {
928     return -1;
929   }
930 
931   ngtcp2_crypto_aead_aes_128_gcm(&aead);
932   ngtcp2_crypto_md_sha256(&md);
933 
934   keylen = ngtcp2_crypto_aead_keylen(&aead);
935   ivlen = ngtcp2_crypto_aead_noncelen(&aead);
936 
937   assert(sizeof(key) >= keylen);
938   assert(sizeof(iv) >= ivlen);
939 
940   if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
941                               rand_data, sizeof(rand_data),
942                               retry_token_info_prefix,
943                               sizeof(retry_token_info_prefix) - 1) != 0) {
944     return -1;
945   }
946 
947   aadlen = crypto_generate_retry_token_aad(aad, version, remote_addr,
948                                            remote_addrlen, retry_scid);
949 
950   p = token;
951   *p++ = NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY;
952 
953   if (ngtcp2_crypto_aead_ctx_encrypt_init(&aead_ctx, &aead, key, ivlen) != 0) {
954     return -1;
955   }
956 
957   rv = ngtcp2_crypto_encrypt(p, &aead, &aead_ctx, plaintext, plaintextlen, iv,
958                              ivlen, aad, aadlen);
959 
960   ngtcp2_crypto_aead_ctx_free(&aead_ctx);
961 
962   if (rv != 0) {
963     return -1;
964   }
965 
966   p += plaintextlen + aead.max_overhead;
967   memcpy(p, rand_data, sizeof(rand_data));
968   p += sizeof(rand_data);
969 
970   return p - token;
971 }
972 
ngtcp2_crypto_verify_retry_token(ngtcp2_cid * odcid,const uint8_t * token,size_t tokenlen,const uint8_t * secret,size_t secretlen,uint32_t version,const ngtcp2_sockaddr * remote_addr,ngtcp2_socklen remote_addrlen,const ngtcp2_cid * dcid,ngtcp2_duration timeout,ngtcp2_tstamp ts)973 int ngtcp2_crypto_verify_retry_token(
974     ngtcp2_cid *odcid, const uint8_t *token, size_t tokenlen,
975     const uint8_t *secret, size_t secretlen, uint32_t version,
976     const ngtcp2_sockaddr *remote_addr, ngtcp2_socklen remote_addrlen,
977     const ngtcp2_cid *dcid, ngtcp2_duration timeout, ngtcp2_tstamp ts) {
978   uint8_t
979       plaintext[/* cid len = */ 1 + NGTCP2_MAX_CIDLEN + sizeof(ngtcp2_tstamp)];
980   uint8_t key[32];
981   uint8_t iv[32];
982   size_t keylen;
983   size_t ivlen;
984   ngtcp2_crypto_aead_ctx aead_ctx;
985   ngtcp2_crypto_aead aead;
986   ngtcp2_crypto_md md;
987   uint8_t aad[sizeof(version) + sizeof(ngtcp2_sockaddr_storage) +
988               NGTCP2_MAX_CIDLEN];
989   size_t aadlen;
990   const uint8_t *rand_data;
991   const uint8_t *ciphertext;
992   size_t ciphertextlen;
993   size_t cil;
994   int rv;
995   ngtcp2_tstamp gen_ts;
996 
997   if (tokenlen != NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN ||
998       token[0] != NGTCP2_CRYPTO_TOKEN_MAGIC_RETRY) {
999     return -1;
1000   }
1001 
1002   rand_data = token + tokenlen - NGTCP2_CRYPTO_TOKEN_RAND_DATALEN;
1003   ciphertext = token + 1;
1004   ciphertextlen = tokenlen - 1 - NGTCP2_CRYPTO_TOKEN_RAND_DATALEN;
1005 
1006   ngtcp2_crypto_aead_aes_128_gcm(&aead);
1007   ngtcp2_crypto_md_sha256(&md);
1008 
1009   keylen = ngtcp2_crypto_aead_keylen(&aead);
1010   ivlen = ngtcp2_crypto_aead_noncelen(&aead);
1011 
1012   if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
1013                               rand_data, NGTCP2_CRYPTO_TOKEN_RAND_DATALEN,
1014                               retry_token_info_prefix,
1015                               sizeof(retry_token_info_prefix) - 1) != 0) {
1016     return -1;
1017   }
1018 
1019   aadlen = crypto_generate_retry_token_aad(aad, version, remote_addr,
1020                                            remote_addrlen, dcid);
1021 
1022   if (ngtcp2_crypto_aead_ctx_decrypt_init(&aead_ctx, &aead, key, ivlen) != 0) {
1023     return -1;
1024   }
1025 
1026   rv = ngtcp2_crypto_decrypt(plaintext, &aead, &aead_ctx, ciphertext,
1027                              ciphertextlen, iv, ivlen, aad, aadlen);
1028 
1029   ngtcp2_crypto_aead_ctx_free(&aead_ctx);
1030 
1031   if (rv != 0) {
1032     return -1;
1033   }
1034 
1035   cil = plaintext[0];
1036 
1037   assert(cil == 0 || (cil >= NGTCP2_MIN_CIDLEN && cil <= NGTCP2_MAX_CIDLEN));
1038 
1039   memcpy(&gen_ts, plaintext + /* cid len = */ 1 + NGTCP2_MAX_CIDLEN,
1040          sizeof(gen_ts));
1041 
1042   gen_ts = ngtcp2_ntohl64(gen_ts);
1043   if (gen_ts + timeout <= ts) {
1044     return -1;
1045   }
1046 
1047   ngtcp2_cid_init(odcid, plaintext + /* cid len = */ 1, cil);
1048 
1049   return 0;
1050 }
1051 
crypto_generate_regular_token_aad(uint8_t * dest,const ngtcp2_sockaddr * sa)1052 static size_t crypto_generate_regular_token_aad(uint8_t *dest,
1053                                                 const ngtcp2_sockaddr *sa) {
1054   const uint8_t *addr;
1055   size_t addrlen;
1056 
1057   switch (sa->sa_family) {
1058   case AF_INET:
1059     addr = (const uint8_t *)&((const ngtcp2_sockaddr_in *)(void *)sa)->sin_addr;
1060     addrlen = sizeof(((const ngtcp2_sockaddr_in *)(void *)sa)->sin_addr);
1061     break;
1062   case AF_INET6:
1063     addr =
1064         (const uint8_t *)&((const ngtcp2_sockaddr_in6 *)(void *)sa)->sin6_addr;
1065     addrlen = sizeof(((const ngtcp2_sockaddr_in6 *)(void *)sa)->sin6_addr);
1066     break;
1067   default:
1068     assert(0);
1069     abort();
1070   }
1071 
1072   memcpy(dest, addr, addrlen);
1073 
1074   return addrlen;
1075 }
1076 
1077 static const uint8_t regular_token_info_prefix[] = "regular_token";
1078 
ngtcp2_crypto_generate_regular_token(uint8_t * token,const uint8_t * secret,size_t secretlen,const ngtcp2_sockaddr * remote_addr,ngtcp2_socklen remote_addrlen,ngtcp2_tstamp ts)1079 ngtcp2_ssize ngtcp2_crypto_generate_regular_token(
1080     uint8_t *token, const uint8_t *secret, size_t secretlen,
1081     const ngtcp2_sockaddr *remote_addr, ngtcp2_socklen remote_addrlen,
1082     ngtcp2_tstamp ts) {
1083   uint8_t plaintext[sizeof(ngtcp2_tstamp)];
1084   uint8_t rand_data[NGTCP2_CRYPTO_TOKEN_RAND_DATALEN];
1085   uint8_t key[32];
1086   uint8_t iv[32];
1087   size_t keylen;
1088   size_t ivlen;
1089   ngtcp2_crypto_aead aead;
1090   ngtcp2_crypto_md md;
1091   ngtcp2_crypto_aead_ctx aead_ctx;
1092   size_t plaintextlen;
1093   uint8_t aad[sizeof(ngtcp2_sockaddr_in6)];
1094   size_t aadlen;
1095   uint8_t *p = plaintext;
1096   ngtcp2_tstamp ts_be = ngtcp2_htonl64(ts);
1097   int rv;
1098   (void)remote_addrlen;
1099 
1100   memcpy(p, &ts_be, sizeof(ts_be));
1101   p += sizeof(ts_be);
1102 
1103   plaintextlen = (size_t)(p - plaintext);
1104 
1105   if (ngtcp2_crypto_random(rand_data, sizeof(rand_data)) != 0) {
1106     return -1;
1107   }
1108 
1109   ngtcp2_crypto_aead_aes_128_gcm(&aead);
1110   ngtcp2_crypto_md_sha256(&md);
1111 
1112   keylen = ngtcp2_crypto_aead_keylen(&aead);
1113   ivlen = ngtcp2_crypto_aead_noncelen(&aead);
1114 
1115   assert(sizeof(key) >= keylen);
1116   assert(sizeof(iv) >= ivlen);
1117 
1118   if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
1119                               rand_data, sizeof(rand_data),
1120                               regular_token_info_prefix,
1121                               sizeof(regular_token_info_prefix) - 1) != 0) {
1122     return -1;
1123   }
1124 
1125   aadlen = crypto_generate_regular_token_aad(aad, remote_addr);
1126 
1127   p = token;
1128   *p++ = NGTCP2_CRYPTO_TOKEN_MAGIC_REGULAR;
1129 
1130   if (ngtcp2_crypto_aead_ctx_encrypt_init(&aead_ctx, &aead, key, ivlen) != 0) {
1131     return -1;
1132   }
1133 
1134   rv = ngtcp2_crypto_encrypt(p, &aead, &aead_ctx, plaintext, plaintextlen, iv,
1135                              ivlen, aad, aadlen);
1136 
1137   ngtcp2_crypto_aead_ctx_free(&aead_ctx);
1138 
1139   if (rv != 0) {
1140     return -1;
1141   }
1142 
1143   p += plaintextlen + aead.max_overhead;
1144   memcpy(p, rand_data, sizeof(rand_data));
1145   p += sizeof(rand_data);
1146 
1147   return p - token;
1148 }
1149 
ngtcp2_crypto_verify_regular_token(const uint8_t * token,size_t tokenlen,const uint8_t * secret,size_t secretlen,const ngtcp2_sockaddr * remote_addr,ngtcp2_socklen remote_addrlen,ngtcp2_duration timeout,ngtcp2_tstamp ts)1150 int ngtcp2_crypto_verify_regular_token(const uint8_t *token, size_t tokenlen,
1151                                        const uint8_t *secret, size_t secretlen,
1152                                        const ngtcp2_sockaddr *remote_addr,
1153                                        ngtcp2_socklen remote_addrlen,
1154                                        ngtcp2_duration timeout,
1155                                        ngtcp2_tstamp ts) {
1156   uint8_t plaintext[sizeof(ngtcp2_tstamp)];
1157   uint8_t key[32];
1158   uint8_t iv[32];
1159   size_t keylen;
1160   size_t ivlen;
1161   ngtcp2_crypto_aead_ctx aead_ctx;
1162   ngtcp2_crypto_aead aead;
1163   ngtcp2_crypto_md md;
1164   uint8_t aad[sizeof(ngtcp2_sockaddr_in6)];
1165   size_t aadlen;
1166   const uint8_t *rand_data;
1167   const uint8_t *ciphertext;
1168   size_t ciphertextlen;
1169   int rv;
1170   ngtcp2_tstamp gen_ts;
1171   (void)remote_addrlen;
1172 
1173   if (tokenlen != NGTCP2_CRYPTO_MAX_REGULAR_TOKENLEN ||
1174       token[0] != NGTCP2_CRYPTO_TOKEN_MAGIC_REGULAR) {
1175     return -1;
1176   }
1177 
1178   rand_data = token + tokenlen - NGTCP2_CRYPTO_TOKEN_RAND_DATALEN;
1179   ciphertext = token + 1;
1180   ciphertextlen = tokenlen - 1 - NGTCP2_CRYPTO_TOKEN_RAND_DATALEN;
1181 
1182   ngtcp2_crypto_aead_aes_128_gcm(&aead);
1183   ngtcp2_crypto_md_sha256(&md);
1184 
1185   keylen = ngtcp2_crypto_aead_keylen(&aead);
1186   ivlen = ngtcp2_crypto_aead_noncelen(&aead);
1187 
1188   if (crypto_derive_token_key(key, keylen, iv, ivlen, &md, secret, secretlen,
1189                               rand_data, NGTCP2_CRYPTO_TOKEN_RAND_DATALEN,
1190                               regular_token_info_prefix,
1191                               sizeof(regular_token_info_prefix) - 1) != 0) {
1192     return -1;
1193   }
1194 
1195   aadlen = crypto_generate_regular_token_aad(aad, remote_addr);
1196 
1197   if (ngtcp2_crypto_aead_ctx_decrypt_init(&aead_ctx, &aead, key, ivlen) != 0) {
1198     return -1;
1199   }
1200 
1201   rv = ngtcp2_crypto_decrypt(plaintext, &aead, &aead_ctx, ciphertext,
1202                              ciphertextlen, iv, ivlen, aad, aadlen);
1203 
1204   ngtcp2_crypto_aead_ctx_free(&aead_ctx);
1205 
1206   if (rv != 0) {
1207     return -1;
1208   }
1209 
1210   memcpy(&gen_ts, plaintext, sizeof(gen_ts));
1211 
1212   gen_ts = ngtcp2_ntohl64(gen_ts);
1213   if (gen_ts + timeout <= ts) {
1214     return -1;
1215   }
1216 
1217   return 0;
1218 }
1219 
ngtcp2_crypto_write_connection_close(uint8_t * dest,size_t destlen,uint32_t version,const ngtcp2_cid * dcid,const ngtcp2_cid * scid,uint64_t error_code,const uint8_t * reason,size_t reasonlen)1220 ngtcp2_ssize ngtcp2_crypto_write_connection_close(
1221     uint8_t *dest, size_t destlen, uint32_t version, const ngtcp2_cid *dcid,
1222     const ngtcp2_cid *scid, uint64_t error_code, const uint8_t *reason,
1223     size_t reasonlen) {
1224   uint8_t rx_secret[NGTCP2_CRYPTO_INITIAL_SECRETLEN];
1225   uint8_t tx_secret[NGTCP2_CRYPTO_INITIAL_SECRETLEN];
1226   uint8_t initial_secret[NGTCP2_CRYPTO_INITIAL_SECRETLEN];
1227   uint8_t tx_key[NGTCP2_CRYPTO_INITIAL_KEYLEN];
1228   uint8_t tx_iv[NGTCP2_CRYPTO_INITIAL_IVLEN];
1229   uint8_t tx_hp_key[NGTCP2_CRYPTO_INITIAL_KEYLEN];
1230   ngtcp2_crypto_ctx ctx;
1231   ngtcp2_ssize spktlen;
1232   ngtcp2_crypto_aead_ctx aead_ctx = {0};
1233   ngtcp2_crypto_cipher_ctx hp_ctx = {0};
1234 
1235   ngtcp2_crypto_ctx_initial(&ctx);
1236 
1237   if (ngtcp2_crypto_derive_initial_secrets(version, rx_secret, tx_secret,
1238                                            initial_secret, scid,
1239                                            NGTCP2_CRYPTO_SIDE_SERVER) != 0) {
1240     return -1;
1241   }
1242 
1243   if (ngtcp2_crypto_derive_packet_protection_key(
1244           tx_key, tx_iv, tx_hp_key, version, &ctx.aead, &ctx.md, tx_secret,
1245           NGTCP2_CRYPTO_INITIAL_SECRETLEN) != 0) {
1246     return -1;
1247   }
1248 
1249   if (ngtcp2_crypto_aead_ctx_encrypt_init(&aead_ctx, &ctx.aead, tx_key,
1250                                           NGTCP2_CRYPTO_INITIAL_IVLEN) != 0) {
1251     spktlen = -1;
1252     goto end;
1253   }
1254 
1255   if (ngtcp2_crypto_cipher_ctx_encrypt_init(&hp_ctx, &ctx.hp, tx_hp_key) != 0) {
1256     spktlen = -1;
1257     goto end;
1258   }
1259 
1260   spktlen = ngtcp2_pkt_write_connection_close(
1261       dest, destlen, version, dcid, scid, error_code, reason, reasonlen,
1262       ngtcp2_crypto_encrypt_cb, &ctx.aead, &aead_ctx, tx_iv,
1263       ngtcp2_crypto_hp_mask_cb, &ctx.hp, &hp_ctx);
1264   if (spktlen < 0) {
1265     spktlen = -1;
1266   }
1267 
1268 end:
1269   ngtcp2_crypto_cipher_ctx_free(&hp_ctx);
1270   ngtcp2_crypto_aead_ctx_free(&aead_ctx);
1271 
1272   return spktlen;
1273 }
1274 
ngtcp2_crypto_write_retry(uint8_t * dest,size_t destlen,uint32_t version,const ngtcp2_cid * dcid,const ngtcp2_cid * scid,const ngtcp2_cid * odcid,const uint8_t * token,size_t tokenlen)1275 ngtcp2_ssize ngtcp2_crypto_write_retry(uint8_t *dest, size_t destlen,
1276                                        uint32_t version, const ngtcp2_cid *dcid,
1277                                        const ngtcp2_cid *scid,
1278                                        const ngtcp2_cid *odcid,
1279                                        const uint8_t *token, size_t tokenlen) {
1280   ngtcp2_crypto_aead aead;
1281   ngtcp2_ssize spktlen;
1282   ngtcp2_crypto_aead_ctx aead_ctx = {0};
1283   const uint8_t *key;
1284   size_t noncelen;
1285 
1286   ngtcp2_crypto_aead_retry(&aead);
1287 
1288   switch (version) {
1289   case NGTCP2_PROTO_VER_V1:
1290     key = (const uint8_t *)NGTCP2_RETRY_KEY_V1;
1291     noncelen = sizeof(NGTCP2_RETRY_NONCE_V1) - 1;
1292     break;
1293   case NGTCP2_PROTO_VER_V2_DRAFT:
1294     key = (const uint8_t *)NGTCP2_RETRY_KEY_V2_DRAFT;
1295     noncelen = sizeof(NGTCP2_RETRY_NONCE_V2_DRAFT) - 1;
1296     break;
1297   default:
1298     key = (const uint8_t *)NGTCP2_RETRY_KEY_DRAFT;
1299     noncelen = sizeof(NGTCP2_RETRY_NONCE_DRAFT) - 1;
1300   }
1301 
1302   if (ngtcp2_crypto_aead_ctx_encrypt_init(&aead_ctx, &aead, key, noncelen) !=
1303       0) {
1304     return -1;
1305   }
1306 
1307   spktlen = ngtcp2_pkt_write_retry(dest, destlen, version, dcid, scid, odcid,
1308                                    token, tokenlen, ngtcp2_crypto_encrypt_cb,
1309                                    &aead, &aead_ctx);
1310   if (spktlen < 0) {
1311     spktlen = -1;
1312   }
1313 
1314   ngtcp2_crypto_aead_ctx_free(&aead_ctx);
1315 
1316   return spktlen;
1317 }
1318 
ngtcp2_crypto_client_initial_cb(ngtcp2_conn * conn,void * user_data)1319 int ngtcp2_crypto_client_initial_cb(ngtcp2_conn *conn, void *user_data) {
1320   const ngtcp2_cid *dcid = ngtcp2_conn_get_dcid(conn);
1321   void *tls = ngtcp2_conn_get_tls_native_handle(conn);
1322   (void)user_data;
1323 
1324   if (ngtcp2_crypto_derive_and_install_initial_key(
1325           conn, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1326           ngtcp2_conn_get_client_chosen_version(conn), dcid) != 0) {
1327     return NGTCP2_ERR_CALLBACK_FAILURE;
1328   }
1329 
1330   if (crypto_set_local_transport_params(conn, tls) != 0) {
1331     return NGTCP2_ERR_CALLBACK_FAILURE;
1332   }
1333 
1334   if (ngtcp2_crypto_read_write_crypto_data(conn, NGTCP2_CRYPTO_LEVEL_INITIAL,
1335                                            NULL, 0) != 0) {
1336     return NGTCP2_ERR_CALLBACK_FAILURE;
1337   }
1338 
1339   return 0;
1340 }
1341 
ngtcp2_crypto_recv_retry_cb(ngtcp2_conn * conn,const ngtcp2_pkt_hd * hd,void * user_data)1342 int ngtcp2_crypto_recv_retry_cb(ngtcp2_conn *conn, const ngtcp2_pkt_hd *hd,
1343                                 void *user_data) {
1344   (void)user_data;
1345 
1346   if (ngtcp2_crypto_derive_and_install_initial_key(
1347           conn, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1348           ngtcp2_conn_get_client_chosen_version(conn), &hd->scid) != 0) {
1349     return NGTCP2_ERR_CALLBACK_FAILURE;
1350   }
1351 
1352   return 0;
1353 }
1354 
ngtcp2_crypto_recv_client_initial_cb(ngtcp2_conn * conn,const ngtcp2_cid * dcid,void * user_data)1355 int ngtcp2_crypto_recv_client_initial_cb(ngtcp2_conn *conn,
1356                                          const ngtcp2_cid *dcid,
1357                                          void *user_data) {
1358   (void)user_data;
1359 
1360   if (ngtcp2_crypto_derive_and_install_initial_key(
1361           conn, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1362           ngtcp2_conn_get_client_chosen_version(conn), dcid) != 0) {
1363     return NGTCP2_ERR_CALLBACK_FAILURE;
1364   }
1365 
1366   return 0;
1367 }
1368 
ngtcp2_crypto_version_negotiation_cb(ngtcp2_conn * conn,uint32_t version,const ngtcp2_cid * client_dcid,void * user_data)1369 int ngtcp2_crypto_version_negotiation_cb(ngtcp2_conn *conn, uint32_t version,
1370                                          const ngtcp2_cid *client_dcid,
1371                                          void *user_data) {
1372   (void)user_data;
1373 
1374   if (ngtcp2_crypto_derive_and_install_vneg_initial_key(
1375           conn, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, version,
1376           client_dcid) != 0) {
1377     return NGTCP2_ERR_CALLBACK_FAILURE;
1378   }
1379 
1380   return 0;
1381 }
1382 
ngtcp2_crypto_delete_crypto_aead_ctx_cb(ngtcp2_conn * conn,ngtcp2_crypto_aead_ctx * aead_ctx,void * user_data)1383 void ngtcp2_crypto_delete_crypto_aead_ctx_cb(ngtcp2_conn *conn,
1384                                              ngtcp2_crypto_aead_ctx *aead_ctx,
1385                                              void *user_data) {
1386   (void)conn;
1387   (void)user_data;
1388 
1389   ngtcp2_crypto_aead_ctx_free(aead_ctx);
1390 }
1391 
ngtcp2_crypto_delete_crypto_cipher_ctx_cb(ngtcp2_conn * conn,ngtcp2_crypto_cipher_ctx * cipher_ctx,void * user_data)1392 void ngtcp2_crypto_delete_crypto_cipher_ctx_cb(
1393     ngtcp2_conn *conn, ngtcp2_crypto_cipher_ctx *cipher_ctx, void *user_data) {
1394   (void)conn;
1395   (void)user_data;
1396 
1397   ngtcp2_crypto_cipher_ctx_free(cipher_ctx);
1398 }
1399 
ngtcp2_crypto_recv_crypto_data_cb(ngtcp2_conn * conn,ngtcp2_crypto_level crypto_level,uint64_t offset,const uint8_t * data,size_t datalen,void * user_data)1400 int ngtcp2_crypto_recv_crypto_data_cb(ngtcp2_conn *conn,
1401                                       ngtcp2_crypto_level crypto_level,
1402                                       uint64_t offset, const uint8_t *data,
1403                                       size_t datalen, void *user_data) {
1404   int rv;
1405   (void)offset;
1406   (void)user_data;
1407 
1408   if (ngtcp2_crypto_read_write_crypto_data(conn, crypto_level, data, datalen) !=
1409       0) {
1410     rv = ngtcp2_conn_get_tls_error(conn);
1411     if (rv) {
1412       return rv;
1413     }
1414     return NGTCP2_ERR_CRYPTO;
1415   }
1416 
1417   return 0;
1418 }
1419