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

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