xref: /aosp_15_r20/external/cronet/crypto/unexportable_key_metrics.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2022 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "crypto/unexportable_key_metrics.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <memory>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include "base/feature_list.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_functions.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/task/task_traits.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/task/thread_pool.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/timer/elapsed_timer.h"
14*6777b538SAndroid Build Coastguard Worker #include "crypto/unexportable_key.h"
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker namespace crypto {
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker namespace {
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker enum class TPMOperation {
21*6777b538SAndroid Build Coastguard Worker   kMessageSigning,
22*6777b538SAndroid Build Coastguard Worker   kMessageVerify,
23*6777b538SAndroid Build Coastguard Worker   kWrappedKeyCreation,
24*6777b538SAndroid Build Coastguard Worker   kNewKeyCreation,
25*6777b538SAndroid Build Coastguard Worker };
26*6777b538SAndroid Build Coastguard Worker 
27*6777b538SAndroid Build Coastguard Worker enum class KeyType {
28*6777b538SAndroid Build Coastguard Worker   kHardwareKey,
29*6777b538SAndroid Build Coastguard Worker   kVirtualizedKey,
30*6777b538SAndroid Build Coastguard Worker };
31*6777b538SAndroid Build Coastguard Worker 
32*6777b538SAndroid Build Coastguard Worker const SignatureVerifier::SignatureAlgorithm kAllAlgorithms[] = {
33*6777b538SAndroid Build Coastguard Worker     SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256,
34*6777b538SAndroid Build Coastguard Worker     SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256,
35*6777b538SAndroid Build Coastguard Worker };
36*6777b538SAndroid Build Coastguard Worker 
37*6777b538SAndroid Build Coastguard Worker constexpr char kTestKeyName[] = "ChromeMetricsTestKey";
38*6777b538SAndroid Build Coastguard Worker 
39*6777b538SAndroid Build Coastguard Worker // Leaving HW empty will keep the existing metric as is today.
GetHistogramPrefixForKeyType(KeyType type)40*6777b538SAndroid Build Coastguard Worker std::string GetHistogramPrefixForKeyType(KeyType type) {
41*6777b538SAndroid Build Coastguard Worker   switch (type) {
42*6777b538SAndroid Build Coastguard Worker     case KeyType::kHardwareKey:
43*6777b538SAndroid Build Coastguard Worker       return "";
44*6777b538SAndroid Build Coastguard Worker     case KeyType::kVirtualizedKey:
45*6777b538SAndroid Build Coastguard Worker       return "Virtual.";
46*6777b538SAndroid Build Coastguard Worker   }
47*6777b538SAndroid Build Coastguard Worker }
48*6777b538SAndroid Build Coastguard Worker 
GetHistogramSuffixForOperation(TPMOperation operation)49*6777b538SAndroid Build Coastguard Worker std::string GetHistogramSuffixForOperation(TPMOperation operation) {
50*6777b538SAndroid Build Coastguard Worker   switch (operation) {
51*6777b538SAndroid Build Coastguard Worker     case TPMOperation::kMessageSigning:
52*6777b538SAndroid Build Coastguard Worker       return "MessageSigning";
53*6777b538SAndroid Build Coastguard Worker     case TPMOperation::kMessageVerify:
54*6777b538SAndroid Build Coastguard Worker       return "MessageVerify";
55*6777b538SAndroid Build Coastguard Worker     case TPMOperation::kNewKeyCreation:
56*6777b538SAndroid Build Coastguard Worker       return "NewKeyCreation";
57*6777b538SAndroid Build Coastguard Worker     case TPMOperation::kWrappedKeyCreation:
58*6777b538SAndroid Build Coastguard Worker       return "WrappedKeyCreation";
59*6777b538SAndroid Build Coastguard Worker   }
60*6777b538SAndroid Build Coastguard Worker   return "";
61*6777b538SAndroid Build Coastguard Worker }
62*6777b538SAndroid Build Coastguard Worker 
GetHistogramSuffixForAlgo(internal::TPMSupport algo)63*6777b538SAndroid Build Coastguard Worker std::string GetHistogramSuffixForAlgo(internal::TPMSupport algo) {
64*6777b538SAndroid Build Coastguard Worker   switch (algo) {
65*6777b538SAndroid Build Coastguard Worker     case internal::TPMSupport::kECDSA:
66*6777b538SAndroid Build Coastguard Worker       return "ECDSA";
67*6777b538SAndroid Build Coastguard Worker     case internal::TPMSupport::kRSA:
68*6777b538SAndroid Build Coastguard Worker       return "RSA";
69*6777b538SAndroid Build Coastguard Worker     case internal::TPMSupport::kNone:
70*6777b538SAndroid Build Coastguard Worker       return "";
71*6777b538SAndroid Build Coastguard Worker   }
72*6777b538SAndroid Build Coastguard Worker   return "";
73*6777b538SAndroid Build Coastguard Worker }
74*6777b538SAndroid Build Coastguard Worker 
GetSupportedTpm(internal::TPMSupport hw,internal::TPMSupport virt)75*6777b538SAndroid Build Coastguard Worker internal::TPMType GetSupportedTpm(internal::TPMSupport hw,
76*6777b538SAndroid Build Coastguard Worker                                   internal::TPMSupport virt) {
77*6777b538SAndroid Build Coastguard Worker   if (hw != internal::TPMSupport::kNone &&
78*6777b538SAndroid Build Coastguard Worker       virt != internal::TPMSupport::kNone) {
79*6777b538SAndroid Build Coastguard Worker     return internal::TPMType::kBoth;
80*6777b538SAndroid Build Coastguard Worker   }
81*6777b538SAndroid Build Coastguard Worker 
82*6777b538SAndroid Build Coastguard Worker   if (hw != internal::TPMSupport::kNone) {
83*6777b538SAndroid Build Coastguard Worker     return internal::TPMType::kHW;
84*6777b538SAndroid Build Coastguard Worker   }
85*6777b538SAndroid Build Coastguard Worker 
86*6777b538SAndroid Build Coastguard Worker   // This is not expected
87*6777b538SAndroid Build Coastguard Worker   if (virt != internal::TPMSupport::kNone) {
88*6777b538SAndroid Build Coastguard Worker     return internal::TPMType::kVirtual;
89*6777b538SAndroid Build Coastguard Worker   }
90*6777b538SAndroid Build Coastguard Worker 
91*6777b538SAndroid Build Coastguard Worker   return internal::TPMType::kNone;
92*6777b538SAndroid Build Coastguard Worker }
93*6777b538SAndroid Build Coastguard Worker 
ReportUmaLatency(TPMOperation operation,internal::TPMSupport algo,base::TimeDelta latency,KeyType type=KeyType::kHardwareKey)94*6777b538SAndroid Build Coastguard Worker void ReportUmaLatency(TPMOperation operation,
95*6777b538SAndroid Build Coastguard Worker                       internal::TPMSupport algo,
96*6777b538SAndroid Build Coastguard Worker                       base::TimeDelta latency,
97*6777b538SAndroid Build Coastguard Worker                       KeyType type = KeyType::kHardwareKey) {
98*6777b538SAndroid Build Coastguard Worker   std::string histogram_name = "Crypto.TPMDuration." +
99*6777b538SAndroid Build Coastguard Worker                                GetHistogramPrefixForKeyType(type) +
100*6777b538SAndroid Build Coastguard Worker                                GetHistogramSuffixForOperation(operation) +
101*6777b538SAndroid Build Coastguard Worker                                GetHistogramSuffixForAlgo(algo);
102*6777b538SAndroid Build Coastguard Worker   base::UmaHistogramMediumTimes(histogram_name, latency);
103*6777b538SAndroid Build Coastguard Worker }
104*6777b538SAndroid Build Coastguard Worker 
ReportUmaOperationSuccess(TPMOperation operation,internal::TPMSupport algo,bool status,KeyType type=KeyType::kHardwareKey)105*6777b538SAndroid Build Coastguard Worker void ReportUmaOperationSuccess(TPMOperation operation,
106*6777b538SAndroid Build Coastguard Worker                                internal::TPMSupport algo,
107*6777b538SAndroid Build Coastguard Worker                                bool status,
108*6777b538SAndroid Build Coastguard Worker                                KeyType type = KeyType::kHardwareKey) {
109*6777b538SAndroid Build Coastguard Worker   std::string histogram_name = "Crypto.TPMOperation." +
110*6777b538SAndroid Build Coastguard Worker                                GetHistogramPrefixForKeyType(type) +
111*6777b538SAndroid Build Coastguard Worker                                GetHistogramSuffixForOperation(operation) +
112*6777b538SAndroid Build Coastguard Worker                                GetHistogramSuffixForAlgo(algo);
113*6777b538SAndroid Build Coastguard Worker   base::UmaHistogramBoolean(histogram_name, status);
114*6777b538SAndroid Build Coastguard Worker }
115*6777b538SAndroid Build Coastguard Worker 
ReportUmaTpmOperation(TPMOperation operation,internal::TPMSupport algo,base::TimeDelta latency,bool status,KeyType type=KeyType::kHardwareKey)116*6777b538SAndroid Build Coastguard Worker void ReportUmaTpmOperation(TPMOperation operation,
117*6777b538SAndroid Build Coastguard Worker                            internal::TPMSupport algo,
118*6777b538SAndroid Build Coastguard Worker                            base::TimeDelta latency,
119*6777b538SAndroid Build Coastguard Worker                            bool status,
120*6777b538SAndroid Build Coastguard Worker                            KeyType type = KeyType::kHardwareKey) {
121*6777b538SAndroid Build Coastguard Worker   ReportUmaOperationSuccess(operation, algo, status, type);
122*6777b538SAndroid Build Coastguard Worker   if (status && operation != TPMOperation::kMessageVerify) {
123*6777b538SAndroid Build Coastguard Worker     // Only report latency for successful operations
124*6777b538SAndroid Build Coastguard Worker     // No latency reported for verification that is done outside of TPM
125*6777b538SAndroid Build Coastguard Worker     ReportUmaLatency(operation, algo, latency, type);
126*6777b538SAndroid Build Coastguard Worker   }
127*6777b538SAndroid Build Coastguard Worker }
128*6777b538SAndroid Build Coastguard Worker 
MeasureVirtualTpmOperations()129*6777b538SAndroid Build Coastguard Worker internal::TPMSupport MeasureVirtualTpmOperations() {
130*6777b538SAndroid Build Coastguard Worker   internal::TPMSupport supported_virtual_algo = internal::TPMSupport::kNone;
131*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<VirtualUnexportableKeyProvider> virtual_provider =
132*6777b538SAndroid Build Coastguard Worker       GetVirtualUnexportableKeyProvider_DO_NOT_USE_METRICS_ONLY();
133*6777b538SAndroid Build Coastguard Worker 
134*6777b538SAndroid Build Coastguard Worker   if (!virtual_provider) {
135*6777b538SAndroid Build Coastguard Worker     return supported_virtual_algo;
136*6777b538SAndroid Build Coastguard Worker   }
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker   auto algo = virtual_provider->SelectAlgorithm(kAllAlgorithms);
139*6777b538SAndroid Build Coastguard Worker   if (algo) {
140*6777b538SAndroid Build Coastguard Worker     switch (*algo) {
141*6777b538SAndroid Build Coastguard Worker       case SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256:
142*6777b538SAndroid Build Coastguard Worker         supported_virtual_algo = internal::TPMSupport::kECDSA;
143*6777b538SAndroid Build Coastguard Worker         break;
144*6777b538SAndroid Build Coastguard Worker       case SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256:
145*6777b538SAndroid Build Coastguard Worker         supported_virtual_algo = internal::TPMSupport::kRSA;
146*6777b538SAndroid Build Coastguard Worker         break;
147*6777b538SAndroid Build Coastguard Worker       case SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA1:
148*6777b538SAndroid Build Coastguard Worker       case SignatureVerifier::SignatureAlgorithm::RSA_PSS_SHA256:
149*6777b538SAndroid Build Coastguard Worker         // Not supported for this metric.
150*6777b538SAndroid Build Coastguard Worker         break;
151*6777b538SAndroid Build Coastguard Worker     }
152*6777b538SAndroid Build Coastguard Worker   }
153*6777b538SAndroid Build Coastguard Worker 
154*6777b538SAndroid Build Coastguard Worker   // Report if virtual TPM is supported and best algo
155*6777b538SAndroid Build Coastguard Worker   base::UmaHistogramEnumeration("Crypto.VirtualKeySupport",
156*6777b538SAndroid Build Coastguard Worker                                 supported_virtual_algo);
157*6777b538SAndroid Build Coastguard Worker 
158*6777b538SAndroid Build Coastguard Worker   base::ElapsedTimer key_creation_timer;
159*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<VirtualUnexportableSigningKey> current_key =
160*6777b538SAndroid Build Coastguard Worker       virtual_provider->GenerateSigningKey(kAllAlgorithms, kTestKeyName);
161*6777b538SAndroid Build Coastguard Worker   ReportUmaTpmOperation(TPMOperation::kNewKeyCreation, supported_virtual_algo,
162*6777b538SAndroid Build Coastguard Worker                         key_creation_timer.Elapsed(), current_key != nullptr,
163*6777b538SAndroid Build Coastguard Worker                         KeyType::kVirtualizedKey);
164*6777b538SAndroid Build Coastguard Worker   if (!current_key) {
165*6777b538SAndroid Build Coastguard Worker     // Report no support if keys cannot be created, Windows appears to always
166*6777b538SAndroid Build Coastguard Worker     // mark the keys as available in SelectAlgorithm.
167*6777b538SAndroid Build Coastguard Worker     return internal::TPMSupport::kNone;
168*6777b538SAndroid Build Coastguard Worker   }
169*6777b538SAndroid Build Coastguard Worker 
170*6777b538SAndroid Build Coastguard Worker   base::ElapsedTimer open_key_timer;
171*6777b538SAndroid Build Coastguard Worker   std::string key_name = current_key->GetKeyName();
172*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<VirtualUnexportableSigningKey> opened_key =
173*6777b538SAndroid Build Coastguard Worker       virtual_provider->FromKeyName(key_name);
174*6777b538SAndroid Build Coastguard Worker   // Re-using TPMOperation::kWrappedKeyCreation for restoring keys even though
175*6777b538SAndroid Build Coastguard Worker   // there are no wrapped keys involved.
176*6777b538SAndroid Build Coastguard Worker   ReportUmaTpmOperation(TPMOperation::kWrappedKeyCreation,
177*6777b538SAndroid Build Coastguard Worker                         supported_virtual_algo, open_key_timer.Elapsed(),
178*6777b538SAndroid Build Coastguard Worker                         opened_key != nullptr, KeyType::kVirtualizedKey);
179*6777b538SAndroid Build Coastguard Worker 
180*6777b538SAndroid Build Coastguard Worker   const uint8_t msg[] = {1, 2, 3, 4};
181*6777b538SAndroid Build Coastguard Worker   base::ElapsedTimer message_signing_timer;
182*6777b538SAndroid Build Coastguard Worker   std::optional<std::vector<uint8_t>> signed_bytes = current_key->Sign(msg);
183*6777b538SAndroid Build Coastguard Worker   ReportUmaTpmOperation(TPMOperation::kMessageSigning, supported_virtual_algo,
184*6777b538SAndroid Build Coastguard Worker                         message_signing_timer.Elapsed(),
185*6777b538SAndroid Build Coastguard Worker                         signed_bytes.has_value(), KeyType::kVirtualizedKey);
186*6777b538SAndroid Build Coastguard Worker 
187*6777b538SAndroid Build Coastguard Worker   if (signed_bytes.has_value()) {
188*6777b538SAndroid Build Coastguard Worker     crypto::SignatureVerifier verifier;
189*6777b538SAndroid Build Coastguard Worker     bool verify_init =
190*6777b538SAndroid Build Coastguard Worker         verifier.VerifyInit(current_key->Algorithm(), signed_bytes.value(),
191*6777b538SAndroid Build Coastguard Worker                             current_key->GetSubjectPublicKeyInfo());
192*6777b538SAndroid Build Coastguard Worker     if (verify_init) {
193*6777b538SAndroid Build Coastguard Worker       verifier.VerifyUpdate(msg);
194*6777b538SAndroid Build Coastguard Worker       bool verify_final = verifier.VerifyFinal();
195*6777b538SAndroid Build Coastguard Worker       ReportUmaOperationSuccess(TPMOperation::kMessageVerify,
196*6777b538SAndroid Build Coastguard Worker                                 supported_virtual_algo, verify_final,
197*6777b538SAndroid Build Coastguard Worker                                 KeyType::kVirtualizedKey);
198*6777b538SAndroid Build Coastguard Worker     } else {
199*6777b538SAndroid Build Coastguard Worker       ReportUmaOperationSuccess(TPMOperation::kMessageVerify,
200*6777b538SAndroid Build Coastguard Worker                                 supported_virtual_algo, verify_init,
201*6777b538SAndroid Build Coastguard Worker                                 KeyType::kVirtualizedKey);
202*6777b538SAndroid Build Coastguard Worker     }
203*6777b538SAndroid Build Coastguard Worker   }
204*6777b538SAndroid Build Coastguard Worker 
205*6777b538SAndroid Build Coastguard Worker   current_key.get()->DeleteKey();
206*6777b538SAndroid Build Coastguard Worker   return supported_virtual_algo;
207*6777b538SAndroid Build Coastguard Worker }
208*6777b538SAndroid Build Coastguard Worker 
MeasureTpmOperationsInternal(UnexportableKeyProvider::Config config)209*6777b538SAndroid Build Coastguard Worker void MeasureTpmOperationsInternal(UnexportableKeyProvider::Config config) {
210*6777b538SAndroid Build Coastguard Worker   internal::TPMSupport supported_algo = internal::TPMSupport::kNone;
211*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<UnexportableKeyProvider> provider =
212*6777b538SAndroid Build Coastguard Worker       GetUnexportableKeyProvider(std::move(config));
213*6777b538SAndroid Build Coastguard Worker   if (!provider) {
214*6777b538SAndroid Build Coastguard Worker     return;
215*6777b538SAndroid Build Coastguard Worker   }
216*6777b538SAndroid Build Coastguard Worker 
217*6777b538SAndroid Build Coastguard Worker   auto algo = provider->SelectAlgorithm(kAllAlgorithms);
218*6777b538SAndroid Build Coastguard Worker   if (algo) {
219*6777b538SAndroid Build Coastguard Worker     switch (*algo) {
220*6777b538SAndroid Build Coastguard Worker       case SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256:
221*6777b538SAndroid Build Coastguard Worker         supported_algo = internal::TPMSupport::kECDSA;
222*6777b538SAndroid Build Coastguard Worker         break;
223*6777b538SAndroid Build Coastguard Worker       case SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256:
224*6777b538SAndroid Build Coastguard Worker         supported_algo = internal::TPMSupport::kRSA;
225*6777b538SAndroid Build Coastguard Worker         break;
226*6777b538SAndroid Build Coastguard Worker       case SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA1:
227*6777b538SAndroid Build Coastguard Worker       case SignatureVerifier::SignatureAlgorithm::RSA_PSS_SHA256:
228*6777b538SAndroid Build Coastguard Worker         // Not supported for this metric.
229*6777b538SAndroid Build Coastguard Worker         break;
230*6777b538SAndroid Build Coastguard Worker     }
231*6777b538SAndroid Build Coastguard Worker   }
232*6777b538SAndroid Build Coastguard Worker 
233*6777b538SAndroid Build Coastguard Worker   internal::TPMSupport supported_virtual_algo = MeasureVirtualTpmOperations();
234*6777b538SAndroid Build Coastguard Worker   base::UmaHistogramEnumeration(
235*6777b538SAndroid Build Coastguard Worker       "Crypto.TPMSupportType",
236*6777b538SAndroid Build Coastguard Worker       GetSupportedTpm(supported_algo, supported_virtual_algo));
237*6777b538SAndroid Build Coastguard Worker 
238*6777b538SAndroid Build Coastguard Worker   // Report if TPM is supported and best algo
239*6777b538SAndroid Build Coastguard Worker   base::UmaHistogramEnumeration("Crypto.TPMSupport2", supported_algo);
240*6777b538SAndroid Build Coastguard Worker   if (supported_algo == internal::TPMSupport::kNone) {
241*6777b538SAndroid Build Coastguard Worker     return;
242*6777b538SAndroid Build Coastguard Worker   }
243*6777b538SAndroid Build Coastguard Worker 
244*6777b538SAndroid Build Coastguard Worker   auto delete_key = [&provider](UnexportableSigningKey* key) {
245*6777b538SAndroid Build Coastguard Worker     provider->DeleteSigningKey(key->GetWrappedKey());
246*6777b538SAndroid Build Coastguard Worker     delete key;
247*6777b538SAndroid Build Coastguard Worker   };
248*6777b538SAndroid Build Coastguard Worker   base::ElapsedTimer key_creation_timer;
249*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<UnexportableSigningKey, decltype(delete_key)> current_key(
250*6777b538SAndroid Build Coastguard Worker       provider->GenerateSigningKeySlowly(kAllAlgorithms).release(), delete_key);
251*6777b538SAndroid Build Coastguard Worker   ReportUmaTpmOperation(TPMOperation::kNewKeyCreation, supported_algo,
252*6777b538SAndroid Build Coastguard Worker                         key_creation_timer.Elapsed(), current_key != nullptr);
253*6777b538SAndroid Build Coastguard Worker   if (!current_key) {
254*6777b538SAndroid Build Coastguard Worker     return;
255*6777b538SAndroid Build Coastguard Worker   }
256*6777b538SAndroid Build Coastguard Worker 
257*6777b538SAndroid Build Coastguard Worker   base::ElapsedTimer wrapped_key_creation_timer;
258*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<UnexportableSigningKey, decltype(delete_key)> wrapped_key(
259*6777b538SAndroid Build Coastguard Worker       provider->FromWrappedSigningKeySlowly(current_key->GetWrappedKey())
260*6777b538SAndroid Build Coastguard Worker           .release(),
261*6777b538SAndroid Build Coastguard Worker       delete_key);
262*6777b538SAndroid Build Coastguard Worker   ReportUmaTpmOperation(TPMOperation::kWrappedKeyCreation, supported_algo,
263*6777b538SAndroid Build Coastguard Worker                         wrapped_key_creation_timer.Elapsed(),
264*6777b538SAndroid Build Coastguard Worker                         wrapped_key != nullptr);
265*6777b538SAndroid Build Coastguard Worker 
266*6777b538SAndroid Build Coastguard Worker   const uint8_t msg[] = {1, 2, 3, 4};
267*6777b538SAndroid Build Coastguard Worker   base::ElapsedTimer message_signing_timer;
268*6777b538SAndroid Build Coastguard Worker   std::optional<std::vector<uint8_t>> signed_bytes =
269*6777b538SAndroid Build Coastguard Worker       current_key->SignSlowly(msg);
270*6777b538SAndroid Build Coastguard Worker   ReportUmaTpmOperation(TPMOperation::kMessageSigning, supported_algo,
271*6777b538SAndroid Build Coastguard Worker                         message_signing_timer.Elapsed(),
272*6777b538SAndroid Build Coastguard Worker                         signed_bytes.has_value());
273*6777b538SAndroid Build Coastguard Worker   if (!signed_bytes.has_value()) {
274*6777b538SAndroid Build Coastguard Worker     return;
275*6777b538SAndroid Build Coastguard Worker   }
276*6777b538SAndroid Build Coastguard Worker 
277*6777b538SAndroid Build Coastguard Worker   crypto::SignatureVerifier verifier;
278*6777b538SAndroid Build Coastguard Worker   bool verify_init =
279*6777b538SAndroid Build Coastguard Worker       verifier.VerifyInit(current_key->Algorithm(), signed_bytes.value(),
280*6777b538SAndroid Build Coastguard Worker                           current_key->GetSubjectPublicKeyInfo());
281*6777b538SAndroid Build Coastguard Worker   if (verify_init) {
282*6777b538SAndroid Build Coastguard Worker     verifier.VerifyUpdate(msg);
283*6777b538SAndroid Build Coastguard Worker     bool verify_final = verifier.VerifyFinal();
284*6777b538SAndroid Build Coastguard Worker     ReportUmaOperationSuccess(TPMOperation::kMessageVerify, supported_algo,
285*6777b538SAndroid Build Coastguard Worker                               verify_final);
286*6777b538SAndroid Build Coastguard Worker   } else {
287*6777b538SAndroid Build Coastguard Worker     ReportUmaOperationSuccess(TPMOperation::kMessageVerify, supported_algo,
288*6777b538SAndroid Build Coastguard Worker                               verify_init);
289*6777b538SAndroid Build Coastguard Worker   }
290*6777b538SAndroid Build Coastguard Worker }
291*6777b538SAndroid Build Coastguard Worker 
292*6777b538SAndroid Build Coastguard Worker }  // namespace
293*6777b538SAndroid Build Coastguard Worker 
294*6777b538SAndroid Build Coastguard Worker namespace internal {
295*6777b538SAndroid Build Coastguard Worker 
MeasureTpmOperationsInternalForTesting()296*6777b538SAndroid Build Coastguard Worker void MeasureTpmOperationsInternalForTesting() {
297*6777b538SAndroid Build Coastguard Worker   MeasureTpmOperationsInternal(/*config=*/{});
298*6777b538SAndroid Build Coastguard Worker }
299*6777b538SAndroid Build Coastguard Worker 
300*6777b538SAndroid Build Coastguard Worker }  // namespace internal
301*6777b538SAndroid Build Coastguard Worker 
MaybeMeasureTpmOperations(UnexportableKeyProvider::Config config)302*6777b538SAndroid Build Coastguard Worker void MaybeMeasureTpmOperations(UnexportableKeyProvider::Config config) {
303*6777b538SAndroid Build Coastguard Worker   static BASE_FEATURE(kTpmLatencyMetrics, "TpmLatencyMetrics",
304*6777b538SAndroid Build Coastguard Worker                       base::FEATURE_ENABLED_BY_DEFAULT);
305*6777b538SAndroid Build Coastguard Worker   if (base::FeatureList::IsEnabled(kTpmLatencyMetrics)) {
306*6777b538SAndroid Build Coastguard Worker     base::ThreadPool::PostTask(
307*6777b538SAndroid Build Coastguard Worker         FROM_HERE,
308*6777b538SAndroid Build Coastguard Worker         {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
309*6777b538SAndroid Build Coastguard Worker          base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
310*6777b538SAndroid Build Coastguard Worker         base::BindOnce(&MeasureTpmOperationsInternal, std::move(config)));
311*6777b538SAndroid Build Coastguard Worker   }
312*6777b538SAndroid Build Coastguard Worker }
313*6777b538SAndroid Build Coastguard Worker 
314*6777b538SAndroid Build Coastguard Worker }  // namespace crypto
315