Use FOURCC as protection scheme parameter
- Remove EncryptionMode enums - Remove AesEncryptor::InitializeWithRandomIv, replaced with a static function AesCryptor::GenerateRandomIv, which should be called to generate the iv if the iv is empty. This change is to prepare support for CBCS and CENS pattern-based protection schemes. Issue #77 Change-Id: Icba35089d6e451cbea7ebbf5dd5674079f206390
This commit is contained in:
parent
0218d9c690
commit
2ac57bf9b9
|
@ -25,7 +25,7 @@
|
|||
#include "packager/base/time/clock.h"
|
||||
#include "packager/media/base/container_names.h"
|
||||
#include "packager/media/base/demuxer.h"
|
||||
#include "packager/media/base/encryption_modes.h"
|
||||
#include "packager/media/base/fourccs.h"
|
||||
#include "packager/media/base/key_source.h"
|
||||
#include "packager/media/base/muxer_options.h"
|
||||
#include "packager/media/base/muxer_util.h"
|
||||
|
@ -105,15 +105,19 @@ std::string DetermineTextFileFormat(const std::string& file) {
|
|||
return "";
|
||||
}
|
||||
|
||||
edash_packager::media::EncryptionMode GetEncryptionMode(
|
||||
edash_packager::media::FourCC GetProtectionScheme(
|
||||
const std::string& protection_scheme) {
|
||||
if (protection_scheme == "cenc") {
|
||||
return edash_packager::media::kEncryptionModeAesCtr;
|
||||
return edash_packager::media::FOURCC_cenc;
|
||||
} else if (protection_scheme == "cens") {
|
||||
return edash_packager::media::FOURCC_cens;
|
||||
} else if (protection_scheme == "cbc1") {
|
||||
return edash_packager::media::kEncryptionModeAesCbc;
|
||||
return edash_packager::media::FOURCC_cbc1;
|
||||
} else if (protection_scheme == "cbcs") {
|
||||
return edash_packager::media::FOURCC_cbcs;
|
||||
} else {
|
||||
LOG(ERROR) << "Unknown protection scheme: " << protection_scheme;
|
||||
return edash_packager::media::kEncryptionModeUnknown;
|
||||
return edash_packager::media::FOURCC_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,7 +314,7 @@ bool CreateRemuxJobs(const StreamDescriptorList& stream_descriptors,
|
|||
FLAGS_max_sd_pixels,
|
||||
FLAGS_clear_lead,
|
||||
FLAGS_crypto_period_duration,
|
||||
GetEncryptionMode(FLAGS_protection_scheme));
|
||||
GetProtectionScheme(FLAGS_protection_scheme));
|
||||
}
|
||||
|
||||
scoped_ptr<MuxerListener> muxer_listener;
|
||||
|
@ -374,11 +378,11 @@ Status RunRemuxJobs(const std::vector<RemuxJob*>& remux_jobs) {
|
|||
}
|
||||
|
||||
bool RunPackager(const StreamDescriptorList& stream_descriptors) {
|
||||
EncryptionMode encryption_mode = GetEncryptionMode(FLAGS_protection_scheme);
|
||||
if (encryption_mode == kEncryptionModeUnknown)
|
||||
const FourCC protection_scheme = GetProtectionScheme(FLAGS_protection_scheme);
|
||||
if (protection_scheme == FOURCC_NULL)
|
||||
return false;
|
||||
if (encryption_mode == kEncryptionModeAesCbc && !FLAGS_iv.empty()) {
|
||||
if (FLAGS_iv.size() != 16) {
|
||||
if (protection_scheme == FOURCC_cbc1 || protection_scheme == FOURCC_cbcs) {
|
||||
if (!FLAGS_iv.empty() && FLAGS_iv.size() != 16) {
|
||||
LOG(ERROR) << "Iv size should be 16 bytes for CBC encryption mode.";
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "packager/media/base/aes_cryptor.h"
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/base/stl_util.h"
|
||||
|
@ -53,6 +55,25 @@ size_t AesCryptor::NumPaddingBytes(size_t size) const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool AesCryptor::GenerateRandomIv(FourCC protection_scheme,
|
||||
std::vector<uint8_t>* iv) {
|
||||
// ISO/IEC 23001-7:2016 10.1 and 10.3 For 'cenc' and 'cens'
|
||||
// default_Per_Sample_IV_Size and Per_Sample_IV_Size SHOULD be 8-bytes.
|
||||
// There is no official guideline on the iv size for 'cbc1' and 'cbcs',
|
||||
// but 16-byte provides better security.
|
||||
const size_t iv_size =
|
||||
(protection_scheme == FOURCC_cenc || protection_scheme == FOURCC_cens)
|
||||
? 8
|
||||
: 16;
|
||||
iv->resize(iv_size);
|
||||
if (RAND_bytes(iv->data(), iv_size) != 1) {
|
||||
LOG(ERROR) << "RAND_bytes failed with error: "
|
||||
<< ERR_error_string(ERR_get_error(), NULL);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace media
|
||||
} // namespace edash_packager
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "packager/base/macros.h"
|
||||
#include "packager/base/memory/scoped_ptr.h"
|
||||
#include "packager/media/base/fourccs.h"
|
||||
|
||||
struct aes_key_st;
|
||||
typedef struct aes_key_st AES_KEY;
|
||||
|
@ -58,6 +59,13 @@ class AesCryptor {
|
|||
/// @return The current iv.
|
||||
const std::vector<uint8_t>& iv() const { return iv_; }
|
||||
|
||||
/// @param protection_scheme specifies the protection scheme: 'cenc', 'cens',
|
||||
/// 'cbc1', 'cbcs', which is useful to determine the random iv size.
|
||||
/// @param iv points to generated initialization vector.
|
||||
/// @return true on success, false otherwise.
|
||||
static bool GenerateRandomIv(FourCC protection_scheme,
|
||||
std::vector<uint8_t>* iv);
|
||||
|
||||
protected:
|
||||
void set_iv(const std::vector<uint8_t>& iv) { iv_ = iv; }
|
||||
const AES_KEY* aes_key() const { return aes_key_.get(); }
|
||||
|
|
|
@ -220,12 +220,12 @@ TEST_F(AesCtrEncryptorTest, 128BitIVBoundaryCaseEncryption) {
|
|||
EXPECT_EQ(encrypted, encrypted_verify);
|
||||
}
|
||||
|
||||
TEST_F(AesCtrEncryptorTest, InitWithRandomIv) {
|
||||
const uint8_t kIvSize = 8;
|
||||
ASSERT_TRUE(encryptor_.InitializeWithRandomIv(key_, kIvSize));
|
||||
ASSERT_EQ(kIvSize, encryptor_.iv().size());
|
||||
LOG(INFO) << "Random IV: "
|
||||
<< base::HexEncode(&encryptor_.iv()[0], encryptor_.iv().size());
|
||||
TEST_F(AesCtrEncryptorTest, GenerateRandomIv) {
|
||||
const uint8_t kCencIvSize = 8;
|
||||
std::vector<uint8_t> iv;
|
||||
ASSERT_TRUE(AesCryptor::GenerateRandomIv(FOURCC_cenc, &iv));
|
||||
ASSERT_EQ(kCencIvSize, iv.size());
|
||||
LOG(INFO) << "Random IV: " << base::HexEncode(iv.data(), iv.size());
|
||||
}
|
||||
|
||||
TEST_F(AesCtrEncryptorTest, UnsupportedKeySize) {
|
||||
|
@ -238,10 +238,6 @@ TEST_F(AesCtrEncryptorTest, UnsupportedIV) {
|
|||
ASSERT_FALSE(encryptor_.InitializeWithIv(key_, iv));
|
||||
}
|
||||
|
||||
TEST_F(AesCtrEncryptorTest, IncorrectIvSize) {
|
||||
ASSERT_FALSE(encryptor_.InitializeWithRandomIv(key_, 15));
|
||||
}
|
||||
|
||||
class AesCtrEncryptorSubsampleTest
|
||||
: public AesCtrEncryptorTest,
|
||||
public ::testing::WithParamInterface<SubsampleTestCase> {};
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
#include "packager/media/base/aes_encryptor.h"
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
|
||||
|
@ -40,17 +38,6 @@ namespace media {
|
|||
AesEncryptor::AesEncryptor() {}
|
||||
AesEncryptor::~AesEncryptor() {}
|
||||
|
||||
bool AesEncryptor::InitializeWithRandomIv(const std::vector<uint8_t>& key,
|
||||
uint8_t iv_size) {
|
||||
std::vector<uint8_t> iv(iv_size, 0);
|
||||
if (RAND_bytes(iv.data(), iv_size) != 1) {
|
||||
LOG(ERROR) << "RAND_bytes failed with error: "
|
||||
<< ERR_error_string(ERR_get_error(), NULL);
|
||||
return false;
|
||||
}
|
||||
return InitializeWithIv(key, iv);
|
||||
}
|
||||
|
||||
bool AesEncryptor::InitializeWithIv(const std::vector<uint8_t>& key,
|
||||
const std::vector<uint8_t>& iv) {
|
||||
if (!IsKeySizeValidForAes(key.size())) {
|
||||
|
|
|
@ -24,11 +24,6 @@ class AesEncryptor : public AesCryptor {
|
|||
AesEncryptor();
|
||||
~AesEncryptor() override;
|
||||
|
||||
/// Initialize the encryptor with specified key and a random generated IV
|
||||
/// of the specified size.
|
||||
/// @return true on successful initialization, false otherwise.
|
||||
bool InitializeWithRandomIv(const std::vector<uint8_t>& key, uint8_t iv_size);
|
||||
|
||||
/// Initialize the encryptor with specified key and IV.
|
||||
/// @return true on successful initialization, false otherwise.
|
||||
bool InitializeWithIv(const std::vector<uint8_t>& key,
|
||||
|
|
|
@ -9,14 +9,19 @@
|
|||
namespace edash_packager {
|
||||
namespace media {
|
||||
|
||||
DecryptConfig::DecryptConfig(const std::vector<uint8_t>& key_id,
|
||||
const std::vector<uint8_t>& iv,
|
||||
const std::vector<SubsampleEntry>& subsamples)
|
||||
: DecryptConfig(key_id, iv, subsamples, FOURCC_cenc) {}
|
||||
|
||||
DecryptConfig::DecryptConfig(const std::vector<uint8_t>& key_id,
|
||||
const std::vector<uint8_t>& iv,
|
||||
const std::vector<SubsampleEntry>& subsamples,
|
||||
EncryptionMode decryption_mode)
|
||||
FourCC protection_scheme)
|
||||
: key_id_(key_id),
|
||||
iv_(iv),
|
||||
subsamples_(subsamples),
|
||||
decryption_mode_(decryption_mode) {
|
||||
protection_scheme_(protection_scheme) {
|
||||
CHECK_GT(key_id.size(), 0u);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "packager/base/memory/scoped_ptr.h"
|
||||
#include "packager/media/base/encryption_modes.h"
|
||||
#include "packager/media/base/fourccs.h"
|
||||
|
||||
namespace edash_packager {
|
||||
namespace media {
|
||||
|
@ -42,23 +42,35 @@ class DecryptConfig {
|
|||
/// Keys are always 128 bits.
|
||||
static const size_t kDecryptionKeySize = 16;
|
||||
|
||||
/// Create a 'cenc' decrypt config.
|
||||
/// @param key_id is the ID that references the decryption key.
|
||||
/// @param iv is the initialization vector defined by the encryptor.
|
||||
/// @param subsamples defines the clear and encrypted portions of the sample
|
||||
/// as described in SubsampleEntry. A decrypted buffer will be equal
|
||||
/// in size to the sum of the subsample sizes.
|
||||
/// @param decryption_mode decryption_mode is to determine which decryptor to
|
||||
/// use.
|
||||
DecryptConfig(const std::vector<uint8_t>& key_id,
|
||||
const std::vector<uint8_t>& iv,
|
||||
const std::vector<SubsampleEntry>& subsamples);
|
||||
|
||||
/// Create a general decrypt config with possible pattern-based encryption.
|
||||
/// @param key_id is the ID that references the decryption key.
|
||||
/// @param iv is the initialization vector defined by the encryptor.
|
||||
/// @param subsamples defines the clear and encrypted portions of the sample
|
||||
/// as described in SubsampleEntry. A decrypted buffer will be equal
|
||||
/// in size to the sum of the subsample sizes.
|
||||
/// @param protection_scheme specifies the protection scheme: 'cenc', 'cens',
|
||||
/// 'cbc1', 'cbcs'.
|
||||
DecryptConfig(const std::vector<uint8_t>& key_id,
|
||||
const std::vector<uint8_t>& iv,
|
||||
const std::vector<SubsampleEntry>& subsamples,
|
||||
EncryptionMode decryption_mode);
|
||||
FourCC protection_scheme);
|
||||
|
||||
~DecryptConfig();
|
||||
|
||||
const std::vector<uint8_t>& key_id() const { return key_id_; }
|
||||
const std::vector<uint8_t>& iv() const { return iv_; }
|
||||
const std::vector<SubsampleEntry>& subsamples() const { return subsamples_; }
|
||||
EncryptionMode decryption_mode() const { return decryption_mode_; }
|
||||
FourCC protection_scheme() const { return protection_scheme_; }
|
||||
|
||||
private:
|
||||
const std::vector<uint8_t> key_id_;
|
||||
|
@ -70,7 +82,7 @@ class DecryptConfig {
|
|||
// (less data ignored by data_offset_) is encrypted.
|
||||
const std::vector<SubsampleEntry> subsamples_;
|
||||
|
||||
EncryptionMode decryption_mode_;
|
||||
const FourCC protection_scheme_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(DecryptConfig);
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/base/stl_util.h"
|
||||
#include "packager/media/base/aes_decryptor.h"
|
||||
|
||||
namespace edash_packager {
|
||||
namespace media {
|
||||
|
@ -39,16 +40,16 @@ bool DecryptorSource::DecryptSampleBuffer(const DecryptConfig* decrypt_config,
|
|||
}
|
||||
|
||||
scoped_ptr<AesCryptor> aes_decryptor;
|
||||
switch (decrypt_config->decryption_mode()) {
|
||||
case kEncryptionModeAesCtr:
|
||||
switch (decrypt_config->protection_scheme()) {
|
||||
case FOURCC_cenc:
|
||||
aes_decryptor.reset(new AesCtrDecryptor);
|
||||
break;
|
||||
case kEncryptionModeAesCbc:
|
||||
case FOURCC_cbc1:
|
||||
aes_decryptor.reset(new AesCbcDecryptor(kNoPadding, kChainAcrossCalls));
|
||||
break;
|
||||
default:
|
||||
LOG(ERROR) << "Unsupported Decryption Mode: "
|
||||
<< decrypt_config->decryption_mode();
|
||||
LOG(ERROR) << "Unsupported protection scheme: "
|
||||
<< decrypt_config->protection_scheme();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,10 +81,9 @@ TEST_F(DecryptorSourceTest, FullSampleDecryption) {
|
|||
|
||||
DecryptConfig decrypt_config(key_id_,
|
||||
std::vector<uint8_t>(kIv, kIv + arraysize(kIv)),
|
||||
std::vector<SubsampleEntry>(),
|
||||
kEncryptionModeAesCtr);
|
||||
ASSERT_TRUE(decryptor_source_.DecryptSampleBuffer(&decrypt_config, &buffer_[0],
|
||||
buffer_.size()));
|
||||
std::vector<SubsampleEntry>());
|
||||
ASSERT_TRUE(decryptor_source_.DecryptSampleBuffer(
|
||||
&decrypt_config, &buffer_[0], buffer_.size()));
|
||||
EXPECT_EQ(std::vector<uint8_t>(
|
||||
kExpectedDecryptedBuffer,
|
||||
kExpectedDecryptedBuffer + arraysize(kExpectedDecryptedBuffer)),
|
||||
|
@ -95,7 +94,7 @@ TEST_F(DecryptorSourceTest, FullSampleDecryption) {
|
|||
buffer_.assign(kBuffer2, kBuffer2 + arraysize(kBuffer2));
|
||||
DecryptConfig decrypt_config2(
|
||||
key_id_, std::vector<uint8_t>(kIv2, kIv2 + arraysize(kIv2)),
|
||||
std::vector<SubsampleEntry>(), kEncryptionModeAesCtr);
|
||||
std::vector<SubsampleEntry>());
|
||||
ASSERT_TRUE(decryptor_source_.DecryptSampleBuffer(
|
||||
&decrypt_config2, &buffer_[0], buffer_.size()));
|
||||
EXPECT_EQ(std::vector<uint8_t>(kExpectedDecryptedBuffer2,
|
||||
|
@ -130,8 +129,7 @@ TEST_F(DecryptorSourceTest, SubsampleDecryption) {
|
|||
DecryptConfig decrypt_config(
|
||||
key_id_, std::vector<uint8_t>(kIv, kIv + arraysize(kIv)),
|
||||
std::vector<SubsampleEntry>(kSubsamples,
|
||||
kSubsamples + arraysize(kSubsamples)),
|
||||
kEncryptionModeAesCtr);
|
||||
kSubsamples + arraysize(kSubsamples)));
|
||||
ASSERT_TRUE(decryptor_source_.DecryptSampleBuffer(
|
||||
&decrypt_config, &buffer_[0], buffer_.size()));
|
||||
EXPECT_EQ(std::vector<uint8_t>(
|
||||
|
@ -155,8 +153,7 @@ TEST_F(DecryptorSourceTest, SubsampleDecryptionSizeValidation) {
|
|||
DecryptConfig decrypt_config(
|
||||
key_id_, std::vector<uint8_t>(kIv, kIv + arraysize(kIv)),
|
||||
std::vector<SubsampleEntry>(kSubsamples,
|
||||
kSubsamples + arraysize(kSubsamples)),
|
||||
kEncryptionModeAesCtr);
|
||||
kSubsamples + arraysize(kSubsamples)));
|
||||
ASSERT_FALSE(decryptor_source_.DecryptSampleBuffer(
|
||||
&decrypt_config, &buffer_[0], buffer_.size()));
|
||||
}
|
||||
|
@ -167,8 +164,7 @@ TEST_F(DecryptorSourceTest, DecryptFailedIfGetKeyFailed) {
|
|||
|
||||
DecryptConfig decrypt_config(key_id_,
|
||||
std::vector<uint8_t>(kIv, kIv + arraysize(kIv)),
|
||||
std::vector<SubsampleEntry>(),
|
||||
kEncryptionModeAesCtr);
|
||||
std::vector<SubsampleEntry>());
|
||||
ASSERT_FALSE(decryptor_source_.DecryptSampleBuffer(
|
||||
&decrypt_config, &buffer_[0], buffer_.size()));
|
||||
}
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
#ifndef MEDIA_BASE_ENCRYPTION_MODE_H_
|
||||
#define MEDIA_BASE_ENCRYPTION_MODE_H_
|
||||
|
||||
namespace edash_packager {
|
||||
namespace media {
|
||||
|
||||
/// Supported encryption mode.
|
||||
enum EncryptionMode {
|
||||
kEncryptionModeUnknown,
|
||||
kEncryptionModeAesCtr,
|
||||
kEncryptionModeAesCbc
|
||||
};
|
||||
|
||||
} // namespace media
|
||||
} // namespace edash_packager
|
||||
|
||||
#endif // MEDIA_BASE_ENCRYPTION_MODE_H_
|
|
@ -21,7 +21,9 @@ enum FourCC {
|
|||
FOURCC_avcC = 0x61766343,
|
||||
FOURCC_bloc = 0x626C6F63,
|
||||
FOURCC_cbc1 = 0x63626331,
|
||||
FOURCC_cbcs = 0x63626373,
|
||||
FOURCC_cenc = 0x63656e63,
|
||||
FOURCC_cens = 0x63656e73,
|
||||
FOURCC_co64 = 0x636f3634,
|
||||
FOURCC_ctim = 0x6374696d,
|
||||
FOURCC_ctts = 0x63747473,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "packager/media/base/muxer.h"
|
||||
|
||||
#include "packager/media/base/fourccs.h"
|
||||
#include "packager/media/base/media_sample.h"
|
||||
#include "packager/media/base/media_stream.h"
|
||||
|
||||
|
@ -19,7 +20,7 @@ Muxer::Muxer(const MuxerOptions& options)
|
|||
max_sd_pixels_(0),
|
||||
clear_lead_in_seconds_(0),
|
||||
crypto_period_duration_in_seconds_(0),
|
||||
encryption_mode_(kEncryptionModeUnknown),
|
||||
protection_scheme_(FOURCC_NULL),
|
||||
cancelled_(false),
|
||||
clock_(NULL) {}
|
||||
|
||||
|
@ -29,13 +30,13 @@ void Muxer::SetKeySource(KeySource* encryption_key_source,
|
|||
uint32_t max_sd_pixels,
|
||||
double clear_lead_in_seconds,
|
||||
double crypto_period_duration_in_seconds,
|
||||
EncryptionMode encryption_mode) {
|
||||
FourCC protection_scheme) {
|
||||
DCHECK(encryption_key_source);
|
||||
encryption_key_source_ = encryption_key_source;
|
||||
max_sd_pixels_ = max_sd_pixels;
|
||||
clear_lead_in_seconds_ = clear_lead_in_seconds;
|
||||
crypto_period_duration_in_seconds_ = crypto_period_duration_in_seconds;
|
||||
encryption_mode_ = encryption_mode;
|
||||
protection_scheme_ = protection_scheme;
|
||||
}
|
||||
|
||||
void Muxer::AddStream(MediaStream* stream) {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "packager/base/memory/ref_counted.h"
|
||||
#include "packager/base/memory/scoped_ptr.h"
|
||||
#include "packager/base/time/clock.h"
|
||||
#include "packager/media/base/encryption_modes.h"
|
||||
#include "packager/media/base/fourccs.h"
|
||||
#include "packager/media/base/muxer_options.h"
|
||||
#include "packager/media/base/status.h"
|
||||
#include "packager/media/event/muxer_listener.h"
|
||||
|
@ -45,11 +45,13 @@ class Muxer {
|
|||
/// @param crypto_period_duration_in_seconds specifies crypto period duration
|
||||
/// in seconds. A positive value means key rotation is enabled, the
|
||||
/// key source must support key rotation in this case.
|
||||
/// @param protection_scheme specifies the protection scheme: 'cenc', 'cens',
|
||||
/// 'cbc1', 'cbcs'.
|
||||
void SetKeySource(KeySource* encryption_key_source,
|
||||
uint32_t max_sd_pixels,
|
||||
double clear_lead_in_seconds,
|
||||
double crypto_period_duration_in_seconds,
|
||||
EncryptionMode encryption_mode);
|
||||
FourCC protection_scheme);
|
||||
|
||||
/// Add video/audio stream.
|
||||
void AddStream(MediaStream* stream);
|
||||
|
@ -94,7 +96,7 @@ class Muxer {
|
|||
MuxerListener* muxer_listener() { return muxer_listener_.get(); }
|
||||
ProgressListener* progress_listener() { return progress_listener_.get(); }
|
||||
base::Clock* clock() { return clock_; }
|
||||
EncryptionMode encryption_mode() const { return encryption_mode_; }
|
||||
FourCC protection_scheme() const { return protection_scheme_; }
|
||||
|
||||
private:
|
||||
friend class MediaStream; // Needed to access AddSample.
|
||||
|
@ -120,7 +122,7 @@ class Muxer {
|
|||
uint32_t max_sd_pixels_;
|
||||
double clear_lead_in_seconds_;
|
||||
double crypto_period_duration_in_seconds_;
|
||||
EncryptionMode encryption_mode_;
|
||||
FourCC protection_scheme_;
|
||||
bool cancelled_;
|
||||
|
||||
scoped_ptr<MuxerListener> muxer_listener_;
|
||||
|
|
|
@ -22,9 +22,6 @@ namespace media {
|
|||
namespace mp4 {
|
||||
|
||||
namespace {
|
||||
// Generate 64bit IV by default.
|
||||
const size_t kDefaultIvSizeForCtr = 8u;
|
||||
const size_t kDefaultIvSizeForCbc = 16u;
|
||||
const size_t kCencBlockSize = 16u;
|
||||
|
||||
// Adds one or more subsamples to |*subsamples|. This may add more than one
|
||||
|
@ -66,14 +63,14 @@ EncryptingFragmenter::EncryptingFragmenter(
|
|||
TrackFragment* traf,
|
||||
scoped_ptr<EncryptionKey> encryption_key,
|
||||
int64_t clear_time,
|
||||
EncryptionMode encryption_mode)
|
||||
FourCC protection_scheme)
|
||||
: Fragmenter(traf),
|
||||
info_(info),
|
||||
encryption_key_(encryption_key.Pass()),
|
||||
nalu_length_size_(GetNaluLengthSize(*info)),
|
||||
video_codec_(GetVideoCodec(*info)),
|
||||
clear_time_(clear_time),
|
||||
encryption_mode_(encryption_mode) {
|
||||
protection_scheme_(protection_scheme) {
|
||||
DCHECK(encryption_key_);
|
||||
if (video_codec_ == kCodecVP8) {
|
||||
vpx_parser_.reset(new VP8Parser);
|
||||
|
@ -175,22 +172,21 @@ void EncryptingFragmenter::FinalizeFragmentForEncryption() {
|
|||
|
||||
Status EncryptingFragmenter::CreateEncryptor() {
|
||||
DCHECK(encryption_key_);
|
||||
scoped_ptr<AesEncryptor> encryptor;
|
||||
size_t default_iv_size = 0;
|
||||
if (encryption_mode_ == kEncryptionModeAesCtr) {
|
||||
encryptor.reset(new AesCtrEncryptor);
|
||||
default_iv_size = kDefaultIvSizeForCtr;
|
||||
} else if (encryption_mode_ == kEncryptionModeAesCbc) {
|
||||
encryptor.reset(new AesCbcEncryptor(kNoPadding, kChainAcrossCalls));
|
||||
default_iv_size = kDefaultIvSizeForCbc;
|
||||
} else {
|
||||
return Status(error::MUXER_FAILURE, "Unsupported encryption mode.");
|
||||
scoped_ptr<AesCryptor> encryptor;
|
||||
switch (protection_scheme_) {
|
||||
case FOURCC_cenc:
|
||||
encryptor.reset(new AesCtrEncryptor);
|
||||
break;
|
||||
case FOURCC_cbc1:
|
||||
encryptor.reset(new AesCbcEncryptor(kNoPadding, kChainAcrossCalls));
|
||||
break;
|
||||
default:
|
||||
return Status(error::MUXER_FAILURE, "Unsupported protection scheme.");
|
||||
}
|
||||
const bool initialized = encryption_key_->iv.empty()
|
||||
? encryptor->InitializeWithRandomIv(
|
||||
encryption_key_->key, default_iv_size)
|
||||
: encryptor->InitializeWithIv(
|
||||
encryption_key_->key, encryption_key_->iv);
|
||||
|
||||
DCHECK(!encryption_key_->iv.empty());
|
||||
const bool initialized =
|
||||
encryptor->InitializeWithIv(encryption_key_->key, encryption_key_->iv);
|
||||
if (!initialized)
|
||||
return Status(error::MUXER_FAILURE, "Failed to create the encryptor.");
|
||||
encryptor_ = encryptor.Pass();
|
||||
|
@ -229,7 +225,7 @@ Status EncryptingFragmenter::EncryptSample(scoped_refptr<MediaSample> sample) {
|
|||
// within the superframe.
|
||||
// For AES-CBC mode 'cbc1' scheme, clear data is sized appropriately so
|
||||
// that the cipher data is block aligned.
|
||||
if (is_superframe || encryption_mode_ == kEncryptionModeAesCbc) {
|
||||
if (is_superframe || protection_scheme_ == FOURCC_cbc1) {
|
||||
const uint16_t misalign_bytes =
|
||||
subsample.cipher_bytes % kCencBlockSize;
|
||||
subsample.clear_bytes += misalign_bytes;
|
||||
|
@ -271,7 +267,7 @@ Status EncryptingFragmenter::EncryptSample(scoped_refptr<MediaSample> sample) {
|
|||
|
||||
// For AES-CBC mode 'cbc1' scheme, clear data is sized appropriately
|
||||
// so that the cipher data is block aligned.
|
||||
if (encryption_mode_ == kEncryptionModeAesCbc) {
|
||||
if (protection_scheme_ == FOURCC_cbc1) {
|
||||
const uint16_t misalign_bytes = cipher_bytes % kCencBlockSize;
|
||||
current_clear_bytes += misalign_bytes;
|
||||
cipher_bytes -= misalign_bytes;
|
||||
|
@ -303,7 +299,7 @@ Status EncryptingFragmenter::EncryptSample(scoped_refptr<MediaSample> sample) {
|
|||
uint64_t encryption_data_size = sample->data_size();
|
||||
// AES-CBC mode requires all encrypted cipher blocks to be 16 bytes. The
|
||||
// partial blocks are left unencrypted.
|
||||
if (encryption_mode_ == kEncryptionModeAesCbc)
|
||||
if (protection_scheme_ == FOURCC_cbc1)
|
||||
encryption_data_size -= encryption_data_size % kCencBlockSize;
|
||||
EncryptBytes(data, encryption_data_size);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include "packager/base/memory/ref_counted.h"
|
||||
#include "packager/base/memory/scoped_ptr.h"
|
||||
#include "packager/media/base/encryption_modes.h"
|
||||
#include "packager/media/base/fourccs.h"
|
||||
#include "packager/media/filters/vpx_parser.h"
|
||||
#include "packager/media/formats/mp4/fragmenter.h"
|
||||
#include "packager/media/formats/mp4/video_slice_header_parser.h"
|
||||
|
@ -17,7 +17,7 @@
|
|||
namespace edash_packager {
|
||||
namespace media {
|
||||
|
||||
class AesEncryptor;
|
||||
class AesCryptor;
|
||||
class StreamInfo;
|
||||
struct EncryptionKey;
|
||||
|
||||
|
@ -30,11 +30,13 @@ class EncryptingFragmenter : public Fragmenter {
|
|||
/// @param encryption_key contains the encryption parameters.
|
||||
/// @param clear_time specifies clear lead duration in units of the current
|
||||
/// track's timescale.
|
||||
/// @param protection_scheme specifies the protection scheme: 'cenc', 'cens',
|
||||
/// 'cbc1', 'cbcs'.
|
||||
EncryptingFragmenter(scoped_refptr<StreamInfo> info,
|
||||
TrackFragment* traf,
|
||||
scoped_ptr<EncryptionKey> encryption_key,
|
||||
int64_t clear_time,
|
||||
EncryptionMode encryption_mode);
|
||||
FourCC protection_scheme);
|
||||
|
||||
~EncryptingFragmenter() override;
|
||||
|
||||
|
@ -57,8 +59,9 @@ class EncryptingFragmenter : public Fragmenter {
|
|||
/// @return OK on success, an error status otherwise.
|
||||
Status CreateEncryptor();
|
||||
|
||||
EncryptionKey* encryption_key() { return encryption_key_.get(); }
|
||||
AesEncryptor* encryptor() { return encryptor_.get(); }
|
||||
const EncryptionKey* encryption_key() const { return encryption_key_.get(); }
|
||||
AesCryptor* encryptor() { return encryptor_.get(); }
|
||||
FourCC protection_scheme() const { return protection_scheme_; }
|
||||
|
||||
void set_encryption_key(scoped_ptr<EncryptionKey> encryption_key) {
|
||||
encryption_key_ = encryption_key.Pass();
|
||||
|
@ -73,14 +76,14 @@ class EncryptingFragmenter : public Fragmenter {
|
|||
|
||||
scoped_refptr<StreamInfo> info_;
|
||||
scoped_ptr<EncryptionKey> encryption_key_;
|
||||
scoped_ptr<AesEncryptor> encryptor_;
|
||||
scoped_ptr<AesCryptor> encryptor_;
|
||||
// If this stream contains AVC, subsample encryption specifies that the size
|
||||
// and type of NAL units remain unencrypted. This function returns the size of
|
||||
// the size field in bytes. Can be 1, 2 or 4 bytes.
|
||||
const uint8_t nalu_length_size_;
|
||||
const VideoCodec video_codec_;
|
||||
int64_t clear_time_;
|
||||
EncryptionMode encryption_mode_;
|
||||
FourCC protection_scheme_;
|
||||
|
||||
scoped_ptr<VPxParser> vpx_parser_;
|
||||
scoped_ptr<VideoSliceHeaderParser> header_parser_;
|
||||
|
|
|
@ -24,13 +24,13 @@ KeyRotationFragmenter::KeyRotationFragmenter(MovieFragment* moof,
|
|||
KeySource::TrackType track_type,
|
||||
int64_t crypto_period_duration,
|
||||
int64_t clear_time,
|
||||
MuxerListener* muxer_listener,
|
||||
EncryptionMode encryption_mode)
|
||||
FourCC protection_scheme,
|
||||
MuxerListener* muxer_listener)
|
||||
: EncryptingFragmenter(info,
|
||||
traf,
|
||||
scoped_ptr<EncryptionKey>(new EncryptionKey()),
|
||||
clear_time,
|
||||
encryption_mode),
|
||||
protection_scheme),
|
||||
moof_(moof),
|
||||
encryption_key_source_(encryption_key_source),
|
||||
track_type_(track_type),
|
||||
|
@ -55,6 +55,12 @@ Status KeyRotationFragmenter::PrepareFragmentForEncryption(
|
|||
current_crypto_period_index, track_type_, encryption_key.get());
|
||||
if (!status.ok())
|
||||
return status;
|
||||
if (encryption_key->iv.empty()) {
|
||||
if (!AesCryptor::GenerateRandomIv(protection_scheme(),
|
||||
&encryption_key->iv)) {
|
||||
return Status(error::INTERNAL_ERROR, "Failed to generate random iv.");
|
||||
}
|
||||
}
|
||||
set_encryption_key(encryption_key.Pass());
|
||||
prev_crypto_period_index_ = current_crypto_period_index;
|
||||
need_to_refresh_encryptor = true;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#ifndef MEDIA_FORMATS_MP4_KEY_ROTATION_FRAGMENTER_H_
|
||||
#define MEDIA_FORMATS_MP4_KEY_ROTATION_FRAGMENTER_H_
|
||||
|
||||
#include "packager/media/base/encryption_modes.h"
|
||||
#include "packager/media/base/fourccs.h"
|
||||
#include "packager/media/base/key_source.h"
|
||||
#include "packager/media/event/muxer_listener.h"
|
||||
#include "packager/media/formats/mp4/encrypting_fragmenter.h"
|
||||
|
@ -32,6 +32,8 @@ class KeyRotationFragmenter : public EncryptingFragmenter {
|
|||
/// of the current track's timescale.
|
||||
/// @param clear_time specifies clear lead duration in units of the current
|
||||
/// track's timescale.
|
||||
/// @param protection_scheme specifies the protection scheme: 'cenc', 'cens',
|
||||
/// 'cbc1', 'cbcs'.
|
||||
/// @param muxer_listener is a pointer to MuxerListener for notifying
|
||||
/// muxer related events. This may be null.
|
||||
KeyRotationFragmenter(MovieFragment* moof,
|
||||
|
@ -41,8 +43,8 @@ class KeyRotationFragmenter : public EncryptingFragmenter {
|
|||
KeySource::TrackType track_type,
|
||||
int64_t crypto_period_duration,
|
||||
int64_t clear_time,
|
||||
MuxerListener* muxer_listener,
|
||||
EncryptionMode encryption_mode);
|
||||
FourCC protection_scheme,
|
||||
MuxerListener* muxer_listener);
|
||||
~KeyRotationFragmenter() override;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -147,15 +147,10 @@ Status MP4Muxer::Initialize() {
|
|||
new MultiSegmentSegmenter(options(), ftyp.Pass(), moov.Pass()));
|
||||
}
|
||||
|
||||
Status segmenter_initialized =
|
||||
segmenter_->Initialize(streams(),
|
||||
muxer_listener(),
|
||||
progress_listener(),
|
||||
encryption_key_source(),
|
||||
max_sd_pixels(),
|
||||
clear_lead_in_seconds(),
|
||||
crypto_period_duration_in_seconds(),
|
||||
encryption_mode());
|
||||
const Status segmenter_initialized = segmenter_->Initialize(
|
||||
streams(), muxer_listener(), progress_listener(), encryption_key_source(),
|
||||
max_sd_pixels(), clear_lead_in_seconds(),
|
||||
crypto_period_duration_in_seconds(), protection_scheme());
|
||||
|
||||
if (!segmenter_initialized.ok())
|
||||
return segmenter_initialized;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <algorithm>
|
||||
|
||||
#include "packager/base/stl_util.h"
|
||||
#include "packager/media/base/aes_cryptor.h"
|
||||
#include "packager/media/base/buffer_writer.h"
|
||||
#include "packager/media/base/key_source.h"
|
||||
#include "packager/media/base/media_sample.h"
|
||||
|
@ -26,8 +27,6 @@ namespace mp4 {
|
|||
|
||||
namespace {
|
||||
|
||||
// Generate 64bit IV by default.
|
||||
const size_t kDefaultIvSize = 8u;
|
||||
const size_t kCencKeyIdSize = 16u;
|
||||
|
||||
// The version of cenc implemented here. CENC 4.
|
||||
|
@ -50,26 +49,24 @@ uint64_t Rescale(uint64_t time_in_old_scale,
|
|||
|
||||
void GenerateSinf(const EncryptionKey& encryption_key,
|
||||
FourCC old_type,
|
||||
EncryptionMode encryption_mode,
|
||||
FourCC protection_scheme,
|
||||
ProtectionSchemeInfo* sinf) {
|
||||
sinf->format.format = old_type;
|
||||
|
||||
if (encryption_mode == kEncryptionModeAesCtr){
|
||||
sinf->type.type = FOURCC_cenc;
|
||||
} else if (encryption_mode == kEncryptionModeAesCbc) {
|
||||
sinf->type.type = FOURCC_cbc1;
|
||||
}
|
||||
|
||||
DCHECK_NE(protection_scheme, FOURCC_NULL);
|
||||
sinf->type.type = protection_scheme;
|
||||
sinf->type.version = kCencSchemeVersion;
|
||||
sinf->info.track_encryption.is_encrypted = true;
|
||||
sinf->info.track_encryption.default_iv_size =
|
||||
encryption_key.iv.empty() ? kDefaultIvSize : encryption_key.iv.size();
|
||||
sinf->info.track_encryption.default_kid = encryption_key.key_id;
|
||||
|
||||
auto& track_encryption = sinf->info.track_encryption;
|
||||
track_encryption.is_encrypted = true;
|
||||
DCHECK(!encryption_key.iv.empty());
|
||||
track_encryption.default_iv_size = encryption_key.iv.size();
|
||||
track_encryption.default_kid = encryption_key.key_id;
|
||||
}
|
||||
|
||||
void GenerateEncryptedSampleEntry(const EncryptionKey& encryption_key,
|
||||
double clear_lead_in_seconds,
|
||||
EncryptionMode encryption_mode,
|
||||
FourCC protection_scheme,
|
||||
SampleDescription* description) {
|
||||
DCHECK(description);
|
||||
if (description->type == kVideo) {
|
||||
|
@ -81,7 +78,7 @@ void GenerateEncryptedSampleEntry(const EncryptionKey& encryption_key,
|
|||
|
||||
// Convert the first entry to an encrypted entry.
|
||||
VideoSampleEntry& entry = description->video_entries[0];
|
||||
GenerateSinf(encryption_key, entry.format, encryption_mode, &entry.sinf);
|
||||
GenerateSinf(encryption_key, entry.format, protection_scheme, &entry.sinf);
|
||||
entry.format = FOURCC_encv;
|
||||
} else {
|
||||
DCHECK_EQ(kAudio, description->type);
|
||||
|
@ -93,7 +90,7 @@ void GenerateEncryptedSampleEntry(const EncryptionKey& encryption_key,
|
|||
|
||||
// Convert the first entry to an encrypted entry.
|
||||
AudioSampleEntry& entry = description->audio_entries[0];
|
||||
GenerateSinf(encryption_key, entry.format, encryption_mode, &entry.sinf);
|
||||
GenerateSinf(encryption_key, entry.format, protection_scheme, &entry.sinf);
|
||||
entry.format = FOURCC_enca;
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +134,7 @@ Status Segmenter::Initialize(const std::vector<MediaStream*>& streams,
|
|||
uint32_t max_sd_pixels,
|
||||
double clear_lead_in_seconds,
|
||||
double crypto_period_duration_in_seconds,
|
||||
EncryptionMode encryption_mode) {
|
||||
FourCC protection_scheme) {
|
||||
DCHECK_LT(0u, streams.size());
|
||||
muxer_listener_ = muxer_listener;
|
||||
progress_listener_ = progress_listener;
|
||||
|
@ -173,8 +170,10 @@ Status Segmenter::Initialize(const std::vector<MediaStream*>& streams,
|
|||
encryption_key.key_id.assign(
|
||||
kKeyRotationDefaultKeyId,
|
||||
kKeyRotationDefaultKeyId + arraysize(kKeyRotationDefaultKeyId));
|
||||
if (!AesCryptor::GenerateRandomIv(protection_scheme, &encryption_key.iv))
|
||||
return Status(error::INTERNAL_ERROR, "Failed to generate random iv.");
|
||||
GenerateEncryptedSampleEntry(encryption_key, clear_lead_in_seconds,
|
||||
encryption_mode, &description);
|
||||
protection_scheme, &description);
|
||||
if (muxer_listener_) {
|
||||
muxer_listener_->OnEncryptionInfoReady(
|
||||
kInitialEncryptionInfo, encryption_key.key_id,
|
||||
|
@ -186,7 +185,7 @@ Status Segmenter::Initialize(const std::vector<MediaStream*>& streams,
|
|||
encryption_key_source, track_type,
|
||||
crypto_period_duration_in_seconds * streams[i]->info()->time_scale(),
|
||||
clear_lead_in_seconds * streams[i]->info()->time_scale(),
|
||||
muxer_listener_, encryption_mode);
|
||||
protection_scheme, muxer_listener_);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -195,9 +194,13 @@ Status Segmenter::Initialize(const std::vector<MediaStream*>& streams,
|
|||
encryption_key_source->GetKey(track_type, encryption_key.get());
|
||||
if (!status.ok())
|
||||
return status;
|
||||
if (encryption_key->iv.empty()) {
|
||||
if (!AesCryptor::GenerateRandomIv(protection_scheme, &encryption_key->iv))
|
||||
return Status(error::INTERNAL_ERROR, "Failed to generate random iv.");
|
||||
}
|
||||
|
||||
GenerateEncryptedSampleEntry(*encryption_key, clear_lead_in_seconds,
|
||||
encryption_mode, &description);
|
||||
protection_scheme, &description);
|
||||
|
||||
if (moov_->pssh.empty()) {
|
||||
moov_->pssh.resize(encryption_key->key_system_info.size());
|
||||
|
@ -215,7 +218,7 @@ Status Segmenter::Initialize(const std::vector<MediaStream*>& streams,
|
|||
fragmenters_[i] = new EncryptingFragmenter(
|
||||
streams[i]->info(), &moof_->tracks[i], encryption_key.Pass(),
|
||||
clear_lead_in_seconds * streams[i]->info()->time_scale(),
|
||||
encryption_mode);
|
||||
protection_scheme);
|
||||
}
|
||||
|
||||
// Choose the first stream if there is no VIDEO.
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include "packager/base/memory/ref_counted.h"
|
||||
#include "packager/base/memory/scoped_ptr.h"
|
||||
#include "packager/media/base/encryption_modes.h"
|
||||
#include "packager/media/base/fourccs.h"
|
||||
#include "packager/media/base/status.h"
|
||||
#include "packager/media/formats/mp4/box_definitions.h"
|
||||
|
||||
|
@ -59,6 +59,8 @@ class Segmenter {
|
|||
/// pixels per frame than max_sd_pixels, it is HD, SD otherwise.
|
||||
/// @param clear_time specifies clear lead duration in seconds.
|
||||
/// @param crypto_period_duration specifies crypto period duration in seconds.
|
||||
/// @param protection_scheme specifies the protection scheme: 'senc', 'sens',
|
||||
/// 'cbc1', 'cbcs'.
|
||||
/// @return OK on success, an error status otherwise.
|
||||
Status Initialize(const std::vector<MediaStream*>& streams,
|
||||
MuxerListener* muxer_listener,
|
||||
|
@ -67,7 +69,7 @@ class Segmenter {
|
|||
uint32_t max_sd_pixels,
|
||||
double clear_lead_in_seconds,
|
||||
double crypto_period_duration_in_seconds,
|
||||
EncryptionMode encryption_mode);
|
||||
FourCC protection_scheme);
|
||||
|
||||
/// Finalize the segmenter.
|
||||
/// @return OK on success, an error status otherwise.
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <limits>
|
||||
|
||||
#include "packager/media/base/buffer_reader.h"
|
||||
#include "packager/media/base/encryption_modes.h"
|
||||
#include "packager/media/base/fourccs.h"
|
||||
#include "packager/media/base/rcheck.h"
|
||||
#include "packager/media/formats/mp4/chunk_info_iterator.h"
|
||||
#include "packager/media/formats/mp4/composition_offset_iterator.h"
|
||||
|
@ -600,24 +600,10 @@ scoped_ptr<DecryptConfig> TrackRunIterator::GetDecryptConfig() {
|
|||
|
||||
FourCC protection_scheme = is_audio() ? audio_description().sinf.type.type
|
||||
: video_description().sinf.type.type;
|
||||
EncryptionMode decryption_mode;
|
||||
switch (protection_scheme) {
|
||||
case FOURCC_cenc:
|
||||
decryption_mode = kEncryptionModeAesCtr;
|
||||
break;
|
||||
case FOURCC_cbc1:
|
||||
decryption_mode = kEncryptionModeAesCbc;
|
||||
break;
|
||||
default:
|
||||
LOG(ERROR) << "Unsupported protection scheme.";
|
||||
return scoped_ptr<DecryptConfig>();
|
||||
}
|
||||
|
||||
return scoped_ptr<DecryptConfig>(new DecryptConfig(
|
||||
track_encryption().default_kid,
|
||||
sample_encryption_entry.initialization_vector,
|
||||
sample_encryption_entry.subsamples,
|
||||
decryption_mode));
|
||||
return scoped_ptr<DecryptConfig>(
|
||||
new DecryptConfig(track_encryption().default_kid,
|
||||
sample_encryption_entry.initialization_vector,
|
||||
sample_encryption_entry.subsamples, protection_scheme));
|
||||
}
|
||||
|
||||
} // namespace mp4
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "packager/media/formats/webm/encryptor.h"
|
||||
|
||||
#include "packager/media/base/aes_encryptor.h"
|
||||
#include "packager/media/base/fourccs.h"
|
||||
#include "packager/media/base/media_sample.h"
|
||||
|
||||
namespace edash_packager {
|
||||
|
@ -14,9 +15,6 @@ namespace media {
|
|||
namespace webm {
|
||||
namespace {
|
||||
|
||||
// Generate 64bit IV by default.
|
||||
const size_t kDefaultIvSize = 8u;
|
||||
|
||||
Status CreateContentEncryption(mkvmuxer::Track* track, EncryptionKey* key) {
|
||||
if (!track->AddContentEncoding()) {
|
||||
return Status(error::INTERNAL_ERROR,
|
||||
|
@ -107,13 +105,14 @@ Status Encryptor::CreateEncryptor(MuxerListener* muxer_listener,
|
|||
Status status = key_source->GetKey(track_type, encryption_key.get());
|
||||
if (!status.ok())
|
||||
return status;
|
||||
if (encryption_key->iv.empty()) {
|
||||
if (!AesCryptor::GenerateRandomIv(FOURCC_cenc, &encryption_key->iv))
|
||||
return Status(error::INTERNAL_ERROR, "Failed to generate random iv.");
|
||||
}
|
||||
|
||||
scoped_ptr<AesCtrEncryptor> encryptor(new AesCtrEncryptor());
|
||||
const bool initialized = encryption_key->iv.empty()
|
||||
? encryptor->InitializeWithRandomIv(
|
||||
encryption_key->key, kDefaultIvSize)
|
||||
: encryptor->InitializeWithIv(
|
||||
encryption_key->key, encryption_key->iv);
|
||||
const bool initialized =
|
||||
encryptor->InitializeWithIv(encryption_key->key, encryption_key->iv);
|
||||
if (!initialized)
|
||||
return Status(error::INTERNAL_ERROR, "Failed to create the encryptor.");
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/base/sys_byteorder.h"
|
||||
#include "packager/media/base/encryption_modes.h"
|
||||
#include "packager/media/formats/webm/webm_constants.h"
|
||||
|
||||
namespace edash_packager {
|
||||
|
@ -56,8 +55,7 @@ bool WebMCreateDecryptConfig(const uint8_t* data,
|
|||
decrypt_config->reset(new DecryptConfig(
|
||||
std::vector<uint8_t>(key_id, key_id + key_id_size),
|
||||
std::vector<uint8_t>(counter_block.begin(), counter_block.end()),
|
||||
std::vector<SubsampleEntry>(),
|
||||
kEncryptionModeAesCtr));
|
||||
std::vector<SubsampleEntry>()));
|
||||
*data_offset = frame_offset;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "packager/media/formats/webm/webm_muxer.h"
|
||||
|
||||
#include "packager/media/base/fourccs.h"
|
||||
#include "packager/media/base/media_sample.h"
|
||||
#include "packager/media/base/media_stream.h"
|
||||
#include "packager/media/base/stream_info.h"
|
||||
|
@ -30,12 +31,11 @@ Status WebMMuxer::Initialize() {
|
|||
"Key rotation is not implemented for WebM");
|
||||
}
|
||||
|
||||
if (encryption_key_source() && (encryption_mode() != kEncryptionModeAesCtr)) {
|
||||
if (encryption_key_source() && (protection_scheme() != FOURCC_cenc)) {
|
||||
NOTIMPLEMENTED()
|
||||
<< "WebM muxer does not support encryption mode other than AES-CTR.";
|
||||
return Status(
|
||||
error::UNIMPLEMENTED,
|
||||
"WebM muxer does not support encryption mode other than AES-CTR.");
|
||||
<< "WebM does not support protection scheme other than 'cenc'.";
|
||||
return Status(error::UNIMPLEMENTED,
|
||||
"WebM does not support protection scheme other than 'cenc'.");
|
||||
}
|
||||
|
||||
scoped_ptr<MkvWriter> writer(new MkvWriter);
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
#include "packager/base/strings/stringprintf.h"
|
||||
#include "packager/base/time/clock.h"
|
||||
#include "packager/media/base/demuxer.h"
|
||||
#include "packager/media/base/encryption_modes.h"
|
||||
#include "packager/media/base/fixed_key_source.h"
|
||||
#include "packager/media/base/fourccs.h"
|
||||
#include "packager/media/base/media_stream.h"
|
||||
#include "packager/media/base/muxer.h"
|
||||
#include "packager/media/base/stream_info.h"
|
||||
|
@ -174,10 +174,8 @@ void PackagerTestBasic::Remux(const std::string& input,
|
|||
|
||||
if (enable_encryption) {
|
||||
muxer_video->SetKeySource(encryption_key_source.get(),
|
||||
KeySource::TRACK_TYPE_SD,
|
||||
kClearLeadInSeconds,
|
||||
kCryptoDurationInSeconds,
|
||||
kEncryptionModeAesCtr);
|
||||
KeySource::TRACK_TYPE_SD, kClearLeadInSeconds,
|
||||
kCryptoDurationInSeconds, FOURCC_cenc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,10 +194,8 @@ void PackagerTestBasic::Remux(const std::string& input,
|
|||
|
||||
if (enable_encryption) {
|
||||
muxer_audio->SetKeySource(encryption_key_source.get(),
|
||||
KeySource::TRACK_TYPE_SD,
|
||||
kClearLeadInSeconds,
|
||||
kCryptoDurationInSeconds,
|
||||
kEncryptionModeAesCtr);
|
||||
KeySource::TRACK_TYPE_SD, kClearLeadInSeconds,
|
||||
kCryptoDurationInSeconds, FOURCC_cenc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue