!build: add build-time password generation with mkpasswd tool.

Introduce mkpasswd, a pure-C host tool for generating encrypted password
files at build time using TEA encryption. This enables secure,
credential-free firmware images while allowing build-time password
configuration.

Changes:
* Add mkpasswd.c host tool for TEA-based password hashing and encryption
* Integrate mkpasswd into Make build system (tools/Makefile.host)
* Add CMake support for mkpasswd compilation and ROMFS passwd generation
* Add CONFIG_BOARD_ETC_ROMFS_PASSWD_* configuration options to Kconfig
* Implement credential exclusion from defconfig to prevent password leaking
* Update savedefconfig.cmake to strip sensitive credentials
* Fix mkdir() portability for Windows Native builds (CONFIG_WINDOWS_NATIVE)
* Change default username from "admin" to "root" (POSIX convention)
* Improve build-failure error message with full menuconfig navigation path

BREAKING CHANGE: Boards enabling CONFIG_BOARD_ETC_ROMFS_PASSWD_ENABLE
must set CONFIG_BOARD_ETC_ROMFS_PASSWD_PASSWORD to a non-empty string
of at least 8 characters. The build now fails with an explicit error if
this config is left empty. To fix: run 'make menuconfig' and navigate to:
  Board Selection --->
    Auto-generate /etc/passwd at build time --->
      Admin password

Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
This commit is contained in:
Abhishek Mishra
2026-03-20 13:54:21 +00:00
committed by Xiang Xiao
parent ea161e4fa9
commit ab6b1fd6f9
9 changed files with 813 additions and 8 deletions
+18 -1
View File
@@ -30,11 +30,28 @@ $(RCOBJS): $(ETCDIR)$(DELIM)%: %
$(Q) mkdir -p $(dir $@)
$(call PREPROCESS, $<, $@)
$(ETCSRC): $(foreach raw,$(RCRAWS), $(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)))) $(RCOBJS)
$(ETCSRC): $(foreach raw,$(RCRAWS), $(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)))) $(RCOBJS) $(TOPDIR)$(DELIM).config
$(foreach raw, $(RCRAWS), \
$(shell rm -rf $(ETCDIR)$(DELIM)$(raw)) \
$(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) \
--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) \
$(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"
$(Q) echo "#include <nuttx/compiler.h>" > $@
$(Q) xxd -i romfs.img | sed -e "s/^unsigned char/const unsigned char aligned_data(4)/g" >> $@
+50
View File
@@ -5446,3 +5446,53 @@ config BOARD_MEMORY_RANGE
end: end address of memory range
flags: Executable 0x1, Writable 0x2, Readable 0x4
example:{0x1000,0x2000,0x4},{0x2000,0x3000,0x6},{0x3000,0x4000,0x7} ... {0x0,0x0,0x0}
config BOARD_ETC_ROMFS_PASSWD_ENABLE
bool "Auto-generate /etc/passwd at build time"
default n
depends on ETC_ROMFS
---help---
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.
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.
See Documentation/components/passwd_autogen.rst for details.
if BOARD_ETC_ROMFS_PASSWD_ENABLE
config BOARD_ETC_ROMFS_PASSWD_USER
string "Admin username"
default "root"
---help---
The username for the auto-generated /etc/passwd entry.
config BOARD_ETC_ROMFS_PASSWD_PASSWORD
string "Admin password (required)"
default "Administrator"
---help---
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"
default 0
config BOARD_ETC_ROMFS_PASSWD_GID
int "Admin group ID"
default 0
config BOARD_ETC_ROMFS_PASSWD_HOME
string "Admin home directory"
default "/"
endif # BOARD_ETC_ROMFS_PASSWD_ENABLE