Mercurial > hg > nginx-quic
comparison src/event/ngx_event_quic.c @ 7667:5c66dadb1e34 quic
Using SSL cipher suite id to obtain cipher/digest, part 2.
Ciphers negotiation handling refactored into ngx_quic_ciphers().
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Tue, 10 Mar 2020 19:12:22 +0300 |
parents | 9582adbc7d70 |
children | a4ed2305ad2c |
comparison
equal
deleted
inserted
replaced
7666:9582adbc7d70 | 7667:5c66dadb1e34 |
---|---|
6 | 6 |
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 | 9 |
10 | 10 |
11 #define quic_version 0xff000018 | 11 #define quic_version 0xff000018 |
12 | 12 |
13 #define NGX_AES_128_GCM_SHA256 0x1301 | 13 #define NGX_AES_128_GCM_SHA256 0x1301 |
14 #define NGX_AES_256_GCM_SHA384 0x1302 | 14 #define NGX_AES_256_GCM_SHA384 0x1302 |
15 | |
16 #define NGX_QUIC_IV_LEN 12 | |
17 | |
18 #ifdef OPENSSL_IS_BORINGSSL | |
19 #define ngx_quic_cipher_t EVP_AEAD | |
20 #else | |
21 #define ngx_quic_cipher_t EVP_CIPHER | |
22 #endif | |
15 | 23 |
16 | 24 |
17 #if (NGX_HAVE_NONALIGNED) | 25 #if (NGX_HAVE_NONALIGNED) |
18 | 26 |
19 #define ngx_quic_parse_uint16(p) ntohs(*(uint16_t *) (p)) | 27 #define ngx_quic_parse_uint16(p) ntohs(*(uint16_t *) (p)) |
126 ngx_str_t key; | 134 ngx_str_t key; |
127 ngx_str_t iv; | 135 ngx_str_t iv; |
128 ngx_str_t hp; | 136 ngx_str_t hp; |
129 } ngx_quic_secret_t; | 137 } ngx_quic_secret_t; |
130 | 138 |
139 typedef struct { | |
140 const ngx_quic_cipher_t *c; | |
141 const EVP_CIPHER *hp; | |
142 const EVP_MD *d; | |
143 } ngx_quic_ciphers_t; | |
131 | 144 |
132 typedef enum ssl_encryption_level_t ngx_quic_level_t; | 145 typedef enum ssl_encryption_level_t ngx_quic_level_t; |
133 | 146 |
134 typedef struct ngx_quic_frame_s ngx_quic_frame_t; | 147 typedef struct ngx_quic_frame_s ngx_quic_frame_t; |
135 | 148 |
259 | 272 |
260 static ngx_int_t ngx_quic_hkdf_expand(ngx_connection_t *c, const EVP_MD *digest, | 273 static ngx_int_t ngx_quic_hkdf_expand(ngx_connection_t *c, const EVP_MD *digest, |
261 ngx_str_t *out, ngx_str_t *label, const uint8_t *prk, size_t prk_len); | 274 ngx_str_t *out, ngx_str_t *label, const uint8_t *prk, size_t prk_len); |
262 | 275 |
263 static ngx_int_t ngx_quic_tls_open(ngx_connection_t *c, | 276 static ngx_int_t ngx_quic_tls_open(ngx_connection_t *c, |
264 const EVP_CIPHER *cipher, ngx_quic_secret_t *s, ngx_str_t *out, | 277 const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s, ngx_str_t *out, |
265 u_char *nonce, ngx_str_t *in, ngx_str_t *ad); | 278 u_char *nonce, ngx_str_t *in, ngx_str_t *ad); |
266 static ngx_int_t ngx_quic_tls_seal(ngx_connection_t *c, | 279 static ngx_int_t ngx_quic_tls_seal(ngx_connection_t *c, |
267 const EVP_CIPHER *cipher, ngx_quic_secret_t *s, ngx_str_t *out, | 280 const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s, ngx_str_t *out, |
268 u_char *nonce, ngx_str_t *in, ngx_str_t *ad); | 281 u_char *nonce, ngx_str_t *in, ngx_str_t *ad); |
269 | 282 |
270 static ngx_int_t ngx_quic_tls_hp(ngx_connection_t *c, const EVP_CIPHER *cipher, | 283 static ngx_int_t ngx_quic_tls_hp(ngx_connection_t *c, const EVP_CIPHER *cipher, |
271 ngx_quic_secret_t *s, u_char *out, u_char *in); | 284 ngx_quic_secret_t *s, u_char *out, u_char *in); |
272 | 285 |
286 static ngx_int_t ngx_quic_ciphers(ngx_connection_t *c, | |
287 ngx_quic_ciphers_t *ciphers, enum ssl_encryption_level_t level); | |
273 | 288 |
274 static SSL_QUIC_METHOD quic_method = { | 289 static SSL_QUIC_METHOD quic_method = { |
275 ngx_quic_set_encryption_secrets, | 290 ngx_quic_set_encryption_secrets, |
276 ngx_quic_add_handshake_data, | 291 ngx_quic_add_handshake_data, |
277 ngx_quic_flush_flight, | 292 ngx_quic_flush_flight, |
516 static int | 531 static int |
517 ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, | 532 ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, |
518 enum ssl_encryption_level_t level, const uint8_t *read_secret, | 533 enum ssl_encryption_level_t level, const uint8_t *read_secret, |
519 const uint8_t *write_secret, size_t secret_len) | 534 const uint8_t *write_secret, size_t secret_len) |
520 { | 535 { |
521 ngx_uint_t i; | 536 ngx_int_t key_len; |
522 const EVP_MD *digest; | 537 ngx_uint_t i; |
523 const EVP_CIPHER *cipher; | 538 ngx_connection_t *c; |
524 ngx_connection_t *c; | 539 ngx_quic_secret_t *client, *server; |
525 ngx_quic_secret_t *client, *server; | 540 ngx_quic_ciphers_t ciphers; |
526 | 541 |
527 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); | 542 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); |
528 | 543 |
529 ngx_quic_hexdump(c->log, "level:%d read", read_secret, secret_len, level); | 544 ngx_quic_hexdump(c->log, "level:%d read", read_secret, secret_len, level); |
530 ngx_quic_hexdump(c->log, "level:%d write", write_secret, secret_len, level); | 545 ngx_quic_hexdump(c->log, "level:%d write", write_secret, secret_len, level); |
531 | 546 |
532 switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl_conn)) & 0xffff) { | 547 key_len = ngx_quic_ciphers(c, &ciphers, level); |
533 | 548 |
534 case NGX_AES_128_GCM_SHA256: | 549 if (key_len == NGX_ERROR) { |
535 cipher = EVP_aes_128_gcm(); | |
536 digest = EVP_sha256(); | |
537 break; | |
538 | |
539 case NGX_AES_256_GCM_SHA384: | |
540 cipher = EVP_aes_256_gcm(); | |
541 digest = EVP_sha384(); | |
542 break; | |
543 | |
544 default: | |
545 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher"); | 550 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher"); |
546 return 0; | 551 return 0; |
547 } | 552 } |
548 | 553 |
549 switch (level) { | 554 switch (level) { |
562 | 567 |
563 default: | 568 default: |
564 return 0; | 569 return 0; |
565 } | 570 } |
566 | 571 |
567 client->key.len = EVP_CIPHER_key_length(cipher); | 572 client->key.len = key_len; |
568 server->key.len = EVP_CIPHER_key_length(cipher); | 573 server->key.len = key_len; |
569 | 574 |
570 client->iv.len = EVP_CIPHER_iv_length(cipher); | 575 client->iv.len = NGX_QUIC_IV_LEN; |
571 server->iv.len = EVP_CIPHER_iv_length(cipher); | 576 server->iv.len = NGX_QUIC_IV_LEN; |
572 | 577 |
573 client->hp.len = EVP_CIPHER_key_length(cipher); | 578 client->hp.len = key_len; |
574 server->hp.len = EVP_CIPHER_key_length(cipher); | 579 server->hp.len = key_len; |
575 | 580 |
576 struct { | 581 struct { |
577 ngx_str_t label; | 582 ngx_str_t label; |
578 ngx_str_t *key; | 583 ngx_str_t *key; |
579 const uint8_t *secret; | 584 const uint8_t *secret; |
586 { ngx_string("tls13 quic hp"), &server->hp, write_secret }, | 591 { ngx_string("tls13 quic hp"), &server->hp, write_secret }, |
587 }; | 592 }; |
588 | 593 |
589 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) { | 594 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) { |
590 | 595 |
591 if (ngx_quic_hkdf_expand(c, digest, seq[i].key, &seq[i].label, | 596 if (ngx_quic_hkdf_expand(c, ciphers.d, seq[i].key, &seq[i].label, |
592 seq[i].secret, secret_len) | 597 seq[i].secret, secret_len) |
593 != NGX_OK) | 598 != NGX_OK) |
594 { | 599 { |
595 return 0; | 600 return 0; |
596 } | 601 } |
604 ngx_quic_create_long_packet(ngx_connection_t *c, ngx_ssl_conn_t *ssl_conn, | 609 ngx_quic_create_long_packet(ngx_connection_t *c, ngx_ssl_conn_t *ssl_conn, |
605 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res) | 610 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res) |
606 { | 611 { |
607 u_char *p, *pnp, *nonce, *sample, *packet; | 612 u_char *p, *pnp, *nonce, *sample, *packet; |
608 ngx_str_t ad, out; | 613 ngx_str_t ad, out; |
609 const EVP_CIPHER *cipher, *hp; | 614 ngx_quic_ciphers_t ciphers; |
610 ngx_quic_connection_t *qc; | 615 ngx_quic_connection_t *qc; |
611 | |
612 u_char mask[16]; | 616 u_char mask[16]; |
613 | 617 |
614 qc = c->quic; | 618 qc = c->quic; |
615 | 619 |
616 out.len = payload->len + EVP_GCM_TLS_TAG_LEN; | 620 out.len = payload->len + EVP_GCM_TLS_TAG_LEN; |
643 | 647 |
644 ad.len = p - ad.data; | 648 ad.len = p - ad.data; |
645 | 649 |
646 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len); | 650 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len); |
647 | 651 |
648 if (pkt->level != ssl_encryption_initial) { | 652 if (ngx_quic_ciphers(c, &ciphers, pkt->level) == NGX_ERROR) { |
649 switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl_conn)) & 0xffff) { | 653 return NGX_ERROR; |
650 | |
651 case NGX_AES_128_GCM_SHA256: | |
652 cipher = EVP_aes_128_gcm(); | |
653 hp = EVP_aes_128_ecb(); | |
654 break; | |
655 | |
656 case NGX_AES_256_GCM_SHA384: | |
657 cipher = EVP_aes_256_gcm(); | |
658 hp = EVP_aes_256_ecb(); | |
659 break; | |
660 | |
661 default: | |
662 return NGX_ERROR; | |
663 } | |
664 | |
665 } else { | |
666 cipher = EVP_aes_128_gcm(); | |
667 hp = EVP_aes_128_ecb(); | |
668 } | 654 } |
669 | 655 |
670 nonce = ngx_pstrdup(c->pool, &pkt->secret->iv); | 656 nonce = ngx_pstrdup(c->pool, &pkt->secret->iv); |
671 if (pkt->level == ssl_encryption_handshake) { | 657 if (pkt->level == ssl_encryption_handshake) { |
672 nonce[11] ^= (*pkt->number - 1); | 658 nonce[11] ^= (*pkt->number - 1); |
673 } | 659 } |
674 | 660 |
675 ngx_quic_hexdump0(c->log, "server_iv", pkt->secret->iv.data, 12); | 661 ngx_quic_hexdump0(c->log, "server_iv", pkt->secret->iv.data, 12); |
676 ngx_quic_hexdump0(c->log, "nonce", nonce, 12); | 662 ngx_quic_hexdump0(c->log, "nonce", nonce, 12); |
677 | 663 |
678 if (ngx_quic_tls_seal(c, cipher, pkt->secret, &out, nonce, payload, &ad) != NGX_OK) { | 664 if (ngx_quic_tls_seal(c, ciphers.c, pkt->secret, &out, nonce, payload, &ad) |
665 != NGX_OK) | |
666 { | |
679 return NGX_ERROR; | 667 return NGX_ERROR; |
680 } | 668 } |
681 | 669 |
682 sample = &out.data[3]; // pnl=0 | 670 sample = &out.data[3]; // pnl=0 |
683 if (ngx_quic_tls_hp(c, hp, pkt->secret, mask, sample) != NGX_OK) { | 671 if (ngx_quic_tls_hp(c, ciphers.hp, pkt->secret, mask, sample) != NGX_OK) { |
684 return NGX_ERROR; | 672 return NGX_ERROR; |
685 } | 673 } |
686 | 674 |
687 ngx_quic_hexdump0(c->log, "sample", sample, 16); | 675 ngx_quic_hexdump0(c->log, "sample", sample, 16); |
688 ngx_quic_hexdump0(c->log, "mask", mask, 16); | 676 ngx_quic_hexdump0(c->log, "mask", mask, 16); |
711 ngx_quic_create_short_packet(ngx_connection_t *c, ngx_ssl_conn_t *ssl_conn, | 699 ngx_quic_create_short_packet(ngx_connection_t *c, ngx_ssl_conn_t *ssl_conn, |
712 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res) | 700 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res) |
713 { | 701 { |
714 u_char *p, *pnp, *nonce, *sample, *packet; | 702 u_char *p, *pnp, *nonce, *sample, *packet; |
715 ngx_str_t ad, out; | 703 ngx_str_t ad, out; |
716 const EVP_CIPHER *cipher, *hp; | 704 ngx_quic_ciphers_t ciphers; |
717 ngx_quic_connection_t *qc; | 705 ngx_quic_connection_t *qc; |
718 | |
719 u_char mask[16]; | 706 u_char mask[16]; |
720 | 707 |
721 qc = c->quic; | 708 qc = c->quic; |
722 | 709 |
723 out.len = payload->len + EVP_GCM_TLS_TAG_LEN; | 710 out.len = payload->len + EVP_GCM_TLS_TAG_LEN; |
739 | 726 |
740 ad.len = p - ad.data; | 727 ad.len = p - ad.data; |
741 | 728 |
742 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len); | 729 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len); |
743 | 730 |
744 switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl_conn)) & 0xffff) { | 731 if (ngx_quic_ciphers(c, &ciphers, pkt->level) == NGX_ERROR) { |
745 | |
746 case NGX_AES_128_GCM_SHA256: | |
747 cipher = EVP_aes_128_gcm(); | |
748 hp = EVP_aes_128_ecb(); | |
749 break; | |
750 | |
751 case NGX_AES_256_GCM_SHA384: | |
752 cipher = EVP_aes_256_gcm(); | |
753 hp = EVP_aes_256_ecb(); | |
754 break; | |
755 | |
756 default: | |
757 return NGX_ERROR; | 732 return NGX_ERROR; |
758 } | 733 } |
759 | 734 |
760 nonce = ngx_pstrdup(c->pool, &pkt->secret->iv); | 735 nonce = ngx_pstrdup(c->pool, &pkt->secret->iv); |
761 if (pkt->level == ssl_encryption_handshake | 736 if (pkt->level == ssl_encryption_handshake |
765 } | 740 } |
766 | 741 |
767 ngx_quic_hexdump0(c->log, "server_iv", pkt->secret->iv.data, 12); | 742 ngx_quic_hexdump0(c->log, "server_iv", pkt->secret->iv.data, 12); |
768 ngx_quic_hexdump0(c->log, "nonce", nonce, 12); | 743 ngx_quic_hexdump0(c->log, "nonce", nonce, 12); |
769 | 744 |
770 if (ngx_quic_tls_seal(c, cipher, pkt->secret, &out, nonce, payload, &ad) | 745 if (ngx_quic_tls_seal(c, ciphers.c, pkt->secret, &out, nonce, payload, &ad) |
771 != NGX_OK) | 746 != NGX_OK) |
772 { | 747 { |
773 return NGX_ERROR; | 748 return NGX_ERROR; |
774 } | 749 } |
775 | 750 |
776 ngx_quic_hexdump0(c->log, "out", out.data, out.len); | 751 ngx_quic_hexdump0(c->log, "out", out.data, out.len); |
777 | 752 |
778 sample = &out.data[3]; // pnl=0 | 753 sample = &out.data[3]; // pnl=0 |
779 if (ngx_quic_tls_hp(c, hp, pkt->secret, mask, sample) != NGX_OK) { | 754 if (ngx_quic_tls_hp(c, ciphers.hp, pkt->secret, mask, sample) != NGX_OK) { |
780 return NGX_ERROR; | 755 return NGX_ERROR; |
781 } | 756 } |
782 | 757 |
783 ngx_quic_hexdump0(c->log, "sample", sample, 16); | 758 ngx_quic_hexdump0(c->log, "sample", sample, 16); |
784 ngx_quic_hexdump0(c->log, "mask", mask, 16); | 759 ngx_quic_hexdump0(c->log, "mask", mask, 16); |
1143 | 1118 |
1144 | 1119 |
1145 static ngx_int_t | 1120 static ngx_int_t |
1146 ngx_quic_decrypt(ngx_connection_t *c, ngx_quic_header_t *pkt) | 1121 ngx_quic_decrypt(ngx_connection_t *c, ngx_quic_header_t *pkt) |
1147 { | 1122 { |
1148 u_char clearflags, *p, *sample; | 1123 u_char clearflags, *p, *sample; |
1149 uint8_t *nonce; | 1124 uint8_t *nonce; |
1150 uint64_t pn; | 1125 uint64_t pn; |
1151 ngx_int_t pnl, rc; | 1126 ngx_int_t pnl, rc; |
1152 ngx_str_t in, ad; | 1127 ngx_str_t in, ad; |
1153 | 1128 ngx_quic_ciphers_t ciphers; |
1154 const EVP_CIPHER *cipher, *hp; | 1129 uint8_t mask[16]; |
1155 | 1130 |
1156 uint8_t mask[16]; | 1131 if (ngx_quic_ciphers(c, &ciphers, pkt->level) == NGX_ERROR) { |
1157 | 1132 return NGX_ERROR; |
1158 if (c->ssl) { | |
1159 switch (SSL_CIPHER_get_id(SSL_get_current_cipher(c->ssl->connection)) & 0xffff) { | |
1160 | |
1161 case NGX_AES_128_GCM_SHA256: | |
1162 cipher = EVP_aes_128_gcm(); | |
1163 hp = EVP_aes_128_ecb(); | |
1164 break; | |
1165 case NGX_AES_256_GCM_SHA384: | |
1166 cipher = EVP_aes_256_gcm(); | |
1167 hp = EVP_aes_256_ecb(); | |
1168 break; | |
1169 default: | |
1170 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher"); | |
1171 return NGX_ERROR; | |
1172 } | |
1173 | |
1174 } else { | |
1175 /* initial packets */ | |
1176 cipher = EVP_aes_128_gcm(); | |
1177 hp = EVP_aes_128_ecb(); | |
1178 } | 1133 } |
1179 | 1134 |
1180 p = pkt->pos; | 1135 p = pkt->pos; |
1181 | 1136 |
1182 /* draft-ietf-quic-tls-23#section-5.4.2: | 1137 /* draft-ietf-quic-tls-23#section-5.4.2: |
1189 | 1144 |
1190 ngx_quic_hexdump0(c->log, "sample", sample, 16); | 1145 ngx_quic_hexdump0(c->log, "sample", sample, 16); |
1191 | 1146 |
1192 /* header protection */ | 1147 /* header protection */ |
1193 | 1148 |
1194 if (ngx_quic_tls_hp(c, hp, pkt->secret, mask, sample) != NGX_OK) { | 1149 if (ngx_quic_tls_hp(c, ciphers.hp, pkt->secret, mask, sample) != NGX_OK) { |
1195 return NGX_ERROR; | 1150 return NGX_ERROR; |
1196 } | 1151 } |
1197 | 1152 |
1198 if (pkt->flags & NGX_QUIC_PKT_LONG) { | 1153 if (pkt->flags & NGX_QUIC_PKT_LONG) { |
1199 clearflags = pkt->flags ^ (mask[0] & 0x0f); | 1154 clearflags = pkt->flags ^ (mask[0] & 0x0f); |
1238 nonce[11] ^= pn; | 1193 nonce[11] ^= pn; |
1239 | 1194 |
1240 ngx_quic_hexdump0(c->log, "nonce", nonce, 12); | 1195 ngx_quic_hexdump0(c->log, "nonce", nonce, 12); |
1241 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len); | 1196 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len); |
1242 | 1197 |
1243 rc = ngx_quic_tls_open(c, cipher, pkt->secret, &pkt->payload, | 1198 rc = ngx_quic_tls_open(c, ciphers.c, pkt->secret, &pkt->payload, |
1244 nonce, &in, &ad); | 1199 nonce, &in, &ad); |
1245 | 1200 |
1246 ngx_quic_hexdump0(c->log, "packet payload", | 1201 ngx_quic_hexdump0(c->log, "packet payload", |
1247 pkt->payload.data, pkt->payload.len); | 1202 pkt->payload.data, pkt->payload.len); |
1248 | 1203 |
1880 return NGX_OK; | 1835 return NGX_OK; |
1881 } | 1836 } |
1882 | 1837 |
1883 | 1838 |
1884 static ngx_int_t | 1839 static ngx_int_t |
1885 ngx_quic_tls_open(ngx_connection_t *c, const EVP_CIPHER *cipher, | 1840 ngx_quic_tls_open(ngx_connection_t *c, const ngx_quic_cipher_t *cipher, |
1886 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, | 1841 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, |
1887 ngx_str_t *ad) | 1842 ngx_str_t *ad) |
1888 { | 1843 { |
1889 out->len = in->len - EVP_GCM_TLS_TAG_LEN; | 1844 out->len = in->len - EVP_GCM_TLS_TAG_LEN; |
1890 out->data = ngx_pnalloc(c->pool, out->len); | 1845 out->data = ngx_pnalloc(c->pool, out->len); |
1891 if (out->data == NULL) { | 1846 if (out->data == NULL) { |
1892 return NGX_ERROR; | 1847 return NGX_ERROR; |
1893 } | 1848 } |
1894 | 1849 |
1895 #ifdef OPENSSL_IS_BORINGSSLL | 1850 #ifdef OPENSSL_IS_BORINGSSL |
1896 EVP_AEAD_CTX *ctx; | 1851 EVP_AEAD_CTX *ctx; |
1897 | 1852 |
1898 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len, | 1853 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len, |
1899 EVP_AEAD_DEFAULT_TAG_LENGTH); | 1854 EVP_AEAD_DEFAULT_TAG_LENGTH); |
1900 if (ctx == NULL) { | 1855 if (ctx == NULL) { |
1985 return NGX_OK; | 1940 return NGX_OK; |
1986 } | 1941 } |
1987 | 1942 |
1988 | 1943 |
1989 static ngx_int_t | 1944 static ngx_int_t |
1990 ngx_quic_tls_seal(ngx_connection_t *c, const EVP_CIPHER *cipher, | 1945 ngx_quic_tls_seal(ngx_connection_t *c, const ngx_quic_cipher_t *cipher, |
1991 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, | 1946 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, |
1992 ngx_str_t *ad) | 1947 ngx_str_t *ad) |
1993 { | 1948 { |
1994 out->len = in->len + EVP_GCM_TLS_TAG_LEN; | 1949 out->len = in->len + EVP_GCM_TLS_TAG_LEN; |
1995 out->data = ngx_pnalloc(c->pool, out->len); | 1950 out->data = ngx_pnalloc(c->pool, out->len); |
1996 if (out->data == NULL) { | 1951 if (out->data == NULL) { |
1997 return NGX_ERROR; | 1952 return NGX_ERROR; |
1998 } | 1953 } |
1999 | 1954 |
2000 #ifdef OPENSSL_IS_BORINGSSLL | 1955 #ifdef OPENSSL_IS_BORINGSSL |
2001 EVP_AEAD_CTX *ctx; | 1956 EVP_AEAD_CTX *ctx; |
2002 | 1957 |
2003 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len, | 1958 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len, |
2004 EVP_AEAD_DEFAULT_TAG_LENGTH); | 1959 EVP_AEAD_DEFAULT_TAG_LENGTH); |
2005 if (ctx == NULL) { | 1960 if (ctx == NULL) { |
2093 ngx_quic_tls_hp(ngx_connection_t *c, const EVP_CIPHER *cipher, | 2048 ngx_quic_tls_hp(ngx_connection_t *c, const EVP_CIPHER *cipher, |
2094 ngx_quic_secret_t *s, u_char *out, u_char *in) | 2049 ngx_quic_secret_t *s, u_char *out, u_char *in) |
2095 { | 2050 { |
2096 int outlen; | 2051 int outlen; |
2097 EVP_CIPHER_CTX *ctx; | 2052 EVP_CIPHER_CTX *ctx; |
2053 u_char zero[5] = {0}; | |
2098 | 2054 |
2099 ctx = EVP_CIPHER_CTX_new(); | 2055 ctx = EVP_CIPHER_CTX_new(); |
2100 if (ctx == NULL) { | 2056 if (ctx == NULL) { |
2101 return NGX_ERROR; | 2057 return NGX_ERROR; |
2102 } | 2058 } |
2103 | 2059 |
2104 if (EVP_EncryptInit_ex(ctx, cipher, NULL, s->hp.data, NULL) != 1) { | 2060 if (EVP_EncryptInit_ex(ctx, cipher, NULL, s->hp.data, in) != 1) { |
2105 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptInit_ex() failed"); | 2061 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptInit_ex() failed"); |
2106 goto failed; | 2062 goto failed; |
2107 } | 2063 } |
2108 | 2064 |
2109 if (!EVP_EncryptUpdate(ctx, out, &outlen, in, 16)) { | 2065 if (!EVP_EncryptUpdate(ctx, out, &outlen, zero, 5)) { |
2110 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptUpdate() failed"); | 2066 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptUpdate() failed"); |
2111 goto failed; | 2067 goto failed; |
2112 } | 2068 } |
2113 | 2069 |
2070 if (!EVP_EncryptFinal_ex(ctx, out + 5, &outlen)) { | |
2071 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptFinal_Ex() failed"); | |
2072 goto failed; | |
2073 } | |
2074 | |
2114 EVP_CIPHER_CTX_free(ctx); | 2075 EVP_CIPHER_CTX_free(ctx); |
2115 | 2076 |
2116 return NGX_OK; | 2077 return NGX_OK; |
2117 | 2078 |
2118 failed: | 2079 failed: |
2119 | 2080 |
2120 EVP_CIPHER_CTX_free(ctx); | 2081 EVP_CIPHER_CTX_free(ctx); |
2121 | 2082 |
2122 return NGX_ERROR; | 2083 return NGX_ERROR; |
2123 } | 2084 } |
2085 | |
2086 | |
2087 static ngx_int_t | |
2088 ngx_quic_ciphers(ngx_connection_t *c, ngx_quic_ciphers_t *ciphers, | |
2089 enum ssl_encryption_level_t level) | |
2090 { | |
2091 ngx_int_t id, len; | |
2092 | |
2093 if (level == ssl_encryption_initial) { | |
2094 id = NGX_AES_128_GCM_SHA256; | |
2095 | |
2096 } else { | |
2097 id = SSL_CIPHER_get_id(SSL_get_current_cipher(c->ssl->connection)) | |
2098 & 0xffff; | |
2099 } | |
2100 | |
2101 switch (id) { | |
2102 | |
2103 case NGX_AES_128_GCM_SHA256: | |
2104 #ifdef OPENSSL_IS_BORINGSSL | |
2105 ciphers->c = EVP_aead_aes_128_gcm(); | |
2106 #else | |
2107 ciphers->c = EVP_aes_128_gcm(); | |
2108 #endif | |
2109 ciphers->hp = EVP_aes_128_ctr(); | |
2110 ciphers->d = EVP_sha256(); | |
2111 len = 16; | |
2112 break; | |
2113 | |
2114 case NGX_AES_256_GCM_SHA384: | |
2115 #ifdef OPENSSL_IS_BORINGSSL | |
2116 ciphers->c = EVP_aead_aes_256_gcm(); | |
2117 #else | |
2118 ciphers->c = EVP_aes_256_gcm(); | |
2119 #endif | |
2120 ciphers->hp = EVP_aes_256_ctr(); | |
2121 ciphers->d = EVP_sha384(); | |
2122 len = 32; | |
2123 break; | |
2124 | |
2125 default: | |
2126 return NGX_ERROR; | |
2127 } | |
2128 | |
2129 return len; | |
2130 } |