Move cryptof_ioctl() below the routines it calls.
Reviewed by: markj Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D27069
This commit is contained in:
parent
b19d4c075f
commit
f5074add75
@ -381,13 +381,6 @@ static struct csession *csecreate(struct fcrypt *, crypto_session_t,
|
||||
struct auth_hash *, void *);
|
||||
static void csefree(struct csession *);
|
||||
|
||||
static int cryptodev_op(struct csession *, const struct crypt_op *,
|
||||
struct ucred *, struct thread *);
|
||||
static int cryptodev_aead(struct csession *, struct crypt_aead *,
|
||||
struct ucred *, struct thread *);
|
||||
static int cryptodev_key(struct crypt_kop *);
|
||||
static int cryptodev_find(struct crypt_find_op *);
|
||||
|
||||
/*
|
||||
* Check a crypto identifier to see if it requested
|
||||
* a software device/driver. This can be done either
|
||||
@ -713,194 +706,6 @@ cryptodev_create_session(struct fcrypt *fcr, struct session2_op *sop)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
cryptof_ioctl(struct file *fp, u_long cmd, void *data,
|
||||
struct ucred *active_cred, struct thread *td)
|
||||
{
|
||||
static struct timeval keywarn, featwarn;
|
||||
struct fcrypt *fcr = fp->f_data;
|
||||
struct csession *cse;
|
||||
struct session2_op *sop;
|
||||
struct crypt_op *cop;
|
||||
struct crypt_aead *caead;
|
||||
struct crypt_kop *kop;
|
||||
uint32_t ses;
|
||||
int error = 0;
|
||||
union {
|
||||
struct session2_op sopc;
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
struct crypt_op copc;
|
||||
struct crypt_aead aeadc;
|
||||
struct crypt_kop kopc;
|
||||
#endif
|
||||
} thunk;
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
u_long cmd32;
|
||||
void *data32;
|
||||
|
||||
cmd32 = 0;
|
||||
data32 = NULL;
|
||||
switch (cmd) {
|
||||
case CIOCGSESSION32:
|
||||
cmd32 = cmd;
|
||||
data32 = data;
|
||||
cmd = CIOCGSESSION;
|
||||
data = &thunk.sopc;
|
||||
session_op_from_32((struct session_op32 *)data32, &thunk.sopc);
|
||||
break;
|
||||
case CIOCGSESSION232:
|
||||
cmd32 = cmd;
|
||||
data32 = data;
|
||||
cmd = CIOCGSESSION2;
|
||||
data = &thunk.sopc;
|
||||
session2_op_from_32((struct session2_op32 *)data32,
|
||||
&thunk.sopc);
|
||||
break;
|
||||
case CIOCCRYPT32:
|
||||
cmd32 = cmd;
|
||||
data32 = data;
|
||||
cmd = CIOCCRYPT;
|
||||
data = &thunk.copc;
|
||||
crypt_op_from_32((struct crypt_op32 *)data32, &thunk.copc);
|
||||
break;
|
||||
case CIOCCRYPTAEAD32:
|
||||
cmd32 = cmd;
|
||||
data32 = data;
|
||||
cmd = CIOCCRYPTAEAD;
|
||||
data = &thunk.aeadc;
|
||||
crypt_aead_from_32((struct crypt_aead32 *)data32, &thunk.aeadc);
|
||||
break;
|
||||
case CIOCKEY32:
|
||||
case CIOCKEY232:
|
||||
cmd32 = cmd;
|
||||
data32 = data;
|
||||
if (cmd == CIOCKEY32)
|
||||
cmd = CIOCKEY;
|
||||
else
|
||||
cmd = CIOCKEY2;
|
||||
data = &thunk.kopc;
|
||||
crypt_kop_from_32((struct crypt_kop32 *)data32, &thunk.kopc);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (cmd) {
|
||||
case CIOCGSESSION:
|
||||
case CIOCGSESSION2:
|
||||
if (cmd == CIOCGSESSION) {
|
||||
session2_op_from_op(data, &thunk.sopc);
|
||||
sop = &thunk.sopc;
|
||||
} else
|
||||
sop = (struct session2_op *)data;
|
||||
|
||||
error = cryptodev_create_session(fcr, sop);
|
||||
if (cmd == CIOCGSESSION && error == 0)
|
||||
session2_op_to_op(sop, data);
|
||||
break;
|
||||
case CIOCFSESSION:
|
||||
ses = *(uint32_t *)data;
|
||||
if (!csedelete(fcr, ses)) {
|
||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
||||
return (EINVAL);
|
||||
}
|
||||
break;
|
||||
case CIOCCRYPT:
|
||||
cop = (struct crypt_op *)data;
|
||||
cse = csefind(fcr, cop->ses);
|
||||
if (cse == NULL) {
|
||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
||||
return (EINVAL);
|
||||
}
|
||||
error = cryptodev_op(cse, cop, active_cred, td);
|
||||
csefree(cse);
|
||||
break;
|
||||
case CIOCKEY:
|
||||
case CIOCKEY2:
|
||||
if (ratecheck(&keywarn, &warninterval))
|
||||
gone_in(14,
|
||||
"Asymmetric crypto operations via /dev/crypto");
|
||||
|
||||
if (!crypto_userasymcrypto) {
|
||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
||||
return (EPERM); /* XXX compat? */
|
||||
}
|
||||
kop = (struct crypt_kop *)data;
|
||||
if (cmd == CIOCKEY) {
|
||||
/* NB: crypto core enforces s/w driver use */
|
||||
kop->crk_crid =
|
||||
CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
|
||||
}
|
||||
mtx_lock(&Giant);
|
||||
error = cryptodev_key(kop);
|
||||
mtx_unlock(&Giant);
|
||||
break;
|
||||
case CIOCASYMFEAT:
|
||||
if (ratecheck(&featwarn, &warninterval))
|
||||
gone_in(14,
|
||||
"Asymmetric crypto features via /dev/crypto");
|
||||
|
||||
if (!crypto_userasymcrypto) {
|
||||
/*
|
||||
* NB: if user asym crypto operations are
|
||||
* not permitted return "no algorithms"
|
||||
* so well-behaved applications will just
|
||||
* fallback to doing them in software.
|
||||
*/
|
||||
*(int *)data = 0;
|
||||
} else {
|
||||
error = crypto_getfeat((int *)data);
|
||||
if (error)
|
||||
SDT_PROBE1(opencrypto, dev, ioctl, error,
|
||||
__LINE__);
|
||||
}
|
||||
break;
|
||||
case CIOCFINDDEV:
|
||||
error = cryptodev_find((struct crypt_find_op *)data);
|
||||
break;
|
||||
case CIOCCRYPTAEAD:
|
||||
caead = (struct crypt_aead *)data;
|
||||
cse = csefind(fcr, caead->ses);
|
||||
if (cse == NULL) {
|
||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
||||
return (EINVAL);
|
||||
}
|
||||
error = cryptodev_aead(cse, caead, active_cred, td);
|
||||
csefree(cse);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
switch (cmd32) {
|
||||
case CIOCGSESSION32:
|
||||
if (error == 0)
|
||||
session_op_to_32(data, data32);
|
||||
break;
|
||||
case CIOCGSESSION232:
|
||||
if (error == 0)
|
||||
session2_op_to_32(data, data32);
|
||||
break;
|
||||
case CIOCCRYPT32:
|
||||
if (error == 0)
|
||||
crypt_op_to_32(data, data32);
|
||||
break;
|
||||
case CIOCCRYPTAEAD32:
|
||||
if (error == 0)
|
||||
crypt_aead_to_32(data, data32);
|
||||
break;
|
||||
case CIOCKEY32:
|
||||
case CIOCKEY232:
|
||||
crypt_kop_to_32(data, data32);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return (error);
|
||||
}
|
||||
|
||||
static struct cryptop_data *
|
||||
cod_alloc(struct csession *cse, size_t aad_len, size_t len, struct thread *td)
|
||||
{
|
||||
@ -1498,6 +1303,193 @@ cryptodev_find(struct crypt_find_op *find)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
cryptof_ioctl(struct file *fp, u_long cmd, void *data,
|
||||
struct ucred *active_cred, struct thread *td)
|
||||
{
|
||||
static struct timeval keywarn, featwarn;
|
||||
struct fcrypt *fcr = fp->f_data;
|
||||
struct csession *cse;
|
||||
struct session2_op *sop;
|
||||
struct crypt_op *cop;
|
||||
struct crypt_aead *caead;
|
||||
struct crypt_kop *kop;
|
||||
uint32_t ses;
|
||||
int error = 0;
|
||||
union {
|
||||
struct session2_op sopc;
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
struct crypt_op copc;
|
||||
struct crypt_aead aeadc;
|
||||
struct crypt_kop kopc;
|
||||
#endif
|
||||
} thunk;
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
u_long cmd32;
|
||||
void *data32;
|
||||
|
||||
cmd32 = 0;
|
||||
data32 = NULL;
|
||||
switch (cmd) {
|
||||
case CIOCGSESSION32:
|
||||
cmd32 = cmd;
|
||||
data32 = data;
|
||||
cmd = CIOCGSESSION;
|
||||
data = &thunk.sopc;
|
||||
session_op_from_32((struct session_op32 *)data32, &thunk.sopc);
|
||||
break;
|
||||
case CIOCGSESSION232:
|
||||
cmd32 = cmd;
|
||||
data32 = data;
|
||||
cmd = CIOCGSESSION2;
|
||||
data = &thunk.sopc;
|
||||
session2_op_from_32((struct session2_op32 *)data32,
|
||||
&thunk.sopc);
|
||||
break;
|
||||
case CIOCCRYPT32:
|
||||
cmd32 = cmd;
|
||||
data32 = data;
|
||||
cmd = CIOCCRYPT;
|
||||
data = &thunk.copc;
|
||||
crypt_op_from_32((struct crypt_op32 *)data32, &thunk.copc);
|
||||
break;
|
||||
case CIOCCRYPTAEAD32:
|
||||
cmd32 = cmd;
|
||||
data32 = data;
|
||||
cmd = CIOCCRYPTAEAD;
|
||||
data = &thunk.aeadc;
|
||||
crypt_aead_from_32((struct crypt_aead32 *)data32, &thunk.aeadc);
|
||||
break;
|
||||
case CIOCKEY32:
|
||||
case CIOCKEY232:
|
||||
cmd32 = cmd;
|
||||
data32 = data;
|
||||
if (cmd == CIOCKEY32)
|
||||
cmd = CIOCKEY;
|
||||
else
|
||||
cmd = CIOCKEY2;
|
||||
data = &thunk.kopc;
|
||||
crypt_kop_from_32((struct crypt_kop32 *)data32, &thunk.kopc);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (cmd) {
|
||||
case CIOCGSESSION:
|
||||
case CIOCGSESSION2:
|
||||
if (cmd == CIOCGSESSION) {
|
||||
session2_op_from_op(data, &thunk.sopc);
|
||||
sop = &thunk.sopc;
|
||||
} else
|
||||
sop = (struct session2_op *)data;
|
||||
|
||||
error = cryptodev_create_session(fcr, sop);
|
||||
if (cmd == CIOCGSESSION && error == 0)
|
||||
session2_op_to_op(sop, data);
|
||||
break;
|
||||
case CIOCFSESSION:
|
||||
ses = *(uint32_t *)data;
|
||||
if (!csedelete(fcr, ses)) {
|
||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
||||
return (EINVAL);
|
||||
}
|
||||
break;
|
||||
case CIOCCRYPT:
|
||||
cop = (struct crypt_op *)data;
|
||||
cse = csefind(fcr, cop->ses);
|
||||
if (cse == NULL) {
|
||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
||||
return (EINVAL);
|
||||
}
|
||||
error = cryptodev_op(cse, cop, active_cred, td);
|
||||
csefree(cse);
|
||||
break;
|
||||
case CIOCKEY:
|
||||
case CIOCKEY2:
|
||||
if (ratecheck(&keywarn, &warninterval))
|
||||
gone_in(14,
|
||||
"Asymmetric crypto operations via /dev/crypto");
|
||||
|
||||
if (!crypto_userasymcrypto) {
|
||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
||||
return (EPERM); /* XXX compat? */
|
||||
}
|
||||
kop = (struct crypt_kop *)data;
|
||||
if (cmd == CIOCKEY) {
|
||||
/* NB: crypto core enforces s/w driver use */
|
||||
kop->crk_crid =
|
||||
CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
|
||||
}
|
||||
mtx_lock(&Giant);
|
||||
error = cryptodev_key(kop);
|
||||
mtx_unlock(&Giant);
|
||||
break;
|
||||
case CIOCASYMFEAT:
|
||||
if (ratecheck(&featwarn, &warninterval))
|
||||
gone_in(14,
|
||||
"Asymmetric crypto features via /dev/crypto");
|
||||
|
||||
if (!crypto_userasymcrypto) {
|
||||
/*
|
||||
* NB: if user asym crypto operations are
|
||||
* not permitted return "no algorithms"
|
||||
* so well-behaved applications will just
|
||||
* fallback to doing them in software.
|
||||
*/
|
||||
*(int *)data = 0;
|
||||
} else {
|
||||
error = crypto_getfeat((int *)data);
|
||||
if (error)
|
||||
SDT_PROBE1(opencrypto, dev, ioctl, error,
|
||||
__LINE__);
|
||||
}
|
||||
break;
|
||||
case CIOCFINDDEV:
|
||||
error = cryptodev_find((struct crypt_find_op *)data);
|
||||
break;
|
||||
case CIOCCRYPTAEAD:
|
||||
caead = (struct crypt_aead *)data;
|
||||
cse = csefind(fcr, caead->ses);
|
||||
if (cse == NULL) {
|
||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
||||
return (EINVAL);
|
||||
}
|
||||
error = cryptodev_aead(cse, caead, active_cred, td);
|
||||
csefree(cse);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef COMPAT_FREEBSD32
|
||||
switch (cmd32) {
|
||||
case CIOCGSESSION32:
|
||||
if (error == 0)
|
||||
session_op_to_32(data, data32);
|
||||
break;
|
||||
case CIOCGSESSION232:
|
||||
if (error == 0)
|
||||
session2_op_to_32(data, data32);
|
||||
break;
|
||||
case CIOCCRYPT32:
|
||||
if (error == 0)
|
||||
crypt_op_to_32(data, data32);
|
||||
break;
|
||||
case CIOCCRYPTAEAD32:
|
||||
if (error == 0)
|
||||
crypt_aead_to_32(data, data32);
|
||||
break;
|
||||
case CIOCKEY32:
|
||||
case CIOCKEY232:
|
||||
crypt_kop_to_32(data, data32);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
cryptof_stat(struct file *fp, struct stat *sb, struct ucred *active_cred,
|
||||
|
Loading…
Reference in New Issue
Block a user