Commit dd058bca4a30fff27bcd643575b2935c706d021b

Authored by Breno Lima
Committed by Ye Li
1 parent 5cc3fbe211

MLK-21174 mx7ulp: hab: Add hab_status command for HABv4 M4 boot

When booting in low power or dual boot modes the M4 binary is
authenticated by the M4 ROM code.

Add an option in hab_status command so users can retrieve M4 HAB
failure and warning events.

=> hab_status m4

   Secure boot disabled

   HAB Configuration: 0xf0, HAB State: 0x66
   No HAB Events Found!

Add command documentation in mx6_mx7_secure_boot.txt guide.

As HAB M4 API cannot be called from A7 core the code is parsing
the M4 HAB persistent memory region. The HAB persistent memory
stores HAB events, public keys and others HAB related information.

The HAB persistent memory region addresses and sizes can be found
in AN12263 "HABv4 RVT Guidelines and Recommendations".

Reviewed-by: Utkarsh Gupta <utkarsh.gupta@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Breno Lima <breno.lima@nxp.com>
(cherry picked from commit 0efff16579fabcf57acb9c8857afac8fb58de355)

Showing 3 changed files with 139 additions and 0 deletions Inline Diff

arch/arm/include/asm/mach-imx/hab.h
1 /* 1 /*
2 * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. All Rights Reserved. 2 * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. All Rights Reserved.
3 * 3 *
4 * SPDX-License-Identifier: GPL-2.0+ 4 * SPDX-License-Identifier: GPL-2.0+
5 * 5 *
6 */ 6 */
7 7
8 #ifndef __SECURE_MX6Q_H__ 8 #ifndef __SECURE_MX6Q_H__
9 #define __SECURE_MX6Q_H__ 9 #define __SECURE_MX6Q_H__
10 10
11 #include <linux/types.h> 11 #include <linux/types.h>
12 #include <linux/compiler.h> 12 #include <linux/compiler.h>
13 13
14 /* 14 /*
15 * IVT header definitions 15 * IVT header definitions
16 * Security Reference Manual for i.MX 7Dual and 7Solo Applications Processors, 16 * Security Reference Manual for i.MX 7Dual and 7Solo Applications Processors,
17 * Rev. 0, 03/2017 17 * Rev. 0, 03/2017
18 * Section : 6.7.1.1 18 * Section : 6.7.1.1
19 */ 19 */
20 #define IVT_HEADER_MAGIC 0xD1 20 #define IVT_HEADER_MAGIC 0xD1
21 #define IVT_TOTAL_LENGTH 0x20 21 #define IVT_TOTAL_LENGTH 0x20
22 #define IVT_HEADER_V1 0x40 22 #define IVT_HEADER_V1 0x40
23 #define IVT_HEADER_V2 0x41 23 #define IVT_HEADER_V2 0x41
24 24
25 struct __packed ivt_header { 25 struct __packed ivt_header {
26 uint8_t magic; 26 uint8_t magic;
27 uint16_t length; 27 uint16_t length;
28 uint8_t version; 28 uint8_t version;
29 }; 29 };
30 30
31 struct ivt { 31 struct ivt {
32 struct ivt_header hdr; /* IVT header above */ 32 struct ivt_header hdr; /* IVT header above */
33 uint32_t entry; /* Absolute address of first instruction */ 33 uint32_t entry; /* Absolute address of first instruction */
34 uint32_t reserved1; /* Reserved should be zero */ 34 uint32_t reserved1; /* Reserved should be zero */
35 uint32_t dcd; /* Absolute address of the image DCD */ 35 uint32_t dcd; /* Absolute address of the image DCD */
36 uint32_t boot; /* Absolute address of the boot data */ 36 uint32_t boot; /* Absolute address of the boot data */
37 uint32_t self; /* Absolute address of the IVT */ 37 uint32_t self; /* Absolute address of the IVT */
38 uint32_t csf; /* Absolute address of the CSF */ 38 uint32_t csf; /* Absolute address of the CSF */
39 uint32_t reserved2; /* Reserved should be zero */ 39 uint32_t reserved2; /* Reserved should be zero */
40 }; 40 };
41 41
42 struct __packed hab_hdr { 42 struct __packed hab_hdr {
43 u8 tag; /* Tag field */ 43 u8 tag; /* Tag field */
44 u8 len[2]; /* Length field in bytes (big-endian) */ 44 u8 len[2]; /* Length field in bytes (big-endian) */
45 u8 par; /* Parameters field */ 45 u8 par; /* Parameters field */
46 }; 46 };
47 47
48 /* Default event structure */
49 struct __packed evt_def {
50 struct hab_hdr hdr; /* Header */
51 uint32_t sts; /* Status */
52 uint32_t ctx; /* Default context */
53 uint8_t *data; /* Default data location */
54 size_t bytes; /* Size of default data */
55 };
56
48 /* -------- start of HAB API updates ------------*/ 57 /* -------- start of HAB API updates ------------*/
49 /* The following are taken from HAB4 SIS */ 58 /* The following are taken from HAB4 SIS */
50 59
51 /* Status definitions */ 60 /* Status definitions */
52 enum hab_status { 61 enum hab_status {
53 HAB_STS_ANY = 0x00, 62 HAB_STS_ANY = 0x00,
54 HAB_FAILURE = 0x33, 63 HAB_FAILURE = 0x33,
55 HAB_WARNING = 0x69, 64 HAB_WARNING = 0x69,
56 HAB_SUCCESS = 0xf0 65 HAB_SUCCESS = 0xf0
57 }; 66 };
58 67
59 /* Security Configuration definitions */ 68 /* Security Configuration definitions */
60 enum hab_config { 69 enum hab_config {
61 HAB_CFG_RETURN = 0x33, /* < Field Return IC */ 70 HAB_CFG_RETURN = 0x33, /* < Field Return IC */
62 HAB_CFG_OPEN = 0xf0, /* < Non-secure IC */ 71 HAB_CFG_OPEN = 0xf0, /* < Non-secure IC */
63 HAB_CFG_CLOSED = 0xcc /* < Secure IC */ 72 HAB_CFG_CLOSED = 0xcc /* < Secure IC */
64 }; 73 };
65 74
66 /* State definitions */ 75 /* State definitions */
67 enum hab_state { 76 enum hab_state {
68 HAB_STATE_INITIAL = 0x33, /* Initialising state (transitory) */ 77 HAB_STATE_INITIAL = 0x33, /* Initialising state (transitory) */
69 HAB_STATE_CHECK = 0x55, /* Check state (non-secure) */ 78 HAB_STATE_CHECK = 0x55, /* Check state (non-secure) */
70 HAB_STATE_NONSECURE = 0x66, /* Non-secure state */ 79 HAB_STATE_NONSECURE = 0x66, /* Non-secure state */
71 HAB_STATE_TRUSTED = 0x99, /* Trusted state */ 80 HAB_STATE_TRUSTED = 0x99, /* Trusted state */
72 HAB_STATE_SECURE = 0xaa, /* Secure state */ 81 HAB_STATE_SECURE = 0xaa, /* Secure state */
73 HAB_STATE_FAIL_SOFT = 0xcc, /* Soft fail state */ 82 HAB_STATE_FAIL_SOFT = 0xcc, /* Soft fail state */
74 HAB_STATE_FAIL_HARD = 0xff, /* Hard fail state (terminal) */ 83 HAB_STATE_FAIL_HARD = 0xff, /* Hard fail state (terminal) */
75 HAB_STATE_NONE = 0xf0, /* No security state machine */ 84 HAB_STATE_NONE = 0xf0, /* No security state machine */
76 HAB_STATE_MAX 85 HAB_STATE_MAX
77 }; 86 };
78 87
79 enum hab_reason { 88 enum hab_reason {
80 HAB_RSN_ANY = 0x00, /* Match any reason */ 89 HAB_RSN_ANY = 0x00, /* Match any reason */
81 HAB_ENG_FAIL = 0x30, /* Engine failure */ 90 HAB_ENG_FAIL = 0x30, /* Engine failure */
82 HAB_INV_ADDRESS = 0x22, /* Invalid address: access denied */ 91 HAB_INV_ADDRESS = 0x22, /* Invalid address: access denied */
83 HAB_INV_ASSERTION = 0x0c, /* Invalid assertion */ 92 HAB_INV_ASSERTION = 0x0c, /* Invalid assertion */
84 HAB_INV_CALL = 0x28, /* Function called out of sequence */ 93 HAB_INV_CALL = 0x28, /* Function called out of sequence */
85 HAB_INV_CERTIFICATE = 0x21, /* Invalid certificate */ 94 HAB_INV_CERTIFICATE = 0x21, /* Invalid certificate */
86 HAB_INV_COMMAND = 0x06, /* Invalid command: command malformed */ 95 HAB_INV_COMMAND = 0x06, /* Invalid command: command malformed */
87 HAB_INV_CSF = 0x11, /* Invalid csf */ 96 HAB_INV_CSF = 0x11, /* Invalid csf */
88 HAB_INV_DCD = 0x27, /* Invalid dcd */ 97 HAB_INV_DCD = 0x27, /* Invalid dcd */
89 HAB_INV_INDEX = 0x0f, /* Invalid index: access denied */ 98 HAB_INV_INDEX = 0x0f, /* Invalid index: access denied */
90 HAB_INV_IVT = 0x05, /* Invalid ivt */ 99 HAB_INV_IVT = 0x05, /* Invalid ivt */
91 HAB_INV_KEY = 0x1d, /* Invalid key */ 100 HAB_INV_KEY = 0x1d, /* Invalid key */
92 HAB_INV_RETURN = 0x1e, /* Failed callback function */ 101 HAB_INV_RETURN = 0x1e, /* Failed callback function */
93 HAB_INV_SIGNATURE = 0x18, /* Invalid signature */ 102 HAB_INV_SIGNATURE = 0x18, /* Invalid signature */
94 HAB_INV_SIZE = 0x17, /* Invalid data size */ 103 HAB_INV_SIZE = 0x17, /* Invalid data size */
95 HAB_MEM_FAIL = 0x2e, /* Memory failure */ 104 HAB_MEM_FAIL = 0x2e, /* Memory failure */
96 HAB_OVR_COUNT = 0x2b, /* Expired poll count */ 105 HAB_OVR_COUNT = 0x2b, /* Expired poll count */
97 HAB_OVR_STORAGE = 0x2d, /* Exhausted storage region */ 106 HAB_OVR_STORAGE = 0x2d, /* Exhausted storage region */
98 HAB_UNS_ALGORITHM = 0x12, /* Unsupported algorithm */ 107 HAB_UNS_ALGORITHM = 0x12, /* Unsupported algorithm */
99 HAB_UNS_COMMAND = 0x03, /* Unsupported command */ 108 HAB_UNS_COMMAND = 0x03, /* Unsupported command */
100 HAB_UNS_ENGINE = 0x0a, /* Unsupported engine */ 109 HAB_UNS_ENGINE = 0x0a, /* Unsupported engine */
101 HAB_UNS_ITEM = 0x24, /* Unsupported configuration item */ 110 HAB_UNS_ITEM = 0x24, /* Unsupported configuration item */
102 HAB_UNS_KEY = 0x1b, /* Unsupported key type/parameters */ 111 HAB_UNS_KEY = 0x1b, /* Unsupported key type/parameters */
103 HAB_UNS_PROTOCOL = 0x14, /* Unsupported protocol */ 112 HAB_UNS_PROTOCOL = 0x14, /* Unsupported protocol */
104 HAB_UNS_STATE = 0x09, /* Unsuitable state */ 113 HAB_UNS_STATE = 0x09, /* Unsuitable state */
105 HAB_RSN_MAX 114 HAB_RSN_MAX
106 }; 115 };
107 116
108 enum hab_context { 117 enum hab_context {
109 HAB_CTX_ANY = 0x00, /* Match any context */ 118 HAB_CTX_ANY = 0x00, /* Match any context */
110 HAB_CTX_FAB = 0xff, /* Event logged in hab_fab_test() */ 119 HAB_CTX_FAB = 0xff, /* Event logged in hab_fab_test() */
111 HAB_CTX_ENTRY = 0xe1, /* Event logged in hab_rvt.entry() */ 120 HAB_CTX_ENTRY = 0xe1, /* Event logged in hab_rvt.entry() */
112 HAB_CTX_TARGET = 0x33, /* Event logged in hab_rvt.check_target() */ 121 HAB_CTX_TARGET = 0x33, /* Event logged in hab_rvt.check_target() */
113 HAB_CTX_AUTHENTICATE = 0x0a,/* Logged in hab_rvt.authenticate_image() */ 122 HAB_CTX_AUTHENTICATE = 0x0a,/* Logged in hab_rvt.authenticate_image() */
114 HAB_CTX_DCD = 0xdd, /* Event logged in hab_rvt.run_dcd() */ 123 HAB_CTX_DCD = 0xdd, /* Event logged in hab_rvt.run_dcd() */
115 HAB_CTX_CSF = 0xcf, /* Event logged in hab_rvt.run_csf() */ 124 HAB_CTX_CSF = 0xcf, /* Event logged in hab_rvt.run_csf() */
116 HAB_CTX_COMMAND = 0xc0, /* Event logged executing csf/dcd command */ 125 HAB_CTX_COMMAND = 0xc0, /* Event logged executing csf/dcd command */
117 HAB_CTX_AUT_DAT = 0xdb, /* Authenticated data block */ 126 HAB_CTX_AUT_DAT = 0xdb, /* Authenticated data block */
118 HAB_CTX_ASSERT = 0xa0, /* Event logged in hab_rvt.assert() */ 127 HAB_CTX_ASSERT = 0xa0, /* Event logged in hab_rvt.assert() */
119 HAB_CTX_EXIT = 0xee, /* Event logged in hab_rvt.exit() */ 128 HAB_CTX_EXIT = 0xee, /* Event logged in hab_rvt.exit() */
120 HAB_CTX_MAX 129 HAB_CTX_MAX
121 }; 130 };
122 131
123 enum hab_target { 132 enum hab_target {
124 HAB_TGT_MEMORY = 0x0f, 133 HAB_TGT_MEMORY = 0x0f,
125 HAB_TGT_PERIPHERAL = 0xf0, 134 HAB_TGT_PERIPHERAL = 0xf0,
126 HAB_TGT_ANY = 0x55, 135 HAB_TGT_ANY = 0x55,
127 }; 136 };
128 137
129 struct imx_sec_config_fuse_t { 138 struct imx_sec_config_fuse_t {
130 int bank; 139 int bank;
131 int word; 140 int word;
132 }; 141 };
133 142
134 #if defined(CONFIG_SECURE_BOOT) 143 #if defined(CONFIG_SECURE_BOOT)
135 extern struct imx_sec_config_fuse_t const imx_sec_config_fuse; 144 extern struct imx_sec_config_fuse_t const imx_sec_config_fuse;
136 #endif 145 #endif
137 146
138 /*Function prototype description*/ 147 /*Function prototype description*/
139 typedef enum hab_status hab_rvt_report_event_t(enum hab_status, uint32_t, 148 typedef enum hab_status hab_rvt_report_event_t(enum hab_status, uint32_t,
140 uint8_t* , size_t*); 149 uint8_t* , size_t*);
141 typedef enum hab_status hab_rvt_report_status_t(enum hab_config *, 150 typedef enum hab_status hab_rvt_report_status_t(enum hab_config *,
142 enum hab_state *); 151 enum hab_state *);
143 typedef enum hab_status hab_loader_callback_f_t(void**, size_t*, const void*); 152 typedef enum hab_status hab_loader_callback_f_t(void**, size_t*, const void*);
144 typedef enum hab_status hab_rvt_entry_t(void); 153 typedef enum hab_status hab_rvt_entry_t(void);
145 typedef enum hab_status hab_rvt_exit_t(void); 154 typedef enum hab_status hab_rvt_exit_t(void);
146 typedef void *hab_rvt_authenticate_image_t(uint8_t, ptrdiff_t, 155 typedef void *hab_rvt_authenticate_image_t(uint8_t, ptrdiff_t,
147 void **, size_t *, hab_loader_callback_f_t); 156 void **, size_t *, hab_loader_callback_f_t);
148 typedef enum hab_status hab_rvt_check_target_t(enum hab_target, const void *, 157 typedef enum hab_status hab_rvt_check_target_t(enum hab_target, const void *,
149 size_t); 158 size_t);
150 typedef void hab_rvt_failsafe_t(void); 159 typedef void hab_rvt_failsafe_t(void);
151 typedef void hapi_clock_init_t(void); 160 typedef void hapi_clock_init_t(void);
152 161
153 #define HAB_ENG_ANY 0x00 /* Select first compatible engine */ 162 #define HAB_ENG_ANY 0x00 /* Select first compatible engine */
154 #define HAB_ENG_SCC 0x03 /* Security controller */ 163 #define HAB_ENG_SCC 0x03 /* Security controller */
155 #define HAB_ENG_RTIC 0x05 /* Run-time integrity checker */ 164 #define HAB_ENG_RTIC 0x05 /* Run-time integrity checker */
156 #define HAB_ENG_SAHARA 0x06 /* Crypto accelerator */ 165 #define HAB_ENG_SAHARA 0x06 /* Crypto accelerator */
157 #define HAB_ENG_CSU 0x0a /* Central Security Unit */ 166 #define HAB_ENG_CSU 0x0a /* Central Security Unit */
158 #define HAB_ENG_SRTC 0x0c /* Secure clock */ 167 #define HAB_ENG_SRTC 0x0c /* Secure clock */
159 #define HAB_ENG_DCP 0x1b /* Data Co-Processor */ 168 #define HAB_ENG_DCP 0x1b /* Data Co-Processor */
160 #define HAB_ENG_CAAM 0x1d /* CAAM */ 169 #define HAB_ENG_CAAM 0x1d /* CAAM */
161 #define HAB_ENG_SNVS 0x1e /* Secure Non-Volatile Storage */ 170 #define HAB_ENG_SNVS 0x1e /* Secure Non-Volatile Storage */
162 #define HAB_ENG_OCOTP 0x21 /* Fuse controller */ 171 #define HAB_ENG_OCOTP 0x21 /* Fuse controller */
163 #define HAB_ENG_DTCP 0x22 /* DTCP co-processor */ 172 #define HAB_ENG_DTCP 0x22 /* DTCP co-processor */
164 #define HAB_ENG_ROM 0x36 /* Protected ROM area */ 173 #define HAB_ENG_ROM 0x36 /* Protected ROM area */
165 #define HAB_ENG_HDCP 0x24 /* HDCP co-processor */ 174 #define HAB_ENG_HDCP 0x24 /* HDCP co-processor */
166 #define HAB_ENG_RTL 0x77 /* RTL simulation engine */ 175 #define HAB_ENG_RTL 0x77 /* RTL simulation engine */
167 #define HAB_ENG_SW 0xff /* Software engine */ 176 #define HAB_ENG_SW 0xff /* Software engine */
168 177
169 #ifdef CONFIG_ARM64 178 #ifdef CONFIG_ARM64
170 #ifdef CONFIG_IMX8MQ 179 #ifdef CONFIG_IMX8MQ
171 #define HAB_RVT_BASE 0x00000880 180 #define HAB_RVT_BASE 0x00000880
172 #else 181 #else
173 #define HAB_RVT_BASE 0x00000900 182 #define HAB_RVT_BASE 0x00000900
174 #endif 183 #endif
175 184
176 #define HAB_RVT_ENTRY (*(ulong *)(HAB_RVT_BASE + 0x08)) 185 #define HAB_RVT_ENTRY (*(ulong *)(HAB_RVT_BASE + 0x08))
177 #define HAB_RVT_EXIT (*(ulong *)(HAB_RVT_BASE + 0x10)) 186 #define HAB_RVT_EXIT (*(ulong *)(HAB_RVT_BASE + 0x10))
178 #define HAB_RVT_CHECK_TARGET (*(ulong *)(HAB_RVT_BASE + 0x18)) 187 #define HAB_RVT_CHECK_TARGET (*(ulong *)(HAB_RVT_BASE + 0x18))
179 #define HAB_RVT_AUTHENTICATE_IMAGE (*(ulong *)(HAB_RVT_BASE + 0x20)) 188 #define HAB_RVT_AUTHENTICATE_IMAGE (*(ulong *)(HAB_RVT_BASE + 0x20))
180 #define HAB_RVT_REPORT_EVENT (*(ulong *)(HAB_RVT_BASE + 0x40)) 189 #define HAB_RVT_REPORT_EVENT (*(ulong *)(HAB_RVT_BASE + 0x40))
181 #define HAB_RVT_REPORT_STATUS (*(ulong *)(HAB_RVT_BASE + 0x48)) 190 #define HAB_RVT_REPORT_STATUS (*(ulong *)(HAB_RVT_BASE + 0x48))
182 #define HAB_RVT_FAILSAFE (*(ulong *)(HAB_RVT_BASE + 0x50)) 191 #define HAB_RVT_FAILSAFE (*(ulong *)(HAB_RVT_BASE + 0x50))
183 #else 192 #else
184 193
185 #ifdef CONFIG_ROM_UNIFIED_SECTIONS 194 #ifdef CONFIG_ROM_UNIFIED_SECTIONS
186 #define HAB_RVT_BASE 0x00000100 195 #define HAB_RVT_BASE 0x00000100
187 #else 196 #else
188 #define HAB_RVT_BASE_NEW 0x00000098 197 #define HAB_RVT_BASE_NEW 0x00000098
189 #define HAB_RVT_BASE_OLD 0x00000094 198 #define HAB_RVT_BASE_OLD 0x00000094
190 #define HAB_RVT_BASE ((is_mx6dqp()) ? \ 199 #define HAB_RVT_BASE ((is_mx6dqp()) ? \
191 HAB_RVT_BASE_NEW : \ 200 HAB_RVT_BASE_NEW : \
192 (is_mx6dq() && (soc_rev() >= CHIP_REV_1_3)) ? \ 201 (is_mx6dq() && (soc_rev() >= CHIP_REV_1_3)) ? \
193 HAB_RVT_BASE_NEW : \ 202 HAB_RVT_BASE_NEW : \
194 (is_mx6sdl() && (soc_rev() >= CHIP_REV_1_2)) ? \ 203 (is_mx6sdl() && (soc_rev() >= CHIP_REV_1_2)) ? \
195 HAB_RVT_BASE_NEW : HAB_RVT_BASE_OLD) 204 HAB_RVT_BASE_NEW : HAB_RVT_BASE_OLD)
196 #endif 205 #endif
197 206
198 #define HAB_RVT_ENTRY (*(uint32_t *)(HAB_RVT_BASE + 0x04)) 207 #define HAB_RVT_ENTRY (*(uint32_t *)(HAB_RVT_BASE + 0x04))
199 #define HAB_RVT_EXIT (*(uint32_t *)(HAB_RVT_BASE + 0x08)) 208 #define HAB_RVT_EXIT (*(uint32_t *)(HAB_RVT_BASE + 0x08))
200 #define HAB_RVT_CHECK_TARGET (*(uint32_t *)(HAB_RVT_BASE + 0x0C)) 209 #define HAB_RVT_CHECK_TARGET (*(uint32_t *)(HAB_RVT_BASE + 0x0C))
201 #define HAB_RVT_AUTHENTICATE_IMAGE (*(uint32_t *)(HAB_RVT_BASE + 0x10)) 210 #define HAB_RVT_AUTHENTICATE_IMAGE (*(uint32_t *)(HAB_RVT_BASE + 0x10))
202 #define HAB_RVT_REPORT_EVENT (*(uint32_t *)(HAB_RVT_BASE + 0x20)) 211 #define HAB_RVT_REPORT_EVENT (*(uint32_t *)(HAB_RVT_BASE + 0x20))
203 #define HAB_RVT_REPORT_STATUS (*(uint32_t *)(HAB_RVT_BASE + 0x24)) 212 #define HAB_RVT_REPORT_STATUS (*(uint32_t *)(HAB_RVT_BASE + 0x24))
204 #define HAB_RVT_FAILSAFE (*(uint32_t *)(HAB_RVT_BASE + 0x28)) 213 #define HAB_RVT_FAILSAFE (*(uint32_t *)(HAB_RVT_BASE + 0x28))
205 214
206 #endif /*CONFIG_ARM64*/ 215 #endif /*CONFIG_ARM64*/
207 216
208 #define HAB_CID_ROM 0 /**< ROM Caller ID */ 217 #define HAB_CID_ROM 0 /**< ROM Caller ID */
209 #define HAB_CID_UBOOT 1 /**< UBOOT Caller ID*/ 218 #define HAB_CID_UBOOT 1 /**< UBOOT Caller ID*/
210 219
211 #define HAB_CMD_HDR 0xD4 /* CSF Header */ 220 #define HAB_CMD_HDR 0xD4 /* CSF Header */
212 #define HAB_CMD_WRT_DAT 0xCC /* Write Data command tag */ 221 #define HAB_CMD_WRT_DAT 0xCC /* Write Data command tag */
213 #define HAB_CMD_CHK_DAT 0xCF /* Check Data command tag */ 222 #define HAB_CMD_CHK_DAT 0xCF /* Check Data command tag */
214 #define HAB_CMD_SET 0xB1 /* Set command tag */ 223 #define HAB_CMD_SET 0xB1 /* Set command tag */
215 #define HAB_PAR_MID 0x01 /* MID parameter value */ 224 #define HAB_PAR_MID 0x01 /* MID parameter value */
216 225
217 #define IVT_SIZE 0x20 226 #define IVT_SIZE 0x20
218 #define CSF_PAD_SIZE 0x2000 227 #define CSF_PAD_SIZE 0x2000
228
229 #define HAB_TAG_EVT 0xDB
230 #define HAB_TAG_EVT_DEF 0x0C
231
232 #define HAB_MAJ_VER 0x40
233 #define HAB_MAJ_MASK 0xF0
219 234
220 /* ----------- end of HAB API updates ------------*/ 235 /* ----------- end of HAB API updates ------------*/
221 236
222 int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size, 237 int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
223 uint32_t ivt_offset); 238 uint32_t ivt_offset);
224 bool imx_hab_is_enabled(void); 239 bool imx_hab_is_enabled(void);
225 240
226 #endif 241 #endif
227 242
arch/arm/mach-imx/hab.c
1 /* 1 /*
2 * Copyright (C) 2010-2015 Freescale Semiconductor, Inc. 2 * Copyright (C) 2010-2015 Freescale Semiconductor, Inc.
3 * 3 *
4 * SPDX-License-Identifier: GPL-2.0+ 4 * SPDX-License-Identifier: GPL-2.0+
5 */ 5 */
6 6
7 #include <common.h> 7 #include <common.h>
8 #include <config.h> 8 #include <config.h>
9 #include <fuse.h> 9 #include <fuse.h>
10 #include <asm/io.h> 10 #include <asm/io.h>
11 #include <asm/system.h> 11 #include <asm/system.h>
12 #include <asm/arch/clock.h> 12 #include <asm/arch/clock.h>
13 #include <asm/arch/sys_proto.h> 13 #include <asm/arch/sys_proto.h>
14 #include <asm/mach-imx/hab.h> 14 #include <asm/mach-imx/hab.h>
15 15
16 DECLARE_GLOBAL_DATA_PTR; 16 DECLARE_GLOBAL_DATA_PTR;
17 17
18 #define ALIGN_SIZE 0x1000 18 #define ALIGN_SIZE 0x1000
19 #define MX6DQ_PU_IROM_MMU_EN_VAR 0x009024a8 19 #define MX6DQ_PU_IROM_MMU_EN_VAR 0x009024a8
20 #define MX6DLS_PU_IROM_MMU_EN_VAR 0x00901dd0 20 #define MX6DLS_PU_IROM_MMU_EN_VAR 0x00901dd0
21 #define MX6SL_PU_IROM_MMU_EN_VAR 0x00900a18 21 #define MX6SL_PU_IROM_MMU_EN_VAR 0x00900a18
22 #define IS_HAB_ENABLED_BIT \ 22 #define IS_HAB_ENABLED_BIT \
23 (is_soc_type(MXC_SOC_MX7ULP) ? 0x80000000 : \ 23 (is_soc_type(MXC_SOC_MX7ULP) ? 0x80000000 : \
24 ((is_soc_type(MXC_SOC_MX7) || is_soc_type(MXC_SOC_IMX8M))? 0x2000000 : 0x2)) 24 ((is_soc_type(MXC_SOC_MX7) || is_soc_type(MXC_SOC_IMX8M))? 0x2000000 : 0x2))
25 25
26 #ifdef CONFIG_MX7ULP
27 #define HAB_M4_PERSISTENT_START ((soc_rev() >= CHIP_REV_2_0) ? 0x20008040 : \
28 0x20008180)
29 #define HAB_M4_PERSISTENT_BYTES 0xB80
30 #endif
31
26 static int ivt_header_error(const char *err_str, struct ivt_header *ivt_hdr) 32 static int ivt_header_error(const char *err_str, struct ivt_header *ivt_hdr)
27 { 33 {
28 printf("%s magic=0x%x length=0x%02x version=0x%x\n", err_str, 34 printf("%s magic=0x%x length=0x%02x version=0x%x\n", err_str,
29 ivt_hdr->magic, ivt_hdr->length, ivt_hdr->version); 35 ivt_hdr->magic, ivt_hdr->length, ivt_hdr->version);
30 36
31 return 1; 37 return 1;
32 } 38 }
33 39
34 static int verify_ivt_header(struct ivt_header *ivt_hdr) 40 static int verify_ivt_header(struct ivt_header *ivt_hdr)
35 { 41 {
36 int result = 0; 42 int result = 0;
37 43
38 if (ivt_hdr->magic != IVT_HEADER_MAGIC) 44 if (ivt_hdr->magic != IVT_HEADER_MAGIC)
39 result = ivt_header_error("bad magic", ivt_hdr); 45 result = ivt_header_error("bad magic", ivt_hdr);
40 46
41 if (be16_to_cpu(ivt_hdr->length) != IVT_TOTAL_LENGTH) 47 if (be16_to_cpu(ivt_hdr->length) != IVT_TOTAL_LENGTH)
42 result = ivt_header_error("bad length", ivt_hdr); 48 result = ivt_header_error("bad length", ivt_hdr);
43 49
44 if (ivt_hdr->version != IVT_HEADER_V1 && 50 if (ivt_hdr->version != IVT_HEADER_V1 &&
45 ivt_hdr->version != IVT_HEADER_V2) 51 ivt_hdr->version != IVT_HEADER_V2)
46 result = ivt_header_error("bad version", ivt_hdr); 52 result = ivt_header_error("bad version", ivt_hdr);
47 53
48 return result; 54 return result;
49 } 55 }
50 56
51 #ifdef CONFIG_ARM64 57 #ifdef CONFIG_ARM64
52 #define FSL_SIP_HAB 0xC2000007 58 #define FSL_SIP_HAB 0xC2000007
53 #define FSL_SIP_HAB_AUTHENTICATE 0x00 59 #define FSL_SIP_HAB_AUTHENTICATE 0x00
54 #define FSL_SIP_HAB_ENTRY 0x01 60 #define FSL_SIP_HAB_ENTRY 0x01
55 #define FSL_SIP_HAB_EXIT 0x02 61 #define FSL_SIP_HAB_EXIT 0x02
56 #define FSL_SIP_HAB_REPORT_EVENT 0x03 62 #define FSL_SIP_HAB_REPORT_EVENT 0x03
57 #define FSL_SIP_HAB_REPORT_STATUS 0x04 63 #define FSL_SIP_HAB_REPORT_STATUS 0x04
58 #define FSL_SIP_HAB_FAILSAFE 0x05 64 #define FSL_SIP_HAB_FAILSAFE 0x05
59 #define FSL_SIP_HAB_CHECK_TARGET 0x06 65 #define FSL_SIP_HAB_CHECK_TARGET 0x06
60 static volatile gd_t *gd_save; 66 static volatile gd_t *gd_save;
61 #endif 67 #endif
62 68
63 static inline void save_gd(void) 69 static inline void save_gd(void)
64 { 70 {
65 #ifdef CONFIG_ARM64 71 #ifdef CONFIG_ARM64
66 gd_save = gd; 72 gd_save = gd;
67 #endif 73 #endif
68 } 74 }
69 75
70 static inline void restore_gd(void) 76 static inline void restore_gd(void)
71 { 77 {
72 #ifdef CONFIG_ARM64 78 #ifdef CONFIG_ARM64
73 /* 79 /*
74 * Make will already error that reserving x18 is not supported at the 80 * Make will already error that reserving x18 is not supported at the
75 * time of writing, clang: error: unknown argument: '-ffixed-x18' 81 * time of writing, clang: error: unknown argument: '-ffixed-x18'
76 */ 82 */
77 __asm__ volatile("mov x18, %0\n" : : "r" (gd_save)); 83 __asm__ volatile("mov x18, %0\n" : : "r" (gd_save));
78 #endif 84 #endif
79 } 85 }
80 86
81 enum hab_status hab_rvt_report_event(enum hab_status status, uint32_t index, 87 enum hab_status hab_rvt_report_event(enum hab_status status, uint32_t index,
82 uint8_t *event, size_t *bytes) 88 uint8_t *event, size_t *bytes)
83 { 89 {
84 enum hab_status ret; 90 enum hab_status ret;
85 hab_rvt_report_event_t *hab_rvt_report_event_func; 91 hab_rvt_report_event_t *hab_rvt_report_event_func;
86 hab_rvt_report_event_func = (hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT; 92 hab_rvt_report_event_func = (hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT;
87 93
88 #if defined(CONFIG_ARM64) 94 #if defined(CONFIG_ARM64)
89 if (current_el() != 3) { 95 if (current_el() != 3) {
90 /* call sip */ 96 /* call sip */
91 ret = (enum hab_status)call_imx_sip(FSL_SIP_HAB, FSL_SIP_HAB_REPORT_EVENT, (unsigned long)index, 97 ret = (enum hab_status)call_imx_sip(FSL_SIP_HAB, FSL_SIP_HAB_REPORT_EVENT, (unsigned long)index,
92 (unsigned long)event, (unsigned long)bytes); 98 (unsigned long)event, (unsigned long)bytes);
93 return ret; 99 return ret;
94 } 100 }
95 #endif 101 #endif
96 102
97 save_gd(); 103 save_gd();
98 ret = hab_rvt_report_event_func(status, index, event, bytes); 104 ret = hab_rvt_report_event_func(status, index, event, bytes);
99 restore_gd(); 105 restore_gd();
100 106
101 return ret; 107 return ret;
102 108
103 } 109 }
104 110
105 enum hab_status hab_rvt_report_status(enum hab_config *config, 111 enum hab_status hab_rvt_report_status(enum hab_config *config,
106 enum hab_state *state) 112 enum hab_state *state)
107 { 113 {
108 enum hab_status ret; 114 enum hab_status ret;
109 hab_rvt_report_status_t *hab_rvt_report_status_func; 115 hab_rvt_report_status_t *hab_rvt_report_status_func;
110 hab_rvt_report_status_func = (hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS; 116 hab_rvt_report_status_func = (hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS;
111 117
112 #if defined(CONFIG_ARM64) 118 #if defined(CONFIG_ARM64)
113 if (current_el() != 3) { 119 if (current_el() != 3) {
114 /* call sip */ 120 /* call sip */
115 ret = (enum hab_status)call_imx_sip(FSL_SIP_HAB, FSL_SIP_HAB_REPORT_STATUS, 121 ret = (enum hab_status)call_imx_sip(FSL_SIP_HAB, FSL_SIP_HAB_REPORT_STATUS,
116 (unsigned long)config, (unsigned long)state, 0); 122 (unsigned long)config, (unsigned long)state, 0);
117 return ret; 123 return ret;
118 } 124 }
119 #endif 125 #endif
120 126
121 save_gd(); 127 save_gd();
122 ret = hab_rvt_report_status_func(config, state); 128 ret = hab_rvt_report_status_func(config, state);
123 restore_gd(); 129 restore_gd();
124 130
125 return ret; 131 return ret;
126 } 132 }
127 133
128 enum hab_status hab_rvt_entry(void) 134 enum hab_status hab_rvt_entry(void)
129 { 135 {
130 enum hab_status ret; 136 enum hab_status ret;
131 hab_rvt_entry_t *hab_rvt_entry_func; 137 hab_rvt_entry_t *hab_rvt_entry_func;
132 hab_rvt_entry_func = (hab_rvt_entry_t *)HAB_RVT_ENTRY; 138 hab_rvt_entry_func = (hab_rvt_entry_t *)HAB_RVT_ENTRY;
133 139
134 #if defined(CONFIG_ARM64) 140 #if defined(CONFIG_ARM64)
135 if (current_el() != 3) { 141 if (current_el() != 3) {
136 /* call sip */ 142 /* call sip */
137 ret = (enum hab_status)call_imx_sip(FSL_SIP_HAB, FSL_SIP_HAB_ENTRY, 0, 0, 0); 143 ret = (enum hab_status)call_imx_sip(FSL_SIP_HAB, FSL_SIP_HAB_ENTRY, 0, 0, 0);
138 return ret; 144 return ret;
139 } 145 }
140 #endif 146 #endif
141 147
142 save_gd(); 148 save_gd();
143 ret = hab_rvt_entry_func(); 149 ret = hab_rvt_entry_func();
144 restore_gd(); 150 restore_gd();
145 151
146 return ret; 152 return ret;
147 } 153 }
148 154
149 enum hab_status hab_rvt_exit(void) 155 enum hab_status hab_rvt_exit(void)
150 { 156 {
151 enum hab_status ret; 157 enum hab_status ret;
152 hab_rvt_exit_t *hab_rvt_exit_func; 158 hab_rvt_exit_t *hab_rvt_exit_func;
153 hab_rvt_exit_func = (hab_rvt_exit_t *)HAB_RVT_EXIT; 159 hab_rvt_exit_func = (hab_rvt_exit_t *)HAB_RVT_EXIT;
154 160
155 #if defined(CONFIG_ARM64) 161 #if defined(CONFIG_ARM64)
156 if (current_el() != 3) { 162 if (current_el() != 3) {
157 /* call sip */ 163 /* call sip */
158 ret = (enum hab_status)call_imx_sip(FSL_SIP_HAB, FSL_SIP_HAB_EXIT, 0, 0, 0); 164 ret = (enum hab_status)call_imx_sip(FSL_SIP_HAB, FSL_SIP_HAB_EXIT, 0, 0, 0);
159 return ret; 165 return ret;
160 } 166 }
161 #endif 167 #endif
162 168
163 save_gd(); 169 save_gd();
164 ret = hab_rvt_exit_func(); 170 ret = hab_rvt_exit_func();
165 restore_gd(); 171 restore_gd();
166 172
167 return ret; 173 return ret;
168 } 174 }
169 175
170 void hab_rvt_failsafe(void) 176 void hab_rvt_failsafe(void)
171 { 177 {
172 hab_rvt_failsafe_t *hab_rvt_failsafe_func; 178 hab_rvt_failsafe_t *hab_rvt_failsafe_func;
173 hab_rvt_failsafe_func = (hab_rvt_failsafe_t *)HAB_RVT_FAILSAFE; 179 hab_rvt_failsafe_func = (hab_rvt_failsafe_t *)HAB_RVT_FAILSAFE;
174 180
175 #if defined(CONFIG_ARM64) 181 #if defined(CONFIG_ARM64)
176 if (current_el() != 3) { 182 if (current_el() != 3) {
177 /* call sip */ 183 /* call sip */
178 call_imx_sip(FSL_SIP_HAB, FSL_SIP_HAB_FAILSAFE, 0, 0, 0); 184 call_imx_sip(FSL_SIP_HAB, FSL_SIP_HAB_FAILSAFE, 0, 0, 0);
179 return; 185 return;
180 } 186 }
181 #endif 187 #endif
182 188
183 save_gd(); 189 save_gd();
184 hab_rvt_failsafe_func(); 190 hab_rvt_failsafe_func();
185 restore_gd(); 191 restore_gd();
186 } 192 }
187 193
188 enum hab_status hab_rvt_check_target(enum hab_target type, const void *start, 194 enum hab_status hab_rvt_check_target(enum hab_target type, const void *start,
189 size_t bytes) 195 size_t bytes)
190 { 196 {
191 enum hab_status ret; 197 enum hab_status ret;
192 hab_rvt_check_target_t *hab_rvt_check_target_func; 198 hab_rvt_check_target_t *hab_rvt_check_target_func;
193 hab_rvt_check_target_func = (hab_rvt_check_target_t *)HAB_RVT_CHECK_TARGET; 199 hab_rvt_check_target_func = (hab_rvt_check_target_t *)HAB_RVT_CHECK_TARGET;
194 200
195 #if defined(CONFIG_ARM64) 201 #if defined(CONFIG_ARM64)
196 if (current_el() != 3) { 202 if (current_el() != 3) {
197 /* call sip */ 203 /* call sip */
198 ret = (enum hab_status)call_imx_sip(FSL_SIP_HAB, FSL_SIP_HAB_CHECK_TARGET, (unsigned long)type, 204 ret = (enum hab_status)call_imx_sip(FSL_SIP_HAB, FSL_SIP_HAB_CHECK_TARGET, (unsigned long)type,
199 (unsigned long)start, (unsigned long)bytes); 205 (unsigned long)start, (unsigned long)bytes);
200 return ret; 206 return ret;
201 } 207 }
202 #endif 208 #endif
203 209
204 save_gd(); 210 save_gd();
205 ret = hab_rvt_check_target_func(type, start, bytes); 211 ret = hab_rvt_check_target_func(type, start, bytes);
206 restore_gd(); 212 restore_gd();
207 213
208 return ret; 214 return ret;
209 } 215 }
210 216
211 void *hab_rvt_authenticate_image(uint8_t cid, ptrdiff_t ivt_offset, 217 void *hab_rvt_authenticate_image(uint8_t cid, ptrdiff_t ivt_offset,
212 void **start, size_t *bytes, hab_loader_callback_f_t loader) 218 void **start, size_t *bytes, hab_loader_callback_f_t loader)
213 { 219 {
214 void *ret; 220 void *ret;
215 hab_rvt_authenticate_image_t *hab_rvt_authenticate_image_func; 221 hab_rvt_authenticate_image_t *hab_rvt_authenticate_image_func;
216 hab_rvt_authenticate_image_func = (hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE; 222 hab_rvt_authenticate_image_func = (hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE;
217 223
218 #if defined(CONFIG_ARM64) 224 #if defined(CONFIG_ARM64)
219 if (current_el() != 3) { 225 if (current_el() != 3) {
220 /* call sip */ 226 /* call sip */
221 ret = (void *)call_imx_sip(FSL_SIP_HAB, FSL_SIP_HAB_AUTHENTICATE, (unsigned long)ivt_offset, 227 ret = (void *)call_imx_sip(FSL_SIP_HAB, FSL_SIP_HAB_AUTHENTICATE, (unsigned long)ivt_offset,
222 (unsigned long)start, (unsigned long)bytes); 228 (unsigned long)start, (unsigned long)bytes);
223 return ret; 229 return ret;
224 } 230 }
225 #endif 231 #endif
226 232
227 save_gd(); 233 save_gd();
228 ret = hab_rvt_authenticate_image_func(cid, ivt_offset, start, bytes, loader); 234 ret = hab_rvt_authenticate_image_func(cid, ivt_offset, start, bytes, loader);
229 restore_gd(); 235 restore_gd();
230 236
231 return ret; 237 return ret;
232 } 238 }
233 239
234 #if !defined(CONFIG_SPL_BUILD) 240 #if !defined(CONFIG_SPL_BUILD)
235 241
236 #define MAX_RECORD_BYTES (8*1024) /* 4 kbytes */ 242 #define MAX_RECORD_BYTES (8*1024) /* 4 kbytes */
237 243
238 struct record { 244 struct record {
239 uint8_t tag; /* Tag */ 245 uint8_t tag; /* Tag */
240 uint8_t len[2]; /* Length */ 246 uint8_t len[2]; /* Length */
241 uint8_t par; /* Version */ 247 uint8_t par; /* Version */
242 uint8_t contents[MAX_RECORD_BYTES];/* Record Data */ 248 uint8_t contents[MAX_RECORD_BYTES];/* Record Data */
243 bool any_rec_flag; 249 bool any_rec_flag;
244 }; 250 };
245 251
246 static char *rsn_str[] = { 252 static char *rsn_str[] = {
247 "RSN = HAB_RSN_ANY (0x00)\n", 253 "RSN = HAB_RSN_ANY (0x00)\n",
248 "RSN = HAB_ENG_FAIL (0x30)\n", 254 "RSN = HAB_ENG_FAIL (0x30)\n",
249 "RSN = HAB_INV_ADDRESS (0x22)\n", 255 "RSN = HAB_INV_ADDRESS (0x22)\n",
250 "RSN = HAB_INV_ASSERTION (0x0C)\n", 256 "RSN = HAB_INV_ASSERTION (0x0C)\n",
251 "RSN = HAB_INV_CALL (0x28)\n", 257 "RSN = HAB_INV_CALL (0x28)\n",
252 "RSN = HAB_INV_CERTIFICATE (0x21)\n", 258 "RSN = HAB_INV_CERTIFICATE (0x21)\n",
253 "RSN = HAB_INV_COMMAND (0x06)\n", 259 "RSN = HAB_INV_COMMAND (0x06)\n",
254 "RSN = HAB_INV_CSF (0x11)\n", 260 "RSN = HAB_INV_CSF (0x11)\n",
255 "RSN = HAB_INV_DCD (0x27)\n", 261 "RSN = HAB_INV_DCD (0x27)\n",
256 "RSN = HAB_INV_INDEX (0x0F)\n", 262 "RSN = HAB_INV_INDEX (0x0F)\n",
257 "RSN = HAB_INV_IVT (0x05)\n", 263 "RSN = HAB_INV_IVT (0x05)\n",
258 "RSN = HAB_INV_KEY (0x1D)\n", 264 "RSN = HAB_INV_KEY (0x1D)\n",
259 "RSN = HAB_INV_RETURN (0x1E)\n", 265 "RSN = HAB_INV_RETURN (0x1E)\n",
260 "RSN = HAB_INV_SIGNATURE (0x18)\n", 266 "RSN = HAB_INV_SIGNATURE (0x18)\n",
261 "RSN = HAB_INV_SIZE (0x17)\n", 267 "RSN = HAB_INV_SIZE (0x17)\n",
262 "RSN = HAB_MEM_FAIL (0x2E)\n", 268 "RSN = HAB_MEM_FAIL (0x2E)\n",
263 "RSN = HAB_OVR_COUNT (0x2B)\n", 269 "RSN = HAB_OVR_COUNT (0x2B)\n",
264 "RSN = HAB_OVR_STORAGE (0x2D)\n", 270 "RSN = HAB_OVR_STORAGE (0x2D)\n",
265 "RSN = HAB_UNS_ALGORITHM (0x12)\n", 271 "RSN = HAB_UNS_ALGORITHM (0x12)\n",
266 "RSN = HAB_UNS_COMMAND (0x03)\n", 272 "RSN = HAB_UNS_COMMAND (0x03)\n",
267 "RSN = HAB_UNS_ENGINE (0x0A)\n", 273 "RSN = HAB_UNS_ENGINE (0x0A)\n",
268 "RSN = HAB_UNS_ITEM (0x24)\n", 274 "RSN = HAB_UNS_ITEM (0x24)\n",
269 "RSN = HAB_UNS_KEY (0x1B)\n", 275 "RSN = HAB_UNS_KEY (0x1B)\n",
270 "RSN = HAB_UNS_PROTOCOL (0x14)\n", 276 "RSN = HAB_UNS_PROTOCOL (0x14)\n",
271 "RSN = HAB_UNS_STATE (0x09)\n", 277 "RSN = HAB_UNS_STATE (0x09)\n",
272 "RSN = INVALID\n", 278 "RSN = INVALID\n",
273 NULL 279 NULL
274 }; 280 };
275 281
276 static char *sts_str[] = { 282 static char *sts_str[] = {
277 "STS = HAB_SUCCESS (0xF0)\n", 283 "STS = HAB_SUCCESS (0xF0)\n",
278 "STS = HAB_FAILURE (0x33)\n", 284 "STS = HAB_FAILURE (0x33)\n",
279 "STS = HAB_WARNING (0x69)\n", 285 "STS = HAB_WARNING (0x69)\n",
280 "STS = INVALID\n", 286 "STS = INVALID\n",
281 NULL 287 NULL
282 }; 288 };
283 289
284 static char *eng_str[] = { 290 static char *eng_str[] = {
285 "ENG = HAB_ENG_ANY (0x00)\n", 291 "ENG = HAB_ENG_ANY (0x00)\n",
286 "ENG = HAB_ENG_SCC (0x03)\n", 292 "ENG = HAB_ENG_SCC (0x03)\n",
287 "ENG = HAB_ENG_RTIC (0x05)\n", 293 "ENG = HAB_ENG_RTIC (0x05)\n",
288 "ENG = HAB_ENG_SAHARA (0x06)\n", 294 "ENG = HAB_ENG_SAHARA (0x06)\n",
289 "ENG = HAB_ENG_CSU (0x0A)\n", 295 "ENG = HAB_ENG_CSU (0x0A)\n",
290 "ENG = HAB_ENG_SRTC (0x0C)\n", 296 "ENG = HAB_ENG_SRTC (0x0C)\n",
291 "ENG = HAB_ENG_DCP (0x1B)\n", 297 "ENG = HAB_ENG_DCP (0x1B)\n",
292 "ENG = HAB_ENG_CAAM (0x1D)\n", 298 "ENG = HAB_ENG_CAAM (0x1D)\n",
293 "ENG = HAB_ENG_SNVS (0x1E)\n", 299 "ENG = HAB_ENG_SNVS (0x1E)\n",
294 "ENG = HAB_ENG_OCOTP (0x21)\n", 300 "ENG = HAB_ENG_OCOTP (0x21)\n",
295 "ENG = HAB_ENG_DTCP (0x22)\n", 301 "ENG = HAB_ENG_DTCP (0x22)\n",
296 "ENG = HAB_ENG_ROM (0x36)\n", 302 "ENG = HAB_ENG_ROM (0x36)\n",
297 "ENG = HAB_ENG_HDCP (0x24)\n", 303 "ENG = HAB_ENG_HDCP (0x24)\n",
298 "ENG = HAB_ENG_RTL (0x77)\n", 304 "ENG = HAB_ENG_RTL (0x77)\n",
299 "ENG = HAB_ENG_SW (0xFF)\n", 305 "ENG = HAB_ENG_SW (0xFF)\n",
300 "ENG = INVALID\n", 306 "ENG = INVALID\n",
301 NULL 307 NULL
302 }; 308 };
303 309
304 static char *ctx_str[] = { 310 static char *ctx_str[] = {
305 "CTX = HAB_CTX_ANY(0x00)\n", 311 "CTX = HAB_CTX_ANY(0x00)\n",
306 "CTX = HAB_CTX_FAB (0xFF)\n", 312 "CTX = HAB_CTX_FAB (0xFF)\n",
307 "CTX = HAB_CTX_ENTRY (0xE1)\n", 313 "CTX = HAB_CTX_ENTRY (0xE1)\n",
308 "CTX = HAB_CTX_TARGET (0x33)\n", 314 "CTX = HAB_CTX_TARGET (0x33)\n",
309 "CTX = HAB_CTX_AUTHENTICATE (0x0A)\n", 315 "CTX = HAB_CTX_AUTHENTICATE (0x0A)\n",
310 "CTX = HAB_CTX_DCD (0xDD)\n", 316 "CTX = HAB_CTX_DCD (0xDD)\n",
311 "CTX = HAB_CTX_CSF (0xCF)\n", 317 "CTX = HAB_CTX_CSF (0xCF)\n",
312 "CTX = HAB_CTX_COMMAND (0xC0)\n", 318 "CTX = HAB_CTX_COMMAND (0xC0)\n",
313 "CTX = HAB_CTX_AUT_DAT (0xDB)\n", 319 "CTX = HAB_CTX_AUT_DAT (0xDB)\n",
314 "CTX = HAB_CTX_ASSERT (0xA0)\n", 320 "CTX = HAB_CTX_ASSERT (0xA0)\n",
315 "CTX = HAB_CTX_EXIT (0xEE)\n", 321 "CTX = HAB_CTX_EXIT (0xEE)\n",
316 "CTX = INVALID\n", 322 "CTX = INVALID\n",
317 NULL 323 NULL
318 }; 324 };
319 325
320 static uint8_t hab_statuses[5] = { 326 static uint8_t hab_statuses[5] = {
321 HAB_STS_ANY, 327 HAB_STS_ANY,
322 HAB_FAILURE, 328 HAB_FAILURE,
323 HAB_WARNING, 329 HAB_WARNING,
324 HAB_SUCCESS, 330 HAB_SUCCESS,
325 -1 331 -1
326 }; 332 };
327 333
328 static uint8_t hab_reasons[26] = { 334 static uint8_t hab_reasons[26] = {
329 HAB_RSN_ANY, 335 HAB_RSN_ANY,
330 HAB_ENG_FAIL, 336 HAB_ENG_FAIL,
331 HAB_INV_ADDRESS, 337 HAB_INV_ADDRESS,
332 HAB_INV_ASSERTION, 338 HAB_INV_ASSERTION,
333 HAB_INV_CALL, 339 HAB_INV_CALL,
334 HAB_INV_CERTIFICATE, 340 HAB_INV_CERTIFICATE,
335 HAB_INV_COMMAND, 341 HAB_INV_COMMAND,
336 HAB_INV_CSF, 342 HAB_INV_CSF,
337 HAB_INV_DCD, 343 HAB_INV_DCD,
338 HAB_INV_INDEX, 344 HAB_INV_INDEX,
339 HAB_INV_IVT, 345 HAB_INV_IVT,
340 HAB_INV_KEY, 346 HAB_INV_KEY,
341 HAB_INV_RETURN, 347 HAB_INV_RETURN,
342 HAB_INV_SIGNATURE, 348 HAB_INV_SIGNATURE,
343 HAB_INV_SIZE, 349 HAB_INV_SIZE,
344 HAB_MEM_FAIL, 350 HAB_MEM_FAIL,
345 HAB_OVR_COUNT, 351 HAB_OVR_COUNT,
346 HAB_OVR_STORAGE, 352 HAB_OVR_STORAGE,
347 HAB_UNS_ALGORITHM, 353 HAB_UNS_ALGORITHM,
348 HAB_UNS_COMMAND, 354 HAB_UNS_COMMAND,
349 HAB_UNS_ENGINE, 355 HAB_UNS_ENGINE,
350 HAB_UNS_ITEM, 356 HAB_UNS_ITEM,
351 HAB_UNS_KEY, 357 HAB_UNS_KEY,
352 HAB_UNS_PROTOCOL, 358 HAB_UNS_PROTOCOL,
353 HAB_UNS_STATE, 359 HAB_UNS_STATE,
354 -1 360 -1
355 }; 361 };
356 362
357 static uint8_t hab_contexts[12] = { 363 static uint8_t hab_contexts[12] = {
358 HAB_CTX_ANY, 364 HAB_CTX_ANY,
359 HAB_CTX_FAB, 365 HAB_CTX_FAB,
360 HAB_CTX_ENTRY, 366 HAB_CTX_ENTRY,
361 HAB_CTX_TARGET, 367 HAB_CTX_TARGET,
362 HAB_CTX_AUTHENTICATE, 368 HAB_CTX_AUTHENTICATE,
363 HAB_CTX_DCD, 369 HAB_CTX_DCD,
364 HAB_CTX_CSF, 370 HAB_CTX_CSF,
365 HAB_CTX_COMMAND, 371 HAB_CTX_COMMAND,
366 HAB_CTX_AUT_DAT, 372 HAB_CTX_AUT_DAT,
367 HAB_CTX_ASSERT, 373 HAB_CTX_ASSERT,
368 HAB_CTX_EXIT, 374 HAB_CTX_EXIT,
369 -1 375 -1
370 }; 376 };
371 377
372 static uint8_t hab_engines[16] = { 378 static uint8_t hab_engines[16] = {
373 HAB_ENG_ANY, 379 HAB_ENG_ANY,
374 HAB_ENG_SCC, 380 HAB_ENG_SCC,
375 HAB_ENG_RTIC, 381 HAB_ENG_RTIC,
376 HAB_ENG_SAHARA, 382 HAB_ENG_SAHARA,
377 HAB_ENG_CSU, 383 HAB_ENG_CSU,
378 HAB_ENG_SRTC, 384 HAB_ENG_SRTC,
379 HAB_ENG_DCP, 385 HAB_ENG_DCP,
380 HAB_ENG_CAAM, 386 HAB_ENG_CAAM,
381 HAB_ENG_SNVS, 387 HAB_ENG_SNVS,
382 HAB_ENG_OCOTP, 388 HAB_ENG_OCOTP,
383 HAB_ENG_DTCP, 389 HAB_ENG_DTCP,
384 HAB_ENG_ROM, 390 HAB_ENG_ROM,
385 HAB_ENG_HDCP, 391 HAB_ENG_HDCP,
386 HAB_ENG_RTL, 392 HAB_ENG_RTL,
387 HAB_ENG_SW, 393 HAB_ENG_SW,
388 -1 394 -1
389 }; 395 };
390 396
391 static inline uint8_t get_idx(uint8_t *list, uint8_t tgt) 397 static inline uint8_t get_idx(uint8_t *list, uint8_t tgt)
392 { 398 {
393 uint8_t idx = 0; 399 uint8_t idx = 0;
394 uint8_t element = list[idx]; 400 uint8_t element = list[idx];
395 while (element != -1) { 401 while (element != -1) {
396 if (element == tgt) 402 if (element == tgt)
397 return idx; 403 return idx;
398 element = list[++idx]; 404 element = list[++idx];
399 } 405 }
400 return -1; 406 return -1;
401 } 407 }
402 408
403 static void process_event_record(uint8_t *event_data, size_t bytes) 409 static void process_event_record(uint8_t *event_data, size_t bytes)
404 { 410 {
405 struct record *rec = (struct record *)event_data; 411 struct record *rec = (struct record *)event_data;
406 412
407 printf("\n\n%s", sts_str[get_idx(hab_statuses, rec->contents[0])]); 413 printf("\n\n%s", sts_str[get_idx(hab_statuses, rec->contents[0])]);
408 printf("%s", rsn_str[get_idx(hab_reasons, rec->contents[1])]); 414 printf("%s", rsn_str[get_idx(hab_reasons, rec->contents[1])]);
409 printf("%s", ctx_str[get_idx(hab_contexts, rec->contents[2])]); 415 printf("%s", ctx_str[get_idx(hab_contexts, rec->contents[2])]);
410 printf("%s", eng_str[get_idx(hab_engines, rec->contents[3])]); 416 printf("%s", eng_str[get_idx(hab_engines, rec->contents[3])]);
411 } 417 }
412 418
413 static void display_event(uint8_t *event_data, size_t bytes) 419 static void display_event(uint8_t *event_data, size_t bytes)
414 { 420 {
415 uint32_t i; 421 uint32_t i;
416 422
417 if (!(event_data && bytes > 0)) 423 if (!(event_data && bytes > 0))
418 return; 424 return;
419 425
420 for (i = 0; i < bytes; i++) { 426 for (i = 0; i < bytes; i++) {
421 if (i == 0) 427 if (i == 0)
422 printf("\t0x%02x", event_data[i]); 428 printf("\t0x%02x", event_data[i]);
423 else if ((i % 8) == 0) 429 else if ((i % 8) == 0)
424 printf("\n\t0x%02x", event_data[i]); 430 printf("\n\t0x%02x", event_data[i]);
425 else 431 else
426 printf(" 0x%02x", event_data[i]); 432 printf(" 0x%02x", event_data[i]);
427 } 433 }
428 434
429 process_event_record(event_data, bytes); 435 process_event_record(event_data, bytes);
430 } 436 }
431 437
432 static int get_hab_status(void) 438 static int get_hab_status(void)
433 { 439 {
434 uint32_t index = 0; /* Loop index */ 440 uint32_t index = 0; /* Loop index */
435 uint8_t event_data[128]; /* Event data buffer */ 441 uint8_t event_data[128]; /* Event data buffer */
436 size_t bytes = sizeof(event_data); /* Event size in bytes */ 442 size_t bytes = sizeof(event_data); /* Event size in bytes */
437 enum hab_config config = 0; 443 enum hab_config config = 0;
438 enum hab_state state = 0; 444 enum hab_state state = 0;
439 445
440 if (imx_hab_is_enabled()) 446 if (imx_hab_is_enabled())
441 puts("\nSecure boot enabled\n"); 447 puts("\nSecure boot enabled\n");
442 else 448 else
443 puts("\nSecure boot disabled\n"); 449 puts("\nSecure boot disabled\n");
444 450
445 /* Check HAB status */ 451 /* Check HAB status */
446 if (hab_rvt_report_status(&config, &state) != HAB_SUCCESS) { 452 if (hab_rvt_report_status(&config, &state) != HAB_SUCCESS) {
447 printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n", 453 printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
448 config, state); 454 config, state);
449 455
450 /* Display HAB events */ 456 /* Display HAB events */
451 while (hab_rvt_report_event(HAB_STS_ANY, index, event_data, 457 while (hab_rvt_report_event(HAB_STS_ANY, index, event_data,
452 &bytes) == HAB_SUCCESS) { 458 &bytes) == HAB_SUCCESS) {
453 puts("\n"); 459 puts("\n");
454 printf("--------- HAB Event %d -----------------\n", 460 printf("--------- HAB Event %d -----------------\n",
455 index + 1); 461 index + 1);
456 puts("event data:\n"); 462 puts("event data:\n");
457 display_event(event_data, bytes); 463 display_event(event_data, bytes);
458 puts("\n"); 464 puts("\n");
459 bytes = sizeof(event_data); 465 bytes = sizeof(event_data);
460 index++; 466 index++;
461 } 467 }
462 } 468 }
463 /* Display message if no HAB events are found */ 469 /* Display message if no HAB events are found */
464 else { 470 else {
465 printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n", 471 printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
466 config, state); 472 config, state);
467 puts("No HAB Events Found!\n\n"); 473 puts("No HAB Events Found!\n\n");
468 } 474 }
469 return 0; 475 return 0;
470 } 476 }
471 477
478 #ifdef CONFIG_MX7ULP
479
480 static int get_record_len(struct record *rec)
481 {
482 return (size_t)((rec->len[0] << 8) + (rec->len[1]));
483 }
484
485 static int get_hab_status_m4(void)
486 {
487 unsigned int index = 0;
488 uint8_t event_data[128];
489 size_t record_len, offset = 0;
490 enum hab_config config = 0;
491 enum hab_state state = 0;
492
493 if (imx_hab_is_enabled())
494 puts("\nSecure boot enabled\n");
495 else
496 puts("\nSecure boot disabled\n");
497
498 /*
499 * HAB in both A7 and M4 gather the security state
500 * and configuration of the chip from
501 * shared SNVS module
502 */
503 hab_rvt_report_status(&config, &state);
504 printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
505 config, state);
506
507 struct record *rec = (struct record *)(HAB_M4_PERSISTENT_START);
508
509 record_len = get_record_len(rec);
510
511 /* Check if HAB persistent memory is valid */
512 if (rec->tag != HAB_TAG_EVT_DEF ||
513 record_len != sizeof(struct evt_def) ||
514 (rec->par & HAB_MAJ_MASK) != HAB_MAJ_VER) {
515 puts("\nERROR: Invalid HAB persistent memory\n");
516 return 1;
517 }
518
519 /* Parse events in HAB M4 persistent memory region */
520 while (offset < HAB_M4_PERSISTENT_BYTES) {
521 rec = (struct record *)(HAB_M4_PERSISTENT_START + offset);
522
523 record_len = get_record_len(rec);
524
525 if (rec->tag == HAB_TAG_EVT) {
526 memcpy(&event_data, rec, record_len);
527 puts("\n");
528 printf("--------- HAB Event %d -----------------\n",
529 index + 1);
530 puts("event data:\n");
531 display_event(event_data, record_len);
532 puts("\n");
533 index++;
534 }
535
536 offset += record_len;
537
538 /* Ensure all records start on a word boundary */
539 if ((offset % 4) != 0)
540 offset = offset + (4 - (offset % 4));
541 }
542
543 if (!index)
544 puts("No HAB Events Found!\n\n");
545
546 return 0;
547 }
548 #endif
549
472 static int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, 550 static int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc,
473 char * const argv[]) 551 char * const argv[])
474 { 552 {
553 #ifdef CONFIG_MX7ULP
554 if ((argc > 2)) {
555 cmd_usage(cmdtp);
556 return 1;
557 }
558
559 if (strcmp("m4", argv[1]) == 0)
560 get_hab_status_m4();
561 else
562 get_hab_status();
563 #else
475 if ((argc != 1)) { 564 if ((argc != 1)) {
476 cmd_usage(cmdtp); 565 cmd_usage(cmdtp);
477 return 1; 566 return 1;
478 } 567 }
479 568
480 get_hab_status(); 569 get_hab_status();
570 #endif
481 571
482 return 0; 572 return 0;
483 } 573 }
484 574
485 static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc, 575 static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc,
486 char * const argv[]) 576 char * const argv[])
487 { 577 {
488 ulong addr, length, ivt_offset; 578 ulong addr, length, ivt_offset;
489 int rcode = 0; 579 int rcode = 0;
490 580
491 if (argc < 4) 581 if (argc < 4)
492 return CMD_RET_USAGE; 582 return CMD_RET_USAGE;
493 583
494 addr = simple_strtoul(argv[1], NULL, 16); 584 addr = simple_strtoul(argv[1], NULL, 16);
495 length = simple_strtoul(argv[2], NULL, 16); 585 length = simple_strtoul(argv[2], NULL, 16);
496 ivt_offset = simple_strtoul(argv[3], NULL, 16); 586 ivt_offset = simple_strtoul(argv[3], NULL, 16);
497 587
498 rcode = imx_hab_authenticate_image(addr, length, ivt_offset); 588 rcode = imx_hab_authenticate_image(addr, length, ivt_offset);
499 if (rcode == 0) 589 if (rcode == 0)
500 rcode = CMD_RET_SUCCESS; 590 rcode = CMD_RET_SUCCESS;
501 else 591 else
502 rcode = CMD_RET_FAILURE; 592 rcode = CMD_RET_FAILURE;
503 593
504 return rcode; 594 return rcode;
505 } 595 }
506 596
507 static int do_hab_failsafe(cmd_tbl_t *cmdtp, int flag, int argc, 597 static int do_hab_failsafe(cmd_tbl_t *cmdtp, int flag, int argc,
508 char * const argv[]) 598 char * const argv[])
509 { 599 {
510 if (argc != 1) { 600 if (argc != 1) {
511 cmd_usage(cmdtp); 601 cmd_usage(cmdtp);
512 return 1; 602 return 1;
513 } 603 }
514 604
515 hab_rvt_failsafe(); 605 hab_rvt_failsafe();
516 606
517 return 0; 607 return 0;
518 } 608 }
519 609
610 #ifdef CONFIG_MX7ULP
520 U_BOOT_CMD( 611 U_BOOT_CMD(
612 hab_status, CONFIG_SYS_MAXARGS, 2, do_hab_status,
613 "display HAB status and events",
614 "hab_status - A7 HAB event and status\n"
615 "hab_status m4 - M4 HAB event and status"
616 );
617 #else
618 U_BOOT_CMD(
521 hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status, 619 hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
522 "display HAB status", 620 "display HAB status",
523 "" 621 ""
524 ); 622 );
623 #endif
525 624
526 U_BOOT_CMD( 625 U_BOOT_CMD(
527 hab_auth_img, 4, 0, do_authenticate_image, 626 hab_auth_img, 4, 0, do_authenticate_image,
528 "authenticate image via HAB", 627 "authenticate image via HAB",
529 "addr length ivt_offset\n" 628 "addr length ivt_offset\n"
530 "addr - image hex address\n" 629 "addr - image hex address\n"
531 "length - image hex length\n" 630 "length - image hex length\n"
532 "ivt_offset - hex offset of IVT in the image" 631 "ivt_offset - hex offset of IVT in the image"
533 ); 632 );
534 633
535 U_BOOT_CMD( 634 U_BOOT_CMD(
536 hab_failsafe, CONFIG_SYS_MAXARGS, 1, do_hab_failsafe, 635 hab_failsafe, CONFIG_SYS_MAXARGS, 1, do_hab_failsafe,
537 "run BootROM failsafe routine", 636 "run BootROM failsafe routine",
538 "" 637 ""
539 ); 638 );
540 639
541 #endif /* !defined(CONFIG_SPL_BUILD) */ 640 #endif /* !defined(CONFIG_SPL_BUILD) */
542 641
543 /* Get CSF Header length */ 642 /* Get CSF Header length */
544 static int get_hab_hdr_len(struct hab_hdr *hdr) 643 static int get_hab_hdr_len(struct hab_hdr *hdr)
545 { 644 {
546 return (size_t)((hdr->len[0] << 8) + (hdr->len[1])); 645 return (size_t)((hdr->len[0] << 8) + (hdr->len[1]));
547 } 646 }
548 647
549 /* Check whether addr lies between start and 648 /* Check whether addr lies between start and
550 * end and is within the length of the image 649 * end and is within the length of the image
551 */ 650 */
552 static int chk_bounds(u8 *addr, size_t bytes, u8 *start, u8 *end) 651 static int chk_bounds(u8 *addr, size_t bytes, u8 *start, u8 *end)
553 { 652 {
554 size_t csf_size = (size_t)((end + 1) - addr); 653 size_t csf_size = (size_t)((end + 1) - addr);
555 654
556 return (addr && (addr >= start) && (addr <= end) && 655 return (addr && (addr >= start) && (addr <= end) &&
557 (csf_size >= bytes)); 656 (csf_size >= bytes));
558 } 657 }
559 658
560 /* Get Length of each command in CSF */ 659 /* Get Length of each command in CSF */
561 static int get_csf_cmd_hdr_len(u8 *csf_hdr) 660 static int get_csf_cmd_hdr_len(u8 *csf_hdr)
562 { 661 {
563 if (*csf_hdr == HAB_CMD_HDR) 662 if (*csf_hdr == HAB_CMD_HDR)
564 return sizeof(struct hab_hdr); 663 return sizeof(struct hab_hdr);
565 664
566 return get_hab_hdr_len((struct hab_hdr *)csf_hdr); 665 return get_hab_hdr_len((struct hab_hdr *)csf_hdr);
567 } 666 }
568 667
569 /* Check if CSF is valid */ 668 /* Check if CSF is valid */
570 static bool csf_is_valid(struct ivt *ivt, ulong start_addr, size_t bytes) 669 static bool csf_is_valid(struct ivt *ivt, ulong start_addr, size_t bytes)
571 { 670 {
572 u8 *start = (u8 *)start_addr; 671 u8 *start = (u8 *)start_addr;
573 u8 *csf_hdr; 672 u8 *csf_hdr;
574 u8 *end; 673 u8 *end;
575 674
576 size_t csf_hdr_len; 675 size_t csf_hdr_len;
577 size_t cmd_hdr_len; 676 size_t cmd_hdr_len;
578 size_t offset = 0; 677 size_t offset = 0;
579 678
580 if (bytes != 0) 679 if (bytes != 0)
581 end = start + bytes - 1; 680 end = start + bytes - 1;
582 else 681 else
583 end = start; 682 end = start;
584 683
585 /* Verify if CSF pointer content is zero */ 684 /* Verify if CSF pointer content is zero */
586 if (!ivt->csf) { 685 if (!ivt->csf) {
587 puts("Error: CSF pointer is NULL\n"); 686 puts("Error: CSF pointer is NULL\n");
588 return false; 687 return false;
589 } 688 }
590 689
591 csf_hdr = (u8 *)(ulong)ivt->csf; 690 csf_hdr = (u8 *)(ulong)ivt->csf;
592 691
593 /* Verify if CSF Header exist */ 692 /* Verify if CSF Header exist */
594 if (*csf_hdr != HAB_CMD_HDR) { 693 if (*csf_hdr != HAB_CMD_HDR) {
595 puts("Error: CSF header command not found\n"); 694 puts("Error: CSF header command not found\n");
596 return false; 695 return false;
597 } 696 }
598 697
599 csf_hdr_len = get_hab_hdr_len((struct hab_hdr *)csf_hdr); 698 csf_hdr_len = get_hab_hdr_len((struct hab_hdr *)csf_hdr);
600 699
601 /* Check if the CSF lies within the image bounds */ 700 /* Check if the CSF lies within the image bounds */
602 if (!chk_bounds(csf_hdr, csf_hdr_len, start, end)) { 701 if (!chk_bounds(csf_hdr, csf_hdr_len, start, end)) {
603 puts("Error: CSF lies outside the image bounds\n"); 702 puts("Error: CSF lies outside the image bounds\n");
604 return false; 703 return false;
605 } 704 }
606 705
607 do { 706 do {
608 struct hab_hdr *cmd; 707 struct hab_hdr *cmd;
609 708
610 cmd = (struct hab_hdr *)&csf_hdr[offset]; 709 cmd = (struct hab_hdr *)&csf_hdr[offset];
611 710
612 switch (cmd->tag) { 711 switch (cmd->tag) {
613 case (HAB_CMD_WRT_DAT): 712 case (HAB_CMD_WRT_DAT):
614 puts("Error: Deprecated write command found\n"); 713 puts("Error: Deprecated write command found\n");
615 return false; 714 return false;
616 case (HAB_CMD_CHK_DAT): 715 case (HAB_CMD_CHK_DAT):
617 puts("Error: Deprecated check command found\n"); 716 puts("Error: Deprecated check command found\n");
618 return false; 717 return false;
619 case (HAB_CMD_SET): 718 case (HAB_CMD_SET):
620 if (cmd->par == HAB_PAR_MID) { 719 if (cmd->par == HAB_PAR_MID) {
621 puts("Error: Deprecated Set MID command found\n"); 720 puts("Error: Deprecated Set MID command found\n");
622 return false; 721 return false;
623 } 722 }
624 default: 723 default:
625 break; 724 break;
626 } 725 }
627 726
628 cmd_hdr_len = get_csf_cmd_hdr_len(&csf_hdr[offset]); 727 cmd_hdr_len = get_csf_cmd_hdr_len(&csf_hdr[offset]);
629 if (!cmd_hdr_len) { 728 if (!cmd_hdr_len) {
630 puts("Error: Invalid command length\n"); 729 puts("Error: Invalid command length\n");
631 return false; 730 return false;
632 } 731 }
633 offset += cmd_hdr_len; 732 offset += cmd_hdr_len;
634 733
635 } while (offset < csf_hdr_len); 734 } while (offset < csf_hdr_len);
636 735
637 return true; 736 return true;
638 } 737 }
639 738
640 /* 739 /*
641 * Validate IVT structure of the image being authenticated 740 * Validate IVT structure of the image being authenticated
642 */ 741 */
643 static int validate_ivt(struct ivt *ivt_initial) 742 static int validate_ivt(struct ivt *ivt_initial)
644 { 743 {
645 struct ivt_header *ivt_hdr = &ivt_initial->hdr; 744 struct ivt_header *ivt_hdr = &ivt_initial->hdr;
646 745
647 if ((ulong)ivt_initial & 0x3) { 746 if ((ulong)ivt_initial & 0x3) {
648 puts("Error: Image's start address is not 4 byte aligned\n"); 747 puts("Error: Image's start address is not 4 byte aligned\n");
649 return 0; 748 return 0;
650 } 749 }
651 750
652 /* Check IVT fields before allowing authentication */ 751 /* Check IVT fields before allowing authentication */
653 if ((!verify_ivt_header(ivt_hdr)) && \ 752 if ((!verify_ivt_header(ivt_hdr)) && \
654 (ivt_initial->entry != 0x0) && \ 753 (ivt_initial->entry != 0x0) && \
655 (ivt_initial->reserved1 == 0x0) && \ 754 (ivt_initial->reserved1 == 0x0) && \
656 (ivt_initial->self == \ 755 (ivt_initial->self == \
657 (uint32_t)((ulong)ivt_initial & 0xffffffff)) && \ 756 (uint32_t)((ulong)ivt_initial & 0xffffffff)) && \
658 (ivt_initial->csf != 0x0) && \ 757 (ivt_initial->csf != 0x0) && \
659 (ivt_initial->reserved2 == 0x0)) { 758 (ivt_initial->reserved2 == 0x0)) {
660 /* Report boot failure if DCD pointer is found in IVT */ 759 /* Report boot failure if DCD pointer is found in IVT */
661 if (ivt_initial->dcd != 0x0) 760 if (ivt_initial->dcd != 0x0)
662 puts("Error: DCD pointer must be 0\n"); 761 puts("Error: DCD pointer must be 0\n");
663 else 762 else
664 return 1; 763 return 1;
665 } 764 }
666 765
667 puts("Error: Invalid IVT structure\n"); 766 puts("Error: Invalid IVT structure\n");
668 puts("\nAllowed IVT structure:\n"); 767 puts("\nAllowed IVT structure:\n");
669 puts("IVT HDR = 0x4X2000D1\n"); 768 puts("IVT HDR = 0x4X2000D1\n");
670 puts("IVT ENTRY = 0xXXXXXXXX\n"); 769 puts("IVT ENTRY = 0xXXXXXXXX\n");
671 puts("IVT RSV1 = 0x0\n"); 770 puts("IVT RSV1 = 0x0\n");
672 puts("IVT DCD = 0x0\n"); /* Recommended */ 771 puts("IVT DCD = 0x0\n"); /* Recommended */
673 puts("IVT BOOT_DATA = 0xXXXXXXXX\n"); /* Commonly 0x0 */ 772 puts("IVT BOOT_DATA = 0xXXXXXXXX\n"); /* Commonly 0x0 */
674 puts("IVT SELF = 0xXXXXXXXX\n"); /* = ddr_start + ivt_offset */ 773 puts("IVT SELF = 0xXXXXXXXX\n"); /* = ddr_start + ivt_offset */
675 puts("IVT CSF = 0xXXXXXXXX\n"); 774 puts("IVT CSF = 0xXXXXXXXX\n");
676 puts("IVT RSV2 = 0x0\n"); 775 puts("IVT RSV2 = 0x0\n");
677 776
678 /* Invalid IVT structure */ 777 /* Invalid IVT structure */
679 return 0; 778 return 0;
680 } 779 }
681 780
682 bool imx_hab_is_enabled(void) 781 bool imx_hab_is_enabled(void)
683 { 782 {
684 struct imx_sec_config_fuse_t *fuse = 783 struct imx_sec_config_fuse_t *fuse =
685 (struct imx_sec_config_fuse_t *)&imx_sec_config_fuse; 784 (struct imx_sec_config_fuse_t *)&imx_sec_config_fuse;
686 uint32_t reg; 785 uint32_t reg;
687 int ret; 786 int ret;
688 787
689 ret = fuse_read(fuse->bank, fuse->word, &reg); 788 ret = fuse_read(fuse->bank, fuse->word, &reg);
690 if (ret) { 789 if (ret) {
691 puts("\nSecure boot fuse read error\n"); 790 puts("\nSecure boot fuse read error\n");
692 return ret; 791 return ret;
693 } 792 }
694 793
695 return (reg & IS_HAB_ENABLED_BIT) == IS_HAB_ENABLED_BIT; 794 return (reg & IS_HAB_ENABLED_BIT) == IS_HAB_ENABLED_BIT;
696 } 795 }
697 796
698 int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size, 797 int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
699 uint32_t ivt_offset) 798 uint32_t ivt_offset)
700 { 799 {
701 ulong load_addr = 0; 800 ulong load_addr = 0;
702 size_t bytes; 801 size_t bytes;
703 ulong ivt_addr = 0; 802 ulong ivt_addr = 0;
704 int result = 1; 803 int result = 1;
705 ulong start; 804 ulong start;
706 struct ivt *ivt; 805 struct ivt *ivt;
707 enum hab_status status; 806 enum hab_status status;
708 807
709 if (!imx_hab_is_enabled()) 808 if (!imx_hab_is_enabled())
710 puts("hab fuse not enabled\n"); 809 puts("hab fuse not enabled\n");
711 810
712 printf("\nAuthenticate image from DDR location 0x%x...\n", 811 printf("\nAuthenticate image from DDR location 0x%x...\n",
713 ddr_start); 812 ddr_start);
714 813
715 hab_caam_clock_enable(1); 814 hab_caam_clock_enable(1);
716 815
717 /* Calculate IVT address header */ 816 /* Calculate IVT address header */
718 ivt_addr = (ulong) (ddr_start + ivt_offset); 817 ivt_addr = (ulong) (ddr_start + ivt_offset);
719 ivt = (struct ivt *)ivt_addr; 818 ivt = (struct ivt *)ivt_addr;
720 819
721 /* Verify IVT header bugging out on error */ 820 /* Verify IVT header bugging out on error */
722 if (!validate_ivt(ivt)) 821 if (!validate_ivt(ivt))
723 goto hab_authentication_exit; 822 goto hab_authentication_exit;
724 823
725 start = ddr_start; 824 start = ddr_start;
726 bytes = image_size; 825 bytes = image_size;
727 826
728 /* Verify CSF */ 827 /* Verify CSF */
729 if (!csf_is_valid(ivt, start, bytes)) 828 if (!csf_is_valid(ivt, start, bytes))
730 goto hab_authentication_exit; 829 goto hab_authentication_exit;
731 830
732 if (hab_rvt_entry() != HAB_SUCCESS) { 831 if (hab_rvt_entry() != HAB_SUCCESS) {
733 puts("hab entry function fail\n"); 832 puts("hab entry function fail\n");
734 goto hab_exit_failure_print_status; 833 goto hab_exit_failure_print_status;
735 } 834 }
736 835
737 status = hab_rvt_check_target(HAB_TGT_MEMORY, (void *)(ulong)ddr_start, bytes); 836 status = hab_rvt_check_target(HAB_TGT_MEMORY, (void *)(ulong)ddr_start, bytes);
738 if (status != HAB_SUCCESS) { 837 if (status != HAB_SUCCESS) {
739 printf("HAB check target 0x%08x-0x%08lx fail\n", 838 printf("HAB check target 0x%08x-0x%08lx fail\n",
740 ddr_start, ddr_start + bytes); 839 ddr_start, ddr_start + bytes);
741 goto hab_exit_failure_print_status; 840 goto hab_exit_failure_print_status;
742 } 841 }
743 #ifdef DEBUG 842 #ifdef DEBUG
744 printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", ivt_offset, ivt_addr); 843 printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", ivt_offset, ivt_addr);
745 printf("ivt entry = 0x%08x, dcd = 0x%08x, csf = 0x%08x\n", ivt->entry, 844 printf("ivt entry = 0x%08x, dcd = 0x%08x, csf = 0x%08x\n", ivt->entry,
746 ivt->dcd, ivt->csf); 845 ivt->dcd, ivt->csf);
747 puts("Dumping IVT\n"); 846 puts("Dumping IVT\n");
748 print_buffer(ivt_addr, (void *)(ivt_addr), 4, 0x8, 0); 847 print_buffer(ivt_addr, (void *)(ivt_addr), 4, 0x8, 0);
749 848
750 puts("Dumping CSF Header\n"); 849 puts("Dumping CSF Header\n");
751 print_buffer(ivt->csf, (void *)(ivt->csf), 4, 0x10, 0); 850 print_buffer(ivt->csf, (void *)(ivt->csf), 4, 0x10, 0);
752 851
753 #if !defined(CONFIG_SPL_BUILD) 852 #if !defined(CONFIG_SPL_BUILD)
754 get_hab_status(); 853 get_hab_status();
755 #endif 854 #endif
756 855
757 puts("\nCalling authenticate_image in ROM\n"); 856 puts("\nCalling authenticate_image in ROM\n");
758 printf("\tivt_offset = 0x%x\n", ivt_offset); 857 printf("\tivt_offset = 0x%x\n", ivt_offset);
759 printf("\tstart = 0x%08lx\n", start); 858 printf("\tstart = 0x%08lx\n", start);
760 printf("\tbytes = 0x%x\n", bytes); 859 printf("\tbytes = 0x%x\n", bytes);
761 #endif 860 #endif
762 861
763 #ifndef CONFIG_ARM64 862 #ifndef CONFIG_ARM64
764 /* 863 /*
765 * If the MMU is enabled, we have to notify the ROM 864 * If the MMU is enabled, we have to notify the ROM
766 * code, or it won't flush the caches when needed. 865 * code, or it won't flush the caches when needed.
767 * This is done, by setting the "pu_irom_mmu_enabled" 866 * This is done, by setting the "pu_irom_mmu_enabled"
768 * word to 1. You can find its address by looking in 867 * word to 1. You can find its address by looking in
769 * the ROM map. This is critical for 868 * the ROM map. This is critical for
770 * authenticate_image(). If MMU is enabled, without 869 * authenticate_image(). If MMU is enabled, without
771 * setting this bit, authentication will fail and may 870 * setting this bit, authentication will fail and may
772 * crash. 871 * crash.
773 */ 872 */
774 /* Check MMU enabled */ 873 /* Check MMU enabled */
775 if (is_soc_type(MXC_SOC_MX6) && get_cr() & CR_M) { 874 if (is_soc_type(MXC_SOC_MX6) && get_cr() & CR_M) {
776 if (is_mx6dq()) { 875 if (is_mx6dq()) {
777 /* 876 /*
778 * This won't work on Rev 1.0.0 of 877 * This won't work on Rev 1.0.0 of
779 * i.MX6Q/D, since their ROM doesn't 878 * i.MX6Q/D, since their ROM doesn't
780 * do cache flushes. don't think any 879 * do cache flushes. don't think any
781 * exist, so we ignore them. 880 * exist, so we ignore them.
782 */ 881 */
783 if (!is_mx6dqp()) 882 if (!is_mx6dqp())
784 writel(1, MX6DQ_PU_IROM_MMU_EN_VAR); 883 writel(1, MX6DQ_PU_IROM_MMU_EN_VAR);
785 } else if (is_mx6sdl()) { 884 } else if (is_mx6sdl()) {
786 writel(1, MX6DLS_PU_IROM_MMU_EN_VAR); 885 writel(1, MX6DLS_PU_IROM_MMU_EN_VAR);
787 } else if (is_mx6sl()) { 886 } else if (is_mx6sl()) {
788 writel(1, MX6SL_PU_IROM_MMU_EN_VAR); 887 writel(1, MX6SL_PU_IROM_MMU_EN_VAR);
789 } 888 }
790 } 889 }
791 #endif 890 #endif
792 891
793 load_addr = (ulong)hab_rvt_authenticate_image( 892 load_addr = (ulong)hab_rvt_authenticate_image(
794 HAB_CID_UBOOT, 893 HAB_CID_UBOOT,
795 ivt_offset, (void **)&start, 894 ivt_offset, (void **)&start,
796 (size_t *)&bytes, NULL); 895 (size_t *)&bytes, NULL);
797 if (hab_rvt_exit() != HAB_SUCCESS) { 896 if (hab_rvt_exit() != HAB_SUCCESS) {
798 puts("hab exit function fail\n"); 897 puts("hab exit function fail\n");
799 load_addr = 0; 898 load_addr = 0;
800 } 899 }
801 900
802 hab_exit_failure_print_status: 901 hab_exit_failure_print_status:
803 #if !defined(CONFIG_SPL_BUILD) 902 #if !defined(CONFIG_SPL_BUILD)
804 get_hab_status(); 903 get_hab_status();
805 #endif 904 #endif
806 905
807 hab_authentication_exit: 906 hab_authentication_exit:
808 907
809 if (load_addr != 0 || !imx_hab_is_enabled()) 908 if (load_addr != 0 || !imx_hab_is_enabled())
810 result = 0; 909 result = 0;
811 910
812 return result; 911 return result;
813 } 912 }
814 913
815 int authenticate_image(uint32_t ddr_start, uint32_t raw_image_size) 914 int authenticate_image(uint32_t ddr_start, uint32_t raw_image_size)
816 { 915 {
817 uint32_t ivt_offset; 916 uint32_t ivt_offset;
818 size_t bytes; 917 size_t bytes;
819 918
820 ivt_offset = (raw_image_size + ALIGN_SIZE - 1) & 919 ivt_offset = (raw_image_size + ALIGN_SIZE - 1) &
821 ~(ALIGN_SIZE - 1); 920 ~(ALIGN_SIZE - 1);
822 bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE; 921 bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE;
823 922
824 return imx_hab_authenticate_image(ddr_start, bytes, ivt_offset); 923 return imx_hab_authenticate_image(ddr_start, bytes, ivt_offset);
825 } 924 }
826 925
doc/imx/habv4/guides/mx6_mx7_secure_boot.txt
1 +=======================================================+ 1 +=======================================================+
2 + i.MX6, i.MX7 U-Boot Secure Boot guide using HABv4 + 2 + i.MX6, i.MX7 U-Boot Secure Boot guide using HABv4 +
3 +=======================================================+ 3 +=======================================================+
4 4
5 1. HABv4 secure boot process 5 1. HABv4 secure boot process
6 ----------------------------- 6 -----------------------------
7 7
8 This document describes a step-by-step procedure on how to sign and securely 8 This document describes a step-by-step procedure on how to sign and securely
9 boot an U-Boot image. It is assumed that the reader is familiar with basic 9 boot an U-Boot image. It is assumed that the reader is familiar with basic
10 HAB concepts and with the PKI tree generation. 10 HAB concepts and with the PKI tree generation.
11 11
12 Details about HAB can be found in the application note AN4581[1] and in the 12 Details about HAB can be found in the application note AN4581[1] and in the
13 introduction_habv4.txt document. 13 introduction_habv4.txt document.
14 14
15 1.1 Building a u-boot-dtb.imx image supporting secure boot 15 1.1 Building a u-boot-dtb.imx image supporting secure boot
16 ----------------------------------------------------------- 16 -----------------------------------------------------------
17 17
18 The U-Boot provides support to secure boot configuration and also provide 18 The U-Boot provides support to secure boot configuration and also provide
19 access to the HAB APIs exposed by the ROM vector table, the support is 19 access to the HAB APIs exposed by the ROM vector table, the support is
20 enabled by selecting the CONFIG_SECURE_BOOT option. 20 enabled by selecting the CONFIG_SECURE_BOOT option.
21 21
22 When built with this configuration, the U-Boot provides extra functions for 22 When built with this configuration, the U-Boot provides extra functions for
23 HAB, such as the HAB status logs retrievement through the hab_status command 23 HAB, such as the HAB status logs retrievement through the hab_status command
24 and support for extending the root of trust. 24 and support for extending the root of trust.
25 25
26 The U-Boot also correctly pads the final image by aligning to the next 0xC00 26 The U-Boot also correctly pads the final image by aligning to the next 0xC00
27 address, so the CSF signature data generated by CST can be concatenated to 27 address, so the CSF signature data generated by CST can be concatenated to
28 image. 28 image.
29 29
30 The diagram below illustrate a signed u-boot-dtb.imx image layout: 30 The diagram below illustrate a signed u-boot-dtb.imx image layout:
31 31
32 ------- +-----------------------------+ <-- *start 32 ------- +-----------------------------+ <-- *start
33 ^ | Image Vector Table | 33 ^ | Image Vector Table |
34 | +-----------------------------+ <-- *boot_data 34 | +-----------------------------+ <-- *boot_data
35 | | Boot Data | 35 | | Boot Data |
36 | +-----------------------------+ <-- *dcd 36 | +-----------------------------+ <-- *dcd
37 | | DCD Table | 37 | | DCD Table |
38 | +-----------------------------+ 38 | +-----------------------------+
39 Signed | | Padding | 39 Signed | | Padding |
40 Data | +-----------------------------+ <-- *entry 40 Data | +-----------------------------+ <-- *entry
41 | | | 41 | | |
42 | | | 42 | | |
43 | | u-boot-dtb.bin | 43 | | u-boot-dtb.bin |
44 | | | 44 | | |
45 | | | 45 | | |
46 | +-----------------------------+ 46 | +-----------------------------+
47 v | Padding | 47 v | Padding |
48 ------- +-----------------------------+ <-- *csf 48 ------- +-----------------------------+ <-- *csf
49 | | 49 | |
50 | Command Sequence File (CSF) | 50 | Command Sequence File (CSF) |
51 | | 51 | |
52 +-----------------------------+ 52 +-----------------------------+
53 | Padding (optional) | 53 | Padding (optional) |
54 +-----------------------------+ 54 +-----------------------------+
55 55
56 1.2 Enabling the secure boot support 56 1.2 Enabling the secure boot support
57 ------------------------------------- 57 -------------------------------------
58 58
59 The first step is to generate an U-Boot image supporting the HAB features 59 The first step is to generate an U-Boot image supporting the HAB features
60 mentioned above, this can be achieved by adding CONFIG_SECURE_BOOT to the 60 mentioned above, this can be achieved by adding CONFIG_SECURE_BOOT to the
61 build configuration: 61 build configuration:
62 62
63 - Defconfig: 63 - Defconfig:
64 64
65 CONFIG_SECURE_BOOT=y 65 CONFIG_SECURE_BOOT=y
66 66
67 - Kconfig: 67 - Kconfig:
68 68
69 ARM architecture -> Support i.MX HAB features 69 ARM architecture -> Support i.MX HAB features
70 70
71 1.3 Creating the CSF description file 71 1.3 Creating the CSF description file
72 -------------------------------------- 72 --------------------------------------
73 73
74 The CSF contains all the commands that the ROM executes during the secure 74 The CSF contains all the commands that the ROM executes during the secure
75 boot. These commands instruct the HAB on which memory areas of the image 75 boot. These commands instruct the HAB on which memory areas of the image
76 to authenticate, which keys to install, use and etc. 76 to authenticate, which keys to install, use and etc.
77 77
78 CSF examples are available under doc/imx/habv4/csf_examples/ directory. 78 CSF examples are available under doc/imx/habv4/csf_examples/ directory.
79 79
80 A build log containing the "Authenticate Data" parameters is available after 80 A build log containing the "Authenticate Data" parameters is available after
81 the U-Boot build, the example below is a log for mx7dsabresd_defconfig target: 81 the U-Boot build, the example below is a log for mx7dsabresd_defconfig target:
82 82
83 - mkimage build log: 83 - mkimage build log:
84 84
85 $ cat u-boot-dtb.imx.log 85 $ cat u-boot-dtb.imx.log
86 86
87 Image Type: Freescale IMX Boot Image 87 Image Type: Freescale IMX Boot Image
88 Image Ver: 2 (i.MX53/6/7 compatible) 88 Image Ver: 2 (i.MX53/6/7 compatible)
89 Mode: DCD 89 Mode: DCD
90 Data Size: 667648 Bytes = 652.00 KiB = 0.64 MiB 90 Data Size: 667648 Bytes = 652.00 KiB = 0.64 MiB
91 Load Address: 877ff420 91 Load Address: 877ff420
92 Entry Point: 87800000 92 Entry Point: 87800000
93 HAB Blocks: 877ff400 00000000 0009ec00 93 HAB Blocks: 877ff400 00000000 0009ec00
94 ^^^^^^^^ ^^^^^^^^ ^^^^^^^^ 94 ^^^^^^^^ ^^^^^^^^ ^^^^^^^^
95 | | | 95 | | |
96 | | ------- (1) 96 | | ------- (1)
97 | | 97 | |
98 | ---------------- (2) 98 | ---------------- (2)
99 | 99 |
100 ------------------------- (3) 100 ------------------------- (3)
101 101
102 (1) Size of area in file u-boot-dtb.imx to sign. 102 (1) Size of area in file u-boot-dtb.imx to sign.
103 This area should include the IVT, the Boot Data the DCD 103 This area should include the IVT, the Boot Data the DCD
104 and the U-Boot itself. 104 and the U-Boot itself.
105 (2) Start of area in u-boot-dtb.imx to sign. 105 (2) Start of area in u-boot-dtb.imx to sign.
106 (3) Start of area in RAM to authenticate. 106 (3) Start of area in RAM to authenticate.
107 107
108 - In "Authenticate Data" CSF command users can copy and past the output 108 - In "Authenticate Data" CSF command users can copy and past the output
109 addresses: 109 addresses:
110 110
111 Block = 0x877ff400 0x00000000 0x0009ec00 "u-boot-dtb.imx" 111 Block = 0x877ff400 0x00000000 0x0009ec00 "u-boot-dtb.imx"
112 112
113 1.3.1 Avoiding Kernel crash when OP-TEE is enabled 113 1.3.1 Avoiding Kernel crash when OP-TEE is enabled
114 --------------------------------------------------- 114 ---------------------------------------------------
115 115
116 For devices prior to HAB v4.4.0, the HAB code locks the Job Ring and DECO 116 For devices prior to HAB v4.4.0, the HAB code locks the Job Ring and DECO
117 master ID registers in HAB closed configuration. In case the user specific 117 master ID registers in HAB closed configuration. In case the user specific
118 application requires any changes in CAAM MID registers it's necessary to 118 application requires any changes in CAAM MID registers it's necessary to
119 add the "Unlock CAAM MID" command in CSF file. 119 add the "Unlock CAAM MID" command in CSF file.
120 120
121 The current NXP OP-TEE implementation expects the CAAM registers to be unlocked 121 The current NXP OP-TEE implementation expects the CAAM registers to be unlocked
122 when configuring CAAM to operate in non-secure TrustZone world. 122 when configuring CAAM to operate in non-secure TrustZone world.
123 123
124 - Add Unlock MID command in CSF: 124 - Add Unlock MID command in CSF:
125 125
126 [Unlock] 126 [Unlock]
127 Engine = CAAM 127 Engine = CAAM
128 Features = MID 128 Features = MID
129 129
130 1.4 Signing the U-Boot binary 130 1.4 Signing the U-Boot binary
131 ------------------------------ 131 ------------------------------
132 132
133 The CST tool is used for singing the U-Boot binary and generating a CSF binary, 133 The CST tool is used for singing the U-Boot binary and generating a CSF binary,
134 users should input the CSF description file created in the step above and 134 users should input the CSF description file created in the step above and
135 should receive a CSF binary, which contains the CSF commands, SRK table, 135 should receive a CSF binary, which contains the CSF commands, SRK table,
136 signatures and certificates. 136 signatures and certificates.
137 137
138 - Create CSF binary file: 138 - Create CSF binary file:
139 139
140 $ ./cst -i csf_uboot.txt -o csf_uboot.bin 140 $ ./cst -i csf_uboot.txt -o csf_uboot.bin
141 141
142 - Append CSF signature to the end of U-Boot image: 142 - Append CSF signature to the end of U-Boot image:
143 143
144 $ cat u-boot-dtb.imx csf_uboot.bin > u-boot-signed.imx 144 $ cat u-boot-dtb.imx csf_uboot.bin > u-boot-signed.imx
145 145
146 The u-boot-signed.imx is the signed binary and should be flashed into the boot 146 The u-boot-signed.imx is the signed binary and should be flashed into the boot
147 media. 147 media.
148 148
149 - Flash signed U-Boot binary: 149 - Flash signed U-Boot binary:
150 150
151 $ sudo dd if=u-boot-signed.imx of=/dev/sd<x> bs=1K seek=1 && sync 151 $ sudo dd if=u-boot-signed.imx of=/dev/sd<x> bs=1K seek=1 && sync
152 152
153 1.5 Programming SRK Hash 153 1.5 Programming SRK Hash
154 ------------------------- 154 -------------------------
155 155
156 As explained in AN4581[1] and in introduction_habv4.txt document the SRK Hash 156 As explained in AN4581[1] and in introduction_habv4.txt document the SRK Hash
157 fuse values are generated by the srktool and should be programmed in the 157 fuse values are generated by the srktool and should be programmed in the
158 SoC SRK_HASH[255:0] fuses. 158 SoC SRK_HASH[255:0] fuses.
159 159
160 Be careful when programming these values, as this data is the basis for the 160 Be careful when programming these values, as this data is the basis for the
161 root of trust. An error in SRK Hash results in a part that does not boot. 161 root of trust. An error in SRK Hash results in a part that does not boot.
162 162
163 The U-Boot fuse tool can be used for programming eFuses on i.MX SoCs. 163 The U-Boot fuse tool can be used for programming eFuses on i.MX SoCs.
164 164
165 - Dump SRK Hash fuses values in host machine: 165 - Dump SRK Hash fuses values in host machine:
166 166
167 $ hexdump -e '/4 "0x"' -e '/4 "%X""\n"' SRK_1_2_3_4_fuse.bin 167 $ hexdump -e '/4 "0x"' -e '/4 "%X""\n"' SRK_1_2_3_4_fuse.bin
168 0x20593752 168 0x20593752
169 0x6ACE6962 169 0x6ACE6962
170 0x26E0D06C 170 0x26E0D06C
171 0xFC600661 171 0xFC600661
172 0x1240E88F 172 0x1240E88F
173 0x1209F144 173 0x1209F144
174 0x831C8117 174 0x831C8117
175 0x1190FD4D 175 0x1190FD4D
176 176
177 - Program SRK_HASH[255:0] fuses, using i.MX6 series as example: 177 - Program SRK_HASH[255:0] fuses, using i.MX6 series as example:
178 178
179 => fuse prog 3 0 0x20593752 179 => fuse prog 3 0 0x20593752
180 => fuse prog 3 1 0x6ACE6962 180 => fuse prog 3 1 0x6ACE6962
181 => fuse prog 3 2 0x26E0D06C 181 => fuse prog 3 2 0x26E0D06C
182 => fuse prog 3 3 0xFC600661 182 => fuse prog 3 3 0xFC600661
183 => fuse prog 3 4 0x1240E88F 183 => fuse prog 3 4 0x1240E88F
184 => fuse prog 3 5 0x1209F144 184 => fuse prog 3 5 0x1209F144
185 => fuse prog 3 6 0x831C8117 185 => fuse prog 3 6 0x831C8117
186 => fuse prog 3 7 0x1190FD4D 186 => fuse prog 3 7 0x1190FD4D
187 187
188 The table below lists the SRK_HASH bank and word according to the i.MX device: 188 The table below lists the SRK_HASH bank and word according to the i.MX device:
189 189
190 +-------------------+---------------+---------------+---------------+ 190 +-------------------+---------------+---------------+---------------+
191 | | i.MX6 Series | i.MX7D/S | i.MX7ULP | 191 | | i.MX6 Series | i.MX7D/S | i.MX7ULP |
192 +-------------------+---------------+---------------+---------------+ 192 +-------------------+---------------+---------------+---------------+
193 | SRK_HASH[31:00] | bank 3 word 0 | bank 6 word 0 | bank 5 word 0 | 193 | SRK_HASH[31:00] | bank 3 word 0 | bank 6 word 0 | bank 5 word 0 |
194 +-------------------+---------------+---------------+---------------+ 194 +-------------------+---------------+---------------+---------------+
195 | SRK_HASH[63:32] | bank 3 word 1 | bank 6 word 1 | bank 5 word 1 | 195 | SRK_HASH[63:32] | bank 3 word 1 | bank 6 word 1 | bank 5 word 1 |
196 +-------------------+---------------+---------------+---------------+ 196 +-------------------+---------------+---------------+---------------+
197 | SRK_HASH[95:64] | bank 3 word 2 | bank 6 word 2 | bank 5 word 2 | 197 | SRK_HASH[95:64] | bank 3 word 2 | bank 6 word 2 | bank 5 word 2 |
198 +-------------------+---------------+---------------+---------------+ 198 +-------------------+---------------+---------------+---------------+
199 | SRK_HASH[127:96] | bank 3 word 3 | bank 6 word 3 | bank 5 word 3 | 199 | SRK_HASH[127:96] | bank 3 word 3 | bank 6 word 3 | bank 5 word 3 |
200 +-------------------+---------------+---------------+---------------+ 200 +-------------------+---------------+---------------+---------------+
201 | SRK_HASH[159:128] | bank 3 word 4 | bank 7 word 0 | bank 5 word 4 | 201 | SRK_HASH[159:128] | bank 3 word 4 | bank 7 word 0 | bank 5 word 4 |
202 +-------------------+---------------+---------------+---------------+ 202 +-------------------+---------------+---------------+---------------+
203 | SRK_HASH[191:160] | bank 3 word 5 | bank 7 word 1 | bank 5 word 5 | 203 | SRK_HASH[191:160] | bank 3 word 5 | bank 7 word 1 | bank 5 word 5 |
204 +-------------------+---------------+---------------+---------------+ 204 +-------------------+---------------+---------------+---------------+
205 | SRK_HASH[223:192] | bank 3 word 6 | bank 7 word 2 | bank 5 word 6 | 205 | SRK_HASH[223:192] | bank 3 word 6 | bank 7 word 2 | bank 5 word 6 |
206 +-------------------+---------------+---------------+---------------+ 206 +-------------------+---------------+---------------+---------------+
207 | SRK_HASH[255:224] | bank 3 word 7 | bank 7 word 3 | bank 5 word 7 | 207 | SRK_HASH[255:224] | bank 3 word 7 | bank 7 word 3 | bank 5 word 7 |
208 +-------------------+---------------+---------------+---------------+ 208 +-------------------+---------------+---------------+---------------+
209 209
210 1.6 Verifying HAB events 210 1.6 Verifying HAB events
211 ------------------------- 211 -------------------------
212 212
213 The next step is to verify that the signature attached to U-Boot is 213 The next step is to verify that the signature attached to U-Boot is
214 successfully processed without errors. HAB generates events when processing 214 successfully processed without errors. HAB generates events when processing
215 the commands if it encounters issues. 215 the commands if it encounters issues.
216 216
217 The hab_status U-Boot command call the hab_report_event() and hab_status() 217 The hab_status U-Boot command call the hab_report_event() and hab_status()
218 HAB API functions to verify the processor security configuration and status. 218 HAB API functions to verify the processor security configuration and status.
219 This command displays any events that were generated during the process. 219 This command displays any events that were generated during the process.
220 220
221 Prior to closing the device users should ensure no HAB events were found, as 221 Prior to closing the device users should ensure no HAB events were found, as
222 the example below: 222 the example below:
223 223
224 - Verify HAB events: 224 - Verify HAB events:
225 225
226 => hab_status 226 => hab_status
227 227
228 Secure boot disabled 228 Secure boot disabled
229 229
230 HAB Configuration: 0xf0, HAB State: 0x66 230 HAB Configuration: 0xf0, HAB State: 0x66
231 No HAB Events Found! 231 No HAB Events Found!
232 232
233 1.6.1 Verifying HAB events in i.MX7ULP
234 ---------------------------------------
235
236 When booting i.MX7ULP in low power or dual boot modes the M4 binary is
237 authenticated by an independent HAB in M4 ROM code using a
238 different SRK key set.
239
240 The U-Boot provides a M4 option in hab_status command so users can retrieve
241 M4 HAB failure and warning events.
242
243 - Verify HAB M4 events:
244
245 => hab_status m4
246
247 Secure boot disabled
248
249 HAB Configuration: 0xf0, HAB State: 0x66
250 No HAB Events Found!
251
252 As HAB M4 API cannot be called from A7 core the command is parsing the M4 HAB
253 persistent memory region, M4 software should not modify this reserved region.
254
255 Details about HAB persistent memory region can be found in AN12263[2].
256
233 1.7 Closing the device 257 1.7 Closing the device
234 ----------------------- 258 -----------------------
235 259
236 After the device successfully boots a signed image without generating any HAB 260 After the device successfully boots a signed image without generating any HAB
237 events, it is safe to close the device. This is the last step in the HAB 261 events, it is safe to close the device. This is the last step in the HAB
238 process, and is achieved by programming the SEC_CONFIG[1] fuse bit. 262 process, and is achieved by programming the SEC_CONFIG[1] fuse bit.
239 263
240 Once the fuse is programmed, the chip does not load an image that has not been 264 Once the fuse is programmed, the chip does not load an image that has not been
241 signed using the correct PKI tree. 265 signed using the correct PKI tree.
242 266
243 - Program SEC_CONFIG[1] fuse, using i.MX6 series as example: 267 - Program SEC_CONFIG[1] fuse, using i.MX6 series as example:
244 268
245 => fuse prog 0 6 0x00000002 269 => fuse prog 0 6 0x00000002
246 270
247 The table below list the SEC_CONFIG[1] bank and word according to the i.MX 271 The table below list the SEC_CONFIG[1] bank and word according to the i.MX
248 device: 272 device:
249 273
250 +--------------+-----------------+------------+ 274 +--------------+-----------------+------------+
251 | Device | Bank and Word | Value | 275 | Device | Bank and Word | Value |
252 +--------------+-----------------+------------+ 276 +--------------+-----------------+------------+
253 | i.MX6 Series | bank 0 word 6 | 0x00000002 | 277 | i.MX6 Series | bank 0 word 6 | 0x00000002 |
254 +--------------+-----------------+------------+ 278 +--------------+-----------------+------------+
255 | i.MX7D/S | bank 1 word 3 | 0x02000000 | 279 | i.MX7D/S | bank 1 word 3 | 0x02000000 |
256 +--------------+-----------------+------------+ 280 +--------------+-----------------+------------+
257 | i.MX7ULP | bank 29 word 6 | 0x80000000 | 281 | i.MX7ULP | bank 29 word 6 | 0x80000000 |
258 +--------------+-----------------+------------+ 282 +--------------+-----------------+------------+
259 283
260 1.8 Completely secure the device 284 1.8 Completely secure the device
261 --------------------------------- 285 ---------------------------------
262 286
263 Additional fuses can be programmed for completely secure the device, more 287 Additional fuses can be programmed for completely secure the device, more
264 details about these fuses and their possible impact can be found at AN4581[1]. 288 details about these fuses and their possible impact can be found at AN4581[1].
265 289
266 - Program SRK_LOCK, using i.MX6 series as example: 290 - Program SRK_LOCK, using i.MX6 series as example:
267 291
268 => fuse prog 0 0 0x4000 292 => fuse prog 0 0 0x4000
269 293
270 - Program DIR_BT_DIS, using i.MX6 series as example: 294 - Program DIR_BT_DIS, using i.MX6 series as example:
271 295
272 => fuse prog 0 6 0x8 296 => fuse prog 0 6 0x8
273 297
274 - Program SJC_DISABLE, using i.MX6 series as example: 298 - Program SJC_DISABLE, using i.MX6 series as example:
275 299
276 => fuse prog 0 6 0x100000 300 => fuse prog 0 6 0x100000
277 301
278 - JTAG_SMODE, using i.MX6 series as example: 302 - JTAG_SMODE, using i.MX6 series as example:
279 303
280 => fuse prog 0 6 0xC00000 304 => fuse prog 0 6 0xC00000
281 305
282 The table below list the SRK_LOCK, DIR_BT_DIS, SJC_DISABLE, and JTAG_SMODE bank 306 The table below list the SRK_LOCK, DIR_BT_DIS, SJC_DISABLE, and JTAG_SMODE bank
283 and word according to the i.MX device: 307 and word according to the i.MX device:
284 308
285 +--------------+---------------+------------+ 309 +--------------+---------------+------------+
286 | Device | Bank and Word | Value | 310 | Device | Bank and Word | Value |
287 +--------------+---------------+------------+ 311 +--------------+---------------+------------+
288 | SRK_LOCK | 312 | SRK_LOCK |
289 +-------------------------------------------+ 313 +-------------------------------------------+
290 | i.MX6 Series | bank 0 word 0 | 0x00004000 | 314 | i.MX6 Series | bank 0 word 0 | 0x00004000 |
291 +--------------+---------------+------------+ 315 +--------------+---------------+------------+
292 | i.MX7D/S | bank 0 word 0 | 0x00000200 | 316 | i.MX7D/S | bank 0 word 0 | 0x00000200 |
293 +--------------+---------------+------------+ 317 +--------------+---------------+------------+
294 | i.MX7ULP | bank 1 word 1 | 0x00000080 | 318 | i.MX7ULP | bank 1 word 1 | 0x00000080 |
295 +--------------+---------------+------------+ 319 +--------------+---------------+------------+
296 | DIR_BT_DIS | 320 | DIR_BT_DIS |
297 +-------------------------------------------+ 321 +-------------------------------------------+
298 | i.MX6 Series | bank 0 word 6 | 0x00000008 | 322 | i.MX6 Series | bank 0 word 6 | 0x00000008 |
299 +--------------+---------------+------------+ 323 +--------------+---------------+------------+
300 | i.MX7D/S | bank 1 word 3 | 0x08000000 | 324 | i.MX7D/S | bank 1 word 3 | 0x08000000 |
301 +--------------+---------------+------------+ 325 +--------------+---------------+------------+
302 | i.MX7ULP | bank 1 word 1 | 0x00002000 | 326 | i.MX7ULP | bank 1 word 1 | 0x00002000 |
303 +--------------+---------------+------------+ 327 +--------------+---------------+------------+
304 | SJC_DISABLE | 328 | SJC_DISABLE |
305 +-------------------------------------------+ 329 +-------------------------------------------+
306 | i.MX6 Series | bank 0 word 6 | 0x00100000 | 330 | i.MX6 Series | bank 0 word 6 | 0x00100000 |
307 +--------------+---------------+------------+ 331 +--------------+---------------+------------+
308 | i.MX7D/S | bank 1 word 3 | 0x00200000 | 332 | i.MX7D/S | bank 1 word 3 | 0x00200000 |
309 +--------------+---------------+------------+ 333 +--------------+---------------+------------+
310 | i.MX7ULP | bank 1 word 1 | 0x00000020 | 334 | i.MX7ULP | bank 1 word 1 | 0x00000020 |
311 +--------------+---------------+------------+ 335 +--------------+---------------+------------+
312 | JTAG_SMODE | 336 | JTAG_SMODE |
313 +-------------------------------------------+ 337 +-------------------------------------------+
314 | i.MX6 Series | bank 0 word 6 | 0x00C00000 | 338 | i.MX6 Series | bank 0 word 6 | 0x00C00000 |
315 +--------------+---------------+------------+ 339 +--------------+---------------+------------+
316 | i.MX7D/S | bank 1 word 3 | 0x00C00000 | 340 | i.MX7D/S | bank 1 word 3 | 0x00C00000 |
317 +--------------+---------------+------------+ 341 +--------------+---------------+------------+
318 | i.MX7ULP | bank 1 word 1 | 0x000000C0 | 342 | i.MX7ULP | bank 1 word 1 | 0x000000C0 |
319 +--------------+---------------+------------+ 343 +--------------+---------------+------------+
320 344
321 2. Extending the root of trust 345 2. Extending the root of trust
322 ------------------------------- 346 -------------------------------
323 347
324 The High Assurance Boot (HAB) code located in the on-chip ROM provides an 348 The High Assurance Boot (HAB) code located in the on-chip ROM provides an
325 Application Programming Interface (API) making it possible to call back 349 Application Programming Interface (API) making it possible to call back
326 into the HAB code for authenticating additional boot images. 350 into the HAB code for authenticating additional boot images.
327 351
328 The U-Boot supports this feature and can be used to authenticate the Linux 352 The U-Boot supports this feature and can be used to authenticate the Linux
329 Kernel Image. 353 Kernel Image.
330 354
331 The process of signing an additional image is similar to the U-Boot. 355 The process of signing an additional image is similar to the U-Boot.
332 The diagram below illustrate the zImage layout: 356 The diagram below illustrate the zImage layout:
333 357
334 ------- +-----------------------------+ <-- *load_address 358 ------- +-----------------------------+ <-- *load_address
335 ^ | | 359 ^ | |
336 | | | 360 | | |
337 | | | 361 | | |
338 | | | 362 | | |
339 | | zImage | 363 | | zImage |
340 Signed | | | 364 Signed | | |
341 Data | | | 365 Data | | |
342 | | | 366 | | |
343 | +-----------------------------+ 367 | +-----------------------------+
344 | | Padding Next Boundary | 368 | | Padding Next Boundary |
345 | +-----------------------------+ <-- *ivt 369 | +-----------------------------+ <-- *ivt
346 v | Image Vector Table | 370 v | Image Vector Table |
347 ------- +-----------------------------+ <-- *csf 371 ------- +-----------------------------+ <-- *csf
348 | | 372 | |
349 | Command Sequence File (CSF) | 373 | Command Sequence File (CSF) |
350 | | 374 | |
351 +-----------------------------+ 375 +-----------------------------+
352 | Padding (optional) | 376 | Padding (optional) |
353 +-----------------------------+ 377 +-----------------------------+
354 378
355 2.1 Padding the image 379 2.1 Padding the image
356 ---------------------- 380 ----------------------
357 381
358 The zImage must be padded to the next boundary address (0x1000), for instance 382 The zImage must be padded to the next boundary address (0x1000), for instance
359 if the image size is 0x649920 it must be padded to 0x64A000. 383 if the image size is 0x649920 it must be padded to 0x64A000.
360 384
361 The tool objcopy can be used for padding the image. 385 The tool objcopy can be used for padding the image.
362 386
363 - Pad the zImage: 387 - Pad the zImage:
364 388
365 $ objcopy -I binary -O binary --pad-to 0x6EA000 --gap-fill=0x00 \ 389 $ objcopy -I binary -O binary --pad-to 0x6EA000 --gap-fill=0x00 \
366 zImage zImage_pad.bin 390 zImage zImage_pad.bin
367 391
368 2.2 Generating Image Vector Table 392 2.2 Generating Image Vector Table
369 ---------------------------------- 393 ----------------------------------
370 394
371 The HAB code requires an Image Vector Table (IVT) for determining the image 395 The HAB code requires an Image Vector Table (IVT) for determining the image
372 length and the CSF location. Since zImage does not include an IVT this has 396 length and the CSF location. Since zImage does not include an IVT this has
373 to be manually created and appended to the end of the padded zImage, the 397 to be manually created and appended to the end of the padded zImage, the
374 script genIVT.pl in script_examples directory can be used as reference. 398 script genIVT.pl in script_examples directory can be used as reference.
375 399
376 - Generate IVT: 400 - Generate IVT:
377 401
378 $ genIVT.pl 402 $ genIVT.pl
379 403
380 Note: The load Address may change depending on the device. 404 Note: The load Address may change depending on the device.
381 405
382 - Append the ivt.bin at the end of the padded zImage: 406 - Append the ivt.bin at the end of the padded zImage:
383 407
384 $ cat zImage_pad.bin ivt.bin > zImage_pad_ivt.bin 408 $ cat zImage_pad.bin ivt.bin > zImage_pad_ivt.bin
385 409
386 2.3 Signing the image 410 2.3 Signing the image
387 ---------------------- 411 ----------------------
388 412
389 A CSF file has to be created to sign the image. HAB does not allow to change 413 A CSF file has to be created to sign the image. HAB does not allow to change
390 the SRK once the first image is authenticated, so the same SRK key used in 414 the SRK once the first image is authenticated, so the same SRK key used in
391 U-Boot must be used when extending the root of trust. 415 U-Boot must be used when extending the root of trust.
392 416
393 CSF examples are available in ../csf_examples/additional_images/ 417 CSF examples are available in ../csf_examples/additional_images/
394 directory. 418 directory.
395 419
396 - Create CSF binary file: 420 - Create CSF binary file:
397 421
398 $ ./cst --i csf_additional_images.txt --o csf_zImage.bin 422 $ ./cst --i csf_additional_images.txt --o csf_zImage.bin
399 423
400 - Attach the CSF binary to the end of the image: 424 - Attach the CSF binary to the end of the image:
401 425
402 $ cat zImage_pad_ivt.bin csf_zImage.bin > zImage_signed.bin 426 $ cat zImage_pad_ivt.bin csf_zImage.bin > zImage_signed.bin
403 427
404 2.4 Verifying HAB events 428 2.4 Verifying HAB events
405 ------------------------- 429 -------------------------
406 430
407 The U-Boot includes the hab_auth_img command which can be used for 431 The U-Boot includes the hab_auth_img command which can be used for
408 authenticating and troubleshooting the signed image, zImage must be 432 authenticating and troubleshooting the signed image, zImage must be
409 loaded at the load address specified in the IVT. 433 loaded at the load address specified in the IVT.
410 434
411 - Authenticate additional image: 435 - Authenticate additional image:
412 436
413 => hab_auth_img <Load Address> <Image Size> <IVT Offset> 437 => hab_auth_img <Load Address> <Image Size> <IVT Offset>
414 438
415 If no HAB events were found the zImage is successfully signed. 439 If no HAB events were found the zImage is successfully signed.
416 440
417 References: 441 References:
418 [1] AN4581: "Secure Boot on i.MX 50, i.MX 53, i.MX 6 and i.MX 7 Series using 442 [1] AN4581: "Secure Boot on i.MX 50, i.MX 53, i.MX 6 and i.MX 7 Series using
419 HABv4" - Rev 2. 443 HABv4" - Rev 2.
444 [2] AN12263: "HABv4 RVT Guidelines and Recommendations" - Rev 0.
420 445