OEMCrypto v17.2

Version 17.2 includes udpates to support MediaCAS. See the
CHANGELOG for full details.
This commit is contained in:
Fred Gylys-Colwell
2023-09-07 13:32:55 -07:00
parent f998d6c4ae
commit 31f24774e8
189 changed files with 6390 additions and 3411 deletions

View File

@@ -637,7 +637,7 @@ OEMCryptoResult OPKI_GenerateCertSignature(OEMCryptoSession* session,
}
NO_IGNORE_RESULT static OEMCryptoResult CheckStatusOnline(
OEMCryptoSession* session, uint32_t nonce, uint32_t control) {
OEMCryptoSession* session, uint32_t nonce, uint32_t control UNUSED) {
if (!session) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
if (session->nonce_values.nonce != nonce) {
return OEMCrypto_ERROR_INVALID_NONCE;
@@ -655,7 +655,7 @@ NO_IGNORE_RESULT static OEMCryptoResult CheckStatusOnline(
}
NO_IGNORE_RESULT static OEMCryptoResult CheckStatusOffline(
OEMCryptoSession* session, uint32_t nonce, uint32_t control) {
OEMCryptoSession* session, uint32_t nonce, uint32_t control UNUSED) {
if (!session) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
switch (OPKI_GetUsageEntryStatus(session->session_id)) {
default: /* Invalid status. */
@@ -713,6 +713,7 @@ OEMCryptoResult OPKI_InstallKey(OEMCryptoSession* session,
SymmetricKey** current_key_ptr;
uint32_t current_key_index = 0;
SymmetricKeyType key_type;
uint8_t minimum_patch_level = 0;
if (session->license_type == OEMCrypto_ContentLicense) {
if (key_data_length != KEY_SIZE_128 && key_data_length != KEY_SIZE_256) {
/* Generic crypto allows both key sizes. */
@@ -815,9 +816,9 @@ OEMCryptoResult OPKI_InstallKey(OEMCryptoSession* session,
result = OEMCrypto_ERROR_UNKNOWN_FAILURE;
goto cleanup;
}
uint8_t minimum_patch_level = (current_key->key_control_block.control_bits &
CONTROL_SECURITY_PATCH_LEVEL_MASK) >>
CONTROL_SECURITY_PATCH_LEVEL_SHIFT;
minimum_patch_level = (current_key->key_control_block.control_bits &
CONTROL_SECURITY_PATCH_LEVEL_MASK) >>
CONTROL_SECURITY_PATCH_LEVEL_SHIFT;
if (minimum_patch_level > OEMCrypto_Security_Patch_Level()) {
LOGE(
"Security patch level doesn't meet the minimum requirement. Current: "
@@ -1093,6 +1094,52 @@ static bool IsHdcpLevelSufficient(OEMCrypto_HDCP_Capability required,
return current_priority >= required_priority;
}
OEMCryptoResult OPKI_CheckKeyControlBlock(const KeyControlBlock* control,
uint32_t use_type,
OPK_OutputBuffer_Type buffer_type) {
RETURN_INVALID_CONTEXT_IF_NULL(control);
if (use_type && (!(control->control_bits & use_type))) {
/* Could not use this key for the given use type. */
LOGE("Could not use this key for the given use type: %u", use_type);
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
if (control->control_bits & CONTROL_DATA_PATH_SECURE) {
if (!WTPI_IsClosedPlatform() &&
buffer_type == OPK_CLEAR_INSECURE_OUTPUT_BUFFER) {
return OEMCrypto_ERROR_DECRYPT_FAILED;
}
}
const OEMCrypto_HDCP_Capability capability = WTPI_CurrentHDCPCapability();
if (capability != HDCP_NO_DIGITAL_OUTPUT &&
(control->control_bits & CONTROL_HDCP_REQUIRED)) {
/* Check to see if HDCP requirements are satisfied. */
const uint8_t required_hdcp =
(control->control_bits & CONTROL_HDCP_VERSION_MASK) >>
CONTROL_HDCP_VERSION_SHIFT;
if (!IsHdcpLevelSufficient(required_hdcp, capability) ||
capability == HDCP_NONE) {
return OEMCrypto_ERROR_INSUFFICIENT_HDCP;
}
}
/* Disable the analog outputs, if required. */
if (control->control_bits & CONTROL_DISABLE_ANALOG_OUTPUT) {
if (WTPI_IsAnalogDisplayActive() && !WTPI_DisableAnalogDisplay()) {
LOGE("Analog output could not be disabled");
return OEMCrypto_ERROR_ANALOG_OUTPUT;
}
}
/* If CGMS-A is required, either it must be active or analog output must be
disabled. */
if (control->control_bits & CONTROL_CGMS_MASK) {
if (!WTPI_IsCGMS_AActive() && WTPI_IsAnalogDisplayActive() &&
!WTPI_DisableAnalogDisplay()) {
LOGE("CGMS must be active if analog output is active");
return OEMCrypto_ERROR_ANALOG_OUTPUT;
}
}
return OEMCrypto_SUCCESS;
}
OEMCryptoResult OPKI_CheckCurrentContentKeyUsage(
OEMCryptoSession* session, OEMCryptoEntitledKeySession* key_session,
uint32_t use_type, OPK_OutputBuffer_Type buffer_type) {
@@ -1118,46 +1165,7 @@ OEMCryptoResult OPKI_CheckCurrentContentKeyUsage(
result = OPKI_GetKeyControlBlock(current_content_key, session, key_session,
&control);
if (result != OEMCrypto_SUCCESS) return result;
if (use_type && (!(control.control_bits & use_type))) {
/* Could not use this key for the given use type. */
LOGE("Could not use this key for the given use type: %u", use_type);
return OEMCrypto_ERROR_INVALID_CONTEXT;
}
if (control.control_bits & CONTROL_DATA_PATH_SECURE) {
if (!WTPI_IsClosedPlatform() &&
buffer_type == OPK_CLEAR_INSECURE_OUTPUT_BUFFER) {
return OEMCrypto_ERROR_DECRYPT_FAILED;
}
}
const OEMCrypto_HDCP_Capability capability = WTPI_CurrentHDCPCapability();
if (capability != HDCP_NO_DIGITAL_OUTPUT &&
(control.control_bits & CONTROL_HDCP_REQUIRED)) {
/* Check to see if HDCP requirements are satisfied. */
const uint8_t required_hdcp =
(control.control_bits & CONTROL_HDCP_VERSION_MASK) >>
CONTROL_HDCP_VERSION_SHIFT;
if (!IsHdcpLevelSufficient(required_hdcp, capability) ||
capability == HDCP_NONE) {
return OEMCrypto_ERROR_INSUFFICIENT_HDCP;
}
}
/* Disable the analog outputs, if required. */
if (control.control_bits & CONTROL_DISABLE_ANALOG_OUTPUT) {
if (WTPI_IsAnalogDisplayActive() && !WTPI_DisableAnalogDisplay()) {
LOGE("Analog output could not be disabled");
return OEMCrypto_ERROR_ANALOG_OUTPUT;
}
}
/* If CGMS-A is required, either it must be active or analog output must be
disabled. */
if (control.control_bits & CONTROL_CGMS_MASK) {
if (!WTPI_IsCGMS_AActive() && WTPI_IsAnalogDisplayActive() &&
!WTPI_DisableAnalogDisplay()) {
LOGE("CGMS must be active if analog output is active");
return OEMCrypto_ERROR_ANALOG_OUTPUT;
}
}
return OEMCrypto_SUCCESS;
return OPKI_CheckKeyControlBlock(&control, use_type, buffer_type);
}
OEMCryptoResult OPKI_UpdatePlaybackTimeAndUsageEntryStatus(
@@ -1271,12 +1279,14 @@ NO_IGNORE_RESULT static OEMCryptoResult ComputeDecryptHash(
return result;
}
}
result = WTPI_Crc32Cont_OutputBuffer(
output_buffer, current_offset, subsample_length,
decrypt_hash->current_hash, &decrypt_hash->current_hash);
if (result != OEMCrypto_SUCCESS) {
LOGE("Failed to compute CRC32 with result: %u", result);
return result;
if (subsample_length > 0) {
result = WTPI_Crc32Cont_OutputBuffer(
output_buffer, current_offset, subsample_length,
decrypt_hash->current_hash, &decrypt_hash->current_hash);
if (result != OEMCrypto_SUCCESS) {
LOGE("Failed to compute CRC32 with result: %u", result);
return result;
}
}
if (OEMCrypto_LastSubsample & subsample->subsample_flags) {
if (decrypt_hash->current_hash != decrypt_hash->given_hash) {