Merge cdm changes to android repo

Bug: 251924225
Test: GtsMediaTestCases
Change-Id: I1b4e64c0abf701fe1f5017f14dc72b72c3ea6770
This commit is contained in:
Kyle Zhang
2022-10-07 23:55:37 +00:00
parent 3cfe7c7299
commit af0168dbed
54 changed files with 295536 additions and 294359 deletions

View File

@@ -0,0 +1,34 @@
// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine
// License Agreement.
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
if (size < sizeof(ODK_ParsedLicense) + sizeof(MessageData)) {
return 0;
}
OEMCryptoLicenseAPIFuzz license_api_fuzz;
license_api_fuzz.license_messages().set_license_type(
OEMCrypto_EntitlementLicense);
license_api_fuzz.license_messages().SignAndVerifyRequest();
// Interpreting input fuzz data as unencrypted (core_response + license
// message data) from license server.
license_api_fuzz.license_messages().InjectFuzzedResponseData(data, size);
license_api_fuzz.license_messages().EncryptAndSignResponse();
license_api_fuzz.license_messages().LoadResponse();
uint32_t key_session_id;
OEMCrypto_CreateEntitledKeySession(license_api_fuzz.session_id(),
&key_session_id);
OEMCrypto_RemoveEntitledKeySession(key_session_id);
return 0;
}
} // namespace wvoec

View File

@@ -16,8 +16,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
Session* session = entry.license_messages().session();
session->open();
entry.InstallTestRSAKey(session);
session->GenerateNonce();
session->CreateNewUsageEntry();
session->GenerateNonce();
vector<uint8_t> encrypted_usage_header;
session->UpdateUsageEntry(&encrypted_usage_header);
// LoadLicense sets the pst for usage entry.

View File

@@ -52,6 +52,8 @@ class OEMCryptoLicenseAPIFuzz : public InitializeFuzz {
Session* session() { return &session_; }
uint32_t session_id() { return session_.session_id(); }
void LoadLicense();
private:

View File

@@ -49,10 +49,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
Session* session = license_api_fuzz.session();
// Load license and call generic_decrypt API.
license_api_fuzz.LoadLicense();
OEMCryptoResult sts = OEMCrypto_SelectKey(
session->session_id(), session->license().keys[0].key_id,
session->license().keys[0].key_id_length, fuzzed_structure.cipher_mode);
CheckStatusAndExitFuzzerOnFailure(sts, OEMCrypto_SUCCESS);
OEMCrypto_SelectKey(session->session_id(), session->license().keys[0].key_id,
session->license().keys[0].key_id_length,
fuzzed_structure.cipher_mode);
OEMCrypto_Generic_Decrypt(session->session_id(), encrypted_buffer.data(),
encrypted_buffer.size(), iv.data(),
fuzzed_structure.algorithm, clear_buffer.data());

View File

@@ -49,10 +49,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
Session* session = license_api_fuzz.session();
// Load license and call generic_encrypt API.
license_api_fuzz.LoadLicense();
OEMCryptoResult sts = OEMCrypto_SelectKey(
session->session_id(), session->license().keys[0].key_id,
session->license().keys[0].key_id_length, fuzzed_structure.cipher_mode);
CheckStatusAndExitFuzzerOnFailure(sts, OEMCrypto_SUCCESS);
OEMCrypto_SelectKey(session->session_id(), session->license().keys[0].key_id,
session->license().keys[0].key_id_length,
fuzzed_structure.cipher_mode);
OEMCrypto_Generic_Encrypt(
session->session_id(), clear_buffer.data(), clear_buffer.size(),
iv.data(), fuzzed_structure.algorithm, encrypted_buffer.data());

View File

@@ -38,10 +38,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
Session* session = license_api_fuzz.session();
// Load license and call generic_sign API.
license_api_fuzz.LoadLicense();
OEMCryptoResult sts = OEMCrypto_SelectKey(
session->session_id(), session->license().keys[0].key_id,
session->license().keys[0].key_id_length, fuzzed_structure.cipher_mode);
CheckStatusAndExitFuzzerOnFailure(sts, OEMCrypto_SUCCESS);
OEMCrypto_SelectKey(session->session_id(), session->license().keys[0].key_id,
session->license().keys[0].key_id_length,
fuzzed_structure.cipher_mode);
size_t signature_length = 0;
OEMCrypto_Generic_Sign(session->session_id(), clear_buffer.data(),
clear_buffer.size(), fuzzed_structure.algorithm,

View File

@@ -0,0 +1,33 @@
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
size_t pst_buffer_length = 0;
if (size <= sizeof(pst_buffer_length)) {
return 0;
}
LicenseWithUsageEntryFuzz entry;
entry.CreateUsageTableHeader();
// Open a session, create a usage entry.
Session* session = entry.license_messages().session();
session->open();
entry.InstallTestRSAKey(session);
session->GenerateNonce();
session->CreateNewUsageEntry();
vector<uint8_t> encrypted_usage_header;
session->UpdateUsageEntry(&encrypted_usage_header);
std::vector<uint8_t> wrapped_private_key(size);
memcpy(wrapped_private_key.data(), data, size);
OEMCrypto_PrivateKeyType key_type = OEMCrypto_RSA_Private_Key;
OEMCrypto_InstallOemPrivateKey(session->session_id(), key_type, wrapped_private_key.data(), size);
session->close();
return 0;
}
}

