DRM

Android DRM HAL アイコン

このドキュメントでは、Android デジタル著作権管理(DRM)フレームワークの概要と、DRM プラグインが実装する必要があるインターフェースについて説明します。DRM スキームによって定義される堅牢性ルールやコンプライアンス ルールについては説明しません。

フレームワーク

Android プラットフォームは、コンテンツに関連付けられたライセンス制約に従って、アプリが著作権で保護されたコンテンツを管理できる、拡張可能な DRM フレームワークを提供します。DRM フレームワークは多くの DRM スキームをサポートしています。デバイスがサポートする DRM スキームはデバイス メーカーによります。DRM フレームワークは、アプリ デベロッパーに一元化されたインターフェースを提供し、DRM オペレーションの複雑さを軽減します。また、保護されたコンテンツと保護されていないコンテンツに対して一貫性のあるオペレーション モードを提供します。DRM スキームでは、ライセンス メタデータによって複雑な使用モデルを定義できます。DRM フレームワークで DRM コンテンツとライセンスの間の関連付けを提供し、著作権管理を処理します。これにより、DRM で保護されたコンテンツまたは保護されていないコンテンツからメディア プレーヤーを抽象化できます。保護されたメディア ストリームを復号するための鍵を取得するクラスについては、MediaDrm をご覧ください。

Android DRM HAL
図 1a. Android 11 より前の DRM Hardware Abstraction Layer
Android DRM HAL ポスト R
図 1b. Android 11 以降の DRM Hardware Abstraction Layer

モバイル デバイスのユーザーにとって、リッチ デジタル コンテンツを利用できることは大切です。コンテンツを多機種で利用できるようにするには、Android デベロッパーとデジタル コンテンツ パブリッシャーは、Android エコシステム全体でサポートされる、一貫した DRM を実装する必要があります。このデジタル コンテンツを Android デバイスで利用できるようにし、あらゆるデバイスで一貫した DRM を少なくとも 1 つ利用できるようにするため、Google は互換性のある Android デバイスにおいて、ライセンス料なしで DRM を提供しています。DRM プラグインは Android DRM フレームワークと統合されており、ハードウェアによる保護を使用してプレミアム コンテンツとユーザー認証情報を保護します。

DRM プラグインが提供するコンテンツ保護は、基盤となるハードウェア プラットフォームのセキュリティ機能とコンテンツ保護機能によって異なります。デバイスのハードウェア機能には、セキュリティの信頼チェーンと暗号鍵の保護を確立するためのハードウェア セキュアブートが含まれている必要があります。デバイスのコンテンツ保護機能には、デバイス内の復号されたフレームの保護と、信頼できる出力保護メカニズムによるコンテンツ保護が含まれる必要があります。すべてのハードウェア プラットフォームが上記のセキュリティ機能とコンテンツ保護機能をすべてサポートしているわけではありません。セキュリティは、スタック内の 1 つの場所に実装されることはなく、ハードウェア、ソフトウェア、サービスの統合に依存します。セキュアなデバイスを提供するには、ハードウェア セキュリティ機能、信頼できるブート メカニズム、セキュリティ機能を処理するための分離されたセキュア OS の組み合わせが重要です。

アーキテクチャ

DRM フレームワークは、実装に依存しないように設計されており、スキーム固有の DRM プラグインで特定の DRM スキーム実装の詳細を抽象化します。DRM フレームワークには、複雑な DRM オペレーションの処理、ライセンスの取得、デバイスのプロビジョニング、DRM コンテンツとライセンスの関連付け、DRM コンテンツの復号を行うためのシンプルな API が含まれています。

Android DRM フレームワークは、次の 2 つのアーキテクチャ レイヤで実装されています。

  • DRM フレームワーク API。Android アプリ フレームワークを介してアプリに公開されます。
  • ネイティブ コード DRM フレームワーク。DRM プラグイン(エージェント)のインターフェースを公開し、さまざまな DRM スキームの権利の管理と復号を行います。
Android DRM フレームワーク
図 2a. Android 11 より前の DRM フレームワーク
Android DRM フレームワーク
図 2b. Android 11 以降の DRM フレームワーク

詳しくは、Android メディア DRM と Android メディア暗号化をご覧ください。

DRM プラグイン

システムの起動時に、DRM フレームワークは HAL インスタンス / サービス(.rc ファイルに記載)をスキャンし、プラグインが検出されます。メディア DRM サーバー(mediadrmserver)は、CryptoHal オブジェクトと DrmHal オブジェクトの両方を作成します。その後、CryptoHal と DrmHal はベンダー固有の実装でプラグインを呼び出します。

プラグインでは、バインダ化された 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.aidl、ICryptoFactory.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 Init 言語をご覧ください。

プラグインの実装

  1. プラグイン サービスの service.cpp に main() エントリ ポイントを実装します。
  2. ICryptoPlugin、IDrmPlugin、ICryptoFactory、IDrmFactory を実装します。
  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 で定義されています。対応する IDrmPlugin.h ファイルは、ビルド後の out/Soong にあります。