/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>

#include "2sysincludes.h"
#include "2api.h"
#include "2common.h"
#include "2nvstorage.h"

#include "host_common.h"

#include "crossystem.h"
#include "crossystem_arch.h"
#include "crossystem_vbnv.h"
#include "utility.h"
#include "vboot_struct.h"

/* Filename for kernel command line */
#define KERNEL_CMDLINE_PATH "/proc/cmdline"

#define MOSYS_CROS_PATH "/usr/sbin/mosys"
#define MOSYS_ANDROID_PATH "/system/bin/mosys"

/* Fields that GetVdatString() can get */
typedef enum VdatStringField {
	VDAT_STRING_TIMERS = 0,           /* Timer values */
	VDAT_STRING_LOAD_FIRMWARE_DEBUG,  /* LoadFirmware() debug information */
	VDAT_STRING_LOAD_KERNEL_DEBUG,    /* LoadKernel() debug information */
	VDAT_STRING_MAINFW_ACT            /* Active main firmware */
} VdatStringField;


/* Fields that GetVdatInt() can get */
typedef enum VdatIntField {
	VDAT_INT_FLAGS = 0,           /* Flags */
	VDAT_INT_HEADER_VERSION,      /* Header version for VbSharedData */
	VDAT_INT_DEVSW_BOOT,          /* Dev switch position at boot */
	VDAT_INT_DEPRECATED_DEVSW_VIRTUAL,  /* Dev switch is virtual;
	                                     * deprecated: chromium:942901 */
	VDAT_INT_RECSW_BOOT,          /* Recovery switch position at boot */
	VDAT_INT_RECSW_VIRTUAL,       /* Recovery switch is virtual */
	VDAT_INT_HW_WPSW_BOOT,        /* Hardware WP switch position at boot */

	VDAT_INT_FW_VERSION_TPM,      /* Current firmware version in TPM */
	VDAT_INT_KERNEL_VERSION_TPM,  /* Current kernel version in TPM */
	VDAT_INT_TRIED_FIRMWARE_B,    /* Tried firmware B due to fwb_tries */
	VDAT_INT_KERNEL_KEY_VERIFIED, /* Kernel key verified using
				       * signature, not just hash */
	VDAT_INT_RECOVERY_REASON,     /* Recovery reason for current boot */
	VDAT_INT_FW_BOOT2             /* Firmware selection by vboot2 */
} VdatIntField;


/* Description of build options that may be specified on the
 * kernel command line. */
typedef enum VbBuildOption {
	VB_BUILD_OPTION_UNKNOWN,
	VB_BUILD_OPTION_DEBUG,
	VB_BUILD_OPTION_NODEBUG
} VbBuildOption;

static const char *fw_results[] = {"unknown", "trying", "success", "failure"};
static const char *default_boot[] = {"disk", "usb", "legacy"};

/* Masks for kern_nv usage by kernel. */
#define KERN_NV_FWUPDATE_TRIES_MASK 0x000F
#define KERN_NV_BLOCK_DEVMODE_FLAG  0x0010
#define KERN_NV_TPM_ATTACK_FLAG     0x0020
/* If you want to use the remaining currently-unused bits in kern_nv
 * for something kernel-y, define a new field (the way we did for
 * fwupdate_tries).  Don't just modify kern_nv directly, because that
 * makes it too easy to accidentally corrupt other sub-fields. */
#define KERN_NV_CURRENTLY_UNUSED    0xFFC0

/* Return true if the FWID starts with the specified string. */
int FwidStartsWith(const char *start)
{
	char fwid[VB_MAX_STRING_PROPERTY];
	if (!VbGetSystemPropertyString("fwid", fwid, sizeof(fwid)))
		return 0;

	return 0 == strncmp(fwid, start, strlen(start));
}

static int vnc_read;

int vb2_get_nv_storage(enum vb2_nv_param param)
{
	VbSharedDataHeader* sh = VbSharedDataRead();
	static struct vb2_context cached_ctx;

	if (!sh)
		return -1;

	/* TODO: locking around NV access */
	if (!vnc_read) {
		memset(&cached_ctx, 0, sizeof(cached_ctx));
		if (sh && sh->flags & VBSD_NVDATA_V2)
			cached_ctx.flags |= VB2_CONTEXT_NVDATA_V2;
		if (0 != vb2_read_nv_storage(&cached_ctx)) {
			free(sh);
			return -1;
		}
		vb2_nv_init(&cached_ctx);

		/* TODO: If vnc.raw_changed, attempt to reopen NVRAM for write
		 * and save the new defaults.  If we're able to, log. */

		vnc_read = 1;
	}

	free(sh);
	return (int)vb2_nv_get(&cached_ctx, param);
}

int vb2_set_nv_storage(enum vb2_nv_param param, int value)
{
	VbSharedDataHeader* sh = VbSharedDataRead();
	struct vb2_context ctx;

	if (!sh)
		return -1;

	/* TODO: locking around NV access */
	memset(&ctx, 0, sizeof(ctx));
	if (sh && sh->flags & VBSD_NVDATA_V2)
		ctx.flags |= VB2_CONTEXT_NVDATA_V2;
	if (0 != vb2_read_nv_storage(&ctx)) {
		free(sh);
		return -1;
	}
	vb2_nv_init(&ctx);
	vb2_nv_set(&ctx, param, (uint32_t)value);

	if (ctx.flags & VB2_CONTEXT_NVDATA_CHANGED) {
		vnc_read = 0;
		if (0 != vb2_write_nv_storage(&ctx)) {
			free(sh);
			return -1;
		}
	}

	/* Success */
	free(sh);
	return 0;
}

/*
 * Set a param value, and try to flag it for persistent backup.  It's okay if
 * backup isn't supported (which it isn't, in current designs). It's
 * best-effort only.
 */
static int vb2_set_nv_storage_with_backup(enum vb2_nv_param param, int value)
{
	int retval;
	retval = vb2_set_nv_storage(param, value);
	if (!retval)
		vb2_set_nv_storage(VB2_NV_BACKUP_NVRAM_REQUEST, 1);
	return retval;
}

/* Find what build/debug status is specified on the kernel command
 * line, if any. */
static VbBuildOption VbScanBuildOption(void)
{
	FILE* f = NULL;
	char buf[4096] = "";
	char *t, *saveptr;
	const char *delimiters = " \r\n";

	f = fopen(KERNEL_CMDLINE_PATH, "r");
	if (NULL != f) {
		if (NULL == fgets(buf, sizeof(buf), f))
			buf[0] = 0;
		fclose(f);
	}
	for (t = strtok_r(buf, delimiters, &saveptr); t;
	     t = strtok_r(NULL, delimiters, &saveptr)) {
		if (0 == strcmp(t, "cros_debug"))
			return VB_BUILD_OPTION_DEBUG;
		else if (0 == strcmp(t, "cros_nodebug"))
			return VB_BUILD_OPTION_NODEBUG;
	}

	return VB_BUILD_OPTION_UNKNOWN;
}

/* Determine whether the running OS image was built for debugging.
 * Returns 1 if yes, 0 if no or indeterminate. */
static vb2_error_t VbGetDebugBuild(void)
{
	return VB_BUILD_OPTION_DEBUG == VbScanBuildOption();
}

/* Determine whether OS-level debugging should be allowed.
 * Returns 1 if yes, 0 if no or indeterminate. */
static int VbGetCrosDebug(void)
{
	/* If the currently running system specifies its debug status, use
	 * that in preference to other indicators. */
	VbBuildOption option = VbScanBuildOption();
	if (VB_BUILD_OPTION_DEBUG == option) {
		return 1;
	} else if (VB_BUILD_OPTION_NODEBUG == option) {
		return 0;
	}

	/* Command line is silent; allow debug if the dev switch is on. */
	if (1 == VbGetSystemPropertyInt("devsw_boot"))
		return 1;

	/* All other cases disallow debug. */
	return 0;
}

static char *GetVdatLoadFirmwareDebug(char *dest, int size,
				      const VbSharedDataHeader *sh)
{
	snprintf(dest, size,
		 "Check A result=%d\n"
		 "Check B result=%d\n"
		 "Firmware index booted=0x%02x\n"
		 "TPM combined version at start=0x%08x\n"
		 "Lowest combined version from firmware=0x%08x\n",
		 sh->check_fw_a_result,
		 sh->check_fw_b_result,
		 sh->firmware_index,
		 sh->fw_version_tpm_start,
		 sh->fw_version_lowest);
	return dest;
}

#define TRUNCATED "\n(truncated)\n"