View File

@@ -0,0 +1,33 @@
// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
LicenseWithUsageEntryFuzz entry;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
uint32_t usage_entry_number = 0;
if (size < sizeof(usage_entry_number)) {
return 0;
}
entry.CreateUsageTableHeader();
Session* s = entry.license_messages().session();
s->open();
entry.InstallTestRSAKey(s);
memcpy(&usage_entry_number, data, sizeof(uint32_t));
s->CreateNewUsageEntry();
vector<uint8_t> encrypted_usage_header;
s->UpdateUsageEntry(&encrypted_usage_header);
OEMCrypto_MoveEntry(s->session_id(), usage_entry_number);
s ->close();
return 0;
}
} // namespace wvoec

View File

@@ -22,8 +22,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
Session* session = entry.license_messages().session();
session->open();
entry.InstallTestRSAKey(session);
session->GenerateNonce();
session->CreateNewUsageEntry();
session->GenerateNonce();
vector<uint8_t> encrypted_usage_header;
session->UpdateUsageEntry(&encrypted_usage_header);
// Sets pst for usage entry.

View File

@@ -0,0 +1,33 @@
// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine Master
// License Agreement.
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
LicenseWithUsageEntryFuzz entry;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
uint32_t usage_entry_number = 0;
if (size < sizeof(usage_entry_number)) {
return 0;
}
entry.CreateUsageTableHeader();
Session* s = entry.license_messages().session();
s->open();
entry.InstallTestRSAKey(s);
s->CreateNewUsageEntry();
s->close();
s->open();
memcpy(&usage_entry_number, data, sizeof(uint32_t));
OEMCrypto_ReuseUsageEntry(s->session_id(), usage_entry_number);
s->close();
return 0;
}
} // namespace wvoec

View File

@@ -0,0 +1,28 @@
// Copyright 2022 Google LLC. All Rights Reserved. This file and proprietary
// source code may only be used and distributed under the Widevine
// License Agreement.
#include "OEMCryptoCENC.h"
#include "oemcrypto_fuzz_helper.h"
namespace wvoec {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Redirect printf and log statements from oemcrypto functions to a file to
// reduce noise
RedirectStdoutToFile();
if (size < sizeof(uint32_t)) {
return 0;
}
LicenseWithUsageEntryFuzz entry;
uint32_t new_entry_count = 0;
memcpy(&new_entry_count, data, sizeof(uint32_t));
std::vector<uint8_t> header_buffer(size - sizeof(uint32_t));
size_t header_buffer_length = header_buffer.size();
OEMCrypto_ShrinkUsageTableHeader(new_entry_count, header_buffer.data(),
&header_buffer_length);
return 0;
}
} // namespace wvoec

View File

