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.git


The following commit(s) were added to refs/heads/master by this push:
     new 30391848066 crypto/cryptosoft: Add support for PBKDF2
30391848066 is described below

commit 30391848066d4cf989da74abcc79e5524f959540
Author: Vlad Pruteanu <[email protected]>
AuthorDate: Wed Mar 25 00:10:16 2026 +0200

    crypto/cryptosoft: Add support for PBKDF2
    
    This adds support for PBKDF2 (SHA1 and SHA256) while leveraging
    the existing infrastructure for HMAC.
    
    Signed-off-by: Vlad Pruteanu <[email protected]>
---
 Documentation/components/crypto.rst |  6 +++
 crypto/cryptodev.c                  |  7 ++++
 crypto/cryptosoft.c                 | 80 +++++++++++++++++++++++++++++++++++++
 include/crypto/cryptodev.h          |  8 +++-
 include/crypto/cryptosoft.h         |  2 +
 5 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/Documentation/components/crypto.rst 
b/Documentation/components/crypto.rst
index 4674ddca7cc..fcc4bb9b1ca 100644
--- a/Documentation/components/crypto.rst
+++ b/Documentation/components/crypto.rst
@@ -192,6 +192,12 @@ Key Management Operations
 
 The cryptodev module provides comprehensive key management interfaces:
 
+**Key Derivation**
+
+- PBKDF2:
+  - CRYPTO_PBKDF2_HMAC_SHA1
+  - CRYPTO_PBKDF2_HMAC_SHA256
+
 **Key Generation**
 
 - CRK_GENERATE_AES_KEY: Generate AES key data with specified key ID
