Pick widevine oemcrypto-v18 change
No-Typo-Check: From a third party header file Bug: 260918793 Test: unit tests Test: atp v2/widevine-eng/drm_compliance Change-Id: I36effd6a10a99bdb2399ab1f4a0fad026d607c70
This commit is contained in:
@@ -11,10 +11,10 @@
|
||||
#include <string>
|
||||
|
||||
#include "OEMCryptoCENCCommon.h"
|
||||
#include "odk_message.h"
|
||||
#include "odk_serialize.h"
|
||||
#include "odk_structs.h"
|
||||
#include "odk_structs_priv.h"
|
||||
#include "serialization_base.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
namespace deserialize {
|
||||
@@ -89,8 +89,33 @@ bool ParseRequest(uint32_t message_type,
|
||||
|
||||
} // namespace
|
||||
|
||||
static bool GetNonceFromMessage(const std::string& oemcrypto_core_message,
|
||||
ODK_NonceValues* nonce_values) {
|
||||
if (nonce_values == nullptr) return false;
|
||||
if (oemcrypto_core_message.size() < sizeof(ODK_CoreMessage)) return false;
|
||||
|
||||
ODK_CoreMessage core_message;
|
||||
const uint8_t* buf =
|
||||
reinterpret_cast<const uint8_t*>(oemcrypto_core_message.c_str());
|
||||
ODK_Message msg = ODK_Message_Create(const_cast<uint8_t*>(buf),
|
||||
oemcrypto_core_message.size());
|
||||
ODK_Message_SetSize(&msg, sizeof(ODK_CoreMessage));
|
||||
Unpack_ODK_CoreMessage(&msg, &core_message);
|
||||
if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK) return false;
|
||||
*nonce_values = core_message.nonce_values;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CoreLicenseRequestFromMessage(const std::string& oemcrypto_core_message,
|
||||
ODK_LicenseRequest* core_license_request) {
|
||||
ODK_NonceValues nonce;
|
||||
if (!GetNonceFromMessage(oemcrypto_core_message, &nonce)) return false;
|
||||
if (nonce.api_major_version <= 17) {
|
||||
const auto unpacker = Unpack_ODK_PreparedLicenseRequestV17;
|
||||
ODK_PreparedLicenseRequestV17 prepared_license = {};
|
||||
return ParseRequest(ODK_License_Request_Type, oemcrypto_core_message,
|
||||
core_license_request, &prepared_license, unpacker);
|
||||
}
|
||||
const auto unpacker = Unpack_ODK_PreparedLicenseRequest;
|
||||
ODK_PreparedLicenseRequest prepared_license = {};
|
||||
return ParseRequest(ODK_License_Request_Type, oemcrypto_core_message,
|
||||
@@ -112,26 +137,70 @@ bool CoreRenewalRequestFromMessage(const std::string& oemcrypto_core_message,
|
||||
bool CoreProvisioningRequestFromMessage(
|
||||
const std::string& oemcrypto_core_message,
|
||||
ODK_ProvisioningRequest* core_provisioning_request) {
|
||||
const auto unpacker = Unpack_ODK_PreparedProvisioningRequest;
|
||||
ODK_PreparedProvisioningRequest prepared_provision = {};
|
||||
if (!ParseRequest(ODK_Provisioning_Request_Type, oemcrypto_core_message,
|
||||
// We can't tell if V18 format or older. Need to partially parse in order
|
||||
// to get the nonce values, which will tell us.
|
||||
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;
|
||||
ODK_PreparedProvisioningRequest prepared_provision = {};
|
||||
if (!ParseRequest(ODK_Provisioning_Request_Type, oemcrypto_core_message,
|
||||
core_provisioning_request, &prepared_provision,
|
||||
unpacker)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// V17 and older
|
||||
const auto unpacker = Unpack_ODK_PreparedProvisioningRequestV17;
|
||||
ODK_PreparedProvisioningRequestV17 prepared_provision = {};
|
||||
if (!ParseRequest(ODK_Provisioning_Request_Type, oemcrypto_core_message,
|
||||
core_provisioning_request, &prepared_provision,
|
||||
unpacker)) {
|
||||
return false;
|
||||
}
|
||||
const uint8_t* device_id = prepared_provision.device_id;
|
||||
const uint32_t device_id_length = prepared_provision.device_id_length;
|
||||
if (device_id_length > ODK_DEVICE_ID_LEN_MAX) {
|
||||
return false;
|
||||
}
|
||||
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)) {
|
||||
return false;
|
||||
}
|
||||
core_provisioning_request->device_id.assign(
|
||||
reinterpret_cast<const char*>(device_id), device_id_length);
|
||||
}
|
||||
core_provisioning_request->renewal_type = OEMCrypto_NoRenewal;
|
||||
core_provisioning_request->renewal_data.clear();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CoreProvisioning40RequestFromMessage(
|
||||
const std::string& oemcrypto_core_message,
|
||||
ODK_Provisioning40Request* core_provisioning_request) {
|
||||
const auto unpacker = Unpack_ODK_PreparedProvisioning40Request;
|
||||
ODK_PreparedProvisioning40Request prepared_provision = {};
|
||||
if (!ParseRequest(ODK_Provisioning40_Request_Type, oemcrypto_core_message,
|
||||
core_provisioning_request, &prepared_provision, unpacker)) {
|
||||
return false;
|
||||
}
|
||||
const uint8_t* device_id = prepared_provision.device_id;
|
||||
const uint32_t device_id_length = prepared_provision.device_id_length;
|
||||
if (device_id_length > ODK_DEVICE_ID_LEN_MAX) {
|
||||
const uint8_t* device_info = prepared_provision.device_info;
|
||||
const uint32_t device_info_length = prepared_provision.device_info_length;
|
||||
if (device_info_length > ODK_DEVICE_INFO_LEN_MAX) {
|
||||
return false;
|
||||
}
|
||||
uint8_t zero[ODK_DEVICE_ID_LEN_MAX] = {};
|
||||
if (memcmp(zero, device_id + device_id_length,
|
||||
ODK_DEVICE_ID_LEN_MAX - device_id_length)) {
|
||||
uint8_t zero[ODK_DEVICE_INFO_LEN_MAX] = {};
|
||||
if (memcmp(zero, device_info + device_info_length,
|
||||
ODK_DEVICE_INFO_LEN_MAX - device_info_length)) {
|
||||
return false;
|
||||
}
|
||||
core_provisioning_request->device_id.assign(
|
||||
reinterpret_cast<const char*>(device_id), device_id_length);
|
||||
core_provisioning_request->renewal_type = OEMCrypto_NoRenewal;
|
||||
core_provisioning_request->renewal_data.clear();
|
||||
core_provisioning_request->device_info.assign(
|
||||
reinterpret_cast<const char*>(device_info), device_info_length);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "core_message_features.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
namespace features {
|
||||
const CoreMessageFeatures CoreMessageFeatures::kDefaultFeatures;
|
||||
@@ -25,6 +27,9 @@ CoreMessageFeatures CoreMessageFeatures::DefaultFeatures(
|
||||
case 17:
|
||||
features.maximum_minor_version = 2; // 17.2
|
||||
break;
|
||||
case 18:
|
||||
features.maximum_minor_version = 0; // 18.0
|
||||
break;
|
||||
default:
|
||||
features.maximum_minor_version = 0;
|
||||
}
|
||||
|
||||
@@ -30,8 +30,9 @@ namespace {
|
||||
*/
|
||||
template <typename T, typename S>
|
||||
bool CreateResponseHeader(const CoreMessageFeatures& features,
|
||||
ODK_MessageType message_type, const S& core_request,
|
||||
T& response) {
|
||||
ODK_MessageType message_type,
|
||||
ODK_CoreMessage* response_header,
|
||||
const S& core_request, T& response) {
|
||||
// Bad major version.
|
||||
if ((features.maximum_major_version > ODK_MAJOR_VERSION) ||
|
||||
(features.maximum_major_version == ODK_MAJOR_VERSION &&
|
||||
@@ -40,20 +41,24 @@ bool CreateResponseHeader(const CoreMessageFeatures& features,
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* header = &response.request.core_message;
|
||||
header->message_type = message_type;
|
||||
header->nonce_values.api_major_version = core_request.api_major_version;
|
||||
header->nonce_values.api_minor_version = core_request.api_minor_version;
|
||||
header->nonce_values.nonce = core_request.nonce;
|
||||
header->nonce_values.session_id = core_request.session_id;
|
||||
response_header->message_type = message_type;
|
||||
response_header->nonce_values.api_major_version =
|
||||
core_request.api_major_version;
|
||||
response_header->nonce_values.api_minor_version =
|
||||
core_request.api_minor_version;
|
||||
response_header->nonce_values.nonce = core_request.nonce;
|
||||
response_header->nonce_values.session_id = core_request.session_id;
|
||||
// The message API version for the response is the minimum of our version and
|
||||
// the request's version.
|
||||
if (core_request.api_major_version > features.maximum_major_version) {
|
||||
header->nonce_values.api_major_version = features.maximum_major_version;
|
||||
header->nonce_values.api_minor_version = features.maximum_minor_version;
|
||||
response_header->nonce_values.api_major_version =
|
||||
features.maximum_major_version;
|
||||
response_header->nonce_values.api_minor_version =
|
||||
features.maximum_minor_version;
|
||||
} else if (core_request.api_major_version == features.maximum_major_version &&
|
||||
core_request.api_minor_version > features.maximum_minor_version) {
|
||||
header->nonce_values.api_minor_version = features.maximum_minor_version;
|
||||
response_header->nonce_values.api_minor_version =
|
||||
features.maximum_minor_version;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -68,14 +73,14 @@ bool CreateResponseHeader(const CoreMessageFeatures& features,
|
||||
*/
|
||||
template <typename T, typename S, typename P>
|
||||
bool CreateResponse(ODK_MessageType message_type, const S& core_request,
|
||||
std::string* oemcrypto_core_message, T& response,
|
||||
std::string* oemcrypto_core_message,
|
||||
ODK_CoreMessage* response_header, T& response,
|
||||
const P& packer) {
|
||||
if (!oemcrypto_core_message) {
|
||||
return false;
|
||||
}
|
||||
auto* header = &response.request.core_message;
|
||||
if (header->message_type != message_type ||
|
||||
header->nonce_values.api_major_version < ODK_FIRST_VERSION) {
|
||||
if (response_header->message_type != message_type ||
|
||||
response_header->nonce_values.api_major_version < ODK_FIRST_VERSION) {
|
||||
// This indicates CreateResponseHeader was not called.
|
||||
return false;
|
||||
}
|
||||
@@ -89,8 +94,8 @@ bool CreateResponse(ODK_MessageType message_type, const S& core_request,
|
||||
}
|
||||
|
||||
uint32_t message_length = static_cast<uint32_t>(ODK_Message_GetSize(&msg));
|
||||
msg = ODK_Message_Create(buf.data() + sizeof(header->message_type),
|
||||
sizeof(header->message_length));
|
||||
msg = ODK_Message_Create(buf.data() + sizeof(response_header->message_type),
|
||||
sizeof(response_header->message_length));
|
||||
Pack_uint32_t(&msg, &message_length);
|
||||
oemcrypto_core_message->assign(reinterpret_cast<const char*>(buf.data()),
|
||||
message_length);
|
||||
@@ -98,10 +103,10 @@ bool CreateResponse(ODK_MessageType message_type, const S& core_request,
|
||||
}
|
||||
|
||||
bool CopyDeviceId(const ODK_ProvisioningRequest& src,
|
||||
ODK_ProvisioningResponse* dest) {
|
||||
ODK_ProvisioningResponseV16* dest) {
|
||||
auto& request = dest->request;
|
||||
const std::string& device_id = src.device_id;
|
||||
if (request.device_id_length > sizeof(request.device_id)) {
|
||||
if (device_id.size() > sizeof(request.device_id)) {
|
||||
return false;
|
||||
}
|
||||
request.device_id_length = static_cast<uint32_t>(device_id.size());
|
||||
@@ -119,17 +124,17 @@ bool CreateCoreLicenseResponse(const CoreMessageFeatures& features,
|
||||
std::string* oemcrypto_core_message) {
|
||||
ODK_LicenseResponse license_response{
|
||||
{}, const_cast<ODK_ParsedLicense*>(&parsed_lic)};
|
||||
if (!CreateResponseHeader(features, ODK_License_Response_Type, core_request,
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
if (license_response.request.core_message.nonce_values.api_major_version ==
|
||||
16) {
|
||||
if (license_response.core_message.nonce_values.api_major_version == 16) {
|
||||
ODK_LicenseResponseV16 license_response_v16;
|
||||
license_response_v16.request = license_response.request;
|
||||
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 =
|
||||
@@ -158,12 +163,73 @@ bool CreateCoreLicenseResponse(const CoreMessageFeatures& features,
|
||||
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,
|
||||
Pack_ODK_LicenseResponseV16);
|
||||
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);
|
||||
}
|
||||
return CreateResponse(ODK_License_Response_Type, core_request,
|
||||
oemcrypto_core_message, license_response,
|
||||
Pack_ODK_LicenseResponse);
|
||||
oemcrypto_core_message, &license_response.core_message,
|
||||
license_response, Pack_ODK_LicenseResponse);
|
||||
}
|
||||
|
||||
bool CreateCoreRenewalResponse(const CoreMessageFeatures& features,
|
||||
@@ -173,13 +239,15 @@ bool CreateCoreRenewalResponse(const CoreMessageFeatures& features,
|
||||
ODK_RenewalResponse renewal_response{{}, core_request.playback_time_seconds};
|
||||
renewal_response.request.playback_time = core_request.playback_time_seconds;
|
||||
renewal_response.renewal_duration_seconds = renewal_duration_seconds;
|
||||
if (!CreateResponseHeader(features, ODK_Renewal_Response_Type, core_request,
|
||||
renewal_response)) {
|
||||
if (!CreateResponseHeader(features, ODK_Renewal_Response_Type,
|
||||
&renewal_response.request.core_message,
|
||||
core_request, renewal_response)) {
|
||||
return false;
|
||||
}
|
||||
return CreateResponse(ODK_Renewal_Response_Type, core_request,
|
||||
oemcrypto_core_message, renewal_response,
|
||||
Pack_ODK_RenewalResponse);
|
||||
oemcrypto_core_message,
|
||||
&renewal_response.request.core_message,
|
||||
renewal_response, Pack_ODK_RenewalResponse);
|
||||
}
|
||||
|
||||
bool CreateCoreProvisioningResponse(const CoreMessageFeatures& features,
|
||||
@@ -188,16 +256,43 @@ bool CreateCoreProvisioningResponse(const CoreMessageFeatures& features,
|
||||
std::string* oemcrypto_core_message) {
|
||||
ODK_ProvisioningResponse prov_response{
|
||||
{}, const_cast<ODK_ParsedProvisioning*>(&parsed_prov)};
|
||||
if (!CopyDeviceId(core_request, &prov_response)) {
|
||||
if (!CreateResponseHeader(features, ODK_Provisioning_Response_Type,
|
||||
&prov_response.core_message, core_request,
|
||||
prov_response)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (prov_response.core_message.nonce_values.api_major_version <= 17) {
|
||||
ODK_ProvisioningResponseV16 prov_response_v16;
|
||||
if (!CopyDeviceId(core_request, &prov_response_v16)) {
|
||||
return false;
|
||||
}
|
||||
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,
|
||||
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);
|
||||
}
|
||||
|
||||
bool CreateCoreProvisioning40Response(
|
||||
const CoreMessageFeatures& features,
|
||||
const ODK_Provisioning40Request& core_request,
|
||||
std::string* oemcrypto_core_message) {
|
||||
ODK_Provisioning40Response prov_response = {};
|
||||
if (!CreateResponseHeader(features, ODK_Provisioning_Response_Type,
|
||||
core_request, prov_response)) {
|
||||
&prov_response.core_message, core_request,
|
||||
prov_response)) {
|
||||
return false;
|
||||
}
|
||||
return CreateResponse(ODK_Provisioning_Response_Type, core_request,
|
||||
oemcrypto_core_message, prov_response,
|
||||
Pack_ODK_ProvisioningResponse);
|
||||
oemcrypto_core_message, &prov_response.core_message,
|
||||
prov_response, Pack_ODK_Provisioning40Response);
|
||||
}
|
||||
|
||||
} // namespace serialize
|
||||
|
||||
@@ -164,19 +164,16 @@ bool CreateCoreLicenseResponseFromProto(const CoreMessageFeatures& features,
|
||||
core_request_sha256, oemcrypto_core_message);
|
||||
}
|
||||
|
||||
bool CreateCoreProvisioningResponseFromProto(
|
||||
const CoreMessageFeatures& features,
|
||||
bool DeserializeProvisioningResponse(
|
||||
const std::string& serialized_provisioning_resp,
|
||||
const ODK_ProvisioningRequest& core_request,
|
||||
std::string* oemcrypto_core_message) {
|
||||
ODK_ParsedProvisioning parsed_prov{};
|
||||
const OEMCrypto_PrivateKeyType device_key_type,
|
||||
ODK_ParsedProvisioning& parsed_prov) {
|
||||
video_widevine::ProvisioningResponse prov;
|
||||
if (!prov.ParseFromString(serialized_provisioning_resp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
parsed_prov.key_type =
|
||||
OEMCrypto_RSA_Private_Key; // TODO(b/148404408): ECC or RSA
|
||||
parsed_prov.key_type = device_key_type;
|
||||
if (prov.has_device_rsa_key()) {
|
||||
parsed_prov.enc_private_key =
|
||||
GetOecSubstring(serialized_provisioning_resp, prov.device_rsa_key());
|
||||
@@ -189,7 +186,19 @@ bool CreateCoreProvisioningResponseFromProto(
|
||||
parsed_prov.encrypted_message_key =
|
||||
GetOecSubstring(serialized_provisioning_resp, prov.wrapping_key());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateCoreProvisioningResponseFromProto(
|
||||
const CoreMessageFeatures& features,
|
||||
const std::string& serialized_provisioning_resp,
|
||||
const ODK_ProvisioningRequest& core_request,
|
||||
const OEMCrypto_PrivateKeyType device_key_type,
|
||||
std::string* oemcrypto_core_message) {
|
||||
ODK_ParsedProvisioning parsed_prov{};
|
||||
if (!DeserializeProvisioningResponse(serialized_provisioning_resp,
|
||||
device_key_type, parsed_prov))
|
||||
return false;
|
||||
return CreateCoreProvisioningResponse(features, parsed_prov, core_request,
|
||||
oemcrypto_core_message);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "odk_overflow.h"
|
||||
@@ -13,7 +14,6 @@
|
||||
#include "odk_structs.h"
|
||||
#include "odk_structs_priv.h"
|
||||
#include "odk_util.h"
|
||||
#include "serialization_base.h"
|
||||
|
||||
/* @ private odk functions */
|
||||
|
||||
@@ -72,6 +72,16 @@ static OEMCryptoResult ODK_PrepareRequest(
|
||||
&msg, (ODK_PreparedProvisioningRequest*)prepared_request_buffer);
|
||||
break;
|
||||
}
|
||||
case ODK_Provisioning40_Request_Type: {
|
||||
core_message->message_length = ODK_PROVISIONING40_REQUEST_SIZE;
|
||||
if (sizeof(ODK_PreparedProvisioning40Request) >
|
||||
prepared_request_buffer_length) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
Pack_ODK_PreparedProvisioning40Request(
|
||||
&msg, (ODK_PreparedProvisioning40Request*)prepared_request_buffer);
|
||||
break;
|
||||
}
|
||||
case ODK_Renewed_Provisioning_Request_Type: {
|
||||
core_message->message_length = ODK_RENEWED_PROVISIONING_REQUEST_SIZE;
|
||||
if (sizeof(ODK_PreparedRenewedProvisioningRequest) >
|
||||
@@ -169,14 +179,18 @@ static OEMCryptoResult ODK_ParseCoreHeader(const uint8_t* message,
|
||||
/* @@ prepare request functions */
|
||||
|
||||
OEMCryptoResult ODK_PrepareCoreLicenseRequest(
|
||||
uint8_t* message, size_t message_length, size_t* core_message_length,
|
||||
const ODK_NonceValues* nonce_values) {
|
||||
if (core_message_length == NULL || nonce_values == NULL) {
|
||||
uint8_t* message, size_t message_length, size_t* core_message_size,
|
||||
const ODK_NonceValues* nonce_values,
|
||||
const ODK_MessageCounterInfo* counter_info) {
|
||||
if (core_message_size == NULL || nonce_values == NULL ||
|
||||
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_length, ODK_License_Request_Type,
|
||||
message, message_length, core_message_size, ODK_License_Request_Type,
|
||||
nonce_values, &license_request, sizeof(ODK_PreparedLicenseRequest));
|
||||
}
|
||||
|
||||
@@ -230,25 +244,47 @@ OEMCryptoResult ODK_PrepareCoreRenewalRequest(uint8_t* message,
|
||||
|
||||
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) {
|
||||
if (core_message_length == NULL || nonce_values == NULL) {
|
||||
const ODK_NonceValues* nonce_values,
|
||||
const ODK_MessageCounterInfo* counter_info) {
|
||||
if (core_message_length == NULL || nonce_values == NULL ||
|
||||
counter_info == NULL) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
ODK_PreparedProvisioningRequest provisioning_request = {0};
|
||||
if (device_id_length > sizeof(provisioning_request.device_id)) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
provisioning_request.device_id_length = (uint32_t)device_id_length;
|
||||
if (device_id) {
|
||||
memcpy(provisioning_request.device_id, device_id, device_id_length);
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
OEMCryptoResult ODK_PrepareCoreProvisioning40Request(
|
||||
uint8_t* message, size_t message_length, size_t* core_message_length,
|
||||
const ODK_NonceValues* nonce_values, const uint8_t* device_info,
|
||||
size_t device_info_length, const ODK_MessageCounterInfo* counter_info) {
|
||||
if (core_message_length == NULL || nonce_values == NULL ||
|
||||
counter_info == NULL) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
ODK_PreparedProvisioning40Request provisioning_request = {0};
|
||||
if (device_info_length > sizeof(provisioning_request.device_info)) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
provisioning_request.device_info_length = (uint32_t)device_info_length;
|
||||
if (device_info) {
|
||||
memcpy(provisioning_request.device_info, device_info, device_info_length);
|
||||
}
|
||||
memcpy(&provisioning_request.counter_info, counter_info,
|
||||
sizeof(provisioning_request.counter_info));
|
||||
|
||||
return ODK_PrepareRequest(message, message_length, core_message_length,
|
||||
ODK_Provisioning40_Request_Type, nonce_values,
|
||||
&provisioning_request,
|
||||
sizeof(provisioning_request));
|
||||
}
|
||||
|
||||
OEMCryptoResult ODK_PrepareCoreRenewedProvisioningRequest(
|
||||
uint8_t* message, size_t message_length, size_t* core_message_length,
|
||||
const ODK_NonceValues* nonce_values, const uint8_t* device_id,
|
||||
@@ -285,14 +321,15 @@ OEMCryptoResult ODK_PrepareCoreRenewedProvisioningRequest(
|
||||
OEMCryptoResult ODK_ParseLicense(
|
||||
const uint8_t* message, size_t message_length, size_t core_message_length,
|
||||
bool initial_license_load, bool usage_entry_present,
|
||||
ODK_TimerLimits* timer_limits, ODK_ClockValues* clock_values,
|
||||
ODK_NonceValues* nonce_values, ODK_ParsedLicense* parsed_license) {
|
||||
uint64_t system_time_seconds, ODK_TimerLimits* timer_limits,
|
||||
ODK_ClockValues* clock_values, ODK_NonceValues* nonce_values,
|
||||
ODK_ParsedLicense* parsed_license, uint64_t* timer_value) {
|
||||
if (message == NULL || timer_limits == NULL || clock_values == NULL ||
|
||||
nonce_values == NULL || parsed_license == NULL) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
|
||||
const OEMCryptoResult err =
|
||||
OEMCryptoResult err =
|
||||
ODK_ParseCoreHeader(message, message_length, core_message_length,
|
||||
ODK_License_Response_Type, nonce_values);
|
||||
if (err != OEMCrypto_SUCCESS) {
|
||||
@@ -303,6 +340,7 @@ OEMCryptoResult ODK_ParseLicense(
|
||||
license_response.parsed_license = parsed_license;
|
||||
|
||||
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};
|
||||
@@ -339,7 +377,6 @@ OEMCryptoResult ODK_ParseLicense(
|
||||
}
|
||||
// Set fields not used in V16 to default values.
|
||||
parsed_license->watermarking = 0;
|
||||
// Set fields not used in V16 to default values.
|
||||
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;
|
||||
@@ -357,7 +394,73 @@ OEMCryptoResult ODK_ParseLicense(
|
||||
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.request = license_response_v16.request;
|
||||
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);
|
||||
|
||||
@@ -382,26 +485,32 @@ OEMCryptoResult ODK_ParseLicense(
|
||||
*/
|
||||
if (parsed_license->nonce_required && initial_license_load) {
|
||||
if (nonce_values->nonce !=
|
||||
license_response.request.core_message.nonce_values.nonce ||
|
||||
license_response.core_message.nonce_values.nonce ||
|
||||
nonce_values->session_id !=
|
||||
license_response.request.core_message.nonce_values.session_id) {
|
||||
license_response.core_message.nonce_values.session_id) {
|
||||
return OEMCrypto_ERROR_INVALID_NONCE;
|
||||
}
|
||||
} else { /* !initial_license_load, or can't tell if initial. */
|
||||
nonce_values->nonce =
|
||||
license_response.request.core_message.nonce_values.nonce;
|
||||
nonce_values->nonce = license_response.core_message.nonce_values.nonce;
|
||||
nonce_values->session_id =
|
||||
license_response.request.core_message.nonce_values.session_id;
|
||||
license_response.core_message.nonce_values.session_id;
|
||||
}
|
||||
bool license_load =
|
||||
(parsed_license->renewal_delay_base == OEMCrypto_License_Load);
|
||||
*timer_limits = parsed_license->timer_limits;
|
||||
/* And update the clock values state. */
|
||||
clock_values->timer_status = ODK_CLOCK_TIMER_STATUS_LICENSE_LOADED;
|
||||
if (nonce_values->api_major_version == 18 && license_load) {
|
||||
err = ODK_AttemptFirstPlayback(system_time_seconds, timer_limits,
|
||||
clock_values, timer_value);
|
||||
return err;
|
||||
}
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
|
||||
size_t core_message_length,
|
||||
const ODK_NonceValues* nonce_values,
|
||||
ODK_NonceValues* nonce_values,
|
||||
uint64_t system_time,
|
||||
const ODK_TimerLimits* timer_limits,
|
||||
ODK_ClockValues* clock_values,
|
||||
@@ -413,7 +522,7 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
|
||||
|
||||
const OEMCryptoResult err =
|
||||
ODK_ParseCoreHeader(message, message_length, core_message_length,
|
||||
ODK_Renewal_Response_Type, NULL);
|
||||
ODK_Renewal_Response_Type, nonce_values);
|
||||
if (err != OEMCrypto_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
@@ -454,7 +563,7 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
|
||||
|
||||
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,
|
||||
ODK_NonceValues* nonce_values, const uint8_t* device_id,
|
||||
size_t device_id_length, ODK_ParsedProvisioning* parsed_response) {
|
||||
if (message == NULL || nonce_values == NULL || device_id == NULL ||
|
||||
parsed_response == NULL) {
|
||||
@@ -462,44 +571,96 @@ OEMCryptoResult ODK_ParseProvisioning(
|
||||
}
|
||||
const OEMCryptoResult err =
|
||||
ODK_ParseCoreHeader(message, message_length, core_message_length,
|
||||
ODK_Provisioning_Response_Type, NULL);
|
||||
ODK_Provisioning_Response_Type, nonce_values);
|
||||
if (err != OEMCrypto_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
ODK_ProvisioningResponse provisioning_response = {0};
|
||||
provisioning_response.parsed_provisioning = parsed_response;
|
||||
|
||||
if (device_id_length > ODK_DEVICE_ID_LEN_MAX) {
|
||||
if (nonce_values->api_major_version <= 17) {
|
||||
// Do v16/v17
|
||||
ODK_ProvisioningResponseV16 provisioning_response = {0};
|
||||
provisioning_response.parsed_provisioning = parsed_response;
|
||||
|
||||
if (device_id_length > ODK_DEVICE_ID_LEN_MAX) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
|
||||
ODK_Message msg = ODK_Message_Create((uint8_t*)message, message_length);
|
||||
ODK_Message_SetSize(&msg, core_message_length);
|
||||
Unpack_ODK_ProvisioningResponseV16(&msg, &provisioning_response);
|
||||
if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK ||
|
||||
ODK_Message_GetOffset(&msg) != core_message_length) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
/* always verify nonce_values for Renewal and Provisioning responses */
|
||||
if (!ODK_NonceValuesEqualExcludingVersion(
|
||||
nonce_values,
|
||||
&(provisioning_response.request.core_message.nonce_values))) {
|
||||
return OEMCrypto_ERROR_INVALID_NONCE;
|
||||
}
|
||||
|
||||
if (crypto_memcmp(device_id, provisioning_response.request.device_id,
|
||||
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};
|
||||
provisioning_response.parsed_provisioning = parsed_response;
|
||||
|
||||
ODK_Message msg = ODK_Message_Create((uint8_t*)message, message_length);
|
||||
ODK_Message_SetSize(&msg, core_message_length);
|
||||
Unpack_ODK_ProvisioningResponse(&msg, &provisioning_response);
|
||||
if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK ||
|
||||
ODK_Message_GetOffset(&msg) != core_message_length) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
/* always verify nonce_values for Renewal and Provisioning responses */
|
||||
if (!ODK_NonceValuesEqualExcludingVersion(
|
||||
nonce_values, &(provisioning_response.core_message.nonce_values))) {
|
||||
return OEMCrypto_ERROR_INVALID_NONCE;
|
||||
}
|
||||
}
|
||||
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
OEMCryptoResult ODK_ParseProvisioning40(const uint8_t* message,
|
||||
size_t message_length,
|
||||
size_t core_message_length,
|
||||
ODK_NonceValues* nonce_values) {
|
||||
if (message == NULL || nonce_values == NULL) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
const OEMCryptoResult err =
|
||||
ODK_ParseCoreHeader(message, message_length, core_message_length,
|
||||
ODK_Provisioning_Response_Type, nonce_values);
|
||||
if (err != OEMCrypto_SUCCESS) {
|
||||
return err;
|
||||
}
|
||||
ODK_Provisioning40Response provisioning_response = {0};
|
||||
|
||||
ODK_Message msg = ODK_Message_Create((uint8_t*)message, message_length);
|
||||
ODK_Message_SetSize(&msg, core_message_length);
|
||||
Unpack_ODK_ProvisioningResponse(&msg, &provisioning_response);
|
||||
Unpack_ODK_Provisioning40Response(&msg, &provisioning_response);
|
||||
if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK ||
|
||||
ODK_Message_GetOffset(&msg) != core_message_length) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
}
|
||||
/* always verify nonce_values for Renewal and Provisioning responses */
|
||||
if (!ODK_NonceValuesEqualExcludingVersion(
|
||||
nonce_values,
|
||||
&(provisioning_response.request.core_message.nonce_values))) {
|
||||
nonce_values, &(provisioning_response.core_message.nonce_values))) {
|
||||
return OEMCrypto_ERROR_INVALID_NONCE;
|
||||
}
|
||||
|
||||
if (crypto_memcmp(device_id, provisioning_response.request.device_id,
|
||||
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;
|
||||
}
|
||||
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#include "odk_overflow.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* This code is auto-generated, do not edit
|
||||
*/
|
||||
|
||||
#include "odk_serialize.h"
|
||||
|
||||
#include "odk_structs_priv.h"
|
||||
#include "serialization_base.h"
|
||||
|
||||
@@ -78,6 +80,48 @@ static void Pack_ODK_ParsedLicense(ODK_Message* msg,
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
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++) {
|
||||
@@ -114,11 +158,31 @@ static void Pack_ODK_ParsedProvisioning(ODK_Message* msg,
|
||||
Pack_OEMCrypto_Substring(msg, &obj->encrypted_message_key);
|
||||
}
|
||||
|
||||
static void Pack_ODK_MessageCounterInfo(ODK_Message* msg,
|
||||
ODK_MessageCounterInfo const* obj) {
|
||||
Pack_uint64_t(msg, &obj->master_generation_number);
|
||||
Pack_uint32_t(msg, &obj->provisioning_count);
|
||||
Pack_uint32_t(msg, &obj->license_count);
|
||||
Pack_uint32_t(msg, &obj->decrypt_count);
|
||||
Pack_uint16_t(msg, &obj->major_version);
|
||||
Pack_uint16_t(msg, &obj->minor_version);
|
||||
Pack_uint16_t(msg, &obj->patch_version);
|
||||
PackArray(msg, &obj->soc_vendor[0], sizeof(obj->soc_vendor));
|
||||
PackArray(msg, &obj->chipset_model[0], sizeof(obj->chipset_model));
|
||||
PackArray(msg, &obj->extra[0], sizeof(obj->extra));
|
||||
}
|
||||
|
||||
/* @@ odk serialize */
|
||||
|
||||
void Pack_ODK_PreparedLicenseRequest(ODK_Message* msg,
|
||||
ODK_PreparedLicenseRequest const* obj) {
|
||||
Pack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
Pack_ODK_MessageCounterInfo(msg, &obj->counter_info);
|
||||
}
|
||||
|
||||
void Pack_ODK_PreparedLicenseRequestV17(
|
||||
ODK_Message* msg, ODK_PreparedLicenseRequestV17 const* obj) {
|
||||
Pack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
}
|
||||
|
||||
void Pack_ODK_PreparedRenewalRequest(ODK_Message* msg,
|
||||
@@ -130,10 +194,24 @@ void Pack_ODK_PreparedRenewalRequest(ODK_Message* msg,
|
||||
void Pack_ODK_PreparedProvisioningRequest(
|
||||
ODK_Message* msg, const ODK_PreparedProvisioningRequest* obj) {
|
||||
Pack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
Pack_ODK_MessageCounterInfo(msg, &obj->counter_info);
|
||||
}
|
||||
|
||||
void Pack_ODK_PreparedProvisioningRequestV17(
|
||||
ODK_Message* msg, const ODK_PreparedProvisioningRequestV17* obj) {
|
||||
Pack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
Pack_uint32_t(msg, &obj->device_id_length);
|
||||
PackArray(msg, &obj->device_id[0], sizeof(obj->device_id));
|
||||
}
|
||||
|
||||
void Pack_ODK_PreparedProvisioning40Request(
|
||||
ODK_Message* msg, const ODK_PreparedProvisioning40Request* obj) {
|
||||
Pack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
Pack_uint32_t(msg, &obj->device_info_length);
|
||||
PackArray(msg, &obj->device_info[0], sizeof(obj->device_info));
|
||||
Pack_ODK_MessageCounterInfo(msg, &obj->counter_info);
|
||||
}
|
||||
|
||||
void Pack_ODK_PreparedRenewedProvisioningRequest(
|
||||
ODK_Message* msg, const ODK_PreparedRenewedProvisioningRequest* obj) {
|
||||
Pack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
@@ -148,13 +226,19 @@ void Pack_ODK_PreparedRenewedProvisioningRequest(
|
||||
|
||||
void Pack_ODK_LicenseResponse(ODK_Message* msg,
|
||||
ODK_LicenseResponse const* obj) {
|
||||
Pack_ODK_PreparedLicenseRequest(msg, &obj->request);
|
||||
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_PreparedLicenseRequest(msg, &obj->request);
|
||||
Pack_ODK_PreparedLicenseRequestV17(msg, &obj->request);
|
||||
Pack_ODK_ParsedLicenseV16(msg, &obj->parsed_license);
|
||||
PackArray(msg, &obj->request_hash[0], sizeof(obj->request_hash));
|
||||
}
|
||||
@@ -167,11 +251,23 @@ void Pack_ODK_RenewalResponse(ODK_Message* msg,
|
||||
|
||||
void Pack_ODK_ProvisioningResponse(ODK_Message* msg,
|
||||
const ODK_ProvisioningResponse* obj) {
|
||||
Pack_ODK_PreparedProvisioningRequest(msg, &obj->request);
|
||||
Pack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
Pack_ODK_ParsedProvisioning(
|
||||
msg, (const ODK_ParsedProvisioning*)obj->parsed_provisioning);
|
||||
}
|
||||
|
||||
void Pack_ODK_ProvisioningResponseV16(ODK_Message* msg,
|
||||
const ODK_ProvisioningResponseV16* obj) {
|
||||
Pack_ODK_PreparedProvisioningRequestV17(msg, &obj->request);
|
||||
Pack_ODK_ParsedProvisioning(
|
||||
msg, (const ODK_ParsedProvisioning*)obj->parsed_provisioning);
|
||||
}
|
||||
|
||||
void Pack_ODK_Provisioning40Response(ODK_Message* msg,
|
||||
const ODK_Provisioning40Response* obj) {
|
||||
Pack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
}
|
||||
|
||||
/* @ deserialize */
|
||||
|
||||
/* @@ private deserialize */
|
||||
@@ -253,6 +349,65 @@ static void Unpack_ODK_ParsedLicense(ODK_Message* msg, ODK_ParsedLicense* obj) {
|
||||
obj->dtcp2_required.cmi_descriptor_2.data[1] = 0;
|
||||
obj->dtcp2_required.cmi_descriptor_2.data[2] = 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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);
|
||||
@@ -292,11 +447,31 @@ static void Unpack_ODK_ParsedProvisioning(ODK_Message* msg,
|
||||
Unpack_OEMCrypto_Substring(msg, &obj->encrypted_message_key);
|
||||
}
|
||||
|
||||
static void Unpack_ODK_MessageCounterInfo(ODK_Message* msg,
|
||||
ODK_MessageCounterInfo* obj) {
|
||||
Unpack_uint64_t(msg, &obj->master_generation_number);
|
||||
Unpack_uint32_t(msg, &obj->provisioning_count);
|
||||
Unpack_uint32_t(msg, &obj->license_count);
|
||||
Unpack_uint32_t(msg, &obj->decrypt_count);
|
||||
Unpack_uint16_t(msg, &obj->major_version);
|
||||
Unpack_uint16_t(msg, &obj->minor_version);
|
||||
Unpack_uint16_t(msg, &obj->patch_version);
|
||||
UnpackArray(msg, &obj->soc_vendor[0], sizeof(obj->soc_vendor));
|
||||
UnpackArray(msg, &obj->chipset_model[0], sizeof(obj->chipset_model));
|
||||
UnpackArray(msg, &obj->extra[0], sizeof(obj->extra));
|
||||
}
|
||||
|
||||
/* @ kdo deserialize */
|
||||
|
||||
void Unpack_ODK_PreparedLicenseRequest(ODK_Message* msg,
|
||||
ODK_PreparedLicenseRequest* obj) {
|
||||
Unpack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
Unpack_ODK_MessageCounterInfo(msg, &obj->counter_info);
|
||||
}
|
||||
|
||||
void Unpack_ODK_PreparedLicenseRequestV17(ODK_Message* msg,
|
||||
ODK_PreparedLicenseRequestV17* obj) {
|
||||
Unpack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
}
|
||||
|
||||
void Unpack_ODK_PreparedRenewalRequest(ODK_Message* msg,
|
||||
@@ -308,10 +483,24 @@ void Unpack_ODK_PreparedRenewalRequest(ODK_Message* msg,
|
||||
void Unpack_ODK_PreparedProvisioningRequest(
|
||||
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);
|
||||
Unpack_uint32_t(msg, &obj->device_id_length);
|
||||
UnpackArray(msg, &obj->device_id[0], sizeof(obj->device_id));
|
||||
}
|
||||
|
||||
void Unpack_ODK_PreparedProvisioning40Request(
|
||||
ODK_Message* msg, ODK_PreparedProvisioning40Request* obj) {
|
||||
Unpack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
Unpack_uint32_t(msg, &obj->device_info_length);
|
||||
UnpackArray(msg, &obj->device_info[0], sizeof(obj->device_info));
|
||||
Unpack_ODK_MessageCounterInfo(msg, &obj->counter_info);
|
||||
}
|
||||
|
||||
void Unpack_ODK_PreparedRenewedProvisioningRequest(
|
||||
ODK_Message* msg, ODK_PreparedRenewedProvisioningRequest* obj) {
|
||||
Unpack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
@@ -329,13 +518,19 @@ void Unpack_ODK_PreparedCommonRequest(ODK_Message* msg,
|
||||
/* @@ odk deserialize */
|
||||
|
||||
void Unpack_ODK_LicenseResponse(ODK_Message* msg, ODK_LicenseResponse* obj) {
|
||||
Unpack_ODK_PreparedLicenseRequest(msg, &obj->request);
|
||||
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_PreparedLicenseRequest(msg, &obj->request);
|
||||
Unpack_ODK_PreparedLicenseRequestV17(msg, &obj->request);
|
||||
Unpack_ODK_ParsedLicenseV16(msg, &obj->parsed_license);
|
||||
UnpackArray(msg, &obj->request_hash[0], sizeof(obj->request_hash));
|
||||
}
|
||||
@@ -347,6 +542,17 @@ void Unpack_ODK_RenewalResponse(ODK_Message* msg, ODK_RenewalResponse* obj) {
|
||||
|
||||
void Unpack_ODK_ProvisioningResponse(ODK_Message* msg,
|
||||
ODK_ProvisioningResponse* obj) {
|
||||
Unpack_ODK_PreparedProvisioningRequest(msg, &obj->request);
|
||||
Unpack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
Unpack_ODK_ParsedProvisioning(msg, obj->parsed_provisioning);
|
||||
}
|
||||
|
||||
void Unpack_ODK_ProvisioningResponseV16(ODK_Message* msg,
|
||||
ODK_ProvisioningResponseV16* obj) {
|
||||
Unpack_ODK_PreparedProvisioningRequestV17(msg, &obj->request);
|
||||
Unpack_ODK_ParsedProvisioning(msg, obj->parsed_provisioning);
|
||||
}
|
||||
|
||||
void Unpack_ODK_Provisioning40Response(ODK_Message* msg,
|
||||
ODK_Provisioning40Response* obj) {
|
||||
Unpack_ODK_CoreMessage(msg, &obj->core_message);
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#ifndef WIDEVINE_ODK_SRC_ODK_SERIALIZE_H_
|
||||
#define WIDEVINE_ODK_SRC_ODK_SERIALIZE_H_
|
||||
|
||||
#include "odk_message.h"
|
||||
#include "odk_structs_priv.h"
|
||||
#include "serialization_base.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -18,37 +18,61 @@ extern "C" {
|
||||
/* odk pack */
|
||||
void Pack_ODK_PreparedLicenseRequest(ODK_Message* msg,
|
||||
const ODK_PreparedLicenseRequest* obj);
|
||||
void Pack_ODK_PreparedLicenseRequestV16(
|
||||
ODK_Message* msg, const ODK_PreparedLicenseRequestV17* obj);
|
||||
void Pack_ODK_PreparedRenewalRequest(ODK_Message* msg,
|
||||
const ODK_PreparedRenewalRequest* obj);
|
||||
void Pack_ODK_PreparedProvisioningRequest(
|
||||
ODK_Message* msg, const ODK_PreparedProvisioningRequest* obj);
|
||||
void Pack_ODK_PreparedProvisioningRequestV17(
|
||||
ODK_Message* msg, const ODK_PreparedProvisioningRequestV17* obj);
|
||||
void Pack_ODK_PreparedProvisioning40Request(
|
||||
ODK_Message* msg, const ODK_PreparedProvisioning40Request* obj);
|
||||
void Pack_ODK_PreparedRenewedProvisioningRequest(
|
||||
ODK_Message* msg, const ODK_PreparedRenewedProvisioningRequest* obj);
|
||||
|
||||
/* 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);
|
||||
void Unpack_ODK_ProvisioningResponseV16(ODK_Message* msg,
|
||||
ODK_ProvisioningResponseV16* obj);
|
||||
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_RenewalResponse(ODK_Message* msg, const ODK_RenewalResponse* obj);
|
||||
void Pack_ODK_ProvisioningResponse(ODK_Message* msg,
|
||||
const ODK_ProvisioningResponse* obj);
|
||||
void Pack_ODK_ProvisioningResponseV16(ODK_Message* msg,
|
||||
const ODK_ProvisioningResponseV16* obj);
|
||||
void Pack_ODK_Provisioning40Response(ODK_Message* msg,
|
||||
const ODK_Provisioning40Response* obj);
|
||||
|
||||
/* kdo unpack */
|
||||
void Unpack_ODK_PreparedLicenseRequest(ODK_Message* msg,
|
||||
ODK_PreparedLicenseRequest* obj);
|
||||
void Unpack_ODK_PreparedLicenseRequestV17(ODK_Message* msg,
|
||||
ODK_PreparedLicenseRequestV17* obj);
|
||||
void Unpack_ODK_PreparedRenewalRequest(ODK_Message* msg,
|
||||
ODK_PreparedRenewalRequest* obj);
|
||||
void Unpack_ODK_PreparedProvisioningRequest(
|
||||
ODK_Message* msg, ODK_PreparedProvisioningRequest* obj);
|
||||
void Unpack_ODK_PreparedProvisioningRequestV17(
|
||||
ODK_Message* msg, ODK_PreparedProvisioningRequestV17* obj);
|
||||
void Unpack_ODK_PreparedProvisioning40Request(
|
||||
ODK_Message* msg, ODK_PreparedProvisioning40Request* obj);
|
||||
void Unpack_ODK_PreparedRenewedProvisioningRequest(
|
||||
ODK_Message* msg, ODK_PreparedRenewedProvisioningRequest* obj);
|
||||
|
||||
|
||||
@@ -25,8 +25,10 @@ typedef uint32_t ODK_MessageType;
|
||||
#define ODK_Provisioning_Request_Type ((ODK_MessageType)5u)
|
||||
#define ODK_Provisioning_Response_Type ((ODK_MessageType)6u)
|
||||
#define ODK_Renewed_Provisioning_Request_Type ((ODK_MessageType)11u)
|
||||
#define ODK_Provisioning40_Request_Type ((ODK_MessageType)12u)
|
||||
|
||||
// Reserve future message types to support forward compatibility.
|
||||
// TODO(b/244580447): Reserve future message types to support
|
||||
// forward compatibility.
|
||||
#define ODK_Release_Request_Type ((ODK_MessageType)7u)
|
||||
#define ODK_Release_Response_Type ((ODK_MessageType)8u)
|
||||
#define ODK_Common_Request_Type ((ODK_MessageType)9u)
|
||||
@@ -40,18 +42,35 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
ODK_CoreMessage core_message;
|
||||
ODK_MessageCounterInfo counter_info;
|
||||
} ODK_PreparedLicenseRequest;
|
||||
|
||||
typedef struct {
|
||||
ODK_CoreMessage core_message;
|
||||
} ODK_PreparedLicenseRequestV17;
|
||||
|
||||
typedef struct {
|
||||
ODK_CoreMessage core_message;
|
||||
uint64_t playback_time;
|
||||
} ODK_PreparedRenewalRequest;
|
||||
|
||||
typedef struct {
|
||||
ODK_CoreMessage core_message;
|
||||
ODK_MessageCounterInfo counter_info;
|
||||
} ODK_PreparedProvisioningRequest;
|
||||
|
||||
typedef struct {
|
||||
ODK_CoreMessage core_message;
|
||||
uint32_t device_id_length;
|
||||
uint8_t device_id[ODK_DEVICE_ID_LEN_MAX];
|
||||
} ODK_PreparedProvisioningRequest;
|
||||
} ODK_PreparedProvisioningRequestV17;
|
||||
|
||||
typedef struct {
|
||||
ODK_CoreMessage core_message;
|
||||
uint32_t device_info_length;
|
||||
uint8_t device_info[ODK_DEVICE_INFO_LEN_MAX];
|
||||
ODK_MessageCounterInfo counter_info;
|
||||
} ODK_PreparedProvisioning40Request;
|
||||
|
||||
typedef struct {
|
||||
ODK_CoreMessage core_message;
|
||||
@@ -79,12 +98,32 @@ typedef struct {
|
||||
} ODK_ParsedLicenseV16;
|
||||
|
||||
typedef struct {
|
||||
ODK_PreparedLicenseRequest request;
|
||||
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;
|
||||
} ODK_LicenseResponse;
|
||||
|
||||
typedef struct {
|
||||
ODK_PreparedLicenseRequest request;
|
||||
ODK_PreparedLicenseRequestV17 request;
|
||||
ODK_ParsedLicenseV17 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;
|
||||
@@ -95,18 +134,30 @@ typedef struct {
|
||||
} ODK_RenewalResponse;
|
||||
|
||||
typedef struct {
|
||||
ODK_PreparedProvisioningRequest request;
|
||||
ODK_CoreMessage core_message;
|
||||
ODK_ParsedProvisioning* parsed_provisioning;
|
||||
} ODK_ProvisioningResponse;
|
||||
|
||||
// Used by V16 and V17
|
||||
typedef struct {
|
||||
ODK_PreparedProvisioningRequestV17 request;
|
||||
ODK_ParsedProvisioning* parsed_provisioning;
|
||||
} ODK_ProvisioningResponseV16;
|
||||
|
||||
typedef struct {
|
||||
ODK_CoreMessage core_message;
|
||||
} ODK_Provisioning40Response;
|
||||
|
||||
// These are the sum of sizeof of each individual member of the request structs
|
||||
// without any padding added by the compiler. Make sure they get updated when
|
||||
// request structs change. Refer to test suite OdkSizeTest in
|
||||
// ../test/odk_test.cpp for validations of each of the defined request sizes.
|
||||
#define ODK_LICENSE_REQUEST_SIZE 20u
|
||||
#define ODK_LICENSE_REQUEST_SIZE 90u
|
||||
#define ODK_RENEWAL_REQUEST_SIZE 28u
|
||||
#define ODK_PROVISIONING_REQUEST_SIZE 88u
|
||||
#define ODK_PROVISIONING_REQUEST_SIZE 90u
|
||||
#define ODK_PROVISIONING40_REQUEST_SIZE 350u
|
||||
#define ODK_RENEWED_PROVISIONING_REQUEST_SIZE 1694u
|
||||
#define ODK_MESSAGECOUNTERINFO_SIZE 70u
|
||||
|
||||
// These are the possible timer status values.
|
||||
#define ODK_CLOCK_TIMER_STATUS_UNDEFINED 0u // Should not happen.
|
||||
|
||||
@@ -132,6 +132,18 @@ void Unpack_OEMCrypto_PrivateKeyType(ODK_Message* message,
|
||||
}
|
||||
}
|
||||
|
||||
void Unpack_OEMCrypto_TimerDelayBase(ODK_Message* message,
|
||||
OEMCrypto_TimerDelayBase* value) {
|
||||
assert(value);
|
||||
uint32_t v32 = 0;
|
||||
Unpack_uint32_t(message, &v32);
|
||||
if (v32 <= OEMCrypto_TimerDelayBase_MaxValue) {
|
||||
*value = (OEMCrypto_TimerDelayBase)v32;
|
||||
} else {
|
||||
ODK_Message_SetStatus(message, MESSAGE_STATUS_PARSE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
void Unpack_bool(ODK_Message* message, bool* value) {
|
||||
uint8_t data[4] = {0};
|
||||
UnpackBytes(message, data, sizeof(data));
|
||||
|
||||
@@ -29,6 +29,8 @@ void Unpack_OEMCrypto_LicenseType(ODK_Message* message,
|
||||
OEMCrypto_LicenseType* value);
|
||||
void Unpack_OEMCrypto_PrivateKeyType(ODK_Message* message,
|
||||
OEMCrypto_PrivateKeyType* value);
|
||||
void Unpack_OEMCrypto_TimerDelayBase(ODK_Message* message,
|
||||
OEMCrypto_TimerDelayBase* value);
|
||||
void Unpack_bool(ODK_Message* message, bool* value);
|
||||
void Unpack_uint8_t(ODK_Message* message, uint8_t* value);
|
||||
void Unpack_uint16_t(ODK_Message* message, uint16_t* value);
|
||||
|
||||
Reference in New Issue
Block a user