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

stefanberger / libtpms / #2100

19 Mar 2026 09:14PM UTC coverage: 77.208% (-0.005%) from 77.213%
#2100

push

travis-ci

web-flow
Merge 94dc182fd into 77104fbfb

2 of 3 new or added lines in 1 file covered. (66.67%)

1217 existing lines in 26 files now uncovered.

36408 of 47156 relevant lines covered (77.21%)

124705.5 hits per line

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

60.99
/src/tpm2/BackwardsCompatibilityObject.c
1
// SPDX-License-Identifier: BSD-2-Clause
2

3
// (c) Copyright IBM Corporation 2017-2026
4

5
#include <assert.h>
6

7
#include "BackwardsCompatibilityObject.h"
8

9
MUST_BE(offsetof(TPMU_NAME, digest.digest) == 2);
10
MUST_BE(sizeof(TPMU_NAME) == 2 + 64 + 2 /*!*/);
11
MUST_BE(sizeof(TPM2B_NAME) == 2 + 64 + 2 + 2);
12
MUST_BE(sizeof(TPM2B_DIGEST) == 2 + 64);
13
MUST_BE(sizeof(TPM2B_NAME) == 2 + 64 + 2 + 2);
14
MUST_BE(sizeof(TPM2B_DIGEST) == 2 + 64);
15
#ifdef ARCH_NEEDS_INT_PADDING
16
MUST_BE(sizeof(TPMU_PUBLIC_PARMS) == 20);
17
#endif
18

19
/* The following are data structure from libtpms 0.7.x with RSA 2048 support
20
 * that help to resume key and hash contexts (TPM2_ContextSave/Load) from this
21
 * earlier version. All structures that have different sizes in 0.8 are found
22
 * here.
23
 *
24
 * The functions RSA3072_OBJECT_Buffer_To_OBJECT and
25
 * RSA2048_OBJECT_Buffer_to_OBJECT fill an old 2048/3072 OBJECT data structure
26
 * by directly copying from a byte array into this data structure. Since data
27
 * structure are supposed to be interchangeable between architectures (at least
28
 * if they have the same endianess in this case) the fields in the OBJECT must
29
 * be located at the same offsets. This is the reason why there are paddings
30
 * in some data structures for architectures where the compiler does not pad
31
 * automatically as expected (m68k).
32
 */
33
typedef union
34
{
35
    struct
36
    {
37
        UINT16 size;
38
        BYTE   buffer[2048 / 8];
39
    } t;
40
    TPM2B b;
41
} RSA2048_TPM2B_PUBLIC_KEY_RSA;
42
MUST_BE(sizeof(RSA2048_TPM2B_PUBLIC_KEY_RSA) == 2 + 2048 / 8);
43

44
typedef union
45
{
46
    TPM2B_DIGEST                 keyedHash;
47
    TPM2B_DIGEST                 sym;
48
    RSA2048_TPM2B_PUBLIC_KEY_RSA rsa;
49
    TPMS_ECC_POINT               ecc;
50
    //    TPMS_DERIVE                derive;
51
} RSA2048_TPMU_PUBLIC_ID;
52
MUST_BE(sizeof(RSA2048_TPMU_PUBLIC_ID) == 2 + 2048 / 8);
53
MUST_BE(sizeof(TPMS_ECC_POINT) == 2 * (2 + MAX_ECC_KEY_BYTES));
54

55
typedef struct
56
{
57
    TPMI_ALG_PUBLIC type;
58
    TPMI_ALG_HASH   nameAlg;
59
    TPMA_OBJECT     objectAttributes;
60
    TPM2B_DIGEST    authPolicy;
61
    ARCH_PADDING(pad1, 2);
62
    TPMU_PUBLIC_PARMS      parameters;
63
    RSA2048_TPMU_PUBLIC_ID unique;
64
    ARCH_PADDING(pad2, 2);
65
} RSA2048_TPMT_PUBLIC;
66
MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, nameAlg) == 2);
67
MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, objectAttributes) == 2 + 2);
68
MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, authPolicy) == 2 + 2 + 4);
69
MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, parameters) == 2 + 2 + 4 + 66 + 2 /*!*/);
70
MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, unique) == 2 + 2 + 4 + 66 + 2 + 20);
71
MUST_BE(sizeof(RSA2048_TPMT_PUBLIC) == 356);
72

