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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user