This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git


The following commit(s) were added to refs/heads/master by this push:
     new 690ec808e netutils/dropbear: back hmac-sha2-256 with NuttX /dev/crypto
690ec808e is described below

commit 690ec808e54168459b127122bc0791044388118d
Author: Felipe Moura <[email protected]>
AuthorDate: Sat Jul 11 20:14:39 2026 -0300

    netutils/dropbear: back hmac-sha2-256 with NuttX /dev/crypto
    
    Replace the bundled libtomcrypt HMAC modules with an adapter that computes 
the hmac-sha2-256 packet MAC through the NuttX crypto device using 
CRYPTO_SHA2_256_HMAC sessions.
    
    Require CRYPTO, CRYPTO_RANDOM_POOL, CRYPTO_CRYPTODEV and 
CRYPTO_CRYPTODEV_SOFTWARE_CRYPTO explicitly instead of selecting crypto support.
    
    Signed-off-by: Felipe Moura <[email protected]>
---
 netutils/dropbear/CMakeLists.txt                  |   7 +
 netutils/dropbear/Kconfig                         |  11 +
 netutils/dropbear/Makefile                        |  10 +
 netutils/dropbear/port/dropbear_ltc_hmac_sha256.c | 255 ++++++++++++++++++++++
 4 files changed, 283 insertions(+)

diff --git a/netutils/dropbear/CMakeLists.txt b/netutils/dropbear/CMakeLists.txt
index eb31d0012..96cbcc233 100644
--- a/netutils/dropbear/CMakeLists.txt
+++ b/netutils/dropbear/CMakeLists.txt
@@ -135,6 +135,13 @@ 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$")
+
+  # Drop the bundled libtomcrypt HMAC modules replaced by the NuttX adapter.
+  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_hmac_sha256.c)
+
   list(APPEND DROPBEAR_SRCS ${LIBTOMCRYPT_SRCS})
 
   if(CONFIG_NETUTILS_DROPBEAR_SCP)
diff --git a/netutils/dropbear/Kconfig b/netutils/dropbear/Kconfig
index 43a2c4a51..ae37135cb 100644
--- a/netutils/dropbear/Kconfig
+++ b/netutils/dropbear/Kconfig
@@ -21,11 +21,22 @@ menuconfig NETUTILS_DROPBEAR
        depends on LIBC_GAISTRERROR
        depends on CRYPTO
        depends on CRYPTO_RANDOM_POOL
+       depends on ALLOW_BSD_COMPONENTS
+       depends on CRYPTO_CRYPTODEV
+       depends on CRYPTO_CRYPTODEV_SOFTWARE_CRYPTO
        ---help---
                Enable a minimal Dropbear SSH server port for NuttX.  This 
initial
                port is based on the ESP-IDF MCU test port and provides a single
                foreground SSH server process with SSH sessions backed by NSH.
 
+               The port computes the hmac-sha2-256 packet MAC through the NuttX
+               crypto device (/dev/crypto, CRYPTO_SHA2_256_HMAC) instead of the
+               bundled libtomcrypt implementation, which is dropped from the
+               build.  The SHA-256 hash descriptor itself stays in the
+               application: Dropbear's key derivation clones partially-updated
+               hash states (hashkeys() in common-kex.c), which cannot be
+               represented by a kernel crypto session.
+
 if NETUTILS_DROPBEAR
 
 config NETUTILS_DROPBEAR_STACKSIZE
diff --git a/netutils/dropbear/Makefile b/netutils/dropbear/Makefile
index 17e5ec8db..145e5c5ae 100644
--- a/netutils/dropbear/Makefile
+++ b/netutils/dropbear/Makefile
@@ -119,6 +119,16 @@ 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)
 
