5#include <packager/media/formats/webm/webm_crypto_helpers.h>
12#include <absl/log/log.h>
14#include <packager/media/base/buffer_reader.h>
15#include <packager/media/base/decrypt_config.h>
16#include <packager/media/formats/webm/webm_constants.h>
26std::vector<uint8_t> GenerateWebMCounterBlock(
const uint8_t* iv,
int iv_size) {
27 std::vector<uint8_t> counter_block(iv, iv + iv_size);
28 counter_block.insert(counter_block.end(),
36bool WebMCreateDecryptConfig(
const uint8_t* data,
38 const uint8_t* key_id,
40 std::unique_ptr<DecryptConfig>* decrypt_config,
42 int header_size = kWebMSignalByteSize;
43 if (data_size < header_size) {
44 DVLOG(1) <<
"Empty WebM sample.";
47 uint8_t signal_byte = data[0];
49 if (signal_byte & kWebMEncryptedSignal) {
51 header_size += kWebMIvSize;
52 if (data_size < header_size) {
53 DVLOG(1) <<
"Encrypted WebM sample too small to hold IV: " << data_size;
56 std::vector<SubsampleEntry> subsamples;
57 if (signal_byte & kWebMPartitionedSignal) {
59 header_size += kWebMNumPartitionsSize;
60 if (data_size < header_size) {
62 <<
"Encrypted WebM sample too small to hold number of partitions: "
66 uint8_t num_partitions = data[kWebMSignalByteSize + kWebMIvSize];
67 BufferReader offsets_buffer(data + header_size, data_size - header_size);
68 header_size += num_partitions * kWebMPartitionOffsetSize;
69 uint32_t subsample_offset = 0;
70 bool encrypted_subsample =
false;
71 uint16_t clear_size = 0;
72 uint32_t encrypted_size = 0;
73 for (uint8_t partition_idx = 0; partition_idx < num_partitions;
75 uint32_t partition_offset;
76 if (!offsets_buffer.Read4(&partition_offset)) {
78 <<
"Encrypted WebM sample too small to hold partition offsets: "
82 if (partition_offset < subsample_offset) {
83 DVLOG(1) <<
"Partition offsets out of order.";
86 if (encrypted_subsample) {
87 encrypted_size = partition_offset - subsample_offset;
88 subsamples.push_back(SubsampleEntry(clear_size, encrypted_size));
90 clear_size = partition_offset - subsample_offset;
91 if (partition_idx == (num_partitions - 1)) {
93 data_size - header_size - subsample_offset - clear_size;
94 subsamples.push_back(SubsampleEntry(clear_size, encrypted_size));
97 subsample_offset = partition_offset;
98 encrypted_subsample = !encrypted_subsample;
100 if (!(num_partitions % 2)) {
102 clear_size = data_size - header_size - subsample_offset;
104 subsamples.push_back(SubsampleEntry(clear_size, encrypted_size));
107 decrypt_config->reset(
new DecryptConfig(
108 std::vector<uint8_t>(key_id, key_id + key_id_size),
109 GenerateWebMCounterBlock(data + kWebMSignalByteSize, kWebMIvSize),
113 decrypt_config->reset();
116 *data_offset = header_size;
All the methods that are virtual are virtual for mocking.