Skip to content

Signed OTA updates not working at all #783

@maxgerhardt

Description

@maxgerhardt

While integrating OTA updates (works) and signed OTA updates (doesn't work) into PlatformIO, I stumbled upon these problems:

First: Even though the platform.txt generates the Updater_Signing.h by using the command

recipe.hooks.sketch.prebuild.pattern="{runtime.tools.pqt-python3.path}/python3" -I "{runtime.platform.path}/tools/signing.py" --mode header --publickey "{build.source.path}/public.key" --out "{build.path}/core/Updater_Signing.h"

in the path

{build.path}/core/Updater_Signing.h

This folder is not in the include path when the WiFi and Update etc. libraries are built. This is evident by looking at the verbose build command

"C:\Users\Max\AppData\Local\Arduino15\packages\rp2040\tools\pqt-gcc\1.4.0-c-0196c06/bin/arm-none-eabi-g++" -c -Werror=return-type -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DUSB_VID=0x2e8a -DUSB_PID=0xf00a "-DUSB_MANUFACTURER="Raspberry Pi"" "-DUSB_PRODUCT="Pico W"" -DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_LWIP=0 -DLWIP_IPV6=0 -DLWIP_IPV4=1 -DLWIP_IGMP=1 -DLWIP_CHECKSUM_CTRL_PER_NETIF=1 "-DARDUINO_VARIANT="rpipicow"" -march=armv6-m -mcpu=cortex-m0plus -mthumb -ffunction-sections -fdata-sections -fno-exceptions -DARM_MATH_CM0_FAMILY -DARM_MATH_CM0_PLUS -MMD "-iprefixC:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0/" "@C:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0/lib/platform_inc.txt" "-IC:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0/include" -fno-rtti -std=gnu++17 -g -DSERIALUSB_PID=0xf00a -DUSBD_MAX_POWER_MA=250 -DF_CPU=133000000L -DARDUINO=10819 -DARDUINO_RASPBERRY_PI_PICO_W "-DBOARD_NAME="RASPBERRY_PI_PICO_W"" -DARDUINO_ARCH_RP2040 -Os "-IC:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0\cores\rp2040" "-IC:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0\variants\rpipicow" "-IC:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0\libraries\WiFi\src" "-IC:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0\libraries\Updater\src" "-IC:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0\libraries\MD5Builder\src" "-IC:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0\libraries\LEAmDNS\src" "-IC:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0\libraries\lwIP_Ethernet\src" "-IC:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0\libraries\ArduinoOTA\src" "-IC:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0\libraries\LittleFS\src" "-IC:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0\libraries\lwIP_CYW43\src" "-IC:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0\libraries\SPI\src" "-IC:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0\libraries\PicoOTA\src" "C:\Users\Max\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\2.4.0\libraries\WiFi\src\BearSSLHelpers.cpp" -o "C:\Users\Max\AppData\Local\Temp\arduino_build_461914\libraries\WiFi\BearSSLHelpers.cpp.o"

There would have to be a reference to -I C:\Users\Max\AppData\Local\Temp\arduino_build_xxxx\core there since the file was generated there, which there isn't. This is using the latest Arduino IDE 1.8.19

grafik

So instead of the generated one they always get the default file in https://github.com/earlephilhower/arduino-pico/blob/master/libraries/Updater/src/Updater_Signing.h.

Second:

//#include <Updater_Signing.h>
#ifndef ARDUINO_SIGNING
#define ARDUINO_SIGNING 0
#endif

being commented out, the BearSSLHelper.cpp does not recognize whether signing is on or off, and always assumes signing is off.

This leads (when issue 1 is fixed) to a later linking error when another library needs the objects that BearSSLHelper.cpp would have created and leads to a linking error.

Linking .pio\build\rpipicow_via_usb\firmware.elf
c:/users/max/.platformio/packages/toolchain-rp2040-earlephilhower/bin/../lib/gcc/arm-none-eabi/10.3.0/../../../../arm-none-eabi/bin/ld.exe: .pio\build\rpipicow_via_usb\lib771\Updater\Updater.cpp.o: in function `_ZN12UpdaterClassC1Ev':
Updater.cpp:(.text._ZN12UpdaterClassC2Ev+0x70): undefined reference to `_ZN7esp826622updaterSigningVerifierE'
c:/users/max/.platformio/packages/toolchain-rp2040-earlephilhower/bin/../lib/gcc/arm-none-eabi/10.3.0/../../../../arm-none-eabi/bin/ld.exe: Updater.cpp:(.text._ZN12UpdaterClassC2Ev+0x74): undefined reference to `_ZN7esp826618updaterSigningHashE'
collect2.exe: error: ld returned 1 exit status

And third: Even when both of these issues are fixed (added -I flag and commenting in the include), the update does accept the signed binary.

Progress: 5%
[...]
Error[4]: End Failed
ERROR[12]: Signature verification failed

So while in the Arduino IDE, the "Signed OTA" update example indeed "seems to work" because it generates the signed binary and uploading the binary via WiFi works, it actually does only work because it does not do any verification at all.

And fourth: The platform.txt only has the capability to upload the firmware.bin, never the firmware.bin.signed, so all signed OTA uploading must be done manually.

tools.uf2conv.upload.network_pattern="{network_cmd}" -I "{runtime.platform.path}/tools/espota.py" -i "{serial.port}" -p "{network.port}" "--auth={network.password}" -f "{build.path}/{build.project_name}.bin"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions