Files
android/libwvdrmengine/tools/factory_upload_tool/common/src/WidevineOemcryptoInterface.cpp
conglin 7496c1c84c Move ASOP factory extraction tool to its own directory
Moved some source to common folder.
Added uploading script which is also shared by CE CDM partners.
Added README.

Test: m wv_factory_extraction_tool
Bug: 414642286
Change-Id: I565027b75528ab28f9f1eb8d9086c0213de992d0
2025-06-17 06:23:03 +00:00

167 lines
5.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 "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));
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