opencrypto - Finish porting
authorAlex Hornung <ahornung@gmail.com>
Fri, 2 Oct 2009 13:24:19 +0000 (14:24 +0100)
committerAlex Hornung <ahornung@gmail.com>
Fri, 2 Oct 2009 15:18:08 +0000 (16:18 +0100)
* Fix all remaining porting issues from the original opencrypto WIP
  commit.
* Remove clashes due to rebase.

19 files changed:
sys/conf/files
sys/config/GENERIC
sys/crypto/via/padlock.c
sys/crypto/via/padlock.h
sys/crypto/via/padlock_cipher.c
sys/crypto/via/padlock_hash.c
sys/dev/crypto/hifn/hifn7751.c
sys/dev/crypto/hifn/hifn7751var.h
sys/dev/crypto/ubsec/ubsec.c
sys/dev/crypto/ubsec/ubsecvar.h
sys/netinet6/esp_aesctr.c [new file with mode: 0644]
sys/netinet6/esp_camellia.c [new file with mode: 0644]
sys/opencrypto/crypto.c
sys/opencrypto/cryptodev.c
sys/opencrypto/cryptodev.h
sys/opencrypto/cryptosoft.c
sys/opencrypto/xform.c
sys/opencrypto/xform.h
sys/platform/pc32/i386/identcpu.c

index 7b68495..b0d4be2 100644 (file)
@@ -1166,6 +1166,8 @@ netinet6/esp_core.c               optional ipsec ipsec_esp
 netinet6/esp_input.c           optional ipsec ipsec_esp
 netinet6/esp_output.c          optional ipsec ipsec_esp
 netinet6/esp_rijndael.c                optional ipsec ipsec_esp
+netinet6/esp_camellia.c                optional ipsec ipsec_esp
+netinet6/esp_aesctr.c          optional ipsec ipsec_esp
 netinet6/ipsec.c               optional ipsec
 netinet6/dest6.c               optional inet6
 netinet6/frag6.c               optional inet6
index 1ba6658..0ae1588 100644 (file)
@@ -312,6 +312,7 @@ pseudo-device       faith   1       # IPv6-to-IPv4 relaying (translation)
 pseudo-device  bpf             #Berkeley packet filter
 
 pseudo-device  crypto          # core crypto support, used by wlan
+pseudo-device  cryptodev
 
 # USB support
 device         uhci            # UHCI PCI->USB interface
index e0cd691..3510aa5 100644 (file)
@@ -73,8 +73,9 @@ static void
 padlock_identify(driver_t *drv, device_t parent)
 {
        /* NB: order 10 is so we get attached after h/w devices */
+       /* XXX: wouldn't bet about this BUS_ADD_CHILD correctness */
        if (device_find_child(parent, "padlock", -1) == NULL &&
-           BUS_ADD_CHILD(parent, 10, "padlock", -1) == 0)
+           BUS_ADD_CHILD(parent, parent, 10, "padlock", -1) == 0)
                panic("padlock: could not attach");
 }
 
index 41ca39e..96707ba 100644 (file)
@@ -60,8 +60,8 @@ union padlock_cw {
 
 struct padlock_session {
        union padlock_cw ses_cw __aligned(16);
-       uint32_t        ses_ekey[4 * (RIJNDAEL_MAXROUNDS + 1) + 4] __aligned(16);       /* 128 bit aligned */
-       uint32_t        ses_dkey[4 * (RIJNDAEL_MAXROUNDS + 1) + 4] __aligned(16);       /* 128 bit aligned */
+       uint32_t        ses_ekey[4 * (RIJNDAEL_MAXNR + 1) + 4] __aligned(16);   /* 128 bit aligned */
+       uint32_t        ses_dkey[4 * (RIJNDAEL_MAXNR + 1) + 4] __aligned(16);   /* 128 bit aligned */
        uint8_t         ses_iv[16] __aligned(16);                       /* 128 bit aligned */
        struct auth_hash *ses_axf;
        uint8_t         *ses_ictx;
index d75b376..831187c 100644 (file)
@@ -153,7 +153,7 @@ padlock_cipher_setup(struct padlock_session *ses, struct cryptoini *encini)
                    encini->cri_klen);
        }
 
-       arc4rand(ses->ses_iv, sizeof(ses->ses_iv), 0);
+       karc4rand(ses->ses_iv, sizeof(ses->ses_iv));
        return (0);
 }
 
@@ -190,7 +190,7 @@ padlock_cipher_alloc(struct cryptodesc *enccrd, struct cryptop *crp,
        }
 alloc:
        *allocated = 1;
-       addr = malloc(enccrd->crd_len + 16, M_PADLOCK, M_NOWAIT);
+       addr = kmalloc(enccrd->crd_len + 16, M_PADLOCK, M_NOWAIT);
        return (addr);
 }
 
@@ -262,7 +262,7 @@ padlock_cipher_process(struct padlock_session *ses, struct cryptodesc *enccrd,
 
        if (allocated) {
                bzero(buf, enccrd->crd_len + 16);
-               free(buf, M_PADLOCK);
+               kfree(buf, M_PADLOCK);
        }
        return (0);
 }
index 6630262..32aae26 100644 (file)
@@ -169,7 +169,7 @@ padlock_sha_update(struct padlock_sha_ctx *ctx, uint8_t *buf, uint16_t bufsize)
 
        if (ctx->psc_size - ctx->psc_offset < bufsize) {
                ctx->psc_size = MAX(ctx->psc_size * 2, ctx->psc_size + bufsize);
-               ctx->psc_buf = realloc(ctx->psc_buf, ctx->psc_size, M_PADLOCK,
+               ctx->psc_buf = krealloc(ctx->psc_buf, ctx->psc_size, M_PADLOCK,
                    M_NOWAIT);
                if(ctx->psc_buf == NULL)
                        return (ENOMEM);
@@ -185,7 +185,7 @@ padlock_sha_free(struct padlock_sha_ctx *ctx)
 
        if (ctx->psc_buf != NULL) {
                //bzero(ctx->psc_buf, ctx->psc_size);
-               free(ctx->psc_buf, M_PADLOCK);
+               kfree(ctx->psc_buf, M_PADLOCK);
                ctx->psc_buf = NULL;
                ctx->psc_offset = 0;
                ctx->psc_size = 0;
@@ -219,7 +219,7 @@ padlock_copy_ctx(struct auth_hash *axf, void *sctx, void *dctx)
 
                dpctx->psc_offset = spctx->psc_offset;
                dpctx->psc_size = spctx->psc_size;
-               dpctx->psc_buf = malloc(dpctx->psc_size, M_PADLOCK, M_WAITOK);
+               dpctx->psc_buf = kmalloc(dpctx->psc_size, M_PADLOCK, M_WAITOK);
                bcopy(spctx->psc_buf, dpctx->psc_buf, dpctx->psc_size);
        } else {
                bcopy(sctx, dctx, axf->ctxsize);
@@ -343,9 +343,9 @@ padlock_hash_setup(struct padlock_session *ses, struct cryptoini *macini)
        }
 
        /* Allocate memory for HMAC inner and outer contexts. */
-       ses->ses_ictx = malloc(ses->ses_axf->ctxsize, M_PADLOCK,
+       ses->ses_ictx = kmalloc(ses->ses_axf->ctxsize, M_PADLOCK,
            M_ZERO | M_NOWAIT);
-       ses->ses_octx = malloc(ses->ses_axf->ctxsize, M_PADLOCK,
+       ses->ses_octx = kmalloc(ses->ses_axf->ctxsize, M_PADLOCK,
            M_ZERO | M_NOWAIT);
        if (ses->ses_ictx == NULL || ses->ses_octx == NULL)
                return (ENOMEM);
@@ -378,13 +378,13 @@ padlock_hash_free(struct padlock_session *ses)
        if (ses->ses_ictx != NULL) {
                padlock_free_ctx(ses->ses_axf, ses->ses_ictx);
                bzero(ses->ses_ictx, ses->ses_axf->ctxsize);
-               free(ses->ses_ictx, M_PADLOCK);
+               kfree(ses->ses_ictx, M_PADLOCK);
                ses->ses_ictx = NULL;
        }
        if (ses->ses_octx != NULL) {
                padlock_free_ctx(ses->ses_axf, ses->ses_octx);
                bzero(ses->ses_octx, ses->ses_axf->ctxsize);
-               free(ses->ses_octx, M_PADLOCK);
+               kfree(ses->ses_octx, M_PADLOCK);
                ses->ses_octx = NULL;
        }
 }
index 488f6de..b4426f1 100644 (file)
@@ -68,6 +68,8 @@
 #include <machine/clock.h>
 #include <opencrypto/cryptodev.h>
 
+#include "cryptodev_if.h"
+
 #include <bus/pci/pcivar.h>
 #include <bus/pci/pcireg.h>
 
@@ -87,35 +89,6 @@ static       int hifn_suspend(device_t);
 static int hifn_resume(device_t);
 static void hifn_shutdown(device_t);
 
-static device_method_t hifn_methods[] = {
-       /* Device interface */
-       DEVMETHOD(device_probe,         hifn_probe),
-       DEVMETHOD(device_attach,        hifn_attach),
-       DEVMETHOD(device_detach,        hifn_detach),
-       DEVMETHOD(device_suspend,       hifn_suspend),
-       DEVMETHOD(device_resume,        hifn_resume),
-       DEVMETHOD(device_shutdown,      hifn_shutdown),
-
-       /* bus interface */
-       DEVMETHOD(bus_print_child,      bus_generic_print_child),
-       DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
-
-       { 0, 0 }
-};
-static driver_t hifn_driver = {
-       "hifn",
-       hifn_methods,
-       sizeof (struct hifn_softc)
-};
-static devclass_t hifn_devclass;
-
-DECLARE_DUMMY_MODULE(hifn);
-DRIVER_MODULE(hifn, pci, hifn_driver, hifn_devclass, 0, 0);
-MODULE_DEPEND(hifn, crypto, 1, 1, 1);
-#ifdef HIFN_RNDTEST
-MODULE_DEPEND(hifn, rndtest, 1, 1, 1);
-#endif
-
 static void hifn_reset_board(struct hifn_softc *, int);
 static void hifn_reset_puc(struct hifn_softc *);
 static void hifn_puc_wait(struct hifn_softc *);
@@ -150,6 +123,41 @@ static     void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, int *);
 static void hifn_write_reg_0(struct hifn_softc *, bus_size_t, u_int32_t);
 static void hifn_write_reg_1(struct hifn_softc *, bus_size_t, u_int32_t);
 
+
+static device_method_t hifn_methods[] = {
+       /* Device interface */
+       DEVMETHOD(device_probe,         hifn_probe),
+       DEVMETHOD(device_attach,        hifn_attach),
+       DEVMETHOD(device_detach,        hifn_detach),
+       DEVMETHOD(device_suspend,       hifn_suspend),
+       DEVMETHOD(device_resume,        hifn_resume),
+       DEVMETHOD(device_shutdown,      hifn_shutdown),
+
+       /* bus interface */
+       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 = {
+       "hifn",
+       hifn_methods,
+       sizeof (struct hifn_softc)
+};
+static devclass_t hifn_devclass;
+
+DECLARE_DUMMY_MODULE(hifn);
+DRIVER_MODULE(hifn, pci, hifn_driver, hifn_devclass, 0, 0);
+MODULE_DEPEND(hifn, crypto, 1, 1, 1);
+#ifdef HIFN_RNDTEST
+MODULE_DEPEND(hifn, rndtest, 1, 1, 1);
+#endif
+
 static __inline__ u_int32_t
 READ_REG_0(struct hifn_softc *sc, bus_size_t reg)
 {
@@ -564,7 +572,7 @@ hifn_attach(device_t dev)
                        2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
        kprintf("\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;
@@ -576,26 +584,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;
        }
 
@@ -2370,7 +2369,19 @@ hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
                        if (mac)
                                return (EINVAL);
                        mac = 1;
-                       break;
+                       ses->hs_mlen = c->cri_mlen;
+                       if (ses->hs_mlen == 0) {
+                               switch (c->cri_alg) {
+                               case CRYPTO_MD5:
+                               case CRYPTO_MD5_HMAC:
+                                       ses->hs_mlen = 16;
+                                       break;
+                               case CRYPTO_SHA1:
+                               case CRYPTO_SHA1_HMAC:
+                                       ses->hs_mlen = 20;
+                                       break;
+                               }
+                       }
                case CRYPTO_DES_CBC:
                case CRYPTO_3DES_CBC:
                case CRYPTO_AES_CBC:
@@ -2836,6 +2847,17 @@ hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, u_int8_t *macbuf)
                for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
                         int len;
 
+                       if (crd->crd_alg != CRYPTO_MD5 &&
+                           crd->crd_alg != CRYPTO_SHA1 &&
+                           crd->crd_alg != CRYPTO_MD5_HMAC &&
+                           crd->crd_alg != CRYPTO_SHA1_HMAC) {
+                               continue;
+                       }
+                       len = cmd->softc->sc_sessions[cmd->session_num].hs_mlen;
+                       crypto_copyback(crp->crp_flags, crp->crp_buf,
+                           crd->crd_inject, len, macbuf);
+                       break;
+#if 0
                         if (crd->crd_alg == CRYPTO_MD5)
                                len = 16;
                         else if (crd->crd_alg == CRYPTO_SHA1)
@@ -2852,6 +2874,7 @@ hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, u_int8_t *macbuf)
                        else if ((crp->crp_flags & CRYPTO_F_IOV) && crp->crp_mac)
                                bcopy((caddr_t)macbuf, crp->crp_mac, len);
                        break;
+#endif
                }
        }
 
