In order to match the other implementations of CDM, we are going to replace the android OEMCrypto mockup with the one in the cdm repository. This would be disruptive to the clear key library because it relies on the current implementation of the mockup. In order to prevent that, I am moving the current mockup into the same directory as the clear key library. Then, we can put the new mockup under the directory libwvdrmengine. This mockup will then be deleted when the clear key library is deleted. Change-Id: I89ee23f249dacd18241ae5ca499329e620bf5a2c
147 lines
5.5 KiB
C++
147 lines
5.5 KiB
C++
/*********************************************************************
|
||
* 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 <openssl/aes.h>
|
||
#include <stdint.h>
|
||
#include <utils/KeyedVector.h>
|
||
#include <utils/Mutex.h>
|
||
#include <utils/RefBase.h>
|
||
#include <utils/SortedVector.h>
|
||
#include <utils/String8.h>
|
||
#include <utils/Vector.h>
|
||
#include <media/stagefright/foundation/ABase.h>
|
||
|
||
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<uint8_t> mKeyId;
|
||
OEMCrypto_KeyControl mControl;
|
||
uint8_t mKeyData[16];
|
||
AES_KEY mKey;
|
||
};
|
||
|
||
class MockSession : public android::RefBase {
|
||
public:
|
||
OEMCrypto_SESSION mId;
|
||
android::Vector<ControlledKey> 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<OEMCrypto_SESSION, android::sp<MockSession> > 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_
|