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

SSH transport-layer protocol state machine (RFC 4253). More...

Go to the source code of this file.

Classes

struct  SshSession
 

Macros

#define SSH_VERSION_MAX   256
 Max stored length of an SSH identification string (RFC 4253 §4.2: 255).
 
#define SSH_SERVER_VERSION   "SSH-2.0-DetWS_1.0"
 Server identification string (no CR LF; appended on the wire).
 

Enumerations

enum class  SshPhase : uint8_t {
  SSH_PHASE_BANNER , SSH_PHASE_KEXINIT , SSH_PHASE_DH_INIT , SSH_PHASE_NEWKEYS ,
  SSH_PHASE_SERVICE , SSH_PHASE_AUTH , SSH_PHASE_OPEN
}
 SSH connection lifecycle phase. More...
 
enum class  SshKexAlg : uint8_t { SSH_KEX_DH_GROUP14 = 0 , SSH_KEX_CURVE25519 = 1 , SSH_KEX_MLKEM768_X25519 = 2 , SSH_KEX_ECDH_NISTP256 = 3 }
 SSH transport/session state for one connection (BSS pool). More...
 
enum class  SshHostkeyAlg : uint8_t { SSH_HOSTKEY_RSA_SHA256 = 0 , SSH_HOSTKEY_ED25519 = 1 , SSH_HOSTKEY_RSA_SHA512 = 2 , SSH_HOSTKEY_ECDSA_NISTP256 = 3 }
 Negotiated host-key / signature algorithm. More...
 

Functions

void ssh_transport_init (uint8_t i)
 Reset transport state for slot i to the start of a handshake.
 
int ssh_transport_server_banner (uint8_t *out, size_t *out_len, size_t cap)
 Write the server identification string ("SSH-2.0-…\r\n") to out.
 
int ssh_transport_recv_banner (uint8_t i, const uint8_t *data, size_t len, size_t *consumed)
 Feed raw bytes while awaiting the client identification string.
 
int ssh_kexinit_build (uint8_t i, uint8_t *payload, size_t *len, size_t cap)
 Build the server KEXINIT payload for slot i (RFC 4253 §7.1).
 
int ssh_kexinit_parse (uint8_t i, const uint8_t *payload, size_t len)
 Parse and negotiate the client KEXINIT payload (RFC 4253 §7.1).
 
void ssh_kex_set_prefer_rsa (bool prefer)
 Steer KEX / host-key negotiation toward RSA + DH-group14 (default) or toward the modern curve25519 + ed25519 suite.
 
bool ssh_kex_prefer_rsa (void)
 Current negotiation preference (true = prefer RSA/DH, the ESP32-accelerated path).
 
void ssh_hostkey_ed25519_set (const uint8_t seed[32])
 Install an ssh-ed25519 host key from its 32-byte seed (RFC 8032 private key).
 
bool ssh_hostkey_ed25519_available (void)
 True if an ssh-ed25519 host key has been installed.
 
void ssh_hostkey_ecdsa_set (const uint8_t priv[32])
 Install an ecdsa-sha2-nistp256 host key from its 32-byte P-256 private scalar.
 
bool ssh_hostkey_ecdsa_available (void)
 True if an ecdsa-sha2-nistp256 host key has been installed.
 
int ssh_kex_generate (uint8_t i)
 Generate the server ephemeral for the negotiated KEX method (call after parse).
 
int ssh_extinfo_build (uint8_t *out, size_t *len, size_t cap)
 Build SSH_MSG_EXT_INFO advertising server-sig-algs (RFC 8308).
 
int ssh_kex_exchange_hash (uint8_t i, const uint8_t *e_be, const uint8_t *f_be, const uint8_t *k_be, const uint8_t *ks, size_t ks_len, uint8_t out[SSH_SHA256_DIGEST_LEN])
 Compute the SSH exchange hash H (RFC 4253 §8).
 
int ssh_kexdh_parse_init (const uint8_t *payload, size_t len, uint8_t e_be[256])
 Parse SSH_MSG_KEXDH_INIT, extracting the client DH value e.
 