diff --git a/crypto/cryptodev.c b/crypto/cryptodev.c
index 183c7b59a0b..b4d4ec5f5dd 100644
--- a/crypto/cryptodev.c
+++ b/crypto/cryptodev.c
@@ -264,6 +264,8 @@ static int cryptof_ioctl(FAR struct file *filep,
             case CRYPTO_SHA2_384:
             case CRYPTO_SHA2_512:
             case CRYPTO_CRC32:
+            case CRYPTO_PBKDF2_HMAC_SHA1:
+            case CRYPTO_PBKDF2_HMAC_SHA256:
               thash = true;
               break;
             default:
@@ -470,6 +472,11 @@ static int cryptodev_op(FAR struct csession *cse,
       crp.crp_mac = cop->mac;
     }
 
+  if (cop->iterations)
+    {
+      crp.crp_iter = cop->iterations;
+    }
+
   /* try the fast path first */
 
   crp.crp_flags = CRYPTO_F_IOV | CRYPTO_F_NOQUEUE;
diff --git a/crypto/cryptosoft.c b/crypto/cryptosoft.c
index cfb151b056a..7a22b6ce80f 100644
--- a/crypto/cryptosoft.c
+++ b/crypto/cryptosoft.c
@@ -1156,6 +1156,9 @@ int swcr_authcompute(FAR struct cryptop *crp,
       case CRYPTO_SHA2_256_HMAC:
       case CRYPTO_SHA2_384_HMAC:
       case CRYPTO_SHA2_512_HMAC:
+      case CRYPTO_PBKDF2_HMAC_SHA1:
+      case CRYPTO_PBKDF2_HMAC_SHA256:
+
         if (sw->sw_octx == NULL)
           {
             return -EINVAL;
@@ -1656,12 +1659,14 @@ int swcr_newsession(FAR uint32_t *sid, FAR struct 
cryptoini *cri)
             axf = &auth_hash_hmac_md5_96;
             goto authcommon;
           case CRYPTO_SHA1_HMAC:
+          case CRYPTO_PBKDF2_HMAC_SHA1:
             axf = &auth_hash_hmac_sha1_96;
             goto authcommon;
           case CRYPTO_RIPEMD160_HMAC:
             axf = &auth_hash_hmac_ripemd_160_96;
             goto authcommon;
           case CRYPTO_SHA2_256_HMAC:
+          case CRYPTO_PBKDF2_HMAC_SHA256:
             axf = &auth_hash_hmac_sha2_256_128;
             goto authcommon;
           case CRYPTO_SHA2_384_HMAC:
@@ -1892,6 +1897,8 @@ int swcr_freesession(uint64_t tid)
           case CRYPTO_SHA2_256_HMAC:
           case CRYPTO_SHA2_384_HMAC:
           case CRYPTO_SHA2_512_HMAC:
+          case CRYPTO_PBKDF2_HMAC_SHA1:
+          case CRYPTO_PBKDF2_HMAC_SHA256:
             axf = swd->sw_axf;
 
             if (swd->sw_ictx)
@@ -2047,7 +2054,11 @@ int swcr_process(struct cryptop *crp)
               }
 
             break;
+          case CRYPTO_PBKDF2_HMAC_SHA1:
+          case CRYPTO_PBKDF2_HMAC_SHA256:
+            swcr_pbkdf2(crp, crd, sw, crp->crp_buf);
 
+            break;
           case CRYPTO_MD5:
           case CRYPTO_POLY1305:
           case CRYPTO_RIPEMD160:
@@ -2090,6 +2101,73 @@ done:
   return 0;
 }
 
+int swcr_pbkdf2(FAR struct cryptop *crp,
+                FAR struct cryptodesc *crd,
+                FAR struct swcr_data *swd,
+                caddr_t buf)
+{
+  uint8_t U[64];
+  uint8_t T[64];
+  uint8_t macbuf[64];
+  uint8_t ictx[256];
+  struct cryptop crp_dummy;
+  struct cryptodesc crd_dummy;
+
+  size_t generated = 0;
+  uint32_t blocknum;
+  uint32_t i;
+  uint32_t j;
+
+  crp_dummy.crp_mac = (caddr_t)macbuf;
+
+  for (blocknum = 1; generated < crp->crp_olen; blocknum++)
+    {
+      uint8_t saltblk[crp->crp_ilen + 4];
+
+      memcpy(saltblk, crp->crp_buf, crp->crp_ilen);
+      *(FAR uint32_t *)(saltblk + crp->crp_ilen) = htobe32(blocknum);
+
+      memcpy(ictx, swd->sw_ictx, swd->sw_axf->ctxsize);
+      memcpy(&swd->sw_ctx, ictx, swd->sw_axf->ctxsize);
+
+      crd_dummy.crd_skip = 0;
+      crd_dummy.crd_flags = 0;
+
+      /* U1 */
+
+      crd_dummy.crd_len = crp->crp_ilen + 4;
+      swcr_authcompute(&crp_dummy, &crd_dummy, swd, (caddr_t)saltblk);
+
+      memcpy(U, macbuf, swd->sw_axf->hashsize);
+      memcpy(T, U, swd->sw_axf->hashsize);
+
+      /* U2..Uc */
+
+      for (i = 1; i < crp->crp_iter; i++)
+        {
+          memcpy(&swd->sw_ctx, ictx, swd->sw_axf->ctxsize);
+
+          crd_dummy.crd_len = swd->sw_axf->hashsize;
+          swcr_authcompute(&crp_dummy, &crd_dummy, swd, (caddr_t)U);
+
+          memcpy(U, macbuf, swd->sw_axf->hashsize);
+
+          for (j = 0; j < swd->sw_axf->hashsize; j++)
+            {
+              T[j] ^= U[j];
+            }
+        }
+
+      size_t tocopy = MIN(crp->crp_olen - generated,
+                          swd->sw_axf->hashsize);
+
+      memcpy(crp->crp_mac + generated, T, tocopy);
+      generated += tocopy;
+    }
+
+  return 0;
+}
+
 int swcr_mod_exp(struct cryptkop *krp)
 {
   uint8_t *input = (uint8_t *)krp->krp_param[0].crp_p;
@@ -2353,6 +2431,8 @@ void swcr_init(void)
   algs[CRYPTO_CRC32] = CRYPTO_ALG_FLAG_SUPPORTED;
   algs[CRYPTO_AES_CMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
   algs[CRYPTO_AES_128_CMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
+  algs[CRYPTO_PBKDF2_HMAC_SHA1] = CRYPTO_ALG_FLAG_SUPPORTED;
+  algs[CRYPTO_PBKDF2_HMAC_SHA256] = CRYPTO_ALG_FLAG_SUPPORTED;
   algs[CRYPTO_ESN] = CRYPTO_ALG_FLAG_SUPPORTED;
 
   crypto_register(swcr_id, algs, swcr_newsession,
diff --git a/include/crypto/cryptodev.h b/include/crypto/cryptodev.h
index 049b7f41f3e..f58f1b38e43 100644
--- a/include/crypto/cryptodev.h
+++ b/include/crypto/cryptodev.h
@@ -135,8 +135,10 @@
 #define CRYPTO_CRC32            35
 #define CRYPTO_AES_CMAC         36
 #define CRYPTO_AES_128_CMAC     37
-#define CRYPTO_ESN              38 /* Support for Extended Sequence Numbers */
-#define CRYPTO_ALGORITHM_MAX    38 /* Keep updated */
+#define CRYPTO_PBKDF2_HMAC_SHA1 38
+#define CRYPTO_PBKDF2_HMAC_SHA256 39
+#define CRYPTO_ESN              40 /* Support for Extended Sequence Numbers */
+#define CRYPTO_ALGORITHM_MAX    40 /* Keep updated */
 
 /* Algorithm flags */
 
@@ -235,6 +237,7 @@ struct cryptop
   caddr_t crp_dst;
   caddr_t crp_iv;
   caddr_t crp_aad;
+  int crp_iter;
 };
 
 #define CRYPTO_BUF_IOV 0x1
@@ -408,6 +411,7 @@ struct crypt_op
  */
 
   uint16_t flags;
+  uint32_t iterations;
   unsigned len;
   unsigned olen;
   unsigned ivlen;
diff --git a/include/crypto/cryptosoft.h b/include/crypto/cryptosoft.h
index 1523a8bf497..dd9aef9ebc0 100644
--- a/include/crypto/cryptosoft.h
+++ b/include/crypto/cryptosoft.h
@@ -91,6 +91,8 @@ int swcr_authenc(FAR struct cryptop *);
 int swcr_compdec(FAR struct cryptodesc *, FAR struct swcr_data *,
                  caddr_t, int);
 int swcr_rsa_verify(FAR struct cryptkop *);
+int swcr_pbkdf2(FAR struct cryptop *, FAR struct cryptodesc *,
+                FAR struct swcr_data *, caddr_t);
 int swcr_process(FAR struct cryptop *);
 int swcr_kprocess(FAR struct cryptkop *);
 int swcr_newsession(FAR uint32_t *, FAR struct cryptoini *);

Reply via email to