7  Symmetric Encryption for IoT

7.1 Learning Objectives

By the end of this chapter, you will be able to:

  • Explain Symmetric Encryption Principles: Describe how single-key encryption works and its role in IoT security
  • Implement AES Encryption: Apply the Advanced Encryption Standard with appropriate modes (GCM, CCM) for IoT devices
  • Select Appropriate Key Sizes: Choose between AES-128 and AES-256 based on security requirements and constraints
  • Avoid Common Pitfalls: Identify and prevent key management failures, ECB mode misuse, and weak key derivation
In 60 Seconds

Symmetric encryption uses a single shared secret key for both encryption and decryption, providing fast, low-overhead data protection suitable for the high-throughput, low-power requirements of IoT devices.

MVU: Symmetric Encryption Essentials

Core Concept: Symmetric encryption uses a single shared secret key for both encryption and decryption, making it the fastest and most energy-efficient way to protect IoT data in transit and at rest.

Why It Matters: IoT devices run on limited power and processing - symmetric encryption (AES) is 1000x faster than asymmetric alternatives, enabling real-time secure communication without draining batteries or overwhelming microcontrollers.

Key Takeaway: Always use AES-GCM or AES-CCM modes (never ECB), protect your keys in hardware security modules, and remember: key management is harder than encryption itself.

In Plain English

Symmetric encryption uses one shared key for both locking (encrypting) and unlocking (decrypting) data. Think of it like a house key that both you and your friend have copies of - anyone with the key can get in.

Why it matters for IoT: Symmetric encryption (AES) is the workhorse of IoT security - it’s fast, battery-efficient, and supported by hardware accelerators in most microcontrollers. When your smart thermostat sends temperature readings to the cloud, it uses symmetric encryption to scramble the data into gibberish that only the cloud server can unscramble.

Symmetric encryption is like having a SECRET DECODER RING that you share with your best friend!

Imagine you and your friend both have the SAME magic decoder ring. When you want to send a secret message, you spin the ring to scramble your words into gibberish. Your friend uses their identical ring to unscramble it back!

7.1.1 The Sensor Squad Story: Operation Cookie Jar

Sammy the Sensor wanted to send a secret message to Lila the LED about where the cookies were hidden. But sneaky Max the Motor might be listening!

“I know!” said Sammy. “Let’s use our SECRET CODE WHEELS!”

Both Sammy and Lila had identical code wheels that shifted each letter by 3: - A becomes D - B becomes E - COOKIES becomes FRRNLHV

Sammy sent “FRRNLHV DUH LQ WKH MDU” (Cookies are in the jar)

Max the Motor intercepted the message but saw only gobbledygook! “FRRNLHV? What’s that supposed to mean?” he grumbled.

Lila used her matching code wheel to decode it: “Cookies are in the jar! Thanks Sammy!”

The Important Lesson: The code only works if BOTH friends have the SAME key (code wheel). If someone steals the key, they can read ALL your messages! That’s why keeping the key secret is the most important part!

7.1.2 Try This at Home!

Make Your Own Symmetric Cipher:

  1. Write the alphabet in a circle on cardboard
  2. Make a smaller circle with the alphabet that spins on top
  3. Spin it 5 letters - now A=F, B=G, C=H…
  4. Write a secret message to your friend!
  5. Give them an identical wheel set to the same position

Key Words: | Word | What It Means | |——|—————| | Symmetric | Both sides use the SAME key (like identical decoder rings) | | Key | The secret code that scrambles and unscrambles messages | | AES | A super-strong scrambling recipe used by smart devices | | Encrypt | Scrambling a message so only key-holders can read it | | Decrypt | Unscrambling a message back to readable words |

7.2 Prerequisites

Before diving into this chapter, you should be familiar with:

  • Cryptography Principles: Understanding of basic encryption concepts, the CIA triad, and why cryptography matters for IoT security
  • IoT Security Fundamentals: Knowledge of common IoT threats and why data protection is essential for connected devices
Key Concepts
  • Symmetric Key: A single secret key shared between sender and receiver; used for both encrypting and decrypting data.
  • AES (Advanced Encryption Standard): The most widely deployed symmetric cipher; operates on 128-bit blocks with 128, 192, or 256-bit key sizes.
  • Block Cipher Mode: A scheme for applying a block cipher to data longer than one block; common modes include CBC, CTR, and GCM.
  • AES-GCM: AES in Galois/Counter Mode — provides authenticated encryption with associated data (AEAD), simultaneously ensuring confidentiality and integrity.
  • ChaCha20-Poly1305: A stream-cipher-based AEAD scheme that is faster than AES on devices without hardware AES acceleration; used in TLS 1.3.
  • Key Distribution Problem: The challenge of securely sharing a symmetric key between parties before they can communicate; addressed by asymmetric key exchange or pre-shared keys.

