kernel/net/ssh/, plus a userland ssh client app); the "Appendix B: Algorithm Identifier Strings" list further down is this plan's proposed superset, not a confirmed list of what was implemented. What the server side actually speaks, verified against the source: key exchange curve25519-sha256 / [email protected] only (no Diffie-Hellman group fallback); host key ssh-ed25519 (Ed25519) and rsa-sha2-256 (explicitly not rsa-sha2-512); cipher aes256-ctr. Treat the rest of Appendix B as aspirational unless confirmed elsewhere.SSH Implementation Plan for MayteraOS
Document Version: 1.0 Date: 2026-01-25 Status: Planning
Table of Contents
- Executive Summary
- Options Analysis
- Requirements
- Implementation Phases
- Dependencies
- Security Considerations
- Testing Strategy
- Resource Estimates
- References
Executive Summary
This document outlines a comprehensive plan for implementing SSH (Secure Shell) client and server functionality in MayteraOS. SSH will enable secure remote login, command execution, and file transfer capabilities, making the OS suitable for networked environments and remote use.
Current State
MayteraOS has a functional network stack including:
- Network Drivers: E1000 Ethernet is the driver actually in use. A VirtIO-net driver exists in the tree and compiles and links, but
virtio_subsystem_init()has no caller anywhere in the kernel as of this writing, so no VirtIO device is initialized at boot; treat it as present-but-dormant, not active. - Protocol Stack: Ethernet, IP, ICMP, ARP, UDP, and TCP
- TCP Implementation: Full state machine with socket-like API (
tcp_socket,tcp_connect,tcp_send,tcp_recv,tcp_close) - Terminal: XTerm-compatible GUI terminal with ANSI escape sequence support (80x25, 16 colors)
- No Crypto: At the time of writing, no cryptographic primitives implemented
Goals
- Implement SSH client to connect to external SSH servers
- Implement SSH server to accept incoming SSH connections
- Support secure file transfer (SCP/SFTP)
- Enable port forwarding capabilities
Options Analysis
Option A: Port Dropbear SSH
Overview: Dropbear is a small SSH server and client implementation designed for embedded and resource-constrained environments. First released in 2003, it is actively maintained with the latest version 2025.88 (May 2025).
Architecture:
dropbear/
src/ # Main SSH implementation
libtomcrypt/ # Embedded crypto library
libtommath/ # Big number mathematics
manpages/ # Documentation
test/ # Test suite
fuzz/ # Fuzzing infrastructure
Pros:
- Mature, well-tested codebase (~20 years of development)
- Self-contained: includes LibTomCrypt and LibTomMath internally
- Small binary size (~110KB statically linked with minimal options)
- Supports both client (
dbclient) and server (dropbear) - Active development with modern cipher support (ChaCha20-Poly1305, Ed25519)
- Post-quantum key exchange support (sntrup761, ML-KEM) as of 2025
- Multi-purpose binary capability (single executable for all functions)
- BSD license compatible
Cons:
- Still relatively large for a bare-metal OS (~50-100 KLOC)
- Assumes POSIX environment (needs significant adaptation)
- Complex porting effort for PTY, process management, filesystem
- Heavy use of standard C library features
Porting Effort: HIGH (3-6 months)
Option B: Port TinySSH
Overview: TinySSH is a minimalistic SSH server using NaCl/TweetNaCl cryptography. It focuses on modern, auditable code with less than 100,000 words of source.
Key Features:
- Statically allocated memory (< 1MB total)
- Modern crypto only: Ed25519, Curve25519, ChaCha20-Poly1305
- No dynamic memory allocation
- systemd integration (on-demand startup)
Supported Algorithms:
- Host key:
ssh-ed25519 - Key exchange:
curve25519-sha256 - Cipher:
[email protected] - Authentication: Public key only (no password auth)
Pros:
- Smallest footprint of all options
- Auditable codebase
- No legacy crypto (more secure by design)
- Static memory allocation suits bare-metal
- Simple configuration ("can't be misconfigured")
Cons:
- Server only (no client implementation)
- No password authentication
- No SCP/SFTP support
- Limited algorithm support (no RSA, no AES)
- Less actively maintained than Dropbear
- Still assumes POSIX environment
Porting Effort: MEDIUM (2-4 months)
Option C: Custom Implementation Based on RFC 4253
Overview: Build SSH implementation from scratch following the SSH protocol RFCs. This approach provides maximum control and optimization for MayteraOS.
Relevant RFCs:
- RFC 4250: SSH Protocol Assigned Numbers
- RFC 4251: SSH Protocol Architecture
- RFC 4252: SSH Authentication Protocol
- RFC 4253: SSH Transport Layer Protocol
- RFC 4254: SSH Connection Protocol
- RFC 4256: Generic Message Exchange Authentication (keyboard-interactive)
- RFC 4419: Diffie-Hellman Group Exchange
- RFC 8332: Use of RSA Keys with SHA-256 and SHA-512
- RFC 8709: Ed25519 and Ed448 Public Key Algorithms
Protocol Layers:
+------------------------+
| Application Layer | - Interactive shell, command execution
+------------------------+
| Connection Layer | - Channels, multiplexing (RFC 4254)
+------------------------+
| Authentication Layer | - Password, public key (RFC 4252)
+------------------------+
| Transport Layer | - Encryption, integrity, key exchange (RFC 4253)
+------------------------+
| TCP | - Already implemented in MayteraOS
+------------------------+
Pros:
- Full control over implementation
- Can optimize for MayteraOS architecture
- No POSIX dependencies to port
- Better integration with existing terminal and network stack
- Educational value for OS development
- Can implement exactly what's needed, nothing more
Cons:
- Most development effort required
- Risk of security vulnerabilities in crypto implementation
- Longer time to first working version
- Need to implement/port cryptographic primitives separately
- Interoperability testing more challenging
Porting Effort: HIGH (6-12 months for full implementation)
Recommendation: Hybrid Approach
Primary Strategy: Custom Implementation with Ported Crypto Libraries
The recommended approach is a hybrid:
- Crypto Layer: Port LibTomCrypt + LibTomMath from Dropbear
- These are well-tested, standalone libraries
- Minimal POSIX dependencies
- Provide all needed cryptographic primitives
- SSH Protocol: Custom implementation following RFCs
- Tailored to MayteraOS architecture
- Integrates with existing TCP stack
- Integrates with existing terminal implementation
- Avoids POSIX porting complexity
- Algorithm Selection: Start with TinySSH's minimal set
- Ed25519 for host keys and authentication
- Curve25519-SHA256 for key exchange
- ChaCha20-Poly1305 for encryption
- Add AES-256-GCM and RSA-SHA256 later for compatibility
Justification:
- Lower risk than full crypto implementation from scratch
- More maintainable than porting full SSH implementations
- Natural integration with MayteraOS components
- Clear separation of concerns (crypto vs. protocol)
- Can leverage existing terminal's ANSI support
Requirements
3.1 Cryptographic Requirements
3.1.1 Required Primitives
| Category | Algorithm | Priority | Use Case |
|---|---|---|---|
| Hash Functions | SHA-256 | Required | Key derivation, signatures |
| SHA-512 | Required | Ed25519 signatures | |
| SHA-1 | Optional | Legacy compatibility only | |
| Symmetric Encryption | ChaCha20-Poly1305 | Required | Preferred cipher |
| AES-256-GCM | High | Compatibility | |
| AES-256-CTR + HMAC-SHA2 | Medium | Fallback | |
| Asymmetric Crypto | Ed25519 | Required | Modern signatures |
| Curve25519 | Required | ECDH key exchange | |
| RSA (2048-4096 bit) | Medium | Compatibility | |
| Key Exchange | curve25519-sha256 | Required | Modern ECDH |
| diffie-hellman-group14-sha256 | Medium | Compatibility | |
| diffie-hellman-group16-sha512 | Low | High security | |
| Random Numbers | CSPRNG | Required | Key generation, nonces |
3.1.2 Crypto Library Structure
// crypto/hash.h
void sha256_init(sha256_ctx *ctx);
void sha256_update(sha256_ctx *ctx, const uint8_t *data, size_t len);
void sha256_final(sha256_ctx *ctx, uint8_t digest[32]);
void sha256(const uint8_t *data, size_t len, uint8_t digest[32]);
void sha512_init(sha512_ctx *ctx);
void sha512_update(sha512_ctx *ctx, const uint8_t *data, size_t len);
void sha512_final(sha512_ctx *ctx, uint8_t digest[64]);
// crypto/chacha20.h
void chacha20_poly1305_encrypt(
const uint8_t key[32],
const uint8_t nonce[12],
const uint8_t *plaintext, size_t pt_len,
const uint8_t *aad, size_t aad_len,
uint8_t *ciphertext,
uint8_t tag[16]
);
int chacha20_poly1305_decrypt(
const uint8_t key[32],
const uint8_t nonce[12],
const uint8_t *ciphertext, size_t ct_len,
const uint8_t *aad, size_t aad_len,
uint8_t tag[16],
uint8_t *plaintext
);
// crypto/curve25519.h
void curve25519_keygen(uint8_t public[32], const uint8_t private[32]);
void curve25519_shared(uint8_t shared[32], const uint8_t private[32],
const uint8_t peer_public[32]);
// crypto/ed25519.h
void ed25519_keygen(uint8_t public[32], uint8_t private[64]);
void ed25519_sign(uint8_t signature[64], const uint8_t *message, size_t len,
const uint8_t private[64]);
int ed25519_verify(const uint8_t signature[64], const uint8_t *message,
size_t len, const uint8_t public[32]);
// crypto/random.h
void random_bytes(uint8_t *buffer, size_t len);
uint32_t random_u32(void);
3.2 Key Exchange Algorithms
3.2.1 Curve25519-SHA256 (Primary)
Key Exchange Flow:
1. Client generates ephemeral Curve25519 keypair
2. Client sends public key in SSH_MSG_KEX_ECDH_INIT
3. Server generates ephemeral Curve25519 keypair
4. Server computes shared secret K = curve25519(server_private, client_public)
5. Server computes exchange hash H = SHA256(session_data || K)
6. Server signs H with host key
7. Server sends public key, signature in SSH_MSG_KEX_ECDH_REPLY
8. Client computes K, verifies signature
9. Both derive session keys from K and H
3.2.2 Diffie-Hellman Group14-SHA256 (Compatibility)
Parameters:
- Prime (p): 2048-bit MODP group (RFC 3526)
- Generator (g): 2
- Hash: SHA-256
Key Derivation:
- Initial IV client to server: HASH(K || H || "A" || session_id)
- Initial IV server to client: HASH(K || H || "B" || session_id)
- Encryption key client to server: HASH(K || H || "C" || session_id)
- Encryption key server to client: HASH(K || H || "D" || session_id)
- Integrity key client to server: HASH(K || H || "E" || session_id)
- Integrity key server to client: HASH(K || H || "F" || session_id)
3.3 Authentication Methods
3.3.1 Public Key Authentication (Required)
// Supported key types
typedef enum {
SSH_KEY_ED25519, // ssh-ed25519 (preferred)
SSH_KEY_RSA_SHA256, // rsa-sha2-256
SSH_KEY_RSA_SHA512, // rsa-sha2-512
SSH_KEY_ECDSA_P256, // ecdsa-sha2-nistp256
} ssh_key_type_t;
// Key storage format (OpenSSH compatible)
typedef struct {
ssh_key_type_t type;
uint8_t public_key[256];
size_t public_key_len;
uint8_t private_key[512]; // Encrypted for storage
size_t private_key_len;
} ssh_keypair_t;
3.3.2 Password Authentication (Optional)
// Password auth should be optional and disabled by default
// When enabled, requires:
// - Secure password storage (bcrypt/argon2)
// - Rate limiting
// - Account lockout after failures
3.3.3 Authentication Flow
Client Server
| |
|---SSH_MSG_USERAUTH_REQUEST-------->|
| (publickey, no signature) |
| |
|<--SSH_MSG_USERAUTH_PK_OK-----------|
| (if key is acceptable) |
| |
|---SSH_MSG_USERAUTH_REQUEST-------->|
| (publickey, with signature) |
| |
|<--SSH_MSG_USERAUTH_SUCCESS---------|
| (or FAILURE) |
3.4 Channel Multiplexing
3.4.1 Channel Types
typedef enum {
SSH_CHANNEL_SESSION, // Interactive shell, exec
SSH_CHANNEL_DIRECT_TCPIP, // Local port forwarding
SSH_CHANNEL_FORWARDED_TCPIP, // Remote port forwarding
SSH_CHANNEL_X11, // X11 forwarding (low priority)
} ssh_channel_type_t;
typedef struct ssh_channel {
uint32_t local_id;
uint32_t remote_id;
ssh_channel_type_t type;
uint32_t local_window;
uint32_t remote_window;
uint32_t local_max_packet;
uint32_t remote_max_packet;
// Buffers
uint8_t *recv_buffer;
size_t recv_len;
uint8_t *send_buffer;
size_t send_len;
// Channel state
int state; // OPEN, CLOSE_PENDING, CLOSED
// For session channels
int pty_allocated;
int shell_pid; // If we had processes
} ssh_channel_t;
#define SSH_MAX_CHANNELS 16
3.4.2 Channel Messages
// Message types for channel operations
#define SSH_MSG_CHANNEL_OPEN 90
#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91
#define SSH_MSG_CHANNEL_OPEN_FAILURE 92
#define SSH_MSG_CHANNEL_WINDOW_ADJUST 93
#define SSH_MSG_CHANNEL_DATA 94
#define SSH_MSG_CHANNEL_EXTENDED_DATA 95
#define SSH_MSG_CHANNEL_EOF 96
#define SSH_MSG_CHANNEL_CLOSE 97
#define SSH_MSG_CHANNEL_REQUEST 98
#define SSH_MSG_CHANNEL_SUCCESS 99
#define SSH_MSG_CHANNEL_FAILURE 100
Implementation Phases
Phase 1: SSH Client (4-6 weeks)
Goal: Connect to external SSH servers from MayteraOS
1.1 Crypto Foundation (Week 1-2)
Tasks:
[ ] Port LibTomCrypt SHA-256/SHA-512
[ ] Port LibTomCrypt ChaCha20-Poly1305
[ ] Port LibTomMath for big integers
[ ] Implement/port Curve25519 (TweetNaCl)
[ ] Implement/port Ed25519 (TweetNaCl)
[ ] Implement CSPRNG using RDRAND + entropy pool
[ ] Create crypto test suite
Files to create:
kernel/crypto/
sha256.c, sha256.h
sha512.c, sha512.h
chacha20_poly1305.c, chacha20_poly1305.h
curve25519.c, curve25519.h
ed25519.c, ed25519.h
bignum.c, bignum.h
random.c, random.h
1.2 SSH Transport Layer (Week 3-4)
Tasks:
[ ] Implement SSH version exchange
[ ] Implement algorithm negotiation (SSH_MSG_KEXINIT)
[ ] Implement Curve25519 key exchange
[ ] Implement session key derivation
[ ] Implement encrypted packet format
[ ] Implement MAC verification
[ ] Implement packet sequence numbers
[ ] Implement re-keying
Key Data Structures:
typedef struct ssh_session {
int tcp_socket;
// Version strings
char client_version[256];
char server_version[256];
// Session identifiers
uint8_t session_id[32];
uint8_t exchange_hash[32];
// Encryption state
uint8_t enc_key_c2s[32];
uint8_t enc_key_s2c[32];
uint8_t mac_key_c2s[32];
uint8_t mac_key_s2c[32];
uint8_t iv_c2s[12];
uint8_t iv_s2c[12];
// Sequence numbers
uint32_t seq_c2s;
uint32_t seq_s2c;
// Channels
ssh_channel_t channels[SSH_MAX_CHANNELS];
int num_channels;
// State
int state;
int authenticated;
} ssh_session_t;
1.3 SSH Authentication (Week 5)
Tasks:
[ ] Implement SSH_MSG_USERAUTH_REQUEST
[ ] Implement public key authentication
[ ] Implement SSH key file parsing (OpenSSH format)
[ ] Store host keys for known_hosts equivalent
[ ] Implement keyboard-interactive (optional)
1.4 SSH Connection/Channels (Week 6)
Tasks:
[ ] Implement channel open/close
[ ] Implement channel data transfer
[ ] Implement window management
[ ] Implement PTY request
[ ] Implement shell request
[ ] Integrate with MayteraOS terminal
Client API:
// High-level client API
ssh_session_t *ssh_connect(const char *host, uint16_t port);
int ssh_authenticate_pubkey(ssh_session_t *session, const char *username,
const ssh_keypair_t *key);
int ssh_authenticate_password(ssh_session_t *session, const char *username,
const char *password);
ssh_channel_t *ssh_open_session(ssh_session_t *session);
int ssh_request_pty(ssh_channel_t *channel, const char *term,
int width, int height);
int ssh_request_shell(ssh_channel_t *channel);
int ssh_channel_write(ssh_channel_t *channel, const void *data, size_t len);
int ssh_channel_read(ssh_channel_t *channel, void *buffer, size_t len);
void ssh_disconnect(ssh_session_t *session);
Phase 2: SSH Server (4-6 weeks)
Goal: Accept incoming SSH connections
2.1 Server Framework (Week 1-2)
Tasks:
[ ] Create SSH server listener on port 22
[ ] Generate/store server host keys
[ ] Implement connection handling loop
[ ] Implement version exchange (server side)
[ ] Implement algorithm negotiation (server side)
Server Structure:
typedef struct ssh_server {
int listen_socket;
uint16_t port;
// Host keys
ssh_keypair_t host_key_ed25519;
ssh_keypair_t host_key_rsa; // Optional
// Active connections
ssh_session_t *sessions[SSH_MAX_SESSIONS];
int num_sessions;
// Configuration
int allow_password_auth;
int allow_pubkey_auth;
int max_auth_attempts;
} ssh_server_t;
#define SSH_MAX_SESSIONS 8
2.2 Server Authentication (Week 3)
Tasks:
[ ] Implement authorized_keys equivalent
[ ] Implement user authentication verification
[ ] Implement authentication attempt limiting
[ ] Implement banner messages
Authorized Keys Storage:
// Store in an /etc/ssh-style authorized_keys file on the FAT filesystem
typedef struct authorized_key {
char username[32];
ssh_key_type_t type;
uint8_t public_key[256];
size_t key_len;
char comment[64];
} authorized_key_t;
int ssh_check_authorized_key(const char *username,
ssh_key_type_t type,
const uint8_t *key, size_t key_len);
2.3 PTY/Terminal Integration (Week 4-5)
Tasks:
[ ] Create pseudo-terminal abstraction layer
[ ] Connect SSH channel to MayteraOS terminal
[ ] Implement terminal size negotiation
[ ] Implement terminal mode settings
[ ] Handle Ctrl+C, Ctrl+Z signals
PTY Abstraction:
// Since MayteraOS doesn't have Unix PTYs, create abstraction
typedef struct ssh_pty {
ssh_channel_t *channel;
// Terminal dimensions
int cols;
int rows;
int pixel_width;
int pixel_height;
// Terminal type
char term[32]; // e.g., "xterm-256color"
// Input/output buffers
uint8_t input_buffer[4096];
int input_len;
uint8_t output_buffer[4096];
int output_len;
// Terminal modes
uint8_t modes[256];
} ssh_pty_t;
// Connect PTY to shell/command processor
void ssh_pty_handle_input(ssh_pty_t *pty, const uint8_t *data, size_t len);
void ssh_pty_write_output(ssh_pty_t *pty, const uint8_t *data, size_t len);
2.4 Session Management (Week 6)
Tasks:
[ ] Implement exec request (run single command)
[ ] Implement environment variable passing
[ ] Implement session cleanup
[ ] Implement graceful disconnect
[ ] Implement keep-alive
Phase 3: SCP/SFTP File Transfer (3-4 weeks)
Goal: Enable secure file transfers
3.1 SCP Protocol (Week 1-2)
Tasks:
[ ] Implement SCP source mode (upload to server)
[ ] Implement SCP sink mode (download from server)
[ ] Implement recursive directory transfer
[ ] Implement file permissions handling
[ ] Progress reporting
SCP Functions:
// SCP client functions
int scp_upload(ssh_session_t *session, const char *local_path,
const char *remote_path);
int scp_download(ssh_session_t *session, const char *remote_path,
const char *local_path);
int scp_upload_recursive(ssh_session_t *session, const char *local_dir,
const char *remote_dir);
// SCP server handler
void scp_handle_request(ssh_channel_t *channel, const char *command);
3.2 SFTP Protocol (Week 3-4)
Tasks:
[ ] Implement SFTP subsystem
[ ] Implement SFTP packet format
[ ] Implement file operations (open, read, write, close)
[ ] Implement directory operations (opendir, readdir, mkdir, rmdir)
[ ] Implement file attributes (stat, fstat, setstat)
[ ] Implement rename, remove operations
SFTP Packet Types:
#define SSH_FXP_INIT 1
#define SSH_FXP_VERSION 2
#define SSH_FXP_OPEN 3
#define SSH_FXP_CLOSE 4
#define SSH_FXP_READ 5
#define SSH_FXP_WRITE 6
#define SSH_FXP_LSTAT 7
#define SSH_FXP_FSTAT 8
#define SSH_FXP_SETSTAT 9
#define SSH_FXP_FSETSTAT 10
#define SSH_FXP_OPENDIR 11
#define SSH_FXP_READDIR 12
#define SSH_FXP_REMOVE 13
#define SSH_FXP_MKDIR 14
#define SSH_FXP_RMDIR 15
#define SSH_FXP_REALPATH 16
#define SSH_FXP_STAT 17
#define SSH_FXP_RENAME 18
#define SSH_FXP_STATUS 101
#define SSH_FXP_HANDLE 102
#define SSH_FXP_DATA 103
#define SSH_FXP_NAME 104
#define SSH_FXP_ATTRS 105
Phase 4: Port Forwarding (2-3 weeks)
Goal: Enable TCP tunneling over SSH
4.1 Local Port Forwarding (Week 1)
Tasks:
[ ] Implement direct-tcpip channel type
[ ] Implement local listener socket
[ ] Forward connections through SSH tunnel
[ ] Handle channel flow control
Local Forward Structure:
typedef struct ssh_local_forward {
uint16_t local_port;
char remote_host[256];
uint16_t remote_port;
int listen_socket;
ssh_channel_t *channels[8];
} ssh_local_forward_t;
// -L equivalent: ssh -L local_port:remote_host:remote_port
int ssh_local_forward(ssh_session_t *session, uint16_t local_port,
const char *remote_host, uint16_t remote_port);
4.2 Remote Port Forwarding (Week 2)
Tasks:
[ ] Implement tcpip-forward global request
[ ] Handle forwarded-tcpip channel opens
[ ] Connect to local services
Remote Forward:
// -R equivalent: ssh -R remote_port:local_host:local_port
int ssh_remote_forward(ssh_session_t *session, uint16_t remote_port,
const char *local_host, uint16_t local_port);
// Handle incoming forwarded connection
void ssh_handle_forwarded_tcpip(ssh_session_t *session,
ssh_channel_t *channel,
const char *connected_addr,
uint16_t connected_port);
4.3 Dynamic Port Forwarding (Week 3)
Tasks:
[ ] Implement SOCKS5 server
[ ] Handle SOCKS5 connect requests
[ ] Create direct-tcpip channels for each connection
Dependencies
5.1 SSL/TLS Crypto Primitives
The SSH implementation shares cryptographic primitives with a future TLS implementation:
Shared Crypto Components:
+------------------+------------------+------------------+
| Component | SSH Usage | TLS Usage |
+------------------+------------------+------------------+
| SHA-256 | KEX, signatures | Handshake, certs |
| SHA-384/512 | Ed25519 sigs | TLS 1.3 cipher |
| ChaCha20-Poly1305| Preferred cipher | TLS 1.3 cipher |
| AES-GCM | Alt cipher | TLS 1.2/1.3 |
| Curve25519 | ECDH KEX | TLS 1.3 KEX |
| Ed25519 | Host/user keys | Certificates |
| RSA | Compat keys | Certificates |
| CSPRNG | Nonces, keys | Nonces, keys |
| Big integers | DH, RSA | DH, RSA |
+------------------+------------------+------------------+
Recommendation: Implement crypto layer first, shared between SSH and future TLS.
5.2 TCP Stack (Already Available)
The existing TCP implementation in the kernel's net/tcp.c provides:
// Available API
int tcp_socket(void);
int tcp_bind(int sock, uint16_t port);
int tcp_listen(int sock, int backlog);
int tcp_accept(int sock);
int tcp_connect(int sock, uint32_t remote_ip, uint16_t remote_port);
int tcp_send(int sock, const void *data, uint16_t length);
int tcp_recv(int sock, void *buffer, uint16_t length);
int tcp_close(int sock);
tcp_state_t tcp_get_state(int sock);
int tcp_is_connected(int sock);
Required Enhancements:
- Increase
TCP_MAX_CONNECTIONSfrom 16 to 32 - Increase
TCP_RECV_BUFFER_SIZEfrom 4096 to 16384 - Add non-blocking socket options
- Add socket timeout configuration
5.3 Terminal/PTY Support
The existing terminal in the kernel's gui/terminal.c provides:
// Available terminal features
- 80x25 character display
- 16-color ANSI support
- ANSI escape sequence parsing (CSI sequences)
- Cursor positioning
- Screen clearing/scrolling
- Keyboard input with history
Required Additions:
// PTY abstraction for SSH
typedef struct pty {
int master_fd; // SSH channel side
int slave_fd; // Shell side
struct termios termios; // Terminal settings
struct winsize winsize; // Terminal size
} pty_t;
pty_t *pty_allocate(void);
int pty_set_size(pty_t *pty, int cols, int rows);
int pty_read(pty_t *pty, void *buf, size_t len);
int pty_write(pty_t *pty, const void *buf, size_t len);
void pty_close(pty_t *pty);
5.4 Filesystem (For Key Storage)
Keys and configuration need persistent storage, following the conventional OpenSSH layout:
/etc/ssh/
ssh_host_ed25519_key # Server private host key
ssh_host_ed25519_key.pub # Server public host key
authorized_keys # Allowed user public keys
/home/<user>/.ssh/
id_ed25519 # User private key
id_ed25519.pub # User public key
known_hosts # Cached server public keys
config # SSH client configuration
Required: FAT filesystem write support for key management.
Security Considerations
6.1 Cryptographic Security
Key Requirements:
- Minimum 2048-bit RSA keys (prefer 4096-bit or Ed25519)
- Ephemeral keys for forward secrecy
- Constant-time operations for crypto to prevent timing attacks
- Secure memory wiping after key use
Implementation Guidelines:
// Constant-time comparison
int secure_compare(const void *a, const void *b, size_t len) {
const volatile uint8_t *pa = a;
const volatile uint8_t *pb = b;
uint8_t diff = 0;
for (size_t i = 0; i < len; i++) {
diff |= pa[i] ^ pb[i];
}
return diff == 0 ? 0 : -1;
}
// Secure memory wipe
void secure_wipe(void *ptr, size_t len) {
volatile uint8_t *p = ptr;
while (len--) *p++ = 0;
__asm__ volatile("" ::: "memory");
}
6.2 Authentication Security
Design requirements for the planned server:
- Rate limiting on authentication attempts per connection
- Exponential backoff between failed attempts
- Temporary account lockout after repeated failures
- No root login without explicit configuration
- Public key authentication preferred
6.3 Protocol Security
Mitigations:
- Strict algorithm negotiation (no downgrade attacks)
- Packet sequence number verification
- Re-keying after a data volume or time threshold (per RFC 4253 guidance)
- Maximum packet size limits
- Channel window limits
6.4 Host Key Verification
Known Hosts Implementation:
typedef struct known_host {
char hostname[256];
uint16_t port;
ssh_key_type_t key_type;
uint8_t key_hash[32]; // SHA-256 of public key
uint64_t first_seen;
uint64_t last_seen;
} known_host_t;
typedef enum {
HOST_KEY_OK, // Key matches known host
HOST_KEY_NEW, // New host, prompt user
HOST_KEY_CHANGED, // WARNING: Key changed (possible MITM)
HOST_KEY_REVOKED, // Key explicitly revoked
} host_key_status_t;
host_key_status_t ssh_verify_host_key(const char *hostname, uint16_t port,
ssh_key_type_t type,
const uint8_t *key, size_t key_len);
6.5 Denial of Service Protection
The planned server design bounds resource use with hard limits on concurrent sessions, channels per session, authentication time, idle time, and pending connections.
Testing Strategy
7.1 Unit Tests
// Crypto tests
void test_sha256(void);
void test_chacha20_poly1305(void);
void test_curve25519(void);
void test_ed25519(void);
// Protocol tests
void test_packet_encode_decode(void);
void test_algorithm_negotiation(void);
void test_key_exchange(void);
void test_key_derivation(void);
void test_channel_operations(void);
7.2 Integration Tests
Test Matrix:
| Server | Client | Test Focus |
|---|---|---|
| OpenSSH | MayteraOS SSH Client | Interoperability |
| MayteraOS SSH Server | OpenSSH | Interoperability |
| MayteraOS SSH Server | MayteraOS SSH Client | Full stack |
| Dropbear | MayteraOS SSH Client | Alternative server |
7.3 Security Tests
Run from a Linux host against a MayteraOS test VM:
# Test with SSH audit tool
ssh-audit <test-vm-address>:22
# Test with nmap
nmap -sV -p22 --script ssh2-enum-algos <test-vm-address>
# Fuzzing with AFL
afl-fuzz -i testcases -o findings ./ssh_server @@
7.4 Performance Tests
- Connection establishment time
- Data throughput (MB/s)
- Memory usage per connection
- Maximum concurrent connections
Resource Estimates
8.1 Code Size Estimates
| Component | Estimated LOC | Binary Size |
|---|---|---|
| Crypto (SHA, ChaCha, Curve25519, Ed25519) | 3,000-5,000 | 20-40 KB |
| SSH Transport | 2,000-3,000 | 15-25 KB |
| SSH Authentication | 1,000-1,500 | 8-12 KB |
| SSH Channels | 1,500-2,000 | 12-18 KB |
| SSH Client | 1,000-1,500 | 8-12 KB |
| SSH Server | 1,500-2,000 | 12-18 KB |
| SCP | 500-800 | 4-6 KB |
| SFTP | 1,500-2,000 | 12-18 KB |
| Total | 12,000-18,000 | 90-150 KB |
8.2 Memory Requirements
| Resource | Size |
|---|---|
| Per-session state | ~16 KB |
| Per-channel state | ~8 KB |
| Crypto context | ~2 KB |
| Buffers (per session) | ~32 KB |
| Maximum (8 sessions) | ~400 KB |
8.3 Development Time Estimates
| Phase | Duration | Developers |
|---|---|---|
| Phase 1: SSH Client | 4-6 weeks | 1 |
| Phase 2: SSH Server | 4-6 weeks | 1 |
| Phase 3: SCP/SFTP | 3-4 weeks | 1 |
| Phase 4: Port Forwarding | 2-3 weeks | 1 |
| Total | 13-19 weeks |
References
RFC Documents
- RFC 4250: SSH Protocol Assigned Numbers
- RFC 4251: SSH Protocol Architecture
- RFC 4252: SSH Authentication Protocol
- RFC 4253: SSH Transport Layer Protocol
- RFC 4254: SSH Connection Protocol
- RFC 8332: Use of RSA Keys with SHA-256 and SHA-512
- RFC 8709: Ed25519 and Ed448 Public Key Algorithms
Implementations
- Dropbear SSH - Lightweight SSH implementation
- Dropbear GitHub Repository - Source code
- TinySSH - Minimal SSH server using NaCl
- SSH Implementation Comparison
- LibTomCrypt - Crypto library used by Dropbear
Cryptography
- TweetNaCl - Minimal NaCl implementation (Curve25519, Ed25519)
- LibTomMath - Big integer library
- ChaCha20-Poly1305 IETF
Terminal/PTY
Appendix A: Message Type Reference
// Transport layer
#define SSH_MSG_DISCONNECT 1
#define SSH_MSG_IGNORE 2
#define SSH_MSG_UNIMPLEMENTED 3
#define SSH_MSG_DEBUG 4
#define SSH_MSG_SERVICE_REQUEST 5
#define SSH_MSG_SERVICE_ACCEPT 6
// Key exchange
#define SSH_MSG_KEXINIT 20
#define SSH_MSG_NEWKEYS 21
#define SSH_MSG_KEX_ECDH_INIT 30
#define SSH_MSG_KEX_ECDH_REPLY 31
// User authentication
#define SSH_MSG_USERAUTH_REQUEST 50
#define SSH_MSG_USERAUTH_FAILURE 51
#define SSH_MSG_USERAUTH_SUCCESS 52
#define SSH_MSG_USERAUTH_BANNER 53
#define SSH_MSG_USERAUTH_PK_OK 60
// Connection protocol
#define SSH_MSG_GLOBAL_REQUEST 80
#define SSH_MSG_REQUEST_SUCCESS 81
#define SSH_MSG_REQUEST_FAILURE 82
#define SSH_MSG_CHANNEL_OPEN 90
#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91
#define SSH_MSG_CHANNEL_OPEN_FAILURE 92
#define SSH_MSG_CHANNEL_WINDOW_ADJUST 93
#define SSH_MSG_CHANNEL_DATA 94
#define SSH_MSG_CHANNEL_EXTENDED_DATA 95
#define SSH_MSG_CHANNEL_EOF 96
#define SSH_MSG_CHANNEL_CLOSE 97
#define SSH_MSG_CHANNEL_REQUEST 98
#define SSH_MSG_CHANNEL_SUCCESS 99
#define SSH_MSG_CHANNEL_FAILURE 100
Appendix B: Algorithm Identifier Strings
// Key exchange
"curve25519-sha256"
"[email protected]"
"diffie-hellman-group14-sha256"
"diffie-hellman-group16-sha512"
// Host key algorithms
"ssh-ed25519"
"rsa-sha2-256"
"rsa-sha2-512"
"ecdsa-sha2-nistp256"
// Encryption algorithms
"[email protected]"
"[email protected]"
"[email protected]"
"aes256-ctr"
"aes128-ctr"
// MAC algorithms (with encrypt-then-mac)
"[email protected]"
"[email protected]"
"hmac-sha2-256"
"hmac-sha2-512"
// Compression
"none"
Document prepared for MayteraOS SSH implementation planning.