Mercurial > hg > nginx-quic
comparison src/event/ngx_event_quic.c @ 7664:ff14b0fe9731 quic
Fixed header protection with negotiated cipher suite.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Thu, 05 Mar 2020 20:05:40 +0300 |
parents | 75a2817808bf |
children | 1297dc83a6b9 |
comparison
equal
deleted
inserted
replaced
7663:75a2817808bf | 7664:ff14b0fe9731 |
---|---|
593 ngx_quic_create_long_packet(ngx_connection_t *c, ngx_ssl_conn_t *ssl_conn, | 593 ngx_quic_create_long_packet(ngx_connection_t *c, ngx_ssl_conn_t *ssl_conn, |
594 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res) | 594 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res) |
595 { | 595 { |
596 u_char *p, *pnp, *nonce, *sample, *packet; | 596 u_char *p, *pnp, *nonce, *sample, *packet; |
597 ngx_str_t ad, out; | 597 ngx_str_t ad, out; |
598 const EVP_CIPHER *cipher; | 598 const EVP_CIPHER *cipher, *hp; |
599 ngx_quic_connection_t *qc; | 599 ngx_quic_connection_t *qc; |
600 | 600 |
601 u_char mask[16]; | 601 u_char mask[16]; |
602 | 602 |
603 qc = c->quic; | 603 qc = c->quic; |
637 if (pkt->level != ssl_encryption_initial) { | 637 if (pkt->level != ssl_encryption_initial) { |
638 switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl_conn)) & 0xffff) { | 638 switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl_conn)) & 0xffff) { |
639 | 639 |
640 case NGX_AES_128_GCM_SHA256: | 640 case NGX_AES_128_GCM_SHA256: |
641 cipher = EVP_aes_128_gcm(); | 641 cipher = EVP_aes_128_gcm(); |
642 hp = EVP_aes_128_ecb(); | |
642 break; | 643 break; |
643 | 644 |
644 case NGX_AES_256_GCM_SHA384: | 645 case NGX_AES_256_GCM_SHA384: |
645 cipher = EVP_aes_256_gcm(); | 646 cipher = EVP_aes_256_gcm(); |
647 hp = EVP_aes_256_ecb(); | |
646 break; | 648 break; |
647 | 649 |
648 default: | 650 default: |
649 return NGX_ERROR; | 651 return NGX_ERROR; |
650 } | 652 } |
651 | 653 |
652 } else { | 654 } else { |
653 cipher = EVP_aes_128_gcm(); | 655 cipher = EVP_aes_128_gcm(); |
656 hp = EVP_aes_128_ecb(); | |
654 } | 657 } |
655 | 658 |
656 nonce = ngx_pstrdup(c->pool, &pkt->secret->iv); | 659 nonce = ngx_pstrdup(c->pool, &pkt->secret->iv); |
657 if (pkt->level == ssl_encryption_handshake) { | 660 if (pkt->level == ssl_encryption_handshake) { |
658 nonce[11] ^= (*pkt->number - 1); | 661 nonce[11] ^= (*pkt->number - 1); |
664 if (ngx_quic_tls_seal(c, cipher, pkt->secret, &out, nonce, payload, &ad) != NGX_OK) { | 667 if (ngx_quic_tls_seal(c, cipher, pkt->secret, &out, nonce, payload, &ad) != NGX_OK) { |
665 return NGX_ERROR; | 668 return NGX_ERROR; |
666 } | 669 } |
667 | 670 |
668 sample = &out.data[3]; // pnl=0 | 671 sample = &out.data[3]; // pnl=0 |
669 if (ngx_quic_tls_hp(c, EVP_aes_128_ecb(), pkt->secret, mask, sample) != NGX_OK) { | 672 if (ngx_quic_tls_hp(c, hp, pkt->secret, mask, sample) != NGX_OK) { |
670 return NGX_ERROR; | 673 return NGX_ERROR; |
671 } | 674 } |
672 | 675 |
673 ngx_quic_hexdump0(c->log, "sample", sample, 16); | 676 ngx_quic_hexdump0(c->log, "sample", sample, 16); |
674 ngx_quic_hexdump0(c->log, "mask", mask, 16); | 677 ngx_quic_hexdump0(c->log, "mask", mask, 16); |
697 ngx_quic_create_short_packet(ngx_connection_t *c, ngx_ssl_conn_t *ssl_conn, | 700 ngx_quic_create_short_packet(ngx_connection_t *c, ngx_ssl_conn_t *ssl_conn, |
698 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res) | 701 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res) |
699 { | 702 { |
700 u_char *p, *pnp, *nonce, *sample, *packet; | 703 u_char *p, *pnp, *nonce, *sample, *packet; |
701 ngx_str_t ad, out; | 704 ngx_str_t ad, out; |
702 const EVP_CIPHER *cipher; | 705 const EVP_CIPHER *cipher, *hp; |
703 ngx_quic_connection_t *qc; | 706 ngx_quic_connection_t *qc; |
704 | 707 |
705 u_char mask[16]; | 708 u_char mask[16]; |
706 | 709 |
707 qc = c->quic; | 710 qc = c->quic; |
729 | 732 |
730 switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl_conn)) & 0xffff) { | 733 switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl_conn)) & 0xffff) { |
731 | 734 |
732 case NGX_AES_128_GCM_SHA256: | 735 case NGX_AES_128_GCM_SHA256: |
733 cipher = EVP_aes_128_gcm(); | 736 cipher = EVP_aes_128_gcm(); |
737 hp = EVP_aes_128_ecb(); | |
734 break; | 738 break; |
735 | 739 |
736 case NGX_AES_256_GCM_SHA384: | 740 case NGX_AES_256_GCM_SHA384: |
737 cipher = EVP_aes_256_gcm(); | 741 cipher = EVP_aes_256_gcm(); |
742 hp = EVP_aes_256_ecb(); | |
738 break; | 743 break; |
739 | 744 |
740 default: | 745 default: |
741 return NGX_ERROR; | 746 return NGX_ERROR; |
742 } | 747 } |
756 } | 761 } |
757 | 762 |
758 ngx_quic_hexdump0(c->log, "out", out.data, out.len); | 763 ngx_quic_hexdump0(c->log, "out", out.data, out.len); |
759 | 764 |
760 sample = &out.data[3]; // pnl=0 | 765 sample = &out.data[3]; // pnl=0 |
761 if (ngx_quic_tls_hp(c, EVP_aes_128_ecb(), pkt->secret, mask, sample) | 766 if (ngx_quic_tls_hp(c, hp, pkt->secret, mask, sample) != NGX_OK) { |
762 != NGX_OK) | |
763 { | |
764 return NGX_ERROR; | 767 return NGX_ERROR; |
765 } | 768 } |
766 | 769 |
767 ngx_quic_hexdump0(c->log, "sample", sample, 16); | 770 ngx_quic_hexdump0(c->log, "sample", sample, 16); |
768 ngx_quic_hexdump0(c->log, "mask", mask, 16); | 771 ngx_quic_hexdump0(c->log, "mask", mask, 16); |
1111 uint8_t *nonce; | 1114 uint8_t *nonce; |
1112 uint64_t pn; | 1115 uint64_t pn; |
1113 ngx_int_t pnl, rc; | 1116 ngx_int_t pnl, rc; |
1114 ngx_str_t in, ad; | 1117 ngx_str_t in, ad; |
1115 | 1118 |
1116 const EVP_CIPHER *cipher; | 1119 const EVP_CIPHER *cipher, *hp; |
1117 | 1120 |
1118 uint8_t mask[16]; | 1121 uint8_t mask[16]; |
1122 | |
1123 if (c->ssl) { | |
1124 switch (SSL_CIPHER_get_id(SSL_get_current_cipher(c->ssl->connection)) & 0xffff) { | |
1125 | |
1126 case NGX_AES_128_GCM_SHA256: | |
1127 cipher = EVP_aes_128_gcm(); | |
1128 hp = EVP_aes_128_ecb(); | |
1129 break; | |
1130 case NGX_AES_256_GCM_SHA384: | |
1131 cipher = EVP_aes_256_gcm(); | |
1132 hp = EVP_aes_256_ecb(); | |
1133 break; | |
1134 default: | |
1135 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher"); | |
1136 return NGX_ERROR; | |
1137 } | |
1138 | |
1139 } else { | |
1140 /* initial packets */ | |
1141 cipher = EVP_aes_128_gcm(); | |
1142 hp = EVP_aes_128_ecb(); | |
1143 } | |
1119 | 1144 |
1120 p = pkt->pos; | 1145 p = pkt->pos; |
1121 | 1146 |
1122 /* draft-ietf-quic-tls-23#section-5.4.2: | 1147 /* draft-ietf-quic-tls-23#section-5.4.2: |
1123 * the Packet Number field is assumed to be 4 bytes long | 1148 * the Packet Number field is assumed to be 4 bytes long |
1129 | 1154 |
1130 ngx_quic_hexdump0(c->log, "sample", sample, 16); | 1155 ngx_quic_hexdump0(c->log, "sample", sample, 16); |
1131 | 1156 |
1132 /* header protection */ | 1157 /* header protection */ |
1133 | 1158 |
1134 if (ngx_quic_tls_hp(c, EVP_aes_128_ecb(), pkt->secret, mask, sample) | 1159 if (ngx_quic_tls_hp(c, hp, pkt->secret, mask, sample) != NGX_OK) { |
1135 != NGX_OK) | |
1136 { | |
1137 return NGX_ERROR; | 1160 return NGX_ERROR; |
1138 } | 1161 } |
1139 | 1162 |
1140 clearflags = pkt->flags ^ (mask[0] & 0x0f); | 1163 clearflags = pkt->flags ^ (mask[0] & 0x0f); |
1141 pnl = (clearflags & 0x03) + 1; | 1164 pnl = (clearflags & 0x03) + 1; |
1167 nonce = ngx_pstrdup(c->pool, &pkt->secret->iv); | 1190 nonce = ngx_pstrdup(c->pool, &pkt->secret->iv); |
1168 nonce[11] ^= pn; | 1191 nonce[11] ^= pn; |
1169 | 1192 |
1170 ngx_quic_hexdump0(c->log, "nonce", nonce, 12); | 1193 ngx_quic_hexdump0(c->log, "nonce", nonce, 12); |
1171 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len); | 1194 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len); |
1172 | |
1173 if (c->ssl) { | |
1174 switch (SSL_CIPHER_get_id(SSL_get_current_cipher(c->ssl->connection)) & 0xffff) { | |
1175 | |
1176 case NGX_AES_128_GCM_SHA256: | |
1177 cipher = EVP_aes_128_gcm(); | |
1178 break; | |
1179 case NGX_AES_256_GCM_SHA384: | |
1180 cipher = EVP_aes_256_gcm(); | |
1181 break; | |
1182 default: | |
1183 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher"); | |
1184 return NGX_ERROR; | |
1185 } | |
1186 | |
1187 } else { | |
1188 /* initial packets */ | |
1189 cipher = EVP_aes_128_gcm(); | |
1190 } | |
1191 | 1195 |
1192 rc = ngx_quic_tls_open(c, cipher, pkt->secret, &pkt->payload, | 1196 rc = ngx_quic_tls_open(c, cipher, pkt->secret, &pkt->payload, |
1193 nonce, &in, &ad); | 1197 nonce, &in, &ad); |
1194 | 1198 |
1195 ngx_quic_hexdump0(c->log, "packet payload", | 1199 ngx_quic_hexdump0(c->log, "packet payload", |