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 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 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