Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/marvell Add Marvell CESA(Cryptographic Engines and S...



details:   https://anonhg.NetBSD.org/src/rev/3167a00ab4ab
branches:  trunk
changeset: 780481:3167a00ab4ab
user:      kiyohara <kiyohara%NetBSD.org@localhost>
date:      Fri Jul 27 03:00:01 2012 +0000

description:
Add Marvell CESA(Cryptographic Engines and Security Accelerator) module driver.
But support only PIO-mode now.  Also AES-CBC not supported.
 Don't know how to process to AES CBC in PIO-mode. I haven't found IV registers.

diffstat:

 sys/dev/marvell/files.discovery |    8 +-
 sys/dev/marvell/mvcesa.c        |  767 ++++++++++++++++++++++++++++++++++++++++
 sys/dev/marvell/mvcesareg.h     |  125 ++++++
 3 files changed, 896 insertions(+), 4 deletions(-)

diffs (truncated from 922 to 300 lines):

diff -r cec5c6481dfc -r 3167a00ab4ab sys/dev/marvell/files.discovery
--- a/sys/dev/marvell/files.discovery   Thu Jul 26 21:23:13 2012 +0000
+++ b/sys/dev/marvell/files.discovery   Fri Jul 27 03:00:01 2012 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.discovery,v 1.18 2010/10/02 05:53:37 kiyohara Exp $
+#      $NetBSD: files.discovery,v 1.19 2012/07/27 03:00:01 kiyohara Exp $
 #
 # Config file and device description for machine-independent support for
 # the Marvell (formerly Galileo Technology) Discovery system controllers.
@@ -72,9 +72,9 @@
 file   dev/marvell/ehci_mv.c           mvusb_gt | mvusb_mbus
 
 # Cryptographic Engines and Security Accelerator
-#device        mvcesa: opencrypto
-#file  dev/marvell/mvcesa.c            mvcesa
-#attach        mvcesa at gt with mvcesa_gt
+device mvcesa: opencrypto
+file   dev/marvell/mvcesa.c            mvcesa
+attach mvcesa at gt with mvcesa_gt
 
 # Two-Wire Serial Interface
 device gttwsi: i2cbus
diff -r cec5c6481dfc -r 3167a00ab4ab sys/dev/marvell/mvcesa.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/marvell/mvcesa.c  Fri Jul 27 03:00:01 2012 +0000
@@ -0,0 +1,767 @@
+/*     $NetBSD: mvcesa.c,v 1.1 2012/07/27 03:00:01 kiyohara Exp $      */
+/*
+ * Copyright (c) 2008 KIYOHARA Takashi
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: mvcesa.c,v 1.1 2012/07/27 03:00:01 kiyohara Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/cprng.h>
+#include <sys/device.h>
+#include <sys/endian.h>
+#include <sys/errno.h>
+#include <sys/mbuf.h>
+#include <sys/md5.h>
+#include <sys/uio.h>
+#include <sys/sha1.h>
+
+#include <opencrypto/cryptodev.h>
+#include <opencrypto/xform.h>
+
+#include <dev/marvell/marvellreg.h>
+#include <dev/marvell/marvellvar.h>
+#include <dev/marvell/mvcesareg.h>
+
+#include "locators.h"
+
+#define MVCESA_SESSION(sid)            ((sid) & 0x0fffffff)
+#define MVCESA_SID(crd, sesn)          (((crd) << 28) | ((sesn) & 0x0fffffff))
+
+
+struct mvcesa_session {
+       int ses_used;
+
+       int ses_klen;
+       uint32_t ses_iv[4];
+       uint32_t ses_key[8];
+
+       uint32_t ses_hminner[5];        /* HMAC inner state */
+       uint32_t ses_hmouter[5];        /* HMAC outer state */
+};
+
+struct mvcesa_softc {
+       device_t sc_dev;
+
+       bus_space_tag_t sc_iot;
+       bus_space_handle_t sc_ioh;
+       bus_dma_tag_t sc_dmat;
+
+       int sc_cid;
+       int sc_nsessions;
+       struct mvcesa_session *sc_sessions;
+};
+
+static int mvcesa_match(device_t, cfdata_t, void *);
+static void mvcesa_attach(device_t, device_t, void *);
+
+static int mvcesa_intr(void *);
+
+static int mvcesa_newsession(void *, u_int32_t *, struct cryptoini *);
+static int mvcesa_freesession(void *, u_int64_t);
+static int mvcesa_process(void *, struct cryptop *, int);
+
+static int mvcesa_authentication(struct mvcesa_softc *, struct mvcesa_session *,
+                                uint32_t, uint32_t *, uint32_t *, uint64_t,
+                                int, int, char *, struct mbuf *, struct uio *);
+static int mvcesa_des_encdec(struct mvcesa_softc *, struct mvcesa_session *,
+                            uint32_t, uint32_t, uint32_t, uint32_t *, int, int,
+                            char *, struct mbuf *, struct uio *);
+
+
+CFATTACH_DECL_NEW(mvcesa_gt, sizeof(struct mvcesa_softc),
+    mvcesa_match, mvcesa_attach, NULL, NULL);
+CFATTACH_DECL_NEW(mvcesa_mbus, sizeof(struct mvcesa_softc),
+    mvcesa_match, mvcesa_attach, NULL, NULL);
+
+
+/* ARGSUSED */
+static int
+mvcesa_match(device_t parent, cfdata_t match, void *aux)
+{
+       struct marvell_attach_args *mva = aux;
+
+       if (strcmp(mva->mva_name, match->cf_name) != 0)
+               return 0;
+       if (mva->mva_offset == MVA_OFFSET_DEFAULT ||
+           mva->mva_irq == MVA_IRQ_DEFAULT)
+               return 0;
+
+       mva->mva_size = MVCESA_SIZE;
+       return 1;
+}
+
+/* ARGSUSED */
+static void
+mvcesa_attach(device_t parent, device_t self, void *aux)
+{
+       struct mvcesa_softc *sc = device_private(self);
+       struct marvell_attach_args *mva = aux;
+
+       aprint_normal(
+           ": Marvell Cryptographic Engines and Security Accelerator\n");
+       aprint_naive("\n");
+
+       sc->sc_dev = self;
+       sc->sc_iot = mva->mva_iot;
+        /* Map I/O registers */
+       if (bus_space_subregion(mva->mva_iot, mva->mva_ioh, mva->mva_offset,
+           mva->mva_size, &sc->sc_ioh)) {
+               aprint_error_dev(self, "can't map registers\n");
+               return;
+       }
+       sc->sc_dmat = mva->mva_dmat;
+
+       sc->sc_nsessions = 0;
+
+       /* Setup Opencrypto stuff */
+       sc->sc_cid = crypto_get_driverid(0);
+       if (sc->sc_cid < 0) {
+               aprint_error_dev(self, "couldn't get crypto driver id\n");
+               return;
+       }
+       crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0,
+           mvcesa_newsession, mvcesa_freesession, mvcesa_process, sc);
+       crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0,
+           mvcesa_newsession, mvcesa_freesession, mvcesa_process, sc);
+#if __DMA_notyet__
+/*
+ * Don't know how to process to AES CBC in PIO-mode.
+ * I havn't found IV registers.
+ */
+       crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0,
+           mvcesa_newsession, mvcesa_freesession, mvcesa_process, sc);
+#endif
+       crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0,
+           mvcesa_newsession, mvcesa_freesession, mvcesa_process, sc);
+       crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0,
+           mvcesa_newsession, mvcesa_freesession, mvcesa_process, sc);
+       crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0,
+           mvcesa_newsession, mvcesa_freesession, mvcesa_process, sc);
+       crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0,
+           mvcesa_newsession, mvcesa_freesession, mvcesa_process, sc);
+
+       /* Clear and establish interrupt */
+       bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVCESA_IC, 0);
+       marvell_intr_establish(mva->mva_irq, IPL_NET, mvcesa_intr, sc);
+
+       bus_space_write_4(sc->sc_iot, sc->sc_ioh, MVCESA_IM, 0);
+}
+
+
+static int
+mvcesa_intr(void *arg)
+{
+#if 0
+       struct mvcesa_softc *sc = (struct mvcesa_softc *)arg;
+#endif
+       int handled = 0;
+
+       return handled;
+}
+
+
+/*
+ * Opencrypto functions
+ */
+/*
+ * Allocate a new 'session' and return an encoded session id.  'sidp'
+ * contains our registration id, and should contain an encoded session
+ * id on successful allocation.
+ */
+static int
+mvcesa_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
+{
+       struct mvcesa_softc *sc = (struct mvcesa_softc *)arg;
+       struct cryptoini *c;
+       struct mvcesa_session *ses = NULL;
+       int sesn, count, enc, mac, i;
+
+       KASSERT(sc != NULL /*, ("mvcesa_newsession: null softc")*/);
+       if (sidp == NULL || cri == NULL || sc == NULL)
+               return EINVAL;
+
+       for (sesn = 0; sesn < sc->sc_nsessions; sesn++)
+               if (sc->sc_sessions[sesn].ses_used == 0) {
+                       ses = sc->sc_sessions + sesn;
+                       break;
+               }
+
+       if (ses == NULL) {
+               sesn = sc->sc_nsessions;
+               ses = malloc((sesn + 1) * sizeof(*ses), M_DEVBUF, M_NOWAIT);
+               if (ses == NULL)
+                       return ENOMEM;
+               if (sesn != 0) {
+                       memcpy(ses, sc->sc_sessions, sesn * sizeof(*ses));
+                       memset(sc->sc_sessions, 0, sesn * sizeof(*ses));
+                       free(sc->sc_sessions, M_DEVBUF);
+               }
+               sc->sc_sessions = ses;
+               ses = sc->sc_sessions + sesn;
+               sc->sc_nsessions++;
+       }
+       memset(ses, 0, sizeof(*ses));
+
+       count = 0;
+       enc = mac = 0;
+       for (c = cri; c != NULL; c = c->cri_next) {
+               switch (c->cri_alg) {
+               case CRYPTO_DES_CBC:
+               case CRYPTO_3DES_CBC:
+                       if (enc)
+                               return EINVAL;
+                       enc = 1;
+
+                       cprng_fast(ses->ses_iv,
+                           c->cri_alg == CRYPTO_AES_CBC ? 16 : 8);
+
+                       /* Go ahead and compute key in CESA's byte order */
+                       ses->ses_klen = c->cri_klen;
+                       memcpy(ses->ses_key, c->cri_key, c->cri_klen / 8);
+                       switch (c->cri_alg) {
+                       case CRYPTO_3DES_CBC:
+                               ses->ses_key[5] = htobe32(ses->ses_key[5]);
+                               ses->ses_key[4] = htobe32(ses->ses_key[4]);
+                               ses->ses_key[3] = htobe32(ses->ses_key[3]);
+                               ses->ses_key[2] = htobe32(ses->ses_key[2]);
+
+                               /* FALLTHROUGH */
+                       case CRYPTO_DES_CBC:
+                               ses->ses_key[1] = htobe32(ses->ses_key[1]);
+                               ses->ses_key[0] = htobe32(ses->ses_key[0]);
+                       }
+                       break;
+
+               case CRYPTO_SHA1_HMAC:
+               case CRYPTO_MD5_HMAC:
+               {
+                       MD5_CTX md5ctx;
+                       SHA1_CTX sha1ctx;
+                       int klen_bytes = c->cri_klen / 8;
+
+                       KASSERT(c->cri_klen == 512);
+
+                       for (i = 0; i < klen_bytes; i++)
+                               c->cri_key[i] ^= HMAC_IPAD_VAL;
+                       if (c->cri_alg == CRYPTO_MD5_HMAC_96) {
+                               MD5Init(&md5ctx);
+                               MD5Update(&md5ctx, c->cri_key, klen_bytes);
+                               MD5Update(&md5ctx, hmac_ipad_buffer,
+                                   HMAC_BLOCK_LEN - klen_bytes);



Home | Main Index | Thread Index | Old Index