/* * 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 /* for integer types */ #include /* for bool type */ #include /* 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 = ; 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 */