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

stefanberger / libtpms / #2093

05 Mar 2026 11:01PM UTC coverage: 77.201% (+0.009%) from 77.192%
#2093

push

travis-ci

web-flow
Merge 32dd0828e into 11a66d261

36390 of 47137 relevant lines covered (77.2%)

125362.31 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,2018.
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
typedef union {
25
    struct {
26
        UINT16                  size;
27
        BYTE                    buffer[2048/8];
28
    }            t;
29
    TPM2B        b;
30
} RSA2048_TPM2B_PUBLIC_KEY_RSA;
31
MUST_BE(sizeof(RSA2048_TPM2B_PUBLIC_KEY_RSA) == 2 + 2048/8);
32

33
typedef union {
34
    TPM2B_DIGEST                 keyedHash;
35
    TPM2B_DIGEST                 sym;
36
    RSA2048_TPM2B_PUBLIC_KEY_RSA rsa;
37
    TPMS_ECC_POINT               ecc;
38
//    TPMS_DERIVE                derive;
39
} RSA2048_TPMU_PUBLIC_ID;
40
MUST_BE(sizeof(RSA2048_TPMU_PUBLIC_ID) == 2 + 2048/8);
41
MUST_BE(sizeof(TPMS_ECC_POINT) == 2 * (2 + MAX_ECC_KEY_BYTES));
42

43
typedef struct {
44
    TPMI_ALG_PUBLIC         type;
45
    TPMI_ALG_HASH           nameAlg;
46
    TPMA_OBJECT             objectAttributes;
47
    TPM2B_DIGEST            authPolicy;
48
    ARCH_PADDING(pad1, 2);
49
    TPMU_PUBLIC_PARMS       parameters;
50
    RSA2048_TPMU_PUBLIC_ID  unique;
51
    ARCH_PADDING(pad2, 2);
52
} RSA2048_TPMT_PUBLIC;
53
MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, nameAlg) == 2);
54
MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, objectAttributes) == 2 + 2);
55
MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, authPolicy) == 2 + 2 + 4);
56
MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, parameters) == 2 + 2 + 4 + 66 + 2/*!*/);
57
MUST_BE(offsetof(RSA2048_TPMT_PUBLIC, unique)     == 2 + 2 + 4 + 66 + 2 + 20);
58
MUST_BE(sizeof(RSA2048_TPMT_PUBLIC) == 356);
59

60
typedef union {
61
    struct {
62
        UINT16                  size;
63
        BYTE                    buffer[((2048/8)/2)*5];
64
    }            t;
65
    TPM2B        b;
66
} RSA2048_TPM2B_PRIVATE_KEY_RSA;
67

68
MUST_BE(sizeof(RSA2048_TPM2B_PRIVATE_KEY_RSA) == 642);
69

70
typedef union {
71
    struct {
72
        UINT16                  size;
73
        BYTE                    buffer[((2048/8)/2)*5];
74
    }            t;
75
    TPM2B        b;
76
} RSA2048_TPM2B_PRIVATE_VENDOR_SPECIFIC;
77

78
typedef union {
79
    RSA2048_TPM2B_PRIVATE_KEY_RSA         rsa;
80
    TPM2B_ECC_PARAMETER                   ecc;
81
    TPM2B_SENSITIVE_DATA                  bits;
82
    TPM2B_SYM_KEY                         sym;
83
    RSA2048_TPM2B_PRIVATE_VENDOR_SPECIFIC any;
84
} RSA2048_TPMU_SENSITIVE_COMPOSITE;
85

86
typedef struct {
87
    TPMI_ALG_PUBLIC                  sensitiveType;
88
    TPM2B_AUTH                       authValue;
89
    TPM2B_DIGEST                     seedValue;
90
    RSA2048_TPMU_SENSITIVE_COMPOSITE sensitive;
91
} RSA2048_TPMT_SENSITIVE;
92

93
MUST_BE(offsetof(RSA2048_TPMT_SENSITIVE, authValue) == 2);
94
MUST_BE(offsetof(RSA2048_TPMT_SENSITIVE, seedValue) == 2 + 66);
95
MUST_BE(offsetof(RSA2048_TPMT_SENSITIVE, sensitive) == 2 + 66 + 66);
96
MUST_BE(sizeof(RSA2048_TPMT_SENSITIVE) == 776);
97

98
BN_TYPE(old_prime, (2048 / 2));
99

