1 /* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  */
5 
6 /* Non-volatile storage routines.
7  */
8 #include "sysincludes.h"
9 
10 #include "crc8.h"
11 #include "utility.h"
12 #include "vboot_common.h"
13 #include "vboot_nvstorage.h"
14 #include "rollback_index.h"
15 
16 /* These are the fields of the nvram that we want to back up. */
17 static const VbNvParam backup_params[] = {
18 	VBNV_KERNEL_FIELD,
19 	VBNV_LOCALIZATION_INDEX,
20 	VBNV_DEV_BOOT_USB,
21 	VBNV_DEV_BOOT_LEGACY,
22 	VBNV_DEV_BOOT_SIGNED_ONLY,
23 };
24 
25 /* We can't back things up if there isn't enough storage. */
26 BUILD_ASSERT(VBNV_BLOCK_SIZE <= BACKUP_NV_SIZE);
27 
RestoreNvFromBackup(VbNvContext * vnc)28 int RestoreNvFromBackup(VbNvContext *vnc)
29 {
30 	VbNvContext bvnc;
31 	uint32_t value;
32 	int i;
33 
34 	VBDEBUG(("TPM: %s()\n", __func__));
35 
36 	if (TPM_SUCCESS != RollbackBackupRead(bvnc.raw))
37 		return 1;
38 
39 	VbNvSetup(&bvnc);
40 	if (bvnc.regenerate_crc) {
41 		VBDEBUG(("TPM: Oops, backup is no good.\n"));
42 		return 1;
43 	}
44 
45 	for (i = 0; i < ARRAY_SIZE(backup_params); i++) {
46 		VbNvGet(&bvnc, backup_params[i], &value);
47 		VbNvSet(vnc, backup_params[i], value);
48 	}
49 
50 	/* VbNvTeardown(&bvnc); is not needed. We're done with it. */
51 	return 0;
52 }
53 
SaveNvToBackup(VbNvContext * vnc)54 int SaveNvToBackup(VbNvContext *vnc)
55 {
56 	VbNvContext bvnc;
57 	uint32_t value;
58 	int i;
59 
60 	VBDEBUG(("TPM: %s()\n", __func__));
61 
62 	/* Read it first. No point in writing the same data. */
63 	if (TPM_SUCCESS != RollbackBackupRead(bvnc.raw))
64 		return 1;
65 
66 	VbNvSetup(&bvnc);
67 	VBDEBUG(("TPM: existing backup is %s\n",
68 		 bvnc.regenerate_crc ? "bad" : "good"));
69 
70 	for (i = 0; i < ARRAY_SIZE(backup_params); i++) {
71 		VbNvGet(vnc, backup_params[i], &value);
72 		VbNvSet(&bvnc, backup_params[i], value);
73 	}
74 
75 	VbNvTeardown(&bvnc);
76 
77 	if (!bvnc.raw_changed) {
78 		VBDEBUG(("TPM: Nothing's changed, not writing backup\n"));
79 		/* Clear the request flag, since we're happy. */
80 		VbNvSet(vnc, VBNV_BACKUP_NVRAM_REQUEST, 0);
81 		return 0;
82 	}
83 
84 	if (TPM_SUCCESS == RollbackBackupWrite(bvnc.raw)) {
85 		/* Clear the request flag if we wrote successfully too */
86 		VbNvSet(vnc, VBNV_BACKUP_NVRAM_REQUEST, 0);
87 		return 0;
88 	}
89 
90 	VBDEBUG(("TPM: Sorry, couldn't write backup.\n"));
91 	return 1;
92 }
93