int ssh_kexdh_build_reply (const uint8_t *ks, size_t ks_len, const uint8_t *f_be, const uint8_t *sig, size_t sig_len, uint8_t *out, size_t *out_len, size_t cap)
 Build SSH_MSG_KEXDH_REPLY (RFC 4253 §8, RFC 8332 §3).
 
int ssh_kexdh_handle (uint8_t i, const uint8_t *payload, size_t len, uint8_t *reply_out, size_t *reply_len, size_t cap)
 Handle KEXDH/ECDH_INIT (msg 30) end-to-end and produce the reply payload.
 
void ssh_newkeys_sent (uint8_t i)
 Activate the outbound direction after emitting our SSH_MSG_NEWKEYS.
 
void ssh_newkeys_complete (uint8_t i)
 Complete the NEWKEYS exchange: activate the inbound direction and advance phase.
 
bool ssh_rekey_needed (uint8_t i)
 True if slot i has reached the re-key threshold (RFC 4253 §9).
 
bool ssh_rekey_due (uint32_t seq_send, uint32_t seq_recv, uint32_t elapsed_ms, uint32_t pkt_threshold, uint32_t time_threshold_ms)
 Pure re-key decision (RFC 4253 §9: "after each gigabyte ... or after each hour").
 
int ssh_transport_begin_rekey (uint8_t i, uint8_t *out, size_t *out_len, size_t cap)
 Begin a server-initiated re-key by emitting a fresh KEXINIT.
 

Variables

SshSession ssh_sess [MAX_SSH_CONNS]
 Static pool of SSH session state (BSS), one per SSH slot.
 

Detailed Description

SSH transport-layer protocol state machine (RFC 4253).

Sits on top of the binary packet layer (ssh_packet.*) and the crypto primitives (ssh_dh, ssh_rsa, ssh_aes256ctr, ssh_hmac_sha256). Drives the handshake: identification-string (banner) exchange → algorithm negotiation (KEXINIT) → Diffie-Hellman key exchange (KEXDH) → NEWKEYS → key install, then hands off to the user-auth layer (ssh_auth.*).

── Supported algorithms (crypto-agnostic KEX; steered to a runtime preference) ─ kex : diffie-hellman-group14-sha256 (RFC 8268) curve25519-sha256 (RFC 8731) ecdh-sha2-nistp256 (RFC 5656 §4) host key / sig : rsa-sha2-512, rsa-sha2-256 (RFC 8332) ecdsa-sha2-nistp256 (RFC 5656) ssh-ed25519 (RFC 8709) cipher (both) : aes256-ctr (RFC 4344) MAC (both) : hmac-sha2-256 (RFC 6668) compression : none

KEX method and host-key type are negotiated: the server advertises both suites in ssh_kex_set_prefer_rsa() order (default: RSA/DH, hardware-accelerated on ESP32) and picks the first mutually supported one it holds a key for. Cipher / MAC / compression are fixed; the connection is accepted only if the client offers each of those.

Author
Douglas Quigg (dstroy0)
Date
2026

Definition in file ssh_transport.h.

Macro Definition Documentation

◆ SSH_VERSION_MAX

#define SSH_VERSION_MAX   256

Max stored length of an SSH identification string (RFC 4253 §4.2: 255).

Definition at line 48 of file ssh_transport.h.

◆ SSH_SERVER_VERSION

#define SSH_SERVER_VERSION   "SSH-2.0-DetWS_1.0"

Server identification string (no CR LF; appended on the wire).

Definition at line 57 of file ssh_transport.h.

Enumeration Type Documentation

◆ SshPhase

enum class SshPhase : uint8_t
strong

SSH connection lifecycle phase.

Enumerator
SSH_PHASE_BANNER 

Awaiting the client identification string.

SSH_PHASE_KEXINIT 

Awaiting the client KEXINIT.

SSH_PHASE_DH_INIT 

Awaiting SSH_MSG_KEXDH_INIT.

SSH_PHASE_NEWKEYS 

Awaiting SSH_MSG_NEWKEYS.

