comparison src/event/ngx_event_quic.c @ 8201:5c66dadb1e34 quic

Using SSL cipher suite id to obtain cipher/digest, part 2. Ciphers negotiation handling refactored into ngx_quic_ciphers().
author Sergey Kandaurov <pluknet@nginx.com>
date Tue, 10 Mar 2020 19:12:22 +0300
parents 9582adbc7d70
children a4ed2305ad2c
comparison
equal deleted inserted replaced
8200:9582adbc7d70 8201:5c66dadb1e34
6 6
7 #include <ngx_config.h> 7 #include <ngx_config.h>
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 9
10 10
11 #define quic_version 0xff000018 11 #define quic_version 0xff000018
12 12
13 #define NGX_AES_128_GCM_SHA256 0x1301 13 #define NGX_AES_128_GCM_SHA256 0x1301
14 #define NGX_AES_256_GCM_SHA384 0x1302 14 #define NGX_AES_256_GCM_SHA384 0x1302
15
16 #define NGX_QUIC_IV_LEN 12
17
18 #ifdef OPENSSL_IS_BORINGSSL
19 #define ngx_quic_cipher_t EVP_AEAD
20 #else
21 #define ngx_quic_cipher_t EVP_CIPHER
22 #endif
15 23
16 24
17 #if (NGX_HAVE_NONALIGNED) 25 #if (NGX_HAVE_NONALIGNED)
18 26
19 #define ngx_quic_parse_uint16(p) ntohs(*(uint16_t *) (p)) 27 #define ngx_quic_parse_uint16(p) ntohs(*(uint16_t *) (p))
126 ngx_str_t key; 134 ngx_str_t key;
127 ngx_str_t iv; 135 ngx_str_t iv;
128 ngx_str_t hp; 136 ngx_str_t hp;
129 } ngx_quic_secret_t; 137 } ngx_quic_secret_t;
130 138
139 typedef struct {
140 const ngx_quic_cipher_t *c;
141 const EVP_CIPHER *hp;
142 const EVP_MD *d;
143 } ngx_quic_ciphers_t;
131 144
132 typedef enum ssl_encryption_level_t ngx_quic_level_t; 145 typedef enum ssl_encryption_level_t ngx_quic_level_t;
133 146
134 typedef struct ngx_quic_frame_s ngx_quic_frame_t; 147 typedef struct ngx_quic_frame_s ngx_quic_frame_t;
135 148
259 272
260 static ngx_int_t ngx_quic_hkdf_expand(ngx_connection_t *c, const EVP_MD *digest, 273 static ngx_int_t ngx_quic_hkdf_expand(ngx_connection_t *c, const EVP_MD *digest,
261 ngx_str_t *out, ngx_str_t *label, const uint8_t *prk, size_t prk_len); 274 ngx_str_t *out, ngx_str_t *label, const uint8_t *prk, size_t prk_len);
262 275
263 static ngx_int_t ngx_quic_tls_open(ngx_connection_t *c, 276 static ngx_int_t ngx_quic_tls_open(ngx_connection_t *c,
264 const EVP_CIPHER *cipher, ngx_quic_secret_t *s, ngx_str_t *out, 277 const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s, ngx_str_t *out,
265 u_char *nonce, ngx_str_t *in, ngx_str_t *ad); 278 u_char *nonce, ngx_str_t *in, ngx_str_t *ad);
266 static ngx_int_t ngx_quic_tls_seal(ngx_connection_t *c, 279 static ngx_int_t ngx_quic_tls_seal(ngx_connection_t *c,
267 const EVP_CIPHER *cipher, ngx_quic_secret_t *s, ngx_str_t *out, 280 const ngx_quic_cipher_t *cipher, ngx_quic_secret_t *s, ngx_str_t *out,
268 u_char *nonce, ngx_str_t *in, ngx_str_t *ad); 281 u_char *nonce, ngx_str_t *in, ngx_str_t *ad);
269 282
270 static ngx_int_t ngx_quic_tls_hp(ngx_connection_t *c, const EVP_CIPHER *cipher, 283 static ngx_int_t ngx_quic_tls_hp(ngx_connection_t *c, const EVP_CIPHER *cipher,
271 ngx_quic_secret_t *s, u_char *out, u_char *in); 284 ngx_quic_secret_t *s, u_char *out, u_char *in);
272 285
286 static ngx_int_t ngx_quic_ciphers(ngx_connection_t *c,
287 ngx_quic_ciphers_t *ciphers, enum ssl_encryption_level_t level);
273 288
274 static SSL_QUIC_METHOD quic_method = { 289 static SSL_QUIC_METHOD quic_method = {
275 ngx_quic_set_encryption_secrets, 290 ngx_quic_set_encryption_secrets,
276 ngx_quic_add_handshake_data, 291 ngx_quic_add_handshake_data,
277 ngx_quic_flush_flight, 292 ngx_quic_flush_flight,
516 static int 531 static int
517 ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn, 532 ngx_quic_set_encryption_secrets(ngx_ssl_conn_t *ssl_conn,
518 enum ssl_encryption_level_t level, const uint8_t *read_secret, 533 enum ssl_encryption_level_t level, const uint8_t *read_secret,
519 const uint8_t *write_secret, size_t secret_len) 534 const uint8_t *write_secret, size_t secret_len)
520 { 535 {
521 ngx_uint_t i; 536 ngx_int_t key_len;
522 const EVP_MD *digest; 537 ngx_uint_t i;
523 const EVP_CIPHER *cipher; 538 ngx_connection_t *c;
524 ngx_connection_t *c; 539 ngx_quic_secret_t *client, *server;
525 ngx_quic_secret_t *client, *server; 540 ngx_quic_ciphers_t ciphers;
526 541
527 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn); 542 c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
528 543
529 ngx_quic_hexdump(c->log, "level:%d read", read_secret, secret_len, level); 544 ngx_quic_hexdump(c->log, "level:%d read", read_secret, secret_len, level);
530 ngx_quic_hexdump(c->log, "level:%d write", write_secret, secret_len, level); 545 ngx_quic_hexdump(c->log, "level:%d write", write_secret, secret_len, level);
531 546
532 switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl_conn)) & 0xffff) { 547 key_len = ngx_quic_ciphers(c, &ciphers, level);
533 548
534 case NGX_AES_128_GCM_SHA256: 549 if (key_len == NGX_ERROR) {
535 cipher = EVP_aes_128_gcm();
536 digest = EVP_sha256();
537 break;
538
539 case NGX_AES_256_GCM_SHA384:
540 cipher = EVP_aes_256_gcm();
541 digest = EVP_sha384();
542 break;
543
544 default:
545 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher"); 550 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher");
546 return 0; 551 return 0;
547 } 552 }
548 553
549 switch (level) { 554 switch (level) {
562 567
563 default: 568 default:
564 return 0; 569 return 0;
565 } 570 }
566 571
567 client->key.len = EVP_CIPHER_key_length(cipher); 572 client->key.len = key_len;
568 server->key.len = EVP_CIPHER_key_length(cipher); 573 server->key.len = key_len;
569 574
570 client->iv.len = EVP_CIPHER_iv_length(cipher); 575 client->iv.len = NGX_QUIC_IV_LEN;
571 server->iv.len = EVP_CIPHER_iv_length(cipher); 576 server->iv.len = NGX_QUIC_IV_LEN;
572 577
573 client->hp.len = EVP_CIPHER_key_length(cipher); 578 client->hp.len = key_len;
574 server->hp.len = EVP_CIPHER_key_length(cipher); 579 server->hp.len = key_len;
575 580
576 struct { 581 struct {
577 ngx_str_t label; 582 ngx_str_t label;
578 ngx_str_t *key; 583 ngx_str_t *key;
579 const uint8_t *secret; 584 const uint8_t *secret;
586 { ngx_string("tls13 quic hp"), &server->hp, write_secret }, 591 { ngx_string("tls13 quic hp"), &server->hp, write_secret },
587 }; 592 };
588 593
589 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) { 594 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
590 595
591 if (ngx_quic_hkdf_expand(c, digest, seq[i].key, &seq[i].label, 596 if (ngx_quic_hkdf_expand(c, ciphers.d, seq[i].key, &seq[i].label,
592 seq[i].secret, secret_len) 597 seq[i].secret, secret_len)
593 != NGX_OK) 598 != NGX_OK)
594 { 599 {
595 return 0; 600 return 0;
596 } 601 }
604 ngx_quic_create_long_packet(ngx_connection_t *c, ngx_ssl_conn_t *ssl_conn, 609 ngx_quic_create_long_packet(ngx_connection_t *c, ngx_ssl_conn_t *ssl_conn,
605 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res) 610 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res)
606 { 611 {
607 u_char *p, *pnp, *nonce, *sample, *packet; 612 u_char *p, *pnp, *nonce, *sample, *packet;
608 ngx_str_t ad, out; 613 ngx_str_t ad, out;
609 const EVP_CIPHER *cipher, *hp; 614 ngx_quic_ciphers_t ciphers;
610 ngx_quic_connection_t *qc; 615 ngx_quic_connection_t *qc;
611
612 u_char mask[16]; 616 u_char mask[16];
613 617
614 qc = c->quic; 618 qc = c->quic;
615 619
616 out.len = payload->len + EVP_GCM_TLS_TAG_LEN; 620 out.len = payload->len + EVP_GCM_TLS_TAG_LEN;
643 647
644 ad.len = p - ad.data; 648 ad.len = p - ad.data;
645 649
646 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len); 650 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len);
647 651
648 if (pkt->level != ssl_encryption_initial) { 652 if (ngx_quic_ciphers(c, &ciphers, pkt->level) == NGX_ERROR) {
649 switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl_conn)) & 0xffff) { 653 return NGX_ERROR;
650
651 case NGX_AES_128_GCM_SHA256:
652 cipher = EVP_aes_128_gcm();
653 hp = EVP_aes_128_ecb();
654 break;
655
656 case NGX_AES_256_GCM_SHA384:
657 cipher = EVP_aes_256_gcm();
658 hp = EVP_aes_256_ecb();
659 break;
660
661 default:
662 return NGX_ERROR;
663 }
664
665 } else {
666 cipher = EVP_aes_128_gcm();
667 hp = EVP_aes_128_ecb();
668 } 654 }
669 655
670 nonce = ngx_pstrdup(c->pool, &pkt->secret->iv); 656 nonce = ngx_pstrdup(c->pool, &pkt->secret->iv);
671 if (pkt->level == ssl_encryption_handshake) { 657 if (pkt->level == ssl_encryption_handshake) {
672 nonce[11] ^= (*pkt->number - 1); 658 nonce[11] ^= (*pkt->number - 1);
673 } 659 }
674 660
675 ngx_quic_hexdump0(c->log, "server_iv", pkt->secret->iv.data, 12); 661 ngx_quic_hexdump0(c->log, "server_iv", pkt->secret->iv.data, 12);
676 ngx_quic_hexdump0(c->log, "nonce", nonce, 12); 662 ngx_quic_hexdump0(c->log, "nonce", nonce, 12);
677 663
678 if (ngx_quic_tls_seal(c, cipher, pkt->secret, &out, nonce, payload, &ad) != NGX_OK) { 664 if (ngx_quic_tls_seal(c, ciphers.c, pkt->secret, &out, nonce, payload, &ad)
665 != NGX_OK)
666 {
679 return NGX_ERROR; 667 return NGX_ERROR;
680 } 668 }
681 669
682 sample = &out.data[3]; // pnl=0 670 sample = &out.data[3]; // pnl=0
683 if (ngx_quic_tls_hp(c, hp, pkt->secret, mask, sample) != NGX_OK) { 671 if (ngx_quic_tls_hp(c, ciphers.hp, pkt->secret, mask, sample) != NGX_OK) {
684 return NGX_ERROR; 672 return NGX_ERROR;
685 } 673 }
686 674
687 ngx_quic_hexdump0(c->log, "sample", sample, 16); 675 ngx_quic_hexdump0(c->log, "sample", sample, 16);
688 ngx_quic_hexdump0(c->log, "mask", mask, 16); 676 ngx_quic_hexdump0(c->log, "mask", mask, 16);
711 ngx_quic_create_short_packet(ngx_connection_t *c, ngx_ssl_conn_t *ssl_conn, 699 ngx_quic_create_short_packet(ngx_connection_t *c, ngx_ssl_conn_t *ssl_conn,
712 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res) 700 ngx_quic_header_t *pkt, ngx_str_t *payload, ngx_str_t *res)
713 { 701 {
714 u_char *p, *pnp, *nonce, *sample, *packet; 702 u_char *p, *pnp, *nonce, *sample, *packet;
715 ngx_str_t ad, out; 703 ngx_str_t ad, out;
716 const EVP_CIPHER *cipher, *hp; 704 ngx_quic_ciphers_t ciphers;
717 ngx_quic_connection_t *qc; 705 ngx_quic_connection_t *qc;
718
719 u_char mask[16]; 706 u_char mask[16];
720 707
721 qc = c->quic; 708 qc = c->quic;
722 709
723 out.len = payload->len + EVP_GCM_TLS_TAG_LEN; 710 out.len = payload->len + EVP_GCM_TLS_TAG_LEN;
739 726
740 ad.len = p - ad.data; 727 ad.len = p - ad.data;
741 728
742 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len); 729 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len);
743 730
744 switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl_conn)) & 0xffff) { 731 if (ngx_quic_ciphers(c, &ciphers, pkt->level) == NGX_ERROR) {
745
746 case NGX_AES_128_GCM_SHA256:
747 cipher = EVP_aes_128_gcm();
748 hp = EVP_aes_128_ecb();
749 break;
750
751 case NGX_AES_256_GCM_SHA384:
752 cipher = EVP_aes_256_gcm();
753 hp = EVP_aes_256_ecb();
754 break;
755
756 default:
757 return NGX_ERROR; 732 return NGX_ERROR;
758 } 733 }
759 734
760 nonce = ngx_pstrdup(c->pool, &pkt->secret->iv); 735 nonce = ngx_pstrdup(c->pool, &pkt->secret->iv);
761 if (pkt->level == ssl_encryption_handshake 736 if (pkt->level == ssl_encryption_handshake
765 } 740 }
766 741
767 ngx_quic_hexdump0(c->log, "server_iv", pkt->secret->iv.data, 12); 742 ngx_quic_hexdump0(c->log, "server_iv", pkt->secret->iv.data, 12);
768 ngx_quic_hexdump0(c->log, "nonce", nonce, 12); 743 ngx_quic_hexdump0(c->log, "nonce", nonce, 12);
769 744
770 if (ngx_quic_tls_seal(c, cipher, pkt->secret, &out, nonce, payload, &ad) 745 if (ngx_quic_tls_seal(c, ciphers.c, pkt->secret, &out, nonce, payload, &ad)
771 != NGX_OK) 746 != NGX_OK)
772 { 747 {
773 return NGX_ERROR; 748 return NGX_ERROR;
774 } 749 }
775 750
776 ngx_quic_hexdump0(c->log, "out", out.data, out.len); 751 ngx_quic_hexdump0(c->log, "out", out.data, out.len);
777 752
778 sample = &out.data[3]; // pnl=0 753 sample = &out.data[3]; // pnl=0
779 if (ngx_quic_tls_hp(c, hp, pkt->secret, mask, sample) != NGX_OK) { 754 if (ngx_quic_tls_hp(c, ciphers.hp, pkt->secret, mask, sample) != NGX_OK) {
780 return NGX_ERROR; 755 return NGX_ERROR;
781 } 756 }
782 757
783 ngx_quic_hexdump0(c->log, "sample", sample, 16); 758 ngx_quic_hexdump0(c->log, "sample", sample, 16);
784 ngx_quic_hexdump0(c->log, "mask", mask, 16); 759 ngx_quic_hexdump0(c->log, "mask", mask, 16);
1143 1118
1144 1119
1145 static ngx_int_t 1120 static ngx_int_t
1146 ngx_quic_decrypt(ngx_connection_t *c, ngx_quic_header_t *pkt) 1121 ngx_quic_decrypt(ngx_connection_t *c, ngx_quic_header_t *pkt)
1147 { 1122 {
1148 u_char clearflags, *p, *sample; 1123 u_char clearflags, *p, *sample;
1149 uint8_t *nonce; 1124 uint8_t *nonce;
1150 uint64_t pn; 1125 uint64_t pn;
1151 ngx_int_t pnl, rc; 1126 ngx_int_t pnl, rc;
1152 ngx_str_t in, ad; 1127 ngx_str_t in, ad;
1153 1128 ngx_quic_ciphers_t ciphers;
1154 const EVP_CIPHER *cipher, *hp; 1129 uint8_t mask[16];
1155 1130
1156 uint8_t mask[16]; 1131 if (ngx_quic_ciphers(c, &ciphers, pkt->level) == NGX_ERROR) {
1157 1132 return NGX_ERROR;
1158 if (c->ssl) {
1159 switch (SSL_CIPHER_get_id(SSL_get_current_cipher(c->ssl->connection)) & 0xffff) {
1160
1161 case NGX_AES_128_GCM_SHA256:
1162 cipher = EVP_aes_128_gcm();
1163 hp = EVP_aes_128_ecb();
1164 break;
1165 case NGX_AES_256_GCM_SHA384:
1166 cipher = EVP_aes_256_gcm();
1167 hp = EVP_aes_256_ecb();
1168 break;
1169 default:
1170 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "unexpected cipher");
1171 return NGX_ERROR;
1172 }
1173
1174 } else {
1175 /* initial packets */
1176 cipher = EVP_aes_128_gcm();
1177 hp = EVP_aes_128_ecb();
1178 } 1133 }
1179 1134
1180 p = pkt->pos; 1135 p = pkt->pos;
1181 1136
1182 /* draft-ietf-quic-tls-23#section-5.4.2: 1137 /* draft-ietf-quic-tls-23#section-5.4.2:
1189 1144
1190 ngx_quic_hexdump0(c->log, "sample", sample, 16); 1145 ngx_quic_hexdump0(c->log, "sample", sample, 16);
1191 1146
1192 /* header protection */ 1147 /* header protection */
1193 1148
1194 if (ngx_quic_tls_hp(c, hp, pkt->secret, mask, sample) != NGX_OK) { 1149 if (ngx_quic_tls_hp(c, ciphers.hp, pkt->secret, mask, sample) != NGX_OK) {
1195 return NGX_ERROR; 1150 return NGX_ERROR;
1196 } 1151 }
1197 1152
1198 if (pkt->flags & NGX_QUIC_PKT_LONG) { 1153 if (pkt->flags & NGX_QUIC_PKT_LONG) {
1199 clearflags = pkt->flags ^ (mask[0] & 0x0f); 1154 clearflags = pkt->flags ^ (mask[0] & 0x0f);
1238 nonce[11] ^= pn; 1193 nonce[11] ^= pn;
1239 1194
1240 ngx_quic_hexdump0(c->log, "nonce", nonce, 12); 1195 ngx_quic_hexdump0(c->log, "nonce", nonce, 12);
1241 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len); 1196 ngx_quic_hexdump0(c->log, "ad", ad.data, ad.len);
1242 1197
1243 rc = ngx_quic_tls_open(c, cipher, pkt->secret, &pkt->payload, 1198 rc = ngx_quic_tls_open(c, ciphers.c, pkt->secret, &pkt->payload,
1244 nonce, &in, &ad); 1199 nonce, &in, &ad);
1245 1200
1246 ngx_quic_hexdump0(c->log, "packet payload", 1201 ngx_quic_hexdump0(c->log, "packet payload",
1247 pkt->payload.data, pkt->payload.len); 1202 pkt->payload.data, pkt->payload.len);
1248 1203
1880 return NGX_OK; 1835 return NGX_OK;
1881 } 1836 }
1882 1837
1883 1838
1884 static ngx_int_t 1839 static ngx_int_t
1885 ngx_quic_tls_open(ngx_connection_t *c, const EVP_CIPHER *cipher, 1840 ngx_quic_tls_open(ngx_connection_t *c, const ngx_quic_cipher_t *cipher,
1886 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, 1841 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in,
1887 ngx_str_t *ad) 1842 ngx_str_t *ad)
1888 { 1843 {
1889 out->len = in->len - EVP_GCM_TLS_TAG_LEN; 1844 out->len = in->len - EVP_GCM_TLS_TAG_LEN;
1890 out->data = ngx_pnalloc(c->pool, out->len); 1845 out->data = ngx_pnalloc(c->pool, out->len);
1891 if (out->data == NULL) { 1846 if (out->data == NULL) {
1892 return NGX_ERROR; 1847 return NGX_ERROR;
1893 } 1848 }
1894 1849
1895 #ifdef OPENSSL_IS_BORINGSSLL 1850 #ifdef OPENSSL_IS_BORINGSSL
1896 EVP_AEAD_CTX *ctx; 1851 EVP_AEAD_CTX *ctx;
1897 1852
1898 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len, 1853 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len,
1899 EVP_AEAD_DEFAULT_TAG_LENGTH); 1854 EVP_AEAD_DEFAULT_TAG_LENGTH);
1900 if (ctx == NULL) { 1855 if (ctx == NULL) {
1985 return NGX_OK; 1940 return NGX_OK;
1986 } 1941 }
1987 1942
1988 1943
1989 static ngx_int_t 1944 static ngx_int_t
1990 ngx_quic_tls_seal(ngx_connection_t *c, const EVP_CIPHER *cipher, 1945 ngx_quic_tls_seal(ngx_connection_t *c, const ngx_quic_cipher_t *cipher,
1991 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in, 1946 ngx_quic_secret_t *s, ngx_str_t *out, u_char *nonce, ngx_str_t *in,
1992 ngx_str_t *ad) 1947 ngx_str_t *ad)
1993 { 1948 {
1994 out->len = in->len + EVP_GCM_TLS_TAG_LEN; 1949 out->len = in->len + EVP_GCM_TLS_TAG_LEN;
1995 out->data = ngx_pnalloc(c->pool, out->len); 1950 out->data = ngx_pnalloc(c->pool, out->len);
1996 if (out->data == NULL) { 1951 if (out->data == NULL) {
1997 return NGX_ERROR; 1952 return NGX_ERROR;
1998 } 1953 }
1999 1954
2000 #ifdef OPENSSL_IS_BORINGSSLL 1955 #ifdef OPENSSL_IS_BORINGSSL
2001 EVP_AEAD_CTX *ctx; 1956 EVP_AEAD_CTX *ctx;
2002 1957
2003 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len, 1958 ctx = EVP_AEAD_CTX_new(cipher, s->key.data, s->key.len,
2004 EVP_AEAD_DEFAULT_TAG_LENGTH); 1959 EVP_AEAD_DEFAULT_TAG_LENGTH);
2005 if (ctx == NULL) { 1960 if (ctx == NULL) {
2093 ngx_quic_tls_hp(ngx_connection_t *c, const EVP_CIPHER *cipher, 2048 ngx_quic_tls_hp(ngx_connection_t *c, const EVP_CIPHER *cipher,
2094 ngx_quic_secret_t *s, u_char *out, u_char *in) 2049 ngx_quic_secret_t *s, u_char *out, u_char *in)
2095 { 2050 {
2096 int outlen; 2051 int outlen;
2097 EVP_CIPHER_CTX *ctx; 2052 EVP_CIPHER_CTX *ctx;
2053 u_char zero[5] = {0};
2098 2054
2099 ctx = EVP_CIPHER_CTX_new(); 2055 ctx = EVP_CIPHER_CTX_new();
2100 if (ctx == NULL) { 2056 if (ctx == NULL) {
2101 return NGX_ERROR; 2057 return NGX_ERROR;
2102 } 2058 }
2103 2059
2104 if (EVP_EncryptInit_ex(ctx, cipher, NULL, s->hp.data, NULL) != 1) { 2060 if (EVP_EncryptInit_ex(ctx, cipher, NULL, s->hp.data, in) != 1) {
2105 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptInit_ex() failed"); 2061 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptInit_ex() failed");
2106 goto failed; 2062 goto failed;
2107 } 2063 }
2108 2064
2109 if (!EVP_EncryptUpdate(ctx, out, &outlen, in, 16)) { 2065 if (!EVP_EncryptUpdate(ctx, out, &outlen, zero, 5)) {
2110 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptUpdate() failed"); 2066 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptUpdate() failed");
2111 goto failed; 2067 goto failed;
2112 } 2068 }
2113 2069
2070 if (!EVP_EncryptFinal_ex(ctx, out + 5, &outlen)) {
2071 ngx_ssl_error(NGX_LOG_INFO, c->log, 0, "EVP_EncryptFinal_Ex() failed");
2072 goto failed;
2073 }
2074
2114 EVP_CIPHER_CTX_free(ctx); 2075 EVP_CIPHER_CTX_free(ctx);
2115 2076
2116 return NGX_OK; 2077 return NGX_OK;
2117 2078
2118 failed: 2079 failed:
2119 2080
2120 EVP_CIPHER_CTX_free(ctx); 2081 EVP_CIPHER_CTX_free(ctx);
2121 2082
2122 return NGX_ERROR; 2083 return NGX_ERROR;
2123 } 2084 }
2085
2086
2087 static ngx_int_t
2088 ngx_quic_ciphers(ngx_connection_t *c, ngx_quic_ciphers_t *ciphers,
2089 enum ssl_encryption_level_t level)
2090 {
2091 ngx_int_t id, len;
2092
2093 if (level == ssl_encryption_initial) {
2094 id = NGX_AES_128_GCM_SHA256;
2095
2096 } else {
2097 id = SSL_CIPHER_get_id(SSL_get_current_cipher(c->ssl->connection))
2098 & 0xffff;
2099 }
2100
2101 switch (id) {
2102
2103 case NGX_AES_128_GCM_SHA256:
2104 #ifdef OPENSSL_IS_BORINGSSL
2105 ciphers->c = EVP_aead_aes_128_gcm();
2106 #else
2107 ciphers->c = EVP_aes_128_gcm();
2108 #endif
2109 ciphers->hp = EVP_aes_128_ctr();
2110 ciphers->d = EVP_sha256();
2111 len = 16;
2112 break;
2113
2114 case NGX_AES_256_GCM_SHA384:
2115 #ifdef OPENSSL_IS_BORINGSSL
2116 ciphers->c = EVP_aead_aes_256_gcm();
2117 #else
2118 ciphers->c = EVP_aes_256_gcm();
2119 #endif
2120 ciphers->hp = EVP_aes_256_ctr();
2121 ciphers->d = EVP_sha384();
2122 len = 32;
2123 break;
2124
2125 default:
2126 return NGX_ERROR;
2127 }
2128
2129 return len;
2130 }