5 <- index ->7


6. TLS レコードプロトコル English

TLS レコードプロトコルは、層状のプロトコルである。各層において、メッセージは、length、description および content用のフィールドを含む可能性がある。レコードプロトコルは、転送されるべき メッセージを得て、そのデータを管理可能な blocks に分解し、オプションとして、そのデータを圧縮し、MAC を適用し、 暗号化し、その結果を転送する。受信されたデータは、復号され、検証され、解凍(decompress)され、再構成(reassemble)され、そして、高位層クライアント宛に配られる。

レコードプロトコルを使う 4 つのプロトコルは、本書中に記述されている。: ハンドシェイクプロトコル、アラートプロトコル、change cipher spec プロトコル、および、アプリケーションデータプロトコル。TLS プロトコルの拡張を許容するために、追加的なレコードコンテンツ種別が、レコードプロトコルによってサポートされる可能性がある。 IANA によって、新しい レコード content type 値が、12 節に記述されているように TLS Content Type Registry 中に割り当てられた。

実装は、何らかの拡張によって交渉されない限り、本書中に定義されていないレコード種別を送ってはならない(MUST NOT)。ある TLS 実装が予期していなかったレコード種別を受け取る場合、これは、unexpected_message アラートを送らなければならない(MUST)

TLS 上において利用するように設計された、あらゆるプロトコルは、それに対する、すべての可能性ある攻撃を扱うために注意深く設計されなければならない。実際問題として、これは、「そのプロトコル設計者は、『どのセキュリティ属性を TLS が提供し、そして提供しないか、さらに、後者に依存できないこと』を認識しておかなければならないこと」を意味する。

「レコードの種別と長さは、暗号化によって防護されていないこと」に特に注意。この情報自体が取扱注意である場合、アプリケーション設計者は、情報漏洩を最小化するためのステップ(パディング、トラフィックの隠喩(cover))を踏むことを望む可能性がある。

6.1. コネクション状態 English

TLS コネクション状態は、TLS レコードプロトコルの運用環境である。これは、圧縮アルゴリズム、暗号化アルゴリズムおよび MAC アルゴリズムを規定する。さらに、これらのアルゴリズム用のパラメータは、既知となる。: read および write の双方向の MAC 鍵およびバルク暗号化鍵の両方におけるコネクション用がある。理論的には、常に、重要な(outstanding)4 つのコネクション状態がある。: 現在の read 状態と write 状態、および、保留中の read 状態と write 状態がある。すべてのレコードは、現在の read および write 状態のもとで処理される。その保留(pending)状態用のセキュリティパラメータは、TLS Handshake プロトコルによってセットされる可能性がある。そして、ChangeCipherSpec は、両方の保留(pending)状態を選択的に current にできる。この場合、適切な現在の状態 が処理され(disposed)、保留(pending)状態に書き換えられる。; 次に、その保留(pending)状態は、空の状態に再初期化される。セキュリティパラメータで初期化されていない状態を現在の状態にすることは、不正である。当初の、現在の状態は、常に、「暗号化、圧縮もしくは MAC は、使われない」と規定する。

TLS コネクション の read と write 状態用のセキュリティパラメータは、下記の値を提供することによってセットされる。:

connection end
  「この主体は、このコネクションにおける "client" もしくは "server"と見なされるか否か?」(を示す)。

PRF algorithm
 

鍵を、その master secret (5 節6.3 節を参照)から生成するために使われるアルゴリズム。


bulk encryption algorithm
 

バルク暗号化用に使われるべきアルゴリズム。この仕様は、このアルゴリズムの鍵長、これがブロックであるか/ストリームであるか/AEAD cipher であるか、(適切な場合)その cipher のブロック長、および、明示的(explicit)および黙示的(implicit)な初期化ベクトル(もしくは nonces)
の長さを含む。


MAC algorithm
  メッセージ認証用に使われるアルゴリズム。この仕様は、MAC アルゴリズムによって返される値の大きさを含む。

compression algorithm
  データ圧縮用に使われるべきアルゴリズム。この仕様は、そのアルゴリズムが圧縮するために要求する、すべての情報を含まなければならない。

master secret
  コネクション中の 2 ピア間で共有された 48 byte の secret。

client random
  そのクライアントによって提供された 32 byte 値。

server random
 
そのサーバによって提供される 32 byte 値。
 
これらのパラメータは、下記のように
the presentation language で定義される。: enum { server, client } ConnectionEnd;enum { tls_prf_sha256 } PRFAlgorithm; enum { null, rc4, 3des, aes } BulkCipherAlgorithm; enum { stream, block, aead } CipherType; enum { null, hmac_md5, hmac_sha1, hmac_sha256, hmac_sha384, hmac_sha512} MACAlgorithm; enum { null(0), (255) } CompressionMethod; /* CompressionMethod、PRFAlgorithm、BulkCipherAlgorithm 中に規定されたアルゴリズム。
そして、MACAlgorithm が、加えられる可能性がある。*/ struct { ConnectionEnd entity; PRFAlgorithm prf_algorithm; BulkCipherAlgorithm bulk_cipher_algorithm; CipherType cipher_type; uint8 enc_key_length; uint8 block_length; uint8 fixed_iv_length; uint8 record_iv_length; MACAlgorithm mac_algorithm; uint8 mac_length; uint8 mac_key_length; CompressionMethod compression_algorithm; opaque master_secret[48]; opaque client_random[32]; opaque server_random[32]; } SecurityParameters;

レコード層は、下記の 6 項目を生成するためのセキュリティパラメータを使う。(これらのいくつかは、すべての暗号によって要求されるわけではないので、空である。):

  client write MAC 鍵
server write MAC 鍵
client write 暗号化鍵
server write 暗号化鍵
client write IV
server write IV

クライアントの write パラメータは、レコードを受け取って処理するとき、そのサーバーによって使われる。そして、逆のときもまた同様です。セキュリティパラメータから、これらの項目を生成するために使われるアルゴリズムは、6.3 節 に記述されている。

ひとたびセキュリティパラメータが生成され、その鍵が生成されると、そのコネクション状態は、それらを現在の状態にすることによって例示される可能性がある。これらの現在の状態は、処理される各レコードについて更新されなければならない(MUST)。各コネクション状態は、下記の要素を含む。:

compression state

  圧縮アルゴリズムの現在の状態。

cipher state
  暗号化アルゴリズムの現在の状態。これは、そのコネクション用にスケジュールされた鍵から成る。ストリーム暗号について、これは、「データを暗号化もしくは復号することを続けるために、その stream を許容する状態情報が必要不可欠であるか否か?」も収める。

MAC key
  上記のように生成されたコネクション用の MAC 鍵。

sequence number
 

各コネクション状態は、シーケンス番号を含み、これは、read 状態用と write 状態用に分離して維持管理される。シーケンス番号は、コネクション状態が active state とされたときは常にゼロにセットされなければならない(MUST)。シーケンス番号は、type uint64 であり、2^64-1 を越えてはいけない。シーケンス番号は、包まない。TLS 実装がシーケンス番号を包む(wrap)ことを必要とする場合、これは、代わりに再交渉しなければならない。シーケンス番号は、各レコード後に増加される。: 具体的には、 ある特定の コネクション 状態のもとで転送された最初のレコードは、シーケンス番号として 0 を使わなければならない(MUST)


6.2. レコード層 English

TLS レコード層は、uninterpreted データを任意の長さの空でないブロック中の高位層から受け取る。

6.2.1. Fragmentation English

レコード層は、情報ブロックを、データを 2^14 byte 以下の chunks にして運ぶ TLSPlaintext レコードに分解する。クライアントメッセージ境界は、レコード層中に確保されていない。(すなわち、同一の ContentType をもつ複数のクライアントメッセージが、単一の TLSPlaintext レコードに結合される可能性がある(MAY)か、あるいは、単一のメッセージは、いくつかのレコードに跨るように分解される可能性がある(MAY)。)

   struct {
       uint8 major;
       uint8 minor;
   } ProtocolVersion;

   enum {
       change_cipher_spec(20), alert(21), handshake(22),
       application_data(23), (255)
   } ContentType;

   struct {
       ContentType type;
       ProtocolVersion version;
       uint16 length;
       opaque fragment[TLSPlaintext.length];
   } TLSPlaintext;
type
 

符号化されたフラグメントを処理するために使われる上位層プロトコル。


version
 

採用されたプロトコルのバージョン。本書は、TLS バージョン 1.2 を記述しており、これは、バージョン { 3, 3 } を使う。バージョン値 3.3 は、TLS 1.0 について {3, 1} が利用されたことから導かれる経緯上のものである。(Appendix A.1.参照)TLS の複数バージョンをサポートするクライアントは、「ServerHello を受信する前に、どのバージョンが採用されるか?」を知らない可能性があることに注意。「どのレコード層のバージョン番号が、ClientHello について採用される必要があるか?」についての検討については、Appendix E 参照。


length
  下記の TLSPlaintext.fragment の長さ(byte 単位)。その長さは、2^14 を越えてはならない(MUST NOT)

fragment
  アプリケーションデータ。このデータは、透過的であり、type フィールドによって規定された高位層プロトコルによって扱われるべき、独立したブロックとして扱われる。

実装は、Handshake、Alert もしくは ChangeCipherSpec content 種別のゼロ長フラグメントを送らなければならない(MUST NOT)。アプリケーションデータ の Zero-length の断片は、潜在的にトラフィック分析対策として有用であるので、送られる可能性がある(MAY)

注: 異なる TLS レコード層 content 種別のデータが挿入(interleave)される可能性がある(MAY)。アプリケーションデータ は、一般に、転送について、他のコンテンツ種別よりも優先度が低いものである。しかし、レコードは、そのネットワーク宛に、レコード層によって守られているのと同じ順に配信されなければならない(MUST)。受信者は、コネクション時の最初の handshake以降の handshakes との間に、interleaved アプリケーション層トラフィックを受信して処理しなければならない(MUST)

6.2.2. レコードの圧縮および Decompression English

すべてのレコードは、現在のセッション状態中に定義された圧縮アルゴリズムを使って圧縮される。常に、アーカイブ圧縮アルゴリズムが存在する。; しかし、最初、これは、CompressionMethod.null として定義される。その圧縮アルゴリズムは、TLSPlaintext 構造体を TLSCompressed 構造体に翻訳する。圧縮関数は、コネクション状態が active にされるときは常にデフォルト状態情報に初期化される。[RFC3749] は、TLS についての圧縮アルゴリズムを記述する。

圧縮は、ロスレス(lossless)でなければならず、そのコンテンツの長さを 1024 byte 以上、増やさない可能性がある。その解凍(decompression)関数が 2^14 byte を越える長さに解凍される TLSCompressed.fragment に遭遇する場合、それは、fatal 解凍(decompression)失敗エラーを報告しなければならない(MUST)

   struct {
       ContentType type;       /* same as TLSPlaintext.type */
       ProtocolVersion version;/* same as TLSPlaintext.version */
       uint16 length;
       opaque fragment[TLSCompressed.length];
   } TLSCompressed;
length
  下記の TLSCompressed.fragment の長さ(in bytes)。その長さは、2^14 + 1024 を越えてはならない(MUST NOT)

fragment
 

TLSPlaintext.fragment の圧縮された形態。
注: CompressionMethod.null 操作は、identity 操作である。; 改変されたフィールドは、無い。

