Files
android/libwvdrmengine/oemcrypto/mock/OEMCryptoWrapper.cpp
Fred Gylys-Colwell fede3bffdd 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
2012-12-21 12:41:42 -08:00

240 lines
8.8 KiB
C++

/*********************************************************************
* OEMCryptoWrapper.cpp
*
* (c) Copyright 2011-2012 Google, Inc.
*
* OEMCryptoDASH fuctions wrapped around a Mock OEMCrypto object.
*********************************************************************/
#define LOG_TAG "WV.MockOEMCrypto"
#include <utils/Log.h>
#include <utils/String8.h>
#include "OEMCryptoDASH.h"
#include "MockOEMCrypto.h"
#include "openssl/rand.h"
using namespace android;
using namespace wvdrm;
extern "C"
OEMCryptoResult OEMCrypto_Initialize(void) {
if (MockOEMCrypto::sSingleton == NULL) MockOEMCrypto::sSingleton = new MockOEMCrypto();
return MockOEMCrypto::sSingleton->initialize();
}
extern "C"
OEMCryptoResult OEMCrypto_Terminate(void) {
if (!MockOEMCrypto::sSingleton) {
ALOGE( "[OEMCrypto_Terminate(): failed - not initialized, no engine]\n" );
return OEMCrypto_ERROR_TERMINATE_FAILED;
}
return MockOEMCrypto::sSingleton->terminate();
}
extern "C"
OEMCryptoResult OEMCrypto_OpenSession(OEMCrypto_SESSION *session) {
if (! MockOEMCrypto::sSingleton) {
ALOGE("OEMCrypto not initialized");
return OEMCrypto_ERROR_OPEN_SESSION_FAILED;
}
return MockOEMCrypto::sSingleton->openSession(session);
}
extern "C"
OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session) {
if (! MockOEMCrypto::sSingleton) {
ALOGE("OEMCrypto not initialized");
return OEMCrypto_ERROR_TERMINATE_FAILED;
}
return MockOEMCrypto::sSingleton->closeSession(session);
}
extern "C"
OEMCryptoResult OEMCrypto_GenerateDerivedKeys(OEMCrypto_SESSION session,
const uint8_t *mac_key_context,
uint32_t mac_key_context_length,
const uint8_t *enc_key_context,
uint32_t enc_key_context_length) {
if (! MockOEMCrypto::sSingleton) {
ALOGE("OEMCrypto not initialized");
return OEMCrypto_ERROR_INVALID_SESSION;
}
MockSession *s = MockOEMCrypto::sSingleton->findSession(session);
if (!s) {
ALOGE("OEMCrypto no session for id %d", session);
return OEMCrypto_ERROR_INVALID_SESSION;
}
return s->generateDerivedKeys(mac_key_context,mac_key_context_length,
enc_key_context, enc_key_context_length);
}
extern "C"
OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
uint32_t* nonce) {
if (! MockOEMCrypto::sSingleton) {
ALOGE("OEMCrypto not initialized");
return OEMCrypto_ERROR_INVALID_SESSION;
}
MockSession *s = MockOEMCrypto::sSingleton->findSession(session);
if (!s) {
ALOGE("OEMCrypto no session for id %d", session);
return OEMCrypto_ERROR_INVALID_SESSION;
}
return s->generateNonce(nonce);
}
extern "C"
OEMCryptoResult OEMCrypto_GenerateSignature(OEMCrypto_SESSION session,
const uint8_t* message,
size_t message_length,
uint8_t* signature,
size_t* signature_length) {
if (! MockOEMCrypto::sSingleton) {
ALOGE("OEMCrypto not initialized");
return OEMCrypto_ERROR_INVALID_SESSION;
}
MockSession *s = MockOEMCrypto::sSingleton->findSession(session);
if (!s) {
ALOGE("OEMCrypto no session for id %d", session);
return OEMCrypto_ERROR_INVALID_SESSION;
}
return s->generateSignature(message, message_length,
signature, signature_length);
}
extern "C"
OEMCryptoResult OEMCrypto_LoadKeys(OEMCrypto_SESSION session,
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) {
if (! MockOEMCrypto::sSingleton) {
ALOGE("OEMCrypto not initialized");
return OEMCrypto_ERROR_INVALID_SESSION;
}
MockSession *s = MockOEMCrypto::sSingleton->findSession(session);
if (!s) {
ALOGE("OEMCrypto no session for id %d", session);
return OEMCrypto_ERROR_INVALID_SESSION;
}
return s->loadKeys(message, message_length, signature, signature_length,
enc_mac_key_iv, enc_mac_key,
num_keys, key_array);
}
extern "C"
OEMCryptoResult
OEMCrypto_RefreshKeys(OEMCrypto_SESSION session,
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) {
if (! MockOEMCrypto::sSingleton) {
ALOGE("OEMCrypto not initialized");
return OEMCrypto_ERROR_INVALID_SESSION;
}
MockSession *s = MockOEMCrypto::sSingleton->findSession(session);
if (!s) {
ALOGE("OEMCrypto no session for id %d", session);
return OEMCrypto_ERROR_INVALID_SESSION;
}
return s->refreshKeys(message, message_length, signature,
signature_length, num_keys, key_array);
}
extern "C"
OEMCryptoResult OEMCrypto_SelectKey(const OEMCrypto_SESSION session,
const uint8_t* key_id,
size_t key_id_length) {
if (! MockOEMCrypto::sSingleton) {
ALOGE("OEMCrypto not initialized");
return OEMCrypto_ERROR_INVALID_SESSION;
}
MockSession *s = MockOEMCrypto::sSingleton->findSession(session);
if (!s) {
ALOGE("OEMCrypto no session for id %d", session);
return OEMCrypto_ERROR_INVALID_SESSION;
}
return s->selectKey(key_id, key_id_length);
}
extern "C"
OEMCryptoResult OEMCrypto_DecryptCTR(OEMCrypto_SESSION session,
const uint8_t *data_addr,
size_t data_length,
bool is_encrypted,
const uint8_t *iv,
size_t offset,
const OEMCrypto_DestBufferDesc* out_buffer) {
if (! MockOEMCrypto::sSingleton) {
ALOGE("OEMCrypto not initialized");
return OEMCrypto_ERROR_INVALID_SESSION;
}
MockSession *s = MockOEMCrypto::sSingleton->findSession(session);
if (!s) {
ALOGE("OEMCrypto no session for id %d", session);
return OEMCrypto_ERROR_INVALID_SESSION;
}
return s->decryptCTR(data_addr, data_length, is_encrypted,
iv, offset, out_buffer);
}
extern "C"
OEMCryptoResult OEMCrypto_InstallKeybox(uint8_t *keybox,
size_t keyBoxLength) {
if (!MockOEMCrypto::sSingleton) {
MockOEMCrypto::sSingleton = new MockOEMCrypto(NULL);
}
return MockOEMCrypto::sSingleton->installKeybox(keybox, keyBoxLength);
}
extern "C"
OEMCryptoResult OEMCrypto_IsKeyboxValid(void) {
if (!MockOEMCrypto::sSingleton) {
MockOEMCrypto::sSingleton = new MockOEMCrypto(NULL);
}
return MockOEMCrypto::sSingleton->isKeyboxValid();
}
extern "C"
OEMCryptoResult OEMCrypto_GetDeviceID(uint8_t* deviceID,
size_t *idLength) {
if (MockOEMCrypto::sSingleton == NULL) MockOEMCrypto::sSingleton = new MockOEMCrypto();
return MockOEMCrypto::sSingleton->getDeviceID(deviceID, idLength);
}
extern "C"
OEMCryptoResult OEMCrypto_GetKeyData(uint8_t* keyData,
size_t *keyDataLength) {
if (MockOEMCrypto::sSingleton == NULL) MockOEMCrypto::sSingleton = new MockOEMCrypto();
return MockOEMCrypto::sSingleton->getKeyData(keyData, keyDataLength);
}
extern "C"
OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData,
size_t dataLength) {
ALOGV("OEMCryptoResult OEMCrypto_GetRandom\n");
if (RAND_bytes(randomData, dataLength)) {
return OEMCrypto_SUCCESS;
} else {
return OEMCrypto_ERROR_RNG_FAILED;
}
}
extern "C"
OEMCryptoResult OEMCrypto_WrapKeybox(uint8_t *keybox,
size_t keyBoxLength,
uint8_t *wrappedKeybox,
size_t *wrappedKeyBoxLength,
uint8_t *transportKey,
size_t transportKeyLength) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}