/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 | } |