100
typedef struct RSA2048_privateExponent
101
{
102
    bn_old_prime_t          Q;
103
    bn_old_prime_t          dP;
104
    bn_old_prime_t          dQ;
105
    bn_old_prime_t          qInv;
106
} RSA2048_privateExponent_t;
107

108
static inline void CopyFromOldPrimeT(ci_prime_t *dst,
109
                                     const bn_old_prime_t *src)
110
{
111
    dst->allocated = src->allocated;
×
112
    dst->size = src->size;
×
113
    memcpy(dst->d, src->d, sizeof(src->d));
×
114
}
115

116
MUST_BE(sizeof(RSA2048_privateExponent_t) == 608);
117

118
typedef struct RSA2048_OBJECT
119
{
120
    // The attributes field is required to be first followed by the publicArea.
121
    // This allows the overlay of the object structure and a sequence structure
122
    OBJECT_ATTRIBUTES   attributes;         // object attributes
123
    RSA2048_TPMT_PUBLIC     publicArea;         // public area of an object
124
    RSA2048_TPMT_SENSITIVE  sensitive;          // sensitive area of an object
125
    RSA2048_privateExponent_t privateExponent;  // Additional field for the private
126
    TPM2B_NAME          qualifiedName;      // object qualified name
127
    ARCH_PADDING(pad1, 2);
128
    TPMI_DH_OBJECT      evictHandle;        // if the object is an evict object,
129
    // the original handle is kept here.
130
    // The 'working' handle will be the
131
    // handle of an object slot.
132
    TPM2B_NAME          name;               // Name of the object name. Kept here
133
    // to avoid repeatedly computing it.
134
    ARCH_PADDING(pad2, 2);
135

136
    // libtpms added: OBJECT lies in NVRAM; to avoid that it needs different number
137
    // of bytes on 32 bit and 64 bit architectures, we need to make sure it's the
138
    // same size; simple padding at the end works here
139
    UINT32             _pad;
140
} RSA2048_OBJECT;
141

142
MUST_BE(sizeof(OBJECT_ATTRIBUTES) == 4);
143
MUST_BE(offsetof(RSA2048_OBJECT, publicArea) == 4);
144
MUST_BE(offsetof(RSA2048_OBJECT, sensitive) == 4 + 356);
145
MUST_BE(offsetof(RSA2048_OBJECT, privateExponent) == 4 + 356 + 776);
146
MUST_BE(offsetof(RSA2048_OBJECT, qualifiedName) == 4 + 356 + 776 + 608);
147
MUST_BE(offsetof(RSA2048_OBJECT, evictHandle) == 4 + 356 + 776 + 608 + 68 + 4);
148
MUST_BE(offsetof(RSA2048_OBJECT, name) == 4 + 356 + 776 + 608 + 68 + 4 + 4);
149
MUST_BE(sizeof(RSA2048_OBJECT) == 1896);
150

151
TPMI_RH_HIERARCHY ObjectGetHierarchyFromAttributes(OBJECT* object)
68,948✔
152
{
153
    if(object->attributes.spsHierarchy)
68,948✔
154
        return TPM_RH_OWNER;
155

156
    if(object->attributes.epsHierarchy)
1,332✔
157
        return TPM_RH_ENDORSEMENT;
158

159
    if(object->attributes.ppsHierarchy)
110✔
160
        return TPM_RH_PLATFORM;
22✔
161

162
    return TPM_RH_NULL;
163
}
164

165
static void RSA2048_OBJECT_To_OBJECT(OBJECT* dest, const RSA2048_OBJECT* src)
166
{
167
    dest->attributes = src->attributes;
×
168
    dest->hierarchy = ObjectGetHierarchyFromAttributes(dest);
×
169

170
    dest->publicArea.type = src->publicArea.type;
×
171
    dest->publicArea.nameAlg = src->publicArea.nameAlg;
×
172
    dest->publicArea.objectAttributes = src->publicArea.objectAttributes;
×
173
    dest->publicArea.authPolicy = src->publicArea.authPolicy;
×
174
    dest->publicArea.parameters = src->publicArea.parameters;
×
175
    /* the unique part can be one or two TPM2B's */
176
    switch (dest->publicArea.type) {
×
177
    case TPM_ALG_KEYEDHASH:
×
178
        MemoryCopy2B(&dest->publicArea.unique.keyedHash.b,
×
179
                     &src->publicArea.unique.keyedHash.b,
180
                     sizeof(src->publicArea.unique.keyedHash.t.buffer));
181
        memset(&dest->privateExponent, 0, sizeof(dest->privateExponent));
×
182
        break;
183
    case TPM_ALG_SYMCIPHER:
×
184
        MemoryCopy2B(&dest->publicArea.unique.sym.b,
×
185
                     &src->publicArea.unique.sym.b,
186
                     sizeof(src->publicArea.unique.sym.t.buffer));
187
        memset(&dest->privateExponent, 0, sizeof(dest->privateExponent));
×
188
        break;
189
    case TPM_ALG_RSA:
×
190
        MemoryCopy2B(&dest->publicArea.unique.rsa.b,
×
191
                     &src->publicArea.unique.rsa.b,
192
                     sizeof(src->publicArea.unique.rsa.t.buffer));
193

194
        CopyFromOldPrimeT(&dest->privateExponent.Q, &src->privateExponent.Q);
×
195
        CopyFromOldPrimeT(&dest->privateExponent.dP, &src->privateExponent.dP);
×
196
        CopyFromOldPrimeT(&dest->privateExponent.dQ, &src->privateExponent.dQ);
×
197
        CopyFromOldPrimeT(&dest->privateExponent.qInv, &src->privateExponent.qInv);
×
198
        break;
×
199
    case TPM_ALG_ECC:
×
200
        MemoryCopy2B(&dest->publicArea.unique.ecc.x.b,
×
201
                     &src->publicArea.unique.ecc.x.b,
202
                     sizeof(src->publicArea.unique.ecc.x.t.buffer));
203
        MemoryCopy2B(&dest->publicArea.unique.ecc.y.b,
×
204
                     &src->publicArea.unique.ecc.y.b,
205
                     sizeof(src->publicArea.unique.ecc.y.t.buffer));
206
        memset(&dest->privateExponent, 0, sizeof(dest->privateExponent));
×
207
        break;
208
    }
209

210
    dest->sensitive.sensitiveType = src->sensitive.sensitiveType;
×
211
    dest->sensitive.authValue = src->sensitive.authValue;
×
212
    dest->sensitive.seedValue = src->sensitive.seedValue;
×
213
    /* The RSA2048_TPMU_SENSITIVE_COMPOSITE is always a TPM2B */
214
    MemoryCopy2B(&dest->sensitive.sensitive.any.b,
×
215
                 &src->sensitive.sensitive.any.b,
216
                 sizeof(src->sensitive.sensitive.any.t.buffer));
217

218
    dest->qualifiedName = src->qualifiedName;
×
219
    dest->evictHandle = src->evictHandle;
×
220
    dest->name = src->name;
×
221
}
222

223
// Convert an RSA2048_OBJECT that was copied into buffer using MemoryCopy
224
TPM_RC
225
RSA2048_OBJECT_Buffer_To_OBJECT(OBJECT* newObject, BYTE* buffer, INT32 size)
×
226
{
227
    RSA2048_OBJECT    oldObject;
×
228
    TPM_RC        rc = 0;
×
229

230
    // get the attributes
231
    MemoryCopy(newObject, buffer, sizeof(newObject->attributes));
×
232
    if (ObjectIsSequence(newObject))
×
233
        {
234
            /* resuming old hash contexts is not supported */
235
            rc = TPM_RC_DISABLED;
236
        }
237
    else
238
        {
239
            if (size != sizeof(RSA2048_OBJECT))
×
240
                return TPM_RC_SIZE;
241
            MemoryCopy(&oldObject, buffer, sizeof(RSA2048_OBJECT));
×
242

243
            /* fill the newObject with the contents of the oldObject */
244
            RSA2048_OBJECT_To_OBJECT(newObject, &oldObject);
×
245
    }
246

247
    return rc;
248
}
249

250
/* The following are data structure from libtpms 0.9.x with RSA 3072 support.
251
 */
252
typedef union {
253
    struct {
254
        UINT16                  size;
255
        BYTE                    buffer[3072/8];
256
    }            t;
257
    TPM2B        b;
258
} RSA3072_TPM2B_PUBLIC_KEY_RSA;
259
MUST_BE(sizeof(RSA3072_TPM2B_PUBLIC_KEY_RSA) == 2 + 3072/8);
260

261
typedef union {
262
    TPM2B_DIGEST                 keyedHash;
263
    TPM2B_DIGEST                 sym;
264
    RSA3072_TPM2B_PUBLIC_KEY_RSA rsa;
265
    TPMS_ECC_POINT               ecc;
266
    TPMS_DERIVE                  derive;
267
} RSA3072_TPMU_PUBLIC_ID;
268
MUST_BE(sizeof(TPM2B_DIGEST) == 2 + BITS_TO_BYTES(512));
269
MUST_BE(sizeof(TPMS_ECC_POINT) == 2 * (2 + BITS_TO_BYTES(638)));
270
MUST_BE(sizeof(TPMS_DERIVE) == 2 * (2 + 32));
271
MUST_BE(sizeof(RSA3072_TPMU_PUBLIC_ID) == 2 + 3072/8);
272

273
typedef struct {
274
    TPMI_ALG_PUBLIC         type;
275
    TPMI_ALG_HASH           nameAlg;
276
    TPMA_OBJECT             objectAttributes;
277
    TPM2B_DIGEST            authPolicy;
278
    ARCH_PADDING(pad1, 2);
279
    TPMU_PUBLIC_PARMS       parameters;
280
    RSA3072_TPMU_PUBLIC_ID          unique;
281
    ARCH_PADDING(pad2, 2);
282
} RSA3072_TPMT_PUBLIC;
283
MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, nameAlg) == 2);
284
MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, objectAttributes) == 2 + 2);
285
MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, authPolicy) == 2 + 2 + 4);
286
MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, parameters) == 2 + 2 + 4 + 66 + 2/*!*/);
287
MUST_BE(offsetof(RSA3072_TPMT_PUBLIC, unique) == 2 + 2 + 4 + 66 + 2 + 20);
288
MUST_BE(sizeof(RSA3072_TPMT_PUBLIC) == 484);
289

290
typedef union {
291
    struct {
292
        UINT16                  size;
293
        BYTE                    buffer[((3072 / 8) / 2) * 5];
294
    }            t;
295
    TPM2B        b;
296
} RSA3072_TPM2B_PRIVATE_KEY_RSA;
297
MUST_BE(sizeof(RSA3072_TPM2B_PRIVATE_KEY_RSA) == 962);
298

299
typedef union {
300
    struct {
301
        UINT16                  size;
302
        BYTE                    buffer[((3072 / 8) / 2) * 5];
303
    }            t;
304
    TPM2B        b;
305
} RSA3072_TPM2B_PRIVATE_VENDOR_SPECIFIC;
306

307
typedef union {
308
    RSA3072_TPM2B_PRIVATE_KEY_RSA         rsa;
309
    TPM2B_ECC_PARAMETER                   ecc;
310
    TPM2B_SENSITIVE_DATA                  bits;
311
    TPM2B_SYM_KEY                         sym;
312
    RSA3072_TPM2B_PRIVATE_VENDOR_SPECIFIC any;
313
} RSA3072_TPMU_SENSITIVE_COMPOSITE;
314
MUST_BE(sizeof(TPM2B_ECC_PARAMETER) == 2 + BITS_TO_BYTES(638) /* BN P638 */);
315
MUST_BE(sizeof(TPM2B_SENSITIVE_DATA) == 2 + 128);
316
MUST_BE(sizeof(TPM2B_SYM_KEY) == 2 + BITS_TO_BYTES(256));
317

318
typedef struct {
319
    TPMI_ALG_PUBLIC             sensitiveType;
320
    TPM2B_AUTH                  authValue;
321
    TPM2B_DIGEST                seedValue;
322
    RSA3072_TPMU_SENSITIVE_COMPOSITE    sensitive;
323
} RSA3072_TPMT_SENSITIVE;
324
MUST_BE(sizeof(TPM2B_AUTH) == 2 + BITS_TO_BYTES(512));
325
MUST_BE(sizeof(TPM2B_DIGEST) == 2 + BITS_TO_BYTES(512));
326
MUST_BE(sizeof(RSA3072_TPMT_SENSITIVE) == 1096);
327

328
BN_TYPE(rsa3072_prime, (3072 / 2));
329

