メインコンテンツまでスキップ

6. 鍵更新 (Key Update)

ハンドシェイクが確認されると(セクション 4.1.2 参照)、エンドポイントは鍵更新を開始してもよいです (MAY)。

鍵フェーズビット (Key Phase bit) は、パケットの保護に使用されるパケット保護鍵を示します。鍵フェーズビットは、最初の 1-RTT パケットのセットでは最初に 0 に設定され、後続の各鍵更新を示すために切り替わります。

鍵フェーズビットにより、受信者は鍵材料の変更を検出できます。変更を含むパケットを受信する必要はありません。鍵フェーズビットの変更に気付いたエンドポイントは、鍵を更新し、変更された値を含むパケットを復号化します。

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

このメカニズムは、KeyUpdate メッセージの送信に依存する TLS の鍵更新メカニズムに代わるものです。KeyUpdate メッセージは 1-RTT 暗号化鍵を使用して送信されます。エンドポイントは TLS KeyUpdate メッセージを送信してはなりません (MUST NOT)。エンドポイントは、TLS KeyUpdate メッセージの受信を、unexpected_message 致命的 TLS アラートに相当する 0x010a タイプの接続エラーとして扱わなければなりません (MUST)(セクション 4.8 参照)。

図9は、鍵更新プロセスを示しています。最初に使用される鍵のセット(@M で識別)が更新された鍵(@N で識別)に置き換えられます。鍵フェーズビットの値は角括弧 [] で示されています。

開始者                      応答者

@M [0] QUIC パケット

... @N に更新
@N [1] QUIC パケット
-------->
@N に更新 ...
QUIC パケット [1] @N
<--------
QUIC パケット [1] @N
ACK を含む
<--------
... 鍵更新を許可

@N [1] QUIC パケット
@N パケットへの ACK を含む
-------->
鍵更新を許可 ...

図9: 鍵更新

6.1. 鍵更新の開始 (Initiating a Key Update)

エンドポイントは、パケット保護のために独立した読み取りおよび書き込みシークレットを維持します。エンドポイントは、パケット保護書き込みシークレットを更新し、それを使用して新しいパケットを保護することにより、鍵更新を開始します。エンドポイントは、[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)

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

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

| 注: 1-RTT パケット以外のパケットの鍵は更新されません。それらの鍵は完全に TLS ハンドシェイク状態から派生します。

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

エンドポイントは、新しい鍵を使用して送信されたパケットの保護を正常に解除するまで、古い鍵を保持しなければなりません (MUST)。エンドポイントは、新しい鍵を使用して送信されたパケットの保護を解除した後、一定期間古い鍵を保持すべきです (SHOULD)。古い鍵を早期に破棄すると、遅延パケットが破棄される可能性があります。パケットの破棄は、ピアによってパケット損失として解釈され、パフォーマンスに悪影響を与える可能性があります。

6.2. 鍵更新への応答 (Responding to a Key Update)

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

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

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

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

6.3. 受信鍵生成のタイミング (Timing of Receive Key Generation)

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

パケットを受信するための新しいパケット保護鍵を作成するプロセスは、鍵更新が発生したことを明らかにする可能性があります。エンドポイントは、パケット処理の一環として新しい鍵を生成してもよいですが (MAY)、これによりタイミング信号が作成され、攻撃者はそれを利用して鍵更新がいつ発生したかを知り、鍵フェーズビットの値を漏洩させることができます。

エンドポイントは通常、現在および次の受信パケット保護鍵を持つべきです。鍵更新が完了してから PTO まで短時間の間、エンドポイントは次のセットの受信パケット保護鍵の生成を延期してもよいです (MAY)。これにより、エンドポイントは2セットの受信鍵のみを保持できます(セクション 6.5 参照)。

生成されると、次のセットのパケット保護鍵は保持すべきであり (SHOULD)、受信したパケットがその後破棄されても同様です。明らかな鍵更新を含むパケットは簡単に偽造できますが、鍵更新プロセスには大きな労力を必要としませんが、このプロセスをトリガーすることは攻撃者によって DoS に使用される可能性があります。

したがって、エンドポイントは、パケットを受信するための2セットのパケット保護鍵(現在の鍵と次の鍵)を保持できなければなりません (MUST)。これらの鍵に加えて、以前の鍵を保持するとパフォーマンスが向上する可能性がありますが、これは必須ではありません。

6.4. 更新された鍵での送信 (Sending with Updated Keys)

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

より高いパケット番号を持つパケットは、より低いパケット番号を持つパケットと同じかそれより新しいパケット保護鍵を使用して保護されなければなりません (MUST)。エンドポイントが、より低いパケット番号を持つパケットに新しい鍵が使用されていることを検出した場合、古い鍵を使用して保護を正常に解除すると、これを KEY_UPDATE_ERROR タイプの接続エラーとして扱わなければなりません (MUST)。

6.5. 異なる鍵での受信 (Receiving with Different Keys)

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