73
typedef union
74
{
75
    struct
76
    {
77
        UINT16 size;
78
        BYTE   buffer[((2048 / 8) / 2) * 5];
79
    } t;
80
    TPM2B b;
81
} RSA2048_TPM2B_PRIVATE_KEY_RSA;
82

83
MUST_BE(sizeof(RSA2048_TPM2B_PRIVATE_KEY_RSA) == 642);
84

85
typedef union
86
{
87
    struct
88
    {
89
        UINT16 size;
90
        BYTE   buffer[((2048 / 8) / 2) * 5];
91
    } t;
92
    TPM2B b;
93
} RSA2048_TPM2B_PRIVATE_VENDOR_SPECIFIC;
94

95
typedef union
96
{
97
    RSA2048_TPM2B_PRIVATE_KEY_RSA         rsa;
98
    TPM2B_ECC_PARAMETER                   ecc;
99
    TPM2B_SENSITIVE_DATA                  bits;
100
    TPM2B_SYM_KEY                         sym;
101
    RSA2048_TPM2B_PRIVATE_VENDOR_SPECIFIC any;
102
} RSA2048_TPMU_SENSITIVE_COMPOSITE;
103

104
typedef struct
105
{
106
    TPMI_ALG_PUBLIC                  sensitiveType;
107
    TPM2B_AUTH                       authValue;
108
    TPM2B_DIGEST                     seedValue;
109
    RSA2048_TPMU_SENSITIVE_COMPOSITE sensitive;
110
} RSA2048_TPMT_SENSITIVE;
111

112
MUST_BE(offsetof(RSA2048_TPMT_SENSITIVE, authValue) == 2);
113
MUST_BE(offsetof(RSA2048_TPMT_SENSITIVE, seedValue) == 2 + 66);
114
MUST_BE(offsetof(RSA2048_TPMT_SENSITIVE, sensitive) == 2 + 66 + 66);
115
MUST_BE(sizeof(RSA2048_TPMT_SENSITIVE) == 776);
116

117
BN_TYPE(old_prime, (2048 / 2));
118

119
typedef struct RSA2048_privateExponent
120
{
121
    bn_old_prime_t Q;
122
    bn_old_prime_t dP;
123
    bn_old_prime_t dQ;
124
    bn_old_prime_t qInv;
125
} RSA2048_privateExponent_t;
126

127
static inline void CopyFromOldPrimeT(ci_prime_t* dst, const bn_old_prime_t* src)
128
{
UNCOV
129
    dst->allocated = src->allocated;
×
UNCOV
130
    dst->size      = src->size;
×
UNCOV
131
    memcpy(dst->d, src->d, sizeof(src->d));
×
132
}
133

134
MUST_BE(sizeof(RSA2048_privateExponent_t) == 608);
135

136
typedef struct RSA2048_OBJECT
137
{
138
    // The attributes field is required to be first followed by the publicArea.
139
    // This allows the overlay of the object structure and a sequence structure
140
    OBJECT_ATTRIBUTES         attributes;       // object attributes
141
    RSA2048_TPMT_PUBLIC       publicArea;       // public area of an object
142
    RSA2048_TPMT_SENSITIVE    sensitive;        // sensitive area of an object
143
    RSA2048_privateExponent_t privateExponent;  // Additional field for the private
144
    TPM2B_NAME                qualifiedName;    // object qualified name
145
    ARCH_PADDING(pad1, 2);
146
    TPMI_DH_OBJECT evictHandle;  // if the object is an evict object,
147
    // the original handle is kept here.
148
    // The 'working' handle will be the
149
    // handle of an object slot.
150
    TPM2B_NAME name;  // Name of the object name. Kept here
151
    // to avoid repeatedly computing it.
152
    ARCH_PADDING(pad2, 2);
153

154
    // libtpms added: OBJECT lies in NVRAM; to avoid that it needs different number
155
    // of bytes on 32 bit and 64 bit architectures, we need to make sure it's the
156
    // same size; simple padding at the end works here
157
    UINT32 _pad;
158
} RSA2048_OBJECT;
159

160
MUST_BE(sizeof(OBJECT_ATTRIBUTES) == 4);
161
MUST_BE(offsetof(RSA2048_OBJECT, publicArea) == 4);
162
MUST_BE(offsetof(RSA2048_OBJECT, sensitive) == 4 + 356);
163
MUST_BE(offsetof(RSA2048_OBJECT, privateExponent) == 4 + 356 + 776);
164
MUST_BE(offsetof(RSA2048_OBJECT, qualifiedName) == 4 + 356 + 776 + 608);
165
MUST_BE(offsetof(RSA2048_OBJECT, evictHandle) == 4 + 356 + 776 + 608 + 68 + 4);
166
MUST_BE(offsetof(RSA2048_OBJECT, name) == 4 + 356 + 776 + 608 + 68 + 4 + 4);
167
MUST_BE(sizeof(RSA2048_OBJECT) == 1896);
168

169
TPMI_RH_HIERARCHY ObjectGetHierarchyFromAttributes(OBJECT* object)
68,948✔
170
{
171
    if(object->attributes.spsHierarchy)
68,948✔
172
        return TPM_RH_OWNER;
173

174
    if(object->attributes.epsHierarchy)
1,332✔
175
        return TPM_RH_ENDORSEMENT;
176

177
    if(object->attributes.ppsHierarchy)
110✔
178
        return TPM_RH_PLATFORM;
22✔
179

180
    return TPM_RH_NULL;
181
}
182

183
static void RSA2048_OBJECT_To_OBJECT(OBJECT* dest, const RSA2048_OBJECT* src)
184
{
UNCOV
185
    dest->attributes                  = src->attributes;
×
186
    dest->hierarchy                   = ObjectGetHierarchyFromAttributes(dest);
×
187

UNCOV
188
    dest->publicArea.type             = src->publicArea.type;
×
UNCOV
189
    dest->publicArea.nameAlg          = src->publicArea.nameAlg;
×
190
    dest->publicArea.objectAttributes = src->publicArea.objectAttributes;
×
UNCOV
191
    dest->publicArea.authPolicy       = src->publicArea.authPolicy;
×
192
    dest->publicArea.parameters       = src->publicArea.parameters;
×
193
    /* the unique part can be one or two TPM2B's */
UNCOV
194
    switch(dest->publicArea.type)
×
195
    {
UNCOV
196
        case TPM_ALG_KEYEDHASH:
×
197
            MemoryCopy2B(&dest->publicArea.unique.keyedHash.b,
×
198
                         &src->publicArea.unique.keyedHash.b,
199
                         sizeof(src->publicArea.unique.keyedHash.t.buffer));
200
            memset(&dest->privateExponent, 0, sizeof(dest->privateExponent));
×
201
            break;
202
        case TPM_ALG_SYMCIPHER:
×
203
            MemoryCopy2B(&dest->publicArea.unique.sym.b,
×
204
                         &src->publicArea.unique.sym.b,
205
                         sizeof(src->publicArea.unique.sym.t.buffer));
206
            memset(&dest->privateExponent, 0, sizeof(dest->privateExponent));
×
207
            break;
UNCOV
208
        case TPM_ALG_RSA:
×
209
            MemoryCopy2B(&dest->publicArea.unique.rsa.b,
×
210
                         &src->publicArea.unique.rsa.b,
211
                         sizeof(src->publicArea.unique.rsa.t.buffer));
212

213
            CopyFromOldPrimeT(&dest->privateExponent.Q, &src->privateExponent.Q);
×
214
            CopyFromOldPrimeT(&dest->privateExponent.dP, &src->privateExponent.dP);
×
215
            CopyFromOldPrimeT(&dest->privateExponent.dQ, &src->privateExponent.dQ);
×
UNCOV
216
            CopyFromOldPrimeT(&dest->privateExponent.qInv,
×
217
                              &src->privateExponent.qInv);
UNCOV
218
            break;
×
UNCOV
219
        case TPM_ALG_ECC:
×
UNCOV
220
            MemoryCopy2B(&dest->publicArea.unique.ecc.x.b,
×
221
                         &src->publicArea.unique.ecc.x.b,
222
                         sizeof(src->publicArea.unique.ecc.x.t.buffer));
223
            MemoryCopy2B(&dest->publicArea.unique.ecc.y.b,
×
224
                         &src->publicArea.unique.ecc.y.b,
225
                         sizeof(src->publicArea.unique.ecc.y.t.buffer));
UNCOV
226
            memset(&dest->privateExponent, 0, sizeof(dest->privateExponent));
×
227
            break;
228
    }
229

230
    dest->sensitive.sensitiveType = src->sensitive.sensitiveType;
×
231
    dest->sensitive.authValue     = src->sensitive.authValue;
×
UNCOV
232
    dest->sensitive.seedValue     = src->sensitive.seedValue;
×
233
    /* The RSA2048_TPMU_SENSITIVE_COMPOSITE is always a TPM2B */
234
    MemoryCopy2B(&dest->sensitive.sensitive.any.b,
×
235
                 &src->sensitive.sensitive.any.b,
236
                 sizeof(src->sensitive.sensitive.any.t.buffer));
237

UNCOV
238
    dest->qualifiedName = src->qualifiedName;
×
UNCOV
239
    dest->evictHandle   = src->evictHandle;
×
UNCOV
240
    dest->name          = src->name;
×
241
}
242

