Coverage Report

Created: 2026-03-31 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libtpms/src/tpm2/NVMarshal.c
Line
Count
Source
1
// SPDX-License-Identifier: BSD-2-Clause
2
3
// (c) Copyright IBM Corporation 2017,2018.
4
5
#include <string.h>
6
#include <inttypes.h>
7
8
#include "assert.h"
9
10
#define _CRYPT_HASH_C_
11
#define SESSION_PROCESS_C
12
#define NV_C
13
#define OBJECT_C
14
#define PCR_C
15
#define SESSION_C
16
#include "Platform.h"
17
#include "NVMarshal.h"
18
#include "Marshal_fp.h"
19
#include "Unmarshal_fp.h"
20
#include "Global.h"
21
#include "TpmTcpProtocol.h"
22
#include "Simulator_fp.h"
23
#include "BackwardsCompatibilityBitArray.h"
24
#include "BackwardsCompatibilityObject.h"
25
#include <platform_interface/prototypes/platform_failure_mode_fp.h>
26
27
#define TPM_HAVE_TPM2_DECLARATIONS
28
#include "tpm_library_intern.h"
29
30
MUST_BE(CONTEXT_INTEGRITY_HASH_ALG == TPM_ALG_SHA512);
31
32
/*
33
 * The TPM2 maintains a pcrAllocated shadow variable; the current active one is
34
 * in gp.pcrAllocated and the one to be active after reboot is in NVRAM. So,
35
 * this means we have to restore two of these variables when we resume. The
36
 * tricky part is that the global gp will be restored by reading from NVRAM.
37
 * Once that has been done the gp.pcrAllocated needs to be restored with the
38
 * one that is supposed to be active. All of this is only supposed to happen
39
 * when we resume a VM's volatile state.
40
 */
41
static struct shadow {
42
    TPML_PCR_SELECTION  pcrAllocated;
43
    BOOL                pcrAllocatedIsNew;
44
} shadow;
45
46
/* prevent misconfiguration: */
47
typedef char assertion_failed_nvram[
48
    (NV_USER_DYNAMIC_END < NV_USER_DYNAMIC) ? -1 : 0];
49
50
typedef struct
51
{
52
    UINT16 version;
53
    UINT32 magic;
54
    UINT16 min_version; /* min. implementation version to accept the blob */
55
} NV_HEADER;
56
57
static UINT8 BOOL_Marshal(BOOL *boolean, BYTE **buffer, INT32 *size);
58
static TPM_RC BOOL_Unmarshal(BOOL *boolean, BYTE **buffer, INT32 *size);
59
60
/*
61
 * There are compile-time optional variables that we marshal. To allow
62
 * for some flexibility, we marshal them in such a way that these
63
 * variables can be skipped if they are in the byte stream but are not
64
 * needed by the implementation. The following block_skip data structure
65
 * and related functions address this issue.
66
 */
67
typedef struct {
68
    size_t idx;
69
    size_t sz;
70
    struct position {
71
        BYTE *buffer;
72
        INT32 size;
73
    } pos[5]; /* more only needed for nested compile-time #ifdef's */
74
} block_skip_t;
75
76
/*
77
 * This function is to be called when an optional block follows. It inserts
78
 * a BOOL into the byte stream indicating whether the block is there or not.
79
 * Then it leaves a 16bit zero in the byt stream and remembers the location
80
 * of that zero. We will update the location with the number of optional
81
 * bytes written when block_skip_write_pop() is called.
82
 */
83
static UINT16
84
block_skip_write_push(block_skip_t *bs, BOOL has_block,
85
591k
                      BYTE **buffer, INT32 *size) {
86
591k
    UINT16 written , w;
87
591k
    UINT16 zero = 0;
88
591k
    written = BOOL_Marshal(&has_block, buffer, size);
89
591k
    bs->pos[bs->idx].buffer = *buffer;
90
591k
    bs->pos[bs->idx].size = *size;
91
591k
    w = UINT16_Marshal(&zero, buffer, size);
92
591k
    if (w) {
93
591k
        bs->idx++;
94
591k
        pAssert(bs->idx < bs->sz);
95
591k
        written += w;
96
591k
    }
97
591k
    return written;
98
591k
}
99
100
/*
101
 * This function must be called for every block_skip_write_push() call.
102
 * It has to be called once a compile-time optional block has been
103
 * processed. It must be called after the #endif.
104
 * In this function we updated the previously remembered location with
105
 * the numbers of bytes to skip in case a block is there but it is not
106
 * needed.
107
 */
108
static void
109
591k
block_skip_write_pop(block_skip_t *bs, INT32 *size) {
110
591k
    UINT16 skip;
111
591k
    unsigned i = --bs->idx;
112
591k
    pAssert_VOID_OK((int)bs->idx >= 0);
113
591k
    skip = bs->pos[i].size - *size - sizeof(UINT16);
114
591k
    UINT16_Marshal(&skip, &bs->pos[i].buffer, &bs->pos[i].size);
115
591k
}
116
117
/*
118
 * This function must be called when unmarshalling a byte stream and
119
 * a compile-time optional block follows. In case the compile-time
120
 * optional block is there but not in the byte stream, we log an error.
121
 * In case the bytes stream contains the block, but we don't need it
122
 * we skip it. In the other cases we don't need to do anything since
123
 * the code is 'in sync' with the byte stream.
124
 */
125
static TPM_RC
126
block_skip_read(BOOL needs_block, BYTE **buffer, INT32 *size,
127
                const char *name, const char *field,
128
                BOOL *skip_code)
129
887k
{
130
887k
    TPM_RC rc = TPM_RC_SUCCESS;
131
887k
    BOOL has_block;
132
887k
    UINT16 blocksize;
133
134
887k
    if (rc == TPM_RC_SUCCESS) {
135
887k
        rc = BOOL_Unmarshal(&has_block, buffer, size);
136
887k
    }
137
887k
    if (rc == TPM_RC_SUCCESS) {
138
887k
        rc = UINT16_Unmarshal(&blocksize, buffer, size);
139
887k
    }
140
887k
    if (rc == TPM_RC_SUCCESS) {
141
887k
        if (!has_block && needs_block) {
142
0
            TPMLIB_LogTPM2Error("%s needs missing %s\n", name, field);
143
0
            rc = TPM_RC_BAD_PARAMETER;
144
887k
        } else if (has_block && !needs_block) {
145
            /* byte stream has the data but we don't need them */
146
608k
            *buffer += blocksize;
147
608k
            *size -= blocksize;
148
608k
            *skip_code = TRUE;
149
608k
        } else if (!has_block && !needs_block) {
150
            /* no block but also none needed */
151
12.0k
            *skip_code = TRUE;
152
12.0k
        }
153
887k
    }
154
887k
    return rc;
155
887k
}
156
157
#define BLOCK_SKIP_INIT       \
158
420k
    block_skip_t block_skip = {     \
159
420k
        .idx = 0,       \
160
420k
        .sz = ARRAY_SIZE(block_skip.pos), \
161
420k
    }
162
163
#define BLOCK_SKIP_WRITE_PUSH(HAS_BLOCK, BUFFER, POS) \
164
591k
    block_skip_write_push(&block_skip, HAS_BLOCK, BUFFER, POS)
165
166
#define BLOCK_SKIP_WRITE_POP(SIZE) \
167
591k
    block_skip_write_pop(&block_skip, SIZE)
168
169
#define BLOCK_SKIP_WRITE_CHECK \
170
402k
    pAssert(block_skip.idx == 0)
171
172
#define BLOCK_SKIP_READ(SKIP_MARK, NEEDS_BLOCK, BUFFER, SIZE, NAME, FIELD) \
173
887k
    {                 \
174
887k
        BOOL skip_code = FALSE;           \
175
887k
        rc = block_skip_read(NEEDS_BLOCK, buffer, size,     \
176
887k
                             NAME, FIELD, &skip_code);      \
177
887k
        if (rc == TPM_RC_SUCCESS && skip_code)       \
178
887k
            goto SKIP_MARK;           \
179
887k
    }
180
181
static unsigned int _ffsll(long long bits)
182
0
{
183
0
    size_t i = 0;
184
185
0
    for (i = 0; i < 8 * sizeof(bits); i++) {
186
0
        if (bits & (1ULL << i))
187
0
            return i + 1;
188
0
    }
189
0
    return 0;
190
0
}
191
192
/* BOOL is 'int' but we store a single byte */
193
static UINT8
194
BOOL_Marshal(BOOL *boolean, BYTE **buffer, INT32 *size)
195
760k
{
196
760k
    UINT8 _bool = (*boolean != 0);
197
760k
    UINT16 written = 0;
198
760k
    written += UINT8_Marshal(&_bool, buffer, size);
199
760k
    return written;
200
760k
}
201
202
static TPM_RC
203
BOOL_Unmarshal(BOOL *boolean, BYTE **buffer, INT32 *size)
204
1.17M
{
205
1.17M
    UINT8 _bool;
206
1.17M
    TPM_RC rc = TPM_RC_SUCCESS;
207
208
1.17M
    if (rc == TPM_RC_SUCCESS) {
209
1.17M
        rc = UINT8_Unmarshal(&_bool, buffer, size);
210
1.17M
    }
211
212
1.17M
    if (rc == TPM_RC_SUCCESS) {
213
1.17M
        *boolean = (_bool != 0);
214
1.17M
    }
215
216
1.17M
    return rc;
217
1.17M
}
218
219
static UINT16
220
SEED_COMPAT_LEVEL_Marshal(SEED_COMPAT_LEVEL *source,
221
                          BYTE **buffer, INT32 *size)
222
79.4k
{
223
79.4k
    return UINT8_Marshal((UINT8 *)source, buffer, size);
224
79.4k
}
225
226
static TPM_RC
227
SEED_COMPAT_LEVEL_Unmarshal(SEED_COMPAT_LEVEL *source,
228
                            BYTE **buffer, INT32 *size,
229
                            const char *name)
230
85.2k
{
231
85.2k
    TPM_RC rc;
232
233
85.2k
    rc = UINT8_Unmarshal((UINT8 *)source, buffer, size);
234
85.2k
    if (rc == TPM_RC_SUCCESS && *source > SEED_COMPAT_LEVEL_LAST) {
235
0
        TPMLIB_LogTPM2Error("%s compatLevel '%u' higher than supported '%u'\n",
236
0
                            name, *source, SEED_COMPAT_LEVEL_LAST);
237
0
        rc = TPM_RC_BAD_VERSION;
238
0
    }
239
85.2k
    return rc;
240
85.2k
}
241
242
static int
243
TPM2B_Cmp(const TPM2B *t1, const TPM2B *t2)
244
36.2k
{
245
36.2k
    if (t1->size != t2->size)
246
0
        return 1;
247
248
36.2k
    return memcmp(t1->buffer, t2->buffer, t1->size);
249
36.2k
}
250
251
static UINT16
252
TPM2B_PROOF_Marshal(TPM2B_PROOF *source, BYTE **buffer, INT32 *size)
253
79.1k
{
254
79.1k
    UINT16 written = 0;
255
79.1k
    written += TPM2B_Marshal(&source->b, sizeof(source->t.buffer), buffer, size);
256
79.1k
    return written;
257
79.1k
}
258
259
static TPM_RC
260
TPM2B_PROOF_Unmarshal(TPM2B_PROOF *target, BYTE **buffer, INT32 *size)
261
84.5k
{
262
84.5k
    TPM_RC rc = TPM_RC_SUCCESS;
263
264
84.5k
    if (rc == TPM_RC_SUCCESS) {
265
84.5k
  rc = TPM2B_Unmarshal(&target->b, sizeof(target->t.buffer), buffer, size);
266
84.5k
    }
267
84.5k
    return rc;
268
84.5k
}
269
270
/* Marshal a string including its terminating NUL byte. A NULL pointer will be
271
 * marshalled with 0 bytes and will be unmarshalled as a NULL pointer again.
272
 */
273
static UINT16
274
String_Marshal(const char *source, BYTE **buffer, INT32 *size)
275
0
{
276
0
    UINT16 written = 0;
277
0
    UINT16 len = 0;
278
279
0
    if (source)
280
0
        len = (UINT16)strlen(source) + 1;
281
0
    written += UINT16_Marshal(&len, buffer, size);
282
283
0
    if (len > 0 && *size >= len) {
284
0
        memcpy(*buffer, source, len);
285
0
        *buffer += len;
286
0
        *size -= len;
287
288
0
        written += len;
289
0
    }
290
291
0
    return written;
292
0
}
293
294
static TPM_RC
295
String_Unmarshal(char **target, BYTE **buffer, INT32 *size)
296
0
{
297
0
    TPM_RC rc = TPM_RC_SUCCESS;
298
0
    UINT16 len;
299
300
0
    *target = NULL;
301
302
0
    if (rc == TPM_RC_SUCCESS) {
303
0
        rc = UINT16_Unmarshal(&len, buffer, size);
304
0
    }
305
0
    if (rc == TPM_RC_SUCCESS) {
306
0
        if (*size < len) {
307
0
            rc = TPM_RC_INSUFFICIENT;
308
0
        } else if (len > 0) {
309
0
            *target = malloc(len);
310
0
            if (!*target) {
311
0
                rc = TPM_RC_MEMORY;
312
0
            }
313
0
        }
314
0
    }
315
0
    if (rc == TPM_RC_SUCCESS) {
316
0
        if (len > 0) {
317
0
            memcpy(*target, *buffer, len);
318
0
            *buffer += len;
319
0
            *size -= len;
320
0
        }
321
0
    }
322
323
0
    return rc;
324
0
}
325
326
static TPM_RC
327
UINT32_Unmarshal_Check(UINT32 *data, UINT32 exp, BYTE **buffer, INT32 *size,
328
                       const char *msg)
329
24.1k
{
330
24.1k
    TPM_RC rc = TPM_RC_SUCCESS;
331
332
24.1k
    if (rc == TPM_RC_SUCCESS) {
333
24.1k
        rc = UINT32_Unmarshal(data, buffer, size);
334
24.1k
    }
335
24.1k
    if (rc == TPM_RC_SUCCESS && exp != *data) {
336
0
        TPMLIB_LogTPM2Error("%s: Expected value: 0x%08x, found: 0x%08x\n",
337
0
                            msg, exp, *data);
338
0
        rc = TPM_RC_BAD_TAG;
339
0
    }
340
24.1k
    return rc;
341
24.1k
}
342
343
static void
344
NV_HEADER_INIT(NV_HEADER *t, UINT16 version, UINT32 magic, UINT16 min_version)
345
420k
{
346
420k
    t->version = version;
347
420k
    t->magic = magic;
348
420k
    t->min_version = min_version;
349
420k
}
350
351
static UINT16
352
NV_HEADER_Marshal(BYTE **buffer, INT32 *size, UINT16 version, UINT32 magic,
353
                  UINT16 min_version)
354
420k
{
355
420k
    UINT16 written;
356
420k
    NV_HEADER hdr;
357
358
420k
    NV_HEADER_INIT(&hdr, version, magic, min_version);
359
360
420k
    written = UINT16_Marshal(&hdr.version, buffer, size);
361
420k
    written += UINT32_Marshal(&hdr.magic, buffer, size);
362
420k
    if (version >= 2)
363
420k
        written += UINT16_Marshal(&hdr.min_version, buffer, size);
364
365
420k
    return written;
366
420k
}
367
368
static TPM_RC
369
NV_HEADER_UnmarshalVerbose(NV_HEADER *data, BYTE **buffer, INT32 *size,
370
                           UINT16 cur_version, UINT32 exp_magic, BOOL verbose)
371
644k
{
372
644k
    TPM_RC rc = TPM_RC_SUCCESS;
373
374
644k
    if (rc == TPM_RC_SUCCESS) {
375
644k
        rc = UINT16_Unmarshal(&data->version, buffer, size);
376
644k
    }
377
644k
    if (rc == TPM_RC_SUCCESS) {
378
644k
        rc = UINT32_Unmarshal(&data->magic, buffer, size);
379
644k
    }
380
644k
    if (rc == TPM_RC_SUCCESS && exp_magic != data->magic) {
381
0
        if (verbose)
382
0
            TPMLIB_LogTPM2Error("%s: Invalid magic. Expected 0x%08x, got 0x%08x\n",
383
0
                                __func__, exp_magic, data->magic);
384
0
        rc = TPM_RC_BAD_TAG;
385
0
    }
386
387
644k
    data->min_version = 0;
388
644k
    if (rc == TPM_RC_SUCCESS && data->version >= 2) {
389
390
644k
        rc = UINT16_Unmarshal(&data->min_version, buffer, size);
391
392
644k
        if (rc == TPM_RC_SUCCESS && data->min_version > cur_version) {
393
0
            if (verbose)
394
0
                TPMLIB_LogTPM2Error("%s: Minimum version %u higher than "
395
0
                                    "implementation version %u for type 0x%08x\n",
396
0
                                    __func__, data->min_version, cur_version,
397
0
                                    exp_magic);
398
0
            rc = TPM_RC_BAD_VERSION;
399
0
        }
400
644k
    }
401
402
644k
    return rc;
403
644k
}
404
405
static TPM_RC
406
NV_HEADER_Unmarshal(NV_HEADER *data, BYTE **buffer, INT32 *size,
407
                    UINT16 cur_version, UINT32 exp_magic)
408
608k
{
409
608k
    return NV_HEADER_UnmarshalVerbose(data, buffer, size, cur_version,
410
608k
                                      exp_magic, true);
411
608k
}
412
413
438
#define NV_INDEX_MAGIC 0x2547265a
414
438
#define NV_INDEX_VERSION 2
415
static UINT16
416
NV_INDEX_Marshal(NV_INDEX *data, BYTE **buffer, INT32 *size)
417
219
{
418
219
    UINT16 written;
419
219
    BLOCK_SKIP_INIT;
420
421
219
    written = NV_HEADER_Marshal(buffer, size,
422
219
                                NV_INDEX_VERSION,
423
219
                                NV_INDEX_MAGIC, 1);
424
425
219
    written += TPMS_NV_PUBLIC_Marshal(&data->publicArea, buffer, size);
426
219
    written += TPM2B_AUTH_Marshal(&data->authValue, buffer, size);
427
428
219
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
429
    /* future versions append below this line */
430
431
219
    BLOCK_SKIP_WRITE_POP(size);
432
433
219
    BLOCK_SKIP_WRITE_CHECK;
434
435
219
    return written;
436
219
}
437
438
static TPM_RC
439
NV_INDEX_Unmarshal(NV_INDEX *data, BYTE **buffer, INT32 *size)
440
219
{
441
219
    TPM_RC rc = TPM_RC_SUCCESS;
442
219
    NV_HEADER hdr;
443
444
219
    if (rc == TPM_RC_SUCCESS) {
445
219
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
446
219
                                 NV_INDEX_VERSION, NV_INDEX_MAGIC);
447
219
    }
448
449
219
    if (rc == TPM_RC_SUCCESS) {
450
219
        rc = TPMS_NV_PUBLIC_Unmarshal(&data->publicArea, buffer, size);
451
219
    }
452
219
    if (rc == TPM_RC_SUCCESS) {
453
219
        rc = TPM2B_AUTH_Unmarshal(&data->authValue, buffer, size);
454
219
    }
455
456
    /* version 2 starts having indicator for next versions that we can skip;
457
       this allows us to downgrade state */
458
219
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
459
219
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
460
219
                        "NV_INDEX", "version 3 or later");
461
        /* future versions nest-append here */
462
0
    }
463
219
skip_future_versions:
464
219
    return rc;
465
219
}
466
467
66.6k
#define DRBG_STATE_MAGIC 0x6fe83ea1
468
66.6k
#define DRBG_STATE_VERSION 2
469
static UINT16
470
DRBG_STATE_Marshal(DRBG_STATE *data, BYTE **buffer, INT32 *size)
471
30.4k
{
472
30.4k
    UINT16 written;
473
30.4k
    size_t i;
474
30.4k
    UINT16 array_size;
475
30.4k
    BLOCK_SKIP_INIT;
476
477
30.4k
    written = NV_HEADER_Marshal(buffer, size,
478
30.4k
                                DRBG_STATE_VERSION, DRBG_STATE_MAGIC, 1);
479
30.4k
    written += UINT64_Marshal(&data->reseedCounter, buffer, size);
480
30.4k
    written += UINT32_Marshal(&data->magic, buffer, size);
481
482
30.4k
    array_size = sizeof(data->seed.bytes);
483
30.4k
    written += UINT16_Marshal(&array_size, buffer, size);
484
30.4k
    written += Array_Marshal(&data->seed.bytes[0], array_size, buffer, size);
485
486
30.4k
    array_size = ARRAY_SIZE(data->lastValue);
487
30.4k
    written += UINT16_Marshal(&array_size, buffer, size);
488
152k
    for (i = 0; i < array_size; i++) {
489
121k
        written += UINT32_Marshal(&data->lastValue[i], buffer, size);
490
121k
    }
491
492
30.4k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
493
    /* future versions append below this line */
494
495
30.4k
    BLOCK_SKIP_WRITE_POP(size);
496
497
30.4k
    BLOCK_SKIP_WRITE_CHECK;
498
499
30.4k
    return written;
500
30.4k
}
501
502
static TPM_RC
503
DRBG_STATE_Unmarshal(DRBG_STATE *data, BYTE **buffer, INT32 *size)
504
36.2k
{
505
36.2k
    TPM_RC rc= TPM_RC_SUCCESS;
506
36.2k
    size_t i;
507
36.2k
    NV_HEADER hdr;
508
36.2k
    UINT16 array_size = 0;
509
510
36.2k
    if (rc == TPM_RC_SUCCESS) {
511
36.2k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
512
36.2k
                                 DRBG_STATE_VERSION, DRBG_STATE_MAGIC);
513
36.2k
    }
514
515
36.2k
    if (rc == TPM_RC_SUCCESS) {
516
36.2k
        rc = UINT64_Unmarshal(&data->reseedCounter, buffer, size);
517
36.2k
    }
518
36.2k
    if (rc == TPM_RC_SUCCESS) {
519
36.2k
        rc = UINT32_Unmarshal(&data->magic, buffer, size);
520
36.2k
    }
521
522
36.2k
    if (rc == TPM_RC_SUCCESS) {
523
36.2k
        rc = UINT16_Unmarshal(&array_size, buffer, size);
524
36.2k
    }
525
36.2k
    if (rc == TPM_RC_SUCCESS) {
526
36.2k
        if (array_size != ARRAY_SIZE(data->seed.bytes)) {
527
0
            TPMLIB_LogTPM2Error("Non-matching DRBG_STATE seed array size. "
528
0
                                "Expected %zu, got %u\n",
529
0
                                ARRAY_SIZE(data->seed.bytes), array_size);
530
0
            rc = TPM_RC_SIZE;
531
0
        }
532
36.2k
    }
533
36.2k
    if (rc == TPM_RC_SUCCESS) {
534
36.2k
        rc = Array_Unmarshal(&data->seed.bytes[0], array_size, buffer, size);
535
36.2k
    }
536
537
36.2k
    if (rc == TPM_RC_SUCCESS) {
538
36.2k
        rc = UINT16_Unmarshal(&array_size, buffer, size);
539
36.2k
    }
540
36.2k
    if (rc == TPM_RC_SUCCESS) {
541
36.2k
        if (array_size != ARRAY_SIZE(data->lastValue)) {
542
0
            TPMLIB_LogTPM2Error("Non-matching DRBG_STATE lastValue array size. "
543
0
                                "Expected %zu, got %u\n",
544
0
                                ARRAY_SIZE(data->lastValue), array_size);
545
0
            rc = TPM_RC_SIZE;
546
0
        }
547
36.2k
    }
548
36.2k
    if (rc == TPM_RC_SUCCESS) {
549
181k
        for (i = 0; i < ARRAY_SIZE(data->lastValue) && rc == TPM_RC_SUCCESS; i++) {
550
144k
            rc = UINT32_Unmarshal(&data->lastValue[i], buffer, size);
551
144k
        }
552
36.2k
    }
553
554
    /* version 2 starts having indicator for next versions that we can skip;
555
       this allows us to downgrade state */
556
36.2k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
557
36.2k
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
558
36.2k
                        "DRBG_STATE", "version 3 or later");
559
        /* future versions nest-append here */
560
0
    }
561
36.2k
skip_future_versions:
562
563
36.2k
    return rc;
564
36.2k
}
565
566
48.5k
#define PCR_POLICY_MAGIC 0x176be626
567
48.5k
#define PCR_POLICY_VERSION 2
568
static UINT16
569
PCR_POLICY_Marshal(PCR_POLICY *data, BYTE **buffer, INT32 *size)
570
24.3k
{
571
24.3k
    UINT16 written;
572
24.3k
    unsigned i;
573
24.3k
    UINT16 array_size = ARRAY_SIZE(data->hashAlg);
574
24.3k
    BLOCK_SKIP_INIT;
575
576
24.3k
    written = NV_HEADER_Marshal(buffer, size,
577
24.3k
                                PCR_POLICY_VERSION,
578
24.3k
                                PCR_POLICY_MAGIC, 1);
579
580
24.3k
    written += UINT16_Marshal(&array_size, buffer, size);
581
582
48.7k
    for (i = 0; i < array_size; i++) {
583
        /* TPMI_ALG_HASH_Unmarshal errors on algid 0 */
584
24.3k
        written += TPM_ALG_ID_Marshal(&data->hashAlg[i], buffer, size);
585
24.3k
        written += TPM2B_DIGEST_Marshal(&data->policy[i], buffer, size);
586
24.3k
    }
587
588
24.3k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
589
    /* future versions append below this line */
590
591
24.3k
    BLOCK_SKIP_WRITE_POP(size);
592
593
24.3k
    BLOCK_SKIP_WRITE_CHECK;
594
595
24.3k
    return written;
596
24.3k
}
597
598
static TPM_RC
599
PCR_POLICY_Unmarshal(PCR_POLICY *data, BYTE **buffer, INT32 *size)
600
24.1k
{
601
24.1k
    TPM_RC rc= TPM_RC_SUCCESS;
602
24.1k
    unsigned i;
603
24.1k
    UINT16 array_size;
604
24.1k
    NV_HEADER hdr;
605
606
24.1k
    if (rc == TPM_RC_SUCCESS) {
607
24.1k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
608
24.1k
                                 PCR_POLICY_VERSION, PCR_POLICY_MAGIC);
609
24.1k
    }
610
611
24.1k
    if (rc == TPM_RC_SUCCESS) {
612
24.1k
        rc = UINT16_Unmarshal(&array_size, buffer, size);
613
24.1k
    }
614
615
24.1k
    if (rc == TPM_RC_SUCCESS) {
616
24.1k
        if (array_size != ARRAY_SIZE(data->hashAlg)) {
617
0
            TPMLIB_LogTPM2Error("Non-matching PCR_POLICY array size. "
618
0
                                "Expected %zu, got %u\n",
619
0
                                ARRAY_SIZE(data->hashAlg), array_size);
620
0
            rc = TPM_RC_SIZE;
621
0
        }
622
24.1k
    }
623
624
24.1k
    for (i = 0;
625
48.3k
         rc == TPM_RC_SUCCESS &&
626
48.3k
         i < ARRAY_SIZE(data->hashAlg);
627
24.1k
         i++) {
628
        /* TPMI_ALG_HASH_Unmarshal errors on algid 0 */
629
24.1k
        if (rc == TPM_RC_SUCCESS) {
630
24.1k
            rc = TPM_ALG_ID_Unmarshal(&data->hashAlg[i], buffer, size);
631
24.1k
        }
632
24.1k
        if (rc == TPM_RC_SUCCESS) {
633
24.1k
            rc = TPM2B_DIGEST_Unmarshal(&data->policy[i], buffer, size);
634
24.1k
        }
635
24.1k
    }
636
637
    /* version 2 starts having indicator for next versions that we can skip;
638
       this allows us to downgrade state */
639
24.1k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
640
24.1k
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
641
24.1k
                        "PCR_POLICY", "version 3 or later");
642
        /* future versions nest-append here */
643
0
    }
644
24.1k
skip_future_versions:
645
24.1k
    return rc;
646
24.1k
}
647
648
66.6k
#define ORDERLY_DATA_MAGIC      0x56657887
649
66.6k
#define ORDERLY_DATA_VERSION 2
650
651
static UINT16
652
ORDERLY_DATA_Marshal(ORDERLY_DATA *data, BYTE **buffer, INT32 *size)
653
30.4k
{
654
30.4k
    UINT16 written;
655
30.4k
    BOOL has_block;
656
30.4k
    BLOCK_SKIP_INIT;
657
658
30.4k
    written =  NV_HEADER_Marshal(buffer, size,
659
30.4k
                                 ORDERLY_DATA_VERSION, ORDERLY_DATA_MAGIC, 1);
660
30.4k
    written += UINT64_Marshal(&data->clock, buffer, size);
661
30.4k
    written += UINT8_Marshal(&data->clockSafe, buffer, size);
662
663
30.4k
    written += DRBG_STATE_Marshal(&data->drbgState, buffer, size);
664
665
30.4k
#if ACCUMULATE_SELF_HEAL_TIMER
666
30.4k
    has_block = TRUE;
667
#else
668
    has_block = FALSE;
669
#endif
670
30.4k
    written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
671
672
30.4k
#if ACCUMULATE_SELF_HEAL_TIMER
673
30.4k
    written += UINT64_Marshal(&data->selfHealTimer, buffer, size);
674
30.4k
    written += UINT64_Marshal(&data->lockoutTimer, buffer, size);
675
30.4k
    written += UINT64_Marshal(&data->time, buffer, size);
676
30.4k
#endif // ACCUMULATE_SELF_HEAL_TIMER
677
678
30.4k
    BLOCK_SKIP_WRITE_POP(size);
679
680
30.4k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
681
    /* future versions append below this line */
682
683
30.4k
    BLOCK_SKIP_WRITE_POP(size);
684
685
30.4k
    BLOCK_SKIP_WRITE_CHECK;
686
687
30.4k
    return written;
688
30.4k
}
689
690
static TPM_RC
691
ORDERLY_DATA_Unmarshal(ORDERLY_DATA *data, BYTE **buffer, INT32 *size)
692
36.2k
{
693
36.2k
    TPM_RC rc = TPM_RC_SUCCESS;
694
36.2k
    BOOL needs_block;
695
36.2k
    NV_HEADER hdr;
696
697
36.2k
    if (rc == TPM_RC_SUCCESS) {
698
36.2k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
699
36.2k
                                 ORDERLY_DATA_VERSION, ORDERLY_DATA_MAGIC);
700
36.2k
    }
701
36.2k
    if (rc == TPM_RC_SUCCESS) {
702
36.2k
        rc = UINT64_Unmarshal(&data->clock, buffer, size);
703
36.2k
    }
704
36.2k
    if (rc == TPM_RC_SUCCESS) {
705
36.2k
        rc = UINT8_Unmarshal(&data->clockSafe, buffer, size);
706
36.2k
    }
707
708
36.2k
    if (rc == TPM_RC_SUCCESS) {
709
36.2k
        rc = DRBG_STATE_Unmarshal(&data->drbgState, buffer, size);
710
36.2k
    }
711
712
36.2k
#if ACCUMULATE_SELF_HEAL_TIMER
713
36.2k
    needs_block = TRUE;
714
#else
715
    needs_block = FALSE;
716
#endif
717
36.2k
    if (rc == TPM_RC_SUCCESS) {
718
36.2k
        BLOCK_SKIP_READ(skip_self_heal_timer, needs_block, buffer, size,
719
36.2k
                        "ORDERLY_DATA", "selfHealTimer");
720
36.2k
    }
721
36.2k
#if ACCUMULATE_SELF_HEAL_TIMER
722
36.2k
    if (rc == TPM_RC_SUCCESS) {
723
36.2k
        rc = UINT64_Unmarshal(&data->selfHealTimer, buffer, size);
724
36.2k
    }
725
36.2k
    if (rc == TPM_RC_SUCCESS) {
726
36.2k
        rc = UINT64_Unmarshal(&data->lockoutTimer, buffer, size);
727
36.2k
    }
728
36.2k
    if (rc == TPM_RC_SUCCESS) {
729
36.2k
        rc = UINT64_Unmarshal(&data->time, buffer, size);
730
36.2k
    }
731
36.2k
#endif // ACCUMULATE_SELF_HEAL_TIMER
732
36.2k
skip_self_heal_timer:
733
734
    /* version 2 starts having indicator for next versions that we can skip;
735
       this allows us to downgrade state */
736
36.2k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
737
36.2k
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
738
36.2k
                        "ORDERLY_DATA", "version 3 or later");
739
        /* future versions nest-append here */
740
0
    }
741
36.2k
skip_future_versions:
742
743
36.2k
    return rc;
744
36.2k
}
745
746
18.1k
#define PCR_SAVE_MAGIC 0x7372eabc
747
18.1k
#define PCR_SAVE_VERSION 2
748
static UINT16
749
PCR_SAVE_Marshal(PCR_SAVE *data, BYTE **buffer, INT32 *size)
750
6.04k
{
751
6.04k
    UINT16 written = 0;
752
6.04k
    TPM_ALG_ID algid;
753
6.04k
    UINT16 array_size;
754
6.04k
    BLOCK_SKIP_INIT;
755
756
6.04k
    written = NV_HEADER_Marshal(buffer, size,
757
6.04k
                                PCR_SAVE_VERSION, PCR_SAVE_MAGIC, 1);
758
759
6.04k
    array_size = NUM_STATIC_PCR;
760
6.04k
    written += UINT16_Marshal(&array_size, buffer, size);
761
762
6.04k
#if ALG_SHA1
763
6.04k
    algid = TPM_ALG_SHA1;
764
6.04k
    written += TPM_ALG_ID_Marshal(&algid, buffer, size);
765
766
6.04k
    array_size = sizeof(data->Sha1);
767
6.04k
    written += UINT16_Marshal(&array_size, buffer, size);
768
6.04k
    written += Array_Marshal((BYTE *)&data->Sha1, array_size,
769
6.04k
                            buffer, size);
770
6.04k
#endif
771
6.04k
#if ALG_SHA256
772
6.04k
    algid = TPM_ALG_SHA256;
773
6.04k
    written += TPM_ALG_ID_Marshal(&algid, buffer, size);
774
775
6.04k
    array_size = sizeof(data->Sha256);
776
6.04k
    written += UINT16_Marshal(&array_size, buffer, size);
777
6.04k
    written += Array_Marshal((BYTE *)&data->Sha256, array_size,
778
6.04k
                              buffer, size);
779
6.04k
#endif
780
6.04k
#if ALG_SHA384
781
6.04k
    algid = TPM_ALG_SHA384;
782
6.04k
    written += TPM_ALG_ID_Marshal(&algid, buffer, size);
783
784
6.04k
    array_size = sizeof(data->Sha384);
785
6.04k
    written += UINT16_Marshal(&array_size, buffer, size);
786
6.04k
    written += Array_Marshal((BYTE *)&data->Sha384, array_size,
787
6.04k
                             buffer, size);
788
6.04k
#endif
789
6.04k
#if ALG_SHA512
790
6.04k
    algid = TPM_ALG_SHA512;
791
6.04k
    written += TPM_ALG_ID_Marshal(&algid, buffer, size);
792
793
6.04k
    array_size = sizeof(data->Sha512);
794
6.04k
    written += UINT16_Marshal(&array_size, buffer, size);
795
6.04k
    written += Array_Marshal((BYTE *)&data->Sha512, array_size,
796
6.04k
                             buffer, size);
797
6.04k
#endif
798
#if ALG_SM3_256
799
    algid = TPM_ALG_SM3_256;
800
    written += TPM_ALG_ID_Marshal(&algid, buffer, size);
801
802
    array_size = sizeof(data->Sm3_256);
803
    written += UINT16_Marshal(&array_size, buffer, size);
804
    written += Array_Marshal((BYTE *)&data->Sm3_256, array_size,
805
                             buffer, size);
806
#endif
807
#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256
808
#error SHA3 and SM3 are not supported
809
#endif
810
811
    /* end marker */
812
6.04k
    algid = TPM_ALG_NULL;
813
6.04k
    written += TPM_ALG_ID_Marshal(&algid, buffer, size);
814
815
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
816
    /* future versions append below this line */
817
818
6.04k
    BLOCK_SKIP_WRITE_POP(size);
819
820
6.04k
    BLOCK_SKIP_WRITE_CHECK;
821
822
6.04k
    return written;
823
6.04k
}
824
825
/*
826
 * Get the PCR banks that are active so that we know what PCRs need to be
827
 * restored. Only data for active PCR banks needs to restored, inactive PCR
828
 * banks need no data restored.
829
 */
830
static UINT64
831
pcrbanks_algs_active(const TPML_PCR_SELECTION *pcrAllocated)
832
302k
{
833
302k
    UINT64 algs_active = 0;
834
302k
    unsigned i, j;
835
836
1.51M
    for(i = 0; i < pcrAllocated->count; i++) {
837
1.20M
        for (j = 0; j < pcrAllocated->pcrSelections[i].sizeofSelect; j++) {
838
1.20M
            if (pcrAllocated->pcrSelections[i].pcrSelect[j]) {
839
1.20M
                if (pcrAllocated->pcrSelections[i].hash >= 64) {
840
0
                    TPMLIB_LogTPM2Error("pcrbanks_algs_active: invalid hash alg id: %d\n",
841
0
                                        pcrAllocated->pcrSelections[i].hash);
842
1.20M
                } else {
843
1.20M
                    algs_active |= ((UINT64)1 << pcrAllocated->pcrSelections[i].hash);
844
1.20M
                }
845
1.20M
                break;
846
1.20M
            }
847
1.20M
        }
848
1.20M
    }
849
850
302k
    return algs_active;
851
302k
}
852
853
static TPM_RC
854
PCR_SAVE_Unmarshal(PCR_SAVE *data, BYTE **buffer, INT32 *size,
855
                   const TPML_PCR_SELECTION *pcrAllocated)
856
12.0k
{
857
12.0k
    TPM_RC rc = TPM_RC_SUCCESS;
858
12.0k
    UINT16 array_size, needed_size = 0;
859
12.0k
    NV_HEADER hdr;
860
12.0k
    TPM_ALG_ID algid;
861
12.0k
    BOOL end = FALSE;
862
12.0k
    BYTE *t = NULL;
863
12.0k
    UINT64 algs_needed = pcrbanks_algs_active(pcrAllocated);
864
865
12.0k
    if (rc == TPM_RC_SUCCESS) {
866
12.0k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
867
12.0k
                                 PCR_SAVE_VERSION, PCR_SAVE_MAGIC);
868
12.0k
    }
869
870
12.0k
    if (rc == TPM_RC_SUCCESS) {
871
12.0k
        rc = UINT16_Unmarshal(&array_size, buffer, size);
872
12.0k
    }
873
12.0k
    if (rc == TPM_RC_SUCCESS &&
874
12.0k
        array_size != NUM_STATIC_PCR) {
875
0
        TPMLIB_LogTPM2Error("Non-matching PCR_SAVE NUM_STATIC_PCR. "
876
0
                            "Expected %zu, got %u\n",
877
0
                            sizeof(NUM_STATIC_PCR), array_size);
878
0
        rc = TPM_RC_SIZE;
879
0
    }
880
881
72.4k
    while (rc == TPM_RC_SUCCESS && !end) {
882
60.4k
        if (rc == TPM_RC_SUCCESS) {
883
60.4k
            rc = TPM_ALG_ID_Unmarshal(&algid, buffer, size);
884
60.4k
        }
885
60.4k
        if (rc == TPM_RC_SUCCESS) {
886
60.4k
            switch (algid) {
887
0
#if ALG_SHA1
888
12.0k
            case TPM_ALG_SHA1:
889
12.0k
                needed_size = sizeof(data->Sha1);
890
12.0k
                t = (BYTE *)&data->Sha1;
891
12.0k
                break;
892
0
#endif
893
0
#if ALG_SHA256
894
12.0k
            case TPM_ALG_SHA256:
895
12.0k
                needed_size = sizeof(data->Sha256);
896
12.0k
                t = (BYTE *)&data->Sha256;
897
12.0k
                break;
898
0
#endif
899
0
#if ALG_SHA384
900
12.0k
            case TPM_ALG_SHA384:
901
12.0k
                needed_size = sizeof(data->Sha384);
902
12.0k
                t = (BYTE *)&data->Sha384;
903
12.0k
                break;
904
0
#endif
905
0
#if ALG_SHA512
906
12.0k
            case TPM_ALG_SHA512:
907
12.0k
                needed_size = sizeof(data->Sha512);
908
12.0k
                t = (BYTE *)&data->Sha512;
909
12.0k
                break;
910
0
#endif
911
#if ALG_SM3_256
912
            case TPM_ALG_SM3_256:
913
                needed_size = sizeof(data->Sm3_256);
914
                t = (BYTE *)&data->Sm3_256;
915
                break;
916
#endif
917
#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256
918
#error SHA3 and SM3 are not supported
919
#endif
920
12.0k
            case TPM_ALG_NULL:
921
                /* end marker */
922
12.0k
                end = TRUE;
923
12.0k
                t = NULL;
924
12.0k
                break;
925
0
            default:
926
0
                TPMLIB_LogTPM2Error("PCR_SAVE: Unsupported algid %d.",
927
0
                                    algid);
928
0
                rc = TPM_RC_BAD_PARAMETER;
929
0
                t = NULL;
930
60.4k
            }
931
60.4k
        }
932
60.4k
        if (t) {
933
48.3k
            if (rc == TPM_RC_SUCCESS) {
934
48.3k
                algs_needed &= ~(1 << algid);
935
48.3k
                rc = UINT16_Unmarshal(&array_size, buffer, size);
936
48.3k
            }
937
48.3k
            if (rc == TPM_RC_SUCCESS && array_size != needed_size) {
938
0
                TPMLIB_LogTPM2Error("PCR_SAVE: Bad size for PCRs for hash 0x%x; "
939
0
                                    "Expected %u, got %d\n",
940
0
                                    algid, needed_size, array_size);
941
0
                rc = TPM_RC_BAD_PARAMETER;
942
0
            }
943
48.3k
            if (rc == TPM_RC_SUCCESS) {
944
48.3k
                rc = Array_Unmarshal(t, array_size, buffer, size);
945
48.3k
            }
946
48.3k
        }
947
60.4k
    }
948
949
12.0k
    if (rc == TPM_RC_SUCCESS && algs_needed) {
950
0
        TPMLIB_LogTPM2Error("PCR_SAVE: Missing data for hash algorithm %d.\n",
951
0
                            _ffsll(algs_needed) - 1);
952
0
        rc = TPM_RC_BAD_PARAMETER;
953
0
    }
954
955
    /* version 2 starts having indicator for next versions that we can skip;
956
       this allows us to downgrade state */
957
12.0k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
958
12.0k
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
959
12.0k
                        "PCR_SAVE", "version 3 or later");
960
        /* future versions nest-append here */
961
0
    }
962
12.0k
skip_future_versions:
963
964
12.0k
    return rc;
965
12.0k
}
966
967
968
#ifdef PCR_C
969
970
434k
#define PCR_MAGIC 0xe95f0387
971
434k
#define PCR_VERSION 2
972
static UINT16
973
PCR_Marshal(PCR *data, BYTE **buffer, INT32 *size)
974
144k
{
975
144k
    UINT16 written;
976
144k
    TPM_ALG_ID algid;
977
144k
    UINT16 array_size;
978
144k
    BLOCK_SKIP_INIT;
979
980
144k
    written = NV_HEADER_Marshal(buffer, size,
981
144k
                                PCR_VERSION, PCR_MAGIC, 1);
982
983
144k
#if ALG_SHA1
984
144k
    algid = TPM_ALG_SHA1;
985
144k
    written += TPM_ALG_ID_Marshal(&algid, buffer, size);
986
987
144k
    array_size = sizeof(data->Sha1Pcr);
988
144k
    written += UINT16_Marshal(&array_size, buffer, size);
989
144k
    written += Array_Marshal((BYTE *)&data->Sha1Pcr, array_size,
990
144k
                            buffer, size);
991
144k
#endif
992
144k
#if ALG_SHA256
993
144k
    algid = TPM_ALG_SHA256;
994
144k
    written += TPM_ALG_ID_Marshal(&algid, buffer, size);
995
996
144k
    array_size = sizeof(data->Sha256Pcr);
997
144k
    written += UINT16_Marshal(&array_size, buffer, size);
998
144k
    written += Array_Marshal((BYTE *)&data->Sha256Pcr, array_size,
999
144k
                              buffer, size);
1000
144k
#endif
1001
144k
#if ALG_SHA384
1002
144k
    algid = TPM_ALG_SHA384;
1003
144k
    written += TPM_ALG_ID_Marshal(&algid, buffer, size);
1004
1005
144k
    array_size = sizeof(data->Sha384Pcr);
1006
144k
    written += UINT16_Marshal(&array_size, buffer, size);
1007
144k
    written += Array_Marshal((BYTE *)&data->Sha384Pcr, array_size,
1008
144k
                             buffer, size);
1009
144k
#endif
1010
144k
#if ALG_SHA512
1011
144k
    algid = TPM_ALG_SHA512;
1012
144k
    written += TPM_ALG_ID_Marshal(&algid, buffer, size);
1013
1014
144k
    array_size = sizeof(data->Sha512Pcr);
1015
144k
    written += UINT16_Marshal(&array_size, buffer, size);
1016
144k
    written += Array_Marshal((BYTE *)&data->Sha512Pcr, array_size,
1017
144k
                             buffer, size);
1018
144k
#endif
1019
#if ALG_SM3_256
1020
    algid = TPM_ALG_SM3_256;
1021
    written += TPM_ALG_ID_Marshal(&algid, buffer, size);
1022
1023
    array_size = sizeof(data->Sm3_256Pcr);
1024
    written += UINT16_Marshal(&array_size, buffer, size);
1025
    written += Array_Marshal((BYTE *)&data->Sm3_256Pcr, array_size,
1026
                             buffer, size);
1027
#endif
1028
#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256
1029
#error SHA3 and SM3 are not supported
1030
#endif
1031
1032
    /* end marker */
1033
144k
    algid = TPM_ALG_NULL;
1034
144k
    written += TPM_ALG_ID_Marshal(&algid, buffer, size);
1035
1036
144k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
1037
    /* future versions append below this line */
1038
1039
144k
    BLOCK_SKIP_WRITE_POP(size);
1040
1041
144k
    BLOCK_SKIP_WRITE_CHECK;
1042
1043
144k
    return written;
1044
144k
}
1045
1046
static TPM_RC
1047
PCR_Unmarshal(PCR *data, BYTE **buffer, INT32 *size,
1048
              const TPML_PCR_SELECTION *pcrAllocated)
1049
289k
{
1050
289k
    TPM_RC rc = TPM_RC_SUCCESS;
1051
289k
    NV_HEADER hdr;
1052
289k
    BOOL end = FALSE;
1053
289k
    BYTE *t = NULL;
1054
289k
    UINT16 needed_size = 0, array_size;
1055
289k
    TPM_ALG_ID algid;
1056
289k
    UINT64 algs_needed = pcrbanks_algs_active(pcrAllocated);
1057
1058
289k
    if (rc == TPM_RC_SUCCESS) {
1059
289k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
1060
289k
                                 PCR_VERSION, PCR_MAGIC);
1061
289k
    }
1062
1063
1.73M
    while (rc == TPM_RC_SUCCESS && !end) {
1064
1.44M
        if (rc == TPM_RC_SUCCESS) {
1065
1.44M
            rc = TPM_ALG_ID_Unmarshal(&algid, buffer, size);
1066
1.44M
        }
1067
1.44M
        if (rc == TPM_RC_SUCCESS) {
1068
1.44M
            switch (algid) {
1069
0
#if ALG_SHA1
1070
289k
            case TPM_ALG_SHA1:
1071
289k
                needed_size = sizeof(data->Sha1Pcr);
1072
289k
                t = (BYTE *)&data->Sha1Pcr;
1073
289k
                break;
1074
0
#endif
1075
0
#if ALG_SHA256
1076
289k
            case TPM_ALG_SHA256:
1077
289k
                needed_size = sizeof(data->Sha256Pcr);
1078
289k
                t = (BYTE *)&data->Sha256Pcr;
1079
289k
                break;
1080
0
#endif
1081
0
#if ALG_SHA384
1082
289k
            case TPM_ALG_SHA384:
1083
289k
                needed_size = sizeof(data->Sha384Pcr);
1084
289k
                t = (BYTE *)&data->Sha384Pcr;
1085
289k
                break;
1086
0
#endif
1087
0
#if ALG_SHA512
1088
289k
            case TPM_ALG_SHA512:
1089
289k
                needed_size = sizeof(data->Sha512Pcr);
1090
289k
                t = (BYTE *)&data->Sha512Pcr;
1091
289k
                break;
1092
0
#endif
1093
#if ALG_SM3_256
1094
            case TPM_ALG_SM3_256:
1095
                needed_size = sizeof(data->Sm3_256Pcr);
1096
                t = (BYTE *)&data->Sm3_256Pcr;
1097
                break;
1098
#endif
1099
#if ALG_SHA3_256 || ALG_SHA3_384 || ALG_SHA3_512 || ALG_SM3_256
1100
#error SHA3 and SM3 are not supported
1101
#endif
1102
289k
            case TPM_ALG_NULL:
1103
                /* end marker */
1104
289k
                end = TRUE;
1105
289k
                t = NULL;
1106
289k
                break;
1107
0
            default:
1108
0
                TPMLIB_LogTPM2Error("PCR: Unsupported algid %d.",
1109
0
                                    algid);
1110
0
                rc = TPM_RC_BAD_PARAMETER;
1111
0
                t = NULL;
1112
1.44M
            }
1113
1.44M
        }
1114
1.44M
        if (t) {
1115
1.15M
            if (rc == TPM_RC_SUCCESS) {
1116
1.15M
                algs_needed &= ~(1 << algid);
1117
1.15M
                rc = UINT16_Unmarshal(&array_size, buffer, size);
1118
1.15M
            }
1119
1.15M
            if (rc == TPM_RC_SUCCESS && array_size != needed_size) {
1120
0
                TPMLIB_LogTPM2Error("PCR: Bad size for PCR for hash 0x%x; "
1121
0
                                    "Expected %u, got %d\n",
1122
0
                                    algid, needed_size, array_size);
1123
0
                rc = TPM_RC_BAD_PARAMETER;
1124
0
            }
1125
1.15M
            if (rc == TPM_RC_SUCCESS) {
1126
1.15M
                rc = Array_Unmarshal(t, array_size, buffer, size);
1127
1.15M
            }
1128
1.15M
        }
1129
1.44M
    }
1130
1131
289k
    if (rc == TPM_RC_SUCCESS && algs_needed) {
1132
0
        TPMLIB_LogTPM2Error("PCR: Missing data for hash algorithm %d.\n",
1133
0
                            _ffsll(algs_needed) - 1);
1134
0
        rc = TPM_RC_BAD_PARAMETER;
1135
0
    }
1136
1137
    /* version 2 starts having indicator for next versions that we can skip;
1138
       this allows us to downgrade state */
1139
289k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
1140
289k
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
1141
289k
                        "PCR", "version 3 or later");
1142
        /* future versions nest-append here */
1143
0
    }
1144
289k
skip_future_versions:
1145
1146
289k
    return rc;
1147
289k
}
1148
#endif
1149
1150
18.1k
#define PCR_AUTHVALUE_MAGIC 0x6be82eaf
1151
18.1k
#define PCR_AUTHVALUE_VERSION 2
1152
static UINT16
1153
PCR_AUTHVALUE_Marshal(PCR_AUTHVALUE *data, BYTE **buffer, INT32 *size)
1154
6.04k
{
1155
6.04k
    UINT16 written;
1156
6.04k
    size_t i;
1157
6.04k
    UINT16 array_size;
1158
6.04k
    BLOCK_SKIP_INIT;
1159
1160
6.04k
    written = NV_HEADER_Marshal(buffer, size,
1161
6.04k
                                PCR_AUTHVALUE_VERSION, PCR_AUTHVALUE_MAGIC, 1);
1162
1163
6.04k
    array_size = ARRAY_SIZE(data->auth);
1164
6.04k
    written += UINT16_Marshal(&array_size, buffer, size);
1165
12.0k
    for (i = 0; i < array_size; i++) {
1166
6.04k
        written += TPM2B_DIGEST_Marshal(&data->auth[i], buffer, size);
1167
6.04k
    }
1168
1169
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
1170
    /* future versions append below this line */
1171
1172
6.04k
    BLOCK_SKIP_WRITE_POP(size);
1173
1174
6.04k
    BLOCK_SKIP_WRITE_CHECK;
1175
1176
6.04k
    return written;
1177
6.04k
}
1178
1179
static TPM_RC
1180
PCR_AUTHVALUE_Unmarshal(PCR_AUTHVALUE *data, BYTE **buffer, INT32 *size)
1181
12.0k
{
1182
12.0k
    TPM_RC rc = TPM_RC_SUCCESS;
1183
12.0k
    size_t i;
1184
12.0k
    NV_HEADER hdr;
1185
12.0k
    UINT16 array_size = 0;
1186
1187
12.0k
    if (rc == TPM_RC_SUCCESS) {
1188
12.0k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
1189
12.0k
                                 PCR_AUTHVALUE_VERSION, PCR_AUTHVALUE_MAGIC);
1190
12.0k
    }
1191
1192
12.0k
    if (rc == TPM_RC_SUCCESS) {
1193
12.0k
        rc = UINT16_Unmarshal(&array_size, buffer, size);
1194
12.0k
    }
1195
12.0k
    if (rc == TPM_RC_SUCCESS &&
1196
12.0k
        array_size != ARRAY_SIZE(data->auth)) {
1197
0
        TPMLIB_LogTPM2Error("PCR_AUTHVALUE: Bad array size for auth; "
1198
0
                            "expected %zu, got %u\n",
1199
0
                            ARRAY_SIZE(data->auth), array_size);
1200
0
        rc = TPM_RC_BAD_PARAMETER;
1201
0
    }
1202
12.0k
    if (rc == TPM_RC_SUCCESS) {
1203
24.1k
        for (i = 0; i < ARRAY_SIZE(data->auth) && rc == TPM_RC_SUCCESS; i++) {
1204
12.0k
            rc = TPM2B_DIGEST_Unmarshal(&data->auth[i], buffer, size);
1205
12.0k
        }
1206
12.0k
    }
1207
1208
    /* version 2 starts having indicator for next versions that we can skip;
1209
       this allows us to downgrade state */
1210
12.0k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
1211
12.0k
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
1212
12.0k
                        "PCR_AUTHVALUE", "version 3 or later");
1213
        /* future versions nest-append here */
1214
0
    }
1215
12.0k
skip_future_versions:
1216
1217
12.0k
    return rc;
1218
12.0k
}
1219
1220
18.1k
#define STATE_CLEAR_DATA_MAGIC  0x98897667
1221
18.1k
#define STATE_CLEAR_DATA_VERSION 2
1222
1223
static UINT16
1224
STATE_CLEAR_DATA_Marshal(STATE_CLEAR_DATA *data, BYTE **buffer, INT32 *size)
1225
6.04k
{
1226
6.04k
    UINT16 written;
1227
6.04k
    BLOCK_SKIP_INIT;
1228
1229
6.04k
    written = NV_HEADER_Marshal(buffer, size,
1230
6.04k
                                STATE_CLEAR_DATA_VERSION,
1231
6.04k
                                STATE_CLEAR_DATA_MAGIC, 1);
1232
6.04k
    written += BOOL_Marshal(&data->shEnable, buffer, size);
1233
6.04k
    written += BOOL_Marshal(&data->ehEnable, buffer, size);
1234
6.04k
    written += BOOL_Marshal(&data->phEnableNV, buffer, size);
1235
6.04k
    written += UINT16_Marshal(&data->platformAlg, buffer, size);
1236
6.04k
    written += TPM2B_DIGEST_Marshal(&data->platformPolicy, buffer, size);
1237
6.04k
    written += TPM2B_AUTH_Marshal(&data->platformAuth, buffer, size);
1238
6.04k
    written += PCR_SAVE_Marshal(&data->pcrSave, buffer, size);
1239
6.04k
    written += PCR_AUTHVALUE_Marshal(&data->pcrAuthValues, buffer, size);
1240
1241
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
1242
    /* future versions append below this line */
1243
1244
6.04k
    BLOCK_SKIP_WRITE_POP(size);
1245
1246
6.04k
    BLOCK_SKIP_WRITE_CHECK;
1247
1248
6.04k
    return written;
1249
6.04k
}
1250
1251
static TPM_RC
1252
STATE_CLEAR_DATA_Unmarshal(STATE_CLEAR_DATA *data, BYTE **buffer, INT32 *size)
1253
12.0k
{
1254
12.0k
    TPM_RC rc = TPM_RC_SUCCESS;
1255
12.0k
    NV_HEADER hdr;
1256
1257
12.0k
    if (rc == TPM_RC_SUCCESS) {
1258
12.0k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
1259
12.0k
                                 STATE_CLEAR_DATA_VERSION,
1260
12.0k
                                 STATE_CLEAR_DATA_MAGIC);
1261
12.0k
    }
1262
12.0k
    if (rc == TPM_RC_SUCCESS) {
1263
12.0k
        rc = BOOL_Unmarshal(&data->shEnable, buffer, size);
1264
12.0k
    }
1265
12.0k
    if (rc == TPM_RC_SUCCESS) {
1266
12.0k
        rc = BOOL_Unmarshal(&data->ehEnable, buffer, size);
1267
12.0k
    }
1268
12.0k
    if (rc == TPM_RC_SUCCESS) {
1269
12.0k
        rc = BOOL_Unmarshal(&data->phEnableNV, buffer, size);
1270
12.0k
    }
1271
12.0k
    if (rc == TPM_RC_SUCCESS) {
1272
12.0k
        rc = UINT16_Unmarshal(&data->platformAlg, buffer, size);
1273
12.0k
    }
1274
12.0k
    if (rc == TPM_RC_SUCCESS) {
1275
12.0k
        rc = TPM2B_DIGEST_Unmarshal(&data->platformPolicy, buffer, size);
1276
12.0k
    }
1277
12.0k
    if (rc == TPM_RC_SUCCESS) {
1278
12.0k
        rc = TPM2B_AUTH_Unmarshal(&data->platformAuth, buffer, size);
1279
12.0k
    }
1280
12.0k
    if (rc == TPM_RC_SUCCESS) {
1281
12.0k
        rc = PCR_SAVE_Unmarshal(&data->pcrSave, buffer, size, &shadow.pcrAllocated);
1282
12.0k
    }
1283
12.0k
    if (rc == TPM_RC_SUCCESS) {
1284
12.0k
        rc = PCR_AUTHVALUE_Unmarshal(&data->pcrAuthValues, buffer, size);
1285
12.0k
    }
1286
1287
    /* version 2 starts having indicator for next versions that we can skip;
1288
       this allows us to downgrade state */
1289
12.0k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
1290
12.0k
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
1291
12.0k
                        "STATE_CLEAR_DATA", "version 3 or later");
1292
        /* future versions nest-append here */
1293
0
    }
1294
12.0k
skip_future_versions:
1295
1296
12.0k
    return rc;
1297
12.0k
}
1298
1299
18.1k
#define STATE_RESET_DATA_MAGIC  0x01102332
1300
18.1k
#define STATE_RESET_DATA_VERSION 4
1301
1302
static TPM_RC
1303
STATE_RESET_DATA_Unmarshal(STATE_RESET_DATA *data, BYTE **buffer, INT32 *size)
1304
12.0k
{
1305
12.0k
    TPM_RC rc = TPM_RC_SUCCESS;
1306
12.0k
    BOOL needs_block;
1307
12.0k
    UINT16 array_size;
1308
12.0k
    NV_HEADER hdr;
1309
1310
12.0k
    if (rc == TPM_RC_SUCCESS) {
1311
12.0k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
1312
12.0k
                                 STATE_RESET_DATA_VERSION,
1313
12.0k
                                 STATE_RESET_DATA_MAGIC);
1314
12.0k
    }
1315
12.0k
    if (rc == TPM_RC_SUCCESS) {
1316
12.0k
        rc = TPM2B_PROOF_Unmarshal(&data->nullProof, buffer, size);
1317
12.0k
    }
1318
12.0k
    if (rc == TPM_RC_SUCCESS) {
1319
12.0k
        rc = TPM2B_Unmarshal(&data->nullSeed.b, PRIMARY_SEED_SIZE, buffer, size);
1320
12.0k
    }
1321
12.0k
    if (rc == TPM_RC_SUCCESS) {
1322
12.0k
        rc = UINT32_Unmarshal(&data->clearCount, buffer, size);
1323
12.0k
    }
1324
12.0k
    if (rc == TPM_RC_SUCCESS) {
1325
12.0k
        rc = UINT64_Unmarshal(&data->objectContextID, buffer, size);
1326
12.0k
    }
1327
1328
1329
12.0k
    if (rc == TPM_RC_SUCCESS) {
1330
12.0k
        rc = UINT16_Unmarshal(&array_size, buffer, size);
1331
12.0k
    }
1332
12.0k
    if (rc == TPM_RC_SUCCESS &&
1333
12.0k
        array_size != ARRAY_SIZE(data->contextArray)) {
1334
0
        TPMLIB_LogTPM2Error("STATE_RESET_DATA: Bad array size for contextArray; "
1335
0
                            "expected %zu, got %u\n",
1336
0
                            ARRAY_SIZE(data->contextArray), array_size);
1337
0
        rc = TPM_RC_BAD_PARAMETER;
1338
0
    }
1339
12.0k
    if (rc == TPM_RC_SUCCESS) {
1340
12.0k
        size_t i;
1341
12.0k
        if (hdr.version <= 3) {
1342
            /* version <= 3 was writing an array of UINT8 */
1343
0
            UINT8 element;
1344
0
            for (i = 0; i < array_size; i++) {
1345
0
                rc = UINT8_Unmarshal(&element, buffer, size);
1346
0
                if (rc != TPM_RC_SUCCESS)
1347
0
                    break;
1348
1349
0
                data->contextArray[i] = element;
1350
0
            }
1351
0
            s_ContextSlotMask = 0xff;
1352
12.0k
        } else {
1353
            /* version 4 and later an array of UINT16 */
1354
785k
            for (i = 0; i < array_size && rc == TPM_RC_SUCCESS; i++) {
1355
773k
                rc = UINT16_Unmarshal(&data->contextArray[i], buffer, size);
1356
773k
            }
1357
12.0k
            if (rc == TPM_RC_SUCCESS) {
1358
12.0k
                rc = UINT16_Unmarshal(&s_ContextSlotMask, buffer, size);
1359
12.0k
            }
1360
12.0k
            if (rc == TPM_RC_SUCCESS) {
1361
12.0k
                if (s_ContextSlotMask != 0xffff && s_ContextSlotMask != 0x00ff) {
1362
0
                    TPMLIB_LogTPM2Error("STATE_RESET_DATA: s_ContextSlotMask has bad value: 0x%04x\n",
1363
0
                                        s_ContextSlotMask);
1364
0
                    rc = TPM_RC_BAD_PARAMETER;
1365
0
                }
1366
12.0k
            }
1367
12.0k
        }
1368
12.0k
    }
1369
12.0k
    if (rc == TPM_RC_SUCCESS) {
1370
12.0k
        rc = UINT64_Unmarshal(&data->contextCounter, buffer, size);
1371
12.0k
    }
1372
12.0k
    if (rc == TPM_RC_SUCCESS) {
1373
12.0k
        rc = TPM2B_DIGEST_Unmarshal(&data->commandAuditDigest,
1374
12.0k
                              buffer, size);
1375
12.0k
    }
1376
12.0k
    if (rc == TPM_RC_SUCCESS) {
1377
12.0k
        rc = UINT32_Unmarshal(&data->restartCount, buffer, size);
1378
12.0k
    }
1379
12.0k
    if (rc == TPM_RC_SUCCESS) {
1380
12.0k
        rc = UINT32_Unmarshal(&data->pcrCounter, buffer, size);
1381
12.0k
    }
1382
1383
12.0k
#if ALG_ECC
1384
12.0k
    needs_block = TRUE;
1385
#else
1386
    needs_block = FALSE;
1387
#endif
1388
12.0k
    if (rc == TPM_RC_SUCCESS) {
1389
12.0k
        BLOCK_SKIP_READ(skip_alg_ecc, needs_block, buffer, size,
1390
12.0k
                        "STATE_RESET_DATA", "commitCounter");
1391
12.0k
    }
1392
12.0k
#if ALG_ECC
1393
12.0k
    if (rc == TPM_RC_SUCCESS) {
1394
12.0k
        rc = UINT64_Unmarshal(&data->commitCounter, buffer, size);
1395
12.0k
    }
1396
12.0k
    if (rc == TPM_RC_SUCCESS) {
1397
12.0k
        rc = TPM2B_AUTH_Unmarshal(&data->commitNonce, buffer, size);
1398
12.0k
    }
1399
1400
12.0k
    if (rc == TPM_RC_SUCCESS) {
1401
12.0k
        rc = UINT16_Unmarshal(&array_size, buffer, size);
1402
12.0k
    }
1403
12.0k
    if (rc == TPM_RC_SUCCESS &&
1404
12.0k
        array_size != sizeof(data->commitArray)) {
1405
0
        TPMLIB_LogTPM2Error("STATE_RESET_DATA: Bad array size for commitArray; "
1406
0
                            "expected %zu, got %u\n",
1407
0
                            sizeof(data->commitArray), array_size);
1408
0
        rc = TPM_RC_BAD_PARAMETER;
1409
0
    }
1410
12.0k
    if (rc == TPM_RC_SUCCESS) {
1411
12.0k
        rc = Array_Unmarshal((BYTE *)&data->commitArray, array_size,
1412
12.0k
                              buffer, size);
1413
12.0k
    }
1414
12.0k
#endif
1415
12.0k
skip_alg_ecc:
1416
1417
    /* default values before conditional block */
1418
12.0k
    data->nullSeedCompatLevel = SEED_COMPAT_LEVEL_ORIGINAL;
1419
1420
    /* version 2 starts having indicator for next versions that we can skip;
1421
       this allows us to downgrade state */
1422
12.0k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
1423
12.0k
        BLOCK_SKIP_READ(skip_future_versions, hdr.version >= 3, buffer, size,
1424
12.0k
                        "STATE_RESET_DATA", "version 3 or later");
