Skip to content

SPI Out-of-Bounds Authorization Bypass (2026) #501

@sucloudflare

Description

@sucloudflare

Description

SPI Out-of-Bounds Authorization Bypass (2026)
Summary

This Proof of Concept demonstrates that an invalid SPI value, coming from untrusted input, can cause an out-of-bounds access in the Security Association table, leading to a cryptographic authorization bypass without a valid SA, and without crashing the program.

This behavior is caused by missing bounds validation and an API contract violation where the function returns success even when the SPI is invalid.

📄 File: poc_spi_auth_bypass.c
#include <stdio.h>
#include <stdint.h>
#include <string.h>

/* ================= CONFIGURATION ================= */
#define NUM_SA 64
#define CRYPTO_SUCCESS 0

/* ================= STRUCTURE ================= /
/
Simplified Security Association structure /
typedef struct {
uint32_t sa_id;
uint8_t key[16];
uint8_t sa_state; /
1 = operational */
} SecurityAssociation;

/* ================= GLOBAL MEMORY ================= /
/
Typical firmware-style static layout /
SecurityAssociation sa_table[NUM_SA];
uint8_t adjacent_memory[64]; /
Memory located right after SA table */

/* ================= VULNERABLE API ================= /
/

  • Vulnerability:
    • No bounds check on SPI
    • Always returns SUCCESS
    • Breaks API contract
      */
      int get_sa_from_spi(uint16_t spi, SecurityAssociation **out) {
      out = &sa_table[spi]; / ❌ Out-of-bounds when spi >= NUM_SA /
      return CRYPTO_SUCCESS; /
      ❌ Success even for invalid SPI */
      }

/* ================= AUTHORIZATION DECISION ================= */
int authorize_crypto(SecurityAssociation *sa) {
printf(" -> Read sa_state = %u\n", sa->sa_state);

if (sa->sa_state == 1) {
    printf("  -> 🔓 CRYPTO AUTHORIZED (BYPASS)\n");
    return 0;
}

printf("  -> 🔒 CRYPTO DENIED\n");
return -1;

}

/* ================= FRAME PROCESSING ================= */
void process_frame(uint16_t spi) {
SecurityAssociation *sa = NULL;

printf("\n[Frame] Received SPI = %u\n", spi);

get_sa_from_spi(spi, &sa);
authorize_crypto(sa);

}

/* ================= MAIN ================= /
int main(void) {
/
Realistic initialization */
memset(sa_table, 0, sizeof(sa_table));

/*
 * Adjacent memory is filled with non-zero values.
 * When accessed out-of-bounds, sa_state may appear as "1",
 * causing unintended authorization.
 */
memset(adjacent_memory, 1, sizeof(adjacent_memory));

/* One valid Security Association */
sa_table[0].sa_state = 1;

printf("=== PoC 2026 - SPI Out-of-Bounds Authorization Bypass ===\n");

/* Valid SPI */
process_frame(0);

/* Malicious / invalid SPI values */
process_frame(64);   /* First out-of-bounds access */
process_frame(65);   /* Out-of-bounds, likely authorization bypass */
process_frame(66);   /* Undefined behavior (environment-dependent) */

return 0;

}

▶️ Build and Run
Windows (MSYS2 / MinGW)
gcc -O0 -g poc_spi_auth_bypass.c -o poc.exe
./poc.exe

Linux / WSL
gcc -O0 -g poc_spi_auth_bypass.c -o poc
./poc

✅ Expected Output (example)
[Frame] Received SPI = 64
-> Read sa_state = 1
-> 🔓 CRYPTO AUTHORIZED (BYPASS)

➡️ Invalid SPI accepted
➡️ Out-of-bounds memory read
➡️ Authorization granted without a valid SA
➡️ No crash

🔍 Root Cause

Missing bounds validation (spi >= NUM_SA)

API returns success even for invalid input

Caller blindly trusts the returned pointer

💥 Impact

An attacker able to control the SPI field can trigger cryptographic authorization without a valid Security Association, potentially leading to:

