Regular sync.

Changes include:
1. Fix refreshkeys when handling renewal response.
2. Change ECM start detect method.
3. Fix signing key truncation.
4. Reformat C++ code.
5. Return license_id in LICENSE_CAS_READY payload.
6. Expose OEMCrypto API version in the license request.
7. Add support for newly added widevine cas ids.
8. Store content iv and encryption mode info to entitled key.
9. Upgrade ODK library to 16.4.
This commit is contained in:
huihli
2020-10-21 11:16:23 -07:00
parent 0f6db6f751
commit 2feec02df2
39 changed files with 703 additions and 546 deletions

View File

@@ -13,6 +13,8 @@
#include <utility>
#include <vector>
#include "OEMCryptoCAS.h"
namespace wvoec_ref {
class KeyControlBlock {
@@ -66,18 +68,21 @@ class Key {
class EntitledKey {
public:
explicit EntitledKey(std::vector<uint8_t> key_string)
: value_(std::move(key_string)), ctr_mode_(true){};
: value_(std::move(key_string)), cipher_mode_(OEMCrypto_CipherMode_CTR){};
EntitledKey(const EntitledKey&) = default;
EntitledKey(EntitledKey&&) = default;
~EntitledKey() = default;
const std::vector<uint8_t>& value() const { return value_; }
bool ctr_mode() const { return ctr_mode_; }
void set_ctr_mode(bool ctr_mode) { ctr_mode_ = ctr_mode; }
OEMCryptoCipherMode cipher_mode() const { return cipher_mode_; }
void set_cipher_mode(OEMCryptoCipherMode mode) { cipher_mode_ = mode; }
void set_content_iv(const std::vector<uint8_t>& iv) { content_iv_ = iv; }
const std::vector<uint8_t>& content_iv() const { return content_iv_; }
private:
std::vector<uint8_t> value_;
bool ctr_mode_;
OEMCryptoCipherMode cipher_mode_;
std::vector<uint8_t> content_iv_;
};
} // namespace wvoec_ref

View File

@@ -7,11 +7,6 @@
#include "oemcrypto_session.h"
#include <assert.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <vector>
#include <openssl/aes.h>
#include <openssl/bio.h>
#include <openssl/cmac.h>
@@ -23,6 +18,11 @@
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/x509.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <vector>
#include "advance_iv_ctr.h"
#include "keys.h"
@@ -97,8 +97,7 @@ SessionContext::SessionContext(CryptoEngine* ce, SessionId sid,
CryptoEngine::kApiVersion, sid);
}
SessionContext::~SessionContext() {
}
SessionContext::~SessionContext() {}
// Internal utility function to derive key using CMAC-128
bool SessionContext::DeriveKey(const std::vector<uint8_t>& key,
@@ -562,11 +561,13 @@ OEMCryptoResult SessionContext::CheckStatusOffline(uint32_t nonce,
OEMCryptoResult SessionContext::CheckNonceOrEntry(
const KeyControlBlock& key_control_block) {
switch (key_control_block.control_bits() & wvoec::kControlReplayMask) {
case wvoec::kControlNonceRequired: // Online license. Nonce always required.
case wvoec::kControlNonceRequired: // Online license. Nonce always
// required.
return CheckStatusOnline(key_control_block.nonce(),
key_control_block.control_bits());
break;
case wvoec::kControlNonceOrEntry: // Offline license. Nonce required on first use.
case wvoec::kControlNonceOrEntry: // Offline license. Nonce required on
// first use.
return CheckStatusOffline(key_control_block.nonce(),
key_control_block.control_bits());
break;
@@ -725,9 +726,8 @@ OEMCryptoResult SessionContext::LoadKeysNoSignature(
message + key_array[i].key_control_iv.offset,
message + key_array[i].key_control_iv.offset + wvoec::KEY_IV_SIZE);
OEMCryptoResult result =
InstallKey(key_id, enc_key_data, key_data_iv, key_control,
key_control_iv);
OEMCryptoResult result = InstallKey(key_id, enc_key_data, key_data_iv,
key_control, key_control_iv);
if (result != OEMCrypto_SUCCESS) {
status = result;
break;
@@ -882,9 +882,20 @@ OEMCryptoResult SessionContext::LoadEntitledCasKeys(
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
if (!key_session->AddOrUpdateContentKey(
entitlement_key, content_key_id,
std::unique_ptr<EntitledKey>(new EntitledKey(content_key)))) {
auto content_key_obj =
std::unique_ptr<EntitledKey>(new EntitledKey(content_key));
// Store content iv and encryption info.
if (key_data->content_iv.length > 0) {
std::vector<uint8_t> content_iv;
content_iv.assign(
message + key_data->content_iv.offset,
message + key_data->content_iv.offset + key_data->content_iv.length);
content_key_obj->set_content_iv(content_iv);
}
content_key_obj->set_cipher_mode(key_data->cipher_mode);
if (!key_session->AddOrUpdateContentKey(entitlement_key, content_key_id,
std::move(content_key_obj))) {
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
}
@@ -1172,7 +1183,7 @@ OEMCryptoResult SessionContext::CheckKeyControlBlockUse(
LOGE("[%s(): CGMS required, but buffer is clear", log_string.c_str());
return OEMCrypto_ERROR_ANALOG_OUTPUT;
}
if ( ce_->analog_display_active() && !ce_->cgms_a_active()) {
if (ce_->analog_display_active() && !ce_->cgms_a_active()) {
LOGE("[%s(): control bit says CGMS required", log_string.c_str());
return OEMCrypto_ERROR_ANALOG_OUTPUT;
}
@@ -1200,8 +1211,9 @@ OEMCryptoResult SessionContext::Generic_Encrypt(
LOGE("[Generic_Encrypt(): CONTENT_KEY has wrong size: %d", key.size());
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
OEMCryptoResult result = CheckKeyUse("Generic_Encrypt", wvoec::kControlAllowEncrypt,
OEMCrypto_BufferType_Clear);
OEMCryptoResult result =
CheckKeyUse("Generic_Encrypt", wvoec::kControlAllowEncrypt,
OEMCrypto_BufferType_Clear);
if (result != OEMCrypto_SUCCESS) return result;
if (algorithm != OEMCrypto_AES_CBC_128_NO_PADDING) {
LOGE("[Generic_Encrypt(): algorithm bad");
@@ -1242,8 +1254,9 @@ OEMCryptoResult SessionContext::Generic_Decrypt(
LOGE("[Generic_Decrypt(): CONTENT_KEY has wrong size");
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
OEMCryptoResult result = CheckKeyUse("Generic_Decrypt", wvoec::kControlAllowDecrypt,
OEMCrypto_BufferType_Clear);
OEMCryptoResult result =
CheckKeyUse("Generic_Decrypt", wvoec::kControlAllowDecrypt,
OEMCrypto_BufferType_Clear);
if (result != OEMCrypto_SUCCESS) return result;
if (algorithm != OEMCrypto_AES_CBC_128_NO_PADDING) {
@@ -1327,8 +1340,8 @@ OEMCryptoResult SessionContext::Generic_Verify(
LOGE("[Generic_Verify(): CONTENT_KEY has wrong size: %d", key.size());
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
}
OEMCryptoResult result = CheckKeyUse("Generic_Verify", wvoec::kControlAllowVerify,
OEMCrypto_BufferType_Clear);
OEMCryptoResult result = CheckKeyUse(
"Generic_Verify", wvoec::kControlAllowVerify, OEMCrypto_BufferType_Clear);
if (result != OEMCrypto_SUCCESS) return result;
if (algorithm != OEMCrypto_HMAC_SHA256) {
LOGE("[Generic_Verify(): bad algorithm");
@@ -1411,7 +1424,7 @@ OEMCryptoResult SessionContext::SelectEntitledContentKey(
LOGE("No key matches key id");
return OEMCrypto_ERROR_NO_CONTENT_KEY;
}
content_key->set_ctr_mode(cipher_mode == OEMCrypto_CipherMode_CTR);
content_key->set_cipher_mode(cipher_mode);
// Update current content key selection.
key_session->SetCurrentKey(key_id);
@@ -1579,9 +1592,11 @@ OEMCryptoResult SessionContext::DecryptSamples(
subsample_source += subsample_length;
advance_dest_buffer(&subsample_dest, subsample_length);
if (subsample.num_bytes_encrypted > 0) {
bool is_ctr_mode = key_session == nullptr
? current_content_key()->ctr_mode()
: key_session->CurrentContentKey()->ctr_mode();
bool is_ctr_mode =
key_session == nullptr
? current_content_key()->ctr_mode()
: key_session->CurrentContentKey()->cipher_mode() ==
OEMCrypto_CipherMode_CTR;
if (is_ctr_mode) {
wvutil::AdvanceIvCtr(
&subsample_iv,
@@ -1702,7 +1717,8 @@ OEMCryptoResult SessionContext::ChooseDecrypt(
}
bool is_ctr_mode = key_session == nullptr
? current_content_key()->ctr_mode()
: key_session->CurrentContentKey()->ctr_mode();
: key_session->CurrentContentKey()->cipher_mode() ==
OEMCrypto_CipherMode_CTR;
if (!is_ctr_mode) {
if (block_offset > 0 || pattern->encrypt == 0) {
return OEMCrypto_ERROR_INVALID_CONTEXT;