数字版权管理

Android DRM HAL 图标

本文档概述了 Android 数字版权管理 (DRM) 框架,并介绍了 DRM 插件必须实现的接口。本文档不描述 DRM 方案可能定义的稳健性规则或合规性规则。

框架

Android 平台提供了一个可扩展的 DRM 框架,允许应用根据与内容相关的许可限制来管理受版权保护的内容。 DRM 框架支持多种 DRM 方案;设备支持哪些 DRM 方案取决于设备制造商。 DRM 框架为应用程序开发人员提供了统一的接口,并隐藏了 DRM 操作的复杂性。 DRM 框架为受保护和不受保护的内容提供一致的操作模式。 DRM 方案可以通过许可证元数据定义复杂的使用模型。 DRM 框架提供 DRM 内容和许可证之间的关联,并处理权限管理。这使得媒体播放器可以从受 DRM 保护或不受保护的内容中抽象出来。有关获取解密受保护媒体流的密钥的类,请参阅MediaDrm

安卓 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 插件提供的内容保护取决于底层硬件平台的安全和内容保护能力。设备的硬件功能应包括硬件安全启动,以建立安全信任链和加密密钥保护。设备的内容保护能力应包括保护设备中的解密帧和通过可信输出保护机制保护内容。并非所有硬件平台都支持上述所有安全和内容保护功能。安全性永远不会在堆栈中的一个地方实现,而是依赖于硬件、软件和服务的集成。硬件安全功能、受信任的引导机制和用于处理安全功能的隔离安全操作系统的组合对于提供安全设备至关重要。

建筑学

DRM 框架设计为与实现无关,并在特定于方案的 DRM 插件中抽象了特定 DRM 方案实现的细节。 DRM 框架包括简单的 API 来处理复杂的 DRM 操作、获取许可证、配置设备、关联 DRM 内容及其许可证,最后解密 DRM 内容。

Android DRM 框架在两个架构层中实现:

  • 一个 DRM 框架 API,通过 Android 应用程序框架向应用程序公开。
  • 本机代码 DRM 框架,它为 DRM 插件(代理)公开了一个接口,以处理各种 DRM 方案的权限管理和解密。
Android DRM 框架
图 2a。 Android 11 之前的 DRM 框架
Android DRM 框架
图 2b。从 Android 11 开始的 DRM 框架

有关详细信息,请参阅Android Media DRMAndroid Media Crypto

数字版权管理插件

在系统启动时,DRM 框架会扫描 HAL 实例/服务(在.rc文件中描述)并发现插件。媒体 DRM 服务器 ( mediadrmserver ) 创建CryptoHalDrmHal对象。 CryptoHalDrmHal然后调用具有供应商特定实现的插件。

插件应该实现绑定的 HAL。 Binderized 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.aidlICryptoPlugin.aidlIDrmFactory.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>

STABLE AIDL VERSION 是每个 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 初始化语言

实现插件

  1. 在插件服务的service.cpp中实现main()入口点。
  2. 实现ICryptoPluginIDrmPluginICryptoFactoryIDrmFactory
  3. 在插件中实现新的 API。

DRM 插件详细信息

DRM 插件供应商实现DrmFactoryCryptoFactory和 DRM 插件。

工厂

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);

确定插件工厂是否能够构建支持给定加密方案的 DRM 插件,该加密方案由 UUID 指定。

::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 插件。

加密工厂

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中定义。对应的IDrmPlugin.h文件可以在构建后的 out/Soong 中找到。