Skip to content

Commit

Permalink
Fix pattern signaling in seig for key rotation with cbcs
Browse files Browse the repository at this point in the history
Closes #460.
Bug: 112769382

Change-Id: Id2277edf9ac1ca637354f3a585666ad139ed8ee2
  • Loading branch information
kqyang committed Sep 17, 2018
1 parent 3cf9b91 commit 18492a2
Show file tree
Hide file tree
Showing 13 changed files with 70 additions and 32 deletions.
10 changes: 10 additions & 0 deletions packager/app/test/packager_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1409,6 +1409,16 @@ def testLiveProfileAndKeyRotation(self):
self._GetFlags(encryption=True, key_rotation=True, output_dash=True))
self._CheckTestResults('live-profile-and-key-rotation')

def testLiveProfileAndKeyRotationCbcs(self):
self.assertPackageSuccess(
self._GetStreams(['audio', 'video'], segmented=True),
self._GetFlags(
encryption=True,
protection_scheme='cbcs',
key_rotation=True,
output_dash=True))
self._CheckTestResults('live-profile-and-key-rotation-cbcs')

def testLiveProfileAndKeyRotationAndNoPsshInStream(self):
self.assertPackageSuccess(
self._GetStreams(['audio', 'video'], segmented=True),
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="dynamic" publishTime="some_time" availabilityStartTime="some_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
<Period id="0" start="PT0S">
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
<ContentProtection value="cbcs" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
<Representation id="0" bandwidth="977527" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
<SegmentTemplate timescale="30000" initialization="bear-640x360-video-init.mp4" media="bear-640x360-video-$Number$.m4s" startNumber="1">
<SegmentTimeline>
<S t="0" d="30030" r="1"/>
<S t="60060" d="22022"/>
</SegmentTimeline>
</SegmentTemplate>
</Representation>
</AdaptationSet>
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
<ContentProtection value="cbcs" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
<Representation id="1" bandwidth="134336" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
<SegmentTemplate timescale="44100" initialization="bear-640x360-audio-init.mp4" media="bear-640x360-audio-$Number$.m4s" startNumber="1">
<SegmentTimeline>
<S t="0" d="45056"/>
<S t="45056" d="44032"/>
<S t="89088" d="31744"/>
</SegmentTimeline>
</SegmentTemplate>
</Representation>
</AdaptationSet>
</Period>
</MPD>
53 changes: 27 additions & 26 deletions packager/media/crypto/encryption_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "packager/media/codecs/vp8_parser.h"
#include "packager/media/codecs/vp9_parser.h"
#include "packager/media/crypto/sample_aes_ec3_cryptor.h"
#include "packager/status_macros.h"

namespace shaka {
namespace media {
Expand All @@ -32,10 +33,17 @@ const size_t kCencBlockSize = 16u;
// The encryption handler only supports a single output.
const size_t kStreamIndex = 0;

// The default KID for key rotation is all 0s.
// The default KID, KEY and IV for key rotation are all 0s.
// They are placeholders and are not really being used to encrypt data.
const uint8_t kKeyRotationDefaultKeyId[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
const uint8_t kKeyRotationDefaultKey[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
const uint8_t kKeyRotationDefaultIv[] = {
0, 0, 0, 0, 0, 0, 0, 0,
};

// Adds one or more subsamples to |*decrypt_config|. This may add more than one
// if one of the values overflows the integer in the subsample.
Expand Down Expand Up @@ -179,25 +187,21 @@ Status EncryptionHandler::ProcessStreamInfo(const StreamInfo& clear_info) {
}
}

Status status = SetupProtectionPattern(stream_info->stream_type());
if (!status.ok())
return status;
RETURN_IF_ERROR(SetupProtectionPattern(stream_info->stream_type()));

EncryptionKey encryption_key;
const bool key_rotation_enabled = crypto_period_duration_ != 0;
if (key_rotation_enabled) {
check_new_crypto_period_ = true;
// Setup dummy key id and key to signal encryption for key rotation.
encryption_key.key_id.assign(
kKeyRotationDefaultKeyId,
kKeyRotationDefaultKeyId + sizeof(kKeyRotationDefaultKeyId));
// The key is not really used to encrypt any data. It is there just for
// convenience.
encryption_key.key = encryption_key.key_id;
// Setup dummy key id, key and iv to signal encryption for key rotation.
encryption_key.key_id.assign(std::begin(kKeyRotationDefaultKeyId),
std::end(kKeyRotationDefaultKeyId));
encryption_key.key.assign(std::begin(kKeyRotationDefaultKey),
std::end(kKeyRotationDefaultKey));
encryption_key.iv.assign(std::begin(kKeyRotationDefaultIv),
std::end(kKeyRotationDefaultIv));
} else {
status = key_source_->GetKey(stream_label_, &encryption_key);
if (!status.ok())
return status;
RETURN_IF_ERROR(key_source_->GetKey(stream_label_, &encryption_key));
}
if (!CreateEncryptor(encryption_key))
return Status(error::ENCRYPTION_FAILURE, "Failed to create encryptor");
Expand Down Expand Up @@ -233,10 +237,8 @@ Status EncryptionHandler::ProcessMediaSample(
const int64_t current_crypto_period_index = dts / crypto_period_duration_;
if (current_crypto_period_index != prev_crypto_period_index_) {
EncryptionKey encryption_key;
Status status = key_source_->GetCryptoPeriodKey(
current_crypto_period_index, stream_label_, &encryption_key);
if (!status.ok())
return status;
RETURN_IF_ERROR(key_source_->GetCryptoPeriodKey(
current_crypto_period_index, stream_label_, &encryption_key));
if (!CreateEncryptor(encryption_key))
return Status(error::ENCRYPTION_FAILURE, "Failed to create encryptor");
prev_crypto_period_index_ = current_crypto_period_index;
Expand Down Expand Up @@ -355,14 +357,13 @@ Status EncryptionHandler::SetupProtectionPattern(StreamType stream_type) {
skip_byte_block_ = 9u;
} else {
// Tracks other than video are protected using whole-block full-sample
// encryption, which is essentially a pattern of 1:0. Note that this may
// not be the same as the non-pattern based encryption counterparts,
// e.g. in 'cens' for full sample encryption, the whole sample is
// encrypted up to the last 16-byte boundary, see 23001-7:2016(E) 9.7;
// while in 'cenc' for full sample encryption, the last partial 16-byte
// block is also encrypted, see 23001-7:2016(E) 9.4.2. Another
// difference is the use of constant iv.
crypt_byte_block_ = 1u;
// encryption. Note that this may not be the same as the non-pattern
// based encryption counterparts, e.g. in 'cens' whole-block full sample
// encryption, the whole sample is encrypted up to the last 16-byte
// boundary, see 23001-7:2016(E) 9.7; while in 'cenc' full sample
// encryption, the last partial 16-byte block is also encrypted, see
// 23001-7:2016(E) 9.4.2. Another difference is the use of constant iv.
crypt_byte_block_ = 0u;
skip_byte_block_ = 0u;
}
break;
Expand Down
2 changes: 1 addition & 1 deletion packager/media/crypto/encryption_handler_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ class EncryptionHandlerEncryptionTest
return 0;
case FOURCC_cens:
case FOURCC_cbcs:
return 1;
return codec_ == kCodecAAC ? 0 : 1;
default:
return 0;
}
Expand Down
5 changes: 0 additions & 5 deletions packager/media/formats/mp4/mp4_muxer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,6 @@ void GenerateSinf(FourCC old_type,
break;
case FOURCC_cbcs:
case FOURCC_cens:
if (track_encryption.default_skip_byte_block == 0) {
// Some clients, e.g. Safari v11.0.3 does not like having
// crypt_byte_block as a non-zero value when skip_byte_block is zero.
track_encryption.default_crypt_byte_block = 0;
}
// CENCv3 10.3 ‘cens’ AES-CTR subsample pattern encryption scheme and
// 10.4 ‘cbcs’ AES-CBC subsample pattern encryption scheme:
// The version of the Track Encryption Box (‘tenc’) SHALL be 1.
Expand Down

0 comments on commit 18492a2

Please sign in to comment.