243
// Convert an RSA2048_OBJECT that was copied into buffer using MemoryCopy
244
TPM_RC
UNCOV
245
RSA2048_OBJECT_Buffer_To_OBJECT(OBJECT* newObject, BYTE* buffer, INT32 size)
×
246
{
247
    RSA2048_OBJECT oldObject;
×
UNCOV
248
    TPM_RC         rc = 0;
×
249

250
    // get the attributes
UNCOV
251
    MemoryCopy(newObject, buffer, sizeof(newObject->attributes));
×
UNCOV
252
    if(ObjectIsSequence(newObject))
×
253
    {
254
        /* resuming old hash contexts is not supported */
255
        rc = TPM_RC_DISABLED;
256
    }
257
    else
258
    {
UNCOV
259
        if(size != sizeof(RSA2048_OBJECT))
×
260
            return TPM_RC_SIZE;
UNCOV
261
        MemoryCopy(&oldObject, buffer, sizeof(RSA2048_OBJECT));
×
262

263
        /* fill the newObject with the contents of the oldObject */
UNCOV
264
        RSA2048_OBJECT_To_OBJECT(newObject, &oldObject);
×
265
    }
266

267
    return rc;
268
}
269

270
/* The following are data structure from libtpms 0.9.x with RSA 3072 support.
271
 */
272
typedef union
273
{
274
    struct
275
    {
276
        UINT16 size;
277
        BYTE   buffer[3072 / 8];
278
    } t;
279
    TPM2B b;
280
} RSA3072_TPM2B_PUBLIC_KEY_RSA;
281
MUST_BE(sizeof(RSA3072_TPM2B_PUBLIC_KEY_RSA) == 2 + 3072 / 8);
282

283
typedef union
284
{
285
    TPM2B_DIGEST                 keyedHash;
286
    TPM2B_DIGEST                 sym;
287
    RSA3072_TPM2B_PUBLIC_KEY_RSA rsa;
288
    TPMS_ECC_POINT               ecc;
289
    TPMS_DERIVE                  derive;
290
} RSA3072_TPMU_PUBLIC_ID;
291
MUST_BE(sizeof(TPM2B_DIGEST) == 2 + BITS_TO_BYTES(512));
292
MUST_BE(sizeof(TPMS_ECC_POINT) == 2 * (2 + BITS_TO_BYTES(638)));
293
MUST_BE(sizeof(TPMS_DERIVE) == 2 * (2 + 32));
294
MUST_BE(sizeof(RSA3072_TPMU_PUBLIC_ID) == 2 + 3072 / 8);
295

