Skip to main content

Encryption

HDDS uses AES-256-GCM authenticated encryption for data protection.

Overview

Encryption protects:

  • Confidentiality: Data cannot be read by unauthorized parties
  • Integrity: Data tampering is detected
  • Authenticity: Data origin is verified

Algorithm Details

PropertyValue
CipherAES-256-GCM
Key Size256 bits (32 bytes)
Nonce Size96 bits (12 bytes)
Auth Tag128 bits (16 bytes)
Hardware AccelAES-NI (when available)

Configuration

use hdds::prelude::*;
use hdds::security::SecurityConfig;

let security = SecurityConfig::builder()
.identity_certificate("cert.pem")
.private_key("key.pem")
.ca_certificates("ca.pem")
.enable_encryption(true) // Enable AES-256-GCM
.build()?;

let participant = DomainParticipant::builder()
.domain_id(0)
.security(security)
.build()?;

Key Exchange

Session keys are derived using ECDH + HKDF:

Key Derivation

  1. ECDH: Each participant generates ephemeral P-256 keypair
  2. Agreement: Compute shared secret from peer's public key
  3. HKDF-Extract: Derive pseudorandom key with salt
  4. HKDF-Expand: Derive 256-bit session key with context info
ECDH shared secret (32 bytes)


HKDF-Extract (salt)


Pseudorandom Key (PRK)


HKDF-Expand (info: "DDS Security v1.1")


Session Key (32 bytes)

Nonce Management

Each message uses a unique 96-bit nonce:

  • Generation: Cryptographically random via SystemRandom
  • Uniqueness: Never reused with same key
  • Collision probability: ~2^-96 (negligible)
// Internal: Nonce generation per message
let nonce = SystemRandom::new().generate_nonce_96();
let ciphertext = aes_gcm_encrypt(&key, &nonce, &plaintext);
// Output: ciphertext || auth_tag (16 bytes)

What Gets Encrypted

DataEncryptedNotes
User data payloadFull encryption
RTPS submessageAfter authentication
Discovery (SPDP)Required for handshake
Discovery (SEDP)After authentication
Metadata headersRequired for routing

Encryption Modes

Per-Submessage Encryption

Each RTPS submessage is encrypted independently:

+-------------------+
| RTPS Header | <- Not encrypted (routing)
+-------------------+
| SEC_PREFIX | <- Crypto transform info
+-------------------+
| Encrypted DATA | <- AES-256-GCM ciphertext
+-------------------+
| SEC_POSTFIX | <- Authentication tag
+-------------------+

Origin Authentication

GCM authentication tag verifies:

  • Data was not modified in transit
  • Data came from expected sender (via key binding)

Performance

MetricValue
Encryption overhead~200 ns per message
Latency increase~80% vs unencrypted
Throughput625 MB/s
CPU at 50K msg/s~5%

Hardware Acceleration

HDDS uses the ring crate which leverages:

  • x86_64: AES-NI instructions
  • ARM: ARMv8 Crypto extensions
  • Fallback: Software implementation

Check hardware support:

# x86_64
grep -o aes /proc/cpuinfo | head -1
# Output: aes (if supported)

# ARM
cat /proc/cpuinfo | grep Features | grep -o aes

Ciphertext Format

+-------------------+-------------------+
| Ciphertext | Authentication Tag |
| (len = plaintext) | (16 bytes) |
+-------------------+-------------------+

Total overhead: 16 bytes per message (auth tag only, nonce transmitted separately in SEC_PREFIX)

Key Rotation

Session keys can be rotated for forward secrecy:

  1. New ephemeral keypair generated
  2. New ECDH agreement
  3. New session key derived
  4. Old key securely erased

This ensures past traffic cannot be decrypted if current key is compromised.

Audit Logging

When enabled, encryption events are logged:

let security = SecurityConfig::builder()
// ...
.enable_encryption(true)
.enable_audit_log(true) // Log crypto events
.build()?;

Events logged:

  • Key derivation (success/failure)
  • Encryption operations
  • Decryption failures (potential attack)

Security Guarantees

What Encryption Provides

  • Confidentiality: Only intended recipients can read data
  • Integrity: Any modification is detected
  • Replay protection: Via sequence numbers and timestamps

What Encryption Does NOT Provide

  • Traffic analysis protection: Message timing/size visible
  • Denial of service protection: Attackers can drop packets
  • Endpoint security: Application must protect keys

Troubleshooting

Decryption Fails

# Enable crypto debug logging
export RUST_LOG=hdds::security::crypto=debug

Common causes:

  • Key mismatch (check authentication)
  • Corrupted ciphertext (network issue)
  • Clock skew (check NTP)

Performance Issues

If encryption is too slow:

  1. Verify AES-NI is enabled (check CPU flags)
  2. Consider message batching
  3. Use larger messages (overhead is per-message)

Best Practices

  1. Always enable encryption for sensitive data
  2. Use authentication - encryption without auth is meaningless
  3. Protect private keys - encrypt at rest, restrict access
  4. Monitor failures - decryption failures may indicate attacks
  5. Keep time synced - use NTP for timestamp verification

Next Steps