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