Home | History | Annotate | Download | only in common
      1 //
      2 // Copyright (C) 2015 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #include "attestation/common/tpm_utility_v1.h"
     18 
     19 #include <base/files/file_path.h>
     20 #include <base/files/file_util.h>
     21 #include <base/logging.h>
     22 #include <base/memory/scoped_ptr.h>
     23 #include <base/stl_util.h>
     24 #include <crypto/scoped_openssl_types.h>
     25 #include <crypto/sha2.h>
     26 #include <openssl/rsa.h>
     27 #include <openssl/sha.h>
     28 #include <trousers/scoped_tss_type.h>
     29 #include <trousers/trousers.h>
     30 #include <trousers/tss.h>
     31 
     32 #define TPM_LOG(severity, result)                               \
     33   LOG(severity) << "TPM error 0x" << std::hex << result << " (" \
     34                 << Trspi_Error_String(result) << "): "
     35 
     36 using trousers::ScopedTssContext;
     37 using trousers::ScopedTssKey;
     38 using trousers::ScopedTssMemory;
     39 using trousers::ScopedTssPcrs;
     40 
     41 namespace {
     42 
     43 using ScopedByteArray = scoped_ptr<BYTE, base::FreeDeleter>;
     44 using ScopedTssEncryptedData = trousers::ScopedTssObject<TSS_HENCDATA>;
     45 using ScopedTssHash = trousers::ScopedTssObject<TSS_HHASH>;
     46 
     47 const char* kTpmTpmEnabledFile = "/sys/class/tpm/tpm0/device/enabled";
     48 const char* kMscTpmEnabledFile = "/sys/class/misc/tpm0/device/enabled";
     49 const char* kTpmTpmOwnedFile = "/sys/class/tpm/tpm0/device/owned";
     50 const char* kMscTpmOwnedFile = "/sys/class/misc/tpm0/device/owned";
     51 const unsigned int kWellKnownExponent = 65537;
     52 const unsigned char kSha256DigestInfo[] = {
     53     0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
     54     0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
     55 
     56 std::string GetFirstByte(const char* file_name) {
     57   std::string content;
     58   base::ReadFileToString(base::FilePath(file_name), &content);
     59   if (content.size() > 1) {
     60     content.resize(1);
     61   }
     62   return content;
     63 }
     64 
     65 BYTE* StringAsTSSBuffer(std::string* s) {
     66   return reinterpret_cast<BYTE*>(string_as_array(s));
     67 }
     68 
     69 std::string TSSBufferAsString(const BYTE* buffer, size_t length) {
     70   return std::string(reinterpret_cast<const char*>(buffer), length);
     71 }
     72 
     73 }  // namespace
     74 
     75 namespace attestation {
     76 
     77 TpmUtilityV1::~TpmUtilityV1() {}
     78 
     79 bool TpmUtilityV1::Initialize() {
     80   if (!ConnectContext(&context_handle_, &tpm_handle_)) {
     81     LOG(ERROR) << __func__ << ": Failed to connect to the TPM.";
     82     return false;
     83   }
     84   if (!IsTpmReady()) {
     85     LOG(WARNING) << __func__ << ": TPM is not owned; attestation services will "
     86                  << "not be available until ownership is taken.";
     87   }
     88   return true;
     89 }
     90 
     91 bool TpmUtilityV1::IsTpmReady() {
     92   if (!is_ready_) {
     93     if (base::PathExists(base::FilePath(kMscTpmEnabledFile))) {
     94       is_ready_ = (GetFirstByte(kMscTpmEnabledFile) == "1" &&
     95                    GetFirstByte(kMscTpmOwnedFile) == "1");
     96     } else {
     97       is_ready_ = (GetFirstByte(kTpmTpmEnabledFile) == "1" &&
     98                    GetFirstByte(kTpmTpmOwnedFile) == "1");
     99     }
    100   }
    101   return is_ready_;
    102 }
    103 
    104 bool TpmUtilityV1::ActivateIdentity(const std::string& delegate_blob,
    105                                     const std::string& delegate_secret,
    106                                     const std::string& identity_key_blob,
    107                                     const std::string& asym_ca_contents,
    108                                     const std::string& sym_ca_attestation,
    109                                     std::string* credential) {
    110   CHECK(credential);
    111   if (!SetupSrk()) {
    112     LOG(ERROR) << "SRK is not ready.";
    113     return false;
    114   }
    115 
    116   // Connect to the TPM as the owner delegate.
    117   ScopedTssContext context_handle;
    118   TSS_HTPM tpm_handle;
    119   if (!ConnectContextAsDelegate(delegate_blob, delegate_secret, &context_handle,
    120                                 &tpm_handle)) {
    121     LOG(ERROR) << __func__ << ": Could not connect to the TPM.";
    122     return false;
    123   }
    124   // Load the Storage Root Key.
    125   TSS_RESULT result;
    126   ScopedTssKey srk_handle(context_handle);
    127   if (!LoadSrk(context_handle, &srk_handle)) {
    128     LOG(ERROR) << __func__ << ": Failed to load SRK.";
    129     return false;
    130   }
    131   // Load the AIK (which is wrapped by the SRK).
    132   std::string mutable_identity_key_blob(identity_key_blob);
    133   BYTE* identity_key_blob_buffer =
    134       StringAsTSSBuffer(&mutable_identity_key_blob);
    135   ScopedTssKey identity_key(context_handle);
    136   result = Tspi_Context_LoadKeyByBlob(
    137       context_handle, srk_handle, identity_key_blob.size(),
    138       identity_key_blob_buffer, identity_key.ptr());
    139   if (TPM_ERROR(result)) {
    140     TPM_LOG(ERROR, result) << __func__ << ": Failed to load AIK.";
    141     return false;
    142   }
    143   std::string mutable_asym_ca_contents(asym_ca_contents);
    144   BYTE* asym_ca_contents_buffer = StringAsTSSBuffer(&mutable_asym_ca_contents);
    145   std::string mutable_sym_ca_attestation(sym_ca_attestation);
    146   BYTE* sym_ca_attestation_buffer =
    147       StringAsTSSBuffer(&mutable_sym_ca_attestation);
    148   UINT32 credential_length = 0;
    149   ScopedTssMemory credential_buffer(context_handle);
    150   result = Tspi_TPM_ActivateIdentity(
    151       tpm_handle, identity_key, asym_ca_contents.size(),
    152       asym_ca_contents_buffer, sym_ca_attestation.size(),
    153       sym_ca_attestation_buffer, &credential_length, credential_buffer.ptr());
    154   if (TPM_ERROR(result)) {
    155     TPM_LOG(ERROR, result) << __func__ << ": Failed to activate identity.";
    156     return false;
    157   }
    158   credential->assign(
    159       TSSBufferAsString(credential_buffer.value(), credential_length));
    160   return true;
    161 }
    162 
    163 bool TpmUtilityV1::CreateCertifiedKey(KeyType key_type,
    164                                       KeyUsage key_usage,
    165                                       const std::string& identity_key_blob,
    166                                       const std::string& external_data,
    167                                       std::string* key_blob,
    168                                       std::string* public_key,
    169                                       std::string* public_key_tpm_format,
    170                                       std::string* key_info,
    171                                       std::string* proof) {
    172   CHECK(key_blob && public_key && public_key_tpm_format && key_info && proof);
    173   if (!SetupSrk()) {
    174     LOG(ERROR) << "SRK is not ready.";
    175     return false;
    176   }
    177   if (key_type != KEY_TYPE_RSA) {
    178     LOG(ERROR) << "Only RSA supported on TPM v1.2.";
    179     return false;
    180   }
    181 
    182   // Load the AIK (which is wrapped by the SRK).
    183   ScopedTssKey identity_key(context_handle_);
    184   if (!LoadKeyFromBlob(identity_key_blob, context_handle_, srk_handle_,
    185                        &identity_key)) {
    186     LOG(ERROR) << __func__ << "Failed to load AIK.";
    187     return false;
    188   }
    189 
    190   // Create a non-migratable RSA key.
    191   ScopedTssKey key(context_handle_);
    192   UINT32 tss_key_type =
    193       (key_usage == KEY_USAGE_SIGN) ? TSS_KEY_TYPE_SIGNING : TSS_KEY_TYPE_BIND;
    194   UINT32 init_flags = tss_key_type | TSS_KEY_NOT_MIGRATABLE | TSS_KEY_VOLATILE |
    195                       TSS_KEY_NO_AUTHORIZATION | TSS_KEY_SIZE_2048;
    196   TSS_RESULT result = Tspi_Context_CreateObject(
    197       context_handle_, TSS_OBJECT_TYPE_RSAKEY, init_flags, key.ptr());
    198   if (TPM_ERROR(result)) {
    199     TPM_LOG(ERROR, result) << __func__ << ": Failed to create object.";
    200     return false;
    201   }
    202   if (key_usage == KEY_USAGE_SIGN) {
    203     result = Tspi_SetAttribUint32(key, TSS_TSPATTRIB_KEY_INFO,
    204                                   TSS_TSPATTRIB_KEYINFO_SIGSCHEME,
    205                                   TSS_SS_RSASSAPKCS1V15_DER);
    206   } else {
    207     result = Tspi_SetAttribUint32(key, TSS_TSPATTRIB_KEY_INFO,
    208                                   TSS_TSPATTRIB_KEYINFO_ENCSCHEME,
    209                                   TSS_ES_RSAESOAEP_SHA1_MGF1);
    210   }
    211   if (TPM_ERROR(result)) {
    212     TPM_LOG(ERROR, result) << __func__ << ": Failed to set scheme.";
    213     return false;
    214   }
    215   result = Tspi_Key_CreateKey(key, srk_handle_, 0);
    216   if (TPM_ERROR(result)) {
    217     TPM_LOG(ERROR, result) << __func__ << ": Failed to create key.";
    218     return false;
    219   }
    220   result = Tspi_Key_LoadKey(key, srk_handle_);
    221   if (TPM_ERROR(result)) {
    222     TPM_LOG(ERROR, result) << __func__ << ": Failed to load key.";
    223     return false;
    224   }
    225 
    226   // Certify the key.
    227   TSS_VALIDATION validation;
    228   memset(&validation, 0, sizeof(validation));
    229   validation.ulExternalDataLength = external_data.size();
    230   std::string mutable_external_data(external_data);
    231   validation.rgbExternalData = StringAsTSSBuffer(&mutable_external_data);
    232   result = Tspi_Key_CertifyKey(key, identity_key, &validation);
    233   if (TPM_ERROR(result)) {
    234     TPM_LOG(ERROR, result) << __func__ << ": Failed to certify key.";
    235     return false;
    236   }
    237   ScopedTssMemory scoped_certified_data(0, validation.rgbData);
    238   ScopedTssMemory scoped_proof(0, validation.rgbValidationData);
    239 
    240   // Get the certified public key.
    241   if (!GetDataAttribute(context_handle_, key, TSS_TSPATTRIB_KEY_BLOB,
    242                         TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY,
    243                         public_key_tpm_format)) {
    244     LOG(ERROR) << __func__ << ": Failed to read public key.";
    245     return false;
    246   }
    247   if (!ConvertPublicKeyToDER(*public_key_tpm_format, public_key)) {
    248     return false;
    249   }
    250 
    251   // Get the certified key blob so we can load it later.
    252   if (!GetDataAttribute(context_handle_, key, TSS_TSPATTRIB_KEY_BLOB,
    253                         TSS_TSPATTRIB_KEYBLOB_BLOB, key_blob)) {
    254     LOG(ERROR) << __func__ << ": Failed to read key blob.";
    255     return false;
    256   }
    257 
    258   // Get the data that was certified.
    259   key_info->assign(
    260       TSSBufferAsString(validation.rgbData, validation.ulDataLength));
    261 
    262   // Get the certification proof.
    263   proof->assign(TSSBufferAsString(validation.rgbValidationData,
    264                                   validation.ulValidationDataLength));
    265   return true;
    266 }
    267 
    268 bool TpmUtilityV1::SealToPCR0(const std::string& data,
    269                               std::string* sealed_data) {
    270   CHECK(sealed_data);
    271   if (!SetupSrk()) {
    272     LOG(ERROR) << "SRK is not ready.";
    273     return false;
    274   }
    275 
    276   // Create a PCRS object which holds the value of PCR0.
    277   ScopedTssPcrs pcrs_handle(context_handle_);
    278   TSS_RESULT result;
    279   if (TPM_ERROR(result = Tspi_Context_CreateObject(
    280                     context_handle_, TSS_OBJECT_TYPE_PCRS, TSS_PCRS_STRUCT_INFO,
    281                     pcrs_handle.ptr()))) {
    282     TPM_LOG(ERROR, result) << __func__
    283                            << ": Error calling Tspi_Context_CreateObject";
    284     return false;
    285   }
    286   UINT32 pcr_length = 0;
    287   ScopedTssMemory pcr_value(context_handle_);
    288   Tspi_TPM_PcrRead(tpm_handle_, 0, &pcr_length, pcr_value.ptr());
    289   Tspi_PcrComposite_SetPcrValue(pcrs_handle, 0, pcr_length, pcr_value.value());
    290 
    291   // Create a ENCDATA object to receive the sealed data.
    292   ScopedTssKey encrypted_data_handle(context_handle_);
    293   if (TPM_ERROR(result = Tspi_Context_CreateObject(
    294                     context_handle_, TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_SEAL,
    295                     encrypted_data_handle.ptr()))) {
    296     TPM_LOG(ERROR, result) << __func__
    297                            << ": Error calling Tspi_Context_CreateObject";
    298     return false;
    299   }
    300 
    301   // Seal the given value with the SRK.
    302   std::string mutable_data(data);
    303   BYTE* data_buffer = StringAsTSSBuffer(&mutable_data);
    304   if (TPM_ERROR(result =
    305                     Tspi_Data_Seal(encrypted_data_handle, srk_handle_,
    306                                    data.size(), data_buffer, pcrs_handle))) {
    307     TPM_LOG(ERROR, result) << __func__ << ": Error calling Tspi_Data_Seal";
    308     return false;
    309   }
    310 
    311   // Extract the sealed value.
    312   ScopedTssMemory encrypted_data(context_handle_);
    313   UINT32 encrypted_data_length = 0;
    314   if (TPM_ERROR(result = Tspi_GetAttribData(
    315                     encrypted_data_handle, TSS_TSPATTRIB_ENCDATA_BLOB,
    316                     TSS_TSPATTRIB_ENCDATABLOB_BLOB, &encrypted_data_length,
    317                     encrypted_data.ptr()))) {
    318     TPM_LOG(ERROR, result) << __func__ << ": Error calling Tspi_GetAttribData";
    319     return false;
    320   }
    321   sealed_data->assign(
    322       TSSBufferAsString(encrypted_data.value(), encrypted_data_length));
    323   return true;
    324 }
    325 
    326 bool TpmUtilityV1::Unseal(const std::string& sealed_data, std::string* data) {
    327   CHECK(data);
    328   if (!SetupSrk()) {
    329     LOG(ERROR) << "SRK is not ready.";
    330     return false;
    331   }
    332 
    333   // Create an ENCDATA object with the sealed value.
    334   ScopedTssKey encrypted_data_handle(context_handle_);
    335   TSS_RESULT result;
    336   if (TPM_ERROR(result = Tspi_Context_CreateObject(
    337                     context_handle_, TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_SEAL,
    338                     encrypted_data_handle.ptr()))) {
    339     TPM_LOG(ERROR, result) << __func__
    340                            << ": Error calling Tspi_Context_CreateObject";
    341     return false;
    342   }
    343 
    344   std::string mutable_sealed_data(sealed_data);
    345   BYTE* sealed_data_buffer = StringAsTSSBuffer(&mutable_sealed_data);
    346   if (TPM_ERROR(result = Tspi_SetAttribData(
    347                     encrypted_data_handle, TSS_TSPATTRIB_ENCDATA_BLOB,
    348                     TSS_TSPATTRIB_ENCDATABLOB_BLOB, sealed_data.size(),
    349                     sealed_data_buffer))) {
    350     TPM_LOG(ERROR, result) << __func__ << ": Error calling Tspi_SetAttribData";
    351     return false;
    352   }
    353 
    354   // Unseal using the SRK.
    355   ScopedTssMemory decrypted_data(context_handle_);
    356   UINT32 decrypted_data_length = 0;
    357   if (TPM_ERROR(result = Tspi_Data_Unseal(encrypted_data_handle, srk_handle_,
    358                                           &decrypted_data_length,
    359                                           decrypted_data.ptr()))) {
    360     TPM_LOG(ERROR, result) << __func__ << ": Error calling Tspi_Data_Unseal";
    361     return false;
    362   }
    363   data->assign(
    364       TSSBufferAsString(decrypted_data.value(), decrypted_data_length));
    365   return true;
    366 }
    367 
    368 bool TpmUtilityV1::GetEndorsementPublicKey(std::string* public_key) {
    369   // Get a handle to the EK public key.
    370   ScopedTssKey ek_public_key_object(context_handle_);
    371   TSS_RESULT result = Tspi_TPM_GetPubEndorsementKey(tpm_handle_, false, nullptr,
    372                                                     ek_public_key_object.ptr());
    373   if (TPM_ERROR(result)) {
    374     TPM_LOG(ERROR, result) << __func__ << ": Failed to get key.";
    375     return false;
    376   }
    377   // Get the public key in TPM_PUBKEY form.
    378   std::string ek_public_key_blob;
    379   if (!GetDataAttribute(
    380           context_handle_, ek_public_key_object, TSS_TSPATTRIB_KEY_BLOB,
    381           TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, &ek_public_key_blob)) {
    382     LOG(ERROR) << __func__ << ": Failed to read public key.";
    383     return false;
    384   }
    385   // Get the public key in DER encoded form.
    386   if (!ConvertPublicKeyToDER(ek_public_key_blob, public_key)) {
    387     return false;
    388   }
    389   return true;
    390 }
    391 
    392 bool TpmUtilityV1::Unbind(const std::string& key_blob,
    393                           const std::string& bound_data,
    394                           std::string* data) {
    395   CHECK(data);
    396   if (!SetupSrk()) {
    397     LOG(ERROR) << "SRK is not ready.";
    398     return false;
    399   }
    400   ScopedTssKey key_handle(context_handle_);
    401   if (!LoadKeyFromBlob(key_blob, context_handle_, srk_handle_, &key_handle)) {
    402     return false;
    403   }
    404   TSS_RESULT result;
    405   ScopedTssEncryptedData data_handle(context_handle_);
    406   if (TPM_ERROR(result = Tspi_Context_CreateObject(
    407                     context_handle_, TSS_OBJECT_TYPE_ENCDATA, TSS_ENCDATA_BIND,
    408                     data_handle.ptr()))) {
    409     TPM_LOG(ERROR, result) << __func__ << ": Tspi_Context_CreateObject failed.";
    410     return false;
    411   }
    412   std::string mutable_bound_data(bound_data);
    413   if (TPM_ERROR(result = Tspi_SetAttribData(
    414                     data_handle, TSS_TSPATTRIB_ENCDATA_BLOB,
    415                     TSS_TSPATTRIB_ENCDATABLOB_BLOB, bound_data.size(),
    416                     StringAsTSSBuffer(&mutable_bound_data)))) {
    417     TPM_LOG(ERROR, result) << __func__ << ": Tspi_SetAttribData failed.";
    418     return false;
    419   }
    420 
    421   ScopedTssMemory decrypted_data(context_handle_);
    422   UINT32 length = 0;
    423   if (TPM_ERROR(result = Tspi_Data_Unbind(data_handle, key_handle, &length,
    424                                           decrypted_data.ptr()))) {
    425     TPM_LOG(ERROR, result) << __func__ << ": Tspi_Data_Unbind failed.";
    426     return false;
    427   }
    428   data->assign(TSSBufferAsString(decrypted_data.value(), length));
    429   return true;
    430 }
    431 
    432 bool TpmUtilityV1::Sign(const std::string& key_blob,
    433                         const std::string& data_to_sign,
    434                         std::string* signature) {
    435   CHECK(signature);
    436   if (!SetupSrk()) {
    437     LOG(ERROR) << "SRK is not ready.";
    438     return false;
    439   }
    440   ScopedTssKey key_handle(context_handle_);
    441   if (!LoadKeyFromBlob(key_blob, context_handle_, srk_handle_, &key_handle)) {
    442     return false;
    443   }
    444   // Construct an ASN.1 DER DigestInfo.
    445   std::string digest_to_sign(std::begin(kSha256DigestInfo),
    446                              std::end(kSha256DigestInfo));
    447   digest_to_sign += crypto::SHA256HashString(data_to_sign);
    448   // Create a hash object to hold the digest.
    449   ScopedTssHash hash_handle(context_handle_);
    450   TSS_RESULT result = Tspi_Context_CreateObject(
    451       context_handle_, TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER, hash_handle.ptr());
    452   if (TPM_ERROR(result)) {
    453     TPM_LOG(ERROR, result) << __func__ << ": Failed to create hash object.";
    454     return false;
    455   }
    456   result = Tspi_Hash_SetHashValue(hash_handle, digest_to_sign.size(),
    457                                   StringAsTSSBuffer(&digest_to_sign));
    458   if (TPM_ERROR(result)) {
    459     TPM_LOG(ERROR, result) << __func__ << ": Failed to set hash data.";
    460     return false;
    461   }
    462   UINT32 length = 0;
    463   ScopedTssMemory buffer(context_handle_);
    464   result = Tspi_Hash_Sign(hash_handle, key_handle, &length, buffer.ptr());
    465   if (TPM_ERROR(result)) {
    466     TPM_LOG(ERROR, result) << __func__ << ": Failed to generate signature.";
    467     return false;
    468   }
    469   signature->assign(TSSBufferAsString(buffer.value(), length));
    470   return true;
    471 }
    472 
    473 bool TpmUtilityV1::ConnectContext(ScopedTssContext* context, TSS_HTPM* tpm) {
    474   *tpm = 0;
    475   TSS_RESULT result;
    476   if (TPM_ERROR(result = Tspi_Context_Create(context->ptr()))) {
    477     TPM_LOG(ERROR, result) << __func__ << ": Error calling Tspi_Context_Create";
    478     return false;
    479   }
    480   if (TPM_ERROR(result = Tspi_Context_Connect(*context, nullptr))) {
    481     TPM_LOG(ERROR, result) << __func__
    482                            << ": Error calling Tspi_Context_Connect";
    483     return false;
    484   }
    485   if (TPM_ERROR(result = Tspi_Context_GetTpmObject(*context, tpm))) {
    486     TPM_LOG(ERROR, result) << __func__
    487                            << ": Error calling Tspi_Context_GetTpmObject";
    488     return false;
    489   }
    490   return true;
    491 }
    492 
    493 bool TpmUtilityV1::ConnectContextAsDelegate(const std::string& delegate_blob,
    494                                             const std::string& delegate_secret,
    495                                             ScopedTssContext* context,
    496                                             TSS_HTPM* tpm) {
    497   *tpm = 0;
    498   if (!ConnectContext(context, tpm)) {
    499     return false;
    500   }
    501   TSS_RESULT result;
    502   TSS_HPOLICY tpm_usage_policy;
    503   if (TPM_ERROR(result = Tspi_GetPolicyObject(*tpm, TSS_POLICY_USAGE,
    504                                               &tpm_usage_policy))) {
    505     TPM_LOG(ERROR, result) << __func__
    506                            << ": Error calling Tspi_GetPolicyObject";
    507     return false;
    508   }
    509   std::string mutable_delegate_secret(delegate_secret);
    510   BYTE* secret_buffer = StringAsTSSBuffer(&mutable_delegate_secret);
    511   if (TPM_ERROR(result = Tspi_Policy_SetSecret(
    512                     tpm_usage_policy, TSS_SECRET_MODE_PLAIN,
    513                     delegate_secret.size(), secret_buffer))) {
    514     TPM_LOG(ERROR, result) << __func__
    515                            << ": Error calling Tspi_Policy_SetSecret";
    516     return false;
    517   }
    518   std::string mutable_delegate_blob(delegate_blob);
    519   BYTE* blob_buffer = StringAsTSSBuffer(&mutable_delegate_blob);
    520   if (TPM_ERROR(result = Tspi_SetAttribData(
    521                     tpm_usage_policy, TSS_TSPATTRIB_POLICY_DELEGATION_INFO,
    522                     TSS_TSPATTRIB_POLDEL_OWNERBLOB, delegate_blob.size(),
    523                     blob_buffer))) {
    524     TPM_LOG(ERROR, result) << __func__ << ": Error calling Tspi_SetAttribData";
    525     return false;
    526   }
    527   return true;
    528 }
    529 
    530 bool TpmUtilityV1::SetupSrk() {
    531   if (!IsTpmReady()) {
    532     return false;
    533   }
    534   if (srk_handle_) {
    535     return true;
    536   }
    537   srk_handle_.reset(context_handle_, 0);
    538   if (!LoadSrk(context_handle_, &srk_handle_)) {
    539     LOG(ERROR) << __func__ << ": Failed to load SRK.";
    540     return false;
    541   }
    542   // In order to wrap a key with the SRK we need access to the SRK public key
    543   // and we need to get it manually. Once it's in the key object, we don't need
    544   // to do this again.
    545   UINT32 length = 0;
    546   ScopedTssMemory buffer(context_handle_);
    547   TSS_RESULT result;
    548   result = Tspi_Key_GetPubKey(srk_handle_, &length, buffer.ptr());
    549   if (result != TSS_SUCCESS) {
    550     TPM_LOG(INFO, result) << __func__ << ": Failed to read SRK public key.";
    551     return false;
    552   }
    553   return true;
    554 }
    555 
    556 bool TpmUtilityV1::LoadSrk(TSS_HCONTEXT context_handle,
    557                            ScopedTssKey* srk_handle) {
    558   TSS_RESULT result;
    559   TSS_UUID uuid = TSS_UUID_SRK;
    560   if (TPM_ERROR(result = Tspi_Context_LoadKeyByUUID(context_handle,
    561                                                     TSS_PS_TYPE_SYSTEM, uuid,
    562                                                     srk_handle->ptr()))) {
    563     TPM_LOG(ERROR, result) << __func__
    564                            << ": Error calling Tspi_Context_LoadKeyByUUID";
    565     return false;
    566   }
    567   // Check if the SRK wants a password.
    568   UINT32 auth_usage;
    569   if (TPM_ERROR(result = Tspi_GetAttribUint32(
    570                     *srk_handle, TSS_TSPATTRIB_KEY_INFO,
    571                     TSS_TSPATTRIB_KEYINFO_AUTHUSAGE, &auth_usage))) {
    572     TPM_LOG(ERROR, result) << __func__
    573                            << ": Error calling Tspi_GetAttribUint32";
    574     return false;
    575   }
    576   if (auth_usage) {
    577     // Give it an empty password if needed.
    578     TSS_HPOLICY usage_policy;
    579     if (TPM_ERROR(result = Tspi_GetPolicyObject(*srk_handle, TSS_POLICY_USAGE,
    580                                                 &usage_policy))) {
    581       TPM_LOG(ERROR, result) << __func__
    582                              << ": Error calling Tspi_GetPolicyObject";
    583       return false;
    584     }
    585 
    586     BYTE empty_password[] = {};
    587     if (TPM_ERROR(result =
    588                       Tspi_Policy_SetSecret(usage_policy, TSS_SECRET_MODE_PLAIN,
    589                                             0, empty_password))) {
    590       TPM_LOG(ERROR, result) << __func__
    591                              << ": Error calling Tspi_Policy_SetSecret";
    592       return false;
    593     }
    594   }
    595   return true;
    596 }
    597 
    598 bool TpmUtilityV1::LoadKeyFromBlob(const std::string& key_blob,
    599                                    TSS_HCONTEXT context_handle,
    600                                    TSS_HKEY parent_key_handle,
    601                                    ScopedTssKey* key_handle) {
    602   std::string mutable_key_blob(key_blob);
    603   BYTE* key_blob_buffer = StringAsTSSBuffer(&mutable_key_blob);
    604   TSS_RESULT result = Tspi_Context_LoadKeyByBlob(
    605       context_handle, parent_key_handle, key_blob.size(), key_blob_buffer,
    606       key_handle->ptr());
    607   if (TPM_ERROR(result)) {
    608     TPM_LOG(ERROR, result) << __func__ << ": Failed to load key by blob.";
    609     return false;
    610   }
    611   return true;
    612 }
    613 
    614 bool TpmUtilityV1::GetDataAttribute(TSS_HCONTEXT context,
    615                                     TSS_HOBJECT object,
    616                                     TSS_FLAG flag,
    617                                     TSS_FLAG sub_flag,
    618                                     std::string* data) {
    619   UINT32 length = 0;
    620   ScopedTssMemory buffer(context);
    621   TSS_RESULT result =
    622       Tspi_GetAttribData(object, flag, sub_flag, &length, buffer.ptr());
    623   if (TPM_ERROR(result)) {
    624     TPM_LOG(ERROR, result) << __func__ << "Failed to read object attribute.";
    625     return false;
    626   }
    627   data->assign(TSSBufferAsString(buffer.value(), length));
    628   return true;
    629 }
    630 
    631 bool TpmUtilityV1::ConvertPublicKeyToDER(const std::string& public_key,
    632                                          std::string* public_key_der) {
    633   // Parse the serialized TPM_PUBKEY.
    634   UINT64 offset = 0;
    635   std::string mutable_public_key(public_key);
    636   BYTE* buffer = StringAsTSSBuffer(&mutable_public_key);
    637   TPM_PUBKEY parsed;
    638   TSS_RESULT result = Trspi_UnloadBlob_PUBKEY(&offset, buffer, &parsed);
    639   if (TPM_ERROR(result)) {
    640     TPM_LOG(ERROR, result) << "Failed to parse TPM_PUBKEY.";
    641     return false;
    642   }
    643   ScopedByteArray scoped_key(parsed.pubKey.key);
    644   ScopedByteArray scoped_parms(parsed.algorithmParms.parms);
    645   TPM_RSA_KEY_PARMS* parms =
    646       reinterpret_cast<TPM_RSA_KEY_PARMS*>(parsed.algorithmParms.parms);
    647   crypto::ScopedRSA rsa(RSA_new());
    648   CHECK(rsa.get());
    649   // Get the public exponent.
    650   if (parms->exponentSize == 0) {
    651     rsa.get()->e = BN_new();
    652     CHECK(rsa.get()->e);
    653     BN_set_word(rsa.get()->e, kWellKnownExponent);
    654   } else {
    655     rsa.get()->e = BN_bin2bn(parms->exponent, parms->exponentSize, nullptr);
    656     CHECK(rsa.get()->e);
    657   }
    658   // Get the modulus.
    659   rsa.get()->n = BN_bin2bn(parsed.pubKey.key, parsed.pubKey.keyLength, nullptr);
    660   CHECK(rsa.get()->n);
    661 
    662   // DER encode.
    663   int der_length = i2d_RSAPublicKey(rsa.get(), nullptr);
    664   if (der_length < 0) {
    665     LOG(ERROR) << "Failed to DER-encode public key.";
    666     return false;
    667   }
    668   public_key_der->resize(der_length);
    669   unsigned char* der_buffer =
    670       reinterpret_cast<unsigned char*>(string_as_array(public_key_der));
    671   der_length = i2d_RSAPublicKey(rsa.get(), &der_buffer);
    672   if (der_length < 0) {
    673     LOG(ERROR) << "Failed to DER-encode public key.";
    674     return false;
    675   }
    676   public_key_der->resize(der_length);
    677   return true;
    678 }
    679 
    680 }  // namespace attestation
    681