-
Notifications
You must be signed in to change notification settings - Fork 515
Description
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
Line 107 in a2465f5
| 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
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:
arduino-pico/libraries/WiFi/src/BearSSLHelpers.cpp
Lines 32 to 35 in a2465f5
| //#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.
Line 163 in a2465f5
| 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" |
