forked from nuttx/nuttx-update
nuttx/crypto: export asynchronous calling process
Signed-off-by: makejian <makejian@xiaomi.com>
This commit is contained in:
parent
f49d5f4451
commit
5b1d910ec6
2 changed files with 173 additions and 39 deletions
|
@ -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>
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -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
|
||||
****************************************************************************/
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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,
|
||||
|
@ -365,7 +367,10 @@ bail:
|
|||
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);
|
||||
|
@ -377,8 +382,8 @@ bail:
|
|||
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;
|
||||
|
@ -549,7 +554,7 @@ bail:
|
|||
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;
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -720,12 +733,100 @@ fail:
|
|||
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 */
|
||||
|
@ -734,6 +835,8 @@ 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)))
|
||||
{
|
||||
|
@ -741,9 +844,24 @@ static int cryptof_close(FAR struct file *filep)
|
|||
(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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
/* Some initial values */
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -273,6 +277,7 @@ 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 */
|
||||
|
@ -280,6 +285,10 @@ struct cryptkop
|
|||
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 */
|
||||
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue