cenc_decryptor_unittest.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "media/cdm/cenc_decryptor.h"
  5. #include <stdint.h>
  6. #include <algorithm>
  7. #include <string>
  8. #include <vector>
  9. #include "base/containers/span.h"
  10. #include "base/time/time.h"
  11. #include "crypto/encryptor.h"
  12. #include "crypto/symmetric_key.h"
  13. #include "media/base/decoder_buffer.h"
  14. #include "media/base/decrypt_config.h"
  15. #include "testing/gtest/include/gtest/gtest.h"
  16. namespace media {
  17. namespace {
  18. // Keys and IVs have to be 128 bits.
  19. const uint8_t kKey[] = {0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
  20. 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13};
  21. static_assert(std::size(kKey) * 8 == 128, "kKey must be 128 bits");
  22. const uint8_t kIv[] = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
  23. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  24. static_assert(std::size(kIv) * 8 == 128, "kIv must be 128 bits");
  25. const uint8_t kOneBlock[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
  26. 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'};
  27. const uint8_t kPartialBlock[] = {'a', 'b', 'c', 'd', 'e', 'f'};
  28. std::string MakeString(const std::vector<uint8_t>& chars) {
  29. return std::string(chars.begin(), chars.end());
  30. }
  31. // Combine multiple std::vector<uint8_t> into one.
  32. std::vector<uint8_t> Combine(const std::vector<std::vector<uint8_t>>& inputs) {
  33. std::vector<uint8_t> result;
  34. for (const auto& input : inputs)
  35. result.insert(result.end(), input.begin(), input.end());
  36. return result;
  37. }
  38. // Returns a std::vector<uint8_t> containing |count| copies of |input|.
  39. std::vector<uint8_t> Repeat(const std::vector<uint8_t>& input, size_t count) {
  40. std::vector<uint8_t> result;
  41. for (size_t i = 0; i < count; ++i)
  42. result.insert(result.end(), input.begin(), input.end());
  43. return result;
  44. }
  45. } // namespace
  46. // These tests only test decryption logic.
  47. class CencDecryptorTest : public testing::Test {
  48. public:
  49. CencDecryptorTest()
  50. : key_(crypto::SymmetricKey::Import(
  51. crypto::SymmetricKey::AES,
  52. std::string(kKey, kKey + std::size(kKey)))),
  53. iv_(kIv, kIv + std::size(kIv)),
  54. one_block_(kOneBlock, kOneBlock + std::size(kOneBlock)),
  55. partial_block_(kPartialBlock,
  56. kPartialBlock + std::size(kPartialBlock)) {}
  57. // Excrypt |original| using AES-CTR encryption with |key| and |iv|.
  58. std::vector<uint8_t> Encrypt(const std::vector<uint8_t>& original,
  59. const crypto::SymmetricKey& key,
  60. const std::string& iv) {
  61. crypto::Encryptor encryptor;
  62. EXPECT_TRUE(encryptor.Init(&key, crypto::Encryptor::CTR, ""));
  63. EXPECT_TRUE(encryptor.SetCounter(iv));
  64. std::string ciphertext;
  65. EXPECT_TRUE(encryptor.Encrypt(MakeString(original), &ciphertext));
  66. DCHECK_EQ(ciphertext.size(), original.size());
  67. return std::vector<uint8_t>(ciphertext.begin(), ciphertext.end());
  68. }
  69. // Returns a 'cenc' DecoderBuffer using the data and other parameters.
  70. scoped_refptr<DecoderBuffer> CreateEncryptedBuffer(
  71. const std::vector<uint8_t>& data,
  72. const std::string& iv,
  73. const std::vector<SubsampleEntry>& subsample_entries) {
  74. EXPECT_FALSE(data.empty());
  75. EXPECT_FALSE(iv.empty());
  76. scoped_refptr<DecoderBuffer> encrypted_buffer =
  77. DecoderBuffer::CopyFrom(data.data(), data.size());
  78. // Key_ID is never used.
  79. encrypted_buffer->set_decrypt_config(
  80. DecryptConfig::CreateCencConfig("key_id", iv, subsample_entries));
  81. return encrypted_buffer;
  82. }
  83. // Calls DecryptCencBuffer() to decrypt |encrypted| using |key|, and then
  84. // returns the decrypted buffer (empty if decryption fails).
  85. std::vector<uint8_t> DecryptWithKey(scoped_refptr<DecoderBuffer> encrypted,
  86. const crypto::SymmetricKey& key) {
  87. scoped_refptr<DecoderBuffer> decrypted = DecryptCencBuffer(*encrypted, key);
  88. std::vector<uint8_t> decrypted_data;
  89. if (decrypted.get()) {
  90. EXPECT_TRUE(decrypted->data_size());
  91. decrypted_data.assign(decrypted->data(),
  92. decrypted->data() + decrypted->data_size());
  93. }
  94. return decrypted_data;
  95. }
  96. // Constants for testing.
  97. const std::unique_ptr<crypto::SymmetricKey> key_;
  98. const std::string iv_;
  99. const std::vector<uint8_t> one_block_;
  100. const std::vector<uint8_t> partial_block_;
  101. };
  102. TEST_F(CencDecryptorTest, OneBlock) {
  103. auto encrypted_block = Encrypt(one_block_, *key_, iv_);
  104. // Only 1 subsample, all encrypted data.
  105. std::vector<SubsampleEntry> subsamples = {
  106. {0, static_cast<uint32_t>(encrypted_block.size())}};
  107. auto encrypted_buffer =
  108. CreateEncryptedBuffer(encrypted_block, iv_, subsamples);
  109. EXPECT_EQ(one_block_, DecryptWithKey(encrypted_buffer, *key_));
  110. }
  111. TEST_F(CencDecryptorTest, ExtraData) {
  112. auto encrypted_block = Encrypt(one_block_, *key_, iv_);
  113. // Only 1 subsample, all encrypted data.
  114. std::vector<SubsampleEntry> subsamples = {
  115. {0, static_cast<uint32_t>(encrypted_block.size())}};
  116. auto encrypted_buffer =
  117. CreateEncryptedBuffer(encrypted_block, iv_, subsamples);
  118. encrypted_buffer->set_timestamp(base::Days(2));
  119. encrypted_buffer->set_duration(base::Minutes(5));
  120. encrypted_buffer->set_is_key_frame(true);
  121. encrypted_buffer->CopySideDataFrom(encrypted_block.data(),
  122. encrypted_block.size());
  123. auto decrypted_buffer = DecryptCencBuffer(*encrypted_buffer, *key_);
  124. EXPECT_EQ(encrypted_buffer->timestamp(), decrypted_buffer->timestamp());
  125. EXPECT_EQ(encrypted_buffer->duration(), decrypted_buffer->duration());
  126. EXPECT_EQ(encrypted_buffer->end_of_stream(),
  127. decrypted_buffer->end_of_stream());
  128. EXPECT_EQ(encrypted_buffer->is_key_frame(), decrypted_buffer->is_key_frame());
  129. EXPECT_EQ(encrypted_buffer->side_data_size(),
  130. decrypted_buffer->side_data_size());
  131. EXPECT_TRUE(std::equal(
  132. encrypted_buffer->side_data(),
  133. encrypted_buffer->side_data() + encrypted_buffer->side_data_size(),
  134. decrypted_buffer->side_data(),
  135. decrypted_buffer->side_data() + encrypted_buffer->side_data_size()));
  136. }
  137. TEST_F(CencDecryptorTest, NoSubsamples) {
  138. auto encrypted_block = Encrypt(one_block_, *key_, iv_);
  139. // No subsamples specified.
  140. std::vector<SubsampleEntry> subsamples = {};
  141. auto encrypted_buffer =
  142. CreateEncryptedBuffer(encrypted_block, iv_, subsamples);
  143. EXPECT_EQ(one_block_, DecryptWithKey(encrypted_buffer, *key_));
  144. }
  145. TEST_F(CencDecryptorTest, BadSubsamples) {
  146. auto encrypted_block = Encrypt(one_block_, *key_, iv_);
  147. // Subsample size > data size.
  148. std::vector<SubsampleEntry> subsamples = {
  149. {0, static_cast<uint32_t>(encrypted_block.size() + 1)}};
  150. auto encrypted_buffer =
  151. CreateEncryptedBuffer(encrypted_block, iv_, subsamples);
  152. EXPECT_EQ(std::vector<uint8_t>(), DecryptWithKey(encrypted_buffer, *key_));
  153. }
  154. TEST_F(CencDecryptorTest, InvalidIv) {
  155. auto encrypted_block = Encrypt(one_block_, *key_, iv_);
  156. std::vector<SubsampleEntry> subsamples = {
  157. {0, static_cast<uint32_t>(encrypted_block.size())}};
  158. // Use an invalid IV for decryption. Call should succeed, but return
  159. // something other than the original data.
  160. std::string invalid_iv(iv_.size(), 'a');
  161. auto encrypted_buffer =
  162. CreateEncryptedBuffer(encrypted_block, invalid_iv, subsamples);
  163. EXPECT_NE(one_block_, DecryptWithKey(encrypted_buffer, *key_));
  164. }
  165. TEST_F(CencDecryptorTest, InvalidKey) {
  166. std::unique_ptr<crypto::SymmetricKey> bad_key = crypto::SymmetricKey::Import(
  167. crypto::SymmetricKey::AES, std::string(std::size(kKey), 'b'));
  168. auto encrypted_block = Encrypt(one_block_, *key_, iv_);
  169. std::vector<SubsampleEntry> subsamples = {
  170. {0, static_cast<uint32_t>(encrypted_block.size())}};
  171. // Use a different key for decryption. Call should succeed, but return
  172. // something other than the original data.
  173. auto encrypted_buffer =
  174. CreateEncryptedBuffer(encrypted_block, iv_, subsamples);
  175. EXPECT_NE(one_block_, DecryptWithKey(encrypted_buffer, *bad_key));
  176. }
  177. TEST_F(CencDecryptorTest, PartialBlock) {
  178. auto encrypted_block = Encrypt(partial_block_, *key_, iv_);
  179. // Only 1 subsample, all encrypted data.
  180. std::vector<SubsampleEntry> subsamples = {
  181. {0, static_cast<uint32_t>(encrypted_block.size())}};
  182. auto encrypted_buffer =
  183. CreateEncryptedBuffer(encrypted_block, iv_, subsamples);
  184. EXPECT_EQ(partial_block_, DecryptWithKey(encrypted_buffer, *key_));
  185. }
  186. TEST_F(CencDecryptorTest, MultipleSubsamples) {
  187. // Encrypt 3 copies of |one_block_| together.
  188. auto encrypted_block = Encrypt(Repeat(one_block_, 3), *key_, iv_);
  189. // Treat as 3 subsamples.
  190. std::vector<SubsampleEntry> subsamples = {
  191. {0, static_cast<uint32_t>(one_block_.size())},
  192. {0, static_cast<uint32_t>(one_block_.size())},
  193. {0, static_cast<uint32_t>(one_block_.size())}};
  194. auto encrypted_buffer =
  195. CreateEncryptedBuffer(encrypted_block, iv_, subsamples);
  196. EXPECT_EQ(Repeat(one_block_, 3), DecryptWithKey(encrypted_buffer, *key_));
  197. }
  198. TEST_F(CencDecryptorTest, MultipleSubsamplesWithClearBytes) {
  199. // Create a buffer that looks like:
  200. // subsamples: | subsample#1 | subsample#2 | subsample#3 |
  201. // | clear | encrypted | clear | encrypted | clear |
  202. // source: | one | partial* | partial | one* | partial |
  203. // where * means the source is encrypted
  204. auto encrypted_block =
  205. Encrypt(Combine({partial_block_, one_block_}), *key_, iv_);
  206. std::vector<uint8_t> encrypted_partial_block(
  207. encrypted_block.begin(), encrypted_block.begin() + partial_block_.size());
  208. EXPECT_EQ(encrypted_partial_block.size(), partial_block_.size());
  209. std::vector<uint8_t> encrypted_one_block(
  210. encrypted_block.begin() + partial_block_.size(), encrypted_block.end());
  211. EXPECT_EQ(encrypted_one_block.size(), one_block_.size());
  212. auto input_data =
  213. Combine({one_block_, encrypted_partial_block, partial_block_,
  214. encrypted_one_block, partial_block_});
  215. auto expected_result = Combine(
  216. {one_block_, partial_block_, partial_block_, one_block_, partial_block_});
  217. std::vector<SubsampleEntry> subsamples = {
  218. {static_cast<uint32_t>(one_block_.size()),
  219. static_cast<uint32_t>(partial_block_.size())},
  220. {static_cast<uint32_t>(partial_block_.size()),
  221. static_cast<uint32_t>(one_block_.size())},
  222. {static_cast<uint32_t>(partial_block_.size()), 0}};
  223. auto encrypted_buffer = CreateEncryptedBuffer(input_data, iv_, subsamples);
  224. EXPECT_EQ(expected_result, DecryptWithKey(encrypted_buffer, *key_));
  225. }
  226. } // namespace media