RFC 9001 TLSを使用したQUICの保護 2021年5月
Thomson & Turner 標準化過程 [ページ]
ストリーム:
Internet Engineering Task Force (IETF)
RFC:
9001
カテゴリー:
標準化過程
公開:
ISSN:
2070-1721
著者:
M. Thomson, 編
Mozilla
S. Turner, 編
sn3rd

RFC 9001

TLSを使用したQUICの保護

概要

この文書では、Transport Layer Security (TLS)を使用して QUICを保護する方法について説明します。

このメモの位置付け

これはInternet Standards Trackの文書です。

この文書はInternet Engineering Task Force (IETF)の成果物です。これはIETFコミュニティの総意を表しています。これは 公開レビューを受け、Internet Engineering Steering Group (IESG)によって公開が承認されています。Internet Standardsに関する 詳細情報はRFC 7841のセクション2で 入手できます。

この文書の現在の状態、訂正情報、および この文書に対するフィードバックの提供方法に関する情報は、 https://www.rfc-editor.org/info/rfc9001で入手できます。

▲

目次

1. はじめに

この文書では、QUIC [QUIC-TRANSPORT]をTLS [TLS13]を使用して保護する方法について説明します。

TLS 1.3は、以前のバージョンと比べて接続確立のレイテンシーを大幅に改善します。 パケット損失がなければ、ほとんどの新しい接続は1回のラウンドトリップ内で確立して 保護できます。同じクライアントとサーバー間の後続の接続では、クライアントは多くの場合、 アプリケーションデータを直ちに送信できます。つまり、ゼロラウンドトリップ設定を使用できます。

この文書では、TLSがQUICのセキュリティコンポーネントとしてどのように機能するかを説明します。

2. 表記規則

この文書におけるキーワード「MUST」、「MUST NOT」、 「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、 「SHOULD NOT」、「RECOMMENDED」、「NOT RECOMMENDED」、「MAY」、および「OPTIONAL」は、 ここに示すようにすべて大文字で表記されている場合に限り、BCP 14 [RFC2119] [RFC8174] に記載されているとおりに解釈されます。

この文書では、[QUIC-TRANSPORT]で確立された用語を使用します。

簡潔にするため、より新しいバージョンを使用できる場合でも、TLSという略語はTLS 1.3を指すために使用します。 セクション4.2を参照してください。

2.1. TLSの概要

TLSは、2つのエンドポイントが信頼できない媒体(たとえばインターネット)上で 通信手段を確立する方法を提供します。TLSはピアの認証を可能にし、 エンドポイント間で交換されるメッセージの機密性と完全性を 保護します。

内部的には、TLSは階層化されたプロトコルであり、その構造を 図1に示します。

          +-------------+------------+--------------+---------+
コンテンツ|             |            |アプリケーション|         |
レイヤー  |ハンドシェイク|  アラート  |    データ      |   ...   |
          |             |            |              |         |
          +-------------+------------+--------------+---------+
レコード  |                                                   |
レイヤー  |                    レコード                       |
          |                                                   |
          +---------------------------------------------------+
図1: TLSのレイヤー

各コンテンツレイヤーのメッセージ(たとえば、ハンドシェイク、アラート、アプリケーションデータ)は、 レコードレイヤーによって一連の型付きTLSレコードとして伝送されます。レコードは 個別に暗号学的保護が施された後、順序付けと確実な配信を提供する 信頼性のあるトランスポート(通常はTCP)上で送信されます。

TLSの認証付き鍵交換は、クライアントと サーバーという2つのエンドポイント間で行われます。クライアントが交換を開始し、サーバーが応答します。鍵 交換が正常に完了すると、クライアントとサーバーの両方がシークレットについて合意します。 TLSは、事前共有鍵(PSK)と、有限 体または楕円曲線上のDiffie-Hellman((EC)DHE)鍵交換の両方をサポートします。PSKはEarly Data(0-RTT)の基礎となります。後者は、(EC)DHE 鍵が破棄された場合に前方秘匿性(FS)を提供します。2つのモードを組み合わせて、PSKを認証に使用しながら 前方秘匿性を提供することもできます。

TLSハンドシェイクが完了すると、クライアントはサーバーの IDを取得して認証しており、サーバーは任意で クライアントのIDを取得して認証できます。TLSは、サーバーとクライアントの両方についてX.509 [RFC5280]証明書ベースの認証をサポートします。 PSK鍵交換が使用される場合(再開時など)、PSKを知っていることが ピアの認証として機能します。

TLS鍵交換は攻撃者による改ざんに耐性があり、 参加するどちらのピアも制御できない共有シークレットを生成します。

TLSは、QUICに関連する2つの基本的なハンドシェイクモードを提供します。

  • 完全な1-RTTハンドシェイクでは、クライアントは 1回のラウンドトリップ後にアプリケーションデータを送信でき、サーバーはクライアントから 最初のハンドシェイクメッセージを受信した直後に応答します。
  • 0-RTTハンドシェイクでは、クライアントは以前に サーバーについて取得した情報を使用して、アプリケーションデータを直ちに送信します。この アプリケーションデータは攻撃者によってリプレイされる可能性があるため、0-RTTは リプレイされた場合に望ましくない影響を引き起こす可能性のある 動作を開始する命令の伝送には適していません。

0-RTTアプリケーションデータを含む簡略化されたTLSハンドシェイクを図2に示します。

    クライアント                                         サーバー

    ClientHello
   (0-RTTアプリケーションデータ) -------->
                                                  ServerHello
                                         {EncryptedExtensions}
                                                    {Finished}
                             <-------- [アプリケーションデータ]
   {Finished}                -------->

   [アプリケーションデータ]  <-------> [アプリケーションデータ]

    () はEarly Data(0-RTT)鍵で保護されたメッセージを示す
    {} はHandshake鍵を使用して保護されたメッセージを示す
    [] はApplication Data
       (1-RTT)鍵を使用して保護されたメッセージを示す
図2: 0-RTTを使用するTLSハンドシェイク

図2では、QUICで使用されないEndOfEarlyData メッセージを省略しています。 セクション8.3を参照してください。同様に、ChangeCipherSpecメッセージも KeyUpdateメッセージも QUICでは使用されません。ChangeCipherSpecはTLS 1.3では冗長です。セクション8.4を参照してください。 QUICには独自の鍵更新メカニズムがあります。セクション6を参照してください。

データは、複数の暗号化レベルを使用して保護されます。

  • Initial鍵
  • Early Data(0-RTT)鍵
  • Handshake鍵
  • Application Data(1-RTT)鍵

アプリケーションデータは、Early DataレベルとApplication Data レベルにのみ現れることができます。ハンドシェイクメッセージとアラートメッセージは、どのレベルにも現れることができます。

0-RTTハンドシェイクは、クライアントとサーバーが以前に 通信したことがある場合に使用できます。1-RTTハンドシェイクでは、クライアントは サーバーから送信されたすべてのハンドシェイクメッセージを受信するまで、保護された アプリケーションデータを送信できません。

3. プロトコルの概要

QUIC [QUIC-TRANSPORT]は、 パケットの機密性と 完全性の保護を担います。そのためにTLS ハンドシェイク[TLS13]から導出された鍵を使用しますが、 (TCPの場合のように)TLSレコードをQUIC上で伝送するのではなく、TLSハンドシェイクメッセージとアラートメッセージを QUICトランスポート上で直接伝送します。QUICトランスポートはTLSレコードレイヤーの責務を引き継ぎます。 これを図3に示します。

+--------------+--------------+ +-------------+
|     TLS      |     TLS      | |    QUIC     |
|ハンドシェイク|   アラート   | |アプリケーション|
|              |              | |(h3など)      |
+--------------+--------------+-+-------------+
|                                             |
|                QUICトランスポート            |
| (ストリーム、信頼性、輻輳など)             |
|                                             |
+---------------------------------------------+
|                                             |
|              QUICパケット保護               |
|                                             |
+---------------------------------------------+
図3: QUICのレイヤー

QUICは、セキュリティと性能にとって重要なパラメーターの認証とネゴシエーションについても TLSに依存します。

厳密な階層化ではなく、これら2つのプロトコルは協調します。QUICはTLS ハンドシェイクを使用し、TLSはQUICが提供する信頼性、順序付き配信、およびレコードレイヤーを 使用します。

大まかに言えば、TLSコンポーネントとQUICコンポーネントの間には、 主に2つの相互作用があります。

図4では、これらの相互作用をより詳しく示し、 QUICパケット 保護を特に取り上げています。

+------------+                               +------------+
|            |<-- ハンドシェイクメッセージ -->|            |
|            |<- 0-RTTパラメーターを検証 ---->|            |
|            |<--------- 0-RTT鍵 ------------|            |
|    QUIC    |<------- Handshake鍵 ----------|    TLS     |
|            |<--------- 1-RTT鍵 ------------|            |
|            |<----- ハンドシェイク完了 ------|            |
+------------+                               +------------+
 |         ^
 | 保護    | 保護済み
 v         | パケット
+------------+
|    QUIC    |
|  パケット  |
|    保護    |
+------------+
図4: QUICとTLSの相互作用

TCP上のTLSとは異なり、データを送信しようとするQUICアプリケーションは、 TLS Application Dataレコードを使用して送信しません。代わりに、QUIC STREAM フレームまたはその他のフレームタイプとして送信し、それらがQUICパケットで伝送されます。

4. TLSメッセージの伝送

QUICはTLSハンドシェイクデータをCRYPTOフレームで伝送します。各フレームは、 オフセットと長さによって識別される連続したハンドシェイクデータのブロックで構成されます。これらの フレームはQUICパケットに格納され、現在の 暗号化レベルで暗号化されます。TCP上のTLSと同様に、TLSハンドシェイクデータが QUICに渡された後は、それを確実に配信することはQUICの責任です。TLSによって 生成される各データチャンクには、その時点で TLSが使用している鍵のセットが関連付けられます。QUICがそのデータを再送する必要がある場合、TLSが すでに新しい鍵に更新されていたとしても、 同じ鍵を使用MUST。

各暗号化レベルは、1つのパケット番号空間に対応します。使用されるパケット番号 空間によって、フレームの意味が決まります。一部のフレームは、 特定のパケット番号空間では禁止されています。 [QUIC-TRANSPORT]のセクション12.5を参照してください。

パケットはネットワーク上で並べ替えられる可能性があるため、QUICはパケットタイプを使用して、 特定のパケットの保護にどの鍵が使用されたかを示します。これを 表1に示します。異なるタイプのパケットを送信する必要がある場合、 エンドポイントは同じUDP データグラム内で送信するために結合パケットを使用するSHOULD。

表1: パケットタイプ別の暗号化鍵
パケットタイプ 暗号化鍵 PN空間
Initial Initialシークレット Initial
0-RTT Protected 0-RTT アプリケーションデータ
Handshake Handshake Handshake
Retry Retry N/A
Version Negotiation N/A N/A
Short Header 1-RTT アプリケーションデータ

[QUIC-TRANSPORT]のセクション17では、さまざまな暗号化 レベルのパケットがハンドシェイク処理にどのように組み込まれるかを示しています。

4.1. TLSへのインターフェイス

図4に示すように、QUICからTLSへのインターフェイスは、 4つの主要な機能で構成されます。

  • ハンドシェイクメッセージの送受信
  • 再開されたセッションから保存済みのトランスポートおよびアプリケーション状態を 処理し、0-RTTデータを生成または受け入れることが有効かどうかを判断すること
  • 鍵の再生成(送信と受信の両方)
  • ハンドシェイク状態の更新

TLSを構成するために追加の機能が必要になる場合があります。特に、QUICと TLSは、証明書の検証[RFC5280]など、 ピア資格情報の検証をどちらが担当するかについて合意する必要があります。

4.1.1. ハンドシェイクの完了

この文書では、TLSスタックが ハンドシェイクの完了を報告した時点で、TLSハンドシェイクが完了したものとみなします。これは、TLSスタックが Finishedメッセージを送信し、かつピアのFinishedメッセージを検証したときに発生します。 ピアのFinishedメッセージを検証することで、エンドポイントは、 それ以前のハンドシェイクメッセージが変更されていないことを確信できます。なお、 ハンドシェイクは両方のエンドポイントで同時に完了するわけではありません。したがって、 ハンドシェイクの完了に基づく要件は、対象となる エンドポイントの観点によって異なります。

4.1.2. ハンドシェイクの 確認

この文書では、サーバーでは ハンドシェイクが完了した時点でTLSハンドシェイクが確認済みとみなされます。サーバーは、 ハンドシェイクが完了すると直ちにHANDSHAKE_DONEフレームを送信MUST。 クライアントでは、HANDSHAKE_DONEフレームを受信した時点でハンドシェイクが確認済みとみなされます。

さらに、クライアントは、1-RTTパケットに対する 確認応答を受信した時点でハンドシェイクが確認済みであるとみなすMAY。これは、 1-RTT鍵で送信した最小のパケット番号を記録し、それを受信した 任意の1-RTT ACKフレームのLargest Acknowledgedフィールドと比較することで実装できます。後者が 前者以上になった時点で、ハンドシェイクは確認済みです。

4.1.3. ハンドシェイクメッセージの 送受信

ハンドシェイクを進めるために、TLSは ハンドシェイクメッセージを送受信できることに依存します。このインターフェイスには2つの基本的な機能があります。1つは QUICがハンドシェイクメッセージを要求するもの、もう1つはQUICが ハンドシェイクメッセージを構成するバイト列を提供するものです。

ハンドシェイクを開始する前に、QUICは伝送したいトランスポート パラメーター(セクション8.2を参照)をTLSに提供します。

QUICクライアントは、TLSにTLSハンドシェイクバイトを要求することでTLSを開始します。クライアントは、 最初のパケットを送信する前にハンドシェイクバイトを取得します。QUICサーバーは、 クライアントのハンドシェイクバイトをTLSに提供することで処理を開始します。

任意の時点で、エンドポイントのTLSスタックには、現在の 送信暗号化レベルと受信暗号化レベルがあります。TLSの暗号化レベルによって、データの保護に使用されるQUIC パケットタイプと鍵が決まります。

各暗号化レベルには異なるバイト列が関連付けられ、 CRYPTOフレーム内でピアに確実に送信されます。TLSが送信する ハンドシェイクバイトを提供すると、それらは現在の 暗号化レベルのハンドシェイクバイトに追加されます。その後、暗号化レベルによって、 生成されたCRYPTOフレームが格納されるパケットタイプが決まります。表1を参照してください。

4つの暗号化レベルが使用され、Initial、0-RTT、 Handshake、 および1-RTTパケット用の鍵が生成されます。CRYPTOフレームはこれらのうち3つのレベルでのみ伝送され、 0-RTTレベルでは伝送されません。これら4つのレベルは3つのパケット番号 空間に対応します。InitialおよびHandshake暗号化パケットはそれぞれ独立した空間を使用し、 0-RTTおよび1-RTTパケットはアプリケーションデータのパケット番号空間を使用します。

QUICは、TLSハンドシェイクレコードの保護されていない内容を CRYPTOフレームの内容として使用します。TLSレコード保護はQUICでは使用されません。QUICは CRYPTOフレームをQUICパケットにまとめ、それらをQUICパケット 保護を使用して保護します。

