comparison src/event/quic/ngx_event_quic_openssl_compat.c @ 9172:4ccb0d973206

QUIC: reusing crypto contexts for packet protection.
author Sergey Kandaurov <pluknet@nginx.com>
date Fri, 20 Oct 2023 18:05:07 +0400
parents f98636db77ef
children f7c9cd726298
comparison
equal deleted inserted replaced
9171:f98636db77ef 9172:4ccb0d973206
52 ngx_str_t ctp; 52 ngx_str_t ctp;
53 }; 53 };
54 54
55 55
56 static void ngx_quic_compat_keylog_callback(const SSL *ssl, const char *line); 56 static void ngx_quic_compat_keylog_callback(const SSL *ssl, const char *line);
57 static ngx_int_t ngx_quic_compat_set_encryption_secret(ngx_log_t *log, 57 static ngx_int_t ngx_quic_compat_set_encryption_secret(ngx_connection_t *c,
58 ngx_quic_compat_keys_t *keys, enum ssl_encryption_level_t level, 58 ngx_quic_compat_keys_t *keys, enum ssl_encryption_level_t level,
59 const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len); 59 const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len);
60 static void ngx_quic_compat_cleanup_encryption_secret(void *data);
60 static int ngx_quic_compat_add_transport_params_callback(SSL *ssl, 61 static int ngx_quic_compat_add_transport_params_callback(SSL *ssl,
61 unsigned int ext_type, unsigned int context, const unsigned char **out, 62 unsigned int ext_type, unsigned int context, const unsigned char **out,
62 size_t *outlen, X509 *x, size_t chainidx, int *al, void *add_arg); 63 size_t *outlen, X509 *x, size_t chainidx, int *al, void *add_arg);
63 static int ngx_quic_compat_parse_transport_params_callback(SSL *ssl, 64 static int ngx_quic_compat_parse_transport_params_callback(SSL *ssl,
64 unsigned int ext_type, unsigned int context, const unsigned char *in, 65 unsigned int ext_type, unsigned int context, const unsigned char *in,
212 213
213 } else { 214 } else {
214 com->method->set_read_secret((SSL *) ssl, level, cipher, secret, n); 215 com->method->set_read_secret((SSL *) ssl, level, cipher, secret, n);
215 com->read_record = 0; 216 com->read_record = 0;
216 217
217 (void) ngx_quic_compat_set_encryption_secret(c->log, &com->keys, level, 218 (void) ngx_quic_compat_set_encryption_secret(c, &com->keys, level,
218 cipher, secret, n); 219 cipher, secret, n);
219 } 220 }
220 } 221 }
221 222
222 223
223 static ngx_int_t 224 static ngx_int_t
224 ngx_quic_compat_set_encryption_secret(ngx_log_t *log, 225 ngx_quic_compat_set_encryption_secret(ngx_connection_t *c,
225 ngx_quic_compat_keys_t *keys, enum ssl_encryption_level_t level, 226 ngx_quic_compat_keys_t *keys, enum ssl_encryption_level_t level,
226 const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len) 227 const SSL_CIPHER *cipher, const uint8_t *secret, size_t secret_len)
227 { 228 {
228 ngx_int_t key_len; 229 ngx_int_t key_len;
229 ngx_str_t secret_str; 230 ngx_str_t secret_str;
230 ngx_uint_t i; 231 ngx_uint_t i;
231 ngx_quic_hkdf_t seq[2]; 232 ngx_quic_hkdf_t seq[2];
232 ngx_quic_secret_t *peer_secret; 233 ngx_quic_secret_t *peer_secret;
233 ngx_quic_ciphers_t ciphers; 234 ngx_quic_ciphers_t ciphers;
235 ngx_pool_cleanup_t *cln;
234 236
235 peer_secret = &keys->secret; 237 peer_secret = &keys->secret;
236 238
237 keys->cipher = SSL_CIPHER_get_id(cipher); 239 keys->cipher = SSL_CIPHER_get_id(cipher);
238 240
239 key_len = ngx_quic_ciphers(keys->cipher, &ciphers, level); 241 key_len = ngx_quic_ciphers(keys->cipher, &ciphers, level);
240 242
241 if (key_len == NGX_ERROR) { 243 if (key_len == NGX_ERROR) {
242 ngx_ssl_error(NGX_LOG_INFO, log, 0, "unexpected cipher"); 244 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher");
243 return NGX_ERROR; 245 return NGX_ERROR;
244 } 246 }
245 247
246 if (sizeof(peer_secret->secret.data) < secret_len) { 248 if (sizeof(peer_secret->secret.data) < secret_len) {
247 ngx_log_error(NGX_LOG_ALERT, log, 0, 249 ngx_log_error(NGX_LOG_ALERT, c->log, 0,
248 "unexpected secret len: %uz", secret_len); 250 "unexpected secret len: %uz", secret_len);
249 return NGX_ERROR; 251 return NGX_ERROR;
250 } 252 }
251 253
252 peer_secret->secret.len = secret_len; 254 peer_secret->secret.len = secret_len;
260 262
261 ngx_quic_hkdf_set(&seq[0], "tls13 key", &peer_secret->key, &secret_str); 263 ngx_quic_hkdf_set(&seq[0], "tls13 key", &peer_secret->key, &secret_str);
262 ngx_quic_hkdf_set(&seq[1], "tls13 iv", &peer_secret->iv, &secret_str); 264 ngx_quic_hkdf_set(&seq[1], "tls13 iv", &peer_secret->iv, &secret_str);
263 265
264 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) { 266 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
265 if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, log) != NGX_OK) { 267 if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, c->log) != NGX_OK) {
266 return NGX_ERROR; 268 return NGX_ERROR;
267 } 269 }
268 } 270 }
269 271
272 /* register cleanup handler once */
273
274 if (peer_secret->ctx) {
275 ngx_quic_crypto_cleanup(peer_secret);
276
277 } else {
278 cln = ngx_pool_cleanup_add(c->pool, 0);
279 if (cln == NULL) {
280 return NGX_ERROR;
281 }
282
283 cln->handler = ngx_quic_compat_cleanup_encryption_secret;
284 cln->data = peer_secret;
285 }
286
287 if (ngx_quic_crypto_init(ciphers.c, peer_secret, 1, c->log) == NGX_ERROR) {
288 return NGX_ERROR;
289 }
290
270 return NGX_OK; 291 return NGX_OK;
292 }
293
294
295 static void
296 ngx_quic_compat_cleanup_encryption_secret(void *data)
297 {
298 ngx_quic_secret_t *secret = data;
299
300 ngx_quic_crypto_cleanup(secret);
271 } 301 }
272 302
273 303
274 static int 304 static int
275 ngx_quic_compat_add_transport_params_callback(SSL *ssl, unsigned int ext_type, 305 ngx_quic_compat_add_transport_params_callback(SSL *ssl, unsigned int ext_type,
576 secret = &rec->keys->secret; 606 secret = &rec->keys->secret;
577 607
578 ngx_memcpy(nonce, secret->iv.data, secret->iv.len); 608 ngx_memcpy(nonce, secret->iv.data, secret->iv.len);
579 ngx_quic_compute_nonce(nonce, sizeof(nonce), rec->number); 609 ngx_quic_compute_nonce(nonce, sizeof(nonce), rec->number);
580 610
581 if (ngx_quic_crypto_seal(ciphers.c, secret, &out, 611 if (ngx_quic_crypto_seal(secret, &out, nonce, &rec->payload, &ad, rec->log)
582 nonce, &rec->payload, &ad, rec->log)
583 != NGX_OK) 612 != NGX_OK)
584 { 613 {
585 return NGX_ERROR; 614 return NGX_ERROR;
586 } 615 }
587 616