DRM

Android DRM HAL 아이콘

이 문서에서는 Android 디지털 권한 관리(DRM) 프레임워크를 간략하게 설명하며 DRM 플러그인이 구현해야 하는 인터페이스를 소개합니다. DRM 스키마에서 정의할 수 있는 견고성 규칙 또는 규정 준수 규칙을 설명하지는 않습니다.

프레임워크

Android 플랫폼은 확장 가능한 DRM 프레임워크를 제공하여 앱이 콘텐츠와 관련된 라이선스 제한에 따라 권한으로 보호되는 콘텐츠를 관리할 수 있도록 합니다. DRM 프레임워크는 많은 DRM 스키마를 지원하며 기기가 지원하는 DRM 스키마는 기기 제조업체가 결정합니다. DRM 프레임워크는 애플리케이션 개발자를 위한 통합 인터페이스를 제공하며 DRM 작업의 복잡성을 숨깁니다. DRM 프레임워크는 보호되는 콘텐츠와 보호되지 않는 콘텐츠에 일관된 작동 모드를 제공합니다. DRM 스키마는 라이선스 메타데이터별로 복잡한 사용 모델을 정의할 수 있습니다. DRM 프레임워크는 DRM 콘텐츠와 라이선스를 연결하고 권한 관리를 처리합니다. 이를 통해 DRM으로 보호되는 콘텐츠 또는 보호되지 않는 콘텐츠에서 미디어 플레이어를 추상화할 수 있습니다. 클래스가 보호되는 미디어 스트림을 복호화하기 위한 키를 얻는 방법은 MediaDrm을 참고하세요.

Android DRM HAL
그림 1a. Android 11 이전의 DRM 하드웨어 추상화 계층
Android DRM HAL R 이후
그림 1b. Android 11 이상에서의 DRM 하드웨어 추상화 계층

리치 디지털 콘텐츠의 사용 가능 여부는 휴대기기 사용자에게 중요합니다. 콘텐츠가 널리 사용될 수 있게 하려면 Android 개발자와 디지털 콘텐츠 게시자에게 Android 생태계 전반에서 지원되는 일관된 DRM 구현이 필요합니다. Android 기기에서 디지털 콘텐츠를 사용할 수 있고, 모든 기기에서 하나 이상의 일관된 DRM을 사용할 수 있도록 Google은 호환 가능한 Android 기기에 라이선스 요금 없이 DRM을 제공합니다. DRM 플러그인은 Android DRM 프레임워크와 통합되어 하드웨어 기반의 보호를 사용하여 프리미엄 콘텐츠와 사용자 인증 정보를 보호할 수 있습니다.

DRM 플러그인에서 제공하는 콘텐츠 보호는 기본 하드웨어 플랫폼의 보안 및 콘텐츠 보호 기능에 따라 다릅니다. 기기의 하드웨어 기능에는 보안 신뢰 체인 및 암호화 키 보호를 설정하는 하드웨어 안전한 부팅이 포함되어야 합니다. 기기의 콘텐츠 보호 기능에는 기기의 복호화된 프레임 보호 및 신뢰할 수 있는 출력 보호 메커니즘을 통한 콘텐츠 보호가 포함되어야 합니다. 모든 하드웨어 플랫폼이 위의 보안 및 콘텐츠 보호 기능을 모두 지원하는 것은 아닙니다. 보안은 스택의 단일 위치에서 구현되는 것이 아니라 하드웨어, 소프트웨어 및 서비스의 통합 속에 구현되어야 합니다. 하드웨어 보안 기능, 신뢰할 수 있는 부팅 메커니즘 및 보안 기능을 처리하기 위한 격리된 보안 OS는 모두 안전한 기기를 제공하는 데 중요한 영향을 미칩니다.

아키텍처

DRM 프레임워크는 구현과 무관하게 설계되었으며 스키마별 DRM 플러그인의 특정 DRM 스키마 구현 세부정보를 추상화합니다. DRM 프레임워크에는 복잡한 DRM 작업을 처리하고 라이선스를 취득하며 기기를 프로비저닝하고 DRM 콘텐츠와 라이선스를 연결하고 마지막으로 DRM 콘텐츠를 복호화하는 간단한 API가 포함됩니다.