static char *GetVdatLoadKernelDebug(char *dest, int size,
				    const VbSharedDataHeader *sh)
{
	int used = 0;
	int first_call_tracked = 0;
	int call;

	/* Make sure we have space for truncation warning */
	if (size < strlen(TRUNCATED) + 1)
		return NULL;
	size -= strlen(TRUNCATED) + 1;

	used += snprintf(
	    dest + used, size - used,
	    "Calls to LoadKernel()=%d\n",
	    sh->lk_call_count);
	if (used > size)
		goto LoadKernelDebugExit;

	/* Report on the last calls */
	if (sh->lk_call_count > VBSD_MAX_KERNEL_CALLS)
		first_call_tracked = sh->lk_call_count - VBSD_MAX_KERNEL_CALLS;
	for (call = first_call_tracked; call < sh->lk_call_count; call++) {
		const VbSharedDataKernelCall* shc = sh->lk_calls +
				(call & (VBSD_MAX_KERNEL_CALLS - 1));
		int first_part_tracked = 0;
		int part;

		used += snprintf(dest + used, size - used,
				 "Call %d:\n"
				 "  Boot flags=0x%02x\n"
				 "  Boot mode=%d\n"
				 "  Test error=%d\n"
				 "  Return code=%d\n"
				 "  Debug flags=0x%02x\n"
				 "  Drive sectors=%" PRIu64 "\n"
				 "  Sector size=%d\n"
				 "  Check result=%d\n"
				 "  Kernel partitions found=%d\n",
				 call + 1,
				 shc->boot_flags,
				 shc->boot_mode,
				 shc->test_error_num,
				 shc->return_code,
				 shc->flags,
				 shc->sector_count,
				 shc->sector_size,
				 shc->check_result,
				 shc->kernel_parts_found);
		if (used > size)
			goto LoadKernelDebugExit;

		/* If we found too many partitions, only prints ones where the
		 * structure has info. */
		if (shc->kernel_parts_found > VBSD_MAX_KERNEL_PARTS)
			first_part_tracked = shc->kernel_parts_found -
					VBSD_MAX_KERNEL_PARTS;

		/* Report on the partitions checked */
		for (part = first_part_tracked; part < shc->kernel_parts_found;
		     part++) {
			const VbSharedDataKernelPart* shp = shc->parts +
					(part & (VBSD_MAX_KERNEL_PARTS - 1));

			used += snprintf(dest + used, size - used,
					 "  Kernel %d:\n"
					 "    GPT index=%d\n"
					 "    Start sector=%" PRIu64 "\n"
					 "    Sector count=%" PRIu64 "\n"
					 "    Combined version=0x%08x\n"
					 "    Check result=%d\n"
					 "    Debug flags=0x%02x\n",
					 part + 1,
					 shp->gpt_index,
					 shp->sector_start,
					 shp->sector_count,
					 shp->combined_version,
					 shp->check_result,
					 shp->flags);
			if (used > size)
				goto LoadKernelDebugExit;
		}
	}

LoadKernelDebugExit:

	/* Warn if data was truncated; we left space for this above. */
	if (used > size)
		strcat(dest, TRUNCATED);

	return dest;
}

static char *GetVdatString(char *dest, int size, VdatStringField field)
{
	VbSharedDataHeader *sh = VbSharedDataRead();
	char *value = dest;

	if (!sh)
		return NULL;

	switch (field) {
		case VDAT_STRING_TIMERS:
			snprintf(dest, size,
				 "LFS=%" PRIu64 ",%" PRIu64
				 " LF=%" PRIu64 ",%" PRIu64
				 " LK=%" PRIu64 ",%" PRIu64,
				 sh->timer_vb_init_enter,
				 sh->timer_vb_init_exit,
				 sh->timer_vb_select_firmware_enter,
				 sh->timer_vb_select_firmware_exit,
				 sh->timer_vb_select_and_load_kernel_enter,
				 sh->timer_vb_select_and_load_kernel_exit);
			break;

		case VDAT_STRING_LOAD_FIRMWARE_DEBUG:
			value = GetVdatLoadFirmwareDebug(dest, size, sh);
			break;

		case VDAT_STRING_LOAD_KERNEL_DEBUG:
			value = GetVdatLoadKernelDebug(dest, size, sh);
			break;

		case VDAT_STRING_MAINFW_ACT:
			switch(sh->firmware_index) {
				case 0:
					StrCopy(dest, "A", size);
					break;
				case 1:
					StrCopy(dest, "B", size);
					break;
				case 0xFF:
					StrCopy(dest, "recovery", size);
					break;
				default:
					value = NULL;
			}
			break;

		default:
			value = NULL;
			break;
	}

	free(sh);
	return value;
}

static int GetVdatInt(VdatIntField field)
{
	VbSharedDataHeader* sh = VbSharedDataRead();
	int value = -1;

	if (!sh)
		return -1;

	/* Fields supported in version 1 */
	switch (field) {
		case VDAT_INT_FLAGS:
			value = (int)sh->flags;
			break;
		case VDAT_INT_HEADER_VERSION:
			value = sh->struct_version;
			break;
		case VDAT_INT_TRIED_FIRMWARE_B:
			value = (sh->flags & VBSD_FWB_TRIED ? 1 : 0);
			break;
		case VDAT_INT_KERNEL_KEY_VERIFIED:
			value = (sh->flags & VBSD_KERNEL_KEY_VERIFIED ? 1 : 0);
			break;
		case VDAT_INT_FW_VERSION_TPM:
			value = (int)sh->fw_version_tpm;
			break;
		case VDAT_INT_KERNEL_VERSION_TPM:
			value = (int)sh->kernel_version_tpm;
			break;
		case VDAT_INT_FW_BOOT2:
			value = (sh->flags & VBSD_BOOT_FIRMWARE_VBOOT2 ? 1 : 0);
			VBOOT_FALLTHROUGH;
		default:
			break;
	}

	/* Fields added in struct version 2 */
	if (sh->struct_version >= 2) {
		switch(field) {
			case VDAT_INT_DEVSW_BOOT:
				value = (sh->flags &
					 VBSD_BOOT_DEV_SWITCH_ON ? 1 : 0);
				break;
			case VDAT_INT_RECSW_BOOT:
				value = (sh->flags &
					 VBSD_BOOT_REC_SWITCH_ON ? 1 : 0);
				break;
			case VDAT_INT_RECSW_VIRTUAL:
				value = (sh->flags &
					 VBSD_BOOT_REC_SWITCH_VIRTUAL ? 1 : 0);
				break;
			case VDAT_INT_HW_WPSW_BOOT:
				value = (sh->flags &
					 VBSD_BOOT_FIRMWARE_WP_ENABLED ? 1 : 0);
				break;
			case VDAT_INT_RECOVERY_REASON:
				value = sh->recovery_reason;
				break;
			default:
				break;
		}
	}

	free(sh);
	return value;
}

/* Return version of VbSharedData struct or -1 if not found. */
int VbSharedDataVersion(void)
{
	return GetVdatInt(VDAT_INT_HEADER_VERSION);
}

