TL

セキュアブートとTrustZone

改ざんされたファームを起動させず、鍵を攻撃者から守る仕組みが原理からつかめる。不変なRoot of Trustを起点にした信頼の連鎖と、TrustZoneが安全/非安全領域をハードで隔離する理由を、なぜそうなるかから理解できる。

応用組込みセキュアブートTrustZoneRoot of TrustARM機能安全最終更新: 2026-06-21
TL;DR要点だけ先に
  • 1.セキュアブートはブートROM(不変なRoot of Trust)を起点に、各段が次段の署名を公開鍵で検証してから制御を渡す信頼の連鎖。検証鍵の指紋はeFuseに焼き、秘密鍵は機器に入れずHSMで保管する。
  • 2.TrustZoneはCPUを『安全世界/非安全世界』の2状態に分ける仕組み。Cortex-AはNSビットをバスへ伝搬しMonitor(EL3)がSMCで橋渡しする。Cortex-M(ARMv8-M)はSAU/IDAUで領域を分けSG命令で遷移する。
  • 3.鍵・改ざん対策の要は不変領域。ルート公開鍵ハッシュとアンチロールバックカウンタをeFuse/OTPに置き、署名検証(真正性)と単調増加版数の照合(巻き戻し防止)を両方かける。

なぜ「起動時の検証」だけでは足りないのか

組込みセキュリティは2つの独立した問いに分かれます。「起動するコードが正規か」に答えるのが セキュアブート、「動作中の秘密(鍵・資産)を脆弱なアプリから守れるか」に答えるのが TrustZone に代表される 実行時の領域分離 です。前者は時間軸(起動の連鎖)、後者は空間軸(メモリ・周辺回路の隔離)を守り、両者は補完関係にあります。起動時に正しくても動作中に鍵を抜かれれば意味がなく、実行時分離が堅牢でも起動ファームを差し替えられれば土台から崩れます。

多段ブートの流れ(ブートROM→1次→2次ブートローダ→アプリ)と、OTA更新での安全な置き換えは /embedded/bootloader-ota-update/ で扱いました。本稿はその上で、検証がなぜ改ざんを止められるのかTrustZone がなぜ鍵を守れるのか を内部動作から掘り下げます。リセット直後の起動の前提は /embedded/bare-metal-firmware/ を参照してください。

Root of Trust:信頼はどこから生まれるか

セキュアブートは「あるコードが別のコードを検証する」連鎖ですが、必ず 検証されない最初の1段 が存在します。それを検証する主体がいない以上、その1段は 無条件に信頼するしかなく、ここを Root of Trust(RoT、信頼の起点) と呼びます。RoT が成立する唯一の根拠は「書き換え不能であること」です。攻撃者が最初の1段を差し替えられるなら、その先の署名検証はすべて攻撃者の都合で書き換えられ、無意味になります。

したがって RoT は、製造時に焼き込まれ変更できない ブートROM(マスクROM) と、一度書くと反転できない eFuse/OTP(One-Time Programmable) に固定します。RoT が保持すべきものは次の通りです。

RoTの要素実体格納場所役割
検証コードのRoT署名検証ルーチンブートROM(不変)次段の署名を確かめてから制御を渡す。攻撃者が書き換えられない
信頼のRoT(鍵)ルート公開鍵のハッシュeFuse/OTP受信した公開鍵が正規かを照合する『真の起点』。鍵本体でなく指紋を焼く
機密のRoTHUK(Hardware Unique Key)等OTP/専用鍵ストア機器固有鍵。派生鍵の元。ソフトから直接読めない設計

ここで重要なのは、eFuse に焼くのが公開鍵 そのもの ではなく そのハッシュ(指紋) である点です。RSA-3072 の公開鍵は数百バイト(モジュラスだけで 384 バイト)、ECDSA-P256 でも 64 バイトあり、いずれも 32 バイトのハッシュより大きく貴重な eFuse を余計に消費します。そこでファームには公開鍵を平文で同梱し、ブートROM は「同梱鍵をハッシュした値」が「eFuse の指紋」と一致するかだけを確かめる。一致すればその鍵は正規と見なせ、以降その鍵で署名を検証します。指紋(SHA-256 なら 32 バイト)だけなら eFuse に収まり、鍵更新も別スロットの指紋を有効化すれば済みます。

Root of Trust は「不変」からしか生まれない

セキュアブートの安全性は、暗号アルゴリズムの強度ではなく『連鎖の起点が書き換え不能か』に懸かっています。どれほど強い署名方式でも、検証コードや検証鍵を攻撃者が差し替えられるなら破綻します。だから起点は必ずマスクROM と eFuse に固定し、ソフトウェアで守れるのは『不変な起点があって初めて』という順序を崩しません。

署名検証:完全性と真正性を分けて守る

ファームイメージには2つの独立した保証が要ります。完全性(壊れていない・改変されていない)真正性(正規の発行元が作った) です。完全性だけならハッシュで足りそうに見えますが、ハッシュは誰でも再計算できます。攻撃者が改ざんイメージと、その改ざん後のハッシュをセットで送れば、単純なハッシュ照合は通ってしまう。だから真正性には、発行元だけが持つ 秘密鍵での署名 と、機器側での 公開鍵による検証 という非対称鍵が要ります。

署名(開発側・HSM内)                検証(機器側・各ブート段)
  digest = SHA-256(image)             pubKey を同梱鍵から取り出す
  sig    = Sign(privKey, digest)      assert Hash(pubKey) == eFuse指紋   ← 真正性の起点
                                       digest' = SHA-256(受信image)
                                       ok = Verify(pubKey, sig, digest') ← 署名照合

  privKey は HSM の外に一切出さない
  機器には pubKey(の指紋)だけ。漏れても署名は偽造できない

機器が持つのは公開鍵(の指紋)だけで、秘密鍵は決して機器へ入れないのが鉄則です。公開鍵は漏れても署名の偽造には使えないため、平文で置いても安全です。この検証を各段が繰り返す——ブートROM が1次を、1次が2次を、2次がアプリを検証する——ことで、電源投入から業務コード起動まで 信頼の連鎖(chain of trust) が途切れずに伸びます。どこか1段でも署名が合わなければ連鎖は切れ、起動は止まります。

Verified Boot と Measured Boot は目的が違う

Verified Boot は署名が合わなければ起動を 止める(改ざんの実行阻止)。対して Measured Boot は各段のハッシュを TPM 等の PCR に累積 記録 し、起動自体は止めず、後で外部の検証者に『どんなコードが動いたか』を証明します(リモート認証/remote attestation)。前者は起動可否をローカルで決め、後者は起動履歴を遠隔に証明する——両者は併用もできます。

ロールバック攻撃は署名検証だけでは防げない

攻撃者が『正規に署名された古い脆弱版』を再配布すれば、署名は正しいので検証を通過し、既知の穴を持つ版へ機器を巻き戻せます(ダウングレード攻撃)。対策は、各イメージに単調増加する セキュリティ版数(anti-rollback counter) を持たせ、その最小許容値を eFuse など巻き戻せない領域に記録すること。検証時に『イメージ版数が機器の記録値以上か』を確かめ、古い版数の署名済みイメージを拒否します。署名検証(真正性)と版数照合(巻き戻し防止)は別物で、両方が要ります。

Arm TrustZone:安全世界と非安全世界の分離

セキュアブートが起動コードの正しさを保証しても、動作中のアプリが巨大で脆弱なら、そこを突かれて鍵を抜かれます。そこで 実行中の資産を通常のソフトから物理的に隔離する のが Arm TrustZone です。核心は、CPU を 安全世界(Secure World)非安全世界(Normal World) の2つの実行状態に分け、両者の間に ハードウェアの壁 を設けることにあります。

Cortex-A(アプリケーションプロセッサ)の TrustZone

Cortex-A 系では、現在どちらの世界にいるかを示す NSビット(Non-Secure bit、SCR.NS) が中核です。決定的に重要なのは、この NS ビットが CPU 内部にとどまらず、AMBA/AXI バスのトランザクションに信号線として伝搬する ことです。メモリや周辺回路へのアクセス要求そのものに「安全世界からか、非安全世界からか」の印が付いて回ります。

  • メモリTZASC(TrustZone Address Space Controller) がアドレス領域ごとに「安全世界のみアクセス可」を設定します。非安全世界から安全メモリを読もうとしてもバス側で弾かれる——ソフトのチェックではなく 配線レベルの遮断 なので、非安全コードをいくら攻略しても安全メモリには届きません。
  • 周辺回路TZPC(TrustZone Protection Controller) が、暗号エンジンや鍵ストアを安全世界専用に割り当てます。
  • 世界の切替:橋渡しは最高特権の Monitor モード(EL3) だけが行えます。非安全世界から安全サービスを呼ぶには SMC(Secure Monitor Call)命令 を発行し、EL3 の Monitor がコンテキストを切り替えて該当サービスへ渡す。この一点集中の関所により、遷移経路を検証可能に保ちます。

この上に、安全世界で動く小さな TEE(Trusted Execution Environment、例:OP-TEE) を載せ、鍵操作・指紋照合・DRM といった機密処理だけを Trusted Application に閉じ込めます。非安全世界の Linux やアプリが侵害されても、鍵は壁の内側にあり届きません。

Cortex-M(ARMv8-M)の TrustZone-M

マイコン向けの ARMv8-M(Cortex-M23/M33/M55 等)にも TrustZone は載りますが、実装は Cortex-A とかなり異なります。EL3 や Monitor モードのような別特権レベルは 持たずアドレスによって世界を決める のが特徴です。MCU の固定メモリマップは /embedded/microcontroller-architecture/ を前提とします。

  • 領域定義SAU(Security Attribution Unit) とベンダ実装の IDAU(Implementation Defined Attribution Unit) が、アドレス空間の各領域を Secure / Non-secure / NSC(Non-secure Callable) に分類します。どの番地を実行中かで CPU の状態が自動的に決まります。
  • 安全な入口:非安全コードが安全関数を直接呼ぶことは許されず、入口は NSC 領域に置いた SG(Secure Gate)命令 に限られます。着地点が SG でなければ フォールト し、「安全コードの途中に飛び込んで検証をスキップする」攻撃を封じます。
  • 戻り:安全世界から非安全世界へ戻る・呼ぶには BXNS/BLXNS 命令で状態を明示的に切り替えます。
  • 資源の分離(banking):スタックポインタ(MSP/PSP)、SysTick、MPU、ベクタなどが Secure/Non-secure で 二重化(banked) され、割り込み優先度も NVIC 側で世界ごとに管理されます。安全世界の割り込みを非安全世界から乗っ取れません。
観点Cortex-A TrustZoneCortex-M TrustZone-M(ARMv8-M)
世界の決定NSビット(実行状態)をバスへ伝搬実行アドレスの属性(SAU/IDAU)で決定
特権レベルMonitor モード(EL3)が仲介専用特権なし。状態遷移で切替
非安全→安全の入口SMC 命令 → MonitorNSC 領域の SG 命令に限定
安全→非安全の戻りERET 等でコンテキスト復帰BXNS / BLXNS 命令
メモリ隔離TZASC/TZPC でバス側遮断SAU/IDAU+banked MPU
典型用途TEE(OP-TEE)で鍵・DRM を隔離セキュアブート後の鍵保護・PSA 準拠

鍵の保護とファーム改ざん対策の統合

ここまでの部品を「鍵をどう守り、改ざんをどう止めるか」に集約します。原則は、秘密は不変領域か安全世界の内側にしか置かず、そこから外へ出さない ことです。

  • ルート公開鍵の指紋:eFuse に焼き、署名検証の真正性の起点にする(前述)。
  • 機器固有鍵(HUK):OTP や専用鍵ストアに封じ、ソフトから平文で読めない。暗号鍵は HUK から鍵導出関数で派生させ、派生鍵も安全世界の外へ出さない。
  • アンチロールバックカウンタ:eFuse の単調増加ビットで、古い署名済みファームへの巻き戻しを拒否する。
  • 実行時の鍵操作:復号や署名照合を安全世界(または専用の暗号エンジン)で行い、鍵が非安全世界のメモリに一瞬たりとも現れないようにする。

改ざん対策は、起動時の 署名検証(Verified Boot) で不正コードの実行を止め、アンチロールバック で正規署名の旧版復活を止め、動作中は TrustZone の隔離 で鍵資産をアプリ層の脆弱性から守る三層で構成します。新ファームが起動途中でハングしても、独立クロックで動く ウォッチドッグ が強制リセットをかけ、回復の最後の砦になります(/embedded/watchdog-timer/)。

TrustZone は『万能の暗号化』ではない

よくある誤解は『TrustZone を有効にすればメモリが暗号化されて安全になる』というものです。TrustZone が提供するのは暗号化ではなく アクセス制御(世界による隔離) です。安全世界のコードにバグ(検証漏れ・境界チェック欠如)があれば、非安全世界からその欠陥経由で安全世界の資産に手が届きます。だから安全世界に置くコードは最小限に保ち(TCB=Trusted Computing Base の最小化)、入口(SMC/SG)で引数を厳格に検証することが前提です。壁を作っても、門番が甘ければ破られます。

資格・面接で問われる勘どころ

『Root of Trust とは』→『検証されない不変な起点。書き換え不能だからこそ基点になれる(ブートROM+eFuse)』。『なぜ鍵本体でなく指紋を焼くか』→『eFuse 容量の節約と鍵更新の柔軟性。同梱鍵のハッシュを指紋と照合する』。『TrustZone-A と -M の違い』→『A は NS ビットをバスへ伝搬し Monitor(EL3)+SMC で仲介、M は SAU/IDAU でアドレス属性を決め SG 命令で遷移し専用特権はない』。『署名検証で防げない攻撃』→『ロールバック攻撃。単調増加カウンタで塞ぐ』。

まとめ

  • セキュアブートは 不変なブートROM+eFuse を Root of Trust とし、各段が次段の署名を 公開鍵で検証 してから制御を渡す信頼の連鎖。eFuse には公開鍵の 指紋 を焼き、秘密鍵は機器に入れず HSM で保管する。
  • 検証は 完全性(ハッシュ)真正性(署名) を分担する。Verified Boot は不正実行を止め、Measured Boot は起動履歴を遠隔に証明。ロールバック攻撃 は単調増加版数で別途塞ぐ。
  • TrustZone は CPU を 安全/非安全世界 に分ける実行時分離。Cortex-A は NS ビットをバスへ伝搬 し TZASC/TZPC で遮断、Monitor(EL3)+SMC で橋渡し。Cortex-M は SAU/IDAU で領域を決め SG 命令 で遷移し、資源を banked に二重化する。
  • 鍵は 不変領域か安全世界の内側 にのみ置き外へ出さない。署名検証・アンチロールバック・実行時隔離 の三層と最後の砦の ウォッチドッグ で、改ざんと鍵漏洩に多層で備える。

組込み・IoT Article

セキュアブートとTrustZoneを実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

組込み

比較で見る軸

難易度: advanced / カテゴリ: 組込み・IoT / タグ数: 6

導入後に効く点

TrustZoneはCPUを『安全世界/非安全世界』の2状態に分ける仕組み。Cortex-AはNSビットをバスへ伝搬しMonitor(EL3)がSMCで橋渡しする。Cortex-M(ARMv8-M)はSAU/IDAUで領域を分けSG命令で遷移する。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
組込み・IoT
タグ数
6

判断チェックリスト

  • 自社の用途が「組込み / セキュアブート」に近いか確認する。
  • 強みである「セキュアブートはブートROM(不変なRoot of Trust)を起点に、各段が次段の署名を公開鍵で検証してから制御を渡す信頼の連鎖。検証鍵の指紋はeFuseに焼き、秘密鍵は機器に入れずHSMで保管する。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

組込みセキュアブートTrustZoneRoot of TrustARM組込みセキュアブートTrustZone