index c8d3cc9..5c8e7e6 100644 (file)
@@ -113,6 +113,7 @@ struct hifn_dma {
 
 struct hifn_session {
        int hs_used;
+       int hs_mlen;
        u_int8_t hs_iv[HIFN_MAX_IV_LENGTH];
 };
 
index 933f9bb..5d93a8f 100644 (file)
@@ -71,6 +71,8 @@
 #include <opencrypto/cryptodev.h>
 #include <opencrypto/cryptosoft.h>
 
+#include "cryptodev_if.h"
+
 #include <bus/pci/pcivar.h>
 #include <bus/pci/pcireg.h>
 
@@ -102,36 +104,6 @@ static     int ubsec_detach(device_t);
 static int ubsec_suspend(device_t);
 static int ubsec_resume(device_t);
 static void ubsec_shutdown(device_t);
-
-static device_method_t ubsec_methods[] = {
-       /* Device interface */
-       DEVMETHOD(device_probe,         ubsec_probe),
-       DEVMETHOD(device_attach,        ubsec_attach),
-       DEVMETHOD(device_detach,        ubsec_detach),
-       DEVMETHOD(device_suspend,       ubsec_suspend),
-       DEVMETHOD(device_resume,        ubsec_resume),
-       DEVMETHOD(device_shutdown,      ubsec_shutdown),
-
-       /* bus interface */
-       DEVMETHOD(bus_print_child,      bus_generic_print_child),
-       DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
-
-       { 0, 0 }
-};
-static driver_t ubsec_driver = {
-       "ubsec",
-       ubsec_methods,
-       sizeof (struct ubsec_softc)
-};
-static devclass_t ubsec_devclass;
-
-DECLARE_DUMMY_MODULE(ubsec);
-DRIVER_MODULE(ubsec, pci, ubsec_driver, ubsec_devclass, 0, 0);
-MODULE_DEPEND(ubsec, crypto, 1, 1, 1);
-#ifdef UBSEC_RNDTEST
-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);
@@ -165,6 +137,42 @@ static     int ubsec_ksigbits(struct crparam *);
 static void ubsec_kshift_r(u_int, u_int8_t *, u_int, u_int8_t *, u_int);
 static void ubsec_kshift_l(u_int, u_int8_t *, u_int, u_int8_t *, u_int);
 
+
+static device_method_t ubsec_methods[] = {
+       /* Device interface */
+       DEVMETHOD(device_probe,         ubsec_probe),
+       DEVMETHOD(device_attach,        ubsec_attach),
+       DEVMETHOD(device_detach,        ubsec_detach),
+       DEVMETHOD(device_suspend,       ubsec_suspend),
+       DEVMETHOD(device_resume,        ubsec_resume),
+       DEVMETHOD(device_shutdown,      ubsec_shutdown),
+
+       /* bus interface */
+       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 = {
+       "ubsec",
+       ubsec_methods,
+       sizeof (struct ubsec_softc)
+};
+static devclass_t ubsec_devclass;
+
+DECLARE_DUMMY_MODULE(ubsec);
+DRIVER_MODULE(ubsec, pci, ubsec_driver, ubsec_devclass, 0, 0);
+MODULE_DEPEND(ubsec, crypto, 1, 1, 1);
+#ifdef UBSEC_RNDTEST
+MODULE_DEPEND(ubsec, rndtest, 1, 1, 1);
+#endif
+
 SYSCTL_NODE(_hw, OID_AUTO, ubsec, CTLFLAG_RD, 0, "Broadcom driver parameters");
 
 #ifdef UBSEC_DEBUG
@@ -353,7 +361,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;
@@ -397,14 +405,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
@@ -465,11 +469,9 @@ skip_rng:
        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);
@@ -815,6 +817,69 @@ feed1:
        return;
 }
 
+static void
+ubsec_setup_enckey(struct ubsec_session *ses, int algo, caddr_t key)
+{
+
+       /* Go ahead and compute key in ubsec's byte order */
+       if (algo == CRYPTO_DES_CBC) {
+               bcopy(key, &ses->ses_deskey[0], 8);
+               bcopy(key, &ses->ses_deskey[2], 8);
+               bcopy(key, &ses->ses_deskey[4], 8);
+       } else
+               bcopy(key, ses->ses_deskey, 24);
+
+       SWAP32(ses->ses_deskey[0]);
+       SWAP32(ses->ses_deskey[1]);
+       SWAP32(ses->ses_deskey[2]);
+       SWAP32(ses->ses_deskey[3]);
+       SWAP32(ses->ses_deskey[4]);
+       SWAP32(ses->ses_deskey[5]);
+}
+
+static void
+ubsec_setup_mackey(struct ubsec_session *ses, int algo, caddr_t key, int klen)
+{
+       MD5_CTX md5ctx;
+       SHA1_CTX sha1ctx;
+       int i;
+
+       for (i = 0; i < klen; i++)
+               key[i] ^= HMAC_IPAD_VAL;
+
+       if (algo == CRYPTO_MD5_HMAC) {
+               MD5Init(&md5ctx);
+               MD5Update(&md5ctx, key, klen);
+               MD5Update(&md5ctx, hmac_ipad_buffer, MD5_HMAC_BLOCK_LEN - klen);
+               bcopy(md5ctx.state, ses->ses_hminner, sizeof(md5ctx.state));
+       } else {
+               SHA1Init(&sha1ctx);
+               SHA1Update(&sha1ctx, key, klen);
+               SHA1Update(&sha1ctx, hmac_ipad_buffer,
+                   SHA1_HMAC_BLOCK_LEN - klen);
+               bcopy(sha1ctx.h.b32, ses->ses_hminner, sizeof(sha1ctx.h.b32));
+       }
+
+       for (i = 0; i < klen; i++)
+               key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
+
+       if (algo == CRYPTO_MD5_HMAC) {
+               MD5Init(&md5ctx);
+               MD5Update(&md5ctx, key, klen);
+               MD5Update(&md5ctx, hmac_opad_buffer, MD5_HMAC_BLOCK_LEN - klen);
+               bcopy(md5ctx.state, ses->ses_hmouter, sizeof(md5ctx.state));
+       } else {
+               SHA1Init(&sha1ctx);
+               SHA1Update(&sha1ctx, key, klen);
+               SHA1Update(&sha1ctx, hmac_opad_buffer,
+                   SHA1_HMAC_BLOCK_LEN - klen);
+               bcopy(sha1ctx.h.b32, ses->ses_hmouter, sizeof(sha1ctx.h.b32));
+       }
+
+       for (i = 0; i < klen; i++)
+               key[i] ^= HMAC_OPAD_VAL;
+}
+
 /*
  * Allocate a new 'session' and return an encoded session id.  'sidp'
  * contains our registration id, and should contain an encoded session
@@ -882,6 +947,12 @@ ubsec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
        bzero(ses, sizeof(struct ubsec_session));
        ses->ses_used = 1;
        if (encini) {
+               read_random(ses->ses_iv, sizeof(ses->ses_iv));
+               if (encini->cri_key != NULL) {
+                       ubsec_setup_enckey(ses, encini->cri_alg,
+                           encini->cri_key);
+               }
+#if 0
                /* get an IV, network byte order */
                /* XXX may read fewer than requested */
                read_random(ses->ses_iv, sizeof(ses->ses_iv));
@@ -900,9 +971,23 @@ ubsec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
                SWAP32(ses->ses_deskey[3]);
                SWAP32(ses->ses_deskey[4]);
                SWAP32(ses->ses_deskey[5]);
+#endif
        }
 
        if (macini) {
+               ses->ses_mlen = macini->cri_mlen;
+               if (ses->ses_mlen == 0) {
+                       if (macini->cri_alg == CRYPTO_MD5_HMAC)
+                               ses->ses_mlen = MD5_HASH_LEN;
+                       else
+                               ses->ses_mlen = SHA1_HASH_LEN;
+               }
+
+               if (macini->cri_key != NULL) {
+                       ubsec_setup_mackey(ses, macini->cri_alg,
+                           macini->cri_key, macini->cri_klen/8);
+               }
+#if 0
                for (i = 0; i < macini->cri_klen / 8; i++)
                        macini->cri_key[i] ^= HMAC_IPAD_VAL;
 
@@ -911,7 +996,7 @@ ubsec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
                        MD5Update(&md5ctx, macini->cri_key,
                            macini->cri_klen / 8);
                        MD5Update(&md5ctx, hmac_ipad_buffer,
-                           HMAC_BLOCK_LEN - (macini->cri_klen / 8));
+                           MD5_HMAC_BLOCK_LEN - (macini->cri_klen / 8));
                        bcopy(md5ctx.state, ses->ses_hminner,
                            sizeof(md5ctx.state));
                } else {
@@ -919,7 +1004,7 @@ ubsec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
                        SHA1Update(&sha1ctx, macini->cri_key,
                            macini->cri_klen / 8);
                        SHA1Update(&sha1ctx, hmac_ipad_buffer,
-                           HMAC_BLOCK_LEN - (macini->cri_klen / 8));
+                           SHA1_HMAC_BLOCK_LEN - (macini->cri_klen / 8));
                        bcopy(sha1ctx.h.b32, ses->ses_hminner,
                            sizeof(sha1ctx.h.b32));
                }
@@ -932,7 +1017,7 @@ ubsec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
                        MD5Update(&md5ctx, macini->cri_key,
                            macini->cri_klen / 8);
                        MD5Update(&md5ctx, hmac_opad_buffer,
-                           HMAC_BLOCK_LEN - (macini->cri_klen / 8));
+                           MD5_HMAC_BLOCK_LEN - (macini->cri_klen / 8));
                        bcopy(md5ctx.state, ses->ses_hmouter,
                            sizeof(md5ctx.state));
                } else {
@@ -940,13 +1025,14 @@ ubsec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
                        SHA1Update(&sha1ctx, macini->cri_key,
                            macini->cri_klen / 8);
                        SHA1Update(&sha1ctx, hmac_opad_buffer,
-                           HMAC_BLOCK_LEN - (macini->cri_klen / 8));
+                           SHA1_HMAC_BLOCK_LEN - (macini->cri_klen / 8));
                        bcopy(sha1ctx.h.b32, ses->ses_hmouter,
                            sizeof(sha1ctx.h.b32));
                }
 
                for (i = 0; i < macini->cri_klen / 8; i++)
                        macini->cri_key[i] ^= HMAC_OPAD_VAL;
+#endif
        }
 
        *sidp = UBSEC_SID(device_get_unit(sc->sc_dev), sesn);
@@ -1580,6 +1666,10 @@ ubsec_callback(struct ubsec_softc *sc, struct ubsec_q *q)
                if (crd->crd_alg != CRYPTO_MD5_HMAC &&
                    crd->crd_alg != CRYPTO_SHA1_HMAC)
                        continue;
+               crypto_copyback(crp->crp_flags, crp->crp_buf, crd->crd_inject,
+                   sc->sc_sessions[q->q_sesn].ses_mlen,
+                   (caddr_t)dmap->d_dma->d_macbuf);
+#if 0
                if (crp->crp_flags & CRYPTO_F_IMBUF)
                        m_copyback((struct mbuf *)crp->crp_buf,
                            crd->crd_inject, 12,
@@ -1588,6 +1678,7 @@ ubsec_callback(struct ubsec_softc *sc, struct ubsec_q *q)
                        bcopy((caddr_t)dmap->d_dma->d_macbuf,
                            crp->crp_mac, 12);
                break;
+#endif
        }
        SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next);
        crypto_done(crp);
