comparison src/event/quic/ngx_event_quic_protection.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 904a54092d5b
comparison
equal deleted inserted replaced
9171:f98636db77ef 9172:4ccb0d973206
24 const u_char *salt, size_t salt_len); 24 const u_char *salt, size_t salt_len);
25 25
26 static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask, 26 static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask,
27 uint64_t *largest_pn); 27 uint64_t *largest_pn);
28 28
29 static ngx_int_t ngx_quic_crypto_open(const ngx_quic_cipher_t *cipher, 29 static ngx_int_t ngx_quic_crypto_open(ngx_quic_secret_t *s, ngx_str_t *out,
30 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, 30 u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log);
31 ngx_str_t *ad, ngx_log_t *log);
32 static ngx_int_t ngx_quic_crypto_hp(ngx_log_t *log, const EVP_CIPHER *cipher, 31 static ngx_int_t ngx_quic_crypto_hp(ngx_log_t *log, const EVP_CIPHER *cipher,
33 ngx_quic_secret_t *s, u_char *out, u_char *in); 32 ngx_quic_secret_t *s, u_char *out, u_char *in);
34 33
35 static ngx_int_t ngx_quic_create_packet(ngx_quic_header_t *pkt, 34 static ngx_int_t ngx_quic_create_packet(ngx_quic_header_t *pkt,
36 ngx_str_t *res); 35 ngx_str_t *res);
106 105
107 ngx_int_t 106 ngx_int_t
108 ngx_quic_keys_set_initial_secret(ngx_quic_keys_t *keys, ngx_str_t *secret, 107 ngx_quic_keys_set_initial_secret(ngx_quic_keys_t *keys, ngx_str_t *secret,
109 ngx_log_t *log) 108 ngx_log_t *log)
110 { 109 {
111 size_t is_len; 110 size_t is_len;
112 uint8_t is[SHA256_DIGEST_LENGTH]; 111 uint8_t is[SHA256_DIGEST_LENGTH];
113 ngx_str_t iss; 112 ngx_str_t iss;
114 ngx_uint_t i; 113 ngx_uint_t i;
115 const EVP_MD *digest; 114 const EVP_MD *digest;
116 ngx_quic_hkdf_t seq[8]; 115 ngx_quic_hkdf_t seq[8];
117 ngx_quic_secret_t *client, *server; 116 ngx_quic_secret_t *client, *server;
117 ngx_quic_ciphers_t ciphers;
118 118
119 static const uint8_t salt[20] = 119 static const uint8_t salt[20] =
120 "\x38\x76\x2c\xf7\xf5\x59\x34\xb3\x4d\x17" 120 "\x38\x76\x2c\xf7\xf5\x59\x34\xb3\x4d\x17"
121 "\x9a\xe6\xa4\xc8\x0c\xad\xcc\xbb\x7f\x0a"; 121 "\x9a\xe6\xa4\xc8\x0c\xad\xcc\xbb\x7f\x0a";
122 122
178 if (ngx_quic_hkdf_expand(&seq[i], digest, log) != NGX_OK) { 178 if (ngx_quic_hkdf_expand(&seq[i], digest, log) != NGX_OK) {
179 return NGX_ERROR; 179 return NGX_ERROR;
180 } 180 }
181 } 181 }
182 182
183 return NGX_OK; 183 if (ngx_quic_ciphers(0, &ciphers, ssl_encryption_initial) == NGX_ERROR) {
184 return NGX_ERROR;
185 }
186
187 if (ngx_quic_crypto_init(ciphers.c, client, 0, log) == NGX_ERROR) {
188 return NGX_ERROR;
189 }
190
191 if (ngx_quic_crypto_init(ciphers.c, server, 1, log) == NGX_ERROR) {
192 goto failed;
193 }
194
195 return NGX_OK;
196
197 failed:
198
199 ngx_quic_keys_cleanup(keys);
200
201 return NGX_ERROR;
184 } 202 }
185 203
186 204
187 ngx_int_t 205 ngx_int_t
188 ngx_quic_hkdf_expand(ngx_quic_hkdf_t *h, const EVP_MD *digest, ngx_log_t *log) 206 ngx_quic_hkdf_expand(ngx_quic_hkdf_t *h, const EVP_MD *digest, ngx_log_t *log)
341 359
342 #endif 360 #endif
343 } 361 }
344 362
345 363
346 static ngx_int_t 364 ngx_int_t
347 ngx_quic_crypto_open(const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s, 365 ngx_quic_crypto_init(const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s,
348 ngx_str_t *out, u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log) 366 ngx_int_t enc, ngx_log_t *log)
349 { 367 {
350 368
351 #ifdef OPENSSL_IS_BORINGSSL 369 #ifdef OPENSSL_IS_BORINGSSL
352 EVP_AEAD_CTX *ctx; 370 EVP_AEAD_CTX *ctx;
353 371
355 EVP_AEAD_DEFAULT_TAG_LENGTH); 373 EVP_AEAD_DEFAULT_TAG_LENGTH);
356 if (ctx == NULL) { 374 if (ctx == NULL) {
357 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_new() failed"); 375 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_new() failed");
358 return NGX_ERROR; 376 return NGX_ERROR;
359 } 377 }
360
361 if (EVP_AEAD_CTX_open(ctx, out->data, &out->len, out->len, nonce, s->iv.len,
362 in->data, in->len, ad->data, ad->len)
363 != 1)
364 {
365 EVP_AEAD_CTX_free(ctx);
366 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_open() failed");
367 return NGX_ERROR;
368 }
369
370 EVP_AEAD_CTX_free(ctx);
371 #else 378 #else
372 int len;
373 EVP_CIPHER_CTX *ctx; 379 EVP_CIPHER_CTX *ctx;
374 380
375 ctx = EVP_CIPHER_CTX_new(); 381 ctx = EVP_CIPHER_CTX_new();
376 if (ctx == NULL) { 382 if (ctx == NULL) {
377 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_CIPHER_CTX_new() failed"); 383 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_CIPHER_CTX_new() failed");
378 return NGX_ERROR; 384 return NGX_ERROR;
379 } 385 }
380 386
381 if (EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) { 387 if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc) != 1) {
382 EVP_CIPHER_CTX_free(ctx); 388 EVP_CIPHER_CTX_free(ctx);
383 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptInit_ex() failed"); 389 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_CipherInit_ex() failed");
384 return NGX_ERROR;
385 }
386
387 in->len -= NGX_QUIC_TAG_LEN;
388
389 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, NGX_QUIC_TAG_LEN,
390 in->data + in->len)
391 == 0)
392 {
393 EVP_CIPHER_CTX_free(ctx);
394 ngx_ssl_error(NGX_LOG_INFO, log, 0,
395 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_AEAD_SET_TAG) failed");
396 return NGX_ERROR;
397 }
398
399 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, s->iv.len, NULL)
400 == 0)
401 {
402 EVP_CIPHER_CTX_free(ctx);
403 ngx_ssl_error(NGX_LOG_INFO, log, 0,
404 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_AEAD_SET_IVLEN) failed");
405 return NGX_ERROR;
406 }
407
408 if (EVP_DecryptInit_ex(ctx, NULL, NULL, s->key.data, nonce) != 1) {
409 EVP_CIPHER_CTX_free(ctx);
410 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptInit_ex() failed");
411 return NGX_ERROR;
412 }
413
414 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE
415 && EVP_DecryptUpdate(ctx, NULL, &len, NULL, in->len) != 1)
416 {
417 EVP_CIPHER_CTX_free(ctx);
418 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptUpdate() failed");
419 return NGX_ERROR;
420 }
421
422 if (EVP_DecryptUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) {
423 EVP_CIPHER_CTX_free(ctx);
424 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptUpdate() failed");
425 return NGX_ERROR;
426 }
427
428 if (EVP_DecryptUpdate(ctx, out->data, &len, in->data, in->len) != 1) {
429 EVP_CIPHER_CTX_free(ctx);
430 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptUpdate() failed");
431 return NGX_ERROR;
432 }
433
434 out->len = len;
435
436 if (EVP_DecryptFinal_ex(ctx, out->data + out->len, &len) <= 0) {
437 EVP_CIPHER_CTX_free(ctx);
438 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptFinal_ex failed");
439 return NGX_ERROR;
440 }
441
442 out->len += len;
443
444 EVP_CIPHER_CTX_free(ctx);
445 #endif
446
447 return NGX_OK;
448 }
449
450
451 ngx_int_t
452 ngx_quic_crypto_seal(const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s,
453 ngx_str_t *out, u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
454 {
455
456 #ifdef OPENSSL_IS_BORINGSSL
457 EVP_AEAD_CTX *ctx;
458
459 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len,
460 EVP_AEAD_DEFAULT_TAG_LENGTH);
461 if (ctx == NULL) {
462 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_new() failed");
463 return NGX_ERROR;
464 }
465
466 if (EVP_AEAD_CTX_seal(ctx, out->data, &out->len, out->len, nonce, s->iv.len,
467 in->data, in->len, ad->data, ad->len)
468 != 1)
469 {
470 EVP_AEAD_CTX_free(ctx);
471 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_seal() failed");
472 return NGX_ERROR;
473 }
474
475 EVP_AEAD_CTX_free(ctx);
476 #else
477 int len;
478 EVP_CIPHER_CTX *ctx;
479
480 ctx = EVP_CIPHER_CTX_new();
481 if (ctx == NULL) {
482 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_CIPHER_CTX_new() failed");
483 return NGX_ERROR;
484 }
485
486 if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) != 1) {
487 EVP_CIPHER_CTX_free(ctx);
488 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptInit_ex() failed");
489 return NGX_ERROR; 390 return NGX_ERROR;
490 } 391 }
491 392
492 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE 393 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE
493 && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, NGX_QUIC_TAG_LEN, 394 && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, NGX_QUIC_TAG_LEN,
507 ngx_ssl_error(NGX_LOG_INFO, log, 0, 408 ngx_ssl_error(NGX_LOG_INFO, log, 0,
508 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_AEAD_SET_IVLEN) failed"); 409 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_AEAD_SET_IVLEN) failed");
509 return NGX_ERROR; 410 return NGX_ERROR;
510 } 411 }
511 412
512 if (EVP_EncryptInit_ex(ctx, NULL, NULL, s->key.data, nonce) != 1) { 413 if (EVP_CipherInit_ex(ctx, NULL, NULL, s->key.data, NULL, enc) != 1) {
513 EVP_CIPHER_CTX_free(ctx); 414 EVP_CIPHER_CTX_free(ctx);
415 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_CipherInit_ex() failed");
416 return NGX_ERROR;
417 }
418 #endif
419
420 s->ctx = ctx;
421 return NGX_OK;
422 }
423
424
425 static ngx_int_t
426 ngx_quic_crypto_open(ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce,
427 ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
428 {
429 ngx_quic_crypto_ctx_t *ctx;
430
431 ctx = s->ctx;
432
433 #ifdef OPENSSL_IS_BORINGSSL
434 if (EVP_AEAD_CTX_open(ctx, out->data, &out->len, out->len, nonce, s->iv.len,
435 in->data, in->len, ad->data, ad->len)
436 != 1)
437 {
438 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_open() failed");
439 return NGX_ERROR;
440 }
441 #else
442 int len;
443
444 if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, nonce) != 1) {
445 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptInit_ex() failed");
446 return NGX_ERROR;
447 }
448
449 in->len -= NGX_QUIC_TAG_LEN;
450
451 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, NGX_QUIC_TAG_LEN,
452 in->data + in->len)
453 == 0)
454 {
455 ngx_ssl_error(NGX_LOG_INFO, log, 0,
456 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_AEAD_SET_TAG) failed");
457 return NGX_ERROR;
458 }
459
460 if (EVP_CIPHER_mode(EVP_CIPHER_CTX_cipher(ctx)) == EVP_CIPH_CCM_MODE
461 && EVP_DecryptUpdate(ctx, NULL, &len, NULL, in->len) != 1)
462 {
463 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptUpdate() failed");
464 return NGX_ERROR;
465 }
466
467 if (EVP_DecryptUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) {
468 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptUpdate() failed");
469 return NGX_ERROR;
470 }
471
472 if (EVP_DecryptUpdate(ctx, out->data, &len, in->data, in->len) != 1) {
473 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptUpdate() failed");
474 return NGX_ERROR;
475 }
476
477 out->len = len;
478
479 if (EVP_DecryptFinal_ex(ctx, out->data + out->len, &len) <= 0) {
480 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_DecryptFinal_ex failed");
481 return NGX_ERROR;
482 }
483
484 out->len += len;
485 #endif
486
487 return NGX_OK;
488 }
489
490
491 ngx_int_t
492 ngx_quic_crypto_seal(ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce,
493 ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log)
494 {
495 ngx_quic_crypto_ctx_t *ctx;
496
497 ctx = s->ctx;
498
499 #ifdef OPENSSL_IS_BORINGSSL
500 if (EVP_AEAD_CTX_seal(ctx, out->data, &out->len, out->len, nonce, s->iv.len,
501 in->data, in->len, ad->data, ad->len)
502 != 1)
503 {
504 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_AEAD_CTX_seal() failed");
505 return NGX_ERROR;
506 }
507 #else
508 int len;
509
510 if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, nonce) != 1) {
514 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptInit_ex() failed"); 511 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptInit_ex() failed");
515 return NGX_ERROR; 512 return NGX_ERROR;
516 } 513 }
517 514
518 if (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE 515 if (EVP_CIPHER_mode(EVP_CIPHER_CTX_cipher(ctx)) == EVP_CIPH_CCM_MODE
519 && EVP_EncryptUpdate(ctx, NULL, &len, NULL, in->len) != 1) 516 && EVP_EncryptUpdate(ctx, NULL, &len, NULL, in->len) != 1)
520 { 517 {
521 EVP_CIPHER_CTX_free(ctx);
522 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed"); 518 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed");
523 return NGX_ERROR; 519 return NGX_ERROR;
524 } 520 }
525 521
526 if (EVP_EncryptUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) { 522 if (EVP_EncryptUpdate(ctx, NULL, &len, ad->data, ad->len) != 1) {
527 EVP_CIPHER_CTX_free(ctx);
528 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed"); 523 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed");
529 return NGX_ERROR; 524 return NGX_ERROR;
530 } 525 }
531 526
532 if (EVP_EncryptUpdate(ctx, out->data, &len, in->data, in->len) != 1) { 527 if (EVP_EncryptUpdate(ctx, out->data, &len, in->data, in->len) != 1) {
533 EVP_CIPHER_CTX_free(ctx);
534 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed"); 528 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed");
535 return NGX_ERROR; 529 return NGX_ERROR;
536 } 530 }
537 531
538 out->len = len; 532 out->len = len;
539 533
540 if (EVP_EncryptFinal_ex(ctx, out->data + out->len, &len) <= 0) { 534 if (EVP_EncryptFinal_ex(ctx, out->data + out->len, &len) <= 0) {
541 EVP_CIPHER_CTX_free(ctx);
542 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptFinal_ex failed"); 535 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptFinal_ex failed");
543 return NGX_ERROR; 536 return NGX_ERROR;
544 } 537 }
545 538
546 out->len += len; 539 out->len += len;
547 540
548 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, NGX_QUIC_TAG_LEN, 541 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, NGX_QUIC_TAG_LEN,
549 out->data + out->len) 542 out->data + out->len)
550 == 0) 543 == 0)
551 { 544 {
552 EVP_CIPHER_CTX_free(ctx);
553 ngx_ssl_error(NGX_LOG_INFO, log, 0, 545 ngx_ssl_error(NGX_LOG_INFO, log, 0,
554 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_AEAD_GET_TAG) failed"); 546 "EVP_CIPHER_CTX_ctrl(EVP_CTRL_AEAD_GET_TAG) failed");
555 return NGX_ERROR; 547 return NGX_ERROR;
556 } 548 }
557 549
558 out->len += NGX_QUIC_TAG_LEN; 550 out->len += NGX_QUIC_TAG_LEN;
559 551 #endif
560 EVP_CIPHER_CTX_free(ctx); 552
561 #endif 553 return NGX_OK;
562 554 }
563 return NGX_OK; 555
556
557 void
558 ngx_quic_crypto_cleanup(ngx_quic_secret_t *s)
559 {
560 if (s->ctx) {
561 #ifdef OPENSSL_IS_BORINGSSL
562 EVP_AEAD_CTX_free(s->ctx);
563 #else
564 EVP_CIPHER_CTX_free(s->ctx);
565 #endif
566 s->ctx = NULL;
567 }
564 } 568 }
565 569
566 570
567 static ngx_int_t 571 static ngx_int_t
568 ngx_quic_crypto_hp(ngx_log_t *log, const EVP_CIPHER *cipher, 572 ngx_quic_crypto_hp(ngx_log_t *log, const EVP_CIPHER *cipher,
664 if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, log) != NGX_OK) { 668 if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, log) != NGX_OK) {
665 return NGX_ERROR; 669 return NGX_ERROR;
666 } 670 }
667 } 671 }
668 672
673 if (ngx_quic_crypto_init(ciphers.c, peer_secret, is_write, log)
674 == NGX_ERROR)
675 {
676 return NGX_ERROR;
677 }
678
669 return NGX_OK; 679 return NGX_OK;
670 } 680 }
671 681
672 682
673 ngx_uint_t 683 ngx_uint_t
674 ngx_quic_keys_available(ngx_quic_keys_t *keys, 684 ngx_quic_keys_available(ngx_quic_keys_t *keys,
675 enum ssl_encryption_level_t level, ngx_uint_t is_write) 685 enum ssl_encryption_level_t level, ngx_uint_t is_write)
676 { 686 {
677 if (is_write == 0) { 687 if (is_write == 0) {
678 return keys->secrets[level].client.key.len != 0; 688 return keys->secrets[level].client.ctx != NULL;
679 } 689 }
680 690
681 return keys->secrets[level].server.key.len != 0; 691 return keys->secrets[level].server.ctx != NULL;
682 } 692 }
683 693
684 694
685 void 695 void
686 ngx_quic_keys_discard(ngx_quic_keys_t *keys, 696 ngx_quic_keys_discard(ngx_quic_keys_t *keys,
687 enum ssl_encryption_level_t level) 697 enum ssl_encryption_level_t level)
688 { 698 {
689 keys->secrets[level].client.key.len = 0; 699 ngx_quic_secret_t *client, *server;
690 keys->secrets[level].server.key.len = 0; 700
701 client = &keys->secrets[level].client;
702 server = &keys->secrets[level].server;
703
704 ngx_quic_crypto_cleanup(client);
705 ngx_quic_crypto_cleanup(server);
691 } 706 }
692 707
693 708
694 void 709 void
695 ngx_quic_keys_switch(ngx_connection_t *c, ngx_quic_keys_t *keys) 710 ngx_quic_keys_switch(ngx_connection_t *c, ngx_quic_keys_t *keys)
696 { 711 {
697 ngx_quic_secrets_t *current, *next, tmp; 712 ngx_quic_secrets_t *current, *next, tmp;
698 713
699 current = &keys->secrets[ssl_encryption_application]; 714 current = &keys->secrets[ssl_encryption_application];
700 next = &keys->next_key; 715 next = &keys->next_key;
716
717 ngx_quic_crypto_cleanup(&current->client);
718 ngx_quic_crypto_cleanup(&current->server);
701 719
702 tmp = *current; 720 tmp = *current;
703 *current = *next; 721 *current = *next;
704 *next = tmp; 722 *next = tmp;
705 } 723 }
760 if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, c->log) != NGX_OK) { 778 if (ngx_quic_hkdf_expand(&seq[i], ciphers.d, c->log) != NGX_OK) {
761 goto failed; 779 goto failed;
762 } 780 }
763 } 781 }
764 782
783 if (ngx_quic_crypto_init(ciphers.c, &next->client, 0, c->log) == NGX_ERROR)
784 {
785 goto failed;
786 }
787
788 if (ngx_quic_crypto_init(ciphers.c, &next->server, 1, c->log) == NGX_ERROR)
789 {
790 goto failed;
791 }
792
765 return; 793 return;
766 794
767 failed: 795 failed:
768 796
769 ngx_quic_close_connection(c, NGX_ERROR); 797 ngx_quic_close_connection(c, NGX_ERROR);
798 }
799
800
801 void
802 ngx_quic_keys_cleanup(ngx_quic_keys_t *keys)
803 {
804 ngx_uint_t i;
805 ngx_quic_secrets_t *next;
806
807 for (i = 0; i < NGX_QUIC_ENCRYPTION_LAST; i++) {
808 ngx_quic_keys_discard(keys, i);
809 }
810
811 next = &keys->next_key;
812
813 ngx_quic_crypto_cleanup(&next->client);
814 ngx_quic_crypto_cleanup(&next->server);
770 } 815 }
771 816
772 817
773 static ngx_int_t 818 static ngx_int_t
774 ngx_quic_create_packet(ngx_quic_header_t *pkt, ngx_str_t *res) 819 ngx_quic_create_packet(ngx_quic_header_t *pkt, ngx_str_t *res)
799 secret = &pkt->keys->secrets[pkt->level].server; 844 secret = &pkt->keys->secrets[pkt->level].server;
800 845
801 ngx_memcpy(nonce, secret->iv.data, secret->iv.len); 846 ngx_memcpy(nonce, secret->iv.data, secret->iv.len);
802 ngx_quic_compute_nonce(nonce, sizeof(nonce), pkt->number); 847 ngx_quic_compute_nonce(nonce, sizeof(nonce), pkt->number);
803 848
804 if (ngx_quic_crypto_seal(ciphers.c, secret, &out, 849 if (ngx_quic_crypto_seal(secret, &out, nonce, &pkt->payload, &ad, pkt->log)
805 nonce, &pkt->payload, &ad, pkt->log)
806 != NGX_OK) 850 != NGX_OK)
807 { 851 {
808 return NGX_ERROR; 852 return NGX_ERROR;
809 } 853 }
810 854
860 904
861 secret.key.len = sizeof(key); 905 secret.key.len = sizeof(key);
862 ngx_memcpy(secret.key.data, key, sizeof(key)); 906 ngx_memcpy(secret.key.data, key, sizeof(key));
863 secret.iv.len = NGX_QUIC_IV_LEN; 907 secret.iv.len = NGX_QUIC_IV_LEN;
864 908
865 if (ngx_quic_crypto_seal(ciphers.c, &secret, &itag, nonce, &in, &ad, 909 if (ngx_quic_crypto_init(ciphers.c, &secret, 1, pkt->log) == NGX_ERROR) {
866 pkt->log) 910 return NGX_ERROR;
911 }
912
913 if (ngx_quic_crypto_seal(&secret, &itag, nonce, &in, &ad, pkt->log)
867 != NGX_OK) 914 != NGX_OK)
868 { 915 {
869 return NGX_ERROR; 916 ngx_quic_crypto_cleanup(&secret);
870 } 917 return NGX_ERROR;
918 }
919
920 ngx_quic_crypto_cleanup(&secret);
871 921
872 res->len = itag.data + itag.len - start; 922 res->len = itag.data + itag.len - start;
873 res->data = start; 923 res->data = start;
874 924
875 return NGX_OK; 925 return NGX_OK;
997 ngx_quic_decrypt(ngx_quic_header_t *pkt, uint64_t *largest_pn) 1047 ngx_quic_decrypt(ngx_quic_header_t *pkt, uint64_t *largest_pn)
998 { 1048 {
999 u_char *p, *sample; 1049 u_char *p, *sample;
1000 size_t len; 1050 size_t len;
1001 uint64_t pn, lpn; 1051 uint64_t pn, lpn;
1002 ngx_int_t pnl, rc; 1052 ngx_int_t pnl;
1003 ngx_str_t in, ad; 1053 ngx_str_t in, ad;
1004 ngx_uint_t key_phase; 1054 ngx_uint_t key_phase;
1005 ngx_quic_secret_t *secret; 1055 ngx_quic_secret_t *secret;
1006 ngx_quic_ciphers_t ciphers; 1056 ngx_quic_ciphers_t ciphers;
1007 uint8_t nonce[NGX_QUIC_IV_LEN], mask[NGX_QUIC_HP_LEN]; 1057 uint8_t nonce[NGX_QUIC_IV_LEN], mask[NGX_QUIC_HP_LEN];
1086 #endif 1136 #endif
1087 1137
1088 pkt->payload.len = in.len - NGX_QUIC_TAG_LEN; 1138 pkt->payload.len = in.len - NGX_QUIC_TAG_LEN;
1089 pkt->payload.data = pkt->plaintext + ad.len; 1139 pkt->payload.data = pkt->plaintext + ad.len;
1090 1140
1091 rc = ngx_quic_crypto_open(ciphers.c, secret, &pkt->payload, 1141 if (ngx_quic_crypto_open(secret, &pkt->payload, nonce, &in, &ad, pkt->log)
1092 nonce, &in, &ad, pkt->log); 1142 != NGX_OK)
1093 if (rc != NGX_OK) { 1143 {
1094 return NGX_DECLINED; 1144 return NGX_DECLINED;
1095 } 1145 }
1096 1146
1097 if (pkt->payload.len == 0) { 1147 if (pkt->payload.len == 0) {
1098 /* 1148 /*