aboutsummaryrefslogtreecommitdiffstats
path: root/doc/imx/habv4/guides/mx8m_mx8mm_secure_boot.txt
blob: 5922a1c31f298bf0653e903b9efdf6977ca81682 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
         +=======================================================+
         +     i.MX8M, i.MX8MM Secure Boot guide using HABv4     +
         +=======================================================+

1. HABv4 secure boot process
-----------------------------

This document describes a step-by-step procedure on how to sign and securely
boot a bootloader image on i.MX8M and i.MX8MM devices. It is assumed that
the reader is familiar with basic HAB concepts and with the PKI tree generation.

Details about HAB can be found in the application note AN4581[1] and in the
introduction_habv4.txt document.

1.1 Understanding the i.MX8M and i.MX8MM flash.bin image layout
----------------------------------------------------------------

Due to the new the architecture, multiple firmwares and softwares are required
to boot i.MX8M and i.MX8MM devices. In order to store all the images in a
single binary the FIT (Flattened Image Tree) image structure is used.

The final image is generated by the imx-mkimage project, the tool combines all
the input images in a FIT structure, generating a flash.bin image with an
appropriate IVT set.

For a secure boot process users should ensure all images included in flash.bin
file are covered by a digital signature.

- The diagram below illustrate a signed flash.bin image layout:

                     +-----------------------------+
                     |                             |
                     |     *Signed HDMI/DP FW      |
                     |                             |
                     +-----------------------------+
                     |           Padding           |
             ------- +-----------------------------+ --------
                 ^   |          IVT - SPL          |   ^
          Signed |   +-----------------------------+   |
           Data  |   |        u-boot-spl.bin       |   |
                 |   |              +              |   |  SPL
                 v   |           DDR FW            |   | Image
             ------- +-----------------------------+   |
                     |      CSF - SPL + DDR FW     |   v
                     +-----------------------------+ --------
                     |           Padding           |
             ------- +-----------------------------+ --------
          Signed ^   |          FDT - FIT          |   ^
           Data  |   +-----------------------------+   |
                 v   |          IVT - FIT          |   |
             ------- +-----------------------------+   |
                     |          CSF - FIT          |   |
             ------- +-----------------------------+   |
                 ^   |       u-boot-nodtb.bin      |   |  FIT
                 |   |               +             |   | Image
                 |   |          u-boot.bin         |   |
          Signed |   +-----------------------------+   |
           Data  |   |       OP-TEE (Optional)     |   |
                 |   +-----------------------------+   |
                 |   |        bl31.bin (ATF)       |   |
                 |   +-----------------------------+   |
                 v   |          u-boot.dtb         |   v
             ------- +-----------------------------+ --------
  * Only supported on i.MX8M series

The boot flow on i.MX8M and i.MX8MM devices are slightly different when compared
with i.MX6 and i.MX7 series, the diagram below illustrate the boot sequence
overview:

- i.MX8M and i.MX8MM devices boot flow:

                  Secure World                     Non-Secure World
                                         |
                                         |
  +------------+      +------------+     |
  |     SPL    |      | i.MX 8M/MM |     |
  |      +     | ---> |    ROM     |     |
  |   DDR FW   |      |   + HAB    |     |
  +------------+      +------------+     |
                             |           |
                             v           |
                      +------------+     |
                      |  *Signed   |     |
                      | HDMI/DP FW |     |
                      +------------+     |
                             |           |
                             v           |
  +------------+      +------------+     |
  | FIT Image: |      |     SPL    |     |
  | ATF + TEE  | ---> |      +     |     |
  |  + U-Boot  |      |   DDR FW   |     |      +-----------+
  +------------+      +------------+     |      |   Linux   |
                             |           |      +-----------+
                             v           |            ^
                      +------------+     |            |             +-------+
                      |    ARM     |     |      +-----------+       | Linux |
                      |  Trusted   | ----+--->  |   U-Boot  |  <--- |   +   |
                      |  Firmware  |     |      +-----------+       |  DTB  |
                      +------------+     |                          +-------+
                             |           |
                             v           |
                       +----------+      |
                       | **OP-TEE |      |
                       +----------+      |
  * Only supported on i.MX8M series
  ** Optional

On i.MX8M devices the HDMI firmware or DisplayPort firmware are the first image
to boot on the device. These firmwares are signed and distributed by NXP, and
are always authenticated regardless of security configuration. In case not
required by the application the HDMI or DisplayPort controllers can be disabled
by eFuses and the firmwares are not required anymore.

