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