blob: 1b9980c49d271ff56d1f2a2bcdea8dc41e392151 [file] [log] [blame]
// 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";
// Common initialization data formats. These are defined as strings rather than
// enums so as to not limit the types a ContentDecryptionModule may support.
const string LICENSE_INIT_DATA_TYPE_CENC = "cenc";
const string LICENSE_INIT_DATA_TYPE_KEYIDS = "keyids";
const string LICENSE_INIT_DATA_TYPE_WEBM = "webm";
const string LICENSE_INIT_DATA_TYPE_HLS = "hls";
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 {
/// The type is a string that indicates the format of the accompanying init
/// data. Common types include "cenc", "keyids", "webm", and "hls". CDMs may
/// also define their own.
string type;
bytes: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;
};
table DecryptorParams {
/// Requires the decryptor to only output to secure buffers.
1: bool require_secure_mode;
/// Initial format details for the StreamProcessor.
2: FormatDetails input_details;
};
protocol 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]
protocol ContentDecryptionModule {
/// Set the certificate to be used for encrypting outgoing messages.
SetServerCertificate(bytes 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]
protocol ClearKeyContentDecryptionModule {
compose ContentDecryptionModule;
};
[Discoverable]
protocol WidevineContentDecryptionModule {
compose ContentDecryptionModule;
};
[Discoverable]
protocol PlayReadyContentDecryptionModule {
compose ContentDecryptionModule;
};
[Discoverable]
protocol 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);
};