再起動時に再開

Android 11では、 A / B更新または仮想A / B更新メカニズムを、 RecoverySystemクラスメソッドと組み合わせて使用​​して、OTA更新を適用できます。デバイスをリブートしてOTAアップデートを適用した後、Resume-on-Reboot(RoR)はデバイスのCredential Encrypted(CE)ストレージのロックを解除します。

パートナーはこのプロセスを、Android 11でデバイスがアイドル状態であると予想されるときに更新を適用するOTAシステム機能と組み合わせることができますが、Android12パートナーでは追加のOTAシステム機能は必要ありません。 RoRプロセスは、デバイスのアイドル時間中に更新を行うことができるため、ユーザーにセキュリティと利便性を追加します。Android12マルチクライアントとサーバーベースの更新機能は、デバイスのハードウェアレベルのタイプのセキュリティを提供します。

Android 11でRoRをサポートするには、 android.hardware.reboot_escrow機能にデバイス権限を付与する必要がありますが、Android 12以降でサーバーベースのRoRを有効にするには、HALを使用しないため、これを行う必要はありません。

android.hardware.reboot_escrow機能のデバイス権限を提供します。 Android 12以降ではHALを使用しないため、Android12でサーバーベースのRoRを有効にするために何もする必要はありません。

バックグラウンド

Android 7以降、Androidはダイレクトブートをサポートしました。これにより、ユーザーがCEストレージのロックを解除する前に、デバイス上のアプリを起動できます。ダイレクトブートサポートの実装により、ユーザーは、ブート後にロック画面ナレッジファクター(LSKF)を入力する必要が生じる前に、より優れたエクスペリエンスを提供できました。

RoRを使用すると、OTAの更新後に再起動が開始されたときに、ダイレクトブートをサポートしていないアプリを含め、デバイス上のすべてのアプリのCEストレージのロックを解除できます。この機能により、ユーザーは再起動後に、インストールされているすべてのアプリから通知を受け取ることができます。

脅威モデル

RoRの実装では、デバイスが攻撃者の手に渡った場合、デバイスの電源がオンで、CEストレージがロック解除され、デバイスがOTAアップデートを受信した後のユーザー。インサイダー攻撃への耐性は、攻撃者がブロードキャスト暗号署名キーにアクセスした場合でも効果的である必要があります。

具体的には、CEストレージは、デバイスを物理的に持っており、次の機能と制限がある攻撃者によって読み取られてはなりません

機能

  • 任意のベンダーまたは会社の署名キーを使用して、任意のメッセージに署名できます。
  • デバイスにOTAアップデートを受信させる可能性があります。
  • 以下の制限事項で詳しく説明されている場合を除き、任意のハードウェア(アプリケーションプロセッサ、フラッシュメモリなど)の動作を変更できます。 (ただし、このような変更には、少なくとも1時間の遅延と、RAMの内容を破壊する電源の入れ直しの両方が含まれます。)

制限事項

  • 改ざん防止ハードウェア(Titan Mなど)の動作を変更することはできません。
  • ライブデバイスのRAMを読み取ることができません。
  • ユーザーの資格情報(PIN、パターン、パスワード)を推測したり、入力させたりすることはできません。

解決

Android 12 RoRアップデートシステムは、非常に高度な攻撃者に対するセキュリティを提供し、デバイス上のパスワードとPINがデバイスに残っている間、Googleサーバーに送信されたり保存されたりすることはありません。これは、提供されるセキュリティレベルがハードウェアベースのデバイスレベルのRoRシステムと同様であることを保証するプロセスの概要です。

  • Androidは、デバイスに保存されているデータに暗号化保護を適用します。
  • すべてのデータは、 Trusted Execution Environment (TEE)に保存されているキーによって保護されています。
  • TEEは、実行中のオペレーティングシステムが暗号化認証(検証済みブート)に合格した場合にのみキーを解放します。
  • Googleサーバーで実行されているRoRサービスは、限られた時間だけ取得できるシークレットを保存することでCEデータを保護します。これはAndroidエコシステム全体で機能します。
  • ユーザーのPINで保護された暗号化キーは、デバイスのロックを解除し、CEストレージを復号化するために使用されます。
    • 夜間の再起動がスケジュールされると、AndroidはユーザーにPINの入力を求め、合成パスワード(SP)を計算します。
    • 次に、SPを2回暗号化します。1回はRAMに格納されたキーK_sを使用し、もう1回はTEEに格納されたキーK_kを使用します。
    • 二重暗号化されたSPはディスクに保存され、SPはRAMから消去されます。両方のキーが新たに生成され、 1回の再起動でのみ使用されます。
  • 再起動するとき、AndroidはK_sをサーバーに委託します。 K_kのレシートは、ディスクに保存される前に暗号化されます。
  • 再起動後、AndroidはK_kを使用してレシートを復号化し、サーバーに送信してK_sを取得します。
    • K_kK_sは、ディスクに保存されているSPを復号化するために使用されます。
    • AndroidはSPを使用してCEストレージのロックを解除し、通常のアプリの起動を許可します。
    • K_kK_sは破棄されます。

スマートフォンを安全に保つための更新は、睡眠中など、都合のよい時間に行うことができます。

SIM-PINリプレイ

特定の条件下では、SIMカードのPINコードがキャッシュから検証されます。これは、SIM-PINリプレイと呼ばれるプロセスです。

PINが有効になっているSIMカードは、セルラー接続(電話、SMSメッセージ、およびデータサービスに必要)を復元するために、無人再起動後にシームレスなPINコード検証(SIM-PIN再生)を受ける必要があります。 SIM PINとそれに対応するSIMカード情報(ICCIDとSIMスロット番号)は、一緒に安全に保管されます。保存されたPINは、無人での再起動が成功した後にのみ取得して検証に使用できます。デバイスが保護されている場合、SIMPINはLSKFによって保護されたキーとともに保存されます。 SIMでPINが有効になっている場合、RoRサーバーとの対話にはOTA更新用のWiFi接続とサーバーベースのRoRが必要です。これにより、再起動後の基本機能(セルラー接続)が保証されます。

SIM PINは、ユーザーがSIM PINを有効化、検証、または変更するたびに再暗号化および保存されます。次のいずれかが発生した場合、SIMPINは破棄されます。

  • SIMが取り外されるかリセットされます。
  • ユーザーはPINを無効にします。
  • RoRによって開始されていない再起動が発生しました。

保存されたSIMPINは、RoRによって開始された再起動後に1回だけ使用でき、SIMカードの詳細が一致する場合は非常に短い時間(20秒)のみ使用できます。保存されたSIMPINは、TelephonyManagerアプリを離れることはなく、外部モジュールから取得することもできません。

実装ガイドライン

Android 12では、マルチクライアントおよびサーバーベースのRoR機能により、パートナーがOTAアップデートをプッシュする際の負荷が軽減されます。必要な更新は、指定されたスリープ時間中など、デバイスの便利なダウンタイム中に発生する可能性があります。

このような期間中のOTA更新がユーザーの邪魔にならないようにするには、ダークモードを使用して発光を軽減します。これを行うには、デバイスのブートローダーに文字列unattendedを検索させます。 unattended trueは、デバイスをダークモードにします。音と光の放出を軽減するのは各OEMの責任であることに注意してください。

Android 12にアップグレードする場合、またはAndroid 12デバイスを起動する場合は、新しいRoR機能を実装するために何もする必要はありません。

以下に示すように、マルチクライアントフローにはisPreparedForUnattendedUpdateという新しい呼び出しが1つあります。

@RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY,
            android.Manifest.permission.REBOOT})
public static boolean isPreparedForUnattendedUpdate(@NonNull Context context)

HALはAndroid12で非推奨になっているため、これを実装する必要はありません。

TelephonyManager

Android 12で再起動が差し迫っている場合、OTAクライアントはTelephonyManagerシステムAPIを呼び出します。このAPIは、キャッシュされたすべてのPINコードをAVAILABLE状態からREBOOT_READY状態に移動します。 TelephonyManagerシステムAPIは、既存のREBOOTマニフェスト権限によって保護されています。

 /**
    * The unattended reboot was prepared successfully.
    * @hide
    */
   @SystemApi
   public static final int PREPARE_UNATTENDED_REBOOT_SUCCESS = 0;

   /**
    * The unattended reboot was prepared, but the user will need to manually
    * enter the PIN code of at least one SIM card present in the device.
    * @hide
    */
   @SystemApi
   public static final int PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED = 1;

   /**
    * The unattended reboot was not prepared due to generic error.
    * @hide
    */
   @SystemApi
   public static final int PREPARE_UNATTENDED_REBOOT_ERROR = 2;

   /** @hide */
   @Retention(RetentionPolicy.SOURCE)
   @IntDef(prefix = {"PREPARE_UNATTENDED_REBOOT_"},
           value = {
                   PREPARE_UNATTENDED_REBOOT_SUCCESS,
                   PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED,
                   PREPARE_UNATTENDED_REBOOT_ERROR
           })
   public @interface PrepareUnattendedRebootResult {}

   /**
    * Prepare TelephonyManager for an unattended reboot. The reboot is
    * required to be done shortly after the API is invoked.
    *
    * Requires system privileges.
    *
    * <p>Requires Permission:
    *   {@link android.Manifest.permission#REBOOT}
    *
    * @return {@link #PREPARE_UNATTENDED_REBOOT_SUCCESS} in case of success.
    * {@link #PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED} if the device contains
    * at least one SIM card for which the user needs to manually enter the PIN
    * code after the reboot. {@link #PREPARE_UNATTENDED_REBOOT_ERROR} in case
    * of error.
    * @hide
    */
   @SystemApi
   @RequiresPermission(android.Manifest.permission.REBOOT)
   @PrepareUnattendedRebootResult
   public int prepareForUnattendedReboot()