330
typedef struct RSA3072_privateExponent
331
{
332
    bn_rsa3072_prime_t          Q;
333
    bn_rsa3072_prime_t          dP;
334
    bn_rsa3072_prime_t          dQ;
335
    bn_rsa3072_prime_t          qInv;
336
} RSA3072_privateExponent_t;
337
MUST_BE(offsetof(RSA3072_privateExponent_t, dP) == 216);
338
MUST_BE(offsetof(RSA3072_privateExponent_t, dQ) == 216 + 216);
339
MUST_BE(offsetof(RSA3072_privateExponent_t, qInv) == 216 + 216 + 216);
340
MUST_BE(sizeof(RSA3072_privateExponent_t) == 864);
341

342
typedef struct RSA3072_OBJECT
343
{
344
    // The attributes field is required to be first followed by the publicArea.
345
    // This allows the overlay of the object structure and a sequence structure
346
    OBJECT_ATTRIBUTES     attributes;     // object attributes
347
    RSA3072_TPMT_PUBLIC     publicArea;     // public area of an object
348
    RSA3072_TPMT_SENSITIVE  sensitive;      // sensitive area of an object
349
#if 1                                        // libtpms added begin: keep
350
    RSA3072_privateExponent_t privateExponent;    // Additional field for the private
351
#endif                                        // libtpms added end
352
    TPM2B_NAME        qualifiedName;  // object qualified name
353
    ARCH_PADDING(pad1, 2);
354
    TPMI_DH_OBJECT    evictHandle;    // if the object is an evict object,
355
    // the original handle is kept here.
356
    // The 'working' handle will be the
357
    // handle of an object slot.
358
    TPM2B_NAME name;                  // Name of the object name. Kept here
359
    // to avoid repeatedly computing it.
360

361
    // libtpms added: SEED_COMPAT_LEVEL to use for deriving child keys
362
    SEED_COMPAT_LEVEL   seedCompatLevel;
363
    // libtpms added: OBJECT lies in NVRAM; to avoid that it needs different number
364
    // of bytes on 32 bit and 64 bit architectures, we need to make sure it's the
365
    // same size; simple padding at the end works here
366
    UINT8               _pad[3];
367
    ARCH_PADDING(pad2, 2);
368
} RSA3072_OBJECT;
369
MUST_BE(sizeof(OBJECT_ATTRIBUTES) == 4);
370
MUST_BE(offsetof(RSA3072_OBJECT, publicArea) == 4);
371
MUST_BE(offsetof(RSA3072_OBJECT, sensitive) == 4 + 484);
372
MUST_BE(offsetof(RSA3072_OBJECT, privateExponent) == 4 + 484 + 1096);
373
MUST_BE(offsetof(RSA3072_OBJECT, qualifiedName) == 4 + 484 + 1096 + 864);
374
MUST_BE(offsetof(RSA3072_OBJECT, evictHandle) == 4 + 484 + 1096 + 864 + 68 + 4);
375
MUST_BE(offsetof(RSA3072_OBJECT, name) == 4 + 484 + 1096 + 864 + 68 + 4 + 4);
376
MUST_BE(offsetof(RSA3072_OBJECT, seedCompatLevel) == 4 + 484 + 1096 + 864 + 68 + 4 + 4 + 70);
377
MUST_BE(offsetof(RSA3072_OBJECT, _pad) == 4 + 484 + 1096 + 864 + 68 + 4 + 4 + 70 + 1);
378
MUST_BE(sizeof(RSA3072_OBJECT) == 2600);
379

380
static inline void CopyFromRSA3072PrimeT(ci_prime_t* dst,
269,268✔
381
                                       const bn_rsa3072_prime_t* src)
382
{
383
    dst->allocated = src->allocated;
269,268✔
384
    dst->size = src->size;
269,268✔
385
    memcpy(dst->d, src->d, sizeof(src->d));
269,268✔
386
}
269,268✔
387

388
static inline void CopyToRSA3072PrimeT(bn_rsa3072_prime_t* dst,
1,732✔
389
                                       const ci_prime_t* src)
390
{
391
    dst->allocated = src->allocated;
1,732✔
392
    dst->size = src->size;
1,732✔
393
    memcpy(dst->d, src->d, sizeof(dst->d));
1,732✔
394
}
1,732✔
395

