/********************************************************************* * MockOEMCrypto.h * * (c) Copyright 2011-2012 Google, Inc. * * Mock implementation of OEMCrypto.h used for testing. *********************************************************************/ #ifndef WV_MOCK_OEMCRYPTO_H_ #define WV_MOCK_OEMCRYPTO_H_ #include "OEMCryptoDASH.h" #include #include #include #include #include #include #include #include #include namespace wvdrm { // Widevine keybox. struct BinaryKeybox { // 128 bytes total. uint8_t mDeviceId[32]; // C character string identifying the device. Null terminated. uint8_t mKey[16]; // 128 bit AES key assigned to device. Generated by Widevine. uint8_t mData[72]; // Key Data. Encrypted data. uint8_t mMagic[4]; // Constant code used to recognize a valid keybox "kbox" = 0x6b626f78. uint8_t mCrc[4]; // The CRC checksum of the first 124 bytes of the keybox. }; struct OEMCrypto_KeyControl { uint8_t mVerification[4]; // Known pattern to verify decryption is // successful = ‘kctl’ uint32_t mDuration; // Maximum number of seconds during which the key // can be used after being set. Interpret 0 as // unlimited. (Network Byte Order) uint32_t mNonce; uint32_t mControl; // Bit field. (Network Byte Order) // bit 4: data path type: 0 normal, 1 = secure only. // bit 3: nonce enabled. 0 = ignore, 1 = requre nonce. // bit 2: HDCP: 0 = not required, 1 = required. // bit 1:0 CGMS control: 0 = copy freely, 2= copy once. 3= copy never. }; enum KeyType { SIGNING = 1, CONTENT_ANY = 2, CONTENT_AUDIO = 3, CONTENT_VIDEO = 4 }; struct ControlledKey { android::Vector mKeyId; OEMCrypto_KeyControl mControl; uint8_t mKeyData[16]; AES_KEY mKey; }; class MockSession : public android::RefBase { public: OEMCrypto_SESSION mId; android::Vector mKeys; ControlledKey *mCurrentKey; bool mNoKeyLoaded; ControlledKey mClearKey; // Stores a single key, for clear key demo. uint8_t mMacKey[32]; uint8_t mEncryptKey[16]; uint32_t mNonce; MockSession(OEMCrypto_SESSION id); ~MockSession(); OEMCryptoResult generateDerivedKeys(const uint8_t *mac_key_context, uint32_t mac_key_context_length, const uint8_t *enc_key_context, uint32_t enc_key_context_length); OEMCryptoResult generateNonce(uint32_t* nonce); OEMCryptoResult generateSignature(const uint8_t* message, size_t message_length, uint8_t* signature, size_t* signature_length); OEMCryptoResult loadKeys(const uint8_t* message, size_t message_length, const uint8_t* signature, size_t signature_length, const uint8_t* enc_mac_key_iv, const uint8_t* enc_mac_key, size_t num_keys, const OEMCrypto_KeyObject* key_array); OEMCryptoResult refreshKeys(const uint8_t* message, size_t message_length, const uint8_t* signature, size_t signature_length, size_t num_keys, const OEMCrypto_KeyRefreshObject* key_array); OEMCryptoResult selectKey(const uint8_t* key_id, size_t key_id_length); OEMCryptoResult decryptCTR(const uint8_t *data_addr, size_t data_length, bool is_encrypted, const uint8_t *iv, size_t offset, const OEMCrypto_DestBufferDesc* out_buffer); DISALLOW_EVIL_CONSTRUCTORS(MockSession); }; class MockOEMCrypto : public android::RefBase { public: static MockOEMCrypto *sSingleton; bool mInitialized; BinaryKeybox mKeybox; OEMCrypto_SESSION mMaxId; android::KeyedVector > mSessions; android::Mutex mSessionListMutex; // This locks list access only, not the items in the list. // TODO: max sessions. // TODO max keys. bool mClearKeys; MockOEMCrypto(BinaryKeybox *keybox = NULL); virtual OEMCryptoResult initialize(void); virtual OEMCryptoResult terminate(void); virtual OEMCryptoResult openSession(OEMCrypto_SESSION *session); virtual OEMCryptoResult closeSession(OEMCrypto_SESSION session); virtual MockSession *findSession(OEMCrypto_SESSION id); virtual OEMCryptoResult installKeybox(uint8_t *keybox, size_t keyBoxLength); virtual OEMCryptoResult isKeyboxValid(void); virtual OEMCryptoResult getDeviceID(uint8_t* deviceID, size_t* idLength); virtual OEMCryptoResult getKeyData(uint8_t* keyData, size_t* keyDataLength); virtual ~MockOEMCrypto(); DISALLOW_EVIL_CONSTRUCTORS(MockOEMCrypto); }; } #endif // _WV_MOCK_OEMCRYPTO_H_