5 #include "packager/media/formats/webm/webm_crypto_helpers.h"
7 #include "packager/base/logging.h"
8 #include "packager/base/sys_byteorder.h"
9 #include "packager/media/base/buffer_reader.h"
10 #include "packager/media/formats/webm/webm_constants.h"
20 std::vector<uint8_t> GenerateWebMCounterBlock(
const uint8_t* iv,
int iv_size) {
21 std::vector<uint8_t> counter_block(iv, iv + iv_size);
22 counter_block.insert(counter_block.end(),
30 bool WebMCreateDecryptConfig(
const uint8_t* data,
32 const uint8_t* key_id,
34 scoped_ptr<DecryptConfig>* decrypt_config,
36 int header_size = kWebMSignalByteSize;
37 if (data_size < header_size) {
38 DVLOG(1) <<
"Empty WebM sample.";
41 uint8_t signal_byte = data[0];
43 if (signal_byte & kWebMEncryptedSignal) {
45 header_size += kWebMIvSize;
46 if (data_size < header_size) {
47 DVLOG(1) <<
"Encrypted WebM sample too small to hold IV: " << data_size;
50 std::vector<SubsampleEntry> subsamples;
51 if (signal_byte & kWebMPartitionedSignal) {
53 header_size += kWebMNumPartitionsSize;
54 if (data_size < header_size) {
56 <<
"Encrypted WebM sample too small to hold number of partitions: "
60 uint8_t num_partitions = data[kWebMSignalByteSize + kWebMIvSize];
61 BufferReader offsets_buffer(data + header_size, data_size - header_size);
62 header_size += num_partitions * kWebMPartitionOffsetSize;
63 uint32_t subsample_offset = 0;
64 bool encrypted_subsample =
false;
65 uint16_t clear_size = 0;
66 uint32_t encrypted_size = 0;
67 for (uint8_t partition_idx = 0; partition_idx < num_partitions;
69 uint32_t partition_offset;
70 if (!offsets_buffer.Read4(&partition_offset)) {
72 <<
"Encrypted WebM sample too small to hold partition offsets: "
76 if (partition_offset < subsample_offset) {
77 DVLOG(1) <<
"Partition offsets out of order.";
80 if (encrypted_subsample) {
81 encrypted_size = partition_offset - subsample_offset;
82 subsamples.push_back(SubsampleEntry(clear_size, encrypted_size));
84 clear_size = partition_offset - subsample_offset;
85 if (partition_idx == (num_partitions - 1)) {
86 encrypted_size = data_size - header_size - subsample_offset - clear_size;
87 subsamples.push_back(SubsampleEntry(clear_size, encrypted_size));
90 subsample_offset = partition_offset;
91 encrypted_subsample = !encrypted_subsample;
93 if (!(num_partitions % 2)) {
95 clear_size = data_size - header_size - subsample_offset;
97 subsamples.push_back(SubsampleEntry(clear_size, encrypted_size));
100 decrypt_config->reset(
new DecryptConfig(
101 std::vector<uint8_t>(key_id, key_id + key_id_size),
102 GenerateWebMCounterBlock(data + kWebMSignalByteSize, kWebMIvSize),
106 decrypt_config->reset();
109 *data_offset = header_size;