Skip to content

netutils/dropbear: initial Dropbear SSH server port for NuttX#3532

Draft
FelipeMdeO wants to merge 1 commit into
apache:masterfrom
FelipeMdeO:feature/dropbear-esp32c3-port
Draft

netutils/dropbear: initial Dropbear SSH server port for NuttX#3532
FelipeMdeO wants to merge 1 commit into
apache:masterfrom
FelipeMdeO:feature/dropbear-esp32c3-port

Conversation

@FelipeMdeO

Copy link
Copy Markdown
Contributor

Summary

This PR adds two related changes that together bring up an SSH server
on the ESP32-C3 DevKit board using the Dropbear application:

boards/risc-v/esp32c3/esp32c3-devkit/configs/dropbear

A new dropbear defconfig is introduced for the ESP32-C3 DevKit board.
It wires up the Dropbear SSH server application together with:

  • Wi-Fi STA mode with DHCP client (WAPI tooling included for link
    bring-up at boot).
  • urandom device for key material.
  • SPIFFS on SPI flash (/data mountpoint) to persist the host key and
    the password database.
  • FSUTILS_PASSWD pointing to /data/passwd as the credential store,
    replacing a previous Dropbear-specific password-file path.
  • ECDSA host key stored at /data/dropbear_ecdsa_host_key.
  • NSH autostart of the dropbear task on every boot.
  • PTY support and Ctrl-C signal delivery enabled for interactive
    sessions.
  • CONFIG_NETUTILS_DROPBEAR_STACKSIZE pinned to 65536 bytes; the
    default 32 KiB overflows during key exchange on this RISC-V target.
  • CONFIG_NETUTILS_DROPBEAR_LISTEN_RETRY_MAX=120 so the daemon keeps
    retrying until the Wi-Fi link is fully up.

Wi-Fi credentials (myssid / mypasswd) are placeholders and must be
set via menuconfig before flashing.

crypto: expose ChaCha20 stream helpers

Dropbear uses the chacha20-poly1305@openssh.com cipher, which requires
a stateful, multi-call ChaCha20 stream interface rather than the single-
block interface currently exposed by crypto/chachapoly.c. Three helpers
and a context struct are added:

  • struct chacha20_stream_ctx — opaque wrapper around chacha_ctx.
  • chacha20_stream_setkey() — initialise the key.
  • chacha20_stream_ivctr64() — set IV and 64-bit counter.
  • chacha20_stream_crypt() — encrypt/decrypt an arbitrary-length buffer.

All three functions are thin wrappers over the existing chacha_*
primitives; no new algorithm code is introduced.

Impact

  • New board configuration: the dropbear defconfig is additive and
    does not affect any existing configuration.
  • New public API: three functions and one struct are added to
    include/crypto/chachapoly.h. The change is purely additive; existing
    users of chacha20_setkey / chacha20_crypt are unaffected.
  • Build: no impact on boards or configurations that do not select
    CONFIG_NETUTILS_DROPBEAR.
  • Security: host keys and credentials live on a SPIFFS partition
    under /data; they are generated at first run and persist across
    reboots. Wi-Fi credentials must be provisioned by the user before
    flashing.

Testing

Host: Linux x86_64, GCC RISC-V toolchain
Board: ESP32-C3 DevKit (rev 0.4)

Build:

./tools/configure.sh esp32c3-devkit:dropbear
make -j$(nproc)
make flash ESPTOOL_PORT=/dev/ttyUSB0

First-time user provisioning (serial console):

The NuttX passwd file lives on SPIFFS (/data/passwd) and is empty on a
fresh flash. Before the first SSH login, create a user from the NSH
serial console:

nsh> useradd root <password>

The ECDSA host key is generated automatically on first boot.

Boot log shows Dropbear listening after Wi-Fi association:

NuttShell (NSH) NuttX-12.6.0
nsh> loaded ECDSA P-256 host key from /data/dropbear_ecdsa_host_key
     using NuttX passwd auth at /data/passwd
     dropbear: listening on port 2222

SSH connection from the host:

$ ssh -p 2222 root@<board-ip>
root@<board-ip>'s password: <password>
NuttShell (NSH) NuttX-12.6.0
nsh>

Ports the Dropbear SSH server to NuttX targeting RISC-V (ESP32-C3).
Companion to the NuttX kernel PR that adds the ESP32-C3 dropbear
defconfig and ChaCha20 stream helpers.

The port provides a fully integrated SSH daemon that authenticates users
against the NuttX passwd file (FSUTILS_PASSWD) via a pluggable
nuttx_auth.c layer, generates and persists an ECDSA P-256 host key on
SPIFFS, and spawns an interactive NSH session on a PTY for each
authenticated connection.

Build system:
- Makefile/CMakeLists.txt: download the upstream Dropbear tarball at
  build time, compile it with bundled libtomcrypt/libtommath, and link
  into the NuttX image.
- Uses gpatch on macOS (CONFIG_HOST_MACOS) since Apple patch 2.0 lacks
  support for diff --git format. All patch invocations use -i flag
  instead of stdin redirect to avoid conflicts under parallel make.
- patch/0001-0007: series of patches applied to the upstream tree to
  replace autoconf-generated headers, redirect crypto primitives to
  NuttX kernel APIs, fix compiler warnings, and guard the environ
  declaration for NuttX. Patches 0003-0006 strip diff --git/index
  headers for BSD patch compatibility.

Port layer (netutils/dropbear/port/):
- nuttx_config.h/localoptions.h: trim algorithm set to ECDSA,
  ChaCha20-Poly1305, Curve25519, AES-128-CTR, and HMAC-SHA256.
- nuttx_hostkey.c: generate and store ECDSA host key on first run.
- nuttx_auth.c: password verification against NuttX passwd file.
- dropbear_chachapoly.c: wires ChaCha20-Poly1305 to chacha20_stream_*
  helpers from the kernel PR.
- dropbear_ltc_aes.c/hmac_sha256.c/sha256.c: redirect libtomcrypt
  calls to NuttX kernel crypto APIs.
- nuttx_compat.c: minimal POSIX shims.

Application layer:
- dropbear_main.c: foreground accept loop with configurable listen
  retries; setjmp/longjmp recovery fence per session.
- dropbear_nshsession.c: ChanType handler opening a PTY pair, spawning
  NSH on the slave end, threading I/O, delivering SIGINT on Ctrl-C.

NSH integration (nshlib/):
- nsh_dropbear.c/nsh_init.c: optionally autostart dropbear at NSH boot
  when CONFIG_NSH_DROPBEAR is enabled.

fsutils/passwd:
- passwd_adduser.c: create passwd file if missing before appending
  first user, preventing error on fresh filesystem.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@acassis

acassis commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

@FelipeMdeO nice work! Kudos!!!

Some suggestions to improve this PR:

  • many of these patches are just to fix the UNUSED()s, moving it from function parameters to inside at the end of the function, please talk with the original author, maybe he accepts to move it to the end of the function;

Comment thread nshlib/nsh_dropbear.c
for (i = 0; i < len; i++)
ninfo("Starting the Dropbear SSH server\n");

ret = nsh_parse(&pstate->cn_vtbl, cmdline);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why to use it instead of doing like Telnet does: "nsh_session(pstate, NSH_LOGIN_TELNET, argc, argv);" ?

Comment on lines +27 to +36
#define DISABLE_LASTLOG 1
#define DISABLE_PAM 1
#define DISABLE_PUTUTLINE 1
#define DISABLE_PUTUTXLINE 1
#define DISABLE_SYSLOG 1
#define DISABLE_UTMP 1
#define DISABLE_UTMPX 1
#define DISABLE_WTMP 1
#define DISABLE_WTMPX 1
#define DISABLE_ZLIB 1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these variable could be controlled from Kconfig definitions

Comment on lines +69 to +73
#define HAVE_STRUCT_ADDRINFO 1
#define HAVE_STRUCT_IN6_ADDR 1
#define HAVE_STRUCT_SOCKADDR_IN6 1
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these definitions cannot be hard-code, i.e.: HAVE_STRUCT_SOCKADDR_IN6, HAVE_STRUCT_SOCKADDR_IN6, could be disabled if IPv6 support on NuttX is not enabled.

Comment thread netutils/dropbear/Kconfig
select DEV_RANDOM
select DEV_URANDOM
select LIBC_NETDB
select LIBC_GAISTRERROR

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change select to depends on

Comment thread netutils/dropbear/Kconfig
config NETUTILS_DROPBEAR_STACKSIZE
int "Dropbear main stack size"
default 65536 if ARCH_CHIP_ESP32C3
default 32768

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not fix to 65536


/* Check if the username already exists */

stream = fopen(CONFIG_FSUTILS_PASSWD_PATH, "a");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why need open stream and close it immediately

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants