// Copyright 2017 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: 5
// The original version of this file lives in the Chromium repository at:
// src/components/arc/mojom/oemcrypto.mojom
// This file defines the mojo interface between Android, Chrome and the
// Chrome OS daemon for the Widevine L1 OEMCrypto implementation used in ARC++.
// This file matches what's in Widevine's OEMCryptoCENC.h file closely and all
// methods are documented there.
// Version 1 of this interface supported OEMCrypto v11 and is now deprecated.
// Version 2 supports OEMCrypto v14.
// Version 3 maintains backwards compatibility with version 2 and supports
// OEMCrypto v15.
// Version 4 maintains backwards compatibility and supports OEMCrypto v16.
// Version 5 adds the v16 CopyBuffer variant.
module arc.mojom;
[Stable, Extensible]
enum OemCryptoResult {
SUCCESS = 0,
ERROR_INIT_FAILED = 1,
ERROR_TERMINATE_FAILED = 2,
ERROR_OPEN_FAILURE = 3,
ERROR_CLOSE_FAILURE = 4,
ERROR_ENTER_SECURE_PLAYBACK_FAILED = 5,
ERROR_EXIT_SECURE_PLAYBACK_FAILED = 6,
ERROR_SHORT_BUFFER = 7,
ERROR_NO_DEVICE_KEY = 8,
ERROR_NO_ASSET_KEY = 9,
ERROR_KEYBOX_INVALID = 10,
ERROR_NO_KEYDATA = 11,
ERROR_NO_CW = 12,
ERROR_DECRYPT_FAILED = 13,
ERROR_WRITE_KEYBOX = 14,
ERROR_WRAP_KEYBOX = 15,
ERROR_BAD_MAGIC = 16,
ERROR_BAD_CRC = 17,
ERROR_NO_DEVICEID = 18,
ERROR_RNG_FAILED = 19,
ERROR_RNG_NOT_SUPPORTED = 20,
ERROR_SETUP = 21,
ERROR_OPEN_SESSION_FAILED = 22,
ERROR_CLOSE_SESSION_FAILED = 23,
ERROR_INVALID_SESSIONS = 24,
ERROR_NOT_IMPLEMENTED = 25,
ERROR_NO_CONTENT_KEY = 26,
ERROR_CONTROL_INVALID = 27,
ERROR_UNKNOWN_FAILURE = 28,
ERROR_INVALID_CONTEXT = 29,
ERROR_SIGNATURE_FAILURE = 30,
ERROR_TOO_MANY_SESSIONS = 31,
ERROR_INVALID_NONCE = 32,
ERROR_TOO_MANY_KEYS = 33,
ERROR_DEVICE_NOT_RSA_PROVISIONED = 34,
ERROR_INVALID_RSA_KEY = 35,
ERROR_KEY_EXPIRED = 36,
ERROR_INSUFFICIENT_RESOURCES = 37,
ERROR_INSUFFICIENT_HDCP = 38,
ERROR_BUFFER_TOO_LARGE = 39,
[MinVersion=2] WARNING_GENERATION_SKEW = 40, // Warning, not an error.
[MinVersion=2] ERROR_GENERATION_SKEW = 41,
[MinVersion=2] LOCAL_DISPLAY_ONLY = 42, // Info, not an error.
[MinVersion=2] ERROR_ANALOG_OUTPUT = 43,
[MinVersion=2] ERROR_WRONG_PST = 44,
[MinVersion=2] ERROR_WRONG_KEYS = 45,
[MinVersion=2] ERROR_MISSING_MASTER = 46,
[MinVersion=2] ERROR_LICENSE_INACTIVE = 47,
[MinVersion=2] ERROR_ENTRY_NEEDS_UPDATE = 48,
[MinVersion=2] ERROR_ENTRY_IN_USE = 49,
[MinVersion=2] ERROR_USAGE_TABLE_UNRECOVERABLE = 50, // Reserved. Do not use.
[MinVersion=2] KEY_NOT_LOADED = 51,
[MinVersion=2] KEY_NOT_ENTITLED = 52,
[MinVersion=3] ERROR_BAD_HASH = 53,
[MinVersion=3] ERROR_OUTPUT_TOO_LARGE = 54,
[MinVersion=3] ERROR_SESSION_LOST_STATE = 55,
[MinVersion=3] ERROR_SYSTEM_INVALIDATED = 56,
[MinVersion=4] ERROR_LICENSE_RELOAD = 57,
[MinVersion=4] ERROR_MULTIPLE_USAGE_ENTRIES = 58,
[MinVersion=4] WARNING_MIXED_OUTPUT_PROTECTION = 59,
[MinVersion=4] ODK_ERROR_CORE_MESSAGE = 1000,
[MinVersion=4] ODK_SET_TIMER = 1001,
[MinVersion=4] ODK_DISABLE_TIMER = 1002,
[MinVersion=4] ODK_TIMER_EXPIRED = 1003,
[MinVersion=4] ODK_UNSUPPORTED_API = 1004,
[MinVersion=4] ODK_STALE_RENEWAL = 1005,
};
[Stable]
struct OemCryptoSecureBuffer {
// buffer_handle should be passed to the ProtectedBufferManager service in
// the GPU in order to retrieve the shared memory handle that corresponds
// to the actual secure buffer. It should then be mapped and data written at
// offset up until offset + max_length.
handle buffer_handle;
uint32 max_length;
uint32 offset;
};
[Stable, Extensible]
enum OemCryptoCipherMode {
CIPHER_MODE_CTR = 0,
CIPHER_MODE_CBC = 1,
};
[Stable, Extensible]
enum OemCryptoLicenseType {
CONTENT_LICENSE = 0,
ENTITLEMENT_LICENSE = 1,
};
[Stable]
struct OemCryptoSubstring {
uint32 offset;
uint32 length;
};
[Stable]
struct OemCryptoKeyObjectV14 {
uint32 key_id_offset;
uint32 key_id_length;
uint32 key_data_iv_offset;
uint32 key_data_offset;
uint32 key_data_length;
uint32 key_control_iv_offset;
uint32 key_control_offset;
OemCryptoCipherMode cipher_mode;
};
[Stable]
struct OemCryptoKeyObject {
OemCryptoSubstring key_id;
OemCryptoSubstring key_data_iv;
OemCryptoSubstring key_data;
OemCryptoSubstring key_control_iv;
OemCryptoSubstring key_control;
};
[Stable]
struct OemCryptoEntitledContentKeyObjectV14 {
array<uint8> entitlement_key_id;
array<uint8> content_key_id;
array<uint8, 16> content_key_data_iv;
array<uint8> content_key_data;
};
[Stable]
struct OemCryptoEntitledContentKeyObject {
OemCryptoSubstring entitlement_key_id;
OemCryptoSubstring content_key_id;
OemCryptoSubstring content_key_data_iv;
OemCryptoSubstring content_key_data;
};
[Stable]
struct OemCryptoKeyRefreshObjectV14 {
uint32 key_id_offset;
uint32 key_id_length;
bool has_key_control_iv;
uint32 key_control_iv_offset;
uint32 key_control_offset;
};
[Stable]
struct OemCryptoKeyRefreshObject {
OemCryptoSubstring key_id;
OemCryptoSubstring key_control_iv;
OemCryptoSubstring key_control;
};
[Stable, Extensible]
enum OemCryptoAlgorithm {
AES_CBC_128_NO_PADDING = 0,
HMAC_SHA265 = 1,
};
[Stable]
struct OemCryptoCencEncryptPatternDesc {
uint32 encrypt;
uint32 skip;
uint32 offset;
};
[Stable, Extensible]
enum OemCryptoUsageEntryStatus {
UNUSED = 0,
ACTIVE = 1,
INACTIVE = 2,
INACTIVE_USED = 3,
INACTIVE_UNUSED = 4,
};
[Stable]
struct OemCryptoPstReport {
array<uint8, 20> signature;
uint8 status;
uint8 clock_security_level;
uint64 seconds_since_license_received;
uint64 seconds_since_first_decrypt;
uint64 seconds_since_last_decrypt;
};
[Stable, Extensible]
enum OemCryptoRsaPaddingScheme {
SIGN_RSASSA_PSS = 1,
SIGN_PKCS1_BLOCK1 = 2,
};
[Stable, Extensible]
enum OemCryptoHdcpCapability {
HDCP_NONE = 0,
HDCP_V1 = 1,
HDCP_V2 = 2,
HDCP_V2_1 = 3,
HDCP_V2_2 = 4,
HDCP_V2_3 = 5,
HDCP_NO_DIGITAL_OUTPUT = 0xFF,
};
[Stable, Extensible]
enum OemCryptoProvisioningMethod {
PROVISIONING_ERROR = 0,
DRM_CERTIFICATE = 1,
KEYBOX = 2,
OEM_CERTIFICATE = 3,
};
[Stable, Extensible]
enum OemCryptoPrivateKey {
RSA_PRIVATE_KEY = 0,
ECC_PRIVATE_KEY = 1,
};
[Stable]
struct SubSampleDescription {
uint32 num_bytes_clear;
uint32 num_bytes_encrypted;
uint8 subsample_flags;
uint32 block_offset;
};
// This is the interface that implements all the calls that map to the
// OEMCrypto API itself.
// Next method ID: 77
[Stable, Uuid="ed3807bc-7bce-472d-be4f-68774e613ace"]
interface OemCryptoService {
InitializeDeprecated@0() => (OemCryptoResult result);
[MinVersion=2] Initialize@36(uint32 oemcrypto_version)
=> (OemCryptoResult result);
Terminate@1() => (OemCryptoResult result);
OpenSession@2() => (OemCryptoResult result, uint32 session);
CloseSession@3(uint32 session) => (OemCryptoResult result);
GenerateDerivedKeys@4(uint32 session, array<uint8> mac_key_context,
array<uint8> enc_key_context)
=> (OemCryptoResult result);
GenerateNonce@5(uint32 session) => (OemCryptoResult result, uint32 nonce);
GenerateSignature@6(uint32 session, array<uint8> message)
=> (OemCryptoResult result, array<uint8>? signature);
// The offset values are offsets into the message parameter for those values.
// If they have a length and it's zero, then they are NULL; if there is no
// length param then a bool param is there to indicate presence.
LoadKeysV11OrV12@7(uint32 session, array<uint8> message,
array<uint8> signature, bool has_enc_mac_keys,
uint32 enc_mac_keys_iv_offset,
uint32 enc_mac_keys_offset,
array<OemCryptoKeyObjectV14> key_array,
uint32 pst_offset, uint32 pst_length)
=> (OemCryptoResult result);
RefreshKeysV14@8(uint32 session, array<uint8> message,
array<uint8> signature,
array<OemCryptoKeyRefreshObjectV14> key_array)
=> (OemCryptoResult result);
QueryKeyControl@9(uint32 session, array<uint8> key_id)
=> (OemCryptoResult result, array<uint8>? key_control_block);
SelectKeyV13@10(uint32 session, array<uint8> key_id)
=> (OemCryptoResult result);
DecryptCencV15@11(uint32 session, array<uint8> data, bool is_encrypted,
array<uint8, 16> iv, uint32 block_offset,
OemCryptoSecureBuffer? secure_buffer,
OemCryptoCencEncryptPatternDesc pattern)
=> (OemCryptoResult result, array<uint8>? decrypted_data);
GenericEncrypt@12(uint32 session, array<uint8> data, array<uint8, 16> iv,
OemCryptoAlgorithm algorithm) =>
(OemCryptoResult result, array<uint8>? encrypted_data);
GenericDecrypt@13(uint32 session, array<uint8> data, array<uint8, 16> iv,
OemCryptoAlgorithm algorithm) =>
(OemCryptoResult result, array<uint8>? decrypted_data);
GenericSign@14(uint32 session, array<uint8> data,
OemCryptoAlgorithm algorithm) =>
(OemCryptoResult result, array<uint8>? signature);
GenericVerify@15(uint32 session, array<uint8> data,
OemCryptoAlgorithm algorithm, array<uint8> signature) =>
(OemCryptoResult result);
CopyBufferV14@16(array<uint8> data, OemCryptoSecureBuffer out_buffer)
=> (OemCryptoResult result);
LoadTestKeyboxV13@17() => (OemCryptoResult result);
IsRootKeyCertificateValid@18() => (OemCryptoResult result);
GetDeviceId@19() => (OemCryptoResult result, array<uint8>? device_id);
GetKeyData@20() => (OemCryptoResult result, array<uint8>? key_data);
GetRandom@21(uint32 length) => (OemCryptoResult result, array<uint8>? data);
GetNumberOfOpenSessions@22() => (OemCryptoResult result, uint32 num);
GetMaxNumberOfSessions@23() => (OemCryptoResult result, uint32 max);
RewrapDeviceRsaKey@24(uint32 session, array<uint8> message,
array<uint8> signature, uint32 nonce_offset,
uint32 enc_rsa_key_offset, uint32 enc_rsa_key_length,
uint32 enc_rsa_key_iv_offset)
=> (OemCryptoResult result, array<uint8>? wrapped_key);
LoadDeviceRsaKey@25(uint32 session, array<uint8> wrapped_rsa_key)
=> (OemCryptoResult result);
GenerateRsaSignature@26(uint32 session, array<uint8> message,
OemCryptoRsaPaddingScheme padding_scheme)
=> (OemCryptoResult result, array<uint8>? signature);
DeriveKeysFromSessionKey@27(uint32 session, array<uint8> enc_session_key,
array<uint8> mac_key_context,
array<uint8> enc_key_context)
=> (OemCryptoResult result);
SecurityPatchLevel@28() => (uint8 security_patch_level);
GetHdcpCapability@29() => (OemCryptoResult result,
OemCryptoHdcpCapability current,
OemCryptoHdcpCapability maximum);
UpdateUsageTable@30() => (OemCryptoResult result);
DeactivateUsageEntryV12@31(array<uint8> pst) => (OemCryptoResult result);
ReportUsage@32(uint32 session, array<uint8> pst)
=> (OemCryptoResult result, OemCryptoPstReport? report);
DeleteUsageEntry@33(uint32 session, uint32 pst_offset, uint32 pst_length,
array<uint8> message, array<uint8> signature) =>
(OemCryptoResult result);
ForceDeleteUsageEntry@34(array<uint8> pst) => (OemCryptoResult result);
DeleteOldUsageTable@35() => (OemCryptoResult result);
[MinVersion=2] GetProvisioningMethod@37()
=> (OemCryptoProvisioningMethod result);
[MinVersion=2] SupportedCertificates@38() => (uint32 result);
[MinVersion=2] IsSrmUpdateSupported@39() => (bool result);
[MinVersion=2] GetCurrentSrmVersion@40()
=> (OemCryptoResult result, uint16 version);
[MinVersion=2] LoadSrm@41(array<uint8> buffer) => (OemCryptoResult result);
[MinVersion=2] RemoveSrm@42() => (OemCryptoResult result);
// |avail_header_length| is the buffer size this was called with from Android.
// We need to specify that so we know if we can complete this call for real or
// instead just need to return the needed buffer size because execution of
// this call has side effects.
[MinVersion=2] CreateUsageTableHeader@43(uint32 avail_header_length)
=> (OemCryptoResult result, array<uint8>? header);
[MinVersion=2] LoadUsageTableHeader@44(array<uint8> buffer)
=> (OemCryptoResult result);
[MinVersion=2] CreateNewUsageEntry@45(uint32 session)
=> (OemCryptoResult result, uint32 usage_entry_number);
[MinVersion=2] LoadUsageEntry@46(uint32 session, uint32 index,
array<uint8> buffer) =>
(OemCryptoResult result);
// |avail_header_length| and |avail_entry_length| are the buffer sizes this
// was called with from Android. We need to specify that so we know if we can
// complete this call for real or instead just need to return the needed
// buffer size because execution of this call has side effects.
[MinVersion=2] UpdateUsageEntry@47(uint32 session, uint32 avail_header_length,
uint32 avail_entry_length)
=> (OemCryptoResult result, array<uint8>? header, array<uint8>? entry);
[MinVersion=2] DeactivateUsageEntry@48(uint32 session, array<uint8> pst)
=> (OemCryptoResult result);
// |avail_header_length| is the buffer size this was called with from Android.
// We need to specify that so we know if we can complete this call for real or
// instead just need to return the needed buffer size because execution of
// this call has side effects.
[MinVersion=2] ShrinkUsageTableHeader@49(uint32 new_entry_count,
uint32 avail_header_length)
=> (OemCryptoResult result, array<uint8>? header);
[MinVersion=2] MoveEntry@50(uint32 session, uint32 new_index)
=> (OemCryptoResult result);
[MinVersion=2] CopyOldUsageEntry@51(uint32 session, array<uint8> pst)
=> (OemCryptoResult result);
[MinVersion=2] CreateOldUsageEntry@52(uint64 time_since_license_received,
uint64 time_since_first_decrypt,
uint64 time_since_last_decrypt,
OemCryptoUsageEntryStatus status,
array<uint8> server_mac_key,
array<uint8> client_mac_key,
array<uint8> pst) =>
(OemCryptoResult result);
[MinVersion=2] GetAnalogOutputFlags@53() => (uint32 result);
[MinVersion=2] LoadTestKeybox@54(array<uint8> buffer) =>
(OemCryptoResult result);
[MinVersion=2]
LoadEntitledContentKeysV14@55(
uint32 session, array<OemCryptoEntitledContentKeyObjectV14> key_array)
=> (OemCryptoResult result);
[MinVersion=2] SelectKey@56(uint32 session, array<uint8> content_key_id,
OemCryptoCipherMode cipher_mode) =>
(OemCryptoResult result);
[MinVersion=2] LoadKeysV14@57(uint32 session, array<uint8> message,
array<uint8> signature, bool has_enc_mac_keys,
uint32 enc_mac_keys_iv_offset,
uint32 enc_mac_keys_offset,
array<OemCryptoKeyObjectV14> key_array,
uint32 pst_offset, uint32 pst_length,
array<uint8> srm_requirement,
OemCryptoLicenseType license_type) =>
(OemCryptoResult result);
[MinVersion=3] LoadKeys@58(uint32 session, array<uint8> message,
array<uint8> signature,
OemCryptoSubstring enc_mac_keys_iv,
OemCryptoSubstring enc_mac_keys,
array<OemCryptoKeyObject> key_array,
OemCryptoSubstring pst,
OemCryptoSubstring srm_restriction_data,
OemCryptoLicenseType license_type) =>
(OemCryptoResult result);
[MinVersion=3] ResourceRatingTier@59() => (uint32 rating_tier);
[MinVersion=3] BuildInformation@60() => (string build_information);
[MinVersion=3] RefreshKeys@61(uint32 session, array<uint8> message,
array<uint8> signature,
array<OemCryptoKeyRefreshObject> key_array)
=> (OemCryptoResult result);
[MinVersion=3] LoadEntitledContentKeys@62(
uint32 session, array<uint8> message,
array<OemCryptoEntitledContentKeyObject> key_array)
=> (OemCryptoResult result);
[MinVersion=4] GetOemPublicCertificate@63()
=> (OemCryptoResult result, array<uint8>? public_cert);
[MinVersion=4] MaximumUsageTableHeaderSize@64() => (uint32 size);
[MinVersion=4] IsAntiRollbackHwPresent@65() => (bool result);
[MinVersion=4] MinorApiVersion@66() => (uint32 version);
[MinVersion=4] PrepAndSignLicenseRequest@67(uint32 session,
array<uint8> message,
uint32 core_message_size,
uint32 avail_signature_size)
=> (OemCryptoResult result, uint32 core_message_size,
array<uint8>? message, array<uint8>? signature);
[MinVersion=4] PrepAndSignRenewalRequest@68(uint32 session,
array<uint8> message,
uint32 core_message_size,
uint32 avail_signature_size)
=> (OemCryptoResult result, uint32 core_message_size,
array<uint8>? message, array<uint8>? signature);
[MinVersion=4] PrepAndSignProvisioningRequest@69(uint32 session,
array<uint8> message,
uint32 core_message_size,
uint32 avail_signature_size)
=> (OemCryptoResult result, uint32 core_message_size,
array<uint8>? message, array<uint8>? signature);
[MinVersion=4] LoadLicense@70(uint32 session, array<uint8> message,
uint32 core_message_length,
array<uint8> signature)
=> (OemCryptoResult result);
[MinVersion=4] LoadRenewal@71(uint32 session, array<uint8> message,
uint32 core_message_length,
array<uint8> signature)
=> (OemCryptoResult result);
[MinVersion=4] LoadProvisioning@72(uint32 session, array<uint8> message,
uint32 core_message_length,
array<uint8> signature,
uint32 avail_wrapped_private_key_size)
=> (OemCryptoResult result, array<uint8>? wrapped_private_key);
[MinVersion=4] LoadOemPrivateKey@73(uint32 session)
=> (OemCryptoResult result);
[MinVersion=4] LoadDrmPrivateKey@74(uint32 session,
OemCryptoPrivateKey key_type,
array<uint8> wrapped_private_key)
=> (OemCryptoResult result);
// For decrypting to a secure buffer, pass in the secure_buffer parameter,
// otherwise it will return the contents decrypted into a clear buffer in the
// returned array. It will only do that if the drm policy allows it.
[MinVersion=4] DecryptCenc@75(uint32 session, array<uint8> data,
array<uint8, 16> iv,
array<SubSampleDescription> sub_samples,
OemCryptoCencEncryptPatternDesc pattern,
OemCryptoSecureBuffer? secure_buffer)
=> (OemCryptoResult result, array<uint8>? decrypted_data);
[MinVersion=5] CopyBuffer@76(uint32 session, array<uint8> data,
OemCryptoSecureBuffer out_buffer,
uint8 subsample_flags)
=> (OemCryptoResult result);
};
// OemCryptoService is implemented as another service outside of the Browser
// process, so we need to proxy a connection to it through ArcBridge initially.
// This interface is implemented in the Browser process and also in the daemon
// that runs in Chrome OS.
// Next Method ID: 1
interface OemCryptoHost {
Connect@0(pending_receiver<OemCryptoService> oemcryptor);
};
// OemCryptoInstance is implemented in the liboemcrypto.so library that runs in
// Android and handles the Android side of the ArcBridge connection.
// Deprecated method IDs: 0
// Next Method ID: 2
interface OemCryptoInstance {
// Establishes full-duplex communication with the host.
[MinVersion=1] Init@1(pending_remote<OemCryptoHost> host_remote) => ();
};