1425
12.0k
        if (rc == TPM_RC_SUCCESS) {
1426
12.0k
            rc = SEED_COMPAT_LEVEL_Unmarshal(&gr.nullSeedCompatLevel,
1427
12.0k
                                             buffer, size, "nullSeed");
1428
12.0k
        }
1429
1430
12.0k
        if (rc == TPM_RC_SUCCESS) {
1431
12.0k
            BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
1432
12.0k
                            "STATE_RESET_DATA", "version 4 or later");
1433
0
        }
1434
        /* future versions nest-append here */
1435
12.0k
    }
1436
1437
12.0k
skip_future_versions:
1438
1439
12.0k
    return rc;
1440
12.0k
}
1441
1442
static UINT16
1443
STATE_RESET_DATA_Marshal(STATE_RESET_DATA *data, BYTE **buffer, INT32 *size)
1444
6.04k
{
1445
6.04k
    UINT16 written;
1446
6.04k
    BOOL has_block;
1447
6.04k
    UINT16 array_size;
1448
6.04k
    BLOCK_SKIP_INIT;
1449
6.04k
    size_t i;
1450
1451
6.04k
    written = NV_HEADER_Marshal(buffer, size,
1452
6.04k
                                STATE_RESET_DATA_VERSION,
1453
6.04k
                                STATE_RESET_DATA_MAGIC, 4);
1454
6.04k
    written += TPM2B_PROOF_Marshal(&data->nullProof, buffer, size);
1455
6.04k
    written += TPM2B_Marshal(&data->nullSeed.b, sizeof(data->nullSeed.t.buffer), buffer, size);
1456
6.04k
    written += UINT32_Marshal(&data->clearCount, buffer, size);
1457
6.04k
    written += UINT64_Marshal(&data->objectContextID, buffer, size);
1458
1459
6.04k
    array_size = ARRAY_SIZE(data->contextArray);
1460
6.04k
    written += UINT16_Marshal(&array_size, buffer, size);
1461
392k
    for (i = 0; i < array_size; i++)
1462
386k
        written += UINT16_Marshal(&data->contextArray[i], buffer, size);
1463
1464
6.04k
    if (s_ContextSlotMask != 0x00ff && s_ContextSlotMask != 0xffff) {
1465
        /* TPM wasn't initialized, so s_ContextSlotMask wasn't set */
1466
0
        s_ContextSlotMask = 0xffff;
1467
0
    }
1468
6.04k
    written += UINT16_Marshal(&s_ContextSlotMask, buffer, size);
1469
1470
6.04k
    written += UINT64_Marshal(&data->contextCounter, buffer, size);
1471
6.04k
    written += TPM2B_DIGEST_Marshal(&data->commandAuditDigest,
1472
6.04k
                              buffer, size);
1473
6.04k
    written += UINT32_Marshal(&data->restartCount, buffer, size);
1474
6.04k
    written += UINT32_Marshal(&data->pcrCounter, buffer, size);
1475
6.04k
#if ALG_ECC
1476
6.04k
    has_block = TRUE;
1477
#else
1478
    has_block = FALSE;
1479
#endif
1480
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
1481
1482
6.04k
#if ALG_ECC
1483
6.04k
    written += UINT64_Marshal(&data->commitCounter, buffer, size);
1484
6.04k
    written += TPM2B_AUTH_Marshal(&data->commitNonce, buffer, size);
1485
1486
6.04k
    array_size = sizeof(data->commitArray);
1487
6.04k
    written += UINT16_Marshal(&array_size, buffer, size);
1488
6.04k
    written += Array_Marshal((BYTE *)&data->commitArray, array_size,
1489
6.04k
                             buffer, size);
1490
6.04k
#endif
1491
6.04k
    BLOCK_SKIP_WRITE_POP(size);
1492
1493
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
1494
6.04k
    written += SEED_COMPAT_LEVEL_Marshal(&data->nullSeedCompatLevel,
1495
6.04k
                                         buffer, size);
1496
1497
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
1498
    /* future versions append below this line */
1499
1500
6.04k
    BLOCK_SKIP_WRITE_POP(size);
1501
6.04k
    BLOCK_SKIP_WRITE_POP(size);
1502
1503
6.04k
    BLOCK_SKIP_WRITE_CHECK;
1504
1505
6.04k
    return written;
1506
6.04k
}
1507
1508
3.94k
#define BN_PRIME_T_MAGIC 0x2fe736ab
1509
3.94k
#define BN_PRIME_T_VERSION 2
1510
static UINT16
1511
ci_prime_t_Marshal(ci_prime_t *data, BYTE **buffer, INT32 *size)
1512
1.31k
{
1513
1.31k
    UINT16 written, numbytes;
1514
1.31k
    size_t i, idx;
1515
1.31k
    BLOCK_SKIP_INIT;
1516
1517
1.31k
    written = NV_HEADER_Marshal(buffer, size,
1518
1.31k
                                BN_PRIME_T_VERSION, BN_PRIME_T_MAGIC, 1);
1519
1520
    /* we do not write 'allocated' */
1521
1.31k
    numbytes = data->size * sizeof(crypt_uword_t);
1522
1.31k
    written += UINT16_Marshal(&numbytes, buffer, size);
1523
1524
1.31k
    for (i = 0, idx = 0;
1525
7.65k
         i < numbytes;
1526
6.33k
         i += sizeof(crypt_uword_t), idx += 1) {
1527
6.33k
#if RADIX_BITS == 64
1528
6.33k
        written += UINT64_Marshal(&data->d[idx], buffer, size);
1529
#elif RADIX_BITS == 32
1530
        written += UINT32_Marshal(&data->d[idx], buffer, size);
1531
#else
1532
#error RADIX_BYTES it no defined
1533
#endif
1534
6.33k
    }
1535
1536
1.31k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
1537
    /* future versions append below this line */
1538
1539
1.31k
    BLOCK_SKIP_WRITE_POP(size);
1540
1541
1.31k
    BLOCK_SKIP_WRITE_CHECK;
1542
1543
1.31k
    return written;
1544
1.31k
}
1545
1546
static TPM_RC
1547
ci_prime_t_Unmarshal(ci_prime_t *data, BYTE **buffer, INT32 *size)
1548
2.63k
{
1549
2.63k
    TPM_RC rc = TPM_RC_SUCCESS;
1550
2.63k
    size_t i, idx;
1551
2.63k
    UINT16 numbytes = 0;
1552
2.63k
    UINT32 word;
1553
2.63k
    NV_HEADER hdr;
1554
1555
2.63k
    if (rc == TPM_RC_SUCCESS) {
1556
2.63k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
1557
2.63k
                                 BN_PRIME_T_VERSION,
1558
2.63k
                                 BN_PRIME_T_MAGIC);
1559
2.63k
    }
1560
1561
2.63k
    data->allocated = ARRAY_SIZE(data->d);
1562
1563
2.63k
    if (rc == TPM_RC_SUCCESS) {
1564
2.63k
        rc = UINT16_Unmarshal(&numbytes, buffer, size);
1565
2.63k
    }
1566
2.63k
    if (rc == TPM_RC_SUCCESS) {
1567
        /* coverity: num_bytes is sanitized here! */
1568
2.63k
        data->size = (numbytes + sizeof(crypt_uword_t) - 1) / sizeof(crypt_word_t);
1569
2.63k
        if (data->size > data->allocated) {
1570
0
            TPMLIB_LogTPM2Error("ci_prime_t: Require size larger %zu than "
1571
0
                                "allocated %zu\n",
1572
0
                                (size_t)data->size, (size_t)data->allocated);
1573
0
            rc = TPM_RC_SIZE;
1574
0
            data->size = 0;
1575
0
        }
1576
2.63k
    }
1577
1578
2.63k
    if (rc == TPM_RC_SUCCESS) {
1579
2.63k
        for (i = 0, idx = 0;
1580
27.9k
             i < numbytes && rc == TPM_RC_SUCCESS;
1581
25.3k
             i += sizeof(UINT32), idx += 1) {
1582
25.3k
            rc = UINT32_Unmarshal(&word, buffer, size);
1583
25.3k
#if RADIX_BITS == 64
1584
25.3k
            data->d[idx / 2] <<= 32;
1585
25.3k
            data->d[idx / 2] |= word;
1586
#elif RADIX_BITS == 32
1587
            data->d[idx] = word;
1588
#endif
1589
25.3k
        }
1590
2.63k
    }
1591
1592
2.63k
#if RADIX_BITS == 64
1593
2.63k
    if (rc == TPM_RC_SUCCESS) {
1594
2.63k
        if (idx & 1)
1595
0
            data->d[idx / 2] <<= 32;
1596
2.63k
    }
1597
2.63k
#endif
1598
1599
    /* version 2 starts having indicator for next versions that we can skip;
1600
       this allows us to downgrade state */
1601
2.63k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
1602
2.63k
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
1603
2.63k
                        "BN_PRIME_T", "version 3 or later");
1604
        /* future versions nest-append here */
1605
0
    }
1606
1607
2.63k
skip_future_versions:
1608
1609
2.63k
    return rc;
1610
2.63k
}
1611
1612
987
#define PRIVATE_EXPONENT_T_MAGIC 0x854eab2
1613
987
#define PRIVATE_EXPONENT_T_VERSION 2
1614
static UINT16
1615
privateExponent_t_Marshal(privateExponent_t *data, BYTE **buffer, INT32 *size)
1616
329
{
1617
329
    UINT16 written;
1618
329
    BLOCK_SKIP_INIT;
1619
1620
329
    written = NV_HEADER_Marshal(buffer, size,
1621
329
                                PRIVATE_EXPONENT_T_VERSION,
1622
329
                                PRIVATE_EXPONENT_T_MAGIC, 1);
1623
#if CRT_FORMAT_RSA == NO
1624
#error Missing code
1625
#else
1626
329
    written += ci_prime_t_Marshal(&data->Q, buffer, size);
1627
329
    written += ci_prime_t_Marshal(&data->dP, buffer, size);
1628
329
    written += ci_prime_t_Marshal(&data->dQ, buffer, size);
1629
329
    written += ci_prime_t_Marshal(&data->qInv, buffer, size);
1630
329
#endif
1631
1632
329
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
1633
    /* future versions append below this line */
1634
1635
329
    BLOCK_SKIP_WRITE_POP(size);
1636
1637
329
    BLOCK_SKIP_WRITE_CHECK;
1638
1639
329
    return written;
1640
329
}
1641
1642
static TPM_RC
1643
privateExponent_t_Unmarshal(privateExponent_t *data, BYTE **buffer, INT32 *size)
1644
658
{
1645
658
    TPM_RC rc = TPM_RC_SUCCESS;
1646
658
    NV_HEADER hdr;
1647
1648
658
    if (rc == TPM_RC_SUCCESS) {
1649
658
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
1650
658
                                 PRIVATE_EXPONENT_T_VERSION,
1651
658
                                 PRIVATE_EXPONENT_T_MAGIC);
1652
658
    }
1653
1654
#if CRT_FORMAT_RSA == NO
1655
#error Missing code
1656
#else
1657
658
    if (rc == TPM_RC_SUCCESS) {
1658
658
        rc = ci_prime_t_Unmarshal(&data->Q, buffer, size);
1659
658
    }
1660
658
    if (rc == TPM_RC_SUCCESS) {
1661
658
        rc = ci_prime_t_Unmarshal(&data->dP, buffer, size);
1662
658
    }
1663
658
    if (rc == TPM_RC_SUCCESS) {
1664
658
        rc = ci_prime_t_Unmarshal(&data->dQ, buffer, size);
1665
658
    }
1666
658
    if (rc == TPM_RC_SUCCESS) {
1667
658
        rc = ci_prime_t_Unmarshal(&data->qInv, buffer, size);
1668
658
    }
1669
658
#endif
1670
1671
    /* version 2 starts having indicator for next versions that we can skip;
1672
       this allows us to downgrade state */
1673
658
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
1674
658
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
1675
658
                        "PRIVATE_EXPONENT_T", "version 3 or later");
1676
        /* future versions nest-append here */
1677
0
    }
1678
1679
658
skip_future_versions:
1680
1681
658
    return rc;
1682
658
}
1683
1684
static UINT16
1685
HASH_STATE_TYPE_Marshal(HASH_STATE_TYPE *data, BYTE **buffer, INT32 *size)
1686
20
{
1687
20
    UINT16 written;
1688
1689
20
    written = UINT8_Marshal(data, buffer, size);
1690
1691
20
    return written;
1692
20
}
1693
1694
static UINT16
1695
HASH_STATE_TYPE_Unmarshal(HASH_STATE_TYPE *data, BYTE **buffer, INT32 *size)
1696
40
{
1697
40
    return UINT8_Unmarshal(data, buffer, size);
1698
40
}
1699
1700
static inline UINT16
1701
SHA_LONG_Marshal(SHA_LONG *data, BYTE **buffer, INT32 *size)
1702
44
{
1703
44
    return UINT32_Marshal(data, buffer, size);
1704
44
}
1705
1706
static inline UINT16
1707
SHA_LONG_Unmarshal(SHA_LONG *data, BYTE **buffer, INT32 *size)
1708
88
{
1709
88
    return UINT32_Unmarshal(data, buffer, size);
1710
88
}
1711
1712
static inline UINT16
1713
SHA_LONG64_Marshal(SHA_LONG64 *data, BYTE **buffer, INT32 *size)
1714
30
{
1715
30
    assert(sizeof(*data) == 8);
1716
30
    return UINT64_Marshal((UINT64 *)data, buffer, size);
1717
30
}
1718
1719
static inline UINT16
1720
SHA_LONG64_Unmarshal(SHA_LONG64 *data, BYTE **buffer, INT32 *size)
1721
60
{
1722
60
    assert(sizeof(*data) == 8);
1723
60
    return UINT64_Unmarshal((UINT64 *)data, buffer, size);
1724
60
}
1725
1726
#if ALG_SHA1
1727
1728
6
#define HASH_STATE_SHA1_MAGIC   0x19d46f50
1729
6
#define HASH_STATE_SHA1_VERSION 2
1730
1731
static UINT16
1732
tpmHashStateSHA1_Marshal(tpmHashStateSHA1_t *data, BYTE **buffer, INT32 *size)
1733
2
{
1734
2
    UINT16 written;
1735
2
    UINT16 array_size;
1736
2
    BLOCK_SKIP_INIT;
1737
1738
2
    written = NV_HEADER_Marshal(buffer, size,
1739
2
                                HASH_STATE_SHA1_VERSION,
1740
2
                                HASH_STATE_SHA1_MAGIC,1);
1741
2
    written += SHA_LONG_Marshal(&data->h0, buffer, size);
1742
2
    written += SHA_LONG_Marshal(&data->h1, buffer, size);
1743
2
    written += SHA_LONG_Marshal(&data->h2, buffer, size);
1744
2
    written += SHA_LONG_Marshal(&data->h3, buffer, size);
1745
2
    written += SHA_LONG_Marshal(&data->h4, buffer, size);
1746
2
    written += SHA_LONG_Marshal(&data->Nl, buffer, size);
1747
2
    written += SHA_LONG_Marshal(&data->Nh, buffer, size);
1748
1749
    /* data must be written as array */
1750
2
    array_size = sizeof(data->data);
1751
2
    written += UINT16_Marshal(&array_size, buffer, size);
1752
2
    written += Array_Marshal((BYTE *)&data->data[0], array_size,
1753
2
                             buffer, size);
1754
1755
2
    written += UINT32_Marshal(&data->num, buffer, size);
1756
1757
2
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
1758
    /* future versions append below this line */
1759
1760
2
    BLOCK_SKIP_WRITE_POP(size);
1761
1762
2
    BLOCK_SKIP_WRITE_CHECK;
1763
1764
2
    return written;
1765
2
}
1766
1767
static UINT16
1768
tpmHashStateSHA1_Unmarshal(tpmHashStateSHA1_t *data, BYTE **buffer, INT32 *size)
1769
4
{
1770
4
    UINT16 rc = TPM_RC_SUCCESS;
1771
4
    NV_HEADER hdr;
1772
4
    UINT16 array_size;
1773
1774
4
    if (rc == TPM_RC_SUCCESS) {
1775
4
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
1776
4
                                 HASH_STATE_SHA1_VERSION,
1777
4
                                 HASH_STATE_SHA1_MAGIC);
1778
4
    }
1779
1780
4
    if (rc == TPM_RC_SUCCESS) {
1781
4
        rc = SHA_LONG_Unmarshal(&data->h0, buffer, size);
1782
4
    }
1783
4
    if (rc == TPM_RC_SUCCESS) {
1784
4
        rc = SHA_LONG_Unmarshal(&data->h1, buffer, size);
1785
4
    }
1786
4
    if (rc == TPM_RC_SUCCESS) {
1787
4
        rc = SHA_LONG_Unmarshal(&data->h2, buffer, size);
1788
4
    }
1789
4
    if (rc == TPM_RC_SUCCESS) {
1790
4
        rc = SHA_LONG_Unmarshal(&data->h3, buffer, size);
1791
4
    }
1792
4
    if (rc == TPM_RC_SUCCESS) {
1793
4
        rc = SHA_LONG_Unmarshal(&data->h4, buffer, size);
1794
4
    }
1795
4
    if (rc == TPM_RC_SUCCESS) {
1796
4
        rc = SHA_LONG_Unmarshal(&data->Nl, buffer, size);
1797
4
    }
1798
4
    if (rc == TPM_RC_SUCCESS) {
1799
4
        rc = SHA_LONG_Unmarshal(&data->Nh, buffer, size);
1800
4
    }
1801
1802
4
    if (rc == TPM_RC_SUCCESS) {
1803
4
        rc = UINT16_Unmarshal(&array_size, buffer, size);
1804
4
    }
1805
4
    if (rc == TPM_RC_SUCCESS &&
1806
4
        array_size != sizeof(data->data)) {
1807
0
        TPMLIB_LogTPM2Error("HASH_STATE_SHA1: Bad array size for data; "
1808
0
                            "expected %zu, got %u\n",
1809
0
                            sizeof(data->data), array_size);
1810
0
        rc = TPM_RC_BAD_PARAMETER;
1811
0
    }
1812
4
    if (rc == TPM_RC_SUCCESS) {
1813
4
        rc = Array_Unmarshal((BYTE *)&data->data[0], array_size,
1814
4
                             buffer, size);
1815
4
    }
1816
4
    if (rc == TPM_RC_SUCCESS) {
1817
4
        rc = UINT32_Unmarshal(&data->num, buffer, size);
1818
4
    }
1819
1820
    /* version 2 starts having indicator for next versions that we can skip;
1821
       this allows us to downgrade state */
1822
4
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
1823
4
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
1824
4
                        "HASH_STATE_SHA1", "version 3 or later");
1825
        /* future versions nest-append here */
1826
0
    }
1827
1828
4
skip_future_versions:
1829
1830
4
    return rc;
1831
4
}
1832
#endif
1833
1834
#if ALG_SHA256
1835
9
#define HASH_STATE_SHA256_MAGIC 0x6ea059d0
1836
9
#define HASH_STATE_SHA256_VERSION 2
1837
1838
static UINT16
1839
tpmHashStateSHA256_Marshal(tpmHashStateSHA256_t *data, BYTE **buffer, INT32 *size)
1840
3
{
1841
3
    UINT16 written = 0;
1842
3
    UINT16 array_size;
1843
3
    size_t i;
1844
3
    BLOCK_SKIP_INIT;
1845
1846
3
    written = NV_HEADER_Marshal(buffer, size,
1847
3
                                HASH_STATE_SHA256_VERSION,
1848
3
                                HASH_STATE_SHA256_MAGIC, 1);
1849
1850
3
    array_size = ARRAY_SIZE(data->h);
1851
3
    written += UINT16_Marshal(&array_size, buffer, size);
1852
27
    for (i = 0; i < array_size; i++) {
1853
24
        written += SHA_LONG_Marshal(&data->h[i], buffer, size);
1854
24
    }
1855
3
    written += SHA_LONG_Marshal(&data->Nl, buffer, size);
1856
3
    written += SHA_LONG_Marshal(&data->Nh, buffer, size);
1857
1858
    /* data must be written as array */
1859
3
    array_size = sizeof(data->data);
1860
3
    written += UINT16_Marshal(&array_size, buffer, size);
1861
3
    written += Array_Marshal((BYTE *)&data->data[0], array_size,
1862
3
                             buffer, size);
1863
1864
3
    written += UINT32_Marshal(&data->num, buffer, size);
1865
3
    written += UINT32_Marshal(&data->md_len, buffer, size);
1866
1867
3
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
1868
    /* future versions append below this line */
1869
1870
3
    BLOCK_SKIP_WRITE_POP(size);
1871
1872
3
    BLOCK_SKIP_WRITE_CHECK;
1873
1874
3
    return written;
1875
3
}
1876
1877
static UINT16
1878
tpmHashStateSHA256_Unmarshal(tpmHashStateSHA256_t *data, BYTE **buffer, INT32 *size)
1879
6
{
1880
6
    UINT16 rc = TPM_RC_SUCCESS;
1881
6
    size_t i;
1882
6
    UINT16 array_size;
1883
6
    NV_HEADER hdr;
1884
1885
6
    if (rc == TPM_RC_SUCCESS) {
1886
6
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
1887
6
                                 HASH_STATE_SHA256_VERSION,
1888
6
                                 HASH_STATE_SHA256_MAGIC);
1889
6
    }
1890
1891
6
    if (rc == TPM_RC_SUCCESS) {
1892
6
        rc = UINT16_Unmarshal(&array_size, buffer, size);
1893
6
    }
1894
6
    if (rc == TPM_RC_SUCCESS &&
1895
6
        array_size != ARRAY_SIZE(data->h)) {
1896
0
        TPMLIB_LogTPM2Error("HASH_STATE_SHA256: Bad array size for h; "
1897
0
                            "expected %zu, got %u\n",
1898
0
                            ARRAY_SIZE(data->h), array_size);
1899
0
        rc = TPM_RC_BAD_PARAMETER;
1900
0
    }
1901
54
    for (i = 0; rc == TPM_RC_SUCCESS && i < array_size; i++) {
1902
48
        rc = SHA_LONG_Unmarshal(&data->h[i], buffer, size);
1903
48
    }
1904
6
    if (rc == TPM_RC_SUCCESS) {
1905
6
        rc = SHA_LONG_Unmarshal(&data->Nl, buffer, size);
1906
6
    }
1907
6
    if (rc == TPM_RC_SUCCESS) {
1908
6
        rc = SHA_LONG_Unmarshal(&data->Nh, buffer, size);
1909
6
    }
1910
1911
6
    if (rc == TPM_RC_SUCCESS) {
1912
6
        rc = UINT16_Unmarshal(&array_size, buffer, size);
1913
6
    }
1914
6
    if (rc == TPM_RC_SUCCESS &&
1915
6
        array_size != sizeof(data->data)) {
1916
0
        TPMLIB_LogTPM2Error("HASH_STATE_SHA256: Bad array size for data; "
1917
0
                            "expected %zu, got %u\n",
1918
0
                            sizeof(data->data), array_size);
1919
0
        rc = TPM_RC_BAD_PARAMETER;
1920
0
    }
1921
6
    if (rc == TPM_RC_SUCCESS) {
1922
6
        rc = Array_Unmarshal((BYTE *)&data->data[0], array_size,
1923
6
                             buffer, size);
1924
6
    }
1925
6
    if (rc == TPM_RC_SUCCESS) {
1926
6
        rc = UINT32_Unmarshal(&data->num, buffer, size);
1927
6
    }
1928
6
    if (rc == TPM_RC_SUCCESS) {
1929
6
        rc = UINT32_Unmarshal(&data->md_len, buffer, size);
1930
6
    }
1931
1932
    /* version 2 starts having indicator for next versions that we can skip;
1933
       this allows us to downgrade state */
1934
6
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
1935
6
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
1936
6
                        "HASH_STATE_SHA256", "version 3 or later");
1937
        /* future versions nest-append here */
1938
0
    }
1939
1940
6
skip_future_versions:
1941
1942
6
    return rc;
1943
6
}
1944
#endif
1945
1946
#if ALG_SHA384 || ALG_SHA512
1947
1948
6
#define HASH_STATE_SHA384_MAGIC 0x14814b08
1949
6
#define HASH_STATE_SHA384_VERSION 2
1950
1951
9
#define HASH_STATE_SHA512_MAGIC 0x269e8ae0
1952
9
#define HASH_STATE_SHA512_VERSION 2
1953
1954
static UINT16
1955
tpmHashStateSHA512_Marshal(SHA512_CTX *data, BYTE **buffer, INT32 *size,
1956
                           UINT16 hashAlg)
1957
3
{
1958
3
    UINT16 written = 0;
1959
3
    UINT16 array_size;
1960
3
    size_t i;
1961
3
    BLOCK_SKIP_INIT;
1962
3
    UINT16 version = HASH_STATE_SHA512_VERSION;
1963
3
    UINT32 magic = HASH_STATE_SHA512_MAGIC;
1964
1965
3
    if (hashAlg == ALG_SHA384_VALUE) {
1966
2
        version = HASH_STATE_SHA384_VERSION;
1967
2
        magic = HASH_STATE_SHA384_MAGIC;
1968
2
    }
1969
1970
3
    written = NV_HEADER_Marshal(buffer, size,
1971
3
                                version, magic, 1);
1972
1973
3
    array_size = ARRAY_SIZE(data->h);
1974
3
    written += UINT16_Marshal(&array_size, buffer, size);
1975
27
    for (i = 0; i < array_size; i++) {
1976
24
        written += SHA_LONG64_Marshal(&data->h[i], buffer, size);
1977
24
    }
1978
3
    written += SHA_LONG64_Marshal(&data->Nl, buffer, size);
1979
3
    written += SHA_LONG64_Marshal(&data->Nh, buffer, size);
1980
1981
3
    array_size = sizeof(data->u.p);
1982
3
    written += UINT16_Marshal(&array_size, buffer, size);
1983
3
    written += Array_Marshal(&data->u.p[0], array_size, buffer, size);
1984
1985
3
    written += UINT32_Marshal(&data->num, buffer, size);
1986
3
    written += UINT32_Marshal(&data->md_len, buffer, size);
1987
1988
3
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
1989
    /* future versions append below this line */
1990
1991
3
    BLOCK_SKIP_WRITE_POP(size);
1992
1993
3
    BLOCK_SKIP_WRITE_CHECK;
1994
1995
3
    return written;
1996
3
}
1997
1998
static UINT16
1999
tpmHashStateSHA512_Unmarshal(SHA512_CTX *data, BYTE **buffer, INT32 *size,
2000
                             UINT16 hashAlg)
2001
6
{
2002
6
    UINT16 rc = TPM_RC_SUCCESS;
2003
6
    size_t i;
2004
6
    UINT16 array_size;
2005
6
    NV_HEADER hdr;
2006
6
    UINT16 version = HASH_STATE_SHA512_VERSION;
2007
6
    UINT32 magic = HASH_STATE_SHA512_MAGIC;
2008
2009
6
    if (hashAlg == ALG_SHA384_VALUE) {
2010
4
        version = HASH_STATE_SHA384_VERSION;
2011
4
        magic = HASH_STATE_SHA384_MAGIC;
2012
4
    }
2013
2014
6
    if (rc == TPM_RC_SUCCESS) {
2015
6
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
2016
6
                                 version, magic);
2017
6
    }
2018
2019
6
    if (rc == TPM_RC_SUCCESS) {
2020
6
        rc = UINT16_Unmarshal(&array_size, buffer, size);
2021
6
    }
2022
6
    if (rc == TPM_RC_SUCCESS &&
2023
6
        array_size != ARRAY_SIZE(data->h)) {
2024
0
        TPMLIB_LogTPM2Error("HASH_STATE_SHA512: Bad array size for h; "
2025
0
                            "expected %zu, got %u\n",
2026
0
                            ARRAY_SIZE(data->h), array_size);
2027
0
        rc = TPM_RC_BAD_PARAMETER;
2028
0
    }
2029
54
    for (i = 0; rc == TPM_RC_SUCCESS && i < array_size; i++) {
2030
48
        rc = SHA_LONG64_Unmarshal(&data->h[i], buffer, size);
2031
48
    }
2032
6
    if (rc == TPM_RC_SUCCESS) {
2033
6
        rc = SHA_LONG64_Unmarshal(&data->Nl, buffer, size);
2034
6
    }
2035
6
    if (rc == TPM_RC_SUCCESS) {
2036
6
        rc = SHA_LONG64_Unmarshal(&data->Nh, buffer, size);
2037
6
    }
2038
2039
6
    if (rc == TPM_RC_SUCCESS) {
2040
6
        rc = UINT16_Unmarshal(&array_size, buffer, size);
2041
6
    }
2042
6
    if (rc == TPM_RC_SUCCESS &&
2043
6
        array_size != sizeof(data->u.p)) {
2044
0
        TPMLIB_LogTPM2Error("HASH_STATE_SHA512: Bad array size for u.p; "
2045
0
                            "expected %zu, got %u\n",
2046
0
                            sizeof(data->u.p), array_size);
2047
0
        rc = TPM_RC_BAD_PARAMETER;
2048
0
    }
2049
6
    if (rc == TPM_RC_SUCCESS) {
2050
6
        rc = Array_Unmarshal(&data->u.p[0], array_size, buffer, size);
2051
6
    }
2052
6
    if (rc == TPM_RC_SUCCESS) {
2053
6
        rc = UINT32_Unmarshal(&data->num, buffer, size);
2054
6
    }
2055
6
    if (rc == TPM_RC_SUCCESS) {
2056
6
        rc = UINT32_Unmarshal(&data->md_len, buffer, size);
2057
6
    }
2058
2059
    /* version 2 starts having indicator for next versions that we can skip;
2060
       this allows us to downgrade state */
2061
6
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
2062
6
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
2063
6
                        "HASH_STATE_SHA512", "version 3 or later");
2064
        /* future versions nest-append here */
2065
0
    }
2066
2067
6
skip_future_versions:
2068
2069
6
    return rc;
2070
6
}
2071
#endif
2072
2073
60
#define ANY_HASH_STATE_MAGIC 0x349d494b
2074
60
#define ANY_HASH_STATE_VERSION 2
2075
2076
static UINT16
2077
ANY_HASH_STATE_Marshal(ANY_HASH_STATE *data, BYTE **buffer, INT32 *size,
2078
                       UINT16 hashAlg)
2079
20
{
2080
20
    UINT16 written;
2081
20
    BLOCK_SKIP_INIT;
2082
2083
20
    written = NV_HEADER_Marshal(buffer, size,
2084
20
                                ANY_HASH_STATE_VERSION,
2085
20
                                ANY_HASH_STATE_MAGIC, 1);
2086
2087
20
    switch (hashAlg) {
2088
0
#if ALG_SHA1
2089
2
    case ALG_SHA1_VALUE:
2090
2
        written += tpmHashStateSHA1_Marshal(&data->Sha1, buffer, size);
2091
2
        break;
2092
0
#endif
2093
0
#if ALG_SHA256
2094
3
    case ALG_SHA256_VALUE:
2095
3
        written += tpmHashStateSHA256_Marshal(&data->Sha256, buffer, size);
2096
3
        break;
2097
0
#endif
2098
0
#if ALG_SHA384
2099
2
    case ALG_SHA384_VALUE:
2100
2
        written += tpmHashStateSHA512_Marshal(&data->Sha384, buffer, size,
2101
2
                                              ALG_SHA384_VALUE);
2102
2
        break;
2103
0
#endif
2104
0
#if ALG_SHA512
2105
1
    case ALG_SHA512_VALUE:
2106
1
        written += tpmHashStateSHA512_Marshal(&data->Sha512, buffer, size,
2107
1
                                              ALG_SHA512_VALUE);
2108
1
        break;
2109
0
#endif
2110
12
    default:
2111
12
        break;
2112
20
    }
2113
2114
20
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
2115
    /* future versions append below this line */
2116
2117
20
    BLOCK_SKIP_WRITE_POP(size);
2118
2119
20
    BLOCK_SKIP_WRITE_CHECK;
2120
2121
20
    return written;
2122
20
}
2123
2124
static UINT16
2125
ANY_HASH_STATE_Unmarshal(ANY_HASH_STATE *data, BYTE **buffer, INT32 *size,
2126
                         UINT16 hashAlg)
2127
40
{
2128
40
    UINT16 rc = TPM_RC_SUCCESS;
2129
40
    NV_HEADER hdr;
2130
2131
40
    if (rc == TPM_RC_SUCCESS) {
2132
40
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
2133
40
                                 ANY_HASH_STATE_VERSION,
2134
40
                                 ANY_HASH_STATE_MAGIC);
2135
40
    }
2136
2137
40
    switch (hashAlg) {
2138
0
#if ALG_SHA1
2139
4
    case ALG_SHA1_VALUE:
2140
4
        rc = tpmHashStateSHA1_Unmarshal(&data->Sha1, buffer, size);
2141
4
        break;
2142
0
#endif
2143
0
#if ALG_SHA256
2144
6
    case ALG_SHA256_VALUE:
2145
6
        rc = tpmHashStateSHA256_Unmarshal(&data->Sha256, buffer, size);
2146
6
        break;
2147
0
#endif
2148
0
#if ALG_SHA384
2149
4
    case ALG_SHA384_VALUE:
2150
4
        rc = tpmHashStateSHA512_Unmarshal(&data->Sha384, buffer, size,
2151
4
                                          ALG_SHA384_VALUE);
2152
4
        break;
2153
0
#endif
2154
0
#if ALG_SHA512
2155
2
    case ALG_SHA512_VALUE:
2156
2
        rc = tpmHashStateSHA512_Unmarshal(&data->Sha512, buffer, size,
2157
2
                                          ALG_SHA512_VALUE);
2158
2
        break;
2159
40
#endif
2160
40
    }
2161
2162
    /* version 2 starts having indicator for next versions that we can skip;
2163
       this allows us to downgrade state */
2164
40
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
2165
40
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
2166
40
                        "ANY_HASH_STATE", "version 3 or later");
2167
        /* future versions nest-append here */
2168
0
    }
2169
2170
40
skip_future_versions:
2171
2172
40
    return rc;
2173
40
}
2174
2175
60
#define HASH_STATE_MAGIC 0x562878a2
2176
60
#define HASH_STATE_VERSION 2
2177
2178
static UINT16
2179
HASH_STATE_Marshal(HASH_STATE *data, BYTE **buffer, INT32 *size)
2180
20
{
2181
20
    UINT16 written;
2182
20
    BLOCK_SKIP_INIT;
2183
2184
20
    written = NV_HEADER_Marshal(buffer, size,
2185
20
                                HASH_STATE_VERSION,
2186
20
                                HASH_STATE_MAGIC, 1);
2187
2188
20
    written += HASH_STATE_TYPE_Marshal(&data->type, buffer, size);
2189
20
    written += TPM_ALG_ID_Marshal(&data->hashAlg, buffer, size);
2190
    /* def does not need to be written */
2191
20
    written += ANY_HASH_STATE_Marshal(&data->state, buffer, size, data->hashAlg);
2192
2193
20
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
2194
    /* future versions append below this line */
2195
2196
20
    BLOCK_SKIP_WRITE_POP(size);
2197
2198
20
    BLOCK_SKIP_WRITE_CHECK;
2199
2200
20
    return written;
2201
20
}
2202
2203
static UINT16
2204
HASH_STATE_Unmarshal(HASH_STATE *data, BYTE **buffer, INT32 *size)
2205
40
{
2206
40
    UINT16 rc = TPM_RC_SUCCESS;
2207
40
    NV_HEADER hdr;
2208
2209
40
    if (rc == TPM_RC_SUCCESS) {
2210
40
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
2211
40
                                 HASH_STATE_VERSION, HASH_STATE_MAGIC);
2212
40
    }
2213
2214
40
    if (rc == TPM_RC_SUCCESS) {
2215
40
        rc = HASH_STATE_TYPE_Unmarshal(&data->type, buffer, size);
2216
40
    }
2217
40
    if (rc == TPM_RC_SUCCESS) {
2218
40
        rc  = TPM_ALG_ID_Unmarshal(&data->hashAlg, buffer, size);
2219
40
    }
2220
40
    if (rc == TPM_RC_SUCCESS) {
2221
40
        data->def = CryptGetHashDef(data->hashAlg);
2222
40
        if (!data->def) {
2223
0
            TPMLIB_LogTPM2Error("Could not get hash function interface for "
2224
0
                                "hashAlg 0x%02x\n", data->hashAlg);
2225
0
            rc = TPM_RC_BAD_PARAMETER;
2226
0
        }
2227
40
    }
2228
40
    if (rc == TPM_RC_SUCCESS) {
2229
40
        rc = ANY_HASH_STATE_Unmarshal(&data->state, buffer, size, data->hashAlg);
2230
40
    }
2231
2232
    /* version 2 starts having indicator for next versions that we can skip;
2233
       this allows us to downgrade state */
2234
40
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
2235
40
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
2236
40
                        "HASH_STATE", "version 3 or later");
2237
        /* future versions nest-append here */
2238
0
    }
2239
2240
40
skip_future_versions:
2241
40
    return rc;
2242
40
}
2243
2244
static inline UINT16
2245
TPM2B_HASH_BLOCK_Marshal(TPM2B_HASH_BLOCK *data, BYTE **buffer, INT32 *size)
2246
0
{
2247
0
    UINT16 written;
2248
2249
0
    written = TPM2B_Marshal(&data->b, sizeof(data->t.buffer), buffer, size);
2250
2251
0
    return written;
2252
0
}
2253
2254
static inline UINT16
2255
TPM2B_HASH_BLOCK_Unmarshal(TPM2B_HASH_BLOCK *data, BYTE **buffer, INT32 *size)
2256
0
{
2257
0
    UINT16 rc;
2258
2259
0
    rc = TPM2B_Unmarshal(&data->b, sizeof(data->t.buffer), buffer, size);
2260
2261
0
    return rc;
2262
0
}
2263
2264
static UINT16
2265
HMAC_STATE_Marshal(HMAC_STATE *data, BYTE **buffer, INT32 *size)
2266
0
{
2267
0
    UINT16 written;
2268
2269
0
    written = HASH_STATE_Marshal(&data->hashState, buffer, size);
2270
0
    written += TPM2B_HASH_BLOCK_Marshal(&data->hmacKey, buffer, size);
2271
2272
0
    return written;
2273
0
}
2274
2275
static UINT16
2276
HMAC_STATE_Unmarshal(HMAC_STATE *data, BYTE **buffer, INT32 *size)
2277
0
{
2278
0
    UINT16 rc = TPM_RC_SUCCESS;
2279
2280
0
    if (rc == TPM_RC_SUCCESS) {
2281
0
        rc = HASH_STATE_Unmarshal(&data->hashState, buffer, size);
2282
0
    }
2283
0
    if (rc == TPM_RC_SUCCESS) {
2284
0
        rc = TPM2B_HASH_BLOCK_Unmarshal(&data->hmacKey, buffer, size);
2285
0
    }
2286
2287
0
    return rc;
2288
0
}
2289
2290
15
#define HASH_OBJECT_MAGIC 0xb874fe38
2291
15
#define HASH_OBJECT_VERSION 3
2292
2293
static UINT16
2294
HASH_OBJECT_Marshal(HASH_OBJECT *data, BYTE **buffer, INT32 *size)
2295
5
{
2296
5
    UINT16 written;
2297
5
    size_t i;
2298
5
    UINT16 array_size;
2299
5
    BLOCK_SKIP_INIT;
2300
2301
5
    written = NV_HEADER_Marshal(buffer, size,
2302
5
                                HASH_OBJECT_VERSION, HASH_OBJECT_MAGIC, 1);
2303
5
    written += TPMI_ALG_PUBLIC_Marshal(&data->type, buffer, size);
2304
5
    written += TPMI_ALG_HASH_Marshal(&data->nameAlg, buffer, size);
2305
5
    written += TPMA_OBJECT_Marshal(&data->objectAttributes, buffer, size);
2306
5
    written += TPM2B_AUTH_Marshal(&data->auth, buffer, size);
2307
5
    if (data->attributes.hashSeq == SET ||
2308
5
        data->attributes.eventSeq == SET /* since v3 */) {
2309
5
        array_size = ARRAY_SIZE(data->state.hashState);
2310
5
        written += UINT16_Marshal(&array_size, buffer, size);
2311
25
        for (i = 0; i < array_size; i++) {
2312
20
            written += HASH_STATE_Marshal(&data->state.hashState[i], buffer,
2313
20
                                          size);
2314
20
        }
2315
5
    } else if (data->attributes.hmacSeq == SET) {
2316
0
        written += HMAC_STATE_Marshal(&data->state.hmacState, buffer, size);
2317
0
    }
2318
2319
5
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
2320
    /* future versions append below this line */
2321
2322
5
    BLOCK_SKIP_WRITE_POP(size);
2323
2324
5
    BLOCK_SKIP_WRITE_CHECK;
2325
2326
5
    return written;
2327
5
}
2328
2329
static UINT16
2330
HASH_OBJECT_Unmarshal(HASH_OBJECT *data, BYTE **buffer, INT32 *size)
2331
10
{
2332
10
    TPM_RC rc = TPM_RC_SUCCESS;
2333
10
    size_t i;
2334
10
    UINT16 array_size;
2335
10
    NV_HEADER hdr;
2336
2337
10
    if (rc == TPM_RC_SUCCESS) {
2338
10
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
2339
10
                                 HASH_OBJECT_VERSION, HASH_OBJECT_MAGIC);
2340
10
    }
2341
10
    if (rc == TPM_RC_SUCCESS) {
2342
10
        rc = TPMI_ALG_PUBLIC_Unmarshal(&data->type, buffer, size);
2343
10
        if (rc == TPM_RC_TYPE)
2344
10
            rc = TPM_RC_SUCCESS;
2345
10
    }
2346
10
    if (rc == TPM_RC_SUCCESS) {
2347
10
        rc = TPMI_ALG_HASH_Unmarshal(&data->nameAlg, buffer, size, TRUE);
2348
10
    }
2349
10
    if (rc == TPM_RC_SUCCESS) {
2350
10
        rc = TPMA_OBJECT_Unmarshal(&data->objectAttributes, buffer, size);
2351
10
    }
2352
10
    if (rc == TPM_RC_SUCCESS) {
2353
10
        rc = TPM2B_AUTH_Unmarshal(&data->auth, buffer, size);
2354
10
    }
2355
10
    if (rc == TPM_RC_SUCCESS) {
2356
        /* hashSeq was always written correctly; eventSeq only appeared in v3 */
2357
10
        if (data->attributes.hashSeq == SET ||
2358
10
            (data->attributes.eventSeq == SET && hdr.version >= 3)) {
2359
10
            if (rc == TPM_RC_SUCCESS) {
2360
10
                rc = UINT16_Unmarshal(&array_size, buffer, size);
2361
10
            }
2362
10
            if (rc == TPM_RC_SUCCESS) {
2363
10
                if (array_size != ARRAY_SIZE(data->state.hashState)) {
2364
0
                    TPMLIB_LogTPM2Error("HASH_OBJECT: Bad array size for state.hashState; "
2365
0
                                        "expected %zu, got %u\n",
2366
0
                                        ARRAY_SIZE(data->state.hashState),
2367
0
                                        array_size);
2368
0
                    rc = TPM_RC_SIZE;
2369
0
                }
2370
10
            }
2371
50
            for (i = 0; rc == TPM_RC_SUCCESS && i < array_size; i++) {
2372
40
                rc = HASH_STATE_Unmarshal(&data->state.hashState[i],
2373
40
                                          buffer, size);
2374
40
            }
2375
10
        } else if (data->attributes.hmacSeq == SET) {
2376
0
            rc = HMAC_STATE_Unmarshal(&data->state.hmacState, buffer, size);
2377
0
        }
2378
10
    }
2379
2380
    /* version 2 starts having indicator for next versions that we can skip;
2381
       this allows us to downgrade state */
2382
10
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
2383
10
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
2384
10
                        "HASH_OBJECT", "version 3 or later");
2385
        /* future versions nest-append here */
2386
0
    }
2387
2388
10
skip_future_versions:
2389
2390
10
    return rc;
2391
10
}
2392
2393
/* Local version of TPMT_SENSITIVE_Marshal handling public keys that don't have much in TPM_SENSITIVE */
2394
static UINT16
2395
NV_TPMT_SENSITIVE_Marshal(TPMT_SENSITIVE *source, BYTE **buffer, INT32 *size)
2396
329
{
2397
329
    UINT16 written = 0;
2398
2399
329
    written += TPM_ALG_ID_Marshal(&source->sensitiveType, buffer, size);
2400
329
    written += TPM2B_AUTH_Marshal(&source->authValue, buffer, size);
2401
329
    written += TPM2B_DIGEST_Marshal(&source->seedValue, buffer, size);
2402
2403
329
    switch (source->sensitiveType) {
2404
87
    case TPM_ALG_RSA:
2405
146
    case TPM_ALG_ECC:
2406
162
    case TPM_ALG_KEYEDHASH:
2407
273
    case TPM_ALG_SYMCIPHER:
2408
273
        written += TPMU_SENSITIVE_COMPOSITE_Marshal(&source->sensitive, buffer, size, source->sensitiveType);
2409
273
        break;
2410
56
    default:
2411
        /* we wrote these but they must have been 0 in this case */
2412
56
        pAssert(source->authValue.t.size == 0);
2413
56
        pAssert(source->seedValue.t.size == 0);
2414
329
        pAssert(source->sensitiveType == TPM_ALG_ERROR);
2415
        /* public keys */
2416
329
    }
2417
329
    return written;
2418
329
}
2419
2420
/* local version of TPM_SENSITIVE_Unmarshal handling public keys that don't have much in TPMT_SENSITVE */
2421
static TPM_RC
2422
NV_TPMT_SENSITIVE_Unmarshal(TPMT_SENSITIVE *target, BYTE **buffer, INT32 *size)
2423
658
{
2424
658
    TPM_RC rc = TPM_RC_SUCCESS;
2425
2426
658
    if (rc == TPM_RC_SUCCESS) {
2427
        /* TPMI_ALG_PUBLIC_Unmarshal would test the sensitiveType; we don't want this */
2428
658
  rc = TPM_ALG_ID_Unmarshal(&target->sensitiveType, buffer, size);
2429
658
    }
2430
658
    if (rc == TPM_RC_SUCCESS) {
2431
658
  rc = TPM2B_AUTH_Unmarshal(&target->authValue, buffer, size);
2432
658
    }
2433
658
    if (rc == TPM_RC_SUCCESS) {
2434
658
  rc = TPM2B_DIGEST_Unmarshal(&target->seedValue, buffer, size);
2435
658
    }
2436
658
    if (rc == TPM_RC_SUCCESS) {
2437
658
        switch (target->sensitiveType) {
2438
174
        case TPM_ALG_RSA:
2439
292
        case TPM_ALG_ECC:
2440
324
        case TPM_ALG_KEYEDHASH:
2441
546
        case TPM_ALG_SYMCIPHER:
2442
546
      rc = TPMU_SENSITIVE_COMPOSITE_Unmarshal(&target->sensitive, buffer, size, target->sensitiveType);
2443
546
      break;
2444
112
  default:
2445
112
            pAssert(target->authValue.t.size == 0);
2446
112
            pAssert(target->seedValue.t.size == 0);
2447
658
            pAssert(target->sensitiveType == TPM_ALG_ERROR);
2448
      /* nothing do to do */
2449
658
  }
2450
658
    }
2451
658
    return rc;
2452
658
}
2453
2454
987
#define OBJECT_MAGIC 0x75be73af
2455
658
#define OBJECT_VERSION 4
2456
2457
static UINT16
2458
OBJECT_Marshal(OBJECT *data, BYTE **buffer, INT32 *size,
2459
               struct RuntimeProfile *RuntimeProfile)
2460
329
{
2461
329
    UINT16 written;
2462
329
    BOOL has_block;
2463
329
    BLOCK_SKIP_INIT;
2464
329
    UINT16 blob_version;
2465
2466
329
    switch (RuntimeProfile->stateFormatLevel) {
2467
0
    case 0:
2468
0
        pAssert(FALSE);
2469
0
        break;
2470
329
    case 1 ... 5:
2471
329
        blob_version = 3;
2472
329
        break;
2473
0
    default:  // since StateFormatLevel 6
2474
0
        blob_version = 4;
2475
0
        break;
2476
329
    }
2477
2478
329
    written = NV_HEADER_Marshal(buffer, size,
2479
329
                                blob_version, OBJECT_MAGIC, blob_version);
2480
2481
    /*
2482
     * attributes are written in ANY_OBJECT_Marshal
2483
     */
2484
329
    written += TPMT_PUBLIC_Marshal(&data->publicArea, buffer, size);
2485
329
    written += NV_TPMT_SENSITIVE_Marshal(&data->sensitive, buffer, size);
2486
2487
    /* before v4: private exponent was always written
2488
     *  since v4: private exponent only written for RSA keys
2489
     */
2490
329
    has_block = TRUE;
2491
329
    if (blob_version >= 4 &&
2492
0
        data->sensitive.sensitiveType != TPM_ALG_RSA)
2493
0
        has_block = FALSE;
2494
2495
329
    written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
2496
329
    if (has_block)
2497
329
        written += privateExponent_t_Marshal(&data->privateExponent,
2498
329
                                             buffer, size);
2499
329
    BLOCK_SKIP_WRITE_POP(size);
2500
2501
329
    written += TPM2B_NAME_Marshal(&data->qualifiedName, buffer, size);
2502
329
    written += TPM_HANDLE_Marshal(&data->evictHandle, buffer, size);
2503
329
    written += TPM2B_NAME_Marshal(&data->name, buffer, size);
2504
2505
329
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
2506
329
    written += SEED_COMPAT_LEVEL_Marshal(&data->seedCompatLevel,
2507
329
                                         buffer, size);
2508
2509
329
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
2510
    /* future versions append below this line */
2511
2512
    /* since v4: hierarchy is written */
2513
329
    if (blob_version >= 4)
2514
0
        written += TPMI_RH_HIERARCHY_Marshal(&data->hierarchy, buffer, size);
2515
2516
329
    BLOCK_SKIP_WRITE_POP(size);
2517
329
    BLOCK_SKIP_WRITE_POP(size);
2518
2519
329
    BLOCK_SKIP_WRITE_CHECK;
2520
2521
329
    return written;
2522
329
}
2523
2524
static TPM_RC
2525
OBJECT_Unmarshal(OBJECT *data, BYTE **buffer, INT32 *size)
2526
658
{
2527
658
    TPM_RC rc = TPM_RC_SUCCESS;
2528
658
    NV_HEADER hdr;
2529
658
    BOOL needs_block;
2530
2531
    /*
2532
     * attributes are read in ANY_OBJECT_Unmarshal
2533
     */
2534
658
    if (rc == TPM_RC_SUCCESS) {
2535
658
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
2536
658
                                 OBJECT_VERSION, OBJECT_MAGIC);
2537
658
    }
2538
2539
658
    if (rc == TPM_RC_SUCCESS) {
2540
658
        rc = TPMT_PUBLIC_Unmarshal(&data->publicArea, buffer, size, TRUE);
2541
658
    }
2542
658
    if (rc == TPM_RC_SUCCESS) {
2543
658
        rc = NV_TPMT_SENSITIVE_Unmarshal(&data->sensitive, buffer, size);
2544
658
    }
2545
2546
    /* before v4: private exponent was always written
2547
     *  since v4: private exponent only written for RSA keys
2548
     */
2549
658
    needs_block = TRUE;
2550
658
    if (hdr.version >= 4 &&
2551
0
        data->sensitive.sensitiveType != TPM_ALG_RSA)
2552
0
        needs_block = FALSE;
2553
2554
658
    if (rc == TPM_RC_SUCCESS) {
2555
658
        BLOCK_SKIP_READ(skip_alg_rsa, needs_block, buffer, size,
2556
658
                        "OBJECT", "privateExponent");
2557
658
    }
2558
658
    if (rc == TPM_RC_SUCCESS) {
2559
658
        rc = privateExponent_t_Unmarshal(&data->privateExponent,
2560
658
                                         buffer, size);
2561
658
    }
2562
658
skip_alg_rsa:
2563
2564
658
    if (rc == TPM_RC_SUCCESS) {
2565
658
        rc = TPM2B_NAME_Unmarshal(&data->qualifiedName, buffer, size);
2566
658
    }
2567
658
    if (rc == TPM_RC_SUCCESS) {
2568
658
        rc = TPM_HANDLE_Unmarshal(&data->evictHandle, buffer, size);
2569
658
    }
2570
658
    if (rc == TPM_RC_SUCCESS) {
2571
658
        rc = TPM2B_NAME_Unmarshal(&data->name, buffer, size);
2572
658
    }
2573
2574
    /* default values before conditional block */
2575
658
    data->seedCompatLevel = SEED_COMPAT_LEVEL_ORIGINAL;
2576
658
    data->hierarchy = ObjectGetHierarchyFromAttributes(data);
2577
2578
    /* version 2 starts having indicator for next versions that we can skip;
2579
       this allows us to downgrade state */
2580
658
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
2581
658
        BLOCK_SKIP_READ(skip_future_versions, hdr.version >= 3, buffer, size,
2582
658
                        "OBJECT", "version 3 or later");
2583
658
        if (rc == TPM_RC_SUCCESS) {
2584
658
            rc = SEED_COMPAT_LEVEL_Unmarshal(&data->seedCompatLevel,
2585
658
                                        buffer, size,
2586
658
                                        "OBJECT seedCompatLevel");
2587
658
        }
2588
2589
658
        if (rc == TPM_RC_SUCCESS) {
2590
658
            BLOCK_SKIP_READ(skip_future_versions, hdr.version >= 4, buffer, size,
2591
658
                            "OBJECT", "version 4 or later");
2592
0
        }
2593
2594
0
        if (rc == TPM_RC_SUCCESS) {
2595
0
            rc = TPMI_RH_HIERARCHY_Unmarshal(&data->hierarchy, buffer, size, TRUE);
2596
0
        }
2597
0
    }
2598
2599
658
skip_future_versions:
2600
658
    return rc;
2601
658
}
2602
2603
54.3k
#define ANY_OBJECT_MAGIC 0xfe9a3974
2604
54.3k
#define ANY_OBJECT_VERSION 2
2605
2606
UINT16
2607
ANY_OBJECT_Marshal(OBJECT *data, BYTE **buffer, INT32 *size,
2608
                   struct RuntimeProfile *RuntimeProfile)
2609
18.1k
{
2610
18.1k
    UINT16 written;
2611
18.1k
    UINT32 *ptr = (UINT32 *)&data->attributes;
2612
18.1k
    BLOCK_SKIP_INIT;
2613
2614
18.1k
    written = NV_HEADER_Marshal(buffer, size,
2615
18.1k
                                ANY_OBJECT_VERSION, ANY_OBJECT_MAGIC, 1);
2616
2617
18.1k
    written += UINT32_Marshal(ptr, buffer, size);
2618
    /* the slot must be occupied, otherwise the rest may not be initialized */
2619
18.1k
    if (data->attributes.occupied) {
2620
334
        if (ObjectIsSequence(data))
2621
5
            written += HASH_OBJECT_Marshal((HASH_OBJECT *)data, buffer, size);
2622
329
        else
2623
329
            written += OBJECT_Marshal(data, buffer, size, RuntimeProfile);
2624
334
    }
2625
2626
18.1k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
2627
    /* future versions append below this line */
2628
2629
18.1k
    BLOCK_SKIP_WRITE_POP(size);
2630
2631
18.1k
    BLOCK_SKIP_WRITE_CHECK;
2632
2633
18.1k
    return written;
2634
18.1k
}
2635
2636
TPM_RC
2637
ANY_OBJECT_Unmarshal(OBJECT *data, BYTE **buffer, INT32 *size, BOOL verbose)
2638
36.2k
{
2639
36.2k
    TPM_RC rc = TPM_RC_SUCCESS;
2640
36.2k
    UINT32 *ptr = (UINT32 *)&data->attributes;
2641
36.2k
    NV_HEADER hdr;
2642
2643
36.2k
    if (rc == TPM_RC_SUCCESS) {
2644
36.2k
        rc = NV_HEADER_UnmarshalVerbose(&hdr, buffer, size,
2645
36.2k
                                        ANY_OBJECT_VERSION, ANY_OBJECT_MAGIC,
2646
36.2k
                                        verbose);
2647
36.2k
    }
2648
36.2k
    if (rc == TPM_RC_SUCCESS) {
2649
36.2k
        rc = UINT32_Unmarshal(ptr, buffer, size);
2650
36.2k
    }
2651
2652
36.2k
    if (rc == TPM_RC_SUCCESS && data->attributes.occupied) {
2653
668
        if (ObjectIsSequence(data))
2654
10
            rc = HASH_OBJECT_Unmarshal((HASH_OBJECT *)data, buffer, size);
2655
658
        else
2656
658
            rc = OBJECT_Unmarshal(data, buffer, size);
2657
668
    }
2658
2659
    /* version 2 starts having indicator for next versions that we can skip;
2660
       this allows us to downgrade state */
2661
36.2k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
2662
36.2k
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
2663
36.2k
                        "ANY_OBJECT", "version 3 or later");
2664
        /* future versions nest-append here */
2665
0
    }
2666
2667
36.2k
skip_future_versions:
2668
2669
36.2k
    return rc;
2670
36.2k
}
2671
2672
static UINT16
2673
TPMT_SYM_DEF_Marshal(TPMT_SYM_DEF *data, BYTE **buffer, INT32 *size)
2674
27
{
2675
27
    UINT16 written;
2676
2677
27
    written = UINT16_Marshal(&data->algorithm, buffer, size);
2678
27
    written += TPMU_SYM_KEY_BITS_Marshal(&data->keyBits, buffer, size, data->algorithm);
2679
27
    written += TPMU_SYM_MODE_Marshal(&data->mode, buffer, size, data->algorithm);
2680
2681
27
    return written;
2682
27
}
2683
2684
81
#define SESSION_MAGIC 0x44be9f45
2685
81
#define SESSION_VERSION 2
2686
2687
static UINT16
2688
SESSION_Marshal(SESSION *data, BYTE **buffer, INT32 *size)
2689
27
{
2690
27
    UINT16 written;
2691
27
    UINT8 clocksize;
2692
27
    BLOCK_SKIP_INIT;
2693
2694
27
    written = NV_HEADER_Marshal(buffer, size,
2695
27
                                SESSION_VERSION, SESSION_MAGIC, 1);
2696
27
    written += UINT32_Marshal((UINT32 *)&data->attributes, buffer, size);
2697
27
    written += UINT32_Marshal(&data->pcrCounter, buffer, size);
2698
27
    written += UINT64_Marshal(&data->startTime, buffer, size);
2699
27
    written += UINT64_Marshal(&data->timeout, buffer, size);
2700
2701
#if CLOCK_STOPS
2702
    clocksize = sizeof(UINT64);
2703
    written += UINT8_Marshal(&clocksize, buffer, size);
2704
    written += UINT64_Marshal(&data->epoch, buffer, size);
2705
#else
2706
27
    clocksize = sizeof(UINT32);
2707
27
    written += UINT8_Marshal(&clocksize, buffer, size);
2708
27
    written += UINT32_Marshal(&data->epoch, buffer, size);
2709
27
#endif
2710
2711
27
    written += UINT32_Marshal(&data->commandCode, buffer, size);
2712
27
    written += UINT16_Marshal(&data->authHashAlg, buffer, size);
2713
27
    written += UINT8_Marshal(&data->commandLocality, buffer, size);
2714
27
    written += TPMT_SYM_DEF_Marshal(&data->symmetric, buffer, size);
2715
27
    written += TPM2B_AUTH_Marshal(&data->sessionKey, buffer, size);
2716
27
    written += TPM2B_NONCE_Marshal(&data->nonceTPM, buffer, size);
2717
    // TPM2B_NAME or TPM2B_DIGEST could be used for marshalling
2718
27
    MUST_BE(sizeof(data->u1.boundEntity) == sizeof(data->u1));
2719
27
    written += TPM2B_NAME_Marshal(&data->u1.boundEntity, buffer, size);
2720
27
    MUST_BE(sizeof(data->u2.auditDigest) == sizeof(data->u2));
2721
27
    written += TPM2B_DIGEST_Marshal(&data->u2.auditDigest, buffer, size);
2722
2723
27
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
2724
    /* future versions append below this line */
2725
2726
27
    BLOCK_SKIP_WRITE_POP(size);
2727
2728
27
    BLOCK_SKIP_WRITE_CHECK;
2729
2730
27
    return written;
2731
27
}
2732
2733
static TPM_RC
2734
SESSION_Unmarshal(SESSION *data, BYTE **buffer, INT32 *size)
2735
54
{
2736
54
    TPM_RC rc = TPM_RC_SUCCESS;
2737
54
    NV_HEADER hdr;
2738
54
    UINT8 clocksize;
2739
2740
54
    if (rc == TPM_RC_SUCCESS) {
2741
54
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
2742
54
                                 SESSION_VERSION, SESSION_MAGIC);
2743
54
    }
2744
54
    if (rc == TPM_RC_SUCCESS) {
2745
54
        rc = UINT32_Unmarshal((UINT32 *)&data->attributes, buffer, size);
2746
54
    }
2747
54
    if (rc == TPM_RC_SUCCESS) {
2748
54
        rc = UINT32_Unmarshal(&data->pcrCounter, buffer, size);
2749
54
    }
2750
54
    if (rc == TPM_RC_SUCCESS) {
2751
54
        rc = UINT64_Unmarshal(&data->startTime, buffer, size);
2752
54
    }
2753
54
    if (rc == TPM_RC_SUCCESS) {
2754
54
        rc = UINT64_Unmarshal(&data->timeout, buffer, size);
2755
54
    }
2756
54
    if (rc == TPM_RC_SUCCESS) {
2757
54
        rc = UINT8_Unmarshal(&clocksize, buffer, size);
2758
54
    }
2759
54
    if (rc == TPM_RC_SUCCESS) {
2760
#if CLOCK_STOPS
2761
        if (clocksize != sizeof(UINT64)) {
2762
            TPMLIB_LogTPM2Error("Unexpected clocksize for epoch; "
2763
                                "Expected %zu, got %u\n",
2764
                                sizeof(UINT64), clocksize);
2765
            rc = TPM_RC_BAD_PARAMETER;
2766
        }
2767
        if (rc == TPM_RC_SUCCESS) {
2768
            rc = UINT64_Unmarshal(&data->epoch, buffer, size);
2769
        }
2770
#else
2771
54
        if (clocksize != sizeof(UINT32)) {
2772
0
            TPMLIB_LogTPM2Error("Unexpected clocksize for epoch; "
2773
0
                                "Expected %zu, got %u\n",
2774
0
                                sizeof(UINT32), clocksize);
2775
0
            rc = TPM_RC_BAD_PARAMETER;
2776
0
        }
2777
54
        if (rc == TPM_RC_SUCCESS) {
2778
54
            rc = UINT32_Unmarshal(&data->epoch, buffer, size);
2779
54
        }
2780
54
#endif
2781
54
    }
2782
54
    if (rc == TPM_RC_SUCCESS) {
2783
54
        rc = UINT32_Unmarshal(&data->commandCode, buffer, size);
2784
54
    }
2785
54
    if (rc == TPM_RC_SUCCESS) {
2786
54
        rc = UINT16_Unmarshal(&data->authHashAlg, buffer, size);
2787
54
    }
2788
54
    if (rc == TPM_RC_SUCCESS) {
2789
54
        rc = UINT8_Unmarshal(&data->commandLocality, buffer, size);
2790
54
    }
2791
54
    if (rc == TPM_RC_SUCCESS) {
2792
54
        rc = TPMT_SYM_DEF_Unmarshal(&data->symmetric, buffer, size, YES);
2793
54
    }
2794
54
    if (rc == TPM_RC_SUCCESS) {
2795
54
        rc = TPM2B_AUTH_Unmarshal(&data->sessionKey, buffer, size);
2796
54
    }
2797
54
    if (rc == TPM_RC_SUCCESS) {
2798
54
        rc = TPM2B_NONCE_Unmarshal(&data->nonceTPM, buffer, size);
2799
54
    }
2800
54
    if (rc == TPM_RC_SUCCESS) {
2801
54
        rc = TPM2B_NAME_Unmarshal(&data->u1.boundEntity, buffer, size);
2802
54
    }
2803
54
    if (rc == TPM_RC_SUCCESS) {
2804
54
        rc = TPM2B_DIGEST_Unmarshal(&data->u2.auditDigest, buffer, size);
2805
54
    }
2806
2807
    /* version 2 starts having indicator for next versions that we can skip;
2808
       this allows us to downgrade state */
2809
54
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
2810
54
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
2811
54
                        "SESSION", "version 3 or later");
2812
        /* future versions nest-append here */
2813
0
    }
2814
2815
54
skip_future_versions:
2816
54
    return rc;
2817
54
}
2818
2819
54.3k
#define SESSION_SLOT_MAGIC 0x3664aebc
2820
54.3k
#define SESSION_SLOT_VERSION 2
2821
2822
static UINT16
2823
SESSION_SLOT_Marshal(SESSION_SLOT *data, BYTE **buffer, INT32* size)
2824
18.1k
{
2825
18.1k
    UINT16 written;
2826
18.1k
    BLOCK_SKIP_INIT;
2827
2828
18.1k
    written = NV_HEADER_Marshal(buffer, size,
2829
18.1k
                                SESSION_SLOT_VERSION,
2830
18.1k
                                SESSION_SLOT_MAGIC, 1);
2831
2832
18.1k
    written += BOOL_Marshal(&data->occupied, buffer, size);
2833
18.1k
    if (!data->occupied)
2834
18.0k
        return written;
2835
2836
27
    written += SESSION_Marshal(&data->session, buffer, size);
2837
2838
27
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
2839
    /* future versions append below this line */
2840
2841
27
    BLOCK_SKIP_WRITE_POP(size);
2842
2843
27
    BLOCK_SKIP_WRITE_CHECK;
2844
2845
27
    return written;
2846
27
}
2847
2848
static TPM_RC
2849
SESSION_SLOT_Unmarshal(SESSION_SLOT *data, BYTE **buffer, INT32 *size)
2850
36.2k
{
2851
36.2k
    TPM_RC rc = TPM_RC_SUCCESS;
2852
36.2k
    NV_HEADER hdr;
2853
2854
36.2k
    if (rc == TPM_RC_SUCCESS) {
2855
36.2k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
2856
36.2k
                                 SESSION_SLOT_VERSION, SESSION_SLOT_MAGIC);
2857
36.2k
    }
