Jump to content
  • 0

H3-Soc boot rom security & E-Fuse


Ravikumar
 Share

Question

Hi,

 

I bought nanopi_neo boards (for my hobby projects). I am learning about security.

I am able to dump e-Fuse area at uboot stage. But i can't modify it (i want to write my own key). I don't have any memory map information of e-fuse.

 

In present boards, bootROM is not verifying the uboot signature(RSA sign:-)). 

1) How to enable signature verification in bootROM?

2) Is there any code or information regarding BootROM security and e-Fuse area mapping?

3) Is there any support of TEE (Trusted execution environment)?

 

 

Link to comment
Share on other sites

Recommended Posts

Check forum guidelines to use maximum potential!

  • 0
On 6/5/2019 at 9:11 PM, spitfire said:

Hi Team,

 

Nice conversion regarding to secure boot for H3.

From this reference, I am trying to enable secure boot in H6 SoC (Orange pi3). I have followed steps as given by @xeniter

 

1. Instead of generating private key using openssl, I have used same private key as used by @spitfire. Please find key file.
2. Generate SHA256 of public key using ruby script.
3. Enable and write a SHA256 of public key into eFuse using ruby script with help of FEL mode.
4. Sign SPL image using ruby script

    


$ ruby gen_toc0.rb privatekey.pem  sunxi-spl.bin sunxi-spl.toco

NOTE: Used entry address (run_addr = 0x20000) according to H6 SoC

5. Written signed image into sdcard

    


$ sudo dd if=unxi-spl.toco of=/dev/sdb bs=1024 seek=8

After performed the above steps on board, board is sucked on booting of SPL image. There are nothing to print on serial console. Please find attached script and SPL image file. Please help me out the problem, What i am doing wrong?

 

Any help would be appreciable.

 

Thanks,
Pratik

 

Edited by Pratik
How to add attachment.
Link to comment
Share on other sites

  • 0

how did you you written the key? could you post fel code?

 

