Cherry pick cdm udc-widevine-release changes to udc-widevine-dev to be in sync with 18.3 release

Merged from go/wvgerrit/178231

Bug: 290252845
Test: WVTS tests seem to be running and passing
Change-Id: Ifff9123a73e173e835a6e89ba7c2760e1cd500fd
(cherry picked from commit 6889845d2e7e24f22c00b333335c34259b3fc96e)
This commit is contained in:
Vicky Min
2023-07-12 18:59:13 +00:00
parent 42a5f26c5a
commit bc20b9dac9
460 changed files with 16767 additions and 3215 deletions

View File

@@ -162,44 +162,26 @@ bool CoreRenewalRequestFromMessage(const std::string& oemcrypto_core_message,
bool CoreProvisioningRequestFromMessage(
const std::string& oemcrypto_core_message,
ODK_ProvisioningRequest* core_provisioning_request) {
// We can't tell if V18 format or older. Need to partially parse in order
// to get the nonce values, which will tell us.
// Need to partially parse in order to get the nonce values, which will tell
// us the major/minor version
ODK_NonceValues nonce;
if (!GetNonceFromMessage(oemcrypto_core_message, &nonce)) return false;
if (nonce.api_major_version == 18) {
// Proceed with V18 types
const auto unpacker = Unpack_ODK_PreparedProvisioningRequest;
// Use special case unpacker for v18.0
const auto unpacker = nonce.api_minor_version == 0
? Unpack_ODK_PreparedProvisioningRequestV180
: Unpack_ODK_PreparedProvisioningRequest;
ODK_PreparedProvisioningRequest prepared_provision = {};
if (!ParseRequest(ODK_Provisioning_Request_Type, oemcrypto_core_message,
core_provisioning_request, &prepared_provision,
unpacker)) {
// check for edge case: initial v18 message which is 4 bytes smaller and
// has 0's in the message counter struct
const uint8_t* buf =
reinterpret_cast<const uint8_t*>(oemcrypto_core_message.c_str());
const size_t buf_length = oemcrypto_core_message.size();
return false;
}
if (!(buf_length + 4 == ODK_PROVISIONING_REQUEST_SIZE)) {
return false;
}
// Expected zero padding. Size is the new ODK Provisioning Request (core
// message + const uint32_t + the rest) without the core message and const
// uint32_t.
uint8_t zeros[ODK_PROVISIONING_REQUEST_SIZE - 4 - ODK_CORE_MESSAGE_SIZE] =
{0};
// Compare zeros against the old Provisioning Request (core message + the
// rest).
if (memcmp(zeros, buf + ODK_CORE_MESSAGE_SIZE, sizeof(zeros)) != 0) {
return false;
}
memset(&prepared_provision.counter_info, 0,
sizeof(prepared_provision.counter_info));
} else if (!CopyCounterInfo(&core_provisioning_request->counter_info,
&prepared_provision.counter_info)) {
if (!CopyCounterInfo(&core_provisioning_request->counter_info,
&prepared_provision.counter_info)) {
return false;
}
} else {
@@ -219,7 +201,7 @@ bool CoreProvisioningRequestFromMessage(
if (device_id_length > 0) {
uint8_t zero[ODK_DEVICE_ID_LEN_MAX] = {};
if (memcmp(zero, device_id + device_id_length,
ODK_DEVICE_ID_LEN_MAX - device_id_length)) {
ODK_DEVICE_ID_LEN_MAX - device_id_length) != 0) {
return false;
}
core_provisioning_request->device_id.assign(
@@ -251,7 +233,7 @@ bool CoreProvisioning40RequestFromMessage(
}
uint8_t zero[ODK_DEVICE_INFO_LEN_MAX] = {};
if (memcmp(zero, device_info + device_info_length,
ODK_DEVICE_INFO_LEN_MAX - device_info_length)) {
ODK_DEVICE_INFO_LEN_MAX - device_info_length) != 0) {
return false;
}
core_provisioning_request->device_info.assign(
@@ -276,7 +258,7 @@ bool CoreRenewedProvisioningRequestFromMessage(
}
uint8_t zero[ODK_DEVICE_ID_LEN_MAX] = {};
if (memcmp(zero, device_id + device_id_length,
ODK_DEVICE_ID_LEN_MAX - device_id_length)) {
ODK_DEVICE_ID_LEN_MAX - device_id_length) != 0) {
return false;
}
core_provisioning_request->device_id.assign(

View File

@@ -28,7 +28,7 @@ CoreMessageFeatures CoreMessageFeatures::DefaultFeatures(
features.maximum_minor_version = 2; // 17.2
break;
case 18:
features.maximum_minor_version = 1; // 18.0
features.maximum_minor_version = 3; // 18.3
break;
default:
features.maximum_minor_version = 0;

View File

@@ -25,14 +25,13 @@ namespace {
* computing the API version of the response.
*
* Template arguments:
* T: struct to be deserialized by odk
* S: kdo input struct
*/
template <typename T, typename S>
template <typename S>
bool CreateResponseHeader(const CoreMessageFeatures& features,
ODK_MessageType message_type,
ODK_CoreMessage* response_header,
const S& core_request, T& response) {
const S& core_request) {
// Bad major version.
if ((features.maximum_major_version > ODK_MAJOR_VERSION) ||
(features.maximum_major_version == ODK_MAJOR_VERSION &&
@@ -68,11 +67,10 @@ bool CreateResponseHeader(const CoreMessageFeatures& features,
*
* Template arguments:
* T: struct to be deserialized by odk
* S: kdo input struct
* P: auto-generated serializing function for |T|
*/
template <typename T, typename S, typename P>
bool CreateResponse(ODK_MessageType message_type, const S& core_request,
template <typename T, typename P>
bool CreateResponse(ODK_MessageType message_type,
std::string* oemcrypto_core_message,
ODK_CoreMessage* response_header, T& response,
const P& packer) {
@@ -118,118 +116,25 @@ bool CopyDeviceId(const ODK_ProvisioningRequest& src,
} // namespace
bool CreateCoreLicenseResponse(const CoreMessageFeatures& features,
const ODK_ParsedLicense& parsed_lic,
const ODK_Packing_ParsedLicense& parsed_lic,
const ODK_LicenseRequest& core_request,
const std::string& core_request_sha256,
std::string* oemcrypto_core_message) {
ODK_LicenseResponse license_response{
{}, const_cast<ODK_ParsedLicense*>(&parsed_lic)};
ODK_Packing_LicenseResponse license_response{
{}, const_cast<ODK_Packing_ParsedLicense*>(&parsed_lic), {}};
if (!CreateResponseHeader(features, ODK_License_Response_Type,
&license_response.core_message, core_request,
license_response)) {
return false;
}
if (ODK_MAX_NUM_KEYS < license_response.parsed_license->key_array_length) {
&license_response.core_message, core_request)) {
return false;
}
if (license_response.core_message.nonce_values.api_major_version == 16) {
ODK_LicenseResponseV16 license_response_v16;
license_response_v16.request.core_message = license_response.core_message;
license_response_v16.parsed_license.enc_mac_keys_iv =
license_response.parsed_license->enc_mac_keys_iv;
license_response_v16.parsed_license.enc_mac_keys =
license_response.parsed_license->enc_mac_keys;
license_response_v16.parsed_license.pst =
license_response.parsed_license->pst;
license_response_v16.parsed_license.srm_restriction_data =
license_response.parsed_license->srm_restriction_data;
license_response_v16.parsed_license.license_type =
license_response.parsed_license->license_type;
license_response_v16.parsed_license.nonce_required =
license_response.parsed_license->nonce_required;
license_response_v16.parsed_license.timer_limits =
license_response.parsed_license->timer_limits;
license_response_v16.parsed_license.key_array_length =
license_response.parsed_license->key_array_length;
uint32_t i;
for (i = 0; i < license_response_v16.parsed_license.key_array_length &&
i < license_response.parsed_license->key_array_length;
i++) {
license_response_v16.parsed_license.key_array[i] =
license_response.parsed_license->key_array[i];
}
if (core_request_sha256.size() != sizeof(license_response_v16.request_hash))
if (core_request_sha256.size() != sizeof(license_response.request_hash))
return false;
memcpy(license_response_v16.request_hash, core_request_sha256.data(),
sizeof(license_response_v16.request_hash));
return CreateResponse(ODK_License_Response_Type, core_request,
oemcrypto_core_message,
&license_response_v16.request.core_message,
license_response_v16, Pack_ODK_LicenseResponseV16);
} else if (license_response.core_message.nonce_values.api_major_version ==
17) {
ODK_LicenseResponseV17 license_response_v17;
ODK_ParsedLicenseV17* dest = &license_response_v17.parsed_license;
ODK_ParsedLicense src = *license_response.parsed_license;
license_response_v17.request.core_message = license_response.core_message;
dest->enc_mac_keys_iv = src.enc_mac_keys_iv;
dest->enc_mac_keys = src.enc_mac_keys;
dest->pst = src.pst;
dest->srm_restriction_data = src.srm_restriction_data;
dest->license_type = src.license_type;
dest->nonce_required = src.nonce_required;
dest->timer_limits = src.timer_limits;
dest->watermarking = src.watermarking;
dest->dtcp2_required.dtcp2_required = src.dtcp2_required.dtcp2_required;
dest->dtcp2_required.cmi_descriptor_0.id =
src.dtcp2_required.cmi_descriptor_0.id;
dest->dtcp2_required.cmi_descriptor_0.extension =
src.dtcp2_required.cmi_descriptor_0.extension;
dest->dtcp2_required.cmi_descriptor_0.length =
src.dtcp2_required.cmi_descriptor_0.length;
dest->dtcp2_required.cmi_descriptor_0.data =
src.dtcp2_required.cmi_descriptor_0.data;
dest->dtcp2_required.cmi_descriptor_1.id =
src.dtcp2_required.cmi_descriptor_1.id;
dest->dtcp2_required.cmi_descriptor_1.extension =
src.dtcp2_required.cmi_descriptor_1.extension;
dest->dtcp2_required.cmi_descriptor_1.length =
src.dtcp2_required.cmi_descriptor_1.length;
dest->dtcp2_required.cmi_descriptor_1.data[0] =
src.dtcp2_required.cmi_descriptor_1.data[0];
dest->dtcp2_required.cmi_descriptor_1.data[1] =
src.dtcp2_required.cmi_descriptor_1.data[1];
dest->dtcp2_required.cmi_descriptor_1.data[2] =
src.dtcp2_required.cmi_descriptor_1.data[2];
dest->dtcp2_required.cmi_descriptor_2.id =
src.dtcp2_required.cmi_descriptor_2.id;
dest->dtcp2_required.cmi_descriptor_2.extension =
src.dtcp2_required.cmi_descriptor_2.extension;
dest->dtcp2_required.cmi_descriptor_2.length =
src.dtcp2_required.cmi_descriptor_2.length;
dest->dtcp2_required.cmi_descriptor_2.data[0] =
src.dtcp2_required.cmi_descriptor_2.data[0];
dest->dtcp2_required.cmi_descriptor_2.data[1] =
src.dtcp2_required.cmi_descriptor_2.data[1];
dest->dtcp2_required.cmi_descriptor_2.data[2] =
src.dtcp2_required.cmi_descriptor_2.data[2];
dest->key_array_length = src.key_array_length;
uint32_t i;
for (i = 0; i < dest->key_array_length && i < src.key_array_length; i++) {
dest->key_array[i] = src.key_array[i];
}
if (core_request_sha256.size() != sizeof(license_response_v17.request_hash))
return false;
memcpy(license_response_v17.request_hash, core_request_sha256.data(),
sizeof(license_response_v17.request_hash));
return CreateResponse(ODK_License_Response_Type, core_request,
oemcrypto_core_message,
&license_response_v17.request.core_message,
license_response_v17, Pack_ODK_LicenseResponseV17);
memcpy(license_response.request_hash, core_request_sha256.data(),
sizeof(license_response.request_hash));
}
return CreateResponse(ODK_License_Response_Type, core_request,
oemcrypto_core_message, &license_response.core_message,
license_response, Pack_ODK_LicenseResponse);
return CreateResponse(ODK_License_Response_Type, oemcrypto_core_message,
&license_response.core_message, license_response,
Pack_ODK_LicenseResponse);
}
bool CreateCoreRenewalResponse(const CoreMessageFeatures& features,
@@ -241,11 +146,10 @@ bool CreateCoreRenewalResponse(const CoreMessageFeatures& features,
renewal_response.renewal_duration_seconds = renewal_duration_seconds;
if (!CreateResponseHeader(features, ODK_Renewal_Response_Type,
&renewal_response.request.core_message,
core_request, renewal_response)) {
core_request)) {
return false;
}
return CreateResponse(ODK_Renewal_Response_Type, core_request,
oemcrypto_core_message,
return CreateResponse(ODK_Renewal_Response_Type, oemcrypto_core_message,
&renewal_response.request.core_message,
renewal_response, Pack_ODK_RenewalResponse);
}
@@ -257,8 +161,7 @@ bool CreateCoreProvisioningResponse(const CoreMessageFeatures& features,
ODK_ProvisioningResponse prov_response{
{}, const_cast<ODK_ParsedProvisioning*>(&parsed_prov)};
if (!CreateResponseHeader(features, ODK_Provisioning_Response_Type,
&prov_response.core_message, core_request,
prov_response)) {
&prov_response.core_message, core_request)) {
return false;
}
@@ -269,15 +172,15 @@ bool CreateCoreProvisioningResponse(const CoreMessageFeatures& features,
}
prov_response_v16.request.core_message = prov_response.core_message;
prov_response_v16.parsed_provisioning = prov_response.parsed_provisioning;
return CreateResponse(ODK_Provisioning_Response_Type, core_request,
return CreateResponse(ODK_Provisioning_Response_Type,
oemcrypto_core_message,
&prov_response_v16.request.core_message,
prov_response_v16, Pack_ODK_ProvisioningResponseV16);
}
return CreateResponse(ODK_Provisioning_Response_Type, core_request,
oemcrypto_core_message, &prov_response.core_message,
prov_response, Pack_ODK_ProvisioningResponse);
return CreateResponse(ODK_Provisioning_Response_Type, oemcrypto_core_message,
&prov_response.core_message, prov_response,
Pack_ODK_ProvisioningResponse);
}
bool CreateCoreProvisioning40Response(
@@ -286,13 +189,12 @@ bool CreateCoreProvisioning40Response(
std::string* oemcrypto_core_message) {
ODK_Provisioning40Response prov_response = {};
if (!CreateResponseHeader(features, ODK_Provisioning_Response_Type,
&prov_response.core_message, core_request,
prov_response)) {
&prov_response.core_message, core_request)) {
return false;
}
return CreateResponse(ODK_Provisioning_Response_Type, core_request,
oemcrypto_core_message, &prov_response.core_message,
prov_response, Pack_ODK_Provisioning40Response);
return CreateResponse(ODK_Provisioning_Response_Type, oemcrypto_core_message,
&prov_response.core_message, prov_response,
Pack_ODK_Provisioning40Response);
}
} // namespace serialize

View File

@@ -9,6 +9,7 @@
#include <cstdint>
#include <cstring>
#include <string>
#include <vector>
#include "core_message_serialize.h"
#include "license_protocol.pb.h"
@@ -83,7 +84,8 @@ bool CreateCoreLicenseResponseFromProto(const CoreMessageFeatures& features,
return false;
}
ODK_ParsedLicense parsed_lic{};
ODK_Packing_ParsedLicense parsed_lic{};
std::vector<OEMCrypto_KeyObject> key_array;
bool any_content = false;
bool any_entitlement = false;
@@ -110,12 +112,8 @@ bool CreateCoreLicenseResponseFromProto(const CoreMessageFeatures& features,
} else {
any_content = true;
}
if (parsed_lic.key_array_length >= ODK_MAX_NUM_KEYS) {
return false;
}
uint32_t& n = parsed_lic.key_array_length;
parsed_lic.key_array[n++] =
KeyContainerToOecKey(serialized_license, k, uses_padding);
key_array.push_back(
KeyContainerToOecKey(serialized_license, k, uses_padding));
break;
}
default: {
@@ -147,6 +145,19 @@ bool CreateCoreLicenseResponseFromProto(const CoreMessageFeatures& features,
}
parsed_lic.nonce_required = nonce_required;
const auto& policy = lic.policy();
switch (policy.initial_renewal_delay_base()) {
case video_widevine::License_Policy::LICENSE_LOAD:
parsed_lic.renewal_delay_base = OEMCrypto_License_Load;
break;
case video_widevine::License_Policy::FIRST_DECRYPT:
parsed_lic.renewal_delay_base = OEMCrypto_First_Decrypt;
break;
case video_widevine::License_Policy::TIMER_DELAY_BASE_UNSPECIFIED:
case video_widevine::License_Policy::LICENSE_START:
default:
parsed_lic.renewal_delay_base = OEMCrypto_License_Start;
break;
}
ODK_TimerLimits& timer_limits = parsed_lic.timer_limits;
timer_limits.soft_enforce_rental_duration =
policy.soft_enforce_rental_duration();
@@ -160,6 +171,9 @@ bool CreateCoreLicenseResponseFromProto(const CoreMessageFeatures& features,
policy.renewal_delay_seconds() +
policy.renewal_recovery_duration_seconds();
parsed_lic.key_array = key_array.data();
parsed_lic.key_array_length = static_cast<uint32_t>(key_array.size());
return CreateCoreLicenseResponse(features, parsed_lic, core_request,
core_request_sha256, oemcrypto_core_message);
}

View File

@@ -9,6 +9,7 @@
#include <stdio.h>
#include <string.h>
#include "odk_message.h"
#include "odk_overflow.h"
#include "odk_serialize.h"
#include "odk_structs.h"
@@ -45,12 +46,23 @@ static OEMCryptoResult ODK_PrepareRequest(
* message buffer has been correctly initialized by the caller. */
switch (message_type) {
case ODK_License_Request_Type: {
core_message->message_length = ODK_LICENSE_REQUEST_SIZE;
if (sizeof(ODK_PreparedLicenseRequest) > prepared_request_buffer_length) {
return ODK_ERROR_CORE_MESSAGE;
if (nonce_values->api_major_version > 17) {
core_message->message_length = ODK_LICENSE_REQUEST_SIZE;
if (sizeof(ODK_PreparedLicenseRequest) >
prepared_request_buffer_length) {
return ODK_ERROR_CORE_MESSAGE;
}
Pack_ODK_PreparedLicenseRequest(
&msg, (ODK_PreparedLicenseRequest*)prepared_request_buffer);
} else {
core_message->message_length = ODK_LICENSE_REQUEST_SIZE_V17;
if (sizeof(ODK_PreparedLicenseRequestV17) >
prepared_request_buffer_length) {
return ODK_ERROR_CORE_MESSAGE;
}
Pack_ODK_PreparedLicenseRequestV17(
&msg, (ODK_PreparedLicenseRequestV17*)prepared_request_buffer);
}
Pack_ODK_PreparedLicenseRequest(
&msg, (ODK_PreparedLicenseRequest*)prepared_request_buffer);
break;
}
case ODK_Renewal_Request_Type: {
@@ -63,13 +75,23 @@ static OEMCryptoResult ODK_PrepareRequest(
break;
}
case ODK_Provisioning_Request_Type: {
core_message->message_length = ODK_PROVISIONING_REQUEST_SIZE;
if (sizeof(ODK_PreparedProvisioningRequest) >
prepared_request_buffer_length) {
return ODK_ERROR_CORE_MESSAGE;
if (nonce_values->api_major_version > 17) {
core_message->message_length = ODK_PROVISIONING_REQUEST_SIZE;
if (sizeof(ODK_PreparedProvisioningRequest) >
prepared_request_buffer_length) {
return ODK_ERROR_CORE_MESSAGE;
}
Pack_ODK_PreparedProvisioningRequest(
&msg, (ODK_PreparedProvisioningRequest*)prepared_request_buffer);
} else {
core_message->message_length = ODK_PROVISIONING_REQUEST_SIZE_V17;
if (sizeof(ODK_PreparedProvisioningRequestV17) >
prepared_request_buffer_length) {
return ODK_ERROR_CORE_MESSAGE;
}
Pack_ODK_PreparedProvisioningRequestV17(
&msg, (ODK_PreparedProvisioningRequestV17*)prepared_request_buffer);
}
Pack_ODK_PreparedProvisioningRequest(
&msg, (ODK_PreparedProvisioningRequest*)prepared_request_buffer);
break;
}
case ODK_Provisioning40_Request_Type: {
@@ -186,12 +208,19 @@ OEMCryptoResult ODK_PrepareCoreLicenseRequest(
counter_info == NULL) {
return ODK_ERROR_CORE_MESSAGE;
}
ODK_PreparedLicenseRequest license_request = {0};
memcpy(&license_request.counter_info, counter_info,
sizeof(license_request.counter_info));
return ODK_PrepareRequest(
message, message_length, core_message_size, ODK_License_Request_Type,
nonce_values, &license_request, sizeof(ODK_PreparedLicenseRequest));
if (nonce_values->api_major_version > 17) {
ODK_PreparedLicenseRequest license_request = {0};
memcpy(&license_request.counter_info, counter_info,
sizeof(license_request.counter_info));
return ODK_PrepareRequest(
message, message_length, core_message_size, ODK_License_Request_Type,
nonce_values, &license_request, sizeof(ODK_PreparedLicenseRequest));
} else {
ODK_PreparedLicenseRequestV17 license_request = {0};
return ODK_PrepareRequest(
message, message_length, core_message_size, ODK_License_Request_Type,
nonce_values, &license_request, sizeof(ODK_PreparedLicenseRequestV17));
}
}
OEMCryptoResult ODK_PrepareCoreRenewalRequest(uint8_t* message,
@@ -250,14 +279,22 @@ OEMCryptoResult ODK_PrepareCoreProvisioningRequest(
counter_info == NULL) {
return ODK_ERROR_CORE_MESSAGE;
}
ODK_PreparedProvisioningRequest provisioning_request = {0};
memcpy(&provisioning_request.counter_info, counter_info,
sizeof(ODK_MessageCounterInfo));
if (nonce_values->api_major_version > 17) {
ODK_PreparedProvisioningRequest provisioning_request = {0};
memcpy(&provisioning_request.counter_info, counter_info,
sizeof(ODK_MessageCounterInfo));
return ODK_PrepareRequest(message, message_length, core_message_length,
ODK_Provisioning_Request_Type, nonce_values,
&provisioning_request,
sizeof(ODK_PreparedProvisioningRequest));
return ODK_PrepareRequest(message, message_length, core_message_length,
ODK_Provisioning_Request_Type, nonce_values,
&provisioning_request,
sizeof(ODK_PreparedProvisioningRequest));
} else {
ODK_PreparedProvisioningRequestV17 provisioning_request = {0};
return ODK_PrepareRequest(message, message_length, core_message_length,
ODK_Provisioning_Request_Type, nonce_values,
&provisioning_request,
sizeof(ODK_PreparedProvisioningRequestV17));
}
}
OEMCryptoResult ODK_PrepareCoreProvisioning40Request(
@@ -342,132 +379,12 @@ OEMCryptoResult ODK_ParseLicense(
ODK_Message msg = ODK_Message_Create((uint8_t*)message, message_length);
ODK_Message_SetSize(&msg, core_message_length);
if (nonce_values->api_major_version == 16) {
ODK_LicenseResponseV16 license_response_v16 = {0};
Unpack_ODK_LicenseResponseV16(&msg, &license_response_v16);
if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK ||
ODK_Message_GetOffset(&msg) != core_message_length) {
return ODK_ERROR_CORE_MESSAGE;
}
Unpack_ODK_LicenseResponse(&msg, &license_response);
// Need to manually set parsed_license fields to
// license_response_v16.parsed_license field values since
// license_response_v16 is no longer a pointer so parsed_license doesn't get
// updated during the unpacking.
parsed_license->enc_mac_keys_iv =
license_response_v16.parsed_license.enc_mac_keys_iv;
parsed_license->enc_mac_keys =
license_response_v16.parsed_license.enc_mac_keys;
parsed_license->pst = license_response_v16.parsed_license.pst;
parsed_license->srm_restriction_data =
license_response_v16.parsed_license.srm_restriction_data;
parsed_license->license_type =
license_response_v16.parsed_license.license_type;
parsed_license->nonce_required =
license_response_v16.parsed_license.nonce_required;
parsed_license->timer_limits =
license_response_v16.parsed_license.timer_limits;
parsed_license->key_array_length =
license_response_v16.parsed_license.key_array_length;
uint32_t i;
for (i = 0; i < parsed_license->key_array_length; i++) {
parsed_license->key_array[i] =
license_response_v16.parsed_license.key_array[i];
}
// Set fields not used in V16 to default values.
parsed_license->watermarking = 0;
parsed_license->dtcp2_required.dtcp2_required = 0;
parsed_license->dtcp2_required.cmi_descriptor_0.id = 0;
parsed_license->dtcp2_required.cmi_descriptor_0.extension = 0;
parsed_license->dtcp2_required.cmi_descriptor_0.length = 1;
parsed_license->dtcp2_required.cmi_descriptor_0.data = 0;
parsed_license->dtcp2_required.cmi_descriptor_1.id = 1;
parsed_license->dtcp2_required.cmi_descriptor_1.extension = 0;
parsed_license->dtcp2_required.cmi_descriptor_1.length = 3;
parsed_license->dtcp2_required.cmi_descriptor_1.data[0] = 0;
parsed_license->dtcp2_required.cmi_descriptor_1.data[1] = 0;
parsed_license->dtcp2_required.cmi_descriptor_1.data[2] = 0;
parsed_license->dtcp2_required.cmi_descriptor_2.id = 2;
parsed_license->dtcp2_required.cmi_descriptor_2.extension = 0;
parsed_license->dtcp2_required.cmi_descriptor_2.length = 3;
parsed_license->dtcp2_required.cmi_descriptor_2.data[0] = 0;
parsed_license->dtcp2_required.cmi_descriptor_2.data[1] = 0;
parsed_license->dtcp2_required.cmi_descriptor_2.data[2] = 0;
license_response.core_message = license_response_v16.request.core_message;
parsed_license->renewal_delay_base = 0;
} else if (nonce_values->api_major_version == 17) {
ODK_LicenseResponseV17 license_response_v17 = {0};
Unpack_ODK_LicenseResponseV17(&msg, &license_response_v17);
if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK ||
ODK_Message_GetOffset(&msg) != core_message_length) {
return ODK_ERROR_CORE_MESSAGE;
}
ODK_ParsedLicenseV17 src = license_response_v17.parsed_license;
// Need to manually set parsed_license fields to
// license_response_v17.parsed_license field values since
// license_response_v17 is no longer a pointer so parsed_license doesn't get
// updated during the unpacking.
parsed_license->enc_mac_keys_iv = src.enc_mac_keys_iv;
parsed_license->enc_mac_keys = src.enc_mac_keys;
parsed_license->pst = src.pst;
parsed_license->srm_restriction_data = src.srm_restriction_data;
parsed_license->license_type = src.license_type;
parsed_license->nonce_required = src.nonce_required;
parsed_license->timer_limits = src.timer_limits;
parsed_license->watermarking = src.watermarking;
parsed_license->dtcp2_required.dtcp2_required =
src.dtcp2_required.dtcp2_required;
parsed_license->dtcp2_required.cmi_descriptor_0.id =
src.dtcp2_required.cmi_descriptor_0.id;
parsed_license->dtcp2_required.cmi_descriptor_0.extension =
src.dtcp2_required.cmi_descriptor_0.extension;
parsed_license->dtcp2_required.cmi_descriptor_0.length =
src.dtcp2_required.cmi_descriptor_0.length;
parsed_license->dtcp2_required.cmi_descriptor_0.data =
src.dtcp2_required.cmi_descriptor_0.data;
parsed_license->dtcp2_required.cmi_descriptor_1.id =
src.dtcp2_required.cmi_descriptor_1.id;
parsed_license->dtcp2_required.cmi_descriptor_1.extension =
src.dtcp2_required.cmi_descriptor_1.extension;
parsed_license->dtcp2_required.cmi_descriptor_1.length =
src.dtcp2_required.cmi_descriptor_1.length;
parsed_license->dtcp2_required.cmi_descriptor_1.data[0] =
src.dtcp2_required.cmi_descriptor_1.data[0];
parsed_license->dtcp2_required.cmi_descriptor_1.data[1] =
src.dtcp2_required.cmi_descriptor_1.data[1];
parsed_license->dtcp2_required.cmi_descriptor_1.data[2] =
src.dtcp2_required.cmi_descriptor_1.data[2];
parsed_license->dtcp2_required.cmi_descriptor_2.id =
src.dtcp2_required.cmi_descriptor_2.id;
parsed_license->dtcp2_required.cmi_descriptor_2.extension =
src.dtcp2_required.cmi_descriptor_2.extension;
parsed_license->dtcp2_required.cmi_descriptor_2.length =
src.dtcp2_required.cmi_descriptor_2.length;
parsed_license->dtcp2_required.cmi_descriptor_2.data[0] =
src.dtcp2_required.cmi_descriptor_2.data[0];
parsed_license->dtcp2_required.cmi_descriptor_2.data[1] =
src.dtcp2_required.cmi_descriptor_2.data[1];
parsed_license->dtcp2_required.cmi_descriptor_2.data[2] =
src.dtcp2_required.cmi_descriptor_2.data[2];
parsed_license->key_array_length = src.key_array_length;
uint32_t i;
for (i = 0; i < parsed_license->key_array_length; i++) {
parsed_license->key_array[i] = src.key_array[i];
}
// Set fields not used in V17 to default values.
parsed_license->renewal_delay_base = 0;
license_response.core_message = license_response_v17.request.core_message;
} else {
Unpack_ODK_LicenseResponse(&msg, &license_response);
if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK ||
ODK_Message_GetOffset(&msg) != core_message_length) {
return ODK_ERROR_CORE_MESSAGE;
}
if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK ||
ODK_Message_GetOffset(&msg) != core_message_length) {
return ODK_ERROR_CORE_MESSAGE;
}
/* If the license has a provider session token (pst), then OEMCrypto should
@@ -494,6 +411,12 @@ OEMCryptoResult ODK_ParseLicense(
nonce_values->nonce = license_response.core_message.nonce_values.nonce;
nonce_values->session_id =
license_response.core_message.nonce_values.session_id;
/* Start the rental clock if not already started for reloading an offline
* license without a nonce. */
if (!parsed_license->nonce_required &&
clock_values->time_of_license_request_signed == 0) {
clock_values->time_of_license_request_signed = system_time_seconds;
}
}
bool license_load =
(parsed_license->renewal_delay_base == OEMCrypto_License_Load);
@@ -548,10 +471,14 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
*/
/* If a renewal request is lost in transit, we should throw it out and create
* a new one. We use the timestamp to make sure we have the latest request.
* We only do this if playback has already started. This allows us to reload
* an offline license and also reload a renewal before starting playback.
* We only do this if a renewal has been requested for this session. This
* allows us to reload an offline license and also reload a renewal from a
* previous session before starting playback.
* TODO: b/290249855 - This is reversed. It should be "!=" instead of "<".
* We will not fix this in the current release, because it is already in
* production code. Instead, this will be fixed in v19.
*/
if (clock_values->timer_status != ODK_CLOCK_TIMER_STATUS_LICENSE_LOADED &&
if (clock_values->time_of_renewal_request > 0 &&
clock_values->time_of_renewal_request <
renewal_response.request.playback_time) {
return ODK_STALE_RENEWAL;
@@ -603,14 +530,6 @@ OEMCryptoResult ODK_ParseProvisioning(
device_id_length) != 0) {
return ODK_ERROR_CORE_MESSAGE;
}
const uint8_t zero[ODK_DEVICE_ID_LEN_MAX] = {0};
/* check bytes beyond device_id_length are 0 */
if (crypto_memcmp(
zero, provisioning_response.request.device_id + device_id_length,
ODK_DEVICE_ID_LEN_MAX - device_id_length) != 0) {
return ODK_ERROR_CORE_MESSAGE;
}
} else {
// v18
ODK_ProvisioningResponse provisioning_response = {0};

View File

@@ -8,20 +8,13 @@
#include <stdio.h>
#include <string.h>
#include "odk_assert.h"
#include "odk_message_priv.h"
/*
* C11 defines static_assert in assert.h. If it is available, force a compile
* time error if the abstract ODK_Message struct size does not match its
* implementation. If static_assert is not available, the runtime assert in
* InitMessage will catch the mismatch at the time a message is initialized.
*/
#ifdef static_assert
static_assert(
odk_static_assert(
sizeof(ODK_Message) >= sizeof(ODK_Message_Impl),
"sizeof(ODK_Message) is too small. You can increase "
"SIZE_OF_ODK_MESSAGE_IMPL in odk_message.h to make it large enough.");
#endif
/*
* Create a message structure that references a separate data buffer. An
@@ -34,7 +27,6 @@ static_assert(
* unchanged by this function.
*/
ODK_Message ODK_Message_Create(uint8_t* buffer, size_t capacity) {
assert(sizeof(ODK_Message) >= sizeof(ODK_Message_Impl));
ODK_Message message;
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)&message;
message_impl->base = buffer;

View File

@@ -47,7 +47,8 @@ static void Pack_ODK_TimerLimits(ODK_Message* msg, ODK_TimerLimits const* obj) {
}
static void Pack_ODK_ParsedLicense(ODK_Message* msg,
ODK_ParsedLicense const* obj) {
ODK_Packing_ParsedLicense const* obj,
const ODK_NonceValues* nonce_values) {
/* hand-coded */
if (obj->key_array_length > ODK_MAX_NUM_KEYS) {
ODK_Message_SetStatus(msg, MESSAGE_STATUS_OVERFLOW_ERROR);
@@ -60,89 +61,31 @@ static void Pack_ODK_ParsedLicense(ODK_Message* msg,
Pack_enum(msg, obj->license_type);
Pack_bool(msg, &obj->nonce_required);
Pack_ODK_TimerLimits(msg, &obj->timer_limits);
Pack_uint32_t(msg, &obj->watermarking);
Pack_uint8_t(msg, &obj->dtcp2_required.dtcp2_required);
if (obj->dtcp2_required.dtcp2_required) {
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.id);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.extension);
Pack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_0.length);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.data);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.id);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.extension);
Pack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_1.length);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[0]);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[1]);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[2]);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.id);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.extension);
Pack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_2.length);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[0]);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[1]);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[2]);
if (nonce_values->api_major_version >= 17) {
Pack_uint32_t(msg, &obj->watermarking);
Pack_uint8_t(msg, &obj->dtcp2_required.dtcp2_required);
if (obj->dtcp2_required.dtcp2_required) {
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.id);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.extension);
Pack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_0.length);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.data);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.id);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.extension);
Pack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_1.length);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[0]);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[1]);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[2]);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.id);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.extension);
Pack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_2.length);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[0]);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[1]);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[2]);
}
}
Pack_enum(msg, obj->renewal_delay_base);
Pack_uint32_t(msg, &obj->key_array_length);
size_t i;
for (i = 0; i < (size_t)obj->key_array_length; i++) {
Pack_OEMCrypto_KeyObject(msg, &obj->key_array[i]);
if (nonce_values->api_major_version >= 18) {
Pack_enum(msg, obj->renewal_delay_base);
}
}
static void Pack_ODK_ParsedLicenseV17(ODK_Message* msg,
ODK_ParsedLicenseV17 const* obj) {
/* hand-coded */
if (obj->key_array_length > ODK_MAX_NUM_KEYS) {
ODK_Message_SetStatus(msg, MESSAGE_STATUS_OVERFLOW_ERROR);
return;
}
Pack_OEMCrypto_Substring(msg, &obj->enc_mac_keys_iv);
Pack_OEMCrypto_Substring(msg, &obj->enc_mac_keys);
Pack_OEMCrypto_Substring(msg, &obj->pst);
Pack_OEMCrypto_Substring(msg, &obj->srm_restriction_data);
Pack_enum(msg, obj->license_type);
Pack_bool(msg, &obj->nonce_required);
Pack_ODK_TimerLimits(msg, &obj->timer_limits);
Pack_uint32_t(msg, &obj->watermarking);
Pack_uint8_t(msg, &obj->dtcp2_required.dtcp2_required);
if (obj->dtcp2_required.dtcp2_required) {
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.id);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.extension);
Pack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_0.length);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.data);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.id);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.extension);
Pack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_1.length);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[0]);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[1]);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[2]);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.id);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.extension);
Pack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_2.length);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[0]);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[1]);
Pack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[2]);
}
Pack_uint32_t(msg, &obj->key_array_length);
size_t i;
for (i = 0; i < (size_t)obj->key_array_length; i++) {
Pack_OEMCrypto_KeyObject(msg, &obj->key_array[i]);
}
}
static void Pack_ODK_ParsedLicenseV16(ODK_Message* msg,
ODK_ParsedLicenseV16 const* obj) {
/* hand-coded */
if (obj->key_array_length > ODK_MAX_NUM_KEYS) {
ODK_Message_SetStatus(msg, MESSAGE_STATUS_OVERFLOW_ERROR);
return;
}
Pack_OEMCrypto_Substring(msg, &obj->enc_mac_keys_iv);
Pack_OEMCrypto_Substring(msg, &obj->enc_mac_keys);
Pack_OEMCrypto_Substring(msg, &obj->pst);
Pack_OEMCrypto_Substring(msg, &obj->srm_restriction_data);
Pack_enum(msg, obj->license_type);
Pack_bool(msg, &obj->nonce_required);
Pack_ODK_TimerLimits(msg, &obj->timer_limits);
Pack_uint32_t(msg, &obj->key_array_length);
size_t i;
for (i = 0; i < (size_t)obj->key_array_length; i++) {
@@ -229,22 +172,14 @@ void Pack_ODK_PreparedRenewedProvisioningRequest(
/* @@ kdo serialize */
void Pack_ODK_LicenseResponse(ODK_Message* msg,
ODK_LicenseResponse const* obj) {
ODK_Packing_LicenseResponse const* obj) {
Pack_ODK_CoreMessage(msg, &obj->core_message);
Pack_ODK_ParsedLicense(msg, (const ODK_ParsedLicense*)obj->parsed_license);
}
void Pack_ODK_LicenseResponseV17(ODK_Message* msg,
ODK_LicenseResponseV17 const* obj) {
Pack_ODK_PreparedLicenseRequestV17(msg, &obj->request);
Pack_ODK_ParsedLicenseV17(msg, &obj->parsed_license);
}
void Pack_ODK_LicenseResponseV16(ODK_Message* msg,
ODK_LicenseResponseV16 const* obj) {
Pack_ODK_PreparedLicenseRequestV17(msg, &obj->request);
Pack_ODK_ParsedLicenseV16(msg, &obj->parsed_license);
PackArray(msg, &obj->request_hash[0], sizeof(obj->request_hash));
Pack_ODK_ParsedLicense(msg,
(const ODK_Packing_ParsedLicense*)obj->parsed_license,
&obj->core_message.nonce_values);
if ((&obj->core_message.nonce_values)->api_major_version == 16) {
PackArray(msg, &obj->request_hash[0], sizeof(obj->request_hash));
}
}
void Pack_ODK_RenewalResponse(ODK_Message* msg,
@@ -307,7 +242,8 @@ static void Unpack_ODK_TimerLimits(ODK_Message* msg, ODK_TimerLimits* obj) {
Unpack_uint64_t(msg, &obj->initial_renewal_duration_seconds);
}
static void Unpack_ODK_ParsedLicense(ODK_Message* msg, ODK_ParsedLicense* obj) {
static void Unpack_ODK_ParsedLicense(ODK_Message* msg, ODK_ParsedLicense* obj,
const ODK_NonceValues* nonce_values) {
Unpack_OEMCrypto_Substring(msg, &obj->enc_mac_keys_iv);
Unpack_OEMCrypto_Substring(msg, &obj->enc_mac_keys);
Unpack_OEMCrypto_Substring(msg, &obj->pst);
@@ -315,123 +251,31 @@ static void Unpack_ODK_ParsedLicense(ODK_Message* msg, ODK_ParsedLicense* obj) {
Unpack_OEMCrypto_LicenseType(msg, &obj->license_type);
Unpack_bool(msg, &obj->nonce_required);
Unpack_ODK_TimerLimits(msg, &obj->timer_limits);
Unpack_uint32_t(msg, &obj->watermarking);
Unpack_uint8_t(msg, &obj->dtcp2_required.dtcp2_required);
if (obj->dtcp2_required.dtcp2_required) {
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.id);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.extension);
Unpack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_0.length);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.data);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.id);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.extension);
Unpack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_1.length);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[0]);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[1]);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[2]);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.id);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.extension);
Unpack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_2.length);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[0]);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[1]);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[2]);
} else {
obj->dtcp2_required.dtcp2_required = 0;
obj->dtcp2_required.cmi_descriptor_0.id = 0;
obj->dtcp2_required.cmi_descriptor_0.extension = 0;
obj->dtcp2_required.cmi_descriptor_0.length = 0;
obj->dtcp2_required.cmi_descriptor_0.data = 0;
obj->dtcp2_required.cmi_descriptor_1.id = 0;
obj->dtcp2_required.cmi_descriptor_1.extension = 0;
obj->dtcp2_required.cmi_descriptor_1.length = 0;
obj->dtcp2_required.cmi_descriptor_1.data[0] = 0;
obj->dtcp2_required.cmi_descriptor_1.data[1] = 0;
obj->dtcp2_required.cmi_descriptor_1.data[2] = 0;
obj->dtcp2_required.cmi_descriptor_2.id = 0;
obj->dtcp2_required.cmi_descriptor_2.extension = 0;
obj->dtcp2_required.cmi_descriptor_2.length = 0;
obj->dtcp2_required.cmi_descriptor_2.data[0] = 0;
obj->dtcp2_required.cmi_descriptor_2.data[1] = 0;
obj->dtcp2_required.cmi_descriptor_2.data[2] = 0;
if (nonce_values->api_major_version >= 17) {
Unpack_uint32_t(msg, &obj->watermarking);
Unpack_uint8_t(msg, &obj->dtcp2_required.dtcp2_required);
if (obj->dtcp2_required.dtcp2_required) {
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.id);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.extension);
Unpack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_0.length);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.data);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.id);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.extension);
Unpack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_1.length);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[0]);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[1]);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[2]);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.id);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.extension);
Unpack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_2.length);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[0]);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[1]);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[2]);
}
}
Unpack_OEMCrypto_TimerDelayBase(msg, &obj->renewal_delay_base);
Unpack_uint32_t(msg, &obj->key_array_length);
if (obj->key_array_length > ODK_MAX_NUM_KEYS) {
ODK_Message_SetStatus(msg, MESSAGE_STATUS_OVERFLOW_ERROR);
return;
if (nonce_values->api_major_version >= 18) {
Unpack_OEMCrypto_TimerDelayBase(msg, &obj->renewal_delay_base);
}
uint32_t i;
for (i = 0; i < obj->key_array_length; i++) {
Unpack_OEMCrypto_KeyObject(msg, &obj->key_array[i]);
}
}
static void Unpack_ODK_ParsedLicenseV17(ODK_Message* msg,
ODK_ParsedLicenseV17* obj) {
Unpack_OEMCrypto_Substring(msg, &obj->enc_mac_keys_iv);
Unpack_OEMCrypto_Substring(msg, &obj->enc_mac_keys);
Unpack_OEMCrypto_Substring(msg, &obj->pst);
Unpack_OEMCrypto_Substring(msg, &obj->srm_restriction_data);
Unpack_OEMCrypto_LicenseType(msg, &obj->license_type);
Unpack_bool(msg, &obj->nonce_required);
Unpack_ODK_TimerLimits(msg, &obj->timer_limits);
Unpack_uint32_t(msg, &obj->watermarking);
Unpack_uint8_t(msg, &obj->dtcp2_required.dtcp2_required);
if (obj->dtcp2_required.dtcp2_required) {
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.id);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.extension);
Unpack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_0.length);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_0.data);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.id);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.extension);
Unpack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_1.length);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[0]);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[1]);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_1.data[2]);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.id);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.extension);
Unpack_uint16_t(msg, &obj->dtcp2_required.cmi_descriptor_2.length);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[0]);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[1]);
Unpack_uint8_t(msg, &obj->dtcp2_required.cmi_descriptor_2.data[2]);
} else {
obj->dtcp2_required.dtcp2_required = 0;
obj->dtcp2_required.cmi_descriptor_0.id = 0;
obj->dtcp2_required.cmi_descriptor_0.extension = 0;
obj->dtcp2_required.cmi_descriptor_0.length = 0;
obj->dtcp2_required.cmi_descriptor_0.data = 0;
obj->dtcp2_required.cmi_descriptor_1.id = 0;
obj->dtcp2_required.cmi_descriptor_1.extension = 0;
obj->dtcp2_required.cmi_descriptor_1.length = 0;
obj->dtcp2_required.cmi_descriptor_1.data[0] = 0;
obj->dtcp2_required.cmi_descriptor_1.data[1] = 0;
obj->dtcp2_required.cmi_descriptor_1.data[2] = 0;
obj->dtcp2_required.cmi_descriptor_2.id = 0;
obj->dtcp2_required.cmi_descriptor_2.extension = 0;
obj->dtcp2_required.cmi_descriptor_2.length = 0;
obj->dtcp2_required.cmi_descriptor_2.data[0] = 0;
obj->dtcp2_required.cmi_descriptor_2.data[1] = 0;
obj->dtcp2_required.cmi_descriptor_2.data[2] = 0;
}
Unpack_uint32_t(msg, &obj->key_array_length);
if (obj->key_array_length > ODK_MAX_NUM_KEYS) {
ODK_Message_SetStatus(msg, MESSAGE_STATUS_OVERFLOW_ERROR);
return;
}
uint32_t i;
for (i = 0; i < obj->key_array_length; i++) {
Unpack_OEMCrypto_KeyObject(msg, &obj->key_array[i]);
}
}
static void Unpack_ODK_ParsedLicenseV16(ODK_Message* msg,
ODK_ParsedLicenseV16* obj) {
Unpack_OEMCrypto_Substring(msg, &obj->enc_mac_keys_iv);
Unpack_OEMCrypto_Substring(msg, &obj->enc_mac_keys);
Unpack_OEMCrypto_Substring(msg, &obj->pst);
Unpack_OEMCrypto_Substring(msg, &obj->srm_restriction_data);
Unpack_OEMCrypto_LicenseType(msg, &obj->license_type);
Unpack_bool(msg, &obj->nonce_required);
Unpack_ODK_TimerLimits(msg, &obj->timer_limits);
Unpack_uint32_t(msg, &obj->key_array_length);
if (obj->key_array_length > ODK_MAX_NUM_KEYS) {
ODK_Message_SetStatus(msg, MESSAGE_STATUS_OVERFLOW_ERROR);
@@ -494,6 +338,12 @@ void Unpack_ODK_PreparedProvisioningRequest(
Unpack_ODK_MessageCounterInfo(msg, &obj->counter_info);
}
void Unpack_ODK_PreparedProvisioningRequestV180(
ODK_Message* msg, ODK_PreparedProvisioningRequest* obj) {
Unpack_ODK_CoreMessage(msg, &obj->core_message);
Unpack_ODK_MessageCounterInfo(msg, &obj->counter_info);
}
void Unpack_ODK_PreparedProvisioningRequestV17(
ODK_Message* msg, ODK_PreparedProvisioningRequestV17* obj) {
Unpack_ODK_CoreMessage(msg, &obj->core_message);
@@ -527,20 +377,11 @@ void Unpack_ODK_PreparedCommonRequest(ODK_Message* msg,
void Unpack_ODK_LicenseResponse(ODK_Message* msg, ODK_LicenseResponse* obj) {
Unpack_ODK_CoreMessage(msg, &obj->core_message);
Unpack_ODK_ParsedLicense(msg, obj->parsed_license);
}
void Unpack_ODK_LicenseResponseV17(ODK_Message* msg,
ODK_LicenseResponseV17* obj) {
Unpack_ODK_PreparedLicenseRequestV17(msg, &obj->request);
Unpack_ODK_ParsedLicenseV17(msg, &obj->parsed_license);
}
void Unpack_ODK_LicenseResponseV16(ODK_Message* msg,
ODK_LicenseResponseV16* obj) {
Unpack_ODK_PreparedLicenseRequestV17(msg, &obj->request);
Unpack_ODK_ParsedLicenseV16(msg, &obj->parsed_license);
UnpackArray(msg, &obj->request_hash[0], sizeof(obj->request_hash));
Unpack_ODK_ParsedLicense(msg, obj->parsed_license,
&obj->core_message.nonce_values);
if ((&obj->core_message.nonce_values)->api_major_version == 16) {
UnpackArray(msg, &obj->request_hash[0], sizeof(obj->request_hash));
}
}
void Unpack_ODK_RenewalResponse(ODK_Message* msg, ODK_RenewalResponse* obj) {

View File

@@ -34,10 +34,6 @@ void Pack_ODK_PreparedRenewedProvisioningRequest(
/* odk unpack */
void Unpack_ODK_CoreMessage(ODK_Message* msg, ODK_CoreMessage* obj);
void Unpack_ODK_LicenseResponse(ODK_Message* msg, ODK_LicenseResponse* obj);
void Unpack_ODK_LicenseResponseV17(ODK_Message* msg,
ODK_LicenseResponseV17* obj);
void Unpack_ODK_LicenseResponseV16(ODK_Message* msg,
ODK_LicenseResponseV16* obj);
void Unpack_ODK_RenewalResponse(ODK_Message* msg, ODK_RenewalResponse* obj);
void Unpack_ODK_ProvisioningResponse(ODK_Message* msg,
ODK_ProvisioningResponse* obj);
@@ -47,11 +43,8 @@ void Unpack_ODK_Provisioning40Response(ODK_Message* msg,
ODK_Provisioning40Response* obj);
/* kdo pack */
void Pack_ODK_LicenseResponse(ODK_Message* msg, const ODK_LicenseResponse* obj);
void Pack_ODK_LicenseResponseV17(ODK_Message* msg,
const ODK_LicenseResponseV17* obj);
void Pack_ODK_LicenseResponseV16(ODK_Message* msg,
const ODK_LicenseResponseV16* obj);
void Pack_ODK_LicenseResponse(ODK_Message* msg,
const ODK_Packing_LicenseResponse* obj);
void Pack_ODK_RenewalResponse(ODK_Message* msg, const ODK_RenewalResponse* obj);
void Pack_ODK_ProvisioningResponse(ODK_Message* msg,
const ODK_ProvisioningResponse* obj);
@@ -69,6 +62,8 @@ void Unpack_ODK_PreparedRenewalRequest(ODK_Message* msg,
ODK_PreparedRenewalRequest* obj);
void Unpack_ODK_PreparedProvisioningRequest(
ODK_Message* msg, ODK_PreparedProvisioningRequest* obj);
void Unpack_ODK_PreparedProvisioningRequestV180(
ODK_Message* msg, ODK_PreparedProvisioningRequest* obj);
void Unpack_ODK_PreparedProvisioningRequestV17(
ODK_Message* msg, ODK_PreparedProvisioningRequestV17* obj);
void Unpack_ODK_PreparedProvisioning40Request(

View File

@@ -85,48 +85,17 @@ typedef struct {
ODK_CoreMessage core_message;
} ODK_PreparedCommonRequest;
typedef struct {
OEMCrypto_Substring enc_mac_keys_iv;
OEMCrypto_Substring enc_mac_keys;
OEMCrypto_Substring pst;
OEMCrypto_Substring srm_restriction_data;
OEMCrypto_LicenseType license_type;
bool nonce_required;
ODK_TimerLimits timer_limits;
uint32_t key_array_length;
OEMCrypto_KeyObject key_array[ODK_MAX_NUM_KEYS];
} ODK_ParsedLicenseV16;
typedef struct {
OEMCrypto_Substring enc_mac_keys_iv;
OEMCrypto_Substring enc_mac_keys;
OEMCrypto_Substring pst;
OEMCrypto_Substring srm_restriction_data;
OEMCrypto_LicenseType license_type;
bool nonce_required;
ODK_TimerLimits timer_limits;
uint32_t watermarking;
OEMCrypto_DTCP2_CMI_Packet dtcp2_required;
uint32_t key_array_length;
OEMCrypto_KeyObject key_array[ODK_MAX_NUM_KEYS];
} ODK_ParsedLicenseV17;
typedef struct {
ODK_CoreMessage core_message;
ODK_ParsedLicense* parsed_license;
uint8_t request_hash[ODK_SHA256_HASH_SIZE];
} ODK_LicenseResponse;
typedef struct {
ODK_PreparedLicenseRequestV17 request;
ODK_ParsedLicenseV17 parsed_license;
ODK_CoreMessage core_message;
ODK_Packing_ParsedLicense* parsed_license;
uint8_t request_hash[ODK_SHA256_HASH_SIZE];
} ODK_LicenseResponseV17;
typedef struct {
ODK_PreparedLicenseRequestV17 request;
ODK_ParsedLicenseV16 parsed_license;
uint8_t request_hash[ODK_SHA256_HASH_SIZE];
} ODK_LicenseResponseV16;
} ODK_Packing_LicenseResponse;
typedef struct {
ODK_PreparedRenewalRequest request;
@@ -154,8 +123,10 @@ typedef struct {
// ../test/odk_test.cpp for validations of each of the defined request sizes.
#define ODK_CORE_MESSAGE_SIZE 20u
#define ODK_LICENSE_REQUEST_SIZE 90u
#define ODK_LICENSE_REQUEST_SIZE_V17 20u
#define ODK_RENEWAL_REQUEST_SIZE 28u
#define ODK_PROVISIONING_REQUEST_SIZE 94u
#define ODK_PROVISIONING_REQUEST_SIZE_V17 88u
#define ODK_PROVISIONING40_REQUEST_SIZE 862u
#define ODK_RENEWED_PROVISIONING_REQUEST_SIZE 1694u
#define ODK_MESSAGECOUNTERINFO_SIZE 70u

View File

@@ -254,11 +254,6 @@ OEMCryptoResult ODK_InitializeSessionValues(ODK_TimerLimits* timer_limits,
if (timer_limits == NULL || clock_values == NULL || nonce_values == NULL) {
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
/* Check that the API version passed in from OEMCrypto matches the version of
* this ODK library. */
if (api_major_version != ODK_MAJOR_VERSION) {
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
timer_limits->soft_enforce_rental_duration = false;
timer_limits->soft_enforce_playback_duration = false;
timer_limits->earliest_playback_start_seconds = 0;
@@ -268,7 +263,7 @@ OEMCryptoResult ODK_InitializeSessionValues(ODK_TimerLimits* timer_limits,
ODK_InitializeClockValues(clock_values, 0);
nonce_values->api_major_version = ODK_MAJOR_VERSION;
nonce_values->api_major_version = api_major_version;
nonce_values->api_minor_version = ODK_MINOR_VERSION;
nonce_values->nonce = 0;
nonce_values->session_id = session_id;
@@ -300,6 +295,7 @@ OEMCryptoResult ODK_InitializeClockValues(ODK_ClockValues* clock_values,
clock_values->time_of_license_request_signed = system_time_seconds;
clock_values->time_of_first_decrypt = 0;
clock_values->time_of_last_decrypt = 0;
clock_values->time_of_renewal_request = 0;
clock_values->time_when_timer_expires = 0;
clock_values->timer_status = ODK_CLOCK_TIMER_STATUS_LICENSE_NOT_LOADED;
clock_values->status = kUnused;