ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
esp.h File Reference

ESP (RFC 4303) packet transform with AES-256-GCM (RFC 4106) - the IPsec datapath's crypto core. More...

#include "protocore_config.h"

Go to the source code of this file.

Classes

struct  EspReplay
 Anti-replay sliding-window state for one inbound SA (zero-heap). More...
 
struct  EspNs
 Dispatch table. Addressed by offset, so the layout is asserted below. More...
 

Macros

#define PROTOCORE_ESP_HDR_LEN   8
 ESP header size: SPI(4) + Sequence Number(4).
 
#define PROTOCORE_ESP_IV_LEN   8
 Explicit IV length carried in the packet (AES-GCM, RFC 4106).
 
#define PROTOCORE_ESP_SALT_LEN   4
 Implicit salt length (the tail of the ESP key, not on the wire).
 
#define PROTOCORE_ESP_ICV_LEN   16
 AES-GCM authentication tag / ICV length.
 
#define PROTOCORE_ESP_KEY_LEN   32
 AES-256 key length.
 
#define PROTOCORE_ESP_REPLAY_WINDOW   64
 ESP anti-replay window size (fixed by the 64-bit bitmap).
 

Functions

 PROTOCORE_NS_LAYOUT (EspNs, gcm_encapsulate, gcm_decapsulate, replay_init, replay_check)
 
size_t protocore_esp_gcm_encapsulate (uint8_t *work, uint32_t spi, uint32_t seq, const uint8_t *key, const uint8_t *salt, const uint8_t *iv, uint8_t next_header, const uint8_t *payload, size_t payload_len, uint8_t *out, size_t out_cap)
 Encapsulate payload in an RFC 4303 ESP packet with AES-256-GCM. .
 
