espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.63k stars 7.28k forks source link

esptool.py flash fails with secure boot v2 on a ESP32-S3-WROOM-1 (IDFGH-9419) #10788

Closed mhgue closed 1 year ago

mhgue commented 1 year ago

Answers checklist.

IDF version.

v5.0.1-3-g886e98a2c1

Operating System used.

Linux

How did you build your project?

Command line with idf.py

If you are using Windows, please specify command line type.

None

What is the expected behavior?

Ability to flash applications with correct signature.

What is the actual behavior?

1.) With --no-stub flash fails with: A fatal error occurred: Failed to enter Flash download mode (result was 01060000: Operation or feature not supported) 2.) Without --no-stub flash fails with: A fatal error occurred: Failed to start stub. There was no response.

Steps to reproduce.

Enable secure boot V2 on a ESP32-S3 as described in How To Enable Secure Boot V2

Build or installation Logs.

Uploading stub...
Running stub...

A fatal error occurred: Failed to start stub. There was no response.
Try increasing timeouts, for more information see: https://docs.espressif.com/projects/esptool/en/latest/esptool/configuration-file.html
CMake Error at run_serial_tool.cmake:55 (message):

  /home/mg/.espressif/python_env/idf5.0_py3.10_env/bin/python;;/dec/mg/src/DX3_DSX_ESP/libs/esp-idf/components/esptool_py/esptool/esptool.py;--chip;esp32s3
  failed

FAILED: CMakeFiles/flash 

=========================================================================================
or without stub:

Erasing flash...

A fatal error occurred: Failed to enter Flash download mode (result was 01060000: Operation or feature not supported)
CMake Error at run_serial_tool.cmake:55 (message):

  /home/mg/.espressif/python_env/idf5.0_py3.10_env/bin/python;;/dec/mg/src/DX3_DSX_ESP/libs/esp-idf/components/esptool_py/esptool/esptool.py;--chip;esp32s3
  failed

FAILED: CMakeFiles/flash

More Information.

Using head of release/v5.0 branch of IDF, components/bootloader/Kconfig.projbuild contains

config SECURE_BOOT
    ...
        select ESPTOOLPY_NO_STUB if !IDF_TARGET_ESP32 && !IDF_TARGET_ESP32S2

and thus for IDF_TARGET_ESP32S3 activating SECURE_BOOT will activate ESPTOOLPY_NO_STUB=y too and therefore the esptool is called with option --no-stub and fails with:

Erasing flash...
A fatal error occurred: Failed to enter Flash download mode (result was 01060000: Operation or feature not supported)

If changing the Kconfig entry to exclude S3 from NO_STUB too (like done for S2):

config SECURE_BOOT
    ...
        select ESPTOOLPY_NO_STUB if !IDF_TARGET_ESP32 && !IDF_TARGET_ESP32S2 && !IDF_TARGET_ESP32S3

the option --no-stub is not used, but after enabling secure boot the esptool now fails with:

Uploading stub...
Running stub...

A fatal error occurred: Failed to start stub. There was no response.

In my application secure boot is only needed to verify OTA updates. Protection against direct access to the HW is not needed. Is there a way to allow flash stubs even with secure boot enabled? Or is there a way to enable flashing without stubs on a ESP32-S3-WROOM-1?

radimkarnis commented 1 year ago

Hello @mhgue, thanks for the report. This issue might not be related to the stub flasher - you can see flashing fails even in the ROM bootloader.

This could be an esptool regression, could you please help with verification? You can try to install an older esptool version with pip install esptool==3.3.2 in your ESP-IDF environment a try the operations again. Please let me know hoe that went.

I will investigate more, I have a similar report of this happening on the C3 with active secure boot.

mhgue commented 1 year ago

Hello @radimkarnis thank you for answering. Currently I used the esptool v4.5 . Now with

Installing collected packages: esptool
  Attempting uninstall: esptool
    Found existing installation: esptool 4.5
    Uninstalling esptool-4.5:
      Successfully uninstalled esptool-4.5
  DEPRECATION: esptool is being installed using the legacy 'setup.py install' method, because it does not have a 'pyproject.toml' and the 'wheel' package is not installed. pip 23.1 will enforce this behaviour change. A possible replacement is to enable the '--use-pep517' option. Discussion can be found at https://github.com/pypa/pip/issues/8559
  Running setup.py install for esptool ... done
