ブートローダーの使用

ロック解除と Trusty

推奨事項

上記のすべてのパーティションを再フラッシュできるように、Google ブランドのデバイスをすべてロック解除可能にする必要があります。 このロック解除モードは fastboot flashing unlock で設定します。設定した場合、このモードは再起動間にまたがって持続する必要があります。

デバイスは、 fastboot flashing get_unlock_ability が 1 である場合を除き、fastboot flashing unlock コマンドを拒否する必要があります。get_unlock_ability が 0 の場合、ユーザーはホーム画面に起動し、[設定] > [システム] > [開発者向けオプション] メニューに移動し、[OEM ロック解除] オプションを有効にして、unlock_ability を 1 に設定します。このフラグは、再起動間と、データの初期化間で持続する必要があります。

fastboot flashing unlock コマンドが送信されると、デバイスではユーザーに対して、非公式のイメージによる問題が発生する可能性があるという警告が表示されます。承認後、データの不正なアクセスを防ぐため、データの初期化を行う必要があります。ブートローダーは、デバイスを正しく再フォーマットできない場合でも、デバイスをリセットする必要があります。永続フラグを設定できるのはリセット後のみであるため、デバイスの再フラッシュが可能になります。

fastboot flashing lock コマンドはデバイスの再ロックとリセットを行い、その結果将来のフラッシュやロック解除の試行時に別のデータのリセットが必要となります。

まだ上書きされていない RAM はすべて fastboot flashing unlock プロセスでリセットする必要があります。これにより、以前の起動から残りの RAM の内容を読み取る攻撃を防止できます。同様に、ロック解除されたデバイスでは、許容できない遅延が発生しない場合、毎回起動時に RAM を消去する必要があります。ただし、カーネルの ramoops に使用する領域は残す必要があります。

小売用のデバイスはロック状態で出荷する必要があります(また、get_unlock_ability が 0 を返す必要があります)。これは、攻撃者が独自のシステムやブートイメージをインストールしてデバイスに損害を与えることができないようにするためです。

プロパティ

ro.oem_unlock_supported プロパティは、デバイスがロック解除のフラッシュに対応するかどうかに基づいてビルド時に設定する必要があります。 ro.oem_unlock_supported は、デバイスがロック解除のフラッシュに対応していない場合は 0、対応している場合は 1 に設定する必要があります。

デバイスがロック解除のフラッシュに対応している場合(ro.oem_unlock_supported = 1)、ブートローダーはロック状態を表す必要があります。そのため、カーネル コマンドライン変数 androidboot.flash.locked(または /firmware/android/flash.locked DT プロパティ)が、ロックされている場合は 1、ロック解除されている場合は 0 に設定されます。

注: dm-verity に対応しているデバイスの場合、ro.boot.verifiedbootstate を代わりに使用して ro.boot.flash.locked の値を設定できます。この場合、確認済みのブート状態がオレンジであれば値は 0 です。

lock/unlock_critical のフラッシュ

デバイスは、クリティカル セクションのロックとロック解除に対応している必要があります。これらのクリティカル セクションは、デバイスをブートローダーにブートするために必要なものとして定義されます。たとえば、ヒューズ、センサーハブの仮想パーティション、第 1 ステージのブートローダーなどがあげられます。

クリティカル セクションのロックとは、任意のクリティカル セクションで、デバイス上で実行されている任意のコード(カーネル、リカバリ イメージ、OTA コードなど)を意図的に変更できないようにすることです。つまり、デバイスがロック クリティカル状態の場合、OTA はクリティカル セクションのアップデートに失敗します。ロック状態からロック解除状態への移行には、デバイスを物理的に操作する必要があります。

この物理的な操作は、fastboot flashing unlock により引き起こされる動作に似ています。ユーザーはデバイス上のいずれかの物理的ボタンを押す必要があります。設計では、物理的な操作なしでプログラムによって lock critical から unlock critical に移行できないようにする必要があります。デバイスは出荷時に unlock critical 状態である必要があります。

クリティカル パーティション/データの指定

デバイスの実行に必要なパーティションやデータは、次のいずれかである必要があります。

  • 再フラッシュ可能 - fastboot oem コマンドによる再構築、提供、抽出が可能
  • 完全保護(以前のセクションでクリティカルと判断されている)

デバイスごとの工場固有の設定、シリアル番号、キャリブレーション データなどがこれに含まれます。

オフモード充電

デバイスが「オフモード充電」に対応している場合、またはそれ以外で電源投入時に特殊モードで自動起動する場合、fastboot oem off-mode-charge 0 を使用するとこれらの特殊モードが無視され、ユーザーが電源ボタンを押した場合と同じように起動します。

Trusty 用ブートローダー

Trusty は、Google による Trusted Execution Environment(TEE)OS の実装であり、Android で実行されます。これは ARM TrustzoneTM テクノロジーで TEE を提供するための仕様です。

Trusty が ARM デバイスでのセキュアな OS ソリューションとして使用されている場合、ブートローダーはこの後の各セクションの記述に従って実装する必要があります。

初期化

Trusty OS(TOS)を読み込んで初期化するには、ブートローダーは以下の処理を行う必要があります。

  • 使用可能なすべての RAM を設定して構成する
  • シリアルポートを少なくとも 1 つ初期化する
  • TOS イメージの署名を確認する
  • TOS を RAM に読み込む(フラッシュや TCM からの実行には対応していません)
  • 次のセクションで説明するように、状態とレジスタを設定した後、TOS イメージの最初の命令にジャンプする

TOS イメージの呼び出し

最初に次の状態を構成する必要があります。

  • MMU をオフにする
  • データ キャッシュをフラッシュしてオフにする(命令キャッシュはオンとオフのどちらも可能)
  • すべての割り込み(IRQ と FIQ)を無効にする
  • CPU を ARM v7 では SVC モード、ARM v8 では EL3 モードにする
  • レジスタを次の状態にする
    • r0/x0: TOS に割り当てるメモリのサイズ。
    • r1/x1: プラットフォーム独自のブート パラメータを含むメモリの連続したブロックの物理アドレス。このブロックのレイアウトはプラットフォームによって異なります。
    • r2/x2: メモリの上記ブロックのサイズ。
    • r14/x30: TOS の初期化後に(非セキュアモードで)ジャンプするリターン アドレス。

注: r0-r3/x0-x3 も TOS へのスクラッチ レジスタとして機能します。返されたときに値が保持されるとは限りません。

64 ビットプラットフォームの場合、次のようになります。

  • パラメータには w0-w2 のみが使用されるため、x0-x2 には 32 ビット値のみを含めます。
  • x30 には 64 ビットの値を設定できます。
  • x0 の値が TOS エントリ ポイントのベースアドレスに追加された場合、結果は 32 ビット値になります。x1 のブート パラメータ ブロックのアドレスに追加したときのレジスタ x2 のサイズについても同様です。

TOS からの戻り

TOS の初期化が完了すると、TOS は非セキュアモードでブートローダーに戻ります(SCR.NS が 1 に設定されます)。これにより、ブートローダーは主たるオペレーティング システム(Android など)の読み込みを続行できます。