diff --git a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h index 09560566..8687da1f 100644 --- a/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h +++ b/libwvdrmengine/oemcrypto/ref/src/oemcrypto_session.h @@ -128,7 +128,7 @@ class SessionContext { const OEMCrypto_KeyObject* key_array, OEMCrypto_Substring pst, OEMCrypto_Substring srm_restriction_data, OEMCrypto_LicenseType license_type); - OEMCryptoResult LoadEntitledContentKeys( + virtual OEMCryptoResult LoadEntitledContentKeys( const uint8_t* message, size_t message_length, size_t num_keys, const OEMCrypto_EntitledContentKeyObject* key_array); virtual OEMCryptoResult InstallKey( diff --git a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp index 2b768de0..1ae83b32 100644 --- a/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp +++ b/libwvdrmengine/oemcrypto/test/oemcrypto_test.cpp @@ -1252,10 +1252,7 @@ TEST_F(OEMCryptoSessionTests, LoadKeyWithBadRange7) { // The IV should not be identical to the data right before the encrypted mac // keys. -// This test is for OEMCrypto v15.2. It is being disabled on the Android branch -// the 15.2 updates to 15.2 were not available in time for the Q release. SOC -// vendors who are able to pass this tests, should. -TEST_F(OEMCryptoSessionTests, DISABLED_LoadKeyWithSuspiciousIV) { +TEST_F(OEMCryptoSessionTests, LoadKeyWithSuspiciousIV) { Session s; ASSERT_NO_FATAL_FAILURE(s.open()); ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); @@ -1606,9 +1603,7 @@ TEST_F(OEMCryptoSessionTests, SelectKeyNotThereAPI15) { s.session_id(), in_buffer.data(), in_buffer.size(), is_encrypted, encryptionIv.data(), 0, &destBuffer, &pattern, OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - EXPECT_TRUE( - (OEMCrypto_ERROR_NO_CONTENT_KEY == sts) // Preferred return code. - || (OEMCrypto_KEY_NOT_LOADED == sts)); // Obsolete return code. + EXPECT_EQ(OEMCrypto_ERROR_NO_CONTENT_KEY, sts); } } @@ -2075,6 +2070,18 @@ class OEMCryptoSessionTestsDecryptTests pattern_ = ::testing::get<0>(GetParam()); cipher_mode_ = ::testing::get<1>(GetParam()); decrypt_inplace_ = ::testing::get<2>(GetParam()); + verify_crc_ = global_features.supports_crc; + // Pick a random key. + EXPECT_EQ(1, GetRandBytes(key_, AES_BLOCK_SIZE)); + // Pick a random starting iv. Some tests override this before using it. + starting_iv_.resize(AES_BLOCK_SIZE); + EXPECT_EQ(1, GetRandBytes(starting_iv_.data(), starting_iv_.size())); + total_size_ = -1; + } + + virtual void TearDown() { + ASSERT_NO_FATAL_FAILURE(session_.close()); + OEMCryptoSessionTests::TearDown(); } void FindTotalSize() { @@ -2085,24 +2092,47 @@ class OEMCryptoSessionTestsDecryptTests } } - void EncryptData(const vector& key, - const vector& starting_iv, - const vector& in_buffer, - vector* out_buffer) { + // Set up the input buffer and output buffer. + // This should be called after FindTotalSize(). + void MakeBuffers() { + ASSERT_GT(total_size_, 0u); + encrypted_buffer_.resize(total_size_); + truth_buffer_.resize(total_size_); + for (size_t i = 0; i < total_size_; i++) truth_buffer_[i] = i % 256; + output_descriptor_.type = OEMCrypto_BufferType_Clear; + if (decrypt_inplace_) { + output_descriptor_.buffer.clear.address = encrypted_buffer_.data(); + } else { + // Add some padding to verify there is no overrun. + clear_buffer_.resize(total_size_ + 16, 0xaa); + output_descriptor_.buffer.clear.address = clear_buffer_.data(); + } + output_descriptor_.buffer.clear.max_length = total_size_; + } + + void UpdateOutputOffset(size_t offset) { + if (decrypt_inplace_) { + output_descriptor_.buffer.clear.address = + encrypted_buffer_.data() + offset; + } else { + output_descriptor_.buffer.clear.address = clear_buffer_.data() + offset; + } + output_descriptor_.buffer.clear.max_length = total_size_ - offset; + } + + void EncryptData() { AES_KEY aes_key; - AES_set_encrypt_key(key.data(), AES_BLOCK_SIZE * 8, &aes_key); - out_buffer->resize(in_buffer.size()); + AES_set_encrypt_key(key_, AES_BLOCK_SIZE * 8, &aes_key); uint8_t iv[AES_BLOCK_SIZE]; // Current iv. - - memcpy(iv, starting_iv.data(), AES_BLOCK_SIZE); + memcpy(iv, starting_iv_.data(), AES_BLOCK_SIZE); size_t buffer_index = 0; // byte index into in and out. size_t block_offset = 0; // byte index into current block. for (size_t i = 0; i < subsample_size_.size(); i++) { // Copy clear content. if (subsample_size_[i].clear_size > 0) { - memcpy(&(*out_buffer)[buffer_index], &in_buffer[buffer_index], + memcpy(&encrypted_buffer_[buffer_index], &truth_buffer_[buffer_index], subsample_size_[i].clear_size); buffer_index += subsample_size_[i].clear_size; } @@ -2129,15 +2159,17 @@ class OEMCryptoSessionTestsDecryptTests // can put whatever we want in the output buffer. if (skip_block || ((cipher_mode_ == OEMCrypto_CipherMode_CBC) && (size < AES_BLOCK_SIZE))) { - memcpy(&(*out_buffer)[buffer_index], &in_buffer[buffer_index], size); + memcpy(&encrypted_buffer_[buffer_index], &truth_buffer_[buffer_index], + size); block_offset = 0; // Next block should be complete. } else { if (cipher_mode_ == OEMCrypto_CipherMode_CTR) { uint8_t aes_output[AES_BLOCK_SIZE]; AES_encrypt(iv, aes_output, &aes_key); for (size_t n = 0; n < size; n++) { - (*out_buffer)[buffer_index + n] = - aes_output[n + block_offset] ^ in_buffer[buffer_index + n]; + encrypted_buffer_[buffer_index + n] = + aes_output[n + block_offset] ^ + truth_buffer_[buffer_index + n]; } if (size + block_offset < AES_BLOCK_SIZE) { // Partial block. Don't increment iv. Compute next block offset. @@ -2152,10 +2184,10 @@ class OEMCryptoSessionTestsDecryptTests } else { uint8_t aes_input[AES_BLOCK_SIZE]; for (size_t n = 0; n < size; n++) { - aes_input[n] = in_buffer[buffer_index + n] ^ iv[n]; + aes_input[n] = truth_buffer_[buffer_index + n] ^ iv[n]; } - AES_encrypt(aes_input, &(*out_buffer)[buffer_index], &aes_key); - memcpy(iv, &(*out_buffer)[buffer_index], AES_BLOCK_SIZE); + AES_encrypt(aes_input, &encrypted_buffer_[buffer_index], &aes_key); + memcpy(iv, &encrypted_buffer_[buffer_index], AES_BLOCK_SIZE); // CBC mode should always start on block boundary. block_offset = 0; } @@ -2165,73 +2197,58 @@ class OEMCryptoSessionTestsDecryptTests } } - void TestDecryptCENC(const vector& key, - const vector& /* encryptionIv */, - const vector& encryptedData, - const vector& unencryptedData) { + void LoadLicense() { + // First we open a session and load a license. + ASSERT_NO_FATAL_FAILURE(session_.open()); + ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&session_)); + uint32_t control = 0; + if (verify_crc_) control |= kControlAllowHashVerification; + ASSERT_NO_FATAL_FAILURE(session_.FillSimpleMessage( + kDuration, control, 0)); + memcpy(session_.license().keys[0].key_data, key_, sizeof(key_)); + session_.license().keys[0].cipher_mode = cipher_mode_; + ASSERT_NO_FATAL_FAILURE(session_.EncryptAndSign()); + ASSERT_NO_FATAL_FAILURE(session_.LoadTestKeys()); + ASSERT_EQ(OEMCrypto_SUCCESS, + OEMCrypto_SelectKey( + session_.session_id(), session_.license().keys[0].key_id, + session_.license().keys[0].key_id_length, cipher_mode_)); + } + + void TestDecryptCENC() { OEMCryptoResult sts; - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s)); - ASSERT_NO_FATAL_FAILURE( - s.FillSimpleMessage(kDuration, kControlAllowHashVerification, 0)); - memcpy(s.license().keys[0].key_data, key.data(), key.size()); - s.license().keys[0].cipher_mode = cipher_mode_; - ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign()); - ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys()); - if (global_features.supports_crc) { - uint32_t hash = - wvcrc32(unencryptedData.data(), unencryptedData.size()); + // If supported, initialize the decrypt hash. + if (verify_crc_) { + uint32_t hash = wvcrc32(truth_buffer_.data(), truth_buffer_.size()); ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_SetDecryptHash( - s.session_id(), 1, reinterpret_cast(&hash), - sizeof(hash))); - } - sts = OEMCrypto_SelectKey(s.session_id(), s.license().keys[0].key_id, - s.license().keys[0].key_id_length, - cipher_mode_); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - // We decrypt each subsample. - vector output_buffer(total_size_ + 16, 0xaa); - const uint8_t *input_buffer = NULL; - if (decrypt_inplace_) { // Use same buffer for input and output. - // Copy the useful data from encryptedData to output_buffer, which - // will be the same as input_buffer. Leave the 0xaa padding at the end. - for(size_t i=0; i < total_size_; i++) output_buffer[i] = encryptedData[i]; - // Now let input_buffer point to the same data. - input_buffer = output_buffer.data(); - } else { - input_buffer = encryptedData.data(); + session_.session_id(), 1, + reinterpret_cast(&hash), sizeof(hash))); } size_t buffer_offset = 0; for (size_t i = 0; i < subsample_size_.size(); i++) { OEMCrypto_CENCEncryptPatternDesc pattern = pattern_; pattern.offset = 0; // Final CENC spec says pattern offset always 0. bool is_encrypted = false; - OEMCrypto_DestBufferDesc destBuffer; size_t block_offset = 0; uint8_t subsample_flags = 0; if (subsample_size_[i].clear_size > 0) { - destBuffer.type = OEMCrypto_BufferType_Clear; - destBuffer.buffer.clear.address = &output_buffer[buffer_offset]; - destBuffer.buffer.clear.max_length = total_size_ - buffer_offset; + ASSERT_NO_FATAL_FAILURE(UpdateOutputOffset(buffer_offset)); if (i == 0) subsample_flags |= OEMCrypto_FirstSubsample; if ((i == subsample_size_.size() - 1) && (subsample_size_[i].encrypted_size == 0)) { subsample_flags |= OEMCrypto_LastSubsample; } - sts = - OEMCrypto_DecryptCENC(s.session_id(), input_buffer + buffer_offset, - subsample_size_[i].clear_size, is_encrypted, - sample_init_data_[i].iv, block_offset, - &destBuffer, &pattern, subsample_flags); + sts = OEMCrypto_DecryptCENC( + session_.session_id(), &encrypted_buffer_[buffer_offset], + subsample_size_[i].clear_size, is_encrypted, + sample_init_data_[i].iv, block_offset, &output_descriptor_, + &pattern, subsample_flags); ASSERT_EQ(OEMCrypto_SUCCESS, sts); buffer_offset += subsample_size_[i].clear_size; } if (subsample_size_[i].encrypted_size > 0) { - destBuffer.type = OEMCrypto_BufferType_Clear; - destBuffer.buffer.clear.address = &output_buffer[buffer_offset]; - destBuffer.buffer.clear.max_length = total_size_ - buffer_offset; + ASSERT_NO_FATAL_FAILURE(UpdateOutputOffset(buffer_offset)); is_encrypted = true; block_offset = sample_init_data_[i].block_offset; subsample_flags = 0; @@ -2242,10 +2259,10 @@ class OEMCryptoSessionTestsDecryptTests subsample_flags |= OEMCrypto_LastSubsample; } sts = OEMCrypto_DecryptCENC( - s.session_id(), input_buffer + buffer_offset, + session_.session_id(), &encrypted_buffer_[buffer_offset], subsample_size_[i].encrypted_size, is_encrypted, - sample_init_data_[i].iv, block_offset, &destBuffer, &pattern, - subsample_flags); + sample_init_data_[i].iv, block_offset, &output_descriptor_, + &pattern, subsample_flags); // CBC mode should not accept a block offset. if ((block_offset > 0) && (cipher_mode_ == OEMCrypto_CipherMode_CBC)) { ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT, sts) @@ -2256,14 +2273,23 @@ class OEMCryptoSessionTestsDecryptTests buffer_offset += subsample_size_[i].encrypted_size; } } - EXPECT_EQ(0xaa, output_buffer[total_size_]) << "Buffer overrun."; - output_buffer.resize(total_size_); - EXPECT_EQ(unencryptedData, output_buffer); + if (output_descriptor_.type == OEMCrypto_BufferType_Clear) { + if (decrypt_inplace_) { + // We expect encrypted buffer to have been changed by OEMCrypto. + EXPECT_EQ(encrypted_buffer_, truth_buffer_); + } else { + // If we are not decrypting in place, then look at the one byte just + // after the data that was written. It should not have changed from the + // original 0xaa that we set in MakeBuffersession_. + EXPECT_EQ(0xaa, clear_buffer_[total_size_]) << "Buffer overrun."; + clear_buffer_.resize(total_size_); // Remove padding. + EXPECT_EQ(clear_buffer_, truth_buffer_); + } + } if (global_features.supports_crc) { uint32_t frame; ASSERT_EQ(OEMCrypto_SUCCESS, - OEMCrypto_GetHashErrorCode(s.session_id(), &frame)); - + OEMCrypto_GetHashErrorCode(session_.session_id(), &frame)); } } @@ -2272,7 +2298,17 @@ class OEMCryptoSessionTestsDecryptTests bool decrypt_inplace_; // If true, input and output buffers are the same. vector subsample_size_; size_t total_size_; + bool verify_crc_; vector sample_init_data_; +// Encrypted data -- this is input to OEMCrypto, and output from EncryptData. + std::vector encrypted_buffer_; + std::vector clear_buffer_; // OEMCrypto store clear output here. + void* secure_handle_; // OEMCrypto stores secure output here. + std::vector truth_buffer_; // Truth data for clear text. + OEMCrypto_DestBufferDesc output_descriptor_; + uint8_t key_[AES_BLOCK_SIZE]; // Encryption Key. + std::vector starting_iv_; // Starting IV. + Session session_; }; // Tests that generate partial ending blocks. These tests should not be used @@ -2286,15 +2322,10 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, SingleLargeSubsample) { // full patterns if we have more than 320 -- round up to 400. subsample_size_.push_back(SampleSize(0, 400)); FindTotalSize(); - vector unencryptedData(total_size_); - vector encryptedData(total_size_); - vector encryptionIv(AES_BLOCK_SIZE); - vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); - for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; - EncryptData(key, encryptionIv, unencryptedData, &encryptedData); - TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); } // When the pattern length is 10 blocks, there is a discrepancy between the @@ -2304,30 +2335,20 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, SingleLargeSubsample) { TEST_P(OEMCryptoSessionTestsDecryptTests, PatternPlusOneBlock) { subsample_size_.push_back(SampleSize(0, 160 + 16)); FindTotalSize(); - vector unencryptedData(total_size_); - vector encryptedData(total_size_); - vector encryptionIv(AES_BLOCK_SIZE); - vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); - for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; - EncryptData(key, encryptionIv, unencryptedData, &encryptedData); - TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); } // Test that a single block can be decrypted. TEST_P(OEMCryptoSessionTestsDecryptTests, OneBlock) { subsample_size_.push_back(SampleSize(0, 16)); FindTotalSize(); - vector unencryptedData(total_size_); - vector encryptedData(total_size_); - vector encryptionIv(AES_BLOCK_SIZE); - vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); - for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; - EncryptData(key, encryptionIv, unencryptedData, &encryptedData); - TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); } // This tests the ability to decrypt multiple subsamples with no offset. @@ -2338,41 +2359,36 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, NoOffset) { subsample_size_.push_back(SampleSize(50, 256)); subsample_size_.push_back(SampleSize(25, 160)); FindTotalSize(); - vector unencryptedData(total_size_); - vector encryptedData(total_size_); - vector encryptionIv(AES_BLOCK_SIZE); - vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); - for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; - EncryptData(key, encryptionIv, unencryptedData, &encryptedData); - TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); } // This tests an offset into the block for the second encrypted subsample. // This should only work for CTR mode, for CBC mode an error is expected in // the decrypt step. -// If this test fails for CTR mode, then it is probably handleing the +// If this test fails for CTR mode, then it is probably handling the // block_offset incorrectly. TEST_P(OEMCryptoSessionTestsPartialBlockTests, EvenOffset) { subsample_size_.push_back(SampleSize(25, 8)); subsample_size_.push_back(SampleSize(25, 32)); subsample_size_.push_back(SampleSize(25, 50)); FindTotalSize(); - vector unencryptedData(total_size_); - vector encryptedData(total_size_); - vector encryptionIv(AES_BLOCK_SIZE); - vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); // CTR Mode is self-inverse -- i.e. We can pick the encrypted data and // compute the unencrypted data. By picking the encrypted data to be all 0, // it is easier to re-encrypt the data and debug problems. Similarly, we // pick an iv = 0. - EncryptData(key, encryptionIv, encryptedData, &unencryptedData); - // Run EncryptData again to correctly compute intermediate IV vectors. - // For CBC mode, this also computes the real encrypted data. - EncryptData(key, encryptionIv, unencryptedData, &encryptedData); - TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); + starting_iv_.assign(AES_BLOCK_SIZE, 0); + truth_buffer_.assign(total_size_, 0); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + truth_buffer_ = encrypted_buffer_; // truth_buffer_ = encrypted zero buffer. + // Run EncryptData to re-encrypt this buffer. For CTR mode, we should get + // back to zeros. + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); } // If the EvenOffset test passes, but this one doesn't, then DecryptCTR might @@ -2387,15 +2403,10 @@ TEST_P(OEMCryptoSessionTestsPartialBlockTests, OddOffset) { subsample_size_.push_back(SampleSize(10, 75)); subsample_size_.push_back(SampleSize(10, 25)); FindTotalSize(); - vector unencryptedData(total_size_); - vector encryptedData(total_size_); - vector encryptionIv(AES_BLOCK_SIZE); - vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); - for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; - EncryptData(key, encryptionIv, unencryptedData, &encryptedData); - TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); } // This tests that the algorithm used to increment the counter for @@ -2409,17 +2420,13 @@ TEST_P(OEMCryptoSessionTestsPartialBlockTests, OddOffset) { // If you start with an IV of 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE, after you // increment twice, you should get 0xFFFFFFFFFFFFFFFF0000000000000000. TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptWithNearWrap) { + starting_iv_ = wvcdm::a2b_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"); subsample_size_.push_back(SampleSize(0, 256)); FindTotalSize(); - vector unencryptedData(total_size_); - vector encryptedData(total_size_); - vector encryptionIv(AES_BLOCK_SIZE); - vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); - encryptionIv = wvcdm::a2b_hex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"); - for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; - EncryptData(key, encryptionIv, unencryptedData, &encryptedData); - TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); } // This tests the case where an encrypted sample is not an even number of @@ -2431,15 +2438,10 @@ TEST_P(OEMCryptoSessionTestsPartialBlockTests, PartialBlock) { // other tests, e.g. (7, 3). 3*16 < 50 and 7*16 > 50. subsample_size_.push_back(SampleSize(0, 50)); FindTotalSize(); - vector unencryptedData(total_size_); - vector encryptedData(total_size_); - vector encryptionIv(AES_BLOCK_SIZE); - vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); - for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; - EncryptData(key, encryptionIv, unencryptedData, &encryptedData); - TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); } // Based on the resource rating, oemcrypto should handle at least @@ -2456,15 +2458,10 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSample) { subsample_size_.push_back(SampleSize(0, max_subsample_size)); } FindTotalSize(); - vector unencryptedData(total_size_); - vector encryptedData(total_size_); - vector encryptionIv(AES_BLOCK_SIZE); - vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); - for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; - EncryptData(key, encryptionIv, unencryptedData, &encryptedData); - TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); } // This tests that we can decrypt the required maximum number of subsamples. @@ -2473,30 +2470,20 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptMaxSubsample) { subsample_size_.push_back(SampleSize(max_subsample_size, 0)); subsample_size_.push_back(SampleSize(0, max_subsample_size)); FindTotalSize(); - vector unencryptedData(total_size_); - vector encryptedData(total_size_); - vector encryptionIv(AES_BLOCK_SIZE); - vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); - for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; - EncryptData(key, encryptionIv, unencryptedData, &encryptedData); - TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); } // There are probably no frames this small, but we should handle them anyway. TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptSmallBuffer) { subsample_size_.push_back(SampleSize(5, 5)); FindTotalSize(); - vector unencryptedData(total_size_); - vector encryptedData(total_size_); - vector encryptionIv(AES_BLOCK_SIZE); - vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); - for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; - EncryptData(key, encryptionIv, unencryptedData, &encryptedData); - TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); } // Test the case where there is only a clear subsample and no encrypted @@ -2504,47 +2491,25 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptSmallBuffer) { TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptUnencrypted) { subsample_size_.push_back(SampleSize(256, 0)); FindTotalSize(); - vector unencryptedData(total_size_); - vector encryptedData(total_size_); - vector encryptionIv(AES_BLOCK_SIZE); - vector key(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); - EXPECT_EQ(1, GetRandBytes(key.data(), AES_BLOCK_SIZE)); - for (size_t i = 0; i < total_size_; i++) unencryptedData[i] = i % 256; - EncryptData(key, encryptionIv, unencryptedData, &encryptedData); - TestDecryptCENC(key, encryptionIv, encryptedData, unencryptedData); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); } -TEST_F(OEMCryptoSessionTests, DecryptUnencryptedNoKey) { - OEMCryptoResult sts; - Session s; - ASSERT_NO_FATAL_FAILURE(s.open()); - // Clear data should be copied even if there is no key selected. - // Set up our expected input and output - // This is dummy decrypted data. - vector in_buffer(256); - for (size_t i = 0; i < in_buffer.size(); i++) in_buffer[i] = i % 256; - vector encryptionIv(AES_BLOCK_SIZE); - EXPECT_EQ(1, GetRandBytes(encryptionIv.data(), AES_BLOCK_SIZE)); - // Describe the output - vector out_buffer(in_buffer.size()); - OEMCrypto_DestBufferDesc destBuffer; - destBuffer.type = OEMCrypto_BufferType_Clear; - destBuffer.buffer.clear.address = out_buffer.data(); - destBuffer.buffer.clear.max_length = out_buffer.size(); - OEMCrypto_CENCEncryptPatternDesc pattern; - pattern.encrypt = 0; - pattern.skip = 0; - pattern.offset = 0; - - // Decrypt the data - sts = - OEMCrypto_DecryptCENC(s.session_id(), in_buffer.data(), in_buffer.size(), - false, encryptionIv.data(), 0, &destBuffer, - &pattern, - OEMCrypto_FirstSubsample | OEMCrypto_LastSubsample); - ASSERT_EQ(OEMCrypto_SUCCESS, sts); - ASSERT_EQ(in_buffer, out_buffer); +TEST_P(OEMCryptoSessionTestsDecryptTests, DecryptUnencryptedNoKey) { + ASSERT_NO_FATAL_FAILURE(session_.open()); + // Single clear subsample + subsample_size_.push_back(SampleSize(400, 0)); + // Do not try to compute the CRC because we have not loaded a license. + verify_crc_ = false; + FindTotalSize(); + ASSERT_NO_FATAL_FAILURE(MakeBuffers()); + // Clear data should be copied even if there is no key selected, and no + // license loaded. + // ASSERT_NO_FATAL_FAILURE(LoadLicense()); + ASSERT_NO_FATAL_FAILURE(EncryptData()); + ASSERT_NO_FATAL_FAILURE(TestDecryptCENC()); } // Used to construct a specific pattern.