Update unit tests for v15.2

Merge from Widevine repo of http://go/wvgerrit/77609

For v15.2 we require that nonces not collide across sessions and there are
restrictions placed on the mac key's IV in LoadKeys.

Test: ran unit tests on reference code

Bug: 131325434
Bug: 131326334

Change-Id: I1bb01c30d8c15d66d762c28b57d7700c44daa835
This commit is contained in:
Fred Gylys-Colwell
2019-04-29 14:40:57 -07:00
parent 3e5ade22f9
commit 96431e9c2d
9 changed files with 74 additions and 13 deletions

View File

@@ -182,6 +182,14 @@ time_t CryptoEngine::RollbackCorrectedOfflineTime() {
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() {
return config_local_display_only() ? HDCP_NO_DIGITAL_OUTPUT : HDCP_V1;
}

View File

@@ -91,6 +91,10 @@ class CryptoEngine {
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.
virtual OEMCrypto_HDCP_Capability config_current_hdcp_capability();

View File

@@ -58,6 +58,13 @@ bool NonceTable::CheckNonce(uint32_t nonce) {
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() {
for (int i = 0; i < kTableSize; ++i) {
if (kNTStateFlushPending == state_[i]) {

View File

@@ -13,7 +13,7 @@ namespace wvoec_ref {
class NonceTable {
public:
static const int kTableSize = 16;
static const int kTableSize = 4;
NonceTable() {
for (int i = 0; i < kTableSize; ++i) {
state_[i] = kNTStateInvalid;
@@ -22,6 +22,8 @@ class NonceTable {
~NonceTable() {}
void AddNonce(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();
private:

View File

@@ -189,13 +189,15 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
last_nonce_time = now;
}
uint32_t nonce_value;
uint32_t nonce_value = 0;
uint8_t* nonce_string = reinterpret_cast<uint8_t*>(&nonce_value);
// Generate 4 bytes of random data
if (!RAND_bytes(nonce_string, 4)) {
LOGE("[OEMCrypto_GenerateNonce(): Random bytes failure]");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
while (nonce_value == 0 || crypto_engine->NonceCollision(nonce_value)) {
// Generate 4 bytes of random data
if (!RAND_bytes(nonce_string, 4)) {
LOGE("[OEMCrypto_GenerateNonce(): Random bytes failure]");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
}
session_ctx->AddNonce(nonce_value);
*nonce = nonce_value;
@@ -281,9 +283,8 @@ OEMCRYPTO_API OEMCryptoResult OEMCrypto_LoadKeys(
!RangeCheck(message_length, enc_mac_keys, true) ||
!RangeCheck(message_length, pst, true) ||
!RangeCheck(message_length, srm_restriction_data, true)) {
LOGE(
"[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT - range "
"check.]");
LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT - "
"range check.]");
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_control, false) ||
!RangeCheck(message_length, key_array[i].key_control_iv, false)) {
LOGE(
"[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT -range "
"check %d]",
i);
LOGE("[OEMCrypto_LoadKeys(): OEMCrypto_ERROR_INVALID_CONTEXT - "
"range check %d]", i);
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,
signature_length, enc_mac_keys_iv, enc_mac_keys,
num_keys, key_array, pst, srm_restriction_data,

View File

@@ -173,6 +173,10 @@ class SessionContext {
void AddNonce(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();
virtual OEMCryptoResult CreateNewUsageEntry(uint32_t* usage_entry_number);