| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| library fuchsia.media; |
| |
| using fuchsia.io; |
| using fuchsia.mem; |
| |
| const uint32 KEY_ID_SIZE = 16; |
| const uint32 MAX_INIT_DATA_SIZE = 16; |
| |
| // Encryption modes as defined by ISO 23001-7: Common encryption in ISO base |
| // media file format files. These are defined as strings rather than enums so as |
| // to not limit the types of encryption formats to just the set as defined by |
| // the current Common Encryption standard. |
| const string ENCRYPTION_MODE_CENC = "cenc"; |
| const string ENCRYPTION_MODE_CBC1 = "cbc1"; |
| const string ENCRYPTION_MODE_CENS = "cens"; |
| const string ENCRYPTION_MODE_CBCS = "cbcs"; |
| |
| enum LicenseSessionType { |
| /// A session for which the license, keys, and record of the session are not |
| /// persisted. |
| TEMPORARY = 1; |
| /// A session for which the license, keys, and record of the session will be |
| /// persisted for offline use and can subsequently be loaded using |
| /// LoadSession(). |
| PERSISTENT_LICENSE = 2; |
| /// A session for which the the record of the session will be persisted, but |
| /// the keys and license will not be. |
| PERSISTENT_USAGE_RECORD = 3; |
| }; |
| |
| enum LicenseMessageType { |
| REQUEST = 1; |
| RENEWAL = 2; |
| RELEASE = 3; |
| }; |
| |
| enum LicenseInitDataType { |
| CENC = 0; |
| KEYIDS = 1; |
| WEBM = 2; |
| }; |
| |
| enum KeyStatus { |
| USABLE = 0; |
| EXPIRED = 1; |
| RELEASED = 2; |
| OUTPUT_RESTRICTED = 3; |
| OUTPUT_DOWNSCALED = 4; |
| STATUS_PENDING = 5; |
| INTERNAL_ERROR = 6; |
| }; |
| |
| struct LicenseInitData { |
| LicenseInitDataType type; |
| vector<uint8>:MAX_INIT_DATA_SIZE data; |
| }; |
| |
| /// LicenseMessage is for messages originating from the LicenseSession that the |
| /// caller must route to the license server. |
| struct LicenseMessage { |
| LicenseMessageType type; |
| fuchsia.mem.Buffer message; |
| }; |
| |
| /// LicenseServerMessage is for messages originating from the license server |
| /// that the caller must provide to the LicenseSession via |
| /// |ProcessLicenseServerMessage|. |
| struct LicenseServerMessage { |
| fuchsia.mem.Buffer message; |
| }; |
| |
| /// ProvisionMessage is for messages originating from the CDM that the caller |
| /// must route to the provisioning server. |
| struct ProvisionMessage { |
| fuchsia.mem.Buffer message; |
| }; |
| |
| /// ProvisionServerMessage is for messages originating from the provisioning |
| /// server that the caller must provide to the CDM via |
| /// |ProcessProvisionServerMessage|. |
| struct ProvisionServerMessage { |
| fuchsia.mem.Buffer message; |
| }; |
| |
| struct KeyId { |
| array<uint8>:KEY_ID_SIZE data; |
| }; |
| |
| struct KeyInfo { |
| KeyId key_id; |
| KeyStatus status; |
| }; |
| |
| struct DecryptorParams { |
| /// Requires the decryptor to only output to secure buffers. |
| bool require_secure_mode; |
| |
| /// Initial format details for the StreamProcessor. |
| FormatDetails input_details; |
| }; |
| |
| interface LicenseSession { |
| /// Generate a license request for a session based on the |init_data|. When |
| /// the LicenseMessage has been created, the |OnLicenseMessageGenerated| |
| /// event will be triggered with the message to be sent to the license |
| /// server. |
| GenerateLicenseRequest(LicenseInitData init_data); |
| |
| /// Inititiate the release process for the license session. This will cause |
| /// the CDM to generate a LicenseMessage through the |
| /// |OnLicenseMessageGenerated| event. The client must route that message |
| /// to the license server and the server's response to |
| /// |ProcessLicenseServerMessage|. Once the LicenseSession has received the |
| /// license server's reply, it will close the LicenseSession channel as this |
| /// session will no longer be usable. |
| GenerateLicenseRelease(); |
| |
| /// Update the LicenseSession with a message from the license server. All |
| /// responses from license requests, renewals, and releases should be routed |
| /// to the LicenseSession through this method. |
| ProcessLicenseServerMessage(LicenseServerMessage message); |
| |
| /// Create a Decryptor StreamProcessor interface to be used to decrypt |
| /// content. |
| CreateDecryptor(DecryptorParams params, request<StreamProcessor> decryptor); |
| |
| /// The LicenseSession has generated a message to be sent to the license |
| /// server. The client is responsible for transporting this message to the |
| /// license server. |
| -> OnLicenseMessageGenerated(LicenseMessage message); |
| |
| /// The LicenseSession has updated key status information. |
| -> OnKeysChanged(vector<KeyInfo> key_info); |
| }; |
| |
| [FragileBase] |
| interface ContentDecryptionModule { |
| /// Set the certificate to be used for encrypting outgoing messages. |
| SetServerCertificate(vector<uint8> certificate); |
| |
| /// Create a new session for the given type. The |session_id| will be |
| /// generated by the CDM and can be used to reload the session after |
| /// closing. |
| CreateLicenseSession(LicenseSessionType session_type, |
| request<LicenseSession> license_session) |
| -> (string session_id); |
| |
| /// Load an existing session from persistent storage using the given |
| /// |session_id|. If the session is not found, then the |license_session| |
| /// will be closed. |
| LoadLicenseSession(string session_id, request<LicenseSession> license_session); |
| |
| /// Update the CDM with a message from the provisioning server. Not all |
| /// underlying CDM systems will require provisioning for individual |
| /// providers. If they do, this method will carry the provisioning message |
| /// to the CDM instance so that it may persistently store the provider |
| /// certificate. |
| ProcessProvisionServerMessage(ProvisionServerMessage message); |
| |
| /// Remove the persistent session data associated with the session without |
| /// waiting for server acknowledgement. No LicenseMessage will be generated. |
| /// If there is an active LicenseSession for this |session_id|, it will be |
| /// closed. |
| RemoveLicenseSessionData(string session_id); |
| |
| /// Check whether the device has been provisioned. Some CDM systems will be |
| /// entirely provisioned at the time of device manufacturing, while others |
| /// might require additional provisioning for a given content provider. This |
| /// provisioning status will indicate whether the CDM is capable of |
| /// generating license requests. |
| IsProvisioned() -> (bool is_provisioned); |
| |
| /// Removes all provider based provisioning for this CDM instance. This does |
| /// not impact any factory provisioning. |
| RemoveProvisioning(); |
| |
| /// Remove all persistent usage records for this CDM instance. Any |
| /// associated license sessions will no longer be usable. |
| RemoveUsageRecords(); |
| |
| /// Query the status of a hypothetical key associated with an HDCP policy |
| /// without setting up a license session. This aids clients in determining |
| /// which content type to fetch prior to establishing. For example, if the |
| /// device would restrict output for HDCP 1.x, then the client can choose to |
| /// fetch SD content rather than HD. |
| GetKeyStatusForHdcpVersion(string hdcp_version) -> (KeyStatus key_status); |
| |
| /// Query the CDM for the list of supported encryption modes, such as |
| /// 'cenc', 'cbc1', 'cens', or 'cbcs'. |
| GetSupportedEncryptionModes() -> (vector<string> encryption_modes); |
| |
| /// If the underlying CDM system requires provisioning for individual |
| /// providers (the owner of the CDM instance), then it will generate a |
| /// ProvisionMessage the first time a LicenseSession attempts to request a |
| /// license. This message must be routed to the provisioning server by the |
| /// client and the server's response provided to the CDM by calling |
| /// |ProcessProvisionServerMessage|. |
| -> OnProvisionMessageGenerated(ProvisionMessage message); |
| }; |
| |
| // There are two ways to create the desired ContentDecryptionModule. Which |
| // method to use is dependent on how persistent storage should be provided to |
| // the CDM. The preferred method to use is the per key system discoverable |
| // interface. This method will rely on the componentmgr to create the CDM |
| // instance's persistent storage for it. This provides isolation of the storage |
| // location from the client. |
| // |
| // The second method is to use the discoverable ContentDecryptionModuleFactory |
| // and request that it creates the CDM on the client's behalf. Using this method |
| // requires the client to provide the storage to be used. This storage should be |
| // isolated to distinct origins/providers. |
| |
| [Discoverable] |
| interface ClearKeyContentDecryptionModule : ContentDecryptionModule { |
| }; |
| |
| [Discoverable] |
| interface WidevineContentDecryptionModule : ContentDecryptionModule { |
| }; |
| |
| [Discoverable] |
| interface PlayReadyContentDecryptionModule : ContentDecryptionModule { |
| }; |
| |
| [Discoverable] |
| interface ContentDecryptionModuleFactory { |
| /// The Factory interface should only be used if the client needs to inject |
| /// the storage to be used by the CDM. The storage must be a unique location |
| /// per origin/ provider. |
| CreateClearKeyContentDecryptionModule( |
| fuchsia.io.Directory data_directory, |
| request<ClearKeyContentDecryptionModule> cdm); |
| |
| CreateWidevineContentDecryptionModule( |
| fuchsia.io.Directory data_directory, |
| request<WidevineContentDecryptionModule> cdm); |
| |
| CreatePlayReadyContentDecryptionModule( |
| fuchsia.io.Directory data_directory, |
| request<PlayReadyContentDecryptionModule> cdm); |
| }; |