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