Add DecryptCTR to OEMCrypto Mock

This is a software only implementation of the OEMCrypto library for
testing the rest of the DRM code.  It currently implements the
OEMCrypto_DecrtyptCTR function using a clear key.

I've included the license request code so the rest of the group can
play with it, but I have only tested part of it.

This patch also has some makefiles and an integration testing.  You
should be able to generate the shared library libclearkeydrmengine.so with
cd vendor/widevine/libclearkeydrmengine; mm
You can create some unit test and integration test programs from the
directories:
vendor/widevine/libwvdrmengine/oemcrypto/test
vendor/widevine/libclearkeydrmengine/test
vendor/widevine/libclearkeydrmengine/inttest
vendor/widevine/libclearkeydrmengine/crypto/test

This change also addresses some comments about comments in OEMCryptoDASH.h
which were made in https://googleplex-android-review.googlesource.com/257323

Change-Id: Id6899b9f8d2f09e09be2ea493baa83a6b929073b
This commit is contained in:
Fred Gylys-Colwell
2012-12-14 19:03:25 -08:00
committed by Jeff Tinker
parent 04bfbb0198
commit fede3bffdd
26 changed files with 1561 additions and 1492 deletions

View File

@@ -9,14 +9,138 @@
#ifndef WV_MOCK_OEMCRYPTO_H_
#define WV_MOCK_OEMCRYPTO_H_
#ifdef __cplusplus
extern "C" {
#endif
#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>
extern void initializeMockOEMCrypto();
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);
};
#ifdef __cplusplus
}
#endif
#endif // _WV_MOCK_OEMCRYPTO_H_