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