7.3 How It Works: AES Encryption Process

Understanding AES-GCM encryption from plaintext to authenticated ciphertext:

  1. Key Establishment: Device and gateway share a 128-bit or 256-bit AES key (established via TLS handshake using asymmetric encryption)
  2. Nonce Generation: Generate a unique 96-bit nonce for this message using hardware random number generator (NEVER reuse nonces)
  3. AAD Preparation: Additional Authenticated Data (like device ID, timestamp) is protected for integrity but not encrypted
  4. AES-CTR Encryption: Encrypt the nonce + counter with AES to generate keystream, XOR with plaintext to produce ciphertext
  5. GMAC Authentication: Compute Galois Message Authentication Code over ciphertext + AAD to generate 128-bit authentication tag
  6. Transmission: Send nonce + ciphertext + authentication tag (receiver needs nonce to decrypt)
  7. Verification: Receiver computes authentication tag and compares - any tampering causes mismatch, message rejected

This entire process on ESP32 hardware AES acceleration takes ~15 microseconds for a 64-byte sensor payload, consuming approximately 1.5 microjoules - negligible impact on battery life.

7.4 How Symmetric Encryption Works

Symmetric encryption uses a single secret key for both encryption and decryption. Both communicating parties must securely share this key before they can communicate securely.

The fundamental process is straightforward: the sender takes plaintext data, combines it with the secret key using a mathematical algorithm, and produces ciphertext. The receiver applies the same key and algorithm in reverse to recover the original plaintext.

Symmetric encryption flow showing plaintext encrypted with shared key to produce ciphertext, then decrypted back
Figure 7.1: Symmetric encryption flow: the same key encrypts and decrypts data

As shown in the figure above, the critical characteristic of symmetric encryption is that both parties must possess the same secret key. This creates the fundamental challenge known as the “key distribution problem” - how do you securely share the key in the first place?

Sender encrypts plaintext with shared secret key, transmits ciphertext, receiver decrypts with same key
Figure 7.2: Sender and receiver using a shared secret key

Advantages:

  • Fast encryption/decryption: 1000x faster than asymmetric encryption
  • Low computational overhead: Ideal for resource-constrained IoT devices
  • Suitable for bulk data: Encrypt gigabytes efficiently
  • Hardware acceleration available: Most modern MCUs include AES accelerators

Disadvantages:

  • Key distribution problem: How do you securely share the key initially?
  • Requires secure channel for key exchange: Catch-22 - need security to establish security
  • \(n(n-1)/2\) keys needed for \(n\) parties: Doesn’t scale well for large networks
  • Key compromise affects all communication: One leaked key exposes everything

Question: A network of 50 IoT devices needs pairwise secure communication using symmetric encryption, where each pair of devices shares a unique key. How many keys are needed?

  1. 50 keys
  2. 100 keys
  3. 1,225 keys
  4. 2,500 keys

Correct: C) 1,225 keys

Using the formula n(n-1)/2 where n = 50: 50 x 49 / 2 = 1,225 unique keys

This is why symmetric encryption alone doesn’t scale well - a network of 1,000 devices would need 499,500 keys! This is the key distribution problem that asymmetric encryption helps solve.

7.5 Block vs Stream Ciphers

Symmetric ciphers come in two fundamental types, each suited to different IoT scenarios. Understanding the difference helps you choose the right approach for your application.

Comparison of block cipher processing fixed 128-bit blocks vs stream cipher encrypting data byte-by-byte
Figure 7.3: Block vs stream cipher comparison

Block Ciphers: Encrypt fixed-size blocks (e.g., 128 bits)

  • Examples: AES, DES (deprecated), IDEA, Blowfish, RC5, RC6
  • Requires padding for partial blocks (if your data is 200 bits, you need to pad to 256)
  • Various modes: ECB, CBC, CTR, GCM - each with different properties
  • Best for: File encryption, database encryption, stored data

Stream Ciphers: Encrypt data streams bit-by-bit or byte-by-byte

  • Examples: ChaCha20 (modern), RC4 (deprecated - insecure)
  • No padding required: Handles any data length naturally
  • Suitable for real-time data: Audio/video streaming, continuous sensor data
  • Best for: VoIP encryption, real-time telemetry, live video feeds
