Source release 19.6.0

GitOrigin-RevId: 13a33e34413c19da1bfe76abcc66be519c9ac9d1
This commit is contained in:
Googler
2025-05-30 14:47:25 -07:00
committed by mattfedd
parent f7ec4fdeff
commit 6d36a0c93d
59 changed files with 3327 additions and 1491 deletions

View File

@@ -450,3 +450,11 @@ OEMCryptoResult _oecc157(OEMCrypto_SESSION session, uint8_t* wrapped_pvr_key,
OEMCryptoResult _oecc158(OEMCrypto_SESSION session,
const uint8_t* wrapped_pvr_key,
size_t wrapped_pvr_key_length);
// OEMCrypto_LoadLicenseData defined in v19.6
OEMCryptoResult _oecc159(OEMCrypto_SESSION session, const uint8_t* data,
size_t data_length);
// OEMCrypto_SaveLicenseData defined in v19.6
OEMCryptoResult _oecc160(OEMCrypto_SESSION session, uint8_t* data,
size_t* data_length);

View File

@@ -7,13 +7,13 @@ namespace {
void OpenOEMCryptoTASession() {
uint8_t request_body[] = {
0x06, // TAG_UINT32
0x07, // TAG_UINT32
0x09, 0x00, 0x00, 0x00, // API value (0x09)
0x07, // TAG_UINT64
0x08, // TAG_UINT64
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Timestamp
0x01, // TAG_BOOL
0x00, // value (false)
0x0a // TAG_EOM
0x0b // TAG_EOM
};
ODK_Message request = ODK_Message_Create(request_body, sizeof(request_body));
ODK_Message_SetSize(&request, sizeof(request_body));
@@ -23,11 +23,11 @@ void OpenOEMCryptoTASession() {
void InitializeOEMCryptoTA() {
uint8_t request_body[] = {
0x06, // TAG_UINT32
0x07, // TAG_UINT32
0x01, 0x00, 0x00, 0x00, // API value (0x01)
0x07, // TAG_UINT64
0x08, // TAG_UINT64
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Timestamp
0x0a // TAG_EOM
0x0b // TAG_EOM
};
ODK_Message request = ODK_Message_Create(request_body, sizeof(request_body));
ODK_Message_SetSize(&request, sizeof(request_body));

View File

@@ -42,12 +42,8 @@
{
'target_name': 'oemcrypto_opk_dispatcher_fuzz',
'include_dirs': [
'<(oemcrypto_dir)/opk/serialization/common',
'<(oemcrypto_dir)/opk/serialization/common/include',
'<(oemcrypto_dir)/opk/serialization/os_interfaces',
'<(oemcrypto_dir)/opk/serialization/tee',
'<(oemcrypto_dir)/opk/serialization/tee/include',
'<(oemcrypto_dir)/opk/ports/trusty/include/',
],
'dependencies': [
'<(oemcrypto_dir)/opk/serialization/tee/tee.gyp:opk_tee',
@@ -55,9 +51,9 @@
'sources': [
'oemcrypto_opk_dispatcher_fuzz.cc',
'<(oemcrypto_dir)/opk/serialization/test/tos_secure_buffers.c',
'<(oemcrypto_dir)/opk/serialization/test/tos_transport_interface.c',
'<(oemcrypto_dir)/opk/serialization/test/tos_logging.c',
'<(oemcrypto_dir)/opk/ports/trusty/serialization_adapter/shared_memory.c',
'<(oemcrypto_dir)/opk/serialization/test/tos_shared_memory.c',
'<(oemcrypto_dir)/opk/serialization/test/tos_transport_interface.c',
],
},
{

View File

@@ -1796,7 +1796,11 @@ void Session::close() {
void Session::GenerateNonce(int* error_counter) {
// We make one attempt. If it fails, we assume there was a nonce flood.
if (OEMCrypto_SUCCESS == OEMCrypto_GenerateNonce(session_id(), &nonce_)) {
// Using |temp_nonce| to avoid member |nonce_| being modified
// during failure.
uint32_t temp_nonce = 0;
if (OEMCrypto_SUCCESS == OEMCrypto_GenerateNonce(session_id(), &temp_nonce)) {
nonce_ = temp_nonce;
return;
}
if (error_counter) {
@@ -1806,7 +1810,8 @@ void Session::GenerateNonce(int* error_counter) {
// The following is after a 1 second pause, so it cannot be from a nonce
// flood.
ASSERT_EQ(OEMCrypto_SUCCESS,
OEMCrypto_GenerateNonce(session_id(), &nonce_));
OEMCrypto_GenerateNonce(session_id(), &temp_nonce));
nonce_ = temp_nonce;
}
}

View File

@@ -317,14 +317,14 @@ TEST_F(OEMCryptoClientTest, FreeUnallocatedSecureBufferNoFailure) {
*/
TEST_F(OEMCryptoClientTest, VersionNumber) {
const std::string log_message =
"OEMCrypto unit tests for API 19.5. Tests last updated 2025-03-11";
"OEMCrypto unit tests for API 19.6. Tests last updated 2025-06-03";
cout << " " << log_message << "\n";
cout << " " << "These tests are part of Android V." << "\n";
LOGI("%s", log_message.c_str());
// If any of the following fail, then it is time to update the log message
// above.
EXPECT_EQ(ODK_MAJOR_VERSION, 19);
EXPECT_EQ(ODK_MINOR_VERSION, 5);
EXPECT_EQ(ODK_MINOR_VERSION, 6);
EXPECT_EQ(kCurrentAPI, static_cast<unsigned>(ODK_MAJOR_VERSION));
RecordWvProperty("test_major_version", std::to_string(ODK_MAJOR_VERSION));
RecordWvProperty("test_minor_version", std::to_string(ODK_MINOR_VERSION));
@@ -498,45 +498,58 @@ TEST_F(OEMCryptoClientTest, CheckBuildInformation_OutputLengthAPI17) {
ASSERT_GT(build_info_length, kZero)
<< "Signaling ERROR_SHORT_BUFFER should have assigned a length";
// Try again using the size they provided, ensuring that it
// is successful.
const size_t initial_estimate_length = build_info_length;
build_info.assign(build_info_length, kNullChar);
result = OEMCrypto_BuildInformation(&build_info[0], &build_info_length);
ASSERT_EQ(result, OEMCrypto_SUCCESS)
<< "initial_estimate_length = " << initial_estimate_length
<< ", build_info_length (output) = " << build_info_length;
ASSERT_GT(build_info_length, kZero) << "Build info cannot be empty";
// Ensure the real length is within the size originally specified.
// OK if final length is smaller than estimated length.
ASSERT_LE(build_info_length, initial_estimate_length);
const size_t expected_length = build_info_length;
// Force a ERROR_SHORT_BUFFER using a non-zero value.
// Note: It is assumed that vendors will provide more than a single
// character of info.
const size_t second_attempt_length =
(build_info_length >= 2) ? build_info_length / 2 : 1;
build_info.assign(second_attempt_length, kNullChar);
const size_t short_length = (expected_length >= 2) ? expected_length / 2 : 1;
build_info.assign(short_length, kNullChar);
build_info_length = build_info.size();
result = OEMCrypto_BuildInformation(&build_info[0], &build_info_length);
ASSERT_EQ(result, OEMCrypto_ERROR_SHORT_BUFFER)
<< "second_attempt_length = " << second_attempt_length
<< ", build_info_length" << build_info_length;
<< "short_length = " << short_length
<< ", expected_length = " << expected_length << ", build_info_length"
<< build_info_length;
// OEM specified build info length should be larger than the
// original length if returning ERROR_SHORT_BUFFER.
ASSERT_GT(build_info_length, second_attempt_length);
ASSERT_GT(build_info_length, short_length);
// Final attempt with a buffer large enough buffer, padding to
// ensure the caller truncates.
constexpr size_t kBufferPadSize = 42;
const size_t expected_length = build_info_length;
const size_t final_attempt_length = expected_length + kBufferPadSize;
build_info.assign(final_attempt_length, kNullChar);
const size_t oversize_length = expected_length + kBufferPadSize;
build_info.assign(oversize_length, kNullChar);
build_info_length = build_info.size();
result = OEMCrypto_BuildInformation(&build_info[0], &build_info_length);
ASSERT_EQ(result, OEMCrypto_SUCCESS)
<< "final_attempt_length = " << final_attempt_length
<< "oversize_length = " << oversize_length
<< ", expected_length = " << expected_length
<< ", build_info_length = " << build_info_length;
<< ", build_info_length (output) = " << build_info_length;
// Ensure not empty.
ASSERT_GT(build_info_length, kZero) << "Build info cannot be empty";
// Ensure it was truncated down from the padded length.
ASSERT_LT(build_info_length, final_attempt_length)
ASSERT_LT(build_info_length, oversize_length)
<< "Should have truncated from oversized buffer: expected_length = "
<< expected_length;
// Ensure the real length is within the size originally specified.
// OK if final length is smaller than estimated length.
ASSERT_LE(build_info_length, expected_length);
// Ensure that length is equal to the length of the previous
// successful call.
ASSERT_EQ(build_info_length, expected_length);
}
// Verifies that OEMCrypto_BuildInformation() is behaving as expected
@@ -680,7 +693,7 @@ TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) {
// Whether this was built with FACTORY_MODE_ONLY defined
{"is_factory_mode", JSMN_PRIMITIVE},
// ... provide information about liboemcrypto.so
// Special case, see kOptionalReeFields for details.
// Special case, see kReeOptionalFields for details.
{kSpecialCaseReeKey, JSMN_OBJECT},
// Technically required, but several implementations
// do not implement this fields.
@@ -778,7 +791,7 @@ TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) {
// The optional field "ree", if present, must follow the required
// format.
const std::map<std::string, jsmntype_t> kReeRequiredFields = {
const std::map<std::string, jsmntype_t> kReeOptionalFields = {
// liboemcrypto.so version in string format eg "2.15.0+tag"
{"liboemcrypto_ver", JSMN_STRING},
// git hash of code that compiled liboemcrypto.so
@@ -786,7 +799,6 @@ TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) {
// ISO 8601 timestamp for when liboemcrypto.so was built
{"build_timestamp", JSMN_STRING}};
found_required_fields.clear();
for (int32_t i = 0; (i + 1) < static_cast<int32_t>(ree_tokens.size());
i += 2) {
const jsmntok_t& key_token = ree_tokens[i];
@@ -796,11 +808,10 @@ TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) {
const std::string key =
build_info.substr(key_token.start, key_token.end - key_token.start);
if (kReeRequiredFields.find(key) != kReeRequiredFields.end()) {
ASSERT_EQ(value_token.type, kReeRequiredFields.at(key))
if (kReeOptionalFields.find(key) != kReeOptionalFields.end()) {
ASSERT_EQ(value_token.type, kReeOptionalFields.at(key))
<< "Unexpected optional REE field type: ree_field = " << key
<< ", build_info = " << build_info;
found_required_fields.insert(key);
RecordWvProperty(kReeBuildInfoRecordPrefix + key,
build_info.substr(value_token.start,
value_token.end - value_token.start));
@@ -810,25 +821,6 @@ TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) {
i += JsmnAncestorCount(ree_tokens, i + 1);
}
// Step 4b: Ensure all required fields of the "ree" object were found.
if (found_required_fields.size() == kReeRequiredFields.size()) return;
// Generate a list of all the missing REE fields.
std::string missing_ree_fields;
for (const auto& required_field : kReeRequiredFields) {
if (found_required_fields.find(required_field.first) !=
found_required_fields.end())
continue;
if (!missing_ree_fields.empty()) {
missing_ree_fields.append(", ");
}
missing_ree_fields.push_back('"');
missing_ree_fields.append(required_field.first);
missing_ree_fields.push_back('"');
}
FAIL() << "REE info JSON object does not contain all required keys; "
<< "missing_ree_fields = [" << missing_ree_fields
<< "], build_info = " << build_info;
}
TEST_F(OEMCryptoClientTest, CheckMaxNumberOfSessionsAPI10) {

View File

@@ -9,7 +9,9 @@
namespace wvoec {
namespace {
bool g_generate_corpus;
}
void AppendToFile(const std::string& file_name, const char* message,
const size_t message_size) {

View File

@@ -604,11 +604,13 @@ TEST_P(OEMCryptoSessionTestsDecryptTests, ContinueDecryptionAfterIdleAndWake) {
ASSERT_NO_FATAL_FAILURE(TestDecryptCENC());
}
namespace {
// Used to construct a specific pattern.
constexpr OEMCrypto_CENCEncryptPatternDesc MakePattern(size_t encrypt,
size_t skip) {
return {encrypt, skip};
}
} // namespace
INSTANTIATE_TEST_SUITE_P(
CTRTests, OEMCryptoSessionTestsDecryptTests,

View File

@@ -8,18 +8,6 @@ using namespace wvoec;
namespace wvoec {
// Make this function available when in Fuzz mode because we are not inheriting
// from OEMCryptoClientTest.
const uint8_t* find(const vector<uint8_t>& message,
const vector<uint8_t>& substring) {
vector<uint8_t>::const_iterator pos = search(
message.begin(), message.end(), substring.begin(), substring.end());
if (pos == message.end()) {
return nullptr;
}
return &(*pos);
}
void SessionUtil::CreateWrappedDRMKey() {
if (global_features.provisioning_method == OEMCrypto_BootCertificateChain) {
// Have the device create a wrapped key.