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:
Kyle Zhang
2022-12-16 03:21:08 +00:00
parent 4586522c07
commit 11255b7426
105 changed files with 324641 additions and 299787 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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.

View File

@@ -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));

View File

@@ -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);