|
ProtoCore v1.0.16
Deterministic, zero-heap network stack for embedded targets
|
Root infrastructure: fixed widths, serializers, opcodes and sizes, for every layer above. More...
#include "cellularum_laboro/cellularum_laboro.h"#include "crypto/aead/chachapoly/chachapoly.h"#include "crypto/asymmetric/bignum/bignum.h"#include "crypto/cipher/aes256ctr/aes256ctr.h"#include "crypto/mac/hmac_sha256/hmac_sha256.h"#include "crypto/pqc/sntrup761/sntrup761.h"#include "memoria_operor/memoria_operor.h"#include "network_drivers/presentation/ssh/transport/ssh_kexhash/ssh_kexhash.h"#include "octetus_introitus_exitus/octetus_introitus_exitus.h"#include "protocore_config.h"Go to the source code of this file.
Classes | |
| struct | Rd |
Macros | |
| #define | SSH_VERSION_MAX 256 |
| Max stored length of an SSH identification string (RFC 4253 sec 4.2: 255). | |
| #define | SSH_VERSION_CONTENT_MAX 253 |
| Longest identification string RFC 4253 sec 4.2 admits: 255 on the wire, CR and LF counted. | |
| #define | PROTOCORE_SSH_KEXINIT_S_MAX 704 |
| Max stored size of our own KEXINIT (I_S). Sized for the full advertised suite: the kex list (mlkem + dh + ecdsa-nistp256 + curve25519 x2 + ext-info-s), all three host-key types, the cipher (chacha + 2x aes) and MAC (2x aes + 2x plain) lists, and zlib s2c compression (worst case ~580 bytes; 704 leaves headroom for future algorithm additions). | |
| #define | PROTOCORE_SSH_I_C_MAX SSH_KEXINIT_MAX |
| Capacity of I_C and I_S. A buffer takes the peer bound in the role that receives into it, our own bound in the role that writes it. | |
| #define | PROTOCORE_SSH_I_S_MAX PROTOCORE_SSH_KEXINIT_S_MAX |
| #define | SSH_SERVER_VERSION "SSH-2.0-1.0" |
| Server identification string (no CR LF; appended on the wire). | |
| #define | SSH_CLIENT_VERSION "SSH-2.0-PROTOCORE_client_1.0" |
| Client identification string (no CR LF; appended on the wire). | |
| #define | SSH_OFF_GCM_C2S 0u |
| The connection's memory map: every byte it uses, at a named offset from its slot base. | |
| #define | SSH_OFF_GCM_S2C (SSH_OFF_GCM_C2S + PROTOCORE_AESGCM_BORROW) |
| #define | SSH_OFF_CHACHA_C2S (SSH_OFF_GCM_S2C + PROTOCORE_AESGCM_BORROW) |
| #define | SSH_OFF_CHACHA_S2C (SSH_OFF_CHACHA_C2S + PROTOCORE_CHACHAPOLY_KEY_LEN) |
| #define | SSH_OFF_MAC_C2S (SSH_OFF_CHACHA_S2C + PROTOCORE_CHACHAPOLY_KEY_LEN) |
| #define | SSH_OFF_MAC_S2C (SSH_OFF_MAC_C2S + 64u) |
| #define | SSH_OFF_AES_KEY_C2S (SSH_OFF_MAC_S2C + 64u) |
| #define | SSH_OFF_AES_KEY_S2C (SSH_OFF_AES_KEY_C2S + PROTOCORE_AES256CTR_KEY_LEN) |
| #define | SSH_OFF_AES_IV_C2S (SSH_OFF_AES_KEY_S2C + PROTOCORE_AES256CTR_KEY_LEN) |
| #define | SSH_OFF_AES_IV_S2C (SSH_OFF_AES_IV_C2S + PROTOCORE_AES256CTR_CTR_LEN) |
| #define | SSH_EPOCH_STRIDE (SSH_OFF_AES_IV_S2C + PROTOCORE_AES256CTR_CTR_LEN) |
| #define | SSH_OFF_WIRE 0u |
| #define | SSH_OFF_V_C (SSH_OFF_WIRE + SSH_WIRE_CAP) |
| #define | SSH_OFF_V_S (SSH_OFF_V_C + SSH_VERSION_MAX) |
| #define | SSH_OFF_SESSION_ID (SSH_OFF_V_S + SSH_VERSION_MAX) |
| #define | SSH_OFF_EPOCH_0 (SSH_OFF_SESSION_ID + SSH_KEXHASH_MAX_LEN) |
| #define | SSH_OFF_EPOCH_1 (SSH_OFF_EPOCH_0 + SSH_EPOCH_STRIDE) |
| #define | SSH_SESSION_END (SSH_OFF_EPOCH_1 + SSH_EPOCH_STRIDE) |
| #define | SSH_OFF_IDENT SSH_SESSION_END |
| #define | SSH_OFF_I_C (SSH_OFF_IDENT + SSH_VERSION_MAX) |
| #define | SSH_OFF_I_S (SSH_OFF_I_C + PROTOCORE_SSH_I_C_MAX) |
| #define | SSH_OFF_KEXINIT (SSH_OFF_I_S + PROTOCORE_SSH_I_S_MAX) |
| #define | SSH_OFF_CPUB (SSH_OFF_KEXINIT + PROTOCORE_SSH_KEXINIT_S_MAX) |
| #define | SSH_OFF_DH_Y (SSH_OFF_CPUB + PROTOCORE_SSH_CPUB_MAX) |
| #define | SSH_OFF_DH_F (SSH_OFF_DH_Y + sizeof(protocore_bignum)) |
| #define | SSH_OFF_DH_K (SSH_OFF_DH_F + sizeof(protocore_bignum)) |
| #define | SSH_OFF_ECDH_SK (SSH_OFF_DH_K + sizeof(protocore_bignum)) |
| #define | SSH_OFF_ECDH_PK (SSH_OFF_ECDH_SK + 32u) |
| #define | SSH_ECDH_PAIR_LEN 64u |
| The ECDH ephemeral pair, private then public: what one wipe covers. | |
| #define | SSH_OFF_CRYPTO_WORK (SSH_OFF_ECDH_PK + 32u) |
| #define | SSH_EXCHANGE_END (SSH_OFF_CRYPTO_WORK + PROTOCORE_CRYPTO_BORROW_MAX) |
| #define | SSH_OFF_MAC_WORK SSH_EXCHANGE_END |
| #define | SSH_OFF_CIPHER_WORK (SSH_OFF_MAC_WORK + PROTOCORE_HMAC_SHA256_BORROW) |
| #define | SSH_CIPHER_WORK_LEN PROTOCORE_AES256CTR_BORROW |
| #define | SSH_PACKET_END (SSH_OFF_CIPHER_WORK + SSH_CIPHER_WORK_LEN) |
| #define | SSH_OFF_RX_READ SSH_PACKET_END |
| #define | SSH_OFF_RX_ASM (SSH_OFF_RX_READ + RX_BUF_SIZE) |
| #define | SSH_RX_ASM_CAP ((size_t)SSH_RFC_MAX_PAYLOAD) |
| Capacity of the reassembly region at SSH_OFF_RX_ASM: what rx_buf actually spans. | |
| #define | SSH_SLOT_BORROW (SSH_OFF_RX_ASM + SSH_RX_ASM_CAP) |
| One connection's whole span, and the stride between slots. | |
| #define | SSH_SESSION_SIZE (SSH_SESSION_END - SSH_OFF_V_C) |
| #define | SSH_EXCHANGE_SIZE (SSH_EXCHANGE_END - SSH_OFF_IDENT) |
| #define | SSH_PACKET_SIZE (SSH_PACKET_END - SSH_OFF_MAC_WORK) |
| #define | SSH_RX_SIZE (SSH_SLOT_BORROW - SSH_OFF_RX_READ) |
| #define | SSH_SEQ_CLOSE_THRESHOLD 0xFFFFFFF0u |
| Close the connection when seq_no reaches this value. | |
| #define | SSH_MAX_EFFECTIVE_PAYLOAD (SSH_RFC_MAX_PAYLOAD) |
| #define | SSH_MAX_PAD 32 |
| #define | SSH_MAX_MAC 64 |
| #define | SSH_PKT_WIRE_MAX ((size_t)(4 + 1 + SSH_MAX_EFFECTIVE_PAYLOAD + SSH_MAX_PAD + SSH_MAX_MAC)) |
| #define | SSH_RFC_MAX_PAYLOAD 32768u |
| Uncompressed payload RFC 4253 sec 6.1 requires an implementation to process. | |
| #define | SSH_RFC_MAX_PACKET 35000u |
| Largest total packet RFC 4253 sec 6.1 requires an implementation to process. | |
| #define | SSH_WIRE_CAP ((size_t)131072u) |
| #define | PROTOCORE_PLAINTEXT_WORK_SSH_TRANSPORT ((size_t)(SSH_PKT_BUF_SIZE + 64)) |
| #define | SSH_WIRE_PAYLOAD_OFF 5 |
| Where a payload sits inside a wire buffer: past packet_length and padding_length. | |
Typedefs | |
| typedef PROTOCORE_BEGIN_DECLS enum PROTO_ENUM_PACKED | SshMsgId |
| Protocol opcodes, by the number each RFC assigns it (RFC 4250 sec 4.1.2). | |
| typedef enum PROTO_ENUM_PACKED | SshDisconnectReason |
| Disconnect reason codes (RFC 4253 sec 11.1, numbered by RFC 4250 sec 4.2.2). | |
| typedef enum PROTO_ENUM_PACKED | SshOpenFailureReason |
| Channel open failure reason codes (RFC 4254 sec 5.1). | |
Functions | |
| PROTOCORE_INLINE void | protocore_ssh_wr_str (mmgr_span *w, const void *data, size_t n) |
Append a string: uint32 length, then n bytes of data. | |
| PROTOCORE_INLINE void | protocore_ssh_wr_cstr (mmgr_span *w, const char *s) |
Append a NUL-terminated s as a string, its length taken up to the span's capacity. | |
| PROTOCORE_INLINE void | protocore_ssh_wr_mpint (mmgr_span *w, const uint8_t *be, size_t len) |
Append len big-endian bytes as an mpint: leading zero bytes stripped, a 0x00 prepended when the top bit is set, and a zero value written as the empty string. | |
| PROTOCORE_INLINE uint8_t | protocore_ssh_rd_u8 (Rd *r) |
| PROTOCORE_INLINE uint32_t | protocore_ssh_rd_u32 (Rd *r) |
| PROTOCORE_INLINE const uint8_t * | protocore_ssh_rd_string (Rd *r, uint32_t *n) |
Root infrastructure: fixed widths, serializers, opcodes and sizes, for every layer above.
Definition in file common.h.
| #define SSH_VERSION_MAX 256 |
| #define SSH_VERSION_CONTENT_MAX 253 |
| #define PROTOCORE_SSH_KEXINIT_S_MAX 704 |
Max stored size of our own KEXINIT (I_S). Sized for the full advertised suite: the kex list (mlkem + dh + ecdsa-nistp256 + curve25519 x2 + ext-info-s), all three host-key types, the cipher (chacha + 2x aes) and MAC (2x aes + 2x plain) lists, and zlib s2c compression (worst case ~580 bytes; 704 leaves headroom for future algorithm additions).
| #define PROTOCORE_SSH_I_C_MAX SSH_KEXINIT_MAX |
| #define PROTOCORE_SSH_I_S_MAX PROTOCORE_SSH_KEXINIT_S_MAX |
| #define SSH_SERVER_VERSION "SSH-2.0-1.0" |
| #define SSH_CLIENT_VERSION "SSH-2.0-PROTOCORE_client_1.0" |
| #define SSH_OFF_GCM_C2S 0u |
The connection's memory map: every byte it uses, at a named offset from its slot base.
Laid out kmt | constants | control packet | data packet, each offset the previous one plus that member's size. The storage is ssh.c's; a translation unit takes its pointer as ssh_conn_slot(i) + the offset and already knows the member's size.
| #define SSH_OFF_GCM_S2C (SSH_OFF_GCM_C2S + PROTOCORE_AESGCM_BORROW) |
| #define SSH_OFF_CHACHA_C2S (SSH_OFF_GCM_S2C + PROTOCORE_AESGCM_BORROW) |
| #define SSH_OFF_CHACHA_S2C (SSH_OFF_CHACHA_C2S + PROTOCORE_CHACHAPOLY_KEY_LEN) |
| #define SSH_OFF_MAC_C2S (SSH_OFF_CHACHA_S2C + PROTOCORE_CHACHAPOLY_KEY_LEN) |
| #define SSH_OFF_MAC_S2C (SSH_OFF_MAC_C2S + 64u) |
| #define SSH_OFF_AES_KEY_C2S (SSH_OFF_MAC_S2C + 64u) |
| #define SSH_OFF_AES_KEY_S2C (SSH_OFF_AES_KEY_C2S + PROTOCORE_AES256CTR_KEY_LEN) |
| #define SSH_OFF_AES_IV_C2S (SSH_OFF_AES_KEY_S2C + PROTOCORE_AES256CTR_KEY_LEN) |
| #define SSH_OFF_AES_IV_S2C (SSH_OFF_AES_IV_C2S + PROTOCORE_AES256CTR_CTR_LEN) |
| #define SSH_EPOCH_STRIDE (SSH_OFF_AES_IV_S2C + PROTOCORE_AES256CTR_CTR_LEN) |
| #define SSH_OFF_V_C (SSH_OFF_WIRE + SSH_WIRE_CAP) |
| #define SSH_OFF_V_S (SSH_OFF_V_C + SSH_VERSION_MAX) |
| #define SSH_OFF_SESSION_ID (SSH_OFF_V_S + SSH_VERSION_MAX) |
| #define SSH_OFF_EPOCH_0 (SSH_OFF_SESSION_ID + SSH_KEXHASH_MAX_LEN) |
| #define SSH_OFF_EPOCH_1 (SSH_OFF_EPOCH_0 + SSH_EPOCH_STRIDE) |
| #define SSH_SESSION_END (SSH_OFF_EPOCH_1 + SSH_EPOCH_STRIDE) |
| #define SSH_OFF_IDENT SSH_SESSION_END |
| #define SSH_OFF_I_C (SSH_OFF_IDENT + SSH_VERSION_MAX) |
| #define SSH_OFF_I_S (SSH_OFF_I_C + PROTOCORE_SSH_I_C_MAX) |
| #define SSH_OFF_KEXINIT (SSH_OFF_I_S + PROTOCORE_SSH_I_S_MAX) |
| #define SSH_OFF_CPUB (SSH_OFF_KEXINIT + PROTOCORE_SSH_KEXINIT_S_MAX) |
| #define SSH_OFF_DH_Y (SSH_OFF_CPUB + PROTOCORE_SSH_CPUB_MAX) |
| #define SSH_OFF_DH_F (SSH_OFF_DH_Y + sizeof(protocore_bignum)) |
| #define SSH_OFF_DH_K (SSH_OFF_DH_F + sizeof(protocore_bignum)) |
| #define SSH_OFF_ECDH_SK (SSH_OFF_DH_K + sizeof(protocore_bignum)) |
| #define SSH_OFF_ECDH_PK (SSH_OFF_ECDH_SK + 32u) |
| #define SSH_ECDH_PAIR_LEN 64u |
| #define SSH_OFF_CRYPTO_WORK (SSH_OFF_ECDH_PK + 32u) |
| #define SSH_EXCHANGE_END (SSH_OFF_CRYPTO_WORK + PROTOCORE_CRYPTO_BORROW_MAX) |
| #define SSH_OFF_MAC_WORK SSH_EXCHANGE_END |
| #define SSH_OFF_CIPHER_WORK (SSH_OFF_MAC_WORK + PROTOCORE_HMAC_SHA256_BORROW) |
| #define SSH_CIPHER_WORK_LEN PROTOCORE_AES256CTR_BORROW |
| #define SSH_PACKET_END (SSH_OFF_CIPHER_WORK + SSH_CIPHER_WORK_LEN) |
| #define SSH_OFF_RX_READ SSH_PACKET_END |
| #define SSH_OFF_RX_ASM (SSH_OFF_RX_READ + RX_BUF_SIZE) |
| #define SSH_RX_ASM_CAP ((size_t)SSH_RFC_MAX_PAYLOAD) |
| #define SSH_SLOT_BORROW (SSH_OFF_RX_ASM + SSH_RX_ASM_CAP) |
| #define SSH_SESSION_SIZE (SSH_SESSION_END - SSH_OFF_V_C) |
| #define SSH_EXCHANGE_SIZE (SSH_EXCHANGE_END - SSH_OFF_IDENT) |
| #define SSH_PACKET_SIZE (SSH_PACKET_END - SSH_OFF_MAC_WORK) |
| #define SSH_RX_SIZE (SSH_SLOT_BORROW - SSH_OFF_RX_READ) |
| #define SSH_SEQ_CLOSE_THRESHOLD 0xFFFFFFF0u |
Close the connection when seq_no reaches this value.
Set to 0xFFFFFFF0 (16 below the 32-bit wrap) as a conservative margin. This prevents CTR keystream reuse that would occur at wrap. The counter is never reset; a re-key at SSH_REKEY_PACKET_THRESHOLD keeps it far from here.
| #define SSH_MAX_EFFECTIVE_PAYLOAD (SSH_RFC_MAX_PAYLOAD) |
| #define SSH_PKT_WIRE_MAX ((size_t)(4 + 1 + SSH_MAX_EFFECTIVE_PAYLOAD + SSH_MAX_PAD + SSH_MAX_MAC)) |
| #define SSH_RFC_MAX_PAYLOAD 32768u |
Uncompressed payload RFC 4253 sec 6.1 requires an implementation to process.
"All implementations MUST be able to process packets with an uncompressed payload length of 32768 bytes or less". This tree sizes its own spans on this rather than on SSH_PKT_BUF_SIZE, which the pre-move tree still shares.
| #define SSH_RFC_MAX_PACKET 35000u |
| #define PROTOCORE_PLAINTEXT_WORK_SSH_TRANSPORT ((size_t)(SSH_PKT_BUF_SIZE + 64)) |
| #define SSH_WIRE_PAYLOAD_OFF 5 |
Where a payload sits inside a wire buffer: past packet_length and padding_length.
Every cipher mode lays those two fields down ahead of the payload and encrypts from there, so a caller that writes its message at this offset hands ssh_pkt_send_at() a packet the framer never has to move. A pipe (forwarding, a channel data pump) reads its source straight into that slot and the bytes are copied once, into the packet they leave in.
| typedef PROTOCORE_BEGIN_DECLS enum PROTO_ENUM_PACKED SshMsgId |
Protocol opcodes, by the number each RFC assigns it (RFC 4250 sec 4.1.2).
| typedef enum PROTO_ENUM_PACKED SshDisconnectReason |
Disconnect reason codes (RFC 4253 sec 11.1, numbered by RFC 4250 sec 4.2.2).
| typedef enum PROTO_ENUM_PACKED SshOpenFailureReason |
Channel open failure reason codes (RFC 4254 sec 5.1).
| enum PROTO_ENUM_PACKED |
Protocol opcodes, by the number each RFC assigns it (RFC 4250 sec 4.1.2).
| enum PROTO_ENUM_PACKED |
Disconnect reason codes (RFC 4253 sec 11.1, numbered by RFC 4250 sec 4.2.2).
| enum PROTO_ENUM_PACKED |
Channel open failure reason codes (RFC 4254 sec 5.1).
| PROTOCORE_INLINE void protocore_ssh_wr_str | ( | mmgr_span * | w, |
| const void * | data, | ||
| size_t | n | ||
| ) |
Append a string: uint32 length, then n bytes of data.
Definition at line 253 of file common.h.
Referenced by protocore_ssh_wr_cstr().
| PROTOCORE_INLINE void protocore_ssh_wr_cstr | ( | mmgr_span * | w, |
| const char * | s | ||
| ) |
Append a NUL-terminated s as a string, its length taken up to the span's capacity.
A comma-separated name-list (RFC 4253 sec 7.1) is one of these.
Definition at line 264 of file common.h.
References protocore_ssh_wr_str().
| PROTOCORE_INLINE void protocore_ssh_wr_mpint | ( | mmgr_span * | w, |
| const uint8_t * | be, | ||
| size_t | len | ||
| ) |
| PROTOCORE_INLINE uint8_t protocore_ssh_rd_u8 | ( | Rd * | r | ) |
| PROTOCORE_INLINE uint32_t protocore_ssh_rd_u32 | ( | Rd * | r | ) |
| PROTOCORE_INLINE const uint8_t * protocore_ssh_rd_string | ( | Rd * | r, |
| uint32_t * | n | ||
| ) |