Successfully installed esptool-3.3.2

I do get from idf.py

The following Python requirements are not satisfied:
esptool~=4.5 - (esptool 3.3.2 (/home/mg/.espressif/python_env/idf5.0_py3.10_env/lib/python3.10/site-packages), Requirement.parse('esptool~=4.5'))

Try with direct call to esptool

$ esptool.py --chip esp32s3 -p /dev/ttyUSB1 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 80m --flash_size keep 0x20000 build/dx3-dsx-esp.bin
esptool.py v3.3.2
Serial port /dev/ttyUSB1
Connecting....
Chip is ESP32-S3
Features: WiFi, BLE
Crystal is 40MHz
MAC: 7c:df:a1:fd:6d:90
Uploading stub...
Running stub...
Traceback (most recent call last):
  File "/home/mg/.espressif/python_env/idf5.0_py3.10_env/bin/esptool.py", line 5482, in <module>
    _main()
  File "/home/mg/.espressif/python_env/idf5.0_py3.10_env/bin/esptool.py", line 5475, in _main
    main()
  File "/home/mg/.espressif/python_env/idf5.0_py3.10_env/bin/esptool.py", line 4805, in main
    esp = esp.run_stub()
  File "/home/mg/.espressif/python_env/idf5.0_py3.10_env/bin/esptool.py", line 946, in run_stub
    p = self.read()
  File "/home/mg/.espressif/python_env/idf5.0_py3.10_env/bin/esptool.py", line 438, in read
    return next(self._slip_reader)
StopIteration

and without STUB

$ esptool.py --chip esp32s3 -p /dev/ttyUSB1 -b 460800 --no-stub --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 80m --flash_size keep 0x20000 build/dx3-dsx-esp.bin
esptool.py v3.3.2
Serial port /dev/ttyUSB1
Connecting....
Chip is ESP32-S3
Features: WiFi, BLE
Crystal is 40MHz
MAC: 7c:df:a1:fd:6d:90
Changing baud rate to 460800
Changed.
Enabling default SPI flash mode...
Configuring flash size...
Flash will be erased from 0x00020000 to 0x002f0fff...
Erasing flash...

A fatal error occurred: Failed to enter Flash download mode (result was 01060000: Operation or feature not supported)

So unfortunately no significant difference.

radimkarnis commented 1 year ago

Thanks a lot, let's investigate more. You can switch back to your original version of esptool with pip install esptool==4.5. Could you please share your efuse summary? You can get that with espefuse.py -p /dev/ttyUSB1 summary.

Also: 1) Are you sure this didn't happen before enabling secure boot? 2) Were there any additional steps, or have you just enabled SB and this started happening? 3) Is flash encryption active? 4) Have you tried using a different host machine?

Thanks for your patience, I am trying to gain as much info as possible to reproduce this.

mhgue commented 1 year ago

Doing esp-idf/install.sh is very nice for resetting all those changes.

$ espefuse.py -p /dev/ttyUSB1 summary
espefuse.py v4.5
Connecting....
Detecting chip type... ESP32-S3