296
typedef struct
297
{
298
    TPMI_ALG_PUBLIC type;
299
    TPMI_ALG_HASH   nameAlg;
300
    TPMA_OBJECT     objectAttributes;
301
    TPM2B_DIGEST    authPolicy;
302
    ARCH_PADDING(pad1, 2);
303
    TPMU_PUBLIC_PARMS      parameters;
304
    RSA3072_TPMU_PUBLIC_ID unique;
305
    ARCH_PADDING(pad2, 2);
306
} RSA3072_TPMT_PUBLIC;
307
MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, nameAlg) == 2);
308
MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, objectAttributes) == 2 + 2);
309
MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, authPolicy) == 2 + 2 + 4);
310
MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, parameters) == 2 + 2 + 4 + 66 + 2 /*!*/);
311
MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, unique) == 2 + 2 + 4 + 66 + 2 + 20);
312
MUST_BE(sizeof(RSA3072_TPMT_PUBLIC) == 484);
313

314
typedef union
315
{
316
    struct
317
    {
318
        UINT16 size;
319
        BYTE   buffer[((3072 / 8) / 2) * 5];
320
    } t;
321
    TPM2B b;
322
} RSA3072_TPM2B_PRIVATE_KEY_RSA;
323
MUST_BE(sizeof(RSA3072_TPM2B_PRIVATE_KEY_RSA) == 962);
324

325
typedef union
326
{
327
    struct
328
    {
329
        UINT16 size;
330
        BYTE   buffer[((3072 / 8) / 2) * 5];
331
    } t;
332
    TPM2B b;
333
} RSA3072_TPM2B_PRIVATE_VENDOR_SPECIFIC;
334

335
typedef union
336
{
337
    RSA3072_TPM2B_PRIVATE_KEY_RSA         rsa;
338
    TPM2B_ECC_PARAMETER                   ecc;
339
    TPM2B_SENSITIVE_DATA                  bits;
340
    TPM2B_SYM_KEY                         sym;
341
    RSA3072_TPM2B_PRIVATE_VENDOR_SPECIFIC any;
342
} RSA3072_TPMU_SENSITIVE_COMPOSITE;
343
MUST_BE(sizeof(TPM2B_ECC_PARAMETER) == 2 + BITS_TO_BYTES(638) /* BN P638 */);
344
MUST_BE(sizeof(TPM2B_SENSITIVE_DATA) == 2 + 128);
345
MUST_BE(sizeof(TPM2B_SYM_KEY) == 2 + BITS_TO_BYTES(256));
346

347
typedef struct
348
{
349
    TPMI_ALG_PUBLIC                  sensitiveType;
350
    TPM2B_AUTH                       authValue;
351
    TPM2B_DIGEST                     seedValue;
352
    RSA3072_TPMU_SENSITIVE_COMPOSITE sensitive;
353
} RSA3072_TPMT_SENSITIVE;
354
MUST_BE(sizeof(TPM2B_AUTH) == 2 + BITS_TO_BYTES(512));
355
MUST_BE(sizeof(TPM2B_DIGEST) == 2 + BITS_TO_BYTES(512));
356
MUST_BE(sizeof(RSA3072_TPMT_SENSITIVE) == 1096);
357

358
BN_TYPE(rsa3072_prime, (3072 / 2));
359

360
typedef struct RSA3072_privateExponent
361
{
362
    bn_rsa3072_prime_t Q;
363
    bn_rsa3072_prime_t dP;
364
    bn_rsa3072_prime_t dQ;
365
    bn_rsa3072_prime_t qInv;
366
} RSA3072_privateExponent_t;
367
MUST_BE(offsetof(RSA3072_privateExponent_t, dP) == 216);
368
MUST_BE(offsetof(RSA3072_privateExponent_t, dQ) == 216 + 216);
369
MUST_BE(offsetof(RSA3072_privateExponent_t, qInv) == 216 + 216 + 216);
370
MUST_BE(sizeof(RSA3072_privateExponent_t) == 864);
371

