github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/tpm2/GetEndorsementKey.cc (about)

     1  #include <stdio.h>
     2  #include <stdlib.h>
     3  #include <sys/types.h>
     4  #include <sys/stat.h>
     5  #include <fcntl.h>
     6  #include <unistd.h>
     7  #include <string.h>
     8  
     9  #include <tpm20.h>
    10  #include <tpm2_lib.h>
    11  #include <tpm2.pb.h>
    12  #include <gflags/gflags.h>
    13  
    14  //
    15  // Copyright 2015 Google Corporation, All Rights Reserved.
    16  //
    17  // Licensed under the Apache License, Version 2.0 (the "License");
    18  // you may not use this file except in compliance with the License.
    19  // You may obtain a copy of the License at
    20  //     http://www.apache.org/licenses/LICENSE-2.0
    21  // or in the the file LICENSE-2.0.txt in the top level sourcedirectory
    22  // Unless required by applicable law or agreed to in writing, software
    23  // distributed under the License is distributed on an "AS IS" BASIS,
    24  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    25  // See the License for the specific language governing permissions and
    26  // limitations under the License
    27  //
    28  // Portions of this code were derived TPM2.0-TSS published
    29  // by Intel under the license set forth in intel_license.txt
    30  // and downloaded on or about August 6, 2015.
    31  // Portions of this code were derived tboot published
    32  // by Intel under the license set forth in intel_license.txt
    33  // and downloaded on or about August 6, 2015.
    34  // Portions of this code were derived from the crypto utility
    35  // published by John Manferdelli under the Apache 2.0 license.
    36  // See github.com/jlmucb/crypto.
    37  // File: GetEndorsementKey.cc
    38  
    39  
    40  // Calling sequence
    41  //   GetEndorsementKey.exe --endorsement_info_file=output-file
    42  
    43  using std::string;
    44  
    45  // This program creates the endorsement key and produces a file containing
    46  // a protobuf consisting of the TPM2B_PUBLIC blob and other information.
    47  // TODO: include machine identifier?
    48  
    49  DEFINE_string(endorsement_info_file, "", "output file");
    50  DEFINE_string(machine_identifier, "", "text to identify endorsement");
    51  DEFINE_string(hash_alg, "sha1", "hash");
    52  
    53  #ifndef GFLAGS_NS
    54  #define GFLAGS_NS google
    55  #endif
    56  #define DEBUG
    57  
    58  void PrintOptions() {
    59    printf("Calling sequence: GetEndorsementKey.exe " \
    60            "-- machine_identifier= name --endorsement_info_file=output-file\n");
    61  }
    62  
    63  int main(int an, char** av) {
    64    LocalTpm tpm;
    65    TPM_HANDLE ekHandle;
    66    TPM2B_PUBLIC pub_out;
    67    TPM2B_NAME pub_name;
    68    TPM2B_NAME qualified_pub_name;
    69    uint16_t pub_blob_size = 1024;
    70    byte pub_blob[1024];
    71    string emptyAuth;
    72    TPML_PCR_SELECTION pcrSelect;
    73    TPMA_OBJECT primary_flags;
    74    *(uint32_t*)(&primary_flags) = 0;
    75  
    76    int ret_val = 0;
    77    endorsement_key_message message;
    78    string output;
    79  
    80    printf("\nGetEndorsementKey\n\n");
    81  
    82    TPM_ALG_ID hash_alg_id;
    83    if (FLAGS_hash_alg == "sha1") {
    84      hash_alg_id = TPM_ALG_SHA1;
    85    } else if (FLAGS_hash_alg == "sha256") {
    86      hash_alg_id = TPM_ALG_SHA256;
    87    } else {
    88      printf("Unknown hash algorithm\n");
    89      return 1;
    90    }
    91  
    92    GFLAGS_NS::ParseCommandLineFlags(&an, &av, true);
    93    if (FLAGS_endorsement_info_file == "") {
    94      printf("You must specify an endorsement output file\n");
    95      PrintOptions();
    96      return 1;
    97    }
    98  
    99    if (!tpm.OpenTpm("/dev/tpm0")) {
   100      printf("Can't open tpm\n");
   101      return 1;
   102    }
   103  
   104    primary_flags.fixedTPM = 1;
   105    primary_flags.fixedParent = 1;
   106    primary_flags.sensitiveDataOrigin = 1;
   107    primary_flags.userWithAuth = 1;
   108    primary_flags.decrypt = 1;
   109    primary_flags.restricted = 1;
   110  
   111    InitSinglePcrSelection(7, hash_alg_id, &pcrSelect);
   112    if (Tpm2_CreatePrimary(tpm, TPM_RH_ENDORSEMENT, emptyAuth, pcrSelect,
   113                           TPM_ALG_RSA, hash_alg_id, primary_flags,
   114                           TPM_ALG_AES, 128, TPM_ALG_CFB, TPM_ALG_NULL,
   115                           2048, 0x010001, &ekHandle, &pub_out)) {
   116      printf("CreatePrimary succeeded parent: %08x\n", ekHandle);
   117    } else {
   118      printf("CreatePrimary failed\n");
   119      ret_val = 1;
   120      goto done;
   121    }
   122    if (Tpm2_ReadPublic(tpm, ekHandle, &pub_blob_size, pub_blob,
   123                        &pub_out, &pub_name, &qualified_pub_name)) {
   124      printf("ReadPublic succeeded\n");
   125    } else {
   126      printf("ReadPublic failed\n");
   127      ret_val = 1;
   128      Tpm2_FlushContext(tpm, ekHandle);
   129      goto done;
   130    }
   131    Tpm2_FlushContext(tpm, ekHandle);
   132  
   133  #ifdef DEBUG
   134    printf("Public blob: ");
   135    PrintBytes(pub_blob_size, pub_blob);
   136    printf("\n");
   137    printf("Name: ");
   138    PrintBytes(pub_name.size, pub_name.name);
   139    printf("\n");
   140    printf("Qualified name: ");
   141    PrintBytes(qualified_pub_name.size, qualified_pub_name.name);
   142    printf("\n");
   143  #endif
   144  
   145    message.set_machine_identifier(FLAGS_machine_identifier);
   146    message.set_tpm2b_blob((const char*)pub_blob, (int)pub_blob_size);
   147    message.set_tpm2_name((const char*)pub_name.name, (int)pub_name.size);
   148  
   149    if (!message.SerializeToString(&output)) {
   150      printf("Can't serialize output\n");
   151      ret_val = 1;
   152      goto done;
   153    }
   154    if (!WriteFileFromBlock(FLAGS_endorsement_info_file, output.size(),
   155                            (byte*)output.data())) {
   156      printf("Can't write output file\n");
   157      ret_val = 1;
   158    }
   159  
   160  done:
   161    tpm.CloseTpm();
   162    return ret_val;
   163  }
   164