+# Drop the bundled libtomcrypt HMAC modules replaced by the NuttX adapter.
+
+TOMCRYPT_SRCS := $(filter-out \
+       %/mac/hmac/hmac_init.c \
+       %/mac/hmac/hmac_process.c \
+       %/mac/hmac/hmac_done.c, \
+       $(TOMCRYPT_SRCS))
+
+CSRCS += port/dropbear_ltc_hmac_sha256.c
+
 CSRCS += $(TOMMATH_SRCS)
 CSRCS += $(TOMCRYPT_SRCS)
 
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 000000000..dda511d5f
--- /dev/null
+++ b/netutils/dropbear/port/dropbear_ltc_hmac_sha256.c
@@ -0,0 +1,255 @@
+/****************************************************************************
+ * apps/netutils/dropbear/port/dropbear_ltc_hmac_sha256.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* LibTomCrypt-compatible incremental HMAC API backed by a
+ * CRYPTO_SHA2_256_HMAC /dev/crypto session (hmac-sha2-256, the only MAC the
+ * NuttX Dropbear configuration enables): init opens the session, process
+ * feeds data with COP_FLAG_UPDATE, done reads the tag and frees the session.
+ */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "includes.h"
+
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <crypto/cryptodev.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define DROPBEAR_HMAC_SHA256_DIGESTLEN 32
+#define DROPBEAR_HMAC_SHA256_BLOCKLEN  64
+
+/* Stash the process-local /dev/crypto descriptor and session id in the
+ * unused md hash-state buffer so the upstream hmac_state needs no patch.
+ */
+
+static_assert(sizeof(int) + sizeof(uint32_t) <= sizeof(hash_state),
+              "cryptodev state does not fit in hmac_state.md");
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int dropbear_hmac_cryptodev_open(void)
+{
+  int fd;
+  int cfd;
+
+  fd = open("/dev/crypto", O_RDWR);
+  if (fd < 0)
+    {
+      return -1;
+    }
+
+  if (ioctl(fd, CRIOGET, &cfd) < 0)
+    {
+      close(fd);
+      return -1;
+    }
+
+  close(fd);
+
+  if (fcntl(cfd, F_SETFD, FD_CLOEXEC) < 0)
+    {
+      close(cfd);
+      return -1;
+    }
+
+  return cfd;
+}
+
+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 != DROPBEAR_HMAC_SHA256_DIGESTLEN ||
+      hash_descriptor[hash].blocksize != DROPBEAR_HMAC_SHA256_BLOCKLEN)
+    {
+      return CRYPT_INVALID_HASH;
+    }
+
+  return CRYPT_OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int hmac_init(hmac_state *hmac, int hash, const unsigned char *key,
+              unsigned long keylen)
+{
+  struct session_op session;
+  int cfd;
+  int ret;
+
+  LTC_ARGCHK(hmac != NULL);
+  LTC_ARGCHK(key != NULL);
+
+  if (keylen == 0 || keylen > INT_MAX)
+    {
+      return CRYPT_INVALID_KEYSIZE;
+    }
+
+  ret = dropbear_hmac_hash_is_sha256(hash);
+  if (ret != CRYPT_OK)
+    {
+      return ret;
+    }
+
+  zeromem(hmac, sizeof(*hmac));
+  cfd = dropbear_hmac_cryptodev_open();
+  if (cfd < 0)
+    {
+      return CRYPT_ERROR;
+    }
+
+  memset(&session, 0, sizeof(session));
+  session.mac = CRYPTO_SHA2_256_HMAC;
+  session.mackey = (caddr_t)key;
+  session.mackeylen = (int)keylen;
+  if (ioctl(cfd, CIOCGSESSION, &session) < 0)
+    {
+      close(cfd);
+      zeromem(hmac, sizeof(*hmac));
+      return CRYPT_ERROR;
+    }
+
+  memcpy(&hmac->md, &cfd, sizeof(cfd));
+  memcpy((FAR uint8_t *)&hmac->md + sizeof(cfd),
+         &session.ses, sizeof(session.ses));
+  hmac->hash = hash;
+  return CRYPT_OK;
+}
+
+int hmac_process(hmac_state *hmac, const unsigned char *in,
+                 unsigned long inlen)
+{
+  struct crypt_op cryp;
+  uint32_t ses;
+  int cfd;
+  int ret;
+
+  LTC_ARGCHK(hmac != NULL);
+  LTC_ARGCHK(in != NULL || inlen == 0);
+
+  ret = dropbear_hmac_hash_is_sha256(hmac->hash);
+  if (ret != CRYPT_OK)
+    {
+      return ret;
+    }
+
+  if (inlen > UINT_MAX)
+    {
+      return CRYPT_OVERFLOW;
+    }
+
+  memcpy(&cfd, &hmac->md, sizeof(cfd));
+  memcpy(&ses, (FAR uint8_t *)&hmac->md + sizeof(cfd), sizeof(ses));
+  if (cfd < 0)
+    {
+      return CRYPT_ERROR;
+    }
+
+  memset(&cryp, 0, sizeof(cryp));
+  cryp.ses = ses;
+  cryp.op = COP_ENCRYPT;
+  cryp.flags = COP_FLAG_UPDATE;
+  cryp.len = (unsigned int)inlen;
+  cryp.src = (caddr_t)in;
+  if (ioctl(cfd, CIOCCRYPT, &cryp) < 0)
+    {
+      return CRYPT_ERROR;
+    }
+
+  return CRYPT_OK;
+}
+
+int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen)
+{
+  unsigned char digest[DROPBEAR_HMAC_SHA256_DIGESTLEN];
+  struct crypt_op cryp;
+  unsigned long copylen;
+  uint32_t ses;
+  int cfd;
+  int ret = CRYPT_ERROR;
+
+  LTC_ARGCHK(hmac != NULL);
+  LTC_ARGCHK(out != NULL);
+  LTC_ARGCHK(outlen != NULL);
+
+  memcpy(&cfd, &hmac->md, sizeof(cfd));
+  memcpy(&ses, (FAR uint8_t *)&hmac->md + sizeof(cfd), sizeof(ses));
+  if (cfd < 0)
+    {
+      goto out;
+    }
+
+  ret = dropbear_hmac_hash_is_sha256(hmac->hash);
+  if (ret != CRYPT_OK)
+    {
+      goto out;
+    }
+
+  memset(&cryp, 0, sizeof(cryp));
+  cryp.ses = ses;
+  cryp.op = COP_ENCRYPT;
+  cryp.len = 0;
+  cryp.src = (caddr_t)digest;
+  cryp.mac = (caddr_t)digest;
+  if (ioctl(cfd, CIOCCRYPT, &cryp) < 0)
+    {
+      ret = CRYPT_ERROR;
+      goto out;
+    }
+
+  copylen = MIN(*outlen, DROPBEAR_HMAC_SHA256_DIGESTLEN);
+  memcpy(out, digest, copylen);
+  *outlen = copylen;
+  ret = CRYPT_OK;
+
+out:
+  if (cfd >= 0)
+    {
+      ioctl(cfd, CIOCFSESSION, &ses);
+      close(cfd);
+    }
+
+  zeromem(digest, sizeof(digest));
+  zeromem(hmac, sizeof(*hmac));
+  return ret;
+}

Reply via email to