Skip to content

!boards/nsh: Replace TEA password storage with PBKDF2-HMAC-SHA256 hashing #19209

Open
Abhishekmishra2808 wants to merge 4 commits into
apache:masterfrom
Abhishekmishra2808:passwd-empty-default-hardening
Open

!boards/nsh: Replace TEA password storage with PBKDF2-HMAC-SHA256 hashing #19209
Abhishekmishra2808 wants to merge 4 commits into
apache:masterfrom
Abhishekmishra2808:passwd-empty-default-hardening

Conversation

@Abhishekmishra2808

@Abhishekmishra2808 Abhishekmishra2808 commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Replace reversible TEA password storage in /etc/passwd with one-way PBKDF2-HMAC-SHA256 hashing in modular crypt format (MCF): $pbkdf2-sha256$<iterations>$<base64url-salt>$<base64url-hash>

BREAKING CHANGE: TEA-encoded /etc/passwd entries no longer verify.
Regenerate with tools/mkpasswd or NSH passwd/useradd after upgrading nuttx-apps.

Changes:

  • Add apps/crypto/pbkdf2 (PBKDF2-HMAC-SHA256; Mbed TLS backend when available, self-contained SHA-256 fallback otherwise)
  • Rewrite passwd_encrypt.c / passwd_verify.c to use PBKDF2 and timingsafe_bcmp() for verification
  • Add shared passwd_base64.c for base64url encode/decode
  • Enforce password complexity when setting passwords (min 8 chars, upper, lower, digit, special character)
  • Add testing/pbkdf2 (RFC 6070 vectors + passwd round-trip test)

Companion nuttx PR (host mkpasswd tool and ROMFS build integration): apache/nuttx-apps#3557

Impact

Security

  • Passwords are stored as one-way hashes with per-password random salt and configurable iteration count (default 10000).
  • Plaintext passwords are never written to /etc/passwd.

Compatibility (breaking)

  • Existing TEA-encoded /etc/passwd entries will not verify. Users must regenerate passwords with NSH passwd / useradd or build-time mkpasswd after upgrading.
  • Depends on companion nuttx PR for ROMFS autogen and host tooling.

Build

  • Selects CRYPTO_PBKDF2 automatically when FSUTILS_PASSWD is enabled.

Runtime

  • Login latency increases slightly on low MHz MCUs due to PBKDF2 iterations (tunable via CONFIG_FSUTILS_PASSWD_PBKDF2_ITERATIONS).

Testing

Host: WSL2 Linux, x86_64

Sim (sim:nsh or login-enabled config)

  • Build succeeds with FSUTILS_PASSWD and TESTING_PBKDF2
abhishek@Lethallaptop:~/nuttx$ time make -j$(nproc)
Create version.h
LN: platform/board to /home/abhishek/nuttx-apps/platform/dummy
Register: gpio
Register: dd
Register: dumpstack
Register: nsh
Register: sh
Register: hello
CP:  /home/abhishek/nuttx/include/nuttx/config.h
CP:  /home/abhishek/nuttx/include/nuttx/fs/hostfs.h
ROMFS root password (min 8 characters): 
LD:  nuttx
Pac SIM with dynamic libs..
'/lib/x86_64-linux-gnu/libz.so.1' -> 'sim-pac/libs/libz.so.1'
'/lib/x86_64-linux-gnu/libc.so.6' -> 'sim-pac/libs/libc.so.6'
'/lib64/ld-linux-x86-64.so.2' -> 'sim-pac/ld-linux-x86-64.so.2'
SIM elf with dynamic libs archive in nuttx.tgz

real    0m51.470s
user    3m38.379s
sys     2m34.115s

ESP32-C3 (esp32c3-devkit:login, local test config, not in this PR)

  • ROMFS /etc/passwd with PBKDF2 hash
  • NSH console login over USB serial (/dev/ttyACM0) succeeds with configured password; wrong password rejected
abhishek@Lethallaptop:~/nuttx$ make -j$(nproc) CROSSDEV=riscv32-esp-elf-
Create version.h
Cloning Espressif HAL for 3rd Party Platforms
Clone: chip/esp-hal-3rdparty LN: platform/board to /home/abhishek/nuttx-apps/platform/dummy
Register: dumpstack
Register: nsh
Register: sh
Register: dd
Register: ostest
Register: pbkdf2_test
Register: getprime
Espressif HAL for 3rd Party Platforms: cleaning current repository...
Espressif HAL for 3rd Party Platforms: 0eb59f7e02a4735f2b9a78797e691b66740fcadb
ROMFS root password (min 8 characters): 
LD: nuttx
Memory region         Used Size  Region Size  %age Used
             ROM:      310900 B         4 MB      7.41%
     iram0_0_seg:       14768 B     321296 B      4.60%
     irom0_0_seg:      139684 B         4 MB      3.33%
     dram0_0_seg:       24512 B     321296 B      7.63%
     drom0_0_seg:      245328 B         4 MB      5.85%
    rtc_iram_seg:          52 B       8168 B      0.64%
rtc_reserved_seg:          0 GB         24 B      0.00%
CP: nuttx.hex
MKIMAGE: NuttX binary
esptool.py -c esp32c3 elf2image --ram-only-header -fs 4MB -fm dio -ff "80m" -o nuttx.bin nuttx
Warning: DEPRECATED: 'esptool.py' is deprecated. Please use 'esptool' instead. The '.py' suffix will be removed in a future major release.
esptool v5.3.0
Creating ESP32-C3 image...
Image has only RAM segments visible. ROM segments are hidden and SHA256 digest is not appended.
Merged 1 ELF section.
Successfully created ESP32-C3 image.
Generated: nuttx.bin

Manual verification

  • useradd / passwd reject weak passwords (no special char, too short)
  • Valid password produces $pbkdf2-sha256$... hash in /etc/passwd

@github-actions github-actions Bot added Area: Build system Size: M The size of the change in this PR is medium Board: risc-v Board: simulator labels Jun 24, 2026
@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

@Abhishekmishra2808

Copy link
Copy Markdown
Contributor Author

@acassis, Checks are failing because the password is currently empty, and CI expects some passwd value.
What would be the right way to fix CI?

@acassis

acassis commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

@acassis, Checks are failing because the password is currently empty, and CI expects some passwd value. What would be the right way to fix CI?

Let's wait for @simbit18 suggestion. I think one option will be removing the board profile from CI testing

Comment thread boards/Kconfig Outdated
@github-actions github-actions Bot added Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces. and removed Size: M The size of the change in this PR is medium labels Jun 25, 2026
@Abhishekmishra2808
Abhishekmishra2808 marked this pull request as draft June 25, 2026 15:35
@Abhishekmishra2808
Abhishekmishra2808 force-pushed the passwd-empty-default-hardening branch from f4a6ce2 to aeec705 Compare June 25, 2026 16:43
@Abhishekmishra2808 Abhishekmishra2808 changed the title !boards/nsh: Require explicit ROMFS passwd password at build time !boards/nsh: Replace reversible TEA password storage in /etc/passwd with one-way PBKDF2-HMAC-SHA256 hashing Jun 25, 2026
@Abhishekmishra2808
Abhishekmishra2808 force-pushed the passwd-empty-default-hardening branch from aeec705 to 084e043 Compare June 25, 2026 16:47
@Abhishekmishra2808
Abhishekmishra2808 force-pushed the passwd-empty-default-hardening branch from 14e477a to 08bd6bb Compare July 15, 2026 15:42
Add standalone host PBKDF2-HMAC-SHA256 mkpasswd, board_romfs_mkpasswd.sh,
and promptpasswd.sh with confirm-password support. Integrate ROMFS passwd
generation in Board.mk and CMake. Drop TEA key checks from passwd_keys.mk.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Migrate moxa:nsh from fixed telnet password to build-time ROMFS
/etc/passwd with PBKDF2-HMAC-SHA256 and cryptodev.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
@Abhishekmishra2808
Abhishekmishra2808 force-pushed the passwd-empty-default-hardening branch 2 times, most recently from 26eec91 to f83759c Compare July 15, 2026 16:18
Abhishekmishra2808 added a commit to Abhishekmishra2808/nuttx-apps that referenced this pull request Jul 15, 2026
Migrate passwd encrypt/verify to PBKDF2 modular crypt format using
kernel cryptodev (CRYPTO_PBKDF2_HMAC_SHA256 via /dev/crypto).  Add
passwd_pbkdf2 wrapper, base64url helpers, complexity validation, and
pbkdf2_test for RFC 6070 vector coverage.  FSUTILS_PASSWD selects
CRYPTO, ALLOW_BSD_COMPONENTS, and CRYPTO_CRYPTODEV so existing sim
defconfigs keep building.  Change NSH_LOGIN_USERNAME default to root and
remove fixed-login password defaults.

BREAKING CHANGE: TEA-encoded /etc/passwd entries no longer verify.
Regenerate each entry after upgrading.  Pair with the nuttx host mkpasswd
changes in apache/nuttx#19209.  Boards must enable the appropriate
software or hardware crypto backend for PBKDF2 at runtime.  When
CONFIG_NSH_LOGIN_FIXED=y, set CONFIG_NSH_LOGIN_PASSWORD in the board
defconfig or menuconfig; there is no default password.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
@Abhishekmishra2808
Abhishekmishra2808 force-pushed the passwd-empty-default-hardening branch from f83759c to 18a493e Compare July 15, 2026 18:38
Update login and mkpasswd documentation for PBKDF2, root password
terminology, and NUTTX_ROMFS_PASSWD_PASSWORD. Set CI sim/login test
password to NuttXSim1!. Restore sim lely docs dropped during rebase.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Avoid base64 symbol collision with Dropbear libtomcrypt at link time.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
@Abhishekmishra2808
Abhishekmishra2808 force-pushed the passwd-empty-default-hardening branch from f0a2a54 to a4c807a Compare July 16, 2026 08:02
@Abhishekmishra2808 Abhishekmishra2808 changed the title !boards/nsh: Replace reversible TEA password storage in /etc/passwd with one-way PBKDF2-HMAC-SHA256 hashing !boards/nsh: Replace TEA password storage with PBKDF2-HMAC-SHA256 hashing Jul 16, 2026
@Abhishekmishra2808
Abhishekmishra2808 marked this pull request as ready for review July 16, 2026 12:10
@Abhishekmishra2808

Copy link
Copy Markdown
Contributor Author

@acassis, @xiaoxiang781216 PTAL !

@acassis

acassis commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

@Abhishekmishra2808 why did you disable the Crypto for Dropbear? I think @FelipeMdeO is already fixing this issue.

@FelipeMdeO is it ok for you to let disable it?

@Abhishekmishra2808

Copy link
Copy Markdown
Contributor Author

They caused base64 symbol collisions with libtomcrypt at link time, so I reverted only the CODECS/CRYPTO lines I'd added for Kconfig deps. Dropbear still uses CRYPTO_MBEDTLS as upstream.

I think I should coordinate with @FelipeMdeO for this.

@FelipeMdeO

Copy link
Copy Markdown
Contributor

They caused base64 symbol collisions with libtomcrypt at link time, so I reverted only the CODECS/CRYPTO lines I'd added for Kconfig deps. Dropbear still uses CRYPTO_MBEDTLS as upstream.

I think I should coordinate with @FelipeMdeO for this.

Hello @Abhishekmishra2808 , I cannot access my environment now, but more late I will take a look and ping you.

@FelipeMdeO

Copy link
Copy Markdown
Contributor

Hello @acassis , @Abhishekmishra2808 , sorry, combining your 2 PR will "crash" dropbear.
I followed the steps below to have this conclusion:

git clone git@github.com:apache/nuttx.git nuttx-repro && cd nuttx-repro
git fetch origin pull/19209/head:pr-19209 && git checkout pr-19209

cd .. && git clone git@github.com:apache/nuttx-apps.git apps && cd apps
git fetch origin pull/3557/head:pr-3557 && git checkout pr-3557

cd ../nuttx-repro
./tools/configure.sh sim:dropbear
make -j$(nproc)                     # builda com sucesso, sem dropbear dentro

After build, you will see:

➜  nuttx-repro git:(pr-19209) grep CONFIG_NETUTILS_DROPBEAR .config
➜  nuttx-repro git:(pr-19209) ./nuttx 