int VbGetSystemPropertyInt(const char *name)
{
	int value = -1;

	/* Check architecture-dependent properties first */
	value = VbGetArchPropertyInt(name);
	if (-1 != value)
		return value;

	/* NV storage values */
	else if (!strcasecmp(name,"kern_nv")) {
		value = vb2_get_nv_storage(VB2_NV_KERNEL_FIELD);
	} else if (!strcasecmp(name,"nvram_cleared")) {
		value = vb2_get_nv_storage(VB2_NV_KERNEL_SETTINGS_RESET);
	} else if (!strcasecmp(name,"recovery_request")) {
		value = vb2_get_nv_storage(VB2_NV_RECOVERY_REQUEST);
	} else if (!strcasecmp(name,"diagnostic_request")) {
		value = vb2_get_nv_storage(VB2_NV_DIAG_REQUEST);
	} else if (!strcasecmp(name,"dbg_reset")) {
		value = vb2_get_nv_storage(VB2_NV_DEBUG_RESET_MODE);
	} else if (!strcasecmp(name,"disable_dev_request")) {
		value = vb2_get_nv_storage(VB2_NV_DISABLE_DEV_REQUEST);
	} else if (!strcasecmp(name,"clear_tpm_owner_request")) {
		value = vb2_get_nv_storage(VB2_NV_CLEAR_TPM_OWNER_REQUEST);
	} else if (!strcasecmp(name,"clear_tpm_owner_done")) {
		value = vb2_get_nv_storage(VB2_NV_CLEAR_TPM_OWNER_DONE);
	} else if (!strcasecmp(name,"tpm_rebooted")) {
		value = vb2_get_nv_storage(VB2_NV_TPM_REQUESTED_REBOOT);
	} else if (!strcasecmp(name,"fwb_tries") ||
		   !strcasecmp(name,"fw_try_count")) {
		value = vb2_get_nv_storage(VB2_NV_TRY_COUNT);
	} else if (!strcasecmp(name,"fw_vboot2")) {
		value = GetVdatInt(VDAT_INT_FW_BOOT2);
	} else if (!strcasecmp(name,"fwupdate_tries")) {
		value = vb2_get_nv_storage(VB2_NV_KERNEL_FIELD);
		if (value != -1)
			value &= KERN_NV_FWUPDATE_TRIES_MASK;
	} else if (!strcasecmp(name,"block_devmode")) {
		value = vb2_get_nv_storage(VB2_NV_KERNEL_FIELD);
		if (value != -1) {
			value &= KERN_NV_BLOCK_DEVMODE_FLAG;
			value = !!value;
		}
	} else if (!strcasecmp(name,"tpm_attack")) {
		value = vb2_get_nv_storage(VB2_NV_KERNEL_FIELD);
		if (value != -1) {
			value &= KERN_NV_TPM_ATTACK_FLAG;
			value = !!value;
		}
	} else if (!strcasecmp(name,"loc_idx")) {
		value = vb2_get_nv_storage(VB2_NV_LOCALIZATION_INDEX);
	} else if (!strcasecmp(name,"backup_nvram_request")) {
		value = vb2_get_nv_storage(VB2_NV_BACKUP_NVRAM_REQUEST);
	} else if (!strcasecmp(name,"dev_boot_usb")) {
		value = vb2_get_nv_storage(VB2_NV_DEV_BOOT_USB);
	} else if (!strcasecmp(name,"dev_boot_legacy")) {
		value = vb2_get_nv_storage(VB2_NV_DEV_BOOT_LEGACY);
	} else if (!strcasecmp(name,"dev_boot_signed_only")) {
		value = vb2_get_nv_storage(VB2_NV_DEV_BOOT_SIGNED_ONLY);
	} else if (!strcasecmp(name,"dev_enable_udc")) {
		value = vb2_get_nv_storage(VB2_NV_DEV_ENABLE_UDC);
	} else if (!strcasecmp(name,"display_request")) {
		value = vb2_get_nv_storage(VB2_NV_DISPLAY_REQUEST);
	} else if (!strcasecmp(name,"recovery_subcode")) {
		value = vb2_get_nv_storage(VB2_NV_RECOVERY_SUBCODE);
	} else if (!strcasecmp(name,"wipeout_request")) {
		value = vb2_get_nv_storage(VB2_NV_REQ_WIPEOUT);
	} else if (!strcasecmp(name,"kernel_max_rollforward")) {
		value = vb2_get_nv_storage(VB2_NV_KERNEL_MAX_ROLLFORWARD);
	}
	/* Other parameters */
	else if (!strcasecmp(name,"cros_debug")) {
		value = VbGetCrosDebug();
	} else if (!strcasecmp(name,"debug_build")) {
		value = VbGetDebugBuild();
	} else if (!strcasecmp(name,"devsw_boot")) {
		value = GetVdatInt(VDAT_INT_DEVSW_BOOT);
	} else if (!strcasecmp(name, "recoverysw_boot")) {
		value = GetVdatInt(VDAT_INT_RECSW_BOOT);
	} else if (!strcasecmp(name, "recoverysw_is_virtual")) {
		value = GetVdatInt(VDAT_INT_RECSW_VIRTUAL);
	} else if (!strcasecmp(name, "wpsw_boot")) {
		value = GetVdatInt(VDAT_INT_HW_WPSW_BOOT);
	} else if (!strcasecmp(name,"vdat_flags")) {
		value = GetVdatInt(VDAT_INT_FLAGS);
	} else if (!strcasecmp(name,"tpm_fwver")) {
		value = GetVdatInt(VDAT_INT_FW_VERSION_TPM);
	} else if (!strcasecmp(name,"tpm_kernver")) {
		value = GetVdatInt(VDAT_INT_KERNEL_VERSION_TPM);
	} else if (!strcasecmp(name,"tried_fwb")) {
		value = GetVdatInt(VDAT_INT_TRIED_FIRMWARE_B);
	} else if (!strcasecmp(name,"recovery_reason")) {
		value = GetVdatInt(VDAT_INT_RECOVERY_REASON);
	} else if (!strcasecmp(name, "boot_on_ac_detect")) {
		value = vb2_get_nv_storage(VB2_NV_BOOT_ON_AC_DETECT);
	} else if (!strcasecmp(name, "try_ro_sync")) {
		value = vb2_get_nv_storage(VB2_NV_TRY_RO_SYNC);
	} else if (!strcasecmp(name, "battery_cutoff_request")) {
		value = vb2_get_nv_storage(VB2_NV_BATTERY_CUTOFF_REQUEST);
	} else if (!strcasecmp(name, "inside_vm")) {
		/* Detect if the host is a VM. If there is no HWID and the
		 * firmware type is "nonchrome", then assume it is a VM. If
		 * HWID is present, it is a baremetal Chrome OS machine. Other
		 * cases are errors. */
		char hwid[VB_MAX_STRING_PROPERTY];
		if (!VbGetSystemPropertyString("hwid", hwid, sizeof(hwid))) {
			char fwtype_buf[VB_MAX_STRING_PROPERTY];
			const char *fwtype = VbGetSystemPropertyString(
				"mainfw_type", fwtype_buf, sizeof(fwtype_buf));
			if (fwtype && !strcasecmp(fwtype, "nonchrome")) {
				value = 1;
			}
		} else {
			value = 0;
		}
	} else if (!strcasecmp(name, "post_ec_sync_delay")) {
		value = vb2_get_nv_storage(VB2_NV_POST_EC_SYNC_DELAY);
	}

	return value;
}

