diff --git a/example/BUILD b/example/BUILD index 32d1060..4c6cb44 100644 --- a/example/BUILD +++ b/example/BUILD @@ -48,6 +48,6 @@ cc_binary( deps = [ "@abseil_repo//absl/base:core_headers", "//media_cas_packager_sdk/public:wv_cas_ecm", - "//media_cas_packager_sdk/public:wv_cas_status", + "//media_cas_packager_sdk/public:wv_cas_types", ], ) diff --git a/example/wv_cas_ecm_example.cc b/example/wv_cas_ecm_example.cc index 4d65e34..3473d6b 100644 --- a/example/wv_cas_ecm_example.cc +++ b/example/wv_cas_ecm_example.cc @@ -12,11 +12,10 @@ #include #include "media_cas_packager_sdk/public/wv_cas_ecm.h" -#include "media_cas_packager_sdk/public/wv_cas_status.h" +#include "media_cas_packager_sdk/public/wv_cas_types.h" const int kContentIvSize = 16; const bool kKeyRotationEnabled = true; -const int kCryptoMode = 1; // CTR const char kEvenKey[] = "even_content_key"; // 16 bytes const char kEvenContentIv8Bytes[] = "evencont"; // 8 bytes const char kEvenContentIv16Bytes[] = "evencontevencont"; // 16 bytes @@ -29,7 +28,8 @@ const char kEntitlementKey[] = "entitlement_key................."; // 32 bytes int main(int argc, char **argv) { widevine::cas::WvCasEcm wv_cas_ecm; widevine::cas::WvCasStatus status = - wv_cas_ecm.Initialize(kContentIvSize, kKeyRotationEnabled, kCryptoMode); + wv_cas_ecm.Initialize(kContentIvSize, kKeyRotationEnabled, + widevine::cas::CryptoMode::kDvbCsa); if (status != widevine::cas::OK) { std::cerr << "Failed to initialize WV CAS ECM, error: " << widevine::cas::GetWvCasStatusMessage(status) diff --git a/media_cas_packager_sdk/internal/BUILD b/media_cas_packager_sdk/internal/BUILD index a2219a3..8f13434 100644 --- a/media_cas_packager_sdk/internal/BUILD +++ b/media_cas_packager_sdk/internal/BUILD @@ -32,6 +32,7 @@ cc_library( "//common:aes_cbc_util", "//common:random_util", "//common:string_util", + "//media_cas_packager_sdk/public:wv_cas_types", "//protos/public:media_cas_encryption_proto", "//protos/public:media_cas_proto", ], @@ -45,6 +46,7 @@ cc_test( ":ecm", "//testing:gunit_main", "//util:status", + "//media_cas_packager_sdk/public:wv_cas_types", "//protos/public:media_cas_encryption_proto", ], ) @@ -91,6 +93,7 @@ cc_library( "@abseil_repo//absl/strings", "//util:status", "//example:constants", + "//media_cas_packager_sdk/public:wv_cas_types", ], ) diff --git a/media_cas_packager_sdk/internal/ecm.cc b/media_cas_packager_sdk/internal/ecm.cc index 8924cc2..90316dd 100644 --- a/media_cas_packager_sdk/internal/ecm.cc +++ b/media_cas_packager_sdk/internal/ecm.cc @@ -18,7 +18,6 @@ #include "common/aes_cbc_util.h" #include "common/random_util.h" #include "common/string_util.h" -#include "protos/public/media_cas.pb.h" #include "protos/public/media_cas_encryption.pb.h" namespace widevine { @@ -40,7 +39,7 @@ static constexpr int kNumBitsEcmVersionField = 8; // Byte 3 static constexpr int kNumBitsEcmGenerationCountField = 5; -// Values for Decrypt Mode are from enum CasCryptoMode +// Values for Decrypt Mode are from enum CryptoMode static constexpr int kNumBitsDecryptModeField = 2; static constexpr int kNumBitsRotationEnabledField = 1; @@ -140,10 +139,8 @@ util::Status CasEcm::Initialize(const std::string& content_id, "Parameter content_iv_size must be kIvSize8 or kIvSize16."}; } - if (ecm_init_parameters.crypto_mode != CasCryptoMode::CTR && - ecm_init_parameters.crypto_mode != CasCryptoMode::CBC) { - return {util::error::INVALID_ARGUMENT, - "Crypto mode setting is out of range."}; + if (ecm_init_parameters.crypto_mode == CryptoMode::kCryptoModeUnspecified) { + return {util::error::INVALID_ARGUMENT, "Invalid crypto mode."}; } else { crypto_mode_ = ecm_init_parameters.crypto_mode; } @@ -391,7 +388,8 @@ std::string CasEcm::SerializeEcm(const std::vector& keys) { std::bitset ecm_version(kEcmVersion); std::bitset ecm_generation_count( generation()); - std::bitset decrypt_mode(crypto_mode()); + std::bitset decrypt_mode( + static_cast(crypto_mode())); std::bitset rotation_enabled( RotationFieldValue(paired_keys_required())); std::bitset wrapped_key_iv_size( diff --git a/media_cas_packager_sdk/internal/ecm.h b/media_cas_packager_sdk/internal/ecm.h index 349965b..2adf97b 100644 --- a/media_cas_packager_sdk/internal/ecm.h +++ b/media_cas_packager_sdk/internal/ecm.h @@ -17,6 +17,7 @@ #include #include "util/status.h" +#include "media_cas_packager_sdk/public/wv_cas_types.h" #include "protos/public/media_cas.pb.h" namespace widevine { @@ -49,13 +50,13 @@ enum EcmIvSize { kIvSize8 = 0, kIvSize16 = 1 }; // A constant of type CasEcmSize specifying 8 or 16. // |key_rotation_enabled| the encryption uses multiple keys in rotation. // |crypto_mode| the encryption mode used for the content stream. -// A constant of type CasCryptoMode. +// A constant of type CryptoMode. // |track_types| a vector of track ID (std::string) that specify the set of track // types of interest; controls the entitlement keys returned by the server. struct EcmInitParameters { EcmIvSize content_iv_size = kIvSize8; bool key_rotation_enabled = true; - CasCryptoMode crypto_mode = CasCryptoMode::CTR; + CryptoMode crypto_mode = CryptoMode::kAesCtr; std::vector track_types; }; @@ -216,7 +217,7 @@ class CasEcm { virtual util::Status ParseEntitlementResponse(const std::string& response_string); virtual uint32_t generation() const { return generation_; } - virtual CasCryptoMode crypto_mode() const { return crypto_mode_; } + virtual CryptoMode crypto_mode() const { return crypto_mode_; } virtual bool paired_keys_required() const { return paired_keys_required_; } virtual size_t content_iv_size() const { return content_iv_size_; } @@ -235,7 +236,7 @@ class CasEcm { std::vector track_types_; // Remember if a pair of keys is required (for key rotation). bool paired_keys_required_ = false; - CasCryptoMode crypto_mode_ = CasCryptoMode::CTR; + CryptoMode crypto_mode_ = CryptoMode::kAesCtr; // Entitlement keys needed for ECM generation. // The keys are added when the CasEncryptionResponse is processed. std::map> entitlement_keys_; diff --git a/media_cas_packager_sdk/internal/ecm_test.cc b/media_cas_packager_sdk/internal/ecm_test.cc index f4e7aa8..2bab89e 100644 --- a/media_cas_packager_sdk/internal/ecm_test.cc +++ b/media_cas_packager_sdk/internal/ecm_test.cc @@ -14,6 +14,7 @@ #include "testing/gmock.h" #include "testing/gunit.h" #include "util/status.h" +#include "media_cas_packager_sdk/public/wv_cas_types.h" #include "protos/public/media_cas_encryption.pb.h" using ::testing::Return; @@ -59,7 +60,7 @@ class MockCasEcm : public CasEcm { ~MockCasEcm() override = default; MOCK_CONST_METHOD0(generation, uint32_t()); - MOCK_CONST_METHOD0(crypto_mode, CasCryptoMode()); + MOCK_CONST_METHOD0(crypto_mode, CryptoMode()); MOCK_CONST_METHOD0(paired_keys_required, bool()); MOCK_CONST_METHOD0(content_iv_size, size_t()); @@ -78,7 +79,7 @@ class MockCasEcm : public CasEcm { } void MockSetup(bool two_keys, const std::string& track_type, uint32_t generation, - CasCryptoMode crypto_mode, size_t civ_size) { + CryptoMode crypto_mode, size_t civ_size) { EXPECT_CALL(*this, generation()).WillRepeatedly(Return(generation)); EXPECT_CALL(*this, crypto_mode()).WillRepeatedly(Return(crypto_mode)); EXPECT_CALL(*this, paired_keys_required()).WillRepeatedly(Return(two_keys)); @@ -187,7 +188,7 @@ class CasEcmTest : public testing::Test { class CasEcmSerializeEcmTest : public CasEcmTest { public: void ValidateEcmHeaderFields(const std::string& ecm_string, bool rotation_enabled, - int gen, CasCryptoMode crypto_mode, + int gen, CryptoMode crypto_mode, EcmIvSize content_iv) { EXPECT_THAT('\x4A', ecm_string[0]); EXPECT_THAT('\xD4', ecm_string[1]); @@ -201,8 +202,7 @@ class CasEcmSerializeEcmTest : public CasEcmTest { } void ValidateEcmFieldsOneKey(const std::string& buf_string, int gen, - CasCryptoMode crypto_mode, - EcmIvSize content_iv) { + CryptoMode crypto_mode, EcmIvSize content_iv) { size_t expected_size = kEcmHeaderSize + kEcmKeyInfoSize + kEcmIvSize16 + IvExpectedSize(content_iv); size_t ecm_len = buf_string.size(); @@ -211,8 +211,7 @@ class CasEcmSerializeEcmTest : public CasEcmTest { } void ValidateEcmFieldsTwoKeys(const std::string& buf_string, int gen, - CasCryptoMode crypto_mode, - EcmIvSize content_iv) { + CryptoMode crypto_mode, EcmIvSize content_iv) { size_t expected_size = kEcmHeaderSize + (2 * (kEcmKeyInfoSize + kEcmIvSize16 + IvExpectedSize(content_iv))); @@ -559,7 +558,7 @@ TEST_F(CasEcmSerializeEcmTest, SerializeEcmDoubleKey16ByteIvs) { EntitledKeyInfo key1 = valid3_iv_16_16_; EntitledKeyInfo key2 = valid4_iv_16_16_; - ecm_gen.MockSetup(true, kTrackTypeSD, 0, CasCryptoMode::CTR, 16); + ecm_gen.MockSetup(true, kTrackTypeSD, 0, CryptoMode::kAesCtr, 16); std::vector keys; keys.push_back(&key1); @@ -568,20 +567,20 @@ TEST_F(CasEcmSerializeEcmTest, SerializeEcmDoubleKey16ByteIvs) { std::string buf_string = ecm_gen.CallSerializeEcm(keys); - ValidateEcmFieldsTwoKeys(buf_string, 0, CasCryptoMode::CTR, kIvSize16); + ValidateEcmFieldsTwoKeys(buf_string, 0, CryptoMode::kAesCtr, kIvSize16); EXPECT_CALL(ecm_gen, generation()).WillRepeatedly(Return(1)); buf_string = ecm_gen.CallSerializeEcm(keys); - ValidateEcmFieldsTwoKeys(buf_string, 1, CasCryptoMode::CTR, kIvSize16); + ValidateEcmFieldsTwoKeys(buf_string, 1, CryptoMode::kAesCtr, kIvSize16); } TEST_F(CasEcmSerializeEcmTest, SerializeEcmSingleKey16ByteIvs) { MockCasEcm ecm_gen; EntitledKeyInfo key1 = valid3_iv_16_16_; - ecm_gen.MockSetup(false, kTrackTypeSD, 0, CasCryptoMode::CTR, 16); + ecm_gen.MockSetup(false, kTrackTypeSD, 0, CryptoMode::kAesCtr, 16); std::vector keys; keys.push_back(&key1); @@ -589,13 +588,13 @@ TEST_F(CasEcmSerializeEcmTest, SerializeEcmSingleKey16ByteIvs) { std::string buf_string = ecm_gen.CallSerializeEcm(keys); - ValidateEcmFieldsOneKey(buf_string, 0, CasCryptoMode::CTR, kIvSize16); + ValidateEcmFieldsOneKey(buf_string, 0, CryptoMode::kAesCtr, kIvSize16); EXPECT_CALL(ecm_gen, generation()).WillRepeatedly(Return(1)); buf_string = ecm_gen.CallSerializeEcm(keys); - ValidateEcmFieldsOneKey(buf_string, 1, CasCryptoMode::CTR, kIvSize16); + ValidateEcmFieldsOneKey(buf_string, 1, CryptoMode::kAesCtr, kIvSize16); } TEST_F(CasEcmSerializeEcmTest, SerializeEcmDoubleKey16x8ByteIvs) { @@ -603,7 +602,7 @@ TEST_F(CasEcmSerializeEcmTest, SerializeEcmDoubleKey16x8ByteIvs) { EntitledKeyInfo key1 = valid1_iv_16_8_; EntitledKeyInfo key2 = valid2_iv_16_8_; - ecm_gen.MockSetup(true, kTrackTypeSD, 0, CasCryptoMode::CTR, 8); + ecm_gen.MockSetup(true, kTrackTypeSD, 0, CryptoMode::kAesCtr, 8); std::vector keys; keys.push_back(&key1); @@ -612,20 +611,20 @@ TEST_F(CasEcmSerializeEcmTest, SerializeEcmDoubleKey16x8ByteIvs) { std::string buf_string = ecm_gen.CallSerializeEcm(keys); - ValidateEcmFieldsTwoKeys(buf_string, 0, CasCryptoMode::CTR, kIvSize8); + ValidateEcmFieldsTwoKeys(buf_string, 0, CryptoMode::kAesCtr, kIvSize8); EXPECT_CALL(ecm_gen, generation()).WillRepeatedly(Return(1)); buf_string = ecm_gen.CallSerializeEcm(keys); - ValidateEcmFieldsTwoKeys(buf_string, 1, CasCryptoMode::CTR, kIvSize8); + ValidateEcmFieldsTwoKeys(buf_string, 1, CryptoMode::kAesCtr, kIvSize8); } TEST_F(CasEcmSerializeEcmTest, SerializeEcmSingleKey16x8ByteIvs) { MockCasEcm ecm_gen; EntitledKeyInfo key1 = valid1_iv_16_8_; - ecm_gen.MockSetup(false, kTrackTypeSD, 0, CasCryptoMode::CTR, 8); + ecm_gen.MockSetup(false, kTrackTypeSD, 0, CryptoMode::kAesCtr, 8); std::vector keys; keys.push_back(&key1); @@ -633,13 +632,13 @@ TEST_F(CasEcmSerializeEcmTest, SerializeEcmSingleKey16x8ByteIvs) { std::string buf_string = ecm_gen.CallSerializeEcm(keys); - ValidateEcmFieldsOneKey(buf_string, 0, CasCryptoMode::CTR, kIvSize8); + ValidateEcmFieldsOneKey(buf_string, 0, CryptoMode::kAesCtr, kIvSize8); EXPECT_CALL(ecm_gen, generation()).WillRepeatedly(Return(1)); buf_string = ecm_gen.CallSerializeEcm(keys); - ValidateEcmFieldsOneKey(buf_string, 1, CasCryptoMode::CTR, kIvSize8); + ValidateEcmFieldsOneKey(buf_string, 1, CryptoMode::kAesCtr, kIvSize8); } } // namespace cas diff --git a/media_cas_packager_sdk/internal/ecmg.cc b/media_cas_packager_sdk/internal/ecmg.cc index d893f13..9b7187f 100644 --- a/media_cas_packager_sdk/internal/ecmg.cc +++ b/media_cas_packager_sdk/internal/ecmg.cc @@ -10,10 +10,10 @@ #include #include -#include #include #include #include +#include #include "glog/logging.h" #include "absl/memory/memory.h" @@ -23,6 +23,7 @@ #include "media_cas_packager_sdk/internal/ecm_generator.h" #include "media_cas_packager_sdk/internal/ecmg_constants.h" #include "media_cas_packager_sdk/internal/util.h" +#include "media_cas_packager_sdk/public/wv_cas_types.h" namespace widevine { namespace cas { @@ -225,8 +226,8 @@ util::Status Ecmg::ProcessCwProvisionMessage(const char* message, EcmInitParameters ecm_init_params; ecm_init_params.content_iv_size = kIvSize8; ecm_init_params.key_rotation_enabled = key_rotation_enabled; - // Only CTR is supported for now. - ecm_init_params.crypto_mode = CasCryptoMode::CTR; + // TODO(user): Allow caller to specify the crypto mode. + ecm_init_params.crypto_mode = CryptoMode::kAesCtr; // Only encrypt one video track. ecm_init_params.track_types.push_back(kDefaultTrackTypeSd); std::string entitlement_request; diff --git a/media_cas_packager_sdk/public/BUILD b/media_cas_packager_sdk/public/BUILD index fb59ab2..ab2c395 100644 --- a/media_cas_packager_sdk/public/BUILD +++ b/media_cas_packager_sdk/public/BUILD @@ -29,7 +29,7 @@ cc_binary( deps = [ ":wv_cas_ca_descriptor", ":wv_cas_ecm", - ":wv_cas_status", + ":wv_cas_types", ], ) @@ -63,7 +63,7 @@ cc_library( hdrs = ["wv_cas_ca_descriptor.h"], copts = PUBLIC_COPTS, deps = [ - ":wv_cas_status", + ":wv_cas_types", "//base", "@abseil_repo//absl/base:core_headers", "@abseil_repo//absl/strings", @@ -79,7 +79,7 @@ cc_test( srcs = ["wv_cas_ca_descriptor_test.cc"], deps = [ ":wv_cas_ca_descriptor", - ":wv_cas_status", + ":wv_cas_types", "//testing:gunit_main", "//protos/public:media_cas_proto", ], @@ -91,7 +91,7 @@ cc_library( hdrs = ["wv_cas_ecm.h"], copts = PUBLIC_COPTS, deps = [ - ":wv_cas_status", + ":wv_cas_types", "//base", "@abseil_repo//absl/base:core_headers", "@abseil_repo//absl/memory", @@ -102,7 +102,6 @@ cc_library( "//media_cas_packager_sdk/internal:ecm", "//media_cas_packager_sdk/internal:ecm_generator", "//media_cas_packager_sdk/internal:fixed_key_fetcher", - "//protos/public:media_cas_proto", ], ) @@ -112,26 +111,26 @@ cc_test( srcs = ["wv_cas_ecm_test.cc"], deps = [ ":wv_cas_ecm", - ":wv_cas_status", + ":wv_cas_types", "//testing:gunit_main", "@abseil_repo//absl/strings", ], ) cc_library( - name = "wv_cas_status", - srcs = ["wv_cas_status.cc"], - hdrs = ["wv_cas_status.h"], + name = "wv_cas_types", + srcs = ["wv_cas_types.cc"], + hdrs = ["wv_cas_types.h"], copts = PUBLIC_COPTS, deps = ["//base"], ) cc_test( - name = "wv_cas_status_test", + name = "wv_cas_types_test", size = "small", - srcs = ["wv_cas_status_test.cc"], + srcs = ["wv_cas_types_test.cc"], deps = [ - ":wv_cas_status", + ":wv_cas_types", "//testing:gunit_main", ], ) diff --git a/media_cas_packager_sdk/public/wv_cas_ca_descriptor.cc b/media_cas_packager_sdk/public/wv_cas_ca_descriptor.cc index 982bd18..124621d 100644 --- a/media_cas_packager_sdk/public/wv_cas_ca_descriptor.cc +++ b/media_cas_packager_sdk/public/wv_cas_ca_descriptor.cc @@ -14,7 +14,7 @@ #include "absl/strings/str_cat.h" #include "util/status.h" #include "common/string_util.h" -#include "media_cas_packager_sdk/public/wv_cas_status.h" +#include "media_cas_packager_sdk/public/wv_cas_types.h" #include "protos/public/media_cas.pb.h" namespace widevine { diff --git a/media_cas_packager_sdk/public/wv_cas_ca_descriptor.h b/media_cas_packager_sdk/public/wv_cas_ca_descriptor.h index baea1bf..b61c988 100644 --- a/media_cas_packager_sdk/public/wv_cas_ca_descriptor.h +++ b/media_cas_packager_sdk/public/wv_cas_ca_descriptor.h @@ -12,7 +12,7 @@ #include #include -#include "media_cas_packager_sdk/public/wv_cas_status.h" +#include "media_cas_packager_sdk/public/wv_cas_types.h" namespace widevine { namespace cas { diff --git a/media_cas_packager_sdk/public/wv_cas_ca_descriptor_test.cc b/media_cas_packager_sdk/public/wv_cas_ca_descriptor_test.cc index 594bb36..4d6d89e 100644 --- a/media_cas_packager_sdk/public/wv_cas_ca_descriptor_test.cc +++ b/media_cas_packager_sdk/public/wv_cas_ca_descriptor_test.cc @@ -11,7 +11,7 @@ #include #include "testing/gunit.h" -#include "media_cas_packager_sdk/public/wv_cas_status.h" +#include "media_cas_packager_sdk/public/wv_cas_types.h" #include "protos/public/media_cas.pb.h" using ::testing::Test; diff --git a/media_cas_packager_sdk/public/wv_cas_ecm.cc b/media_cas_packager_sdk/public/wv_cas_ecm.cc index f8fffdb..685530a 100644 --- a/media_cas_packager_sdk/public/wv_cas_ecm.cc +++ b/media_cas_packager_sdk/public/wv_cas_ecm.cc @@ -8,7 +8,6 @@ #include "media_cas_packager_sdk/public/wv_cas_ecm.h" -#include #include #include #include @@ -22,19 +21,15 @@ #include "media_cas_packager_sdk/internal/ecm.h" #include "media_cas_packager_sdk/internal/ecm_generator.h" #include "media_cas_packager_sdk/internal/fixed_key_fetcher.h" -#include "media_cas_packager_sdk/public/wv_cas_status.h" -#include "protos/public/media_cas.pb.h" +#include "media_cas_packager_sdk/public/wv_cas_types.h" namespace widevine { namespace cas { namespace { -static constexpr size_t kCryptoModeCbc = 0; -static constexpr size_t kCryptoModeCtr = 1; - EcmInitParameters CreateEcmInitParameters(int content_iv_size, bool key_rotation_enabled, - int crypto_mode) { + CryptoMode crypto_mode) { EcmInitParameters params; if (content_iv_size == 8) { params.content_iv_size = kIvSize8; @@ -42,7 +37,7 @@ EcmInitParameters CreateEcmInitParameters(int content_iv_size, params.content_iv_size = kIvSize16; } params.key_rotation_enabled = key_rotation_enabled; - params.crypto_mode = CasCryptoMode::CTR; + params.crypto_mode = crypto_mode; // Internal ECM class can hold entitlement keys for multiple tracks. // So we need to set a default track type here to be associated with // the entitlement keys set later. @@ -53,7 +48,7 @@ EcmInitParameters CreateEcmInitParameters(int content_iv_size, } // namespace WvCasStatus WvCasEcm::Initialize(int content_iv_size, bool key_rotation_enabled, - int crypto_mode) { + CryptoMode crypto_mode) { if (initialized_) { LOG(ERROR) << "Cannot initialize an instance of WvCasEcm more than once"; return UNAVAILABLE; @@ -64,11 +59,6 @@ WvCasStatus WvCasEcm::Initialize(int content_iv_size, bool key_rotation_enabled, } content_iv_size_ = content_iv_size; key_rotation_enabled_ = key_rotation_enabled; - if (crypto_mode != kCryptoModeCtr) { - LOG(ERROR) << "Only CTR crypto mode is supported by Widevine plugin for " - "content encryption"; - return INVALID_ARGUMENT; - } crypto_mode_ = crypto_mode; initialized_ = true; diff --git a/media_cas_packager_sdk/public/wv_cas_ecm.h b/media_cas_packager_sdk/public/wv_cas_ecm.h index 5b089b8..0d38c43 100644 --- a/media_cas_packager_sdk/public/wv_cas_ecm.h +++ b/media_cas_packager_sdk/public/wv_cas_ecm.h @@ -16,7 +16,7 @@ #include #include -#include "media_cas_packager_sdk/public/wv_cas_status.h" +#include "media_cas_packager_sdk/public/wv_cas_types.h" namespace widevine { namespace cas { @@ -42,9 +42,7 @@ class WvCasEcm { // if this is 'true' only subsequent call to GenerateEcm will be allowed, // if this is 'false' only subsequent call to GenerateSingleKeyEcm will // be allowed - // - |crypto_mode| crypto mode for encrypting content, - // kCryptoModeCbc = 0, kCryptoModeCtr = 1 - // only CTR is supported by Widevine CAS plugin for now + // - |crypto_mode| crypto mode for encrypting content // // Returns: // - A status indicating whether there was any error during initialization @@ -52,7 +50,7 @@ class WvCasEcm { // Note: // - 'even'/'odd' key in the ECM will be be encrypted using AEC_CBC virtual WvCasStatus Initialize(int content_iv_size, bool key_rotation_enabled, - int crypto_mode); + CryptoMode crypto_mode); // Generate an ECM containing two keys (even and odd). Can be called when // |key_rotation_enabled| is initialized to 'true'. @@ -108,7 +106,7 @@ class WvCasEcm { bool initialized_ = false; int content_iv_size_; bool key_rotation_enabled_; - int crypto_mode_; + CryptoMode crypto_mode_; }; } // namespace cas diff --git a/media_cas_packager_sdk/public/wv_cas_ecm_test.cc b/media_cas_packager_sdk/public/wv_cas_ecm_test.cc index 1ad8da4..a16b2fa 100644 --- a/media_cas_packager_sdk/public/wv_cas_ecm_test.cc +++ b/media_cas_packager_sdk/public/wv_cas_ecm_test.cc @@ -11,7 +11,7 @@ #include "testing/gunit.h" #include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" -#include "media_cas_packager_sdk/public/wv_cas_status.h" +#include "media_cas_packager_sdk/public/wv_cas_types.h" using ::testing::Test; @@ -34,31 +34,24 @@ class WvCasEcmTest : public Test { TEST_F(WvCasEcmTest, InitializeTwice) { EXPECT_EQ(OK, wv_cas_ecm_.Initialize(/* content_iv_size= */ 8, /* key_rotation_enabled= */ true, - /* crypto_mode= */ 1)); + CryptoMode::kAesCtr)); EXPECT_EQ(UNAVAILABLE, wv_cas_ecm_.Initialize(/* content_iv_size= */ 8, /* key_rotation_enabled= */ true, - /* crypto_mode= */ 1)); + CryptoMode::kAesCtr)); } TEST_F(WvCasEcmTest, InitializeInvalidContentIvSize) { EXPECT_EQ(INVALID_ARGUMENT, wv_cas_ecm_.Initialize(/* content_iv_size= */ 4, /* key_rotation_enabled= */ true, - /* crypto_mode= */ 1)); -} - -TEST_F(WvCasEcmTest, InitializeUnsupportedCryptoMode) { - EXPECT_EQ(INVALID_ARGUMENT, - wv_cas_ecm_.Initialize(/* content_iv_size= */ 8, - /* key_rotation_enabled= */ true, - /* crypto_mode= */ 0)); + CryptoMode::kAesCtr)); } TEST_F(WvCasEcmTest, InitializeKeyRotationEnabledThenGenerateSingleKeyEcm) { EXPECT_EQ(OK, wv_cas_ecm_.Initialize(/* content_iv_size= */ 8, /* key_rotation_enabled= */ true, - /* crypto_mode= */ 1)); + CryptoMode::kAesCtr)); std::string actual_ecm; EXPECT_EQ(UNAVAILABLE, wv_cas_ecm_.GenerateSingleKeyEcm("", "", "", "", &actual_ecm)); @@ -67,7 +60,7 @@ TEST_F(WvCasEcmTest, InitializeKeyRotationEnabledThenGenerateSingleKeyEcm) { TEST_F(WvCasEcmTest, InitializeKeyRotationDisabledThenGenerateEcm) { EXPECT_EQ(OK, wv_cas_ecm_.Initialize(/* content_iv_size= */ 8, /* key_rotation_enabled= */ false, - /* crypto_mode= */ 1)); + CryptoMode::kAesCtr)); std::string actual_ecm; EXPECT_EQ(UNAVAILABLE, wv_cas_ecm_.GenerateEcm("", "", "", "", "", "", &actual_ecm)); @@ -76,7 +69,7 @@ TEST_F(WvCasEcmTest, InitializeKeyRotationDisabledThenGenerateEcm) { TEST_F(WvCasEcmTest, GenerateEcmInvalidContentIv) { EXPECT_EQ(OK, wv_cas_ecm_.Initialize(/* content_iv_size= */ 8, /* key_rotation_enabled= */ true, - /* crypto_mode= */ 1)); + CryptoMode::kAesCtr)); std::string actual_ecm; EXPECT_EQ(INVALID_ARGUMENT, wv_cas_ecm_.GenerateEcm( @@ -91,7 +84,7 @@ TEST_F(WvCasEcmTest, GenerateEcmInvalidContentIv) { TEST_F(WvCasEcmTest, GenerateSingleKeyEcmInvalidContentIv) { EXPECT_EQ(OK, wv_cas_ecm_.Initialize(/* content_iv_size= */ 8, /* key_rotation_enabled= */ false, - /* crypto_mode= */ 1)); + CryptoMode::kAesCtr)); std::string actual_ecm; EXPECT_EQ(INVALID_ARGUMENT, wv_cas_ecm_.GenerateSingleKeyEcm( @@ -101,10 +94,10 @@ TEST_F(WvCasEcmTest, GenerateSingleKeyEcmInvalidContentIv) { /* entitlement_key= */ kEntitlementKey, &actual_ecm)); } -TEST_F(WvCasEcmTest, GenerateEcm8BytesContentIvSuccess) { +TEST_F(WvCasEcmTest, GenerateEcm8BytesContentIvCtrSuccess) { EXPECT_EQ(OK, wv_cas_ecm_.Initialize(/* content_iv_size= */ 8, /* key_rotation_enabled= */ true, - /* crypto_mode= */ 1)); + CryptoMode::kAesCtr)); std::string actual_ecm; EXPECT_EQ(OK, wv_cas_ecm_.GenerateEcm( @@ -124,10 +117,10 @@ TEST_F(WvCasEcmTest, GenerateEcm8BytesContentIvSuccess) { absl::BytesToHexString(actual_ecm)); } -TEST_F(WvCasEcmTest, GenerateSingleKeyEcm8BytesContentIvSuccess) { +TEST_F(WvCasEcmTest, GenerateSingleKeyEcm8BytesContentIvCtrSuccess) { EXPECT_EQ(OK, wv_cas_ecm_.Initialize(/* content_iv_size= */ 8, /* key_rotation_enabled= */ false, - /* crypto_mode= */ 1)); + CryptoMode::kAesCtr)); std::string actual_ecm; EXPECT_EQ(OK, wv_cas_ecm_.GenerateSingleKeyEcm( @@ -143,10 +136,10 @@ TEST_F(WvCasEcmTest, GenerateSingleKeyEcm8BytesContentIvSuccess) { absl::BytesToHexString(actual_ecm)); } -TEST_F(WvCasEcmTest, GenerateEcm16BytesContentIvSuccess) { +TEST_F(WvCasEcmTest, GenerateEcm16BytesContentIvCtrSuccess) { EXPECT_EQ(OK, wv_cas_ecm_.Initialize(/* content_iv_size= */ 16, /* key_rotation_enabled= */ true, - /* crypto_mode= */ 1)); + CryptoMode::kAesCtr)); std::string actual_ecm; EXPECT_EQ(OK, wv_cas_ecm_.GenerateEcm( @@ -168,10 +161,10 @@ TEST_F(WvCasEcmTest, GenerateEcm16BytesContentIvSuccess) { absl::BytesToHexString(actual_ecm)); } -TEST_F(WvCasEcmTest, GenerateSingleKeyEcm16BytesContentIvSuccess) { +TEST_F(WvCasEcmTest, GenerateSingleKeyEcm16BytesContentIvCtrSuccess) { EXPECT_EQ(OK, wv_cas_ecm_.Initialize(/* content_iv_size= */ 16, /* key_rotation_enabled= */ false, - /* crypto_mode= */ 1)); + CryptoMode::kAesCtr)); std::string actual_ecm; EXPECT_EQ(OK, wv_cas_ecm_.GenerateSingleKeyEcm( @@ -188,5 +181,95 @@ TEST_F(WvCasEcmTest, GenerateSingleKeyEcm16BytesContentIvSuccess) { absl::BytesToHexString(actual_ecm)); } +TEST_F(WvCasEcmTest, GenerateEcm16BytesContentIvCbcSuccess) { + EXPECT_EQ(OK, wv_cas_ecm_.Initialize(/* content_iv_size= */ 16, + /* key_rotation_enabled= */ true, + CryptoMode::kAesCbc)); + + std::string actual_ecm; + EXPECT_EQ(OK, wv_cas_ecm_.GenerateEcm( + /* even_key= */ kEvenKey, + /* even_content_iv= */ + absl::StrCat(kEvenContentIv8Bytes, kEvenContentIv8Bytes), + /* odd_key= */ kOddKey, + /* odd_content_iv= */ + absl::StrCat(kOddContentIv8Bytes, kOddContentIv8Bytes), + /* entitlement_key_id= */ kEntitlementKeyId, + /* entitlement_key= */ kEntitlementKey, &actual_ecm)); + + EXPECT_EQ( + "4ad40105c0656e745f6b65795f69642e2e2e2e2e2ea5693deeba52b4cb27e7021eefa2f8" + "c2b25f7d48e60627208f4ecca00703aa2467f28b214546a42320e3fa49f936369c657665" + "6e636f6e746576656e636f6e74656e745f6b65795f69642e2e2e2e2e2e0700509b67763b" + "3f1c356bc1e1dc8bac99a1e2f95c37d9183cbb96582f3a05fdbe29925c37c6c6a45eb552" + "b5ddf87f8a6f6464636f6e742e6f6464636f6e742e", + absl::BytesToHexString(actual_ecm)); +} + +TEST_F(WvCasEcmTest, GenerateSingleKeyEcm16BytesContentIvCbcSuccess) { + EXPECT_EQ(OK, wv_cas_ecm_.Initialize(/* content_iv_size= */ 16, + /* key_rotation_enabled= */ false, + CryptoMode::kAesCbc)); + + std::string actual_ecm; + EXPECT_EQ(OK, wv_cas_ecm_.GenerateSingleKeyEcm( + /* even_key= */ kEvenKey, + /* even_content_iv= */ + absl::StrCat(kEvenContentIv8Bytes, kEvenContentIv8Bytes), + /* entitlement_key_id= */ kEntitlementKeyId, + /* entitlement_key= */ kEntitlementKey, &actual_ecm)); + + EXPECT_EQ( + "4ad40104c0656e745f6b65795f69642e2e2e2e2e2ea5693deeba52b4cb27e7021eefa2f8" + "c2b25f7d48e60627208f4ecca00703aa2467f28b214546a42320e3fa49f936369c657665" + "6e636f6e746576656e636f6e74", + absl::BytesToHexString(actual_ecm)); +} + +TEST_F(WvCasEcmTest, GenerateEcm16BytesContentIvCsaSuccess) { + EXPECT_EQ(OK, wv_cas_ecm_.Initialize(/* content_iv_size= */ 16, + /* key_rotation_enabled= */ true, + CryptoMode::kDvbCsa)); + + std::string actual_ecm; + EXPECT_EQ(OK, wv_cas_ecm_.GenerateEcm( + /* even_key= */ kEvenKey, + /* even_content_iv= */ + absl::StrCat(kEvenContentIv8Bytes, kEvenContentIv8Bytes), + /* odd_key= */ kOddKey, + /* odd_content_iv= */ + absl::StrCat(kOddContentIv8Bytes, kOddContentIv8Bytes), + /* entitlement_key_id= */ kEntitlementKeyId, + /* entitlement_key= */ kEntitlementKey, &actual_ecm)); + + EXPECT_EQ( + "4ad40107c0656e745f6b65795f69642e2e2e2e2e2ea5693deeba52b4cb27e7021eefa2f8" + "c2b25f7d48e60627208f4ecca00703aa2467f28b214546a42320e3fa49f936369c657665" + "6e636f6e746576656e636f6e74656e745f6b65795f69642e2e2e2e2e2e0700509b67763b" + "3f1c356bc1e1dc8bac99a1e2f95c37d9183cbb96582f3a05fdbe29925c37c6c6a45eb552" + "b5ddf87f8a6f6464636f6e742e6f6464636f6e742e", + absl::BytesToHexString(actual_ecm)); +} + +TEST_F(WvCasEcmTest, GenerateSingleKeyEcm16BytesContentIvCsaSuccess) { + EXPECT_EQ(OK, wv_cas_ecm_.Initialize(/* content_iv_size= */ 16, + /* key_rotation_enabled= */ false, + CryptoMode::kDvbCsa)); + + std::string actual_ecm; + EXPECT_EQ(OK, wv_cas_ecm_.GenerateSingleKeyEcm( + /* even_key= */ kEvenKey, + /* even_content_iv= */ + absl::StrCat(kEvenContentIv8Bytes, kEvenContentIv8Bytes), + /* entitlement_key_id= */ kEntitlementKeyId, + /* entitlement_key= */ kEntitlementKey, &actual_ecm)); + + EXPECT_EQ( + "4ad40106c0656e745f6b65795f69642e2e2e2e2e2ea5693deeba52b4cb27e7021eefa2f8" + "c2b25f7d48e60627208f4ecca00703aa2467f28b214546a42320e3fa49f936369c657665" + "6e636f6e746576656e636f6e74", + absl::BytesToHexString(actual_ecm)); +} + } // namespace cas } // namespace widevine diff --git a/media_cas_packager_sdk/public/wv_cas_status.cc b/media_cas_packager_sdk/public/wv_cas_types.cc similarity index 63% rename from media_cas_packager_sdk/public/wv_cas_status.cc rename to media_cas_packager_sdk/public/wv_cas_types.cc index 984632f..503e7f1 100644 --- a/media_cas_packager_sdk/public/wv_cas_status.cc +++ b/media_cas_packager_sdk/public/wv_cas_types.cc @@ -6,7 +6,7 @@ // widevine-licensing@google.com. //////////////////////////////////////////////////////////////////////////////// -#include "media_cas_packager_sdk/public/wv_cas_status.h" +#include "media_cas_packager_sdk/public/wv_cas_types.h" #include "base/macros.h" @@ -37,5 +37,35 @@ std::string GetWvCasStatusMessage(WvCasStatus status) { return kWvCasStatusMessage[status]; } +std::string CryptoModeToString(CryptoMode mode) { + switch (mode) { + case CryptoMode::kAesCtr: { + return "kAesCtr"; + } + case CryptoMode::kAesCbc: { + return "kAesCbc"; + } + case CryptoMode::kDvbCsa: { + return "kDvbCsa"; + } + default: { + return "kCryptoModeUnspecified"; + } + } +} + +CryptoMode StringToCryptoMode(std::string str) { + if (str == "kAesCtr") { + return CryptoMode::kAesCtr; + } + if (str == "kAesCbc") { + return CryptoMode::kAesCbc; + } + if (str == "kDvbCsa") { + return CryptoMode::kDvbCsa; + } + return CryptoMode::kCryptoModeUnspecified; +} + } // namespace cas } // namespace widevine diff --git a/media_cas_packager_sdk/public/wv_cas_status.h b/media_cas_packager_sdk/public/wv_cas_types.h similarity index 77% rename from media_cas_packager_sdk/public/wv_cas_status.h rename to media_cas_packager_sdk/public/wv_cas_types.h index 99e49f6..63977c9 100644 --- a/media_cas_packager_sdk/public/wv_cas_status.h +++ b/media_cas_packager_sdk/public/wv_cas_types.h @@ -6,8 +6,8 @@ // widevine-licensing@google.com. //////////////////////////////////////////////////////////////////////////////// -#ifndef MEDIA_CAS_PACKAGER_SDK_PUBLIC_WV_CAS_STATUS_H_ -#define MEDIA_CAS_PACKAGER_SDK_PUBLIC_WV_CAS_STATUS_H_ +#ifndef MEDIA_CAS_PACKAGER_SDK_PUBLIC_WV_CAS_TYPES_H_ +#define MEDIA_CAS_PACKAGER_SDK_PUBLIC_WV_CAS_TYPES_H_ #include @@ -50,7 +50,19 @@ enum WvCasStatus { // Returns the message std::string for the given WvCasStatus. std::string GetWvCasStatusMessage(WvCasStatus status); +// Crypto mode for encryption / decryption. +enum class CryptoMode : int { + kCryptoModeUnspecified = 0, + kAesCtr = 1, + kAesCbc = 2, + kDvbCsa = 3 +}; + +std::string CryptoModeToString(CryptoMode mode); + +CryptoMode StringToCryptoMode(std::string str); + } // namespace cas } // namespace widevine -#endif // MEDIA_CAS_PACKAGER_SDK_PUBLIC_WV_CAS_STATUS_H_ +#endif // MEDIA_CAS_PACKAGER_SDK_PUBLIC_WV_CAS_TYPES_H_ diff --git a/media_cas_packager_sdk/public/wv_cas_status_test.cc b/media_cas_packager_sdk/public/wv_cas_types_test.cc similarity index 55% rename from media_cas_packager_sdk/public/wv_cas_status_test.cc rename to media_cas_packager_sdk/public/wv_cas_types_test.cc index 511310e..61fd383 100644 --- a/media_cas_packager_sdk/public/wv_cas_status_test.cc +++ b/media_cas_packager_sdk/public/wv_cas_types_test.cc @@ -6,14 +6,14 @@ // widevine-licensing@google.com. //////////////////////////////////////////////////////////////////////////////// -#include "media_cas_packager_sdk/public/wv_cas_status.h" +#include "media_cas_packager_sdk/public/wv_cas_types.h" #include "testing/gunit.h" namespace widevine { namespace cas { -TEST(WvCasStatusTest, GetWvCasStatusMessage) { +TEST(WvCasTypesTest, GetWvCasStatusMessage) { EXPECT_EQ("OK", GetWvCasStatusMessage(OK)); EXPECT_EQ("Invalid argument", GetWvCasStatusMessage(INVALID_ARGUMENT)); EXPECT_EQ("Not found", GetWvCasStatusMessage(NOT_FOUND)); @@ -24,5 +24,21 @@ TEST(WvCasStatusTest, GetWvCasStatusMessage) { EXPECT_EQ("Unavailable", GetWvCasStatusMessage(UNAVAILABLE)); } +TEST(WvCasTypesTest, CryptoModeToString) { + EXPECT_EQ("kAesCtr", CryptoModeToString(CryptoMode::kAesCtr)); + EXPECT_EQ("kAesCbc", CryptoModeToString(CryptoMode::kAesCbc)); + EXPECT_EQ("kDvbCsa", CryptoModeToString(CryptoMode::kDvbCsa)); + EXPECT_EQ("kCryptoModeUnspecified", + CryptoModeToString(CryptoMode::kCryptoModeUnspecified)); +} + +TEST(WvCasTypesTest, StringToCryptoMode) { + EXPECT_EQ(CryptoMode::kAesCtr, StringToCryptoMode("kAesCtr")); + EXPECT_EQ(CryptoMode::kAesCbc, StringToCryptoMode("kAesCbc")); + EXPECT_EQ(CryptoMode::kDvbCsa, StringToCryptoMode("kDvbCsa")); + EXPECT_EQ(CryptoMode::kCryptoModeUnspecified, + StringToCryptoMode("wrong crypto mode")); +} + } // namespace cas } // namespace widevine