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)