boards: add CI ROMFS passwd credentials and refresh docs

Support NUTTX_ROMFS_PASSWD_PASSWORD via update_romfs_password.sh for
configs that enable ROMFS passwd without a defconfig password (sim/login
CI). Enable RANDOMIZE_KEYS in sim/login defconfig. Update mkpasswd.c
header, platform docs, and the mkpasswd_autogen guide.

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
This commit is contained in:
Abhishek Mishra
2026-07-09 22:41:11 +08:00
committed by Xiang Xiao
parent ffa6ba222f
commit e9c9cba51d
12 changed files with 307 additions and 119 deletions
+107 -43
View File
@@ -17,64 +17,130 @@ and host C programs that are important parts of the NuttX build system:
mkpasswd — Build-time ``/etc/passwd`` Generation
-------------------------------------------------
``tools/mkpasswd`` is a host tool (``tools/mkpasswd.c``) that generates a
single ``/etc/passwd`` entry at build time. It runs automatically when
``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y``.
``tools/mkpasswd`` (``tools/mkpasswd.c``) is a host program that writes a
single ``/etc/passwd`` entry with a TEA-encrypted password hash. The
plaintext password is **not** stored in the firmware image.
The plaintext password is hashed with TEA and is not stored in the firmware.
The build fails if the password is empty or uses known insecure defaults.
When ``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y``, the build invokes
``mkpasswd`` automatically from ``boards/Board.mk`` (Make) or
``cmake/nuttx_add_romfs.cmake`` (CMake). You normally configure the
password and keys in menuconfig; you do not run ``mkpasswd`` by hand.
Setup
~~~~~
Prerequisites
~~~~~~~~~~~~~
1. Run ``make menuconfig`` and configure:
Enable all of the following (via ``make menuconfig``):
* **Board Selection** → Auto-generate /etc/passwd at build time
* Set the admin password (required, minimum 8 characters)
* Enable random TEA key generation, or set keys manually (see below)
* **Application Configuration** → NSH Library → Console Login
* Set verification method to **Encrypted password file**
* **Application Configuration** → File System Utilities → Password file support
* Enable password file support
* **Board Selection** → **Auto-generate /etc/passwd at build time**
(``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE``)
* **Application Configuration** → **NSH Library** → **Console Login**
(``CONFIG_NSH_CONSOLE_LOGIN``) with verification method **Encrypted
password file** (``CONFIG_NSH_LOGIN_PASSWD``)
* **Application Configuration** → **File System Utilities** → **Password file
support** (``CONFIG_FSUTILS_PASSWD``)
2. Run ``make``.
Setup workflow
~~~~~~~~~~~~~~
1. ``tools/configure.sh <board>:<config>``
2. ``make menuconfig``:
* **Board Selection** → Auto-generate /etc/passwd
* **Admin password** — required, at least 8 characters. There is no
Kconfig default (the legacy ``Administrator`` password is rejected).
* **Generate random TEA encryption keys automatically** — recommended;
or disable this and set keys manually (see below).
* Confirm NSH uses **Encrypted password file** verification (above).
3. ``make`` — on the first build, ``tools/passwd_keys.mk`` validates the
password and keys, may generate TEA keys, then ``mkpasswd`` runs before
``config.h`` is created so the hash and firmware always agree.
Build-time credentials (CI / automation)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
These values are **not** written to defconfig by ``make savedefconfig``:
* ``CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD``
* ``CONFIG_FSUTILS_PASSWD_KEY1`` … ``CONFIG_FSUTILS_PASSWD_KEY4``
For scripted or CI builds, export the admin password before ``configure.sh``
or ``make``:
.. code:: bash
export NUTTX_ROMFS_PASSWD_PASSWORD="your-password-here"
``tools/update_romfs_password.sh`` copies this into ``.config`` when ROMFS
passwd generation is enabled and the password field is still empty. NuttX
CI sets ``NuttXSimLogin1`` for the ``sim/login`` configuration (a documented
sim-only test credential, not a product secret).
TEA encryption keys
~~~~~~~~~~~~~~~~~~~
Keys must match between the build (``mkpasswd``) and the firmware
(``CONFIG_FSUTILS_PASSWD_KEY1..4``). Choose one option:
``mkpasswd`` and the firmware must use the **same** four 32-bit key words
(``CONFIG_FSUTILS_PASSWD_KEY1`` … ``KEY4``). Choose one approach:
* **Random generation** (``CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS=y``):
On the first build, four keys are generated from ``/dev/urandom`` and
written to ``.config``. Key values are not printed in the build log.
Search ``.config`` for ``CONFIG_FSUTILS_PASSWD_KEY`` to view them.
**Random generation** (``CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS=y``):
* **Manual**: Set ``CONFIG_FSUTILS_PASSWD_KEY1..4`` under Password file
support to unique non-zero values.
On the first ``make`` when keys are missing or still placeholders,
``tools/gen_passwd_keys.sh`` writes random values to ``.config``. A
build warning explains where to view or change them in menuconfig. Key
values are never printed in the build log.
Kconfig options
~~~~~~~~~~~~~~~
**Manual keys** (``CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS`` disabled):
Set ``CONFIG_FSUTILS_PASSWD_KEY1`` … ``KEY4`` under **Application
Configuration** → **File System Utilities** → **Password file support**.
Each must be a unique non-zero value. The legacy published defaults
``0x12345678`` / ``0x9abcdef0`` are rejected.
If random generation is enabled but keys are already present in ``.config``,
they are **not** regenerated (subsequent builds stay consistent).
How the build enforces security
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+---------------------------+-----------------------------------------------+
| Check | Where |
+===========================+===============================================+
| Password set, min 8 chars | ``tools/passwd_keys.mk`` (before ``config.h``)|
| Not ``Administrator`` | ``tools/mkpasswd.c`` (last line of defence) |
| TEA keys configured | ``tools/check_passwd_keys.sh`` |
| Not legacy default keys | ``check_passwd_keys.sh`` + ``mkpasswd.c`` |
+---------------------------+-----------------------------------------------+
Standalone ``mkpasswd`` (advanced)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For debugging only, you may run the host binary directly. You must pass all
four ``--key`` options with non-default values and a password of at least 8
characters:
.. code:: bash
./tools/mkpasswd --user root --password 'my-secret' \
--key1 0x11111111 --key2 0x22222222 \
--key3 0x33333333 --key4 0x44444444
Kconfig summary
~~~~~~~~~~~~~~~~~
Example ``.config`` fragment (password and keys normally **not** in defconfig):
.. code:: kconfig
CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y
CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD="<secret>"
CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS=y
CONFIG_BOARD_ETC_ROMFS_PASSWD_USER="root"
CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD="<set in menuconfig or env>"
CONFIG_NSH_CONSOLE_LOGIN=y
CONFIG_NSH_LOGIN_PASSWD=y
CONFIG_FSUTILS_PASSWD=y
How it works
~~~~~~~~~~~~
1. ``tools/passwd_keys.mk`` checks the password and TEA keys before
``config.h`` is generated.
2. If random generation is enabled and keys are not set, ``gen_passwd_keys.sh``
writes new keys to ``.config``.
3. ``mkpasswd`` hashes the password with the configured TEA keys.
4. The entry is embedded in the ROMFS image as ``/etc/passwd``.
``/etc/passwd`` file format
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -85,9 +151,7 @@ How it works
Notes on ``savedefconfig``
~~~~~~~~~~~~~~~~~~~~~~~~~~
``make savedefconfig`` does not save these options:
* ``CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD``
* ``CONFIG_FSUTILS_PASSWD_KEY1`` through ``CONFIG_FSUTILS_PASSWD_KEY4``
Do not copy them into a defconfig or commit them to version control.
``make savedefconfig`` omits the password and ``KEY1``–``KEY4`` from the
generated defconfig on purpose. ``CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS``
may remain in defconfig (policy, not a secret). Do not commit passwords or
key values to version control.
@@ -494,31 +494,28 @@ mounted at /etc and will look like this at run-time:
start-up script; ``/etc/passwd`` is the password file.
The ``/etc/passwd`` file is auto-generated at build time when
``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE`` is set. Enable the option and set
credentials via ``make menuconfig``:
``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE`` is set. See :ref:`mkpasswd_autogen`
for the full setup (admin password, TEA keys, NSH encrypted-password login).
* ``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y``
* ``CONFIG_BOARD_ETC_ROMFS_PASSWD_USER`` (default: ``root``)
* ``CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD`` (required, build fails if empty)
* Admin password and TEA keys — set in menuconfig (not saved in defconfig)
The password is hashed with TEA at build time by the host tool
``tools/mkpasswd``; the plaintext is **not** stored in the firmware.
For the full description of the mechanism, TEA key configuration, file format,
and verification steps, see :ref:`mkpasswd_autogen`.
The password is hashed with TEA by ``tools/mkpasswd``; the plaintext is **not**
stored in the firmware.
The format of the password file is:
.. code:: text
user:x:uid:gid:home
user:encrypted_hash:uid:gid:home
Where:
user: User name
x: Encrypted password
uid: User ID (0 for now)
gid: Group ID (0 for now)
home: Login directory (/ for now)
encrypted_hash: TEA-encrypted password (base64)
uid: User ID
gid: Group ID
home: Login directory
``/etc/group`` is a group file. It is not currently used.
@@ -1927,10 +1927,14 @@ This is a configuration with login password protection for NSH.
.. note::
This config has password protection enabled. The default login info is:
This config has password protection enabled. After configuring from
defconfig, set the admin password in menuconfig (Board Selection →
Auto-generate /etc/passwd) or export ``NUTTX_ROMFS_PASSWD_PASSWORD``
before building. NuttX CI uses the documented test password
``NuttXSimLogin1`` for this configuration.
* USERNAME: root
* PASSWORD: Administrator
* USERNAME: root (default)
* PASSWORD: set at build time (not stored in defconfig)
The encrypted password is retained in ``/etc/passwd``.
You can disable the password protection by
@@ -2133,41 +2137,30 @@ mounted at ``/etc`` and will look like this at run-time:
start-up script; ``/etc/passwd`` is the password file.
The ``/etc/passwd`` file is auto-generated at build time when
``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE`` is set. Enable the option and set
credentials via ``make menuconfig``:
``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE`` is set. Configure credentials in
``make menuconfig`` (see :ref:`mkpasswd_autogen`):
* ``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y``
* ``CONFIG_NSH_CONSOLE_LOGIN=y`` (required, otherwise login is not enforced)
* ``CONFIG_NSH_CONSOLE_LOGIN=y`` with **Encrypted password file** verification
* ``CONFIG_BOARD_ETC_ROMFS_PASSWD_USER`` (default: ``root``)
* ``CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD`` (required, build fails if empty or shorter than 8 characters)
* Admin password — required in menuconfig or via ``NUTTX_ROMFS_PASSWD_PASSWORD``
(minimum 8 characters; not saved in defconfig)
* TEA keys — enable **Generate random TEA encryption keys automatically**, or
set ``CONFIG_FSUTILS_PASSWD_KEY1`` … ``KEY4`` manually
The password is hashed with TEA at build time by the host tool
``tools/mkpasswd``; the plaintext is **not** stored in the firmware.
The password is hashed with TEA by ``tools/mkpasswd``; the plaintext is **not**
stored in the firmware.
For the full description of the build-time password generation mechanism,
TEA key configuration, file format, and verification steps, see
:ref:`mkpasswd_autogen`.
The format of the password file is:
.. code:: text
user:x:uid:gid:home
Where:
* user: User name
* x: Encrypted password
* uid: User ID (0 for now)
* gid: Group ID (0 for now)
* home: Login directory (/ for now)
For configuration, verification steps, and TEA key details, see
For the full build flow, CI credentials, and verification steps, see
:ref:`mkpasswd_autogen`.
Login test inside the simulator
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Use the admin password you set at build time (menuconfig or
``NUTTX_ROMFS_PASSWD_PASSWORD``). For ``sim/login``, CI uses the documented
test password ``NuttXSimLogin1``; see :ref:`mkpasswd_autogen`.
.. code:: console
$ ./nuttx