You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/01/16 17:19:43 UTC

[nuttx] branch master updated: crypto:support crypto can handle streaming data

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

xiaoxiang 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 43d2c595b1 crypto:support crypto can handle streaming data
43d2c595b1 is described below

commit 43d2c595b18cd98cfd3c59a57e6709ac9c5492f1
Author: anjiahao <an...@xiaomi.com>
AuthorDate: Fri Nov 11 16:00:25 2022 +0800

    crypto:support crypto can handle streaming data
    
    in user space
    Use the flag (COP_FLAG_UPDATE)structure member to mark
    whether it is just input data.
    like this:
    can do manys times,just input data
    ....
    
      cryp.ses = session.ses;
      cryp.op = COP_ENCRYPT;
      cryp.src = (caddr_t) s;
      cryp.len = len;
      cryp.flags = COP_FLAG_UPDATE;
      cryp.dst = 0;
      cryp.mac = (caddr_t) out;
      cryp.iv = 0;
      if (ioctl(cryptodev_fd, CIOCCRYPT, &cryp) == -1)
        {
          warn("CIOCCRYPT");
          goto err;
        }
    
    can do manys times like frist...
    
    then,the last time
    
    Don't use any flay structure member to mark
    this is last time,need get final result
    ....
      cryp.ses = session.ses;
      cryp.op = COP_ENCRYPT;
      cryp.src = (caddr_t) s;
      cryp.len = len;
      cryp.flags = 0;
      cryp.dst = 0;
      cryp.mac = (caddr_t) out;
      cryp.iv = 0;
      if (ioctl(cryptodev_fd, CIOCCRYPT, &cryp) == -1)
        {
          warn("CIOCCRYPT");
          goto err;
        }
    ....
    that will get last result.
    
    Signed-off-by: anjiahao <an...@xiaomi.com>
---
 crypto/cryptodev.c          | 24 +++++++++++++++----
 crypto/cryptosoft.c         | 56 ++++++++++++++++++---------------------------
 include/crypto/cryptodev.h  |  9 ++++++++
 include/crypto/cryptosoft.h |  3 +++
 4 files changed, 54 insertions(+), 38 deletions(-)

diff --git a/crypto/cryptodev.c b/crypto/cryptodev.c
index 778ec2aa2d..f5f0d783f3 100644
--- a/crypto/cryptodev.c
+++ b/crypto/cryptodev.c
@@ -452,6 +452,14 @@ int cryptodev_op(FAR struct csession *cse,
       crda->crd_alg = cse->mac;
       crda->crd_key = cse->mackey;
       crda->crd_klen = cse->mackeylen * 8;
+      if (cop->flags & COP_FLAG_UPDATE)
+        {
+          crda->crd_flags |= CRD_F_UPDATE;
+        }
+      else
+        {
+          crda->crd_flags &= ~CRD_F_UPDATE;
+        }
     }
 
   if (crde)
@@ -485,10 +493,13 @@ int cryptodev_op(FAR struct csession *cse,
           goto bail;
         }
 
