• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stefanberger / libtpms / #2067

11 Feb 2026 05:08PM UTC coverage: 77.231% (+0.04%) from 77.19%
#2067

push

travis-ci

web-flow
Merge 146cc2f44 into c2a8109f8

1 of 1 new or added line in 1 file covered. (100.0%)

823 existing lines in 23 files now uncovered.

36107 of 46752 relevant lines covered (77.23%)

125912.64 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.92
/src/tpm2/BackwardsCompatibilityBitArray.c
1
/********************************************************************************/
2
/*                                                                                */
3
/*        Backwards compatibility support related to command code arrays                */
4
/*                             Written by Stefan Berger                                */
5
/*                       IBM Thomas J. Watson Research Center                        */
6
/*                                                                                */
7
/* (c) Copyright IBM Corporation 2023.                                                */
8
/*                                                                                */
9
/* All rights reserved.                                                                */
10
/*                                                                                 */
11
/* Redistribution and use in source and binary forms, with or without                */
12
/* modification, are permitted provided that the following conditions are        */
13
/* met:                                                                                */
14
/*                                                                                 */
15
/* Redistributions of source code must retain the above copyright notice,        */
16
/* this list of conditions and the following disclaimer.                        */
17
/*                                                                                 */
18
/* Redistributions in binary form must reproduce the above copyright                */
19
/* notice, this list of conditions and the following disclaimer in the                */
20
/* documentation and/or other materials provided with the distribution.                */
21
/*                                                                                 */
22
/* Neither the names of the IBM Corporation nor the names of its                */
23
/* contributors may be used to endorse or promote products derived from                */
24
/* this software without specific prior written permission.                        */
25
/*                                                                                 */
26
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS                */
27
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT                */
28
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR        */
29
/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT                */
30
/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,        */
31
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT                */
32
/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,        */
33
/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY        */
34
/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT                */
35
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE        */
36
/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                */
37
/********************************************************************************/
38

39
#include <assert.h>
40

41
#include "BackwardsCompatibilityBitArray.h"
42

43
/* The following array contains exactly the commands that libtpms v0.9 had enabled
44
 * when 'compressed lists' were used. Do not change this array anymore!
45
 * A bit in the PERSISTEN_DATA.auditCommands array corresponds to the index in
46
 * this array where the command code can be found.
47
 */
