diff --git a/libwvdrmengine/cdm/core/src/initialization_data.cpp b/libwvdrmengine/cdm/core/src/initialization_data.cpp index 373e5a96..cf87d24a 100644 --- a/libwvdrmengine/cdm/core/src/initialization_data.cpp +++ b/libwvdrmengine/cdm/core/src/initialization_data.cpp @@ -680,7 +680,7 @@ void InitializationData::DumpToLogs() const { if (!is_supported()) { LOGD("InitData: Not supported"); } - if (!IsEmpty()) { + if (IsEmpty()) { LOGD("InitData: Empty"); } std::string type_info = type(); @@ -736,6 +736,9 @@ void InitializationData::DumpToLogs() const { LOGD("InitData: entitlement_key_id %d: %s -> %s", i, wvutil::b2a_hex(key.entitlement_key_id()).c_str(), wvutil::b2a_hex(key.key_id()).c_str()); + LOGD("InitData: entitled_key %d: %s", i, + wvutil::b2a_hex(key.key()).c_str()); + LOGD("InitData: iv %d: %s", i, wvutil::b2a_hex(key.iv()).c_str()); } } diff --git a/libwvdrmengine/cdm/core/test/test_base.cpp b/libwvdrmengine/cdm/core/test/test_base.cpp index a72c92d8..e3e4e28c 100644 --- a/libwvdrmengine/cdm/core/test/test_base.cpp +++ b/libwvdrmengine/cdm/core/test/test_base.cpp @@ -189,6 +189,16 @@ enum OptionalBool { bool UnwrapOptionalBool(OptionalBool value, bool default_value) { return (value == kBoolUnset) ? default_value : (value == kBoolTrue); } + +// Increment counter for AES-CTR. The CENC spec specifies we increment only +// the low 64 bits of the IV counter, and leave the high 64 bits alone. This +// is different from the BoringSSL implementation, so we implement the CTR loop +// ourselves. +void ctr128_inc64(int64_t increaseBy, std::vector& iv) { + uint64_t* counterBuffer = reinterpret_cast(&(iv[8])); + (*counterBuffer) = + wvutil::htonll64(wvutil::ntohll64(*counterBuffer) + increaseBy); +} } // namespace // Static WvCdmTestBase variables. @@ -208,6 +218,26 @@ void WvCdmTestBase::StripeBuffer(std::vector* buffer, size_t size, } } +// Encrypt a block of data using CTR mode. +std::vector WvCdmTestBase::Aes128CtrEncrypt( + const std::vector& key, const std::vector& starting_iv, + const std::vector& in_buffer) { + AES_KEY aes_key; + AES_set_encrypt_key(key.data(), AES_BLOCK_SIZE * 8, &aes_key); + std::vector out_buffer(in_buffer.size()); + std::vector iv = starting_iv; + size_t l = 0; // byte index into encrypted subsample. + while (l < in_buffer.size()) { + uint8_t aes_output[AES_BLOCK_SIZE]; + AES_encrypt(iv.data(), aes_output, &aes_key); + for (size_t n = 0; n < AES_BLOCK_SIZE && l < in_buffer.size(); n++, l++) { + out_buffer[l] = aes_output[n] ^ in_buffer[l]; + } + ctr128_inc64(1, iv); + } + return out_buffer; +} + std::string WvCdmTestBase::Aes128CbcEncrypt(std::vector key, const std::vector& clear, std::vector iv) { diff --git a/libwvdrmengine/cdm/core/test/test_base.h b/libwvdrmengine/cdm/core/test/test_base.h index d95cef40..646b9409 100644 --- a/libwvdrmengine/cdm/core/test/test_base.h +++ b/libwvdrmengine/cdm/core/test/test_base.h @@ -76,6 +76,10 @@ class WvCdmTestBase : public ::testing::Test { const std::vector& clear, std::vector iv); // Helper method for doing cryptography. + static std::vector Aes128CtrEncrypt( + const std::vector& key, const std::vector& starting_iv, + const std::vector& in_buffer); + // Helper method for doing cryptography. static std::string SignHMAC(const std::string& message, const std::vector& key);