Add unit test for clear KCB in LS SDK 16.4 response am: 8c4c238324 am: b363f54f9e
Original change: https://googleplex-android-review.googlesource.com/c/platform/vendor/widevine/+/18973819 Change-Id: Id78fb4d41f4d7a9b7e090dec2a1d00952e65ebb5 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -28,7 +28,6 @@
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "clock.h"
|
||||
#include "core_message_deserialize.h"
|
||||
#include "core_message_features.h"
|
||||
#include "core_message_serialize.h"
|
||||
#include "disallow_copy_and_assign.h"
|
||||
#include "log.h"
|
||||
@@ -770,7 +769,7 @@ void LicenseRoundTrip::FillCoreResponseSubstrings() {
|
||||
}
|
||||
}
|
||||
|
||||
void LicenseRoundTrip::EncryptAndSignResponse() {
|
||||
void LicenseRoundTrip::EncryptResponse(bool force_clear_kcb) {
|
||||
ASSERT_NO_FATAL_FAILURE(session_->GenerateDerivedKeysFromSessionKey());
|
||||
encrypted_response_data_ = response_data_;
|
||||
uint8_t iv_buffer[KEY_IV_SIZE];
|
||||
@@ -786,7 +785,8 @@ void LicenseRoundTrip::EncryptAndSignResponse() {
|
||||
// Fuzzing skip encryption: key_data_length being a random value will
|
||||
// encrypt data which is not expected to, there by leading to inefficient
|
||||
// fuzzing.
|
||||
if (response_data_.keys[i].key_data_length <=
|
||||
if (!force_clear_kcb &&
|
||||
response_data_.keys[i].key_data_length <=
|
||||
sizeof(response_data_.keys[i].key_data) &&
|
||||
response_data_.keys[i].key_data_length % 16 == 0) {
|
||||
memcpy(iv_buffer, &response_data_.keys[i].control_iv[0], KEY_IV_SIZE);
|
||||
@@ -811,6 +811,10 @@ void LicenseRoundTrip::EncryptAndSignResponse() {
|
||||
response_data_.keys[i].key_iv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LicenseRoundTrip::CreateCoreLicenseResponseWithFeatures(
|
||||
const CoreMessageFeatures& features) {
|
||||
if (api_version_ < kCoreMessagesAPI) {
|
||||
serialized_core_message_.resize(0);
|
||||
} else {
|
||||
@@ -823,11 +827,6 @@ void LicenseRoundTrip::EncryptAndSignResponse() {
|
||||
}
|
||||
std::string request_hash_string(
|
||||
reinterpret_cast<const char*>(request_hash_), sizeof(request_hash_));
|
||||
// We might try to test a future api_version_, but we can only make a core
|
||||
// message with at most the current ODK version. This is only done to verify
|
||||
// that OEMCrypto does not attempt to load a future version.
|
||||
CoreMessageFeatures features = CoreMessageFeatures::DefaultFeatures(
|
||||
std::min(api_version_, static_cast<uint32_t>(ODK_MAJOR_VERSION)));
|
||||
ASSERT_TRUE(oemcrypto_core_message::serialize::CreateCoreLicenseResponse(
|
||||
features, core_response_, core_request_, request_hash_string,
|
||||
&serialized_core_message_));
|
||||
@@ -836,7 +835,9 @@ void LicenseRoundTrip::EncryptAndSignResponse() {
|
||||
serialized_core_message_.resize(
|
||||
std::max(required_core_message_size_, serialized_core_message_.size()));
|
||||
}
|
||||
}
|
||||
|
||||
void LicenseRoundTrip::SignEncryptedResponse() {
|
||||
// Make the message buffer a just big enough, or the
|
||||
// required size, whichever is larger.
|
||||
const size_t message_size =
|
||||
@@ -860,6 +861,24 @@ void LicenseRoundTrip::EncryptAndSignResponse() {
|
||||
&response_signature_);
|
||||
}
|
||||
|
||||
void LicenseRoundTrip::EncryptAndSignResponse() {
|
||||
EncryptResponse();
|
||||
// We might try to test a future api_version_, but we can only make a core
|
||||
// message with at most the current ODK version. This is only done to verify
|
||||
// that OEMCrypto does not attempt to load a future version.
|
||||
CoreMessageFeatures features = CoreMessageFeatures::DefaultFeatures(
|
||||
std::min(api_version_, static_cast<uint32_t>(ODK_MAJOR_VERSION)));
|
||||
CreateCoreLicenseResponseWithFeatures(features);
|
||||
SignEncryptedResponse();
|
||||
}
|
||||
|
||||
void LicenseRoundTrip::EncryptAndSignResponseWithCoreMessageFeatures(
|
||||
const CoreMessageFeatures& features, bool force_clear_kcb) {
|
||||
EncryptResponse(force_clear_kcb);
|
||||
CreateCoreLicenseResponseWithFeatures(features);
|
||||
SignEncryptedResponse();
|
||||
}
|
||||
|
||||
OEMCryptoResult LicenseRoundTrip::LoadResponse(Session* session) {
|
||||
return LoadResponse(session, true);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "core_message_deserialize.h"
|
||||
#include "core_message_features.h"
|
||||
#include "core_message_serialize.h"
|
||||
#include "odk.h"
|
||||
#include "oec_device_features.h"
|
||||
@@ -342,6 +343,18 @@ class LicenseRoundTrip
|
||||
// Fill the |core_response| substrings.
|
||||
virtual void FillCoreResponseSubstrings();
|
||||
void EncryptAndSignResponse() override;
|
||||
// Encrypt and sign license response created from a specific odk version.
|
||||
void EncryptAndSignResponseWithCoreMessageFeatures(
|
||||
const oemcrypto_core_message::features::CoreMessageFeatures& features,
|
||||
bool force_clear_kcb);
|
||||
// Encrypt license response. This is used in EncryptAndSignResponse().
|
||||
void EncryptResponse(bool force_clear_kcb = false);
|
||||
// Create core license response with a specific ODK version. This is used in
|
||||
// EncryptAndSignResponse().
|
||||
void CreateCoreLicenseResponseWithFeatures(
|
||||
const oemcrypto_core_message::features::CoreMessageFeatures& features);
|
||||
// Sign license response. This is used in EncryptAndSignResponse().
|
||||
void SignEncryptedResponse();
|
||||
OEMCryptoResult LoadResponse() override { return LoadResponse(session_); }
|
||||
OEMCryptoResult LoadResponse(Session* session) override;
|
||||
OEMCryptoResult LoadResponse(Session* session, bool verify_keys);
|
||||
|
||||
@@ -266,7 +266,7 @@ TEST_F(OEMCryptoClientTest, FreeUnallocatedSecureBufferNoFailure) {
|
||||
*/
|
||||
TEST_F(OEMCryptoClientTest, VersionNumber) {
|
||||
const std::string log_message =
|
||||
"OEMCrypto unit tests for API 17.0. Tests last updated 2022-02-18";
|
||||
"OEMCrypto unit tests for API 17.1. Tests last updated 2022-06-17";
|
||||
cout << " " << log_message << "\n";
|
||||
cout << " "
|
||||
<< "These tests are part of Android T."
|
||||
@@ -3445,6 +3445,39 @@ TEST_P(OEMCryptoLicenseTest, QueryKeyControl) {
|
||||
strlen(key_id), reinterpret_cast<uint8_t*>(&block), &size));
|
||||
}
|
||||
|
||||
// This case tests against the issue where certain 16.4.x SDK versions return a
|
||||
// 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) {
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&s));
|
||||
LicenseRoundTrip license_messages(&s);
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages.SignAndVerifyRequest());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages.CreateDefaultResponse());
|
||||
// Set odk version in the license response to be 16.4
|
||||
oemcrypto_core_message::features::CoreMessageFeatures features = {};
|
||||
features.maximum_major_version = 16;
|
||||
features.maximum_minor_version = 4;
|
||||
constexpr bool kForceClearKcb = true;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
license_messages.EncryptAndSignResponseWithCoreMessageFeatures(
|
||||
features, kForceClearKcb));
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages.LoadResponse());
|
||||
|
||||
KeyControlBlock block;
|
||||
size_t size = sizeof(block);
|
||||
OEMCryptoResult sts = OEMCrypto_QueryKeyControl(
|
||||
s.session_id(), license_messages.response_data().keys[0].key_id,
|
||||
license_messages.response_data().keys[0].key_id_length,
|
||||
reinterpret_cast<uint8_t*>(&block), &size);
|
||||
if (sts == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
|
||||
return;
|
||||
}
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoSessionTests,
|
||||
OEMCryptoMemoryLoadLicenseForHugeSignatureLength) {
|
||||
auto oemcrypto_function = [&](size_t signature_size) {
|
||||
|
||||
Reference in New Issue
Block a user