15679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// This file was extracted from the TCG Published
25679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Trusted Platform Module Library
35679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Part 3: Commands
45679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Family "2.0"
55679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Level 00 Revision 01.16
65679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// October 30, 2014
75679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
85679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "InternalRoutines.h"
95679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "Attest_spt_fp.h"
105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "NV_spt_fp.h"
115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury#include "NV_Certify_fp.h"
125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     Error Returns                     Meaning
155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_NV_AUTHORIZATION           the authorization was valid but the authorizing entity (authHandle) is
175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                       not allowed to read from the Index referenced by nvIndex
185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_KEY                        signHandle does not reference a signing key
195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_NV_LOCKED                  Index referenced by nvIndex is locked for reading
205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_NV_RANGE                   offset plus size extends outside of the data range of the Index
215679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//                                       referenced by nvIndex
225679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_NV_UNINITIALIZED           Index referenced by nvIndex has not been written
235679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//     TPM_RC_SCHEME                     inScheme is not an allowed value for the key definition
245679752bf24c21135884e987c4077e2f7184897Vadim Bendebury//
255679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM_RC
265679752bf24c21135884e987c4077e2f7184897Vadim BendeburyTPM2_NV_Certify(
275679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NV_Certify_In     *in,                 // IN: input parameter list
285679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NV_Certify_Out    *out                 // OUT: output parameter list
295679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   )
305679752bf24c21135884e987c4077e2f7184897Vadim Bendebury{
315679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPM_RC                    result;
325679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NV_INDEX                  nvIndex;
335679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   TPMS_ATTEST               certifyInfo;
345679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
355679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Attestation command may cause the orderlyState to be cleared due to
365679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // the reporting of clock info. If this is the case, check if NV is
375679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // available first
385679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(gp.orderlyState != SHUTDOWN_NONE)
395679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   {
405679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // The command needs NV update. Check if NV is available.
415679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at
425679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       // this point
435679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       result = NvIsAvailable();
445679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       if(result != TPM_RC_SUCCESS)
455679752bf24c21135884e987c4077e2f7184897Vadim Bendebury           return result;
465679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   }
475679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
485679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Input Validation
495679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
505679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Get NV index info
515679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   NvGetIndexInfo(in->nvIndex, &nvIndex);
525679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
535679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Common access checks. A TPM_RC_NV_AUTHORIZATION or TPM_RC_NV_LOCKED
545679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // error may be returned at this point
555679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   result = NvReadAccessChecks(in->authHandle, in->nvIndex);
565679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if(result != TPM_RC_SUCCESS)
575679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return result;
585679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
595679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // See if the range to be certified is out of the bounds of the defined
605679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   // Index
615679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   if((in->size + in->offset) > nvIndex.publicArea.dataSize)
625679752bf24c21135884e987c4077e2f7184897Vadim Bendebury       return TPM_RC_NV_RANGE;
635679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
645679752bf24c21135884e987c4077e2f7184897Vadim Bendebury// Command Output
655679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
665679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Filling in attest information
675679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Common fields
685679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // FillInAttestInfo can return TPM_RC_SCHEME or TPM_RC_KEY
695679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  result = FillInAttestInfo(in->signHandle,
705679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                            &in->inScheme,
715679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                            &in->qualifyingData,
725679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                            &certifyInfo);
735679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  if(result != TPM_RC_SUCCESS)
745679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  {
755679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      if(result == TPM_RC_KEY)
765679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          return TPM_RC_KEY + RC_NV_Certify_signHandle;
775679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      else
785679752bf24c21135884e987c4077e2f7184897Vadim Bendebury          return RcSafeAddToResult(result, RC_NV_Certify_inScheme);
795679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  }
805679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // NV certify specific fields
815679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Attestation type
825679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  certifyInfo.type = TPM_ST_ATTEST_NV;
835679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
845679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Get the name of the index
855679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  certifyInfo.attested.nv.indexName.t.size =
86e85c65bf85bc6251895cdfe6bb6213d125cc2366ChromeOS Developer      NvGetName(in->nvIndex, &certifyInfo.attested.nv.indexName.t.name);
875679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
885679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Set the return size
895679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  certifyInfo.attested.nv.nvContents.t.size = in->size;
905679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
915679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Set the offset
925679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  certifyInfo.attested.nv.offset = in->offset;
935679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
945679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Perform the read
955679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  NvGetIndexData(in->nvIndex, &nvIndex,
965679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 in->offset, in->size,
975679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                 certifyInfo.attested.nv.nvContents.t.buffer);
985679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
995679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Sign attestation structure. A NULL signature will be returned if
1005679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // signHandle is TPM_RH_NULL. SignAttestInfo() may return TPM_RC_VALUE,
1015679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // TPM_RC_SCHEME or TPM_RC_ATTRUBUTES.
1025679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // Note: SignAttestInfo may return TPM_RC_ATTRIBUTES if the key is not a
1035679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // signing key but that was checked above. TPM_RC_VALUE would mean that the
1045679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // data to sign is too large but the data to sign is a digest
1055679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  result = SignAttestInfo(in->signHandle,
1065679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                          &in->inScheme,
1075679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                          &certifyInfo,
1085679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                          &in->qualifyingData,
1095679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                          &out->certifyInfo,
1105679752bf24c21135884e987c4077e2f7184897Vadim Bendebury                          &out->signature);
1115679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  if(result != TPM_RC_SUCCESS)
1125679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      return result;
1135679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1145679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // orderly state should be cleared because of the reporting of clock info
1155679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  // if signing happens
1165679752bf24c21135884e987c4077e2f7184897Vadim Bendebury  if(in->signHandle != TPM_RH_NULL)
1175679752bf24c21135884e987c4077e2f7184897Vadim Bendebury      g_clearOrderly = TRUE;
1185679752bf24c21135884e987c4077e2f7184897Vadim Bendebury
1195679752bf24c21135884e987c4077e2f7184897Vadim Bendebury   return TPM_RC_SUCCESS;
1205679752bf24c21135884e987c4077e2f7184897Vadim Bendebury}
121