blob: 1322a9dc4202c4b8c50ee1febcd8162443a24aa0 [file] [log] [blame]
Jeff Tinker497ca092014-05-13 09:31:15 -07001/*
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