TelephonyManagerシステムAPIは、特権APKによって使用されます。

テスト

新しいAPIをテストするには、次のコマンドを実行します。

    adb shell cmd phone unattended-reboot

このコマンドは、シェルがroot( adb root )として実行されている場合にのみ機能します。

Android11のみ

このページの残りの部分はAndroid11に適用されます。

2020年7月の時点で、RoRHALの実装は2つのカテゴリに分類されます。

  1. SoCハードウェアが再起動後のRAM永続性をサポートしている場合、OEMはAOSPのデフォルト実装(デフォルトRAMエスクロー)を使用できます。
  2. デバイスハードウェアまたはSoCが安全なハードウェアエンクレーブ(独自のRAMとROMを備えたディスクリートセキュリティコプロセッサー)をサポートしている場合は、さらに次のことを行う必要があります。
    • メインCPUの再起動を検出できます。
    • 再起動後も持続するハードウェアタイマーソースを用意します。つまり、エンクレーブは再起動を検出し、再起動前に設定されたタイマーを期限切れにする必要があります。
    • エスクローされたキーをエンクレーブRAM / ROMに保存して、オフライン攻撃で回復できないようにすることをサポートします。 RoRキーは、内部関係者や攻撃者が回復できないように保存する必要があります。

デフォルトのRAMエスクロー

AOSPには、RAM永続性を使用したRoRHALの実装があります。これが機能するためには、OEMは、SoCが再起動後もRAMの永続性をサポートしていることを確認する必要があります。一部のSoCは、再起動後もRAMの内容を保持できないため、OEMは、このデフォルトのHALを有効にする前にSoCパートナーに相談することをお勧めします。次のセクションでこれに関する正規のリファレンス。

RoRを使用したOTA更新のフロー

電話機のOTAクライアントアプリには、RoRを実装するために必要なメソッドを呼び出すためのManifest.permission.REBOOTおよびManifest.permission.RECOVERY権限が必要です。その前提条件が整っている場合、更新のフローは次の手順に従います。

  1. OTAクライアントアプリがアップデートをダウンロードします。
  2. OTAクライアントアプリがRecoverySystem#prepareForUnattendedUpdateを呼び出すと、ユーザーは次のロック解除時にロック画面でPIN、パターン、またはパスワードの入力を求められます。
  3. ユーザーはロック画面でデバイスのロックを解除し、デバイスは更新を適用する準備ができています。
  4. OTAクライアントアプリがRecoverySystem#rebootAndApplyを呼び出すと、すぐに再起動がトリガーされます。

このフローの最後に、デバイスがリブートし、RoRメカニズムがクレデンシャル暗号化(CE)ストレージのロックを解除します。アプリにとって、これは通常のユーザーのロック解除として表示されるため、アプリは通常行うACTION_LOCKED_BOOT_COMPLETEDACTION_BOOT_COMPLETEDなどのすべてのシグナルを受信します。

製品構成の変更

Android 11でRoR機能をサポートするとマークされた製品には、RebootEscrow HALの実装が含まれ、機能マーカーXMLファイルが含まれている必要があります。デフォルトの実装は、ウォームリブートを使用するデバイスで適切に機能します(リブート中にDRAMへの電源がオンのままである場合)。

エスクロー機能マーカーを再起動します

機能マーカーも存在する必要があります。

PRODUCT_COPY_FILES += \
    frameworks/native/data/etc/android.hardware.reboot_escrow.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.reboot_escrow.xml

デフォルトの再起動エスクローHAL実装

デフォルトの実装を使用するには、65536(0x10000)バイトを予約する必要があります。セキュリティプロパティが持続することを保証するために、これらのバイトを不揮発性ストレージに書き込まないでください。

Linuxカーネルデバイスツリーの変更

Linuxカーネルのデバイスツリーでは、 pmemリージョン用にメモリを予約する必要があります。次の例は、 0x50000000が予約されていることを示しています。

  reserved-memory {
    my_reservation@0x50000000 {
      no-map;
      reg = <0x50000000 0x10000>;
    }
  }

  reboot_escrow@0 {
    compatible = "pmem-region";
    reg = <0x50000000 0x10000>;
  };

ブロックディレクトリに/dev/block/pmem0pmem1pmem2など)のような名前の新しいデバイスがあることを確認します。

Device.mkの変更

前の手順の新しいデバイスの名前がpmem0であるとすると、次の新しいエントリがvendor/<oem>/<product>/device.mkに追加されていることを確認する必要があります。

# Resume on Reboot support
PRODUCT_PROPERTY_OVERRIDES += \
    ro.rebootescrow.device=/dev/block/pmem0
PRODUCT_PACKAGES += \
    android.hardware.rebootescrow-service.default
SELinuxルール

これらの新しいエントリをデバイスのfile_contextsに追加します。

/dev/block/pmem0  u:object_r:rebootescrow_device:s0
/vendor/bin/hw/android\.hardware\.rebootescrow-service\.default  u:object_r:hal_rebootescrow_default_exec:s0