Merge oemcrypto buffer overflow tests from cdm
Widevine CLs: http://go/wvgerrit/112243 http://go/wvgerrit/110563 http://go/wvgerrit/95483 http://go/wvgerrit/107047 http://go/wvgerrit/111123 http://go/wvgerrit/106224 http://go/wvgerrit/106263 http://go/wvgerrit/106223 http://go/wvgerrit/104223 http://go/wvgerrit/108583 http://go/wvgerrit/111403 http://go/wvgerrit/111623 http://go/wvgerrit/106264 http://go/wvgerrit/110483 http://go/wvgerrit/111944 http://go/wvgerrit/108684 http://go/wvgerrit/104183 http://go/wvgerrit/111443 http://go/wvgerrit/111869 http://go/wvgerrit/108843 http://go/wvgerrit/104363 http://go/wvgerrit/104423 http://go/wvgerrit/104263 http://go/wvgerrit/106584 http://go/wvgerrit/105924 http://go/wvgerrit/104524 http://go/wvgerrit/113023 Bug:175401639 Test: We would like to run these tests on pixel devices from master branch using go/wv-and-dash Change-Id: Ic4188504af64de9ce79941f75ac6feaf29189a4d
This commit is contained in:
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user