const char *VbGetSystemPropertyString(const char *name, char *dest,
				      size_t size)
{
	/* Check architecture-dependent properties first */
	if (VbGetArchPropertyString(name, dest, size))
		return dest;

	if (!strcasecmp(name,"kernkey_vfy")) {
		switch(GetVdatInt(VDAT_INT_KERNEL_KEY_VERIFIED)) {
			case 0:
				return "hash";
			case 1:
				return "sig";
			default:
				return NULL;
		}
	} else if (!strcasecmp(name, "mainfw_act")) {
		return GetVdatString(dest, size, VDAT_STRING_MAINFW_ACT);
	} else if (!strcasecmp(name, "vdat_timers")) {
		return GetVdatString(dest, size, VDAT_STRING_TIMERS);
	} else if (!strcasecmp(name, "vdat_lfdebug")) {
		return GetVdatString(dest, size,
				     VDAT_STRING_LOAD_FIRMWARE_DEBUG);
	} else if (!strcasecmp(name, "vdat_lkdebug")) {
		return GetVdatString(dest, size, VDAT_STRING_LOAD_KERNEL_DEBUG);
	} else if (!strcasecmp(name, "fw_try_next")) {
		return vb2_get_nv_storage(VB2_NV_TRY_NEXT) ? "B" : "A";
	} else if (!strcasecmp(name, "fw_tried")) {
		return vb2_get_nv_storage(VB2_NV_FW_TRIED) ? "B" : "A";
	} else if (!strcasecmp(name, "fw_result")) {
		int v = vb2_get_nv_storage(VB2_NV_FW_RESULT);
		if (v < ARRAY_SIZE(fw_results))
			return fw_results[v];
		else
			return "unknown";
	} else if (!strcasecmp(name, "fw_prev_tried")) {
		return vb2_get_nv_storage(VB2_NV_FW_PREV_TRIED) ? "B" : "A";
	} else if (!strcasecmp(name, "fw_prev_result")) {
		int v = vb2_get_nv_storage(VB2_NV_FW_PREV_RESULT);
		if (v < ARRAY_SIZE(fw_results))
			return fw_results[v];
		else
			return "unknown";
	} else if (!strcasecmp(name,"dev_default_boot")) {
		int v = vb2_get_nv_storage(VB2_NV_DEV_DEFAULT_BOOT);
		if (v < ARRAY_SIZE(default_boot))
			return default_boot[v];
		else
			return "unknown";
	}

	return NULL;
}


