Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / media / cdm / aes_decryptor_unittest.cc
blob39a5036cb70a8327cb315ea8243f8d87b9b954fc
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.
5 #include <string>
6 #include <vector>
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"
17 using ::testing::_;
18 using ::testing::Gt;
19 using ::testing::IsNull;
20 using ::testing::NotNull;
21 using ::testing::SaveArg;
22 using ::testing::StrNe;
24 MATCHER(IsEmpty, "") { return arg.empty(); }
26 namespace media {
28 const uint8 kOriginalData[] = "Original subsample data.";
29 const int kOriginalDataSize = 24;
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.
35 const uint8 kKeyId[] = {
36 // base64 equivalent is AAECAw
37 0x00, 0x01, 0x02, 0x03
40 // Key is 0x0405060708090a0b0c0d0e0f10111213,
41 // base64 equivalent is BAUGBwgJCgsMDQ4PEBESEw.
42 const char kKeyAsJWK[] =
43 "{"
44 " \"keys\": ["
45 " {"
46 " \"kty\": \"oct\","
47 " \"kid\": \"AAECAw\","
48 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
49 " }"
50 " ]"
51 "}";
53 // Same kid as kKeyAsJWK, key to decrypt kEncryptedData2
54 const char kKeyAlternateAsJWK[] =
55 "{"
56 " \"keys\": ["
57 " {"
58 " \"kty\": \"oct\","
59 " \"kid\": \"AAECAw\","
60 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
61 " }"
62 " ]"
63 "}";
65 const char kWrongKeyAsJWK[] =
66 "{"
67 " \"keys\": ["
68 " {"
69 " \"kty\": \"oct\","
70 " \"kid\": \"AAECAw\","
71 " \"k\": \"7u7u7u7u7u7u7u7u7u7u7g\""
72 " }"
73 " ]"
74 "}";
76 const char kWrongSizedKeyAsJWK[] =
77 "{"
78 " \"keys\": ["
79 " {"
80 " \"kty\": \"oct\","
81 " \"kid\": \"AAECAw\","
82 " \"k\": \"AAECAw\""
83 " }"
84 " ]"
85 "}";
87 const uint8 kIv[] = {
88 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
92 // kOriginalData encrypted with kKey and kIv but without any subsamples (or
93 // equivalently using kSubsampleEntriesCypherOnly).
94 const 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
100 // kOriginalData encrypted with kSubsampleKey and kSubsampleIv using
101 // kSubsampleEntriesNormal.
102 const 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
108 const uint8 kOriginalData2[] = "Changed Original data.";
110 const uint8 kIv2[] = {
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
115 const 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
122 const char kKey2AsJWK[] =
124 " \"keys\": ["
125 " {"
126 " \"kty\": \"oct\","
127 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
128 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
129 " }"
130 " ]"
131 "}";
133 // 'k' in bytes is x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20x21x22x23
135 const 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
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.
145 const SubsampleEntry kSubsampleEntriesNormal[] = {
146 { 2, 7 },
147 { 3, 11 },
148 { 1, 0 }
151 const SubsampleEntry kSubsampleEntriesWrongSize[] = {
152 { 3, 6 }, // This entry doesn't match the correct entry.
153 { 3, 11 },
154 { 1, 0 }
157 const SubsampleEntry kSubsampleEntriesInvalidTotalSize[] = {
158 { 1, 1000 }, // This entry is too large.
159 { 3, 11 },
160 { 1, 0 }
163 const SubsampleEntry kSubsampleEntriesClearOnly[] = {
164 { 7, 0 },
165 { 8, 0 },
166 { 9, 0 }
169 const SubsampleEntry kSubsampleEntriesCypherOnly[] = {
170 { 0, 6 },
171 { 0, 8 },
172 { 0, 10 }
175 static 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;
194 class 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) {
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;
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);
241 enum UpdateSessionExpectation {
242 SESSION_READY,
243 SESSION_ERROR
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());
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;
263 decryptor_.UpdateSession(
264 session_id, reinterpret_cast<const uint8*>(key.c_str()), key.length());
267 MOCK_METHOD2(BufferDecrypted, void(Decryptor::Status,
268 const scoped_refptr<DecoderBuffer>&));
270 enum DecryptExpectation {
271 SUCCESS,
272 DATA_MISMATCH,
273 DATA_AND_SIZE_MISMATCH,
274 DECRYPT_ERROR,
275 NO_KEY
278 void DecryptAndExpect(const scoped_refptr<DecoderBuffer>& encrypted,
279 const std::vector<uint8>& plain_text,
280 DecryptExpectation result) {
281 scoped_refptr<DecoderBuffer> decrypted;
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;
300 decryptor_.Decrypt(Decryptor::kVideo, encrypted, decrypt_cb_);
302 std::vector<uint8> decrypted_text;
303 if (decrypted && decrypted->data_size()) {
304 decrypted_text.assign(
305 decrypted->data(), decrypted->data() + decrypted->data_size());
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;
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));
339 AesDecryptor decryptor_;
340 AesDecryptor::DecryptCB decrypt_cb_;
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_;
351 // Generate new session ID every time
352 uint32 next_session_id_;
355 TEST_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));
362 TEST_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));
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));
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));
379 TEST_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);
387 TEST_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);
394 TEST_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);
402 TEST_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_);
409 TEST_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_);
414 UpdateSessionAndExpect(session_id, kWrongKeyAsJWK, SESSION_READY);
415 ASSERT_NO_FATAL_FAILURE(DecryptAndExpect(
416 encrypted_buffer, original_data_, DATA_MISMATCH));
418 UpdateSessionAndExpect(session_id, kKeyAsJWK, SESSION_READY);
419 ASSERT_NO_FATAL_FAILURE(
420 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
423 TEST_F(AesDecryptorTest, WrongSizedKey) {
424 uint32 session_id = CreateSession(key_id_);
425 UpdateSessionAndExpect(session_id, kWrongSizedKeyAsJWK, SESSION_ERROR);
428 TEST_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));
436 UpdateSessionAndExpect(session_id, kKey2AsJWK, SESSION_READY);
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));
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));
456 TEST_F(AesDecryptorTest, CorruptedIv) {
457 uint32 session_id = CreateSession(key_id_);
458 UpdateSessionAndExpect(session_id, kKeyAsJWK, SESSION_READY);
460 std::vector<uint8> bad_iv = iv_;
461 bad_iv[1]++;
463 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
464 encrypted_data_, key_id_, bad_iv, no_subsample_entries_);
466 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
469 TEST_F(AesDecryptorTest, CorruptedData) {
470 uint32 session_id = CreateSession(key_id_);
471 UpdateSessionAndExpect(session_id, kKeyAsJWK, SESSION_READY);
473 std::vector<uint8> bad_data = encrypted_data_;
474 bad_data[1]++;
476 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
477 bad_data, key_id_, iv_, no_subsample_entries_);
478 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
481 TEST_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);
489 TEST_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);
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.
500 TEST_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);
508 TEST_F(AesDecryptorTest, SubsampleWrongSize) {
509 uint32 session_id = CreateSession(key_id_);
510 UpdateSessionAndExpect(session_id, kKeyAsJWK, SESSION_READY);
512 std::vector<SubsampleEntry> subsample_entries_wrong_size(
513 kSubsampleEntriesWrongSize,
514 kSubsampleEntriesWrongSize + arraysize(kSubsampleEntriesWrongSize));
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);
521 TEST_F(AesDecryptorTest, SubsampleInvalidTotalSize) {
522 uint32 session_id = CreateSession(key_id_);
523 UpdateSessionAndExpect(session_id, kKeyAsJWK, SESSION_READY);
525 std::vector<SubsampleEntry> subsample_entries_invalid_total_size(
526 kSubsampleEntriesInvalidTotalSize,
527 kSubsampleEntriesInvalidTotalSize +
528 arraysize(kSubsampleEntriesInvalidTotalSize));
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);
536 // No cypher bytes in any of the subsamples.
537 TEST_F(AesDecryptorTest, SubsampleClearBytesOnly) {
538 uint32 session_id = CreateSession(key_id_);
539 UpdateSessionAndExpect(session_id, kKeyAsJWK, SESSION_READY);
541 std::vector<SubsampleEntry> clear_only_subsample_entries(
542 kSubsampleEntriesClearOnly,
543 kSubsampleEntriesClearOnly + arraysize(kSubsampleEntriesClearOnly));
545 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
546 original_data_, key_id_, iv_, clear_only_subsample_entries);
547 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
550 // No clear bytes in any of the subsamples.
551 TEST_F(AesDecryptorTest, SubsampleCypherBytesOnly) {
552 uint32 session_id = CreateSession(key_id_);
553 UpdateSessionAndExpect(session_id, kKeyAsJWK, SESSION_READY);
555 std::vector<SubsampleEntry> cypher_only_subsample_entries(
556 kSubsampleEntriesCypherOnly,
557 kSubsampleEntriesCypherOnly + arraysize(kSubsampleEntriesCypherOnly));
559 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
560 encrypted_data_, key_id_, iv_, cypher_only_subsample_entries);
561 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
564 TEST_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_);
569 UpdateSessionAndExpect(session_id, kKeyAsJWK, SESSION_READY);
570 ASSERT_NO_FATAL_FAILURE(
571 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
573 ReleaseSession(session_id);
576 TEST_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_);
581 UpdateSessionAndExpect(session_id, kKeyAsJWK, SESSION_READY);
582 ASSERT_NO_FATAL_FAILURE(
583 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
585 ReleaseSession(session_id);
586 ASSERT_NO_FATAL_FAILURE(
587 DecryptAndExpect(encrypted_buffer, original_data_, NO_KEY));
590 TEST_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_);
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));
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);
604 // Should be able to decode with latest key.
605 ASSERT_NO_FATAL_FAILURE(
606 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
609 TEST_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));
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);
621 // Should not be able to decode with new key.
622 ASSERT_NO_FATAL_FAILURE(
623 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH));
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));
631 TEST_F(AesDecryptorTest, JWKKey) {
632 uint32 session_id = CreateSession(key_id_);
634 // Try a simple JWK key (i.e. not in a set)
635 const std::string kJwkSimple =
637 " \"kty\": \"oct\","
638 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
639 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
640 "}";
641 UpdateSessionAndExpect(session_id, kJwkSimple, SESSION_ERROR);
643 // Try a key list with multiple entries.
644 const std::string kJwksMultipleEntries =
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);
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);
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);
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);
678 // Try passing some valid JSON that is not a dictionary at the top level.
679 UpdateSessionAndExpect(session_id, "40", SESSION_ERROR);
681 // Try an empty dictionary.
682 UpdateSessionAndExpect(session_id, "{ }", SESSION_ERROR);
684 // Try an empty 'keys' dictionary.
685 UpdateSessionAndExpect(session_id, "{ \"keys\": [] }", SESSION_ERROR);
687 // Try with 'keys' not a dictionary.
688 UpdateSessionAndExpect(session_id, "{ \"keys\":\"1\" }", SESSION_ERROR);
690 // Try with 'keys' a list of integers.
691 UpdateSessionAndExpect(
692 session_id, "{ \"keys\": [ 1, 2, 3 ] }", SESSION_ERROR);
694 // Try padding(=) at end of 'k' base64 string.
695 const std::string kJwksWithPaddedKey =
697 " \"keys\": ["
698 " {"
699 " \"kty\": \"oct\","
700 " \"kid\": \"AAECAw\","
701 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw==\""
702 " }"
703 " ]"
704 "}";
705 UpdateSessionAndExpect(session_id, kJwksWithPaddedKey, SESSION_ERROR);
707 // Try padding(=) at end of 'kid' base64 string.
708 const std::string kJwksWithPaddedKeyId =
710 " \"keys\": ["
711 " {"
712 " \"kty\": \"oct\","
713 " \"kid\": \"AAECAw==\","
714 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
715 " }"
716 " ]"
717 "}";
718 UpdateSessionAndExpect(session_id, kJwksWithPaddedKeyId, SESSION_ERROR);
720 // Try a key with invalid base64 encoding.
721 const std::string kJwksWithInvalidBase64 =
723 " \"keys\": ["
724 " {"
725 " \"kty\": \"oct\","
726 " \"kid\": \"!@#$%^&*()\","
727 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
728 " }"
729 " ]"
730 "}";
731 UpdateSessionAndExpect(session_id, kJwksWithInvalidBase64, SESSION_ERROR);
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 =
738 " \"keys\": ["
739 " {"
740 " \"kty\": \"oct\","
741 " \"kid\": \"Kiss\","
742 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
743 " }"
744 " ]"
745 "}";
746 UpdateSessionAndExpect(session_id, kJwksWithNoPadding, SESSION_READY);
748 // Empty key id.
749 const std::string kJwksWithEmptyKeyId =
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);
763 } // namespace media