Revert "!boards: enforce secure ROMFS passwd and TEA key setup"

This reverts commit f5291a8df1.

Signed-off-by: Alin Jerpelea <alin.jerpelea@sony.com>
This commit is contained in:
Alin Jerpelea 2026-08-03 15:32:58 +02:00 • committed by CeDeROM
parent c96ed0119a
commit 1017d76dd9
9 changed files with 142 additions and 456 deletions

View file

@ -17,77 +17,107 @@ 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`` is a C host tool (compiled from ``tools/mkpasswd.c``) that
generates a single ``/etc/passwd`` entry at build time. It is invoked
automatically by the ROMFS build step when
``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y`` is set.
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.
Why build-time generation?
~~~~~~~~~~~~~~~~~~~~~~~~~~
Setup
~~~~~
Shipping a hard-coded default password in firmware is a well-known security
weakness (CWE-798). By generating the ``/etc/passwd`` entry from a
user-supplied plaintext password at build time, each firmware image carries
unique credentials. The build will fail if the password is left empty,
preventing accidental deployments with no credentials.
1. Run ``make menuconfig`` and configure:
* **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
2. Run ``make``.
TEA encryption keys
~~~~~~~~~~~~~~~~~~~
Keys must match between the build (``mkpasswd``) and the firmware
(``CONFIG_FSUTILS_PASSWD_KEY1..4``). Choose one option:
* **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.
* **Manual**: Set ``CONFIG_FSUTILS_PASSWD_KEY1..4`` under Password file
support to unique non-zero values.
Kconfig options
~~~~~~~~~~~~~~~
.. 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_NSH_CONSOLE_LOGIN=y
CONFIG_NSH_LOGIN_PASSWD=y
CONFIG_FSUTILS_PASSWD=y
For improved baseline security, the configured password must be at least
8 characters long.
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``.
1. The host tool reads the plaintext password from
``CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD``.
2. The password is hashed using the Tiny Encryption Algorithm (TEA) — the
same implementation used at runtime in
``libs/libc/misc/lib_tea_encrypt.c`` — with custom base64 encoding
matching ``apps/fsutils/passwd/passwd_encrypt.c``.
3. The resulting hashed entry is written to
``etctmp/<mountpoint>/passwd`` and then embedded into the ROMFS image.
4. The **plaintext password is never stored in the firmware image**.
Kconfig options
~~~~~~~~~~~~~~~
Enable the feature and configure credentials via ``make menuconfig``:
.. code:: kconfig
CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE=y
CONFIG_NSH_CONSOLE_LOGIN=y # required to enforce login prompt
CONFIG_BOARD_ETC_ROMFS_PASSWD_USER="root" # default: root
CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD="<secret>" # required, min length 8
CONFIG_BOARD_ETC_ROMFS_PASSWD_UID=0
CONFIG_BOARD_ETC_ROMFS_PASSWD_GID=0
CONFIG_BOARD_ETC_ROMFS_PASSWD_HOME="/"
The TEA encryption keys can be changed from their defaults via
``CONFIG_FSUTILS_PASSWD_KEY1..4``.
``/etc/passwd`` file format
~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: text
user:encrypted_hash:uid:gid:home
user:x:uid:gid:home
Where:
* ``user`` — user name
* ``x`` — TEA-hashed, base64-encoded password
* ``uid`` — numeric user ID
* ``gid`` — numeric group ID
* ``home`` — login directory
Verifying the generated entry
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
After enabling ``CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE`` and setting a
password, rebuild and verify:
1. **Configure and build**:
.. code:: console
$ make menuconfig # enable BOARD_ETC_ROMFS_PASSWD_ENABLE and set password
$ make
2. **Inspect the generated passwd line** (written to the board build tree):
.. code:: console
$ cat boards/<arch>/<chip>/<board>/src/etctmp/etc/passwd
root:8Tv+Hbmr3pLVb5HHZgd26D:0:0:/
3. **Verify the plaintext is absent from firmware**:
.. code:: console
$ grep <your-password> boards/<arch>/<chip>/<board>/src/etctmp.c
# must print nothing
Notes on ``savedefconfig``
~~~~~~~~~~~~~~~~~~~~~~~~~~
``make savedefconfig`` does not save these options:
To avoid leaking credentials into board defconfigs, ``make savedefconfig``
does not save the following options in the generated defconfig:
* ``CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD``
* ``CONFIG_FSUTILS_PASSWD_KEY1`` through ``CONFIG_FSUTILS_PASSWD_KEY4``
* ``CONFIG_FSUTILS_PASSWD_KEY1``
* ``CONFIG_FSUTILS_PASSWD_KEY2``
* ``CONFIG_FSUTILS_PASSWD_KEY3``
* ``CONFIG_FSUTILS_PASSWD_KEY4``
Do not copy them into a defconfig or commit them to version control.
If you need these values for local development, add them manually to your
local defconfig after running ``make savedefconfig``.

