9.8 KiB
ClearGrow Probe - Production Build Guide
Security-hardened firmware build for deployment.
Security Features (PROBE-TN-001 Mitigation)
Overview
The nRF52840 does not support NVS encryption (requires TF-M/TrustZone-M, only available on Cortex-M33 devices like nRF5340). Thread network credentials are stored in plaintext in NVS flash.
Defense-in-depth mitigations:
| Layer | Technology | Protection |
|---|---|---|
| 1. Hardware Access | Access Port Protection (APPROTECT) | Prevents JTAG/SWD flash readout |
| 2. Code Integrity | MCUboot RSA-2048 Signature | Prevents unsigned firmware from booting |
| 3. Network Security | Thread MLE/MAC-layer encryption | Prevents over-the-air credential sniffing |
| 4. Physical Security | Device possession | Physical tamper-evident enclosure |
Residual Risk: Attacker with chip-off capability can read plaintext credentials from flash. Mitigation: Rotate Thread network credentials if device is lost/stolen.
Quick Start
# 1. Generate production signing key (ONCE, keep secret)
cd /root/cleargrow/probe
west bootloader keygen --type rsa-2048
# Creates: bootloader/mcuboot/root-rsa-2048.pem
# IMPORTANT: Backup this key securely, do NOT commit to git
# 2. Build production firmware
west build -b nrf52840dk_nrf52840 -- -DOVERLAY_CONFIG=prj.conf.production
# 3. Flash to device
west flash
# 4. OPTIONAL: Lock access port (irreversible without chip erase)
nrfjprog --rbp ALL # Readback protection level ALL
Build Configuration
Development Build (default)
west build -b nrf52840dk_nrf52840
Features:
- Full logging (INFO level)
- Debugging enabled (JTAG/SWD)
- No access port protection
- Assertions enabled
- Larger binary (~40KB more flash)
Use for: Development, testing, debugging
Production Build
west build -b nrf52840dk_nrf52840 -- -DOVERLAY_CONFIG=prj.conf.production
Features (see prj.conf.production):
- Minimal logging (WARNING level only)
- Access port protection enabled (
CONFIG_NRF_APPROTECT_LOCK=y) - Assertions disabled
- Smaller binary (~40KB flash savings)
- Image signature verification required
Use for: Production deployment, field devices
MCUboot Secure Boot
Configuration
MCUboot is automatically configured via child_image/mcuboot.conf:
# Signature verification (RSA-2048)
CONFIG_BOOT_SIGNATURE_TYPE_RSA=y
CONFIG_BOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/root-rsa-2048.pem"
# Validate primary slot on every boot
CONFIG_MCUBOOT_VALIDATE_PRIMARY_SLOT=y
# Prevent downgrade attacks
CONFIG_BOOT_UPGRADE_ONLY=y
# Disable serial recovery mode
CONFIG_MCUBOOT_SERIAL=n
Key Management
Generate signing key (production, ONCE):
west bootloader keygen --type rsa-2048
# Output: bootloader/mcuboot/root-rsa-2048.pem
CRITICAL: Store this key securely:
- Do NOT commit to git (add to
.gitignore) - Backup to secure offline storage
- Use hardware security module (HSM) for multi-device production
- Losing this key means you cannot sign new firmware for deployed devices
Alternative: Use ECDSA-P256 (smaller signatures, faster verification):
west bootloader keygen --type ecdsa-p256
# Edit child_image/mcuboot.conf to use CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256
Image Signing
Automatic (during build):
west build -b nrf52840dk_nrf52840
# Output: build/zephyr/zephyr.signed.bin (for OTA)
# build/zephyr/zephyr.signed.hex (for flash programmer)
# build/zephyr/merged.hex (MCUboot + signed app)
Manual (for external build systems):
west sign -t imgtool -- --key bootloader/mcuboot/root-rsa-2048.pem
Verification
Check if image is signed:
# Install imgtool
pip3 install imgtool
# Verify signature
imgtool verify --key bootloader/mcuboot/root-rsa-2048.pem build/zephyr/zephyr.signed.bin
# Expected: "Image verified successfully"
Access Port Protection
What is APPROTECT?
Access Port Protection (APPROTECT) is a hardware feature on nRF52840 that disables the debug interface (JTAG/SWD), preventing:
- Flash memory readout
- RAM inspection
- Real-time debugging
- Firmware dumping
When enabled: Only way to re-enable debugging is full chip erase (nrfjprog --recover), which erases all flash including Thread credentials.
Configuration Levels
| Config | Development | Production |
|---|---|---|
CONFIG_NRF_APPROTECT_LOCK=n |
Debugging enabled | Debugging enabled |
CONFIG_NRF_APPROTECT_LOCK=y |
- | Debugging locked on boot |
Development build: APPROTECT disabled (default prj.conf)
Production build: APPROTECT enabled (prj.conf.production)
Enable APPROTECT
Software method (recommended, included in production build):
# In prj.conf.production
CONFIG_NRF_APPROTECT_LOCK=y
Firmware sets APPROTECT.FORCEPROTECT register on boot.
Hardware method (permanent until chip erase):
# Write to UICR (User Information Configuration Registers)
nrfjprog --rbp ALL
This writes 0x00 to UICR.APPROTECT, locking debug access.
Unlock APPROTECT (for development)
WARNING: This performs a full chip erase, erasing all firmware and credentials.
nrfjprog --recover
# Erases entire flash, resets UICR, re-enables debugging
After recovery, you must re-flash firmware.
Verification
Check APPROTECT status:
nrfjprog --readcode 0x10001208 --n 1
# 0xFFFFFFFF = disabled
# 0x00000000 = enabled
Attempt to read flash (should fail if protected):
nrfjprog --readcode 0x0000C000 --n 256
# Expected (if protected): "ERROR: Access port is locked"
Flash Layout
nRF52840: 1MB total
| Region | Start | Size | Purpose |
|---|---|---|---|
| MCUboot | 0x00000000 | 48 KB | Bootloader (signature verification) |
| Slot 0 | 0x0000C000 | 476 KB | Active firmware (signed) |
| Slot 1 | 0x00083000 | 476 KB | OTA download area (signed) |
| NVS | 0x000FA000 | 24 KB | Settings storage (Thread credentials) |
IMPORTANT: NVS region contains plaintext credentials. APPROTECT prevents reading this region via debugger.
OTA Updates
Build OTA Image
west build -b nrf52840dk_nrf52840 -- -DOVERLAY_CONFIG=prj.conf.production
# Output: build/zephyr/zephyr.signed.bin (ready for OTA distribution)
OTA Process
- Controller uploads
zephyr.signed.binto Slot 1 (0x00083000) - MCUboot validates signature on next boot
- If valid: swap Slot 0 ↔ Slot 1, boot new firmware
- If invalid: refuse to boot, stay on Slot 0
Security: Only images signed with production key can boot.
Version Management
Edit VERSION file (or use --version flag):
# File: VERSION
1.2.3
MCUboot enforces monotonic versioning (no downgrades) if CONFIG_BOOT_UPGRADE_ONLY=y.
Testing Production Build
Functional Testing
# Flash production build
west build -b nrf52840dk_nrf52840 -- -DOVERLAY_CONFIG=prj.conf.production
west flash
# Monitor logs (should see WARNING-level only)
minicom -D /dev/ttyACM0 -b 115200
# Test Thread pairing
# Test sensor readings
# Test OTA update cycle
Security Testing
Test 1: Signature Verification
# Build unsigned image (should NOT boot)
west build -b nrf52840dk_nrf52840 -- -DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE=""
west flash
# Expected: MCUboot refuses to boot, stays in bootloader
Test 2: Access Port Protection
# Attempt to read flash after APPROTECT enabled
nrfjprog --readcode 0x000FA000 --n 256
# Expected: ERROR: Access port is locked
Test 3: Downgrade Protection
# Build firmware v1.0.0
# OTA to v1.1.0
# Attempt OTA back to v1.0.0
# Expected: MCUboot refuses downgrade
Production Checklist
Before deploying to field:
- Generated production signing key (
root-rsa-2048.pem) - Signing key backed up to secure offline storage
- Signing key NOT in git repository
- Built with
prj.conf.productionoverlay - Verified image signature with
imgtool verify - Tested functional operation (Thread, sensors, OTA)
- Tested APPROTECT activation (verify flash read fails)
- Tested OTA update cycle with signed images
- Documented firmware version in release notes
- Created rollback plan (if needed, recover via
nrfjprog --recover)
Troubleshooting
"west bootloader keygen" not found
Install nRF Connect SDK tools:
pip3 install west
west update
"Image signature verification failed"
Check if correct key file is used:
# Verify key path in child_image/mcuboot.conf
grep SIGNATURE_KEY_FILE child_image/mcuboot.conf
# Verify key exists
ls -la bootloader/mcuboot/root-rsa-2048.pem
Device won't boot after APPROTECT enabled
This is expected if firmware signature is invalid. Recovery:
nrfjprog --recover # Chip erase
west flash # Re-flash firmware
Cannot debug production device
By design. APPROTECT locks debugging. To restore debug access:
nrfjprog --recover # WARNING: Erases all flash including credentials
References
- Nordic APPROTECT Documentation
- MCUboot Secure Boot with Zephyr
- Thread Security Best Practices
- PROBE-TN-001: Network Credentials Not Encrypted (assessment finding)
Future Hardware Upgrade
For full at-rest credential encryption, consider:
| Hardware | Encryption | TrustZone | Cost Impact |
|---|---|---|---|
| nRF52840 | ❌ No | ❌ No | Current |
| nRF5340 | ✅ TF-M + NVS encryption | ✅ Yes | +$2-3 |
| ATECC608 | ✅ Secure element | N/A | +$0.50 (separate chip) |
nRF5340: Drop-in upgrade, supports CONFIG_NVS_ENCRYPTION=y via TF-M.
ATECC608: I2C secure crypto chip, stores keys in tamper-resistant hardware.