xref: /aosp_15_r20/external/cronet/crypto/unexportable_key_metrics_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "crypto/unexportable_key_metrics.h"
6 
7 #include <memory>
8 
9 #include "base/test/metrics/histogram_tester.h"
10 #include "crypto/signature_verifier.h"
11 #include "crypto/unexportable_key.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 
14 namespace crypto {
15 
16 namespace {
17 
18 // Mock that wraps the stateless software unexportable key provider while
19 // tracking key creation and removal. CHECKs if there are keys left that have
20 // not been removed when destroyed.
21 class MockTrackingUnexportableKeyProvider : public UnexportableKeyProvider {
22  public:
MockTrackingUnexportableKeyProvider()23   MockTrackingUnexportableKeyProvider()
24       : key_provider_(GetSoftwareUnsecureUnexportableKeyProvider()) {}
25 
~MockTrackingUnexportableKeyProvider()26   ~MockTrackingUnexportableKeyProvider() override {
27     CHECK(keys_.empty()) << keys_.size() << " key(s) not deleted.";
28   }
29 
30   // UnexportableKeyProvider:
SelectAlgorithm(base::span<const SignatureVerifier::SignatureAlgorithm> acceptable_algorithms)31   std::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
32       base::span<const SignatureVerifier::SignatureAlgorithm>
33           acceptable_algorithms) override {
34     return key_provider_->SelectAlgorithm(acceptable_algorithms);
35   }
GenerateSigningKeySlowly(base::span<const SignatureVerifier::SignatureAlgorithm> acceptable_algorithms)36   std::unique_ptr<UnexportableSigningKey> GenerateSigningKeySlowly(
37       base::span<const SignatureVerifier::SignatureAlgorithm>
38           acceptable_algorithms) override {
39     std::unique_ptr<UnexportableSigningKey> key =
40         key_provider_->GenerateSigningKeySlowly(acceptable_algorithms);
41     if (key) {
42       keys_.emplace(key->GetWrappedKey());
43     }
44     return key;
45   }
FromWrappedSigningKeySlowly(base::span<const uint8_t> wrapped_key)46   std::unique_ptr<UnexportableSigningKey> FromWrappedSigningKeySlowly(
47       base::span<const uint8_t> wrapped_key) override {
48     CHECK(keys_.contains(
49         std::vector<uint8_t>(wrapped_key.begin(), wrapped_key.end())))
50         << "Attempted to delete non existing key";
51     return key_provider_->FromWrappedSigningKeySlowly(wrapped_key);
52   }
DeleteSigningKey(base::span<const uint8_t> wrapped_key)53   bool DeleteSigningKey(base::span<const uint8_t> wrapped_key) override {
54     key_provider_->DeleteSigningKey(wrapped_key);
55     return keys_.erase(
56         std::vector<uint8_t>(wrapped_key.begin(), wrapped_key.end()));
57   }
58 
59  private:
60   std::unique_ptr<UnexportableKeyProvider> key_provider_;
61   std::set<std::vector<uint8_t>> keys_;
62 };
63 
GetUnexportableKeyProviderMock()64 std::unique_ptr<UnexportableKeyProvider> GetUnexportableKeyProviderMock() {
65   return std::make_unique<MockTrackingUnexportableKeyProvider>();
66 }
67 
68 class UnexportableKeyMetricTest : public testing::Test {
SetUp()69   void SetUp() override {
70     internal::SetUnexportableKeyProviderForTesting(
71         GetUnexportableKeyProviderMock);
72   }
73 
TearDown()74   void TearDown() override {
75     internal::SetUnexportableKeyProviderForTesting(nullptr);
76   }
77 };
78 
79 // Note mock provider only supports ECDSA.
TEST_F(UnexportableKeyMetricTest,GatherAllMetrics)80 TEST_F(UnexportableKeyMetricTest, GatherAllMetrics) {
81   base::HistogramTester histogram_tester;
82   histogram_tester.ExpectTotalCount("Crypto.TPMSupport2", 0);
83   histogram_tester.ExpectTotalCount("Crypto.TPMDuration.NewKeyCreationECDSA",
84                                     0);
85   histogram_tester.ExpectTotalCount(
86       "Crypto.TPMDuration.WrappedKeyCreationECDSA", 0);
87   histogram_tester.ExpectTotalCount("Crypto.TPMDuration.MessageSigningECDSA",
88                                     0);
89   histogram_tester.ExpectTotalCount("Crypto.TPMOperation.NewKeyCreation", 0);
90   histogram_tester.ExpectTotalCount("Crypto.TPMOperation.WrappedKeyCreation",
91                                     0);
92   histogram_tester.ExpectTotalCount("Crypto.TPMOperation.MessageSigning", 0);
93   histogram_tester.ExpectTotalCount("Crypto.TPMOperation.MessageVerify", 0);
94 
95   internal::MeasureTpmOperationsInternalForTesting();
96 
97   EXPECT_THAT(histogram_tester.GetAllSamples("Crypto.TPMSupport2"),
98               BucketsAre(base::Bucket(internal::TPMSupport::kECDSA, 1)));
99   histogram_tester.ExpectTotalCount("Crypto.TPMDuration.NewKeyCreationECDSA",
100                                     1);
101   histogram_tester.ExpectTotalCount(
102       "Crypto.TPMDuration.WrappedKeyCreationECDSA", 1);
103   histogram_tester.ExpectTotalCount("Crypto.TPMDuration.MessageSigningECDSA",
104                                     1);
105   EXPECT_THAT(
106       histogram_tester.GetAllSamples("Crypto.TPMOperation.NewKeyCreationECDSA"),
107       BucketsAre(base::Bucket(true, 1)));
108   EXPECT_THAT(histogram_tester.GetAllSamples(
109                   "Crypto.TPMOperation.WrappedKeyCreationECDSA"),
110               BucketsAre(base::Bucket(true, 1)));
111   EXPECT_THAT(
112       histogram_tester.GetAllSamples("Crypto.TPMOperation.MessageSigningECDSA"),
113       BucketsAre(base::Bucket(true, 1)));
114   EXPECT_THAT(
115       histogram_tester.GetAllSamples("Crypto.TPMOperation.MessageVerifyECDSA"),
116       BucketsAre(base::Bucket(true, 1)));
117 }
118 
119 }  // namespace
120 
121 }  // namespace crypto
122