NdkMediaDrm.h revision 497ca097bf373ac69405131bd257915c97b31dc0
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 * This file defines an NDK API.
19 * Do not remove methods.
20 * Do not change method signatures.
21 * Do not change the value of constants.
22 * Do not change the size of any of the classes defined in here.
23 * Do not reference types that are not part of the NDK.
24 * Do not #include files that aren't part of the NDK.
25 */
26
27#ifndef _NDK_MEDIA_DRM_H
28#define _NDK_MEDIA_DRM_H
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34#include <stdint.h>
35#include <stdbool.h>
36
37struct AMediaDrm;
38typedef struct AMediaDrm AMediaDrm;
39
40typedef struct {
41    const uint8_t *ptr;
42    size_t length;
43} AMediaDrmByteArray;
44
45typedef AMediaDrmByteArray AMediaDrmSessionId;
46typedef AMediaDrmByteArray AMediaDrmScope;
47typedef AMediaDrmByteArray AMediaDrmKeySetId;
48typedef AMediaDrmByteArray AMediaDrmSecureStop;
49
50#define MEDIADRM_ERROR_BASE -2000
51
52typedef enum {
53    MEDIADRM_OK = 0,
54    MEDIADRM_NOT_PROVISIONED_ERROR    = MEDIADRM_ERROR_BASE - 1,
55    MEDIADRM_RESOURCE_BUSY_ERROR      = MEDIADRM_ERROR_BASE - 2,
56    MEDIADRM_DEVICE_REVOKED_ERROR     = MEDIADRM_ERROR_BASE - 3,
57    MEDIADRM_SHORT_BUFFER             = MEDIADRM_ERROR_BASE - 4,
58    MEDIADRM_INVALID_OBJECT_ERROR     = MEDIADRM_ERROR_BASE - 5,
59    MEDIADRM_INVALID_PARAMETER_ERROR  = MEDIADRM_ERROR_BASE - 6,
60    MEDIADRM_SESSION_NOT_OPENED_ERROR = MEDIADRM_ERROR_BASE - 7,
61    MEDIADRM_TAMPER_DETECTED_ERROR    = MEDIADRM_ERROR_BASE - 8,
62    MEDIADRM_VERIFY_FAILED            = MEDIADRM_ERROR_BASE - 9,
63    MEDIADRM_NEED_KEY_ERROR           = MEDIADRM_ERROR_BASE - 10,
64    MEDIADRM_LICENSE_EXPIRED_ERROR    = MEDIADRM_ERROR_BASE - 11,
65    MEDIADRM_UNKNOWN_ERROR            = MEDIADRM_ERROR_BASE - 12,
66} mediadrm_status_t;
67
68typedef enum AMediaDrmEventType {
69    /**
70     * This event type indicates that the app needs to request a certificate from
71     * the provisioning server.  The request message data is obtained using
72     * AMediaDrm_getProvisionRequest.
73     */
74    EVENT_PROVISION_REQUIRED = 1,
75
76    /**
77     * This event type indicates that the app needs to request keys from a license
78     * server.  The request message data is obtained using AMediaDrm_getKeyRequest.
79     */
80    EVENT_KEY_REQUIRED = 2,
81
82    /**
83     * This event type indicates that the licensed usage duration for keys in a session
84     * has expired.  The keys are no longer valid.
85     */
86    EVENT_KEY_EXPIRED = 3,
87
88    /**
89     * This event may indicate some specific vendor-defined condition, see your
90     * DRM provider documentation for details
91     */
92    EVENT_VENDOR_DEFINED = 4
93} AMediaDrmEventType;
94
95typedef void (*AMediaDrmEventListener)(AMediaDrm *, const AMediaDrmSessionId &sessionId,
96        AMediaDrmEventType eventType, int extra, const uint8_t *data, size_t dataSize);
97
98
99/**
100 * Query if the given scheme identified by its UUID is supported on this device, and
101 * whether the drm plugin is able to handle the media container format specified by mimeType.
102 *
103 * uuid identifies the universal unique ID of the crypto scheme. uuid must be 16 bytes.
104 * mimeType is the MIME type of the media container, e.g. "video/mp4".  If mimeType
105 * is not known or required, it can be provided as NULL.
106 */
107bool AMediaDrm_isCryptoSchemeSupported(const uint8_t *uuid, const char *mimeType);
108
109/**
110 * Create a MediaDrm instance from a UUID
111 * uuid identifies the universal unique ID of the crypto scheme. uuid must be 16 bytes.
112 */
113AMediaDrm* AMediaDrm_createByUUID(const uint8_t *uuid);
114
115/**
116 * Release a MediaDrm object
117 */
118void AMediaDrm_release(AMediaDrm *);
119
120/**
121 * Register a callback to be invoked when an event occurs
122 *
123 * listener is the callback that will be invoked on event
124 */
125void AMediaDrm_setOnEventListener(AMediaDrm *, AMediaDrmEventListener listener);
126
127/**
128 * Open a new session with the MediaDrm object.  A session ID is returned.
129 *
130 * returns MEDIADRM_NOT_PROVISIONED_ERROR if provisioning is needed
131 * returns MEDIADRM_RESOURCE_BUSY_ERROR if required resources are in use
132 */
133mediadrm_status_t AMediaDrm_openSession(AMediaDrm *, AMediaDrmSessionId &sessionId);
134
135/**
136 * Close a session on the MediaDrm object that was previously opened
137 * with AMediaDrm_openSession.
138 */
139mediadrm_status_t AMediaDrm_closeSession(AMediaDrm *, const AMediaDrmSessionId &sessionId);
140
141typedef enum AMediaDrmKeyType {
142    /**
143     * This key request type species that the keys will be for online use, they will
144     * not be saved to the device for subsequent use when the device is not connected
145     * to a network.
146     */
147    KEY_TYPE_STREAMING = 1,
148
149    /**
150     * This key request type specifies that the keys will be for offline use, they
151     * will be saved to the device for use when the device is not connected to a network.
152     */
153    KEY_TYPE_OFFLINE = 2,
154
155    /**
156     * This key request type specifies that previously saved offline keys should be released.
157     */
158    KEY_TYPE_RELEASE = 3
159} AMediaDrmKeyType;
160
161/**
162 *  Data type containing {key, value} pair
163 */
164typedef struct AMediaDrmKeyValuePair {
165    const char *mKey;
166    const char *mValue;
167} AMediaDrmKeyValue;
168
169/**
170 * A key request/response exchange occurs between the app and a license server
171 * to obtain or release keys used to decrypt encrypted content.
172 * AMediaDrm_getKeyRequest is used to obtain an opaque key request byte array that
173 * is delivered to the license server.  The opaque key request byte array is
174 * returned in KeyRequest.data.  The recommended URL to deliver the key request to
175 * is returned in KeyRequest.defaultUrl.
176 *
177 * After the app has received the key request response from the server,
178 * it should deliver to the response to the DRM engine plugin using the method
179 * AMediaDrm_provideKeyResponse.
180 *
181 * scope may be a sessionId or a keySetId, depending on the specified keyType.
182 * When the keyType is KEY_TYPE_STREAMING or KEY_TYPE_OFFLINE, scope should be set
183 * to the sessionId the keys will be provided to.  When the keyType is
184 * KEY_TYPE_RELEASE, scope should be set to the keySetId of the keys being released.
185 * Releasing keys from a device invalidates them for all sessions.
186 *
187 * init container-specific data, its meaning is interpreted based on the mime type
188 * provided in the mimeType parameter.  It could contain, for example, the content
189 * ID, key ID or other data obtained from the content metadata that is required in
190 * generating the key request. init may be null when keyType is KEY_TYPE_RELEASE.
191 *
192 * initSize is the number of bytes of initData
193 *
194 * mimeType identifies the mime type of the content.
195 *
196 * keyType specifes the type of the request. The request may be to acquire keys for
197 *   streaming or offline content, or to release previously acquired keys, which are
198 *   identified by a keySetId.
199 *
200 * optionalParameters are included in the key request message to allow a client
201 *   application to provide additional message parameters to the server.
202 *
203 * numOptionalParameters indicates the number of optional parameters provided
204 *   by the caller
205 *
206 * On exit:
207 *   1. The keyRequest pointer will reference the opaque key request data.  It
208 *       will reside in memory owned by the AMediaDrm object, and will remain
209 *       accessible until the next call to AMediaDrm_getKeyRequest or until the
210 *       MediaDrm object is released.
211 *   2. keyRequestSize will be set to the size of the request
212 *
213 * returns MEDIADRM_NOT_PROVISIONED_ERROR if reprovisioning is needed, due to a
214 * problem with the device certificate.
215*/
216mediadrm_status_t AMediaDrm_getKeyRequest(AMediaDrm *, const AMediaDrmScope &scope,
217        const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType,
218        const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters,
219        const uint8_t *&keyRequest, size_t &keyRequestSize);
220
221/**
222 * A key response is received from the license server by the app, then it is
223 * provided to the DRM engine plugin using provideKeyResponse.  When the
224 * response is for an offline key request, a keySetId is returned that can be
225 * used to later restore the keys to a new session with AMediaDrm_restoreKeys.
226 * When the response is for a streaming or release request, a null keySetId is
227 * returned.
228 *
229 * scope may be a sessionId or keySetId depending on the type of the
230 * response.  Scope should be set to the sessionId when the response is for either
231 * streaming or offline key requests.  Scope should be set to the keySetId when
232 * the response is for a release request.
233 *
234 * response points to the opaque response from the server
235 * responseSize should be set to the size of the response in bytes
236 */
237
238mediadrm_status_t AMediaDrm_provideKeyResponse(AMediaDrm *, const AMediaDrmScope &scope,
239        const uint8_t *response, size_t responseSize, AMediaDrmKeySetId &keySetId);
240
241/**
242 * Restore persisted offline keys into a new session.  keySetId identifies the
243 * keys to load, obtained from a prior call to AMediaDrm_provideKeyResponse.
244 *
245 * sessionId is the session ID for the DRM session
246 * keySetId identifies the saved key set to restore
247 */
248mediadrm_status_t AMediaDrm_restoreKeys(AMediaDrm *, const AMediaDrmSessionId &sessionId,
249        const AMediaDrmKeySetId &keySetId);
250
251/**
252 * Remove the current keys from a session.
253 *
254 * keySetId identifies keys to remove
255 */
256mediadrm_status_t AMediaDrm_removeKeys(AMediaDrm *, const AMediaDrmSessionId &keySetId);
257
258/**
259 * Request an informative description of the key status for the session.  The status is
260 * in the form of {key, value} pairs.  Since DRM license policies vary by vendor,
261 * the specific status field names are determined by each DRM vendor.  Refer to your
262 * DRM provider documentation for definitions of the field names for a particular
263 * DRM engine plugin.
264 *
265 * On entry, numPairs should be set by the caller to the maximum number of pairs
266 * that can be returned (the size of the array).  On exit, numPairs will be set
267 * to the number of entries written to the array.  If the number of {key, value} pairs
268 * to be returned is greater than *numPairs, MEDIADRM_SHORT_BUFFER will be returned
269 * and numPairs will be set to the number of pairs available.
270 */
271mediadrm_status_t AMediaDrm_queryKeyStatus(AMediaDrm *, const AMediaDrmSessionId &sessionId,
272        AMediaDrmKeyValue *keyValuePairs, size_t &numPairs);
273
274
275/**
276 * A provision request/response exchange occurs between the app and a provisioning
277 * server to retrieve a device certificate.  If provisionining is required, the
278 * EVENT_PROVISION_REQUIRED event will be sent to the event handler.
279 * getProvisionRequest is used to obtain the opaque provision request byte array that
280 * should be delivered to the provisioning server.
281 * On exit:
282 *    1. The provision request data will be referenced by provisionRequest, in
283 *        memory owned by the AMediaDrm object.  It will remain accessible until the
284 *        next call to getProvisionRequest.
285 *    2. provisionRequestSize will be set to the size of the request data.
286 *    3. serverUrl will reference a NULL terminated string containing the URL
287 *       the provisioning request should be sent to.  It will remain accessible until
288 *       the next call to getProvisionRequest.
289 */
290mediadrm_status_t AMediaDrm_getProvisionRequest(AMediaDrm *, const uint8_t *&provisionRequest,
291        size_t &provisionRequestSize, const char *&serverUrl);
292
293
294/**
295 * After a provision response is received by the app, it is provided to the DRM
296 * engine plugin using this method.
297 *
298 * response is the opaque provisioning response byte array to provide to the
299 *   DRM engine plugin.
300 * responseSize is the length of the provisioning response in bytes.
301 *
302 * returns MEDIADRM_DEVICE_REVOKED_ERROR if the response indicates that the
303 * server rejected the request
304 */
305mediadrm_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *,
306        const uint8_t *response, size_t responseSize);
307
308
309/**
310 * A means of enforcing limits on the number of concurrent streams per subscriber
311 * across devices is provided via SecureStop. This is achieved by securely
312 * monitoring the lifetime of sessions.
313 *
314 * Information from the server related to the current playback session is written
315 * to persistent storage on the device when each MediaCrypto object is created.
316 *
317 * In the normal case, playback will be completed, the session destroyed and the
318 * Secure Stops will be queried. The app queries secure stops and forwards the
319 * secure stop message to the server which verifies the signature and notifies the
320 * server side database that the session destruction has been confirmed. The persisted
321 * record on the client is only removed after positive confirmation that the server
322 * received the message using releaseSecureStops().
323 *
324 * numSecureStops is set by the caller to the maximum number of secure stops to
325 * return.  On exit, *numSecureStops will be set to the number actually returned.
326 * If *numSecureStops is too small for the number of secure stops available,
327 * MEDIADRM_SHORT_BUFFER will be returned and *numSecureStops will be set to the
328 * number required.
329 */
330mediadrm_status_t AMediaDrm_getSecureStops(AMediaDrm *,
331        AMediaDrmSecureStop *secureStops, size_t &numSecureStops);
332
333/**
334 * Process the SecureStop server response message ssRelease.  After authenticating
335 * the message, remove the SecureStops identified in the response.
336 *
337 * ssRelease is the server response indicating which secure stops to release
338 */
339mediadrm_status_t AMediaDrm_releaseSecureStops(AMediaDrm *,
340        const AMediaDrmSecureStop &ssRelease);
341
342/**
343 * String property name: identifies the maker of the DRM engine plugin
344 */
345const char *PROPERTY_VENDOR = "vendor";
346
347/**
348 * String property name: identifies the version of the DRM engine plugin
349 */
350const char *PROPERTY_VERSION = "version";
351
352/**
353 * String property name: describes the DRM engine plugin
354 */
355const char *PROPERTY_DESCRIPTION = "description";
356
357/**
358 * String property name: a comma-separated list of cipher and mac algorithms
359 * supported by CryptoSession.  The list may be empty if the DRM engine
360 * plugin does not support CryptoSession operations.
361 */
362const char *PROPERTY_ALGORITHMS = "algorithms";
363
364/**
365 * Read a DRM engine plugin String property value, given the property name string.
366 *
367 * propertyName identifies the property to query
368 * On return, propertyValue will be set to point to the property value.  The
369 * memory that the value resides in is owned by the NDK MediaDrm API and
370 * will remain valid until the next call to AMediaDrm_getPropertyString.
371 */
372mediadrm_status_t AMediaDrm_getPropertyString(AMediaDrm *, const char *propertyName,
373        const char *&propertyValue);
374
375/**
376 * Byte array property name: the device unique identifier is established during
377 * device provisioning and provides a means of uniquely identifying each device.
378 */
379const char *PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId";
380
381/**
382 * Read a DRM engine plugin byte array property value, given the property name string.
383 * On return, *propertyValue will be set to point to the property value.  The
384 * memory that the value resides in is owned by the NDK MediaDrm API and
385 * will remain valid until the next call to AMediaDrm_getPropertyByteArray.
386 */
387mediadrm_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *, const char *propertyName,
388        AMediaDrmByteArray &propertyValue);
389
390/**
391 * Set a DRM engine plugin String property value.
392 */
393mediadrm_status_t AMediaDrm_setPropertyString(AMediaDrm *, const char *propertyName,
394        const char *value);
395
396/**
397 * Set a DRM engine plugin byte array property value.
398 */
399mediadrm_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *, const char *propertyName,
400        const uint8_t *value, size_t valueSize);
401
402/**
403 * In addition to supporting decryption of DASH Common Encrypted Media, the
404 * MediaDrm APIs provide the ability to securely deliver session keys from
405 * an operator's session key server to a client device, based on the factory-installed
406 * root of trust, and then perform encrypt, decrypt, sign and verify operations
407 * with the session key on arbitrary user data.
408 *
409 * Operators create session key servers that receive session key requests and provide
410 * encrypted session keys which can be used for general purpose crypto operations.
411 *
412 * Generic encrypt/decrypt/sign/verify methods are based on the established session
413 * keys.  These keys are exchanged using the getKeyRequest/provideKeyResponse methods.
414 *
415 * Applications of this capability include securing various types of purchased or
416 * private content, such as applications, books and other media, photos or media
417 * delivery protocols.
418 */
419
420/*
421 * Encrypt the data referenced by input of length dataSize using algorithm specified
422 * by cipherAlgorithm, and write the encrypted result into output.  The caller must
423 * ensure that the output buffer is large enough to accept dataSize bytes. The key
424 * to use is identified by the 16 byte keyId.  The key must have been loaded into
425 * the session using provideKeyResponse.
426 */
427mediadrm_status_t AMediaDrm_encrypt(AMediaDrm *, const AMediaDrmSessionId &sessionId,
428        const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
429        const uint8_t *input, uint8_t *output, size_t dataSize);
430
431/*
432 * Decrypt the data referenced by input of length dataSize using algorithm specified
433 * by cipherAlgorithm, and write the decrypted result into output.  The caller must
434 * ensure that the output buffer is large enough to accept dataSize bytes.  The key
435 * to use is identified by the 16 byte keyId.  The key must have been loaded into
436 * the session using provideKeyResponse.
437 */
438mediadrm_status_t AMediaDrm_decrypt(AMediaDrm *, const AMediaDrmSessionId &sessionId,
439        const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
440        const uint8_t *input, uint8_t *output, size_t dataSize);
441
442/*
443 * Generate a signature using the specified macAlgorithm over the message data
444 * referenced by message of size messageSize and store the signature in the
445 * buffer referenced signature of max size *signatureSize.  If the buffer is not
446 * large enough to hold the signature, MEDIADRM_SHORT_BUFFER is returned and
447 * *signatureSize is set to the buffer size required.  The key to use is identified
448 * by the 16 byte keyId.  The key must have been loaded into the session using
449 * provideKeyResponse.
450 */
451mediadrm_status_t AMediaDrm_sign(AMediaDrm *, const AMediaDrmSessionId &sessionId,
452        const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize,
453        uint8_t *signature, size_t *signatureSize);
454
455/*
456 * Perform a signature verification using the specified macAlgorithm over the message
457 * data referenced by the message parameter of size messageSize. Returns MEDIADRM_OK
458 * if the signature matches, otherwise MEDAIDRM_VERIFY_FAILED is returned. The key to
459 * use is identified by the 16 byte keyId.  The key must have been loaded into the
460 * session using provideKeyResponse.
461 */
462mediadrm_status_t AMediaDrm_verify(AMediaDrm *, const AMediaDrmSessionId &sessionId,
463        const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize,
464        const uint8_t *signature, size_t signatureSize);
465
466#ifdef __cplusplus
467} // extern "C"
468#endif
469
470#endif //_NDK_MEDIA_DRM_H
471