Home | History | Annotate | Download | only in media
      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 bool AMediaDrm_isCryptoSchemeSupported(const uint8_t *uuid,
    179         const char *mimeType) __INTRODUCED_IN(21);
    180 
    181 /**
    182  * Create a MediaDrm instance from a UUID
    183  * uuid identifies the universal unique ID of the crypto scheme. uuid must be 16 bytes.
    184  */
    185 AMediaDrm* AMediaDrm_createByUUID(const uint8_t *uuid) __INTRODUCED_IN(21);
    186 
    187 /**
    188  * Release a MediaDrm object
    189  */
    190 void AMediaDrm_release(AMediaDrm *) __INTRODUCED_IN(21);
    191 
    192 /**
    193  * Register a callback to be invoked when an event occurs
    194  *
    195  * listener is the callback that will be invoked on event
    196  */
    197 media_status_t AMediaDrm_setOnEventListener(AMediaDrm *,
    198         AMediaDrmEventListener listener) __INTRODUCED_IN(21);
    199 
    200 /**
    201  * Register a callback to be invoked when an expiration update event occurs
    202  *
    203  * listener is the callback that will be invoked on event
    204  */
    205 media_status_t AMediaDrm_setOnExpirationUpdateListener(AMediaDrm *,
    206         AMediaDrmExpirationUpdateListener listener) __INTRODUCED_IN(29);
    207 
    208 /**
    209  * Register a callback to be invoked when a key status change event occurs
    210  *
    211  * listener is the callback that will be invoked on event
    212  */
    213 media_status_t AMediaDrm_setOnKeysChangeListener(AMediaDrm *,
    214         AMediaDrmKeysChangeListener listener) __INTRODUCED_IN(29);
    215 
    216 /**
    217  * Open a new session with the MediaDrm object.  A session ID is returned.
    218  *
    219  * returns MEDIADRM_NOT_PROVISIONED_ERROR if provisioning is needed
    220  * returns MEDIADRM_RESOURCE_BUSY_ERROR if required resources are in use
    221  */
    222 media_status_t AMediaDrm_openSession(AMediaDrm *,
    223         AMediaDrmSessionId *sessionId) __INTRODUCED_IN(21);
    224 
    225 /**
    226  * Close a session on the MediaDrm object that was previously opened
    227  * with AMediaDrm_openSession.
    228  */
    229 media_status_t AMediaDrm_closeSession(AMediaDrm *,
    230         const AMediaDrmSessionId *sessionId) __INTRODUCED_IN(21);
    231 
    232 /**
    233  * A key request/response exchange occurs between the app and a license server
    234  * to obtain or release keys used to decrypt encrypted content.
    235  * AMediaDrm_getKeyRequest is used to obtain an opaque key request byte array that
    236  * is delivered to the license server.  The opaque key request byte array is
    237  * returned in KeyRequest.data.
    238  *
    239  * After the app has received the key request response from the server,
    240  * it should deliver to the response to the DRM engine plugin using the method
    241  * AMediaDrm_provideKeyResponse.
    242  *
    243  * scope may be a sessionId or a keySetId, depending on the specified keyType.
    244  * When the keyType is KEY_TYPE_STREAMING or KEY_TYPE_OFFLINE, scope should be set
    245  * to the sessionId the keys will be provided to.  When the keyType is
    246  * KEY_TYPE_RELEASE, scope should be set to the keySetId of the keys being released.
    247  * Releasing keys from a device invalidates them for all sessions.
    248  *
    249  * init container-specific data, its meaning is interpreted based on the mime type
    250  * provided in the mimeType parameter.  It could contain, for example, the content
    251  * ID, key ID or other data obtained from the content metadata that is required in
    252  * generating the key request. init may be null when keyType is KEY_TYPE_RELEASE.
    253  *
    254  * initSize is the number of bytes of initData
    255  *
    256  * mimeType identifies the mime type of the content.
    257  *
    258  * keyType specifes the type of the request. The request may be to acquire keys for
    259  *   streaming or offline content, or to release previously acquired keys, which are
    260  *   identified by a keySetId.
    261  *
    262  * optionalParameters are included in the key request message to allow a client
    263  *   application to provide additional message parameters to the server.
    264  *
    265  * numOptionalParameters indicates the number of optional parameters provided
    266  *   by the caller
    267  *
    268  * On exit:
    269  *   1. The keyRequest pointer will reference the opaque key request data.  It
    270  *       will reside in memory owned by the AMediaDrm object, and will remain
    271  *       accessible until the next call to AMediaDrm_getKeyRequest or until the
    272  *       MediaDrm object is released.
    273  *   2. keyRequestSize will be set to the size of the request
    274  *
    275  * returns MEDIADRM_NOT_PROVISIONED_ERROR if reprovisioning is needed, due to a
    276  * problem with the device certificate.
    277 */
    278 media_status_t AMediaDrm_getKeyRequest(AMediaDrm *, const AMediaDrmScope *scope,
    279         const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType,
    280         const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters,
    281         const uint8_t **keyRequest, size_t *keyRequestSize) __INTRODUCED_IN(21);
    282 
    283 /**
    284  * A key response is received from the license server by the app, then it is
    285  * provided to the DRM engine plugin using provideKeyResponse.  When the
    286  * response is for an offline key request, a keySetId is returned that can be
    287  * used to later restore the keys to a new session with AMediaDrm_restoreKeys.
    288  * When the response is for a streaming or release request, a null keySetId is
    289  * returned.
    290  *
    291  * scope may be a sessionId or keySetId depending on the type of the
    292  * response.  Scope should be set to the sessionId when the response is for either
    293  * streaming or offline key requests.  Scope should be set to the keySetId when
    294  * the response is for a release request.
    295  *
    296  * response points to the opaque response from the server
    297  * responseSize should be set to the size of the response in bytes
    298  */
    299 
    300 media_status_t AMediaDrm_provideKeyResponse(AMediaDrm *, const AMediaDrmScope *scope,
    301         const uint8_t *response, size_t responseSize,
    302         AMediaDrmKeySetId *keySetId) __INTRODUCED_IN(21);
    303 
    304 /**
    305  * Restore persisted offline keys into a new session.  keySetId identifies the
    306  * keys to load, obtained from a prior call to AMediaDrm_provideKeyResponse.
    307  *
    308  * sessionId is the session ID for the DRM session
    309  * keySetId identifies the saved key set to restore
    310  */
    311 media_status_t AMediaDrm_restoreKeys(AMediaDrm *, const AMediaDrmSessionId *sessionId,
    312         const AMediaDrmKeySetId *keySetId) __INTRODUCED_IN(21);
    313 
    314 /**
    315  * Remove the current keys from a session.
    316  *
    317  * keySetId identifies keys to remove
    318  */
    319 media_status_t AMediaDrm_removeKeys(AMediaDrm *,
    320         const AMediaDrmSessionId *keySetId) __INTRODUCED_IN(21);
    321 
    322 /**
    323  * Request an informative description of the key status for the session.  The status is
    324  * in the form of {key, value} pairs.  Since DRM license policies vary by vendor,
    325  * the specific status field names are determined by each DRM vendor.  Refer to your
    326  * DRM provider documentation for definitions of the field names for a particular
    327  * DRM engine plugin.
    328  *
    329  * On entry, numPairs should be set by the caller to the maximum number of pairs
    330  * that can be returned (the size of the array).  On exit, numPairs will be set
    331  * to the number of entries written to the array.  If the number of {key, value} pairs
    332  * to be returned is greater than *numPairs, MEDIADRM_SHORT_BUFFER will be returned
    333  * and numPairs will be set to the number of pairs available.
    334  */
    335 media_status_t AMediaDrm_queryKeyStatus(AMediaDrm *, const AMediaDrmSessionId *sessionId,
    336         AMediaDrmKeyValue *keyValuePairs, size_t *numPairs) __INTRODUCED_IN(21);
    337 
    338 
    339 /**
    340  * A provision request/response exchange occurs between the app and a provisioning
    341  * server to retrieve a device certificate.  If provisionining is required, the
    342  * EVENT_PROVISION_REQUIRED event will be sent to the event handler.
    343  * getProvisionRequest is used to obtain the opaque provision request byte array that
    344  * should be delivered to the provisioning server.
    345  * On exit:
    346  *    1. The provision request data will be referenced by provisionRequest, in
    347  *        memory owned by the AMediaDrm object.  It will remain accessible until the
    348  *        next call to getProvisionRequest.
    349  *    2. provisionRequestSize will be set to the size of the request data.
    350  *    3. serverUrl will reference a NULL terminated string containing the URL
    351  *       the provisioning request should be sent to.  It will remain accessible until
    352  *       the next call to getProvisionRequest.
    353  */
    354 media_status_t AMediaDrm_getProvisionRequest(AMediaDrm *, const uint8_t **provisionRequest,
    355         size_t *provisionRequestSize, const char **serverUrl) __INTRODUCED_IN(21);
    356 
    357 
    358 /**
    359  * After a provision response is received by the app, it is provided to the DRM
    360  * engine plugin using this method.
    361  *
    362  * response is the opaque provisioning response byte array to provide to the
    363  *   DRM engine plugin.
    364  * responseSize is the length of the provisioning response in bytes.
    365  *
    366  * returns MEDIADRM_DEVICE_REVOKED_ERROR if the response indicates that the
    367  * server rejected the request
    368  */
    369 media_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *,
    370         const uint8_t *response, size_t responseSize) __INTRODUCED_IN(21);
    371 
    372 
    373 /**
    374  * A means of enforcing limits on the number of concurrent streams per subscriber
    375  * across devices is provided via SecureStop. This is achieved by securely
    376  * monitoring the lifetime of sessions.
    377  *
    378  * Information from the server related to the current playback session is written
    379  * to persistent storage on the device when each MediaCrypto object is created.
    380  *
    381  * In the normal case, playback will be completed, the session destroyed and the
    382  * Secure Stops will be queried. The app queries secure stops and forwards the
    383  * secure stop message to the server which verifies the signature and notifies the
    384  * server side database that the session destruction has been confirmed. The persisted
    385  * record on the client is only removed after positive confirmation that the server
    386  * received the message using releaseSecureStops().
    387  *
    388  * numSecureStops is set by the caller to the maximum number of secure stops to
    389  * return.  On exit, *numSecureStops will be set to the number actually returned.
    390  * If *numSecureStops is too small for the number of secure stops available,
    391  * MEDIADRM_SHORT_BUFFER will be returned and *numSecureStops will be set to the
    392  * number required.
    393  */
    394 media_status_t AMediaDrm_getSecureStops(AMediaDrm *,
    395         AMediaDrmSecureStop *secureStops, size_t *numSecureStops) __INTRODUCED_IN(21);
    396 
    397 /**
    398  * Process the SecureStop server response message ssRelease.  After authenticating
    399  * the message, remove the SecureStops identified in the response.
    400  *
    401  * ssRelease is the server response indicating which secure stops to release
    402  */
    403 media_status_t AMediaDrm_releaseSecureStops(AMediaDrm *,
    404         const AMediaDrmSecureStop *ssRelease) __INTRODUCED_IN(21);
    405 
    406 /**
    407  * String property name: identifies the maker of the DRM engine plugin
    408  */
    409 #define PROPERTY_VENDOR "vendor"
    410 
    411 /**
    412  * String property name: identifies the version of the DRM engine plugin
    413  */
    414 #define PROPERTY_VERSION "version"
    415 
    416 /**
    417  * String property name: describes the DRM engine plugin
    418  */
    419 #define PROPERTY_DESCRIPTION "description"
    420 
    421 /**
    422  * String property name: a comma-separated list of cipher and mac algorithms
    423  * supported by CryptoSession.  The list may be empty if the DRM engine
    424  * plugin does not support CryptoSession operations.
    425  */
    426 #define PROPERTY_ALGORITHMS "algorithms"
    427 
    428 /**
    429  * Read a DRM engine plugin String property value, given the property name string.
    430  *
    431  * propertyName identifies the property to query
    432  * On return, propertyValue will be set to point to the property value.  The
    433  * memory that the value resides in is owned by the NDK MediaDrm API and
    434  * will remain valid until the next call to AMediaDrm_getPropertyString.
    435  */
    436 media_status_t AMediaDrm_getPropertyString(AMediaDrm *, const char *propertyName,
    437         const char **propertyValue) __INTRODUCED_IN(21);
    438 
    439 /**
    440  * Byte array property name: the device unique identifier is established during
    441  * device provisioning and provides a means of uniquely identifying each device.
    442  */
    443 #define PROPERTY_DEVICE_UNIQUE_ID "deviceUniqueId"
    444 
    445 /**
    446  * Read a DRM engine plugin byte array property value, given the property name string.
    447  * On return, *propertyValue will be set to point to the property value.  The
    448  * memory that the value resides in is owned by the NDK MediaDrm API and
    449  * will remain valid until the next call to AMediaDrm_getPropertyByteArray.
    450  */
    451 media_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *, const char *propertyName,
    452         AMediaDrmByteArray *propertyValue) __INTRODUCED_IN(21);
    453 
    454 /**
    455  * Set a DRM engine plugin String property value.
    456  */
    457 media_status_t AMediaDrm_setPropertyString(AMediaDrm *, const char *propertyName,
    458         const char *value) __INTRODUCED_IN(21);
    459 
    460 /**
    461  * Set a DRM engine plugin byte array property value.
    462  */
    463 media_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *, const char *propertyName,
    464         const uint8_t *value, size_t valueSize) __INTRODUCED_IN(21);
    465 
    466 /**
    467  * In addition to supporting decryption of DASH Common Encrypted Media, the
    468  * MediaDrm APIs provide the ability to securely deliver session keys from
    469  * an operator's session key server to a client device, based on the factory-installed
    470  * root of trust, and then perform encrypt, decrypt, sign and verify operations
    471  * with the session key on arbitrary user data.
    472  *
    473  * Operators create session key servers that receive session key requests and provide
    474  * encrypted session keys which can be used for general purpose crypto operations.
    475  *
    476  * Generic encrypt/decrypt/sign/verify methods are based on the established session
    477  * keys.  These keys are exchanged using the getKeyRequest/provideKeyResponse methods.
    478  *
    479  * Applications of this capability include securing various types of purchased or
    480  * private content, such as applications, books and other media, photos or media
    481  * delivery protocols.
    482  */
    483 
    484 /*
    485  * Encrypt the data referenced by input of length dataSize using algorithm specified
    486  * by cipherAlgorithm, and write the encrypted result into output.  The caller must
    487  * ensure that the output buffer is large enough to accept dataSize bytes. The key
    488  * to use is identified by the 16 byte keyId.  The key must have been loaded into
    489  * the session using provideKeyResponse.
    490  */
    491 media_status_t AMediaDrm_encrypt(AMediaDrm *, const AMediaDrmSessionId *sessionId,
    492         const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
    493         const uint8_t *input, uint8_t *output, size_t dataSize) __INTRODUCED_IN(21);
    494 
    495 /*
    496  * Decrypt the data referenced by input of length dataSize using algorithm specified
    497  * by cipherAlgorithm, and write the decrypted result into output.  The caller must
    498  * ensure that the output buffer is large enough to accept dataSize bytes.  The key
    499  * to use is identified by the 16 byte keyId.  The key must have been loaded into
    500  * the session using provideKeyResponse.
    501  */
    502 media_status_t AMediaDrm_decrypt(AMediaDrm *, const AMediaDrmSessionId *sessionId,
    503         const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
    504         const uint8_t *input, uint8_t *output, size_t dataSize) __INTRODUCED_IN(21);
    505 
    506 /*
    507  * Generate a signature using the specified macAlgorithm over the message data
    508  * referenced by message of size messageSize and store the signature in the
    509  * buffer referenced signature of max size *signatureSize.  If the buffer is not
    510  * large enough to hold the signature, MEDIADRM_SHORT_BUFFER is returned and
    511  * *signatureSize is set to the buffer size required.  The key to use is identified
    512  * by the 16 byte keyId.  The key must have been loaded into the session using
    513  * provideKeyResponse.
    514  */
    515 media_status_t AMediaDrm_sign(AMediaDrm *, const AMediaDrmSessionId *sessionId,
    516         const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize,
    517         uint8_t *signature, size_t *signatureSize) __INTRODUCED_IN(21);
    518 
    519 /*
    520  * Perform a signature verification using the specified macAlgorithm over the message
    521  * data referenced by the message parameter of size messageSize. Returns MEDIADRM_OK
    522  * if the signature matches, otherwise MEDAIDRM_VERIFY_FAILED is returned. The key to
    523  * use is identified by the 16 byte keyId.  The key must have been loaded into the
    524  * session using provideKeyResponse.
    525  */
    526 media_status_t AMediaDrm_verify(AMediaDrm *, const AMediaDrmSessionId *sessionId,
    527         const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize,
    528         const uint8_t *signature, size_t signatureSize) __INTRODUCED_IN(21);
    529 
    530 #endif /* __ANDROID_API__ >= 21 */
    531 
    532 __END_DECLS
    533 
    534 #endif //_NDK_MEDIA_DRM_H
    535 
    536 /** @} */
    537