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