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