int cros_cboot_twostop_read_bmp_block(void)
{
	/* Yet another use of this evil #define */
#ifndef CONFIG_HARDWARE_MAPPED_SPI

	firmware_storage_t file;
	int ret;

	if (have_read_gbb_bmp_block)
		return 0;

	if (!fmap.readonly.fmap.length &&
	    cros_fdtdec_flashmap(gd->fdt_blob, &fmap)) {
		VBDEBUG("failed to decode fmap\n");
		return -1;
	}

	if (firmware_storage_open_spi(&file)) {
		VBDEBUG("failed to open firmware storage\n");
		return -1;
	}

	ret = gbb_read_bmp_block(static_gbb, &file, fmap.readonly.gbb.offset,
				  fmap.readonly.gbb.length);
	file.close(&file);
	if (ret)
		return -1;
	have_read_gbb_bmp_block = 1;
#endif /* CONFIG_HARDWARE_MAPPED_SPI */
	return 0;
}
int vboot_flag_dump(enum vboot_flag_id id, struct vboot_flag_details *details)
{
#ifdef VBOOT_DEBUG
	struct vboot_flag_details local_details;

	if (id < 0 || id >= VBOOT_FLAG_MAX_FLAGS) {
		VBDEBUG("id out of range: %d\n", id);
		return -1;
	}

	if (details == NULL) {
		if (vboot_flag_fetch(id, &local_details)) {
			VBDEBUG("failed to get vboot_flag details of %s\n",
				 vboot_flag_node_name(id));
			return -1;
		}
		details = &local_details;
	}

	VBDEBUG("%-24s: port=%3d, active_high=%d, value=%d\n",
			vboot_flag_node_name(id),
			details->port, details->active_high, details->value);
#endif
	return 0;
}
static int
do_vboot_twostop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	uint32_t selection;
	int ro_firmware;

	bootstage_mark_name(BOOTSTAGE_VBOOT_TWOSTOP, "do_vboot_twostop");

	/*
	 * Empty keyboard buffer before boot.  In case EC did not clear its
	 * buffer between power cycles, this prevents vboot of current power
	 * cycle being affected by keystrokes of previous power cycle.
	 */
	while (tstc())
		getc();

	if (cros_init()) {
		VBDEBUG("fail to init cros library\n");
		goto on_error;
	}

	/*
	 * TODO: We should clear screen later if we load graphics optionally.
	 * In normal mode, we don't need to load graphics driver and clear
	 * screen.
	 */
	display_clear();

	/*
	 * A processor reset jumps to the reset entry point (which is the
	 * read-only firmware), otherwise we have entered U-Boot from a
	 * software jump.
	 *
	 * Note: If a read-only firmware is loaded to memory not because of a
	 * processor reset, this instance of read-only firmware should go to the
	 * readwrite firmware code path.
	 */
	ro_firmware = is_processor_reset();
	VBDEBUG("Starting %s firmware\n", ro_firmware ? "read-only" :
			"read-write");
	if (ro_firmware)
		selection = twostop_boot(0);
	else
		selection = twostop_readwrite_main_firmware();

	VBDEBUG("selection of main firmware: %s\n",
			str_selection(selection));

	if (selection == TWOSTOP_SELECT_COMMAND_LINE)
		return 0;

	if (selection == TWOSTOP_SELECT_POWER_OFF)
		power_off();

	assert(selection == TWOSTOP_SELECT_ERROR);

on_error:
	cold_reboot();
	return 0;
}
Beispiel #4
0
uint8_t* ReadFile(const char* filename, uint64_t* sizeptr) {
  FILE* f;
  uint8_t* buf;
  uint64_t size;

  f = fopen(filename, "rb");
  if (!f) {
    VBDEBUG(("Unable to open file %s\n", filename));
    return NULL;
  }

  fseek(f, 0, SEEK_END);
  size = ftell(f);
  rewind(f);

  buf = malloc(size);
  if (!buf) {
    fclose(f);
    return NULL;
  }

  if(1 != fread(buf, size, 1, f)) {
    VBDEBUG(("Unable to read from file %s\n", filename));
    fclose(f);
    free(buf);
    return NULL;
  }

  fclose(f);
  if (sizeptr)
    *sizeptr = size;
  return buf;
}
static int vboot_flag_fetch_sysinfo(enum vboot_flag_id id,
				    struct vboot_flag_context *context,
				    struct vboot_flag_details *details)
{
	const void *blob = gd->fdt_blob;
	const struct fdt_property *prop;
	int len, i, p;

	prop = fdt_get_property(blob, context->node, "google,name", &len);
	if (!prop) {
		VBDEBUG("failed to read name of %s\n",
			vboot_flag_node_name(id));
		return -1;
	}

	for (i = 0; i < lib_sysinfo.num_gpios; i++) {
		if (strncmp((char *)lib_sysinfo.gpios[i].name, prop->data,
						GPIO_MAX_NAME_LENGTH))
			continue;

		/* Entry found */
		details->port = lib_sysinfo.gpios[i].port;
		details->active_high = lib_sysinfo.gpios[i].polarity;
		p = details->active_high ? 0 : 1;
		details->value = p ^ lib_sysinfo.gpios[i].value;

		return 0;
	}

	VBDEBUG("failed to find gpio port for %s\n", vboot_flag_node_name(id));
	return -1;
}
int RestoreNvFromBackup(VbNvContext *vnc)
{
	VbNvContext bvnc;
	uint32_t value;
	int i;

	VBDEBUG(("TPM: %s()\n", __func__));

	if (TPM_SUCCESS != RollbackBackupRead(bvnc.raw))
		return 1;

	VbNvSetup(&bvnc);
	if (bvnc.regenerate_crc) {
		VBDEBUG(("TPM: Oops, backup is no good.\n"));
		return 1;
	}

	for (i = 0; i < ARRAY_SIZE(backup_params); i++) {
		VbNvGet(&bvnc, backup_params[i], &value);
		VbNvSet(vnc, backup_params[i], value);
	}

	/* VbNvTeardown(&bvnc); is not needed. We're done with it. */
	return 0;
}
Beispiel #7
0
/* Like TlclSendReceive below, but do not retry if NEEDS_SELFTEST or
 * DOING_SELFTEST errors are returned.
 */
