AESのCTRモード(TLSとDTLS用)

AESのCTRモードはストリーム暗号が実現できたり、推奨されるモードに入っていたりする割にはCBCモードと違って情報が少ないのですが、IETFのドラフトにTLSの場合の話があったので、それを調べてみた時の各章ごとのメモです。

AES Counter Mode Cipher Suites for TLS and DTLS [draft-ietf-tls-ctr-01]

1. Introduction

AES-CTRモードの利点がいろいろ書かれている。

  • AES-CBCと比べて17〜32バイトお得になる。16バイト分はIVを明示的に送信する必要がなく*1、残りの1〜16バイト分はパディングが必要ないため。
  • 暗号データにランダムアクセスが可能となる。UDPを使ったDTLS*2の時に到着順を気にしなくてよくなる。
  • ランダムアクセス可能という性質を利用して処理の並列化が可能となる。
  • 一つの暗号アルゴリズムでストリームとブロックの両方のモードがサポートできる。

2. Terminology

'counter block'と'IV'という用語の説明なんだけどよく分からない。
counter blockはIPSecから、IVはTLSから持ってきた用語だと言ってる気がする。

3. Encrypting Records with AES Counter Mode

AES-CTRでは、擬似乱数暗号ストリームを生成して、それと平文のXORを取ることで暗号文を作成する。暗号ストリームは、128ビットのカウンターブロックに対して、AES暗号化を行うことで生成する。

カウンターブロックはTLSのレコードシーケンスに基づいて生成する。またDTLSの場合は、それに加えてepoch number(ChangeCipherSpecのたびにインクリメントされる値らしい。)を組み合わせて生成する。

暗号鍵とカウンターブロックの組は1回しか使ってはいけない*3。そのためカウンターブロックをどのような構成にするのかが重要になる

3.1.1. Encryption

平文を128ビットごとに区切って暗号化を行う。ただし最後のブロックは128ビットより小さくてもOKとする。

PT[i]:  暗号化されたブロック(128ビット)
CT[i]:  平文(128ビット)
CtrBlk: カウンターブロックの値

128ビットのブロックを暗号化するたびに、カウンターブロックの値をインクリメントする。ただし最後のブロックだけは128ビット未満の可能性がある。そこでカウンターブロックを暗号化した後、最後のブロックのビット数と同じビット数分だけ(恐らくLSBから)ビットを取り出して利用する。

3.1.3. Counter Block Construction

カウンターブロックをどのように構成するのかというお話。

128ビットのうち、左から48ビットはIVを使う。

  • client側から送信するものはclientの書き込みIVの右から48ビット。
  • server側から送信するものはserverの書き込みIVの左から48ビット。

次の64ビット(seq_num)はTLSのレコードシーケンスを使う。残りの16ビット(blk_ctr)はnetwork byte orderでブロックカウンターとして使う。

seq_numとblk_ctrTLSの1レコードごとに初期化される。またblk_ctrの初期値は1をセットする。

blk_ctrTLSの1レコードの最大値が2^14 + 1024バイトであり、blk_ctrは2^16 * 2^4バイト(128ビット) = 2^20バイトまでOKなのでオーバーフローすることはない。

(明確な説明がない気もするけど、blk_ctrは16バイト(1ブロック)を暗号化するたびにインクリメントするらしい。そして1レコードが終わったところで、seq_numをTLSのレコードシーケンスに合わせてインクリメント、blk_ctrの方はまた1に戻すという処理をするようだ。)

3.2. DTLS (Datagram Transport Layer Securityのこと)

先ほど(TLS)との違いは、シーケンス番号が48ビットになって、その代わりに16ビットのepochが入ってくること。

3.3. Padding

ストリーム暗号なのでパディングは必要ない。

3.4. Session Resumption

セッションを再利用するときのお話。よくわからんけど結果的にはキーやIVに同じ値が使われないから大丈夫ってことかな。

4. Design Rationale

カウンターブロックの別の構成方法として'record tag'を使う方法があるらしい。
TLSのレコードシーケンス番号なら暗黙的に知ってるからいいけど、record tagを導入する場合はそれを明示的にパケットに乗せる必要があるため、帯域的に無駄だと言いようだ。

5. Security Considerations

セキュリティ上の注意点*4

  • 同じカウンターブロックと鍵の組み合わせの使用は一度だけにすること。(DTLSで同じレコードを再送する場合も安全だと言ってるけど、DTLSを調べていないので良く分かりません。)
  • 読み込みと書き込みで違う鍵を生成した後であればサーバとクライアントでカウンターブロックが重なってもOKらしい。(これって一つ目の条件をクリアーしてるよってことを言いたいのかな?)
  • ストリーム暗号は改ざんが簡単。でもTLSではMACを使ってるから気にする必要はない。

5.1. Maximum Key Lifetime

AES-CTRを利用する場合、シーケンスナンバーがリピートする前に鍵を再生成しなければならない(シーケンスナンバーがリピートすると同じ鍵とシーケンスナンバーの組み合わせになってしまう*5。)。1セッション当りTLSでは2^64、DTLSでは2^48が最大値となる。

*1:IVってsecretから生成すると思ってたんだけど違うのかな?(追記)どうやらTLS1.1でレコードにIVが追加されたらしい。

*2:Datagram TLSというUDP版のTLSのことらしい

*3:そのため1回暗号化するたびにカウンターブロックの値を変える必要があります。

*4:これは利用者向けというよりは、プロトコルの評価的な意味合いのようです。

*5:WEPは鍵が固定なのでこれと同じ理由で死んだのですね。