View file

@ -31,7 +31,6 @@ ifeq ($(wildcard .config),)
@echo " tools/configure.sh -L"
else
include .config
include tools/passwd_keys.mk
# Include the correct Makefile for the selected architecture.

View file

@ -36,6 +36,9 @@ $(ETCSRC): $(foreach raw,$(RCRAWS), $(if $(wildcard $(BOARD_DIR)$(DELIM)src$(DEL
$(shell mkdir -p $(dir $(ETCDIR)$(DELIM)$(raw))) \
$(shell cp -rfp $(if $(wildcard $(BOARD_DIR)$(DELIM)src$(DELIM)$(raw)), $(BOARD_DIR)$(DELIM)src$(DELIM)$(raw), $(if $(wildcard $(BOARD_COMMON_DIR)$(DELIM)$(raw)), $(BOARD_COMMON_DIR)$(DELIM)$(raw), $(BOARD_DIR)$(DELIM)src$(DELIM)$(raw))) $(ETCDIR)$(DELIM)$(raw)))
ifeq ($(CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE),y)
ifeq ($(strip $(patsubst "%",%,$(CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD))),)
$(error CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD must be set when BOARD_ETC_ROMFS_PASSWD_ENABLE is enabled. Run 'make menuconfig' and select a password at: Board Selection ---> Auto-generate /etc/passwd at build time ---> Admin password)
endif
$(Q) mkdir -p $(ETCDIR)$(DELIM)$(CONFIG_ETC_ROMFSMOUNTPT)
$(Q) $(TOPDIR)$(DELIM)tools$(DELIM)mkpasswd$(HOSTEXEEXT) \
--user $(CONFIG_BOARD_ETC_ROMFS_PASSWD_USER) \
@ -43,10 +46,10 @@ ifeq ($(CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE),y)
--uid $(CONFIG_BOARD_ETC_ROMFS_PASSWD_UID) \
--gid $(CONFIG_BOARD_ETC_ROMFS_PASSWD_GID) \
--home $(CONFIG_BOARD_ETC_ROMFS_PASSWD_HOME) \
--key1 $(CONFIG_FSUTILS_PASSWD_KEY1) \
--key2 $(CONFIG_FSUTILS_PASSWD_KEY2) \
--key3 $(CONFIG_FSUTILS_PASSWD_KEY3) \
--key4 $(CONFIG_FSUTILS_PASSWD_KEY4) \
$(if $(CONFIG_FSUTILS_PASSWD_KEY1),--key1 $(CONFIG_FSUTILS_PASSWD_KEY1)) \
$(if $(CONFIG_FSUTILS_PASSWD_KEY2),--key2 $(CONFIG_FSUTILS_PASSWD_KEY2)) \
$(if $(CONFIG_FSUTILS_PASSWD_KEY3),--key3 $(CONFIG_FSUTILS_PASSWD_KEY3)) \
$(if $(CONFIG_FSUTILS_PASSWD_KEY4),--key4 $(CONFIG_FSUTILS_PASSWD_KEY4)) \
-o $(ETCDIR)$(DELIM)$(CONFIG_ETC_ROMFSMOUNTPT)$(DELIM)passwd
endif
$(Q) genromfs -f romfs.img -d $(ETCDIR)$(DELIM)$(CONFIG_ETC_ROMFSMOUNTPT) -V "NSHInitVol"

View file

@ -5541,23 +5541,21 @@ config BOARD_ETC_ROMFS_PASSWD_ENABLE
default n
depends on ETC_ROMFS
---help---
Generate /etc/passwd at build time. The password is hashed with TEA
by tools/mkpasswd; the plaintext is not stored in the firmware.
Generate the /etc/passwd file at build time from a user-supplied
password. This avoids shipping a hard-coded default password
(CWE-798). When enabled, the build will fail if no password
is configured, forcing each build to set its own credentials.
Before building, set:
1. Admin password (below)
2. TEA keys — enable random generation below, or set
CONFIG_FSUTILS_PASSWD_KEY1..4 in Application Configuration ->
File System Utilities -> Password file support
The password is hashed at build time by the host tool
tools/mkpasswd (compiled from tools/mkpasswd.c) using the Tiny
Encryption Algorithm (TEA) — the same algorithm used at runtime
in libs/libc/misc/lib_tea_encrypt.c. The plaintext password is
never stored in the firmware image.
Also enable NSH login with "Encrypted password file" verification.
Password and keys are not saved in defconfig. Do not commit them.
See Documentation/components/passwd_autogen.rst for details.
if BOARD_ETC_ROMFS_PASSWD_ENABLE
comment "--- Step 1: set the admin password below ---"
config BOARD_ETC_ROMFS_PASSWD_USER
string "Admin username"
default "root"
@ -5565,39 +5563,14 @@ config BOARD_ETC_ROMFS_PASSWD_USER
The username for the auto-generated /etc/passwd entry.
config BOARD_ETC_ROMFS_PASSWD_PASSWORD
string "Admin password (required, no default)"
string "Admin password (required)"
default "Administrator"
---help---
The plaintext password for the /etc/passwd entry. No default is
provided. The build fails if this is empty or shorter than 8
characters.
Not saved in defconfig.
comment "--- Step 2: choose how to supply the TEA encryption keys ---"
config BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS
bool "Generate random TEA encryption keys automatically"
default n
---help---
Generate four random TEA keys from /dev/urandom and write them
to .config on the first build. The same keys are used for the
/etc/passwd hash and the firmware.
make menuconfig # set password, enable this option
make
Key values are not printed in the build log. Search .config for
CONFIG_FSUTILS_PASSWD_KEY to view them.
Do not copy keys or the password into a defconfig or commit
them to version control.
If disabled, set CONFIG_FSUTILS_PASSWD_KEY1..4 manually under
Application Configuration -> File System Utilities ->
Password file support.
comment " If not randomizing: set KEY1..4 at App Config -> File System Utilities -> Password file support"
depends on !BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS
The plaintext password for the auto-generated /etc/passwd entry.
This value is hashed with TEA at build time; the plaintext is NOT
stored in the firmware image. The build will fail if this is left
empty or shorter than 8 characters. Set this via
'make menuconfig'.
config BOARD_ETC_ROMFS_PASSWD_UID
int "Admin user ID"

View file

@ -287,17 +287,9 @@ function(process_all_directory_romfs)
if("${CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD}" STREQUAL "")
message(
FATAL_ERROR
"\n"
" BUILD ERROR: Admin password not set.\n"
"\n"
" Run make menuconfig and set:\n"
" Board Selection -> Auto-generate /etc/passwd -> Admin password\n"
"\n"
" For TEA keys, either enable random generation in the same menu,\n"
" or set CONFIG_FSUTILS_PASSWD_KEY1..4 under Application Configuration\n"
" -> File System Utilities -> Password file support.\n"
"\n"
" Password and keys are not saved in defconfig.\n")
"CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD must be set when "
"BOARD_ETC_ROMFS_PASSWD_ENABLE is enabled. Run 'make menuconfig' "
"to set a password.")
endif()
# Determine host executable suffix (.exe on Windows, empty elsewhere)
@ -325,77 +317,22 @@ function(process_all_directory_romfs)
add_custom_target(build_host_mkpasswd DEPENDS ${MKPASSWD_BIN})
endif()
# Pass TEA key overrides when the user has changed them from defaults
set(MKPASSWD_KEY_ARGS "")
if(CONFIG_FSUTILS_PASSWD_KEY1)
list(APPEND MKPASSWD_KEY_ARGS --key1 ${CONFIG_FSUTILS_PASSWD_KEY1})
endif()
if(CONFIG_FSUTILS_PASSWD_KEY2)
list(APPEND MKPASSWD_KEY_ARGS --key2 ${CONFIG_FSUTILS_PASSWD_KEY2})
endif()
if(CONFIG_FSUTILS_PASSWD_KEY3)
list(APPEND MKPASSWD_KEY_ARGS --key3 ${CONFIG_FSUTILS_PASSWD_KEY3})
endif()
if(CONFIG_FSUTILS_PASSWD_KEY4)
list(APPEND MKPASSWD_KEY_ARGS --key4 ${CONFIG_FSUTILS_PASSWD_KEY4})
endif()
set(GENPASSWD_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/etc/passwd)
# Delegate detection and generation to the shell helpers so the logic is
# testable outside of cmake. check_passwd_keys.sh prints "yes" when keys
# are absent or at insecure defaults; gen_passwd_keys.sh writes fresh
# /dev/urandom values in-place.
#
# RANDOMIZE_KEYS — single-invocation path: 1. gen_passwd_keys.sh writes new
# keys to .config at configure time. 2. We re-read .config below so
# CONFIG_FSUTILS_PASSWD_KEY1..4 carry the new values for the rest of this
# cmake configure run. 3. add_custom_command is registered with the updated
# key values, so both mkpasswd (passwd hash) and the firmware use the same
# keys — login works without a second cmake invocation.
#
# Note: config.h is regenerated at build time from .config (its dependency),
# so the firmware uses the correct keys automatically.
execute_process(
COMMAND "${NUTTX_DIR}/tools/check_passwd_keys.sh" "${NUTTX_DIR}/.config"
OUTPUT_VARIABLE _passwd_keys_need_setup
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE _check_rc)
if(NOT _check_rc EQUAL 0)
message(
FATAL_ERROR
"check_passwd_keys.sh failed — check ${NUTTX_DIR}/tools/check_passwd_keys.sh"
)
endif()
if(_passwd_keys_need_setup STREQUAL "yes")
if(CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS)
# Generate keys and write to .config (no key values printed here)
execute_process(
COMMAND "${NUTTX_DIR}/tools/gen_passwd_keys.sh" "${NUTTX_DIR}/.config"
RESULT_VARIABLE _gen_rc
OUTPUT_QUIET)
if(NOT _gen_rc EQUAL 0)
message(
FATAL_ERROR
"gen_passwd_keys.sh failed — check ${NUTTX_DIR}/.config permissions"
)
endif()
message(
STATUS
"[passwd] TEA keys written to .config (search for CONFIG_FSUTILS_PASSWD_KEY to view)"
)
# Re-read .config so the new key values are live for this configure run
# (mirrors Board.mk's second -include).
file(STRINGS "${NUTTX_DIR}/.config" _fresh_config
REGEX "^CONFIG_FSUTILS_PASSWD_KEY[1-4]=")
foreach(_line ${_fresh_config})
if(_line MATCHES "^CONFIG_FSUTILS_PASSWD_KEY([1-4])=(.+)$")
set(CONFIG_FSUTILS_PASSWD_KEY${CMAKE_MATCH_1} "${CMAKE_MATCH_2}")
endif()
endforeach()
else()
message(
FATAL_ERROR
"\n"
" BUILD ERROR: TEA encryption keys not configured.\n"
"\n"
" Run make menuconfig and either:\n"
" - enable Generate random TEA keys automatically, or\n"
" - set CONFIG_FSUTILS_PASSWD_KEY1..4 under Application Configuration\n"
" -> File System Utilities -> Password file support\n")
endif()
endif()
# At this point KEY1..4 are guaranteed to be correct (either freshly
# generated above, or manually set by the user).
add_custom_command(
OUTPUT ${GENPASSWD_OUTPUT}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/etc
@ -404,13 +341,10 @@ function(process_all_directory_romfs)
--password "${CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD}" --uid
${CONFIG_BOARD_ETC_ROMFS_PASSWD_UID} --gid
${CONFIG_BOARD_ETC_ROMFS_PASSWD_GID} --home
"${CONFIG_BOARD_ETC_ROMFS_PASSWD_HOME}" --key1
${CONFIG_FSUTILS_PASSWD_KEY1} --key2 ${CONFIG_FSUTILS_PASSWD_KEY2}
--key3 ${CONFIG_FSUTILS_PASSWD_KEY3} --key4
${CONFIG_FSUTILS_PASSWD_KEY4} -o ${GENPASSWD_OUTPUT}
"${CONFIG_BOARD_ETC_ROMFS_PASSWD_HOME}" ${MKPASSWD_KEY_ARGS} -o
${GENPASSWD_OUTPUT}
DEPENDS ${MKPASSWD_BIN} ${NUTTX_DIR}/.config
COMMENT "Generating /etc/passwd from .config TEA keys")
COMMENT "Generating /etc/passwd from Kconfig values")
add_custom_target(generate_passwd DEPENDS ${GENPASSWD_OUTPUT})
add_dependencies(generate_passwd build_host_mkpasswd)
list(APPEND RCRAWS ${GENPASSWD_OUTPUT})

View file

@ -1,82 +0,0 @@
#!/usr/bin/env sh
# tools/check_passwd_keys.sh
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Usage:
# check_passwd_keys.sh <path-to-.config>
#
# Prints "yes" to stdout when CONFIG_FSUTILS_PASSWD_KEY1..4 need setup:
# - any key is absent or "is not set"
# - all four equal the known-insecure Kconfig defaults
# Prints "no" when all four are present and non-default.
# Idempotent; no side effects.
set -e
CONFIG="${1}"
if [ -z "${CONFIG}" ]; then
printf 'Usage: check_passwd_keys.sh <path-to-.config>\n' >&2
exit 1
fi
if [ ! -f "${CONFIG}" ]; then
printf 'check_passwd_keys: file not found: %s\n' "${CONFIG}" >&2
exit 1
fi
# Known-insecure placeholder/default values — must not be used in a build.
DEFAULT1=0x12345678
DEFAULT2=0x9abcdef0
DEFAULT3=0x12345678
DEFAULT4=0x9abcdef0
# Return the assigned value of CONFIG_FSUTILS_PASSWD_KEY<n>, or empty
# string when the line is absent or commented as "is not set".
get_val() {
grep -E "^CONFIG_FSUTILS_PASSWD_KEY${1}=" "${CONFIG}" 2>/dev/null \
| tail -n 1 \
| sed 's/^[^=]*=//'
}
# True when the value is unset or still at the Kconfig placeholder (0).
is_placeholder() {
case "$1" in
''|0|0x0|0x00000000) return 0 ;;
*) return 1 ;;
esac
}
K1=$(get_val 1)
K2=$(get_val 2)
K3=$(get_val 3)
K4=$(get_val 4)
# Any key absent, empty, or placeholder → needs setup
if is_placeholder "${K1}" || is_placeholder "${K2}" || \
is_placeholder "${K3}" || is_placeholder "${K4}"; then
echo yes
exit 0
fi
# All four at the known insecure defaults → needs setup
if [ "${K1}" = "${DEFAULT1}" ] && [ "${K2}" = "${DEFAULT2}" ] && \
[ "${K3}" = "${DEFAULT3}" ] && [ "${K4}" = "${DEFAULT4}" ]; then
echo yes
exit 0
fi
echo no

