Mercurial > hg > nginx
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 } |