static uint32_t tlcl_send_receive_no_retry(const uint8_t* request,
                                           uint8_t* response, int max_length) {
	uint32_t response_length = max_length;
	uint32_t result;

	result = tpm_send_receive(request, tpm_command_size(request),
					response, &response_length);
	if (0 != result) {
		/* Communication with TPM failed, so response is garbage */
		VBDEBUG("TPM: command 0x%x send/receive failed: 0x%x\n",
			tpm_command_code(request), result);
		return result;
	}
	/* Otherwise, use the result code from the response */
	result = tpm_return_code(response);

	/* TODO: add paranoia about returned response_length vs. max_length
	 * (and possibly expected length from the response header).  See
	 * crosbug.com/17017 */

	VBDEBUG("TPM: command 0x%x returned 0x%x\n",
		tpm_command_code(request), result);

return result;
}
Beispiel #8
0
static uint32_t write_secdata(uint32_t index,
			      const uint8_t *secdata,
			      uint32_t len)
{
	uint8_t sd[32];
	uint32_t rv;
	int attempts = 3;

	if (len > sizeof(sd)) {
		VBDEBUG("TPM: %s() - data is too large\n", __func__);
		return TPM_E_WRITE_FAILURE;
	}

	while (attempts--) {
		rv = safe_write(index, secdata, len);
		/* Can't write, not gonna try again */
		if (rv != TPM_SUCCESS)
			return rv;

		/* Read it back to be sure it got the right values. */
		rv = tlcl_read(index, sd, len);
		if (rv == TPM_SUCCESS && memcmp(secdata, sd, len) == 0)
			return rv;

		VBDEBUG("TPM: %s() failed. trying again\n", __func__);
		/* Try writing it again. Maybe it was garbled on the way out. */
	}

	VBDEBUG("TPM: %s() - too many failures, giving up\n", __func__);

	return TPM_E_CORRUPTED_STATE;
}
/* Write-protect portions of the RW flash until the next boot. */
VbError_t VbExProtectFlash(enum VbProtectFlash_t region)
{
#ifdef CONFIG_CAN_PROTECT_RW_FLASH
	switch (region) {
	case VBPROTECT_RW_A:
		VBDEBUG("VBPROTECT_RW_A => 0x%08x 0x%x\n",
			fmap.readwrite_a.all.offset,
			fmap.readwrite_a.all.length);
		spi_write_protect_region(fmap.readwrite_a.all.offset,
					 fmap.readwrite_a.all.length, 0);
		break;
	case VBPROTECT_RW_B:
		VBDEBUG("VBPROTECT_RW_B => 0x%08x 0x%x\n",
			fmap.readwrite_b.all.offset,
			fmap.readwrite_b.all.length);
		spi_write_protect_region(fmap.readwrite_b.all.offset,
					 fmap.readwrite_b.all.length, 0);
		break;
	case VBPROTECT_RW_DEVKEY:
		VBDEBUG("VBPROTECT_RW_DEVKEY => 0x%08x 0x%x\n",
			fmap.readwrite_devkey.offset,
			fmap.readwrite_devkey.length);
		spi_write_protect_region(fmap.readwrite_devkey.offset,
					 fmap.readwrite_devkey.length, 1);
		break;
	default:
		VBDEBUG("unknown region %d\n", region);
		return VBERROR_INVALID_PARAMETER;
	}
	return VBERROR_SUCCESS;
#else
	VBDEBUG("%s not implemented on this platform\n", __func__);
	return VBERROR_UNKNOWN;
#endif
}
int VbSharedDataInit(VbSharedDataHeader *header, uint64_t size)
{
	VBDEBUG(("VbSharedDataInit, %d bytes, header %d bytes\n", (int)size,
		 (int)sizeof(VbSharedDataHeader)));

	if (size < sizeof(VbSharedDataHeader)) {
		VBDEBUG(("Not enough data for header.\n"));
		return VBOOT_SHARED_DATA_INVALID;
	}
	if (size < VB_SHARED_DATA_MIN_SIZE) {
		VBDEBUG(("Shared data buffer too small.\n"));
		return VBOOT_SHARED_DATA_INVALID;
	}

	if (!header)
		return VBOOT_SHARED_DATA_INVALID;

	/* Zero the header */
	Memset(header, 0, sizeof(VbSharedDataHeader));

	/* Initialize fields */
	header->magic = VB_SHARED_DATA_MAGIC;
	header->struct_version = VB_SHARED_DATA_VERSION;
	header->struct_size = sizeof(VbSharedDataHeader);
	header->data_size = size;
	header->data_used = sizeof(VbSharedDataHeader);
	header->firmware_index = 0xFF;

	/* Success */
	return VBOOT_SUCCESS;
}
VbError_t VbUnlockDevice(void)
{
    VBDEBUG(("%s() Enabling dev-mode...\n", __func__));
    if (TPM_SUCCESS != SetVirtualDevMode(1))
        return VBERROR_TPM_SET_BOOT_MODE_STATE;

    VBDEBUG(("%s() Mode change will take effect on next reboot.\n",
             __func__));
    return VBERROR_SUCCESS;
}
/**
 * Wrapper around VbExEcProtectRW() which sets recovery reason on error.
 */