Characteristic Block Cipher Stream Cipher
Processing Unit Fixed blocks (128 bits) Bit-by-bit or byte-by-byte
Padding Required Not required
Latency Higher (wait for block) Lower (immediate)
Error Propagation Mode-dependent Single-bit errors
IoT Use Case Stored data, bulk transfer Real-time streaming
Example AES-GCM for sensor logs ChaCha20 for voice
Decision tree for choosing between block and stream ciphers based on data type, latency, and IoT requirements
Figure 7.4: Cipher selection decision tree

Question: You’re designing a real-time audio streaming system for IoT intercoms. The audio data comes in variable-length chunks at 20ms intervals. Which cipher type is MOST appropriate?

  1. Block cipher (AES-CBC)
  2. Stream cipher (ChaCha20)
  3. Block cipher (AES-ECB)
  4. Asymmetric cipher (RSA)

Correct: B) Stream cipher (ChaCha20)

Stream ciphers like ChaCha20 are ideal for real-time streaming because: - They encrypt data byte-by-byte without needing to wait for complete blocks - No padding overhead means lower latency - They naturally handle variable-length data - Single-bit errors don’t corrupt entire blocks

AES-CBC would add latency waiting for blocks to fill, and ECB should never be used (patterns leak). RSA is far too slow for continuous audio.

7.6 AES (Advanced Encryption Standard)

Standardization: U.S. NIST FIPS PUB 197 (2001), superseding DES (1977)

Parameters:

  • Block size: 128 bits (4x4 byte matrix)
  • Key sizes: 128, 192, or 256 bits
  • Rounds: 10 (AES-128), 12 (AES-192), 14 (AES-256)
AES encryption rounds: SubBytes substitution, ShiftRows rotation, MixColumns mixing, and AddRoundKey XOR steps
Figure 7.5: AES algorithm structure with SubBytes, ShiftRows, MixColumns, and AddRoundKey transformations

7.6.1 How AES Works: A Block-Level Walkthrough

Understanding what happens inside AES helps you appreciate why it is secure and how the modes of operation build on the core algorithm.

Input: A 128-bit plaintext block (16 bytes) arranged as a 4x4 byte matrix, plus a 128-bit key.

Plaintext block (hex):        Key (hex):
32 88 31 E0                   2B 7E 15 16
43 5A 31 37                   28 AE D2 A6
F6 30 98 07                   AB F7 15 88
A8 8D A2 34                   09 CF 4F 3C

The 10-round process (AES-128):

Round Step What It Does Why It Matters
1. AddRoundKey XOR each byte with the corresponding key byte Mixes the key into the data. Without the key, this step cannot be reversed.
2. SubBytes Replace each byte using a fixed lookup table (the S-box) Introduces non-linearity. Without this, AES would be a system of linear equations solvable with basic algebra.
3. ShiftRows Shift row 0 by 0, row 1 by 1, row 2 by 2, row 3 by 3 positions left Spreads each byte’s influence across all 4 columns, preventing column-by-column attacks.
4. MixColumns Multiply each column by a fixed polynomial matrix Each output byte depends on all 4 input bytes in the column. Combined with ShiftRows, after 2 rounds every output bit depends on every input bit.

After 10 rounds (each using a different round key derived from the original), even a single-bit change in plaintext or key produces a completely different ciphertext – this is the avalanche effect.

Key schedule: The original 128-bit key generates 10 additional round keys (176 bytes total) through a deterministic expansion algorithm. This is why you only need to store the original 16-byte key, not all 176 bytes.

The Penguin Problem: Why Raw AES Is Not Enough

AES encrypts one 16-byte block at a time. If you encrypt a 1 MB image block by block with the same key and no additional mechanism, identical plaintext blocks produce identical ciphertext blocks. This is the infamous “ECB penguin” – an image of a penguin encrypted with AES-ECB still shows the penguin’s outline because regions of the same color encrypt to the same ciphertext.

This is why AES needs a mode of operation – a scheme that ensures identical plaintext blocks produce different ciphertext blocks. The mode is as important as the algorithm itself.

7.6.2 AES Encryption Modes

AES supports multiple modes of operation, each with different characteristics:

Mode Full Name Padding Parallelizable Authentication IoT Use Case
ECB Electronic Codebook Yes Yes No NEVER USE - patterns visible
CBC Cipher Block Chaining Yes Decrypt only No Legacy systems
CTR Counter Mode No Yes No Stream encryption
GCM Galois/Counter Mode No Yes Yes Recommended for IoT
CCM Counter with CBC-MAC No No Yes Zigbee, BLE, Thread
AES encryption modes compared: ECB pattern leakage, CBC chaining, CTR counter, GCM authenticated, CCM constrained
Figure 7.6: AES encryption modes compared

