// Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // The original version of this file lives in the Chromium repository at: // src/components/arc/common/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 files matches what's in Widevine's OEMCryptoCENC.h file closely and all // methods are documented there. module arc.mojom; [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, }; 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; }; [Extensible] enum OemCryptoCipherMode { CIPHER_MODE_CTR = 0, CIPHER_MODE_CBC = 1, }; struct OemCryptoKeyObject { 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; }; struct OemCryptoKeyRefreshObject { uint32 key_id_offset; uint32 key_id_length; bool has_key_control_iv; uint32 key_control_iv_offset; uint32 key_control_offset; }; [Extensible] enum OemCryptoAlgorithm { AES_CBC_128_NO_PADDING = 0, HMAC_SHA265 = 1, }; struct OemCryptoCencEncryptPatternDesc { uint32 encrypt; uint32 skip; uint32 offset; }; struct OemCryptoPstReport { array signature; uint8 status; uint8 clock_security_level; uint64 seconds_since_license_received; uint64 seconds_since_first_decrypt; uint64 seconds_since_last_decrypt; }; [Extensible] enum OemCryptoRsaPaddingScheme { SIGN_RSASSA_PSS = 1, SIGN_PKCS1_BLOCK1 = 2, }; [Extensible] enum OemCryptoHdcpCapability { HDCP_NONE = 0, HDCP_V1 = 1, HDCP_V2 = 2, HDCP_V2_1 = 3, HDCP_V2_2 = 4, HDCP_NO_DIGITAL_OUTPUT = 0xFF, }; // This is the interface that implements all the calls that map to the // OEMCrypto API itself. // Next method ID: 36 interface OemCryptoService { Initialize@0() => (OemCryptoResult result); Terminate@1() => (OemCryptoResult result); OpenSession@2() => (OemCryptoResult result, uint32 session); CloseSession@3(uint32 session) => (OemCryptoResult result); GenerateDerivedKeys@4(uint32 session, array mac_key_context, array enc_key_context) => (OemCryptoResult result); GenerateNonce@5(uint32 session) => (OemCryptoResult result, uint32 nonce); GenerateSignature@6(uint32 session, array message) => (OemCryptoResult result, array? 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. LoadKeys@7(uint32 session, array message, array signature, bool has_enc_mac_keys, uint32 enc_mac_keys_iv_offset, uint32 enc_mac_keys_offset, array key_array, uint32 pst_offset, uint32 pst_length) => (OemCryptoResult result); RefreshKeys@8(uint32 session, array message, array signature, array key_array) => (OemCryptoResult result); QueryKeyControl@9(uint32 session, array key_id) => (OemCryptoResult result, array? key_control_block); SelectKey@10(uint32 session, array key_id) => (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. DecryptCenc@11(uint32 session, array data, bool is_encrypted, array iv, uint32 block_offset, OemCryptoSecureBuffer? secure_buffer, OemCryptoCencEncryptPatternDesc pattern) => (OemCryptoResult result, array? decrypted_data); GenericEncrypt@12(uint32 session, array data, array iv, OemCryptoAlgorithm algorithm) => (OemCryptoResult result, array? encrypted_data); GenericDecrypt@13(uint32 session, array data, array iv, OemCryptoAlgorithm algorithm) => (OemCryptoResult result, array? decrypted_data); GenericSign@14(uint32 session, array data, OemCryptoAlgorithm algorithm) => (OemCryptoResult result, array? signature); GenericVerify@15(uint32 session, array data, OemCryptoAlgorithm algorithm, array signature) => (OemCryptoResult result); CopyBuffer@16(array data, OemCryptoSecureBuffer out_buffer) => (OemCryptoResult result); LoadTestKeybox@17() => (OemCryptoResult result); IsKeyboxValid@18() => (OemCryptoResult result); GetDeviceId@19() => (OemCryptoResult result, array? device_id); GetKeyData@20() => (OemCryptoResult result, array? key_data); GetRandom@21(uint32 length) => (OemCryptoResult result, array? data); GetNumberOfOpenSessions@22() => (OemCryptoResult result, uint32 num); GetMaxNumberOfSessions@23() => (OemCryptoResult result, uint32 max); RewrapDeviceRsaKey@24(uint32 session, array message, array signature, uint32 nonce_offset, uint32 enc_rsa_key_offset, uint32 enc_rsa_key_length, uint32 enc_rsa_key_iv_offset) => (OemCryptoResult result, array? wrapped_key); LoadDeviceRsaKey@25(uint32 session, array wrapped_rsa_key) => (OemCryptoResult result); GenerateRsaSignature@26(uint32 session, array message, OemCryptoRsaPaddingScheme padding_scheme) => (OemCryptoResult result, array? signature); DeriveKeysFromSessionKey@27(uint32 session, array enc_session_key, array mac_key_context, array enc_key_context) => (OemCryptoResult result); SecurityPatchLevel@28() => (uint8 security_patch_level); GetHdcpCapability@29() => (OemCryptoResult result, OemCryptoHdcpCapability current, OemCryptoHdcpCapability maximum); UpdateUsageTable@30() => (OemCryptoResult result); DeactivateUsageEntry@31(array pst) => (OemCryptoResult result); ReportUsage@32(uint32 session, array pst) => (OemCryptoResult result, OemCryptoPstReport? report); DeleteUsageEntry@33(uint32 session, uint32 pst_offset, uint32 pst_length, array message, array signature) => (OemCryptoResult result); ForceDeleteUsageEntry@34(array pst) => (OemCryptoResult result); DeleteUsageTable@35() => (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(OemCryptoService& oemcryptor); }; // OemCryptoInstance is implemented in the liboemcrypto.so library that runs in // Android and handles the Android side of the ArcBridge connection. // Next Method ID: 1 interface OemCryptoInstance { Init@0(OemCryptoHost host_ptr); };