trunks_client_test.cc revision a6e332ee7f5fe52c1291d961dbeda975c8272044
12be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi// Copyright 2015 The Chromium OS Authors. All rights reserved.
22be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi// Use of this source code is governed by a BSD-style license that can be
32be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi// found in the LICENSE file.
42be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
52be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/trunks_client_test.h"
62be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
74ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <algorithm>
84ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <map>
94ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <memory>
104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <string>
114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <vector>
124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
132be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include <base/logging.h>
142be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include <base/stl_util.h>
152be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include <crypto/scoped_openssl_types.h>
16e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi#include <crypto/sha2.h>
172be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include <openssl/bn.h>
186ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi#include <openssl/err.h>
192be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include <openssl/rsa.h>
202be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include "trunks/authorization_delegate.h"
222be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/error_codes.h"
232be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/hmac_session.h"
242be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/policy_session.h"
252be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/scoped_key_handle.h"
262be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/tpm_generated.h"
272be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/tpm_state.h"
282be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/tpm_utility.h"
292be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/trunks_factory_impl.h"
302be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
312be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghinamespace trunks {
322be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
332be346182387c502f65c65ea4da49707026ce8f9Utkarsh SanghiTrunksClientTest::TrunksClientTest() : factory_(new TrunksFactoryImpl()) {}
342be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
352be346182387c502f65c65ea4da49707026ce8f9Utkarsh SanghiTrunksClientTest::TrunksClientTest(scoped_ptr<TrunksFactory> factory)
362be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    : factory_(factory.Pass()) {}
372be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
382be346182387c502f65c65ea4da49707026ce8f9Utkarsh SanghiTrunksClientTest::~TrunksClientTest() {}
392be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
402be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::RNGTest() {
412be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
422be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
43a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
44a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session.";
45a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
46a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
472be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string entropy_data("entropy_data");
482be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string random_data;
492be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  size_t num_bytes = 70;
50a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->StirRandom(entropy_data, session->GetDelegate());
512be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
522be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error stirring TPM RNG: " << GetErrorString(result);
532be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
542be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
552be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->GenerateRandom(num_bytes, session->GetDelegate(),
562be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                   &random_data);
572be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
582be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error getting random bytes from TPM: "
592be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi               << GetErrorString(result);
602be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
612be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
622be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (num_bytes != random_data.size()) {
632be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error not enough random bytes received.";
642be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
652be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
662be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  return true;
672be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
682be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
692be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::SignTest() {
702be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
712be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
72a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
73a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session.";
742be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
752be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
762be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string key_authorization("sign");
776f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  std::string key_blob;
78a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->CreateRSAKeyPair(
79a5a2f2ea49e0085bf8d7f6f2b6e7cd624d710c01Utkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kSignKey, 2048, 0x10001,
80a5a2f2ea49e0085bf8d7f6f2b6e7cd624d710c01Utkarsh Sanghi      key_authorization, "", false,  // use_only_policy_authorization
810ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi      kNoCreationPCR, session->GetDelegate(), &key_blob, nullptr);
822be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
832be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error creating signing key: " << GetErrorString(result);
842be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
852be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
866f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  TPM_HANDLE signing_key;
876f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  result = utility->LoadKey(key_blob, session->GetDelegate(), &signing_key);
886f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
896f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi    LOG(ERROR) << "Error loading signing key: " << GetErrorString(result);
906f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  }
912be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  ScopedKeyHandle scoped_key(*factory_.get(), signing_key);
924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  session->SetEntityAuthorizationValue(key_authorization);
934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string signature;
944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  result = utility->Sign(signing_key, TPM_ALG_NULL, TPM_ALG_NULL,
954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                         std::string(32, 'a'), session->GetDelegate(),
964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                         &signature);
974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  if (result != TPM_RC_SUCCESS) {
984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    LOG(ERROR) << "Error using key to sign: " << GetErrorString(result);
994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return false;
1004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
1014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  result = utility->Verify(signing_key, TPM_ALG_NULL, TPM_ALG_NULL,
1024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                           std::string(32, 'a'), signature, nullptr);
1034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  if (result != TPM_RC_SUCCESS) {
1044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    LOG(ERROR) << "Error using key to verify: " << GetErrorString(result);
1054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return false;
1064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
1074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  return true;
1082be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
1092be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
1102be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::DecryptTest() {
1112be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
1122be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
113a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
114a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session.";
1152be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
1162be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
1172be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string key_authorization("decrypt");
1186f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  std::string key_blob;
119a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->CreateRSAKeyPair(
1206f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001,
1216ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      key_authorization, "", false,  // use_only_policy_authorization
1220ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi      kNoCreationPCR, session->GetDelegate(), &key_blob, nullptr);
1232be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
1246f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi    LOG(ERROR) << "Error creating decrypt key: " << GetErrorString(result);
1252be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
1262be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
1276f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  TPM_HANDLE decrypt_key;
1286f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  result = utility->LoadKey(key_blob, session->GetDelegate(), &decrypt_key);
1296f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
1306f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi    LOG(ERROR) << "Error loading decrypt key: " << GetErrorString(result);
1316f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  }
1322be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  ScopedKeyHandle scoped_key(*factory_.get(), decrypt_key);
1332be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  return PerformRSAEncrpytAndDecrpyt(scoped_key.get(),
1342be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                     key_authorization,
1352be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                     session.get());
1362be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
1372be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
1382be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::ImportTest() {
1392be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
1402be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
141a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
142a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session.";
1432be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
1442be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
1454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string modulus;
1464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string prime_factor;
1474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  GenerateRSAKeyPair(&modulus, &prime_factor, nullptr);
1482be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string key_blob;
1492be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string key_authorization("import");
150a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->ImportRSAKey(
1512be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, modulus, 0x10001,
1522be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi      prime_factor, key_authorization, session->GetDelegate(), &key_blob);
1532be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
1542be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error importing key into TPM: " << GetErrorString(result);
1552be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
1562be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
1572be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  TPM_HANDLE key_handle;
1582be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle);
1592be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
1602be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error loading key into TPM: " << GetErrorString(result);
1612be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
1622be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
1632be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  ScopedKeyHandle scoped_key(*factory_.get(), key_handle);
1642be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  return PerformRSAEncrpytAndDecrpyt(scoped_key.get(), key_authorization,
1652be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                     session.get());
1662be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
1672be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
1682be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::AuthChangeTest() {
1692be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
1702be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
171a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
172a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session.";
1732be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
1742be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
1752be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string key_authorization("new_pass");
1766f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  std::string key_blob;
177a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->CreateRSAKeyPair(
1786f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001,
1796ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      "old_pass", "", false,  // use_only_policy_authorization
1800ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi      kNoCreationPCR, session->GetDelegate(), &key_blob, nullptr);
1812be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
1826f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi    LOG(ERROR) << "Error creating change auth key: " << GetErrorString(result);
1832be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
1842be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
1856f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  TPM_HANDLE key_handle;
1866f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle);
1876f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
1886f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi    LOG(ERROR) << "Error loading change auth key: " << GetErrorString(result);
1896f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  }
1902be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  ScopedKeyHandle scoped_key(*factory_.get(), key_handle);
1912be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue("old_pass");
1922be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->ChangeKeyAuthorizationData(key_handle, key_authorization,
1932be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                               session->GetDelegate(),
1942be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                               &key_blob);
1952be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
1962be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error changing auth data: " << GetErrorString(result);
1972be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
1982be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
1992be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue("");
2002be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle);
2012be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
2022be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error reloading key: " << GetErrorString(result);
2032be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
2042be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
2052be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_key.reset(key_handle);
2062be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  return PerformRSAEncrpytAndDecrpyt(scoped_key.get(), key_authorization,
2072be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                     session.get());
2082be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
2092be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
210fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghibool TrunksClientTest::VerifyKeyCreationTest() {
211fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
212fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
213a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
214a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session.";
215fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    return false;
216fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  }
217fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  std::string key_blob;
218fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  std::string creation_blob;
219fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  session->SetEntityAuthorizationValue("");
220a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->CreateRSAKeyPair(
221fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001,
222fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi      "", "", false,  // use_only_policy_authorization
223fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi      kNoCreationPCR, session->GetDelegate(), &key_blob, &creation_blob);
224fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
225fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    LOG(ERROR) << "Error creating certify key: " << GetErrorString(result);
226fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    return false;
227fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  }
228fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  std::string alternate_key_blob;
229fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  result = utility->CreateRSAKeyPair(
230fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001,
231fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi      "", "", false,  // use_only_policy_authorization
232fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi      kNoCreationPCR, session->GetDelegate(), &alternate_key_blob,
233fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi      nullptr);
234fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
235fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    LOG(ERROR) << "Error creating alternate key: " << GetErrorString(result);
236fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    return false;
237fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  }
238fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  TPM_HANDLE key_handle;
239fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle);
240fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
241fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    LOG(ERROR) << "Error loading certify key: " << GetErrorString(result);
242fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    return false;
243fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  }
244fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  TPM_HANDLE alternate_key_handle;
245fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  result = utility->LoadKey(alternate_key_blob,
246fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi                            session->GetDelegate(),
247fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi                            &alternate_key_handle);
248fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
249fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    LOG(ERROR) << "Error loading alternate key: " << GetErrorString(result);
250fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    return false;
251fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  }
252fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  ScopedKeyHandle certify_key(*factory_.get(), key_handle);
253fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  ScopedKeyHandle alternate_key(*factory_.get(), alternate_key_handle);
254fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  result = utility->CertifyCreation(certify_key.get(), creation_blob);
255fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
256fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    LOG(ERROR) << "Error certifying key: " << GetErrorString(result);
257fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    return false;
258fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  }
259fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  result = utility->CertifyCreation(alternate_key.get(), creation_blob);
260fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  if (result == TPM_RC_SUCCESS) {
261fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    LOG(ERROR) << "Error alternate key certified with wrong creation data.";
262fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    return false;
263fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  }
264fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  return true;
265fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi}
266fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi
267a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghibool TrunksClientTest::SealedDataTest() {
2686ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
2696ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
270a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
271a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session.";
272a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
273a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
274a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  int pcr_index = 5;
275a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  std::string policy_digest;
276a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->GetPolicyDigestForPcrValue(pcr_index, "",
277a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi                                                      &policy_digest);
278a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
279a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error getting policy_digest: " << GetErrorString(result);
280a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
281a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
282a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  std::string data_to_seal("seal_data");
283a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  std::string sealed_data;
284a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  result = utility->SealData(data_to_seal, policy_digest,
285a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi                             session->GetDelegate(), &sealed_data);
286a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
287a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error creating Sealed Object: " << GetErrorString(result);
288a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
289a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
290a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  scoped_ptr<PolicySession> policy_session = factory_->GetPolicySession();
291a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  result = policy_session->StartUnboundSession(false);
2926ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
293a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
294a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
295a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
296a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  result = policy_session->PolicyPCR(pcr_index, "");
297a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
298a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy to pcr value: "
299a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi               << GetErrorString(result);
300a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
301a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
302a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  std::string unsealed_data;
303a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  result = utility->UnsealData(sealed_data, policy_session->GetDelegate(),
304a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi                               &unsealed_data);
305a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
306a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error unsealing object: " << GetErrorString(result);
307a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
308a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
309a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (data_to_seal != unsealed_data) {
310a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error unsealed data from TPM does not match original data.";
311a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
312a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
313a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  result = utility->ExtendPCR(pcr_index, "extend", session->GetDelegate());
314a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
315a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error extending pcr: " << GetErrorString(result);
316a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
317a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
318a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  result = policy_session->PolicyPCR(pcr_index, "");
319a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
320a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy to pcr value: "
321a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi               << GetErrorString(result);
322a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
323a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
324a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  result = utility->UnsealData(sealed_data, policy_session->GetDelegate(),
325a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi                               &unsealed_data);
326a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (result == TPM_RC_SUCCESS) {
327a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error object was unsealed with wrong policy_digest.";
328a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
329a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
330a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  return true;
331a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi}
332a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi
333a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghibool TrunksClientTest::PCRTest() {
334a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
335a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
336a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
337a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session.";
3386ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
3396ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
3406ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // We are using PCR 2 because it is currently not used by ChromeOS.
3416ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  uint32_t pcr_index = 2;
3426ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string extend_data("data");
3436ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string old_data;
344a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->ReadPCR(pcr_index, &old_data);
3456ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
3466ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error reading from PCR: " << GetErrorString(result);
3476ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
3486ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
3496ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->ExtendPCR(pcr_index, extend_data, session->GetDelegate());
3506ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
3516ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error extending PCR value: " << GetErrorString(result);
3526ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
3536ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
3546ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string pcr_data;
3556ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->ReadPCR(pcr_index, &pcr_data);
3566ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
3576ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error reading from PCR: " << GetErrorString(result);
3586ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
3596ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
3606ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string hashed_extend_data = crypto::SHA256HashString(extend_data);
3616ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string expected_pcr_data =
3626ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      crypto::SHA256HashString(old_data + hashed_extend_data);
3636ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (pcr_data.compare(expected_pcr_data) != 0) {
3646ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "PCR data does not match expected value.";
3656ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
3666ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
3676ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  return true;
3686ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi}
3692be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
3706ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghibool TrunksClientTest::PolicyAuthValueTest() {
3712be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
3726ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<PolicySession> trial_session = factory_->GetTrialSession();
3732be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  TPM_RC result;
3746ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->StartUnboundSession(true);
3752be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
3762be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
3772be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
3782be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
3796ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->PolicyAuthValue();
3802be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
3812be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy to auth value knowledge: "
3822be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi               << GetErrorString(result);
3832be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
3842be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
3856ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string policy_digest;
3866ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->GetDigest(&policy_digest);
3872be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
3882be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
3892be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
3902be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
3916ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Now that we have the digest, we can close the trial session and use hmac.
3926ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  trial_session.reset();
3932be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
3942be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<HmacSession> hmac_session = factory_->GetHmacSession();
3956ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = hmac_session->StartUnboundSession(true);
3962be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
3972be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
3982be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
3992be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4002be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
4012be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string key_blob;
4022be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->CreateRSAKeyPair(
4036ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001,
4046ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      "password", policy_digest, true,  // use_only_policy_authorization
4050ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi      kNoCreationPCR, hmac_session->GetDelegate(), &key_blob, nullptr);
4062be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4072be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result);
4082be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4092be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4102be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
4112be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  TPM_HANDLE key_handle;
4122be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->LoadKey(key_blob, hmac_session->GetDelegate(), &key_handle);
4132be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4142be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result);
4152be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4162be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4172be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  ScopedKeyHandle scoped_key(*factory_.get(), key_handle);
4182be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
4192be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  // Now we can reset the hmac_session.
4202be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  hmac_session.reset();
4212be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
4226ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<PolicySession> policy_session = factory_->GetPolicySession();
4236ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->StartUnboundSession(false);
4242be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4252be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
4262be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4272be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4282be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = policy_session->PolicyAuthValue();
4292be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4302be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy to auth value knowledge: "
4312be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi               << GetErrorString(result);
4322be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4332be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4342be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string signature;
4352be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  policy_session->SetEntityAuthorizationValue("password");
4362be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
4372be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                         std::string(32, 0), policy_session->GetDelegate(),
4382be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                         &signature);
4392be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4402be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error signing using RSA key: " << GetErrorString(result);
4412be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4422be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4432be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->Verify(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
4446f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi                           std::string(32, 0), signature, nullptr);
4452be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4462be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error verifying using RSA key: " << GetErrorString(result);
4472be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4482be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4492be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string ciphertext;
4502be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->AsymmetricEncrypt(scoped_key.get(), TPM_ALG_NULL,
4512be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                      TPM_ALG_NULL, "plaintext",
4526ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                      nullptr,
4532be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                      &ciphertext);
4542be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4552be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error encrypting using RSA key: " << GetErrorString(result);
4562be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4572be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4582be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = policy_session->PolicyAuthValue();
4592be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4602be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy to auth value knowledge: "
4612be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi               << GetErrorString(result);
4622be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4632be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4642be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string plaintext;
4652be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  policy_session->SetEntityAuthorizationValue("password");
4662be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->AsymmetricDecrypt(scoped_key.get(), TPM_ALG_NULL,
4672be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                      TPM_ALG_NULL, ciphertext,
4682be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                      policy_session->GetDelegate(),
4692be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                      &plaintext);
4702be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4712be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error encrypting using RSA key: " << GetErrorString(result);
4722be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4732be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
474e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  if (plaintext.compare("plaintext") != 0) {
475e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi    LOG(ERROR) << "Plaintext changed after encrypt + decrypt.";
476e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi    return false;
477e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  }
478e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  return true;
479e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi}
480e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi
4816ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghibool TrunksClientTest::PolicyAndTest() {
482e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
4836ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<PolicySession> trial_session = factory_->GetTrialSession();
4846ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  TPM_RC result;
4856ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->StartUnboundSession(true);
486e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4876ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
4886ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
4896ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
4906ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->PolicyCommandCode(TPM_CC_Sign);
4916ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4926ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
493e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi    return false;
494e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  }
495e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  uint32_t pcr_index = 2;
4966ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string pcr_value;
4976ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->ReadPCR(pcr_index, &pcr_value);
498e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4996ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error reading pcr: " << GetErrorString(result);
500e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi    return false;
501e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  }
5026ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string pcr_extend_data("extend");
5036ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string next_pcr_value;
5046ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string hashed_extend_data = crypto::SHA256HashString(pcr_extend_data);
5056ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  next_pcr_value = crypto::SHA256HashString(pcr_value + hashed_extend_data);
5066ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
5076ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->PolicyPCR(pcr_index, next_pcr_value);
508e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5096ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
510e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi    return false;
511e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  }
5126ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string policy_digest;
5136ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->GetDigest(&policy_digest);
514e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5156ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
516e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi    return false;
517e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  }
5186ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Now that we have the digest, we can close the trial session and use hmac.
5196ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  trial_session.reset();
5206ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
5216ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<HmacSession> hmac_session = factory_->GetHmacSession();
5226ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = hmac_session->StartUnboundSession(true);
5236ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5246ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
5256ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5266ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5276ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string key_authorization("password");
5286ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string key_blob;
5296ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // This key is created with a policy that dictates it can only be used
5306ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // when pcr 2 remains unchanged, and when the command is TPM2_Sign.
5316ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->CreateRSAKeyPair(
5326ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001,
5336ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      key_authorization, policy_digest, true,  // use_only_policy_authorization
5340ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi      kNoCreationPCR, hmac_session->GetDelegate(), &key_blob, nullptr);
5356ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5366ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result);
5376ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5386ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5396ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  TPM_HANDLE key_handle;
5406ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->LoadKey(key_blob, hmac_session->GetDelegate(), &key_handle);
5416ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5426ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result);
5436ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5446ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5456ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  ScopedKeyHandle scoped_key(*factory_.get(), key_handle);
5466ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
5476ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Now we can reset the hmac_session.
5486ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  hmac_session.reset();
5496ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
5506ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<PolicySession> policy_session = factory_->GetPolicySession();
5516ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->StartUnboundSession(false);
5526ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5536ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
5546ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5556ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5566ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyCommandCode(TPM_CC_Sign);
5576ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5586ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
5596ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5606ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5616ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyPCR(pcr_index, "");
5626ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5636ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
5646ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5656ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5666ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string signature;
5676ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  policy_session->SetEntityAuthorizationValue(key_authorization);
5686ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Signing with this key when pcr 2 is unchanged fails.
5696ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
5706ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                         std::string(32, 'a'), policy_session->GetDelegate(),
5716ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                         &signature);
5726ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (GetFormatOneError(result) != TPM_RC_POLICY_FAIL) {
5736ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error using key to sign: " << GetErrorString(result);
5746ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5756ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5766ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<AuthorizationDelegate> delegate =
5776ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      factory_->GetPasswordAuthorization("");
5786ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->ExtendPCR(pcr_index, pcr_extend_data, delegate.get());
5796ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5806ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error extending pcr: " << GetErrorString(result);
5816ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5826ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5836ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // we have to restart the session because we changed the pcr values.
5846ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->StartUnboundSession(false);
5856ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5866ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
5876ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5886ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5896ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyCommandCode(TPM_CC_Sign);
5906ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5916ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
5926ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5936ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5946ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyPCR(pcr_index, "");
5956ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5966ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
5976ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5986ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5996ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  policy_session->SetEntityAuthorizationValue(key_authorization);
6006ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Signing with this key when pcr 2 is changed succeeds.
6016ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
6026ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                         std::string(32, 'a'), policy_session->GetDelegate(),
6036ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                         &signature);
6046ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6056ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error using key to sign: " << GetErrorString(result);
6066ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6076ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6086ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->Verify(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
6096ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                           std::string(32, 'a'), signature, nullptr);
6106ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6116ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error using key to verify: " << GetErrorString(result);
6126ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6136ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6146ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string ciphertext;
6156ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->AsymmetricEncrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL,
6166ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                      "plaintext", nullptr, &ciphertext);
6176ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6186ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error using key to encrypt: " << GetErrorString(result);
6196ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6206ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6216ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyCommandCode(TPM_CC_Sign);
6226ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6236ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
6246ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6256ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6266ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyPCR(pcr_index, "");
6276ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6286ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
6296ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6306ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6316ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string plaintext;
6326ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  policy_session->SetEntityAuthorizationValue(key_authorization);
6336ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // This call is not authorized with the policy, because its command code
6346ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // is not TPM_CC_SIGN. It should fail with TPM_RC_POLICY_CC.
6356ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->AsymmetricDecrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL,
6366ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                      ciphertext, policy_session->GetDelegate(),
6376ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                      &plaintext);
6386ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (GetFormatOneError(result) != TPM_RC_POLICY_CC) {
6396ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error: " << GetErrorString(result);
6406ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6416ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6426ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  return true;
6436ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi}
6446ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
6456ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghibool TrunksClientTest::PolicyOrTest() {
6466ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
6476ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<PolicySession> trial_session = factory_->GetTrialSession();
6486ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  TPM_RC result;
6496ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Specify a policy that asserts either TPM_CC_RSA_Encrypt or
6506ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // TPM_CC_RSA_Decrypt. A key created under this policy can only be used
6516ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // to encrypt or decrypt.
6526ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->StartUnboundSession(true);
6536ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6546ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
6556ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6566ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6576ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->PolicyCommandCode(TPM_CC_Sign);
6586ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6596ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
6606ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6616ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6626ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string sign_digest;
6636ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->GetDigest(&sign_digest);
6646ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6656ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
6666ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6676ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6686ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->StartUnboundSession(true);
6696ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6706ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
6716ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6726ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6736ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->PolicyCommandCode(TPM_CC_RSA_Decrypt);
6746ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6756ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
6766ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6776ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6786ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string decrypt_digest;
6796ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->GetDigest(&decrypt_digest);
6806ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6816ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
6826ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6836ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6846ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::vector<std::string> digests;
6856ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  digests.push_back(sign_digest);
6866ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  digests.push_back(decrypt_digest);
6876ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->PolicyOR(digests);
6886ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6896ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
6906ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6916ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6926ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string policy_digest;
6936ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->GetDigest(&policy_digest);
6946ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6956ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
6966ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6976ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6986ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Now that we have the digest, we can close the trial session and use hmac.
6996ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  trial_session.reset();
7006ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
7016ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<HmacSession> hmac_session = factory_->GetHmacSession();
7026ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = hmac_session->StartUnboundSession(true);
7036ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7046ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
7056ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7066ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7076ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string key_authorization("password");
7086ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string key_blob;
7096ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // This key is created with a policy that specifies that it can only be used
7106ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // for encrypt and decrypt operations.
7116ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->CreateRSAKeyPair(
7126ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001,
7136ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      key_authorization, policy_digest, true,  // use_only_policy_authorization
7140ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi      kNoCreationPCR, hmac_session->GetDelegate(), &key_blob, nullptr);
7156ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7166ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result);
7176ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7186ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7196ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  TPM_HANDLE key_handle;
7206ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->LoadKey(key_blob, hmac_session->GetDelegate(), &key_handle);
7216ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7226ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result);
7236ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7246ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7256ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  ScopedKeyHandle scoped_key(*factory_.get(), key_handle);
7266ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
7276ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Now we can reset the hmac_session.
7286ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  hmac_session.reset();
7296ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
7306ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<PolicySession> policy_session = factory_->GetPolicySession();
7316ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->StartUnboundSession(false);
7326ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7336ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
7346ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7356ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7366ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string ciphertext;
7376ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->AsymmetricEncrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL,
7386ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                      "plaintext", nullptr, &ciphertext);
7396ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7406ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error using key to encrypt: " << GetErrorString(result);
7416ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7426ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7436ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyCommandCode(TPM_CC_RSA_Decrypt);
7446ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7456ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
7466ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7476ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7486ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyOR(digests);
7496ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7506ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
7516ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7526ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7536ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string plaintext;
7546ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  policy_session->SetEntityAuthorizationValue(key_authorization);
7556ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // We can freely use the key for decryption.
7566ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->AsymmetricDecrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL,
7576ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                      ciphertext, policy_session->GetDelegate(),
7586ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                      &plaintext);
7596ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7606ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error using key to decrypt: " << GetErrorString(result);
7616ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7626ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7636ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (plaintext.compare("plaintext") != 0) {
7646ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Plaintext changed after encrypt + decrypt.";
7656ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7666ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7676ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyCommandCode(TPM_CC_Sign);
7686ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7696ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
7706ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7716ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7726ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyOR(digests);
7736ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7746ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
7756ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7766ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7776ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string signature;
7786ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  policy_session->SetEntityAuthorizationValue(key_authorization);
7796ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // However signing with a key only authorized for encrypt/decrypt should
7806ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // fail with TPM_RC_POLICY_CC.
7816ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
7826ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                         std::string(32, 'a'), policy_session->GetDelegate(),
7836ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                         &signature);
7846ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7856ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error using key to sign: " << GetErrorString(result);
786e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi    return false;
787e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  }
7882be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  return true;
7892be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
7902be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
7912be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::NvramTest(const std::string& owner_password) {
7922be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
7932be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
7942be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  TPM_RC result = session->StartUnboundSession(true /* enable encryption */);
7952be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7962be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
7972be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
7982be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
7992be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  uint32_t index = 1;
8002be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue(owner_password);
8012be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string nv_data("nv_data");
8022be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->DefineNVSpace(index, nv_data.size(),
8032be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                  session->GetDelegate());
8042be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
8052be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error defining nvram: " << GetErrorString(result);
8062be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8072be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8082be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue(owner_password);
8092be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->WriteNVSpace(index, 0, nv_data, session->GetDelegate());
8102be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
8112be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error writing nvram: " << GetErrorString(result);
8122be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8132be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8142be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string new_nvdata;
8152be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue("");
8162be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->ReadNVSpace(index, 0, nv_data.size(),
8172be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                            &new_nvdata, session->GetDelegate());
8182be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
8192be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error reading nvram: " << GetErrorString(result);
8202be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8212be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8222be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (nv_data.compare(new_nvdata) != 0) {
8232be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "NV space had different data than was written.";
8242be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8252be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8262be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->LockNVSpace(index, session->GetDelegate());
8272be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
8282be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error locking nvram: " << GetErrorString(result);
8292be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8302be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8312be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->ReadNVSpace(index, 0, nv_data.size(),
8322be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                            &new_nvdata, session->GetDelegate());
8332be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
8342be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error reading nvram: " << GetErrorString(result);
8352be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8362be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8372be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (nv_data.compare(new_nvdata) != 0) {
8382be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "NV space had different data than was written.";
8392be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8402be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8412be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue(owner_password);
8422be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->WriteNVSpace(index, 0, nv_data, session->GetDelegate());
8432be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result == TPM_RC_SUCCESS) {
8442be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Wrote nvram after locking: " << GetErrorString(result);
8452be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8462be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8472be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue(owner_password);
8482be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->DestroyNVSpace(index, session->GetDelegate());
8492be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
8502be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error destroying nvram: " << GetErrorString(result);
8512be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8522be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8532be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  return true;
8542be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
8552be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
8564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool TrunksClientTest::ManyKeysTest() {
8574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  const size_t kNumKeys = 20;
8584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<std::unique_ptr<ScopedKeyHandle>> key_handles;
8594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::map<TPM_HANDLE, std::string> public_key_map;
8604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (size_t i = 0; i < kNumKeys; ++i) {
8614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::unique_ptr<ScopedKeyHandle> key_handle(new ScopedKeyHandle(*factory_));
8624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string public_key;
8634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    if (!LoadSigningKey(key_handle.get(), &public_key)) {
8644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      LOG(ERROR) << "Error loading key " << i << " into TPM.";
8654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
8664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    public_key_map[key_handle->get()] = public_key;
8674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    key_handles.push_back(std::move(key_handle));
8684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
8694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  CHECK_EQ(key_handles.size(), kNumKeys);
8704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  CHECK_EQ(public_key_map.size(), kNumKeys);
8714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  scoped_ptr<AuthorizationDelegate> delegate =
8724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      factory_->GetPasswordAuthorization("");
8734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (size_t i = 0; i < kNumKeys; ++i) {
8744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    const ScopedKeyHandle& key_handle = *key_handles[i];
8754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    const std::string& public_key = public_key_map[key_handle.get()];
8764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    if (!SignAndVerify(key_handle, public_key, delegate.get())) {
8774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      LOG(ERROR) << "Error signing with key " << i;
8784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
8794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
8804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::random_shuffle(key_handles.begin(), key_handles.end());
8814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (size_t i = 0; i < kNumKeys; ++i) {
8824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    const ScopedKeyHandle& key_handle = *key_handles[i];
8834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    const std::string& public_key = public_key_map[key_handle.get()];
8844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    if (!SignAndVerify(key_handle, public_key, delegate.get())) {
8854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      LOG(ERROR) << "Error signing with shuffled key " << i;
8864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
8874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
8884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  return true;
8894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
8904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
8914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool TrunksClientTest::ManySessionsTest() {
8924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  const size_t kNumSessions = 20;
8934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
8944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<std::unique_ptr<HmacSession>> sessions;
8954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (size_t i = 0; i < kNumSessions; ++i) {
8964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::unique_ptr<HmacSession> session(factory_->GetHmacSession().release());
8974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    TPM_RC result = session->StartUnboundSession(true /* enable encryption */);
8984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    if (result != TPM_RC_SUCCESS) {
8994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      LOG(ERROR) << "Error starting hmac session " << i << ": "
9004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                 << GetErrorString(result);
9014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      return false;
9024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
9034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    sessions.push_back(std::move(session));
9044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
9054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  CHECK_EQ(sessions.size(), kNumSessions);
9064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  ScopedKeyHandle key_handle(*factory_);
9074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string public_key;
9084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  if (!LoadSigningKey(&key_handle, &public_key)) {
9094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return false;
9104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
9114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (size_t i = 0; i < kNumSessions; ++i) {
9124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    if (!SignAndVerify(key_handle, public_key, sessions[i]->GetDelegate())) {
9134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      LOG(ERROR) << "Error signing with hmac session " << i;
9144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
9154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
9164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::random_shuffle(sessions.begin(), sessions.end());
9174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (size_t i = 0; i < kNumSessions; ++i) {
9184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    if (!SignAndVerify(key_handle, public_key, sessions[i]->GetDelegate())) {
9194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      LOG(ERROR) << "Error signing with shuffled hmac session " << i;
9204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
9214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
9224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  return true;
9234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
9244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
9252be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::PerformRSAEncrpytAndDecrpyt(
9262be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    TPM_HANDLE key_handle,
9272be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    const std::string& key_authorization,
9282be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    HmacSession* session) {
9292be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
9302be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string ciphertext;
9312be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue("");
9322be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  TPM_RC result = utility->AsymmetricEncrypt(key_handle, TPM_ALG_NULL,
9332be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                             TPM_ALG_NULL, "plaintext",
9342be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                             session->GetDelegate(),
9352be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                             &ciphertext);
9362be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
9372be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error using key to encrypt: " << GetErrorString(result);
9382be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
9392be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
9402be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string plaintext;
9412be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue(key_authorization);
9422be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->AsymmetricDecrypt(key_handle, TPM_ALG_NULL,
9432be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                      TPM_ALG_NULL, ciphertext,
9442be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                      session->GetDelegate(), &plaintext);
9452be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
9462be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error using key to decrypt: " << GetErrorString(result);
9472be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
9482be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
9492be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (plaintext.compare("plaintext") != 0) {
9502be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Plaintext changed after encrypt + decrypt.";
9512be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
9522be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
9532be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  return true;
9542be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
9552be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
9564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnvoid TrunksClientTest::GenerateRSAKeyPair(std::string* modulus,
9574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          std::string* prime_factor,
9584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          std::string* public_key) {
9594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  crypto::ScopedRSA rsa(RSA_generate_key(2048, 0x10001, nullptr, nullptr));
9604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  CHECK(rsa.get());
9614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  modulus->resize(BN_num_bytes(rsa.get()->n), 0);
9624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  BN_bn2bin(rsa.get()->n,
9634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn            reinterpret_cast<unsigned char*>(string_as_array(modulus)));
9644ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  prime_factor->resize(BN_num_bytes(rsa.get()->p), 0);
9654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  BN_bn2bin(rsa.get()->p,
9664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn            reinterpret_cast<unsigned char*>(string_as_array(prime_factor)));
9674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  if (public_key) {
9684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    unsigned char* buffer = NULL;
9694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    int length = i2d_RSAPublicKey(rsa.get(), &buffer);
9704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    CHECK_GT(length, 0);
9714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    crypto::ScopedOpenSSLBytes scoped_buffer(buffer);
9724ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    public_key->assign(reinterpret_cast<char*>(buffer), length);
9734ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
9744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
9754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
9764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool TrunksClientTest::VerifyRSASignature(const std::string& public_key,
9774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          const std::string& data,
9784ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          const std::string& signature) {
9794ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  auto asn1_ptr = reinterpret_cast<const unsigned char*>(public_key.data());
9804ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  crypto::ScopedRSA rsa(d2i_RSAPublicKey(nullptr, &asn1_ptr,
9814ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                         public_key.size()));
9824ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  CHECK(rsa.get());
9834ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string digest = crypto::SHA256HashString(data);
9844ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  auto digest_buffer = reinterpret_cast<const unsigned char*>(digest.data());
9854ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string mutable_signature(signature);
9864ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  unsigned char* signature_buffer =
9874ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      reinterpret_cast<unsigned char*>(string_as_array(&mutable_signature));
9884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  return (RSA_verify(NID_sha256, digest_buffer, digest.size(),
9894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                     signature_buffer, signature.size(), rsa.get()) == 1);
9904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
9914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
9924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool TrunksClientTest::LoadSigningKey(ScopedKeyHandle* key_handle,
9934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      std::string* public_key) {
9944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string modulus;
9954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string prime_factor;
9964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  GenerateRSAKeyPair(&modulus, &prime_factor, public_key);
9974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string key_blob;
9986ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
9994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_RC result = utility->ImportRSAKey(
10004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      TpmUtility::AsymmetricKeyUsage::kSignKey,
10014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      modulus, 0x10001, prime_factor,
10024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      "",  // password
10034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      factory_->GetPasswordAuthorization("").get(),
10044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      &key_blob);
10054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  if (result != TPM_RC_SUCCESS) {
10064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    LOG(ERROR) << "ImportRSAKey: " << GetErrorString(result);
10074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return false;
10084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
10094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_HANDLE raw_key_handle;
10104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  result = utility->LoadKey(key_blob,
10114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                            factory_->GetPasswordAuthorization("").get(),
10124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                            &raw_key_handle);
10134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  if (result != TPM_RC_SUCCESS) {
10144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    LOG(ERROR) << "LoadKey: " << GetErrorString(result);
10154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return false;
10164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
10174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  key_handle->reset(raw_key_handle);
10184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  return true;
10194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
10204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
10214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool TrunksClientTest::SignAndVerify(const ScopedKeyHandle& key_handle,
10224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                     const std::string& public_key,
10234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                     AuthorizationDelegate* delegate) {
10246ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string signature;
10254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string data_to_sign("sign_this");
10264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
10274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_RC result = utility->Sign(key_handle.get(),
10284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                TPM_ALG_RSASSA,
10294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                TPM_ALG_SHA256,
10304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                data_to_sign,
10314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                delegate,
10326ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                &signature);
10336ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
10344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    LOG(ERROR) << "Sign: " << GetErrorString(result);
10356ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
10366ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
10374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  if (!VerifyRSASignature(public_key, data_to_sign, signature)) {
10384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    LOG(ERROR) << "Signature verification failed.";
10396ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
10406ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
10416ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  return true;
10426ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi}
10436ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
10442be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}  // namespace trunks
1045