@@ -22,6 +22,7 @@
#include <algorithm>
#include <iostream>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
@@ -249,6 +250,24 @@ RoundTrip<CoreRequest, PrepAndSignRequest, CoreResponse, ResponseData>::
return result;
}
template <class CoreRequest, PrepAndSignRequest_t PrepAndSignRequest,
class CoreResponse, class ResponseData>
void RoundTrip<CoreRequest, PrepAndSignRequest, CoreResponse,
ResponseData>::SetEncryptAndSignResponseLengths() {
encrypted_response_length_ = encrypted_response_.size();
response_signature_length_ = response_signature_.size();
}
template <class CoreRequest, PrepAndSignRequest_t PrepAndSignRequest,
class CoreResponse, class ResponseData>
void RoundTrip<CoreRequest, PrepAndSignRequest, CoreResponse,
ResponseData>::VerifyEncryptAndSignResponseLengths() const {
EXPECT_NE(encrypted_response_length_, 0u);
EXPECT_EQ(encrypted_response_length_, encrypted_response_.size());
EXPECT_NE(response_signature_length_, 0u);
EXPECT_EQ(response_signature_length_, response_signature_.size());
}
template <PrepAndSignRequest_t PrepAndSignRequest>
void GetDefaultRequestSignatureAndCoreMessageLengths(
uint32_t& session_id, const size_t& small_size,
@@ -436,6 +455,7 @@ void ProvisioningRoundTrip::SignResponse() {
session()->key_deriver().ServerSignBuffer(encrypted_response_.data(),
encrypted_response_.size(),
&response_signature_);
SetEncryptAndSignResponseLengths();
}
void ProvisioningRoundTrip::InjectFuzzedResponseData(const uint8_t* data,
@@ -519,12 +539,14 @@ OEMCryptoResult ProvisioningRoundTrip::LoadResponseNoRetry(
Session* session, size_t* wrapped_key_length) {
EXPECT_NE(session, nullptr);
if (global_features.api_version >= kCoreMessagesAPI) {
VerifyEncryptAndSignResponseLengths();
return OEMCrypto_LoadProvisioning(
session->session_id(), encrypted_response_.data(),
encrypted_response_.size(), serialized_core_message_.size(),
response_signature_.data(), response_signature_.size(),
wrapped_rsa_key_.data(), wrapped_key_length);
} else if (global_features.provisioning_method == OEMCrypto_Keybox) {
VerifyEncryptAndSignResponseLengths();
return OEMCrypto_RewrapDeviceRSAKey_V15(
session->session_id(), encrypted_response_.data(),
encrypted_response_.size(), response_signature_.data(),
@@ -859,6 +881,7 @@ void LicenseRoundTrip::SignEncryptedResponse() {
session()->key_deriver().ServerSignBuffer(encrypted_response_.data(),
encrypted_response_.size(),
&response_signature_);
SetEncryptAndSignResponseLengths();
}
void LicenseRoundTrip::EncryptAndSignResponse() {
@@ -909,6 +932,7 @@ OEMCryptoResult LicenseRoundTrip::LoadResponse(Session* session,
// garbage. Since the memory after the message buffer is an exact copy of the
// message, we can increment the offset by the message size and get valid
// data.
VerifyEncryptAndSignResponseLengths();
std::vector<uint8_t> double_message = encrypted_response_;
double_message.insert(
double_message.end(),
@@ -1075,14 +1099,20 @@ OEMCrypto_Substring EntitledMessage::FindSubstring(const void* ptr,
return substring;
}
void EntitledMessage::LoadKeys(OEMCryptoResult expected_sts) {
void EntitledMessage::LoadKeys(bool expected_success) {
EncryptContentKey();
ASSERT_EQ(expected_sts,
OEMCrypto_LoadEntitledContentKeys(
entitled_key_session_,
reinterpret_cast<const uint8_t*>(entitled_key_data_),
sizeof(entitled_key_data_), num_keys_, entitled_key_array_));
if (expected_sts != OEMCrypto_SUCCESS) {
if (expected_success) {
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_LoadEntitledContentKeys(
entitled_key_session_,
reinterpret_cast<const uint8_t*>(entitled_key_data_),
sizeof(entitled_key_data_), num_keys_, entitled_key_array_));
} else {
ASSERT_NE(OEMCrypto_SUCCESS,
OEMCrypto_LoadEntitledContentKeys(
entitled_key_session_,
reinterpret_cast<const uint8_t*>(entitled_key_data_),
sizeof(entitled_key_data_), num_keys_, entitled_key_array_));
return;
}
VerifyKCBs();
@@ -1362,6 +1392,7 @@ void RenewalRoundTrip::EncryptAndSignResponse() {
session()->key_deriver().ServerSignBuffer(encrypted_response_.data(),
encrypted_response_.size(),
&response_signature_);
SetEncryptAndSignResponseLengths();
}
void RenewalRoundTrip::InjectFuzzedResponseData(
@@ -1409,6 +1440,7 @@ OEMCryptoResult RenewalRoundTrip::LoadResponse(Session* session) {
reinterpret_cast<const char*>(&encrypted_response_data_),
sizeof(encrypted_response_data_));
}
VerifyEncryptAndSignResponseLengths();
if (license_messages_->api_version() < kCoreMessagesAPI) {
return OEMCrypto_RefreshKeys(
session->session_id(), encrypted_response_.data(),
@@ -1422,6 +1454,11 @@ OEMCryptoResult RenewalRoundTrip::LoadResponse(Session* session) {
}
}
std::unordered_map<util::EccCurve, std::unique_ptr<util::EccPrivateKey>,
std::hash<int>>
Session::server_ephemeral_keys_;
std::mutex Session::ephemeral_key_map_lock_;
Session::Session() {}
Session::~Session() {
@@ -1798,15 +1835,21 @@ bool Session::GenerateEccSessionKey(vector<uint8_t>* session_key,
cerr << "No public ECC key loaded in test code\n";
return false;
}
auto ephemeral_key = util::EccPrivateKey::New(public_ec_->curve());
if (!ephemeral_key) {
std::unique_lock<std::mutex> lock(Session::ephemeral_key_map_lock_);
const util::EccCurve curve = public_ec_->curve();
if (server_ephemeral_keys_.count(curve) == 0) {
server_ephemeral_keys_[curve] = util::EccPrivateKey::New(curve);
}
if (server_ephemeral_keys_.count(curve) == 0) {
cerr << "Failed to find/create server ECC key for curve "
<< util::EccCurveToString(curve) << std::endl;
return false;
}
*session_key = ephemeral_key->DeriveSessionKey(*public_ec_);
*session_key = server_ephemeral_keys_[curve]->DeriveSessionKey(*public_ec_);
if (session_key->empty()) {
return false;
}
*ecdh_public_key_data = ephemeral_key->SerializeAsPublicKey();
*ecdh_public_key_data = server_ephemeral_keys_[curve]->SerializeAsPublicKey();
if (ecdh_public_key_data->empty()) {
session_key->clear();
return false;

View File

@@ -9,6 +9,7 @@
//
#include <gtest/gtest.h>
#include <time.h>
#include <unordered_map>
#include <string>
#include <vector>
@@ -153,7 +154,9 @@ class RoundTrip {
encrypted_response_data_(),
required_message_size_(0),
required_core_message_size_(0),
required_request_signature_size_(0) {}
required_request_signature_size_(0),
encrypted_response_length_(0),
response_signature_length_(0) {}
virtual ~RoundTrip() {}
// Have OEMCrypto sign a request message and then verify the signature and the
@@ -230,6 +233,11 @@ class RoundTrip {
// Find the given pointer in the response_data_.
virtual OEMCrypto_Substring FindSubstring(const void* pointer, size_t length);
// Set EncryptAndSignResponse output lengths for later verification.
void SetEncryptAndSignResponseLengths();
// Verify EncryptAndSignResponse output lengths are unchanged.
void VerifyEncryptAndSignResponseLengths() const;
// ----------------------------------------------------------------------
// Member variables.
Session* session_;
@@ -244,6 +252,11 @@ class RoundTrip {
std::vector<uint8_t> response_signature_;
std::string serialized_core_message_;
std::vector<uint8_t> encrypted_response_;
private:
// EncryptAndSignResponse output lengths.
size_t encrypted_response_length_;
size_t response_signature_length_;
};
class ProvisioningRoundTrip
@@ -486,7 +499,7 @@ class EntitledMessage {
void SetEntitledKeySession(uint32_t key_session) {
entitled_key_session_ = key_session;
}
void LoadKeys(OEMCryptoResult expected_sts);
void LoadKeys(bool expected_success);
OEMCryptoResult LoadKeys(const vector<uint8_t>& message);
OEMCryptoResult LoadKeys();
void EncryptContentKey();
@@ -721,6 +734,19 @@ class Session {
// Only one of RSA or EC should be set.
std::unique_ptr<util::RsaPublicKey> public_rsa_;
std::unique_ptr<util::EccPublicKey> public_ec_;
// In provisioning 4.0, the shared session key is derived from either
// 1. (client side) client private key + server ephemeral public key, or
// 2. (server side) server ephemeral private key + client public key
// Encryption key and mac keys are derived from the shared session key, and
// are inserted in to the default license response which simulates the
// response from a license server. In order for these keys to be deterministic
// across multiple test calls of GenerateDerivedKeysFromSessionKey(), which
// simulates how the server derives keys, the ephemeral keys used by the
// "server" need to be stored for re-use.
static std::unordered_map<
util::EccCurve, std::unique_ptr<util::EccPrivateKey>, std::hash<int>>
server_ephemeral_keys_;
static std::mutex ephemeral_key_map_lock_;
vector<uint8_t> pst_report_buffer_;
MessageData license_ = {};

View File

@@ -275,7 +275,7 @@ TEST_F(OEMCryptoClientTest, VersionNumber) {
// If any of the following fail, then it is time to update the log message
// above.
EXPECT_EQ(ODK_MAJOR_VERSION, 17);
EXPECT_EQ(ODK_MINOR_VERSION, 0);
EXPECT_EQ(ODK_MINOR_VERSION, 2);
EXPECT_EQ(kCurrentAPI, 17u);
OEMCrypto_Security_Level level = OEMCrypto_SecurityLevel();
EXPECT_GT(level, OEMCrypto_Level_Unknown);
@@ -1515,11 +1515,19 @@ TEST_F(OEMCryptoProv40Test, InstallOemPrivateKeyCanBeUsed) {
wrapped_private_key2.resize(wrapped_private_key_size2);
// Verify public_key_signature2 with public_key1.
ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromSubjectPublicKey(
public_key1.data(), public_key1.size()));
ASSERT_NO_FATAL_FAILURE(
s.VerifyRsaSignature(public_key2, public_key_signature2.data(),
public_key_signature2.size(), kSign_RSASSA_PSS));
if (key_type2 == OEMCrypto_PrivateKeyType::OEMCrypto_RSA_Private_Key) {
ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromSubjectPublicKey(
public_key1.data(), public_key1.size()));
ASSERT_NO_FATAL_FAILURE(
s.VerifyRsaSignature(public_key2, public_key_signature2.data(),
public_key_signature2.size(), kSign_RSASSA_PSS));
} else if (key_type2 == OEMCrypto_PrivateKeyType::OEMCrypto_ECC_Private_Key) {
ASSERT_NO_FATAL_FAILURE(s.SetEccPublicKeyFromSubjectPublicKey(
public_key1.data(), public_key1.size()));
ASSERT_NO_FATAL_FAILURE(s.VerifyEccSignature(public_key2,
public_key_signature2.data(),
public_key_signature2.size()));
}
}
TEST_F(OEMCryptoProv40Test, GetDeviceId) {
@@ -2072,11 +2080,11 @@ TEST_P(OEMCryptoEntitlementLicenseTest, LoadEntitlementKeysAPI17) {
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(true));
EntitledMessage entitled_message_2(&license_messages_);
entitled_message_2.FillKeyArray();
entitled_message_2.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_2.LoadKeys(OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(entitled_message_2.LoadKeys(true));
}
TEST_P(OEMCryptoEntitlementLicenseTest, CasOnlyLoadCasKeysAPI17) {
@@ -2113,6 +2121,7 @@ TEST_P(OEMCryptoEntitlementLicenseTest,
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
uint32_t key_session_id = 0;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id));
@@ -2121,8 +2130,7 @@ TEST_P(OEMCryptoEntitlementLicenseTest,
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(
entitled_message_1.LoadKeys(OEMCrypto_ERROR_INVALID_CONTEXT));
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(false));
}
// This verifies that entitled content keys cannot be loaded if we have loaded
@@ -2160,8 +2168,7 @@ TEST_P(OEMCryptoEntitlementLicenseTest,
const std::string key_id = "no_key";
entitled_message_1.SetEntitlementKeyId(0, key_id);
entitled_message_1.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(
entitled_message_1.LoadKeys(OEMCrypto_KEY_NOT_ENTITLED));
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(false));
}
TEST_P(OEMCryptoEntitlementLicenseTest,
@@ -2194,8 +2201,7 @@ TEST_P(OEMCryptoEntitlementLicenseTest,
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(0);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(
OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION));
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(false));
}
TEST_P(OEMCryptoEntitlementLicenseTest,
@@ -2227,8 +2233,7 @@ TEST_P(OEMCryptoEntitlementLicenseTest,
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(session_.session_id());
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(
OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION));
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(false));
}
TEST_P(OEMCryptoEntitlementLicenseTest,
@@ -2946,7 +2951,7 @@ TEST_P(OEMCryptoLicenseTest,
}
TEST_P(OEMCryptoLicenseTest,
OEMCryptoMemoryDecryptCENCForOutOfRangeNumBytesEncrypted) {
OEMCryptoMemoryDecryptCENCForOutOfRangeNumBytesEncryptedAPI16) {
TestDecryptCENCForOutOfRangeOffsetsAndLengths(
[](OEMCrypto_SampleDescription* sample_description) {
OEMCrypto_SubSampleDescription* sub_samples =
@@ -3037,7 +3042,7 @@ TEST_P(OEMCryptoLicenseTest, SelectKeyEntitledKeyAPI17) {
entitled_message_1.SetEntitledKeySession(key_session_id);
const char* content_key_id = "content_key_id";
entitled_message_1.SetContentKeyId(0, content_key_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(true));
ASSERT_EQ(
OEMCrypto_SUCCESS,
@@ -3061,7 +3066,7 @@ TEST_P(OEMCryptoLicenseTest, SelectKeyEntitledKeyNotThereAPI17) {
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(true));
const char* content_key_id = "no_key";
ASSERT_EQ(
@@ -3071,7 +3076,7 @@ TEST_P(OEMCryptoLicenseTest, SelectKeyEntitledKeyNotThereAPI17) {
strlen(content_key_id), OEMCrypto_CipherMode_CENC));
}
// Select key with entitlement license fails if the key id is entitilement key
// Select key with entitlement license fails if the key id is entitlement key
// id.
TEST_P(OEMCryptoLicenseTest, SelectKeyEntitlementKeyAPI17) {
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
@@ -3086,13 +3091,13 @@ TEST_P(OEMCryptoLicenseTest, SelectKeyEntitlementKeyAPI17) {
EntitledMessage entitled_message_1(&license_messages_);
entitled_message_1.FillKeyArray();
entitled_message_1.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(true));
ASSERT_EQ(OEMCrypto_ERROR_INVALID_CONTEXT,
OEMCrypto_SelectKey(session_.session_id(),
session_.license().keys[0].key_id,
session_.license().keys[0].key_id_length,
OEMCrypto_CipherMode_CENC));
OEMCryptoResult res = OEMCrypto_SelectKey(
session_.session_id(), session_.license().keys[0].key_id,
session_.license().keys[0].key_id_length, OEMCrypto_CipherMode_CENC);
EXPECT_TRUE(res == OEMCrypto_ERROR_INVALID_CONTEXT ||
res == OEMCrypto_ERROR_NO_CONTENT_KEY);
}
// This verifies that entitled key sessions can be created and removed.
@@ -3121,6 +3126,28 @@ TEST_P(OEMCryptoLicenseTest, EntitledKeySessionsAPI17) {
OEMCrypto_RemoveEntitledKeySession(key_session_id_2));
}
TEST_P(OEMCryptoLicenseTest,
EntitledKeySessionsCloseWithOEMCryptoSessionAPI17) {
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
uint32_t key_session_id_1;
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_CreateEntitledKeySession(
session_.session_id(), &key_session_id_1));
// Close the OEMCrypto session.
session_.close();
// All entitled key sessions associated with the OEMCrypto session should
// already be been destroyed,
OEMCryptoResult sts = OEMCrypto_RemoveEntitledKeySession(key_session_id_1);
EXPECT_TRUE(sts == OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION ||
sts == OEMCrypto_ERROR_INVALID_SESSION);
// Open a new session just for OEMCryptoLicenseTest TearDown.
session_.open();
}
// This verifies that multiple entitled key sessions can be created. They can
// load and select keys independently.
TEST_P(OEMCryptoLicenseTest, EntitledKeySessionMultipleKeySessionsAPI17) {
@@ -3138,7 +3165,7 @@ TEST_P(OEMCryptoLicenseTest, EntitledKeySessionMultipleKeySessionsAPI17) {
entitled_message_1.SetEntitledKeySession(key_session_id_1);
const char* content_key_id_1 = "content_key_id_1";
entitled_message_1.SetContentKeyId(0, content_key_id_1);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(true));
// We can select content key 1 in entitled key session 1.
ASSERT_EQ(
OEMCrypto_SUCCESS,
@@ -3157,7 +3184,7 @@ TEST_P(OEMCryptoLicenseTest, EntitledKeySessionMultipleKeySessionsAPI17) {
entitled_message_2.SetEntitledKeySession(key_session_id_2);
const char* content_key_id_2 = "content_key_id_2";
entitled_message_2.SetContentKeyId(0, content_key_id_2);
ASSERT_NO_FATAL_FAILURE(entitled_message_2.LoadKeys(OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(entitled_message_2.LoadKeys(true));
// We can select content key 2 in entitled key session 2.
ASSERT_EQ(
OEMCrypto_SUCCESS,
@@ -3197,7 +3224,7 @@ TEST_P(OEMCryptoLicenseTest,
entitled_message_1.SetEntitledKeySession(key_session_id);
const char* content_key_id_1 = "content_key_id_1";
entitled_message_1.SetContentKeyId(0, content_key_id_1);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(true));
// We can select content key 1 in entitled key session.
ASSERT_EQ(
OEMCrypto_SUCCESS,
@@ -3207,7 +3234,7 @@ TEST_P(OEMCryptoLicenseTest,
// Load content key with new content id.
const char* content_key_id_2 = "content_key_id_2";
entitled_message_1.SetContentKeyId(0, content_key_id_2);
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(entitled_message_1.LoadKeys(true));
// We can select content key 2 in entitled key session.
ASSERT_EQ(
OEMCrypto_SUCCESS,
@@ -3243,7 +3270,7 @@ TEST_P(OEMCryptoLicenseTest,
entitled_message.SetEntitledKeySession(key_session_id);
const char* content_key_id = "content_key_id";
entitled_message.SetContentKeyId(0, content_key_id);
ASSERT_NO_FATAL_FAILURE(entitled_message.LoadKeys(OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(entitled_message.LoadKeys(true));
ASSERT_EQ(
OEMCrypto_SUCCESS,
OEMCrypto_SelectKey(key_session_id,
@@ -3270,7 +3297,7 @@ TEST_P(OEMCryptoLicenseTest,
// This verifies that an entitled key session can be reassociated to an
// OEMCrypto session.
TEST_P(OEMCryptoLicenseTest, ReassociateEntitledKeySessionAPI17) {
TEST_P(OEMCryptoEntitlementLicenseTest, ReassociateEntitledKeySessionAPI17) {
license_messages_.set_license_type(OEMCrypto_EntitlementLicense);
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
@@ -3289,20 +3316,19 @@ TEST_P(OEMCryptoLicenseTest, ReassociateEntitledKeySessionAPI17) {
EntitledMessage entitled_message(&license_messages_);
entitled_message.FillKeyArray();
entitled_message.SetEntitledKeySession(key_session_id);
ASSERT_NO_FATAL_FAILURE(entitled_message.LoadKeys(OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(entitled_message.LoadKeys(true));
// Now reassociate the entitled key session to the second OEMCrypto session.
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_ReassociateEntitledKeySession(
key_session_id, session2.session_id()));
// session2 does not have entitlement keys.
ASSERT_NO_FATAL_FAILURE(
entitled_message.LoadKeys(OEMCrypto_ERROR_INVALID_CONTEXT));
ASSERT_NO_FATAL_FAILURE(entitled_message.LoadKeys(false));
// Now reassociate the entitled key session back to the first OEMCrypto
// session.
ASSERT_EQ(OEMCrypto_SUCCESS, OEMCrypto_ReassociateEntitledKeySession(
key_session_id, session_.session_id()));
ASSERT_NO_FATAL_FAILURE(entitled_message.LoadKeys(OEMCrypto_SUCCESS));
ASSERT_NO_FATAL_FAILURE(entitled_message.LoadKeys(true));
}
// 'cens' mode is no longer supported in v16
@@ -3463,7 +3489,7 @@ TEST_P(OEMCryptoLicenseTest, QueryKeyControl) {
// clear key control block (KCB) in the license response. An OEMCrypto v17.1+
// implementation should be able to handle the clear KCB in the 16.4.x response
// and load the license correctly.
TEST_F(OEMCryptoSessionTests, ClearKcbAPI16_4) {
TEST_F(OEMCryptoSessionTests, ClearKcbAPI17) {
Session s;
ASSERT_NO_FATAL_FAILURE(s.open());
ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s));
@@ -3658,7 +3684,7 @@ TEST_P(
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyControlIvLength) {
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyControlIvLengthAPI16) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& key_control_iv =
@@ -3702,7 +3728,7 @@ TEST_P(OEMCryptoLicenseOverflowTest,
TEST_P(
OEMCryptoLicenseOverflowTest,
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyControlLength) {
OEMCryptoMemoryLoadLicenseForOutOfRangeCoreMessageSubstringKeyControlLengthAPI16) {
TestLoadLicenseForOutOfRangeSubStringOffSetAndLengths(
[](size_t response_message_length, LicenseRoundTrip* license_messages) {
auto& key_control =
@@ -5682,7 +5708,7 @@ TEST_F(OEMCryptoLoadsCertificate,
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncPrivateKeyIvLength) {
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncPrivateKeyIvLengthAPI16) {
TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths(
[](size_t response_message_length,
ProvisioningRoundTrip* provisioning_messages) {
@@ -5728,7 +5754,7 @@ TEST_F(OEMCryptoLoadsCertificate,
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncMessageKeyLength) {
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncMessageKeyLengthProv30) {
TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths(
[](size_t response_message_length,
ProvisioningRoundTrip* provisioning_messages) {
@@ -5741,7 +5767,7 @@ TEST_F(
TEST_F(
OEMCryptoLoadsCertificate,
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncMessageKeyOffset) {
OEMCryptoMemoryLoadProvisioningForOutOfRangeCoreMessageEncMessageKeyOffsetProv30) {
TestLoadProvisioningForOutOfRangeSubstringOffsetAndLengths(
[](size_t response_message_length,
ProvisioningRoundTrip* provisioning_messages) {
@@ -6188,7 +6214,7 @@ TEST_F(OEMCryptoLoadsCertificate, RSAPerformance) {
TEST_F(OEMCryptoUsesCertificate, GenerateDerivedKeysLargeBuffer) {
vector<uint8_t> session_key;
vector<uint8_t> enc_session_key;
ASSERT_TRUE(session_.GenerateRsaSessionKey(&session_key, &enc_session_key));
ASSERT_TRUE(session_.GenerateSessionKey(&session_key, &enc_session_key));
const size_t max_size = GetResourceValue(kLargeMessageSize);
vector<uint8_t> mac_context(max_size);
vector<uint8_t> enc_context(max_size);
@@ -6208,7 +6234,7 @@ TEST_F(OEMCryptoUsesCertificate,
OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeMacContext) {
vector<uint8_t> session_key;
vector<uint8_t> enc_session_key;
ASSERT_TRUE(session_.GenerateRsaSessionKey(&session_key, &enc_session_key));
ASSERT_TRUE(session_.GenerateSessionKey(&session_key, &enc_session_key));
vector<uint8_t> mac_context;
vector<uint8_t> enc_context;
session_.FillDefaultContext(&mac_context, &enc_context);
@@ -6228,7 +6254,7 @@ TEST_F(OEMCryptoUsesCertificate,
OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeEncContext) {
vector<uint8_t> session_key;
vector<uint8_t> enc_session_key;
ASSERT_TRUE(session_.GenerateRsaSessionKey(&session_key, &enc_session_key));
ASSERT_TRUE(session_.GenerateSessionKey(&session_key, &enc_session_key));
vector<uint8_t> mac_context;
vector<uint8_t> enc_context;
session_.FillDefaultContext(&mac_context, &enc_context);
@@ -6248,7 +6274,7 @@ TEST_F(OEMCryptoUsesCertificate,
OEMCryptoMemoryDeriveKeysFromSessionKeyForHugeEncSessionKey) {
vector<uint8_t> session_key;
vector<uint8_t> enc_session_key;
ASSERT_TRUE(session_.GenerateRsaSessionKey(&session_key, &enc_session_key));
ASSERT_TRUE(session_.GenerateSessionKey(&session_key, &enc_session_key));
vector<uint8_t> mac_context;
vector<uint8_t> enc_context;
session_.FillDefaultContext(&mac_context, &enc_context);
@@ -6359,7 +6385,9 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate {
OEMCryptoResult sts = provisioning_messages.LoadResponse();
key_loaded_ = (OEMCrypto_SUCCESS == sts);
if (key_loaded_) {
encoded_rsa_key_ = provisioning_messages.encoded_rsa_key();
uint8_t* ptr = provisioning_messages.response_data().rsa_key;
size_t len = provisioning_messages.response_data().rsa_key_length;
encoded_rsa_key_ = std::vector<uint8_t>(ptr, ptr + len);
wrapped_rsa_key_ = provisioning_messages.wrapped_rsa_key();
EXPECT_GT(wrapped_rsa_key_.size(), 0u);
EXPECT_EQ(nullptr, find(wrapped_rsa_key_, encoded_rsa_key_));