Skip to content

Update using encrypted firmware binary does not appear to work #10205

@victorfleischauer

Description

@victorfleischauer

Board

ESP32-S3-DevKitC-1

Device Description

ESP32-S3-DevKitC-1 v1.0

Hardware Configuration

No other hardware attached.

Version

3.0.4

IDE Name

PlatformIO

Operating System

Windows 11

Flash frequency

40Mhz

PSRAM enabled

no

Upload speed

460800

Description

Update using an encrypted firmware does not appear to work correctly as it seems to try to decrypt incorrectly.
When using a slightly modified version of the example sketch "OTAWebUpdater" to include

const uint8_t key[32] = {/* PUT YOUR KEY HERE */};
Update.setupCrypt(key, 0, 0, U_AES_DECRYPT_ON);

in void handleUpdate(), the update does not work and during it the error "Wrong Magic Byte" is printed repeatedly.

Proposed solution

By changing MBEDTLS_AES_ENCRYPT to MBEDTLS_AES_DECRYPT in line 331 of Updater.cpp the code works as expected.

Sketch

#include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <Update.h>
#include <Ticker.h>
#include "html.h"

#define SSID_FORMAT "ESP32-%06lX"  // 12 chars total
//#define PASSWORD "test123456"    // generate if remarked

WebServer server(80);
Ticker tkSecond;
uint8_t otaDone = 0;

const char *alphanum = "0123456789!@#$%^&*abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
String generatePass(uint8_t str_len) {
  String buff;
  for (int i = 0; i < str_len; i++) {
    buff += alphanum[random(strlen(alphanum) - 1)];
  }
  return buff;
}

void apMode() {
  char ssid[13];
  char passwd[11];
  long unsigned int espmac = ESP.getEfuseMac() >> 24;
  snprintf(ssid, 13, SSID_FORMAT, espmac);
#ifdef PASSWORD
  snprintf(passwd, 11, PASSWORD);
#else
  snprintf(passwd, 11, generatePass(10).c_str());
#endif
  WiFi.mode(WIFI_AP);
  WiFi.softAP(ssid, passwd);  // Set up the SoftAP
  MDNS.begin("esp32");
  Serial.printf("AP: %s, PASS: %s\n", ssid, passwd);
}

void handleUpdateEnd() {
  server.sendHeader("Connection", "close");
  if (Update.hasError()) {
    server.send(502, "text/plain", Update.errorString());
  } else {
    server.sendHeader("Refresh", "10");
    server.sendHeader("Location", "/");
    server.send(307);
    ESP.restart();
  }
}

void handleUpdate() {
  size_t fsize = UPDATE_SIZE_UNKNOWN;
  if (server.hasArg("size")) {
    fsize = server.arg("size").toInt();
  }
  HTTPUpload &upload = server.upload();
  if (upload.status == UPLOAD_FILE_START) {
    Serial.printf("Receiving Update: %s, Size: %d\n", upload.filename.c_str(), fsize);
    if (!Update.begin(fsize)) {
      otaDone = 0;
      Update.printError(Serial);
    }

  const uint8_t key[32] = {/* PUT YOUR KEY HERE */};
  Update.setupCrypt(key, 0, 0, U_AES_DECRYPT_ON);


  } else if (upload.status == UPLOAD_FILE_WRITE) {
    if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
      Update.printError(Serial);
    } else {
      otaDone = 100 * Update.progress() / Update.size();
    }
  } else if (upload.status == UPLOAD_FILE_END) {
    if (Update.end(true)) {
      Serial.printf("Update Success: %u bytes\nRebooting...\n", upload.totalSize);
    } else {
      Serial.printf("%s\n", Update.errorString());
      otaDone = 0;
    }
  }
}

void webServerInit() {
  server.on(
    "/update", HTTP_POST,
    []() {
      handleUpdateEnd();
    },
    []() {
      handleUpdate();
    }
  );
  server.on("/favicon.ico", HTTP_GET, []() {
    server.sendHeader("Content-Encoding", "gzip");
    server.send_P(200, "image/x-icon", favicon_ico_gz, favicon_ico_gz_len);
  });
  server.onNotFound([]() {
    server.send(200, "text/html", indexHtml);
  });
  server.begin();
  Serial.printf("Web Server ready at http://esp32.local or http://%s\n", WiFi.localIP().toString().c_str());
}

void everySecond() {
  if (otaDone > 1) {
    Serial.printf("ota: %d%%\n", otaDone);
  }
}

void setup() {
  Serial.begin(115200);
  // apMode();
  // Either or
  WiFi.begin("SSID", "PASS");
  while(WiFi.status() != WL_CONNECTED)
  {
    Serial.println("Waiting for connection");
    delay(1000);
  }

  webServerInit();
  tkSecond.attach(1, everySecond);
}

void loop() {
  delay(150);
  server.handleClient();
}

Debug Message

Wrong Magic Byte
Wrong Magic Byte
Wrong Magic Byte
...

Other Steps to Reproduce

Having an encrypted binary along with its key is of course necessary.

platformio.ini:

[env:esp32-s3-devkitc-1]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip
framework = arduino
board = esp32-s3-devkitc-1
monitor_speed = 115200

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions