Coverage Report

Created: 2025-07-18 06:04

/src/tpm2/NV_Certify.c
Line
Count
Source (jump to first uncovered line)
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
0
{
31
0
   TPM_RC                    result;
32
0
   NV_INDEX                  nvIndex;
33
0
   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
0
   if(gp.orderlyState != SHUTDOWN_NONE)
39
0
   {
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
0
       result = NvIsAvailable();
44
0
       if(result != TPM_RC_SUCCESS)
45
0
           return result;
46
0
   }
47
48
// Input Validation
49
50
   // Get NV index info
51
0
   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
0
   result = NvReadAccessChecks(in->authHandle, in->nvIndex);
56
0
   if(result != TPM_RC_SUCCESS)
57
0
       return result;
58
59
    // make sure that the selection is within the range of the Index (cast to avoid
60
    // any wrap issues with addition)
61
0
    if((UINT32)in->size + (UINT32)in->offset > (UINT32)nvIndex.publicArea.dataSize)
62
0
        return TPM_RC_NV_RANGE;
63
64
    // Make sure the data will fit the return buffer.
65
    // NOTE: This check may be modified if the output buffer will not hold the
66
    // maximum sized NV buffer as part of the certified data. The difference in
67
    // size could be substantial if the signature scheme was produced a large
68
    // signature (e.g., RSA 4096).
69
0
    if(in->size > MAX_NV_BUFFER_SIZE)
70
0
        return TPM_RC_VALUE + RC_NV_Certify_size;
71
72
73
// Command Output
74
75
  // Filling in attest information
76
  // Common fields
77
  // FillInAttestInfo can return TPM_RC_SCHEME or TPM_RC_KEY
78
0
  result = FillInAttestInfo(in->signHandle,
79
0
                            &in->inScheme,
80
0
                            &in->qualifyingData,
81
0
                            &certifyInfo);
82
0
  if(result != TPM_RC_SUCCESS)
83
0
  {
84
0
      if(result == TPM_RC_KEY)
85
0
          return TPM_RC_KEY + RC_NV_Certify_signHandle;
86
0
      else
87
0
          return RcSafeAddToResult(result, RC_NV_Certify_inScheme);
88
0
  }
89
  // NV certify specific fields
90
  // Attestation type
91
0
  certifyInfo.type = TPM_ST_ATTEST_NV;
92
93
  // Get the name of the index
94
0
  certifyInfo.attested.nv.indexName.t.size =
95
0
      NvGetName(in->nvIndex, &certifyInfo.attested.nv.indexName.t.name);
96
97
  // Set the return size
98
0
  certifyInfo.attested.nv.nvContents.t.size = in->size;
99
100
  // Set the offset
101
0
  certifyInfo.attested.nv.offset = in->offset;
102
103
  // Perform the read
104
0
  NvGetIndexData(in->nvIndex, &nvIndex,
105
0
                 in->offset, in->size,
106
0
                 certifyInfo.attested.nv.nvContents.t.buffer);
107
108
  // Sign attestation structure. A NULL signature will be returned if
109
  // signHandle is TPM_RH_NULL. SignAttestInfo() may return TPM_RC_VALUE,
110
  // TPM_RC_SCHEME or TPM_RC_ATTRUBUTES.
111
  // Note: SignAttestInfo may return TPM_RC_ATTRIBUTES if the key is not a
112
  // signing key but that was checked above. TPM_RC_VALUE would mean that the
113
  // data to sign is too large but the data to sign is a digest
114
0
  result = SignAttestInfo(in->signHandle,
115
0
                          &in->inScheme,
116
0
                          &certifyInfo,
117
0
                          &in->qualifyingData,
118
0
                          &out->certifyInfo,
119
0
                          &out->signature);
120
0
  if(result != TPM_RC_SUCCESS)
121
0
      return result;
122
123
  // orderly state should be cleared because of the reporting of clock info
124
  // if signing happens
125
0
  if(in->signHandle != TPM_RH_NULL)
126
0
      g_clearOrderly = TRUE;
127
128
0
   return TPM_RC_SUCCESS;
129
0
}