static VbError_t EcProtectRW(int devidx)
{
    int rv = VbExEcProtectRW(devidx);

    if (rv == VBERROR_EC_REBOOT_TO_RO_REQUIRED) {
        VBDEBUG(("VbExEcProtectRW() needs reboot\n"));
    } else if (rv != VBERROR_SUCCESS) {
        VBDEBUG(("VbExEcProtectRW() returned %d\n", rv));
        VbSetRecoveryRequest(VBNV_RECOVERY_EC_PROTECT);
    }
    return rv;
}
static uint32_t
twostop_readwrite_main_firmware(void)
{
	crossystem_data_t *cdata;
	void *gbb;
	size_t gbb_size;

	if (!fmap.readonly.fmap.length &&
	    cros_fdtdec_flashmap(gd->fdt_blob, &fmap)) {
		VBDEBUG("failed to decode fmap\n");
		return TWOSTOP_SELECT_ERROR;
	}
	dump_fmap(&fmap);

#ifdef CONFIG_HARDWARE_MAPPED_SPI
	gbb = (void *) (fmap.readonly.gbb.offset + fmap.flash_base);
#endif
	if (setup_gbb_and_cdata(&gbb, &gbb_size, &cdata, 1))
		return TWOSTOP_SELECT_ERROR;
	static_gbb = gbb;

#ifdef CONFIG_ARM
	uint8_t ro_nvtype = cdata->board.arm.nonvolatile_context_storage;
	if (ro_nvtype == NONVOLATILE_STORAGE_NONE) {
		/*
		 * Default to disk for older RO firmware which does not provide
		 * storage type.
		 */
		cdata->board.arm.nonvolatile_context_storage =
			NONVOLATILE_STORAGE_DISK;
	} else {
		/* RW has to use the storage type that RO was using. */
		if (nvstorage_set_type(ro_nvtype))
			return TWOSTOP_SELECT_ERROR;
	}
#endif /* CONFIG_ARM */

	/*
	 * VbSelectAndLoadKernel() assumes the TPM interface has already been
	 * initialized by VbSelectFirmware(). Since we haven't called
	 * VbSelectFirmware() in the readwrite firmware, we need to explicitly
	 * initialize the TPM interface. Note that this only re-initializes the
	 * interface, not the TPM itself.
	 */
	if (VbExTpmInit() != TPM_SUCCESS) {
		VBDEBUG("failed to init tpm interface\n");
		return TWOSTOP_SELECT_ERROR;
	}

	/* TODO Now, initialize device that bootstub did not initialize */

	return twostop_main_firmware(&fmap, gbb, cdata, cdata->vb_shared_data);
}
Beispiel #14
0
uint64_t VbSharedDataReserve(VbSharedDataHeader *header, uint64_t size)
{
	uint64_t offs = header->data_used;

	VBDEBUG(("VbSharedDataReserve %d bytes at %d\n", (int)size, (int)offs));

	if (!header || size > header->data_size - header->data_used) {
		VBDEBUG(("VbSharedData buffer out of space.\n"));
		return 0;  /* Not initialized, or not enough space left. */
	}
	header->data_used += size;
	return offs;
}
static void VbTryLegacy(int allowed)
{
    if (!allowed)
        VBDEBUG(("VbBootDeveloper() - Legacy boot is disabled\n"));
    else if (0 != RollbackKernelLock(0))
        VBDEBUG(("Error locking kernel versions on legacy boot.\n"));
    else
        VbExLegacy();	/* will not return if successful */

    /* If legacy boot fails, beep and return to calling UI loop. */
    VbExBeep(120, 400);
    VbExSleepMs(120);
    VbExBeep(120, 400);
}
void jump_to_firmware(void (*firmware_entry_point)(void))
{
	VBDEBUG(PREFIX "jump to firmware %p\n", firmware_entry_point);

	cleanup_before_linux();

	/* should never return! */
	firmware_entry_point();

	/* FIXME(clchiou) Bring up a sad face as boot has failed */
	enable_interrupts();
	VBDEBUG(PREFIX "error: firmware returns\n");
	while (1);
}
static int
twostop_init_cparams(struct twostop_fmap *fmap, void *gbb,
		     void *vb_shared_data, VbCommonParams *cparams)
{
	cparams->gbb_data = gbb;
	cparams->gbb_size = fmap->readonly.gbb.length;
#ifdef CONFIG_SYS_COREBOOT
	cparams->shared_data_blob =
		&((chromeos_acpi_t *)lib_sysinfo.vdat_addr)->vdat;
	cparams->shared_data_size =
		sizeof(((chromeos_acpi_t *)lib_sysinfo.vdat_addr)->vdat);
#else
	cparams->shared_data_blob = vb_shared_data;
	cparams->shared_data_size = VB_SHARED_DATA_REC_SIZE;
#endif
#define P(format, field) \
	VBDEBUG("- %-20s: " format "\n", #field, cparams->field)

	VBDEBUG("cparams:\n");
	P("%p",   gbb_data);
	P("%08x", gbb_size);
	P("%p",   shared_data_blob);
	P("%08x", shared_data_size);

#undef P

	return 0;
}
static void* MMapFile(const char* filename, size_t *size) {
  FILE* f;
  uint8_t* buf;
  long file_size = 0;

  f = fopen(filename, "rb");
  if (!f) {
    VBDEBUG(("Unable to open file %s\n", filename));
    return NULL;
  }

  fseek(f, 0, SEEK_END);
  file_size = ftell(f);
  rewind(f);

  if (file_size <= 0) {
    fclose(f);
    return NULL;
  }
  *size = (size_t) file_size;

  /* Uses a host primitive as this is not meant for firmware use. */
  buf = mmap(NULL, *size, PROT_READ, MAP_PRIVATE, fileno(f), 0);
  if (buf == MAP_FAILED) {
    VbExError("Failed to mmap the file %s\n", filename);
    fclose(f);
    return NULL;
  }

  fclose(f);
  return buf;
}
VbError_t test_mockable
VbBootNormal(VbCommonParams *cparams, LoadKernelParams *p)
{
    /* Boot from fixed disk only */
    VBDEBUG(("Entering %s()\n", __func__));
    return VbTryLoadKernel(cparams, p, VB_DISK_FLAG_FIXED);
}
Beispiel #20
0
int WriteFile(const char* filename, const void *data, uint64_t size) {
  FILE *f = fopen(filename, "wb");
  if (!f) {
    VBDEBUG(("Unable to open file %s\n", filename));
    return 1;
  }

  if (1 != fwrite(data, size, 1, f)) {
    VBDEBUG(("Unable to write to file %s\n", filename));
    fclose(f);
    unlink(filename);  /* Delete any partial file */
  }

  fclose(f);
  return 0;
}
static int flash_sw_wp_is_enabled(firmware_storage_t *file)
{
	uint8_t yes_it_is = 0;

#ifdef CONFIG_SPI_FLASH
	int r = 0;
	r = spi_flash_read_sw_wp_status(file->context, &yes_it_is);
	if (r) {
		VBDEBUG("spi_flash_read_sw_wp_status() failed: %d\n", r);
		return 0;
	}
#endif

	VBDEBUG("flash SW WP is %d\n", yes_it_is);
	return yes_it_is;
}
Beispiel #22
0
int VbSharedDataSetKernelKey(VbSharedDataHeader *header, const VbPublicKey *src)
{
	VbPublicKey *kdest = &header->kernel_subkey;

	VBDEBUG(("Saving kernel subkey to shared data: size %d, algo %d\n",
		 siglen_map[src->algorithm], (int)src->algorithm));

	if (!header)
		return VBOOT_SHARED_DATA_INVALID;

	/* Attempt to allocate space for key, if it hasn't been allocated yet */
	if (!header->kernel_subkey_data_offset) {
		header->kernel_subkey_data_offset =
			VbSharedDataReserve(header, src->key_size);
		if (!header->kernel_subkey_data_offset)
			return VBOOT_SHARED_DATA_INVALID;
		header->kernel_subkey_data_size = src->key_size;
	}

	/* Copy the kernel sign key blob into the destination buffer */
	PublicKeyInit(kdest,
		      (uint8_t *)header + header->kernel_subkey_data_offset,
		      header->kernel_subkey_data_size);

	return PublicKeyCopy(kdest, src);
}
VbError_t nvstorage_write_disk(const uint8_t *buf)
{
	VbDiskInfo *internal_disk;
	uint8_t *block_buf;

	if (get_internal_disk(&internal_disk))
		return 1;

	if (get_nvcxt_block_of_disk(internal_disk, &block_buf))
		return 1;

	memcpy(block_buf, buf, VBNV_BLOCK_SIZE);

	if (VbExDiskWrite(internal_disk->handle,
				CHROMEOS_VBNVCONTEXT_LBA, 1, block_buf)) {
		VBDEBUG("Failed to write internal disk!\n");
		VbExFree(block_buf);
		return 1;
	}

	VbExFree(block_buf);

#ifdef CONFIG_EXYNOS5
	/*
	 * XXX(chrome-os-partner:10415): On Exynos, reliable write operations
	 * need write busy time; so add a delay here.  In the long run, we
	 * should avoid using eMMC as VbNvContext storage media.
	 */
	mdelay(1);
#endif

	return VBERROR_SUCCESS;
}
int VbNvSet(VbNvContext *context, VbNvParam param, uint32_t value)
{
	VBDEBUG(("%s(): got_recovery_request_val = %d (0x%x)\n", __FUNCTION__,
		 value, value));
	got_recovery_request_val = value;
	return 0;
}
VbError_t VbExDiskGetInfo(VbDiskInfo **infos_ptr, uint32_t *count,
                          uint32_t disk_flags)
{
	int i;
	int num_disks = 0;

	VBDEBUG(("My %s\n", __FUNCTION__));

	*infos_ptr = mock_disks;

	for(i = 0; i < MAX_TEST_DISKS; i++) {
		if (is_nonzero(&t->disks_to_provide[i],
			       sizeof(t->disks_to_provide[i]))) {
			mock_disks[num_disks].bytes_per_lba =
				t->disks_to_provide[i].bytes_per_lba;
			mock_disks[num_disks].lba_count =
				mock_disks[num_disks].streaming_lba_count =
				t->disks_to_provide[i].lba_count;
			mock_disks[num_disks].flags =
				t->disks_to_provide[i].flags;
			mock_disks[num_disks].handle = (VbExDiskHandle_t)
				t->disks_to_provide[i].diskname;
			VBDEBUG(("  mock_disk[%d] %" PRIu64 " %" PRIu64
				 " 0x%x %s\n", i,
				 mock_disks[num_disks].bytes_per_lba,
				 mock_disks[num_disks].lba_count,
				 mock_disks[num_disks].flags,
				 (mock_disks[num_disks].handle
				  ? (char *)mock_disks[num_disks].handle
				  : "0")));
			num_disks++;
		} else {
			mock_disks[num_disks].handle =
				(VbExDiskHandle_t)"INVALID";
		}
	}

	if (t->disk_count_to_return >= 0)
		*count = t->disk_count_to_return;
	else
		*count = num_disks;

	VBDEBUG(("  *count=%" PRIu32 "\n", *count));
	VBDEBUG(("  return 0x%x\n", t->diskgetinfo_return_val));

	return t->diskgetinfo_return_val;
}
Beispiel #26
0
uint32_t tlcl_set_deactivated(uint8_t flag)
{
	struct s_tpm_physicalsetdeactivated_cmd cmd;
	VBDEBUG("TPM: SetDeactivated(%d)\n", flag);
	memcpy(&cmd, &tpm_physicalsetdeactivated_cmd, sizeof(cmd));
	*(cmd.buffer + cmd.deactivated) = flag;
	return send(cmd.buffer);
}
Beispiel #27
0
static uint32_t read_space_firmware(struct vb2_context *ctx)
{
	int attempts = 3;

	while (attempts--) {
		RETURN_ON_FAILURE(tlcl_read(FIRMWARE_NV_INDEX, ctx->secdata,
		                            VB2_SECDATA_SIZE));

		if (vb2api_secdata_check(ctx) == VB2_SUCCESS)
			return TPM_SUCCESS;

		VBDEBUG("TPM: %s() - bad CRC\n", __func__);
	}

	VBDEBUG("TPM: %s() - too many bad CRCs, giving up\n", __func__);
	return TPM_E_CORRUPTED_STATE;
}
VbError_t VbExDiskFreeInfo(VbDiskInfo *infos,
                           VbExDiskHandle_t preserve_handle)
{
	got_load_disk = (const char *)preserve_handle;
	VBDEBUG(("%s(): got_load_disk = %s\n", __FUNCTION__,
		 got_load_disk ? got_load_disk : "0"));
	return VBERROR_SUCCESS;
}
Beispiel #29
0
uint32_t tlcl_continue_self_test(void)
{
	uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
	VBDEBUG("TPM: Continue self test\n");
	/* Call the No Retry version of SendReceive to avoid recursion. */
	return tlcl_send_receive_no_retry(tpm_continueselftest_cmd.buffer,
	                                  response, sizeof(response));
}
Beispiel #30
0
uint32_t tpm_clear_and_reenable(void)
{
	VBDEBUG("TPM: Clear and re-enable\n");
	RETURN_ON_FAILURE(tlcl_force_clear());
	RETURN_ON_FAILURE(tlcl_set_enable());
	RETURN_ON_FAILURE(tlcl_set_deactivated(0));

	return TPM_SUCCESS;
}