annotate src/event/ngx_event_quic_protection.c @ 8082:26a5bd4aff57 quic

QUIC: removed check for packet size beyond MAX_UDP_PAYLOAD_SIZE. The check tested the total size of a packet header and unprotected packet payload, which doesn't include the packet number length and expansion of the packet protection AEAD. If the packet was corrupted, it could cause false triggering of the condition due to unsigned type underflow leading to a connection error. Existing checks for the QUIC header and protected packet payload lengths should be enough.
author Sergey Kandaurov <pluknet@nginx.com>
date Tue, 08 Sep 2020 13:35:50 +0300
parents 9aedab0f0dff
children 0f37b4ef3cd9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
2 /*
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
3 * Copyright (C) Nginx, Inc.
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
4 */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
5
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
6
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
7 #include <ngx_config.h>
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
8 #include <ngx_core.h>
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
9 #include <ngx_event.h>
8004
d0ac4449a07f QUIC: fixed bulding perl module by reducing header pollution.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7996
diff changeset
10 #include <ngx_event_quic_transport.h>
d0ac4449a07f QUIC: fixed bulding perl module by reducing header pollution.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7996
diff changeset
11 #include <ngx_event_quic_protection.h>
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
12
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
13
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
14 #define NGX_QUIC_IV_LEN 12
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
15
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
16 #define NGX_AES_128_GCM_SHA256 0x1301
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
17 #define NGX_AES_256_GCM_SHA384 0x1302
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
18 #define NGX_CHACHA20_POLY1305_SHA256 0x1303
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
19
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
20
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
21 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
22 #define ngx_quic_cipher_t EVP_AEAD
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
23 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
24 #define ngx_quic_cipher_t EVP_CIPHER
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
25 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
26
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
27 typedef struct {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
28 const ngx_quic_cipher_t *c;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
29 const EVP_CIPHER *hp;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
30 const EVP_MD *d;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
31 } ngx_quic_ciphers_t;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
32
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
33
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
34 static ngx_int_t ngx_hkdf_expand(u_char *out_key, size_t out_len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
35 const EVP_MD *digest, const u_char *prk, size_t prk_len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
36 const u_char *info, size_t info_len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
37 static ngx_int_t ngx_hkdf_extract(u_char *out_key, size_t *out_len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
38 const EVP_MD *digest, const u_char *secret, size_t secret_len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
39 const u_char *salt, size_t salt_len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
40
7816
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
41 static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask,
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
42 uint64_t *largest_pn);
7776
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7773
diff changeset
43 static void ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
44 static ngx_int_t ngx_quic_ciphers(ngx_ssl_conn_t *ssl_conn,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
45 ngx_quic_ciphers_t *ciphers, enum ssl_encryption_level_t level);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
46
7754
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 7753
diff changeset
47 static ngx_int_t ngx_quic_tls_open(const ngx_quic_cipher_t *cipher,
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
48 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in,
7753
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7751
diff changeset
49 ngx_str_t *ad, ngx_log_t *log);
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
50 static ngx_int_t ngx_quic_tls_seal(const ngx_quic_cipher_t *cipher,
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
51 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in,
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
52 ngx_str_t *ad, ngx_log_t *log);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
53 static ngx_int_t ngx_quic_tls_hp(ngx_log_t *log, const EVP_CIPHER *cipher,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
54 ngx_quic_secret_t *s, u_char *out, u_char *in);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
55 static ngx_int_t ngx_quic_hkdf_expand(ngx_pool_t *pool, const EVP_MD *digest,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
56 ngx_str_t *out, ngx_str_t *label, const uint8_t *prk, size_t prk_len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
57
7853
2d0f4aa78ed6 Restored ngx_quic_encrypt return type.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7852
diff changeset
58 static ngx_int_t ngx_quic_create_long_packet(ngx_quic_header_t *pkt,
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
59 ngx_ssl_conn_t *ssl_conn, ngx_str_t *res);
7853
2d0f4aa78ed6 Restored ngx_quic_encrypt return type.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7852
diff changeset
60 static ngx_int_t ngx_quic_create_short_packet(ngx_quic_header_t *pkt,
7765
Sergey Kandaurov <pluknet@nginx.com>
parents: 7754
diff changeset
61 ngx_ssl_conn_t *ssl_conn, ngx_str_t *res);
7860
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
62 static ngx_int_t ngx_quic_create_retry_packet(ngx_quic_header_t *pkt,
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
63 ngx_str_t *res);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
64
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
65
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
66 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
67 ngx_quic_ciphers(ngx_ssl_conn_t *ssl_conn, ngx_quic_ciphers_t *ciphers,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
68 enum ssl_encryption_level_t level)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
69 {
7790
7cca3624f9c4 Added check for SSL_get_current_cipher() results.
Vladimir Homutov <vl@nginx.com>
parents: 7785
diff changeset
70 ngx_int_t id, len;
7cca3624f9c4 Added check for SSL_get_current_cipher() results.
Vladimir Homutov <vl@nginx.com>
parents: 7785
diff changeset
71 const SSL_CIPHER *cipher;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
72
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
73 if (level == ssl_encryption_initial) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
74 id = NGX_AES_128_GCM_SHA256;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
75
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
76 } else {
7790
7cca3624f9c4 Added check for SSL_get_current_cipher() results.
Vladimir Homutov <vl@nginx.com>
parents: 7785
diff changeset
77 cipher = SSL_get_current_cipher(ssl_conn);
7cca3624f9c4 Added check for SSL_get_current_cipher() results.
Vladimir Homutov <vl@nginx.com>
parents: 7785
diff changeset
78 if (cipher == NULL) {
7cca3624f9c4 Added check for SSL_get_current_cipher() results.
Vladimir Homutov <vl@nginx.com>
parents: 7785
diff changeset
79 return NGX_ERROR;
7cca3624f9c4 Added check for SSL_get_current_cipher() results.
Vladimir Homutov <vl@nginx.com>
parents: 7785
diff changeset
80 }
7cca3624f9c4 Added check for SSL_get_current_cipher() results.
Vladimir Homutov <vl@nginx.com>
parents: 7785
diff changeset
81
7cca3624f9c4 Added check for SSL_get_current_cipher() results.
Vladimir Homutov <vl@nginx.com>
parents: 7785
diff changeset
82 id = SSL_CIPHER_get_id(cipher) & 0xffff;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
83 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
84
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
85 switch (id) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
86
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
87 case NGX_AES_128_GCM_SHA256:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
88 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
89 ciphers->c = EVP_aead_aes_128_gcm();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
90 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
91 ciphers->c = EVP_aes_128_gcm();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
92 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
93 ciphers->hp = EVP_aes_128_ctr();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
94 ciphers->d = EVP_sha256();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
95 len = 16;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
96 break;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
97
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
98 case NGX_AES_256_GCM_SHA384:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
99 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
100 ciphers->c = EVP_aead_aes_256_gcm();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
101 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
102 ciphers->c = EVP_aes_256_gcm();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
103 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
104 ciphers->hp = EVP_aes_256_ctr();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
105 ciphers->d = EVP_sha384();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
106 len = 32;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
107 break;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
108
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
109 case NGX_CHACHA20_POLY1305_SHA256:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
110 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
111 ciphers->c = EVP_aead_chacha20_poly1305();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
112 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
113 ciphers->c = EVP_chacha20_poly1305();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
114 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
115 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
116 ciphers->hp = (const EVP_CIPHER *) EVP_aead_chacha20_poly1305();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
117 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
118 ciphers->hp = EVP_chacha20();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
119 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
120 ciphers->d = EVP_sha256();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
121 len = 32;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
122 break;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
123
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
124 default:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
125 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
126 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
127
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
128 return len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
129 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
130
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
131
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
132 ngx_int_t
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
133 ngx_quic_set_initial_secret(ngx_pool_t *pool, ngx_quic_secret_t *client,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
134 ngx_quic_secret_t *server, ngx_str_t *secret)
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
135 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
136 size_t is_len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
137 uint8_t is[SHA256_DIGEST_LENGTH];
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
138 ngx_uint_t i;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
139 const EVP_MD *digest;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
140 const EVP_CIPHER *cipher;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
141
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
142 static const uint8_t salt[20] =
7943
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7941
diff changeset
143 #if (NGX_QUIC_DRAFT_VERSION >= 29)
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7941
diff changeset
144 "\xaf\xbf\xec\x28\x99\x93\xd2\x4c\x9e\x97"
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7941
diff changeset
145 "\x86\xf1\x9c\x61\x11\xe0\x43\x90\xa8\x99";
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7941
diff changeset
146 #else
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
147 "\xc3\xee\xf7\x12\xc7\x2e\xbb\x5a\x11\xa7"
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
148 "\xd2\x43\x2b\xb4\x63\x65\xbe\xf9\xf5\x02";
7943
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7941
diff changeset
149 #endif
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
150
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
151 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.3 */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
152
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
153 cipher = EVP_aes_128_gcm();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
154 digest = EVP_sha256();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
155
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
156 if (ngx_hkdf_extract(is, &is_len, digest, secret->data, secret->len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
157 salt, sizeof(salt))
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
158 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
159 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
160 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
161 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
162
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
163 ngx_str_t iss = {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
164 .data = is,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
165 .len = is_len
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
166 };
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
167
7836
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7816
diff changeset
168 #ifdef NGX_QUIC_DEBUG_CRYPTO
7837
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 7836
diff changeset
169 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, pool->log, 0,
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 7836
diff changeset
170 "quic ngx_quic_set_initial_secret");
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 7836
diff changeset
171 ngx_quic_hexdump(pool->log, "quic salt", salt, sizeof(salt));
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 7836
diff changeset
172 ngx_quic_hexdump(pool->log, "quic initial secret", is, is_len);
7836
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7816
diff changeset
173 #endif
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
174
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
175 /* draft-ietf-quic-tls-23#section-5.2 */
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
176 client->secret.len = SHA256_DIGEST_LENGTH;
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
177 server->secret.len = SHA256_DIGEST_LENGTH;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
178
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
179 client->key.len = EVP_CIPHER_key_length(cipher);
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
180 server->key.len = EVP_CIPHER_key_length(cipher);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
181
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
182 client->hp.len = EVP_CIPHER_key_length(cipher);
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
183 server->hp.len = EVP_CIPHER_key_length(cipher);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
184
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
185 client->iv.len = EVP_CIPHER_iv_length(cipher);
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
186 server->iv.len = EVP_CIPHER_iv_length(cipher);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
187
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
188 struct {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
189 ngx_str_t label;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
190 ngx_str_t *key;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
191 ngx_str_t *prk;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
192 } seq[] = {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
193
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
194 /* draft-ietf-quic-tls-23#section-5.2 */
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
195 { ngx_string("tls13 client in"), &client->secret, &iss },
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
196 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
197 ngx_string("tls13 quic key"),
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
198 &client->key,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
199 &client->secret,
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
200 },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
201 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
202 ngx_string("tls13 quic iv"),
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
203 &client->iv,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
204 &client->secret,
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
205 },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
206 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
207 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
208 ngx_string("tls13 quic hp"),
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
209 &client->hp,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
210 &client->secret,
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
211 },
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
212 { ngx_string("tls13 server in"), &server->secret, &iss },
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
213 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
214 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.3 */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
215 ngx_string("tls13 quic key"),
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
216 &server->key,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
217 &server->secret,
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
218 },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
219 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
220 ngx_string("tls13 quic iv"),
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
221 &server->iv,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
222 &server->secret,
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
223 },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
224 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
225 /* AEAD_AES_128_GCM prior to handshake, quic-tls-23#section-5.4.1 */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
226 ngx_string("tls13 quic hp"),
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
227 &server->hp,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
228 &server->secret,
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
229 },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
230
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
231 };
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
232
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
233 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
234
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
235 if (ngx_quic_hkdf_expand(pool, digest, seq[i].key, &seq[i].label,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
236 seq[i].prk->data, seq[i].prk->len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
237 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
238 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
239 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
240 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
241 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
242
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
243 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
244 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
245
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
246
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
247 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
248 ngx_quic_hkdf_expand(ngx_pool_t *pool, const EVP_MD *digest, ngx_str_t *out,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
249 ngx_str_t *label, const uint8_t *prk, size_t prk_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
250 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
251 size_t info_len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
252 uint8_t *p;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
253 uint8_t info[20];
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
254
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
255 if (out->data == NULL) {
7785
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
256 out->data = ngx_pnalloc(pool, out->len);
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
257 if (out->data == NULL) {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
258 return NGX_ERROR;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
259 }
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
260 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
261
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
262 info_len = 2 + 1 + label->len + 1;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
263
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
264 info[0] = 0;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
265 info[1] = out->len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
266 info[2] = label->len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
267 p = ngx_cpymem(&info[3], label->data, label->len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
268 *p = '\0';
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
269
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
270 if (ngx_hkdf_expand(out->data, out->len, digest,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
271 prk, prk_len, info, info_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
272 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
273 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
274 ngx_ssl_error(NGX_LOG_INFO, pool->log, 0,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
275 "ngx_hkdf_expand(%V) failed", label);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
276 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
277 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
278
7836
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7816
diff changeset
279 #ifdef NGX_QUIC_DEBUG_CRYPTO
8063
64a484fd40a9 QUIC: stripped down debug traces that have served its purpose.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8004
diff changeset
280 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pool->log, 0, "quic expand %V", label);
7837
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 7836
diff changeset
281 ngx_quic_hexdump(pool->log, "quic key", out->data, out->len);
7836
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7816
diff changeset
282 #endif
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
283
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
284 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
285 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
286
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
287
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
288 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
289 ngx_hkdf_expand(u_char *out_key, size_t out_len, const EVP_MD *digest,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
290 const uint8_t *prk, size_t prk_len, const u_char *info, size_t info_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
291 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
292 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
293 if (HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
294 == 0)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
295 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
296 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
297 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
298 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
299
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
300 EVP_PKEY_CTX *pctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
301
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
302 pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
303
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
304 if (EVP_PKEY_derive_init(pctx) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
305 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
306 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
307
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
308 if (EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
309 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
310 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
311
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
312 if (EVP_PKEY_CTX_set_hkdf_md(pctx, digest) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
313 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
314 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
315
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
316 if (EVP_PKEY_CTX_set1_hkdf_key(pctx, prk, prk_len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
317 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
318 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
319
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
320 if (EVP_PKEY_CTX_add1_hkdf_info(pctx, info, info_len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
321 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
322 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
323
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
324 if (EVP_PKEY_derive(pctx, out_key, &out_len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
325 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
326 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
327
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
328 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
329
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
330 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
331 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
332
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
333
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
334 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
335 ngx_hkdf_extract(u_char *out_key, size_t *out_len, const EVP_MD *digest,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
336 const u_char *secret, size_t secret_len, const u_char *salt,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
337 size_t salt_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
338 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
339 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
340 if (HKDF_extract(out_key, out_len, digest, secret, secret_len, salt,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
341 salt_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
342 == 0)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
343 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
344 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
345 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
346 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
347
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
348 EVP_PKEY_CTX *pctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
349
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
350 pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
351
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
352 if (EVP_PKEY_derive_init(pctx) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
353 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
354 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
355
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
356 if (EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
357 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
358 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
359
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
360 if (EVP_PKEY_CTX_set_hkdf_md(pctx, digest) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
361 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
362 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
363
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
364 if (EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, secret_len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
365 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
366 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
367
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
368 if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, salt_len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
369 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
370 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
371
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
372 if (EVP_PKEY_derive(pctx, out_key, out_len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
373 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
374 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
375
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
376 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
377
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
378 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
379 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
380
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
381
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
382 static ngx_int_t
7754
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 7753
diff changeset
383 ngx_quic_tls_open(const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s,
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 7753
diff changeset
384 ngx_str_t *out, u_char *nonce, ngx_str_t *in, ngx_str_t *ad,
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 7753
diff changeset
385 ngx_log_t *log)
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
386 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
387
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
388 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
389 EVP_AEAD_CTX *ctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
390
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
391 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
392 EVP_AEAD_DEFAULT_TAG_LENGTH);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
393 if (ctx == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
394 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_new() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
395 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
396 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
397
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
398 if (EVP_AEAD_CTX_open(ctx, out->data, &out->len, out->len, nonce, s->iv.len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
399 in->data, in->len, ad->data, ad->len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
400 != 1)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
401 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
402 EVP_AEAD_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
403 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_open() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
404 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
405 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
406
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
407 EVP_AEAD_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
408 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
409 int len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
410 u_char *tag;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
411 EVP_CIPHER_CTX *ctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
412
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
413 ctx = EVP_CIPHER_CTX_new();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
414 if (ctx == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
415 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_CIPHER_CTX_new() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
416 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
417 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
418
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
419 if (EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
420 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
421 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptInit_ex() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
422 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
423 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
424
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
425 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, s->iv.len, NULL)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
426 == 0)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
427 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
428 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
429 ngx_ssl_error(NGX_LOG_INFO, log, 0,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
430 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_SET_IVLEN) failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
431 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
432 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
433
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
434 if (EVP_DecryptInit_ex(ctx, NULL, NULL, s->key.data, nonce) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
435 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
436 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptInit_ex() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
437 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
438 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
439
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
440 if (EVP_DecryptUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
441 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
442 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptUpdate() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
443 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
444 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
445
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
446 if (EVP_DecryptUpdate(ctx, out->data, &len, in->data,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
447 in->len - EVP_GCM_TLS_TAG_LEN)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
448 != 1)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
449 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
450 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
451 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptUpdate() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
452 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
453 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
454
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
455 out->len = len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
456 tag = in->data + in->len - EVP_GCM_TLS_TAG_LEN;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
457
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
458 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, EVP_GCM_TLS_TAG_LEN, tag)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
459 == 0)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
460 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
461 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
462 ngx_ssl_error(NGX_LOG_INFO, log, 0,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
463 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_SET_TAG) failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
464 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
465 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
466
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
467 if (EVP_DecryptFinal_ex(ctx, out->data + len, &len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
468 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
469 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptFinal_ex failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
470 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
471 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
472
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
473 out->len += len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
474
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
475 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
476 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
477
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
478 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
479 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
480
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
481
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
482 static ngx_int_t
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
483 ngx_quic_tls_seal(const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s,
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
484 ngx_str_t *out, u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
485 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
486
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
487 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
488 EVP_AEAD_CTX *ctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
489
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
490 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
491 EVP_AEAD_DEFAULT_TAG_LENGTH);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
492 if (ctx == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
493 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_new() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
494 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
495 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
496
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
497 if (EVP_AEAD_CTX_seal(ctx, out->data, &out->len, out->len, nonce, s->iv.len,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
498 in->data, in->len, ad->data, ad->len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
499 != 1)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
500 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
501 EVP_AEAD_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
502 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_seal() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
503 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
504 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
505
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
506 EVP_AEAD_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
507 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
508 int len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
509 EVP_CIPHER_CTX *ctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
510
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
511 ctx = EVP_CIPHER_CTX_new();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
512 if (ctx == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
513 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_CIPHER_CTX_new() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
514 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
515 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
516
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
517 if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
518 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
519 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptInit_ex() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
520 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
521 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
522
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
523 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, s->iv.len, NULL)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
524 == 0)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
525 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
526 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
527 ngx_ssl_error(NGX_LOG_INFO, log, 0,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
528 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_SET_IVLEN) failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
529 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
530 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
531
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
532 if (EVP_EncryptInit_ex(ctx, NULL, NULL, s->key.data, nonce) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
533 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
534 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptInit_ex() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
535 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
536 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
537
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
538 if (EVP_EncryptUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
539 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
540 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
541 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
542 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
543
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
544 if (EVP_EncryptUpdate(ctx, out->data, &len, in->data, in->len) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
545 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
546 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
547 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
548 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
549
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
550 out->len = len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
551
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
552 if (EVP_EncryptFinal_ex(ctx, out->data + out->len, &len) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
553 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
554 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptFinal_ex failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
555 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
556 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
557
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
558 out->len += len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
559
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
560 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, EVP_GCM_TLS_TAG_LEN,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
561 out->data + in->len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
562 == 0)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
563 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
564 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
565 ngx_ssl_error(NGX_LOG_INFO, log, 0,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
566 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_GCM_GET_TAG) failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
567 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
568 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
569
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
570 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
571
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
572 out->len += EVP_GCM_TLS_TAG_LEN;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
573 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
574 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
575 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
576
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
577
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
578 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
579 ngx_quic_tls_hp(ngx_log_t *log, const EVP_CIPHER *cipher,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
580 ngx_quic_secret_t *s, u_char *out, u_char *in)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
581 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
582 int outlen;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
583 EVP_CIPHER_CTX *ctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
584 u_char zero[5] = {0};
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
585
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
586 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
587 uint32_t counter;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
588
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
589 ngx_memcpy(&counter, in, sizeof(uint32_t));
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
590
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
591 if (cipher == (const EVP_CIPHER *) EVP_aead_chacha20_poly1305()) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
592 CRYPTO_chacha_20(out, zero, 5, s->hp.data, &in[4], counter);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
593 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
594 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
595 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
596
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
597 ctx = EVP_CIPHER_CTX_new();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
598 if (ctx == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
599 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
600 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
601
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
602 if (EVP_EncryptInit_ex(ctx, cipher, NULL, s->hp.data, in) != 1) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
603 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptInit_ex() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
604 goto failed;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
605 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
606
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
607 if (!EVP_EncryptUpdate(ctx, out, &outlen, zero, 5)) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
608 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
609 goto failed;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
610 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
611
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
612 if (!EVP_EncryptFinal_ex(ctx, out + 5, &outlen)) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
613 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptFinal_Ex() failed");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
614 goto failed;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
615 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
616
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
617 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
618
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
619 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
620
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
621 failed:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
622
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
623 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
624
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
625 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
626 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
627
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
628
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
629 int
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
630 ngx_quic_set_encryption_secret(ngx_pool_t *pool, ngx_ssl_conn_t *ssl_conn,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
631 enum ssl_encryption_level_t level, const uint8_t *secret,
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
632 size_t secret_len, ngx_quic_secret_t *peer_secret)
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
633 {
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
634 ngx_int_t key_len;
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
635 ngx_uint_t i;
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
636 ngx_quic_ciphers_t ciphers;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
637
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
638 key_len = ngx_quic_ciphers(ssl_conn, &ciphers, level);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
639
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
640 if (key_len == NGX_ERROR) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
641 ngx_ssl_error(NGX_LOG_INFO, pool->log, 0, "unexpected cipher");
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
642 return 0;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
643 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
644
7772
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 7769
diff changeset
645 if (level == ssl_encryption_initial) {
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
646 return 0;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
647 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
648
7785
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
649 peer_secret->secret.data = ngx_pnalloc(pool, secret_len);
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
650 if (peer_secret->secret.data == NULL) {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
651 return NGX_ERROR;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
652 }
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
653
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
654 peer_secret->secret.len = secret_len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
655 ngx_memcpy(peer_secret->secret.data, secret, secret_len);
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
656
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
657 peer_secret->key.len = key_len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
658 peer_secret->iv.len = NGX_QUIC_IV_LEN;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
659 peer_secret->hp.len = key_len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
660
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
661 struct {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
662 ngx_str_t label;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
663 ngx_str_t *key;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
664 const uint8_t *secret;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
665 } seq[] = {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
666 { ngx_string("tls13 quic key"), &peer_secret->key, secret },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
667 { ngx_string("tls13 quic iv"), &peer_secret->iv, secret },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
668 { ngx_string("tls13 quic hp"), &peer_secret->hp, secret },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
669 };
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
670
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
671 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
672
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
673 if (ngx_quic_hkdf_expand(pool, ciphers.d, seq[i].key, &seq[i].label,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
674 seq[i].secret, secret_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
675 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
676 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
677 return 0;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
678 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
679 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
680
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
681 return 1;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
682 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
683
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
684
7785
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
685 ngx_int_t
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
686 ngx_quic_key_update(ngx_connection_t *c, ngx_quic_secrets_t *current,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
687 ngx_quic_secrets_t *next)
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
688 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
689 ngx_uint_t i;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
690 ngx_quic_ciphers_t ciphers;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
691
7837
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 7836
diff changeset
692 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic key update");
7785
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
693
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
694 if (ngx_quic_ciphers(c->ssl->connection, &ciphers,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
695 ssl_encryption_application)
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
696 == NGX_ERROR)
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
697 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
698 return NGX_ERROR;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
699 }
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
700
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
701 next->client.secret.len = current->client.secret.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
702 next->client.key.len = current->client.key.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
703 next->client.iv.len = current->client.iv.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
704 next->client.hp = current->client.hp;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
705
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
706 next->server.secret.len = current->server.secret.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
707 next->server.key.len = current->server.key.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
708 next->server.iv.len = current->server.iv.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
709 next->server.hp = current->server.hp;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
710
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
711 struct {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
712 ngx_str_t label;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
713 ngx_str_t *key;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
714 ngx_str_t *secret;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
715 } seq[] = {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
716 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
717 ngx_string("tls13 quic ku"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
718 &next->client.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
719 &current->client.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
720 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
721 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
722 ngx_string("tls13 quic key"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
723 &next->client.key,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
724 &next->client.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
725 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
726 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
727 ngx_string("tls13 quic iv"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
728 &next->client.iv,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
729 &next->client.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
730 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
731 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
732 ngx_string("tls13 quic ku"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
733 &next->server.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
734 &current->server.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
735 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
736 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
737 ngx_string("tls13 quic key"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
738 &next->server.key,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
739 &next->server.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
740 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
741 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
742 ngx_string("tls13 quic iv"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
743 &next->server.iv,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
744 &next->server.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
745 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
746 };
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
747
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
748 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
749
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
750 if (ngx_quic_hkdf_expand(c->pool, ciphers.d, seq[i].key, &seq[i].label,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
751 seq[i].secret->data, seq[i].secret->len)
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
752 != NGX_OK)
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
753 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
754 return NGX_ERROR;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
755 }
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
756 }
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
757
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
758 return NGX_OK;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
759 }
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
760
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
761
7853
2d0f4aa78ed6 Restored ngx_quic_encrypt return type.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7852
diff changeset
762 static ngx_int_t
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
763 ngx_quic_create_long_packet(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn,
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
764 ngx_str_t *res)
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
765 {
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
766 u_char *pnp, *sample;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
767 ngx_str_t ad, out;
7781
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 7779
diff changeset
768 ngx_uint_t i;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
769 ngx_quic_ciphers_t ciphers;
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
770 u_char nonce[12], mask[16];
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
771
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
772 out.len = pkt->payload.len + EVP_GCM_TLS_TAG_LEN;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
773
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
774 ad.data = res->data;
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
775 ad.len = ngx_quic_create_long_header(pkt, ad.data, out.len, &pnp);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
776
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
777 out.data = res->data + ad.len;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
778
7836
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7816
diff changeset
779 #ifdef NGX_QUIC_DEBUG_CRYPTO
7837
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 7836
diff changeset
780 ngx_quic_hexdump(pkt->log, "quic ad", ad.data, ad.len);
7836
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7816
diff changeset
781 #endif
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
782
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
783 if (ngx_quic_ciphers(ssl_conn, &ciphers, pkt->level) == NGX_ERROR) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
784 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
785 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
786
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
787 ngx_memcpy(nonce, pkt->secret->iv.data, pkt->secret->iv.len);
7776
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7773
diff changeset
788 ngx_quic_compute_nonce(nonce, sizeof(nonce), pkt->number);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
789
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
790 if (ngx_quic_tls_seal(ciphers.c, pkt->secret, &out,
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
791 nonce, &pkt->payload, &ad, pkt->log)
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
792 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
793 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
794 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
795 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
796
7781
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 7779
diff changeset
797 sample = &out.data[4 - pkt->num_len];
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
798 if (ngx_quic_tls_hp(pkt->log, ciphers.hp, pkt->secret, mask, sample)
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
799 != NGX_OK)
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
800 {
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
801 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
802 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
803
7781
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 7779
diff changeset
804 /* quic-tls: 5.4.1. Header Protection Application */
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
805 ad.data[0] ^= mask[0] & 0x0f;
7781
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 7779
diff changeset
806
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 7779
diff changeset
807 for (i = 0; i < pkt->num_len; i++) {
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 7779
diff changeset
808 pnp[i] ^= mask[i + 1];
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 7779
diff changeset
809 }
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
810
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
811 res->len = ad.len + out.len;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
812
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
813 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
814 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
815
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
816
7853
2d0f4aa78ed6 Restored ngx_quic_encrypt return type.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7852
diff changeset
817 static ngx_int_t
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
818 ngx_quic_create_short_packet(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn,
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
819 ngx_str_t *res)
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
820 {
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
821 u_char *pnp, *sample;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
822 ngx_str_t ad, out;
7781
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 7779
diff changeset
823 ngx_uint_t i;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
824 ngx_quic_ciphers_t ciphers;
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
825 u_char nonce[12], mask[16];
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
826
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
827 out.len = pkt->payload.len + EVP_GCM_TLS_TAG_LEN;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
828
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
829 ad.data = res->data;
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
830 ad.len = ngx_quic_create_short_header(pkt, ad.data, out.len, &pnp);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
831
7784
1bb5e8538d0c Removed excessive debugging in QUIC packet creation.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7783
diff changeset
832 out.data = res->data + ad.len;
1bb5e8538d0c Removed excessive debugging in QUIC packet creation.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7783
diff changeset
833
7836
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7816
diff changeset
834 #ifdef NGX_QUIC_DEBUG_CRYPTO
7837
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 7836
diff changeset
835 ngx_quic_hexdump(pkt->log, "quic ad", ad.data, ad.len);
7836
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7816
diff changeset
836 #endif
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
837
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
838 if (ngx_quic_ciphers(ssl_conn, &ciphers, pkt->level) == NGX_ERROR) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
839 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
840 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
841
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
842 ngx_memcpy(nonce, pkt->secret->iv.data, pkt->secret->iv.len);
7776
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7773
diff changeset
843 ngx_quic_compute_nonce(nonce, sizeof(nonce), pkt->number);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
844
7784
1bb5e8538d0c Removed excessive debugging in QUIC packet creation.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7783
diff changeset
845 if (ngx_quic_tls_seal(ciphers.c, pkt->secret, &out,
1bb5e8538d0c Removed excessive debugging in QUIC packet creation.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7783
diff changeset
846 nonce, &pkt->payload, &ad, pkt->log)
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
847 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
848 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
849 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
850 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
851
7781
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 7779
diff changeset
852 sample = &out.data[4 - pkt->num_len];
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
853 if (ngx_quic_tls_hp(pkt->log, ciphers.hp, pkt->secret, mask, sample)
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
854 != NGX_OK)
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
855 {
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
856 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
857 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
858
7781
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 7779
diff changeset
859 /* quic-tls: 5.4.1. Header Protection Application */
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
860 ad.data[0] ^= mask[0] & 0x1f;
7781
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 7779
diff changeset
861
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 7779
diff changeset
862 for (i = 0; i < pkt->num_len; i++) {
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 7779
diff changeset
863 pnp[i] ^= mask[i + 1];
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 7779
diff changeset
864 }
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
865
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
866 res->len = ad.len + out.len;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
867
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
868 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
869 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
870
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
871
7860
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
872 static ngx_int_t
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
873 ngx_quic_create_retry_packet(ngx_quic_header_t *pkt, ngx_str_t *res)
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
874 {
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
875 u_char *start;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
876 ngx_str_t ad, itag;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
877 ngx_quic_secret_t secret;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
878 ngx_quic_ciphers_t ciphers;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
879
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
880 /* 5.8. Retry Packet Integrity */
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
881 static u_char key[16] =
7943
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7941
diff changeset
882 #if (NGX_QUIC_DRAFT_VERSION >= 29)
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7941
diff changeset
883 "\xcc\xce\x18\x7e\xd0\x9a\x09\xd0\x57\x28\x15\x5a\x6c\xb9\x6b\xe1";
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7941
diff changeset
884 #else
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7941
diff changeset
885 "\x4d\x32\xec\xdb\x2a\x21\x33\xc8\x41\xe4\x04\x3d\xf2\x7d\x44\x30";
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7941
diff changeset
886 #endif
7860
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
887 static u_char nonce[12] =
7943
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7941
diff changeset
888 #if (NGX_QUIC_DRAFT_VERSION >= 29)
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7941
diff changeset
889 "\xe5\x49\x30\xf9\x7f\x21\x36\xf0\x53\x0a\x8c\x1c";
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7941
diff changeset
890 #else
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7941
diff changeset
891 "\x4d\x16\x11\xd0\x55\x13\xa5\x52\xc5\x87\xd5\x75";
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7941
diff changeset
892 #endif
7860
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
893 static ngx_str_t in = ngx_string("");
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
894
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
895 ad.data = res->data;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
896 ad.len = ngx_quic_create_retry_itag(pkt, ad.data, &start);
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
897
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
898 itag.data = ad.data + ad.len;
7871
df18ae7161b8 Assorted fixes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7863
diff changeset
899 itag.len = EVP_GCM_TLS_TAG_LEN;
7860
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
900
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
901 #ifdef NGX_QUIC_DEBUG_CRYPTO
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
902 ngx_quic_hexdump(pkt->log, "quic retry itag", ad.data, ad.len);
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
903 #endif
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
904
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
905 if (ngx_quic_ciphers(NULL, &ciphers, pkt->level) == NGX_ERROR) {
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
906 return NGX_ERROR;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
907 }
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
908
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
909 secret.key.len = sizeof(key);
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
910 secret.key.data = key;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
911 secret.iv.len = sizeof(nonce);
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
912
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
913 if (ngx_quic_tls_seal(ciphers.c, &secret, &itag, nonce, &in, &ad, pkt->log)
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
914 != NGX_OK)
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
915 {
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
916 return NGX_ERROR;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
917 }
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
918
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
919 res->len = itag.data + itag.len - start;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
920 res->data = start;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
921
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
922 return NGX_OK;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
923 }
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
924
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
925
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
926 static uint64_t
7816
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
927 ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask,
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
928 uint64_t *largest_pn)
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
929 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
930 u_char *p;
7816
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
931 uint64_t truncated_pn, expected_pn, candidate_pn;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
932 uint64_t pn_nbits, pn_win, pn_hwin, pn_mask;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
933
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
934 pn_nbits = ngx_min(len * 8, 62);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
935
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
936 p = *pos;
7816
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
937 truncated_pn = *p++ ^ *mask++;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
938
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
939 while (--len) {
7816
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
940 truncated_pn = (truncated_pn << 8) + (*p++ ^ *mask++);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
941 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
942
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
943 *pos = p;
7816
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
944
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
945 expected_pn = *largest_pn + 1;
7871
df18ae7161b8 Assorted fixes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7863
diff changeset
946 pn_win = 1ULL << pn_nbits;
7816
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
947 pn_hwin = pn_win / 2;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
948 pn_mask = pn_win - 1;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
949
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
950 candidate_pn = (expected_pn & ~pn_mask) | truncated_pn;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
951
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
952 if ((int64_t) candidate_pn <= (int64_t) (expected_pn - pn_hwin)
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
953 && candidate_pn < (1ULL << 62) - pn_win)
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
954 {
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
955 candidate_pn += pn_win;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
956
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
957 } else if (candidate_pn > expected_pn + pn_hwin
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
958 && candidate_pn >= pn_win)
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
959 {
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
960 candidate_pn -= pn_win;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
961 }
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
962
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
963 *largest_pn = ngx_max((int64_t) *largest_pn, (int64_t) candidate_pn);
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
964
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
965 return candidate_pn;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
966 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
967
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
968
7776
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7773
diff changeset
969 static void
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7773
diff changeset
970 ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn)
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7773
diff changeset
971 {
7779
c625bde6cb77 Fixed computing nonce again, by properly shifting packet number.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7776
diff changeset
972 nonce[len - 4] ^= (pn & 0xff000000) >> 24;
c625bde6cb77 Fixed computing nonce again, by properly shifting packet number.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7776
diff changeset
973 nonce[len - 3] ^= (pn & 0x00ff0000) >> 16;
c625bde6cb77 Fixed computing nonce again, by properly shifting packet number.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7776
diff changeset
974 nonce[len - 2] ^= (pn & 0x0000ff00) >> 8;
c625bde6cb77 Fixed computing nonce again, by properly shifting packet number.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7776
diff changeset
975 nonce[len - 1] ^= (pn & 0x000000ff);
7776
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7773
diff changeset
976 }
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7773
diff changeset
977
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7773
diff changeset
978
7853
2d0f4aa78ed6 Restored ngx_quic_encrypt return type.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7852
diff changeset
979 ngx_int_t
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
980 ngx_quic_encrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn,
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
981 ngx_str_t *res)
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
982 {
7847
262396242352 Reworked macros for parsing/assembling packet types.
Vladimir Homutov <vl@nginx.com>
parents: 7837
diff changeset
983 if (ngx_quic_short_pkt(pkt->flags)) {
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
984 return ngx_quic_create_short_packet(pkt, ssl_conn, res);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
985 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
986
7860
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
987 if (ngx_quic_pkt_retry(pkt->flags)) {
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
988 return ngx_quic_create_retry_packet(pkt, res);
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
989 }
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7853
diff changeset
990
7751
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 7731
diff changeset
991 return ngx_quic_create_long_packet(pkt, ssl_conn, res);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
992 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
993
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
994
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
995 ngx_int_t
7816
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
996 ngx_quic_decrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn,
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7790
diff changeset
997 uint64_t *largest_pn)
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
998 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
999 u_char clearflags, *p, *sample;
7863
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1000 uint8_t badflags;
8070
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8063
diff changeset
1001 uint64_t pn, lpn;
7785
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
1002 ngx_int_t pnl, rc, key_phase;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1003 ngx_str_t in, ad;
7785
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
1004 ngx_quic_secret_t *secret;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1005 ngx_quic_ciphers_t ciphers;
7754
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 7753
diff changeset
1006 uint8_t mask[16], nonce[12];
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1007
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1008 if (ngx_quic_ciphers(ssl_conn, &ciphers, pkt->level) == NGX_ERROR) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1009 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1010 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1011
7785
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
1012 secret = pkt->secret;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
1013
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1014 p = pkt->raw->pos;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1015
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1016 /* draft-ietf-quic-tls-23#section-5.4.2:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1017 * the Packet Number field is assumed to be 4 bytes long
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1018 * draft-ietf-quic-tls-23#section-5.4.[34]:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1019 * AES-Based and ChaCha20-Based header protections sample 16 bytes
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1020 */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1021
8081
9aedab0f0dff QUIC: check that the packet length is of at least sample size.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8080
diff changeset
1022 if (pkt->len < EVP_GCM_TLS_TAG_LEN + 4) {
9aedab0f0dff QUIC: check that the packet length is of at least sample size.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8080
diff changeset
1023 return NGX_DECLINED;
9aedab0f0dff QUIC: check that the packet length is of at least sample size.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8080
diff changeset
1024 }
9aedab0f0dff QUIC: check that the packet length is of at least sample size.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8080
diff changeset
1025
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1026 sample = p + 4;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1027
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1028 /* header protection */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1029
7785
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
1030 if (ngx_quic_tls_hp(pkt->log, ciphers.hp, secret, mask, sample)
7753
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7751
diff changeset
1031 != NGX_OK)
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7751
diff changeset
1032 {
7941
df29219988bc Discard short packets which could not be decrypted.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7940
diff changeset
1033 return NGX_DECLINED;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1034 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1035
7717
c217a907ce42 Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents: 7690
diff changeset
1036 if (ngx_quic_long_pkt(pkt->flags)) {
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1037 clearflags = pkt->flags ^ (mask[0] & 0x0f);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1038
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1039 } else {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1040 clearflags = pkt->flags ^ (mask[0] & 0x1f);
7785
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
1041 key_phase = (clearflags & NGX_QUIC_PKT_KPHASE) != 0;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
1042
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
1043 if (key_phase != pkt->key_phase) {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
1044 secret = pkt->next;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
1045 pkt->key_update = 1;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
1046 }
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1047 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1048
8070
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8063
diff changeset
1049 lpn = *largest_pn;
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8063
diff changeset
1050
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1051 pnl = (clearflags & 0x03) + 1;
8070
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8063
diff changeset
1052 pn = ngx_quic_parse_pn(&p, pnl, &mask[1], &lpn);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1053
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1054 pkt->pn = pn;
7852
0aa6b02a1546 Store clearflags in pkt->flags after decryption.
Vladimir Homutov <vl@nginx.com>
parents: 7847
diff changeset
1055 pkt->flags = clearflags;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1056
7753
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7751
diff changeset
1057 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
7996
d2f716e668e8 Fixed format specifiers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7943
diff changeset
1058 "quic clear flags: %xd", clearflags);
7753
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7751
diff changeset
1059 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1060 "quic packet number: %uL, len: %xi", pn, pnl);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1061
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1062 /* packet protection */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1063
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1064 in.data = p;
8080
d3489d225f8f QUIC: update packet length for short packets too.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8074
diff changeset
1065 in.len = pkt->len - pnl;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1066
7717
c217a907ce42 Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents: 7690
diff changeset
1067 if (ngx_quic_long_pkt(pkt->flags)) {
7863
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1068 badflags = clearflags & NGX_QUIC_PKT_LONG_RESERVED_BIT;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1069
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1070 } else {
7863
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1071 badflags = clearflags & NGX_QUIC_PKT_SHORT_RESERVED_BIT;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1072 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1073
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1074 ad.len = p - pkt->data;
7754
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 7753
diff changeset
1075 ad.data = pkt->plaintext;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1076
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1077 ngx_memcpy(ad.data, pkt->data, ad.len);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1078 ad.data[0] = clearflags;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1079
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1080 do {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1081 ad.data[ad.len - pnl] = pn >> (8 * (pnl - 1)) % 256;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1082 } while (--pnl);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1083
7785
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
1084 ngx_memcpy(nonce, secret->iv.data, secret->iv.len);
7776
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7773
diff changeset
1085 ngx_quic_compute_nonce(nonce, sizeof(nonce), pn);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1086
7836
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7816
diff changeset
1087 #ifdef NGX_QUIC_DEBUG_CRYPTO
7837
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 7836
diff changeset
1088 ngx_quic_hexdump(pkt->log, "quic ad", ad.data, ad.len);
7836
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7816
diff changeset
1089 #endif
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1090
7754
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 7753
diff changeset
1091 pkt->payload.len = in.len - EVP_GCM_TLS_TAG_LEN;
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 7753
diff changeset
1092 pkt->payload.data = pkt->plaintext + ad.len;
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 7753
diff changeset
1093
7785
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7784
diff changeset
1094 rc = ngx_quic_tls_open(ciphers.c, secret, &pkt->payload,
7753
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7751
diff changeset
1095 nonce, &in, &ad, pkt->log);
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1096
7836
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7816
diff changeset
1097 #if defined(NGX_QUIC_DEBUG_CRYPTO) && defined(NGX_QUIC_DEBUG_PACKETS)
7837
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 7836
diff changeset
1098 ngx_quic_hexdump(pkt->log, "quic packet payload",
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 7836
diff changeset
1099 pkt->payload.data, pkt->payload.len);
7836
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 7816
diff changeset
1100 #endif
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1101
7863
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1102 if (rc != NGX_OK) {
7941
df29219988bc Discard short packets which could not be decrypted.
Sergey Kandaurov <pluknet@nginx.com>
parents: 7940
diff changeset
1103 return NGX_DECLINED;
7863
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1104 }
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1105
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1106 if (badflags) {
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1107 /*
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1108 * An endpoint MUST treat receipt of a packet that has
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1109 * a non-zero value for these bits, after removing both
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1110 * packet and header protection, as a connection error
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1111 * of type PROTOCOL_VIOLATION.
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1112 */
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1113 ngx_log_error(NGX_LOG_INFO, pkt->log, 0,
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1114 "quic reserved bit set in packet");
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1115 pkt->error = NGX_QUIC_ERR_PROTOCOL_VIOLATION;
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1116 return NGX_ERROR;
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1117 }
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1118
8070
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8063
diff changeset
1119 *largest_pn = lpn;
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8063
diff changeset
1120
7863
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 7860
diff changeset
1121 return NGX_OK;
7687
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1122 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1123