IoT Security 13 · セキュア OTA とロールバック防止

Chapter 13

セキュア OTA とロールバック防止

この章がなぜ必要なのか——更新できない機器は、法的にも技術的にも終わっているから.

03 章で見たとおり、EU CRA はサポート期間中のセキュリティ更新の提供を義務化した。 更新機能を持たない機器は、EU 市場で売れなくなる。

そして技術的にも——脆弱性は必ず見つかる。 見つかったときに直せるかどうかが、製品の寿命を決める。

この章で使う既出の用語(定義は各リンク先). セキュアブート(02 章 3 節)、ハッシュ(04 章 4 節)、eFuse(06 章 2 節)、完全性(06 章 6 節)、機密性(06 章 6 節)、AES(08 章 8 節)、レート制限(09 章 5 節)、必要(09 章 6 節)、Espressif(12 章 3 節)、NXP(12 章 3 節)、ライフサイクル状態(12 章 1 節)

1. OTA が守るべき 5 つの性質

性質内容手段
完全性 (Integrity)転送中に壊れていない・改ざんされていないハッシュ + 署名
真正性 (Authenticity)正規のメーカーが作ったものである署名検証(05 章)
機密性 (Confidentiality)中身を第三者に見られない(IP 保護・秘密の秘匿)暗号化(任意だが推奨)
鮮度 (Freshness)古いバージョンに戻されないロールバック防止(本章 4 節)
原子性 (Atomicity)途中で電源が切れても壊れないA/B 面、トランザクション

このうち、真正性とロールバック防止が最重要である。

OTA の検証チェーンを見る

各段階での検証と、どれか 1 つを飛ばすと何が起きるかを確かめられる。

2. 基本の流れ

OTA の 10 ステップ — 検証は 2 回ある1. 通知サーバが知らせる/機器が定期確認2. 取得TLS でダウンロード3. 保存Secondary Slot へ保存4. 検証★ 署名と SVN を検証5. 適用準備次回はこちらを使うフラグ6. 再起動7. ブート時検証★ 起動時に再検証8. 起動新しい版が動く9. 確認自己診断が通れば確定する10. 報告サーバに結果を返す検証が 2 回あるのは、①の保存後に書き換えられる可能性があるから(TOCTOU)⑨の「確定」を忘れると、次の再起動で旧版に戻る——これは仕様であってバグではない
ダウンロードして書けば終わりではない。ブート時の再検証と、起動確認後の確定までが 1 セット

手順 4 と 7 で二重に検証する理由.

手順 4 は「無駄な再起動を避ける」ため(ダウンロード直後に弾く)。 手順 7 はセキュリティ上必須である。

手順 4 と 6 の間に、フラッシュの内容が書き換えられているかもしれない (04 章の TOCTOU)。ブートローダが起動のたびに検証するのが本筋である。

3. A/B 面(デュアルバンク)

最も確実な構成である。

A/B スロット構成ブートローダ不変・署名済Slot 0現在動作中Slot 1更新用更新:Slot 1 に書く → 検証 → 次回は Slot 1 から起動失敗:Slot 0 に戻す(そのまま残っている)フラッシュ容量は「ブートローダ + アプリ × 2 + スクラッチ + データ」が要る= 容量見積もりの段階で OTA 方式を決めておく必要がある
A/B は容量を食うが、失敗しても確実に戻れる。容量が足りないなら、設計の初期に気づかないと詰む
方式内容長所短所
スワップ方式2 面の内容を入れ替えるどちらのスロットからも起動できる入れ替えに時間がかかる。スクラッチ領域が要る
オーバーライト方式Slot 1 の内容を Slot 0 に上書きする単純失敗すると戻れない(旧版が消える)
ダイレクト XIPどちらのスロットからも直接実行する入れ替え不要で速いリンクアドレスが 2 通り必要

MCUboot はこれら複数のモードに対応している。

フラッシュ容量の問題

