AIMLinux/AddOn/Security

From ESS-WIKI
Revision as of 09:09, 16 March 2020 by Yanwei.cao (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Security is becoming a growing concern, especially when these devices connecte to the Internet,how to protect data from tampering, how to protect FW from malicious damage, how to ensure that the device can start safely... these are security considerations. This topic mainly introduces the Security Boot mechanism.

Security Boot[edit]

For security consideration, it is necessary that the hardware have some mechanism to ensure that the software it is running can be trusted. NXP i.MX6 series chip provides High Assurance Boot (HAB) feature which meets such a requirement. OEM can utilize it to make their product reject any system image which is not authorized for running. You can refer the " i.MX_6_Linux_High_Assurance_Boot_(HAB)_User's_Guide.pdf" file to learn more about HAB introduction,in this topic,we mainly introduce how to implement and test security boot.

Signature

Setup CST enviroment

1.Unpack the Code Siging Tools (CST) package (cst-2.3.2.tar.gz)

2.cd cst-2.3.2/keys

  • Create a text file called serial, which contains 8 digits. For example: Fill in "12356789" to the serial file
  • Create a text file called key_pass.txt, which contains two lines of identical text, such as "advantech_test". For example:
    ~/cst-2.3.2/keys$ cat key_pass.txt
    advantech_test
    advantech_test
  • ./hab4_pki_tree.sh
  • You can now create the signature keys. This script will generate private key and public key pairs in the working directory. For question prompt, enter "n", "n", "4096", "10", "4", "y" one by one.

3.cd ../crts

  • ../linux64/srktool -h 4 -t SRK_1_2_3_4_table.bin -e SRK_1_2_3_4_fuse.bin -d sha256 -c ./SRK1_sha256_4096_65537_v3_ca_crt.pem,./SRK2_sha256_4096_65537_v3_ca_crt.pem,./SRK3_sha256_4096_65537_v3_ca_crt.pem,./SRK4_sha256_4096_65537_v3_ca_crt.pem -f 1
  • Create the fuse table and binary to be flashed later. This command will generate root public key file "SRK_1_2_3_4_table.bin" and its corresponding hash "SRK_1_2_3_4_fuse.bin". The content of the latter will be later on burned to chip eFuse. NOTE: Don't leave space between the pem file names. Otherwise the generated SRK table and fuse file will not be correct.
  • Show "SRK_1_2_3_4_fuse.bin" information. For example:
    ~/cst-2.3.2/crts$ hexdump -C SRK_1_2_3_4_fuse.bin
    00000000 79 f5 61 26 6f cd d4 e9 ae d2 06 ff 5b f8 ea 40  |y.a&o.......[..@|
    00000010 01 1c 32 97 0e e3 6b b0?13 c0 1e c8 88 eb 37 cc  |..2...k.......7.|
    00000020

Build secure images

1.Build uboot and kernel image for i.MX6 project (For example: RSB-4411 project). 

  • You can refer following URL to set up cross compiling environment (Setting up cross compiling environment):

           http://ess-wiki.advantech.com.tw/view/IoTGateway/BSP/Linux/iMX6/Yocto_LBV8_User_Guide#Setting_up_cross_compiling_environment

2.get and build u-boot image

  • git clone https://github.com/ADVANTECH-Corp/uboot-imx6.git -b  imx_v2016.03_4.1.15_2.0.0_ga
  • cd uboot-imx6/
  • source environment for Yocto 2.1:source /opt/poky/2.1/environment-setup-cortexa9hf-neon-poky-linux-gnueabi
  • Make sure the following message is defined in "./include/configs/mx6xxxx.h" (For example: mx6rsb4411.h).

            /* uncomment for SECURE mode support */
           #define CONFIG_SECURE_BOOT

          #ifdef CONFIG_SECURE_BOOT
          #ifndef CONFIG_CSF_SIZE
          #define CONFIG_CSF_SIZE 0x4000
          #endif
          #endif

  • Build SPL and u-boot image for i.MX6 project (For example: RSB-4411 project)

          make mx6qrsb4411a1_1G_defconfig
          make -j4 V=1 u-boot.imx all

  • You can get SPL (SPL) image and u-boot (u-boot_crc.bin, u-boot_crc.bin.crc) image in uboot-imx6/ directory

3.get and build kernel image

  • git clone https://github.com/ADVANTECH-Corp/linux-imx6.git -b imx_4.1.15_2.0.0_ga
  • cd linux-imx6/
  • source environment for Yocto 2.1
    source /opt/poky/2.1/environment-setup-cortexa9hf-neon-poky-linux-gnueabi
  • Build zImage:
    make imx_v7_adv_defconfig
    make -j 4 zImage
  • You can get zImage image in /arch/arm/boot/zImage directory



Sign uboot image

1.Copy SPL (SPL) and u-boot (u-boot_crc.bin, u-boot_crc.bin.crc) images to ~/cst-2.3.2/linux64 directory

2.Copy spl.csf to ~/cst-2.3.2/linux64 directory

  • We will use the “HAB Blocks” information from previous section. Build SPL image, message:
  • ./tools/mkimage -n board/freescale/mx6advantech/mx6qrsb4411a1_4x_MT41K128M16JT-125_1410022609-01.cfg.cfgtmp -T imximage -e 0x00908000 -d spl/u-boot-spl.bin SPL 
    Image Type:   Freescale IMX Boot Image
    Image Ver:    2 (i.MX53/6/7 compatible)
    Mode:         DCD
    Data Size:    57344 Bytes = 56.00 kB = 0.05 MB
    Load Address: 00907420
    Entry Point:  00908000
    HAB Blocks:   00907400 00000000 00009c00
    DCD Blocks:   00910000 0000002c 00000320
  • Open "spl.csf" file to edit the size in the "Blocks = " line...

          Blocks = 0x907400 0x0 0x9C00 "SPL"

3.We provide a secure SPL image generation script "habsplimagegen.sh". Copy habsplimagegen.sh to ~/cst-2.3.2/linux64 directory

4../habsplimagegen.sh

  • This will create certified SPL image "spl_signed"

5.Copy "uboot_normal.csf" file to ~/cst-2.3.2/linux64 directory

  • We will use the “HAB Blocks” information from previous section. Build u-boot image, message:
    ./tools/mkimage -n board/freescale/mx6advantech/mx6qrsb4411a1_4x_MT41K128M16JT-125_1410022609-01.cfg.cfgtmp -T imximage -e 0x26800000 -d u-boot.bin u-boot.imx 
    ./tools/mkimage -A arm -T firmware -C none -O u-boot -a 0x26800000 -e 0 -n "U-Boot 2016.03-dirty for mx6advantech board" -d u-boot.bin u-boot.img 
    Image Type:   Freescale IMX Boot Image
    Image Ver:    2 (i.MX53/6/7 compatible)
    Mode:         DCD
    Data Size:    335872 Bytes = 328.00 kB = 0.32 MB
    Load Address: 267ff420
    Entry Point:  26800000
    HAB Blocks:   267ff400 00000000 0004dc00
    DCD Blocks:   00910000 0000002c 00000320
  • Open "uboot_normal.csf" file to edit the size in the "Blocks = " line...
    Blocks = 0x267FF400 0x0 0x4DC00 "u-boot_crc.bin"

6.We provide a secure u-boot image generation script " habubootimagegen.sh". Copy habubootimagegen.sh to ~/cst-2.3.2/linux64 directory

7../habubootimagegen.sh:This will create certified u-boot image "u-boot_normal_signed.bin".

Sign kernel image

1.Copy zImage to cst-2.3.2/linux64 directory

2.Copy genIVT file to cst-2.3.2/linux64 directory

  • Get zImage length
    hexdump -C zImage | tail -n 1
    Example log:
    00638f58
  • The hexdump command above allows to learn the zImage size. Then you can modify the genIVT to reflect the proper sizes, in our example, the size of the zImage was "638f58" so the next 4kB boundary was "0x639000" as you can see in the genIVT. We need to edit genIVT file.
  • Self Pointer: "0x10800000 + 0x639000 = 0x10E39000"
    print $out pack("V", 0x10E39000); # Self Pointer
  • CSF Pointer: 0x10E39000 + 0x20
    print $out pack("V", 0x10E39020); # CSF Pointer

3.Copy "zImage.csf" file to cst-2.3.2/linux64 directory

4.The "zImage.csf" file for the zImage in order to create the CSF blob and generate the signed image.

  • Edit the size in the "Blocks = " line...
    Blocks = 0x10800000 0x0 0x639020 "zImage-pad-ivt.bin"

5.Copy "habZimagegen.sh" file to cst-2.3.2/linux64 directory

  • We need to edit habZimagegen.sh file
    echo "extend zImage to 0x639000..."
    objcopy -I binary -O binary --pad-to=0x639000 --gap-fill=0x00 zImage zImage-pad.bin

6.Execute "habZimagegen.sh" to generate "zImage_signed" file.

./ habZimagegen.sh

Burn

1.Copy "spl_signed", "u-boot_crc.bin.crc", "u-boot_normal_signed.bin", " zImage_signed " to USB disk

2.Burn the chip fuse to enable HAB boot

  • The fuse table generated in the third point is what needs to be flashed to the device. However, the hexdump command above doesn’t show the values in their correct endianness, instead the command below will be more useful.
  • The following command gives you what needs to be flashed in the proper order. Dump the content of the eFuse file in ~/cst-2.3.2/crts directory. They will be burned to chip with kernel utilities.

          hexdump -e '/4 "0x"' -e '/4 "%X""\n"' < SRK_1_2_3_4_fuse.bin

          Log message:
          0x2661F579
          0xE9D4CD6F
          0xFF06D2AE
          0x40EAF85B
          0x97321C01
          0xB06BE30E
          0xC81EC013
          0xCC37EB88

  • !!! CAUTION!!! Make sure you perform all the steps correctly. Otherwise you may damage a chip permanently. It is strongly recommended that a socket board is used, so in the worst case scenario, we can change a chip without totally damaging the board.
  • Normal boot into kernel.
  • cd /sys/fsl_otp
  • Use the 8 dwords generated in last step and burn them to SRK fuse one by one.
    echo 0x2661F579 > HW_OCOTP_SRK0
    echo 0xE9D4CD6F > HW_OCOTP_SRK1
    echo 0xFF06D2AE > HW_OCOTP_SRK2
    echo 0x40EAF85B > HW_OCOTP_SRK3
    echo 0x97321C01 > HW_OCOTP_SRK4
    echo 0xB06BE30E > HW_OCOTP_SRK5
    echo 0xC81EC013 > HW_OCOTP_SRK6
    echo 0xCC37EB88 > HW_OCOTP_SRK7
  • Verify that the correct value has been burned. Type command:
    ls | grep "SRK.$" | xargs cat
    Log message:
    …/sys/fsl_otp# ls | grep "SRK.$" | xargs cat
    0x2661f579
    0xe9d4cd6f
    0xff06d2ae
    0x40eaf85b
    0x97321c01
    0xb06be30e
    0xc81ec013
    0xcc37eb88

3.Insert USB disk to the device. Suppose the USB disk path is /run/media/sda1

4.Burn the secure SPL image (spl_signed) to SPI.

cd /run/media/sda1
flash_erase /dev/mtd0 0 192
dd if=spl_signed of=/dev/mtd0 bs=512 seek=2
sync

5.Burn the secure u-boot image (u-boot_normal_signed.bin, u-boot_crc.bin.crc) to emmc.

dd if=u-boot_crc.bin.crc of=/dev/mmcblk0 bs=512 seek=2 conv=fsync
dd if=u-boot_normal_signed.bin of=/dev/mmcblk0 bs=512 seek=3 conv=fsync
sync

6.Burn the secure kernel image "zImage_signed" to emmc.

cp zImage_signed /dev/mmcblk0p1/zImage
sync

7.At this point the whole HAB chain is not actually enabled, because the default chip secure config is "open" which ignores any authentication error and continues the boot process. We will enable it in the next step.

Test

1.Boot the device again and press "Enter" key to stay in the u-boot stage

Adv-Boot SPL 2016.03 (Nov 08 2017 - 14:17:25)
BOOT_DEVICE_AUTO
MMC read: dev # 0, block # 3,count 1200 ...
booting from SD
Jumping to U-Boot

U-Boot 2016.03 (Nov 08 2017 - 14:17:25 +0800)

CPU:   Freescale i.MX6D rev1.5 at 792MHz
CPU:   Industrial temperature grade (-40C to 105C) at 37C
.......
Net:   Board Net Initialization Failed
No ethernet found.
Normal Boot
Hit any key to stop autoboot:  0
=>

  • Check hab status for u-boot when HAB disabled. The following message is a correct status.
    => hab_status
    Secure boot disabled
    HAB Configuration: 0xf0, HAB State: 0x66
    No HAB Events Found!
  • Modify U-Boot bootcmd so it includes the HAB command that checks the kernel:
    => load mmc 0 10800000 zImage
    log:
    reading zImage
    6015320 bytes read in 294 ms (19.5 MiB/s)
  • After you type following command: if the device is "open", you will see following message:
    => hab_auth_img 10800000 0x639000
    log:
    hab fuse not enabled

2.Turn on chip HAB.

  • !!! CAUTION !!! Make sure you perform all the steps correctly. After this step, there will be no way back, and a chip may permanently be bricked.
  • Normal boot into kernel.
  • cd /sys/fsl_otp
  • Turn on RNG_TRIM
    echo 0x00040000 > HW_OCOTP_MEM0
  • See hab status for device "open":
    cat HW_OCOTP_CFG5
    log:
    0x0
  • Put SEC_CONFIG to close (turn on chip security).
    echo 0x2 > HW_OCOTP_CFG5
  • See hab status for device "close":
    cat HW_OCOTP_CFG5
    log:
    0x2

3.Boot the device again and press "Enter" key to stay in the u-boot stage. The security patch should work now.

  • Successful authentication will give the following dump message in U-Boot load. Check hab status for u-boot when HAB enabled. The following message is a correct status.
    => hab_status
    Log:
    Secure boot enabled
    HAB Configuration: 0xcc, HAB State: 0x99
    No HAB Events Found!
  • Modify U-Boot bootcmd so it includes the HAB command that checks the kernel:
    => load mmc 0 10800000 zImage
    log:
    reading zImage
    6015320 bytes read in 294 ms (19.5 MiB/s)
  • After typing following command: if the device is "close", will see following message. Successful authentication will give the following dump message in zImage load:
    => hab_auth_img 10800000 0x639000
    log:
    Authenticate image from DDR location 0x10800000...
    Secure boot enabled
    HAB Configuration: 0xcc, HAB State: 0x99
    No HAB Events Found!
  • set and save loading kernel image address
    => setenv loadaddr 10800000
    => saveenv
    log:
    Saving Environment to SPI Flash...
    JEDEC ID: 0xef:0x40:0x16
    Erasing SPI flash...Writing to SPI flash..................................SUCCESS
    .................................................................................
    done
  • Boot the device again. The security patch should work now. Successful authentication will give the following dump message in zImage load:
    ...
    ...
    Kernel image @ 0x10800000 [ 0x000000 - 0x638f58 ]
    ## Flattened Device Tree blob at 18000000
      Booting using the fdt blob at 0x18000000
    Authenticate image from DDR location 0x10800000...
    Secure boot enabled
    HAB Configuration: 0xcc, HAB State: 0x99
    No HAB Events Found!
      Using Device Tree in place at 18000000, end 1800e5df
    Starting kernel ...