mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 23:40:19 +08:00
nuttx/crypto: export asynchronous calling process
Signed-off-by: makejian <makejian@xiaomi.com>
This commit is contained in:
+161
-37
@@ -36,7 +36,6 @@
|
|||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/queue.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
@@ -94,7 +93,9 @@ struct csession
|
|||||||
struct fcrypt
|
struct fcrypt
|
||||||
{
|
{
|
||||||
TAILQ_HEAD(csessionlist, csession) csessions;
|
TAILQ_HEAD(csessionlist, csession) csessions;
|
||||||
|
TAILQ_HEAD(cryptkoplist, cryptkop) crpk_ret;
|
||||||
int sesn;
|
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 cryptoclose(FAR struct file *filep);
|
||||||
static int cryptoioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
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
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -154,6 +172,7 @@ static const struct file_operations g_cryptoops =
|
|||||||
|
|
||||||
static struct inode g_cryptoinode =
|
static struct inode g_cryptoinode =
|
||||||
{
|
{
|
||||||
|
.i_flags = FSNODEFLAG_TYPE_DRIVER,
|
||||||
.i_crefs = 1,
|
.i_crefs = 1,
|
||||||
.u.i_ops = &g_cryptofops
|
.u.i_ops = &g_cryptofops
|
||||||
};
|
};
|
||||||
@@ -162,23 +181,6 @@ static struct inode g_cryptoinode =
|
|||||||
* Private Functions
|
* 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 */
|
/* ARGSUSED */
|
||||||
|
|
||||||
static ssize_t cryptof_read(FAR struct file *filep,
|
static ssize_t cryptof_read(FAR struct file *filep,
|
||||||
@@ -365,7 +367,10 @@ bail:
|
|||||||
error = cryptodev_op(cse, cop);
|
error = cryptodev_op(cse, cop);
|
||||||
break;
|
break;
|
||||||
case CIOCKEY:
|
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;
|
break;
|
||||||
case CIOCASYMFEAT:
|
case CIOCASYMFEAT:
|
||||||
error = crypto_getfeat((FAR int *)arg);
|
error = crypto_getfeat((FAR int *)arg);
|
||||||
@@ -377,8 +382,8 @@ bail:
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cryptodev_op(FAR struct csession *cse,
|
static int cryptodev_op(FAR struct csession *cse,
|
||||||
FAR struct crypt_op *cop)
|
FAR struct crypt_op *cop)
|
||||||
{
|
{
|
||||||
FAR struct cryptop *crp = NULL;
|
FAR struct cryptop *crp = NULL;
|
||||||
FAR struct cryptodesc *crde = NULL;
|
FAR struct cryptodesc *crde = NULL;
|
||||||
@@ -549,7 +554,7 @@ bail:
|
|||||||
return error;
|
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;
|
FAR struct cryptkop *krp = NULL;
|
||||||
int error = -EINVAL;
|
int error = -EINVAL;
|
||||||
@@ -642,11 +647,19 @@ int cryptodev_key(FAR struct crypt_kop *kop)
|
|||||||
}
|
}
|
||||||
|
|
||||||
krp = kmm_zalloc(sizeof *krp);
|
krp = kmm_zalloc(sizeof *krp);
|
||||||
|
if (krp == NULL)
|
||||||
|
{
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
krp->krp_op = kop->crk_op;
|
krp->krp_op = kop->crk_op;
|
||||||
krp->krp_status = kop->crk_status;
|
|
||||||
krp->krp_iparams = kop->crk_iparams;
|
krp->krp_iparams = kop->crk_iparams;
|
||||||
krp->krp_oparams = kop->crk_oparams;
|
krp->krp_oparams = kop->crk_oparams;
|
||||||
krp->krp_status = 0;
|
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++)
|
for (i = 0; i < CRK_MAXPARAM; i++)
|
||||||
{
|
{
|
||||||
@@ -720,12 +733,100 @@ fail:
|
|||||||
return error;
|
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 */
|
/* ARGSUSED */
|
||||||
|
|
||||||
static int cryptof_poll(FAR struct file *filep,
|
static int cryptof_poll(FAR struct file *filep,
|
||||||
FAR struct pollfd *fds, bool setup)
|
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 */
|
/* ARGSUSED */
|
||||||
@@ -734,6 +835,8 @@ static int cryptof_close(FAR struct file *filep)
|
|||||||
{
|
{
|
||||||
FAR struct fcrypt *fcr = filep->f_priv;
|
FAR struct fcrypt *fcr = filep->f_priv;
|
||||||
FAR struct csession *cse;
|
FAR struct csession *cse;
|
||||||
|
FAR struct cryptkop *krp;
|
||||||
|
int i;
|
||||||
|
|
||||||
while ((cse = TAILQ_FIRST(&fcr->csessions)))
|
while ((cse = TAILQ_FIRST(&fcr->csessions)))
|
||||||
{
|
{
|
||||||
@@ -741,9 +844,24 @@ static int cryptof_close(FAR struct file *filep)
|
|||||||
(void)csefree(cse);
|
(void)csefree(cse);
|
||||||
}
|
}
|
||||||
|
|
||||||
kmm_free(fcr);
|
while ((krp = TAILQ_FIRST(&fcr->crpk_ret)))
|
||||||
filep->f_priv = NULL;
|
{
|
||||||
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -899,8 +1017,14 @@ static int cryptoioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case CRIOGET:
|
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->csessions);
|
||||||
|
TAILQ_INIT(&fcr->crpk_ret);
|
||||||
|
|
||||||
fd = file_allocate(&g_cryptoinode, 0,
|
fd = file_allocate(&g_cryptoinode, 0,
|
||||||
0, fcr, 0, true);
|
0, fcr, 0, true);
|
||||||
@@ -921,7 +1045,7 @@ static int cryptoioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
|||||||
return error;
|
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;
|
FAR struct csession *cse;
|
||||||
|
|
||||||
@@ -934,7 +1058,7 @@ FAR struct csession *csefind(FAR struct fcrypt *fcr, u_int ses)
|
|||||||
return NULL;
|
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;
|
FAR struct csession *cse;
|
||||||
|
|
||||||
@@ -950,19 +1074,19 @@ int csedelete(FAR struct fcrypt *fcr, FAR struct csession *cse_del)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FAR struct csession *cseadd(FAR struct fcrypt *fcr,
|
static FAR struct csession *cseadd(FAR struct fcrypt *fcr,
|
||||||
FAR struct csession *cse)
|
FAR struct csession *cse)
|
||||||
{
|
{
|
||||||
TAILQ_INSERT_TAIL(&fcr->csessions, cse, next);
|
TAILQ_INSERT_TAIL(&fcr->csessions, cse, next);
|
||||||
cse->ses = fcr->sesn++;
|
cse->ses = fcr->sesn++;
|
||||||
return cse;
|
return cse;
|
||||||
}
|
}
|
||||||
|
|
||||||
FAR struct csession *csecreate(FAR struct fcrypt *fcr, uint64_t sid,
|
static FAR struct csession *csecreate(FAR struct fcrypt *fcr, uint64_t sid,
|
||||||
caddr_t key, uint64_t keylen,
|
caddr_t key, uint64_t keylen,
|
||||||
caddr_t mackey, uint64_t mackeylen,
|
caddr_t mackey, uint64_t mackeylen,
|
||||||
uint32_t cipher, uint32_t mac,
|
uint32_t cipher, uint32_t mac,
|
||||||
bool txform, bool thash)
|
bool txform, bool thash)
|
||||||
{
|
{
|
||||||
FAR struct csession *cse;
|
FAR struct csession *cse;
|
||||||
|
|
||||||
@@ -985,7 +1109,7 @@ FAR struct csession *csecreate(FAR struct fcrypt *fcr, uint64_t sid,
|
|||||||
return cse;
|
return cse;
|
||||||
}
|
}
|
||||||
|
|
||||||
int csefree(FAR struct csession *cse)
|
static int csefree(FAR struct csession *cse)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/queue.h>
|
||||||
|
|
||||||
/* Some initial values */
|
/* Some initial values */
|
||||||
|
|
||||||
@@ -210,6 +211,8 @@ struct cryptop
|
|||||||
#define CRYPTO_F_REL 0x0004 /* Must return data in same place */
|
#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_NOQUEUE 0x0008 /* Don't use crypto queue/thread */
|
||||||
#define CRYPTO_F_DONE 0x0010 /* request completed */
|
#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_buf; /* Data to be processed */
|
||||||
FAR void *crp_opaque; /* Opaque pointer, passed along */
|
FAR void *crp_opaque; /* Opaque pointer, passed along */
|
||||||
@@ -245,8 +248,9 @@ struct crypt_kop
|
|||||||
u_int crk_status; /* return status */
|
u_int crk_status; /* return status */
|
||||||
u_short crk_iparams; /* # of input parameters */
|
u_short crk_iparams; /* # of input parameters */
|
||||||
u_short crk_oparams; /* # of output parameters */
|
u_short crk_oparams; /* # of output parameters */
|
||||||
u_int crk_pad1;
|
u_int crk_flags;
|
||||||
struct crparam crk_param[CRK_MAXPARAM];
|
struct crparam crk_param[CRK_MAXPARAM];
|
||||||
|
uint32_t crk_reqid;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CRK_MOD_EXP 0
|
#define CRK_MOD_EXP 0
|
||||||
@@ -273,6 +277,7 @@ struct crypt_kop
|
|||||||
|
|
||||||
struct cryptkop
|
struct cryptkop
|
||||||
{
|
{
|
||||||
|
TAILQ_ENTRY(cryptkop) krp_next;
|
||||||
u_int krp_op; /* ie. CRK_MOD_EXP or other */
|
u_int krp_op; /* ie. CRK_MOD_EXP or other */
|
||||||
u_int krp_status; /* return status */
|
u_int krp_status; /* return status */
|
||||||
u_short krp_iparams; /* # of input parameters */
|
u_short krp_iparams; /* # of input parameters */
|
||||||
@@ -280,6 +285,10 @@ struct cryptkop
|
|||||||
uint32_t krp_hid;
|
uint32_t krp_hid;
|
||||||
struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
|
struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
|
||||||
CODE int (*krp_callback)(FAR struct cryptkop *);
|
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 */
|
/* Crypto capabilities structure */
|
||||||
@@ -376,7 +385,8 @@ extern const uint8_t hmac_opad_buffer[HMAC_MAX_BLOCK_LEN];
|
|||||||
#define CIOCFSESSION 102
|
#define CIOCFSESSION 102
|
||||||
#define CIOCCRYPT 103
|
#define CIOCCRYPT 103
|
||||||
#define CIOCKEY 104
|
#define CIOCKEY 104
|
||||||
#define CIOCASYMFEAT 105
|
#define CIOCKEYRET 105
|
||||||
|
#define CIOCASYMFEAT 106
|
||||||
|
|
||||||
int crypto_newsession(FAR uint64_t *, FAR struct cryptoini *, int);
|
int crypto_newsession(FAR uint64_t *, FAR struct cryptoini *, int);
|
||||||
int crypto_freesession(uint64_t);
|
int crypto_freesession(uint64_t);
|
||||||
|
|||||||
Reference in New Issue
Block a user