index e726a41..a62dd93 100644 (file)
@@ -214,6 +214,7 @@ struct ubsec_softc {
 struct ubsec_session {
        u_int32_t       ses_used;
        u_int32_t       ses_deskey[6];          /* 3DES key */
+       u_int32_t       ses_mlen;               /* hmac length */
        u_int32_t       ses_hminner[5];         /* hmac inner state */
        u_int32_t       ses_hmouter[5];         /* hmac outer state */
        u_int32_t       ses_iv[2];              /* [3]DES iv */
diff --git a/sys/netinet6/esp_aesctr.c b/sys/netinet6/esp_aesctr.c
new file mode 100644 (file)
index 0000000..336792e
--- /dev/null
@@ -0,0 +1,447 @@
+/*     $KAME: esp_aesctr.c,v 1.2 2003/07/20 00:29:37 itojun Exp $      */
+
+/*-
+ * Copyright (C) 1995, 1996, 1997, 1998 and 2003 WIDE Project.
+ * 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. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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 <sys/param.h>
+#include <sys/systm.h>
+#include <sys/socket.h>
+#include <sys/queue.h>
+#include <sys/syslog.h>
+#include <sys/mbuf.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netproto/key/key.h>
+
+#include <netinet6/ipsec.h>
+#include <netinet6/esp.h>
+#include <netinet6/esp_aesctr.h>
+
+#include <crypto/rijndael/rijndael.h>
+
+#define AES_BLOCKSIZE  16
+
+#define NONCESIZE      4
+union cblock {
+       struct {
+               u_int8_t nonce[4];
+               u_int8_t iv[8];
+               u_int32_t ctr;
+       } __packed v;
+       u_int8_t cblock[16];
+};
+
+typedef struct {
+       u_int32_t       r_ek[(RIJNDAEL_MAXNR+1)*4];
+       int             r_nr; /* key-length-dependent number of rounds */
+} aesctr_ctx;
+
+int
+esp_aesctr_mature(struct secasvar *sav)
+{
+       int keylen;
+       const struct esp_algorithm *algo;
+
+       algo = esp_algorithm_lookup(sav->alg_enc);
+       if (!algo) {
+               ipseclog((LOG_ERR,
+                   "esp_aeesctr_mature %s: unsupported algorithm.\n",
+                   algo->name));
+               return 1;
+       }
+
+       keylen = sav->key_enc->sadb_key_bits;
+       if (keylen < algo->keymin || algo->keymax < keylen) {
+               ipseclog((LOG_ERR,
+                   "esp_aesctr_mature %s: invalid key length %d.\n",
+                   algo->name, sav->key_enc->sadb_key_bits));
+               return 1;
+       }
+
+       /* rijndael key + nonce */
+       if (!(keylen == 128 + 32 || keylen == 192 + 32 || keylen == 256 + 32)) {
+               ipseclog((LOG_ERR,
+                   "esp_aesctr_mature %s: invalid key length %d.\n",
+                   algo->name, keylen));
+               return 1;
+       }
+
+       return 0;
+}
+
+size_t
+esp_aesctr_schedlen(const struct esp_algorithm *algo)
+{
+
+       return sizeof(aesctr_ctx);
+}
+
+int
+esp_aesctr_schedule(const struct esp_algorithm *algo, struct secasvar *sav)
+{
+       aesctr_ctx *ctx;
+       int keylen;
+
+       /* SA key = AES key + nonce */
+       keylen = _KEYLEN(sav->key_enc) * 8 - NONCESIZE * 8;
+
+       ctx = (aesctr_ctx *)sav->sched;
+       if ((ctx->r_nr = rijndaelKeySetupEnc(ctx->r_ek,
+           (char *)_KEYBUF(sav->key_enc), keylen)) == 0)
+               return -1;
+       return 0;
+}
+
+int
+esp_aesctr_decrypt(struct mbuf *m, size_t off, struct secasvar *sav,
+               const struct esp_algorithm *algo, int ivlen)
+{
+       struct mbuf *s;
+       struct mbuf *d, *d0 = NULL, *dp;
+       int soff, doff; /* offset from the head of chain, to head of this mbuf */
+       int sn, dn;     /* offset from the head of the mbuf, to meat */
+       size_t ivoff, bodyoff;
+       union cblock cblock;
+       u_int8_t keystream[AES_BLOCKSIZE], *nonce;
+       u_int32_t ctr;
+       u_int8_t *ivp;
+       u_int8_t sbuf[AES_BLOCKSIZE], *sp, *dst;
+       struct mbuf *scut;
+       int scutoff;
+       int i;
+       int blocklen;
+       aesctr_ctx *ctx;
+
+       if (ivlen != sav->ivlen) {
+               ipseclog((LOG_ERR, "esp_aesctr_decrypt %s: "
+                   "unsupported ivlen %d\n", algo->name, ivlen));
+               goto fail;
+       }
+
+       /* assumes blocklen == padbound */
+       blocklen = algo->padbound;
+
+       ivoff = off + sizeof(struct newesp);
+       bodyoff = off + sizeof(struct newesp) + ivlen;
+
+       /* setup counter block */
+       nonce = _KEYBUF(sav->key_enc) + _KEYLEN(sav->key_enc) - NONCESIZE;
+       bcopy(nonce, cblock.v.nonce, NONCESIZE);
+       m_copydata(m, ivoff, ivlen, cblock.v.iv);
+       ctr = 1;
+
+       if (m->m_pkthdr.len < bodyoff) {
+               ipseclog((LOG_ERR, "esp_aesctr_decrypt %s: bad len %d/%lu\n",
+                   algo->name, m->m_pkthdr.len, (unsigned long)bodyoff));
+               goto fail;
+       }
+       if ((m->m_pkthdr.len - bodyoff) % blocklen) {
+               ipseclog((LOG_ERR, "esp_aesctr_decrypt %s: "
+                   "payload length must be multiple of %d\n",
+                   algo->name, blocklen));
+               goto fail;
+       }
+
+       s = m;
+       d = d0 = dp = NULL;
+       soff = doff = sn = dn = 0;
+       ivp = sp = NULL;
+
+       /* skip bodyoff */
+       while (soff < bodyoff) {
+               if (soff + s->m_len > bodyoff) {
+                       sn = bodyoff - soff;
+                       break;
+               }
+
+               soff += s->m_len;
+               s = s->m_next;
+       }
+       scut = s;
+       scutoff = sn;
+
+       /* skip over empty mbuf */
+       while (s && s->m_len == 0)
+               s = s->m_next;
+
+       while (soff < m->m_pkthdr.len) {
+               /* source */
+               if (sn + blocklen <= s->m_len) {
+                       /* body is continuous */
+                       sp = mtod(s, u_int8_t *) + sn;
+               } else {
+                       /* body is non-continuous */
+                       m_copydata(s, sn, blocklen, (caddr_t)sbuf);
+                       sp = sbuf;
+               }
+
+               /* destination */
+               if (!d || dn + blocklen > d->m_len) {
+                       if (d)
+                               dp = d;
+                       MGET(d, M_NOWAIT, MT_DATA);
+                       i = m->m_pkthdr.len - (soff + sn);
+                       if (d && i > MLEN) {
+                               MCLGET(d, M_NOWAIT);
+                               if ((d->m_flags & M_EXT) == 0) {
+                                       m_free(d);
+                                       d = NULL;
+                               }
+                       }
+                       if (!d) {
+                               goto nomem;
+                       }
+                       if (!d0)
+                               d0 = d;
+                       if (dp)
+                               dp->m_next = d;
+                       d->m_len = 0;
+                       d->m_len = (M_TRAILINGSPACE(d) / blocklen) * blocklen;
+                       if (d->m_len > i)
+                               d->m_len = i;
+                       dn = 0;
+               }
+
+               /* put counter into counter block */
+               cblock.v.ctr = htonl(ctr);
+
+               /* setup keystream */
+               ctx = (aesctr_ctx *)sav->sched;
+               rijndaelEncrypt(ctx->r_ek, ctx->r_nr, cblock.cblock, keystream);
+
+               bcopy(sp, mtod(d, u_int8_t *) + dn, blocklen);
+               dst = mtod(d, u_int8_t *) + dn;
+               for (i = 0; i < blocklen; i++)
+                       dst[i] ^= keystream[i];
+
+               ctr++;
+
+               sn += blocklen;
+               dn += blocklen;
+
+               /* find the next source block */
+               while (s && sn >= s->m_len) {
+                       sn -= s->m_len;
+                       soff += s->m_len;
+                       s = s->m_next;
+               }
+
+               /* skip over empty mbuf */
+               while (s && s->m_len == 0)
+                       s = s->m_next;
+       }
+
+       m_freem(scut->m_next);
+       scut->m_len = scutoff;
+       scut->m_next = d0;
+
+       /* just in case */
+       bzero(&cblock, sizeof(cblock));
+       bzero(keystream, sizeof(keystream));
+
+       return 0;
+
+fail:
+       m_freem(m);
+       if (d0)
+               m_freem(d0);
+       return EINVAL;
+
+nomem:
+       m_freem(m);
+       if (d0)
+               m_freem(d0);
+       return ENOBUFS;
+}
+
+int
+esp_aesctr_encrypt(struct mbuf *m, size_t off, size_t plen, struct secasvar *sav,
+               const struct esp_algorithm *algo, int ivlen)
+{
+       struct mbuf *s;
+       struct mbuf *d, *d0, *dp;
+       int soff, doff; /* offset from the head of chain, to head of this mbuf */
+       int sn, dn;     /* offset from the head of the mbuf, to meat */
+       size_t ivoff, bodyoff;
+       union cblock cblock;
+       u_int8_t keystream[AES_BLOCKSIZE], *nonce;
+       u_int32_t ctr;
+       u_int8_t sbuf[AES_BLOCKSIZE], *sp, *dst;
+       struct mbuf *scut;
+       int scutoff;
+       int i;
+       int blocklen;
+       aesctr_ctx *ctx;
+
+       if (ivlen != sav->ivlen) {
+               ipseclog((LOG_ERR, "esp_aesctr_encrypt %s: "
+                   "unsupported ivlen %d\n", algo->name, ivlen));
+               m_freem(m);
+               return EINVAL;
+       }
+
+       /* assumes blocklen == padbound */
+       blocklen = algo->padbound;
+
+       ivoff = off + sizeof(struct newesp);
+       bodyoff = off + sizeof(struct newesp) + ivlen;
+
+       /* put iv into the packet. */
+       /* maybe it is better to overwrite dest, not source */
+       m_copyback(m, ivoff, ivlen, sav->iv);
+
+       /* setup counter block */
+       nonce = _KEYBUF(sav->key_enc) + _KEYLEN(sav->key_enc) - NONCESIZE;
+       bcopy(nonce, cblock.v.nonce, NONCESIZE);
+       m_copydata(m, ivoff, ivlen, cblock.v.iv);
+       ctr = 1;
+
+       if (m->m_pkthdr.len < bodyoff) {
+               ipseclog((LOG_ERR, "esp_aesctr_encrypt %s: bad len %d/%lu\n",
+                   algo->name, m->m_pkthdr.len, (unsigned long)bodyoff));
+               m_freem(m);
+               return EINVAL;
+       }
+       if ((m->m_pkthdr.len - bodyoff) % blocklen) {
+               ipseclog((LOG_ERR, "esp_aesctr_encrypt %s: "
+                   "payload length must be multiple of %lu\n",
+                   algo->name, (unsigned long)algo->padbound));
+               m_freem(m);
+               return EINVAL;
+       }
+
+       s = m;
+       d = d0 = dp = NULL;
+       soff = doff = sn = dn = 0;
+       sp = NULL;
+
+       /* skip bodyoff */
+       while (soff < bodyoff) {
+               if (soff + s->m_len > bodyoff) {
+                       sn = bodyoff - soff;
+                       break;
+               }
+
+               soff += s->m_len;
+               s = s->m_next;
+       }
+       scut = s;
+       scutoff = sn;
+
+       /* skip over empty mbuf */
+       while (s && s->m_len == 0)
+               s = s->m_next;
+
+       while (soff < m->m_pkthdr.len) {
+               /* source */
+               if (sn + blocklen <= s->m_len) {
+                       /* body is continuous */
+                       sp = mtod(s, u_int8_t *) + sn;
+               } else {
+                       /* body is non-continuous */
+                       m_copydata(s, sn, blocklen, (caddr_t)sbuf);
+                       sp = sbuf;
+               }
+
+               /* destination */
+               if (!d || dn + blocklen > d->m_len) {
+                       if (d)
+                               dp = d;
+                       MGET(d, M_NOWAIT, MT_DATA);
+                       i = m->m_pkthdr.len - (soff + sn);
+                       if (d && i > MLEN) {
+                               MCLGET(d, M_NOWAIT);
+                               if ((d->m_flags & M_EXT) == 0) {
+                                       m_free(d);
+                                       d = NULL;
+                               }
+                       }
+                       if (!d) {
+                               m_freem(m);
+                               if (d0)
+                                       m_freem(d0);
+                               return ENOBUFS;
+                       }
+                       if (!d0)
+                               d0 = d;
+                       if (dp)
+                               dp->m_next = d;
+                       d->m_len = 0;
+                       d->m_len = (M_TRAILINGSPACE(d) / blocklen) * blocklen;
+                       if (d->m_len > i)
+                               d->m_len = i;
+                       dn = 0;
+               }
+
+               /* put counter into counter block */
+               cblock.v.ctr = htonl(ctr);
+
+               /* setup keystream */
+               ctx = (aesctr_ctx *)sav->sched;
+               rijndaelEncrypt(ctx->r_ek, ctx->r_nr, cblock.cblock, keystream);
+
+               bcopy(sp, mtod(d, u_int8_t *) + dn, blocklen);
+               dst = mtod(d, u_int8_t *) + dn;
+               for (i = 0; i < blocklen; i++)
+                       dst[i] ^= keystream[i];
+
+               ctr++;
+
+               sn += blocklen;
+               dn += blocklen;
+
+               /* find the next source block */
+               while (s && sn >= s->m_len) {
+                       sn -= s->m_len;
+                       soff += s->m_len;
+                       s = s->m_next;
+               }
+
+               /* skip over empty mbuf */
+               while (s && s->m_len == 0)
+                       s = s->m_next;
+       }
+
+       m_freem(scut->m_next);
+       scut->m_len = scutoff;
+       scut->m_next = d0;
+
+       /* just in case */
+       bzero(&cblock, sizeof(cblock));
+       bzero(keystream, sizeof(keystream));
+
+       key_sa_stir_iv(sav);
+
+       return 0;
+}
diff --git a/sys/netinet6/esp_camellia.c b/sys/netinet6/esp_camellia.c
new file mode 100644 (file)
index 0000000..dcd834f
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ *
+ * Copyright (c) 2006
+ * NTT (Nippon Telegraph and Telephone Corporation) . 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 as
+ *   the first lines of this file unmodified.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NTT ``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 NTT 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/socket.h>
+#include <sys/queue.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <netinet/in.h>
+
+#include <netinet6/ipsec.h>
+#include <netinet6/esp.h>
+#include <netinet6/esp_camellia.h>
+
+#include <crypto/camellia/camellia.h>
+
+size_t
+esp_camellia_schedlen(const struct esp_algorithm *algo)
+{
+
+       return sizeof(camellia_ctx);
+}
+
+int
+esp_camellia_schedule(const struct esp_algorithm *algo, struct secasvar *sav)
+{
+       camellia_ctx *ctx;
+
+       ctx = (camellia_ctx *)sav->sched;
+       camellia_set_key(ctx,
+           (u_char *)_KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc) * 8);
+       return 0;
+}
+
+int
+esp_camellia_blockdecrypt(const struct esp_algorithm *algo, struct secasvar *sav,
+                       u_int8_t *s, u_int8_t *d)
+{
+       camellia_ctx *ctx;
+
+       ctx = (camellia_ctx *)sav->sched;
+       camellia_decrypt(ctx, s, d);
+       return 0;
+}
+
+int
+esp_camellia_blockencrypt(const struct esp_algorithm *algo, struct secasvar *sav,
+                       u_int8_t *s, u_int8_t *d)
+{
+       camellia_ctx *ctx;
+
+       ctx = (camellia_ctx *)sav->sched;
+       camellia_encrypt(ctx, s, d);
+       return 0;
+}
index 9a87d7f..31fa1e2 100644 (file)
@@ -253,13 +253,15 @@ crypto_terminate(struct thread **tp, void *q)
        t = *tp;
        *tp = NULL;
        if (t) {
+               kprintf("crypto_terminate: start\n");
                wakeup_one(q);
-               crit_enter()
+               crit_enter();
                tsleep_interlock(t, 0);
                CRYPTO_DRIVER_UNLOCK(); /* let crypto_finis progress */
-               tsleep(t, 0, "crypto_destroy", 0);
                crit_exit();
+               tsleep(t, PINTERLOCKED, "crypto_destroy", 0);
                CRYPTO_DRIVER_LOCK();
+               kprintf("crypto_terminate: end\n");
        }
 }
 