SSH_PHASE_SERVICE 

Awaiting SERVICE_REQUEST ("ssh-userauth").

SSH_PHASE_AUTH 

User authentication in progress (RFC 4252).

SSH_PHASE_OPEN 

Authenticated; connection/channel protocol active.

Definition at line 64 of file ssh_transport.h.

◆ SshKexAlg

enum class SshKexAlg : uint8_t
strong

SSH transport/session state for one connection (BSS pool).

Holds the handshake phase plus the few values that must persist across messages to compute the exchange hash H: the client and server identification strings (V_C, V_S) and the two KEXINIT payloads (I_C, I_S). The exchange hash from the first KEX is retained as the session id, which is required for key derivation and for every later re-key.

Negotiated key-exchange method (crypto-agnostic KEX dispatch).

Enumerator
SSH_KEX_DH_GROUP14 

diffie-hellman-group14-sha256 (HW-accelerated MPI on ESP32)

SSH_KEX_CURVE25519 

curve25519-sha256 (RFC 8731, X25519)

SSH_KEX_MLKEM768_X25519 

mlkem768x25519-sha256 (PQ/T hybrid, draft-ietf-sshm-mlkem-hybrid-kex)

SSH_KEX_ECDH_NISTP256 

ecdh-sha2-nistp256 (NIST P-256 ECDH, RFC 5656 §4)

Definition at line 89 of file ssh_transport.h.

◆ SshHostkeyAlg

enum class SshHostkeyAlg : uint8_t
strong

Negotiated host-key / signature algorithm.

Enumerator
SSH_HOSTKEY_RSA_SHA256 

rsa-sha2-256 (HW-accelerated on ESP32)

SSH_HOSTKEY_ED25519 

ssh-ed25519 (RFC 8032)

SSH_HOSTKEY_RSA_SHA512 

rsa-sha2-512 (same "ssh-rsa" key, SHA-512 signature; RFC 8332)

SSH_HOSTKEY_ECDSA_NISTP256 

ecdsa-sha2-nistp256 (NIST P-256, RFC 5656)

Definition at line 98 of file ssh_transport.h.

Function Documentation

◆ ssh_transport_init()

void ssh_transport_init ( uint8_t  i)

Reset transport state for slot i to the start of a handshake.

Definition at line 307 of file ssh_transport.cpp.

References MAX_SSH_CONNS, SshSession::phase, SSH_PHASE_BANNER, and ssh_sess.

Referenced by ssh_conn_accept().

◆ ssh_transport_server_banner()

int ssh_transport_server_banner ( uint8_t *  out,
size_t *  out_len,
size_t  cap 
)

Write the server identification string ("SSH-2.0-…\r\n") to out.

Sent verbatim (not inside a binary packet) at connection start, before any KEXINIT. The CR LF is included on the wire but excluded from V_S used in H.

Returns
0 on success, -1 if cap is too small.

Definition at line 320 of file ssh_transport.cpp.

References SSH_SERVER_VERSION.

Referenced by ssh_conn_accept().

◆ ssh_transport_recv_banner()

int ssh_transport_recv_banner ( uint8_t  i,
const uint8_t *  data,
size_t  len,
size_t *  consumed 
)

Feed raw bytes while awaiting the client identification string.

Accumulates bytes until a CR LF (or bare LF) terminates a line beginning with "SSH-". Earlier non-SSH lines (allowed by RFC 4253 §4.2) are skipped. On completion the client version (without CR LF) is stored in v_c.

Parameters
[in]iSSH slot.
[in]dataInbound bytes.
[in]lenNumber of bytes in data.
[out]consumedBytes consumed from data (the banner may be followed immediately by binary packets).
Returns
1 when the banner is complete, 0 if more data is needed, -1 on error.

Definition at line 332 of file ssh_transport.cpp.

References SshSession::banner_buf, SshSession::banner_len, MAX_SSH_CONNS, SshSession::phase, SSH_PHASE_KEXINIT, ssh_sess, SSH_VERSION_MAX, SshSession::v_c, and SshSession::v_c_len.