View file

@ -1,89 +0,0 @@
#!/usr/bin/env sh
# tools/gen_passwd_keys.sh
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Usage:
# gen_passwd_keys.sh <path-to-.config>
#
# Generates four random 32-bit TEA key values from /dev/urandom and
# writes/replaces CONFIG_FSUTILS_PASSWD_KEY1..4 in the target .config file.
# Handles both "line exists (replace)" and "line missing (append)" cases.
#
# Key values are NOT printed to stdout or stderr. Search the .config file
# for CONFIG_FSUTILS_PASSWD_KEY to view them if needed.
#
# Exit 0 on success, non-zero with a message on failure.
set -e
CONFIG="${1}"
if [ -z "${CONFIG}" ]; then
printf 'Usage: gen_passwd_keys.sh <path-to-.config>\n' >&2
exit 1
fi
if [ ! -f "${CONFIG}" ]; then
printf 'gen_passwd_keys: file not found: %s\n' "${CONFIG}" >&2
exit 1
fi
# Generate a random 32-bit hex value via /dev/urandom.
# Uses od -tx4 which always produces exactly 8 hex digits.
rand_key() {
dd if=/dev/urandom bs=4 count=1 2>/dev/null \
| od -An -tx4 \
| tr -d ' \n'
}
K1="0x$(rand_key)"
K2="0x$(rand_key)"
K3="0x$(rand_key)"
K4="0x$(rand_key)"
# Remove any existing definitions (assigned or "is not set") everywhere.
sed -i \
'/^# CONFIG_FSUTILS_PASSWD_KEY[1-4] is not set/d;
/^CONFIG_FSUTILS_PASSWD_KEY[1-4]=/d' \
"${CONFIG}" || {
printf 'gen_passwd_keys: ERROR: failed to edit %s (check permissions)\n' \
"${CONFIG}" >&2
exit 1
}
# Insert keys in the FSUTILS_PASSWD section when it exists so menuconfig
# and mkconfig see a single canonical copy (not orphaned lines at EOF).
if grep -q '^CONFIG_FSUTILS_PASSWD_IOBUFFER_SIZE=' "${CONFIG}"; then
sed -i "/^CONFIG_FSUTILS_PASSWD_IOBUFFER_SIZE=/a\\
CONFIG_FSUTILS_PASSWD_KEY1=${K1}\\
CONFIG_FSUTILS_PASSWD_KEY2=${K2}\\
CONFIG_FSUTILS_PASSWD_KEY3=${K3}\\
CONFIG_FSUTILS_PASSWD_KEY4=${K4}" "${CONFIG}" || {
printf 'gen_passwd_keys: ERROR: failed to insert keys into %s\n' \
"${CONFIG}" >&2
exit 1
}
else
printf 'CONFIG_FSUTILS_PASSWD_KEY1=%s\nCONFIG_FSUTILS_PASSWD_KEY2=%s\nCONFIG_FSUTILS_PASSWD_KEY3=%s\nCONFIG_FSUTILS_PASSWD_KEY4=%s\n' \
"${K1}" "${K2}" "${K3}" "${K4}" >> "${CONFIG}" || {
printf 'gen_passwd_keys: ERROR: failed to append keys to %s\n' \
"${CONFIG}" >&2
exit 1
}
fi
printf 'TEA keys generated and written to %s.\nSearch %s for CONFIG_FSUTILS_PASSWD_KEY to view if needed.\n' \
"${CONFIG}" "${CONFIG}"

