DRM

Android DRM HAL 图标

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

框架

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

安卓 DRM HAL
图 1. DRM 硬件抽象层

能否提供丰富的数字内容,对移动设备用户来说非常重要。为保证内容的广泛覆盖面,Android 开发者和数字内容发布者需要在整个 Android 生态系统中实现受支持的一致的 DRM。为了让这类数字内容适用于 Android 设备,并确保至少有一个一致的 DRM 可用于所有设备,Google 会在兼容的 Android 设备上提供无需支付许可费用的 DRM。DRM 插件会与 Android DRM 框架集成在一起,并可使用受硬件支持的保护功能来确保付费内容和用户凭据的安全。

DRM 插件提供的内容保护功能取决于底层硬件平台的安全和内容保护功能。设备的硬件功能应包括硬件安全启动,可建立加密密钥的安全和保护功能的信任链。设备的内容保护功能应包括设备内加密帧的保护和通过可信输出保护机制实现的内容保护。并非所有硬件平台都支持上述所有的安全和内容保护功能。安全功能绝不会在堆栈的单个位置实现,而是依赖于硬件、软件和服务的集成。将硬件安全功能、可信启动机制以及用于处理安全功能的隔离安全操作系统组合使用是保障安全设备的关键。

架构

DRM 框架与实现无关,可在方案特定的 DRM 插件中提取特定 DRM 方案实现的详情。DRM 框架包括可执行以下操作的简单 API:处理复杂的 DRM 操作,获取许可,配置设备,将 DRM 内容与其许可相关联,以及最终解密 DRM 内容。

Android DRM 是在以下两个架构层中实现的:

  • DRM framework API:通过 Android 应用框架提供给应用。
  • 本机代码 DRM 框架:为 DRM 插件(代理)提供接口,以便处理各种 DRM 方案的版权管理和解密操作。
Android DRM 框架
图 2. DRM 框架

如需了解详情,请参阅 Android 媒体 DRMAndroid 媒体加密

DRM 插件

在系统启动时,DRM 框架会扫描 HAL 实例/服务(如 .rc 文件中所述),并通过 HIDL 注册表发现插件。媒体 DRM 服务器 (mediadrmserver) 创建 CryptoHalDrmHal 对象。 然后,CryptoHalDrmHal 使用供应商专用实现来调用发现的插件。

插件应实现绑定式 HAL。绑定式 HAL 使用 HAL 接口定义语言 (HIDL),HIDL 支持在不重新构建 HAL 的情况下替换框架。

插件由供应商或 SOC 制造商构建,放置在设备的 /vendor 分区中。所有在上市时即搭载了 Android 8.0 或更高版本的设备都必须支持使用 HIDL 语言编写的绑定式 HAL。

实现

要通过插件实现新的 DRM 框架 API,请执行以下操作:

  1. 将插件服务添加到设备的构建文件中。
  2. 更新设备清单。
  3. 添加 SELinux 权限。
  4. /vendor 下创建 .rc 文件。
  5. 实现插件。

新的 API 在 iDrmPlugin.haliCryptoPlugin.hal 中定义。

PLATFORM_ROOT/hardware/interfaces/drm/VERSION/

将插件服务添加到设备的构建文件中

例如,要添加接口 1.2 支持,VENDOR DEVICE/device.mk 文件必须包含 android.hardware.drm@1.2-service.* 软件包:


  PRODUCT_PACKAGES += \
    android.hardware.drm@1.0-impl \
    android.hardware.drm@1.0-service \
    android.hardware.drm@1.2-service.clearkey \
    android.hardware.drm@1.2-service.widevine

更新设备清单

设备的 vendor manifest.xml 文件必须包含以下条目:


  <hal format="hidl">
    <name>android.hardware.drm</name>
      <transport>hwbinder</transport>
      <version>1.0</version>
      <interface>
        <name>ICryptoFactory</name>
        <instance>default</instance>
      </interface>
      <interface>
        <name>IDrmFactory</name>
        <instance>default</instance>
      </interface>
      <fqname>@1.2::ICryptoFactory/clearkey</fqname>
      <fqname>@1.2::IDrmFactory/clearkey</fqname>
      <fqname>@1.2::ICryptoFactory/widevine</fqname>
      <fqname>@1.2::IDrmFactory/widevine</fqname>
  </hal>

添加 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@1\.2-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
    allow hal_drm_clearkey mediadrm_vendor_data_file:dir create_dir_perms;
        allow hal_drm_clearkey mediadrm_vendor_data_file:file create_file_perms;
        

在 /vendor 下创建 .rc 文件

.rc 文件指定服务启动时要采取的操作。

如需了解详情,请参阅 Android Init 语言

实现插件

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

DRM 插件详情

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

DrmFactory

DrmHal 类会搜索已注册的 DRM 插件服务,并通过 DrmFactory 类构建支持给定加密方案的相应插件。

Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>uuid);

确定插件工厂能否构建支持给定加密方案(由 UUID 指定)的 DRM 插件。

Return<bool> isContentTypeSupported(const hidl_string &mimeType);

确定插件工厂能否构建支持给定媒体容器格式(由 mimeType 指定)的 DRM 插件。

Return<void> createPlugin(const hidl_array<uint8_t, 16>uuid,
        const hidl_string& appPackageName, createPlugin_cb _hidl_cb);

为 UUID 指定的加密方案构建 DRM 插件。

CryptoFactory

CryptoHal 类会搜索已注册的 DRM 插件服务,并通过 CryptoFactory 类构建支持给定加密方案的相应插件。

Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>uuid);

确定加密工厂能否构建支持给定加密方案(由 UUID 指定)的加密插件。

Return<void> createPlugin(const hidl_array<uint8_t, 16>uuid,
        const hidl_vec<uint8_t>initData, createPlugin_cb _hidl_cb)

确定插件工厂能否构建支持给定加密方案(由 UUID 指定)的加密插件。

DRM 插件

API 在 hardware/interfaces/drm/VERSION /IDrmPlugin.hal 中定义。构建完成后,可以在 out/Soong 中找到相应的 IDrmPlugin.h 文件。