int VbSetSystemPropertyInt(const char *name, int value)
{
	/* Check architecture-dependent properties first */

	if (0 == VbSetArchPropertyInt(name, value))
		return 0;

	/* NV storage values */
	if (!strcasecmp(name,"nvram_cleared")) {
		/* Can only clear this flag; it's set inside the NV storage
		 * library. */
		return vb2_set_nv_storage(VB2_NV_KERNEL_SETTINGS_RESET, 0);
	} else if (!strcasecmp(name,"recovery_request")) {
		return vb2_set_nv_storage(VB2_NV_RECOVERY_REQUEST, value);
	} else if (!strcasecmp(name,"diagnostic_request")) {
		return vb2_set_nv_storage(VB2_NV_DIAG_REQUEST, value);
	} else if (!strcasecmp(name,"recovery_subcode")) {
		return vb2_set_nv_storage(VB2_NV_RECOVERY_SUBCODE, value);
	} else if (!strcasecmp(name,"dbg_reset")) {
		return vb2_set_nv_storage(VB2_NV_DEBUG_RESET_MODE, value);
	} else if (!strcasecmp(name,"disable_dev_request")) {
		return vb2_set_nv_storage(VB2_NV_DISABLE_DEV_REQUEST, value);
	} else if (!strcasecmp(name,"clear_tpm_owner_request")) {
		return vb2_set_nv_storage(VB2_NV_CLEAR_TPM_OWNER_REQUEST, value);
	} else if (!strcasecmp(name,"clear_tpm_owner_done")) {
		/* Can only clear this flag; it's set by firmware. */
		return vb2_set_nv_storage(VB2_NV_CLEAR_TPM_OWNER_DONE, 0);
	} else if (!strcasecmp(name,"fwb_tries") ||
		   !strcasecmp(name,"fw_try_count")) {
		return vb2_set_nv_storage(VB2_NV_TRY_COUNT, value);
	} else if (!strcasecmp(name,"display_request")) {
		return vb2_set_nv_storage(VB2_NV_DISPLAY_REQUEST, value);
	} else if (!strcasecmp(name,"wipeout_request")) {
		/* Can only clear this flag, set only by firmware. */
		return vb2_set_nv_storage(VB2_NV_REQ_WIPEOUT, 0);
	} else if (!strcasecmp(name,"backup_nvram_request")) {
		/* Best-effort only, since it requires firmware and TPM
		 * support. */
		return vb2_set_nv_storage(VB2_NV_BACKUP_NVRAM_REQUEST, value);
	} else if (!strcasecmp(name,"fwupdate_tries")) {
		int kern_nv = vb2_get_nv_storage(VB2_NV_KERNEL_FIELD);
		if (kern_nv == -1)
			return -1;
		kern_nv &= ~KERN_NV_FWUPDATE_TRIES_MASK;
		kern_nv |= (value & KERN_NV_FWUPDATE_TRIES_MASK);
		return vb2_set_nv_storage_with_backup(
			VB2_NV_KERNEL_FIELD, kern_nv);
	} else if (!strcasecmp(name,"block_devmode")) {
		int kern_nv = vb2_get_nv_storage(VB2_NV_KERNEL_FIELD);
		if (kern_nv == -1)
			return -1;
		kern_nv &= ~KERN_NV_BLOCK_DEVMODE_FLAG;
		if (value)
			kern_nv |= KERN_NV_BLOCK_DEVMODE_FLAG;
		return vb2_set_nv_storage_with_backup(
			VB2_NV_KERNEL_FIELD, kern_nv);
	} else if (!strcasecmp(name,"tpm_attack")) {
		/* This value should only be read and cleared, but we allow
		 * setting it to 1 for testing. */
		int kern_nv = vb2_get_nv_storage(VB2_NV_KERNEL_FIELD);
		if (kern_nv == -1)
			return -1;
		kern_nv &= ~KERN_NV_TPM_ATTACK_FLAG;
		if (value)
			kern_nv |= KERN_NV_TPM_ATTACK_FLAG;
		return vb2_set_nv_storage_with_backup(
			VB2_NV_KERNEL_FIELD, kern_nv);
	} else if (!strcasecmp(name,"loc_idx")) {
		return vb2_set_nv_storage_with_backup(
			VB2_NV_LOCALIZATION_INDEX, value);
	} else if (!strcasecmp(name,"dev_boot_usb")) {
		return vb2_set_nv_storage_with_backup(
			VB2_NV_DEV_BOOT_USB, value);
	} else if (!strcasecmp(name,"dev_boot_legacy")) {
		return vb2_set_nv_storage_with_backup(
			VB2_NV_DEV_BOOT_LEGACY, value);
	} else if (!strcasecmp(name,"dev_boot_signed_only")) {
		return vb2_set_nv_storage_with_backup(
			VB2_NV_DEV_BOOT_SIGNED_ONLY, value);
	} else if (!strcasecmp(name, "dev_enable_udc")) {
		return vb2_set_nv_storage_with_backup(
			VB2_NV_DEV_ENABLE_UDC, value);
	} else if (!strcasecmp(name, "boot_on_ac_detect")) {
		return vb2_set_nv_storage_with_backup(
			VB2_NV_BOOT_ON_AC_DETECT, value);
	} else if (!strcasecmp(name, "try_ro_sync")) {
		return vb2_set_nv_storage_with_backup(
			VB2_NV_TRY_RO_SYNC, value);
	} else if (!strcasecmp(name, "battery_cutoff_request")) {
		return vb2_set_nv_storage(VB2_NV_BATTERY_CUTOFF_REQUEST, value);
	} else if (!strcasecmp(name,"kernel_max_rollforward")) {
		return vb2_set_nv_storage(VB2_NV_KERNEL_MAX_ROLLFORWARD, value);
	} else if (!strcasecmp(name, "post_ec_sync_delay")) {
		return vb2_set_nv_storage(VB2_NV_POST_EC_SYNC_DELAY, value);
	}

	return -1;
}

int VbSetSystemPropertyString(const char* name, const char* value)
{
	/* Chain to architecture-dependent properties */
	if (0 == VbSetArchPropertyString(name, value))
		return 0;

	if (!strcasecmp(name, "fw_try_next")) {
		if (!strcasecmp(value, "A"))
			return vb2_set_nv_storage(VB2_NV_TRY_NEXT, 0);
		else if (!strcasecmp(value, "B"))
			return vb2_set_nv_storage(VB2_NV_TRY_NEXT, 1);
		else
			return -1;

	} else if (!strcasecmp(name, "fw_result")) {
		int i;

		for (i = 0; i < ARRAY_SIZE(fw_results); i++) {
			if (!strcasecmp(value, fw_results[i]))
				return vb2_set_nv_storage(VB2_NV_FW_RESULT, i);
		}
		return -1;
	} else if (!strcasecmp(name, "dev_default_boot")) {
		int i;

		for (i = 0; i < ARRAY_SIZE(default_boot); i++) {
			if (!strcasecmp(value, default_boot[i]))
				return vb2_set_nv_storage(
					VB2_NV_DEV_DEFAULT_BOOT, i);
		}
		return -1;
	}

	return -1;
}

