Merge Changes from CDM repository

This CL merges the following changes from the Widevine repository:

Avoid CdmSession reinitialization
https://widevine-internal-review.googlesource.com/#/c/10530/

Fix timer-related unit tests.
https://widevine-internal-review.googlesource.com/#/c/10510/

Correct return statement
bug: 15590802
https://widevine-internal-review.googlesource.com/#/c/10553/

Usage reporting fixes
bug/15388863
https://widevine-internal-review.googlesource.com/#/c/10460/

Make public methods virtual
https://widevine-internal-review.googlesource.com/#/c/10500/

Fix the SetTimer contract in the CDM.
https://widevine-internal-review.googlesource.com/#/c/10493/

Move inline CDM methods, add OVERRIDE.
https://widevine-internal-review.googlesource.com/#/c/10475/

Simplify storage APIs related cleanup.
https://widevine-internal-review.googlesource.com/#/c/10473/

Duration values are not correctly reported when queried
b/15592374
https://widevine-internal-review.googlesource.com/#/c/10437/

Propagate IsKeyValid() through ContentDecryptionModule.
https://widevine-internal-review.googlesource.com/#/c/10483/

Minor clean up in config_test_env.
https://widevine-internal-review.googlesource.com/#/c/10440/

General clean up.
https://widevine-internal-review.googlesource.com/#/c/10441/

Refactor HttpSocket and simplify UrlRequest interface.
https://widevine-internal-review.googlesource.com/#/c/10410/

Install good keybox at end of unit tests
b/15385981
https://widevine-internal-review.googlesource.com/#/c/10374/

Privacy crypto fixes
b/15475012
https://widevine-internal-review.googlesource.com/#/c/10383/

Incorporate header files to resolve build issued based on customers feedback.
https://widevine-internal-review.googlesource.com/#/c/10420/

Support unprovisioning
b/12247651
https://widevine-internal-review.googlesource.com/#/c/10356/

Correct usage of Host::Allocate and Cdm::Decrypt.
https://widevine-internal-review.googlesource.com/#/c/10378/

Fix logging bug, arguments in wrong order.
https://widevine-internal-review.googlesource.com/#/c/10380/

Rename types that look like constants.
https://widevine-internal-review.googlesource.com/#/c/10379/

Fix offline test failures
b/13909635
https://widevine-internal-review.googlesource.com/#/c/10348/

Add -DUNIT_TEST to the unit test makefile for Android
https://widevine-internal-review.googlesource.com/#/c/10375/

Refactor privacy-crypto and add dummy version.
https://widevine-internal-review.googlesource.com/#/c/10353/

Remove References to Apiary
https://widevine-internal-review.googlesource.com/#/c/9924/

Delete oldest entry in usage table when full
bug: 15184824
https://widevine-internal-review.googlesource.com/#/c/10295/

Port DeviceFiles to iOS.
https://widevine-internal-review.googlesource.com/#/c/10355/

Make testing functions in DeviceFiles private.
https://widevine-internal-review.googlesource.com/#/c/10354/

Add RSA encryption to haystack
https://widevine-internal-review.googlesource.com/#/c/10280/

Add string and vector includes to CDM header.
https://widevine-internal-review.googlesource.com/#/c/10352/

First version of oemcrypto logging
https://widevine-internal-review.googlesource.com/#/c/10252/

Update Names of Secure Stop Methods
bug: 11987015
https://widevine-internal-review.googlesource.com/#/c/10152/

Adjust timing on the Usage Table unit test
https://widevine-internal-review.googlesource.com/#/c/10307/

Fix all compiler warnings in CDM source release.
https://widevine-internal-review.googlesource.com/#/c/10293/

Fix memset bug: args in wrong order
https://widevine-internal-review.googlesource.com/#/c/10292/

Partial revert of 'Remove refs to test prov server, Level3 support...'
https://widevine-internal-review.googlesource.com/#/c/10281/

Pack structure OEMCrypto_PST_Report
https://widevine-internal-review.googlesource.com/#/c/10243/

Remove refs to test prov server, Level3 support; remove dead code
https://widevine-internal-review.googlesource.com/#/c/10220/

Partial revert of 'Document data strings; clean up license server parameters.'
https://widevine-internal-review.googlesource.com/#/c/10188/

Document data strings; clean up license server parameters.
https://widevine-internal-review.googlesource.com/#/c/10120/

Fix broken build after partner branch merge.
https://widevine-internal-review.googlesource.com/#/c/10181/

TODO Cleanup - core/src, core/include
https://widevine-internal-review.googlesource.com/#/c/9965/

TODO Cleanup - cdm, chromium, core/test.
https://widevine-internal-review.googlesource.com/#/c/9419/

Remove unneeded properties.
https://widevine-internal-review.googlesource.com/#/c/10162/

Change-Id: If2bb9d743a562a3875bebb91933c0aaadea286b2
This commit is contained in:
Fred Gylys-Colwell
2014-06-25 13:02:54 -07:00
parent 8a8feb747c
commit b5e8b87fed
66 changed files with 2927 additions and 1998 deletions

View File

@@ -11,6 +11,7 @@
#include "log.h"
#include "oemcrypto_key_mock.h"
#include "oemcrypto_logging.h"
#include "oemcrypto_usage_table_mock.h"
#include "openssl/aes.h"
#include "openssl/bio.h"
@@ -34,7 +35,7 @@ void ctr128_inc64(uint8_t* counter) {
uint32_t n = 16;
do {
if (++counter[--n] != 0) return;
} while (n>8);
} while (n > 8);
}
void dump_openssl_error() {
while (unsigned long err = ERR_get_error()) {
@@ -43,7 +44,7 @@ void dump_openssl_error() {
err, ERR_error_string(err, buffer));
}
}
}
} // namespace
namespace wvoec_mock {
@@ -76,7 +77,7 @@ void SessionKeyTable::Remove(const KeyId key_id) {
}
void SessionKeyTable::UpdateDuration(const KeyControlBlock& control) {
for(KeyMap::iterator it = keys_.begin(); it != keys_.end(); ++it) {
for (KeyMap::iterator it = keys_.begin(); it != keys_.end(); ++it) {
it->second->UpdateDuration(control);
}
}
@@ -157,17 +158,13 @@ bool SessionContext::DeriveKeys(const std::vector<uint8_t>& master_key,
return false;
}
#if 0 // Print Derived Keys to stdout.
std::cout << " mac_key_context = " << wvcdm::b2a_hex(mac_key_context)
<< std::endl;
std::cout << " enc_key_context = " << wvcdm::b2a_hex(enc_key_context)
<< std::endl;
std::cout << " mac_key_server = " << wvcdm::b2a_hex(mac_key_server)
<< std::endl;
std::cout << " mac_key_client = " << wvcdm::b2a_hex(mac_key_client)
<< std::endl;
std::cout << " enc_key = " << wvcdm::b2a_hex(enc_key) << std::endl;
#endif
if (LogCategoryEnabled(kLoggingDumpDerivedKeys)) {
LOGI((" mac_key_context = " + wvcdm::b2a_hex(mac_key_context)).c_str());
LOGI((" enc_key_context = " + wvcdm::b2a_hex(enc_key_context)).c_str());
LOGI((" mac_key_server = " + wvcdm::b2a_hex(mac_key_server)).c_str());
LOGI((" mac_key_client = " + wvcdm::b2a_hex(mac_key_client)).c_str());
LOGI((" enc_key = " + wvcdm::b2a_hex(enc_key)).c_str());
}
set_mac_key_server(mac_key_server);
set_mac_key_client(mac_key_client);
@@ -183,7 +180,7 @@ bool SessionContext::RSADeriveKeys(const std::vector<uint8_t>& enc_session_key,
return false;
}
if (enc_session_key.size() != static_cast<size_t>(RSA_size(rsa_key_))) {
LOGE("[RSADeriveKeys(): encrypted session key is wrong size:%zu, should be %d]",
LOGE("[RSADeriveKeys(): encrypted session key wrong size:%zu, expected %d]",
enc_session_key.size(), RSA_size(rsa_key_));
dump_openssl_error();
return false;
@@ -214,7 +211,6 @@ bool SessionContext::GenerateSignature(const uint8_t* message,
size_t message_length,
uint8_t* signature,
size_t* signature_length) {
if (message == NULL || message_length == 0 ||
signature == NULL || signature_length == 0) {
LOGE("[OEMCrypto_GenerateSignature(): OEMCrypto_ERROR_INVALID_CONTEXT]");
@@ -305,8 +301,8 @@ bool SessionContext::GenerateRSASignature(const uint8_t* message,
return false;
}
// Pad the message with PKCS1 padding, and then encrypt.
int status = RSA_private_encrypt(message_length, message, signature,
rsa_key_, RSA_PKCS1_PADDING);
size_t status = RSA_private_encrypt(message_length, message, signature,
rsa_key_, RSA_PKCS1_PADDING);
if (status != *signature_length) {
LOGE("[GeneratRSASignature(): error in RSA private encrypt. status=%d]", status);
dump_openssl_error();
@@ -323,7 +319,6 @@ bool SessionContext::ValidateMessage(const uint8_t* given_message,
size_t message_length,
const uint8_t* given_signature,
size_t signature_length) {
if (signature_length != SHA256_DIGEST_LENGTH) {
return false;
}
@@ -471,14 +466,14 @@ bool SessionContext::InstallKey(const KeyId& key_id,
return false;
}
#if 0 // Print content key to stdout.
std::cout << " InstallKey: key_id = "
<< wvcdm::b2a_hex(key_id) << std::endl;
std::cout << " InstallKey: content_key = "
<< wvcdm::b2a_hex(content_key) << std::endl;
std::cout << " InstallKey: key_control = "
<< wvcdm::b2a_hex(key_control_str) << std::endl;
#endif
if (LogCategoryEnabled(kLoggingDumpContentKeys)) {
LOGI((" InstallKey: key_id = " +
wvcdm::b2a_hex(key_id)).c_str());
LOGI((" InstallKey: content_key = " +
wvcdm::b2a_hex(content_key)).c_str());
LOGI((" InstallKey: key_control = " +
wvcdm::b2a_hex(key_control_str)).c_str());
}
// Key control must be supplied by license server
if (key_control.empty()) {
@@ -517,7 +512,7 @@ bool SessionContext::RefreshKey(const KeyId& key_id,
// Key control is not encrypted if key id is NULL
KeyControlBlock key_control_block(key_control);
if (!key_control_block.valid()) {
LOGD("Parse key control error.");
LOGE("Parse key control error.");
return false;
}
if ((key_control_block.control_bits() & kControlNonceEnabled) &&
@@ -533,12 +528,16 @@ bool SessionContext::RefreshKey(const KeyId& key_id,
Key* content_key = session_keys_.Find(key_id);
if (NULL == content_key) {
LOGD("Error: no matching content key.");
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
LOGD("Error: no matching content key.");
}
return false;
}
if (key_control.empty()) {
LOGD("Error: no key_control.");
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
LOGD("Error: no key_control.");
}
return false;
}
@@ -547,20 +546,28 @@ bool SessionContext::RefreshKey(const KeyId& key_id,
// Decrypt encrypted key control block
std::vector<uint8_t> control;
if (key_control_iv.empty()) {
LOGD("Key control block is NOT encrypted.");
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
LOGD("Key control block is NOT encrypted.");
}
control = key_control;
} else {
LOGD("Key control block is encrypted.");
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
LOGD("Key control block is encrypted.");
}
if (!DecryptMessage(content_key_value, key_control_iv, key_control,
&control)) {
LOGD("Error decrypting key control block.");
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
LOGD("Error decrypting key control block.");
}
return false;
}
}
KeyControlBlock key_control_block(control);
if (!key_control_block.valid()) {
LOGD("Parse key control error.");
if (LogCategoryEnabled(kLoggingDumpKeyControlBlocks)) {
LOGD("Parse key control error.");
}
return false;
}
if ((key_control_block.control_bits() & kControlNonceEnabled) &&
@@ -606,7 +613,6 @@ bool SessionContext::LoadRSAKey(uint8_t* pkcs8_rsa_key,
size_t message_length,
const uint8_t* signature,
size_t signature_length) {
// Validate message signature
if (!ValidateMessage(message, message_length, signature, signature_length)) {
LOGE("[LoadRSAKey(): Could not verify signature]");
@@ -627,7 +633,7 @@ bool SessionContext::LoadRSAKey(uint8_t* pkcs8_rsa_key,
rsa_key_length -= 8;
}
BIO *bio = BIO_new_mem_buf(pkcs8_rsa_key, rsa_key_length);
if( bio == NULL ) {
if ( bio == NULL ) {
LOGE("[LoadRSAKey(): Could not allocate bio buffer]");
return false;
}
@@ -663,7 +669,7 @@ bool SessionContext::LoadRSAKey(uint8_t* pkcs8_rsa_key,
return false;
}
switch (RSA_check_key(rsa_key_)) {
case 1: // valid.
case 1: // valid.
return true;
case 0: // not valid.
LOGE("[LoadRSAKey(): rsa key not valid]");
@@ -690,7 +696,7 @@ OEMCryptoResult SessionContext::Generic_Encrypt(const uint8_t* in_buffer,
const KeyControlBlock& control = current_content_key()->control();
// Set the AES key.
if (static_cast<int>(key.size()) != AES_BLOCK_SIZE) {
LOGE("[Generic_Encrypt(): CONTENT_KEY has wrong size: %d",key.size());
LOGE("[Generic_Encrypt(): CONTENT_KEY has wrong size: %d", key.size());
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!(control.control_bits() & kControlAllowEncrypt)) {
@@ -709,11 +715,11 @@ OEMCryptoResult SessionContext::Generic_Encrypt(const uint8_t* in_buffer,
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
}
if( algorithm != OEMCrypto_AES_CBC_128_NO_PADDING ) {
if ( algorithm != OEMCrypto_AES_CBC_128_NO_PADDING ) {
LOGE("[Generic_Encrypt(): algorithm bad.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if( buffer_length % AES_BLOCK_SIZE != 0 ) {
if ( buffer_length % AES_BLOCK_SIZE != 0 ) {
LOGE("[Generic_Encrypt(): buffers size bad.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
@@ -767,11 +773,11 @@ OEMCryptoResult SessionContext::Generic_Decrypt(const uint8_t* in_buffer,
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
}
if( algorithm != OEMCrypto_AES_CBC_128_NO_PADDING ) {
if ( algorithm != OEMCrypto_AES_CBC_128_NO_PADDING ) {
LOGE("[Generic_Decrypt(): bad algorithm.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if( buffer_length % AES_BLOCK_SIZE != 0 ) {
if ( buffer_length % AES_BLOCK_SIZE != 0 ) {
LOGE("[Generic_Decrypt(): bad buffer size.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
@@ -875,7 +881,7 @@ OEMCryptoResult SessionContext::Generic_Verify(const uint8_t* in_buffer,
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
}
if( algorithm != OEMCrypto_HMAC_SHA256 ) {
if ( algorithm != OEMCrypto_HMAC_SHA256 ) {
LOGE("[Generic_Verify(): bad algorithm.");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
@@ -896,7 +902,6 @@ OEMCryptoResult SessionContext::Generic_Verify(const uint8_t* in_buffer,
bool SessionContext::UpdateMacKeys(const std::vector<uint8_t>& enc_mac_keys,
const std::vector<uint8_t>& iv) {
// Decrypt mac key from enc_mac_key using device_keya
std::vector<uint8_t> mac_keys;
if (!DecryptMessage(encryption_key_, iv, enc_mac_keys, &mac_keys)) {
@@ -911,12 +916,14 @@ bool SessionContext::UpdateMacKeys(const std::vector<uint8_t>& enc_mac_keys,
bool SessionContext::SelectContentKey(const KeyId& key_id) {
const Key* content_key = session_keys_.Find(key_id);
#if 0
std::cout << " Select Key: key_id = "
<< wvcdm::b2a_hex(key_id) << std::endl;
std::cout << " Select Key: key = "
<< wvcdm::b2a_hex(content_key->value()) << std::endl;
#endif
if (LogCategoryEnabled(kLoggingTraceDecryption)){
LOGI(( " Select Key: key_id = " +
wvcdm::b2a_hex(key_id) ).c_str());
LOGI(( " Select Key: key = " +
wvcdm::b2a_hex(content_key->value()) ).c_str());
}
if (NULL == content_key) {
LOGE("[SelectContentKey(): No key matches key id]");
return false;
@@ -1176,4 +1183,4 @@ void NonceTable::Flush() {
}
}
}; // namespace wvoec_mock
}; // namespace wvoec_mock