comparison src/event/quic/ngx_event_quic_protection.c @ 8798:fc5719637aff quic

QUIC: consistent use of 5-byte buffers for header protection. The output buffer is now also of 5 bytes. Header protection uses stream ciphers, which don't produce extra output nor PKCS padding.
author Sergey Kandaurov <pluknet@nginx.com>
date Wed, 16 Jun 2021 17:53:18 +0300
parents 4715f3e669f1
children ef8276c8ccff
comparison
equal deleted inserted replaced
8797:4715f3e669f1 8798:fc5719637aff
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_event.h> 9 #include <ngx_event.h>
10 #include <ngx_event_quic_connection.h> 10 #include <ngx_event_quic_connection.h>
11 11
12 12
13 /* RFC 5116, 5.1 and RFC 8439, 2.3 for all supported ciphers */
13 #define NGX_QUIC_IV_LEN 12 14 #define NGX_QUIC_IV_LEN 12
15 /* RFC 9001, 5.4.1. Header Protection Application: 5-byte mask */
16 #define NGX_QUIC_HP_LEN 5
14 17
15 #define NGX_AES_128_GCM_SHA256 0x1301 18 #define NGX_AES_128_GCM_SHA256 0x1301
16 #define NGX_AES_256_GCM_SHA384 0x1302 19 #define NGX_AES_256_GCM_SHA384 0x1302
17 #define NGX_CHACHA20_POLY1305_SHA256 0x1303 20 #define NGX_CHACHA20_POLY1305_SHA256 0x1303
18 21
625 ngx_quic_tls_hp(ngx_log_t *log, const EVP_CIPHER *cipher, 628 ngx_quic_tls_hp(ngx_log_t *log, const EVP_CIPHER *cipher,
626 ngx_quic_secret_t *s, u_char *out, u_char *in) 629 ngx_quic_secret_t *s, u_char *out, u_char *in)
627 { 630 {
628 int outlen; 631 int outlen;
629 EVP_CIPHER_CTX *ctx; 632 EVP_CIPHER_CTX *ctx;
630 u_char zero[5] = {0}; 633 u_char zero[NGX_QUIC_HP_LEN] = {0};
631 634
632 #ifdef OPENSSL_IS_BORINGSSL 635 #ifdef OPENSSL_IS_BORINGSSL
633 uint32_t counter; 636 uint32_t cnt;
634 637
635 ngx_memcpy(&counter, in, sizeof(uint32_t)); 638 ngx_memcpy(&cnt, in, sizeof(uint32_t));
636 639
637 if (cipher == (const EVP_CIPHER *) EVP_aead_chacha20_poly1305()) { 640 if (cipher == (const EVP_CIPHER *) EVP_aead_chacha20_poly1305()) {
638 CRYPTO_chacha_20(out, zero, 5, s->hp.data, &in[4], counter); 641 CRYPTO_chacha_20(out, zero, NGX_QUIC_HP_LEN, s->hp.data, &in[4], cnt);
639 return NGX_OK; 642 return NGX_OK;
640 } 643 }
641 #endif 644 #endif
642 645
643 ctx = EVP_CIPHER_CTX_new(); 646 ctx = EVP_CIPHER_CTX_new();
648 if (EVP_EncryptInit_ex(ctx, cipher, NULL, s->hp.data, in) != 1) { 651 if (EVP_EncryptInit_ex(ctx, cipher, NULL, s->hp.data, in) != 1) {
649 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptInit_ex() failed"); 652 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptInit_ex() failed");
650 goto failed; 653 goto failed;
651 } 654 }
652 655
653 if (!EVP_EncryptUpdate(ctx, out, &outlen, zero, 5)) { 656 if (!EVP_EncryptUpdate(ctx, out, &outlen, zero, NGX_QUIC_HP_LEN)) {
654 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed"); 657 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptUpdate() failed");
655 goto failed; 658 goto failed;
656 } 659 }
657 660
658 if (!EVP_EncryptFinal_ex(ctx, out + 5, &outlen)) { 661 if (!EVP_EncryptFinal_ex(ctx, out + NGX_QUIC_HP_LEN, &outlen)) {
659 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptFinal_Ex() failed"); 662 ngx_ssl_error(NGX_LOG_INFO, log, 0, "EVP_EncryptFinal_Ex() failed");
660 goto failed; 663 goto failed;
661 } 664 }
662 665
663 EVP_CIPHER_CTX_free(ctx); 666 EVP_CIPHER_CTX_free(ctx);
855 u_char *pnp, *sample; 858 u_char *pnp, *sample;
856 ngx_str_t ad, out; 859 ngx_str_t ad, out;
857 ngx_uint_t i; 860 ngx_uint_t i;
858 ngx_quic_secret_t *secret; 861 ngx_quic_secret_t *secret;
859 ngx_quic_ciphers_t ciphers; 862 ngx_quic_ciphers_t ciphers;
860 u_char nonce[12], mask[16]; 863 u_char nonce[12], mask[NGX_QUIC_HP_LEN];
861 864
862 out.len = pkt->payload.len + EVP_GCM_TLS_TAG_LEN; 865 out.len = pkt->payload.len + EVP_GCM_TLS_TAG_LEN;
863 866
864 ad.data = res->data; 867 ad.data = res->data;
865 ad.len = ngx_quic_create_header(pkt, ad.data, out.len, &pnp); 868 ad.len = ngx_quic_create_header(pkt, ad.data, out.len, &pnp);
1082 uint64_t pn, lpn; 1085 uint64_t pn, lpn;
1083 ngx_int_t pnl, rc, key_phase; 1086 ngx_int_t pnl, rc, key_phase;
1084 ngx_str_t in, ad; 1087 ngx_str_t in, ad;
1085 ngx_quic_secret_t *secret; 1088 ngx_quic_secret_t *secret;
1086 ngx_quic_ciphers_t ciphers; 1089 ngx_quic_ciphers_t ciphers;
1087 uint8_t mask[16], nonce[12]; 1090 uint8_t nonce[12], mask[NGX_QUIC_HP_LEN];
1088 1091
1089 if (ngx_quic_ciphers(pkt->keys->cipher, &ciphers, pkt->level) == NGX_ERROR) 1092 if (ngx_quic_ciphers(pkt->keys->cipher, &ciphers, pkt->level) == NGX_ERROR)
1090 { 1093 {
1091 return NGX_ERROR; 1094 return NGX_ERROR;
1092 } 1095 }