実装上の注意: 解凍(Decompression)関数は、「メッセージは、内部バッファの overflows を起こしえないこと」を確保することについて責任を負う。

6.2.3. レコード Payload 防護 English

  暗号化 および MAC 関数は、TLSCompressed structure を TLSCiphertext に翻訳する。その復号関数は、その過程を逆にする。そのレコードの MAC は、消失したメッセージ、余計なメッセージあるいは置き換えられたメッセージを検知可能となるように、シーケンス番号も含む。
   struct {
       ContentType type;
       ProtocolVersion version;
       uint16 length;
       select (SecurityParameters.cipher_type) {
           case stream: GenericStreamCipher;
           case block:  GenericBlockCipher;
           case aead:   GenericAEADCipher;
       } fragment;
   } TLSCiphertext;
type
  type フィールドは、TLSCompressed.type と同一である。

version
  version フィールドは、TLSCompressed.version と同一である。

length
  下記の TLSCiphertext.fragment の長さ(in bytes)。長さは、
2^14 + 2048 を越えてはならない(MUST NOT)

fragment
  TLSCompressed.fragment, with the MAC
の暗号化された form。

6.2.3.1. Null もしくは標準ストリーム暗号 English

ストリーム暗号(BulkCipherAlgorithm.null を含む。; Appendix A.6 参照)は、TLSCompressed を変換する。構造体に/から stream TLSCiphertext を/に分解する

   stream-ciphered struct {
       opaque content[TLSCompressed.length];
       opaque MAC[SecurityParameters.mac_length];
   } GenericStreamCipher;

MAC は、下記のように生成される。:

   MAC(MAC_write_key, seq_num +
                         TLSCompressed.type +
                         TLSCompressed.version +
                         TLSCompressed.length +
                         TLSCompressed.fragment);

ここで "+" は、連結を表す。

seq_num
  このレコードについてのシーケンス番号。

MAC
 

SecurityParameters.mac_algorithm
によって規定された MAC アルゴリズム。

「その MAC は、暗号化前に計算される。そのストリーム暗号は、その MAC を含むブロック全体を暗号化すること」に注意。(RC4 のような) 同期化(synchronization)ベクトルを使わないストリーム暗号について、あるレコードの終端からのストリーム暗号状態は、単に以降のパケット上で使われる。その cipher suite が TLS_NULL_WITH_NULL_NULL である場合、暗号化は、その identity 操作から成る。(すなわち、そのデータは、暗号化されず、そして、その MAC 長は、ゼロであり、「MAC は、使われないこと」を意味する。)null とストリーム暗号の両方について、TLSCiphertext.length は、TLSCompressed.length + SecurityParameters.mac_length である。

6.2.3.2. CBC ブロック暗号 English

(3DES もしくは AESのような)ブロック暗号について、その暗号化および MAC 関数は、TLSCompressed.fragment 構造体(を/から)block TLSCiphertext.fragment 構造体に変換する。

   struct {
       opaque IV[SecurityParameters.record_iv_length];
       block-ciphered struct {
           opaque content[TLSCompressed.length];
           opaque MAC[SecurityParameters.mac_length];
           uint8 padding[GenericBlockCipher.padding_length];
           uint8 padding_length;
       };
   } GenericBlockCipher;

その MAC は、 6.2.3.1節に記述されているように生成される。