=== Run "summary" command ===
EFUSE_NAME (Block) Description  = [Meaningful Value] [Readable/Writeable] (Hex Value)
----------------------------------------------------------------------------------------
Calibration fuses:
TEMP_SENSOR_CAL (BLOCK2)                           ??? Temperature calibration                        = 3.3000000000000003 R/W (0b000100001)
ADC1_MODE0_D2 (BLOCK2)                             ??? ADC1 calibration 1                             = -40 R/W (0x8a)
ADC1_MODE1_D2 (BLOCK2)                             ??? ADC1 calibration 2                             = 76 R/W (0x13)
ADC1_MODE2_D2 (BLOCK2)                             ??? ADC1 calibration 3                             = -208 R/W (0xb4)
ADC1_MODE3_D2 (BLOCK2)                             ??? ADC1 calibration 4                             = -232 R/W (0xba)
ADC2_MODE0_D2 (BLOCK2)                             ??? ADC2 calibration 5                             = 336 R/W (0x54)
ADC2_MODE1_D2 (BLOCK2)                             ??? ADC2 calibration 6                             = 324 R/W (0x51)
ADC2_MODE2_D2 (BLOCK2)                             ??? ADC2 calibration 7                             = -388 R/W (0xe1)
ADC2_MODE3_D2 (BLOCK2)                             ??? ADC2 calibration 8                             = -272 R/W (0xc4)
ADC1_MODE0_D1 (BLOCK2)                             ??? ADC1 calibration 9                             = 48 R/W (0b001100)
ADC1_MODE1_D1 (BLOCK2)                             ??? ADC1 calibration 10                            = -44 R/W (0b101011)
ADC1_MODE2_D1 (BLOCK2)                             ??? ADC1 calibration 11                            = 44 R/W (0b001011)
ADC1_MODE3_D1 (BLOCK2)                             ??? ADC1 calibration 12                            = -72 R/W (0b110010)
ADC2_MODE0_D1 (BLOCK2)                             ??? ADC2 calibration 13                            = -112 R/W (0b111100)
ADC2_MODE1_D1 (BLOCK2)                             ??? ADC2 calibration 14                            = -108 R/W (0b111011)
ADC2_MODE2_D1 (BLOCK2)                             ??? ADC2 calibration 15                            = 92 R/W (0b010111)
ADC2_MODE3_D1 (BLOCK2)                             ??? ADC2 calibration 16                            = 68 R/W (0b010001)

Config fuses:
DIS_ICACHE (BLOCK0)                                Disables ICache                                    = False R/W (0b0)
DIS_DCACHE (BLOCK0)                                Disables DCache                                    = False R/W (0b0)
DIS_DOWNLOAD_ICACHE (BLOCK0)                       Disables Icache when SoC is in Download mode       = False R/W (0b0)
DIS_DOWNLOAD_DCACHE (BLOCK0)                       Disables Dcache when SoC is in Download mode       = False R/W (0b0)
DIS_FORCE_DOWNLOAD (BLOCK0)                        Disables forcing chip into Download mode           = False R/W (0b0)
DIS_CAN (BLOCK0)                                   Disables the TWAI Controller hardware              = False R/W (0b0)
DIS_APP_CPU (BLOCK0)                               Disables APP CPU                                   = False R/W (0b0)
FLASH_TPUW (BLOCK0)                                Configures flash startup delay after SoC power-up, = 0 R/W (0x0)
                                                    unit is (ms/2). When the value is 15, delay is 7.
                                                   5 ms                                              
DIS_DIRECT_BOOT (BLOCK0)                           Disables direct boot mode                          = True R/W (0b1)
DIS_USB_SERIAL_JTAG_ROM_PRINT (BLOCK0)             Disables USB-Serial-JTAG ROM printing              = False R/W (0b0)
FLASH_ECC_MODE (BLOCK0)                            Configures the ECC mode for SPI flash             
   = 16-byte to 18-byte mode R/W (0b0)
DIS_USB_SERIAL_JTAG_DOWNLOAD_MODE (BLOCK0)         Disables USB-Serial-JTAG download feature in UART  = False R/W (0b0)
                                                   download boot mode                                
UART_PRINT_CONTROL (BLOCK0)                        Sets the default UART boot message output mode     = Enabled R/W (0b00)
FLASH_TYPE (BLOCK0)                                Selects SPI flash type                             = 4 data lines R/W (0b0)
FLASH_PAGE_SIZE (BLOCK0)                           Sets the size of flash page                        = 0 R/W (0b00)
FLASH_ECC_EN (BLOCK0)                              Enables ECC in Flash boot mode                     = False R/W (0b0)
FORCE_SEND_RESUME (BLOCK0)                         Forces ROM code to send an SPI flash resume comman = False R/W (0b0)
                                                   d during SPI boot                                 
DIS_USB_OTG_DOWNLOAD_MODE (BLOCK0)                 Disables USB-OTG download feature in UART download = True R/W (0b1)
                                                    boot mode                                        
DISABLE_WAFER_VERSION_MAJOR (BLOCK0)               Disables check of wafer version major              = False R/W (0b0)
DISABLE_BLK_VERSION_MAJOR (BLOCK0)                 Disables check of blk version major                = False R/W (0b0)
BLOCK_USR_DATA (BLOCK3)                            User data                                         
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W 