View file

@ -529,10 +529,7 @@ int main(int argc, char **argv)
if (password[0] == '\0')
{
fprintf(stderr,
"mkpasswd: ERROR: password must not be empty.\n"
" Set it in menuconfig: Board Selection -> "
"Auto-generate /etc/passwd -> Admin password\n");
fprintf(stderr, "mkpasswd: --password must not be empty\n");
return 1;
}
@ -544,35 +541,30 @@ int main(int argc, char **argv)
return 1;
}
/* Reject the well-known default password. The build system should have
* caught this already; mkpasswd is the last line of defence.
*/
/* Warn if the board Kconfig default password is still being used. */
if (strcmp(password, "Administrator") == 0)
{
fprintf(stderr,
"mkpasswd: ERROR: password \"Administrator\" is not allowed.\n"
" Set a unique password in menuconfig: Board Selection -> "
"Auto-generate /etc/passwd -> Admin password\n");
return 1;
">>>> WARNING: YOU ARE USING THE DEFAULT ADMIN PASSWORD "
"(CONFIG_BOARD_ETC_ROMFS_"
"PASSWD_PASSWORD=\"Administrator\")!!! PLEASE CHANGE "
"IT!!! <<<<\n");
}
/* Reject the default TEA keys. Using the published defaults means any
* attacker who has a copy of the NuttX source can decrypt the password
* hash directly from the firmware image (CWE-321).
/* Warn when the user has not changed the default TEA keys.
* The default values are identical across all NuttX builds, so any
* attacker with access to the firmware image can recover the plaintext
* password. This is a warning only; the build is not aborted.
*/
if (key[0] == DEFAULT_KEY1 && key[1] == DEFAULT_KEY2 &&
key[2] == DEFAULT_KEY3 && key[3] == DEFAULT_KEY4)
{
fprintf(stderr,
"mkpasswd: ERROR: default TEA encryption keys "
"are not allowed.\n"
" Set keys in menuconfig: Application Configuration -> "
"File System Utilities -> Password file support\n"
" Or enable random key generation under Board Selection -> "
"Auto-generate /etc/passwd\n");
return 1;
">>>> WARNING: YOU ARE USING DEFAULT PASSWORD KEYS "
"(CONFIG_FSUTILS_"
"PASSWD_KEY1-4)!!! PLEASE CHANGE IT!!! <<<<\n");
}
/* Encrypt the password using TEA + custom base64.

View file

@ -1,74 +0,0 @@
############################################################################
# tools/passwd_keys.mk
#
# SPDX-License-Identifier: Apache-2.0
#
# Passwd / TEA-key validation and generation. Included from the top-level
# Makefile immediately after .config is loaded, BEFORE tools/Unix.mk builds
# include/nuttx/config.h. This ordering guarantees that freshly generated
# keys are present in .config when config.h is created, so the firmware and
# mkpasswd always agree on the same key values in a single make invocation.
#
# Board.mk only consumes CONFIG_FSUTILS_PASSWD_KEY1..4 in the ROMFS recipe.
############################################################################
TOPDIR ?= .
# Skip enforcement during configuration-only make invocations (menuconfig,
# olddefconfig, clean_context, etc.) so the user can set the password first.
PASSWD_SKIP_GOALS := config menuconfig oldconfig olddefconfig savedefconfig \
nconfig qconfig gconfig clean_context apps_preconfig \
apps_config apps_menuconfig apps_oldconfig apps_olddefconfig \
apps_savedefconfig apps_nconfig apps_qconfig apps_gconfig \
distclean clean
ifeq ($(MAKECMDGOALS),)
_PASSWD_ENFORCE := y
else
_PASSWD_ENFORCE := $(if $(filter-out $(PASSWD_SKIP_GOALS),$(MAKECMDGOALS)),y,)
endif
ifeq ($(CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE),y)
ifeq ($(_PASSWD_ENFORCE),y)
# --- password check ---
ifeq ($(strip $(patsubst "%",%,$(CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD))),)
$(info )
$(info BUILD ERROR: Admin password not set.)
$(info )
$(info Run make menuconfig and set:)
$(info Board Selection -> Auto-generate /etc/passwd -> Admin password)
$(info )
$(info For TEA keys, either enable random generation in the same menu,)
$(info or set CONFIG_FSUTILS_PASSWD_KEY1..4 under Application Configuration)
$(info -> File System Utilities -> Password file support.)
$(info )
$(info Password and keys are not saved in defconfig.)
$(info )
$(error Aborting: CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD is not set)
endif
# --- TEA key check / generation ---
_PASSWD_KEYS_NEED_SETUP := $(shell \
$(TOPDIR)/tools/check_passwd_keys.sh $(TOPDIR)/.config 2>/dev/null)
ifneq ($(_PASSWD_KEYS_NEED_SETUP),no)
ifeq ($(CONFIG_BOARD_ETC_ROMFS_PASSWD_RANDOMIZE_KEYS),y)
$(shell $(TOPDIR)/tools/gen_passwd_keys.sh $(TOPDIR)/.config >/dev/null)
$(info [passwd] TEA keys written to .config (search for CONFIG_FSUTILS_PASSWD_KEY to view))
include $(TOPDIR)/.config
else
$(info )
$(info BUILD ERROR: TEA encryption keys not configured.)
$(info )
$(info Run make menuconfig and either:)
$(info - enable Generate random TEA keys automatically, or)
$(info - set CONFIG_FSUTILS_PASSWD_KEY1..4 under Application Configuration)
$(info -> File System Utilities -> Password file support)
$(info )
$(error Aborting: CONFIG_FSUTILS_PASSWD_KEY1..4 must be set to non-default values)
endif
endif
endif
endif