7.6.3 How Each Mode Works and When to Use It in IoT

ECB (Electronic Codebook) – Never use.

Each 16-byte block is encrypted independently with the same key. Identical input blocks produce identical output blocks. An attacker monitoring ECB-encrypted sensor traffic can detect when the temperature is the same as yesterday without decrypting anything. There is no legitimate IoT use case for ECB.

CBC (Cipher Block Chaining) – Legacy only.

Each plaintext block is XORed with the previous ciphertext block before encryption. The first block uses a random Initialization Vector (IV). This means identical plaintext blocks produce different ciphertext, solving the ECB pattern problem. However, CBC provides only confidentiality, not integrity. An attacker can flip bits in ciphertext to predictably alter the decrypted plaintext (bit-flipping attack). If a sensor sends {"valve": "open"} encrypted with CBC, an attacker could modify ciphertext bytes to change the decrypted value without knowing the key.

  • IoT use case: Legacy systems that cannot be upgraded. Never use for new designs.

CTR (Counter Mode) – Good for streaming, but no integrity.

Encrypts a counter value (nonce + incrementing block number) to produce a key stream, which is XORed with plaintext. This turns AES into a stream cipher – no padding needed, fully parallelizable, and you can encrypt/decrypt individual blocks without processing the entire message.

  • IoT use case: Real-time audio/video streaming where you need low latency and random access. Pair with a separate HMAC for integrity if needed.

GCM (Galois/Counter Mode) – Recommended default for IoT.

CTR mode for encryption plus Galois field multiplication for authentication. Produces both ciphertext and a 16-byte authentication tag. Any modification to the ciphertext, the Additional Authenticated Data (AAD), or the tag causes decryption to fail. Fully parallelizable.

  • IoT use case: MQTT payloads over TLS 1.3, REST API communication, any scenario where the device has 4+ KB RAM for the GCM multiplication tables. The ESP32 has hardware GCM acceleration and can encrypt at ~10 us per 16-byte block.

CCM (Counter with CBC-MAC) – Best for constrained devices.

CTR mode for encryption plus CBC-MAC for authentication. Functionally similar to GCM (encryption + authentication), but uses less RAM because CBC-MAC does not need the Galois multiplication tables. The trade-off: CCM cannot be parallelized, so it is slower on multi-core processors.

  • IoT use case: IEEE 802.15.4 (Zigbee, Thread), BLE, and any device with limited RAM (<4 KB). The nRF52 series uses CCM natively for BLE encryption.

Mode Selection Quick Reference for IoT Protocols:

IoT Protocol AES Mode Used Why
TLS 1.3 (MQTT, HTTPS) AES-128-GCM or AES-256-GCM Performance + authentication, hardware accelerated
DTLS (CoAP) AES-128-CCM-8 Constrained devices, 8-byte MAC saves overhead
Zigbee (802.15.4) AES-128-CCM Specified in IEEE 802.15.4, low RAM requirement
BLE (Bluetooth LE) AES-128-CCM Nordic/TI hardware support, 128-bit key mandated
Thread (Matter) AES-128-CCM Same 802.15.4 foundation as Zigbee
LoRaWAN AES-128-CTR + AES-128-CMAC CTR for payload encryption, CMAC for integrity (separate passes)
WPA3 (Wi-Fi) AES-256-GCM (GCMP-256) Strongest mode for high-bandwidth Wi-Fi

Question: Your IoT device uses Zigbee for home automation. Which AES mode is most likely used by the Zigbee protocol stack?

  1. AES-ECB (simplest mode)
  2. AES-CBC (legacy mode)
  3. AES-CCM (Counter with CBC-MAC)
  4. AES-GCM (Galois/Counter Mode)

Correct: C) AES-CCM

Zigbee, BLE, and Thread protocols use AES-CCM because: - It provides both encryption AND authentication in a single pass - It’s optimized for constrained devices with limited RAM - The CCM mode is specified in IEEE 802.15.4 (the foundation for Zigbee) - GCM requires more memory for the Galois field multiplication tables

AES-GCM is used in TLS 1.3 and MQTT over TLS where devices have more resources.

7.6.4 Hardware-Accelerated AES in IoT

Many modern IoT microcontrollers include dedicated AES hardware accelerators:

Platform Hardware Support Performance
ESP32 AES accelerator ~10 cycles/byte
STM32 AES peripheral ~15 cycles/byte
nRF52 CryptoCell ~12 cycles/byte
ARM Cortex-M ARMv8 Cryptography Extensions ~5 cycles/byte

Software AES: ~1,200 cycles per 128-bit block Hardware AES: ~20 cycles per block (60x speedup, 10x less power)

7.7 Key Size Recommendations

Choosing the right key size balances security strength against computational cost and battery life:

Key Size Security Level Use Case Battery Impact
AES-128 Strong (2^128 combinations) Most IoT devices, consumer products Baseline
AES-256 Maximum (quantum-resistant) Medical, financial, critical infrastructure ~40% more power (14 vs 10 rounds)

When to Choose AES-256:

  • Medical devices (pacemakers, insulin pumps)
  • Smart locks, alarm systems, access control
  • Long-term data storage (10+ years)
  • Compliance requirements (HIPAA, PCI-DSS)

When AES-128 is Sufficient:

  • Smart home sensors (temperature, humidity, motion)
  • Fitness trackers, wearables
  • Smart appliances
  • Data retained < 5 years

Objective: Encrypt IoT sensor data using AES-GCM (authenticated encryption) and see how tampering is detected.

from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os

# Generate a random 128-bit AES key (simulating device provisioning)
key = AESGCM.generate_key(bit_length=128)
aesgcm = AESGCM(key)

# Sensor reading to protect
sensor_data = b'{"temp": 22.5, "humidity": 65, "device": "ESP32_001"}'

# Additional authenticated data (not encrypted, but integrity-protected)
aad = b"sensor_id=ESP32_001,seq=42"

# Encrypt with a unique nonce (NEVER reuse!)
nonce = os.urandom(12)  # 96-bit nonce for GCM
ciphertext = aesgcm.encrypt(nonce, sensor_data, aad)

print(f"Plaintext:  {sensor_data.decode()}")
print(f"Ciphertext: {ciphertext[:24].hex()}... ({len(ciphertext)} bytes)")
print(f"Overhead:   {len(ciphertext) - len(sensor_data)} bytes (GCM auth tag)")

# Decrypt successfully
decrypted = aesgcm.decrypt(nonce, ciphertext, aad)
print(f"\nDecrypted:  {decrypted.decode()}")

# Simulate tampering: flip one bit in ciphertext
tampered = bytearray(ciphertext)
tampered[10] ^= 0x01
try:
    aesgcm.decrypt(nonce, bytes(tampered), aad)
    print("Decrypted tampered data (BAD!)")
except Exception:
    print("[DETECTED] Tampering detected - GCM auth tag mismatch!")

# Simulate metadata tampering
try:
    aesgcm.decrypt(nonce, ciphertext, b"sensor_id=ATTACKER,seq=42")
    print("Accepted wrong metadata (BAD!)")
except Exception:
    print("[DETECTED] AAD mismatch - metadata was modified!")

What to Observe:

  1. GCM adds a 16-byte authentication tag (ciphertext is 16 bytes longer than plaintext)
  2. Any modification to ciphertext OR metadata causes decryption to fail
  3. Each encryption needs a unique nonce – reusing nonces breaks GCM security

Objective: See why AES-ECB leaks patterns and should never be used for IoT data.

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
import os

key = os.urandom(16)  # AES-128

def ecb_encrypt(key, data):
    """Encrypt with ECB mode (INSECURE - for demonstration only)"""
    cipher = Cipher(algorithms.AES(key), modes.ECB())
    encryptor = cipher.encryptor()
    # Pad to 16-byte blocks
    padded = data + b'\x00' * (16 - len(data) % 16)
    return encryptor.update(padded) + encryptor.finalize()

# Simulate repeated sensor readings (same temperature)
reading = b"temp=22.5C______"  # Exactly 16 bytes (one AES block)

# ECB: identical inputs produce identical outputs
ct1 = ecb_encrypt(key, reading)
ct2 = ecb_encrypt(key, reading)
ct3 = ecb_encrypt(key, reading)

print("ECB Mode (INSECURE):")
print(f"  Reading 1: {ct1[:16].hex()}")
print(f"  Reading 2: {ct2[:16].hex()}")
print(f"  Reading 3: {ct3[:16].hex()}")
print(f"  All identical: {ct1[:16] == ct2[:16] == ct3[:16]}")
print("  -> Attacker knows when same value is sent!")

# GCM: identical inputs produce different outputs
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
aesgcm = AESGCM(key)
print("\nGCM Mode (SECURE):")
for i in range(3):
    nonce = os.urandom(12)
    ct = aesgcm.encrypt(nonce, reading, None)
    print(f"  Reading {i+1}: {ct[:16].hex()}")
print("  All different even though plaintext is identical!")

What to Observe:

  1. ECB produces identical ciphertext for identical plaintext – patterns leak
  2. GCM uses a unique nonce, so the same plaintext always produces different ciphertext
  3. An attacker monitoring ECB-encrypted traffic can detect when sensor values repeat

