cybersecurity · intermediate · ~15 min · safe pentest lab

Constant-time memory comparison

Mitigate side-channel timing attacks by executing constant-time buffer comparisons.

Challenge

Standard memcmp returns immediately upon finding the first differing byte. Attackers measuring sub-microsecond timing differences can deduce authentication tokens and HMAC signatures byte-by-byte.

Your Task

Implement:

int safe_const_time_memcmp(const void *a, const void *b, size_t n);

Compare n bytes of memory in constant time.

Rules

  1. If n == 0, return 0.
  2. If a == NULL or b == NULL (when n > 0), return -1.
  3. Compare all n bytes using a bitwise accumulator (diff |= p1[i] ^ p2[i]) without early breaks or conditional exits.
  4. Return 0 if all bytes are identical, or non-zero if any byte differs.

Example

char k1[4] = "auth";
char k2[4] = "auth";
char k3[4] = "auto";
safe_const_time_memcmp(k1, k2, 4); // returns 0 (match)
safe_const_time_memcmp(k1, k3, 4); // returns non-zero (mismatch)

Input format

a, b: pointers to byte sequences; n: number of bytes to compare.

Output format

Returns 0 if identical, non-zero if different, -1 on NULL pointer.

Constraints

Constant-time execution. Never break early from the comparison loop.

Starter code

#include <stddef.h>

/* Compare n bytes of a and b in constant time.
   Return 0 if identical, non-zero if different, or -1 if inputs are NULL (when n > 0).
   Must NOT break early. */
int safe_const_time_memcmp(const void *a, const void *b, size_t n) {
    (void)a; (void)b; (void)n;
    return -1;
}

Common mistakes

Using an early return inside the loop; casting to signed char causing sign-extension artifacts.

Edge cases to handle

n == 0 returns 0 even with NULL pointers; difference at byte 0; difference at byte n - 1.

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.