Update to ODK v18.3

This commit is contained in:
Jacob Trimble
2023-07-20 18:11:31 +00:00
parent 2bfd670424
commit 74178f968f
39 changed files with 14570 additions and 600 deletions

View File

@@ -11,6 +11,7 @@ package {
// all of the 'license_kinds' from "vendor_widevine_license"
// to get the below license kinds:
// legacy_by_exception_only (by exception only)
// legacy_proprietary (by exception only)
default_applicable_licenses: ["vendor_widevine_license"],
}

View File

@@ -18,6 +18,7 @@ package {
// all of the 'license_kinds' from "vendor_widevine_license"
// to get the below license kinds:
// legacy_by_exception_only (by exception only)
// legacy_proprietary (by exception only)
default_applicable_licenses: ["vendor_widevine_license"],
}

View File

@@ -113,15 +113,14 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
OEMCryptoResult ODK_PrepareCoreProvisioningRequest(
uint8_t* message, size_t message_length, size_t* core_message_length,
const ODK_NonceValues* nonce_values, const uint8_t* device_id,
size_t device_id_length) {
const ODK_NonceValues* nonce_values,
const ODK_MessageCounterInfo* counter_info) {
OEMCryptoResult (*original_function)(uint8_t*, size_t, size_t*,
const ODK_NonceValues*, const uint8_t*,
size_t);
const ODK_NonceValues*,
const ODK_MessageCounterInfo*);
original_function = dlsym(RTLD_NEXT, "ODK_PrepareCoreProvisioningRequest");
OEMCryptoResult oem_crypto_result =
(*original_function)(message, message_length, core_message_length,
nonce_values, device_id, device_id_length);
OEMCryptoResult oem_crypto_result = (*original_function)(
message, message_length, core_message_length, nonce_values, counter_info);
char* file_name = GetFileName("provisioning_request_corpus");
// Provisioning Request format expected by fuzzer - [Core Provisioning
@@ -134,18 +133,19 @@ OEMCryptoResult ODK_PrepareCoreProvisioningRequest(
OEMCryptoResult ODK_ParseProvisioning(
const uint8_t* message, size_t message_length, size_t core_message_length,
const ODK_NonceValues* nonce_values, const uint8_t* device_id,
size_t device_id_length, ODK_ParsedProvisioning* parsed_response) {
size_t device_id_length, ODK_MessageCounterInfo* counter_info,
ODK_ParsedProvisioning* parsed_response) {
struct ODK_ParseProvisioning_Args parse_provisioning_args;
parse_provisioning_args.nonce_values = *nonce_values;
memcpy(parse_provisioning_args.device_id, device_id, device_id_length);
parse_provisioning_args.device_id_length = device_id_length;
OEMCryptoResult (*original_function)(const uint8_t*, size_t, size_t,
const ODK_NonceValues*, const uint8_t*,
size_t, ODK_ParsedProvisioning*);
OEMCryptoResult (*original_function)(
const uint8_t*, size_t, size_t, const ODK_NonceValues*, const uint8_t*,
size_t, ODK_MessageCounterInfo*, ODK_ParsedProvisioning*);
original_function = dlsym(RTLD_NEXT, "ODK_ParseProvisioning");
OEMCryptoResult oem_crypto_result = (*original_function)(
message, message_length, core_message_length, nonce_values, device_id,
device_id_length, parsed_response);
device_id_length, counter_info, parsed_response);
char* file_name = GetFileName("provisioning_response_corpus");
// Provisioning Response format expected by fuzzer -

View File

@@ -23,7 +23,7 @@
'-Wno-error=cast-qual',
],
'cflags_cc': [
'-std=c++11',
'-std=c++14',
'-g3',
'-O0',
'-fsanitize=fuzzer,address,undefined',

View File

@@ -4,8 +4,12 @@
#include "fuzzing/odk_fuzz_helper.h"
#include <string>
#include <vector>
#include "core_message_types.h"
#include "odk.h"
#include "odk_attributes.h"
#include "odk_structs.h"
namespace oemcrypto_core_message {
using features::CoreMessageFeatures;
@@ -39,7 +43,11 @@ OEMCryptoResult odk_serialize_LicenseRequest(
const void* in UNUSED, uint8_t* out, size_t* size,
const ODK_LicenseRequest& core_license_request UNUSED,
const ODK_NonceValues* nonce_values) {
return ODK_PrepareCoreLicenseRequest(out, SIZE_MAX, size, nonce_values);
// TODO(mattfedd): hook up counters to fuzzer
const ODK_MessageCounterInfo counter_info = {0, 0, 0, 0, 0,
0, 0, {0}, {0}, {0}};
return ODK_PrepareCoreLicenseRequest(out, SIZE_MAX, size, nonce_values,
&counter_info);
}
OEMCryptoResult odk_serialize_RenewalRequest(
@@ -54,12 +62,13 @@ OEMCryptoResult odk_serialize_RenewalRequest(
OEMCryptoResult odk_serialize_ProvisioningRequest(
const void* in UNUSED, uint8_t* out, size_t* size,
const ODK_ProvisioningRequest& core_provisioning,
const ODK_ProvisioningRequest& core_provisioning UNUSED,
const ODK_NonceValues* nonce_values) {
const std::string& device_id = core_provisioning.device_id;
return ODK_PrepareCoreProvisioningRequest(
out, SIZE_MAX, size, nonce_values,
reinterpret_cast<const uint8_t*>(device_id.data()), device_id.size());
// TODO(mattfedd): hook up counters to fuzzer
const ODK_MessageCounterInfo counter_info = {0, 0, 0, 0, 0,
0, 0, {0}, {0}, {0}};
return ODK_PrepareCoreProvisioningRequest(out, SIZE_MAX, size, nonce_values,
&counter_info);
}
OEMCryptoResult odk_deserialize_LicenseResponse(const uint8_t* message,
@@ -69,9 +78,9 @@ OEMCryptoResult odk_deserialize_LicenseResponse(const uint8_t* message,
ODK_ParsedLicense* parsed_lic) {
return ODK_ParseLicense(message, SIZE_MAX, core_message_length,
static_cast<bool>(a->initial_license_load),
static_cast<bool>(a->usage_entry_present),
static_cast<bool>(a->usage_entry_present), 0,
&a->timer_limits, &a->clock_values, nonce_values,
parsed_lic);
parsed_lic, nullptr);
}
OEMCryptoResult odk_deserialize_RenewalResponse(
@@ -119,13 +128,32 @@ bool kdo_serialize_LicenseResponse(const ODK_ParseLicense_Args* args,
const ODK_ParsedLicense& parsed_lic,
std::string* oemcrypto_core_message) {
const auto& nonce_values = args->nonce_values;
ODK_LicenseRequest core_request{nonce_values.api_minor_version,
nonce_values.api_major_version,
nonce_values.nonce, nonce_values.session_id};
const ODK_MessageCounter counter_info = {0, 0, 0, 0, 0, 0, 0, {0}, {0}, {0}};
ODK_LicenseRequest core_request{
nonce_values.api_minor_version, nonce_values.api_major_version,
nonce_values.nonce, nonce_values.session_id, counter_info};
std::string core_request_sha_256(
reinterpret_cast<const char*>(args->request_hash), ODK_SHA256_HASH_SIZE);
ODK_Packing_ParsedLicense parsed_license;
parsed_license.enc_mac_keys_iv = parsed_lic.enc_mac_keys_iv;
parsed_license.enc_mac_keys = parsed_lic.enc_mac_keys;
parsed_license.pst = parsed_lic.pst;
parsed_license.srm_restriction_data = parsed_lic.srm_restriction_data;
parsed_license.license_type = parsed_lic.license_type;
parsed_license.nonce_required = parsed_lic.nonce_required;
parsed_license.timer_limits = parsed_lic.timer_limits;
parsed_license.watermarking = parsed_lic.watermarking;
parsed_license.dtcp2_required = parsed_lic.dtcp2_required;
parsed_license.renewal_delay_base = parsed_lic.renewal_delay_base;
parsed_license.key_array_length = parsed_lic.key_array_length;
std::vector<OEMCrypto_KeyObject> key_array;
size_t i;
for (i = 0; i < parsed_lic.key_array_length; i++) {
key_array.push_back(parsed_lic.key_array[i]);
}
parsed_license.key_array = key_array.data();
return serialize::CreateCoreLicenseResponse(
CoreMessageFeatures::kDefaultFeatures, parsed_lic, core_request,
CoreMessageFeatures::kDefaultFeatures, parsed_license, core_request,
core_request_sha_256, oemcrypto_core_message);
}
@@ -151,11 +179,17 @@ bool kdo_serialize_ProvisioningResponse(
if (args->device_id_length > sizeof(args->device_id)) {
return false;
}
const ODK_MessageCounter counter_info = {0, 0, 0, 0, 0, 0, 0, {0}, {0}, {0}};
ODK_ProvisioningRequest core_request{
nonce_values.api_minor_version, nonce_values.api_major_version,
nonce_values.nonce, nonce_values.session_id,
nonce_values.api_minor_version,
nonce_values.api_major_version,
nonce_values.nonce,
nonce_values.session_id,
std::string(reinterpret_cast<const char*>(args->device_id),
args->device_id_length)};
args->device_id_length),
0,
"",
counter_info};
return serialize::CreateCoreProvisioningResponse(
CoreMessageFeatures::kDefaultFeatures, parsed_prov, core_request,
oemcrypto_core_message);

View File

@@ -2,14 +2,30 @@
// source code may only be used and distributed under the Widevine
// License Agreement.
#include <ostream>
#include <string>
#include <tuple>
#include <vector>
#include "OEMCryptoCENCCommon.h"
#include "core_message_deserialize.h"
#include "core_message_features.h"
#include "core_message_serialize_proto.h"
#include "core_message_types.h"
#include "gtest/gtest.h"
#include "odk.h"
#include "third_party/absl/strings/escaping.h"
namespace wvodk_test {
using oemcrypto_core_message::ODK_CommonRequest;
using oemcrypto_core_message::ODK_ProvisioningRequest;
using oemcrypto_core_message::deserialize::CoreCommonRequestFromMessage;
using oemcrypto_core_message::deserialize::CoreProvisioningRequestFromMessage;
using oemcrypto_core_message::features::CoreMessageFeatures;
using oemcrypto_core_message::serialize::
CreateCoreProvisioningResponseFromProto;
TEST(CoreMessageTest, RenwalRequest) {
std::string oem =
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst"
@@ -36,4 +52,145 @@ TEST(CoreMessageTest, RenwalRequest) {
char* m = reinterpret_cast<char*>(message);
VLOG(0) << absl::BytesToHexString(std::string(m, core_message_length));
}
TEST(CoreMessageTest, ParseCoreCommonRequestFromMessage) {
// Core message header format:
// message_type : 4 bytes
// message_length : 4 bytes
// minor_version : 2 bytes
// major_version : 2 bytes
// nonce : 4 bytes
// session_id : 4 bytes
const char kv16CoreMessageLicenseRequest[] =
"0000000100000014000300100000000100000001";
std::string oemcrypto_core_message =
absl::HexStringToBytes(kv16CoreMessageLicenseRequest);
ODK_CommonRequest odk_common_request;
ASSERT_TRUE(CoreCommonRequestFromMessage(oemcrypto_core_message,
&odk_common_request));
EXPECT_EQ(odk_common_request.message_type, 1);
EXPECT_EQ(odk_common_request.message_length, 20);
EXPECT_EQ(odk_common_request.api_minor_version, 3);
EXPECT_EQ(odk_common_request.api_major_version, 16);
EXPECT_EQ(odk_common_request.nonce, 1);
EXPECT_EQ(odk_common_request.session_id, 1);
}
struct TestParameters_18V0 {
std::string message;
uint16_t expected_api_minor_version;
uint16_t expected_api_major_version;
uint32_t expected_nonce;
uint32_t expected_session_id;
uint64_t expected_master_generation_number;
};
void PrintTo(const TestParameters_18V0& p, std::ostream* os) {
*os << "request = " << p.message << ", expected : {version = v"
<< p.expected_api_major_version << "." << p.expected_api_minor_version
<< ", nonce = " << p.expected_nonce
<< ", session_id = " << p.expected_session_id
<< ", master_generation_number = " << p.expected_master_generation_number
<< "}";
}
class ProvisioningRoundTripTest_18V0
: public ::testing::Test,
public ::testing::WithParamInterface<TestParameters_18V0> {};
// Make sure that the first version of the V18 provisioning request (no hidden
// 4-byte value, all 0s in message counter struct) will still parse with
// current v18 code. This test is in this file rather than odk_test.cpp
// because of the use of absl::HexStringToBytes
TEST_P(ProvisioningRoundTripTest_18V0, ProvisioningRoundtrip) {
TestParameters_18V0 tc = GetParam();
ODK_ProvisioningRequest request;
// Make sure we can parse the request
ASSERT_TRUE(CoreProvisioningRequestFromMessage(
absl::HexStringToBytes(tc.message), &request));
EXPECT_EQ(request.api_minor_version, tc.expected_api_minor_version);
EXPECT_EQ(request.api_major_version, tc.expected_api_major_version);
EXPECT_EQ(request.nonce, tc.expected_nonce);
EXPECT_EQ(request.session_id, tc.expected_session_id);
if (request.api_major_version >= 18) {
EXPECT_EQ(request.counter_info.master_generation_number,
tc.expected_master_generation_number);
}
// Make sure we can create a response from that request with the same core
// message
const CoreMessageFeatures features =
CoreMessageFeatures::DefaultFeatures(ODK_MAJOR_VERSION);
std::string serialized_provisioning_resp;
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_provisioning_resp)) {
FAIL() << "Cannot set up prov response";
}
std::string oemcrypto_core_message;
EXPECT_TRUE(CreateCoreProvisioningResponseFromProto(
features, serialized_provisioning_resp, request,
OEMCrypto_RSA_Private_Key, &oemcrypto_core_message));
// Extract core message from generated prov response and match values with
// request
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.nonce, tc.expected_nonce);
EXPECT_EQ(odk_common_request.session_id, tc.expected_session_id);
}
std::vector<TestParameters_18V0> TestCases() {
return std::vector<TestParameters_18V0>{
// Source: ODKTest ProvisionRequestRoundtrip running on v18.0 ODK checkout
{"000000050000005a00000012deadbeefcafebabe12345678abcdffff0000000c0000003"
"200000154001200000004ffffffffffffffffffffffffffffffffdddddddddddddddddd"
"ddddddddddddddeeeeeeeeeeeeeeeeeeeeeeee",
0, 18, 0xdeadbeef, 0xcafebabe, 0x12345678abcdffff},
// same as previous request, but replace counter info with all 0s
{"000000050000005a00000012deadbeefcafebabe0000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000",
0, 18, 0xdeadbeef, 0xcafebabe, 0x0},
// Source: ODKTest ProvisionRequestRoundtrip running on v17.2 ODK checkout
{"000000050000005800020011deadbeefcafebabe00000020fffffffffffffffffffffff"
"fffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000"
"0000000000000000000000000000000000",
2, 17, 0xdeadbeef, 0xcafebabe, 0x0},
// Source: ODKTest ProvisionRequestRoundtrip running on v18.2 ODK checkout
{"000000050000005e00020012deadbeefcafebabe0000004012345678abcdffff0000000"
"c0000003200000154001200020004ffffffffffffffffffffffffffffffffdddddddddd"
"ddddddddddddddddddddddeeeeeeeeeeeeeeeeeeeeeeee",
2, 18, 0xdeadbeef, 0xcafebabe, 0x12345678abcdffff},
// Source: CDM unit tests on oemcrypto-v18 internal commit 5c77383 (pre
// v18.0 -> v18.1 ODK bump)
{"000000050000005a00000012b85dfa09000000000000000000000000000000000000000"
"00000000000000000000000000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000",
0, 18, 0xb85dfa09, 0x0, 0x0},
// Same as above but non-zero counter info
{"000000050000005a00000012b85dfa09000000001000000000000001000000000000000"
"00000000000000000000000000000000000000000000000000000000000000000000000"
"00000000000000000000000000000000000000",
0, 18, 0xb85dfa09, 0x0, 0x1000000000000001},
// Source: CDM unit tests on oemcrypto-v18 internal commit fc46827a (post
// v18.0 -> v18.1 ODK bump)
{"000000050000005e000100127c8ac703000000000000004000000000000000000000000"
"00000000000000000001200010000746573740000000000000000000000007465737400"
"0000000000000000000000000000000000000000000000",
1, 18, 0x7c8ac703, 0x0, 0x0},
};
}
INSTANTIATE_TEST_SUITE_P(ProvisioningRoundTripTests_18V0,
ProvisioningRoundTripTest_18V0,
::testing::ValuesIn(TestCases()));
} // namespace wvodk_test

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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,18 +315,49 @@ 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};
core_message_length = ODK_PROVISIONING_REQUEST_SIZE;
EXPECT_EQ(OEMCrypto_SUCCESS,
ODK_PrepareCoreProvisioningRequest(
message, ODK_PROVISIONING_REQUEST_SIZE, &core_message_length,
&nonce_values, nullptr, 0uL));
if (nonce_values.api_major_version > 17) {
uint8_t message[ODK_PROVISIONING_REQUEST_SIZE] = {0};
core_message_length = ODK_PROVISIONING_REQUEST_SIZE;
EXPECT_EQ(OEMCrypto_SUCCESS,
ODK_PrepareCoreProvisioningRequest(
message, ODK_PROVISIONING_REQUEST_SIZE, &core_message_length,
&nonce_values, &counter_info));
} else {
uint8_t message[ODK_PROVISIONING_REQUEST_SIZE_V17] = {0};
core_message_length = ODK_PROVISIONING_REQUEST_SIZE_V17;
EXPECT_EQ(OEMCrypto_SUCCESS,
ODK_PrepareCoreProvisioningRequest(
message, ODK_PROVISIONING_REQUEST_SIZE_V17,
&core_message_length, &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 +401,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 +458,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 +472,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 +485,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 +543,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 +581,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 +628,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 +687,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 +726,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 +811,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 +828,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 +846,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 +864,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 +880,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;
}
@@ -701,7 +894,10 @@ TEST(OdkTest, ParseRenewalErrorTimer) {
uint32_t buf_size = 0;
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
&buf_size);
params.clock_values.time_of_renewal_request = 0;
// Set the time for the last renewal request, as seen in clock_values, to be
// after the time in the request.
// TODO: b/290249855 - This is reversed. It should be +5.
params.clock_values.time_of_renewal_request = params.playback_clock - 5;
OEMCryptoResult err = ODK_ParseRenewal(
buf, buf_size, buf_size, &(params.core_message.nonce_values),
params.system_time, &(params.timer_limits), &(params.clock_values),
@@ -710,20 +906,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 +961,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 +986,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 +1023,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 +1133,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 +1149,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 +1163,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,16 +1212,26 @@ 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, 3},
// 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},
{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},
{ODK_MAJOR_VERSION, 18, 3, 18, 3},
{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, 3, 18, 3}, // Change to 19 when the default version is updated.
};
return test_cases;
}
@@ -887,13 +1247,20 @@ 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);
if (nonce_values.api_major_version > 17) {
EXPECT_EQ(ODK_LICENSE_REQUEST_SIZE, core_message_length);
} else {
EXPECT_EQ(ODK_LICENSE_REQUEST_SIZE_V17, core_message_length);
}
}
TEST(OdkSizeTest, RenewalRequest) {
@@ -948,15 +1315,20 @@ 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);
if (nonce_values.api_major_version > 17) {
EXPECT_EQ(ODK_PROVISIONING_REQUEST_SIZE, core_message_length);
} else {
EXPECT_EQ(ODK_PROVISIONING_REQUEST_SIZE_V17, core_message_length);
}
}
// Verify the version string contains the right version numbers.
@@ -970,6 +1342,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

