Ravikumar Posted December 6, 2016 Posted December 6, 2016 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)? 0 Quote
zador.blood.stained Posted December 6, 2016 Posted December 6, 2016 You can find some info here: https://linux-sunxi.org/BROM and here: https://linux-sunxi.org/EGON#eGON.BRM and disassembled BROM code here: https://github.com/hno/Allwinner-Info/tree/master/BROM I'm pretty sure BROM can only verify checksums and you can't make trusted boot with it. 0 Quote
Ravikumar Posted December 8, 2016 Author Posted December 8, 2016 You can find some info here: https://linux-sunxi.org/BROM and here: https://linux-sunxi.org/EGON#eGON.BRM and disassembled BROM code here: https://github.com/hno/Allwinner-Info/tree/master/BROM I'm pretty sure BROM can only verify checksums and you can't make trusted boot with it. Thanks for reply, With present configuration, it just verifying checksum. But there are some unknow bits in efuse to enable security of the chip. Please check following code void sid_set_security_mode(void) { uint reg_val; reg_val = sid_read_key(EFUSE_LCJS); reg_val |= (0x01 << 11); //ʹÄÜsecurebit sid_program_key(EFUSE_LCJS, reg_val); reg_val = (sid_read_key(EFUSE_LCJS) >> 11) & 1; return; } I have written security (11-bit), now my board is not booting. I think BootROM trying to verify signature. One more thing, H3 is not a simple soc. it has ARM trust zone and it can run TEE(both linux & secure os at a time). BootROM security must for TEE. 0 Quote
zador.blood.stained Posted December 8, 2016 Posted December 8, 2016 Well, there is no documentation for BROM and probably there won't be any in the future from Allwinner side. AFAIK the only way to go forward is to dump and disassemble BROM from H3, and I'm not sure if anyone here (on this forum) has more info on this undocumented stuff. 0 Quote
Ravikumar Posted December 12, 2016 Author Posted December 12, 2016 Well, there is no documentation for BROM and probably there won't be any in the future from Allwinner side. AFAIK the only way to go forward is to dump and disassemble BROM from H3, and I'm not sure if anyone here (on this forum) has more info on this undocumented stuff. Please check the following code. https://github.com/BPI-SINOVOIP/BPI-M3-bsp there are some files in u-boot folder sunxi_efuse.c : efuse map and programing sequencing usb_burn.c : __sunxi_burn_key for burning efuse area do you know this code? He is burning e-fuse area via usb device. If you have any information this code. Please share with me. 0 Quote
xeniter Posted November 9, 2018 Posted November 9, 2018 found some infos: https://github.com/hno/Allwinner-Info/blob/master/BROM/ffff0000.s#L1 and looks like allwinner put h3 secure brom source code online: https://github.com/Allwinner-Homlet/H3-BSP4.4-bootloader/tree/master/uboot_2014_sunxi_spl/sunxi_spl there many printf -> which use sunxi_serial_putc however i didn't find the function definition, would be great to get error message why its not booting the toc0 i set secure bit and wrote rotpk but it does not boot my toc0 image or any other image anymore only fel mode is working now, maybe someone has an idea what it could be wrong: https://pastebin.com/wHWqzPJ7 0 Quote
DrSchottky Posted February 7, 2019 Posted February 7, 2019 I'm interested in secure boot too. @xeniter did you make any progress? 0 Quote
xeniter Posted March 4, 2019 Posted March 4, 2019 still not yet, only some infos and bricks more... burnend one board without rotpk, only the secure bit flag, does now boot only the toc header images (: After that i tried jemk script to generate the sha rotpk checksum and wrote into a new board with secure bit, however this does not boot my sigend toc .... ): Found out there is a private toc0 header with a debug flag, maybe if its possible to set this flag it would be able to get some debug output and infos why the toc does not boot. Compared source h3 sbrom src with the sha generation from jemks script and it looks at first view all correct. did you found something out or got it working? 0 Quote
DrSchottky Posted March 7, 2019 Posted March 7, 2019 On 3/4/2019 at 10:22 AM, xeniter said: still not yet, only some infos and bricks more... burnend one board without rotpk, only the secure bit flag, does now boot only the toc header images (: After that i tried jemk script to generate the sha rotpk checksum and wrote into a new board with secure bit, however this does not boot my sigend toc .... ): Found out there is a private toc0 header with a debug flag, maybe if its possible to set this flag it would be able to get some debug output and infos why the toc does not boot. Compared source h3 sbrom src with the sha generation from jemks script and it looks at first view all correct. did you found something out or got it working? Hi, unfortunately no, I'm still looking at sbrom source. I'm even having problems compiling the fuse burner (it gives me linking error in your implementation of printf). Could you tell me how did you manage to compile it? By the way yes, toc0 header has a debug flag to enable debug prints, but as far as I can see from a sbrom dump they've been removed in production. What about trying to debug sbrom code by making a fel-bootable image containing part of that code? 0 Quote
xeniter Posted March 13, 2019 Posted March 13, 2019 hi, did only copy paste the printf somewhere so no warranties. copied the makefile also somewhere together to compile bare metal, also without warranties https://pastebin.com/x9RftzVm is the makefile (make main.elf) original is from https://github.com/linux-sunxi/sunxi-tools/blob/master/uart0-helloworld-sdboot.c had often issues that programmed died, didn't find out why yet so don't trust it the sram is very limited because of the FEL mode see http://linux-sunxi.org/FEL/USBBoot what helped is to load the uboot spl to init ram, after that i copied my program to the ddr ram. ./sunxi-fel spl ./sunxi-spl.bin ./sunxi-fel write 0x40000000 ./main.elf ./sunxi-fel exe 0x40000000 make sure you adjust linker script with correct adress -> main.lds . = 0x40000000; => set program to start of ddr ram found out, or it looks like the ruby tocgen is missing the #define ITEM_NAME_SBROMSW_KEY 0x010303 pack_tools/toc_tools/key_ladder/create_key_ladder.c: key_item_bin.KEY0_PK_e_len = (key0_e_len+1)>>1; typedef struct SBROM_TOC0_KEY_ITEM_info { unsigned int vendor_id; unsigned int KEY0_PK_mod_len; unsigned int KEY0_PK_e_len; unsigned int KEY1_PK_mod_len; unsigned int KEY1_PK_e_len; unsigned int sign_len; unsigned char KEY0_PK[PK_MAX_LEN_BYTE]; unsigned char KEY1_PK[PK_MAX_LEN_BYTE]; unsigned char reserve[32]; unsigned char sign[256]; } SBROM_TOC0_KEY_ITEM_info_t; assume h3 boot code reads length from it, that could be a possible reason why its not booting the toc. haven't tried to add it yet will continue to test it when i have time for it left again... 0 Quote
spitfire Posted March 30, 2019 Posted March 30, 2019 Hi @xeniter, were you able to verify the secure boot on H3? I have some spare boards i am willing try on. Jmks script generates the files, the rotpk-hash is then also programmed but like yours, the nanopi doesnt boot. When setting all the rotpk-hash to all 0xff, the board boots. any help is highly appreciated wbr 0 Quote
xeniter Posted April 11, 2019 Posted April 11, 2019 (edited) No results yet... Found maybe the original tool to create toc0, always looked over it. https://github.com/friendlyarm/h3_lichee/tree/75b584e2502450b1e8d2f98ac16fb2410cf8c30a/tools/pack/pctools/linux/openssl looks like with it it could be possible to create a valid toc0 which boots with key (assume jemk scripts are based on it) question is now how to use it, haven't tried it yet edit: generating keys: /h3_lichee/tools/pack/pctools/linux/openssl/dragonsecboot -toc0 dragon_toc.cfg ../../../common/keys/ generate toc0: . /create_toc0 dragon_toc.cfg /h3_lichee/tools/pack/common/keys dd if=./toc0.fex of=/dev/sd? bs=1024 seek=8 > did only boot on my board with rotpk fuses burned with all zeros ): maybe you have more luck (cause maybe i burned fuses in wrong order... or something else...) used this to generate Trustkey.bin to be able to use my old generated key: openssl rsa -in rotprivk_rsa.pem -text > /robart/mdipolt/2del/SECBOOT/h3_lichee/tools/pack/common/keys/Trustkey.bin sboot.bin must be raw bin file (no spl and no elf file!) you can verify your sboot.bin with executing it via fel mode: ./sunxi-fel version ./sunxi-fel -p write 0x2000 sboot.bin ./sunxi-fel exe 0x2000 create_toc0 created the ".\\x509_rotpk.bin" which had the same rotpk checksum as jemk script, so i assume its correct. question is how had it to be written into the fuses xxd -i .\\x509_rotpk.bin unsigned char __x509_rotpk_bin[] = { 0xf6, 0xab, 0x5e, 0x33, 0x80, 0xd9, 0xdd, 0xa8, 0x82, 0x86, 0x85, 0x5f, 0x22, 0xdc, 0x9d, 0xc0, 0xf9, 0xa4, 0x2c, 0xbf, 0xec, 0x05, 0xd0, 0xcd, 0xcd, 0xa4, 0x9b, 0xf4, 0xb4, 0xba, 0xf8, 0x94 }; unsigned int __x509_rotpk_bin_len = 32; i burned it like that: // allwinner H3 == sun8iw7p1 #define SID_PRKEY_NEU (SUNXI_SID_BASE_NEU + 0x50) #define EFUSE_ROTPK (0x64) static void sid_program_key(unsigned int key_index, unsigned int key_value) { unsigned int reg_val; writel(key_value, SID_PRKEY_NEU); reg_val = readl(SID_PRCTL_NEU); reg_val &= ~((0x1ff<<16)|0x3); reg_val |= key_index<<16; writel(reg_val, SID_PRCTL_NEU); reg_val &= ~((0xff<<8)|0x3); reg_val |= (SID_OP_LOCK<<8) | 0x1; writel(reg_val, SID_PRCTL_NEU); while(readl(SID_PRCTL_NEU)&0x1){}; reg_val &= ~((0x1ff<<16)|(0xff<<8)|0x3); writel(reg_val, SID_PRCTL_NEU); return; } for(int i = 0; i < 8; i++) { printf("%08x:", rotpk[i]); sid_program_key(EFUSE_ROTPK+4*i, rotpk[i]); } Edited April 12, 2019 by xeniter new tests 0 Quote
xeniter Posted May 24, 2019 Posted May 24, 2019 yes finally it worked (with jemp script, maybe with tocgen also not tested yet...) you have to write the keys only little endian instead big endian 0 Quote
spitfire Posted May 31, 2019 Posted May 31, 2019 On 5/24/2019 at 10:48 AM, xeniter said: yes finally it worked (with jemp script, maybe with tocgen also not tested yet...) you have to write the keys only little endian instead big endian Hi Xeniter, Still haven't succeded into booting a TOC0 spl image. - Wrote the generated ROTPK as little endian SHA256 = 18 D8 E4 D5 A2 4D 8B F2 AA 00 61 98 9B 92 15 E7 9B 99 0A 82 F9 21 A6 5B 0F 56 0D A6 D2 05 E8 CE wrote these values in the Key-section of the efuse(0x64...) as little endian : D5 E4 D8 18 .....CE E8 05 D2 Burned 0xF4(LCJS) -> 0x800 (bit 11->'1' to enable secure boot) Used jmek's Ruby script and used the spl which i compiled from a FriendlyArm's Uboot repository(19KB). After jmek's script, a restuling TOC file generated. The file boots ok if the keys are burned either as 0's or 1's and secure bit-11 in the 0xF4 is set to '1', but when the nanopi neo board is burned with the exact sha256 , it doesn't boot. Can you please describe step by step what you did in order to get a correct spl and how you programmed the exact sha256 of a .pem file in the Key-efuse section. Thank you wbr Spitfire 0 Quote
xeniter Posted June 2, 2019 Posted June 2, 2019 hi can you post or pm me the private key? assume hash is wrong, simple sha256 hash of pem file is not correct.. you can use tocgen to generate it for you, or generate it yourself liked described in the sunxi wiki ROTPK_HASH = SHA256([Byte 0-255] = RSA modulus || [Byte 256-x] = RSA public exponent || [Byte x-511] filled with 0x91) means SHA256 from [256 bytes modules + 3 bytes public key exponent ( normally 65537 means 0x010001) + 253*0x91 fill bytes] if you used exactly this key, please try to read the hash back and post me the result + source of reading the rotpk fuse out 0 Quote
spitfire Posted June 5, 2019 Posted June 5, 2019 Hi @xeniter I used tocgen from the lichee repository. So far i was able to generate ,/x509_rotpk.bin file which holds the hash-value to be programmed. the resulting toc0.fex boots ok when the rotpk-hash is all '0's and '1's. (or all keys are the same) with secure-bit burned. My read_register routine: def read_register(register_addr): sid_ctrl_data = (0xAC<<8) sid_ctrl_data = sid_ctrl_data+(register_addr<<16) sid_ctrl_data = sid_ctrl_data+0x02 #print("SID ctrl content ",hex(sid_ctrl_data)) writel(sid_base_addr+0x40,sid_ctrl_data) while((readl(sid_base_addr+0x40)&0x02)==0x02): print("finishing read ..") time.sleep(1) read_val= readl(sid_base_addr+0x40) #print("read val:",hex(read_val)) reg_val = readl(sid_base_addr+0x60) return reg_val programmed HASH in the rotpk section: ('reg ', '0x64', ':', '0xe9e6181a') ('reg ', '0x68', ':', '0x5fb19a8f') ('reg ', '0x6c', ':', '0xf91d6e62') ('reg ', '0x70', ':', '0x652b9fd8') ('reg ', '0x74', ':', '0x3573e89e') ('reg ', '0x78', ':', '0x6f9c3d21') ('reg ', '0x7c', ':', '0xa8f92947') ('reg ', '0x80', ':', '0xf5326ac5') ('reg ', '0x84', ':', '0x0') ('reg ', '0x88', ':', '0x0') ('reg ', '0x8c', ':', '0x0') ('reg ', '0x90', ':', '0x0') ('reg ', '0x94', ':', '0x0') ('reg ', '0x98', ':', '0x0') ('reg ', '0x9c', ':', '0x0') ('reg ', '0xa0', ':', '0x0') ('reg ', '0xa4', ':', '0x0') ('reg ', '0xa8', ':', '0x0') ('reg ', '0xac', ':', '0x0') ('reg ', '0xb0', ':', '0x0') ('reg ', '0xb4', ':', '0x0') ('reg ', '0xb8', ':', '0x0') ('reg ', '0xbc', ':', '0x0') ('reg ', '0xc0', ':', '0x0') ('reg ', '0xc4', ':', '0x0') ('reg ', '0xc8', ':', '0x0') ('reg ', '0xcc', ':', '0x0') ('reg ', '0xd0', ':', '0x0') ('reg ', '0xd4', ':', '0x0') ('reg ', '0xd8', ':', '0x0') ('reg ', '0xdc', ':', '0x0') ('reg ', '0xe0', ':', '0x0') ('reg ', '0xe4', ':', '0x0') ('reg ', '0xe8', ':', '0x0') ('reg ', '0xec', ':', '0x0') ('reg ', '0xf0', ':', '0x0') ('reg ', '0xf4', ':', '0x800') ('reg ', '0xf8', ':', '0x0') ('reg ', '0xfc', ':', '0x0') my x509_rotpk_: unsigned char x509_rotpk_bin[] = { 0x1a, 0x18, 0xe6, 0xe9, 0x8f, 0x9a, 0xb1, 0x5f, 0x62, 0x6e, 0x1d, 0xf9, 0xd8, 0x9f, 0x2b, 0x65, 0x9e, 0xe8, 0x73, 0x35, 0x21, 0x3d, 0x9c, 0x6f, 0x47, 0x29, 0xf9, 0xa8, 0xc5, 0x6a, 0x32, 0xf5 }; unsigned int x509_rotpk_bin_len = 32; RSA .pem file: -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEA4T91fvEiHwHeNYKY/mgQ4qWUU7CpzzknpOWAy/MQpwrcAUwy TCX/nq6FrDPa2yyucpL4Sd3zPACTUURFSzSTYwkglm8fjWX+iCgWlvOYYXlA3Zjl 6nSEhe08mIvbdNHuhEF0yEdHZ1JfHkbwhIU8yq4oqh4sdYshAgLC5WmOoSBoVQOz 7uNms1wHo3Hy2hT9TQ5ed0ttKoPVgH5CgyA19yW+TKVjvpK8vqw1KuHnZILxH9V7 Id/ElSuNPgE8JIdghl9k/cA5HQ4dglWu2pVyKZfIC3VGB1+M5uJCQmatIU9dmoHL sPaWi79Sn/3qhuxu47en96tShDZL9gasy4qoXwIDAQABAoIBAGeBBJnPblF3R0ep emo1IcU0NwN6A53QcrIoL9YIHFfV+qCyBc7OCzc8lPo7Xc8nKgZGGMfAsLuavBc0 2u6i+zMgB5R4/bO48YxZd3/n8dagpDjvwH7LCfaMvDKQ2chFi2fEuEgr0NjelgzQ pkcO/o9YFiGN+foNc5577FkE92B8KgRCsXrKHMx8UZLCmM1Fw3LIsTKWQCm+/7SL 2gb+D3GDwuCnMRrKxQ7J6oYVeMZ/dqxkHhfZdZXy6ofmdmxvabJAism1xXBPJaBl OD1HX+UAdK2bkIEQDWzVhI+sm2K/0N6MkM3xHxf1gnE0H0Icm8hy6FeZuYm65erc RlIXsXECgYEA+F6e9Wmh2c2SL7mjxYU1cFj7R3OXE6kR7ln3I/QN7fzH2vmcysB/ 3+WhHiWA49rGEMQUjHb9AJ+EYcjyz9PXSLWEWd2rd/78i3SFZvmdZIpNsFJVbhao hELV/6541ehNymr0XmfU9wCnHY3JUq03Yahrlmabt0h2vRGw3vyVJtcCgYEA6Cr9 eInMhisempaXEgloRT61vkxddQXIfwdZ0GMn4uhgnzRPsQHZXWq4iVj5sD1OOID/ R/oF52MhPrItQKf97unAlrsfFwrVwFX+p8wGwg5OY2Vw44ElfQItWaFXgSZLVtPM 2RRO7pDLHn7dnjuEmSuiBX3DgarzixGTE2ajQbkCgYAFi18zDUueqBcmV5ePVjzu KB5b5vmtZ63Ny1ZYCB+ze1weyEm2wPtZzS9+k8m/zGd1glsPE6zsMaNr52d8Ojdp GRw+QVONlzSeDFjaBqJ71xaK5BuiHIFginlqfsOVytzJsv+Hh/vaE7qnTz36SYGd /XuBXQMG4Wg9KkLvh2Xw+wKBgQCBlEz4U+DFGZfxLA+RT5LU4xVI6xJWWC35SD8G ofEHIi+ba/T2lFOfYgsxDWn+xZi8zLKul4toA9nwRj4fkiOWjvygpDvL/o4i1VxW hvdWo+l4bIu/Trt/tBFfrz9Jo/f0tC3nEwCjAkl78c77m7h8TPAXJIRUAPgBLIPs FiMUcQKBgEjAqVqrYpxf/LjVDmE97lzKwR2Yb+BIuzH+4e7QlQEtg9IqVK53+Re1 p4nb46r643RJEkoDLwJqvZQoqngCsSkKCd5jAG1cE9mMyaT/shNDwefYMULf7FLr ScKN2oP6LVdye+2shTMDKfv6fbb2NQ2E3xYThzhUmNvMnkZbj4d8 -----END RSA PRIVATE KEY----- I have used the /keys folder which i first used the create_keys script for and the posted key is the Trustkey.pem Still unable to boot in secure-mode, any help is appreciated. wbr spitfire 0 Quote
xeniter Posted June 5, 2019 Posted June 5, 2019 looks like your rotpk key is okay verified with: https://pastebin.com/ShSQFe95 rotpk 00000000 1a 18 e6 e9 8f 9a b1 5f 62 6e 1d f9 d8 9f 2b 65 |......._bn....+e| 00000010 9e e8 73 35 21 3d 9c 6f 47 29 f9 a8 c5 6a 32 f5 |..s5!=.oG)...j2.| only used tocgen from lichee when fuses where all zero, did you try it also with jemk egon2toc.rb? here is my bare metal example of writing the key, use it at own risk! and double check you replaced your rotpk (1a=f6.... 94=f5) correctly: https://pastebin.com/Aw5q6bdU to read keys create new main and call print_stuff and add a smc instruction before it to be able to print your burned roptk key via fel mode to run it via fel from sdram: arm-none-eabi-objcopy -O binary main.elf main.bin ./sunxi-fel version ./sunxi-fel -p write 0x2000 main.bin ./sunxi-fel exe 0x2000 0 Quote
spitfire Posted June 5, 2019 Posted June 5, 2019 @xeniter finally good news: i was able to boot the SoC in secure mode... using the jmk's egon2toc did the trick. Before i was using the lichee's toc generator, i guess that has some sort of bug. I used sunxi-fel to burn my keys. The keys should be of course burned "little-endian" anyways, thanks for your tremendous work and help. wbr 0 Quote
spitfire Posted June 5, 2019 Posted June 5, 2019 @xeniter now that secure spl is working, i guess, is there any way to disable fel? as securing the spl does not overcome someone to gain access over fel.... and program the rotpk to all '1' and run their own "certified spl" i guess there might be a SID-bit to burn after which no modification is allowed to the SID... I will keep digging and see if you have info as well. 0 Quote
xeniter Posted June 6, 2019 Posted June 6, 2019 @spitfirenice to hear that it finally worked strange that the original tocgen does not work, was lucky that i test the ruby script before. good point with fel mode, would be very interesting if its possible somehow to disable it 0 Quote
youns Posted June 7, 2019 Posted June 7, 2019 can we use this secure mode to run encrypted sd card ? or its only to be sure the os isn't changed by using trust chain thanks 0 Quote
xeniter Posted June 11, 2019 Posted June 11, 2019 now its only for verification of the spl bootloader, maybe you could write some aes keys in the fuses and use it later for decryption. the h3 has also a crypto engine didn't look into deeper it yet, maybe someone has some experience with it already 0 Quote
Yevhen Posted June 21, 2019 Posted June 21, 2019 I'm also looking for a solution to enable secure boot with encrypted SD card and so having a few questions: 1) Is this method applicable to H5 also or it will work only on H3? 2) Are data stored in eFuses (encryption key) are secured? Can someone with physical access to device read them? 3) This topic is very important for IoT devices that store sensitive data in their memory so it will be very helpful if you guys could provide step-by-step instructions on how to enable secure boot with storing an encryption key in eFuses (for newbies to this platform). 0 Quote
xeniter Posted June 24, 2019 Posted June 24, 2019 1) According to Sunxi toc wiki -> You may need to change the entry point address from 0x0 to 0x10000 if you want to run it on A64/H64/H5 (the default 0x0 value is used for H3) have never tested secure toc boot on other hardware than H3, assume it will also work on H5 2) Yes, it is possible to read it via fel mode, since till now as far I know nobody found out how to disable it, the better question is -> is it really possible to disable it... 3) stop dreaming and buy a arm core with documentation or at least from a manufacturer where you can get it, otherwise you are on your own you could try ask allwinner, here some possible answers you may get: there is no documentation about this... what is toc0? <- made my day^^ possible solution: Easiest way is maybe to burn the key in the AES fuses, read it from ram via u-boot and pass it as crypt variable to the kernel parameter (https://wiki.archlinux.org/index.php/Dm-crypt/System_configuration) maybe someone who will use this setup could post the steps, anyhow i wouldn't trust such a step per step without fully understanding each step and its likely you have to adjust anyhow something. 0 Quote
janng0 Posted August 5, 2019 Posted August 5, 2019 Useful links № link description 1 this topic full instruction by itself - extremely useful 2 SID Register Guide description of eFUSE fields; likely created while looking through this code from [11] 3 FEL info description of FEL mode and how to switch in FEL (see also [9]) 4 jemk script ruby-script to pack SPL binary into TOC0 format (see also create_toc0 in 6) ) 5 newer SPL sources (2014) likely original SPL (aka SBromSW) from Allwinner; based on U-Boot 2014 6 AW openssl tools tools for generating keys and TOC0 from Allwinner SDK 7 uart0-helloworld-sdboot code that works on bare metal Allwinner SoC, also in FEL-mode 8 sunxi tools info tool for working with FEL and other useful stuff 9 more on FEL more info about FEL mode (just useful to read) 10 eFUSE burner working code, that burns rotpk from @xeniter (base on code in [7]) 11 original SPL original Allwinner SPL for H3 12 eFUSE structure full description of eFUSE structure (likely [2] is based on this code) 13 Nanopi Neo firmware firmware (and it's source code) 14 Brom sources original Brom sources, dumped from SoC (assembler, not C-sources) Brom == SBromHW == boot ROM - first loader, burned inside SoC SPL == SBromSW == Second Program Loader - second loader, verified and loaded by Brom with help of rotpk U-Boot - third loader, verified and loaded by SPL rotpk == Root Of Trust Public Key - the most important key, burned into eFUSE (as ROTPK_HASH, counted by this formula), as verification chain starts from it Semelis == Secure OS - some code, that works in Secure World (likely just Linux) Normal OS - some code, that works in Normal World (Linux, Android, etc.) verification chain: power on => starts Brom Brom looks for SPL on persistent memory (SD-card, eMMC, etc.; for SD-card it looks at offset 8kb); SPL not present => goto FEL Brom checks for rotpk in eFUSE 1) rotpk present: verify and load SPL; verification failed => goto FEL 2) rotpk not present: load SPL SPL checks for rotpk 1) rotpk present: goto 5. 2) rotpk not present: burn rotpk and other keys into eFUSE SPL checks for secure U-Boot 1) secure U-Boot not found => likely goto FEL (may be options, depending on SPL logic) 2) verify secure U-Boot with some keys (depends on SPL logic); verification failed => goto FEL 3) load secure U-Boot secure U-Boot verifies and loads Semelis, or goes to FEL, if comething is wrong SPL checks for normal U-Boot 1) normal U-Boot not found => likely goto FEL (may be options, depending on SPL logic) 2) verify normal U-Boot with some keys (depends on SPL logic); verification failed => likely goto FEL (may be options, depending on SPL logic) 3) load normal U-Boot normal U-Boot verifies and loads Normal OS or, if comething is wrong, likely goto FEL (may be options, depending on normal U-Boot logic) two full featured (Normal and Secure) OSes are running and communicating Full featured TrustZone is: two full featured (kernel space + user space ) Linux , one works inside Normal World, another inside Secure World. Monitor Mode - some code, that clues two worlds. Normal World issues software interrupt (ARM instruction SMC). Normal World kernel implements Monitor Mode - verifies if the switch between worlds is possible, saves some parameters for Secure World handler and issues SMC instruction. Secure World kernel handles software interrupt, issued by SMC instruction, executes some work, issued by Normal World parameters and returns back from SMC software interrupt handler to Normal Wold. There may be ortions, so Semelis could be something more simple than full featured Linux. to burn eFUSE 1) build sunxi-tools apt-get install libusb-1.0-0-dev git clone https://github.com/linux-sunxi/sunxi-tools sunxi_tools_dir cd ./sunxi_tools_dir make 2) switch H3 into FEL just pull SD-card out and turn on to check: cd ./sunxi_tools_dir # list shows all connected Allwinner SoC's that are in FEL mode ./sunxi-fel list USB device 001:009 Allwinner H3 02c00081:04004620:79910124:5c1a080e # sid shows CHIPID from eFUSE (see [2]) ./sunxi-fel sid 02c00081:04004620:79910124:5c1a080e 3) compile and run uart0-helloworld-sdboot Before continue also would be useful to connect Nanopi Neo UART to PC - there would logs printed in H3 UART0. Also install crosscompiler (used Linaro GCC 4.9-2015.03, prefix arm-angstrom-linux-gnueabi-, for tests). cd ./sunxi_tools_dir # compile uart0-helloworld-sdboot; Makefile has instructions to autosearch crosscompiler, but in case # run: CROSS_COMPILE=arm-angstrom-linux-gnueabi- make uart0-helloworld-sdboot.elf make uart0-helloworld-sdboot.elf # load binary into SRAM A1 on H3 ./sunxi-fel -v -p write 0x2000 ./uart0-helloworld-sdboot.elf # run code; UART should show: # # Hello from Allwinner H3! # Returning back to FEL. # ./sunxi-fel -v exec 0x2000 4) generating keys Keys are generated with by dragonsecboot from [6]. Parameters of this utility are unknown (no --help flag), so look at this post and tools/pack/createkeys in [6]. git clone https://github.com/friendlyarm/h3_lichee.git h3_lichee cd ./h3_lichee/tools/pack/pctools/linux/openssl # flag -key found in h3_lichee/tools/pack/createkeys PATH=".:$PATH" dragonsecboot -key ../../../common/sign_config/dragon_toc.cfg ../../../common/keys dragonsecboot generates bunch of private keys and name files, as mentioned in file dragon_toc.cfg. For every key also generated .bin file (it is a text file actually) with some mathematical processing. Also one of the keys is mentioned as Trustkey. For this one rotpk.bin is generated - this is our Root Of Trust hash to write to eFUSE. 5) build eFUSE burner Take the working code [10] from @xeniter. Change rotpk_bin on the data from your rotpk.bin from 4). Compile and run it as in 3). That's all - @xeniter already done everything for you:) 6) generating TOC0 create_toc0 from [6] (could be found near dragonsecboot) and jemk script [4] do pretty the same, but using jemk script is easier: # install Ruby sudo apt-get install ruby-full # ruby -v git clone git@gist.github.com:2abcab1359c4bce793679c5854062331.git jemk_mktoc0 # generate TOC0 # Trustkey.pem - Root of Trust, from which rootpk. bin was generated in 4), # sboot.bin - compiled binary SPL, for test simply uart0-helloworld-sdboot could be used # sboot.toc0 - output file ruby ./jemk_mktoc0/mktoc0.rb [path_to_BSP]/h3_lichee/tools/pack/common/keys/Trustkey.pem [path_to_SPL]/sboot.bin sboot.toc0 # ruby ./jemk_mktoc0/mktoc0.rb [path_to_BSP]/h3_lichee/tools/pack/common/keys/Trustkey.pem [sunxi_tools_dir]/uart0-helloworld-sdboot.elf sboot.toc0 Just in case, create_toc0 could be used like this cd [path_to_BSP]/h3_lichee/tools/pack/pctools/linux/openssl # create_toc0 is controlled by the same config dragon_toc.cfg as dragonsecboot - see section [toc0] in dragon_toc.cfg # actually the name of binary to pack into TOC0 is also specified there - it's sboot.bin, so we should copy binary here, or # specify another full path cp [path_to_SPL]/sboot.bin ./sboot.bin # run create_toc0 (create_toc0 uses keys, generated by dragonsecboot) PATH=".:$PATH" create_toc0 ../../../common/sign_config/dragon_toc.cfg ../../../common/keys 7) run board with custom TOC0 and rotpk Insert SD-card and flask your SPL in TOC0 format there sudo dd if=[path_to_toc0]/sboot.toc0 of=/dev/sd[?] status=progress bs=1024 seek=8 Now insert SD-card and run board. If you used uart0-helloworld-sdboot.elf as a binary inside TOC0, you should see some output from device UART0. 0 Quote
janng0 Posted August 9, 2019 Posted August 9, 2019 On 6/22/2019 at 1:56 AM, Yevhen said: I'm also looking for a solution to enable secure boot with encrypted SD card and so having a few questions: 1) Is this method applicable to H5 also or it will work only on H3? 2) Are data stored in eFuses (encryption key) are secured? Can someone with physical access to device read them? 3) This topic is very important for IoT devices that store sensitive data in their memory so it will be very helpful if you guys could provide step-by-step instructions on how to enable secure boot with storing an encryption key in eFuses (for newbies to this platform). About 2). As @xeniter mentioned before, it is not secure - one can read it via FEL mode due to hack implemented in sunxi-fel utility: // file fel.c in sunxi-tools /* * Issue a "smc #0" instruction. This brings a SoC booted in "secure boot" * state from the default non-secure FEL into secure FEL. * This crashes on devices using "non-secure boot", as the BROM does not * provide a handler address in MVBAR. So we have a runtime check. */ void aw_apply_smc_workaround(feldev_handle *dev) { soc_info_t *soc_info = dev->soc_info; uint32_t val; uint32_t arm_code[] = { htole32(0xe1600070), /* smc #0 */ htole32(0xe12fff1e), /* bx lr */ }; /* Return if the SoC does not need this workaround */ if (!soc_info->needs_smc_workaround_if_zero_word_at_addr) return; /* This has less overhead than fel_readl_n() and may be good enough */ aw_fel_read(dev, soc_info->needs_smc_workaround_if_zero_word_at_addr, &val, sizeof(val)); /* Return if the workaround is not needed or has been already applied */ if (val != 0) return; pr_info("Applying SMC workaround... "); aw_fel_write(dev, arm_code, soc_info->scratch_addr, sizeof(arm_code)); aw_fel_execute(dev, soc_info->scratch_addr); pr_info(" done.\n"); } But we implemented another hack on this hack - we burned USB)) It's definitely not elegant and not tested well (we don't know for sure, if only USB is burned, but not some other useful parts of the SoC), but finally USB data channels are broken (D+ and D-) but power channels are ok - Nanopi Neo still gets power via USB, but FEL mode is completely unavailable. To do this, we connected USB data channels D+ and D- to 20V power source via capacitor of 0.22uF. ------------------------- D+ 20v -------- 0.22uF -------- D- 0 Quote
xeniter Posted August 12, 2019 Posted August 12, 2019 thanks for the nice summary, epic fel mode solution( made my day ) why i didn't think about it, hope you verify in your EOL tests that fel mode is really not working anymore 0 Quote
Splitice Posted December 19, 2019 Posted December 19, 2019 @janng0 Well done. Nice FEL mode solution, I too confirm it works remarkably well. 15V is sufficient too. Doesn't damage the other USB controllers either which is perfect. Confirmed on NEO & NEO Air devices. Now time to get secure images working. 0 Quote
GnomEne Posted February 24, 2020 Posted February 24, 2020 (edited) Hello Team. I have board based on SoC H3. Board has been damaged and after replace CPU built-in system not booting. New CPU is Ok and work fine in TV-box on android. I think that problem in eFUSES. In new CPU "NV2" zone is clear (0x00) but programmed in old burned CPU. Please share info about simple programm of these eFUSES. Edited February 24, 2020 by GnomEne 0 Quote
Recommended Posts
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.