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
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
|
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This file defines an NDK API.
* Do not remove methods.
* Do not change method signatures.
* Do not change the value of constants.
* Do not change the size of any of the classes defined in here.
* Do not reference types that are not part of the NDK.
* Do not #include files that aren't part of the NDK.
*/
#ifndef _NDK_MEDIA_DRM_H
#define _NDK_MEDIA_DRM_H
#include "NdkMediaError.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
struct AMediaDrm;
typedef struct AMediaDrm AMediaDrm;
typedef struct {
const uint8_t *ptr;
size_t length;
} AMediaDrmByteArray;
typedef AMediaDrmByteArray AMediaDrmSessionId;
typedef AMediaDrmByteArray AMediaDrmScope;
typedef AMediaDrmByteArray AMediaDrmKeySetId;
typedef AMediaDrmByteArray AMediaDrmSecureStop;
typedef enum AMediaDrmEventType {
/**
* This event type indicates that the app needs to request a certificate from
* the provisioning server. The request message data is obtained using
* AMediaDrm_getProvisionRequest.
*/
EVENT_PROVISION_REQUIRED = 1,
/**
* This event type indicates that the app needs to request keys from a license
* server. The request message data is obtained using AMediaDrm_getKeyRequest.
*/
EVENT_KEY_REQUIRED = 2,
/**
* This event type indicates that the licensed usage duration for keys in a session
* has expired. The keys are no longer valid.
*/
EVENT_KEY_EXPIRED = 3,
/**
* This event may indicate some specific vendor-defined condition, see your
* DRM provider documentation for details
*/
EVENT_VENDOR_DEFINED = 4
} AMediaDrmEventType;
typedef void (*AMediaDrmEventListener)(AMediaDrm *, const AMediaDrmSessionId *sessionId,
AMediaDrmEventType eventType, int extra, const uint8_t *data, size_t dataSize);
/**
* Query if the given scheme identified by its UUID is supported on this device, and
* whether the drm plugin is able to handle the media container format specified by mimeType.
*
* uuid identifies the universal unique ID of the crypto scheme. uuid must be 16 bytes.
* mimeType is the MIME type of the media container, e.g. "video/mp4". If mimeType
* is not known or required, it can be provided as NULL.
*/
bool AMediaDrm_isCryptoSchemeSupported(const uint8_t *uuid, const char *mimeType);
/**
* Create a MediaDrm instance from a UUID
* uuid identifies the universal unique ID of the crypto scheme. uuid must be 16 bytes.
*/
AMediaDrm* AMediaDrm_createByUUID(const uint8_t *uuid);
/**
* Release a MediaDrm object
*/
void AMediaDrm_release(AMediaDrm *);
/**
* Register a callback to be invoked when an event occurs
*
* listener is the callback that will be invoked on event
*/
media_status_t AMediaDrm_setOnEventListener(AMediaDrm *, AMediaDrmEventListener listener);
/**
* Open a new session with the MediaDrm object. A session ID is returned.
*
* returns MEDIADRM_NOT_PROVISIONED_ERROR if provisioning is needed
* returns MEDIADRM_RESOURCE_BUSY_ERROR if required resources are in use
*/
media_status_t AMediaDrm_openSession(AMediaDrm *, AMediaDrmSessionId *sessionId);
/**
* Close a session on the MediaDrm object that was previously opened
* with AMediaDrm_openSession.
*/
media_status_t AMediaDrm_closeSession(AMediaDrm *, const AMediaDrmSessionId *sessionId);
typedef enum AMediaDrmKeyType {
/**
* This key request type species that the keys will be for online use, they will
* not be saved to the device for subsequent use when the device is not connected
* to a network.
*/
KEY_TYPE_STREAMING = 1,
/**
* This key request type specifies that the keys will be for offline use, they
* will be saved to the device for use when the device is not connected to a network.
*/
KEY_TYPE_OFFLINE = 2,
/**
* This key request type specifies that previously saved offline keys should be released.
*/
KEY_TYPE_RELEASE = 3
} AMediaDrmKeyType;
/**
* Data type containing {key, value} pair
*/
typedef struct AMediaDrmKeyValuePair {
const char *mKey;
const char *mValue;
} AMediaDrmKeyValue;
/**
* A key request/response exchange occurs between the app and a license server
* to obtain or release keys used to decrypt encrypted content.
* AMediaDrm_getKeyRequest is used to obtain an opaque key request byte array that
* is delivered to the license server. The opaque key request byte array is
* returned in KeyRequest.data. The recommended URL to deliver the key request to
* is returned in KeyRequest.defaultUrl.
*
* After the app has received the key request response from the server,
* it should deliver to the response to the DRM engine plugin using the method
* AMediaDrm_provideKeyResponse.
*
* scope may be a sessionId or a keySetId, depending on the specified keyType.
* When the keyType is KEY_TYPE_STREAMING or KEY_TYPE_OFFLINE, scope should be set
* to the sessionId the keys will be provided to. When the keyType is
* KEY_TYPE_RELEASE, scope should be set to the keySetId of the keys being released.
* Releasing keys from a device invalidates them for all sessions.
*
* init container-specific data, its meaning is interpreted based on the mime type
* provided in the mimeType parameter. It could contain, for example, the content
* ID, key ID or other data obtained from the content metadata that is required in
* generating the key request. init may be null when keyType is KEY_TYPE_RELEASE.
*
* initSize is the number of bytes of initData
*
* mimeType identifies the mime type of the content.
*
* keyType specifes the type of the request. The request may be to acquire keys for
* streaming or offline content, or to release previously acquired keys, which are
* identified by a keySetId.
*
* optionalParameters are included in the key request message to allow a client
* application to provide additional message parameters to the server.
*
* numOptionalParameters indicates the number of optional parameters provided
* by the caller
*
* On exit:
* 1. The keyRequest pointer will reference the opaque key request data. It
* will reside in memory owned by the AMediaDrm object, and will remain
* accessible until the next call to AMediaDrm_getKeyRequest or until the
* MediaDrm object is released.
* 2. keyRequestSize will be set to the size of the request
*
* returns MEDIADRM_NOT_PROVISIONED_ERROR if reprovisioning is needed, due to a
* problem with the device certificate.
*/
media_status_t AMediaDrm_getKeyRequest(AMediaDrm *, const AMediaDrmScope *scope,
const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType,
const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters,
const uint8_t **keyRequest, size_t *keyRequestSize);
/**
* A key response is received from the license server by the app, then it is
* provided to the DRM engine plugin using provideKeyResponse. When the
* response is for an offline key request, a keySetId is returned that can be
* used to later restore the keys to a new session with AMediaDrm_restoreKeys.
* When the response is for a streaming or release request, a null keySetId is
* returned.
*
* scope may be a sessionId or keySetId depending on the type of the
* response. Scope should be set to the sessionId when the response is for either
* streaming or offline key requests. Scope should be set to the keySetId when
* the response is for a release request.
*
* response points to the opaque response from the server
* responseSize should be set to the size of the response in bytes
*/
media_status_t AMediaDrm_provideKeyResponse(AMediaDrm *, const AMediaDrmScope *scope,
const uint8_t *response, size_t responseSize, AMediaDrmKeySetId *keySetId);
/**
* Restore persisted offline keys into a new session. keySetId identifies the
* keys to load, obtained from a prior call to AMediaDrm_provideKeyResponse.
*
* sessionId is the session ID for the DRM session
* keySetId identifies the saved key set to restore
*/
media_status_t AMediaDrm_restoreKeys(AMediaDrm *, const AMediaDrmSessionId *sessionId,
const AMediaDrmKeySetId *keySetId);
/**
* Remove the current keys from a session.
*
* keySetId identifies keys to remove
*/
media_status_t AMediaDrm_removeKeys(AMediaDrm *, const AMediaDrmSessionId *keySetId);
/**
* Request an informative description of the key status for the session. The status is
* in the form of {key, value} pairs. Since DRM license policies vary by vendor,
* the specific status field names are determined by each DRM vendor. Refer to your
* DRM provider documentation for definitions of the field names for a particular
* DRM engine plugin.
*
* On entry, numPairs should be set by the caller to the maximum number of pairs
* that can be returned (the size of the array). On exit, numPairs will be set
* to the number of entries written to the array. If the number of {key, value} pairs
* to be returned is greater than *numPairs, MEDIADRM_SHORT_BUFFER will be returned
* and numPairs will be set to the number of pairs available.
*/
media_status_t AMediaDrm_queryKeyStatus(AMediaDrm *, const AMediaDrmSessionId *sessionId,
AMediaDrmKeyValue *keyValuePairs, size_t *numPairs);
/**
* A provision request/response exchange occurs between the app and a provisioning
* server to retrieve a device certificate. If provisionining is required, the
* EVENT_PROVISION_REQUIRED event will be sent to the event handler.
* getProvisionRequest is used to obtain the opaque provision request byte array that
* should be delivered to the provisioning server.
* On exit:
* 1. The provision request data will be referenced by provisionRequest, in
* memory owned by the AMediaDrm object. It will remain accessible until the
* next call to getProvisionRequest.
* 2. provisionRequestSize will be set to the size of the request data.
* 3. serverUrl will reference a NULL terminated string containing the URL
* the provisioning request should be sent to. It will remain accessible until
* the next call to getProvisionRequest.
*/
media_status_t AMediaDrm_getProvisionRequest(AMediaDrm *, const uint8_t **provisionRequest,
size_t *provisionRequestSize, const char **serverUrl);
/**
* After a provision response is received by the app, it is provided to the DRM
* engine plugin using this method.
*
* response is the opaque provisioning response byte array to provide to the
* DRM engine plugin.
* responseSize is the length of the provisioning response in bytes.
*
* returns MEDIADRM_DEVICE_REVOKED_ERROR if the response indicates that the
* server rejected the request
*/
media_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *,
const uint8_t *response, size_t responseSize);
/**
* A means of enforcing limits on the number of concurrent streams per subscriber
* across devices is provided via SecureStop. This is achieved by securely
* monitoring the lifetime of sessions.
*
* Information from the server related to the current playback session is written
* to persistent storage on the device when each MediaCrypto object is created.
*
* In the normal case, playback will be completed, the session destroyed and the
* Secure Stops will be queried. The app queries secure stops and forwards the
* secure stop message to the server which verifies the signature and notifies the
* server side database that the session destruction has been confirmed. The persisted
* record on the client is only removed after positive confirmation that the server
* received the message using releaseSecureStops().
*
* numSecureStops is set by the caller to the maximum number of secure stops to
* return. On exit, *numSecureStops will be set to the number actually returned.
* If *numSecureStops is too small for the number of secure stops available,
* MEDIADRM_SHORT_BUFFER will be returned and *numSecureStops will be set to the
* number required.
*/
media_status_t AMediaDrm_getSecureStops(AMediaDrm *,
AMediaDrmSecureStop *secureStops, size_t *numSecureStops);
/**
* Process the SecureStop server response message ssRelease. After authenticating
* the message, remove the SecureStops identified in the response.
*
* ssRelease is the server response indicating which secure stops to release
*/
media_status_t AMediaDrm_releaseSecureStops(AMediaDrm *,
const AMediaDrmSecureStop *ssRelease);
/**
* String property name: identifies the maker of the DRM engine plugin
*/
#define PROPERTY_VENDOR "vendor"
/**
* String property name: identifies the version of the DRM engine plugin
*/
#define PROPERTY_VERSION "version"
/**
* String property name: describes the DRM engine plugin
*/
#define PROPERTY_DESCRIPTION "description"
/**
* String property name: a comma-separated list of cipher and mac algorithms
* supported by CryptoSession. The list may be empty if the DRM engine
* plugin does not support CryptoSession operations.
*/
#define PROPERTY_ALGORITHMS "algorithms"
/**
* Read a DRM engine plugin String property value, given the property name string.
*
* propertyName identifies the property to query
* On return, propertyValue will be set to point to the property value. The
* memory that the value resides in is owned by the NDK MediaDrm API and
* will remain valid until the next call to AMediaDrm_getPropertyString.
*/
media_status_t AMediaDrm_getPropertyString(AMediaDrm *, const char *propertyName,
const char **propertyValue);
/**
* Byte array property name: the device unique identifier is established during
* device provisioning and provides a means of uniquely identifying each device.
*/
#define PROPERTY_DEVICE_UNIQUE_ID "deviceUniqueId"
/**
* Read a DRM engine plugin byte array property value, given the property name string.
* On return, *propertyValue will be set to point to the property value. The
* memory that the value resides in is owned by the NDK MediaDrm API and
* will remain valid until the next call to AMediaDrm_getPropertyByteArray.
*/
media_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *, const char *propertyName,
AMediaDrmByteArray *propertyValue);
/**
* Set a DRM engine plugin String property value.
*/
media_status_t AMediaDrm_setPropertyString(AMediaDrm *, const char *propertyName,
const char *value);
/**
* Set a DRM engine plugin byte array property value.
*/
media_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *, const char *propertyName,
const uint8_t *value, size_t valueSize);
/**
* In addition to supporting decryption of DASH Common Encrypted Media, the
* MediaDrm APIs provide the ability to securely deliver session keys from
* an operator's session key server to a client device, based on the factory-installed
* root of trust, and then perform encrypt, decrypt, sign and verify operations
* with the session key on arbitrary user data.
*
* Operators create session key servers that receive session key requests and provide
* encrypted session keys which can be used for general purpose crypto operations.
*
* Generic encrypt/decrypt/sign/verify methods are based on the established session
* keys. These keys are exchanged using the getKeyRequest/provideKeyResponse methods.
*
* Applications of this capability include securing various types of purchased or
* private content, such as applications, books and other media, photos or media
* delivery protocols.
*/
/*
* Encrypt the data referenced by input of length dataSize using algorithm specified
* by cipherAlgorithm, and write the encrypted result into output. The caller must
* ensure that the output buffer is large enough to accept dataSize bytes. The key
* to use is identified by the 16 byte keyId. The key must have been loaded into
* the session using provideKeyResponse.
*/
media_status_t AMediaDrm_encrypt(AMediaDrm *, const AMediaDrmSessionId *sessionId,
const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
const uint8_t *input, uint8_t *output, size_t dataSize);
/*
* Decrypt the data referenced by input of length dataSize using algorithm specified
* by cipherAlgorithm, and write the decrypted result into output. The caller must
* ensure that the output buffer is large enough to accept dataSize bytes. The key
* to use is identified by the 16 byte keyId. The key must have been loaded into
* the session using provideKeyResponse.
*/
media_status_t AMediaDrm_decrypt(AMediaDrm *, const AMediaDrmSessionId *sessionId,
const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
const uint8_t *input, uint8_t *output, size_t dataSize);
/*
* Generate a signature using the specified macAlgorithm over the message data
* referenced by message of size messageSize and store the signature in the
* buffer referenced signature of max size *signatureSize. If the buffer is not
* large enough to hold the signature, MEDIADRM_SHORT_BUFFER is returned and
* *signatureSize is set to the buffer size required. The key to use is identified
* by the 16 byte keyId. The key must have been loaded into the session using
* provideKeyResponse.
*/
media_status_t AMediaDrm_sign(AMediaDrm *, const AMediaDrmSessionId *sessionId,
const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize,
uint8_t *signature, size_t *signatureSize);
/*
* Perform a signature verification using the specified macAlgorithm over the message
* data referenced by the message parameter of size messageSize. Returns MEDIADRM_OK
* if the signature matches, otherwise MEDAIDRM_VERIFY_FAILED is returned. The key to
* use is identified by the 16 byte keyId. The key must have been loaded into the
* session using provideKeyResponse.
*/
media_status_t AMediaDrm_verify(AMediaDrm *, const AMediaDrmSessionId *sessionId,
const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize,
const uint8_t *signature, size_t signatureSize);
#ifdef __cplusplus
} // extern "C"
#endif
#endif //_NDK_MEDIA_DRM_H
|