summaryrefslogtreecommitdiff
path: root/chromium/components/arc/common/oemcrypto.mojom
blob: 9d43e224e5c2c1d184c4618222dbc0b2568c23e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
// 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.

// Next MinVersion: 2

// 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<uint8, 20> 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<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.
  LoadKeys@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<OemCryptoKeyObject> key_array,
             uint32 pst_offset, uint32 pst_length)
      => (OemCryptoResult result);
  RefreshKeys@8(uint32 session, array<uint8> message, array<uint8> signature,
                array<OemCryptoKeyRefreshObject> key_array)
      => (OemCryptoResult result);
  QueryKeyControl@9(uint32 session, array<uint8> key_id)
      => (OemCryptoResult result, array<uint8>? key_control_block);
  SelectKey@10(uint32 session, array<uint8> 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<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);
  CopyBuffer@16(array<uint8> data, OemCryptoSecureBuffer out_buffer)
      => (OemCryptoResult result);
  LoadTestKeybox@17() => (OemCryptoResult result);
  IsKeyboxValid@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);
  DeactivateUsageEntry@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);
  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: 2
interface OemCryptoInstance {
  // DEPRECATED: Please use Init@1 instead.
  InitDeprecated@0(OemCryptoHost host_ptr);

  // Establishes full-duplex communication with the host.
  [MinVersion=1] Init@1(OemCryptoHost host_ptr) => ();
};