diff --git a/libwvdrmengine/tools/factory_upload_tool/cli.cpp b/libwvdrmengine/tools/factory_upload_tool/cli.cpp index eeabacb9..76468be2 100644 --- a/libwvdrmengine/tools/factory_upload_tool/cli.cpp +++ b/libwvdrmengine/tools/factory_upload_tool/cli.cpp @@ -6,45 +6,50 @@ #define LOG_TAG "wv_factory_extraction_tool" +#include + #include -#include #include +#include #include #include #include #include #include -#include - #include "WidevineProvisioner.h" -constexpr size_t kChallengeSize = 16; +constexpr size_t kChallengeSize = 32; -// The Google root key for the Endpoint Encryption Key chain, encoded as COSE_Sign1 +// The Google root key for the Endpoint Encryption Key chain, encoded as +// COSE_Sign1 inline constexpr uint8_t kCoseEncodedRootCert[] = { - 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x58, 0x2a, 0xa4, 0x01, 0x01, 0x03, 0x27, 0x20, 0x06, - 0x21, 0x58, 0x20, 0x99, 0xb9, 0xee, 0xdd, 0x5e, 0xe4, 0x52, 0xf6, 0x85, 0xc6, 0x4c, 0x62, - 0xdc, 0x3e, 0x61, 0xab, 0x57, 0x48, 0x7d, 0x75, 0x37, 0x29, 0xad, 0x76, 0x80, 0x32, 0xd2, - 0xb3, 0xcb, 0x63, 0x58, 0xd9, 0x58, 0x40, 0x1e, 0x22, 0x08, 0x4b, 0xa4, 0xb7, 0xa4, 0xc8, - 0xd7, 0x4e, 0x03, 0x0e, 0xfe, 0xb8, 0xaf, 0x14, 0x4c, 0xa7, 0x3b, 0x6f, 0xa5, 0xcd, 0xdc, - 0xda, 0x79, 0xc6, 0x2b, 0x64, 0xfe, 0x99, 0x39, 0xaf, 0x76, 0xe7, 0x80, 0xfa, 0x66, 0x00, - 0x85, 0x0d, 0x07, 0x98, 0x2a, 0xac, 0x91, 0x5c, 0xa7, 0x25, 0x14, 0x49, 0x06, 0x34, 0x75, - 0xca, 0x8a, 0x27, 0x7a, 0xd9, 0xe3, 0x5a, 0x49, 0xeb, 0x02, 0x03}; + 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x58, 0x2a, 0xa4, 0x01, 0x01, 0x03, + 0x27, 0x20, 0x06, 0x21, 0x58, 0x20, 0x99, 0xb9, 0xee, 0xdd, 0x5e, 0xe4, + 0x52, 0xf6, 0x85, 0xc6, 0x4c, 0x62, 0xdc, 0x3e, 0x61, 0xab, 0x57, 0x48, + 0x7d, 0x75, 0x37, 0x29, 0xad, 0x76, 0x80, 0x32, 0xd2, 0xb3, 0xcb, 0x63, + 0x58, 0xd9, 0x58, 0x40, 0x1e, 0x22, 0x08, 0x4b, 0xa4, 0xb7, 0xa4, 0xc8, + 0xd7, 0x4e, 0x03, 0x0e, 0xfe, 0xb8, 0xaf, 0x14, 0x4c, 0xa7, 0x3b, 0x6f, + 0xa5, 0xcd, 0xdc, 0xda, 0x79, 0xc6, 0x2b, 0x64, 0xfe, 0x99, 0x39, 0xaf, + 0x76, 0xe7, 0x80, 0xfa, 0x66, 0x00, 0x85, 0x0d, 0x07, 0x98, 0x2a, 0xac, + 0x91, 0x5c, 0xa7, 0x25, 0x14, 0x49, 0x06, 0x34, 0x75, 0xca, 0x8a, 0x27, + 0x7a, 0xd9, 0xe3, 0x5a, 0x49, 0xeb, 0x02, 0x03}; // The Google Endpoint Encryption Key certificate, encoded as COSE_Sign1 inline constexpr uint8_t kCoseEncodedGeekCert[] = { - 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x58, 0x4e, 0xa5, 0x01, 0x01, 0x02, 0x58, 0x20, - 0xd0, 0xae, 0xc1, 0x15, 0xca, 0x2a, 0xcf, 0x73, 0xae, 0x6b, 0xcc, 0xcb, 0xd1, 0x96, - 0x1d, 0x65, 0xe8, 0xb1, 0xdd, 0xd7, 0x4a, 0x1a, 0x37, 0xb9, 0x43, 0x3a, 0x97, 0xd5, - 0x99, 0xdf, 0x98, 0x08, 0x03, 0x38, 0x18, 0x20, 0x04, 0x21, 0x58, 0x20, 0xbe, 0x85, - 0xe7, 0x46, 0xc4, 0xa3, 0x42, 0x5a, 0x40, 0xd9, 0x36, 0x3a, 0xa6, 0x15, 0xd0, 0x2c, - 0x58, 0x7e, 0x3d, 0xdc, 0x33, 0x02, 0x32, 0xd2, 0xfc, 0x5e, 0x1e, 0x87, 0x25, 0x5f, - 0x72, 0x60, 0x58, 0x40, 0x9b, 0xcf, 0x90, 0xe2, 0x2e, 0x4b, 0xab, 0xd1, 0x18, 0xb1, - 0x0e, 0x8e, 0x5d, 0x20, 0x27, 0x4b, 0x84, 0x58, 0xfe, 0xfc, 0x32, 0x90, 0x7e, 0x72, - 0x05, 0x83, 0xbc, 0xd7, 0x82, 0xbe, 0xfa, 0x64, 0x78, 0x2d, 0x54, 0x10, 0x4b, 0xc0, - 0x31, 0xbf, 0x6b, 0xe8, 0x1e, 0x35, 0xe2, 0xf0, 0x2d, 0xce, 0x6c, 0x2f, 0x4f, 0xf2, - 0xf5, 0x4f, 0xa5, 0xd4, 0x83, 0xad, 0x96, 0xa2, 0xf1, 0x87, 0x58, 0x04}; + 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x58, 0x4e, 0xa5, 0x01, 0x01, 0x02, + 0x58, 0x20, 0xd0, 0xae, 0xc1, 0x15, 0xca, 0x2a, 0xcf, 0x73, 0xae, 0x6b, + 0xcc, 0xcb, 0xd1, 0x96, 0x1d, 0x65, 0xe8, 0xb1, 0xdd, 0xd7, 0x4a, 0x1a, + 0x37, 0xb9, 0x43, 0x3a, 0x97, 0xd5, 0x99, 0xdf, 0x98, 0x08, 0x03, 0x38, + 0x18, 0x20, 0x04, 0x21, 0x58, 0x20, 0xbe, 0x85, 0xe7, 0x46, 0xc4, 0xa3, + 0x42, 0x5a, 0x40, 0xd9, 0x36, 0x3a, 0xa6, 0x15, 0xd0, 0x2c, 0x58, 0x7e, + 0x3d, 0xdc, 0x33, 0x02, 0x32, 0xd2, 0xfc, 0x5e, 0x1e, 0x87, 0x25, 0x5f, + 0x72, 0x60, 0x58, 0x40, 0x9b, 0xcf, 0x90, 0xe2, 0x2e, 0x4b, 0xab, 0xd1, + 0x18, 0xb1, 0x0e, 0x8e, 0x5d, 0x20, 0x27, 0x4b, 0x84, 0x58, 0xfe, 0xfc, + 0x32, 0x90, 0x7e, 0x72, 0x05, 0x83, 0xbc, 0xd7, 0x82, 0xbe, 0xfa, 0x64, + 0x78, 0x2d, 0x54, 0x10, 0x4b, 0xc0, 0x31, 0xbf, 0x6b, 0xe8, 0x1e, 0x35, + 0xe2, 0xf0, 0x2d, 0xce, 0x6c, 0x2f, 0x4f, 0xf2, 0xf5, 0x4f, 0xa5, 0xd4, + 0x83, 0xad, 0x96, 0xa2, 0xf1, 0x87, 0x58, 0x04}; std::vector generateChallenge() { std::vector challenge(kChallengeSize); @@ -70,10 +75,10 @@ std::vector generateChallenge() { std::vector getEekChain() { cppbor::Array chain; - chain.add(cppbor::EncodedItem( - std::vector(std::begin(kCoseEncodedRootCert), std::end(kCoseEncodedRootCert)))); - chain.add(cppbor::EncodedItem( - std::vector(std::begin(kCoseEncodedGeekCert), std::end(kCoseEncodedGeekCert)))); + chain.add(cppbor::EncodedItem(std::vector( + std::begin(kCoseEncodedRootCert), std::end(kCoseEncodedRootCert)))); + chain.add(cppbor::EncodedItem(std::vector( + std::begin(kCoseEncodedGeekCert), std::end(kCoseEncodedGeekCert)))); return chain.encode(); } @@ -81,20 +86,23 @@ cppbor::Array composeCertificateRequest( const std::vector& protectedData, const std::vector& verifiedDeviceInfo, const std::vector& challenge) { - cppbor::Array macedKeysToSign = cppbor::Array() - .add(std::vector(0)) // empty protected headers as bstr - .add(cppbor::Map()) // empty unprotected headers - .add(cppbor::Null()) // nil for the payload - .add(std::vector(0)); // MAC as returned from the HAL + cppbor::Array macedKeysToSign = + cppbor::Array() + .add(std::vector(0)) // empty protected headers as bstr + .add(cppbor::Map()) // empty unprotected headers + .add(cppbor::Null()) // nil for the payload + .add(std::vector(0)); // MAC as returned from the HAL - cppbor::Array deviceInfo = - cppbor::Array().add(cppbor::EncodedItem(verifiedDeviceInfo)).add(cppbor::Map()); // Empty device info + cppbor::Array deviceInfo = cppbor::Array() + .add(cppbor::EncodedItem(verifiedDeviceInfo)) + .add(cppbor::Map()); // Empty device info - cppbor::Array certificateRequest = cppbor::Array() - .add(std::move(deviceInfo)) - .add(challenge) - .add(cppbor::EncodedItem(protectedData)) - .add(std::move(macedKeysToSign)); + cppbor::Array certificateRequest = + cppbor::Array() + .add(std::move(deviceInfo)) + .add(challenge) + .add(cppbor::EncodedItem(protectedData)) + .add(std::move(macedKeysToSign)); return certificateRequest; } @@ -103,37 +111,51 @@ cppbor::Array getCsr(widevine::WidevineProvisioner& provisioner) { std::vector verifiedDeviceInfo; std::vector protectedData; - if (!provisioner.GenerateCertificateRequest(false, getEekChain(), - verifiedDeviceInfo, - protectedData)) { - std::cerr << "Failed to generate certificate request." << std::endl; + if (!provisioner.GenerateCertificateRequest( + false, getEekChain(), verifiedDeviceInfo, protectedData)) { + std::cerr << "Failed to generate certificate request." << std::endl; exit(-1); } auto csr = - composeCertificateRequest(protectedData, verifiedDeviceInfo, challenge); + composeCertificateRequest(protectedData, verifiedDeviceInfo, challenge); + return csr; +} + +std::vector getCsrV3(widevine::WidevineProvisioner& provisioner) { + const std::vector challenge = generateChallenge(); + std::vector csr; + + if (!provisioner.GenerateCertificateRequestV2(challenge, &csr)) { + std::cerr << "Failed to generate certificate request v2." << std::endl; + exit(-1); + } return csr; } int main(int argc, char** argv) { - if (argc<2) { - fprintf(stderr,"%s \n",argv[0]); + if (argc < 2) { + fprintf(stderr, "%s \n", argv[0]); return 0; } widevine::WidevineProvisioner provisioner; - if (!std::strcmp(argv[1],"bcc")) { + if (!std::strcmp(argv[1], "bcc")) { auto bcc = provisioner.GetBcc(); - fwrite(bcc.data(), 1 , bcc.size(), stdout); + fwrite(bcc.data(), 1, bcc.size(), stdout); fflush(stdout); - } else if (!std::strcmp(argv[1],"device_info")) { + } else if (!std::strcmp(argv[1], "device_info")) { std::vector deviceInfo; if (provisioner.GetDeviceInfo(deviceInfo)) { - fwrite(deviceInfo.data(), 1 , deviceInfo.size(), stdout); + fwrite(deviceInfo.data(), 1, deviceInfo.size(), stdout); fflush(stdout); } - } else if (!std::strcmp(argv[1],"csr")) { + } else if (!std::strcmp(argv[1], "csr")) { auto csr = getCsr(provisioner); auto bytes = csr.encode(); - std::copy(bytes.begin(), bytes.end(), std::ostream_iterator(std::cout)); + std::copy(bytes.begin(), bytes.end(), + std::ostream_iterator(std::cout)); + } else if (!std::strcmp(argv[1], "csr_v3")) { + auto csr = getCsrV3(provisioner); + std::copy(csr.begin(), csr.end(), std::ostream_iterator(std::cout)); } return 0; } diff --git a/libwvdrmengine/tools/factory_upload_tool/include/WidevineOemcryptoInterface.h b/libwvdrmengine/tools/factory_upload_tool/include/WidevineOemcryptoInterface.h index 1723d985..c5f02c58 100644 --- a/libwvdrmengine/tools/factory_upload_tool/include/WidevineOemcryptoInterface.h +++ b/libwvdrmengine/tools/factory_upload_tool/include/WidevineOemcryptoInterface.h @@ -13,13 +13,6 @@ namespace widevine { -struct VerifiedDeviceInfo { - std::vector device_info; - // Used by Interface of Remote Provisioning Component (IRPC) v3 for CSR - // uploading - std::vector signed_csr_payload; -}; - class OEMCryptoInterface { public: OEMCryptoInterface() = default; @@ -40,7 +33,13 @@ class OEMCryptoInterface { // Retrieves the verified device information of the OEMCrypto library from // OEMCrypto implementation. OEMCryptoResult GetVerifiedDeviceInformation( - VerifiedDeviceInfo& verified_device_info); + std::vector& verified_device_info); + + // Generates device registration CSR payload and signs it with the leaf cert + // of BCC. + OEMCryptoResult GetSignedCsrPayload(const std::vector& challenge, + const std::vector& device_info, + std::vector& signed_csr_payload); private: typedef OEMCryptoResult (*Initialize_t)(); @@ -50,8 +49,11 @@ class OEMCryptoInterface { size_t* additional_signature_size); typedef OEMCryptoResult (*BuildInformation_t)(char* buffer, size_t* buffer_length); - typedef OEMCryptoResult (*GetDeviceInformation_t)( - uint8_t* device_info, size_t* device_info_length, + typedef OEMCryptoResult (*GetDeviceInformation_t)(uint8_t* device_info, + size_t* device_info_length); + typedef OEMCryptoResult (*GetDeviceSignedCsrPayload_t)( + const uint8_t* challenge, size_t challenge_length, + const uint8_t* device_info, size_t device_info_length, uint8_t* signed_csr_payload, size_t* signed_csr_payload_length); Initialize_t Initialize = nullptr; @@ -59,6 +61,7 @@ class OEMCryptoInterface { GetBootCertificateChain_t GetBootCertificateChain = nullptr; BuildInformation_t BuildInformation = nullptr; GetDeviceInformation_t GetDeviceInformation = nullptr; + GetDeviceSignedCsrPayload_t GetDeviceSignedCsrPayload = nullptr; void* handle_ = nullptr; }; diff --git a/libwvdrmengine/tools/factory_upload_tool/include/WidevineProvisioner.h b/libwvdrmengine/tools/factory_upload_tool/include/WidevineProvisioner.h index ea3ff86d..d3e81d9d 100644 --- a/libwvdrmengine/tools/factory_upload_tool/include/WidevineProvisioner.h +++ b/libwvdrmengine/tools/factory_upload_tool/include/WidevineProvisioner.h @@ -29,7 +29,8 @@ class WidevineProvisioner { bool GenerateCertificateRequest( bool testMode, const std::vector& endpointEncCertChain, std::vector& deviceInfo, std::vector& protectedData); - + bool GenerateCertificateRequestV2(const std::vector& challenge, + std::vector* csr); bool GetDeviceInfo(std::vector& device_info); private: @@ -46,6 +47,7 @@ class WidevineProvisioner { void InitializeCryptoInterface(); bool GetDeviceInfoCommon(cppbor::Map& device_info_map); bool TryAddVerifiedDeviceInfo(cppbor::Map& device_info_map); + bool GetDeviceInfoV2(cppbor::Map& device_info_map); std::unique_ptr crypto_interface_; }; diff --git a/libwvdrmengine/tools/factory_upload_tool/src/WidevineOemcryptoInterface.cpp b/libwvdrmengine/tools/factory_upload_tool/src/WidevineOemcryptoInterface.cpp index 1e52d4af..ccb105a3 100644 --- a/libwvdrmengine/tools/factory_upload_tool/src/WidevineOemcryptoInterface.cpp +++ b/libwvdrmengine/tools/factory_upload_tool/src/WidevineOemcryptoInterface.cpp @@ -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& 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& challenge, + const std::vector& device_info, + std::vector& 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; } diff --git a/libwvdrmengine/tools/factory_upload_tool/src/WidevineProvisioner.cpp b/libwvdrmengine/tools/factory_upload_tool/src/WidevineProvisioner.cpp index 2c99cea5..7348e358 100644 --- a/libwvdrmengine/tools/factory_upload_tool/src/WidevineProvisioner.cpp +++ b/libwvdrmengine/tools/factory_upload_tool/src/WidevineProvisioner.cpp @@ -42,7 +42,7 @@ std::vector WidevineProvisioner::GetBcc() { std::vector 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 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 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(verified_device_info.device_info.data()), - verified_device_info.device_info.size()); + reinterpret_cast(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& 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& challenge, std::vector* csr) { + if (csr == nullptr) { + LOGE("CSR is null."); + return false; + } + // Prepare BCC + std::vector 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 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)) {