update_engine: Add hardware support for firmware_max_rollforward
- Adds the methods to get and set firmware_max_rollforward
- This is for supporting the rollback feature
- A future CL will set these values based on policy
BUG=chromium:840432
TEST=unittests
Change-Id: I560f4cef9595d4a52d011fcfeb7b2675a096aefa
Reviewed-on: https://chromium-review.googlesource.com/1062766
Commit-Ready: Zentaro Kavanagh <zentaro@chromium.org>
Tested-by: Zentaro Kavanagh <zentaro@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
diff --git a/common/fake_hardware.h b/common/fake_hardware.h
index d68b0f8..55dcc2c 100644
--- a/common/fake_hardware.h
+++ b/common/fake_hardware.h
@@ -44,7 +44,13 @@
// default for consumer devices and effectively means "unlimited rollforward
// is allowed", which is the same as the behavior prior to implementing
// roll forward prevention.
- static const int kMaxKernelRollforward = 0xfffffffe;
+ static const int kKernelMaxRollforward = 0xfffffffe;
+
+ // Default value for crossystem firmware_max_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
+ // roll forward prevention.
+ static const int kFirmwareMaxRollforward = 0xfffffffe;
FakeHardware() = default;
@@ -79,6 +85,18 @@
return min_firmware_key_version_;
}
+ int GetMaxFirmwareKeyRollforward() const override {
+ return firmware_max_rollforward_;
+ }
+
+ bool SetMaxFirmwareKeyRollforward(int firmware_max_rollforward) override {
+ if (GetMaxFirmwareKeyRollforward() == -1)
+ return false;
+
+ firmware_max_rollforward_ = firmware_max_rollforward;
+ return true;
+ }
+
bool SetMaxKernelKeyRollforward(int kernel_max_rollforward) override {
kernel_max_rollforward_ = kernel_max_rollforward;
return true;
@@ -183,7 +201,8 @@
std::string ec_version_{"Fake EC v1.0a"};
int min_kernel_key_version_{kMinKernelKeyVersion};
int min_firmware_key_version_{kMinFirmwareKeyVersion};
- int kernel_max_rollforward_{kMaxKernelRollforward};
+ int kernel_max_rollforward_{kKernelMaxRollforward};
+ int firmware_max_rollforward_{kFirmwareMaxRollforward};
int powerwash_count_{kPowerwashCountNotSet};
bool powerwash_scheduled_{false};
bool first_active_omaha_ping_sent_{false};
diff --git a/common/hardware_interface.h b/common/hardware_interface.h
index 239e7c8..dd42e05 100644
--- a/common/hardware_interface.h
+++ b/common/hardware_interface.h
@@ -78,6 +78,17 @@
// -1 on error, or if not running on Chrome OS.
virtual int GetMinFirmwareKeyVersion() const = 0;
+ // Returns the maximum firmware key version that verified boot should roll
+ // forward to. This is the value of crossystem firmware_max_rollforward.
+ // Returns -1 on error, if this board does not yet support this value, or
+ // if not running on Chrome OS.
+ virtual int GetMaxFirmwareKeyRollforward() const = 0;
+
+ // Sets the maximum firmware key version that verified boot should roll
+ // forward to. This is the value of crossystem firmware_max_rollforward.
+ // This value is not available on all Chrome OS devices.
+ virtual bool SetMaxFirmwareKeyRollforward(int firmware_max_rollforward) = 0;
+
// Sets the maximum kernel key version that verified boot should roll
// forward to. This is the value of crossystem kernel_max_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 662ccd9..f972df2 100644
--- a/common/mock_hardware.h
+++ b/common/mock_hardware.h
@@ -60,6 +60,12 @@
ON_CALL(*this, GetMinFirmwareKeyVersion())
.WillByDefault(
testing::Invoke(&fake_, &FakeHardware::GetMinFirmwareKeyVersion));
+ ON_CALL(*this, GetMaxFirmwareKeyRollforward())
+ .WillByDefault(testing::Invoke(
+ &fake_, &FakeHardware::GetMaxFirmwareKeyRollforward));
+ ON_CALL(*this, SetMaxFirmwareKeyRollforward())
+ .WillByDefault(testing::Invoke(
+ &fake_, &FakeHardware::SetMaxFirmwareKeyRollforward));
ON_CALL(*this, SetMaxKernelKeyRollforward())
.WillByDefault(
testing::Invoke(&fake_, &FakeHardware::SetMaxKernelKeyRollforward));
@@ -92,6 +98,9 @@
MOCK_CONST_METHOD0(GetECVersion, std::string());
MOCK_CONST_METHOD0(GetMinKernelKeyVersion, int());
MOCK_CONST_METHOD0(GetMinFirmwareKeyVersion, int());
+ MOCK_CONST_METHOD0(GetMaxFirmwareKeyRollforward, int());
+ MOCK_CONST_METHOD1(SetMaxFirmwareKeyRollforward,
+ bool(int firmware_max_rollforward));
MOCK_CONST_METHOD1(SetMaxKernelKeyRollforward,
bool(int kernel_max_rollforward));
MOCK_CONST_METHOD0(GetPowerwashCount, int());
diff --git a/hardware_android.cc b/hardware_android.cc
index 3f0fb59..deabc5c 100644
--- a/hardware_android.cc
+++ b/hardware_android.cc
@@ -174,6 +174,17 @@
return -1;
}
+int HardwareAndroid::GetMaxFirmwareKeyRollforward() const {
+ LOG(WARNING) << "STUB: Getting firmware_max_rollforward is not supported.";
+ return -1;
+}
+
+bool HardwareAndroid::SetMaxFirmwareKeyRollforward(
+ int firmware_max_rollforward) {
+ LOG(WARNING) << "STUB: Setting firmware_max_rollforward is not supported.";
+ return false;
+}
+
bool HardwareAndroid::SetMaxKernelKeyRollforward(int kernel_max_rollforward) {
LOG(WARNING) << "STUB: Setting kernel_max_rollforward is not supported.";
return false;
diff --git a/hardware_android.h b/hardware_android.h
index 981f033..b7a6f96 100644
--- a/hardware_android.h
+++ b/hardware_android.h
@@ -44,6 +44,8 @@
std::string GetECVersion() const override;
int GetMinKernelKeyVersion() const override;
int GetMinFirmwareKeyVersion() const override;
+ int GetMaxFirmwareKeyRollforward() const override;
+ bool SetMaxFirmwareKeyRollforward(int firmware_max_rollforward) override;
bool SetMaxKernelKeyRollforward(int kernel_max_rollforward) override;
int GetPowerwashCount() const override;
bool SchedulePowerwash() override;
diff --git a/hardware_chromeos.cc b/hardware_chromeos.cc
index 08303d0..6cfe5ef 100644
--- a/hardware_chromeos.cc
+++ b/hardware_chromeos.cc
@@ -186,6 +186,21 @@
return VbGetSystemPropertyInt("tpm_kernver");
}
+int HardwareChromeOS::GetMaxFirmwareKeyRollforward() const {
+ return VbGetSystemPropertyInt("firmware_max_rollforward");
+}
+
+bool HardwareChromeOS::SetMaxFirmwareKeyRollforward(
+ int firmware_max_rollforward) {
+ // Not all devices have this field yet. So first try to read
+ // it and if there is an error just fail.
+ if (GetMaxFirmwareKeyRollforward() == -1)
+ return false;
+
+ return VbSetSystemPropertyInt("firmware_max_rollforward",
+ firmware_max_rollforward) == 0;
+}
+
int HardwareChromeOS::GetMinFirmwareKeyVersion() const {
return VbGetSystemPropertyInt("tpm_fwver");
}
diff --git a/hardware_chromeos.h b/hardware_chromeos.h
index 6bdd37a..3aeeb0b 100644
--- a/hardware_chromeos.h
+++ b/hardware_chromeos.h
@@ -49,6 +49,8 @@
std::string GetECVersion() const override;
int GetMinKernelKeyVersion() const override;
int GetMinFirmwareKeyVersion() const override;
+ int GetMaxFirmwareKeyRollforward() const override;
+ bool SetMaxFirmwareKeyRollforward(int firmware_max_rollforward) override;
bool SetMaxKernelKeyRollforward(int kernel_max_rollforward) override;
int GetPowerwashCount() const override;
bool SchedulePowerwash() override;