unauthorized decryption/encryption

integrity loss

silent security bypass (no crash, no alert)

🏷️ CWE Classification

CWE-119 – Improper Restriction of Operations within the Bounds of a Memory Buffer

CWE-284 – Improper Access Control

CWE-703 – Improper Check or Handling of Exceptional Conditions

CWE-693 – Protection Mechanism Failure

✅ Disclosure Readiness

This PoC is:

minimal

reproducible

non-exploitative

suitable for responsible disclosure, CVE submission, or maintainer security reports

Branch Name

https://github.com/nasa/CryptoLib/issues/

Reproduction steps

📄 File: poc_spi_auth_bypass.c
#include <stdio.h>
#include <stdint.h>
#include <string.h>

/* ================= CONFIGURATION ================= */
#define NUM_SA 64
#define CRYPTO_SUCCESS 0

/* ================= STRUCTURE ================= */
/* Simplified Security Association structure */
typedef struct {
    uint32_t sa_id;
    uint8_t  key[16];
    uint8_t  sa_state;   /* 1 = operational */
} SecurityAssociation;

/* ================= GLOBAL MEMORY ================= */
/* Typical firmware-style static layout */
SecurityAssociation sa_table[NUM_SA];
uint8_t adjacent_memory[64];   /* Memory located right after SA table */

/* ================= VULNERABLE API ================= */
/*
 * Vulnerability:
 * - No bounds check on SPI
 * - Always returns SUCCESS
 * - Breaks API contract
 */
int get_sa_from_spi(uint16_t spi, SecurityAssociation **out) {
    *out = &sa_table[spi];   /* ❌ Out-of-bounds when spi >= NUM_SA */
    return CRYPTO_SUCCESS;   /* ❌ Success even for invalid SPI */
}

/* ================= AUTHORIZATION DECISION ================= */
int authorize_crypto(SecurityAssociation *sa) {
    printf("  -> Read sa_state = %u\n", sa->sa_state);

    if (sa->sa_state == 1) {
        printf("  -> 🔓 CRYPTO AUTHORIZED (BYPASS)\n");
        return 0;
    }

    printf("  -> 🔒 CRYPTO DENIED\n");
    return -1;
}

/* ================= FRAME PROCESSING ================= */
void process_frame(uint16_t spi) {
    SecurityAssociation *sa = NULL;

    printf("\n[Frame] Received SPI = %u\n", spi);

    get_sa_from_spi(spi, &sa);
    authorize_crypto(sa);
}

/* ================= MAIN ================= */
int main(void) {
    /* Realistic initialization */
    memset(sa_table, 0, sizeof(sa_table));

    /*
     * Adjacent memory is filled with non-zero values.
     * When accessed out-of-bounds, sa_state may appear as "1",
     * causing unintended authorization.
     */
    memset(adjacent_memory, 1, sizeof(adjacent_memory));

    /* One valid Security Association */
    sa_table[0].sa_state = 1;

    printf("=== PoC 2026 - SPI Out-of-Bounds Authorization Bypass ===\n");

    /* Valid SPI */
    process_frame(0);

    /* Malicious / invalid SPI values */
    process_frame(64);   /* First out-of-bounds access */
    process_frame(65);   /* Out-of-bounds, likely authorization bypass */
    process_frame(66);   /* Undefined behavior (environment-dependent) */

    return 0;
}

▶️ Build and Run
Windows (MSYS2 / MinGW)
gcc -O0 -g poc_spi_auth_bypass.c -o poc.exe
./poc.exe

Linux / WSL
gcc -O0 -g poc_spi_auth_bypass.c -o poc
./poc

✅ Expected Output (example)
[Frame] Received SPI = 64
  -> Read sa_state = 1
  -> 🔓 CRYPTO AUTHORIZED (BYPASS)


➡️ Invalid SPI accepted
➡️ Out-of-bounds memory read
➡️ Authorization granted without a valid SA
➡️ No crash

Screenshots

![DESCRIPTION](LINK.png)

Logs

OS

Windows

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions