This is an old revision of the document!


Lab 10. Secure OTA

This lab shows how to implement real remote firmware updates from a browser for an ESP32-C6 board using PlatformIO + pioarduino and an Async Web OTA page powered by ElegantOTA.

You will:

  • flash a first “baseline” firmware over USB,
  • host an authenticated OTA webpage on the device,
  • upload a new firmware from your browser,
  • verify success with a visible NeoPixel behavior change,
  • document basic threat-model thinking.

Learning outcomes

After completing this lab, you can:

  1. Explain why OTA requires an A/B (dual-slot) style partition table.
  2. Configure PlatformIO to use pioarduino and an OTA partition scheme.
  3. Implement a device-hosted OTA updater available at /update.
  4. Validate OTA end-to-end by changing device behavior without USB access.
  5. Identify key security risks for OTA and apply simple mitigations.

Concept snapshot

What you are building:

  • Your device runs a small web server.
  • Visiting http:<device-ip>/update opens a firmware upload page. * The new firmware is written into the inactive OTA slot. * After reboot, the bootloader selects the new slot. Why two slots? If an update fails mid-way (power loss, bad binary), the device still has a valid previous firmware to boot. This is the core reliability concept behind OTA on constrained devices. ===== Part A — Create the PlatformIO project ===== Create a new PlatformIO project and create or replace your ``platformio.ini`` with: <code ini platformio.ini> [env:sparrow_c6] platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip board = esp32-c6-devkitm-1 framework = arduino monitor_speed = 115200 ; Use OTA-capable partition table board_build.partitions = sparrow_ota_4mb.csv ; Optional but often helpful build_flags = -D CORE_DEBUG_LEVEL=1 -D ARDUINO_USB_MODE=1 -D ARDUINO_USB_CDC_ON_BOOT=1 -D ESP32_C6_env -D ELEGANTOTA_USE_ASYNC_WEBSERVER=1 lib_deps = ESP32Async/AsyncTCP@^3.4.9 ESP32Async/ESPAsyncWebServer@^3.9.2 ayushsharma82/ElegantOTA adafruit/Adafruit NeoPixel lib_ignore = AsyncTCP_RP2040W </code> ==== A2. Add the partition table file ==== In your project root (next to ``platformio.ini``), create ``sparrow_ota_4mb.csv``. Paste this: <code csv> # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x5000, otadata, data, ota, 0xE000, 0x2000, app0, app, ota_0, 0x10000, 0x140000, app1, app, ota_1, , 0x140000, spiffs, data, spiffs, , 0xD0000, </code> This layout assumes 4MB internal flash and gives you two OTA application slots plus a small SPIFFS area. ===== Part B — Baseline firmware with Async OTA web page ===== Create ``src/main.cpp`` and paste the code from here then build and upload via USB. You should see: * Wi-Fi connection dots * A printed IP address * A message telling you to open ``/update`` In your browser: * ``http:<device-ip>/``
  • ``http:<device-ip>/update`` Log in with: * user: ``admin`` * pass: ``change-me`` ===== Part C — OTA proof using a NeoPixel blink change ===== Now you will make a visible change and deliver it without USB. Add a small LED pattern into main.cpp, you can get the new code from here.
iothings/laboratoare/2025/lab10.1765041049.txt.gz · Last modified: 2025/12/06 19:10 by dan.tudose
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0