Efuse fuses:
WR_DIS (BLOCK0)                                    Disables programming of individual eFuses          = 8388864 R/W (0x00800100)
RD_DIS (BLOCK0)                                    Disables software reading from BLOCK4-10           = 0 R/W (0b0000000)

Identity fuses:
SECURE_VERSION (BLOCK0)                            Secure version (used by ESP-IDF anti-rollback feat = 0 R/W (0x0000)
                                                   ure)                                              
MAC (BLOCK1)                                       Factory MAC Address                               
   = 7c:df:a1:fd:6d:90 (OK) R/W 
WAFER_VERSION_MINOR_LO (BLOCK1)                    WAFER_VERSION_MINOR least significant bits         = 1 R/W (0b001)
PKG_VERSION (BLOCK1)                               Package version                                    = 0 R/W (0b000)
BLK_VERSION_MINOR (BLOCK1)                         BLOCK version minor                                = 2 R/W (0b010)
WAFER_VERSION_MINOR_HI (BLOCK1)                    WAFER_VERSION_MINOR most significant bits          = 0 R/W (0b0)
WAFER_VERSION_MAJOR (BLOCK1)                       WAFER_VERSION_MAJOR                                = 0 R/W (0b00)
OPTIONAL_UNIQUE_ID (BLOCK2)                        Optional unique 128-bit ID                        
   = 35 a2 2f d9 72 90 cc 73 65 96 7d 64 13 bc cc 0b R/W 
BLK_VERSION_MAJOR (BLOCK2)                         BLOCK version major                                = With calibration R/W (0b01)
CUSTOM_MAC (BLOCK3)                                Custom MAC Address                                
   = 00:00:00:00:00:00 (OK) R/W 
WAFER_VERSION_MINOR (BLOCK0)                       calc WAFER VERSION MINOR = WAFER_VERSION_MINOR_HI  = 1 R/W (0x1)
                                                   << 3 + WAFER_VERSION_MINOR_LO (read only)         

Security fuses:
SOFT_DIS_JTAG (BLOCK0)                             Software disables JTAG by programming odd number o = 0 R/W (0b000)
                                                   f 1 bit(s). JTAG can be re-enabled via HMAC periph
                                                   eral                                              
HARD_DIS_JTAG (BLOCK0)                             Hardware disables JTAG permanently                 = False R/W (0b0)
DIS_DOWNLOAD_MANUAL_ENCRYPT (BLOCK0)               Disables flash encryption when in download boot mo = False R/W (0b0)
                                                   des                                               
SPI_BOOT_CRYPT_CNT (BLOCK0)                        Enables encryption and decryption, when an SPI boo = Disable R/W (0b000)
                                                   t mode is set. Enabled when 1 or 3 bits are set,di
                                                   sabled otherwise                                  
SECURE_BOOT_KEY_REVOKE0 (BLOCK0)                   Revokes use of secure boot key digest 0            = False R/W (0b0)
SECURE_BOOT_KEY_REVOKE1 (BLOCK0)                   Revokes use of secure boot key digest 1            = True R/W (0b1)
SECURE_BOOT_KEY_REVOKE2 (BLOCK0)                   Revokes use of secure boot key digest 2            = True R/W (0b1)
KEY_PURPOSE_0 (BLOCK0)                             KEY0 purpose                                       = SECURE_BOOT_DIGEST0 R/- (0x9)
KEY_PURPOSE_1 (BLOCK0)                             KEY1 purpose                                       = USER R/W (0x0)
KEY_PURPOSE_2 (BLOCK0)                             KEY2 purpose                                       = USER R/W (0x0)
KEY_PURPOSE_3 (BLOCK0)                             KEY3 purpose                                       = USER R/W (0x0)
KEY_PURPOSE_4 (BLOCK0)                             KEY4 purpose                                       = USER R/W (0x0)
KEY_PURPOSE_5 (BLOCK0)                             KEY5 purpose                                       = USER R/W (0x0)
SECURE_BOOT_EN (BLOCK0)                            Enables secure boot                                = True R/W (0b1)
SECURE_BOOT_AGGRESSIVE_REVOKE (BLOCK0)             Enables aggressive secure boot key revocation mode = False R/W (0b0)
STRAP_JTAG_SEL (BLOCK0)                            Enable selection between usb_to_jtagor pad_to_jtag = False R/W (0b0)
                                                    through GPIO3                                    
