aes_decryptor_unittest.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// Copyright 2013 The Chromium Authors. All rights reserved.
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// Use of this source code is governed by a BSD-style license that can be
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// found in the LICENSE file.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include <string>
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include <vector>
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include "base/basictypes.h"
98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "base/bind.h"
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "media/base/decoder_buffer.h"
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "media/base/decrypt_config.h"
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "media/base/mock_filters.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "media/cdm/aes_decryptor.h"
148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "media/webm/webm_constants.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "testing/gmock/include/gmock/gmock.h"
168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "testing/gtest/include/gtest/gtest.h"
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comusing ::testing::_;
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comusing ::testing::Gt;
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comusing ::testing::IsNull;
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comusing ::testing::NotNull;
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comusing ::testing::SaveArg;
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comusing ::testing::StrNe;
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comMATCHER(IsEmpty, "") { return arg.empty(); }
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comnamespace media {
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst uint8 kOriginalData[] = "Original subsample data.";
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst int kOriginalDataSize = 24;
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// In the examples below, 'k'(key) has to be 16 bytes, and will always require
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// 2 bytes of padding. 'kid'(keyid) is variable length, and may require 0, 1,
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// or 2 bytes of padding.
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst uint8 kKeyId[] = {
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // base64 equivalent is AAECAw
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    0x00, 0x01, 0x02, 0x03
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Key is 0x0405060708090a0b0c0d0e0f10111213,
42d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com// base64 equivalent is BAUGBwgJCgsMDQ4PEBESEw.
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst char kKeyAsJWK[] =
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "{"
45868074b50b0fc3e460d2aa97c1096827fe0a1935reed    "  \"keys\": ["
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "    {"
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "      \"kty\": \"oct\","
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "      \"kid\": \"AAECAw\","
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "    }"
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "  ]"
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    "}";
53868074b50b0fc3e460d2aa97c1096827fe0a1935reed
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Same kid as kKeyAsJWK, key to decrypt kEncryptedData2
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst char kKeyAlternateAsJWK[] =
56    "{"
57    "  \"keys\": ["
58    "    {"
59    "      \"kty\": \"oct\","
60    "      \"kid\": \"AAECAw\","
61    "      \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
62    "    }"
63    "  ]"
64    "}";
65
66const char kWrongKeyAsJWK[] =
67    "{"
68    "  \"keys\": ["
69    "    {"
70    "      \"kty\": \"oct\","
71    "      \"kid\": \"AAECAw\","
72    "      \"k\": \"7u7u7u7u7u7u7u7u7u7u7g\""
73    "    }"
74    "  ]"
75    "}";
76
77const char kWrongSizedKeyAsJWK[] =
78    "{"
79    "  \"keys\": ["
80    "    {"
81    "      \"kty\": \"oct\","
82    "      \"kid\": \"AAECAw\","
83    "      \"k\": \"AAECAw\""
84    "    }"
85    "  ]"
86    "}";
87
88const uint8 kIv[] = {
89  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
90  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
91};
92
93// kOriginalData encrypted with kKey and kIv but without any subsamples (or
94// equivalently using kSubsampleEntriesCypherOnly).
95const uint8 kEncryptedData[] = {
96  0x2f, 0x03, 0x09, 0xef, 0x71, 0xaf, 0x31, 0x16,
97  0xfa, 0x9d, 0x18, 0x43, 0x1e, 0x96, 0x71, 0xb5,
98  0xbf, 0xf5, 0x30, 0x53, 0x9a, 0x20, 0xdf, 0x95
99};
100
101// kOriginalData encrypted with kSubsampleKey and kSubsampleIv using
102// kSubsampleEntriesNormal.
103const uint8 kSubsampleEncryptedData[] = {
104  0x4f, 0x72, 0x09, 0x16, 0x09, 0xe6, 0x79, 0xad,
105  0x70, 0x73, 0x75, 0x62, 0x09, 0xbb, 0x83, 0x1d,
106  0x4d, 0x08, 0xd7, 0x78, 0xa4, 0xa7, 0xf1, 0x2e
107};
108
109const uint8 kOriginalData2[] = "Changed Original data.";
110
111const uint8 kIv2[] = {
112  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
114};
115
116const uint8 kKeyId2[] = {
117    // base64 equivalent is AAECAwQFBgcICQoLDA0ODxAREhM=
118    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
119    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
120    0x10, 0x11, 0x12, 0x13
121};
122
123const char kKey2AsJWK[] =
124    "{"
125    "  \"keys\": ["
126    "    {"
127    "      \"kty\": \"oct\","
128    "      \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
129    "      \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
130    "    }"
131    "  ]"
132    "}";
133
134// 'k' in bytes is x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20x21x22x23
135
136const uint8 kEncryptedData2[] = {
137  0x57, 0x66, 0xf4, 0x12, 0x1a, 0xed, 0xb5, 0x79,
138  0x1c, 0x8e, 0x25, 0xd7, 0x17, 0xe7, 0x5e, 0x16,
139  0xe3, 0x40, 0x08, 0x27, 0x11, 0xe9
140};
141
142// Subsample entries for testing. The sum of |cypher_bytes| and |clear_bytes| of
143// all entries must be equal to kOriginalDataSize to make the subsample entries
144// valid.
145
146const SubsampleEntry kSubsampleEntriesNormal[] = {
147  { 2, 7 },
148  { 3, 11 },
149  { 1, 0 }
150};
151
152const SubsampleEntry kSubsampleEntriesWrongSize[] = {
153  { 3, 6 }, // This entry doesn't match the correct entry.
154  { 3, 11 },
155  { 1, 0 }
156};
157
158const SubsampleEntry kSubsampleEntriesInvalidTotalSize[] = {
159  { 1, 1000 }, // This entry is too large.
160  { 3, 11 },
161  { 1, 0 }
162};
163
164const SubsampleEntry kSubsampleEntriesClearOnly[] = {
165  { 7, 0 },
166  { 8, 0 },
167  { 9, 0 }
168};
169
170const SubsampleEntry kSubsampleEntriesCypherOnly[] = {
171  { 0, 6 },
172  { 0, 8 },
173  { 0, 10 }
174};
175
176static scoped_refptr<DecoderBuffer> CreateEncryptedBuffer(
177    const std::vector<uint8>& data,
178    const std::vector<uint8>& key_id,
179    const std::vector<uint8>& iv,
180    int offset,
181    const std::vector<SubsampleEntry>& subsample_entries) {
182  DCHECK(!data.empty());
183  int padded_size = offset + data.size();
184  scoped_refptr<DecoderBuffer> encrypted_buffer(new DecoderBuffer(padded_size));
185  memcpy(encrypted_buffer->writable_data() + offset, &data[0], data.size());
186  CHECK(encrypted_buffer.get());
187  std::string key_id_string(
188      reinterpret_cast<const char*>(key_id.empty() ? NULL : &key_id[0]),
189      key_id.size());
190  std::string iv_string(
191      reinterpret_cast<const char*>(iv.empty() ? NULL : &iv[0]), iv.size());
192  encrypted_buffer->set_decrypt_config(scoped_ptr<DecryptConfig>(
193      new DecryptConfig(key_id_string, iv_string, offset, subsample_entries)));
194  return encrypted_buffer;
195}
196
197class AesDecryptorTest : public testing::Test {
198 public:
199  AesDecryptorTest()
200      : decryptor_(base::Bind(&AesDecryptorTest::OnSessionCreated,
201                              base::Unretained(this)),
202                   base::Bind(&AesDecryptorTest::OnSessionMessage,
203                              base::Unretained(this)),
204                   base::Bind(&AesDecryptorTest::OnSessionReady,
205                              base::Unretained(this)),
206                   base::Bind(&AesDecryptorTest::OnSessionClosed,
207                              base::Unretained(this)),
208                   base::Bind(&AesDecryptorTest::OnSessionError,
209                              base::Unretained(this))),
210        decrypt_cb_(base::Bind(&AesDecryptorTest::BufferDecrypted,
211                               base::Unretained(this))),
212        original_data_(kOriginalData, kOriginalData + kOriginalDataSize),
213        encrypted_data_(kEncryptedData,
214                        kEncryptedData + arraysize(kEncryptedData)),
215        subsample_encrypted_data_(
216            kSubsampleEncryptedData,
217            kSubsampleEncryptedData + arraysize(kSubsampleEncryptedData)),
218        key_id_(kKeyId, kKeyId + arraysize(kKeyId)),
219        iv_(kIv, kIv + arraysize(kIv)),
220        normal_subsample_entries_(
221            kSubsampleEntriesNormal,
222            kSubsampleEntriesNormal + arraysize(kSubsampleEntriesNormal)),
223        next_session_id_(1) {
224  }
225
226 protected:
227  // Creates a new session using |key_id|. Returns the session ID.
228  uint32 CreateSession(const std::vector<uint8>& key_id) {
229    DCHECK(!key_id.empty());
230    uint32 session_id = next_session_id_++;
231    EXPECT_CALL(*this, OnSessionCreated(session_id, StrNe(std::string())));
232    EXPECT_CALL(*this, OnSessionMessage(session_id, key_id, ""));
233    EXPECT_TRUE(decryptor_.CreateSession(
234        session_id, std::string(), &key_id[0], key_id.size()));
235    return session_id;
236  }
237
238  // Releases the session specified by |session_id|.
239  void ReleaseSession(uint32 session_id) {
240    EXPECT_CALL(*this, OnSessionClosed(session_id));
241    decryptor_.ReleaseSession(session_id);
242  }
243
244  enum AddKeyExpectation {
245    KEY_ADDED,
246    KEY_ERROR
247  };
248
249  // Updates the session specified by |session_id| with |key|. |result|
250  // tests that the update succeeds or generates an error.
251  void UpdateSessionAndExpect(uint32 session_id,
252                              const std::string& key,
253                              AddKeyExpectation result) {
254    DCHECK(!key.empty());
255
256    if (result == KEY_ADDED) {
257      EXPECT_CALL(*this, OnSessionReady(session_id));
258    } else if (result == KEY_ERROR) {
259      EXPECT_CALL(*this,
260                  OnSessionError(session_id, MediaKeys::kUnknownError, 0));
261    } else {
262      NOTREACHED();
263    }
264
265    decryptor_.UpdateSession(
266        session_id, reinterpret_cast<const uint8*>(key.c_str()), key.length());
267  }
268
269  MOCK_METHOD2(BufferDecrypted, void(Decryptor::Status,
270                                     const scoped_refptr<DecoderBuffer>&));
271
272  enum DecryptExpectation {
273    SUCCESS,
274    DATA_MISMATCH,
275    DATA_AND_SIZE_MISMATCH,
276    DECRYPT_ERROR,
277    NO_KEY
278  };
279
280  void DecryptAndExpect(const scoped_refptr<DecoderBuffer>& encrypted,
281                        const std::vector<uint8>& plain_text,
282                        DecryptExpectation result) {
283    scoped_refptr<DecoderBuffer> decrypted;
284
285    if (result == NO_KEY) {
286      EXPECT_CALL(*this, BufferDecrypted(Decryptor::kNoKey, IsNull()))
287          .WillOnce(SaveArg<1>(&decrypted));
288    } else if (result != DECRYPT_ERROR) {
289      EXPECT_CALL(*this, BufferDecrypted(Decryptor::kSuccess, NotNull()))
290          .WillOnce(SaveArg<1>(&decrypted));
291    } else {
292      EXPECT_CALL(*this, BufferDecrypted(Decryptor::kError, IsNull()))
293          .WillOnce(SaveArg<1>(&decrypted));
294    }
295
296    decryptor_.Decrypt(Decryptor::kVideo, encrypted, decrypt_cb_);
297
298    std::vector<uint8> decrypted_text;
299    if (decrypted && decrypted->data_size()) {
300      decrypted_text.assign(
301        decrypted->data(), decrypted->data() + decrypted->data_size());
302    }
303
304    switch (result) {
305      case SUCCESS:
306        EXPECT_EQ(plain_text, decrypted_text);
307        break;
308      case DATA_MISMATCH:
309        EXPECT_EQ(plain_text.size(), decrypted_text.size());
310        EXPECT_NE(plain_text, decrypted_text);
311        break;
312      case DATA_AND_SIZE_MISMATCH:
313        EXPECT_NE(plain_text.size(), decrypted_text.size());
314        break;
315      case DECRYPT_ERROR:
316      case NO_KEY:
317        EXPECT_TRUE(decrypted_text.empty());
318        break;
319    }
320  }
321
322  MOCK_METHOD2(OnSessionCreated,
323               void(uint32 session_id, const std::string& web_session_id));
324  MOCK_METHOD3(OnSessionMessage,
325               void(uint32 session_id,
326                    const std::vector<uint8>& message,
327                    const std::string& default_url));
328  MOCK_METHOD1(OnSessionReady, void(uint32 session_id));
329  MOCK_METHOD1(OnSessionClosed, void(uint32 session_id));
330  MOCK_METHOD3(OnSessionError,
331               void(uint32 session_id, MediaKeys::KeyError, int system_code));
332
333  AesDecryptor decryptor_;
334  AesDecryptor::DecryptCB decrypt_cb_;
335
336  // Constants for testing.
337  const std::vector<uint8> original_data_;
338  const std::vector<uint8> encrypted_data_;
339  const std::vector<uint8> subsample_encrypted_data_;
340  const std::vector<uint8> key_id_;
341  const std::vector<uint8> iv_;
342  const std::vector<SubsampleEntry> normal_subsample_entries_;
343  const std::vector<SubsampleEntry> no_subsample_entries_;
344
345  // Generate new session ID every time
346  uint32 next_session_id_;
347};
348
349TEST_F(AesDecryptorTest, CreateSessionWithNullInitData) {
350  uint32 session_id = 8;
351  EXPECT_CALL(*this, OnSessionMessage(session_id, IsEmpty(), ""));
352  EXPECT_CALL(*this, OnSessionCreated(session_id, StrNe(std::string())));
353  EXPECT_TRUE(decryptor_.CreateSession(session_id, std::string(), NULL, 0));
354}
355
356TEST_F(AesDecryptorTest, MultipleCreateSession) {
357  uint32 session_id1 = 10;
358  EXPECT_CALL(*this, OnSessionMessage(session_id1, IsEmpty(), ""));
359  EXPECT_CALL(*this, OnSessionCreated(session_id1, StrNe(std::string())));
360  EXPECT_TRUE(decryptor_.CreateSession(session_id1, std::string(), NULL, 0));
361
362  uint32 session_id2 = 11;
363  EXPECT_CALL(*this, OnSessionMessage(session_id2, IsEmpty(), ""));
364  EXPECT_CALL(*this, OnSessionCreated(session_id2, StrNe(std::string())));
365  EXPECT_TRUE(decryptor_.CreateSession(session_id2, std::string(), NULL, 0));
366
367  uint32 session_id3 = 23;
368  EXPECT_CALL(*this, OnSessionMessage(session_id3, IsEmpty(), ""));
369  EXPECT_CALL(*this, OnSessionCreated(session_id3, StrNe(std::string())));
370  EXPECT_TRUE(decryptor_.CreateSession(session_id3, std::string(), NULL, 0));
371}
372
373TEST_F(AesDecryptorTest, NormalDecryption) {
374  uint32 session_id = CreateSession(key_id_);
375  UpdateSessionAndExpect(session_id, kKeyAsJWK, KEY_ADDED);
376  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
377      encrypted_data_, key_id_, iv_, 0, no_subsample_entries_);
378  DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
379}
380
381TEST_F(AesDecryptorTest, DecryptionWithOffset) {
382  uint32 session_id = CreateSession(key_id_);
383  UpdateSessionAndExpect(session_id, kKeyAsJWK, KEY_ADDED);
384  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
385      encrypted_data_, key_id_, iv_, 23, no_subsample_entries_);
386  DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
387}
388
389TEST_F(AesDecryptorTest, UnencryptedFrame) {
390  // An empty iv string signals that the frame is unencrypted.
391  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
392      original_data_, key_id_, std::vector<uint8>(), 0, no_subsample_entries_);
393  DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
394}
395
396TEST_F(AesDecryptorTest, WrongKey) {
397  uint32 session_id = CreateSession(key_id_);
398  UpdateSessionAndExpect(session_id, kWrongKeyAsJWK, KEY_ADDED);
399  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
400      encrypted_data_, key_id_, iv_, 0, no_subsample_entries_);
401  DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
402}
403
404TEST_F(AesDecryptorTest, NoKey) {
405  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
406      encrypted_data_, key_id_, iv_, 0, no_subsample_entries_);
407  EXPECT_CALL(*this, BufferDecrypted(AesDecryptor::kNoKey, IsNull()));
408  decryptor_.Decrypt(Decryptor::kVideo, encrypted_buffer, decrypt_cb_);
409}
410
411TEST_F(AesDecryptorTest, KeyReplacement) {
412  uint32 session_id = CreateSession(key_id_);
413  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
414      encrypted_data_, key_id_, iv_, 0, no_subsample_entries_);
415
416  UpdateSessionAndExpect(session_id, kWrongKeyAsJWK, KEY_ADDED);
417  ASSERT_NO_FATAL_FAILURE(DecryptAndExpect(
418      encrypted_buffer, original_data_, DATA_MISMATCH));
419
420  UpdateSessionAndExpect(session_id, kKeyAsJWK, KEY_ADDED);
421  ASSERT_NO_FATAL_FAILURE(
422      DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
423}
424
425TEST_F(AesDecryptorTest, WrongSizedKey) {
426  uint32 session_id = CreateSession(key_id_);
427  UpdateSessionAndExpect(session_id, kWrongSizedKeyAsJWK, KEY_ERROR);
428}
429
430TEST_F(AesDecryptorTest, MultipleKeysAndFrames) {
431  uint32 session_id = CreateSession(key_id_);
432  UpdateSessionAndExpect(session_id, kKeyAsJWK, KEY_ADDED);
433  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
434      encrypted_data_, key_id_, iv_, 10, no_subsample_entries_);
435  ASSERT_NO_FATAL_FAILURE(
436      DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
437
438  UpdateSessionAndExpect(session_id, kKey2AsJWK, KEY_ADDED);
439
440  // The first key is still available after we added a second key.
441  ASSERT_NO_FATAL_FAILURE(
442      DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
443
444  // The second key is also available.
445  encrypted_buffer = CreateEncryptedBuffer(
446      std::vector<uint8>(kEncryptedData2,
447                         kEncryptedData2 + arraysize(kEncryptedData2)),
448      std::vector<uint8>(kKeyId2, kKeyId2 + arraysize(kKeyId2)),
449      std::vector<uint8>(kIv2, kIv2 + arraysize(kIv2)),
450      30,
451      no_subsample_entries_);
452  ASSERT_NO_FATAL_FAILURE(DecryptAndExpect(
453      encrypted_buffer,
454      std::vector<uint8>(kOriginalData2,
455                         kOriginalData2 + arraysize(kOriginalData2) - 1),
456      SUCCESS));
457}
458
459TEST_F(AesDecryptorTest, CorruptedIv) {
460  uint32 session_id = CreateSession(key_id_);
461  UpdateSessionAndExpect(session_id, kKeyAsJWK, KEY_ADDED);
462
463  std::vector<uint8> bad_iv = iv_;
464  bad_iv[1]++;
465
466  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
467      encrypted_data_, key_id_, bad_iv, 0, no_subsample_entries_);
468
469  DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
470}
471
472TEST_F(AesDecryptorTest, CorruptedData) {
473  uint32 session_id = CreateSession(key_id_);
474  UpdateSessionAndExpect(session_id, kKeyAsJWK, KEY_ADDED);
475
476  std::vector<uint8> bad_data = encrypted_data_;
477  bad_data[1]++;
478
479  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
480      bad_data, key_id_, iv_, 0, no_subsample_entries_);
481  DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
482}
483
484TEST_F(AesDecryptorTest, EncryptedAsUnencryptedFailure) {
485  uint32 session_id = CreateSession(key_id_);
486  UpdateSessionAndExpect(session_id, kKeyAsJWK, KEY_ADDED);
487  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
488      encrypted_data_, key_id_, std::vector<uint8>(), 0, no_subsample_entries_);
489  DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
490}
491
492TEST_F(AesDecryptorTest, SubsampleDecryption) {
493  uint32 session_id = CreateSession(key_id_);
494  UpdateSessionAndExpect(session_id, kKeyAsJWK, KEY_ADDED);
495  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
496      subsample_encrypted_data_, key_id_, iv_, 0, normal_subsample_entries_);
497  DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
498}
499
500// Ensures noninterference of data offset and subsample mechanisms. We never
501// expect to encounter this in the wild, but since the DecryptConfig doesn't
502// disallow such a configuration, it should be covered.
503TEST_F(AesDecryptorTest, SubsampleDecryptionWithOffset) {
504  uint32 session_id = CreateSession(key_id_);
505  UpdateSessionAndExpect(session_id, kKeyAsJWK, KEY_ADDED);
506  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
507      subsample_encrypted_data_, key_id_, iv_, 23, normal_subsample_entries_);
508  DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
509}
510
511TEST_F(AesDecryptorTest, SubsampleWrongSize) {
512  uint32 session_id = CreateSession(key_id_);
513  UpdateSessionAndExpect(session_id, kKeyAsJWK, KEY_ADDED);
514
515  std::vector<SubsampleEntry> subsample_entries_wrong_size(
516      kSubsampleEntriesWrongSize,
517      kSubsampleEntriesWrongSize + arraysize(kSubsampleEntriesWrongSize));
518
519  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
520      subsample_encrypted_data_, key_id_, iv_, 0, subsample_entries_wrong_size);
521  DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
522}
523
524TEST_F(AesDecryptorTest, SubsampleInvalidTotalSize) {
525  uint32 session_id = CreateSession(key_id_);
526  UpdateSessionAndExpect(session_id, kKeyAsJWK, KEY_ADDED);
527
528  std::vector<SubsampleEntry> subsample_entries_invalid_total_size(
529      kSubsampleEntriesInvalidTotalSize,
530      kSubsampleEntriesInvalidTotalSize +
531          arraysize(kSubsampleEntriesInvalidTotalSize));
532
533  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
534      subsample_encrypted_data_, key_id_, iv_, 0,
535      subsample_entries_invalid_total_size);
536  DecryptAndExpect(encrypted_buffer, original_data_, DECRYPT_ERROR);
537}
538
539// No cypher bytes in any of the subsamples.
540TEST_F(AesDecryptorTest, SubsampleClearBytesOnly) {
541  uint32 session_id = CreateSession(key_id_);
542  UpdateSessionAndExpect(session_id, kKeyAsJWK, KEY_ADDED);
543
544  std::vector<SubsampleEntry> clear_only_subsample_entries(
545      kSubsampleEntriesClearOnly,
546      kSubsampleEntriesClearOnly + arraysize(kSubsampleEntriesClearOnly));
547
548  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
549      original_data_, key_id_, iv_, 0, clear_only_subsample_entries);
550  DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
551}
552
553// No clear bytes in any of the subsamples.
554TEST_F(AesDecryptorTest, SubsampleCypherBytesOnly) {
555  uint32 session_id = CreateSession(key_id_);
556  UpdateSessionAndExpect(session_id, kKeyAsJWK, KEY_ADDED);
557
558  std::vector<SubsampleEntry> cypher_only_subsample_entries(
559      kSubsampleEntriesCypherOnly,
560      kSubsampleEntriesCypherOnly + arraysize(kSubsampleEntriesCypherOnly));
561
562  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
563      encrypted_data_, key_id_, iv_, 0, cypher_only_subsample_entries);
564  DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
565}
566
567TEST_F(AesDecryptorTest, ReleaseSession) {
568  uint32 session_id = CreateSession(key_id_);
569  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
570      encrypted_data_, key_id_, iv_, 0, no_subsample_entries_);
571
572  UpdateSessionAndExpect(session_id, kKeyAsJWK, KEY_ADDED);
573  ASSERT_NO_FATAL_FAILURE(
574      DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
575
576  ReleaseSession(session_id);
577}
578
579TEST_F(AesDecryptorTest, NoKeyAfterReleaseSession) {
580  uint32 session_id = CreateSession(key_id_);
581  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
582      encrypted_data_, key_id_, iv_, 0, no_subsample_entries_);
583
584  UpdateSessionAndExpect(session_id, kKeyAsJWK, KEY_ADDED);
585  ASSERT_NO_FATAL_FAILURE(
586      DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
587
588  ReleaseSession(session_id);
589  ASSERT_NO_FATAL_FAILURE(
590      DecryptAndExpect(encrypted_buffer, original_data_, NO_KEY));
591}
592
593TEST_F(AesDecryptorTest, LatestKeyUsed) {
594  uint32 session_id1 = CreateSession(key_id_);
595  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
596      encrypted_data_, key_id_, iv_, 0, no_subsample_entries_);
597
598  // Add alternate key, buffer should not be decoded properly.
599  UpdateSessionAndExpect(session_id1, kKeyAlternateAsJWK, KEY_ADDED);
600  ASSERT_NO_FATAL_FAILURE(
601      DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH));
602
603  // Create a second session with a correct key value for key_id_.
604  uint32 session_id2 = CreateSession(key_id_);
605  UpdateSessionAndExpect(session_id2, kKeyAsJWK, KEY_ADDED);
606
607  // Should be able to decode with latest key.
608  ASSERT_NO_FATAL_FAILURE(
609      DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
610}
611
612TEST_F(AesDecryptorTest, LatestKeyUsedAfterReleaseSession) {
613  uint32 session_id1 = CreateSession(key_id_);
614  scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
615      encrypted_data_, key_id_, iv_, 0, no_subsample_entries_);
616  UpdateSessionAndExpect(session_id1, kKeyAsJWK, KEY_ADDED);
617  ASSERT_NO_FATAL_FAILURE(
618      DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
619
620  // Create a second session with a different key value for key_id_.
621  uint32 session_id2 = CreateSession(key_id_);
622  UpdateSessionAndExpect(session_id2, kKeyAlternateAsJWK, KEY_ADDED);
623
624  // Should not be able to decode with new key.
625  ASSERT_NO_FATAL_FAILURE(
626      DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH));
627
628  // Close second session, should revert to original key.
629  ReleaseSession(session_id2);
630  ASSERT_NO_FATAL_FAILURE(
631      DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
632}
633
634TEST_F(AesDecryptorTest, JWKKey) {
635  uint32 session_id = CreateSession(key_id_);
636
637  // Try a simple JWK key (i.e. not in a set)
638  const std::string kJwkSimple =
639      "{"
640      "  \"kty\": \"oct\","
641      "  \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
642      "  \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
643      "}";
644  UpdateSessionAndExpect(session_id, kJwkSimple, KEY_ERROR);
645
646  // Try a key list with multiple entries.
647  const std::string kJwksMultipleEntries =
648      "{"
649      "  \"keys\": ["
650      "    {"
651      "      \"kty\": \"oct\","
652      "      \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
653      "      \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
654      "    },"
655      "    {"
656      "      \"kty\": \"oct\","
657      "      \"kid\": \"JCUmJygpKissLS4vMA\","
658      "      \"k\":\"MTIzNDU2Nzg5Ojs8PT4/QA\""
659      "    }"
660      "  ]"
661      "}";
662  UpdateSessionAndExpect(session_id, kJwksMultipleEntries, KEY_ADDED);
663
664  // Try a key with no spaces and some \n plus additional fields.
665  const std::string kJwksNoSpaces =
666      "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\",\"alg\":\"A128KW\","
667      "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"GawgguFyGrWKav7AX4VKUg"
668      "\",\"foo\":\"bar\"}]}\n\n";
669  UpdateSessionAndExpect(session_id, kJwksNoSpaces, KEY_ADDED);
670
671  // Try some non-ASCII characters.
672  UpdateSessionAndExpect(
673      session_id, "This is not ASCII due to \xff\xfe\xfd in it.", KEY_ERROR);
674
675  // Try a badly formatted key. Assume that the JSON parser is fully tested,
676  // so we won't try a lot of combinations. However, need a test to ensure
677  // that the code doesn't crash if invalid JSON received.
678  UpdateSessionAndExpect(session_id, "This is not a JSON key.", KEY_ERROR);
679
680  // Try passing some valid JSON that is not a dictionary at the top level.
681  UpdateSessionAndExpect(session_id, "40", KEY_ERROR);
682
683  // Try an empty dictionary.
684  UpdateSessionAndExpect(session_id, "{ }", KEY_ERROR);
685
686  // Try an empty 'keys' dictionary.
687  UpdateSessionAndExpect(session_id, "{ \"keys\": [] }", KEY_ERROR);
688
689  // Try with 'keys' not a dictionary.
690  UpdateSessionAndExpect(session_id, "{ \"keys\":\"1\" }", KEY_ERROR);
691
692  // Try with 'keys' a list of integers.
693  UpdateSessionAndExpect(session_id, "{ \"keys\": [ 1, 2, 3 ] }", KEY_ERROR);
694
695  // Try padding(=) at end of 'k' base64 string.
696  const std::string kJwksWithPaddedKey =
697      "{"
698      "  \"keys\": ["
699      "    {"
700      "      \"kty\": \"oct\","
701      "      \"kid\": \"AAECAw\","
702      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw==\""
703      "    }"
704      "  ]"
705      "}";
706  UpdateSessionAndExpect(session_id, kJwksWithPaddedKey, KEY_ERROR);
707
708  // Try padding(=) at end of 'kid' base64 string.
709  const std::string kJwksWithPaddedKeyId =
710      "{"
711      "  \"keys\": ["
712      "    {"
713      "      \"kty\": \"oct\","
714      "      \"kid\": \"AAECAw==\","
715      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
716      "    }"
717      "  ]"
718      "}";
719  UpdateSessionAndExpect(session_id, kJwksWithPaddedKeyId, KEY_ERROR);
720
721  // Try a key with invalid base64 encoding.
722  const std::string kJwksWithInvalidBase64 =
723      "{"
724      "  \"keys\": ["
725      "    {"
726      "      \"kty\": \"oct\","
727      "      \"kid\": \"!@#$%^&*()\","
728      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
729      "    }"
730      "  ]"
731      "}";
732  UpdateSessionAndExpect(session_id, kJwksWithInvalidBase64, KEY_ERROR);
733
734  // Try a 3-byte 'kid' where no base64 padding is required.
735  // |kJwksMultipleEntries| above has 2 'kid's that require 1 and 2 padding
736  // bytes. Note that 'k' has to be 16 bytes, so it will always require padding.
737  const std::string kJwksWithNoPadding =
738      "{"
739      "  \"keys\": ["
740      "    {"
741      "      \"kty\": \"oct\","
742      "      \"kid\": \"Kiss\","
743      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
744      "    }"
745      "  ]"
746      "}";
747  UpdateSessionAndExpect(session_id, kJwksWithNoPadding, KEY_ADDED);
748
749  // Empty key id.
750  const std::string kJwksWithEmptyKeyId =
751      "{"
752      "  \"keys\": ["
753      "    {"
754      "      \"kty\": \"oct\","
755      "      \"kid\": \"\","
756      "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
757      "    }"
758      "  ]"
759      "}";
760  UpdateSessionAndExpect(session_id, kJwksWithEmptyKeyId, KEY_ERROR);
761}
762
763}  // namespace media
764