update_engine: Add functions for reading/writing TPM values for rollback.
- Adds function to read the minimum allowed kernel key version
ie. crossystem tpm_kernver
- Adds function to set the maximum kernel key version roll forward
value. ie. crossystem max_kernel_rollforward
- Future CL will set max_kernel_rollforward to tpm_kerver as a temporary
measure to preserve the rollback window until server side changes
are made.
BUG=chromium:814090
TEST=FEATURES=test emerge-samus update_engine
Change-Id: I8d0c7db438cbc892745917ad56ea013e87361898
Reviewed-on: https://chromium-review.googlesource.com/927827
Commit-Ready: Zentaro Kavanagh <zentaro@chromium.org>
Tested-by: Zentaro Kavanagh <zentaro@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
Reviewed-by: Sen Jiang <senj@chromium.org>
diff --git a/common/fake_hardware.h b/common/fake_hardware.h
index 01d23d0..021d891 100644
--- a/common/fake_hardware.h
+++ b/common/fake_hardware.h
@@ -34,6 +34,15 @@
// false.
static const int kPowerwashCountNotSet = -1;
+ // Default value for crossystem tpm_kernver.
+ static const int kMinKernelKeyVersion = 3;
+
+ // 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
+ // roll forward prevention.
+ static const int kMaxKernelRollforward = 0xfffffffe;
+
FakeHardware() = default;
// HardwareInterface methods.
@@ -59,6 +68,15 @@
std::string GetECVersion() const override { return ec_version_; }
+ int GetMinKernelKeyVersion() const override {
+ return min_kernel_key_version_;
+ }
+
+ bool SetMaxKernelKeyRollforward(int max_kernel_rollforward) override {
+ max_kernel_rollforward_ = max_kernel_rollforward;
+ return true;
+ }
+
int GetPowerwashCount() const override { return powerwash_count_; }
bool SchedulePowerwash() override {
@@ -129,20 +147,30 @@
ec_version_ = ec_version;
}
+ void SetMinKernelKeyVersion(int min_kernel_key_version) {
+ min_kernel_key_version_ = min_kernel_key_version;
+ }
+
void SetPowerwashCount(int powerwash_count) {
powerwash_count_ = powerwash_count;
}
+ // Getters to verify state.
+ int GetMaxKernelKeyRollforward() const { return max_kernel_rollforward_; }
+
private:
bool is_official_build_{true};
bool is_normal_boot_mode_{true};
bool are_dev_features_enabled_{false};
bool is_oobe_enabled_{true};
bool is_oobe_complete_{true};
- base::Time oobe_timestamp_{base::Time::FromTimeT(1169280000)}; // Jan 20, 2007
+ // Jan 20, 2007
+ base::Time oobe_timestamp_{base::Time::FromTimeT(1169280000)};
std::string hardware_class_{"Fake HWID BLAH-1234"};
std::string firmware_version_{"Fake Firmware v1.0.1"};
std::string ec_version_{"Fake EC v1.0a"};
+ int min_kernel_key_version_{kMinKernelKeyVersion};
+ int max_kernel_rollforward_{kMaxKernelRollforward};
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 541a68a..9f3f618 100644
--- a/common/hardware_interface.h
+++ b/common/hardware_interface.h
@@ -68,6 +68,16 @@
// running a custom chrome os ec.
virtual std::string GetECVersion() const = 0;
+ // Returns the minimum kernel key version that verified boot on Chrome OS
+ // will allow to boot. This is the value of crossystem tpm_kernver. Returns
+ // -1 on error, or if not running on Chrome OS.
+ virtual int GetMinKernelKeyVersion() 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.
+ virtual bool SetMaxKernelKeyRollforward(int max_kernel_rollforward) = 0;
+
// Returns the powerwash_count from the stateful. If the file is not found
// or is invalid, returns -1. Brand new machines out of the factory or after
// recovery don't have this value set.
diff --git a/common/mock_hardware.h b/common/mock_hardware.h
index 42fa7ba..03ebfdb 100644
--- a/common/mock_hardware.h
+++ b/common/mock_hardware.h
@@ -54,6 +54,12 @@
ON_CALL(*this, GetECVersion())
.WillByDefault(testing::Invoke(&fake_,
&FakeHardware::GetECVersion));
+ ON_CALL(*this, GetMinKernelKeyVersion())
+ .WillByDefault(
+ testing::Invoke(&fake_, &FakeHardware::GetMinKernelKeyVersion));
+ ON_CALL(*this, SetMaxKernelKeyRollforward())
+ .WillByDefault(
+ testing::Invoke(&fake_, &FakeHardware::SetMaxKernelKeyRollforward));
ON_CALL(*this, GetPowerwashCount())
.WillByDefault(testing::Invoke(&fake_,
&FakeHardware::GetPowerwashCount));
@@ -81,6 +87,9 @@
MOCK_CONST_METHOD0(GetHardwareClass, std::string());
MOCK_CONST_METHOD0(GetFirmwareVersion, std::string());
MOCK_CONST_METHOD0(GetECVersion, std::string());
+ MOCK_CONST_METHOD0(GetMinKernelKeyVersion, int());
+ MOCK_CONST_METHOD1(SetMaxKernelKeyRollforward,
+ bool(int max_kernel_rollforward));
MOCK_CONST_METHOD0(GetPowerwashCount, int());
MOCK_CONST_METHOD1(GetNonVolatileDirectory, bool(base::FilePath*));
MOCK_CONST_METHOD1(GetPowerwashSafeDirectory, bool(base::FilePath*));
diff --git a/hardware_android.cc b/hardware_android.cc
index 58c68b6..7bd296b 100644
--- a/hardware_android.cc
+++ b/hardware_android.cc
@@ -165,6 +165,16 @@
return GetProperty(kPropBootBaseband, "");
}
+int HardwareAndroid::GetMinKernelKeyVersion() const {
+ LOG(WARNING) << "STUB: No Kernel 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;
+}
+
int HardwareAndroid::GetPowerwashCount() const {
LOG(WARNING) << "STUB: Assuming no factory reset was performed.";
return 0;
diff --git a/hardware_android.h b/hardware_android.h
index 37393ce..120ccab 100644
--- a/hardware_android.h
+++ b/hardware_android.h
@@ -42,6 +42,8 @@
std::string GetHardwareClass() const override;
std::string GetFirmwareVersion() const override;
std::string GetECVersion() const override;
+ int GetMinKernelKeyVersion() const override;
+ bool SetMaxKernelKeyRollforward(int max_kernel_rollforward) override;
int GetPowerwashCount() const override;
bool SchedulePowerwash() override;
bool CancelPowerwash() override;
diff --git a/hardware_chromeos.cc b/hardware_chromeos.cc
index 8c19aa7..d9c13a3 100644
--- a/hardware_chromeos.cc
+++ b/hardware_chromeos.cc
@@ -16,6 +16,8 @@
#include "update_engine/hardware_chromeos.h"
+#include <utility>
+
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
@@ -180,6 +182,15 @@
return utils::ParseECVersion(input_line);
}
+int HardwareChromeOS::GetMinKernelKeyVersion() const {
+ return VbGetSystemPropertyInt("tpm_kernver");
+}
+
+bool HardwareChromeOS::SetMaxKernelKeyRollforward(int max_kernel_rollforward) {
+ return VbSetSystemPropertyInt("max_kernel_rollforward",
+ max_kernel_rollforward) == 0;
+}
+
int HardwareChromeOS::GetPowerwashCount() const {
int powerwash_count;
base::FilePath marker_path = base::FilePath(kPowerwashSafeDirectory).Append(
diff --git a/hardware_chromeos.h b/hardware_chromeos.h
index 3a0bba2..2d43931 100644
--- a/hardware_chromeos.h
+++ b/hardware_chromeos.h
@@ -17,6 +17,7 @@
#ifndef UPDATE_ENGINE_HARDWARE_CHROMEOS_H_
#define UPDATE_ENGINE_HARDWARE_CHROMEOS_H_
+#include <memory>
#include <string>
#include <vector>
@@ -46,6 +47,8 @@
std::string GetHardwareClass() const override;
std::string GetFirmwareVersion() const override;
std::string GetECVersion() const override;
+ int GetMinKernelKeyVersion() const override;
+ bool SetMaxKernelKeyRollforward(int max_kernel_rollforward) override;
int GetPowerwashCount() const override;
bool SchedulePowerwash() override;
bool CancelPowerwash() override;