Skip to content

Commit

Permalink
nuttx/crypto: export asynchronous calling process
Browse files Browse the repository at this point in the history
Signed-off-by: makejian <[email protected]>
  • Loading branch information
makejian committed Sep 27, 2024
1 parent 21f9fc2 commit 2febfb8
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 39 deletions.
198 changes: 161 additions & 37 deletions crypto/cryptodev.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
#include <nuttx/config.h>

#include <sys/types.h>
#include <sys/queue.h>
#include <stdbool.h>
#include <string.h>
#include <poll.h>
Expand Down Expand Up @@ -94,7 +93,9 @@ struct csession
struct fcrypt
{
TAILQ_HEAD(csessionlist, csession) csessions;
TAILQ_HEAD(cryptkoplist, cryptkop) crpk_ret;
int sesn;
FAR struct pollfd *fds;
};

/****************************************************************************
Expand Down Expand Up @@ -122,6 +123,23 @@ static ssize_t cryptowrite(FAR struct file *filep,
static int cryptoclose(FAR struct file *filep);
static int cryptoioctl(FAR struct file *filep, int cmd, unsigned long arg);

static FAR struct csession *csefind(FAR struct fcrypt *, u_int);
static int csedelete(FAR struct fcrypt *, FAR struct csession *);
static FAR struct csession *cseadd(FAR struct fcrypt *,
FAR struct csession *);
static FAR struct csession *csecreate(FAR struct fcrypt *, uint64_t,
caddr_t, uint64_t,
caddr_t, uint64_t, uint32_t,
uint32_t, bool, bool);
static int csefree(FAR struct csession *);

static int cryptodev_op(FAR struct csession *,
FAR struct crypt_op *);
static int cryptodev_key(FAR struct fcrypt *, FAR struct crypt_kop *);
static int cryptodevkey_cb(FAR struct cryptkop *);
static int cryptodev_getkeystatus(FAR struct fcrypt *,
FAR struct crypt_kop *);

/****************************************************************************
* Private Data
****************************************************************************/
Expand Down Expand Up @@ -154,6 +172,7 @@ static const struct file_operations g_cryptoops =

static struct inode g_cryptoinode =
{
.i_flags = FSNODEFLAG_TYPE_DRIVER,
.i_crefs = 1,
.u.i_ops = &g_cryptofops
};
Expand All @@ -162,23 +181,6 @@ static struct inode g_cryptoinode =
* Private Functions
****************************************************************************/

FAR struct csession *csefind(FAR struct fcrypt *, u_int);
int csedelete(FAR struct fcrypt *, FAR struct csession *);
FAR struct csession *cseadd(FAR struct fcrypt *, FAR struct csession *);
FAR struct csession *csecreate(FAR struct fcrypt *, uint64_t,
caddr_t, uint64_t,
caddr_t, uint64_t, uint32_t,
uint32_t, bool, bool);
int csefree(FAR struct csession *);

int cryptodev_op(FAR struct csession *,
FAR struct crypt_op *);
int cryptodev_key(FAR struct crypt_kop *);
int cryptodev_dokey(FAR struct crypt_kop *kop, FAR struct crparam *kvp);

int cryptodev_cb(FAR struct cryptop *);
int cryptodevkey_cb(FAR struct cryptkop *);

/* ARGSUSED */

