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