DIS_DOWNLOAD_MODE (BLOCK0)                         Disables all Download boot modes                   = False R/W (0b0)
ENABLE_SECURITY_DOWNLOAD (BLOCK0)                  Enables secure UART download mode (read/write flas = False R/W (0b0)
                                                   h only)                                           
BLOCK_KEY0 (BLOCK4)
  Purpose: SECURE_BOOT_DIGEST0
  Encryption key0 or user data                      
   = 4e 8c 03 53 d4 db 8a 28 8c 6f cb 0b 3f 6f 02 fa 5b 32 b1 54 1d da b0 ff f0 6d 8e 24 01 96 1c c8 R/- 
BLOCK_KEY1 (BLOCK5)
  Purpose: USER
               Encryption key1 or user data                      
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W 
BLOCK_KEY2 (BLOCK6)
  Purpose: USER
               Encryption key2 or user data                      
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W 
BLOCK_KEY3 (BLOCK7)
  Purpose: USER
               Encryption key3 or user data                      
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W 
BLOCK_KEY4 (BLOCK8)
  Purpose: USER
               Encryption key4 or user data                      
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W 
BLOCK_KEY5 (BLOCK9)
  Purpose: USER
               Encryption key5 or user data                      
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W 
BLOCK_SYS_DATA2 (BLOCK10)                          System data (part 2)                              
   = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W 

Spi_Pad_Config fuses:
SPI_PAD_CONFIG_CLK (BLOCK1)                        SPI CLK pad                                        = 0 R/W (0b000000)
SPI_PAD_CONFIG_Q (BLOCK1)                          SPI Q (D1) pad                                     = 0 R/W (0b000000)
SPI_PAD_CONFIG_D (BLOCK1)                          SPI D (D0) pad                                     = 0 R/W (0b000000)
SPI_PAD_CONFIG_CS (BLOCK1)                         SPI CS pad                                         = 0 R/W (0b000000)
SPI_PAD_CONFIG_HD (BLOCK1)                         SPI HD (D3) pad                                    = 0 R/W (0b000000)
SPI_PAD_CONFIG_WP (BLOCK1)                         SPI WP (D2) pad                                    = 0 R/W (0b000000)
SPI_PAD_CONFIG_DQS (BLOCK1)                        SPI DQS pad                                        = 0 R/W (0b000000)
SPI_PAD_CONFIG_D4 (BLOCK1)                         SPI D4 pad                                         = 0 R/W (0b000000)
SPI_PAD_CONFIG_D5 (BLOCK1)                         SPI D5 pad                                         = 0 R/W (0b000000)
SPI_PAD_CONFIG_D6 (BLOCK1)                         SPI D6 pad                                         = 0 R/W (0b000000)
SPI_PAD_CONFIG_D7 (BLOCK1)                         SPI D7 pad                                         = 0 R/W (0b000000)

Usb Config fuses:
DIS_USB (BLOCK0)                                   Disables the USB OTG hardware                      = False R/W (0b0)
USB_EXCHG_PINS (BLOCK0)                            Exchanges USB D+ and D- pins                       = False R/W (0b0)
EXT_PHY_ENABLE (BLOCK0)                            Enables external USB PHY                           = False R/W (0b0)
BTLC_GPIO_ENABLE (BLOCK0)                          Enables BTLC GPIO                                  = 0 R/W (0b00)
DIS_USB_JTAG (BLOCK0)                              Disable usb_serial_jtag-to-jtag function           = False R/W (0b0)
DIS_USB_SERIAL_JTAG (BLOCK0)                       Disable usb_serial_jtag module                     = False R/W (0b0)
USB_PHY_SEL (BLOCK0)                               Select internal/external PHY for USB OTGand usb_se = False R/W (0b0)
                                                   rial_jtag                                         

Vdd_Spi Config fuses:
VDD_SPI_XPD (BLOCK0)                               The VDD_SPI regulator is powered on                = True R/W (0b1)
VDD_SPI_TIEH (BLOCK0)                              The VDD_SPI power supply voltage at reset         
   = Connect to VDD_RTC_IO R/W (0b1)
