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 36 namespace 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: DrmFactory()55 DrmFactory() {} ~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 // DrmFactory::isContentTypeSupported can be called to determine 64 // if the plugin factory is able to construct plugins that support a 65 // given media container format specified by mimeType 66 virtual bool isContentTypeSupported(const String8 &mimeType) = 0; 67 68 // Construct a DrmPlugin for the crypto scheme specified by UUID. 69 virtual status_t createDrmPlugin( 70 const uint8_t uuid[16], DrmPlugin **plugin) = 0; 71 72 private: 73 DrmFactory(const DrmFactory &); 74 DrmFactory &operator=(const DrmFactory &); 75 }; 76 77 class DrmPlugin { 78 public: 79 enum EventType { 80 kDrmPluginEventProvisionRequired = 1, 81 kDrmPluginEventKeyNeeded, 82 kDrmPluginEventKeyExpired, 83 kDrmPluginEventVendorDefined, 84 kDrmPluginEventSessionReclaimed, 85 kDrmPluginEventExpirationUpdate, 86 kDrmPluginEventKeysChange, 87 kDrmPluginEventSessionLostState, 88 }; 89 90 // Drm keys can be for offline content or for online streaming. 91 // Offline keys are persisted on the device and may be used when the device 92 // is disconnected from the network. The Release type is used to request 93 // that offline keys be no longer restricted to offline use. 94 enum KeyType { 95 kKeyType_Offline, 96 kKeyType_Streaming, 97 kKeyType_Release 98 }; 99 100 // Enumerate KeyRequestTypes to allow an app to determine the 101 // type of a key request returned from getKeyRequest. 102 enum KeyRequestType { 103 kKeyRequestType_Unknown, 104 kKeyRequestType_Initial, 105 kKeyRequestType_Renewal, 106 kKeyRequestType_Release, 107 kKeyRequestType_None, 108 kKeyRequestType_Update, 109 }; 110 111 // Enumerate KeyStatusTypes which indicate the state of a key 112 enum KeyStatusType 113 { 114 kKeyStatusType_Usable, 115 kKeyStatusType_Expired, 116 kKeyStatusType_OutputNotAllowed, 117 kKeyStatusType_StatusPending, 118 kKeyStatusType_InternalError, 119 kKeyStatusType_UsableInFuture 120 }; 121 122 // Used by sendKeysChange to report the usability status of each 123 // key to the app. 124 struct KeyStatus 125 { 126 Vector<uint8_t> mKeyId; 127 KeyStatusType mType; 128 }; 129 130 // Enumerate HDCP output protection levels 131 enum HdcpLevel { 132 // Failure to access HDCP level, an error occurred 133 kHdcpLevelUnknown, 134 // HDCP is not supported on this device, content is unprotected 135 kHdcpNone, 136 // HDCP version 1.0 137 kHdcpV1, 138 // HDCP version 2.0 Type 1. 139 kHdcpV2, 140 // HDCP version 2.1 Type 1. 141 kHdcpV2_1, 142 // HDCP version 2.2 Type 1. 143 kHdcpV2_2, 144 // HDCP version 2.3 Type 1. 145 kHdcpV2_3, 146 // No digital output, implicitly secure 147 kHdcpNoOutput = 0x7fff 148 }; 149 150 // SecurityLevel indicates the level of robustness of the DRM 151 // implementation on the device 152 enum SecurityLevel { 153 // Failure to access security level, an error occurred 154 kSecurityLevelUnknown, 155 // The maximum security level of the device. This is the default when 156 // a session is opened if no security level is specified 157 kSecurityLevelMax, 158 // Software-based whitebox crypto 159 kSecurityLevelSwSecureCrypto, 160 // Software-based whitebox crypto and an obfuscated decoder 161 kSecurityLevelSwSecureDecode, 162 // DRM key management and crypto operations are performed within a 163 // hardware backed trusted execution environment 164 kSecurityLevelHwSecureCrypto, 165 // DRM key management, crypto operations and decoding of content 166 // are performed within a hardware backed trusted execution environment 167 kSecurityLevelHwSecureDecode, 168 // DRM key management, crypto operations, decoding of content and all 169 // handling of the media (compressed and uncompressed) is handled within 170 // a hardware backed trusted execution environment. 171 kSecurityLevelHwSecureAll 172 }; 173 174 // An offline license may be usable or inactive. The keys in a 175 // usable offline license are available for decryption. When 176 // the offline license state is inactive, the keys have been 177 // marked for release using getKeyRequest with 178 // kKeyType_Release but the key response has not been 179 // received. The keys in an inactive offline license are not 180 // usable for decryption. 181 182 enum OfflineLicenseState { 183 // The offline license state is unknown due to an error 184 kOfflineLicenseStateUnknown, 185 // Offline license state is usable, the keys may be used for decryption. 186 kOfflineLicenseStateUsable, 187 // Offline license state is released, the keys have been marked for 188 // release using getKeyRequest() with kKeyType_Release but the 189 // key response has not been received. 190 kOfflineLicenseStateReleased 191 }; 192 DrmPlugin()193 DrmPlugin() {} ~DrmPlugin()194 virtual ~DrmPlugin() {} 195 196 // Open a new session with the DrmPlugin object. A session ID is returned 197 // in the sessionId parameter. 198 virtual status_t openSession(Vector<uint8_t> &sessionId) = 0; 199 200 // Close a session on the DrmPlugin object. 201 virtual status_t closeSession(Vector<uint8_t> const &sessionId) = 0; 202 203 // A key request/response exchange occurs between the app and a License 204 // Server to obtain the keys required to decrypt the content. getKeyRequest() 205 // is used to obtain an opaque key request blob that is delivered to the 206 // license server. 207 // 208 // The scope parameter may be a sessionId or a keySetId, depending on the 209 // specified keyType. When the keyType is kKeyType_Offline or 210 // kKeyType_Streaming, scope should be set to the sessionId the keys will be 211 // provided to. When the keyType is kKeyType_Release, scope should be set to 212 // the keySetId of the keys being released. Releasing keys from a device 213 // invalidates them for all sessions. 214 // 215 // The init data passed to getKeyRequest is container-specific and its 216 // meaning is interpreted based on the mime type provided in the mimeType 217 // parameter to getKeyRequest. It could contain, for example, the content 218 // ID, key ID or other data obtained from the content metadata that is required 219 // in generating the key request. Init may be null when keyType is 220 // kKeyType_Release. 221 // 222 // mimeType identifies the mime type of the content 223 // 224 // keyType specifies if the keys are to be used for streaming or offline content 225 // 226 // optionalParameters are included in the key request message to allow a 227 // client application to provide additional message parameters to the server. 228 // 229 // If successful, the opaque key request blob is returned to the caller. 230 virtual status_t 231 getKeyRequest(Vector<uint8_t> const &scope, 232 Vector<uint8_t> const &initData, 233 String8 const &mimeType, KeyType keyType, 234 KeyedVector<String8, String8> const &optionalParameters, 235 Vector<uint8_t> &request, String8 &defaultUrl, 236 KeyRequestType *keyRequestType) = 0; 237 238 // 239 // After a key response is received by the app, it is provided to the 240 // Drm plugin using provideKeyResponse. 241 // 242 // scope may be a sessionId or a keySetId depending on the type of the 243 // response. Scope should be set to the sessionId when the response is 244 // for either streaming or offline key requests. Scope should be set to the 245 // keySetId when the response is for a release request. 246 // 247 // When the response is for an offline key request, a keySetId is returned 248 // in the keySetId vector parameter that can be used to later restore the 249 // keys to a new session with the method restoreKeys. When the response is 250 // for a streaming or release request, no keySetId is returned. 251 // 252 virtual status_t provideKeyResponse(Vector<uint8_t> const &scope, 253 Vector<uint8_t> const &response, 254 Vector<uint8_t> &keySetId) = 0; 255 256 // Remove the current keys from a session 257 virtual status_t removeKeys(Vector<uint8_t> const &sessionId) = 0; 258 259 // Restore persisted offline keys into a new session. keySetId identifies 260 // the keys to load, obtained from a prior call to provideKeyResponse(). 261 virtual status_t restoreKeys(Vector<uint8_t> const &sessionId, 262 Vector<uint8_t> const &keySetId) = 0; 263 264 // Request an informative description of the license for the session. The status 265 // is in the form of {name, value} pairs. Since DRM license policies vary by 266 // vendor, the specific status field names are determined by each DRM vendor. 267 // Refer to your DRM provider documentation for definitions of the field names 268 // for a particular DrmEngine. 269 virtual status_t 270 queryKeyStatus(Vector<uint8_t> const &sessionId, 271 KeyedVector<String8, String8> &infoMap) const = 0; 272 273 // A provision request/response exchange occurs between the app and a 274 // provisioning server to retrieve a device certificate. getProvisionRequest 275 // is used to obtain an opaque key request blob that is delivered to the 276 // provisioning server. 277 // 278 // If successful, the opaque provision request blob is returned to the caller. 279 virtual status_t getProvisionRequest(String8 const &cert_type, 280 String8 const &cert_authority, 281 Vector<uint8_t> &request, 282 String8 &defaultUrl) = 0; 283 284 // After a provision response is received by the app, it is provided to the 285 // Drm plugin using provideProvisionResponse. 286 virtual status_t provideProvisionResponse(Vector<uint8_t> const &response, 287 Vector<uint8_t> &certificate, 288 Vector<uint8_t> &wrapped_key) = 0; 289 290 // A means of enforcing the contractual requirement for a concurrent stream 291 // limit per subscriber across devices is provided via SecureStop. SecureStop 292 // is a means of securely monitoring the lifetime of sessions. Since playback 293 // on a device can be interrupted due to reboot, power failure, etc. a means 294 // of persisting the lifetime information on the device is needed. 295 // 296 // A signed version of the sessionID is written to persistent storage on the 297 // device when each MediaCrypto object is created. The sessionID is signed by 298 // the device private key to prevent tampering. 299 // 300 // In the normal case, playback will be completed, the session destroyed and 301 // the Secure Stops will be queried. The App queries secure stops and forwards 302 // the secure stop message to the server which verifies the signature and 303 // notifies the server side database that the session destruction has been 304 // confirmed. The persisted record on the client is only removed after positive 305 // confirmation that the server received the message using releaseSecureStops(). 306 virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) = 0; 307 virtual status_t getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) = 0; 308 virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0; 309 virtual status_t releaseAllSecureStops() = 0; 310 311 // Read a property value given the device property string. There are a few forms 312 // of property access methods, depending on the data type returned. 313 // Since DRM plugin properties may vary, additional field names may be defined 314 // by each DRM vendor. Refer to your DRM provider documentation for definitions 315 // of its additional field names. 316 // 317 // Standard values are: 318 // "vendor" [string] identifies the maker of the plugin 319 // "version" [string] identifies the version of the plugin 320 // "description" [string] describes the plugin 321 // 'deviceUniqueId' [byte array] The device unique identifier is established 322 // during device provisioning and provides a means of uniquely identifying 323 // each device. 324 virtual status_t getPropertyString(String8 const &name, String8 &value ) const = 0; 325 virtual status_t getPropertyByteArray(String8 const &name, 326 Vector<uint8_t> &value ) const = 0; 327 328 // Write a property value given the device property string. There are a few forms 329 // of property setting methods, depending on the data type. 330 // Since DRM plugin properties may vary, additional field names may be defined 331 // by each DRM vendor. Refer to your DRM provider documentation for definitions 332 // of its field names. 333 virtual status_t setPropertyString(String8 const &name, 334 String8 const &value ) = 0; 335 virtual status_t setPropertyByteArray(String8 const &name, 336 Vector<uint8_t> const &value ) = 0; 337 338 // The following methods implement operations on a CryptoSession to support 339 // encrypt, decrypt, sign verify operations on operator-provided 340 // session keys. 341 342 // 343 // The algorithm string conforms to JCA Standard Names for Cipher 344 // Transforms and is case insensitive. For example "AES/CBC/PKCS5Padding". 345 // 346 // Return OK if the algorithm is supported, otherwise return BAD_VALUE 347 // 348 virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId, 349 String8 const &algorithm) = 0; 350 351 // 352 // The algorithm string conforms to JCA Standard Names for Mac 353 // Algorithms and is case insensitive. For example "HmacSHA256". 354 // 355 // Return OK if the algorithm is supported, otherwise return BAD_VALUE 356 // 357 virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId, 358 String8 const &algorithm) = 0; 359 360 // Encrypt the provided input buffer with the cipher algorithm 361 // specified by setCipherAlgorithm and the key selected by keyId, 362 // and return the encrypted data. 363 virtual status_t encrypt(Vector<uint8_t> const &sessionId, 364 Vector<uint8_t> const &keyId, 365 Vector<uint8_t> const &input, 366 Vector<uint8_t> const &iv, 367 Vector<uint8_t> &output) = 0; 368 369 // Decrypt the provided input buffer with the cipher algorithm 370 // specified by setCipherAlgorithm and the key selected by keyId, 371 // and return the decrypted data. 372 virtual status_t decrypt(Vector<uint8_t> const &sessionId, 373 Vector<uint8_t> const &keyId, 374 Vector<uint8_t> const &input, 375 Vector<uint8_t> const &iv, 376 Vector<uint8_t> &output) = 0; 377 378 // Compute a signature on the provided message using the mac algorithm 379 // specified by setMacAlgorithm and the key selected by keyId, 380 // and return the signature. 381 virtual status_t sign(Vector<uint8_t> const &sessionId, 382 Vector<uint8_t> const &keyId, 383 Vector<uint8_t> const &message, 384 Vector<uint8_t> &signature) = 0; 385 386 // Compute a signature on the provided message using the mac algorithm 387 // specified by setMacAlgorithm and the key selected by keyId, 388 // and compare with the expected result. Set result to true or 389 // false depending on the outcome. 390 virtual status_t verify(Vector<uint8_t> const &sessionId, 391 Vector<uint8_t> const &keyId, 392 Vector<uint8_t> const &message, 393 Vector<uint8_t> const &signature, 394 bool &match) = 0; 395 396 397 // Compute an RSA signature on the provided message using the algorithm 398 // specified by algorithm. 399 virtual status_t signRSA(Vector<uint8_t> const &sessionId, 400 String8 const &algorithm, 401 Vector<uint8_t> const &message, 402 Vector<uint8_t> const &wrapped_key, 403 Vector<uint8_t> &signature) = 0; 404 405 setListener(const sp<DrmPluginListener> & listener)406 status_t setListener(const sp<DrmPluginListener>& listener) { 407 Mutex::Autolock lock(mEventLock); 408 mListener = listener; 409 return OK; 410 } 411 412 protected: 413 // Plugins call these methods to deliver events to the java app 414 void sendEvent(EventType eventType, int extra, 415 Vector<uint8_t> const *sessionId, 416 Vector<uint8_t> const *data); 417 418 void sendExpirationUpdate(Vector<uint8_t> const *sessionId, 419 int64_t expiryTimeInMS); 420 421 void sendKeysChange(Vector<uint8_t> const *sessionId, 422 Vector<DrmPlugin::KeyStatus> const *keyStatusList, 423 bool hasNewUsableKey); 424 425 private: 426 Mutex mEventLock; 427 sp<DrmPluginListener> mListener; 428 429 DISALLOW_EVIL_CONSTRUCTORS(DrmPlugin); 430 }; 431 432 class DrmPluginListener: virtual public RefBase 433 { 434 public: 435 virtual void sendEvent(DrmPlugin::EventType eventType, int extra, 436 Vector<uint8_t> const *sessionId, 437 Vector<uint8_t> const *data) = 0; 438 439 virtual void sendExpirationUpdate(Vector<uint8_t> const *sessionId, 440 int64_t expiryTimeInMS) = 0; 441 442 virtual void sendKeysChange(Vector<uint8_t> const *sessionId, 443 Vector<DrmPlugin::KeyStatus> const *keyStatusList, 444 bool hasNewUsableKey) = 0; 445 }; 446 sendEvent(EventType eventType,int extra,Vector<uint8_t> const * sessionId,Vector<uint8_t> const * data)447 inline void DrmPlugin::sendEvent(EventType eventType, int extra, 448 Vector<uint8_t> const *sessionId, 449 Vector<uint8_t> const *data) { 450 mEventLock.lock(); 451 sp<DrmPluginListener> listener = mListener; 452 mEventLock.unlock(); 453 454 if (listener != NULL) { 455 listener->sendEvent(eventType, extra, sessionId, data); 456 } 457 } 458 sendExpirationUpdate(Vector<uint8_t> const * sessionId,int64_t expiryTimeInMS)459 inline void DrmPlugin::sendExpirationUpdate(Vector<uint8_t> const *sessionId, 460 int64_t expiryTimeInMS) { 461 mEventLock.lock(); 462 sp<DrmPluginListener> listener = mListener; 463 mEventLock.unlock(); 464 465 if (listener != NULL) { 466 listener->sendExpirationUpdate(sessionId, expiryTimeInMS); 467 } 468 } 469 sendKeysChange(Vector<uint8_t> const * sessionId,Vector<DrmPlugin::KeyStatus> const * keyStatusList,bool hasNewUsableKey)470 inline void DrmPlugin::sendKeysChange(Vector<uint8_t> const *sessionId, 471 Vector<DrmPlugin::KeyStatus> const *keyStatusList, 472 bool hasNewUsableKey) { 473 mEventLock.lock(); 474 sp<DrmPluginListener> listener = mListener; 475 mEventLock.unlock(); 476 477 if (listener != NULL) { 478 listener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey); 479 } 480 } 481 } // namespace android 482 483 #endif // DRM_API_H_ 484