-      memcpy(cse->tmp_iv, cop->iv, cse->txform->blocksize);
-      bcopy(cse->tmp_iv, crde->crd_iv, cse->txform->blocksize);
-      crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
-      crde->crd_skip = 0;
+      if (!(crde->crd_flags & CRD_F_IV_EXPLICIT))
+        {
+          memcpy(cse->tmp_iv, cop->iv, cse->txform->blocksize);
+          bcopy(cse->tmp_iv, crde->crd_iv, cse->txform->blocksize);
+          crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
+          crde->crd_skip = 0;
+        }
     }
   else if (crde)
     {
@@ -553,6 +564,11 @@ dispatch:
   crypto_invoke(crp);
 processed:
 
+  if ((cop->flags & COP_FLAG_UPDATE) == 0)
+    {
+      crde->crd_flags &= ~CRD_F_IV_EXPLICIT;
+    }
+
   if (cse->error)
     {
       error = cse->error;
diff --git a/crypto/cryptosoft.c b/crypto/cryptosoft.c
index 1d1817e4a9..2ad6671bf5 100644
--- a/crypto/cryptosoft.c
+++ b/crypto/cryptosoft.c
@@ -60,8 +60,8 @@ int swcr_id = -1;
 int swcr_encdec(FAR struct cryptop *crp, FAR struct cryptodesc *crd,
                 FAR struct swcr_data *sw, caddr_t buf)
 {
-  unsigned char iv[EALG_MAX_BLOCK_LEN];
   unsigned char blk[EALG_MAX_BLOCK_LEN];
+  FAR unsigned char *iv;
   FAR unsigned char *ivp;
   FAR unsigned char *nivp;
   unsigned char iv2[EALG_MAX_BLOCK_LEN];
@@ -86,22 +86,12 @@ int swcr_encdec(FAR struct cryptop *crp, FAR struct cryptodesc *crd,
 
   if (crd->crd_flags & CRD_F_ENCRYPT)
     {
-      /* IV explicitly provided ? */
-
-      if (crd->crd_flags & CRD_F_IV_EXPLICIT)
-        {
-          bcopy(crd->crd_iv, iv, ivlen);
-        }
-      else
-        {
-          arc4random_buf(iv, ivlen);
-        }
-
       /* Do we need to write the IV */
 
       if (!(crd->crd_flags & CRD_F_IV_PRESENT))
         {
-          bcopy(iv, buf + crd->crd_inject, ivlen);
+          arc4random_buf(crd->crd_iv, ivlen);
+          bcopy(crd->crd_iv, buf + crd->crd_inject, ivlen);
         }
     }
   else
@@ -110,18 +100,15 @@ int swcr_encdec(FAR struct cryptop *crp, FAR struct cryptodesc *crd,
 
       /* IV explicitly provided ? */
 
-      if (crd->crd_flags & CRD_F_IV_EXPLICIT)
-        {
-          bcopy(crd->crd_iv, iv, ivlen);
-        }
-      else
+      if (!(crd->crd_flags & CRD_F_IV_EXPLICIT))
         {
           /* Get IV off buf */
 
-          bcopy(iv, buf + crd->crd_inject, ivlen);
+          bcopy(crd->crd_iv, buf + crd->crd_inject, ivlen);
         }
     }
 
+  iv = crd->crd_iv;
   ivp = iv;
 
   /* xforms that provide a reinit method perform all IV
@@ -135,6 +122,7 @@ int swcr_encdec(FAR struct cryptop *crp, FAR struct cryptodesc *crd,
 
   i = crd->crd_len;
 
+  buf = buf + crd->crd_skip;
   while (i > 0)
     {
       bcopy(buf, blk, exf->blocksize);
@@ -215,8 +203,7 @@ int swcr_authcompute(FAR struct cryptop *crp,
                      caddr_t buf)
 {
   unsigned char aalg[AALG_MAX_RESULT_LEN];
-  FAR const struct auth_hash *axf;
-  union authctx ctx;
+  FAR const struct auth_hash *axf = sw->sw_axf;
   int err;
 
   if (sw->sw_ictx == 0)
@@ -224,10 +211,9 @@ int swcr_authcompute(FAR struct cryptop *crp,
       return -EINVAL;
     }
 
-  axf = sw->sw_axf;
+  err = axf->update(&sw->sw_ctx, (FAR uint8_t *)buf + crd->crd_skip,
+                    crd->crd_len);
 
-  bcopy(sw->sw_ictx, &ctx, axf->ctxsize);
-  err = axf->update(&ctx, (FAR uint8_t *)buf, crd->crd_len);
   if (err)
     {
       return err;
@@ -235,7 +221,7 @@ int swcr_authcompute(FAR struct cryptop *crp,
 
   if (crd->crd_flags & CRD_F_ESN)
     {
-      axf->update(&ctx, crd->crd_esn, 4);
+      axf->update(&sw->sw_ctx, crd->crd_esn, 4);
     }
 
   switch (sw->sw_alg)
@@ -251,18 +237,19 @@ int swcr_authcompute(FAR struct cryptop *crp,
             return -EINVAL;
           }
 
-        axf->final(aalg, &ctx);
-        bcopy(sw->sw_octx, &ctx, axf->ctxsize);
-        axf->update(&ctx, aalg, axf->hashsize);
-        axf->final(aalg, &ctx);
+        if (crd->crd_flags & CRD_F_UPDATE)
+          {
+            break;
+          }
+
+        axf->final(aalg, &sw->sw_ctx);
+        bcopy(sw->sw_octx, &sw->sw_ctx, axf->ctxsize);
+        axf->update(&sw->sw_ctx, aalg, axf->hashsize);
+        axf->final((FAR uint8_t *)crp->crp_mac, &sw->sw_ctx);
+        bcopy(sw->sw_ictx, &sw->sw_ctx, axf->ctxsize);
         break;
-      default:
-        return -EINVAL;
     }
 
-  /* Inject the authentication data */
-
-  bcopy(aalg, crp->crp_mac, axf->hashsize);
   return 0;
 }
 
@@ -746,6 +733,7 @@ int swcr_newsession(FAR uint32_t *sid, FAR struct cryptoini *cri)
               }
 
             (*swd)->sw_axf = axf;
+            bcopy((*swd)->sw_ictx, &(*swd)->sw_ctx, axf->ctxsize);
             break;
 
           case CRYPTO_AES_128_GMAC:
diff --git a/include/crypto/cryptodev.h b/include/crypto/cryptodev.h
index b61ecba96a..fe6ca1a3da 100644
--- a/include/crypto/cryptodev.h
+++ b/include/crypto/cryptodev.h
@@ -156,6 +156,7 @@ struct cryptodesc
   #define CRD_F_IV_EXPLICIT 0x04   /* IV explicitly provided */
   #define CRD_F_COMP 0x10          /* Set when doing compression */
   #define CRD_F_ESN 0x20           /* Set when ESN field is provided */
+  #define CRD_F_UPDATE 0x40        /* Set just update source */
 
   struct cryptoini CRD_INI; /* Initialization/context data */
   #define crd_esn CRD_INI.cri_esn
@@ -306,6 +307,14 @@ struct crypt_op
 
   uint16_t op;        /* i.e. COP_ENCRYPT */
 
+#define COP_FLAG_UPDATE  (1 << 0) /* Indicates that this operation is a
+                                   * stream operation. This operation will not get
+                                   * the final result of hash. If the iv is not equal,
+                                   * only the iv initialized for the first time will
+                                   * be used, and the subsequent iv will be saved
+                                   * in the driver.
+                                   */
+
   uint16_t flags;
   unsigned len;
   caddr_t src, dst;   /* become iov[] inside kernel */
diff --git a/include/crypto/cryptosoft.h b/include/crypto/cryptosoft.h
index ff7fa64f51..36aca9a838 100644
--- a/include/crypto/cryptosoft.h
+++ b/include/crypto/cryptosoft.h
@@ -32,6 +32,7 @@
 
 #include <sys/queue.h>
 #include <crypto/cryptodev.h>
+#include <crypto/xform.h>
 
 /* Software session entry */
 
@@ -46,6 +47,7 @@ struct swcr_data
         FAR uint8_t *octx;
         uint32_t klen;
         FAR const struct auth_hash *axf;
+        union authctx ctx;
       } SWCR_AUTH;
 
       struct
@@ -65,6 +67,7 @@ struct swcr_data
 #define sw_octx   SWCR_UN.SWCR_AUTH.octx
 #define sw_klen   SWCR_UN.SWCR_AUTH.klen
 #define sw_axf    SWCR_UN.SWCR_AUTH.axf
+#define sw_ctx    SWCR_UN.SWCR_AUTH.ctx
 #define sw_kschedule SWCR_UN.SWCR_ENC.kschedule
 #define sw_exf    SWCR_UN.SWCR_ENC.exf
 #define sw_size   SWCR_UN.SWCR_COMP.size