assume the felscript to burn fuses will not work for H6 cause the sid register are now on 0x03006000  instead at 0x01C14000  (see https://linux-sunxi.org/images/4/46/Allwinner_H6_V200_User_Manual_V1.1.pdf)

So you need adjust at least the sid part of the script, also there some new efuses for changing boot order. would double check if its not necessary to set them.

 

yours,

xeniter

 

Link to comment
Share on other sites

  • 0
4 hours ago, xeniter said:

how did you you written the key? could you post fel code?

 

assume the felscript to burn fuses will not work for H6 cause the sid register are now on 0x03006000  instead at 0x01C14000  (see https://linux-sunxi.org/images/4/46/Allwinner_H6_V200_User_Manual_V1.1.pdf)

So you need adjust at least the sid part of the script, also there some new efuses for changing boot order. would double check if its not necessary to set them.

 

yours,

xeniter

 

Hi Xeniter, Replying on behalf of Pratik.  Thank you for quick reply.


We followed below steps. We also took care of addressing for H6 SoC.
 

1. We used the private key of @spitfire and generate public key from that.  Private key can be found here.

$ openssl rsa -in privkey.pem -pubout -out pubkey.pem // Public key

2. Took jemk script from https://gist.github.com/jemk/8e1006a44c7a2c796fc3fc2f74f7c6c3/revisions

Using mkrotpk.rb script, computed SHA256 of public key.  We can also use your described method to generate ROTPK. Both generate the same output.

$ ruby mkrotpk.rb pubkey.pem rotpk.bin

We got ROTPK in hex format as:

1A18E6E98F9AB15F626E1DF9D89F2B659EE87335213D9C6F4729F9A8C56A32F5


3. Now, We used fel_write_key.sh script to write rotpk hash (in little endian format) and secure bit into eFuse with help of "sunxi-fel" using fel_write_key.sh script. 

(Note: At first we wrote 0x8000 by mistake in LCJS field and then we modified script to make it to 0x800. So after reading, we are getting 0x8800. This shouldn't be a problem as per LCJS format, I guess). 

$ ./fel_write_key.sh

4. We read back all values to confirm whether they are written perfectly or not. We used eFuseReaderr.c to read eFuse values. We got following output. Output looks OK.

Hello from Allwinner H6!
chip_id: 82c00007:3c004708:140dd58:8761f91:
rotpk_hash: e9e6181a:5fb19a8f:f91d6e62:652b9fd8:3573e89e:6f9c3d21:a8f92947:f5326ac5:
LCJS: 00008800:
try read sram A2:0x40004!=0 secure

Returning back to FEL.

5. Then we used mktoc0.rb jemk script from https://gist.github.com/jemk/2abcab1359c4bce793679c5854062331.

NOTE: Before executing a script, following changes are required in mktoc0.rb.

    1. Replace the ".sum" method with ".reduce(:+)" at line number 139 
    2. Change entry address of H6 from 0x0 to 0x20000 at line number 167, because entry address of H6 is 0x20000.

You can find updated mktoc0.rb here.
- Using that mktoc0.rb script, converted spl image from bin format to TOC0 format.

$ ruby mktoc0.rb privkey.pem sunxi-spl.bin sunxi-spl.toc0

6. Flash sunxi-spl.toc0 file into sdcard:

    $ sudo dd if=/dev/zero of=/dev/sdX bs=1k count=1023 seek=1
    $ sudo dd if=sunxi-spl.toc0 of=/dev/sdX bs=1024 seek=8

Output: After writing TOC0 image into sdcard, insert the sdcard with board. Board is stucked on booting of SPL image.  There are no prints in serial console.

 

Regards,

Nilesh Vora

Edited by Nilesh Vora
Proper Formatting
Link to comment
Share on other sites

  • 0

hi,

 

have an issue with booting from toc that sound does not work anymore, have anyone same issue?

only when booting with u-boot with sec mode (setenv bootm_boot_mode sec;) its working again,

however in that case the linux system has only one cpu core available.

 

edit:

sound did not work cause dma did not work, per default dma are disabled, you can enable it via the DMA Security Register.

 

yours,

xeniter

Edited by xeniter
new information
Link to comment
Share on other sites

  • 0

Hello guys.

Thanks to the instructions of @xeniter and @janng0 i was able to burn the fuses in my nanopi neo core and make a SD card bootable with it.

I tried to reproduce this for the internal eMMC of the nanopi neo core but boot process got stuck with

 

U-Boot SPL 2020.10-armbian (Dec 11 2020 - 23:42:28 +0100)
DRAM: 512 MiB
Trying to boot from MMC1
MMC: no card present
spl: mmc init failed with error: -123
SPL: failed to boot from all boot devices
### ERROR ### Please RESET the board ###

 Any clue whats wrong?

Link to comment
Share on other sites

  • 0

As i understand MMC1 stands for SD-Card and MMC2 is the internal eMMC.

What I don't understand is:

Another board without ROTPK burned to eFUSES will try to start from MMC2 when there is no SD inserted.

But the board with ROTPK burned to eFUSES and the right TOC0 on eMMC does not try to boot from MMC2 when no SD is inserted. Instead it hangs trying to boot from MMC1. I am positiv that BROM is reading the TOC0 from eMMC because before i wrote TOC0 to eMMC there was no output from the board when trying to boot from eMMC and i guess it is because of the missing correct key.

Only a SD with the correct TOC0 will boot on this board.

 

Did i disabled MMC2 with burning the eFUSES or is TOC0 preventing booting from MMC2?

Link to comment
Share on other sites

  • 0

Hi, Thank you for the great post on the H3.

I'm trying to repeat the steps on the H5. I've successfully build u-boot, linux 5.1 and ubuntu 21.04 rootfs for the H5.

I'm investigating secure boot as discussed here for the H3. My u-boot is printing its boot log on UART0. I assume my H5 (orangePi Zero+) and USB serial UART

is working correctly. UART set to 115200  8-N-1.

 

I've taken a detour to compile uart0-helloworld-sdboot.c using the 64-bit bare-metal compiler (aarch64-none-elf-gcc), but it fails on the assembler instruction at

line 278: "asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (midr));". Some googling revealed that the 64 bit instruction set does not support the "mcr" instruction.

A bit of reading at https://linux-sunxi.org/Arm64#Boot_modes revealed that the core starts up in 32 bit mode and the BROM & u-boot is standard 32-bit code.

Therefore, the 32-bit bare-metal compiler (arm-none-eabi-gcc) should be used.

 

I've recompiled uart0-helloworld-sdboot.c as follow, without getting any compiler errors:

CROSS_COMPILE=arm-none-eabi- make uart0-helloworld-sdboot.elf

 

I've started up the H5 without the SD card and can see that its present on the USB port in FEL mode:

$ lsusb

  ID 1f3a:efe8 Allwinner Technology sunxi SoC OTG connector in FEL/flashing mode

 

Loading the image didn't report any error:

$ ./sunxi-fel -v -p write 0x2000 ./uart0-helloworld-sdboot.elf  
100% [================================================]    14 kB,  358.0 kB/s

 

Executing the image didn't report any error:

$ ./sunxi-fel -v exec 0x2000

 

However, nothing is printed on the UART0 port.

 

I'm wondering if the 0x2000 is the correct adres to load the image?

According to H5 writeup (https://linux-sunxi.org/H5) the memory map of the H3 and H5 is different:

       The H5 is basically an Allwinner H3 with the Cortex-A7 cores replaced with Cortex-A53 cores. The H3 has SRAM A1 mapped at address 0,

       the BROM is at 0xffff0000. The H5 (much like the A64) has its BROM mapped at address 0, SRAM A1 is mapped right behind it at 0x10000 (64KB).

 

I've tried to load the image & execute the image at 0x10000 (loading failed) and 0x12000 (loading succeeded), but no luck executing.

 

Inside uart0-helloworld-sdboot.c it does reference the H5, which suggests that the developer did manage to boot it on the H5.

 

Has anybody managed to get any success on the H5?

 

Regards,

Link to comment
Share on other sites

  • 0

Good day,

I've made some progress with the Allwinner H5:

 

Hallo World, via USB/FEL

----------------------------------

Changes required to the source code:

For H5, the RAM base is set to 0x10000. The firmwareID is written by the BROM in the first 0x24 bytes.

Set the application start address to 0x10060 so as not to overwrite it. The application must be 32-byte aligned.

$ cd sunxi_tools

$ vi uart0-helloworld-sdboot.c :   

   Line 527: if (soc_is_a64() || soc_is_a80() || soc_is_h5())

                       spl_signature = (void *)0x10064;

$ vi uart0-helloworld-sdboot.lds

    SECTIONS { . = 0x10060;

$ make binfiles

$ ./sunxi-fel -v -p write 0x10060 ./uart0-helloworld-sdboot.bin

   NOTE: Using the .bin file, not the .elf or .sunxi 

$ ./sunxi-fel -v exec 0x10060

The UART0 should show:

Hello from Allwinner H5! Returning back to FEL.

 

Hallo World, via SD

--------------------------

Note: This is for a H5 with the eFuses not yet been set.

Attach your SD card to the PC with a USB/SD card reader.

# dmesg

   Look at the end of the log to see under which /dev/sdX the device was mapped.

Backup the partition table, clear the first 8kb and restore the partition table.

WARNING: You can wipe your hard drive if you specify the wrong device. Make sure

you're pointing to the SD card. Replace sdX with the device number as reported above

by dmesg. Clearing the SD card only needs to be done once:

# dd if=/dev/sdX of=partitiontable.bin bs=1 skip=440 count=72
# dd if=/dev/zero of=/dev/sdX bs=1024 count=8
# dd if=partitiontable.bin of=/dev/sdX bs=1 seek=440 count=72

 

Write the application to the the SD card:

# cd sunxi-tools
# dd if=uart0-helloworld-sdboot.sunxi of=/dev/sdX seek=8 bs=1024

   NOTE: Using the .sunxi file, not the .bin or the .elf

 

Insert the SD card into the H5 and power it up. The UART0 should show:

  Hello from Allwinner H5!

  Returning back to FEL.

 

The application 'sunxi-bootinfo' has the following to say about the hello world application:

$ ./sunxi-bootinfo uart0-helloworld-sdboot.sunxi  
      4:       Magic     : eGON.BT0
     10:       Length    : 8192
     14:       HSize     : 38555731
     18:       HEAD ver  :  
     1c:       FILE ver  :  
     20:       BOOT ver  :  
     24:       eGON ver  :  
     28:       platform  :

     Unknown boot0 header version
Running sunxi-bootinfo on the .bin or .elf returned: Invalid magic

 

Generate keys

===========

$ cd h3_lichee/tools/pack

$ ./generate_keys

Output stored in common/keys/*

$ cd pctools/linux/openssl

$ PATH=".:$PATH" dragonsecboot -key ../../../common/sign_config/dragon_toc.cfg ../../../common/keys

   New file are created in “common/keys”: Trustkey.bin & rotpk.bin

 

Use okteta or another binary viewer to get the contents of rotpk.bin.

Navigate to the sunxi-tools

$ cd sunxi-tools

$ vi eFuse_burner.c

    Line 946: Paste the formatted contents of the rotpk at ‘rotpk_bin[]’,

To test the program, without writing the key to the e-fuses, comment out the command ‘sid_program_key()’ at ~line #969

 

$ make binfiles

 

Check if the board is in FEL mode

$ ./sunxi-fel version

Load binary into SRAM A1 on H5

$ ./sunxi-fel -v -p write 0x10060 ./eFuse_burner.bin
Run the code

$ ./sunxi-fel -v exec 0x10060

 

The UART0 should show:

board locked!
 

Hello world - TOC0 (eFuses)

======================

Using jemk script:

Parameters:

- Trustkey.pem - Root of Trust from which rootpk.bin was generated

- sboot.bin - Compiled binary SPL, for tests simply use uart0-helloworld-sdboot

- sboot.toc0 - Output file

 

Edit the script to place the app at 0x10060 for the H5:

$ cd scripts

$ vi jemk_mktoc0.rb

Line 167:

   toc0_code = TOC0Item.new(0x010202, code, TOC0Item::CODE, 0x00010060)
 

Convert the sunxi SD bootable version of the application to toc0:

$ ruby jemk_mktoc0.rb ../h3_lichee/tools/pack/common/keys/Trustkey.pem ../sunxi-tools/uart0-helloworld-sdboot.sunxi ../sunxi-tools/uart0-helloworld-sdboot.toc0

 

Attach your SD card to the PC with a USB/SD card reader. Note with dmesg where the device was mapped, i.e. /dev/sdc

Write the image to SD card:

# dd if=../sunxi-tools/uart0-helloworld-sdboot.toc0 of=/dev/sdX status=progress bs=1024 seek=8

 

Insert the SD card into the H5 with eFuses already burned. Power it up.

The UART0 should show:

   Hello from Allwinner H5!

   Booted from MMC0, entering an infinite loop.

 

 

U-Boot with SPL - TOC0 (eFuses)

==========================

Used a pre-tested u-boot binary that boots Linux on a H5 board without using the eFuses.

 

$ cd scripts

Sign the file:

$ ruby jemk_mktoc0.rb ../h3_lichee/tools/pack/common/keys/Trustkey.pem u-boot-sunxi-with-spl.bin u-boot-sunxi-with-spl.toc0

 

Write the image to SD card:

# dd if=u-boot-sunxi-with-spl.toc0 of=/dev/sdX status=progress bs=1024 seek=8

 

Insert the SD card into the H5 with the eFuses already burned. Power it up.

The UART0 should show:

  --The uboot boot prompt. However, nothing is displayed on the UART.

 

Looking at the attached USB devices, with 'lsusb', it shows that the H5 is attached in FEL mode

     "Allwinner Technology sunxi SoC OTG connector in FEL/flashing mode"

Something has gone wrong with the boot sequence and the BROM has fallen back to FEL.

 

Verify the bootinfo of the file:

$ ./sunxi-bootinfo u-boot_H5_zero_plus.bin
      4:       Magic     : eGON.BT0
     10:       Length    : 32768
     14:       HSize     : 38555731
     18:       HEAD ver  :  
     1c:       FILE ver  :  
     20:       BOOT ver  : ,
     24:       eGON ver  :  
     28:       platform  : sun5
     Unknown boot0 header version
The bootinfo matches that of uart0-helloworld-sdboot.sunxi, except for the platform that is identified as 'sun5'.

 

Any assistance on how to prepare u-boot will be much appreciated.

Link to comment
Share on other sites

  • 0

Nice, did you managed it on h3 or h5?

Unfortunate (or as far i know) u-boot doesn't have support for it.

You must verify it on your own. For example hash with sha1 it you trust it enough (SPL is very limited here from size)

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...