ESP32

ESP32 Hardware Encryption: Secure IoT Applications

ESP32 Plaintext Hello AES-128 Ciphertext F7B3D1... Key ESP32 Hardware Encryption Secure IoT Connection

Introduction

The ESP32 comes with built-in hardware encryption capabilities that set it apart from many other microcontrollers like the ESP8266. These features make the ESP32 an excellent choice for IoT applications where data security is crucial. The hardware acceleration for cryptographic operations ensures that encryption and decryption processes are fast and power-efficient, unlike software-based alternatives.

ESP32 Cryptographic Features

The ESP32 is equipped with a range of hardware security features that make it ideal for building secure IoT devices:

  • Hardware AES Acceleration: For fast symmetric encryption
  • SHA-2 Acceleration: For secure hashing operations
  • RSA Acceleration: For asymmetric cryptography
  • RNG (Random Number Generator): True hardware-based random number generation
  • Secure Boot: Ensures only trusted code executes on startup
  • Flash Encryption: Protects code and data stored in flash memory

AES Encryption

AES (Advanced Encryption Standard) is a symmetric encryption algorithm widely used for securing sensitive data. The ESP32's hardware-accelerated AES implementation supports 128, 192, and 256-bit key lengths, providing robust security while minimizing CPU and power consumption.

mbedtls_aes_context aes;
mbedtls_aes_init(&aes);
mbedtls_aes_setkey_enc(&aes, key, 128);

Secure Boot

Secure Boot ensures that only authorized firmware can run on your ESP32. When enabled, the bootloader verifies the signature of the firmware before executing it, preventing unauthorized or tampered code from running.

Note: Enabling Secure Boot is a one-time operation. Once enabled, you cannot disable it without replacing the ESP32 chip.

Flash Encryption

Flash Encryption protects the contents of the ESP32's flash memory by encrypting it. This prevents unauthorized access to your firmware, configurations, and sensitive data stored in flash.

Warning: After enabling Flash Encryption, normal UART flashing will no longer work. You'll need to follow specific procedures for updates.

Example 1 - AES-128 Encryption and Decryption

This example demonstrates how to use the ESP32's hardware-accelerated AES encryption to secure data. We'll encrypt a message using AES-128 in ECB mode (for demonstration purposes), then decrypt it to verify the process.

Requirements

You'll need an ESP32 development board and the Arduino IDE with ESP32 support installed. No additional components are required as we're using the ESP32's built-in capabilities.

Code

#include "mbedtls/aes.h"

// AES-128 key (16 bytes)
const unsigned char key[16] = {
  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
};

// Input message to encrypt (must be a multiple of 16 bytes)
unsigned char plaintext[32] = "ESP32 Hardware Encryption Demo!"; 

// Buffer for encrypted output
unsigned char encrypted[32];

// Buffer for decrypted output
unsigned char decrypted[32];

void setup() {
  Serial.begin(115200);
  
  // Wait for serial connection
  delay(1000);
  
  Serial.println("ESP32 Hardware Encryption Demo");
  Serial.println("------------------------------");
  
  // Display original message
  Serial.print("Original message: ");
  Serial.println((char*)plaintext);
  
  // Perform encryption
  encryptAES(plaintext, encrypted);
  
  // Display encrypted message (as hex)
  Serial.print("Encrypted message (hex): ");
  for (int i = 0; i < 32; i++) {
    Serial.printf("%02X", encrypted[i]);
  }
  Serial.println();
  
  // Perform decryption
  decryptAES(encrypted, decrypted);
  
  // Display decrypted message
  Serial.print("Decrypted message: ");
  Serial.println((char*)decrypted);
  
  // Benchmark encryption performance
  Serial.println("\nPerformance Benchmark");
  Serial.println("---------------------");
  benchmarkEncryption();
}

void loop() {
  // Nothing in loop
}

// Encrypt data using AES-128-ECB
void encryptAES(unsigned char* input, unsigned char* output) {
  mbedtls_aes_context aes;
  
  mbedtls_aes_init(&aes);
  mbedtls_aes_setkey_enc(&aes, key, 128);
  
  // Process data in 16-byte blocks (AES block size)
  for (int i = 0; i < 2; i++) {
    mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, input + (i * 16), output + (i * 16));
  }
  
  mbedtls_aes_free(&aes);
}

// Decrypt data using AES-128-ECB
void decryptAES(unsigned char* input, unsigned char* output) {
  mbedtls_aes_context aes;
  
  mbedtls_aes_init(&aes);
  mbedtls_aes_setkey_dec(&aes, key, 128);
  
  // Process data in 16-byte blocks (AES block size)
  for (int i = 0; i < 2; i++) {
    mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_DECRYPT, input + (i * 16), output + (i * 16));
  }
  
  mbedtls_aes_free(&aes);
}

// Benchmark encryption performance
void benchmarkEncryption() {
  const int dataSize = 1024; // 1KB of data
  unsigned char* testData = (unsigned char*)malloc(dataSize);
  unsigned char* encryptedData = (unsigned char*)malloc(dataSize);
  
  // Fill test data
  for (int i = 0; i < dataSize; i++) {
    testData[i] = i & 0xFF;
  }
  
  // Prepare AES context
  mbedtls_aes_context aes;
  mbedtls_aes_init(&aes);
  mbedtls_aes_setkey_enc(&aes, key, 128);
  
  // Start timing
  unsigned long startTime = micros();
  
  // Encrypt data (1KB)
  for (int i = 0; i < dataSize / 16; i++) {
    mbedtls_aes_crypt_ecb(&aes, MBEDTLS_AES_ENCRYPT, testData + (i * 16), encryptedData + (i * 16));
  }
  
  // End timing
  unsigned long endTime = micros();
  
  // Calculate performance
  float timeMs = (endTime - startTime) / 1000.0;
  float throughputKBps = (dataSize / 1024.0) / (timeMs / 1000.0);
  
  Serial.print("Time to encrypt 1KB: ");
  Serial.print(timeMs);
  Serial.println(" ms");
  Serial.print("Encryption throughput: ");
  Serial.print(throughputKBps);
  Serial.println(" KB/s");
  
  // Free memory
  free(testData);
  free(encryptedData);
  mbedtls_aes_free(&aes);
}

Expected Output

ESP32 Hardware Encryption Demo

------------------------------

Original message: ESP32 Hardware Encryption Demo!

Encrypted message (hex): A6B7D8E2F456A3C7D9E2F4A8B7C9D2E3F1A9B7C8D6E3F4A9B7C5D3E6F4A9B8

Decrypted message: ESP32 Hardware Encryption Demo!

Performance Benchmark

---------------------

Time to encrypt 1KB: 2.56 ms

Encryption throughput: 390.62 KB/s

Note: The actual encryption output and performance metrics will vary based on your specific ESP32 model.

Practical Applications

Secure IoT Communications

Encrypt sensor data before transmission to ensure privacy and prevent unauthorized access to sensitive information.

Firmware Protection

Use Secure Boot and Flash Encryption to prevent unauthorized firmware modifications and protect your intellectual property.

Credential Storage

Securely store WiFi passwords, API keys, and other credentials in encrypted flash memory to prevent unauthorized access.

Access Control Systems

Build secure RFID/NFC access control systems with encrypted communication between tags, readers, and backend systems.