Skip to content

Add ESP-IDF Secure Boot v2 support#130

Merged
kwsantiago merged 4 commits intomainfrom
signed-bootloader
Jan 22, 2026
Merged

Add ESP-IDF Secure Boot v2 support#130
kwsantiago merged 4 commits intomainfrom
signed-bootloader

Conversation

@wksantiago
Copy link
Contributor

@wksantiago wksantiago commented Jan 22, 2026

  • Add signing key generation and firmware signing script
  • Add secure boot partition table with adjusted offsets
  • Add sdkconfig defaults for Secure Boot v2 configuration
  • Update .gitignore to protect signing keys
  • Add comprehensive secure boot documentation

Summary by CodeRabbit

  • New Features

    • Secure Boot v2 support for firmware verification with RSA-3072/PSS signatures
    • Command-line firmware signing and verification tooling (app, bootloader, batch operations)
  • Documentation

    • Comprehensive Secure Boot guide: key generation, management, anti-rollback, flash encryption, recovery, CI, and troubleshooting
    • Updated security guidance including vulnerability reporting and revised limitations
  • Chores

    • Added VCS ignores for signing keys and PEM files
    • Added Secure Boot configuration template

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 22, 2026

Walkthrough

Adds ESP32 Secure Boot v2: gitignore entries for keys, new secure-boot SDK defaults, signing/verification script, SECURITY.md updates, and detailed secure-boot docs.

Changes

Cohort / File(s) Summary
Version Control
​.gitignore
Added keys/ and *.pem ignore patterns to prevent committing signing keys.
Security Docs
SECURITY.md, docs/SECURE_BOOT.md
Inserted Secure Boot (v2) guidance and reporting instructions into SECURITY.md (content appears duplicated); added docs/SECURE_BOOT.md with key management, signing workflow, anti-rollback, flash encryption notes, CI guidance, and recovery/troubleshooting.
Signing Tooling
scripts/sign_firmware.sh
New script for key generation, signing (sign-app, sign-bootloader, sign-all), and verify using espsecure.py; includes environment/path handling, prechecks, and usage output.
SDK Defaults
sdkconfig.defaults.secureboot
New SDK config enabling Secure Boot v2, RSA-3072 scheme, CONFIG_SECURE_BOOT_SIGNING_KEY pointing to keys/secure_boot_signing_key.pem, custom partition table, anti-rollback/versioning, and commented flash-encryption options.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Dev as "Developer (CLI)"
  participant Script as "scripts/sign_firmware.sh"
  participant ESP as "espsecure.py"
  participant FS as "Filesystem / Build Artifacts"

  Dev->>Script: run command (generate-key / sign-app / sign-bootloader / sign-all / verify)
  Script->>FS: check `keys/`, `build/keep.bin`, `build/bootloader/bootloader.bin`
  alt generate-key
    Script->>ESP: espsecure.py generate_signing_key (RSA-3072)
    ESP-->>FS: write `keys/secure_boot_signing_key.pem` (chmod set)
    Script-->>Dev: print success and path
  else sign-app / sign-bootloader / sign-all
    Script->>ESP: espsecure.py sign binary -> `*-signed.bin`
    ESP-->>FS: write signed artifact(s)
    Script-->>Dev: print signed artifact paths
  else verify
    Script->>ESP: espsecure.py verify `*-signed.bin`
    ESP-->>Script: verification result
    Script-->>Dev: display verification status/warnings
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Add SECURITY.md #115: Earlier update to SECURITY.md and related security documentation that this PR extends with Secure Boot implementation and docs.

Poem

🐰 I hid the keys beneath the ground,

I signed the bits to keep them sound,
eFuses hum and RSA sings,
Boot is guarded, rollback stings,
A carrot cheers the firmware bound 🥕🔐

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Add ESP-IDF Secure Boot v2 support' directly and accurately reflects the main change across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@wksantiago wksantiago requested a review from kwsantiago January 22, 2026 15:46
@wksantiago wksantiago self-assigned this Jan 22, 2026
@wksantiago wksantiago linked an issue Jan 22, 2026 that may be closed by this pull request
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@sdkconfig.defaults.secureboot`:
- Around line 26-27: The config currently sets
CONFIG_SECURE_DISABLE_ROM_DL_MODE=y which permanently disables ROM Download Mode
via eFuse; confirm this is intentional for production and, if you need
recoverability for development, change the setting to one of the alternatives
(use CONFIG_SECURE_INSECURE_ALLOW_DL_MODE=y for full esptool/ROM download access
during development, or CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE=y to enable
secure/controlled download mode if supported) and remove or set
CONFIG_SECURE_DISABLE_ROM_DL_MODE to n accordingly; update the
sdkconfig.defaults.secureboot entries so only the chosen download-mode option is
enabled and add a short inline comment documenting the risk/reason for the
chosen option.
🧹 Nitpick comments (3)
scripts/sign_firmware.sh (2)

97-120: Add check_signing_key call to verify_signatures for consistent error handling.

The verification function uses $SIGNING_KEY (line 107, 114) but doesn't call check_signing_key() first. If the key is missing, espsecure.py will fail with a less informative error.

Proposed fix
 verify_signatures() {
     check_espsecure
+    check_signing_key

     local app_bin="${BUILD_DIR}/keep-signed.bin"

105-117: Consider non-zero exit when no signed binaries exist.

Currently, if both signed binaries are missing, the function prints warnings but exits successfully. This could mask issues in CI pipelines.

Proposed fix
     local app_bin="${BUILD_DIR}/keep-signed.bin"
     local bootloader_bin="${BUILD_DIR}/bootloader/bootloader-signed.bin"
+    local found=0

     echo "Verifying signatures..."

     if [ -f "$app_bin" ]; then
         echo "Verifying application..."
         espsecure.py verify_signature --version 2 --keyfile "$SIGNING_KEY" "$app_bin"
+        found=1
     else
         echo "Warning: Signed application not found"
     fi

     if [ -f "$bootloader_bin" ]; then
         echo "Verifying bootloader..."
         espsecure.py verify_signature --version 2 --keyfile "$SIGNING_KEY" "$bootloader_bin"
+        found=1
     else
         echo "Warning: Signed bootloader not found"
     fi

+    if [ "$found" -eq 0 ]; then
+        echo "Error: No signed binaries found to verify"
+        exit 1
+    fi
+
     echo "Verification complete."
 }
docs/SECURE_BOOT.md (1)

76-78: Add language specifiers to fenced code blocks.

Per static analysis hints, these configuration snippets should specify a language for proper rendering.

Proposed fix
 To increment version for a security-critical update:

-```
+```ini
 CONFIG_BOOTLOADER_APP_SECURE_VERSION=2

```diff
 For additional protection of firmware at rest, enable flash encryption in `sdkconfig.defaults.secureboot`:

-```
+```ini
 CONFIG_SECURE_FLASH_ENC_ENABLED=y
 CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=y
</details>


Also applies to: 86-89

</blockquote></details>

</blockquote></details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

@kwsantiago kwsantiago merged commit 3ea9c2d into main Jan 22, 2026
9 checks passed
@kwsantiago kwsantiago deleted the signed-bootloader branch January 22, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add signed bootloader verification chain

2 participants