rt-thread/bsp/imx6ul/platform/include/hab_defines.h

2223 lines
82 KiB
C

/*
* Copyright (c) 2008-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*!
* @file hab_defines.h
* @brief defines for data structures and macros used for enabling secure boot
*
* @ingroup diag_init
*/
#ifndef HAB_DEFINES_H
#define HAB_DEFINES_H
/*===========================================================================
INCLUDE FILES
=============================================================================*/
#include <stdint.h> /* for integer types */
#include <stdbool.h> /* for bool type */
#include <stddef.h> /* for NULL and offsetof() */
/*===========================================================================
CONSTANTS
=============================================================================*/
/** @addtogroup struct
* @{
*/
#define HDR_BYTES 4 /* cannot use sizeof(hab_hdr_t) in preprocessor */
/** @name External data structure tags
* @anchor dat_tag
*
* Tag values 0x00 .. 0xef are reserved for HAB. Values 0xf0 .. 0xff
* are available for custom use.
*/
/*@{*/
#define HAB_TAG_IVT 0xd1 /**< Image Vector Table */
#define HAB_TAG_DCD 0xd2 /**< Device Configuration Data */
#define HAB_TAG_CSF 0xd4 /**< Command Sequence File */
#define HAB_TAG_CRT 0xd7 /**< Certificate */
#define HAB_TAG_SIG 0xd8 /**< Signature */
#define HAB_TAG_EVT 0xdb /**< Event */
#define HAB_TAG_RVT 0xdd /**< ROM Vector Table */
#define HAB_TAG_WRP 0x81 /**< Wrapped Key */
#define HAB_TAG_MAC 0xac /**< Message Authentication Code */
/* Values 00 ... 7e reserved for internal use. Values b0 ... cf reserved for
* CSF commands. Values e0 ... ef reserved for key types.
*
* Available values: 82, 84, 87, 88, 8b, 8d, 8e, 90, 93, 95, 96, 99, 9a,
* 9c, 9f, a0, a3, a5, a6, a9, aa, af
*
* Custom values: f0, f3, f5, f6, f9, fa, fc, ff
*/
/*@}*/
/** @name HAB version */
/*@{*/
#define HAB_MAJOR_VERSION 4 /**< Major version of this HAB release */
#define HAB_MINOR_VERSION 1 /**< Minor version of this HAB release */
#define HAB_VER_MAJ_WIDTH 4 /**< Major version field width */
#define HAB_VER_MAJ_SHIFT 4 /**< Major version field offset */
#define HAB_VER_MIN_WIDTH 4 /**< Minor version field width */
#define HAB_VER_MIN_SHIFT 0 /**< Minor version field offset */
/** Full version of this HAB release @hideinitializer */
#define HAB_VERSION HAB_VER(HAB_MAJOR_VERSION, HAB_MINOR_VERSION)
/** Base version for this HAB release @hideinitializer */
#define HAB_BASE_VERSION HAB_VER(HAB_MAJOR_VERSION, 0)
/*@}*/
/* @} struct */
/*---------------------------------------------------------------------------*/
/** @addtogroup cmd
* @{
*/
/** @name Command tags
* @anchor cmd_tag
*
* Tag values 0xb0 .. 0xcf are reserved for HAB. Values 0xf0 .. 0xff
* are available for custom use.
*/
/*@{*/
#define HAB_CMD_SET 0xb1 /**< Set */
#define HAB_CMD_INS_KEY 0xbe /**< Install Key */
#define HAB_CMD_AUT_DAT 0xca /**< Authenticate Data */
#define HAB_CMD_WRT_DAT 0xcc /**< Write Data */
#define HAB_CMD_CHK_DAT 0xcf /**< Check Data */
#define HAB_CMD_NOP 0xc0 /**< No Operation */
#define HAB_CMD_INIT 0xb4 /**< Initialise */
#define HAB_CMD_UNLK 0xb2 /**< Unlock */
#ifdef HAB_FUTURE
#define HAB_CMD_RMV_KEY /**< Remove Key */
#define HAB_CMD_INS_REF /**< Install Reference Data */
#define HAB_CMD_INS_PLG /**< Install Plugin */
#define HAB_CMD_RMV_PLG /**< Remove Plugin */
#define HAB_CMD_CHK_VER /**< Check SW Version */
#endif
/* Remaining values: b7, b8, bb, bd, c3, c5, c6, c9 */
/*@}*/
/* @} cmd */
/*---------------------------------------------------------------------------*/
/** @addtogroup pcl
* @{
*/
/** @name Protocol tags
* @anchor pcl_tag
*
* Tag values 0x00 .. 0xef are reserved for HAB. Values 0xf0 .. 0xff are
* available for custom use.
*/
/*@{*/
#define HAB_PCL_SRK 0x03 /**< SRK certificate format */
#define HAB_PCL_X509 0x09 /**< X.509v3 certificate format */
#define HAB_PCL_CMS 0xc5 /**< CMS/PKCS#7 signature format */
#define HAB_PCL_BLOB 0xbb /**< SHW-specific wrapped key format */
#define HAB_PCL_AEAD 0xa3 /**< Proprietary AEAD MAC format */
#ifdef HAB_FUTURE
#define HAB_PCL_WTLS 0x05 /**< OMA WTLS certificate format */
#define HAB_PCL_FSL 0x0f /**< FSL bound signature protocol */
#define HAB_PCL_HMAC 0x30 /**< NIST HMAC message authentication */
#define HAB_PCL_CBCMAC 0x33 /**< CBC-MAC message authentication */
#endif
/*@}*/
/* Available values: 06, 0a, 0c, 11, 12, 14, 17, 18, 1b, 1d, 1e, 21, 22, 24,
* 27, 28, 2b, 2d, 2e, 35, 36, 39, 3a, 3c, 3f, 41, 42, 44, 47, 48, 4b, 4d, 4e,
* 50, 53, 55, 56, 59, 5a, 5c, 5f, 60, 63, 65, 66, 69, 6a, 6c, 6f, 71, 72, 74,
* 77, 78, 7b, 7d, 7e, 81, 82, 84, 87, 88, 8b, 8d, 8e, 90, 93, 95, 96, 99, 9a,
* 9c, 9f, a0, a5, a6, a9, aa, ac, af, b1, b2, b4, b7, b8, bd, be, c0, c3, c6,
* c9, ca, cc, cf, d1, d2, d4, d7, d8, db, dd, de, e1, e2, e4, e7, e8, eb, ed,
* ee
*
* Custom values: f0, f3, f5, f6, f9, fa, fc, ff
*/
/* @} pcl */
/*---------------------------------------------------------------------------*/
/** @addtogroup alg
* @{
*/
/** @name Algorithm types
* @anchor alg_typ
*
* The most-significant nibble of an algorithm ID denotes the algorithm
* type. Algorithms of the same type share the same interface.
*
* Types 0x0 .. 0xc are reserved for HAB. Types 0xd .. 0xf are available for
* custom use. Within each reserved type N in 0 .. c, tag values 0xN0 .. 0xNc
* are reserved for HAB. Values 0xNd .. 0xNf are available for custom use.
*/
/*@{*/
#define HAB_ALG_ANY 0x0 /**< Algorithm type ANY */
#define HAB_ALG_HASH 0x1 /**< Hash algorithm type */
#define HAB_ALG_SIG 0x2 /**< Signature algorithm type */
#define HAB_ALG_FF 0x3 /**< Finite field arithmetic */
#define HAB_ALG_EC 0x4 /**< Elliptic curve arithmetic */
#define HAB_ALG_CIPHER 0x5 /**< Cipher algorithm type */
#define HAB_ALG_MODE 0x6 /**< Cipher/hash modes */
#define HAB_ALG_WRAP 0x7 /**< Key wrap algorithm type */
/*@}*/
/** @name Algorithm type ANY
*
* Algorithms of type ANY have no common interface: the protocol must know
* what to do.
*/
/*@{*/
#ifdef HAB_FUTURE
#define HAB_ALG_RANDOM /**< Random number generation */
#endif
/* Available values: 03, 05, 06, 09, 0a, 0c, 0f
*/
/*@}*/
/** @name Hash algorithms */
/*@{*/
#define HAB_ALG_SHA1 0x11 /**< SHA-1 algorithm ID */
#define HAB_ALG_SHA256 0x17 /**< SHA-256 algorithm ID */
#define HAB_ALG_SHA512 0x1b /**< SHA-512 algorithm ID */
/* Available values: 0x14, 0x12, 18, 1d, 1e
*/
/*@}*/
/** @name Signature algorithms */
/*@{*/
#define HAB_ALG_PKCS1 0x21 /**< PKCS#1 RSA signature algorithm */
#ifdef HAB_FUTURE
#define HAB_ALG_DSA /**< NIST DSA signature algorithm */
#define HAB_ALG_ECDSA /**< NIST ECDSA signature algorithm */
#endif
/* Available values: 22, 24, 27, 28, 2b, 2d, 2e
*/
/*@}*/
/** @name Cipher algorithms */
/*@{*/
#define HAB_ALG_AES 0x55 /**< AES algorithm ID */
/* Available values: 50, 53, 56, 59, 5a, 5c, 5f
*/
/*@}*/
/** @name Cipher or hash modes */
/*@{*/
#define HAB_MODE_CCM 0x66 /**< Counter with CBC-MAC */
#ifdef HAB_FUTURE
#define HAB_MODE_HMAC /**< HMAC hash mode */
#endif
/* Available values: 60, 63, 65, 69, 6a, 6c, 6f
*/
/*@}*/
/** @name Key wrap algorithms */
/*@{*/
#define HAB_ALG_BLOB 0x71 /**< SHW-specific key wrap */
/* Available values: 72, 74, 77, 78, 7b, 7d, 7e
*/
/*@}*/
/* Available values: 81, 82, 84, 87, 88, 8b, 8d, 8e, 90, 93, 95, 96, 99, 9a,
* 9c, 9f, a0, a3, a5, a6, a9, aa, ac, af, b1, b2, b4, b7, b8, bb, bd, be, c0,
* c3, c5, c6, c9, ca, cc, cf, d1, d2, d4, d7, d8, db, dd, de, e1, e2, e4, e7,
* e8, eb, ed, ee, f0, f3, f5, f6, f9, fa, fc, ff
*/
/* @} alg */
/*---------------------------------------------------------------------------*/
/** @addtogroup eng
* @{
*/
/** @name Engine plugin tags
* @anchor eng_tag
*
* Tag values 0x00 .. 0xef and 0xff are reserved for HAB. Values 0xf0 .. 0xfe
* are available for custom use.
*/
/*@{*/
#define HAB_ENG_ANY 0x00 /**< First compatible engine will be
* selected automatically (no engine
* configuration parameters are allowed).
*/
#define HAB_ENG_SCC 0x03 /**< Security controller */
#define HAB_ENG_RTIC 0x05 /**< Run-time integrity checker */
#define HAB_ENG_SAHARA 0x06 /**< Crypto accelerator */
#define HAB_ENG_CSU 0x0a /**< Central Security Unit */
#define HAB_ENG_SRTC 0x0c /**< Secure clock */
#ifdef HAB_FUTURE
#define HAB_ENG_RNG 0x09 /**< Standalone random number generator */
#define HAB_ENG_SJC 0x0f /**< Secure JTAG controller */
#define HAB_ENG_WDOG 0x11 /**< Watchdog timer */
#define HAB_ENG_SRC 0x12 /**< System Reset Controller */
#define HAB_ENG_SPBA 0x14 /**< Shared Peripheral Bus Arbiter */
#define HAB_ENG_IIM 0x17 /**< Fuse controller */
#define HAB_ENG_IOMUX 0x18 /**< IO multiplexer */
#endif
#define HAB_ENG_DCP 0x1b /**< Data Co-Processor */
#define HAB_ENG_CAAM 0x1d /**< Cryptographic Acceleration and
Assurance Module */
#define HAB_ENG_SNVS 0x1e /**< Secure Non-Volatile Storage */
#define HAB_ENG_OCOTP 0x21 /**< Fuse controller */
/** @cond rom */
#define HAB_ENG_DTCP 0x22 /**< DTCP co-processor */
#define HAB_ENG_ROM 0x36 /**< Protected ROM area */
#define HAB_ENG_HDCP 0x24 /**< HDCP co-processor */
#define HAB_ENG_RTL 0x77 /**< @rom RTL simulation engine */
/** @endcond */
#define HAB_ENG_SW 0xff /**< Software engine */
/* Available values: 27, 28, 2b, 2d, 2e, 30, 33, 35,
* 39, 3a, 3c, 3f, 41, 42, 44, 47, 48, 4b, 4d, 4e, 50, 53, 55, 56, 59, 5a,
* 5c, 5f, 60, 63, 65, 66, 69, 6a, 6c, 6f, 71, 72, 74, 78, 7b, 7d, 7e, 81,
* 82, 84, 87, 88, 8b, 8d, 8e, 90, 93, 95, 96, 99, 9a, 9c, 9f, a0, a3, a5, a6,
* a9, aa, ac, af, b1, b2, b4, b7, b8, bb, bd, be, c0, c3, c5, c6, c9, ca, cc,
* cf, d1, d2, d4, d7, d8, db, dd, de, e1, e2, e4, e7, e8, eb, ed, ee
*
* Custom values: f0, f3, f5, f6, f9, fa, fc
*/
/*@}*/
/* @} eng */
/*---------------------------------------------------------------------------*/
/** @addtogroup sah
* @{
*/
/** Maximum data blocks in a single hash */
#define HAB_SAHARA_BLOCK_MAX 12
/** @cond rom */
/** @rom DMA storage requirement
*
* This figure is derived in several parts:
* - each hash operation needs a 6-word descriptor structure
* - each data block needs a 3-word link structure
* - the result needs a 3-word link structure
* - at least 40 bytes are required for SHA-256 result and memory manager
* overhead: 64 bytes allows some small overhead.
*/
#define HAB_SAHARA_DMA_MIN_BYTES (24 + HAB_SAHARA_BLOCK_MAX * 12 + 12 + 64)
/** @endcond */
/* @} sah */
/*---------------------------------------------------------------------------*/
/** @addtogroup dcp
* @{
*/
/** Maximum data blocks in a single hash */
#define HAB_DCP_BLOCK_MAX 6
/** @cond rom */
/** @rom DMA storage requirement
*
* This figure is derived in two parts:
* - each data block needs an 8-word work packet (descriptor)
* - at least 40 bytes are required for SHA-256 result and memory manager
* overhead: 64 bytes allows some small overhead.
*/
#define HAB_DCP_DMA_MIN_BYTES (64 + HAB_DCP_BLOCK_MAX * 32)
/** @endcond */
/* @} dcp */
/*---------------------------------------------------------------------------*/
/** @addtogroup rtic
* @{
*/
/** Maximum data blocks in a single hash */
#define HAB_RTIC_BLOCK_MAX 2
/* @} rtic */
/*---------------------------------------------------------------------------*/
/** @addtogroup scc
* @{
*/
/** @cond rom */
/** @rom DMA storage requirement
*
* This figure is derived in several stages, and assumes plaintext and
* ciphertext buffers are both allocated in the DMA region :
* - 4 blocks of plaintext required
* - 4 blocks of ciphertext required
* - each block is 16 bytes long
* - the plaintext address must be block-aligned (up to 15 bytes overhead)
* - the ciphertext address must be block-aligned (up to 3 bytes overhead)
* - at least 8 bytes of memory manager overhead: allow 32 for comfort
*/
#define HAB_SCC_DMA_MIN_BYTES ( (4+4)*16 + 15 + 3 + 32)
/** @endcond */
/* @} scc */
/*---------------------------------------------------------------------------*/
/** @addtogroup caam
* @{
*/
/** Maximum data blocks in an @ref cmd_aut_dat command */
#define HAB_CAAM_BLOCK_MAX 8
/** @cond rom */
/** @rom Hash DMA storage requirement
*
* This figure is derived in several parts:
* - each hash operation needs
* - a 7-word descriptor, and
* - a 32-byte result buffer (for SHA-256),
* - giving a base requirement of (7*4 + 32) = 60 bytes
* - each data block needs a 4-word link structure
* - memory manager overhead is at least 8 bytes: 16 bytes allows flexibility
*/
#define HAB_CAAM_HSH_DMA_MIN_BYTES (60 + HAB_CAAM_BLOCK_MAX * 16 + 16)
/** @rom AEAD DMA storage requirement
*
* This figure is derived in several parts:
* - each AEAD operation needs
* - a 16-word descriptor,
* - a 32-byte initial context value (B0 and CTR0), and
* - a 16-byte MAC value,
* - giving a base requirement of (16*4 + 32 + 16) = 112 bytes
* - each data block needs a 4-word link structure
* - memory manager overhead is at least 8 bytes: 16 bytes allows flexibility
*/
#define HAB_CAAM_CCM_DMA_MIN_BYTES (112 + HAB_CAAM_BLOCK_MAX * 16 + 16)
/** @rom RNG DMA storage requirement
*
* This figure is derived in several parts:
* - each DRNG test operation allocates a DMA area with
* - a 1-word header, and
* - a 3-word job ring area, and
* - a 54-word descriptor,
* - requiring a total 58*4 = 232 bytes
* - each DRNG test operation also allocates a DMA area with
* - a 1-word header, and
* - a 32-byte result buffer
* - requiring a total 4 + 32 = 36 bytes
*/
#define HAB_CAAM_RNG_DMA_MIN_BYTES (232 + 32)
/** @endcond */
/* @} caam */
/*---------------------------------------------------------------------------*/
/** @addtogroup key
* @{
*/
/** @name Key types
* @anchor key_types
*
* Tag values 0xe0 .. 0xef are reserved for HAB. Values 0xf0 .. 0xff
* are available for custom use.
*/
/*@{*/
#define HAB_KEY_PUBLIC 0xe1 /**< Public key type: data present */
#define HAB_KEY_SECRET 0xe2 /**< Secret key type: data present */
#define HAB_KEY_MASTER 0xed /**< Master KEK type */
#define HAB_KEY_HASH 0xee /**< Any key type: hash only */
/* Available values: e4, e7, e8, eb
*
* Custom values: f0, f3, f5, f6, f9, fa, fc, ff
*/
/*@}*/
/** @name Public key store indices */
/*@{*/
#define HAB_IDX_SRK 0 /**< Super-Root Key index */
#define HAB_IDX_CSFK 1 /**< CSF key index */
/*@}*/
/** @name Key Counts */
/*@{*/
#define HAB_SRK_MIN 1 /**< Minimum Super-Root Key count */
#define HAB_SRK_MAX 4 /**< Maximum Super-Root Key count */
#define HAB_KEY_PUBLIC_MAX 5 /**< Maximum installed public key count
* (incl Super-Root Key)
*/
#define HAB_KEY_SECRET_MAX 4 /**< Maximum installed secret key count
* (excl Master KEKs)
*/
/*@}*/
/* @} key */
/*---------------------------------------------------------------------------*/
#ifdef HAB_FUTURE
/** @addtogroup key_ecdsa
* @{
*/
/** @name Bitfield definitions */
/*@{*/
#define HAB_KEY_ECDSA_FLG_WIDTH 8 /**< Width of @a flg field */
#define HAB_KEY_ECDSA_FLG_SHIFT 0 /**< Offset of @a flg field */
#define HAB_KEY_ECDSA_TYP_WIDTH 8 /**< Width of @a typ field */
#define HAB_KEY_ECDSA_TYP_SHIFT 24 /**< Offset of @a typ field */
#define HAB_KEY_ECDSA_SIZ_WIDTH 8 /**< Width of @a siz field */
#define HAB_KEY_ECDSA_SIZ_SHIFT 16 /**< Offset of @a siz field */
#define HAB_KEY_ECDSA_REDBITS_WIDTH 16 /**< Width of @a red_bits field */
#define HAB_KEY_ECDSA_REDBITS_SHIFT 0 /**< Offset of @a red_bits field */
/*@}*/
/* @} key_ecdsa */
#endif
/*---------------------------------------------------------------------------*/
/** @addtogroup key_pkcs1
* @{
*/
/** @name Bitfield definitions */
/*@{*/
#define HAB_KEY_PKCS1_FLG_WIDTH 8 /**< Width of @a flg field */
#define HAB_KEY_PKCS1_FLG_SHIFT 0 /**< Offset of @a flg field */
#define HAB_KEY_PKCS1_MODBYTES_WIDTH 16 /**< Width of mod_bytes field */
#define HAB_KEY_PKCS1_MODBYTES_SHIFT 16 /**< Offset of mod_bytes field */
#define HAB_KEY_PKCS1_EXPBYTES_WIDTH 16 /**< Width of exp_bytes field */
#define HAB_KEY_PKCS1_EXPBYTES_SHIFT 0 /**< Offset of exp_bytes field */
/*@}*/
/** @name Binding flag bitfield definitions */
/*@}*/
#define HAB_KEY_BND_FLG_WIDTH 5 /**< Width of binding flags */
#define HAB_KEY_BND_FLG_SHIFT 2 /**< Offset of binding flags */
/*@}*/
/* @} key_pkcs1 */
/*---------------------------------------------------------------------------*/
/** @addtogroup cmd_wrt_dat
* @{
*/
/** @name Parameter bitfield definitions.
*
* Apply to both @ref cmd_wrt_dat and @ref cmd_chk_dat commands. */
/*@{*/
#define HAB_CMD_WRT_DAT_FLAGS_WIDTH 5 /**< @a flags field width */
#define HAB_CMD_WRT_DAT_FLAGS_SHIFT 3 /**< @a flags field offset */
#define HAB_CMD_WRT_DAT_BYTES_WIDTH 3 /**< @a bytes field width */
#define HAB_CMD_WRT_DAT_BYTES_SHIFT 0 /**< @a bytes field offset */
/*@}*/
/* @} cmd_wrt_dat */
/*---------------------------------------------------------------------------*/
/** @addtogroup bnd_obj
* @{
*/
/** @name Binding object IDs
* @anchor bnd_ids
*
* The ASN.1 object identifiers used to identify HAB binding attributes are
* defined in the following arc:
*
@verbatim
id-fsl OBJECT IDENTIFIER ::= {
joint-iso-itu-t(2) country(16) us(840) organization(1) fsl(123456) }
id-habBnd OBJECT IDENTIFIER ::= {
id-fsl hab(32) binding-objects(16) }
id-habBnd-dat OBJECT IDENTIFIER ::= {
id-habBnd dat(1) }
id-habBnd-cfg OBJECT IDENTIFIER ::= {
id-habBnd cfg(3) }
id-habBnd-fid OBJECT IDENTIFIER ::= {
id-habBnd fid(5) }
id-habBnd-mid OBJECT IDENTIFIER ::= {
id-habBnd mid(6) }
id-habBnd-cid OBJECT IDENTIFIER ::= {
id-habBnd cid(9) }
@endverbatim
*
* The ASN.1 object identifiers used to identify HAB binding attributes are
* single component extensions of id-habBnd using a component value less than
* 128 (so that the component can be DER-encoded in a single byte).
*
* The DER encoding of an object identifier in this arc is the concatenation
* of the DER prefix with the single byte identifier for the required binding
* object. Binding object attribute values are encoded as an ASN.1 SET with
* a single OCTET STRING member.
*/
/*@{*/
/** DER prefix
*
* @todo update description and encoding of binding object identifiers with
* real fsl value instead of fsl(123456) encoded as 0x87, 0xc4, 0x40, and
* confirm chosen values for hab(32) and binding-objects(16).
*/
#define HAB_BND_DER_PREFIX \
{0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x87, 0xc4, 0x40, 0x20, 0x10}
#define HAB_BND_DAT 0x01 /**< Data type (mandatory) */
#define HAB_BND_CFG 0x03 /**< Security configuration */
#define HAB_BND_FID 0x05 /**< Fabrication UID */
#define HAB_BND_MID 0x06 /**< Manufacturing ID */
#define HAB_BND_CID 0x09 /**< Caller ID */
/* Available values: 0a, 0c, 0f, 11, 12, 14, 17, 18, 1b, 1d, 1e, 21, 22, 24,
* 27, 28, 2b, 2d, 2e, 30, 33, 35, 36, 39, 3a, 3c, 3f, 41, 42, 44, 47, 48, 4b,
* 4d, 4e, 50, 53, 55, 56, 59, 5a, 5c, 5f, 60, 63, 65, 66, 69, 6a, 6c, 6f, 71,
* 72, 74, 77, 78, 7b, 7d, 7e
*/
/*@}*/
/** @name Caller IDs
*
* Only the ROM caller ID is defined, but other caller IDs may be defined by
* later boot stages.
*/
/*@{*/
#define HAB_CID_ROM 0 /**< ROM Caller ID */
/*@}*/
/* @} bnd_obj */
#ifdef HAB_FUTURE
/** @addtogroup sig_fsl
* @{
*/
#define HAB_BND_DAT_BYTES 512 /**< Maximum binding data size */
/* @} sig_fsl */
#endif
/*===========================================================================
MACROS
=============================================================================*/
/*
* Helper macros
*/
#define HAB_CMD_UNS 0xff
#define DEFAULT_IMG_KEY_IDX 2
#define GEN_MASK(width) \
((1UL << (width)) - 1)
#define GEN_FIELD(f, width, shift) \
(((f) & GEN_MASK(width)) << (shift))
#define PACK_UINT32(a, b, c, d) \
((uint32_t) ( (((uint32_t)(a) & 0xFF) << 24) \
|(((uint32_t)(b) & 0xFF) << 16) \
|(((uint32_t)(c) & 0xFF) << 8) \
|(((uint32_t)(d) & 0xFF)) ) )
#define EXPAND_UINT32(w) \
(uint8_t)((w)>>24), (uint8_t)((w)>>16), (uint8_t)((w)>>8), (uint8_t)(w)
#define EXPAND_UINT16(w) \
(uint8_t)((w)>>8), (uint8_t)(w)
#define HDR(tag, bytes, par) \
(uint8_t)(tag), (uint8_t)((bytes)>>8), (uint8_t)(bytes), (uint8_t)(par)
#define HAB_VER(maj, min) \
(GEN_FIELD((maj), HAB_VER_MAJ_WIDTH, HAB_VER_MAJ_SHIFT) \
| GEN_FIELD((min), HAB_VER_MIN_WIDTH, HAB_VER_MIN_SHIFT))
#define DCD_DATA(addr, data) EXPAND_UINT32(addr), EXPAND_UINT32(data)
/*
* CSF header
*/
#define CSF_HDR(bytes, HABVER) \
HDR(HAB_TAG_CSF, (bytes), HABVER)
/*
* DCD header
*/
#define DCD_HDR(bytes, HABVER) \
HDR(HAB_TAG_DCD, (bytes), HABVER)
/*
* IVT header (goes in the struct's hab_hdr_t field, not a byte array)
*/
#define IVT_HDR(bytes, HABVER) \
{HAB_TAG_IVT, {(uint8_t)((bytes)>>8), (uint8_t)(bytes)}, HABVER}
/*
* Write Data
*/
#define WRT_DAT(flags, bytes, address, val_msk) \
HDR(HAB_CMD_WRT_DAT, WRT_DAT_BYTES, WRT_DAT_PAR((flags), (bytes))), \
EXPAND_UINT32(address), \
EXPAND_UINT32(val_msk)
#define WRT_DAT_BYTES 12
#define MULTI_WRT_DAT(flags, bytes, address1, val_msk1, address2, \
val_msk2, address3, val_msk3) \
HDR(HAB_CMD_WRT_DAT, MULTI_WRT_DAT_BYTES, WRT_DAT_PAR((flags), (bytes))), \
EXPAND_UINT32(address1), \
EXPAND_UINT32(val_msk1), \
EXPAND_UINT32(address2), \
EXPAND_UINT32(val_msk2), \
EXPAND_UINT32(address3), \
EXPAND_UINT32(val_msk3)
#define MULTI_WRT_DAT_BYTES 28
#define WRT_DAT_PAR(flags, bytes) \
(GEN_FIELD((flags), \
HAB_CMD_WRT_DAT_FLAGS_WIDTH, \
HAB_CMD_WRT_DAT_FLAGS_SHIFT) \
| GEN_FIELD((bytes), \
HAB_CMD_WRT_DAT_BYTES_WIDTH, \
HAB_CMD_WRT_DAT_BYTES_SHIFT))
/*
* Check Data (forever)
*/
#define CHK_DAT_FOREVER(flags, bytes, address, mask) \
HDR(HAB_CMD_CHK_DAT, CHK_DAT_FOREVER_BYTES, WRT_DAT_PAR((flags), (bytes))), \
EXPAND_UINT32(address), \
EXPAND_UINT32(mask)
#define CHK_DAT_FOREVER_BYTES 12
/*
* Check Data (polled)
*/
#define HAB_CMD_CHK_DAT_COUNT 100
#define CHK_DAT(flags, bytes, address, mask, count) \
HDR(HAB_CMD_CHK_DAT, CHK_DAT_BYTES, WRT_DAT_PAR((flags), (bytes))), \
EXPAND_UINT32(address), \
EXPAND_UINT32(mask), \
EXPAND_UINT32(count)
#define CHK_DAT_BYTES 16
/*
* Set (generic - used internally only, or to generate invalid commands)
*/
#define SET(bytes, itm, value) \
HDR(HAB_CMD_SET, (bytes), (itm)), \
EXPAND_UINT32(value)
/*
* Set (MID location)
*/
#define SET_MID(bank, row, bit, fuses) \
HDR(HAB_CMD_SET, SET_MID_BYTES, HAB_VAR_CFG_ITM_MID), \
(bank), (row), (bit), (fuses)
#define SET_MID_BYTES 8
/*
* Set (default ENG)
*/
#define SET_ENG(alg, eng, cfg) \
HDR(HAB_CMD_SET, SET_ENG_BYTES, HAB_VAR_CFG_ITM_ENG), \
0, (alg), (eng), (cfg)
#define SET_ENG_BYTES 8
/*
* Init (engine)
*/
#define INIT(eng) \
HDR(HAB_CMD_INIT, INIT_BYTES, (eng))
#define INIT_BYTES 4
/*
* Unlk (engine)
*/
#define UNLK(eng, ...) \
UNLK_ ## eng(__VA_ARGS__)
#define UNLK_BYTES(eng, ...) \
UNLK_BYTES_ ## eng(__VA_ARGS__)
#define UNLK_HDR(eng, ...) \
HDR(HAB_CMD_UNLK, UNLK_BYTES_ ## eng(__VA_ARGS__), eng)
#define UNLK_FLG(flg) \
0, 0, 0, (uint8_t)(flg)
#define UNLK_FLG_BYTES 4
#define UNLK_HAB_ENG_SRTC(dnc) UNLK_HDR(HAB_ENG_SRTC)
#define UNLK_BYTES_HAB_ENG_SRTC(dnc) HDR_BYTES
#define UNLK_HAB_ENG_SNVS(flg) UNLK_HDR(HAB_ENG_SNVS), UNLK_FLG(flg)
#define UNLK_BYTES_HAB_ENG_SNVS(flg) (HDR_BYTES + UNLK_FLG_BYTES)
#define UNLK_HAB_ENG_CAAM(flg) UNLK_HDR(HAB_ENG_CAAM), UNLK_FLG(flg)
#define UNLK_BYTES_HAB_ENG_CAAM(flg) (HDR_BYTES + UNLK_FLG_BYTES)
/* The next definition uses a GCC extension employing ## to swallow the
* trailing comma in case the macro is called with only the fixed arguments
* (i.e. flg here). This extension appears to work in the GNU compatible mode
* of RVDS and GHS compilers.
*/
#define UNLK_HAB_ENG_OCOTP(flg, ...) \
UNLK_HDR(HAB_ENG_OCOTP, flg), UNLK_FLG(flg), ## __VA_ARGS__
#define UNLK_BYTES_HAB_ENG_OCOTP(flg, ...) \
(HDR_BYTES + UNLK_FLG_BYTES \
+ ( ((flg) & (HAB_OCOTP_UNLOCK_FIELD_RETURN \
|HAB_OCOTP_UNLOCK_JTAG \
|HAB_OCOTP_UNLOCK_SCS)) \
? STUB_FAB_UID_BYTES \
: 0 ))
#if 0
/* Note: no comma after HDR(). Supplied by _VAL macro if needed */
#define UNLK(eng, val) \
HDR(HAB_CMD_UNLK, UNLK_BYTES_ ## eng, (eng)) \
UNLK_VAL_ ## eng(val)
#define UNLK_BYTES(eng) \
UNLK_BYTES_ ## eng
#define UNLK_BYTES_HAB_ENG_SRTC HDR_BYTES
#define UNLK_VAL_HAB_ENG_SRTC(val) /* no val field */
#define UNLK_BYTES_HAB_ENG_SNVS (HDR_BYTES + 4)
#define UNLK_VAL_HAB_ENG_SNVS(val) ,0,0,0,((val)&0xff)
#define UNLK_BYTES_HAB_ENG_CAAM (HDR_BYTES + 4)
#define UNLK_VAL_HAB_ENG_CAAM(val) ,0,0,0,((val)&0xff)
#endif
/*
* NOP
*/
#define NOP() \
HDR(HAB_CMD_NOP, NOP_BYTES, 0xae) /* third param is ignored */
#define NOP_BYTES 4
/*
* Install Key (generic - used internally only)
*/
#define INS_KEY(bytes, flg, pcl, alg, src, tgt, crt) \
HDR(HAB_CMD_INS_KEY, (bytes), (flg)), \
(pcl), (alg), (src), (tgt), \
EXPAND_UINT32(crt)
#define INS_KEY_BASE_BYTES 12
/*
* Install Key (SRK)
*/
#define INS_SRK(flg, alg, src, crt) \
INS_KEY(INS_SRK_BYTES, (flg), \
HAB_PCL_SRK, (alg), (src), HAB_IDX_SRK, \
(crt))
#define INS_SRK_BYTES INS_KEY_BASE_BYTES
/*
* Install Key (CSFK)
*/
#define INS_CSFK(flg, pcl, crt) \
INS_KEY(INS_CSFK_BYTES, (flg) | HAB_CMD_INS_KEY_CSF, \
(pcl), HAB_ALG_ANY, HAB_IDX_SRK, HAB_IDX_CSFK, \
(crt))
#define INS_CSFK_BYTES INS_KEY_BASE_BYTES
/*
* Install Key (IMGK - no hash)
*/
#define INS_IMGK(flg, pcl, src, tgt, crt) \
INS_KEY(INS_IMGK_BYTES, (flg), \
(pcl), HAB_ALG_ANY, (src), (tgt), \
(crt))
#define INS_IMGK_BYTES INS_KEY_BASE_BYTES
/*
* Install Key (IMGK - with hash). Must be followed by the crt_hsh contents
* (e.g. using #include). The length field depends on using one of the
* standard HAB algorithm names, with no adornments like casts or
* parentheses. Note that the length macro cannot be used here: the ##
* must appear in the body of this macro to prevent the alg parameter from
* being expanded first.
*/
#define INS_IMGK_HASH(flg, pcl, alg, src, tgt, crt) \
INS_KEY(INS_KEY_BASE_BYTES + BYTES_ ## alg, (flg) | HAB_CMD_INS_KEY_HSH, \
(pcl), (alg), (src), (tgt), \
(crt))
/*
* Same as above but the hash length is fixed to the length of SHA1,
* but the algorithm remains unchanged.
*/
#define INS_IMGK_INV_HASH(flg, pcl, alg, src, tgt, crt) \
INS_KEY(INS_IMGK_HASH_BYTES(HAB_ALG_SHA1), (flg) | HAB_CMD_INS_KEY_HSH, \
(pcl), (alg), (src), (tgt), \
(crt))
#define INS_IMGK_HASH_BYTES(alg) \
(INS_KEY_BASE_BYTES + BYTES_ ## alg)
#define BYTES_HAB_ALG_SHA1 20
#define BYTES_HAB_ALG_SHA256 32
#define BYTES_HAB_ALG_SHA512 64
/* dummy value for invalid hash alg - same as default hash algorithm */
#define DEFAULT_HASH_ALG_BYTES BYTES_HAB_ALG_SHA256
#define BYTES_HAB_ALG_PKCS1 DEFAULT_HASH_ALG_BYTES
/*
* Authenticate Data (generic - used internally only)
*/
#define AUT_DAT(bytes, flg, key, pcl, eng, cfg, sig_start) \
HDR(HAB_CMD_AUT_DAT, (bytes), (flg)), \
(key), (pcl), (eng), (cfg), \
EXPAND_UINT32(sig_start)
#define AUT_DAT_BASE_BYTES 12
/*
* Authenticate Data (CSF)
*/
#define AUT_CSF(flg, pcl, eng, cfg, sig_start) \
AUT_DAT(AUT_CSF_BYTES, (flg), \
HAB_IDX_CSFK, (pcl), (eng), (cfg), \
(sig_start))
#define AUT_CSF_BYTES AUT_DAT_BASE_BYTES
/*
* Authenticate Data (Image)
*/
#define AUT_IMG(blocks, flg, key, pcl, eng, cfg, sig_start) \
AUT_DAT(AUT_IMG_BYTES(blocks), (flg), \
(key), (pcl), (eng), (cfg), \
(sig_start))
#define AUT_IMG_BYTES(blocks) \
(AUT_DAT_BASE_BYTES + 8*(blocks))
/** Supported widths of data commands.
* @ingroup cmd_wrt_dat
*/
typedef enum hab_data_width
{
HAB_DATA_WIDTH_BYTE = 1, /**< 8-bit value */
HAB_DATA_WIDTH_HALF = 2, /**< 16-bit value */
HAB_DATA_WIDTH_WORD = 4 /**< 32-bit value */
} hab_data_width_t;
/** Flags for Write Data commands.
* @ingroup cmd_wrt_dat
*/
typedef enum hab_cmd_wrt_dat_flg
{
HAB_CMD_WRT_DAT_MSK = 1, /**< Mask/value flag: if set, only specific
* bits may be overwritten at target address
* (otherwise all bits may be overwritten)
*/
HAB_CMD_WRT_DAT_SET = 2 /**< Set/clear flag: if #HAB_CMD_WRT_DAT_MSK
* set, bits at the target address overwritten
* with this flag (otherwise it is ignored)
*/
} hab_cmd_wrt_dat_flg_t;
/** Flags for Check Data commands.
* @ingroup cmd_chk_dat
*/
typedef enum hab_cmd_chk_dat_flg
{
HAB_CMD_CHK_DAT_SET = 2, /**< Set/clear flag: bits set in mask must
* match this flag
*/
HAB_CMD_CHK_DAT_ANY = 4 /**< Any/all flag: if clear, all bits set in
* mask must match (otherwise any bit
* suffices)
*/
} hab_cmd_chk_dat_flg_t;
/** Flags for Authenticate Data commands.
* @ingroup cmd_aut_dat
*/
typedef enum hab_cmd_aut_dat_flg
{
HAB_CMD_AUT_DAT_CLR = 0, /**< No flags set */
HAB_CMD_AUT_DAT_ABS = 1 /**< Absolute signature address */
} hab_cmd_aut_dat_flg_t;
/** Flags for Install Key commands.
* @ingroup cmd_ins_key
*/
typedef enum hab_cmd_ins_key_flg
{
HAB_CMD_INS_KEY_CLR = 0, /**< No flags set */
HAB_CMD_INS_KEY_ABS = 1, /**< Absolute certificate address */
HAB_CMD_INS_KEY_CSF = 2, /**< Install CSF key */
HAB_CMD_INS_KEY_DAT = 4, /**< Key binds to Data Type */
HAB_CMD_INS_KEY_CFG = 8, /**< Key binds to Configuration */
HAB_CMD_INS_KEY_FID = 16, /**< Key binds to Fabrication UID */
HAB_CMD_INS_KEY_MID = 32, /**< Key binds to Manufacturing ID */
HAB_CMD_INS_KEY_CID = 64, /**< Key binds to Caller ID */
HAB_CMD_INS_KEY_HSH = 128 /**< Certificate hash present */
} hab_cmd_ins_key_flg_t;
/** Key flags.
* @ingroup key_pkcs1
*
* @ifrom
*
* The binding flags given here align with those in #hab_cmd_ins_key_flg
*
* @endrom
*
*/
typedef enum hab_key_flg
{
/* Two more flag values available */
HAB_KEY_FLG_DAT = 4, /**< Key binds to Data Type */
HAB_KEY_FLG_CFG = 8, /**< Key binds to Configuration */
HAB_KEY_FLG_FID = 16, /**< Key binds to Fabrication UID */
HAB_KEY_FLG_MID = 32, /**< Key binds to Manufacturing ID */
HAB_KEY_FLG_CID = 64, /**< Key binds to Caller ID */
HAB_KEY_FLG_CA = 128 /**< CA key */
} hab_key_flg_t;
/** Secret key flags.
* @ingroup crt_blob
*/
typedef enum hab_key_secret_flg
{
/* Seven more flag values available */
HAB_KEY_FLG_KEK = 128 /**< KEK */
} hab_key_secret_flg_t;
/** Binding data types
* @ingroup bnd_obj
*/
typedef enum hab_dat {
HAB_DAT_CSF = 0x0f, /**< CSF signature */
HAB_DAT_IMG = 0x33, /**< Image signature */
#ifdef HAB_FUTURE
HAB_DAT_PLG = 0x3c, /**< Plugin signature */
#endif
HAB_DAT_MAX
} hab_dat_t;
/* Available values: 55, 5a, 66, 69, 96, 99, a5, aa, c3, cc, f0, ff
*/
/** Target check types
* @ingroup chk_tgt
*/
typedef enum hab_target {
HAB_TGT_MEMORY = 0x0f, /**< Check memory white list */
HAB_TGT_PERIPHERAL = 0xf0, /**< Check peripheral white list */
HAB_TGT_ANY = 0x55, /**< Check memory & peripheral white list */
HAB_TGT_MAX
} hab_target_t;
/** Security configuration types
* @ingroup status
*/
typedef enum hab_config {
/** @cond rom */
HAB_CFG_FAB = 0x00, /**< @rom Un-programmed IC */
/** @endcond */
HAB_CFG_RETURN = 0x33, /**< Field Return IC */
HAB_CFG_OPEN = 0xf0, /**< Non-secure IC */
HAB_CFG_CLOSED = 0xcc /**< Secure IC */
} hab_config_t;
/* Available values: 0f, 3c, 55, 5a, 66, 69, 96, 99, a5, aa, ff
*/
/** Security state types
* @ingroup status
*/
typedef enum hab_state {
HAB_STATE_INITIAL = 0x33, /**< Initialising state (transitory) */
HAB_STATE_CHECK = 0x55, /**< Check state (non-secure) */
HAB_STATE_NONSECURE = 0x66, /**< Non-secure state */
HAB_STATE_TRUSTED = 0x99, /**< Trusted state */
HAB_STATE_SECURE = 0xaa, /**< Secure state */
HAB_STATE_FAIL_SOFT = 0xcc, /**< Soft fail state */
HAB_STATE_FAIL_HARD = 0xff, /**< Hard fail state (terminal) */
HAB_STATE_NONE = 0xf0, /**< No security state machine */
HAB_STATE_MAX
} hab_state_t;
/* Available values: 00, 0f, 3c, 5a, 69, 96, a5, c3
*/
/** HAB status types
* @ingroup status
*/
typedef enum hab_status {
HAB_STS_ANY = 0x00, /**< Match any status in
* hab_rvt.report_event()
*/
HAB_FAILURE = 0x33, /**< Operation failed */
HAB_WARNING = 0x69, /**< Operation completed with warning */
HAB_SUCCESS = 0xf0, /**< Operation completed successfully */
HAB_STS_MAX
} hab_status_t;
/** Failure or warning reasons
* @ingroup evt
*
* Values 0x80 ... 0xff are reserved for internal use.
*/
typedef enum hab_reason {
HAB_RSN_ANY = 0x00, /**< Match any reason in
* hab_rvt.report_event()
*/
HAB_ENG_FAIL = 0x30, /**< Engine failure. */
HAB_INV_ADDRESS = 0x22, /**< Invalid address: access denied. */
HAB_INV_ASSERTION = 0x0c, /**< Invalid assertion. */
HAB_INV_CALL = 0x28, /**< Function called out of sequence. */
HAB_INV_CERTIFICATE = 0x21, /**< Invalid certificate. */
HAB_INV_COMMAND = 0x06, /**< Invalid command: command malformed. */
HAB_INV_CSF = 0x11, /**< Invalid @ref csf. */
HAB_INV_DCD = 0x27, /**< Invalid @ref dcd. */
HAB_INV_INDEX = 0x0f, /**< Invalid index: access denied. */
HAB_INV_IVT = 0x05, /**< Invalid @ref ivt. */
HAB_INV_KEY = 0x1d, /**< Invalid key. */
HAB_INV_RETURN = 0x1e, /**< Failed callback function. */
HAB_INV_SIGNATURE = 0x18, /**< Invalid signature. */
HAB_INV_SIZE = 0x17, /**< Invalid data size. */
HAB_MEM_FAIL = 0x2e, /**< Memory failure. */
HAB_OVR_COUNT = 0x2b, /**< Expired poll count. */
HAB_OVR_STORAGE = 0x2d, /**< Exhausted storage region. */
HAB_UNS_ALGORITHM = 0x12, /**< Unsupported algorithm. */
HAB_UNS_COMMAND = 0x03, /**< Unsupported command. */
HAB_UNS_ENGINE = 0x0a, /**< Unsupported engine. */
HAB_UNS_ITEM = 0x24, /**< Unsupported configuration item. */
HAB_UNS_KEY = 0x1b, /**< Unsupported key type or parameters. */
HAB_UNS_PROTOCOL = 0x14, /**< Unsupported protocol. */
HAB_UNS_STATE = 0x09, /**< Unsuitable state. */
HAB_RSN_MAX
} hab_reason_t;
/* Available values: 33, 35, 36, 39, 3a, 3c, 3f, 41, 42, 44,
* 47, 48, 4b, 4d, 4e, 50, 53, 55, 56, 59, 5a, 5c, 5f, 60, 63, 65, 66, 69, 6a,
* 6c, 6f, 71, 72, 74, 77, 78, 7b, 7d, 7e
*/
/** Audit logging contexts.
* @ingroup evt
*
* This list is sorted in order of increasing priority: where two contexts
* might apply, the latter one is used.
*
* Values 0x40 .. 0x5f are reserved for internal use.
*/
typedef enum hab_context {
HAB_CTX_ANY = 0x00, /**< Match any context in
* hab_rvt.report_event()
*/
/** @cond rom */
HAB_CTX_FAB = 0xff, /**< @rom Event logged in hab_fab_test() */
/** @endcond */
HAB_CTX_ENTRY = 0xe1, /**< Event logged in hab_rvt.entry() */
HAB_CTX_TARGET = 0x33, /**< Event logged in hab_rvt.check_target() */
HAB_CTX_AUTHENTICATE = 0x0a, /**< Event logged in
* hab_rvt.authenticate_image()
*/
HAB_CTX_DCD = 0xdd, /**< Event logged in hab_rvt.run_dcd() */
HAB_CTX_CSF = 0xcf, /**< Event logged in hab_rvt.run_csf() */
HAB_CTX_COMMAND = 0xc0, /**< Event logged executing @ref csf or @ref
* dcd command
*/
HAB_CTX_AUT_DAT = 0xdb, /**< Authenticated data block */
HAB_CTX_ASSERT = 0xa0, /**< Event logged in hab_rvt.assert() */
HAB_CTX_EXIT = 0xee, /**< Event logged in hab_rvt.exit() */
HAB_CTX_MAX
} hab_context_t;
/** Assertion types.
* @ingroup assert
*/
typedef enum hab_assertion {
HAB_ASSERT_BLOCK = 0, /**< Assert that a memory block was authenticated */
HAB_ASSERT_MAX
} hab_assertion_t;
/** RTIC configuration flags
* @ingroup rtic
*/
typedef enum hab_rtic_config {
HAB_RTIC_IN_SWAP8 = 0x01, /**< Set BYTE SWAP bit (reverse bytes within
* word on input to RTIC) */
HAB_RTIC_IN_SWAP16 = 0x02, /**< Set HALF WORD SWAP bit (reverse
* half-words within word on input to
* RTIC) */
HAB_RTIC_OUT_SWAP8 = 0x08, /**< Set HASH RESULT BYTE SWAP bit (reverse
* bytes within word on output from RTIC) */
HAB_RTIC_KEEP = 0x80 /**< Retain reference hash value for later
* monitoring */
} hab_rtic_config_t;
/** SAHARA configuration flags
* @ingroup sah
*/
typedef enum hab_sahara_config {
HAB_SAHARA_IN_SWAP8 = 0x01, /**< Set MESS BYTE SWAP bit (reverse message
* bytes within word on input to
* SAHARA) */
HAB_SAHARA_IN_SWAP16 = 0x02, /**< Set MESS HALF WORD SWAP bit (reverse
* message half-words within word on input
* to SAHARA) */
/* no SWAP32 for SAHARA message - leave 0x04 value unassigned */
/* no SWAP8 for SAHARA descriptors/links - leave 0x08 value unassigned */
HAB_SAHARA_DSC_BE8_16 = 0x10, /**< Interpret descriptors and links as for
* BE-8 16-bit memory. */
HAB_SAHARA_DSC_BE8_32 = 0x20 /**< Interpret descriptors and links as for
* BE-8 32-bit memory. */
} hab_sahara_config_t;
/** CAAM configuration flags
* @ingroup caam
*/
typedef enum hab_caam_config {
HAB_CAAM_IN_SWAP8 = 0x01, /**< Set Message Byte Swap Input bit (reverse
* message bytes within word on input to
* CAAM) */
HAB_CAAM_IN_SWAP16 = 0x02, /**< Set Message Half Word Swap Input bit
* (reverse message half-words within word
* on input to CAAM) */
/* no SWAP32 for CAAM message - leave 0x04 value unassigned */
HAB_CAAM_OUT_SWAP8 = 0x08, /**< Set Message Byte Swap Output bit
* (reverse message bytes within word on
* output from CAAM) */
HAB_CAAM_OUT_SWAP16 = 0x10, /**< Set Message Half Word Swap Output bit
* (reverse message half-words within word
* on output from CAAM) */
/* no SWAP32 for CAAM message - leave 0x20 value unassigned */
HAB_CAAM_DSC_SWAP8 = 0x40, /**< Set Control Byte Swap Input/Output bits
* (reverse descriptor/link bytes within
* word on input to or output from CAAM) */
HAB_CAAM_DSC_SWAP16 = 0x80 /**< Set Control Half Word Swap Input/Output
* bits (reverse descriptor/link half-words
* within word on input to or output from
* CAAM) */
} hab_caam_config_t;
/** CAAM unlock flags
* @ingroup caam
*/
typedef enum hab_caam_unlock_flag {
HAB_CAAM_UNLOCK_MID = 0x01, /**< Leave Job Ring and DECO master ID
* registers unlocked */
HAB_CAAM_UNLOCK_RNG = 0x02 /**< Leave RNG state handle 0
* uninstantiated, do not generate
* descriptor keys, do not set AES DPA
* mask, do not block state handle 0 test
* instantiation */
} hab_caam_unlock_flag_t;
/** SNVS unlock flags
* @ingroup snvs
*/
typedef enum hab_snvs_unlock_flag {
HAB_SNVS_UNLOCK_LP_SWR = 0x01, /**< Leave LP SW reset unlocked */
HAB_SNVS_UNLOCK_ZMK_WRITE = 0x02 /**< Leave Zeroisable Master Key write
* unlocked */
} hab_snvs_unlock_flag_t;
/** SNVS master keys
* @ingroup snvs
*
* @remark Note that the first two master key selections are completely
* interchangeable.
*/
typedef enum hab_snvs_keys {
HAB_SNVS_OTPMK = 0, /**< OTP master key */
HAB_SNVS_OTPMK_ALIAS = 1, /**< OTP master key (alias) */
HAB_SNVS_ZMK = 2, /**< Zeroisable master key */
HAB_SNVS_CMK = 3 /**< Combined master key */
} hab_snvs_keys_t;
/** OCOTP unlock flags
* @ingroup ocotp
*/
typedef enum hab_ocotp_unlock_flag {
HAB_OCOTP_UNLOCK_FIELD_RETURN = 0x01, /**< Leave Field Return activation
* unlocked */
HAB_OCOTP_UNLOCK_SRK_REVOKE = 0x02, /**< Leave SRK revocation unlocked */
HAB_OCOTP_UNLOCK_SCS = 0x04, /**< Leave SCS register unlocked */
HAB_OCOTP_UNLOCK_JTAG = 0x08 /**< Unlock JTAG using SCS HAB_JDE
* bit */
} hab_ocotp_unlock_flag_t;
/** DCP configuration flags
* @ingroup dcp
*
* @warning The byte-swapping controls produce unpredictable results unless
* the input data block lengths are multiples of 4 bytes.
*/
typedef enum hab_dcp_config {
HAB_DCP_IN_SWAP8 = 0x01, /**< Set INPUT BYTE SWAP bit (reverse bytes
* within words on input to DCP) */
/* no SWAP16 for DCP - leave 0x02 value unassigned */
HAB_DCP_IN_SWAP32 = 0x04, /**< Set INPUT WORD SWAP bit (ignored for
* hashing) */
HAB_DCP_OUT_SWAP8 = 0x08, /**< Set OUPUT BYTE SWAP bit (reverse bytes
* within words on output from DCP) */
/* no SWAP16 for DCP - leave 0x10 value unassigned */
HAB_DCP_OUT_SWAP32 = 0x20 /**< Set OUTPUT WORD SWAP bit (ignored for
* hashing) */
} hab_dcp_config_t;
#ifdef HAB_FUTURE
/** EC key specification types.
* @ingroup key_ecdsa
*/
typedef enum hab_ec_spec {
/** Named curve specification. The curve specification is a DER-encoded
* object identifier. Supported object identifiers are listed under @ref
* key_ecdsa_profile "ECDSA key profile".
*/
HAB_EC_SPEC_NAMED_CURVE = 0x01
} hab_ec_spec_t;
#endif
/** Variable configuration items
* @ingroup cmd_set
*/
typedef enum hab_var_cfg_itm {
HAB_VAR_CFG_ITM_MID = 0x01, /**< Manufacturing ID (MID) fuse locations */
HAB_VAR_CFG_ITM_ENG = 0x03 /**< Preferred engine for a given algorithm */
} hab_var_cfg_itm_t;
/*===========================================================================
ENUMS
=============================================================================*/
/*===========================================================================
STRUCTURES AND OTHER TYPEDEFS
=============================================================================*/
/** Header field components
* @ingroup hdr
*/
typedef struct hab_hdr {
uint8_t tag; /**< Tag field */
uint8_t len[2]; /**< Length field in bytes (big-endian) */
uint8_t par; /**< Parameters field */
} hab_hdr_t;
/** Loader callback.
* @ingroup auth_img
*
* @par Purpose
*
* This function must be supplied by the library caller if required. It is
* intended to finalise image loading in those boot modes where only a portion
* of the image is loaded to a temporary initial location prior to device
* configuration.
*
* @par Operation
*
* This function is called during hab_rvt.authenticate_image() between running
* the @ref dcd and @ref csf. The operation of this function is defined by
* the caller.
*
* @param[in,out] start Initial (possibly partial) image load address on
* entry. Final image load address on exit.
*
* @param[in,out] bytes Initial (possibly partial) image size on entry. Final
* image size on exit.
*
* @param[in] boot_data Initial @ref ivt Boot Data load address.
*
* @remark The interpretation of the Boot Data is defined by the caller.
* Different boot components or modes may use different boot data, or even
* different loader callback functions.
*
* @warning It should not be assumed by this function that the Boot Data is
* valid or authentic.
*
* @warning It is the responsibility of the loader callback to check the final
* image load addresses using hab_rvt.check_target() prior to copying any image
* data.
*
* @pre The (possibly partial) image has been loaded in the initial load
* address, and the Boot Data is within the initial image.
*
* @pre The @ref dcd has been run, if provided.
*
* @post The final image load addresses pass hab_rvt.check_target().
*
* @retval #HAB_SUCCESS if all operations completed successfully,
*
* @retval #HAB_FAILURE otherwise.
*/
typedef hab_status_t (*hab_loader_callback_f)(
void** start,
size_t* bytes,
const void* boot_data);
/*---------------------------------------------------------------------------*/
/** Image entry function prototype
* @ingroup rvt
*
* This typedef serves as the return type for hab_rvt.authenticate_image(). It
* specifies a void-void function pointer, but can be cast to another function
* pointer type if required.
*/
typedef void (*hab_image_entry_f)(void);
/*---------------------------------------------------------------------------*/
/** @ref rvt structure
* @ingroup rvt
*
* @par Format
*
* The @ref rvt consists of a @ref hdr followed by a list of addresses as
* described further below.
*/
struct hab_rvt {
/** @ref hdr with tag #HAB_TAG_RVT, length and HAB version fields
* (see @ref data)
*/
hab_hdr_t hdr;
/** Enter and initialise HAB library.
* @ingroup entry
*
* @par Purpose
*
* This function initialises the HAB library and @ref shw plugins. It is
* intended for use by post-ROM boot stage components, via the @ref rvt,
* prior to calling any other HAB functions other than
* hab_rvt.report_event() and hab_rvt.report_status().
*
* @ifrom It is also intended for use by the boot ROM via hab_rvt.entry().
* @endrom
*
* @par Operation
*
* This function performs the following operations every time it is called:
*
* - Initialise the HAB library internal state
* - Initialise the internal secret key store (cleared at the next
* hab_rvt.exit())
* - Run the entry sequence of each available @ref shw plugin
*
* When first called from boot ROM, this function also performs the
* following operations prior to those given above:
*
* - Initialise the internal public key store (persists beyond
* hab_rvt.exit())
* - Run the self-test sequence of each available @ref shw plugin
* - If a state machine is present and enabled, change the security state
* as follows:
* - If the IC is configured as #HAB_CFG_OPEN or #HAB_CFG_RETURN, move to
* #HAB_STATE_NONSECURE
* - If the IC is configured as #HAB_CFG_CLOSED, move to
* #HAB_STATE_TRUSTED
* - Otherwise, leave the security state unchanged
*
* If any failure occurs in the operations above:
*
* - An audit event is logged
* - All remaining operations are abandoned (except that all @ref shw
* self-test and entry sequences are still executed)
* - If a state machine is present and enabled, the security state is set
* as follows:
* - @ifrom Unless the IC is configured as #HAB_CFG_FAB,@endrom move to
* #HAB_STATE_NONSECURE. Note that if a security violation has been
* detected by the HW, the final state will be #HAB_STATE_FAIL_SOFT or
* #HAB_STATE_FAIL_HARD depending on the HW configuration.
*
* @warning Boot sequences may comprise several images with each launching
* the next as well as alternative images should one boot device or boot
* image be unavailable or unusable. The authentication of each image in
* a boot sequence must be bracketed by its own hab_rvt.entry()
* ... hab_rvt.exit() pair in order to ensure that security state
* information gathered for one image cannot be misapplied to another
* image.
*
* @ifrom
*
* @warning This applies to each boot path in boot ROM as well, except for
* the fabrication test path.
*
* @endrom
*
* @post HAB library internal state is initialised.
*
* @post Available @ref shw plugins are initialised.
*
* @post If a failure or warning occurs during @ref shw plugin
* initialisation, an audit event is logged with the relevant @ref eng
* tag. The status and reason logged are described in the relevant @ref
* shw plugin documentation.
*
* @post Security state is initialised, if a state machine is present and
* enabled.
*
* @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED,
* although unsuccessful operations will still generate audit log events,
*
* @retval #HAB_SUCCESS on other ICs if all commands completed
* without failure (even if warnings were generated),
*
* @retval #HAB_FAILURE otherwise.
*/
hab_status_t (*entry)(void);
/** Finalise and exit HAB library.
* @ingroup exit
*
* @par Purpose
*
* This function finalises the HAB library and @ref shw plugins. It is
* intended for use by post-ROM boot stage components, via the @ref rvt,
* after calling other HAB functions and prior to launching the next boot
* stage or switching to another boot path.
*
* @ifrom It is also intended for use by the boot ROM via hab_rvt.exit().
* @endrom
*
* @par Operation
*
* This function performs the following operations:
*
* - Finalise the HAB library internal state
* - Clear the internal secret key store
* - Run the finalisation sequence of each available @ref shw plugin
*
* If any failure occurs, an audit event is logged and all remaining
* operations are abandoned (except that all @ref shw exit sequences are
* still executed).
*
* @warning See warnings for hab_rvt.entry().
*
* @post #HAB_ASSERT_BLOCK records are cleared from audit log. Note that
* other event records are not cleared.
*
* @post Any public keys installed by @ref csf commands remain active.
*
* @post Any secret keys installed by @ref csf commands are deleted.
*
* @post Available @ref shw plugins are in their final state as described
* in the relevant sections.
*
* @post If a failure or warning occurs, an audit event is logged with the
* @ref eng tag of the @ref shw plugin concerned. The status and reason
* logged are described in the relevant @ref shw plugin documentation.
*
* @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED,
* although unsuccessful operations will still generate audit log events,
*
* @retval #HAB_SUCCESS on other ICs if all commands completed
* without failure (even if warnings were generated),
*
* @retval #HAB_FAILURE otherwise.
*/
hab_status_t (*exit)(void);
/** Check target address
* @ingroup chk_tgt
*
* @par Purpose
*
* This function reports whether or not a given target region is allowed
* for either peripheral configuration or image loading in memory. It is
* intended for use by post-ROM boot stage components, via the @ref rvt,
* in order to avoid configuring security-sensitive peripherals, or
* loading images over sensitive memory regions or outside recognised
* memory devices in the address map.
*
* @ifrom It is also available for use by the boot ROM, both directly via
* hab_rvt.check_target() and indirectly via hab_rvt.authenticate_image().
* @endrom
*
* @par Operation
*
* The lists of allowed target regions vary by IC and core, and should be
* taken from the @ref ref_rug.
*
* @ifrom The allowed register sets for peripheral configuration and memory
* regions for image loading are defined in the @ref hal by
* #hab_hal_peripheral and #hab_hal_memory respectively. @endrom
*
* @param[in] type Type of target (memory, peripheral or any in which both
* the memory and peripheral regions are checked)
*
* @param[in] start Address of target region
*
* @param[in] bytes Size of target region
*
* @post if the given target region goes beyond the allowed regions, an
* audit event is logged with status #HAB_FAILURE and reason
* #HAB_INV_ADDRESS, together with the call parameters. See the @ref evt
* record documentation for details.
*
* @post For successful commands, no audit event is logged.
*
* @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED,
* although unsuccessful operations will still generate audit log events,
*
* @retval #HAB_SUCCESS if the given target region lies wholly within the
* allowed regions for the requested type of target.
*
* @retval #HAB_FAILURE otherwise
*/
hab_status_t (*check_target)(hab_target_t type,
const void* start,
size_t bytes);
/** Authenticate image.
* @ingroup auth_img
*
* @par Purpose
*
* This function combines DCD, CSF and Assert functions in a standard
* sequence in order to authenticate a loaded image. It is intended for
* use by post-ROM boot stage components, via the @ref rvt. Support for
* images partially loaded to an initial location is provided via a
* callback function.
*
* @ifrom It is also available for use by the boot ROM via
* hab_rvt.authenticate_image(). @endrom
*
* @par Operation
*
* This function performs the following sequence of operations:
* - Check that the initial image load addresses pass
* hab_rvt.check_target().
* - Check that the IVT offset lies within the initial image bounds.
* - Check that the @ref ivt @a self and @a entry pointers are not NULL
* - Check the @ref ivt header for consistency and compatability.
* - If provided in the @ref ivt, calculate the @ref dcd initial location,
* check that it lies within the initial image bounds, and run the @ref
* dcd commands.
* - If provided in the @ref ivt, calculate the Boot Data initial location
* and check that it lies within the initial image bounds.
* - If provided in the parameters, invoke the callback function with the
* initial image bounds and initial location of the @ref ivt Boot Data.
*
* From this point on, the full image is assumed to be in its final
* location. The following operations will be performed on all IC
* configurations (#hab_config), but will be only enforced on an IC
* configured as #HAB_CFG_CLOSED:
* - Check that the final image load addresses pass hab_rvt.check_target().
* - Check that the CSF lies within the image bounds, and run the CSF
* commands.
* - Check that all of the following data have been authenticated (using
* their final locations):
* - IVT;
* - DCD (if provided);
* - Boot Data (initial byte if provided);
* - Entry point (initial word).
*
* @param[in] cid Caller ID, used to identify which SW issued this call.
*
* @param[in] ivt_offset Offset in bytes of the IVT from the image start
* address.
*
* @param[in,out] start Initial (possibly partial) image load address on
* entry. Final image load address on exit.
*
* @param[in,out] bytes Initial (possibly partial) image size on entry.
* Final image size on exit.
*
* @param[in] loader Callback function to load the full image to its final
* load address. Set to NULL if not required.
*
* @remark Caller ID may be bound to signatures verified using keys
* installed with #HAB_CMD_INS_KEY_CID flag. See @ref cmd_ins_key and @ref
* bnd_obj for details.
*
* @remark A @a loader callback function may be supplied even if the image
* is already loaded to its final location on entry.
*
* @remark Boot Data (boot_data in @ref ivt) will be ignored if the
* @a loader callback function point is set to Null.
*
* @warning The @a loader callback function should lie within existing
* authenticated areas. @ifrom Or within the ROM. @endrom
*
* @warning It is the responsibility of the caller to check the initial
* image load addresses using hab_rvt.check_target() prior to loading the
* initial image and calling this function.
*
* @warning After completion of hab_rvt.authenticate_image(), the caller
* should test using hab_rvt.assert() that the Boot Data was
* authenticated.
*
* @post The post-conditions of the functions hab_rvt.check_target(),
* hab_rvt.run_dcd(), hab_rvt.run_csf() and hab_rvt.assert() apply also to
* this function. In particular, any audit events logged within the given
* functions have the context field appropriate to that function rather
* than #HAB_CTX_AUTHENTICATE. In addition, the side-effects and
* post-conditions of any callback function supplied apply.
*
* @post If a failure or warning occurs outside these contexts, an audit
* event is logged with status:
* - #HAB_FAILURE, with further reasons:
* - #HAB_INV_ADDRESS: initial or final image addresses outside allowed
* regions
* - #HAB_INV_ADDRESS: IVT, DCD, Boot Data or CSF outside image bounds
* - #HAB_INV_ADDRESS: IVT @a self or @a entry pointer is NULL
* - #HAB_INV_CALL: hab_rvt.entry() not run successfully prior to call
* - #HAB_INV_IVT: IVT malformed
* - #HAB_INV_IVT: IVT version number is less than HAB library version
* - #HAB_INV_RETURN: Callback function failed
*
* @retval entry field from @ref ivt on an IC not configured as
* #HAB_CFG_CLOSED provided that the following conditions are met
* (other unsuccessful operations will generate audit log events):
* - the @a start pointer and the pointer it locates are not NULL
* - the initial @ref ivt location is not NULL
* - the @ref ivt @ref hdr (given in the @a hdr field) is valid
* - the final @ref ivt location (given by the @a self field) is not NULL
* - any loader callback completed successfully,
*
* @retval entry field from @ref ivt on other ICs if all operations
* completed without failure (even if warnings were generated),
*
* @retval NULL otherwise.
*/
hab_image_entry_f (*authenticate_image)(uint8_t cid,
ptrdiff_t ivt_offset,
void** start,
size_t* bytes,
hab_loader_callback_f loader);
/** Execute a boot configuration script.
* @ingroup run_dcd
*
* @par Purpose
*
* This function configures the IC based upon a @ref dcd table. It is
* intended for use by post-ROM boot stage components, via the @ref rvt.
* This function may be invoked as often as required for each boot stage.
*
* @ifrom It is also intended for use by the boot ROM, both directly via
* hab_rvt.run_dcd() and indirectly via hab_rvt.authenticate_image().
* @endrom
*
* The difference between the configuration functionality in this function
* and hab_rvt.run_csf() arises because the @ref dcd table is not
* authenticated prior to running the commands. Hence, there is a more
* limited range of commands allowed, and a limited range of parameters to
* allowed commands.
*
* @par Operation
*
* This function performs the following operations:
* - Checks the @ref hdr for compatibility and consistency
* - Makes an internal copy of the @ref dcd table
* - Executes the commands in sequence from the internal copy of the @ref
* dcd
*
* If any failure occurs, an audit event is logged and all remaining
* operations are abandoned.
*
* @param[in] dcd Address of the @ref dcd.
*
* @warning It is the responsibility of the caller to ensure that the @a
* dcd parameter points to a valid memory location.
*
* @warning The @ref dcd must be authenticated by a subsequent @ref csf
* command prior to launching the next boot image, in order to avoid
* unauthorised configurations which may subvert secure operation.
* Although the content of the next boot stage's CSF may be out of scope
* for the hab_rvt.run_dcd() caller, it is possible to enforce this
* constraint by using hab_rvt.assert() to ensure that both the DCD and
* any pointers used to locate it have been authenticated.
*
* @warning Each invocation of hab_rvt.run_dcd() must occur between a pair
* of hab_rvt.entry() and hab_rvt.exit() calls, although multiple
* hab_rvt.run_dcd() calls (and other HAB calls) may be made in one
* bracket. This constraint applies whether hab_rvt.run_dcd() is
* successful or not: a subsequent call to hab_rvt.exit() is required
* prior to launching the authenticated image or switching to another boot
* target.
*
* @post Many commands may cause side-effects. See the @ref dcd
* documentation.
*
* @post If a failure or warning occurs within a command handler, an audit
* event is logged with the offending command, copied from the DCD. The
* status and reason logged are described in the relevant command
* documentation.
*
* @post For other failures or warning, the status logged is:
* - #HAB_WARNING, with further reasons:
* - #HAB_UNS_COMMAND: unsupported command encountered, where DCD
* version and HAB library version differ
* - #HAB_FAILURE, with further reasons:
* - #HAB_INV_ADDRESS: NULL @a dcd parameter
* - #HAB_INV_CALL: hab_rvt.entry() not run successfully prior to call
* - #HAB_INV_COMMAND: command not allowed in DCD
* - #HAB_UNS_COMMAND: unrecognised command encountered, where DCD
* version and HAB library version match
* - #HAB_INV_DCD: DCD malformed or too large
* - #HAB_INV_DCD: DCD version number is less than HAB library version
* @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED,
* although unsuccessful operations will still generate audit log events,
*
* @retval #HAB_SUCCESS on other ICs if all commands completed
* without failure (even if warnings were generated),
*
* @retval #HAB_FAILURE otherwise.
*/
hab_status_t (*run_dcd)(const uint8_t* dcd);
/** Execute an authentication script.
* @ingroup run_csf
*
* @par Purpose
*
* This function authenticates SW images and configures the IC based upon
* a @ref csf. It is intended for use by post-ROM boot stage components,
* via the @ref rvt. This function may be invoked as often as required
* for each boot stage.
*
* @ifrom It is also available for use by the boot ROM via hab_rvt.run_csf,
* although it is anticipated that the boot ROM will mostly call this
* function indirectly via hab_rvt.authenticate_image(). @endrom
*
* @par Operation
*
* This function performs the following operations:
* - Checks the @ref hdr for compatibility and consistency
* - Makes an internal copy of the @ref csf
* - Executes the commands in sequence from the internal copy of the @ref
* csf
*
* The internal copy of the @ref csf is authenticated by an explicit
* command in the sequence. Prior to authentication, a limited set of
* commands is available to:
* - Install a Super-Root key (unless previously installed)
* - Install a CSF key (unless previously installed)
* - Specify any variable configuration items
* - Authenticate the CSF
*
* Subsequent to CSF authentication, the full set of commands is available.
*
* If any failure occurs, an audit event is logged and all remaining
* operations are abandoned.
*
* @param[in] csf Address of the @ref csf.
*
* @param[in] cid Caller ID, used to identify which SW issued this call.
*
* @remark Caller ID may be bound to signatures verified using keys
* installed with #HAB_CMD_INS_KEY_CID flag. See @ref cmd_ins_key and @ref
* bnd_obj for details.
*
* @warning It is the responsibility of the caller to ensure that the @a
* csf parameter points to a valid memory location.
*
* @warning Each invocation of hab_rvt.run_csf() must occur between a pair
* of hab_rvt.entry() and hab_rvt.exit() calls, although multiple
* hab_rvt.run_csf() calls (and other HAB calls) may be made in one
* bracket. This constraint applies whether hab_rvt.run_csf() is
* successful or not: a subsequent call to hab_rvt.exit() is required
* prior to launching the authenticated image or switching to another boot
* target.
*
* @post Many commands may cause side-effects. See the @ref csf
* documentation. In particular, note that keys installed by the @ref csf
* remain available for use in subsequent operations.
*
* @post If a failure or warning occurs within a command handler, an audit
* event is logged with the offending command, copied from the CSF. The
* status and reason logged are described in the relevant command
* documentation.
*
* @post For other failures or warning, the status logged is:
* - #HAB_WARNING, with further reasons:
* - #HAB_UNS_COMMAND: unsupported command encountered, where CSF
* version and HAB library version differ
* - #HAB_FAILURE, with further reasons:
* - #HAB_INV_ADDRESS: NULL @a csf parameter
* - #HAB_INV_CALL: hab_rvt.entry() not run successfully prior to call
* - #HAB_INV_COMMAND: command not allowed prior to CSF authentication
* - #HAB_UNS_COMMAND: unrecognised command encountered, where CSF
* version and HAB library version match
* - #HAB_INV_CSF: CSF not authenticated
* - #HAB_INV_CSF: CSF malformed or too large
* - #HAB_INV_CSF: CSF version number is less than HAB library version
*
* @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED,
* although unsuccessful operations will still generate audit log events,
*
* @retval #HAB_SUCCESS on other ICs if all commands completed
* without failure (even if warnings were generated),
*
* @retval #HAB_FAILURE otherwise.
*/
hab_status_t (*run_csf)(const uint8_t* csf,
uint8_t cid);
/** Test an assertion against the audit log.
* @ingroup assert
*
* @par Purpose
*
* This function allows the audit log to be interrogated. It is intended
* for use by post-ROM boot stage components, via the @ref rvt, to
* determine the state of authentication operations. This function may be
* invoked as often as required for each boot stage.
*
* @ifrom It is also available for use by the boot ROM, both directly via
* hab_rvt.assert() and indirectly via hab_rvt.authenticate_image().
* @endrom
*
* @par Operation
*
* This function checks the required assertion as detailed below.
*
* @param[in] type Assertion type.
*
* @param[in] data Assertion data.
*
* @param[in] count Data size or count.
*
* @par Memory block authentication:
* For #HAB_ASSERT_BLOCK assertion type, hab_rvt.assert() checks that the
* given memory block has been authenticated after running a CSF. The
* parameters are interpreted as follows:
*
* @par
* - @a data: memory block starting address
* - @a count: memory block size (in bytes)
*
* @par
*
* A simple interpretation of "memory block has been authenticated" is
* taken, such that the given block must lie wholly within a single
* contiguous block authenticated while running a CSF. A given memory
* block covered by the union of several neighboring or overlapping
* authenticated blocks could fail the test with this interpretation, but
* it is assumed that such cases will not arise in practice.
*
* @post If the assertion fails, an audit event is logged with status
* #HAB_FAILURE and reason #HAB_INV_ASSERTION, together with the call
* parameters. See the @ref evt record documentation for details.
*
* @post For successful commands, no audit event is logged.
*
* @retval #HAB_SUCCESS on an IC not configured as #HAB_CFG_CLOSED,
* although unsuccessful operations will still generate audit log events,
*
* @retval #HAB_SUCCESS on other ICs if the assertion is confirmed
*
* @retval #HAB_FAILURE otherwise
*/
hab_status_t (*assert)(hab_assertion_t type,
const void* data,
uint32_t count);
/** Report an event from the audit log.
* @ingroup event
*
* @par Purpose
*
* This function allows the audit log to be interrogated. It is intended
* for use by post-ROM boot stage components, via the @ref rvt, to
* determine the state of authentication operations. This function may
* be called outside an hab_rvt.entry() / hab_rvt.exit() pair.
*
* @ifrom It is also available for use by the boot ROM, where it may be
* used to report boot failures as part of a tethered boot
* protocol. @endrom
*
* @par Operation
*
* This function performs the following operations:
* - Scans the audit log for a matching event
* - Copies the required details to the output parameters (if found)
*
* @param[in] status Status level of required event.
*
* @param[in] index Index of required event at given status level.
*
* @param[out] event @ref evt record.
*
* @param[in,out] bytes Size of @a event buffer on entry, size of event
* record on exit.
*
* @remark Use @a status = #HAB_STS_ANY to match any logged event,
* regardless of the status value logged.
*
* @remark Use @a index = 0 to return the first matching event, @a index =
* 1 to return the second matching event, and so on.
*
* @remark The data logged with each event is context-dependent. Refer to
* @ref evt record documentation.
*
* @warning Parameter @a bytes may not be NULL.
*
* @warning If the @a event buffer is a NULL pointer or too small to fit
* the event record, the required size is written to @a bytes, but no
* part of the event record is copied to the output buffer.
*
* @retval #HAB_SUCCESS if the required event is found, and the event
* record is copied to the output buffer.
*
* @retval #HAB_SUCCESS if the required event is found and @a event buffer
* passed is a NULL pointer.
*
* @retval #HAB_FAILURE otherwise
*/
hab_status_t (*report_event)(hab_status_t status,
uint32_t index,
uint8_t* event,
size_t* bytes);
/** Report security status.
* @ingroup status
*
* @par Purpose
*
* This function reports the security configuration and state of the IC as
* well as searching the audit log to determine the status of the boot
* process. It is intended for use by post-ROM boot stage components, via
* the @ref rvt. This function may be called outside an
* hab_rvt.entry() / hab_rvt.exit() pair.
*
* @ifrom It is also available for use by the boot ROM, and should be used
* rather than the HAL function hab_hal_read_sec_cfg(). @endrom
*
* @par Operation
*
* This function reads the fuses which indicate the security
* configuration. The fusemap varies by IC, and should be taken from the
* @ref ref_rug. It also uses the @ref shw state machine, if present and
* enabled, to report on the security state.
*
* @param[out] config Security configuration, NULL if not required
*
* @param[out] state Security state, NULL if not required
*
* @remark If no @ref shw state machine is present and enabled, the state
* #HAB_STATE_NONE will be output.
*
* @retval #HAB_SUCCESS if no warning or failure audit events have been
* logged.
*
* @retval #HAB_WARNING otherwise, if only warning events have been logged.
*
* @retval #HAB_FAILURE otherwise
*/
hab_status_t (*report_status)(hab_config_t* config, hab_state_t* state);
/** Enter failsafe boot mode.
* @ingroup safe
*
* @par Purpose
*
* This function provides a safe path when image authentication has failed
* and all possible boot paths have been exhausted. It is intended for
* use by post-ROM boot stage components, via the @ref rvt.
*
* @ifrom It is also available for use by the boot ROM via
* hab_rvt.failsafe(). @endrom
*
* @par Operation
*
* The precise details of this function vary by IC and core, and should be
* taken from @ref ref_rug.
*
* @warning This function does not return.
*
* @remark Since this function does not return, it implicitly performs the
* functionality of hab_rvt.exit() in order to ensure an appropriate
* configuration of the @ref shw plugins.
*
* @remark Two typical implementations are:
* - a low-level provisioning protocol in which an image is downloaded to
* RAM from an external host, authenticated and launched. The downloaded
* image may communicate with tools on the external host to report the
* reasons for boot failure, and may re-provision the end-product with
* authentic boot images.
* - a failsafe boot mode which does not allow execution to leave the ROM
* until the IC is reset.
*/
void (*failsafe)(void);
};
/** @ref rvt type
* @ingroup rvt
*/
typedef struct hab_rvt hab_rvt_t;
/*---------------------------------------------------------------------------*/
/** @ref ivt structure
* @ingroup ivt
*
* @par Format
*
* An @ref ivt consists of a @ref hdr followed by a list of addresses as
* described further below.
*
* @warning The @a entry address may not be NULL.
*
* @warning On an IC not configured as #HAB_CFG_CLOSED, the
* @a csf address may be NULL. If it is not NULL, the @ref csf will be
* processed, but any failures should be non-fatal.
*
* @warning On an IC configured as #HAB_CFG_CLOSED, the @a
* csf address may not be NULL, and @ref csf failures are typically fatal.
*
* @remark The Boot Data located using the @a boot_data field is interpreted
* by the HAB caller in a boot-mode specific manner. This may be used by the
* boot ROM as to determine the load address and boot device configuration for
* images loaded from block devices (see @ref ref_rug for details).
*
* @remark All addresses given in the IVT, including the Boot Data (if
* present) are those for the final load location.
*
* @anchor ila
*
* @par Initial load addresses
*
* The @a self field is used to calculate addresses in boot modes where an
* initial portion of the image is loaded to an initial location. In such
* cases, the IVT, Boot Data (if present) and DCD (if present) are used in
* configuring the IC and loading the full image to its final location. Only
* the IVT, Boot Data (if present) and DCD (if present) are required to be
* within the initial image portion.
*
* The method for calculating an initial load address for the DCD is
* illustrated in the following C fragment. Similar calculations apply to
* other fields.
*
@verbatim
hab_ivt_t* ivt_initial = <initial IVT load address>;
const void* dcd_initial = ivt_initial->dcd;
if (ivt_initial->dcd != NULL)
dcd_initial = (const uint8_t*)ivt_initial
+ (ivt_initial->dcd - ivt_initial->self)
@endverbatim
*/
struct hab_ivt {
/** @ref hdr with tag #HAB_TAG_IVT, length and HAB version fields
* (see @ref data)
*/
hab_hdr_t hdr;
/** Absolute address of the first instruction to execute from the
* image
*/
hab_image_entry_f entry;
/** Reserved in this version of HAB: should be NULL. */
const void* reserved1;
/** Absolute address of the image DCD: may be NULL. */
const void* dcd;
/** Absolute address of the Boot Data: may be NULL, but not interpreted
* any further by HAB
*/
const void* boot_data;
/** Absolute address of the IVT.*/
const void* self;
/** Absolute address of the image CSF.*/
const void* csf;
/** Reserved in this version of HAB: should be zero. */
uint32_t reserved2;
};
/** @ref ivt type
* @ingroup ivt
*/
typedef struct hab_ivt hab_ivt_t;
/*===========================================================================
FUNCTION PROTOTYPES
=============================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* HAB_DEFINES_H */