QUICのCRYPTOフレームはTLSハンドシェイクメッセージのみを伝送します。TLS アラートはQUIC CONNECTION_CLOSEエラーコードに変換されます。セクション4.8を参照してください。 TLSアプリケーションデータおよびその他のコンテンツタイプは、いかなる 暗号化レベルでもQUICによって伝送できません。TLSスタックからそれらを受信した場合はエラーです。

エンドポイントがネットワークからCRYPTOフレームを含むQUICパケットを 受信すると、次のように処理します。

  • パケットが現在のTLS受信 暗号化レベルを使用している場合、通常どおりデータを入力フローの 順序に配置します。STREAMフレームの場合と同様に、オフセットを使用して データ列内の適切な位置を特定します。この 処理の結果として新しいデータが利用可能になった場合、それを順番にTLSへ渡します。
  • パケットが以前にインストールされた 暗号化レベルからのものである場合、そのフローで以前に受信したデータの末尾を 超えて延長されるデータを含めてはMUST NOT。 実装は、この要件への違反を PROTOCOL_VIOLATIONタイプの接続エラーとして扱うMUST。
  • パケットが新しい暗号化レベルからのものである場合、 TLSによる後の処理のために保存されます。TLSがこの暗号化レベルからの受信へ移行すると、 保存されたデータをTLSに提供できます。TLSがより高い暗号化レベルの鍵を提供したとき、 TLSがまだ消費していない以前の暗号化レベルのデータが存在する場合、 これはPROTOCOL_VIOLATIONタイプの接続エラーとして扱うMUST。

TLSに新しいデータが提供されるたびに、新しいハンドシェイクバイトが TLSに要求されます。受信したハンドシェイクメッセージが 不完全である場合、または送信するデータがない場合、TLSはバイト列を提供しないことがあります。

CRYPTOフレームの内容は、TLSによって インクリメンタルに処理される場合もあれば、完全なメッセージまたはフライトが利用可能になるまで バッファリングされる場合もあります。順番に到着したハンドシェイクバイトをバッファリングする責任はTLSにあります。QUICは、 順不同で到着したハンドシェイクバイト、またはまだ準備ができていない暗号化レベルの ハンドシェイクバイトをバッファリングする責任があります。QUICは CRYPTOフレームに対するフロー制御の手段を提供しません。 [QUIC-TRANSPORT]のセクション7.5を参照してください。

TLSハンドシェイクが完了すると、TLSが送信する必要のある 最終的なハンドシェイクバイトとともに、そのことがQUICに通知されます。この段階で、ハンドシェイク中に ピアが広告したトランスポートパラメーターは認証済みです。 セクション8.2を参照してください。

ハンドシェイクが完了すると、TLSは受動的になります。TLSは引き続き ピアからデータを受信し、それに応答できますが、 アプリケーションまたはQUICから明示的に要求されない限り、それ以上データを送信する必要はありません。 データを送信する理由の1つとして、サーバーが追加または更新されたセッション チケットをクライアントに提供したい場合があります。

ハンドシェイクが完了すると、QUICはCRYPTOストリームに 到着したデータだけをTLSに提供すればよくなります。 ハンドシェイク中と同じ方法で、受信データを提供した後にTLSから新しいデータを要求します。

4.1.4. 暗号化レベルの 変更

特定の暗号化レベルの鍵がTLSで利用可能になると、TLSは その暗号化レベルの読み取り鍵または書き込み鍵が利用可能であることを QUICに通知します。

新しい鍵が利用可能になるのは、常にTLSへ入力を提供した 結果です。TLSは、 (クライアントによって)初期化された後、または新しいハンドシェイクデータが提供されたときにのみ新しい鍵を提供します。

ただし、TLS実装は一部の処理を 非同期で実行する場合があります。特に、証明書を検証する処理には 時間がかかる場合があります。TLS処理の完了を待っている間、エンドポイントは、 まだ利用できない鍵を使用して処理できる可能性がある受信パケットを バッファリングするSHOULD。これらのパケットは、TLSから鍵が提供された時点で処理できます。 エンドポイントは、この 期間中に処理可能なパケットへの応答を続けるSHOULD。

入力を処理した後、TLSはハンドシェイクバイト、新しい 暗号化レベル用の鍵、またはその両方を生成する場合があります。

新しい暗号化レベルが 利用可能になると、TLSはQUICに3つの項目を提供します。

  • シークレット
  • Associated Data付き認証暗号 (AEAD)関数
  • 鍵導出関数(KDF)

これらの値はTLSがネゴシエートした値に基づき、QUICが パケットおよびヘッダー保護鍵を生成するために使用します。セクション5および セクション5.4を参照してください。

0-RTTが可能な場合、クライアントがTLS ClientHello メッセージを送信した後、またはサーバーがそのメッセージを受信した後に準備が整います。QUICクライアントに 最初のハンドシェイクバイトを提供した後、TLSスタックは0-RTT 鍵への変更を通知する場合があります。サーバーでは、ClientHello メッセージを含むハンドシェイクバイトを受信した後、TLSサーバーは0-RTT鍵が利用可能であることを通知する場合があります。

TLSは一度に1つの暗号化レベルしか使用しませんが、QUICは 複数のレベルを使用する場合があります。たとえば、Finishedメッセージを送信した後(Handshake 暗号化レベルのCRYPTO フレームを使用)、エンドポイントはSTREAMデータ(1-RTT暗号化)を送信できます。 Finishedメッセージが失われた場合、エンドポイントは Handshake暗号化レベルを使用して失われたメッセージを再送します。パケットの並べ替えや損失により、 QUICが複数の暗号化 レベルのパケットを処理する必要が生じる場合があります。ハンドシェイク中、これはTLSが現在使用している暗号化レベルより 高いレベルおよび低いレベルのパケットを処理する可能性があることを意味します。

特に、サーバー実装は、 0-RTT暗号化レベルと同時にHandshake暗号化レベルのパケットを読み取れる必要があります。 クライアントはHandshake鍵で保護されたACKフレームを 0-RTTデータの間に挟んで送信することがあり、サーバーは失われたHandshakeパケットを 検出するために、それらの確認応答を処理する必要があります。

QUICはまた、TLS 実装では通常利用できない可能性がある鍵にもアクセスする必要があります。たとえば、クライアントはその暗号化レベルで CRYPTOフレームを送信する準備が整う前に、Handshake パケットへの確認応答を行う必要がある場合があります。したがってTLSは、 自身で使用するために鍵を生成するより前に、それらの鍵をQUICに提供する必要があります。

4.1.5. TLSインターフェイスの 概要

図5は、クライアントとサーバーの両方について QUICとTLS間のやり取りを要約したものです。実線の矢印はハンドシェイクデータを伝送するパケットを示し、 破線の矢印はアプリケーションデータを送信できる箇所を示します。各矢印には、 その送信で使用される暗号化レベルが付されています。

クライアント                                              サーバー
============                                              ======

ハンドシェイク取得
                     Initial ------------->
送信0-RTT鍵をインストール
                     0-RTT - - - - - - - ->

                                          ハンドシェイク受信
                                             ハンドシェイク取得
                     <------------- Initial
                                      受信0-RTT鍵をインストール
                                 Handshake鍵をインストール
                                             ハンドシェイク取得
                     <----------- Handshake
                                     送信1-RTT鍵をインストール
                     <- - - - - - - - 1-RTT

ハンドシェイク受信(Initial)
Handshake鍵をインストール
ハンドシェイク受信(Handshake)
ハンドシェイク取得
                     Handshake ----------->
ハンドシェイク完了
1-RTT鍵をインストール
                     1-RTT - - - - - - - ->

                                          ハンドシェイク受信
                                          ハンドシェイク完了
                                          ハンドシェイク確認済み
                                     受信1-RTT鍵をインストール
                     <--------------- 1-RTT
                           (HANDSHAKE_DONE)
ハンドシェイク確認済み
図5: QUICとTLS間の 相互作用の概要

図5では、単一の「フライト」を構成する 複数のメッセージのパケットを個別に処理して、 どの受信メッセージが異なる動作を引き起こすかを示しています。異なる暗号化レベルで ハンドシェイクメッセージを取得するため、「ハンドシェイク取得」が複数回呼び出されています。新しいハンドシェイクメッセージは、 受信パケットの処理後に要求されます。

図5は、単純なハンドシェイク 交換の可能な構造の1つを示しています。正確な処理は、エンドポイント 実装の構造とパケットが到着する順序によって異なります。実装は、 異なる数の操作を使用したり、それらを別の順序で実行したりできます。

4.2. TLSバージョン

この文書では、TLS 1.3 [TLS13]をQUICとともに使用する方法について説明します。

実際には、TLSハンドシェイクによって使用するTLSのバージョンがネゴシエートされます。 両方のエンドポイントが対応している場合、TLS 1.3より新しいバージョンのTLSが ネゴシエートされる可能性があります。QUICが使用するTLS 1.3の機能が 新しいバージョンでもサポートされている限り、これは許容されます。

クライアントはTLS 1.3より古いTLSバージョンを提示してはMUST NOT。 誤って構成されたTLS 実装では、TLS 1.2または別の古いTLSバージョンがネゴシエートされる可能性があります。 TLS 1.3より古いTLSバージョンがネゴシエートされた場合、エンドポイントは 接続を終了MUST。

4.3. ClientHelloのサイズ

クライアントからの最初のInitialパケットには、その最初の 暗号学的ハンドシェイクメッセージの先頭または全体が含まれます。TLSの場合、これはClientHelloです。サーバーは、 新しい着信QUIC接続を受け入れるかどうかを判断するために、 ClientHello全体を解析する必要がある場合があります(たとえば、 Server Name Identification (SNI)やApplication-Layer Protocol Negotiation (ALPN)などの拡張へアクセスするため)。 ClientHelloが複数のInitialパケットにまたがる場合、そのようなサーバーは 最初に受信した断片をバッファリングする必要があり、クライアントのアドレスがまだ検証されていない場合には 過剰なリソースを消費する可能性があります。これを避けるため、サーバーは、 検証済みアドレスを持つクライアントからの 部分的なClientHelloメッセージだけをバッファリングするよう、Retry機能( [QUIC-TRANSPORT]のセクション8.1を参照)を使用するMAY。

QUICパケットおよびフレーミングは、ClientHello メッセージに少なくとも36バイトのオーバーヘッドを追加します。クライアントが0バイトより長いSource Connection ID フィールドを選択した場合、このオーバーヘッドは増加します。オーバーヘッドには、トークンや 8バイトより長いDestination Connection IDも含まれていません。これらはいずれも、 サーバーがRetryパケットを送信する場合に必要になる可能性があります。

典型的なTLS ClientHelloは、1200バイトのパケットに容易に収まります。ただし、 QUICによって追加されるオーバーヘッドに加えて、この制限を 超える可能性のある変数がいくつかあります。大きなセッションチケット、複数または大きな鍵 共有、およびサポートされる暗号、署名アルゴリズム、バージョン、 QUICトランスポートパラメーター、その他のネゴシエート可能なパラメーターや拡張の長いリストによって、 このメッセージが大きくなる可能性があります。

サーバーについては、接続IDおよびトークンに加えて、TLSセッション チケットのサイズもクライアントが効率的に接続できるかどうかに影響します。 これらの値のサイズを最小化すると、クライアントがそれらを使用しながら ClientHelloメッセージ全体を最初のInitial パケットに収められる可能性が高まります。

TLS実装は、Initialパケットを伝送するデータグラムに対する QUICの要件を満たすほどClientHelloが大きいことを保証する必要はありません。 [QUIC-TRANSPORT]のセクション14.1を参照してください。QUIC 実装はPADDINGフレームまたは パケット結合を使用して、データグラムが十分に大きくなるようにします。

4.4. ピア認証

認証の要件は、 使用されているアプリケーションプロトコルによって異なります。TLSはサーバー認証を提供し、サーバーが クライアント認証を要求することを許可します。

クライアントはサーバーのIDを認証MUST。通常、これには、 サーバーのIDが証明書に含まれており、 その証明書が信頼されたエンティティによって発行されていることの検証が含まれます(たとえば [RFC2818]を参照)。

サーバーは、ハンドシェイク中にクライアントへ認証を要求するMAY。 要求されたときにクライアントが認証できない場合、サーバーは 接続を拒否するMAY。 クライアント認証の要件は、アプリケーションプロトコル およびデプロイメントによって異なります。

サーバーは、ハンドシェイク後のクライアント 認証([TLS13]のセクション4.6.2で定義)を使用してはMUST NOT。これは、QUICが提供する多重化により、 クライアントが証明書要求と、それを引き起こしたアプリケーションレベルの イベントを関連付けられないためです([HTTP2-TLS13]を参照)。より具体的には、 サーバーはハンドシェイク後にTLS CertificateRequestメッセージを送信してはMUST NOT。 また、 クライアントはそのようなメッセージの受信を PROTOCOL_VIOLATIONタイプの接続エラーとして扱うMUST。

4.5. セッション再開

QUICはTLS 1.3のセッション再開機能を使用できます。これは、 ハンドシェイクの完了後にCRYPTOフレームでNewSessionTicketメッセージを 伝送することで行われます。セッション再開は0-RTTを提供するために使用でき、 0-RTTが無効な場合にも使用できます。

セッション再開を使用するエンドポイントは、再開された接続を作成するときに 現在の接続に関する一部の情報を記憶しておく必要がある場合があります。TLSでは、 一部の情報を保持する必要があります。 [TLS13]のセクション4.6.1を参照してください。QUIC自体は、 0-RTTも使用される場合を除き、接続再開時に状態が保持されることには 依存しません。[QUIC-TRANSPORT]のセクション7.4.1および セクション4.6.1を参照してください。アプリケーションプロトコルは、 再開された接続間で保持される状態に依存する場合があります。

クライアントは、再開に必要な任意の状態をセッション チケットとともに保存できます。サーバーは、状態の伝送を補助するためにセッションチケットを使用できます。

セッション再開により、サーバーは元の接続上の活動と 再開された接続を関連付けることができます。これはクライアントにとってプライバシー上の問題となる可能性があります。 クライアントは、この相関を作らないために再開を有効にしないことを選択できます。 クライアントはチケットを再利用するべきではSHOULD NOT。再利用するとサーバー以外のエンティティが 接続を関連付けられるためです。 [TLS13]の付録C.4を参照してください。

4.6. 0-RTT

QUICの0-RTT機能により、クライアントは ハンドシェイクが完了する前にアプリケーションデータを送信できます。これは、 以前の接続でネゴシエートされたパラメーターを再利用することで可能になります。これを有効にするため、0-RTTは クライアントが重要なパラメーターを記憶し、サーバーが同じ情報を 復元できるTLSセッションチケットをサーバーへ提供することに依存します。

この情報には、[TLS13]によって規定されるTLS状態を決定するパラメーター、QUICトランスポートパラメーター、 選択されたアプリケーションプロトコル、および アプリケーションプロトコルが必要とする可能性のある任意の情報が含まれます。セクション 4.6.3を参照してください。この 情報によって、0-RTTパケットとその内容がどのように形成されるかが決まります。

両方のエンドポイントで同じ情報を利用できるようにするため、 0-RTTの確立に使用されるすべての情報は同一の接続から取得されます。エンドポイントは、 0-RTTの送信または処理を変更する可能性がある情報を 選択的に無視することはできません。

[TLS13]は、元の 接続から0-RTTを使用しようとするまでの期間に7日間の制限を設けています。0-RTTの 使用には他にも制約があり、特にリプレイ攻撃にさらされる可能性による制約があります。 セクション9.2を参照してください。

