comparison src/event/ngx_event_quic.c @ 7687:69345a26ba69 quic

Split transport and crypto parts into separate files. New files: src/event/ngx_event_quic_protection.h src/event/ngx_event_quic_protection.c The protection.h header provides interface to the crypto part of the QUIC: 2 functions to initialize corresponding secrets: ngx_quic_set_initial_secret() ngx_quic_set_encryption_secret() and 2 functions to deal with packet processing: ngx_quic_encrypt() ngx_quic_decrypt() Also, structures representing secrets are defined there. All functions require SSL connection and a pool, only crypto operations inside, no access to nginx connections or events. Currently pool->log is used for the logging (instead of original c->log).
author Vladimir Homutov <vl@nginx.com>
date Mon, 16 Mar 2020 19:00:47 +0300
parents 7ada2feeac18
children bec4cd55361e
comparison
equal deleted inserted replaced
7686:7ada2feeac18 7687:69345a26ba69
6 6
7 #include <ngx_config.h> 7 #include <ngx_config.h>
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_event.h> 9 #include <ngx_event.h>
10 10
11
12 #define quic_version 0xff000018
13
14 #define NGX_AES_128_GCM_SHA256 0x1301
15 #define NGX_AES_256_GCM_SHA384 0x1302
16 #define NGX_CHACHA20_POLY1305_SHA256 0x1303
17
18 #define NGX_QUIC_IV_LEN 12
19
20 #ifdef OPENSSL_IS_BORINGSSL
21 #define ngx_quic_cipher_t EVP_AEAD
22 #else
23 #define ngx_quic_cipher_t EVP_CIPHER
24 #endif
25
26
27 #if (NGX_HAVE_NONALIGNED)
28
29 #define ngx_quic_parse_uint16(p) ntohs(*(uint16_t *) (p))
30 #define ngx_quic_parse_uint32(p) ntohl(*(uint32_t *) (p))
31
32 #define ngx_quic_write_uint16 ngx_quic_write_uint16_aligned
33 #define ngx_quic_write_uint32 ngx_quic_write_uint32_aligned
34
35 #else
36
37 #define ngx_quic_parse_uint16(p) ((p)[0] << 8 | (p)[1])
38 #define ngx_quic_parse_uint32(p) \
39 ((uint32_t) (p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3])
40
41 #define ngx_quic_write_uint16(p, s) \
42 ((p)[0] = (u_char) ((s) >> 8), \
43 (p)[1] = (u_char) (s), \
44 (p) + sizeof(uint16_t))
45
46 #define ngx_quic_write_uint32(p, s) \
47 ((p)[0] = (u_char) ((s) >> 24), \
48 (p)[1] = (u_char) ((s) >> 16), \
49 (p)[2] = (u_char) ((s) >> 8), \
50 (p)[3] = (u_char) (s), \
51 (p) + sizeof(uint32_t))
52
53 #endif
54
55
56 #define ngx_quic_write_uint16_aligned(p, s) \
57 (*(uint16_t *) (p) = htons((uint16_t) (s)), (p) + sizeof(uint16_t))
58
59 #define ngx_quic_write_uint32_aligned(p, s) \
60 (*(uint32_t *) (p) = htonl((uint32_t) (s)), (p) + sizeof(uint32_t))
61
62 #define ngx_quic_varint_len(value) \
63 ((value) <= 63 ? 1 : ((uint32_t)value) <= 16383 ? 2 : ((uint64_t)value) <= 1073741823 ? 4 : 8)
64
65
66 #if (NGX_DEBUG)
67
68 #define ngx_quic_hexdump(log, fmt, data, len, ...) \
69 do { \
70 ngx_int_t m; \
71 u_char buf[2048]; \
72 \
73 if (log->log_level & NGX_LOG_DEBUG_EVENT) { \
74 m = ngx_hex_dump(buf, (u_char *) data, ngx_min(len, 1024)) - buf; \
75 ngx_log_debug(NGX_LOG_DEBUG_EVENT, log, 0, \
76 "%s: " fmt " %*s%s, len: %uz", \
77 __FUNCTION__, __VA_ARGS__, m, buf, \
78 len < 2048 ? "" : "...", len); \
79 } \
80 } while (0)
81
82 #else
83
84 #define ngx_quic_hexdump(log, fmt, data, len, ...)
85
86 #endif
87
88 #define ngx_quic_hexdump0(log, fmt, data, len) \
89 ngx_quic_hexdump(log, fmt "%s", data, len, "") \
90
91
92 /* 17.2. Long Header Packets */
93
94 #define NGX_QUIC_PKT_LONG 0x80
95
96 #define NGX_QUIC_PKT_INITIAL 0xc0
97 #define NGX_QUIC_PKT_HANDSHAKE 0xe0
98 11
99 /* 12.4. Frames and Frame Types */ 12 /* 12.4. Frames and Frame Types */
100 #define NGX_QUIC_FT_PADDING 0x00 13 #define NGX_QUIC_FT_PADDING 0x00
101 #define NGX_QUIC_FT_PING 0x01 14 #define NGX_QUIC_FT_PING 0x01
102 #define NGX_QUIC_FT_ACK 0x02 15 #define NGX_QUIC_FT_ACK 0x02
178 NGX_QUIC_ST_HANDSHAKE, 91 NGX_QUIC_ST_HANDSHAKE,
179 NGX_QUIC_ST_APP_DATA 92 NGX_QUIC_ST_APP_DATA
180 } ngx_quic_state_t; 93 } ngx_quic_state_t;
181 94
182 95
183 typedef struct {
184 ngx_str_t secret;
185 ngx_str_t key;
186 ngx_str_t iv;
187 ngx_str_t hp;
188 } ngx_quic_secret_t;
189
190 typedef struct {
191 const ngx_quic_cipher_t *c;
192 const EVP_CIPHER *hp;
193 const EVP_MD *d;
194 } ngx_quic_ciphers_t;
195
196 typedef enum ssl_encryption_level_t ngx_quic_level_t;
197
198 typedef struct ngx_quic_frame_s ngx_quic_frame_t; 96 typedef struct ngx_quic_frame_s ngx_quic_frame_t;
199 97
200 typedef struct { 98 typedef struct {
201 ngx_uint_t pn; 99 ngx_uint_t pn;
202 100
272 /* current packet numbers for each namespace */ 170 /* current packet numbers for each namespace */
273 ngx_uint_t initial_pn; 171 ngx_uint_t initial_pn;
274 ngx_uint_t handshake_pn; 172 ngx_uint_t handshake_pn;
275 ngx_uint_t appdata_pn; 173 ngx_uint_t appdata_pn;
276 174
277 ngx_quic_secret_t client_in; 175 ngx_quic_secrets_t secrets;
278 ngx_quic_secret_t client_hs;
279 ngx_quic_secret_t client_ad;
280 ngx_quic_secret_t server_in;
281 ngx_quic_secret_t server_hs;
282 ngx_quic_secret_t server_ad;
283 176
284 /* streams */ 177 /* streams */
285 ngx_rbtree_t stree; 178 ngx_rbtree_t stree;
286 ngx_rbtree_node_t stree_sentinel; 179 ngx_rbtree_node_t stree_sentinel;
287 ngx_msec_t stream_timeout; 180 ngx_msec_t stream_timeout;
295 ngx_connection_t *c; 188 ngx_connection_t *c;
296 ngx_quic_stream_t s; 189 ngx_quic_stream_t s;
297 } ngx_quic_stream_node_t; 190 } ngx_quic_stream_node_t;
298 191
299 192
300 typedef struct { 193 static ngx_int_t ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b);
301 ngx_quic_secret_t *secret; 194 static ngx_int_t ngx_quic_output(ngx_connection_t *c);
302 ngx_uint_t type;
303 ngx_uint_t *number;
304 ngx_uint_t flags;
305 uint32_t version;
306 ngx_str_t token;
307 ngx_quic_level_t level;
308
309 /* filled in by parser */
310 ngx_buf_t *raw; /* udp datagram from wire */
311
312 u_char *data; /* quic packet */
313 size_t len;
314
315 /* cleartext fields */
316 ngx_str_t dcid;
317 ngx_str_t scid;
318
319 uint64_t pn;
320
321 ngx_str_t payload; /* decrypted payload */
322
323 } ngx_quic_header_t;
324
325 195
326 static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl, 196 static ngx_int_t ngx_quic_new_connection(ngx_connection_t *c, ngx_ssl_t *ssl,
327 ngx_quic_header_t *pkt); 197 ngx_quic_header_t *pkt);
328 static void ngx_quic_close_connection(ngx_connection_t *c); 198 static void ngx_quic_close_connection(ngx_connection_t *c);
329 199
351 enum ssl_encryption_level_t level, const uint8_t *read_secret, 221 enum ssl_encryption_level_t level, const uint8_t *read_secret,
352 const uint8_t *write_secret, size_t secret_len); 222 const uint8_t *write_secret, size_t secret_len);
353 #endif 223 #endif
354 static int ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn, 224 static int ngx_quic_add_handshake_data(ngx_ssl_conn_t *ssl_conn,
355 enum ssl_encryption_level_t level, const uint8_t *data, size_t len); 225 enum ssl_encryption_level_t level, const uint8_t *data, size_t len);
356 static ngx_int_t ngx_quic_create_long_packet(ngx_connection_t *c,
357 ngx_ssl_conn_t *ssl_conn, ngx_quic_header_t *pkt, ngx_str_t *in,
358 ngx_str_t *res);
359 static ngx_int_t ngx_quic_create_short_packet(ngx_connection_t *c,
360 ngx_ssl_conn_t *ssl_conn, ngx_quic_header_t *pkt, ngx_str_t *in,
361 ngx_str_t *res);
362 static int ngx_quic_flush_flight(ngx_ssl_conn_t *ssl_conn); 226 static int ngx_quic_flush_flight(ngx_ssl_conn_t *ssl_conn);
363 static int ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn, 227 static int ngx_quic_send_alert(ngx_ssl_conn_t *ssl_conn,
364 enum ssl_encryption_level_t level, uint8_t alert); 228 enum ssl_encryption_level_t level, uint8_t alert);
365 229
366 static ngx_int_t ngx_quic_process_long_header(ngx_connection_t *c, 230 static ngx_int_t ngx_quic_process_long_header(ngx_connection_t *c,
369 ngx_quic_header_t *pkt); 233 ngx_quic_header_t *pkt);
370 static ngx_int_t ngx_quic_process_initial_header(ngx_connection_t *c, 234 static ngx_int_t ngx_quic_process_initial_header(ngx_connection_t *c,
371 ngx_quic_header_t *pkt); 235 ngx_quic_header_t *pkt);
372 static ngx_int_t ngx_quic_process_handshake_header(ngx_connection_t *c, 236 static ngx_int_t ngx_quic_process_handshake_header(ngx_connection_t *c,
373 ngx_quic_header_t *pkt); 237 ngx_quic_header_t *pkt);
374 static ngx_int_t ngx_quic_initial_secret(ngx_connection_t *c); 238
375 static ngx_int_t ngx_quic_decrypt(ngx_connection_t *c, ngx_quic_header_t *pkt);
376
377 static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask);
378 static uint64_t ngx_quic_parse_int(u_char **pos); 239 static uint64_t ngx_quic_parse_int(u_char **pos);
379 static void ngx_quic_build_int(u_char **pos, uint64_t value);
380
381 static ngx_int_t ngx_hkdf_extract(u_char *out_key, size_t *out_len,
382 const EVP_MD *digest, const u_char *secret, size_t secret_len,
383 const u_char *salt, size_t salt_len);
384 static ngx_int_t ngx_hkdf_expand(u_char *out_key, size_t out_len,
385 const EVP_MD *digest, const u_char *prk, size_t prk_len,
386 const u_char *info, size_t info_len);
387
388 static ngx_int_t ngx_quic_hkdf_expand(ngx_connection_t *c, const EVP_MD *digest,
389 ngx_str_t *out, ngx_str_t *label, const uint8_t *prk, size_t prk_len);
390
391 static ngx_int_t ngx_quic_tls_open(ngx_connection_t *c,
392 const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s, ngx_str_t *out,
393 u_char *nonce, ngx_str_t *in, ngx_str_t *ad);
394 static ngx_int_t ngx_quic_tls_seal(ngx_connection_t *c,
395 const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s, ngx_str_t *out,
396 u_char *nonce, ngx_str_t *in, ngx_str_t *ad);
397
398 static ngx_int_t ngx_quic_tls_hp(ngx_connection_t *c, const EVP_CIPHER *cipher,
399 ngx_quic_secret_t *s, u_char *out, u_char *in);
400
401 static ngx_int_t ngx_quic_ciphers(ngx_connection_t *c,
402 ngx_quic_ciphers_t *ciphers, enum ssl_encryption_level_t level);
403 240
404 static ssize_t ngx_quic_stream_recv(ngx_connection_t *c, u_char *buf, 241 static ssize_t ngx_quic_stream_recv(ngx_connection_t *c, u_char *buf,
405 size_t size); 242 size_t size);
406 static ssize_t ngx_quic_stream_send(ngx_connection_t *c, u_char *buf, 243 static ssize_t ngx_quic_stream_send(ngx_connection_t *c, u_char *buf,
407 size_t size); 244 size_t size);
503 return; 340 return;
504 } 341 }
505 342
506 b.last += n; 343 b.last += n;
507 344
508 if (ngx_quic_input(c, NULL, &b) != NGX_OK) { 345 if (ngx_quic_input(c, &b) != NGX_OK) {
509 ngx_quic_close_connection(c); 346 ngx_quic_close_connection(c);
510 return; 347 return;
511 } 348 }
512 } 349 }
513 350
546 /* XXX */ 383 /* XXX */
547 return NULL; 384 return NULL;
548 } 385 }
549 386
550 387
551 ngx_int_t 388 static ngx_int_t
552 ngx_quic_input(ngx_connection_t *c, ngx_ssl_t *ssl, ngx_buf_t *b) 389 ngx_quic_input(ngx_connection_t *c, ngx_buf_t *b)
553 { 390 {
554 u_char *p; 391 u_char *p;
555 ngx_quic_header_t pkt; 392 ngx_quic_header_t pkt;
556 393
557 if (c->quic == NULL) { 394 if (c->quic == NULL) {
600 437
601 ngx_memzero(&pkt, sizeof(ngx_quic_header_t)); 438 ngx_memzero(&pkt, sizeof(ngx_quic_header_t));
602 ngx_quic_hexdump0(c->log, "payload", payload->data, payload->len); 439 ngx_quic_hexdump0(c->log, "payload", payload->data, payload->len);
603 440
604 pkt.level = level; 441 pkt.level = level;
442 pkt.dcid = qc->dcid;
443 pkt.scid = qc->scid;
605 444
606 if (level == ssl_encryption_initial) { 445 if (level == ssl_encryption_initial) {
607 pkt.number = &qc->initial_pn; 446 pkt.number = &qc->initial_pn;
608 pkt.flags = NGX_QUIC_PKT_INITIAL; 447 pkt.flags = NGX_QUIC_PKT_INITIAL;
609 pkt.secret = &qc->server_in; 448 pkt.secret = &qc->secrets.server.in;
610 pkt.token = initial_token; 449 pkt.token = initial_token;
611
612 if (ngx_quic_create_long_packet(c, c->ssl->connection,
613 &pkt, payload, &res)
614 != NGX_OK)
615 {
616 return NGX_ERROR;
617 }
618 450
619 } else if (level == ssl_encryption_handshake) { 451 } else if (level == ssl_encryption_handshake) {
620 pkt.number = &qc->handshake_pn; 452 pkt.number = &qc->handshake_pn;
621 pkt.flags = NGX_QUIC_PKT_HANDSHAKE; 453 pkt.flags = NGX_QUIC_PKT_HANDSHAKE;
622 pkt.secret = &qc->server_hs; 454 pkt.secret = &qc->secrets.server.hs;
623
624 if (ngx_quic_create_long_packet(c, c->ssl->connection,
625 &pkt, payload, &res)
626 != NGX_OK)
627 {
628 return NGX_ERROR;
629 }
630 455
631 } else { 456 } else {
632 pkt.number = &qc->appdata_pn; 457 pkt.number = &qc->appdata_pn;
633 pkt.secret = &qc->server_ad; 458 pkt.secret = &qc->secrets.server.ad;
634 459 }
635 if (ngx_quic_create_short_packet(c, c->ssl->connection, 460
636 &pkt, payload, &res) 461 if (ngx_quic_encrypt(c->pool, c->ssl->connection, &pkt, payload, &res)
637 != NGX_OK) 462 != NGX_OK)
638 { 463 {
639 return NGX_ERROR; 464 return NGX_ERROR;
640 }
641 } 465 }
642 466
643 ngx_quic_hexdump0(c->log, "packet to send", res.data, res.len); 467 ngx_quic_hexdump0(c->log, "packet to send", res.data, res.len);
644 468
645 c->send(c, res.data, res.len); // TODO: err handling 469 c->send(c, res.data, res.len); // TODO: err handling
470
471 (*pkt.number)++;
646 472
647 return NGX_OK; 473 return NGX_OK;
648 } 474 }
649 475
650 476
838 664
839 return NGX_OK; 665 return NGX_OK;
840 } 666 }
841 667
842 668
843 ngx_int_t 669 static ngx_int_t
844 ngx_quic_output(ngx_connection_t *c) 670 ngx_quic_output(ngx_connection_t *c)
845 { 671 {
846 size_t len; 672 size_t len;
847 ngx_uint_t lvl; 673 ngx_uint_t lvl;
848 ngx_quic_frame_t *f, *start; 674 ngx_quic_frame_t *f, *start;
892 #if BORINGSSL_API_VERSION >= 10 718 #if BORINGSSL_API_VERSION >= 10
893 719
894 static int 720 static int
895 ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn, 721 ngx_quic_set_read_secret(ngx_ssl_conn_t *ssl_conn,
896 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, 722 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher,
897 const uint8_t *secret, size_t secret_len) 723 const uint8_t *rsecret, size_t secret_len)
898 { 724 {
899 ngx_int_t key_len; 725 ngx_connection_t *c;
900 ngx_uint_t i;
901 ngx_connection_t *c;
902 ngx_quic_secret_t *client;
903 ngx_quic_ciphers_t ciphers;
904 726
905 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); 727 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
906 728
907 ngx_quic_hexdump(c->log, "level:%d read", secret, secret_len, level); 729 ngx_quic_hexdump(c->log, "level:%d read secret",
908 730 rsecret, secret_len, level);
909 key_len = ngx_quic_ciphers(c, &ciphers, level); 731
910 732 return ngx_quic_set_encryption_secret(c->pool, ssl_conn, level,
911 if (key_len == NGX_ERROR) { 733 rsecret, secret_len,
912 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher"); 734 &c->quic->secrets.client);
913 return 0;
914 }
915
916 switch (level) {
917
918 case ssl_encryption_handshake:
919 client = &c->quic->client_hs;
920 break;
921
922 case ssl_encryption_application:
923 client = &c->quic->client_ad;
924 break;
925
926 default:
927 return 0;
928 }
929
930 client->key.len = key_len;
931 client->iv.len = NGX_QUIC_IV_LEN;
932 client->hp.len = key_len;
933
934 struct {
935 ngx_str_t label;
936 ngx_str_t *key;
937 const uint8_t *secret;
938 } seq[] = {
939 { ngx_string("tls13 quic key"), &client->key, secret },
940 { ngx_string("tls13 quic iv"), &client->iv, secret },
941 { ngx_string("tls13 quic hp"), &client->hp, secret },
942 };
943
944 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
945
946 if (ngx_quic_hkdf_expand(c, ciphers.d, seq[i].key, &seq[i].label,
947 seq[i].secret, secret_len)
948 != NGX_OK)
949 {
950 return 0;
951 }
952 }
953
954 return 1;
955 } 735 }
956 736
957 737
958 static int 738 static int
959 ngx_quic_set_write_secret(ngx_ssl_conn_t *ssl_conn, 739 ngx_quic_set_write_secret(ngx_ssl_conn_t *ssl_conn,
960 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher, 740 enum ssl_encryption_level_t level, const SSL_CIPHER *cipher,
961 const uint8_t *secret, size_t secret_len) 741 const uint8_t *wsecret, size_t secret_len)
962 { 742 {
963 ngx_int_t key_len; 743 ngx_connection_t *c;
964 ngx_uint_t i;
965 ngx_connection_t *c;
966 ngx_quic_secret_t *server;
967 ngx_quic_ciphers_t ciphers;
968 744
969 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); 745 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
970 746
971 ngx_quic_hexdump(c->log, "level:%d write", secret, secret_len, level); 747 ngx_quic_hexdump(c->log, "level:%d write secret",
972 748 wsecret, secret_len, level);
973 key_len = ngx_quic_ciphers(c, &ciphers, level); 749
974 750 return ngx_quic_set_encryption_secret(c->pool, ssl_conn, level,
975 if (key_len == NGX_ERROR) { 751 wsecret, secret_len,
976 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher"); 752 &c->quic->secrets.server);
977 return 0;
978 }
979
980 switch (level) {
981
982 case ssl_encryption_handshake:
983 server = &c->quic->server_hs;
984 break;
985
986 case ssl_encryption_application:
987 server = &c->quic->server_ad;
988 break;
989
990 default:
991 return 0;
992 }
993
994 server->key.len = key_len;
995 server->iv.len = NGX_QUIC_IV_LEN;
996 server->hp.len = key_len;
997
998 struct {
999 ngx_str_t label;
1000 ngx_str_t *key;
1001 const uint8_t *secret;
1002 } seq[] = {
1003 { ngx_string("tls13 quic key"), &server->key, secret },
1004 { ngx_string("tls13 quic iv"), &server->iv, secret },
1005 { ngx_string("tls13 quic hp"), &server->hp, secret },
1006 };
1007
1008 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
1009
1010 if (ngx_quic_hkdf_expand(c, ciphers.d, seq[i].key, &seq[i].label,
1011 seq[i].secret, secret_len)
1012 != NGX_OK)
1013 {
1014 return 0;
1015 }
1016 }
1017
1018 return 1;
1019 } 753 }
1020 754
1021 #else 755 #else
1022 756
1023 static int 757 static int
1024 ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, 758 ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn,
1025 enum ssl_encryption_level_t level, const uint8_t *read_secret, 759 enum ssl_encryption_level_t level, const uint8_t *rsecret,
1026 const uint8_t *write_secret, size_t secret_len) 760 const uint8_t *wsecret, size_t secret_len)
1027 { 761 {
1028 ngx_int_t key_len; 762 ngx_int_t rc;
1029 ngx_uint_t i; 763 ngx_connection_t *c;
1030 ngx_connection_t *c;
1031 ngx_quic_secret_t *client, *server;
1032 ngx_quic_ciphers_t ciphers;
1033 764
1034 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); 765 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
1035 766
1036 ngx_quic_hexdump(c->log, "level:%d read", read_secret, secret_len, level); 767 ngx_quic_hexdump(c->log, "level:%d read", recret, secret_len, level);
1037 ngx_quic_hexdump(c->log, "level:%d write", write_secret, secret_len, level); 768 ngx_quic_hexdump(c->log, "level:%d write", wsecret, secret_len, level);
1038 769
1039 key_len = ngx_quic_ciphers(c, &ciphers, level); 770 rc = ngx_quic_set_encryption_secret(c->pool, ssl_conn, level,
1040 771 rsecret, secret_len,
1041 if (key_len == NGX_ERROR) { 772 &c->quic->secrets.client);
1042 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher"); 773 if (rc != 1) {
1043 return 0; 774 return rc;
1044 } 775 }
1045 776
1046 switch (level) { 777 return ngx_quic_set_encryption_secret(c->pool, ssl_conn, level,
1047 778 wsecret, secret_len,
1048 case ssl_encryption_handshake: 779 &c->quic->secrets.server);
1049 client = &c->quic->client_hs;
1050 server = &c->quic->server_hs;
1051
1052 break;
1053
1054 case ssl_encryption_application:
1055 client = &c->quic->client_ad;
1056 server = &c->quic->server_ad;
1057
1058 break;
1059
1060 default:
1061 return 0;
1062 }
1063
1064 client->key.len = key_len;
1065 server->key.len = key_len;
1066
1067 client->iv.len = NGX_QUIC_IV_LEN;
1068 server->iv.len = NGX_QUIC_IV_LEN;
1069
1070 client->hp.len = key_len;
1071 server->hp.len = key_len;
1072
1073 struct {
1074 ngx_str_t label;
1075 ngx_str_t *key;
1076 const uint8_t *secret;
1077 } seq[] = {
1078 { ngx_string("tls13 quic key"), &client->key, read_secret },
1079 { ngx_string("tls13 quic iv"), &client->iv, read_secret },
1080 { ngx_string("tls13 quic hp"), &client->hp, read_secret },
1081 { ngx_string("tls13 quic key"), &server->key, write_secret },
1082 { ngx_string("tls13 quic iv"), &server->iv, write_secret },
1083 { ngx_string("tls13 quic hp"), &server->hp, write_secret },
1084 };
1085
1086 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
1087
1088 if (ngx_quic_hkdf_expand(c, ciphers.d, seq[i].key, &seq[i].label,
1089 seq[i].secret, secret_len)
1090 != NGX_OK)
1091 {
1092 return 0;
1093 }
1094 }
1095
1096 return 1;
1097 } 780 }
1098 781
1099 #endif 782 #endif
1100
1101
1102 static ngx_int_t
1103 ngx_quic_create_long_packet(ngx_connection_t *c, ngx_ssl_conn_t *ssl_conn,
1104 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res)
1105 {
1106 u_char *p, *pnp, *nonce, *sample, *packet;
1107 ngx_str_t ad, out;
1108 ngx_quic_ciphers_t ciphers;
1109 ngx_quic_connection_t *qc;
1110 u_char mask[16];
1111
1112 qc = c->quic;
1113
1114 out.len = payload->len + EVP_GCM_TLS_TAG_LEN;
1115
1116 ad.data = ngx_alloc(346 /*max header*/, c->log);
1117 if (ad.data == 0) {
1118 return NGX_ERROR;
1119 }
1120
1121 p = ad.data;
1122
1123 *p++ = pkt->flags;
1124
1125 p = ngx_quic_write_uint32(p, quic_version);
1126
1127 *p++ = qc->scid.len;
1128 p = ngx_cpymem(p, qc->scid.data, qc->scid.len);
1129
1130 *p++ = qc->dcid.len;
1131 p = ngx_cpymem(p, qc->dcid.data, qc->dcid.len);
1132
1133 if (pkt->level == ssl_encryption_initial) {
1134 ngx_quic_build_int(&p, pkt->token.len);
1135 }
1136
1137 ngx_quic_build_int(&p, out.len + 1); // length (inc. pnl)
1138 pnp = p;
1139
1140 *p++ = (*pkt->number)++;
1141
1142 ad.len = p - ad.data;
1143
1144 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len);
1145
1146 if (ngx_quic_ciphers(c, &ciphers, pkt->level) == NGX_ERROR) {
1147 return NGX_ERROR;
1148 }
1149
1150 nonce = ngx_pstrdup(c->pool, &pkt->secret->iv);
1151 if (pkt->level == ssl_encryption_handshake) {
1152 nonce[11] ^= (*pkt->number - 1);
1153 }
1154
1155 ngx_quic_hexdump0(c->log, "server_iv", pkt->secret->iv.data, 12);
1156 ngx_quic_hexdump0(c->log, "nonce", nonce, 12);
1157
1158 if (ngx_quic_tls_seal(c, ciphers.c, pkt->secret, &out, nonce, payload, &ad)
1159 != NGX_OK)
1160 {
1161 return NGX_ERROR;
1162 }
1163
1164 sample = &out.data[3]; // pnl=0
1165 if (ngx_quic_tls_hp(c, ciphers.hp, pkt->secret, mask, sample) != NGX_OK) {
1166 return NGX_ERROR;
1167 }
1168
1169 ngx_quic_hexdump0(c->log, "sample", sample, 16);
1170 ngx_quic_hexdump0(c->log, "mask", mask, 16);
1171 ngx_quic_hexdump0(c->log, "hp_key", pkt->secret->hp.data, 16);
1172
1173 // header protection, pnl = 0
1174 ad.data[0] ^= mask[0] & 0x0f;
1175 *pnp ^= mask[1];
1176
1177 packet = ngx_alloc(ad.len + out.len, c->log);
1178 if (packet == 0) {
1179 return NGX_ERROR;
1180 }
1181
1182 p = ngx_cpymem(packet, ad.data, ad.len);
1183 p = ngx_cpymem(p, out.data, out.len);
1184
1185 res->data = packet;
1186 res->len = p - packet;
1187
1188 return NGX_OK;
1189 }
1190
1191
1192 static ngx_int_t
1193 ngx_quic_create_short_packet(ngx_connection_t *c, ngx_ssl_conn_t *ssl_conn,
1194 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res)
1195 {
1196 u_char *p, *pnp, *nonce, *sample, *packet;
1197 ngx_str_t ad, out;
1198 ngx_quic_ciphers_t ciphers;
1199 ngx_quic_connection_t *qc;
1200 u_char mask[16];
1201
1202 qc = c->quic;
1203
1204 out.len = payload->len + EVP_GCM_TLS_TAG_LEN;
1205
1206 ad.data = ngx_alloc(25 /*max header*/, c->log);
1207 if (ad.data == 0) {
1208 return NGX_ERROR;
1209 }
1210
1211 p = ad.data;
1212
1213 *p++ = 0x40;
1214
1215 p = ngx_cpymem(p, qc->scid.data, qc->scid.len);
1216
1217 pnp = p;
1218
1219 *p++ = (*pkt->number)++;
1220
1221 ad.len = p - ad.data;
1222
1223 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len);
1224
1225 if (ngx_quic_ciphers(c, &ciphers, pkt->level) == NGX_ERROR) {
1226 return NGX_ERROR;
1227 }
1228
1229 nonce = ngx_pstrdup(c->pool, &pkt->secret->iv);
1230 if (pkt->level == ssl_encryption_handshake
1231 || pkt->level == ssl_encryption_application)
1232 {
1233 nonce[11] ^= (*pkt->number - 1);
1234 }
1235
1236 ngx_quic_hexdump0(c->log, "server_iv", pkt->secret->iv.data, 12);
1237 ngx_quic_hexdump0(c->log, "nonce", nonce, 12);
1238
1239 if (ngx_quic_tls_seal(c, ciphers.c, pkt->secret, &out, nonce, payload, &ad)
1240 != NGX_OK)
1241 {
1242 return NGX_ERROR;
1243 }
1244
1245 ngx_quic_hexdump0(c->log, "out", out.data, out.len);
1246
1247 sample = &out.data[3]; // pnl=0
1248 if (ngx_quic_tls_hp(c, ciphers.hp, pkt->secret, mask, sample) != NGX_OK) {
1249 return NGX_ERROR;
1250 }
1251
1252 ngx_quic_hexdump0(c->log, "sample", sample, 16);
1253 ngx_quic_hexdump0(c->log, "mask", mask, 16);
1254 ngx_quic_hexdump0(c->log, "hp_key", pkt->secret->hp.data, 16);
1255
1256 // header protection, pnl = 0
1257 ad.data[0] ^= mask[0] & 0x1f;
1258 *pnp ^= mask[1];
1259
1260 packet = ngx_alloc(ad.len + out.len, c->log);
1261 if (packet == 0) {
1262 return NGX_ERROR;
1263 }
1264
1265 p = ngx_cpymem(packet, ad.data, ad.len);
1266 p = ngx_cpymem(p, out.data, out.len);
1267
1268 ngx_quic_hexdump0(c->log, "packet", packet, p - packet);
1269
1270 res->data = packet;
1271 res->len = p - packet;
1272
1273 return NGX_OK;
1274 }
1275 783
1276 784
1277 static void 785 static void
1278 ngx_quic_queue_frame(ngx_quic_connection_t *qc, ngx_quic_frame_t *frame) 786 ngx_quic_queue_frame(ngx_quic_connection_t *qc, ngx_quic_frame_t *frame)
1279 { 787 {
1498 1006
1499 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, 1007 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
1500 "quic packet length: %d", plen); 1008 "quic packet length: %d", plen);
1501 1009
1502 return NGX_OK; 1010 return NGX_OK;
1503 }
1504
1505
1506 static ngx_int_t
1507 ngx_quic_initial_secret(ngx_connection_t *c)
1508 {
1509 size_t is_len;
1510 uint8_t is[SHA256_DIGEST_LENGTH];
1511 ngx_uint_t i;
1512 const EVP_MD *digest;
1513 const EVP_CIPHER *cipher;
1514 ngx_quic_connection_t *qc;
1515
1516 static const uint8_t salt[20] =
1517 "\xc3\xee\xf7\x12\xc7\x2e\xbb\x5a\x11\xa7"
1518 "\xd2\x43\x2b\xb4\x63\x65\xbe\xf9\xf5\x02";
1519
1520 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.3 */
1521
1522 cipher = EVP_aes_128_gcm();
1523 digest = EVP_sha256();
1524
1525 qc = c->quic;
1526
1527 if (ngx_hkdf_extract(is, &is_len, digest, qc->dcid.data, qc->dcid.len,
1528 salt, sizeof(salt))
1529 != NGX_OK)
1530 {
1531 return NGX_ERROR;
1532 }
1533
1534 ngx_str_t iss = {
1535 .data = is,
1536 .len = is_len
1537 };
1538
1539 ngx_quic_hexdump0(c->log, "salt", salt, sizeof(salt));
1540 ngx_quic_hexdump0(c->log, "initial secret", is, is_len);
1541
1542 /* draft-ietf-quic-tls-23#section-5.2 */
1543 qc->client_in.secret.len = SHA256_DIGEST_LENGTH;
1544 qc->server_in.secret.len = SHA256_DIGEST_LENGTH;
1545
1546 qc->client_in.key.len = EVP_CIPHER_key_length(cipher);
1547 qc->server_in.key.len = EVP_CIPHER_key_length(cipher);
1548
1549 qc->client_in.hp.len = EVP_CIPHER_key_length(cipher);
1550 qc->server_in.hp.len = EVP_CIPHER_key_length(cipher);
1551
1552 qc->client_in.iv.len = EVP_CIPHER_iv_length(cipher);
1553 qc->server_in.iv.len = EVP_CIPHER_iv_length(cipher);
1554
1555 struct {
1556 ngx_str_t label;
1557 ngx_str_t *key;
1558 ngx_str_t *prk;
1559 } seq[] = {
1560
1561 /* draft-ietf-quic-tls-23#section-5.2 */
1562 { ngx_string("tls13 client in"), &qc->client_in.secret, &iss },
1563 {
1564 ngx_string("tls13 quic key"),
1565 &qc->client_in.key,
1566 &qc->client_in.secret,
1567 },
1568 {
1569 ngx_string("tls13 quic iv"),
1570 &qc->client_in.iv,
1571 &qc->client_in.secret,
1572 },
1573 {
1574 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */
1575 ngx_string("tls13 quic hp"),
1576 &qc->client_in.hp,
1577 &qc->client_in.secret,
1578 },
1579 { ngx_string("tls13 server in"), &qc->server_in.secret, &iss },
1580 {
1581 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.3 */
1582 ngx_string("tls13 quic key"),
1583 &qc->server_in.key,
1584 &qc->server_in.secret,
1585 },
1586 {
1587 ngx_string("tls13 quic iv"),
1588 &qc->server_in.iv,
1589 &qc->server_in.secret,
1590 },
1591 {
1592 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */
1593 ngx_string("tls13 quic hp"),
1594 &qc->server_in.hp,
1595 &qc->server_in.secret,
1596 },
1597
1598 };
1599
1600 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
1601
1602 if (ngx_quic_hkdf_expand(c, digest, seq[i].key, &seq[i].label,
1603 seq[i].prk->data, seq[i].prk->len)
1604 != NGX_OK)
1605 {
1606 return NGX_ERROR;
1607 }
1608 }
1609
1610 return NGX_OK;
1611 }
1612
1613
1614 static ngx_int_t
1615 ngx_quic_decrypt(ngx_connection_t *c, ngx_quic_header_t *pkt)
1616 {
1617 u_char clearflags, *p, *sample;
1618 uint8_t *nonce;
1619 uint64_t pn;
1620 ngx_int_t pnl, rc;
1621 ngx_str_t in, ad;
1622 ngx_quic_ciphers_t ciphers;
1623 uint8_t mask[16];
1624
1625 if (ngx_quic_ciphers(c, &ciphers, pkt->level) == NGX_ERROR) {
1626 return NGX_ERROR;
1627 }
1628
1629 p = pkt->raw->pos;
1630
1631 /* draft-ietf-quic-tls-23#section-5.4.2:
1632 * the Packet Number field is assumed to be 4 bytes long
1633 * draft-ietf-quic-tls-23#section-5.4.[34]:
1634 * AES-Based and ChaCha20-Based header protections sample 16 bytes
1635 */
1636
1637 sample = p + 4;
1638
1639 ngx_quic_hexdump0(c->log, "sample", sample, 16);
1640
1641 /* header protection */
1642
1643 if (ngx_quic_tls_hp(c, ciphers.hp, pkt->secret, mask, sample) != NGX_OK) {
1644 return NGX_ERROR;
1645 }
1646
1647 if (pkt->flags & NGX_QUIC_PKT_LONG) {
1648 clearflags = pkt->flags ^ (mask[0] & 0x0f);
1649
1650 } else {
1651 clearflags = pkt->flags ^ (mask[0] & 0x1f);
1652 }
1653
1654 pnl = (clearflags & 0x03) + 1;
1655 pn = ngx_quic_parse_pn(&p, pnl, &mask[1]);
1656
1657 pkt->pn = pn;
1658
1659 ngx_quic_hexdump0(c->log, "mask", mask, 5);
1660 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
1661 "quic clear flags: %xi", clearflags);
1662 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
1663 "quic packet number: %uL, len: %xi", pn, pnl);
1664
1665 /* packet protection */
1666
1667 in.data = p;
1668
1669 if (pkt->flags & NGX_QUIC_PKT_LONG) {
1670 in.len = pkt->len - pnl;
1671
1672 } else {
1673 in.len = pkt->data + pkt->len - p;
1674 }
1675
1676 ad.len = p - pkt->data;
1677 ad.data = ngx_pnalloc(c->pool, ad.len);
1678 if (ad.data == NULL) {
1679 return NGX_ERROR;
1680 }
1681
1682 ngx_memcpy(ad.data, pkt->data, ad.len);
1683 ad.data[0] = clearflags;
1684
1685 do {
1686 ad.data[ad.len - pnl] = pn >> (8 * (pnl - 1)) % 256;
1687 } while (--pnl);
1688
1689 nonce = ngx_pstrdup(c->pool, &pkt->secret->iv);
1690 nonce[11] ^= pn;
1691
1692 ngx_quic_hexdump0(c->log, "nonce", nonce, 12);
1693 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len);
1694
1695 rc = ngx_quic_tls_open(c, ciphers.c, pkt->secret, &pkt->payload,
1696 nonce, &in, &ad);
1697
1698 ngx_quic_hexdump0(c->log, "packet payload",
1699 pkt->payload.data, pkt->payload.len);
1700
1701 return rc;
1702 } 1011 }
1703 1012
1704 1013
1705 ssize_t 1014 ssize_t
1706 ngx_quic_read_frame(ngx_connection_t *c, u_char *start, u_char *end, 1015 ngx_quic_read_frame(ngx_connection_t *c, u_char *start, u_char *end,
1889 } 1198 }
1890 1199
1891 1200
1892 1201
1893 static ngx_int_t 1202 static ngx_int_t
1894 ngx_quic_init_connection(ngx_connection_t *c, ngx_quic_header_t *pkt) 1203 ngx_quic_init_connection(ngx_connection_t *c)
1895 { 1204 {
1896 int n, sslerr; 1205 int n, sslerr;
1897 ngx_ssl_conn_t *ssl_conn; 1206 ngx_ssl_conn_t *ssl_conn;
1898 ngx_quic_connection_t *qc; 1207 ngx_quic_connection_t *qc;
1899 1208
2442 return NGX_ERROR; 1751 return NGX_ERROR;
2443 } 1752 }
2444 ngx_memcpy(qc->token.data, pkt->token.data, qc->token.len); 1753 ngx_memcpy(qc->token.data, pkt->token.data, qc->token.len);
2445 1754
2446 1755
2447 if (ngx_quic_initial_secret(c) != NGX_OK) { 1756 if (ngx_quic_set_initial_secret(c->pool, &qc->secrets, &qc->dcid)
2448 return NGX_ERROR; 1757 != NGX_OK)
2449 } 1758 {
2450 1759 return NGX_ERROR;
2451 pkt->secret = &qc->client_in; 1760 }
1761
1762 pkt->secret = &qc->secrets.client.in;
2452 pkt->level = ssl_encryption_initial; 1763 pkt->level = ssl_encryption_initial;
2453 1764
2454 if (ngx_quic_decrypt(c, pkt) != NGX_OK) { 1765 if (ngx_quic_decrypt(c->pool, NULL, pkt) != NGX_OK) {
2455 return NGX_ERROR; 1766 return NGX_ERROR;
2456 } 1767 }
2457 1768
2458 if (ngx_quic_init_connection(c, pkt) != NGX_OK) { 1769 if (ngx_quic_init_connection(c) != NGX_OK) {
2459 return NGX_ERROR; 1770 return NGX_ERROR;
2460 } 1771 }
2461 1772
2462 return ngx_quic_payload_handler(c, pkt); 1773 return ngx_quic_payload_handler(c, pkt);
2463 } 1774 }
2505 1816
2506 if (ngx_quic_process_handshake_header(c, pkt) != NGX_OK) { 1817 if (ngx_quic_process_handshake_header(c, pkt) != NGX_OK) {
2507 return NGX_ERROR; 1818 return NGX_ERROR;
2508 } 1819 }
2509 1820
2510 pkt->secret = &qc->client_hs; 1821 pkt->secret = &qc->secrets.client.hs;
2511 pkt->level = ssl_encryption_handshake; 1822 pkt->level = ssl_encryption_handshake;
2512 1823
2513 if (ngx_quic_decrypt(c, pkt) != NGX_OK) { 1824 if (ngx_quic_decrypt(c->pool, c->ssl->connection, pkt) != NGX_OK) {
2514 return NGX_ERROR; 1825 return NGX_ERROR;
2515 } 1826 }
2516 1827
2517 return ngx_quic_payload_handler(c, pkt); 1828 return ngx_quic_payload_handler(c, pkt);
2518 } 1829 }
2529 1840
2530 if (ngx_quic_process_short_header(c, pkt) != NGX_OK) { 1841 if (ngx_quic_process_short_header(c, pkt) != NGX_OK) {
2531 return NGX_ERROR; 1842 return NGX_ERROR;
2532 } 1843 }
2533 1844
2534 pkt->secret = &qc->client_ad; 1845 pkt->secret = &qc->secrets.client.ad;
2535 pkt->level = ssl_encryption_application; 1846 pkt->level = ssl_encryption_application;
2536 1847
2537 if (ngx_quic_decrypt(c, pkt) != NGX_OK) { 1848 if (ngx_quic_decrypt(c->pool, c->ssl->connection, pkt) != NGX_OK) {
2538 return NGX_ERROR; 1849 return NGX_ERROR;
2539 } 1850 }
2540 1851
2541 return ngx_quic_payload_handler(c, pkt); 1852 return ngx_quic_payload_handler(c, pkt);
2542 } 1853 }
2589 1900
2590 *pos = p; 1901 *pos = p;
2591 // return len2; 1902 // return len2;
2592 } 1903 }
2593 1904
2594
2595 static uint64_t
2596 ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask)
2597 {
2598 u_char *p;
2599 uint64_t value;
2600
2601 p = *pos;
2602 value = *p++ ^ *mask++;
2603
2604 while (--len) {
2605 value = (value << 8) + (*p++ ^ *mask++);
2606 }
2607
2608 *pos = p;
2609 return value;
2610 }
2611
2612
2613 static ngx_int_t
2614 ngx_hkdf_extract(u_char *out_key, size_t *out_len, const EVP_MD *digest,
2615 const u_char *secret, size_t secret_len, const u_char *salt,
2616 size_t salt_len)
2617 {
2618 #ifdef OPENSSL_IS_BORINGSSL
2619 if (HKDF_extract(out_key, out_len, digest, secret, secret_len, salt,
2620 salt_len)
2621 == 0)
2622 {
2623 return NGX_ERROR;
2624 }
2625 #else
2626
2627 EVP_PKEY_CTX *pctx;
2628
2629 pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
2630
2631 if (EVP_PKEY_derive_init(pctx) <= 0) {
2632 return NGX_ERROR;
2633 }
2634
2635 if (EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) <= 0) {
2636 return NGX_ERROR;
2637 }
2638
2639 if (EVP_PKEY_CTX_set_hkdf_md(pctx, digest) <= 0) {
2640 return NGX_ERROR;
2641 }
2642
2643 if (EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, secret_len) <= 0) {
2644 return NGX_ERROR;
2645 }
2646
2647 if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, salt_len) <= 0) {
2648 return NGX_ERROR;
2649 }
2650
2651 if (EVP_PKEY_derive(pctx, out_key, out_len) <= 0) {
2652 return NGX_ERROR;
2653 }
2654
2655 #endif
2656
2657 return NGX_OK;
2658 }
2659
2660
2661 static ngx_int_t
2662 ngx_quic_hkdf_expand(ngx_connection_t *c, const EVP_MD *digest, ngx_str_t *out,
2663 ngx_str_t *label, const uint8_t *prk, size_t prk_len)
2664 {
2665 uint8_t *p;
2666 size_t info_len;
2667 uint8_t info[20];
2668
2669 out->data = ngx_pnalloc(c->pool, out->len);
2670 if (out->data == NULL) {
2671 return NGX_ERROR;
2672 }
2673
2674 info_len = 2 + 1 + label->len + 1;
2675
2676 info[0] = 0;
2677 info[1] = out->len;
2678 info[2] = label->len;
2679 p = ngx_cpymem(&info[3], label->data, label->len);
2680 *p = '\0';
2681
2682 if (ngx_hkdf_expand(out->data, out->len, digest,
2683 prk, prk_len, info, info_len)
2684 != NGX_OK)
2685 {
2686 ngx_ssl_error(NGX_LOG_INFO, c->log, 0,
2687 "ngx_hkdf_expand(%V) failed", label);
2688 return NGX_ERROR;
2689 }
2690
2691 ngx_quic_hexdump(c->log, "%V info", info, info_len, label);
2692 ngx_quic_hexdump(c->log, "%V key", out->data, out->len, label);
2693
2694 return NGX_OK;
2695 }
2696
2697
2698 static ngx_int_t
2699 ngx_hkdf_expand(u_char *out_key, size_t out_len, const EVP_MD *digest,
2700 const uint8_t *prk, size_t prk_len, const u_char *info, size_t info_len)
2701 {
2702 #ifdef OPENSSL_IS_BORINGSSL
2703 if (HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len)
2704 == 0)
2705 {
2706 return NGX_ERROR;
2707 }
2708 #else
2709
2710 EVP_PKEY_CTX *pctx;
2711
2712 pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
2713
2714 if (EVP_PKEY_derive_init(pctx) <= 0) {
2715 return NGX_ERROR;
2716 }
2717
2718 if (EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) <= 0) {
2719 return NGX_ERROR;
2720 }
2721
2722 if (EVP_PKEY_CTX_set_hkdf_md(pctx, digest) <= 0) {
2723 return NGX_ERROR;
2724 }
2725
2726 if (EVP_PKEY_CTX_set1_hkdf_key(pctx, prk, prk_len) <= 0) {
2727 return NGX_ERROR;
2728 }
2729
2730 if (EVP_PKEY_CTX_add1_hkdf_info(pctx, info, info_len) <= 0) {
2731 return NGX_ERROR;
2732 }
2733
2734 if (EVP_PKEY_derive(pctx, out_key, &out_len) <= 0) {
2735 return NGX_ERROR;
2736 }
2737
2738 #endif
2739
2740 return NGX_OK;
2741 }
2742
2743
2744 static ngx_int_t
2745 ngx_quic_tls_open(ngx_connection_t *c, const ngx_quic_cipher_t *cipher,
2746 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in,
2747 ngx_str_t *ad)
2748 {
2749 out->len = in->len - EVP_GCM_TLS_TAG_LEN;
2750 out->data = ngx_pnalloc(c->pool, out->len);
2751 if (out->data == NULL) {
2752 return NGX_ERROR;
2753 }
2754
2755 #ifdef OPENSSL_IS_BORINGSSL
2756 EVP_AEAD_CTX *ctx;
2757
2758 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len,
2759 EVP_AEAD_DEFAULT_TAG_LENGTH);
2760 if (ctx == NULL) {
2761 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_AEAD_CTX_new() failed");
2762 return NGX_ERROR;
2763 }
2764
2765 if (EVP_AEAD_CTX_open(ctx, out->data, &out->len, out->len, nonce, s->iv.len,
2766 in->data, in->len, ad->data, ad->len)
2767 != 1)
2768 {
2769 EVP_AEAD_CTX_free(ctx);
2770 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_AEAD_CTX_open() failed");
2771 return NGX_ERROR;
2772 }
2773
2774 EVP_AEAD_CTX_free(ctx);
2775 #else
2776 int len;
2777 u_char *tag;
2778 EVP_CIPHER_CTX *ctx;
2779
2780 ctx = EVP_CIPHER_CTX_new();
2781 if (ctx == NULL) {
2782 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_CIPHER_CTX_new() failed");
2783 return NGX_ERROR;
2784 }
2785
2786 if (EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) {
2787 EVP_CIPHER_CTX_free(ctx);
2788 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_DecryptInit_ex() failed");
2789 return NGX_ERROR;
2790 }
2791
2792 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, s->iv.len, NULL)
2793 == 0)
2794 {
2795 EVP_CIPHER_CTX_free(ctx);
2796 ngx_ssl_error(NGX_LOG_INFO, c->log, 0,
2797 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_SET_IVLEN) failed");
2798 return NGX_ERROR;
2799 }
2800
2801 if (EVP_DecryptInit_ex(ctx, NULL, NULL, s->key.data, nonce) != 1) {
2802 EVP_CIPHER_CTX_free(ctx);
2803 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_DecryptInit_ex() failed");
2804 return NGX_ERROR;
2805 }
2806
2807 if (EVP_DecryptUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) {
2808 EVP_CIPHER_CTX_free(ctx);
2809 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_DecryptUpdate() failed");
2810 return NGX_ERROR;
2811 }
2812
2813 if (EVP_DecryptUpdate(ctx, out->data, &len, in->data,
2814 in->len - EVP_GCM_TLS_TAG_LEN)
2815 != 1)
2816 {
2817 EVP_CIPHER_CTX_free(ctx);
2818 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_DecryptUpdate() failed");
2819 return NGX_ERROR;
2820 }
2821
2822 out->len = len;
2823 tag = in->data + in->len - EVP_GCM_TLS_TAG_LEN;
2824
2825 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, EVP_GCM_TLS_TAG_LEN, tag)
2826 == 0)
2827 {
2828 EVP_CIPHER_CTX_free(ctx);
2829 ngx_ssl_error(NGX_LOG_INFO, c->log, 0,
2830 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_SET_TAG) failed");
2831 return NGX_ERROR;
2832 }
2833
2834 if (EVP_DecryptFinal_ex(ctx, out->data + len, &len) <= 0) {
2835 EVP_CIPHER_CTX_free(ctx);
2836 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_DecryptFinal_ex failed");
2837 return NGX_ERROR;
2838 }
2839
2840 out->len += len;
2841
2842 EVP_CIPHER_CTX_free(ctx);
2843 #endif
2844
2845 return NGX_OK;
2846 }
2847
2848
2849 static ngx_int_t
2850 ngx_quic_tls_seal(ngx_connection_t *c, const ngx_quic_cipher_t *cipher,
2851 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in,
2852 ngx_str_t *ad)
2853 {
2854 out->len = in->len + EVP_GCM_TLS_TAG_LEN;
2855 out->data = ngx_pnalloc(c->pool, out->len);
2856 if (out->data == NULL) {
2857 return NGX_ERROR;
2858 }
2859
2860 #ifdef OPENSSL_IS_BORINGSSL
2861 EVP_AEAD_CTX *ctx;
2862
2863 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len,
2864 EVP_AEAD_DEFAULT_TAG_LENGTH);
2865 if (ctx == NULL) {
2866 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_AEAD_CTX_new() failed");
2867 return NGX_ERROR;
2868 }
2869
2870 if (EVP_AEAD_CTX_seal(ctx, out->data, &out->len, out->len, nonce, s->iv.len,
2871 in->data, in->len, ad->data, ad->len)
2872 != 1)
2873 {
2874 EVP_AEAD_CTX_free(ctx);
2875 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_AEAD_CTX_seal() failed");
2876 return NGX_ERROR;
2877 }
2878
2879 EVP_AEAD_CTX_free(ctx);
2880 #else
2881 int len;
2882 EVP_CIPHER_CTX *ctx;
2883
2884 ctx = EVP_CIPHER_CTX_new();
2885 if (ctx == NULL) {
2886 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_CIPHER_CTX_new() failed");
2887 return NGX_ERROR;
2888 }
2889
2890 if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) {
2891 EVP_CIPHER_CTX_free(ctx);
2892 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptInit_ex() failed");
2893 return NGX_ERROR;
2894 }
2895
2896 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, s->iv.len, NULL)
2897 == 0)
2898 {
2899 EVP_CIPHER_CTX_free(ctx);
2900 ngx_ssl_error(NGX_LOG_INFO, c->log, 0,
2901 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_SET_IVLEN) failed");
2902 return NGX_ERROR;
2903 }
2904
2905 if (EVP_EncryptInit_ex(ctx, NULL, NULL, s->key.data, nonce) != 1) {
2906 EVP_CIPHER_CTX_free(ctx);
2907 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptInit_ex() failed");
2908 return NGX_ERROR;
2909 }
2910
2911 if (EVP_EncryptUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) {
2912 EVP_CIPHER_CTX_free(ctx);
2913 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptUpdate() failed");
2914 return NGX_ERROR;
2915 }
2916
2917 if (EVP_EncryptUpdate(ctx, out->data, &len, in->data, in->len) != 1) {
2918 EVP_CIPHER_CTX_free(ctx);
2919 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptUpdate() failed");
2920 return NGX_ERROR;
2921 }
2922
2923 out->len = len;
2924
2925 if (EVP_EncryptFinal_ex(ctx, out->data + out->len, &len) <= 0) {
2926 EVP_CIPHER_CTX_free(ctx);
2927 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptFinal_ex failed");
2928 return NGX_ERROR;
2929 }
2930
2931 out->len += len;
2932
2933 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, EVP_GCM_TLS_TAG_LEN,
2934 out->data + in->len)
2935 == 0)
2936 {
2937 EVP_CIPHER_CTX_free(ctx);
2938 ngx_ssl_error(NGX_LOG_INFO, c->log, 0,
2939 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_GET_TAG) failed");
2940 return NGX_ERROR;
2941 }
2942
2943 EVP_CIPHER_CTX_free(ctx);
2944
2945 out->len += EVP_GCM_TLS_TAG_LEN;
2946 #endif
2947
2948 return NGX_OK;
2949 }
2950
2951
2952 static ngx_int_t
2953 ngx_quic_tls_hp(ngx_connection_t *c, const EVP_CIPHER *cipher,
2954 ngx_quic_secret_t *s, u_char *out, u_char *in)
2955 {
2956 int outlen;
2957 EVP_CIPHER_CTX *ctx;
2958 u_char zero[5] = {0};
2959
2960 #ifdef OPENSSL_IS_BORINGSSL
2961 uint32_t counter;
2962
2963 ngx_memcpy(&counter, in, sizeof(uint32_t));
2964
2965 if (cipher == (const EVP_CIPHER *) EVP_aead_chacha20_poly1305()) {
2966 CRYPTO_chacha_20(out, zero, 5, s->hp.data, &in[4], counter);
2967 return NGX_OK;
2968 }
2969 #endif
2970
2971 ctx = EVP_CIPHER_CTX_new();
2972 if (ctx == NULL) {
2973 return NGX_ERROR;
2974 }
2975
2976 if (EVP_EncryptInit_ex(ctx, cipher, NULL, s->hp.data, in) != 1) {
2977 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptInit_ex() failed");
2978 goto failed;
2979 }
2980
2981 if (!EVP_EncryptUpdate(ctx, out, &outlen, zero, 5)) {
2982 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptUpdate() failed");
2983 goto failed;
2984 }
2985
2986 if (!EVP_EncryptFinal_ex(ctx, out + 5, &outlen)) {
2987 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptFinal_Ex() failed");
2988 goto failed;
2989 }
2990
2991 EVP_CIPHER_CTX_free(ctx);
2992
2993 return NGX_OK;
2994
2995 failed:
2996
2997 EVP_CIPHER_CTX_free(ctx);
2998
2999 return NGX_ERROR;
3000 }
3001
3002
3003 static ngx_int_t
3004 ngx_quic_ciphers(ngx_connection_t *c, ngx_quic_ciphers_t *ciphers,
3005 enum ssl_encryption_level_t level)
3006 {
3007 ngx_int_t id, len;
3008
3009 if (level == ssl_encryption_initial) {
3010 id = NGX_AES_128_GCM_SHA256;
3011
3012 } else {
3013 id = SSL_CIPHER_get_id(SSL_get_current_cipher(c->ssl->connection))
3014 & 0xffff;
3015 }
3016
3017 switch (id) {
3018
3019 case NGX_AES_128_GCM_SHA256:
3020 #ifdef OPENSSL_IS_BORINGSSL
3021 ciphers->c = EVP_aead_aes_128_gcm();
3022 #else
3023 ciphers->c = EVP_aes_128_gcm();
3024 #endif
3025 ciphers->hp = EVP_aes_128_ctr();
3026 ciphers->d = EVP_sha256();
3027 len = 16;
3028 break;
3029
3030 case NGX_AES_256_GCM_SHA384:
3031 #ifdef OPENSSL_IS_BORINGSSL
3032 ciphers->c = EVP_aead_aes_256_gcm();
3033 #else
3034 ciphers->c = EVP_aes_256_gcm();
3035 #endif
3036 ciphers->hp = EVP_aes_256_ctr();
3037 ciphers->d = EVP_sha384();
3038 len = 32;
3039 break;
3040
3041 case NGX_CHACHA20_POLY1305_SHA256:
3042 #ifdef OPENSSL_IS_BORINGSSL
3043 ciphers->c = EVP_aead_chacha20_poly1305();
3044 #else
3045 ciphers->c = EVP_chacha20_poly1305();
3046 #endif
3047 #ifdef OPENSSL_IS_BORINGSSL
3048 ciphers->hp = (const EVP_CIPHER *) EVP_aead_chacha20_poly1305();
3049 #else
3050 ciphers->hp = EVP_chacha20();
3051 #endif
3052 ciphers->d = EVP_sha256();
3053 len = 32;
3054 break;
3055
3056 default:
3057 return NGX_ERROR;
3058 }
3059
3060 return len;
3061 }