The next images are not signed by NXP and users should follow the signing
procedure as described in this document.

The Second Program Loader (SPL) and DDR firmware are loaded and authenticated
by the ROM code, these images are executed in the internal RAM and responsible
for initializing essential features such as DDR, UART, PMIC and clock
enablement.

Once the DDR is available, the SPL code loads all the images included in the
FIT structure to their specific execution addresses, the HAB APIs are called
to extend the root of trust, authenticating the U-Boot, ARM trusted firmware
(ATF) and OP-TEE (If included).

The root of trust can be extended again at U-Boot level to authenticate Kernel
and M4 images.

1.2 Enabling the secure boot support in U-Boot
-----------------------------------------------

The first step is to generate an U-Boot image supporting the HAB features,
similar to i.MX6 and i.MX7 series the U-Boot provides extra functions for
HAB, such as the HAB status logs retrievement through the hab_status command
and support to extend the root of trust.

The support is enabled by adding the CONFIG_SECURE_BOOT to the build
configuration:

- Defconfig:

  CONFIG_SECURE_BOOT=y

- Kconfig:

  ARM architecture -> Support i.MX HAB features

1.3 Preparing the fit image
----------------------------

The imx-mkimage project is used to combines all the images in a single
flash.bin binary, the following files are required:

- U-Boot:
  u-boot.bin
  u-boot-nodtb.bin
  u-boot-spl.bin
  U-Boot DTB file (e.g. fsl-imx8mq-evk.dtb)

- ATF image:
  bl31.bin

- DDR firmware:
  lpddr4_pmu_train_1d_dmem.bin
  lpddr4_pmu_train_1d_imem.bin
  lpddr4_pmu_train_2d_dmem.bin
  lpddr4_pmu_train_2d_imem.bin

- HDMI firmware (Only in i.MX8M):
  signed_hdmi_imx8m.bin

- DisplayPort firmware (Only in i.MX8M):
  signed_dp_imx8m.bin

- OP-TEE (Optional):
  tee.bin

The procedure to build ATF and download the firmwares are out of the scope
of this document, please refer to the Linux BSP Release Notes and AN12212[2]
for further details.

Copy all files to iMX8M directory and run the following command according to
the target device, on this example we are building a HDMI target and also
including the OP-TEE binary:

- Assembly flash.bin binary:

  $ make SOC=<SoC Name> flash_hdmi_spl_uboot

The mkimage log can be used to calculate the authenticate image command
parameters and CSF offsets:

- imx-mkimage build log:

  Loader IMAGE:
   header_image_off 	0x1a000
   dcd_off 		0x0
   image_off 		0x1a040
   csf_off 		0x44600
   spl hab block: 	0x7e0fd0 0x1a000 0x2e600

  Second Loader IMAGE:
   sld_header_off 	0x57c00
   sld_csf_off 		0x58c20
   sld hab block: 	0x401fcdc0 0x57c00 0x1020

Additional HAB information is provided by running the following command:

- Printing HAB FIT information:

  $ make SOC=<SoC Name> print_fit_hab

  TEE_LOAD_ADDR=0xfe000000 ATF_LOAD_ADDR=0x00910000 ./print_fit_hab.sh \
  0x60000 fsl-imx8mq-evk.dtb
  0x40200000 0x5AC00 0x9AAC8
  0x910000 0xF56C8 0x9139
  0xFE000000 0xFE804 0x4D268
  0x4029AAC8 0x14BA6C 0x6DCF

1.4 Creating the CSF description file
--------------------------------------

The CSF contains all the commands that the ROM executes during the secure
boot. These commands instruct the HAB code on which memory areas of the image
to authenticate, which keys to install, use and etc.

CSF examples are available under doc/imx/habv4/csf_examples/ directory.

As explained in sections above the SPL is first authenticated by the ROM code
and the root of trust is extended to the FIT image, hence two CSF files are
necessary to completely sign an flash.bin image.

The build log provided by imx-mkimage can be used to define the "Authenticate
Data" parameter in CSF.

- SPL "Authenticate Data" addresses in flash.bin build log:

  spl hab block: 0x7e0fd0 0x1a000 0x2e600

- "Authenticate Data" command in csf_spl.txt file:

  Blocks = 0x7e0fd0 0x1a000 0x2e600 "flash.bin"

- FIT image "Authenticate Data" addresses in flash.bin build log:

  sld hab block: 0x401fcdc0 0x57c00 0x1020