\[ \text{必要なフラッシュ} = \text{ブートローダ} + 2 \times \text{アプリケーション} + \text{スクラッチ} + \text{データ} \]

アプリケーションが 400 KB なら、最低でも 900 KB 程度が要る。 フラッシュ 512 KB の MCU では A/B 面が取れない。

対策内容注意
外付けフラッシュに Slot 1 を置く内部に Slot 0、外部に Slot 1外部は暗号化する(06 章)
差分更新(デルタ更新)差分だけ送る。適用時に旧版と合成合成中に電源断すると危険。中間状態の保護が必要
圧縮転送量とスロットサイズを減らす展開に RAM が要る
単一バンク + リカバリ失敗したらブートローダのリカバリで復旧リカバリ経路が攻撃面になる(05 章)

「A/B 面が取れるフラッシュ容量か」は、SoC 選定の重要な基準である.

01 章で述べたとおり、フラッシュ容量は後から変えられない。 「更新機能を後で付けよう」としたら容量が足りなかった、という事故が起きる。

企画段階で、アプリケーションサイズの見積り × 2 + 余裕を確保すること。

4. ロールバック防止

最も見落とされる、そして最も重要な機構である。

攻撃のシナリオ

ロールバック攻撃 — 署名が正しくても危ない1メーカーが v1.0 をリリースする2v1.0 に深刻な脆弱性が見つかる3メーカーが v1.1 で修正してリリースする1★ 攻撃者が、正規に署名された v1.0 を機器に送り込む2署名は正しいので、機器は喜んで受け入れる3機器が脆弱な v1.0 に戻る → 攻撃者が脆弱性を突く署名検証は「誰が作ったか」しか確かめない。「新しいか」は別の仕組みが要る
旧版の署名は永久に有効である。だから署名検証だけでは、古い脆弱な版に戻す攻撃を止められない

署名検証だけでは、これを防げない.

v1.0 はメーカーが正規に署名したファームウェアである。 署名検証は当然通る。「古い」ことを検出する別の仕組みが必要である。

対策: セキュリティバージョン番号(SVN)と単調カウンタ

ロールバック防止 — SVN と単調カウンタイメージのヘッダSecurity Version Number(SVN)= 3脆弱性を直したときだけ増やす機器側不揮発の単調カウンタ = 3一度増やしたら減らせない検証image.svn < device.counter → 拒否するimage.svn > device.counter → 受け入れ、起動確定後にカウンタを更新するカウンタを更新するタイミングが要(次の図)
SVN は「表示用のバージョン」とは別物。脆弱性を直したときだけ上げる
単調カウンタの実装内容
OTP / eFuse のビット列ビットを 1 本ずつ焼く。焼ける本数が上限(例: 32 回まで)
専用の単調カウンタ回路一部の SoC / セキュアエレメントが持つ
RPMB(Replay Protected Memory Block)eMMC / UFS の機能。鍵付きで書き込み回数を保護
TPM の NV カウンタTPM を積んでいる場合(22 章)

OTP のビット数が、更新可能回数の上限になる.

eFuse に 32 ビット割り当てたなら、SVN は 32 回しか上げられない。 20 年使う機器で、年 2 回のセキュリティ更新なら 40 回必要になる。

だから——SVN は「表示上のバージョン」とは別に管理する。

SVN を上げるタイミングv1.0.0最初のリリースSVN 1v1.0.1機能追加SVN 1(変えない)v1.0.2機能追加SVN 1(変えない)v1.1.0★ 脆弱性修正SVN 2毎回上げると、単調カウンタの書き換え回数(有限)をすぐ使い切る
SVN は「戻ってはいけない境界」を示すもの。上げすぎるとカウンタの寿命を無駄に消費する

SVN を上げるのは「その版より前に戻したくない」ときだけにする。 これで OTP の消費を最小限にできる。

カウンタを更新するタイミング