Referenced by ssh_conn_rx().

◆ ssh_kexinit_build()

int ssh_kexinit_build ( uint8_t  i,
uint8_t *  payload,
size_t *  len,
size_t  cap 
)

Build the server KEXINIT payload for slot i (RFC 4253 §7.1).

Stores a copy in ssh_sess[i].i_s for later exchange-hash computation.

Returns
0 on success, -1 on buffer overflow.

Definition at line 381 of file ssh_transport.cpp.

References SshSession::i_s, SshSession::i_s_len, MAX_SSH_CONNS, SSH_MSG_KEXINIT, ssh_rng_fill(), and ssh_sess.

Referenced by ssh_server_dispatch(), and ssh_transport_begin_rekey().

◆ ssh_kexinit_parse()

int ssh_kexinit_parse ( uint8_t  i,
const uint8_t *  payload,
size_t  len 
)

Parse and negotiate the client KEXINIT payload (RFC 4253 §7.1).

Stores a copy in ssh_sess[i].i_c. Verifies the client offers every algorithm this server supports (one per category).

Returns
0 if negotiation succeeds, -1 if any required algorithm is absent or the payload is malformed.

Definition at line 492 of file ssh_transport.cpp.

References SshSession::cipher_alg, SshSession::ext_info_c, SshSession::hostkey_alg, SshSession::i_c, SshSession::i_c_len, SshSession::kex_alg, SshSession::mac_alg, MAX_SSH_CONNS, SshSession::phase, SSH_CIPHER_AES256CTR, SSH_CIPHER_AES256GCM, SSH_CIPHER_CHACHA20POLY1305, SSH_KEXINIT_MAX, SSH_MAC_HMAC_SHA256, SSH_MAC_HMAC_SHA256_ETM, SSH_MAC_HMAC_SHA512, SSH_MAC_HMAC_SHA512_ETM, SSH_MSG_KEXINIT, SSH_PHASE_DH_INIT, and ssh_sess.

Referenced by ssh_server_dispatch().

◆ ssh_kex_set_prefer_rsa()

void ssh_kex_set_prefer_rsa ( bool  prefer)

Steer KEX / host-key negotiation toward RSA + DH-group14 (default) or toward the modern curve25519 + ed25519 suite.

On ESP32 the RSA/DH path runs on the hardware MPI accelerator, while curve25519 / ed25519 are software; a device that wants the accelerated handshake keeps the default (prefer RSA), while one that wants modern crypto out of the box calls this with false. The server still advertises both suites (for whatever keys it holds), so a client that only supports one still connects - this only sets the server's preference order.

Runtime-selectable so one firmware can flip per deployment. Default: prefer RSA.

Definition at line 86 of file ssh_transport.cpp.

References SshTransportCtx::prefer_rsa.

◆ ssh_kex_prefer_rsa()

bool ssh_kex_prefer_rsa ( void  )

Current negotiation preference (true = prefer RSA/DH, the ESP32-accelerated path).

Definition at line 90 of file ssh_transport.cpp.

References SshTransportCtx::prefer_rsa.

◆ ssh_hostkey_ed25519_set()

void ssh_hostkey_ed25519_set ( const uint8_t  seed[32])

Install an ssh-ed25519 host key from its 32-byte seed (RFC 8032 private key).

Enables the ssh-ed25519 host-key algorithm for negotiation and derives the public key. The RSA host key (loaded via ssh_rsa) and this may both be present; negotiation picks one per ssh_kex_set_prefer_rsa(). If neither is installed the handshake cannot complete.

Definition at line 95 of file ssh_transport.cpp.

References SshTransportCtx::ed_have, SshTransportCtx::ed_pub, SshTransportCtx::ed_seed, and ssh_ed25519_pubkey().

◆ ssh_hostkey_ed25519_available()

bool ssh_hostkey_ed25519_available ( void  )

True if an ssh-ed25519 host key has been installed.

Definition at line 101 of file ssh_transport.cpp.

References SshTransportCtx::ed_have.

◆ ssh_hostkey_ecdsa_set()