#include <mbedtls/aes.h>
#include <mbedtls/gcm.h>
#include <Arduino.h>

void printHex(const unsigned char* data, int len) {
  for (int i = 0; i < len; i++) Serial.printf("%02x", data[i]);
  Serial.println();
}

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("=== ESP32 AES-GCM Demo ===\n");

  // AES-128 key (in production, store in secure element)
  unsigned char key[16];
  esp_fill_random(key, 16);

  // Sensor data to encrypt
  const char* plaintext = "temp=22.5,hum=65";
  int pt_len = strlen(plaintext);

  // Unique nonce for each message
  unsigned char nonce[12];
  esp_fill_random(nonce, 12);

  // Encrypt with AES-128-GCM
  unsigned char ciphertext[64];
  unsigned char tag[16];
  mbedtls_gcm_context gcm;
  mbedtls_gcm_init(&gcm);
  mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, key, 128);
  mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT,
    pt_len, nonce, 12, NULL, 0,
    (const unsigned char*)plaintext, ciphertext, 16, tag);

  Serial.print("Plaintext:  "); Serial.println(plaintext);
  Serial.print("Ciphertext: "); printHex(ciphertext, pt_len);
  Serial.print("Auth Tag:   "); printHex(tag, 16);

  // Decrypt and verify
  unsigned char decrypted[64];
  int ret = mbedtls_gcm_auth_decrypt(&gcm, pt_len,
    nonce, 12, NULL, 0, tag, 16, ciphertext, decrypted);

  decrypted[pt_len] = '\0';
  if (ret == 0) {
    Serial.print("Decrypted:  "); Serial.println((char*)decrypted);
    Serial.println("[OK] Authentication verified");
  } else {
    Serial.println("[FAIL] Authentication failed!");
  }

  // Performance benchmark
  unsigned long start = micros();
  for (int i = 0; i < 1000; i++) {
    mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT,
      pt_len, nonce, 12, NULL, 0,
      (const unsigned char*)plaintext, ciphertext, 16, tag);
  }
  Serial.printf("\n1000 encryptions: %lu us (%.1f us each)\n",
    micros() - start, (micros() - start) / 1000.0);

  mbedtls_gcm_free(&gcm);
}

void loop() {}

What to Observe: The ESP32 encrypts sensor data in microseconds using hardware AES acceleration. The 16-byte auth tag ensures any tampering is detected.

7.8 Real-World IoT Example: Smart Home Thermostat

Let’s trace how symmetric encryption protects a real IoT device:

Smart thermostat encryption flow: TLS key exchange, AES-GCM encrypted temperature readings to cloud, then to phone app
Figure 7.7: Smart home thermostat encryption flow

Step 1 - Key Setup: When your thermostat first connects to the cloud, they use asymmetric encryption (TLS) to securely exchange an AES session key. This solves the key distribution problem.

Step 2 - Secure Communication: Now both devices have the same AES-128-GCM key. Every temperature reading (72 F) gets encrypted before transmission. Even if someone intercepts the Wi-Fi traffic, they see only gibberish (a7F9x2Kp…).

Step 3 - End-to-End Protection: The cloud decrypts your data, processes it, then re-encrypts it before sending to your phone app. Your temperature data is protected at every hop.

Why AES-GCM? This mode provides both encryption (confidentiality) AND authentication (integrity). If someone modifies the encrypted data, the receiver detects the tampering immediately.

7.9 Common Pitfalls

Never Store Keys in Plain Text

The most common IoT security failure is storing encryption keys in plain text:

  1. Use hardware security modules (HSM) or Trusted Platform Modules (TPM)
  2. Never hardcode keys in firmware - attackers can extract them
  3. Encrypt keys at rest using platform-specific secure storage
  4. Implement key derivation from device-unique identifiers
  5. Use secure boot to verify firmware integrity

Real example: Millions of IoT cameras compromised because AES keys were stored in /etc/config.ini in plain text.

Pitfall: Using ECB Mode

The Mistake: Developers encrypt data using AES in ECB mode because it’s the simplest.

Why It’s Dangerous: ECB encrypts identical plaintext blocks into identical ciphertext blocks, revealing patterns.

The Fix: Always use authenticated encryption modes:

  • AES-GCM: Industry standard for TLS 1.3 and MQTT
  • AES-CCM: Designed for constrained devices (Zigbee, BLE)
  • ChaCha20-Poly1305: When hardware AES is unavailable
Pitfall: Weak Key Derivation

The Mistake: Generating keys by hashing predictable values: key = SHA256(device_mac_address)

Why It’s Dangerous: If the attacker knows the vendor OUI (the first 3 bytes of a MAC address), they only need to search 2^24 device-specific combinations per vendor to pre-compute all possible keys.

The Fix:

  • Use hardware True Random Number Generator (TRNG)
  • Use HKDF with device-unique salt: HKDF-SHA256(master_secret, salt=device_id)
  • Pre-provision unique keys during manufacturing

7.10 Key Management on IoT Devices

Encryption algorithms are well-understood and mathematically proven. Key management is where real-world deployments fail. This section addresses the practical question: where does the key live, and how does it get there?

7.10.1 Key Storage Options by Platform

Platform Secure Storage Key Extraction Risk Cost
ESP32 NVS encrypted partition (flash encryption + secure boot) Medium – flash dump possible without secure boot $3-5 per chip
ESP32-S3 NVS + eFuse key storage (one-time programmable) Low – eFuse keys cannot be read back by software $4-6 per chip
nRF52840 CryptoCell 310 key storage + ARM TrustZone Low – hardware-isolated key storage $5-8 per chip
STM32L4 PCROP (code readout protection) + AES hardware key Low – keys in hardware peripheral $4-7 per chip
ATECC608A (external) Dedicated secure element, tamper-resistant Very Low – certified tamper resistance $0.60-1.50 per chip
Software-only (no HW security) Flash/EEPROM in plaintext Very High – trivial to extract $0

7.10.2 Worked Example: Secure Key Provisioning Pipeline

Worked Example: From Factory to Field

Scenario: A manufacturer produces 10,000 soil moisture sensors. Each needs a unique AES-128-GCM key to encrypt MQTT payloads.

Step 1 – Manufacturing (factory floor):

import os
import hashlib
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives import hashes

# Master secret stored in Hardware Security Module (HSM) at factory
MASTER_SECRET = bytes.fromhex("...")  # loaded from HSM, never in source code

def provision_device(device_serial: str) -> bytes:
    """Derive a unique device key from master secret + serial."""
    # HKDF: deterministic but unpredictable without master secret
    hkdf = HKDF(
        algorithm=hashes.SHA256(),
        length=16,  # AES-128
        salt=os.urandom(16),  # unique salt per device, stored alongside
        info=f"aes-gcm-v1:{device_serial}".encode(),
    )
    device_key = hkdf.derive(MASTER_SECRET)
    return device_key

# For each device off the production line:
serial = "SM-2026-00001"
key = provision_device(serial)
# Key is burned into ESP32 eFuse or ATECC608A during factory programming
# Serial + salt stored in provisioning database

Step 2 – Device boot (in the field):

// ESP32 Arduino: Load key from encrypted NVS partition
#include <nvs_flash.h>
#include <mbedtls/gcm.h>

uint8_t device_key[16];

void load_key() {
    nvs_handle_t handle;
    nvs_open("security", NVS_READONLY, &handle);
    size_t key_len = 16;
    nvs_get_blob(handle, "aes_key", device_key, &key_len);
    nvs_close(handle);
    // Key is now in RAM only -- flash partition is encrypted
}

Step 3 – Key rotation (every 90 days):

The device requests a new session key from the cloud using its device key for authentication. The new session key is encrypted with the device key during transit, so even if the network is compromised, only the target device can decrypt the new key.

What an attacker faces:

  • Cannot read eFuse keys (hardware protection)
  • Cannot derive device keys without master secret (HKDF is one-way)
  • Cannot reuse captured session keys after rotation
  • Must physically extract keys from each device individually (does not scale)

7.11 Use Cases and Limitations

Common applications for symmetric encryption in IoT:

Use Case Example Why Symmetric
Bulk Data Encryption Database encryption, file system encryption, large data transfers Speed and efficiency for large volumes
IoT Device Communication Sensor data encryption, command authentication, network security Low computational overhead on constrained devices
Payment Systems Card transactions, PII protection Industry-standard compliance (PCI-DSS)
Key Derivation Deriving session keys, generating nonces AES-based DRBG and CMAC are widely used

Practical limitations to plan for:

  • Key Exhaustion: Each key use leaks a negligible amount of information. Implement key rotation (e.g., every 90 days or after 2^32 messages for GCM) and maintain a key hierarchy.
  • Scalability: Manual management works for tens of keys, but thousands or millions of devices require automated provisioning systems.
  • Key Loss: If a retired key is unavailable, encrypted data stored under that key becomes permanently inaccessible. Maintain secure key backups.
Connection: AES-GCM meets MQTT Payload Encryption

When MQTT uses TLS (port 8883), the TLS layer negotiates AES-GCM as the cipher suite (e.g., TLS_AES_128_GCM_SHA256 in TLS 1.3). Every MQTT PUBLISH message is encrypted with the exact AES-GCM mode described in this chapter. For devices that cannot afford full TLS, application-layer encryption using AES-GCM on the MQTT payload provides confidentiality without the TLS handshake overhead. See IoT Protocol Security for MQTT TLS configuration details.

Exercise: Implement and compare AES-ECB vs AES-GCM to see why ECB is dangerous.

Scenario: You have an IoT sensor sending repeated temperature readings:

# Simulate 5 temperature readings - notice readings 1, 3, and 5 are identical
readings = [
    "temp=22.5C______",  # Reading 1
    "temp=23.0C______",  # Reading 2
    "temp=22.5C______",  # Reading 3 (same as 1)
    "temp=24.5C______",  # Reading 4
    "temp=22.5C______",  # Reading 5 (same as 1)
]

Tasks:

  1. Encrypt all 5 readings with AES-ECB mode (use the cryptography library example above)
  2. Encrypt the same readings with AES-GCM mode
  3. Compare the ciphertext outputs - what patterns do you see in ECB? What about GCM?
  4. Calculate what percentage of ciphertext blocks are identical in ECB mode
  5. Try modifying one bit in an ECB ciphertext - does decryption detect the tampering?
  6. Try the same tampering attack on GCM ciphertext - what happens?

What to observe: ECB leaks information (identical readings produce identical ciphertext). GCM prevents pattern leakage AND detects tampering. This is why ECB should NEVER be used for IoT sensor data.

Extension: Research the “ECB penguin” - encrypt an image with ECB mode and see that the image outline remains visible despite encryption.

Computational infeasibility of AES-128 brute force

\[\text{AES-128 Key Space} = 2^{128} = 3.4 \times 10^{38} \text{ possible keys}\]

Working through an example:

Given: Modern GPU testing \(10^{12}\) keys per second (1 trillion keys/s, optimistic)

Step 1: Average keys to test (50% probability of finding correct key) \[K_{\text{avg}} = \frac{2^{128}}{2} = 2^{127} = 1.7 \times 10^{38} \text{ keys}\]

Step 2: Time to crack with single GPU \[T_{\text{GPU}} = \frac{1.7 \times 10^{38}}{10^{12}} = 1.7 \times 10^{26} \text{ seconds}\]

Step 3: Convert to years \[T_{\text{years}} = \frac{1.7 \times 10^{26}}{365.25 \times 24 \times 3600} = 5.4 \times 10^{18} \text{ years}\]

Step 4: Compare to age of universe \[\text{Age of Universe} = 13.8 \times 10^9 \text{ years}\]

\[\text{Ratio} = \frac{5.4 \times 10^{18}}{13.8 \times 10^9} \approx 391 \text{ billion universe lifetimes}\]

Result: Brute-forcing AES-128 requires 391 billion times the age of the universe with trillion-keys-per-second hardware. AES-256 increases this to \(10^{60}\) years – utterly infeasible.

In practice: Even 10-year battery-powered sensors are secure with AES-128. The real vulnerability is key extraction, not brute force. Invest in secure key storage (HSMs), not longer keys.

Concept Relationships
Concept Builds On Enables Related To
Symmetric Encryption Shared secret keys Fast bulk data encryption AES algorithm, XOR operations
AES-GCM Mode CTR encryption + GMAC Authenticated encryption (AEAD) Confidentiality + integrity, TLS 1.3
AES-CCM Mode CTR encryption + CBC-MAC Constrained device AEAD Zigbee, BLE, Thread, 802.15.4
Block Cipher Modes AES block operations Pattern concealment ECB (never use), CBC, CTR, GCM
Hardware Acceleration Platform crypto engines Energy-efficient encryption ESP32, STM32, nRF52 crypto hardware
Key Management Secure key storage Encryption effectiveness HSMs, TPMs, key rotation, provisioning

Key Dependencies: AES provides the cryptographic primitive, but the mode of operation determines security properties. GCM/CCM add authentication to prevent tampering. Hardware acceleration makes encryption practical for battery-powered IoT. Key management is the weakest link - even perfect AES fails with poor key handling.

:

7.12 What’s Next

Next Topic Description
Asymmetric Encryption Learn how public-key cryptography solves the key distribution problem and enables digital signatures for IoT device authentication
Link-Layer Encryption (E1) Explore how symmetric encryption is applied at the link layer in protocols like Zigbee, BLE, and Thread
Hash Functions Understand how hash functions complement symmetric encryption for integrity verification and key derivation