comparison src/event/ngx_event_quic_protection.c @ 8288:ebd5c71b9f02 quic

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.
author Vladimir Homutov <vl@nginx.com>
date Thu, 26 Mar 2020 16:54:46 +0300
parents ccb9cc95ad5e
children 4ad7d4272cd5
comparison
equal deleted inserted replaced
8287:ccb9cc95ad5e 8288:ebd5c71b9f02
38 38
39 static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask); 39 static uint64_t ngx_quic_parse_pn(u_char **pos, ngx_int_t len, u_char *mask);
40 static ngx_int_t ngx_quic_ciphers(ngx_ssl_conn_t *ssl_conn, 40 static ngx_int_t ngx_quic_ciphers(ngx_ssl_conn_t *ssl_conn,
41 ngx_quic_ciphers_t *ciphers, enum ssl_encryption_level_t level); 41 ngx_quic_ciphers_t *ciphers, enum ssl_encryption_level_t level);
42 42
43 static ngx_int_t ngx_quic_tls_open(ngx_pool_t *pool, const ngx_quic_cipher_t *cipher, 43 static ngx_int_t ngx_quic_tls_open(const ngx_quic_cipher_t *cipher,
44 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, 44 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in,
45 ngx_str_t *ad, ngx_log_t *log); 45 ngx_str_t *ad, ngx_log_t *log);
46 static ngx_int_t ngx_quic_tls_seal(const ngx_quic_cipher_t *cipher, 46 static ngx_int_t ngx_quic_tls_seal(const ngx_quic_cipher_t *cipher,
47 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, 47 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in,
48 ngx_str_t *ad, ngx_log_t *log); 48 ngx_str_t *ad, ngx_log_t *log);
354 return NGX_OK; 354 return NGX_OK;
355 } 355 }
356 356
357 357
358 static ngx_int_t 358 static ngx_int_t
359 ngx_quic_tls_open(ngx_pool_t *pool, const ngx_quic_cipher_t *cipher, 359 ngx_quic_tls_open(const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s,
360 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, 360 ngx_str_t *out, u_char *nonce, ngx_str_t *in, ngx_str_t *ad,
361 ngx_str_t *ad, ngx_log_t *log) 361 ngx_log_t *log)
362 { 362 {
363 out->len = in->len - EVP_GCM_TLS_TAG_LEN;
364 out->data = ngx_pnalloc(pool, out->len);
365 if (out->data == NULL) {
366 return NGX_ERROR;
367 }
368 363
369 #ifdef OPENSSL_IS_BORINGSSL 364 #ifdef OPENSSL_IS_BORINGSSL
370 EVP_AEAD_CTX *ctx; 365 EVP_AEAD_CTX *ctx;
371 366
372 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len, 367 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len,
817 return ngx_quic_create_long_packet(pkt, ssl_conn, res); 812 return ngx_quic_create_long_packet(pkt, ssl_conn, res);
818 } 813 }
819 814
820 815
821 ngx_int_t 816 ngx_int_t
822 ngx_quic_decrypt(ngx_pool_t *pool, ngx_ssl_conn_t *ssl_conn, 817 ngx_quic_decrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn)
823 ngx_quic_header_t *pkt)
824 { 818 {
825 u_char clearflags, *p, *sample; 819 u_char clearflags, *p, *sample;
826 uint8_t *nonce;
827 uint64_t pn; 820 uint64_t pn;
828 ngx_int_t pnl, rc; 821 ngx_int_t pnl, rc;
829 ngx_str_t in, ad; 822 ngx_str_t in, ad;
830 ngx_quic_ciphers_t ciphers; 823 ngx_quic_ciphers_t ciphers;
831 uint8_t mask[16]; 824 uint8_t mask[16], nonce[12];
832 825
833 if (ngx_quic_ciphers(ssl_conn, &ciphers, pkt->level) == NGX_ERROR) { 826 if (ngx_quic_ciphers(ssl_conn, &ciphers, pkt->level) == NGX_ERROR) {
834 return NGX_ERROR; 827 return NGX_ERROR;
835 } 828 }
836 829
882 } else { 875 } else {
883 in.len = pkt->data + pkt->len - p; 876 in.len = pkt->data + pkt->len - p;
884 } 877 }
885 878
886 ad.len = p - pkt->data; 879 ad.len = p - pkt->data;
887 ad.data = ngx_pnalloc(pool, ad.len); 880 ad.data = pkt->plaintext;
888 if (ad.data == NULL) {
889 return NGX_ERROR;
890 }
891 881
892 ngx_memcpy(ad.data, pkt->data, ad.len); 882 ngx_memcpy(ad.data, pkt->data, ad.len);
893 ad.data[0] = clearflags; 883 ad.data[0] = clearflags;
894 884
895 do { 885 do {
896 ad.data[ad.len - pnl] = pn >> (8 * (pnl - 1)) % 256; 886 ad.data[ad.len - pnl] = pn >> (8 * (pnl - 1)) % 256;
897 } while (--pnl); 887 } while (--pnl);
898 888
899 nonce = ngx_pstrdup(pool, &pkt->secret->iv); 889 ngx_memcpy(nonce, pkt->secret->iv.data, pkt->secret->iv.len);
900 nonce[11] ^= pn; 890 nonce[11] ^= pn;
901 891
902 ngx_quic_hexdump0(pkt->log, "nonce", nonce, 12); 892 ngx_quic_hexdump0(pkt->log, "nonce", nonce, 12);
903 ngx_quic_hexdump0(pkt->log, "ad", ad.data, ad.len); 893 ngx_quic_hexdump0(pkt->log, "ad", ad.data, ad.len);
904 894
905 rc = ngx_quic_tls_open(pool, ciphers.c, pkt->secret, &pkt->payload, 895 pkt->payload.len = in.len - EVP_GCM_TLS_TAG_LEN;
896
897 if (NGX_QUIC_DEFAULT_MAX_PACKET_SIZE - ad.len < pkt->payload.len) {
898 return NGX_ERROR;
899 }
900
901 pkt->payload.data = pkt->plaintext + ad.len;
902
903 rc = ngx_quic_tls_open(ciphers.c, pkt->secret, &pkt->payload,
906 nonce, &in, &ad, pkt->log); 904 nonce, &in, &ad, pkt->log);
907 905
908 ngx_quic_hexdump0(pkt->log, "packet payload", 906 ngx_quic_hexdump0(pkt->log, "packet payload",
909 pkt->payload.data, pkt->payload.len); 907 pkt->payload.data, pkt->payload.len);
910 908