blob: cba43801f471063810a2de031bdc0dcd66aac065 [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
Jeff Tinker29f03a82017-04-05 07:56:54 -0700162 * returned in KeyRequest.data.
Jeff Tinker497ca092014-05-13 09:31:15 -0700163 *
164 * After the app has received the key request response from the server,
165 * it should deliver to the response to the DRM engine plugin using the method
166 * AMediaDrm_provideKeyResponse.
167 *
168 * scope may be a sessionId or a keySetId, depending on the specified keyType.
169 * When the keyType is KEY_TYPE_STREAMING or KEY_TYPE_OFFLINE, scope should be set
170 * to the sessionId the keys will be provided to. When the keyType is
171 * KEY_TYPE_RELEASE, scope should be set to the keySetId of the keys being released.
172 * Releasing keys from a device invalidates them for all sessions.
173 *
174 * init container-specific data, its meaning is interpreted based on the mime type
175 * provided in the mimeType parameter. It could contain, for example, the content
176 * ID, key ID or other data obtained from the content metadata that is required in
177 * generating the key request. init may be null when keyType is KEY_TYPE_RELEASE.
178 *
179 * initSize is the number of bytes of initData
180 *
181 * mimeType identifies the mime type of the content.
182 *
183 * keyType specifes the type of the request. The request may be to acquire keys for
184 * streaming or offline content, or to release previously acquired keys, which are
185 * identified by a keySetId.
186 *
187 * optionalParameters are included in the key request message to allow a client
188 * application to provide additional message parameters to the server.
189 *
190 * numOptionalParameters indicates the number of optional parameters provided
191 * by the caller
192 *
193 * On exit:
194 * 1. The keyRequest pointer will reference the opaque key request data. It
195 * will reside in memory owned by the AMediaDrm object, and will remain
196 * accessible until the next call to AMediaDrm_getKeyRequest or until the
197 * MediaDrm object is released.
198 * 2. keyRequestSize will be set to the size of the request
199 *
200 * returns MEDIADRM_NOT_PROVISIONED_ERROR if reprovisioning is needed, due to a
201 * problem with the device certificate.
202*/
Marco Nelissen18a1b592014-05-20 08:45:18 -0700203media_status_t AMediaDrm_getKeyRequest(AMediaDrm *, const AMediaDrmScope *scope,
Jeff Tinker497ca092014-05-13 09:31:15 -0700204 const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType,
205 const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters,
Marco Nelissen18a1b592014-05-20 08:45:18 -0700206 const uint8_t **keyRequest, size_t *keyRequestSize);
Jeff Tinker497ca092014-05-13 09:31:15 -0700207
208/**
209 * A key response is received from the license server by the app, then it is
210 * provided to the DRM engine plugin using provideKeyResponse. When the
211 * response is for an offline key request, a keySetId is returned that can be
212 * used to later restore the keys to a new session with AMediaDrm_restoreKeys.
213 * When the response is for a streaming or release request, a null keySetId is
214 * returned.
215 *
216 * scope may be a sessionId or keySetId depending on the type of the
217 * response. Scope should be set to the sessionId when the response is for either
218 * streaming or offline key requests. Scope should be set to the keySetId when
219 * the response is for a release request.
220 *
221 * response points to the opaque response from the server
222 * responseSize should be set to the size of the response in bytes
223 */
224
Marco Nelissen18a1b592014-05-20 08:45:18 -0700225media_status_t AMediaDrm_provideKeyResponse(AMediaDrm *, const AMediaDrmScope *scope,
226 const uint8_t *response, size_t responseSize, AMediaDrmKeySetId *keySetId);
Jeff Tinker497ca092014-05-13 09:31:15 -0700227
228/**
229 * Restore persisted offline keys into a new session. keySetId identifies the
230 * keys to load, obtained from a prior call to AMediaDrm_provideKeyResponse.
231 *
232 * sessionId is the session ID for the DRM session
233 * keySetId identifies the saved key set to restore
234 */
Marco Nelissen18a1b592014-05-20 08:45:18 -0700235media_status_t AMediaDrm_restoreKeys(AMediaDrm *, const AMediaDrmSessionId *sessionId,
236 const AMediaDrmKeySetId *keySetId);
Jeff Tinker497ca092014-05-13 09:31:15 -0700237
238/**
239 * Remove the current keys from a session.
240 *
241 * keySetId identifies keys to remove
242 */
Marco Nelissen18a1b592014-05-20 08:45:18 -0700243media_status_t AMediaDrm_removeKeys(AMediaDrm *, const AMediaDrmSessionId *keySetId);
Jeff Tinker497ca092014-05-13 09:31:15 -0700244
245/**
246 * Request an informative description of the key status for the session. The status is
247 * in the form of {key, value} pairs. Since DRM license policies vary by vendor,
248 * the specific status field names are determined by each DRM vendor. Refer to your
249 * DRM provider documentation for definitions of the field names for a particular
250 * DRM engine plugin.
251 *
252 * On entry, numPairs should be set by the caller to the maximum number of pairs
253 * that can be returned (the size of the array). On exit, numPairs will be set
254 * to the number of entries written to the array. If the number of {key, value} pairs
255 * to be returned is greater than *numPairs, MEDIADRM_SHORT_BUFFER will be returned
256 * and numPairs will be set to the number of pairs available.
257 */
Marco Nelissen18a1b592014-05-20 08:45:18 -0700258media_status_t AMediaDrm_queryKeyStatus(AMediaDrm *, const AMediaDrmSessionId *sessionId,
259 AMediaDrmKeyValue *keyValuePairs, size_t *numPairs);
Jeff Tinker497ca092014-05-13 09:31:15 -0700260
261
262/**
263 * A provision request/response exchange occurs between the app and a provisioning
264 * server to retrieve a device certificate. If provisionining is required, the
265 * EVENT_PROVISION_REQUIRED event will be sent to the event handler.
266 * getProvisionRequest is used to obtain the opaque provision request byte array that
267 * should be delivered to the provisioning server.
268 * On exit:
269 * 1. The provision request data will be referenced by provisionRequest, in
270 * memory owned by the AMediaDrm object. It will remain accessible until the
271 * next call to getProvisionRequest.
272 * 2. provisionRequestSize will be set to the size of the request data.
273 * 3. serverUrl will reference a NULL terminated string containing the URL
274 * the provisioning request should be sent to. It will remain accessible until
275 * the next call to getProvisionRequest.
276 */
Marco Nelissen18a1b592014-05-20 08:45:18 -0700277media_status_t AMediaDrm_getProvisionRequest(AMediaDrm *, const uint8_t **provisionRequest,
278 size_t *provisionRequestSize, const char **serverUrl);
Jeff Tinker497ca092014-05-13 09:31:15 -0700279
280
281/**
282 * After a provision response is received by the app, it is provided to the DRM
283 * engine plugin using this method.
284 *
285 * response is the opaque provisioning response byte array to provide to the
286 * DRM engine plugin.
287 * responseSize is the length of the provisioning response in bytes.
288 *
289 * returns MEDIADRM_DEVICE_REVOKED_ERROR if the response indicates that the
290 * server rejected the request
291 */
Marco Nelissene419d7c2014-05-15 14:17:25 -0700292media_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *,
Jeff Tinker497ca092014-05-13 09:31:15 -0700293 const uint8_t *response, size_t responseSize);
294
295
296/**
297 * A means of enforcing limits on the number of concurrent streams per subscriber
298 * across devices is provided via SecureStop. This is achieved by securely
299 * monitoring the lifetime of sessions.
300 *
301 * Information from the server related to the current playback session is written
302 * to persistent storage on the device when each MediaCrypto object is created.
303 *
304 * In the normal case, playback will be completed, the session destroyed and the
305 * Secure Stops will be queried. The app queries secure stops and forwards the
306 * secure stop message to the server which verifies the signature and notifies the
307 * server side database that the session destruction has been confirmed. The persisted
308 * record on the client is only removed after positive confirmation that the server
309 * received the message using releaseSecureStops().
310 *
311 * numSecureStops is set by the caller to the maximum number of secure stops to
312 * return. On exit, *numSecureStops will be set to the number actually returned.
313 * If *numSecureStops is too small for the number of secure stops available,
314 * MEDIADRM_SHORT_BUFFER will be returned and *numSecureStops will be set to the
315 * number required.
316 */
Marco Nelissene419d7c2014-05-15 14:17:25 -0700317media_status_t AMediaDrm_getSecureStops(AMediaDrm *,
Marco Nelissen18a1b592014-05-20 08:45:18 -0700318 AMediaDrmSecureStop *secureStops, size_t *numSecureStops);
Jeff Tinker497ca092014-05-13 09:31:15 -0700319
320/**
321 * Process the SecureStop server response message ssRelease. After authenticating
322 * the message, remove the SecureStops identified in the response.
323 *
324 * ssRelease is the server response indicating which secure stops to release
325 */
Marco Nelissene419d7c2014-05-15 14:17:25 -0700326media_status_t AMediaDrm_releaseSecureStops(AMediaDrm *,
Marco Nelissen18a1b592014-05-20 08:45:18 -0700327 const AMediaDrmSecureStop *ssRelease);
Jeff Tinker497ca092014-05-13 09:31:15 -0700328
329/**
330 * String property name: identifies the maker of the DRM engine plugin
331 */
Martin Storsjoc0fcdc02014-11-27 22:51:14 +0200332#define PROPERTY_VENDOR "vendor"
Jeff Tinker497ca092014-05-13 09:31:15 -0700333
334/**
335 * String property name: identifies the version of the DRM engine plugin
336 */
Martin Storsjoc0fcdc02014-11-27 22:51:14 +0200337#define PROPERTY_VERSION "version"
Jeff Tinker497ca092014-05-13 09:31:15 -0700338
339/**
340 * String property name: describes the DRM engine plugin
341 */
Martin Storsjoc0fcdc02014-11-27 22:51:14 +0200342#define PROPERTY_DESCRIPTION "description"
Jeff Tinker497ca092014-05-13 09:31:15 -0700343
344/**
345 * String property name: a comma-separated list of cipher and mac algorithms
346 * supported by CryptoSession. The list may be empty if the DRM engine
347 * plugin does not support CryptoSession operations.
348 */
Martin Storsjoc0fcdc02014-11-27 22:51:14 +0200349#define PROPERTY_ALGORITHMS "algorithms"
Jeff Tinker497ca092014-05-13 09:31:15 -0700350
351/**
352 * Read a DRM engine plugin String property value, given the property name string.
353 *
354 * propertyName identifies the property to query
355 * On return, propertyValue will be set to point to the property value. The
356 * memory that the value resides in is owned by the NDK MediaDrm API and
357 * will remain valid until the next call to AMediaDrm_getPropertyString.
358 */
Marco Nelissene419d7c2014-05-15 14:17:25 -0700359media_status_t AMediaDrm_getPropertyString(AMediaDrm *, const char *propertyName,
Marco Nelissen18a1b592014-05-20 08:45:18 -0700360 const char **propertyValue);
Jeff Tinker497ca092014-05-13 09:31:15 -0700361
362/**
363 * Byte array property name: the device unique identifier is established during
364 * device provisioning and provides a means of uniquely identifying each device.
365 */
Martin Storsjoc0fcdc02014-11-27 22:51:14 +0200366#define PROPERTY_DEVICE_UNIQUE_ID "deviceUniqueId"
Jeff Tinker497ca092014-05-13 09:31:15 -0700367
368/**
369 * Read a DRM engine plugin byte array property value, given the property name string.
370 * On return, *propertyValue will be set to point to the property value. The
371 * memory that the value resides in is owned by the NDK MediaDrm API and
372 * will remain valid until the next call to AMediaDrm_getPropertyByteArray.
373 */
Marco Nelissene419d7c2014-05-15 14:17:25 -0700374media_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *, const char *propertyName,
Marco Nelissen18a1b592014-05-20 08:45:18 -0700375 AMediaDrmByteArray *propertyValue);
Jeff Tinker497ca092014-05-13 09:31:15 -0700376
377/**
378 * Set a DRM engine plugin String property value.
379 */
Marco Nelissene419d7c2014-05-15 14:17:25 -0700380media_status_t AMediaDrm_setPropertyString(AMediaDrm *, const char *propertyName,
Jeff Tinker497ca092014-05-13 09:31:15 -0700381 const char *value);
382
383/**
384 * Set a DRM engine plugin byte array property value.
385 */
Marco Nelissene419d7c2014-05-15 14:17:25 -0700386media_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *, const char *propertyName,
Jeff Tinker497ca092014-05-13 09:31:15 -0700387 const uint8_t *value, size_t valueSize);
388
389/**
390 * In addition to supporting decryption of DASH Common Encrypted Media, the
391 * MediaDrm APIs provide the ability to securely deliver session keys from
392 * an operator's session key server to a client device, based on the factory-installed
393 * root of trust, and then perform encrypt, decrypt, sign and verify operations
394 * with the session key on arbitrary user data.
395 *
396 * Operators create session key servers that receive session key requests and provide
397 * encrypted session keys which can be used for general purpose crypto operations.
398 *
399 * Generic encrypt/decrypt/sign/verify methods are based on the established session
400 * keys. These keys are exchanged using the getKeyRequest/provideKeyResponse methods.
401 *
402 * Applications of this capability include securing various types of purchased or
403 * private content, such as applications, books and other media, photos or media
404 * delivery protocols.
405 */
406
407/*
408 * Encrypt the data referenced by input of length dataSize using algorithm specified
409 * by cipherAlgorithm, and write the encrypted result into output. The caller must
410 * ensure that the output buffer is large enough to accept dataSize bytes. The key
411 * to use is identified by the 16 byte keyId. The key must have been loaded into
412 * the session using provideKeyResponse.
413 */
Marco Nelissen18a1b592014-05-20 08:45:18 -0700414media_status_t AMediaDrm_encrypt(AMediaDrm *, const AMediaDrmSessionId *sessionId,
Jeff Tinker497ca092014-05-13 09:31:15 -0700415 const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
416 const uint8_t *input, uint8_t *output, size_t dataSize);
417
418/*
419 * Decrypt the data referenced by input of length dataSize using algorithm specified
420 * by cipherAlgorithm, and write the decrypted result into output. The caller must
421 * ensure that the output buffer is large enough to accept dataSize bytes. The key
422 * to use is identified by the 16 byte keyId. The key must have been loaded into
423 * the session using provideKeyResponse.
424 */
Marco Nelissen18a1b592014-05-20 08:45:18 -0700425media_status_t AMediaDrm_decrypt(AMediaDrm *, const AMediaDrmSessionId *sessionId,
Jeff Tinker497ca092014-05-13 09:31:15 -0700426 const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
427 const uint8_t *input, uint8_t *output, size_t dataSize);
428
429/*
430 * Generate a signature using the specified macAlgorithm over the message data
431 * referenced by message of size messageSize and store the signature in the
432 * buffer referenced signature of max size *signatureSize. If the buffer is not
433 * large enough to hold the signature, MEDIADRM_SHORT_BUFFER is returned and
434 * *signatureSize is set to the buffer size required. The key to use is identified
435 * by the 16 byte keyId. The key must have been loaded into the session using
436 * provideKeyResponse.
437 */
Marco Nelissen18a1b592014-05-20 08:45:18 -0700438media_status_t AMediaDrm_sign(AMediaDrm *, const AMediaDrmSessionId *sessionId,
Jeff Tinker497ca092014-05-13 09:31:15 -0700439 const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize,
440 uint8_t *signature, size_t *signatureSize);
441
442/*
443 * Perform a signature verification using the specified macAlgorithm over the message
444 * data referenced by the message parameter of size messageSize. Returns MEDIADRM_OK
445 * if the signature matches, otherwise MEDAIDRM_VERIFY_FAILED is returned. The key to
446 * use is identified by the 16 byte keyId. The key must have been loaded into the
447 * session using provideKeyResponse.
448 */
Marco Nelissen18a1b592014-05-20 08:45:18 -0700449media_status_t AMediaDrm_verify(AMediaDrm *, const AMediaDrmSessionId *sessionId,
Jeff Tinker497ca092014-05-13 09:31:15 -0700450 const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize,
451 const uint8_t *signature, size_t signatureSize);
452
Dan Albert2975a242016-09-23 16:17:45 -0700453#endif /* __ANDROID_API__ >= 21 */
454
Jeff Tinker497ca092014-05-13 09:31:15 -0700455#ifdef __cplusplus
456} // extern "C"
457#endif
458
459#endif //_NDK_MEDIA_DRM_H