- FIT image "Authenticate Data" addresses in print_fit_hab build log:

  0x40200000 0x5AC00 0x9AAC8
  0x910000 0xF56C8 0x9139
  0xFE000000 0xFE804 0x4D268
  0x4029AAC8 0x14BA6C 0x6DCF

- "Authenticate Data" command in csf_fit.txt file:

  Blocks = 0x401fcdc0 0x057c00 0x01020 "flash.bin", \
           0x40200000 0x05AC00 0x9AAC8 "flash.bin", \
           0x00910000 0x0F56C8 0x09139 "flash.bin", \
           0xFE000000 0x0FE804 0x4D268 "flash.bin", \
           0x4029AAC8 0x14BA6C 0x06DCF "flash.bin"

1.4.1 Avoiding Kernel crash in closed devices
----------------------------------------------

For devices prior to HAB v4.4.0, the HAB code locks the Job Ring and DECO
master ID registers in closed configuration. In case the user specific
application requires any changes in CAAM MID registers it's necessary to
add the "Unlock CAAM MID" command in CSF file.

The current NXP BSP implementation expects the CAAM registers to be unlocked
when configuring CAAM to operate in non-secure TrustZone world.

The Unlock command is already included by default in the signed HDMI and
DisplayPort firmwares, on i.MX8MM devices or in case the HDMI or DisplayPort
controllers are disabled, users must ensure this command is included in SPL CSF.

- Add Unlock MID command in csf_spl.txt:

  [Unlock]
      Engine = CAAM
      Features = MID

1.5 Signing the flash.bin binary
---------------------------------

The CST tool is used for singing the flash.bin image and generating the CSF
binary. Users should input the CSF description file created in the step above
and receive a CSF binary, which contains the CSF commands, SRK table,
signatures and certificates.

- Create SPL CSF binary file:

 $ ./cst -i csf_spl.txt -o csf_spl.bin

- Create FIT CSF binary file:

 $ ./cst -i csf_fit.txt -o csf_fit.bin

1.6 Assembling the CSF in flash.bin binary
-------------------------------------------

The CSF binaries generated in the step above have to be inserted into the
flash.bin image.

The CSF offsets can be obtained from the flash.bin build log:

- SPL CSF offset:

  csf_off 0x44600

- FIT CSF offset:

  sld_csf_off 0x58c20

The signed flash.bin image can be then assembled:

- Create a flash.bin copy:

  $ cp flash.bin signed_flash.bin

- Insert csf_spl.bin in signed_flash.bin at 0x44600 offset:

  $ dd if=csf_spl.bin of=signed_flash.bin seek=$((0x44600)) bs=1 conv=notrunc

- Insert csf_fit.bin in signed_flash.bin at 0x58c20 offset:

  $ dd if=csf_fit.bin of=signed_flash.bin seek=$((0x58c20)) bs=1 conv=notrunc

- Flash signed flash.bin image:

  $ sudo dd if=signed_flash.bin of=/dev/sd<x> bs=1K seek=33 && sync

1.7 Programming SRK Hash
-------------------------

As explained in AN4581[1] and in introduction_habv4.txt document the SRK Hash
fuse values are generated by the srktool and should be programmed in the
SoC SRK_HASH[255:0] fuses.

Be careful when programming these values, as this data is the basis for the
root of trust. An error in SRK Hash results in a part that does not boot.

The U-Boot fuse tool can be used for programming eFuses on i.MX SoCs.

- Dump SRK Hash fuses values in host machine:

  $ hexdump -e '/4 "0x"' -e '/4 "%X""\n"' SRK_1_2_3_4_fuse.bin
  0x20593752
  0x6ACE6962
  0x26E0D06C
  0xFC600661
  0x1240E88F
  0x1209F144
  0x831C8117
  0x1190FD4D

- Program SRK_HASH[255:0] fuses on i.MX8MQ and i.MX8MM devices:

  => fuse prog 6 0 0x20593752
  => fuse prog 6 1 0x6ACE6962
  => fuse prog 6 2 0x26E0D06C
  => fuse prog 6 3 0xFC600661
  => fuse prog 7 0 0x1240E88F
  => fuse prog 7 1 0x1209F144
  => fuse prog 7 2 0x831C8117
  => fuse prog 7 3 0x1190FD4D


1.8 Verifying HAB events
-------------------------

The next step is to verify that the signatures included in flash.bin image is
successfully processed without errors. HAB generates events when processing
the commands if it encounters issues.

The hab_status U-Boot command call the hab_report_event() and hab_status()
HAB API functions to verify the processor security configuration and status.
This command displays any events that were generated during the process.