4.6.1. 0-RTTの有効化

NewSessionTicketメッセージ内のTLS early_data拡張は、 サーバーが受け入れる意思のあるTLS 0-RTTデータ量を (max_early_data_sizeパラメーターで)伝達するものとして定義されています。QUICはTLS early dataを使用しません。QUICは 0-RTTパケットを使用してearly dataを伝送します。したがって、max_early_data_sizeパラメーターは、 サーバーがQUIC 0-RTTデータを受け入れる意思があることを示すセンチネル値0xffffffffを 保持するために転用されます。サーバーが0-RTTデータを受け入れないことを示すには、 NewSessionTicketからearly_data拡張を省略します。 クライアントがQUIC 0-RTTで送信できるデータ量は、 サーバーから提供されるinitial_max_dataトランスポートパラメーターによって制御されます。

サーバーは、max_early_data_sizeフィールドが 0xffffffff以外の値に設定されたearly_data拡張を送信してはMUST NOT。 クライアントは、その他の値を持つearly_data拡張を含む NewSessionTicketを受信した場合、 PROTOCOL_VIOLATIONタイプの接続エラーとして扱うMUST。

0-RTTパケットを送信しようとするクライアントは、 後続のハンドシェイクのClientHelloメッセージでearly_data拡張を使用します。 [TLS13]のセクション4.2.10を参照してください。 その後、0-RTTパケットでアプリケーションデータを送信します。

0-RTTを試みるクライアントは、 サーバーがNEW_TOKENフレームを送信している場合、アドレス検証トークンも提供することがあります。 [QUIC-TRANSPORT]のセクション8.1を参照してください。

4.6.2. 0-RTTの受け入れと 拒否

サーバーは、EncryptedExtensions内でearly_data拡張を送信することで 0-RTTを受け入れます。 [TLS13]のセクション4.2.10を参照してください。その後、サーバーは 受信した0-RTTパケットを処理し、確認応答します。

サーバーは、early_data 拡張を含まないEncryptedExtensionsを送信することで0-RTTを拒否します。TLS HelloRetryRequestを送信した場合、サーバーは常に0-RTTを拒否します。0-RTTを拒否する場合、サーバーは 処理可能であったとしても0-RTT パケットを処理してはMUST NOT。0-RTTが拒否された場合、クライアントは、 その状態を検出できるなら、0-RTTパケットに対する確認応答の受信を PROTOCOL_VIOLATIONタイプの接続エラーとして扱うSHOULD。

0-RTTが拒否された場合、クライアントが想定していたすべての接続特性が 不正確である可能性があります。これには、アプリケーションプロトコルの選択、トランスポート パラメーター、およびあらゆるアプリケーション構成が含まれます。したがってクライアントは、 それらのストリームに関連付けられたアプリケーション状態を含む、すべてのストリームの状態をリセットMUST。

RetryまたはVersion Negotiation パケットを受信した場合、クライアントは0-RTTを再試行するMAY。これらのパケットは0-RTTの拒否を意味しません。

4.6.3. 0-RTT構成の 検証

サーバーがearly_data拡張を含むClientHelloを受信すると、 クライアントからの0-RTTデータを受け入れるか拒否するかを 決定する必要があります。この決定の一部はTLSスタックによって行われます(たとえば、再開される暗号スイートが ClientHelloに含まれていたことの確認。 [TLS13]のセクション4.2.10を参照)。TLSスタックに 0-RTTデータを拒否する理由がない場合でも、再開された セッションに関連付けられたトランスポートまたはアプリケーションの構成がサーバーの現在の構成と互換性がなければ、 QUICスタックまたはQUICを使用する アプリケーションプロトコルが0-RTTデータを拒否する可能性があります。

QUICでは、追加のトランスポート状態を 0-RTTセッションチケットに関連付ける必要があります。これを実装する一般的な方法の1つは、 ステートレスセッションチケットを使用し、この状態をセッションチケットに保存することです。QUICを使用する アプリケーションプロトコルにも、状態の関連付けまたは保存に関して同様の要件がある場合があります。この 関連付けられた状態は、0-RTTデータを拒否する必要があるかどうかを判断するために使用されます。たとえば、 HTTP/3設定[QUIC-HTTP]は、 クライアントからの0-RTTデータがどのように解釈されるかを決定します。QUICを使用する他のアプリケーションには、 0-RTTデータを受け入れるか拒否するかを決定するための異なる 要件がある場合があります。

4.7. HelloRetryRequest

HelloRetryRequestメッセージ( [TLS13]のセクション4.1.4を参照)は、 クライアントに鍵共有などの新しい情報を提供するよう要求したり、 クライアントの特性を検証したりするために使用できます。QUICの観点では、 HelloRetryRequestはInitialパケットで伝送される他の暗号学的ハンドシェイク メッセージと区別されません。原理上は この機能をアドレス検証に使用できますが、QUIC実装は 代わりにRetry機能を使用するSHOULD。 [QUIC-TRANSPORT]のセクション8.1を参照してください。

4.8. TLSエラー

TLSでエラーが発生した場合、 [TLS13]のセクション6で定義されている適切なアラートを生成します。

TLSアラートはQUIC接続エラーに変換されます。AlertDescription 値に 0x0100を加えて、CRYPTO_ERROR用に予約された範囲のQUICエラーコードを生成します。 [QUIC-TRANSPORT]のセクション20.1を参照してください。生成された値は、 タイプ0x1cのQUIC CONNECTION_CLOSEフレームで送信されます。

QUICが伝達できるアラートレベルは「fatal」のみです。TLS 1.3では、 「warning」レベルの既存の用途は接続終了を通知することだけです。 [TLS13]のセクション6.1を参照してください。QUICは 接続終了のための別のメカニズムを提供しており、TLS接続はエラーが 発生した場合にのみ閉じられるため、QUICエンドポイントはTLSからの任意のアラートを 「fatal」レベルであるかのように扱うMUST。

QUICでは、特定のエラーコードの代わりに汎用コードを使用できます。 [QUIC-TRANSPORT]のセクション11を参照してください。TLSアラートの場合、これには任意の アラートをhandshake_failure(QUICでは0x0128)などの汎用アラートに置き換えることが含まれます。 エンドポイントは、機密 情報が露出する可能性を避けるために汎用エラーコードを使用するMAY。

4.9. 未使用の鍵の破棄

QUICが新しい暗号化レベルへの移行を完了すると、以前の暗号化レベル用の パケット保護鍵を破棄できます。これは ハンドシェイク中に数回発生し、鍵の更新時にも発生します。セクション6を参照してください。

新しい鍵が 利用可能になっても、パケット保護鍵は直ちには破棄されません。低い暗号化レベルのパケットにCRYPTOフレームが含まれている場合、 そのデータを再送するフレームは同じ暗号化 レベルで送信MUST。 同様に、エンドポイントは確認対象のパケットと同じ 暗号化レベルでパケットの確認応答を生成します。したがって、 新しい暗号化レベル用の鍵が利用可能になった後も、短時間は低い暗号化レベル用の鍵が 必要になる可能性があります。

エンドポイントは、特定の暗号化レベルについて、 その暗号化レベルのピアからすべての暗号学的ハンドシェイクメッセージを受信し、 ピアも同様に受信したことが確認できるまで鍵を破棄できません。これを判定するために、 Initial鍵(セクション4.9.1)と Handshake鍵(セクション4.9.2)には異なる方法が用意されています。これらの方法は、 ピアが必要な確認応答をすべて受信していない可能性があるため、 その暗号化レベルでのパケットの受信または送信を防ぐものではありません。

エンドポイントが古い鍵を保持している場合でも、新しいデータは、 現在利用可能な最も高い暗号化レベルで送信MUST。 以前の暗号化レベルでは、ACKフレームと CRYPTOフレーム内のデータの再送のみが送信されます。これらのパケットには PADDINGフレームを含めるMAY。

4.9.1. Initial 鍵の破棄

Initialシークレット(セクション5.2)で保護されたパケットは 認証されていません。つまり、攻撃者が接続を妨害する目的で パケットを偽装できる可能性があります。これらの攻撃を制限するため、Initialパケット保護鍵は 他の鍵より積極的に破棄されます。

Handshakeパケットの使用に成功したことは、それ以上 Initialパケットを交換する必要がないことを示します。これらの鍵は、 InitialパケットからすべてのCRYPTOフレームを受信した後でのみ生成できるためです。 したがって、クライアントは最初にHandshakeパケットを送信したときに Initial鍵を破棄MUSTし、 サーバーは最初にHandshakeパケットを正常に処理したときに Initial鍵を破棄MUST。 エンドポイントは、この時点以降Initialパケットを送信してはMUST NOT。

その結果、Initial 暗号化レベルの損失回復状態は破棄され、 未解決のInitialパケットはすべて無視されます。

4.9.2. Handshake 鍵の破棄

エンドポイントは、TLSハンドシェイクが確認済みになったとき (セクション4.1.2)にHandshake 鍵を破棄MUST。

4.9.3. 0-RTT 鍵の破棄

0-RTTパケットと1-RTTパケットは同じパケット番号空間を共有し、 クライアントは 1-RTTパケットを送信した後は0-RTTパケットを送信しません(セクション5.6)。

したがって、クライアントは1-RTT 鍵をインストールした時点で0-RTT鍵を破棄するSHOULD。その時点以降、それらには用途がないためです。

さらに、サーバーは1-RTT パケットを受信した時点で0-RTT鍵を破棄するMAY。 ただし、パケットの並べ替えにより、0-RTTパケットが 1-RTTパケットの後に到着する可能性があります。サーバーは、並べ替えられたパケットを、 その内容を1-RTT鍵で再送することなく復号できるようにするため、 0-RTT鍵を一時的に保持するMAY。 1-RTTパケットを受信した後、サーバーは 短時間以内に0-RTT鍵を破棄MUST。 RECOMMENDED期間はProbe Timeoutの3倍です(PTO、[QUIC-RECOVERY]を参照)。サーバーは、 すべての0-RTTパケットを受信したと判断した場合、 0-RTT鍵をより早く破棄するMAY。これは欠落したパケット番号を追跡することで 実行できます。

5. パケット保護

TCP上のTLSと同様に、QUICはTLSによってネゴシエートされた AEADアルゴリズム[AEAD]を使用し、TLS ハンドシェイクから導出された鍵でパケットを保護します。

QUICパケットの保護は、そのタイプによって異なります。

このセクションでは、Handshakeパケット、 0-RTTパケット、および1-RTTパケットにパケット保護を適用する方法について説明します。同じパケット保護処理が Initialパケットにも適用されます。ただし、 Initialパケットに使用される鍵は容易に特定できるため、これらのパケットには機密性または 完全性の保護があるとはみなされません。Retryパケットは固定鍵を使用するため、同様に 機密性と完全性の保護を欠いています。

5.1. パケット保護鍵

QUICは、TLSがレコード 保護鍵を導出するのと同じ方法でパケット保護鍵を導出します。

各暗号化レベルには、それぞれの方向に送信されるパケットを保護するための 個別のシークレット値があります。これらのトラフィックシークレットはTLSによって導出され( [TLS13]のセクション7.1を参照)、 Initial 暗号化レベルを除くすべての暗号化レベルでQUICによって使用されます。Initial暗号化レベル用のシークレットは、 セクション5.2で説明するように、クライアントの初期Destination Connection IDに 基づいて計算されます。

パケット保護に使用される鍵は、TLSが提供する KDFを使用してTLSシークレットから計算されます。TLS 1.3では、 [TLS13]のセクション7.1で説明されているHKDF-Expand-Label関数を、 ネゴシエートされた暗号スイートのハッシュ 関数とともに使用します。QUICにおけるHKDF-Expand-Labelのすべての使用では、長さ0のContextを使用します。

文字列として記述されるラベルは、 引用符や末尾のNUL バイトを付けず、ASCII[ASCII]を使用してバイトとしてエンコードされることに注意してください。

他のTLSバージョンは、QUICとともに 使用できるようにするため、同様の関数を提供MUST。

現在の暗号化レベルのシークレットとラベル"quic key"を KDFへの入力としてAEAD鍵を生成します。ラベル"quic iv"は Initialization Vector (IV)の導出に使用されます。セクション5.3を参照してください。ヘッダー 保護鍵には "quic hp"ラベルを使用します。セクション5.4を参照してください。これらのラベルを使用することで、 QUICとTLSの間で鍵を分離できます。セクション9.6を参照してください。

"quic key"と"quic hp"はいずれも鍵の生成に使用されるため、 これらのラベルとともにHKDF-Expand-Labelへ与えられるLengthは、 AEADまたはヘッダー保護アルゴリズムの鍵サイズによって決まります。"quic iv"とともに与えられるLengthは、 AEAD nonceの最小長、またはそれより大きい場合は8バイトです。 [AEAD]を参照してください。

Initialシークレットに使用するKDFは、常に TLS 1.3のHKDF-Expand-Label関数です。セクション5.2を参照してください。

5.2. Initialシークレット

Initialパケットにはパケット保護処理を適用しますが、 クライアントの最初のInitial パケットのDestination Connection IDフィールドから導出したシークレットを使用します。

このシークレットは、ソルトとして0x38762cf7f55934b34d179ae6a4c80cadccbb7f0a、 入力鍵素材(IKM)としてDestination Connection IDフィールドを使用して HKDF-Extract( [HKDF]のセクション2.2を参照)を実行することで決定されます。これにより、 送信用と受信用の2つの別個のシークレットを導出するために使用される 中間擬似乱数鍵(PRK)が生成されます。

クライアントがInitialパケットを構築するために使用するシークレットは、 TLSのHKDF-Expand-Label関数にPRKと ラベル"client in"を入力し、 [TLS13]に従って32バイトのシークレットを生成します。サーバーが構築するパケットでは、 ラベル"server in"を使用して同じ処理を行います。Initialシークレットおよび鍵を 導出する際のHKDFのハッシュ関数はSHA-256 [SHA]です。

この処理を擬似コードで表すと次のようになります。

initial_salt = 0x38762cf7f55934b34d179ae6a4c80cadccbb7f0a
initial_secret = HKDF-Extract(initial_salt,
                              client_dst_connection_id)

client_initial_secret = HKDF-Expand-Label(initial_secret,
                                          "client in", "",
                                          Hash.length)
server_initial_secret = HKDF-Expand-Label(initial_secret,
                                          "server in", "",
                                          Hash.length)

HKDF-Expand-Labelで使用される接続IDは、クライアントが送信したInitialパケット内の Destination Connection IDです。クライアントがRetry パケットの受信後にInitialパケットを作成する場合を除き、これはランダムに選択された 値になります。Retryパケットの受信後は、Destination Connection IDはサーバーによって選択されます。

将来のQUICバージョンでは新しいソルト 値を生成し、それによってQUICの各バージョンで 鍵が異なることを保証するSHOULD。これにより、1つのQUICバージョンだけを認識するミドルボックスが、 将来のバージョンのパケット内容を閲覧または変更することを防ぎます。

TLS 1.3で定義されたHKDF-Expand-Label関数は、提示されるTLSバージョンに TLS 1.3が含まれていない場合でも、Initial パケットに使用MUST。

後続のInitialパケットを構築するために使用されるシークレットは、 サーバーがRetryパケットを送信した際に、サーバーが選択した接続ID値を使用するよう変更されます。 クライアントがサーバーからのInitialパケットへの応答として使用するDestination Connection IDを変更しても、シークレットは変更されません。

付録AにはInitial パケットの例が含まれています。

5.3. AEADの使用

QUICパケット保護に使用されるAuthenticated Encryption with Associated Data (AEAD)関数([AEAD]を参照)は、 TLS接続で使用するためにネゴシエートされたAEADです。たとえば、TLSが TLS_AES_128_GCM_SHA256暗号スイートを使用している場合、AEAD_AES_128_GCM関数を使用します。

QUICは、TLS_AES_128_CCM_8_SHA256を除き、 [TLS13]で定義されている任意の暗号スイートを使用できます。 暗号スイートに対するヘッダー保護方式が定義されていない限り、 その暗号スイートをネゴシエートしてはMUST NOT。 この文書では、TLS_AES_128_CCM_8_SHA256を除く [TLS13]で定義されているすべての暗号スイートに対するヘッダー保護方式を定義します。 これらの暗号スイートは16バイトの 認証タグを持ち、入力より16バイト大きい出力を生成します。

エンドポイントは、 サポートしていない暗号スイートを提示するClientHelloを拒否してはMUST NOT。 そうすると新しい暗号スイートをデプロイできなくなるためです。これは TLS_AES_128_CCM_8_SHA256にも適用されます。

パケットを構築する際、AEAD関数は ヘッダー保護を適用する前に適用されます。セクション5.4を参照してください。保護されていない パケットヘッダーはassociated data (A)の一部です。パケットを処理する際、 エンドポイントは最初にヘッダー保護を解除します。

パケット用の鍵とIVは、セクション5.1で説明するように計算されます。 nonce Nは、パケット保護IVとパケット 番号を組み合わせて形成されます。再構築されたQUICパケット番号の62ビットは、ネットワークバイト オーダーで、IVのサイズになるまで左側をゼロで埋めます。パディングされた パケット番号とIVの排他的ORによってAEAD nonceが形成されます。

AEADのassociated data Aは、QUICヘッダーの内容であり、 ショートヘッダーまたはロングヘッダーの最初のバイトから始まり、 保護されていないパケット番号を含む位置までです。

AEADへの入力平文Pは、 [QUIC-TRANSPORT]で説明されているQUICパケットのペイロードです。

AEADの出力暗号文Cは、Pの代わりに送信されます。

一部のAEAD関数には、同じ鍵とIVで 暗号化できるパケット数に制限があります。セクション6.6を参照してください。これはパケット 番号の上限より低い場合があります。エンドポイントは、使用中のAEADに設定された 制限を超える前に鍵更新(セクション6)を開始MUST。

5.4. ヘッダー保護

QUICパケットヘッダーの一部、特にPacket Numberフィールドは、 パケット保護鍵およびIVとは別に導出された鍵を使用して 保護されます。"quic hp"ラベルを使用して導出された鍵は、 経路上の要素に公開されないフィールドに 機密性保護を提供するために使用されます。

この保護は、最初のバイトの最下位ビットと Packet Numberフィールドに適用されます。ロングヘッダーを持つパケットでは最初のバイトの最下位4ビットが 保護され、ショートヘッダーを持つパケットでは最初のバイトの最下位5ビットが保護されます。どちらのヘッダー形式でも、 これには予約ビットとPacket Number Lengthフィールドが含まれます。ショートヘッダーを持つパケットでは Key Phaseビットも保護されます。

同じヘッダー保護鍵が接続の存続期間中使用され、 鍵更新後も値は変更されません(セクション6を参照)。これにより、 鍵フェーズを保護するためにヘッダー保護を使用できます。

この処理はRetryまたはVersion Negotiationパケットには適用されません。これらには、 保護されたペイロードも、この 処理によって保護されるフィールドも含まれていないためです。

5.4.1. ヘッダー 保護の適用

ヘッダー保護は、パケット保護が適用された後に適用されます( セクション5.3を参照)。 パケットの暗号文からサンプルを取得し、暗号化 アルゴリズムへの入力として使用します。使用するアルゴリズムは、ネゴシエートされたAEADによって異なります。

このアルゴリズムの出力は5バイトのマスクであり、排他的ORを使用して 保護対象の ヘッダーフィールドに適用されます。パケットの最初のバイトの最下位ビットは、 最初のマスクバイトの最下位ビットによってマスクされ、 パケット番号は残りのバイトによってマスクされます。パケット番号のエンコードが短いために 未使用となるマスクのバイトは使用されません。

図6は、ヘッダー保護を適用するアルゴリズムの例を 示しています。ヘッダー保護の解除では、 パケット番号長(pn_length)を決定する順序だけが異なります(ここでは"^"は排他的ORを表します)。

mask = header_protection(hp_key, sample)

pn_length = (packet[0] & 0x03) + 1
if (packet[0] & 0x80) == 0x80:
   # ロングヘッダー: 4ビットをマスク
   packet[0] ^= mask[0] & 0x0f
else:
   # ショートヘッダー: 5ビットをマスク
   packet[0] ^= mask[0] & 0x1f

# pn_offsetはPacket Numberフィールドの開始位置。
packet[pn_offset:pn_offset+pn_length] ^= mask[1:1+pn_length]
図6: ヘッダー保護の 擬似コード

具体的なヘッダー保護関数は、選択された暗号 スイートに基づいて定義されます。セクション5.4.3およびセクション5.4.4を参照してください。

図7は、ロングヘッダーパケット(Initial)とショートヘッダー パケット(1-RTT)の例を示しています。図7は、各 ヘッダーのうちヘッダー保護の対象となるフィールドと、サンプリングされる 保護済みパケットペイロードの部分を示しています。

Initial Packet {
  Header Form (1) = 1,
  Fixed Bit (1) = 1,
  Long Packet Type (2) = 0,
  Reserved Bits (2),         # 保護対象
  Packet Number Length (2),  # 保護対象
  Version (32),
  DCID Len (8),
  Destination Connection ID (0..160),
  SCID Len (8),
  Source Connection ID (0..160),
  Token Length (i),
  Token (..),
  Length (i),
  Packet Number (8..32),     # 保護対象
  Protected Payload (0..24), # スキップする部分
  Protected Payload (128),   # サンプリングする部分
  Protected Payload (..)     # 残り
}

1-RTT Packet {
  Header Form (1) = 0,
  Fixed Bit (1) = 1,
  Spin Bit (1),
  Reserved Bits (2),         # 保護対象
  Key Phase (1),             # 保護対象
  Packet Number Length (2),  # 保護対象
  Destination Connection ID (0..160),
  Packet Number (8..32),     # 保護対象
  Protected Payload (0..24), # スキップする部分
  Protected Payload (128),   # サンプリングする部分
  Protected Payload (..),    # 残り
}
図7: ヘッダー保護 と暗号文サンプル

TLS暗号スイートをQUICとともに使用できるようにする前に、 その暗号スイートで使用されるAEADに対してヘッダー保護 アルゴリズムを規定MUST。 この文書では、AEAD_AES_128_GCM、AEAD_AES_128_CCM、AEAD_AES_256_GCM(これらの AES AEADはすべて[AEAD]で定義)、 およびAEAD_CHACHA20_POLY1305 ([CHACHA]で定義)のアルゴリズムを定義します。TLSが暗号スイートを 選択する前は、AEAD_AES_128_GCMパケット 保護に対応するAESヘッダー保護(セクション5.4.3)を使用します。

5.4.2. ヘッダー保護 サンプル

ヘッダー保護アルゴリズムは、ヘッダー保護鍵と、 パケットのPayloadフィールドから取得した暗号文のサンプルの両方を使用します。

常に同じバイト数をサンプリングしますが、 受信エンドポイントによる保護解除ではPacket Numberフィールドの 長さが分からないため、それを考慮する必要があります。暗号文のサンプルは、 Packet Numberフィールドの開始位置から4バイト後のオフセットから取得します。つまり、 ヘッダー保護用にパケット暗号文をサンプリングする際には、Packet Numberフィールドの長さを 4バイト(取り得る最大のエンコード長)と仮定します。

エンドポイントは、完全な サンプルを含むのに十分な長さがないパケットを破棄MUST。

サンプリングに十分なデータを確保するため、 エンコードされたパケット番号と保護済みペイロードの合計長が、 ヘッダー保護に必要なサンプルより少なくとも4バイト長くなるよう、パケットをパディングします。 [TLS13]で定義される暗号スイートは、 この文書でヘッダー保護方式が定義されていないTLS_AES_128_CCM_8_SHA256を除き、 16バイトの拡張と16バイトのヘッダー保護サンプルを持ちます。その結果、 パケット番号を1バイトでエンコードする場合は、保護されていないペイロード内に 少なくとも3バイトのフレームが必要となり、2バイトのパケット番号 エンコードの場合は2バイトのフレームが必要となります。

サンプリングする暗号文は、次の 擬似コードで求められます。

# pn_offsetはPacket Numberフィールドの開始位置。
sample_offset = pn_offset + 4

sample = packet[sample_offset..sample_offset+sample_length]

ショートヘッダーパケットのパケット番号オフセットは、 次のように計算できます。

pn_offset = 1 + len(connection_id)

また、ロングヘッダーパケットのパケット番号オフセットは、 次のように計算できます。

pn_offset = 7 + len(destination_connection_id) +
                len(source_connection_id) +
                len(payload_length)
if packet_type == Initial:
    pn_offset += len(token_length) +
                 len(token)

たとえば、ショートヘッダー、8バイトの接続 IDを持ち、 AEAD_AES_128_GCMで保護されたパケットでは、サンプルは13バイト目から28バイト目まで(両端を含む)を取得します (0から始まるインデックスを使用)。

複数のQUICパケットが同じUDPデータグラムに含まれる場合があります。 各パケットは 個別に処理されます。

5.4.3. AESベースの ヘッダー保護

このセクションでは、 AEAD_AES_128_GCM、 AEAD_AES_128_CCM、およびAEAD_AES_256_GCMのパケット保護アルゴリズムを定義します。AEAD_AES_128_GCMとAEAD_AES_128_CCMは、 Electronic Codebook (ECB)モードの128ビットAESを使用します。AEAD_AES_256_GCMは、 ECBモードの256ビットAESを使用します。AESは[AES]で定義されています。

このアルゴリズムは、パケット暗号文から16バイトをサンプリングします。この 値はAES-ECBへの入力として使用されます。擬似コードでは、ヘッダー保護関数は 次のように定義されます。

header_protection(hp_key, sample):
  mask = AES-ECB(hp_key, sample)

5.4.4. ChaCha20ベースの ヘッダー保護

AEAD_CHACHA20_POLY1305を使用する場合、ヘッダー保護では、 [CHACHA]のセクション2.4で定義されている生のChaCha20 関数を使用します。これは256ビット鍵と、 パケット保護出力からサンプリングされた16バイトを使用します。

サンプリングされた暗号文の最初の4バイトはブロックカウンターです。 ChaCha20 実装ではバイト列の代わりに32ビット整数を受け取る場合があり、 その場合、バイト列はリトルエンディアン値として解釈されます。

残りの12バイトはnonceとして使用されます。ChaCha20 実装では、 バイト列の代わりに3つの32ビット整数の配列を受け取る場合があり、その 場合、nonceのバイト列は32ビットのリトルエンディアン 整数列として解釈されます。

暗号化マスクは、5つの ゼロバイトを保護するようChaCha20を呼び出すことで生成されます。擬似コードでは、ヘッダー保護関数は次のように定義されます。

header_protection(hp_key, sample):
  counter = sample[0..3]
  nonce = sample[4..15]
  mask = ChaCha20(hp_key, counter, nonce, {0,0,0,0,0})

5.5. 保護された パケットの受信

エンドポイントが特定のパケット番号を持つパケットを正常に受信した後、 同じパケット番号空間でより大きなパケット 番号を持つパケットが、同じ鍵、または 鍵更新がある場合には後続のパケット保護鍵のいずれを使用しても正常に保護解除できない場合、 それらをすべて破棄MUST。セクション6を参照してください。同様に、鍵更新を引き起こすように見えるが、 正常に保護解除できないパケットも破棄MUST。

パケットの保護解除に失敗しても、必ずしも ピアのプロトコルエラーまたは攻撃の存在を示すわけではありません。QUICで使用される切り詰められたパケット番号 エンコードでは、パケットが大幅に遅延した場合に パケット番号が誤ってデコードされる可能性があります。

5.6. 0-RTT鍵の使用

0-RTT鍵が利用可能な場合(セクション 4.6.1を参照)、リプレイ保護がないため、 プロトコルへのリプレイ攻撃を避けるためにその使用を制限する必要があります。

[QUIC-TRANSPORT]で定義されているフレームのうち、STREAM、RESET_STREAM、 STOP_SENDING、およびCONNECTION_CLOSEフレームは、アプリケーションデータを伝送するため、 0-RTTで使用するには潜在的に安全ではありません。0-RTTで受信したアプリケーションデータにより、 サーバー上のアプリケーションがデータを1回ではなく複数回 処理する可能性があります。リプレイされたアプリケーションデータの処理によってサーバーが行う追加の動作は、 望ましくない結果を引き起こす可能性があります。したがってクライアントは、使用中のアプリケーションから 明示的に要求されない限り、アプリケーションデータに0-RTTを使用してはMUST NOT。

QUICを使用するアプリケーションプロトコルは、 0-RTTの許容される使用方法を定義するプロファイルを含めるMUST。そうでなければ、0-RTTは アプリケーションデータを伝送しないQUICフレームの伝送にのみ使用できます。たとえば、HTTP用のプロファイルは [HTTP-REPLAY]で説明され、HTTP/3で使用されます。 [QUIC-HTTP]のセクション10.9を参照してください。

パケットのリプレイによって追加の接続試行が生じる可能性がありますが、 アプリケーションデータを伝送しないリプレイされたフレームを処理する影響は、 影響を受ける接続の状態を変更することに限られます。TLSハンドシェイクは、 リプレイされたパケットを使用して正常に完了することはできません。

クライアントは、TLSハンドシェイクが完了する前に送信するデータに 追加の制限を適用したい場合があります。

それ以外の場合、クライアントは0-RTT鍵を1-RTT鍵と同等に扱います。ただし、 0-RTT鍵では特定のフレームを送信できません。 [QUIC-TRANSPORT]のセクション12.5を参照してください。

0-RTTデータがサーバーに受け入れられたという通知を受けたクライアントは、 サーバーのすべてのハンドシェイク メッセージを受信するまで0-RTTデータを送信できます。0-RTTデータが拒否されたという通知を受けた場合、 クライアントは0-RTTデータの送信を停止するSHOULD。

サーバーはパケットを保護するために0-RTT鍵を使用してはMUST NOT。 0-RTTパケットへの確認応答を 保護するためには1-RTT鍵を使用します。クライアントは受信した 0-RTTパケットを復号しようとしてはMUST NOT、代わりにそれらを破棄MUST。

クライアントが1-RTT鍵をインストールした後は、それ以上 0-RTTパケットを送信してはMUST NOT。

5.7. 順不同で到着した 保護パケットの受信

並べ替えや損失により、最終的なTLSハンドシェイクメッセージを受信する前に、 保護されたパケットをエンドポイントが受信する可能性があります。クライアントは サーバーからの1-RTTパケットを復号できませんが、サーバーは クライアントからの1-RTTパケットを復号できます。どちらの役割のエンドポイントも、 ハンドシェイクを完了する前にピアからの1-RTTパケットを復号してはMUST NOT。