static int InAndroid(void)
{
	int fd;
	struct stat s;
	int retval = 0;

	/*
	 * In Android, mosys utility located in /system/bin check if file
	 * exists.  Using fstat because for some reason, stat() was seg
	 * faulting in Android
	 */
	fd = open(MOSYS_ANDROID_PATH, O_RDONLY);
	if (fd != -1) {
		if (fstat(fd, &s) == 0)
			retval = 1;
		close(fd);
	}
	return retval;
}

static int ExecuteMosys(const char * const argv[], char *buf, size_t bufsize)
{
	int status, mosys_to_crossystem[2];
	pid_t pid;
	ssize_t n;

	if (pipe(mosys_to_crossystem) < 0) {
		fprintf(stderr, "pipe() error\n");
		return -1;
	}

	if ((pid = fork()) < 0) {
		fprintf(stderr, "fork() error\n");
		close(mosys_to_crossystem[0]);
		close(mosys_to_crossystem[1]);
		return -1;
	} else if (!pid) {  /* Child */
		close(mosys_to_crossystem[0]);
		/* Redirect pipe's write-end to mosys' stdout */
		if (STDOUT_FILENO != mosys_to_crossystem[1]) {
			if (dup2(mosys_to_crossystem[1], STDOUT_FILENO)
			    != STDOUT_FILENO) {
				fprintf(stderr, "stdout dup2() failed (mosys)\n");
				close(mosys_to_crossystem[1]);
				exit(1);
			}
		}
		/* Execute mosys (needs cast because POSIX is stupid) */
		execv(InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH,
		      (char * const *)argv);
		/* We shouldn't be here; exit now! */
		fprintf(stderr, "execv() of mosys failed\n");
		close(mosys_to_crossystem[1]);
		exit(1);
	} else {  /* Parent */
		close(mosys_to_crossystem[1]);
		if (bufsize) {
			bufsize--;  /* Reserve 1 byte for '\0' */
			while ((n = read(mosys_to_crossystem[0],
					 buf, bufsize)) > 0) {
				buf += n;
				bufsize -= n;
			}
			*buf = '\0';
		} else {
			n = 0;
		}
		close(mosys_to_crossystem[0]);
		if (n < 0)
			fprintf(stderr, "read() error on output from mosys\n");
		if (waitpid(pid, &status, 0) < 0 || status) {
			fprintf(stderr, "waitpid() or mosys error\n");
			return -1;
		}
		if (n < 0)
			return -1;
	}
	return 0;
}

int vb2_read_nv_storage_mosys(struct vb2_context *ctx)
{
	/* Reserve extra 32 bytes */
	char hexstring[VB2_NVDATA_SIZE_V2 * 2 + 32];
	/*
	 * TODO(rspangler): mosys doesn't know how to read anything but 16-byte
	 * records yet.  When it grows a command line option to do that, call
	 * it here when needed.
	 *
	 * It's possible mosys won't need that.  For example, if if examines
	 * the header byte to determine the records size, or if it calls back
	 * to crossystem to read the VBSD flag.
	 */
	const char * const argv[] = {
		InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH,
		"nvram", "vboot", "read", NULL
	};
	char hexdigit[3];
	const int nvsize = vb2_nv_get_size(ctx);
	int i;

	if (ExecuteMosys(argv, hexstring, sizeof(hexstring)))
		return -1;
	if (strlen(hexstring) < 2 * nvsize) {
		fprintf(stderr, "mosys returned hex nvdata size %d"
			" (need %d)\n", (int)strlen(hexstring), 2 * nvsize);
		return -1;
	}
	hexdigit[2] = '\0';
	for (i = 0; i < nvsize; i++) {
		hexdigit[0] = hexstring[i * 2];
		hexdigit[1] = hexstring[i * 2 + 1];
		ctx->nvdata[i] = strtol(hexdigit, NULL, 16);
	}
	return 0;
}

int vb2_write_nv_storage_mosys(struct vb2_context *ctx)
{
	char hexstring[VB2_NVDATA_SIZE_V2 * 2 + 1];
	const char * const argv[] = {
		InAndroid() ? MOSYS_ANDROID_PATH : MOSYS_CROS_PATH,
		"nvram", "vboot", "write", hexstring, NULL
	};
	const int nvsize = vb2_nv_get_size(ctx);
	int i;

	for (i = 0; i < nvsize; i++)
		snprintf(hexstring + i * 2, 3, "%02x", ctx->nvdata[i]);
	hexstring[sizeof(hexstring) - 1] = '\0';
	if (ExecuteMosys(argv, NULL, 0))
		return -1;
	return 0;
}
