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