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