Home | History | Annotate | Download | only in tpm2
      1 // This file was extracted from the TCG Published
      2 // Trusted Platform Module Library
      3 // Part 3: Commands
      4 // Family "2.0"
      5 // Level 00 Revision 01.16
      6 // October 30, 2014
      7 
      8 #include "InternalRoutines.h"
      9 #include "Attest_spt_fp.h"
     10 #include "Quote_fp.h"
     11 //
     12 //
     13 //     Error Returns               Meaning
     14 //
     15 //     TPM_RC_KEY                  signHandle does not reference a signing key;
     16 //     TPM_RC_SCHEME               the scheme is not compatible with sign key type, or input scheme is
     17 //                                 not compatible with default scheme, or the chosen scheme is not a
     18 //                                 valid sign scheme
     19 //
     20 TPM_RC
     21 TPM2_Quote(
     22    Quote_In        *in,             // IN: input parameter list
     23    Quote_Out       *out             // OUT: output parameter list
     24    )
     25 {
     26    TPM_RC                  result;
     27    TPMI_ALG_HASH           hashAlg;
     28    TPMS_ATTEST             quoted;
     29 
     30 // Command Output
     31 
     32    // Filling in attest information
     33    // Common fields
     34    // FillInAttestInfo may return TPM_RC_SCHEME or TPM_RC_KEY
     35    result = FillInAttestInfo(in->signHandle,
     36                              &in->inScheme,
     37                              &in->qualifyingData,
     38                              &quoted);
     39    if(result != TPM_RC_SUCCESS)
     40    {
     41        if(result == TPM_RC_KEY)
     42            return TPM_RC_KEY + RC_Quote_signHandle;
     43        else
     44            return RcSafeAddToResult(result, RC_Quote_inScheme);
     45    }
     46 
     47    // Quote specific fields
     48    // Attestation type
     49    quoted.type = TPM_ST_ATTEST_QUOTE;
     50 
     51    // Get hash algorithm in sign scheme. This hash algorithm is used to
     52    // compute PCR digest. If there is no algorithm, then the PCR cannot
     53    // be digested and this command returns TPM_RC_SCHEME
     54    hashAlg = in->inScheme.details.any.hashAlg;
     55 
     56    if(hashAlg == TPM_ALG_NULL)
     57        return TPM_RC_SCHEME + RC_Quote_inScheme;
     58 
     59    // Compute PCR digest
     60    PCRComputeCurrentDigest(hashAlg,
     61                            &in->PCRselect,
     62                            &quoted.attested.quote.pcrDigest);
     63 
     64    // Copy PCR select. "PCRselect" is modified in PCRComputeCurrentDigest
     65    // function
     66    quoted.attested.quote.pcrSelect = in->PCRselect;
     67 
     68    // Sign attestation structure. A NULL signature will be returned if
     69    // signHandle is TPM_RH_NULL. TPM_RC_VALUE, TPM_RC_SCHEME or TPM_RC_ATTRIBUTES
     70    // error may be returned by SignAttestInfo.
     71    // NOTE: TPM_RC_ATTRIBUTES means that the key is not a signing key but that
     72    // was checked above and TPM_RC_KEY was returned. TPM_RC_VALUE means that the
     73    // value to sign is too large but that means that the digest is too big and
     74    // that can't happen.
     75    result = SignAttestInfo(in->signHandle,
     76                            &in->inScheme,
     77                            &quoted,
     78                            &in->qualifyingData,
     79                            &out->quoted,
     80                            &out->signature);
     81    if(result != TPM_RC_SUCCESS)
     82        return result;
     83 
     84    // orderly state should be cleared because of the reporting of clock info
     85    // if signing happens
     86    if(in->signHandle != TPM_RH_NULL)
     87        g_clearOrderly = TRUE;
     88 
     89    return TPM_RC_SUCCESS;
     90 }
     91