48
static const struct {
49
    TPM_CC cc;
50

51
#define ENTRY(CC, INDEX)  \
52
    [INDEX] = { .cc = CC }
53

54
} CCToCompressedListIndex[] = {
55
    ENTRY(TPM_CC_NV_UndefineSpaceSpecial, 0),
56
    ENTRY(TPM_CC_EvictControl, 1),
57
    ENTRY(TPM_CC_HierarchyControl, 2),
58
    ENTRY(TPM_CC_NV_UndefineSpace, 3),
59
    ENTRY(TPM_CC_ChangeEPS, 4),
60
    ENTRY(TPM_CC_ChangePPS, 5),
61
    ENTRY(TPM_CC_Clear, 6),
62
    ENTRY(TPM_CC_ClearControl, 7),
63
    ENTRY(TPM_CC_ClockSet, 8),
64
    ENTRY(TPM_CC_HierarchyChangeAuth, 9),
65
    ENTRY(TPM_CC_NV_DefineSpace, 10),
66
    ENTRY(TPM_CC_PCR_Allocate, 11),
67
    ENTRY(TPM_CC_PCR_SetAuthPolicy, 12),
68
    ENTRY(TPM_CC_PP_Commands, 13),
69
    ENTRY(TPM_CC_SetPrimaryPolicy, 14),
70
    /* CC_FieldUpdateStart */
71
    ENTRY(TPM_CC_ClockRateAdjust, 15),
72
    ENTRY(TPM_CC_CreatePrimary, 16),
73
    ENTRY(TPM_CC_NV_GlobalWriteLock, 17),
74
    ENTRY(TPM_CC_GetCommandAuditDigest, 18),
75
    ENTRY(TPM_CC_NV_Increment, 19),
76
    ENTRY(TPM_CC_NV_SetBits, 20),
77
    ENTRY(TPM_CC_NV_Extend, 21),
78
    ENTRY(TPM_CC_NV_Write, 22),
79
    ENTRY(TPM_CC_NV_WriteLock, 23),
80
    ENTRY(TPM_CC_DictionaryAttackLockReset, 24),
81
    ENTRY(TPM_CC_DictionaryAttackParameters, 25),
82
    ENTRY(TPM_CC_NV_ChangeAuth, 26),
83
    ENTRY(TPM_CC_PCR_Event, 27),
84
    ENTRY(TPM_CC_PCR_Reset, 28),
85
    ENTRY(TPM_CC_SequenceComplete, 29),
86
    ENTRY(TPM_CC_SetAlgorithmSet, 30),
87
    ENTRY(TPM_CC_SetCommandCodeAuditStatus, 31),
88
    /* CC_FieldUpgradeData */
89
    ENTRY(TPM_CC_IncrementalSelfTest, 32),
90
    ENTRY(TPM_CC_SelfTest, 33),
91
    ENTRY(TPM_CC_Startup, 34),
92
    ENTRY(TPM_CC_Shutdown, 35),
93
    ENTRY(TPM_CC_StirRandom, 36),
94
    ENTRY(TPM_CC_ActivateCredential, 37),
95
    ENTRY(TPM_CC_Certify, 38),
96
    ENTRY(TPM_CC_PolicyNV, 39),
97
    ENTRY(TPM_CC_CertifyCreation, 40),
98
    ENTRY(TPM_CC_Duplicate, 41),
99
    ENTRY(TPM_CC_GetTime, 42),
100
    ENTRY(TPM_CC_GetSessionAuditDigest, 43),
101
    ENTRY(TPM_CC_NV_Read, 44),
102
    ENTRY(TPM_CC_NV_ReadLock, 45),
103
    ENTRY(TPM_CC_ObjectChangeAuth, 46),
104
    ENTRY(TPM_CC_PolicySecret, 47),
105
    ENTRY(TPM_CC_Rewrap, 48),
106
    ENTRY(TPM_CC_Create, 49),
107
    ENTRY(TPM_CC_ECDH_ZGen, 50),
108
    ENTRY(TPM_CC_HMAC, 51),
109
    ENTRY(TPM_CC_Import, 52),
110
    ENTRY(TPM_CC_Load, 53),
111
    ENTRY(TPM_CC_Quote, 54),
112
    ENTRY(TPM_CC_RSA_Decrypt, 55),
113
    ENTRY(TPM_CC_HMAC_Start, 56),
114
    ENTRY(TPM_CC_SequenceUpdate, 57),
115
    ENTRY(TPM_CC_Sign, 58),
116
    ENTRY(TPM_CC_Unseal, 59),
117
    ENTRY(TPM_CC_PolicySigned, 60),
118
    ENTRY(TPM_CC_ContextLoad, 61),
119
    ENTRY(TPM_CC_ContextSave, 62),
120
    ENTRY(TPM_CC_ECDH_KeyGen, 63),
121
    ENTRY(TPM_CC_EncryptDecrypt, 64),
122
    ENTRY(TPM_CC_FlushContext, 65),
123
    ENTRY(TPM_CC_LoadExternal, 66),
124
    ENTRY(TPM_CC_MakeCredential, 67),
125
    ENTRY(TPM_CC_NV_ReadPublic, 68),
126
    ENTRY(TPM_CC_PolicyAuthorize, 69),
127
    ENTRY(TPM_CC_PolicyAuthValue, 70),
128
    ENTRY(TPM_CC_PolicyCommandCode, 71),
129
    ENTRY(TPM_CC_PolicyCounterTimer, 72),
130
    ENTRY(TPM_CC_PolicyCpHash, 73),
131
    ENTRY(TPM_CC_PolicyLocality, 74),
132
    ENTRY(TPM_CC_PolicyNameHash, 75),
133
    ENTRY(TPM_CC_PolicyOR, 76),
134
    ENTRY(TPM_CC_PolicyTicket, 77),
135
    ENTRY(TPM_CC_ReadPublic, 78),
136
    ENTRY(TPM_CC_RSA_Encrypt, 79),
137
    ENTRY(TPM_CC_StartAuthSession, 80),
138
    ENTRY(TPM_CC_VerifySignature, 81),
139
    ENTRY(TPM_CC_ECC_Parameters, 82),
140
    /* CC_FirmwareRead */
141
    ENTRY(TPM_CC_GetCapability, 83),
142
    ENTRY(TPM_CC_GetRandom, 84),
143
    ENTRY(TPM_CC_GetTestResult, 85),
144
    ENTRY(TPM_CC_Hash, 86),
145
    ENTRY(TPM_CC_PCR_Read, 87),
146
    ENTRY(TPM_CC_PolicyPCR, 88),
147
    ENTRY(TPM_CC_PolicyRestart, 89),
148
    ENTRY(TPM_CC_ReadClock, 90),
149
    ENTRY(TPM_CC_PCR_Extend, 91),
150
    ENTRY(TPM_CC_PCR_SetAuthValue, 92),
151
    ENTRY(TPM_CC_NV_Certify, 93),
152
    ENTRY(TPM_CC_EventSequenceComplete, 94),
153
    ENTRY(TPM_CC_HashSequenceStart, 95),
154
    ENTRY(TPM_CC_PolicyPhysicalPresence, 96),
155
    ENTRY(TPM_CC_PolicyDuplicationSelect, 97),
156
    ENTRY(TPM_CC_PolicyGetDigest, 98),
157
    ENTRY(TPM_CC_TestParms, 99),
158
    ENTRY(TPM_CC_Commit, 100),
159
    ENTRY(TPM_CC_PolicyPassword, 101),
160
    ENTRY(TPM_CC_ZGen_2Phase, 102),
161
    ENTRY(TPM_CC_EC_Ephemeral, 103),
162
    ENTRY(TPM_CC_PolicyNvWritten, 104),
163
    ENTRY(TPM_CC_PolicyTemplate, 105),
164
    ENTRY(TPM_CC_CreateLoaded, 106),
165
    ENTRY(TPM_CC_PolicyAuthorizeNV, 107),
166
    ENTRY(TPM_CC_EncryptDecrypt2, 108),
167
    /* CC_AC_GetCapability -- never enable here */
168
    /* CC_AC_Send -- never enable here */
169
    /* CC_Policy_AC_SendSelect */
170
    ENTRY(TPM_CC_CertifyX509, 109),
171
    /* CC_ACT_SetTimeout -- never enable here */
172
    /* CC_ECC_Encrypt -- never enable here */
173
    /* CC_ECC_Decrypt -- never enable here */
174
    /* never add new commands */
175
};
176

