Minor change

This commit is contained in:
Lu Chen
2020-02-25 13:16:44 -08:00
parent d71d62d272
commit ed5a1d5db1
18 changed files with 358 additions and 103 deletions

View File

@@ -60,8 +60,20 @@ Status WvCasEcm::GenerateEcm(const WvCasContentKeyInfo& even_key,
LOG(ERROR) << "Failed to get initialize ECM class." << status;
return status;
}
EntitledKeyInfo entitled_even_key = ConvertToEntitledKeyInfo(even_key);
EntitledKeyInfo entitled_odd_key = ConvertToEntitledKeyInfo(odd_key);
// Make content key to 16 bytes if crypto mode is Csa2.
if (ecm_param_.crypto_mode == CryptoMode::kDvbCsa2) {
if (entitled_even_key.key_value.size() == 8) {
entitled_even_key.key_value =
entitled_even_key.key_value + entitled_even_key.key_value;
}
if (entitled_odd_key.key_value.size() == 8) {
entitled_odd_key.key_value =
entitled_odd_key.key_value + entitled_odd_key.key_value;
}
}
return cas_ecm->GenerateEcm(&entitled_even_key, &entitled_odd_key, track_type,
serialized_ecm);
}
@@ -79,6 +91,12 @@ Status WvCasEcm::GenerateSingleKeyEcm(const WvCasContentKeyInfo& key,
}
EntitledKeyInfo entitled_key = ConvertToEntitledKeyInfo(key);
// Make content key to 16 bytes if crypto mode is Csa2.
if (ecm_param_.crypto_mode == CryptoMode::kDvbCsa2) {
if (entitled_key.key_value.size() == 8) {
entitled_key.key_value = entitled_key.key_value + entitled_key.key_value;
}
}
return cas_ecm->GenerateSingleKeyEcm(&entitled_key, track_type,
serialized_ecm);
}

View File