@@ -270,8 +272,8 @@ crypto_destroy(void)
         * Terminate any crypto threads.
         */
        CRYPTO_DRIVER_LOCK();
-       crypto_terminate(&cryptoproc, &crp_q);
-       crypto_terminate(&cryptoretproc, &crp_ret_q);
+       crypto_terminate(&cryptothread, &crp_q);
+       crypto_terminate(&cryptoretthread, &crp_ret_q);
        CRYPTO_DRIVER_UNLOCK();
 
        /* XXX flush queues??? */
@@ -286,9 +288,9 @@ crypto_destroy(void)
                zdestroy(cryptodesc_zone);
        if (cryptop_zone != NULL)
                zdestroy(cryptop_zone);
-       lockuninit(&crypto_q_mtx);
-       lockuninit(&crypto_ret_q_mtx);
-       lockuninit(&crypto_drivers_mtx);
+       lockuninit(&crypto_q_lock);
+       lockuninit(&crypto_ret_q_lock);
+       lockuninit(&crypto_drivers_lock);
 }
 
 static struct cryptocap *
@@ -1362,9 +1364,9 @@ crypto_proc(void)
                         * and some become blocked while others do not.
                         */
                        crp_sleep = 1;
-                       tsleep(&crp_q, 0, "crypto_wait", 0);
+                       lksleep (&crp_q, &crypto_q_lock, 0, "crypto_wait", 0);
                        crp_sleep = 0;
-                       if (cryptoproc == NULL)
+                       if (cryptothread == NULL)
                                break;
                        cryptostats.cs_intrs++;
                }
@@ -1409,7 +1411,7 @@ crypto_ret_proc(void)
                                         * doing the callback as the cryptop is
                                         * likely to be reclaimed.
                                         */
-                                       struct timespec t = crp->crp_tstamp;
+                                       struct timespec t = crpt->crp_tstamp;
                                        crypto_tstat(&cryptostats.cs_cb, &t);
                                        crpt->crp_callback(crpt);
                                        crypto_tstat(&cryptostats.cs_finis, &t);
@@ -1425,9 +1427,10 @@ crypto_ret_proc(void)
                         * Nothing more to be processed.  Sleep until we're
                         * woken because there are more returns to process.
                         */
-                       tsleep(&crp_ret_q, 0, "crypto_ret_wait", 0);
-                       if (cryptoretproc == NULL)
+                       lksleep (&crp_ret_q, &crypto_ret_q_lock, 0, "crypto_ret_wait", 0);
+                       if (cryptoretthread == NULL) {
                                break;
+                       }
                        cryptostats.cs_rets++;
                }
        }
@@ -1551,7 +1554,7 @@ crypto_modevent(module_t mod, int type, void *unused)
        case MOD_LOAD:
                error = crypto_init();
                if (error == 0 && bootverbose)
-                       printf("crypto: <crypto core>\n");
+                       kprintf("crypto: <crypto core>\n");
                break;
        case MOD_UNLOAD:
                /*XXX disallow if active sessions */
index 1cd8bff..b3c7d24 100644 (file)
@@ -36,6 +36,7 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/malloc.h>
+#include <sys/device.h>
 #include <sys/mbuf.h>
 #include <sys/lock.h>
 #include <sys/sysctl.h>
