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

stefanberger / libtpms / #2066

11 Feb 2026 04:23PM UTC coverage: 77.19% (+0.002%) from 77.188%
#2066

push

travis-ci

web-flow
Merge 4b1bba735 into c2a8109f8

1174 of 1370 new or added lines in 95 files covered. (85.69%)

2185 existing lines in 87 files now uncovered.

36352 of 47094 relevant lines covered (77.19%)

125371.74 hits per line

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

95.92
/src/tpm2/BackwardsCompatibilityBitArray.c
1
// SPDX-License-Identifier: BSD-2-Clause
2

3
// (c) Copyright IBM Corporation 2023.
4

5
#include <assert.h>
6

7
#include "BackwardsCompatibilityBitArray.h"
8

9
/* The following array contains exactly the commands that libtpms v0.9 had enabled
10
 * when 'compressed lists' were used. Do not change this array anymore!
11
 * A bit in the PERSISTEN_DATA.auditCommands array corresponds to the index in
12
 * this array where the command code can be found.
13
 */
14
static const struct {
15
    TPM_CC cc;
16

17
#define ENTRY(CC, INDEX)  \
18
    [INDEX] = { .cc = CC }
19

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

143
/* Convert from a bit array from the time when COMPRESSED_LIST was YES
144
 * to an array where the indices do NOT correspond to a COMPRESSED_LIST.
145
 */
146
TPM_RC
147
ConvertFromCompressedBitArray(BYTE         *inAuditCommands,
32,204✔
148
                              size_t        inAuditCommandsLen,
149
                              BYTE         *outAuditCommands,
150
                              size_t        outAuditCommandsLen)
151
{
152
    size_t max_bit = MIN(inAuditCommandsLen * 8, ARRAY_SIZE(CCToCompressedListIndex));
32,204✔
153
    size_t bit = 0;
32,204✔
154

155
    MemorySet(outAuditCommands, 0, outAuditCommandsLen);
32,204✔
156

157
    while (bit < max_bit) {
483,060✔
158
        BYTE bits = inAuditCommands[bit >> 3];
450,856✔
159
        BYTE mask = 1;
450,856✔
160
        size_t lbit = bit;
450,856✔
161

162
        while (bits != 0 && lbit < max_bit) {
676,284✔
163
            if ((bits & mask) != 0) {
225,428✔
164
                TPM_CC cc = CCToCompressedListIndex[lbit].cc;
32,204✔
165
                COMMAND_INDEX idx = cc - TPM_CC_NV_UndefineSpaceSpecial;
32,204✔
166

167
                assert(idx != UNIMPLEMENTED_COMMAND_INDEX);
32,204✔
168

169
                SetBit(idx, outAuditCommands, outAuditCommandsLen);
32,204✔
170
                bits ^= mask; /* unset bit */
32,204✔
171
            }
172
            mask <<= 1;
225,428✔
173
            lbit++;
225,428✔
174
        }
175
        bit += 8;
450,856✔
176
    }
177

178
    return TPM_RC_SUCCESS;
32,204✔
179
}
180

181
static size_t FindCCInCompressedListIndexArray(TPM_CC cc)
35,816✔
182
{
183
    size_t e_index = ARRAY_SIZE(CCToCompressedListIndex) - 1;
35,816✔
184
    size_t s_index = 0;
35,816✔
185

186
    while (true) {
161,172✔
187
        size_t index = (e_index + s_index) >> 1;
161,172✔
188

189
        if (cc == CCToCompressedListIndex[index].cc) {
161,172✔
190
            return index;
35,816✔
191
        }
192
        if (e_index == s_index) {
125,356✔
193
            break;
194
        }
195
        if (cc < CCToCompressedListIndex[index].cc) {
125,356✔
196
            e_index = index;
197
        } else {
198
            if (s_index != index)
35,816✔
199
                s_index = index;
200
            else
UNCOV
201
                s_index++;
×
202
        }
203
    }
204
    /* entry must have been found */
UNCOV
205
    pAssert(false);
×
206
}
207

208
/* Convert to a bit array from the time when COMPRESSED_LIST was YES
209
 * from an array where the indices do NOT correspond to a COMPRESSED_LIST.
210
 */
211
TPM_RC
212
ConvertToCompressedBitArray(BYTE         *inAuditCommands,
35,816✔
213
                            size_t        inAuditCommandsLen,
214
                            BYTE         *outAuditCommands,
215
                            size_t        outAuditCommandsLen)
216
{
217
    size_t max_idx = inAuditCommandsLen * 8;
35,816✔
218
    size_t idx = 0;
35,816✔
219

220
    MemorySet(outAuditCommands, 0, outAuditCommandsLen);
35,816✔
221

222
    while (idx < max_idx) {
644,688✔
223
        BYTE bits = inAuditCommands[idx >> 3];
608,872✔
224
        BYTE mask = 1;
608,872✔
225
        size_t lidx = idx;
608,872✔
226

227
        /* handle bits set in one byte in the loop */
228
        while (bits != 0 && lidx < max_idx) {
770,044✔
229
            if ((bits & mask) != 0) {
161,172✔
230
                TPM_CC cc = lidx + TPM_CC_NV_UndefineSpaceSpecial;
35,816✔
231
                size_t bit = FindCCInCompressedListIndexArray(cc);
35,816✔
232

233
                SetBit(bit, outAuditCommands, outAuditCommandsLen);
35,816✔
234
                bits ^= mask; /* unset bit */
35,816✔
235
            }
236
            mask <<= 1;
161,172✔
237
            lidx++;
161,172✔
238
        }
239
        idx += 8;
608,872✔
240
    }
241

242
    return TPM_RC_SUCCESS;
35,816✔
243
}
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