blob: 4c5e1dc6b249b7a4b1592c2b0940893e30bd70a1 [file] [log] [blame]
/* 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 between calling firmware and vboot_reference
*
* General notes:
*
* 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.
*
* Notes:
* * Assumes this code is never called in the S3 resume path. TPM resume
* must be done elsewhere, and VB2_NV_DEBUG_RESET_MODE is ignored.
*/
#ifndef VBOOT_REFERENCE_2API_H_
#define VBOOT_REFERENCE_2API_H_
#include "2constants.h"
#include "2crypto.h"
#include "2fw_hash_tags.h"
#include "2gbb_flags.h"
#include "2id.h"
#include "2recovery_reasons.h"
#include "2return_codes.h"
#include "2rsa.h"
#include "2secdata_struct.h"
#define _VB2_TRY_IMPL(expr, ctx, recovery_reason, ...) do { \
vb2_error_t _vb2_try_rv = (expr); \
struct vb2_context *_vb2_try_ctx = (ctx); \
uint8_t _vb2_try_reason = (recovery_reason); \
if (_vb2_try_rv != VB2_SUCCESS) { \
vb2ex_printf(__func__, \
"%s returned %#x\n", #expr, _vb2_try_rv); \
if (_vb2_try_rv >= VB2_REQUEST_END && \
(_vb2_try_ctx) && \
(_vb2_try_reason) != VB2_RECOVERY_NOT_REQUESTED) \
vb2api_fail(_vb2_try_ctx, _vb2_try_reason, \
_vb2_try_rv); \
return _vb2_try_rv; \
} \
} while (0)
/*
* Evaluate an expression and return *from the caller* on failure or if an
* action (such as reboot) is requested.
*
* This macro supports two forms of usage:
* 1. VB2_TRY(expr)
* 2. VB2_TRY(expr, ctx, recovery_reason)
*
* When the second form is used, vb2api_fail() will be called on failure before
* return. Note that nvdata only holds one byte for recovery subcode, so any
* other more significant bytes will be truncated.
*
* @param expr An expression (such as a function call) of type
* vb2_error_t.
* @param ctx Vboot context.
* @param recovery_reason Recovery reason passed to vb2api_fail().
*/
#define VB2_TRY(expr, ...) _VB2_TRY_IMPL(expr, ##__VA_ARGS__, NULL, 0)
/* Flags for vb2_context.
*
* Unless otherwise noted, flags are set by verified boot and may be read (but
* not set or cleared) by the caller.
*/
enum vb2_context_flags {
/*
* Verified boot has changed nvdata[]. Caller must save nvdata[] back
* to its underlying storage, then may clear this flag.
*/
VB2_CONTEXT_NVDATA_CHANGED = (1 << 0),
/*
* Verified boot has changed secdata_firmware[]. Caller must save
* secdata_firmware[] back to its underlying storage, then may clear
* this flag.
*/
VB2_CONTEXT_SECDATA_FIRMWARE_CHANGED = (1 << 1),
/* Recovery mode is requested this boot */
VB2_CONTEXT_RECOVERY_MODE = (1 << 2),
/* Developer mode is requested this boot */
VB2_CONTEXT_DEVELOPER_MODE = (1 << 3),
/*
* Force recovery mode due to physical user request. Caller may set
* this flag when initializing the context.
*/
VB2_CONTEXT_FORCE_RECOVERY_MODE = (1 << 4),
/*
* Force developer mode enabled. Caller may set this flag when
* initializing the context. Previously used for forcing developer
* mode with physical dev switch.
*
* Deprecated as part of chromium:942901.
*/
VB2_CONTEXT_DEPRECATED_FORCE_DEVELOPER_MODE = (1 << 5),
/* Using firmware slot B. If this flag is clear, using slot A. */
VB2_CONTEXT_FW_SLOT_B = (1 << 6),
/* RAM should be cleared by caller this boot */
VB2_CONTEXT_CLEAR_RAM = (1 << 7),
/* Wipeout by the app should be requested. */
VB2_CONTEXT_FORCE_WIPEOUT_MODE = (1 << 8),
/* Erase developer mode state if it is enabled. */
VB2_CONTEXT_DISABLE_DEVELOPER_MODE = (1 << 9),
/*
* Verified boot has changed secdata_kernel[]. Caller must save
* secdata_kernel[] back to its underlying storage, then may clear
* this flag.
*/
VB2_CONTEXT_SECDATA_KERNEL_CHANGED = (1 << 10),
/*
* Allow kernel verification to roll forward the version in
* secdata_kernel[]. Caller may set this flag before calling
* vb2api_kernel_phase3().
*/
VB2_CONTEXT_ALLOW_KERNEL_ROLL_FORWARD = (1 << 11),
/*
* Boot optimistically: don't touch failure counters. Caller may set
* this flag when initializing the context.
*/
VB2_CONTEXT_NOFAIL_BOOT = (1 << 12),
/*
* secdata is not ready this boot, but should be ready next boot. It
* would like to reboot. The decision whether to reboot or not must be
* deferred until vboot, because rebooting all the time before then
* could cause a device with malfunctioning secdata to get stuck in an
* unrecoverable crash loop.
*/
VB2_CONTEXT_SECDATA_WANTS_REBOOT = (1 << 13),
/*
* Boot is S3->S0 resume, not S5->S0 normal boot. Caller may set this
* flag when initializing the context.
*/
VB2_CONTEXT_S3_RESUME = (1 << 14),
/*
* System supports EC software sync. Caller may set this flag at any
* time before calling VbSelectAndLoadKernel().
*/
VB2_CONTEXT_EC_SYNC_SUPPORTED = (1 << 15),
/*
* EC software sync is slow to update; warning screen should be
* displayed. Caller may set this flag at any time before calling
* VbSelectAndLoadKernel(). Deprecated as part of chromium:1038259.
*/
VB2_CONTEXT_DEPRECATED_EC_SYNC_SLOW = (1 << 16),
/*
* EC firmware supports early firmware selection; two EC images exist,
* and EC may have already verified and jumped to EC-RW prior to EC
* software sync. Deprecated as part of chromium:1038259.
*/
VB2_CONTEXT_DEPRECATED_EC_EFS = (1 << 17),
/*
* NV storage uses data format V2. Data is size VB2_NVDATA_SIZE_V2,
* not VB2_NVDATA_SIZE.
*
* Caller must set this flag when initializing the context to use V2.
* (Vboot cannot infer the data size from the data itself, because the
* data provided by the caller could be uninitialized.)
*/
VB2_CONTEXT_NVDATA_V2 = (1 << 18),
/* Allow vendor data to be set via the vendor data ui. */
VB2_CONTEXT_VENDOR_DATA_SETTABLE = (1 << 19),
/*
* Caller may set this before running vb2api_fw_phase1. In this case,
* it means: "Display is available on this boot. Please advertise
* as such to downstream vboot code and users."
*
* vboot may also set this before returning from vb2api_fw_phase1.
* In this case, it means: "Please initialize display so that it is
* available to downstream vboot code and users." This is used when
* vboot encounters some internally-generated request for display
* support.
*/
VB2_CONTEXT_DISPLAY_INIT = (1 << 20),
/*
* Caller may set this before running vb2api_kernel_phase1. It means
* that there is no FWMP on this system, and thus default values should
* be used instead.
*
* Caller should *not* set this when FWMP is available but invalid.
*/
VB2_CONTEXT_NO_SECDATA_FWMP = (1 << 21),
/*
* Enable detachable menu ui (volume up/down + power).
*
* Deprecated with CL:1975390.
*/
VB2_CONTEXT_DEPRECATED_DETACHABLE_UI = (1 << 22),
/*
* NO_BOOT means the OS is not allowed to boot. Only relevant for EFS2.
*/
VB2_CONTEXT_NO_BOOT = (1 << 23),
};
/* Helper for aligning fields in vb2_context. */
#define VB2_PAD_STRUCT3(size, align, count) \
uint8_t _pad##count[align - (((size - 1) % align) + 1)]
#define VB2_PAD_STRUCT2(size, align, count) VB2_PAD_STRUCT3(size, align, count)
#define VB2_PAD_STRUCT(size, align) VB2_PAD_STRUCT2(size, align, __COUNTER__)
/*
* Context for firmware verification. Pass this to all vboot APIs.
*
* Context is stored as part of vb2_shared_data, initialized with vb2api_init().
* Subsequent retrieval of the context object should be done by calling
* vb2api_reinit(), e.g. if switching firmware applications.
*
* The context struct can be seen as the "publicly accessible" portion of
* vb2_shared_data, and thus does not require its own magic and version fields.
*/
struct vb2_context {
/**********************************************************************
* Fields caller must initialize before calling any API functions.
*/
/*
* Flags; see vb2_context_flags. Some flags may only be set by caller
* prior to calling vboot functions.
*/
uint64_t flags;
/*
* Non-volatile data. Caller must fill this from some non-volatile
* location before calling vb2api_fw_phase1. If the
* VB2_CONTEXT_NVDATA_CHANGED flag is set when a vb2api function
* returns, caller must save the data back to the non-volatile location
* and then clear the flag.
*/
uint8_t nvdata[VB2_NVDATA_SIZE_V2];
VB2_PAD_STRUCT(VB2_NVDATA_SIZE_V2, 8);
/*
* Secure data for firmware verification stage. Caller must fill this
* from some secure non-volatile location before calling
* vb2api_fw_phase1. If the VB2_CONTEXT_SECDATA_CHANGED flag is set
* when a function returns, caller must save the data back to the
* secure non-volatile location and then clear the flag.
*/
uint8_t secdata_firmware[VB2_SECDATA_FIRMWARE_SIZE];
VB2_PAD_STRUCT(VB2_SECDATA_FIRMWARE_SIZE, 8);
/**********************************************************************
* Fields caller must initialize before calling vb2api_kernel_phase1().
*/
/*
* Secure data for kernel verification stage. Caller must fill this
* from some secure non-volatile location before calling
* vb2api_kernel_phase1. If the VB2_CONTEXT_SECDATA_KERNEL_CHANGED
* flag is set when a function returns, caller must save the data back
* to the secure non-volatile location and then clear the flag.
*/
uint8_t secdata_kernel[VB2_SECDATA_KERNEL_MAX_SIZE];
VB2_PAD_STRUCT(VB2_SECDATA_KERNEL_MAX_SIZE, 8);
/*
* Firmware management parameters (FWMP) secure data. Caller must fill
* this from some secure non-volatile location before calling
* vb2api_kernel_phase1. Since FWMP is a variable-size space, caller
* should initially fill in VB2_SECDATA_FWMP_MIN_SIZE bytes, and call
* vb2_secdata_fwmp_check() to see whether more should be read. If the
* VB2_CONTEXT_SECDATA_FWMP_CHANGED flag is set when a function
* returns, caller must save the data back to the secure non-volatile
* location and then clear the flag.
*/
uint8_t secdata_fwmp[VB2_SECDATA_FWMP_MAX_SIZE];
VB2_PAD_STRUCT(VB2_SECDATA_FWMP_MAX_SIZE, 8);
};
/* Resource index for vb2ex_read_resource() */
enum vb2_resource_index {
/* Google binary block */
VB2_RES_GBB,
/*
* Firmware verified boot block (keyblock+preamble). Use
* VB2_CONTEXT_FW_SLOT_B to determine whether this refers to slot A or
* slot B; vboot will set that flag to the proper state before reading
* the vblock.
*/
VB2_RES_FW_VBLOCK,
/*
* Kernel verified boot block (keyblock+preamble) for the current
* kernel partition. Used only by vb2api_kernel_load_vblock().
* Contents are allowed to change between calls to that function (to
* allow multiple kernels to be examined).
*/
VB2_RES_KERNEL_VBLOCK,
};
/* Digest ID for vbapi_get_pcr_digest() */
enum vb2_pcr_digest {
/* Digest based on current developer and recovery mode flags */
BOOT_MODE_PCR,
/* SHA-256 hash digest of HWID, from GBB */
HWID_DIGEST_PCR,
};
/******************************************************************************
* APIs provided by verified boot.
*
* At a high level, call functions in the order described below. After each
* call, examine vb2_context.flags to determine whether nvdata or secdata
* needs to be written.
*
* If you need to cause the boot process to fail at any point, call
* vb2api_fail(). Then check vb2_context.flags to see what data needs to be
* written. Then reboot.
*
* Load nvdata from wherever you keep it.
*
* Load secdata_firmware from wherever you keep it.
*
* If it wasn't there at all (for example, this is the first boot
* of a new system in the factory), call
* vb2api_secdata_firmware_create() to initialize the data.
*
* If access to your storage is unreliable (reads/writes may
* contain corrupt data), you may call
* vb2api_secdata_firmware_check() to determine if the data was
* valid, and retry reading if it wasn't. (In that case, you
* should also read back and check the data after any time you
* write it, to make sure it was written correctly.)
*
* Call vb2api_fw_phase1(). At present, this nominally decides whether
* recovery mode is needed this boot.
*
* Call vb2api_fw_phase2(). At present, this nominally decides which
* firmware slot will be attempted (A or B).
*
* Call vb2api_fw_phase3(). At present, this nominally verifies the
* firmware keyblock and preamble.
*
* Lock down wherever you keep secdata_firmware. It should no longer be
* writable this boot.
*
* Verify the hash of each section of code/data you need to boot the RW
* firmware. For each section:
*
* Call vb2_init_hash() to see if the hash exists.
*
* Load the data for the section. Call vb2_extend_hash() on the
* data as you load it. You can load it all at once and make one
* call, or load and hash-extend a block at a time.
*
* Call vb2_check_hash() to see if the hash is valid.
*
* If it is valid, you may use the data and/or execute
* code from that section.
*
* If the hash was invalid, you must reboot.
*
* At this point, firmware verification is done, and vb2_context contains the
* kernel key needed to verify the kernel. That context should be preserved
* and passed on to kernel selection. The kernel selection process may be
* done by the same firmware image, or may be done by the RW firmware. The
* recommended order is:
*
* Load secdata_kernel from wherever you keep it.
*
* If it wasn't there at all (for example, this is the first boot
* of a new system in the factory), call
* vb2api_secdata_kernel_create() to initialize the data.
*
* If access to your storage is unreliable (reads/writes may
* contain corrupt data), you may call
* vb2api_secdata_kernel_check() to determine if the data was
* valid, and retry reading if it wasn't. (In that case, you
* should also read back and check the data after any time you
* write it, to make sure it was written correctly.)
*
* Call vb2api_kernel_phase1(). At present, this decides which key to
* use to verify kernel data - the recovery key from the GBB, or the
* kernel subkey from the firmware verification stage.
*
* Kernel phase 2 is finding loading, and verifying the kernel partition.
*
* Find a boot device (you're on your own here).
*
* Call vb2api_load_kernel_vblock() for each kernel partition on the
* boot device, until one succeeds.
*
* When that succeeds, call vb2api_get_kernel_size() to determine where
* the kernel is located in the stream and how big it is. Load or map
* the kernel. (Again, you're on your own. This is the responsibility of
* the caller so that the caller can choose whether to allocate a buffer,
* load the kernel data into a predefined area of RAM, or directly map a
* kernel file into the address space. Note that technically it doesn't
* matter whether the kernel data is even in the same file or stream as
* the vblock, as long as the caller loads the right data.
*
* Call vb2api_verify_kernel_data() on the kernel data.
*
* If you ran out of kernels before finding a good one, call vb2api_fail()
* with an appropriate recovery reason.
*
* Set the VB2_CONTEXT_ALLOW_KERNEL_ROLL_FORWARD flag if the current
* kernel partition has the successful flag (that is, it's already known
* or assumed to be a functional kernel partition).
*
* Call vb2api_kernel_phase3(). This cleans up from kernel verification
* and updates the secure data if needed.
*
* Lock down wherever you keep secdata_kernel. It should no longer be
* writable this boot.
*/
/**
* Initialize verified boot data structures.
*
* Needs to be called once per boot, before using any API functions that
* accept a vb2_context object. Sets up the vboot work buffer, as well as
* vb2_shared_data and vb2_context. A pointer to the context object is
* written to ctxptr. After transitioning between different firmware
* applications, or any time the context pointer is lost, vb2api_reinit()
* should be used to restore access to the context and data on the workbuf.
*
* If the workbuf needs to be relocated, call vb2api_relocate() instead
* of copying memory manually.
*
* @param workbuf Workbuf memory location to initialize
* @param size Size of workbuf being initialized
* @param ctxptr Pointer to a context pointer to be filled in
* @return VB2_SUCCESS, or non-zero error code.
*/
vb2_error_t vb2api_init(void *workbuf, uint32_t size,
struct vb2_context **ctxptr);
/**
* Reinitialize vboot data structures.
*
* After transitioning between different firmware applications, or any time the
* context pointer is lost, this function should be called to restore access to
* the workbuf. A pointer to the context object is written to ctxptr. Returns
* an error if the vboot work buffer is inconsistent.
*
* If the workbuf needs to be relocated, call vb2api_relocate() instead
* of copying memory manually.
*
* @param workbuf Workbuf memory location to check
* @param ctxptr Pointer to a context pointer to be filled in
* @return VB2_SUCCESS, or non-zero error code.
*/
vb2_error_t vb2api_reinit(void *workbuf, struct vb2_context **ctxptr);
/**
* Relocate vboot data structures.
*
* Move the vboot work buffer from one memory location to another, and expand
* or contract the workbuf to fit. The target memory location may be the same
* as the original (used for a "resize" operation), and it is safe to call this
* function with overlapping memory regions.
*
* A pointer to the context object is written to ctxptr. Returns an error if
* the vboot work buffer is inconsistent, or if the new memory space is too
* small to contain the work buffer.
*
* @param new_workbuf Target workbuf memory location
* @param cur_workbuf Original workbuf memory location to relocate
* @param size Target size of relocated workbuf
* @param ctxptr Pointer to a context pointer to be filled in
* @return VB2_SUCCESS, or non-zero error code.
*/
vb2_error_t vb2api_relocate(void *new_workbuf, const void *cur_workbuf,
uint32_t size, struct vb2_context **ctxptr);
/**
* Export "VBSD" vboot1 data structure.
*
* Copy relevant fields from vboot2 data structures to VbSharedDataHeader
* format. Takes a pointer to the memory space to be filled in. Expects
* the memory available to be of size VB2_VBSD_SIZE.
*
* @param ctx Context pointer
* @param dest Target memory to store VbSharedDataHeader
*/
void vb2api_export_vbsd(struct vb2_context *ctx, void *dest);
/**
* Check the validity of firmware secure storage context.
*
* Checks version and CRC.
*
* @param ctx Context pointer
* @return VB2_SUCCESS, or non-zero error code if error.
*/
vb2_error_t vb2api_secdata_firmware_check(struct vb2_context *ctx);
/**
* Create fresh data in firmware secure storage context.
*
* Use this only when initializing the secure storage context on a new machine
* the first time it boots. Do NOT simply use this if
* vb2api_secdata_firmware_check() (or any other API in this library) fails;
* that could allow the secure data to be rolled back to an insecure state.
*
* @param ctx Context pointer
* @return size of created firmware secure storage data in bytes
*/
uint32_t vb2api_secdata_firmware_create(struct vb2_context *ctx);
/**
* Check the validity of kernel secure storage context (ctx->secdata_kernel).
*
* Checks version, UID, and CRC.
*
* @param ctx Context pointer
* @param size (IN) Size of data to be checked
* (OUT) Expected size of data
* @return VB2_SUCCESS, or non-zero error code if error. If data is missing,
* it returns VB2_ERROR_SECDATA_KERNEL_INCOMPLETE and informs the caller
* of the expected size.
*/
vb2_error_t vb2api_secdata_kernel_check(struct vb2_context *ctx, uint8_t *size);
/**
* Create fresh data in kernel secure storage context.
*
* Use this only when initializing the secure storage context on a new machine
* the first time it boots. Do NOT simply use this if
* vb2api_secdata_kernel_check() (or any other API in this library) fails; that
* could allow the secure data to be rolled back to an insecure state.
*
* vb2api_secdata_kernel_create always creates secdata kernel using the latest
* revision.
*
* @param ctx Context pointer
* @return size of created kernel secure storage data in bytes
*/
uint32_t vb2api_secdata_kernel_create(struct vb2_context *ctx);
uint32_t vb2api_secdata_kernel_create_v0(struct vb2_context *ctx);
/**
* Check the validity of firmware management parameters (FWMP) space.
*
* Checks size, version, and CRC. If the struct size is larger than the size
* passed in, the size pointer is set to the expected full size of the struct,
* and VB2_ERROR_SECDATA_FWMP_INCOMPLETE is returned. The caller should
* re-read the returned number of bytes, and call this function again.
*
* @param ctx Context pointer
* @param size Amount of struct which has been read
* @return VB2_SUCCESS, or non-zero error code if error.
*/
vb2_error_t vb2api_secdata_fwmp_check(struct vb2_context *ctx, uint8_t *size);
/**
* Report firmware failure to vboot.
*
* If the failure occurred after choosing a firmware slot, and the other
* firmware slot is not known-bad, try the other firmware slot after reboot.
*
* If the failure occurred before choosing a firmware slot, or both slots have
* failed in successive boots, request recovery.
*
* This may be called before vb2api_phase1() to indicate errors in the boot
* process prior to the start of vboot. On return, the calling firmware should
* check for updates to secdata and/or nvdata, then reboot.
*
* @param reason Recovery reason
* @param subcode Recovery subcode
*/
void vb2api_fail(struct vb2_context *ctx, uint8_t reason, uint8_t subcode);
/**
* Firmware selection, phase 1.
*
* If the returned error is VB2_ERROR_API_PHASE1_RECOVERY, the calling firmware
* should jump directly to recovery-mode firmware without rebooting.
*
* For other errors, the calling firmware should check for updates to secdata
* and/or nvdata, then reboot.
*
* @param ctx Vboot context
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2api_fw_phase1(struct vb2_context *ctx);
/**
* Firmware selection, phase 2.
*
* On error, the calling firmware should check for updates to secdata and/or
* nvdata, then reboot.
*
* @param ctx Vboot context
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2api_fw_phase2(struct vb2_context *ctx);
/**
* Firmware selection, phase 3.
*
* On error, the calling firmware should check for updates to secdata and/or
* nvdata, then reboot.
*
* On success, the calling firmware should lock down secdata before continuing
* with the boot process.
*
* @param ctx Vboot context
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2api_fw_phase3(struct vb2_context *ctx);
/**
* Initialize hashing data for the specified tag.
*
* @param ctx Vboot context
* @param tag Tag to start hashing (enum vb2_hash_tag)
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2api_init_hash(struct vb2_context *ctx, uint32_t tag);
/**
* Extend the hash started by vb2api_init_hash() with additional data.
*
* (This is the same for both old and new style structs.)
*
* @param ctx Vboot context
* @param buf Data to hash
* @param size Size of data in bytes
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2api_extend_hash(struct vb2_context *ctx, const void *buf,
uint32_t size);
/**
* Check the hash value started by vb2api_init_hash().
*
* @param ctx Vboot context
* @return VB2_SUCCESS, or error code on error.
*/
int vb2api_check_hash(struct vb2_context *ctx);
/**
* Check the hash value started by vb2api_init_hash() while retrieving
* calculated digest.
*
* @param ctx Vboot context
* @param digest_out optional pointer to buffer to store digest
* @param digest_out_size optional size of buffer to store digest
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx,
void *digest_out,
uint32_t digest_out_size);
/**
* Get a PCR digest
*
* @param ctx Vboot context
* @param which_digest PCR index of the digest
* @param dest Destination where the digest is copied.
* Recommended size is VB2_PCR_DIGEST_RECOMMENDED_SIZE.
* @param dest_size IN: size of the buffer pointed by dest
* OUT: size of the copied digest
* @return VB2_SUCCESS, or error code on error
*/
vb2_error_t vb2api_get_pcr_digest(struct vb2_context *ctx,
enum vb2_pcr_digest which_digest,
uint8_t *dest, uint32_t *dest_size);
/**
* Prepare for kernel verification stage.
*
* Must be called before other vb2api kernel functions.
*
* @param ctx Vboot context
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2api_kernel_phase1(struct vb2_context *ctx);
/**
* Load the verified boot block (vblock) for a kernel.
*
* This function may be called multiple times, to load and verify the
* vblocks from multiple kernel partitions.
*
* @param ctx Vboot context
* @param stream Kernel stream
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2api_load_kernel_vblock(struct vb2_context *ctx);
/**
* Get the size and offset of the kernel data for the most recent vblock.
*
* Valid after a successful call to vb2api_load_kernel_vblock().
*
* @param ctx Vboot context
* @param offset_ptr Destination for offset in bytes of kernel data as
* reported by vblock.
* @param size_ptr Destination for size of kernel data in bytes.
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2api_get_kernel_size(struct vb2_context *ctx,
uint32_t *offset_ptr, uint32_t *size_ptr);
/**
* Verify kernel data using the previously loaded kernel vblock.
*
* Valid after a successful call to vb2api_load_kernel_vblock(). This allows
* the caller to load or map the kernel data, as appropriate, and pass the
* pointer to the kernel data into vboot.
*
* @param ctx Vboot context
* @param buf Pointer to kernel data
* @param size Size of kernel data in bytes
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2api_verify_kernel_data(struct vb2_context *ctx, const void *buf,
uint32_t size);
/**
* Clean up after kernel verification.
*
* Call this after successfully loading a vblock and verifying kernel data,
* or if you've run out of boot devices and/or kernel partitions.
*
* This cleans up intermediate data structures in the vboot context, and
* updates the version in the secure data if necessary.
*/
vb2_error_t vb2api_kernel_phase3(struct vb2_context *ctx);
/**
* Read the hardware ID from the GBB, and store it onto the given buffer.
*
* @param ctx Vboot context.
* @param hwid Buffer to store HWID, which will be null-terminated.
* @param size Maximum size of HWID including null terminator. HWID
* length may not exceed 256 (VB2_GBB_HWID_MAX_SIZE), so
* this value is suggested. If size is too small, then
* VB2_ERROR_INVALID_PARAMETER is returned. Actual size
* of the output HWID string is returned in this pointer,
* also including null terminator.
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2api_gbb_read_hwid(struct vb2_context *ctx, char *hwid,
uint32_t *size);
/**
* Retrieve current GBB flags.
*
* See enum vb2_gbb_flag in 2gbb_flags.h for a list of all GBB flags.
*
* @param ctx Vboot context.
*
* @return vb2_gbb_flags_t representing current GBB flags.
*/
vb2_gbb_flags_t vb2api_gbb_get_flags(struct vb2_context *ctx);
/**
* Get the size of the signed firmware body. This is only legal to call after
* vb2api_fw_phase3() has returned successfully, and will return 0 otherwise.
*
* @param ctx Vboot context
*
* @return The firmware body size in bytes (or 0 if called too early).
*/
uint32_t vb2api_get_firmware_size(struct vb2_context *ctx);
/**
* Check if this firmware was bundled with the well-known public developer key
* set (more specifically, checks the recovery key in recovery mode and the
* kernel subkey from the firmware preamble in other modes). This is a best
* effort check that could be misled by a specifically crafted key.
*
* May only be called after vb2api_kernel_phase1() has run.
*
* @param ctx Vboot context
*
* @return 1 for developer keys, 0 for any others.
*/
int vb2api_is_developer_signed(struct vb2_context *ctx);
/**
* Return the current kernel rollback version from secdata.
*
* @param ctx Vboot context
*
* @return The rollback version number.
*/
uint32_t vb2api_get_kernel_rollback_version(struct vb2_context *ctx);
/**
* If no display is available, set DISPLAY_REQUEST in nvdata.
*
* @param ctx Vboot2 context
* @return 1 if DISPLAY_REQUEST is set and a reboot is required, or 0 otherwise.
*/
int vb2api_need_reboot_for_display(struct vb2_context *ctx);
/**
* Get the current recovery reason.
*
* See enum vb2_nv_recovery in 2recovery_reasons.h.
*
* @param ctx Vboot context
* @return Current recovery reason.
*/
uint32_t vb2api_get_recovery_reason(struct vb2_context *ctx);
/**
* Get the current locale id from nvdata.
*
* @param ctx Vboot context
* @return Current locale id.
*/
uint32_t vb2api_get_locale_id(struct vb2_context *ctx);
/**
* Whether phone recovery functionality is enabled or not.
*
* @param ctx Vboot context
* @return 1 if enabled, 0 if disabled.
*/
int vb2api_phone_recovery_enabled(struct vb2_context *ctx);
/**
* Whether phone recovery instructions in recovery UI are enabled or not.
*
* @param ctx Vboot context
* @return 1 if enabled, 0 if disabled.
*/
int vb2api_phone_recovery_ui_enabled(struct vb2_context *ctx);
/**
* Whether diagnostic UI functionality is enabled or not.
*
* @param ctx Vboot context
* @return 1 if enabled, 0 if disabled.
*/
int vb2api_diagnostic_ui_enabled(struct vb2_context *ctx);
/* Default boot target in developer mode. */
enum vb2_dev_default_boot_target {
/* Default to boot from internal disk. */
VB2_DEV_DEFAULT_BOOT_TARGET_INTERNAL = 0,
/* Default to boot from external disk. */
VB2_DEV_DEFAULT_BOOT_TARGET_EXTERNAL = 1,
/* Default to boot legacy OS. */
VB2_DEV_DEFAULT_BOOT_TARGET_LEGACY = 2,
};
/**
* Get the default boot target in developer mode.
*
* @param ctx Vboot context
* @return The developer mode default boot target.
*/
enum vb2_dev_default_boot_target vb2api_get_dev_default_boot_target(
struct vb2_context *ctx);
/**
* Whether to use short delay instead of the normal delay in developer screens.
*
* @param ctx Vboot context
* @return 1 for short delay and 0 otherwise.
*/
int vb2api_use_short_dev_screen_delay(struct vb2_context *ctx);
/*****************************************************************************/
/* APIs provided by the caller to verified boot */
/**
* Read a verified boot resource.
*
* @param ctx Vboot context
* @param index Resource index to read
* @param offset Byte offset within resource to start at
* @param buf Destination for data
* @param size Amount of data to read
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2ex_read_resource(struct vb2_context *ctx,
enum vb2_resource_index index, uint32_t offset,
void *buf, uint32_t size);
/**
* Print debug output.
*
* This should work like printf(). If func!=NULL, it will be a string with
* the current function name; that can be used to generate prettier debug
* output. If func==NULL, don't print any extra header/trailer so that this
* can be used to composite a bigger output string from several calls - for
* example, when doing a hex dump.
*
* @param func Function name generating output, or NULL.
* @param fmt Printf format string
*/
__attribute__((format(printf, 2, 3)))
void vb2ex_printf(const char *func, const char *fmt, ...);
/**
* Initialize the hardware crypto engine to calculate a block-style digest.
*
* @param hash_alg Hash algorithm to use
* @param data_size Expected total size of data to hash
* @return VB2_SUCCESS, or non-zero error code (HWCRYPTO_UNSUPPORTED not fatal).
*/
vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
uint32_t data_size);
/**
* Extend the hash in the hardware crypto engine with another block of data.
*
* @param buf Next data block to hash
* @param size Length of data block in bytes
* @return VB2_SUCCESS, or non-zero error code.
*/
vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size);
/**
* Finalize the digest in the hardware crypto engine and extract the result.
*
* @param digest Destination buffer for resulting digest
* @param digest_size Length of digest buffer in bytes
* @return VB2_SUCCESS, or non-zero error code.
*/
vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
uint32_t digest_size);
/**
* Verify a RSA PKCS1.5 signature in hardware crypto engine
* against an expected hash digest.
*
* @param key Key to use in signature verification
* @param sig Signature to verify (destroyed in process)
* @param digest Digest of signed data
* @return VB2_SUCCESS, or non-zero error code (HWCRYPTO_UNSUPPORTED not fatal).
*/
vb2_error_t vb2ex_hwcrypto_rsa_verify_digest(const struct vb2_public_key *key,
const uint8_t *sig,
const uint8_t *digest);
/**
* Calculate modexp using hardware crypto engine.
*
* @param key Key to use in signing
* @param inout Input and output big-endian byte array
* @param workbuf32 Work buffer; caller must verify this is
* (3 * key->arrsize) elements long.
* @param exp RSA public exponent: either 65537 (F4) or 3
* @return VB2_SUCCESS or HWCRYPTO_UNSUPPORTED.
*/
vb2_error_t vb2ex_hwcrypto_modexp(const struct vb2_public_key *key,
uint8_t *inout,
uint32_t *workbuf32, int exp);
/*
* Abort vboot flow due to a failed assertion or broken assumption.
*
* Likely due to caller misusing vboot (e.g. calling API functions
* out-of-order, filling in vb2_context fields inappropriately).
* Implementation should reboot or halt the machine, or fall back to some
* alternative boot flow. Retrying vboot is unlikely to succeed.
*/
void vb2ex_abort(void);
/**
* Commit any pending data to disk.
*
* Commit nvdata and secdata spaces if modified. Normally this should be
* performed after vboot has completed executing and control has been passed
* back to the caller. However, in certain kernel verification cases (e.g.
* right before attempting to boot an OS; from a UI screen which requires
* user-initiated shutdown; just prior to triggering battery cut-off), the
* caller may not get a chance to commit this data.
*
* @param ctx Vboot context
* @returns VB2_SUCCESS, or non-zero error code.
*/
vb2_error_t vb2ex_commit_data(struct vb2_context *ctx);
/*****************************************************************************/
/* TPM functionality */
/**
* Initialize the TPM.
*
* @returns VB2_SUCCESS, or non-zero error code.
*/
vb2_error_t vb2ex_tpm_init(void);
/**
* Close and open the TPM.
*
* 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.
*
* @returns VB2_SUCCESS, or non-zero error code.
*/
vb2_error_t vb2ex_tpm_close(void);
vb2_error_t vb2ex_tpm_open(void);
/**
* Send request to TPM and receive response
*
* 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.
*
* @param request Pointer to request buffer
* @param request_length Number of bytes to send
* @param response Pointer to response buffer
* @param response_length Size of response buffer; on return,
* set to number of received bytes
* @return TPM_SUCCESS, or non-zero if error.
*/
uint32_t vb2ex_tpm_send_recv(const uint8_t *request, uint32_t request_length,
uint8_t *response, uint32_t *response_length);
#ifdef CHROMEOS_ENVIRONMENT
/**
* Obtain cryptographically secure random bytes.
*
* This function is used to generate random nonces for TPM auth sessions for
* example. As an implication, the generated random bytes should not be
* predictable for a TPM communication interception attack. This implies a
* local source of randomness should be used, i.e. this should not be wired to
* the TPM RNG directly. Otherwise, an attacker with communication interception
* abilities could launch replay attacks by reusing previous nonces.
*
* @returns VB2_SUCCESS, or non-zero error code.
*/
vb2_error_t vb2ex_tpm_get_random(uint8_t *buf, uint32_t length);
#endif /* CHROMEOS_ENVIRONMENT */
/* Modes for vb2ex_tpm_set_mode. */
enum vb2_tpm_mode {
/*
* TPM is enabled tentatively, and may be set to either
* ENABLED or DISABLED mode.
*/
VB2_TPM_MODE_ENABLED_TENTATIVE = 0,
/* TPM is enabled, and mode may not be changed. */
VB2_TPM_MODE_ENABLED = 1,
/* TPM is disabled, and mode may not be changed. */
VB2_TPM_MODE_DISABLED = 2,
};
/**
* Set the current TPM mode value, and validate that it was changed. If one
* of the following occurs, the function call fails:
* - TPM does not understand the instruction (old version)
* - TPM has already left the TpmModeEnabledTentative mode
* - TPM responds with a mode other than the requested mode
* - Some other communication error occurs
* Otherwise, the function call succeeds.
*
* @param mode_val Desired TPM mode to set. May be one of ENABLED
* or DISABLED from vb2_tpm_mode enum.
* @returns VB2_SUCCESS, or non-zero error code.
*/
vb2_error_t vb2ex_tpm_set_mode(enum vb2_tpm_mode mode_val);
/**
* Clear the TPM owner.
*
* @param ctx Vboot context
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2ex_tpm_clear_owner(struct vb2_context *ctx);
/*****************************************************************************/
/* Auxiliary firmware (auxfw) */
/**
* Sync all auxiliary firmware to the expected versions.
*
* This function will first check if an auxfw update is needed and
* what the "severity" of that update is (i.e., if any auxfw devices
* exist and the relative quickness of updating it. If the update is
* deemed slow, it may display a screen to notify the user. The
* platform is then instructed to perform the update. Finally, an EC
* reboot to its RO section is performed to ensure that auxfw devices
* are also reset and running the new firmware.
*
* @param ctx Vboot2 context
* @return VB2_SUCCESS, or non-zero error code.
*/
vb2_error_t vb2api_auxfw_sync(struct vb2_context *ctx);
/*
* severity levels for an auxiliary firmware update request
*/
enum vb2_auxfw_update_severity {
/* no update needed and no protection needed */
VB2_AUXFW_NO_DEVICE = 0,
/* no update needed */
VB2_AUXFW_NO_UPDATE = 1,
/* update needed, can be done quickly */
VB2_AUXFW_FAST_UPDATE = 2,
/* update needed, "this would take a while..." */
VB2_AUXFW_SLOW_UPDATE = 3,
};
/*
* Check if any auxiliary firmware needs updating.
*
* This is called after the EC has been updated and is intended to
* version-check additional firmware blobs such as TCPCs.
*
* @param severity return parameter for health of auxiliary firmware
* (see vb2_auxfw_update_severity above)
* @return VBERROR_... error, VB2_SUCCESS on success.
*/
vb2_error_t vb2ex_auxfw_check(enum vb2_auxfw_update_severity *severity);
/*
* Perform auxiliary firmware update(s).
*
* This is called after the EC has been updated and is intended to
* update additional firmware blobs such as TCPCs.
*
* @return VBERROR_... error, VB2_SUCCESS on success.
*/
vb2_error_t vb2ex_auxfw_update(void);
/*
* Notify client that vboot is done with auxfw.
*
* If auxfw sync was successful, this will be called at the end so that
* the client may perform actions that require the auxfw to be in its
* final state. This may include protecting the communcations tunnels that
* allow auxiliary firmware updates from the OS.
*
* @param ctx Vboot context
* @return VBERROR_... error, VB2_SUCCESS on success.
*/
vb2_error_t vb2ex_auxfw_finalize(struct vb2_context *ctx);
/*****************************************************************************/
/* Embedded controller (EC) */
/*
* Firmware selection type for EC software sync logic. Note that we store
* these in a uint32_t because enum maps to int, which isn't fixed-size.
*/
enum vb2_firmware_selection {
/* Read only firmware for normal or developer path. */
VB_SELECT_FIRMWARE_READONLY = 3,
/* Rewritable EC firmware currently set active */
VB_SELECT_FIRMWARE_EC_ACTIVE = 4,
/* Rewritable EC firmware currently not set active thus updatable */
VB_SELECT_FIRMWARE_EC_UPDATE = 5,
/* Keep this at the end */
VB_SELECT_FIRMWARE_COUNT,
};
/**
* Sync the Embedded Controller device to the expected version.
*
* This function will check if EC software sync is allowed, and if it
* is, it will compare the expected image hash to the actual image
* hash. If they are the same, the EC will simply jump to its RW
* firwmare. Otherwise, the specified flash image will be updated to
* the new version, and the EC will reboot into its new firmware.
*
* @param ctx Vboot context
* @return VB2_SUCCESS, or non-zero if error.
*/
vb2_error_t vb2api_ec_sync(struct vb2_context *ctx);
/**
* 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 vb2ex_ec_trusted(void);
/**
* 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. */
vb2_error_t vb2ex_ec_running_rw(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.
*/
vb2_error_t vb2ex_ec_jump_to_rw(void);
/**
* Tell the EC to refuse another jump until it reboots. Subsequent calls to
* vb2ex_ec_jump_to_rw() in this boot will fail.
*/
vb2_error_t vb2ex_ec_disable_jump(void);
/**
* Read the SHA-256 hash of the selected EC image.
*
* @param select Image to get hash of. RO or RW.
* @param hash Pointer to the hash.
* @param hash_size Pointer to the hash size.
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2ex_ec_hash_image(enum vb2_firmware_selection select,
const uint8_t **hash, int *hash_size);
/**
* Read the SHA-256 hash of the expected contents of the EC image associated
* with the main firmware specified by the "select" argument.
*
* @param select Image to get expected hash for (RO or RW).
* @param hash Pointer to the hash.
* @param hash_size Pointer to the hash size (in bytes).
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2ex_ec_get_expected_image_hash(enum vb2_firmware_selection select,
const uint8_t **hash,
int *hash_size);
/**
* Update the selected EC image to the expected version.
*
* @param select Image to get expected hash for (RO or RW).
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2ex_ec_update_image(enum vb2_firmware_selection select);
/**
* Lock the EC code to prevent updates until the EC is rebooted.
* Subsequent calls to vb2ex_ec_update_image() with the same region this
* boot will fail.
*
* @param select Image to get expected hash for (RO or RW).
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2ex_ec_protect(enum vb2_firmware_selection select);
/**
* 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 ctx Pointer to vboot context.
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2ex_ec_vboot_done(struct vb2_context *ctx);
/**
* Request EC to stop discharging and cut-off battery.
*/
vb2_error_t vb2ex_ec_battery_cutoff(void);
/*****************************************************************************/
/* Functions for UI display. */
/* Helpers for bitmask operations */
#define VB2_SET_BIT(mask, index) ((mask) |= ((uint32_t)1 << (index)))
#define VB2_CLR_BIT(mask, index) ((mask) &= ~((uint32_t)1 << (index)))
#define VB2_GET_BIT(mask, index) ((mask) & ((uint32_t)1 << (index)))
/* Screens. */
enum vb2_screen {
/* Blank screen */
VB2_SCREEN_BLANK = 0x0,
/* Wait screen for EC sync and AUXFW sync */
VB2_SCREEN_FIRMWARE_SYNC = 0x100,
/* Broken screen */
VB2_SCREEN_RECOVERY_BROKEN = 0x110,
/* Advanced options */
VB2_SCREEN_ADVANCED_OPTIONS = 0x120,
/* Language selection screen */
VB2_SCREEN_LANGUAGE_SELECT = 0x130,
/* Debug info */
VB2_SCREEN_DEBUG_INFO = 0x140,
/* Firmware log */
VB2_SCREEN_FIRMWARE_LOG = 0x150,
/* First recovery screen to select recovering from disk or phone */
VB2_SCREEN_RECOVERY_SELECT = 0x200,
/* Invalid recovery media inserted */
VB2_SCREEN_RECOVERY_INVALID = 0x201,
/* Confirm transition to developer mode */
VB2_SCREEN_RECOVERY_TO_DEV = 0x202,
/* Recovery using phone */
VB2_SCREEN_RECOVERY_PHONE_STEP1 = 0x210,
VB2_SCREEN_RECOVERY_PHONE_STEP2 = 0x211,
/* Recovery using disk */
VB2_SCREEN_RECOVERY_DISK_STEP1 = 0x220,
VB2_SCREEN_RECOVERY_DISK_STEP2 = 0x221,
VB2_SCREEN_RECOVERY_DISK_STEP3 = 0x222,
/* Developer mode screen */
VB2_SCREEN_DEVELOPER_MODE = 0x300,
/* Confirm transition to normal mode */
VB2_SCREEN_DEVELOPER_TO_NORM = 0x310,
/* Developer boot from external disk */
VB2_SCREEN_DEVELOPER_BOOT_EXTERNAL = 0x320,
/* Invalid external disk inserted */
VB2_SCREEN_DEVELOPER_INVALID_DISK = 0x330,
/* Select alternate bootloader ("legacy boot") */
VB2_SCREEN_DEVELOPER_SELECT_BOOTLOADER = 0x340,
/* Diagnostic tools */
VB2_SCREEN_DIAGNOSTICS = 0x400,
/* Storage diagnostic screen */
VB2_SCREEN_DIAGNOSTICS_STORAGE = 0x410,
/* Memory diagnostic screens */
VB2_SCREEN_DIAGNOSTICS_MEMORY_QUICK = 0x420,
VB2_SCREEN_DIAGNOSTICS_MEMORY_FULL = 0x421,
};
enum vb2_ui_error {
/* No error */
VB2_UI_ERROR_NONE = 0,
/* Dev mode already enabled */
VB2_UI_ERROR_DEV_MODE_ALREADY_ENABLED,
/* To-norm not allowed */
VB2_UI_ERROR_TO_NORM_NOT_ALLOWED,
/* Debug info screen initialization failed */
VB2_UI_ERROR_DEBUG_LOG,
/* External boot not enabled */
VB2_UI_ERROR_EXTERNAL_BOOT_NOT_ENABLED,
/* Firmware log screen initialization failed */
VB2_UI_ERROR_FIRMWARE_LOG,
/* Untrusted confirmation */
VB2_UI_ERROR_UNTRUSTED_CONFIRMATION,
/* Alternate bootloader is disabled */
VB2_UI_ERROR_ALTERNATE_BOOT_DISABLED,
/* No bootloader was found */
VB2_UI_ERROR_NO_BOOTLOADER,
/* Alternate bootloader failed */
VB2_UI_ERROR_ALTERNATE_BOOT_FAILED,
/* Diagnostics internal failure */
VB2_UI_ERROR_DIAGNOSTICS,
};
/**
* Display UI screen.
*
* @param screen Screen to display.
* @param locale_id Id of current locale.
* @param selected_item Index of the selected menu item. If the screen
* doesn't have a menu, this value will be ignored.
* @param disabled_item_mask Mask for disabled menu items. Bit (1 << idx)
* indicates whether item 'idx' is disabled.
* A disabled menu item is visible and selectable,
* with a different button style.
* @param hidden_item_mask Mask for hidden menu items. Bit (1 << idx)
* indicates whether item 'idx' is hidden.
* A hidden menu item is neither visible nor
* selectable.
* @param timer_disabled Whether timer is disabled or not. Some screen
* descriptions will depend on this value.
* @param current_page Current page number for a log screen. If the
* screen doesn't show logs, this value will be
* ignored.
* @param error_code Error code if an error occurred.
* @return VB2_SUCCESS, or error code on error.
*/
vb2_error_t vb2ex_display_ui(enum vb2_screen screen,
uint32_t locale_id,
uint32_t selected_item,
uint32_t disabled_item_mask,
uint32_t hidden_item_mask,
int timer_disabled,
uint32_t current_page,
enum vb2_ui_error error_code);
/**
* Check that physical presence button is currently pressed by the user.
*
* @returns 1 for pressed, 0 for not.
*/
int vb2ex_physical_presence_pressed(void);
/**
* Get the number of supported locales.
*
* @returns Number of locales. 0 if none or on error.
*/
uint32_t vb2ex_get_locale_count(void);
/**
* Return the number of available alternate bootloaders.
*
* @returns Number of alternate bootloaders. 0 if none or on error.
*/
uint32_t vb2ex_get_bootloader_count(void);
/**
* Delay for at least the specified number of milliseconds.
*
* @param msec Duration in milliseconds.
*/
void vb2ex_msleep(uint32_t msec);
/**
* Play a beep tone of the specified frequency in Hz for the duration msec.
*
* This is effectively a sleep call that makes noise. The implementation may
* beep at a fixed frequency if frequency support is not available. Regardless
* of whether any errors occur, the callback is expected to delay for the
* specified duration before returning.
*
* @param msec Duration of beep in milliseconds.
* @param frequency Sound frequency in Hz.
*/
void vb2ex_beep(uint32_t msec, uint32_t frequency);
/**
* Get the full debug info string.
*
* Return a pointer to the full debug info string which is guaranteed to be
* null-terminated. The function implementation should manage string memory
* internally. Subsequent calls may update the string and return the same
* pointer, or return a new pointer if necessary.
*
* @param ctx Vboot context
* @return The pointer to the full debug info string. NULL on error.
*/
const char *vb2ex_get_debug_info(struct vb2_context *ctx);
/**
* Get the vboot debug info.
*
* Return a pointer to the vboot debug info string which is guaranteed to be
* null-terminated. The caller owns the string and should call free() when
* finished with it.
*
* @param ctx Vboot context
* @return The pointer to the vboot debug info string. NULL on error.
*/
char *vb2api_get_debug_info(struct vb2_context *ctx);
/**
* Get the full firmware log string.
*
* Return a pointer to the full firmware log string which is guaranteed to be
* null-terminated. The function implementation should snapshot the full
* firmware log when it is called. If `reset` is not zero, it will reset the
* firmware log snapshot.
*
* @param reset Discard the current firmware log snapshot and
* reacquire a new one.
* @return The pointer to the full firmware log string. NULL on error.
*/
const char *vb2ex_get_firmware_log(int reset);
/**
* Specify the string to be used for an upcoming log screen display.
*
* Before a vb2ex_display_ui() call is made for a screen which displays logs,
* the log string should be provided via this function. The total number of
* pages in the log string is returned. If the log string ever changes, this
* function should be called again before the next vb2ex_display_ui() call.
*
* @param str The log string to display.
* @return The number of pages after pagination. 0 if none or error.
*/
uint32_t vb2ex_prepare_log_screen(const char *str);
/**
* Get the full storage diagnostic log.
*
* Return a pointer of full log string which is guaranteed to be
* null-terminated. The function implementation should manage string memory
* internally. Subsequent calls may update the string and/or may return a new
* pointer.
*
* @return The pointer to the full debug info string. NULL on error.
*/
const char *vb2ex_get_diagnostic_storage(void);
/**
* Get the memory diagnostic status. When it is called, it will take over the
* control for a short period of time running memory test, and then return the
* result of current status. If `reset` is not zero, it will reset the memory
* test state.
*
* @param reset Discard the current memory test result and re-initialize
* a new test.
* @param out For returning a read-only pointer of full log string which is
* guaranteed to be null-terminated. The function will manage
* memory internally, so the returned pointer will only be valid
* until next call.
* @return The status of memory test. VB2_SUCCESS means the test is finished,
* regardless of passing or failing. VB2_ERROR_EX_DIAG_TEST_RUNNING means
* the test is still running but the output buffer was unchanged.
* VB2_ERROR_EX_DIAG_TEST_UPDATED means the test is still running and the output
* buffer was updated. Other non-zero codes for internal errors.
*/
vb2_error_t vb2ex_diag_memory_quick_test(int reset, const char **out);
vb2_error_t vb2ex_diag_memory_full_test(int reset, const char **out);
/*****************************************************************************/
/* Timer. */
/**
* Read a millisecond timer.
*
* This should have a sufficient number of bits to avoid wraparound for at
* least 10 minutes.
*
* @return Current timer value in milliseconds.
*/
uint32_t vb2ex_mtime(void);
#endif /* VBOOT_REFERENCE_2API_H_ */