Mercurial > hg > nginx
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; |