trunks_client_test.cc revision 56b27e3b6eb5349f177cb9a5c621a01a44c8c65a
1//
2// Copyright (C) 2015 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#include "trunks/trunks_client_test.h"
18
19#include <algorithm>
20#include <map>
21#include <memory>
22#include <string>
23#include <vector>
24
25#include <base/callback.h>
26#include <base/logging.h>
27#include <base/stl_util.h>
28#include <brillo/bind_lambda.h>
29#include <crypto/openssl_util.h>
30#include <crypto/scoped_openssl_types.h>
31#include <crypto/sha2.h>
32#include <openssl/bn.h>
33#include <openssl/err.h>
34#include <openssl/rsa.h>
35
36#include "trunks/authorization_delegate.h"
37#include "trunks/error_codes.h"
38#include "trunks/hmac_session.h"
39#include "trunks/policy_session.h"
40#include "trunks/scoped_key_handle.h"
41#include "trunks/tpm_constants.h"
42#include "trunks/tpm_generated.h"
43#include "trunks/tpm_state.h"
44#include "trunks/tpm_utility.h"
45#include "trunks/trunks_factory_impl.h"
46
47namespace {
48
49std::string GetOpenSSLError() {
50  BIO* bio = BIO_new(BIO_s_mem());
51  ERR_print_errors(bio);
52  char* data = nullptr;
53  int data_len = BIO_get_mem_data(bio, &data);
54  std::string error_string(data, data_len);
55  BIO_free(bio);
56  return error_string;
57}
58
59}  // namespace
60
61namespace trunks {
62
63TrunksClientTest::TrunksClientTest(const TrunksFactory& factory)
64    : factory_(factory) {
65  crypto::EnsureOpenSSLInit();
66}
67
68TrunksClientTest::~TrunksClientTest() {}
69
70bool TrunksClientTest::RNGTest() {
71  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
72  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
73  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
74    LOG(ERROR) << "Error starting hmac session.";
75    return false;
76  }
77  std::string entropy_data("entropy_data");
78  std::string random_data;
79  size_t num_bytes = 70;
80  TPM_RC result = utility->StirRandom(entropy_data, session->GetDelegate());
81  if (result != TPM_RC_SUCCESS) {
82    LOG(ERROR) << "Error stirring TPM RNG: " << GetErrorString(result);
83    return false;
84  }
85  result =
86      utility->GenerateRandom(num_bytes, session->GetDelegate(), &random_data);
87  if (result != TPM_RC_SUCCESS) {
88    LOG(ERROR) << "Error getting random bytes from TPM: "
89               << GetErrorString(result);
90    return false;
91  }
92  if (num_bytes != random_data.size()) {
93    LOG(ERROR) << "Error not enough random bytes received.";
94    return false;
95  }
96  return true;
97}
98
99bool TrunksClientTest::SignTest() {
100  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
101  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
102  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
103    LOG(ERROR) << "Error starting hmac session.";
104    return false;
105  }
106  std::string key_authorization("sign");
107  std::string key_blob;
108  TPM_RC result = utility->CreateRSAKeyPair(
109      TpmUtility::AsymmetricKeyUsage::kSignKey, 2048, 0x10001,
110      key_authorization, "", false,  // use_only_policy_authorization
111      kNoCreationPCR, session->GetDelegate(), &key_blob, nullptr);
112  if (result != TPM_RC_SUCCESS) {
113    LOG(ERROR) << "Error creating signing key: " << GetErrorString(result);
114    return false;
115  }
116  TPM_HANDLE signing_key;
117  result = utility->LoadKey(key_blob, session->GetDelegate(), &signing_key);
118  if (result != TPM_RC_SUCCESS) {
119    LOG(ERROR) << "Error loading signing key: " << GetErrorString(result);
120  }
121  ScopedKeyHandle scoped_key(factory_, signing_key);
122  session->SetEntityAuthorizationValue(key_authorization);
123  std::string signature;
124  result =
125      utility->Sign(signing_key, TPM_ALG_NULL, TPM_ALG_NULL,
126                    std::string(32, 'a'), session->GetDelegate(), &signature);
127  if (result != TPM_RC_SUCCESS) {
128    LOG(ERROR) << "Error using key to sign: " << GetErrorString(result);
129    return false;
130  }
131  result = utility->Verify(signing_key, TPM_ALG_NULL, TPM_ALG_NULL,
132                           std::string(32, 'a'), signature, nullptr);
133  if (result != TPM_RC_SUCCESS) {
134    LOG(ERROR) << "Error using key to verify: " << GetErrorString(result);
135    return false;
136  }
137  return true;
138}
139
140bool TrunksClientTest::DecryptTest() {
141  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
142  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
143  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
144    LOG(ERROR) << "Error starting hmac session.";
145    return false;
146  }
147  std::string key_authorization("decrypt");
148  std::string key_blob;
149  TPM_RC result = utility->CreateRSAKeyPair(
150      TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001,
151      key_authorization, "", false,  // use_only_policy_authorization
152      kNoCreationPCR, session->GetDelegate(), &key_blob, nullptr);
153  if (result != TPM_RC_SUCCESS) {
154    LOG(ERROR) << "Error creating decrypt key: " << GetErrorString(result);
155    return false;
156  }
157  TPM_HANDLE decrypt_key;
158  result = utility->LoadKey(key_blob, session->GetDelegate(), &decrypt_key);
159  if (result != TPM_RC_SUCCESS) {
160    LOG(ERROR) << "Error loading decrypt key: " << GetErrorString(result);
161  }
162  ScopedKeyHandle scoped_key(factory_, decrypt_key);
163  return PerformRSAEncrpytAndDecrpyt(scoped_key.get(), key_authorization,
164                                     session.get());
165}
166
167bool TrunksClientTest::ImportTest() {
168  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
169  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
170  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
171    LOG(ERROR) << "Error starting hmac session.";
172    return false;
173  }
174  std::string modulus;
175  std::string prime_factor;
176  GenerateRSAKeyPair(&modulus, &prime_factor, nullptr);
177  std::string key_blob;
178  std::string key_authorization("import");
179  TPM_RC result = utility->ImportRSAKey(
180      TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, modulus, 0x10001,
181      prime_factor, key_authorization, session->GetDelegate(), &key_blob);
182  if (result != TPM_RC_SUCCESS) {
183    LOG(ERROR) << "Error importing key into TPM: " << GetErrorString(result);
184    return false;
185  }
186  TPM_HANDLE key_handle;
187  result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle);
188  if (result != TPM_RC_SUCCESS) {
189    LOG(ERROR) << "Error loading key into TPM: " << GetErrorString(result);
190    return false;
191  }
192  ScopedKeyHandle scoped_key(factory_, key_handle);
193  return PerformRSAEncrpytAndDecrpyt(scoped_key.get(), key_authorization,
194                                     session.get());
195}
196
197bool TrunksClientTest::AuthChangeTest() {
198  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
199  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
200  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
201    LOG(ERROR) << "Error starting hmac session.";
202    return false;
203  }
204  std::string key_authorization("new_pass");
205  std::string key_blob;
206  TPM_RC result = utility->CreateRSAKeyPair(
207      TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001, "old_pass",
208      "", false,  // use_only_policy_authorization
209      kNoCreationPCR, session->GetDelegate(), &key_blob, nullptr);
210  if (result != TPM_RC_SUCCESS) {
211    LOG(ERROR) << "Error creating change auth key: " << GetErrorString(result);
212    return false;
213  }
214  TPM_HANDLE key_handle;
215  result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle);
216  if (result != TPM_RC_SUCCESS) {
217    LOG(ERROR) << "Error loading change auth key: " << GetErrorString(result);
218  }
219  ScopedKeyHandle scoped_key(factory_, key_handle);
220  session->SetEntityAuthorizationValue("old_pass");
221  result = utility->ChangeKeyAuthorizationData(
222      key_handle, key_authorization, session->GetDelegate(), &key_blob);
223  if (result != TPM_RC_SUCCESS) {
224    LOG(ERROR) << "Error changing auth data: " << GetErrorString(result);
225    return false;
226  }
227  session->SetEntityAuthorizationValue("");
228  result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle);
229  if (result != TPM_RC_SUCCESS) {
230    LOG(ERROR) << "Error reloading key: " << GetErrorString(result);
231    return false;
232  }
233  scoped_key.reset(key_handle);
234  return PerformRSAEncrpytAndDecrpyt(scoped_key.get(), key_authorization,
235                                     session.get());
236}
237
238bool TrunksClientTest::VerifyKeyCreationTest() {
239  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
240  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
241  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
242    LOG(ERROR) << "Error starting hmac session.";
243    return false;
244  }
245  std::string key_blob;
246  std::string creation_blob;
247  session->SetEntityAuthorizationValue("");
248  TPM_RC result = utility->CreateRSAKeyPair(
249      TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001, "", "",
250      false,  // use_only_policy_authorization
251      kNoCreationPCR, session->GetDelegate(), &key_blob, &creation_blob);
252  if (result != TPM_RC_SUCCESS) {
253    LOG(ERROR) << "Error creating certify key: " << GetErrorString(result);
254    return false;
255  }
256  std::string alternate_key_blob;
257  result = utility->CreateRSAKeyPair(
258      TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001, "", "",
259      false,  // use_only_policy_authorization
260      kNoCreationPCR, session->GetDelegate(), &alternate_key_blob, nullptr);
261  if (result != TPM_RC_SUCCESS) {
262    LOG(ERROR) << "Error creating alternate key: " << GetErrorString(result);
263    return false;
264  }
265  TPM_HANDLE key_handle;
266  result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle);
267  if (result != TPM_RC_SUCCESS) {
268    LOG(ERROR) << "Error loading certify key: " << GetErrorString(result);
269    return false;
270  }
271  TPM_HANDLE alternate_key_handle;
272  result = utility->LoadKey(alternate_key_blob, session->GetDelegate(),
273                            &alternate_key_handle);
274  if (result != TPM_RC_SUCCESS) {
275    LOG(ERROR) << "Error loading alternate key: " << GetErrorString(result);
276    return false;
277  }
278  ScopedKeyHandle certify_key(factory_, key_handle);
279  ScopedKeyHandle alternate_key(factory_, alternate_key_handle);
280  result = utility->CertifyCreation(certify_key.get(), creation_blob);
281  if (result != TPM_RC_SUCCESS) {
282    LOG(ERROR) << "Error certifying key: " << GetErrorString(result);
283    return false;
284  }
285  result = utility->CertifyCreation(alternate_key.get(), creation_blob);
286  if (result == TPM_RC_SUCCESS) {
287    LOG(ERROR) << "Error alternate key certified with wrong creation data.";
288    return false;
289  }
290  return true;
291}
292
293bool TrunksClientTest::SealedDataTest() {
294  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
295  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
296  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
297    LOG(ERROR) << "Error starting hmac session.";
298    return false;
299  }
300  int pcr_index = 5;
301  std::string policy_digest;
302  TPM_RC result =
303      utility->GetPolicyDigestForPcrValue(pcr_index, "", &policy_digest);
304  if (result != TPM_RC_SUCCESS) {
305    LOG(ERROR) << "Error getting policy_digest: " << GetErrorString(result);
306    return false;
307  }
308  std::string data_to_seal("seal_data");
309  std::string sealed_data;
310  result = utility->SealData(data_to_seal, policy_digest,
311                             session->GetDelegate(), &sealed_data);
312  if (result != TPM_RC_SUCCESS) {
313    LOG(ERROR) << "Error creating Sealed Object: " << GetErrorString(result);
314    return false;
315  }
316  std::unique_ptr<PolicySession> policy_session = factory_.GetPolicySession();
317  result = policy_session->StartUnboundSession(false);
318  if (result != TPM_RC_SUCCESS) {
319    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
320    return false;
321  }
322  result = policy_session->PolicyPCR(pcr_index, "");
323  if (result != TPM_RC_SUCCESS) {
324    LOG(ERROR) << "Error restricting policy to pcr value: "
325               << GetErrorString(result);
326    return false;
327  }
328  std::string unsealed_data;
329  result = utility->UnsealData(sealed_data, policy_session->GetDelegate(),
330                               &unsealed_data);
331  if (result != TPM_RC_SUCCESS) {
332    LOG(ERROR) << "Error unsealing object: " << GetErrorString(result);
333    return false;
334  }
335  if (data_to_seal != unsealed_data) {
336    LOG(ERROR) << "Error unsealed data from TPM does not match original data.";
337    return false;
338  }
339  result = utility->ExtendPCR(pcr_index, "extend", session->GetDelegate());
340  if (result != TPM_RC_SUCCESS) {
341    LOG(ERROR) << "Error extending pcr: " << GetErrorString(result);
342    return false;
343  }
344  result = policy_session->PolicyPCR(pcr_index, "");
345  if (result != TPM_RC_SUCCESS) {
346    LOG(ERROR) << "Error restricting policy to pcr value: "
347               << GetErrorString(result);
348    return false;
349  }
350  result = utility->UnsealData(sealed_data, policy_session->GetDelegate(),
351                               &unsealed_data);
352  if (result == TPM_RC_SUCCESS) {
353    LOG(ERROR) << "Error object was unsealed with wrong policy_digest.";
354    return false;
355  }
356  return true;
357}
358
359bool TrunksClientTest::PCRTest() {
360  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
361  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
362  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
363    LOG(ERROR) << "Error starting hmac session.";
364    return false;
365  }
366  // We are using PCR 2 because it is currently not used by ChromeOS.
367  uint32_t pcr_index = 2;
368  std::string extend_data("data");
369  std::string old_data;
370  TPM_RC result = utility->ReadPCR(pcr_index, &old_data);
371  if (result != TPM_RC_SUCCESS) {
372    LOG(ERROR) << "Error reading from PCR: " << GetErrorString(result);
373    return false;
374  }
375  result = utility->ExtendPCR(pcr_index, extend_data, session->GetDelegate());
376  if (result != TPM_RC_SUCCESS) {
377    LOG(ERROR) << "Error extending PCR value: " << GetErrorString(result);
378    return false;
379  }
380  std::string pcr_data;
381  result = utility->ReadPCR(pcr_index, &pcr_data);
382  if (result != TPM_RC_SUCCESS) {
383    LOG(ERROR) << "Error reading from PCR: " << GetErrorString(result);
384    return false;
385  }
386  std::string hashed_extend_data = crypto::SHA256HashString(extend_data);
387  std::string expected_pcr_data =
388      crypto::SHA256HashString(old_data + hashed_extend_data);
389  if (pcr_data.compare(expected_pcr_data) != 0) {
390    LOG(ERROR) << "PCR data does not match expected value.";
391    return false;
392  }
393  return true;
394}
395
396bool TrunksClientTest::PolicyAuthValueTest() {
397  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
398  std::unique_ptr<PolicySession> trial_session = factory_.GetTrialSession();
399  TPM_RC result;
400  result = trial_session->StartUnboundSession(true);
401  if (result != TPM_RC_SUCCESS) {
402    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
403    return false;
404  }
405  result = trial_session->PolicyAuthValue();
406  if (result != TPM_RC_SUCCESS) {
407    LOG(ERROR) << "Error restricting policy to auth value knowledge: "
408               << GetErrorString(result);
409    return false;
410  }
411  std::string policy_digest;
412  result = trial_session->GetDigest(&policy_digest);
413  if (result != TPM_RC_SUCCESS) {
414    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
415    return false;
416  }
417  // Now that we have the digest, we can close the trial session and use hmac.
418  trial_session.reset();
419
420  std::unique_ptr<HmacSession> hmac_session = factory_.GetHmacSession();
421  result = hmac_session->StartUnboundSession(true);
422  if (result != TPM_RC_SUCCESS) {
423    LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
424    return false;
425  }
426
427  std::string key_blob;
428  result = utility->CreateRSAKeyPair(
429      TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001,
430      "password", policy_digest, true,  // use_only_policy_authorization
431      kNoCreationPCR, hmac_session->GetDelegate(), &key_blob, nullptr);
432  if (result != TPM_RC_SUCCESS) {
433    LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result);
434    return false;
435  }
436
437  TPM_HANDLE key_handle;
438  result = utility->LoadKey(key_blob, hmac_session->GetDelegate(), &key_handle);
439  if (result != TPM_RC_SUCCESS) {
440    LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result);
441    return false;
442  }
443  ScopedKeyHandle scoped_key(factory_, key_handle);
444
445  // Now we can reset the hmac_session.
446  hmac_session.reset();
447
448  std::unique_ptr<PolicySession> policy_session = factory_.GetPolicySession();
449  result = policy_session->StartUnboundSession(false);
450  if (result != TPM_RC_SUCCESS) {
451    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
452    return false;
453  }
454  result = policy_session->PolicyAuthValue();
455  if (result != TPM_RC_SUCCESS) {
456    LOG(ERROR) << "Error restricting policy to auth value knowledge: "
457               << GetErrorString(result);
458    return false;
459  }
460  std::string signature;
461  policy_session->SetEntityAuthorizationValue("password");
462  result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
463                         std::string(32, 0), policy_session->GetDelegate(),
464                         &signature);
465  if (result != TPM_RC_SUCCESS) {
466    LOG(ERROR) << "Error signing using RSA key: " << GetErrorString(result);
467    return false;
468  }
469  result = utility->Verify(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
470                           std::string(32, 0), signature, nullptr);
471  if (result != TPM_RC_SUCCESS) {
472    LOG(ERROR) << "Error verifying using RSA key: " << GetErrorString(result);
473    return false;
474  }
475  std::string ciphertext;
476  result =
477      utility->AsymmetricEncrypt(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
478                                 "plaintext", nullptr, &ciphertext);
479  if (result != TPM_RC_SUCCESS) {
480    LOG(ERROR) << "Error encrypting using RSA key: " << GetErrorString(result);
481    return false;
482  }
483  result = policy_session->PolicyAuthValue();
484  if (result != TPM_RC_SUCCESS) {
485    LOG(ERROR) << "Error restricting policy to auth value knowledge: "
486               << GetErrorString(result);
487    return false;
488  }
489  std::string plaintext;
490  policy_session->SetEntityAuthorizationValue("password");
491  result = utility->AsymmetricDecrypt(
492      scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL, ciphertext,
493      policy_session->GetDelegate(), &plaintext);
494  if (result != TPM_RC_SUCCESS) {
495    LOG(ERROR) << "Error encrypting using RSA key: " << GetErrorString(result);
496    return false;
497  }
498  if (plaintext.compare("plaintext") != 0) {
499    LOG(ERROR) << "Plaintext changed after encrypt + decrypt.";
500    return false;
501  }
502  return true;
503}
504
505bool TrunksClientTest::PolicyAndTest() {
506  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
507  std::unique_ptr<PolicySession> trial_session = factory_.GetTrialSession();
508  TPM_RC result;
509  result = trial_session->StartUnboundSession(true);
510  if (result != TPM_RC_SUCCESS) {
511    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
512    return false;
513  }
514  result = trial_session->PolicyCommandCode(TPM_CC_Sign);
515  if (result != TPM_RC_SUCCESS) {
516    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
517    return false;
518  }
519  uint32_t pcr_index = 2;
520  std::string pcr_value;
521  result = utility->ReadPCR(pcr_index, &pcr_value);
522  if (result != TPM_RC_SUCCESS) {
523    LOG(ERROR) << "Error reading pcr: " << GetErrorString(result);
524    return false;
525  }
526  std::string pcr_extend_data("extend");
527  std::string next_pcr_value;
528  std::string hashed_extend_data = crypto::SHA256HashString(pcr_extend_data);
529  next_pcr_value = crypto::SHA256HashString(pcr_value + hashed_extend_data);
530
531  result = trial_session->PolicyPCR(pcr_index, next_pcr_value);
532  if (result != TPM_RC_SUCCESS) {
533    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
534    return false;
535  }
536  std::string policy_digest;
537  result = trial_session->GetDigest(&policy_digest);
538  if (result != TPM_RC_SUCCESS) {
539    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
540    return false;
541  }
542  // Now that we have the digest, we can close the trial session and use hmac.
543  trial_session.reset();
544
545  std::unique_ptr<HmacSession> hmac_session = factory_.GetHmacSession();
546  result = hmac_session->StartUnboundSession(true);
547  if (result != TPM_RC_SUCCESS) {
548    LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
549    return false;
550  }
551  std::string key_authorization("password");
552  std::string key_blob;
553  // This key is created with a policy that dictates it can only be used
554  // when pcr 2 remains unchanged, and when the command is TPM2_Sign.
555  result = utility->CreateRSAKeyPair(
556      TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001,
557      key_authorization, policy_digest, true,  // use_only_policy_authorization
558      kNoCreationPCR, hmac_session->GetDelegate(), &key_blob, nullptr);
559  if (result != TPM_RC_SUCCESS) {
560    LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result);
561    return false;
562  }
563  TPM_HANDLE key_handle;
564  result = utility->LoadKey(key_blob, hmac_session->GetDelegate(), &key_handle);
565  if (result != TPM_RC_SUCCESS) {
566    LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result);
567    return false;
568  }
569  ScopedKeyHandle scoped_key(factory_, key_handle);
570
571  // Now we can reset the hmac_session.
572  hmac_session.reset();
573
574  std::unique_ptr<PolicySession> policy_session = factory_.GetPolicySession();
575  result = policy_session->StartUnboundSession(false);
576  if (result != TPM_RC_SUCCESS) {
577    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
578    return false;
579  }
580  result = policy_session->PolicyCommandCode(TPM_CC_Sign);
581  if (result != TPM_RC_SUCCESS) {
582    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
583    return false;
584  }
585  result = policy_session->PolicyPCR(pcr_index, "");
586  if (result != TPM_RC_SUCCESS) {
587    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
588    return false;
589  }
590  std::string signature;
591  policy_session->SetEntityAuthorizationValue(key_authorization);
592  // Signing with this key when pcr 2 is unchanged fails.
593  result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
594                         std::string(32, 'a'), policy_session->GetDelegate(),
595                         &signature);
596  if (GetFormatOneError(result) != TPM_RC_POLICY_FAIL) {
597    LOG(ERROR) << "Error using key to sign: " << GetErrorString(result);
598    return false;
599  }
600  std::unique_ptr<AuthorizationDelegate> delegate =
601      factory_.GetPasswordAuthorization("");
602  result = utility->ExtendPCR(pcr_index, pcr_extend_data, delegate.get());
603  if (result != TPM_RC_SUCCESS) {
604    LOG(ERROR) << "Error extending pcr: " << GetErrorString(result);
605    return false;
606  }
607  // we have to restart the session because we changed the pcr values.
608  result = policy_session->StartUnboundSession(false);
609  if (result != TPM_RC_SUCCESS) {
610    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
611    return false;
612  }
613  result = policy_session->PolicyCommandCode(TPM_CC_Sign);
614  if (result != TPM_RC_SUCCESS) {
615    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
616    return false;
617  }
618  result = policy_session->PolicyPCR(pcr_index, "");
619  if (result != TPM_RC_SUCCESS) {
620    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
621    return false;
622  }
623  policy_session->SetEntityAuthorizationValue(key_authorization);
624  // Signing with this key when pcr 2 is changed succeeds.
625  result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
626                         std::string(32, 'a'), policy_session->GetDelegate(),
627                         &signature);
628  if (result != TPM_RC_SUCCESS) {
629    LOG(ERROR) << "Error using key to sign: " << GetErrorString(result);
630    return false;
631  }
632  result = utility->Verify(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
633                           std::string(32, 'a'), signature, nullptr);
634  if (result != TPM_RC_SUCCESS) {
635    LOG(ERROR) << "Error using key to verify: " << GetErrorString(result);
636    return false;
637  }
638  std::string ciphertext;
639  result = utility->AsymmetricEncrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL,
640                                      "plaintext", nullptr, &ciphertext);
641  if (result != TPM_RC_SUCCESS) {
642    LOG(ERROR) << "Error using key to encrypt: " << GetErrorString(result);
643    return false;
644  }
645  result = policy_session->PolicyCommandCode(TPM_CC_Sign);
646  if (result != TPM_RC_SUCCESS) {
647    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
648    return false;
649  }
650  result = policy_session->PolicyPCR(pcr_index, "");
651  if (result != TPM_RC_SUCCESS) {
652    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
653    return false;
654  }
655  std::string plaintext;
656  policy_session->SetEntityAuthorizationValue(key_authorization);
657  // This call is not authorized with the policy, because its command code
658  // is not TPM_CC_SIGN. It should fail with TPM_RC_POLICY_CC.
659  result = utility->AsymmetricDecrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL,
660                                      ciphertext, policy_session->GetDelegate(),
661                                      &plaintext);
662  if (GetFormatOneError(result) != TPM_RC_POLICY_CC) {
663    LOG(ERROR) << "Error: " << GetErrorString(result);
664    return false;
665  }
666  return true;
667}
668
669bool TrunksClientTest::PolicyOrTest() {
670  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
671  std::unique_ptr<PolicySession> trial_session = factory_.GetTrialSession();
672  TPM_RC result;
673  // Specify a policy that asserts either TPM_CC_RSA_Encrypt or
674  // TPM_CC_RSA_Decrypt. A key created under this policy can only be used
675  // to encrypt or decrypt.
676  result = trial_session->StartUnboundSession(true);
677  if (result != TPM_RC_SUCCESS) {
678    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
679    return false;
680  }
681  result = trial_session->PolicyCommandCode(TPM_CC_Sign);
682  if (result != TPM_RC_SUCCESS) {
683    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
684    return false;
685  }
686  std::string sign_digest;
687  result = trial_session->GetDigest(&sign_digest);
688  if (result != TPM_RC_SUCCESS) {
689    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
690    return false;
691  }
692  result = trial_session->StartUnboundSession(true);
693  if (result != TPM_RC_SUCCESS) {
694    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
695    return false;
696  }
697  result = trial_session->PolicyCommandCode(TPM_CC_RSA_Decrypt);
698  if (result != TPM_RC_SUCCESS) {
699    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
700    return false;
701  }
702  std::string decrypt_digest;
703  result = trial_session->GetDigest(&decrypt_digest);
704  if (result != TPM_RC_SUCCESS) {
705    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
706    return false;
707  }
708  std::vector<std::string> digests;
709  digests.push_back(sign_digest);
710  digests.push_back(decrypt_digest);
711  result = trial_session->PolicyOR(digests);
712  if (result != TPM_RC_SUCCESS) {
713    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
714    return false;
715  }
716  std::string policy_digest;
717  result = trial_session->GetDigest(&policy_digest);
718  if (result != TPM_RC_SUCCESS) {
719    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
720    return false;
721  }
722  // Now that we have the digest, we can close the trial session and use hmac.
723  trial_session.reset();
724
725  std::unique_ptr<HmacSession> hmac_session = factory_.GetHmacSession();
726  result = hmac_session->StartUnboundSession(true);
727  if (result != TPM_RC_SUCCESS) {
728    LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
729    return false;
730  }
731  std::string key_authorization("password");
732  std::string key_blob;
733  // This key is created with a policy that specifies that it can only be used
734  // for encrypt and decrypt operations.
735  result = utility->CreateRSAKeyPair(
736      TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001,
737      key_authorization, policy_digest, true,  // use_only_policy_authorization
738      kNoCreationPCR, hmac_session->GetDelegate(), &key_blob, nullptr);
739  if (result != TPM_RC_SUCCESS) {
740    LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result);
741    return false;
742  }
743  TPM_HANDLE key_handle;
744  result = utility->LoadKey(key_blob, hmac_session->GetDelegate(), &key_handle);
745  if (result != TPM_RC_SUCCESS) {
746    LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result);
747    return false;
748  }
749  ScopedKeyHandle scoped_key(factory_, key_handle);
750
751  // Now we can reset the hmac_session.
752  hmac_session.reset();
753
754  std::unique_ptr<PolicySession> policy_session = factory_.GetPolicySession();
755  result = policy_session->StartUnboundSession(false);
756  if (result != TPM_RC_SUCCESS) {
757    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
758    return false;
759  }
760  std::string ciphertext;
761  result = utility->AsymmetricEncrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL,
762                                      "plaintext", nullptr, &ciphertext);
763  if (result != TPM_RC_SUCCESS) {
764    LOG(ERROR) << "Error using key to encrypt: " << GetErrorString(result);
765    return false;
766  }
767  result = policy_session->PolicyCommandCode(TPM_CC_RSA_Decrypt);
768  if (result != TPM_RC_SUCCESS) {
769    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
770    return false;
771  }
772  result = policy_session->PolicyOR(digests);
773  if (result != TPM_RC_SUCCESS) {
774    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
775    return false;
776  }
777  std::string plaintext;
778  policy_session->SetEntityAuthorizationValue(key_authorization);
779  // We can freely use the key for decryption.
780  result = utility->AsymmetricDecrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL,
781                                      ciphertext, policy_session->GetDelegate(),
782                                      &plaintext);
783  if (result != TPM_RC_SUCCESS) {
784    LOG(ERROR) << "Error using key to decrypt: " << GetErrorString(result);
785    return false;
786  }
787  if (plaintext.compare("plaintext") != 0) {
788    LOG(ERROR) << "Plaintext changed after encrypt + decrypt.";
789    return false;
790  }
791  result = policy_session->PolicyCommandCode(TPM_CC_Sign);
792  if (result != TPM_RC_SUCCESS) {
793    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
794    return false;
795  }
796  result = policy_session->PolicyOR(digests);
797  if (result != TPM_RC_SUCCESS) {
798    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
799    return false;
800  }
801  std::string signature;
802  policy_session->SetEntityAuthorizationValue(key_authorization);
803  // However signing with a key only authorized for encrypt/decrypt should
804  // fail with TPM_RC_POLICY_CC.
805  result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
806                         std::string(32, 'a'), policy_session->GetDelegate(),
807                         &signature);
808  if (result != TPM_RC_SUCCESS) {
809    LOG(ERROR) << "Error using key to sign: " << GetErrorString(result);
810    return false;
811  }
812  return true;
813}
814
815bool TrunksClientTest::NvramTest(const std::string& owner_password) {
816  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
817  std::unique_ptr<HmacSession> session = factory_.GetHmacSession();
818  TPM_RC result = session->StartUnboundSession(true /* enable encryption */);
819  if (result != TPM_RC_SUCCESS) {
820    LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
821    return false;
822  }
823  uint32_t index = 1;
824  session->SetEntityAuthorizationValue(owner_password);
825  std::string nv_data("nv_data");
826  TPMA_NV attributes = TPMA_NV_OWNERWRITE | TPMA_NV_AUTHREAD |
827                       TPMA_NV_WRITE_STCLEAR | TPMA_NV_READ_STCLEAR;
828  result = utility->DefineNVSpace(index, nv_data.size(), attributes, "", "",
829                                  session->GetDelegate());
830  if (result != TPM_RC_SUCCESS) {
831    LOG(ERROR) << "Error defining nvram: " << GetErrorString(result);
832    return false;
833  }
834  // Setup auto-cleanup of the NVRAM space.
835  auto cleanup = [](HmacSession* session, const std::string& owner_password,
836                    TpmUtility* utility, uint32_t index) {
837    session->SetEntityAuthorizationValue(owner_password);
838    TPM_RC result = utility->DestroyNVSpace(index, session->GetDelegate());
839    if (result != TPM_RC_SUCCESS) {
840      LOG(ERROR) << "Error destroying nvram: " << GetErrorString(result);
841    }
842  };
843  class Scoper {
844   public:
845    explicit Scoper(const base::Closure& callback) : callback_(callback) {}
846    ~Scoper() {
847      if (!cancel_)
848        callback_.Run();
849    }
850    void Cancel() { cancel_ = true; }
851
852   private:
853    base::Closure callback_;
854    bool cancel_ = false;
855  } scoper(base::Bind(cleanup, base::Unretained(session.get()), owner_password,
856                      base::Unretained(utility.get()), index));
857
858  session->SetEntityAuthorizationValue(owner_password);
859  result = utility->WriteNVSpace(index, 0, nv_data, true /*owner*/,
860                                 false /*extend*/, session->GetDelegate());
861  if (result != TPM_RC_SUCCESS) {
862    LOG(ERROR) << "Error writing nvram: " << GetErrorString(result);
863    return false;
864  }
865  std::string new_nvdata;
866  session->SetEntityAuthorizationValue("");
867  result = utility->ReadNVSpace(index, 0, nv_data.size(), false /*owner*/,
868                                &new_nvdata, session->GetDelegate());
869  if (result != TPM_RC_SUCCESS) {
870    LOG(ERROR) << "Error reading nvram: " << GetErrorString(result);
871    return false;
872  }
873  if (nv_data.compare(new_nvdata) != 0) {
874    LOG(ERROR) << "NV space had different data than was written.";
875    return false;
876  }
877  session->SetEntityAuthorizationValue(owner_password);
878  result = utility->LockNVSpace(index, false /*lock_read*/, true /*lock_write*/,
879                                false /*owner*/, session->GetDelegate());
880  if (result != TPM_RC_SUCCESS) {
881    LOG(ERROR) << "Error locking nvram write: " << GetErrorString(result);
882    return false;
883  }
884  session->SetEntityAuthorizationValue("");
885  result = utility->ReadNVSpace(index, 0, nv_data.size(), false /*owner*/,
886                                &new_nvdata, session->GetDelegate());
887  if (result != TPM_RC_SUCCESS) {
888    LOG(ERROR) << "Error reading nvram: " << GetErrorString(result);
889    return false;
890  }
891  if (nv_data.compare(new_nvdata) != 0) {
892    LOG(ERROR) << "NV space had different data than was written.";
893    return false;
894  }
895  session->SetEntityAuthorizationValue(owner_password);
896  result = utility->WriteNVSpace(index, 0, nv_data, true /*owner*/,
897                                 false /*extend*/, session->GetDelegate());
898  if (result == TPM_RC_SUCCESS) {
899    LOG(ERROR) << "Wrote nvram after locking!";
900    return false;
901  }
902  result = utility->LockNVSpace(index, true /*lock_read*/, false /*lock_write*/,
903                                true /*owner*/, session->GetDelegate());
904  if (result != TPM_RC_SUCCESS) {
905    LOG(ERROR) << "Error locking nvram read: " << GetErrorString(result);
906    return false;
907  }
908  result = utility->ReadNVSpace(index, 0, nv_data.size(), false /*owner*/,
909                                &new_nvdata, session->GetDelegate());
910  if (result == TPM_RC_SUCCESS) {
911    LOG(ERROR) << "Read nvram after locking!";
912    return false;
913  }
914  return true;
915}
916
917bool TrunksClientTest::ManyKeysTest() {
918  const size_t kNumKeys = 20;
919  std::vector<std::unique_ptr<ScopedKeyHandle>> key_handles;
920  std::map<TPM_HANDLE, std::string> public_key_map;
921  for (size_t i = 0; i < kNumKeys; ++i) {
922    std::unique_ptr<ScopedKeyHandle> key_handle(new ScopedKeyHandle(factory_));
923    std::string public_key;
924    if (!LoadSigningKey(key_handle.get(), &public_key)) {
925      LOG(ERROR) << "Error loading key " << i << " into TPM.";
926    }
927    public_key_map[key_handle->get()] = public_key;
928    key_handles.push_back(std::move(key_handle));
929  }
930  CHECK_EQ(key_handles.size(), kNumKeys);
931  CHECK_EQ(public_key_map.size(), kNumKeys);
932  std::unique_ptr<AuthorizationDelegate> delegate =
933      factory_.GetPasswordAuthorization("");
934  for (size_t i = 0; i < kNumKeys; ++i) {
935    const ScopedKeyHandle& key_handle = *key_handles[i];
936    const std::string& public_key = public_key_map[key_handle.get()];
937    if (!SignAndVerify(key_handle, public_key, delegate.get())) {
938      LOG(ERROR) << "Error signing with key " << i;
939    }
940  }
941  std::random_shuffle(key_handles.begin(), key_handles.end());
942  for (size_t i = 0; i < kNumKeys; ++i) {
943    const ScopedKeyHandle& key_handle = *key_handles[i];
944    const std::string& public_key = public_key_map[key_handle.get()];
945    if (!SignAndVerify(key_handle, public_key, delegate.get())) {
946      LOG(ERROR) << "Error signing with shuffled key " << i;
947    }
948  }
949  return true;
950}
951
952bool TrunksClientTest::ManySessionsTest() {
953  const size_t kNumSessions = 20;
954  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
955  std::vector<std::unique_ptr<HmacSession>> sessions;
956  for (size_t i = 0; i < kNumSessions; ++i) {
957    std::unique_ptr<HmacSession> session(factory_.GetHmacSession().release());
958    TPM_RC result = session->StartUnboundSession(true /* enable encryption */);
959    if (result != TPM_RC_SUCCESS) {
960      LOG(ERROR) << "Error starting hmac session " << i << ": "
961                 << GetErrorString(result);
962      return false;
963    }
964    sessions.push_back(std::move(session));
965  }
966  CHECK_EQ(sessions.size(), kNumSessions);
967  ScopedKeyHandle key_handle(factory_);
968  std::string public_key;
969  if (!LoadSigningKey(&key_handle, &public_key)) {
970    return false;
971  }
972  for (size_t i = 0; i < kNumSessions; ++i) {
973    if (!SignAndVerify(key_handle, public_key, sessions[i]->GetDelegate())) {
974      LOG(ERROR) << "Error signing with hmac session " << i;
975    }
976  }
977  std::random_shuffle(sessions.begin(), sessions.end());
978  for (size_t i = 0; i < kNumSessions; ++i) {
979    if (!SignAndVerify(key_handle, public_key, sessions[i]->GetDelegate())) {
980      LOG(ERROR) << "Error signing with shuffled hmac session " << i;
981    }
982  }
983  return true;
984}
985
986bool TrunksClientTest::PerformRSAEncrpytAndDecrpyt(
987    TPM_HANDLE key_handle,
988    const std::string& key_authorization,
989    HmacSession* session) {
990  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
991  std::string ciphertext;
992  session->SetEntityAuthorizationValue("");
993  TPM_RC result = utility->AsymmetricEncrypt(
994      key_handle, TPM_ALG_NULL, TPM_ALG_NULL, "plaintext",
995      session->GetDelegate(), &ciphertext);
996  if (result != TPM_RC_SUCCESS) {
997    LOG(ERROR) << "Error using key to encrypt: " << GetErrorString(result);
998    return false;
999  }
1000  std::string plaintext;
1001  session->SetEntityAuthorizationValue(key_authorization);
1002  result = utility->AsymmetricDecrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL,
1003                                      ciphertext, session->GetDelegate(),
1004                                      &plaintext);
1005  if (result != TPM_RC_SUCCESS) {
1006    LOG(ERROR) << "Error using key to decrypt: " << GetErrorString(result);
1007    return false;
1008  }
1009  if (plaintext.compare("plaintext") != 0) {
1010    LOG(ERROR) << "Plaintext changed after encrypt + decrypt.";
1011    return false;
1012  }
1013  return true;
1014}
1015
1016void TrunksClientTest::GenerateRSAKeyPair(std::string* modulus,
1017                                          std::string* prime_factor,
1018                                          std::string* public_key) {
1019#if defined(OPENSSL_IS_BORINGSSL)
1020  crypto::ScopedRSA rsa(RSA_new());
1021  crypto::ScopedBIGNUM exponent(BN_new());
1022  CHECK(BN_set_word(exponent.get(), RSA_F4));
1023  CHECK(RSA_generate_key_ex(rsa.get(), 2048, exponent.get(), nullptr))
1024      << "Failed to generate RSA key: " << GetOpenSSLError();
1025#else
1026  crypto::ScopedRSA rsa(RSA_generate_key(2048, 0x10001, nullptr, nullptr));
1027  CHECK(rsa.get());
1028#endif
1029  modulus->resize(BN_num_bytes(rsa.get()->n), 0);
1030  BN_bn2bin(rsa.get()->n,
1031            reinterpret_cast<unsigned char*>(string_as_array(modulus)));
1032  prime_factor->resize(BN_num_bytes(rsa.get()->p), 0);
1033  BN_bn2bin(rsa.get()->p,
1034            reinterpret_cast<unsigned char*>(string_as_array(prime_factor)));
1035  if (public_key) {
1036    unsigned char* buffer = NULL;
1037    int length = i2d_RSAPublicKey(rsa.get(), &buffer);
1038    CHECK_GT(length, 0);
1039    crypto::ScopedOpenSSLBytes scoped_buffer(buffer);
1040    public_key->assign(reinterpret_cast<char*>(buffer), length);
1041  }
1042}
1043
1044bool TrunksClientTest::VerifyRSASignature(const std::string& public_key,
1045                                          const std::string& data,
1046                                          const std::string& signature) {
1047  auto asn1_ptr = reinterpret_cast<const unsigned char*>(public_key.data());
1048  crypto::ScopedRSA rsa(
1049      d2i_RSAPublicKey(nullptr, &asn1_ptr, public_key.size()));
1050  CHECK(rsa.get());
1051  std::string digest = crypto::SHA256HashString(data);
1052  auto digest_buffer = reinterpret_cast<const unsigned char*>(digest.data());
1053  std::string mutable_signature(signature);
1054  unsigned char* signature_buffer =
1055      reinterpret_cast<unsigned char*>(string_as_array(&mutable_signature));
1056  return (RSA_verify(NID_sha256, digest_buffer, digest.size(), signature_buffer,
1057                     signature.size(), rsa.get()) == 1);
1058}
1059
1060bool TrunksClientTest::LoadSigningKey(ScopedKeyHandle* key_handle,
1061                                      std::string* public_key) {
1062  std::string modulus;
1063  std::string prime_factor;
1064  GenerateRSAKeyPair(&modulus, &prime_factor, public_key);
1065  std::string key_blob;
1066  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
1067  TPM_RC result = utility->ImportRSAKey(
1068      TpmUtility::AsymmetricKeyUsage::kSignKey, modulus, 0x10001, prime_factor,
1069      "",  // password
1070      factory_.GetPasswordAuthorization("").get(), &key_blob);
1071  if (result != TPM_RC_SUCCESS) {
1072    LOG(ERROR) << "ImportRSAKey: " << GetErrorString(result);
1073    return false;
1074  }
1075  TPM_HANDLE raw_key_handle;
1076  result = utility->LoadKey(
1077      key_blob, factory_.GetPasswordAuthorization("").get(), &raw_key_handle);
1078  if (result != TPM_RC_SUCCESS) {
1079    LOG(ERROR) << "LoadKey: " << GetErrorString(result);
1080    return false;
1081  }
1082  key_handle->reset(raw_key_handle);
1083  return true;
1084}
1085
1086bool TrunksClientTest::SignAndVerify(const ScopedKeyHandle& key_handle,
1087                                     const std::string& public_key,
1088                                     AuthorizationDelegate* delegate) {
1089  std::string signature;
1090  std::string data_to_sign("sign_this");
1091  std::unique_ptr<TpmUtility> utility = factory_.GetTpmUtility();
1092  TPM_RC result =
1093      utility->Sign(key_handle.get(), TPM_ALG_RSASSA, TPM_ALG_SHA256,
1094                    data_to_sign, delegate, &signature);
1095  if (result != TPM_RC_SUCCESS) {
1096    LOG(ERROR) << "Sign: " << GetErrorString(result);
1097    return false;
1098  }
1099  if (!VerifyRSASignature(public_key, data_to_sign, signature)) {
1100    LOG(ERROR) << "Signature verification failed: " << GetOpenSSLError();
1101    return false;
1102  }
1103  return true;
1104}
1105
1106}  // namespace trunks
1107