カウンタを更新する場所を間違えると文鎮化する危険な設計新しいイメージを検証その場でカウンタを更新起動★ 起動に失敗すると旧版に戻れない安全な設計新しいイメージを検証起動 → 自己診断 OK★ そこでカウンタを更新起動失敗なら旧版に戻れる。カウンタはまだ古いまま
順番を 1 つ入れ替えるだけで、回収不能な事故が防げる。この種の設計ミスは実機の失敗試験でしか見つからない

「確定(confirm)」の設計が、可用性とセキュリティのバランスを決める.

実務的には、「新版が起動して、自己診断とネットワーク接続に成功したら確定」 が妥当な線である。

5. イメージの暗号化

必須ではないが、多くの場合で望ましい。

目的内容
知的財産の保護ファームウェアを解析されない
脆弱性の隠蔽修正内容から脆弱性を逆算されない(パッチ差分解析への対策)
秘密の保護イメージ内の設定値などを隠す

「パッチ差分解析」は現実的な脅威である.

攻撃者は v1.0 と v1.1 の差分を取り、 「どこが修正されたか」から脆弱性の場所を特定する。 PC のソフトウェアでは日常的に行われている手法である。

IoT では更新が行き渡るのに数週間〜数か月かかるため、 「攻撃者が脆弱性を知ってから、全機器が更新されるまで」の窓が長い。 イメージの暗号化は、この窓を守る価値がある。

鍵の配り方

方式内容評価
全機器共通の鍵で暗号化単純1 台から鍵が漏れたら全滅。時間稼ぎのみ
機器固有鍵でラップした鍵を個別配信イメージ本体は共通鍵で暗号化。その鍵を機器ごとに暗号化して配る実用的で安全。サーバ側の負荷も小さい
機器ごとにイメージ全体を暗号化完全に個別サーバ負荷が大きい。大規模には向かない
イメージを暗号化して配る — 鍵の配り方イメージ本体共通の一時鍵 K で暗号化する(1 回だけでよい)各機器へK を、その機器の公開鍵で暗号化して配る(小さなデータ)機器自分の秘密鍵で K を復号 → イメージを復号する★ 1 台の鍵が漏れても、漏れるのはその機器が受け取った K だけ全機器に同じ鍵で暗号化して配ると、1 台の解析で全部が読まれる
配信サイズを抑えつつ、機器ごとに鍵を分ける。ハイブリッド暗号のごく標準的な使い方

これは TLS のハイブリッド暗号や、PGP と同じ考え方である。

MCUboot は暗号化イメージに対応しており、 ECIES(ECDH + AES-KW)や RSA-OAEP による鍵配送をサポートしている。

6. 電源断への耐性

更新中に電源が切れても壊れないことは、必須要件である。

危険な瞬間対策
ダウンロード中Secondary Slot に書くだけ。Primary は無傷
スワップ中最も危険。スワップの進捗を不揮発に記録し、再開できるようにする
ブートローダ更新中ブートローダ自体は更新しない設計が安全。するなら二重化
カウンタ更新中順序を設計する(本章 4 節)

ブートローダの更新は最大のリスクである.

ブートローダを書き換えている最中に電源が切れると、確実に文鎮化する。

対策:

7. 更新の運用設計

技術以外の部分も、実は同じくらい重要である。

項目考慮点
段階的展開(カナリアリリース)1 % → 10 % → 100 %。問題があれば止める
更新のタイミングユーザの使用時間を避ける。産業機器は保守窓を調整する
ネットワーク帯域全機器が同時にダウンロードするとサーバが落ちる。ランダムな遅延を入れる
電池残量の確認更新中に電池切れは最悪。閾値を設ける
失敗の検出と報告どれだけの機器が更新に失敗したかを把握する
強制更新深刻な脆弱性のときは、ユーザの同意なしに更新できるか(法的・契約的な検討が要る)
サポート終了 (EOL)いつまで更新するかを購入前に明示する(03 章の PSTI・CRA 要件)

