Merge OEMCrypto KDF and usage functions
Since KDF functions are only used right before specific functions, this merges them to simplify internal state within OEMCrypto. Fixes: 299527712 Change-Id: I426cfcdc102bd73cf65cd809b213da2474f44b34
This commit is contained in:
committed by
Robert Shih
parent
b04fda2908
commit
488a4647db
@@ -125,6 +125,7 @@ class CertificateProvisioning {
|
||||
std::unique_ptr<CryptoSession> crypto_session_;
|
||||
CdmCertificateType cert_type_;
|
||||
std::unique_ptr<ServiceCertificate> service_certificate_;
|
||||
std::string request_;
|
||||
// The wrapped private key in provisioning 4 generated by calling
|
||||
// GenerateCertificateKeyPair. It will be saved to file system if a valid
|
||||
// response is received.
|
||||
|
||||
@@ -24,13 +24,6 @@ class ContentKeySession : public KeySession {
|
||||
|
||||
KeySessionType Type() override { return kDefault; }
|
||||
|
||||
// Generate Derived Keys for ContentKeySession
|
||||
OEMCryptoResult GenerateDerivedKeys(const std::string& message) override;
|
||||
|
||||
// Generate Derived Keys (from session key) for ContentKeySession
|
||||
OEMCryptoResult GenerateDerivedKeys(const std::string& message,
|
||||
const std::string& session_key) override;
|
||||
|
||||
// Load Keys for ContentKeySession
|
||||
OEMCryptoResult LoadKeys(const std::string& message,
|
||||
const std::string& signature,
|
||||
|
||||
@@ -159,7 +159,9 @@ class CryptoSession {
|
||||
OEMCrypto_SignatureHashAlgorithm& algorithm);
|
||||
virtual CdmResponseType UseSecondaryKey(bool dual_key);
|
||||
// V16 licenses.
|
||||
virtual CdmResponseType LoadLicense(const std::string& signed_message,
|
||||
virtual CdmResponseType LoadLicense(const std::string& context,
|
||||
const std::string& session_key,
|
||||
const std::string& signed_message,
|
||||
const std::string& core_message,
|
||||
const std::string& signature,
|
||||
CdmLicenseKeyType key_type);
|
||||
@@ -178,17 +180,19 @@ class CryptoSession {
|
||||
const std::vector<CryptoKey>& key_array);
|
||||
|
||||
// Provisioning request/responses
|
||||
virtual CdmResponseType GenerateDerivedKeys(const std::string& message);
|
||||
virtual CdmResponseType GenerateDerivedKeys(const std::string& message,
|
||||
const std::string& session_key);
|
||||
virtual CdmResponseType PrepareAndSignProvisioningRequest(
|
||||
const std::string& message, std::string* core_message,
|
||||
std::string* signature, bool& should_specify_algorithm,
|
||||
OEMCrypto_SignatureHashAlgorithm& algorithm);
|
||||
virtual CdmResponseType LoadProvisioning(const std::string& signed_message,
|
||||
virtual CdmResponseType LoadProvisioning(const std::string& request,
|
||||
const std::string& signed_message,
|
||||
const std::string& core_message,
|
||||
const std::string& signature,
|
||||
std::string* wrapped_private_key);
|
||||
virtual CdmResponseType LoadProvisioningCast(
|
||||
const std::string& derivation_key, const std::string& request,
|
||||
const std::string& signed_message, const std::string& core_message,
|
||||
const std::string& signature, std::string* wrapped_private_key);
|
||||
virtual CdmResponseType LoadCertificatePrivateKey(
|
||||
const CryptoWrappedKey& private_key);
|
||||
virtual CdmResponseType GetBootCertificateChain(
|
||||
|
||||
@@ -23,9 +23,6 @@ class KeySession {
|
||||
typedef enum { kDefault, kEntitlement } KeySessionType;
|
||||
virtual ~KeySession() {}
|
||||
virtual KeySessionType Type() = 0;
|
||||
virtual OEMCryptoResult GenerateDerivedKeys(const std::string& message) = 0;
|
||||
virtual OEMCryptoResult GenerateDerivedKeys(
|
||||
const std::string& message, const std::string& session_key) = 0;
|
||||
virtual OEMCryptoResult LoadKeys(const std::string& message,
|
||||
const std::string& signature,
|
||||
const std::string& mac_key_iv,
|
||||
|
||||
@@ -105,16 +105,18 @@ class CdmLicense {
|
||||
video_widevine::LicenseRequest* license_request);
|
||||
|
||||
CdmResponseType HandleContentKeyResponse(
|
||||
bool is_restore, const std::string& msg, const std::string& core_message,
|
||||
const std::string& signature, const std::vector<CryptoKey>& key_array,
|
||||
bool is_restore, const std::string& session_key, const std::string& msg,
|
||||
const std::string& core_message, const std::string& signature,
|
||||
const std::vector<CryptoKey>& key_array,
|
||||
const video_widevine::License& license);
|
||||
|
||||
// HandleEntitlementKeyResponse loads the entitlement keys in |key_array| into
|
||||
// the crypto session. In addition, it also extracts content keys from
|
||||
// |wrapped_keys_| and loads them for use.
|
||||
CdmResponseType HandleEntitlementKeyResponse(
|
||||
bool is_restore, const std::string& msg, const std::string& core_message,
|
||||
const std::string& signature, const std::vector<CryptoKey>& key_array,
|
||||
bool is_restore, const std::string& session_key, const std::string& msg,
|
||||
const std::string& core_message, const std::string& signature,
|
||||
const std::vector<CryptoKey>& key_array,
|
||||
const video_widevine::License& license);
|
||||
|
||||
// Prepare to reload a key update message. Some special code is needed to work
|
||||
|
||||
@@ -261,6 +261,7 @@ CdmResponseType CertificateProvisioning::GetProvisioningRequestInternal(
|
||||
status = crypto_session_->PrepareAndSignProvisioningRequest(
|
||||
serialized_message, &core_message, &request_signature,
|
||||
should_specify_algorithm, oec_algorithm);
|
||||
request_ = serialized_message;
|
||||
|
||||
if (status != NO_ERROR) {
|
||||
LOGE("Failed to prepare provisioning request: status = %d",
|
||||
@@ -488,6 +489,7 @@ CdmResponseType CertificateProvisioning::GetProvisioning40RequestInternal(
|
||||
} else {
|
||||
*request = std::move(serialized_request);
|
||||
}
|
||||
request_ = serialized_message;
|
||||
return CdmResponseType(NO_ERROR);
|
||||
}
|
||||
|
||||
@@ -574,20 +576,14 @@ CdmResponseType CertificateProvisioning::HandleProvisioning40Response(
|
||||
return status;
|
||||
}
|
||||
|
||||
status = crypto_session_->GenerateDerivedKeys(
|
||||
provisioning_request_message_, signed_response.session_key());
|
||||
if (status != NO_ERROR) {
|
||||
LOGE("Failed to generate derived keys.");
|
||||
return status;
|
||||
}
|
||||
|
||||
// Get wrapped private key for cast cert
|
||||
CryptoWrappedKey cast_cert_private_key;
|
||||
const std::string& signature = signed_response.signature();
|
||||
const std::string& core_message = signed_response.oemcrypto_core_message();
|
||||
status = crypto_session_->LoadProvisioning(response_message, core_message,
|
||||
signature,
|
||||
&cast_cert_private_key.key());
|
||||
status = crypto_session_->LoadProvisioningCast(
|
||||
signed_response.session_key(), provisioning_request_message_,
|
||||
response_message, core_message, signature,
|
||||
&cast_cert_private_key.key());
|
||||
if (status != NO_ERROR) {
|
||||
LOGE("Failed to generate wrapped key for cast cert.");
|
||||
return status;
|
||||
@@ -728,7 +724,7 @@ CdmResponseType CertificateProvisioning::HandleProvisioningResponse(
|
||||
|
||||
CryptoWrappedKey private_key;
|
||||
const CdmResponseType status = crypto_session_->LoadProvisioning(
|
||||
signed_message, core_message, signature, &private_key.key());
|
||||
request_, signed_message, core_message, signature, &private_key.key());
|
||||
|
||||
if (status != NO_ERROR) {
|
||||
LOGE("LoadProvisioning failed: status = %d", static_cast<int>(status));
|
||||
|
||||
@@ -11,59 +11,6 @@
|
||||
|
||||
namespace wvcdm {
|
||||
|
||||
// Generate Derived Keys for ContentKeySession
|
||||
OEMCryptoResult ContentKeySession::GenerateDerivedKeys(
|
||||
const std::string& message) {
|
||||
std::string mac_deriv_message;
|
||||
std::string enc_deriv_message;
|
||||
GenerateMacContext(message, &mac_deriv_message);
|
||||
GenerateEncryptContext(message, &enc_deriv_message);
|
||||
|
||||
LOGV("Generating derived keys: id = %u", oec_session_id_);
|
||||
OEMCryptoResult sts;
|
||||
M_TIME(sts = OEMCrypto_GenerateDerivedKeys(
|
||||
oec_session_id_,
|
||||
reinterpret_cast<const uint8_t*>(mac_deriv_message.data()),
|
||||
mac_deriv_message.size(),
|
||||
reinterpret_cast<const uint8_t*>(enc_deriv_message.data()),
|
||||
enc_deriv_message.size()),
|
||||
metrics_, oemcrypto_generate_derived_keys_, sts);
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
LOGE("OEMCrypto_GenerateDerivedKeys failed: status = %d",
|
||||
static_cast<int>(sts));
|
||||
}
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
// Generate Derived Keys (from session key) for ContentKeySession
|
||||
OEMCryptoResult ContentKeySession::GenerateDerivedKeys(
|
||||
const std::string& message, const std::string& session_key) {
|
||||
std::string mac_deriv_message;
|
||||
std::string enc_deriv_message;
|
||||
GenerateMacContext(message, &mac_deriv_message);
|
||||
GenerateEncryptContext(message, &enc_deriv_message);
|
||||
|
||||
LOGV("Generating derived keys from session key: id = %u", oec_session_id_);
|
||||
OEMCryptoResult sts;
|
||||
M_TIME(
|
||||
sts = OEMCrypto_DeriveKeysFromSessionKey(
|
||||
oec_session_id_, reinterpret_cast<const uint8_t*>(session_key.data()),
|
||||
session_key.size(),
|
||||
reinterpret_cast<const uint8_t*>(mac_deriv_message.data()),
|
||||
mac_deriv_message.size(),
|
||||
reinterpret_cast<const uint8_t*>(enc_deriv_message.data()),
|
||||
enc_deriv_message.size()),
|
||||
metrics_, oemcrypto_derive_keys_from_session_key_, sts);
|
||||
|
||||
if (OEMCrypto_SUCCESS != sts) {
|
||||
LOGE("OEMCrypto_DeriveKeysFromSessionKey failed: status = %d",
|
||||
static_cast<int>(sts));
|
||||
}
|
||||
|
||||
return sts;
|
||||
}
|
||||
|
||||
// Load Keys for ContentKeySession
|
||||
OEMCryptoResult ContentKeySession::LoadKeys(
|
||||
const std::string& message, const std::string& signature,
|
||||
|
||||
@@ -257,38 +257,6 @@ OEMCrypto_Substring GetSubstring(const std::string& message,
|
||||
return substring;
|
||||
}
|
||||
|
||||
void GenerateMacContext(const std::string& input_context,
|
||||
std::string* deriv_context) {
|
||||
if (!deriv_context) {
|
||||
LOGE("Output parameter |deriv_context| not provided");
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string kSigningKeyLabel = "AUTHENTICATION";
|
||||
const size_t kSigningKeySizeBits = wvcdm::MAC_KEY_SIZE * 8;
|
||||
|
||||
deriv_context->assign(kSigningKeyLabel);
|
||||
deriv_context->append(1, '\0');
|
||||
deriv_context->append(input_context);
|
||||
deriv_context->append(wvutil::EncodeUint32(kSigningKeySizeBits * 2));
|
||||
}
|
||||
|
||||
void GenerateEncryptContext(const std::string& input_context,
|
||||
std::string* deriv_context) {
|
||||
if (!deriv_context) {
|
||||
LOGE("Output parameter |deriv_context| not provided");
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string kEncryptionKeyLabel = "ENCRYPTION";
|
||||
const size_t kEncryptionKeySizeBits = wvcdm::CONTENT_KEY_SIZE * 8;
|
||||
|
||||
deriv_context->assign(kEncryptionKeyLabel);
|
||||
deriv_context->append(1, '\0');
|
||||
deriv_context->append(input_context);
|
||||
deriv_context->append(wvutil::EncodeUint32(kEncryptionKeySizeBits));
|
||||
}
|
||||
|
||||
OEMCryptoCipherMode ToOEMCryptoCipherMode(CdmCipherMode cipher_mode) {
|
||||
return cipher_mode == kCipherModeCtr ? OEMCrypto_CipherMode_CENC
|
||||
: OEMCrypto_CipherMode_CBCS;
|
||||
@@ -1122,7 +1090,9 @@ CdmResponseType CryptoSession::UseSecondaryKey(bool /* dual_key */) {
|
||||
}
|
||||
#endif
|
||||
|
||||
CdmResponseType CryptoSession::LoadLicense(const std::string& signed_message,
|
||||
CdmResponseType CryptoSession::LoadLicense(const std::string& context,
|
||||
const std::string& session_key,
|
||||
const std::string& signed_message,
|
||||
const std::string& core_message,
|
||||
const std::string& signature,
|
||||
CdmLicenseKeyType key_type) {
|
||||
@@ -1138,6 +1108,9 @@ CdmResponseType CryptoSession::LoadLicense(const std::string& signed_message,
|
||||
|
||||
M_TIME(sts = OEMCrypto_LoadLicense(
|
||||
oec_session_id_,
|
||||
reinterpret_cast<const uint8_t*>(context.data()), context.size(),
|
||||
reinterpret_cast<const uint8_t*>(session_key.data()),
|
||||
session_key.size(),
|
||||
reinterpret_cast<const uint8_t*>(combined_message.data()),
|
||||
combined_message.size(), core_message.size(),
|
||||
reinterpret_cast<const uint8_t*>(signature.data()),
|
||||
@@ -1264,8 +1237,6 @@ CdmResponseType CryptoSession::PrepareAndSignProvisioningRequest(
|
||||
OEMCryptoResult sts;
|
||||
if (pre_provision_token_type_ == kClientTokenKeybox) {
|
||||
should_specify_algorithm = false;
|
||||
const CdmResponseType status = GenerateDerivedKeys(message);
|
||||
if (status != NO_ERROR) return status;
|
||||
} else if (pre_provision_token_type_ == kClientTokenOemCert) {
|
||||
should_specify_algorithm = true;
|
||||
WithOecSessionLock("LoadOEMPrivateKey", [&] {
|
||||
@@ -1708,26 +1679,6 @@ CdmResponseType CryptoSession::SelectKey(const std::string& key_id,
|
||||
}
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::GenerateDerivedKeys(const std::string& message) {
|
||||
OEMCryptoResult sts;
|
||||
WithOecSessionLock("GenerateDerivedKeys without session_key",
|
||||
[&] { sts = key_session_->GenerateDerivedKeys(message); });
|
||||
|
||||
return MapOEMCryptoResult(sts, GENERATE_DERIVED_KEYS_ERROR_2,
|
||||
"GenerateDerivedKeys");
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::GenerateDerivedKeys(
|
||||
const std::string& message, const std::string& session_key) {
|
||||
OEMCryptoResult sts;
|
||||
WithOecSessionLock("GenerateDerivedKeys with session_key", [&] {
|
||||
sts = key_session_->GenerateDerivedKeys(message, session_key);
|
||||
});
|
||||
|
||||
return MapOEMCryptoResult(sts, GENERATE_DERIVED_KEYS_ERROR,
|
||||
"GenerateDerivedKeys");
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::GenerateRsaSignature(const std::string& message,
|
||||
std::string* signature,
|
||||
RSA_Padding_Scheme scheme) {
|
||||
@@ -2209,8 +2160,9 @@ bool CryptoSession::SetDestinationBufferType() {
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::LoadProvisioning(
|
||||
const std::string& signed_message, const std::string& core_message,
|
||||
const std::string& signature, std::string* wrapped_private_key) {
|
||||
const std::string& request, const std::string& signed_message,
|
||||
const std::string& core_message, const std::string& signature,
|
||||
std::string* wrapped_private_key) {
|
||||
LOGV("Loading provisioning certificate: id = %u", oec_session_id_);
|
||||
if (wrapped_private_key == nullptr) {
|
||||
LOGE("Missing wrapped |wrapped_private_key|");
|
||||
@@ -2224,6 +2176,7 @@ CdmResponseType CryptoSession::LoadProvisioning(
|
||||
WithOecSessionLock("LoadProvisioning Attempt 1", [&] {
|
||||
M_TIME(status = OEMCrypto_LoadProvisioning(
|
||||
oec_session_id_,
|
||||
reinterpret_cast<const uint8_t*>(request.data()), request.size(),
|
||||
reinterpret_cast<const uint8_t*>(combined_message.data()),
|
||||
combined_message.size(), core_message.size(),
|
||||
reinterpret_cast<const uint8_t*>(signature.data()),
|
||||
@@ -2241,6 +2194,7 @@ CdmResponseType CryptoSession::LoadProvisioning(
|
||||
WithOecSessionLock("LoadProvisioning Attempt 2", [&] {
|
||||
M_TIME(status = OEMCrypto_LoadProvisioning(
|
||||
oec_session_id_,
|
||||
reinterpret_cast<const uint8_t*>(request.data()), request.size(),
|
||||
reinterpret_cast<const uint8_t*>(combined_message.data()),
|
||||
combined_message.size(), core_message.size(),
|
||||
reinterpret_cast<const uint8_t*>(signature.data()),
|
||||
@@ -2259,6 +2213,64 @@ CdmResponseType CryptoSession::LoadProvisioning(
|
||||
"LoadProvisioning");
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::LoadProvisioningCast(
|
||||
const std::string& derivation_key, const std::string& request,
|
||||
const std::string& signed_message, const std::string& core_message,
|
||||
const std::string& signature, std::string* wrapped_private_key) {
|
||||
LOGV("Loading provisioning certificate: id = %u", oec_session_id_);
|
||||
if (wrapped_private_key == nullptr) {
|
||||
LOGE("Missing wrapped |wrapped_private_key|");
|
||||
return CdmResponseType(PARAMETER_NULL);
|
||||
}
|
||||
|
||||
const std::string combined_message = core_message + signed_message;
|
||||
// Round 1, get the size of the wrapped private key buffer.
|
||||
size_t wrapped_private_key_length = 0;
|
||||
OEMCryptoResult status;
|
||||
WithOecSessionLock("LoadProvisioningCast Attempt 1", [&] {
|
||||
M_TIME(status = OEMCrypto_LoadProvisioningCast(
|
||||
oec_session_id_,
|
||||
reinterpret_cast<const uint8_t*>(derivation_key.data()),
|
||||
derivation_key.size(),
|
||||
reinterpret_cast<const uint8_t*>(request.data()), request.size(),
|
||||
reinterpret_cast<const uint8_t*>(combined_message.data()),
|
||||
combined_message.size(), core_message.size(),
|
||||
reinterpret_cast<const uint8_t*>(signature.data()),
|
||||
signature.size(), nullptr, &wrapped_private_key_length),
|
||||
metrics_, oemcrypto_load_provisioning_, status);
|
||||
});
|
||||
|
||||
if (status != OEMCrypto_ERROR_SHORT_BUFFER) {
|
||||
return MapOEMCryptoResult(status, LOAD_PROVISIONING_ERROR,
|
||||
"LoadProvisioningCast");
|
||||
}
|
||||
|
||||
wrapped_private_key->resize(wrapped_private_key_length);
|
||||
|
||||
WithOecSessionLock("LoadProvisioningCast Attempt 2", [&] {
|
||||
M_TIME(status = OEMCrypto_LoadProvisioningCast(
|
||||
oec_session_id_,
|
||||
reinterpret_cast<const uint8_t*>(derivation_key.data()),
|
||||
derivation_key.size(),
|
||||
reinterpret_cast<const uint8_t*>(request.data()), request.size(),
|
||||
reinterpret_cast<const uint8_t*>(combined_message.data()),
|
||||
combined_message.size(), core_message.size(),
|
||||
reinterpret_cast<const uint8_t*>(signature.data()),
|
||||
signature.size(),
|
||||
reinterpret_cast<uint8_t*>(&wrapped_private_key->front()),
|
||||
&wrapped_private_key_length),
|
||||
metrics_, oemcrypto_load_provisioning_, status);
|
||||
});
|
||||
|
||||
if (status == OEMCrypto_SUCCESS) {
|
||||
wrapped_private_key->resize(wrapped_private_key_length);
|
||||
return CdmResponseType(NO_ERROR);
|
||||
}
|
||||
wrapped_private_key->clear();
|
||||
return MapOEMCryptoResult(status, LOAD_PROVISIONING_ERROR,
|
||||
"LoadProvisioningCast");
|
||||
}
|
||||
|
||||
CdmResponseType CryptoSession::GetHdcpCapabilities(HdcpCapability* current,
|
||||
HdcpCapability* max) {
|
||||
LOGV("Getting HDCP capabilities: id = %u", oec_session_id_);
|
||||
|
||||
@@ -585,10 +585,6 @@ CdmResponseType CdmLicense::HandleKeyResponse(
|
||||
LOGE("Signed response has no session keys present");
|
||||
return CdmResponseType(SESSION_KEYS_NOT_FOUND);
|
||||
}
|
||||
CdmResponseType status = crypto_session_->GenerateDerivedKeys(
|
||||
key_request_, signed_response.session_key());
|
||||
|
||||
if (status != NO_ERROR) return status;
|
||||
|
||||
// Extract mac key
|
||||
std::string mac_key_iv;
|
||||
@@ -655,18 +651,19 @@ CdmResponseType CdmLicense::HandleKeyResponse(
|
||||
}
|
||||
|
||||
// If the field is not set, it will default to false.
|
||||
status =
|
||||
CdmResponseType status =
|
||||
crypto_session_->UseSecondaryKey(signed_response.using_secondary_key());
|
||||
if (status != NO_ERROR) return status;
|
||||
|
||||
CdmResponseType resp(NO_CONTENT_KEY);
|
||||
if (kLicenseKeyTypeEntitlement == key_type) {
|
||||
resp =
|
||||
HandleEntitlementKeyResponse(is_restore, signed_message, core_message,
|
||||
signature, key_array, license);
|
||||
resp = HandleEntitlementKeyResponse(
|
||||
is_restore, signed_response.session_key(), signed_message, core_message,
|
||||
signature, key_array, license);
|
||||
} else if (kLicenseKeyTypeContent == key_type) {
|
||||
resp = HandleContentKeyResponse(is_restore, signed_message, core_message,
|
||||
signature, key_array, license);
|
||||
resp = HandleContentKeyResponse(is_restore, signed_response.session_key(),
|
||||
signed_message, core_message, signature,
|
||||
key_array, license);
|
||||
}
|
||||
return resp;
|
||||
}
|
||||
@@ -1086,15 +1083,17 @@ CdmResponseType CdmLicense::PrepareContentId(
|
||||
}
|
||||
|
||||
CdmResponseType CdmLicense::HandleContentKeyResponse(
|
||||
bool is_restore, const std::string& msg, const std::string& core_message,
|
||||
const std::string& signature, const std::vector<CryptoKey>& key_array,
|
||||
bool is_restore, const std::string& session_key, const std::string& msg,
|
||||
const std::string& core_message, const std::string& signature,
|
||||
const std::vector<CryptoKey>& key_array,
|
||||
const video_widevine::License& license) {
|
||||
if (key_array.empty()) {
|
||||
LOGE("No content keys provided");
|
||||
return CdmResponseType(NO_CONTENT_KEY);
|
||||
}
|
||||
const CdmResponseType resp = crypto_session_->LoadLicense(
|
||||
msg, core_message, signature, kLicenseKeyTypeContent);
|
||||
const CdmResponseType resp =
|
||||
crypto_session_->LoadLicense(key_request_, session_key, msg, core_message,
|
||||
signature, kLicenseKeyTypeContent);
|
||||
if (KEY_ADDED == resp) {
|
||||
loaded_keys_.clear();
|
||||
for (const CryptoKey& key : key_array) {
|
||||
@@ -1106,15 +1105,17 @@ CdmResponseType CdmLicense::HandleContentKeyResponse(
|
||||
}
|
||||
|
||||
CdmResponseType CdmLicense::HandleEntitlementKeyResponse(
|
||||
bool is_restore, const std::string& msg, const std::string& core_message,
|
||||
const std::string& signature, const std::vector<CryptoKey>& key_array,
|
||||
bool is_restore, const std::string& session_key, const std::string& msg,
|
||||
const std::string& core_message, const std::string& signature,
|
||||
const std::vector<CryptoKey>& key_array,
|
||||
const video_widevine::License& license) {
|
||||
if (key_array.empty()) {
|
||||
LOGE("No entitlement keys provided");
|
||||
return CdmResponseType(NO_CONTENT_KEY);
|
||||
}
|
||||
const CdmResponseType resp = crypto_session_->LoadLicense(
|
||||
msg, core_message, signature, kLicenseKeyTypeEntitlement);
|
||||
const CdmResponseType resp =
|
||||
crypto_session_->LoadLicense(key_request_, session_key, msg, core_message,
|
||||
signature, kLicenseKeyTypeEntitlement);
|
||||
|
||||
if (KEY_ADDED != resp) {
|
||||
return resp;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "log.h"
|
||||
#include "metrics_collections.h"
|
||||
#include "odk_structs.h"
|
||||
#include "platform.h"
|
||||
#include "properties.h"
|
||||
#include "wv_cdm_constants.h"
|
||||
#include "wv_cdm_types.h"
|
||||
@@ -56,7 +57,7 @@ typedef OEMCryptoResult (*L1_SetMaxAPIVersion_t)(uint32_t max_version);
|
||||
typedef OEMCryptoResult (*L1_Terminate_t)(void);
|
||||
typedef OEMCryptoResult (*L1_OpenSession_t)(OEMCrypto_SESSION* session);
|
||||
typedef OEMCryptoResult (*L1_CloseSession_t)(OEMCrypto_SESSION session);
|
||||
typedef OEMCryptoResult (*L1_GenerateDerivedKeys_t)(
|
||||
typedef OEMCryptoResult (*L1_GenerateDerivedKeys_V18_t)(
|
||||
OEMCrypto_SESSION session, const uint8_t* mac_key_context,
|
||||
size_t mac_key_context_length, const uint8_t* enc_key_context,
|
||||
size_t enc_key_context_length);
|
||||
@@ -76,12 +77,17 @@ typedef OEMCryptoResult (*L1_PrepAndSignRenewalRequest_t)(
|
||||
typedef OEMCryptoResult (*L1_PrepAndSignProvisioningRequest_t)(
|
||||
OEMCrypto_SESSION session, uint8_t* message, size_t message_length,
|
||||
size_t* core_message_length, uint8_t* signature, size_t* signature_length);
|
||||
typedef OEMCryptoResult (*L1_LoadLicense_t)(OEMCrypto_SESSION session,
|
||||
const uint8_t* message,
|
||||
size_t message_length,
|
||||
size_t core_message_length,
|
||||
const uint8_t* signature,
|
||||
size_t signature_length);
|
||||
typedef OEMCryptoResult (*L1_LoadLicense_t)(
|
||||
OEMCrypto_SESSION session, const uint8_t* context, size_t context_length,
|
||||
const uint8_t* derivation_key, size_t derivation_key_length,
|
||||
const uint8_t* message, size_t message_length, size_t core_message_length,
|
||||
const uint8_t* signature, size_t signature_length);
|
||||
typedef OEMCryptoResult (*L1_LoadLicense_V18_t)(OEMCrypto_SESSION session,
|
||||
const uint8_t* message,
|
||||
size_t message_length,
|
||||
size_t core_message_length,
|
||||
const uint8_t* signature,
|
||||
size_t signature_length);
|
||||
typedef OEMCryptoResult (*L1_LoadEntitledContentKeys_t)(
|
||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||
size_t key_array_length,
|
||||
@@ -144,7 +150,7 @@ typedef OEMCryptoResult (*L1_GenerateRSASignature_t)(
|
||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||
uint8_t* signature, size_t* signature_length,
|
||||
RSA_Padding_Scheme padding_scheme);
|
||||
typedef OEMCryptoResult (*L1_DeriveKeysFromSessionKey_t)(
|
||||
typedef OEMCryptoResult (*L1_DeriveKeysFromSessionKey_V18_t)(
|
||||
OEMCrypto_SESSION session, const uint8_t* enc_session_key,
|
||||
size_t enc_session_key_length, const uint8_t* mac_key_context,
|
||||
size_t mac_key_context_length, const uint8_t* enc_key_context,
|
||||
@@ -226,6 +232,17 @@ typedef OEMCryptoResult (*L1_FreeSecureBuffer_t)(
|
||||
int secure_fd);
|
||||
typedef size_t (*L1_MaximumUsageTableHeaderSize_t)();
|
||||
typedef OEMCryptoResult (*L1_LoadProvisioning_t)(
|
||||
OEMCrypto_SESSION session, const uint8_t* request, size_t request_length,
|
||||
const uint8_t* message, size_t message_length, size_t core_message_length,
|
||||
const uint8_t* signature, size_t signature_length,
|
||||
uint8_t* wrapped_private_key, size_t* wrapped_private_key_length);
|
||||
typedef OEMCryptoResult (*L1_LoadProvisioningCast_t)(
|
||||
OEMCrypto_SESSION session, const uint8_t* derivation_key,
|
||||
size_t derivation_key_length, const uint8_t* request, size_t request_length,
|
||||
const uint8_t* message, size_t message_length, size_t core_message_length,
|
||||
const uint8_t* signature, size_t signature_length,
|
||||
uint8_t* wrapped_private_key, size_t* wrapped_private_key_length);
|
||||
typedef OEMCryptoResult (*L1_LoadProvisioning_V18_t)(
|
||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||
size_t core_message_length, const uint8_t* signature,
|
||||
size_t signature_length, uint8_t* wrapped_private_key,
|
||||
@@ -328,13 +345,14 @@ struct FunctionPointers {
|
||||
L1_Terminate_t Terminate;
|
||||
L1_OpenSession_t OpenSession;
|
||||
L1_CloseSession_t CloseSession;
|
||||
L1_GenerateDerivedKeys_t GenerateDerivedKeys;
|
||||
L1_GenerateDerivedKeys_V18_t GenerateDerivedKeys_V18;
|
||||
L1_GenerateNonce_t GenerateNonce;
|
||||
L1_GenerateSignature_t GenerateSignature;
|
||||
L1_PrepAndSignLicenseRequest_t PrepAndSignLicenseRequest;
|
||||
L1_PrepAndSignRenewalRequest_t PrepAndSignRenewalRequest;
|
||||
L1_PrepAndSignProvisioningRequest_t PrepAndSignProvisioningRequest;
|
||||
L1_LoadLicense_t LoadLicense;
|
||||
L1_LoadLicense_V18_t LoadLicense_V18;
|
||||
L1_LoadEntitledContentKeys_t LoadEntitledContentKeys;
|
||||
L1_LoadEntitledContentKeys_V16_t LoadEntitledContentKeys_V16;
|
||||
L1_LoadRenewal_t LoadRenewal;
|
||||
@@ -354,7 +372,7 @@ struct FunctionPointers {
|
||||
L1_LoadDRMPrivateKey_t LoadDRMPrivateKey;
|
||||
L1_LoadTestRSAKey_t LoadTestRSAKey;
|
||||
L1_GenerateRSASignature_t GenerateRSASignature;
|
||||
L1_DeriveKeysFromSessionKey_t DeriveKeysFromSessionKey;
|
||||
L1_DeriveKeysFromSessionKey_V18_t DeriveKeysFromSessionKey_V18;
|
||||
L1_APIVersion_t APIVersion;
|
||||
L1_SecurityPatchLevel_t SecurityPatchLevel;
|
||||
L1_SecurityLevel_V16_t SecurityLevel_V16;
|
||||
@@ -392,6 +410,8 @@ struct FunctionPointers {
|
||||
L1_FreeSecureBuffer_t FreeSecureBuffer;
|
||||
L1_MaximumUsageTableHeaderSize_t MaximumUsageTableHeaderSize;
|
||||
L1_LoadProvisioning_t LoadProvisioning;
|
||||
L1_LoadProvisioningCast_t LoadProvisioningCast;
|
||||
L1_LoadProvisioning_V18_t LoadProvisioning_V18;
|
||||
L1_MinorAPIVersion_t MinorAPIVersion;
|
||||
L1_OPK_SerializationVersion_t OPK_SerializationVersion;
|
||||
L1_CreateEntitledKeySession_t CreateEntitledKeySession;
|
||||
@@ -950,8 +970,8 @@ class Adapter {
|
||||
LOOKUP_ALL(13, CreateUsageTableHeader, OEMCrypto_CreateUsageTableHeader);
|
||||
LOOKUP_ALL(13, DeactivateUsageEntry, OEMCrypto_DeactivateUsageEntry);
|
||||
LOOKUP_ALL(16, DecryptCENC_V17, OEMCrypto_DecryptCENC_V17);
|
||||
LOOKUP_ALL( 8, DeriveKeysFromSessionKey, OEMCrypto_DeriveKeysFromSessionKey);
|
||||
LOOKUP_ALL(16, GenerateDerivedKeys, OEMCrypto_GenerateDerivedKeys);
|
||||
LOOKUP_ALL( 8, DeriveKeysFromSessionKey_V18, OEMCrypto_DeriveKeysFromSessionKey_V18);
|
||||
LOOKUP_ALL(16, GenerateDerivedKeys_V18, OEMCrypto_GenerateDerivedKeys_V18);
|
||||
LOOKUP_ALL( 8, GenerateNonce, OEMCrypto_GenerateNonce);
|
||||
LOOKUP_ALL( 9, GenerateRSASignature, OEMCrypto_GenerateRSASignature);
|
||||
LOOKUP( 8, 15, GenerateSignature, OEMCrypto_GenerateSignature);
|
||||
@@ -981,7 +1001,8 @@ class Adapter {
|
||||
LOOKUP_ALL( 8, IsKeyboxOrOEMCertValid, OEMCrypto_IsKeyboxOrOEMCertValid);
|
||||
LOOKUP( 8, 15, LoadDeviceRSAKey, OEMCrypto_LoadDeviceRSAKey);
|
||||
LOOKUP_ALL(16, LoadDRMPrivateKey, OEMCrypto_LoadDRMPrivateKey);
|
||||
LOOKUP_ALL(16, LoadLicense, OEMCrypto_LoadLicense);
|
||||
LOOKUP_ALL(19, LoadLicense, OEMCrypto_LoadLicense);
|
||||
LOOKUP_ALL(16, LoadLicense_V18, OEMCrypto_LoadLicense_V18);
|
||||
LOOKUP(15, 16, LoadEntitledContentKeys_V16,OEMCrypto_LoadEntitledContentKeys_V16);
|
||||
LOOKUP_ALL(17, LoadEntitledContentKeys, OEMCrypto_LoadEntitledContentKeys);
|
||||
LOOKUP_ALL(14, LoadTestKeybox, OEMCrypto_LoadTestKeybox);
|
||||
@@ -1008,7 +1029,9 @@ class Adapter {
|
||||
LOOKUP_ALL(16, AllocateSecureBuffer, OEMCrypto_AllocateSecureBuffer);
|
||||
LOOKUP_ALL(16, FreeSecureBuffer, OEMCrypto_FreeSecureBuffer);
|
||||
LOOKUP_ALL(16, MaximumUsageTableHeaderSize, OEMCrypto_MaximumUsageTableHeaderSize);
|
||||
LOOKUP_ALL(16, LoadProvisioning, OEMCrypto_LoadProvisioning);
|
||||
LOOKUP_ALL(16, LoadProvisioning_V18, OEMCrypto_LoadProvisioning_V18);
|
||||
LOOKUP_ALL(19, LoadProvisioning, OEMCrypto_LoadProvisioning);
|
||||
LOOKUP_ALL(19, LoadProvisioningCast, OEMCrypto_LoadProvisioningCast);
|
||||
LOOKUP_ALL(16, MinorAPIVersion, OEMCrypto_MinorAPIVersion);
|
||||
LOOKUP_ALL(16, OPK_SerializationVersion, OEMCrypto_OPK_SerializationVersion);
|
||||
LOOKUP_ALL(17, CreateEntitledKeySession, OEMCrypto_CreateEntitledKeySession);
|
||||
@@ -1077,9 +1100,9 @@ class Adapter {
|
||||
level3_.Terminate = Level3_Terminate;
|
||||
level3_.OpenSession = Level3_OpenSession;
|
||||
level3_.CloseSession = Level3_CloseSession;
|
||||
level3_.GenerateDerivedKeys = Level3_GenerateDerivedKeys;
|
||||
level3_.GenerateDerivedKeys_V18 = Level3_GenerateDerivedKeys;
|
||||
level3_.GenerateNonce = Level3_GenerateNonce;
|
||||
level3_.LoadLicense = Level3_LoadLicense;
|
||||
level3_.LoadLicense_V18 = Level3_LoadLicense;
|
||||
level3_.LoadEntitledContentKeys = Level3_LoadEntitledContentKeys;
|
||||
level3_.LoadRenewal = Level3_LoadRenewal;
|
||||
level3_.QueryKeyControl = Level3_QueryKeyControl;
|
||||
@@ -1097,7 +1120,7 @@ class Adapter {
|
||||
level3_.LoadOEMPrivateKey = Level3_LoadOEMPrivateKey;
|
||||
level3_.LoadTestRSAKey = Level3_LoadTestRSAKey;
|
||||
level3_.GenerateRSASignature = Level3_GenerateRSASignature;
|
||||
level3_.DeriveKeysFromSessionKey = Level3_DeriveKeysFromSessionKey;
|
||||
level3_.DeriveKeysFromSessionKey_V18 = Level3_DeriveKeysFromSessionKey;
|
||||
level3_.APIVersion = Level3_APIVersion;
|
||||
level3_.MinorAPIVersion = Level3_MinorAPIVersion;
|
||||
level3_.SecurityPatchLevel = Level3_SecurityPatchLevel;
|
||||
@@ -1130,7 +1153,7 @@ class Adapter {
|
||||
level3_.SupportsDecryptHash = Level3_SupportsDecryptHash;
|
||||
level3_.SetDecryptHash = Level3_SetDecryptHash;
|
||||
level3_.GetHashErrorCode = Level3_GetHashErrorCode;
|
||||
level3_.LoadProvisioning = Level3_LoadProvisioning;
|
||||
level3_.LoadProvisioning_V18 = Level3_LoadProvisioning;
|
||||
level3_.PrepAndSignProvisioningRequest = Level3_PrepAndSignProvisioningRequest;
|
||||
level3_.PrepAndSignLicenseRequest = Level3_PrepAndSignLicenseRequest;
|
||||
level3_.PrepAndSignRenewalRequest = Level3_PrepAndSignRenewalRequest;
|
||||
@@ -1160,6 +1183,9 @@ class Adapter {
|
||||
level3_.Generic_Verify = Level3_Generic_Verify;
|
||||
level3_.GetSignatureHashAlgorithm = nullptr;
|
||||
level3_.EnterTestMode = nullptr;
|
||||
level3_.LoadLicense = nullptr;
|
||||
level3_.LoadProvisioning = nullptr;
|
||||
level3_.LoadProvisioningCast = nullptr;
|
||||
// clang-format on
|
||||
|
||||
level3_.version = Level3_APIVersion();
|
||||
@@ -1992,19 +2018,19 @@ extern "C" OEMCryptoResult OEMCrypto_CloseSession(OEMCrypto_SESSION session) {
|
||||
return gAdapter->CloseSession(session);
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_GenerateDerivedKeys(
|
||||
extern "C" OEMCryptoResult OEMCrypto_GenerateDerivedKeys_V18(
|
||||
OEMCrypto_SESSION session, const uint8_t* mac_key_context,
|
||||
size_t mac_key_context_length, const uint8_t* enc_key_context,
|
||||
size_t enc_key_context_length) {
|
||||
if (!gAdapter.get()) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
LevelSession pair = gAdapter->GetSession(session);
|
||||
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
if (pair.fcn->GenerateDerivedKeys == nullptr) {
|
||||
if (pair.fcn->GenerateDerivedKeys_V18 == nullptr) {
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
return pair.fcn->GenerateDerivedKeys(pair.session, mac_key_context,
|
||||
mac_key_context_length, enc_key_context,
|
||||
enc_key_context_length);
|
||||
return pair.fcn->GenerateDerivedKeys_V18(
|
||||
pair.session, mac_key_context, mac_key_context_length, enc_key_context,
|
||||
enc_key_context_length);
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
|
||||
@@ -2087,20 +2113,49 @@ const uint8_t* PointerOrNull(const uint8_t* pointer, size_t length) {
|
||||
return length ? pointer : nullptr;
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_LoadLicense(OEMCrypto_SESSION session,
|
||||
const uint8_t* message,
|
||||
size_t message_length,
|
||||
size_t core_message_length,
|
||||
const uint8_t* signature,
|
||||
size_t signature_length) {
|
||||
template <size_t N>
|
||||
std::vector<uint8_t> MakeContext(const char (&key_label)[N],
|
||||
const uint8_t* context, size_t context_length,
|
||||
uint32_t suffix) {
|
||||
// TODO(b/299343035): Use ODK methods.
|
||||
std::vector<uint8_t> ret;
|
||||
ret.insert(ret.end(), key_label, key_label + N);
|
||||
ret.insert(ret.end(), context, context + context_length);
|
||||
const uint32_t suffix_net = htonl(suffix);
|
||||
auto* ptr = reinterpret_cast<const uint8_t*>(&suffix_net);
|
||||
ret.insert(ret.end(), ptr, ptr + sizeof(suffix_net));
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_LoadLicense(
|
||||
OEMCrypto_SESSION session, const uint8_t* context, size_t context_length,
|
||||
const uint8_t* derivation_key, size_t derivation_key_length,
|
||||
const uint8_t* message, size_t message_length, size_t core_message_length,
|
||||
const uint8_t* signature, size_t signature_length) {
|
||||
if (!gAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
LevelSession pair = gAdapter->GetSession(session);
|
||||
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
if (pair.fcn->LoadLicense == nullptr) {
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
if (pair.fcn->LoadLicense_V18 == nullptr ||
|
||||
pair.fcn->DeriveKeysFromSessionKey_V18 == nullptr) {
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
const std::vector<uint8_t> mac_context =
|
||||
MakeContext("AUTHENTICATION", context, context_length, 0x200);
|
||||
const std::vector<uint8_t> enc_context =
|
||||
MakeContext("ENCRYPTION", context, context_length, 0x80);
|
||||
const OEMCryptoResult result = pair.fcn->DeriveKeysFromSessionKey_V18(
|
||||
session, derivation_key, derivation_key_length, mac_context.data(),
|
||||
mac_context.size(), enc_context.data(), enc_context.size());
|
||||
if (result != OEMCrypto_SUCCESS) return result;
|
||||
return pair.fcn->LoadLicense_V18(session, message, message_length,
|
||||
core_message_length, signature,
|
||||
signature_length);
|
||||
}
|
||||
return pair.fcn->LoadLicense(pair.session, message, message_length,
|
||||
core_message_length, signature,
|
||||
return pair.fcn->LoadLicense(pair.session, context, context_length,
|
||||
derivation_key, derivation_key_length, message,
|
||||
message_length, core_message_length, signature,
|
||||
signature_length);
|
||||
}
|
||||
|
||||
@@ -2144,7 +2199,7 @@ extern "C" OEMCryptoResult OEMCrypto_LoadRenewal(OEMCrypto_SESSION session,
|
||||
if (!gAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
LevelSession pair = gAdapter->GetSession(session);
|
||||
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
if (pair.fcn->LoadLicense == nullptr) {
|
||||
if (pair.fcn->LoadRenewal == nullptr) {
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
return pair.fcn->LoadRenewal(pair.session, message, message_length,
|
||||
@@ -2334,15 +2389,66 @@ extern "C" OEMCryptoResult OEMCrypto_GetRandom(uint8_t* randomData,
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_LoadProvisioning(
|
||||
OEMCrypto_SESSION session, const uint8_t* message, size_t message_length,
|
||||
size_t core_message_length, const uint8_t* signature,
|
||||
size_t signature_length, uint8_t* wrapped_private_key,
|
||||
size_t* wrapped_private_key_length) {
|
||||
OEMCrypto_SESSION session, const uint8_t* request, size_t request_length,
|
||||
const uint8_t* message, size_t message_length, size_t core_message_length,
|
||||
const uint8_t* signature, size_t signature_length,
|
||||
uint8_t* wrapped_private_key, size_t* wrapped_private_key_length) {
|
||||
if (!gAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
LevelSession pair = gAdapter->GetSession(session);
|
||||
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
if (pair.fcn->LoadProvisioning != nullptr) {
|
||||
return pair.fcn->LoadProvisioning(
|
||||
pair.session, request, request_length, message, message_length,
|
||||
core_message_length, signature, signature_length, wrapped_private_key,
|
||||
wrapped_private_key_length);
|
||||
}
|
||||
if (pair.fcn->LoadProvisioning_V18 != nullptr &&
|
||||
pair.fcn->GenerateDerivedKeys_V18 != nullptr) {
|
||||
const std::vector<uint8_t> mac_context =
|
||||
MakeContext("AUTHENTICATION", request, request_length, 0x200);
|
||||
const std::vector<uint8_t> enc_context =
|
||||
MakeContext("ENCRYPTION", request, request_length, 0x80);
|
||||
const OEMCryptoResult result = pair.fcn->GenerateDerivedKeys_V18(
|
||||
pair.session, mac_context.data(), mac_context.size(),
|
||||
enc_context.data(), enc_context.size());
|
||||
if (result != OEMCrypto_SUCCESS) return result;
|
||||
|
||||
return pair.fcn->LoadProvisioning_V18(
|
||||
pair.session, message, message_length, core_message_length, signature,
|
||||
signature_length, wrapped_private_key, wrapped_private_key_length);
|
||||
}
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_LoadProvisioningCast(
|
||||
OEMCrypto_SESSION session, const uint8_t* derivation_key,
|
||||
size_t derivation_key_length, const uint8_t* provision_request,
|
||||
size_t provision_request_length, const uint8_t* message,
|
||||
size_t message_length, size_t core_message_length, const uint8_t* signature,
|
||||
size_t signature_length, uint8_t* wrapped_private_key,
|
||||
size_t* wrapped_private_key_length) {
|
||||
if (!gAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
LevelSession pair = gAdapter->GetSession(session);
|
||||
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
if (pair.fcn->LoadProvisioningCast != nullptr) {
|
||||
return pair.fcn->LoadProvisioningCast(
|
||||
pair.session, derivation_key, derivation_key_length, provision_request,
|
||||
provision_request_length, message, message_length, core_message_length,
|
||||
signature, signature_length, wrapped_private_key,
|
||||
wrapped_private_key_length);
|
||||
}
|
||||
if (pair.fcn->LoadProvisioning_V18 != nullptr &&
|
||||
pair.fcn->DeriveKeysFromSessionKey_V18 != nullptr) {
|
||||
const std::vector<uint8_t> mac_context = MakeContext(
|
||||
"AUTHENTICATION", provision_request, provision_request_length, 0x200);
|
||||
const std::vector<uint8_t> enc_context = MakeContext(
|
||||
"ENCRYPTION", provision_request, provision_request_length, 0x80);
|
||||
const OEMCryptoResult result = pair.fcn->DeriveKeysFromSessionKey_V18(
|
||||
pair.session, derivation_key, derivation_key_length, mac_context.data(),
|
||||
mac_context.size(), enc_context.data(), enc_context.size());
|
||||
if (result != OEMCrypto_SUCCESS) return result;
|
||||
|
||||
return pair.fcn->LoadProvisioning_V18(
|
||||
pair.session, message, message_length, core_message_length, signature,
|
||||
signature_length, wrapped_private_key, wrapped_private_key_length);
|
||||
}
|
||||
@@ -2393,7 +2499,7 @@ extern "C" OEMCryptoResult OEMCrypto_GenerateRSASignature(
|
||||
padding_scheme);
|
||||
}
|
||||
|
||||
extern "C" OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
|
||||
extern "C" OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey_V18(
|
||||
OEMCrypto_SESSION session, const uint8_t* enc_session_key,
|
||||
size_t enc_session_key_length, const uint8_t* mac_key_context,
|
||||
size_t mac_key_context_length, const uint8_t* enc_key_context,
|
||||
@@ -2401,9 +2507,9 @@ extern "C" OEMCryptoResult OEMCrypto_DeriveKeysFromSessionKey(
|
||||
if (!gAdapter) return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
LevelSession pair = gAdapter->GetSession(session);
|
||||
if (!pair.fcn) return OEMCrypto_ERROR_INVALID_SESSION;
|
||||
if (pair.fcn->DeriveKeysFromSessionKey == nullptr)
|
||||
if (pair.fcn->DeriveKeysFromSessionKey_V18 == nullptr)
|
||||
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
||||
return pair.fcn->DeriveKeysFromSessionKey(
|
||||
return pair.fcn->DeriveKeysFromSessionKey_V18(
|
||||
pair.session, enc_session_key, enc_session_key_length, mac_key_context,
|
||||
mac_key_context_length, enc_key_context, enc_key_context_length);
|
||||
}
|
||||
|
||||
@@ -275,18 +275,14 @@ bool FakeProvisioningServer::MakeResponse(
|
||||
// Next, we derive the keys from the keybox device key. This is Provisioning
|
||||
// 2.0 specific.
|
||||
// TODO(b/141438127): Add support for provisioing 3.0.
|
||||
std::string mac_context;
|
||||
GenerateMacContext(serialized_message, &mac_context);
|
||||
std::vector<uint8_t> mac_context_v(mac_context.begin(), mac_context.end());
|
||||
std::string enc_context;
|
||||
GenerateEncryptContext(serialized_message, &enc_context);
|
||||
std::vector<uint8_t> enc_context_v(enc_context.begin(), enc_context.end());
|
||||
wvoec::KeyDeriver key_deriver;
|
||||
std::vector<uint8_t> serialized_message_v(serialized_message.begin(),
|
||||
serialized_message.end());
|
||||
// Not only is this Prov 2.0 specific, it assumes the device is using the
|
||||
// standard test keybox.
|
||||
key_deriver.DeriveKeys(wvoec::kTestKeybox.device_key_,
|
||||
sizeof(wvoec::kTestKeybox.device_key_), mac_context_v,
|
||||
enc_context_v);
|
||||
sizeof(wvoec::kTestKeybox.device_key_),
|
||||
serialized_message_v);
|
||||
|
||||
// Create a structure to hold the RSA private key. This is used by the key
|
||||
// deriver to encrypt the key.
|
||||
|
||||
Reference in New Issue
Block a user