Made by @adidshaft ↗

Grok Bot is made by SpaceXSI.
Grok Gadgets is an independent project.

↗

Signed updates on the ESP32

A Wi-Fi gadget can take a new image from the relay with no cable (hub ADR 012). The gateway's signed updates guide covers the key, signing and the relay. This page covers the firmware.

On this page

What the gadget does

  1. It sends "update": "ready" in its hello, only when the build compiled in a public key.
  2. When the relay offers an update, it checks the ECDSA P-256 signature with the compiled key. Then it checks the format, the board, the protocol, the version and the size. On a failure it reports rejected and downloads nothing.
  3. It downloads 1,024-byte chunks into the other app slot with Update.write. It still polls at least once a second, so commands keep working. The OLED kit shows Update 42%.
  4. It checks the byte count and the SHA-256 before Update.end(). On a mismatch it reports failed, and the running image stays.
  5. It restarts. The new image starts pending verify. It marks itself valid only after the relay accepts a hello and answers a poll. Then it reports applied.
  6. If the new image is not Online within 5 minutes, it marks itself invalid and the previous image starts. A crash or a power cut on trial has the same result. The previous image reports reverted and refuses that version from then on. The OLED kit shows Reverted for a minute.

A lost connection or a power cut during a download leaves the running image in place. The download starts again from the beginning at the next offer.

Build an image that takes updates

The build compiles in the public key from a file outside the repository:

GROK_UPDATE_PUBLIC_KEY=~/grok-keys/builder.pub.pem .venv/bin/pio run -e esp32s3-oled-kit-wifi

GROK_FIRMWARE_VERSION replaces the version the image reports. The kit's default is the SDK release, for example 0.2.0-alpha.17. Sign each image with the same string:

GROK_UPDATE_PUBLIC_KEY=~/grok-keys/builder.pub.pem GROK_FIRMWARE_VERSION=0.2.0-alpha.17.1 \
  .venv/bin/pio run -e esp32s3-oled-kit-wifi

Without GROK_UPDATE_PUBLIC_KEY the image never asks for updates. Its checksum then depends only on the source and the toolchain. An image with a key differs per builder.

Flash the first update-capable image over USB once. After that, sign each new image with the gateway's firmware sign, using --board esp32s3-oled-kit-wifi and the same version.

To prove the revert, build a signed test image that never connects. Add PLATFORMIO_BUILD_FLAGS=-DOLED_KIT_TEST_NEVER_ONLINE to the build command, with its own GROK_FIRMWARE_VERSION. It reverts 5 minutes after it starts. Never ship it.

The esp32s3-oled-kit-wifi-updates environment compiles the update path with the gateway fixture's test key. It is a compile check; never flash it.

Your own sketch

#include <GrokSession.h>
#include <GrokUpdateEsp.h>
#include "grok_update_key.h" // Generated by tools/update_build.py: GrokUpdateKey, GrokUpdateBoard

grok::EspUpdatePlatform updatePlatform;
grok::MbedtlsUpdateCrypto updateCrypto(GrokUpdateKey);
grok::Updater updater(updatePlatform, updateCrypto, GrokUpdateBoard, "1.0.0");
extern "C" bool verifyRollbackLater() { return true; } // The updater decides, not Arduino.

void setup() {
  // ... capabilities ...
  updater.begin(millis());
  gadget.updates(updater);
  gadget.begin(link);
}
void loop() {
  gadget.loop();
  updater.loop(millis());
}

MbedtlsUpdateCrypto takes a second key. To move to a new key, ship an image that trusts both keys, then sign with the new one.

Cost on the kit

Arduino-ESP32 2.0.17, esp32s3-oled-kit-wifi, 17 October 2026:

Build Static RAM (bytes) Flash (bytes)
No key (updates off) 108,124 933,973
Key compiled in 109,252 943,481

During a download the updater also uses about 2 KB of stack: one chunk buffer and the manifest parser.

Limits

  • Anti-rollback is off. The gadget accepts any signed version other than the running one and other than a reverted one.
  • Secure boot and flash encryption are off. Anyone with the board and a cable can flash it. The signature check protects the over-the-air path only.
  • The bootloader written by the USB flash stays. An update replaces the application only.

Source: grok-gadgets-esp32-sdk/docs/updates.md