Factory BCC extraction tool to consume verified device info
BCC extraction tool calls OEMCrypto_GetDeviceInformation() to read verified device info from TEE. If the verified device info is not available, (e.g. not implemented), it falls back to using OS properties. This CL is mostly identical to ag/20799640, which has the same change for our internal extraction tool. For historical reason, we keep two copies of the extraction tool which are slightly different from each other, one for factory use, one for debug use. Long term they will be merged. Test: Ran the tool on Pixel 7 w/wo verified device info being present Bug: 263312447 Change-Id: Ib9c77dee45e9ff996fc2dc2da14f16f60eaff77c
This commit is contained in:
@@ -1 +1 @@
|
|||||||
This folder contains Widevine's implementation of Android Remote Provisioning HAL, which is used as part of provisioning 4.0 process. It is intented for factory usage only, and should not be present on user devices.
|
This folder contains Widevine's implementation of Android Remote Provisioning HAL, which is used as part of provisioning 4.0 process. It is intended for factory usage only, and should not be present on user devices.
|
||||||
@@ -13,6 +13,13 @@
|
|||||||
|
|
||||||
namespace widevine {
|
namespace widevine {
|
||||||
|
|
||||||
|
struct VerifiedDeviceInfo {
|
||||||
|
std::vector<uint8_t> device_info;
|
||||||
|
// Used by Interface of Remote Provisioning Component (IRPC) v3 for CSR
|
||||||
|
// uploading
|
||||||
|
std::vector<uint8_t> signed_csr_payload;
|
||||||
|
};
|
||||||
|
|
||||||
class OEMCryptoInterface {
|
class OEMCryptoInterface {
|
||||||
public:
|
public:
|
||||||
OEMCryptoInterface() = default;
|
OEMCryptoInterface() = default;
|
||||||
@@ -30,6 +37,11 @@ class OEMCryptoInterface {
|
|||||||
// implementation.
|
// implementation.
|
||||||
OEMCryptoResult GetOEMCryptoBuildInfo(std::string& build_info);
|
OEMCryptoResult GetOEMCryptoBuildInfo(std::string& build_info);
|
||||||
|
|
||||||
|
// Retrieves the verified device information of the OEMCrypto library from
|
||||||
|
// OEMCrypto implementation.
|
||||||
|
OEMCryptoResult GetVerifiedDeviceInformation(
|
||||||
|
VerifiedDeviceInfo& verified_device_info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef OEMCryptoResult (*Initialize_t)();
|
typedef OEMCryptoResult (*Initialize_t)();
|
||||||
typedef OEMCryptoResult (*Terminate_t)();
|
typedef OEMCryptoResult (*Terminate_t)();
|
||||||
@@ -38,11 +50,15 @@ class OEMCryptoInterface {
|
|||||||
size_t* additional_signature_size);
|
size_t* additional_signature_size);
|
||||||
typedef OEMCryptoResult (*BuildInformation_t)(char* buffer,
|
typedef OEMCryptoResult (*BuildInformation_t)(char* buffer,
|
||||||
size_t* buffer_length);
|
size_t* buffer_length);
|
||||||
|
typedef OEMCryptoResult (*GetDeviceInformation_t)(
|
||||||
|
uint8_t* device_info, size_t* device_info_length,
|
||||||
|
uint8_t* signed_csr_payload, size_t* signed_csr_payload_length);
|
||||||
|
|
||||||
Initialize_t Initialize = nullptr;
|
Initialize_t Initialize = nullptr;
|
||||||
Terminate_t Terminate = nullptr;
|
Terminate_t Terminate = nullptr;
|
||||||
GetBootCertificateChain_t GetBootCertificateChain = nullptr;
|
GetBootCertificateChain_t GetBootCertificateChain = nullptr;
|
||||||
BuildInformation_t BuildInformation = nullptr;
|
BuildInformation_t BuildInformation = nullptr;
|
||||||
|
GetDeviceInformation_t GetDeviceInformation = nullptr;
|
||||||
|
|
||||||
void* handle_ = nullptr;
|
void* handle_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ class WidevineProvisioner {
|
|||||||
cppbor::Array BuildCertReqRecipients(const std::vector<uint8_t>& pubkey,
|
cppbor::Array BuildCertReqRecipients(const std::vector<uint8_t>& pubkey,
|
||||||
const std::vector<uint8_t>& kid) const;
|
const std::vector<uint8_t>& kid) const;
|
||||||
void InitializeCryptoInterface();
|
void InitializeCryptoInterface();
|
||||||
|
bool GetDeviceInfoCommon(cppbor::Map& device_info_map);
|
||||||
|
bool TryAddVerifiedDeviceInfo(cppbor::Map& device_info_map);
|
||||||
|
|
||||||
std::unique_ptr<OEMCryptoInterface> crypto_interface_;
|
std::unique_ptr<OEMCryptoInterface> crypto_interface_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
LOGE("%s", dlerror()); \
|
LOGE("%s", dlerror()); \
|
||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
|
#define LOAD_SYM_IF_EXIST(name) \
|
||||||
|
name = reinterpret_cast<name##_t>(LOOKUP(handle_, OEMCrypto_##name));
|
||||||
|
|
||||||
// These are implementations required by OEMCrypto Reference Implementation
|
// These are implementations required by OEMCrypto Reference Implementation
|
||||||
// and/or the Testbed, but not needed in this package.
|
// and/or the Testbed, but not needed in this package.
|
||||||
@@ -78,6 +80,7 @@ bool OEMCryptoInterface::Init(const std::string& oemcrypto_path) {
|
|||||||
LOAD_SYM(Terminate);
|
LOAD_SYM(Terminate);
|
||||||
LOAD_SYM(GetBootCertificateChain);
|
LOAD_SYM(GetBootCertificateChain);
|
||||||
LOAD_SYM(BuildInformation);
|
LOAD_SYM(BuildInformation);
|
||||||
|
LOAD_SYM_IF_EXIST(GetDeviceInformation);
|
||||||
|
|
||||||
OEMCryptoResult status = Initialize();
|
OEMCryptoResult status = Initialize();
|
||||||
if (status != OEMCrypto_SUCCESS) {
|
if (status != OEMCrypto_SUCCESS) {
|
||||||
@@ -141,4 +144,37 @@ OEMCryptoResult OEMCryptoInterface::GetOEMCryptoBuildInfo(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OEMCryptoResult OEMCryptoInterface::GetVerifiedDeviceInformation(
|
||||||
|
VerifiedDeviceInfo& verified_device_info) {
|
||||||
|
if (handle_ == nullptr) {
|
||||||
|
return OEMCrypto_ERROR_INIT_FAILED;
|
||||||
|
}
|
||||||
|
if (GetDeviceInformation == nullptr) {
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
LOGI("GetVerifiedDeviceInformation second attempt result %d", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace widevine
|
} // namespace widevine
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "WidevineOemcryptoInterface.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "properties.h"
|
#include "properties.h"
|
||||||
|
|
||||||
@@ -61,25 +62,87 @@ bool WidevineProvisioner::GenerateCertificateRequest(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WidevineProvisioner::GetDeviceInfo(std::vector<uint8_t>& device_info) {
|
bool WidevineProvisioner::TryAddVerifiedDeviceInfo(
|
||||||
auto device_info_map = cppbor::Map();
|
cppbor::Map& device_info_map) {
|
||||||
device_info_map.add(cppbor::Tstr("type"), cppbor::Tstr("widevine"));
|
VerifiedDeviceInfo verified_device_info;
|
||||||
device_info_map.add(cppbor::Tstr("version"), cppbor::Uint(2));
|
OEMCryptoResult result =
|
||||||
|
crypto_interface_->GetVerifiedDeviceInformation(verified_device_info);
|
||||||
std::string company_name;
|
if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED) {
|
||||||
if (!wvcdm::Properties::GetCompanyName(&company_name) ||
|
// OEMCrypto v17 and earlier doesn't support GetDeviceInformation()
|
||||||
company_name.empty()) {
|
LOGI("OEMCrypto_GetDeviceInformation is not implemented.");
|
||||||
LOGE("Failed to get company name.");
|
return true;
|
||||||
|
}
|
||||||
|
if (result != OEMCrypto_SUCCESS) {
|
||||||
|
LOGE("Failed to get verified device information.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
device_info_map.add(cppbor::Tstr("manufacturer"), cppbor::Tstr(company_name));
|
auto [parsed, _, err] = cppbor::parse(
|
||||||
|
reinterpret_cast<const uint8_t*>(verified_device_info.device_info.data()),
|
||||||
std::string model_name;
|
verified_device_info.device_info.size());
|
||||||
if (!wvcdm::Properties::GetModelName(&model_name) || model_name.empty()) {
|
if (!parsed || !parsed->asMap()) {
|
||||||
LOGE("Failed to get model name.");
|
LOGE("Failed to parse the verified device info cbor: %s", err.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
device_info_map.add(cppbor::Tstr("model"), cppbor::Tstr(model_name));
|
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());
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WidevineProvisioner::GetDeviceInfoCommon(cppbor::Map& device_info_map) {
|
||||||
|
if (!TryAddVerifiedDeviceInfo(device_info_map)) return false;
|
||||||
|
// Add device information from OS properties if the verified device info is
|
||||||
|
// not present
|
||||||
|
if (device_info_map.get("manufacturer") == nullptr) {
|
||||||
|
std::string company_name;
|
||||||
|
if (!wvcdm::Properties::GetCompanyName(&company_name) ||
|
||||||
|
company_name.empty()) {
|
||||||
|
LOGE("Failed to get company name.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
device_info_map.add(cppbor::Tstr("manufacturer"),
|
||||||
|
cppbor::Tstr(company_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_info_map.get("model") == nullptr) {
|
||||||
|
std::string model_name;
|
||||||
|
if (!wvcdm::Properties::GetModelName(&model_name) || model_name.empty()) {
|
||||||
|
LOGE("Failed to get model name.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
device_info_map.add(cppbor::Tstr("model"), cppbor::Tstr(model_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_info_map.get("device") == nullptr) {
|
||||||
|
std::string device_name;
|
||||||
|
if (!wvcdm::Properties::GetDeviceName(&device_name) ||
|
||||||
|
device_name.empty()) {
|
||||||
|
LOGE("Failed to get device name.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
device_info_map.add(cppbor::Tstr("device"), cppbor::Tstr(device_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_info_map.get("product") == nullptr) {
|
||||||
|
std::string product_name;
|
||||||
|
if (!wvcdm::Properties::GetProductName(&product_name) ||
|
||||||
|
product_name.empty()) {
|
||||||
|
LOGE("Failed to get product name.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
device_info_map.add(cppbor::Tstr("product"), cppbor::Tstr(product_name));
|
||||||
|
}
|
||||||
|
|
||||||
std::string arch_name;
|
std::string arch_name;
|
||||||
if (!wvcdm::Properties::GetArchitectureName(&arch_name) ||
|
if (!wvcdm::Properties::GetArchitectureName(&arch_name) ||
|
||||||
@@ -89,21 +152,6 @@ bool WidevineProvisioner::GetDeviceInfo(std::vector<uint8_t>& device_info) {
|
|||||||
}
|
}
|
||||||
device_info_map.add(cppbor::Tstr("architecture"), cppbor::Tstr(arch_name));
|
device_info_map.add(cppbor::Tstr("architecture"), cppbor::Tstr(arch_name));
|
||||||
|
|
||||||
std::string device_name;
|
|
||||||
if (!wvcdm::Properties::GetDeviceName(&device_name) || device_name.empty()) {
|
|
||||||
LOGE("Failed to get device name.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
device_info_map.add(cppbor::Tstr("device"), cppbor::Tstr(device_name));
|
|
||||||
|
|
||||||
std::string product_name;
|
|
||||||
if (!wvcdm::Properties::GetProductName(&product_name) ||
|
|
||||||
product_name.empty()) {
|
|
||||||
LOGE("Failed to get product name.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
device_info_map.add(cppbor::Tstr("product"), cppbor::Tstr(product_name));
|
|
||||||
|
|
||||||
std::string build_info;
|
std::string build_info;
|
||||||
if (!wvcdm::Properties::GetBuildInfo(&build_info) || build_info.empty()) {
|
if (!wvcdm::Properties::GetBuildInfo(&build_info) || build_info.empty()) {
|
||||||
LOGE("Failed to get build info.");
|
LOGE("Failed to get build info.");
|
||||||
@@ -121,6 +169,16 @@ bool WidevineProvisioner::GetDeviceInfo(std::vector<uint8_t>& device_info) {
|
|||||||
device_info_map.add(cppbor::Tstr("oemcrypto_build_info"),
|
device_info_map.add(cppbor::Tstr("oemcrypto_build_info"),
|
||||||
cppbor::Tstr(oemcrypto_build_info));
|
cppbor::Tstr(oemcrypto_build_info));
|
||||||
|
|
||||||
|
device_info_map.canonicalize();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
device_info = device_info_map.canonicalize().encode();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user