Skip to content

Commit

Permalink
feat: experiment with decrypt and re-encrypt
Browse files Browse the repository at this point in the history
  • Loading branch information
lee.fordyce committed Mar 26, 2024
1 parent 05d44f3 commit c695ade
Show file tree
Hide file tree
Showing 18 changed files with 84 additions and 0 deletions.
3 changes: 3 additions & 0 deletions include/packager/live_packager.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef PACKAGER_LIVE_PACKAGER_H_
#define PACKAGER_LIVE_PACKAGER_H_

#include <packager/crypto_params.h>
#include <packager/packager.h>

namespace shaka {
Expand Down Expand Up @@ -104,6 +105,8 @@ struct LiveConfig {
/// Used for timed text packaging to set the fragment decode time when the
/// output format is either VTT in MP4 or TTML in MP4.
int64_t timed_text_decode_time = -1;

RawKeyParams* decryption_keys = nullptr;
};

class LivePackager {
Expand Down
7 changes: 7 additions & 0 deletions packager/live_packager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <absl/log/globals.h>
#include <absl/log/log.h>
#include <absl/strings/escaping.h>
#include <packager/chunking_params.h>
#include <packager/file.h>

Expand Down Expand Up @@ -379,6 +380,12 @@ Status LivePackager::Package(const Segment& init_segment,
packaging_params.cts_offset_adjustment =
config_.format == LiveConfig::OutputFormat::TS;

if (config_.decryption_keys) {
DecryptionParams& decryption_params = packaging_params.decryption_params;
decryption_params.key_provider = KeyProvider::kRawKey;
decryption_params.raw_key = *config_.decryption_keys;
}

EncryptionParams& encryption_params = packaging_params.encryption_params;
// As a side effect of InitializeEncryption, encryption_params will be
// modified.
Expand Down
74 changes: 74 additions & 0 deletions packager/live_packager_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <packager/file.h>
#include <packager/live_packager.h>
#include <packager/media/base/aes_decryptor.h>
#include <packager/media/base/aes_pattern_cryptor.h>
#include <packager/media/base/byte_queue.h>
#include <packager/media/base/key_source.h>
#include <packager/media/base/media_sample.h>
Expand Down Expand Up @@ -48,6 +49,22 @@ const uint8_t kIv[]{
0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
};

const char kDrmLabel0[] = "k_0";
const char kDrmLabel1[] = "k_1";

const char kKeyIdHex[] = "00000000621f2afe7ab2c868d5fd2e2e";
const char kKeyHex[] = "1af987fa084ff3c0f4ad35a6bdab98e2";
const char kIvHex[] = "3edd0ba826f5fdf994f2569fea8e091e";

const char kKeyId2Hex[] = "00000000621f2afe7ab2c868d5fd2e2f";
const char kKey2Hex[] = "fbc5b49c8b03b37b4522ddd0b09b204d";
const char kIv2Hex[] = "676e6bb65321a027749fcae57acdc71f";

std::vector<uint8_t> HexStringToVector(const std::string& hex_str) {
std::string raw_str = absl::HexStringToBytes(hex_str);
return std::vector<uint8_t>(raw_str.begin(), raw_str.end());
}

const int kNumSegments = 10;

std::filesystem::path GetTestDataFilePath(const std::string& name) {
Expand Down Expand Up @@ -649,6 +666,63 @@ TEST_F(LivePackagerBaseTest, VerifyAes128WithDecryption) {
}
}

// Test demonstrates decrypting fmp4 source with one set of keys and
// re-encrypting using a difference encryption schema (AES-128) and different
// set of keys. As validation the re-encryption segments are decrypted and
// compared against decrypted segments.
TEST_F(LivePackagerBaseTest, VerifyPrdDecryptReEncrypt) {
std::vector<uint8_t> init_segment_buffer =
ReadTestDataFile("encrypted/prd_data/init.mp4");
ASSERT_FALSE(init_segment_buffer.empty());

media::AesCbcDecryptor decryptor(media::kPkcs5Padding,
media::AesCryptor::kUseConstantIv);
ASSERT_TRUE(decryptor.InitializeWithIv(key_, iv_));

for (unsigned int i = 1; i <= 7; i++) {
std::string segment_num = absl::StrFormat("encrypted/prd_data/%05d.m4s", i);
std::vector<uint8_t> segment_buffer = ReadTestDataFile(segment_num);
ASSERT_FALSE(segment_buffer.empty());

SegmentData init_seg(init_segment_buffer.data(),
init_segment_buffer.size());
SegmentData media_seg(segment_buffer.data(), segment_buffer.size());

LiveConfig live_config;
live_config.format = LiveConfig::OutputFormat::TS;
live_config.track_type = LiveConfig::TrackType::VIDEO;
live_config.protection_scheme = LiveConfig::EncryptionScheme::AES_128;
live_config.segment_number = i;
auto* decryption_keys = new (shaka::RawKeyParams);
decryption_keys->key_map[kDrmLabel0].key_id = HexStringToVector(kKeyIdHex);
decryption_keys->key_map[kDrmLabel0].key = HexStringToVector(kKeyHex);
decryption_keys->key_map[kDrmLabel0].iv = HexStringToVector(kIvHex);
decryption_keys->key_map[kDrmLabel1].key_id = HexStringToVector(kKeyId2Hex);
decryption_keys->key_map[kDrmLabel1].key = HexStringToVector(kKey2Hex);
decryption_keys->key_map[kDrmLabel1].iv = HexStringToVector(kIv2Hex);
live_config.decryption_keys = decryption_keys;

SetupLivePackagerConfig(live_config);

FullSegmentBuffer out;
ASSERT_EQ(Status::OK, live_packager_->Package(init_seg, media_seg, out));
ASSERT_GT(out.SegmentSize(), 0);

std::string exp_decrypted_segment =
absl::StrFormat("encrypted/prd_data/decrypt/ts/%04d.ts", i);
std::vector<uint8_t> exp_decrypted_segment_buffer =
ReadTestDataFile(exp_decrypted_segment);
ASSERT_FALSE(exp_decrypted_segment_buffer.empty());

std::vector<uint8_t> decrypted;
std::vector<uint8_t> buffer(out.SegmentData(),
out.SegmentData() + out.SegmentSize());

ASSERT_TRUE(decryptor.Crypt(buffer, &decrypted));
ASSERT_EQ(decrypted, exp_decrypted_segment_buffer);
}
}

TEST_F(LivePackagerBaseTest, EncryptionFailure) {
std::vector<uint8_t> init_segment_buffer = ReadTestDataFile("input/init.mp4");
ASSERT_FALSE(init_segment_buffer.empty());
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.
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.

0 comments on commit c695ade

Please sign in to comment.