Prior to closing the device users should ensure no HAB events were found, as
the example below:

- Verify HAB events:

  => hab_status

  Secure boot disabled

  HAB Configuration: 0xf0, HAB State: 0x66

1.9 Closing the device
-----------------------

After the device successfully boots a signed image without generating any HAB
events, it is safe to close the device. This is the last step in the HAB
process, and is achieved by programming the SEC_CONFIG[1] fuse bit.

Once the fuse is programmed, the chip does not load an image that has not been
signed using the correct PKI tree.

- Program SEC_CONFIG[1] fuse on i.MX8MQ and i.MX8MM devices:

  => fuse prog 1 3 0x2000000

1.10 Completely secure the device
----------------------------------

Additional fuses can be programmed for completely secure the device, more
details about these fuses and their possible impact can be found at AN4581[1].

- Program SRK_LOCK:

  => fuse prog 0 0 0x200

- Program DIR_BT_DIS:

  => fuse prog 1 3 0x8000000

- Program SJC_DISABLE:

  => fuse prog 1 3 0x200000

- JTAG_SMODE:

  => fuse prog 1 3 0xC00000

2. Authenticating additional boot images
-----------------------------------------

The High Assurance Boot (HAB) code located in the on-chip ROM provides an
Application Programming Interface (API) making it possible to call back
into the HAB code for authenticating additional boot images.

The U-Boot is running in non-secure TrustZone world and to make use of this
feature it's necessary to use a SIP call to the ATF, this is already
implemented in hab.c code and it's transparent to the user.

The process of signing an additional image is similar as in i.MX6 and i.MX7
series devices, the steps below are using the Linux Kernel image as example.

The diagram below illustrate the Image layout:

            ------- +-----------------------------+ <-- *load_address
                ^   |                             |
                |   |                             |
                |   |                             |
                |   |                             |
                |   |            Image            |
         Signed |   |                             |
          Data  |   |                             |
                |   |                             |
                |   +-----------------------------+
                |   |    Padding to Image size    |
                |   |          in header          |
                |   +-----------------------------+ <-- *ivt
                v   |     Image Vector Table      |
            ------- +-----------------------------+ <-- *csf
                    |                             |
                    | Command Sequence File (CSF) |
                    |                             |
                    +-----------------------------+
                    |     Padding (optional)      |
                    +-----------------------------+

2.1 Padding the image
----------------------

The Image must be padded to the size specified in the Image header, this can be
achieved by using the od command.

- Read Image size:

  $ od -x -j 0x10 -N 0x4 --endian=little Image
  0000020 5000 0145
  0000024

The tool objcopy can be used for padding the image.

- Pad the Image:

  $ objcopy -I binary -O binary --pad-to 0x1455000 --gap-fill=0x00 \
	Image Image_pad.bin

2.2 Generating Image Vector Table
----------------------------------

The HAB code requires an Image Vector Table (IVT) for determining the image
length and the CSF location. Since Image does not include an IVT this has
to be manually created and appended to the end of the padded Image, the
script genIVT.pl in script_examples directory can be used as reference.

- Generate IVT:

  $ genIVT.pl

Note: The load Address may change depending on the device.

- Append the ivt.bin at the end of the padded Image:

  $ cat Image_pad.bin ivt.bin > Image_pad_ivt.bin

2.3 Signing the image
----------------------

A CSF file has to be created to sign the image. HAB does not allow to change
the SRK once the first image is authenticated, so the same SRK key used in
the initial image must be used when extending the root of trust.

CSF examples are available in ../csf_examples/additional_images/ directory.

- Create CSF binary file:

  $ ./cst --i csf_additional_images.txt --o csf_Image.bin

- Attach the CSF binary to the end of the image:

  $ cat Image_pad_ivt.bin csf_Image.bin > Image_signed.bin

2.4 Verifying HAB events
-------------------------

The U-Boot includes the hab_auth_img command which can be used for
authenticating and troubleshooting the signed image, the Image must be
loaded at the load address specified in the IVT.

- Authenticate additional image:

  => hab_auth_img <Load Address> <Image Size> <IVT Offset>

If no HAB events were found the Image is successfully signed.

References:
[1] AN4581: "Secure Boot on i.MX 50, i.MX 53, i.MX 6 and i.MX 7 Series using
 HABv4" - Rev 2.
[2] AN12212: "Software Solutions for Migration Guide from Aarch32 to
Aarch64" - Rev 0.