Support Offline Licenses

Bug: 8621588

Merge of the following CLs from the Widevine CDM repository:

https://widevine-internal-review.googlesource.com/#/c/5602/
https://widevine-internal-review.googlesource.com/#/c/5431/
https://widevine-internal-review.googlesource.com/#/c/5660/

Change-Id: If37940e2535e1a1eca95e4394d8cf9bf689e9c3a
This commit is contained in:
Jeff Tinker
2013-05-15 19:23:36 -07:00
parent 898d870126
commit 1b295f4c81
30 changed files with 1647 additions and 471 deletions

View File

@@ -323,8 +323,8 @@ bool SessionContext::ValidateMessage(const uint8_t* given_message,
}
bool SessionContext::ParseKeyControl(
const std::vector<uint8_t>& key_control_string,
KeyControlBlock& key_control_block) {
const std::vector<uint8_t>& key_control_string,
KeyControlBlock& key_control_block) {
key_control_block.Invalidate();
@@ -337,15 +337,6 @@ bool SessionContext::ParseKeyControl(
return false;
}
if (!key_control_block.Validate()) {
LOGE("KCB: BAD Signature");
return false;
}
if (!CheckNonce(key_control_block.nonce())) {
LOGE("KCB: BAD Nonce");
return false;
}
LOGD("KCB:");
LOGD(" valid: %d", key_control_block.valid());
LOGD(" duration: %d", key_control_block.duration());
@@ -375,6 +366,16 @@ bool SessionContext::ParseKeyControl(
const char* cgms_values[4] = {"free", "BAD", "once", "never"};
LOGD(" CGMS = %s", cgms_values[cgms_bits]);
if (!key_control_block.Validate()) {
LOGE("KCB: BAD Signature");
return false;
}
if ((key_control_block.control_bits() & kControlNonceEnabled)
&& (!CheckNonce(key_control_block.nonce()))) {
LOGE("KCB: BAD Nonce");
return false;
}
return true;
}

View File

@@ -1,175 +0,0 @@
// Copyright 2013 Google Inc. All Rights Reserved.
//
// OEMCrypto unit tests
//
#include <gtest/gtest.h>
#include <map>
#include <stdint.h>
#include <string>
#include <sys/types.h>
#include "OEMCryptoCENC.h"
#include "string_conversions.h"
#include "wv_cdm_constants.h"
#include "wv_keybox.h"
using namespace std;
namespace wvoec {
static wvoec_mock::WidevineKeybox kValidKeybox02 = {
// Sample keybox used for test vectors
{
// deviceID
0x54, 0x65, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x30, // TestKey02
0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
}, {
// key
0x76, 0x5d, 0xce, 0x01, 0x04, 0x89, 0xb3, 0xd0,
0xdf, 0xce, 0x54, 0x8a, 0x49, 0xda, 0xdc, 0xb6,
}, {
// data
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x19,
0x92, 0x27, 0x0b, 0x1f, 0x1a, 0xd5, 0xc6, 0x93,
0x19, 0x3f, 0xaa, 0x74, 0x1f, 0xdd, 0x5f, 0xb4,
0xe9, 0x40, 0x2f, 0x34, 0xa4, 0x92, 0xf4, 0xae,
0x9a, 0x52, 0x39, 0xbc, 0xb7, 0x24, 0x38, 0x13,
0xab, 0xf4, 0x92, 0x96, 0xc4, 0x81, 0x60, 0x33,
0xd8, 0xb8, 0x09, 0xc7, 0x55, 0x0e, 0x12, 0xfa,
0xa8, 0x98, 0x62, 0x8a, 0xec, 0xea, 0x74, 0x8a,
0x4b, 0xfa, 0x5a, 0x9e, 0xb6, 0x49, 0x0d, 0x80,
}, {
// magic
0x6b, 0x62, 0x6f, 0x78,
}, {
// Crc
0x2a, 0x3b, 0x3e, 0xe4,
}
};
static wvoec_mock::WidevineKeybox kValidKeybox03 = {
// Sample keybox used for test vectors
{
// deviceID
0x54, 0x65, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x30, // TestKey03
0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........
}, {
// key
0x25, 0xe5, 0x2a, 0x02, 0x29, 0x68, 0x04, 0xa2,
0x92, 0xfd, 0x7c, 0x67, 0x0b, 0x67, 0x1f, 0x31,
}, {
// data
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x19,
0xf4, 0x0a, 0x0e, 0xa2, 0x0a, 0x71, 0xd5, 0x92,
0xfa, 0xa3, 0x25, 0xc6, 0x4b, 0x76, 0xf1, 0x64,
0xf4, 0x60, 0xa0, 0x30, 0x72, 0x23, 0xbe, 0x03,
0xcd, 0xde, 0x7a, 0x06, 0xd4, 0x01, 0xeb, 0xdc,
0xe0, 0x50, 0xc0, 0x53, 0x0a, 0x50, 0xb0, 0x37,
0xe5, 0x05, 0x25, 0x0e, 0xa4, 0xc8, 0x5a, 0xff,
0x46, 0x6e, 0xa5, 0x31, 0xf3, 0xdd, 0x94, 0xb7,
0xe0, 0xd3, 0xf9, 0x04, 0xb2, 0x54, 0xb1, 0x64,
}, {
// magic
0x6b, 0x62, 0x6f, 0x78,
}, {
// Crc
0xa1, 0x99, 0x5f, 0x46,
}
};
// Define CAN_INSTALL_KEYBOX if you are compiling with the reference
// implementation of OEMCrypto, or if your version of OEMCrypto supports
// OEMCrypto_InstallKeybox and OEMCrypto_WrapKeybox.
#if defined(CAN_INSTALL_KEYBOX)
// The Below tests are based on a specific keybox which is installed for testing.
class OEMCryptoKeyboxTest : public ::testing::Test {
protected:
virtual void SetUp() {
}
void install_keybox(wvoec_mock::WidevineKeybox& keybox, bool good) {
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize())
<< "OEMCrypto_Initialize failed.";
OEMCryptoResult sts;
uint8_t wrapped[sizeof(wvoec_mock::WidevineKeybox)];
size_t length = sizeof(wvoec_mock::WidevineKeybox);
sts = OEMCrypto_WrapKeybox(reinterpret_cast<uint8_t*>(&keybox),
sizeof(keybox),
wrapped,
&length,
NULL, 0);
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
sts = OEMCrypto_InstallKeybox(wrapped, sizeof(keybox));
if( good ) {
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
} else {
// Can return error now, or return error on IsKeyboxValid.
}
}
virtual void TearDown() {
OEMCrypto_Terminate();
}
public:
};
TEST_F(OEMCryptoKeyboxTest, DefaultKeybox) {
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_Initialize())
<< "OEMCrypto_Initialize failed.";
OEMCryptoResult sts;
sts = OEMCrypto_IsKeyboxValid();
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
}
TEST_F(OEMCryptoKeyboxTest, GoodKeybox) {
wvoec_mock::WidevineKeybox keybox = kValidKeybox02;
OEMCryptoResult sts;
install_keybox(keybox, true);
sts = OEMCrypto_IsKeyboxValid();
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
keybox = kValidKeybox03;
install_keybox(keybox, true);
sts = OEMCrypto_IsKeyboxValid();
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
}
TEST_F(OEMCryptoKeyboxTest, BadCRCKeybox) {
wvoec_mock::WidevineKeybox keybox = kValidKeybox02;
keybox.crc_[1] = 42;
OEMCryptoResult sts;
install_keybox(keybox, false);
sts = OEMCrypto_IsKeyboxValid();
ASSERT_EQ(OEMCrypto_ERROR_BAD_CRC, sts);
}
TEST_F(OEMCryptoKeyboxTest, BadMagicKeybox) {
wvoec_mock::WidevineKeybox keybox = kValidKeybox02;
keybox.magic_[1] = 42;
OEMCryptoResult sts;
install_keybox(keybox, false);
sts = OEMCrypto_IsKeyboxValid();
ASSERT_EQ(OEMCrypto_ERROR_BAD_MAGIC, sts);
}
TEST_F(OEMCryptoKeyboxTest, BadDataKeybox) {
wvoec_mock::WidevineKeybox keybox = kValidKeybox02;
keybox.data_[1] = 42;
OEMCryptoResult sts;
install_keybox(keybox, false);
sts = OEMCrypto_IsKeyboxValid();
ASSERT_EQ(OEMCrypto_ERROR_BAD_CRC, sts);
}
#endif // CAN_INSTALL_KEYBOX
} // namespace wvoec

View File

@@ -934,9 +934,9 @@ class Session {
enc_key_ = wvcdm::a2b_hex("D0BFC35DA9E33436E81C4229E78CB9F4");
}
void LoadTestKeys(uint32_t duration, uint32_t control) {
void LoadTestKeys(uint32_t duration, uint32_t control, uint32_t nonce) {
MessageData data;
FillSimpleMessage(&data, duration, control);
FillSimpleMessage(&data, duration, control, nonce);
MessageData encrypted;
EncryptMessage(data, &encrypted);
std::vector<uint8_t> signature;
@@ -1059,7 +1059,8 @@ class Session {
}
}
void FillSimpleMessage(MessageData* data, uint32_t duration, uint32_t control) {
void FillSimpleMessage(MessageData* data, uint32_t duration, uint32_t control,
uint32_t nonce) {
OEMCrypto_GetRandom(data->mac_key_iv, sizeof(data->mac_key_iv));
OEMCrypto_GetRandom(data->mac_keys, sizeof(data->mac_keys));
for (unsigned int i = 0; i < kNumKeys; i++) {
@@ -1072,7 +1073,7 @@ class Session {
sizeof(data->keys[i].control_iv));
memcpy(data->keys[i].control.verification, "kctl", 4);
data->keys[i].control.duration = htonl(duration);
data->keys[i].control.nonce = htonl(nonce_);
data->keys[i].control.nonce = htonl(nonce);
data->keys[i].control.control_bits = htonl(control);
}
// For the canned decryption content, The first key is:
@@ -1918,7 +1919,7 @@ TEST_F(DISABLED_TestKeybox, LoadKeyNoNonce) {
Session& s = createSession("ONE");
s.open();
s.GenerateDerivedKeys();
s.LoadTestKeys(kDuration, 0);
s.LoadTestKeys(kDuration, 0, 42);
s.close();
testTearDown();
}
@@ -1930,7 +1931,7 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithNonce) {
s.open();
s.GenerateDerivedKeys();
s.LoadTestKeys(0, wvoec_mock::kControlNonceEnabled);
s.LoadTestKeys(0, wvoec_mock::kControlNonceEnabled, s.get_nonce());
s.close();
testTearDown();
}
@@ -1946,7 +1947,7 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange1) {
s.GenerateDerivedKeys();
MessageData data;
s.FillSimpleMessage(&data, 0, 0);
s.FillSimpleMessage(&data, 0, 0, 0);
MessageData encrypted;
s.EncryptMessage(data, &encrypted);
@@ -1978,7 +1979,7 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange2) {
s.GenerateDerivedKeys();
MessageData data;
s.FillSimpleMessage(&data, 0, 0);
s.FillSimpleMessage(&data, 0, 0, 0);
MessageData encrypted;
s.EncryptMessage(data, &encrypted);
@@ -2011,7 +2012,7 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange3) {
s.GenerateDerivedKeys();
MessageData data;
s.FillSimpleMessage(&data, 0, 0);
s.FillSimpleMessage(&data, 0, 0, 0);
MessageData encrypted;
s.EncryptMessage(data, &encrypted);
@@ -2045,7 +2046,7 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange4) {
s.GenerateDerivedKeys();
MessageData data;
s.FillSimpleMessage(&data, 0, 0);
s.FillSimpleMessage(&data, 0, 0, 0);
MessageData encrypted;
s.EncryptMessage(data, &encrypted);
@@ -2079,7 +2080,7 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange5) {
s.GenerateDerivedKeys();
MessageData data;
s.FillSimpleMessage(&data, 0, 0);
s.FillSimpleMessage(&data, 0, 0, 0);
MessageData encrypted;
s.EncryptMessage(data, &encrypted);
@@ -2113,7 +2114,7 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange6) {
s.GenerateDerivedKeys();
MessageData data;
s.FillSimpleMessage(&data, 0, 0);
s.FillSimpleMessage(&data, 0, 0, 0);
MessageData encrypted;
s.EncryptMessage(data, &encrypted);
@@ -2147,7 +2148,7 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadRange7) {
s.GenerateDerivedKeys();
MessageData data;
s.FillSimpleMessage(&data, 0, 0);
s.FillSimpleMessage(&data, 0, 0, 0);
MessageData encrypted;
s.EncryptMessage(data, &encrypted);
@@ -2181,12 +2182,8 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadNonce) {
s.GenerateDerivedKeys();
MessageData data;
s.FillSimpleMessage(&data, 0, 0);
data.keys[0].control.control_bits = htonl(wvoec_mock::kControlNonceEnabled);
data.keys[1].control.control_bits = htonl(wvoec_mock::kControlNonceEnabled);
data.keys[2].control.control_bits = htonl(wvoec_mock::kControlNonceEnabled);
data.keys[1].control.nonce = 42; // This one is bad.
s.FillSimpleMessage(&data, 0, wvoec_mock::kControlNonceEnabled,
42); // bad nonce.
MessageData encrypted;
s.EncryptMessage(data, &encrypted);
std::vector<uint8_t> signature;
@@ -2218,7 +2215,7 @@ TEST_F(DISABLED_TestKeybox, LoadKeyWithBadVerification) {
s.GenerateDerivedKeys();
MessageData data;
s.FillSimpleMessage(&data, 0, 0);
s.FillSimpleMessage(&data, 0, 0, 0);
data.keys[1].control.verification[2] = 'Z';
MessageData encrypted;
@@ -2252,7 +2249,7 @@ TEST_F(DISABLED_TestKeybox, LoadKeysBadSignature) {
s.GenerateDerivedKeys();
MessageData data;
s.FillSimpleMessage(&data, 0, 0);
s.FillSimpleMessage(&data, 0, 0, 0);
MessageData encrypted;
s.EncryptMessage(data, &encrypted);
@@ -2287,7 +2284,7 @@ TEST_F(DISABLED_TestKeybox, LoadKeysWithNoDerivedKeys) {
// s.GenerateDerivedKeys();
MessageData data;
s.FillSimpleMessage(&data, 0, 0);
s.FillSimpleMessage(&data, 0, 0, 0);
MessageData encrypted;
s.EncryptMessage(data, &encrypted);
@@ -2321,11 +2318,10 @@ class DISABLED_RefreshKeyTest : public DISABLED_TestKeybox {
Session& s = createSession("ONE");
s.open();
s.GenerateDerivedKeys();
s.LoadTestKeys(kDuration, wvoec_mock::kControlNonceEnabled);
s.LoadTestKeys(kDuration, wvoec_mock::kControlNonceEnabled, s.get_nonce());
uint32_t nonce;
s.GenerateNonce(&nonce);
s.RefreshTestKeys(key_count, wvoec_mock::kControlNonceEnabled, nonce,
true);
s.RefreshTestKeys(key_count, wvoec_mock::kControlNonceEnabled, nonce, true);
s.close();
}
@@ -2333,7 +2329,7 @@ class DISABLED_RefreshKeyTest : public DISABLED_TestKeybox {
Session& s = createSession("ONE");
s.open();
s.GenerateDerivedKeys();
s.LoadTestKeys(kDuration, 0);
s.LoadTestKeys(kDuration, 0, 0);
uint32_t nonce;
s.GenerateNonce(&nonce);
s.RefreshTestKeys(key_count,0, 0, true);
@@ -2344,7 +2340,7 @@ class DISABLED_RefreshKeyTest : public DISABLED_TestKeybox {
Session& s = createSession("ONE");
s.open();
s.GenerateDerivedKeys();
s.LoadTestKeys(kDuration, wvoec_mock::kControlNonceEnabled);
s.LoadTestKeys(kDuration, wvoec_mock::kControlNonceEnabled, s.get_nonce());
uint32_t nonce = s.get_nonce();
s.RefreshTestKeys(key_count, wvoec_mock::kControlNonceEnabled, nonce,
false);
@@ -2354,7 +2350,7 @@ class DISABLED_RefreshKeyTest : public DISABLED_TestKeybox {
Session& s = createSession("ONE");
s.open();
s.GenerateDerivedKeys();
s.LoadTestKeys(kDuration, wvoec_mock::kControlNonceEnabled);
s.LoadTestKeys(kDuration, wvoec_mock::kControlNonceEnabled, s.get_nonce());
uint32_t nonce;
s.GenerateNonce(&nonce);
nonce = 42;
@@ -2395,7 +2391,7 @@ TEST_F(DISABLED_TestKeybox, Decrypt) {
s.open();
s.GenerateDerivedKeys();
s.LoadTestKeys(kDuration, 0);
s.LoadTestKeys(kDuration, 0, 0);
// Select the key (from FillSimpleMessage)
vector<uint8_t> keyId = wvcdm::a2b_hex("000000000000000000000000");
@@ -2452,7 +2448,7 @@ TEST_F(DISABLED_TestKeybox, DecryptZeroDuration) {
s.open();
s.GenerateDerivedKeys();
s.LoadTestKeys(0, 0);
s.LoadTestKeys(0, 0, 0);
// Select the key (from FillSimpleMessage)
vector<uint8_t> keyId = wvcdm::a2b_hex("000000000000000000000000");
@@ -2509,7 +2505,7 @@ TEST_F(DISABLED_TestKeybox, DecryptWithOffset) {
s.open();
s.GenerateDerivedKeys();
s.LoadTestKeys(kDuration, 0);
s.LoadTestKeys(kDuration, 0, 0);
// Select the key (from FillSimpleMessage)
vector<uint8_t> keyId = wvcdm::a2b_hex("000000000000000000000000");
@@ -2568,7 +2564,7 @@ TEST_F(DISABLED_TestKeybox, DecryptUnencrypted) {
s.open();
s.GenerateDerivedKeys();
s.LoadTestKeys(kDuration, 0);
s.LoadTestKeys(kDuration, 0, 0);
// Select the key (from FillSimpleMessage)
vector<uint8_t> keyId = wvcdm::a2b_hex("000000000000000000000000");
@@ -2658,7 +2654,7 @@ TEST_F(DISABLED_TestKeybox, DecryptSecureToClear) {
s.open();
s.GenerateDerivedKeys();
s.LoadTestKeys(kDuration, wvoec_mock::kControlObserveDataPath
| wvoec_mock::kControlDataPathSecure);
| wvoec_mock::kControlDataPathSecure, 0);
// Select the key (from FillSimpleMessage)
vector<uint8_t> keyId = wvcdm::a2b_hex("000000000000000000000000");
@@ -2714,7 +2710,7 @@ TEST_F(DISABLED_TestKeybox, KeyDuration) {
Session& s = createSession("ONE");
s.open();
s.GenerateDerivedKeys();
s.LoadTestKeys(kDuration, wvoec_mock::kControlNonceEnabled);
s.LoadTestKeys(kDuration, wvoec_mock::kControlNonceEnabled, s.get_nonce());
// Select the key (from FillSimpleMessage)
vector<uint8_t> keyId = wvcdm::a2b_hex("000000000000000000000000");
@@ -3168,7 +3164,7 @@ TEST_F(DISABLED_TestKeybox, CertificateDecrypt) {
s.open();
s.InstallRSASessionTestKey(wrapped_rsa_key);
s.LoadTestKeys(kDuration, 0);
s.LoadTestKeys(kDuration, 0, 0);
// Select the key (from FillSimpleMessage)
vector<uint8_t> keyId = wvcdm::a2b_hex("000000000000000000000000");
@@ -3228,7 +3224,7 @@ class DISABLED_GenericDRMTest : public DISABLED_TestKeybox {
void MakeFourKeys(Session* s) {
s->FillSimpleMessage(&message_data_, kDuration, 0);
s->FillSimpleMessage(&message_data_, kDuration, 0, 0);
message_data_.keys[0].control.control_bits = htonl(wvoec_mock::kControlAllowEncrypt);
message_data_.keys[1].control.control_bits = htonl(wvoec_mock::kControlAllowDecrypt);
message_data_.keys[2].control.control_bits = htonl(wvoec_mock::kControlAllowSign);