| /* Copyright (c) 2013 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. |
| */ |
| |
| /* APIs provided by firmware to vboot_reference. |
| * |
| * General notes: |
| * |
| * All verified boot functions now start with "Vb" for namespace clarity. This |
| * fixes the problem where uboot and vboot both defined assert(). |
| * |
| * Verified boot APIs to be implemented by the calling firmware and exported to |
| * vboot_reference start with "VbEx". |
| * |
| * TODO: split this file into a vboot_entry_points.h file which contains the |
| * entry points for the firmware to call vboot_reference, and a |
| * vboot_firmware_exports.h which contains the APIs to be implemented by the |
| * calling firmware and exported to vboot_reference. |
| */ |
| |
| #ifndef VBOOT_REFERENCE_VBOOT_API_H_ |
| #define VBOOT_REFERENCE_VBOOT_API_H_ |
| #include <stdint.h> |
| #include <stdlib.h> |
| |
| #include "gpt.h" |
| |
| /*****************************************************************************/ |
| /* Error codes */ |
| |
| /* |
| * Functions which return an error all return this type. This is a 32-bit |
| * value rather than an int so it's consistent across UEFI, which is 32-bit |
| * during PEI and 64-bit during DXE/BDS. |
| */ |
| typedef uint32_t VbError_t; |
| |
| /* |
| * Define test_mockable for mocking functions. |
| */ |
| #define test_mockable __attribute__((weak)) |
| |
| /* |
| * Predefined error numbers. Success is 0. Errors are non-zero, but differ |
| * between functions. For example, the TPM functions may pass through TPM |
| * error codes, some of which may be recoverable. |
| */ |
| enum VbErrorPredefined_t { |
| /* No error; function completed successfully. */ |
| VBERROR_SUCCESS = 0, |
| |
| /* |
| * The verified boot entry points VbInit(), VbSelectFirmware(), |
| * VbSelectAndLoadKernel() may return the following errors. |
| */ |
| /* Unknown error */ |
| VBERROR_UNKNOWN = 0x10000, |
| /* Unable to initialize shared data */ |
| VBERROR_INIT_SHARED_DATA = 0x10001, |
| /* Error resuming TPM during a S3 resume */ |
| VBERROR_TPM_S3_RESUME = 0x10002, |
| /* VbSelectFirmware() failed to find a valid firmware */ |
| VBERROR_LOAD_FIRMWARE = 0x10003, |
| /* Unable to write firmware versions to TPM */ |
| VBERROR_TPM_WRITE_FIRMWARE = 0x10004, |
| /* Unable to lock firmware versions in TPM */ |
| VBERROR_TPM_LOCK_FIRMWARE = 0x10005, |
| /* Unable to set boot mode state in TPM */ |
| VBERROR_TPM_SET_BOOT_MODE_STATE = 0x10006, |
| /* TPM requires reboot */ |
| VBERROR_TPM_REBOOT_REQUIRED = 0x10007, |
| /* Unable to set up TPM */ |
| VBERROR_TPM_FIRMWARE_SETUP = 0x10008, |
| /* Unable to read kernel versions from TPM */ |
| VBERROR_TPM_READ_KERNEL = 0x10009, |
| /* Attempt to load developer-only firmware with developer switch off */ |
| VBERROR_DEV_FIRMWARE_SWITCH_MISMATCH = 0x1000A, |
| /* Unable to write kernel versions to TPM */ |
| VBERROR_TPM_WRITE_KERNEL = 0x1000B, |
| /* Unable to lock kernel versions in TPM */ |
| VBERROR_TPM_LOCK_KERNEL = 0x1000C, |
| /* Calling firmware requested shutdown via VbExIsShutdownRequested() */ |
| VBERROR_SHUTDOWN_REQUESTED = 0x1000D, |
| /* Unable to find a boot device on which to look for a kernel */ |
| VBERROR_NO_DISK_FOUND = 0x1000E, |
| /* No OS kernel found on any boot device */ |
| VBERROR_NO_KERNEL_FOUND = 0x1000F, |
| /* All OS kernels found were invalid (corrupt, improperly signed...) */ |
| VBERROR_INVALID_KERNEL_FOUND = 0x10010, |
| /* VbSelectAndLoadKernel() requested recovery mode */ |
| VBERROR_LOAD_KERNEL_RECOVERY = 0x10011, |
| /* Other error inside VbSelectAndLoadKernel() */ |
| VBERROR_LOAD_KERNEL = 0x10012, |
| /* Invalid Google binary block */ |
| VBERROR_INVALID_GBB = 0x10013, |
| /* Invalid bitmap volume */ |
| VBERROR_INVALID_BMPFV = 0x10014, |
| /* Invalid screen index */ |
| VBERROR_INVALID_SCREEN_INDEX = 0x10015, |
| /* Simulated (test) error */ |
| VBERROR_SIMULATED = 0x10016, |
| /* Invalid parameter */ |
| VBERROR_INVALID_PARAMETER = 0x10017, |
| /* VbExBeep() can't make sounds at all */ |
| VBERROR_NO_SOUND = 0x10018, |
| /* VbExBeep() can't make sound in the background */ |
| VBERROR_NO_BACKGROUND_SOUND = 0x10019, |
| /* Developer has requested a BIOS shell */ |
| VBERROR_BIOS_SHELL_REQUESTED = 0x10020, |
| /* Need VGA and don't have it, or vice-versa */ |
| VBERROR_VGA_OPROM_MISMATCH = 0x10021, |
| /* Need EC to reboot to read-only code */ |
| VBERROR_EC_REBOOT_TO_RO_REQUIRED = 0x10022, |
| /* Invalid region read parameters */ |
| VBERROR_REGION_READ_INVALID = 0x10023, |
| /* Cannot read from region */ |
| VBERROR_REGION_READ_FAILED = 0x10024, |
| /* Unsupported region type */ |
| VBERROR_UNSUPPORTED_REGION = 0x10025, |
| /* No image present (returned from VbGbbReadImage() for missing image) */ |
| VBERROR_NO_IMAGE_PRESENT = 0x10026, |
| /* failed to draw screen */ |
| VBERROR_SCREEN_DRAW = 0x10027, |
| /* failed to jump to RW image */ |
| VBERROR_RW_JUMP_FAILED = 0x10028, |
| |
| /* VbExEcGetExpectedRWHash() may return the following codes */ |
| /* Compute expected RW hash from the EC image; BIOS doesn't have it */ |
| VBERROR_EC_GET_EXPECTED_HASH_FROM_IMAGE = 0x20000, |
| }; |
| |
| |
| /*****************************************************************************/ |
| /* Main entry points from firmware into vboot_reference */ |
| |
| /* |
| * Minimum and recommended size of shared_data_blob in bytes. Shared data blob |
| * is used to communicate data between calls to VbInit(), VbSelectFirmware(), |
| * the OS. Minimum size is enough to hold all required data for verified boot |
| * but may not be able to hold debug output. |
| */ |
| #define VB_SHARED_DATA_MIN_SIZE 3072 |
| #define VB_SHARED_DATA_REC_SIZE 16384 |
| |
| /* |
| * Data passed by firmware to VbInit(), VbSelectFirmware() and |
| * VbSelectAndLoadKernel(). |
| * |
| * Note that in UEFI, these are called by different phases in different |
| * processor modes (VbInit() and VbSelectFirmware() = 32-bit PEI, |
| * VbSelectAndLoadKernel() = 64-bit BDS), so the data may be at a different |
| * location between calls. |
| */ |
| typedef struct VbCommonParams { |
| /* Pointer to GBB data */ |
| void *gbb_data; |
| /* Size of GBB data in bytes */ |
| uint32_t gbb_size; |
| |
| /* |
| * Shared data blob for data shared between verified boot entry points. |
| * This should be at least VB_SHARED_DATA_MIN_SIZE bytes long, and |
| * ideally is VB_SHARED_DATA_REC_SIZE bytes long. |
| */ |
| /* Pointer to shared data blob buffer */ |
| void *shared_data_blob; |
| /* |
| * On input, set to size of shared data blob buffer, in bytes. On |
| * output, this will contain the actual data size placed into the |
| * buffer. |
| */ |
| uint32_t shared_data_size; |
| |
| /* |
| * Internal context/data for verified boot, to maintain state during |
| * calls to other API functions such as VbExHashFirmwareBody(). |
| * Allocated and freed inside the entry point; firmware should not look |
| * at this. |
| */ |
| void *vboot_context; |
| |
| /* |
| * Internal context/data for firmware / VbExHashFirmwareBody(). Needed |
| * because the PEI phase of UEFI boot runs out of ROM and thus can't |
| * modify global variables; everything needs to get passed around on |
| * the stack. |
| */ |
| void *caller_context; |
| |
| /* For internal use of Vboot - do not examine or modify! */ |
| struct GoogleBinaryBlockHeader *gbb; |
| struct BmpBlockHeader *bmp; |
| } VbCommonParams; |
| |
| /* Flags for VbInitParams.flags */ |
| /* Developer switch was on at boot time. */ |
| #define VB_INIT_FLAG_DEV_SWITCH_ON 0x00000001 |
| /* Recovery button was pressed at boot time. */ |
| #define VB_INIT_FLAG_REC_BUTTON_PRESSED 0x00000002 |
| /* Hardware write protect was enabled at boot time. */ |
| #define VB_INIT_FLAG_WP_ENABLED 0x00000004 |
| /* This is a S3 resume, not a normal boot. */ |
| #define VB_INIT_FLAG_S3_RESUME 0x00000008 |
| /* |
| * Previous boot attempt failed for reasons external to verified boot (RAM |
| * init failure, SSD missing, etc.). |
| * |
| * TODO: add a field to VbInitParams which holds a reason code, and report |
| * that via VbSharedData. |
| */ |
| #define VB_INIT_FLAG_PREVIOUS_BOOT_FAIL 0x00000010 |
| /* |
| * Calling firmware supports read only firmware for normal/developer boot path. |
| */ |
| #define VB_INIT_FLAG_RO_NORMAL_SUPPORT 0x00000020 |
| /* |
| * This platform does not have a physical dev-switch, so we must rely on a |
| * virtual switch (kept in the TPM) instead. When this flag is set, |
| * VB_INIT_FLAG_DEV_SWITCH_ON is ignored. |
| */ |
| #define VB_INIT_FLAG_VIRTUAL_DEV_SWITCH 0x00000040 |
| /* Set when the VGA Option ROM has been loaded already. */ |
| #define VB_INIT_FLAG_OPROM_LOADED 0x00000080 |
| /* Set if we care about the VGA Option ROM - some platforms don't. */ |
| #define VB_INIT_FLAG_OPROM_MATTERS 0x00000100 |
| /* EC on this platform supports EC software sync. */ |
| #define VB_INIT_FLAG_EC_SOFTWARE_SYNC 0x00000200 |
| /* EC on this platform is slow to update. */ |
| #define VB_INIT_FLAG_EC_SLOW_UPDATE 0x00000400 |
| /* |
| * Software write protect was enabled at boot time. This is separate from the |
| * HW write protect. Both must be set for flash write protection to work. |
| */ |
| #define VB_INIT_FLAG_SW_WP_ENABLED 0x00000800 |
| /* |
| * This platform does not have a physical recovery switch which, when present, |
| * can (and should) be used for additional physical presence checks. |
| */ |
| #define VB_INIT_FLAG_VIRTUAL_REC_SWITCH 0x00001000 |
| /* Set when we are calling VbInit() before loading Option ROMs */ |
| #define VB_INIT_FLAG_BEFORE_OPROM_LOAD 0x00002000 |
| /* Allow USB boot on transition to dev */ |
| #define VB_INIT_FLAG_ALLOW_USB_BOOT 0x00004000 |
| /* Set when we can't reliably identify boot failures. This prevents |
| * the boot-try counters from decrementing. |
| */ |
| #define VB_INIT_FLAG_NOFAIL_BOOT 0x00008000 |
| |
| /* |
| * Output flags for VbInitParams.out_flags. Used to indicate potential boot |
| * paths and configuration to the calling firmware early in the boot process, |
| * so that it can properly configure itself for the capabilities subsequently |
| * required by VbSelectFirmware() and VbSelectAndLoadKernel(). |
| */ |
| /* |
| * Enable recovery path. Do not rely on any rewritable data (cached RAM |
| * timings, etc.). Reliable operation is more important than boot speed. |
| */ |
| #define VB_INIT_OUT_ENABLE_RECOVERY 0x00000001 |
| /* RAM must be cleared before calling VbSelectFirmware(). */ |
| #define VB_INIT_OUT_CLEAR_RAM 0x00000002 |
| /* |
| * Load display drivers; VbExDisplay*() functions may be called. If this flag |
| * is not present, VbExDisplay*() functions will not be called this boot. |
| */ |
| #define VB_INIT_OUT_ENABLE_DISPLAY 0x00000004 |
| /* |
| * Load USB storage drivers; VbExDisk*() functions may be called with the |
| * VB_DISK_FLAG_REMOVABLE flag. If this flag is not present, VbExDisk*() |
| * functions will only be called for fixed disks. |
| */ |
| #define VB_INIT_OUT_ENABLE_USB_STORAGE 0x00000008 |
| /* If this is a S3 resume, do a debug reset boot instead */ |
| #define VB_INIT_OUT_S3_DEBUG_BOOT 0x00000010 |
| /* BIOS should load any PCI option ROMs it finds, not just internal video */ |
| #define VB_INIT_OUT_ENABLE_OPROM 0x00000020 |
| /* BIOS may be asked to boot something other than ChromeOS */ |
| #define VB_INIT_OUT_ENABLE_ALTERNATE_OS 0x00000040 |
| /* Enable developer path. */ |
| #define VB_INIT_OUT_ENABLE_DEVELOPER 0x00000080 |
| |
| /* Data only used by VbInit() */ |
| typedef struct VbInitParams { |
| /* Inputs to VbInit() */ |
| /* Flags (see VB_INIT_FLAG_*) */ |
| uint32_t flags; |
| |
| /* Outputs from VbInit(); valid only if it returns success. */ |
| /* Output flags for firmware; see VB_INIT_OUT_*) */ |
| uint32_t out_flags; |
| } VbInitParams; |
| |
| /* |
| * Firmware types for VbHashFirmwareBody() and |
| * VbSelectFirmwareParams.selected_firmware. Note that we store these in a |
| * uint32_t because enum maps to int, which isn't fixed-size. |
| */ |
| enum VbSelectFirmware_t { |
| /* Recovery mode */ |
| VB_SELECT_FIRMWARE_RECOVERY = 0, |
| /* Rewritable firmware A/B for normal or developer path */ |
| VB_SELECT_FIRMWARE_A = 1, |
| VB_SELECT_FIRMWARE_B = 2, |
| /* Read only firmware for normal or developer path. */ |
| VB_SELECT_FIRMWARE_READONLY = 3, |
| VB_SELECT_FIRMWARE_COUNT, |
| }; |
| |
| /* Data only used by VbSelectFirmware() */ |
| typedef struct VbSelectFirmwareParams { |
| /* Inputs to VbSelectFirmware() */ |
| /* Key block + preamble for firmware A */ |
| void *verification_block_A; |
| /* Key block + preamble for firmware B */ |
| void *verification_block_B; |
| /* Verification block A size in bytes */ |
| uint32_t verification_size_A; |
| /* Verification block B size in bytes */ |
| uint32_t verification_size_B; |
| |
| /* Outputs from VbSelectFirmware(); valid only if it returns success. */ |
| /* Main firmware to run; see VB_SELECT_FIRMWARE_*. */ |
| uint32_t selected_firmware; |
| } VbSelectFirmwareParams; |
| |
| /* |
| * We use disk handles rather than indices. Using indices causes problems if |
| * a disk is removed/inserted in the middle of processing. |
| */ |
| typedef void *VbExDiskHandle_t; |
| |
| /* Data used only by VbSelectAndLoadKernel() */ |
| typedef struct VbSelectAndLoadKernelParams { |
| /* Inputs to VbSelectAndLoadKernel() */ |
| /* Destination buffer for kernel (normally at 0x100000 on x86) */ |
| void *kernel_buffer; |
| /* Size of kernel buffer in bytes */ |
| uint32_t kernel_buffer_size; |
| |
| /* |
| * Outputs from VbSelectAndLoadKernel(); valid only if it returns |
| * success. |
| */ |
| /* Handle of disk containing loaded kernel */ |
| VbExDiskHandle_t disk_handle; |
| /* Partition number on disk to boot (1...M) */ |
| uint32_t partition_number; |
| /* Address of bootloader image in RAM */ |
| uint64_t bootloader_address; |
| /* Size of bootloader image in bytes */ |
| uint32_t bootloader_size; |
| /* UniquePartitionGuid for boot partition */ |
| uint8_t partition_guid[16]; |
| /* Flags passed in by signer */ |
| uint32_t flags; |
| /* |
| * TODO: in H2C, all that pretty much just gets passed to the |
| * bootloader as KernelBootloaderOptions, though the disk handle is |
| * passed as an index instead of a handle. Is that used anymore now |
| * that we're passing partition_guid? |
| */ |
| } VbSelectAndLoadKernelParams; |
| |
| /** |
| * Initialize the verified boot library. |
| * |
| * Returns VBERROR_SUCCESS if success, non-zero if error; on error, |
| * caller should reboot. |
| */ |
| VbError_t VbInit(VbCommonParams *cparams, VbInitParams *iparams); |
| |
| /** |
| * Select the main firmware. |
| * |
| * Returns VBERROR_SUCCESS if success, non-zero if error; on error, |
| * caller should reboot. |
| * |
| * NOTE: This is now called in all modes, including recovery. Previously, |
| * LoadFirmware() was not called in recovery mode, which meant that |
| * LoadKernel() needed to duplicate the TPM and VbSharedData initialization |
| * code. |
| */ |
| VbError_t VbSelectFirmware(VbCommonParams *cparams, |
| VbSelectFirmwareParams *fparams); |
| |
| /** |
| * Update the data hash for the current firmware image, extending it by [size] |
| * bytes stored in [*data]. This function must only be called inside |
| * VbExHashFirmwareBody(), which is in turn called by VbSelectFirmware(). |
| */ |
| void VbUpdateFirmwareBodyHash(VbCommonParams *cparams, |
| uint8_t *data, uint32_t size); |
| |
| /** |
| * Select and loads the kernel. |
| * |
| * Returns VBERROR_SUCCESS if success, non-zero if error; on error, caller |
| * should reboot. */ |
| VbError_t VbSelectAndLoadKernel(VbCommonParams *cparams, |
| VbSelectAndLoadKernelParams *kparams); |
| |
| /*****************************************************************************/ |
| /* Debug output (from utility.h) */ |
| |
| /** |
| * Output an error message and quit. Does not return. Supports |
| * printf()-style formatting. |
| */ |
| void VbExError(const char *format, ...); |
| |
| /** |
| * Output a debug message. Supports printf()-style formatting. |
| */ |
| void VbExDebug(const char *format, ...) |
| __attribute__ ((format (__printf__, 1, 2))); |
| |
| /*****************************************************************************/ |
| /* Memory (from utility.h) */ |
| |
| /** |
| * Allocate [size] bytes and return a pointer to the allocated memory. Abort |
| * on error; this always either returns a good pointer or never returns. |
| * |
| * If any of the firmware API implementations require aligned data (for |
| * example, disk access on ARM), all pointers returned by VbExMalloc() must |
| * also be aligned. |
| */ |
| void *VbExMalloc(size_t size); |
| |
| /** |
| * Free memory pointed to by [ptr] previously allocated by VbExMalloc(). |
| */ |
| void VbExFree(void *ptr); |
| |
| /*****************************************************************************/ |
| /* Timer and delay (first two from utility.h) */ |
| |
| /** |
| * Read a high-resolution timer. Returns the current timer value in arbitrary |
| * units. |
| * |
| * This is intended for benchmarking, so this call MUST be fast. The timer |
| * frequency must be >1 KHz (preferably >1 MHz), and the timer must not wrap |
| * around for at least 10 minutes. It is preferable (but not required) that |
| * the timer be initialized to 0 at boot. |
| * |
| * It is assumed that the firmware has some other way of communicating the |
| * timer frequency to the OS. For example, on x86 we use TSC, and the OS |
| * kernel reports the initial TSC value at kernel-start and calculates the |
| * frequency. */ |
| uint64_t VbExGetTimer(void); |
| |
| /** |
| * Delay for at least the specified number of milliseconds. Should be accurate |
| * to within 10% (a requested delay of 1000 ms should result in an actual delay |
| * of between 1000 - 1100 ms). |
| */ |
| void VbExSleepMs(uint32_t msec); |
| |
| /** |
| * Play a beep tone of the specified frequency in Hz and duration in msec. |
| * This is effectively a VbSleep() variant that makes noise. |
| * |
| * If the audio codec can run in the background, then: |
| * zero frequency means OFF, non-zero frequency means ON |
| * zero msec means return immediately, non-zero msec means delay (and |
| * then OFF if needed) |
| * otherwise, |
| * non-zero msec and non-zero frequency means ON, delay, OFF, return |
| * zero msec or zero frequency means do nothing and return immediately |
| * |
| * The return value is used by the caller to determine the capabilities. The |
| * implementation should always do the best it can if it cannot fully support |
| * all features - for example, beeping at a fixed frequency if frequency |
| * support is not available. At a minimum, it must delay for the specified |
| * non-zero duration. |
| */ |
| VbError_t VbExBeep(uint32_t msec, uint32_t frequency); |
| |
| /*****************************************************************************/ |
| /* TPM (from tlcl_stub.h) */ |
| |
| /** |
| * Initialize the stub library. */ |
| VbError_t VbExTpmInit(void); |
| |
| /** |
| * Close and open the device. This is needed for running more complex commands |
| * at user level, such as TPM_TakeOwnership, since the TPM device can be opened |
| * only by one process at a time. |
| */ |
| VbError_t VbExTpmClose(void); |
| VbError_t VbExTpmOpen(void); |
| |
| /** |
| * Send a request_length-byte request to the TPM and receive a response. On |
| * input, response_length is the size of the response buffer in bytes. On |
| * exit, response_length is set to the actual received response length in |
| * bytes. */ |
| VbError_t VbExTpmSendReceive(const uint8_t *request, uint32_t request_length, |
| uint8_t *response, uint32_t *response_length); |
| |
| /*****************************************************************************/ |
| /* Non-volatile storage */ |
| |
| #define VBNV_BLOCK_SIZE 16 /* Size of NV storage block in bytes */ |
| |
| /** |
| * Read the VBNV_BLOCK_SIZE-byte non-volatile storage into buf. |
| */ |
| VbError_t VbExNvStorageRead(uint8_t *buf); |
| |
| /** |
| * Write the VBNV_BLOCK_SIZE-byte non-volatile storage from buf. |
| */ |
| VbError_t VbExNvStorageWrite(const uint8_t *buf); |
| |
| /*****************************************************************************/ |
| /* Firmware / EEPROM access (previously in load_firmware_fw.h) */ |
| |
| /** |
| * Calculate the hash of the firmware body data for [firmware_index], which is |
| * either VB_SELECT_FIRMWARE_A or VB_SELECT_FIRMWARE B. |
| * |
| * This function must call VbUpdateFirmwareBodyHash() before returning, to |
| * update the secure hash for the firmware image. For best performance, the |
| * implementation should call VbUpdateFirmwareBodyHash() periodically during |
| * the read, so that updating the hash can be pipelined with the read. If the |
| * reader cannot update the hash during the read process, it should call |
| * VbUpdateFirmwareBodyHash() on the entire firmware data after the read, |
| * before returning. |
| * |
| * It is recommended that the firmware use this call to copy the requested |
| * firmware body from EEPROM into RAM, so that it doesn't need to do a second |
| * slow copy from EEPROM to RAM if this firmware body is selected. |
| * |
| * Note this function doesn't actually pass the firmware body data to verified |
| * boot, because verified boot doesn't actually need the firmware body, just |
| * its hash. This is important on x86, where the firmware is stored |
| * compressed. We hash the compressed data, but the BIOS decompresses it |
| * during read. Simply updating a hash is compatible with the x86 |
| * read-and-decompress pipeline. |
| */ |
| VbError_t VbExHashFirmwareBody(VbCommonParams *cparams, |
| uint32_t firmware_index); |
| |
| /*****************************************************************************/ |
| /* Disk access (previously in boot_device.h) */ |
| |
| /* Flags for VbDisk APIs */ |
| /* Disk is removable. Example removable disks: SD cards, USB keys. */ |
| #define VB_DISK_FLAG_REMOVABLE 0x00000001 |
| /* |
| * Disk is fixed. If this flag is present, disk is internal to the system and |
| * not removable. Example fixed disks: internal SATA SSD, eMMC. |
| */ |
| #define VB_DISK_FLAG_FIXED 0x00000002 |
| /* |
| * Note that VB_DISK_FLAG_REMOVABLE and VB_DISK_FLAG_FIXED are |
| * mutually-exclusive for a single disk. VbExDiskGetInfo() may specify both |
| * flags to request disks of both types in a single call. |
| * |
| * At some point we could specify additional flags, but we don't currently |
| * have a way to make use of these: |
| * |
| * USB Device is known to be attached to USB. Note that the SD |
| * card reader inside x86 systems is attached to USB so this |
| * isn't super useful. |
| * SD Device is known to be a SD card. Note that external card |
| * readers might not return this information, so also of |
| * questionable use. |
| * READ_ONLY Device is known to be read-only. Could be used by recovery |
| * when processing read-only recovery image. |
| */ |
| |
| /* |
| * Disks are used in two ways: |
| * - As a random-access device to read and write the GPT |
| * - As a streaming device to read the kernel |
| * These are implemented differently on raw NAND vs eMMC/SATA/USB |
| * - On eMMC/SATA/USB, both of these refer to the same underlying |
| * storage, so they have the same size and LBA size. In this case, |
| * the GPT should not point to the same address as itself. |
| * - On raw NAND, the GPT is held on a portion of the SPI flash. |
| * Random access GPT operations refer to the SPI and streaming |
| * operations refer to NAND. The GPT may therefore point into |
| * the same offsets as itself. |
| * These types are distinguished by the following flag and VbDiskInfo |
| * has separate fields to describe the random-access ("GPT") and |
| * streaming aspects of the disk. If a disk is random-access (i.e. |
| * not raw NAND) then these fields are equal. |
| */ |
| #define VB_DISK_FLAG_EXTERNAL_GPT 0x00000004 |
| |
| /* Information on a single disk */ |
| typedef struct VbDiskInfo { |
| /* Disk handle */ |
| VbExDiskHandle_t handle; |
| /* Size of a random-access LBA sector in bytes */ |
| uint64_t bytes_per_lba; |
| /* Number of random-access LBA sectors on the device. |
| * If streaming_lba_count is 0, this stands in for the size of the |
| * randomly accessed portion as well as the streaming portion. |
| * Otherwise, this is only the randomly-accessed portion. */ |
| uint64_t lba_count; |
| /* Number of streaming sectors on the device */ |
| uint64_t streaming_lba_count; |
| /* Flags (see VB_DISK_FLAG_* constants) */ |
| uint32_t flags; |
| /* |
| * Optional name string, for use in debugging. May be empty or null if |
| * not available. |
| */ |
| const char *name; |
| } VbDiskInfo; |
| |
| /** |
| * Store information into [info] for all disks (storage devices) attached to |
| * the system which match all of the disk_flags. |
| * |
| * On output, count indicates how many disks are present, and [infos_ptr] |
| * points to a [count]-sized array of VbDiskInfo structs with the information |
| * on those disks; this pointer must be freed by calling VbExDiskFreeInfo(). |
| * If count=0, infos_ptr may point to NULL. If [infos_ptr] points to NULL |
| * because count=0 or error, it is not necessary to call VbExDiskFreeInfo(). |
| * |
| * A multi-function device (such as a 4-in-1 card reader) should provide |
| * multiple disk handles. |
| * |
| * The firmware must not alter or free the list pointed to by [infos_ptr] until |
| * VbExDiskFreeInfo() is called. |
| */ |
| VbError_t VbExDiskGetInfo(VbDiskInfo **infos_ptr, uint32_t *count, |
| uint32_t disk_flags); |
| |
| /** |
| * Free a disk information list [infos] previously returned by |
| * VbExDiskGetInfo(). If [preserve_handle] != NULL, the firmware must ensure |
| * that handle remains valid after this call; all other handles from the info |
| * list need not remain valid after this call. |
| */ |
| VbError_t VbExDiskFreeInfo(VbDiskInfo *infos, |
| VbExDiskHandle_t preserve_handle); |
| |
| /** |
| * Read lba_count LBA sectors, starting at sector lba_start, from the disk, |
| * into the buffer. |
| * |
| * This is used for random access to the GPT. It is not for the partition |
| * contents. The upper limit is lba_count. |
| * |
| * If the disk handle is invalid (for example, the handle refers to a disk |
| * which as been removed), the function must return error but must not |
| * crash. |
| */ |
| VbError_t VbExDiskRead(VbExDiskHandle_t handle, uint64_t lba_start, |
| uint64_t lba_count, void *buffer); |
| |
| /** |
| * Write lba_count LBA sectors, starting at sector lba_start, to the disk, from |
| * the buffer. |
| * |
| * This is used for random access to the GPT. It does not (necessarily) access |
| * the streaming portion of the device. |
| * |
| * If the disk handle is invalid (for example, the handle refers to a disk |
| * which as been removed), the function must return error but must not |
| * crash. |
| */ |
| VbError_t VbExDiskWrite(VbExDiskHandle_t handle, uint64_t lba_start, |
| uint64_t lba_count, const void *buffer); |
| |
| /* Streaming read interface */ |
| typedef void *VbExStream_t; |
| |
| /** |
| * Open a stream on a disk |
| * |
| * @param handle Disk to open the stream against |
| * @param lba_start Starting sector offset within the disk to stream from |
| * @param lba_count Maximum extent of the stream in sectors |
| * @param stream out-paramter for the generated stream |
| * |
| * @return Error code, or VBERROR_SUCCESS. |
| * |
| * This is used for access to the contents of the actual partitions on the |
| * device. It is not used to access the GPT. The size of the content addressed |
| * is within streaming_lba_count. |
| */ |
| VbError_t VbExStreamOpen(VbExDiskHandle_t handle, uint64_t lba_start, |
| uint64_t lba_count, VbExStream_t *stream_ptr); |
| |
| /** |
| * Read from a stream on a disk |
| * |
| * @param stream Stream to read from |
| * @param bytes Number of bytes to read |
| * @param buffer Destination to read into |
| * |
| * @return Error code, or VBERROR_SUCCESS. Failure to read as much data as |
| * requested is an error. |
| * |
| * This is used for access to the contents of the actual partitions on the |
| * device. It is not used to access the GPT. |
| */ |
| VbError_t VbExStreamRead(VbExStream_t stream, uint32_t bytes, void *buffer); |
| |
| /** |
| * Close a stream |
| * |
| * @param stream Stream to close |
| */ |
| void VbExStreamClose(VbExStream_t stream); |
| |
| |
| /*****************************************************************************/ |
| /* Display */ |
| |
| /* Predefined (default) screens for VbExDisplayScreen(). */ |
| enum VbScreenType_t { |
| /* Blank (clear) screen */ |
| VB_SCREEN_BLANK = 0, |
| /* Developer - warning */ |
| VB_SCREEN_DEVELOPER_WARNING = 0x101, |
| /* Developer - easter egg */ |
| VB_SCREEN_DEVELOPER_EGG = 0x102, |
| /* Recovery - remove inserted devices */ |
| VB_SCREEN_RECOVERY_REMOVE = 0x201, |
| /* Recovery - insert recovery image */ |
| VB_SCREEN_RECOVERY_INSERT = 0x202, |
| /* Recovery - inserted image invalid */ |
| VB_SCREEN_RECOVERY_NO_GOOD = 0x203, |
| /* Recovery - confirm dev mode */ |
| VB_SCREEN_RECOVERY_TO_DEV = 0x204, |
| /* Developer - confirm normal mode */ |
| VB_SCREEN_DEVELOPER_TO_NORM = 0x205, |
| /* Please wait - programming EC */ |
| VB_SCREEN_WAIT = 0x206, |
| /* Confirm after DEVELOPER_TO_NORM */ |
| VB_SCREEN_TO_NORM_CONFIRMED = 0x207, |
| /* Broken screen shown after verification failure */ |
| VB_SCREEN_OS_BROKEN = 0x208, |
| }; |
| |
| /** |
| * Initialize and clear the display. Set width and height to the screen |
| * dimensions in pixels. |
| */ |
| VbError_t VbExDisplayInit(uint32_t *width, uint32_t *height); |
| |
| /** |
| * Enable (enable!=0) or disable (enable=0) the display backlight. |
| */ |
| VbError_t VbExDisplayBacklight(uint8_t enable); |
| |
| /** |
| * Sets the logical dimension to display. |
| * |
| * If the physical display is larger or smaller than given dimension, display |
| * provider may decide to scale or shift images (from VbExDisplayImage)to proper |
| * location. |
| */ |
| VbError_t VbExDisplaySetDimension(uint32_t width, uint32_t height); |
| |
| /** |
| * Display a predefined screen; see VB_SCREEN_* for valid screens. |
| * |
| * This is a backup method of screen display, intended for use if the GBB does |
| * not contain a full set of bitmaps. It is acceptable for the backup screen |
| * to be simple ASCII text such as "NO GOOD" or "INSERT"; these screens should |
| * only be seen during development. |
| */ |
| VbError_t VbExDisplayScreen(uint32_t screen_type, uint32_t locale); |
| |
| /** |
| * Write an image to the display, with the upper left corner at the specified |
| * pixel coordinates. The bitmap buffer is a pointer to the platform-dependent |
| * uncompressed binary blob with dimensions and format specified internally |
| * (for example, a raw BMP, GIF, PNG, whatever). We pass the size just for |
| * convenience. |
| */ |
| VbError_t VbExDisplayImage(uint32_t x, uint32_t y, |
| void *buffer, uint32_t buffersize); |
| |
| /** |
| * Display a string containing debug information on the screen, rendered in a |
| * platform-dependent font. Should be able to handle newlines '\n' in the |
| * string. Firmware must support displaying at least 20 lines of text, where |
| * each line may be at least 80 characters long. If the firmware has its own |
| * debug state, it may display it to the screen below this information. |
| * |
| * NOTE: This is what we currently display when TAB is pressed. Some |
| * information (HWID, recovery reason) is ours; some (CMOS breadcrumbs) is |
| * platform-specific. If we decide to soft-render the HWID string |
| * (chrome-os-partner:3693), we'll need to maintain our own fonts, so we'll |
| * likely display it via VbExDisplayImage() above. |
| */ |
| VbError_t VbExDisplayDebugInfo(const char *info_str); |
| |
| /*****************************************************************************/ |
| /* Keyboard and switches */ |
| |
| /* Key codes for required non-printable-ASCII characters. */ |
| enum VbKeyCode_t { |
| VB_KEY_UP = 0x100, |
| VB_KEY_DOWN = 0x101, |
| VB_KEY_LEFT = 0x102, |
| VB_KEY_RIGHT = 0x103, |
| VB_KEY_CTRL_ENTER = 0x104, |
| }; |
| |
| /* Flags for additional information. |
| * TODO(semenzato): consider adding flags for modifiers instead of |
| * making up some of the key codes above. |
| */ |
| enum VbKeyFlags_t { |
| VB_KEY_FLAG_TRUSTED_KEYBOARD = 1 << 0, |
| }; |
| |
| /** |
| * Read the next keypress from the keyboard buffer. |
| * |
| * Returns the keypress, or zero if no keypress is pending or error. |
| * |
| * The following keys must be returned as ASCII character codes: |
| * 0x08 Backspace |
| * 0x09 Tab |
| * 0x0D Enter (carriage return) |
| * 0x01 - 0x1A Ctrl+A - Ctrl+Z (yes, those alias with backspace/tab/enter) |
| * 0x1B Esc |
| * 0x20 Space |
| * 0x30 - 0x39 '0' - '9' |
| * 0x60 - 0x7A 'a' - 'z' |
| * |
| * Some extended keys must also be supported; see the VB_KEY_* defines above. |
| * |
| * Keys ('/') or key-chords (Fn+Q) not defined above may be handled in any of |
| * the following ways: |
| * 1. Filter (don't report anything if one of these keys is pressed). |
| * 2. Report as ASCII (if a well-defined ASCII value exists for the key). |
| * 3. Report as any other value in the range 0x200 - 0x2FF. |
| * It is not permitted to report a key as a multi-byte code (for example, |
| * sending an arrow key as the sequence of keys '\x1b', '[', '1', 'A'). */ |
| uint32_t VbExKeyboardRead(void); |
| |
| /** |
| * Same as VbExKeyboardRead(), but return extra information. |
| */ |
| uint32_t VbExKeyboardReadWithFlags(uint32_t *flags_ptr); |
| |
| /** |
| * Return the current state of the switches specified in request_mask |
| */ |
| uint32_t VbExGetSwitches(uint32_t request_mask); |
| |
| /*****************************************************************************/ |
| /* Embedded controller (EC) */ |
| |
| /* |
| * All these functions take a devidx parameter, which indicates which embedded |
| * processor the call applies to. At present, only devidx=0 is valid, but |
| * upcoming CLs will add support for multiple devices. |
| */ |
| |
| /** |
| * This is called only if the system implements a keyboard-based (virtual) |
| * developer switch. It must return true only if the system has an embedded |
| * controller which is provably running in its RO firmware at the time the |
| * function is called. |
| */ |
| int VbExTrustEC(int devidx); |
| |
| /** |
| * Check if the EC is currently running rewritable code. |
| * |
| * If the EC is in RO code, sets *in_rw=0. |
| * If the EC is in RW code, sets *in_rw non-zero. |
| * If the current EC image is unknown, returns error. */ |
| VbError_t VbExEcRunningRW(int devidx, int *in_rw); |
| |
| /** |
| * Request the EC jump to its rewritable code. If successful, returns when the |
| * EC has booting its RW code far enough to respond to subsequent commands. |
| * Does nothing if the EC is already in its rewritable code. |
| */ |
| VbError_t VbExEcJumpToRW(int devidx); |
| |
| /** |
| * Tell the EC to refuse another jump until it reboots. Subsequent calls to |
| * VbExEcJumpToRW() in this boot will fail. |
| */ |
| VbError_t VbExEcDisableJump(int devidx); |
| |
| /** |
| * Read the SHA-256 hash of the selected EC image. |
| */ |
| VbError_t VbExEcHashImage(int devidx, enum VbSelectFirmware_t select, |
| const uint8_t **hash, int *hash_size); |
| |
| /** |
| * Get the expected contents of the EC image associated with the main firmware |
| * specified by the "select" argument. |
| */ |
| VbError_t VbExEcGetExpectedImage(int devidx, enum VbSelectFirmware_t select, |
| const uint8_t **image, int *image_size); |
| |
| /** |
| * Read the SHA-256 hash of the expected contents of the EC image associated |
| * with the main firmware specified by the "select" argument. |
| */ |
| VbError_t VbExEcGetExpectedImageHash(int devidx, enum VbSelectFirmware_t select, |
| const uint8_t **hash, int *hash_size); |
| |
| /** |
| * Update the selected EC image. |
| */ |
| VbError_t VbExEcUpdateImage(int devidx, enum VbSelectFirmware_t select, |
| const uint8_t *image, int image_size); |
| |
| /** |
| * Lock the selected EC code to prevent updates until the EC is rebooted. |
| * Subsequent calls to VbExEcUpdateImage() with the same region this boot will |
| * fail. |
| */ |
| VbError_t VbExEcProtect(int devidx, enum VbSelectFirmware_t select); |
| |
| /** |
| * Info the EC of the boot mode selected by the AP. |
| * mode: Normal, Developer, or Recovery |
| */ |
| enum VbEcBootMode_t {VB_EC_NORMAL, VB_EC_DEVELOPER, VB_EC_RECOVERY }; |
| VbError_t VbExEcEnteringMode(int devidx, enum VbEcBootMode_t mode); |
| |
| /** |
| * Perform EC post-verification / updating / jumping actions. |
| * |
| * This routine is called to perform certain actions that must wait until |
| * after the EC resides in its `final` image (the image the EC will |
| * run for the duration of boot). These actions include verifying that |
| * enough power is available to continue with boot. |
| * |
| * @param in_recovery 1 if recovery mode is selected by the AP, 0 otherwise. |
| * @return VBERROR_... error, VBERROR_SUCCESS on success. |
| */ |
| VbError_t VbExEcVbootDone(int in_recovery); |
| |
| /*****************************************************************************/ |
| /* Misc */ |
| |
| /* Args to VbExProtectFlash() */ |
| enum VbProtectFlash_t { VBPROTECT_RW_A, VBPROTECT_RW_B, VBPROTECT_RW_DEVKEY }; |
| |
| /** |
| * Lock a section of the BIOS flash address space to prevent updates until the |
| * host is rebooted. Subsequent attempts to erase or modify the specified BIOS |
| * image will fail. If this function is called more than once each call should |
| * be cumulative. |
| */ |
| VbError_t VbExProtectFlash(enum VbProtectFlash_t region); |
| |
| /** |
| * Check if the firmware needs to shut down the system. |
| * |
| * Returns a non-zero VB_SHUTDOWN_REQUEST mask indicating the reason(s) for |
| * shutdown if a shutdown is being requested (see VB_SHUTDOWN_REQUEST_*), or 0 |
| * if a shutdown is not being requested. |
| * |
| * NOTE: When we're displaying a screen, pressing the power button should shut |
| * down the computer. We need a way to break out of our control loop so this |
| * can occur cleanly. |
| */ |
| uint32_t VbExIsShutdownRequested(void); |
| |
| /* |
| * Shutdown requested for a reason which is not defined among other |
| * VB_SHUTDOWN_REQUEST_* values. This must be defined as 1 for backward |
| * compatibility with old versions of the API. |
| */ |
| #define VB_SHUTDOWN_REQUEST_OTHER 0x00000001 |
| /* Shutdown requested due to a lid switch being closed. */ |
| #define VB_SHUTDOWN_REQUEST_LID_CLOSED 0x00000002 |
| /* Shutdown requested due to a power button being pressed. */ |
| #define VB_SHUTDOWN_REQUEST_POWER_BUTTON 0x00000004 |
| |
| /** |
| * Expose the BIOS' built-in decompression routine to the vboot wrapper. The |
| * caller must know how large the uncompressed data will be and must manage |
| * that memory. The decompression routine just puts the uncompressed data into |
| * the specified buffer. We pass in the size of the outbuf, and get back the |
| * actual size used. |
| */ |
| VbError_t VbExDecompress(void *inbuf, uint32_t in_size, |
| uint32_t compression_type, |
| void *outbuf, uint32_t *out_size); |
| |
| /* Constants for compression_type */ |
| enum { |
| COMPRESS_NONE = 0, |
| COMPRESS_EFIv1, /* The x86 BIOS only supports this */ |
| COMPRESS_LZMA1, /* The ARM BIOS supports LZMA1 */ |
| MAX_COMPRESS, |
| }; |
| |
| /** |
| * Execute legacy boot option. |
| */ |
| int VbExLegacy(void); |
| |
| /* Regions for VbExRegionRead() */ |
| enum vb_firmware_region { |
| VB_REGION_GBB, /* Google Binary Block - see gbbheader.h */ |
| |
| VB_REGION_COUNT, |
| }; |
| |
| /** |
| * Read data from a region of the firmware image |
| * |
| * Vboot wants access to a region, to read data from it. This function |
| * reads it (typically from the firmware image such as SPI flash) and |
| * returns the data. |
| * |
| * cparams is passed so that the boot loader has some context for the |
| * operation. |
| * |
| * @param cparams Common parameters, e.g. use member caller_context |
| * to point to useful context data |
| * @param region Firmware region to read |
| * @param offset Start offset within region |
| * @param size Number of bytes to read |
| * @param buf Place to put data |
| * @return VBERROR_... error, VBERROR_SUCCESS on success, |
| */ |
| VbError_t VbExRegionRead(VbCommonParams *cparams, |
| enum vb_firmware_region region, uint32_t offset, |
| uint32_t size, void *buf); |
| |
| /** |
| * Verify Kernel Image loaded in memory. |
| * |
| * This routine is used by fastboot boot command to verify the kernel image in |
| * memory sent by the host device using fastboot protocol. It checks if the |
| * image in memory is signed using official recovery keys. In case of GBB |
| * override to allow full fastboot functionality, it checks image integrity, but |
| * does not check the image signature. |
| * |
| * @param cparams Common parameters, e.g. use member caller_context |
| * to point to useful context data |
| * @param kparams kernel params |
| * @param boot_image Image in memory that needs to be verified |
| * @param image_size Size of the image in memory |
| * @return VBERROR_... error, VBERROR_SUCCESS on success. |
| */ |
| VbError_t VbVerifyMemoryBootImage(VbCommonParams *cparams, |
| VbSelectAndLoadKernelParams *kparams, |
| void *boot_image, |
| size_t image_size); |
| |
| /** |
| * Fastboot API to enter dev mode. |
| * |
| * This routine is used by fastboot oem unlock command to switch the device into |
| * dev mode. |
| * |
| * NOTE: The caller MUST be in read-only firmware, and MUST have just obtained |
| * explicit physical confirmation from the user via a trusted input method |
| * before calling this function! Also, on successful return from this function, |
| * the caller needs to reboot the device immediately for changes to take effect. |
| * |
| * @return VBERROR_... error, VBERROR_SUCCESS on success. |
| */ |
| VbError_t VbUnlockDevice(void); |
| |
| /** |
| * Fastboot API to enter normal mode. |
| * |
| * This routine is used by fastboot oem lock command to switch the device into |
| * normal mode. |
| * |
| * NOTE: On successful return from this function, the caller needs to reboot the |
| * device immediately for changes to take effect. This routine just stores a |
| * request, which will be handled by RO firmware on next reboot. |
| * |
| * @return VBERROR_... error, VBERROR_SUCCESS on success. |
| */ |
| VbError_t VbLockDevice(void); |
| |
| /** |
| * Check if the firmware wants to override GPT entry priority. |
| * |
| * In case of kernel entry, check if there is an override of priority |
| * available. This is used to select a particular partition to boot in the |
| * current boot cycle. Rollback protection, image verification and all other |
| * checks in LoadKernel still remain the same. |
| * |
| * @param e Gpt Entry to check for priority override. |
| * @return 0 if no override, 1-15 for override priority. |
| */ |
| uint8_t VbExOverrideGptEntryPriority(const GptEntry *e); |
| |
| /** |
| * Return number of locales supported |
| * |
| * @param count Pointer to the number of locales. |
| * @return VBERROR_... error, VBERROR_SUCCESS on success. |
| */ |
| VbError_t VbExGetLocalizationCount(uint32_t *count); |
| #endif /* VBOOT_REFERENCE_VBOOT_API_H_ */ |