Haystack and Obfuscated OEMCrypto Level 3

This CL contains working versions of the haystack tools and the
OEMCrypto Level 3 library for android ARM, MIPS and x86.

The version number of the level 3 library is:
android/level3/arm/libwvlevel3.a  Level3 Library Nov  4 2013 18:39:06
android/level3/mips/libwvlevel3.a Level3 Library Nov  4 2013 18:42:29
android/level3/x86/libwvlevel3.a  Level3 Library Nov  4 2013 18:41:07

bug: 9374954 MediaDrm haystack based L3 code hardening implementation.
Change-Id: Ifef13900a11e83e4257723d3c6fc7107550882a8
This commit is contained in:
Fred Gylys-Colwell
2013-10-30 11:55:30 -07:00
parent 49e593d127
commit becb1bf0be
10 changed files with 51 additions and 33 deletions

View File

@@ -31,9 +31,17 @@ using namespace std;
namespace {
const size_t kNumKeys = 4;
const size_t kDuration = 2;
const size_t kLongDuration = 5;
const size_t kBufferMaxLength = 256;
#if defined(TEST_SPEED_MULTIPLIER) // Can slow test time limits when
// debugging is slowing everything.
const int kSpeedMultiplier = TEST_SPEED_MULTIPLIER1;
#else
const int kSpeedMultiplier = 1;
#endif
const int kShortSleep = 1 * kSpeedMultiplier;
const int kLongSleep = 2 * kSpeedMultiplier;
const uint32_t kDuration = 2 * kSpeedMultiplier;
const uint32_t kLongDuration = 5 * kSpeedMultiplier;
}
namespace wvoec {
@@ -320,7 +328,7 @@ static const uint8_t kTestPKCS1RSAPrivateKey2_2048[] = {
0x39, 0x28, 0x33, 0xe0, 0xdb, 0x03 };
// 2048 bit RSA key in PKCS#8 PrivateKeyInfo
static const char kTestRSAPKCS8PrivateKeyInfo2_2048[] = {
static const uint8_t kTestRSAPKCS8PrivateKeyInfo2_2048[] = {
0x30, 0x82, 0x04, 0xbc, 0x02, 0x01, 0x00, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
@@ -662,7 +670,7 @@ static const uint8_t kTestPKCS1RSAPrivateKey3_2048[] = {
0x21, 0xdc, 0x86, 0x17, 0x6e, 0xc8, 0xee, 0x24 };
// 2048 bit RSA key in PKCS#8 PrivateKeyInfo
static const char kTestRSAPKCS8PrivateKeyInfo3_2048[] = {
static const uint8_t kTestRSAPKCS8PrivateKeyInfo3_2048[] = {
0x30, 0x82, 0x04, 0xbe, 0x02, 0x01, 0x00, 0x30,
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
@@ -1014,7 +1022,7 @@ class Session {
ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer,
unencryptedData.size()));
sleep(1); // Should still be valid key.
sleep(kShortSleep); // Should still be valid key.
memset(outputBuffer, 0, sizeof(outputBuffer));
destBuffer.type = OEMCrypto_BufferType_Clear;
@@ -1030,7 +1038,7 @@ class Session {
ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer,
unencryptedData.size()));
sleep(3); // Should be after first expiration.
sleep(kShortSleep + kLongSleep); // Should be after first expiration.
memset(outputBuffer, 0, sizeof(outputBuffer));
destBuffer.type = OEMCrypto_BufferType_Clear;
@@ -1398,7 +1406,11 @@ class OEMCryptoClientTest : public ::testing::Test {
return !alive_;
}
void testSetUp() {
void testSetUp() { // TODO(fredgc): Wha...
// All these tests should be using Setup() and Teardown() so that you
// don't need to call them manually...
// https://code.google.com/p/googletest/wiki/Primer#Test_Fixtures:
// _Using_the_Same_Data_Configuration_for_Multiple_Te
init();
}
@@ -1828,7 +1840,7 @@ TEST_F(DISABLED_TestKeybox, DefaultKeybox) {
TEST_F(DISABLED_TestKeybox, BadCRCKeybox) {
testSetUp();
wvoec_mock::WidevineKeybox keybox = kValidKeybox02;
keybox.crc_[1] = 42;
keybox.crc_[1] ^= 42;
OEMCryptoResult sts;
InstallKeybox(keybox, false);
sts = OEMCrypto_IsKeyboxValid();
@@ -1838,7 +1850,7 @@ TEST_F(DISABLED_TestKeybox, BadCRCKeybox) {
TEST_F(DISABLED_TestKeybox, BadMagicKeybox) {
testSetUp();
wvoec_mock::WidevineKeybox keybox = kValidKeybox02;
keybox.magic_[1] = 42;
keybox.magic_[1] ^= 42;
OEMCryptoResult sts;
InstallKeybox(keybox, false);
sts = OEMCrypto_IsKeyboxValid();
@@ -1848,7 +1860,7 @@ TEST_F(DISABLED_TestKeybox, BadMagicKeybox) {
TEST_F(DISABLED_TestKeybox, BadDataKeybox) {
testSetUp();
wvoec_mock::WidevineKeybox keybox = kValidKeybox02;
keybox.data_[1] = 42;
keybox.data_[1] ^= 42;
OEMCryptoResult sts;
InstallKeybox(keybox, false);
sts = OEMCrypto_IsKeyboxValid();
@@ -2269,7 +2281,7 @@ TEST_F(DISABLED_TestKeybox, LoadKeysBadSignature) {
const uint8_t* message_ptr = reinterpret_cast<const uint8_t*>(&encrypted);
s.FillKeyArray(encrypted, key_array);
signature[0] = 42; // Bad signature.
signature[0] ^= 42; // Bad signature.
OEMCryptoResult sts = OEMCrypto_LoadKeys(
s.session_id(),
@@ -2363,7 +2375,7 @@ class DISABLED_RefreshKeyTest : public DISABLED_TestKeybox {
s.LoadTestKeys(kDuration, wvoec_mock::kControlNonceEnabled, s.get_nonce());
uint32_t nonce;
s.GenerateNonce(&nonce);
nonce = 42;
nonce ^= 42;
s.RefreshTestKeys(key_count, wvoec_mock::kControlNonceEnabled, nonce,
false);
s.close();
@@ -2764,7 +2776,7 @@ TEST_F(DISABLED_TestKeybox, KeyDuration) {
ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer,
unencryptedData.size()));
sleep(1); // Should still be valid key.
sleep(kShortSleep); // Should still be valid key.
memset(outputBuffer, 0, sizeof(outputBuffer));
destBuffer.type = OEMCrypto_BufferType_Clear;
@@ -2780,7 +2792,7 @@ TEST_F(DISABLED_TestKeybox, KeyDuration) {
ASSERT_EQ(0, memcmp(&unencryptedData[0], outputBuffer,
unencryptedData.size()));
sleep(2); // Should be expired key.
sleep(kLongSleep); // Should be expired key.
memset(outputBuffer, 0, sizeof(outputBuffer));
destBuffer.type = OEMCrypto_BufferType_Clear;
@@ -2990,7 +3002,7 @@ TEST_F(DISABLED_TestKeybox, CertificateProvisionBadSignature) {
&wrapped_key_length));
wrapped_key.clear();
wrapped_key.resize(wrapped_key_length);
signature[4] = 42; // bad signature.
signature[4] ^= 42; // bad signature.
ASSERT_NE(OEMCrypto_SUCCESS,
OEMCrypto_RewrapDeviceRSAKey(s.session_id(), message_ptr,
sizeof(encrypted), &signature[0],
@@ -3027,7 +3039,7 @@ TEST_F(DISABLED_TestKeybox, CertificateProvisionBadNonce) {
&wrapped_key_length));
wrapped_key.clear();
wrapped_key.resize(wrapped_key_length);
encrypted.nonce = 42; // Almost surely a bad nonce.
encrypted.nonce ^= 42; // Almost surely a bad nonce.
ASSERT_NE(OEMCrypto_SUCCESS,
OEMCrypto_RewrapDeviceRSAKey(s.session_id(), message_ptr,
sizeof(encrypted), &signature[0],
@@ -3064,7 +3076,7 @@ TEST_F(DISABLED_TestKeybox, CertificateProvisionBadRSAKey) {
&wrapped_key_length));
wrapped_key.clear();
wrapped_key.resize(wrapped_key_length);
encrypted.rsa_key[1] = 42; // Almost surely a bad key.
encrypted.rsa_key[1] ^= 42; // Almost surely a bad key.
ASSERT_NE(OEMCrypto_SUCCESS,
OEMCrypto_RewrapDeviceRSAKey(s.session_id(), message_ptr,
sizeof(encrypted), &signature[0],
@@ -3588,7 +3600,7 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationEncrypt) {
unsigned int key_index = 0;
uint8_t encrypted[kBufferSize];
sleep(1); // Should still be valid key.
sleep(kShortSleep); // Should still be valid key.
memset(encrypted, 0, kBufferSize);
sts = OEMCrypto_SelectKey(s.session_id(), message_data_.keys[key_index].key_id,
@@ -3599,8 +3611,7 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationEncrypt) {
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
ASSERT_EQ(0, memcmp(encrypted, expected_encrypted, kBufferSize));
sleep(2); // Should be expired key.
sleep(kLongSleep); // Should be expired key.
memset(encrypted, 0, kBufferSize);
sts = OEMCrypto_Generic_Encrypt(s.session_id(), clear_buffer_, kBufferSize, iv_,
@@ -3633,7 +3644,7 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationDecrypt) {
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
uint8_t resultant[kBufferSize];
sleep(1); // Should still be valid key.
sleep(kShortSleep); // Should still be valid key.
memset(resultant, 0, kBufferSize);
sts = OEMCrypto_Generic_Decrypt(s.session_id(), encrypted, kBufferSize, iv_,
@@ -3641,7 +3652,7 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationDecrypt) {
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
ASSERT_EQ(0, memcmp(clear_buffer_, resultant, kBufferSize));
sleep(2); // Should be expired key.
sleep(kLongSleep); // Should be expired key.
memset(resultant, 0, kBufferSize);
sts = OEMCrypto_Generic_Decrypt(s.session_id(), encrypted, kBufferSize, iv_,
@@ -3678,7 +3689,7 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationSign) {
kTestKeyIdLength);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
sleep(1); // Should still be valid key.
sleep(kShortSleep); // Should still be valid key.
memset(signature, 0, SHA256_DIGEST_LENGTH);
sts = OEMCrypto_Generic_Sign(s.session_id(), clear_buffer_, kBufferSize,
@@ -3687,7 +3698,7 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationSign) {
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
ASSERT_EQ(0, memcmp(signature, expected_signature, SHA256_DIGEST_LENGTH));
sleep(2); // Should be expired key.
sleep(kLongSleep); // Should be expired key.
memset(signature, 0, SHA256_DIGEST_LENGTH);
sts = OEMCrypto_Generic_Sign(s.session_id(), clear_buffer_, kBufferSize,
@@ -3722,14 +3733,14 @@ TEST_F(DISABLED_GenericDRMTest, KeyDurationVerify) {
kTestKeyIdLength);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
sleep(1); // Should still be valid key.
sleep(kShortSleep); // Should still be valid key.
sts = OEMCrypto_Generic_Verify(s.session_id(), clear_buffer_, kBufferSize,
OEMCrypto_HMAC_SHA256,signature,
SHA256_DIGEST_LENGTH);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
sleep(2); // Should be expired key.
sleep(kLongSleep); // Should be expired key.
sts = OEMCrypto_Generic_Verify(s.session_id(), clear_buffer_, kBufferSize,
OEMCrypto_HMAC_SHA256,signature,