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