Version 17.1
Updates to OEMCrypto API and OPK reference implementation.
This commit is contained in:
@@ -30,42 +30,31 @@ NO_IGNORE_RESULT static bool IsSupportedDrmKeyType(AsymmetricKeyType key_type) {
|
||||
return key_type == DRM_RSA_PRIVATE_KEY || key_type == DRM_ECC_PRIVATE_KEY;
|
||||
}
|
||||
|
||||
/* In OEMCrypto version 16.5 and forward, key control blocks are expected to be
|
||||
* clear. Caller ensures the pointer is not NULL. */
|
||||
NO_IGNORE_RESULT static bool IsExpectedClearKeyControlBlockVersion(
|
||||
const ODK_NonceValues* nonce_values) {
|
||||
if (nonce_values->api_major_version == 16) {
|
||||
return nonce_values->api_minor_version >= 5;
|
||||
}
|
||||
return nonce_values->api_major_version >= 17;
|
||||
}
|
||||
|
||||
OEMCryptoResult OPKI_InitializeSession(OEMCryptoSession* session,
|
||||
OEMCrypto_SESSION session_id) {
|
||||
if (session == NULL) return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
session->session_id = session_id;
|
||||
session->state = SESSION_INVALID;
|
||||
session->drm_private_key = NULL;
|
||||
session->prov40_oem_private_key = NULL;
|
||||
session->mac_key_client = NULL;
|
||||
session->mac_key_server = NULL;
|
||||
session->encryption_key = NULL;
|
||||
session->refresh_valid = false;
|
||||
session->license_type = OEMCrypto_ContentLicense;
|
||||
session->current_content_key_index = CONTENT_KEYS_PER_SESSION;
|
||||
for (int i = 0; i < CONTENT_KEYS_PER_SESSION; i++) {
|
||||
session->content_keys[i] = NULL;
|
||||
}
|
||||
session->num_content_keys = 0;
|
||||
for (int i = 0; i < ENTITLEMENT_KEYS_PER_SESSION; i++) {
|
||||
session->entitlement_keys[i] = NULL;
|
||||
}
|
||||
session->num_entitlement_keys = 0;
|
||||
session->valid_srm_version = false;
|
||||
session->timer_start = 0;
|
||||
session->decrypt_hash.compute_hash = false;
|
||||
session->decrypt_hash.current_hash = 0;
|
||||
session->decrypt_hash.given_hash = 0;
|
||||
session->decrypt_hash.current_frame_number = 0;
|
||||
session->decrypt_hash.bad_frame_number = 0;
|
||||
session->decrypt_hash.hash_error = OEMCrypto_SUCCESS;
|
||||
session->allowed_schemes = kSign_RSASSA_PSS;
|
||||
session->prov40_oem_allowed_schemes = kSign_RSASSA_PSS;
|
||||
session->decrypt_started = false;
|
||||
session->nonce_created = false;
|
||||
session->request_signed = false;
|
||||
session->response_loaded = false;
|
||||
memset(session->license_request_hash, 0, ODK_SHA256_HASH_SIZE);
|
||||
RETURN_INVALID_CONTEXT_IF_NULL(session);
|
||||
*session = (OEMCryptoSession){
|
||||
.session_id = session_id,
|
||||
.state = SESSION_INVALID,
|
||||
.license_type = OEMCrypto_ContentLicense,
|
||||
.current_content_key_index = CONTENT_KEYS_PER_SESSION,
|
||||
.decrypt_hash =
|
||||
(DecryptHash){
|
||||
.hash_error = OEMCrypto_SUCCESS,
|
||||
},
|
||||
.allowed_schemes = kSign_RSASSA_PSS,
|
||||
.prov40_oem_allowed_schemes = kSign_RSASSA_PSS,
|
||||
};
|
||||
OEMCryptoResult result = ODK_InitializeSessionValues(
|
||||
&session->timer_limits, &session->clock_values, &session->nonce_values,
|
||||
API_MAJOR_VERSION, session->session_id);
|
||||
@@ -614,7 +603,7 @@ OEMCryptoResult OPKI_GenerateCertSignature(OEMCryptoSession* session,
|
||||
}
|
||||
switch (signature_type) {
|
||||
case CERT_SIGNATURE_OEM:
|
||||
// TODO(b/180530495): implement this.
|
||||
// TODO(b/225216277): implement this.
|
||||
// return SignMessageWithOEMPrivateKey(message, message_length, signature,
|
||||
// signature_length);
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
@@ -715,8 +704,7 @@ OEMCryptoResult OPKI_InstallKey(OEMCryptoSession* session,
|
||||
const uint8_t* key_control_iv) {
|
||||
if (session == NULL || key_id == NULL || key_id_length == 0 ||
|
||||
key_id_length > KEY_ID_MAX_SIZE || key_data == NULL ||
|
||||
key_data_length == 0 || key_data_iv == NULL || key_control == NULL ||
|
||||
key_control_iv == NULL) {
|
||||
key_data_length == 0 || key_data_iv == NULL || key_control == NULL) {
|
||||
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
||||
}
|
||||
uint8_t raw_key_control[KEY_CONTROL_SIZE];
|
||||
@@ -772,7 +760,23 @@ OEMCryptoResult OPKI_InstallKey(OEMCryptoSession* session,
|
||||
result = OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
goto cleanup;
|
||||
}
|
||||
if (CheckApiVersionAtMost(&session->nonce_values, 16, 4)) {
|
||||
/* To address backwards compatibility issues with a v16.x server SDK bug, the
|
||||
* exact rules for determining whether a KCB is encrypted or clear have
|
||||
* changed.
|
||||
*
|
||||
* Original behavior:
|
||||
* - Version <= 16.4.x --> KCB encrypted
|
||||
* - Version >= 16.5.x --> KCB clear
|
||||
* New behavior:
|
||||
* - No KCB IV --> KCB clear
|
||||
* - KCB IV --> KCB encrypted
|
||||
*/
|
||||
if (key_control_iv != NULL) {
|
||||
if (IsExpectedClearKeyControlBlockVersion(&session->nonce_values)) {
|
||||
LOGW("Unexpected encrypted KCB: response_odk_version = %u.%u",
|
||||
session->nonce_values.api_major_version,
|
||||
session->nonce_values.api_minor_version);
|
||||
}
|
||||
/* We use the first 128 bits regardless of the license type to decrypt the
|
||||
key control. */
|
||||
result = WTPI_C1_AESCBCDecrypt(current_key->key_handle, KEY_SIZE_128,
|
||||
@@ -784,6 +788,11 @@ OEMCryptoResult OPKI_InstallKey(OEMCryptoSession* session,
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
if (!IsExpectedClearKeyControlBlockVersion(&session->nonce_values)) {
|
||||
LOGW("Unexpected clear KCB: response_odk_version = %u.%u",
|
||||
session->nonce_values.api_major_version,
|
||||
session->nonce_values.api_minor_version);
|
||||
}
|
||||
memcpy(raw_key_control, key_control, KEY_CONTROL_SIZE);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user