Skip to content

!boards/nsh: Replace reversible TEA password storage in /etc/passwd with one-way PBKDF2-HMAC-SHA256 hashing #19209

Draft
Abhishekmishra2808 wants to merge 2 commits into
apache:masterfrom
Abhishekmishra2808:passwd-empty-default-hardening
Draft

!boards/nsh: Replace reversible TEA password storage in /etc/passwd with one-way PBKDF2-HMAC-SHA256 hashing #19209
Abhishekmishra2808 wants to merge 2 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 added a commit to Abhishekmishra2808/nuttx-apps that referenced this pull request Jun 25, 2026
Add apps/crypto/pbkdf2, migrate passwd encrypt/verify to modular crypt
format with complexity validation, share base64url helpers, and add
pbkdf2_test for RFC 6070 vector coverage.  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.  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 added a commit to Abhishekmishra2808/nuttx-apps that referenced this pull request Jun 25, 2026
Add apps/crypto/pbkdf2, migrate passwd encrypt/verify to modular crypt
format with complexity validation, share base64url helpers, and add
pbkdf2_test for RFC 6070 vector coverage.  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.  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>
Comment thread cmake/nuttx_add_romfs.cmake Outdated

@simbit18 simbit18 Jun 25, 2026

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.

Hi @Abhishekmishra2808 Is this a cross-platform solution (board_romfs_mkpasswd.sh)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, on supported NuttX host environments

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.

This shell script (board_romfs_mkpasswd.sh) used in CMake (cmake/nuttx_add_romfs.cmake ) is not a cross-platform solution

      COMMAND
        ${NUTTX_DIR}/tools/board_romfs_mkpasswd.sh ${NUTTX_DIR}
        ${ROMFS_PASSWD_FILE} ${MKPASSWD_BIN} ${GENPASSWD_OUTPUT} --user
        "${CONFIG_BOARD_ETC_ROMFS_PASSWD_USER}" --uid
        ${CONFIG_BOARD_ETC_ROMFS_PASSWD_UID} --gid
        ${CONFIG_BOARD_ETC_ROMFS_PASSWD_GID} --home
        "${CONFIG_BOARD_ETC_ROMFS_PASSWD_HOME}"
      DEPENDS ${MKPASSWD_BIN} ${NUTTX_DIR}/.config
      COMMENT "Generating /etc/passwd from Kconfig values")

https://github.com/Abhishekmishra2808/nuttx/blob/084e0432d7943ad96c163d34dd5cbaea909fbdd6/cmake/nuttx_add_romfs.cmake#L318-L326

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I mixed up "works on supported NuttX Unix hosts" with "cross-platform in CMake," which isn't the same thing :(
Now I have updated cmake/nuttx_add_romfs.cmake to call the host mkpasswd binary directly again, reading the passwd and iterations from Kconfig

Replace TEA based build time hashing with PBKDF2-HMAC-SHA256, add
promptpasswd and board_romfs_mkpasswd helpers, require a root password
when ROMFS passwd autogen is enabled, and enforce password complexity
at build time.

BREAKING CHANGE: TEA-encoded /etc/passwd entries no longer verify.
Regenerate each entry with tools/mkpasswd or NSH passwd/useradd after
upgrading nuttx-apps. Builds with CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y
fail until CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD is set in menuconfig
(Board Selection -> Auto-generate /etc/passwd at build time -> Root
password) or entered when make prompts.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Document PBKDF2-HMAC-SHA256 passwd format, build-time ROMFS flow,
password complexity rules, and remove obsolete TEA references.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
@Abhishekmishra2808 Abhishekmishra2808 force-pushed the passwd-empty-default-hardening branch from 084e043 to 6671871 Compare June 25, 2026 20:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Build system 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.

4 participants