comparison src/event/ngx_event_quic_protection.c @ 8319:29354c6fc5f2 quic

TLS Key Update in QUIC. Old keys retention is yet to be implemented.
author Sergey Kandaurov <pluknet@nginx.com>
date Mon, 06 Apr 2020 14:54:08 +0300
parents 1bb5e8538d0c
children 7cca3624f9c4
comparison
equal deleted inserted replaced
8318:1bb5e8538d0c 8319:29354c6fc5f2
230 { 230 {
231 size_t info_len; 231 size_t info_len;
232 uint8_t *p; 232 uint8_t *p;
233 uint8_t info[20]; 233 uint8_t info[20];
234 234
235 out->data = ngx_pnalloc(pool, out->len);
236 if (out->data == NULL) { 235 if (out->data == NULL) {
237 return NGX_ERROR; 236 out->data = ngx_pnalloc(pool, out->len);
237 if (out->data == NULL) {
238 return NGX_ERROR;
239 }
238 } 240 }
239 241
240 info_len = 2 + 1 + label->len + 1; 242 info_len = 2 + 1 + label->len + 1;
241 243
242 info[0] = 0; 244 info[0] = 0;
619 } 621 }
620 622
621 if (level == ssl_encryption_initial) { 623 if (level == ssl_encryption_initial) {
622 return 0; 624 return 0;
623 } 625 }
626
627 peer_secret->secret.data = ngx_pnalloc(pool, secret_len);
628 if (peer_secret->secret.data == NULL) {
629 return NGX_ERROR;
630 }
631
632 peer_secret->secret.len = secret_len;
633 ngx_memcpy(peer_secret->secret.data, secret, secret_len);
624 634
625 peer_secret->key.len = key_len; 635 peer_secret->key.len = key_len;
626 peer_secret->iv.len = NGX_QUIC_IV_LEN; 636 peer_secret->iv.len = NGX_QUIC_IV_LEN;
627 peer_secret->hp.len = key_len; 637 peer_secret->hp.len = key_len;
628 638
648 658
649 return 1; 659 return 1;
650 } 660 }
651 661
652 662
663 ngx_int_t
664 ngx_quic_key_update(ngx_connection_t *c, ngx_quic_secrets_t *current,
665 ngx_quic_secrets_t *next)
666 {
667 ngx_uint_t i;
668 ngx_quic_ciphers_t ciphers;
669
670 ngx_log_debug(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic key update");
671
672 if (ngx_quic_ciphers(c->ssl->connection, &ciphers,
673 ssl_encryption_application)
674 == NGX_ERROR)
675 {
676 return NGX_ERROR;
677 }
678
679 next->client.secret.len = current->client.secret.len;
680 next->client.key.len = current->client.key.len;
681 next->client.iv.len = current->client.iv.len;
682 next->client.hp = current->client.hp;
683
684 next->server.secret.len = current->server.secret.len;
685 next->server.key.len = current->server.key.len;
686 next->server.iv.len = current->server.iv.len;
687 next->server.hp = current->server.hp;
688
689 struct {
690 ngx_str_t label;
691 ngx_str_t *key;
692 ngx_str_t *secret;
693 } seq[] = {
694 {
695 ngx_string("tls13 quic ku"),
696 &next->client.secret,
697 &current->client.secret,
698 },
699 {
700 ngx_string("tls13 quic key"),
701 &next->client.key,
702 &next->client.secret,
703 },
704 {
705 ngx_string("tls13 quic iv"),
706 &next->client.iv,
707 &next->client.secret,
708 },
709 {
710 ngx_string("tls13 quic ku"),
711 &next->server.secret,
712 &current->server.secret,
713 },
714 {
715 ngx_string("tls13 quic key"),
716 &next->server.key,
717 &next->server.secret,
718 },
719 {
720 ngx_string("tls13 quic iv"),
721 &next->server.iv,
722 &next->server.secret,
723 },
724 };
725
726 for (i = 0; i < (sizeof(seq) / sizeof(seq[0])); i++) {
727
728 if (ngx_quic_hkdf_expand(c->pool, ciphers.d, seq[i].key, &seq[i].label,
729 seq[i].secret->data, seq[i].secret->len)
730 != NGX_OK)
731 {
732 return NGX_ERROR;
733 }
734 }
735
736 return NGX_OK;
737 }
738
739
653 static ssize_t 740 static ssize_t
654 ngx_quic_create_long_packet(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn, 741 ngx_quic_create_long_packet(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn,
655 ngx_str_t *res) 742 ngx_str_t *res)
656 { 743 {
657 u_char *pnp, *sample; 744 u_char *pnp, *sample;
819 ngx_int_t 906 ngx_int_t
820 ngx_quic_decrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn) 907 ngx_quic_decrypt(ngx_quic_header_t *pkt, ngx_ssl_conn_t *ssl_conn)
821 { 908 {
822 u_char clearflags, *p, *sample; 909 u_char clearflags, *p, *sample;
823 uint64_t pn; 910 uint64_t pn;
824 ngx_int_t pnl, rc; 911 ngx_int_t pnl, rc, key_phase;
825 ngx_str_t in, ad; 912 ngx_str_t in, ad;
913 ngx_quic_secret_t *secret;
826 ngx_quic_ciphers_t ciphers; 914 ngx_quic_ciphers_t ciphers;
827 uint8_t mask[16], nonce[12]; 915 uint8_t mask[16], nonce[12];
828 916
829 if (ngx_quic_ciphers(ssl_conn, &ciphers, pkt->level) == NGX_ERROR) { 917 if (ngx_quic_ciphers(ssl_conn, &ciphers, pkt->level) == NGX_ERROR) {
830 return NGX_ERROR; 918 return NGX_ERROR;
831 } 919 }
920
921 secret = pkt->secret;
832 922
833 p = pkt->raw->pos; 923 p = pkt->raw->pos;
834 924
835 /* draft-ietf-quic-tls-23#section-5.4.2: 925 /* draft-ietf-quic-tls-23#section-5.4.2:
836 * the Packet Number field is assumed to be 4 bytes long 926 * the Packet Number field is assumed to be 4 bytes long
842 932
843 ngx_quic_hexdump0(pkt->log, "sample", sample, 16); 933 ngx_quic_hexdump0(pkt->log, "sample", sample, 16);
844 934
845 /* header protection */ 935 /* header protection */
846 936
847 if (ngx_quic_tls_hp(pkt->log, ciphers.hp, pkt->secret, mask, sample) 937 if (ngx_quic_tls_hp(pkt->log, ciphers.hp, secret, mask, sample)
848 != NGX_OK) 938 != NGX_OK)
849 { 939 {
850 return NGX_ERROR; 940 return NGX_ERROR;
851 } 941 }
852 942
853 if (ngx_quic_long_pkt(pkt->flags)) { 943 if (ngx_quic_long_pkt(pkt->flags)) {
854 clearflags = pkt->flags ^ (mask[0] & 0x0f); 944 clearflags = pkt->flags ^ (mask[0] & 0x0f);
855 945
856 } else { 946 } else {
857 clearflags = pkt->flags ^ (mask[0] & 0x1f); 947 clearflags = pkt->flags ^ (mask[0] & 0x1f);
948 key_phase = (clearflags & NGX_QUIC_PKT_KPHASE) != 0;
949
950 if (key_phase != pkt->key_phase) {
951 secret = pkt->next;
952 pkt->key_update = 1;
953 }
858 } 954 }
859 955
860 pnl = (clearflags & 0x03) + 1; 956 pnl = (clearflags & 0x03) + 1;
861 pn = ngx_quic_parse_pn(&p, pnl, &mask[1]); 957 pn = ngx_quic_parse_pn(&p, pnl, &mask[1]);
862 958
887 983
888 do { 984 do {
889 ad.data[ad.len - pnl] = pn >> (8 * (pnl - 1)) % 256; 985 ad.data[ad.len - pnl] = pn >> (8 * (pnl - 1)) % 256;
890 } while (--pnl); 986 } while (--pnl);
891 987
892 ngx_memcpy(nonce, pkt->secret->iv.data, pkt->secret->iv.len); 988 ngx_memcpy(nonce, secret->iv.data, secret->iv.len);
893 ngx_quic_compute_nonce(nonce, sizeof(nonce), pn); 989 ngx_quic_compute_nonce(nonce, sizeof(nonce), pn);
894 990
895 ngx_quic_hexdump0(pkt->log, "nonce", nonce, 12); 991 ngx_quic_hexdump0(pkt->log, "nonce", nonce, 12);
896 ngx_quic_hexdump0(pkt->log, "ad", ad.data, ad.len); 992 ngx_quic_hexdump0(pkt->log, "ad", ad.data, ad.len);
897 993
901 return NGX_ERROR; 997 return NGX_ERROR;
902 } 998 }
903 999
904 pkt->payload.data = pkt->plaintext + ad.len; 1000 pkt->payload.data = pkt->plaintext + ad.len;
905 1001
906 rc = ngx_quic_tls_open(ciphers.c, pkt->secret, &pkt->payload, 1002 rc = ngx_quic_tls_open(ciphers.c, secret, &pkt->payload,
907 nonce, &in, &ad, pkt->log); 1003 nonce, &in, &ad, pkt->log);
908 1004
909 ngx_quic_hexdump0(pkt->log, "packet payload", 1005 ngx_quic_hexdump0(pkt->log, "packet payload",
910 pkt->payload.data, pkt->payload.len); 1006 pkt->payload.data, pkt->payload.len);
911 1007