1c0e3742996a84d3c503cfa002b09a0831bcb2c32Randall Spangler/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler * Use of this source code is governed by a BSD-style license that can be
3542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler * found in the LICENSE file.
4542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler */
5542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler
6a3d70a3d2b5c052db039d097aaffa42008da24b5J. Richard Barnette#include <stddef.h>
7542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler#include <stdio.h>
8542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler#include <string.h>
92008423d5fb291eb7628389dcb04fe6d5ebb75fcVadim Bendebury#include <sys/types.h>
102008423d5fb291eb7628389dcb04fe6d5ebb75fcVadim Bendebury#include <sys/stat.h>
112008423d5fb291eb7628389dcb04fe6d5ebb75fcVadim Bendebury#include <unistd.h>
122008423d5fb291eb7628389dcb04fe6d5ebb75fcVadim Bendebury#include <ctype.h>
13542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler
14542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler#include "host_common.h"
15542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler
16542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler#include "crossystem.h"
17eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler#include "crossystem_arch.h"
18542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler#include "utility.h"
19542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler#include "vboot_common.h"
20e73302caae852485fdf180baa9a443b74f565dccRandall Spangler#include "vboot_nvstorage.h"
21f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler#include "vboot_struct.h"
22542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler
23196e1772ed9092a679767c0497343799f13d2875Randall Spangler/* Filename for kernel command line */
24196e1772ed9092a679767c0497343799f13d2875Randall Spangler#define KERNEL_CMDLINE_PATH "/proc/cmdline"
25196e1772ed9092a679767c0497343799f13d2875Randall Spangler
26f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler/* Fields that GetVdatString() can get */
27f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spanglertypedef enum VdatStringField {
287141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  VDAT_STRING_TIMERS = 0,           /* Timer values */
297141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  VDAT_STRING_LOAD_FIRMWARE_DEBUG,  /* LoadFirmware() debug information */
30a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler  VDAT_STRING_LOAD_KERNEL_DEBUG,    /* LoadKernel() debug information */
31a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler  VDAT_STRING_MAINFW_ACT            /* Active main firmware */
32f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler} VdatStringField;
33f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
34f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
35f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler/* Fields that GetVdatInt() can get */
36f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spanglertypedef enum VdatIntField {
37cabe6b3514f3228b350a7d07d6cc7cb39eecaaf6Randall Spangler  VDAT_INT_FLAGS = 0,                /* Flags */
38da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler  VDAT_INT_HEADER_VERSION,           /* Header version for VbSharedData */
39da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler  VDAT_INT_DEVSW_BOOT,               /* Dev switch position at boot */
40da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler  VDAT_INT_DEVSW_VIRTUAL,            /* Dev switch is virtual */
41da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler  VDAT_INT_RECSW_BOOT,               /* Recovery switch position at boot */
429dc62178c97b94e5c308f1c36fd0858c316959e5Bill Richardson  VDAT_INT_HW_WPSW_BOOT,             /* Hardware WP switch position at boot */
439dc62178c97b94e5c308f1c36fd0858c316959e5Bill Richardson  VDAT_INT_SW_WPSW_BOOT,             /* Flash chip's WP setting at boot */
44da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler
45cabe6b3514f3228b350a7d07d6cc7cb39eecaaf6Randall Spangler  VDAT_INT_FW_VERSION_TPM,           /* Current firmware version in TPM */
46cabe6b3514f3228b350a7d07d6cc7cb39eecaaf6Randall Spangler  VDAT_INT_KERNEL_VERSION_TPM,       /* Current kernel version in TPM */
47cabe6b3514f3228b350a7d07d6cc7cb39eecaaf6Randall Spangler  VDAT_INT_TRIED_FIRMWARE_B,         /* Tried firmware B due to fwb_tries */
487adcc60e6f5f6db081b9ad6e02288335502a0d77Randall Spangler  VDAT_INT_KERNEL_KEY_VERIFIED,      /* Kernel key verified using
49cabe6b3514f3228b350a7d07d6cc7cb39eecaaf6Randall Spangler                                      * signature, not just hash */
50d11086caf05c692815ae6f90aa83a4fc30d50ed7Daisuke Nojiri  VDAT_INT_RECOVERY_REASON,          /* Recovery reason for current boot */
51d11086caf05c692815ae6f90aa83a4fc30d50ed7Daisuke Nojiri  VDAT_INT_FW_BOOT2                  /* Firmware selection by vboot2 */
52f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler} VdatIntField;
53f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
54f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
5592cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette/* Description of build options that may be specified on the
5692cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette * kernel command line. */
5792cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnettetypedef enum VbBuildOption {
5892cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette  VB_BUILD_OPTION_UNKNOWN,
5992cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette  VB_BUILD_OPTION_DEBUG,
6092cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette  VB_BUILD_OPTION_NODEBUG
6192cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette} VbBuildOption;
6292cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette
639e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spanglerstatic const char *fw_results[] = {"unknown", "trying", "success", "failure"};
6492cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette
65ff3f0006447330228f43ad2da5ec55e1f003f870Randall Spangler/* Masks for kern_nv usage by kernel. */
66d7728233dd7b3d772ce840c5477bcacc536ceb5dRandall Spangler#define KERN_NV_FWUPDATE_TRIES_MASK 0x0000000F
67850b74fa19f6eadd1d3221f484c738f41f993653Bill Richardson#define KERN_NV_BLOCK_DEVMODE_FLAG  0x00000010
68ff3f0006447330228f43ad2da5ec55e1f003f870Randall Spangler/* If you want to use the remaining currently-unused bits in kern_nv
69ff3f0006447330228f43ad2da5ec55e1f003f870Randall Spangler * for something kernel-y, define a new field (the way we did for
70ff3f0006447330228f43ad2da5ec55e1f003f870Randall Spangler * fwupdate_tries).  Don't just modify kern_nv directly, because that
71ff3f0006447330228f43ad2da5ec55e1f003f870Randall Spangler * makes it too easy to accidentally corrupt other sub-fields. */
72850b74fa19f6eadd1d3221f484c738f41f993653Bill Richardson#define KERN_NV_CURRENTLY_UNUSED    0xFFFFFFE0
73d7728233dd7b3d772ce840c5477bcacc536ceb5dRandall Spangler
74c80fe65f9e42aba26077fc93ce43ae6c02b9eb67Randall Spangler/* Return true if the FWID starts with the specified string. */
75eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spanglerint FwidStartsWith(const char *start) {
76a3d70a3d2b5c052db039d097aaffa42008da24b5J. Richard Barnette  char fwid[VB_MAX_STRING_PROPERTY];
77c80fe65f9e42aba26077fc93ce43ae6c02b9eb67Randall Spangler  if (!VbGetSystemPropertyString("fwid", fwid, sizeof(fwid)))
78c80fe65f9e42aba26077fc93ce43ae6c02b9eb67Randall Spangler    return 0;
79c80fe65f9e42aba26077fc93ce43ae6c02b9eb67Randall Spangler
80c80fe65f9e42aba26077fc93ce43ae6c02b9eb67Randall Spangler  return 0 == strncmp(fwid, start, strlen(start));
81c80fe65f9e42aba26077fc93ce43ae6c02b9eb67Randall Spangler}
82c80fe65f9e42aba26077fc93ce43ae6c02b9eb67Randall Spangler
8338201fe1f7c0144578b0d67572a0f2db22b8d0b7Vadim Bendeburystatic int vnc_read;
84c80fe65f9e42aba26077fc93ce43ae6c02b9eb67Randall Spangler
850f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spanglerint VbGetNvStorage(VbNvParam param) {
860f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  uint32_t value;
870f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  int retval;
8838201fe1f7c0144578b0d67572a0f2db22b8d0b7Vadim Bendebury  static VbNvContext cached_vnc;
890f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler
900f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  /* TODO: locking around NV access */
9138201fe1f7c0144578b0d67572a0f2db22b8d0b7Vadim Bendebury  if (!vnc_read) {
9238201fe1f7c0144578b0d67572a0f2db22b8d0b7Vadim Bendebury    if (0 != VbReadNvStorage(&cached_vnc))
9338201fe1f7c0144578b0d67572a0f2db22b8d0b7Vadim Bendebury      return -1;
9438201fe1f7c0144578b0d67572a0f2db22b8d0b7Vadim Bendebury    vnc_read = 1;
9538201fe1f7c0144578b0d67572a0f2db22b8d0b7Vadim Bendebury  }
960f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler
9738201fe1f7c0144578b0d67572a0f2db22b8d0b7Vadim Bendebury  if (0 != VbNvSetup(&cached_vnc))
980f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler    return -1;
9938201fe1f7c0144578b0d67572a0f2db22b8d0b7Vadim Bendebury  retval = VbNvGet(&cached_vnc, param, &value);
10038201fe1f7c0144578b0d67572a0f2db22b8d0b7Vadim Bendebury  if (0 != VbNvTeardown(&cached_vnc))
1010f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler    return -1;
1020f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  if (0 != retval)
1030f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler    return -1;
1040f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler
1050f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  /* TODO: If vnc.raw_changed, attempt to reopen NVRAM for write and
1060f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler   * save the new defaults.  If we're able to, log. */
1070f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  /* TODO: release lock */
1080f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler
1090f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  return (int)value;
1100f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler}
1110f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler
1120f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler
1130f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spanglerint VbSetNvStorage(VbNvParam param, int value) {
1140f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  VbNvContext vnc;
1150f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  int retval = -1;
1160f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  int i;
1170f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler
118eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  if (0 != VbReadNvStorage(&vnc))
1190f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler    return -1;
1200f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler
1210f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  if (0 != VbNvSetup(&vnc))
1220f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler    goto VbSetNvCleanup;
1230f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  i = VbNvSet(&vnc, param, (uint32_t)value);
1240f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  if (0 != VbNvTeardown(&vnc))
1250f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler    goto VbSetNvCleanup;
1260f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  if (0 != i)
1270f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler    goto VbSetNvCleanup;
1280f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler
1290f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  if (vnc.raw_changed) {
13038201fe1f7c0144578b0d67572a0f2db22b8d0b7Vadim Bendebury    vnc_read = 0;
131d7728233dd7b3d772ce840c5477bcacc536ceb5dRandall Spangler    if (0 != VbWriteNvStorage(&vnc))
1320f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler      goto VbSetNvCleanup;
1330f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  }
1340f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler
1350f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  /* Success */
1360f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  retval = 0;
1370f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler
1380f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall SpanglerVbSetNvCleanup:
1390f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  /* TODO: release lock */
1400f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler  return retval;
1410f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler}
1420f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler
143b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson/*
144b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson * Set a param value, and try to flag it for persistent backup.
145b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson * It's okay if backup isn't supported. It's best-effort only.
146b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson */
147b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardsonstatic int VbSetNvStorage_WithBackup(VbNvParam param, int value)
148b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson{
149b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson  int retval;
150b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson  retval = VbSetNvStorage(param, value);
151b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson  if (!retval)
152b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson    VbSetNvStorage(VBNV_BACKUP_NVRAM_REQUEST, 1);
153b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson  return retval;
154b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson}
155b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson
15692cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette/* Find what build/debug status is specified on the kernel command
15792cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette * line, if any. */
15892cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnettestatic VbBuildOption VbScanBuildOption(void) {
159196e1772ed9092a679767c0497343799f13d2875Randall Spangler  FILE* f = NULL;
160196e1772ed9092a679767c0497343799f13d2875Randall Spangler  char buf[4096] = "";
161196e1772ed9092a679767c0497343799f13d2875Randall Spangler  char *t, *saveptr;
16264ee1530ee55f70a5e65d80cbf584971d7beb1e4Hung-Te Lin  const char *delimiters = " \r\n";
163196e1772ed9092a679767c0497343799f13d2875Randall Spangler
164dbffddce5a4e582265582f3aed7cc0c976ccd3c1J. Richard Barnette  f = fopen(KERNEL_CMDLINE_PATH, "r");
165dbffddce5a4e582265582f3aed7cc0c976ccd3c1J. Richard Barnette  if (NULL != f) {
166196e1772ed9092a679767c0497343799f13d2875Randall Spangler    if (NULL == fgets(buf, sizeof(buf), f))
167dbffddce5a4e582265582f3aed7cc0c976ccd3c1J. Richard Barnette      buf[0] = 0;
168196e1772ed9092a679767c0497343799f13d2875Randall Spangler    fclose(f);
169196e1772ed9092a679767c0497343799f13d2875Randall Spangler  }
17064ee1530ee55f70a5e65d80cbf584971d7beb1e4Hung-Te Lin  for (t = strtok_r(buf, delimiters, &saveptr); t;
17164ee1530ee55f70a5e65d80cbf584971d7beb1e4Hung-Te Lin       t = strtok_r(NULL, delimiters, &saveptr)) {
172196e1772ed9092a679767c0497343799f13d2875Randall Spangler    if (0 == strcmp(t, "cros_debug"))
17392cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette      return VB_BUILD_OPTION_DEBUG;
174227f792c1ba64eb8dd3474395659e27696fcf355Randall Spangler    else if (0 == strcmp(t, "cros_nodebug"))
17592cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette      return VB_BUILD_OPTION_NODEBUG;
17692cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette  }
17792cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette
17892cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette  return VB_BUILD_OPTION_UNKNOWN;
17992cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette}
18092cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette
18192cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette
18292cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette/* Determine whether the running OS image was built for debugging.
18392cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette * Returns 1 if yes, 0 if no or indeterminate. */
18492cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnetteint VbGetDebugBuild(void) {
18592cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette  return VB_BUILD_OPTION_DEBUG == VbScanBuildOption();
18692cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette}
18792cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette
18892cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette
18992cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette/* Determine whether OS-level debugging should be allowed.
19092cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette * Returns 1 if yes, 0 if no or indeterminate. */
19192cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnetteint VbGetCrosDebug(void) {
19292cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette  /* If the currently running system specifies its debug status, use
19392cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette   * that in preference to other indicators. */
19492cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette  VbBuildOption option = VbScanBuildOption();
19592cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette  if (VB_BUILD_OPTION_DEBUG == option) {
19692cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette      return 1;
19792cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette  } else if (VB_BUILD_OPTION_NODEBUG == option) {
198227f792c1ba64eb8dd3474395659e27696fcf355Randall Spangler      return 0;
199196e1772ed9092a679767c0497343799f13d2875Randall Spangler  }
200196e1772ed9092a679767c0497343799f13d2875Randall Spangler
201dbffddce5a4e582265582f3aed7cc0c976ccd3c1J. Richard Barnette  /* Command line is silent; allow debug if the dev switch is on. */
202eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  if (1 == VbGetSystemPropertyInt("devsw_boot"))
203196e1772ed9092a679767c0497343799f13d2875Randall Spangler    return 1;
204196e1772ed9092a679767c0497343799f13d2875Randall Spangler
205196e1772ed9092a679767c0497343799f13d2875Randall Spangler  /* All other cases disallow debug. */
206196e1772ed9092a679767c0497343799f13d2875Randall Spangler  return 0;
207196e1772ed9092a679767c0497343799f13d2875Randall Spangler}
208196e1772ed9092a679767c0497343799f13d2875Randall Spangler
209b47ed5a8fb6aed29fdb2830300c25ca5862a25ecRandall Spangler
2107141571d55373fc2a84a70b5663409a653f8049dRandall Spanglerchar* GetVdatLoadFirmwareDebug(char* dest, int size,
2117141571d55373fc2a84a70b5663409a653f8049dRandall Spangler                               const VbSharedDataHeader* sh) {
2127141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  snprintf(dest, size,
2137141571d55373fc2a84a70b5663409a653f8049dRandall Spangler           "Check A result=%d\n"
2147141571d55373fc2a84a70b5663409a653f8049dRandall Spangler           "Check B result=%d\n"
2157141571d55373fc2a84a70b5663409a653f8049dRandall Spangler           "Firmware index booted=0x%02x\n"
2167141571d55373fc2a84a70b5663409a653f8049dRandall Spangler           "TPM combined version at start=0x%08x\n"
2177141571d55373fc2a84a70b5663409a653f8049dRandall Spangler           "Lowest combined version from firmware=0x%08x\n",
2187141571d55373fc2a84a70b5663409a653f8049dRandall Spangler           sh->check_fw_a_result,
2197141571d55373fc2a84a70b5663409a653f8049dRandall Spangler           sh->check_fw_b_result,
2207141571d55373fc2a84a70b5663409a653f8049dRandall Spangler           sh->firmware_index,
2217141571d55373fc2a84a70b5663409a653f8049dRandall Spangler           sh->fw_version_tpm_start,
2227141571d55373fc2a84a70b5663409a653f8049dRandall Spangler           sh->fw_version_lowest);
2237141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  return dest;
2247141571d55373fc2a84a70b5663409a653f8049dRandall Spangler}
2257141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
2267141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
2277141571d55373fc2a84a70b5663409a653f8049dRandall Spangler#define TRUNCATED "\n(truncated)\n"
2287141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
2297141571d55373fc2a84a70b5663409a653f8049dRandall Spanglerchar* GetVdatLoadKernelDebug(char* dest, int size,
2307141571d55373fc2a84a70b5663409a653f8049dRandall Spangler                             const VbSharedDataHeader* sh) {
2317141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  int used = 0;
2327141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  int first_call_tracked = 0;
2337141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  int call;
2347141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
2357141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  /* Make sure we have space for truncation warning */
2367141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  if (size < strlen(TRUNCATED) + 1)
2377141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    return NULL;
2387141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  size -= strlen(TRUNCATED) + 1;
2397141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
2407141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  used += snprintf(
2417141571d55373fc2a84a70b5663409a653f8049dRandall Spangler      dest + used, size - used,
2427141571d55373fc2a84a70b5663409a653f8049dRandall Spangler      "Calls to LoadKernel()=%d\n",
2437141571d55373fc2a84a70b5663409a653f8049dRandall Spangler      sh->lk_call_count);
2447141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  if (used > size)
2457141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    goto LoadKernelDebugExit;
2467141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
2477141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  /* Report on the last calls */
2487141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  if (sh->lk_call_count > VBSD_MAX_KERNEL_CALLS)
2497141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    first_call_tracked = sh->lk_call_count - VBSD_MAX_KERNEL_CALLS;
2507141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  for (call = first_call_tracked; call < sh->lk_call_count; call++) {
2517141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    const VbSharedDataKernelCall* shc =
2527141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        sh->lk_calls + (call & (VBSD_MAX_KERNEL_CALLS - 1));
2537141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    int first_part_tracked = 0;
2547141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    int part;
2557141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
2567141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    used += snprintf(
2577141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        dest + used, size - used,
2587141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        "Call %d:\n"
2597141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        "  Boot flags=0x%02x\n"
2607141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        "  Boot mode=%d\n"
2617141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        "  Test error=%d\n"
2627141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        "  Return code=%d\n"
2637141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        "  Debug flags=0x%02x\n"
2647141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        "  Drive sectors=%" PRIu64 "\n"
2657141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        "  Sector size=%d\n"
2667141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        "  Check result=%d\n"
2677141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        "  Kernel partitions found=%d\n",
2687141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        call + 1,
2697141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        shc->boot_flags,
2707141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        shc->boot_mode,
2717141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        shc->test_error_num,
2727141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        shc->return_code,
2737141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        shc->flags,
2747141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        shc->sector_count,
2757141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        shc->sector_size,
2767141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        shc->check_result,
2777141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        shc->kernel_parts_found);
2787141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    if (used > size)
2797141571d55373fc2a84a70b5663409a653f8049dRandall Spangler      goto LoadKernelDebugExit;
2807141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
2817141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    /* If we found too many partitions, only prints ones where the
2827141571d55373fc2a84a70b5663409a653f8049dRandall Spangler     * structure has info. */
2837141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    if (shc->kernel_parts_found > VBSD_MAX_KERNEL_PARTS)
2847141571d55373fc2a84a70b5663409a653f8049dRandall Spangler      first_part_tracked = shc->kernel_parts_found - VBSD_MAX_KERNEL_PARTS;
2857141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
2867141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    /* Report on the partitions checked */
2877141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    for (part = first_part_tracked; part < shc->kernel_parts_found; part++) {
2887141571d55373fc2a84a70b5663409a653f8049dRandall Spangler      const VbSharedDataKernelPart* shp =
2897141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          shc->parts + (part & (VBSD_MAX_KERNEL_PARTS - 1));
2907141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
2917141571d55373fc2a84a70b5663409a653f8049dRandall Spangler      used += snprintf(
2927141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          dest + used, size - used,
2937141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          "  Kernel %d:\n"
2947141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          "    GPT index=%d\n"
2957141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          "    Start sector=%" PRIu64 "\n"
2967141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          "    Sector count=%" PRIu64 "\n"
2977141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          "    Combined version=0x%08x\n"
2987141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          "    Check result=%d\n"
2997141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          "    Debug flags=0x%02x\n",
3007141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          part + 1,
3017141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          shp->gpt_index,
3027141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          shp->sector_start,
3037141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          shp->sector_count,
3047141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          shp->combined_version,
3057141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          shp->check_result,
3067141571d55373fc2a84a70b5663409a653f8049dRandall Spangler          shp->flags);
3077141571d55373fc2a84a70b5663409a653f8049dRandall Spangler      if (used > size)
3087141571d55373fc2a84a70b5663409a653f8049dRandall Spangler        goto LoadKernelDebugExit;
3097141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    }
3107141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  }
3117141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
3127141571d55373fc2a84a70b5663409a653f8049dRandall SpanglerLoadKernelDebugExit:
3137141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
3147141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  /* Warn if data was truncated; we left space for this above. */
3157141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  if (used > size)
3167141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    strcat(dest, TRUNCATED);
3177141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
3187141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  return dest;
3197141571d55373fc2a84a70b5663409a653f8049dRandall Spangler}
3207141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
3217141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
322f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spanglerchar* GetVdatString(char* dest, int size, VdatStringField field)
323f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler{
324eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  VbSharedDataHeader* sh = VbSharedDataRead();
3257141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  char* value = dest;
326f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
327eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  if (!sh)
328eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler    return NULL;
329f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
330f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler  switch (field) {
331f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler    case VDAT_STRING_TIMERS:
332f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler      snprintf(dest, size,
333f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler               "LFS=%" PRIu64 ",%" PRIu64
334f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler               " LF=%" PRIu64 ",%" PRIu64
335f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler               " LK=%" PRIu64 ",%" PRIu64,
3369619112a574b975476667545e3a326052fa0c50bRandall Spangler               sh->timer_vb_init_enter,
3379619112a574b975476667545e3a326052fa0c50bRandall Spangler               sh->timer_vb_init_exit,
3389619112a574b975476667545e3a326052fa0c50bRandall Spangler               sh->timer_vb_select_firmware_enter,
3399619112a574b975476667545e3a326052fa0c50bRandall Spangler               sh->timer_vb_select_firmware_exit,
3409619112a574b975476667545e3a326052fa0c50bRandall Spangler               sh->timer_vb_select_and_load_kernel_enter,
3419619112a574b975476667545e3a326052fa0c50bRandall Spangler               sh->timer_vb_select_and_load_kernel_exit);
342f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler      break;
343f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
344f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler    case VDAT_STRING_LOAD_FIRMWARE_DEBUG:
3457141571d55373fc2a84a70b5663409a653f8049dRandall Spangler      value = GetVdatLoadFirmwareDebug(dest, size, sh);
3467141571d55373fc2a84a70b5663409a653f8049dRandall Spangler      break;
3477141571d55373fc2a84a70b5663409a653f8049dRandall Spangler
3487141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    case VDAT_STRING_LOAD_KERNEL_DEBUG:
3497141571d55373fc2a84a70b5663409a653f8049dRandall Spangler      value = GetVdatLoadKernelDebug(dest, size, sh);
350f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler      break;
351f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
352a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler    case VDAT_STRING_MAINFW_ACT:
353a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler      switch(sh->firmware_index) {
354a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler        case 0:
355a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler          StrCopy(dest, "A", size);
356a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler          break;
357a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler        case 1:
358a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler          StrCopy(dest, "B", size);
359a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler          break;
360a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler        case 0xFF:
361a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler          StrCopy(dest, "recovery", size);
362a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler          break;
363a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler        default:
364a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler          value = NULL;
365a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler      }
366a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler      break;
367a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler
368f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler    default:
369eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler      value = NULL;
370eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler      break;
371f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler  }
372f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
37332a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler  free(sh);
3747141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  return value;
375f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler}
376f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
377f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
378f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spanglerint GetVdatInt(VdatIntField field) {
379eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  VbSharedDataHeader* sh = VbSharedDataRead();
380f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler  int value = -1;
381f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
382eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  if (!sh)
383f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler    return -1;
384f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
385da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler  /* Fields supported in version 1 */
386f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler  switch (field) {
387f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler    case VDAT_INT_FLAGS:
388f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler      value = (int)sh->flags;
389f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler      break;
390da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler    case VDAT_INT_HEADER_VERSION:
391da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler      value = sh->struct_version;
3925ac39bfff0d9e2ad2c3e1fe9b3fd3f314b50a472Randall Spangler      break;
393cabe6b3514f3228b350a7d07d6cc7cb39eecaaf6Randall Spangler    case VDAT_INT_TRIED_FIRMWARE_B:
394cabe6b3514f3228b350a7d07d6cc7cb39eecaaf6Randall Spangler      value = (sh->flags & VBSD_FWB_TRIED ? 1 : 0);
395cabe6b3514f3228b350a7d07d6cc7cb39eecaaf6Randall Spangler      break;
396cabe6b3514f3228b350a7d07d6cc7cb39eecaaf6Randall Spangler    case VDAT_INT_KERNEL_KEY_VERIFIED:
397cabe6b3514f3228b350a7d07d6cc7cb39eecaaf6Randall Spangler      value = (sh->flags & VBSD_KERNEL_KEY_VERIFIED ? 1 : 0);
398cabe6b3514f3228b350a7d07d6cc7cb39eecaaf6Randall Spangler      break;
39989286bc73ac3939e4df8c5952346ce0825e1c76cRandall Spangler    case VDAT_INT_FW_VERSION_TPM:
40089286bc73ac3939e4df8c5952346ce0825e1c76cRandall Spangler      value = (int)sh->fw_version_tpm;
40189286bc73ac3939e4df8c5952346ce0825e1c76cRandall Spangler      break;
40289286bc73ac3939e4df8c5952346ce0825e1c76cRandall Spangler    case VDAT_INT_KERNEL_VERSION_TPM:
40389286bc73ac3939e4df8c5952346ce0825e1c76cRandall Spangler      value = (int)sh->kernel_version_tpm;
40489286bc73ac3939e4df8c5952346ce0825e1c76cRandall Spangler      break;
405d11086caf05c692815ae6f90aa83a4fc30d50ed7Daisuke Nojiri    case VDAT_INT_FW_BOOT2:
406d11086caf05c692815ae6f90aa83a4fc30d50ed7Daisuke Nojiri      value = (sh->flags & VBSD_BOOT_FIRMWARE_VBOOT2 ? 1 : 0);
407da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler    default:
4087adcc60e6f5f6db081b9ad6e02288335502a0d77Randall Spangler      break;
409f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler  }
410f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
411da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler  /* Fields added in struct version 2 */
412da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler  if (sh->struct_version >= 2) {
413da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler    switch(field) {
414da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler      case VDAT_INT_DEVSW_BOOT:
415da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler        value = (sh->flags & VBSD_BOOT_DEV_SWITCH_ON ? 1 : 0);
416da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler        break;
417da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler      case VDAT_INT_DEVSW_VIRTUAL:
418da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler        value = (sh->flags & VBSD_HONOR_VIRT_DEV_SWITCH ? 1 : 0);
419da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler        break;
420da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler      case VDAT_INT_RECSW_BOOT:
421da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler        value = (sh->flags & VBSD_BOOT_REC_SWITCH_ON ? 1 : 0);
422da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler        break;
4239dc62178c97b94e5c308f1c36fd0858c316959e5Bill Richardson      case VDAT_INT_HW_WPSW_BOOT:
424da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler        value = (sh->flags & VBSD_BOOT_FIRMWARE_WP_ENABLED ? 1 : 0);
425da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler        break;
4269dc62178c97b94e5c308f1c36fd0858c316959e5Bill Richardson      case VDAT_INT_SW_WPSW_BOOT:
4279dc62178c97b94e5c308f1c36fd0858c316959e5Bill Richardson        value = (sh->flags & VBSD_BOOT_FIRMWARE_SW_WP_ENABLED ? 1 : 0);
4289dc62178c97b94e5c308f1c36fd0858c316959e5Bill Richardson        break;
429da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler      case VDAT_INT_RECOVERY_REASON:
430da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler        value = sh->recovery_reason;
431da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler        break;
432da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler      default:
433da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler        break;
434da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler    }
435da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler  }
436da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler
43732a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler  free(sh);
438f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler  return value;
439f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler}
440f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
441da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler/* Return version of VbSharedData struct or -1 if not found. */
442da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spanglerint VbSharedDataVersion(void) {
443da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler  return GetVdatInt(VDAT_INT_HEADER_VERSION);
444da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler}
445f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler
446542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spanglerint VbGetSystemPropertyInt(const char* name) {
447c80fe65f9e42aba26077fc93ce43ae6c02b9eb67Randall Spangler  int value = -1;
448542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler
449eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  /* Check architecture-dependent properties first */
450eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  value = VbGetArchPropertyInt(name);
451eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  if (-1 != value)
452eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler    return value;
453eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
454eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  /* NV storage values */
455cabe6b3514f3228b350a7d07d6cc7cb39eecaaf6Randall Spangler  else if (!strcasecmp(name,"kern_nv")) {
456618d17d48ceb095e06f7c4395217c304567f316eRandall Spangler    value = VbGetNvStorage(VBNV_KERNEL_FIELD);
457b416714a10cc8b8048009ca2ab0f3fa1dc4ac24bRandall Spangler  } else if (!strcasecmp(name,"nvram_cleared")) {
458b416714a10cc8b8048009ca2ab0f3fa1dc4ac24bRandall Spangler    value = VbGetNvStorage(VBNV_KERNEL_SETTINGS_RESET);
459eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  } else if (!strcasecmp(name,"recovery_request")) {
4600f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler    value = VbGetNvStorage(VBNV_RECOVERY_REQUEST);
461e73302caae852485fdf180baa9a443b74f565dccRandall Spangler  } else if (!strcasecmp(name,"dbg_reset")) {
4620f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler    value = VbGetNvStorage(VBNV_DEBUG_RESET_MODE);
46335d073362603c2c3f63974d04b4af9548297e208Bill Richardson  } else if (!strcasecmp(name,"disable_dev_request")) {
46435d073362603c2c3f63974d04b4af9548297e208Bill Richardson    value = VbGetNvStorage(VBNV_DISABLE_DEV_REQUEST);
46529e8807ea045e119e3adeaec40c5f8421901b6fbRandall Spangler  } else if (!strcasecmp(name,"clear_tpm_owner_request")) {
46629e8807ea045e119e3adeaec40c5f8421901b6fbRandall Spangler    value = VbGetNvStorage(VBNV_CLEAR_TPM_OWNER_REQUEST);
46729e8807ea045e119e3adeaec40c5f8421901b6fbRandall Spangler  } else if (!strcasecmp(name,"clear_tpm_owner_done")) {
46829e8807ea045e119e3adeaec40c5f8421901b6fbRandall Spangler    value = VbGetNvStorage(VBNV_CLEAR_TPM_OWNER_DONE);
469e73302caae852485fdf180baa9a443b74f565dccRandall Spangler  } else if (!strcasecmp(name,"fwb_tries")) {
4700f8ffb11f5fe456aab4ef3a07ace0eb6c825dbd3Randall Spangler    value = VbGetNvStorage(VBNV_TRY_B_COUNT);
471d11086caf05c692815ae6f90aa83a4fc30d50ed7Daisuke Nojiri  } else if (!strcasecmp(name,"fw_vboot2")) {
472d11086caf05c692815ae6f90aa83a4fc30d50ed7Daisuke Nojiri    value = GetVdatInt(VDAT_INT_FW_BOOT2);
4739e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler  } else if (!strcasecmp(name,"fw_try_count")) {
4749e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler    value = VbGetNvStorage(VBNV_FW_TRY_COUNT);
475d7728233dd7b3d772ce840c5477bcacc536ceb5dRandall Spangler  } else if (!strcasecmp(name,"fwupdate_tries")) {
476d7728233dd7b3d772ce840c5477bcacc536ceb5dRandall Spangler    value = VbGetNvStorage(VBNV_KERNEL_FIELD);
477d7728233dd7b3d772ce840c5477bcacc536ceb5dRandall Spangler    if (value != -1)
478d7728233dd7b3d772ce840c5477bcacc536ceb5dRandall Spangler      value &= KERN_NV_FWUPDATE_TRIES_MASK;
479850b74fa19f6eadd1d3221f484c738f41f993653Bill Richardson  } else if (!strcasecmp(name,"block_devmode")) {
480850b74fa19f6eadd1d3221f484c738f41f993653Bill Richardson    value = VbGetNvStorage(VBNV_KERNEL_FIELD);
481850b74fa19f6eadd1d3221f484c738f41f993653Bill Richardson    if (value != -1) {
482850b74fa19f6eadd1d3221f484c738f41f993653Bill Richardson      value &= KERN_NV_BLOCK_DEVMODE_FLAG;
483850b74fa19f6eadd1d3221f484c738f41f993653Bill Richardson      value = !!value;
484850b74fa19f6eadd1d3221f484c738f41f993653Bill Richardson    }
48544a127675b311aaa46ebb171e95701b29aba74deRandall Spangler  } else if (!strcasecmp(name,"loc_idx")) {
48644a127675b311aaa46ebb171e95701b29aba74deRandall Spangler    value = VbGetNvStorage(VBNV_LOCALIZATION_INDEX);
487b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson  } else if (!strcasecmp(name,"backup_nvram_request")) {
488b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson    value = VbGetNvStorage(VBNV_BACKUP_NVRAM_REQUEST);
489daa807c51ef6d5bf6599e649d1777432bea8a3e5Randall Spangler  } else if (!strcasecmp(name,"dev_boot_usb")) {
490daa807c51ef6d5bf6599e649d1777432bea8a3e5Randall Spangler    value = VbGetNvStorage(VBNV_DEV_BOOT_USB);
491a2326ee152ab5b8aee924ccf794cee38d54909bdStefan Reinauer  } else if (!strcasecmp(name,"dev_boot_legacy")) {
492a2326ee152ab5b8aee924ccf794cee38d54909bdStefan Reinauer    value = VbGetNvStorage(VBNV_DEV_BOOT_LEGACY);
4937272a6951107251a5c9b26330c506319a92a54b3Bill Richardson  } else if (!strcasecmp(name,"dev_boot_signed_only")) {
4947272a6951107251a5c9b26330c506319a92a54b3Bill Richardson    value = VbGetNvStorage(VBNV_DEV_BOOT_SIGNED_ONLY);
49517b8224ea582b2ba90b30a3e8e2d913e49c7818aBill Richardson  } else if (!strcasecmp(name,"oprom_needed")) {
49617b8224ea582b2ba90b30a3e8e2d913e49c7818aBill Richardson    value = VbGetNvStorage(VBNV_OPROM_NEEDED);
497699ebf398f84bb0a6138856c38db1d693e581f85Bill Richardson  } else if (!strcasecmp(name,"recovery_subcode")) {
498699ebf398f84bb0a6138856c38db1d693e581f85Bill Richardson    value = VbGetNvStorage(VBNV_RECOVERY_SUBCODE);
499e73302caae852485fdf180baa9a443b74f565dccRandall Spangler  }
500b47ed5a8fb6aed29fdb2830300c25ca5862a25ecRandall Spangler  /* Other parameters */
501eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  else if (!strcasecmp(name,"cros_debug")) {
502196e1772ed9092a679767c0497343799f13d2875Randall Spangler    value = VbGetCrosDebug();
50392cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette  } else if (!strcasecmp(name,"debug_build")) {
50492cbd5d214e0f2f9a3d52db48dcdaaceb57993d4J. Richard Barnette    value = VbGetDebugBuild();
505da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler  } else if (!strcasecmp(name,"devsw_boot")) {
506da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler    value = GetVdatInt(VDAT_INT_DEVSW_BOOT);
507da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler  } else if (!strcasecmp(name,"devsw_virtual")) {
508da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler    value = GetVdatInt(VDAT_INT_DEVSW_VIRTUAL);
509da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler  } else if (!strcasecmp(name, "recoverysw_boot")) {
510da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler    value = GetVdatInt(VDAT_INT_RECSW_BOOT);
511da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79acRandall Spangler  } else if (!strcasecmp(name, "wpsw_boot")) {
5129dc62178c97b94e5c308f1c36fd0858c316959e5Bill Richardson    value = GetVdatInt(VDAT_INT_HW_WPSW_BOOT);
5139dc62178c97b94e5c308f1c36fd0858c316959e5Bill Richardson  } else if (!strcasecmp(name, "sw_wpsw_boot")) {
5149dc62178c97b94e5c308f1c36fd0858c316959e5Bill Richardson    value = GetVdatInt(VDAT_INT_SW_WPSW_BOOT);
515f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler  } else if (!strcasecmp(name,"vdat_flags")) {
516f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler    value = GetVdatInt(VDAT_INT_FLAGS);
5175ac39bfff0d9e2ad2c3e1fe9b3fd3f314b50a472Randall Spangler  } else if (!strcasecmp(name,"tpm_fwver")) {
5185ac39bfff0d9e2ad2c3e1fe9b3fd3f314b50a472Randall Spangler    value = GetVdatInt(VDAT_INT_FW_VERSION_TPM);
5195ac39bfff0d9e2ad2c3e1fe9b3fd3f314b50a472Randall Spangler  } else if (!strcasecmp(name,"tpm_kernver")) {
5205ac39bfff0d9e2ad2c3e1fe9b3fd3f314b50a472Randall Spangler    value = GetVdatInt(VDAT_INT_KERNEL_VERSION_TPM);
521cabe6b3514f3228b350a7d07d6cc7cb39eecaaf6Randall Spangler  } else if (!strcasecmp(name,"tried_fwb")) {
522cabe6b3514f3228b350a7d07d6cc7cb39eecaaf6Randall Spangler    value = GetVdatInt(VDAT_INT_TRIED_FIRMWARE_B);
5237adcc60e6f5f6db081b9ad6e02288335502a0d77Randall Spangler  } else if (!strcasecmp(name,"recovery_reason")) {
5247adcc60e6f5f6db081b9ad6e02288335502a0d77Randall Spangler    value = GetVdatInt(VDAT_INT_RECOVERY_REASON);
525b47ed5a8fb6aed29fdb2830300c25ca5862a25ecRandall Spangler  }
526542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler
527c80fe65f9e42aba26077fc93ce43ae6c02b9eb67Randall Spangler  return value;
528542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler}
529542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler
530eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
531a3d70a3d2b5c052db039d097aaffa42008da24b5J. Richard Barnetteconst char* VbGetSystemPropertyString(const char* name, char* dest,
532a3d70a3d2b5c052db039d097aaffa42008da24b5J. Richard Barnette                                      size_t size) {
533d808a43d357371451c8ca4b4ad1a38f2251155c4Tom Wai-Hong Tam  static const char unknown_string[] = "unknown";
534d808a43d357371451c8ca4b4ad1a38f2251155c4Tom Wai-Hong Tam
535eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  /* Check architecture-dependent properties first */
536eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  if (VbGetArchPropertyString(name, dest, size))
537eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler    return dest;
538542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler
539eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  if (!strcasecmp(name,"kernkey_vfy")) {
540cabe6b3514f3228b350a7d07d6cc7cb39eecaaf6Randall Spangler    switch(GetVdatInt(VDAT_INT_KERNEL_KEY_VERIFIED)) {
541172602829dc0d79ed65d7ed81225389f090b981fRandall Spangler      case 0:
542172602829dc0d79ed65d7ed81225389f090b981fRandall Spangler        return "hash";
543172602829dc0d79ed65d7ed81225389f090b981fRandall Spangler      case 1:
544172602829dc0d79ed65d7ed81225389f090b981fRandall Spangler        return "sig";
545172602829dc0d79ed65d7ed81225389f090b981fRandall Spangler      default:
546172602829dc0d79ed65d7ed81225389f090b981fRandall Spangler        return NULL;
547172602829dc0d79ed65d7ed81225389f090b981fRandall Spangler    }
548a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler  } else if (!strcasecmp(name, "mainfw_act")) {
549a185b8d8f61ac165bc15c6b51d23b6e1be5b15cfRandall Spangler    return GetVdatString(dest, size, VDAT_STRING_MAINFW_ACT);
550f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler  } else if (!strcasecmp(name, "vdat_timers")) {
551f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler    return GetVdatString(dest, size, VDAT_STRING_TIMERS);
552f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler  } else if (!strcasecmp(name, "vdat_lfdebug")) {
553f4ba19d81d4fefa0dba4efbdd57dc863138fde3aRandall Spangler    return GetVdatString(dest, size, VDAT_STRING_LOAD_FIRMWARE_DEBUG);
5547141571d55373fc2a84a70b5663409a653f8049dRandall Spangler  } else if (!strcasecmp(name, "vdat_lkdebug")) {
5557141571d55373fc2a84a70b5663409a653f8049dRandall Spangler    return GetVdatString(dest, size, VDAT_STRING_LOAD_KERNEL_DEBUG);
556d808a43d357371451c8ca4b4ad1a38f2251155c4Tom Wai-Hong Tam  } else if (!strcasecmp(name, "ddr_type")) {
557d808a43d357371451c8ca4b4ad1a38f2251155c4Tom Wai-Hong Tam    return unknown_string;
5589e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler  } else if (!strcasecmp(name, "fw_try_next")) {
5599e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler    return VbGetNvStorage(VBNV_FW_TRY_NEXT) ? "B" : "A";
5609e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler  } else if (!strcasecmp(name, "fw_tried")) {
5619e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler    return VbGetNvStorage(VBNV_FW_TRIED) ? "B" : "A";
5629e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler  } else if (!strcasecmp(name, "fw_result")) {
5639e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler    int v = VbGetNvStorage(VBNV_FW_RESULT);
5649e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler    if (v < ARRAY_SIZE(fw_results))
5659e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler      return fw_results[v];
5669e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler    else
5679e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler      return "unknown";
568782300d093a2fbf2ca24e446fb6d65f9f28e56a6Randall Spangler  } else if (!strcasecmp(name, "fw_prev_tried")) {
569782300d093a2fbf2ca24e446fb6d65f9f28e56a6Randall Spangler    return VbGetNvStorage(VBNV_FW_PREV_TRIED) ? "B" : "A";
570782300d093a2fbf2ca24e446fb6d65f9f28e56a6Randall Spangler  } else if (!strcasecmp(name, "fw_prev_result")) {
571782300d093a2fbf2ca24e446fb6d65f9f28e56a6Randall Spangler    int v = VbGetNvStorage(VBNV_FW_PREV_RESULT);
572782300d093a2fbf2ca24e446fb6d65f9f28e56a6Randall Spangler    if (v < ARRAY_SIZE(fw_results))
573782300d093a2fbf2ca24e446fb6d65f9f28e56a6Randall Spangler      return fw_results[v];
574782300d093a2fbf2ca24e446fb6d65f9f28e56a6Randall Spangler    else
575782300d093a2fbf2ca24e446fb6d65f9f28e56a6Randall Spangler      return "unknown";
576eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  }
577eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler
578eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  return NULL;
579542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler}
580542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler
581542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler
582542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spanglerint VbSetSystemPropertyInt(const char* name, int value) {
583eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  /* Check architecture-dependent properties first */
584d7728233dd7b3d772ce840c5477bcacc536ceb5dRandall Spangler
585eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  if (0 == VbSetArchPropertyInt(name, value))
586eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler    return 0;
587542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler
588eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  /* NV storage values */
589b416714a10cc8b8048009ca2ab0f3fa1dc4ac24bRandall Spangler  if (!strcasecmp(name,"nvram_cleared")) {
590b416714a10cc8b8048009ca2ab0f3fa1dc4ac24bRandall Spangler    /* Can only clear this flag; it's set inside the NV storage library. */
591b416714a10cc8b8048009ca2ab0f3fa1dc4ac24bRandall Spangler    return VbSetNvStorage(VBNV_KERNEL_SETTINGS_RESET, 0);
592eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  } else if (!strcasecmp(name,"recovery_request")) {
593eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler    return VbSetNvStorage(VBNV_RECOVERY_REQUEST, value);
594699ebf398f84bb0a6138856c38db1d693e581f85Bill Richardson  } else if (!strcasecmp(name,"recovery_subcode")) {
595699ebf398f84bb0a6138856c38db1d693e581f85Bill Richardson    return VbSetNvStorage(VBNV_RECOVERY_SUBCODE, value);
596e73302caae852485fdf180baa9a443b74f565dccRandall Spangler  } else if (!strcasecmp(name,"dbg_reset")) {
597eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler    return VbSetNvStorage(VBNV_DEBUG_RESET_MODE, value);
59835d073362603c2c3f63974d04b4af9548297e208Bill Richardson  } else if (!strcasecmp(name,"disable_dev_request")) {
59935d073362603c2c3f63974d04b4af9548297e208Bill Richardson    return VbSetNvStorage(VBNV_DISABLE_DEV_REQUEST, value);
60029e8807ea045e119e3adeaec40c5f8421901b6fbRandall Spangler  } else if (!strcasecmp(name,"clear_tpm_owner_request")) {
60129e8807ea045e119e3adeaec40c5f8421901b6fbRandall Spangler    return VbSetNvStorage(VBNV_CLEAR_TPM_OWNER_REQUEST, value);
60229e8807ea045e119e3adeaec40c5f8421901b6fbRandall Spangler  } else if (!strcasecmp(name,"clear_tpm_owner_done")) {
60329e8807ea045e119e3adeaec40c5f8421901b6fbRandall Spangler    /* Can only clear this flag; it's set by firmware. */
60429e8807ea045e119e3adeaec40c5f8421901b6fbRandall Spangler    return VbSetNvStorage(VBNV_CLEAR_TPM_OWNER_DONE, 0);
605e73302caae852485fdf180baa9a443b74f565dccRandall Spangler  } else if (!strcasecmp(name,"fwb_tries")) {
606eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler    return VbSetNvStorage(VBNV_TRY_B_COUNT, value);
6079e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler  } else if (!strcasecmp(name,"fw_try_count")) {
6089e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler    return VbSetNvStorage(VBNV_FW_TRY_COUNT, value);
609b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson  } else if (!strcasecmp(name,"oprom_needed")) {
610b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson    return VbSetNvStorage(VBNV_OPROM_NEEDED, value);
611b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson  } else if (!strcasecmp(name,"backup_nvram_request")) {
612b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson      /* Best-effort only, since it requires firmware and TPM support. */
613b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson    return VbSetNvStorage(VBNV_BACKUP_NVRAM_REQUEST, value);
614d7728233dd7b3d772ce840c5477bcacc536ceb5dRandall Spangler  } else if (!strcasecmp(name,"fwupdate_tries")) {
615d7728233dd7b3d772ce840c5477bcacc536ceb5dRandall Spangler    int kern_nv = VbGetNvStorage(VBNV_KERNEL_FIELD);
616d7728233dd7b3d772ce840c5477bcacc536ceb5dRandall Spangler    if (kern_nv == -1)
617d7728233dd7b3d772ce840c5477bcacc536ceb5dRandall Spangler      return -1;
618d7728233dd7b3d772ce840c5477bcacc536ceb5dRandall Spangler    kern_nv &= ~KERN_NV_FWUPDATE_TRIES_MASK;
619d7728233dd7b3d772ce840c5477bcacc536ceb5dRandall Spangler    kern_nv |= (value & KERN_NV_FWUPDATE_TRIES_MASK);
620b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson    return VbSetNvStorage_WithBackup(VBNV_KERNEL_FIELD, kern_nv);
621850b74fa19f6eadd1d3221f484c738f41f993653Bill Richardson  } else if (!strcasecmp(name,"block_devmode")) {
622850b74fa19f6eadd1d3221f484c738f41f993653Bill Richardson    int kern_nv = VbGetNvStorage(VBNV_KERNEL_FIELD);
623850b74fa19f6eadd1d3221f484c738f41f993653Bill Richardson    if (kern_nv == -1)
624850b74fa19f6eadd1d3221f484c738f41f993653Bill Richardson      return -1;
625850b74fa19f6eadd1d3221f484c738f41f993653Bill Richardson    kern_nv &= ~KERN_NV_BLOCK_DEVMODE_FLAG;
626850b74fa19f6eadd1d3221f484c738f41f993653Bill Richardson    if (value)
627850b74fa19f6eadd1d3221f484c738f41f993653Bill Richardson	kern_nv |= KERN_NV_BLOCK_DEVMODE_FLAG;
628b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson    return VbSetNvStorage_WithBackup(VBNV_KERNEL_FIELD, kern_nv);
62944a127675b311aaa46ebb171e95701b29aba74deRandall Spangler  } else if (!strcasecmp(name,"loc_idx")) {
630b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson    return VbSetNvStorage_WithBackup(VBNV_LOCALIZATION_INDEX, value);
631daa807c51ef6d5bf6599e649d1777432bea8a3e5Randall Spangler  } else if (!strcasecmp(name,"dev_boot_usb")) {
632b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson    return VbSetNvStorage_WithBackup(VBNV_DEV_BOOT_USB, value);
633a2326ee152ab5b8aee924ccf794cee38d54909bdStefan Reinauer  } else if (!strcasecmp(name,"dev_boot_legacy")) {
634b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson    return VbSetNvStorage_WithBackup(VBNV_DEV_BOOT_LEGACY, value);
6357272a6951107251a5c9b26330c506319a92a54b3Bill Richardson  } else if (!strcasecmp(name,"dev_boot_signed_only")) {
636b64f097891e697eaf3b2794baae934f8b4d82d14Bill Richardson    return VbSetNvStorage_WithBackup(VBNV_DEV_BOOT_SIGNED_ONLY, value);
637e73302caae852485fdf180baa9a443b74f565dccRandall Spangler  }
638e73302caae852485fdf180baa9a443b74f565dccRandall Spangler
639542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler  return -1;
640542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler}
641542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler
642542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler
643542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spanglerint VbSetSystemPropertyString(const char* name, const char* value) {
644eb59195473246f8ff3076950f3c3b8d3564d433dRandall Spangler  /* Chain to architecture-dependent properties */
6459e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler  if (0 == VbSetArchPropertyString(name, value))
6469e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler    return 0;
6479e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler
6489e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler  if (!strcasecmp(name, "fw_try_next")) {
6499e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler    if (!strcasecmp(value, "A"))
6509e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler      return VbSetNvStorage(VBNV_FW_TRY_NEXT, 0);
6519e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler    else if (!strcasecmp(value, "B"))
6529e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler      return VbSetNvStorage(VBNV_FW_TRY_NEXT, 1);
6539e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler    else
6549e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler      return -1;
6559e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler
6569e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler  } else if (!strcasecmp(name, "fw_result")) {
6579e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler    int i;
6589e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler
6599e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler    for (i = 0; i < ARRAY_SIZE(fw_results); i++) {
6609e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler      if (!strcasecmp(value, fw_results[i]))
6619e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler	return VbSetNvStorage(VBNV_FW_RESULT, i);
6629e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler    }
6639e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler    return -1;
6649e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler  }
6659e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler
6669e1da784487fb8cfbe4e76693e07205b66675bdaRandall Spangler  return -1;
667542186618a43fb0786ff161a4ecc226f2f0c59e9Randall Spangler}
668