Internal factory tool implements CSR v3

Widevine internal BCC extraction tool to extract CSR v3 for testing
purpose. The difference it has from the factory tool is it doesn't rely
on Widevine IRPC HAL.

It just extracts BCC/CSR in the specified format from cli.

Test: Extract CSR v3 on Pixel 7 and upload
Bug: 268246995
Change-Id: I52abe09f991c89c6e7601bcef4d980f24c020c9f
This commit is contained in:
Cong Lin
2023-02-13 11:48:14 -08:00
parent 8dc7cc0c74
commit 5e24549b1a
5 changed files with 183 additions and 103 deletions

View File

@@ -81,6 +81,7 @@ bool OEMCryptoInterface::Init(const std::string& oemcrypto_path) {
LOAD_SYM(GetBootCertificateChain);
LOAD_SYM(BuildInformation);
LOAD_SYM_IF_EXIST(GetDeviceInformation);
LOAD_SYM_IF_EXIST(GetDeviceSignedCsrPayload);
OEMCryptoResult status = Initialize();
if (status != OEMCrypto_SUCCESS) {
@@ -145,7 +146,7 @@ OEMCryptoResult OEMCryptoInterface::GetOEMCryptoBuildInfo(
}
OEMCryptoResult OEMCryptoInterface::GetVerifiedDeviceInformation(
VerifiedDeviceInfo& verified_device_info) {
std::vector<uint8_t>& verified_device_info) {
if (handle_ == nullptr) {
return OEMCrypto_ERROR_INIT_FAILED;
}
@@ -153,27 +154,46 @@ OEMCryptoResult OEMCryptoInterface::GetVerifiedDeviceInformation(
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
verified_device_info.device_info.resize(0);
size_t device_info_size = 0;
verified_device_info.signed_csr_payload.resize(0);
size_t signed_csr_payload_size = 0;
OEMCryptoResult result = GetDeviceInformation(
verified_device_info.device_info.data(), &device_info_size,
verified_device_info.signed_csr_payload.data(), &signed_csr_payload_size);
verified_device_info.resize(0);
size_t verified_device_info_size = 0;
OEMCryptoResult result = GetDeviceInformation(verified_device_info.data(),
&verified_device_info_size);
LOGI("GetVerifiedDeviceInformation first attempt result %d", result);
if (result == OEMCrypto_ERROR_SHORT_BUFFER) {
verified_device_info.device_info.resize(device_info_size);
verified_device_info.signed_csr_payload.resize(signed_csr_payload_size);
result = GetDeviceInformation(
verified_device_info.device_info.data(), &device_info_size,
verified_device_info.signed_csr_payload.data(),
&signed_csr_payload_size);
verified_device_info.device_info.resize(device_info_size);
verified_device_info.signed_csr_payload.resize(signed_csr_payload_size);
verified_device_info.resize(verified_device_info_size);
result = GetDeviceInformation(verified_device_info.data(),
&verified_device_info_size);
verified_device_info.resize(verified_device_info_size);
LOGI("GetVerifiedDeviceInformation second attempt result %d", result);
}
return result;
}
OEMCryptoResult OEMCryptoInterface::GetSignedCsrPayload(
const std::vector<uint8_t>& challenge,
const std::vector<uint8_t>& device_info,
std::vector<uint8_t>& signed_csr_payload) {
if (handle_ == nullptr) {
return OEMCrypto_ERROR_INIT_FAILED;
}
if (GetDeviceSignedCsrPayload == nullptr) {
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
}
size_t signed_csr_payload_size = signed_csr_payload.size();
OEMCryptoResult result = GetDeviceSignedCsrPayload(
challenge.data(), challenge.size(), device_info.data(),
device_info.size(), signed_csr_payload.data(), &signed_csr_payload_size);
LOGI("GetDeviceSignedCsrPayload first attempt result %d", result);
if (result == OEMCrypto_ERROR_SHORT_BUFFER) {
signed_csr_payload.resize(signed_csr_payload_size);
result = GetDeviceSignedCsrPayload(challenge.data(), challenge.size(),
device_info.data(), device_info.size(),
signed_csr_payload.data(),
&signed_csr_payload_size);
signed_csr_payload.resize(signed_csr_payload_size);
LOGI("GetDeviceSignedCsrPayload second attempt result %d", result);
}
return result;
}

View File

@@ -42,7 +42,7 @@ std::vector<uint8_t> WidevineProvisioner::GetBcc() {
std::vector<uint8_t> bcc;
OEMCryptoResult result = crypto_interface_->GetBcc(bcc);
if (result != OEMCrypto_SUCCESS) {
LOGE("Failed to get BCC.");
LOGE("Failed to get BCC, result = %d", result);
}
return bcc;
}
@@ -58,7 +58,7 @@ bool WidevineProvisioner::GenerateCertificateRequest(
std::vector<uint8_t> bcc;
OEMCryptoResult result = crypto_interface_->GetBcc(bcc);
if (result != OEMCrypto_SUCCESS) {
LOGE("Failed to get BCC.");
LOGE("Failed to get BCC, result = %d", result);
return false;
}
@@ -73,7 +73,7 @@ bool WidevineProvisioner::GenerateCertificateRequest(
bool WidevineProvisioner::TryAddVerifiedDeviceInfo(
cppbor::Map& device_info_map) {
VerifiedDeviceInfo verified_device_info;
std::vector<uint8_t> verified_device_info;
OEMCryptoResult result =
crypto_interface_->GetVerifiedDeviceInformation(verified_device_info);
if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
@@ -82,30 +82,22 @@ bool WidevineProvisioner::TryAddVerifiedDeviceInfo(
return true;
}
if (result != OEMCrypto_SUCCESS) {
LOGE("Failed to get verified device information.");
LOGE("Failed to get verified device information, result = %d", result);
return false;
}
auto [parsed, _, err] = cppbor::parse(
reinterpret_cast<const uint8_t*>(verified_device_info.device_info.data()),
verified_device_info.device_info.size());
reinterpret_cast<const uint8_t*>(verified_device_info.data()),
verified_device_info.size());
if (!parsed || !parsed->asMap()) {
LOGE("Failed to parse the verified device info cbor: %s", err.c_str());
return false;
}
const cppbor::Map* verified_device_info_map = parsed->asMap();
auto& make = verified_device_info_map->get("manufacturer");
if (make && make->asTstr() && make->asTstr()->value() != "") {
device_info_map.add("manufacturer", make->asTstr()->value());
for (size_t i = 0; i < verified_device_info_map->size(); i++) {
auto& [key_item, value_item] = (*verified_device_info_map)[i];
LOGI("Found device info %s", key_item->asTstr()->value().data());
device_info_map.add(key_item->clone(), value_item->clone());
}
auto& model = verified_device_info_map->get("model");
if (model && model->asTstr() && model->asTstr()->value() != "") {
device_info_map.add("model", model->asTstr()->value());
}
auto& fused = verified_device_info_map->get("fused");
if (fused && fused->asUint()) {
device_info_map.add("fused", fused->asUint()->value());
}
device_info_map.canonicalize();
return true;
}
@@ -172,13 +164,11 @@ bool WidevineProvisioner::GetDeviceInfoCommon(cppbor::Map& device_info_map) {
OEMCryptoResult result =
crypto_interface_->GetOEMCryptoBuildInfo(oemcrypto_build_info);
if (result != OEMCrypto_SUCCESS) {
LOGE("Failed to get oemcrypto build info.");
LOGE("Failed to get oemcrypto build info, result = %d", result);
return false;
}
device_info_map.add(cppbor::Tstr("oemcrypto_build_info"),
cppbor::Tstr(oemcrypto_build_info));
device_info_map.canonicalize();
return true;
}
@@ -186,7 +176,6 @@ bool WidevineProvisioner::GetDeviceInfo(std::vector<uint8_t>& device_info) {
auto device_info_map = cppbor::Map();
device_info_map.add(cppbor::Tstr("type"), cppbor::Tstr("widevine"));
device_info_map.add(cppbor::Tstr("version"), cppbor::Uint(2));
device_info_map.canonicalize();
if (!GetDeviceInfoCommon(device_info_map)) return false;
device_info = device_info_map.canonicalize().encode();
return true;
@@ -318,6 +307,50 @@ cppbor::Array WidevineProvisioner::BuildCertReqRecipients(
.add(cppbor::Null())); // No ciphertext
}
bool WidevineProvisioner::GetDeviceInfoV2(cppbor::Map& device_info_map) {
if (!GetDeviceInfoCommon(device_info_map)) return false;
device_info_map.canonicalize();
return true;
}
bool WidevineProvisioner::GenerateCertificateRequestV2(
const std::vector<uint8_t>& challenge, std::vector<uint8_t>* csr) {
if (csr == nullptr) {
LOGE("CSR is null.");
return false;
}
// Prepare BCC
std::vector<uint8_t> bcc;
OEMCryptoResult result = crypto_interface_->GetBcc(bcc);
if (result != OEMCrypto_SUCCESS) {
LOGE("Failed to get BCC, result = %d", result);
return false;
}
// Prepare device info
auto device_info_map = cppbor::Map();
if (!GetDeviceInfoV2(device_info_map)) {
LOGE("Failed to get device_info.");
return false;
}
// Prepare signed CSR payload
auto device_info = device_info_map.encode();
std::vector<uint8_t> signed_csr_payload;
result = crypto_interface_->GetSignedCsrPayload(challenge, device_info,
signed_csr_payload);
if (result != OEMCrypto_SUCCESS) {
LOGE("Failed to get the signed CSR payload, result = %d", result);
return false;
}
// https://source.corp.google.com/android-internal/hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
*csr = cppbor::Array()
.add(1 /* version */)
.add(cppbor::Map() /* UdsCerts */)
.add(cppbor::EncodedItem(std::move(bcc)))
.add(cppbor::EncodedItem(std::move(signed_csr_payload)))
.encode();
return true;
}
void WidevineProvisioner::InitializeCryptoInterface() {
std::string oemcrypto_path;
if (!wvcdm::Properties::GetOEMCryptoPath(&oemcrypto_path)) {