VDD_SPI_FORCE (BLOCK0)                             Force using VDD_SPI_XPD and VDD_SPI_TIEH to config = True R/W (0b1)
                                                   ure VDD_SPI LDO                                   
PIN_POWER_SELECTION (BLOCK0)                       Sets default power supply for GPIO33..37           = VDD_SPI R/W (0b1)

Wdt Config fuses:
WDT_DELAY_SEL (BLOCK0)                             Selects RTC WDT timeout threshold at startup       = 0 R/W (0b00)

Flash voltage (VDD_SPI) set to 3.3V by efuse.
  1. pretty sure, I have several PCBs and those without sec-boot do fine.
  2. I just flashed the sec enabled bootloader and starting the system the bootloader wrote the key-hash to block 4 and set 8 more efuse-bits in block 0: 8: Write protect Key 0 purpose WR_DIS_KEY0_PURPOSE 23: Write protect Key 0 WR_DIS_KEY0 86: Secure boot key revoke 1 SECURE_BOOT_KEY_REVOKE1 87: Secure boot key revoke 2 SECURE_BOOT_KEY_REVOKE2 88+91: Key 0 purpose KEY_PURPOSE_0 116: Secure boot enable SECURE_BOOT_EN (do verify signature before starting code) 129: Disable direct boot mode DIS_DIRECT_BOOT (application start via second stage BL only) Blocks 1+2 are unchanged.
    I (754) secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set
    I (762) secure_boot_v2: Verifying with RSA-PSS...
    I (770) secure_boot_v2: Signature verified successfully!
    I (774) secure_boot_v2: Secure boot digests absent, generating..
    I (786) secure_boot_v2: Digests successfully calculated, 1 valid signatures (image offset 0x0)
    I (789) secure_boot_v2: 1 signature block(s) found appended to the bootloader.
    I (797) secure_boot_v2: Burning public key hash to eFuse
    I (806) efuse: Writing EFUSE_BLK_KEY0 with purpose 9
    I (1123) secure_boot_v2: Digests successfully calculated, 1 valid signatures (image offset 0x20000)
    I (1124) secure_boot_v2: 1 signature block(s) found appended to the app.
    I (1129) secure_boot_v2: Application key(0) matches with bootloader key(0).
    I (1137) secure_boot_v2: Revoking empty key digest slot (1)...
    I (1143) secure_boot_v2: Revoking empty key digest slot (2)...
    I (1150) secure_boot_v2: blowing secure boot efuse...
    W (1156) secure_boot: UART ROM Download mode kept enabled - SECURITY COMPROMISED
    W (1164) secure_boot: Not disabling JTAG - SECURITY COMPROMISED
    W (1170) secure_boot: Allowing read disabling of additional efuses - SECURITY COMPROMISED
    I (1180) efuse: BURN BLOCK4
    I (1186) efuse: BURN BLOCK4 - OK (write block == read block)
    I (1189) efuse: BURN BLOCK0
    I (1194) efuse: BURN BLOCK0 - OK (all write block bits are set)
    I (1199) efuse: Batch mode. Prepared fields are committed
    I (1205) secure_boot_v2: Secure boot permanently enabled
    I (1211) boot: Disabling RNG early entropy source...
    I (2428) main: CPU0 app_main_plus started
  3. No, right now I was not brave enough for that. Secure boot itself is enough trouble.
  4. No. Shall this make a difference? My host is an Ubuntu 22.04.2 LTS
mahavirj commented 1 year ago

@mhgue

In my application secure boot is only needed to verify OTA updates. Protection against direct access to the HW is not needed.

Please check documentation section regarding secure OTA without secure boot here and here.

mhgue commented 1 year ago

@mahavirj Thank you. I will have a look, this might be a workaround for me. Regardless, I'd like to continue using the already irreversibly secure booting device, to assist @radimkarnis in clarifying this issue as described.

One unfavourable consequence of secure OTA without secure boot seems to be, that using multiple trusted public keys is no longer possible. Verification is always done with the public key of the running application in the first position only.

radimkarnis commented 1 year ago

Hi @mhgue, thanks again for trying to debug the issue. We are actively trying to reproduce it but without any luck. In our tests, everything works as intended.

The 01060000: Operation or feature not supported error code from the ROM seems to be connected to the SPI Flash chip operations. That leads me to believe maybe this is not an ESP issue, but a problem with the flash chip.

We can try to narrow the problem down. For starters - could you please try the same process on a different host machine? Thank you.

mhgue commented 1 year ago

Hi @radimkarnis, thank you again for investigating this issue. I have no special or extra flash chip. It is a ready to use ESP32-S3-WROOM-1-n16r8 module with 16 MB flash right from the market. There is absolutely nothing special with it. Is there a way to identify the flash chip build inside the WROOM? To try the process on a differnet host machine will take some time, because I usually only use Ubuntu Linux, no MacOS and no others capable of using the IDF. But maybe I can find a way with a virtual machine. If it belongs to the flash chip, it would be interesting to try a module with a differnet chip. What module exactly have your used for your tries? In your tests are there both way working, with and without stub? Thank you.

Ramakrishna247 commented 1 year ago

Hi,

I'am also facing similar issue with the ESP32 S3 N16R8 , my host machine is Windows 11, using VS code . tried IDF versions 4.4, 4.4.3 and 5.0 I have enabled the secure boot and Flash encryption , I'am able to flash the application in the first OTA partition , but if i'am trying to flash the application manually in to 2nd OTA partition i'am getting issue as bellow

esptool.py v3.3.2 Serial port COM3 Connecting.... Chip is ESP32-S3 Features: WiFi, BLE Crystal is 40MHz MAC: f4:12:fa:d6:f2:70 Changing baud rate to 460800 Changed. Enabling default SPI flash mode... Configuring flash size... Flash will be erased from 0x0000b000 to 0x0000bfff... Flash will be erased from 0x0001d000 to 0x0001efff... Flash will be erased from 0x00220000 to 0x00310fff... Erasing flash... Took 0.06s to erase flash block Wrote 3072 bytes at 0x0000b000 in 0.1 seconds (169.1 kbit/s)... Erasing flash... Took 0.09s to erase flash block Wrote 8192 bytes at 0x0001d000 in 0.4 seconds (172.1 kbit/s)... Erasing flash...

A fatal error occurred: Failed to enter Flash download mode (result was 01060000: Operation or feature not supported)

My partition table is as below.

Partition table binary generated. Contents:


ESP-IDF Partition Table

Name, Type, SubType, Offset, Size, Flags

nvs_key,data,nvs_keys,0xc000,4K,encrypted nvs,data,nvs,0xd000,64K, otadata,data,ota,0x1d000,8K, phy_init,data,phy,0x1f000,4K, ota_0,app,ota_0,0x20000,2M, ota_1,app,ota_1,0x220000,2M, file,data,spiffs,0x420000,12160K,


Also I have configured PSRAM as octal OPI , 40 MHZ and serial flash as QIO , 80 MHZ, i have tried different configurations of PSRAM and FLASH but no luck. Please help me to resolve the issue.

Also i tried to update binary via OTA, Iam not able to do OTA also as soon as binary gets downloaded and second stage bootloader verification of downloaded app is successful a stackover flow is happening.

mhgue commented 1 year ago

Hi @radimkarnis, I think the best way to reproduce this for you, is to use my HW. I have got the permission to send you the board. On the backside there is the 6-pole connector for the ESPprog. If you give me a postal address, I will send you the board. You can keep it if you like. We do have an update server providing signed images for testing.

p.s.: As suggested by @mahavirj I am currently using signature of application without secure boot, which is working fine, but full protection with more than one key and maybe later with encryption would be the goal.

gm-jiang commented 1 year ago

@mhgue Note that if secure boot v2 is enabled, then the ROM code will refuse to execute the stub even if the stub has been downloaded into RAM. Because we think it is not safe to execute stub. The correct logic should be bootROM(trusted) + efuse (trusted) ---> verify 2ndbootload ---> verify application.

gm-jiang commented 1 year ago

For errors A fatal error occurred: Failed to enter Flash download mode (result was 01060000: Operation or feature not supported) . In fact, this is a normal download process (without --no-stub ), I don't think it has anything to do with secureboot, the error code show that the esptool message is ok,but the runing result is wrong(Erase flash failed).

Ramakrishna247 commented 1 year ago

Hi,

