chromium/chromeos/components/cdm_factory_daemon/mojom/content_decryption_module.mojom

// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Next MinVersion: 4

module chromeos.cdm.mojom;

// Provides an interface a CDM implementation in the daemon. This interface is
// meant to translate to the media/base/content_decryption_module.h interface in
// Chrome. The media/base/decryptor.h functionality is also included because
// this implementation ties both of them together and does not need that
// abstracted away, however this only implements the decrypt functionality of
// that interface and not decrypt + decode.
//
// We do not use the corresponding mojo interfaces that already exist in Chrome
// because we need to do version management so we can handle version diffs
// between Chrome and Chrome OS.

// See media::EmeInitDataType.
[Stable, Extensible]
enum EmeInitDataType {
  UNKNOWN,
  WEBM,
  CENC,
  KEYIDS,
};

// See media::CdmSessionType
[Stable, Extensible]
enum CdmSessionType {
  kTemporary,
  kPersistentLicense,
};

// See media::CdmMessageType
[Stable, Extensible]
enum CdmMessageType {
  LICENSE_REQUEST,
  LICENSE_RENEWAL,
  LICENSE_RELEASE,
  INDIVIDUALIZATION_REQUEST,
};

// See media::CdmKeyInformation::KeyStatus
[Stable, Extensible]
enum CdmKeyStatus {
  USABLE,
  INTERNAL_ERROR,
  EXPIRED,
  OUTPUT_RESTRICTED,
  OUTPUT_DOWNSCALED,
  KEY_STATUS_PENDING,
  RELEASED,
};

// See media::HdcpVersion
[Stable, Extensible]
enum HdcpVersion {
  kHdcpVersionNone,
  kHdcpVersion1_0,
  kHdcpVersion1_1,
  kHdcpVersion1_2,
  kHdcpVersion1_3,
  kHdcpVersion1_4,
  kHdcpVersion2_0,
  kHdcpVersion2_1,
  kHdcpVersion2_2,
  kHdcpVersion2_3,
};

// See media::CdmPromise::Exception
[Stable, Extensible]
enum PromiseException {
  NOT_SUPPORTED_ERROR,
  INVALID_STATE_ERROR,
  QUOTA_EXCEEDED_ERROR,
  TYPE_ERROR,
};

// Transport layer of media::CdmPromise (see media/base/cdm_promise.h).
// - When |success| is true, the promise is resolved and all other fields should
//   be ignored.
// - When |success| is false, the promise is rejected with |exception|,
//   |system_code| and |error_message|.
[Stable]
struct CdmPromiseResult {
  bool success;
  PromiseException exception;
  uint32 system_code;
  string error_message;
};

// Transport layer of media::CdmKeyInformation (see
// media/base/cdm_key_information.h). It is used to specify a key_id and it's
// associated status.
[Stable]
struct CdmKeyInformation {
  array<uint8> key_id;
  CdmKeyStatus status;
  uint32 system_code;
};

[Stable, Extensible]
enum EncryptionScheme {
  kCenc,
  kCbcs
};

[Stable]
struct EncryptionPattern {
  uint32 crypt_byte_block;
  uint32 skip_byte_block;
};

// See media::SubsampleEntry
[Stable]
struct SubsampleEntry {
  uint32 clear_bytes;
  uint32 cipher_bytes;
};

[Stable]
struct DecryptConfig {
  EncryptionScheme encryption_scheme;
  string key_id;
  string iv;
  array<SubsampleEntry> subsamples;
  EncryptionPattern? encryption_pattern;
};

[Stable, Extensible]
enum DecryptStatus {
  kSuccess,
  kNoKey,
  kFailure
};

// Next Method ID: 11
// These method calls originate in the Chrome GPU process and end up in the
// cdm-oemcrypto daemon in ChromeOS.
[Stable, Uuid="cbe7142d-379a-4b23-bfee-a370ab01bdea"]
interface ContentDecryptionModule {
  // Provides a server certificate to be used to encrypt messages to the
  // license server.
  SetServerCertificate@1(array<uint8> certificate_data)
      => (CdmPromiseResult result);