2858
36.2k
    if (rc == TPM_RC_SUCCESS) {
2859
36.2k
        rc = BOOL_Unmarshal(&data->occupied, buffer, size);
2860
36.2k
    }
2861
36.2k
    if (!data->occupied)
2862
36.1k
        return rc;
2863
2864
54
    if (rc == TPM_RC_SUCCESS) {
2865
54
        rc = SESSION_Unmarshal(&data->session, buffer, size);
2866
54
    }
2867
2868
    /* version 2 starts having indicator for next versions that we can skip;
2869
       this allows us to downgrade state */
2870
54
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
2871
54
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
2872
54
                        "SESSION_SLOT", "version 3 or later");
2873
        /* future versions nest-append here */
2874
0
    }
2875
2876
54
skip_future_versions:
2877
54
    return rc;
2878
54
}
2879
2880
18.1k
#define VOLATILE_STATE_VERSION 4
2881
36.2k
#define VOLATILE_STATE_MAGIC 0x45637889
2882
2883
UINT16
2884
VolatileState_Marshal(BYTE **buffer, INT32 *size, struct RuntimeProfile *RuntimeProfile)
2885
6.04k
{
2886
6.04k
    UINT16 written;
2887
6.04k
    size_t i;
2888
6.04k
    BOOL tpmEst;
2889
6.04k
    UINT64 tmp_uint64;
2890
6.04k
    UINT32 tmp_uint32;
2891
6.04k
    BOOL has_block;
2892
6.04k
    UINT16 array_size;
2893
6.04k
    BLOCK_SKIP_INIT;
2894
6.04k
    PERSISTENT_DATA pd;
2895
6.04k
    TPM2B_AUTH unused = {
2896
6.04k
        .b.size = 0,
2897
6.04k
    };
2898
6.04k
    BOOL inFailureMode;
2899
6.04k
    UINT32 failFunction, failLine, failCode;
2900
2901
6.04k
    written = NV_HEADER_Marshal(buffer, size,
2902
6.04k
                                VOLATILE_STATE_VERSION, VOLATILE_STATE_MAGIC,
2903
6.04k
                                1);
2904
2905
    /* skip g_rcIndex: these are 'constants' */
2906
6.04k
    written += TPM_HANDLE_Marshal(&g_exclusiveAuditSession, buffer, size); /* line 423 */
2907
    /* g_time: may not be necessary */
2908
6.04k
    written += UINT64_Marshal(&g_time, buffer, size); /* line 426 */
2909
    /* g_timeEpoch: skipped so far -- needs investigation */
2910
    /* g_phEnable: since we won't call TPM2_Starup, we need to write it */
2911
6.04k
    written += BOOL_Marshal(&g_phEnable, buffer, size); /* line 439 */
2912
    /* g_pcrReconfig: must write */
2913
6.04k
    written += BOOL_Marshal(&g_pcrReConfig, buffer, size); /* line 443 */
2914
    /* g_DRTMHandle: must write */
2915
6.04k
    written += TPM_HANDLE_Marshal(&g_DRTMHandle, buffer, size); /* line 448 */
2916
    /* g_DrtmPreStartup: must write */
2917
6.04k
    written += BOOL_Marshal(&g_DrtmPreStartup, buffer, size); /* line 453 */
2918
    /* g_StartupLocality3: must write */
2919
6.04k
    written += BOOL_Marshal(&g_StartupLocality3, buffer, size); /* line 458 */
2920
2921
6.04k
#if USE_DA_USED
2922
6.04k
    has_block = TRUE;
2923
#else
2924
# error Unsupport #define value(s)
2925
    has_block = FALSE;
2926
#endif
2927
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
2928
2929
6.04k
#if USE_DA_USED
2930
    /* g_daUsed: must write */
2931
6.04k
    written += BOOL_Marshal(&g_daUsed, buffer, size); /* line 484 */
2932
#else
2933
# error Unsupport #define value(s)
2934
#endif
2935
6.04k
    BLOCK_SKIP_WRITE_POP(size);
2936
2937
    /* g_updateNV: can skip since it seems to only be valid during execution of a command*/
2938
    /* g_powerWasLost: must write */
2939
6.04k
    written += BOOL_Marshal(&g_powerWasLost, buffer, size); /* line 504 */
2940
    /* g_clearOrderly: can skip since it seems to only be valid during execution of a command */
2941
    /* g_prevOrderlyState: must write */
2942
6.04k
    written += UINT16_Marshal(&g_prevOrderlyState, buffer, size); /* line 516 */
2943
    /* g_nvOk: must write */
2944
6.04k
    written += BOOL_Marshal(&g_nvOk, buffer, size); /* line 522 */
2945
    /* g_NvStatus: can skip since it seems to only be valid during execution of a command */
2946
2947
#if 0 /* does not exist */
2948
    written += TPM2B_AUTH_Marshal(&g_platformUniqueAuthorities, buffer, size); /* line 535 */
2949
#endif
2950
6.04k
    written += TPM2B_AUTH_Marshal(&unused, buffer, size); /* was g_platformUniqueDetails; unused since v0.10 */
2951
2952
    /* gp (persistent_data): skip; we assume its latest states in the persistent data file */
2953
2954
    /* we store the next 3 because they may not have been written to NVRAM */
2955
6.04k
    written += ORDERLY_DATA_Marshal(&go, buffer, size); /* line 707 */
2956
6.04k
    written += STATE_CLEAR_DATA_Marshal(&gc, buffer, size); /* line 738 */
2957
6.04k
    written += STATE_RESET_DATA_Marshal(&gr, buffer, size); /* line 826 */
2958
2959
    /* g_manufactured: must write */
2960
6.04k
    written += BOOL_Marshal(&g_manufactured, buffer, size); /* line 928 */
2961
    /* g_initialized: must write */
2962
6.04k
    written += BOOL_Marshal(&g_initialized, buffer, size); /* line 932 */
2963
2964
6.04k
#if defined SESSION_PROCESS_C || defined GLOBAL_C || defined MANUFACTURE_C
2965
6.04k
    has_block = TRUE;
2966
#else
2967
# error Unsupport #define value(s)
2968
    has_block = FALSE;
2969
#endif
2970
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
2971
2972
6.04k
#if defined SESSION_PROCESS_C || defined GLOBAL_C || defined MANUFACTURE_C
2973
    /*
2974
     * The session related variables may only be valid during the execution
2975
     * of a single command; safer to store
2976
     */
2977
6.04k
    array_size = ARRAY_SIZE(s_sessionHandles);
2978
6.04k
    written += UINT16_Marshal(&array_size, buffer, size);
2979
2980
24.1k
    for (i = 0; i < array_size; i++) {
2981
18.1k
        written += TPM_HANDLE_Marshal(&s_sessionHandles[i], buffer, size);
2982
18.1k
        written += TPMA_SESSION_Marshal(&s_attributes[i], buffer, size);
2983
18.1k
        written += TPM_HANDLE_Marshal(&s_associatedHandles[i], buffer, size);
2984
18.1k
        written += TPM2B_NONCE_Marshal(&s_nonceCaller[i], buffer, size);
2985
18.1k
        written += TPM2B_AUTH_Marshal(&s_inputAuthValues[i], buffer, size);
2986
        /* s_usedSessions: cannot serialize this since it is a pointer; also, isn't used */
2987
18.1k
    }
2988
6.04k
    written += TPM_HANDLE_Marshal(&s_encryptSessionIndex, buffer, size);
2989
6.04k
    written += TPM_HANDLE_Marshal(&s_decryptSessionIndex, buffer, size);
2990
6.04k
    written += TPM_HANDLE_Marshal(&s_auditSessionIndex, buffer, size);
2991
2992
6.04k
#if CC_GetCommandAuditDigest
2993
6.04k
    has_block = TRUE;
2994
#else
2995
# error Unsupport #define value(s)
2996
    has_block = FALSE;
2997
#endif
2998
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
2999
3000
6.04k
#if CC_GetCommandAuditDigest
3001
    /* s_cpHashForCommandAudit: seems not used; better to write it */
3002
6.04k
    written += TPM2B_DIGEST_Marshal(&s_cpHashForCommandAudit, buffer, size);
3003
#else
3004
# error Unsupport #define value(s)
3005
#endif
3006
6.04k
    BLOCK_SKIP_WRITE_POP(size);
3007
3008
    /* s_DAPendingOnNV: needs investigation ... */
3009
6.04k
    written += BOOL_Marshal(&s_DAPendingOnNV, buffer, size);
3010
6.04k
#endif // SESSION_PROCESS_C
3011
6.04k
    BLOCK_SKIP_WRITE_POP(size);
3012
3013
#if defined DA_C || defined GLOBAL_C_UNSUPPORTED || defined MANUFACTURE_C
3014
    has_block = TRUE;
3015
#error Unsupport #define value(s)
3016
#else
3017
6.04k
    has_block = FALSE;
3018
6.04k
#endif
3019
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
3020
3021
#if defined DA_C || defined GLOBAL_C_UNSUPPORTED || defined MANUFACTURE_C
3022
#error Unsupport #define value(s)
3023
#if !ACCUMULATE_SELF_HEAL_TIMER
3024
    has_block = TRUE;
3025
#else
3026
    has_block = FALSE;
3027
#endif
3028
    written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
3029
3030
#if !ACCUMULATE_SELF_HEAL_TIMER
3031
    written += UINT64_Marshal(&s_selfHealTimer, buffer, size); /* line 975 */
3032
    written += UINT64_Marshal(&s_lockoutTimer, buffer, size); /* line 977 */
3033
#endif // ACCUMULATE_SELF_HEAL_TIMER
3034
    BLOCK_SKIP_WRITE_POP(size);
3035
#endif // DA_C
3036
6.04k
    BLOCK_SKIP_WRITE_POP(size);
3037
3038
6.04k
#if defined NV_C || defined GLOBAL_C
3039
6.04k
    has_block = TRUE;
3040
#else
3041
# error Unsupport #define value(s)
3042
    has_block = FALSE;
3043
#endif
3044
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
3045
    /* s_evictNvEnd set in NvInitStatic called by NvPowerOn in case g_powerWasLost
3046
     * Unless we set g_powerWasLost=TRUE and call NvPowerOn, we have to include it.
3047
     */
3048
6.04k
#if defined NV_C || defined GLOBAL_C
3049
6.04k
    written += UINT32_Marshal(&s_evictNvEnd, buffer, size); /* line 984 */
3050
    /* s_indexOrderlyRam read from NVRAM in NvEntityStartup and written to it
3051
     * in NvUpdateIndexOrderlyData called by TPM2_Shutdown and initialized
3052
     * in NvManufacture -- since we don't call TPM2_Shutdown we serialize it here
3053
     */
3054
6.04k
    array_size = sizeof(s_indexOrderlyRam);
3055
6.04k
    written += UINT16_Marshal(&array_size, buffer, size);
3056
6.04k
    written += Array_Marshal(s_indexOrderlyRam, array_size, buffer, size);
3057
3058
6.04k
    written += UINT64_Marshal(&s_maxCounter, buffer, size); /* line 992 */
3059
    /* the following need not be written; NvIndexCacheInit initializes them partly
3060
     * and NvIndexCacheInit() is called during ExecuteCommand()
3061
     * - s_cachedNvIndex
3062
     * - s_cachedNvRef
3063
     * - s_cachedNvRamRef
3064
     */
3065
#else
3066
# error Unsupport #define value(s)
3067
#endif
3068
6.04k
    BLOCK_SKIP_WRITE_POP(size);
3069
3070
6.04k
#if defined OBJECT_C || defined GLOBAL_C
3071
6.04k
    has_block = TRUE;
3072
#else
3073
# error Unsupport #define value(s)
3074
    has_block = FALSE;
3075
#endif
3076
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
3077
3078
6.04k
#if defined OBJECT_C || defined GLOBAL_C
3079
    /* used in many places; it doesn't look like TPM2_Shutdown writes this into
3080
     * persistent memory, so what is lost upon TPM2_Shutdown?
3081
     */
3082
6.04k
    array_size = ARRAY_SIZE(s_objects);
3083
6.04k
    written += UINT16_Marshal(&array_size, buffer, size);
3084
3085
24.1k
    for (i = 0; i < array_size; i++) {
3086
18.1k
        written += ANY_OBJECT_Marshal(&s_objects[i], buffer, size, RuntimeProfile);
3087
18.1k
    }
3088
#else
3089
# error Unsupport #define value(s)
3090
#endif
3091
6.04k
    BLOCK_SKIP_WRITE_POP(size);
3092
3093
6.04k
#if defined PCR_C || defined GLOBAL_C
3094
6.04k
    has_block = TRUE;
3095
#else
3096
# error Unsupport #define value(s)
3097
    has_block = FALSE;
3098
#endif
3099
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
3100
3101
6.04k
#if defined PCR_C || defined GLOBAL_C
3102
    /* s_pcrs: Marshal *all* PCRs, even those for which stateSave bit is not set */
3103
6.04k
    array_size = ARRAY_SIZE(s_pcrs);
3104
6.04k
    written += UINT16_Marshal(&array_size, buffer, size);
3105
3106
151k
    for (i = 0; i < array_size; i++) {
3107
144k
        written += PCR_Marshal(&s_pcrs[i], buffer, size);
3108
144k
    }
3109
#else
3110
# error Unsupport #define value(s)
3111
#endif
3112
6.04k
    BLOCK_SKIP_WRITE_POP(size);
3113
3114
6.04k
#if defined SESSION_C || defined GLOBAL_C
3115
6.04k
    has_block = TRUE;
3116
#else
3117
# error Unsupport #define value(s)
3118
    has_block = FALSE;
3119
#endif
3120
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
3121
3122
6.04k
#if defined SESSION_C || defined GLOBAL_C
3123
    /* s_sessions: */
3124
6.04k
    array_size = ARRAY_SIZE(s_sessions);
3125
6.04k
    written += UINT16_Marshal(&array_size, buffer, size);
3126
3127
24.1k
    for (i = 0; i < array_size; i++) {
3128
18.1k
        written += SESSION_SLOT_Marshal(&s_sessions[i], buffer, size);
3129
18.1k
    }
3130
    /* s_oldestSavedSession: */
3131
6.04k
    written += UINT32_Marshal(&s_oldestSavedSession, buffer, size);
3132
    /* s_freeSessionSlots: */
3133
6.04k
    written += UINT32_Marshal((UINT32 *)&s_freeSessionSlots, buffer, size);
3134
#else
3135
# error Unsupport #define value(s)
3136
#endif
3137
6.04k
    BLOCK_SKIP_WRITE_POP(size);
3138
3139
#if defined IO_BUFFER_C || defined GLOBAL_C_UNSUPPORTED
3140
# error Unsupport #define value(s)
3141
    /* s_actionInputBuffer: skip; only used during a single command */
3142
    /* s_actionOutputBuffer: skip; only used during a single command */
3143
#endif
3144
6.04k
    inFailureMode = _plat__InFailureMode();
3145
6.04k
    written += BOOL_Marshal(&inFailureMode, buffer, size); /* line 1078 */
3146
3147
    /* TPM established bit */
3148
6.04k
    tpmEst = _rpc__Signal_GetTPMEstablished();
3149
6.04k
    written += BOOL_Marshal(&tpmEst, buffer, size);
3150
3151
6.04k
#if defined TPM_FAIL_C || defined GLOBAL_C || 1
3152
6.04k
    has_block = TRUE;
3153
#else
3154
# error Unsupport #define value(s)
3155
    has_block = FALSE;
3156
#endif
3157
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
3158
3159
6.04k
#if defined TPM_FAIL_C || defined GLOBAL_C || 1
3160
6.04k
    failFunction = _plat__GetFailureLocation();
3161
6.04k
    written += UINT32_Marshal(&failFunction, buffer, size);
3162
6.04k
    failLine = _plat__GetFailureLine();
3163
6.04k
    written += UINT32_Marshal(&failLine, buffer, size);
3164
6.04k
    failCode = _plat__GetFailureCode();
3165
6.04k
    written += UINT32_Marshal(&failCode, buffer, size);
3166
#else
3167
# error Unsupport #define value(s)
3168
#endif // TPM_FAIL_C
3169
6.04k
    BLOCK_SKIP_WRITE_POP(size);
3170
3171
6.04k
#ifndef HARDWARE_CLOCK
3172
6.04k
    has_block = TRUE;
3173
#else
3174
    has_block = FALSE;
3175
# error Unsupport #define value(s)
3176
#endif
3177
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
3178
3179
6.04k
#ifndef HARDWARE_CLOCK
3180
6.04k
    tmp_uint64 = s_realTimePrevious;
3181
6.04k
    written += UINT64_Marshal(&tmp_uint64, buffer, size);
3182
6.04k
    tmp_uint64 = s_tpmTime;
3183
6.04k
    written += UINT64_Marshal(&tmp_uint64, buffer, size);
3184
#else
3185
# error Unsupport #define value(s)
3186
#endif
3187
6.04k
    BLOCK_SKIP_WRITE_POP(size);
3188
3189
6.04k
    written += BOOL_Marshal(&s_timerReset, buffer, size);
3190
6.04k
    written += BOOL_Marshal(&s_timerStopped, buffer, size);
3191
6.04k
    written += UINT32_Marshal(&s_adjustRate, buffer, size);
3192
3193
6.04k
    tmp_uint64 = ClockGetTime(CLOCK_REALTIME);
3194
6.04k
    written += UINT64_Marshal(&tmp_uint64, buffer, size);
3195
3196
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size); /* v3 */
3197
3198
    /* tie the volatile state to the EP,SP, and PPSeed */
3199
6.04k
    NvRead(&pd, NV_PERSISTENT_DATA, sizeof(pd));
3200
6.04k
    written += TPM2B_Marshal(&pd.EPSeed.b, sizeof(pd.EPSeed.t.buffer), buffer, size);
3201
6.04k
    written += TPM2B_Marshal(&pd.SPSeed.b, sizeof(pd.SPSeed.t.buffer), buffer, size);
3202
6.04k
    written += TPM2B_Marshal(&pd.PPSeed.b, sizeof(pd.PPSeed.t.buffer), buffer, size);
3203
3204
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size); /* v4 */
3205
3206
6.04k
    tmp_uint64 = ClockGetTime(CLOCK_MONOTONIC) + s_hostMonotonicAdjustTime;
3207
6.04k
    written += UINT64_Marshal(&tmp_uint64, buffer, size);
3208
3209
6.04k
    written += UINT64_Marshal(&s_suspendedElapsedTime, buffer, size);
3210
6.04k
    written += UINT64_Marshal(&s_lastSystemTime, buffer, size);
3211
6.04k
    written += UINT64_Marshal(&s_lastReportedTime, buffer, size);
3212
3213
6.04k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size); /* v5 */
3214
    /* future versions append below this line */
3215
3216
6.04k
    BLOCK_SKIP_WRITE_POP(size); /* v5 */
3217
6.04k
    BLOCK_SKIP_WRITE_POP(size); /* v4 */
3218
6.04k
    BLOCK_SKIP_WRITE_POP(size); /* v3 */
3219
3220
    /* keep marker at end */
3221
6.04k
    tmp_uint32 = VOLATILE_STATE_MAGIC;
3222
6.04k
    written += UINT32_Marshal(&tmp_uint32, buffer, size);
3223
3224
6.04k
    BLOCK_SKIP_WRITE_CHECK;
3225
3226
6.04k
    return written;
3227
6.04k
}
3228
3229
static TPM_RC
3230
VolatileState_TailV4_Unmarshal(BYTE **buffer, INT32 *size)
3231
12.0k
{
3232
12.0k
    TPM_RC rc = TPM_RC_SUCCESS;
3233
12.0k
    UINT64 tmp_uint64;
3234
3235
12.0k
    if (rc == TPM_RC_SUCCESS) {
3236
12.0k
        rc = UINT64_Unmarshal(&tmp_uint64, buffer, size);
3237
12.0k
        s_hostMonotonicAdjustTime = tmp_uint64 - ClockGetTime(CLOCK_MONOTONIC);
3238
12.0k
    }
3239
12.0k
    if (rc == TPM_RC_SUCCESS) {
3240
12.0k
        rc = UINT64_Unmarshal(&s_suspendedElapsedTime, buffer, size);
3241
12.0k
    }
3242
12.0k
    if (rc == TPM_RC_SUCCESS) {
3243
12.0k
        rc = UINT64_Unmarshal(&s_lastSystemTime, buffer, size);
3244
12.0k
    }
3245
12.0k
    if (rc == TPM_RC_SUCCESS) {
3246
12.0k
        rc = UINT64_Unmarshal(&s_lastReportedTime, buffer, size);
3247
12.0k
    }
3248
3249
12.0k
    return rc;
3250
12.0k
}
3251
3252
static TPM_RC
3253
VolatileState_TailV3_Unmarshal(BYTE **buffer, INT32 *size)
3254
12.0k
{
3255
12.0k
    TPM_RC rc = TPM_RC_SUCCESS;
3256
12.0k
    PERSISTENT_DATA pd;
3257
12.0k
    TPM2B_SEED seed = {
3258
12.0k
        .b.size = 0,
3259
12.0k
    };
3260
3261
12.0k
    NvRead(&pd, NV_PERSISTENT_DATA, sizeof(pd));
3262
3263
12.0k
    if (rc == TPM_RC_SUCCESS) {
3264
12.0k
        rc = TPM2B_Unmarshal(&seed.b, PRIMARY_SEED_SIZE, buffer, size);
3265
12.0k
    }
3266
12.0k
    if (rc == TPM_RC_SUCCESS) {
3267
12.0k
        if (seed.b.size > PRIMARY_SEED_SIZE) /* coverity */
3268
0
            rc = TPM_RC_SIZE;
3269
12.0k
    }
3270
12.0k
    if (rc == TPM_RC_SUCCESS) {
3271
12.0k
        if (TPM2B_Cmp(&seed.b, &pd.EPSeed.b)) {
3272
0
            TPMLIB_LogTPM2Error("%s: EPSeed does not match\n",
3273
0
                                __func__);
3274
0
            rc = TPM_RC_VALUE;
3275
0
        }
3276
12.0k
    }
3277
12.0k
    if (rc == TPM_RC_SUCCESS) {
3278
12.0k
        rc = TPM2B_Unmarshal(&seed.b, PRIMARY_SEED_SIZE, buffer, size);
3279
12.0k
    }
3280
12.0k
    if (rc == TPM_RC_SUCCESS) {
3281
12.0k
        if (seed.b.size > PRIMARY_SEED_SIZE) /* coverity */
3282
0
            rc = TPM_RC_SIZE;
3283
12.0k
    }
3284
12.0k
    if (rc == TPM_RC_SUCCESS) {
3285
12.0k
        if (TPM2B_Cmp(&seed.b, &pd.SPSeed.b)) {
3286
0
            TPMLIB_LogTPM2Error("%s: SPSeed does not match\n",
3287
0
                                __func__);
3288
0
            rc = TPM_RC_VALUE;
3289
0
        }
3290
12.0k
    }
3291
12.0k
    if (rc == TPM_RC_SUCCESS) {
3292
12.0k
        rc = TPM2B_Unmarshal(&seed.b, PRIMARY_SEED_SIZE, buffer, size);
3293
12.0k
    }
3294
12.0k
    if (rc == TPM_RC_SUCCESS) {
3295
12.0k
        if (seed.b.size > PRIMARY_SEED_SIZE) /* coverity */
3296
0
            rc = TPM_RC_SIZE;
3297
12.0k
    }
3298
12.0k
    if (rc == TPM_RC_SUCCESS) {
3299
12.0k
        if (TPM2B_Cmp(&seed.b, &pd.PPSeed.b)) {
3300
0
            TPMLIB_LogTPM2Error("%s: PPSeed does not match\n",
3301
0
                                __func__);
3302
0
            rc = TPM_RC_VALUE;
3303
0
        }
3304
12.0k
    }
3305
3306
12.0k
    return rc;
3307
12.0k
}
3308
3309
TPM_RC
3310
VolatileState_Unmarshal(BYTE **buffer, INT32 *size)
3311
12.0k
{
3312
12.0k
    TPM_RC rc = TPM_RC_SUCCESS;
3313
12.0k
    size_t i;
3314
12.0k
    UINT64 tmp_uint64;
3315
12.0k
    UINT32 tmp_uint32;
3316
12.0k
    NV_HEADER hdr;
3317
12.0k
    BOOL needs_block;
3318
12.0k
    UINT16 array_size = 0;
3319
12.0k
    UINT64 backthen;
3320
12.0k
    TPM2B_AUTH unused = {
3321
12.0k
        .b.size = 0,
3322
12.0k
    };
3323
12.0k
    UINT32 failFunction, failLine, failCode;
3324
3325
12.0k
    if (rc == TPM_RC_SUCCESS) {
3326
12.0k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
3327
12.0k
                                 VOLATILE_STATE_VERSION, VOLATILE_STATE_MAGIC);
3328
12.0k
    }
3329
12.0k
    if (rc == TPM_RC_SUCCESS) {
3330
12.0k
        rc = TPM_HANDLE_Unmarshal(&g_exclusiveAuditSession, buffer, size); /* line 423 */
3331
12.0k
    }
3332
12.0k
    if (rc == TPM_RC_SUCCESS) {
3333
12.0k
        rc = UINT64_Unmarshal(&g_time, buffer, size); /* line 426 */
3334
12.0k
    }
3335
12.0k
    if (rc == TPM_RC_SUCCESS) {
3336
12.0k
        rc = BOOL_Unmarshal(&g_phEnable, buffer, size); /* line 439 */
3337
12.0k
    }
3338
12.0k
    if (rc == TPM_RC_SUCCESS) {
3339
12.0k
        rc = BOOL_Unmarshal(&g_pcrReConfig, buffer, size); /* line 443 */
3340
12.0k
    }
3341
12.0k
    if (rc == TPM_RC_SUCCESS) {
3342
12.0k
        rc = TPM_HANDLE_Unmarshal(&g_DRTMHandle, buffer, size); /* line 448 */
3343
12.0k
    }
3344
12.0k
    if (rc == TPM_RC_SUCCESS) {
3345
12.0k
        rc = BOOL_Unmarshal(&g_DrtmPreStartup, buffer, size); /* line 453 */
3346
12.0k
    }
3347
12.0k
    if (rc == TPM_RC_SUCCESS) {
3348
12.0k
        rc = BOOL_Unmarshal(&g_StartupLocality3, buffer, size); /* line 458 */
3349
12.0k
    }
3350
3351
12.0k
#if USE_DA_USED
3352
12.0k
    needs_block = TRUE;
3353
#else
3354
# error Unsupport #define value(s)
3355
    needs_block = FALSE;
3356
#endif
3357
12.0k
    if (rc == TPM_RC_SUCCESS) {
3358
12.0k
        BLOCK_SKIP_READ(skip_da, needs_block, buffer, size,
3359
12.0k
                        "Volatile state", "g_daUsed");
3360
12.0k
    }
3361
12.0k
#if USE_DA_USED
3362
12.0k
    if (rc == TPM_RC_SUCCESS) {
3363
12.0k
        rc = BOOL_Unmarshal(&g_daUsed, buffer, size); /* line 484 */
3364
12.0k
    }
3365
#else
3366
# error Unsupport #define value(s)
3367
#endif
3368
12.0k
skip_da:
3369
3370
12.0k
    if (rc == TPM_RC_SUCCESS) {
3371
12.0k
        rc = BOOL_Unmarshal(&g_powerWasLost, buffer, size); /* line 504 */
3372
12.0k
    }
3373
12.0k
    if (rc == TPM_RC_SUCCESS) {
3374
12.0k
        rc = UINT16_Unmarshal(&g_prevOrderlyState, buffer, size); /* line 516 */
3375
12.0k
    }
3376
12.0k
    if (rc == TPM_RC_SUCCESS) {
3377
12.0k
        rc = BOOL_Unmarshal(&g_nvOk, buffer, size); /* line 522 */
3378
12.0k
    }
3379
#if 0 /* does not exist */
3380
    if (rc == TPM_RC_SUCCESS) {
3381
        rc = TPM2B_AUTH_Unmarshal(&g_platformUniqueAuthorities, buffer, size); /* line 535 */
3382
    }
3383
#endif
3384
12.0k
    if (rc == TPM_RC_SUCCESS) {
3385
12.0k
        rc = TPM2B_AUTH_Unmarshal(&unused, buffer, size); /* was g_platformUniqueDetails; unused since v0.10 */
3386
12.0k
    }
3387
3388
12.0k
    if (rc == TPM_RC_SUCCESS) {
3389
12.0k
        rc = ORDERLY_DATA_Unmarshal(&go, buffer, size);
3390
12.0k
    }
3391
12.0k
    if (rc == TPM_RC_SUCCESS) {
3392
12.0k
        rc = STATE_CLEAR_DATA_Unmarshal(&gc, buffer, size);
3393
12.0k
    }
3394
12.0k
    if (rc == TPM_RC_SUCCESS) {
3395
12.0k
       rc = STATE_RESET_DATA_Unmarshal(&gr, buffer, size);
3396
12.0k
    }
3397
3398
12.0k
    if (rc == TPM_RC_SUCCESS) {
3399
12.0k
        rc = BOOL_Unmarshal(&g_manufactured, buffer, size); /* line 928 */
3400
12.0k
    }
3401
12.0k
    if (rc == TPM_RC_SUCCESS) {
3402
12.0k
        rc = BOOL_Unmarshal(&g_initialized, buffer, size); /* line 932 */
3403
12.0k
    }
3404
3405
12.0k
#if defined SESSION_PROCESS_C || defined GLOBAL_C || defined MANUFACTURE_C
3406
12.0k
    needs_block = TRUE;
3407
#else
3408
# error Unsupport #define value(s)
3409
    needs_block = FALSE;
3410
#endif
3411
12.0k
    if (rc == TPM_RC_SUCCESS) {
3412
12.0k
        BLOCK_SKIP_READ(skip_session_process, needs_block, buffer, size,
3413
12.0k
                        "Volatile state", "s_sessionHandles");
3414
12.0k
    }
3415
12.0k
#if defined SESSION_PROCESS_C || defined GLOBAL_C || defined MANUFACTURE_C
3416
12.0k
    if (rc == TPM_RC_SUCCESS) {
3417
12.0k
        rc = UINT16_Unmarshal(&array_size, buffer, size);
3418
12.0k
    }
3419
12.0k
    if (rc == TPM_RC_SUCCESS &&
3420
12.0k
        array_size != ARRAY_SIZE(s_sessionHandles)) {
3421
0
        TPMLIB_LogTPM2Error("Volatile state: Bad array size for s_sessionHandles; "
3422
0
                            "expected %zu, got %u\n",
3423
0
                            ARRAY_SIZE(s_sessionHandles), array_size);
3424
0
        rc = TPM_RC_BAD_PARAMETER;
3425
0
    }
3426
48.3k
    for (i = 0; i < array_size && rc == TPM_RC_SUCCESS; i++) {
3427
36.2k
        if (rc == TPM_RC_SUCCESS) {
3428
36.2k
            rc = TPM_HANDLE_Unmarshal(&s_sessionHandles[i], buffer, size);
3429
36.2k
        }
3430
36.2k
        if (rc == TPM_RC_SUCCESS) {
3431
36.2k
            rc = TPMA_SESSION_Unmarshal(&s_attributes[i], buffer, size);
3432
36.2k
        }
3433
36.2k
        if (rc == TPM_RC_SUCCESS) {
3434
36.2k
            rc = TPM_HANDLE_Unmarshal(&s_associatedHandles[i], buffer, size);
3435
36.2k
        }
3436
36.2k
        if (rc == TPM_RC_SUCCESS) {
3437
36.2k
            rc = TPM2B_NONCE_Unmarshal(&s_nonceCaller[i], buffer, size);
3438
36.2k
        }
3439
36.2k
        if (rc == TPM_RC_SUCCESS) {
3440
36.2k
            rc = TPM2B_AUTH_Unmarshal(&s_inputAuthValues[i], buffer, size);
3441
36.2k
        }
3442
36.2k
    }
3443
3444
12.0k
    if (rc == TPM_RC_SUCCESS) {
3445
12.0k
        rc = TPM_HANDLE_Unmarshal(&s_encryptSessionIndex, buffer, size);
3446
12.0k
    }
3447
12.0k
    if (rc == TPM_RC_SUCCESS) {
3448
12.0k
        rc = TPM_HANDLE_Unmarshal(&s_decryptSessionIndex, buffer, size);
3449
12.0k
    }
3450
12.0k
    if (rc == TPM_RC_SUCCESS) {
3451
12.0k
        rc = TPM_HANDLE_Unmarshal(&s_auditSessionIndex, buffer, size);
3452
12.0k
    }
3453
3454
12.0k
#if CC_GetCommandAuditDigest
3455
12.0k
    needs_block = TRUE;
3456
#else
3457
# error Unsupport #define value(s)
3458
    needs_block = FALSE;
3459
#endif
3460
12.0k
    if (rc == TPM_RC_SUCCESS) {
3461
12.0k
        BLOCK_SKIP_READ(skip_cc_getcommandauditdigest, needs_block, buffer, size,
3462
12.0k
                        "Volatile state", "s_cpHashForCommandAudit");
3463
12.0k
    }