「全機器が同時に更新を取りに来る」問題は、実際に起きる.

100 万台の機器が一斉にダウンロードを始めると、 CDN の帯域が飽和し、更新自体が失敗する。

技術的な正しさだけでは運用できない。

8. 標準とプロトコル

標準内容
IETF SUIT (RFC 9019 / 9124 / 9459 など)組み込み向けのソフトウェア更新アーキテクチャとマニフェスト形式。CBOR/COSE ベース
TUF / UptaneThe Update Framework。鍵の危殆化(漏洩して信頼できなくなること)に耐える設計。Uptane は自動車向け
LwM2M Firmware UpdateOMA LwM2M のオブジェクト 5。制約デバイス向け
PSA Firmware Update APITF-M の一部(17 章)
OMA-DM / TR-069レガシーだが、通信機器で現役

SUIT マニフェストの考え方は参考になる.

「何を、どこから取得し、どう検証し、どこに書き、いつ再起動するか」を 署名されたマニフェストに記述する。

自前でプロトコルを設計する前に、SUIT の RFC を読む価値がある。

TUF / Uptane の「鍵の危殆化に耐える」設計:

Uptane — 役割ごとに鍵を分けるRoot キー他の鍵を承認する。オフライン保管。最も重要Targets キーどのイメージが正規かを示すSnapshot キーメタデータの一貫性を保証するTimestamp キー鮮度を保証する。オンラインで頻繁に使う★ オンラインで使う鍵(Timestamp)が漏れても、イメージの差し替えはできない差し替えには Targets キーが必要で、それはオフラインにある「よく使う鍵ほど権限を小さくする」——鍵設計の一般原則
車載で使われる仕組みだが、考え方は一般の IoT にも効く。1 本の鍵にすべての権限を持たせない

これは「オンラインに置く鍵の権限を最小にする」という原則の実装である.

署名サーバがハッキングされても、 オフラインの Root/Targets キーがなければ偽のファームウェアは配れない。

自動車業界では Uptane が事実上の標準になりつつある。 一般 IoT でも、署名鍵をオフライン HSM に置き、配信サーバには置かない という原則は共通である。

9. 実装の選択肢

実装特徴
MCUboot最も広く使われる。A/B、ロールバック防止、暗号化イメージに対応
ベンダ提供(ST の SBSFU、NXP の ..., Espressif の esp_ota)チップの機能に最適化されている
クラウドサービス連携AWS IoT Jobs / OTA、Azure Device Update、各社の IoT PaaS
自作強く非推奨

OTA も自作しないこと.

セキュアブートと同じで、細部で必ず事故る領域である。

既に何百万台で動いている実装を使うのが正解である。

10. この章のまとめ

ポイント内容
法的要求CRA がサポート期間中の更新提供を義務化。更新できない機器は売れない
5 つの性質完全性・真正性・機密性・鮮度・原子性
二重検証ダウンロード直後と起動のたびに検証する(TOCTOU 対策)
A/B 面最も確実。フラッシュ容量は企画段階で確保する(後から変えられない)
ロールバック防止署名検証だけでは防げない。SVN + 単調カウンタが必要
SVN の運用脆弱性修正のときだけ上げる。OTP のビット数が上限になる
確定のタイミング起動して自己診断が通ってからカウンタを更新する
イメージ暗号化パッチ差分解析への対策として価値がある
鍵の配り方共通鍵で暗号化 + その鍵を機器ごとに暗号化して配る
ブートローダ更新最大のリスク。更新しない設計が安全
運用段階的展開・ジッタ・電池確認・EOL の明示
鍵の分離オンラインに置く鍵の権限を最小に(TUF / Uptane の原則)
実装MCUboot などを使う。自作しない

次章では、機器の一生を通した状態管理—— ライフサイクル状態と廃棄を扱う。