Home | History | Annotate | Download | only in lib
      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