# HG changeset patch # User Vladimir Homutov # Date 1585230886 -10800 # Node ID ebd5c71b9f026159fd95475d8d2b23dcb7e3c73d # Parent ccb9cc95ad5e00219e04ed0ede77bc7e4c6a4611 Got rid of memory allocation in decryption. Static buffers are used instead in functions where decryption takes place. The pkt->plaintext points to the beginning of a static buffer. The pkt->payload.data points to decrypted data actual start. diff --git a/src/event/ngx_event_quic.c b/src/event/ngx_event_quic.c --- a/src/event/ngx_event_quic.c +++ b/src/event/ngx_event_quic.c @@ -377,6 +377,7 @@ ngx_quic_new_connection(ngx_connection_t { ngx_quic_tp_t *ctp; ngx_quic_connection_t *qc; + static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; if (ngx_buf_size(pkt->raw) < 1200) { ngx_log_error(NGX_LOG_INFO, c->log, 0, "too small UDP datagram"); @@ -448,8 +449,9 @@ ngx_quic_new_connection(ngx_connection_t pkt->secret = &qc->secrets.client.in; pkt->level = ssl_encryption_initial; + pkt->plaintext = buf; - if (ngx_quic_decrypt(c->pool, NULL, pkt) != NGX_OK) { + if (ngx_quic_decrypt(pkt, NULL) != NGX_OK) { return NGX_ERROR; } @@ -532,8 +534,7 @@ ngx_quic_input_handler(ngx_event_t *rev) ngx_buf_t b; ngx_connection_t *c; ngx_quic_connection_t *qc; - - static u_char buf[65535]; + static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; b.start = buf; b.end = buf + sizeof(buf); @@ -719,6 +720,7 @@ ngx_quic_initial_input(ngx_connection_t { ngx_ssl_conn_t *ssl_conn; ngx_quic_connection_t *qc; + static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; c->log->action = "processing initial quic packet"; @@ -735,8 +737,9 @@ ngx_quic_initial_input(ngx_connection_t pkt->secret = &qc->secrets.client.in; pkt->level = ssl_encryption_initial; + pkt->plaintext = buf; - if (ngx_quic_decrypt(c->pool, ssl_conn, pkt) != NGX_OK) { + if (ngx_quic_decrypt(pkt, ssl_conn) != NGX_OK) { return NGX_ERROR; } @@ -748,6 +751,7 @@ static ngx_int_t ngx_quic_handshake_input(ngx_connection_t *c, ngx_quic_header_t *pkt) { ngx_quic_connection_t *qc; + static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; c->log->action = "processing handshake quic packet"; @@ -790,8 +794,9 @@ ngx_quic_handshake_input(ngx_connection_ pkt->secret = &qc->secrets.client.hs; pkt->level = ssl_encryption_handshake; + pkt->plaintext = buf; - if (ngx_quic_decrypt(c->pool, c->ssl->connection, pkt) != NGX_OK) { + if (ngx_quic_decrypt(pkt, c->ssl->connection) != NGX_OK) { return NGX_ERROR; } @@ -803,6 +808,7 @@ static ngx_int_t ngx_quic_app_input(ngx_connection_t *c, ngx_quic_header_t *pkt) { ngx_quic_connection_t *qc; + static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; c->log->action = "processing application data quic packet"; @@ -820,8 +826,9 @@ ngx_quic_app_input(ngx_connection_t *c, pkt->secret = &qc->secrets.client.ad; pkt->level = ssl_encryption_application; + pkt->plaintext = buf; - if (ngx_quic_decrypt(c->pool, c->ssl->connection, pkt) != NGX_OK) { + if (ngx_quic_decrypt(pkt, c->ssl->connection) != NGX_OK) { return NGX_ERROR; } @@ -1374,7 +1381,7 @@ ngx_quic_send_packet(ngx_connection_t *c { ngx_str_t res; ngx_quic_header_t pkt; - static u_char buf[65535]; + static u_char buf[NGX_QUIC_DEFAULT_MAX_PACKET_SIZE]; static ngx_str_t initial_token = ngx_null_string; diff --git a/src/event/ngx_event_quic_protection.c b/src/event/ngx_event_quic_protection.c --- a/src/event/ngx_event_quic_protection.c +++ b/src/event/ngx_event_quic_protection.c @@ -40,7 +40,7 @@ static uint64_t ngx_quic_parse_pn(u_char static ngx_int_t ngx_quic_ciphers(ngx_ssl_conn_t *ssl_conn, ngx_quic_ciphers_t *ciphers, enum ssl_encryption_level_t level); -static ngx_int_t ngx_quic_tls_open(ngx_pool_t *pool, const ngx_quic_cipher_t *cipher, +static ngx_int_t ngx_quic_tls_open(const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, ngx_str_t *ad, ngx_log_t *log); static ngx_int_t ngx_quic_tls_seal(const ngx_quic_cipher_t *cipher, @@ -356,15 +356,10 @@ ngx_hkdf_extract(u_char *out_key, size_t static ngx_int_t -ngx_quic_tls_open(ngx_pool_t *pool, const ngx_quic_cipher_t *cipher, - ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, - ngx_str_t *ad, ngx_log_t *log) +ngx_quic_tls_open(const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s, + ngx_str_t *out, u_char *nonce, ngx_str_t *in, ngx_str_t *ad, + ngx_log_t *log) { - out->len = in->len - EVP_GCM_TLS_TAG_LEN; - out->data = ngx_pnalloc(pool, out->len); - if (out->data == NULL) { - return NGX_ERROR; - } #ifdef OPENSSL_IS_BORINGSSL EVP_AEAD_CTX *ctx; @@ -819,16 +814,14 @@ ngx_quic_encrypt(ngx_quic_header_t *pkt, ngx_int_t -ngx_quic_decrypt(ngx_pool_t *pool, ngx_ssl_conn_t *ssl_conn, - ngx_quic_header_t *pkt) +ngx_quic_decrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn) { u_char clearflags, *p, *sample; - uint8_t *nonce; uint64_t pn; ngx_int_t pnl, rc; ngx_str_t in, ad; ngx_quic_ciphers_t ciphers; - uint8_t mask[16]; + uint8_t mask[16], nonce[12]; if (ngx_quic_ciphers(ssl_conn, &ciphers, pkt->level) == NGX_ERROR) { return NGX_ERROR; @@ -884,10 +877,7 @@ ngx_quic_decrypt(ngx_pool_t *pool, ngx_s } ad.len = p - pkt->data; - ad.data = ngx_pnalloc(pool, ad.len); - if (ad.data == NULL) { - return NGX_ERROR; - } + ad.data = pkt->plaintext; ngx_memcpy(ad.data, pkt->data, ad.len); ad.data[0] = clearflags; @@ -896,13 +886,21 @@ ngx_quic_decrypt(ngx_pool_t *pool, ngx_s ad.data[ad.len - pnl] = pn >> (8 * (pnl - 1)) % 256; } while (--pnl); - nonce = ngx_pstrdup(pool, &pkt->secret->iv); + ngx_memcpy(nonce, pkt->secret->iv.data, pkt->secret->iv.len); nonce[11] ^= pn; ngx_quic_hexdump0(pkt->log, "nonce", nonce, 12); ngx_quic_hexdump0(pkt->log, "ad", ad.data, ad.len); - rc = ngx_quic_tls_open(pool, ciphers.c, pkt->secret, &pkt->payload, + pkt->payload.len = in.len - EVP_GCM_TLS_TAG_LEN; + + if (NGX_QUIC_DEFAULT_MAX_PACKET_SIZE - ad.len < pkt->payload.len) { + return NGX_ERROR; + } + + pkt->payload.data = pkt->plaintext + ad.len; + + rc = ngx_quic_tls_open(ciphers.c, pkt->secret, &pkt->payload, nonce, &in, &ad, pkt->log); ngx_quic_hexdump0(pkt->log, "packet payload", diff --git a/src/event/ngx_event_quic_protection.h b/src/event/ngx_event_quic_protection.h --- a/src/event/ngx_event_quic_protection.h +++ b/src/event/ngx_event_quic_protection.h @@ -39,8 +39,7 @@ int ngx_quic_set_encryption_secret(ngx_p ssize_t ngx_quic_encrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn, ngx_str_t *res); -ngx_int_t ngx_quic_decrypt(ngx_pool_t *pool, ngx_ssl_conn_t *ssl_conn, - ngx_quic_header_t *pkt); +ngx_int_t ngx_quic_decrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn); #endif /* _NGX_EVENT_QUIC_PROTECTION_H_INCLUDED_ */ diff --git a/src/event/ngx_event_quic_transport.h b/src/event/ngx_event_quic_transport.h --- a/src/event/ngx_event_quic_transport.h +++ b/src/event/ngx_event_quic_transport.h @@ -249,7 +249,8 @@ typedef struct { ngx_str_t dcid; ngx_str_t scid; uint64_t pn; - ngx_str_t payload; /* decrypted */ + u_char *plaintext; + ngx_str_t payload; /* decrypted data */ } ngx_quic_header_t;