Overhaul driver/subsystem api's:
o make all crypto drivers have a device_t; pseudo drivers like the s/w crypto driver synthesize one o change the api between the crypto subsystem and drivers to use kobj; cryptodev_if.m defines this api o use the fact that all crypto drivers now have a device_t to add support for specifying which of several potential devices to use when doing crypto operations o add new ioctls that allow user apps to select a specific crypto device to use (previous ioctls maintained for compatibility) o overhaul crypto subsystem code to eliminate lots of cruft and hide implementation details from drivers o bring in numerous fixes from Michale Richardson/hifn; mostly for 795x parts o add an optional mechanism for mmap'ing the hifn 795x public key h/w to user space for use by openssl (not enabled by default) o update crypto test tools to use new ioctl's and add cmd line options to specify a device to use for tests These changes will also enable much future work on improving the core crypto subsystem; including proper load balancing and interposing code between the core and drivers to dispatch small operations to the s/w driver as appropriate. These changes were instigated by the work of Michael Richardson. Reviewed by: pjd Approved by: re
This commit is contained in:
parent
3f9dd9edcb
commit
f96ba7ffda
@ -1919,6 +1919,7 @@ opencrypto/cast.c optional crypto | ipsec ipsec_esp
|
||||
opencrypto/criov.c optional crypto
|
||||
opencrypto/crypto.c optional crypto
|
||||
opencrypto/cryptodev.c optional cryptodev
|
||||
opencrypto/cryptodev_if.m optional crypto
|
||||
opencrypto/cryptosoft.c optional crypto
|
||||
opencrypto/deflate.c optional crypto
|
||||
opencrypto/rmd160.c optional crypto | ipsec
|
||||
|
@ -332,7 +332,7 @@ MFILES?= dev/acpica/acpi_if.m dev/ata/ata_if.m dev/eisa/eisa_if.m \
|
||||
dev/sound/midi/mpu_if.m dev/sound/midi/mpufoi_if.m \
|
||||
dev/sound/midi/synth_if.m dev/usb/usb_if.m isa/isa_if.m \
|
||||
kern/bus_if.m kern/cpufreq_if.m kern/device_if.m kern/serdev_if.m \
|
||||
libkern/iconv_converter_if.m opencrypto/crypto_if.m \
|
||||
libkern/iconv_converter_if.m opencrypto/cryptodev_if.m \
|
||||
pc98/pc98/canbus_if.m pci/agp_if.m
|
||||
|
||||
.for _srcsrc in ${MFILES}
|
||||
|
@ -46,6 +46,10 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <crypto/via/padlock.h>
|
||||
|
||||
#include <sys/kobj.h>
|
||||
#include <sys/bus.h>
|
||||
#include "cryptodev_if.h"
|
||||
|
||||
/*
|
||||
* Technical documentation about the PadLock engine can be found here:
|
||||
*
|
||||
@ -59,26 +63,30 @@ struct padlock_softc {
|
||||
struct mtx sc_sessions_mtx;
|
||||
};
|
||||
|
||||
static struct padlock_softc *padlock_sc;
|
||||
|
||||
static int padlock_newsession(void *arg __unused, uint32_t *sidp,
|
||||
struct cryptoini *cri);
|
||||
static int padlock_freesession(void *arg __unused, uint64_t tid);
|
||||
static int padlock_process(void *arg __unused, struct cryptop *crp,
|
||||
int hint __unused);
|
||||
static int padlock_newsession(device_t, uint32_t *sidp, struct cryptoini *cri);
|
||||
static int padlock_freesession(device_t, uint64_t tid);
|
||||
static int padlock_process(device_t, struct cryptop *crp, int hint __unused);
|
||||
|
||||
MALLOC_DEFINE(M_PADLOCK, "padlock_data", "PadLock Data");
|
||||
|
||||
static int
|
||||
padlock_init(void)
|
||||
static void
|
||||
padlock_identify(device_t *dev, device_t parent)
|
||||
{
|
||||
/* NB: order 10 is so we get attached after h/w devices */
|
||||
if (device_find_child(parent, "padlock", -1) == NULL &&
|
||||
BUS_ADD_CHILD(parent, 10, "padlock", -1) == 0)
|
||||
panic("padlock: could not attach");
|
||||
}
|
||||
|
||||
static int
|
||||
padlock_probe(device_t dev)
|
||||
{
|
||||
struct padlock_softc *sc;
|
||||
char capp[256];
|
||||
|
||||
#if defined(__i386__) && !defined(PC98)
|
||||
/* If there is no AES support, we has nothing to do here. */
|
||||
if (!(via_feature_xcrypt & VIA_HAS_AES)) {
|
||||
printf("PadLock: No ACE support.\n");
|
||||
device_printf(dev, "No ACE support.\n");
|
||||
return (EINVAL);
|
||||
}
|
||||
strlcpy(capp, "AES-CBC", sizeof(capp));
|
||||
@ -97,63 +105,53 @@ padlock_init(void)
|
||||
if (via_feature_xcrypt & VIA_HAS_MM)
|
||||
strlcat(capp, ",RSA", sizeof(capp));
|
||||
#endif
|
||||
printf("PadLock: HW support loaded for %s.\n", capp);
|
||||
device_set_desc_copy(dev, capp);
|
||||
return (0);
|
||||
#else
|
||||
return (EINVAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
padlock_attach(device_t dev)
|
||||
{
|
||||
struct padlock_softc *sc = device_get_softc(dev);
|
||||
|
||||
padlock_sc = sc = malloc(sizeof(*padlock_sc), M_PADLOCK,
|
||||
M_WAITOK | M_ZERO);
|
||||
TAILQ_INIT(&sc->sc_sessions);
|
||||
sc->sc_sid = 1;
|
||||
|
||||
sc->sc_cid = crypto_get_driverid(0);
|
||||
sc->sc_cid = crypto_get_driverid(dev, CRYPTOCAP_F_HARDWARE);
|
||||
if (sc->sc_cid < 0) {
|
||||
printf("PadLock: Could not get crypto driver id.\n");
|
||||
free(padlock_sc, M_PADLOCK);
|
||||
padlock_sc = NULL;
|
||||
device_printf(dev, "Could not get crypto driver id.\n");
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
mtx_init(&sc->sc_sessions_mtx, "padlock_mtx", NULL, MTX_DEF);
|
||||
crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0, padlock_newsession,
|
||||
padlock_freesession, padlock_process, NULL);
|
||||
crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0, padlock_newsession,
|
||||
padlock_freesession, padlock_process, NULL);
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0, padlock_newsession,
|
||||
padlock_freesession, padlock_process, NULL);
|
||||
crypto_register(sc->sc_cid, CRYPTO_RIPEMD160_HMAC, 0, 0,
|
||||
padlock_newsession, padlock_freesession, padlock_process, NULL);
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA2_256_HMAC, 0, 0,
|
||||
padlock_newsession, padlock_freesession, padlock_process, NULL);
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA2_384_HMAC, 0, 0,
|
||||
padlock_newsession, padlock_freesession, padlock_process, NULL);
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA2_512_HMAC, 0, 0,
|
||||
padlock_newsession, padlock_freesession, padlock_process, NULL);
|
||||
crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_RIPEMD160_HMAC, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA2_256_HMAC, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA2_384_HMAC, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA2_512_HMAC, 0, 0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
padlock_destroy(void)
|
||||
padlock_detach(device_t dev)
|
||||
{
|
||||
struct padlock_softc *sc = padlock_sc;
|
||||
struct padlock_softc *sc = device_get_softc(dev);
|
||||
struct padlock_session *ses;
|
||||
u_int active = 0;
|
||||
|
||||
if (sc == NULL)
|
||||
return (0);
|
||||
mtx_lock(&sc->sc_sessions_mtx);
|
||||
TAILQ_FOREACH(ses, &sc->sc_sessions, ses_next) {
|
||||
if (ses->ses_used)
|
||||
active++;
|
||||
if (ses->ses_used) {
|
||||
mtx_unlock(&sc->sc_sessions_mtx);
|
||||
device_printf(dev,
|
||||
"Cannot detach, sessions still active.\n");
|
||||
return (EBUSY);
|
||||
}
|
||||
}
|
||||
if (active > 0) {
|
||||
mtx_unlock(&sc->sc_sessions_mtx);
|
||||
printf("PadLock: Cannot destroy, %u sessions active.\n",
|
||||
active);
|
||||
return (EBUSY);
|
||||
}
|
||||
padlock_sc = NULL;
|
||||
for (ses = TAILQ_FIRST(&sc->sc_sessions); ses != NULL;
|
||||
ses = TAILQ_FIRST(&sc->sc_sessions)) {
|
||||
TAILQ_REMOVE(&sc->sc_sessions, ses, ses_next);
|
||||
@ -161,19 +159,18 @@ padlock_destroy(void)
|
||||
}
|
||||
mtx_destroy(&sc->sc_sessions_mtx);
|
||||
crypto_unregister_all(sc->sc_cid);
|
||||
free(sc, M_PADLOCK);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
padlock_newsession(void *arg __unused, uint32_t *sidp, struct cryptoini *cri)
|
||||
padlock_newsession(device_t dev, uint32_t *sidp, struct cryptoini *cri)
|
||||
{
|
||||
struct padlock_softc *sc = padlock_sc;
|
||||
struct padlock_softc *sc = device_get_softc(dev);
|
||||
struct padlock_session *ses = NULL;
|
||||
struct cryptoini *encini, *macini;
|
||||
int error;
|
||||
|
||||
if (sc == NULL || sidp == NULL || cri == NULL)
|
||||
if (sidp == NULL || cri == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
encini = macini = NULL;
|
||||
@ -255,14 +252,12 @@ padlock_newsession(void *arg __unused, uint32_t *sidp, struct cryptoini *cri)
|
||||
}
|
||||
|
||||
static int
|
||||
padlock_freesession(void *arg __unused, uint64_t tid)
|
||||
padlock_freesession(device_t dev, uint64_t tid)
|
||||
{
|
||||
struct padlock_softc *sc = padlock_sc;
|
||||
struct padlock_softc *sc = device_get_softc(dev);
|
||||
struct padlock_session *ses;
|
||||
uint32_t sid = ((uint32_t)tid) & 0xffffffff;
|
||||
|
||||
if (sc == NULL)
|
||||
return (EINVAL);
|
||||
mtx_lock(&sc->sc_sessions_mtx);
|
||||
TAILQ_FOREACH(ses, &sc->sc_sessions, ses_next) {
|
||||
if (ses->ses_id == sid)
|
||||
@ -282,9 +277,9 @@ padlock_freesession(void *arg __unused, uint64_t tid)
|
||||
}
|
||||
|
||||
static int
|
||||
padlock_process(void *arg __unused, struct cryptop *crp, int hint __unused)
|
||||
padlock_process(device_t dev, struct cryptop *crp, int hint __unused)
|
||||
{
|
||||
struct padlock_softc *sc = padlock_sc;
|
||||
struct padlock_softc *sc = device_get_softc(dev);
|
||||
struct padlock_session *ses = NULL;
|
||||
struct cryptodesc *crd, *enccrd, *maccrd;
|
||||
int error = 0;
|
||||
@ -373,28 +368,27 @@ padlock_process(void *arg __unused, struct cryptop *crp, int hint __unused)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
padlock_modevent(module_t mod, int type, void *unused __unused)
|
||||
{
|
||||
int error;
|
||||
static device_method_t padlock_methods[] = {
|
||||
DEVMETHOD(device_identify, padlock_identify),
|
||||
DEVMETHOD(device_probe, padlock_probe),
|
||||
DEVMETHOD(device_attach, padlock_attach),
|
||||
DEVMETHOD(device_detach, padlock_detach),
|
||||
|
||||
error = EOPNOTSUPP;
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
error = padlock_init();
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
error = padlock_destroy();
|
||||
break;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
DEVMETHOD(cryptodev_newsession, padlock_newsession),
|
||||
DEVMETHOD(cryptodev_freesession,padlock_freesession),
|
||||
DEVMETHOD(cryptodev_process, padlock_process),
|
||||
|
||||
static moduledata_t padlock_mod = {
|
||||
"padlock",
|
||||
padlock_modevent,
|
||||
0
|
||||
{0, 0},
|
||||
};
|
||||
DECLARE_MODULE(padlock, padlock_mod, SI_SUB_DRIVERS, SI_ORDER_ANY);
|
||||
|
||||
static driver_t padlock_driver = {
|
||||
"padlock",
|
||||
padlock_methods,
|
||||
sizeof(struct padlock_softc),
|
||||
};
|
||||
static devclass_t padlock_devclass;
|
||||
|
||||
/* XXX where to attach */
|
||||
DRIVER_MODULE(padlock, nexus, padlock_driver, padlock_devclass, 0, 0);
|
||||
MODULE_VERSION(padlock, 1);
|
||||
MODULE_DEPEND(padlock, crypto, 1, 1, 1);
|
||||
|
@ -70,6 +70,9 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <opencrypto/cryptodev.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/kobj.h>
|
||||
|
||||
#include "cryptodev_if.h"
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
@ -80,6 +83,13 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/hifn/hifn7751reg.h>
|
||||
#include <dev/hifn/hifn7751var.h>
|
||||
|
||||
#ifdef HIFN_VULCANDEV
|
||||
#include <sys/conf.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
static struct cdevsw vulcanpk_cdevsw; /* forward declaration */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prototypes and count for the pci_device structure
|
||||
*/
|
||||
@ -90,6 +100,10 @@ static int hifn_suspend(device_t);
|
||||
static int hifn_resume(device_t);
|
||||
static void hifn_shutdown(device_t);
|
||||
|
||||
static int hifn_newsession(device_t, u_int32_t *, struct cryptoini *);
|
||||
static int hifn_freesession(device_t, u_int64_t);
|
||||
static int hifn_process(device_t, struct cryptop *, int);
|
||||
|
||||
static device_method_t hifn_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, hifn_probe),
|
||||
@ -103,6 +117,11 @@ static device_method_t hifn_methods[] = {
|
||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
|
||||
|
||||
/* crypto device methods */
|
||||
DEVMETHOD(cryptodev_newsession, hifn_newsession),
|
||||
DEVMETHOD(cryptodev_freesession,hifn_freesession),
|
||||
DEVMETHOD(cryptodev_process, hifn_process),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
static driver_t hifn_driver = {
|
||||
@ -132,9 +151,6 @@ static void hifn_sessions(struct hifn_softc *);
|
||||
static void hifn_intr(void *);
|
||||
static u_int hifn_write_command(struct hifn_command *, u_int8_t *);
|
||||
static u_int32_t hifn_next_signature(u_int32_t a, u_int cnt);
|
||||
static int hifn_newsession(void *, u_int32_t *, struct cryptoini *);
|
||||
static int hifn_freesession(void *, u_int64_t);
|
||||
static int hifn_process(void *, struct cryptop *, int);
|
||||
static void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *);
|
||||
static int hifn_crypto(struct hifn_softc *, struct hifn_command *, struct cryptop *, int);
|
||||
static int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *);
|
||||
@ -279,6 +295,12 @@ checkmaxmin(device_t dev, const char *what, u_int v, u_int min, u_int max)
|
||||
* always will allow the card to work. If a card is using the PCI
|
||||
* bus clock and in a 33MHz slot then it will be operating at half
|
||||
* speed until the correct information is provided.
|
||||
*
|
||||
* We use a default setting of "ext66" because according to Mike Ham
|
||||
* of HiFn, almost every board in existence has an external crystal
|
||||
* populated at 66Mhz. Using PCI can be a problem on modern motherboards,
|
||||
* because PCI33 can have clocks from 0 to 33Mhz, and some have
|
||||
* non-PCI-compliant spread-spectrum clocks, which can confuse the pll.
|
||||
*/
|
||||
static void
|
||||
hifn_getpllconfig(device_t dev, u_int *pll)
|
||||
@ -290,7 +312,7 @@ hifn_getpllconfig(device_t dev, u_int *pll)
|
||||
|
||||
if (resource_string_value("hifn", device_get_unit(dev),
|
||||
"pllconfig", &pllspec))
|
||||
pllspec = "pci66";
|
||||
pllspec = "ext66";
|
||||
fl = 33, fh = 66;
|
||||
pllconfig = 0;
|
||||
if (strncmp(pllspec, "ext", 3) == 0) {
|
||||
@ -559,7 +581,7 @@ hifn_attach(device_t dev)
|
||||
2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
|
||||
printf("\n");
|
||||
|
||||
sc->sc_cid = crypto_get_driverid(0);
|
||||
sc->sc_cid = crypto_get_driverid(dev, CRYPTOCAP_F_HARDWARE);
|
||||
if (sc->sc_cid < 0) {
|
||||
device_printf(dev, "could not get crypto driver id\n");
|
||||
goto fail_intr;
|
||||
@ -571,26 +593,17 @@ hifn_attach(device_t dev)
|
||||
|
||||
switch (ena) {
|
||||
case HIFN_PUSTAT_ENA_2:
|
||||
crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0,
|
||||
hifn_newsession, hifn_freesession, hifn_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0,
|
||||
hifn_newsession, hifn_freesession, hifn_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
|
||||
if (sc->sc_flags & HIFN_HAS_AES)
|
||||
crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0,
|
||||
hifn_newsession, hifn_freesession,
|
||||
hifn_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
|
||||
/*FALLTHROUGH*/
|
||||
case HIFN_PUSTAT_ENA_1:
|
||||
crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0,
|
||||
hifn_newsession, hifn_freesession, hifn_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0,
|
||||
hifn_newsession, hifn_freesession, hifn_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0,
|
||||
hifn_newsession, hifn_freesession, hifn_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0,
|
||||
hifn_newsession, hifn_freesession, hifn_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0,
|
||||
hifn_newsession, hifn_freesession, hifn_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -790,6 +803,12 @@ hifn_init_pubrng(struct hifn_softc *sc)
|
||||
WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE);
|
||||
sc->sc_dmaier |= HIFN_DMAIER_PUBDONE;
|
||||
WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
|
||||
#ifdef HIFN_VULCANDEV
|
||||
sc->sc_pkdev = make_dev(&vulcanpk_cdevsw, 0,
|
||||
UID_ROOT, GID_WHEEL, 0666,
|
||||
"vulcanpk");
|
||||
sc->sc_pkdev->si_drv1 = sc;
|
||||
#endif
|
||||
}
|
||||
|
||||
return (0);
|
||||
@ -804,6 +823,7 @@ hifn_rng(void *vsc)
|
||||
int i;
|
||||
|
||||
if (sc->sc_flags & HIFN_IS_7811) {
|
||||
/* ONLY VALID ON 7811!!!! */
|
||||
for (i = 0; i < 5; i++) {
|
||||
sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS);
|
||||
if (sts & HIFN_7811_RNGSTS_UFL) {
|
||||
@ -846,10 +866,15 @@ static void
|
||||
hifn_puc_wait(struct hifn_softc *sc)
|
||||
{
|
||||
int i;
|
||||
int reg = HIFN_0_PUCTRL;
|
||||
|
||||
if (sc->sc_flags & HIFN_IS_7956) {
|
||||
reg = HIFN_0_PUCTRL2;
|
||||
}
|
||||
|
||||
for (i = 5000; i > 0; i--) {
|
||||
DELAY(1);
|
||||
if (!(READ_REG_0(sc, HIFN_0_PUCTRL) & HIFN_PUCTRL_RESET))
|
||||
if (!(READ_REG_0(sc, reg) & HIFN_PUCTRL_RESET))
|
||||
break;
|
||||
}
|
||||
if (!i)
|
||||
@ -863,7 +888,13 @@ static void
|
||||
hifn_reset_puc(struct hifn_softc *sc)
|
||||
{
|
||||
/* Reset processing unit */
|
||||
WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA);
|
||||
int reg = HIFN_0_PUCTRL;
|
||||
|
||||
if (sc->sc_flags & HIFN_IS_7956) {
|
||||
reg = HIFN_0_PUCTRL2;
|
||||
}
|
||||
WRITE_REG_0(sc, reg, HIFN_PUCTRL_DMAENA);
|
||||
|
||||
hifn_puc_wait(sc);
|
||||
}
|
||||
|
||||
@ -932,7 +963,16 @@ hifn_reset_board(struct hifn_softc *sc, int full)
|
||||
}
|
||||
if (reg == 1000)
|
||||
printf(": cram init timeout\n");
|
||||
} else {
|
||||
/* set up DMA configuration register #2 */
|
||||
/* turn off all PK and BAR0 swaps */
|
||||
WRITE_REG_1(sc, HIFN_1_DMA_CNFG2,
|
||||
(3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT)|
|
||||
(3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT)|
|
||||
(2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT)|
|
||||
(2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static u_int32_t
|
||||
@ -1170,13 +1210,15 @@ hifn_init_pci_registers(struct hifn_softc *sc)
|
||||
/* turn off the clocks and insure bypass is set */
|
||||
pll = READ_REG_1(sc, HIFN_1_PLL);
|
||||
pll = (pll &~ (HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL))
|
||||
| HIFN_PLL_BP;
|
||||
| HIFN_PLL_BP | HIFN_PLL_MBSET;
|
||||
WRITE_REG_1(sc, HIFN_1_PLL, pll);
|
||||
DELAY(10*1000); /* 10ms */
|
||||
|
||||
/* change configuration */
|
||||
pll = (pll &~ HIFN_PLL_CONFIG) | sc->sc_pllconfig;
|
||||
WRITE_REG_1(sc, HIFN_1_PLL, pll);
|
||||
DELAY(10*1000); /* 10ms */
|
||||
|
||||
/* disable bypass */
|
||||
pll &= ~HIFN_PLL_BP;
|
||||
WRITE_REG_1(sc, HIFN_1_PLL, pll);
|
||||
@ -1657,6 +1699,21 @@ hifn_dmamap_aligned(struct hifn_operand *op)
|
||||
return (1);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
hifn_dmamap_dstwrap(struct hifn_softc *sc, int idx)
|
||||
{
|
||||
struct hifn_dma *dma = sc->sc_dma;
|
||||
|
||||
if (++idx == HIFN_D_DST_RSIZE) {
|
||||
dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP |
|
||||
HIFN_D_MASKDONEIRQ);
|
||||
HIFN_DSTR_SYNC(sc, idx,
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
idx = 0;
|
||||
}
|
||||
return (idx);
|
||||
}
|
||||
|
||||
static int
|
||||
hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)
|
||||
{
|
||||
@ -1674,13 +1731,7 @@ hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
used++;
|
||||
|
||||
if (++idx == HIFN_D_DST_RSIZE) {
|
||||
dma->dstr[idx].l = htole32(HIFN_D_VALID |
|
||||
HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
|
||||
HIFN_DSTR_SYNC(sc, idx,
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
idx = 0;
|
||||
}
|
||||
idx = hifn_dmamap_dstwrap(sc, idx);
|
||||
}
|
||||
|
||||
if (cmd->sloplen == 0) {
|
||||
@ -1702,13 +1753,7 @@ hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
used++;
|
||||
|
||||
if (++idx == HIFN_D_DST_RSIZE) {
|
||||
dma->dstr[idx].l = htole32(HIFN_D_VALID |
|
||||
HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
|
||||
HIFN_DSTR_SYNC(sc, idx,
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
idx = 0;
|
||||
}
|
||||
idx = hifn_dmamap_dstwrap(sc, idx);
|
||||
}
|
||||
}
|
||||
dma->dstr[idx].p = htole32(p);
|
||||
@ -1716,19 +1761,28 @@ hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)
|
||||
HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
used++;
|
||||
|
||||
if (++idx == HIFN_D_DST_RSIZE) {
|
||||
dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP |
|
||||
HIFN_D_MASKDONEIRQ);
|
||||
HIFN_DSTR_SYNC(sc, idx,
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
idx = 0;
|
||||
}
|
||||
idx = hifn_dmamap_dstwrap(sc, idx);
|
||||
|
||||
dma->dsti = idx;
|
||||
dma->dstu += used;
|
||||
return (idx);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
hifn_dmamap_srcwrap(struct hifn_softc *sc, int idx)
|
||||
{
|
||||
struct hifn_dma *dma = sc->sc_dma;
|
||||
|
||||
if (++idx == HIFN_D_SRC_RSIZE) {
|
||||
dma->srcr[idx].l = htole32(HIFN_D_VALID |
|
||||
HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
|
||||
HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
|
||||
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
|
||||
idx = 0;
|
||||
}
|
||||
return (idx);
|
||||
}
|
||||
|
||||
static int
|
||||
hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd)
|
||||
{
|
||||
@ -1748,13 +1802,7 @@ hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd)
|
||||
HIFN_SRCR_SYNC(sc, idx,
|
||||
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
|
||||
|
||||
if (++idx == HIFN_D_SRC_RSIZE) {
|
||||
dma->srcr[idx].l = htole32(HIFN_D_VALID |
|
||||
HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
|
||||
HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
|
||||
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
|
||||
idx = 0;
|
||||
}
|
||||
idx = hifn_dmamap_srcwrap(sc, idx);
|
||||
}
|
||||
dma->srci = idx;
|
||||
dma->srcu += src->nsegs;
|
||||
@ -1782,7 +1830,7 @@ hifn_crypto(
|
||||
int hint)
|
||||
{
|
||||
struct hifn_dma *dma = sc->sc_dma;
|
||||
u_int32_t cmdlen;
|
||||
u_int32_t cmdlen, csr;
|
||||
int cmdi, resi, err = 0;
|
||||
|
||||
/*
|
||||
@ -1995,10 +2043,6 @@ hifn_crypto(
|
||||
HIFN_CMDR_SYNC(sc, cmdi,
|
||||
BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
|
||||
dma->cmdu++;
|
||||
if (sc->sc_c_busy == 0) {
|
||||
WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_C_CTRL_ENA);
|
||||
sc->sc_c_busy = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't worry about missing an interrupt (which a "command wait"
|
||||
@ -2014,10 +2058,6 @@ hifn_crypto(
|
||||
hifnstats.hst_ibytes += cmd->src_mapsize;
|
||||
|
||||
hifn_dmamap_load_src(sc, cmd);
|
||||
if (sc->sc_s_busy == 0) {
|
||||
WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_S_CTRL_ENA);
|
||||
sc->sc_s_busy = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlike other descriptors, we don't mask done interrupt from
|
||||
@ -2054,20 +2094,31 @@ hifn_crypto(
|
||||
HIFN_RESR_SYNC(sc, resi,
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
dma->resu++;
|
||||
if (sc->sc_r_busy == 0) {
|
||||
WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_R_CTRL_ENA);
|
||||
sc->sc_r_busy = 1;
|
||||
}
|
||||
|
||||
if (cmd->sloplen)
|
||||
cmd->slopidx = resi;
|
||||
|
||||
hifn_dmamap_load_dst(sc, cmd);
|
||||
|
||||
csr = 0;
|
||||
if (sc->sc_c_busy == 0) {
|
||||
csr |= HIFN_DMACSR_C_CTRL_ENA;
|
||||
sc->sc_c_busy = 1;
|
||||
}
|
||||
if (sc->sc_s_busy == 0) {
|
||||
csr |= HIFN_DMACSR_S_CTRL_ENA;
|
||||
sc->sc_s_busy = 1;
|
||||
}
|
||||
if (sc->sc_r_busy == 0) {
|
||||
csr |= HIFN_DMACSR_R_CTRL_ENA;
|
||||
sc->sc_r_busy = 1;
|
||||
}
|
||||
if (sc->sc_d_busy == 0) {
|
||||
WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_D_CTRL_ENA);
|
||||
csr |= HIFN_DMACSR_D_CTRL_ENA;
|
||||
sc->sc_d_busy = 1;
|
||||
}
|
||||
if (csr)
|
||||
WRITE_REG_1(sc, HIFN_1_DMA_CSR, csr);
|
||||
|
||||
#ifdef HIFN_DEBUG
|
||||
if (hifn_debug) {
|
||||
@ -2292,10 +2343,10 @@ hifn_intr(void *arg)
|
||||
* id on successful allocation.
|
||||
*/
|
||||
static int
|
||||
hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
|
||||
hifn_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
|
||||
{
|
||||
struct hifn_softc *sc = device_get_softc(dev);
|
||||
struct cryptoini *c;
|
||||
struct hifn_softc *sc = arg;
|
||||
int mac = 0, cry = 0, sesn;
|
||||
struct hifn_session *ses = NULL;
|
||||
|
||||
@ -2303,11 +2354,14 @@ hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
|
||||
if (sidp == NULL || cri == NULL || sc == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
HIFN_LOCK(sc);
|
||||
if (sc->sc_sessions == NULL) {
|
||||
ses = sc->sc_sessions = (struct hifn_session *)malloc(
|
||||
sizeof(*ses), M_DEVBUF, M_NOWAIT);
|
||||
if (ses == NULL)
|
||||
if (ses == NULL) {
|
||||
HIFN_UNLOCK(sc);
|
||||
return (ENOMEM);
|
||||
}
|
||||
sesn = 0;
|
||||
sc->sc_nsessions = 1;
|
||||
} else {
|
||||
@ -2322,8 +2376,10 @@ hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
|
||||
sesn = sc->sc_nsessions;
|
||||
ses = (struct hifn_session *)malloc((sesn + 1) *
|
||||
sizeof(*ses), M_DEVBUF, M_NOWAIT);
|
||||
if (ses == NULL)
|
||||
if (ses == NULL) {
|
||||
HIFN_UNLOCK(sc);
|
||||
return (ENOMEM);
|
||||
}
|
||||
bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
|
||||
bzero(sc->sc_sessions, sesn * sizeof(*ses));
|
||||
free(sc->sc_sessions, M_DEVBUF);
|
||||
@ -2332,6 +2388,8 @@ hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
|
||||
sc->sc_nsessions++;
|
||||
}
|
||||
}
|
||||
HIFN_UNLOCK(sc);
|
||||
|
||||
bzero(ses, sizeof(*ses));
|
||||
ses->hs_used = 1;
|
||||
|
||||
@ -2389,28 +2447,32 @@ hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
|
||||
* XXX to blow away any keys already stored there.
|
||||
*/
|
||||
static int
|
||||
hifn_freesession(void *arg, u_int64_t tid)
|
||||
hifn_freesession(device_t dev, u_int64_t tid)
|
||||
{
|
||||
struct hifn_softc *sc = arg;
|
||||
int session;
|
||||
struct hifn_softc *sc = device_get_softc(dev);
|
||||
int session, error;
|
||||
u_int32_t sid = CRYPTO_SESID2LID(tid);
|
||||
|
||||
KASSERT(sc != NULL, ("hifn_freesession: null softc"));
|
||||
if (sc == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
HIFN_LOCK(sc);
|
||||
session = HIFN_SESSION(sid);
|
||||
if (session >= sc->sc_nsessions)
|
||||
return (EINVAL);
|
||||
if (session < sc->sc_nsessions) {
|
||||
bzero(&sc->sc_sessions[session], sizeof(struct hifn_session));
|
||||
error = 0;
|
||||
} else
|
||||
error = EINVAL;
|
||||
HIFN_UNLOCK(sc);
|
||||
|
||||
bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));
|
||||
return (0);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
hifn_process(void *arg, struct cryptop *crp, int hint)
|
||||
hifn_process(device_t dev, struct cryptop *crp, int hint)
|
||||
{
|
||||
struct hifn_softc *sc = arg;
|
||||
struct hifn_softc *sc = device_get_softc(dev);
|
||||
struct hifn_command *cmd = NULL;
|
||||
int session, err, ivlen;
|
||||
struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
|
||||
@ -2858,3 +2920,41 @@ hifn_write_reg_1(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
|
||||
}
|
||||
bus_space_write_4(sc->sc_st1, sc->sc_sh1, reg, val);
|
||||
}
|
||||
|
||||
#ifdef HIFN_VULCANDEV
|
||||
/*
|
||||
* this code provides support for mapping the PK engine's register
|
||||
* into a userspace program.
|
||||
*
|
||||
*/
|
||||
static int
|
||||
vulcanpk_mmap(struct cdev *dev, vm_offset_t offset,
|
||||
vm_paddr_t *paddr, int nprot)
|
||||
{
|
||||
struct hifn_softc *sc;
|
||||
vm_paddr_t pd;
|
||||
void *b;
|
||||
|
||||
sc = dev->si_drv1;
|
||||
|
||||
pd = rman_get_start(sc->sc_bar1res);
|
||||
b = rman_get_virtual(sc->sc_bar1res);
|
||||
|
||||
#if 0
|
||||
printf("vpk mmap: %p(%08x) offset=%d\n", b, pd, offset);
|
||||
hexdump(b, HIFN_1_PUB_MEMEND, "vpk", 0);
|
||||
#endif
|
||||
|
||||
if (offset == 0) {
|
||||
*paddr = pd;
|
||||
return (0);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static struct cdevsw vulcanpk_cdevsw = {
|
||||
.d_version = D_VERSION,
|
||||
.d_mmap = vulcanpk_mmap,
|
||||
.d_name = "vulcanpk",
|
||||
};
|
||||
#endif /* HIFN_VULCANDEV */
|
||||
|
@ -118,7 +118,10 @@ typedef struct hifn_desc {
|
||||
#define HIFN_0_PUSTAT 0x14 /* Processing Unit Status/Chip ID */
|
||||
#define HIFN_0_FIFOSTAT 0x18 /* FIFO Status */
|
||||
#define HIFN_0_FIFOCNFG 0x1c /* FIFO Configuration */
|
||||
#define HIFN_0_SPACESIZE 0x20 /* Register space size */
|
||||
#define HIFN_0_PUCTRL2 0x28 /* Processing Unit Control (2nd map) */
|
||||
#define HIFN_0_MUTE1 0x80
|
||||
#define HIFN_0_MUTE2 0x90
|
||||
#define HIFN_0_SPACESIZE 0x100 /* Register space size */
|
||||
|
||||
/* Processing Unit Control Register (HIFN_0_PUCTRL) */
|
||||
#define HIFN_PUCTRL_CLRSRCFIFO 0x0010 /* clear source fifo */
|
||||
@ -200,7 +203,7 @@ typedef struct hifn_desc {
|
||||
#define HIFN_FIFOSTAT_DST 0x007f /* Destination FIFO available */
|
||||
|
||||
/* FIFO Configuration Register (HIFN_0_FIFOCNFG) */
|
||||
#define HIFN_FIFOCNFG_THRESHOLD 0x0400 /* must be written as 1 */
|
||||
#define HIFN_FIFOCNFG_THRESHOLD 0x0400 /* must be written as this value */
|
||||
|
||||
/*
|
||||
* DMA Interface Registers (offset from BASEREG1)
|
||||
@ -217,17 +220,21 @@ typedef struct hifn_desc {
|
||||
#define HIFN_1_7811_RNGCFG 0x64 /* 7811: rng config */
|
||||
#define HIFN_1_7811_RNGDAT 0x68 /* 7811: rng data */
|
||||
#define HIFN_1_7811_RNGSTS 0x6c /* 7811: rng status */
|
||||
#define HIFN_1_DMA_CNFG2 0x6c /* 7955/7956: dma config #2 */
|
||||
#define HIFN_1_7811_MIPSRST 0x94 /* 7811: MIPS reset */
|
||||
#define HIFN_1_REVID 0x98 /* Revision ID */
|
||||
|
||||
#define HIFN_1_PUB_RESET 0x204 /* Public/RNG Reset */
|
||||
#define HIFN_1_PUB_BASE 0x300 /* Public Base Address */
|
||||
#define HIFN_1_PUB_OPLEN 0x304 /* Public Operand Length */
|
||||
#define HIFN_1_PUB_OP 0x308 /* Public Operand */
|
||||
#define HIFN_1_PUB_STATUS 0x30c /* Public Status */
|
||||
#define HIFN_1_PUB_IEN 0x310 /* Public Interrupt nable */
|
||||
#define HIFN_1_PUB_OPLEN 0x304 /* 7951-compat Public Operand Length */
|
||||
#define HIFN_1_PUB_OP 0x308 /* 7951-compat Public Operand */
|
||||
#define HIFN_1_PUB_STATUS 0x30c /* 7951-compat Public Status */
|
||||
#define HIFN_1_PUB_IEN 0x310 /* Public Interrupt enable */
|
||||
#define HIFN_1_RNG_CONFIG 0x314 /* RNG config */
|
||||
#define HIFN_1_RNG_DATA 0x318 /* RNG data */
|
||||
#define HIFN_1_PUB_MODE 0x320 /* PK mode */
|
||||
#define HIFN_1_PUB_FIFO_OPLEN 0x380 /* first element of oplen fifo */
|
||||
#define HIFN_1_PUB_FIFO_OP 0x384 /* first element of op fifo */
|
||||
#define HIFN_1_PUB_MEM 0x400 /* start of Public key memory */
|
||||
#define HIFN_1_PUB_MEMEND 0xbff /* end of Public key memory */
|
||||
|
||||
@ -305,6 +312,16 @@ typedef struct hifn_desc {
|
||||
#define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */
|
||||
#define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */
|
||||
|
||||
/* DMA Configuration Register (HIFN_1_DMA_CNFG2) */
|
||||
#define HIFN_DMACNFG2_PKSWAP32 (1 << 19) /* swap the OPLEN/OP reg */
|
||||
#define HIFN_DMACNFG2_PKSWAP8 (1 << 18) /* swap the bits of OPLEN/OP */
|
||||
#define HIFN_DMACNFG2_BAR0_SWAP32 (1<<17) /* swap the bytes of BAR0 */
|
||||
#define HIFN_DMACNFG2_BAR1_SWAP8 (1<<16) /* swap the bits of BAR0 */
|
||||
#define HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT 12
|
||||
#define HIFN_DMACNFG2_INIT_READ_BURST_SHIFT 8
|
||||
#define HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT 4
|
||||
#define HIFN_DMACNFG2_TGT_READ_BURST_SHIFT 0
|
||||
|
||||
/* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */
|
||||
#define HIFN_7811_RNGENA_ENA 0x00000001 /* enable RNG */
|
||||
|
||||
@ -358,6 +375,11 @@ typedef struct hifn_desc {
|
||||
/* Public status register (HIFN_1_PUB_STATUS) */
|
||||
#define HIFN_PUBSTS_DONE 0x00000001 /* operation done */
|
||||
#define HIFN_PUBSTS_CARRY 0x00000002 /* carry */
|
||||
#define HIFN_PUBSTS_FIFO_EMPTY 0x00000100 /* fifo empty */
|
||||
#define HIFN_PUBSTS_FIFO_FULL 0x00000200 /* fifo full */
|
||||
#define HIFN_PUBSTS_FIFO_OVFL 0x00000400 /* fifo overflow */
|
||||
#define HIFN_PUBSTS_FIFO_WRITE 0x000f0000 /* fifo write */
|
||||
#define HIFN_PUBSTS_FIFO_READ 0x0f000000 /* fifo read */
|
||||
|
||||
/* Public interrupt enable register (HIFN_1_PUB_IEN) */
|
||||
#define HIFN_PUBIEN_DONE 0x00000001 /* operation done interrupt */
|
||||
@ -407,6 +429,13 @@ typedef struct hifn_desc {
|
||||
*/
|
||||
#define HIFN_PLL_CONFIG (HIFN_PLL_IS|HIFN_PLL_ND|HIFN_PLL_REF_SEL)
|
||||
|
||||
/*
|
||||
* Public Key Engine Mode Register
|
||||
*/
|
||||
#define HIFN_PKMODE_HOSTINVERT (1 << 0) /* HOST INVERT */
|
||||
#define HIFN_PKMODE_ENHANCED (1 << 1) /* Enable enhanced mode */
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* Structs for board commands
|
||||
*
|
||||
|
@ -183,6 +183,9 @@ struct hifn_softc {
|
||||
int sc_needwakeup; /* ops q'd wating on resources */
|
||||
int sc_curbatch; /* # ops submitted w/o int */
|
||||
int sc_suspended;
|
||||
#ifdef HIFN_VULCANDEV
|
||||
struct cdev *sc_pkdev;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define HIFN_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
|
||||
|
@ -59,6 +59,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <opencrypto/cryptosoft.h>
|
||||
#include <sys/md5.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/kobj.h>
|
||||
|
||||
#include "cryptodev_if.h"
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
@ -83,6 +86,10 @@ static int safe_suspend(device_t);
|
||||
static int safe_resume(device_t);
|
||||
static void safe_shutdown(device_t);
|
||||
|
||||
static int safe_newsession(device_t, u_int32_t *, struct cryptoini *);
|
||||
static int safe_freesession(device_t, u_int64_t);
|
||||
static int safe_process(device_t, struct cryptop *, int);
|
||||
|
||||
static device_method_t safe_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, safe_probe),
|
||||
@ -96,6 +103,11 @@ static device_method_t safe_methods[] = {
|
||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
|
||||
|
||||
/* crypto device methods */
|
||||
DEVMETHOD(cryptodev_newsession, safe_newsession),
|
||||
DEVMETHOD(cryptodev_freesession,safe_freesession),
|
||||
DEVMETHOD(cryptodev_process, safe_process),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
static driver_t safe_driver = {
|
||||
@ -112,9 +124,6 @@ MODULE_DEPEND(safe, rndtest, 1, 1, 1);
|
||||
#endif
|
||||
|
||||
static void safe_intr(void *);
|
||||
static int safe_newsession(void *, u_int32_t *, struct cryptoini *);
|
||||
static int safe_freesession(void *, u_int64_t);
|
||||
static int safe_process(void *, struct cryptop *, int);
|
||||
static void safe_callback(struct safe_softc *, struct safe_ringentry *);
|
||||
static void safe_feed(struct safe_softc *, struct safe_ringentry *);
|
||||
static void safe_mcopy(struct mbuf *, struct mbuf *, u_int);
|
||||
@ -270,7 +279,7 @@ safe_attach(device_t dev)
|
||||
goto bad2;
|
||||
}
|
||||
|
||||
sc->sc_cid = crypto_get_driverid(0);
|
||||
sc->sc_cid = crypto_get_driverid(dev, CRYPTOCAP_F_HARDWARE);
|
||||
if (sc->sc_cid < 0) {
|
||||
device_printf(dev, "could not get crypto driver id\n");
|
||||
goto bad3;
|
||||
@ -388,39 +397,30 @@ safe_attach(device_t dev)
|
||||
#if 0
|
||||
printf(" key");
|
||||
sc->sc_flags |= SAFE_FLAGS_KEY;
|
||||
crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0,
|
||||
safe_kprocess, sc);
|
||||
crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0,
|
||||
safe_kprocess, sc);
|
||||
crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0);
|
||||
crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0);
|
||||
#endif
|
||||
}
|
||||
if (devinfo & SAFE_DEVINFO_DES) {
|
||||
printf(" des/3des");
|
||||
crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0,
|
||||
safe_newsession, safe_freesession, safe_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0,
|
||||
safe_newsession, safe_freesession, safe_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
|
||||
}
|
||||
if (devinfo & SAFE_DEVINFO_AES) {
|
||||
printf(" aes");
|
||||
crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0,
|
||||
safe_newsession, safe_freesession, safe_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
|
||||
}
|
||||
if (devinfo & SAFE_DEVINFO_MD5) {
|
||||
printf(" md5");
|
||||
crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0,
|
||||
safe_newsession, safe_freesession, safe_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
|
||||
}
|
||||
if (devinfo & SAFE_DEVINFO_SHA1) {
|
||||
printf(" sha1");
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0,
|
||||
safe_newsession, safe_freesession, safe_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
|
||||
}
|
||||
printf(" null");
|
||||
crypto_register(sc->sc_cid, CRYPTO_NULL_CBC, 0, 0,
|
||||
safe_newsession, safe_freesession, safe_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0,
|
||||
safe_newsession, safe_freesession, safe_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_NULL_CBC, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0);
|
||||
/* XXX other supported algorithms */
|
||||
printf("\n");
|
||||
|
||||
@ -710,10 +710,10 @@ safe_setup_mackey(struct safe_session *ses, int algo, caddr_t key, int klen)
|
||||
* id on successful allocation.
|
||||
*/
|
||||
static int
|
||||
safe_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
|
||||
safe_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
|
||||
{
|
||||
struct safe_softc *sc = device_get_softc(dev);
|
||||
struct cryptoini *c, *encini = NULL, *macini = NULL;
|
||||
struct safe_softc *sc = arg;
|
||||
struct safe_session *ses = NULL;
|
||||
int sesn;
|
||||
|
||||
@ -826,9 +826,9 @@ safe_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
|
||||
* Deallocate a session.
|
||||
*/
|
||||
static int
|
||||
safe_freesession(void *arg, u_int64_t tid)
|
||||
safe_freesession(device_t dev, u_int64_t tid)
|
||||
{
|
||||
struct safe_softc *sc = arg;
|
||||
struct safe_softc *sc = device_get_softc(dev);
|
||||
int session, ret;
|
||||
u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
|
||||
|
||||
@ -859,10 +859,10 @@ safe_op_cb(void *arg, bus_dma_segment_t *seg, int nsegs, bus_size_t mapsize, int
|
||||
}
|
||||
|
||||
static int
|
||||
safe_process(void *arg, struct cryptop *crp, int hint)
|
||||
safe_process(device_t dev, struct cryptop *crp, int hint)
|
||||
{
|
||||
struct safe_softc *sc = device_get_softc(dev);
|
||||
int err = 0, i, nicealign, uniform;
|
||||
struct safe_softc *sc = arg;
|
||||
struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
|
||||
int bypass, oplen, ivsize;
|
||||
caddr_t iv;
|
||||
|
@ -73,6 +73,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <opencrypto/cryptosoft.h>
|
||||
#include <sys/md5.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/kobj.h>
|
||||
|
||||
#include "cryptodev_if.h"
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pcireg.h>
|
||||
@ -106,6 +109,11 @@ static int ubsec_suspend(device_t);
|
||||
static int ubsec_resume(device_t);
|
||||
static void ubsec_shutdown(device_t);
|
||||
|
||||
static int ubsec_newsession(device_t, u_int32_t *, struct cryptoini *);
|
||||
static int ubsec_freesession(device_t, u_int64_t);
|
||||
static int ubsec_process(device_t, struct cryptop *, int);
|
||||
static int ubsec_kprocess(device_t, struct cryptkop *, int);
|
||||
|
||||
static device_method_t ubsec_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, ubsec_probe),
|
||||
@ -119,6 +127,12 @@ static device_method_t ubsec_methods[] = {
|
||||
DEVMETHOD(bus_print_child, bus_generic_print_child),
|
||||
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
|
||||
|
||||
/* crypto device methods */
|
||||
DEVMETHOD(cryptodev_newsession, ubsec_newsession),
|
||||
DEVMETHOD(cryptodev_freesession,ubsec_freesession),
|
||||
DEVMETHOD(cryptodev_process, ubsec_process),
|
||||
DEVMETHOD(cryptodev_kprocess, ubsec_kprocess),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
static driver_t ubsec_driver = {
|
||||
@ -135,9 +149,6 @@ MODULE_DEPEND(ubsec, rndtest, 1, 1, 1);
|
||||
#endif
|
||||
|
||||
static void ubsec_intr(void *);
|
||||
static int ubsec_newsession(void *, u_int32_t *, struct cryptoini *);
|
||||
static int ubsec_freesession(void *, u_int64_t);
|
||||
static int ubsec_process(void *, struct cryptop *, int);
|
||||
static void ubsec_callback(struct ubsec_softc *, struct ubsec_q *);
|
||||
static void ubsec_feed(struct ubsec_softc *);
|
||||
static void ubsec_mcopy(struct mbuf *, struct mbuf *, int, int);
|
||||
@ -158,7 +169,6 @@ static void ubsec_totalreset(struct ubsec_softc *sc);
|
||||
|
||||
static int ubsec_free_q(struct ubsec_softc *sc, struct ubsec_q *q);
|
||||
|
||||
static int ubsec_kprocess(void*, struct cryptkop *, int);
|
||||
static int ubsec_kprocess_modexp_hw(struct ubsec_softc *, struct cryptkop *, int);
|
||||
static int ubsec_kprocess_modexp_sw(struct ubsec_softc *, struct cryptkop *, int);
|
||||
static int ubsec_kprocess_rsapriv(struct ubsec_softc *, struct cryptkop *, int);
|
||||
@ -350,7 +360,7 @@ ubsec_attach(device_t dev)
|
||||
goto bad2;
|
||||
}
|
||||
|
||||
sc->sc_cid = crypto_get_driverid(0);
|
||||
sc->sc_cid = crypto_get_driverid(dev, CRYPTOCAP_F_HARDWARE);
|
||||
if (sc->sc_cid < 0) {
|
||||
device_printf(dev, "could not get crypto driver id\n");
|
||||
goto bad3;
|
||||
@ -405,14 +415,10 @@ ubsec_attach(device_t dev)
|
||||
|
||||
device_printf(sc->sc_dev, "%s\n", ubsec_partname(sc));
|
||||
|
||||
crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0,
|
||||
ubsec_newsession, ubsec_freesession, ubsec_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0,
|
||||
ubsec_newsession, ubsec_freesession, ubsec_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0,
|
||||
ubsec_newsession, ubsec_freesession, ubsec_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0,
|
||||
ubsec_newsession, ubsec_freesession, ubsec_process, sc);
|
||||
crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
|
||||
crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
|
||||
|
||||
/*
|
||||
* Reset Broadcom chip
|
||||
@ -475,11 +481,9 @@ ubsec_attach(device_t dev)
|
||||
if (sc->sc_flags & UBS_FLAGS_KEY) {
|
||||
sc->sc_statmask |= BS_STAT_MCR2_DONE;
|
||||
|
||||
crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0,
|
||||
ubsec_kprocess, sc);
|
||||
crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0);
|
||||
#if 0
|
||||
crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0,
|
||||
ubsec_kprocess, sc);
|
||||
crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0);
|
||||
#endif
|
||||
}
|
||||
return (0);
|
||||
@ -900,10 +904,10 @@ ubsec_setup_mackey(struct ubsec_session *ses, int algo, caddr_t key, int klen)
|
||||
* id on successful allocation.
|
||||
*/
|
||||
static int
|
||||
ubsec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
|
||||
ubsec_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
|
||||
{
|
||||
struct ubsec_softc *sc = device_get_softc(dev);
|
||||
struct cryptoini *c, *encini = NULL, *macini = NULL;
|
||||
struct ubsec_softc *sc = arg;
|
||||
struct ubsec_session *ses = NULL;
|
||||
int sesn;
|
||||
|
||||
@ -995,9 +999,9 @@ ubsec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
|
||||
* Deallocate a session.
|
||||
*/
|
||||
static int
|
||||
ubsec_freesession(void *arg, u_int64_t tid)
|
||||
ubsec_freesession(device_t dev, u_int64_t tid)
|
||||
{
|
||||
struct ubsec_softc *sc = arg;
|
||||
struct ubsec_softc *sc = device_get_softc(dev);
|
||||
int session, ret;
|
||||
u_int32_t sid = CRYPTO_SESID2LID(tid);
|
||||
|
||||
@ -1035,11 +1039,11 @@ ubsec_op_cb(void *arg, bus_dma_segment_t *seg, int nsegs, bus_size_t mapsize, in
|
||||
}
|
||||
|
||||
static int
|
||||
ubsec_process(void *arg, struct cryptop *crp, int hint)
|
||||
ubsec_process(device_t dev, struct cryptop *crp, int hint)
|
||||
{
|
||||
struct ubsec_softc *sc = device_get_softc(dev);
|
||||
struct ubsec_q *q = NULL;
|
||||
int err = 0, i, j, nicealign;
|
||||
struct ubsec_softc *sc = arg;
|
||||
struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
|
||||
int encoffset = 0, macoffset = 0, cpskip, cpoffset;
|
||||
int sskip, dskip, stheend, dtheend;
|
||||
@ -2110,9 +2114,9 @@ ubsec_kfree(struct ubsec_softc *sc, struct ubsec_q2 *q)
|
||||
}
|
||||
|
||||
static int
|
||||
ubsec_kprocess(void *arg, struct cryptkop *krp, int hint)
|
||||
ubsec_kprocess(device_t dev, struct cryptkop *krp, int hint)
|
||||
{
|
||||
struct ubsec_softc *sc = arg;
|
||||
struct ubsec_softc *sc = device_get_softc(dev);
|
||||
int r;
|
||||
|
||||
if (krp == NULL || krp->krp_callback == NULL)
|
||||
|
@ -662,12 +662,14 @@ g_eli_create(struct gctl_req *req, struct g_class *mp, struct g_provider *bpp,
|
||||
* Use software cryptography, if we cannot get it.
|
||||
*/
|
||||
if (LIST_EMPTY(&sc->sc_workers)) {
|
||||
error = crypto_newsession(&wr->w_sid, &crie, 1);
|
||||
error = crypto_newsession(&wr->w_sid, &crie,
|
||||
CRYPTOCAP_F_HARDWARE);
|
||||
if (error == 0)
|
||||
sc->sc_crypto = G_ELI_CRYPTO_HW;
|
||||
}
|
||||
if (sc->sc_crypto == G_ELI_CRYPTO_SW)
|
||||
error = crypto_newsession(&wr->w_sid, &crie, 0);
|
||||
error = crypto_newsession(&wr->w_sid, &crie,
|
||||
CRYPTOCAP_F_SOFTWARE);
|
||||
if (error != 0) {
|
||||
free(wr, M_ELI);
|
||||
if (req != NULL) {
|
||||
|
@ -73,7 +73,7 @@ g_eli_crypto_cipher(u_int algo, int enc, u_char *data, size_t datasize,
|
||||
cri.cri_alg = algo;
|
||||
cri.cri_key = __DECONST(void *, key);
|
||||
cri.cri_klen = keysize;
|
||||
error = crypto_newsession(&sid, &cri, 0);
|
||||
error = crypto_newsession(&sid, &cri, CRYPTOCAP_F_SOFTWARE);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
p = malloc(sizeof(*crp) + sizeof(*crd) + sizeof(*uio) + sizeof(*iov),
|
||||
|
@ -4,7 +4,7 @@
|
||||
KMOD = hifn
|
||||
SRCS = hifn7751.c opt_hifn.h
|
||||
SRCS += device_if.h bus_if.h pci_if.h
|
||||
SRCS += opt_bus.h crypto_if.h
|
||||
SRCS += opt_bus.h cryptodev_if.h
|
||||
|
||||
.if !defined(KERNBUILDDIR)
|
||||
opt_hifn.h:
|
||||
|
@ -30,7 +30,7 @@
|
||||
KMOD = safe
|
||||
SRCS = safe.c opt_safe.h
|
||||
SRCS += device_if.h bus_if.h pci_if.h
|
||||
SRCS += opt_bus.h crypto_if.h
|
||||
SRCS += opt_bus.h cryptodev_if.h
|
||||
|
||||
.if !defined(KERNBUILDDIR)
|
||||
opt_safe.h:
|
||||
|
@ -4,7 +4,7 @@
|
||||
KMOD = ubsec
|
||||
SRCS = ubsec.c opt_ubsec.h
|
||||
SRCS += device_if.h bus_if.h pci_if.h
|
||||
SRCS += opt_bus.h crypto_if.h
|
||||
SRCS += opt_bus.h cryptodev_if.h
|
||||
|
||||
.if !defined(KERNBUILDDIR)
|
||||
opt_ubsec.h:
|
||||
|
@ -117,7 +117,7 @@ int ip4_esp_randpad = -1;
|
||||
* -1 require software support
|
||||
* 0 take anything
|
||||
*/
|
||||
int crypto_support = 0;
|
||||
int crypto_support = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
|
||||
|
||||
SYSCTL_DECL(_net_inet_ipsec);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,128 +0,0 @@
|
||||
#-
|
||||
# Copyright (c) 2002, Sam Leffler
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. All advertising materials mentioning features or use of this software
|
||||
# must display the following acknowledgement:
|
||||
# This product includes software developed by Boris Popov.
|
||||
# 4. Neither the name of the author nor the names of any co-contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
#include <crypto/cryptodev.h>
|
||||
|
||||
INTERFACE crypto;
|
||||
|
||||
METHOD int32_t get_driverid {
|
||||
u_int32_t flags;
|
||||
};
|
||||
|
||||
# XXX define typedefs to work around inadequate parser
|
||||
HEADER {
|
||||
typedef int crypto_newsession_cb(void*, u_int32_t*, struct cryptoini*);
|
||||
typedef int crypto_freesession_cb(void*, u_int64_t*);
|
||||
typedef int crypto_process_cb(void*, struct cryptop*);
|
||||
typedef int crypto_kprocess_cb(void*, struct cryptkop*);
|
||||
};
|
||||
|
||||
METHOD int register {
|
||||
u_int32_t driverid;
|
||||
int alg;
|
||||
u_int16_t maxoplen;
|
||||
u_int32_t flags;
|
||||
crypto_newsession_cb* newses;
|
||||
crypto_freesession_cb* freeses;
|
||||
crypto_process_cb* process;
|
||||
void *arg;
|
||||
};
|
||||
|
||||
METHOD int kregister {
|
||||
u_int32_t driverid;
|
||||
int kalg;
|
||||
u_int32_t flags;
|
||||
crypto_kprocess_cb* kprocess;
|
||||
void *arg;
|
||||
};
|
||||
|
||||
METHOD int unregister {
|
||||
u_int32_t driverid;
|
||||
int alg;
|
||||
};
|
||||
|
||||
METHOD int unregister_all {
|
||||
u_int32_t driverid;
|
||||
};
|
||||
|
||||
METHOD int newsession {
|
||||
u_int64_t *sid;
|
||||
struct cryptoini *cri;
|
||||
int hard;
|
||||
};
|
||||
|
||||
METHOD int freesession {
|
||||
u_int64_t sid;
|
||||
};
|
||||
|
||||
METHOD int dispatch {
|
||||
struct cryptop *crp;
|
||||
};
|
||||
|
||||
METHOD int kdispatch {
|
||||
struct cryptkop *krp;
|
||||
};
|
||||
|
||||
METHOD int crypto_unblock {
|
||||
u_int32_t driverid;
|
||||
int what;
|
||||
};
|
||||
|
||||
METHOD int invoke {
|
||||
struct cryptop *crp;
|
||||
};
|
||||
|
||||
METHOD int kinvoke {
|
||||
struct cryptkop *krp;
|
||||
};
|
||||
|
||||
METHOD struct cryptop * getreq {
|
||||
int num;
|
||||
};
|
||||
|
||||
METHOD void freereq {
|
||||
struct cryptop *crp;
|
||||
};
|
||||
|
||||
METHOD void done {
|
||||
struct cryptop *crp;
|
||||
};
|
||||
|
||||
METHOD void kdone {
|
||||
struct cryptkop *krp;
|
||||
};
|
||||
|
||||
METHOD int getfeat {
|
||||
int *featp;
|
||||
};
|
@ -2,6 +2,7 @@
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 Theo de Raadt
|
||||
* Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -50,6 +51,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <opencrypto/cryptodev.h>
|
||||
#include <opencrypto/xform.h>
|
||||
@ -113,6 +115,7 @@ static int csefree(struct csession *);
|
||||
static int cryptodev_op(struct csession *, struct crypt_op *,
|
||||
struct ucred *, struct thread *td);
|
||||
static int cryptodev_key(struct crypt_kop *);
|
||||
static int cryptodev_find(struct crypt_find_op *);
|
||||
|
||||
static int
|
||||
cryptof_rw(
|
||||
@ -126,6 +129,22 @@ cryptof_rw(
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check a crypto identifier to see if it requested
|
||||
* a software device/driver. This can be done either
|
||||
* by device name/class or through search constraints.
|
||||
*/
|
||||
static int
|
||||
checkforsoftware(int crid)
|
||||
{
|
||||
if (crid & CRYPTOCAP_F_SOFTWARE)
|
||||
return EINVAL; /* XXX */
|
||||
if ((crid & CRYPTOCAP_F_HARDWARE) == 0 &&
|
||||
(crypto_getcaps(crid) & CRYPTOCAP_F_HARDWARE) == 0)
|
||||
return EINVAL; /* XXX */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
cryptof_ioctl(
|
||||
@ -135,6 +154,7 @@ cryptof_ioctl(
|
||||
struct ucred *active_cred,
|
||||
struct thread *td)
|
||||
{
|
||||
#define SES2(p) ((struct session2_op *)p)
|
||||
struct cryptoini cria, crie;
|
||||
struct fcrypt *fcr = fp->f_data;
|
||||
struct csession *cse;
|
||||
@ -142,16 +162,14 @@ cryptof_ioctl(
|
||||
struct crypt_op *cop;
|
||||
struct enc_xform *txform = NULL;
|
||||
struct auth_hash *thash = NULL;
|
||||
struct crypt_kop *kop;
|
||||
u_int64_t sid;
|
||||
u_int32_t ses;
|
||||
int error = 0;
|
||||
int error = 0, crid;
|
||||
|
||||
/*
|
||||
* XXX: Not sure Giant is needed, but better safe than sorry
|
||||
*/
|
||||
mtx_lock(&Giant);
|
||||
switch (cmd) {
|
||||
case CIOCGSESSION:
|
||||
case CIOCGSESSION2:
|
||||
sop = (struct session_op *)data;
|
||||
switch (sop->cipher) {
|
||||
case 0:
|
||||
@ -181,7 +199,6 @@ cryptof_ioctl(
|
||||
txform = &enc_xform_arc4;
|
||||
break;
|
||||
default:
|
||||
mtx_unlock(&Giant);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
@ -218,7 +235,6 @@ cryptof_ioctl(
|
||||
thash = &auth_hash_null;
|
||||
break;
|
||||
default:
|
||||
mtx_unlock(&Giant);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
@ -260,15 +276,17 @@ cryptof_ioctl(
|
||||
}
|
||||
}
|
||||
|
||||
error = crypto_newsession(&sid, (txform ? &crie : &cria), 1);
|
||||
if (error) {
|
||||
if (crypto_devallowsoft) {
|
||||
error = crypto_newsession(&sid,
|
||||
(txform ? &crie : &cria), 0);
|
||||
}
|
||||
/* NB: CIOGSESSION2 has the crid */
|
||||
if (cmd == CIOCGSESSION2) {
|
||||
crid = SES2(sop)->crid;
|
||||
error = checkforsoftware(crid);
|
||||
if (error)
|
||||
goto bail;
|
||||
}
|
||||
} else
|
||||
crid = CRYPTOCAP_F_HARDWARE;
|
||||
error = crypto_newsession(&sid, (txform ? &crie : &cria), crid);
|
||||
if (error)
|
||||
goto bail;
|
||||
|
||||
cse = csecreate(fcr, sid, crie.cri_key, crie.cri_klen,
|
||||
cria.cri_key, cria.cri_klen, sop->cipher, sop->mac, txform,
|
||||
@ -280,7 +298,10 @@ cryptof_ioctl(
|
||||
goto bail;
|
||||
}
|
||||
sop->ses = cse->ses;
|
||||
|
||||
if (cmd == CIOCGSESSION2) {
|
||||
/* return hardware/driver id */
|
||||
SES2(sop)->crid = CRYPTO_SESID2HID(cse->sid);
|
||||
}
|
||||
bail:
|
||||
if (error) {
|
||||
if (crie.cri_key)
|
||||
@ -292,33 +313,53 @@ cryptof_ioctl(
|
||||
case CIOCFSESSION:
|
||||
ses = *(u_int32_t *)data;
|
||||
cse = csefind(fcr, ses);
|
||||
if (cse == NULL) {
|
||||
mtx_unlock(&Giant);
|
||||
if (cse == NULL)
|
||||
return (EINVAL);
|
||||
}
|
||||
csedelete(fcr, cse);
|
||||
error = csefree(cse);
|
||||
break;
|
||||
case CIOCCRYPT:
|
||||
cop = (struct crypt_op *)data;
|
||||
cse = csefind(fcr, cop->ses);
|
||||
if (cse == NULL) {
|
||||
mtx_unlock(&Giant);
|
||||
if (cse == NULL)
|
||||
return (EINVAL);
|
||||
}
|
||||
error = cryptodev_op(cse, cop, active_cred, td);
|
||||
break;
|
||||
case CIOCKEY:
|
||||
error = cryptodev_key((struct crypt_kop *)data);
|
||||
case CIOCKEY2:
|
||||
if (!crypto_userasymcrypto)
|
||||
return (EPERM); /* XXX compat? */
|
||||
mtx_lock(&Giant);
|
||||
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;
|
||||
}
|
||||
error = cryptodev_key(kop);
|
||||
mtx_unlock(&Giant);
|
||||
break;
|
||||
case CIOCASYMFEAT:
|
||||
error = crypto_getfeat((int *)data);
|
||||
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);
|
||||
break;
|
||||
case CIOCFINDDEV:
|
||||
error = cryptodev_find((struct crypt_find_op *)data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
#undef SES2
|
||||
}
|
||||
|
||||
static int cryptodev_cb(void *);
|
||||
@ -485,12 +526,16 @@ cryptodev_cb(void *op)
|
||||
{
|
||||
struct cryptop *crp = (struct cryptop *) op;
|
||||
struct csession *cse = (struct csession *)crp->crp_opaque;
|
||||
int error;
|
||||
|
||||
cse->error = crp->crp_etype;
|
||||
if (crp->crp_etype == EAGAIN)
|
||||
return crypto_dispatch(crp);
|
||||
error = crp->crp_etype;
|
||||
if (error == EAGAIN)
|
||||
error = crypto_dispatch(crp);
|
||||
mtx_lock(&cse->lock);
|
||||
wakeup_one(crp);
|
||||
if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {
|
||||
cse->error = error;
|
||||
wakeup_one(crp);
|
||||
}
|
||||
mtx_unlock(&cse->lock);
|
||||
return (0);
|
||||
}
|
||||
@ -500,7 +545,7 @@ cryptodevkey_cb(void *op)
|
||||
{
|
||||
struct cryptkop *krp = (struct cryptkop *) op;
|
||||
|
||||
wakeup(krp);
|
||||
wakeup_one(krp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -550,6 +595,7 @@ cryptodev_key(struct crypt_kop *kop)
|
||||
krp->krp_status = kop->crk_status;
|
||||
krp->krp_iparams = kop->crk_iparams;
|
||||
krp->krp_oparams = kop->crk_oparams;
|
||||
krp->krp_crid = kop->crk_crid;
|
||||
krp->krp_status = 0;
|
||||
krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
|
||||
|
||||
@ -576,6 +622,7 @@ cryptodev_key(struct crypt_kop *kop)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
kop->crk_crid = krp->krp_crid; /* device that did the work */
|
||||
if (krp->krp_status != 0) {
|
||||
error = krp->krp_status;
|
||||
goto fail;
|
||||
@ -602,6 +649,25 @@ cryptodev_key(struct crypt_kop *kop)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
cryptodev_find(struct crypt_find_op *find)
|
||||
{
|
||||
device_t dev;
|
||||
|
||||
if (find->crid != -1) {
|
||||
dev = crypto_find_device_byhid(find->crid);
|
||||
if (dev == NULL)
|
||||
return (ENOENT);
|
||||
strlcpy(find->name, device_get_nameunit(dev),
|
||||
sizeof(find->name));
|
||||
} else {
|
||||
find->crid = crypto_find_driver(find->name);
|
||||
if (find->crid == -1)
|
||||
return (ENOENT);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
cryptof_poll(
|
||||
@ -775,6 +841,12 @@ cryptoioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread
|
||||
*(u_int32_t *)data = fd;
|
||||
fdrop(f, td);
|
||||
break;
|
||||
case CRIOFINDDEV:
|
||||
error = cryptodev_find((struct crypt_find_op *)data);
|
||||
break;
|
||||
case CRIOASYMFEAT:
|
||||
error = crypto_getfeat((int *)data);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
/*-
|
||||
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
|
||||
* Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
|
||||
*
|
||||
* This code was written by Angelos D. Keromytis in Athens, Greece, in
|
||||
* February 2000. Network Security Technologies Inc. (NSTI) kindly
|
||||
@ -127,6 +128,18 @@
|
||||
#define CRYPTO_ALG_FLAG_RNG_ENABLE 0x02 /* Has HW RNG for DH/DSA */
|
||||
#define CRYPTO_ALG_FLAG_DSA_SHA 0x04 /* Can do SHA on msg */
|
||||
|
||||
/*
|
||||
* Crypto driver/device flags. They can set in the crid
|
||||
* parameter when creating a session or submitting a key
|
||||
* op to affect the device/driver assigned. If neither
|
||||
* of these are specified then the crid is assumed to hold
|
||||
* the driver id of an existing (and suitable) device that
|
||||
* must be used to satisfy the request.
|
||||
*/
|
||||
#define CRYPTO_FLAG_HARDWARE 0x01000000 /* hardware accelerated */
|
||||
#define CRYPTO_FLAG_SOFTWARE 0x02000000 /* software implementation */
|
||||
|
||||
/* NB: deprecated */
|
||||
struct session_op {
|
||||
u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
|
||||
u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
|
||||
@ -139,6 +152,20 @@ struct session_op {
|
||||
u_int32_t ses; /* returns: session # */
|
||||
};
|
||||
|
||||
struct session2_op {
|
||||
u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
|
||||
u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
|
||||
|
||||
u_int32_t keylen; /* cipher key */
|
||||
caddr_t key;
|
||||
int mackeylen; /* mac key */
|
||||
caddr_t mackey;
|
||||
|
||||
u_int32_t ses; /* returns: session # */
|
||||
int crid; /* driver id + flags (rw) */
|
||||
int pad[4]; /* for future expansion */
|
||||
};
|
||||
|
||||
struct crypt_op {
|
||||
u_int32_t ses;
|
||||
u_int16_t op; /* i.e. COP_ENCRYPT */
|
||||
@ -152,6 +179,16 @@ struct crypt_op {
|
||||
caddr_t iv;
|
||||
};
|
||||
|
||||
/*
|
||||
* Parameters for looking up a crypto driver/device by
|
||||
* device name or by id. The latter are returned for
|
||||
* created sessions (crid) and completed key operations.
|
||||
*/
|
||||
struct crypt_find_op {
|
||||
int crid; /* driver id + flags */
|
||||
char name[32]; /* device/driver name */
|
||||
};
|
||||
|
||||
/* bignum parameter, in packed bytes, ... */
|
||||
struct crparam {
|
||||
caddr_t crp_p;
|
||||
@ -165,7 +202,7 @@ 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_crid; /* NB: only used by CIOCKEY2 (rw) */
|
||||
struct crparam crk_param[CRK_MAXPARAM];
|
||||
};
|
||||
#define CRK_ALGORITM_MIN 0
|
||||
@ -187,14 +224,18 @@ struct crypt_kop {
|
||||
* Please use F_SETFD against the cloned descriptor.
|
||||
*/
|
||||
#define CRIOGET _IOWR('c', 100, u_int32_t)
|
||||
#define CRIOASYMFEAT CIOCASYMFEAT
|
||||
#define CRIOFINDDEV CIOCFINDDEV
|
||||
|
||||
/* the following are done against the cloned descriptor */
|
||||
#define CIOCGSESSION _IOWR('c', 101, struct session_op)
|
||||
#define CIOCFSESSION _IOW('c', 102, u_int32_t)
|
||||
#define CIOCCRYPT _IOWR('c', 103, struct crypt_op)
|
||||
#define CIOCKEY _IOWR('c', 104, struct crypt_kop)
|
||||
|
||||
#define CIOCASYMFEAT _IOR('c', 105, u_int32_t)
|
||||
#define CIOCGSESSION2 _IOWR('c', 106, struct session2_op)
|
||||
#define CIOCKEY2 _IOWR('c', 107, struct crypt_kop)
|
||||
#define CIOCFINDDEV _IOWR('c', 108, struct crypt_find_op)
|
||||
|
||||
struct cryptotstat {
|
||||
struct timespec acc; /* total accumulated time */
|
||||
@ -316,48 +357,12 @@ struct cryptkop {
|
||||
u_int krp_status; /* return status */
|
||||
u_short krp_iparams; /* # of input parameters */
|
||||
u_short krp_oparams; /* # of output parameters */
|
||||
u_int krp_crid; /* desired device, etc. */
|
||||
u_int32_t krp_hid;
|
||||
struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
|
||||
int (*krp_callback)(struct cryptkop *);
|
||||
};
|
||||
|
||||
/*
|
||||
* Crypto capabilities structure.
|
||||
*
|
||||
* Synchronization:
|
||||
* (d) - protected by CRYPTO_DRIVER_LOCK()
|
||||
* (q) - protected by CRYPTO_Q_LOCK()
|
||||
* Not tagged fields are read-only.
|
||||
*/
|
||||
struct cryptocap {
|
||||
u_int32_t cc_sessions; /* (d) number of sessions */
|
||||
u_int32_t cc_koperations; /* (d) number os asym operations */
|
||||
|
||||
/*
|
||||
* Largest possible operator length (in bits) for each type of
|
||||
* encryption algorithm.
|
||||
*/
|
||||
u_int16_t cc_max_op_len[CRYPTO_ALGORITHM_MAX + 1];
|
||||
|
||||
u_int8_t cc_alg[CRYPTO_ALGORITHM_MAX + 1];
|
||||
|
||||
u_int8_t cc_kalg[CRK_ALGORITHM_MAX + 1];
|
||||
|
||||
u_int8_t cc_flags; /* (d) flags */
|
||||
#define CRYPTOCAP_F_CLEANUP 0x01 /* needs resource cleanup */
|
||||
#define CRYPTOCAP_F_SOFTWARE 0x02 /* software implementation */
|
||||
#define CRYPTOCAP_F_SYNC 0x04 /* operates synchronously */
|
||||
u_int8_t cc_qblocked; /* (q) symmetric q blocked */
|
||||
u_int8_t cc_kqblocked; /* (q) asymmetric q blocked */
|
||||
|
||||
void *cc_arg; /* callback argument */
|
||||
int (*cc_newsession)(void*, u_int32_t*, struct cryptoini*);
|
||||
int (*cc_process)(void*, struct cryptop *, int);
|
||||
int (*cc_freesession)(void*, u_int64_t);
|
||||
void *cc_karg; /* callback argument */
|
||||
int (*cc_kprocess) (void*, struct cryptkop *, int);
|
||||
};
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -365,24 +370,24 @@ struct cryptocap {
|
||||
* a copy of the driver's capabilities that can be used by client code to
|
||||
* optimize operation.
|
||||
*/
|
||||
#define CRYPTO_SESID2HID(_sid) (((_sid) >> 32) & 0xffffff)
|
||||
#define CRYPTO_SESID2CAPS(_sid) (((_sid) >> 56) & 0xff)
|
||||
#define CRYPTO_SESID2HID(_sid) (((_sid) >> 32) & 0x00ffffff)
|
||||
#define CRYPTO_SESID2CAPS(_sid) (((_sid) >> 32) & 0xff000000)
|
||||
#define CRYPTO_SESID2LID(_sid) (((u_int32_t) (_sid)) & 0xffffffff)
|
||||
|
||||
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 int32_t crypto_get_driverid(u_int32_t flags);
|
||||
#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 int crypto_find_driver(const char *);
|
||||
extern device_t crypto_find_device_byhid(int hid);
|
||||
extern int crypto_getcaps(int hid);
|
||||
extern int crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
|
||||
u_int32_t flags,
|
||||
int (*newses)(void*, u_int32_t*, struct cryptoini*),
|
||||
int (*freeses)(void*, u_int64_t),
|
||||
int (*process)(void*, struct cryptop *, int),
|
||||
void *arg);
|
||||
extern int crypto_kregister(u_int32_t, int, u_int32_t,
|
||||
int (*)(void*, struct cryptkop *, int),
|
||||
void *arg);
|
||||
u_int32_t flags);
|
||||
extern int crypto_kregister(u_int32_t, int, u_int32_t);
|
||||
extern int crypto_unregister(u_int32_t driverid, int alg);
|
||||
extern int crypto_unregister_all(u_int32_t driverid);
|
||||
extern int crypto_dispatch(struct cryptop *crp);
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
/*-
|
||||
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
|
||||
* Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
|
||||
*
|
||||
* This code was written by Angelos D. Keromytis in Athens, Greece, in
|
||||
* February 2000. Network Security Technologies Inc. (NSTI) kindly
|
||||
@ -28,6 +29,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/random.h>
|
||||
@ -45,19 +47,21 @@ __FBSDID("$FreeBSD$");
|
||||
#include <opencrypto/cryptosoft.h>
|
||||
#include <opencrypto/xform.h>
|
||||
|
||||
u_int8_t *hmac_ipad_buffer;
|
||||
u_int8_t *hmac_opad_buffer;
|
||||
#include <sys/kobj.h>
|
||||
#include <sys/bus.h>
|
||||
#include "cryptodev_if.h"
|
||||
|
||||
struct swcr_data **swcr_sessions = NULL;
|
||||
u_int32_t swcr_sesnum = 0;
|
||||
int32_t swcr_id = -1;
|
||||
static int32_t swcr_id;
|
||||
static struct swcr_data **swcr_sessions = NULL;
|
||||
static u_int32_t swcr_sesnum;
|
||||
|
||||
u_int8_t hmac_ipad_buffer[HMAC_MAX_BLOCK_LEN];
|
||||
u_int8_t hmac_opad_buffer[HMAC_MAX_BLOCK_LEN];
|
||||
|
||||
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_compdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
|
||||
static int swcr_process(void *, struct cryptop *, int);
|
||||
static int swcr_newsession(void *, u_int32_t *, struct cryptoini *);
|
||||
static int swcr_freesession(void *, u_int64_t);
|
||||
static int swcr_freesession(device_t dev, u_int64_t tid);
|
||||
|
||||
/*
|
||||
* Apply a symmetric encryption/decryption algorithm.
|
||||
@ -580,7 +584,7 @@ swcr_compdec(struct cryptodesc *crd, struct swcr_data *sw,
|
||||
* Generate a new software session.
|
||||
*/
|
||||
static int
|
||||
swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
|
||||
swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
|
||||
{
|
||||
struct swcr_data **swd;
|
||||
struct auth_hash *axf;
|
||||
@ -618,7 +622,7 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
|
||||
}
|
||||
|
||||
/* Copy existing sessions */
|
||||
if (swcr_sessions) {
|
||||
if (swcr_sessions != NULL) {
|
||||
bcopy(swcr_sessions, swd,
|
||||
(swcr_sesnum / 2) * sizeof(struct swcr_data *));
|
||||
free(swcr_sessions, M_CRYPTO_DATA);
|
||||
@ -634,7 +638,7 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
|
||||
MALLOC(*swd, struct swcr_data *, sizeof(struct swcr_data),
|
||||
M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
|
||||
if (*swd == NULL) {
|
||||
swcr_freesession(NULL, i);
|
||||
swcr_freesession(dev, i);
|
||||
return ENOBUFS;
|
||||
}
|
||||
|
||||
@ -665,7 +669,7 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
|
||||
error = txf->setkey(&((*swd)->sw_kschedule),
|
||||
cri->cri_key, cri->cri_klen / 8);
|
||||
if (error) {
|
||||
swcr_freesession(NULL, i);
|
||||
swcr_freesession(dev, i);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
@ -696,14 +700,14 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
|
||||
(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
|
||||
M_NOWAIT);
|
||||
if ((*swd)->sw_ictx == NULL) {
|
||||
swcr_freesession(NULL, i);
|
||||
swcr_freesession(dev, i);
|
||||
return ENOBUFS;
|
||||
}
|
||||
|
||||
(*swd)->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
|
||||
M_NOWAIT);
|
||||
if ((*swd)->sw_octx == NULL) {
|
||||
swcr_freesession(NULL, i);
|
||||
swcr_freesession(dev, i);
|
||||
return ENOBUFS;
|
||||
}
|
||||
|
||||
@ -726,14 +730,14 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
|
||||
(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
|
||||
M_NOWAIT);
|
||||
if ((*swd)->sw_ictx == NULL) {
|
||||
swcr_freesession(NULL, i);
|
||||
swcr_freesession(dev, i);
|
||||
return ENOBUFS;
|
||||
}
|
||||
|
||||
(*swd)->sw_octx = malloc(cri->cri_klen / 8,
|
||||
M_CRYPTO_DATA, M_NOWAIT);
|
||||
if ((*swd)->sw_octx == NULL) {
|
||||
swcr_freesession(NULL, i);
|
||||
swcr_freesession(dev, i);
|
||||
return ENOBUFS;
|
||||
}
|
||||
|
||||
@ -757,7 +761,7 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
|
||||
(*swd)->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
|
||||
M_NOWAIT);
|
||||
if ((*swd)->sw_ictx == NULL) {
|
||||
swcr_freesession(NULL, i);
|
||||
swcr_freesession(dev, i);
|
||||
return ENOBUFS;
|
||||
}
|
||||
|
||||
@ -771,7 +775,7 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
|
||||
(*swd)->sw_cxf = cxf;
|
||||
break;
|
||||
default:
|
||||
swcr_freesession(NULL, i);
|
||||
swcr_freesession(dev, i);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
@ -786,7 +790,7 @@ swcr_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
|
||||
* Free a session.
|
||||
*/
|
||||
static int
|
||||
swcr_freesession(void *arg, u_int64_t tid)
|
||||
swcr_freesession(device_t dev, u_int64_t tid)
|
||||
{
|
||||
struct swcr_data *swd;
|
||||
struct enc_xform *txf;
|
||||
@ -874,7 +878,7 @@ swcr_freesession(void *arg, u_int64_t tid)
|
||||
* Process a software request.
|
||||
*/
|
||||
static int
|
||||
swcr_process(void *arg, struct cryptop *crp, int hint)
|
||||
swcr_process(device_t dev, struct cryptop *crp, int hint)
|
||||
{
|
||||
struct cryptodesc *crd;
|
||||
struct swcr_data *sw;
|
||||
@ -967,28 +971,37 @@ swcr_process(void *arg, struct cryptop *crp, int hint)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the driver, called from the kernel main().
|
||||
*/
|
||||
static void
|
||||
swcr_init(void)
|
||||
swcr_identify(device_t *dev, device_t parent)
|
||||
{
|
||||
u_int i;
|
||||
/* NB: order 10 is so we get attached after h/w devices */
|
||||
if (device_find_child(parent, "cryptosoft", -1) == NULL &&
|
||||
BUS_ADD_CHILD(parent, 10, "cryptosoft", -1) == 0)
|
||||
panic("cryptosoft: could not attach");
|
||||
}
|
||||
|
||||
hmac_ipad_buffer = malloc(HMAC_MAX_BLOCK_LEN, M_CRYPTO_DATA, M_WAITOK);
|
||||
for (i = 0; i < HMAC_MAX_BLOCK_LEN; i++)
|
||||
hmac_ipad_buffer[i] = HMAC_IPAD_VAL;
|
||||
hmac_opad_buffer = malloc(HMAC_MAX_BLOCK_LEN, M_CRYPTO_DATA, M_WAITOK);
|
||||
for (i = 0; i < HMAC_MAX_BLOCK_LEN; i++)
|
||||
hmac_opad_buffer[i] = HMAC_OPAD_VAL;
|
||||
static int
|
||||
swcr_probe(device_t dev)
|
||||
{
|
||||
device_set_desc(dev, "software crypto");
|
||||
return (0);
|
||||
}
|
||||
|
||||
swcr_id = crypto_get_driverid(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
|
||||
if (swcr_id < 0)
|
||||
panic("Software crypto device cannot initialize!");
|
||||
crypto_register(swcr_id, CRYPTO_DES_CBC,
|
||||
0, 0, swcr_newsession, swcr_freesession, swcr_process, NULL);
|
||||
static int
|
||||
swcr_attach(device_t dev)
|
||||
{
|
||||
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,
|
||||
CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
|
||||
if (swcr_id < 0) {
|
||||
device_printf(dev, "cannot initialize!");
|
||||
return ENOMEM;
|
||||
}
|
||||
#define REGISTER(alg) \
|
||||
crypto_register(swcr_id, alg, 0,0,NULL,NULL,NULL,NULL)
|
||||
crypto_register(swcr_id, alg, 0,0)
|
||||
REGISTER(CRYPTO_DES_CBC);
|
||||
REGISTER(CRYPTO_3DES_CBC);
|
||||
REGISTER(CRYPTO_BLF_CBC);
|
||||
REGISTER(CRYPTO_CAST_CBC);
|
||||
@ -1008,16 +1021,47 @@ swcr_init(void)
|
||||
REGISTER(CRYPTO_RIJNDAEL128_CBC);
|
||||
REGISTER(CRYPTO_DEFLATE_COMP);
|
||||
#undef REGISTER
|
||||
|
||||
return 0;
|
||||
}
|
||||
SYSINIT(cryptosoft_init, SI_SUB_PSEUDO, SI_ORDER_ANY, swcr_init, NULL)
|
||||
|
||||
static void
|
||||
swcr_uninit(void)
|
||||
swcr_detach(device_t dev)
|
||||
{
|
||||
|
||||
crypto_unregister_all(swcr_id);
|
||||
if (swcr_sessions != NULL)
|
||||
FREE(swcr_sessions, M_CRYPTO_DATA);
|
||||
free(hmac_ipad_buffer, M_CRYPTO_DATA);
|
||||
free(hmac_opad_buffer, M_CRYPTO_DATA);
|
||||
}
|
||||
SYSUNINIT(cryptosoft_uninit, SI_SUB_PSEUDO, SI_ORDER_ANY, swcr_uninit, NULL);
|
||||
|
||||
static device_method_t swcr_methods[] = {
|
||||
DEVMETHOD(device_identify, swcr_identify),
|
||||
DEVMETHOD(device_probe, swcr_probe),
|
||||
DEVMETHOD(device_attach, swcr_attach),
|
||||
DEVMETHOD(device_detach, swcr_detach),
|
||||
|
||||
DEVMETHOD(cryptodev_newsession, swcr_newsession),
|
||||
DEVMETHOD(cryptodev_freesession,swcr_freesession),
|
||||
DEVMETHOD(cryptodev_process, swcr_process),
|
||||
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static driver_t swcr_driver = {
|
||||
"cryptosoft",
|
||||
swcr_methods,
|
||||
0, /* NB: no softc */
|
||||
};
|
||||
static devclass_t swcr_devclass;
|
||||
|
||||
/*
|
||||
* NB: We explicitly reference the crypto module so we
|
||||
* get the necessary ordering when built as a loadable
|
||||
* module. This is required because we bundle the crypto
|
||||
* module code together with the cryptosoft driver (otherwise
|
||||
* normal module dependencies would handle things).
|
||||
*/
|
||||
extern int crypto_modevent(struct module *, int, void *);
|
||||
/* XXX where to attach */
|
||||
DRIVER_MODULE(cryptosoft, nexus, swcr_driver, swcr_devclass, crypto_modevent,0);
|
||||
MODULE_VERSION(cryptosoft, 1);
|
||||
MODULE_DEPEND(cryptosoft, crypto, 1, 1, 1);
|
||||
|
@ -60,8 +60,8 @@ struct swcr_data {
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
extern u_int8_t *hmac_ipad_buffer;
|
||||
extern u_int8_t *hmac_opad_buffer;
|
||||
extern u_int8_t hmac_ipad_buffer[];
|
||||
extern u_int8_t hmac_opad_buffer[];
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _CRYPTO_CRYPTO_H_ */
|
||||
|
@ -12,13 +12,55 @@
|
||||
#include <sys/time.h>
|
||||
#include <crypto/cryptodev.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <paths.h>
|
||||
#include <fcntl.h>
|
||||
#include <err.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static int crypto_fd = -1;
|
||||
int crid = CRYPTO_FLAG_HARDWARE;
|
||||
int verbose = 0;
|
||||
|
||||
static int
|
||||
devcrypto(void)
|
||||
{
|
||||
static int fd = -1;
|
||||
|
||||
if (fd < 0) {
|
||||
fd = open(_PATH_DEV "crypto", O_RDWR, 0);
|
||||
if (fd < 0)
|
||||
err(1, _PATH_DEV "crypto");
|
||||
if (fcntl(fd, F_SETFD, 1) == -1)
|
||||
err(1, "fcntl(F_SETFD) (devcrypto)");
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int
|
||||
crlookup(const char *devname)
|
||||
{
|
||||
struct crypt_find_op find;
|
||||
|
||||
find.crid = -1;
|
||||
strlcpy(find.name, devname, sizeof(find.name));
|
||||
if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
|
||||
err(1, "ioctl(CIOCFINDDEV)");
|
||||
return find.crid;
|
||||
}
|
||||
|
||||
static const char *
|
||||
crfind(int crid)
|
||||
{
|
||||
static struct crypt_find_op find;
|
||||
|
||||
bzero(&find, sizeof(find));
|
||||
find.crid = crid;
|
||||
if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
|
||||
err(1, "ioctl(CIOCFINDDEV)");
|
||||
return find.name;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a little endian byte string in 'p' that
|
||||
@ -85,17 +127,10 @@ UB_mod_exp(BIGNUM *res, BIGNUM *a, BIGNUM *b, BIGNUM *c, BN_CTX *ctx)
|
||||
{
|
||||
struct crypt_kop kop;
|
||||
u_int8_t *ale, *ble, *cle;
|
||||
static int crypto_fd = -1;
|
||||
|
||||
if (crypto_fd == -1) {
|
||||
int fd, fdc = open("/dev/crypto", O_RDONLY);
|
||||
|
||||
if (fdc == -1)
|
||||
err(1, "/dev/crypto");
|
||||
if (ioctl(fdc, CRIOGET, &fd) == -1)
|
||||
err(1, "CRIOGET");
|
||||
close(fdc);
|
||||
crypto_fd = fd;
|
||||
}
|
||||
if (crypto_fd == -1 && ioctl(devcrypto(), CRIOGET, &crypto_fd) == -1)
|
||||
err(1, "CRIOGET");
|
||||
|
||||
if ((ale = bignum_to_le(a, NULL)) == NULL)
|
||||
err(1, "bignum_to_le, a");
|
||||
@ -108,6 +143,7 @@ UB_mod_exp(BIGNUM *res, BIGNUM *a, BIGNUM *b, BIGNUM *c, BN_CTX *ctx)
|
||||
kop.crk_op = CRK_MOD_EXP;
|
||||
kop.crk_iparams = 3;
|
||||
kop.crk_oparams = 1;
|
||||
kop.crk_crid = crid;
|
||||
kop.crk_param[0].crp_p = ale;
|
||||
kop.crk_param[0].crp_nbits = BN_num_bytes(a) * 8;
|
||||
kop.crk_param[1].crp_p = ble;
|
||||
@ -117,8 +153,10 @@ UB_mod_exp(BIGNUM *res, BIGNUM *a, BIGNUM *b, BIGNUM *c, BN_CTX *ctx)
|
||||
kop.crk_param[3].crp_p = cle;
|
||||
kop.crk_param[3].crp_nbits = BN_num_bytes(c) * 8;
|
||||
|
||||
if (ioctl(crypto_fd, CIOCKEY, &kop) == -1)
|
||||
err(1, "CIOCKEY");
|
||||
if (ioctl(crypto_fd, CIOCKEY2, &kop) == -1)
|
||||
err(1, "CIOCKEY2");
|
||||
if (verbose)
|
||||
printf("device = %s\n", crfind(kop.crk_crid));
|
||||
|
||||
bzero(ale, BN_num_bytes(a));
|
||||
free(ale);
|
||||
@ -211,10 +249,35 @@ testit(void)
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
static void
|
||||
usage(const char* cmd)
|
||||
{
|
||||
int i;
|
||||
printf("usage: %s [-d dev] [-v] [count]\n", cmd);
|
||||
printf("count is the number of bignum ops to do\n");
|
||||
printf("\n");
|
||||
printf("-d use specific device\n");
|
||||
printf("-v be verbose\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int c, i;
|
||||
|
||||
while ((c = getopt(argc, argv, "d:v")) != -1) {
|
||||
switch (c) {
|
||||
case 'd':
|
||||
crid = crlookup(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
argc -= optind, argv += optind;
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
fprintf(stderr, "test %d\n", i);
|
||||
|
@ -40,6 +40,7 @@
|
||||
* Run count iterations of a crypt+decrypt or mac operation on a buffer of
|
||||
* size bytes. A random key and iv are used. Options:
|
||||
* -c check the results
|
||||
* -d dev pin work on device dev
|
||||
* -z run all available algorithms on a variety of buffer sizes
|
||||
* -v be verbose
|
||||
* -b mark operations for batching
|
||||
@ -106,6 +107,7 @@ void hexdump(char *, int);
|
||||
int verbose = 0;
|
||||
int opflags = 0;
|
||||
int verify = 0;
|
||||
int crid = CRYPTO_FLAG_HARDWARE;
|
||||
|
||||
struct alg {
|
||||
const char* name;
|
||||
@ -139,7 +141,7 @@ struct alg {
|
||||
static void
|
||||
usage(const char* cmd)
|
||||
{
|
||||
printf("usage: %s [-c] [-z] [-s] [-b] [-v] [-a algorithm] [count] [size ...]\n",
|
||||
printf("usage: %s [-czsbv] [-d dev] [-a algorithm] [count] [size ...]\n",
|
||||
cmd);
|
||||
printf("where algorithm is one of:\n");
|
||||
printf(" des 3des (default) blowfish cast skipjack\n");
|
||||
@ -148,6 +150,7 @@ usage(const char* cmd)
|
||||
printf("size is the number of bytes of text to encrypt+decrypt\n");
|
||||
printf("\n");
|
||||
printf("-c check the results (slows timing)\n");
|
||||
printf("-d use specific device\n");
|
||||
printf("-z run all available algorithms on a variety of sizes\n");
|
||||
printf("-v be verbose\n");
|
||||
printf("-b mark operations for batching\n");
|
||||
@ -192,6 +195,30 @@ devcrypto(void)
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int
|
||||
crlookup(const char *devname)
|
||||
{
|
||||
struct crypt_find_op find;
|
||||
|
||||
find.crid = -1;
|
||||
strlcpy(find.name, devname, sizeof(find.name));
|
||||
if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
|
||||
err(1, "ioctl(CIOCFINDDEV)");
|
||||
return find.crid;
|
||||
}
|
||||
|
||||
static const char *
|
||||
crfind(int crid)
|
||||
{
|
||||
static struct crypt_find_op find;
|
||||
|
||||
bzero(&find, sizeof(find));
|
||||
find.crid = crid;
|
||||
if (ioctl(devcrypto(), CRIOFINDDEV, &find) == -1)
|
||||
err(1, "ioctl(CIOCFINDDEV): crid %d", crid);
|
||||
return find.name;
|
||||
}
|
||||
|
||||
static int
|
||||
crget(void)
|
||||
{
|
||||
@ -220,7 +247,7 @@ runtest(struct alg *alg, int count, int size, u_long cmd, struct timeval *tv)
|
||||
int i, fd = crget();
|
||||
struct timeval start, stop, dt;
|
||||
char *cleartext, *ciphertext, *originaltext;
|
||||
struct session_op sop;
|
||||
struct session2_op sop;
|
||||
struct crypt_op cop;
|
||||
char iv[8];
|
||||
|
||||
@ -242,8 +269,9 @@ runtest(struct alg *alg, int count, int size, u_long cmd, struct timeval *tv)
|
||||
sop.mackey[i] = rdigit();
|
||||
sop.mac = alg->code;
|
||||
}
|
||||
sop.crid = crid;
|
||||
if (ioctl(fd, cmd, &sop) < 0) {
|
||||
if (cmd == CIOCGSESSION) {
|
||||
if (cmd == CIOCGSESSION || cmd == CIOCGSESSION2) {
|
||||
close(fd);
|
||||
if (verbose) {
|
||||
printf("cipher %s", alg->name);
|
||||
@ -274,6 +302,7 @@ runtest(struct alg *alg, int count, int size, u_long cmd, struct timeval *tv)
|
||||
|
||||
if (verbose) {
|
||||
printf("session = 0x%x\n", sop.ses);
|
||||
printf("device = %s\n", crfind(sop.crid));
|
||||
printf("count = %d, size = %d\n", count, size);
|
||||
if (!alg->ishash) {
|
||||
printf("iv:");
|
||||
@ -448,10 +477,17 @@ runtests(struct alg *alg, int count, int size, u_long cmd, int threads, int prof
|
||||
if (t) {
|
||||
int nops = alg->ishash ? count : 2*count;
|
||||
|
||||
#if 0
|
||||
t /= threads;
|
||||
printf("%6.3lf sec, %7d %6s crypts, %7d bytes, %8.0lf byte/sec, %7.1lf Mb/sec\n",
|
||||
t, nops, alg->name, size, (double)nops*size / t,
|
||||
(double)nops*size / t * 8 / 1024 / 1024);
|
||||
#else
|
||||
nops *= threads;
|
||||
printf("%8.3lf sec, %7d %6s crypts, %7d bytes, %8.0lf byte/sec, %7.1lf Mb/sec\n",
|
||||
t, nops, alg->name, size, (double)nops*size / t,
|
||||
(double)nops*size / t * 8 / 1024 / 1024);
|
||||
#endif
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
if (profile) {
|
||||
@ -480,13 +516,13 @@ main(int argc, char **argv)
|
||||
struct alg *alg = NULL;
|
||||
int count = 1;
|
||||
int sizes[128], nsizes = 0;
|
||||
u_long cmd = CIOCGSESSION;
|
||||
u_long cmd = CIOCGSESSION2;
|
||||
int testall = 0;
|
||||
int maxthreads = 1;
|
||||
int profile = 0;
|
||||
int i, ch;
|
||||
|
||||
while ((ch = getopt(argc, argv, "cpzsva:bt:")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "cpzsva:bd:t:")) != -1) {
|
||||
switch (ch) {
|
||||
#ifdef CIOCGSSESSION
|
||||
case 's':
|
||||
@ -505,6 +541,9 @@ main(int argc, char **argv)
|
||||
usage(argv[0]);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
crid = crlookup(optarg);
|
||||
break;
|
||||
case 't':
|
||||
maxthreads = atoi(optarg);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user