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