372
typedef struct RSA3072_OBJECT
373
{
374
    // The attributes field is required to be first followed by the publicArea.
375
    // This allows the overlay of the object structure and a sequence structure
376
    OBJECT_ATTRIBUTES      attributes;          // object attributes
377
    RSA3072_TPMT_PUBLIC    publicArea;          // public area of an object
378
    RSA3072_TPMT_SENSITIVE sensitive;           // sensitive area of an object
379
#if 1                                           // libtpms added begin: keep
380
    RSA3072_privateExponent_t privateExponent;  // Additional field for the private
381
#endif                                          // libtpms added end
382
    TPM2B_NAME qualifiedName;                   // object qualified name
383
    ARCH_PADDING(pad1, 2);
384
    TPMI_DH_OBJECT evictHandle;  // if the object is an evict object,
385
    // the original handle is kept here.
386
    // The 'working' handle will be the
387
    // handle of an object slot.
388
    TPM2B_NAME name;  // Name of the object name. Kept here
389
    // to avoid repeatedly computing it.
390

391
    // libtpms added: SEED_COMPAT_LEVEL to use for deriving child keys
392
    SEED_COMPAT_LEVEL seedCompatLevel;
393
    // libtpms added: OBJECT lies in NVRAM; to avoid that it needs different number
394
    // of bytes on 32 bit and 64 bit architectures, we need to make sure it's the
395
    // same size; simple padding at the end works here
396
    UINT8 _pad[3];
397
    ARCH_PADDING(pad2, 2);
398
} RSA3072_OBJECT;
399
MUST_BE(sizeof(OBJECT_ATTRIBUTES) == 4);
400
MUST_BE(offsetof(RSA3072_OBJECT, publicArea) == 4);
401
MUST_BE(offsetof(RSA3072_OBJECT, sensitive) == 4 + 484);
402
MUST_BE(offsetof(RSA3072_OBJECT, privateExponent) == 4 + 484 + 1096);
403
MUST_BE(offsetof(RSA3072_OBJECT, qualifiedName) == 4 + 484 + 1096 + 864);
404
MUST_BE(offsetof(RSA3072_OBJECT, evictHandle) == 4 + 484 + 1096 + 864 + 68 + 4);
405
MUST_BE(offsetof(RSA3072_OBJECT, name) == 4 + 484 + 1096 + 864 + 68 + 4 + 4);
406
MUST_BE(offsetof(RSA3072_OBJECT, seedCompatLevel)
407
        == 4 + 484 + 1096 + 864 + 68 + 4 + 4 + 70);
408
MUST_BE(offsetof(RSA3072_OBJECT, _pad) == 4 + 484 + 1096 + 864 + 68 + 4 + 4 + 70 + 1);
409
MUST_BE(sizeof(RSA3072_OBJECT) == 2600);
410

411
static inline void CopyFromRSA3072PrimeT(ci_prime_t*               dst,
269,268✔
412
                                         const bn_rsa3072_prime_t* src)
413
{
414
    dst->allocated = src->allocated;
269,268✔
415
    dst->size      = src->size;
269,268✔
416
    memcpy(dst->d, src->d, sizeof(src->d));
269,268✔
417
}
269,268✔
418

419
static inline void CopyToRSA3072PrimeT(bn_rsa3072_prime_t* dst, const ci_prime_t* src)
1,732✔
420
{
421
    dst->allocated = src->allocated;
1,732✔
422
    dst->size      = src->size;
1,732✔
423
    memcpy(dst->d, src->d, sizeof(dst->d));
1,732✔
424
}
1,732✔
425

