재부팅 시 재개

Android 11에서는 RecoverySystem 클래스 메서드와 결합된 A/B 업데이트 또는 가상 A/B 업데이트 메커니즘을 사용하여 OTA 업데이트를 적용할 수 있습니다. OTA 업데이트를 적용하기 위해 기기를 재부팅한 후, RoR(Resume-on-Reboot)은 기기의 CE(Credential Encrypted) 스토리지 를 잠금 해제합니다.

파트너는 Android 11에서 기기가 유휴 상태일 것으로 예상될 때 업데이트를 적용하는 OTA 시스템 기능과 이 프로세스를 연결할 수 있지만 Android 12에서는 파트너에게 추가 OTA 시스템 기능이 필요하지 않습니다. RoR 프로세스는 장치 유휴 시간 동안 업데이트가 수행될 수 있기 때문에 사용자에게 추가 보안 및 편의성을 제공하는 반면 Android 12 다중 클라이언트 및 서버 기반 업데이트 기능은 함께 장치 하드웨어 수준 유형 보안을 제공합니다.

Android 11에서 RoR을 지원하려면 android.hardware.reboot_escrow 기능에 대한 기기 권한을 제공해야 하지만 HAL을 사용하지 않기 때문에 Android 12 이상에서 서버 기반 RoR을 활성화하기 위해 이 권한을 제공할 필요는 없습니다.

android.hardware.reboot_escrow 기능에 대한 장치 권한을 제공합니다. Android 12 이상에서는 HAL을 사용하지 않기 때문에 Android 12에서 서버 기반 RoR을 활성화하기 위해 아무 것도 할 필요가 없습니다.

배경

Android 7부터 Android는 사용자가 CE 스토리지의 잠금을 해제하기 전에 기기의 앱을 시작할 수 있도록 하는 Direct Boot 를 지원했습니다. 직접 부팅 지원의 구현은 부팅 후 LSKF(잠금 화면 지식 요소)를 입력해야 하기 전에 사용자에게 더 나은 경험을 제공했습니다.

RoR을 사용하면 OTA 업데이트 후 재부팅이 시작될 때 직접 부팅을 지원하지 않는 앱을 ​​포함하여 기기에 있는 모든 앱의 CE 스토리지를 잠금 해제할 수 있습니다. 이 기능을 통해 사용자는 재부팅 후 설치된 모든 앱에서 알림을 받을 수 있습니다.

위협 모델

RoR의 구현은 장치가 공격자의 손에 넘어갔을 때 공격자가 사용자의 CE 암호화 데이터를 복구하는 것이 극히 어렵다는 것을 보장해야 합니다. 장치 의 전원이 켜져 있고 CE 스토리지가 잠금 해제되어 있고 OTA 업데이트를 받은 후 사용자. 내부자 공격 저항은 공격자가 브로드캐스트 암호화 서명 키에 액세스하는 경우에도 효과적이어야 합니다.

특히, CE 스토리지 는 물리적으로 장치를 가지고 있고 다음과 같은 기능과 제한이 있는 공격자가 읽을 수 없습니다 .

기능

  • 임의의 메시지에 서명하기 위해 모든 공급업체 또는 회사의 서명 키를 사용할 수 있습니다.
  • 장치가 OTA 업데이트를 수신하도록 할 수 있습니다.
  • 아래 제한 사항 에 자세히 설명된 경우를 제외하고 모든 하드웨어(예: 애플리케이션 프로세서 또는 플래시 메모리)의 작동을 수정할 수 있습니다. (그러나 이러한 수정에는 최소 1시간의 지연과 RAM 내용을 파괴하는 전원 주기가 모두 포함됩니다.)

제한 사항

  • 변조 방지 하드웨어(예: Titan M)의 작동을 수정할 수 없습니다.
  • 라이브 장치의 RAM을 읽을 수 없습니다.
  • 사용자의 자격 증명(PIN, 패턴, 비밀번호)을 추측하거나 입력하도록 할 수 없습니다.

해결책

Android 12 RoR 업데이트 시스템은 매우 정교한 공격자에 대한 보안을 제공하며 기기 비밀번호 및 PIN이 기기에 유지되는 동안 보안을 제공합니다. Google 서버로 전송되거나 Google 서버에 저장되지 않습니다. 다음은 제공된 보안 수준이 하드웨어 기반 장치 수준 RoR 시스템과 유사한지 확인하는 프로세스의 개요입니다.

  • Android는 기기에 저장된 데이터에 암호화 보호를 적용합니다.
  • 모든 데이터는 TEE( 신뢰할 수 있는 실행 환경 )에 저장된 키로 보호됩니다.
  • TEE는 실행 중인 운영 체제가 암호화 인증( 검증된 부팅 )을 통과한 경우에만 키를 해제합니다.
  • Google 서버에서 실행되는 RoR 서비스 는 제한된 시간 동안만 검색할 수 있는 비밀을 저장하여 CE 데이터를 보호합니다. 이는 Android 생태계 전반에서 작동합니다.
  • 사용자의 PIN으로 보호되는 암호화 키는 장치의 잠금을 해제하고 CE 저장소를 해독하는 데 사용됩니다.
    • 야간 재부팅이 예약되면 Android는 사용자에게 PIN을 입력하라는 메시지를 표시한 다음 합성 암호(SP)를 계산합니다.
    • 그런 다음 SP를 두 번 암호화합니다. 한 번은 RAM에 저장된 K_s 키를 사용하고 다시 한 번은 TEE에 저장된 K_k 키를 사용하여 암호화합니다.
    • 이중 암호화된 SP는 디스크에 저장되고 SP는 RAM에서 지워집니다. 두 키 모두 새로 생성되어 한 번의 재부팅에만 사용됩니다.
  • 재부팅할 시간이 되면 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 카드는 무인 재부팅 후 원활한 PIN 코드 확인(SIM-PIN 재생)을 거쳐야 셀룰러 연결을 복원할 수 있습니다(전화 통화, SMS 메시지 및 데이터 서비스에 필요). SIM PIN과 일치하는 SIM 카드 정보(ICCID 및 SIM 슬롯 번호)는 함께 안전하게 저장됩니다. 저장된 PIN은 무인 재부팅에 성공한 후에만 검색하여 확인할 수 있습니다. 장치가 보안되면 LSKF로 보호되는 키와 함께 SIM PIN이 저장됩니다. SIM에 PIN이 활성화되어 있는 경우 RoR 서버와 상호 작용하려면 OTA 업데이트 및 서버 기반 RoR을 위한 WiFi 연결이 필요 하며, 이는 재부팅 후 기본 기능(셀룰러 연결 포함)을 보장합니다.

SIM PIN은 사용자가 성공적으로 활성화, 확인 또는 수정할 때마다 다시 암호화되어 저장됩니다. 다음 중 하나가 발생하면 SIM PIN이 삭제됩니다.

  • SIM이 제거되거나 재설정됩니다.
  • 사용자가 PIN을 비활성화합니다.
  • RoR이 시작하지 않은 재부팅이 발생했습니다.

저장된 SIM PIN은 RoR이 시작한 재부팅 후 한 번만 사용할 수 있으며 SIM 카드의 세부 정보가 일치하는 경우 매우 짧은 시간(20초) 동안만 사용할 수 있습니다. 저장된 SIM PIN은 TelephonyManager 앱을 떠나지 않으며 외부 모듈에서 검색할 수 없습니다.

구현 지침

Android 12에서 다중 클라이언트 및 서버 기반 RoR 기능은 OTA 업데이트를 푸시할 때 파트너에게 더 가벼운 부하를 제공합니다. 필요한 업데이트는 지정된 취침 시간과 같이 편리한 장치 가동 중지 시간 동안 발생할 수 있습니다.

이러한 기간 동안 OTA 업데이트가 사용자를 방해하지 않도록 하려면 어두운 모드를 사용하여 빛 방출을 완화하십시오. 그렇게 하려면 장치 부트로더가 문자열 이유 unattended 를 검색하도록 하십시오. unattendedtrue 장치를 어두운 모드로 설정합니다. 소리와 빛 방출을 완화하는 것은 각 OEM의 책임입니다.

Android 12로 업그레이드하거나 Android 12 기기를 시작하는 경우 새로운 RoR 기능을 구현하기 위해 아무 것도 할 필요가 없습니다.

다중 클라이언트 흐름에는 다음과 같이 isPreparedForUnattendedUpdate 라는 새로운 호출이 하나 있습니다.

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

HAL은 Android 12부터 더 이상 사용되지 않으므로 이를 구현할 필요가 없습니다.

텔레포니 매니저

OTA 클라이언트는 Android 12에서 재부팅이 임박한 경우 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

이 명령은 쉘이 루트( adb root )로 실행 중일 때만 작동합니다.

안드로이드 11 전용

이 페이지의 나머지 부분은 Android 11에 적용됩니다.

2020년 7월부터 RoR HAL 구현은 두 가지 범주로 나뉩니다.

  1. SoC 하드웨어가 재부팅 시 RAM 지속성을 지원하는 경우 OEM은 AOSP( Default RAM Escrow )의 기본 구현을 사용할 수 있습니다.
  2. 장치 하드웨어 또는 SoC가 보안 하드웨어 엔클레이브(자체 RAM 및 ROM이 있는 개별 보안 보조 프로세서)를 지원하는 경우 추가로 다음을 수행해야 합니다.
    • 메인 CPU 재부팅을 감지할 수 있습니다.
    • 재부팅 후에도 지속되는 하드웨어 타이머 소스가 있어야 합니다. 즉, 엔클레이브는 재부팅을 감지하고 재부팅 전에 설정된 타이머를 만료할 수 있어야 합니다.
    • 오프라인 공격으로 복구할 수 없도록 엔클레이브 RAM/ROM에 에스크로된 키 저장을 지원합니다. 내부자나 공격자가 복구할 수 없도록 하는 방식으로 RoR 키를 저장해야 합니다.

기본 RAM 에스크로

AOSP는 RAM 지속성을 사용하여 RoR HAL을 구현합니다. 이것이 작동하려면 OEM은 SoC가 재부팅 시 RAM 지속성을 지원하는지 확인해야 합니다. 일부 SoC는 재부팅 후에도 RAM 콘텐츠를 유지할 수 없으므로 OEM은 이 기본 HAL을 활성화하기 전에 SoC 파트너에게 문의하는 것이 좋습니다. 다음 섹션에서 이에 대한 표준 참조입니다.

RoR을 이용한 OTA 업데이트 흐름

전화의 OTA 클라이언트 앱에는 RoR을 구현하는 데 필요한 메서드를 호출할 수 있는 Manifest.permission.REBOOTManifest.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/pmem0 (예: pmem1 또는 pmem2 )과 같은 이름을 가진 새 장치가 있는지 확인합니다.

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