IV
  IV(Initialization Vector)は、ランダムに選択される必要がある(SHOULD)。そして、予測不能でなければならない(MUST)。「TLS の 1.1 より前のバージョンにおいて、IV フィールドは無かったことと、レコードの最後の ciphertext block((the "CBC residue")が、その IV として使われていたこと」に注意。これは、[CBCATT] 中に記述された攻撃を予防するために変更された。ブロック暗号について、IV 長は、SecurityParameters.record_iv_length の長さである。これは、SecurityParameters.block_size と等しい。

padding
 

その plaintext の長さを、そのブロック暗号のブロックの長さの整数倍となることを強制するために加えられた Padding。その padding は、 TLSCiphertext.length が必須の、そのブロック長の倍数となる限り、255 byte を上限とするあらゆる長さである可能性がある(MAY)。必要不可欠な長さ以上の長さは、交換されたメッセージの長さの解析に基づくプロトコルに対する攻撃を失敗させる(frustrate)ために渇望される可能性がある。その padding データベクトル中の各 uint8 は、その padding 長値で埋められなければならない(MUST)。その受信者は、この padding をチェックしなければならない(MUST)。そして、padding エラーを示すために bad_record_mac alert を使わなければならない(MUST)


padding_length
 

padding length は、GenericBlockCipher 構造体の全長が、その cipher のブロック長の倍数であるものでなければならない(MUST)。正規の(Legal)値は、ゼロから 255 に渡る。この長さは、padding_length フィールド自体を除く padding フィールドの長さを規定する。

暗号化されたデータ長(TLSCiphertext.length)は、SecurityParameters.block_length、TLSCompressed.length、SecurityParameters.mac_length および padding_length 等と同列以上の項目である。

例: ブロック長が 8 byte であり、その content 長(TLSCompressed.length)が 61 byte であり、かつ、その MAC 長が 20 byte である場合、padding 前の長さは、82 byte(これは、IV を含まない)となる。それゆえ、パディング長 modulo 8 は、その総長を 8 byte (そのブロック長)の倍数と等しくなるようにするために 6 と等しくなければならない。そのパディング長は、6, 14, 22 等 254 までである可能性がある。そのパディング長が最小値(必ず 6)であった場合、そのパディングは、各々 6 という値を収める 6 byte となる。それゆえ、ブロック暗号化前の GenericBlockCipher の最後の 8 octet は、xx 06 06 06 06 06 06 06 となり、ここで、xx は、その MAC の最後の octet である。

注意: CBC(Cipher Block Chaining)モードのブロック暗号について、「そのレコードが、いかなる ciphertext の前に知られている plaintext 全体が転送されること」は、重要である。さもなければ、その攻撃者が [CBCATT] 中に記述された攻撃を放つ可能性がある。

実装上の注意: Canvel ら [CBCTIME] は、その MAC を計算するために要する時間に基づく CBC padding についてのタイミング攻撃を実証した。この攻撃を防ぐために、実装は、「レコード処理時間は、その padding が正しいか否かに関わらず、本質的には同じこと」を確保しなければならない(MUST)。一般に、これを行う最善の方法は、たとえその padding が不正であり、そのときのみパケットを棄却する場合でも、その MAC を計算することである。例えば、その pad が誤っているように見える場合、その実装は、ゼロ長の pad と見なし、その MAC を計算する可能性がある。これは、小さなタイミングチャネルを残す。なぜならば、MAC の性能は、そのデータフラグメントの大きさに、ある程度、依存するからである。しかし、存在する MAC の大きなブロックサイズと、そのタイミング信号の小ささに起因して、攻略されることは、十分に大きい問題とは信じられていない。

6.2.3.3. AEAD 暗号 English

AEAD [AEAD] 暗号(例: [CCM] もしくは [GCM])について、AEAD 関数は、TLSCompressed.fragment 構造体に(/から) AEAD TLSCiphertext.fragment 構造体から(/に)変換する。

   struct {
      opaque nonce_explicit[SecurityParameters.record_iv_length];
      aead-ciphered struct {
          opaque content[TLSCompressed.length];
      };
   } GenericAEADCipher;

AEAD ciphers は、[AEAD] の 2.1 節 に記述されているように、input として、単一の鍵、nonce、plaintext および認証(authentication)チェック中に含められる "additional data" を取る。その鍵は、client_write_key か、server_write_key のいずれかである。MAC 鍵は、使われない。

各 AEAD cipher suite は、「どのように、その AEAD 操作に提供される nonce は、構築されるか?」および 「GenericAEADCipher.nonce_explicit part の長さは、どれだけか?」を規定しなければならない(MUST)。多くの場合において、[AEAD] の 3.2.1 節 に記述されている部分的に黙示的な(implicit) nonce テクニックを(明示的(explicit)な部分の長さである record_iv_length と共に)使うことは、適切である。この場合、その黙示的(implicit)な部分は、(6.3 節に記述されているように)key_block から client_write_iv および server_write_iv として取得される必要がある(SHOULD)。そして、その明示部分は、GenericAEAEDCipher.nonce_explicit 中に含められる。

その plaintext は、TLSCompressed.fragment である。

我々が additional_data と表記している追加的な認証された(authenticated)データは、下記のように定義される。:

   additional_data = seq_num + TLSCompressed.type +
                     TLSCompressed.version + TLSCompressed.length;

ここで、"+" は、連結(concatenation)を意味する。

aead_output は、その AEAD 暗号化操作による ciphertext output から成る。その長さは、一般に、TLSCompressed.length より大きくなるが、AEAD cipher によって変化する量による。その暗号は、padding を組み込む(incorporate)可能性があるので、オーバーヘッドの量は、異なる TLSCompressed.length 値に応じて多様である可能性がある。各 AEAD cipher は、1024 byte より大きな拡張を作り出してはならない(MUST NOT)
Symbolically,

   AEADEncrypted = AEAD-Encrypt(write_key, nonce, plaintext, additional_data)

復号し、検証するために、その暗号(cipher)は、input として、その鍵、nonce、"additional_data" および AEADEncrypted 値を要する。その output は、plaintext か、あるいは、復号が失敗したことを示すエラーのいずれかである。別々の integrity チェックは無い。すなわち、下記のとおり。:

   TLSCompressed.fragment = AEAD-Decrypt(write_key, nonce,
                                         AEADEncrypted,
                                         additional_data)

その復号が失敗する場合、fatal bad_record_mac alert が生成されなければならない(MUST)

6.3. 鍵 Calculation English

レコードプロトコルは、現在のコネクション状態によって要求される鍵(Appendix A.6参照)を、ハンドシェイクプロトコルによって提供されるセキュリティパラメータから生成するためのアルゴリズムを要する。

master secret は、secure bytes のシーケンスに拡張される。次に、これは、client write MAC 鍵、server write MAC 鍵、client write 暗号化鍵および
server write 暗号化鍵に分割される。これらの各々は、その順に、そのバイトシーケンスから生成される。Unused 値は、空である。AEAD cipher には、client write IV および server write IV(6.2.3.3 節を参照)を追加的に要求する可能性があるものがある。

鍵および MAC 鍵が生成されるとき、その master secret は、エントロピーの源泉として使われる。

その鍵とする素材を生成するために、十分な output が生成されるまで下記を計算する。

   key_block = PRF(SecurityParameters.master_secret,
                   "key expansion",
                   SecurityParameters.server_random +
                   SecurityParameters.client_random);

そして、key_block は、下記のように分割される。:

   client_write_MAC_key[SecurityParameters.mac_key_length]
   server_write_MAC_key[SecurityParameters.mac_key_length]
   client_write_key[SecurityParameters.enc_key_length]
   server_write_key[SecurityParameters.enc_key_length]
   client_write_IV[SecurityParameters.fixed_iv_length]
   server_write_IV[SecurityParameters.fixed_iv_length]

現在、client_write_IV と server_write_IV は、[AEAD] の 3.2.1 節中に記述されているように黙示的(implicit)nonce テクニック用にのみ生成される。

実装上の注意: 最も素材を要する、現在定義されている cipher suite は、AES_256_CBC_SHA256 である。これは、計 128 byte の鍵とする素材用に 2 x 32 byte 鍵および 2 x 32 byte MAC 鍵を要する。

 


5 <- index -> 7