13333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 23333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Use of this source code is governed by a BSD-style license that can be 33333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * found in the LICENSE file. 43333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 53333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 63333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler/* APIs between calling firmware and vboot_reference 73333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * 83333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * General notes: 93333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * 103333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * TODO: split this file into a vboot_entry_points.h file which contains the 113333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * entry points for the firmware to call vboot_reference, and a 123333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * vboot_firmware_exports.h which contains the APIs to be implemented by the 133333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * calling firmware and exported to vboot_reference. 143333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * 153333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Notes: 163333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * * Assumes this code is never called in the S3 resume path. TPM resume 173333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * must be done elsewhere, and VB2_NV_DEBUG_RESET_MODE is ignored. 183333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 193333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 203333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler#ifndef VBOOT_2_API_H_ 213333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler#define VBOOT_2_API_H_ 223333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler#include <stdint.h> 233333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 2473e5eb38821d693244f841ce4f0a14546e5b6361Bill Richardson#include "2common.h" 25f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner#include "2crypto.h" 26435c74f1ec8a522e41c034cd5fd7a424356dbfb7Randall Spangler#include "2fw_hash_tags.h" 277c1eee09eff54c6e60a3b261e6df790c11331695Randall Spangler#include "2guid.h" 283333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler#include "2recovery_reasons.h" 293333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler#include "2return_codes.h" 303333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 313333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler/* Size of non-volatile data used by vboot */ 323333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler#define VB2_NVDATA_SIZE 16 333333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 343333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler/* Size of secure data used by vboot */ 353333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler#define VB2_SECDATA_SIZE 10 363333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 373333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler/* 383333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Recommended size of work buffer. 393333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * 403333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * TODO: The recommended size really depends on which key algorithms are 413333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * used. Should have a better / more accurate recommendation than this. 423333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 433333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler#define VB2_WORKBUF_RECOMMENDED_SIZE (12 * 1024) 443333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 4562d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri/* Recommended buffer size for vb2api_get_pcr_digest */ 4662d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri#define VB2_PCR_DIGEST_RECOMMENDED_SIZE 32 4762d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri 483333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler/* Flags for vb2_context. 493333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * 503333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Unless otherwise noted, flags are set by verified boot and may be read (but 513333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * not set or cleared) by the caller. 523333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 533333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spanglerenum vb2_context_flags { 543333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 553333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /* 563333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Verified boot has changed nvdata[]. Caller must save nvdata[] back 573333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * to its underlying storage, then may clear this flag. 583333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 593333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler VB2_CONTEXT_NVDATA_CHANGED = (1 << 0), 603333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 613333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /* 623333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Verified boot has changed secdata[]. Caller must save secdata[] 633333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * back to its underlying storage, then may clear this flag. 643333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 653333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler VB2_CONTEXT_SECDATA_CHANGED = (1 << 1), 663333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 673333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /* Recovery mode is requested this boot */ 683333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler VB2_CONTEXT_RECOVERY_MODE = (1 << 2), 693333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 703333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /* Developer mode is requested this boot */ 713333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler VB2_CONTEXT_DEVELOPER_MODE = (1 << 3), 723333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 733333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /* 743333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Force recovery mode due to physical user request. Caller may set 753333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * this flag when initializing the context. 763333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 773333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler VB2_CONTEXT_FORCE_RECOVERY_MODE = (1 << 4), 783333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 793333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /* 803333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Force developer mode enabled. Caller may set this flag when 813333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * initializing the context. 823333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 833333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler VB2_CONTEXT_FORCE_DEVELOPER_MODE = (1 << 5), 843333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 853333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /* Using firmware slot B. If this flag is clear, using slot A. */ 863333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler VB2_CONTEXT_FW_SLOT_B = (1 << 6), 873333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 883333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /* RAM should be cleared by caller this boot */ 893333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler VB2_CONTEXT_CLEAR_RAM = (1 << 7), 903333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler}; 913333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 923333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler/* 933333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Context for firmware verification. Pass this to all vboot APIs. 943333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * 953333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Caller may relocate this between calls to vboot APIs. 963333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 973333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spanglerstruct vb2_context { 983333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /********************************************************************** 993333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Fields which must be initialized by caller. 1003333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 1013333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 1023333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /* 1033333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Flags; see vb2_context_flags. Some flags may only be set by caller 1043333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * prior to calling vboot functions. 1053333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 1063333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler uint32_t flags; 1073333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 1083333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /* 1093333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Work buffer, and length in bytes. Caller may relocate this between 1103333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * calls to vboot APIs; it contains no internal pointers. Caller must 1113333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * not examine the contents of this work buffer directly. 1123333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 1133333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler uint8_t *workbuf; 1143333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler uint32_t workbuf_size; 1153333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 1163333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /* 1173333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Non-volatile data. Caller must fill this from some non-volatile 1183333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * location. If the VB2_CONTEXT_NVDATA_CHANGED flag is set when a 1193333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * vb2api function returns, caller must save the data back to the 1203333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * non-volatile location and then clear the flag. 1213333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 1223333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler uint8_t nvdata[VB2_NVDATA_SIZE]; 1233333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 1243333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /* 1253333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Secure data. Caller must fill this from some secure non-volatile 1263333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * location. If the VB2_CONTEXT_SECDATA_CHANGED flag is set when a 1273333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * function returns, caller must save the data back to the secure 1283333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * non-volatile location and then clear the flag. 1293333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 1303333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler uint8_t secdata[VB2_SECDATA_SIZE]; 1313333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 1323333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /* 1333333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Context pointer for use by caller. Verified boot never looks at 1343333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * this. Put context here if you need it for APIs that verified boot 1353333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * may call (vb2ex_...() functions). 1363333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 1373333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler void *non_vboot_context; 1383333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 1393333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /********************************************************************** 1403333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Fields caller may examine after calling vb2api_fw_phase1(). Caller 1413333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * must set these fields to 0 before calling any vboot functions. 1423333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 1433333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 1443333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler /* 1453333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * Amount of work buffer used so far. Verified boot sub-calls use 1463333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * this to know where the unused work area starts. Caller may use 1473333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * this between calls to vboot APIs to know how much data must be 1483333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler * copied when relocating the work buffer. 1493333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler */ 1503333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler uint32_t workbuf_used; 1513333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler}; 1523333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler 153da2b49cf08a27551fd910626f669910a636378d4Randall Spanglerenum vb2_resource_index { 154da2b49cf08a27551fd910626f669910a636378d4Randall Spangler 155da2b49cf08a27551fd910626f669910a636378d4Randall Spangler /* Google binary block */ 156da2b49cf08a27551fd910626f669910a636378d4Randall Spangler VB2_RES_GBB, 157da2b49cf08a27551fd910626f669910a636378d4Randall Spangler 158da2b49cf08a27551fd910626f669910a636378d4Randall Spangler /* 159da2b49cf08a27551fd910626f669910a636378d4Randall Spangler * Verified boot block (keyblock+preamble). Use VB2_CONTEXT_FW_SLOT_B 160da2b49cf08a27551fd910626f669910a636378d4Randall Spangler * to determine whether this refers to slot A or slot B; vboot will 161da2b49cf08a27551fd910626f669910a636378d4Randall Spangler * set that flag to the proper state before reading the vblock. 162da2b49cf08a27551fd910626f669910a636378d4Randall Spangler */ 163da2b49cf08a27551fd910626f669910a636378d4Randall Spangler VB2_RES_FW_VBLOCK, 164da2b49cf08a27551fd910626f669910a636378d4Randall Spangler}; 165da2b49cf08a27551fd910626f669910a636378d4Randall Spangler 16662d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri/* Digest ID for vbapi_get_pcr_digest() */ 16762d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojirienum vb2_pcr_digest { 16862d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri /* Digest based on current developer and recovery mode flags */ 16962d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri BOOT_MODE_PCR, 17062d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri 17162d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri /* SHA-256 hash digest of HWID, from GBB */ 17262d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri HWID_DIGEST_PCR, 17362d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri}; 17462d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri 175a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler/****************************************************************************** 176a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * APIs provided by verified boot. 177a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 178a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * At a high level, call functions in the order described below. After each 179a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * call, examine vb2_context.flags to determine whether nvdata or secdata 180a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * needs to be written. 181a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 182a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * If you need to cause the boot process to fail at any point, call 183a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * vb2api_fail(). Then check vb2_context.flags to see what data needs to be 184a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * written. Then reboot. 185a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 186a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Load nvdata from wherever you keep it. 187a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 188a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Load secdata from wherever you keep it. 189a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 190a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * If it wasn't there at all (for example, this is the first boot 191a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * of a new system in the factory), call vb2api_secdata_create() 192a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * to initialize the data. 193a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 194a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * If access to your storage is unreliable (reads/writes may 195a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * contain corrupt data), you may call vb2api_secdata_check() to 196a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * determine if the data was valid, and retry reading if it 197a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * wasn't. (In that case, you should also read back and check the 198a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * data after any time you write it, to make sure it was written 199a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * correctly.) 200a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 201a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Call vb2api_fw_phase1(). At present, this nominally decides whether 202a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * recovery mode is needed this boot. 203a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 204a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Call vb2api_fw_phase2(). At present, this nominally decides which 205a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * firmware slot will be attempted (A or B). 206a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 207a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Call vb2api_fw_phase3(). At present, this nominally verifies the 208a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * firmware keyblock and preamble. 209a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 210a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Lock down wherever you keep secdata. It should no longer be writable 211a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * this boot. 212a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 213a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Verify the hash of each section of code/data you need to boot the RW 214a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * firmware. For each section: 215a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 216a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Call vb2_init_hash() to see if the hash exists. 217a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 218a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Load the data for the section. Call vb2_extend_hash() on the 219a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * data as you load it. You can load it all at once and make one 220a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * call, or load and hash-extend a block at a time. 221a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 222a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Call vb2_check_hash() to see if the hash is valid. 223a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 224a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * If it is valid, you may use the data and/or execute 225a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * code from that section. 226a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 227a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * If the hash was invalid, you must reboot. 228a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 229a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * At this point, firmware verification is done, and vb2_context contains the 230a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * kernel key needed to verify the kernel. That context should be preserved 231a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * and passed on to kernel selection. For now, that requires translating it 232a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * into the old VbSharedData format (via a func which does not yet exist...) 233a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler */ 234a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler 235a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler/** 236a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Sanity-check the contents of the secure storage context. 237a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 238a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Use this if reading from secure storage may be flaky, and you want to retry 239a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * reading it several times. 240a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 241a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * This may be called before vb2api_phase1(). 242a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 243a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @param ctx Context pointer 244a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @return VB2_SUCCESS, or non-zero error code if error. 245a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler */ 246a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spanglerint vb2api_secdata_check(const struct vb2_context *ctx); 247a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler 248a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler/** 249a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Create fresh data in the secure storage context. 250a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 251a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Use this only when initializing the secure storage context on a new machine 252a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * the first time it boots. Do NOT simply use this if vb2api_secdata_check() 253a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * (or any other API in this library) fails; that could allow the secure data 254a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * to be rolled back to an insecure state. 255a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 256a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * This may be called before vb2api_phase1(). 257a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 258a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @param ctx Context pointer 259a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @return VB2_SUCCESS, or non-zero error code if error. 260a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler */ 261a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spanglerint vb2api_secdata_create(struct vb2_context *ctx); 262a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler 263a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler/** 264a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Report firmware failure to vboot. 265a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 266a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * This may be called before vb2api_phase1() to indicate errors in the boot 267a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * process prior to the start of vboot. 268a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 269a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * If this is called after vb2api_phase1(), on return, the calling firmware 270a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * should check for updates to secdata and/or nvdata, then reboot. 271a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 272a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @param reason Recovery reason 273a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @param subcode Recovery subcode 274a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler */ 275a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spanglervoid vb2api_fail(struct vb2_context *ctx, uint8_t reason, uint8_t subcode); 276a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler 277a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler/** 278a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Firmware selection, phase 1. 279a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 280a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * On error, the calling firmware should jump directly to recovery-mode 281a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * firmware without rebooting. 282a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 283a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @param ctx Vboot context 284a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @return VB2_SUCCESS, or error code on error. 285a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler */ 286a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spanglerint vb2api_fw_phase1(struct vb2_context *ctx); 287a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler 288a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler/** 289a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Firmware selection, phase 2. 290a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 291a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * On error, the calling firmware should check for updates to secdata and/or 292a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * nvdata, then reboot. 293a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 294a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @param ctx Vboot context 295a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @return VB2_SUCCESS, or error code on error. 296a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler */ 297a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spanglerint vb2api_fw_phase2(struct vb2_context *ctx); 298a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler 299a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler/** 300a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Firmware selection, phase 3. 301a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 302a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * On error, the calling firmware should check for updates to secdata and/or 303a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * nvdata, then reboot. 304a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 305a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * On success, the calling firmware should lock down secdata before continuing 306a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * with the boot process. 307a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 308a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @param ctx Vboot context 309a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @return VB2_SUCCESS, or error code on error. 310a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler */ 311a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spanglerint vb2api_fw_phase3(struct vb2_context *ctx); 312a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler 313a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler/** 314a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Initialize hashing data for the specified tag. 315a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 316a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @param ctx Vboot context 317435c74f1ec8a522e41c034cd5fd7a424356dbfb7Randall Spangler * @param tag Tag to start hashing (enum vb2_hash_tag) 318a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @param size If non-null, expected size of data for tag will be 319a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * stored here on output. 320a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @return VB2_SUCCESS, or error code on error. 321a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler */ 322a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spanglerint vb2api_init_hash(struct vb2_context *ctx, uint32_t tag, uint32_t *size); 323a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler 324a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler/** 325efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler * Same, but for new-style structs. 326efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler */ 327efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spanglerint vb2api_init_hash2(struct vb2_context *ctx, 328efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler const struct vb2_guid *guid, 329efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler uint32_t *size); 330efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler 331efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler/** 332a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Extend the hash started by vb2api_init_hash() with additional data. 333a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 334efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler * (This is the same for both old and new style structs.) 335efa37b87f2b4cd4b4f515e96201502ae0408cec7Randall Spangler * 336a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @param ctx Vboot context 337a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @param buf Data to hash 338a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @param size Size of data in bytes 339a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @return VB2_SUCCESS, or error code on error. 340a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler */ 341a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spanglerint vb2api_extend_hash(struct vb2_context *ctx, 342a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler const void *buf, 343a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler uint32_t size); 344a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler 345a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler/** 346a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * Check the hash value started by vb2api_init_hash(). 347a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * 348a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @param ctx Vboot context 349a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler * @return VB2_SUCCESS, or error code on error. 350a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler */ 351a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spanglerint vb2api_check_hash(struct vb2_context *ctx); 352a7ab8b50b8923afcfd7a9e6181892c4c8a2de250Randall Spangler 35362d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri/** 35462d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri * Get a PCR digest 35562d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri * 35662d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri * @param ctx Vboot context 35762d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri * @param which_digest PCR index of the digest 35862d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri * @param dest Destination where the digest is copied. 35962d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri * Recommended size is VB2_PCR_DIGEST_RECOMMENDED_SIZE. 36062d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri * @param dest_size IN: size of the buffer pointed by dest 36162d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri * OUT: size of the copied digest 36262d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri * @return VB2_SUCCESS, or error code on error 36362d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri */ 36462d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiriint vb2api_get_pcr_digest(struct vb2_context *ctx, 36562d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri enum vb2_pcr_digest which_digest, 36662d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri uint8_t *dest, 36762d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri uint32_t *dest_size); 36862d482ecddf5735076a085859cf40fcfa24671eeDaisuke Nojiri 369da2b49cf08a27551fd910626f669910a636378d4Randall Spangler/*****************************************************************************/ 370da2b49cf08a27551fd910626f669910a636378d4Randall Spangler/* APIs provided by the caller to verified boot */ 371da2b49cf08a27551fd910626f669910a636378d4Randall Spangler 372da2b49cf08a27551fd910626f669910a636378d4Randall Spangler/** 373da2b49cf08a27551fd910626f669910a636378d4Randall Spangler * Clear the TPM owner. 374da2b49cf08a27551fd910626f669910a636378d4Randall Spangler * 375da2b49cf08a27551fd910626f669910a636378d4Randall Spangler * @param ctx Vboot context 376da2b49cf08a27551fd910626f669910a636378d4Randall Spangler * @return VB2_SUCCESS, or error code on error. 377da2b49cf08a27551fd910626f669910a636378d4Randall Spangler */ 378da2b49cf08a27551fd910626f669910a636378d4Randall Spanglerint vb2ex_tpm_clear_owner(struct vb2_context *ctx); 379da2b49cf08a27551fd910626f669910a636378d4Randall Spangler 380da2b49cf08a27551fd910626f669910a636378d4Randall Spangler/** 381da2b49cf08a27551fd910626f669910a636378d4Randall Spangler * Read a verified boot resource. 382da2b49cf08a27551fd910626f669910a636378d4Randall Spangler * 383da2b49cf08a27551fd910626f669910a636378d4Randall Spangler * @param ctx Vboot context 384da2b49cf08a27551fd910626f669910a636378d4Randall Spangler * @param index Resource index to read 385da2b49cf08a27551fd910626f669910a636378d4Randall Spangler * @param offset Byte offset within resource to start at 386da2b49cf08a27551fd910626f669910a636378d4Randall Spangler * @param buf Destination for data 387da2b49cf08a27551fd910626f669910a636378d4Randall Spangler * @param size Amount of data to read 388da2b49cf08a27551fd910626f669910a636378d4Randall Spangler * @return VB2_SUCCESS, or error code on error. 389da2b49cf08a27551fd910626f669910a636378d4Randall Spangler */ 390da2b49cf08a27551fd910626f669910a636378d4Randall Spanglerint vb2ex_read_resource(struct vb2_context *ctx, 391da2b49cf08a27551fd910626f669910a636378d4Randall Spangler enum vb2_resource_index index, 392da2b49cf08a27551fd910626f669910a636378d4Randall Spangler uint32_t offset, 393da2b49cf08a27551fd910626f669910a636378d4Randall Spangler void *buf, 394da2b49cf08a27551fd910626f669910a636378d4Randall Spangler uint32_t size); 395da2b49cf08a27551fd910626f669910a636378d4Randall Spangler 396dd5883dee60a06995bb167badc2352bf42a8aee5Daisuke Nojirivoid vb2ex_printf(const char *func, const char *fmt, ...); 397f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner 398f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner/** 399f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner * Initialize the hardware crypto engine to calculate a block-style digest. 400f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner * 401f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner * @param hash_alg Hash algorithm to use 402f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner * @param data_size Expected total size of data to hash 403f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner * @return VB2_SUCCESS, or non-zero error code (HWCRYPTO_UNSUPPORTED not fatal). 404f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner */ 405f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Wernerint vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg, 406f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner uint32_t data_size); 407f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner 408f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner/** 409f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner * Extend the hash in the hardware crypto engine with another block of data. 410f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner * 411f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner * @param buf Next data block to hash 412f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner * @param size Length of data block in bytes 413f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner * @return VB2_SUCCESS, or non-zero error code. 414f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner */ 415f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Wernerint vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size); 416f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner 417f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner/** 418f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner * Finalize the digest in the hardware crypto engine and extract the result. 419f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner * 420f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner * @param digest Destination buffer for resulting digest 421f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner * @param digest_size Length of digest buffer in bytes 422f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner * @return VB2_SUCCESS, or non-zero error code. 423f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner */ 424f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Wernerint vb2ex_hwcrypto_digest_finalize(uint8_t *digest, uint32_t digest_size); 425f10e9099286202f83ce4c1dc5ef1e85fcb5ccde7Julius Werner 4263333e578497aafc4eb8c6e1e359f6e2b1dee633aRandall Spangler#endif /* VBOOT_2_API_H_ */ 427