void ssh_hostkey_ecdsa_set ( const uint8_t  priv[32])

Install an ecdsa-sha2-nistp256 host key from its 32-byte P-256 private scalar.

Enables the ecdsa-sha2-nistp256 host-key algorithm (RFC 5656) for negotiation and derives the public point. May coexist with the RSA and ssh-ed25519 host keys; negotiation picks one per ssh_kex_set_prefer_rsa(). An invalid scalar (0 or >= the group order) is ignored.

◆ ssh_hostkey_ecdsa_available()

bool ssh_hostkey_ecdsa_available ( void  )

True if an ecdsa-sha2-nistp256 host key has been installed.

Definition at line 113 of file ssh_transport.cpp.

References SshTransportCtx::ecdsa_have.

◆ ssh_kex_generate()

int ssh_kex_generate ( uint8_t  i)

Generate the server ephemeral for the negotiated KEX method (call after parse).

Branches on ssh_sess[i].kex_alg: for diffie-hellman-group14 it delegates to ssh_dh_generate(); for curve25519-sha256 it draws a random X25519 scalar and computes the matching public value into ssh_sess[i].ecdh_sk / ecdh_pk; for ecdh-sha2-nistp256 it draws a random P-256 scalar into ecdh_sk (the 65-byte public point is re-derived when the KEXDH_INIT arrives). Must run after ssh_kexinit_parse() has set kex_alg.

Returns
0 on success, -1 on error.

Definition at line 865 of file ssh_transport.cpp.

References SshSession::kex_alg, MAX_SSH_CONNS, ssh_dh_generate(), ssh_ecdsa_p256_pubkey(), SSH_KEX_CURVE25519, SSH_KEX_ECDH_NISTP256, SSH_KEX_MLKEM768_X25519, ssh_rng_fill(), ssh_sess, and ssh_x25519_base().

Referenced by ssh_server_dispatch(), and ssh_transport_begin_rekey().

◆ ssh_extinfo_build()

int ssh_extinfo_build ( uint8_t *  out,
size_t *  len,
size_t  cap 
)

Build SSH_MSG_EXT_INFO advertising server-sig-algs (RFC 8308).

Tells the client which public-key signature algorithms the server will accept for userauth (rsa-sha2-512, rsa-sha2-256, ssh-ed25519); without it a modern OpenSSH client refuses to sign an RSA key ("no mutual signature algorithm"). Sent once, right after NEWKEYS, when the client advertised ext-info-c.

Returns
0 on success, -1 on buffer overflow.

Definition at line 585 of file ssh_transport.cpp.

References SshTransportCtx::prefer_rsa, and SSH_MSG_EXT_INFO.

Referenced by ssh_server_dispatch().

◆ ssh_kex_exchange_hash()

int ssh_kex_exchange_hash ( uint8_t  i,
const uint8_t *  e_be,
const uint8_t *  f_be,
const uint8_t *  k_be,
const uint8_t *  ks,
size_t  ks_len,
uint8_t  out[SSH_SHA256_DIGEST_LEN] 
)

Compute the SSH exchange hash H (RFC 4253 §8).

H = SHA256( string(V_C) || string(V_S) || string(I_C) || string(I_S) || string(K_S) || mpint(e) || mpint(f) || mpint(K) )

V_C/V_S/I_C/I_S are taken from ssh_sess[i]; the rest are supplied. The 256-byte big-endian integers are re-encoded as SSH mpints (minimal length, leading 0x00 when the high bit is set).

Parameters
[in]iSSH slot.
[in]e_beClient DH public value e (256-byte big-endian).
[in]f_beServer DH public value f (256-byte big-endian).
[in]k_beShared secret K (256-byte big-endian).
[in]ksServer host-key blob K_S.
[in]ks_lenLength of ks.
[out]out32-byte exchange hash.
Returns
0 on success, -1 on bad slot.

Definition at line 690 of file ssh_transport.cpp.

◆ ssh_kexdh_parse_init()

int ssh_kexdh_parse_init ( const uint8_t *  payload,
size_t  len,
uint8_t  e_be[256] 
)

