annotate src/event/ngx_event_quic_protection.c @ 8542:d3489d225f8f quic

QUIC: update packet length for short packets too. During long packet header parsing, pkt->len is updated with the Length field value that is used to find next coalesced packets in a datagram. For short packets it still contained the whole QUIC packet size. This change uniforms packet length handling to always contain the total length of the packet number and protected packet payload in pkt->len.
author Sergey Kandaurov <pluknet@nginx.com>
date Tue, 08 Sep 2020 13:27:39 +0300
parents c6b963de0c00
children 9aedab0f0dff
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8221
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>
8486
d0ac4449a07f QUIC: fixed bulding perl module by reducing header pollution.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8478
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: 8478
diff changeset
11 #include <ngx_event_quic_protection.h>
8221
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
8339
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
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: 8324
diff changeset
42 uint64_t *largest_pn);
8310
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8307
diff changeset
43 static void ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn);
8221
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
8288
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
47 static ngx_int_t ngx_quic_tls_open(const ngx_quic_cipher_t *cipher,
8221
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,
8287
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8285
diff changeset
49 ngx_str_t *ad, ngx_log_t *log);
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
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: 8265
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: 8265
diff changeset
52 ngx_str_t *ad, ngx_log_t *log);
8221
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
8376
2d0f4aa78ed6 Restored ngx_quic_encrypt return type.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8375
diff changeset
58 static ngx_int_t ngx_quic_create_long_packet(ngx_quic_header_t *pkt,
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
59 ngx_ssl_conn_t *ssl_conn, ngx_str_t *res);
8376
2d0f4aa78ed6 Restored ngx_quic_encrypt return type.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8375
diff changeset
60 static ngx_int_t ngx_quic_create_short_packet(ngx_quic_header_t *pkt,
8299
Sergey Kandaurov <pluknet@nginx.com>
parents: 8288
diff changeset
61 ngx_ssl_conn_t *ssl_conn, ngx_str_t *res);
8383
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
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: 8376
diff changeset
63 ngx_str_t *res);
8221
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 {
8324
7cca3624f9c4 Added check for SSL_get_current_cipher() results.
Vladimir Homutov <vl@nginx.com>
parents: 8319
diff changeset
70 ngx_int_t id, len;
7cca3624f9c4 Added check for SSL_get_current_cipher() results.
Vladimir Homutov <vl@nginx.com>
parents: 8319
diff changeset
71 const SSL_CIPHER *cipher;
8221
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 {
8324
7cca3624f9c4 Added check for SSL_get_current_cipher() results.
Vladimir Homutov <vl@nginx.com>
parents: 8319
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: 8319
diff changeset
78 if (cipher == NULL) {
7cca3624f9c4 Added check for SSL_get_current_cipher() results.
Vladimir Homutov <vl@nginx.com>
parents: 8319
diff changeset
79 return NGX_ERROR;
7cca3624f9c4 Added check for SSL_get_current_cipher() results.
Vladimir Homutov <vl@nginx.com>
parents: 8319
diff changeset
80 }
7cca3624f9c4 Added check for SSL_get_current_cipher() results.
Vladimir Homutov <vl@nginx.com>
parents: 8319
diff changeset
81
7cca3624f9c4 Added check for SSL_get_current_cipher() results.
Vladimir Homutov <vl@nginx.com>
parents: 8319
diff changeset
82 id = SSL_CIPHER_get_id(cipher) & 0xffff;
8221
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
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
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: 8303
diff changeset
134 ngx_quic_secret_t *server, ngx_str_t *secret)
8221
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] =
8448
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8446
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: 8446
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: 8446
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: 8446
diff changeset
146 #else
8221
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";
8448
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8446
diff changeset
149 #endif
8221
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
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
168 #ifdef NGX_QUIC_DEBUG_CRYPTO
8360
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
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: 8359
diff changeset
170 "quic ngx_quic_set_initial_secret");
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
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: 8359
diff changeset
172 ngx_quic_hexdump(pool->log, "quic initial secret", is, is_len);
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
173 #endif
8221
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 */
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
176 client->secret.len = SHA256_DIGEST_LENGTH;
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
177 server->secret.len = SHA256_DIGEST_LENGTH;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
178
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
179 client->key.len = EVP_CIPHER_key_length(cipher);
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
180 server->key.len = EVP_CIPHER_key_length(cipher);
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
181
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
182 client->hp.len = EVP_CIPHER_key_length(cipher);
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
183 server->hp.len = EVP_CIPHER_key_length(cipher);
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
184
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
185 client->iv.len = EVP_CIPHER_iv_length(cipher);
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
186 server->iv.len = EVP_CIPHER_iv_length(cipher);
8221
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 */
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
195 { ngx_string("tls13 client in"), &client->secret, &iss },
8221
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"),
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
198 &client->key,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
199 &client->secret,
8221
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"),
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
203 &client->iv,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
204 &client->secret,
8221
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"),
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
209 &client->hp,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
210 &client->secret,
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
211 },
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
212 { ngx_string("tls13 server in"), &server->secret, &iss },
8221
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"),
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
216 &server->key,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
217 &server->secret,
8221
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"),
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
221 &server->iv,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
222 &server->secret,
8221
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"),
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
227 &server->hp,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
228 &server->secret,
8221
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) {
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
256 out->data = ngx_pnalloc(pool, out->len);
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
257 if (out->data == NULL) {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
258 return NGX_ERROR;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
259 }
8221
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
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
279 #ifdef NGX_QUIC_DEBUG_CRYPTO
8525
64a484fd40a9 QUIC: stripped down debug traces that have served its purpose.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8486
diff changeset
280 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pool->log, 0, "quic expand %V", label);
8360
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
diff changeset
281 ngx_quic_hexdump(pool->log, "quic key", out->data, out->len);
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
282 #endif
8221
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
8288
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
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: 8287
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: 8287
diff changeset
385 ngx_log_t *log)
8221
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
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
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: 8265
diff changeset
484 ngx_str_t *out, u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
8221
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,
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
632 size_t secret_len, ngx_quic_secret_t *peer_secret)
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
633 {
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
634 ngx_int_t key_len;
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
635 ngx_uint_t i;
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
636 ngx_quic_ciphers_t ciphers;
8221
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
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
645 if (level == ssl_encryption_initial) {
8221
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
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
649 peer_secret->secret.data = ngx_pnalloc(pool, secret_len);
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
650 if (peer_secret->secret.data == NULL) {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
651 return NGX_ERROR;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
652 }
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
653
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
654 peer_secret->secret.len = secret_len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
655 ngx_memcpy(peer_secret->secret.data, secret, secret_len);
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
656
8221
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
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
685 ngx_int_t
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
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: 8318
diff changeset
687 ngx_quic_secrets_t *next)
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
688 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
689 ngx_uint_t i;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
690 ngx_quic_ciphers_t ciphers;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
691
8360
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
diff changeset
692 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic key update");
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
693
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
694 if (ngx_quic_ciphers(c->ssl->connection, &ciphers,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
695 ssl_encryption_application)
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
696 == NGX_ERROR)
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
697 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
698 return NGX_ERROR;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
699 }
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
700
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
701 next->client.secret.len = current->client.secret.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
702 next->client.key.len = current->client.key.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
703 next->client.iv.len = current->client.iv.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
704 next->client.hp = current->client.hp;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
705
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
706 next->server.secret.len = current->server.secret.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
707 next->server.key.len = current->server.key.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
708 next->server.iv.len = current->server.iv.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
709 next->server.hp = current->server.hp;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
710
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
711 struct {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
712 ngx_str_t label;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
713 ngx_str_t *key;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
714 ngx_str_t *secret;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
715 } seq[] = {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
716 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
717 ngx_string("tls13 quic ku"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
718 &next->client.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
719 &current->client.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
720 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
721 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
722 ngx_string("tls13 quic key"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
723 &next->client.key,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
724 &next->client.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
725 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
726 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
727 ngx_string("tls13 quic iv"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
728 &next->client.iv,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
729 &next->client.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
730 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
731 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
732 ngx_string("tls13 quic ku"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
733 &next->server.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
734 &current->server.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
735 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
736 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
737 ngx_string("tls13 quic key"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
738 &next->server.key,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
739 &next->server.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
740 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
741 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
742 ngx_string("tls13 quic iv"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
743 &next->server.iv,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
744 &next->server.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
745 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
746 };
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
747
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
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: 8318
diff changeset
749
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
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: 8318
diff changeset
751 seq[i].secret->data, seq[i].secret->len)
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
752 != NGX_OK)
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
753 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
754 return NGX_ERROR;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
755 }
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
756 }
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
757
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
758 return NGX_OK;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
759 }
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
760
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
761
8376
2d0f4aa78ed6 Restored ngx_quic_encrypt return type.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8375
diff changeset
762 static ngx_int_t
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
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: 8265
diff changeset
764 ngx_str_t *res)
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
765 {
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
766 u_char *pnp, *sample;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
767 ngx_str_t ad, out;
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
768 ngx_uint_t i;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
769 ngx_quic_ciphers_t ciphers;
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
770 u_char nonce[12], mask[16];
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
771
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
772 out.len = pkt->payload.len + EVP_GCM_TLS_TAG_LEN;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
773
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
774 ad.data = res->data;
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
775 ad.len = ngx_quic_create_long_header(pkt, ad.data, out.len, &pnp);
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
776
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
777 out.data = res->data + ad.len;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
778
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
779 #ifdef NGX_QUIC_DEBUG_CRYPTO
8360
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
diff changeset
780 ngx_quic_hexdump(pkt->log, "quic ad", ad.data, ad.len);
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
781 #endif
8221
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
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
787 ngx_memcpy(nonce, pkt->secret->iv.data, pkt->secret->iv.len);
8310
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8307
diff changeset
788 ngx_quic_compute_nonce(nonce, sizeof(nonce), pkt->number);
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
789
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
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: 8265
diff changeset
791 nonce, &pkt->payload, &ad, pkt->log)
8221
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
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
797 sample = &out.data[4 - pkt->num_len];
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
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: 8265
diff changeset
799 != NGX_OK)
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
800 {
8221
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
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
804 /* quic-tls: 5.4.1. Header Protection Application */
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
805 ad.data[0] ^= mask[0] & 0x0f;
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
806
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
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: 8313
diff changeset
808 pnp[i] ^= mask[i + 1];
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
809 }
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
810
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
811 res->len = ad.len + out.len;
8221
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
8376
2d0f4aa78ed6 Restored ngx_quic_encrypt return type.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8375
diff changeset
817 static ngx_int_t
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
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: 8265
diff changeset
819 ngx_str_t *res)
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
820 {
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
821 u_char *pnp, *sample;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
822 ngx_str_t ad, out;
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
823 ngx_uint_t i;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
824 ngx_quic_ciphers_t ciphers;
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
825 u_char nonce[12], mask[16];
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
826
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
827 out.len = pkt->payload.len + EVP_GCM_TLS_TAG_LEN;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
828
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
829 ad.data = res->data;
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
830 ad.len = ngx_quic_create_short_header(pkt, ad.data, out.len, &pnp);
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
831
8318
1bb5e8538d0c Removed excessive debugging in QUIC packet creation.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8317
diff changeset
832 out.data = res->data + ad.len;
1bb5e8538d0c Removed excessive debugging in QUIC packet creation.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8317
diff changeset
833
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
834 #ifdef NGX_QUIC_DEBUG_CRYPTO
8360
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
diff changeset
835 ngx_quic_hexdump(pkt->log, "quic ad", ad.data, ad.len);
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
836 #endif
8221
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
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
842 ngx_memcpy(nonce, pkt->secret->iv.data, pkt->secret->iv.len);
8310
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8307
diff changeset
843 ngx_quic_compute_nonce(nonce, sizeof(nonce), pkt->number);
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
844
8318
1bb5e8538d0c Removed excessive debugging in QUIC packet creation.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8317
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: 8317
diff changeset
846 nonce, &pkt->payload, &ad, pkt->log)
8221
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
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
852 sample = &out.data[4 - pkt->num_len];
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
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: 8265
diff changeset
854 != NGX_OK)
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
855 {
8221
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
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
859 /* quic-tls: 5.4.1. Header Protection Application */
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
860 ad.data[0] ^= mask[0] & 0x1f;
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
861
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
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: 8313
diff changeset
863 pnp[i] ^= mask[i + 1];
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
864 }
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
865
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
866 res->len = ad.len + out.len;
8221
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
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
871
8383
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
872 static ngx_int_t
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
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: 8376
diff changeset
874 {
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
875 u_char *start;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
876 ngx_str_t ad, itag;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
877 ngx_quic_secret_t secret;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
878 ngx_quic_ciphers_t ciphers;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
879
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
880 /* 5.8. Retry Packet Integrity */
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
881 static u_char key[16] =
8448
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8446
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: 8446
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: 8446
diff changeset
884 #else
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8446
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: 8446
diff changeset
886 #endif
8383
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
887 static u_char nonce[12] =
8448
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8446
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: 8446
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: 8446
diff changeset
890 #else
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8446
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: 8446
diff changeset
892 #endif
8383
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
893 static ngx_str_t in = ngx_string("");
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
894
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
895 ad.data = res->data;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
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: 8376
diff changeset
897
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
898 itag.data = ad.data + ad.len;
8394
df18ae7161b8 Assorted fixes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8386
diff changeset
899 itag.len = EVP_GCM_TLS_TAG_LEN;
8383
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
900
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
901 #ifdef NGX_QUIC_DEBUG_CRYPTO
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
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: 8376
diff changeset
903 #endif
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
904
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
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: 8376
diff changeset
906 return NGX_ERROR;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
907 }
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
908
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
909 secret.key.len = sizeof(key);
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
910 secret.key.data = key;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
911 secret.iv.len = sizeof(nonce);
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
912
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
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: 8376
diff changeset
914 != NGX_OK)
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
915 {
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
916 return NGX_ERROR;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
917 }
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
918
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
919 res->len = itag.data + itag.len - start;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
920 res->data = start;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
921
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
922 return NGX_OK;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
923 }
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
924
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
925
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
926 static uint64_t
8339
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
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: 8324
diff changeset
928 uint64_t *largest_pn)
8221
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;
8339
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
931 uint64_t truncated_pn, expected_pn, candidate_pn;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
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: 8324
diff changeset
933
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
934 pn_nbits = ngx_min(len * 8, 62);
8221
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;
8339
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
937 truncated_pn = *p++ ^ *mask++;
8221
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) {
8339
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
940 truncated_pn = (truncated_pn << 8) + (*p++ ^ *mask++);
8221
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;
8339
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
944
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
945 expected_pn = *largest_pn + 1;
8394
df18ae7161b8 Assorted fixes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8386
diff changeset
946 pn_win = 1ULL << pn_nbits;
8339
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
947 pn_hwin = pn_win / 2;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
948 pn_mask = pn_win - 1;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
949
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
950 candidate_pn = (expected_pn & ~pn_mask) | truncated_pn;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
951
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
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: 8324
diff changeset
953 && candidate_pn < (1ULL << 62) - pn_win)
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
954 {
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
955 candidate_pn += pn_win;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
956
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
957 } else if (candidate_pn > expected_pn + pn_hwin
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
958 && candidate_pn >= pn_win)
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
959 {
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
960 candidate_pn -= pn_win;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
961 }
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
962
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
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: 8324
diff changeset
964
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
965 return candidate_pn;
8221
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
8310
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8307
diff changeset
969 static void
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8307
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: 8307
diff changeset
971 {
8313
c625bde6cb77 Fixed computing nonce again, by properly shifting packet number.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8310
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: 8310
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: 8310
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: 8310
diff changeset
975 nonce[len - 1] ^= (pn & 0x000000ff);
8310
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8307
diff changeset
976 }
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8307
diff changeset
977
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8307
diff changeset
978
8376
2d0f4aa78ed6 Restored ngx_quic_encrypt return type.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8375
diff changeset
979 ngx_int_t
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
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: 8265
diff changeset
981 ngx_str_t *res)
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
982 {
8370
262396242352 Reworked macros for parsing/assembling packet types.
Vladimir Homutov <vl@nginx.com>
parents: 8360
diff changeset
983 if (ngx_quic_short_pkt(pkt->flags)) {
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
984 return ngx_quic_create_short_packet(pkt, ssl_conn, res);
8221
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
8383
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
987 if (ngx_quic_pkt_retry(pkt->flags)) {
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
988 return ngx_quic_create_retry_packet(pkt, res);
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
989 }
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
990
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
991 return ngx_quic_create_long_packet(pkt, ssl_conn, res);
8221
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
8339
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
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: 8324
diff changeset
997 uint64_t *largest_pn)
8221
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;
8386
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1000 uint8_t badflags;
8532
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8525
diff changeset
1001 uint64_t pn, lpn;
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1002 ngx_int_t pnl, rc, key_phase;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1003 ngx_str_t in, ad;
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1004 ngx_quic_secret_t *secret;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1005 ngx_quic_ciphers_t ciphers;
8288
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
1006 uint8_t mask[16], nonce[12];
8221
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
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1012 secret = pkt->secret;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1013
8221
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1022 sample = p + 4;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1023
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1024 /* header protection */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1025
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1026 if (ngx_quic_tls_hp(pkt->log, ciphers.hp, secret, mask, sample)
8287
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8285
diff changeset
1027 != NGX_OK)
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8285
diff changeset
1028 {
8446
df29219988bc Discard short packets which could not be decrypted.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8445
diff changeset
1029 return NGX_DECLINED;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1030 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1031
8251
c217a907ce42 Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents: 8224
diff changeset
1032 if (ngx_quic_long_pkt(pkt->flags)) {
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1033 clearflags = pkt->flags ^ (mask[0] & 0x0f);
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 } else {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1036 clearflags = pkt->flags ^ (mask[0] & 0x1f);
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1037 key_phase = (clearflags & NGX_QUIC_PKT_KPHASE) != 0;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1038
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1039 if (key_phase != pkt->key_phase) {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1040 secret = pkt->next;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1041 pkt->key_update = 1;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1042 }
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1043 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1044
8532
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8525
diff changeset
1045 lpn = *largest_pn;
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8525
diff changeset
1046
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1047 pnl = (clearflags & 0x03) + 1;
8532
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8525
diff changeset
1048 pn = ngx_quic_parse_pn(&p, pnl, &mask[1], &lpn);
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1049
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1050 pkt->pn = pn;
8375
0aa6b02a1546 Store clearflags in pkt->flags after decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8370
diff changeset
1051 pkt->flags = clearflags;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1052
8287
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8285
diff changeset
1053 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
8478
d2f716e668e8 Fixed format specifiers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8448
diff changeset
1054 "quic clear flags: %xd", clearflags);
8287
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8285
diff changeset
1055 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1056 "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
1057
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1058 /* packet protection */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1059
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1060 in.data = p;
8542
d3489d225f8f QUIC: update packet length for short packets too.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8536
diff changeset
1061 in.len = pkt->len - pnl;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1062
8251
c217a907ce42 Added checks for permitted frame types.
Vladimir Homutov <vl@nginx.com>
parents: 8224
diff changeset
1063 if (ngx_quic_long_pkt(pkt->flags)) {
8386
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1064 badflags = clearflags & NGX_QUIC_PKT_LONG_RESERVED_BIT;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1065
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1066 } else {
8386
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1067 badflags = clearflags & NGX_QUIC_PKT_SHORT_RESERVED_BIT;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1068 }
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 ad.len = p - pkt->data;
8288
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
1071 ad.data = pkt->plaintext;
8221
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 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
1074 ad.data[0] = clearflags;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1075
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1076 do {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1077 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
1078 } while (--pnl);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1079
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1080 ngx_memcpy(nonce, secret->iv.data, secret->iv.len);
8310
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8307
diff changeset
1081 ngx_quic_compute_nonce(nonce, sizeof(nonce), pn);
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1082
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
1083 #ifdef NGX_QUIC_DEBUG_CRYPTO
8360
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
diff changeset
1084 ngx_quic_hexdump(pkt->log, "quic ad", ad.data, ad.len);
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
1085 #endif
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1086
8288
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
1087 pkt->payload.len = in.len - EVP_GCM_TLS_TAG_LEN;
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
1088
8415
125cbfa77013 Renamed max_packet_size to max_udp_payload_size, from draft-28.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8394
diff changeset
1089 if (NGX_QUIC_MAX_UDP_PAYLOAD_SIZE - ad.len < pkt->payload.len) {
8288
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
1090 return NGX_ERROR;
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
1091 }
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
1092
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
1093 pkt->payload.data = pkt->plaintext + ad.len;
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
1094
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1095 rc = ngx_quic_tls_open(ciphers.c, secret, &pkt->payload,
8287
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8285
diff changeset
1096 nonce, &in, &ad, pkt->log);
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1097
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
1098 #if defined(NGX_QUIC_DEBUG_CRYPTO) && defined(NGX_QUIC_DEBUG_PACKETS)
8360
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
diff changeset
1099 ngx_quic_hexdump(pkt->log, "quic packet payload",
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
diff changeset
1100 pkt->payload.data, pkt->payload.len);
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
1101 #endif
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1102
8386
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1103 if (rc != NGX_OK) {
8446
df29219988bc Discard short packets which could not be decrypted.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8445
diff changeset
1104 return NGX_DECLINED;
8386
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1105 }
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1106
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1107 if (badflags) {
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1108 /*
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1109 * 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: 8383
diff changeset
1110 * 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: 8383
diff changeset
1111 * packet and header protection, as a connection error
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1112 * of type PROTOCOL_VIOLATION.
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1113 */
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1114 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: 8383
diff changeset
1115 "quic reserved bit set in packet");
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1116 pkt->error = NGX_QUIC_ERR_PROTOCOL_VIOLATION;
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1117 return NGX_ERROR;
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1118 }
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1119
8532
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8525
diff changeset
1120 *largest_pn = lpn;
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8525
diff changeset
1121
8386
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1122 return NGX_OK;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1123 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1124