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