comparison src/event/ngx_event_quic_protection.c @ 8310:7ac890c18f5e quic

Fixed computing nonce by xoring all packet number bytes. Previously, the stub worked only with pnl=0.
author Sergey Kandaurov <pluknet@nginx.com>
date Thu, 02 Apr 2020 11:40:25 +0300
parents dc7ac778aafe
children c625bde6cb77
comparison
equal deleted inserted replaced
8309:7ea2c68735f9 8310:7ac890c18f5e
35 static ngx_int_t ngx_hkdf_extract(u_char *out_key, size_t *out_len, 35 static ngx_int_t ngx_hkdf_extract(u_char *out_key, size_t *out_len,
36 const EVP_MD *digest, const u_char *secret, size_t secret_len, 36 const EVP_MD *digest, const u_char *secret, size_t secret_len,
37 const u_char *salt, size_t salt_len); 37 const u_char *salt, size_t salt_len);
38 38
39 static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask); 39 static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask);
40 static void ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn);
40 static ngx_int_t ngx_quic_ciphers(ngx_ssl_conn_t *ssl_conn, 41 static ngx_int_t ngx_quic_ciphers(ngx_ssl_conn_t *ssl_conn,
41 ngx_quic_ciphers_t *ciphers, enum ssl_encryption_level_t level); 42 ngx_quic_ciphers_t *ciphers, enum ssl_encryption_level_t level);
42 43
43 static ngx_int_t ngx_quic_tls_open(const ngx_quic_cipher_t *cipher, 44 static ngx_int_t ngx_quic_tls_open(const ngx_quic_cipher_t *cipher,
44 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, 45 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in,
652 static ssize_t 653 static ssize_t
653 ngx_quic_create_long_packet(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn, 654 ngx_quic_create_long_packet(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn,
654 ngx_str_t *res) 655 ngx_str_t *res)
655 { 656 {
656 u_char *pnp, *sample; 657 u_char *pnp, *sample;
657 uint64_t pn;
658 ngx_str_t ad, out; 658 ngx_str_t ad, out;
659 ngx_quic_ciphers_t ciphers; 659 ngx_quic_ciphers_t ciphers;
660 u_char nonce[12], mask[16]; 660 u_char nonce[12], mask[16];
661 661
662 out.len = pkt->payload.len + EVP_GCM_TLS_TAG_LEN; 662 out.len = pkt->payload.len + EVP_GCM_TLS_TAG_LEN;
671 if (ngx_quic_ciphers(ssl_conn, &ciphers, pkt->level) == NGX_ERROR) { 671 if (ngx_quic_ciphers(ssl_conn, &ciphers, pkt->level) == NGX_ERROR) {
672 return NGX_ERROR; 672 return NGX_ERROR;
673 } 673 }
674 674
675 ngx_memcpy(nonce, pkt->secret->iv.data, pkt->secret->iv.len); 675 ngx_memcpy(nonce, pkt->secret->iv.data, pkt->secret->iv.len);
676 pn = pkt->number; 676 ngx_quic_compute_nonce(nonce, sizeof(nonce), pkt->number);
677 nonce[11] ^= pn;
678 677
679 ngx_quic_hexdump0(pkt->log, "server_iv", pkt->secret->iv.data, 12); 678 ngx_quic_hexdump0(pkt->log, "server_iv", pkt->secret->iv.data, 12);
680 ngx_quic_hexdump0(pkt->log, "nonce", nonce, 12); 679 ngx_quic_hexdump0(pkt->log, "nonce", nonce, 12);
681 680
682 if (ngx_quic_tls_seal(ciphers.c, pkt->secret, &out, 681 if (ngx_quic_tls_seal(ciphers.c, pkt->secret, &out,
726 if (ngx_quic_ciphers(ssl_conn, &ciphers, pkt->level) == NGX_ERROR) { 725 if (ngx_quic_ciphers(ssl_conn, &ciphers, pkt->level) == NGX_ERROR) {
727 return NGX_ERROR; 726 return NGX_ERROR;
728 } 727 }
729 728
730 ngx_memcpy(nonce, pkt->secret->iv.data, pkt->secret->iv.len); 729 ngx_memcpy(nonce, pkt->secret->iv.data, pkt->secret->iv.len);
731 if (pkt->level == ssl_encryption_handshake 730 ngx_quic_compute_nonce(nonce, sizeof(nonce), pkt->number);
732 || pkt->level == ssl_encryption_application)
733 {
734 nonce[11] ^= pkt->number;
735 }
736 731
737 ngx_quic_hexdump0(pkt->log, "server_iv", pkt->secret->iv.data, 12); 732 ngx_quic_hexdump0(pkt->log, "server_iv", pkt->secret->iv.data, 12);
738 ngx_quic_hexdump0(pkt->log, "nonce", nonce, 12); 733 ngx_quic_hexdump0(pkt->log, "nonce", nonce, 12);
739 734
740 out.data = res->data + ad.len; 735 out.data = res->data + ad.len;
784 value = (value << 8) + (*p++ ^ *mask++); 779 value = (value << 8) + (*p++ ^ *mask++);
785 } 780 }
786 781
787 *pos = p; 782 *pos = p;
788 return value; 783 return value;
784 }
785
786
787 static void
788 ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn)
789 {
790 nonce[len - 4] ^= pn & 0xff000000;
791 nonce[len - 3] ^= pn & 0x00ff0000;
792 nonce[len - 2] ^= pn & 0x0000ff00;
793 nonce[len - 1] ^= pn & 0x000000ff;
789 } 794 }
790 795
791 796
792 ssize_t 797 ssize_t
793 ngx_quic_encrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn, 798 ngx_quic_encrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn,
873 do { 878 do {
874 ad.data[ad.len - pnl] = pn >> (8 * (pnl - 1)) % 256; 879 ad.data[ad.len - pnl] = pn >> (8 * (pnl - 1)) % 256;
875 } while (--pnl); 880 } while (--pnl);
876 881
877 ngx_memcpy(nonce, pkt->secret->iv.data, pkt->secret->iv.len); 882 ngx_memcpy(nonce, pkt->secret->iv.data, pkt->secret->iv.len);
878 nonce[11] ^= pn; 883 ngx_quic_compute_nonce(nonce, sizeof(nonce), pn);
879 884
880 ngx_quic_hexdump0(pkt->log, "nonce", nonce, 12); 885 ngx_quic_hexdump0(pkt->log, "nonce", nonce, 12);
881 ngx_quic_hexdump0(pkt->log, "ad", ad.data, ad.len); 886 ngx_quic_hexdump0(pkt->log, "ad", ad.data, ad.len);
882 887
883 pkt->payload.len = in.len - EVP_GCM_TLS_TAG_LEN; 888 pkt->payload.len = in.len - EVP_GCM_TLS_TAG_LEN;