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 <anjiahao@xiaomi.com>
This commit is contained in:
anjiahao 2022-11-11 16:00:25 +08:00 committed by Xiang Xiao
parent fedad91b0d
commit 43d2c595b1
4 changed files with 54 additions and 38 deletions

View File

@ -452,6 +452,14 @@ int cryptodev_op(FAR struct csession *cse,
crda->crd_alg = cse->mac; crda->crd_alg = cse->mac;
crda->crd_key = cse->mackey; crda->crd_key = cse->mackey;
crda->crd_klen = cse->mackeylen * 8; 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) if (crde)
@ -485,10 +493,13 @@ int cryptodev_op(FAR struct csession *cse,
goto bail; goto bail;
} }
memcpy(cse->tmp_iv, cop->iv, cse->txform->blocksize); if (!(crde->crd_flags & CRD_F_IV_EXPLICIT))
bcopy(cse->tmp_iv, crde->crd_iv, cse->txform->blocksize); {
crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT; memcpy(cse->tmp_iv, cop->iv, cse->txform->blocksize);
crde->crd_skip = 0; 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) else if (crde)
{ {
@ -553,6 +564,11 @@ dispatch:
crypto_invoke(crp); crypto_invoke(crp);
processed: processed:
if ((cop->flags & COP_FLAG_UPDATE) == 0)
{
crde->crd_flags &= ~CRD_F_IV_EXPLICIT;
}
if (cse->error) if (cse->error)
{ {
error = cse->error; error = cse->error;

View File

@ -60,8 +60,8 @@ int swcr_id = -1;
int swcr_encdec(FAR struct cryptop *crp, FAR struct cryptodesc *crd, int swcr_encdec(FAR struct cryptop *crp, FAR struct cryptodesc *crd,
FAR struct swcr_data *sw, caddr_t buf) FAR struct swcr_data *sw, caddr_t buf)
{ {
unsigned char iv[EALG_MAX_BLOCK_LEN];
unsigned char blk[EALG_MAX_BLOCK_LEN]; unsigned char blk[EALG_MAX_BLOCK_LEN];
FAR unsigned char *iv;
FAR unsigned char *ivp; FAR unsigned char *ivp;
FAR unsigned char *nivp; FAR unsigned char *nivp;
unsigned char iv2[EALG_MAX_BLOCK_LEN]; 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) 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 */ /* Do we need to write the IV */
if (!(crd->crd_flags & CRD_F_IV_PRESENT)) 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 else
@ -110,18 +100,15 @@ int swcr_encdec(FAR struct cryptop *crp, FAR struct cryptodesc *crd,
/* IV explicitly provided ? */ /* IV explicitly provided ? */
if (crd->crd_flags & CRD_F_IV_EXPLICIT) if (!(crd->crd_flags & CRD_F_IV_EXPLICIT))
{
bcopy(crd->crd_iv, iv, ivlen);
}
else
{ {
/* Get IV off buf */ /* 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; ivp = iv;
/* xforms that provide a reinit method perform all 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; i = crd->crd_len;
buf = buf + crd->crd_skip;
while (i > 0) while (i > 0)
{ {
bcopy(buf, blk, exf->blocksize); bcopy(buf, blk, exf->blocksize);
@ -215,8 +203,7 @@ int swcr_authcompute(FAR struct cryptop *crp,
caddr_t buf) caddr_t buf)
{ {
unsigned char aalg[AALG_MAX_RESULT_LEN]; unsigned char aalg[AALG_MAX_RESULT_LEN];
FAR const struct auth_hash *axf; FAR const struct auth_hash *axf = sw->sw_axf;
union authctx ctx;
int err; int err;
if (sw->sw_ictx == 0) if (sw->sw_ictx == 0)
@ -224,10 +211,9 @@ int swcr_authcompute(FAR struct cryptop *crp,
return -EINVAL; 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) if (err)
{ {
return err; return err;
@ -235,7 +221,7 @@ int swcr_authcompute(FAR struct cryptop *crp,
if (crd->crd_flags & CRD_F_ESN) 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) switch (sw->sw_alg)
@ -251,18 +237,19 @@ int swcr_authcompute(FAR struct cryptop *crp,
return -EINVAL; return -EINVAL;
} }
axf->final(aalg, &ctx); if (crd->crd_flags & CRD_F_UPDATE)
bcopy(sw->sw_octx, &ctx, axf->ctxsize); {
axf->update(&ctx, aalg, axf->hashsize); break;
axf->final(aalg, &ctx); }
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; break;
default:
return -EINVAL;
} }
/* Inject the authentication data */
bcopy(aalg, crp->crp_mac, axf->hashsize);
return 0; return 0;
} }
@ -746,6 +733,7 @@ int swcr_newsession(FAR uint32_t *sid, FAR struct cryptoini *cri)
} }
(*swd)->sw_axf = axf; (*swd)->sw_axf = axf;
bcopy((*swd)->sw_ictx, &(*swd)->sw_ctx, axf->ctxsize);
break; break;
case CRYPTO_AES_128_GMAC: case CRYPTO_AES_128_GMAC:

View File

@ -156,6 +156,7 @@ struct cryptodesc
#define CRD_F_IV_EXPLICIT 0x04 /* IV explicitly provided */ #define CRD_F_IV_EXPLICIT 0x04 /* IV explicitly provided */
#define CRD_F_COMP 0x10 /* Set when doing compression */ #define CRD_F_COMP 0x10 /* Set when doing compression */
#define CRD_F_ESN 0x20 /* Set when ESN field is provided */ #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 */ struct cryptoini CRD_INI; /* Initialization/context data */
#define crd_esn CRD_INI.cri_esn #define crd_esn CRD_INI.cri_esn
@ -306,6 +307,14 @@ struct crypt_op
uint16_t op; /* i.e. COP_ENCRYPT */ 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; uint16_t flags;
unsigned len; unsigned len;
caddr_t src, dst; /* become iov[] inside kernel */ caddr_t src, dst; /* become iov[] inside kernel */

View File

@ -32,6 +32,7 @@
#include <sys/queue.h> #include <sys/queue.h>
#include <crypto/cryptodev.h> #include <crypto/cryptodev.h>
#include <crypto/xform.h>
/* Software session entry */ /* Software session entry */
@ -46,6 +47,7 @@ struct swcr_data
FAR uint8_t *octx; FAR uint8_t *octx;
uint32_t klen; uint32_t klen;
FAR const struct auth_hash *axf; FAR const struct auth_hash *axf;
union authctx ctx;
} SWCR_AUTH; } SWCR_AUTH;
struct struct
@ -65,6 +67,7 @@ struct swcr_data
#define sw_octx SWCR_UN.SWCR_AUTH.octx #define sw_octx SWCR_UN.SWCR_AUTH.octx
#define sw_klen SWCR_UN.SWCR_AUTH.klen #define sw_klen SWCR_UN.SWCR_AUTH.klen
#define sw_axf SWCR_UN.SWCR_AUTH.axf #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_kschedule SWCR_UN.SWCR_ENC.kschedule
#define sw_exf SWCR_UN.SWCR_ENC.exf #define sw_exf SWCR_UN.SWCR_ENC.exf
#define sw_size SWCR_UN.SWCR_COMP.size #define sw_size SWCR_UN.SWCR_COMP.size