NuttShell (NSH) NuttX-13.0.0
nsh> help
help usage:  help [-v] [<cmd>]

    .           cmp         free        mkfifo      rmdir       uname       
    [           dirname     help        mkrd        set         umount      
    ?           df          hexdump     mount       kill        unset       
    alias       dmesg       ifconfig    mv          pkill       uptime      
    unalias     echo        ifdown      nslookup    sleep       watch       
    arp         env         ifup        pidof       usleep      xd          
    basename    exec        losetup     printf      source      wait        
    break       exit        ln          ps          test        
    cat         expr        ls          pwd         time        
    cd          false       mkdir       readlink    true        
    cp          fdinfo      mkfatfs     rm          truncate    

Builtin Apps:
    aescbc       aesxts       des3cbc      gpio         hmac         ping         
    aesctr       dd           dumpstack    hello        nsh          sh           
nsh> 

So the dropbear was silently disabled.
I will start to look right now why its happen when how can we solve this issue.

@FelipeMdeO

FelipeMdeO commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Hello @Abhishekmishra2808 .

Please revert commit a4c807a (your last commit), the base64/ecc collision it worked around is already handled by the symbol renaming in netutils/dropbear/Makefile, so the strip is redundant. When restoring the lines, also add CONFIG_CRYPTO_CRYPTODEV_SOFTWARE_CRYPTO=y (+ CONFIG_CRYPTO_SW_AES=y), or /dev/crypto won't have the swcr_pbkdf2 backend and PBKDF2 login fails at runtime.

Look for git diff from your last commit:

diff --git a/boards/sim/sim/sim/configs/dropbear/defconfig b/boards/sim/sim/sim/configs/dropbear/defconfig
index e5990f622c..3905398c47 100644
--- a/boards/sim/sim/sim/configs/dropbear/defconfig
+++ b/boards/sim/sim/sim/configs/dropbear/defconfig
@@ -16,7 +16,13 @@ CONFIG_ARCH_SIM=y
 CONFIG_BOARD_LOOPSPERMSEC=0
 CONFIG_BOOT_RUNFROMEXTSRAM=y
 CONFIG_BUILTIN=y
+CONFIG_CODECS_BASE64=y
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_CRYPTODEV=y
+CONFIG_CRYPTO_CRYPTODEV_SOFTWARE_CRYPTO=y
 CONFIG_CRYPTO_MBEDTLS=y
+CONFIG_CRYPTO_RANDOM_POOL=y
+CONFIG_CRYPTO_SW_AES=y
 CONFIG_DEBUG_SYMBOLS=y
 CONFIG_DEV_GPIO=y
 CONFIG_DEV_LOOP=y
@@ -55,6 +61,7 @@ CONFIG_NET=y
 CONFIG_NETDEV_LATEINIT=y
 CONFIG_NETINIT_DRIPADDR=0x0a000101
 CONFIG_NETINIT_IPADDR=0x0a000102
+CONFIG_NETUTILS_CODECS=y
 CONFIG_NETUTILS_DROPBEAR=y
 CONFIG_NETUTILS_DROPBEAR_HOSTKEY_PATH="/tmp/dropbear_ecdsa_host_key"
 CONFIG_NET_BROADCAST=y

PS: You changed the password policy, right?
What do you think about explicitly stating that the password does not meet the security policies, and perhaps adding some information that makes it easier for the user to identify the security policy?

I don't have relevant background on this point, could you give your opinion, @acassis , @xiaoxiang781216 , @ThePassionate ?

I took some time to get issue when I tested dropbear after your change, the current output for password out of policy is:

./nuttx

dropbear [6:100]

NuttShell (NSH) NuttX-13.0.0
nsh> [6] Jun 01 00:00:00 using NuttX passwd auth at /tmp/passwd
dropbear: listening on port 2222

nsh> useradd test dropbear
nsh: useradd: passwd_adduser failed: 22
nsh> 


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

Labels

Area: Build system Board: arm Board: risc-v Board: simulator Size: XL The size of the change in this PR is very large. Consider breaking down the PR into smaller pieces.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants