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 "NV_spt_fp.h" 11 #include "NV_Certify_fp.h" 12 // 13 // 14 // Error Returns Meaning 15 // 16 // TPM_RC_NV_AUTHORIZATION the authorization was valid but the authorizing entity (authHandle) is 17 // not allowed to read from the Index referenced by nvIndex 18 // TPM_RC_KEY signHandle does not reference a signing key 19 // TPM_RC_NV_LOCKED Index referenced by nvIndex is locked for reading 20 // TPM_RC_NV_RANGE offset plus size extends outside of the data range of the Index 21 // referenced by nvIndex 22 // TPM_RC_NV_UNINITIALIZED Index referenced by nvIndex has not been written 23 // TPM_RC_SCHEME inScheme is not an allowed value for the key definition 24 // 25 TPM_RC 26 TPM2_NV_Certify( 27 NV_Certify_In *in, // IN: input parameter list 28 NV_Certify_Out *out // OUT: output parameter list 29 ) 30 { 31 TPM_RC result; 32 NV_INDEX nvIndex; 33 TPMS_ATTEST certifyInfo; 34 35 // Attestation command may cause the orderlyState to be cleared due to 36 // the reporting of clock info. If this is the case, check if NV is 37 // available first 38 if(gp.orderlyState != SHUTDOWN_NONE) 39 { 40 // The command needs NV update. Check if NV is available. 41 // A TPM_RC_NV_UNAVAILABLE or TPM_RC_NV_RATE error may be returned at 42 // this point 43 result = NvIsAvailable(); 44 if(result != TPM_RC_SUCCESS) 45 return result; 46 } 47 48 // Input Validation 49 50 // Get NV index info 51 NvGetIndexInfo(in->nvIndex, &nvIndex); 52 53 // Common access checks. A TPM_RC_NV_AUTHORIZATION or TPM_RC_NV_LOCKED 54 // error may be returned at this point 55 result = NvReadAccessChecks(in->authHandle, in->nvIndex); 56 if(result != TPM_RC_SUCCESS) 57 return result; 58 59 // See if the range to be certified is out of the bounds of the defined 60 // Index 61 if((in->size + in->offset) > nvIndex.publicArea.dataSize) 62 return TPM_RC_NV_RANGE; 63 64 // Command Output 65 66 // Filling in attest information 67 // Common fields 68 // FillInAttestInfo can return TPM_RC_SCHEME or TPM_RC_KEY 69 result = FillInAttestInfo(in->signHandle, 70 &in->inScheme, 71 &in->qualifyingData, 72 &certifyInfo); 73 if(result != TPM_RC_SUCCESS) 74 { 75 if(result == TPM_RC_KEY) 76 return TPM_RC_KEY + RC_NV_Certify_signHandle; 77 else 78 return RcSafeAddToResult(result, RC_NV_Certify_inScheme); 79 } 80 // NV certify specific fields 81 // Attestation type 82 certifyInfo.type = TPM_ST_ATTEST_NV; 83 84 // Get the name of the index 85 certifyInfo.attested.nv.indexName.t.size = 86 NvGetName(in->nvIndex, &certifyInfo.attested.nv.indexName.t.name); 87 88 // Set the return size 89 certifyInfo.attested.nv.nvContents.t.size = in->size; 90 91 // Set the offset 92 certifyInfo.attested.nv.offset = in->offset; 93 94 // Perform the read 95 NvGetIndexData(in->nvIndex, &nvIndex, 96 in->offset, in->size, 97 certifyInfo.attested.nv.nvContents.t.buffer); 98 99 // Sign attestation structure. A NULL signature will be returned if 100 // signHandle is TPM_RH_NULL. SignAttestInfo() may return TPM_RC_VALUE, 101 // TPM_RC_SCHEME or TPM_RC_ATTRUBUTES. 102 // Note: SignAttestInfo may return TPM_RC_ATTRIBUTES if the key is not a 103 // signing key but that was checked above. TPM_RC_VALUE would mean that the 104 // data to sign is too large but the data to sign is a digest 105 result = SignAttestInfo(in->signHandle, 106 &in->inScheme, 107 &certifyInfo, 108 &in->qualifyingData, 109 &out->certifyInfo, 110 &out->signature); 111 if(result != TPM_RC_SUCCESS) 112 return result; 113 114 // orderly state should be cleared because of the reporting of clock info 115 // if signing happens 116 if(in->signHandle != TPM_RH_NULL) 117 g_clearOrderly = TRUE; 118 119 return TPM_RC_SUCCESS; 120 } 121