1aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler * Use of this source code is governed by a BSD-style license that can be
3aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler * found in the LICENSE file.
4aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler *
5aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler * Tests for tpm_bootmode functions
6aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler */
7aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
80c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson#include <stdint.h>
9aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler#include <stdio.h>
10aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler#include <stdlib.h>
11aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler#include <string.h>
12aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
13aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler#define _STUB_IMPLEMENTATION_  /* So we can use memset() ourselves */
14aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
15aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler#include "test_common.h"
16aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler#include "utility.h"
17aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler#include "tpm_bootmode.h"
18aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
19aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spanglerextern const char* kBootStateSHA1Digests[];
20aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
21f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson/* Last in_digest passed to TlclExtend() for each PCR */
22f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardsonstatic const uint8_t *last_in[20];
23aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
24aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler/* Return value to pass for TlclExtend() */
25f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardsonstatic uint32_t extend_returns;
26aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
27f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson/* How many calls to TlclExtend() should one SetTPMBootModeState() make? */
28f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardsonstatic int expected_extend_count;
29f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson/* How many did we get? */
30f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardsonstatic int actual_extend_count;
31f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson
32f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardsonstatic GoogleBinaryBlockHeader gbb_v1 = {
33f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	.major_version = GBB_MAJOR_VER,
34f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	.minor_version = 1,
35f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson};
36aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
37f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardsonstatic GoogleBinaryBlockHeader gbb_v2 = {
38f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	.major_version = GBB_MAJOR_VER,
39f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	.minor_version = 2,
40f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	.hwid_digest = {1, 2, 3, 4,},
41f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson};
42aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
43f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson/* Mocked TlclExtend() function for testing */
44f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardsonuint32_t TlclExtend(int pcr_num, const uint8_t *in_digest,
45f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson		    uint8_t *out_digest)
46f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson{
47f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	/* Should be using correct pcr */
48f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	TEST_EQ(pcr_num, actual_extend_count, "TlclExtend pcr_num");
49aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
50f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	last_in[actual_extend_count] = in_digest;
51f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson
52f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	actual_extend_count++;
53f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	return extend_returns;
54aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler}
55aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
56aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
57aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler/* Test setting TPM boot mode state */
58f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardsonstatic void BootStateTest(void)
59f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson{
60f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	int recdev;
61f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	int flags;
62f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	int index;
63f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	char what[128];
64f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson
65f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	/* Test all permutations of developer and recovery mode */
66f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	for (recdev = 0; recdev < 4; recdev++) {
67f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson		/* Exhaustively test all permutations of key block flags
68f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson		 * currently defined in vboot_struct.h (KEY_BLOCK_FLAG_*) */
69f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson		for (flags = 0; flags < 16; flags++) {
70f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			index = recdev * 3;
71f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			if (6 == flags)
72f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				index += 2;
73f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			else if (7 == flags)
74f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				index += 1;
75f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson
76f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			/* Passing a null pointer for GBB */
77f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			memset(last_in, 0, sizeof(last_in));
78f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			actual_extend_count = 0;
79f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			expected_extend_count = 1;
80f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			TEST_EQ(SetTPMBootModeState(recdev & 2, recdev & 1,
81f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson						    flags, 0), 0,
82f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				"SetTPMBootModeState return (gbb0)");
83f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			snprintf(what, sizeof(what),
84f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				 "SetTPMBootModeState %d, 0x%x (gbb0)",
85f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				 recdev, flags);
86f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			TEST_PTR_EQ(last_in[0],
87f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				    kBootStateSHA1Digests[index], what);
88f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			TEST_EQ(expected_extend_count, actual_extend_count,
89f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				"Expected TlclExtend call count (gbb0)");
90f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			snprintf(what, sizeof(what),
91f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				 "SetTPMBootModeState %d, 0x%x (gbb0) PCR1",
92f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				 recdev, flags);
93f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			TEST_PTR_EQ(last_in[1], NULL, what);
94f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson
95f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			/* GBB v1.1 - should be exactly the same */
96f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			memset(last_in, 0, sizeof(last_in));
97f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			actual_extend_count = 0;
98f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			expected_extend_count = 1;
99f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			TEST_EQ(SetTPMBootModeState(recdev & 2, recdev & 1,
100f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson						    flags, &gbb_v1), 0,
101f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				"SetTPMBootModeState return (gbb1)");
102f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			snprintf(what, sizeof(what),
103f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				 "SetTPMBootModeState %d, 0x%x (gbb1)",
104f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				 recdev, flags);
105f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			TEST_PTR_EQ(last_in[0],
106f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				    kBootStateSHA1Digests[index], what);
107f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			TEST_EQ(expected_extend_count, actual_extend_count,
108f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				"Expected TlclExtend call count (gbb1)");
109f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			snprintf(what, sizeof(what),
110f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				 "SetTPMBootModeState %d, 0x%x (gbb1) PCR1",
111f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				 recdev, flags);
112f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			TEST_PTR_EQ(last_in[1], NULL, what);
113f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson
114f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			/* GBB v1.2 - should extend PCR1 with HWID digest */
115f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			memset(last_in, 0, sizeof(last_in));
116f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			actual_extend_count = 0;
117f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			expected_extend_count = 2;
118f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			TEST_EQ(SetTPMBootModeState(recdev & 2, recdev & 1,
119f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson						    flags, &gbb_v2), 0,
120f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				"SetTPMBootModeState return (gbb2)");
121f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			snprintf(what, sizeof(what),
122f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				 "SetTPMBootModeState %d, 0x%x (gbb2)",
123f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				 recdev, flags);
124f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			TEST_PTR_EQ(last_in[0],
125f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				    kBootStateSHA1Digests[index], what);
126f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			TEST_EQ(expected_extend_count, actual_extend_count,
127f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				"Expected TlclExtend call count (gbb2)");
128f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			snprintf(what, sizeof(what),
129f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				 "SetTPMBootModeState %d, 0x%x (gbb2) PCR1",
130f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson				 recdev, flags);
131f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson			TEST_PTR_EQ(last_in[1], gbb_v2.hwid_digest, what);
132f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson		}
133f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	}
134f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson
135f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	extend_returns = 1;
136f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	actual_extend_count = 0;
137f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	expected_extend_count = 1;
138f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	TEST_EQ(SetTPMBootModeState(0, 0, 0, 0), 1,
139f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson		"SetTPMBootModeState error");
140aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler}
141aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
142f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardsonint main(int argc, char *argv[])
143f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson{
144f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	int error_code = 0;
145aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
146f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	BootStateTest();
147aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
148f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	if (!gTestSuccess)
149f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson		error_code = 255;
150aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler
151f4f395e1ca724ef8795cfe86a9edbf15f14eacd1Bill Richardson	return error_code;
152aeb8632258f240c9350716bdfe149d1f3c5c54a1Randall Spangler}
153