Changeset View
Changeset View
Standalone View
Standalone View
head/sys/opencrypto/cryptodev.c
Show First 20 Lines • Show All 277 Lines • ▼ Show 20 Lines | struct csession { | ||||
void *mackey; | void *mackey; | ||||
}; | }; | ||||
struct cryptop_data { | struct cryptop_data { | ||||
struct csession *cse; | struct csession *cse; | ||||
char *buf; | char *buf; | ||||
char *obuf; | char *obuf; | ||||
char *aad; | |||||
bool done; | bool done; | ||||
}; | }; | ||||
struct fcrypt { | struct fcrypt { | ||||
TAILQ_HEAD(csessionlist, csession) csessions; | TAILQ_HEAD(csessionlist, csession) csessions; | ||||
int sesn; | int sesn; | ||||
struct mtx lock; | struct mtx lock; | ||||
}; | }; | ||||
static bool use_outputbuffers; | static bool use_outputbuffers; | ||||
SYSCTL_BOOL(_kern_crypto, OID_AUTO, cryptodev_use_output, CTLFLAG_RW, | SYSCTL_BOOL(_kern_crypto, OID_AUTO, cryptodev_use_output, CTLFLAG_RW, | ||||
&use_outputbuffers, 0, | &use_outputbuffers, 0, | ||||
"Use separate output buffers for /dev/crypto requests."); | "Use separate output buffers for /dev/crypto requests."); | ||||
static bool use_separate_aad; | |||||
SYSCTL_BOOL(_kern_crypto, OID_AUTO, cryptodev_separate_aad, CTLFLAG_RW, | |||||
&use_separate_aad, 0, | |||||
"Use separate AAD buffer for /dev/crypto requests."); | |||||
static int cryptof_ioctl(struct file *, u_long, void *, | static int cryptof_ioctl(struct file *, u_long, void *, | ||||
struct ucred *, struct thread *); | struct ucred *, struct thread *); | ||||
static int cryptof_stat(struct file *, struct stat *, | static int cryptof_stat(struct file *, struct stat *, | ||||
struct ucred *, struct thread *); | struct ucred *, struct thread *); | ||||
static int cryptof_close(struct file *, struct thread *); | static int cryptof_close(struct file *, struct thread *); | ||||
static int cryptof_fill_kinfo(struct file *, struct kinfo_file *, | static int cryptof_fill_kinfo(struct file *, struct kinfo_file *, | ||||
struct filedesc *); | struct filedesc *); | ||||
▲ Show 20 Lines • Show All 291 Lines • ▼ Show 20 Lines | #endif | ||||
csp.csp_mode = CSP_MODE_AEAD; | csp.csp_mode = CSP_MODE_AEAD; | ||||
} else if (txform && thash) | } else if (txform && thash) | ||||
csp.csp_mode = CSP_MODE_ETA; | csp.csp_mode = CSP_MODE_ETA; | ||||
else if (txform) | else if (txform) | ||||
csp.csp_mode = CSP_MODE_CIPHER; | csp.csp_mode = CSP_MODE_CIPHER; | ||||
else | else | ||||
csp.csp_mode = CSP_MODE_DIGEST; | csp.csp_mode = CSP_MODE_DIGEST; | ||||
switch (csp.csp_mode) { | |||||
case CSP_MODE_AEAD: | |||||
case CSP_MODE_ETA: | |||||
if (use_separate_aad) | |||||
csp.csp_flags |= CSP_F_SEPARATE_AAD; | |||||
break; | |||||
} | |||||
if (txform) { | if (txform) { | ||||
csp.csp_cipher_alg = txform->type; | csp.csp_cipher_alg = txform->type; | ||||
csp.csp_cipher_klen = sop->keylen; | csp.csp_cipher_klen = sop->keylen; | ||||
if (sop->keylen > txform->maxkey || | if (sop->keylen > txform->maxkey || | ||||
sop->keylen < txform->minkey) { | sop->keylen < txform->minkey) { | ||||
CRYPTDEB("invalid cipher parameters"); | CRYPTDEB("invalid cipher parameters"); | ||||
error = EINVAL; | error = EINVAL; | ||||
SDT_PROBE1(opencrypto, dev, ioctl, error, | SDT_PROBE1(opencrypto, dev, ioctl, error, | ||||
▲ Show 20 Lines • Show All 199 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
return (error); | return (error); | ||||
#undef SES2 | #undef SES2 | ||||
} | } | ||||
static int cryptodev_cb(struct cryptop *); | static int cryptodev_cb(struct cryptop *); | ||||
static struct cryptop_data * | static struct cryptop_data * | ||||
cod_alloc(struct csession *cse, size_t len, struct thread *td) | cod_alloc(struct csession *cse, size_t aad_len, size_t len, struct thread *td) | ||||
{ | { | ||||
struct cryptop_data *cod; | struct cryptop_data *cod; | ||||
cod = malloc(sizeof(struct cryptop_data), M_XDATA, M_WAITOK | M_ZERO); | cod = malloc(sizeof(struct cryptop_data), M_XDATA, M_WAITOK | M_ZERO); | ||||
cod->cse = cse; | cod->cse = cse; | ||||
if (crypto_get_params(cse->cses)->csp_flags & CSP_F_SEPARATE_AAD) { | |||||
if (aad_len != 0) | |||||
cod->aad = malloc(aad_len, M_XDATA, M_WAITOK); | |||||
cod->buf = malloc(len, M_XDATA, M_WAITOK); | cod->buf = malloc(len, M_XDATA, M_WAITOK); | ||||
} else | |||||
cod->buf = malloc(aad_len + len, M_XDATA, M_WAITOK); | |||||
if (crypto_get_params(cse->cses)->csp_flags & CSP_F_SEPARATE_OUTPUT) | if (crypto_get_params(cse->cses)->csp_flags & CSP_F_SEPARATE_OUTPUT) | ||||
cod->obuf = malloc(len, M_XDATA, M_WAITOK); | cod->obuf = malloc(len, M_XDATA, M_WAITOK); | ||||
return (cod); | return (cod); | ||||
} | } | ||||
static void | static void | ||||
cod_free(struct cryptop_data *cod) | cod_free(struct cryptop_data *cod) | ||||
{ | { | ||||
free(cod->aad, M_XDATA); | |||||
free(cod->obuf, M_XDATA); | free(cod->obuf, M_XDATA); | ||||
free(cod->buf, M_XDATA); | free(cod->buf, M_XDATA); | ||||
free(cod, M_XDATA); | free(cod, M_XDATA); | ||||
} | } | ||||
static int | static int | ||||
cryptodev_op( | cryptodev_op( | ||||
struct csession *cse, | struct csession *cse, | ||||
Show All 29 Lines | cryptodev_op( | ||||
*/ | */ | ||||
if (cop->flags & COP_F_CIPHER_FIRST) { | if (cop->flags & COP_F_CIPHER_FIRST) { | ||||
if (cop->op != COP_ENCRYPT) { | if (cop->op != COP_ENCRYPT) { | ||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); | SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
} | } | ||||
cod = cod_alloc(cse, cop->len + cse->hashsize, td); | cod = cod_alloc(cse, 0, cop->len + cse->hashsize, td); | ||||
crp = crypto_getreq(cse->cses, M_WAITOK); | crp = crypto_getreq(cse->cses, M_WAITOK); | ||||
error = copyin(cop->src, cod->buf, cop->len); | error = copyin(cop->src, cod->buf, cop->len); | ||||
if (error) { | if (error) { | ||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); | SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); | ||||
goto bail; | goto bail; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 189 Lines • ▼ Show 20 Lines | cryptodev_aead( | ||||
*/ | */ | ||||
if (caead->flags & COP_F_CIPHER_FIRST) { | if (caead->flags & COP_F_CIPHER_FIRST) { | ||||
if (caead->op != COP_ENCRYPT) { | if (caead->op != COP_ENCRYPT) { | ||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); | SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
} | } | ||||
cod = cod_alloc(cse, caead->aadlen + caead->len + cse->hashsize, td); | cod = cod_alloc(cse, caead->aadlen, caead->len + cse->hashsize, td); | ||||
crp = crypto_getreq(cse->cses, M_WAITOK); | crp = crypto_getreq(cse->cses, M_WAITOK); | ||||
if (cod->aad != NULL) | |||||
error = copyin(caead->aad, cod->aad, caead->aadlen); | |||||
else | |||||
error = copyin(caead->aad, cod->buf, caead->aadlen); | error = copyin(caead->aad, cod->buf, caead->aadlen); | ||||
if (error) { | if (error) { | ||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); | SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); | ||||
goto bail; | goto bail; | ||||
} | } | ||||
crp->crp_aad = cod->aad; | |||||
crp->crp_aad_start = 0; | crp->crp_aad_start = 0; | ||||
crp->crp_aad_length = caead->aadlen; | crp->crp_aad_length = caead->aadlen; | ||||
error = copyin(caead->src, cod->buf + caead->aadlen, caead->len); | if (cod->aad != NULL) | ||||
crp->crp_payload_start = 0; | |||||
else | |||||
crp->crp_payload_start = caead->aadlen; | |||||
error = copyin(caead->src, cod->buf + crp->crp_payload_start, | |||||
caead->len); | |||||
if (error) { | if (error) { | ||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); | SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); | ||||
goto bail; | goto bail; | ||||
} | } | ||||
crp->crp_payload_start = caead->aadlen; | |||||
crp->crp_payload_length = caead->len; | crp->crp_payload_length = caead->len; | ||||
if (caead->op == COP_ENCRYPT && cod->obuf != NULL) | if (caead->op == COP_ENCRYPT && cod->obuf != NULL) | ||||
crp->crp_digest_start = caead->len; | crp->crp_digest_start = crp->crp_payload_output_start + | ||||
caead->len; | |||||
else | else | ||||
crp->crp_digest_start = caead->aadlen + caead->len; | crp->crp_digest_start = crp->crp_payload_start + caead->len; | ||||
switch (cse->mode) { | switch (cse->mode) { | ||||
case CSP_MODE_AEAD: | case CSP_MODE_AEAD: | ||||
case CSP_MODE_ETA: | case CSP_MODE_ETA: | ||||
switch (caead->op) { | switch (caead->op) { | ||||
case COP_ENCRYPT: | case COP_ENCRYPT: | ||||
crp->crp_op = CRYPTO_OP_ENCRYPT | | crp->crp_op = CRYPTO_OP_ENCRYPT | | ||||
CRYPTO_OP_COMPUTE_DIGEST; | CRYPTO_OP_COMPUTE_DIGEST; | ||||
Show All 10 Lines | case CSP_MODE_ETA: | ||||
break; | break; | ||||
default: | default: | ||||
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); | SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__); | ||||
error = EINVAL; | error = EINVAL; | ||||
goto bail; | goto bail; | ||||
} | } | ||||
crp->crp_flags = CRYPTO_F_CBIMM | (caead->flags & COP_F_BATCH); | crp->crp_flags = CRYPTO_F_CBIMM | (caead->flags & COP_F_BATCH); | ||||
crypto_use_buf(crp, cod->buf, caead->aadlen + caead->len + | crypto_use_buf(crp, cod->buf, crp->crp_payload_start + caead->len + | ||||
cse->hashsize); | cse->hashsize); | ||||
if (cod->obuf != NULL) | if (cod->obuf != NULL) | ||||
crypto_use_output_buf(crp, cod->obuf, caead->len + | crypto_use_output_buf(crp, cod->obuf, caead->len + | ||||
cse->hashsize); | cse->hashsize); | ||||
crp->crp_callback = cryptodev_cb; | crp->crp_callback = cryptodev_cb; | ||||
crp->crp_opaque = cod; | crp->crp_opaque = cod; | ||||
if (caead->iv) { | if (caead->iv) { | ||||
▲ Show 20 Lines • Show All 458 Lines • Show Last 20 Lines |