Android DRM 프레임워크는 다음과 같은 두 가지 아키텍처 레이어로 구현됩니다.

  • DRM 프레임워크 API: Android 애플리케이션 프레임워크를 통해 앱에 노출됩니다.
  • 네이티브 코드 DRM 프레임워크: DRM 플러그인(에이전트)의 인터페이스를 노출하여 다양한 DRM 스키마의 권한 관리 및 복호화를 처리합니다.
Android DRM 프레임워크
그림 2a. Android 11 이전의 DRM 프레임워크
Android DRM 프레임워크
그림 2b. Android 11 이상에서의 DRM 프레임워크

자세한 내용은 Android 미디어 DRMAndroid 미디어 Crypto를 참고하세요.

DRM 플러그인

시스템 시작 시 DRM 프레임워크가 HAL 인스턴스/서비스(.rc 파일에 설명됨)를 스캔하고 플러그인을 찾습니다. 미디어 DRM 서버(mediadrmserver)는 CryptoHal 객체와 DrmHal 객체를 모두 생성합니다. 그러면 CryptoHalDrmHal은 공급업체별 구현을 사용하여 플러그인을 호출합니다.

플러그인은 바인더화된 HAL을 구현해야 합니다. 바인더화된 HAL은 Android 인터페이스 정의 언어(AIDL)를 사용합니다. 이를 사용하면 HAL을 다시 빌드하지 않고 프레임워크를 교체할 수 있습니다.

플러그인은 공급업체 또는 SoC 제조업체에서 빌드하며 기기의 /vendor 파티션에 배치됩니다. Android 13 이상으로 출시되는 모든 기기는 AIDL 언어로 작성된 바인더화된 HAL을 지원해야 합니다.

구현

Android 13용 GMS 및 AOSP 기기 버전은 AIDL 인터페이스를 사용해야 합니다.

플러그인에서 새 DRM 프레임워크 API를 구현하려면 다음을 실행하세요.

  1. 기기의 빌드 파일에 플러그인 서비스를 추가합니다.
  2. 기기 매니페스트를 업데이트합니다.
  3. SELinux 권한을 추가합니다.
  4. /vendor.rc 파일을 생성합니다.
  5. 플러그인을 구현합니다.

API는 IDrmPlugin.aidl, ICryptoPlugin.aidl, IDrmFactory.aidlICryptoFactory.aidl의 각 버전에서 정의됩니다.

aidl/PLATFORM_ROOT/hardware/interfaces/drm/

기기의 빌드 파일에 플러그인 서비스 추가

예를 들어, AIDL 인터페이스 지원을 추가하려면 VENDOR DEVICE/device.mk 파일에 android.hardware.drm-service.* 패키지가 포함되어야 합니다.


  PRODUCT_PACKAGES += \
    android.hardware.drm-service.clearkey \
    android.hardware.drm-service.widevine

기기 매니페스트 업데이트

기기의 vendor manifest.xml 파일에는 다음 항목이 포함되어야 합니다.

  <hal format="aidl">
    <name>android.hardware.drm</name>
    <version>STABLE AIDL VERSION</version>
      <fqname>ICryptoFactory/clearkey</fqname>
      <fqname>IDrmFactory/clearkey</fqname>
      <fqname>ICryptoFactory/widevine</fqname>
      <fqname>IDrmFactory/widevine</fqname>
  </hal>

AIDL 공개 버전은 각 AIDL API 출시의 버전 번호입니다(예: 1, 2). 또는 vintf_fragments를 사용하는 것이 좋습니다.

SELinux 권한 추가

  1. VENDOR DEVICE/sepolicy/vendor/file.te에 추가
    type mediadrm_vendor_data_file, file_type, data_file_type;
  2. VENDOR DEVICE/sepolicy/vendor/file_contexts에 추가
        /vendor/bin/hw/android\.hardware\.drm-service\.clearkey  u:object_r:hal_drm_clearkey_exec:s0
    /data/vendor/mediadrm(/.*)? u:object_r:mediadrm_vendor_data_file:s0
  3. device/sepolicy/vendor/hal_drm_clearkey.te에 추가
        vndbinder_use(hal_drm_clearkey)
        allow hal_drm_clearkey servicemanager:binder { call transfer };
        allow hal_drm_clearkey hal_drm_service:service_manager add;
        allow hal_drm_clearkey { appdomain -isolated_app }:fd use;
        get_prop(ramdump, public_vendor_default_prop)
        

/vendor에 .rc 파일 생성

.rc 파일은 서비스가 시작될 때 실행할 작업을 지정합니다.

자세한 내용은 Android Init 언어를 참고하세요.

플러그인 구현

  1. 플러그인 서비스의 service.cpp에서 main() 진입점을 구현합니다.
  2. ICryptoPlugin, IDrmPlugin, ICryptoFactoryIDrmFactory를 구현합니다.
  3. 플러그인에 새 API를 구현합니다.

DRM 플러그인 세부정보

DRM 플러그인 공급업체는 DrmFactory, CryptoFactory 및 DRM 플러그인을 구현합니다.

DrmFactory

DrmHal 클래스는 등록된 DRM 플러그인 서비스를 검색하고 DrmFactory 클래스를 통해 지정된 암호화 스키마를 지원하는 해당 플러그인을 생성합니다.

IDrmFactory는 createPlugin API를 통해 공급업체의 DRM HAL과 상호작용하기 위한 기본 진입점입니다. createPlugin API는 IDrmPlugin 인스턴스를 생성하는 데 사용됩니다.

::ndk::ScopedAStatus getSupportedCryptoSchemes(
    std::vector<::aidl::android::hardware::drm::Uuid>* _aidl_return);

getSupportedCryptoSchemes는 AIDL DRM HAL 인스턴스에 지원되는 암호화 스키마 목록을 반환합니다.

::ndk::ScopedAStatus isCryptoSchemeSupported(
    const ::aidl::android::hardware::drm::Uuid& in_uuid,
    const std::string& in_mimeType,
    ::aidl::android::hardware::drm::SecurityLevel in_securityLevel,
    bool* _aidl_return);

플러그인 팩토리가 UUID로 지정되는 특정 암호화 스키마를 지원하는 DRM 플러그인을 생성할 수 있는지를 판별합니다.

::ndk::ScopedAStatus isContentTypeSupported(const std::string& in_mimeType,
    bool* _aidl_return);

플러그인 팩토리가 mimeType으로 지정된 특정 미디어 컨테이너 형식을 지원하는 DRM 플러그인을 생성할 수 있는지를 판별합니다.

::ndk::ScopedAStatus createPlugin(
    const ::aidl::android::hardware::drm::Uuid& in_uuid,
    const std::string& in_appPackageName,
    std::shared_ptr<::aidl::android::hardware::drm::IDrmPlugin>* _aidl_return);

UUID로 지정된 암호화 스키마의 DRM 플러그인을 생성합니다.

CryptoFactory

CryptoHal 클래스는 등록된 DRM 플러그인 서비스를 검색하고 CryptoFactory 클래스를 통해 지정된 암호화 스키마를 지원하는 해당 플러그인을 생성합니다.

::ndk::ScopedAStatus isCryptoSchemeSupported(
    const ::aidl::android::hardware::drm::Uuid& in_uuid,
    bool* _aidl_return);

암호화 팩토리가 UUID로 지정된 특정 암호화 스키마를 지원하는 암호화 플러그인을 생성할 수 있는지를 판별합니다.

::ndk::ScopedAStatus createPlugin(
    const ::aidl::android::hardware::drm::Uuid& in_uuid,
    const std::vector<uint8_t>& in_initData,
    std::shared_ptr<::aidl::android::hardware::drm::ICryptoPlugin>* _aidl_return);

플러그인 팩토리가 UUID로 지정된 특정 암호화 스키마를 지원하는 암호화 플러그인을 생성할 수 있는지를 판별합니다.

DRM 플러그인 API

API는 hardware/interfaces/drm/aidl/aidl_api/android.hardware.drm/ VERSION/android/hardware/drm/IDrmPlugin.aidl에 정의되어 있습니다. API에 대응하는 IDrmPlugin.h 파일은 빌드 후 out/Soong에서 확인할 수 있습니다.