DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
ssh_aesgcm.h File Reference

AES-256-GCM AEAD for SSH (aes25.nosp@m.6-gc.nosp@m.m@ope.nosp@m.nssh.nosp@m..com, RFC 5647). More...

#include "shared_primitives/ghash.h"
#include <stddef.h>
#include <stdint.h>
#include <mbedtls/aes.h>

Go to the source code of this file.

Classes

struct  SshAesGcmCtx
 AES-256-GCM context for one SSH direction (HW AES on ESP32). More...
 

Functions

void ssh_aesgcm_init (SshAesGcmCtx *ctx, const uint8_t key[SSH_AESGCM_KEY_LEN], const uint8_t iv[SSH_AESGCM_IV_LEN])
 Initialize an AES-256-GCM context: expand the key, precompute H, latch the initial nonce.
 
void ssh_aesgcm_seal (SshAesGcmCtx *ctx, const uint8_t *aad, size_t aad_len, const uint8_t *pt, size_t pt_len, uint8_t *out)
 Seal one packet: AES-256-GCM encrypt pt (pt_len bytes) and authenticate it together with aad. Writes pt_len ciphertext bytes then the 16-byte tag into out (so out must hold pt_len + SSH_AESGCM_TAG_LEN bytes). out may alias pt (in place). The context's invocation counter is advanced by one afterwards.
 
bool ssh_aesgcm_open (SshAesGcmCtx *ctx, const uint8_t *aad, size_t aad_len, const uint8_t *ct, size_t ct_len, const uint8_t tag[SSH_AESGCM_TAG_LEN], uint8_t *out)
 Open one packet: verify the 16-byte tag over aad || ct in constant time, and only on success decrypt ct (ct_len bytes) into out (out may alias ct). The invocation counter is advanced by one on success.
 
void ssh_aesgcm_wipe (SshAesGcmCtx *ctx)
 Zero the key schedule, H, and nonce (volatile wipe). Call on disconnect.
 

Detailed Description

AES-256-GCM AEAD for SSH (aes25.nosp@m.6-gc.nosp@m.m@ope.nosp@m.nssh.nosp@m..com, RFC 5647).

The OpenSSH AES-GCM cipher is an AEAD: the 4-byte SSH packet_length is sent in the clear and authenticated as additional data (AAD), the rest of the binary packet (padding_length || payload || padding) is encrypted, and a 16-byte GCM tag follows. No separate MAC is negotiated - the AEAD tag is the integrity check (RFC 5647 sec 7.3).

NONCE / INVOCATION COUNTER (RFC 5647 sec 7.1) The 12-byte GCM nonce is fixed_field(4) || invocation_counter(8). The initial nonce is the first 12 bytes of the IV derived from the key exchange (RFC 4253 sec 7.2, labels 'A'/'B'). After every packet the 8-byte invocation_counter is incremented as a big-endian integer; the 4-byte fixed field never changes. The counter therefore lives in the context and advances once per sealed/opened packet

  • this is what makes the cipher stateful and requires whole-packet atomicity in the packet layer.

PLATFORM SELECTION (mirrors ssh_aes256ctr / quic_aead) On Arduino (ESP32) the AES-256 block is mbedtls, routed to the hardware AES accelerator. On native host builds a compact software AES-256 is used so the whole AEAD is unit-testable off-target. GHASH and the counter loop are the same software on both targets.

Pure, zero heap; host-tested against the NIST/McGrew AES-256-GCM test vectors and round-tripped through the SSH packet layer.

Author
Douglas Quigg (dstroy0)
Date
2026

Definition in file ssh_aesgcm.h.

Function Documentation

◆ ssh_aesgcm_init()

void ssh_aesgcm_init ( SshAesGcmCtx ctx,
const uint8_t  key[SSH_AESGCM_KEY_LEN],
const uint8_t  iv[SSH_AESGCM_IV_LEN] 
)

Initialize an AES-256-GCM context: expand the key, precompute H, latch the initial nonce.

Parameters
ctxUninitialized context.
key32-byte AES-256 key (KEX label 'C'/'D').
iv12-byte initial nonce (first 12 bytes of the KEX 'A'/'B' IV).

Definition at line 268 of file ssh_aesgcm.cpp.

References ghash_key_init(), SshAesGcmCtx::ghk, SshAesGcmCtx::h, SshAesGcmCtx::iv, and SshAesGcmCtx::ready.

Referenced by ssh_dh_derive_keys_sid().

◆ ssh_aesgcm_seal()

void ssh_aesgcm_seal ( SshAesGcmCtx ctx,
const uint8_t *  aad,
size_t  aad_len,
const uint8_t *  pt,
size_t  pt_len,
uint8_t *  out 
)

Seal one packet: AES-256-GCM encrypt pt (pt_len bytes) and authenticate it together with aad. Writes pt_len ciphertext bytes then the 16-byte tag into out (so out must hold pt_len + SSH_AESGCM_TAG_LEN bytes). out may alias pt (in place). The context's invocation counter is advanced by one afterwards.

Definition at line 278 of file ssh_aesgcm.cpp.

References SshAesGcmCtx::iv.

Referenced by ssh_pkt_send().

◆ ssh_aesgcm_open()

bool ssh_aesgcm_open ( SshAesGcmCtx ctx,
const uint8_t *  aad,
size_t  aad_len,
const uint8_t *  ct,
size_t  ct_len,
const uint8_t  tag[SSH_AESGCM_TAG_LEN],
uint8_t *  out 
)

Open one packet: verify the 16-byte tag over aad || ct in constant time, and only on success decrypt ct (ct_len bytes) into out (out may alias ct). The invocation counter is advanced by one on success.

Returns
true iff the tag is valid.

Definition at line 301 of file ssh_aesgcm.cpp.

References SshAesGcmCtx::iv.

Referenced by ssh_pkt_recv().

◆ ssh_aesgcm_wipe()

void ssh_aesgcm_wipe ( SshAesGcmCtx ctx)

Zero the key schedule, H, and nonce (volatile wipe). Call on disconnect.

Definition at line 324 of file ssh_aesgcm.cpp.