Mercurial > hg > nginx
comparison src/event/ngx_event_quic_protection.c @ 8339:aba84d9ab256 quic
Parsing of truncated packet numbers.
For sample decoding algorithm, see quic-transport-27#appendix-A.
author | Sergey Kandaurov <pluknet@nginx.com> |
---|---|
date | Thu, 16 Apr 2020 12:46:48 +0300 |
parents | 7cca3624f9c4 |
children | 2f900ae486bc |
comparison
equal
deleted
inserted
replaced
8338:0f9e9786b90d | 8339:aba84d9ab256 |
---|---|
34 const u_char *info, size_t info_len); | 34 const u_char *info, size_t info_len); |
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 uint64_t *largest_pn); | |
40 static void ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn); | 41 static void ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn); |
41 static ngx_int_t ngx_quic_ciphers(ngx_ssl_conn_t *ssl_conn, | 42 static ngx_int_t ngx_quic_ciphers(ngx_ssl_conn_t *ssl_conn, |
42 ngx_quic_ciphers_t *ciphers, enum ssl_encryption_level_t level); | 43 ngx_quic_ciphers_t *ciphers, enum ssl_encryption_level_t level); |
43 | 44 |
44 static ngx_int_t ngx_quic_tls_open(const ngx_quic_cipher_t *cipher, | 45 static ngx_int_t ngx_quic_tls_open(const ngx_quic_cipher_t *cipher, |
868 return NGX_OK; | 869 return NGX_OK; |
869 } | 870 } |
870 | 871 |
871 | 872 |
872 static uint64_t | 873 static uint64_t |
873 ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask) | 874 ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask, |
875 uint64_t *largest_pn) | |
874 { | 876 { |
875 u_char *p; | 877 u_char *p; |
876 uint64_t value; | 878 uint64_t truncated_pn, expected_pn, candidate_pn; |
879 uint64_t pn_nbits, pn_win, pn_hwin, pn_mask; | |
880 | |
881 pn_nbits = ngx_min(len * 8, 62); | |
877 | 882 |
878 p = *pos; | 883 p = *pos; |
879 value = *p++ ^ *mask++; | 884 truncated_pn = *p++ ^ *mask++; |
880 | 885 |
881 while (--len) { | 886 while (--len) { |
882 value = (value << 8) + (*p++ ^ *mask++); | 887 truncated_pn = (truncated_pn << 8) + (*p++ ^ *mask++); |
883 } | 888 } |
884 | 889 |
885 *pos = p; | 890 *pos = p; |
886 return value; | 891 |
892 expected_pn = *largest_pn + 1; | |
893 pn_win = 1 << pn_nbits; | |
894 pn_hwin = pn_win / 2; | |
895 pn_mask = pn_win - 1; | |
896 | |
897 candidate_pn = (expected_pn & ~pn_mask) | truncated_pn; | |
898 | |
899 if ((int64_t) candidate_pn <= (int64_t) (expected_pn - pn_hwin) | |
900 && candidate_pn < (1ULL << 62) - pn_win) | |
901 { | |
902 candidate_pn += pn_win; | |
903 | |
904 } else if (candidate_pn > expected_pn + pn_hwin | |
905 && candidate_pn >= pn_win) | |
906 { | |
907 candidate_pn -= pn_win; | |
908 } | |
909 | |
910 *largest_pn = ngx_max((int64_t) *largest_pn, (int64_t) candidate_pn); | |
911 | |
912 return candidate_pn; | |
887 } | 913 } |
888 | 914 |
889 | 915 |
890 static void | 916 static void |
891 ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn) | 917 ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn) |
908 return ngx_quic_create_long_packet(pkt, ssl_conn, res); | 934 return ngx_quic_create_long_packet(pkt, ssl_conn, res); |
909 } | 935 } |
910 | 936 |
911 | 937 |
912 ngx_int_t | 938 ngx_int_t |
913 ngx_quic_decrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn) | 939 ngx_quic_decrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn, |
940 uint64_t *largest_pn) | |
914 { | 941 { |
915 u_char clearflags, *p, *sample; | 942 u_char clearflags, *p, *sample; |
916 uint64_t pn; | 943 uint64_t pn; |
917 ngx_int_t pnl, rc, key_phase; | 944 ngx_int_t pnl, rc, key_phase; |
918 ngx_str_t in, ad; | 945 ngx_str_t in, ad; |
958 pkt->key_update = 1; | 985 pkt->key_update = 1; |
959 } | 986 } |
960 } | 987 } |
961 | 988 |
962 pnl = (clearflags & 0x03) + 1; | 989 pnl = (clearflags & 0x03) + 1; |
963 pn = ngx_quic_parse_pn(&p, pnl, &mask[1]); | 990 pn = ngx_quic_parse_pn(&p, pnl, &mask[1], largest_pn); |
964 | 991 |
965 pkt->pn = pn; | 992 pkt->pn = pn; |
966 | 993 |
967 ngx_quic_hexdump0(pkt->log, "mask", mask, 5); | 994 ngx_quic_hexdump0(pkt->log, "mask", mask, 5); |
968 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0, | 995 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0, |