@gm-jiang is there any other way to flash the 2nd partition, also why esptool.py not able to erase the second partition ?

gm-jiang commented 1 year ago

@Ramakrishna247 From what I can see so far, there are some reasons for flash erasing failure in ROM download stage.

  1. start_addr + len > flash chip size
  2. start_addr not align to sector size
  3. Unlock flash failed
  4. Erase flash sector/block failed

If possible, could you connect a logic analyzer to see the signal on the SPI bus, this can determine whether the flash chip is hung up.

gm-jiang commented 1 year ago

Related with https://github.com/espressif/esp-idf/issues/10959#issuecomment-1466037168

mhgue commented 1 year ago

Hi @gm-jiang, concerning your first comment: yes that is the reason why I tried both (with and without stub), because I saw that components/bootloader/Kconfig.projbuild disables stub usage for S3 but not for S2. So the decision to consider it unsafe to execute stubs obviously was made in between and I just wanted to try if it was just a wrong config entry. In general I perfectly agree with that, but it makes operation without stub indispensable.

concerning your second comment: Good point. I will try flash without stub on a device without secure boot.

Emill commented 1 year ago

@gm-jiang, for ESP32-S3, when the SECURE_BOOT_EN bit has been enabled in efuse, is code execution from RAM totally disabled in all possible means when the chip is booted in uart download mode, or can e.g. a signed RSA signature be appended (in RAM) so that it allows to run the stub?

gm-jiang commented 1 year ago

@Emill Good question, but the bootROM does not support the feature of verifying the stub.

Emill commented 1 year ago

It seems like the ROM loader by default fails the flash command for certain addresses for ESP32-S3 with a 16 MB flash.

If the --flash_size 16MB is passed to esptool.py, it works as expected. This can be configured using idf.py menuconfig by going to Serial flasher config -> Flash size (16 MB).

Not sure if this should be treated as a bug in the ROM loader, or something that should be expected. In any case, maybe it's possible to implement a workaround in esptool.py to maybe figure out the flash size by reading/writing SPI registers and automatically set it accordingly, if the user has not provided the flash size.

Regarding the "security feature" to not allow execution of code passed in download mode, it's a bit strange that arbitrary register reads/writes are allowed (which basically gives full access anyway) but not code execution. I would rather write in the user manual that a "secure boot" enabled device is of course only actually protected if Download Mode is disabled (or maybe when Secure Download Mode is enabled).

mahavirj commented 1 year ago

@Emill

Regarding the "security feature" to not allow execution of code passed in download mode, it's a bit strange that arbitrary register reads/writes are allowed (which basically gives full access anyway) but not code execution

Yes, ideally the secure DL mode along with the secure boot should control the stub execution over UART. We have this addressed in our recent chips like C6/H2 but for S3 as you rightly mentioned that only secure boot configuration disallows the stub execution.

Just a note that we always recommend enabling secure DL mode along with any security features, please see: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/security/security.html#debug-interfaces

radimkarnis commented 1 year ago

This has been fixed in esptool v4.6. Running the install script again should install the latest available version.

If you are using the secure download mode, the flash size has to be explicitly set in menuconfig.

Closing this issue. Thanks everyone for the investigation.

discreetmayor commented 7 months ago

Using esptool.py 4.7, it looks like I am facing the same issue. Could it have to do that I am writing to ota_1 and not "factory"? Secure Boot v2 and flash encryption both enabled. I am able to flash bootloader and partition table.

esptool.py -p /dev/cu.usbmodem101 --chip esp32c6 write_flash --flash_size keep 0x1a0000 firmware-ota1-enc.bin --force esptool.py v4.7.0 Serial port /dev/cu.usbmodem101 Connecting... Chip is ESP32-C6 in Secure Download Mode WARNING: Stub loader is not supported in Secure Download Mode, setting --no-stub Enabling default SPI flash mode... Configuring flash size... Flash will be erased from 0x001a0000 to 0x002a0fff... Erasing flash...

A fatal error occurred: Failed to enter Flash download mode (result was 01060000: Operation or feature not supported)

radimkarnis commented 7 months ago

Hello @discreetmayor,

The solution is mentioned above:

If you are using the secure download mode, the flash size has to be explicitly set in menuconfig.

Please change --flash_size keep to a specific flash size. That should fix the issue.