177
/* Convert from a bit array from the time when COMPRESSED_LIST was YES
178
 * to an array where the indices do NOT correspond to a COMPRESSED_LIST.
179
 */
180
TPM_RC
181
ConvertFromCompressedBitArray(BYTE         *inAuditCommands,
32,208✔
182
                              size_t        inAuditCommandsLen,
183
                              BYTE         *outAuditCommands,
184
                              size_t        outAuditCommandsLen)
185
{
186
    size_t max_bit = MIN(inAuditCommandsLen * 8, ARRAY_SIZE(CCToCompressedListIndex));
32,208✔
187
    size_t bit = 0;
32,208✔
188

189
    MemorySet(outAuditCommands, 0, outAuditCommandsLen);
32,208✔
190

191
    while (bit < max_bit) {
483,120✔
192
        BYTE bits = inAuditCommands[bit >> 3];
450,912✔
193
        BYTE mask = 1;
450,912✔
194
        size_t lbit = bit;
450,912✔
195

196
        while (bits != 0 && lbit < max_bit) {
676,368✔
197
            if ((bits & mask) != 0) {
225,456✔
198
                TPM_CC cc = CCToCompressedListIndex[lbit].cc;
32,208✔
199
                COMMAND_INDEX idx = cc - TPM_CC_NV_UndefineSpaceSpecial;
32,208✔
200

201
                assert(idx != UNIMPLEMENTED_COMMAND_INDEX);
32,208✔
202

203
                SetBit(idx, outAuditCommands, outAuditCommandsLen);
32,208✔
204
                bits ^= mask; /* unset bit */
32,208✔
205
            }
206
            mask <<= 1;
225,456✔
207
            lbit++;
225,456✔
208
        }
209
        bit += 8;
450,912✔
210
    }
211

212
    return TPM_RC_SUCCESS;
32,208✔
213
}
214

215
static size_t FindCCInCompressedListIndexArray(TPM_CC cc)
35,818✔
216
{
217
    size_t e_index = ARRAY_SIZE(CCToCompressedListIndex) - 1;
35,818✔
218
    size_t s_index = 0;
35,818✔
219

220
    while (true) {
161,181✔
221
        size_t index = (e_index + s_index) >> 1;
161,181✔
222

223
        if (cc == CCToCompressedListIndex[index].cc) {
161,181✔
224
            return index;
35,818✔
225
        }
226
        if (e_index == s_index) {
125,363✔
227
            break;
228
        }
229
        if (cc < CCToCompressedListIndex[index].cc) {
125,363✔
230
            e_index = index;
231
        } else {
232
            if (s_index != index)
35,818✔
233
                s_index = index;
234
            else
UNCOV
235
                s_index++;
×
236
        }
237
    }
238
    /* entry must have been found */
UNCOV
239
    pAssert(false);
×
240
}
241

242
/* Convert to a bit array from the time when COMPRESSED_LIST was YES
243
 * from an array where the indices do NOT correspond to a COMPRESSED_LIST.
244
 */
245
TPM_RC
246
ConvertToCompressedBitArray(BYTE         *inAuditCommands,
35,818✔
247
                            size_t        inAuditCommandsLen,
248
                            BYTE         *outAuditCommands,
249
                            size_t        outAuditCommandsLen)
250
{
251
    size_t max_idx = inAuditCommandsLen * 8;
35,818✔
252
    size_t idx = 0;
35,818✔
253

254
    MemorySet(outAuditCommands, 0, outAuditCommandsLen);
35,818✔
255

256
    while (idx < max_idx) {
644,724✔
257
        BYTE bits = inAuditCommands[idx >> 3];
608,906✔
258
        BYTE mask = 1;
608,906✔
259
        size_t lidx = idx;
608,906✔
260

261
        /* handle bits set in one byte in the loop */
262
        while (bits != 0 && lidx < max_idx) {
770,087✔
263
            if ((bits & mask) != 0) {
161,181✔
264
                TPM_CC cc = lidx + TPM_CC_NV_UndefineSpaceSpecial;
35,818✔
265
                size_t bit = FindCCInCompressedListIndexArray(cc);
35,818✔
266

267
                SetBit(bit, outAuditCommands, outAuditCommandsLen);
35,818✔
268
                bits ^= mask; /* unset bit */
35,818✔
269
            }
270
            mask <<= 1;
161,181✔
271
            lidx++;
161,181✔
272
        }
273
        idx += 8;
608,906✔
274
    }
275

276
    return TPM_RC_SUCCESS;
35,818✔
277
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc