Update to FreeBSD head 2018-09-17

Git mirror commit 6c2192b1ef8c50788c751f878552526800b1e319.

Update #3472.
This commit is contained in:
Sebastian Huber
2018-08-22 14:59:50 +02:00
parent 3becda1fef
commit 3489e3b639
579 changed files with 26749 additions and 11388 deletions

View File

@@ -0,0 +1,8 @@
/*
* This trivial work is released to the public domain, or licensed under the
* terms of the CC0, at your option.
* $FreeBSD$
*/
#pragma once
typedef struct crypto_session *crypto_session_t;

View File

@@ -91,6 +91,13 @@ __FBSDID("$FreeBSD$");
#include <machine/pcb.h>
#endif
struct crypto_session {
device_t parent;
void *softc;
uint32_t hid;
uint32_t capabilities;
};
SDT_PROVIDER_DEFINE(opencrypto);
/*
@@ -127,6 +134,7 @@ struct cryptocap {
#define CRYPTOCAP_F_CLEANUP 0x80000000 /* needs resource cleanup */
int cc_qblocked; /* (q) symmetric q blocked */
int cc_kqblocked; /* (q) asymmetric q blocked */
size_t cc_session_size;
};
static struct cryptocap *crypto_drivers = NULL;
static int crypto_drivers_num = 0;
@@ -187,6 +195,7 @@ SYSCTL_INT(_kern, OID_AUTO, crypto_workers_num, CTLFLAG_RDTUN,
static uma_zone_t cryptop_zone;
static uma_zone_t cryptodesc_zone;
static uma_zone_t cryptoses_zone;
int crypto_userasymcrypto = 1; /* userland may do asym crypto reqs */
SYSCTL_INT(_kern, OID_AUTO, userasymcrypto, CTLFLAG_RW,
@@ -205,6 +214,7 @@ static void crypto_ret_proc(struct crypto_ret_worker *ret_worker);
static void crypto_destroy(void);
static int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint);
static int crypto_kinvoke(struct cryptkop *krp, int flags);
static void crypto_remove(struct cryptocap *cap);
static void crypto_task_invoke(void *ctx, int pending);
static void crypto_batch_enqueue(struct cryptop *crp);
@@ -268,7 +278,12 @@ crypto_init(void)
cryptodesc_zone = uma_zcreate("cryptodesc", sizeof (struct cryptodesc),
0, 0, 0, 0,
UMA_ALIGN_PTR, UMA_ZONE_ZINIT);
if (cryptodesc_zone == NULL || cryptop_zone == NULL) {
cryptoses_zone = uma_zcreate("crypto_session",
sizeof(struct crypto_session), NULL, NULL, NULL, NULL,
UMA_ALIGN_PTR, UMA_ZONE_ZINIT);
if (cryptodesc_zone == NULL || cryptop_zone == NULL ||
cryptoses_zone == NULL) {
printf("crypto_init: cannot setup crypto zones\n");
error = ENOMEM;
goto bad;
@@ -395,6 +410,8 @@ crypto_destroy(void)
if (crypto_drivers != NULL)
free(crypto_drivers, M_CRYPTO_DATA);
if (cryptoses_zone != NULL)
uma_zdestroy(cryptoses_zone);
if (cryptodesc_zone != NULL)
uma_zdestroy(cryptodesc_zone);
if (cryptop_zone != NULL)
@@ -408,6 +425,24 @@ crypto_destroy(void)
mtx_destroy(&crypto_drivers_mtx);
}
uint32_t
crypto_ses2hid(crypto_session_t crypto_session)
{
return (crypto_session->hid);
}
uint32_t
crypto_ses2caps(crypto_session_t crypto_session)
{
return (crypto_session->capabilities);
}
void *
crypto_get_driver_session(crypto_session_t crypto_session)
{
return (crypto_session->softc);
}
static struct cryptocap *
crypto_checkdriver(u_int32_t hid)
{
@@ -495,12 +530,19 @@ again:
* must be capable of the requested crypto algorithms.
*/
int
crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int crid)
crypto_newsession(crypto_session_t *cses, struct cryptoini *cri, int crid)
{
crypto_session_t res;
void *softc_mem;
struct cryptocap *cap;
u_int32_t hid, lid;
u_int32_t hid;
size_t softc_size;
int err;
restart:
res = NULL;
softc_mem = NULL;
CRYPTO_DRIVER_LOCK();
if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
/*
@@ -520,24 +562,53 @@ crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int crid)
* XXX layer right about here.
*/
}
if (cap != NULL) {
/* Call the driver initialization routine. */
hid = cap - crypto_drivers;
lid = hid; /* Pass the driver ID. */
err = CRYPTODEV_NEWSESSION(cap->cc_dev, &lid, cri);
if (err == 0) {
(*sid) = (cap->cc_flags & 0xff000000)
| (hid & 0x00ffffff);
(*sid) <<= 32;
(*sid) |= (lid & 0xffffffff);
cap->cc_sessions++;
} else
CRYPTDEB("dev newsession failed: %d", err);
} else {
if (cap == NULL) {
CRYPTDEB("no driver");
err = EOPNOTSUPP;
goto out;
}
cap->cc_sessions++;
softc_size = cap->cc_session_size;
hid = cap - crypto_drivers;
cap = NULL;
CRYPTO_DRIVER_UNLOCK();
softc_mem = malloc(softc_size, M_CRYPTO_DATA, M_WAITOK | M_ZERO);
res = uma_zalloc(cryptoses_zone, M_WAITOK | M_ZERO);
res->softc = softc_mem;
CRYPTO_DRIVER_LOCK();
cap = crypto_checkdriver(hid);
if (cap != NULL && (cap->cc_flags & CRYPTOCAP_F_CLEANUP) != 0) {
cap->cc_sessions--;
crypto_remove(cap);
cap = NULL;
}
if (cap == NULL) {
free(softc_mem, M_CRYPTO_DATA);
uma_zfree(cryptoses_zone, res);
CRYPTO_DRIVER_UNLOCK();
goto restart;
}
/* Call the driver initialization routine. */
err = CRYPTODEV_NEWSESSION(cap->cc_dev, res, cri);
if (err != 0) {
CRYPTDEB("dev newsession failed: %d", err);
goto out;
}
res->capabilities = cap->cc_flags & 0xff000000;
res->hid = hid;
*cses = res;
out:
CRYPTO_DRIVER_UNLOCK();
if (err != 0) {
free(softc_mem, M_CRYPTO_DATA);
if (res != NULL)
uma_zfree(cryptoses_zone, res);
}
return err;
}
@@ -554,41 +625,41 @@ crypto_remove(struct cryptocap *cap)
* Delete an existing session (or a reserved session on an unregistered
* driver).
*/
int
crypto_freesession(u_int64_t sid)
void
crypto_freesession(crypto_session_t cses)
{
struct cryptocap *cap;
void *ses;
size_t ses_size;
u_int32_t hid;
int err;
if (cses == NULL)
return;
CRYPTO_DRIVER_LOCK();
if (crypto_drivers == NULL) {
err = EINVAL;
goto done;
}
/* Determine two IDs. */
hid = CRYPTO_SESID2HID(sid);
if (hid >= crypto_drivers_num) {
err = ENOENT;
goto done;
}
hid = crypto_ses2hid(cses);
KASSERT(hid < crypto_drivers_num,
("bogus crypto_session %p hid %u", cses, hid));
cap = &crypto_drivers[hid];
ses = cses->softc;
ses_size = cap->cc_session_size;
if (cap->cc_sessions)
cap->cc_sessions--;
/* Call the driver cleanup routine, if available. */
err = CRYPTODEV_FREESESSION(cap->cc_dev, sid);
CRYPTODEV_FREESESSION(cap->cc_dev, cses);
explicit_bzero(ses, ses_size);
free(ses, M_CRYPTO_DATA);
uma_zfree(cryptoses_zone, cses);
if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
crypto_remove(cap);
done:
CRYPTO_DRIVER_UNLOCK();
return err;
}
/*
@@ -596,7 +667,7 @@ done:
* support for the algorithms they handle.
*/
int32_t
crypto_get_driverid(device_t dev, int flags)
crypto_get_driverid(device_t dev, size_t sessionsize, int flags)
{
struct cryptocap *newdrv;
int i;
@@ -646,6 +717,7 @@ crypto_get_driverid(device_t dev, int flags)
crypto_drivers[i].cc_sessions = 1; /* Mark */
crypto_drivers[i].cc_dev = dev;
crypto_drivers[i].cc_flags = flags;
crypto_drivers[i].cc_session_size = sessionsize;
if (bootverbose)
printf("crypto: assign %s driver id %u, flags 0x%x\n",
device_get_nameunit(dev), i, flags);
@@ -903,7 +975,7 @@ crypto_dispatch(struct cryptop *crp)
binuptime(&crp->crp_tstamp);
#endif
crp->crp_retw_id = crp->crp_sid % crypto_workers_num;
crp->crp_retw_id = ((uintptr_t)crp->crp_session) % crypto_workers_num;
if (CRYPTOP_ASYNC(crp)) {
if (crp->crp_flags & CRYPTO_F_ASYNC_KEEPORDER) {
@@ -922,7 +994,7 @@ crypto_dispatch(struct cryptop *crp)
}
if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) {
hid = CRYPTO_SESID2HID(crp->crp_sid);
hid = crypto_ses2hid(crp->crp_session);
/*
* Caller marked the request to be processed
@@ -1143,7 +1215,7 @@ crypto_task_invoke(void *ctx, int pending)
crp = (struct cryptop *)ctx;
hid = CRYPTO_SESID2HID(crp->crp_sid);
hid = crypto_ses2hid(crp->crp_session);
cap = crypto_checkdriver(hid);
result = crypto_invoke(cap, crp, 0);
@@ -1169,7 +1241,7 @@ crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint)
#endif
if (cap->cc_flags & CRYPTOCAP_F_CLEANUP) {
struct cryptodesc *crd;
u_int64_t nid;
crypto_session_t nses;
/*
* Driver has unregistered; migrate the session and return
@@ -1178,15 +1250,15 @@ crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint)
* XXX: What if there are more already queued requests for this
* session?
*/
crypto_freesession(crp->crp_sid);
crypto_freesession(crp->crp_session);
for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
/* XXX propagate flags from initial session? */
if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI),
if (crypto_newsession(&nses, &(crp->crp_desc->CRD_INI),
CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE) == 0)
crp->crp_sid = nid;
crp->crp_session = nses;
crp->crp_etype = EAGAIN;
crypto_done(crp);
@@ -1292,7 +1364,7 @@ crypto_done(struct cryptop *crp)
if (!CRYPTOP_ASYNC_KEEPORDER(crp) &&
((crp->crp_flags & CRYPTO_F_CBIMM) ||
((crp->crp_flags & CRYPTO_F_CBIFSYNC) &&
(CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC)))) {
(crypto_ses2caps(crp->crp_session) & CRYPTOCAP_F_SYNC)))) {
/*
* Do the callback directly. This is ok when the
* callback routine does very little (e.g. the
@@ -1454,7 +1526,7 @@ crypto_proc(void)
submit = NULL;
hint = 0;
TAILQ_FOREACH(crp, &crp_q, crp_next) {
hid = CRYPTO_SESID2HID(crp->crp_sid);
hid = crypto_ses2hid(crp->crp_session);
cap = crypto_checkdriver(hid);
/*
* Driver cannot disappeared when there is an active
@@ -1478,7 +1550,7 @@ crypto_proc(void)
* better to just use a per-driver
* queue instead.
*/
if (CRYPTO_SESID2HID(submit->crp_sid) == hid)
if (crypto_ses2hid(submit->crp_session) == hid)
hint = CRYPTO_HINT_MORE;
break;
} else {
@@ -1491,7 +1563,7 @@ crypto_proc(void)
}
if (submit != NULL) {
TAILQ_REMOVE(&crp_q, submit, crp_next);
hid = CRYPTO_SESID2HID(submit->crp_sid);
hid = crypto_ses2hid(submit->crp_session);
cap = crypto_checkdriver(hid);
KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
__func__, __LINE__));
@@ -1507,7 +1579,7 @@ crypto_proc(void)
* it at the end does not work.
*/
/* XXX validate sid again? */
crypto_drivers[CRYPTO_SESID2HID(submit->crp_sid)].cc_qblocked = 1;
crypto_drivers[crypto_ses2hid(submit->crp_session)].cc_qblocked = 1;
TAILQ_INSERT_HEAD(&crp_q, submit, crp_next);
cryptostats.cs_blocks++;
}
@@ -1696,8 +1768,8 @@ DB_SHOW_COMMAND(crypto, db_show_crypto)
"Desc", "Callback");
TAILQ_FOREACH(crp, &crp_q, crp_next) {
db_printf("%4u %08x %4u %4u %4u %04x %8p %8p\n"
, (int) CRYPTO_SESID2HID(crp->crp_sid)
, (int) CRYPTO_SESID2CAPS(crp->crp_sid)
, (int) crypto_ses2hid(crp->crp_session)
, (int) crypto_ses2caps(crp->crp_session)
, crp->crp_ilen, crp->crp_olen
, crp->crp_etype
, crp->crp_flags
@@ -1712,7 +1784,7 @@ DB_SHOW_COMMAND(crypto, db_show_crypto)
TAILQ_FOREACH(crp, &ret_worker->crp_ret_q, crp_next) {
db_printf("%8td %4u %4u %04x %8p\n"
, CRYPTO_RETW_ID(ret_worker)
, (int) CRYPTO_SESID2HID(crp->crp_sid)
, (int) crypto_ses2hid(crp->crp_session)
, crp->crp_etype
, crp->crp_flags
, crp->crp_callback

View File

@@ -267,7 +267,7 @@ crypt_kop_to_32(const struct crypt_kop *from, struct crypt_kop32 *to)
struct csession {
TAILQ_ENTRY(csession) next;
u_int64_t sid;
crypto_session_t cses;
u_int32_t ses;
struct mtx lock; /* for op submission */
@@ -326,10 +326,10 @@ static const rtems_filesystem_file_handlers_r cryptofops;
static struct csession *csefind(struct fcrypt *, u_int);
static int csedelete(struct fcrypt *, struct csession *);
static struct csession *cseadd(struct fcrypt *, struct csession *);
static struct csession *csecreate(struct fcrypt *, u_int64_t, caddr_t,
static struct csession *csecreate(struct fcrypt *, crypto_session_t, caddr_t,
u_int64_t, caddr_t, u_int64_t, u_int32_t, u_int32_t, struct enc_xform *,
struct auth_hash *);
static int csefree(struct csession *);
static void csefree(struct csession *);
static int cryptodev_op(struct csession *, struct crypt_op *,
struct ucred *, struct thread *td);
@@ -384,7 +384,7 @@ cryptof_ioctl(
struct enc_xform *txform = NULL;
struct auth_hash *thash = NULL;
struct crypt_kop *kop;
u_int64_t sid;
crypto_session_t cses;
u_int32_t ses;
int error = 0, crid;
#ifdef COMPAT_FREEBSD32
@@ -463,9 +463,15 @@ cryptof_ioctl(
case CRYPTO_MD5_HMAC:
thash = &auth_hash_hmac_md5;
break;
case CRYPTO_POLY1305:
thash = &auth_hash_poly1305;
break;
case CRYPTO_SHA1_HMAC:
thash = &auth_hash_hmac_sha1;
break;
case CRYPTO_SHA2_224_HMAC:
thash = &auth_hash_hmac_sha2_224;
break;
case CRYPTO_SHA2_256_HMAC:
thash = &auth_hash_hmac_sha2_256;
break;
@@ -492,10 +498,23 @@ cryptof_ioctl(
case CRYPTO_MD5:
thash = &auth_hash_md5;
break;
#endif
case CRYPTO_SHA1:
thash = &auth_hash_sha1;
break;
#endif
case CRYPTO_SHA2_224:
thash = &auth_hash_sha2_224;
break;
case CRYPTO_SHA2_256:
thash = &auth_hash_sha2_256;
break;
case CRYPTO_SHA2_384:
thash = &auth_hash_sha2_384;
break;
case CRYPTO_SHA2_512:
thash = &auth_hash_sha2_512;
break;
case CRYPTO_NULL_HMAC:
thash = &auth_hash_null;
break;
@@ -582,19 +601,19 @@ cryptof_ioctl(
}
} else
crid = CRYPTOCAP_F_HARDWARE;
error = crypto_newsession(&sid, (txform ? &crie : &cria), crid);
error = crypto_newsession(&cses, (txform ? &crie : &cria), crid);
if (error) {
CRYPTDEB("crypto_newsession");
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
goto bail;
}
cse = csecreate(fcr, sid, crie.cri_key, crie.cri_klen,
cse = csecreate(fcr, cses, crie.cri_key, crie.cri_klen,
cria.cri_key, cria.cri_klen, sop->cipher, sop->mac, txform,
thash);
if (cse == NULL) {
crypto_freesession(sid);
crypto_freesession(cses);
error = EINVAL;
SDT_PROBE1(opencrypto, dev, ioctl, error, __LINE__);
CRYPTDEB("csecreate");
@@ -607,7 +626,7 @@ cryptof_ioctl(
#endif
) {
/* return hardware/driver id */
SES2(sop)->crid = CRYPTO_SESID2HID(cse->sid);
SES2(sop)->crid = crypto_ses2hid(cse->cses);
}
bail:
if (error) {
@@ -634,7 +653,7 @@ bail:
return (EINVAL);
}
csedelete(fcr, cse);
error = csefree(cse);
csefree(cse);
break;
case CIOCCRYPT:
#ifdef COMPAT_FREEBSD32
@@ -867,7 +886,7 @@ cryptodev_op(
| (cop->flags & COP_F_BATCH);
crp->crp_uio = &cod->uio;
crp->crp_callback = cryptodev_cb;
crp->crp_sid = cse->sid;
crp->crp_session = cse->cses;
crp->crp_opaque = cod;
if (cop->iv) {
@@ -1043,7 +1062,7 @@ cryptodev_aead(
| (caead->flags & COP_F_BATCH);
crp->crp_uio = &cod->uio;
crp->crp_callback = cryptodev_cb;
crp->crp_sid = cse->sid;
crp->crp_session = cse->cses;
crp->crp_opaque = cod;
if (caead->iv) {
@@ -1318,7 +1337,7 @@ cryptof_close(struct file *fp, struct thread *td)
while ((cse = TAILQ_FIRST(&fcr->csessions))) {
TAILQ_REMOVE(&fcr->csessions, cse, next);
(void)csefree(cse);
csefree(cse);
}
free(fcr, M_XDATA);
fp->f_data = NULL;
@@ -1389,7 +1408,7 @@ cseadd(struct fcrypt *fcr, struct csession *cse)
}
struct csession *
csecreate(struct fcrypt *fcr, u_int64_t sid, caddr_t key, u_int64_t keylen,
csecreate(struct fcrypt *fcr, crypto_session_t cses, caddr_t key, u_int64_t keylen,
caddr_t mackey, u_int64_t mackeylen, u_int32_t cipher, u_int32_t mac,
struct enc_xform *txform, struct auth_hash *thash)
{
@@ -1403,7 +1422,7 @@ csecreate(struct fcrypt *fcr, u_int64_t sid, caddr_t key, u_int64_t keylen,
cse->keylen = keylen/8;
cse->mackey = mackey;
cse->mackeylen = mackeylen/8;
cse->sid = sid;
cse->cses = cses;
cse->cipher = cipher;
cse->mac = mac;
cse->txform = txform;
@@ -1412,19 +1431,17 @@ csecreate(struct fcrypt *fcr, u_int64_t sid, caddr_t key, u_int64_t keylen,
return (cse);
}
static int
static void
csefree(struct csession *cse)
{
int error;
error = crypto_freesession(cse->sid);
crypto_freesession(cse->cses);
mtx_destroy(&cse->lock);
if (cse->key)
free(cse->key, M_XDATA);
if (cse->mackey)
free(cse->mackey, M_XDATA);
free(cse, M_XDATA);
return (error);
}
static int

View File

@@ -65,6 +65,10 @@
#include <sys/ioccom.h>
#include <sys/_task.h>
#ifdef _KERNEL
#include <opencrypto/_cryptodev.h>
#endif
/* Some initial values */
#define CRYPTO_DRIVERS_INITIAL 4
#define CRYPTO_SW_SESSIONS 32
@@ -74,25 +78,29 @@
#define MD5_HASH_LEN 16
#define SHA1_HASH_LEN 20
#define RIPEMD160_HASH_LEN 20
#define SHA2_224_HASH_LEN 28
#define SHA2_256_HASH_LEN 32
#define SHA2_384_HASH_LEN 48
#define SHA2_512_HASH_LEN 64
#define MD5_KPDK_HASH_LEN 16
#define SHA1_KPDK_HASH_LEN 20
#define AES_GMAC_HASH_LEN 16
#define POLY1305_HASH_LEN 16
/* Maximum hash algorithm result length */
#define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */
#define MD5_BLOCK_LEN 64
#define SHA1_BLOCK_LEN 64
#define RIPEMD160_BLOCK_LEN 64
#define SHA2_224_BLOCK_LEN 64
#define SHA2_256_BLOCK_LEN 64
#define SHA2_384_BLOCK_LEN 128
#define SHA2_512_BLOCK_LEN 128
/* HMAC values */
#define NULL_HMAC_BLOCK_LEN 64
#define MD5_HMAC_BLOCK_LEN 64
#define SHA1_HMAC_BLOCK_LEN 64
#define RIPEMD160_HMAC_BLOCK_LEN 64
#define SHA2_256_HMAC_BLOCK_LEN 64
#define SHA2_384_HMAC_BLOCK_LEN 128
#define SHA2_512_HMAC_BLOCK_LEN 128
/* Maximum HMAC block length */
#define HMAC_MAX_BLOCK_LEN SHA2_512_HMAC_BLOCK_LEN /* Keep this updated */
#define HMAC_MAX_BLOCK_LEN SHA2_512_BLOCK_LEN /* Keep this updated */
#define HMAC_IPAD_VAL 0x36
#define HMAC_OPAD_VAL 0x5C
/* HMAC Key Length */
@@ -100,6 +108,8 @@
#define AES_192_GMAC_KEY_LEN 24
#define AES_256_GMAC_KEY_LEN 32
#define POLY1305_KEY_LEN 32
/* Encryption algorithm block sizes */
#define NULL_BLOCK_LEN 4 /* IPsec to maintain alignment */
#define DES_BLOCK_LEN 8
@@ -182,7 +192,14 @@
#define CRYPTO_BLAKE2B 29 /* Blake2b hash */
#define CRYPTO_BLAKE2S 30 /* Blake2s hash */
#define CRYPTO_CHACHA20 31 /* Chacha20 stream cipher */
#define CRYPTO_ALGORITHM_MAX 31 /* Keep updated - see below */
#define CRYPTO_SHA2_224_HMAC 32
#define CRYPTO_RIPEMD160 33
#define CRYPTO_SHA2_224 34
#define CRYPTO_SHA2_256 35
#define CRYPTO_SHA2_384 36
#define CRYPTO_SHA2_512 37
#define CRYPTO_POLY1305 38
#define CRYPTO_ALGORITHM_MAX 38 /* Keep updated - see below */
#define CRYPTO_ALGO_VALID(x) ((x) >= CRYPTO_ALGORITHM_MIN && \
(x) <= CRYPTO_ALGORITHM_MAX)
@@ -216,6 +233,11 @@ struct session_op {
u_int32_t ses; /* returns: session # */
};
/*
* session and crypt _op structs are used by userspace programs to interact
* with /dev/crypto. Confusingly, the internal kernel interface is named
* "cryptop" (no underscore).
*/
struct session2_op {
u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
@@ -399,7 +421,7 @@ struct cryptop {
struct task crp_task;
u_int64_t crp_sid; /* Session ID */
crypto_session_t crp_session; /* Session */
int crp_ilen; /* Input data total length */
int crp_olen; /* Result total length */
@@ -408,7 +430,7 @@ struct cryptop {
* All error codes except EAGAIN
* indicate possible data corruption (as in,
* the data have been touched). On all
* errors, the crp_sid may have changed
* errors, the crp_session may have changed
* (reset to a new one), so the caller
* should always check and use the new
* value on future requests.
@@ -450,7 +472,7 @@ struct cryptop {
#define CRYPTOP_ASYNC(crp) \
(((crp)->crp_flags & CRYPTO_F_ASYNC) && \
CRYPTO_SESID2CAPS((crp)->crp_sid) & CRYPTOCAP_F_SYNC)
crypto_ses2caps((crp)->crp_session) & CRYPTOCAP_F_SYNC)
#define CRYPTOP_ASYNC_KEEPORDER(crp) \
(CRYPTOP_ASYNC(crp) && \
(crp)->crp_flags & CRYPTO_F_ASYNC_KEEPORDER)
@@ -480,25 +502,19 @@ struct cryptkop {
int (*krp_callback)(struct cryptkop *);
};
/*
* Session ids are 64 bits. The lower 32 bits contain a "local id" which
* is a driver-private session identifier. The upper 32 bits contain a
* "hardware id" used by the core crypto code to identify the driver and
* a copy of the driver's capabilities that can be used by client code to
* optimize operation.
*/
#define CRYPTO_SESID2HID(_sid) (((_sid) >> 32) & 0x00ffffff)
#define CRYPTO_SESID2CAPS(_sid) (((_sid) >> 32) & 0xff000000)
#define CRYPTO_SESID2LID(_sid) (((u_int32_t) (_sid)) & 0xffffffff)
uint32_t crypto_ses2hid(crypto_session_t crypto_session);
uint32_t crypto_ses2caps(crypto_session_t crypto_session);
void *crypto_get_driver_session(crypto_session_t crypto_session);
MALLOC_DECLARE(M_CRYPTO_DATA);
extern int crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard);
extern int crypto_freesession(u_int64_t sid);
extern int crypto_newsession(crypto_session_t *cses, struct cryptoini *cri, int hard);
extern void crypto_freesession(crypto_session_t cses);
#define CRYPTOCAP_F_HARDWARE CRYPTO_FLAG_HARDWARE
#define CRYPTOCAP_F_SOFTWARE CRYPTO_FLAG_SOFTWARE
#define CRYPTOCAP_F_SYNC 0x04000000 /* operates synchronously */
extern int32_t crypto_get_driverid(device_t dev, int flags);
extern int32_t crypto_get_driverid(device_t dev, size_t session_size,
int flags);
extern int crypto_find_driver(const char *);
extern device_t crypto_find_device_byhid(int hid);
extern int crypto_getcaps(int hid);

View File

@@ -64,10 +64,6 @@ __FBSDID("$FreeBSD$");
#include <rtems/bsd/local/cryptodev_if.h>
static int32_t swcr_id;
static struct swcr_data **swcr_sessions = NULL;
static u_int32_t swcr_sesnum;
/* Protects swcr_sessions pointer, not data. */
static struct rwlock swcr_sessions_lock;
u_int8_t hmac_ipad_buffer[HMAC_MAX_BLOCK_LEN];
u_int8_t hmac_opad_buffer[HMAC_MAX_BLOCK_LEN];
@@ -76,8 +72,7 @@ static int swcr_encdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
static int swcr_authcompute(struct cryptodesc *, struct swcr_data *, caddr_t, int);
static int swcr_authenc(struct cryptop *crp);
static int swcr_compdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
static int swcr_freesession(device_t dev, u_int64_t tid);
static int swcr_freesession_locked(device_t dev, u_int64_t tid);
static void swcr_freesession(device_t dev, crypto_session_t cses);
/*
* Apply a symmetric encryption/decryption algorithm.
@@ -328,7 +323,7 @@ out:
return (error);
}
static void
static int __result_use_check
swcr_authprepare(struct auth_hash *axf, struct swcr_data *sw, u_char *key,
int klen)
{
@@ -339,6 +334,7 @@ swcr_authprepare(struct auth_hash *axf, struct swcr_data *sw, u_char *key,
switch (axf->type) {
case CRYPTO_MD5_HMAC:
case CRYPTO_SHA1_HMAC:
case CRYPTO_SHA2_224_HMAC:
case CRYPTO_SHA2_256_HMAC:
case CRYPTO_SHA2_384_HMAC:
case CRYPTO_SHA2_512_HMAC:
@@ -383,6 +379,12 @@ swcr_authprepare(struct auth_hash *axf, struct swcr_data *sw, u_char *key,
axf->Final(buf, sw->sw_ictx);
break;
}
case CRYPTO_POLY1305:
if (klen != POLY1305_KEY_LEN) {
CRYPTDEB("bad poly1305 key size %d", klen);
return EINVAL;
}
/* FALLTHROUGH */
case CRYPTO_BLAKE2B:
case CRYPTO_BLAKE2S:
axf->Setkey(sw->sw_ictx, key, klen);
@@ -391,7 +393,9 @@ swcr_authprepare(struct auth_hash *axf, struct swcr_data *sw, u_char *key,
default:
printf("%s: CRD_F_KEY_EXPLICIT flag given, but algorithm %d "
"doesn't use keys.\n", __func__, axf->type);
return EINVAL;
}
return 0;
}
/*
@@ -411,8 +415,11 @@ swcr_authcompute(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
axf = sw->sw_axf;
if (crd->crd_flags & CRD_F_KEY_EXPLICIT)
swcr_authprepare(axf, sw, crd->crd_key, crd->crd_klen);
if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
err = swcr_authprepare(axf, sw, crd->crd_key, crd->crd_klen);
if (err != 0)
return err;
}
bcopy(sw->sw_ictx, &ctx, axf->ctxsize);
@@ -422,8 +429,17 @@ swcr_authcompute(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
return err;
switch (sw->sw_alg) {
case CRYPTO_SHA1:
case CRYPTO_SHA2_224:
case CRYPTO_SHA2_256:
case CRYPTO_SHA2_384:
case CRYPTO_SHA2_512:
axf->Final(aalg, &ctx);
break;
case CRYPTO_MD5_HMAC:
case CRYPTO_SHA1_HMAC:
case CRYPTO_SHA2_224_HMAC:
case CRYPTO_SHA2_256_HMAC:
case CRYPTO_SHA2_384_HMAC:
case CRYPTO_SHA2_512_HMAC:
@@ -457,6 +473,7 @@ swcr_authcompute(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
case CRYPTO_BLAKE2B:
case CRYPTO_BLAKE2S:
case CRYPTO_NULL_HMAC:
case CRYPTO_POLY1305:
axf->Final(aalg, &ctx);
break;
}
@@ -482,6 +499,7 @@ swcr_authenc(struct cryptop *crp)
u_char uaalg[AALG_MAX_RESULT_LEN];
u_char iv[EALG_MAX_BLOCK_LEN];
union authctx ctx;
struct swcr_session *ses;
struct cryptodesc *crd, *crda = NULL, *crde = NULL;
struct swcr_data *sw, *swa, *swe = NULL;
struct auth_hash *axf = NULL;
@@ -492,14 +510,16 @@ swcr_authenc(struct cryptop *crp)
ivlen = blksz = iskip = oskip = 0;
ses = crypto_get_driver_session(crp->crp_session);
for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
for (sw = swcr_sessions[crp->crp_sid & 0xffffffff];
sw && sw->sw_alg != crd->crd_alg;
sw = sw->sw_next)
for (i = 0; i < nitems(ses->swcr_algorithms) &&
ses->swcr_algorithms[i].sw_alg != crd->crd_alg; i++)
;
if (sw == NULL)
if (i == nitems(ses->swcr_algorithms))
return (EINVAL);
sw = &ses->swcr_algorithms[i];
switch (sw->sw_alg) {
case CRYPTO_AES_NIST_GCM_16:
case CRYPTO_AES_NIST_GMAC:
@@ -732,68 +752,24 @@ swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw,
* Generate a new software session.
*/
static int
swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
swcr_newsession(device_t dev, crypto_session_t cses, struct cryptoini *cri)
{
struct swcr_data **swd;
struct swcr_session *ses;
struct swcr_data *swd;
struct auth_hash *axf;
struct enc_xform *txf;
struct comp_algo *cxf;
u_int32_t i;
size_t i;
int len;
int error;
if (sid == NULL || cri == NULL)
if (cses == NULL || cri == NULL)
return EINVAL;
rw_wlock(&swcr_sessions_lock);
if (swcr_sessions) {
for (i = 1; i < swcr_sesnum; i++)
if (swcr_sessions[i] == NULL)
break;
} else
i = 1; /* NB: to silence compiler warning */
ses = crypto_get_driver_session(cses);
if (swcr_sessions == NULL || i == swcr_sesnum) {
if (swcr_sessions == NULL) {
i = 1; /* We leave swcr_sessions[0] empty */
swcr_sesnum = CRYPTO_SW_SESSIONS;
} else
swcr_sesnum *= 2;
swd = malloc(swcr_sesnum * sizeof(struct swcr_data *),
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
if (swd == NULL) {
/* Reset session number */
if (swcr_sesnum == CRYPTO_SW_SESSIONS)
swcr_sesnum = 0;
else
swcr_sesnum /= 2;
rw_wunlock(&swcr_sessions_lock);
return ENOBUFS;
}
/* Copy existing sessions */
if (swcr_sessions != NULL) {
bcopy(swcr_sessions, swd,
(swcr_sesnum / 2) * sizeof(struct swcr_data *));
free(swcr_sessions, M_CRYPTO_DATA);
}
swcr_sessions = swd;
}
rw_downgrade(&swcr_sessions_lock);
swd = &swcr_sessions[i];
*sid = i;
while (cri) {
*swd = malloc(sizeof(struct swcr_data),
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
if (*swd == NULL) {
swcr_freesession_locked(dev, i);
rw_runlock(&swcr_sessions_lock);
return ENOBUFS;
}
for (i = 0; cri != NULL && i < nitems(ses->swcr_algorithms); i++) {
swd = &ses->swcr_algorithms[i];
switch (cri->cri_alg) {
case CRYPTO_DES_CBC:
@@ -825,7 +801,7 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
goto enccommon;
case CRYPTO_AES_NIST_GMAC:
txf = &enc_xform_aes_nist_gmac;
(*swd)->sw_exf = txf;
swd->sw_exf = txf;
break;
case CRYPTO_CAMELLIA_CBC:
txf = &enc_xform_camellia;
@@ -838,15 +814,14 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
goto enccommon;
enccommon:
if (cri->cri_key != NULL) {
error = txf->setkey(&((*swd)->sw_kschedule),
error = txf->setkey(&swd->sw_kschedule,
cri->cri_key, cri->cri_klen / 8);
if (error) {
swcr_freesession_locked(dev, i);
rw_runlock(&swcr_sessions_lock);
swcr_freesession(dev, cses);
return error;
}
}
(*swd)->sw_exf = txf;
swd->sw_exf = txf;
break;
case CRYPTO_MD5_HMAC:
@@ -855,6 +830,9 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
case CRYPTO_SHA1_HMAC:
axf = &auth_hash_hmac_sha1;
goto authcommon;
case CRYPTO_SHA2_224_HMAC:
axf = &auth_hash_hmac_sha2_224;
goto authcommon;
case CRYPTO_SHA2_256_HMAC:
axf = &auth_hash_hmac_sha2_256;
goto authcommon;
@@ -870,29 +848,31 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
case CRYPTO_RIPEMD160_HMAC:
axf = &auth_hash_hmac_ripemd_160;
authcommon:
(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
swd->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
if ((*swd)->sw_ictx == NULL) {
swcr_freesession_locked(dev, i);
rw_runlock(&swcr_sessions_lock);
if (swd->sw_ictx == NULL) {
swcr_freesession(dev, cses);
return ENOBUFS;
}
(*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
swd->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
if ((*swd)->sw_octx == NULL) {
swcr_freesession_locked(dev, i);
rw_runlock(&swcr_sessions_lock);
if (swd->sw_octx == NULL) {
swcr_freesession(dev, cses);
return ENOBUFS;
}
if (cri->cri_key != NULL) {
swcr_authprepare(axf, *swd, cri->cri_key,
cri->cri_klen);
error = swcr_authprepare(axf, swd,
cri->cri_key, cri->cri_klen);
if (error != 0) {
swcr_freesession(dev, cses);
return error;
}
}
(*swd)->sw_mlen = cri->cri_mlen;
(*swd)->sw_axf = axf;
swd->sw_mlen = cri->cri_mlen;
swd->sw_axf = axf;
break;
case CRYPTO_MD5_KPDK:
@@ -902,52 +882,66 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
case CRYPTO_SHA1_KPDK:
axf = &auth_hash_key_sha1;
auth2common:
(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
swd->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
if ((*swd)->sw_ictx == NULL) {
swcr_freesession_locked(dev, i);
rw_runlock(&swcr_sessions_lock);
if (swd->sw_ictx == NULL) {
swcr_freesession(dev, cses);
return ENOBUFS;
}
(*swd)->sw_octx = malloc(cri->cri_klen / 8,
swd->sw_octx = malloc(cri->cri_klen / 8,
M_CRYPTO_DATA, M_NOWAIT);
if ((*swd)->sw_octx == NULL) {
swcr_freesession_locked(dev, i);
rw_runlock(&swcr_sessions_lock);
if (swd->sw_octx == NULL) {
swcr_freesession(dev, cses);
return ENOBUFS;
}
/* Store the key so we can "append" it to the payload */
if (cri->cri_key != NULL) {
swcr_authprepare(axf, *swd, cri->cri_key,
cri->cri_klen);
error = swcr_authprepare(axf, swd,
cri->cri_key, cri->cri_klen);
if (error != 0) {
swcr_freesession(dev, cses);
return error;
}
}
(*swd)->sw_mlen = cri->cri_mlen;
(*swd)->sw_axf = axf;
swd->sw_mlen = cri->cri_mlen;
swd->sw_axf = axf;
break;
#ifdef notdef
case CRYPTO_MD5:
axf = &auth_hash_md5;
goto auth3common;
#endif
case CRYPTO_SHA1:
axf = &auth_hash_sha1;
goto auth3common;
case CRYPTO_SHA2_224:
axf = &auth_hash_sha2_224;
goto auth3common;
case CRYPTO_SHA2_256:
axf = &auth_hash_sha2_256;
goto auth3common;
case CRYPTO_SHA2_384:
axf = &auth_hash_sha2_384;
goto auth3common;
case CRYPTO_SHA2_512:
axf = &auth_hash_sha2_512;
auth3common:
(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
swd->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
if ((*swd)->sw_ictx == NULL) {
swcr_freesession_locked(dev, i);
rw_runlock(&swcr_sessions_lock);
if (swd->sw_ictx == NULL) {
swcr_freesession(dev, cses);
return ENOBUFS;
}
axf->Init((*swd)->sw_ictx);
(*swd)->sw_mlen = cri->cri_mlen;
(*swd)->sw_axf = axf;
axf->Init(swd->sw_ictx);
swd->sw_mlen = cri->cri_mlen;
swd->sw_axf = axf;
break;
#endif
case CRYPTO_AES_128_NIST_GMAC:
axf = &auth_hash_nist_gmac_aes_128;
@@ -962,21 +956,19 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
auth4common:
len = cri->cri_klen / 8;
if (len != 16 && len != 24 && len != 32) {
swcr_freesession_locked(dev, i);
rw_runlock(&swcr_sessions_lock);
swcr_freesession(dev, cses);
return EINVAL;
}
(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
swd->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
if ((*swd)->sw_ictx == NULL) {
swcr_freesession_locked(dev, i);
rw_runlock(&swcr_sessions_lock);
if (swd->sw_ictx == NULL) {
swcr_freesession(dev, cses);
return ENOBUFS;
}
axf->Init((*swd)->sw_ictx);
axf->Setkey((*swd)->sw_ictx, cri->cri_key, len);
(*swd)->sw_axf = axf;
axf->Init(swd->sw_ictx);
axf->Setkey(swd->sw_ictx, cri->cri_key, len);
swd->sw_axf = axf;
break;
case CRYPTO_BLAKE2B:
@@ -984,70 +976,56 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
goto auth5common;
case CRYPTO_BLAKE2S:
axf = &auth_hash_blake2s;
goto auth5common;
case CRYPTO_POLY1305:
axf = &auth_hash_poly1305;
auth5common:
(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
swd->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
M_NOWAIT);
if ((*swd)->sw_ictx == NULL) {
swcr_freesession_locked(dev, i);
rw_runlock(&swcr_sessions_lock);
if (swd->sw_ictx == NULL) {
swcr_freesession(dev, cses);
return ENOBUFS;
}
axf->Setkey((*swd)->sw_ictx, cri->cri_key,
axf->Setkey(swd->sw_ictx, cri->cri_key,
cri->cri_klen / 8);
axf->Init((*swd)->sw_ictx);
(*swd)->sw_axf = axf;
axf->Init(swd->sw_ictx);
swd->sw_axf = axf;
break;
case CRYPTO_DEFLATE_COMP:
cxf = &comp_algo_deflate;
(*swd)->sw_cxf = cxf;
swd->sw_cxf = cxf;
break;
default:
swcr_freesession_locked(dev, i);
rw_runlock(&swcr_sessions_lock);
swcr_freesession(dev, cses);
return EINVAL;
}
(*swd)->sw_alg = cri->cri_alg;
swd->sw_alg = cri->cri_alg;
cri = cri->cri_next;
swd = &((*swd)->sw_next);
ses->swcr_nalgs++;
}
if (cri != NULL) {
CRYPTDEB("Bogus session request for three or more algorithms");
return EINVAL;
}
rw_runlock(&swcr_sessions_lock);
return 0;
}
static int
swcr_freesession(device_t dev, u_int64_t tid)
{
int error;
rw_rlock(&swcr_sessions_lock);
error = swcr_freesession_locked(dev, tid);
rw_runlock(&swcr_sessions_lock);
return error;
}
/*
* Free a session.
*/
static int
swcr_freesession_locked(device_t dev, u_int64_t tid)
static void
swcr_freesession(device_t dev, crypto_session_t cses)
{
struct swcr_session *ses;
struct swcr_data *swd;
struct enc_xform *txf;
struct auth_hash *axf;
u_int32_t sid = CRYPTO_SESID2LID(tid);
size_t i;
if (sid > swcr_sesnum || swcr_sessions == NULL ||
swcr_sessions[sid] == NULL)
return EINVAL;
ses = crypto_get_driver_session(cses);
/* Silently accept and return */
if (sid == 0)
return 0;
while ((swd = swcr_sessions[sid]) != NULL) {
swcr_sessions[sid] = swd->sw_next;
for (i = 0; i < nitems(ses->swcr_algorithms); i++) {
swd = &ses->swcr_algorithms[i];
switch (swd->sw_alg) {
case CRYPTO_DES_CBC:
@@ -1071,6 +1049,7 @@ swcr_freesession_locked(device_t dev, u_int64_t tid)
case CRYPTO_MD5_HMAC:
case CRYPTO_SHA1_HMAC:
case CRYPTO_SHA2_224_HMAC:
case CRYPTO_SHA2_256_HMAC:
case CRYPTO_SHA2_384_HMAC:
case CRYPTO_SHA2_512_HMAC:
@@ -1105,7 +1084,12 @@ swcr_freesession_locked(device_t dev, u_int64_t tid)
case CRYPTO_BLAKE2B:
case CRYPTO_BLAKE2S:
case CRYPTO_MD5:
case CRYPTO_POLY1305:
case CRYPTO_SHA1:
case CRYPTO_SHA2_224:
case CRYPTO_SHA2_256:
case CRYPTO_SHA2_384:
case CRYPTO_SHA2_512:
axf = swd->sw_axf;
if (swd->sw_ictx) {
@@ -1118,10 +1102,7 @@ swcr_freesession_locked(device_t dev, u_int64_t tid)
/* Nothing to do */
break;
}
free(swd, M_CRYPTO_DATA);
}
return 0;
}
/*
@@ -1130,9 +1111,10 @@ swcr_freesession_locked(device_t dev, u_int64_t tid)
static int
swcr_process(device_t dev, struct cryptop *crp, int hint)
{
struct swcr_session *ses;
struct cryptodesc *crd;
struct swcr_data *sw;
u_int32_t lid;
size_t i;
/* Sanity check */
if (crp == NULL)
@@ -1143,15 +1125,7 @@ swcr_process(device_t dev, struct cryptop *crp, int hint)
goto done;
}
lid = CRYPTO_SESID2LID(crp->crp_sid);
rw_rlock(&swcr_sessions_lock);
if (swcr_sessions == NULL || lid >= swcr_sesnum || lid == 0 ||
swcr_sessions[lid] == NULL) {
rw_runlock(&swcr_sessions_lock);
crp->crp_etype = ENOENT;
goto done;
}
rw_runlock(&swcr_sessions_lock);
ses = crypto_get_driver_session(crp->crp_session);
/* Go through crypto descriptors, processing as we go */
for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
@@ -1165,23 +1139,16 @@ swcr_process(device_t dev, struct cryptop *crp, int hint)
* XXX between the various instances of an algorithm (so we can
* XXX locate the correct crypto context).
*/
rw_rlock(&swcr_sessions_lock);
if (swcr_sessions == NULL) {
rw_runlock(&swcr_sessions_lock);
crp->crp_etype = ENOENT;
goto done;
}
for (sw = swcr_sessions[lid];
sw && sw->sw_alg != crd->crd_alg;
sw = sw->sw_next)
for (i = 0; i < nitems(ses->swcr_algorithms) &&
ses->swcr_algorithms[i].sw_alg != crd->crd_alg; i++)
;
rw_runlock(&swcr_sessions_lock);
/* No such context ? */
if (sw == NULL) {
if (i == nitems(ses->swcr_algorithms)) {
crp->crp_etype = EINVAL;
goto done;
}
sw = &ses->swcr_algorithms[i];
switch (sw->sw_alg) {
case CRYPTO_DES_CBC:
case CRYPTO_3DES_CBC:
@@ -1202,6 +1169,7 @@ swcr_process(device_t dev, struct cryptop *crp, int hint)
break;
case CRYPTO_MD5_HMAC:
case CRYPTO_SHA1_HMAC:
case CRYPTO_SHA2_224_HMAC:
case CRYPTO_SHA2_256_HMAC:
case CRYPTO_SHA2_384_HMAC:
case CRYPTO_SHA2_512_HMAC:
@@ -1211,8 +1179,13 @@ swcr_process(device_t dev, struct cryptop *crp, int hint)
case CRYPTO_SHA1_KPDK:
case CRYPTO_MD5:
case CRYPTO_SHA1:
case CRYPTO_SHA2_224:
case CRYPTO_SHA2_256:
case CRYPTO_SHA2_384:
case CRYPTO_SHA2_512:
case CRYPTO_BLAKE2B:
case CRYPTO_BLAKE2S:
case CRYPTO_POLY1305:
if ((crp->crp_etype = swcr_authcompute(crd, sw,
crp->crp_buf, crp->crp_flags)) != 0)
goto done;
@@ -1265,11 +1238,10 @@ swcr_probe(device_t dev)
static int
swcr_attach(device_t dev)
{
rw_init(&swcr_sessions_lock, "swcr_sessions_lock");
memset(hmac_ipad_buffer, HMAC_IPAD_VAL, HMAC_MAX_BLOCK_LEN);
memset(hmac_opad_buffer, HMAC_OPAD_VAL, HMAC_MAX_BLOCK_LEN);
swcr_id = crypto_get_driverid(dev,
swcr_id = crypto_get_driverid(dev, sizeof(struct swcr_session),
CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
if (swcr_id < 0) {
device_printf(dev, "cannot initialize!");
@@ -1285,6 +1257,7 @@ swcr_attach(device_t dev)
REGISTER(CRYPTO_NULL_CBC);
REGISTER(CRYPTO_MD5_HMAC);
REGISTER(CRYPTO_SHA1_HMAC);
REGISTER(CRYPTO_SHA2_224_HMAC);
REGISTER(CRYPTO_SHA2_256_HMAC);
REGISTER(CRYPTO_SHA2_384_HMAC);
REGISTER(CRYPTO_SHA2_512_HMAC);
@@ -1294,6 +1267,10 @@ swcr_attach(device_t dev)
REGISTER(CRYPTO_SHA1_KPDK);
REGISTER(CRYPTO_MD5);
REGISTER(CRYPTO_SHA1);
REGISTER(CRYPTO_SHA2_224);
REGISTER(CRYPTO_SHA2_256);
REGISTER(CRYPTO_SHA2_384);
REGISTER(CRYPTO_SHA2_512);
REGISTER(CRYPTO_RIJNDAEL128_CBC);
REGISTER(CRYPTO_AES_XTS);
REGISTER(CRYPTO_AES_ICM);
@@ -1307,6 +1284,7 @@ swcr_attach(device_t dev)
REGISTER(CRYPTO_BLAKE2B);
REGISTER(CRYPTO_BLAKE2S);
REGISTER(CRYPTO_CHACHA20);
REGISTER(CRYPTO_POLY1305);
#undef REGISTER
return 0;
@@ -1316,11 +1294,6 @@ static int
swcr_detach(device_t dev)
{
crypto_unregister_all(swcr_id);
rw_wlock(&swcr_sessions_lock);
free(swcr_sessions, M_CRYPTO_DATA);
swcr_sessions = NULL;
rw_wunlock(&swcr_sessions_lock);
rw_destroy(&swcr_sessions_lock);
return 0;
}

View File

@@ -55,8 +55,11 @@ struct swcr_data {
#define sw_exf SWCR_UN.SWCR_ENC.SW_exf
#define sw_size SWCR_UN.SWCR_COMP.SW_size
#define sw_cxf SWCR_UN.SWCR_COMP.SW_cxf
};
struct swcr_data *sw_next;
struct swcr_session {
struct swcr_data swcr_algorithms[2];
unsigned swcr_nalgs;
};
#ifdef _KERNEL

View File

@@ -69,14 +69,21 @@ extern struct auth_hash auth_hash_key_sha1;
extern struct auth_hash auth_hash_hmac_md5;
extern struct auth_hash auth_hash_hmac_sha1;
extern struct auth_hash auth_hash_hmac_ripemd_160;
extern struct auth_hash auth_hash_hmac_sha2_224;
extern struct auth_hash auth_hash_hmac_sha2_256;
extern struct auth_hash auth_hash_hmac_sha2_384;
extern struct auth_hash auth_hash_hmac_sha2_512;
extern struct auth_hash auth_hash_sha1;
extern struct auth_hash auth_hash_sha2_224;
extern struct auth_hash auth_hash_sha2_256;
extern struct auth_hash auth_hash_sha2_384;
extern struct auth_hash auth_hash_sha2_512;
extern struct auth_hash auth_hash_nist_gmac_aes_128;
extern struct auth_hash auth_hash_nist_gmac_aes_192;
extern struct auth_hash auth_hash_nist_gmac_aes_256;
extern struct auth_hash auth_hash_blake2b;
extern struct auth_hash auth_hash_blake2s;
extern struct auth_hash auth_hash_poly1305;
union authctx {
MD5_CTX md5ctx;

View File

@@ -59,10 +59,10 @@ static int MD5Update_int(void *, const u_int8_t *, u_int16_t);
struct auth_hash auth_hash_hmac_md5 = {
.type = CRYPTO_MD5_HMAC,
.name = "HMAC-MD5",
.keysize = MD5_HMAC_BLOCK_LEN,
.keysize = MD5_BLOCK_LEN,
.hashsize = MD5_HASH_LEN,
.ctxsize = sizeof(MD5_CTX),
.blocksize = MD5_HMAC_BLOCK_LEN,
.blocksize = MD5_BLOCK_LEN,
.Init = (void (*) (void *)) MD5Init,
.Update = MD5Update_int,
.Final = (void (*) (u_int8_t *, void *)) MD5Final,

View File

@@ -0,0 +1,93 @@
#include <machine/rtems-bsd-kernel-space.h>
/* This file is in the public domain. */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <opencrypto/xform_auth.h>
#include <opencrypto/xform_poly1305.h>
#include <sodium/crypto_onetimeauth_poly1305.h>
struct poly1305_xform_ctx {
struct crypto_onetimeauth_poly1305_state state;
};
CTASSERT(sizeof(union authctx) >= sizeof(struct poly1305_xform_ctx));
CTASSERT(POLY1305_KEY_LEN == crypto_onetimeauth_poly1305_KEYBYTES);
CTASSERT(POLY1305_HASH_LEN == crypto_onetimeauth_poly1305_BYTES);
void
Poly1305_Init(struct poly1305_xform_ctx *polyctx)
{
/* Nop */
}
void
Poly1305_Setkey(struct poly1305_xform_ctx *polyctx,
const uint8_t key[__min_size(POLY1305_KEY_LEN)], size_t klen)
{
int rc;
if (klen != POLY1305_KEY_LEN)
panic("%s: Bogus keylen: %u bytes", __func__, (unsigned)klen);
rc = crypto_onetimeauth_poly1305_init(&polyctx->state, key);
if (rc != 0)
panic("%s: Invariant violated: %d", __func__, rc);
}
static void
xform_Poly1305_Setkey(void *ctx, const uint8_t *key, uint16_t klen)
{
Poly1305_Setkey(ctx, key, klen);
}
int
Poly1305_Update(struct poly1305_xform_ctx *polyctx, const void *data,
size_t len)
{
int rc;
rc = crypto_onetimeauth_poly1305_update(&polyctx->state, data, len);
if (rc != 0)
panic("%s: Invariant violated: %d", __func__, rc);
return (0);
}
static int
xform_Poly1305_Update(void *ctx, const uint8_t *data, uint16_t len)
{
return (Poly1305_Update(ctx, data, len));
}
void
Poly1305_Final(uint8_t digest[__min_size(POLY1305_HASH_LEN)],
struct poly1305_xform_ctx *polyctx)
{
int rc;
rc = crypto_onetimeauth_poly1305_final(&polyctx->state, digest);
if (rc != 0)
panic("%s: Invariant violated: %d", __func__, rc);
}
static void
xform_Poly1305_Final(uint8_t *digest, void *ctx)
{
Poly1305_Final(digest, ctx);
}
struct auth_hash auth_hash_poly1305 = {
.type = CRYPTO_POLY1305,
.name = "Poly-1305",
.keysize = POLY1305_KEY_LEN,
.hashsize = POLY1305_HASH_LEN,
.ctxsize = sizeof(struct poly1305_xform_ctx),
.blocksize = crypto_onetimeauth_poly1305_BYTES,
.Init = (void *)Poly1305_Init,
.Setkey = xform_Poly1305_Setkey,
.Update = xform_Poly1305_Update,
.Final = xform_Poly1305_Final,
};

View File

@@ -0,0 +1,16 @@
/* This file is in the public domain. */
/* $FreeBSD$ */
#pragma once
#include <sys/types.h>
struct poly1305_xform_ctx;
void Poly1305_Init(struct poly1305_xform_ctx *);
void Poly1305_Setkey(struct poly1305_xform_ctx *,
const uint8_t [__min_size(32)], size_t);
int Poly1305_Update(struct poly1305_xform_ctx *, const void *, size_t);
void Poly1305_Final(uint8_t [__min_size(16)], struct poly1305_xform_ctx *);

View File

@@ -59,10 +59,10 @@ static int RMD160Update_int(void *, const u_int8_t *, u_int16_t);
struct auth_hash auth_hash_hmac_ripemd_160 = {
.type = CRYPTO_RIPEMD160_HMAC,
.name = "HMAC-RIPEMD-160",
.keysize = RIPEMD160_HMAC_BLOCK_LEN,
.keysize = RIPEMD160_BLOCK_LEN,
.hashsize = RIPEMD160_HASH_LEN,
.ctxsize = sizeof(RMD160_CTX),
.blocksize = RIPEMD160_HMAC_BLOCK_LEN,
.blocksize = RIPEMD160_BLOCK_LEN,
.Init = (void (*)(void *)) RMD160Init,
.Update = RMD160Update_int,
.Final = (void (*)(u_int8_t *, void *)) RMD160Final,

View File

@@ -57,14 +57,26 @@ static void SHA1Init_int(void *);
static int SHA1Update_int(void *, const u_int8_t *, u_int16_t);
static void SHA1Final_int(u_int8_t *, void *);
/* Plain hash */
struct auth_hash auth_hash_sha1 = {
.type = CRYPTO_SHA1,
.name = "SHA1",
.hashsize = SHA1_HASH_LEN,
.ctxsize = sizeof(SHA1_CTX),
.blocksize = SHA1_BLOCK_LEN,
.Init = SHA1Init_int,
.Update = SHA1Update_int,
.Final = SHA1Final_int,
};
/* Authentication instances */
struct auth_hash auth_hash_hmac_sha1 = {
.type = CRYPTO_SHA1_HMAC,
.name = "HMAC-SHA1",
.keysize = SHA1_HMAC_BLOCK_LEN,
.keysize = SHA1_BLOCK_LEN,
.hashsize = SHA1_HASH_LEN,
.ctxsize = sizeof(SHA1_CTX),
.blocksize = SHA1_HMAC_BLOCK_LEN,
.blocksize = SHA1_BLOCK_LEN,
.Init = SHA1Init_int,
.Update = SHA1Update_int,
.Final = SHA1Final_int,

View File

@@ -50,23 +50,85 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <crypto/sha2/sha224.h>
#include <crypto/sha2/sha256.h>
#include <crypto/sha2/sha384.h>
#include <crypto/sha2/sha512.h>
#include <opencrypto/xform_auth.h>
static int SHA224Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA256Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA384Update_int(void *, const u_int8_t *, u_int16_t);
static int SHA512Update_int(void *, const u_int8_t *, u_int16_t);
/* Plain hashes */
struct auth_hash auth_hash_sha2_224 = {
.type = CRYPTO_SHA2_224,
.name = "SHA2-224",
.hashsize = SHA2_224_HASH_LEN,
.ctxsize = sizeof(SHA224_CTX),
.blocksize = SHA2_224_BLOCK_LEN,
.Init = (void (*)(void *)) SHA224_Init,
.Update = SHA224Update_int,
.Final = (void (*)(u_int8_t *, void *)) SHA224_Final,
};
struct auth_hash auth_hash_sha2_256 = {
.type = CRYPTO_SHA2_256,
.name = "SHA2-256",
.keysize = SHA2_256_BLOCK_LEN,
.hashsize = SHA2_256_HASH_LEN,
.ctxsize = sizeof(SHA256_CTX),
.blocksize = SHA2_256_BLOCK_LEN,
.Init = (void (*)(void *)) SHA256_Init,
.Update = SHA256Update_int,
.Final = (void (*)(u_int8_t *, void *)) SHA256_Final,
};
struct auth_hash auth_hash_sha2_384 = {
.type = CRYPTO_SHA2_384,
.name = "SHA2-384",
.keysize = SHA2_384_BLOCK_LEN,
.hashsize = SHA2_384_HASH_LEN,
.ctxsize = sizeof(SHA384_CTX),
.blocksize = SHA2_384_BLOCK_LEN,
.Init = (void (*)(void *)) SHA384_Init,
.Update = SHA384Update_int,
.Final = (void (*)(u_int8_t *, void *)) SHA384_Final,
};
struct auth_hash auth_hash_sha2_512 = {
.type = CRYPTO_SHA2_512,
.name = "SHA2-512",
.keysize = SHA2_512_BLOCK_LEN,
.hashsize = SHA2_512_HASH_LEN,
.ctxsize = sizeof(SHA512_CTX),
.blocksize = SHA2_512_BLOCK_LEN,
.Init = (void (*)(void *)) SHA512_Init,
.Update = SHA512Update_int,
.Final = (void (*)(u_int8_t *, void *)) SHA512_Final,
};
/* Authentication instances */
struct auth_hash auth_hash_hmac_sha2_224 = {
.type = CRYPTO_SHA2_224_HMAC,
.name = "HMAC-SHA2-224",
.keysize = SHA2_224_BLOCK_LEN,
.hashsize = SHA2_224_HASH_LEN,
.ctxsize = sizeof(SHA224_CTX),
.blocksize = SHA2_224_BLOCK_LEN,
.Init = (void (*)(void *)) SHA224_Init,
.Update = SHA224Update_int,
.Final = (void (*)(u_int8_t *, void *)) SHA224_Final,
};
struct auth_hash auth_hash_hmac_sha2_256 = {
.type = CRYPTO_SHA2_256_HMAC,
.name = "HMAC-SHA2-256",
.keysize = SHA2_256_HMAC_BLOCK_LEN,
.keysize = SHA2_256_BLOCK_LEN,
.hashsize = SHA2_256_HASH_LEN,
.ctxsize = sizeof(SHA256_CTX),
.blocksize = SHA2_256_HMAC_BLOCK_LEN,
.blocksize = SHA2_256_BLOCK_LEN,
.Init = (void (*)(void *)) SHA256_Init,
.Update = SHA256Update_int,
.Final = (void (*)(u_int8_t *, void *)) SHA256_Final,
@@ -75,10 +137,10 @@ struct auth_hash auth_hash_hmac_sha2_256 = {
struct auth_hash auth_hash_hmac_sha2_384 = {
.type = CRYPTO_SHA2_384_HMAC,
.name = "HMAC-SHA2-384",
.keysize = SHA2_384_HMAC_BLOCK_LEN,
.keysize = SHA2_384_BLOCK_LEN,
.hashsize = SHA2_384_HASH_LEN,
.ctxsize = sizeof(SHA384_CTX),
.blocksize = SHA2_384_HMAC_BLOCK_LEN,
.blocksize = SHA2_384_BLOCK_LEN,
.Init = (void (*)(void *)) SHA384_Init,
.Update = SHA384Update_int,
.Final = (void (*)(u_int8_t *, void *)) SHA384_Final,
@@ -87,10 +149,10 @@ struct auth_hash auth_hash_hmac_sha2_384 = {
struct auth_hash auth_hash_hmac_sha2_512 = {
.type = CRYPTO_SHA2_512_HMAC,
.name = "HMAC-SHA2-512",
.keysize = SHA2_512_HMAC_BLOCK_LEN,
.keysize = SHA2_512_BLOCK_LEN,
.hashsize = SHA2_512_HASH_LEN,
.ctxsize = sizeof(SHA512_CTX),
.blocksize = SHA2_512_HMAC_BLOCK_LEN,
.blocksize = SHA2_512_BLOCK_LEN,
.Init = (void (*)(void *)) SHA512_Init,
.Update = SHA512Update_int,
.Final = (void (*)(u_int8_t *, void *)) SHA512_Final,
@@ -99,6 +161,13 @@ struct auth_hash auth_hash_hmac_sha2_512 = {
/*
* And now for auth.
*/
static int
SHA224Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{
SHA224_Update(ctx, buf, len);
return 0;
}
static int
SHA256Update_int(void *ctx, const u_int8_t *buf, u_int16_t len)
{