QUIC Version 2 の仕様 (RFC 9369)

(追記: 2023/06/01 RFC 9369になりました)

QUIC Version 2」という仕様が提案されています。これは、「RFC 9000」で標準化されたQUIC v1と機能上はまったく同じものです。

この提案仕様の目的は、主にふたつあります。

  • 硬直化(ossification)の問題を緩和し将来のQUICバージョンをインターネットでデプロイしやすくする
  • バージョンネゴシエーションを実行できるようにする

11月に実施されたIETF 112の後に、QUIC WGのメーリングリストで、この仕様にWGとして取り組んでいくコンセンサスが得られました。現在はWG Draftとなっています。

なお、Version 2はまだ2番目のバージョンということで便宜上そう呼んでいるようです。バージョン番号の正式なアサインは後に行われます。

硬直化(ossification)の問題の緩和

硬直化とは、新しいバージョンのプロトコルを使おうとしたときに、対応していないネットワーク機器やミドルウェアが不具合を起こし、通信が阻害されることを言います。TCP Fast Openや、TLS 1.3 などで、ハンドジェクは完了するが片方向で通信がブロックされるといった、おかしな挙動をするネットワーク機器が見つかり、問題になりました。

QUICも硬直化する可能性があります。将来デプロイされるQUICv2に対応してない実装が誤ってそのパケットを処理し、不具合が起き通信が阻害される可能性があります。Google QUICでの実験ではその問題がすでに起こっていたことを明らかにしています。もちろん、IETF QUICでは硬直化が起きないように対策されています。

QUICv1のパケットは、暗号化にバージョン固有のソルトを使用しています。将来のQUICでも同様にバージョン固有のソルトを使えば、そのバージョンに対応していない(=ソルトを知らない)実装は、暗号的に初期パケットを解読できません。ですので、間違えて処理をするという問題を軽減されています。

QUIC Version 2では、これらのバージョンに固有な暗号用のパラーメータが実装上正しく変えられるようになります。逆にQUIC Version 2に対応していない実装が、QUIC Version 1のロジックで復号しようとするネットワーク装置などの問題をあぶり出すことが出来ます。

暗号関連の変更点

QUIC Version 2で変更される暗号関係のパラメータは次のとおりです。

QUIC Version 2」では、initial_salt を次のように指定しています。

initial_salt = 0xa707c203a59b47184a1d62ca570406ea7ae3e5d3

またパケット保護に使う鍵の導出に使うラベルも変更されます

  • quic key => quicv2 key
  • quic iv => quicv2 iv
  • quic hp => quicv2 hp
  • quic ku => quicv2 ku

Retry Integrityタグに使う値は次に変更されます

secret = 0x3425c20cf88779df2ff71e8abfa78249891e763bbed2f13c048343d348c060e2
key = 0xba858dc7b43de5dbf87617ff4ab253db
nonce = 0x141b99c239b03e785d6a2e9f

バージョンネゴシエーション

QUICはクライアント・サーバ間で使用するQUICバージョンをネゴシエーションします。将来標準化されるQUICの登場を待ってその仕組を作るのではなく、すでに「https://www.ietf.org/id/draft-ietf-quic-version-negotiation-05.html」として標準化が進められています。この仕組を実際に使っていくことで、将来のQUICバージョンのデプロイをしやすく出来ます。バージョンネゴシエーションを行う選択肢として「QUIC Version 2」の標準化を行っているという意味もあります

バージョンネゴシエーションの仕組みは以前書いたとおりになります。
asnokaze.hatenablog.com

アプリケーションでの利用、拡張機能

QUIC Version 2は、機能上QUICv1と代わりありません。QUICv1を使うアプリケーションプロトコルは、ALPNの変更無くQUIC Version 2を使用出来ます。

また、QUICv1で機能する拡張は、QUIC Version 2でも使用できます。

その他

ふと、疑問が一点。
QUICv1で通信したことある、Version 2に対応しているクライアントとサーバがいたとする。次の通信で、QUICv1で0-RTTを投げたときにCompatible Version NegotiationしたときのEarly Dataの扱いは、実装依存なのかな?ハンドシェイク上はただのPSKという感じで?

なんだかややこしい...orz