Xpatch: Secure OTA Firmware Delivery
Split firmware images across independent delivery channels using XorIDA threshold sharing. No single intercepted update can reveal proprietary algorithms, enable counterfeiting, or allow reverse engineering. HMAC-SHA256 verification on every chunk ensures tampered shares are rejected before installation. Information-theoretic security for mission-critical IoT deployments.
Executive Summary
Xpatch protects firmware over-the-air (OTA) updates from interception, reverse engineering, and unauthorized modification by splitting firmware images into XorIDA threshold shares distributed across independent delivery channels.
A single intercepted firmware update is a complete blueprint for counterfeiting, reverse engineering, or malicious modification. Traditional OTA delivery sends firmware as a single encrypted file over HTTPS. If that channel is compromised, the entire firmware is exposed. Code signing verifies authenticity but does not prevent reverse engineering once the firmware is delivered.
Xpatch splits firmware into K-of-N shares using XorIDA (threshold sharing over GF(2)). Default configuration is 2-of-3: any 2 shares reconstruct the firmware, but 1 share reveals zero information about the original. Each share is HMAC-verified independently. Firmware is delivered via multiple independent channels (cellular, Wi-Fi, LoRaWAN, satellite). An attacker who compromises any single channel learns nothing about the firmware.
Two functions cover the entire workflow: splitFirmware() chunks the firmware, applies XorIDA splitting, and generates HMAC-protected shares. reconstructFirmware() verifies HMACs, reconstructs from threshold shares, and returns the original firmware bytes ready for installation.
Zero npm runtime dependencies. Works anywhere Web Crypto API is available. Runs on constrained IoT gateways, edge devices, and industrial PLCs. Ships dual ESM + CJS in a single package.
Developer Experience
Xpatch provides structured error codes with actionable hints and field attribution to simplify debugging firmware delivery failures across multiple channels.
Error Structure
Every error includes a machine-readable code, human-readable message, and optional actionable hint describing exactly how to fix the issue.
interface OTAError { code: string; // e.g., 'HMAC_FAILED' message: string; // Human-readable description hint?: string; // Actionable suggestion field?: string; // Field that caused the error }
Error Categories
| Category | Example Codes | When |
|---|---|---|
| Configuration | INVALID_CONFIG | Invalid threshold, channel count, or missing version |
| Splitting | SPLIT_FAILED | Empty firmware or XorIDA split failure |
| Integrity | HMAC_FAILED | HMAC verification failed on received share |
| Reconstruction | RECONSTRUCT_FAILED, INSUFFICIENT_SHARES | XorIDA reconstruction or unpadding failure, fewer shares than threshold |
| Version | VERSION_MISMATCH | Share version does not match manifest version |
const result = await splitFirmware(firmwareBytes, config); if (!result.ok) { const err = result.error; console.error(`Error: ${err.code}`); if (err.code === 'INVALID_CONFIG') { // Field attribution tells you which parameter failed console.log(`Fix: ${err.hint}`); console.log(`Field: ${err.field}`); } if (err.code === 'HMAC_FAILED') { // Indicates tampered or corrupted share during transit throw new Error('Firmware integrity check failed'); } }
hint field with specific guidance. For example, INVALID_CONFIG with field: 'threshold' returns: "threshold must be ≥ 2 and ≤ channels". No guessing, no documentation diving.
The Problem
Firmware over-the-air (OTA) updates are high-value targets. A single intercepted update can reveal proprietary algorithms, enable counterfeiting, or allow malicious modification before installation.
Current OTA delivery relies on trust in a single channel. Whether firmware travels over cellular, Wi-Fi, or satellite, the update is delivered as a single encrypted file. If that channel is compromised at any point — cellular carrier, ISP, cloud CDN, or on-device storage before installation — the entire firmware is exposed.
Code signing verifies authenticity but not confidentiality. Digital signatures prove the firmware came from the manufacturer and was not modified in transit. They do not prevent reverse engineering once the firmware is delivered. An attacker with a signed firmware image can disassemble it, extract algorithms, identify vulnerabilities, or create counterfeit devices.
Encryption-at-rest does not prevent exfiltration. Firmware stored encrypted on-device still requires a decryption key on the same device. If an attacker gains physical or remote access to the device, they can extract both the encrypted firmware and the key, then decrypt offline.
Single-channel delivery is a single point of failure for confidentiality. Industrial espionage, nation-state interception, and supply chain compromise all target OTA delivery as the weakest link. One intercepted update exposes everything.
Attack Scenarios
Cellular carriers are required to comply with lawful interception requests. A cellular OTA update can be intercepted in transit via IMSI catcher or carrier-level surveillance without device compromise.
Contract manufacturers handling OTA server infrastructure can exfiltrate firmware updates intended for production devices, enabling counterfeit production or IP theft.
OTA firmware stored on cloud CDNs for global distribution becomes a single high-value target. A CDN breach exposes every firmware version for every device model in production.
Firmware stored encrypted on-device before installation can be extracted alongside the decryption key via physical debug interfaces (JTAG, SWD) or remote exploits.
| Property | Single-Channel OTA | Encrypted OTA | Signed OTA | Xpatch |
|---|---|---|---|---|
| Prevents interception | No | In transit only | No | Multi-channel split |
| Prevents reverse engineering | No | No | No | Info-theoretic |
| Integrity verification | No | Optional | Signature | HMAC per share |
| Single point of failure | Yes | Yes | Yes | No (K-of-N) |
| Fault tolerance | No | No | No | N-K channels can fail |
| On-device key storage | N/A | Required | Public key only | No keys |
Real-World Use Cases
Six industries where firmware intellectual property is a high-value target and OTA delivery is mission-critical.
ECU firmware delivered over cellular contains proprietary engine control algorithms worth billions. Splitting firmware across cellular + Wi-Fi + satellite prevents single-channel interception during fleet rollout.
2-of-3 split — cellular + Wi-Fi + satcomIndustrial control firmware contains process optimization algorithms and safety logic. Multi-channel OTA protects IP from competitors and nation-state adversaries targeting critical infrastructure.
3-of-4 split — air-gapped + on-site + VPN + cellularAvionics firmware for UAVs and satellites delivered via multiple independent ground stations. No single station can reconstruct mission-critical flight control logic or sensor calibration algorithms.
2-of-4 split — geographic diversity across ground stationsPacemaker and insulin pump firmware contains proprietary therapeutic algorithms. OTA updates via Bluetooth + cellular clinic gateway prevent single-point exfiltration during wireless update procedures.
2-of-2 split — BLE + cellular gatewaySatellite firmware updates delivered via multiple ground stations across different continents. Prevents single ground station compromise from exposing proprietary orbital maneuvering or signal processing algorithms.
3-of-5 split — multi-continent ground stationsGrid-scale battery BMS firmware contains proprietary charge/discharge algorithms worth millions in competitive advantage. Multi-channel OTA prevents IP theft via single cellular or LoRaWAN interception.
2-of-3 split — LoRaWAN + cellular + local EthernetArchitecture
Xpatch splits firmware into fixed-size chunks, applies XorIDA threshold sharing to each chunk independently, generates HMAC integrity tags, and packages shares for multi-channel delivery.
Chunking Strategy
Large firmware images are split into 512KB chunks by default (configurable via chunkSize in OTAConfig). Each chunk is processed independently. Chunking provides three benefits:
- Memory efficiency: Devices with limited RAM can process one chunk at a time without loading the entire firmware.
- Parallelization: Multiple chunks can be transmitted simultaneously across different channels.
- Granular integrity: HMAC verification happens per chunk. A single corrupted chunk is rejected without discarding the entire firmware.
const chunkSize = config.chunkSize || 512 * 1024; // 512KB default const totalChunks = Math.ceil(firmware.length / chunkSize); for (let i = 0; i < totalChunks; i++) { const start = i * chunkSize; const end = Math.min(start + chunkSize, firmware.length); const chunk = firmware.slice(start, end); // XorIDA split this chunk into K-of-N shares const splitResult = await createShares(chunk, config.threshold, config.channels); // ... HMAC each share, package for delivery }
Share Format
Each share is a self-contained object carrying all metadata needed for reconstruction:
| Field | Type | Description |
|---|---|---|
| index | number | 1-based share index (1 to N) |
| total | number | Total number of shares (N) |
| threshold | number | Minimum shares required (K) |
| version | string | Firmware version (e.g., "1.4.0") |
| deviceType | string | Device model identifier |
| chunkIndex | number | 0-based chunk index |
| totalChunks | number | Total number of chunks in firmware |
| data | string | Base64-encoded XorIDA share bytes |
| hmac | string | HMAC-SHA256 of share data (hex) |
| originalSize | number | Original chunk size before padding |
version and deviceType. Reconstruction validates version consistency across all shares. Mixing shares from different firmware versions is rejected with VERSION_MISMATCH error.
Reconstruction
On-device reconstruction follows a 4-step pipeline:
version and deviceTypeIf any HMAC verification fails, reconstruction aborts immediately. No partial or corrupted firmware is returned. The device must re-fetch the tampered share.
Integration
Two integration points: splitting firmware on the OTA server and reconstructing firmware on the device.
Server-Side: Firmware Splitting
import { splitFirmware } from '@private.me/otadelivery'; import type { OTAConfig } from '@private.me/otadelivery'; // Read firmware binary from build output const firmwareBytes = await fs.readFile('./build/firmware-v1.4.0.bin'); const config: OTAConfig = { channels: 3, // 3 delivery channels threshold: 2, // Any 2 shares reconstruct version: '1.4.0', deviceType: 'sensor-v2', chunkSize: 512 * 1024 // 512KB chunks }; const result = await splitFirmware(firmwareBytes, config); if (!result.ok) { console.error(`Split failed: ${result.error.message}`); throw new Error(result.error.hint || result.error.message); } const { manifest, shares } = result.value; // shares[chunkIndex][channelIndex] // Distribute shares to delivery channels: // shares[*][0] → Cellular // shares[*][1] → Wi-Fi // shares[*][2] → Satellite await uploadToChannels(shares, manifest);
Device-Side: Firmware Reconstruction
import { reconstructFirmware } from '@private.me/otadelivery'; // Download manifest + shares from OTA channels const manifest = await fetchManifest(); const shares = await fetchShares(manifest); // Reconstruct (HMAC verification + XorIDA reconstruction) const result = await reconstructFirmware(manifest, shares); if (!result.ok) { if (result.error.code === 'HMAC_FAILED') { // Share was tampered or corrupted in transit console.error('Integrity check failed - re-downloading'); await retryDownload(); } else if (result.error.code === 'INSUFFICIENT_SHARES') { // Not enough shares received (network failure) console.error('Need more shares to reconstruct'); } else { throw new Error(result.error.message); } } const firmwareBytes = result.value; // Uint8Array, ready to flash await installFirmware(firmwareBytes);
Channel Delivery Options
| Channel Type | Use Case | Typical Bandwidth |
|---|---|---|
| Cellular (LTE/5G) | Automotive, consumer IoT | 1-100 Mbps |
| Wi-Fi | Industrial gateways, smart home | 10-1000 Mbps |
| LoRaWAN | Long-range sensors, smart meters | 0.3-50 kbps |
| Satellite (Iridium/Starlink) | Remote industrial, maritime, aviation | 1-150 Mbps |
| Ethernet (on-site) | Factory PLCs, critical infrastructure | 100-10000 Mbps |
| Bluetooth LE | Wearables, medical devices | 125 kbps - 2 Mbps |
Security
Xpatch provides information-theoretic confidentiality and cryptographic integrity for OTA firmware delivery.
Information-Theoretic Security
XorIDA threshold sharing over GF(2) provides unconditional security. An attacker who intercepts fewer than threshold shares learns zero information about the firmware — not computationally hard to break, but mathematically impossible.
In a 2-of-3 configuration, intercepting any single channel (cellular, Wi-Fi, or satellite) reveals zero bits of the firmware. There is no ciphertext to attack, no key to brute-force, and no quantum computer that can recover the firmware from 1 share.
HMAC-SHA256 Integrity
Every share is protected by HMAC-SHA256 before transmission. On-device reconstruction verifies the HMAC before processing. If any share is tampered or corrupted in transit, HMAC verification fails and reconstruction aborts.
HMAC keys are derived from firmware metadata (version + deviceType + chunkIndex) to prevent share substitution attacks. An attacker cannot replace a valid share with a different share from another firmware version or chunk.
Security Properties
| Threat | Mitigation |
|---|---|
| Single-channel interception | XorIDA ensures 1 share reveals zero information |
| Share tampering in transit | HMAC-SHA256 verification before reconstruction |
| Share substitution attack | HMAC keys bound to version + deviceType + chunkIndex |
| Version mismatch (mixing shares) | Reconstruction validates version consistency |
| Reverse engineering after delivery | Multi-channel split prevents single-point capture |
| Quantum computer attack | Information-theoretic security, no computational assumption |
What Xpatch Does NOT Protect
- Firmware signing: Xpatch provides confidentiality and integrity, not authenticity. You should sign firmware images before splitting.
- Rollback attacks: Xpatch does not enforce version ordering. Devices must implement anti-rollback logic to prevent downgrade attacks.
- On-device extraction after installation: Once firmware is installed, physical or remote device compromise can extract it. Xpatch protects OTA delivery, not on-device storage.
- Transport-layer encryption: Xpatch does not encrypt shares for transport. Each delivery channel must use TLS or equivalent.
Benchmarks
XorIDA splitting and reconstruction performance measured on Node.js 20.12 (Apple M1 Pro, 16GB RAM). All operations are CPU-bound; network latency dominates real-world OTA delivery times.
Splitting Performance (Server-Side)
| Firmware Size | Chunk Size | Config | Split Time | Throughput |
|---|---|---|---|---|
| 1 MB | 512 KB | 2-of-3 | ~8 ms | 125 MB/s |
| 10 MB | 512 KB | 2-of-3 | ~72 ms | 139 MB/s |
| 50 MB | 512 KB | 2-of-3 | ~340 ms | 147 MB/s |
| 100 MB | 512 KB | 2-of-3 | ~680 ms | 147 MB/s |
| 10 MB | 512 KB | 3-of-5 | ~110 ms | 91 MB/s |
Reconstruction Performance (Device-Side)
| Firmware Size | Config | Reconstruct Time | Throughput |
|---|---|---|---|
| 1 MB | 2-of-3 | ~6 ms | 167 MB/s |
| 10 MB | 2-of-3 | ~54 ms | 185 MB/s |
| 50 MB | 2-of-3 | ~260 ms | 192 MB/s |
| 100 MB | 2-of-3 | ~520 ms | 192 MB/s |
Memory Consumption
Peak memory usage during splitting/reconstruction is proportional to chunkSize × channels. For 2-of-3 configuration with 512KB chunks:
- Server-side splitting: ~3.5 MB peak (512KB chunk × 3 channels + HMAC buffers + padding)
- Device-side reconstruction: ~2.5 MB peak (512KB chunk × 2 shares + verification buffers)
Constrained IoT devices can reduce chunkSize to 64KB or 128KB to fit within tighter memory budgets. Smaller chunks increase overhead (more HMAC operations, more share metadata) but reduce peak memory usage.
Honest Limitations
What Xpatch does not do, what it cannot do, and where it should not be used.
Not a Complete OTA Stack
Xpatch splits firmware and provides integrity verification. It does not handle:
- Code signing: You must sign firmware before splitting to prove authenticity.
- Transport-layer encryption: Each delivery channel must use TLS, DTLS, or equivalent.
- Rollback protection: Devices must implement anti-rollback logic to prevent version downgrade attacks.
- Channel orchestration: You are responsible for routing shares to independent channels and assembling them on-device.
Channel Independence Is Critical
XorIDA security guarantees rely on truly independent delivery channels. Routing cellular and Wi-Fi shares through the same ISP, cloud provider, or VPN does not provide meaningful channel diversity. An attacker who controls the common infrastructure can intercept multiple shares.
Meaningful independence examples:
- Cellular (Verizon) + Satellite (Iridium)
- LoRaWAN + Wi-Fi + Ethernet (on-site)
- Multiple ground stations in different countries (satellite OTA)
Not a Substitute for Secure Boot
Xpatch protects firmware during delivery. Once firmware is installed on-device, physical or remote compromise can extract it. Combine Xpatch with secure boot, measured boot, and hardware root-of-trust for complete on-device protection.
Chunk Size Trade-Offs
Smaller chunks reduce memory usage but increase overhead (more HMAC operations, more share metadata). Larger chunks reduce overhead but require more RAM. The default 512KB balances throughput and memory for typical IoT gateways. Adjust based on your device constraints.
No Firmware Delta Updates
Xpatch operates on complete firmware images. It does not support delta/differential updates. For large firmware images where only a small portion changed, you must split and deliver the entire new firmware. Delta update support is a future consideration.
For Production Deployments
Error handling patterns, multi-channel routing strategies, and complete API surface documentation.
Error Handling Patterns
Xpatch uses a Result<T, E> pattern with discriminated error codes. Handle errors based on category for robust OTA deployment.
const result = await reconstructFirmware(manifest, shares); if (!result.ok) { const err = result.error; switch (err.code) { case 'HMAC_FAILED': // Share tampered or corrupted in transit // Action: Re-download from the same channel await retryChannelDownload(err.field); // err.field = channel index break; case 'INSUFFICIENT_SHARES': // Network failure prevented receiving threshold shares // Action: Wait for additional channels to complete await waitForMoreShares(manifest); break; case 'VERSION_MISMATCH': // Mixing shares from different firmware versions // Action: Clear cache and re-download all shares await clearShareCache(); await downloadAllShares(manifest); break; case 'RECONSTRUCT_FAILED': // XorIDA reconstruction or unpadding failure // This should never happen with valid shares throw new Error('Critical: Reconstruction failure'); default: console.error(`Unexpected error: ${err.message}`); throw err; } }
Error Codes Reference
| Code | Category | Description |
|---|---|---|
| INVALID_CONFIG | Configuration | Invalid threshold, channel count, or missing required fields (version, deviceType) |
| SPLIT_FAILED | Splitting | Empty firmware or XorIDA split operation failed |
| HMAC_FAILED | Integrity | HMAC-SHA256 verification failed on a received share (tampered or corrupted) |
| RECONSTRUCT_FAILED | Reconstruction | XorIDA reconstruction or PKCS#7 unpadding failed |
| INSUFFICIENT_SHARES | Reconstruction | Fewer than threshold shares provided for a chunk |
| VERSION_MISMATCH | Version | Share version does not match manifest version or deviceType |
Multi-Channel Routing Strategies
Production OTA deployments must handle channel failures, bandwidth variability, and latency differences. Three common routing strategies:
Strategy 1: Parallel Delivery (Fastest)
Send all shares simultaneously across all channels. Device reconstructs as soon as threshold shares arrive. Fastest time-to-install but highest bandwidth consumption.
// Server-side: Send all shares immediately await Promise.all([ sendToCellular(shares[0]), sendToWiFi(shares[1]), sendToSatellite(shares[2]) ]); // Device-side: Reconstruct as soon as threshold met const received = await waitForThresholdShares(manifest.threshold); const firmware = await reconstructFirmware(manifest, received);
Strategy 2: Sequential with Timeout (Bandwidth-Aware)
Send shares sequentially, prioritizing lowest-cost channels. Fall back to additional channels only if primary channel fails or times out. Minimizes bandwidth costs but slower.
// Try Wi-Fi first (free), fall back to cellular if timeout let shares = []; try { shares[0] = await downloadFromWiFi(manifest, { timeout: 30000 }); shares[1] = await downloadFromLoRaWAN(manifest, { timeout: 60000 }); } catch (err) { // Fallback to cellular if Wi-Fi/LoRaWAN fail shares[2] = await downloadFromCellular(manifest); }
Strategy 3: Adaptive Channel Selection
Monitor channel performance (latency, bandwidth, error rate) and dynamically select the best channels for each update. Balances speed, cost, and reliability.
Full API Surface
Complete API documentation for all exported functions and types.
Functions
Split firmware into XorIDA shares for multi-channel OTA delivery. Returns manifest + shares array indexed by [chunkIndex][channelIndex]. Each share includes HMAC-SHA256 integrity tag.
Reconstruct firmware from threshold shares. Verifies HMAC on each share, validates version consistency, reconstructs via XorIDA, and returns original firmware bytes.
Types
Configuration for firmware splitting: channels (total shares), threshold (min shares to reconstruct), version (firmware version string), deviceType (device model identifier), optional chunkSize (default 512KB).
Metadata for split firmware: id (UUID), version, deviceType, firmwareSize, totalChunks, firmwareHash (SHA-256), config (OTAConfig), createdAt (ISO timestamp).
Single share for one chunk: index (1-based share index), total, threshold, version, deviceType, chunkIndex, totalChunks, data (base64-encoded XorIDA share bytes), hmac (HMAC-SHA256 hex string), originalSize.
Result of firmware splitting: manifest (FirmwareManifest) + shares (FirmwareShare[][] indexed by [chunkIndex][channelIndex]).
Discriminated error union: code (machine-readable error code), message (human-readable description), optional hint (actionable suggestion), optional field (field that caused the error).
Deployment Options
SaaS Recommended
Fully managed infrastructure. Call our REST API, we handle scaling, updates, and operations.
- Zero infrastructure setup
- Automatic updates
- 99.9% uptime SLA
- Enterprise SLA available
SDK Integration
Embed directly in your application. Runs in your codebase with full programmatic control.
npm install @private.me/otadelivery- TypeScript/JavaScript SDK
- Full source access
- Enterprise support available
On-Premise Upon Request
Enterprise CLI for compliance, air-gap, or data residency requirements.
- Complete data sovereignty
- Air-gap capable deployment
- Custom SLA + dedicated support
- Professional services included
Enterprise On-Premise Deployment
While otaDelivery is primarily delivered as SaaS or SDK, we build dedicated on-premise infrastructure for customers with:
- Regulatory mandates — HIPAA, SOX, FedRAMP, CMMC requiring self-hosted processing
- Air-gapped environments — SCIF, classified networks, offline operations
- Data residency requirements — EU GDPR, China data laws, government mandates
- Custom integration needs — Embed in proprietary platforms, specialized workflows
Includes: Enterprise CLI, Docker/Kubernetes orchestration, RBAC, audit logging, and dedicated support.