Mercurial > hg > nginx-quic
comparison src/http/ngx_http_request.c @ 7645:7ee1ada04c8a quic
Generic function for HKDF expansion.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Wed, 26 Feb 2020 16:56:47 +0300 |
parents | a9ff4392ecde |
children | 01dc595de244 |
comparison
equal
deleted
inserted
replaced
7644:a9ff4392ecde | 7645:7ee1ada04c8a |
---|---|
783 | 783 |
784 // initial secret | 784 // initial secret |
785 | 785 |
786 size_t is_len; | 786 size_t is_len; |
787 uint8_t is[SHA256_DIGEST_LENGTH]; | 787 uint8_t is[SHA256_DIGEST_LENGTH]; |
788 ngx_uint_t i; | |
788 const EVP_MD *digest; | 789 const EVP_MD *digest; |
789 const ngx_aead_cipher_t *cipher; | 790 const ngx_aead_cipher_t *cipher; |
790 static const uint8_t salt[20] = | 791 static const uint8_t salt[20] = |
791 "\xc3\xee\xf7\x12\xc7\x2e\xbb\x5a\x11\xa7" | 792 "\xc3\xee\xf7\x12\xc7\x2e\xbb\x5a\x11\xa7" |
792 "\xd2\x43\x2b\xb4\x63\x65\xbe\xf9\xf5\x02"; | 793 "\xd2\x43\x2b\xb4\x63\x65\xbe\xf9\xf5\x02"; |
802 { | 803 { |
803 ngx_http_close_connection(c); | 804 ngx_http_close_connection(c); |
804 return; | 805 return; |
805 } | 806 } |
806 | 807 |
808 ngx_str_t iss = { | |
809 .data = is, | |
810 .len = is_len | |
811 }; | |
812 | |
807 #if (NGX_DEBUG) | 813 #if (NGX_DEBUG) |
808 if (c->log->log_level & NGX_LOG_DEBUG_EVENT) { | 814 if (c->log->log_level & NGX_LOG_DEBUG_EVENT) { |
809 m = ngx_hex_dump(buf, (uint8_t *) salt, sizeof(salt)) - buf; | 815 m = ngx_hex_dump(buf, (uint8_t *) salt, sizeof(salt)) - buf; |
810 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, rev->log, 0, | 816 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, rev->log, 0, |
811 "quic salt: %*s, len: %uz", m, buf, sizeof(salt)); | 817 "quic salt: %*s, len: %uz", m, buf, sizeof(salt)); |
814 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, rev->log, 0, | 820 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, rev->log, 0, |
815 "quic initial secret: %*s, len: %uz", m, buf, is_len); | 821 "quic initial secret: %*s, len: %uz", m, buf, is_len); |
816 } | 822 } |
817 #endif | 823 #endif |
818 | 824 |
819 size_t hkdfl_len; | |
820 uint8_t hkdfl[20]; | |
821 uint8_t *p; | |
822 | |
823 /* draft-ietf-quic-tls-23#section-5.2 */ | 825 /* draft-ietf-quic-tls-23#section-5.2 */ |
824 | |
825 qc->client_in.secret.len = SHA256_DIGEST_LENGTH; | 826 qc->client_in.secret.len = SHA256_DIGEST_LENGTH; |
826 qc->client_in.secret.data = ngx_pnalloc(c->pool, qc->client_in.secret.len); | 827 qc->server_in.secret.len = SHA256_DIGEST_LENGTH; |
827 if (qc->client_in.secret.data == NULL) { | 828 |
828 ngx_http_close_connection(c); | 829 #ifdef OPENSSL_IS_BORINGSSL |
829 return; | 830 qc->client_in.key.len = EVP_AEAD_key_length(cipher); |
830 } | 831 qc->server_in.key.len = EVP_AEAD_key_length(cipher); |
831 | 832 |
832 hkdfl_len = 2 + 1 + sizeof("tls13 client in") - 1 + 1; | 833 qc->client_in.hp.len = EVP_AEAD_key_length(cipher); |
833 bzero(hkdfl, sizeof(hkdfl)); | 834 qc->server_in.hp.len = EVP_AEAD_key_length(cipher); |
834 hkdfl[0] = 0; | 835 |
835 hkdfl[1] = qc->client_in.secret.len; | 836 qc->client_in.iv.len = EVP_AEAD_nonce_length(cipher); |
836 hkdfl[2] = sizeof("tls13 client in") - 1; | 837 qc->server_in.iv.len = EVP_AEAD_nonce_length(cipher); |
837 p = ngx_cpymem(&hkdfl[3], "tls13 client in", sizeof("tls13 client in") - 1); | 838 #else |
838 *p = '\0'; | 839 qc->client_in.key.len = EVP_CIPHER_key_length(cipher); |
839 | 840 qc->server_in.key.len = EVP_CIPHER_key_length(cipher); |
840 #if 0 | 841 |
841 ngx_memcpy(hkdfl, "\x00\x20\x0f\x74\x6c\x73\x31\x33\x20\x63" | 842 qc->client_in.hp.len = EVP_CIPHER_key_length(cipher); |
842 "\x6c\x69\x65\x6e\x74\x20\x69\x6e\x00\x00", 20); | 843 qc->server_in.hp.len = EVP_CIPHER_key_length(cipher); |
843 | 844 |
844 m = ngx_hex_dump(buf, hkdfl, sizeof(hkdfl)) - buf; | 845 qc->client_in.iv.len = EVP_CIPHER_iv_length(cipher); |
845 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, rev->log, 0, | 846 qc->server_in.iv.len = EVP_CIPHER_iv_length(cipher); |
846 "quic initial secret hkdf: %*s, len: %uz", | 847 #endif |
847 m, buf, sizeof(hkdfl)); | |
848 #endif | |
849 | |
850 if (ngx_hkdf_expand(qc->client_in.secret.data, qc->client_in.secret.len, | |
851 digest, is, is_len, hkdfl, hkdfl_len) | |
852 != NGX_OK) | |
853 { | |
854 ngx_ssl_error(NGX_LOG_INFO, rev->log, 0, | |
855 "ngx_hkdf_expand(client_in) failed"); | |
856 ngx_http_close_connection(c); | |
857 return; | |
858 } | |
859 | 848 |
860 #ifdef OPENSSL_IS_BORINGSSL | 849 #ifdef OPENSSL_IS_BORINGSSL |
861 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, rev->log, 0, | 850 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, rev->log, 0, |
862 "quic EVP key:%d tag:%d nonce:%d", | 851 "quic EVP key:%d tag:%d nonce:%d", |
863 EVP_AEAD_key_length(cipher), | 852 EVP_AEAD_key_length(cipher), |
864 EVP_AEAD_max_tag_len(cipher), | 853 EVP_AEAD_max_tag_len(cipher), |
865 EVP_AEAD_nonce_length(cipher)); | 854 EVP_AEAD_nonce_length(cipher)); |
866 #endif | 855 #endif |
867 | 856 |
868 | 857 struct { |
869 #ifdef OPENSSL_IS_BORINGSSL | 858 ngx_str_t id; |
870 qc->client_in.key.len = EVP_AEAD_key_length(cipher); | 859 ngx_str_t *in; |
871 #else | 860 ngx_str_t *prk; |
872 qc->client_in.key.len = EVP_CIPHER_key_length(cipher); | 861 } seq[] = { |
873 #endif | 862 |
874 qc->client_in.key.data = ngx_pnalloc(c->pool, qc->client_in.key.len); | 863 /* draft-ietf-quic-tls-23#section-5.2 */ |
875 if (qc->client_in.key.data == NULL) { | 864 { ngx_string("tls13 client in"), &qc->client_in.secret, &iss }, |
876 ngx_http_close_connection(c); | 865 { |
877 return; | 866 ngx_string("tls13 quic key"), |
878 } | 867 &qc->client_in.key, |
879 | 868 &qc->client_in.secret, |
880 hkdfl_len = 2 + 1 + sizeof("tls13 quic key") - 1 + 1; | 869 }, |
881 hkdfl[1] = qc->client_in.key.len; | 870 { |
882 hkdfl[2] = sizeof("tls13 quic key") - 1; | 871 ngx_string("tls13 quic iv"), |
883 p = ngx_cpymem(&hkdfl[3], "tls13 quic key", sizeof("tls13 quic key") - 1); | 872 &qc->client_in.iv, |
884 *p = '\0'; | 873 &qc->client_in.secret, |
885 | 874 }, |
886 if (ngx_hkdf_expand(qc->client_in.key.data, qc->client_in.key.len, | 875 { |
887 digest, qc->client_in.secret.data, qc->client_in.secret.len, | 876 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */ |
888 hkdfl, hkdfl_len) | 877 ngx_string("tls13 quic hp"), |
889 != NGX_OK) | 878 &qc->client_in.hp, |
890 { | 879 &qc->client_in.secret, |
891 ngx_ssl_error(NGX_LOG_INFO, rev->log, 0, | 880 }, |
892 "ngx_hkdf_expand(client_in.key) failed"); | 881 { ngx_string("tls13 server in"), &qc->server_in.secret, &iss }, |
893 ngx_http_close_connection(c); | 882 { |
894 return; | 883 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.3 */ |
895 } | 884 ngx_string("tls13 quic key"), |
896 | 885 &qc->server_in.key, |
897 #ifdef OPENSSL_IS_BORINGSSL | 886 &qc->server_in.secret, |
898 qc->client_in.iv.len = EVP_AEAD_nonce_length(cipher); | 887 }, |
899 #else | 888 { |
900 qc->client_in.iv.len = EVP_CIPHER_iv_length(cipher); | 889 ngx_string("tls13 quic iv"), |
901 #endif | 890 &qc->server_in.iv, |
902 qc->client_in.iv.data = ngx_pnalloc(c->pool, qc->client_in.iv.len); | 891 &qc->server_in.secret, |
903 if (qc->client_in.iv.data == NULL) { | 892 }, |
904 ngx_http_close_connection(c); | 893 { |
905 return; | 894 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */ |
906 } | 895 ngx_string("tls13 quic hp"), |
907 | 896 &qc->server_in.hp, |
908 hkdfl_len = 2 + 1 + sizeof("tls13 quic iv") - 1 + 1; | 897 &qc->server_in.secret |
909 hkdfl[1] = qc->client_in.iv.len; | 898 }, |
910 hkdfl[2] = sizeof("tls13 quic iv") - 1; | 899 |
911 p = ngx_cpymem(&hkdfl[3], "tls13 quic iv", sizeof("tls13 quic iv") - 1); | 900 }; |
912 *p = '\0'; | 901 |
913 | 902 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) { |
914 if (ngx_hkdf_expand(qc->client_in.iv.data, qc->client_in.iv.len, | 903 |
915 digest, qc->client_in.secret.data, qc->client_in.secret.len, | 904 if (ngx_quic_hkdf_expand(c, digest, seq[i].in, seq[i].prk, &seq[i].id, 0) |
916 hkdfl, hkdfl_len) | 905 != NGX_OK) |
917 != NGX_OK) | 906 { |
918 { | 907 ngx_http_close_connection(c); |
919 ngx_ssl_error(NGX_LOG_INFO, rev->log, 0, | 908 return; |
920 "ngx_hkdf_expand(client_in.iv) failed"); | 909 } |
921 ngx_http_close_connection(c); | 910 } |
922 return; | |
923 } | |
924 | |
925 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */ | |
926 | |
927 #ifdef OPENSSL_IS_BORINGSSL | |
928 qc->client_in.hp.len = EVP_AEAD_key_length(cipher); | |
929 #else | |
930 qc->client_in.hp.len = EVP_CIPHER_key_length(cipher); | |
931 #endif | |
932 qc->client_in.hp.data = ngx_pnalloc(c->pool, qc->client_in.hp.len); | |
933 if (qc->client_in.hp.data == NULL) { | |
934 ngx_http_close_connection(c); | |
935 return; | |
936 } | |
937 | |
938 hkdfl_len = 2 + 1 + sizeof("tls13 quic hp") - 1 + 1; | |
939 hkdfl[1] = qc->client_in.hp.len; | |
940 hkdfl[2] = sizeof("tls13 quic hp") - 1; | |
941 p = ngx_cpymem(&hkdfl[3], "tls13 quic hp", sizeof("tls13 quic hp") - 1); | |
942 *p = '\0'; | |
943 | |
944 if (ngx_hkdf_expand(qc->client_in.hp.data, qc->client_in.hp.len, | |
945 digest, qc->client_in.secret.data, qc->client_in.secret.len, | |
946 hkdfl, hkdfl_len) | |
947 != NGX_OK) | |
948 { | |
949 ngx_ssl_error(NGX_LOG_INFO, rev->log, 0, | |
950 "ngx_hkdf_expand(client_in.hp) failed"); | |
951 ngx_http_close_connection(c); | |
952 return; | |
953 } | |
954 | |
955 #if (NGX_DEBUG) | |
956 if (c->log->log_level & NGX_LOG_DEBUG_EVENT) { | |
957 m = ngx_hex_dump(buf, qc->client_in.secret.data, qc->client_in.secret.len) - buf; | |
958 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, rev->log, 0, | |
959 "quic client initial secret: %*s, len: %uz", | |
960 m, buf, qc->client_in.secret.len); | |
961 | |
962 m = ngx_hex_dump(buf, qc->client_in.key.data, qc->client_in.key.len) | |
963 - buf; | |
964 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, rev->log, 0, | |
965 "quic client key: %*s, len: %uz", | |
966 m, buf, qc->client_in.key.len); | |
967 | |
968 m = ngx_hex_dump(buf, qc->client_in.iv.data, qc->client_in.iv.len) | |
969 - buf; | |
970 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, rev->log, 0, | |
971 "quic client iv: %*s, len: %uz", | |
972 m, buf, qc->client_in.iv.len); | |
973 | |
974 m = ngx_hex_dump(buf, qc->client_in.hp.data, qc->client_in.hp.len) | |
975 - buf; | |
976 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, rev->log, 0, | |
977 "quic client hp: %*s, len: %uz", | |
978 m, buf, qc->client_in.hp.len); | |
979 } | |
980 #endif | |
981 | |
982 // server initial | |
983 | |
984 /* draft-ietf-quic-tls-23#section-5.2 */ | |
985 | |
986 qc->server_in.secret.len = SHA256_DIGEST_LENGTH; | |
987 qc->server_in.secret.data = ngx_pnalloc(c->pool, qc->server_in.secret.len); | |
988 if (qc->server_in.secret.data == NULL) { | |
989 ngx_http_close_connection(c); | |
990 return; | |
991 } | |
992 | |
993 hkdfl_len = 2 + 1 + sizeof("tls13 server in") - 1 + 1; | |
994 hkdfl[0] = 0; | |
995 hkdfl[1] = qc->server_in.secret.len; | |
996 hkdfl[2] = sizeof("tls13 server in") - 1; | |
997 p = ngx_cpymem(&hkdfl[3], "tls13 server in", sizeof("tls13 server in") - 1); | |
998 *p = '\0'; | |
999 | |
1000 if (ngx_hkdf_expand(qc->server_in.secret.data, qc->server_in.secret.len, | |
1001 digest, is, is_len, hkdfl, hkdfl_len) | |
1002 != NGX_OK) | |
1003 { | |
1004 ngx_ssl_error(NGX_LOG_INFO, rev->log, 0, | |
1005 "ngx_hkdf_expand(server_in) failed"); | |
1006 ngx_http_close_connection(c); | |
1007 return; | |
1008 } | |
1009 | |
1010 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.3 */ | |
1011 | |
1012 #ifdef OPENSSL_IS_BORINGSSL | |
1013 qc->server_in.key.len = EVP_AEAD_key_length(cipher); | |
1014 #else | |
1015 qc->server_in.key.len = EVP_CIPHER_key_length(cipher); | |
1016 #endif | |
1017 qc->server_in.key.data = ngx_pnalloc(c->pool, qc->server_in.key.len); | |
1018 if (qc->server_in.key.data == NULL) { | |
1019 ngx_http_close_connection(c); | |
1020 return; | |
1021 } | |
1022 | |
1023 hkdfl_len = 2 + 1 + sizeof("tls13 quic key") - 1 + 1; | |
1024 hkdfl[1] = qc->server_in.key.len; | |
1025 hkdfl[2] = sizeof("tls13 quic key") - 1; | |
1026 p = ngx_cpymem(&hkdfl[3], "tls13 quic key", sizeof("tls13 quic key") - 1); | |
1027 *p = '\0'; | |
1028 | |
1029 if (ngx_hkdf_expand(qc->server_in.key.data, qc->server_in.key.len, | |
1030 digest, qc->server_in.secret.data, qc->server_in.secret.len, | |
1031 hkdfl, hkdfl_len) | |
1032 != NGX_OK) | |
1033 { | |
1034 ngx_ssl_error(NGX_LOG_INFO, rev->log, 0, | |
1035 "ngx_hkdf_expand(server_in.key) failed"); | |
1036 ngx_http_close_connection(c); | |
1037 return; | |
1038 } | |
1039 | |
1040 #ifdef OPENSSL_IS_BORINGSSL | |
1041 qc->server_in.iv.len = EVP_AEAD_nonce_length(cipher); | |
1042 #else | |
1043 qc->server_in.iv.len = EVP_CIPHER_iv_length(cipher); | |
1044 #endif | |
1045 qc->server_in.iv.data = ngx_pnalloc(c->pool, qc->server_in.iv.len); | |
1046 if (qc->server_in.iv.data == NULL) { | |
1047 ngx_http_close_connection(c); | |
1048 return; | |
1049 } | |
1050 | |
1051 hkdfl_len = 2 + 1 + sizeof("tls13 quic iv") - 1 + 1; | |
1052 hkdfl[1] = qc->server_in.iv.len; | |
1053 hkdfl[2] = sizeof("tls13 quic iv") - 1; | |
1054 p = ngx_cpymem(&hkdfl[3], "tls13 quic iv", sizeof("tls13 quic iv") - 1); | |
1055 *p = '\0'; | |
1056 | |
1057 if (ngx_hkdf_expand(qc->server_in.iv.data, qc->server_in.iv.len, | |
1058 digest, qc->server_in.secret.data, qc->server_in.secret.len, | |
1059 hkdfl, hkdfl_len) | |
1060 != NGX_OK) | |
1061 { | |
1062 ngx_ssl_error(NGX_LOG_INFO, rev->log, 0, | |
1063 "ngx_hkdf_expand(server_in.iv) failed"); | |
1064 ngx_http_close_connection(c); | |
1065 return; | |
1066 } | |
1067 | |
1068 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */ | |
1069 | |
1070 #ifdef OPENSSL_IS_BORINGSSL | |
1071 qc->server_in.hp.len = EVP_AEAD_key_length(cipher); | |
1072 #else | |
1073 qc->server_in.hp.len = EVP_CIPHER_key_length(cipher); | |
1074 #endif | |
1075 qc->server_in.hp.data = ngx_pnalloc(c->pool, qc->server_in.hp.len); | |
1076 if (qc->server_in.hp.data == NULL) { | |
1077 ngx_http_close_connection(c); | |
1078 return; | |
1079 } | |
1080 | |
1081 hkdfl_len = 2 + 1 + sizeof("tls13 quic hp") - 1 + 1; | |
1082 hkdfl[1] = qc->server_in.hp.len; | |
1083 hkdfl[2] = sizeof("tls13 quic hp") - 1; | |
1084 p = ngx_cpymem(&hkdfl[3], "tls13 quic hp", sizeof("tls13 quic hp") - 1); | |
1085 *p = '\0'; | |
1086 | |
1087 if (ngx_hkdf_expand(qc->server_in.hp.data, qc->server_in.hp.len, | |
1088 digest, qc->server_in.secret.data, qc->server_in.secret.len, | |
1089 hkdfl, hkdfl_len) | |
1090 != NGX_OK) | |
1091 { | |
1092 ngx_ssl_error(NGX_LOG_INFO, rev->log, 0, | |
1093 "ngx_hkdf_expand(server_in.hp) failed"); | |
1094 ngx_http_close_connection(c); | |
1095 return; | |
1096 } | |
1097 | |
1098 #if (NGX_DEBUG) | |
1099 if (c->log->log_level & NGX_LOG_DEBUG_EVENT) { | |
1100 m = ngx_hex_dump(buf, qc->server_in.secret.data, qc->server_in.secret.len) - buf; | |
1101 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, rev->log, 0, | |
1102 "quic server initial secret: %*s, len: %uz", | |
1103 m, buf, qc->server_in.secret.len); | |
1104 | |
1105 m = ngx_hex_dump(buf, qc->server_in.key.data, qc->server_in.key.len) | |
1106 - buf; | |
1107 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, rev->log, 0, | |
1108 "quic server key: %*s, len: %uz", | |
1109 m, buf, qc->server_in.key.len); | |
1110 | |
1111 m = ngx_hex_dump(buf, qc->server_in.iv.data, qc->server_in.iv.len) | |
1112 - buf; | |
1113 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, rev->log, 0, | |
1114 "quic server iv: %*s, len: %uz", | |
1115 m, buf, qc->server_in.iv.len); | |
1116 | |
1117 m = ngx_hex_dump(buf, qc->server_in.hp.data, qc->server_in.hp.len) | |
1118 - buf; | |
1119 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, rev->log, 0, | |
1120 "quic server hp: %*s, len: %uz", | |
1121 m, buf, qc->server_in.hp.len); | |
1122 } | |
1123 #endif | |
1124 | 911 |
1125 // header protection | 912 // header protection |
1126 | 913 |
1127 uint8_t mask[16]; | 914 uint8_t mask[16]; |
1128 if (ngx_quic_tls_hp(c, EVP_aes_128_ecb(), &qc->client_in, mask, sample) | 915 if (ngx_quic_tls_hp(c, EVP_aes_128_ecb(), &qc->client_in, mask, sample) |