1bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//
2bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Copyright (C) 2015 The Android Open Source Project
3bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//
4bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Licensed under the Apache License, Version 2.0 (the "License");
5bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// you may not use this file except in compliance with the License.
6bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// You may obtain a copy of the License at
7bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//
8bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//      http://www.apache.org/licenses/LICENSE-2.0
9bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//
10bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Unless required by applicable law or agreed to in writing, software
11bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// distributed under the License is distributed on an "AS IS" BASIS,
12bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// See the License for the specific language governing permissions and
14bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// limitations under the License.
15bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi//
162be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
172be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/trunks_client_test.h"
182be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <algorithm>
204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <map>
214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <memory>
224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <string>
234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <vector>
244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
252be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include <base/logging.h>
262be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include <base/stl_util.h>
27ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn#include <crypto/openssl_util.h>
282be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include <crypto/scoped_openssl_types.h>
29e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi#include <crypto/sha2.h>
302be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include <openssl/bn.h>
316ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi#include <openssl/err.h>
322be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include <openssl/rsa.h>
332be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include "trunks/authorization_delegate.h"
352be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/error_codes.h"
362be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/hmac_session.h"
372be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/policy_session.h"
382be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/scoped_key_handle.h"
392be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/tpm_generated.h"
402be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/tpm_state.h"
412be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/tpm_utility.h"
422be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/trunks_factory_impl.h"
432be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
44ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahnnamespace {
45ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn
46ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahnstd::string GetOpenSSLError() {
47ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn  BIO* bio = BIO_new(BIO_s_mem());
48ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn  ERR_print_errors(bio);
49ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn  char* data = nullptr;
50ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn  int data_len = BIO_get_mem_data(bio, &data);
51ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn  std::string error_string(data, data_len);
52ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn  BIO_free(bio);
53ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn  return error_string;
54ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn}
55ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn
56ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn}  // namespace
57ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn
582be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghinamespace trunks {
592be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
609caf492818a4cc51ba471534d3fcaa84c9ce0278Darren KrahnTrunksClientTest::TrunksClientTest()
619caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn    : factory_(new TrunksFactoryImpl(true /* failure_is_fatal */)) {
62ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn  crypto::EnsureOpenSSLInit();
63ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn}
642be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
652be346182387c502f65c65ea4da49707026ce8f9Utkarsh SanghiTrunksClientTest::TrunksClientTest(scoped_ptr<TrunksFactory> factory)
667e763a9434e12c7980529980de5f8eced22b310aAlex Vakulenko    : factory_(std::move(factory)) {}
672be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
682be346182387c502f65c65ea4da49707026ce8f9Utkarsh SanghiTrunksClientTest::~TrunksClientTest() {}
692be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
702be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::RNGTest() {
712be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
722be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
73a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
74a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session.";
75a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
76a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
772be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string entropy_data("entropy_data");
782be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string random_data;
792be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  size_t num_bytes = 70;
80a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->StirRandom(entropy_data, session->GetDelegate());
812be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
822be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error stirring TPM RNG: " << GetErrorString(result);
832be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
842be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
852be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->GenerateRandom(num_bytes, session->GetDelegate(),
862be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                   &random_data);
872be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
882be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error getting random bytes from TPM: "
892be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi               << GetErrorString(result);
902be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
912be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
922be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (num_bytes != random_data.size()) {
932be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error not enough random bytes received.";
942be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
952be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
962be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  return true;
972be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
982be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
992be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::SignTest() {
1002be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
1012be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
102a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
103a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session.";
1042be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
1052be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
1062be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string key_authorization("sign");
1076f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  std::string key_blob;
108a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->CreateRSAKeyPair(
109a5a2f2ea49e0085bf8d7f6f2b6e7cd624d710c01Utkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kSignKey, 2048, 0x10001,
110a5a2f2ea49e0085bf8d7f6f2b6e7cd624d710c01Utkarsh Sanghi      key_authorization, "", false,  // use_only_policy_authorization
1110ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi      kNoCreationPCR, session->GetDelegate(), &key_blob, nullptr);
1122be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
1132be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error creating signing key: " << GetErrorString(result);
1142be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
1152be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
1166f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  TPM_HANDLE signing_key;
1176f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  result = utility->LoadKey(key_blob, session->GetDelegate(), &signing_key);
1186f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
1196f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi    LOG(ERROR) << "Error loading signing key: " << GetErrorString(result);
1206f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  }
1212be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  ScopedKeyHandle scoped_key(*factory_.get(), signing_key);
1224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  session->SetEntityAuthorizationValue(key_authorization);
1234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string signature;
1244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  result = utility->Sign(signing_key, TPM_ALG_NULL, TPM_ALG_NULL,
1254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                         std::string(32, 'a'), session->GetDelegate(),
1264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                         &signature);
1274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  if (result != TPM_RC_SUCCESS) {
1284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    LOG(ERROR) << "Error using key to sign: " << GetErrorString(result);
1294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return false;
1304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
1314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  result = utility->Verify(signing_key, TPM_ALG_NULL, TPM_ALG_NULL,
1324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                           std::string(32, 'a'), signature, nullptr);
1334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  if (result != TPM_RC_SUCCESS) {
1344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    LOG(ERROR) << "Error using key to verify: " << GetErrorString(result);
1354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return false;
1364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
1374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  return true;
1382be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
1392be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
1402be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::DecryptTest() {
1412be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
1422be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
143a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
144a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session.";
1452be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
1462be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
1472be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string key_authorization("decrypt");
1486f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  std::string key_blob;
149a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->CreateRSAKeyPair(
1506f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001,
1516ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      key_authorization, "", false,  // use_only_policy_authorization
1520ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi      kNoCreationPCR, session->GetDelegate(), &key_blob, nullptr);
1532be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
1546f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi    LOG(ERROR) << "Error creating decrypt key: " << GetErrorString(result);
1552be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
1562be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
1576f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  TPM_HANDLE decrypt_key;
1586f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  result = utility->LoadKey(key_blob, session->GetDelegate(), &decrypt_key);
1596f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
1606f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi    LOG(ERROR) << "Error loading decrypt key: " << GetErrorString(result);
1616f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  }
1622be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  ScopedKeyHandle scoped_key(*factory_.get(), decrypt_key);
1632be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  return PerformRSAEncrpytAndDecrpyt(scoped_key.get(),
1642be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                     key_authorization,
1652be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                     session.get());
1662be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
1672be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
1682be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::ImportTest() {
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  }
1754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string modulus;
1764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string prime_factor;
1774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  GenerateRSAKeyPair(&modulus, &prime_factor, nullptr);
1782be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string key_blob;
1792be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string key_authorization("import");
180a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->ImportRSAKey(
1812be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, modulus, 0x10001,
1822be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi      prime_factor, key_authorization, session->GetDelegate(), &key_blob);
1832be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
1842be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error importing key into TPM: " << GetErrorString(result);
1852be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
1862be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
1872be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  TPM_HANDLE key_handle;
1882be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle);
1892be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
1902be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error loading key into TPM: " << GetErrorString(result);
1912be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
1922be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
1932be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  ScopedKeyHandle scoped_key(*factory_.get(), key_handle);
1942be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  return PerformRSAEncrpytAndDecrpyt(scoped_key.get(), key_authorization,
1952be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                     session.get());
1962be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
1972be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
1982be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::AuthChangeTest() {
1992be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
2002be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
201a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
202a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session.";
2032be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
2042be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
2052be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string key_authorization("new_pass");
2066f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  std::string key_blob;
207a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->CreateRSAKeyPair(
2086f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001,
2096ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      "old_pass", "", false,  // use_only_policy_authorization
2100ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi      kNoCreationPCR, session->GetDelegate(), &key_blob, nullptr);
2112be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
2126f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi    LOG(ERROR) << "Error creating change auth key: " << GetErrorString(result);
2132be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
2142be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
2156f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  TPM_HANDLE key_handle;
2166f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle);
2176f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
2186f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi    LOG(ERROR) << "Error loading change auth key: " << GetErrorString(result);
2196f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi  }
2202be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  ScopedKeyHandle scoped_key(*factory_.get(), key_handle);
2212be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue("old_pass");
2222be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->ChangeKeyAuthorizationData(key_handle, key_authorization,
2232be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                               session->GetDelegate(),
2242be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                               &key_blob);
2252be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
2262be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error changing auth data: " << GetErrorString(result);
2272be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
2282be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
2292be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue("");
2302be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle);
2312be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
2322be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error reloading key: " << GetErrorString(result);
2332be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
2342be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
2352be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_key.reset(key_handle);
2362be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  return PerformRSAEncrpytAndDecrpyt(scoped_key.get(), key_authorization,
2372be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                     session.get());
2382be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
2392be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
240fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghibool TrunksClientTest::VerifyKeyCreationTest() {
241fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
242fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
243a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
244a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session.";
245fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    return false;
246fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  }
247fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  std::string key_blob;
248fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  std::string creation_blob;
249fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  session->SetEntityAuthorizationValue("");
250a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->CreateRSAKeyPair(
251fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001,
252fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi      "", "", false,  // use_only_policy_authorization
253fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi      kNoCreationPCR, session->GetDelegate(), &key_blob, &creation_blob);
254fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
255fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    LOG(ERROR) << "Error creating certify key: " << GetErrorString(result);
256fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    return false;
257fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  }
258fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  std::string alternate_key_blob;
259fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  result = utility->CreateRSAKeyPair(
260fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001,
261fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi      "", "", false,  // use_only_policy_authorization
262fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi      kNoCreationPCR, session->GetDelegate(), &alternate_key_blob,
263fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi      nullptr);
264fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
265fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    LOG(ERROR) << "Error creating alternate key: " << GetErrorString(result);
266fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    return false;
267fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  }
268fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  TPM_HANDLE key_handle;
269fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle);
270fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
271fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    LOG(ERROR) << "Error loading certify key: " << GetErrorString(result);
272fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    return false;
273fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  }
274fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  TPM_HANDLE alternate_key_handle;
275fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  result = utility->LoadKey(alternate_key_blob,
276fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi                            session->GetDelegate(),
277fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi                            &alternate_key_handle);
278fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
279fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    LOG(ERROR) << "Error loading alternate key: " << GetErrorString(result);
280fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    return false;
281fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  }
282fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  ScopedKeyHandle certify_key(*factory_.get(), key_handle);
283fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  ScopedKeyHandle alternate_key(*factory_.get(), alternate_key_handle);
284fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  result = utility->CertifyCreation(certify_key.get(), creation_blob);
285fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
286fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    LOG(ERROR) << "Error certifying key: " << GetErrorString(result);
287fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    return false;
288fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  }
289fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  result = utility->CertifyCreation(alternate_key.get(), creation_blob);
290fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  if (result == TPM_RC_SUCCESS) {
291fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    LOG(ERROR) << "Error alternate key certified with wrong creation data.";
292fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi    return false;
293fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  }
294fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi  return true;
295fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi}
296fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi
297a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghibool TrunksClientTest::SealedDataTest() {
2986ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
2996ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
300a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
301a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session.";
302a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
303a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
304a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  int pcr_index = 5;
305a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  std::string policy_digest;
306a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->GetPolicyDigestForPcrValue(pcr_index, "",
307a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi                                                      &policy_digest);
308a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
309a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error getting policy_digest: " << GetErrorString(result);
310a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
311a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
312a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  std::string data_to_seal("seal_data");
313a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  std::string sealed_data;
314a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  result = utility->SealData(data_to_seal, policy_digest,
315a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi                             session->GetDelegate(), &sealed_data);
316a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
317a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error creating Sealed Object: " << GetErrorString(result);
318a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
319a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
320a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  scoped_ptr<PolicySession> policy_session = factory_->GetPolicySession();
321a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  result = policy_session->StartUnboundSession(false);
3226ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
323a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
324a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
325a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
326a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  result = policy_session->PolicyPCR(pcr_index, "");
327a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
328a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy to pcr value: "
329a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi               << GetErrorString(result);
330a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
331a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
332a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  std::string unsealed_data;
333a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  result = utility->UnsealData(sealed_data, policy_session->GetDelegate(),
334a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi                               &unsealed_data);
335a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
336a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error unsealing object: " << GetErrorString(result);
337a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
338a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
339a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (data_to_seal != unsealed_data) {
340a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error unsealed data from TPM does not match original data.";
341a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
342a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
343a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  result = utility->ExtendPCR(pcr_index, "extend", session->GetDelegate());
344a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
345a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error extending pcr: " << GetErrorString(result);
346a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
347a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
348a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  result = policy_session->PolicyPCR(pcr_index, "");
349a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
350a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy to pcr value: "
351a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi               << GetErrorString(result);
352a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
353a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
354a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  result = utility->UnsealData(sealed_data, policy_session->GetDelegate(),
355a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi                               &unsealed_data);
356a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (result == TPM_RC_SUCCESS) {
357a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error object was unsealed with wrong policy_digest.";
358a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    return false;
359a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  }
360a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  return true;
361a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi}
362a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi
363a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghibool TrunksClientTest::PCRTest() {
364a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
365a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
366a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) {
367a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session.";
3686ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
3696ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
3706ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // We are using PCR 2 because it is currently not used by ChromeOS.
3716ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  uint32_t pcr_index = 2;
3726ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string extend_data("data");
3736ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string old_data;
374a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi  TPM_RC result = utility->ReadPCR(pcr_index, &old_data);
3756ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
3766ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error reading from PCR: " << GetErrorString(result);
3776ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
3786ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
3796ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->ExtendPCR(pcr_index, extend_data, session->GetDelegate());
3806ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
3816ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error extending PCR value: " << GetErrorString(result);
3826ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
3836ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
3846ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string pcr_data;
3856ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->ReadPCR(pcr_index, &pcr_data);
3866ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
3876ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error reading from PCR: " << GetErrorString(result);
3886ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
3896ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
3906ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string hashed_extend_data = crypto::SHA256HashString(extend_data);
3916ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string expected_pcr_data =
3926ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      crypto::SHA256HashString(old_data + hashed_extend_data);
3936ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (pcr_data.compare(expected_pcr_data) != 0) {
3946ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "PCR data does not match expected value.";
3956ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
3966ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
3976ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  return true;
3986ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi}
3992be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
4006ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghibool TrunksClientTest::PolicyAuthValueTest() {
4012be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
4026ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<PolicySession> trial_session = factory_->GetTrialSession();
4032be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  TPM_RC result;
4046ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->StartUnboundSession(true);
4052be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4062be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
4072be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4082be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4096ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->PolicyAuthValue();
4102be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4112be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy to auth value knowledge: "
4122be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi               << GetErrorString(result);
4132be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4142be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4156ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string policy_digest;
4166ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->GetDigest(&policy_digest);
4172be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4182be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
4192be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4202be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4216ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Now that we have the digest, we can close the trial session and use hmac.
4226ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  trial_session.reset();
4232be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
4242be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<HmacSession> hmac_session = factory_->GetHmacSession();
4256ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = hmac_session->StartUnboundSession(true);
4262be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4272be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
4282be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4292be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4302be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
4312be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string key_blob;
4322be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->CreateRSAKeyPair(
4336ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001,
4346ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      "password", policy_digest, true,  // use_only_policy_authorization
4350ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi      kNoCreationPCR, hmac_session->GetDelegate(), &key_blob, nullptr);
4362be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4372be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result);
4382be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4392be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4402be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
4412be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  TPM_HANDLE key_handle;
4422be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->LoadKey(key_blob, hmac_session->GetDelegate(), &key_handle);
4432be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4442be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result);
4452be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4462be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4472be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  ScopedKeyHandle scoped_key(*factory_.get(), key_handle);
4482be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
4492be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  // Now we can reset the hmac_session.
4502be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  hmac_session.reset();
4512be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
4526ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<PolicySession> policy_session = factory_->GetPolicySession();
4536ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->StartUnboundSession(false);
4542be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4552be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << 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 signature;
4652be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  policy_session->SetEntityAuthorizationValue("password");
4662be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
4672be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                         std::string(32, 0), policy_session->GetDelegate(),
4682be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                         &signature);
4692be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4702be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error signing using RSA key: " << GetErrorString(result);
4712be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4722be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4732be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->Verify(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
4746f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi                           std::string(32, 0), signature, nullptr);
4752be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4762be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error verifying using RSA key: " << GetErrorString(result);
4772be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4782be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4792be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string ciphertext;
4802be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->AsymmetricEncrypt(scoped_key.get(), TPM_ALG_NULL,
4812be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                      TPM_ALG_NULL, "plaintext",
4826ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                      nullptr,
4832be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                      &ciphertext);
4842be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4852be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error encrypting using RSA key: " << GetErrorString(result);
4862be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4872be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4882be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = policy_session->PolicyAuthValue();
4892be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
4902be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy to auth value knowledge: "
4912be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi               << GetErrorString(result);
4922be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
4932be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
4942be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string plaintext;
4952be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  policy_session->SetEntityAuthorizationValue("password");
4962be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->AsymmetricDecrypt(scoped_key.get(), TPM_ALG_NULL,
4972be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                      TPM_ALG_NULL, ciphertext,
4982be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                      policy_session->GetDelegate(),
4992be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                      &plaintext);
5002be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5012be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error encrypting using RSA key: " << GetErrorString(result);
5022be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
5032be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
504e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  if (plaintext.compare("plaintext") != 0) {
505e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi    LOG(ERROR) << "Plaintext changed after encrypt + decrypt.";
506e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi    return false;
507e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  }
508e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  return true;
509e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi}
510e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi
5116ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghibool TrunksClientTest::PolicyAndTest() {
512e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
5136ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<PolicySession> trial_session = factory_->GetTrialSession();
5146ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  TPM_RC result;
5156ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->StartUnboundSession(true);
516e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5176ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
5186ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5196ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5206ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->PolicyCommandCode(TPM_CC_Sign);
5216ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5226ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
523e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi    return false;
524e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  }
525e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  uint32_t pcr_index = 2;
5266ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string pcr_value;
5276ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->ReadPCR(pcr_index, &pcr_value);
528e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5296ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error reading pcr: " << GetErrorString(result);
530e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi    return false;
531e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  }
5326ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string pcr_extend_data("extend");
5336ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string next_pcr_value;
5346ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string hashed_extend_data = crypto::SHA256HashString(pcr_extend_data);
5356ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  next_pcr_value = crypto::SHA256HashString(pcr_value + hashed_extend_data);
5366ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
5376ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->PolicyPCR(pcr_index, next_pcr_value);
538e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5396ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
540e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi    return false;
541e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  }
5426ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string policy_digest;
5436ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->GetDigest(&policy_digest);
544e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5456ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
546e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi    return false;
547e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  }
5486ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Now that we have the digest, we can close the trial session and use hmac.
5496ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  trial_session.reset();
5506ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
5516ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<HmacSession> hmac_session = factory_->GetHmacSession();
5526ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = hmac_session->StartUnboundSession(true);
5536ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5546ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
5556ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5566ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5576ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string key_authorization("password");
5586ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string key_blob;
5596ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // This key is created with a policy that dictates it can only be used
5606ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // when pcr 2 remains unchanged, and when the command is TPM2_Sign.
5616ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->CreateRSAKeyPair(
5626ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001,
5636ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      key_authorization, policy_digest, true,  // use_only_policy_authorization
5640ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi      kNoCreationPCR, hmac_session->GetDelegate(), &key_blob, nullptr);
5656ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5666ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result);
5676ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5686ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5696ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  TPM_HANDLE key_handle;
5706ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->LoadKey(key_blob, hmac_session->GetDelegate(), &key_handle);
5716ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5726ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result);
5736ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5746ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5756ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  ScopedKeyHandle scoped_key(*factory_.get(), key_handle);
5766ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
5776ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Now we can reset the hmac_session.
5786ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  hmac_session.reset();
5796ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
5806ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<PolicySession> policy_session = factory_->GetPolicySession();
5816ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->StartUnboundSession(false);
5826ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5836ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
5846ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5856ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5866ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyCommandCode(TPM_CC_Sign);
5876ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5886ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
5896ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5906ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5916ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyPCR(pcr_index, "");
5926ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
5936ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
5946ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
5956ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
5966ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string signature;
5976ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  policy_session->SetEntityAuthorizationValue(key_authorization);
5986ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Signing with this key when pcr 2 is unchanged fails.
5996ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
6006ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                         std::string(32, 'a'), policy_session->GetDelegate(),
6016ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                         &signature);
6026ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (GetFormatOneError(result) != TPM_RC_POLICY_FAIL) {
6036ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error using key to sign: " << GetErrorString(result);
6046ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6056ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6066ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<AuthorizationDelegate> delegate =
6076ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      factory_->GetPasswordAuthorization("");
6086ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->ExtendPCR(pcr_index, pcr_extend_data, delegate.get());
6096ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6106ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error extending pcr: " << GetErrorString(result);
6116ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6126ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6136ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // we have to restart the session because we changed the pcr values.
6146ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->StartUnboundSession(false);
6156ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6166ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
6176ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6186ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6196ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyCommandCode(TPM_CC_Sign);
6206ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6216ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
6226ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6236ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6246ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyPCR(pcr_index, "");
6256ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6266ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
6276ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6286ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6296ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  policy_session->SetEntityAuthorizationValue(key_authorization);
6306ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Signing with this key when pcr 2 is changed succeeds.
6316ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
6326ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                         std::string(32, 'a'), policy_session->GetDelegate(),
6336ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                         &signature);
6346ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6356ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error using key to sign: " << GetErrorString(result);
6366ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6376ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6386ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->Verify(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
6396ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                           std::string(32, 'a'), signature, nullptr);
6406ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6416ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error using key to verify: " << GetErrorString(result);
6426ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6436ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6446ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string ciphertext;
6456ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->AsymmetricEncrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL,
6466ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                      "plaintext", nullptr, &ciphertext);
6476ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6486ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error using key to encrypt: " << GetErrorString(result);
6496ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6506ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6516ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyCommandCode(TPM_CC_Sign);
6526ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6536ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
6546ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6556ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6566ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyPCR(pcr_index, "");
6576ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6586ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
6596ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6606ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6616ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string plaintext;
6626ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  policy_session->SetEntityAuthorizationValue(key_authorization);
6636ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // This call is not authorized with the policy, because its command code
6646ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // is not TPM_CC_SIGN. It should fail with TPM_RC_POLICY_CC.
6656ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->AsymmetricDecrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL,
6666ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                      ciphertext, policy_session->GetDelegate(),
6676ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                      &plaintext);
6686ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (GetFormatOneError(result) != TPM_RC_POLICY_CC) {
6696ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error: " << GetErrorString(result);
6706ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6716ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6726ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  return true;
6736ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi}
6746ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
6756ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghibool TrunksClientTest::PolicyOrTest() {
6766ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
6776ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<PolicySession> trial_session = factory_->GetTrialSession();
6786ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  TPM_RC result;
6796ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Specify a policy that asserts either TPM_CC_RSA_Encrypt or
6806ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // TPM_CC_RSA_Decrypt. A key created under this policy can only be used
6816ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // to encrypt or decrypt.
6826ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->StartUnboundSession(true);
6836ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
6846ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
6856ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
6866ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
6876ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->PolicyCommandCode(TPM_CC_Sign);
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 sign_digest;
6936ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->GetDigest(&sign_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  result = trial_session->StartUnboundSession(true);
6996ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7006ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
7016ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7026ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7036ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->PolicyCommandCode(TPM_CC_RSA_Decrypt);
7046ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7056ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
7066ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7076ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7086ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string decrypt_digest;
7096ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->GetDigest(&decrypt_digest);
7106ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7116ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
7126ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7136ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7146ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::vector<std::string> digests;
7156ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  digests.push_back(sign_digest);
7166ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  digests.push_back(decrypt_digest);
7176ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->PolicyOR(digests);
7186ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7196ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
7206ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7216ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7226ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string policy_digest;
7236ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = trial_session->GetDigest(&policy_digest);
7246ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7256ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
7266ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7276ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7286ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Now that we have the digest, we can close the trial session and use hmac.
7296ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  trial_session.reset();
7306ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
7316ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<HmacSession> hmac_session = factory_->GetHmacSession();
7326ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = hmac_session->StartUnboundSession(true);
7336ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7346ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
7356ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7366ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7376ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string key_authorization("password");
7386ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string key_blob;
7396ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // This key is created with a policy that specifies that it can only be used
7406ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // for encrypt and decrypt operations.
7416ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->CreateRSAKeyPair(
7426ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001,
7436ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi      key_authorization, policy_digest, true,  // use_only_policy_authorization
7440ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi      kNoCreationPCR, hmac_session->GetDelegate(), &key_blob, nullptr);
7456ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7466ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result);
7476ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7486ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7496ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  TPM_HANDLE key_handle;
7506ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->LoadKey(key_blob, hmac_session->GetDelegate(), &key_handle);
7516ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7526ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result);
7536ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7546ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7556ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  ScopedKeyHandle scoped_key(*factory_.get(), key_handle);
7566ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
7576ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // Now we can reset the hmac_session.
7586ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  hmac_session.reset();
7596ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
7606ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<PolicySession> policy_session = factory_->GetPolicySession();
7616ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->StartUnboundSession(false);
7626ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7636ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error starting policy session: " << GetErrorString(result);
7646ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7656ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7666ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string ciphertext;
7676ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->AsymmetricEncrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL,
7686ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                      "plaintext", nullptr, &ciphertext);
7696ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7706ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error using key to encrypt: " << GetErrorString(result);
7716ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7726ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7736ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyCommandCode(TPM_CC_RSA_Decrypt);
7746ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7756ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
7766ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7776ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7786ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyOR(digests);
7796ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7806ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
7816ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7826ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7836ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string plaintext;
7846ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  policy_session->SetEntityAuthorizationValue(key_authorization);
7856ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // We can freely use the key for decryption.
7866ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->AsymmetricDecrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL,
7876ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                      ciphertext, policy_session->GetDelegate(),
7886ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                      &plaintext);
7896ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7906ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error using key to decrypt: " << GetErrorString(result);
7916ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7926ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7936ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (plaintext.compare("plaintext") != 0) {
7946ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Plaintext changed after encrypt + decrypt.";
7956ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
7966ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
7976ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyCommandCode(TPM_CC_Sign);
7986ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
7996ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
8006ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
8016ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
8026ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = policy_session->PolicyOR(digests);
8036ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
8046ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error restricting policy: " << GetErrorString(result);
8056ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
8066ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
8076ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string signature;
8086ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  policy_session->SetEntityAuthorizationValue(key_authorization);
8096ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // However signing with a key only authorized for encrypt/decrypt should
8106ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  // fail with TPM_RC_POLICY_CC.
8116ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL,
8126ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                         std::string(32, 'a'), policy_session->GetDelegate(),
8136ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                         &signature);
8146ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
8156ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    LOG(ERROR) << "Error using key to sign: " << GetErrorString(result);
816e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi    return false;
817e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi  }
8182be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  return true;
8192be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
8202be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
8212be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::NvramTest(const std::string& owner_password) {
8222be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
8232be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<HmacSession> session = factory_->GetHmacSession();
8242be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  TPM_RC result = session->StartUnboundSession(true /* enable encryption */);
8252be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
8262be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result);
8272be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8282be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8292be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  uint32_t index = 1;
8302be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue(owner_password);
8312be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string nv_data("nv_data");
8322be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->DefineNVSpace(index, nv_data.size(),
8332be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                  session->GetDelegate());
8342be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
8352be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error defining nvram: " << GetErrorString(result);
8362be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8372be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8382be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue(owner_password);
8392be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->WriteNVSpace(index, 0, nv_data, session->GetDelegate());
8402be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
8412be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error writing nvram: " << GetErrorString(result);
8422be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8432be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8442be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string new_nvdata;
8452be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue("");
8462be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->ReadNVSpace(index, 0, nv_data.size(),
847707e3e1ac5185eac0c992fb6fbcae574fde9c4bbUtkarsh Sanghi                                &new_nvdata, session->GetDelegate());
8482be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
8492be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error reading nvram: " << GetErrorString(result);
8502be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8512be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8522be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (nv_data.compare(new_nvdata) != 0) {
8532be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "NV space had different data than was written.";
8542be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8552be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
85638e6ef38e5ee4c7f735366a26111e97a7759f26eUtkarsh Sanghi  session->SetEntityAuthorizationValue(owner_password);
8572be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->LockNVSpace(index, session->GetDelegate());
8582be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
8592be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error locking nvram: " << GetErrorString(result);
8602be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8612be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
86238e6ef38e5ee4c7f735366a26111e97a7759f26eUtkarsh Sanghi  session->SetEntityAuthorizationValue("");
8632be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->ReadNVSpace(index, 0, nv_data.size(),
8642be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                            &new_nvdata, session->GetDelegate());
8652be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
8662be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error reading nvram: " << GetErrorString(result);
8672be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8682be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8692be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (nv_data.compare(new_nvdata) != 0) {
8702be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "NV space had different data than was written.";
8712be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8722be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8732be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue(owner_password);
8742be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->WriteNVSpace(index, 0, nv_data, session->GetDelegate());
8752be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result == TPM_RC_SUCCESS) {
8762be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Wrote nvram after locking: " << GetErrorString(result);
8772be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8782be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8792be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue(owner_password);
8802be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->DestroyNVSpace(index, session->GetDelegate());
8812be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
8822be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error destroying nvram: " << GetErrorString(result);
8832be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
8842be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
8852be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  return true;
8862be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
8872be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
8884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool TrunksClientTest::ManyKeysTest() {
8894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  const size_t kNumKeys = 20;
8904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<std::unique_ptr<ScopedKeyHandle>> key_handles;
8914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::map<TPM_HANDLE, std::string> public_key_map;
8924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (size_t i = 0; i < kNumKeys; ++i) {
8934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::unique_ptr<ScopedKeyHandle> key_handle(new ScopedKeyHandle(*factory_));
8944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::string public_key;
8954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    if (!LoadSigningKey(key_handle.get(), &public_key)) {
8964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      LOG(ERROR) << "Error loading key " << i << " into TPM.";
8974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
8984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    public_key_map[key_handle->get()] = public_key;
8994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    key_handles.push_back(std::move(key_handle));
9004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
9014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  CHECK_EQ(key_handles.size(), kNumKeys);
9024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  CHECK_EQ(public_key_map.size(), kNumKeys);
9034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  scoped_ptr<AuthorizationDelegate> delegate =
9044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      factory_->GetPasswordAuthorization("");
9054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (size_t i = 0; i < kNumKeys; ++i) {
9064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    const ScopedKeyHandle& key_handle = *key_handles[i];
9074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    const std::string& public_key = public_key_map[key_handle.get()];
9084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    if (!SignAndVerify(key_handle, public_key, delegate.get())) {
9094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      LOG(ERROR) << "Error signing with key " << i;
9104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
9114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
9124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::random_shuffle(key_handles.begin(), key_handles.end());
9134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (size_t i = 0; i < kNumKeys; ++i) {
9144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    const ScopedKeyHandle& key_handle = *key_handles[i];
9154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    const std::string& public_key = public_key_map[key_handle.get()];
9164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    if (!SignAndVerify(key_handle, public_key, delegate.get())) {
9174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      LOG(ERROR) << "Error signing with shuffled key " << i;
9184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
9194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
9204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  return true;
9214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
9224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
9234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool TrunksClientTest::ManySessionsTest() {
9244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  const size_t kNumSessions = 20;
9254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
9264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::vector<std::unique_ptr<HmacSession>> sessions;
9274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (size_t i = 0; i < kNumSessions; ++i) {
9284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    std::unique_ptr<HmacSession> session(factory_->GetHmacSession().release());
9294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    TPM_RC result = session->StartUnboundSession(true /* enable encryption */);
9304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    if (result != TPM_RC_SUCCESS) {
9314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      LOG(ERROR) << "Error starting hmac session " << i << ": "
9324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                 << GetErrorString(result);
9334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      return false;
9344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
9354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    sessions.push_back(std::move(session));
9364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
9374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  CHECK_EQ(sessions.size(), kNumSessions);
9384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  ScopedKeyHandle key_handle(*factory_);
9394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string public_key;
9404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  if (!LoadSigningKey(&key_handle, &public_key)) {
9414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return false;
9424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
9434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (size_t i = 0; i < kNumSessions; ++i) {
9444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    if (!SignAndVerify(key_handle, public_key, sessions[i]->GetDelegate())) {
9454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      LOG(ERROR) << "Error signing with hmac session " << i;
9464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
9474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
9484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::random_shuffle(sessions.begin(), sessions.end());
9494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  for (size_t i = 0; i < kNumSessions; ++i) {
9504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    if (!SignAndVerify(key_handle, public_key, sessions[i]->GetDelegate())) {
9514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      LOG(ERROR) << "Error signing with shuffled hmac session " << i;
9524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    }
9534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
9544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  return true;
9554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
9564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
9572be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::PerformRSAEncrpytAndDecrpyt(
9582be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    TPM_HANDLE key_handle,
9592be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    const std::string& key_authorization,
9602be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    HmacSession* session) {
9612be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
9622be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string ciphertext;
9632be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue("");
9642be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  TPM_RC result = utility->AsymmetricEncrypt(key_handle, TPM_ALG_NULL,
9652be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                             TPM_ALG_NULL, "plaintext",
9662be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                             session->GetDelegate(),
9672be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                             &ciphertext);
9682be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
9692be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error using key to encrypt: " << GetErrorString(result);
9702be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
9712be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
9722be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  std::string plaintext;
9732be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  session->SetEntityAuthorizationValue(key_authorization);
9742be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  result = utility->AsymmetricDecrypt(key_handle, TPM_ALG_NULL,
9752be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                      TPM_ALG_NULL, ciphertext,
9762be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi                                      session->GetDelegate(), &plaintext);
9772be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
9782be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Error using key to decrypt: " << GetErrorString(result);
9792be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
9802be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
9812be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  if (plaintext.compare("plaintext") != 0) {
9822be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    LOG(ERROR) << "Plaintext changed after encrypt + decrypt.";
9832be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi    return false;
9842be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  }
9852be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi  return true;
9862be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}
9872be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi
9884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnvoid TrunksClientTest::GenerateRSAKeyPair(std::string* modulus,
9894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          std::string* prime_factor,
9904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          std::string* public_key) {
9919caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#if defined(OPENSSL_IS_BORINGSSL)
992ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn  crypto::ScopedRSA rsa(RSA_new());
993ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn  crypto::ScopedBIGNUM exponent(BN_new());
994ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn  CHECK(BN_set_word(exponent.get(), RSA_F4));
995ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn  CHECK(RSA_generate_key_ex(rsa.get(), 2048, exponent.get(), nullptr))
996ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn      << "Failed to generate RSA key: " << GetOpenSSLError();
997ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn#else
9984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  crypto::ScopedRSA rsa(RSA_generate_key(2048, 0x10001, nullptr, nullptr));
9994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  CHECK(rsa.get());
1000ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn#endif
10014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  modulus->resize(BN_num_bytes(rsa.get()->n), 0);
10024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  BN_bn2bin(rsa.get()->n,
10034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn            reinterpret_cast<unsigned char*>(string_as_array(modulus)));
10044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  prime_factor->resize(BN_num_bytes(rsa.get()->p), 0);
10054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  BN_bn2bin(rsa.get()->p,
10064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn            reinterpret_cast<unsigned char*>(string_as_array(prime_factor)));
10074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  if (public_key) {
10084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    unsigned char* buffer = NULL;
10094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    int length = i2d_RSAPublicKey(rsa.get(), &buffer);
10104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    CHECK_GT(length, 0);
10114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    crypto::ScopedOpenSSLBytes scoped_buffer(buffer);
10124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    public_key->assign(reinterpret_cast<char*>(buffer), length);
10134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
10144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
10154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
10164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool TrunksClientTest::VerifyRSASignature(const std::string& public_key,
10174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          const std::string& data,
10184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                          const std::string& signature) {
10194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  auto asn1_ptr = reinterpret_cast<const unsigned char*>(public_key.data());
10204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  crypto::ScopedRSA rsa(d2i_RSAPublicKey(nullptr, &asn1_ptr,
10214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                         public_key.size()));
10224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  CHECK(rsa.get());
10234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string digest = crypto::SHA256HashString(data);
10244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  auto digest_buffer = reinterpret_cast<const unsigned char*>(digest.data());
10254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string mutable_signature(signature);
10264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  unsigned char* signature_buffer =
10274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      reinterpret_cast<unsigned char*>(string_as_array(&mutable_signature));
10284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  return (RSA_verify(NID_sha256, digest_buffer, digest.size(),
10294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                     signature_buffer, signature.size(), rsa.get()) == 1);
10304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
10314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
10324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool TrunksClientTest::LoadSigningKey(ScopedKeyHandle* key_handle,
10334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                      std::string* public_key) {
10344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string modulus;
10354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string prime_factor;
10364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  GenerateRSAKeyPair(&modulus, &prime_factor, public_key);
10374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string key_blob;
10386ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
10394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_RC result = utility->ImportRSAKey(
10404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      TpmUtility::AsymmetricKeyUsage::kSignKey,
10414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      modulus, 0x10001, prime_factor,
10424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      "",  // password
10434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      factory_->GetPasswordAuthorization("").get(),
10444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn      &key_blob);
10454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  if (result != TPM_RC_SUCCESS) {
10464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    LOG(ERROR) << "ImportRSAKey: " << GetErrorString(result);
10474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return false;
10484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
10494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_HANDLE raw_key_handle;
10504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  result = utility->LoadKey(key_blob,
10514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                            factory_->GetPasswordAuthorization("").get(),
10524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                            &raw_key_handle);
10534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  if (result != TPM_RC_SUCCESS) {
10544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    LOG(ERROR) << "LoadKey: " << GetErrorString(result);
10554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    return false;
10564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  }
10574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  key_handle->reset(raw_key_handle);
10584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  return true;
10594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn}
10604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn
10614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool TrunksClientTest::SignAndVerify(const ScopedKeyHandle& key_handle,
10624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                     const std::string& public_key,
10634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                     AuthorizationDelegate* delegate) {
10646ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  std::string signature;
10654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  std::string data_to_sign("sign_this");
10664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility();
10674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  TPM_RC result = utility->Sign(key_handle.get(),
10684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                TPM_ALG_RSASSA,
10694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                TPM_ALG_SHA256,
10704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                data_to_sign,
10714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn                                delegate,
10726ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi                                &signature);
10736ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  if (result != TPM_RC_SUCCESS) {
10744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn    LOG(ERROR) << "Sign: " << GetErrorString(result);
10756ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
10766ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
10774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn  if (!VerifyRSASignature(public_key, data_to_sign, signature)) {
1078ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn    LOG(ERROR) << "Signature verification failed: " << GetOpenSSLError();
10796ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi    return false;
10806ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  }
10816ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi  return true;
10826ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi}
10836ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi
10842be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi}  // namespace trunks
1085