@@ -68,6 +69,7 @@ struct csession {
 
        caddr_t         key;
        int             keylen;
+       u_char          tmp_iv[EALG_MAX_BLOCK_LEN];
 
        caddr_t         mackey;
        int             mackeylen;
@@ -147,7 +149,7 @@ cryptof_ioctl(struct file *fp, u_long cmd, caddr_t data,
 {
 #define        SES2(p) ((struct session2_op *)p)
        struct cryptoini cria, crie;
-       struct fcrypt *fcr;
+       struct fcrypt *fcr = fp->f_data;
        struct csession *cse;
        struct session_op *sop;
        struct crypt_op *cop;
@@ -262,7 +264,7 @@ cryptof_ioctl(struct file *fp, u_long cmd, caddr_t data,
                        }
 
                        if (cria.cri_klen) {
-                               cria.cri_key = malloc(cria.cri_klen / 8,
+                               cria.cri_key = kmalloc(cria.cri_klen / 8,
                                    M_XDATA, M_WAITOK);
                                if ((error = copyin(sop->mackey, cria.cri_key,
                                    cria.cri_klen / 8)))
@@ -317,7 +319,7 @@ bail:
                cse = csefind(fcr, cop->ses);
                if (cse == NULL)
                        return (EINVAL);
-               error = cryptodev_op(cse, cop, active_cred);
+               error = cryptodev_op(cse, cop, cred);
                break;
        case CIOCKEY:
        case CIOCKEY2:
@@ -382,7 +384,8 @@ cryptodev_op(struct csession *cse, struct crypt_op *cop,
        cse->uio.uio_resid = cop->len;
        cse->uio.uio_segflg = UIO_SYSSPACE;
        cse->uio.uio_rw = UIO_WRITE;
-       cse->uio.uio_td = td;
+       /* XXX: not sure, was td, now curthread? */
+       cse->uio.uio_td = curthread;
        cse->uio.uio_iov[0].iov_len = cop->len;
        if (cse->thash) {
                cse->uio.uio_iov[0].iov_len += cse->thash->hashsize;
@@ -482,7 +485,7 @@ again:
        error = crypto_dispatch(crp);
        lockmgr(&cse->lock, LK_EXCLUSIVE);
        if (error == 0 && (crp->crp_flags & CRYPTO_F_DONE) == 0)
-               error = tsleep(crp, 0, "crydev", 0);
+               error = lksleep(crp, &cse->lock, 0, "crydev", 0);
        lockmgr(&cse->lock, LK_RELEASE);
 
        if (error != 0)
@@ -612,7 +615,7 @@ cryptodev_key(struct crypt_kop *kop)
        error = crypto_kdispatch(krp);
        if (error)
                goto fail;
-       error = tsleep(krp, PSOCK, "crydev", 0);
+       error = tsleep(krp, 0, "crydev", 0);
        if (error) {
                /* XXX can this happen?  if so, how do we recover? */
                goto fail;
@@ -754,10 +757,10 @@ csecreate(struct fcrypt *fcr, u_int64_t sid, caddr_t key, u_int64_t keylen,
 {
        struct csession *cse;
 
-       cse = malloc(sizeof(struct csession), M_XDATA, M_NOWAIT);
+       cse = kmalloc(sizeof(struct csession), M_XDATA, M_NOWAIT);
        if (cse == NULL)
                return NULL;
-       lockinit(&cse->lock, "cryptodev", LK_CANRECURSE);
+       lockinit(&cse->lock, "cryptodev", 0, LK_CANRECURSE);
        cse->key = key;
        cse->keylen = keylen/8;
        cse->mackey = mackey;
@@ -825,15 +828,20 @@ cryptoioctl(struct dev_ioctl_args *ap)
                        return (error);
                }
                /* falloc automatically provides an extra reference to 'f'. */
-               finit(f, FREAD | FWRITE, DTYPE_CRYPTO, fcr, &cryptofops);
-               *(u_int32_t *)data = fd;
-               fdrop(f, td);
+               f->f_flag = FREAD | FWRITE;
+               f->f_type = DTYPE_CRYPTO;
+               f->f_ops = &cryptofops;
+               f->f_data = fcr;
+               fsetfd(curproc, f, fd);
+               *(u_int32_t *)ap->a_data = fd;
+               fdrop(f);
+
                break;
        case CRIOFINDDEV:
-               error = cryptodev_find((struct crypt_find_op *)data);
+               error = cryptodev_find((struct crypt_find_op *)ap->a_data);
                break;
        case CRIOASYMFEAT:
-               error = crypto_getfeat((int *)data);
+               error = crypto_getfeat((int *)ap->a_data);
                break;
        default:
                error = EINVAL;
index f93a8ed..d151a87 100644 (file)
@@ -57,6 +57,7 @@
 #define _CRYPTO_CRYPTO_H_
 
 #include <sys/ioccom.h>
+#include <sys/bus.h>
 
 /* Some initial values */
 #define CRYPTO_DRIVERS_INITIAL 4
@@ -242,6 +243,7 @@ struct crypt_kop {
 struct cryptotstat {
        struct timespec acc;            /* total accumulated time */
        struct timespec min;            /* min time */
+       struct timespec max;            /* max time */
        u_int32_t       count;          /* number of observations */
 };
 
index b077aad..707c89e 100644 (file)
@@ -86,7 +86,7 @@ swcr_encdec(struct cryptodesc *crd, struct swcr_data *sw, caddr_t buf,
                if (crd->crd_flags & CRD_F_IV_EXPLICIT)
                        bcopy(crd->crd_iv, iv, blks);
                else
-                       arc4rand(iv, blks, 0);
+                       karc4rand(iv, blks);
 
                /* Do we need to write the IV */
                if (!(crd->crd_flags & CRD_F_IV_PRESENT))
@@ -443,7 +443,7 @@ swcr_authprepare(struct auth_hash *axf, struct swcr_data *sw, u_char *key,
                break;
        }
        default:
-               printf("%s: CRD_F_KEY_EXPLICIT flag given, but algorithm %d "
+               kprintf("%s: CRD_F_KEY_EXPLICIT flag given, but algorithm %d "
                    "doesn't use keys.\n", __func__, axf->type);
        }
 }
@@ -880,7 +880,8 @@ swcr_freesession(device_t dev, u_int64_t tid)
                        break;
                }
 
-               FREE(swd, M_CRYPTO_DATA);
+               //FREE(swd, M_CRYPTO_DATA);
+               kfree(swd, M_CRYPTO_DATA);
        }
        return 0;
 }
@@ -987,8 +988,9 @@ static void
 swcr_identify(driver_t *drv, device_t parent)
 {
        /* NB: order 10 is so we get attached after h/w devices */
+       /* XXX: wouldn't bet about this BUS_ADD_CHILD correctness */
        if (device_find_child(parent, "cryptosoft", -1) == NULL &&
-           BUS_ADD_CHILD(parent, 10, "cryptosoft", -1) == 0)
+           BUS_ADD_CHILD(parent, parent, 10, "cryptosoft", -1) == 0)
                panic("cryptosoft: could not attach");
 }
 
@@ -1043,7 +1045,7 @@ swcr_detach(device_t dev)
 {
        crypto_unregister_all(swcr_id);
        if (swcr_sessions != NULL)
-               free(swcr_sessions, M_CRYPTO_DATA);
+               kfree(swcr_sessions, M_CRYPTO_DATA);
        return 0;
 }
 
index be648e0..8a3de01 100644 (file)
@@ -311,7 +311,7 @@ des1_setkey(u_int8_t **sched, u_int8_t *key, int len)
        des_key_schedule *p;
        int err;
 
-       p = malloc(sizeof (des_key_schedule),
+       p = kmalloc(sizeof (des_key_schedule),
                M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
        if (p != NULL) {
                des_set_key((des_cblock *) key, p[0]);
@@ -354,7 +354,7 @@ des3_setkey(u_int8_t **sched, u_int8_t *key, int len)
        des_key_schedule *p;
        int err;
 
-       p = malloc(3*sizeof (des_key_schedule),
+       p = kmalloc(3*sizeof (des_key_schedule),
                M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
        if (p != NULL) {
                des_set_key((des_cblock *)(key +  0), p[0]);
@@ -410,7 +410,7 @@ blf_setkey(u_int8_t **sched, u_int8_t *key, int len)
 {
        int err;
 
-       *sched = malloc(sizeof(BF_KEY),
+       *sched = kmalloc(sizeof(BF_KEY),
                M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
        if (*sched != NULL) {
                BF_set_key((BF_KEY *) *sched, len, key);
@@ -445,7 +445,7 @@ cast5_setkey(u_int8_t **sched, u_int8_t *key, int len)
 {
        int err;
 
-       *sched = malloc(sizeof(cast_key), M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
+       *sched = kmalloc(sizeof(cast_key), M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
        if (*sched != NULL) {
                cast_setkey((cast_key *)*sched, key, len);
                err = 0;
@@ -480,7 +480,7 @@ skipjack_setkey(u_int8_t **sched, u_int8_t *key, int len)
        int err;
 
        /* NB: allocate all the memory that's needed at once */
-       *sched = malloc(10 * (sizeof(u_int8_t *) + 0x100),
+       *sched = kmalloc(10 * (sizeof(u_int8_t *) + 0x100),
                M_CRYPTO_DATA, M_NOWAIT|M_ZERO);
        if (*sched != NULL) {
                u_int8_t** key_tables = (u_int8_t**) *sched;
@@ -526,7 +526,7 @@ rijndael128_setkey(u_int8_t **sched, u_int8_t *key, int len)
 
        if (len != 16 && len != 24 && len != 32)
                return (EINVAL);
-       *sched = malloc(sizeof(rijndael_ctx), M_CRYPTO_DATA,
+       *sched = kmalloc(sizeof(rijndael_ctx), M_CRYPTO_DATA,
            M_NOWAIT|M_ZERO);
        if (*sched != NULL) {
                rijndael_set_key((rijndael_ctx *) *sched, (u_char *) key,
@@ -541,7 +541,7 @@ static void
 rijndael128_zerokey(u_int8_t **sched)
 {
        bzero(*sched, sizeof(rijndael_ctx));
-       free(*sched, M_CRYPTO_DATA);
+       kfree(*sched, M_CRYPTO_DATA);
        *sched = NULL;
 }
 
index d0f1a9b..8481424 100644 (file)
@@ -37,7 +37,7 @@ struct auth_hash {
        char *name;
        u_int16_t keysize;
        u_int16_t hashsize; 
-       u_int16_t authsize;
+       u_int16_t blocksize;
        u_int16_t ctxsize;
        void (*Init) (void *);
        int  (*Update) (void *, u_int8_t *, u_int16_t);
index 45d0531..93b6d89 100644 (file)
@@ -80,7 +80,6 @@ static void print_AMD_features(void);
 static void print_AMD_info(void);
 static void print_AMD_assoc(int i);
 static void print_transmeta_info(void);
-static void print_via_padlock_info(void);
 static void setup_tmx86_longrun(void);
 static void print_via_padlock_info(void);
 
@@ -723,8 +722,6 @@ printcpuinfo(void)
                                "\040<b31>"
                                );
                        }
-                       if (strcmp(cpu_vendor, "CentaurHauls") == 0)
-                               print_via_padlock_info();
 
                        if (strcmp(cpu_vendor, "CentaurHauls") == 0)
                                print_via_padlock_info();
@@ -1467,36 +1464,3 @@ additional_cpu_info(const char *line)
        }
 }
 
-static void
-print_via_padlock_info(void)
-{
-       u_int regs[4];
-
-       /* Check for supported models. */
-       switch (cpu_id & 0xff0) {
-       case 0x690:
-               if ((cpu_id & 0xf) < 3)
-                       return;
-       case 0x6a0:
-       case 0x6d0:
-       case 0x6f0:
-               break;
-       default:
-               return;
-       }
-
-       do_cpuid(0xc0000000, regs);
-       if (regs[0] >= 0xc0000001)
-               do_cpuid(0xc0000001, regs);
-       else
-               return;
-
-       kprintf("\n  VIA Padlock Features=0x%b", regs[3],
-       "\020"
-       "\003RNG"               /* RNG */
-       "\007AES"               /* ACE */
-       "\011AES-CTR"           /* ACE2 */
-       "\013SHA1,SHA256"       /* PHE */
-       "\015RSA"               /* PMM */
-       );
-}