Merge "Update unit tests for v15.2" into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
2f79fe2773
@@ -182,6 +182,14 @@ time_t CryptoEngine::RollbackCorrectedOfflineTime() {
|
|||||||
return current_time;
|
return current_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CryptoEngine::NonceCollision(uint32_t nonce) {
|
||||||
|
for (const auto & session_pair : sessions_) {
|
||||||
|
const SessionContext* session = session_pair.second;
|
||||||
|
if (session->NonceCollision(nonce)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
OEMCrypto_HDCP_Capability CryptoEngine::config_current_hdcp_capability() {
|
OEMCrypto_HDCP_Capability CryptoEngine::config_current_hdcp_capability() {
|
||||||
return config_local_display_only() ? HDCP_NO_DIGITAL_OUTPUT : HDCP_V1;
|
return config_local_display_only() ? HDCP_NO_DIGITAL_OUTPUT : HDCP_V1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,6 +91,10 @@ class CryptoEngine {
|
|||||||
|
|
||||||
time_t RollbackCorrectedOfflineTime();
|
time_t RollbackCorrectedOfflineTime();
|
||||||
|
|
||||||
|
// Verify that this nonce does not collide with another nonce in any session's
|
||||||
|
// nonce table.
|
||||||
|
virtual bool NonceCollision(uint32_t nonce);
|
||||||
|
|
||||||
// Returns the HDCP version currently in use.
|
// Returns the HDCP version currently in use.
|
||||||
virtual OEMCrypto_HDCP_Capability config_current_hdcp_capability();
|
virtual OEMCrypto_HDCP_Capability config_current_hdcp_capability();
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,13 @@ bool NonceTable::CheckNonce(uint32_t nonce) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NonceTable::NonceCollision(uint32_t nonce) const {
|
||||||
|
for (int i = 0; i < kTableSize; ++i) {
|
||||||
|
if (nonce == nonces_[i]) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void NonceTable::Flush() {
|
void NonceTable::Flush() {
|
||||||
for (int i = 0; i < kTableSize; ++i) {
|
for (int i = 0; i < kTableSize; ++i) {
|
||||||
if (kNTStateFlushPending == state_[i]) {
|
if (kNTStateFlushPending == state_[i]) {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace wvoec_ref {
|
|||||||
|
|
||||||
class NonceTable {
|
class NonceTable {
|
||||||
public:
|
public:
|
||||||
static const int kTableSize = 16;
|
static const int kTableSize = 4;
|
||||||
NonceTable() {
|
NonceTable() {
|
||||||
for (int i = 0; i < kTableSize; ++i) {
|
for (int i = 0; i < kTableSize; ++i) {
|
||||||
state_[i] = kNTStateInvalid;
|
state_[i] = kNTStateInvalid;
|
||||||
@@ -22,6 +22,8 @@ class NonceTable {
|
|||||||
~NonceTable() {}
|
~NonceTable() {}
|
||||||
void AddNonce(uint32_t nonce);
|
void AddNonce(uint32_t nonce);
|
||||||
bool CheckNonce(uint32_t nonce);
|
bool CheckNonce(uint32_t nonce);
|
||||||
|
// Verify that the nonce is not the same as any in this table.
|
||||||
|
bool NonceCollision(uint32_t nonce) const;
|
||||||
void Flush();
|
void Flush();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -189,13 +189,15 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
|
|||||||
last_nonce_time = now;
|
last_nonce_time = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t nonce_value;
|
uint32_t nonce_value = 0;
|
||||||
uint8_t* nonce_string = reinterpret_cast<uint8_t*>(&nonce_value);
|
uint8_t* nonce_string = reinterpret_cast<uint8_t*>(&nonce_value);
|
||||||
|
|
||||||
// Generate 4 bytes of random data
|
while (nonce_value == 0 || crypto_engine->NonceCollision(nonce_value)) {
|
||||||
if (!RAND_bytes(nonce_string, 4)) {
|
// Generate 4 bytes of random data
|
||||||
LOGE("[OEMCrypto_GenerateNonce(): Random bytes failure]");
|
if (!RAND_bytes(nonce_string, 4)) {
|
||||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
LOGE("[OEMCrypto_GenerateNonce(): Random bytes failure]");
|
||||||
|
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
session_ctx->AddNonce(nonce_value);
|
session_ctx->AddNonce(nonce_value);
|
||||||
*nonce = nonce_value;
|
*nonce = nonce_value;
|
||||||
@@ -281,9 +283,8 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadKeys(
|
|||||||
!RangeCheck(message_length, enc_mac_keys, true) ||
|
!RangeCheck(message_length, enc_mac_keys, true) ||
|
||||||
!RangeCheck(message_length, pst, true) ||
|
!RangeCheck(message_length, pst, true) ||
|
||||||
!RangeCheck(message_length, srm_restriction_data, true)) {
|
!RangeCheck(message_length, srm_restriction_data, true)) {
|
||||||
LOGE(
|
LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT - "
|
||||||
"[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT - range "
|
"range check.]");
|
||||||
"check.]");
|
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,13 +294,25 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadKeys(
|
|||||||
!RangeCheck(message_length, key_array[i].key_data_iv, false) ||
|
!RangeCheck(message_length, key_array[i].key_data_iv, false) ||
|
||||||
!RangeCheck(message_length, key_array[i].key_control, false) ||
|
!RangeCheck(message_length, key_array[i].key_control, false) ||
|
||||||
!RangeCheck(message_length, key_array[i].key_control_iv, false)) {
|
!RangeCheck(message_length, key_array[i].key_control_iv, false)) {
|
||||||
LOGE(
|
LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT - "
|
||||||
"[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT -range "
|
"range check %d]", i);
|
||||||
"check %d]",
|
|
||||||
i);
|
|
||||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (enc_mac_keys.offset >= wvoec::KEY_IV_SIZE && enc_mac_keys.length > 0) {
|
||||||
|
if (enc_mac_keys_iv.offset + wvoec::KEY_IV_SIZE == enc_mac_keys.offset) {
|
||||||
|
LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT - "
|
||||||
|
"range check iv]");
|
||||||
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
|
} else {
|
||||||
|
if (memcmp(message + enc_mac_keys.offset - wvoec::KEY_IV_SIZE,
|
||||||
|
message + enc_mac_keys_iv.offset, wvoec::KEY_IV_SIZE) == 0) {
|
||||||
|
LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT - "
|
||||||
|
"suspicious iv]");
|
||||||
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return session_ctx->LoadKeys(message, message_length, signature,
|
return session_ctx->LoadKeys(message, message_length, signature,
|
||||||
signature_length, enc_mac_keys_iv, enc_mac_keys,
|
signature_length, enc_mac_keys_iv, enc_mac_keys,
|
||||||
num_keys, key_array, pst, srm_restriction_data,
|
num_keys, key_array, pst, srm_restriction_data,
|
||||||
|
|||||||
@@ -173,6 +173,10 @@ class SessionContext {
|
|||||||
|
|
||||||
void AddNonce(uint32_t nonce);
|
void AddNonce(uint32_t nonce);
|
||||||
bool CheckNonce(uint32_t nonce);
|
bool CheckNonce(uint32_t nonce);
|
||||||
|
// Verify that the nonce does not match any in this session's nonce table.
|
||||||
|
bool NonceCollision(uint32_t nonce) const {
|
||||||
|
return nonce_table_.NonceCollision(nonce);
|
||||||
|
}
|
||||||
void FlushNonces();
|
void FlushNonces();
|
||||||
|
|
||||||
virtual OEMCryptoResult CreateNewUsageEntry(uint32_t* usage_entry_number);
|
virtual OEMCryptoResult CreateNewUsageEntry(uint32_t* usage_entry_number);
|
||||||
|
|||||||
@@ -539,6 +539,7 @@ void Session::FillSimpleMessage(uint32_t duration, uint32_t control,
|
|||||||
uint32_t nonce, const std::string& pst) {
|
uint32_t nonce, const std::string& pst) {
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
1, GetRandBytes(license_.mac_key_iv, sizeof(license_.mac_key_iv)));
|
1, GetRandBytes(license_.mac_key_iv, sizeof(license_.mac_key_iv)));
|
||||||
|
memset(license_.padding, 0, sizeof(license_.padding));
|
||||||
EXPECT_EQ(1, GetRandBytes(license_.mac_keys, sizeof(license_.mac_keys)));
|
EXPECT_EQ(1, GetRandBytes(license_.mac_keys, sizeof(license_.mac_keys)));
|
||||||
for (unsigned int i = 0; i < num_keys_; i++) {
|
for (unsigned int i = 0; i < num_keys_; i++) {
|
||||||
memset(license_.keys[i].key_id, 0, kTestKeyIdMaxLength);
|
memset(license_.keys[i].key_id, 0, kTestKeyIdMaxLength);
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ typedef struct {
|
|||||||
struct MessageData {
|
struct MessageData {
|
||||||
MessageKeyData keys[kMaxNumKeys];
|
MessageKeyData keys[kMaxNumKeys];
|
||||||
uint8_t mac_key_iv[KEY_IV_SIZE];
|
uint8_t mac_key_iv[KEY_IV_SIZE];
|
||||||
|
uint8_t padding[KEY_IV_SIZE];
|
||||||
uint8_t mac_keys[2 * MAC_KEY_SIZE];
|
uint8_t mac_keys[2 * MAC_KEY_SIZE];
|
||||||
uint8_t pst[kMaxPSTLength];
|
uint8_t pst[kMaxPSTLength];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1215,6 +1215,27 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange7) {
|
|||||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The IV should not be identical to the data right before the encrypted mac
|
||||||
|
// keys.
|
||||||
|
TEST_F(OEMCryptoSessionTests, LoadKeyWithSuspiciousIV) {
|
||||||
|
Session s;
|
||||||
|
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||||
|
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||||
|
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(0, 0, 0));
|
||||||
|
// This is suspicious: the data right before the mac keys is identical to the
|
||||||
|
// iv.
|
||||||
|
memcpy(s.license().padding, s.license().mac_key_iv,
|
||||||
|
sizeof(s.license().padding));
|
||||||
|
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||||
|
|
||||||
|
OEMCryptoResult sts = OEMCrypto_LoadKeys(
|
||||||
|
s.session_id(), s.message_ptr(), s.message_size(), s.signature().data(),
|
||||||
|
s.signature().size(), s.enc_mac_keys_iv_substr(), s.enc_mac_keys_substr(),
|
||||||
|
s.num_keys(), s.key_array(), GetSubstring(), GetSubstring(),
|
||||||
|
OEMCrypto_ContentLicense);
|
||||||
|
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||||
|
}
|
||||||
|
|
||||||
// Test that LoadKeys fails when a key is loaded with no key control block.
|
// Test that LoadKeys fails when a key is loaded with no key control block.
|
||||||
TEST_F(OEMCryptoSessionTests, LoadKeyWithNullKeyControl) {
|
TEST_F(OEMCryptoSessionTests, LoadKeyWithNullKeyControl) {
|
||||||
Session s;
|
Session s;
|
||||||
|
|||||||
Reference in New Issue
Block a user