Source release 18.1.0

This commit is contained in:
John "Juce" Bruce
2023-06-23 15:45:08 -07:00
parent 2baa7c6e2b
commit b2c35151ad
2074 changed files with 196004 additions and 427059 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 */
@@ -31,7 +31,7 @@ static OEMCryptoResult ODK_PrepareRequest(
/* The core message should be at the beginning of the buffer, and with a
* shorter length. */
if (sizeof(ODK_CoreMessage) > prepared_request_buffer_length) {
if (ODK_CORE_MESSAGE_SIZE > prepared_request_buffer_length) {
return ODK_ERROR_CORE_MESSAGE;
}
ODK_CoreMessage* core_message = (ODK_CoreMessage*)prepared_request_buffer;
@@ -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,68 +340,14 @@ 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};
Unpack_ODK_LicenseResponseV16(&msg, &license_response_v16);
if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK ||
ODK_Message_GetOffset(&msg) != core_message_length) {
return ODK_ERROR_CORE_MESSAGE;
}
Unpack_ODK_LicenseResponse(&msg, &license_response);
// Need to manually set parsed_license fields to
// license_response_v16.parsed_license field values since
// license_response_v16 is no longer a pointer so parsed_license doesn't get
// updated during the unpacking.
parsed_license->enc_mac_keys_iv =
license_response_v16.parsed_license.enc_mac_keys_iv;
parsed_license->enc_mac_keys =
license_response_v16.parsed_license.enc_mac_keys;
parsed_license->pst = license_response_v16.parsed_license.pst;
parsed_license->srm_restriction_data =
license_response_v16.parsed_license.srm_restriction_data;
parsed_license->license_type =
license_response_v16.parsed_license.license_type;
parsed_license->nonce_required =
license_response_v16.parsed_license.nonce_required;
parsed_license->timer_limits =
license_response_v16.parsed_license.timer_limits;
parsed_license->key_array_length =
license_response_v16.parsed_license.key_array_length;
uint32_t i;
for (i = 0; i < parsed_license->key_array_length; i++) {
parsed_license->key_array[i] =
license_response_v16.parsed_license.key_array[i];
}
// Set fields not used in V16 to default values.
parsed_license->watermarking = 0;
// 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;
parsed_license->dtcp2_required.cmi_descriptor_0.length = 1;
parsed_license->dtcp2_required.cmi_descriptor_0.data = 0;
parsed_license->dtcp2_required.cmi_descriptor_1.id = 1;
parsed_license->dtcp2_required.cmi_descriptor_1.extension = 0;
parsed_license->dtcp2_required.cmi_descriptor_1.length = 3;
parsed_license->dtcp2_required.cmi_descriptor_1.data[0] = 0;
parsed_license->dtcp2_required.cmi_descriptor_1.data[1] = 0;
parsed_license->dtcp2_required.cmi_descriptor_1.data[2] = 0;
parsed_license->dtcp2_required.cmi_descriptor_2.id = 2;
parsed_license->dtcp2_required.cmi_descriptor_2.extension = 0;
parsed_license->dtcp2_required.cmi_descriptor_2.length = 3;
parsed_license->dtcp2_required.cmi_descriptor_2.data[0] = 0;
parsed_license->dtcp2_required.cmi_descriptor_2.data[1] = 0;
parsed_license->dtcp2_required.cmi_descriptor_2.data[2] = 0;
license_response.request = license_response_v16.request;
} else {
Unpack_ODK_LicenseResponse(&msg, &license_response);
if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK ||
ODK_Message_GetOffset(&msg) != core_message_length) {
return ODK_ERROR_CORE_MESSAGE;
}
if (ODK_Message_GetStatus(&msg) != MESSAGE_STATUS_OK ||
ODK_Message_GetOffset(&msg) != core_message_length) {
return ODK_ERROR_CORE_MESSAGE;
}
/* If the license has a provider session token (pst), then OEMCrypto should
@@ -382,26 +365,38 @@ 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;
/* Start the rental clock if not already started for reloading an offline
* license without a nonce. */
if (!parsed_license->nonce_required &&
clock_values->time_of_license_request_signed == 0) {
clock_values->time_of_license_request_signed = system_time_seconds;
}
}
bool license_load =
(parsed_license->renewal_delay_base == OEMCrypto_License_Load);
*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 +408,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 +449,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 +457,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;
}