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
201 lines
6.7 KiB
C++
201 lines
6.7 KiB
C++
// Copyright 2021 Google LLC. All Rights Reserved. This file and proprietary
|
|
// source code may only be used and distributed under the Widevine License
|
|
// Agreement.
|
|
|
|
#include "WidevineOemcryptoInterface.h"
|
|
|
|
#include <dlfcn.h>
|
|
|
|
#include "OEMCryptoCENC.h"
|
|
#include "clock.h"
|
|
#include "file_store.h"
|
|
#include "log.h"
|
|
|
|
// These macros lookup the obfuscated name used for OEMCrypto.
|
|
#define QUOTE_DEFINE(A) #A
|
|
#define QUOTE(A) QUOTE_DEFINE(A)
|
|
#define LOOKUP(handle, name) dlsym(handle, QUOTE(name))
|
|
#define LOAD_SYM(name) \
|
|
name = reinterpret_cast<name##_t>(LOOKUP(handle_, OEMCrypto_##name)); \
|
|
if (name == nullptr) { \
|
|
LOGE("%s", dlerror()); \
|
|
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
|
|
// and/or the Testbed, but not needed in this package.
|
|
namespace wvutil {
|
|
int64_t Clock::GetCurrentTime() { return 0; }
|
|
|
|
class FileImpl final : public File {
|
|
public:
|
|
FileImpl() {}
|
|
ssize_t Read(char*, size_t) override { return 0; }
|
|
ssize_t Write(const char*, size_t) override { return 0; }
|
|
};
|
|
|
|
class FileSystem::Impl {
|
|
public:
|
|
Impl() {}
|
|
};
|
|
|
|
FileSystem::FileSystem() {}
|
|
FileSystem::FileSystem(const std::string&, void*) {}
|
|
FileSystem::~FileSystem() {}
|
|
std::unique_ptr<File> FileSystem::Open(const std::string&, int) {
|
|
return std::unique_ptr<File>(new FileImpl());
|
|
}
|
|
bool FileSystem::Exists(const std::string&) { return false; }
|
|
bool FileSystem::Remove(const std::string&) { return false; }
|
|
ssize_t FileSystem::FileSize(const std::string&) { return false; }
|
|
bool FileSystem::List(const std::string&, std::vector<std::string>*) {
|
|
return false;
|
|
}
|
|
|
|
} // namespace wvutil
|
|
|
|
namespace widevine {
|
|
|
|
OEMCryptoInterface::~OEMCryptoInterface() {
|
|
if (Terminate != nullptr) {
|
|
Terminate();
|
|
}
|
|
if (handle_ != nullptr) {
|
|
dlclose(handle_);
|
|
}
|
|
}
|
|
|
|
bool OEMCryptoInterface::Init(const std::string& oemcrypto_path) {
|
|
dlerror();
|
|
handle_ = dlopen(oemcrypto_path.c_str(), RTLD_LAZY | RTLD_GLOBAL);
|
|
if (handle_ == nullptr) {
|
|
LOGE("Can't open OEMCrypto library: %s", dlerror());
|
|
return false;
|
|
}
|
|
LOGI("OEMCrypto library opened.");
|
|
|
|
LOAD_SYM(Initialize);
|
|
LOAD_SYM(Terminate);
|
|
LOAD_SYM(GetBootCertificateChain);
|
|
LOAD_SYM(BuildInformation);
|
|
LOAD_SYM_IF_EXIST(GetDeviceInformation);
|
|
LOAD_SYM_IF_EXIST(GetDeviceSignedCsrPayload);
|
|
|
|
OEMCryptoResult status = Initialize();
|
|
if (status != OEMCrypto_SUCCESS) {
|
|
LOGE("OEMCrypto Initialize failed: %d", status);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
OEMCryptoResult OEMCryptoInterface::GetBcc(std::vector<uint8_t>& bcc) {
|
|
if (handle_ == nullptr) {
|
|
return OEMCrypto_ERROR_INIT_FAILED;
|
|
}
|
|
|
|
bcc.resize(0);
|
|
size_t bcc_size = 0;
|
|
|
|
std::vector<uint8_t> additional_signature; // It should be empty.
|
|
size_t additional_signature_size = 0;
|
|
OEMCryptoResult result = GetBootCertificateChain(bcc.data(), &bcc_size,
|
|
additional_signature.data(),
|
|
&additional_signature_size);
|
|
LOGI("GetBootCertificateChain first attempt result %d", result);
|
|
if (additional_signature_size != 0) {
|
|
LOGW(
|
|
"The additional_signature_size required by OEMCrypto is %zu, while it "
|
|
"is expected to be zero.",
|
|
additional_signature_size);
|
|
}
|
|
|
|
if (result == OEMCrypto_ERROR_SHORT_BUFFER) {
|
|
bcc.resize(bcc_size);
|
|
additional_signature.resize(additional_signature_size);
|
|
result = GetBootCertificateChain(bcc.data(), &bcc_size,
|
|
additional_signature.data(),
|
|
&additional_signature_size);
|
|
if (result == OEMCrypto_SUCCESS) bcc.resize(bcc_size);
|
|
LOGI("GetBootCertificateChain second attempt result %d", result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
OEMCryptoResult OEMCryptoInterface::GetOEMCryptoBuildInfo(
|
|
std::string& build_info) {
|
|
if (handle_ == nullptr) {
|
|
return OEMCrypto_ERROR_INIT_FAILED;
|
|
}
|
|
|
|
build_info.resize(0);
|
|
size_t build_info_size = 0;
|
|
|
|
OEMCryptoResult result = BuildInformation(&build_info[0], &build_info_size);
|
|
LOGI("BuildInformation first attempt result %d", result);
|
|
if (result == OEMCrypto_ERROR_SHORT_BUFFER) {
|
|
build_info.resize(build_info_size);
|
|
result = BuildInformation(&build_info[0], &build_info_size);
|
|
LOGI("BuildInformation second attempt result %d", result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
OEMCryptoResult OEMCryptoInterface::GetVerifiedDeviceInformation(
|
|
std::vector<uint8_t>& verified_device_info) {
|
|
if (handle_ == nullptr) {
|
|
return OEMCrypto_ERROR_INIT_FAILED;
|
|
}
|
|
if (GetDeviceInformation == nullptr) {
|
|
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
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.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;
|
|
}
|
|
|
|
} // namespace widevine
|