diff --git a/media/base/encryptor_source.cc b/media/base/encryptor_source.cc index 593611fc0e..9201fb45f5 100644 --- a/media/base/encryptor_source.cc +++ b/media/base/encryptor_source.cc @@ -4,19 +4,36 @@ #include "media/base/encryptor_source.h" +#include "media/base/aes_encryptor.h" + namespace { -const char kWidevineSystemId[] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6, - 0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc, - 0xd5, 0x1d, 0x21, 0xed}; +// Generate 64bit IV by default. +const size_t kDefaultIvSize = 8u; + +const uint8 kWidevineSystemId[] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6, + 0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc, + 0xd5, 0x1d, 0x21, 0xed}; } // namespace namespace media { EncryptorSource::EncryptorSource() - : key_system_id_(kWidevineSystemId, - kWidevineSystemId + arraysize(kWidevineSystemId)), - clear_milliseconds_(0) {} + : iv_size_(kDefaultIvSize), + key_system_id_(kWidevineSystemId, + kWidevineSystemId + arraysize(kWidevineSystemId)) {} EncryptorSource::~EncryptorSource() {} +scoped_ptr EncryptorSource::CreateEncryptor() { + scoped_ptr encryptor(new AesCtrEncryptor()); + const bool initialized = + iv_.empty() ? encryptor->InitializeWithRandomIv(key_, iv_size_) + : encryptor->InitializeWithIv(key_, iv_); + if (!initialized) { + LOG(ERROR) << "Failed to the initialize encryptor."; + return scoped_ptr(); + } + return encryptor.Pass(); +} + } // namespace media diff --git a/media/base/encryptor_source.h b/media/base/encryptor_source.h index 7f1623f72f..cf9a3835cc 100644 --- a/media/base/encryptor_source.h +++ b/media/base/encryptor_source.h @@ -15,45 +15,51 @@ namespace media { +class AesCtrEncryptor; + class EncryptorSource { public: EncryptorSource(); virtual ~EncryptorSource(); + // Initialize the encryptor source. Calling other public methods of this + // class without this method returning Status::OK, results in an undefined + // behavior. virtual Status Initialize() = 0; - // Refreshes the encryptor. NOP except for key rotation encryptor source. + // Refresh the encryptor. NOP except for key rotation encryptor source. // TODO(kqyang): Do we need to pass in duration or fragment number? virtual void RefreshEncryptor() {} - // EncryptorSource retains the ownership of |encryptor_|. - AesCtrEncryptor* encryptor() { return encryptor_.get(); } + // Create an encryptor from this encryptor source. The encryptor will be + // initialized with a random IV of the default size by default. The behavior + // can be adjusted using set_iv_size or set_iv (exclusive). + scoped_ptr CreateEncryptor(); + const std::vector& key_id() const { return key_id_; } const std::vector& key() const { return key_; } const std::vector& pssh() const { return pssh_; } - uint32 clear_milliseconds() const { return clear_milliseconds_; } const std::vector& key_system_id() const { return key_system_id_; } + size_t iv_size() const { return iv_.empty() ? iv_size_ : iv_.size(); } + + // Set IV size. The encryptor will be initialized with a random IV of the + // specified size. Mutally exclusive with set_iv. + void set_iv_size(size_t iv_size) { iv_size_ = iv_size; } + // Set IV. The encryptor will be initialized with the specified IV. + // Mutally exclusive with set_iv_size. + void set_iv(std::vector& iv) { iv_ = iv; } protected: - // EncryptorSource takes ownership of |encryptor|. - void set_encryptor(scoped_ptr encryptor) { - encryptor_ = encryptor.Pass(); - } void set_key_id(const std::vector& key_id) { key_id_ = key_id; } void set_key(const std::vector& key) { key_ = key; } void set_pssh(const std::vector& pssh) { pssh_ = pssh; } - void set_clear_milliseconds(uint32 clear_milliseconds) { - clear_milliseconds_ = clear_milliseconds; - } private: - scoped_ptr encryptor_; std::vector key_id_; std::vector key_; std::vector pssh_; - // The first |clear_milliseconds_| of the result media should be in the clear - // text, i.e. should not be encrypted. - uint32 clear_milliseconds_; + size_t iv_size_; + std::vector iv_; const std::vector key_system_id_; DISALLOW_COPY_AND_ASSIGN(EncryptorSource); diff --git a/media/base/fixed_encryptor_source.cc b/media/base/fixed_encryptor_source.cc index 265a931215..6d4fecb259 100644 --- a/media/base/fixed_encryptor_source.cc +++ b/media/base/fixed_encryptor_source.cc @@ -6,24 +6,13 @@ #include "base/logging.h" #include "base/strings/string_number_conversions.h" -#include "media/base/aes_encryptor.h" - -namespace { -// The size of generated IV for this encryptor source. -const uint8 kIvSize = 8; -} // namespace namespace media { FixedEncryptorSource::FixedEncryptorSource(const std::string& key_id_hex, const std::string& key_hex, - const std::string& pssh_hex, - uint32 clear_milliseconds) - : key_id_hex_(key_id_hex), - key_hex_(key_hex), - pssh_hex_(pssh_hex) { - set_clear_milliseconds(clear_milliseconds); -} + const std::string& pssh_hex) + : key_id_hex_(key_id_hex), key_hex_(key_hex), pssh_hex_(pssh_hex) {} FixedEncryptorSource::~FixedEncryptorSource() {} @@ -46,11 +35,6 @@ Status FixedEncryptorSource::Initialize() { return Status(error::INVALID_ARGUMENT, "Cannot parse input pssh_hex."); } - scoped_ptr encryptor(new AesCtrEncryptor()); - if (!encryptor->InitializeWithRandomIv(key, kIvSize)) - return Status(error::UNKNOWN, "Failed to initialize the encryptor."); - - set_encryptor(encryptor.Pass()); set_key_id(key_id); set_key(key); set_pssh(pssh); diff --git a/media/base/fixed_encryptor_source.h b/media/base/fixed_encryptor_source.h index 85ffa2d245..50ada38d9a 100644 --- a/media/base/fixed_encryptor_source.h +++ b/media/base/fixed_encryptor_source.h @@ -15,8 +15,7 @@ class FixedEncryptorSource : public EncryptorSource { public: FixedEncryptorSource(const std::string& key_id_hex, const std::string& key_hex, - const std::string& pssh_hex, - uint32 clear_milliseconds); + const std::string& pssh_hex); virtual ~FixedEncryptorSource(); // EncryptorSource implementation. diff --git a/media/base/widevine_encryptor_source.cc b/media/base/widevine_encryptor_source.cc index e9f8eef418..697dae2bf8 100644 --- a/media/base/widevine_encryptor_source.cc +++ b/media/base/widevine_encryptor_source.cc @@ -25,9 +25,6 @@ namespace { -// The size of generated IV for this encryptor source. -const uint8 kIvSize = 8; - bool Base64StringToBytes(const std::string& base64_string, std::vector* bytes) { DCHECK(bytes); @@ -117,7 +114,7 @@ bool WidevineEncryptorSource::SetAesSigningKey(const std::string& signer, } scoped_ptr encryptor(new AesCbcEncryptor()); - if (!encryptor->Initialize(aes_key, iv)) { + if (!encryptor->InitializeWithIv(aes_key, iv)) { LOG(ERROR) << "Failed to initialize encryptor with key: " << aes_key_hex << " iv:" << iv_hex; return false; @@ -166,11 +163,6 @@ Status WidevineEncryptorSource::Initialize() { "Failed to extract encryption key from '" + response + "'."); } - // TODO(kqyang): Move the creation of encryptor to Muxer. - scoped_ptr encryptor(new AesCtrEncryptor()); - CHECK(encryptor->InitializeWithRandomIv(key, kIvSize)); - - set_encryptor(encryptor.Pass()); set_key_id(key_id); set_key(key); set_pssh(pssh);