Coverage Report

Created: 2025-08-29 07:01

/src/libtpms/src/tpm2/RuntimeAttributes.c
Line
Count
Source (jump to first uncovered line)
1
/********************************************************************************/
2
/*                    */
3
/*              Runtime Attributes        */
4
/*           Written by Stefan Berger       */
5
/*           IBM Thomas J. Watson Research Center     */
6
/*                    */
7
/*  Licenses and Notices              */
8
/*                    */
9
/*  (c) Copyright IBM Corporation, 2023           */
10
/*                    */
11
/* All rights reserved.               */
12
/*                    */
13
/* Redistribution and use in source and binary forms, with or without   */
14
/* modification, are permitted provided that the following conditions are */
15
/* met:                   */
16
/*                    */
17
/* Redistributions of source code must retain the above copyright notice, */
18
/* this list of conditions and the following disclaimer.      */
19
/*                    */
20
/* Redistributions in binary form must reproduce the above copyright    */
21
/* notice, this list of conditions and the following disclaimer in the    */
22
/* documentation and/or other materials provided with the distribution.   */
23
/*                    */
24
/* Neither the names of the IBM Corporation nor the names of its    */
25
/* contributors may be used to endorse or promote products derived from   */
26
/* this software without specific prior written permission.     */
27
/*                    */
28
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS    */
29
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    */
30
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR  */
31
/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT   */
32
/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
33
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT   */
34
/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  */
35
/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY  */
36
/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT    */
37
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  */
38
/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.   */
39
/*                    */
40
/********************************************************************************/
41
42
#define _GNU_SOURCE
43
#include <assert.h>
44
#include <string.h>
45
46
#include "Tpm.h"
47
#include "tpm_library_intern.h"
48
49
0
#define ATTR_SEPARATOR_C ','
50
0
#define ATTR_SEPARATOR_STR ","
51
52
static const struct {
53
    const char   *name;
54
    unsigned int  attributeFlags;
55
    unsigned int  stateFormatLevel;
56
    /* all of them can be disabled */
57
} s_AttributeProperties[NUM_ENTRIES_ATTRIBUTE_PROPERTIES] = {
58
#define ATTRIBUTE(NAME, FLAGS, SFL) \
59
    { .name = NAME, .attributeFlags = FLAGS, .stateFormatLevel = SFL }
60
    ATTRIBUTE("no-unpadded-encryption", RUNTIME_ATTRIBUTE_NO_UNPADDED_ENCRYPTION,
61
        7),
62
    ATTRIBUTE("no-sha1-signing", RUNTIME_ATTRIBUTE_NO_SHA1_SIGNING,
63
        7),
64
    ATTRIBUTE("no-sha1-verification", RUNTIME_ATTRIBUTE_NO_SHA1_VERIFICATION,
65
        7),
66
    ATTRIBUTE("no-sha1-hmac-creation", RUNTIME_ATTRIBUTE_NO_SHA1_HMAC_CREATION,
67
        7),
68
    ATTRIBUTE("no-sha1-hmac-verification", RUNTIME_ATTRIBUTE_NO_SHA1_HMAC_VERIFICATION,
69
        7),
70
    ATTRIBUTE("no-sha1-hmac", RUNTIME_ATTRIBUTE_NO_SHA1_HMAC_VERIFICATION |
71
                              RUNTIME_ATTRIBUTE_NO_SHA1_HMAC_CREATION,
72
        7),
73
    ATTRIBUTE("fips-host", RUNTIME_ATTRIBUTE_NO_UNPADDED_ENCRYPTION |
74
         RUNTIME_ATTRIBUTE_NO_SHA1_SIGNING |
75
         RUNTIME_ATTRIBUTE_NO_SHA1_VERIFICATION,
76
        7),
77
    ATTRIBUTE("drbg-continous-test", RUNTIME_ATTRIBUTE_DRBG_CONTINOUS_TEST,
78
        7),
79
    ATTRIBUTE("pct", RUNTIME_ATTRIBUTE_PAIRWISE_CONSISTENCY_TEST,
80
              7),
81
    ATTRIBUTE("no-ecc-key-derivation", RUNTIME_ATTRIBUTE_NO_ECC_KEY_DERIVATION,
82
        7),
83
};
84
85
LIB_EXPORT void
86
RuntimeAttributesFree(struct RuntimeAttributes *RuntimeAttributes)
87
86.8k
{
88
86.8k
    free(RuntimeAttributes->attributesProfile);
89
86.8k
    RuntimeAttributes->attributesProfile = NULL;
90
86.8k
}
91
92
LIB_EXPORT void
93
RuntimeAttributesInit(struct RuntimeAttributes *RuntimeAttributes)
94
72.3k
{
95
72.3k
    RuntimeAttributes->attributeFlags = 0;
96
72.3k
    MemorySet(RuntimeAttributes->enabledAttributesPrint, 0, sizeof(RuntimeAttributes->enabledAttributesPrint));
97
72.3k
    RuntimeAttributesFree(RuntimeAttributes);
98
72.3k
}
99
100
LIB_EXPORT TPM_RC
101
RuntimeAttributesSetProfile(struct RuntimeAttributes *RuntimeAttributes,
102
          const char         *newProfile,   // IN: colon-separated list of algorithm names
103
          unsigned int             *stateFormatLevel,   // IN/OUT: stateFormatLevel
104
          unsigned int              maxStateFormatLevel // IN: maximum allowed stateFormatLevel
105
          )
106
65.1k
{
107
65.1k
    TPM_RC retVal = TPM_RC_SUCCESS;
108
65.1k
    size_t toklen, idx, cmplen;
109
65.1k
    const char *token, *comma;
110
65.1k
    bool found;
111
112
65.1k
    RuntimeAttributesInit(RuntimeAttributes);
113
114
    /* NULL pointer for profile or empty profiles enables nothing */
115
65.1k
    if (!newProfile || strlen(newProfile) == 0)
116
65.1k
  return TPM_RC_SUCCESS;
117
118
0
    token = newProfile;
119
0
    while (1) {
120
0
  comma = strchr(token, ATTR_SEPARATOR_C);
121
0
  if (comma)
122
0
      toklen = (size_t)(comma - token);
123
0
  else
124
0
      toklen = strlen(token);
125
126
0
  found = false;
127
0
  for (idx = 0; idx < ARRAY_SIZE(s_AttributeProperties); idx++) {
128
0
      cmplen = MAX(strlen(s_AttributeProperties[idx].name), toklen);
129
0
      if (!strncmp(token, s_AttributeProperties[idx].name, cmplen)) {
130
0
    if (s_AttributeProperties[idx].stateFormatLevel > maxStateFormatLevel) {
131
0
        TPMLIB_LogTPM2Error("Requested attribute %.*s requires StateFormatLevel %u but maximum allowed is %u.\n",
132
0
          (int)toklen, token,
133
0
          s_AttributeProperties[idx].stateFormatLevel,
134
0
          maxStateFormatLevel);
135
0
        retVal = TPM_RC_VALUE;
136
0
        goto exit;
137
0
    }
138
0
    SET_BIT(idx, RuntimeAttributes->enabledAttributesPrint);
139
0
    RuntimeAttributes->attributeFlags |= s_AttributeProperties[idx].attributeFlags;
140
0
    assert(s_AttributeProperties[idx].stateFormatLevel > 0);
141
0
    *stateFormatLevel = MAX(*stateFormatLevel,
142
0
          s_AttributeProperties[idx].stateFormatLevel);
143
0
    found = true;
144
0
    break;
145
0
      }
146
0
  }
147
148
0
  if (!found) {
149
0
      TPMLIB_LogTPM2Error("Requested attribute %.*s is not supported.\n",
150
0
        (int)toklen, token);
151
0
      retVal = TPM_RC_FAILURE;
152
0
      goto exit;
153
0
  }
154
155
0
  if (!comma)
156
0
      break;
157
0
  token = &comma[1];
158
0
    }
159
160
0
    free(RuntimeAttributes->attributesProfile);
161
0
    RuntimeAttributes->attributesProfile = strdup(newProfile);
162
0
    if (!RuntimeAttributes->attributesProfile)
163
0
  retVal = TPM_RC_MEMORY;
164
165
0
exit:
166
0
    if (retVal != TPM_RC_SUCCESS)
167
0
  RuntimeAttributesInit(RuntimeAttributes);
168
169
0
    return retVal;
170
0
}
171
172
LIB_EXPORT TPM_RC
173
RuntimeAttributesSwitchProfile(struct RuntimeAttributes *RuntimeAttributes,
174
             const char               *newProfile,
175
             unsigned int              maxStateFormatLevel,
176
             char                    **oldProfile)
177
0
{
178
0
    TPM_RC retVal;
179
0
    unsigned int stateFormatLevel = 0; // ignored
180
181
0
    *oldProfile = RuntimeAttributes->attributesProfile;
182
0
    RuntimeAttributes->attributesProfile = NULL;
183
184
0
    retVal = RuntimeAttributesSetProfile(RuntimeAttributes, newProfile,
185
0
           &stateFormatLevel, maxStateFormatLevel);
186
0
    if (retVal != TPM_RC_SUCCESS) {
187
0
  RuntimeAttributesSetProfile(RuntimeAttributes, *oldProfile,
188
0
            &stateFormatLevel, maxStateFormatLevel);
189
0
  *oldProfile = NULL;
190
0
    }
191
0
    return retVal;
192
0
}
193
194
LIB_EXPORT char *
195
RuntimeAttributesGet(struct RuntimeAttributes   *RuntimeAttributes,
196
         enum RuntimeAttributeType  rat)
197
0
{
198
0
    char *buffer, *nbuffer = NULL;
199
0
    bool first = true;
200
0
    size_t idx;
201
0
    int n;
202
203
0
    buffer = strdup("\"");
204
0
    if (!buffer)
205
0
  return NULL;
206
207
0
    for (idx = 0; idx < ARRAY_SIZE(s_AttributeProperties); idx++) {
208
0
  switch (rat) {
209
0
  case RUNTIME_ATTR_IMPLEMENTED:
210
      // no filter
211
0
      break;
212
0
  case RUNTIME_ATTR_CAN_BE_DISABLED:
213
      // all of them can be disabled
214
0
      break;
215
0
  case RUNTIME_ATTR_ENABLED:
216
      // skip over disabled ones
217
0
      if (!TEST_BIT(idx, RuntimeAttributes->enabledAttributesPrint))
218
0
    continue;
219
0
      break;
220
0
  case RUNTIME_ATTR_DISABLED:
221
      // skip over enabled ones
222
0
      if (TEST_BIT(idx, RuntimeAttributes->enabledAttributesPrint))
223
0
    continue;
224
0
      break;
225
0
  default:
226
0
      continue;
227
0
  }
228
0
  n = asprintf(&nbuffer, "%s%s%s",
229
0
         buffer ? buffer : "",
230
0
         first ? "" : ATTR_SEPARATOR_STR,
231
0
         s_AttributeProperties[idx].name);
232
0
  free(buffer);
233
0
  if (n < 0)
234
0
       return NULL;
235
236
0
  buffer = nbuffer;
237
0
  first = false;
238
0
    }
239
240
0
    n = asprintf(&nbuffer, "%s\"", buffer);
241
0
    free(buffer);
242
0
    if (n < 0)
243
0
        return NULL;
244
245
0
    return nbuffer;
246
0
}
247
248
LIB_EXPORT BOOL
249
RuntimeAttributeCheckRequired(struct RuntimeAttributes *RuntimeAttributes,
250
            unsigned int              attributeFlags)
251
377k
{
252
377k
    return (RuntimeAttributes->attributeFlags & attributeFlags) == attributeFlags;
253
377k
}