Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nuttx/crypto: export asynchronous calling process #13696

Merged
merged 1 commit into from
Sep 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading