OEMCrypto unit tests for license release

Bug: 295956275
Change-Id: I3c8fc5fcadeae051cc734a64378e473492437c34
This commit is contained in:
Vicky Min
2023-12-05 01:36:58 +00:00
committed by Robert Shih
parent f94a8dfac9
commit d5157c536d
7 changed files with 233 additions and 21 deletions

View File

@@ -1513,27 +1513,9 @@ void RenewalRoundTrip::FillAndVerifyCoreRequest(
}
}
void RenewalRoundTrip::CreateDefaultResponse() {
if (is_release_) {
uint32_t control = 0;
uint32_t nonce = 0;
// A single key object with no key id should update all keys.
constexpr size_t index = 0;
response_data_.keys[index].key_id_length = 0;
response_data_.keys[index].key_id[0] = '\0';
const uint32_t renewal_api =
std::max<uint32_t>(core_request_.api_major_version, 15u);
std::string kcVersion = "kc" + std::to_string(renewal_api);
memcpy(response_data_.keys[index].control.verification, kcVersion.c_str(),
4);
const uint32_t duration = static_cast<uint32_t>(
license_messages_->core_response()
.timer_limits.initial_renewal_duration_seconds);
response_data_.keys[index].control.duration = htonl(duration);
response_data_.keys[index].control.nonce = htonl(nonce);
response_data_.keys[index].control.control_bits = htonl(control);
}
}
// Nothing is needed for this function but it needs a definition since it's
// declared as a virtual function in the RoundTrip class.
void RenewalRoundTrip::CreateDefaultResponse() {}
void RenewalRoundTrip::EncryptAndSignResponse() {
// Renewal messages are not encrypted.
@@ -1628,6 +1610,80 @@ OEMCryptoResult RenewalRoundTrip::LoadResponse(Session* session) {
response_signature_.data(), response_signature_.size());
}
void ReleaseRoundTrip::VerifyRequestSignature(
const vector<uint8_t>& data, const vector<uint8_t>& generated_signature,
size_t core_message_length) {
ASSERT_EQ(HMAC_SHA256_SIGNATURE_SIZE, generated_signature.size());
std::vector<uint8_t> expected_signature;
session()->key_deriver().ClientSignBuffer(data, &expected_signature);
ASSERT_EQ(expected_signature, generated_signature);
}
void ReleaseRoundTrip::FillAndVerifyCoreRequest(
const std::string& core_message_string) {
EXPECT_TRUE(
oemcrypto_core_message::deserialize::CoreReleaseRequestFromMessage(
core_message_string, &core_request_));
EXPECT_EQ(license_messages_->api_version(), core_request_.api_major_version);
EXPECT_EQ(license_messages_->core_request().nonce, core_request_.nonce);
EXPECT_EQ(license_messages_->core_request().session_id,
core_request_.session_id);
}
// Nothing is needed for this function but it needs a definition since it's
// declared as a virtual function in the RoundTrip class.
void ReleaseRoundTrip::CreateDefaultResponse() {}
void ReleaseRoundTrip::EncryptAndSignResponse() {
// Release messages are not encrypted.
encrypted_response_data_ = response_data_;
// Create a core response for a call to LoadRelease.
// TODO(b/191724203): Test release server has different version from license
// server.
ASSERT_NE(license_messages_, nullptr);
CoreMessageFeatures features =
CoreMessageFeatures::DefaultFeatures(license_messages_->api_version());
ASSERT_TRUE(oemcrypto_core_message::serialize::CreateCoreReleaseResponse(
features, core_request_, seconds_since_license_received_,
seconds_since_first_decrypt_, &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.
const size_t message_size =
std::max(required_message_size_, serialized_core_message_.size() +
sizeof(encrypted_response_data_));
// Stripe the encrypted message.
encrypted_response_.resize(message_size);
for (size_t i = 0; i < encrypted_response_.size(); i++) {
encrypted_response_[i] = i % 0x100;
}
// Concatenate the core message and the response.
ASSERT_GE(encrypted_response_.size(), serialized_core_message_.size());
memcpy(encrypted_response_.data(), serialized_core_message_.data(),
serialized_core_message_.size());
ASSERT_GE(encrypted_response_.size(),
serialized_core_message_.size() + sizeof(encrypted_response_data_));
memcpy(encrypted_response_.data() + serialized_core_message_.size(),
reinterpret_cast<const uint8_t*>(&encrypted_response_data_),
sizeof(encrypted_response_data_));
session()->key_deriver().ServerSignBuffer(encrypted_response_.data(),
encrypted_response_.size(),
&response_signature_);
SetEncryptAndSignResponseLengths();
}
OEMCryptoResult ReleaseRoundTrip::LoadResponse(Session* session) {
// TODO(vickymin): Write corpus for oemcrypto_load_release_fuzz.
VerifyEncryptAndSignResponseLengths();
return OEMCrypto_LoadRelease(
session->session_id(), encrypted_response_.data(),
encrypted_response_.size(), serialized_core_message_.size(),
response_signature_.data(), response_signature_.size());
}
std::unordered_map<util::EccCurve, std::unique_ptr<util::EccPrivateKey>,
std::hash<int>>
Session::server_ephemeral_keys_;