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",