diff --git a/netutils/dropbear/CMakeLists.txt b/netutils/dropbear/CMakeLists.txt index 8ca691be094..4261c2bc0ed 100644 --- a/netutils/dropbear/CMakeLists.txt +++ b/netutils/dropbear/CMakeLists.txt @@ -63,6 +63,11 @@ if(CONFIG_NETUTILS_DROPBEAR) patch -s -N -l -p1 -d "${DROPBEAR_UNPACKNAME}" -i "${CMAKE_CURRENT_SOURCE_DIR}/patch/0004-use-nuttx-unused-macro.patch" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") + execute_process( + COMMAND + patch -s -N -l -p1 -d "${DROPBEAR_UNPACKNAME}" -i + "${CMAKE_CURRENT_SOURCE_DIR}/patch/0005-use-nuttx-sha256-hmac.patch" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") message(STATUS "Generating default_options_guard.h") execute_process( COMMAND @@ -135,6 +140,17 @@ if(CONFIG_NETUTILS_DROPBEAR) file(GLOB_RECURSE LIBTOMCRYPT_SRCS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/dropbear/libtomcrypt/src/*.c") list(FILTER LIBTOMCRYPT_SRCS EXCLUDE REGEX ".*/prngs/sober128tab\\.c$") + + if(CONFIG_NETUTILS_DROPBEAR_NUTTX_CRYPTO) + # Drop the bundled libtomcrypt modules replaced by the NuttX adapters. + list(FILTER LIBTOMCRYPT_SRCS EXCLUDE REGEX ".*/hashes/sha2/sha256\\.c$") + list(FILTER LIBTOMCRYPT_SRCS EXCLUDE REGEX ".*/mac/hmac/hmac_init\\.c$") + list(FILTER LIBTOMCRYPT_SRCS EXCLUDE REGEX ".*/mac/hmac/hmac_process\\.c$") + list(FILTER LIBTOMCRYPT_SRCS EXCLUDE REGEX ".*/mac/hmac/hmac_done\\.c$") + list(APPEND DROPBEAR_SRCS port/dropbear_ltc_sha256.c + port/dropbear_ltc_hmac_sha256.c) + endif() + list(APPEND DROPBEAR_SRCS ${LIBTOMCRYPT_SRCS}) if(CONFIG_NETUTILS_DROPBEAR_SCP) @@ -195,6 +211,11 @@ if(CONFIG_NETUTILS_DROPBEAR) ${PROGNAME} PRIVATE LOCALOPTIONS_H_EXISTS=1 DROPBEAR_NUTTX=1 DROPBEAR_NUTTX_PASSWD=1) + if(CONFIG_NETUTILS_DROPBEAR_NUTTX_CRYPTO) + target_compile_definitions(${PROGNAME} PRIVATE DROPBEAR_NUTTX_SHA256=1 + DROPBEAR_NUTTX_HMAC_SHA256=1) + endif() + if(CONFIG_NETUTILS_DROPBEAR_SCP) target_compile_definitions( scp PRIVATE LOCALOPTIONS_H_EXISTS=1 DROPBEAR_NUTTX=1 diff --git a/netutils/dropbear/Kconfig b/netutils/dropbear/Kconfig index 94eee878c80..d86775afda3 100644 --- a/netutils/dropbear/Kconfig +++ b/netutils/dropbear/Kconfig @@ -90,6 +90,16 @@ config NETUTILS_DROPBEAR_SCP_PRIORITY default 100 depends on NETUTILS_DROPBEAR_SCP +config NETUTILS_DROPBEAR_NUTTX_CRYPTO + bool "Use NuttX kernel crypto primitives" + default y + depends on BUILD_FLAT + ---help--- + Back Dropbear's SHA-256 and HMAC-SHA256 primitives with the NuttX + kernel crypto implementation instead of the bundled libtomcrypt + modules, reducing flash usage. This requires a flat build because + Dropbear calls the kernel crypto functions directly. + config NETUTILS_DROPBEAR_PORT int "Dropbear listen port" default 2222 diff --git a/netutils/dropbear/Makefile b/netutils/dropbear/Makefile index 53b1f2f720b..dab411d5725 100644 --- a/netutils/dropbear/Makefile +++ b/netutils/dropbear/Makefile @@ -63,6 +63,11 @@ CFLAGS += ${DEFINE_PREFIX}DROPBEAR_NUTTX=1 CFLAGS += ${DEFINE_PREFIX}DROPBEAR_NUTTX_PASSWD=1 CFLAGS += -Wno-pointer-sign -Wno-format +ifneq ($(CONFIG_NETUTILS_DROPBEAR_NUTTX_CRYPTO),) +CFLAGS += ${DEFINE_PREFIX}DROPBEAR_NUTTX_SHA256=1 +CFLAGS += ${DEFINE_PREFIX}DROPBEAR_NUTTX_HMAC_SHA256=1 +endif + dropbear_nshsession.c_CFLAGS += ${DEFINE_PREFIX}Channel=dropbear_channel dropbear_nshsession.c_CFLAGS += ${DEFINE_PREFIX}ChanType=dropbear_chantype @@ -119,6 +124,20 @@ CSRCS += \ TOMMATH_SRCS = $(shell if [ -d "$(DROPBEAR_UNPACKNAME)/libtommath" ]; then find "$(DROPBEAR_UNPACKNAME)/libtommath" -name "*.c"; fi) TOMCRYPT_SRCS = $(shell if [ -d "$(DROPBEAR_UNPACKNAME)/libtomcrypt/src" ]; then find "$(DROPBEAR_UNPACKNAME)/libtomcrypt/src" -name "*.c" ! -name "sober128tab.c"; fi) +ifneq ($(CONFIG_NETUTILS_DROPBEAR_NUTTX_CRYPTO),) +# Drop the bundled libtomcrypt modules replaced by the NuttX adapters. + +TOMCRYPT_SRCS := $(filter-out \ + %/hashes/sha2/sha256.c \ + %/mac/hmac/hmac_init.c \ + %/mac/hmac/hmac_process.c \ + %/mac/hmac/hmac_done.c, \ + $(TOMCRYPT_SRCS)) + +CSRCS += port/dropbear_ltc_sha256.c +CSRCS += port/dropbear_ltc_hmac_sha256.c +endif + CSRCS += $(TOMMATH_SRCS) CSRCS += $(TOMCRYPT_SRCS) @@ -161,6 +180,7 @@ $(DROPBEAR_UNPACKNAME): $(DROPBEAR_ZIP) $(Q) $(PATCH) -s -N -l -p1 -d $(DROPBEAR_UNPACKNAME) -i $(APPDIR)$(DELIM)netutils$(DELIM)dropbear$(DELIM)patch$(DELIM)0002-use-nuttx-passwd-auth.patch; true $(Q) $(PATCH) -s -N -l -p1 -d $(DROPBEAR_UNPACKNAME) -i $(APPDIR)$(DELIM)netutils$(DELIM)dropbear$(DELIM)patch$(DELIM)0003-allow-localoptions-to-override-tracking-malloc.patch; true $(Q) $(PATCH) -s -N -l -p1 -d $(DROPBEAR_UNPACKNAME) -i $(APPDIR)$(DELIM)netutils$(DELIM)dropbear$(DELIM)patch$(DELIM)0004-use-nuttx-unused-macro.patch; true + $(Q) $(PATCH) -s -N -l -p1 -d $(DROPBEAR_UNPACKNAME) -i $(APPDIR)$(DELIM)netutils$(DELIM)dropbear$(DELIM)patch$(DELIM)0005-use-nuttx-sha256-hmac.patch; true @echo "Generating default_options_guard.h" $(Q) sh $(DROPBEAR_UNPACKNAME)$(DELIM)src$(DELIM)ifndef_wrapper.sh \ < $(DROPBEAR_UNPACKNAME)$(DELIM)src$(DELIM)default_options.h \ diff --git a/netutils/dropbear/patch/0005-use-nuttx-sha256-hmac.patch b/netutils/dropbear/patch/0005-use-nuttx-sha256-hmac.patch new file mode 100644 index 00000000000..6aa1e174437 --- /dev/null +++ b/netutils/dropbear/patch/0005-use-nuttx-sha256-hmac.patch @@ -0,0 +1,45 @@ +--- a/libtomcrypt/src/headers/tomcrypt_hash.h ++++ b/libtomcrypt/src/headers/tomcrypt_hash.h +@@ -30,11 +30,18 @@ struct sha512_state { + #endif + + #ifdef LTC_SHA256 ++#ifdef DROPBEAR_NUTTX_SHA256 ++#include ++struct sha256_state { ++ SHA2_CTX ctx; ++}; ++#else + struct sha256_state { + ulong64 length; + ulong32 state[8], curlen; + unsigned char buf[64]; + }; ++#endif + #endif + + #ifdef LTC_SHA1 +--- a/libtomcrypt/src/headers/tomcrypt_mac.h ++++ b/libtomcrypt/src/headers/tomcrypt_mac.h +@@ -7,6 +7,13 @@ + */ + + #ifdef LTC_HMAC ++#ifdef DROPBEAR_NUTTX_HMAC_SHA256 ++#include ++typedef struct Hmac_state { ++ HMAC_SHA256_CTX ctx; ++ int hash; ++} hmac_state; ++#else + typedef struct Hmac_state { + hash_state md; + int hash; +@@ -14,6 +21,7 @@ typedef struct Hmac_state { + unsigned char *key; + } hmac_state; + ++#endif + int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen); + int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen); + int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen); diff --git a/netutils/dropbear/port/dropbear_ltc_hmac_sha256.c b/netutils/dropbear/port/dropbear_ltc_hmac_sha256.c new file mode 100644 index 00000000000..bae7ab3916a --- /dev/null +++ b/netutils/dropbear/port/dropbear_ltc_hmac_sha256.c @@ -0,0 +1,103 @@ +/**************************************************************************** + * apps/netutils/dropbear/port/dropbear_ltc_hmac_sha256.c + * + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +/* LibTomCrypt-compatible HMAC API backed by NuttX crypto/hmac. The NuttX + * Dropbear configuration only enables hmac-sha2-256. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "includes.h" + +#include + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int dropbear_hmac_hash_is_sha256(int hash) +{ + int ret; + + ret = hash_is_valid(hash); + if (ret != CRYPT_OK) + { + return ret; + } + + if (hash_descriptor[hash].hashsize != SHA256_DIGEST_LENGTH || + hash_descriptor[hash].blocksize != SHA256_BLOCK_LENGTH) + { + return CRYPT_INVALID_HASH; + } + + return CRYPT_OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, + unsigned long keylen) +{ + int ret; + + LTC_ARGCHK(hmac != NULL); + LTC_ARGCHK(key != NULL); + + if (keylen == 0) + { + return CRYPT_INVALID_KEYSIZE; + } + + ret = dropbear_hmac_hash_is_sha256(hash); + if (ret != CRYPT_OK) + { + return ret; + } + + hmac->hash = hash; + hmac_sha256_init(&hmac->ctx, key, (u_int)keylen); + return CRYPT_OK; +} + +int hmac_process(hmac_state *hmac, const unsigned char *in, + unsigned long inlen) +{ + LTC_ARGCHK(hmac != NULL); + LTC_ARGCHK(in != NULL || inlen == 0); + + hmac_sha256_update(&hmac->ctx, in, (u_int)inlen); + return CRYPT_OK; +} + +int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen) +{ + uint8_t digest[SHA256_DIGEST_LENGTH]; + unsigned long copylen; + + LTC_ARGCHK(hmac != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + if (dropbear_hmac_hash_is_sha256(hmac->hash) != CRYPT_OK) + { + return CRYPT_INVALID_HASH; + } + + hmac_sha256_final(digest, &hmac->ctx); + + copylen = MIN(*outlen, SHA256_DIGEST_LENGTH); + memcpy(out, digest, copylen); + *outlen = copylen; + + zeromem(digest, sizeof(digest)); + zeromem(hmac, sizeof(*hmac)); + return CRYPT_OK; +} diff --git a/netutils/dropbear/port/dropbear_ltc_sha256.c b/netutils/dropbear/port/dropbear_ltc_sha256.c new file mode 100644 index 00000000000..3e889fa453e --- /dev/null +++ b/netutils/dropbear/port/dropbear_ltc_sha256.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * apps/netutils/dropbear/port/dropbear_ltc_sha256.c + * + * SPDX-License-Identifier: Apache-2.0 + ****************************************************************************/ + +/* LibTomCrypt-compatible SHA256 descriptor backed by NuttX crypto/sha2. + * Dropbear still expects the libtomcrypt hash API for KEX and HMAC. This + * adapter keeps that API while avoiding the bundled SHA256 implementation. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "includes.h" + +#include + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +const struct ltc_hash_descriptor sha256_desc = +{ + "sha256", + 0, + SHA256_DIGEST_LENGTH, + SHA256_BLOCK_LENGTH, + { 2, 16, 840, 1, 101, 3, 4, 2, 1 }, + 9, + + sha256_init, + sha256_process, + sha256_done, + sha256_test, + NULL +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int sha256_init(hash_state *md) +{ + LTC_ARGCHK(md != NULL); + + sha256init(&md->sha256.ctx); + return CRYPT_OK; +} + +int sha256_process(hash_state *md, const unsigned char *in, + unsigned long inlen) +{ + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(in != NULL || inlen == 0); + + sha256update(&md->sha256.ctx, in, inlen); + return CRYPT_OK; +} + +int sha256_done(hash_state *md, unsigned char *out) +{ + LTC_ARGCHK(md != NULL); + LTC_ARGCHK(out != NULL); + + sha256final(out, &md->sha256.ctx); + zeromem(md, sizeof(*md)); + return CRYPT_OK; +} + +int sha256_test(void) +{ + return CRYPT_NOP; +}