Added an OTA keybox provisioner.

[ Merge of http://go/wvgerrit/133729 ]

The OtaKeyboxProvisioner is a system-wide provisioner for sharing the
provisioning workflow between CDM engines.

Bug: 189232882
Test: GtsMediaTestCases
Change-Id: I873af3087cc05e1831bdd1d2c14fb002b73e6902

Added keybox provisioning proto fields.

[ Merge of http://go/wvgerrit/133730 and http://go/ag/15113032 ]

This CL copies over the required license_protocol.proto changes that
are required for OTA keybox provisioning.  These fields are defined in
the server-side certificate_provisioning.proto, defined in
http://cl/377533774.

Note, changes are slightly different from server proto due to the RVC
version of license_protocol.proto being out of date with SC and newer
changes.

Bug: 189232882
Test: run_x86_64_tests
Change-Id: I55fcf6a7ac2ba4b6026b9acc63e822ff33c431d9

Added OTA keybox provisioning device files.

[ Merge of http://go/wvgerrit/133743 and http://go/ag/15421141 ]

This change adds a new set of proto messages/fields the CDM's device
files for recording device and engine information around OTA keybox
provisioning (OKP).

To make cleanup and thread protection possible, there is a single file
which will contain all the information for the device as a whole and
each CDM engine tied to an app/origin.

Bug: 189232882
Test: Linux unit tests
Change-Id: Iaf80cd6342f32657e04416750d9b278d935821a5

Client ID for OKP requests.

[ Merge of http://go/wvgerrit/133744 and http://go/ag/15645331 ]

Extended the CDM ClientIdentification class to support a subset of
client info used for OKP requests.

Bug: 189232882
Test: Android unit tests
Merged-In: I6aafb4f2164efe69bc733ece0a912f0e91893b91
Change-Id: I6aafb4f2164efe69bc733ece0a912f0e91893b91
This commit is contained in:
Rahul Frias
2021-09-15 02:56:19 -07:00
committed by Alex Dale
parent 44ba42f5cc
commit 52bd1d206e
13 changed files with 586 additions and 30 deletions

View File

@@ -20,6 +20,7 @@
#include "crypto_key.h"
#include "entitlement_key_session.h"
#include "log.h"
#include "ota_keybox_provisioner.h"
#include "platform.h"
#include "privacy_crypto.h"
#include "properties.h"
@@ -178,6 +179,7 @@ std::unique_ptr<UsageTableHeader> CryptoSession::usage_table_header_l1_;
std::unique_ptr<UsageTableHeader> CryptoSession::usage_table_header_l3_;
std::recursive_mutex CryptoSession::usage_table_mutex_;
std::atomic<uint64_t> CryptoSession::request_id_index_source_(0);
std::unique_ptr<OtaKeyboxProvisioner> CryptoSession::ota_keybox_provisioner_l1_;
size_t GetOffset(std::string message, std::string field) {
size_t pos = message.find(field);
@@ -360,8 +362,15 @@ void CryptoSession::Init() {
LOGD("OEMCrypto version (L3 security level): %s.%s", api_version.c_str(),
api_minor_version.c_str());
if (needs_keybox_provisioning_) {
LOGE("OEMCrypto needs provisioning");
// TODO(fredgc,sigquit,rfrias): handle provisioning.
WithStaticFieldWriteLock("OtaKeyboxProvisioner", [&] {
if (!ota_keybox_provisioner_l1_) {
LOGD("OEMCrypto needs keybox provisioning");
// Only create once. Possible that OEMCrypto is initialized
// and terminated many times over the life cycle of the OTA
// keybox provisioning process.
ota_keybox_provisioner_l1_ = OtaKeyboxProvisioner::Create();
}
});
}
}
}
@@ -3011,11 +3020,20 @@ OEMCryptoResult CryptoSession::LegacyDecryptInChunks(
remaining_input_data -= chunk_size;
AdvanceDestBuffer(&fake_sample.buffers.output_descriptor, chunk_size);
}
return sts;
}
// TODO(sigquit): include rest of http://go/wvgerrit/126004
OtaKeyboxProvisioner* CryptoSession::GetOtaKeyboxProvisioner() {
const auto getter = [&]() -> OtaKeyboxProvisioner* {
// If not set, then OTA keybox provisioning is not supported or
// not needed.
if (!ota_keybox_provisioner_l1_) return nullptr;
// May have already been initialized.
if (ota_keybox_provisioner_l1_->IsProvisioned()) return nullptr;
return ota_keybox_provisioner_l1_.get();
};
return WithStaticFieldReadLock("GetOtaKeyboxProvisioner", getter);
}
CdmResponseType CryptoSession::PrepareOtaProvisioningRequest(
bool use_test_key, std::string* request) {
@@ -3026,17 +3044,25 @@ CdmResponseType CryptoSession::PrepareOtaProvisioningRequest(
if (status != OEMCrypto_ERROR_SHORT_BUFFER)
return MapOEMCryptoResult(status, UNKNOWN_ERROR,
"PrepareOtaProvisioningRequest");
std::string temp_buffer(buffer_length, '\0');
uint8_t* buf = reinterpret_cast<uint8_t*>(&temp_buffer[0]);
if (buffer_length == 0) {
LOGE("OTA request size is zero");
return UNKNOWN_ERROR;
}
request->resize(buffer_length);
uint8_t* buf = reinterpret_cast<uint8_t*>(&request->front());
status = OEMCrypto_GenerateOTARequest(buf, &buffer_length, use_test_key);
if (OEMCrypto_SUCCESS == status) request->assign(temp_buffer);
if (OEMCrypto_SUCCESS != status) {
request->clear();
} else if (buffer_length != request->size()) {
request->resize(buffer_length);
}
return MapOEMCryptoResult(status, UNKNOWN_ERROR,
"PrepareOtaProvisioningRequest");
}
CdmResponseType CryptoSession::LoadOtaProvisioning(
bool use_test_key, const std::string& response) {
OEMCryptoResult status = OEMCrypto_ProcessOTAKeybox(
const OEMCryptoResult status = OEMCrypto_ProcessOTAKeybox(
reinterpret_cast<const uint8_t*>(response.data()), response.size(),
use_test_key);
return MapOEMCryptoResult(status, UNKNOWN_ERROR, "LoadOtaProvisioning");