DrmAPI.h revision 7eafcae5ffb7f6f12ee573dea685dc6989a0ee91
1/* 2 * Copyright (C) 2013 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#ifndef DRM_API_H_ 18#define DRM_API_H_ 19 20#include <utils/List.h> 21#include <utils/String8.h> 22#include <utils/Vector.h> 23#include <utils/KeyedVector.h> 24#include <utils/RefBase.h> 25#include <utils/Mutex.h> 26#include <media/stagefright/foundation/ABase.h> 27 28// Loadable DrmEngine shared libraries should define the entry points 29// createDrmFactory and createCryptoFactory as shown below: 30// 31// extern "C" { 32// extern android::DrmFactory *createDrmFactory(); 33// extern android::CryptoFactory *createCryptoFactory(); 34// } 35 36namespace android { 37 38 class DrmPlugin; 39 class DrmPluginListener; 40 41 // DRMs are implemented in DrmEngine plugins, which are dynamically 42 // loadable shared libraries that implement the entry points 43 // createDrmFactory and createCryptoFactory. createDrmFactory 44 // constructs and returns an instance of a DrmFactory object. Similarly, 45 // createCryptoFactory creates an instance of a CryptoFactory object. 46 // When a MediaCrypto or MediaDrm object needs to be constructed, all 47 // available DrmEngines present in the plugins directory on the device 48 // are scanned for a matching DrmEngine that can support the crypto 49 // scheme. When a match is found, the DrmEngine's createCryptoPlugin and 50 // createDrmPlugin methods are used to create CryptoPlugin or 51 // DrmPlugin instances to support that DRM scheme. 52 53 class DrmFactory { 54 public: 55 DrmFactory() {} 56 virtual ~DrmFactory() {} 57 58 // DrmFactory::isCryptoSchemeSupported can be called to determine 59 // if the plugin factory is able to construct plugins that support a 60 // given crypto scheme, which is specified by a UUID. 61 virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) = 0; 62 63 // Construct a DrmPlugin for the crypto scheme specified by UUID. 64 virtual status_t createDrmPlugin( 65 const uint8_t uuid[16], DrmPlugin **plugin) = 0; 66 67 private: 68 DrmFactory(const DrmFactory &); 69 DrmFactory &operator=(const DrmFactory &); 70 }; 71 72 class DrmPlugin { 73 public: 74 enum EventType { 75 kDrmPluginEventProvisionRequired = 1, 76 kDrmPluginEventKeyNeeded, 77 kDrmPluginEventKeyExpired, 78 kDrmPluginEventVendorDefined 79 }; 80 81 // Drm keys can be for offline content or for online streaming. 82 // Offline keys are persisted on the device and may be used when the device 83 // is disconnected from the network. 84 enum KeyType { 85 kKeyType_Offline, 86 kKeyType_Streaming 87 }; 88 89 DrmPlugin() {} 90 virtual ~DrmPlugin() {} 91 92 // Open a new session with the DrmPlugin object. A session ID is returned 93 // in the sessionId parameter. 94 virtual status_t openSession(Vector<uint8_t> &sessionId) = 0; 95 96 // Close a session on the DrmPlugin object. 97 virtual status_t closeSession(Vector<uint8_t> const &sessionId) = 0; 98 99 // A key request/response exchange occurs between the app and a License 100 // Server to obtain the keys required to decrypt the content. getKeyRequest() 101 // is used to obtain an opaque key request blob that is delivered to the 102 // license server. 103 // 104 // The init data passed to getKeyRequest is container-specific and its 105 // meaning is interpreted based on the mime type provided in the mimeType 106 // parameter to getKeyRequest. It could contain, for example, the content 107 // ID, key ID or other data obtained from the content metadata that is required 108 // in generating the key request. 109 // 110 // keyType specifes if the keys are to be used for streaming or offline content 111 // 112 // optionalParameters are included in the key request message to allow a 113 // client application to provide additional message parameters to the server. 114 // 115 // If successful, the opaque key request blob is returned to the caller. 116 virtual status_t 117 getKeyRequest(Vector<uint8_t> const &sessionId, 118 Vector<uint8_t> const &initData, 119 String8 const &mimeType, KeyType keyType, 120 KeyedVector<String8, String8> const &optionalParameters, 121 Vector<uint8_t> &request, String8 &defaultUrl) = 0; 122 123 // After a key response is received by the app, it is provided to the 124 // Drm plugin using provideKeyResponse. Returns the id of the key set 125 // in keySetId. The keySetId can be used by removeKeys or restoreKeys 126 // when the keys are used for offline content. 127 virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId, 128 Vector<uint8_t> const &response, 129 Vector<uint8_t> &keySetId) = 0; 130 131 // Remove the persisted keys associated with an offline license for a session. 132 virtual status_t removeKeys(Vector<uint8_t> const &keySetId) = 0; 133 134 // Restore persisted offline keys into a new session. keySetId identifies 135 // the keys to load, obtained from a prior call to provideKeyResponse(). 136 virtual status_t restoreKeys(Vector<uint8_t> const &sessionId, 137 Vector<uint8_t> const &keySetId) = 0; 138 139 // Request an informative description of the license for the session. The status 140 // is in the form of {name, value} pairs. Since DRM license policies vary by 141 // vendor, the specific status field names are determined by each DRM vendor. 142 // Refer to your DRM provider documentation for definitions of the field names 143 // for a particular DrmEngine. 144 virtual status_t 145 queryKeyStatus(Vector<uint8_t> const &sessionId, 146 KeyedVector<String8, String8> &infoMap) const = 0; 147 148 // A provision request/response exchange occurs between the app and a 149 // provisioning server to retrieve a device certificate. getProvisionRequest 150 // is used to obtain an opaque key request blob that is delivered to the 151 // provisioning server. 152 // 153 // If successful, the opaque provision request blob is returned to the caller. 154 virtual status_t getProvisionRequest(Vector<uint8_t> &request, 155 String8 &defaultUrl) = 0; 156 157 // After a provision response is received by the app, it is provided to the 158 // Drm plugin using provideProvisionResponse. 159 virtual status_t provideProvisionResponse(Vector<uint8_t> const &response) = 0; 160 161 // A means of enforcing the contractual requirement for a concurrent stream 162 // limit per subscriber across devices is provided via SecureStop. SecureStop 163 // is a means of securely monitoring the lifetime of sessions. Since playback 164 // on a device can be interrupted due to reboot, power failure, etc. a means 165 // of persisting the lifetime information on the device is needed. 166 // 167 // A signed version of the sessionID is written to persistent storage on the 168 // device when each MediaCrypto object is created. The sessionID is signed by 169 // the device private key to prevent tampering. 170 // 171 // In the normal case, playback will be completed, the session destroyed and 172 // the Secure Stops will be queried. The App queries secure stops and forwards 173 // the secure stop message to the server which verifies the signature and 174 // notifies the server side database that the session destruction has been 175 // confirmed. The persisted record on the client is only removed after positive 176 // confirmation that the server received the message using releaseSecureStops(). 177 virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) = 0; 178 virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0; 179 180 // Read a property value given the device property string. There are a few forms 181 // of property access methods, depending on the data type returned. 182 // Since DRM plugin properties may vary, additional field names may be defined 183 // by each DRM vendor. Refer to your DRM provider documentation for definitions 184 // of its additional field names. 185 // 186 // Standard values are: 187 // "vendor" [string] identifies the maker of the plugin 188 // "version" [string] identifies the version of the plugin 189 // "description" [string] describes the plugin 190 // 'deviceUniqueId' [byte array] The device unique identifier is established 191 // during device provisioning and provides a means of uniquely identifying 192 // each device. 193 virtual status_t getPropertyString(String8 const &name, String8 &value ) const = 0; 194 virtual status_t getPropertyByteArray(String8 const &name, 195 Vector<uint8_t> &value ) const = 0; 196 197 // Write a property value given the device property string. There are a few forms 198 // of property setting methods, depending on the data type. 199 // Since DRM plugin properties may vary, additional field names may be defined 200 // by each DRM vendor. Refer to your DRM provider documentation for definitions 201 // of its field names. 202 virtual status_t setPropertyString(String8 const &name, 203 String8 const &value ) = 0; 204 virtual status_t setPropertyByteArray(String8 const &name, 205 Vector<uint8_t> const &value ) = 0; 206 207 // The following methods implement operations on a CryptoSession to support 208 // encrypt, decrypt, sign verify operations on operator-provided 209 // session keys. 210 211 // 212 // The algorithm string conforms to JCA Standard Names for Cipher 213 // Transforms and is case insensitive. For example "AES/CBC/PKCS5Padding". 214 // 215 // Return OK if the algorithm is supported, otherwise return BAD_VALUE 216 // 217 virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId, 218 String8 const &algorithm) = 0; 219 220 // 221 // The algorithm string conforms to JCA Standard Names for Mac 222 // Algorithms and is case insensitive. For example "HmacSHA256". 223 // 224 // Return OK if the algorithm is supported, otherwise return BAD_VALUE 225 // 226 virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId, 227 String8 const &algorithm) = 0; 228 229 // Encrypt the provided input buffer with the cipher algorithm 230 // specified by setCipherAlgorithm and the key selected by keyId, 231 // and return the encrypted data. 232 virtual status_t encrypt(Vector<uint8_t> const &sessionId, 233 Vector<uint8_t> const &keyId, 234 Vector<uint8_t> const &input, 235 Vector<uint8_t> const &iv, 236 Vector<uint8_t> &output) = 0; 237 238 // Decrypt the provided input buffer with the cipher algorithm 239 // specified by setCipherAlgorithm and the key selected by keyId, 240 // and return the decrypted data. 241 virtual status_t decrypt(Vector<uint8_t> const &sessionId, 242 Vector<uint8_t> const &keyId, 243 Vector<uint8_t> const &input, 244 Vector<uint8_t> const &iv, 245 Vector<uint8_t> &output) = 0; 246 247 // Compute a signature on the provided message using the mac algorithm 248 // specified by setMacAlgorithm and the key selected by keyId, 249 // and return the signature. 250 virtual status_t sign(Vector<uint8_t> const &sessionId, 251 Vector<uint8_t> const &keyId, 252 Vector<uint8_t> const &message, 253 Vector<uint8_t> &signature) = 0; 254 255 // Compute a signature on the provided message using the mac algorithm 256 // specified by setMacAlgorithm and the key selected by keyId, 257 // and compare with the expected result. Set result to true or 258 // false depending on the outcome. 259 virtual status_t verify(Vector<uint8_t> const &sessionId, 260 Vector<uint8_t> const &keyId, 261 Vector<uint8_t> const &message, 262 Vector<uint8_t> const &signature, 263 bool &match) = 0; 264 265 266 status_t setListener(const sp<DrmPluginListener>& listener) { 267 Mutex::Autolock lock(mEventLock); 268 mListener = listener; 269 return OK; 270 } 271 272 protected: 273 // Plugins call sendEvent to deliver events to the java app 274 void sendEvent(EventType eventType, int extra, 275 Vector<uint8_t> const *sessionId, 276 Vector<uint8_t> const *data); 277 278 private: 279 Mutex mEventLock; 280 sp<DrmPluginListener> mListener; 281 282 DISALLOW_EVIL_CONSTRUCTORS(DrmPlugin); 283 }; 284 285 class DrmPluginListener: virtual public RefBase 286 { 287 public: 288 virtual void sendEvent(DrmPlugin::EventType eventType, int extra, 289 Vector<uint8_t> const *sesionId, 290 Vector<uint8_t> const *data) = 0; 291 }; 292 293 inline void DrmPlugin::sendEvent(EventType eventType, int extra, 294 Vector<uint8_t> const *sessionId, 295 Vector<uint8_t> const *data) { 296 297 mEventLock.lock(); 298 sp<DrmPluginListener> listener = mListener; 299 mEventLock.unlock(); 300 301 if (listener != NULL) { 302 listener->sendEvent(eventType, extra, sessionId, data); 303 } 304 } 305 306} // namespace android 307 308#endif // DRM_API_H_ 309