  // Gets the key status if there's a hypothetical key that requires the
  // |min_hdcp_version|. Resolve the |result| with the |key_status| after the
  // operation completes. Reject the |result| if this operation is not
  // supported or unexpected error happened.
  GetStatusForPolicy@2(HdcpVersion min_hdcp_version)
      => (CdmPromiseResult result, CdmKeyStatus key_status);

  // Creates a session with the |init_data_type|, |init_data| and |session_type|
  // provided. If |result.success| is false, the output |session_id| will be
  // empty.
  CreateSessionAndGenerateRequest@3(CdmSessionType session_type,
                                    EmeInitDataType init_data_type,
                                    array<uint8> init_data)
      => (CdmPromiseResult result, string session_id);

  // Loads the session associated with |session_id| and |session_type|.
  // Combinations of |result.success| and |session_id| means:
  //   (true, non-empty) : Session successfully loaded.
  //   (true, empty) : Session not found.
  //   (false, non-empty): N/A; this combination is not allowed.
  //   (false, empty) : Unexpected error. See other fields in |result|.
  LoadSession@4(CdmSessionType session_type, string session_id)
      => (CdmPromiseResult result, string session_id);

  // Updates a session specified by |session_id| with |response|.
  UpdateSession@5(string session_id, array<uint8> response)
      => (CdmPromiseResult result);

  // Closes the session specified by |session_id|.
  CloseSession@6(string session_id) => (CdmPromiseResult result);

  // Removes stored session data associated with the active session specified by
  // |session_id|.
  RemoveSession@7(string session_id) => (CdmPromiseResult result);

  // Decprecated: Do not use.
  DecryptDeprecated@8(array<uint8> encrypted_data, DecryptConfig decrypt_config)
      => (DecryptStatus status, array<uint8> decrypted_data);

  // Returns HW information for a specific key that is passed along as part of
  // HW decrypt+decode. |hw_identifier| is specific to the HW implementation
  // to allow it to correlate the decode session with the context to get the key
  // from.
  [MinVersion=1] GetHwKeyData@9(DecryptConfig decrypt_config,
                                array<uint8> hw_identifier) =>
      (DecryptStatus status, array<uint8> key_data);

  // Used for decrypting to clear, transcrypting to a secure buffer or
  // decrypting to secure memory. If |is_video| is true, then it will be
  // transcrypted to a secure buffer on supported platforms (e.g. AMD). If
  // |secure_handle| is non-zero, then it will be written to the corresponding
  // secure Trust Zone memory (ARM only). |secure_handle| is an identifier for
  // the corresponding secure memory that can be resolved in the TEE and not
  // a handle to the actual resource (we have another FD we use for that).
  // |decrypt_config_in| can be null if the input data is not encrypted.
  // |decrypt_config_out| will be non-null only in the case of transcryption and
  // will specify crypto information for the returned |decrypted_data|.
  [MinVersion=2]
  Decrypt@10(array<uint8> encrypted_data, DecryptConfig? decrypt_config_in,
             bool is_video,
             [MinVersion=3] uint64 secure_handle)
      => (DecryptStatus status, array<uint8> decrypted_data,
          DecryptConfig? decrypt_config_out);
};

// Session callbacks. See media/base/content_decryption_module.h for details.
// Next Method ID: 4
[Stable, Uuid="f08e6938-ac41-48b8-8f55-a381732b932b"]
interface ContentDecryptionModuleClient {
  // Called when the CDM needs to queue a message event to the session object.
  // See http://w3c.github.io/encrypted-media/#dom-evt-message
  OnSessionMessage@0(string session_id, CdmMessageType message_type,
                     array<uint8> message);

  // Called when the session specified by |session_id| is closed. Note that the
  // CDM may close a session at any point, such as in response to a
  // CloseSession() call, when the session is no longer needed, or when system
  // resources are lost.
  // See http://w3c.github.io/encrypted-media/#session-closed
  OnSessionClosed@1(string session_id);

  // Called when there has been a change in the keys in the session or their
  // status. See http://w3c.github.io/encrypted-media/#dom-evt-keystatuseschange
  OnSessionKeysChange@2(string session_id, bool has_additional_usable_key,
                      array<CdmKeyInformation> keys_info);

  // Provide session expiration update for |session_id|.
  // |new_expiry_time_sec| is the number of seconds since epoch (Jan 1, 1970).
  OnSessionExpirationUpdate@3(string session_id, double new_expiry_time_sec);
};