MAVLINK CYBERSECURITY
PROTECTING THE DRONE DATA LINK
MAVLINK SECURITY
The signing mechanism uses SHA-256 hash-based message authentication. Each packet includes a timestamp to prevent replay attacks — an intercepted command cannot be resent later because the timestamp will be stale. The autopilot maintains a rolling window of accepted timestamps and rejects any packet more than 60 seconds old. This approach is computationally lightweight enough to run on SpeedyBee F405 at 400 Hz without affecting flight control latency.
The authentication framework extends beyond the aerial domain to ground vehicles and fixed command posts integrated through Lisa 26. Every node in the brigade network — whether a drone, a UGV, or a battalion laptop — uses the same signing infrastructure. Key distribution follows the same USB-at-startup protocol across all platforms, ensuring consistent security posture from platoon to brigade level without per-device configuration differences that could create exploitable inconsistencies in the security boundary.
Signing Mechanism — SHA-256 HMAC
MAVLink 2.0 signing appends a 13-byte signature to every packet: 6 bytes of timestamp (48-bit microsecond counter) and 6 bytes of truncated SHA-256 HMAC computed over the packet header, payload, CRC, link ID, and timestamp using the 32-byte secret key. The autopilot maintains a monotonically increasing timestamp counter — it rejects any packet with a timestamp older than the most recently accepted packet. This prevents replay attacks: an intercepted command cannot be resent later because its timestamp will be stale.
The 32-byte key is generated randomly (openssl rand -hex 32) and loaded onto the drone's flight controller via USB during initial setup. The key is stored in volatile RAM, not in persistent flash memory. On power loss, the key vanishes — the drone cannot be interrogated for its key after physical capture. The operator keeps the key on a USB drive that never leaves their person. Each drone in the fleet can have a unique key, or all drones in a unit can share a key for simplified management (with the tradeoff that compromising one drone's key compromises all).
Attack Scenarios and Mitigations
Scenario 1 — DISARM injection: adversary captures a MAVLink telemetry packet, identifies the drone's system ID, and transmits a DISARM command. Without signing: drone motors cut, aircraft falls from sky. With signing: the unsigned DISARM command is silently discarded. The adversary receives no feedback — they do not know if the command was rejected or if the radio link failed. Scenario 2 — RTL hijack: adversary sends a MAV_CMD_NAV_RETURN_TO_LAUNCH with a falsified home position. Without signing: drone flies to enemy coordinates. With signing: rejected.
Scenario 3 — Parameter modification: adversary sends PARAM_SET commands to change failsafe behavior (disable geofence, set RTL altitude to 5m for easy capture). Without signing: parameters silently changed, drone vulnerable on next failsafe trigger. With signing: every PARAM_SET requires valid HMAC. The adversary cannot modify any parameter without the key. This is why signing must be enabled BEFORE the drone enters a contested electromagnetic environment — enabling it after deployment exposes the pre-signing configuration window to attack.
MAVLink Signing Setup (SITL Configuration)
# MAVLink 2.0 Signing — Anti-Spoofing Protection
# pip install pymavlink
import hashlib, struct, time
def sign_mavlink_packet(packet_bytes, key_bytes, timestamp_us):
"""Sign a MAVLink 2.0 packet with HMAC-SHA256."""
# MAVLink 2.0 signature: 6 bytes timestamp + 6 bytes signature
ts_bytes = struct.pack('
Expected behavior: with signing enabled, an injected fake COMMAND_LONG (disarm motors) from a second radio should be rejected by the flight controller because it lacks a valid HMAC. Without signing, the same attack would successfully disarm motors. FSG-A has verified this logic in SITL simulation; it has not been tested under real-world RF attack conditions.
MANET encryption (Silvus AES-256) provides an additional layer — even if MAVLink signing is misconfigured, the MANET radio encrypts the entire IP stream, preventing eavesdropping and injection at the radio layer.
Related Chapters
Attack Demonstration (SITL)
Reproduce the injection attack in SITL to verify your defenses work:
Run this test BEFORE deploying any drone in a contested environment. If the attacker's command succeeds, MAVLink signing is not configured correctly. Fix before flight.
Signature Overhead Derivation
Starting from the MAVLink 2.0 signing specification, each signed packet carries 13 additional bytes of overhead (6-byte timestamp + 6-byte signature + 1-byte link ID). This overhead bandwidth cost can be derived from the telemetry rate:
overhead_bps = N_packets_per_sec × 13 bytes × 8 bits/byte
Where:
N_packets_per_sec = MAVLink packet rate (typical tactical telemetry: 50 Hz)
Substituting for Fischer 26 typical telemetry stream:
overhead_bps = 50 × 13 × 8 = 5,200 bps = 5.2 kbps
Against the Silvus SL5200 MANET minimum sustainable throughput of 2 Mbps, the 5.2 kbps signing overhead represents 0.26% of link capacity — negligible in practice.
Computational cost derivation. SHA-256 HMAC requires approximately 1,200 clock cycles per 64-byte block on ARM Cortex-M7 (the processor class in SpeedyBee F405 and Pixhawk 6C). Substituting into the CPU-budget equation:
cpu_fraction = (packets_per_sec × cycles_per_hmac) / f_cpu
Where:
packets_per_sec = 50 Hz typical tactical rate
cycles_per_hmac = 1,200 cycles per HMAC computation
f_cpu = 480 MHz STM32H7 or 216 MHz STM32F4
For STM32H7 (Pixhawk 6C):
cpu_fraction = (50 × 1200) / 480e6 = 0.0125%
For STM32F4 (SpeedyBee F405):
cpu_fraction = (50 × 1200) / 216e6 = 0.028%
MAVLINK 2.0 SIGNING OVERHEAD — FISCHER 26 AVIONICS
Key Rotation Implementation
The HMAC collision protection is predicated on keeping the shared key secret. Because Fischer 26 airframes are expected to be captured at 20-30% weekly loss rate (per the FSG-A brigade doctrine), the shared key must rotate on a schedule that limits exposure after any single loss. The implementation below is representative — it is what ew_integration.py uses to rotate MAVLink signing keys across the fleet.
# mavlink_key_rotation.py — Daily key rotation for captured-airframe tolerance
import hashlib, hmac, os, time
class MAVLinkSigningKeys:
def __init__(self, master_secret):
"""master_secret is stored only at GCS, never on drones."""
self.master_secret = master_secret
def key_for_day(self, day_index):
"""Derive per-day signing key using HKDF-like construction."""
return hmac.new(
self.master_secret,
f"FSGA-MAVLINK-{day_index}".encode(),
hashlib.sha256
).digest()
def rotate_fleet(self, drone_ids, day_index):
"""Push new keys to all drones for given day."""
key = self.key_for_day(day_index)
for drone_id in drone_ids:
# Send via pre-existing authenticated channel
# Drone stores key in RAM only; wiped at shutdown
push_key_to_drone(drone_id, key)
return key
# Example: Monday's key, Tuesday's key are independent
# Capturing Monday's drone does not compromise Tuesday's fleet
master = os.urandom(32)
keyring = MAVLinkSigningKeys(master)
monday_key = keyring.key_for_day(20260420)
tuesday_key = keyring.key_for_day(20260421)
assert monday_key != tuesday_key # Independent
Why This Matters Operationally
MAVLink signing matters because the Russian EW playbook from Ukraine 2022-2026 includes sustained effort to inject commands into ExpressLRS and MAVLink streams. Without signing, a Russian EW operator within MANET range can inject "return to launch" or "disarm motors" commands that immediately crash the targeted drone. A brigade losing drones to command injection rather than kinetic attack is losing the cheap category — the very effect that the doctrinal cost-asymmetry argument depends on.
The signing overhead being negligible (0.26% bandwidth, 0.028% CPU) means there is no operational reason to disable it. The only argument against enabling signing on every drone is key management complexity — and the HKDF-based daily-rotation scheme above reduces that complexity to a single master secret kept at the GCS. Once implemented, signing is a free defensive capability that eliminates an entire class of Russian EW attacks. This is why MAVLink signing is flagged as a mandatory Fischer 26 configuration parameter, not an optional hardening measure.
External source: Kryptering – Wikipedia
Sources
Normative sources. MAVLink 2.0 signing specification — mavlink.io/en/. ArduPilot parameter documentation (BRD_SERIAL_SIGNING, SERIAL_PROTOCOL) — ardupilot.org. SHA-256 HMAC — RFC 2104 (HMAC) plus FIPS 180-4 (SHA-256). AES-128 (ELRS) and AES-256 (Silvus) — standard certified ciphers.
Mathematically verified estimates. Computational infeasibility of brute-forcing a 256-bit key — validated under HMAC_COLLISION_YEARS in provable_claims.py. Signature size 6 + 6 + 1 = 13 bytes and 60-second replay threshold — public values from the MAVLink 2.0 specification.
Operational estimates — not validated by FSG-A in the field. The "signing + ELRS encryption blocks 95% of known MAVLink attacks" claim is an estimate based on taxonomy of published MAVLink attack research (Shostack 2023, other public CVEs). It is not statistics from FSG-A real-world deployments. The "computationally lightweight at 400 Hz on SpeedyBee F405" statement is from public SHA-256 benchmarks, not measured by FSG-A on a flight controller. The "5 minutes to configure" figure is a procedure design goal, not timed with a stopwatch.
External standards and references. ArduPilot documentation. ExpressLRS documentation. NATO STANAG 4609 Ed. 4 (motion imagery metadata), STANAG 4671 (UAV airworthiness), and STANAG 2022 (intelligence source reliability). MAVLink security analysis (Shostack, 2023). MAVLink 2.0 specification. Specifically: Watling & Reynolds, "Meatgrinder: Russian Tactics", RUSI (2023); Bronk, Reynolds & Watling, "The Russian Air War and Ukrainian Requirements for Air Defence", RUSI (2022); ISW daily campaign assessments (understandingwar.org archive); CSIS Center for Strategic and International Studies Ukraine briefings. FSG-A has verified signing in SITL — not under field conditions.