Generate random challenge in RKP factory tool
The challenge was previously hard-coded to an empty string previously.
Though it's not necessarily required for remote key provisioning
certificate signing requests, go ahead and include good randomness
(via getrandom) into the csr.
Bug: 191301285
Test: Manually run rkp_factory_extraction_tool
Change-Id: I68e7d86259c67d40ecbb0c9e4ecac22954757dd3
Merged-In: I68e7d86259c67d40ecbb0c9e4ecac22954757dd3
diff --git a/provisioner/rkp_factory_extraction_tool.cpp b/provisioner/rkp_factory_extraction_tool.cpp
index 7c5454a..a6c7d72 100644
--- a/provisioner/rkp_factory_extraction_tool.cpp
+++ b/provisioner/rkp_factory_extraction_tool.cpp
@@ -24,6 +24,7 @@
#include <keymaster/cppcose/cppcose.h>
#include <log/log.h>
#include <remote_prov/remote_prov_utils.h>
+#include <sys/random.h>
#include <vintf/VintfObject.h>
using std::set;
@@ -51,12 +52,28 @@
const string kInterface = "IRemotelyProvisionedComponent";
const string kFormattedName = kPackage + "." + kInterface + "/";
-std::vector<uint8_t> getChallenge() {
- return std::vector<uint8_t>(0);
+constexpr size_t kChallengeSize = 16;
+
+std::vector<uint8_t> generateChallenge() {
+ std::vector<uint8_t> challenge(kChallengeSize);
+
+ ssize_t bytesRemaining = static_cast<ssize_t>(challenge.size());
+ uint8_t* writePtr = challenge.data();
+ while (bytesRemaining > 0) {
+ int bytesRead = getrandom(writePtr, bytesRemaining, /*flags=*/0);
+ if (bytesRead < 0) {
+ LOG_FATAL_IF(errno != EINTR, "%d - %s", errno, strerror(errno));
+ }
+ bytesRemaining -= bytesRead;
+ writePtr += bytesRead;
+ }
+
+ return challenge;
}
std::vector<uint8_t> composeCertificateRequest(ProtectedData&& protectedData,
- DeviceInfo&& deviceInfo) {
+ DeviceInfo&& deviceInfo,
+ const std::vector<uint8_t>& challenge) {
Array emptyMacedKeysToSign;
emptyMacedKeysToSign
.add(std::vector<uint8_t>(0)) // empty protected headers as bstr
@@ -65,7 +82,7 @@
.add(std::vector<uint8_t>(0)); // empty tag as bstr
Array certificateRequest;
certificateRequest.add(EncodedItem(std::move(deviceInfo.deviceInfo)))
- .add(getChallenge()) // fake challenge
+ .add(challenge)
.add(EncodedItem(std::move(protectedData.protectedData)))
.add(std::move(emptyMacedKeysToSign));
return certificateRequest.encode();
@@ -95,6 +112,7 @@
gflags::ParseCommandLineFlags(&argc, &argv, /*remove_flags=*/true);
const std::vector<uint8_t> eek_chain = getEekChain();
+ const std::vector<uint8_t> challenge = generateChallenge();
std::shared_ptr<const HalManifest> manifest = VintfObject::GetDeviceHalManifest();
set<string> rkpNames = manifest->getAidlInstances(kPackage, kInterface);
@@ -116,14 +134,14 @@
if (rkp_service) {
ALOGE("extracting bundle");
::ndk::ScopedAStatus status = rkp_service->generateCertificateRequest(
- FLAGS_test_mode, emptyKeys, eek_chain, getChallenge(), &deviceInfo, &protectedData,
+ FLAGS_test_mode, emptyKeys, eek_chain, challenge, &deviceInfo, &protectedData,
&keysToSignMac);
if (!status.isOk()) {
ALOGE("Bundle extraction failed. Error code: %d", status.getServiceSpecificError());
return errorMsg(name);
}
- std::vector<uint8_t> certificateRequest =
- composeCertificateRequest(std::move(protectedData), std::move(deviceInfo));
+ std::vector<uint8_t> certificateRequest = composeCertificateRequest(
+ std::move(protectedData), std::move(deviceInfo), challenge);
std::copy(certificateRequest.begin(), certificateRequest.end(),
std::ostream_iterator<char>(std::cout));
}