426
static void RSA3072_OBJECT_To_OBJECT(OBJECT* dest, const RSA3072_OBJECT* src)
67,513✔
427
{
428
    dest->attributes                  = src->attributes;
67,513✔
429
    dest->hierarchy                   = ObjectGetHierarchyFromAttributes(dest);
67,513✔
430

431
    dest->publicArea.type             = src->publicArea.type;
67,513✔
432
    dest->publicArea.nameAlg          = src->publicArea.nameAlg;
67,513✔
433
    dest->publicArea.objectAttributes = src->publicArea.objectAttributes;
67,513✔
434
    dest->publicArea.authPolicy       = src->publicArea.authPolicy;
67,513✔
435
    dest->publicArea.parameters       = src->publicArea.parameters;
67,513✔
436
    /* the unique part can be one or two TPM2B's */
437
    switch(dest->publicArea.type)
67,513✔
438
    {
UNCOV
439
        case TPM_ALG_KEYEDHASH:
×
UNCOV
440
            MemoryCopy2B(&dest->publicArea.unique.keyedHash.b,
×
441
                         &src->publicArea.unique.keyedHash.b,
442
                         sizeof(src->publicArea.unique.keyedHash.t.buffer));
UNCOV
443
            memset(&dest->privateExponent, 0, sizeof(dest->privateExponent));
×
444
            break;
UNCOV
445
        case TPM_ALG_SYMCIPHER:
×
UNCOV
446
            MemoryCopy2B(&dest->publicArea.unique.sym.b,
×
447
                         &src->publicArea.unique.sym.b,
448
                         sizeof(src->publicArea.unique.sym.t.buffer));
UNCOV
449
            memset(&dest->privateExponent, 0, sizeof(dest->privateExponent));
×
450
            break;
451
        case TPM_ALG_RSA:
67,317✔
452
            MemoryCopy2B(&dest->publicArea.unique.rsa.b,
67,317✔
453
                         &src->publicArea.unique.rsa.b,
454
                         sizeof(src->publicArea.unique.rsa.t.buffer));
455

456
            CopyFromRSA3072PrimeT(&dest->privateExponent.Q, &src->privateExponent.Q);
67,317✔
457
            CopyFromRSA3072PrimeT(&dest->privateExponent.dP,
67,317✔
458
                                  &src->privateExponent.dP);
459
            CopyFromRSA3072PrimeT(&dest->privateExponent.dQ,
67,317✔
460
                                  &src->privateExponent.dQ);
461
            CopyFromRSA3072PrimeT(&dest->privateExponent.qInv,
67,317✔
462
                                  &src->privateExponent.qInv);
463
            break;
67,317✔
464
        case TPM_ALG_ECC:
196✔
465
            MemoryCopy2B(&dest->publicArea.unique.ecc.x.b,
196✔
466
                         &src->publicArea.unique.ecc.x.b,
467
                         sizeof(src->publicArea.unique.ecc.x.t.buffer));
468
            MemoryCopy2B(&dest->publicArea.unique.ecc.y.b,
196✔
469
                         &src->publicArea.unique.ecc.y.b,
470
                         sizeof(src->publicArea.unique.ecc.y.t.buffer));
471
            memset(&dest->privateExponent, 0, sizeof(dest->privateExponent));
196✔
472
            break;
473
    }
474

475
    dest->sensitive.sensitiveType = src->sensitive.sensitiveType;
67,513✔
476
    dest->sensitive.authValue     = src->sensitive.authValue;
67,513✔
477
    dest->sensitive.seedValue     = src->sensitive.seedValue;
67,513✔
478
    /* The OLD_TPMU_SENSITIVE_COMPOSITE is always a TPM2B */
479
    MemoryCopy2B(&dest->sensitive.sensitive.any.b,
67,513✔
480
                 &src->sensitive.sensitive.any.b,
481
                 sizeof(src->sensitive.sensitive.any.t.buffer));
482

483
    dest->qualifiedName   = src->qualifiedName;
67,513✔
484
    dest->evictHandle     = src->evictHandle;
67,513✔
485
    dest->name            = src->name;
67,513✔
486
    dest->seedCompatLevel = src->seedCompatLevel;
67,513✔
487
}
67,513✔
488