3464
12.0k
#if CC_GetCommandAuditDigest
3465
12.0k
    if (rc == TPM_RC_SUCCESS) {
3466
12.0k
        rc = TPM2B_DIGEST_Unmarshal(&s_cpHashForCommandAudit, buffer, size);
3467
12.0k
    }
3468
12.0k
#endif
3469
12.0k
skip_cc_getcommandauditdigest:
3470
3471
12.0k
    if (rc == TPM_RC_SUCCESS) {
3472
12.0k
        rc = BOOL_Unmarshal(&s_DAPendingOnNV, buffer, size);
3473
12.0k
    }
3474
#else
3475
# error Unsupport #define value(s)
3476
#endif /* SESSION_PROCESS_C */
3477
12.0k
skip_session_process:
3478
3479
#if defined DA_C || defined GLOBAL_C_UNSUPPORTED || defined MANUFACTURE_C
3480
# error Unsupport #define value(s)
3481
    needs_block = TRUE;
3482
#else
3483
12.0k
    needs_block = FALSE;
3484
12.0k
#endif
3485
12.0k
    if (rc == TPM_RC_SUCCESS) {
3486
12.0k
        BLOCK_SKIP_READ(skip_accumulate_self_heal_timer_1, needs_block, buffer, size,
3487
12.0k
                        "Volatile state", "s_selfHealTimer.1");
3488
0
    }
3489
3490
#if defined DA_C || defined GLOBAL_C_UNSUPPORTED || defined MANUFACTURE_C
3491
# error Unsupport #define value(s)
3492
#if !ACCUMULATE_SELF_HEAL_TIMER
3493
    needs_block = TRUE;
3494
#else
3495
    needs_block = FALSE;
3496
#endif
3497
    if (rc == TPM_RC_SUCCESS) {
3498
        BLOCK_SKIP_READ(skip_accumulate_self_heal_timer_2, needs_block, buffer, size,
3499
                        "Volatile state", "s_selfHealTimer.2");
3500
    }
3501
#if !ACCUMULATE_SELF_HEAL_TIMER
3502
    if (rc == TPM_RC_SUCCESS) {
3503
        rc = UINT64_Unmarshal(&s_selfHealTimer, buffer, size); /* line 975 */
3504
    }
3505
    if (rc == TPM_RC_SUCCESS) {
3506
        rc = UINT64_Unmarshal(&s_lockoutTimer, buffer, size); /* line 977 */
3507
    }
3508
#endif
3509
skip_accumulate_self_heal_timer_2:
3510
#endif
3511
12.0k
skip_accumulate_self_heal_timer_1:
3512
3513
12.0k
#if defined NV_C || defined GLOBAL_C
3514
12.0k
    needs_block = TRUE;
3515
#else
3516
# error Unsupport #define value(s)
3517
    needs_block = FALSE;
3518
#endif
3519
12.0k
    if (rc == TPM_RC_SUCCESS) {
3520
12.0k
        BLOCK_SKIP_READ(skip_nv, needs_block, buffer, size,
3521
12.0k
                        "Volatile state", "s_evictNvEnd");
3522
12.0k
    }
3523
3524
12.0k
#if defined NV_C || defined GLOBAL_C
3525
12.0k
    if (rc == TPM_RC_SUCCESS) {
3526
12.0k
        rc = UINT32_Unmarshal(&s_evictNvEnd, buffer, size); /* line 984 */
3527
12.0k
    }
3528
3529
12.0k
    if (rc == TPM_RC_SUCCESS) {
3530
12.0k
        rc = UINT16_Unmarshal(&array_size, buffer, size);
3531
12.0k
    }
3532
12.0k
    if (rc == TPM_RC_SUCCESS &&
3533
12.0k
        array_size != ARRAY_SIZE(s_indexOrderlyRam)) {
3534
0
        TPMLIB_LogTPM2Error("Volatile state: Bad array size for s_indexOrderlyRam; "
3535
0
                            "expected %zu, got %u\n",
3536
0
                            ARRAY_SIZE(s_indexOrderlyRam), array_size);
3537
0
        rc = TPM_RC_BAD_PARAMETER;
3538
0
    }
3539
12.0k
    if (rc == TPM_RC_SUCCESS) {
3540
12.0k
        rc = Array_Unmarshal(s_indexOrderlyRam, array_size, buffer, size);
3541
12.0k
    }
3542
12.0k
    if (rc == TPM_RC_SUCCESS) {
3543
12.0k
        rc = UINT64_Unmarshal(&s_maxCounter, buffer, size); /* line 992 */
3544
12.0k
    }
3545
    /* The following are not included:
3546
     * - s_cachedNvIndex
3547
     * - s_cachedNvRef
3548
     * - s_cachedNvRamRef
3549
     */
3550
#else
3551
# error Unsupport #define value(s)
3552
#endif
3553
12.0k
skip_nv:
3554
3555
12.0k
#if defined OBJECT_C || defined GLOBAL_C
3556
12.0k
    needs_block = TRUE;
3557
#else
3558
# error Unsupport #define value(s)
3559
    needs_block = FALSE;
3560
#endif
3561
12.0k
    if (rc == TPM_RC_SUCCESS) {
3562
12.0k
        BLOCK_SKIP_READ(skip_object, needs_block, buffer, size,
3563
12.0k
                        "Volatile state", "s_objects");
3564
12.0k
    }
3565
12.0k
#if defined OBJECT_C || defined GLOBAL_C
3566
12.0k
    if (rc == TPM_RC_SUCCESS) {
3567
12.0k
        rc = UINT16_Unmarshal(&array_size, buffer, size);
3568
12.0k
    }
3569
12.0k
    if (rc == TPM_RC_SUCCESS &&
3570
12.0k
        array_size != ARRAY_SIZE(s_objects)) {
3571
0
        TPMLIB_LogTPM2Error("Volatile state: Bad array size for s_objects; "
3572
0
                            "expected %zu, got %u\n",
3573
0
                            ARRAY_SIZE(s_objects), array_size);
3574
0
        rc = TPM_RC_BAD_PARAMETER;
3575
0
    }
3576
48.3k
    for (i = 0; i < array_size && rc == TPM_RC_SUCCESS; i++) {
3577
36.2k
        rc = ANY_OBJECT_Unmarshal(&s_objects[i], buffer, size, true);
3578
36.2k
    }
3579
#else
3580
# error Unsupport #define value(s)
3581
#endif
3582
12.0k
skip_object:
3583
3584
12.0k
#if defined PCR_C || defined GLOBAL_C
3585
12.0k
    needs_block = TRUE;
3586
#else
3587
# error Unsupport #define value(s)
3588
    needs_block = FALSE;
3589
#endif
3590
12.0k
    if (rc == TPM_RC_SUCCESS) {
3591
12.0k
        BLOCK_SKIP_READ(skip_pcr, needs_block, buffer, size,
3592
12.0k
                        "Volatile state", "s_pcrs");
3593
12.0k
    }
3594
12.0k
#if defined PCR_C || defined GLOBAL_C
3595
12.0k
    if (rc == TPM_RC_SUCCESS) {
3596
12.0k
        rc = UINT16_Unmarshal(&array_size, buffer, size);
3597
12.0k
    }
3598
12.0k
    if (rc == TPM_RC_SUCCESS &&
3599
12.0k
        array_size != ARRAY_SIZE(s_pcrs)) {
3600
0
        TPMLIB_LogTPM2Error("Volatile state: Bad array size for s_pcrs; "
3601
0
                            "expected %zu, got %u\n",
3602
0
                            ARRAY_SIZE(s_pcrs), array_size);
3603
0
        rc = TPM_RC_BAD_PARAMETER;
3604
0
    }
3605
302k
    for (i = 0; i < array_size && rc == TPM_RC_SUCCESS; i++) {
3606
289k
        rc = PCR_Unmarshal(&s_pcrs[i], buffer, size, &shadow.pcrAllocated);
3607
289k
    }
3608
#else
3609
# error Unsupport #define value(s)
3610
#endif
3611
12.0k
skip_pcr:
3612
3613
12.0k
#if defined SESSION_C || defined GLOBAL_C
3614
12.0k
    needs_block = TRUE;
3615
#else
3616
# error Unsupport #define value(s)
3617
    needs_block = FALSE;
3618
#endif
3619
12.0k
    if (rc == TPM_RC_SUCCESS) {
3620
12.0k
        BLOCK_SKIP_READ(skip_session, needs_block, buffer, size,
3621
12.0k
                        "Volatile state", "s_sessions");
3622
12.0k
    }
3623
12.0k
#if defined SESSION_C || defined GLOBAL_C
3624
12.0k
    if (rc == TPM_RC_SUCCESS) {
3625
12.0k
        rc = UINT16_Unmarshal(&array_size, buffer, size);
3626
12.0k
    }
3627
12.0k
    if (rc == TPM_RC_SUCCESS &&
3628
12.0k
        array_size != ARRAY_SIZE(s_sessions)) {
3629
0
        TPMLIB_LogTPM2Error("Volatile state: Bad array size for s_sessions; "
3630
0
                            "expected %zu, got %u\n",
3631
0
                            ARRAY_SIZE(s_sessions), array_size);
3632
0
        rc = TPM_RC_BAD_PARAMETER;
3633
0
    }
3634
    /* s_sessions: */
3635
48.3k
    for (i = 0; i < array_size && rc == TPM_RC_SUCCESS; i++) {
3636
36.2k
        rc = SESSION_SLOT_Unmarshal(&s_sessions[i], buffer, size);
3637
36.2k
    }
3638
    /* s_oldestSavedSession: */
3639
12.0k
    if (rc == TPM_RC_SUCCESS) {
3640
12.0k
        rc = UINT32_Unmarshal(&s_oldestSavedSession, buffer, size);
3641
12.0k
    }
3642
    /* s_freeSessionSlots: */
3643
12.0k
    if (rc == TPM_RC_SUCCESS) {
3644
12.0k
        rc = UINT32_Unmarshal((UINT32 *)&s_freeSessionSlots, buffer, size);
3645
12.0k
    }
3646
#else
3647
# error Unsupport #define value(s)
3648
#endif
3649
12.0k
skip_session:
3650
3651
12.0k
    if (rc == TPM_RC_SUCCESS) {
3652
12.0k
        BOOL inFailureMode = FALSE;
3653
12.0k
        rc = BOOL_Unmarshal(&inFailureMode, buffer, size); /* line 1078 */
3654
12.0k
        _plat__SetInFailureMode(inFailureMode);
3655
12.0k
    }
3656
3657
    /* TPM established bit */
3658
12.0k
    if (rc == TPM_RC_SUCCESS) {
3659
12.0k
        BOOL tpmEst;
3660
12.0k
        rc = BOOL_Unmarshal(&tpmEst, buffer, size);
3661
12.0k
        if (rc == TPM_RC_SUCCESS) {
3662
12.0k
            if (tpmEst)
3663
0
                _rpc__Signal_SetTPMEstablished();
3664
12.0k
            else
3665
12.0k
                _rpc__Signal_ResetTPMEstablished();
3666
12.0k
        }
3667
12.0k
    }
3668
3669
12.0k
#if defined TPM_FAIL_C || defined GLOBAL_C || 1
3670
12.0k
    needs_block = TRUE;
3671
#else
3672
# error Unsupport #define value(s)
3673
    needs_block = FALSE;
3674
#endif
3675
12.0k
    if (rc == TPM_RC_SUCCESS) {
3676
12.0k
        BLOCK_SKIP_READ(skip_fail, needs_block, buffer, size,
3677
12.0k
                        "Volatile state", "s_failFunction");
3678
12.0k
    }
3679
3680
12.0k
#if defined TPM_FAIL_C || defined GLOBAL_C || 1
3681
    /* appended in v2 */
3682
12.0k
    if (rc == TPM_RC_SUCCESS) {
3683
12.0k
        rc = UINT32_Unmarshal(&failFunction, buffer, size);
3684
12.0k
    }
3685
12.0k
    if (rc == TPM_RC_SUCCESS) {
3686
12.0k
        rc = UINT32_Unmarshal(&failLine, buffer, size);
3687
12.0k
    }
3688
12.0k
    if (rc == TPM_RC_SUCCESS) {
3689
12.0k
        rc = UINT32_Unmarshal(&failCode, buffer, size);
3690
12.0k
    }
3691
12.0k
    if (rc == TPM_RC_SUCCESS) {
3692
12.0k
        _plat__SetFailureModeParameters(NULL, failLine, failCode);
3693
12.0k
    }
3694
#else
3695
# error Unsupport #define value(s)
3696
#endif
3697
12.0k
skip_fail:
3698
3699
12.0k
#ifndef HARDWARE_CLOCK
3700
12.0k
    needs_block = TRUE;
3701
#else
3702
# error Unsupport #define value(s)
3703
    needs_block = FALSE;
3704
#endif
3705
12.0k
    if (rc == TPM_RC_SUCCESS) {
3706
12.0k
        BLOCK_SKIP_READ(skip_hardware_clock, needs_block, buffer, size,
3707
12.0k
                        "Volatile state", "s_realTimePrevious");
3708
12.0k
    }
3709
3710
12.0k
#ifndef HARDWARE_CLOCK
3711
12.0k
    if (rc == TPM_RC_SUCCESS) {
3712
12.0k
        rc = UINT64_Unmarshal(&tmp_uint64, buffer, size);
3713
12.0k
        s_realTimePrevious = tmp_uint64;
3714
12.0k
    }
3715
12.0k
    if (rc == TPM_RC_SUCCESS) {
3716
12.0k
        rc = UINT64_Unmarshal(&tmp_uint64, buffer, size);
3717
12.0k
        s_tpmTime = tmp_uint64;
3718
12.0k
    }
3719
#else
3720
# error Unsupport #define value(s)
3721
#endif
3722
12.0k
skip_hardware_clock:
3723
3724
12.0k
    if (rc == TPM_RC_SUCCESS) {
3725
12.0k
        rc = BOOL_Unmarshal(&s_timerReset, buffer, size);
3726
12.0k
    }
3727
12.0k
    if (rc == TPM_RC_SUCCESS) {
3728
12.0k
        rc = BOOL_Unmarshal(&s_timerStopped, buffer, size);
3729
12.0k
    }
3730
12.0k
    if (rc == TPM_RC_SUCCESS) {
3731
12.0k
       rc = UINT32_Unmarshal(&s_adjustRate, buffer, size);
3732
12.0k
    }
3733
12.0k
    if (rc == TPM_RC_SUCCESS) {
3734
12.0k
        rc = UINT64_Unmarshal(&backthen, buffer, size);
3735
12.0k
    }
3736
3737
    /* version 2 starts having indicator for next versions that we can skip;
3738
       this allows us to downgrade state */
3739
12.0k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
3740
12.0k
        BLOCK_SKIP_READ(skip_future_versions, hdr.version >= 3, buffer, size,
3741
12.0k
                        "Volatile State", "version 3 or later");
3742
12.0k
        if (rc == TPM_RC_SUCCESS) {
3743
12.0k
            rc = VolatileState_TailV3_Unmarshal(buffer, size);
3744
12.0k
        }
3745
12.0k
        if (rc == TPM_RC_SUCCESS) {
3746
12.0k
            BLOCK_SKIP_READ(skip_future_versions, hdr.version >= 4, buffer, size,
3747
12.0k
                            "Volatile State", "version 4 or later");
3748
12.0k
        }
3749
12.0k
        if (rc == TPM_RC_SUCCESS) {
3750
12.0k
            rc = VolatileState_TailV4_Unmarshal(buffer, size);
3751
12.0k
        }
3752
12.0k
        if (rc == TPM_RC_SUCCESS) {
3753
12.0k
            BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
3754
12.0k
                            "Volatile State", "version 5 or later");
3755
0
        }
3756
        /* future versions append here */
3757
12.0k
    }
3758
3759
12.0k
skip_future_versions:
3760
3761
    /* keep marker at end: */
3762
12.0k
    if (rc == TPM_RC_SUCCESS) {
3763
12.0k
        rc = UINT32_Unmarshal(&tmp_uint32, buffer, size);
3764
12.0k
        if (rc == TPM_RC_SUCCESS) {
3765
12.0k
            if (tmp_uint32 != VOLATILE_STATE_MAGIC) {
3766
0
                TPMLIB_LogTPM2Error("Invalid volatile state magic. "
3767
0
                                    "Expected 0x%08x, got 0x%08x\n",
3768
0
                                    VOLATILE_STATE_MAGIC, tmp_uint32);
3769
0
                rc = TPM_RC_BAD_TAG;
3770
0
            }
3771
12.0k
        }
3772
12.0k
    }
3773
3774
12.0k
    if (rc == TPM_RC_SUCCESS) {
3775
12.0k
        BOOL timesAreRealtime = hdr.version <= 3;
3776
        /* Before Rev148 (header version <= 3), times were reported in
3777
           realtime; we need to account for this now */
3778
12.0k
        ClockAdjustPostResume(backthen, timesAreRealtime);
3779
12.0k
    }
3780
12.0k
    return rc;
3781
12.0k
}
3782
3783
/********************************************************************
3784
 * The following is a list of compile-time constants that we verify against
3785
 * when state is presented to us. Comparison operators allow us to verify
3786
 * compile time constants' values against what we would accept when reading
3787
 * state. So for example a value of 1024 for a buffer size that is read can
3788
 * be compared against the value that this implementation has been compiled
3789
 * with. In some case a 'less or equal' [LE] (1024 < 2048) may be acceptable
3790
 * but that depends on the purpose of the compile time constant. The most
3791
 * conservative approach is to force that the unmarshalled values are equal
3792
 * [EQ] to the ones of this implementation.
3793
 *
3794
 * Meanings of comparison operators:
3795
 * EQ: The read state must match the state the implementation would produce
3796
 *     The algorithm must have been enabled at the previously implementation
3797
 *     and at the current implementation; or it must have been disabled at
3798
 *     both
3799
 *
3800
 * LE: The read state may have been written by a version that did not
3801
 *     implement an algorithm ('0') but the current implementation does
3802
 *     implement it ('1'); this does NOT allow an implementation to accept
3803
 *     the state anymore if the state was written by an implementation that
3804
 *     implemented it ('1') but the current implementation does not im-
3805
 *     plement it
3806
 *
3807
 * DONTCARE: Implementation that wrote the state can either have implemented
3808
 *           an algorithm or not and implementation reading the state may
3809
 *           also either implement it or not
3810
 */
3811
static const struct _entry {
3812
    UINT32 constant;
3813
    const char *name;
3814
    enum CompareOp { EQ, LE, GE, DONTCARE } cmp;
3815
} pa_compile_constants[] = {
3816
#define COMPILE_CONSTANT(CONST, CMP) \
3817
    .constant = CONST, .name = #CONST, .cmp = CMP
3818
    { COMPILE_CONSTANT(ALG_RSA, EQ) },
3819
    { COMPILE_CONSTANT(ALG_SHA1, EQ) },
3820
    { COMPILE_CONSTANT(ALG_HMAC, EQ) },
3821
    { COMPILE_CONSTANT(ALG_TDES, LE) },
3822
    { COMPILE_CONSTANT(ALG_AES, EQ) },
3823
    { COMPILE_CONSTANT(ALG_MGF1, EQ) },
3824
    { COMPILE_CONSTANT(ALG_XOR, EQ) },
3825
    { COMPILE_CONSTANT(ALG_KEYEDHASH, EQ) },
3826
    { COMPILE_CONSTANT(ALG_SHA256, EQ) },
3827
    { COMPILE_CONSTANT(ALG_SHA384, EQ) },
3828
    { COMPILE_CONSTANT(ALG_SHA512, EQ) },
3829
    { COMPILE_CONSTANT(ALG_SM3_256, EQ) },
3830
    { COMPILE_CONSTANT(ALG_SM4, EQ) },
3831
    { COMPILE_CONSTANT(ALG_RSASSA, EQ) },
3832
    { COMPILE_CONSTANT(ALG_RSAES, EQ) },
3833
    { COMPILE_CONSTANT(ALG_RSAPSS, EQ) },
3834
    { COMPILE_CONSTANT(ALG_OAEP, EQ) },
3835
    { COMPILE_CONSTANT(ALG_ECC, EQ) },
3836
    { COMPILE_CONSTANT(ALG_ECDH, EQ) },
3837
    { COMPILE_CONSTANT(ALG_ECDSA, EQ) },
3838
    { COMPILE_CONSTANT(ALG_ECDAA, EQ) },
3839
    { COMPILE_CONSTANT(ALG_SM2, LE) },
3840
    { COMPILE_CONSTANT(ALG_ECSCHNORR, EQ) },
3841
    { COMPILE_CONSTANT(ALG_ECMQV, LE) },
3842
    { COMPILE_CONSTANT(ALG_SYMCIPHER, EQ) },
3843
    { COMPILE_CONSTANT(ALG_KDF1_SP800_56A, EQ) },
3844
    { COMPILE_CONSTANT(ALG_KDF2, LE) },
3845
    { COMPILE_CONSTANT(ALG_KDF1_SP800_108, EQ) },
3846
    { COMPILE_CONSTANT(ALG_CMAC, LE) },
3847
    { COMPILE_CONSTANT(ALG_CTR, EQ) },
3848
    { COMPILE_CONSTANT(ALG_OFB, EQ) },
3849
    { COMPILE_CONSTANT(ALG_CBC, EQ) },
3850
    { COMPILE_CONSTANT(ALG_CFB, EQ) },
3851
    { COMPILE_CONSTANT(ALG_ECB, EQ) },
3852
    { COMPILE_CONSTANT(3072, LE) }, /* previous: MAX_RSA_KEY_BITS (4096 since StateFormatLevel 8) */
3853
    { COMPILE_CONSTANT(MAX_TDES_KEY_BITS, EQ) },
3854
    { COMPILE_CONSTANT(MAX_AES_KEY_BITS, EQ) },
3855
    { COMPILE_CONSTANT(128, EQ) }, /* MAX_SM4_KEY_BITS      in older code was 128 also with SM4 not active */
3856
    { COMPILE_CONSTANT(128, EQ) }, /* MAX_CAMELLIA_KEY_BITS in older code was 128 also with CAMELLIA not active */
3857
    { COMPILE_CONSTANT(ECC_NIST_P192, LE) },
3858
    { COMPILE_CONSTANT(ECC_NIST_P224, LE) },
3859
    { COMPILE_CONSTANT(ECC_NIST_P256, LE) },
3860
    { COMPILE_CONSTANT(ECC_NIST_P384, LE) },
3861
    { COMPILE_CONSTANT(ECC_NIST_P521, LE) },
3862
    { COMPILE_CONSTANT(ECC_BN_P256, LE) },
3863
    { COMPILE_CONSTANT(ECC_BN_P638, LE) },
3864
    { COMPILE_CONSTANT(ECC_SM2_P256, LE) },
3865
    { COMPILE_CONSTANT(MAX_ECC_KEY_BITS, LE) },
3866
    { COMPILE_CONSTANT(4, EQ) }, /* was: HASH_ALIGNMENT, which is not relevant */
3867
    { COMPILE_CONSTANT(SYM_ALIGNMENT, EQ) },
3868
    { COMPILE_CONSTANT(IMPLEMENTATION_PCR, EQ) },
3869
    { COMPILE_CONSTANT(PLATFORM_PCR, EQ) },
3870
    { COMPILE_CONSTANT(DRTM_PCR, EQ) },
3871
    { COMPILE_CONSTANT(HCRTM_PCR, EQ) },
3872
    { COMPILE_CONSTANT(NUM_LOCALITIES, EQ) },
3873
    { COMPILE_CONSTANT(MAX_HANDLE_NUM, EQ) },
3874
    { COMPILE_CONSTANT(MAX_ACTIVE_SESSIONS, EQ) },
3875
    { COMPILE_CONSTANT(MAX_LOADED_SESSIONS, EQ) },
3876
    { COMPILE_CONSTANT(MAX_SESSION_NUM, EQ) },
3877
    { COMPILE_CONSTANT(MAX_LOADED_OBJECTS, EQ) },
3878
    { COMPILE_CONSTANT(MIN_EVICT_OBJECTS, LE) },
3879
    { COMPILE_CONSTANT(NUM_POLICY_PCR_GROUP, EQ) },
3880
    { COMPILE_CONSTANT(NUM_AUTHVALUE_PCR_GROUP, EQ) },
3881
    { COMPILE_CONSTANT(MAX_CONTEXT_SIZE, LE) }, /* old: 2474 */
3882
    { COMPILE_CONSTANT(MAX_DIGEST_BUFFER, EQ) },
3883
    { COMPILE_CONSTANT(MAX_NV_INDEX_SIZE, EQ) },
3884
    { COMPILE_CONSTANT(MAX_NV_BUFFER_SIZE, EQ) },
3885
    { COMPILE_CONSTANT(MAX_CAP_BUFFER, EQ) },
3886
    { COMPILE_CONSTANT(NV_MEMORY_SIZE, LE) },
3887
    { COMPILE_CONSTANT(MIN_COUNTER_INDICES, EQ) },
3888
    { COMPILE_CONSTANT(NUM_STATIC_PCR, EQ) },
3889
    { COMPILE_CONSTANT(MAX_ALG_LIST_SIZE, EQ) },
3890
    { COMPILE_CONSTANT(PRIMARY_SEED_SIZE, EQ) },
3891
#if CONTEXT_ENCRYPT_ALG == ALG_AES_VALUE
3892
#define CONTEXT_ENCRYPT_ALGORITHM_ TPM_ALG_AES
3893
#endif
3894
    { COMPILE_CONSTANT(CONTEXT_ENCRYPT_ALGORITHM_, EQ) },
3895
    { COMPILE_CONSTANT(NV_CLOCK_UPDATE_INTERVAL, EQ) },
3896
    { COMPILE_CONSTANT(NUM_POLICY_PCR, EQ) },
3897
    { COMPILE_CONSTANT(ORDERLY_BITS, EQ) },
3898
    { COMPILE_CONSTANT(MAX_SYM_DATA, EQ) },
3899
    { COMPILE_CONSTANT(MAX_RNG_ENTROPY_SIZE, EQ) },
3900
    { COMPILE_CONSTANT(RAM_INDEX_SPACE, EQ) },
3901
    { COMPILE_CONSTANT(RSA_DEFAULT_PUBLIC_EXPONENT, EQ) },
3902
    { COMPILE_CONSTANT(ENABLE_PCR_NO_INCREMENT, EQ) },
3903
    { COMPILE_CONSTANT(CRT_FORMAT_RSA, EQ) },
3904
    { COMPILE_CONSTANT(VENDOR_COMMAND_COUNT, EQ) },
3905
    { COMPILE_CONSTANT(MAX_VENDOR_BUFFER_SIZE, EQ) },
3906
    { COMPILE_CONSTANT(TPM_MAX_DERIVATION_BITS, EQ) },
3907
    { COMPILE_CONSTANT(PROOF_SIZE, EQ) },
3908
    { COMPILE_CONSTANT(HASH_COUNT, EQ) },
3909
3910
    /* added for PA_COMPILE_CONSTANTS_VERSION == 3 */
3911
    { COMPILE_CONSTANT(AES_128, LE) },
3912
    { COMPILE_CONSTANT(0, LE) }, /* was: AES_192; now handled via profile */
3913
    { COMPILE_CONSTANT(AES_256, LE) },
3914
    { COMPILE_CONSTANT(SM4_128, LE) },
3915
    { COMPILE_CONSTANT(ALG_CAMELLIA, LE) },
3916
    { COMPILE_CONSTANT(CAMELLIA_128, LE) },
3917
    { COMPILE_CONSTANT(0, LE) }, /* was: CAMELLIA_192; now handled via profile */
3918
    { COMPILE_CONSTANT(CAMELLIA_256, LE) },
3919
    { COMPILE_CONSTANT(ALG_SHA3_256, LE) },
3920
    { COMPILE_CONSTANT(ALG_SHA3_384, LE) },
3921
    { COMPILE_CONSTANT(ALG_SHA3_512, LE) },
3922
    { COMPILE_CONSTANT(RSA_1024, LE) },
3923
    { COMPILE_CONSTANT(RSA_2048, LE) },
3924
    { COMPILE_CONSTANT(RSA_3072, LE) },
3925
    { COMPILE_CONSTANT(0, LE) }, /* was RSA_4096; changed a StateFormatLevel 8 */
3926
    { COMPILE_CONSTANT(RSA_16384, LE) },
3927
    { COMPILE_CONSTANT(RH_ACT_0, LE) },
3928
    { COMPILE_CONSTANT(RH_ACT_1, LE) },
3929
    { COMPILE_CONSTANT(RH_ACT_2, LE) },
3930
    { COMPILE_CONSTANT(RH_ACT_3, LE) },
3931
    { COMPILE_CONSTANT(RH_ACT_4, LE) },
3932
    { COMPILE_CONSTANT(RH_ACT_5, LE) },
3933
    { COMPILE_CONSTANT(RH_ACT_6, LE) },
3934
    { COMPILE_CONSTANT(RH_ACT_7, LE) },
3935
    { COMPILE_CONSTANT(RH_ACT_8, LE) },
3936
    { COMPILE_CONSTANT(RH_ACT_9, LE) },
3937
    { COMPILE_CONSTANT(RH_ACT_A, LE) },
3938
    { COMPILE_CONSTANT(RH_ACT_B, LE) },
3939
    { COMPILE_CONSTANT(RH_ACT_C, LE) },
3940
    { COMPILE_CONSTANT(RH_ACT_D, LE) },
3941
    { COMPILE_CONSTANT(RH_ACT_E, LE) },
3942
    { COMPILE_CONSTANT(RH_ACT_F, LE) },
3943
};
3944
MUST_BE(CONTEXT_ENCRYPT_ALG == ALG_AES_VALUE);
3945
3946
static TPM_RC
3947
UINT32_Unmarshal_CheckConstant(BYTE **buffer, INT32 *size, UINT32 constant,
3948
                               const char *name,
3949
                               enum CompareOp cmp, UINT16 struct_version)
3950
2.89M
{
3951
2.89M
    TPM_RC rc = TPM_RC_SUCCESS;
3952
2.89M
    UINT32 value;
3953
2.89M
    const char *op = NULL;
3954
3955
2.89M
    if (rc == TPM_RC_SUCCESS) {
3956
2.89M
        rc = UINT32_Unmarshal(&value, buffer, size);
3957
2.89M
    }
3958
2.89M
    if (rc == TPM_RC_SUCCESS) {
3959
2.89M
        switch (cmp) {
3960
1.69M
        case EQ:
3961
1.69M
            if (!(constant == value))
3962
0
                op = "=";
3963
1.69M
            break;
3964
1.20M
        case LE:
3965
1.20M
            if (!(value <= constant))
3966
0
                op = "<=";
3967
1.20M
            break;
3968
0
        case GE:
3969
0
            if (!(value >= constant))
3970
0
                op = ">=";
3971
0
            break;
3972
0
        case DONTCARE:
3973
0
            break;
3974
2.89M
        }
3975
2.89M
        if (op) {
3976
0
            TPMLIB_LogTPM2Error("Unexpected value for %s; "
3977
0
                                "its value %d is not %s %d; "
3978
0
                                "(version: %u)\n",
3979
0
                                name, value, op, constant,
3980
0
                                struct_version);
3981
0
            rc = TPM_RC_BAD_PARAMETER;
3982
0
        }
3983
2.89M
    }
3984
2.89M
    return rc;
3985
2.89M
}
3986
3987
48.5k
#define PA_COMPILE_CONSTANTS_MAGIC 0xc9ea6431
3988
48.5k
#define PA_COMPILE_CONSTANTS_VERSION 3
3989
3990
/* Marshal compile-time constants related to persistent-all state */
3991
static UINT32
3992
PACompileConstants_Marshal(BYTE **buffer, INT32 *size)
3993
24.3k
{
3994
24.3k
    unsigned i;
3995
24.3k
    UINT32 written, tmp_uint32;
3996
24.3k
    UINT32 array_size = ARRAY_SIZE(pa_compile_constants);
3997
24.3k
    BLOCK_SKIP_INIT;
3998
3999
24.3k
    written = NV_HEADER_Marshal(buffer, size,
4000
24.3k
                                PA_COMPILE_CONSTANTS_VERSION,
4001
24.3k
                                PA_COMPILE_CONSTANTS_MAGIC, 1);
4002
4003
24.3k
    written += UINT32_Marshal(&array_size, buffer, size);
4004
4005
2.94M
    for (i = 0; i < array_size; i++) {
4006
2.92M
        tmp_uint32 = pa_compile_constants[i].constant;
4007
2.92M
        written += UINT32_Marshal(&tmp_uint32, buffer, size);
4008
2.92M
    }
4009
4010
24.3k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
4011
    /* future versions append below this line */
4012
4013
24.3k
    BLOCK_SKIP_WRITE_POP(size);
4014
4015
24.3k
    BLOCK_SKIP_WRITE_CHECK;
4016
4017
24.3k
    return written;
4018
24.3k
}
4019
4020
static TPM_RC
4021
PACompileConstants_Unmarshal(BYTE **buffer, INT32 *size)
4022
24.1k
{
4023
24.1k
    TPM_RC rc = TPM_RC_SUCCESS;
4024
24.1k
    unsigned i;
4025
24.1k
    NV_HEADER hdr;
4026
24.1k
    UINT32 array_size;
4027
24.1k
    UINT32 exp_array_size = 0;
4028
4029
24.1k
    if (rc == TPM_RC_SUCCESS) {
4030
24.1k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
4031
24.1k
                                 PA_COMPILE_CONSTANTS_VERSION,
4032
24.1k
                                 PA_COMPILE_CONSTANTS_MAGIC);
4033
24.1k
    }