サーバーはクライアントから最初の ハンドシェイクメッセージを受信した後に1-RTT鍵を利用できますが、クライアントの状態に関する保証が不足しています。

  • サーバーが 事前共有鍵を使用することを選択し、クライアントの事前共有鍵binderを検証していない限り、クライアントは認証されていません。 [TLS13]のセクション4.2.11を参照してください。
  • サーバーがRetryパケットまたはその他の手段で クライアントのアドレスを検証していない限り、クライアントは稼働性を実証していません。 [QUIC-TRANSPORT]のセクション8.1を参照してください。
  • サーバーが応答する受信済み0-RTTデータは、 リプレイ攻撃によるものである可能性があります。

したがって、ハンドシェイクが完了する前にサーバーが1-RTT鍵を使用できるのは、 データの送信に限られます。サーバーは、TLSハンドシェイクが完了する前に受信した 1-RTT保護パケットを処理してはMUST NOT。 確認応答を送信することはパケット内のすべてのフレームが処理済みであることを示すため、サーバーは TLSハンドシェイクが完了するまで1-RTTパケットへの確認応答を送信できません。 1-RTT鍵で保護された受信パケットは保存し、 ハンドシェイク完了後に復号して使用するMAY。

サーバーがクライアントのFinishedメッセージを待つという要件により、 そのメッセージが配信されることへの依存が生じます。クライアントは、 Finishedメッセージを伝送するCRYPTOフレームのコピーを含むHandshakeパケットと 1-RTTパケットを結合して送信し、いずれかのHandshakeパケットが 確認応答されるまで続けることで、これによって生じ得るhead-of-line blockingを回避できます。 これにより、サーバーはそれらのパケットを直ちに処理できます。

サーバーは、TLS ClientHelloを受信する前に0-RTT鍵で保護されたパケットを 受信する可能性があります。サーバーは、 ClientHelloを受信することを見越して、後で復号するためにこれらのパケットを保持するMAY。

クライアントは通常、ハンドシェイクが 完了するのと同時に1-RTT鍵を受け取ります。1-RTTシークレットを持っていたとしても、クライアントは TLSハンドシェイクが完了する前に受信した1-RTT保護パケットを処理してはMUST NOT。

5.8. Retryパケットの完全性

Retryパケット( [QUIC-TRANSPORT]のセクション17.2.5を参照)は、 2つの特性を提供するRetry Integrity Tagを伝送します。これは、ネットワークによって 偶発的に破損したパケットを破棄できるようにし、Initialパケットを観測したエンティティだけが 有効なRetryパケットを送信できるようにします。

Retry Integrity Tagは、次の入力を使用した AEAD_AES_128_GCM[AEAD]の出力として計算される128ビットのフィールドです。

  • シークレット鍵Kは128ビットで、 0xbe0c690b9f66575a1d766b54e368c84eに等しい値です。
  • nonce Nは96ビットで、 0x461599d35d632bf2239825bbに等しい値です。
  • 平文Pは空です。
  • associated data Aは、 図8に示すRetry Pseudo-Packetの内容です。

シークレット鍵とnonceは、 0xd9c9943e6101fd200021506bcc02814c73030f25c79d71ce876eca876e6fca8eを シークレットとして、ラベル"quic key"と"quic iv"を使用してHKDF-Expand-Labelを呼び出すことで導出されます (セクション5.1)。

Retry Pseudo-Packet {
  ODCID Length (8),
  Original Destination Connection ID (0..160),
  Header Form (1) = 1,
  Fixed Bit (1) = 1,
  Long Packet Type (2) = 3,
  Unused (4),
  Version (32),
  DCID Len (8),
  Destination Connection ID (0..160),
  SCID Len (8),
  Source Connection ID (0..160),
  Retry Token (..),
}
図8: Retry Pseudo-Packet

Retry Pseudo-Packetはネットワーク上には送信されません。送信された RetryパケットからRetry Integrity Tagを除去し、 次の2つのフィールドを先頭に付加することで計算されます。

ODCID Length:

ODCID Lengthフィールドには、その後に続く Original Destination Connection IDフィールドの長さをバイト単位で格納し、8ビットの符号なし 整数としてエンコードします。

Original Destination Connection ID:

Original Destination Connection IDには、このRetryが応答しているInitialパケットの Destination Connection IDの値が格納されます。この フィールドの長さはODCID Lengthによって指定されます。このフィールドが存在することにより、 Initialパケットを観測したエンティティだけが有効なRetryパケットを送信できることが 保証されます。

6. 鍵の更新

ハンドシェイクが確認された後(セクション 4.1.2を参照)、エンドポイントは鍵の更新を 開始するMAY。

Key Phaseビットは、パケットの保護にどのパケット保護鍵が使用されているかを示します。 Key Phaseビットは、最初の1-RTT パケットのセットでは最初に0に設定され、その後の各鍵更新を通知するために切り替えられます。

Key Phaseビットにより、受信者は変更を引き起こした最初のパケットを 受信する必要なく、鍵素材の変更を検出できます。変更されたKey Phaseビットを検出した エンドポイントは鍵を更新し、変更された値を含む パケットを復号します。

鍵の更新を開始すると、両方のエンドポイントが鍵を更新します。これは、 エンドポイントが独立して鍵を更新できるTLSとは異なります。

このメカニズムは、1-RTT暗号化鍵を使用して送信される KeyUpdateメッセージに依存するTLSの鍵更新メカニズムを置き換えます。エンドポイントは TLS KeyUpdateメッセージを送信してはMUST NOT。エンドポイントはTLS KeyUpdate メッセージの受信を、unexpected_messageの fatal TLSアラートと同等の、タイプ0x010aの接続エラーとして扱うMUST。 セクション4.8を参照してください。

図9は鍵更新処理を示しています。ここでは、 最初に使用される鍵のセット (@Mで識別)が更新された鍵(@Nで識別)に置き換えられます。 Key Phaseビットの値は角括弧[]内に示されています。

   開始側ピア                         応答側ピア

@M [0] QUICパケット

... @Nへ更新
@N [1] QUICパケット
                      -------->
                                         @Nへ更新 ...
                                      QUICパケット [1] @N
                      <--------
                                      QUICパケット [1] @N
                                    ACKを含む
                      <--------
... 鍵更新が許可される

@N [1] QUICパケット
         @NパケットへのACKを含む
                      -------->
                                 鍵更新が許可される ...
図9: 鍵の更新

6.1. 鍵の更新の 開始

エンドポイントは、パケット保護用に個別の読み取りシークレットと書き込みシークレットを保持します。 エンドポイントは、パケット保護用の書き込みシークレットを更新し、 それを新しいパケットの保護に使用することで鍵の更新を開始します。エンドポイントは、 [TLS13]のセクション7.2で行われるのと同様に、 既存の書き込みシークレットから新しい書き込みシークレットを作成します。これには、 TLSによって提供されるKDF関数を"quic ku"というラベルとともに使用します。対応する 鍵とIVは、セクション5.1で定義されるように、そのシークレットから作成されます。 ヘッダー保護鍵は更新されません。

たとえば、TLS 1.3で書き込み鍵を更新するには、HKDF-Expand-Labelを 次のように使用します。

secret_<n+1> = HKDF-Expand-Label(secret_<n>, "quic ku",
                                 "", Hash.length)

エンドポイントはKey Phaseビットの値を切り替え、更新された鍵と IVを使用して、その後のすべてのパケットを保護します。

エンドポイントは、ハンドシェイクを確認する前に 鍵の更新を開始してはMUST NOT(セクション4.1.2)。 エンドポイントは、現在の鍵フェーズの鍵で保護して送信されたパケットに対する 確認応答を受信していない限り、後続の 鍵更新を開始してはMUST NOT。これにより、次の鍵更新を開始する前に、 両方のピアで鍵が利用可能であることが保証されます。これは、 各鍵フェーズで送信した最小のパケット番号と、 1-RTT空間で確認応答された最大のパケット番号を追跡することで実装できます。後者が 前者以上になれば、次の鍵更新を開始できます。

鍵更新を開始するエンドポイントは、 パケットの受信に使用する鍵も更新します。これらの鍵は、 ピアが更新後に送信するパケットを処理するために必要になります。

エンドポイントは、新しい鍵を使用して送信されたパケットの保護を 正常に解除するまで古い鍵を保持MUST。 エンドポイントは、新しい鍵を使用して送信されたパケットの保護を解除した後も、 しばらくの間古い鍵を保持するSHOULD。 古い鍵を早く破棄しすぎると、遅延したパケットが破棄される可能性があります。パケットの破棄は ピアによってパケット損失として解釈され、性能に悪影響を及ぼす可能性があります。

6.2. 鍵の更新への 応答

ピアは、現在の鍵フェーズのパケットに対する確認応答を受信した後、 鍵の更新を開始できます。エンドポイントは、 最後に送信したパケットの保護に使用した値とは異なる鍵フェーズを持つパケットを 処理するときに鍵更新を検出します。このパケットを処理するため、エンドポイントは次の パケット保護鍵とIVを使用します。これらの鍵を生成する際の考慮事項については、 セクション6.3を参照してください。

次の鍵とIVを使用してパケットが正常に処理された場合、ピアが 鍵更新を開始したことになります。エンドポイントは、応答として送信鍵を 対応する鍵フェーズへ更新MUST。これはセクション6.1で説明されています。 送信鍵は、更新された鍵で受信したパケットに対する確認応答を 送信する前に更新MUST。 鍵更新を引き起こしたパケットを、更新された鍵で保護されたパケット内で確認応答することで、 エンドポイントは鍵更新が完了したことを通知します。

エンドポイントは、通常のパケット送信動作に従ってパケットまたは確認応答の送信を 遅らせることができます。鍵更新に応答して直ちに パケットを生成する必要はありません。エンドポイントが次に送信するパケットでは 更新された鍵を使用します。確認応答を含む次のパケットによって 鍵更新が完了します。エンドポイントが、更新された鍵を使用し、 鍵更新を開始したパケットへの確認応答を含むパケットをまだ一度も送信していないうちに 2回目の更新を検出した場合、これは ピアが確認を待たずに鍵を2回更新したことを示します。エンドポイントは、 このような連続した鍵更新を KEY_UPDATE_ERRORタイプの接続エラーとして扱うMAY。

エンドポイントが、古い鍵で保護されたパケットに含まれる確認応答を受信し、 その確認対象パケットのいずれかが新しい 鍵で保護されていた場合、これをKEY_UPDATE_ERRORタイプの接続エラーとして扱うMAY。 これは、ピアが鍵更新を開始するパケットを受信して確認応答したものの、 応答として鍵を更新していないことを示します。

6.3. 受信鍵 生成のタイミング

見かけ上の鍵更新に応答するエンドポイントは、 Key Phaseビットが無効であったことを示す可能性があるタイミング サイドチャネル信号を生成してはMUST NOT(セクション9.5を参照)。 鍵更新がまだ許可されていない場合、エンドポイントは破棄された鍵の代わりに ランダム化されたパケット保護鍵を使用できます。 ランダム化された鍵を使用することで、パケット保護の解除を試みても タイミングのばらつきが生じないことが保証され、無効なKey Phase ビットを持つパケットは拒否されます。

パケット受信用に新しいパケット保護鍵を作成する処理によって、 鍵更新が発生したことが明らかになる可能性があります。エンドポイントは、パケット処理の 一部として新しい鍵を生成するMAYが、これは攻撃者が 鍵更新がいつ発生するかを知るために利用できるタイミング信号を生み出し、その結果 Key Phaseビットの値が漏れる可能性があります。

一般に、エンドポイントは現在および次の受信パケット 保護鍵を利用可能にしておくことが期待されます。鍵更新が完了した後の短い期間、 最大PTOまで、エンドポイントは次の 受信パケット保護鍵セットの生成を遅らせるMAY。 これにより、エンドポイントは 受信鍵を2セットだけ保持できます。セクション6.5を参照してください。

一度生成された次のパケット保護鍵セットは、 受信したパケットが後で破棄された場合でも保持するSHOULD。 見かけ上の鍵更新を含むパケットは容易に偽造できます。鍵更新処理自体は 大きな労力を必要としませんが、この処理を引き起こすことは 攻撃者によるDoSに利用される可能性があります。

このため、エンドポイントは、パケット受信用に 現在および次の2セットのパケット保護 鍵を保持できるMUST。 これらに加えて以前の鍵を保持すると性能が向上する可能性がありますが、必須ではありません。

6.4. 更新された鍵による 送信

エンドポイントは、古い鍵で保護されたパケットを送信することはありません。 現在の鍵だけが使用されます。パケット保護に使用した鍵は、 新しい鍵へ切り替えた直後に破棄できます。

より大きなパケット番号を持つパケットは、より小さなパケット番号を持つパケットと 同じか、それより新しいパケット保護鍵で 保護MUST。 より小さなパケット番号を持つパケットに新しい鍵が使用されていたにもかかわらず、 古い鍵で正常に保護を解除したエンドポイントは、これを KEY_UPDATE_ERRORタイプの接続エラーとして扱うMUST。

6.5. 異なる鍵による 受信

鍵更新中にパケットを受信する際、古い鍵で保護されたパケットが ネットワークで遅延したために到着する可能性があります。古いパケット 保護鍵を保持しておくことで、これらのパケットを正常に処理できます。

次の鍵フェーズの鍵で保護されたパケットは、 以前の鍵フェーズの鍵で保護されたパケットと同じKey Phase 値を使用するため、古い鍵で保護されたパケットを処理する場合には、 両者を区別する必要があります。これはパケット番号を使用して行えます。復元されたパケット番号が 現在の鍵フェーズのどのパケット番号よりも小さい場合は 以前のパケット保護鍵を使用し、復元されたパケット番号が 現在の鍵フェーズのどのパケット番号よりも大きい場合は、次のパケット 保護鍵を使用する必要があります。

以前、現在、次のパケット保護鍵から選択する 処理が、どの鍵を使用してパケット保護を解除したかを明らかにする可能性があるタイミング サイドチャネルを露出しないよう注意が必要です。詳細については、 セクション9.5を参照してください。

または、エンドポイントはパケット保護鍵を2セットだけ保持し、 ネットワークでの並べ替えを許容するのに十分な時間が経過した後、 以前の鍵を次の鍵と入れ替えることもできます。この場合、Key Phaseビットだけを使用して 鍵を選択できます。

エンドポイントは、次の受信鍵セットを現在の鍵へ昇格させた後、 後続のパケット保護鍵セットを作成するまで、 Probe Timeout(PTO。[QUIC-RECOVERY]を参照)程度の期間を 設けるMAY。 その時点で、これらの更新された 鍵は以前の鍵を置き換えるMAY。PTOは 主観的な尺度である、つまりピアがRTTについて異なる見方を持つ可能性があるという点に注意が必要ですが、 この期間は、並べ替えられたパケットが確認応答されたとしても ピアによって損失と宣言されるのに十分長く、かつ ピアが追加の鍵更新を開始できる程度には短いと想定されています。

エンドポイントは、ピアが古い鍵を保持している期間中、 鍵更新を開始するパケットを復号できない可能性を考慮する必要があります。 エンドポイントは、以前の鍵更新が受信されたことを確認する確認応答を受け取った後、 次の鍵更新を開始するまでPTOの3倍待つSHOULD。 十分な時間を設けないと、パケットが破棄される可能性があります。

エンドポイントは、新しい鍵を使用して保護されたパケットを受信した後、 PTOの3倍を超えて古い読み取り鍵を保持するべきではSHOULD。 この期間が経過した後、 古い読み取り鍵と対応するシークレットは破棄するSHOULD。

6.6. AEAD使用の制限

この文書では、AEADアルゴリズムの過度な使用によって、 QUIC使用時の通信の 機密性と完全性を攻撃する上で、攻撃者に不釣り合いな優位性を与えないようにするため、 使用制限を定めています。

TLS 1.3で定義される使用制限は、 機密性への攻撃に対する保護のために存在し、AEAD保護の適用に成功した場合に適用されます。 認証付き暗号化における完全性保護は、パケット偽造の 試行回数を制限することにも依存します。TLSでは、レコードが 認証チェックに失敗した後に接続を閉じることでこれを実現します。これに対しQUICは、 認証できないパケットをすべて無視し、複数回の偽造試行を許容します。

QUICは、AEADの機密性制限と完全性制限を別々に扱います。 機密性制限は、特定の 鍵で暗号化されるパケット数に適用されます。完全性制限は、 特定の接続内で復号されるパケット数に適用されます。 各AEADアルゴリズムでこれらの制限を適用する方法の詳細を以下に示します。

エンドポイントは、各鍵セットについて暗号化された パケット数を数えるMUST。同じ鍵で暗号化されたパケットの 総数が、選択されたAEADの機密性制限を超えた場合、エンドポイントは それらの鍵の使用を停止MUST。 エンドポイントは、選択されたAEADの機密性制限で許可される数を超える 保護パケットを送信する前に、鍵更新を開始MUST。 鍵更新が不可能な場合、または完全性制限に達した場合、エンドポイントは 接続の使用を停止MUSTし、パケット受信への応答としては stateless resetだけを送信しなければなりません。 鍵更新が不可能な状態に達する前に、 エンドポイントがAEAD_LIMIT_REACHEDタイプの接続エラーで 接続を直ちに閉じることがRECOMMENDED。

AEAD_AES_128_GCMおよびAEAD_AES_256_GCMでは、機密性制限は 223個の暗号化パケットです。付録B.1を参照してください。 AEAD_CHACHA20_POLY1305では、機密性制限は 可能なパケット数(262)より大きいため、無視できます。 AEAD_AES_128_CCMでは、機密性制限は221.5個の暗号化 パケットです。付録B.2を参照してください。制限を適用することで、 攻撃者が使用中のAEADとランダム置換を区別できる確率が低下します。 [AEBounds]、[ROBUST]、および[GCM-MU]を参照してください。

送信パケットを数えることに加えて、エンドポイントは、 接続の存続期間中に認証に失敗した 受信パケット数を数えるMUST。 すべての鍵にわたって、接続内で認証に失敗した受信パケットの 総数が、選択されたAEADの完全性制限を超えた場合、 エンドポイントはAEAD_LIMIT_REACHEDタイプの接続エラーで 接続を直ちに閉じ、それ以上パケットを処理してはMUST。

AEAD_AES_128_GCMおよびAEAD_AES_256_GCMでは、完全性制限は 252個の 無効なパケットです。付録B.1を参照してください。 AEAD_CHACHA20_POLY1305では、完全性 制限は236個の無効なパケットです。[AEBounds]を参照してください。AEAD_AES_128_CCMでは、 完全性制限は221.5個の無効なパケットです。 付録B.2を参照してください。この制限を適用することで、 攻撃者がパケットの偽造に成功する確率が低下します。[AEBounds]、 [ROBUST]、および[GCM-MU]を参照してください。

パケットサイズを制限するエンドポイントは、より高い機密性および 完全性制限を使用するMAY。詳細については付録Bを参照してください。

将来の分析および仕様では、AEADの 機密性または完全性の制限を緩和するMAY。

QUICで使用するよう規定される任意のTLS暗号スイートは、 機密性および完全性の余裕を維持する、 関連するAEAD関数の使用制限を定義MUST。 すなわち、認証できるパケット数と、 認証に失敗できるパケット数について制限を規定MUST。 値の根拠となる分析、およびその分析で使用した前提への参照を提供することで、 さまざまな使用条件に応じて制限を調整できます。

6.7. 鍵更新エラーコード

KEY_UPDATE_ERRORエラーコード(0x0e)は、鍵の 更新に関連するエラーを通知するために使用されます。

7. Initialメッセージのセキュリティ

Initialパケットはシークレット鍵で保護されていないため、 攻撃者による改ざんを受ける可能性があります。QUICは、 パケットを読み取れない攻撃者に対する保護を提供しますが、 攻撃者がパケットを観測して注入できる攻撃に対する追加の保護は提供しません。 TLSメッセージ自体の変更など、一部の形式の 改ざんは検出可能ですが、ACKの変更などは検出できません。

たとえば、攻撃者はACKフレームを含むパケットを注入して、 パケットが受信されていないように見せたり、接続状態について誤った 印象を作り出したりできます(たとえばACK Delayを変更することによって)。 このようなパケットにより、正当なパケットが重複として 破棄される可能性があることに注意してください。実装は、 Initialパケットに含まれ、他の方法で認証されていないデータに依存する際には 注意するSHOULD。

攻撃者がHandshakeパケットで伝送されるデータを改ざんすることも可能ですが、 その種の改ざんにはTLS ハンドシェイクメッセージの変更が必要となるため、そのような改ざんはすべてTLSハンドシェイクを失敗させます。

8. TLSハンドシェイクに対するQUIC固有の調整

TLSハンドシェイクの一部の側面は、QUICとともに使用する場合に異なります。

QUICは、TLSに追加の機能も要求します。 暗号学的パラメーターのネゴシエーションに加えて、TLSハンドシェイクは QUICトランスポートパラメーターの値を伝送し、認証します。

8.1. プロトコルネゴシエーション

QUICは、暗号学的ハンドシェイクが認証されたプロトコル ネゴシエーションを提供することを要求します。TLSはApplication-Layer Protocol Negotiation [ALPN]を使用してアプリケーションプロトコルを選択します。 アプリケーションプロトコルへの合意に別のメカニズムが 使用されない限り、エンドポイントはこの目的にALPNを使用MUST。

ALPNを使用する場合、アプリケーションプロトコルがネゴシエートされなければ、 エンドポイントはno_application_protocol TLSアラート(QUIC エラーコード0x0178。セクション4.8を参照)で接続を直ちに閉じるMUST ([QUIC-TRANSPORT]のセクション10.2を参照)。 [ALPN]では、このアラートを使用するのはサーバーだけと規定されていますが、 QUICクライアントは ALPNネゴシエーションが失敗した場合、エラー0x0178を使用して接続を終了MUST。

アプリケーションプロトコルは、動作できるQUIC バージョンを制限するMAY。 サーバーは、クライアントが選択したQUIC バージョンと互換性のあるアプリケーションプロトコルを選択MUST。 サーバーは、 互換性のあるアプリケーションプロトコルを選択できないことを タイプ0x0178(no_application_protocol)の接続エラーとして扱うMUST。 同様に、クライアントは サーバーによる互換性のないアプリケーションプロトコルの選択を タイプ0x0178の接続エラーとして扱うMUST。

8.2. QUICトランスポート パラメーター拡張

QUICトランスポートパラメーターはTLS拡張で伝送されます。異なる QUICバージョンでは、トランスポート構成をネゴシエートするための別の方法を定義する場合があります。

TLSハンドシェイクにトランスポートパラメーターを含めることで、 これらの値に完全性保護が提供されます。

   enum {
      quic_transport_parameters(0x39), (65535)
   } ExtensionType;

quic_transport_parameters拡張のextension_dataフィールドには、 使用中のQUICバージョンによって定義される値が含まれます。

quic_transport_parameters拡張は、ハンドシェイク中にClientHelloおよび EncryptedExtensionsメッセージで伝送されます。エンドポイントは quic_transport_parameters拡張を送信MUST。 quic_transport_parameters拡張を含まないClientHelloまたは EncryptedExtensionsメッセージを受信したエンドポイントは、 タイプ0x016dのエラー(fatal TLS missing_extensionアラートに相当。セクション4.8を参照)で接続を閉じるMUST。

トランスポートパラメーターは、ハンドシェイク完了前に利用可能になります。 サーバーは、ハンドシェイク完了前にこれらの値を使用する場合があります。ただし、 トランスポートパラメーターの値はハンドシェイクが 完了するまで認証されないため、これらのパラメーターの使用はその真正性に依存できません。 トランスポートパラメーターが改ざんされると、ハンドシェイクは失敗します。

エンドポイントは、QUICを使用しないTLS 接続([TLS13]で定義されるTCPでのTLS使用など)でこの拡張を送信してはMUST NOT。 トランスポートがQUICでないときにこの拡張を受信した場合、 この拡張をサポートする実装はfatal unsupported_extensionアラートを送信MUST。

quic_transport_parameters拡張をネゴシエートすると、EndOfEarlyDataが 削除されます。セクション8.3を参照してください。

8.3. EndOfEarlyDataメッセージの削除

TLS EndOfEarlyDataメッセージはQUICでは使用されません。QUICは、 このメッセージを0-RTTデータの終端を示したり、Handshake 鍵への変更を通知したりするために使用しません。

クライアントはEndOfEarlyDataメッセージを送信してはMUST NOT。 サーバーは、 0-RTTパケット内のCRYPTOフレームの受信を PROTOCOL_VIOLATIONタイプの接続エラーとして扱うMUST。

その結果、EndOfEarlyDataはTLSハンドシェイクトランスクリプトには現れません。

8.4. TLSミドルボックス 互換モードの禁止

[TLS13]の付録D.4では、 一部のミドルボックスのバグを回避するための TLS 1.3ハンドシェイクの変更について説明しています。TLS 1.3ミドルボックス互換 モードでは、ClientHelloとServerHelloのlegacy_session_idフィールドを 32バイトの値に設定し、その後change_cipher_specレコードを送信します。 フィールドもレコードも意味的な内容を持たず、無視されます。

このモードは、TCP上のTLSに干渉するミドルボックスにのみ適用されるため、 QUICでは用途がありません。QUICにはchange_cipher_spec レコードを伝送する手段もありません。クライアントはTLS 1.3 互換モードの使用を要求してはMUST NOT。 サーバーは、空でない legacy_session_idフィールドを持つTLS ClientHelloの受信をPROTOCOL_VIOLATIONタイプの接続エラーとして扱うSHOULD。

9. セキュリティに関する考慮事項

TLSに適用されるすべてのセキュリティ上の考慮事項は、 QUICでTLSを使用する場合にも適用されます。[TLS13]とその付録をすべて読むことが、 QUICのセキュリティ特性を理解するための最良の方法です。

このセクションでは、TLS統合に固有の、より重要なセキュリティ上の側面の一部を 要約します。ただし、文書の 残りの部分にもセキュリティに関連する詳細が多数あります。

9.1. セッションのリンク可能性

TLSセッションチケットを使用すると、サーバーや場合によっては他のエンティティが、 同じクライアントによって行われた接続を関連付けることができます。詳細についてはセクション 4.5を参照してください。

9.2. 0-RTTに対する リプレイ攻撃

[TLS13]のセクション8で説明されているように、 TLS early dataの使用にはリプレイ攻撃にさらされる危険があります。QUICでの0-RTTの使用も同様に リプレイ攻撃に対して脆弱です。

エンドポイントは、[TLS13]で説明されているリプレイ 保護を実装して使用MUSTしますが、 これらの保護が完全ではないことも認識されています。したがって、 リプレイのリスクについて追加の考慮が必要です。

QUICは、伝送する可能性のあるアプリケーションプロトコル情報を介する場合を除き、 リプレイ攻撃に対して脆弱ではありません。[QUIC-TRANSPORT]で 定義されているフレームタイプに基づくQUICプロトコル状態の管理は、リプレイに対して脆弱ではありません。 QUICフレームの処理は冪等であり、フレームがリプレイ、並べ替え、または損失しても 無効な接続状態になることはありません。QUIC接続は、 QUICが提供するアプリケーションプロトコルによるものを除き、 接続の存続期間を超えて残る影響を生成しません。

TLSセッションチケットとアドレス検証トークンは、接続間でQUIC 構成情報を伝送するために使用されます。具体的には、サーバーが接続確立および アドレス検証で使用する状態を効率的に復元できるようにします。これらは、エンドポイント間で アプリケーションの意味を伝達するために使用してはMUST NOT。 クライアントはこれらを不透明な値として扱うMUST。 これらのトークンは再利用される可能性があるため、 リプレイに対してより強い保護が必要です。

接続で0-RTTを受け入れるサーバーは、 0-RTTなしで接続を受け入れる場合よりも高いコストを負担します。これには、 より高い処理コストおよび計算コストが含まれます。 サーバーは0-RTTを受け入れる際、リプレイの可能性とそれに伴うすべての コストを考慮する必要があります。

最終的に、0-RTTにおけるリプレイ攻撃のリスクを管理する責任は アプリケーションプロトコルにあります。QUICを使用するアプリケーションプロトコルは、 プロトコルが0-RTTをどのように使用するか、およびリプレイ攻撃から 保護するために採用する対策を説明MUST。 リプレイリスクの分析では、 アプリケーションの意味を伝送するすべてのQUICプロトコル機能を考慮する必要があります。

0-RTTを完全に無効化することが、リプレイ 攻撃に対する最も効果的な防御です。

QUIC拡張は、リプレイ 攻撃がその動作にどのような影響を与えるかを説明するか、 0-RTTでその拡張を使用することを禁止するかのいずれかを行うMUST。 アプリケーションプロトコルは、 アプリケーションの意味を伝送する拡張を0-RTTで使用することを禁止するか、 リプレイ緩和戦略を提供するかのいずれかを行うMUST。

9.3. パケット反射攻撃の 緩和

小さなClientHelloによってサーバーから大きなハンドシェイクメッセージのブロックが 生成される場合、攻撃者が生成するトラフィックを増幅する パケット反射攻撃に利用できます。

QUICには、この攻撃に対する3つの防御があります。第一に、ClientHelloを含むパケットは 最小サイズまでパディングMUST。第二に、 検証されていない送信元アドレスに応答する場合、サーバーは受信したバイト数の 3倍を超えるバイトを送信することを禁止されています( [QUIC-TRANSPORT]のセクション8.1を参照)。 最後に、Handshakeパケットへの 確認応答は認証されるため、ブラインド攻撃者はそれを偽造できません。これらの防御を 組み合わせることで、増幅の程度が制限されます。

9.4. ヘッダー保護の 分析

[NAN]では、nonceのプライバシーを提供する 認証付き暗号化アルゴリズムを分析しており、これらを「Hide Nonce」(HN) 変換と呼びます。この文書の一般的なヘッダー保護構成は、 それらのアルゴリズムの1つ(HN1)です。ヘッダー保護はパケット 保護AEADの後に適用され、AEAD出力から一連のバイト(sample)をサンプリングし、 次のように擬似乱数関数(PRF)を使用してヘッダーフィールドを暗号化します。

protected_field = field XOR PRF(hp_key, sample)

この文書のヘッダー保護の各方式では、一般的なPRFの代わりに 擬似乱数置換(PRP)を使用します。ただし、すべてのPRPはPRFでもあるため[IMC]、 これらの方式はHN1構成から逸脱しません。

hp_keyはパケット保護鍵とは異なるため、 ヘッダー 保護は[NAN]で定義されるAE2セキュリティを実現し、 したがって保護されたパケットヘッダーであるfieldのプライバシーを保証します。この構成に基づく将来のヘッダー保護 方式は、同等の セキュリティ保証を確保するためにPRFを使用MUST。

同じ鍵と暗号文サンプルを複数回使用すると、 ヘッダー保護が損なわれる危険があります。同じ鍵と 暗号文サンプルで2つの異なるヘッダーを保護すると、保護されたフィールドの排他的ORが明らかになります。 AEADがPRFとして機能すると仮定し、Lビットをサンプリングする場合、2つの暗号文 サンプルが同一になる確率は2-L/2に近づきます。これは誕生日限界です。 この文書で説明するアルゴリズムでは、その確率は 264分の1です。

攻撃者がパケットヘッダーを変更するのを防ぐため、ヘッダーは パケット保護によって間接的に 認証されます。パケットヘッダー全体が 認証対象の追加データの一部です。偽造または変更された保護フィールドは、 パケット保護を解除して初めて検出できます。

9.5. ヘッダー保護のタイミング サイドチャネル

攻撃者はパケット番号またはKey Phaseの値を推測し、 タイミングサイドチャネルを介してエンドポイントに推測を確認させる可能性があります。同様に、 パケット番号長を推測して試し、その結果を露出させることもできます。パケットの受信者が、 パケット保護を解除しようとせずに重複したパケット番号を持つパケットを 破棄する場合、タイミングサイドチャネルを介して、 そのパケット番号が受信済みパケットと一致することが明らかになる可能性があります。認証で サイドチャネルが生じないようにするには、ヘッダー保護の解除、パケット番号の 復元、およびパケット保護の解除という処理全体を、タイミング その他のサイドチャネルなしに一体として適用MUST。

パケット送信では、パケットペイロードおよび パケット番号の構築と保護は、パケット 番号またはそのエンコードサイズを明らかにするサイドチャネルを生じさせてはMUST。

鍵更新中、新しい鍵の生成に要する時間によって、 鍵更新が発生したことがタイミングサイドチャネルを通じて明らかになる可能性があります。また、 攻撃者がパケットを注入した場合、このサイドチャネルによって注入されたパケットのKey Phaseの値が明らかになる可能性があります。鍵更新を受信した後、エンドポイントは、 セクション6.3で説明されているように、 次の受信パケット保護鍵セットを生成して保存するSHOULD。 鍵更新を受信する前に新しい鍵を生成することで、 パケット受信時にKey Phaseの値を漏らすタイミング信号が生じなくなります。

これは、パケット処理中にこの鍵生成を行わないことに依存しており、 エンドポイントが受信用に3セットのパケット保護鍵を保持する必要が生じる場合があります。 すなわち、以前の鍵フェーズ、現在の鍵フェーズ、および 次の鍵フェーズ用です。エンドポイントは代わりに、古い鍵を破棄するまで 次の受信パケット保護鍵の生成を遅らせることを選択でき、その場合は任意の時点で 受信鍵を2セットだけ保持すれば済みます。

9.6. 鍵の多様性

TLSを使用する際には、TLSの中心的な鍵スケジュールが使用されます。 TLSハンドシェイクメッセージがシークレットの計算に組み込まれる結果として、 QUICトランスポートパラメーター拡張を含めることで、ハンドシェイク および1-RTT鍵が、TCP上でTLSを実行するサーバーによって生成される可能性がある鍵と 同じにならないことが保証されます。プロトコル間の鍵 同期の可能性を避けるため、鍵の分離を改善する追加の対策が提供されています。

QUICパケット保護鍵とIVは、 TLSの対応する鍵とは異なるラベルを使用して導出されます。

この分離を維持するため、新しいQUICバージョンは、 パケット保護鍵とIV、およびヘッダー保護 鍵の鍵導出に新しいラベルを定義するSHOULD。このQUICバージョンでは文字列"quic"を使用します。他のバージョンでは、 この文字列の代わりにバージョン固有のラベルを使用できます。

Initialシークレットは、ネゴシエートされたQUICバージョン固有の鍵を使用します。 新しいQUICバージョンは、Initial シークレットの計算に使用する新しいソルト値を定義するSHOULD。

9.7. ランダム性

QUICは、接続IDなどのプロトコル値に直接使用する場合と、 TLSを介して間接的に使用する場合の両方で、エンドポイントが安全な乱数を生成できることに依存します。 安全な乱数生成に関するガイダンスについては[RFC4086]を参照してください。

10. IANAに関する考慮事項

IANAは、 quic_transport_parameters拡張(セクション8.2で定義)に対して57(または0x39)のコードポイントを 「TLS ExtensionType Values」レジストリ[TLS-REGISTRIES]に登録しています。

この拡張のRecommended列はYesとされています。TLS 1.3列には CH(ClientHello)およびEE(EncryptedExtensions)が含まれます。

表2: TLS ExtensionType Valuesレジストリ エントリ
値 拡張名 TLS 1.3 推奨 参照
57 quic_transport_parameters CH, EE Y この文書

11. 参考文献

11.1. 規範的参考文献

[AEAD]
McGrew, D., 「認証付き暗号化のためのインターフェイスと アルゴリズム」, RFC 5116, DOI 10.17487/RFC5116, , <https://www.rfc-editor.org/info/rfc5116>.
[AES]
「Advanced Encryption Standard (AES)」, 米国国立標準技術研究所報告書, DOI 10.6028/nist.fips.197, , <https://doi.org/10.6028/nist.fips.197>.
[ALPN]
Friedl, S., Popov, A., Langley, A., およびE. Stephan, 「Transport Layer Security (TLS) Application-Layer Protocol Negotiation 拡張」, RFC 7301, DOI 10.17487/RFC7301, , <https://www.rfc-editor.org/info/rfc7301>.
[CHACHA]
Nir, Y.およびA. Langley, 「IETFプロトコルのためのChaCha20およびPoly1305」, RFC 8439, DOI 10.17487/RFC8439, , <https://www.rfc-editor.org/info/rfc8439>.
[HKDF]
Krawczyk, H.およびP. Eronen, 「HMACベースのExtract-and-Expand鍵導出関数(HKDF)」, RFC 5869, DOI 10.17487/RFC5869, , <https://www.rfc-editor.org/info/rfc5869>.
[QUIC-RECOVERY]
Iyengar, J., Ed.およびI. Swett, Ed., 「QUICの損失検出および輻輳制御」, RFC 9002, DOI 10.17487/RFC9002, , <https://www.rfc-editor.org/info/rfc9002>.
[QUIC-TRANSPORT]
Iyengar, J., Ed.およびM. Thomson, Ed., 「QUIC: UDPベースの多重化された安全なトランスポート」, RFC 9000, DOI 10.17487/RFC9000, , <https://www.rfc-editor.org/info/rfc9000>.
[RFC2119]
Bradner, S., 「要件レベルを 示すためにRFCで使用するキーワード」, BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC4086]
Eastlake 3rd, D., Schiller, J., および S. Crocker, 「セキュリティのための ランダム性要件」, BCP 106, RFC 4086, DOI 10.17487/RFC4086, , <https://www.rfc-editor.org/info/rfc4086>.
[RFC8174]
Leiba, B., 「RFC 2119キーワードにおける大文字と 小文字の曖昧さ」, BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[SHA]
Dang, Q., 「Secure Hash Standard」, 米国国立標準技術研究所報告書, DOI 10.6028/nist.fips.180-4, , <https://doi.org/10.6028/nist.fips.180-4>.
[TLS-REGISTRIES]
Salowey, J.およびS. Turner, 「TLSおよびDTLSのIANAレジストリ更新」, RFC 8447, DOI 10.17487/RFC8447, , <https://www.rfc-editor.org/info/rfc8447>.
[TLS13]
Rescorla, E., 「Transport Layer Security (TLS)プロトコル バージョン1.3」, RFC 8446, DOI 10.17487/RFC8446, , <https://www.rfc-editor.org/info/rfc8446>.

11.2. 参考情報

[AEBounds]
Luykx, A.およびK. Paterson, 「TLSにおける認証付き暗号化の使用制限」, , <https://www.isg.rhul.ac.uk/~kp/TLS-AEbounds.pdf>.
[ASCII]
Cerf, V., 「ネットワーク 交換用ASCII形式」, STD 80, RFC 20, DOI 10.17487/RFC0020, , <https://www.rfc-editor.org/info/rfc20>.
[CCM-ANALYSIS]
Jonsson, J., 「CTR + CBC-MACのセキュリティについて」, 暗号技術の選択分野, SAC 2002, Lecture Notes in Computer Science, 第2595巻, 76-93ページ, DOI 10.1007/3-540-36492-7_7, , <https://doi.org/10.1007/3-540-36492-7_7>.
[COMPRESS]
Ghedini, A.およびV. Vasiliev, 「TLS証明書圧縮」, RFC 8879, DOI 10.17487/RFC8879, , <https://www.rfc-editor.org/info/rfc8879>.
[GCM-MU]
Hoang, V., Tessaro, S., およびA. Thiruvengadam, 「GCMのマルチユーザーセキュリティ 再考: Nonceランダム化のための厳密な境界」, CCS '18: 2018 ACM SIGSAC Conference on Computer and Communications Security論文集, 1429-1440ページ, DOI 10.1145/3243734.3243816, , <https://doi.org/10.1145/3243734.3243816>.
[HTTP-REPLAY]
Thomson, M., Nottingham, M., およびW. Tarreau, 「HTTPでのEarly Dataの使用」, RFC 8470, DOI 10.17487/RFC8470, , <https://www.rfc-editor.org/info/rfc8470>.
[HTTP2-TLS13]
Benjamin, D., 「HTTP/2でのTLS 1.3の 使用」, RFC 8740, DOI 10.17487/RFC8740, , <https://www.rfc-editor.org/info/rfc8740>.
[IMC]
Katz, J.およびY. Lindell, 「現代暗号学入門 第2版」, ISBN 978-1466570269, .
[NAN]
Bellare, M., Ng, R., およびB. Tackmann, 「Nonceは注目される: AEAD 再考」, 暗号技術の進歩 - CRYPTO 2019, Lecture Notes in Computer Science, 第11692巻, 235-265ページ, DOI 10.1007/978-3-030-26948-7_9, , <https://doi.org/10.1007/978-3-030-26948-7_9>.
[QUIC-HTTP]
Bishop, M., Ed., 「Hypertext Transfer Protocol バージョン3(HTTP/3)」, 作業中, Internet-Draft, draft-ietf-quic-http-34, , <https://tools.ietf.org/html/draft-ietf-quic-http-34>.
[RFC2818]
Rescorla, E., 「TLS上のHTTP」, RFC 2818, DOI 10.17487/RFC2818, , <https://www.rfc-editor.org/info/rfc2818>.
[RFC5280]
Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., およびW. Polk, 「Internet X.509公開鍵基盤の証明書および証明書 失効リスト(CRL)プロファイル」, RFC 5280, DOI 10.17487/RFC5280, , <https://www.rfc-editor.org/info/rfc5280>.
[ROBUST]
Fischlin, M., Günther, F., およびC. Janson, 「堅牢なチャネル: QUICおよびDTLS 1.3の レコードレイヤーにおける信頼できないネットワークへの対処」, , <https://eprint.iacr.org/2020/718>.

付録A. パケット保護の例

このセクションでは、実装を段階的に 検証できるように、パケット保護の例を示します。クライアントとサーバーの両方のInitialパケットの例に加えて、 Retryパケットも定義します。これらのパケットでは、クライアントが選択した8バイトの Destination Connection IDである0x8394c8f03e515708を使用します。いくつかの中間値も 含まれています。すべての値は16進数で示します。

A.1. 鍵

HKDF-Expand-Label関数の実行中に生成されるラベル (すなわちHkdfLabel.label)と、その出力を生成するためにHKDF-Expand 関数に与えられる値の一部は次のとおりです。

client in:

00200f746c73313320636c69656e7420696e00

server in:

00200f746c7331332073657276657220696e00

quic key:

00100e746c7331332071756963206b657900

quic iv:

000c0d746c733133207175696320697600

quic hp:

00100d746c733133207175696320687000

Initialシークレットは共通です。

initial_secret = HKDF-Extract(initial_salt, cid)
    = 7db5df06e7a69e432496adedb0085192
      3595221596ae2ae9fb8115c1e9ed0a44

クライアントパケットを保護するためのシークレットは次のとおりです。

client_initial_secret
    = HKDF-Expand-Label(initial_secret, "client in", "", 32)
    = c00cf151ca5be075ed0ebfb5c80323c4
      2d6b7db67881289af4008f1f6c357aea

key = HKDF-Expand-Label(client_initial_secret, "quic key", "", 16)
    = 1f369613dd76d5467730efcbe3b1a22d

iv  = HKDF-Expand-Label(client_initial_secret, "quic iv", "", 12)
    = fa044b2f42a3fd3b46fb255c

hp  = HKDF-Expand-Label(client_initial_secret, "quic hp", "", 16)
    = 9f50449e04a0e810283a1e9933adedd2

サーバーパケットを保護するためのシークレットは次のとおりです。

server_initial_secret
    = HKDF-Expand-Label(initial_secret, "server in", "", 32)
    = 3c199828fd139efd216c155ad844cc81
      fb82fa8d7446fa7d78be803acdda951b

key = HKDF-Expand-Label(server_initial_secret, "quic key", "", 16)
    = cf3a5331653c364c88f0f379b6067e37

iv  = HKDF-Expand-Label(server_initial_secret, "quic iv", "", 12)
    = 0ac1493ca1905853b0bba03e

hp  = HKDF-Expand-Label(server_initial_secret, "quic hp", "", 16)
    = c206b8d9b9f0f37644430b490eeaa314

A.2. クライアントInitial

クライアントはInitialパケットを送信します。このパケットの保護されていないペイロードには、 次のCRYPTOフレームと、ペイロードを 1162バイトにするために十分なPADDINGフレームが含まれます。

060040f1010000ed0303ebf8fa56f129 39b9584a3896472ec40bb863cfd3e868
04fe3a47f06a2b69484c000004130113 02010000c000000010000e00000b6578
616d706c652e636f6dff01000100000a 00080006001d00170018001000070005
04616c706e0005000501000000000033 00260024001d00209370b2c9caa47fba
baf4559fedba753de171fa71f50f1ce1 5d43e994ec74d748002b000302030400
0d0010000e0403050306030203080408 050806002d00020101001c0002400100
3900320408ffffffffffffffff050480 00ffff07048000ffff08011001048000
75300901100f088394c8f03e51570806 048000ffff

保護されていないヘッダーは1182バイトの長さを示します。4バイトのパケット 番号、1162バイトのフレーム、および16バイトの認証タグです。ヘッダーには 接続IDとパケット番号2が含まれます。

c300000001088394c8f03e5157080000449e00000002

ペイロードを保護すると、ヘッダー保護用にサンプリングされる出力が生成されます。 ヘッダーでは4バイトのパケット番号エンコードを使用しているため、保護されたペイロードの最初の16バイトが サンプリングされ、次のようにヘッダーへ適用されます。

sample = d1b1c98dd7689fb8ec11d242b123dc9b

mask = AES-ECB(hp, sample)[0..4]
     = 437b9aec36

header[0] ^= mask[0] & 0x0f
     = c0
header[18..21] ^= mask[1..4]
     = 7b9aec34
