update_engine: Add GetMinFirmwareKeyVersion to read tpm_fwver value

Add function to read the minimum allowed firmware key version, ie.
crossystem tpm_fwver.

This is the firmware key version equivalent of crrev.com/c/927827.

BUG=chromium:840432
TEST='cros_run_unit_tests --board=caroline --packages update_engine'

Change-Id: Iadd56b3283028722c94e4ebc7cf5b6470cf1fec9
Reviewed-on: https://chromium-review.googlesource.com/1049667
Commit-Ready: Marton Hunyady <[email protected]>
Tested-by: Marton Hunyady <[email protected]>
Reviewed-by: Amin Hassani <[email protected]>
Reviewed-by: Zentaro Kavanagh <[email protected]>
diff --git a/common/fake_hardware.h b/common/fake_hardware.h
index 021d891..68fdd5b 100644
--- a/common/fake_hardware.h
+++ b/common/fake_hardware.h
@@ -37,6 +37,9 @@
   // Default value for crossystem tpm_kernver.
   static const int kMinKernelKeyVersion = 3;
 
+  // Default value for crossystem tpm_fwver.
+  static const int kMinFirmwareKeyVersion = 13;
+
   // Default value for crossystem max_kernel_rollforward. This value is the
   // default for consumer devices and effectively means "unlimited rollforward
   // is allowed", which is the same as the behavior prior to implementing
@@ -72,6 +75,10 @@
     return min_kernel_key_version_;
   }
 
+  int GetMinFirmwareKeyVersion() const override {
+    return min_firmware_key_version_;
+  }
+
   bool SetMaxKernelKeyRollforward(int max_kernel_rollforward) override {
     max_kernel_rollforward_ = max_kernel_rollforward;
     return true;
@@ -151,6 +158,10 @@
     min_kernel_key_version_ = min_kernel_key_version;
   }
 
+  void SetMinFirmwareKeyVersion(int min_firmware_key_version) {
+    min_firmware_key_version_ = min_firmware_key_version;
+  }
+
   void SetPowerwashCount(int powerwash_count) {
     powerwash_count_ = powerwash_count;
   }
@@ -170,6 +181,7 @@
   std::string firmware_version_{"Fake Firmware v1.0.1"};
   std::string ec_version_{"Fake EC v1.0a"};
   int min_kernel_key_version_{kMinKernelKeyVersion};
+  int min_firmware_key_version_{kMinFirmwareKeyVersion};
   int max_kernel_rollforward_{kMaxKernelRollforward};
   int powerwash_count_{kPowerwashCountNotSet};
   bool powerwash_scheduled_{false};
diff --git a/common/hardware_interface.h b/common/hardware_interface.h
index 9f3f618..4946b91 100644
--- a/common/hardware_interface.h
+++ b/common/hardware_interface.h
@@ -73,6 +73,11 @@
   // -1 on error, or if not running on Chrome OS.
   virtual int GetMinKernelKeyVersion() const = 0;
 
+  // Returns the minimum firmware key version that verified boot on Chrome OS
+  // will allow to boot. This is the value of crossystem tpm_fwver. Returns
+  // -1 on error, or if not running on Chrome OS.
+  virtual int GetMinFirmwareKeyVersion() const = 0;
+
   // Sets the maximum kernel key version that verified boot should roll
   // forward to. This is the value of crossystem max_kernel_rollforward.
   // Returns false if the value cannot be set, or if not running on Chrome OS.
diff --git a/common/mock_hardware.h b/common/mock_hardware.h
index 03ebfdb..fcbb0d5 100644
--- a/common/mock_hardware.h
+++ b/common/mock_hardware.h
@@ -57,6 +57,9 @@
     ON_CALL(*this, GetMinKernelKeyVersion())
         .WillByDefault(
             testing::Invoke(&fake_, &FakeHardware::GetMinKernelKeyVersion));
+    ON_CALL(*this, GetMinFirmwareKeyVersion())
+        .WillByDefault(
+            testing::Invoke(&fake_, &FakeHardware::GetMinFirmwareKeyVersion));
     ON_CALL(*this, SetMaxKernelKeyRollforward())
         .WillByDefault(
             testing::Invoke(&fake_, &FakeHardware::SetMaxKernelKeyRollforward));
@@ -88,6 +91,7 @@
   MOCK_CONST_METHOD0(GetFirmwareVersion, std::string());
   MOCK_CONST_METHOD0(GetECVersion, std::string());
   MOCK_CONST_METHOD0(GetMinKernelKeyVersion, int());
+  MOCK_CONST_METHOD0(GetMinFirmwareKeyVersion, int());
   MOCK_CONST_METHOD1(SetMaxKernelKeyRollforward,
                      bool(int max_kernel_rollforward));
   MOCK_CONST_METHOD0(GetPowerwashCount, int());
diff --git a/hardware_android.cc b/hardware_android.cc
index 7bd296b..6812c71 100644
--- a/hardware_android.cc
+++ b/hardware_android.cc
@@ -170,6 +170,11 @@
   return -1;
 }
 
+int HardwareAndroid::GetMinFirmwareKeyVersion() const {
+  LOG(WARNING) << "STUB: No Firmware key version is available.";
+  return -1;
+}
+
 bool HardwareAndroid::SetMaxKernelKeyRollforward(int max_kernel_rollforward) {
   LOG(WARNING) << "STUB: Setting max_kernel_rollforward is not supported.";
   return false;
diff --git a/hardware_android.h b/hardware_android.h
index 120ccab..4d354ac 100644
--- a/hardware_android.h
+++ b/hardware_android.h
@@ -43,6 +43,7 @@
   std::string GetFirmwareVersion() const override;
   std::string GetECVersion() const override;
   int GetMinKernelKeyVersion() const override;
+  int GetMinFirmwareKeyVersion() const override;
   bool SetMaxKernelKeyRollforward(int max_kernel_rollforward) override;
   int GetPowerwashCount() const override;
   bool SchedulePowerwash() override;
diff --git a/hardware_chromeos.cc b/hardware_chromeos.cc
index d9c13a3..3099151 100644
--- a/hardware_chromeos.cc
+++ b/hardware_chromeos.cc
@@ -186,6 +186,10 @@
   return VbGetSystemPropertyInt("tpm_kernver");
 }
 
+int HardwareChromeOS::GetMinFirmwareKeyVersion() const {
+  return VbGetSystemPropertyInt("tpm_fwver");
+}
+
 bool HardwareChromeOS::SetMaxKernelKeyRollforward(int max_kernel_rollforward) {
   return VbSetSystemPropertyInt("max_kernel_rollforward",
                                 max_kernel_rollforward) == 0;
diff --git a/hardware_chromeos.h b/hardware_chromeos.h
index 2d43931..9cb02f8 100644
--- a/hardware_chromeos.h
+++ b/hardware_chromeos.h
@@ -48,6 +48,7 @@
   std::string GetFirmwareVersion() const override;
   std::string GetECVersion() const override;
   int GetMinKernelKeyVersion() const override;
+  int GetMinFirmwareKeyVersion() const override;
   bool SetMaxKernelKeyRollforward(int max_kernel_rollforward) override;
   int GetPowerwashCount() const override;
   bool SchedulePowerwash() override;