4034
24.1k
    if (rc == TPM_RC_SUCCESS) {
4035
24.1k
        switch (hdr.version) {
4036
0
        case 1:
4037
0
        case 2:
4038
            /* PA_COMPILE_CONSTANTS_VERSION 1 and 2 had 88 entries */
4039
0
            exp_array_size = 88;
4040
0
            break;
4041
24.1k
        case 3:
4042
            /* PA_COMPILE_CONSTANTS_VERSION 3 had 104 entries */
4043
24.1k
            exp_array_size = 120;
4044
24.1k
            break;
4045
0
        default:
4046
            /* we don't support anything newer - no downgrade */
4047
0
            TPMLIB_LogTPM2Error("Unsupported PA_COMPILE_CONSTANTS version %d. "
4048
0
                                "Supporting up to version %d.\n",
4049
0
                                hdr.version, PA_COMPILE_CONSTANTS_VERSION);
4050
0
            rc = TPM_RC_BAD_VERSION;
4051
24.1k
        }
4052
24.1k
    }
4053
4054
24.1k
    if (rc == TPM_RC_SUCCESS) {
4055
24.1k
        rc = UINT32_Unmarshal(&array_size, buffer, size);
4056
24.1k
    }
4057
4058
24.1k
    if (rc == TPM_RC_SUCCESS &&
4059
24.1k
        array_size != exp_array_size) {
4060
0
        TPMLIB_LogTPM2Error("PA_COMPILE_CONSTANTS v%d has non-matching number of "
4061
0
                            "elements; found %u, expected %u\n",
4062
0
                            hdr.version, array_size, exp_array_size);
4063
0
    }
4064
4065
2.92M
    for (i = 0; rc == TPM_RC_SUCCESS && i < exp_array_size; i++)
4066
2.89M
        rc = UINT32_Unmarshal_CheckConstant(
4067
2.89M
                                  buffer, size, pa_compile_constants[i].constant,
4068
2.89M
                                  pa_compile_constants[i].name,
4069
2.89M
                                  pa_compile_constants[i].cmp, hdr.version);
4070
4071
4072
    /* version 2 starts having indicator for next versions that we can skip;
4073
       this allows us to downgrade state */
4074
24.1k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
4075
24.1k
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
4076
24.1k
                        "PA_COMPILE_CONSTANTS", "version 3 or later");
4077
        /* future versions nest-append here */
4078
0
    }
4079
4080
24.1k
skip_future_versions:
4081
4082
    /* keep marker at end: */
4083
24.1k
    return rc;
4084
24.1k
}
4085
4086
static UINT16
4087
PERSISTENT_DATA_PPList_Marshal(PERSISTENT_DATA *data, BYTE **buffer, INT32 *size,
4088
                               UINT16 blob_version,
4089
                               UINT32 commandCount, UINT32 commandArraySize)
4090
24.3k
{
4091
24.3k
    UINT8 ppList[BITS_TO_BYTES(110)];
4092
24.3k
    UINT16 array_size;
4093
24.3k
    UINT16 written;
4094
24.3k
    UINT8 *ptr;
4095
4096
24.3k
    assert(!COMPRESSED_LISTS);
4097
24.3k
    if (blob_version <= 4) {
4098
        /* Custom profile can get here; v0.9 had 110 commands enabled and
4099
         * was using a COMPRESSED_LIST.
4100
         */
4101
24.3k
        assert(commandCount <= 110);
4102
24.3k
        array_size = (commandCount + 7) / 8;
4103
24.3k
        assert(sizeof(ppList) >= array_size);
4104
24.3k
        ConvertToCompressedBitArray(data->ppList, sizeof(data->ppList),
4105
24.3k
                                    ppList, array_size);
4106
24.3k
        ptr = ppList;
4107
24.3k
    } else {
4108
        /* write the array as it is */
4109
0
        array_size = commandArraySize;
4110
0
        assert(array_size <= sizeof(data->ppList));
4111
0
        ptr = data->ppList;
4112
0
    }
4113
24.3k
    written = UINT16_Marshal(&array_size, buffer, size);
4114
24.3k
    written += Array_Marshal(ptr, array_size, buffer, size);
4115
4116
24.3k
    return written;
4117
24.3k
}
4118
4119
static TPM_RC
4120
PERSISTENT_DATA_PPList_Unmarshal(PERSISTENT_DATA *data, BYTE **buffer, INT32 *size,
4121
                                 UINT16 blob_version)
4122
24.1k
{
4123
24.1k
    TPM_RC rc = TPM_RC_SUCCESS;
4124
24.1k
    UINT16 array_size;
4125
4126
24.1k
    assert(!COMPRESSED_LISTS);
4127
4128
24.1k
    if (rc == TPM_RC_SUCCESS) {
4129
24.1k
        rc = UINT16_Unmarshal(&array_size, buffer, size);
4130
24.1k
    }
4131
24.1k
    if (rc == TPM_RC_SUCCESS) {
4132
24.1k
        BYTE buf[array_size];
4133
4134
24.1k
        rc = Array_Unmarshal(buf, array_size, buffer, size);
4135
24.1k
        if (rc == TPM_RC_SUCCESS) {
4136
24.1k
            if (blob_version <= 4) {
4137
                /* version <= 4 used COMPRESSED_LISTS and needs to be converted */
4138
24.1k
                rc = ConvertFromCompressedBitArray(buf, array_size,
4139
24.1k
                                                   data->ppList, sizeof(data->ppList));
4140
24.1k
            } else {
4141
                /* later versions of libtpms may write bigger arrays - truncate them */
4142
0
                if (array_size > sizeof(data->ppList))
4143
0
                    array_size = sizeof(data->ppList);
4144
4145
0
                memcpy(data->ppList, buf, array_size);
4146
                /* clear the rest of byte array */
4147
0
                MUST_BE(sizeof(data->ppList[0]) == sizeof(BYTE));
4148
0
                while (array_size < ARRAY_SIZE(data->ppList))
4149
0
                    data->ppList[array_size++] = 0;
4150
0
            }
4151
24.1k
        }
4152
24.1k
    }
4153
24.1k
    return rc;
4154
24.1k
}
4155
4156
static UINT16
4157
PERSISTENT_DATA_AuditCommands_Marshal(PERSISTENT_DATA *data, BYTE **buffer, INT32 *size,
4158
                                      UINT16 blob_version,
4159
                                      UINT32 commandCount, UINT32 commandArraySize)
4160
24.3k
{
4161
24.3k
    UINT8 auditCommands[BITS_TO_BYTES(110 + 1)];
4162
24.3k
    UINT16 array_size;
4163
24.3k
    UINT16 written;
4164
24.3k
    UINT8 *ptr;
4165
4166
24.3k
    assert(!COMPRESSED_LISTS);
4167
4168
24.3k
    if (blob_version <= 4) {
4169
        /* Custom profile can get here; v0.9 had 110 commands enabled and
4170
         * was using a COMPRESSED_LIST.
4171
         */
4172
24.3k
        assert(commandCount <= 110);
4173
24.3k
        array_size = BITS_TO_BYTES(commandCount + 1); /* same as in Global.h PERSISTENT_DATA */
4174
24.3k
        assert(sizeof(auditCommands) >= array_size);
4175
24.3k
        ConvertToCompressedBitArray(data->auditCommands, sizeof(data->auditCommands),
4176
24.3k
                                    auditCommands, array_size);
4177
24.3k
        ptr = auditCommands;
4178
24.3k
    } else {
4179
        /* write the array as it is */
4180
0
        array_size = commandArraySize;
4181
0
        assert(array_size <= sizeof(data->auditCommands));
4182
0
        ptr = data->auditCommands;
4183
0
    }
4184
24.3k
    written = UINT16_Marshal(&array_size, buffer, size);
4185
24.3k
    written += Array_Marshal(ptr, array_size, buffer, size);
4186
4187
24.3k
    return written;
4188
24.3k
}
4189
4190
static TPM_RC
4191
PERSISTENT_DATA_AuditCommands_Unmarshal(PERSISTENT_DATA *data, BYTE **buffer, INT32 *size,
4192
                                        UINT16 blob_version)
4193
24.1k
{
4194
24.1k
    TPM_RC rc = TPM_RC_SUCCESS;
4195
24.1k
    UINT16 array_size;
4196
4197
24.1k
    assert(!COMPRESSED_LISTS);
4198
4199
24.1k
    if (rc == TPM_RC_SUCCESS) {
4200
24.1k
        rc = UINT16_Unmarshal(&array_size, buffer, size);
4201
24.1k
    }
4202
24.1k
    if (rc == TPM_RC_SUCCESS) {
4203
24.1k
        BYTE buf[array_size];
4204
4205
24.1k
        rc = Array_Unmarshal(buf, array_size, buffer, size);
4206
24.1k
        if (rc == TPM_RC_SUCCESS) {
4207
24.1k
            if (blob_version <= 4) {
4208
                /* version <= 4 used COMPRESSED_LISTS and needs to be converted */
4209
24.1k
                rc = ConvertFromCompressedBitArray(buf, array_size,
4210
24.1k
                                                   data->auditCommands, sizeof(data->auditCommands));
4211
24.1k
            } else {
4212
                /* later versions of libtpms may write bigger arrays - truncate them */
4213
0
                if (array_size > sizeof(data->auditCommands))
4214
0
                    array_size = sizeof(data->auditCommands);
4215
4216
0
                memcpy(data->auditCommands, buf, array_size);
4217
                /* clear the rest of byte array */
4218
0
                MUST_BE(sizeof(data->auditCommands[0]) == sizeof(BYTE));
4219
0
                while (array_size < ARRAY_SIZE(data->auditCommands))
4220
0
                    data->auditCommands[array_size++] = 0;
4221
0
            }
4222
24.1k
        }
4223
24.1k
    }
4224
24.1k
    return rc;
4225
24.1k
}
4226
4227
4228
48.5k
#define PERSISTENT_DATA_MAGIC   0x12213443
4229
24.1k
#define PERSISTENT_DATA_VERSION 5
4230
4231
static UINT16
4232
PERSISTENT_DATA_Marshal(PERSISTENT_DATA *data, BYTE **buffer, INT32 *size,
4233
                        struct RuntimeProfile *RuntimeProfile)
4234
24.3k
{
4235
24.3k
    UINT32 commandCount = RuntimeCommandsCountEnabled(&RuntimeProfile->RuntimeCommands);
4236
24.3k
    UINT32 commandArraySize = RuntimeCommandsGetArraySize(&RuntimeProfile->RuntimeCommands);
4237
24.3k
    UINT16 written;
4238
24.3k
    UINT8 clocksize;
4239
24.3k
    BOOL has_block;
4240
24.3k
    BLOCK_SKIP_INIT;
4241
24.3k
    UINT16 blob_version;
4242
4243
24.3k
    switch (RuntimeProfile->stateFormatLevel) {
4244
0
    case 0:
4245
0
        pAssert(FALSE);
4246
0
        break;
4247
24.3k
    case 1 ... 2:
4248
24.3k
        blob_version = 4;
4249
24.3k
        break;
4250
0
    default:
4251
0
        blob_version = 5; /* since stateFormatLevel 3 */
4252
0
        break;
4253
24.3k
    }
4254
4255
24.3k
    written = NV_HEADER_Marshal(buffer, size,
4256
24.3k
                                blob_version,
4257
24.3k
                                PERSISTENT_DATA_MAGIC, blob_version);
4258
    // platformReserved (added in v0.10) is not persisted
4259
24.3k
    written += BOOL_Marshal(&data->disableClear, buffer, size);
4260
24.3k
    written += TPM_ALG_ID_Marshal(&data->ownerAlg, buffer, size);
4261
24.3k
    written += TPM_ALG_ID_Marshal(&data->endorsementAlg, buffer, size);
4262
24.3k
    written += TPM_ALG_ID_Marshal(&data->lockoutAlg, buffer, size);
4263
24.3k
    written += TPM2B_DIGEST_Marshal(&data->ownerPolicy, buffer, size);
4264
24.3k
    written += TPM2B_DIGEST_Marshal(&data->endorsementPolicy, buffer, size);
4265
24.3k
    written += TPM2B_DIGEST_Marshal(&data->lockoutPolicy, buffer, size);
4266
24.3k
    written += TPM2B_AUTH_Marshal(&data->ownerAuth, buffer, size);
4267
24.3k
    written += TPM2B_AUTH_Marshal(&data->endorsementAuth, buffer, size);
4268
24.3k
    written += TPM2B_AUTH_Marshal(&data->lockoutAuth, buffer, size);
4269
24.3k
    written += TPM2B_Marshal(&data->EPSeed.b, sizeof(data->EPSeed.t.buffer), buffer, size);
4270
24.3k
    written += TPM2B_Marshal(&data->SPSeed.b, sizeof(data->SPSeed.t.buffer), buffer, size);
4271
24.3k
    written += TPM2B_Marshal(&data->PPSeed.b, sizeof(data->PPSeed.t.buffer), buffer, size);
4272
24.3k
    written += TPM2B_PROOF_Marshal(&data->phProof, buffer, size);
4273
24.3k
    written += TPM2B_PROOF_Marshal(&data->shProof, buffer, size);
4274
24.3k
    written += TPM2B_PROOF_Marshal(&data->ehProof, buffer, size);
4275
24.3k
    written += UINT64_Marshal(&data->totalResetCount, buffer, size);
4276
24.3k
    written += UINT32_Marshal(&data->resetCount, buffer, size);
4277
4278
24.3k
#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
4279
24.3k
    has_block = TRUE;
4280
#else
4281
    has_block = FALSE;
4282
#endif
4283
24.3k
    written += BLOCK_SKIP_WRITE_PUSH(has_block, buffer, size);
4284
4285
24.3k
#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
4286
24.3k
    written += PCR_POLICY_Marshal(&data->pcrPolicies, buffer, size);
4287
24.3k
#endif
4288
24.3k
    BLOCK_SKIP_WRITE_POP(size);
4289
4290
24.3k
    written += TPML_PCR_SELECTION_Marshal(&data->pcrAllocated, buffer, size);
4291
4292
24.3k
    written += PERSISTENT_DATA_PPList_Marshal(data, buffer, size, blob_version,
4293
24.3k
                                              commandCount, commandArraySize);
4294
24.3k
    written += UINT32_Marshal(&data->failedTries, buffer, size);
4295
24.3k
    written += UINT32_Marshal(&data->maxTries, buffer, size);
4296
24.3k
    written += UINT32_Marshal(&data->recoveryTime, buffer, size);
4297
24.3k
    written += UINT32_Marshal(&data->lockoutRecovery, buffer, size);
4298
24.3k
    written += BOOL_Marshal(&data->lockOutAuthEnabled, buffer, size);
4299
24.3k
    written += UINT16_Marshal(&data->orderlyState, buffer, size);
4300
4301
24.3k
    written += PERSISTENT_DATA_AuditCommands_Marshal(data, buffer, size, blob_version,
4302
24.3k
                                                     commandCount, commandArraySize);
4303
24.3k
    written += TPM_ALG_ID_Marshal(&data->auditHashAlg, buffer, size);
4304
24.3k
    written += UINT64_Marshal(&data->auditCounter, buffer, size);
4305
24.3k
    written += UINT32_Marshal(&data->algorithmSet, buffer, size);
4306
24.3k
    written += UINT32_Marshal(&data->firmwareV1, buffer, size);
4307
24.3k
    written += UINT32_Marshal(&data->firmwareV2, buffer, size);
4308
#if CLOCK_STOPS
4309
    clocksize = sizeof(UINT64);
4310
    written += UINT8_Marshal(&clocksize, buffer, size);
4311
    written += UINT64_Marshal(&data->timeEpoch, buffer, size);
4312
#else
4313
24.3k
    clocksize = sizeof(UINT32);
4314
24.3k
    written += UINT8_Marshal(&clocksize, buffer, size);
4315
24.3k
    written += UINT32_Marshal(&data->timeEpoch, buffer, size);
4316
24.3k
#endif
4317
4318
24.3k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
4319
4320
    /* there's a 'shadow' pcrAllocated as well */
4321
24.3k
    written += TPML_PCR_SELECTION_Marshal(&gp.pcrAllocated, buffer, size);
4322
4323
24.3k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
4324
24.3k
    written += SEED_COMPAT_LEVEL_Marshal(&data->EPSeedCompatLevel,
4325
24.3k
                                         buffer, size);
4326
24.3k
    written += SEED_COMPAT_LEVEL_Marshal(&data->SPSeedCompatLevel,
4327
24.3k
                                         buffer, size);
4328
24.3k
    written += SEED_COMPAT_LEVEL_Marshal(&data->PPSeedCompatLevel,
4329
24.3k
                                         buffer, size);
4330
4331
24.3k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
4332
    /* future versions append below this line */
4333
4334
24.3k
    BLOCK_SKIP_WRITE_POP(size);
4335
24.3k
    BLOCK_SKIP_WRITE_POP(size);
4336
24.3k
    BLOCK_SKIP_WRITE_POP(size);
4337
4338
24.3k
    BLOCK_SKIP_WRITE_CHECK;
4339
4340
24.3k
    return written;
4341
24.3k
}
4342
4343
static TPM_RC
4344
PERSISTENT_DATA_Unmarshal(PERSISTENT_DATA *data, BYTE **buffer, INT32 *size)
4345
24.1k
{
4346
24.1k
    TPM_RC rc = TPM_RC_SUCCESS;
4347
24.1k
    NV_HEADER hdr;
4348
24.1k
    UINT8 clocksize;
4349
24.1k
    BOOL needs_block;
4350
4351
24.1k
    if (rc == TPM_RC_SUCCESS) {
4352
24.1k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
4353
24.1k
                                 PERSISTENT_DATA_VERSION,
4354
24.1k
                                 PERSISTENT_DATA_MAGIC);
4355
24.1k
    }
4356
4357
24.1k
    if (rc == TPM_RC_SUCCESS) {
4358
24.1k
        rc = BOOL_Unmarshal(&data->disableClear, buffer, size);
4359
24.1k
    }
4360
24.1k
    if (rc == TPM_RC_SUCCESS) {
4361
24.1k
        rc = TPM_ALG_ID_Unmarshal(&data->ownerAlg, buffer, size);
4362
24.1k
    }
4363
24.1k
    if (rc == TPM_RC_SUCCESS) {
4364
24.1k
        rc = TPM_ALG_ID_Unmarshal(&data->endorsementAlg, buffer, size);
4365
24.1k
    }
4366
24.1k
    if (rc == TPM_RC_SUCCESS) {
4367
24.1k
        rc = TPM_ALG_ID_Unmarshal(&data->lockoutAlg, buffer, size);
4368
24.1k
    }
4369
24.1k
    if (rc == TPM_RC_SUCCESS) {
4370
24.1k
        rc = TPM2B_DIGEST_Unmarshal(&data->ownerPolicy, buffer, size);
4371
24.1k
    }
4372
24.1k
    if (rc == TPM_RC_SUCCESS) {
4373
24.1k
        rc = TPM2B_DIGEST_Unmarshal(&data->endorsementPolicy, buffer, size);
4374
24.1k
    }
4375
24.1k
    if (rc == TPM_RC_SUCCESS) {
4376
24.1k
        rc = TPM2B_DIGEST_Unmarshal(&data->lockoutPolicy, buffer, size);
4377
24.1k
    }
4378
24.1k
    if (rc == TPM_RC_SUCCESS) {
4379
24.1k
        rc = TPM2B_AUTH_Unmarshal(&data->ownerAuth, buffer, size);
4380
24.1k
    }
4381
24.1k
    if (rc == TPM_RC_SUCCESS) {
4382
24.1k
        rc = TPM2B_AUTH_Unmarshal(&data->endorsementAuth, buffer, size);
4383
24.1k
    }
4384
24.1k
    if (rc == TPM_RC_SUCCESS) {
4385
24.1k
        rc = TPM2B_AUTH_Unmarshal(&data->lockoutAuth, buffer, size);
4386
24.1k
    }
4387
24.1k
    if (rc == TPM_RC_SUCCESS) {
4388
24.1k
        rc = TPM2B_Unmarshal(&data->EPSeed.b, PRIMARY_SEED_SIZE, buffer, size);
4389
24.1k
    }
4390
24.1k
    if (rc == TPM_RC_SUCCESS) {
4391
24.1k
        rc = TPM2B_Unmarshal(&data->SPSeed.b, PRIMARY_SEED_SIZE, buffer, size);
4392
24.1k
    }
4393
24.1k
    if (rc == TPM_RC_SUCCESS) {
4394
24.1k
        rc = TPM2B_Unmarshal(&data->PPSeed.b, PRIMARY_SEED_SIZE, buffer, size);
4395
24.1k
    }
4396
24.1k
    if (rc == TPM_RC_SUCCESS) {
4397
24.1k
        rc = TPM2B_PROOF_Unmarshal(&data->phProof, buffer, size);
4398
24.1k
    }
4399
24.1k
    if (rc == TPM_RC_SUCCESS) {
4400
24.1k
        rc = TPM2B_PROOF_Unmarshal(&data->shProof, buffer, size);
4401
24.1k
    }
4402
24.1k
    if (rc == TPM_RC_SUCCESS) {
4403
24.1k
        rc = TPM2B_PROOF_Unmarshal(&data->ehProof, buffer, size);
4404
24.1k
    }
4405
24.1k
    if (rc == TPM_RC_SUCCESS) {
4406
24.1k
        rc = UINT64_Unmarshal(&data->totalResetCount, buffer, size);
4407
24.1k
    }
4408
24.1k
    if (rc == TPM_RC_SUCCESS) {
4409
24.1k
        rc = UINT32_Unmarshal(&data->resetCount, buffer, size);
4410
24.1k
    }
4411
4412
24.1k
#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
4413
24.1k
    needs_block = TRUE;
4414
#else
4415
    needs_block = FALSE;
4416
#endif
4417
24.1k
    if (rc == TPM_RC_SUCCESS) {
4418
24.1k
        BLOCK_SKIP_READ(skip_num_policy_pcr_group, needs_block, buffer, size,
4419
24.1k
                        "PERSISTENT_DATA", "pcrPolicies");
4420
24.1k
    }
4421
24.1k
#if defined NUM_POLICY_PCR_GROUP && NUM_POLICY_PCR_GROUP > 0
4422
24.1k
    if (rc == TPM_RC_SUCCESS) {
4423
24.1k
        rc = PCR_POLICY_Unmarshal(&data->pcrPolicies, buffer, size);
4424
24.1k
    }
4425
24.1k
#endif
4426
24.1k
skip_num_policy_pcr_group:
4427
4428
24.1k
    if (rc == TPM_RC_SUCCESS) {
4429
24.1k
        rc = TPML_PCR_SELECTION_Unmarshal(&data->pcrAllocated, buffer, size);
4430
4431
24.1k
        shadow.pcrAllocated = data->pcrAllocated;
4432
24.1k
        shadow.pcrAllocatedIsNew = TRUE;
4433
24.1k
    }
4434
4435
24.1k
    if (rc == TPM_RC_SUCCESS) {
4436
24.1k
        rc = PERSISTENT_DATA_PPList_Unmarshal(data, buffer, size, hdr.version);
4437
24.1k
    }
4438
4439
24.1k
    if (rc == TPM_RC_SUCCESS) {
4440
24.1k
        rc = UINT32_Unmarshal(&data->failedTries, buffer, size);
4441
24.1k
    }
4442
24.1k
    if (rc == TPM_RC_SUCCESS) {
4443
24.1k
        rc = UINT32_Unmarshal(&data->maxTries, buffer, size);
4444
24.1k
    }
4445
24.1k
    if (rc == TPM_RC_SUCCESS) {
4446
24.1k
        rc = UINT32_Unmarshal(&data->recoveryTime, buffer, size);
4447
24.1k
    }
4448
24.1k
    if (rc == TPM_RC_SUCCESS) {
4449
24.1k
        rc = UINT32_Unmarshal(&data->lockoutRecovery, buffer, size);
4450
24.1k
    }
4451
24.1k
    if (rc == TPM_RC_SUCCESS) {
4452
24.1k
        rc = BOOL_Unmarshal(&data->lockOutAuthEnabled, buffer, size);
4453
24.1k
    }
4454
24.1k
    if (rc == TPM_RC_SUCCESS) {
4455
        /* TPM_SU_Unmarshal returns error if value is 0 */
4456
24.1k
        rc = UINT16_Unmarshal(&data->orderlyState, buffer, size);
4457
24.1k
    }
4458
4459
    /* auditCommands array may not be our size */
4460
24.1k
    if (rc == TPM_RC_SUCCESS) {
4461
24.1k
        rc = PERSISTENT_DATA_AuditCommands_Unmarshal(data, buffer, size, hdr.version);
4462
24.1k
    }
4463
24.1k
    if (rc == TPM_RC_SUCCESS) {
4464
24.1k
        rc = TPM_ALG_ID_Unmarshal(&data->auditHashAlg, buffer, size);
4465
24.1k
    }
4466
24.1k
    if (rc == TPM_RC_SUCCESS) {
4467
24.1k
        rc = UINT64_Unmarshal(&data->auditCounter, buffer, size);
4468
24.1k
    }
4469
24.1k
    if (rc == TPM_RC_SUCCESS) {
4470
24.1k
        rc = UINT32_Unmarshal(&data->algorithmSet, buffer, size);
4471
24.1k
    }
4472
24.1k
    if (rc == TPM_RC_SUCCESS) {
4473
24.1k
        rc = UINT32_Unmarshal(&data->firmwareV1, buffer, size);
4474
24.1k
    }
4475
24.1k
    if (rc == TPM_RC_SUCCESS) {
4476
24.1k
        rc = UINT32_Unmarshal(&data->firmwareV2, buffer, size);
4477
24.1k
    }
4478
4479
24.1k
    if (rc == TPM_RC_SUCCESS) {
4480
24.1k
        rc = UINT8_Unmarshal(&clocksize, buffer, size);
4481
24.1k
    }
4482
24.1k
    if (rc == TPM_RC_SUCCESS) {
4483
#if CLOCK_STOPS
4484
        if (clocksize != sizeof(UINT64)) {
4485
            TPMLIB_LogTPM2Error("Unexpected clocksize for epoch; "
4486
                                "Expected %u, got %u\n",
4487
                                sizeof(UINT64), clocksize);
4488
            rc = TPM_RC_BAD_PARAMETER;
4489
        }
4490
        if (rc == TPM_RC_SUCCESS) {
4491
            rc = UINT64_Unmarshal(&data->timeEpoch, buffer, size);
4492
        }
4493
#else
4494
24.1k
        if (clocksize != sizeof(UINT32)) {
4495
0
            TPMLIB_LogTPM2Error("Unexpected clocksize for epoch; "
4496
0
                                "Expected %zu, got %u\n",
4497
0
                                sizeof(UINT32), clocksize);
4498
0
            rc = TPM_RC_BAD_PARAMETER;
4499
0
        }
4500
24.1k
        if (rc == TPM_RC_SUCCESS) {
4501
24.1k
            rc = UINT32_Unmarshal(&data->timeEpoch, buffer, size);
4502
24.1k
        }
4503
24.1k
#endif
4504
24.1k
    }
4505
4506
    /* default values before conditional block */
4507
24.1k
    data->EPSeedCompatLevel = SEED_COMPAT_LEVEL_ORIGINAL;
4508
24.1k
    data->SPSeedCompatLevel = SEED_COMPAT_LEVEL_ORIGINAL;
4509
24.1k
    data->PPSeedCompatLevel = SEED_COMPAT_LEVEL_ORIGINAL;
4510
4511
    /* version 2 starts having indicator for next versions that we can skip;
4512
       this allows us to downgrade state */
4513
24.1k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
4514
24.1k
        BLOCK_SKIP_READ(skip_future_versions, hdr.version >= 3, buffer, size,
4515
24.1k
                        "PERSISTENT_DATA", "version 3 or later");
4516
24.1k
        if (rc == TPM_RC_SUCCESS) {
4517
24.1k
            rc = TPML_PCR_SELECTION_Unmarshal(&shadow.pcrAllocated, buffer, size);
4518
24.1k
        }
4519
4520
24.1k
        if (rc == TPM_RC_SUCCESS) {
4521
24.1k
            BLOCK_SKIP_READ(skip_future_versions, hdr.version >= 4, buffer, size,
4522
24.1k
                            "PERSISTENT_DATA", "version 4 or later");
4523
24.1k
        }
4524
4525
24.1k
        if (rc == TPM_RC_SUCCESS) {
4526
24.1k
            rc = SEED_COMPAT_LEVEL_Unmarshal(&data->EPSeedCompatLevel,
4527
24.1k
                                             buffer, size, "EPSeed");
4528
24.1k
        }
4529
24.1k
        if (rc == TPM_RC_SUCCESS) {
4530
24.1k
            rc = SEED_COMPAT_LEVEL_Unmarshal(&data->SPSeedCompatLevel,
4531
24.1k
                                             buffer, size, "SPSeed");
4532
24.1k
        }
4533
24.1k
        if (rc == TPM_RC_SUCCESS) {
4534
24.1k
            rc = SEED_COMPAT_LEVEL_Unmarshal(&data->PPSeedCompatLevel,
4535
24.1k
                                             buffer, size, "PPSeed");
4536
24.1k
        }
4537
4538
24.1k
        if (rc == TPM_RC_SUCCESS) {
4539
24.1k
            BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
4540
24.1k
                            "PERSISTENT_DATA", "version 5 or later");
4541
0
        }
4542
        /* future versions nest-append here */
4543
24.1k
    }
4544
4545
24.1k
skip_future_versions:
4546
4547
24.1k
    if (rc != TPM_RC_SUCCESS) {
4548
0
        TPMLIB_LogTPM2Error("Failed to unmarshal PERSISTENT_DATA version %u\n",
4549
0
                            hdr.version);
4550
0
    }
4551
24.1k
    return rc;
4552
24.1k
}
4553
4554
48.5k
#define INDEX_ORDERLY_RAM_VERSION 2
4555
48.5k
#define INDEX_ORDERLY_RAM_MAGIC   0x5346feab
4556
static UINT32
4557
INDEX_ORDERLY_RAM_Marshal(void *array, size_t array_size,
4558
                          BYTE **buffer, INT32 *size)
4559
24.3k
{
4560
24.3k
    UINT16 written;
4561
24.3k
    NV_RAM_HEADER nrh, *nrhp;
4562
24.3k
    UINT16 offset = 0;
4563
24.3k
    UINT16 datasize;
4564
24.3k
    UINT32 sourceside_size = array_size;
4565
24.3k
    BLOCK_SKIP_INIT;
4566
4567
24.3k
    written = NV_HEADER_Marshal(buffer, size,
4568
24.3k
                                INDEX_ORDERLY_RAM_VERSION,
4569
24.3k
                                INDEX_ORDERLY_RAM_MAGIC, 1);
4570
4571
    /* the size of the array we are using here */
4572
24.3k
    written += UINT32_Marshal(&sourceside_size, buffer, size);
4573
4574
24.4k
    while (TRUE) {
4575
24.4k
        nrhp = (NV_RAM_HEADER *)((BYTE *)array + offset);
4576
        /* nrhp may point to misaligned address (ubsan), so use 'nrh'; first access only 'size' */
4577
24.4k
        memcpy(&nrh, nrhp, sizeof(nrh.size));
4578
4579
        /* write the NVRAM header;
4580
           nrh->size holds the complete size including data;
4581
           nrh->size = 0 indicates the end */
4582
24.4k
        written += UINT32_Marshal(&nrh.size, buffer, size);
4583
24.4k
        if (nrh.size == 0)
4584
24.3k
            break;
4585
        /* copy the entire structure now; ubsan does not allow 'nrh = *nrhp' */
4586
69
        memcpy(&nrh, nrhp, sizeof(nrh));
4587
4588
69
        written += TPM_HANDLE_Marshal(&nrh.handle, buffer, size);
4589
69
        written += TPMA_NV_Marshal(&nrh.attributes, buffer, size);
4590
4591
69
        if (offset + nrh.size > array_size) {
4592
0
            TPMLIB_LogTPM2Error("INDEX_ORDERLY_RAM: nrh->size corrupted: %d\n",
4593
0
                                nrh.size);
4594
0
            break;
4595
0
        }
4596
        /* write data size before array */
4597
69
        if (nrh.size < sizeof(NV_RAM_HEADER)) {
4598
0
            TPMLIB_LogTPM2Error(
4599
0
                "INDEX_ORDERLY_RAM: nrh->size < sizeof(NV_RAM_HEADER): %d < %zu\n",
4600
0
                (int)nrh.size, sizeof(NV_RAM_HEADER));
4601
0
            break;
4602
0
        }
4603
69
        datasize = nrh.size - sizeof(NV_RAM_HEADER);
4604
69
        written += UINT16_Marshal(&datasize, buffer, size);
4605
69
        if (datasize > 0) {
4606
            /* append the data */
4607
66
            written += Array_Marshal((BYTE *)array + offset + sizeof(NV_RAM_HEADER),
4608
66
                                     datasize, buffer, size);
4609
66
        }
4610
69
        offset += nrh.size;
4611
69
        if (offset + sizeof(NV_RAM_HEADER) > array_size) {
4612
            /* nothing will fit anymore and there won't be a 0-sized
4613
             * terminating node (@1).
4614
             */
4615
12
            break;
4616
12
        }
4617
69
    }
4618
4619
24.3k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
4620
    /* future versions append below this line */
4621
4622
24.3k
    BLOCK_SKIP_WRITE_POP(size);
4623
4624
24.3k
    BLOCK_SKIP_WRITE_CHECK;
4625
4626
24.3k
    return written;
4627
24.3k
}
4628
4629
static TPM_RC
4630
INDEX_ORDERLY_RAM_Unmarshal(void *array, size_t array_size,
4631
                            BYTE **buffer, INT32 *size)
4632
24.1k
{
4633
24.1k
    TPM_RC rc = TPM_RC_SUCCESS;
4634
24.1k
    NV_HEADER hdr;
4635
24.1k
    NV_RAM_HEADER nrh, *nrhp;
4636
24.1k
    UINT16 offset = 0;
4637
24.1k
    UINT16 datasize = 0;
4638
24.1k
    UINT32 sourceside_size;
4639
4640
24.1k
    if (rc == TPM_RC_SUCCESS) {
4641
24.1k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
4642
24.1k
                                 INDEX_ORDERLY_RAM_VERSION,
4643
24.1k
                                 INDEX_ORDERLY_RAM_MAGIC);
4644
24.1k
    }
4645
24.1k
    if (rc == TPM_RC_SUCCESS) {
4646
        /* get the size of the array on the source side
4647
           we can accommodate different sizes when rebuilding
4648
           but if it doesn't fit we'll error out and report the sizes */
4649
24.1k
        rc = UINT32_Unmarshal(&sourceside_size, buffer, size);
4650
24.1k
    }
4651
4652
24.2k
    while (rc == TPM_RC_SUCCESS) {
4653
24.2k
        memset(&nrh, 0, sizeof(nrh)); /* coverity */
4654
        /* nrhp may point to misaligned address (ubsan)
4655
         * we read 'into' nrh and copy to nrhp at end
4656
         */
4657
24.2k
        nrhp = (NV_RAM_HEADER *)((BYTE *)array + offset);
4658
4659
24.2k
        if (offset + sizeof(NV_RAM_HEADER) > sourceside_size) {
4660
            /* this case can occur with the previous entry filling up the
4661
             * space; in this case there will not be a 0-sized terminating
4662
             * node (see @1 above). We clear the rest of our space.
4663
             */
4664
12
            if (array_size > offset)
4665
6
                memset(nrhp, 0, array_size - offset);
4666
12
            break;
4667
12
        }
4668
4669
        /* write the NVRAM header;
4670
           nrh->size holds the complete size including data;
4671
           nrh->size = 0 indicates the end */
4672
24.2k
        if (offset + sizeof(nrh.size) > array_size) {
4673
0
            offset += sizeof(nrh.size);
4674
0
            goto exit_size;
4675
0
        }
4676
4677
24.2k
        if (rc == TPM_RC_SUCCESS) {
4678
24.2k
            rc = UINT32_Unmarshal(&nrh.size, buffer, size);
4679
24.2k
            if (rc == TPM_RC_SUCCESS && nrh.size == 0) {
4680
24.1k
                memcpy(nrhp, &nrh, sizeof(nrh.size));
4681
24.1k
                break;
4682
24.1k
            }
4683
24.2k
        }
4684
69
        if (offset + sizeof(NV_RAM_HEADER) > array_size) {
4685
0
            offset += sizeof(NV_RAM_HEADER);
4686
0
            goto exit_size;
4687
0
        }
4688
69
        if (rc == TPM_RC_SUCCESS) {
4689
69
            rc = TPM_HANDLE_Unmarshal(&nrh.handle, buffer, size);
4690
69
        }
4691
69
        if (rc == TPM_RC_SUCCESS) {
4692
69
            rc = TPMA_NV_Unmarshal(&nrh.attributes, buffer, size);
4693
69
        }
4694
69
        if (rc == TPM_RC_SUCCESS) {
4695
69
            rc = UINT16_Unmarshal(&datasize, buffer, size);
4696
69
        }
4697
69
        if (offset + sizeof(NV_RAM_HEADER) + datasize > array_size) {
4698
0
            offset += sizeof(NV_RAM_HEADER) + datasize;
4699
0
            goto exit_size;
4700
0
        }
4701
69
        if (rc == TPM_RC_SUCCESS && datasize > 0) {
4702
            /* append the data */
4703
66
            rc = Array_Unmarshal((BYTE *)array + offset + sizeof(NV_RAM_HEADER),
4704
66
                                 datasize, buffer, size);
4705
66
        }
4706
69
        if (rc == TPM_RC_SUCCESS) {
4707
            /* fix up size in case it is architecture-dependent */
4708
69
            nrh.size = sizeof(nrh) + datasize;
4709
69
            offset += nrh.size;
4710
            /* copy header into possibly misaligned address in NVRAM */
4711
69
            *nrhp = nrh;
4712
69
        }
4713
69
    }
4714
4715
    /* version 2 starts having indicator for next versions that we can skip;
4716
       this allows us to downgrade state */
4717
24.1k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
4718
24.1k
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
4719
24.1k
                        "INDEX_ORDERLY_RAM", "version 3 or later");
4720
        /* future versions nest-append here */
4721
0
    }
4722
4723
24.1k
skip_future_versions:
4724
24.1k
    return rc;
4725
4726
0
exit_size:
4727
0
    TPMLIB_LogTPM2Error("INDEX_ORDERLY_RAM:"
4728
0
                        "Insufficient space to write to offset %u;"
4729
0
                        "Source had %u bytes, we have %zu bytes.\n",
4730
0
                        offset, sourceside_size, array_size);
4731
0
    return TPM_RC_SIZE;
4732
24.1k
}
4733
4734
static void
4735
USER_NVRAM_Display(const char *msg)
4736
0
{
4737
0
    NV_REF entryRef = NV_USER_DYNAMIC;
4738
0
    UINT32 entrysize;
4739
0
    UINT64 offset = 0;
4740
0
    TPM_HANDLE handle;
4741
0
    UINT32 datasize;
4742
0
    NV_INDEX nvi;
4743
0
    OBJECT obj;
4744
0
    UINT64 maxCount;
4745
0
4746
0
    fprintf(stderr, "USER_NVRAM contents %s:\n", msg);
4747
0
4748
0
    while (TRUE) {
4749
0
        /* 1st: entrysize */
4750
0
        NvRead(&entrysize, entryRef, sizeof(entrysize));
4751
0
        fprintf(stderr, " offset: %5"PRIu32"   entry size: %5u ",
4752
0
                (UINT32)(entryRef - NV_USER_DYNAMIC), entrysize);
4753
0
        offset = sizeof(UINT32);
4754
0
4755
0
        if (entrysize == 0)
4756
0
            break;
4757
0
4758
0
        /* 2nd: the handle -- it will tell us what datatype this is */
4759
0
        NvRead(&handle, entryRef + offset, sizeof(handle));
4760
0
        fprintf(stderr, "handle: 0x%08x ", handle);
4761
0
4762
0
        switch (HandleGetType(handle)) {
4763
0
        case TPM_HT_NV_INDEX:
4764
0
            fprintf(stderr, " (NV_INDEX)  ");
4765
0
            /* NV_INDEX has the index again at offset 0! */
4766
0
            NvReadNvIndexInfo(entryRef + offset, &nvi);
4767
0
            datasize = entrysize - sizeof(UINT32) - sizeof(nvi);
4768
0
            fprintf(stderr, " datasize: %u\n", datasize);
4769
0
            break;
4770
0
        case TPM_HT_PERSISTENT:
4771
0
            fprintf(stderr, " (PERSISTENT)");
4772
0
4773
0
            NvReadObject(entryRef + offset, &obj);
4774
0
            fprintf(stderr, " sizeof(obj): %zu  entrysize: %u\n", sizeof(obj), entrysize);
4775
0
            break;
4776
0
#if CC_NV_DefineSpace2
4777
0
# error Missing support for TPM_HT_PERMANENT_NV
4778
0
#endif
4779
0
        default:
4780
0
            TPMLIB_LogTPM2Error("USER_NVRAM: Corrupted handle: %08x\n", handle);
4781
0
        }
4782
0
        /* advance to next entry */
4783
0
        entryRef += entrysize;
4784
0
    }
4785
0
    fprintf(stderr, "\n");
4786
0
4787
0
    NvRead(&maxCount, entryRef + offset, sizeof(maxCount));
4788
0
    fprintf(stderr, " maxCount:   %"PRIu64"\n", maxCount);
4789
0
    fprintf(stderr, "-----------------------------\n");
4790
0
}
4791
4792
48.5k
#define USER_NVRAM_VERSION 2
4793
48.5k
#define USER_NVRAM_MAGIC   0x094f22c3
4794
static UINT32
4795
USER_NVRAM_Marshal(BYTE **buffer, INT32 *size, struct RuntimeProfile *RuntimeProfile)
4796
24.3k
{
4797
24.3k
    UINT32 written;
4798
24.3k
    UINT32 entrysize;
4799
24.3k
    UINT64 offset;
4800
24.3k
    NV_REF entryRef = NV_USER_DYNAMIC;
4801
24.3k
    NV_INDEX nvi;
4802
24.3k
    UINT64 maxCount;
4803
24.3k
    TPM_HANDLE handle;
4804
24.3k
    OBJECT obj;
4805
24.3k
    UINT32 datasize;
4806
24.3k
    UINT64 sourceside_size = NV_USER_DYNAMIC_END - NV_USER_DYNAMIC;
4807
24.3k
    BLOCK_SKIP_INIT;
4808
4809
24.3k
    if (FALSE)
4810
0
        USER_NVRAM_Display("before marshalling");
4811
4812
24.3k
    written = NV_HEADER_Marshal(buffer, size,
4813
24.3k
                                USER_NVRAM_VERSION, USER_NVRAM_MAGIC,
4814
24.3k
                                1);
4815
4816
24.3k
    written += UINT64_Marshal(&sourceside_size, buffer, size);
4817
4818
24.5k
    while (TRUE) {
4819
        /* 1st: entrysize */
4820
24.5k
        NvRead(&entrysize, entryRef, sizeof(entrysize));
4821
24.5k
        offset = sizeof(UINT32);
4822
4823
        /* entrysize is in native format now */
4824
24.5k
        written += UINT32_Marshal(&entrysize, buffer, size);
4825
24.5k
        if (entrysize == 0)
4826
24.3k
            break;
4827
4828
        /* 2nd: the handle -- it will tell us what datatype this is */
4829
219
        NvRead(&handle, entryRef + offset, sizeof(handle));
4830
219
        written += TPM_HANDLE_Marshal(&handle, buffer, size);
4831
4832
219
        switch (HandleGetType(handle)) {
4833
219
        case TPM_HT_NV_INDEX:
4834
            /* NV_INDEX has the index again at offset 0! */
4835
219
            NvReadNvIndexInfo(entryRef + offset, &nvi);
4836
219
            offset += sizeof(nvi);
4837
4838
219
            written += NV_INDEX_Marshal(&nvi, buffer, size);
4839
            /* after that: bulk data */
4840
219
            datasize = entrysize - sizeof(UINT32) - sizeof(nvi);
4841
219
            written += UINT32_Marshal(&datasize, buffer, size);
4842
219
            if (datasize > 0) {
4843
147
                BYTE buf[datasize];
4844
147
                NvRead(buf, entryRef + offset, datasize);
4845
147
                written += Array_Marshal(buf, datasize, buffer, size);
4846
147
            }
4847
219
            break;
4848
0
        case TPM_HT_PERSISTENT:
4849
0
            NvReadObject(entryRef + offset, &obj);
4850
0
            written += ANY_OBJECT_Marshal(&obj, buffer, size, RuntimeProfile);
4851
0
            break;
4852
#if CC_NV_DefineSpace2
4853
# error Missing support for TPM_HT_PERMANENT_NV
4854
#endif
4855
0
        default:
4856
0
            TPMLIB_LogTPM2Error("USER_NVRAM: Corrupted handle: %08x\n", handle);
4857
219
        }
4858
        /* advance to next entry */
4859
219
        entryRef += entrysize;
4860
219
    }
4861
24.3k
    NvRead(&maxCount, entryRef + offset, sizeof(maxCount));
4862
24.3k
    written += UINT64_Marshal(&maxCount, buffer, size);
4863
4864
24.3k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
4865
    /* future versions append below this line */
4866
4867
24.3k
    BLOCK_SKIP_WRITE_POP(size);
4868
4869
24.3k
    BLOCK_SKIP_WRITE_CHECK;
4870
4871
24.3k
    return written;
4872
24.3k
}
4873
4874
/*
4875
 * USER_NVRAM_Unmarshal:
4876
 *
4877
 * Unmarshal the byte stream directly into the NVRAM. Ensure that the
4878
 * the data fit into the user NVRAM before writing them.
4879
 *
4880
 * This function fails if there's not enough NVRAM to write the data into
4881
 * or if an unknown handle type was encountered.
4882
 */
4883
static TPM_RC
4884
USER_NVRAM_Unmarshal(BYTE **buffer, INT32 *size)
4885
24.1k
{
4886
24.1k
    TPM_RC rc = TPM_RC_SUCCESS;
4887
24.1k
    NV_HEADER hdr;
4888
24.1k
    NV_REF entryRef = NV_USER_DYNAMIC;
4889
24.1k
    UINT32 entrysize;
4890
24.1k
    UINT64 offset, o = 0;
4891
24.1k
    NV_INDEX nvi = {
4892
24.1k
        .publicArea.attributes = 0, // Coverity
4893
24.1k
    };
4894
24.1k
    UINT64 maxCount;
4895
24.1k
    TPM_HANDLE handle;
4896
24.1k
    OBJECT obj;
4897
24.1k
    UINT32 datasize = 0;
4898
24.1k
    UINT64 sourceside_size;
4899
24.1k
    UINT64 array_size = NV_USER_DYNAMIC_END - NV_USER_DYNAMIC;
4900
24.1k
    UINT64 entrysize_offset;
4901
4902
24.1k
    if (rc == TPM_RC_SUCCESS) {
4903
24.1k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
4904
24.1k
                                 USER_NVRAM_VERSION,
4905
24.1k
                                 USER_NVRAM_MAGIC);
4906
24.1k
    }
4907
24.1k
    if (rc == TPM_RC_SUCCESS) {
4908
24.1k
        rc = UINT64_Unmarshal(&sourceside_size, buffer, size);
4909
24.1k
    }
4910
4911
24.3k
    while (rc == TPM_RC_SUCCESS) {
4912
        /* 1st: entrysize */
4913
24.3k
        if (o + sizeof(UINT32) > array_size) {
4914
0
            o += sizeof(UINT32);
4915
0
            goto exit_size;
4916
0
        }
4917
24.3k
        if (rc == TPM_RC_SUCCESS) {
4918
24.3k
            rc = UINT32_Unmarshal(&entrysize, buffer, size);
4919
24.3k
        }
4920
24.3k
        if (rc == TPM_RC_SUCCESS) {
4921
            /* the entrysize also depends on the sizeof(nvi); we may have to
4922
               update it if sizeof(nvi) changed between versions */
4923
24.3k
            entrysize_offset = o;
4924
24.3k
            NvWrite(entryRef + o, sizeof(entrysize), &entrysize);
4925
24.3k
            offset = sizeof(UINT32);
4926
24.3k
            if (entrysize == 0)
4927
24.1k
                break;
4928
4929
            /* 2nd: handle */
4930
219
            rc = TPM_HANDLE_Unmarshal(&handle, buffer, size);
4931
219
        }
4932
4933
219
        if (rc == TPM_RC_SUCCESS) {
4934
219
            switch (HandleGetType(handle)) {
4935
219
            case TPM_HT_NV_INDEX:
4936
                /* we need to read the handle again */
4937
219
                if (rc == TPM_RC_SUCCESS &&
4938
219
                    o + offset + sizeof(nvi) > array_size) {
4939
0
                     o += offset + sizeof(nvi);
4940
0
                     goto exit_size;
4941
0
                }
4942
219
                if (rc == TPM_RC_SUCCESS) {
4943
219
                    rc = NV_INDEX_Unmarshal(&nvi, buffer, size);
4944
219
                    if (rc == TPM_RC_SUCCESS) {
4945
219
                        NvWrite(entryRef + o + offset, sizeof(nvi), &nvi);
4946
219
                        offset += sizeof(nvi);
4947
219
                    }
4948
219
                }
4949
219
                if (rc == TPM_RC_SUCCESS) {
4950
219
                    rc = UINT32_Unmarshal(&datasize, buffer, size);
4951
219
                }
4952
219
                if (rc == TPM_RC_SUCCESS) {
4953
                    /*
4954
                     * datasize cannot exceed MAX_NV_INDEX_SIZE (2048 bytes)
4955
                     */
4956
219
                    if (datasize > MAX_NV_INDEX_SIZE) {
4957
0
                        TPMLIB_LogTPM2Error("datasize for NV_INDEX too "
4958
0
                                            "large: %u\n", datasize);
4959
0
                        rc = TPM_RC_SIZE;
4960
0
                    }
4961
219
                }
4962
219
                if (rc == TPM_RC_SUCCESS &&
4963
219
                    o + offset + datasize > array_size) {
4964
0
                    o += offset + datasize;
4965
0
                    goto exit_size;
4966
0
                }
4967
219
                if (rc == TPM_RC_SUCCESS && datasize > 0) {
4968
147
                    BYTE buf[MAX_NV_INDEX_SIZE];
4969
147
                    rc = Array_Unmarshal(buf, datasize, buffer, size);
4970
147
                    NvWrite(entryRef + o + offset, datasize, buf);
4971
147
                    offset += datasize;
4972
4973
                    /* update the entry size; account for expanding nvi */
4974
147
                    entrysize = sizeof(UINT32) + sizeof(nvi) + datasize;
4975
147
                }
4976
219
                break;
4977
0
            case TPM_HT_PERSISTENT:
4978
0
                if (rc == TPM_RC_SUCCESS &&
4979
0
                    o + offset + sizeof(TPM_HANDLE) > array_size) {
4980
0
                    o += offset + sizeof(TPM_HANDLE);
4981
0
                    goto exit_size;
4982
0
                }
4983
0
                if (rc == TPM_RC_SUCCESS) {
4984
0
                    BYTE objBuffer[MAX_MARSHALLED_OBJECT_SIZE];
4985
0
                    UINT32 marshalledObjectSize;
4986
4987
0
                    NvWrite(entryRef + o + offset, sizeof(handle), &handle);
4988
0
                    offset += sizeof(TPM_HANDLE);
4989
4990
0
                    memset(&obj, 0, sizeof(obj));
4991
0
                    rc = ANY_OBJECT_Unmarshal(&obj, buffer, size, true);
4992
0
                    pAssert(rc == TPM_RC_SUCCESS);
4993
                    // convert the OBJECT into a buffer to copy into NVRAM
4994
0
                    marshalledObjectSize = NvObjectToBuffer(&obj, objBuffer, sizeof(objBuffer));
4995
4996
0
                    if (o + offset + marshalledObjectSize > array_size) {
4997
0
                        o += offset + marshalledObjectSize;
4998
0
                        goto exit_size;
4999
0
                    }
5000
0
                    NvWrite(entryRef + o + offset, marshalledObjectSize, objBuffer);
5001
0
                    offset += marshalledObjectSize;
5002
5003
0
                    entrysize = sizeof(UINT32) + sizeof(TPM_HANDLE) + marshalledObjectSize;
5004
0
                }
5005
0
                break;
5006
0
            default:
5007
0
                TPMLIB_LogTPM2Error("USER_NVRAM: "
5008
0
                                    "Read handle 0x%08x of unknown type\n",
5009
0
                                    handle);
5010
0
                rc = TPM_RC_HANDLE;
5011
219
            }
5012
5013
219
            if (rc == TPM_RC_SUCCESS) {
5014
219
                NvWrite(entryRef + entrysize_offset, sizeof(entrysize), &entrysize);
5015
219
            }
5016
219
        }
5017
219
        if (rc == TPM_RC_SUCCESS) {
5018
219
            o += offset;
5019
219
        }
5020
219
    }
5021
24.1k
    if (rc == TPM_RC_SUCCESS &&
5022
24.1k
        o + offset + sizeof(UINT64) > array_size) {
5023
0
        o += offset + sizeof(UINT64);
5024
0
        goto exit_size;
5025
0
    }
5026
24.1k
    if (rc == TPM_RC_SUCCESS) {
5027
24.1k
        rc = UINT64_Unmarshal(&maxCount, buffer, size);
5028
24.1k
        NvWrite(entryRef + o + offset, sizeof(maxCount), &maxCount);
5029
24.1k
    }
5030
5031
    /* version 2 starts having indicator for next versions that we can skip;
5032
       this allows us to downgrade state */
5033
24.1k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
5034
24.1k
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
5035
24.1k
                        "USER_NVRAM", "version 3 or later");
5036
        /* future versions nest-append here */
5037
0
    }
5038
5039
24.1k
skip_future_versions:
5040
5041
24.1k
    if (FALSE)
5042
0
        USER_NVRAM_Display("after unmarshalling");
5043
5044
24.1k
    return rc;
5045
5046
0
exit_size:
5047
0
    TPMLIB_LogTPM2Error("USER_NVRAM:"
5048
0
                        "Insufficient space to write to offset %"PRIu64";"
5049
0
                        "Source had %"PRIu64" bytes, we have %"PRIu64" "
5050
0
                        "bytes.\n",
5051
0
                        o, sourceside_size, array_size);
5052
0
    return TPM_RC_SIZE;
5053
24.1k
}
5054
5055
/*
5056
 * Write out all persistent data by reading them from the NVRAM
5057
 * and then writing them out.
5058
 *
5059
 * - PERSISTENT_DATA  (NV_PERSISTENT_DATA)
5060
 * - ORDERLY_DATA     (NV_STATE_RESET_DATA)
5061
 * - STATE_RESET_DATA (NV_STATE_RESET_DATA)
5062
 * - STATE_CLEAR_DATA (NV_STATE_CLEAR_DATA)
5063
 * - indexOrderlyRAM  (NV_INDEX_RAM_DATA)
5064
 * - NVRAM locations  (NV_USER_DYNAMIC)
5065
 */
5066
24.1k
#define PERSISTENT_ALL_VERSION 4
5067
97.0k
#define PERSISTENT_ALL_MAGIC   0xab364723
5068
UINT32
5069
PERSISTENT_ALL_Marshal(BYTE **buffer, INT32 *size)
5070
24.3k
{
5071
24.3k
    struct RuntimeProfile *RuntimeProfile = &g_RuntimeProfile;
5072
24.3k
    const char *profileJSON;
5073
24.3k
    UINT32 magic;
5074
24.3k
    PERSISTENT_DATA pd;
5075
24.3k
    ORDERLY_DATA od;
5076
24.3k
    STATE_RESET_DATA srd;
5077
24.3k
    STATE_CLEAR_DATA scd;
5078
24.3k
    UINT32 written = 0;
5079
24.3k
    BYTE indexOrderlyRam[sizeof(s_indexOrderlyRam)];
5080
24.3k
    BLOCK_SKIP_INIT;
5081
24.3k
    BOOL writeSuState;
5082
24.3k
    UINT16 blob_version;
5083
5084
24.3k
    NvRead(&pd, NV_PERSISTENT_DATA, sizeof(pd));
5085
24.3k
    NvRead(&od, NV_ORDERLY_DATA, sizeof(od));
5086
24.3k
    NvRead(&srd, NV_STATE_RESET_DATA, sizeof(srd));
5087
24.3k
    NvRead(&scd, NV_STATE_CLEAR_DATA, sizeof(scd));
5088
5089
    /* indexOrderlyRam was never endianess-converted; so it's native */
5090
24.3k
    NvRead(indexOrderlyRam, NV_INDEX_RAM_DATA, sizeof(indexOrderlyRam));
5091
5092
    /* If we previously read state that did not contain a profile then
5093
     * we don't want to upgrade the state unnecessarily but still write
5094
     * it as v3.
5095
     */
5096
24.3k
    switch (RuntimeProfile->stateFormatLevel) {
5097
24.3k
    case 1:
5098
24.3k
        blob_version = 3;
5099
24.3k
        break;
5100
0
    default:
5101
0
        blob_version = 4; /* since stateFormatLevel 2 */
5102
0
        break;
5103
24.3k
    }
5104
5105
24.3k
    if (RuntimeProfileWasNullProfile(RuntimeProfile) && blob_version != 3)
5106
24.3k
        assert(false);
5107
24.3k
    else if (!RuntimeProfileWasNullProfile(RuntimeProfile) && blob_version == 3)
5108
24.3k
        assert(false);
5109
5110
24.3k
    written = NV_HEADER_Marshal(buffer, size,
5111
24.3k
                                blob_version,
5112
24.3k
                                PERSISTENT_ALL_MAGIC, blob_version);
5113
24.3k
    if (blob_version >= 4) {
5114
0
        profileJSON = RuntimeProfileGetJSON(RuntimeProfile);
5115
0
        assert(profileJSON);
5116
0
        written += String_Marshal(profileJSON, buffer, size); // since v4
5117
0
    }
5118
24.3k
    written += PACompileConstants_Marshal(buffer, size);
5119
24.3k
    written += PERSISTENT_DATA_Marshal(&pd, buffer, size, RuntimeProfile);
5120
24.3k
    written += ORDERLY_DATA_Marshal(&od, buffer, size);
5121
24.3k
    writeSuState = (pd.orderlyState & TPM_SU_STATE_MASK) == TPM_SU_STATE;
5122
    /* starting with v3 we only write STATE_RESET and STATE_CLEAR if needed */
5123
24.3k
    if (writeSuState) {
5124
3
        written += STATE_RESET_DATA_Marshal(&srd, buffer, size);
5125
3
        written += STATE_CLEAR_DATA_Marshal(&scd, buffer, size);
5126
3
    }
5127
24.3k
    written += INDEX_ORDERLY_RAM_Marshal(indexOrderlyRam, sizeof(indexOrderlyRam),
5128
24.3k
                                         buffer, size);
5129
24.3k
    written += USER_NVRAM_Marshal(buffer, size, RuntimeProfile);
5130
5131
24.3k
    written += BLOCK_SKIP_WRITE_PUSH(TRUE, buffer, size);
5132
    /* future versions append below this line */
5133
5134
24.3k
    BLOCK_SKIP_WRITE_POP(size);
5135
5136
24.3k
    magic = PERSISTENT_ALL_MAGIC;
5137
24.3k
    written += UINT32_Marshal(&magic, buffer, size);
5138
5139
24.3k
    BLOCK_SKIP_WRITE_CHECK;
5140
5141
24.3k
    return written;
5142
24.3k
}
5143
5144
TPM_RC
5145
PERSISTENT_ALL_Unmarshal(BYTE **buffer, INT32 *size)
5146
24.1k
{
5147
24.1k
    TPM_RC rc = TPM_RC_SUCCESS;
5148
24.1k
    NV_HEADER hdr;
5149
24.1k
    PERSISTENT_DATA pd;
5150
24.1k
    ORDERLY_DATA od;
5151
24.1k
    STATE_RESET_DATA srd;
5152
24.1k
    STATE_CLEAR_DATA scd;
5153
24.1k
    BYTE indexOrderlyRam[sizeof(s_indexOrderlyRam)];
5154
24.1k
    unsigned int stateFormatLevel = 0; // ignored
5155
24.1k
    BOOL readSuState = false;
5156
24.1k
    char *profileJSON = NULL;
5157
5158
24.1k
    memset(&pd, 0, sizeof(pd));
5159
24.1k
    memset(&od, 0, sizeof(od));
5160
24.1k
    memset(&srd, 0, sizeof(srd));
5161
24.1k
    memset(&scd, 0, sizeof(scd));
5162
24.1k
    memset(indexOrderlyRam, 0, sizeof(indexOrderlyRam));
5163
5164
24.1k
    if (rc == TPM_RC_SUCCESS) {
5165
24.1k
        rc = NV_HEADER_Unmarshal(&hdr, buffer, size,
5166
24.1k
                                 PERSISTENT_ALL_VERSION,
5167
24.1k
                                 PERSISTENT_ALL_MAGIC);
5168
24.1k
    }
5169
24.1k
    if (rc == TPM_RC_SUCCESS) {
5170
24.1k
        if (hdr.version >= 4) {
5171
0
            rc = String_Unmarshal(&profileJSON, buffer, size);
5172
0
        }
5173
24.1k
    }
5174
24.1k
    if (rc == TPM_RC_SUCCESS) {
5175
        /* set the profile read from the state */
5176
24.1k
        rc = RuntimeProfileSet(&g_RuntimeProfile, profileJSON, false);
5177
24.1k
    }
5178
24.1k
    if (rc == TPM_RC_SUCCESS) {
5179
        /* allow all algorithms to be unmarshalled */
5180
24.1k
        rc = RuntimeAlgorithmSetProfile(&g_RuntimeProfile.RuntimeAlgorithm, NULL, &stateFormatLevel, ~0);
5181
24.1k
    }
5182
24.1k
    if (rc == TPM_RC_SUCCESS) {
5183
24.1k
        rc = PACompileConstants_Unmarshal(buffer, size);
5184
24.1k
    }
5185
24.1k
    if (rc == TPM_RC_SUCCESS) {
5186
24.1k
        rc = PERSISTENT_DATA_Unmarshal(&pd, buffer, size);
5187
24.1k
    }
5188
24.1k
    if (rc == TPM_RC_SUCCESS) {
5189
24.1k
        if (hdr.version < 3) {
5190
            /* STATE_RESET and STATE_CLEAR were always written before version 3 */
5191
0
            readSuState = true;
5192
24.1k
        } else {
5193
24.1k
            readSuState = (pd.orderlyState & TPM_SU_STATE_MASK) == TPM_SU_STATE;
5194
24.1k
        }
5195
24.1k
        rc = ORDERLY_DATA_Unmarshal(&od, buffer, size);
5196
24.1k
    }
5197
24.1k
    if (rc == TPM_RC_SUCCESS && readSuState) {
5198
3
        rc = STATE_RESET_DATA_Unmarshal(&srd, buffer, size);
5199
3
    }
5200
24.1k
    if (rc == TPM_RC_SUCCESS && readSuState) {
5201
3
        rc = STATE_CLEAR_DATA_Unmarshal(&scd, buffer, size);
5202
3
    }
5203
24.1k
    if (rc == TPM_RC_SUCCESS) {
5204
24.1k
        rc = INDEX_ORDERLY_RAM_Unmarshal(indexOrderlyRam, sizeof(indexOrderlyRam),
5205
24.1k
                                         buffer, size);
5206
24.1k
    }
5207
24.1k
    if (rc == TPM_RC_SUCCESS) {
5208
        /* this will write it into NVRAM right away */
5209
24.1k
        rc = USER_NVRAM_Unmarshal(buffer, size);
5210
        /* if rc == TPM_RC_SUCCESS, we know that there is enough
5211
           NVRAM to fit everything. */
5212
24.1k
    }
5213
5214
    /* version 2 starts having indicator for next versions that we can skip;
5215
       this allows us to downgrade state */
5216
24.1k
    if (rc == TPM_RC_SUCCESS && hdr.version >= 2) {
5217
24.1k
        BLOCK_SKIP_READ(skip_future_versions, FALSE, buffer, size,
5218
24.1k
                        "PERSISTENT_ALL", "version 3 or later");
5219
        /* future versions nest-append here */
5220
0
    }
5221
5222
24.1k
skip_future_versions:
5223
24.1k
    if (rc == TPM_RC_SUCCESS) {
5224
24.1k
        rc = UINT32_Unmarshal_Check(&hdr.magic,
5225
24.1k
                               PERSISTENT_ALL_MAGIC, buffer, size,
5226
24.1k
                               "PERSISTENT_ALL_MAGIC after USER_NVRAM");
5227
24.1k
    }
5228
5229
24.1k
    if (rc == TPM_RC_SUCCESS) {
5230
24.1k
        NvWrite(NV_PERSISTENT_DATA, sizeof(pd), &pd);
5231
24.1k
        NvWrite(NV_ORDERLY_DATA, sizeof(od), &od);
5232
24.1k
        NvWrite(NV_STATE_RESET_DATA, sizeof(srd), &srd);
5233
24.1k
        NvWrite(NV_STATE_CLEAR_DATA, sizeof(scd), &scd);
5234
24.1k
        NvWrite(NV_INDEX_RAM_DATA, sizeof(indexOrderlyRam), indexOrderlyRam);
5235
        /* Activate a profile read from the state of the TPM 2 */
5236
24.1k
        rc = RuntimeProfileSet(&g_RuntimeProfile, profileJSON, false);
5237
24.1k
    }
5238
5239
24.1k
    free(profileJSON);
5240
5241
24.1k
    return rc;
5242
24.1k
}
5243
5244
void
5245
NVShadowRestore(void)
5246
6.04k
{
5247
6.04k
    if (shadow.pcrAllocatedIsNew) {
5248
6.04k
        gp.pcrAllocated = shadow.pcrAllocated;
5249
6.04k
        shadow.pcrAllocatedIsNew = FALSE;
5250
6.04k
    }
5251
6.04k
}