header = c000000001088394c8f03e5157080000449e7b9aec34

結果として得られる保護されたパケットは次のとおりです。

c000000001088394c8f03e5157080000 449e7b9aec34d1b1c98dd7689fb8ec11
d242b123dc9bd8bab936b47d92ec356c 0bab7df5976d27cd449f63300099f399
1c260ec4c60d17b31f8429157bb35a12 82a643a8d2262cad67500cadb8e7378c
8eb7539ec4d4905fed1bee1fc8aafba1 7c750e2c7ace01e6005f80fcb7df6212
30c83711b39343fa028cea7f7fb5ff89 eac2308249a02252155e2347b63d58c5
457afd84d05dfffdb20392844ae81215 4682e9cf012f9021a6f0be17ddd0c208
4dce25ff9b06cde535d0f920a2db1bf3 62c23e596d11a4f5a6cf3948838a3aec
4e15daf8500a6ef69ec4e3feb6b1d98e 610ac8b7ec3faf6ad760b7bad1db4ba3
485e8a94dc250ae3fdb41ed15fb6a8e5 eba0fc3dd60bc8e30c5c4287e53805db
059ae0648db2f64264ed5e39be2e20d8 2df566da8dd5998ccabdae053060ae6c
7b4378e846d29f37ed7b4ea9ec5d82e7 961b7f25a9323851f681d582363aa5f8
9937f5a67258bf63ad6f1a0b1d96dbd4 faddfcefc5266ba6611722395c906556
be52afe3f565636ad1b17d508b73d874 3eeb524be22b3dcbc2c7468d54119c74
68449a13d8e3b95811a198f3491de3e7 fe942b330407abf82a4ed7c1b311663a
c69890f4157015853d91e923037c227a 33cdd5ec281ca3f79c44546b9d90ca00
f064c99e3dd97911d39fe9c5d0b23a22 9a234cb36186c4819e8b9c5927726632
291d6a418211cc2962e20fe47feb3edf 330f2c603a9d48c0fcb5699dbfe58964
25c5bac4aee82e57a85aaf4e2513e4f0 5796b07ba2ee47d80506f8d2c25e50fd
14de71e6c418559302f939b0e1abd576 f279c4b2e0feb85c1f28ff18f58891ff
ef132eef2fa09346aee33c28eb130ff2 8f5b766953334113211996d20011a198
e3fc433f9f2541010ae17c1bf202580f 6047472fb36857fe843b19f5984009dd
c324044e847a4f4a0ab34f719595de37 252d6235365e9b84392b061085349d73
203a4a13e96f5432ec0fd4a1ee65accd d5e3904df54c1da510b0ff20dcc0c77f
cb2c0e0eb605cb0504db87632cf3d8b4 dae6e705769d1de354270123cb11450e
fc60ac47683d7b8d0f811365565fd98c 4c8eb936bcab8d069fc33bd801b03ade
a2e1fbc5aa463d08ca19896d2bf59a07 1b851e6c239052172f296bfb5e724047
90a2181014f3b94a4e97d117b4381303 68cc39dbb2d198065ae3986547926cd2
162f40a29f0c3c8745c0f50fba3852e5 66d44575c29d39a03f0cda721984b6f4
40591f355e12d439ff150aab7613499d bd49adabc8676eef023b15b65bfc5ca0
6948109f23f350db82123535eb8a7433 bdabcb909271a6ecbcb58b936a88cd4e
8f2e6ff5800175f113253d8fa9ca8885 c2f552e657dc603f252e1a8e308f76f0
be79e2fb8f5d5fbbe2e30ecadd220723 c8c0aea8078cdfcb3868263ff8f09400
54da48781893a7e49ad5aff4af300cd8 04a6b6279ab3ff3afb64491c85194aab
760d58a606654f9f4400e8b38591356f bf6425aca26dc85244259ff2b19c41b9
f96f3ca9ec1dde434da7d2d392b905dd f3d1f9af93d1af5950bd493f5aa731b4
056df31bd267b6b90a079831aaf579be 0a39013137aac6d404f518cfd4684064
7e78bfe706ca4cf5e9c5453e9f7cfd2b 8b4c8d169a44e55c88d4a9a7f9474241
e221af44860018ab0856972e194cd934

A.3. サーバーInitial

サーバーは応答として、ACKフレームと CRYPTOフレームを含み、PADDINGフレームを含まない次のペイロードを送信します。

02000000000600405a020000560303ee fce7f7b37ba1d1632e96677825ddf739
88cfc79825df566dc5430b9a045a1200 130100002e00330024001d00209d3c94
0d89690b84d08a60993c144eca684d10 81287c834d5311bcf32bb9da1a002b00
020304

サーバーからのヘッダーには、新しい接続IDと、パケット番号1に対する2バイトのパケット 番号エンコードが含まれます。

c1000000010008f067a5502a4262b50040750001

その結果、保護後、ヘッダー保護サンプルは 3番目の保護されたバイトから取得されます。

sample = 2cd0991cd25b0aac406a5816b6394100
mask   = 2ec0d8356a
header = cf000000010008f067a5502a4262b5004075c0d9

最終的な保護されたパケットは次のようになります。

cf000000010008f067a5502a4262b500 4075c0d95a482cd0991cd25b0aac406a
5816b6394100f37a1c69797554780bb3 8cc5a99f5ede4cf73c3ec2493a1839b3
dbcba3f6ea46c5b7684df3548e7ddeb9 c3bf9c73cc3f3bded74b562bfb19fb84
022f8ef4cdd93795d77d06edbb7aaf2f 58891850abbdca3d20398c276456cbc4
2158407dd074ee

A.4. Retry

これは、付録A.2のInitialパケットへの応答として 送信される可能性があるRetryパケットを示します。完全性チェックには、クライアントが選択した 接続ID値0x8394c8f03e515708が含まれますが、その値は 最終的なRetryパケットには含まれません。

ff000000010008f067a5502a4262b574 6f6b656e04a265ba2eff4d829058fb3f
0f2496ba

A.5. ChaCha20-Poly1305 ショートヘッダーパケット

この例では、ショートヘッダーを持つパケットを保護するために 必要な手順の一部を示します。この例ではAEAD_CHACHA20_POLY1305を使用します。

この例では、TLSはアプリケーション書き込みシークレットを生成し、サーバーはそこから HKDF-Expand-Labelを使用して、鍵、IV、ヘッダー 保護鍵、および鍵更新後に使用されるシークレットという4つの値を生成します(この 最後の値は、この例ではこれ以上使用しません)。

secret
    = 9ac312a7f877468ebe69422748ad00a1
      5443f18203a07d6060f688f30f21632b

key = HKDF-Expand-Label(secret, "quic key", "", 32)
    = c6d98ff3441c3fe1b2182094f69caa2e
      d4b716b65488960a7a984979fb23e1c8

iv  = HKDF-Expand-Label(secret, "quic iv", "", 12)
    = e0459b3474bdd0e44a41c144

hp  = HKDF-Expand-Label(secret, "quic hp", "", 32)
    = 25a282b9e82f06f21f488917a4fc8f1b
      73573685608597d0efcb076b0ab7a7a4

ku  = HKDF-Expand-Label(secret, "quic ku", "", 32)
    = 1223504755036d556342ee9361d25342
      1a826c9ecdf3c7148684b36b714881f9

次に、空のDestination Connection IDを持つ 最小パケットを保護する手順を示します。このパケットには1つのPINGフレーム (すなわち、0x01だけのペイロード)が含まれ、パケット番号は654360564です。この 例では、長さ3のパケット番号(すなわち49140がエンコードされる)を使用することで、 パケットのペイロードをパディングする必要がなくなります。パケット番号を より少ないバイト数でエンコードする場合はPADDINGフレームが必要になります。

pn                 = 654360564 (decimal)
nonce              = e0459b3474bdd0e46d417eb0
unprotected header = 4200bff4
payload plaintext  = 01
payload ciphertext = 655e5cd55c41f69080575d7999c25a5bfb

結果として得られる暗号文は可能な最小サイズです。ヘッダー保護用の サンプルを生成するために1バイトをスキップします。

sample = 5e5cd55c41f69080575d7999c25a5bfb
mask   = aefefe7d03
header = 4cfe4189

保護されたパケットは、可能な最小パケットサイズである21バイトです。

packet = 4cfe4189655e5cd55c41f69080575d7999c25a5bfb

付録B. AEADアルゴリズムの分析

このセクションでは、 AEAD_AES_128_GCM、AEAD_AES_128_CCM、およびAEAD_AES_256_GCMのAEADアルゴリズム制限を導出するために使用した分析を記載します。以下の分析では、 乗算(*)、除算(/)、指数演算(^)の記号と、 優先順位を設定するための括弧を使用します。さらに、次の記号も 使用します。

t:

認証タグのビット単位のサイズです。これらの暗号では、tは 128です。

n:

ブロック関数のビット単位のサイズです。これらの暗号では、nは 128です。

k:

鍵のビット単位のサイズです。AEAD_AES_128_GCMおよび AEAD_AES_128_CCMでは128、AEAD_AES_256_GCMでは256です。

l:

各パケット内のブロック数です(以下を参照)。

q:

エンドポイントによって作成され保護される正規のパケット数です。この 値は、鍵を更新する前に保護できるパケット数の 上限です。

v:

エンドポイントが受け入れる偽造パケット数です。この 値は、鍵を更新する前にエンドポイントが拒否できる 偽造パケット数の上限です。

o:

攻撃者が行うオフラインの理想暗号クエリの量です。

以下の分析は、各メッセージの生成に 関与するブロック操作数の計数に依存します。この分析は、最大 211(l = 27)および216(l = 212)のサイズのパケットについて行います。211というサイズは、 一般的なデプロイメントパターンに一致する制限と予想される一方、216は QUICパケットで可能な最大 サイズです。パケットサイズを厳密に制限するエンドポイントだけが、 より小さいパケットサイズを使用して導出された、より大きな機密性および完全性の制限を使用できます。

AEAD_AES_128_GCMおよびAEAD_AES_256_GCMでは、メッセージ長(l)は、 ブロック単位のassociated dataの長さと、ブロック単位の平文の長さの合計です。

AEAD_AES_128_CCMでは、ブロック暗号操作の総数は、 ブロック単位のassociated dataの長さ、ブロック単位の 暗号文の長さ、ブロック単位の平文の長さに1を加えた合計です。この 分析では、これをブロック単位のパケット長の2倍という値に簡略化します (すなわち、211バイトに制限されたパケットでは 2l = 28、それ以外では2l = 213)。この 簡略化は、パケットがassociated dataと 暗号文をすべて含むことに基づいています。その結果、パケットあたりの 操作数は1から3ブロック過大評価されます。

B.1. AEAD_AES_128_GCMおよびAEAD_AES_256_GCMの使用制限の分析

[GCM-MU]は、TLS 1.3およびQUICで 使用されるAEAD_AES_128_GCMおよびAEAD_AES_256_GCMについて具体的な境界を 規定しています。このセクションでは、いくつかの 単純化した仮定を用いてこの分析を記載します。

  • 攻撃者が偽造試行に使用する暗号文ブロック数は、 v * l、すなわち偽造試行回数に 各パケットのサイズ(ブロック単位)を乗じた値で上限付けされます。
  • 攻撃者が行うオフライン作業の量は、 分析内の他の要因を支配しません。

[GCM-MU]の境界は、 [AEBounds]で使用されるものより 厳密かつ完全であり、[TLS13]で説明されているものよりも 大きな制限を許容します。

B.1.1. 機密性の 制限

機密性について、[GCM-MU]の定理(4.3)は、nonceを再利用しない単一の ユーザーについて、実際のAEADアルゴリズムとランダムなAEADアルゴリズムを 区別する際に攻撃者が得る優位性を決定する支配的な項が次であることを示しています。

2 * (q * l)^2 / 2^n

目標とする優位性を2-57とすると、次の 関係が得られます。

q <= 2^35 / l

したがって、211 バイトを超えるパケットを送信しないエンドポイントは、 攻撃者が目標値 2-57よりも大きな優位性を得ることなく、単一の接続で228個を超えるパケットを 保護できません。パケットサイズとして最大 216を許容するエンドポイントの制限は、代わりに223です。

B.1.2. 完全性の制限

完全性について、[GCM-MU]の定理(4.3)は、攻撃者が パケットの偽造に成功することで得る優位性が、次の値を超えないことを示しています。

(1 / 2^(8 * n)) + ((2 * v) / 2^(2 * n))
        + ((2 * o * v) / 2^(k + n)) + (n * (v + (v * l)) / 2^k)

目標は、この優位性を2-57に制限することです。 AEAD_AES_128_GCMでは、 この不等式の第4項が残りを支配するため、結果に 大きな影響を与えることなく他の項を除去できます。これにより、次の 近似が得られます。

v <= 2^64 / l

211バイトを超えるパケットから保護を解除しようとしない エンドポイントは、最大 257個のパケットについて保護解除を試行できます。処理する パケットのサイズを制限しないエンドポイントは、最大252個のパケットについて保護解除を試行できます。

AEAD_AES_256_GCMでは同じ項が支配的ですが、kの値が 大きいため、次の近似が得られます。

v <= 2^192 / l

これはAEAD_AES_128_GCMの制限より大幅に大きな値です。 ただし、この 文書では、どちらの制限も十分に大きいため、両方の関数に同じ制限を適用することを推奨します。

B.2. AEAD_AES_128_CCMの使用制限の分析

TLS [TLS13]および[AEBounds]は、AEAD_AES_128_CCMの使用 制限を規定していません。ただし、QUICとともに使用される任意のAEADには、 機密性と完全性の両方が維持されることを保証する使用制限が必要です。この セクションでは、その分析を記載します。

[CCM-ANALYSIS]を この分析の基礎として使用します。その分析結果を用いて、 [TLS13]で選択された値に基づく使用制限を導出します。

機密性について、[CCM-ANALYSIS]の定理2は、攻撃者が 理想的な擬似乱数置換(PRP)に対して得る識別上の優位性が、 次の値を超えないことを示しています。

(2l * q)^2 / 2^n

[CCM-ANALYSIS]の定理1における完全性制限では、同じ数のメッセージについて 攻撃者に厳密により大きな優位性を与えます。機密性の優位性と 完全性の優位性の目標が同じであるため、 定理1だけを考慮すれば十分です。

定理1は、攻撃者が 理想的なPRPに対して得る優位性が次の値を超えないことを示しています。

v / 2^t + (2l * (v + q))^2 / 2^n

tとnはいずれも128であるため、第1項は 第2項と比べて無視できるほど小さく、結果に大きな影響を与えることなくその項を除去できます。

これにより、暗号化と復号の両方の試行を、 機密性のみについての定理から得られるものと同じ制限で組み合わせる関係が得られます。 目標とする優位性を2-57とすると、次のようになります。

v + q <= 2^34.5 / l

q = vと設定することで、機密性と完全性の両方の 制限値を生成できます。したがって、パケットを211バイトに制限するエンドポイントでは、 機密性と完全性の両方の制限が226.5パケットとなります。パケットサイズを 制限しないエンドポイントでは、制限は221.5です。

貢献者

IETF QUIC Working Groupは、多くの 人々から多大な支援を受けました。以下の方々は、この 文書に実質的な貢献を行いました。

著者の連絡先

Martin Thomson (編集者)
Mozilla
Sean Turner (編集者)
sn3rd