Parse SSH_MSG_KEXDH_INIT, extracting the client DH value e.

Payload: byte(30) || mpint(e). The mpint is normalized into a fixed 256-byte big-endian buffer (leading sign/zero bytes stripped, right-aligned).

Parameters
[in]payloadKEXDH_INIT payload.
[in]lenPayload length.
[out]e_be256-byte big-endian client public value.
Returns
0 on success, -1 if malformed or e exceeds 2048 bits.

Definition at line 700 of file ssh_transport.cpp.

References SSH_MSG_KEXDH_INIT.

Referenced by ssh_kexdh_handle().

◆ ssh_kexdh_build_reply()

int ssh_kexdh_build_reply ( const uint8_t *  ks,
size_t  ks_len,
const uint8_t *  f_be,
const uint8_t *  sig,
size_t  sig_len,
uint8_t *  out,
size_t *  out_len,
size_t  cap 
)

Build SSH_MSG_KEXDH_REPLY (RFC 4253 §8, RFC 8332 §3).

Payload: byte(31) || string(K_S) || mpint(f) || string(signature), where the signature blob is string("rsa-sha2-256") || string(sig).

Parameters
[in]ksServer host-key blob K_S.
[in]ks_lenLength of ks.
[in]f_beServer DH public value f (256-byte big-endian).
[in]sigRaw RSA signature over the exchange hash H.
[in]sig_lenLength of sig (256 for RSA-2048).
[out]outOutput payload buffer.
[out]out_lenBytes written.
[in]capCapacity of out.
Returns
0 on success, -1 on overflow.

Definition at line 723 of file ssh_transport.cpp.

References SSH_MSG_KEXDH_REPLY.

◆ ssh_kexdh_handle()

int ssh_kexdh_handle ( uint8_t  i,
const uint8_t *  payload,
size_t  len,
uint8_t *  reply_out,
size_t *  reply_len,
size_t  cap 
)

Handle KEXDH/ECDH_INIT (msg 30) end-to-end and produce the reply payload.

Branches on the negotiated KEX method (ssh_sess[i].kex_alg): computes the shared secret K = e^y mod p (DH-group14) or K = X25519(sk, Q_C) (curve25519), builds the method-correct exchange hash H (e/f as mpints for DH, Q_C/Q_S as strings for curve), signs H with the negotiated host key (rsa-sha2-512/256 or ssh-ed25519), assembles SSH_MSG_KEXDH_REPLY, and derives the six session keys (installed into ssh_keys[i]; encryption is not activated until NEWKEYS - see ssh_newkeys_complete()). On the first KEX the exchange hash is saved as the session id. K is wiped from the stack before returning.

Requires ssh_kex_generate(i) and a host key (ssh_rsa_load_pubkey() and/or ssh_hostkey_ed25519_set()) to have been called.

Parameters
[in]iSSH slot.
[in]payloadKEXDH_INIT payload.
[in]lenPayload length.
[out]reply_outKEXDH_REPLY payload buffer.
[out]reply_lenBytes written to reply_out.
[in]capCapacity of reply_out.
Returns
0 on success, -1 on validation/crypto/buffer error.

Definition at line 947 of file ssh_transport.cpp.

References bn_dh_validate(), bn_expmod_group14(), bn_from_bytes(), bn_to_bytes(), SshSession::cipher_alg, SshSession::ecdh_pk, SshSession::ecdh_sk, SshSession::have_session_id, SshSession::kex_alg, SshSession::mac_alg, MAX_SSH_CONNS, SshSession::phase, SshSession::session_id, ssh_dh, ssh_dh_derive_keys_sid(), ssh_ecdsa_p256_ecdh(), ssh_ecdsa_p256_pubkey(), SSH_KEX_CURVE25519, SSH_KEX_ECDH_NISTP256, SSH_KEX_MLKEM768_X25519, ssh_kexdh_parse_init(), SSH_PHASE_NEWKEYS, SSH_RSA_PUBKEY_BLOB_MAX, SSH_RSA_SIG_BYTES, ssh_sess, SSH_SHA256_DIGEST_LEN, and ssh_x25519().

Referenced by ssh_server_dispatch().

◆ ssh_newkeys_sent()

void ssh_newkeys_sent ( uint8_t  i)

Activate the outbound direction after emitting our SSH_MSG_NEWKEYS.

Call this right after sending the server's NEWKEYS: it turns on the outbound cipher/MAC (enc_out) and starts the s2c compression stream. Per RFC 4253 sec 7.3 each direction activates independently, so the outbound turns on when we send, not when the peer's NEWKEYS arrives.

Definition at line 1093 of file ssh_transport.cpp.

References SshPacketState::enc_out, MAX_SSH_CONNS, and ssh_pkt.

Referenced by ssh_server_dispatch().

◆ ssh_newkeys_complete()

void ssh_newkeys_complete ( uint8_t  i)

Complete the NEWKEYS exchange: activate the inbound direction and advance phase.

Called once the client's SSH_MSG_NEWKEYS has been received (the server having already sent its own, via ssh_newkeys_sent()). Turns on the inbound cipher/MAC (enc_in), clears kex_active, and moves to SshPhase::SSH_PHASE_SERVICE (or back to SshPhase::SSH_PHASE_OPEN on a re-key).

Definition at line 1105 of file ssh_transport.cpp.

References SshSession::authed, detws_millis(), SshPacketState::enc_in, SshPacketState::kex_active, SshSession::last_kex_ms, MAX_SSH_CONNS, SshSession::phase, SSH_PHASE_OPEN, SSH_PHASE_SERVICE, ssh_pkt, and ssh_sess.

Referenced by ssh_server_dispatch().

◆ ssh_rekey_needed()

bool ssh_rekey_needed ( uint8_t  i)

True if slot i has reached the re-key threshold (RFC 4253 §9).

Checks both packet sequence numbers against SSH_REKEY_PACKET_THRESHOLD.

Definition at line 1120 of file ssh_transport.cpp.

References MAX_SSH_CONNS, SshPacketState::seq_no_recv, SshPacketState::seq_no_send, ssh_pkt, and SSH_REKEY_PACKET_THRESHOLD.

◆ ssh_rekey_due()

bool ssh_rekey_due ( uint32_t  seq_send,
uint32_t  seq_recv,
uint32_t  elapsed_ms,
uint32_t  pkt_threshold,
uint32_t  time_threshold_ms 
)

Pure re-key decision (RFC 4253 §9: "after each gigabyte ... or after each hour").

Parameters
seq_send/
seq_recvthe outbound / inbound packet counters (a data-volume proxy).
elapsed_msmilliseconds since the last KEX completed.
pkt_thresholdthe packet-count trigger (SSH_REKEY_PACKET_THRESHOLD).
time_threshold_msthe elapsed-time trigger (SSH_REKEY_TIME_MS); 0 disables the time trigger.
Returns
true if either a packet counter or the elapsed time has crossed its threshold.

Definition at line 1127 of file ssh_transport.cpp.

Referenced by ssh_conn_poll().

◆ ssh_transport_begin_rekey()

int ssh_transport_begin_rekey ( uint8_t  i,
uint8_t *  out,
size_t *  out_len,
size_t  cap 
)

Begin a server-initiated re-key by emitting a fresh KEXINIT.

Generates a new ephemeral DH key pair, builds and stores a new server KEXINIT (I_S), and returns the transport to SshPhase::SSH_PHASE_KEXINIT. The session id and authentication state are preserved, so once the re-key completes the connection resumes in its prior (authenticated) phase.

Parameters
[in]iConnection slot index.
[out]outKEXINIT payload to send.
[out]out_lenBytes written.
[in]capCapacity of out.
Returns
0 on success, -1 on error.

Definition at line 1137 of file ssh_transport.cpp.

References MAX_SSH_CONNS, SshSession::phase, ssh_kex_generate(), ssh_kexinit_build(), SSH_PHASE_KEXINIT, and ssh_sess.

Referenced by ssh_conn_poll().

Variable Documentation

◆ ssh_sess