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