proto_bool protocore_esp_gcm_decapsulate (uint8_t *work, const uint8_t *key, const uint8_t *salt, uint8_t *packet, size_t len, uint32_t *spi_out, uint32_t *seq_out, uint8_t *next_header_out, const uint8_t **payload_out, size_t *payload_len_out)
 Verify + decapsulate an ESP packet in place (the ciphertext is .
 
void protocore_esp_replay_init (uint8_t *work, EspReplay *r)
 Reset an anti-replay window (no packets seen yet).
 
proto_bool protocore_esp_replay_check (uint8_t *work, EspReplay *r, uint32_t seq)
 Anti-replay check + record for a received sequence number seq (RFC .
 

Variables

PROTOCORE_NS EspNs Esp PROTOCORE_UNUSED
 Module namespace.
 

Detailed Description

ESP (RFC 4303) packet transform with AES-256-GCM (RFC 4106) - the IPsec datapath's crypto core.

Tier 3 of the IPsec roadmap item is the ESP datapath. Its two halves separate cleanly: this pure, host-testable PACKET transform (encapsulate a payload into an ESP packet / verify + decapsulate one), and the device-side network-layer integration (hooking lwIP's IP input/output + the SAD/SPD), which is a separate, later track. This file is only the transform, gated with the IKEv2 feature (its Child-SA keys - SK_ei / SK_er from Ike.child_keymat - drive it) and reusing the library's AES-256-GCM.

Wire layout (RFC 4303 ยง2, AES-GCM per RFC 4106): SPI(4) | Sequence Number(4) | IV(8, explicit) | { AES-GCM: Payload | Padding | Pad Length | Next Header } | ICV(16). The AEAD authenticates SPI | Seq as additional data; the nonce is the 4-byte salt (from the ESP key) concatenated with the 8-byte explicit IV. Padding right-aligns Pad Length + Next Header to a 4-octet boundary and holds the RFC 4303 monotonic bytes 1, 2, 3 ...

work is bytes the CALLER holds. This module reads none of them: it carries nothing between calls, so there is no state to keep and nothing to wipe. The parameter is there so a caller drives every namespace the same way.

Author
Douglas Quigg (dstroy0)
Date
2026

Definition in file esp.h.

Macro Definition Documentation

◆ PROTOCORE_ESP_HDR_LEN

#define PROTOCORE_ESP_HDR_LEN   8

ESP header size: SPI(4) + Sequence Number(4).

Definition at line 41 of file esp.h.

◆ PROTOCORE_ESP_IV_LEN

#define PROTOCORE_ESP_IV_LEN   8

Explicit IV length carried in the packet (AES-GCM, RFC 4106).

Definition at line 44 of file esp.h.

◆ PROTOCORE_ESP_SALT_LEN

#define PROTOCORE_ESP_SALT_LEN   4

Implicit salt length (the tail of the ESP key, not on the wire).

Definition at line 47 of file esp.h.

◆ PROTOCORE_ESP_ICV_LEN

#define PROTOCORE_ESP_ICV_LEN   16

AES-GCM authentication tag / ICV length.

Definition at line 50 of file esp.h.

◆ PROTOCORE_ESP_KEY_LEN

#define PROTOCORE_ESP_KEY_LEN   32

AES-256 key length.

Definition at line 53 of file esp.h.

◆ PROTOCORE_ESP_REPLAY_WINDOW

#define PROTOCORE_ESP_REPLAY_WINDOW   64

ESP anti-replay window size (fixed by the 64-bit bitmap).

Definition at line 56 of file esp.h.

Function Documentation

◆ PROTOCORE_NS_LAYOUT()

PROTOCORE_NS_LAYOUT ( EspNs  ,
gcm_encapsulate  ,
gcm_decapsulate  ,
replay_init  ,
replay_check   
)

◆ protocore_esp_gcm_encapsulate()

size_t protocore_esp_gcm_encapsulate ( uint8_t *  work,
uint32_t  spi,
uint32_t  seq,
const uint8_t *  key,
const uint8_t *  salt,
const uint8_t *  iv,
uint8_t  next_header,
const uint8_t *  payload,
size_t  payload_len,
uint8_t *  out,
size_t  out_cap 
)

Encapsulate payload in an RFC 4303 ESP packet with AES-256-GCM. .

Parameters
workPROTOCORE_ESP_BORROW bytes the caller took. Not held past the call.
spiSpi
seqSeq
key32-byte AES-256 key (SK_ei / SK_er without the salt) PROTOCORE_ESP_KEY_LEN bytes
saltthe 4-byte salt (the ESP key's tail) PROTOCORE_ESP_SALT_LEN bytes
ivthe 8-byte explicit IV (unique per packet under a key - e.g. the sequence number)
next_headerNext header
payloadPayload
payload_lenPayload len
outOut
out_capOut cap
Returns
The size_t.

◆ protocore_esp_gcm_decapsulate()

proto_bool protocore_esp_gcm_decapsulate ( uint8_t *  work,
const uint8_t *  key,
const uint8_t *  salt,
uint8_t *  packet,
size_t  len,
uint32_t *  spi_out,
uint32_t *  seq_out,
uint8_t *  next_header_out,
const uint8_t **  payload_out,
size_t *  payload_len_out 
)

Verify + decapsulate an ESP packet in place (the ciphertext is .

Parameters
workPROTOCORE_ESP_BORROW bytes the caller took. Not held past the call.
keyPROTOCORE_ESP_KEY_LEN bytes
saltPROTOCORE_ESP_SALT_LEN bytes
packetthe ESP packet (mutated: decrypted in place). payload_out points into it on success
lenLen
spi_outSpi out
seq_outSeq out
next_header_outNext header out
payload_outPayload out
payload_len_outPayload len out
Returns
PROTO_TRUE on success.

◆ protocore_esp_replay_init()

void protocore_esp_replay_init ( uint8_t *  work,
EspReplay *  r 
)

Reset an anti-replay window (no packets seen yet).

Parameters
workPROTOCORE_ESP_BORROW bytes the caller took. Not held past the call.
rR

◆ protocore_esp_replay_check()

proto_bool protocore_esp_replay_check ( uint8_t *  work,
EspReplay *  r,
uint32_t  seq 
)

Anti-replay check + record for a received sequence number seq (RFC .

Parameters
workPROTOCORE_ESP_BORROW bytes the caller took. Not held past the call.
rR
seqSeq
Returns
PROTO_TRUE on success.

Variable Documentation

◆ PROTOCORE_UNUSED

PROTOCORE_NS EspNs Esp PROTOCORE_UNUSED
Initial value:
= {.gcm_encapsulate = protocore_esp_gcm_encapsulate,
.gcm_decapsulate = protocore_esp_gcm_decapsulate,
.replay_init = protocore_esp_replay_init,
.replay_check = protocore_esp_replay_check}
void protocore_esp_replay_init(uint8_t *work, EspReplay *r)
Reset an anti-replay window (no packets seen yet).
proto_bool protocore_esp_replay_check(uint8_t *work, EspReplay *r, uint32_t seq)
Anti-replay check + record for a received sequence number seq (RFC .
size_t protocore_esp_gcm_encapsulate(uint8_t *work, uint32_t spi, uint32_t seq, const uint8_t *key, const uint8_t *salt, const uint8_t *iv, uint8_t next_header, const uint8_t *payload, size_t payload_len, uint8_t *out, size_t out_cap)
Encapsulate payload in an RFC 4303 ESP packet with AES-256-GCM. .
proto_bool protocore_esp_gcm_decapsulate(uint8_t *work, const uint8_t *key, const uint8_t *salt, uint8_t *packet, size_t len, uint32_t *spi_out, uint32_t *seq_out, uint8_t *next_header_out, const uint8_t **payload_out, size_t *payload_len_out)
Verify + decapsulate an ESP packet in place (the ciphertext is .

Module namespace.

Definition at line 129 of file esp.h.