489
/* Convert an OBJECT to the (smaller) RSA3072_OBJECT. */
490
static void OBJECT_To_RSA3072_OBJECT(RSA3072_OBJECT* dest, const OBJECT* src)
463✔
491
{
492
    dest->attributes                  = src->attributes;
463✔
493

494
    dest->publicArea.type             = src->publicArea.type;
463✔
495
    dest->publicArea.nameAlg          = src->publicArea.nameAlg;
463✔
496
    dest->publicArea.objectAttributes = src->publicArea.objectAttributes;
463✔
497
    dest->publicArea.authPolicy       = src->publicArea.authPolicy;
463✔
498
    dest->publicArea.parameters       = src->publicArea.parameters;
463✔
499
    /* the unique part can be one or two TPM2B's */
500
    switch(dest->publicArea.type)
463✔
501
    {
UNCOV
502
        case TPM_ALG_KEYEDHASH:
×
UNCOV
503
            MemoryCopy2B(&dest->publicArea.unique.keyedHash.b,
×
504
                         &src->publicArea.unique.keyedHash.b,
505
                         sizeof(dest->publicArea.unique.keyedHash.t.buffer));
UNCOV
506
            break;
×
UNCOV
507
        case TPM_ALG_SYMCIPHER:
×
UNCOV
508
            MemoryCopy2B(&dest->publicArea.unique.sym.b,
×
509
                         &src->publicArea.unique.sym.b,
510
                         sizeof(dest->publicArea.unique.sym.t.buffer));
UNCOV
511
            break;
×
512
        case TPM_ALG_RSA:
433✔
513
            MemoryCopy2B(&dest->publicArea.unique.rsa.b,
433✔
514
                         &src->publicArea.unique.rsa.b,
515
                         sizeof(dest->publicArea.unique.rsa.t.buffer));
516

517
            CopyToRSA3072PrimeT(&dest->privateExponent.Q, &src->privateExponent.Q);
433✔
518
            CopyToRSA3072PrimeT(&dest->privateExponent.dP, &src->privateExponent.dP);
433✔
519
            CopyToRSA3072PrimeT(&dest->privateExponent.dQ, &src->privateExponent.dQ);
433✔
520
            CopyToRSA3072PrimeT(&dest->privateExponent.qInv,
433✔
521
                                &src->privateExponent.qInv);
522
            break;
433✔
523
        case TPM_ALG_ECC:
30✔
524
            MemoryCopy2B(&dest->publicArea.unique.ecc.x.b,
30✔
525
                         &src->publicArea.unique.ecc.x.b,
526
                         sizeof(dest->publicArea.unique.ecc.x.t.buffer));
527
            MemoryCopy2B(&dest->publicArea.unique.ecc.y.b,
30✔
528
                         &src->publicArea.unique.ecc.y.b,
529
                         sizeof(dest->publicArea.unique.ecc.y.t.buffer));
530
            break;
30✔
531
    }
532

533
    dest->sensitive.sensitiveType = src->sensitive.sensitiveType;
463✔
534
    dest->sensitive.authValue     = src->sensitive.authValue;
463✔
535
    dest->sensitive.seedValue     = src->sensitive.seedValue;
463✔
536
    /* The OLD_TPMU_SENSITIVE_COMPOSITE is always a TPM2B */
537
    MemoryCopy2B(&dest->sensitive.sensitive.any.b,
463✔
538
                 &src->sensitive.sensitive.any.b,
539
                 sizeof(dest->sensitive.sensitive.any.t.buffer));
540

541
    dest->qualifiedName   = src->qualifiedName;
463✔
542
    dest->evictHandle     = src->evictHandle;
463✔
543
    dest->name            = src->name;
463✔
544
    dest->seedCompatLevel = src->seedCompatLevel;
463✔
545
    MemorySet(dest->_pad, 0, sizeof(dest->_pad));
463✔
546
}
463✔
547

548
TPM_RC
549
RSA3072_OBJECT_Buffer_To_OBJECT(OBJECT* object, BYTE* buffer, INT32 size)
67,513✔
550
{
551
    RSA3072_OBJECT rsa3072_object;
67,513✔
552

553
    if(size != sizeof(RSA3072_OBJECT))
67,513✔
554
        return TPM_RC_SIZE;
555

556
    MemoryCopy(&rsa3072_object, buffer, size);
67,513✔
557

558
    RSA3072_OBJECT_To_OBJECT(object, &rsa3072_object);
67,513✔
559

560
    return 0;
67,513✔
561
}
562

563
UINT32 OBJECT_To_Buffer_As_RSA3072_OBJECT(OBJECT* object, BYTE* buffer, UINT32 size)
463✔
564
{
565
    RSA3072_OBJECT rsa3072_object;
463✔
566
    UINT32         written = sizeof(rsa3072_object);
463✔
567

568
    OBJECT_To_RSA3072_OBJECT(&rsa3072_object, object);
463✔
569

570
    pAssert(size >= sizeof(rsa3072_object));
463✔
571
    MemoryCopy(buffer, &rsa3072_object, sizeof(rsa3072_object));
463✔
572

573
    return written;
463✔
574
}
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