Source release 18.1.0

This commit is contained in:
John "Juce" Bruce
2023-06-23 15:45:08 -07:00
parent 2baa7c6e2b
commit b2c35151ad
2074 changed files with 196004 additions and 427059 deletions

View File

@@ -4,16 +4,22 @@
#include "odk.h"
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <ostream>
#include <string>
#include <vector>
#include "OEMCryptoCENCCommon.h"
#include "core_message_deserialize.h"
#include "core_message_features.h"
#include "core_message_serialize.h"
#include "core_message_serialize_proto.h"
#include "core_message_types.h"
#include "gtest/gtest.h"
#include "odk_overflow.h"
#include "odk_structs.h"
#include "odk_structs_priv.h"
#include "odk_test_helper.h"
@@ -21,11 +27,16 @@ namespace wvodk_test {
namespace {
using oemcrypto_core_message::ODK_CommonRequest;
using oemcrypto_core_message::ODK_LicenseRequest;
using oemcrypto_core_message::ODK_MessageCounter;
using oemcrypto_core_message::ODK_Provisioning40Request;
using oemcrypto_core_message::ODK_ProvisioningRequest;
using oemcrypto_core_message::ODK_RenewalRequest;
using oemcrypto_core_message::deserialize::CoreCommonRequestFromMessage;
using oemcrypto_core_message::deserialize::CoreLicenseRequestFromMessage;
using oemcrypto_core_message::deserialize::CoreProvisioning40RequestFromMessage;
using oemcrypto_core_message::deserialize::CoreProvisioningRequestFromMessage;
using oemcrypto_core_message::deserialize::CoreRenewalRequestFromMessage;
using oemcrypto_core_message::deserialize::
@@ -34,7 +45,10 @@ using oemcrypto_core_message::deserialize::
using oemcrypto_core_message::features::CoreMessageFeatures;
using oemcrypto_core_message::serialize::CreateCoreLicenseResponse;
using oemcrypto_core_message::serialize::CreateCoreProvisioning40Response;
using oemcrypto_core_message::serialize::CreateCoreProvisioningResponse;
using oemcrypto_core_message::serialize::
CreateCoreProvisioningResponseFromProto;
using oemcrypto_core_message::serialize::CreateCoreRenewalResponse;
constexpr uint32_t kExtraPayloadSize = 128u;
@@ -59,6 +73,40 @@ void PrintTo(const VersionParameters& p, std::ostream* os) {
<< p.response_minor_version;
}
void SetDefaultSerializedProvisioningResponse(std::string* serialized_message) {
// Create a dummy provisioning response
video_widevine::ProvisioningResponse provisioning_response;
provisioning_response.set_device_certificate("device_certificate");
provisioning_response.set_device_rsa_key("device_rsa_key");
provisioning_response.set_device_rsa_key_iv("device_rsa_key_iv");
if (!provisioning_response.SerializeToString(serialized_message)) {
FAIL();
}
}
bool CheckCounterInfoIsEqual(ODK_MessageCounterInfo* a, ODK_MessageCounter* b) {
if (!a || !b) return false;
EXPECT_EQ(a->master_generation_number, b->master_generation_number);
EXPECT_EQ(a->provisioning_count, b->provisioning_count);
EXPECT_EQ(a->license_count, b->license_count);
EXPECT_EQ(a->decrypt_count, b->decrypt_count);
EXPECT_EQ(a->major_version, b->major_version);
EXPECT_EQ(a->minor_version, b->minor_version);
EXPECT_EQ(a->patch_version, b->patch_version);
for (size_t i = 0; i < sizeof(a->soc_vendor); i++) {
EXPECT_EQ(a->soc_vendor[i], b->soc_vendor[i]);
}
for (size_t i = 0; i < sizeof(a->chipset_model); i++) {
EXPECT_EQ(a->chipset_model[i], b->chipset_model[i]);
}
for (size_t i = 0; i < sizeof(a->extra); i++) {
EXPECT_EQ(a->extra[i], b->extra[i]);
}
return true;
}
template <typename T, typename F, typename G>
void ValidateRequest(uint32_t message_type,
const std::vector<ODK_Field>& extra_fields,
@@ -241,13 +289,19 @@ TEST(OdkTest, NullRequestTest) {
memset(&nonce_values, 0, sizeof(nonce_values));
ODK_ClockValues clock_values;
memset(&clock_values, 0, sizeof(clock_values));
ODK_MessageCounterInfo counter_info;
memset(&counter_info, 0, sizeof(counter_info));
// Assert that nullptr does not cause a core dump.
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreLicenseRequest(
nullptr, 0uL, nullptr, &nonce_values));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_PrepareCoreLicenseRequest(nullptr, 0uL, nullptr, &nonce_values,
&counter_info));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_PrepareCoreLicenseRequest(nullptr, 0uL, &core_message_length,
nullptr));
nullptr, &counter_info));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_PrepareCoreLicenseRequest(nullptr, 0uL, &core_message_length,
&nonce_values, nullptr));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_PrepareCoreRenewalRequest(nullptr, 0uL, nullptr, &nonce_values,
@@ -261,10 +315,23 @@ TEST(OdkTest, NullRequestTest) {
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_PrepareCoreProvisioningRequest(
nullptr, 0uL, &core_message_length, nullptr, nullptr, 0uL));
nullptr, 0uL, &core_message_length, nullptr, &counter_info));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_PrepareCoreProvisioningRequest(nullptr, 0uL, nullptr,
&nonce_values, nullptr, 0uL));
&nonce_values, &counter_info));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_PrepareCoreProvisioningRequest(
nullptr, 0uL, &core_message_length, &nonce_values, nullptr));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreProvisioning40Request(
nullptr, 0uL, &core_message_length,
nullptr, nullptr, 0uL, &counter_info));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreProvisioning40Request(
nullptr, 0uL, nullptr, &nonce_values,
nullptr, 0uL, &counter_info));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, ODK_PrepareCoreProvisioning40Request(
nullptr, 0uL, &core_message_length,
&nonce_values, nullptr, 0uL, nullptr));
// Null device id in provisioning request is ok
uint8_t message[ODK_PROVISIONING_REQUEST_SIZE] = {0};
@@ -272,7 +339,16 @@ TEST(OdkTest, NullRequestTest) {
EXPECT_EQ(OEMCrypto_SUCCESS,
ODK_PrepareCoreProvisioningRequest(
message, ODK_PROVISIONING_REQUEST_SIZE, &core_message_length,
&nonce_values, nullptr, 0uL));
&nonce_values, &counter_info));
// Null device info in provisioning 4.0 request is ok
uint8_t message_prov4[ODK_PROVISIONING40_REQUEST_SIZE] = {0};
core_message_length = ODK_PROVISIONING40_REQUEST_SIZE;
EXPECT_EQ(
OEMCrypto_SUCCESS,
ODK_PrepareCoreProvisioning40Request(
message_prov4, ODK_PROVISIONING40_REQUEST_SIZE, &core_message_length,
&nonce_values, nullptr, 0uL, &counter_info));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_PrepareCoreRenewedProvisioningRequest(
@@ -316,26 +392,26 @@ TEST(OdkTest, NullResponseTest) {
memset(&clock_values, 0, sizeof(clock_values));
// Assert that nullptr does not cause a core dump.
EXPECT_EQ(
ODK_ERROR_CORE_MESSAGE,
ODK_ParseLicense(message, message_size, core_message_length, true, true,
&timer_limits, &clock_values, &nonce_values, nullptr));
EXPECT_EQ(
ODK_ERROR_CORE_MESSAGE,
ODK_ParseLicense(message, message_size, core_message_length, true, true,
&timer_limits, &clock_values, nullptr, &parsed_license));
EXPECT_EQ(
ODK_ERROR_CORE_MESSAGE,
ODK_ParseLicense(message, message_size, core_message_length, true, true,
&timer_limits, nullptr, &nonce_values, &parsed_license));
EXPECT_EQ(
ODK_ERROR_CORE_MESSAGE,
ODK_ParseLicense(message, message_size, core_message_length, true, true,
nullptr, &clock_values, &nonce_values, &parsed_license));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_ParseLicense(message, message_size, core_message_length, true,
true, 0, &timer_limits, &clock_values,
&nonce_values, nullptr, nullptr));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_ParseLicense(message, message_size, core_message_length, true,
true, 0, &timer_limits, &clock_values, nullptr,
&parsed_license, nullptr));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_ParseLicense(message, message_size, core_message_length, true,
true, 0, &timer_limits, nullptr, &nonce_values,
&parsed_license, nullptr));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_ParseLicense(message, message_size, core_message_length, true,
true, 0, nullptr, &clock_values, &nonce_values,
&parsed_license, nullptr));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_ParseLicense(nullptr, message_size, core_message_length, true,
true, &timer_limits, &clock_values, &nonce_values,
&parsed_license));
true, 0, &timer_limits, &clock_values,
&nonce_values, &parsed_license, nullptr));
constexpr uint64_t system_time = 0;
uint64_t timer_value = 0;
@@ -373,6 +449,13 @@ TEST(OdkTest, NullResponseTest) {
ODK_ParseProvisioning(nullptr, message_size, core_message_length,
&nonce_values, device_id,
ODK_DEVICE_ID_LEN_MAX, &parsed_response));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_ParseProvisioning40(message, message_size, core_message_length,
nullptr));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_ParseProvisioning40(nullptr, message_size, core_message_length,
&nonce_values));
}
TEST(OdkTest, PrepareCoreLicenseRequest) {
@@ -380,9 +463,12 @@ TEST(OdkTest, PrepareCoreLicenseRequest) {
size_t core_message_length = sizeof(license_message);
ODK_NonceValues nonce_values;
memset(&nonce_values, 0, sizeof(nonce_values));
EXPECT_EQ(OEMCrypto_SUCCESS, ODK_PrepareCoreLicenseRequest(
license_message, sizeof(license_message),
&core_message_length, &nonce_values));
ODK_MessageCounterInfo counter_info;
memset(&counter_info, 0, sizeof(counter_info));
EXPECT_EQ(OEMCrypto_SUCCESS,
ODK_PrepareCoreLicenseRequest(
license_message, sizeof(license_message), &core_message_length,
&nonce_values, &counter_info));
}
TEST(OdkTest, PrepareCoreLicenseRequestSize) {
@@ -390,18 +476,20 @@ TEST(OdkTest, PrepareCoreLicenseRequestSize) {
size_t core_message_length = sizeof(license_message);
ODK_NonceValues nonce_values;
memset(&nonce_values, 0, sizeof(nonce_values));
ODK_MessageCounterInfo counter_info;
memset(&counter_info, 0, sizeof(counter_info));
// message length smaller than core message length
size_t core_message_length_invalid = core_message_length + 1;
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_PrepareCoreLicenseRequest(
license_message, sizeof(license_message),
&core_message_length_invalid, &nonce_values));
&core_message_length_invalid, &nonce_values, &counter_info));
// message length larger than core message length
uint8_t license_message_large[ODK_LICENSE_REQUEST_SIZE * 2] = {0};
EXPECT_EQ(OEMCrypto_SUCCESS,
ODK_PrepareCoreLicenseRequest(license_message_large,
sizeof(license_message_large),
&core_message_length, &nonce_values));
ODK_PrepareCoreLicenseRequest(
license_message_large, sizeof(license_message_large),
&core_message_length, &nonce_values, &counter_info));
}
TEST(OdkTest, PrepareCoreRenewalRequest) {
@@ -446,12 +534,27 @@ TEST(OdkTest, PrepareCoreProvisioningRequest) {
size_t core_message_length = sizeof(provisioning_message);
ODK_NonceValues nonce_values;
memset(&nonce_values, 0, sizeof(nonce_values));
uint8_t device_id[ODK_DEVICE_ID_LEN_MAX] = {0};
EXPECT_EQ(
OEMCrypto_SUCCESS,
ODK_PrepareCoreProvisioningRequest(
provisioning_message, sizeof(provisioning_message),
&core_message_length, &nonce_values, device_id, sizeof(device_id)));
ODK_MessageCounterInfo counter_info;
memset(&counter_info, 0, sizeof(counter_info));
EXPECT_EQ(OEMCrypto_SUCCESS,
ODK_PrepareCoreProvisioningRequest(
provisioning_message, sizeof(provisioning_message),
&core_message_length, &nonce_values, &counter_info));
}
TEST(OdkTest, PrepareCoreProvisioning40Request) {
uint8_t provisioning_message[ODK_PROVISIONING40_REQUEST_SIZE] = {0};
size_t core_message_length = sizeof(provisioning_message);
ODK_NonceValues nonce_values;
memset(&nonce_values, 0, sizeof(nonce_values));
ODK_MessageCounterInfo counter_info;
memset(&counter_info, 0, sizeof(counter_info));
uint8_t device_info[ODK_DEVICE_INFO_LEN_MAX] = {0};
EXPECT_EQ(OEMCrypto_SUCCESS,
ODK_PrepareCoreProvisioning40Request(
provisioning_message, sizeof(provisioning_message),
&core_message_length, &nonce_values, device_info,
sizeof(device_info), &counter_info));
}
TEST(OdkTest, PrepareCoreRenewedProvisioningRequest) {
@@ -469,17 +572,19 @@ TEST(OdkTest, PrepareCoreRenewedProvisioningRequest) {
OEMCrypto_RenewalACert, renewal_data, sizeof(renewal_data)));
}
TEST(OdkTest, PrepareCoreProvisioningRequestDeviceId) {
uint8_t provisioning_message[ODK_PROVISIONING_REQUEST_SIZE] = {0};
TEST(OdkTest, PrepareCoreProvisioning40RequestDeviceInfo) {
uint8_t provisioning_message[ODK_PROVISIONING40_REQUEST_SIZE] = {0};
size_t core_message_length = sizeof(provisioning_message);
ODK_NonceValues nonce_values;
memset(&nonce_values, 0, sizeof(nonce_values));
uint8_t device_id_invalid[ODK_DEVICE_ID_LEN_MAX + 1] = {0};
ODK_MessageCounterInfo counter_info;
memset(&counter_info, 0, sizeof(counter_info));
uint8_t device_info_invalid[ODK_DEVICE_INFO_LEN_MAX + 1] = {0};
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE,
ODK_PrepareCoreProvisioningRequest(
ODK_PrepareCoreProvisioning40Request(
provisioning_message, sizeof(provisioning_message),
&core_message_length, &nonce_values, device_id_invalid,
sizeof(device_id_invalid)));
&core_message_length, &nonce_values, device_info_invalid,
sizeof(device_info_invalid), &counter_info));
}
TEST(OdkTest, PrepareCoreRenewedProvisioningRequestDeviceId) {
@@ -514,13 +619,36 @@ TEST(OdkTest, PrepareCoreRenewedProvisioningRequestRenewalDataInvalid) {
// Serialize and de-serialize license request
TEST(OdkTest, LicenseRequestRoundtrip) {
std::vector<ODK_Field> empty;
ODK_MessageCounterInfo counter_info;
counter_info.master_generation_number = 0x12345678abcdffff;
counter_info.provisioning_count = 12;
counter_info.license_count = 50;
counter_info.decrypt_count = 340;
counter_info.major_version = ODK_MAJOR_VERSION;
counter_info.minor_version = ODK_MINOR_VERSION;
counter_info.patch_version = 4;
memset(counter_info.soc_vendor, 0xff, sizeof(counter_info.soc_vendor));
memset(counter_info.chipset_model, 0xdd, sizeof(counter_info.chipset_model));
memset(counter_info.extra, 0xee, sizeof(counter_info.extra));
std::vector<ODK_Field> extra_fields = {
{ODK_MESSAGECOUNTER, &counter_info, "counter_info"},
};
auto odk_prepare_func = [&](uint8_t* const buf, size_t* size,
ODK_NonceValues* nonce_values) {
return ODK_PrepareCoreLicenseRequest(buf, SIZE_MAX, size, nonce_values);
return ODK_PrepareCoreLicenseRequest(buf, SIZE_MAX, size, nonce_values,
&counter_info);
};
auto kdo_parse_func = CoreLicenseRequestFromMessage;
ValidateRequest<ODK_LicenseRequest>(ODK_License_Request_Type, empty,
auto kdo_parse_func = [&](const std::string& oemcrypto_core_message,
ODK_LicenseRequest* core_license_request) {
bool ok = CoreLicenseRequestFromMessage(oemcrypto_core_message,
core_license_request);
if (!ok) return false;
ok = CheckCounterInfoIsEqual(&counter_info,
&core_license_request->counter_info);
return ok;
};
ValidateRequest<ODK_LicenseRequest>(ODK_License_Request_Type, extra_fields,
odk_prepare_func, kdo_parse_func);
}
@@ -550,23 +678,38 @@ TEST(OdkTest, RenewalRequestRoundtrip) {
}
TEST(OdkTest, ProvisionRequestRoundtrip) {
uint32_t device_id_length = ODK_DEVICE_ID_LEN_MAX / 2;
uint8_t device_id[ODK_DEVICE_ID_LEN_MAX] = {0};
memset(device_id, 0xff, device_id_length);
ODK_MessageCounterInfo counter_info;
counter_info.master_generation_number = 0x12345678abcdffff;
counter_info.provisioning_count = 12;
counter_info.license_count = 50;
counter_info.decrypt_count = 340;
counter_info.major_version = ODK_MAJOR_VERSION;
counter_info.minor_version = ODK_MINOR_VERSION;
counter_info.patch_version = 4;
memset(counter_info.soc_vendor, 0xff, sizeof(counter_info.soc_vendor));
memset(counter_info.chipset_model, 0xdd, sizeof(counter_info.chipset_model));
memset(counter_info.extra, 0xee, sizeof(counter_info.extra));
// Fake device_id_length for older servers, since we removed device id from
// the v18 request
uint32_t fake_device_id_length = 64;
std::vector<ODK_Field> extra_fields = {
{ODK_UINT32, &device_id_length, "device_id_length"},
{ODK_DEVICEID, device_id, "device_id"},
{ODK_UINT32, &(fake_device_id_length), "fake_device_id_length"},
{ODK_MESSAGECOUNTER, &counter_info, "counter_info"},
};
auto odk_prepare_func = [&](uint8_t* const buf, size_t* size,
const ODK_NonceValues* nonce_values) {
return ODK_PrepareCoreProvisioningRequest(buf, SIZE_MAX, size, nonce_values,
device_id, device_id_length);
&counter_info);
};
auto kdo_parse_func =
[&](const std::string& oemcrypto_core_message,
ODK_ProvisioningRequest* core_provisioning_request) {
bool ok = CoreProvisioningRequestFromMessage(oemcrypto_core_message,
core_provisioning_request);
if (!ok) return false;
ok = CheckCounterInfoIsEqual(&counter_info,
&core_provisioning_request->counter_info);
return ok;
};
ValidateRequest<ODK_ProvisioningRequest>(ODK_Provisioning_Request_Type,
@@ -574,6 +717,47 @@ TEST(OdkTest, ProvisionRequestRoundtrip) {
kdo_parse_func);
}
TEST(OdkTest, ProvisionRequest40Roundtrip) {
uint32_t device_info_length = ODK_DEVICE_INFO_LEN_MAX / 2;
uint8_t device_info[ODK_DEVICE_INFO_LEN_MAX] = {0};
memset(device_info, 0xaa, device_info_length);
ODK_MessageCounterInfo counter_info;
counter_info.master_generation_number = 0x12345678abcdffff;
counter_info.provisioning_count = 12;
counter_info.license_count = 50;
counter_info.decrypt_count = 340;
counter_info.major_version = ODK_MAJOR_VERSION;
counter_info.minor_version = ODK_MINOR_VERSION;
counter_info.patch_version = 4;
memset(counter_info.soc_vendor, 0xff, sizeof(counter_info.soc_vendor));
memset(counter_info.chipset_model, 0xdd, sizeof(counter_info.chipset_model));
memset(counter_info.extra, 0xee, sizeof(counter_info.extra));
std::vector<ODK_Field> extra_fields = {
{ODK_UINT32, &device_info_length, "device_info_length"},
{ODK_DEVICEINFO, device_info, "device_info"},
{ODK_MESSAGECOUNTER, &counter_info, "counter_info"},
};
auto odk_prepare_func = [&](uint8_t* const buf, size_t* size,
const ODK_NonceValues* nonce_values) {
return ODK_PrepareCoreProvisioning40Request(
buf, SIZE_MAX, size, nonce_values, device_info, device_info_length,
&counter_info);
};
auto kdo_parse_func =
[&](const std::string& oemcrypto_core_message,
ODK_Provisioning40Request* core_provisioning_request) {
bool ok = CoreProvisioning40RequestFromMessage(
oemcrypto_core_message, core_provisioning_request);
if (!ok) return false;
ok = CheckCounterInfoIsEqual(&counter_info,
&core_provisioning_request->counter_info);
return ok;
};
ValidateRequest<ODK_Provisioning40Request>(ODK_Provisioning40_Request_Type,
extra_fields, odk_prepare_func,
kdo_parse_func);
}
TEST(OdkTest, RenewedProvisionRequestRoundtrip) {
uint32_t device_id_length = ODK_DEVICE_ID_LEN_MAX / 2;
uint8_t device_id[ODK_DEVICE_ID_LEN_MAX] = {0};
@@ -618,9 +802,9 @@ TEST(OdkTest, ParseLicenseErrorNonce) {
params.core_message.nonce_values.nonce = 0;
OEMCryptoResult err = ODK_ParseLicense(
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
params.usage_entry_present, &(params.timer_limits),
params.usage_entry_present, 0, &(params.timer_limits),
&(params.clock_values), &(params.core_message.nonce_values),
&(params.parsed_license));
&(params.parsed_license), nullptr);
EXPECT_EQ(OEMCrypto_ERROR_INVALID_NONCE, err);
delete[] buf;
}
@@ -635,9 +819,9 @@ TEST(OdkTest, ParseLicenseErrorUsageEntry) {
params.usage_entry_present = false;
OEMCryptoResult err = ODK_ParseLicense(
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
params.usage_entry_present, &(params.timer_limits),
params.usage_entry_present, 0, &(params.timer_limits),
&(params.clock_values), &(params.core_message.nonce_values),
&(params.parsed_license));
&(params.parsed_license), nullptr);
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, err);
delete[] buf;
}
@@ -653,9 +837,9 @@ TEST(OdkTest, ParseLicenseNullSubstring) {
&buf_size);
OEMCryptoResult result = ODK_ParseLicense(
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
params.usage_entry_present, &(params.timer_limits),
params.usage_entry_present, 0, &(params.timer_limits),
&(params.clock_values), &(params.core_message.nonce_values),
&(params.parsed_license));
&(params.parsed_license), nullptr);
EXPECT_EQ(OEMCrypto_SUCCESS, result);
delete[] buf;
}
@@ -671,9 +855,9 @@ TEST(OdkTest, ParseLicenseErrorSubstringOffset) {
&buf_size);
OEMCryptoResult err = ODK_ParseLicense(
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
params.usage_entry_present, &(params.timer_limits),
params.usage_entry_present, 0, &(params.timer_limits),
&(params.clock_values), &(params.core_message.nonce_values),
&(params.parsed_license));
&(params.parsed_license), nullptr);
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, err);
delete[] buf;
@@ -687,9 +871,9 @@ TEST(OdkTest, ParseLicenseErrorSubstringOffset) {
&buf_size);
err = ODK_ParseLicense(
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
params.usage_entry_present, &(params.timer_limits),
params.usage_entry_present, 0, &(params.timer_limits),
&(params.clock_values), &(params.core_message.nonce_values),
&(params.parsed_license));
&(params.parsed_license), nullptr);
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, err);
delete[] buf;
}
@@ -710,20 +894,50 @@ TEST(OdkTest, ParseRenewalErrorTimer) {
delete[] buf;
}
TEST(OdkTest, ParsePrivisioningErrorDeviceId) {
ODK_ProvisioningResponseParams params;
ODK_SetDefaultProvisioningResponseParams(&params);
uint8_t* buf = nullptr;
uint32_t buf_size = 0;
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
&buf_size);
// temporarily mess up with device_id
params.device_id[0] = 0;
OEMCryptoResult err = ODK_ParseProvisioning(
buf, buf_size + 16, buf_size, &(params.core_message.nonce_values),
params.device_id, params.device_id_length, &(params.parsed_provisioning));
EXPECT_EQ(ODK_ERROR_CORE_MESSAGE, err);
delete[] buf;
TEST(OdkTest, ProvisionResponseFromProto) {
std::string serialized_provisioning_resp;
EXPECT_NO_FATAL_FAILURE(
SetDefaultSerializedProvisioningResponse(&serialized_provisioning_resp));
ODK_ProvisioningRequest core_request = {
.api_minor_version = ODK_MINOR_VERSION,
.api_major_version = ODK_MAJOR_VERSION,
.nonce = 0xdeadbeef,
.session_id = 0xcafebabe,
};
const CoreMessageFeatures features =
CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION);
std::string oemcrypto_core_message;
EXPECT_TRUE(CreateCoreProvisioningResponseFromProto(
features, serialized_provisioning_resp, core_request,
OEMCrypto_RSA_Private_Key, &oemcrypto_core_message));
}
// Verify de-serialize common request.
TEST(OdkTest, ParseCoreCommonRequestFromMessage) {
std::string serialized_provisioning_resp;
EXPECT_NO_FATAL_FAILURE(
SetDefaultSerializedProvisioningResponse(&serialized_provisioning_resp));
ODK_ProvisioningRequest core_request = {
.api_minor_version = ODK_MINOR_VERSION,
.api_major_version = ODK_MAJOR_VERSION,
.nonce = 0xdeadbeef,
.session_id = 0xcafebabe,
};
const CoreMessageFeatures features =
CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION);
std::string oemcrypto_core_message;
EXPECT_TRUE(CreateCoreProvisioningResponseFromProto(
features, serialized_provisioning_resp, core_request,
OEMCrypto_RSA_Private_Key, &oemcrypto_core_message));
ODK_CommonRequest odk_common_request;
ASSERT_TRUE(CoreCommonRequestFromMessage(oemcrypto_core_message,
&odk_common_request));
EXPECT_EQ(odk_common_request.message_type, 6u);
EXPECT_EQ(odk_common_request.message_length, 48u);
EXPECT_EQ(odk_common_request.api_minor_version, ODK_MINOR_VERSION);
EXPECT_EQ(odk_common_request.api_major_version, ODK_MAJOR_VERSION);
EXPECT_EQ(odk_common_request.nonce, 0xdeadbeef);
EXPECT_EQ(odk_common_request.session_id, 0xcafebabe);
}
class OdkVersionTest : public ::testing::Test,
@@ -735,8 +949,12 @@ class OdkVersionTest : public ::testing::Test,
GetParam().response_major_version;
params->core_message.nonce_values.api_minor_version =
GetParam().response_minor_version;
features_ =
CoreMessageFeatures::DefaultFeatures(GetParam().maximum_major_version);
if (GetParam().maximum_major_version > 0) {
features_ = CoreMessageFeatures::DefaultFeatures(
GetParam().maximum_major_version);
} else {
features_ = CoreMessageFeatures::kDefaultFeatures;
}
}
CoreMessageFeatures features_;
};
@@ -756,17 +974,36 @@ TEST_P(OdkVersionTest, LicenseResponseRoundtrip) {
auto odk_parse_func = [&](const uint8_t* buf, size_t size) {
return ODK_ParseLicense(
buf, size + kExtraPayloadSize, size, params.initial_license_load,
params.usage_entry_present, &(params.timer_limits),
params.usage_entry_present, 0, &(params.timer_limits),
&(params.clock_values), &(params.core_message.nonce_values),
&(params.parsed_license));
&(params.parsed_license), nullptr);
};
ODK_Packing_ParsedLicense parsed_license;
parsed_license.enc_mac_keys_iv = params.parsed_license.enc_mac_keys_iv;
parsed_license.enc_mac_keys = params.parsed_license.enc_mac_keys;
parsed_license.pst = params.parsed_license.pst;
parsed_license.srm_restriction_data =
params.parsed_license.srm_restriction_data;
parsed_license.license_type = params.parsed_license.license_type;
parsed_license.nonce_required = params.parsed_license.nonce_required;
parsed_license.timer_limits = params.parsed_license.timer_limits;
parsed_license.watermarking = params.parsed_license.watermarking;
parsed_license.dtcp2_required = params.parsed_license.dtcp2_required;
parsed_license.renewal_delay_base = params.parsed_license.renewal_delay_base;
parsed_license.key_array_length = params.parsed_license.key_array_length;
std::vector<OEMCrypto_KeyObject> key_array;
for (size_t i = 0; i < params.parsed_license.key_array_length; i++) {
key_array.push_back(params.parsed_license.key_array[i]);
}
parsed_license.key_array = key_array.data();
const std::string request_hash_string(
reinterpret_cast<const char*>(request_hash_read),
sizeof(request_hash_read));
auto kdo_prepare_func = [&](const ODK_LicenseRequest& core_request,
std::string* oemcrypto_core_message) {
return CreateCoreLicenseResponse(features_, params.parsed_license,
core_request, request_hash_string,
return CreateCoreLicenseResponse(features_, parsed_license, core_request,
request_hash_string,
oemcrypto_core_message);
};
ValidateResponse<ODK_LicenseRequest>(GetParam(), &(params.core_message),
@@ -774,6 +1011,84 @@ TEST_P(OdkVersionTest, LicenseResponseRoundtrip) {
kdo_prepare_func);
}
// Serialize and de-serialize license response with more keys than
// ODK_MAX_NUM_KEYS.
TEST_P(OdkVersionTest, LicenseResponseRoundtripMoreThanMaxKeys) {
ODK_LicenseResponseParams params;
ODK_SetDefaultLicenseResponseParams(&params,
GetParam().response_major_version);
SetRequestVersion(&params);
// For v17, we do not use the hash to verify the request. However, the server
// needs to be backwards compatible, so it still needs to pass the hash into
// CreateCoreLiceseseResponse below. Save a copy of params.request_hash as it
// will be zero out during the test
uint8_t request_hash_read[ODK_SHA256_HASH_SIZE];
memcpy(request_hash_read, params.request_hash, sizeof(request_hash_read));
uint8_t* buf = nullptr;
uint32_t buf_size = 0;
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
&buf_size);
uint8_t* zero = new uint8_t[buf_size]{};
size_t bytes_read = 0;
// zero-out input
EXPECT_EQ(OEMCrypto_SUCCESS,
ODK_IterFields(ODK_READ, zero, buf_size, &bytes_read,
params.extra_fields));
// Parse buf with odk
const OEMCryptoResult parse_result = ODK_ParseLicense(
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
params.usage_entry_present, 0, &(params.timer_limits),
&(params.clock_values), &(params.core_message.nonce_values),
&(params.parsed_license), nullptr);
EXPECT_EQ(OEMCrypto_SUCCESS, parse_result);
size_t size_out = 0;
if (parse_result != OEMCrypto_SUCCESS) {
ODK_IterFields(ODK_FieldMode::ODK_DUMP, buf, buf_size, &size_out,
params.extra_fields);
}
ODK_Packing_ParsedLicense parsed_license;
parsed_license.enc_mac_keys_iv = params.parsed_license.enc_mac_keys_iv;
parsed_license.enc_mac_keys = params.parsed_license.enc_mac_keys;
parsed_license.pst = params.parsed_license.pst;
parsed_license.srm_restriction_data =
params.parsed_license.srm_restriction_data;
parsed_license.license_type = params.parsed_license.license_type;
parsed_license.nonce_required = params.parsed_license.nonce_required;
parsed_license.timer_limits = params.parsed_license.timer_limits;
parsed_license.watermarking = params.parsed_license.watermarking;
parsed_license.dtcp2_required = params.parsed_license.dtcp2_required;
parsed_license.renewal_delay_base = params.parsed_license.renewal_delay_base;
parsed_license.key_array_length = ODK_MAX_NUM_KEYS + 1;
std::vector<OEMCrypto_KeyObject> key_array;
for (size_t i = 0; i < ODK_MAX_NUM_KEYS + 1; i++) {
OEMCrypto_KeyObject key = {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}};
key_array.push_back(key);
}
parsed_license.key_array = key_array.data();
const std::string request_hash_string(
reinterpret_cast<const char*>(request_hash_read),
sizeof(request_hash_read));
// serialize odk output to oemcrypto_core_message
std::string oemcrypto_core_message;
ODK_LicenseRequest core_request = {};
core_request.api_major_version = GetParam().request_major_version;
core_request.api_minor_version = GetParam().request_minor_version;
core_request.nonce = params.core_message.nonce_values.nonce;
core_request.session_id = params.core_message.nonce_values.session_id;
bool result =
CreateCoreLicenseResponse(features_, parsed_license, core_request,
request_hash_string, &oemcrypto_core_message);
EXPECT_FALSE(result);
delete[] buf;
delete[] zero;
}
TEST_P(OdkVersionTest, RenewalResponseRoundtrip) {
ODK_RenewalResponseParams params;
ODK_SetDefaultRenewalResponseParams(&params);
@@ -806,7 +1121,8 @@ TEST_P(OdkVersionTest, RenewalResponseRoundtrip) {
TEST_P(OdkVersionTest, ProvisionResponseRoundtrip) {
ODK_ProvisioningResponseParams params;
ODK_SetDefaultProvisioningResponseParams(&params);
ODK_SetDefaultProvisioningResponseParams(&params,
GetParam().response_major_version);
SetRequestVersion(&params);
// save a copy of params.device_id as it will be zero out during the test
const uint32_t device_id_length = params.device_id_length;
@@ -821,8 +1137,12 @@ TEST_P(OdkVersionTest, ProvisionResponseRoundtrip) {
};
auto kdo_prepare_func = [&](ODK_ProvisioningRequest& core_request,
std::string* oemcrypto_core_message) {
// use device_id for V17 and V16
core_request.device_id.assign(reinterpret_cast<char*>(device_id),
device_id_length);
// use counter info for V18
memcpy(&core_request.counter_info, &params.counter_info,
sizeof(params.counter_info));
return CreateCoreProvisioningResponse(features_, params.parsed_provisioning,
core_request, oemcrypto_core_message);
};
@@ -831,12 +1151,30 @@ TEST_P(OdkVersionTest, ProvisionResponseRoundtrip) {
kdo_prepare_func);
}
TEST_P(OdkVersionTest, Provision40ResponseRoundtrip) {
ODK_Provisioning40ResponseParams params;
ODK_SetDefaultProvisioning40ResponseParams(&params);
SetRequestVersion(&params);
auto odk_parse_func = [&](const uint8_t* buf, size_t size) {
OEMCryptoResult err = ODK_ParseProvisioning40(
buf, size + 16, size, &(params.core_message.nonce_values));
return err;
};
auto kdo_prepare_func = [&](ODK_Provisioning40Request& core_request,
std::string* oemcrypto_core_message) {
return CreateCoreProvisioning40Response(features_, core_request,
oemcrypto_core_message);
};
ValidateResponse<ODK_Provisioning40Request>(
GetParam(), &(params.core_message), params.extra_fields, odk_parse_func,
kdo_prepare_func);
}
// If the minor version is positive, we can test an older minor version.
const uint16_t kOldMinor = ODK_MINOR_VERSION > 0 ? ODK_MINOR_VERSION - 1 : 0;
// Similarly, if this isn't the first major version, we can test an older major
// version.
// TODO(b/163416999): Remove it in the future. This will be unecessarily
// complicated after we upgrade to version 17.
const uint16_t kOldMajor = ODK_MAJOR_VERSION > ODK_FIRST_VERSION
? ODK_MAJOR_VERSION - 1
: ODK_FIRST_VERSION;
@@ -862,17 +1200,25 @@ std::vector<VersionParameters> TestCases() {
{ODK_MAJOR_VERSION, kOldMajor, kOldMajorMinor, kOldMajor, kOldMajorMinor},
// If the server is restricted to v16, then the response can be at
// most 16.5
// These tests cases must be updated whenever we roll the minor version
// number.
{16, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 16, 5},
{17, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 17, 2},
{18, ODK_MAJOR_VERSION, ODK_MINOR_VERSION, 18, 2},
// Here are some known good versions. Make extra sure they work.
{16, 16, 3, 16, 3},
{16, 16, 4, 16, 4},
{16, 16, 5, 16, 5},
{17, 16, 3, 16, 3},
{17, 16, 4, 16, 4},
{17, 16, 5, 16, 5},
{17, 17, 0, 17, 0},
{17, 17, 1, 17, 1},
{17, 17, 2, 17, 2},
{ODK_MAJOR_VERSION, 16, 3, 16, 3},
{ODK_MAJOR_VERSION, 16, 4, 16, 4},
{ODK_MAJOR_VERSION, 16, 5, 16, 5},
{ODK_MAJOR_VERSION, 17, 1, 17, 1},
{ODK_MAJOR_VERSION, 17, 2, 17, 2},
{ODK_MAJOR_VERSION, 18, 1, 18, 1},
{ODK_MAJOR_VERSION, 18, 2, 18, 2},
{0, 16, 3, 16, 3},
{0, 16, 4, 16, 4},
{0, 16, 5, 16, 5},
{0, 17, 1, 17, 1},
{0, 17, 2, 17, 2},
{0, 18, 2, 18, 2}, // Change to 19 when the default version is updated.
};
return test_cases;
}
@@ -888,11 +1234,14 @@ TEST(OdkSizeTest, LicenseRequest) {
uint16_t api_major_version = 0;
uint32_t nonce = 0;
uint32_t session_id = 0;
ODK_MessageCounterInfo counter_info;
memset(&counter_info, 0, sizeof(counter_info));
ODK_NonceValues nonce_values{api_minor_version, api_major_version, nonce,
session_id};
EXPECT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
ODK_PrepareCoreLicenseRequest(message, message_length,
&core_message_length, &nonce_values));
&core_message_length, &nonce_values,
&counter_info));
// the core_message_length should be appropriately set
EXPECT_EQ(ODK_LICENSE_REQUEST_SIZE, core_message_length);
}
@@ -949,13 +1298,14 @@ TEST(OdkSizeTest, ProvisioningRequest) {
uint16_t api_major_version = 0;
uint32_t nonce = 0;
uint32_t session_id = 0;
uint32_t device_id_length = 0;
ODK_MessageCounterInfo counter_info;
memset(&counter_info, 0, sizeof(counter_info));
ODK_NonceValues nonce_values{api_minor_version, api_major_version, nonce,
session_id};
EXPECT_EQ(OEMCrypto_ERROR_SHORT_BUFFER,
ODK_PrepareCoreProvisioningRequest(
message, message_length, &core_message_length, &nonce_values,
nullptr, device_id_length));
ODK_PrepareCoreProvisioningRequest(message, message_length,
&core_message_length,
&nonce_values, &counter_info));
// the core_message_length should be appropriately set
EXPECT_EQ(ODK_PROVISIONING_REQUEST_SIZE, core_message_length);
}
@@ -971,6 +1321,37 @@ TEST(OdkTest, CheckReleaseVersion) {
<< "Version mismatch in odk_structs.h";
}
TEST(OdkOverflowTest, SubtractU64) {
uint64_t result = 0;
EXPECT_FALSE(odk_sub_overflow_u64(10, 5, &result));
EXPECT_EQ(result, static_cast<uint64_t>(10 - 5));
EXPECT_TRUE(odk_sub_overflow_u64(5, 10, &result));
}
TEST(OdkOverflowTest, AddU64) {
uint64_t result = 0;
EXPECT_FALSE(odk_add_overflow_u64(2, 2, &result));
EXPECT_EQ(result, static_cast<uint64_t>(2 + 2));
EXPECT_TRUE(odk_add_overflow_u64(0xffffffffffffffff, 1, &result));
EXPECT_TRUE(odk_add_overflow_u64(1, 0xffffffffffffffff, &result));
}
TEST(OdkOverflowTest, AddUX) {
size_t result = 0;
EXPECT_FALSE(odk_add_overflow_ux(2, 2, &result));
EXPECT_EQ(result, static_cast<uint64_t>(2 + 2));
EXPECT_TRUE(odk_add_overflow_ux(SIZE_MAX, 1, &result));
EXPECT_TRUE(odk_add_overflow_ux(1, SIZE_MAX, &result));
}
TEST(OdkOverflowTest, MultiplyUX) {
size_t result = 0;
EXPECT_FALSE(odk_mul_overflow_ux(2, 7, &result));
EXPECT_EQ(result, static_cast<uint64_t>(2 * 7));
EXPECT_TRUE(odk_mul_overflow_ux(SIZE_MAX >> 1, 4, &result));
EXPECT_TRUE(odk_mul_overflow_ux(4, SIZE_MAX >> 1, &result));
}
} // namespace
} // namespace wvodk_test