IoT Security 09 · サイドチャネル攻撃 — 消費電力から鍵が出てくる

Chapter 09

サイドチャネル攻撃 — 消費電力から鍵が出てくる

この章がなぜ必要なのか——「暗号が数学的に安全」でも、実装から漏れるから.

AES-256 の鍵空間は \(2^{256}\) で、総当たりは不可能である。 だが実装が動いている物理的な装置は、 演算内容に応じて消費電力・処理時間・電磁波を変化させる。

その変化を測ると、鍵が出てくる。 しかも、条件が整えば数分から数時間で。

この章で使う既出の用語(定義は各リンク先). デフォルトパスワード(01 章 5 節)、数万円(01 章 2 節)、不可能(04 章 3 節)、物理攻撃(04 章 6 節)、定時間比較(05 章 7 節)、サイドチャネル(07 章 8 節)、フォールト(07 章 8 節)、AES(08 章 8 節)、libsodium(08 章 7 節)、マスキング(08 章 6 節)

1. サイドチャネルとは何か

設計者が見ている経路と、実際に存在する経路平文暗号処理ここだけを守っている暗号文消費電力処理時間電磁放射音温度キャッシュ攻撃者はこれらを観測できるアルゴリズムが数学的に安全でも、実装が漏らす情報から鍵が求まる
暗号の強度は数学だけでは決まらない。実装が外に出してしまう副次的な情報が攻撃面になる
サイドチャネル観測方法必要な機材
処理時間応答時間を測るPC だけ(リモートでも可能な場合がある)
消費電力電源ラインに抵抗を入れて電圧を測るオシロスコープ(数万円〜)
電磁放射磁界プローブを近づけるプローブ + オシロ(非接触)
キャッシュ自分のアクセス時間から他プロセスの動作を推定ソフトウェアのみ(主に Cortex-A / PC)
フォールト応答誤り時の挙動の違い10 章

電磁放射による攻撃が実務的には厄介である.

チップに触れる必要がない。 パッケージの上にプローブを置くだけでよい。 基板を改造する必要も、電源ラインに介入する必要もない。

しかも空間分解能があるので、 「チップのこの部分だけ」を狙って観測できる。 AES エンジンの真上にプローブを置けば、ノイズの少ない波形が取れる。

2. タイミング攻撃 — 最も基本的で、最も見落とされる

典型的な脆弱コード

/* ★ 危険: 早期リターンする比較 */
int compare_mac(const uint8_t *a, const uint8_t *b, size_t len)
{
    for (size_t i = 0; i < len; i++) {
        if (a[i] != b[i]) return 0;     /* ← 一致しなくなった位置で抜ける */
    }
    return 1;
}

攻撃者は 1 バイトずつ MAC を復元できる。

タイミング攻撃 — 1 バイトずつ独立に破れてしまう11 バイト目を 0x00〜0xFF まで試す2正しい値のときだけ 2 バイト目の比較まで進む → その分だけ処理時間が長い(数十 ns)3何千回も測って平均を取ると、その差が見える → 1 バイト目が確定42 バイト目へ。以下同様1 バイトずつ独立に決められる256 × 16 = 4096 回16 バイトの MAC を破るのに必要な試行総当たりなら2¹²⁸ 回現実的に不可能な回数この差が「早期リターンする比較」を使ってはいけない理由
memcmp で MAC を比較してはいけない。定数時間比較(全バイトを必ず見る)を使う

定時間実装

/* ★ 正しい: 常に全バイトを比較し、実行時間が入力に依存しない */
int compare_mac_ct(const uint8_t *a, const uint8_t *b, size_t len)
{
    uint8_t diff = 0;
    for (size_t i = 0; i < len; i++) {
        diff |= (uint8_t)(a[i] ^ b[i]);      /* 差分を溜める */
    }
    return (diff == 0);                       /* 最後に 1 回だけ判定 */
}

定時間実装の原則:

原則内容
秘密値で分岐しないif (secret) { ... } を書かない
秘密値でメモリアドレスを決めないtable[secret] はキャッシュ攻撃の的になる
早期リターンしない常に同じ処理量を実行する
秘密値で除算しない除算命令は値によって時間が変わる CPU がある

既存ライブラリの定時間実装を使うこと.

自分で書かない。 特に「コンパイラが最適化で分岐を復活させる」ことがあり、 ソースが定時間でもバイナリが定時間とは限らない。

RSA と ECC のタイミング攻撃

素朴な冪乗計算(square-and-multiply)は、指数のビットが 1 か 0 かで処理が変わる。

for each bit of exponent:
    square();                   /* 常に実行する */
    if (bit == 1) multiply();   /* ★ ビットが 1 のときだけ実行する */

処理時間を測れば、指数(= 秘密鍵)のビット列が分かる。

対策:

