Merge changes from topic "rkp-factory-tool-redux" into sc-dev

* changes:
  Generate random challenge in RKP factory tool
  Add prod GEEK to rkp_factory_extraction_tool
  Remove duplicate generateEekChain routine
diff --git a/provisioner/Android.bp b/provisioner/Android.bp
index ea84063..86f0f12 100644
--- a/provisioner/Android.bp
+++ b/provisioner/Android.bp
@@ -53,8 +53,9 @@
         "libcppbor_external",
         "libcppcose_rkp",
         "libcrypto",
+        "libgflags",
         "liblog",
+        "libkeymint_remote_prov_support",
         "libvintf",
     ],
-    //export_include_dirs: ["include"],
 }
diff --git a/provisioner/rkp_factory_extraction_tool.cpp b/provisioner/rkp_factory_extraction_tool.cpp
index d4842b1..a6c7d72 100644
--- a/provisioner/rkp_factory_extraction_tool.cpp
+++ b/provisioner/rkp_factory_extraction_tool.cpp
@@ -20,8 +20,11 @@
 #include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
 #include <android/binder_manager.h>
 #include <cppbor.h>
+#include <gflags/gflags.h>
 #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;
@@ -32,6 +35,8 @@
 using aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent;
 using aidl::android::hardware::security::keymint::MacedPublicKey;
 using aidl::android::hardware::security::keymint::ProtectedData;
+using aidl::android::hardware::security::keymint::remote_prov::generateEekChain;
+using aidl::android::hardware::security::keymint::remote_prov::getProdEekChain;
 
 using android::vintf::HalManifest;
 using android::vintf::VintfObject;
@@ -39,66 +44,36 @@
 using namespace cppbor;
 using namespace cppcose;
 
+DEFINE_bool(test_mode, false, "If enabled, a fake EEK key/cert are used.");
+
 namespace {
 
 const string kPackage = "android.hardware.security.keymint";
 const string kInterface = "IRemotelyProvisionedComponent";
 const string kFormattedName = kPackage + "." + kInterface + "/";
 
-ErrMsgOr<vector<uint8_t>> generateEekChain(size_t length, const vector<uint8_t>& eekId) {
-    auto eekChain = cppbor::Array();
+constexpr size_t kChallengeSize = 16;
 
-    vector<uint8_t> prevPrivKey;
-    for (size_t i = 0; i < length - 1; ++i) {
-        vector<uint8_t> pubKey(ED25519_PUBLIC_KEY_LEN);
-        vector<uint8_t> privKey(ED25519_PRIVATE_KEY_LEN);
+std::vector<uint8_t> generateChallenge() {
+    std::vector<uint8_t> challenge(kChallengeSize);
 
-        ED25519_keypair(pubKey.data(), privKey.data());
-
-        // The first signing key is self-signed.
-        if (prevPrivKey.empty()) prevPrivKey = privKey;
-
-        auto coseSign1 = constructCoseSign1(prevPrivKey,
-                                            cppbor::Map() /* payload CoseKey */
-                                                .add(CoseKey::KEY_TYPE, OCTET_KEY_PAIR)
-                                                .add(CoseKey::ALGORITHM, EDDSA)
-                                                .add(CoseKey::CURVE, ED25519)
-                                                .add(CoseKey::PUBKEY_X, pubKey)
-                                                .canonicalize()
-                                                .encode(),
-                                            {} /* AAD */);
-        if (!coseSign1) return coseSign1.moveMessage();
-        eekChain.add(coseSign1.moveValue());
-
-        prevPrivKey = privKey;
+    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;
     }
 
-    vector<uint8_t> pubKey(X25519_PUBLIC_VALUE_LEN);
-    vector<uint8_t> privKey(X25519_PRIVATE_KEY_LEN);
-    X25519_keypair(pubKey.data(), privKey.data());
-
-    auto coseSign1 = constructCoseSign1(prevPrivKey,
-                                        cppbor::Map() /* payload CoseKey */
-                                            .add(CoseKey::KEY_TYPE, OCTET_KEY_PAIR)
-                                            .add(CoseKey::KEY_ID, eekId)
-                                            .add(CoseKey::ALGORITHM, ECDH_ES_HKDF_256)
-                                            .add(CoseKey::CURVE, cppcose::X25519)
-                                            .add(CoseKey::PUBKEY_X, pubKey)
-                                            .canonicalize()
-                                            .encode(),
-                                        {} /* AAD */);
-    if (!coseSign1) return coseSign1.moveMessage();
-    eekChain.add(coseSign1.moveValue());
-
-    return eekChain.encode();
-}
-
-std::vector<uint8_t> getChallenge() {
-    return std::vector<uint8_t>(0);
+    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
@@ -107,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();
@@ -118,9 +93,27 @@
     return -1;
 }
 
+std::vector<uint8_t> getEekChain() {
+    if (FLAGS_test_mode) {
+        const std::vector<uint8_t> kFakeEekId = {'f', 'a', 'k', 'e', 0};
+        auto eekOrErr = generateEekChain(3 /* chainlength */, kFakeEekId);
+        LOG_FATAL_IF(!eekOrErr, "Failed to generate test EEK somehow: %s",
+                     eekOrErr.message().c_str());
+        auto [eek, ignored_pubkey, ignored_privkey] = eekOrErr.moveValue();
+        return eek;
+    }
+
+    return getProdEekChain();
+}
+
 }  // namespace
 
-int main() {
+int main(int argc, char** argv) {
+    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);
     for (auto name : rkpNames) {
@@ -136,29 +129,19 @@
         std::vector<uint8_t> keysToSignMac;
         std::vector<MacedPublicKey> emptyKeys;
 
-        // Replace this eek chain generation with the actual production GEEK
-        std::vector<uint8_t> eekId(10);  // replace with real KID later (EEK fingerprint)
-        auto eekOrErr = generateEekChain(3 /* chainlength */, eekId);
-        if (!eekOrErr) {
-            ALOGE("Failed to generate test EEK somehow: %s", eekOrErr.message().c_str());
-            return errorMsg(name);
-        }
-
-        std::vector<uint8_t> eek = eekOrErr.moveValue();
         DeviceInfo deviceInfo;
         ProtectedData protectedData;
         if (rkp_service) {
             ALOGE("extracting bundle");
             ::ndk::ScopedAStatus status = rkp_service->generateCertificateRequest(
-                true /* testMode */, emptyKeys, eek, 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::cout << "\n";
-            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));
         }