このドキュメントでは、Android デジタル著作権管理(DRM)フレームワークの概要と、DRM プラグインが実装する必要があるインターフェースについて説明します。DRM スキームによって定義される堅牢性ルールやコンプライアンス ルールについては説明しません。
フレームワーク
Android プラットフォームは、コンテンツに関連付けられたライセンス制約に従って、アプリが著作権で保護されたコンテンツを管理できる、拡張可能な DRM フレームワークを提供します。DRM フレームワークは多くの DRM スキームをサポートしています。デバイスがサポートする DRM スキームはデバイス メーカーによります。DRM フレームワークは、アプリ デベロッパーに一元化されたインターフェースを提供し、DRM オペレーションの複雑さを軽減します。また、保護されたコンテンツと保護されていないコンテンツに対して一貫性のあるオペレーション モードを提供します。DRM スキームでは、ライセンス メタデータによって複雑な使用モデルを定義できます。DRM フレームワークで DRM コンテンツとライセンスの間の関連付けを提供し、著作権管理を処理します。これにより、DRM で保護されたコンテンツまたは保護されていないコンテンツからメディア プレーヤーを抽象化できます。保護されたメディア ストリームを復号するための鍵を取得するクラスについては、MediaDrm をご覧ください。
モバイル デバイスのユーザーにとって、リッチ デジタル コンテンツを利用できることは大切です。コンテンツを多機種で利用できるようにするには、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 と 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 を実装するには:
- プラグイン サービスをデバイスのビルドファイルに追加します。
- デバイス マニフェストを更新します。
- SELinux の権限を追加します。
/vendor
に.rc
ファイルを作成します。- プラグインを実装します。
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 の権限の追加
VENDOR DEVICE/sepolicy/vendor/file.te
に追加します。
type mediadrm_vendor_data_file, file_type, data_file_type;
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:s0device/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 言語をご覧ください。
プラグインの実装
- プラグイン サービスの
service.cpp
にmain()
エントリ ポイントを実装します。 ICryptoPlugin
、IDrmPlugin
、ICryptoFactory
、IDrmFactory
を実装します。- 新しい 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 にあります。