Bharath Chandra Elluru
2020-12-15 12:13:07 -08:00
parent e851d42eb1
commit 6b548748b2
5 changed files with 2391 additions and 139 deletions

View File

@@ -144,26 +144,29 @@ Test_PST_Report::Test_PST_Report(const std::string& pst_in,
template <class CoreRequest, PrepAndSignRequest_t PrepAndSignRequest,
class CoreResponse, class ResponseData>
void RoundTrip<CoreRequest, PrepAndSignRequest, CoreResponse,
ResponseData>::SignAndVerifyRequest() {
OEMCryptoResult
RoundTrip<CoreRequest, PrepAndSignRequest, CoreResponse, ResponseData>::
SignAndCreateRequestWithCustomBufferLengths(bool verify_request) {
// In the real world, a message should be signed by the client and
// verified by the server. This simulates that.
size_t gen_signature_length = 0;
size_t core_message_length = 0;
constexpr size_t small_size = 42; // arbitrary.
size_t message_size =
std::max(required_message_size_, core_message_length + small_size);
vector<uint8_t> data(message_size, 0);
for (size_t i = 0; i < data.size(); i++) data[i] = i & 0xFF;
ASSERT_EQ(
PrepAndSignRequest(session()->session_id(), data.data(), data.size(),
&core_message_length, nullptr, &gen_signature_length),
OEMCrypto_ERROR_SHORT_BUFFER);
uint32_t session_id = session()->session_id();
GetDefaultRequestSignatureAndCoreMessageLengths<PrepAndSignRequest>(
session_id, required_message_size_, small_size, &gen_signature_length,
&core_message_length);
// Used to test request APIs with varying lengths of core message.
core_message_length =
std::max(core_message_length, required_core_message_size_);
// Used to test request APIs with varying lengths of signature.
gen_signature_length =
std::max(gen_signature_length, required_request_signature_size_);
// Make the message buffer a little bigger than the core message, or the
// required size, whichever is larger.
message_size =
size_t message_size =
std::max(required_message_size_, core_message_length + small_size);
data.resize(message_size);
vector<uint8_t> data(message_size);
for (size_t i = 0; i < data.size(); i++) data[i] = i & 0xFF;
if (ShouldGenerateCorpus()) {
WriteRequestApiCorpus<CoreRequest>(gen_signature_length,
@@ -171,17 +174,33 @@ void RoundTrip<CoreRequest, PrepAndSignRequest, CoreResponse,
}
vector<uint8_t> gen_signature(gen_signature_length);
ASSERT_EQ(PrepAndSignRequest(session()->session_id(), data.data(),
data.size(), &core_message_length,
gen_signature.data(), &gen_signature_length),
OEMCrypto_SUCCESS);
OEMCryptoResult result = PrepAndSignRequest(
session()->session_id(), data.data(), data.size(), &core_message_length,
gen_signature.data(), &gen_signature_length);
// We need to fill in core request and verify signature only for calls other
// than OEMCryptoMemory buffer overflow test. Any test other than buffer
// overflow will pass true.
if (!verify_request || result != OEMCrypto_SUCCESS) return result;
if (global_features.api_version >= kCoreMessagesAPI) {
ASSERT_GT(data.size(), core_message_length);
std::string core_message(reinterpret_cast<char*>(data.data()),
core_message_length);
FillAndVerifyCoreRequest(core_message);
}
VerifyRequestSignature(data, gen_signature, core_message_length);
return result;
}
template <PrepAndSignRequest_t PrepAndSignRequest>
void GetDefaultRequestSignatureAndCoreMessageLengths(
uint32_t& session_id, size_t& required_message_size,
const size_t& small_size, size_t* gen_signature_length,
size_t* core_message_length) {
vector<uint8_t> data(small_size);
for (size_t i = 0; i < data.size(); i++) data[i] = i & 0xFF;
ASSERT_EQ(
PrepAndSignRequest(session_id, data.data(), data.size(),
core_message_length, nullptr, gen_signature_length),
OEMCrypto_ERROR_SHORT_BUFFER);
}
template <class CoreRequest, PrepAndSignRequest_t PrepAndSignRequest,
@@ -306,10 +325,26 @@ void ProvisioningRoundTrip::EncryptAndSignResponse() {
&encrypted_response_data_);
core_response_.enc_private_key.length =
encrypted_response_data_.rsa_key_length;
SignResponse();
}
// We need this for provisioning response out of range tests where
// core response substring lengths are modified.
void ProvisioningRoundTrip::
EncryptAndSignResponseWithoutUpdatingEncPrivateKeyLength() {
encryptor_.PadAndEncryptProvisioningMessage(&response_data_,
&encrypted_response_data_);
SignResponse();
}
void ProvisioningRoundTrip::SignResponse() {
if (global_features.api_version >= kCoreMessagesAPI) {
ASSERT_TRUE(
oemcrypto_core_message::serialize::CreateCoreProvisioningResponse(
core_response_, core_request_, &serialized_core_message_));
// Resizing for huge core message length unit tests.
serialized_core_message_.resize(
std::max(required_core_message_size_, serialized_core_message_.size()));
}
// Make the message buffer a just big enough, or the
// required size, whichever is larger.
@@ -689,6 +724,10 @@ void LicenseRoundTrip::EncryptAndSignResponse() {
ASSERT_TRUE(oemcrypto_core_message::serialize::CreateCoreLicenseResponse(
core_response_, core_request_, request_hash_string,
&serialized_core_message_));
// Resize serialize core message to be just big enough or required core
// message size, whichever is larger.
serialized_core_message_.resize(
std::max(required_core_message_size_, serialized_core_message_.size()));
}
// Make the message buffer a just big enough, or the
@@ -701,7 +740,6 @@ void LicenseRoundTrip::EncryptAndSignResponse() {
for (size_t i = 0; i < encrypted_response_.size(); i++) {
encrypted_response_[i] = i % 0x100;
}
ASSERT_GE(kMaxCoreMessage, serialized_core_message_.size());
ASSERT_GE(encrypted_response_.size(), serialized_core_message_.size());
memcpy(encrypted_response_.data(), serialized_core_message_.data(),
serialized_core_message_.size());
@@ -716,6 +754,11 @@ void LicenseRoundTrip::EncryptAndSignResponse() {
}
OEMCryptoResult LicenseRoundTrip::LoadResponse(Session* session) {
return LoadResponse(session, true);
}
OEMCryptoResult LicenseRoundTrip::LoadResponse(Session* session,
bool verify_keys) {
EXPECT_NE(session, nullptr);
// Write corpus for oemcrypto_load_license_fuzz. Fuzz script expects
// unecnrypted response from license server as input corpus data.
@@ -762,7 +805,7 @@ OEMCryptoResult LicenseRoundTrip::LoadResponse(Session* session) {
encrypted_response_.size(), serialized_core_message_.size(),
response_signature_.data(), response_signature_.size());
}
if (result == OEMCrypto_SUCCESS) {
if (verify_keys && result == OEMCrypto_SUCCESS) {
// Give the session object a copy of the license truth data so that it can
// call SelectKey, use key control information, and so that it has key data
// to verify decrypt operations.
@@ -861,6 +904,18 @@ void EntitledMessage::MakeOneKey(size_t entitlement_key_index) {
key_data->content_key_data_iv, sizeof(key_data->content_key_data_iv));
}
OEMCrypto_EntitledContentKeyObject* EntitledMessage::entitled_key_array() {
return entitled_key_array_;
}
EntitledContentKeyData* EntitledMessage::entitled_key_data() {
return entitled_key_data_;
}
size_t EntitledMessage::entitled_key_data_size() {
return sizeof(entitled_key_data_);
}
void EntitledMessage::SetEntitlementKeyId(unsigned int index,
const std::string& key_id) {
ASSERT_LT(index, num_keys_);
@@ -884,6 +939,32 @@ OEMCrypto_Substring EntitledMessage::FindSubstring(const void* ptr,
}
void EntitledMessage::LoadKeys(OEMCryptoResult expected_sts) {
EncryptContentKey();
ASSERT_EQ(expected_sts,
OEMCrypto_LoadEntitledContentKeys(
license_messages_->session()->session_id(),
reinterpret_cast<const uint8_t*>(entitled_key_data_),
sizeof(entitled_key_data_), num_keys_, entitled_key_array_));
if (expected_sts != OEMCrypto_SUCCESS) {
return;
}
VerifyEntitlementTestKeys();
}
OEMCryptoResult EntitledMessage::LoadKeys(const vector<uint8_t>& message) {
return OEMCrypto_LoadEntitledContentKeys(
license_messages_->session()->session_id(), message.data(),
message.size(), num_keys_, entitled_key_array_);
}
OEMCryptoResult EntitledMessage::LoadKeys() {
return OEMCrypto_LoadEntitledContentKeys(
license_messages_->session()->session_id(),
reinterpret_cast<const uint8_t*>(entitled_key_data_),
sizeof(entitled_key_data_), num_keys_, entitled_key_array_);
}
void EntitledMessage::EncryptContentKey() {
for (size_t i = 0; i < num_keys_; ++i) {
EntitledContentKeyData* key_data = &entitled_key_data_[i];
const size_t entitlement_key_index = key_data->key_index;
@@ -912,15 +993,6 @@ void EntitledMessage::LoadKeys(OEMCryptoResult expected_sts) {
AppendToFile(file_name, reinterpret_cast<const char*>(entitled_key_array_),
num_keys_);
}
ASSERT_EQ(expected_sts,
OEMCrypto_LoadEntitledContentKeys(
license_messages_->session()->session_id(),
reinterpret_cast<const uint8_t*>(entitled_key_data_),
sizeof(entitled_key_data_), num_keys_, entitled_key_array_));
if (expected_sts != OEMCrypto_SUCCESS) {
return;
}
VerifyEntitlementTestKeys();
}
// This function verifies that the key control block reported by OEMCrypto agree
@@ -1035,6 +1107,10 @@ void RenewalRoundTrip::EncryptAndSignResponse() {
} else {
ASSERT_TRUE(oemcrypto_core_message::serialize::CreateCoreRenewalResponse(
core_request_, renewal_duration_seconds_, &serialized_core_message_));
// Resize serialize core message to be just big enough or required core
// message size, whichever is larger.
serialized_core_message_.resize(
std::max(required_core_message_size_, serialized_core_message_.size()));
}
// Make the message buffer a just big enough, or the
// required size, whichever is larger.
@@ -1047,7 +1123,6 @@ void RenewalRoundTrip::EncryptAndSignResponse() {
encrypted_response_[i] = i % 0x100;
}
// Concatenate the core message and the response.
ASSERT_GE(kMaxCoreMessage, serialized_core_message_.size());
ASSERT_GE(encrypted_response_.size(), serialized_core_message_.size());
memcpy(encrypted_response_.data(), serialized_core_message_.data(),
serialized_core_message_.size());