View File

@@ -4,6 +4,9 @@
{
'sources': [
'odk_golden_v16.cpp',
'odk_golden_v17.cpp',
'odk_golden_v18.cpp',
'odk_test.cpp',
'odk_test_helper.cpp',
'odk_test_helper.h',

View File

@@ -8,7 +8,10 @@
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <ios>
#include <iostream>
#include <ostream>
#include <string>
#include <vector>
@@ -75,6 +78,7 @@ void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params,
.length = 3,
.data = {0, 0, 0},
}},
.renewal_delay_base = OEMCrypto_License_Start,
.key_array_length = 3,
.key_array =
{
@@ -203,6 +207,11 @@ void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params,
".cmi_descriptor_data"});
}
}
if (odk_major_version >= 18) {
params->extra_fields.push_back(
{ODK_UINT32, &(params->parsed_license.renewal_delay_base),
".renewal_delay_base"});
}
params->extra_fields.push_back({ODK_UINT32,
&(params->parsed_license.key_array_length),
".key_array_length"});
@@ -288,7 +297,7 @@ void ODK_SetDefaultRenewalResponseParams(ODK_RenewalResponseParams* params) {
}
void ODK_SetDefaultProvisioningResponseParams(
ODK_ProvisioningResponseParams* params) {
ODK_ProvisioningResponseParams* params, uint32_t odk_major_version) {
ODK_SetDefaultCoreFields(&(params->core_message),
ODK_Provisioning_Response_Type);
params->device_id_length = ODK_DEVICE_ID_LEN_MAX / 2;
@@ -301,17 +310,34 @@ void ODK_SetDefaultProvisioningResponseParams(
.enc_private_key_iv = {.offset = 2, .length = 3},
.encrypted_message_key = {.offset = 4, .length = 5},
};
params->extra_fields = {
{ODK_UINT32, &(params->device_id_length), "device_id_length"},
{ODK_DEVICEID, params->device_id, "device_id"},
{ODK_UINT32, &(params->parsed_provisioning).key_type, "key_type"},
params->extra_fields = {};
// V17 uses device_id
if (odk_major_version <= 17) {
params->extra_fields.push_back(
{ODK_UINT32, &(params->device_id_length), "device_id_length"});
params->extra_fields.push_back(
{ODK_DEVICEID, params->device_id, "device_id"});
}
params->extra_fields.push_back(
{ODK_UINT32, &(params->parsed_provisioning).key_type, "key_type"});
params->extra_fields.push_back(
{ODK_SUBSTRING, &(params->parsed_provisioning).enc_private_key,
"enc_private_key"},
"enc_private_key"});
params->extra_fields.push_back(
{ODK_SUBSTRING, &(params->parsed_provisioning).enc_private_key_iv,
"enc_private_key_iv"},
"enc_private_key_iv"});
params->extra_fields.push_back(
{ODK_SUBSTRING, &(params->parsed_provisioning).encrypted_message_key,
"encrypted_message_key"},
};
"encrypted_message_key"});
}
void ODK_SetDefaultProvisioning40ResponseParams(
ODK_Provisioning40ResponseParams* params) {
ODK_SetDefaultCoreFields(&(params->core_message),
ODK_Provisioning_Response_Type);
params->extra_fields = {};
}
size_t ODK_FieldLength(ODK_FieldType type) {
@@ -330,6 +356,10 @@ size_t ODK_FieldLength(ODK_FieldType type) {
return sizeof(uint32_t) + sizeof(uint32_t);
case ODK_DEVICEID:
return ODK_DEVICE_ID_LEN_MAX;
case ODK_MESSAGECOUNTER:
return ODK_MESSAGECOUNTERINFO_SIZE;
case ODK_DEVICEINFO:
return ODK_DEVICE_INFO_LEN_MAX;
case ODK_RENEWALDATA:
return ODK_KEYBOX_RENEWAL_DATA_SIZE;
case ODK_HASH:
@@ -343,6 +373,9 @@ size_t ODK_AllocSize(ODK_FieldType type) {
if (type == ODK_SUBSTRING) {
return sizeof(OEMCrypto_Substring);
}
if (type == ODK_MESSAGECOUNTER) {
return sizeof(ODK_MessageCounterInfo);
}
return ODK_FieldLength(type);
}
@@ -388,6 +421,7 @@ OEMCryptoResult ODK_WriteSingleField(uint8_t* buf, const ODK_Field* field) {
break;
}
case ODK_DEVICEID:
case ODK_DEVICEINFO:
case ODK_RENEWALDATA:
case ODK_HASH: {
const size_t field_len = ODK_FieldLength(field->type);
@@ -396,6 +430,27 @@ OEMCryptoResult ODK_WriteSingleField(uint8_t* buf, const ODK_Field* field) {
break;
}
case ODK_MESSAGECOUNTER: {
// Size required in field->value, which may get padding from the compiler.
const size_t src_len = ODK_AllocSize(field->type);
// Size taken up in serialized message buffer, which is tightly packed.
const size_t dest_len = ODK_FieldLength(field->type);
const uint8_t* const write_src = static_cast<uint8_t*>(field->value);
// Copy data from field to buf, fixing endian-ness
ODK_MessageCounterInfo info;
memcpy(&info, write_src, src_len);
info.master_generation_number =
oemcrypto_htobe64(info.master_generation_number);
info.provisioning_count = oemcrypto_htobe32(info.provisioning_count);
info.license_count = oemcrypto_htobe32(info.license_count);
info.decrypt_count = oemcrypto_htobe32(info.decrypt_count);
info.major_version = oemcrypto_htobe16(info.major_version);
info.minor_version = oemcrypto_htobe16(info.minor_version);
info.patch_version = oemcrypto_htobe16(info.patch_version);
memcpy(buf, &info, dest_len);
break;
}
default:
return ODK_ERROR_CORE_MESSAGE;
}
@@ -448,6 +503,7 @@ OEMCryptoResult ODK_ReadSingleField(const uint8_t* buf,
break;
}
case ODK_DEVICEID:
case ODK_DEVICEINFO:
case ODK_RENEWALDATA:
case ODK_HASH: {
const size_t field_len = ODK_FieldLength(field->type);
@@ -455,6 +511,55 @@ OEMCryptoResult ODK_ReadSingleField(const uint8_t* buf,
memcpy(id, buf, field_len);
break;
}
case ODK_MESSAGECOUNTER: {
// Size required in field->value, which may get padding from the compiler.
const size_t dest_len = ODK_AllocSize(field->type);
// Size taken up in serialized message buffer, which is tightly packed.
const size_t src_len = ODK_FieldLength(field->type);
uint8_t* const read_dest = static_cast<uint8_t*>(field->value);
// Copy data from buf to field, fixing endian-ness
uint8_t temp_buf[sizeof(ODK_MessageCounterInfo)] = {0};
memcpy(temp_buf, buf, src_len);
size_t index = 0;
ODK_MessageCounterInfo info;
uint64_t* u64 = reinterpret_cast<uint64_t*>(&temp_buf[index]);
info.master_generation_number = oemcrypto_be64toh(*u64);
index += sizeof(uint64_t);
uint32_t* u32 = reinterpret_cast<uint32_t*>(&temp_buf[index]);
info.provisioning_count = oemcrypto_be32toh(*u32);
index += sizeof(uint32_t);
u32 = reinterpret_cast<uint32_t*>(&temp_buf[index]);
info.license_count = oemcrypto_be32toh(*u32);
index += sizeof(uint32_t);
u32 = reinterpret_cast<uint32_t*>(&temp_buf[index]);
info.decrypt_count = oemcrypto_be32toh(*u32);
index += sizeof(uint32_t);
uint16_t* u16 = reinterpret_cast<uint16_t*>(&temp_buf[index]);
info.major_version = oemcrypto_be16toh(*u16);
index += sizeof(uint16_t);
u16 = reinterpret_cast<uint16_t*>(&temp_buf[index]);
info.minor_version = oemcrypto_be16toh(*u16);
index += sizeof(uint16_t);
u16 = reinterpret_cast<uint16_t*>(&temp_buf[index]);
info.patch_version = oemcrypto_be16toh(*u16);
index += sizeof(uint16_t);
memcpy(info.soc_vendor, &temp_buf[index], sizeof(info.soc_vendor));
index += sizeof(info.soc_vendor);
memcpy(info.chipset_model, &temp_buf[index], sizeof(info.chipset_model));
index += sizeof(info.chipset_model);
memcpy(info.extra, &temp_buf[index], sizeof(info.extra));
memcpy(read_dest, &info, dest_len);
break;
}
default:
return ODK_ERROR_CORE_MESSAGE;
}
@@ -508,6 +613,8 @@ OEMCryptoResult ODK_DumpSingleField(const uint8_t* buf,
break;
}
case ODK_DEVICEID:
case ODK_MESSAGECOUNTER:
case ODK_DEVICEINFO:
case ODK_RENEWALDATA:
case ODK_HASH: {
const size_t field_len = ODK_FieldLength(field->type);

View File

@@ -21,6 +21,8 @@ enum ODK_FieldType {
ODK_UINT64,
ODK_SUBSTRING,
ODK_DEVICEID,
ODK_DEVICEINFO,
ODK_MESSAGECOUNTER,
ODK_RENEWALDATA,
ODK_HASH,
// The "stressable" types are the ones we can put in a stress test that packs
@@ -71,10 +73,17 @@ struct ODK_ProvisioningResponseParams {
ODK_CoreMessage core_message;
uint8_t device_id[ODK_DEVICE_ID_LEN_MAX];
uint32_t device_id_length;
uint32_t padding_u32;
ODK_MessageCounterInfo counter_info;
ODK_ParsedProvisioning parsed_provisioning;
std::vector<ODK_Field> extra_fields;
};
struct ODK_Provisioning40ResponseParams {
ODK_CoreMessage core_message;
std::vector<ODK_Field> extra_fields;
};
// Default values in core_message for testing
void ODK_SetDefaultCoreFields(ODK_CoreMessage* core_message,
ODK_MessageType message_type);
@@ -82,7 +91,9 @@ void ODK_SetDefaultLicenseResponseParams(ODK_LicenseResponseParams* params,
uint32_t odk_major_version);
void ODK_SetDefaultRenewalResponseParams(ODK_RenewalResponseParams* params);
void ODK_SetDefaultProvisioningResponseParams(
ODK_ProvisioningResponseParams* params);
ODK_ProvisioningResponseParams* params, uint32_t odk_major_version);
void ODK_SetDefaultProvisioning40ResponseParams(
ODK_Provisioning40ResponseParams* params);
size_t ODK_FieldLength(ODK_FieldType type);
size_t ODK_AllocSize(ODK_FieldType type);
@@ -92,8 +103,8 @@ OEMCryptoResult ODK_WriteSingleField(uint8_t* buf, const ODK_Field* field);
// Load buf to ODK_Field
OEMCryptoResult ODK_ReadSingleField(const uint8_t* buf, const ODK_Field* field);
OEMCryptoResult ODK_DumpSingleField(const uint8_t* buf, const ODK_Field* field);
OEMCryptoResult ODK_IterFields(ODK_FieldMode mode, uint8_t* buf,
const size_t size_in, size_t* size_out,
OEMCryptoResult ODK_IterFields(ODK_FieldMode mode, uint8_t* buf, size_t size_in,
size_t* size_out,
const std::vector<ODK_Field>& fields);
void ODK_ExpectEqualBuf(const void* s1, const void* s2, size_t n,
const std::vector<ODK_Field>& fields);

View File

@@ -6,7 +6,9 @@
#include "OEMCryptoCENCCommon.h"
#include "gtest/gtest.h"
#include "odk.h"
#include "odk_structs.h"
#include "odk_structs_priv.h"
#include "odk_test_helper.h"
namespace {
@@ -23,6 +25,99 @@ constexpr uint64_t kRentalClockStart = 1000u;
// renewal is not loaded.
constexpr uint64_t kGracePeriod = 5u;
constexpr uint32_t kExtraPayloadSize = 128u;
constexpr uint32_t kSystemTime = 20u;
namespace wvodk_test {
TEST(OdkTimerBasicTest, ParseLicenseTimerSet) {
// playback timer is successfully started
::wvodk_test::ODK_LicenseResponseParams params;
ODK_SetDefaultLicenseResponseParams(&params, ODK_MAJOR_VERSION);
params.parsed_license.renewal_delay_base = OEMCrypto_License_Load;
params.parsed_license.timer_limits.soft_enforce_rental_duration = false;
params.parsed_license.timer_limits.soft_enforce_playback_duration = false;
params.parsed_license.timer_limits.earliest_playback_start_seconds = 10;
params.parsed_license.timer_limits.total_playback_duration_seconds = 0;
params.parsed_license.timer_limits.rental_duration_seconds = 10;
params.parsed_license.timer_limits.initial_renewal_duration_seconds = 0;
OEMCryptoResult result =
ODK_InitializeClockValues(&params.clock_values, kSystemTime);
EXPECT_EQ(OEMCrypto_SUCCESS, result);
params.clock_values.time_of_license_request_signed = 5;
params.clock_values.status = kActive;
uint8_t* buf = nullptr;
uint32_t buf_size = 0;
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
&buf_size);
result = ODK_ParseLicense(
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
params.usage_entry_present, kSystemTime, &(params.timer_limits),
&(params.clock_values), &(params.core_message.nonce_values),
&(params.parsed_license), nullptr);
EXPECT_EQ(ODK_SET_TIMER, result);
delete[] buf;
}
TEST(OdkTimerBasicTest, ParseLicenseTimerDisabled) {
// playback timer is successfully started
::wvodk_test::ODK_LicenseResponseParams params;
ODK_SetDefaultLicenseResponseParams(&params, ODK_MAJOR_VERSION);
params.parsed_license.renewal_delay_base = OEMCrypto_License_Load;
params.parsed_license.timer_limits.soft_enforce_rental_duration = true;
params.parsed_license.timer_limits.earliest_playback_start_seconds = 3;
params.parsed_license.timer_limits.total_playback_duration_seconds = 0;
params.parsed_license.timer_limits.initial_renewal_duration_seconds = 0;
params.clock_values.time_of_first_decrypt = 10;
params.clock_values.time_of_license_request_signed = 5;
params.clock_values.status = kActive;
uint8_t* buf = nullptr;
uint32_t buf_size = 0;
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
&buf_size);
OEMCryptoResult result = ODK_ParseLicense(
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
params.usage_entry_present, kSystemTime, &(params.timer_limits),
&(params.clock_values), &(params.core_message.nonce_values),
&(params.parsed_license), nullptr);
EXPECT_EQ(ODK_DISABLE_TIMER, result);
delete[] buf;
}
TEST(OdkTimerBasicTest, ParseRenewalTimerExpired) {
// playback timer is successfully started
::wvodk_test::ODK_LicenseResponseParams params;
ODK_SetDefaultLicenseResponseParams(&params, ODK_MAJOR_VERSION);
params.parsed_license.renewal_delay_base = OEMCrypto_License_Load;
params.parsed_license.timer_limits.rental_duration_seconds = 5;
params.parsed_license.timer_limits.earliest_playback_start_seconds = 3;
OEMCryptoResult result =
ODK_InitializeClockValues(&params.clock_values, kSystemTime);
EXPECT_EQ(OEMCrypto_SUCCESS, result);
params.clock_values.time_of_license_request_signed = 5;
uint8_t* buf = nullptr;
uint32_t buf_size = 0;
ODK_BuildMessageBuffer(&(params.core_message), params.extra_fields, &buf,
&buf_size);
result = ODK_ParseLicense(
buf, buf_size + kExtraPayloadSize, buf_size, params.initial_license_load,
params.usage_entry_present, kSystemTime, &(params.timer_limits),
&(params.clock_values), &(params.core_message.nonce_values),
&(params.parsed_license), nullptr);
EXPECT_EQ(ODK_TIMER_EXPIRED, result);
delete[] buf;
}
} // namespace wvodk_test
TEST(OdkTimerBasicTest, NullTest) {
// Assert that nullptr does not cause a core dump.
ODK_InitializeClockValues(nullptr, 0u);