annotate src/event/ngx_event_quic_protection.c @ 8643:5fdd0ef42232 quic

QUIC: macros for manipulating header protection and reserved bits. This gets rid of magic numbers from quic protection and allows to push down header construction specifics further to quic transport.
author Sergey Kandaurov <pluknet@nginx.com>
date Tue, 17 Nov 2020 21:32:22 +0000
parents 05b1ee464350
children e953bd2c5bb3
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
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
27
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
28 typedef struct {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
29 const ngx_quic_cipher_t *c;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
30 const EVP_CIPHER *hp;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
31 const EVP_MD *d;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
32 } ngx_quic_ciphers_t;
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
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
35 typedef struct ngx_quic_secret_s {
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
36 ngx_str_t secret;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
37 ngx_str_t key;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
38 ngx_str_t iv;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
39 ngx_str_t hp;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
40 } ngx_quic_secret_t;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
41
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
42
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
43 typedef struct {
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
44 ngx_quic_secret_t client;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
45 ngx_quic_secret_t server;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
46 } ngx_quic_secrets_t;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
47
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
48
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
49 struct ngx_quic_keys_s {
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
50 ngx_quic_secrets_t secrets[NGX_QUIC_ENCRYPTION_LAST];
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
51 ngx_quic_secrets_t next_key;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
52 ngx_uint_t cipher;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
53 };
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
54
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
55
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
56 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
57 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
58 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
59 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
60 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
61 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
62
8339
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
63 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
64 uint64_t *largest_pn);
8310
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8307
diff changeset
65 static void ngx_quic_compute_nonce(u_char *nonce, size_t len, uint64_t pn);
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
66 static ngx_int_t ngx_quic_ciphers(ngx_uint_t id,
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
67 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
68
8288
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
69 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
70 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
71 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
72 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
73 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
74 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
75 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
76 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
77 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
78 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
79
8376
2d0f4aa78ed6 Restored ngx_quic_encrypt return type.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8375
diff changeset
80 static ngx_int_t ngx_quic_create_long_packet(ngx_quic_header_t *pkt,
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
81 ngx_str_t *res);
8376
2d0f4aa78ed6 Restored ngx_quic_encrypt return type.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8375
diff changeset
82 static ngx_int_t ngx_quic_create_short_packet(ngx_quic_header_t *pkt,
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
83 ngx_str_t *res);
8383
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
84 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
85 ngx_str_t *res);
8221
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
88 static ngx_int_t
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
89 ngx_quic_ciphers(ngx_uint_t id, ngx_quic_ciphers_t *ciphers,
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
90 enum ssl_encryption_level_t level)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
91 {
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
92 ngx_int_t len;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
93
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
94 if (level == ssl_encryption_initial) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
95 id = NGX_AES_128_GCM_SHA256;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
96 }
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 switch (id) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
99
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
100 case NGX_AES_128_GCM_SHA256:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
101 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
102 ciphers->c = EVP_aead_aes_128_gcm();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
103 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
104 ciphers->c = EVP_aes_128_gcm();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
105 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
106 ciphers->hp = EVP_aes_128_ctr();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
107 ciphers->d = EVP_sha256();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
108 len = 16;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
109 break;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
110
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
111 case NGX_AES_256_GCM_SHA384:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
112 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
113 ciphers->c = EVP_aead_aes_256_gcm();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
114 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
115 ciphers->c = EVP_aes_256_gcm();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
116 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
117 ciphers->hp = EVP_aes_256_ctr();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
118 ciphers->d = EVP_sha384();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
119 len = 32;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
120 break;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
121
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
122 case NGX_CHACHA20_POLY1305_SHA256:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
123 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
124 ciphers->c = EVP_aead_chacha20_poly1305();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
125 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
126 ciphers->c = EVP_chacha20_poly1305();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
127 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
128 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
129 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
130 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
131 ciphers->hp = EVP_chacha20();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
132 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
133 ciphers->d = EVP_sha256();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
134 len = 32;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
135 break;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
136
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
137 default:
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
138 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
139 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
140
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
141 return len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
142 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
143
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
144
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
145 ngx_int_t
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
146 ngx_quic_keys_set_initial_secret(ngx_pool_t *pool, ngx_quic_keys_t *keys,
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
147 ngx_str_t *secret)
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
148 {
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
149 size_t is_len;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
150 uint8_t is[SHA256_DIGEST_LENGTH];
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
151 ngx_uint_t i;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
152 const EVP_MD *digest;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
153 const EVP_CIPHER *cipher;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
154 ngx_quic_secret_t *client, *server;
8221
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 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
157 #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
158 "\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
159 "\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
160 #else
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
161 "\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
162 "\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
163 #endif
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
164
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
165 client = &keys->secrets[ssl_encryption_initial].client;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
166 server = &keys->secrets[ssl_encryption_initial].server;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
167
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
168 /* 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
169
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
170 cipher = EVP_aes_128_gcm();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
171 digest = EVP_sha256();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
172
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
173 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
174 salt, sizeof(salt))
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
175 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
176 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
177 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
178 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
179
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
180 ngx_str_t iss = {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
181 .data = is,
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
182 .len = is_len
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
183 };
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
184
8360
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
diff changeset
185 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
186 "quic ngx_quic_set_initial_secret");
8578
52ad697f9d1c QUIC: enabled more key-related debug by default.
Vladimir Homutov <vl@nginx.com>
parents: 8565
diff changeset
187 #ifdef NGX_QUIC_DEBUG_CRYPTO
8360
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
diff changeset
188 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
189 ngx_quic_hexdump(pool->log, "quic initial secret", is, is_len);
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
190 #endif
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
191
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
192 /* draft-ietf-quic-tls-23#section-5.2 */
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
193 client->secret.len = SHA256_DIGEST_LENGTH;
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
194 server->secret.len = SHA256_DIGEST_LENGTH;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
195
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
196 client->key.len = EVP_CIPHER_key_length(cipher);
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
197 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
198
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
199 client->hp.len = EVP_CIPHER_key_length(cipher);
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
200 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
201
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
202 client->iv.len = EVP_CIPHER_iv_length(cipher);
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
203 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
204
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
205 struct {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
206 ngx_str_t label;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
207 ngx_str_t *key;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
208 ngx_str_t *prk;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
209 } seq[] = {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
210
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
211 /* draft-ietf-quic-tls-23#section-5.2 */
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
212 { 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
213 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
214 ngx_string("tls13 quic key"),
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
215 &client->key,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
216 &client->secret,
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
217 },
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 ngx_string("tls13 quic iv"),
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
220 &client->iv,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
221 &client->secret,
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
222 },
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 /* 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
225 ngx_string("tls13 quic hp"),
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
226 &client->hp,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
227 &client->secret,
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
228 },
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
229 { 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
230 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
231 /* 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
232 ngx_string("tls13 quic key"),
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
233 &server->key,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
234 &server->secret,
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
235 },
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
236 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
237 ngx_string("tls13 quic iv"),
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
238 &server->iv,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
239 &server->secret,
8221
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 /* 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
243 ngx_string("tls13 quic hp"),
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
244 &server->hp,
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
245 &server->secret,
8221
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
248 };
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
249
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
250 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
251
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
252 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
253 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
254 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
255 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
256 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
257 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
258 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
259
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
260 return NGX_OK;
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
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 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
265 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
266 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
267 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
268 size_t info_len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
269 uint8_t *p;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
270 uint8_t info[20];
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
271
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
272 if (out->data == NULL) {
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
273 out->data = ngx_pnalloc(pool, out->len);
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
274 if (out->data == NULL) {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
275 return NGX_ERROR;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
276 }
8221
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
279 info_len = 2 + 1 + label->len + 1;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
280
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
281 info[0] = 0;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
282 info[1] = out->len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
283 info[2] = label->len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
284 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
285 *p = '\0';
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 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
288 prk, prk_len, info, info_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
289 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
290 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
291 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
292 "ngx_hkdf_expand(%V) failed", label);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
293 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
294 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
295
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
296 #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
297 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
298 ngx_quic_hexdump(pool->log, "quic key", out->data, out->len);
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
299 #endif
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
300
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
301 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
302 }
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
305 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
306 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
307 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
308 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
309 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
310 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
311 == 0)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
312 {
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 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
316
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
317 EVP_PKEY_CTX *pctx;
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 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
320
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
321 if (EVP_PKEY_derive_init(pctx) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
322 return NGX_ERROR;
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
325 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
326 return NGX_ERROR;
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
329 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
330 return NGX_ERROR;
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 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
334 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
335 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
336
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
337 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
338 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
339 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
340
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
341 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
342 return NGX_ERROR;
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
345 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
346
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
347 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
348 }
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
351 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
352 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
353 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
354 size_t salt_len)
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 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
357 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
358 salt_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
359 == 0)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
360 {
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 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
364
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
365 EVP_PKEY_CTX *pctx;
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 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
368
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
369 if (EVP_PKEY_derive_init(pctx) <= 0) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
370 return NGX_ERROR;
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
373 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
374 return NGX_ERROR;
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
377 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
378 return NGX_ERROR;
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 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
382 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
383 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
384
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
385 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
386 return NGX_ERROR;
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
389 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
390 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
391 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
392
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
393 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
394
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
395 return NGX_OK;
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
399 static ngx_int_t
8288
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
400 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
401 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
402 ngx_log_t *log)
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
403 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
404
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
405 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
406 EVP_AEAD_CTX *ctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
407
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
408 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
409 EVP_AEAD_DEFAULT_TAG_LENGTH);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
410 if (ctx == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
411 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
412 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
413 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
414
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
415 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
416 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
417 != 1)
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 EVP_AEAD_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
420 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
421 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
422 }
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 EVP_AEAD_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
425 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
426 int len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
427 u_char *tag;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
428 EVP_CIPHER_CTX *ctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
429
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
430 ctx = EVP_CIPHER_CTX_new();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
431 if (ctx == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
432 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
433 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
434 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
435
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
436 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
437 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
438 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
439 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
440 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
441
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
442 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
443 == 0)
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 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
446 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
447 "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
448 return NGX_ERROR;
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
451 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
452 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
453 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
454 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
455 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
456
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
457 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
458 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
459 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
460 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
461 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
462
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
463 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
464 in->len - EVP_GCM_TLS_TAG_LEN)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
465 != 1)
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 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
468 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
469 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
470 }
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 out->len = len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
473 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
474
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
475 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
476 == 0)
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 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
479 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
480 "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
481 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
482 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
483
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
484 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
485 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
486 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
487 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
488 }
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 out->len += len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
491
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
492 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
493 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
494
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
495 return NGX_OK;
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
498
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
499 static ngx_int_t
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
500 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
501 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
502 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
503
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
504 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
505 EVP_AEAD_CTX *ctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
506
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
507 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
508 EVP_AEAD_DEFAULT_TAG_LENGTH);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
509 if (ctx == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
510 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
511 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
512 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
513
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
514 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
515 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
516 != 1)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
517 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
518 EVP_AEAD_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_AEAD_CTX_seal() 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 EVP_AEAD_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
524 #else
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
525 int len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
526 EVP_CIPHER_CTX *ctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
527
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
528 ctx = EVP_CIPHER_CTX_new();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
529 if (ctx == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
530 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
531 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
532 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
533
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
534 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
535 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
536 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
537 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
538 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
539
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
540 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
541 == 0)
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 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
544 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
545 "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
546 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
547 }
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 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
550 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
551 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
552 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
553 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
554
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
555 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
556 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
557 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
558 return NGX_ERROR;
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
561 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
562 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
563 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
564 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
565 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
566
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
567 out->len = len;
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 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
570 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
571 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
572 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
573 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
574
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
575 out->len += len;
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 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
578 out->data + in->len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
579 == 0)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
580 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
581 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
582 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
583 "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
584 return NGX_ERROR;
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
587 EVP_CIPHER_CTX_free(ctx);
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 out->len += EVP_GCM_TLS_TAG_LEN;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
590 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
591 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
592 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
593
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 static ngx_int_t
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
596 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
597 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
598 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
599 int outlen;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
600 EVP_CIPHER_CTX *ctx;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
601 u_char zero[5] = {0};
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
602
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
603 #ifdef OPENSSL_IS_BORINGSSL
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
604 uint32_t counter;
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 ngx_memcpy(&counter, in, sizeof(uint32_t));
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
607
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
608 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
609 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
610 return NGX_OK;
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 #endif
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
613
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
614 ctx = EVP_CIPHER_CTX_new();
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
615 if (ctx == NULL) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
616 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
617 }
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 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
620 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
621 goto 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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
624 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
625 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
626 goto failed;
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 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
630 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
631 goto failed;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
632 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
633
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
634 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
635
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
636 return NGX_OK;
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 failed:
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 EVP_CIPHER_CTX_free(ctx);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
641
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
642 return NGX_ERROR;
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
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
645
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
646 int ngx_quic_keys_set_encryption_secret(ngx_pool_t *pool, ngx_uint_t is_write,
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
647 ngx_quic_keys_t *keys, enum ssl_encryption_level_t level,
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
648 const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len)
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
649 {
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
650 ngx_int_t key_len;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
651 ngx_uint_t i;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
652 ngx_quic_secret_t *peer_secret;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
653 ngx_quic_ciphers_t ciphers;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
654
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
655 peer_secret = is_write ? &keys->secrets[level].server
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
656 : &keys->secrets[level].client;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
657
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
658 /*
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
659 * SSL_CIPHER_get_protocol_id() is not universally available,
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
660 * casting to uint16_t works for both OpenSSL and BoringSSL
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
661 */
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
662 keys->cipher = (uint16_t) SSL_CIPHER_get_id(cipher);
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
663
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
664 key_len = ngx_quic_ciphers(keys->cipher, &ciphers, level);
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
665
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
666 if (key_len == NGX_ERROR) {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
667 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
668 return 0;
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
8306
058a5af7ddfc Refactored QUIC secrets storage.
Vladimir Homutov <vl@nginx.com>
parents: 8303
diff changeset
671 if (level == ssl_encryption_initial) {
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
672 return 0;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
673 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
674
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
675 peer_secret->secret.data = ngx_pnalloc(pool, secret_len);
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
676 if (peer_secret->secret.data == NULL) {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
677 return NGX_ERROR;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
678 }
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
679
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
680 peer_secret->secret.len = secret_len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
681 ngx_memcpy(peer_secret->secret.data, secret, secret_len);
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
682
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
683 peer_secret->key.len = key_len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
684 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
685 peer_secret->hp.len = key_len;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
686
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
687 struct {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
688 ngx_str_t label;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
689 ngx_str_t *key;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
690 const uint8_t *secret;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
691 } seq[] = {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
692 { 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
693 { 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
694 { 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
695 };
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
696
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
697 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
698
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
699 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
700 seq[i].secret, secret_len)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
701 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
702 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
703 return 0;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
704 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
705 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
706
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
707 return 1;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
708 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
709
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
710
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
711 ngx_quic_keys_t *
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
712 ngx_quic_keys_new(ngx_pool_t *pool)
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
713 {
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
714 return ngx_pcalloc(pool, sizeof(ngx_quic_keys_t));
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
715 }
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
716
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
717
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
718 ngx_uint_t
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
719 ngx_quic_keys_available(ngx_quic_keys_t *keys,
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
720 enum ssl_encryption_level_t level)
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
721 {
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
722 return keys->secrets[level].client.key.len != 0;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
723 }
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
724
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
725
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
726 void
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
727 ngx_quic_keys_discard(ngx_quic_keys_t *keys,
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
728 enum ssl_encryption_level_t level)
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
729 {
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
730 keys->secrets[level].client.key.len = 0;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
731 }
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
732
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
733
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
734 void
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
735 ngx_quic_keys_switch(ngx_connection_t *c, ngx_quic_keys_t *keys)
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
736 {
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
737 ngx_quic_secrets_t *current, *next, tmp;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
738
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
739 current = &keys->secrets[ssl_encryption_application];
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
740 next = &keys->next_key;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
741
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
742 tmp = *current;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
743 *current = *next;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
744 *next = tmp;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
745 }
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
746
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
747
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
748 ngx_int_t
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
749 ngx_quic_keys_update(ngx_connection_t *c, ngx_quic_keys_t *keys)
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
750 {
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
751 ngx_uint_t i;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
752 ngx_quic_ciphers_t ciphers;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
753 ngx_quic_secrets_t *current, *next;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
754
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
755 current = &keys->secrets[ssl_encryption_application];
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
756 next = &keys->next_key;
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
757
8360
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
diff changeset
758 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
759
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
760 if (ngx_quic_ciphers(keys->cipher, &ciphers, ssl_encryption_application)
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
761 == NGX_ERROR)
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
762 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
763 return NGX_ERROR;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
764 }
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
765
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
766 next->client.secret.len = current->client.secret.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
767 next->client.key.len = current->client.key.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
768 next->client.iv.len = current->client.iv.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
769 next->client.hp = current->client.hp;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
770
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
771 next->server.secret.len = current->server.secret.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
772 next->server.key.len = current->server.key.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
773 next->server.iv.len = current->server.iv.len;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
774 next->server.hp = current->server.hp;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
775
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
776 struct {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
777 ngx_str_t label;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
778 ngx_str_t *key;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
779 ngx_str_t *secret;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
780 } seq[] = {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
781 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
782 ngx_string("tls13 quic ku"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
783 &next->client.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
784 &current->client.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
785 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
786 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
787 ngx_string("tls13 quic key"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
788 &next->client.key,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
789 &next->client.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
790 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
791 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
792 ngx_string("tls13 quic iv"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
793 &next->client.iv,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
794 &next->client.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
795 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
796 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
797 ngx_string("tls13 quic ku"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
798 &next->server.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
799 &current->server.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
800 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
801 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
802 ngx_string("tls13 quic key"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
803 &next->server.key,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
804 &next->server.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
805 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
806 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
807 ngx_string("tls13 quic iv"),
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
808 &next->server.iv,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
809 &next->server.secret,
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
810 },
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
811 };
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
812
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
813 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
814
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
815 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
816 seq[i].secret->data, seq[i].secret->len)
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
817 != NGX_OK)
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
818 {
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
819 return NGX_ERROR;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
820 }
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
821 }
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
822
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
823 return NGX_OK;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
824 }
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
825
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
826
8376
2d0f4aa78ed6 Restored ngx_quic_encrypt return type.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8375
diff changeset
827 static ngx_int_t
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
828 ngx_quic_create_long_packet(ngx_quic_header_t *pkt, ngx_str_t *res)
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
829 {
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
830 u_char *pnp, *sample;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
831 ngx_str_t ad, out;
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
832 ngx_uint_t i;
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
833 ngx_quic_secret_t *secret;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
834 ngx_quic_ciphers_t ciphers;
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
835 u_char nonce[12], mask[16];
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
836
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
837 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
838
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
839 ad.data = res->data;
8642
05b1ee464350 QUIC: hide header creation internals in ngx_event_quic_transport.c.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8621
diff changeset
840 ad.len = ngx_quic_create_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
841
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
842 out.data = res->data + ad.len;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
843
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
844 #ifdef NGX_QUIC_DEBUG_CRYPTO
8360
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
diff changeset
845 ngx_quic_hexdump(pkt->log, "quic ad", ad.data, ad.len);
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
846 #endif
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
847
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
848 if (ngx_quic_ciphers(pkt->keys->cipher, &ciphers, pkt->level) == NGX_ERROR)
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
849 {
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
850 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
851 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
852
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
853 secret = &pkt->keys->secrets[pkt->level].server;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
854
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
855 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
856 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
857
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
858 if (ngx_quic_tls_seal(ciphers.c, secret, &out,
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
859 nonce, &pkt->payload, &ad, pkt->log)
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
860 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
861 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
862 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
863 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
864
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
865 sample = &out.data[4 - pkt->num_len];
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
866 if (ngx_quic_tls_hp(pkt->log, ciphers.hp, secret, mask, sample)
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
867 != NGX_OK)
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
868 {
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
869 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
870 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
871
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
872 /* quic-tls: 5.4.1. Header Protection Application */
8643
5fdd0ef42232 QUIC: macros for manipulating header protection and reserved bits.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8642
diff changeset
873 ad.data[0] ^= mask[0] & ngx_quic_pkt_hp_mask(pkt->flags);
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
874
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
875 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
876 pnp[i] ^= mask[i + 1];
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
877 }
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
878
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
879 res->len = ad.len + out.len;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
880
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
881 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
882 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
883
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
884
8376
2d0f4aa78ed6 Restored ngx_quic_encrypt return type.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8375
diff changeset
885 static ngx_int_t
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
886 ngx_quic_create_short_packet(ngx_quic_header_t *pkt, ngx_str_t *res)
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
887 {
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
888 u_char *pnp, *sample;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
889 ngx_str_t ad, out;
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
890 ngx_uint_t i;
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
891 ngx_quic_secret_t *secret;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
892 ngx_quic_ciphers_t ciphers;
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
893 u_char nonce[12], mask[16];
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
894
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
895 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
896
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
897 ad.data = res->data;
8642
05b1ee464350 QUIC: hide header creation internals in ngx_event_quic_transport.c.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8621
diff changeset
898 ad.len = ngx_quic_create_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
899
8318
1bb5e8538d0c Removed excessive debugging in QUIC packet creation.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8317
diff changeset
900 out.data = res->data + ad.len;
1bb5e8538d0c Removed excessive debugging in QUIC packet creation.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8317
diff changeset
901
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
902 #ifdef NGX_QUIC_DEBUG_CRYPTO
8360
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
diff changeset
903 ngx_quic_hexdump(pkt->log, "quic ad", ad.data, ad.len);
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
904 #endif
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
905
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
906 if (ngx_quic_ciphers(pkt->keys->cipher, &ciphers, pkt->level) == NGX_ERROR)
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
907 {
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
908 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
909 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
910
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
911 secret = &pkt->keys->secrets[pkt->level].server;
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
912
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
913 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
914 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
915
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
916 if (ngx_quic_tls_seal(ciphers.c, secret, &out,
8318
1bb5e8538d0c Removed excessive debugging in QUIC packet creation.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8317
diff changeset
917 nonce, &pkt->payload, &ad, pkt->log)
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
918 != NGX_OK)
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
919 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
920 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
921 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
922
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
923 sample = &out.data[4 - pkt->num_len];
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
924 if (ngx_quic_tls_hp(pkt->log, ciphers.hp, secret, mask, sample)
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
925 != NGX_OK)
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
926 {
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
927 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
928 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
929
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
930 /* quic-tls: 5.4.1. Header Protection Application */
8643
5fdd0ef42232 QUIC: macros for manipulating header protection and reserved bits.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8642
diff changeset
931 ad.data[0] ^= mask[0] & ngx_quic_pkt_hp_mask(pkt->flags);
8315
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
932
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
933 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
934 pnp[i] ^= mask[i + 1];
fdda518d10ba Proper handling of packet number in header.
Vladimir Homutov <vl@nginx.com>
parents: 8313
diff changeset
935 }
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
936
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
937 res->len = ad.len + out.len;
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 return NGX_OK;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
940 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
941
8285
f85749b60e58 Removed memory allocations from encryption code.
Vladimir Homutov <vl@nginx.com>
parents: 8265
diff changeset
942
8383
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
943 static ngx_int_t
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
944 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
945 {
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
946 u_char *start;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
947 ngx_str_t ad, itag;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
948 ngx_quic_secret_t secret;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
949 ngx_quic_ciphers_t ciphers;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
950
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
951 /* 5.8. Retry Packet Integrity */
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
952 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
953 #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
954 "\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
955 #else
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8446
diff changeset
956 "\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
957 #endif
8383
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
958 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
959 #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
960 "\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
961 #else
011668fc9efd Update Initial salt and Retry secret from quic-tls-29.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8446
diff changeset
962 "\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
963 #endif
8383
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
964 static ngx_str_t in = ngx_string("");
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
965
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
966 ad.data = res->data;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
967 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
968
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
969 itag.data = ad.data + ad.len;
8394
df18ae7161b8 Assorted fixes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8386
diff changeset
970 itag.len = EVP_GCM_TLS_TAG_LEN;
8383
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
971
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
972 #ifdef NGX_QUIC_DEBUG_CRYPTO
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
973 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
974 #endif
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
975
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
976 if (ngx_quic_ciphers(0, &ciphers, pkt->level) == NGX_ERROR) {
8383
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
977 return NGX_ERROR;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
978 }
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
979
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
980 secret.key.len = sizeof(key);
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
981 secret.key.data = key;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
982 secret.iv.len = sizeof(nonce);
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
983
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
984 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
985 != NGX_OK)
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
986 {
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
987 return NGX_ERROR;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
988 }
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 res->len = itag.data + itag.len - start;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
991 res->data = start;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
992
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
993 return NGX_OK;
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
994 }
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
995
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
996
8562
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
997 ngx_int_t
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
998 ngx_quic_new_sr_token(ngx_connection_t *c, ngx_str_t *cid, ngx_str_t *secret,
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
999 u_char *token)
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1000 {
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1001 uint8_t *p;
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1002 size_t is_len, key_len, info_len;
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1003 ngx_str_t label;
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1004 const EVP_MD *digest;
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1005 uint8_t info[20];
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1006 uint8_t is[SHA256_DIGEST_LENGTH];
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1007 uint8_t key[SHA256_DIGEST_LENGTH];
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1008
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1009 /* 10.4.2. Calculating a Stateless Reset Token */
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1010
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1011 digest = EVP_sha256();
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1012 ngx_str_set(&label, "sr_token_key");
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1013
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1014 if (ngx_hkdf_extract(is, &is_len, digest, secret->data, secret->len,
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1015 cid->data, cid->len)
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1016 != NGX_OK)
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1017 {
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1018 ngx_ssl_error(NGX_LOG_INFO, c->log, 0,
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1019 "ngx_hkdf_extract(%V) failed", &label);
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1020 return NGX_ERROR;
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1021 }
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1022
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1023 key_len = SHA256_DIGEST_LENGTH;
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1024
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1025 info_len = 2 + 1 + label.len + 1;
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1026
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1027 info[0] = 0;
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1028 info[1] = key_len;
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1029 info[2] = label.len;
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1030
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1031 p = ngx_cpymem(&info[3], label.data, label.len);
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1032 *p = '\0';
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1033
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1034 if (ngx_hkdf_expand(key, key_len, digest, is, is_len, info, info_len)
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1035 != NGX_OK)
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1036 {
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1037 ngx_ssl_error(NGX_LOG_INFO, c->log, 0,
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1038 "ngx_hkdf_expand(%V) failed", &label);
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1039 return NGX_ERROR;
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1040 }
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1041
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1042 ngx_memcpy(token, key, NGX_QUIC_SR_TOKEN_LEN);
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1043
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1044 #if (NGX_DEBUG)
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1045 ngx_quic_hexdump(c->log, "quic stateless reset token", token,
8565
0e12c4aca3ab QUIC: fixed clang-ast asserts.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8562
diff changeset
1046 (size_t) NGX_QUIC_SR_TOKEN_LEN);
8562
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1047 #endif
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1048
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1049 return NGX_OK;
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1050 }
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1051
b31c02454539 QUIC: added stateless reset support.
Vladimir Homutov <vl@nginx.com>
parents: 8558
diff changeset
1052
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1053 static uint64_t
8339
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1054 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
1055 uint64_t *largest_pn)
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1056 {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1057 u_char *p;
8339
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1058 uint64_t truncated_pn, expected_pn, candidate_pn;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1059 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
1060
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1061 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
1062
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1063 p = *pos;
8339
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1064 truncated_pn = *p++ ^ *mask++;
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 while (--len) {
8339
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1067 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
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 *pos = p;
8339
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1071
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1072 expected_pn = *largest_pn + 1;
8394
df18ae7161b8 Assorted fixes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8386
diff changeset
1073 pn_win = 1ULL << pn_nbits;
8339
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1074 pn_hwin = pn_win / 2;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1075 pn_mask = pn_win - 1;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1076
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1077 candidate_pn = (expected_pn & ~pn_mask) | truncated_pn;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1078
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1079 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
1080 && candidate_pn < (1ULL << 62) - pn_win)
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1081 {
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1082 candidate_pn += pn_win;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1083
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1084 } else if (candidate_pn > expected_pn + pn_hwin
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1085 && candidate_pn >= pn_win)
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1086 {
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1087 candidate_pn -= pn_win;
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1088 }
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1089
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1090 *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
1091
aba84d9ab256 Parsing of truncated packet numbers.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8324
diff changeset
1092 return candidate_pn;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1093 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1094
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1095
8310
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8307
diff changeset
1096 static void
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8307
diff changeset
1097 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
1098 {
8313
c625bde6cb77 Fixed computing nonce again, by properly shifting packet number.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8310
diff changeset
1099 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
1100 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
1101 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
1102 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
1103 }
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8307
diff changeset
1104
7ac890c18f5e Fixed computing nonce by xoring all packet number bytes.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8307
diff changeset
1105
8376
2d0f4aa78ed6 Restored ngx_quic_encrypt return type.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8375
diff changeset
1106 ngx_int_t
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
1107 ngx_quic_encrypt(ngx_quic_header_t *pkt, ngx_str_t *res)
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1108 {
8370
262396242352 Reworked macros for parsing/assembling packet types.
Vladimir Homutov <vl@nginx.com>
parents: 8360
diff changeset
1109 if (ngx_quic_short_pkt(pkt->flags)) {
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
1110 return ngx_quic_create_short_packet(pkt, res);
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1111 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1112
8383
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
1113 if (ngx_quic_pkt_retry(pkt->flags)) {
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
1114 return ngx_quic_create_retry_packet(pkt, res);
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
1115 }
7ea34e13937f Address validation using Retry packets.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8376
diff changeset
1116
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
1117 return ngx_quic_create_long_packet(pkt, res);
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1118 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1119
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1120
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1121 ngx_int_t
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
1122 ngx_quic_decrypt(ngx_quic_header_t *pkt, uint64_t *largest_pn)
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 u_char clearflags, *p, *sample;
8558
0f37b4ef3cd9 QUIC: keep the entire packet size in pkt->len.
Roman Arutyunyan <arut@nginx.com>
parents: 8544
diff changeset
1125 size_t len;
8386
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1126 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
1127 uint64_t pn, lpn;
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1128 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
1129 ngx_str_t in, ad;
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1130 ngx_quic_secret_t *secret;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1131 ngx_quic_ciphers_t ciphers;
8288
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
1132 uint8_t mask[16], nonce[12];
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1133
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
1134 if (ngx_quic_ciphers(pkt->keys->cipher, &ciphers, pkt->level) == NGX_ERROR)
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
1135 {
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1136 return NGX_ERROR;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1137 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1138
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
1139 secret = &pkt->keys->secrets[pkt->level].client;
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1140
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1141 p = pkt->raw->pos;
8558
0f37b4ef3cd9 QUIC: keep the entire packet size in pkt->len.
Roman Arutyunyan <arut@nginx.com>
parents: 8544
diff changeset
1142 len = pkt->data + pkt->len - p;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1143
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1144 /* 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
1145 * 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
1146 * 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
1147 * 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
1148 */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1149
8558
0f37b4ef3cd9 QUIC: keep the entire packet size in pkt->len.
Roman Arutyunyan <arut@nginx.com>
parents: 8544
diff changeset
1150 if (len < EVP_GCM_TLS_TAG_LEN + 4) {
8543
9aedab0f0dff QUIC: check that the packet length is of at least sample size.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8542
diff changeset
1151 return NGX_DECLINED;
9aedab0f0dff QUIC: check that the packet length is of at least sample size.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8542
diff changeset
1152 }
9aedab0f0dff QUIC: check that the packet length is of at least sample size.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8542
diff changeset
1153
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1154 sample = p + 4;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1155
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1156 /* header protection */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1157
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1158 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
1159 != NGX_OK)
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8285
diff changeset
1160 {
8446
df29219988bc Discard short packets which could not be decrypted.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8445
diff changeset
1161 return NGX_DECLINED;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1162 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1163
8643
5fdd0ef42232 QUIC: macros for manipulating header protection and reserved bits.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8642
diff changeset
1164 clearflags = pkt->flags ^ (mask[0] & ngx_quic_pkt_hp_mask(pkt->flags));
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1165
8643
5fdd0ef42232 QUIC: macros for manipulating header protection and reserved bits.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8642
diff changeset
1166 if (ngx_quic_short_pkt(pkt->flags)) {
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1167 key_phase = (clearflags & NGX_QUIC_PKT_KPHASE) != 0;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1168
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1169 if (key_phase != pkt->key_phase) {
8621
9c3be23ddbe7 QUIC: refactored key handling.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8609
diff changeset
1170 secret = &pkt->keys->next_key.client;
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1171 pkt->key_update = 1;
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1172 }
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1173 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1174
8532
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8525
diff changeset
1175 lpn = *largest_pn;
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8525
diff changeset
1176
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1177 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
1178 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
1179
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1180 pkt->pn = pn;
8375
0aa6b02a1546 Store clearflags in pkt->flags after decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8370
diff changeset
1181 pkt->flags = clearflags;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1182
8287
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8285
diff changeset
1183 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
8609
f32740ddd484 QUIC: got rid of "pkt" abbreviation in logs.
Vladimir Homutov <vl@nginx.com>
parents: 8608
diff changeset
1184 "quic packet rx clearflags:%xd", clearflags);
8287
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8285
diff changeset
1185 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pkt->log, 0,
8609
f32740ddd484 QUIC: got rid of "pkt" abbreviation in logs.
Vladimir Homutov <vl@nginx.com>
parents: 8608
diff changeset
1186 "quic packet rx number:%uL len:%xi", pn, pnl);
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1187
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1188 /* packet protection */
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1189
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1190 in.data = p;
8558
0f37b4ef3cd9 QUIC: keep the entire packet size in pkt->len.
Roman Arutyunyan <arut@nginx.com>
parents: 8544
diff changeset
1191 in.len = len - pnl;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1192
8643
5fdd0ef42232 QUIC: macros for manipulating header protection and reserved bits.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8642
diff changeset
1193 badflags = clearflags & ngx_quic_pkt_rb_mask(pkt->flags);
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1194
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1195 ad.len = p - pkt->data;
8288
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
1196 ad.data = pkt->plaintext;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1197
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1198 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
1199 ad.data[0] = clearflags;
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1200
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1201 do {
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1202 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
1203 } while (--pnl);
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1204
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1205 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
1206 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
1207
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
1208 #ifdef NGX_QUIC_DEBUG_CRYPTO
8360
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
diff changeset
1209 ngx_quic_hexdump(pkt->log, "quic ad", ad.data, ad.len);
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
1210 #endif
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1211
8288
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
1212 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
1213 pkt->payload.data = pkt->plaintext + ad.len;
ebd5c71b9f02 Got rid of memory allocation in decryption.
Vladimir Homutov <vl@nginx.com>
parents: 8287
diff changeset
1214
8319
29354c6fc5f2 TLS Key Update in QUIC.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8318
diff changeset
1215 rc = ngx_quic_tls_open(ciphers.c, secret, &pkt->payload,
8287
ccb9cc95ad5e Logging cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8285
diff changeset
1216 nonce, &in, &ad, pkt->log);
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1217
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
1218 #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
1219 ngx_quic_hexdump(pkt->log, "quic packet payload",
f175006124d0 Cleaned up hexdumps in debug output.
Vladimir Homutov <vl@nginx.com>
parents: 8359
diff changeset
1220 pkt->payload.data, pkt->payload.len);
8359
2f900ae486bc Debug cleanup.
Vladimir Homutov <vl@nginx.com>
parents: 8339
diff changeset
1221 #endif
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1222
8386
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1223 if (rc != NGX_OK) {
8446
df29219988bc Discard short packets which could not be decrypted.
Sergey Kandaurov <pluknet@nginx.com>
parents: 8445
diff changeset
1224 return NGX_DECLINED;
8386
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1225 }
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1226
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1227 if (badflags) {
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1228 /*
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1229 * 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
1230 * 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
1231 * 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
1232 * of type PROTOCOL_VIOLATION.
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1233 */
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1234 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
1235 "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
1236 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
1237 return NGX_ERROR;
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1238 }
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1239
8532
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8525
diff changeset
1240 *largest_pn = lpn;
b13141d6d250 QUIC: do not update largest packet number from a bad packet.
Roman Arutyunyan <arut@nginx.com>
parents: 8525
diff changeset
1241
8386
81f85c479d7e Discard packets without fixed bit or reserved bits set.
Vladimir Homutov <vl@nginx.com>
parents: 8383
diff changeset
1242 return NGX_OK;
8221
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1243 }
69345a26ba69 Split transport and crypto parts into separate files.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1244