396
static void RSA3072_OBJECT_To_OBJECT(OBJECT* dest, const RSA3072_OBJECT* src)
67,513✔
397
{
398
    dest->attributes = src->attributes;
67,513✔
399
    dest->hierarchy = ObjectGetHierarchyFromAttributes(dest);
67,513✔
400

401
    dest->publicArea.type = src->publicArea.type;
67,513✔
402
    dest->publicArea.nameAlg = src->publicArea.nameAlg;
67,513✔
403
    dest->publicArea.objectAttributes = src->publicArea.objectAttributes;
67,513✔
404
    dest->publicArea.authPolicy = src->publicArea.authPolicy;
67,513✔
405
    dest->publicArea.parameters = src->publicArea.parameters;
67,513✔
406
    /* the unique part can be one or two TPM2B's */
407
    switch (dest->publicArea.type) {
67,513✔
408
    case TPM_ALG_KEYEDHASH:
×
409
        MemoryCopy2B(&dest->publicArea.unique.keyedHash.b,
×
410
                     &src->publicArea.unique.keyedHash.b,
411
                     sizeof(src->publicArea.unique.keyedHash.t.buffer));
412
        memset(&dest->privateExponent, 0, sizeof(dest->privateExponent));
×
413
        break;
414
    case TPM_ALG_SYMCIPHER:
×
415
        MemoryCopy2B(&dest->publicArea.unique.sym.b,
×
416
                     &src->publicArea.unique.sym.b,
417
                     sizeof(src->publicArea.unique.sym.t.buffer));
418
        memset(&dest->privateExponent, 0, sizeof(dest->privateExponent));
×
419
        break;
420
    case TPM_ALG_RSA:
67,317✔
421
        MemoryCopy2B(&dest->publicArea.unique.rsa.b,
67,317✔
422
                     &src->publicArea.unique.rsa.b,
423
                     sizeof(src->publicArea.unique.rsa.t.buffer));
424

425
        CopyFromRSA3072PrimeT(&dest->privateExponent.Q, &src->privateExponent.Q);
67,317✔
426
        CopyFromRSA3072PrimeT(&dest->privateExponent.dP, &src->privateExponent.dP);
67,317✔
427
        CopyFromRSA3072PrimeT(&dest->privateExponent.dQ, &src->privateExponent.dQ);
67,317✔
428
        CopyFromRSA3072PrimeT(&dest->privateExponent.qInv, &src->privateExponent.qInv);
67,317✔
429
        break;
67,317✔
430
    case TPM_ALG_ECC:
196✔
431
        MemoryCopy2B(&dest->publicArea.unique.ecc.x.b,
196✔
432
                     &src->publicArea.unique.ecc.x.b,
433
                     sizeof(src->publicArea.unique.ecc.x.t.buffer));
434
        MemoryCopy2B(&dest->publicArea.unique.ecc.y.b,
196✔
435
                     &src->publicArea.unique.ecc.y.b,
436
                     sizeof(src->publicArea.unique.ecc.y.t.buffer));
437
        memset(&dest->privateExponent, 0, sizeof(dest->privateExponent));
196✔
438
        break;
439
    }
440

441
    dest->sensitive.sensitiveType = src->sensitive.sensitiveType;
67,513✔
442
    dest->sensitive.authValue = src->sensitive.authValue;
67,513✔
443
    dest->sensitive.seedValue = src->sensitive.seedValue;
67,513✔
444
    /* The OLD_TPMU_SENSITIVE_COMPOSITE is always a TPM2B */
445
    MemoryCopy2B(&dest->sensitive.sensitive.any.b,
67,513✔
446
                 &src->sensitive.sensitive.any.b,
447
                 sizeof(src->sensitive.sensitive.any.t.buffer));
448

449
    dest->qualifiedName = src->qualifiedName;
67,513✔
450
    dest->evictHandle = src->evictHandle;
67,513✔
451
    dest->name = src->name;
67,513✔
452
    dest->seedCompatLevel = src->seedCompatLevel;
67,513✔
453
}
67,513✔
454

455
/* Convert an OBJECT to the (smaller) RSA3072_OBJECT. */
456
static void OBJECT_To_RSA3072_OBJECT(RSA3072_OBJECT* dest, const OBJECT* src)
463✔
457
{
458
    dest->attributes = src->attributes;
463✔
459

460
    dest->publicArea.type = src->publicArea.type;
463✔
461
    dest->publicArea.nameAlg = src->publicArea.nameAlg;
463✔
462
    dest->publicArea.objectAttributes = src->publicArea.objectAttributes;
463✔
463
    dest->publicArea.authPolicy = src->publicArea.authPolicy;
463✔
464
    dest->publicArea.parameters = src->publicArea.parameters;
463✔
465
    /* the unique part can be one or two TPM2B's */
466
    switch (dest->publicArea.type) {
463✔
467
    case TPM_ALG_KEYEDHASH:
×
468
        MemoryCopy2B(&dest->publicArea.unique.keyedHash.b,
×
469
                     &src->publicArea.unique.keyedHash.b,
470
                     sizeof(dest->publicArea.unique.keyedHash.t.buffer));
471
        break;
×
472
    case TPM_ALG_SYMCIPHER:
×
473
        MemoryCopy2B(&dest->publicArea.unique.sym.b,
×
474
                     &src->publicArea.unique.sym.b,
475
                     sizeof(dest->publicArea.unique.sym.t.buffer));
476
        break;
×
477
    case TPM_ALG_RSA:
433✔
478
        MemoryCopy2B(&dest->publicArea.unique.rsa.b,
433✔
479
                     &src->publicArea.unique.rsa.b,
480
                     sizeof(dest->publicArea.unique.rsa.t.buffer));
481

482
        CopyToRSA3072PrimeT(&dest->privateExponent.Q, &src->privateExponent.Q);
433✔
483
        CopyToRSA3072PrimeT(&dest->privateExponent.dP, &src->privateExponent.dP);
433✔
484
        CopyToRSA3072PrimeT(&dest->privateExponent.dQ, &src->privateExponent.dQ);
433✔
485
        CopyToRSA3072PrimeT(&dest->privateExponent.qInv, &src->privateExponent.qInv);
433✔
486
        break;
433✔
487
    case TPM_ALG_ECC:
30✔
488
        MemoryCopy2B(&dest->publicArea.unique.ecc.x.b,
30✔
489
                     &src->publicArea.unique.ecc.x.b,
490
                     sizeof(dest->publicArea.unique.ecc.x.t.buffer));
491
        MemoryCopy2B(&dest->publicArea.unique.ecc.y.b,
30✔
492
                     &src->publicArea.unique.ecc.y.b,
493
                     sizeof(dest->publicArea.unique.ecc.y.t.buffer));
494
        break;
30✔
495
    }
496

497
    dest->sensitive.sensitiveType = src->sensitive.sensitiveType;
463✔
498
    dest->sensitive.authValue = src->sensitive.authValue;
463✔
499
    dest->sensitive.seedValue = src->sensitive.seedValue;
463✔
500
    /* The OLD_TPMU_SENSITIVE_COMPOSITE is always a TPM2B */
501
    MemoryCopy2B(&dest->sensitive.sensitive.any.b,
463✔
502
                 &src->sensitive.sensitive.any.b,
503
                 sizeof(dest->sensitive.sensitive.any.t.buffer));
504

505
    dest->qualifiedName = src->qualifiedName;
463✔
506
    dest->evictHandle = src->evictHandle;
463✔
507
    dest->name = src->name;
463✔
508
    dest->seedCompatLevel = src->seedCompatLevel;
463✔
509
    MemorySet(dest->_pad, 0, sizeof(dest->_pad));
463✔
510
}
463✔
511

512
TPM_RC
513
RSA3072_OBJECT_Buffer_To_OBJECT(OBJECT *object, BYTE *buffer, INT32 size)
67,513✔
514
{
515
    RSA3072_OBJECT rsa3072_object;
67,513✔
516

517
    if (size != sizeof(RSA3072_OBJECT))
67,513✔
518
        return TPM_RC_SIZE;
519

520
    MemoryCopy(&rsa3072_object, buffer, size);
67,513✔
521

522
    RSA3072_OBJECT_To_OBJECT(object, &rsa3072_object);
67,513✔
523

524
    return 0;
67,513✔
525
}
526

527
UINT32 OBJECT_To_Buffer_As_RSA3072_OBJECT(OBJECT* object, BYTE* buffer, UINT32 size)
463✔
528
{
529
    RSA3072_OBJECT rsa3072_object;
463✔
530
    UINT32         written = sizeof(rsa3072_object);
463✔
531

532
    OBJECT_To_RSA3072_OBJECT(&rsa3072_object, object);
463✔
533

534
    pAssert(size >= sizeof(rsa3072_object));
463✔
535
    MemoryCopy(buffer, &rsa3072_object, sizeof(rsa3072_object));
463✔
536

537
    return written;
463✔
538
}
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