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

4.2. Sequence Number and Epoch (シーケンス番号とエポック)

4.2. Sequence Number and Epoch (シーケンス番号とエポック)

DTLSは, 暗黙的なシーケンス番号ではなく, レコードのsequence_numberフィールドに格納される明示的または部分的に明示的なシーケンス番号を使用します。シーケンス番号は各エポックごとに個別に維持され, 各エポックの各sequence_numberの初期値は0です。

エポック番号は最初はゼロであり, キーイングマテリアルが変更され送信者が再キーイングを目指すたびに増分されます。詳細は第6.1節で提供されます。

4.2.1. Processing Guidelines (処理ガイドライン)

DTLSレコードは並べ替えられる可能性があるため, エポックMからのレコードがエポックN (ここでN > M)が始まった後に受信される可能性があります。実装は以前のエポックからのレコードを破棄すべきですが, パケットの並べ替えを許可するために, TCP [RFC0793]に指定されているデフォルトのMSLまで以前のエポックからのキーイングマテリアルを保持することを選択してもかまいません。(ここでの意図は, 実装者がシステムのTCPスタックが使用しているMSLを調べようとするのではなく, [RFC0793]またはその後継で指定されているIETFからのMSLに関する現在のガイダンスを使用することです。)

逆に, 新しいエポックで保護されたレコードがハンドシェイクの完了前に受信される可能性があります。たとえば, サーバーはFinishedメッセージを送信してからデータの送信を開始する場合があります。実装はそのようなレコードをバッファリングまたは破棄してもかまいませんが, DTLSが信頼できるトランスポート上で使用される場合(たとえば, SCTP [RFC4960]), ハンドシェイクが完了したらそれらをバッファリングして処理すべきです。TLSのレコードをいつ送信できるかに関する制限は引き続き適用され, 受信者はレコードが正しい順序で送信されたかのように扱います。

実装は, 元の送信と同じエポックおよびキーイングマテリアルを使用して失われたメッセージの再送信を送信しなければなりません。

実装は, シーケンス番号のラップを許可する前にアソシエーションを放棄するか, 再キーイングしなければなりません。

実装はエポックのラップを許可してはならず, 代わりに古いアソシエーションを終了して新しいアソシエーションを確立しなければなりません。

4.2.2. Reconstructing the Sequence Number and Epoch (シーケンス番号とエポックの再構築)

保護されたDTLSレコードを受信する場合, 受信者はレコード内に完全なエポックまたはシーケンス番号値を持たないため, 曖昧さが生じる可能性があります。完全なシーケンス番号はレコードごとのnonceの計算に使用され, エポックがキーを決定するため, これらの値の再構築に失敗するとレコードの保護解除に失敗します。したがって, 実装は完全な値を決定するために選択したメカニズムを使用してもかまいません。このセクションでは, 比較的単純なアルゴリズムを提供し, 実装がこのアルゴリズムに従うことを推奨します。

エポックビットが現在のエポックのビットと一致する場合, 実装は現在のエポックで最も高い正常に保護解除されたレコードのシーケンス番号に1を加えたものに数値的に最も近い完全なシーケンス番号を計算することでシーケンス番号を再構築すべきです。

ハンドシェイクフェーズ中, エポックビットは使用する正しいキーを明確に示します。ハンドシェイクが完了した後, エポックビットが現在のエポックのビットと一致しない場合, 実装は一致するビットを持つ最も最近の過去のエポックを使用し, 上記のようにそのエポックのシーケンス番号を再構築すべきです。

4.2.3. Record Number Encryption (レコード番号の暗号化)

DTLS 1.3では, レコードが暗号化されると, レコードシーケンス番号も暗号化されます。基本パターンは, AEADアルゴリズムと共に使用される基礎となる暗号化アルゴリズムを使用してマスクを生成し, そのマスクとシーケンス番号をXORすることです。

AEADがAESベースの場合, 暗号文の最初の16バイトでAES-ECBを計算することでマスクが生成されます:

Mask = AES-ECB(sn_key, Ciphertext[0..15])

AEADがChaCha20ベースの場合, 暗号文の最初の4バイトをブロックカウンターとして扱い, 次の12バイトをnonceとして扱い, それらをChaCha20ブロック関数(CHACHAの第2.3節)に渡すことでマスクが生成されます:

Mask = ChaCha20(sn_key, Ciphertext[0..3], Ciphertext[4..15])

sn_keyは次のように計算されます:

[sender]_sn_key = HKDF-Expand-Label(Secret, "sn", "", key_length)

[sender]は送信側を表します。使用するエポックごとのSecret値は[TLS13]の第7.3節で説明されています。各エポックに新しいキーが使用されることに注意してください。エポックは平文で送信されるため, これは曖昧さをもたらしません。

暗号化されたシーケンス番号は, マスクの先頭バイトとシーケンス番号のワイヤー上の表現をXORすることで計算されます。復号化は同じプロセスで実現されます。

この手順では, 暗号文の長さが少なくとも16バイトである必要があります。受信者は, 第4.5.2節で説明されているように, より短いレコードを保護解除に失敗したかのように拒否しなければなりません。送信者は, 適切な長さの暗号文を作成するために, (従来のレコードパディングメカニズムを使用して)短い平文をパディングしなければなりません。ほとんどのDTLS AEADアルゴリズムには16バイトの認証タグがあり, パディングは不要です。ただし, TLS_AES_128_CCM_8_SHA256などの一部のアルゴリズムには短い認証タグがあり, 短い入力にはパディングが必要になる場合があります。

AESまたはChaCha20に基づいていない将来の暗号スイートは, DTLSで使用するために独自のレコードシーケンス番号暗号化を定義しなければなりません。

シーケンス番号の暗号化は, DTLSCiphertext構造にのみ適用され, DTLSPlaintext構造には適用されないことに注意してください。DTLSPlaintext構造にもシーケンス番号が含まれていますが。