cryptohome: tpm_manager: move TPM version fingerprint UMA
The UMA of TPM version fingerprint is "Platform.TPM.VersionFingerprint".
It doesn't make sense to report it in cryptohome.
BUG=b:164262829
TEST=FEATURES=test emerge-soraka tpm_manager cryptohome
TEST=check chrome://histograms report same value on soraka.
Change-Id: Iadaac457b3bf5c68209b4435ba7d2cf4f9249db6
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2331765
Tested-by: joe Chou <yich@google.com>
Commit-Queue: joe Chou <yich@google.com>
Reviewed-by: Leo Lai <cylai@google.com>
diff --git a/cryptohome/cryptohome_metrics.cc b/cryptohome/cryptohome_metrics.cc
index 324fec6..3647fa5 100644
--- a/cryptohome/cryptohome_metrics.cc
+++ b/cryptohome/cryptohome_metrics.cc
@@ -71,7 +71,6 @@
constexpr char kCryptohomeLESyncOutcomeHistogramSuffix[] = ".SyncOutcome";
constexpr char kHomedirEncryptionTypeHistogram[] =
"Cryptohome.HomedirEncryptionType";
-constexpr char kTPMVersionFingerprint[] = "Platform.TPM.VersionFingerprint";
constexpr char kDircryptoMigrationNoSpaceFailureFreeSpaceInMbHistogram[] =
"Cryptohome.DircryptoMigrationNoSpaceFailureFreeSpaceInMb";
constexpr char kDircryptoMigrationInitialFreeSpaceInMbHistogram[] =
@@ -435,14 +434,6 @@
g_metrics->SendEnumToUMA(hist_str, result, LE_CRED_ERROR_MAX);
}
-void ReportVersionFingerprint(int fingerprint) {
- if (!g_metrics) {
- return;
- }
-
- g_metrics->SendSparseToUMA(kTPMVersionFingerprint, fingerprint);
-}
-
void ReportDircryptoMigrationFailedNoSpace(int initial_migration_free_space_mb,
int failure_free_space_mb) {
if (!g_metrics) {
diff --git a/cryptohome/cryptohome_metrics.h b/cryptohome/cryptohome_metrics.h
index 0812728..df398b2 100644
--- a/cryptohome/cryptohome_metrics.h
+++ b/cryptohome/cryptohome_metrics.h
@@ -412,10 +412,6 @@
// to the "Cryptohome.LECredential.SyncOutcome" enum histogram.
void ReportLESyncOutcome(LECredError result);
-// Reports the TPM version fingerprint to the "Platform.TPM.VersionFingerprint"
-// histogram.
-void ReportVersionFingerprint(int fingerprint);
-
// Reports the free space in MB when the migration fails and what the free space
// was initially when the migration was started.
void ReportDircryptoMigrationFailedNoSpace(int initial_migration_free_space_mb,
diff --git a/cryptohome/tpm_init.cc b/cryptohome/tpm_init.cc
index 6df3d25..b1e3e96 100644
--- a/cryptohome/tpm_init.cc
+++ b/cryptohome/tpm_init.cc
@@ -173,15 +173,6 @@
RestoreTpmStateFromStorage();
}
- // Collect version statistics.
- if (!statistics_reported_) {
- Tpm::TpmVersionInfo version_info;
- if (get_tpm()->GetVersionInfo(&version_info)) {
- ReportVersionFingerprint(version_info.GetFingerprint());
- statistics_reported_ = true;
- }
- }
-
if (load_key) {
// load cryptohome key
LoadOrCreateCryptohomeKey(&cryptohome_key_);
diff --git a/cryptohome/tpm_init.h b/cryptohome/tpm_init.h
index 5dce8a0..f81fb7e 100644
--- a/cryptohome/tpm_init.h
+++ b/cryptohome/tpm_init.h
@@ -169,7 +169,6 @@
bool take_ownership_called_ = false;
bool took_ownership_ = false;
- bool statistics_reported_ = false;
int64_t initialization_time_ = 0;
Platform* platform_ = nullptr;
TpmPersistentState tpm_persistent_state_;
diff --git a/tpm_manager/server/mock_tpm_manager_metrics.h b/tpm_manager/server/mock_tpm_manager_metrics.h
index 09139f1..26e8bc7 100644
--- a/tpm_manager/server/mock_tpm_manager_metrics.h
+++ b/tpm_manager/server/mock_tpm_manager_metrics.h
@@ -20,6 +20,7 @@
(override));
MOCK_METHOD(void, ReportDictionaryAttackCounter, (int), (override));
+ MOCK_METHOD(void, ReportVersionFingerprint, (int), (override));
};
} // namespace tpm_manager
diff --git a/tpm_manager/server/tpm_manager_metrics.cc b/tpm_manager/server/tpm_manager_metrics.cc
index 37f3e2f..cac2d7e 100644
--- a/tpm_manager/server/tpm_manager_metrics.cc
+++ b/tpm_manager/server/tpm_manager_metrics.cc
@@ -24,4 +24,8 @@
kDictionaryAttackCounterNumBuckets);
}
+void TpmManagerMetrics::ReportVersionFingerprint(int fingerprint) {
+ metrics_library_->SendSparseToUMA(kTPMVersionFingerprint, fingerprint);
+}
+
} // namespace tpm_manager
diff --git a/tpm_manager/server/tpm_manager_metrics.h b/tpm_manager/server/tpm_manager_metrics.h
index d59ab45..9379211 100644
--- a/tpm_manager/server/tpm_manager_metrics.h
+++ b/tpm_manager/server/tpm_manager_metrics.h
@@ -23,6 +23,10 @@
virtual void ReportDictionaryAttackCounter(int counter);
+ // Reports the TPM version fingerprint to the
+ // "Platform.TPM.VersionFingerprint" histogram.
+ virtual void ReportVersionFingerprint(int fingerprint);
+
void set_metrics_library_for_testing(
MetricsLibraryInterface* metrics_library) {
metrics_library_ = metrics_library;
diff --git a/tpm_manager/server/tpm_manager_metrics_names.h b/tpm_manager/server/tpm_manager_metrics_names.h
index 55c4272..3ec03d3 100644
--- a/tpm_manager/server/tpm_manager_metrics_names.h
+++ b/tpm_manager/server/tpm_manager_metrics_names.h
@@ -11,6 +11,7 @@
"Platform.TPM.DictionaryAttackResetStatus";
constexpr char kDictionaryAttackCounterHistogram[] =
"Platform.TPM.DictionaryAttackCounter";
+constexpr char kTPMVersionFingerprint[] = "Platform.TPM.VersionFingerprint";
} // namespace tpm_manager
diff --git a/tpm_manager/server/tpm_manager_service.cc b/tpm_manager/server/tpm_manager_service.cc
index 194e18d..a4d2428 100644
--- a/tpm_manager/server/tpm_manager_service.cc
+++ b/tpm_manager/server/tpm_manager_service.cc
@@ -6,13 +6,17 @@
#include <memory>
#include <string>
+#include <utility>
#include <vector>
#include <base/bind.h>
#include <base/callback.h>
#include <base/command_line.h>
#include <base/message_loop/message_pump_type.h>
+#include <base/strings/stringprintf.h>
#include <base/synchronization/lock.h>
+#include <crypto/sha2.h>
+#include <inttypes.h>
namespace {
@@ -39,6 +43,29 @@
return false;
}
+int GetFingerprint(uint32_t family,
+ uint64_t spec_level,
+ uint32_t manufacturer,
+ uint32_t tpm_model,
+ uint64_t firmware_version,
+ std::string vendor_specific) {
+ // The exact encoding doesn't matter as long as its unambiguous, stable and
+ // contains all information present in the version fields.
+ std::string encoded_parameters =
+ base::StringPrintf("%08" PRIx32 "%016" PRIx64 "%08" PRIx32 "%08" PRIx32
+ "%016" PRIx64 "%016zx",
+ family, spec_level, manufacturer, tpm_model,
+ firmware_version, vendor_specific.size());
+ encoded_parameters.append(vendor_specific);
+ std::string hash = crypto::SHA256HashString(encoded_parameters);
+
+ // Return the first 31 bits from |hash|.
+ int result =
+ static_cast<uint8_t>(hash[0]) | static_cast<uint8_t>(hash[1]) << 8 |
+ static_cast<uint8_t>(hash[2]) << 16 | static_cast<uint8_t>(hash[3]) << 24;
+ return result & 0x7fffffff;
+}
+
} // namespace
namespace tpm_manager {
@@ -85,10 +112,31 @@
base::Closure task =
base::Bind(&TpmManagerService::InitializeTask, base::Unretained(this));
worker_thread_->task_runner()->PostNonNestableTask(FROM_HERE, task);
+ ReportVersionFingerprint();
VLOG(1) << "Worker thread started.";
return true;
}
+void TpmManagerService::ReportVersionFingerprint() {
+ auto callback = base::Bind(
+ [](tpm_manager::TpmManagerMetrics* tpm_manager_metrics,
+ const tpm_manager::GetVersionInfoReply& reply) {
+ if (reply.status() == STATUS_SUCCESS) {
+ uint32_t family = reply.family();
+ uint64_t spec_level = reply.spec_level();
+ uint32_t manufacturer = reply.manufacturer();
+ uint32_t tpm_model = reply.tpm_model();
+ uint64_t firmware_version = reply.firmware_version();
+ std::string vendor_specific = reply.vendor_specific();
+ tpm_manager_metrics->ReportVersionFingerprint(
+ GetFingerprint(family, spec_level, manufacturer, tpm_model,
+ firmware_version, vendor_specific));
+ }
+ },
+ base::Unretained(tpm_manager_metrics_));
+ GetVersionInfo(tpm_manager::GetVersionInfoRequest(), callback);
+}
+
void TpmManagerService::InitializeTask() {
VLOG(1) << "Initializing service...";
diff --git a/tpm_manager/server/tpm_manager_service.h b/tpm_manager/server/tpm_manager_service.h
index ceaf38a..dd13a8f 100644
--- a/tpm_manager/server/tpm_manager_service.h
+++ b/tpm_manager/server/tpm_manager_service.h
@@ -91,6 +91,8 @@
// any other method in this class. Returns true on success.
bool Initialize();
+ void ReportVersionFingerprint();
+
// TpmOwnershipInterface methods.
void GetTpmStatus(const GetTpmStatusRequest& request,
const GetTpmStatusCallback& callback) override;
diff --git a/tpm_manager/server/tpm_manager_service_test.cc b/tpm_manager/server/tpm_manager_service_test.cc
index 462b9da..d49f604 100644
--- a/tpm_manager/server/tpm_manager_service_test.cc
+++ b/tpm_manager/server/tpm_manager_service_test.cc
@@ -23,6 +23,7 @@
using testing::_;
using testing::AtLeast;
+using testing::AtMost;
using testing::Ge;
using testing::Invoke;
using testing::Le;
@@ -55,6 +56,8 @@
public:
~TpmManagerServiceTestBase() override = default;
void SetUp() override {
+ EXPECT_CALL(mock_tpm_manager_metrics_, ReportVersionFingerprint(_))
+ .Times(AtMost(1));
service_.reset(new TpmManagerService(
wait_for_ownership, perform_preinit, &mock_local_data_store_,
&mock_tpm_status_, &mock_tpm_initializer_, &mock_tpm_nvram_,
@@ -365,7 +368,7 @@
Run();
}
-TEST_F(TpmManagerServiceTest, GetVersionInfoSuccess) {
+TEST_F(TpmManagerServiceTest_Preinit, GetVersionInfoSuccess) {
EXPECT_CALL(mock_tpm_status_, GetVersionInfo(_, _, _, _, _, _))
.WillOnce(Invoke([](uint32_t* family, uint64_t* spec_level,
uint32_t* manufacturer, uint32_t* tpm_model,
@@ -380,6 +383,8 @@
return true;
}));
+ SetupService();
+
auto callback = [](TpmManagerServiceTestBase* self, int* call_count,
base::Lock* call_count_lock,
const GetVersionInfoReply& reply) {
@@ -413,10 +418,13 @@
Run();
}
-TEST_F(TpmManagerServiceTest, GetVersionInfoError) {
+TEST_F(TpmManagerServiceTest_Preinit, GetVersionInfoError) {
EXPECT_CALL(mock_tpm_status_, GetVersionInfo(_, _, _, _, _, _))
+ .WillOnce(Return(false))
.WillOnce(Return(false));
+ SetupService();
+
auto callback = [](TpmManagerServiceTestBase* self,
const GetVersionInfoReply& reply) {
EXPECT_EQ(STATUS_DEVICE_ERROR, reply.status());