次の鍵フェーズ鍵で保護されたパケットは、前の鍵フェーズ鍵で保護されたパケットと同じ鍵フェーズ値を使用するため、古い鍵で保護されたパケットを処理する必要がある場合は、2つを区別する必要があります。これはパケット番号によって行うことができます。復元されたパケット番号が現在の鍵フェーズのパケット番号より低い場合は、前のパケット保護鍵を使用します。復元されたパケット番号が現在の鍵フェーズのパケット番号より高い場合は、次のパケット保護鍵を使用する必要があります。

前の、現在、および次のパケット保護鍵を選択する任意のプロセスが、パケット保護の解除に使用された鍵を明らかにする可能性のあるタイミングサイドチャネルを公開しないように注意する必要があります。詳細については、セクション 9.5 を参照してください。

あるいは、エンドポイントは2セットのパケット保護鍵のみを保持し、ネットワークで順序が乱れた十分な時間が経過した後、前の鍵を次の鍵に置き換えることができます。この場合、鍵フェーズビットのみを使用して鍵を選択できます。

エンドポイントは、次のセットの受信鍵を現在の鍵に昇格させた後、約1プローブタイムアウト (PTO)([QUIC-RECOVERY] 参照)を許可してから、後続のパケット保護鍵のセットを作成してもよいです (MAY)。これらの更新された鍵は、その時点で以前の鍵を置き換えてもよいです (MAY)。PTO は主観的な測定であり、ピアは RTT について異なる見解を持つ可能性があることに注意してください。この期間は、確認応答されても順序が乱れたパケットがピアによって損失として宣言されるほど長く、ピアがさらなる鍵更新を開始できるほど短いことが期待されます。

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

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

6.6. AEAD 使用の制限 (Limits on AEAD Usage)

本文書は、QUIC で使用する際に過度の使用が攻撃者に通信の機密性と完全性を攻撃する上で不均衡な利点を与えないようにするために、AEAD アルゴリズムの使用制限を設定します。

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

QUIC は、AEAD の機密性と完全性の制限を個別に考慮します。機密性制限は、特定の鍵を使用して暗号化されたパケット数に適用されます。完全性制限は、特定の接続で復号化されたパケット数に適用されます。以下では、各 AEAD アルゴリズムのこれらの制限の実施について詳しく説明します。

エンドポイントは、各鍵セットの暗号化されたパケット数をカウントしなければなりません (MUST)。同じ鍵を使用して暗号化されたパケットの総数が、選択した AEAD の機密性制限を超える場合、エンドポイントはこれらの鍵の使用を停止しなければなりません (MUST)。エンドポイントは、選択した AEAD に許可された機密性制限を超える保護されたパケットを送信する前に、鍵更新を開始しなければなりません (MUST)。鍵更新ができない場合、または完全性制限に達した場合、エンドポイントは接続の使用を停止し、パケットを受信したときにのみステートレスリセットを送信しなければなりません (MUST)。エンドポイントは、鍵更新が不可能な状態に達する前に、AEAD_LIMIT_REACHED タイプの接続エラーを使用して接続を即座に閉じることが推奨されます (RECOMMENDED)。

AEAD_AES_128_GCM および AEAD_AES_256_GCM の場合、機密性制限は 2^23 暗号化パケットです(付録 B.1 参照)。AEAD_CHACHA20_POLY1305 の場合、機密性制限は可能なパケット数 (2^62) よりも大きいため、無視できます。AEAD_AES_128_CCM の場合、機密性制限は 2^21.5 暗号化パケットです(付録 B.2 参照)。制限を適用すると、攻撃者が使用された AEAD をランダム順列と区別できる確率が低下します([AEBounds]、[ROBUST]、[GCM-MU] 参照)。

送信されたパケットのカウントに加えて、エンドポイントは、接続の生存期間中に認証に失敗した受信パケットの数をカウントしなければなりません (MUST)。すべての鍵にわたる接続で認証に失敗した受信パケットの総数が、選択した AEAD の完全性制限を超える場合、エンドポイントは AEAD_LIMIT_REACHED タイプの接続エラーを使用して接続を即座に閉じ、パケットを処理しなくなる必要があります (MUST)。

AEAD_AES_128_GCM および AEAD_AES_256_GCM の場合、完全性制限は 2^52 無効パケットです(付録 B.1 参照)。AEAD_CHACHA20_POLY1305 の場合、完全性制限は 2^36 無効パケットです([AEBounds] 参照)。AEAD_AES_128_CCM の場合、完全性制限は 2^21.5 無効パケットです(付録 B.2 参照)。この制限を適用すると、攻撃者がパケットの偽造に成功する確率が低下します([AEBounds]、[ROBUST]、[GCM-MU] 参照)。

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

将来の分析と仕様により、AEAD の機密性または完全性の制限が緩和される可能性があります (MAY)。

QUIC で使用するように指定された TLS 暗号スイートは、機密性と完全性のマージンを維持するために、関連する AEAD 関数の使用制限を定義しなければなりません (MUST)。つまり、認証できるパケット数と認証に失敗できるパケット数の制限を指定しなければなりません (MUST)。値ベースの分析への参照(およびその分析で使用される仮定)を提供することで、異なる使用条件に基づいて制限を調整できます。

6.7. 鍵更新エラーコード (Key Update Error Code)

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