static ssize_t cryptof_read(FAR struct file *filep,
Expand Down Expand Up @@ -365,7 +367,10 @@ static int cryptof_ioctl(FAR struct file *filep,
error = cryptodev_op(cse, cop);
break;
case CIOCKEY:
error = cryptodev_key((FAR struct crypt_kop *)arg);
error = cryptodev_key(fcr, (FAR struct crypt_kop *)arg);
break;
case CIOCKEYRET:
error = cryptodev_getkeystatus(fcr, (FAR struct crypt_kop *)arg);
break;
case CIOCASYMFEAT:
error = crypto_getfeat((FAR int *)arg);
Expand All @@ -377,8 +382,8 @@ static int cryptof_ioctl(FAR struct file *filep,
return error;
}

int cryptodev_op(FAR struct csession *cse,
FAR struct crypt_op *cop)
static int cryptodev_op(FAR struct csession *cse,
FAR struct crypt_op *cop)
{
FAR struct cryptop *crp = NULL;
FAR struct cryptodesc *crde = NULL;
Expand Down Expand Up @@ -549,7 +554,7 @@ int cryptodev_op(FAR struct csession *cse,
return error;
}

int cryptodev_key(FAR struct crypt_kop *kop)
static int cryptodev_key(FAR struct fcrypt *fcr, FAR struct crypt_kop *kop)
{
FAR struct cryptkop *krp = NULL;
int error = -EINVAL;
Expand Down Expand Up @@ -642,11 +647,19 @@ int cryptodev_key(FAR struct crypt_kop *kop)
}

krp = kmm_zalloc(sizeof *krp);
if (krp == NULL)
{
return -ENOMEM;
}

krp->krp_op = kop->crk_op;
krp->krp_status = kop->crk_status;
krp->krp_iparams = kop->crk_iparams;
krp->krp_oparams = kop->crk_oparams;
krp->krp_status = 0;
krp->krp_flags = kop->crk_flags;
krp->krp_reqid = kop->crk_reqid;
krp->krp_fcr = fcr;
krp->krp_callback = cryptodevkey_cb;

for (i = 0; i < CRK_MAXPARAM; i++)
{
Expand Down Expand Up @@ -720,12 +733,100 @@ int cryptodev_key(FAR struct crypt_kop *kop)
return error;
}

static int cryptodevkey_cb(FAR struct cryptkop *krp)
{
TAILQ_INSERT_TAIL(&krp->krp_fcr->crpk_ret, krp, krp_next);
if (krp->krp_fcr->fds != NULL)
{
poll_notify(&krp->krp_fcr->fds, 1, POLLIN);
}

return OK;
}

static int cryptodev_getkeystatus(struct fcrypt *fcr, struct crypt_kop *ret)
{
FAR struct cryptkop *krp = NULL;
int i;
int size;

if (TAILQ_EMPTY(&fcr->crpk_ret))
{
return -EAGAIN;
}

/* return the result in task list to the upper layer */

krp = TAILQ_FIRST(&fcr->crpk_ret);
TAILQ_REMOVE(&fcr->crpk_ret, krp, krp_next);

ret->crk_op = krp->krp_op;
ret->crk_status = krp->krp_status;
ret->crk_iparams = krp->krp_iparams;
ret->crk_oparams = krp->krp_oparams;
for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++)
{
size = (krp->krp_param[i].crp_nbits + 7) / 8;

/* copy result into oparams */

if (i < ret->crk_iparams || size == 0)
{
continue;
}

memcpy(ret->crk_param[i].crp_p, krp->krp_param[i].crp_p, size);
}

/* free asynchronous result */

for (i = 0; i < CRK_MAXPARAM; i++)
{
if (krp->krp_param[i].crp_p)
{
explicit_bzero(krp->krp_param[i].crp_p,
(krp->krp_param[i].crp_nbits + 7) / 8);
kmm_free(krp->krp_param[i].crp_p);
}
}

kmm_free(krp);
return OK;
}

/* ARGSUSED */

static int cryptof_poll(FAR struct file *filep,
FAR struct pollfd *fds, bool setup)
{
return 0;
FAR struct fcrypt *fcr = filep->f_priv;

if (fcr == NULL || fds == NULL)
{
return -EINVAL;
}

if (setup)
{
if (!TAILQ_EMPTY(&fcr->crpk_ret))
{
poll_notify(&fds, 1, POLLIN);
return OK;
}

if (fcr->fds)
{
return -EBUSY;
}

fcr->fds = fds;
}
else
{
fcr->fds = NULL;
}

return OK;
}

/* ARGSUSED */
Expand All @@ -734,16 +835,33 @@ static int cryptof_close(FAR struct file *filep)
{
FAR struct fcrypt *fcr = filep->f_priv;
FAR struct csession *cse;
FAR struct cryptkop *krp;
int i;

while ((cse = TAILQ_FIRST(&fcr->csessions)))
{
TAILQ_REMOVE(&fcr->csessions, cse, next);
(void)csefree(cse);
}

kmm_free(fcr);
filep->f_priv = NULL;
while ((krp = TAILQ_FIRST(&fcr->crpk_ret)))
{
TAILQ_REMOVE(&fcr->crpk_ret, krp, krp_next);
for (i = 0; i < CRK_MAXPARAM; i++)
{
if (krp->krp_param[i].crp_p)
{
explicit_bzero(krp->krp_param[i].crp_p,
(krp->krp_param[i].crp_nbits + 7) / 8);
kmm_free(krp->krp_param[i].crp_p);
}
}

kmm_free(krp);
}

kmm_free(fcr);
filep->f_priv = NULL;
return 0;
}

Expand Down Expand Up @@ -899,8 +1017,14 @@ static int cryptoioctl(FAR struct file *filep, int cmd, unsigned long arg)
switch (cmd)
{
case CRIOGET:
fcr = kmm_malloc(sizeof(struct fcrypt));
fcr = kmm_zalloc(sizeof(struct fcrypt));
if (fcr == NULL)
{
return -ENOMEM;
}

TAILQ_INIT(&fcr->csessions);
TAILQ_INIT(&fcr->crpk_ret);

fd = file_allocate(&g_cryptoinode, 0,
0, fcr, 0, true);
Expand All @@ -921,7 +1045,7 @@ static int cryptoioctl(FAR struct file *filep, int cmd, unsigned long arg)
return error;
}

FAR struct csession *csefind(FAR struct fcrypt *fcr, u_int ses)
static FAR struct csession *csefind(FAR struct fcrypt *fcr, u_int ses)
{
FAR struct csession *cse;

Expand All @@ -934,7 +1058,7 @@ FAR struct csession *csefind(FAR struct fcrypt *fcr, u_int ses)
return NULL;
}

int csedelete(FAR struct fcrypt *fcr, FAR struct csession *cse_del)
static int csedelete(FAR struct fcrypt *fcr, FAR struct csession *cse_del)
{
FAR struct csession *cse;

Expand All @@ -950,19 +1074,19 @@ int csedelete(FAR struct fcrypt *fcr, FAR struct csession *cse_del)
return 0;
}

FAR struct csession *cseadd(FAR struct fcrypt *fcr,
FAR struct csession *cse)
static FAR struct csession *cseadd(FAR struct fcrypt *fcr,
FAR struct csession *cse)
{
TAILQ_INSERT_TAIL(&fcr->csessions, cse, next);
cse->ses = fcr->sesn++;
return cse;
}

FAR struct csession *csecreate(FAR struct fcrypt *fcr, uint64_t sid,
caddr_t key, uint64_t keylen,
caddr_t mackey, uint64_t mackeylen,
uint32_t cipher, uint32_t mac,
bool txform, bool thash)
static FAR struct csession *csecreate(FAR struct fcrypt *fcr, uint64_t sid,
caddr_t key, uint64_t keylen,
caddr_t mackey, uint64_t mackeylen,
uint32_t cipher, uint32_t mac,
bool txform, bool thash)
{
FAR struct csession *cse;

Expand All @@ -985,7 +1109,7 @@ FAR struct csession *csecreate(FAR struct fcrypt *fcr, uint64_t sid,
return cse;
}

int csefree(FAR struct csession *cse)
static int csefree(FAR struct csession *cse)
{
int error;

Expand Down
14 changes: 12 additions & 2 deletions include/crypto/cryptodev.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
****************************************************************************/

#include <sys/types.h>
#include <sys/queue.h>

/* Some initial values */

Expand Down Expand Up @@ -210,6 +211,8 @@ struct cryptop
#define CRYPTO_F_REL 0x0004 /* Must return data in same place */
#define CRYPTO_F_NOQUEUE 0x0008 /* Don't use crypto queue/thread */
#define CRYPTO_F_DONE 0x0010 /* request completed */
#define CRYPTO_F_CBIMM 0x0020 /* Do callback immediately */
#define CRYPTO_F_CANCEL 0x0040 /* Cancel the current crypto operation */

FAR void *crp_buf; /* Data to be processed */
FAR void *crp_opaque; /* Opaque pointer, passed along */
Expand Down Expand Up @@ -245,8 +248,9 @@ struct crypt_kop
u_int crk_status; /* return status */
u_short crk_iparams; /* # of input parameters */
u_short crk_oparams; /* # of output parameters */
u_int crk_pad1;
u_int crk_flags;
struct crparam crk_param[CRK_MAXPARAM];
uint32_t crk_reqid;
};

#define CRK_MOD_EXP 0
Expand All @@ -273,13 +277,18 @@ struct crypt_kop

struct cryptkop
{
TAILQ_ENTRY(cryptkop) krp_next;
u_int krp_op; /* ie. CRK_MOD_EXP or other */
u_int krp_status; /* return status */
u_short krp_iparams; /* # of input parameters */
u_short krp_oparams; /* # of output parameters */
uint32_t krp_hid;
struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
CODE int (*krp_callback)(FAR struct cryptkop *);

FAR struct fcrypt *krp_fcr;
u_int krp_flags; /* same as cryptop */
uint32_t krp_reqid; /* distinguish tasks in asynchronous calling */
};

/* Crypto capabilities structure */
Expand Down Expand Up @@ -376,7 +385,8 @@ extern const uint8_t hmac_opad_buffer[HMAC_MAX_BLOCK_LEN];
#define CIOCFSESSION 102
#define CIOCCRYPT 103
#define CIOCKEY 104
#define CIOCASYMFEAT 105
#define CIOCKEYRET 105
#define CIOCASYMFEAT 106

int crypto_newsession(FAR uint64_t *, FAR struct cryptoini *, int);
int crypto_freesession(uint64_t);
Expand Down

0 comments on commit 2febfb8

Please sign in to comment.