対策内容
Montgomery ladderビットの値によらず常に同じ演算列を実行する
常時実行 (always-multiply)ビットが 0 でも掛け算し、結果を捨てる
ブラインディング秘密値をランダム値で撹乱してから演算する

3. 電力解析 — SPA と DPA

SPA(単純電力解析)

1 本の波形を見るだけで秘密が分かる場合がある。

SPA — 波形を 1 本見るだけで秘密指数が読める消費電流SSMSSMS01010S = 二乗のみ → 指数のビットは 0S + M = 二乗して乗算 → 指数のビットは 1「ビットが 1 のときだけ乗算する」実装は、波形の形がそのまま鍵になる
対策は「常に同じ処理をする」こと。モンゴメリラダーのように、ビットの値によらず同じ命令列を実行する

波形を目で見るだけで鍵のビット列が読める。 これは対策なしの素朴な実装で実際に起きる。

DPA(差分電力解析)— 本命

DPA — 「1 バイトずつ」試せることが本質的な弱さ波形を大量に収集数千〜数万本鍵 1 バイトを仮定256 通り中間値を予測鍵候補ごとに計算波形との相関を取る正解だけ相関が出る256 通り × 16 バイト = 4096 回の計算で 128 bit 鍵が求まる総当たり 2¹²⁸ とは比較にならない対策:マスキング・シャッフリング・ダミー演算・電源フィルタそして「DPA 対策済み」と明記されたエンジンを選ぶこと
鍵全体を一度に当てる必要がないのが DPA の怖さ。バイトごとに独立して検証できてしまう

SPA が効かない場合でも、統計的手法で鍵が取れる。

電力解析の原理を見る

漏洩モデルとノイズ、波形数を変えて、相関がどう立ち上がるかを確かめられる。

原理:

CMOS 回路の消費電力は、ビットが変化した数(ハミング距離)や 1 のビット数(ハミング重み)に比例する成分を持つ。

\[ P_{\text{測定}} = a \cdot \text{HW}(\text{中間値}) + b + \text{noise} \]

AES の場合、最初のラウンドの S-Box 出力が狙われる。

\[ v = \text{SBox}(p \oplus k) \]

ここで \(p\) は平文の 1 バイト(既知)、\(k\) は鍵の 1 バイト(未知、256 通り)。

攻撃の手順:

順やること
1ランダムな平文で暗号化させ、数百〜数万本の電力波形を記録する
2鍵バイトの候補 \(k'\) を 0〜255 のそれぞれについて、各波形の中間値 \(v = \text{SBox}(p \oplus k')\) を計算する
3その予測消費電力 \(\text{HW}(v)\) と、実測波形の各時点の値との相関係数を計算する
4正しい鍵バイトのときだけ、ある時点で相関が跳ね上がる
516 バイト分を独立に繰り返す
\[ \rho(k') = \frac{\sum_i (\text{HW}(v_i) - \overline{\text{HW}}) (P_i - \overline{P})} {\sqrt{\sum_i (\text{HW}(v_i) - \overline{\text{HW}})^2} \sqrt{\sum_i (P_i - \overline{P})^2}} \]

ここが決定的に重要である: 探索空間が掛け算にならない.

AES-128 の鍵は 16 バイト。総当たりなら \(256^{16} = 2^{128}\) 通り。

だが DPA では、16 バイトを 1 バイトずつ独立に求められる。 必要な試行は \(256 \times 16 = 4096\) 通りの計算だけである。

\[ 2^{128} \quad \longrightarrow \quad 4096 \]

これが「暗号が数学的に強くても実装で破れる」の意味である。

必要な波形数の目安

実装波形数の目安
対策なしのソフトウェア AES数百〜数千本
対策なしのハードウェア AES数千〜数万本
1 次マスキング実装数十万〜数百万本(高次 DPA が必要)
高次マスキング + シャッフリング実用上困難な本数

波形の取得は自動化できる。 1 秒に数百〜数千波形を取れるので、 数千本なら数分、数十万本でも数時間で集まる。

4. 電磁解析(EMA)

原理は電力解析と同じだが、取得方法が違う。

特徴内容
非接触パッケージの上にプローブを置くだけ
空間分解能チップ上の特定の回路だけを狙える
ノイズが少ない場合がある電源ラインの平滑化コンデンサの影響を受けない
基板改造が不要電源ラインに抵抗を入れる必要がない

BGA パッケージや、電源が厳重にフィルタされた基板でも、EMA なら通る.

「電源ラインにアクセスできないから安全」という想定は成り立たない。 物理攻撃を想定するなら、EMA を前提にする必要がある。

5. 対策

対策 1: マスキング(最も重要)

中間値をランダム値で撹乱し、消費電力と秘密の相関を断つ。

マスキング — 処理する値そのものをランダム化する対策なしv = SBox(p ⊕ k)v のハミング重みが消費電力に出る→ p は既知、v が分かる→ k が求まる1 次マスキングv' = SBox(p ⊕ k ⊕ m) ⊕ m'm は毎回ランダムに生成する消費電力は v' に比例するがm がランダムなので、攻撃者が予測する v と相関しない
マスキングは有効だが、実装は難しく性能も落ちる。自前でやらず、対策済みのハードウェアエンジンを使うのが現実的
次数内容破るには
1 次マスキングランダム値 1 個で撹乱2 次 DPA(2 点の積を取る)が必要
d 次マスキングランダム値 d 個で撹乱(d+1) 次 DPA が必要。必要な波形数が指数的に増える

マスキングは「正しく実装するのが極めて難しい」.

自作しないこと。 DPA 対策済みのハードウェアエンジンを使うのが正解である。

対策 2: 隠蔽(Hiding)

信号対雑音比を下げる。

手法内容
シャッフリングS-Box 16 個の処理順序を毎回ランダムに入れ替える
ダミー演算無関係な演算をランダムに挿入する
ランダム遅延処理の間にランダムな待ちを入れる
クロックジッタクロック周波数を微妙に揺らす
電力平坦化回路ハードウェアで消費電流を一定に保つ

隠蔽だけでは不十分である.

シャッフリングやランダム遅延は、波形を位置合わせ(アライメント)すれば無効化される。 攻撃者は相関ベースのアライメント手法を使って、揺らぎを除去できる。

隠蔽は「波形数を増やさせる」効果しかない。 \(n\) 通りのシャッフルなら、必要な波形数が約 \(n^2\) 倍になる程度である。

マスキング(撹乱)と隠蔽(雑音)を組み合わせるのが実際の設計である。

対策 3: プロトコル・システムレベル

そもそも同じ鍵で大量の暗号化をさせない。

手法内容
鍵の使用回数制限同じ鍵での暗号化回数に上限を設ける
フレッシュな鍵の導出セッションごとに鍵を派生させる
リーク耐性のあるプロトコル鍵を都度更新する構成にする
レート制限短時間に大量の要求を受け付けない

これが実は最も費用対効果が高い場合がある.

DPA には数千本以上の波形が要る。 「同じ鍵での暗号化は 100 回まで」という制約をプロトコルで課せば、 必要な波形が集まらない。

ハードウェアを変えずに、プロトコル設計だけで防げる場合がある。

対策 4: 認証済みハードウェアを使う

認証物理攻撃耐性の評価
PSA Certified Level 3サイドチャネル・フォールトへの耐性を含む
SESIP 4 以上同上
CC AVA_VAN.4 以上同上
CC AVA_VAN.5(EAL6+ など)最も高い。セキュアエレメントが取得(22 章)

最も確実な対策は「その用途にセキュアエレメントを使う」ことである.

ATECC608、SE050、OPTIGA Trust M などは、 サイドチャネル対策を前提に設計され、第三者評価を受けている(22 章)。

MCU 内蔵の暗号エンジンで DPA 耐性まで持つものは限られる。 「機器の長期秘密鍵はセキュアエレメントに、 セッション鍵は MCU の暗号エンジンで」という役割分担が現実的である。

6. どこまでやるべきか

02 章の攻撃者クラスに戻る。

攻撃者クラスサイドチャネル対策の必要性
クラス 1〜2(好奇心・愛好家)不要。もっと安い攻撃手段がある
クラス 3(犯罪者)場合による。「1 台破ると全台破れる」構造があるなら必要
クラス 4(競合他社・専門ラボ)必要
クラス 5(国家)必要。かつ、それでも十分とは限らない

優先順位を間違えないこと.

DPA 対策に投資する前に、確認すべきことがある。

これらが空いているなら、そちらから取られる。 攻撃者は最も安い経路を選ぶ(02 章の攻撃ツリー)。

DPA 対策は「他が全部固まってから」検討する項目である。

7. この章のまとめ

ポイント内容
サイドチャネル時間・電力・電磁波・キャッシュ。設計者が想定していない経路
EMA の脅威非接触で、空間分解能がある。基板改造が不要
タイミング攻撃最も基本的。秘密値で分岐しない・早期リターンしない
定時間比較ライブラリの ct_memcmp を使う。自作しない
DPA の核心16 バイトを 1 バイトずつ独立に求められる。\(2^{128} \to 4096\)
必要な波形数対策なしで数百〜数千本。数分で集まる
マスキング最も重要な対策。だが正しい実装が極めて難しい
隠蔽波形数を増やさせるだけ。マスキングと併用する
システムレベル同じ鍵の使用回数を制限する。費用対効果が高い
確実な対策セキュアエレメント(AVA_VAN.5 相当)に長期鍵を置く
優先順位基本の穴を全部塞いでから。DPA 対策は最後

次章では、もう 1 つの物理攻撃—— 「電圧をひと突きすると if 文が飛ぶ」フォールトインジェクションを扱う。