@@ -22,11 +22,12 @@ namespace cas {
// Information needed to generate content key portion of ECM.
// Fields:
// |key_id| key ID for the content key, must be 16 bytes.
// |key| content key value (aka control word), must be 16 bytes. It will be
// wrapped (encrypted) by corresponding entitlement key (decided by track
// type), together with |wrapped_key_iv| as the initial vector.
// |content_iv| content initial vector, must be 8 or 16 bytes. It is used for
// decrypting the content stream.
// |key| content key value (aka control word), must be 8 (DvbCsa2) or 16 bytes
// (all other crypto modes). It will be wrapped (encrypted) by
// corresponding entitlement key (decided by track type), together with
// |wrapped_key_iv| as the initial vector.
// |content_iv| content initial vector, must be 8 (DvbCsa2) or 16 bytes (all
// other crypto modes). It is used for decrypting the content stream.
// |wrapped_key_iv| must be 16 bytes. It is used to encrypt |key|.
struct WvCasContentKeyInfo {
std::string key_id;

View File

@@ -26,6 +26,7 @@ namespace cas {
namespace {
const char kEvenKey[] = "even_key........"; // 16 bytes
const char kEvenKey8Bytes[] = "even_key"; // 8 bytes
const char kEvenContentIv8Bytes[] = "even_iv."; // 8 bytes
const char kEvenContentIv16Bytes[] = "even_iv.even_iv."; // 16 bytes
const char kEvenEntitlementKeyId[] = "even_ent_key_id."; // 16 bytes
@@ -34,6 +35,7 @@ const char kEvenEntitlementKey[] =
const char kEvenEntitlementWrappedKeyIv[] = "1234567812345678"; // 16 bytes
const char kOddKey[] = "odd_key........."; // 16 bytes
const char kOddKey8Bytes[] = "odd_key."; // 8 bytes
const char kOddContentIv8Bytes[] = "odd_iv.."; // 8 bytes
const char kOddContentIv16Bytes[] = "odd_iv..odd_iv.."; // 16 bytes
const char kOddEntitlementKeyId[] = "odd_ent_key_id.."; // 16 bytes
@@ -48,22 +50,24 @@ static constexpr size_t kSingleKeyEcmWith16BytesContentIvSizeBytes =
kSingleKeyEcmWith8BytesContentIvSizeBytes + 8;
} // namespace
class WvCasEcmTest
: public ::testing::Test,
public ::testing::WithParamInterface<::testing::tuple<
int /*content_iv_size*/, bool /*key_rotation_enabled*/>> {
class WvCasEcmTest : public ::testing::Test,
public ::testing::WithParamInterface<::testing::tuple<
int /*content_iv_size*/, bool /*key_rotation_enabled*/,
std::string /*crypto_mode*/>> {
protected:
WvCasEcmTest() {
content_iv_size_ = std::get<0>(GetParam());
key_rotation_ = std::get<1>(GetParam());
crypto_mode_ = std::get<2>(GetParam());
}
WvCasEcmParameters CreateEcmInitParameters(bool key_rotation,
int content_iv_size) {
int content_iv_size,
std::string crypto_mode) {
WvCasEcmParameters params;
params.content_iv_size = content_iv_size == 8 ? kIvSize8 : kIvSize16;
params.key_rotation_enabled = key_rotation;
params.crypto_mode = CryptoMode::kAesScte;
EXPECT_TRUE(StringToCryptoMode(crypto_mode, &params.crypto_mode));
params.age_restriction = 0;
return params;
}
@@ -95,7 +99,7 @@ class WvCasEcmTest
content_keys.reserve(key_rotation ? 2 : 1);
content_keys.emplace_back();
WvCasContentKeyInfo* content_key = &content_keys.back();
content_key->key = kEvenKey;
content_key->key = crypto_mode_ == "DvbCsa2" ? kEvenKey8Bytes : kEvenKey;
content_key->key_id = crypto_util::DeriveKeyId(content_key->key);
content_key->content_iv =
content_iv_size == 8 ? kEvenContentIv8Bytes : kEvenContentIv16Bytes;
@@ -103,7 +107,7 @@ class WvCasEcmTest
if (key_rotation) {
content_keys.emplace_back();
WvCasContentKeyInfo* content_key = &content_keys.back();
content_key->key = kOddKey;
content_key->key = crypto_mode_ == "DvbCsa2" ? kOddKey8Bytes : kOddKey;
content_key->key_id = crypto_util::DeriveKeyId(content_key->key);
content_key->content_iv =
content_iv_size == 8 ? kOddContentIv8Bytes : kOddContentIv16Bytes;
@@ -115,11 +119,12 @@ class WvCasEcmTest
int content_iv_size_;
bool key_rotation_;
std::string crypto_mode_;
};
TEST_P(WvCasEcmTest, InitializeSuccess) {
WvCasEcmParameters params =
CreateEcmInitParameters(key_rotation_, content_iv_size_);
CreateEcmInitParameters(key_rotation_, content_iv_size_, crypto_mode_);
std::vector<EntitlementKeyInfo> entitlements =
CreateInjectedEntitlements(key_rotation_);
WvCasEcm wv_cas_ecm(params, entitlements);
@@ -127,7 +132,7 @@ TEST_P(WvCasEcmTest, InitializeSuccess) {
TEST_P(WvCasEcmTest, GenerateSingleKeyEcmKeyRotationEnabledError) {
WvCasEcmParameters params = CreateEcmInitParameters(
/*key_rotation*/ true, content_iv_size_);
/*key_rotation*/ true, content_iv_size_, crypto_mode_);
std::vector<EntitlementKeyInfo> entitlements =
CreateInjectedEntitlements(/*key_rotation*/ true);
WvCasEcm wv_cas_ecm(params, entitlements);
@@ -144,7 +149,7 @@ TEST_P(WvCasEcmTest, GenerateSingleKeyEcmKeyRotationEnabledError) {
TEST_P(WvCasEcmTest, GenerateEcmKeyRotationDisabledError) {
WvCasEcmParameters params = CreateEcmInitParameters(
/*key_rotation*/ false, content_iv_size_);
/*key_rotation*/ false, content_iv_size_, crypto_mode_);
std::vector<EntitlementKeyInfo> entitlements =
CreateInjectedEntitlements(/*key_rotation*/ false);
WvCasEcm wv_cas_ecm(params, entitlements);
@@ -162,7 +167,7 @@ TEST_P(WvCasEcmTest, GenerateEcmKeyRotationDisabledError) {
TEST_P(WvCasEcmTest, GenerateEcmSuccess) {
WvCasEcmParameters params =
CreateEcmInitParameters(key_rotation_, content_iv_size_);
CreateEcmInitParameters(key_rotation_, content_iv_size_, crypto_mode_);
std::vector<EntitlementKeyInfo> entitlements =
CreateInjectedEntitlements(key_rotation_);
WvCasEcm wv_cas_ecm(params, entitlements);
@@ -193,9 +198,10 @@ TEST_P(WvCasEcmTest, GenerateEcmSuccess) {
}
}
INSTANTIATE_TEST_SUITE_P(WvCasEcmTests, WvCasEcmTest,
::testing::Combine(::testing::Values(8, 16),
::testing::Bool()));
INSTANTIATE_TEST_SUITE_P(
WvCasEcmTests, WvCasEcmTest,
::testing::Combine(::testing::Values(8, 16), ::testing::Bool(),
::testing::Values("AesScte", "DvbCsa2")));
} // namespace cas
} // namespace widevine