summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjchandra <jchandra@FreeBSD.org>2012-03-27 11:43:46 +0000
committerjchandra <jchandra@FreeBSD.org>2012-03-27 11:43:46 +0000
commitb1c8867097879270ea18f2d3acfbee47b9b426f7 (patch)
tree9fef9f0fc4ac0813da3e9660dc0f7a584b4ae11b
parent88cde25ec436fb0216f54a19541905c779f1614c (diff)
downloadFreeBSD-src-b1c8867097879270ea18f2d3acfbee47b9b426f7.zip
FreeBSD-src-b1c8867097879270ea18f2d3acfbee47b9b426f7.tar.gz
Opencrypto driver for XLP Security and RSA/ECC blocks
Support for the Security and RSA blocks on XLP SoC. Even though the XLP supports many more algorithms, only the ones supported in OCF have been added. Submitted by: Venkatesh J. V. (venkatesh at netlogicmicro com)
-rw-r--r--sys/mips/conf/std.XLP10
-rw-r--r--sys/mips/nlm/dev/sec/nlmrsa.c556
-rw-r--r--sys/mips/nlm/dev/sec/nlmrsalib.h68
-rw-r--r--sys/mips/nlm/dev/sec/nlmsec.c850
-rw-r--r--sys/mips/nlm/dev/sec/nlmseclib.c307
-rw-r--r--sys/mips/nlm/dev/sec/nlmseclib.h157
-rw-r--r--sys/mips/nlm/dev/sec/rsa_ucode.h956
-rw-r--r--sys/mips/nlm/files.xlp6
-rw-r--r--sys/mips/nlm/hal/iomap.h1
-rw-r--r--sys/mips/nlm/hal/nlmsaelib.h607
10 files changed, 3518 insertions, 0 deletions
diff --git a/sys/mips/conf/std.XLP b/sys/mips/conf/std.XLP
index e998734..2d867c2 100644
--- a/sys/mips/conf/std.XLP
+++ b/sys/mips/conf/std.XLP
@@ -95,3 +95,13 @@ device iic
device iicbus
device iicoc
device ds1374 # RTC on XLP boards
+
+# Crypto
+device crypto
+device cryptodev
+device nlmsec
+device nlmrsa
+
+# Options that use crypto
+options IPSEC
+options GEOM_ELI
diff --git a/sys/mips/nlm/dev/sec/nlmrsa.c b/sys/mips/nlm/dev/sec/nlmrsa.c
new file mode 100644
index 0000000..2438fdf
--- /dev/null
+++ b/sys/mips/nlm/dev/sec/nlmrsa.c
@@ -0,0 +1,556 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom 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.
+ * 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 BROADCOM ``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 BROADCOM 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/errno.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/mbuf.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/sysctl.h>
+#include <sys/bus.h>
+#include <sys/random.h>
+#include <sys/rman.h>
+#include <sys/uio.h>
+#include <sys/kobj.h>
+
+#include <dev/pci/pcivar.h>
+
+#include <opencrypto/cryptodev.h>
+
+#include "cryptodev_if.h"
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <mips/nlm/hal/haldefs.h>
+#include <mips/nlm/hal/iomap.h>
+#include <mips/nlm/xlp.h>
+#include <mips/nlm/hal/sys.h>
+#include <mips/nlm/hal/fmn.h>
+#include <mips/nlm/hal/nlmsaelib.h>
+#include <mips/nlm/dev/sec/nlmrsalib.h>
+#include <mips/nlm/dev/sec/rsa_ucode.h>
+#include <mips/nlm/hal/cop2.h>
+#include <mips/nlm/hal/mips-extns.h>
+#include <mips/nlm/msgring.h>
+
+#ifdef NLM_RSA_DEBUG
+int print_krp_params(struct cryptkop *krp);
+#endif
+
+static int xlp_rsa_init(struct xlp_rsa_softc *sc, int node);
+static int xlp_rsa_newsession(device_t , uint32_t *, struct cryptoini *);
+static int xlp_rsa_freesession(device_t , uint64_t);
+static int xlp_rsa_kprocess(device_t , struct cryptkop *, int);
+static int xlp_get_rsa_opsize(struct xlp_rsa_command *cmd, unsigned int bits);
+static void xlp_free_cmd_params(struct xlp_rsa_command *cmd);
+static int xlp_rsa_inp2hwformat(uint8_t *src, uint8_t *dst,
+ uint32_t paramsize, uint8_t result);
+
+static int xlp_rsa_probe(device_t);
+static int xlp_rsa_attach(device_t);
+static int xlp_rsa_detach(device_t);
+
+static device_method_t xlp_rsa_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, xlp_rsa_probe),
+ DEVMETHOD(device_attach, xlp_rsa_attach),
+ DEVMETHOD(device_detach, xlp_rsa_detach),
+
+ /* bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+
+ /* crypto device methods */
+ DEVMETHOD(cryptodev_newsession, xlp_rsa_newsession),
+ DEVMETHOD(cryptodev_freesession,xlp_rsa_freesession),
+ DEVMETHOD(cryptodev_kprocess, xlp_rsa_kprocess),
+
+ DEVMETHOD_END
+};
+
+static driver_t xlp_rsa_driver = {
+ "nlmrsa",
+ xlp_rsa_methods,
+ sizeof(struct xlp_rsa_softc)
+};
+static devclass_t xlp_rsa_devclass;
+
+DRIVER_MODULE(nlmrsa, pci, xlp_rsa_driver, xlp_rsa_devclass, 0, 0);
+MODULE_DEPEND(nlmrsa, crypto, 1, 1, 1);
+
+void
+nlm_xlprsaecc_msgring_handler(int vc, int size, int code, int src_id,
+ struct nlm_fmn_msg *msg, void *data);
+
+#ifdef NLM_RSA_DEBUG
+int
+print_krp_params(struct cryptkop *krp)
+{
+ int i;
+
+ printf("krp->krp_op :%d\n",krp->krp_op);
+ printf("krp->krp_status :%d\n",krp->krp_status);
+ printf("krp->krp_iparams:%d\n",krp->krp_iparams);
+ printf("krp->krp_oparams:%d\n",krp->krp_oparams);
+ for (i=0;i<krp->krp_iparams+krp->krp_oparams;i++) {
+ printf("krp->krp_param[%d].crp_p :0x%llx\n",i,
+ (unsigned long long)krp->krp_param[i].crp_p);
+ printf("krp->krp_param[%d].crp_nbits :%d\n",i,
+ krp->krp_param[i].crp_nbits);
+ printf("krp->krp_param[%d].crp_nbytes :%d\n",i,
+ (krp->krp_param[i].crp_nbits+7)/8);
+ }
+ return 0;
+}
+#endif
+
+static int
+xlp_rsa_init(struct xlp_rsa_softc *sc, int node)
+{
+ struct xlp_rsa_command *cmd = NULL;
+ uint32_t size, fbvc, dstvc, endsel, regval;
+ struct nlm_fmn_msg m;
+ int err, ret, i;
+ uint64_t base;
+
+ /* Register interrupt handler for the RSA/ECC CMS messages */
+ if (register_msgring_handler(sc->rsaecc_vc_start,
+ sc->rsaecc_vc_end, nlm_xlprsaecc_msgring_handler, sc) != 0) {
+ err = -1;
+ printf("Couldn't register rsa/ecc msgring handler\n");
+ goto errout;
+ }
+ m.msg[0] = m.msg[1] = m.msg[2] = m.msg[3] = 0;
+ fbvc = nlm_cpuid() / CMS_MAX_VCPU_VC;
+ /* Do the CMS credit initialization */
+ /* Currently it is configured by default to 50 when kernel comes up */
+
+ if ((cmd = malloc(sizeof(struct xlp_rsa_command), M_DEVBUF,
+ M_NOWAIT | M_ZERO)) == NULL) {
+ err = ENOMEM;
+ printf("Failed to allocate mem for cmd\n");
+ goto errout;
+ }
+ size = sizeof(nlm_rsa_ucode_data);
+ if ((cmd->rsasrc = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
+ err = ENOMEM;
+ printf("Failed to allocate mem for cmd->rsasrc\n");
+ goto errout;
+ }
+ if (((uintptr_t)cmd->rsasrc & (XLP_L2L3_CACHELINE_SIZE - 1))) {
+ err = EINVAL;
+ printf("cmd->rsasrc is not cacheline aligned\n");
+ goto errout;
+ }
+ memcpy(cmd->rsasrc, (uint8_t *)nlm_rsa_ucode_data, size);
+ m.msg[0] = nlm_crypto_form_rsa_ecc_fmn_entry0(1, 0x70, 0,
+ vtophys(cmd->rsasrc));
+ m.msg[1] = nlm_crypto_form_rsa_ecc_fmn_entry1(0, 1, fbvc,
+ vtophys(cmd->rsasrc));
+ /* Software scratch pad */
+ m.msg[2] = (uintptr_t)cmd;
+
+ for (dstvc = sc->rsaecc_vc_start; dstvc <= sc->rsaecc_vc_end; dstvc++) {
+ ret = nlm_fmn_msgsend(dstvc, 3, FMN_SWCODE_RSA, &m);
+ if (ret != 0) {
+ err = -1;
+ printf("%s: msgsnd failed (%x)\n", __func__, ret);
+ goto errout;
+ }
+ }
+ /* Configure so that all VCs send request to all RSA pipes */
+ base = nlm_get_rsa_regbase(node);
+ if (nlm_is_xlp3xx()) {
+ endsel = 1;
+ regval = 0xFFFF;
+ } else {
+ endsel = 3;
+ regval = 0x07FFFFFF;
+ }
+ for (i = 0; i < endsel; i++)
+ nlm_write_rsa_reg(base, RSA_ENG_SEL_0 + i, regval);
+ return (0);
+errout:
+ xlp_free_cmd_params(cmd);
+ return (err);
+}
+
+/* This function is called from an interrupt handler */
+void
+nlm_xlprsaecc_msgring_handler(int vc, int size, int code, int src_id,
+ struct nlm_fmn_msg *msg, void *data)
+{
+ struct xlp_rsa_command *cmd = NULL;
+ struct xlp_rsa_softc *sc = NULL;
+
+ KASSERT(code == FMN_SWCODE_RSA,
+ ("%s: bad code = %d, expected code = %d\n", __FUNCTION__, code,
+ FMN_SWCODE_RSA));
+
+ sc = (struct xlp_rsa_softc *)data;
+ KASSERT(src_id >= sc->rsaecc_vc_start && src_id <= sc->rsaecc_vc_end,
+ ("%s: bad src_id = %d, expect %d - %d\n", __FUNCTION__,
+ src_id, sc->rsaecc_vc_start, sc->rsaecc_vc_end));
+
+ cmd = (struct xlp_rsa_command *)(uintptr_t)msg->msg[1];
+ KASSERT(cmd != NULL, ("%s:cmd not received properly\n",
+ __FUNCTION__));
+
+ KASSERT(RSA_ERROR(msg->msg[0]) == 0,
+ ("%s: Message rcv msg0 %llx msg1 %llx err %x \n", __FUNCTION__,
+ (unsigned long long)msg->msg[0], (unsigned long long)msg->msg[1],
+ (int)RSA_ERROR(msg->msg[0])));
+
+ xlp_rsa_inp2hwformat(((uint8_t *)cmd->rsasrc+
+ (cmd->rsaopsize*cmd->krp->krp_iparams)),
+ cmd->krp->krp_param[cmd->krp->krp_iparams].crp_p,
+ ((cmd->krp->krp_param[cmd->krp->krp_iparams].crp_nbits+7)/8), 1);
+
+ if (cmd->krp != NULL)
+ crypto_kdone(cmd->krp);
+
+ xlp_free_cmd_params(cmd);
+
+ return;
+}
+
+static int
+xlp_rsa_probe(device_t dev)
+{
+ struct xlp_rsa_softc *sc;
+
+ if (pci_get_vendor(dev) == PCI_VENDOR_NETLOGIC &&
+ pci_get_device(dev) == PCI_DEVICE_ID_NLM_RSA) {
+ sc = device_get_softc(dev);
+ return (BUS_PROBE_DEFAULT);
+ }
+ return (ENXIO);
+}
+
+/*
+ * Attach an interface that successfully probed.
+ */
+static int
+xlp_rsa_attach(device_t dev)
+{
+ struct xlp_rsa_softc *sc = device_get_softc(dev);
+ uint64_t base;
+ int qstart, qnum;
+ int freq, node;
+
+ sc->sc_dev = dev;
+
+ node = nlm_get_device_node(pci_get_slot(dev));
+ freq = nlm_set_device_frequency(node, DFS_DEVICE_RSA, 250);
+ if (bootverbose)
+ device_printf(dev, "RSA Freq: %dMHz\n", freq);
+ if(pci_get_device(dev) == PCI_DEVICE_ID_NLM_RSA) {
+ device_set_desc(dev, "XLP RSA/ECC Accelerator");
+ if ((sc->sc_cid = crypto_get_driverid(dev,
+ CRYPTOCAP_F_HARDWARE)) < 0) {
+ printf("xlp_rsaecc-err:couldn't get the driver id\n");
+ goto error_exit;
+ }
+ if (crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0) != 0)
+ printf("register failed for CRK_MOD_EXP\n");
+
+ base = nlm_get_rsa_pcibase(node);
+ qstart = nlm_qidstart(base);
+ qnum = nlm_qnum(base);
+ sc->rsaecc_vc_start = qstart;
+ sc->rsaecc_vc_end = qstart + qnum - 1;
+ }
+ if (xlp_rsa_init(sc, node) != 0)
+ goto error_exit;
+ device_printf(dev, "RSA Initialization complete!\n");
+ return (0);
+
+error_exit:
+ return (ENXIO);
+
+}
+
+/*
+ * Detach an interface that successfully probed.
+ */
+static int
+xlp_rsa_detach(device_t dev)
+{
+ return (0);
+}
+
+/*
+ * 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
+xlp_rsa_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
+{
+ struct xlp_rsa_softc *sc = device_get_softc(dev);
+ int sesn;
+ struct xlp_rsa_session *ses = NULL;
+
+ if (sidp == NULL || cri == NULL || sc == NULL)
+ return (EINVAL);
+
+ if (sc->sc_sessions == NULL) {
+ ses = sc->sc_sessions = malloc(sizeof(struct xlp_rsa_session),
+ M_DEVBUF, M_NOWAIT);
+ if (ses == NULL)
+ return (ENOMEM);
+ sesn = 0;
+ sc->sc_nsessions = 1;
+ } else {
+ for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
+ if (!sc->sc_sessions[sesn].hs_used) {
+ ses = &sc->sc_sessions[sesn];
+ break;
+ }
+ }
+
+ if (ses == NULL) {
+ sesn = sc->sc_nsessions;
+ ses = malloc((sesn + 1)*sizeof(struct xlp_rsa_session),
+ M_DEVBUF, M_NOWAIT);
+ if (ses == NULL)
+ return (ENOMEM);
+ bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
+ bzero(sc->sc_sessions, sesn * sizeof(*ses));
+ free(sc->sc_sessions, M_DEVBUF);
+ sc->sc_sessions = ses;
+ ses = &sc->sc_sessions[sesn];
+ sc->sc_nsessions++;
+ }
+ }
+ bzero(ses, sizeof(*ses));
+ ses->sessionid = sesn;
+ ses->hs_used = 1;
+
+ *sidp = XLP_RSA_SID(device_get_unit(sc->sc_dev), sesn);
+ return (0);
+}
+
+/*
+ * Deallocate a session.
+ * XXX this routine should run a zero'd mac/encrypt key into context ram.
+ * XXX to blow away any keys already stored there.
+ */
+static int
+xlp_rsa_freesession(device_t dev, u_int64_t tid)
+{
+ struct xlp_rsa_softc *sc = device_get_softc(dev);
+ int session;
+ u_int32_t sid = CRYPTO_SESID2LID(tid);
+
+ if (sc == NULL)
+ return (EINVAL);
+
+ session = XLP_RSA_SESSION(sid);
+ if (session >= sc->sc_nsessions)
+ return (EINVAL);
+
+ sc->sc_sessions[session].hs_used = 0;
+ return (0);
+}
+
+static void
+xlp_free_cmd_params(struct xlp_rsa_command *cmd)
+{
+ if (cmd->rsasrc != NULL)
+ free(cmd->rsasrc, M_DEVBUF);
+ if (cmd != NULL)
+ free(cmd, M_DEVBUF);
+ return;
+}
+
+static int
+xlp_get_rsa_opsize(struct xlp_rsa_command *cmd, unsigned int bits)
+{
+ if (bits == 0)
+ return (-1);
+ /* XLP hardware expects always a fixed size with unused bytes
+ * zeroed out in the input data */
+ if (bits <= 512) {
+ cmd->rsatype = 0x40;
+ cmd->rsaopsize = (512/8);
+ return (0);
+ } else if ((bits > 512) && (bits <= 1024)) {
+ cmd->rsatype = 0x41;
+ cmd->rsaopsize = (1024/8);
+ return (0);
+ } else if ((bits > 1024) && (bits <= 2048)) {
+ cmd->rsatype = 0x42;
+ cmd->rsaopsize = (2048/8);
+ return (0);
+ } else if ((bits > 2048) && (bits <= 4096)) {
+ cmd->rsatype = 0x43;
+ cmd->rsaopsize = (4096/8);
+ return (0);
+ } else if ((bits > 4096) && (bits <= 8192)) {
+ cmd->rsatype = 0x44;
+ cmd->rsaopsize = (8192/8);
+ return (0);
+ } else {
+ return (-1);
+ }
+}
+
+static int
+xlp_rsa_inp2hwformat(uint8_t *src, uint8_t *dst, uint32_t paramsize,
+ uint8_t result)
+{
+ uint32_t pdwords, pbytes;
+ int i=0, j=0, k=0;
+
+ pdwords = (paramsize / 8);
+ pbytes = (paramsize % 8);
+
+ for (i = 0, k = 0; i < pdwords; i++) {
+ /* copy dwords of inp/hw to hw/out format */
+ for (j = 7; j >= 0; j--, k++)
+ dst[(i*8)+j] = src[k];
+ }
+ if (pbytes) {
+ if (!result) {
+ /* copy rem bytes of input data to hw format */
+ for (j = 7; k < paramsize; j--, k++)
+ dst[(i*8)+j] = src[k];
+ } else {
+ /* copy rem bytes of hw data to exp output format */
+ for (j = 7; k < paramsize; j--, k++)
+ dst[k] = src[(i*8)+j];
+ }
+ }
+
+ return (0);
+}
+
+static int
+nlm_crypto_complete_rsa_request(struct xlp_rsa_softc *sc,
+ struct xlp_rsa_command *cmd)
+{
+ unsigned int fbvc;
+ struct nlm_fmn_msg m;
+ int ret;
+
+ fbvc = nlm_cpuid() / CMS_MAX_VCPU_VC;
+ m.msg[0] = m.msg[1] = m.msg[2] = m.msg[3] = 0;
+
+ m.msg[0] = nlm_crypto_form_rsa_ecc_fmn_entry0(1, cmd->rsatype,
+ cmd->rsafn, vtophys(cmd->rsasrc));
+ m.msg[1] = nlm_crypto_form_rsa_ecc_fmn_entry1(0, 1, fbvc,
+ vtophys(cmd->rsasrc + (cmd->rsaopsize * cmd->krp->krp_iparams)));
+ /* Software scratch pad */
+ m.msg[2] = (uintptr_t)cmd;
+
+ /* Send the message to rsa engine vc */
+ ret = nlm_fmn_msgsend(sc->rsaecc_vc_start, 3, FMN_SWCODE_RSA, &m);
+ if (ret != 0) {
+#ifdef NLM_SEC_DEBUG
+ printf("%s: msgsnd failed (%x)\n", __func__, ret);
+#endif
+ return (ERESTART);
+ }
+ return (0);
+}
+
+static int
+xlp_rsa_kprocess(device_t dev, struct cryptkop *krp, int hint)
+{
+ struct xlp_rsa_softc *sc = device_get_softc(dev);
+ struct xlp_rsa_command *cmd = NULL;
+ int err = -1, i;
+
+ if (krp == NULL || krp->krp_callback == NULL)
+ return (EINVAL);
+
+ if ((cmd = malloc(sizeof(struct xlp_rsa_command), M_DEVBUF,
+ M_NOWAIT | M_ZERO)) == NULL) {
+ err = ENOMEM;
+ goto errout;
+ }
+ cmd->krp = krp;
+
+#ifdef NLM_RSA_DEBUG
+ print_krp_params(krp);
+#endif
+ switch (krp->krp_op) {
+ case CRK_MOD_EXP:
+ if (krp->krp_iparams == 3 && krp->krp_oparams == 1)
+ break;
+ goto errout;
+ default:
+ printf("Op:%d not yet supported\n", krp->krp_op);
+ goto errout;
+ }
+
+ if ((xlp_get_rsa_opsize(cmd,
+ krp->krp_param[krp->krp_iparams-1].crp_nbits)) != 0) {
+ err = EINVAL;
+ goto errout;
+ }
+ cmd->rsafn = 0; /* Mod Exp */
+ if ((cmd->rsasrc = malloc((cmd->rsaopsize *
+ (krp->krp_iparams+krp->krp_oparams)), M_DEVBUF,
+ M_NOWAIT | M_ZERO)) == NULL) {
+ err = ENOMEM;
+ goto errout;
+ }
+ if (((uintptr_t)cmd->rsasrc & (XLP_L2L3_CACHELINE_SIZE - 1))) {
+ err = EINVAL;
+ goto errout;
+ }
+
+ for (i=0;i<krp->krp_iparams;i++) {
+ KASSERT(krp->krp_param[i].crp_nbits != 0,
+ ("%s: parameter[%d]'s length is zero\n", __FUNCTION__, i));
+ xlp_rsa_inp2hwformat(krp->krp_param[i].crp_p,
+ ((uint8_t *)cmd->rsasrc+(i*cmd->rsaopsize)),
+ ((krp->krp_param[i].crp_nbits+7)/8), 0);
+ }
+ if (nlm_crypto_complete_rsa_request(sc, cmd) != 0)
+ goto errout;
+
+ return (0);
+errout:
+ xlp_free_cmd_params(cmd);
+ krp->krp_status = err;
+ crypto_kdone(krp);
+ return (err);
+}
diff --git a/sys/mips/nlm/dev/sec/nlmrsalib.h b/sys/mips/nlm/dev/sec/nlmrsalib.h
new file mode 100644
index 0000000..24c42e1
--- /dev/null
+++ b/sys/mips/nlm/dev/sec/nlmrsalib.h
@@ -0,0 +1,68 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom 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.
+ * 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 BROADCOM ``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 BROADCOM 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$
+ */
+#ifndef _NLMRSALIB_H_
+#define _NLMRSALIB_H_
+
+#define XLP_RSA_SESSION(sid) ((sid) & 0x000007ff)
+#define XLP_RSA_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff))
+
+#define NUM_RSAECC_VC 9
+
+#define RSA_ERROR(__msg0) ((__msg0 >> 53) & 0x1f)
+
+struct xlp_rsa_session {
+ uint32_t sessionid;
+ int hs_used;
+};
+
+struct xlp_rsa_command {
+ uint16_t session_num;
+ struct xlp_rsa_session *ses;
+ struct cryptkop *krp;
+ uint8_t *rsasrc;
+ uint32_t rsaopsize;
+ uint32_t rsatype;
+ uint32_t rsafn;
+};
+
+/*
+ * Holds data specific to nlm security accelerators
+ */
+struct xlp_rsa_softc {
+ device_t sc_dev; /* device backpointer */
+ uint64_t rsa_base;
+ int sc_cid;
+ struct xlp_rsa_session *sc_sessions;
+ int sc_nsessions;
+ int rsaecc_vc_start;
+ int rsaecc_vc_end;
+};
+
+#endif /* _NLMRSALIB_H_ */
diff --git a/sys/mips/nlm/dev/sec/nlmsec.c b/sys/mips/nlm/dev/sec/nlmsec.c
new file mode 100644
index 0000000..4c95661
--- /dev/null
+++ b/sys/mips/nlm/dev/sec/nlmsec.c
@@ -0,0 +1,850 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom 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.
+ * 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 BROADCOM ``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 BROADCOM 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/errno.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/mbuf.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/sysctl.h>
+#include <sys/bus.h>
+#include <sys/random.h>
+#include <sys/rman.h>
+#include <sys/uio.h>
+#include <sys/kobj.h>
+
+#include <dev/pci/pcivar.h>
+
+#include <opencrypto/cryptodev.h>
+
+#include "cryptodev_if.h"
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <mips/nlm/hal/haldefs.h>
+#include <mips/nlm/hal/iomap.h>
+#include <mips/nlm/xlp.h>
+#include <mips/nlm/hal/sys.h>
+#include <mips/nlm/hal/fmn.h>
+#include <mips/nlm/hal/nlmsaelib.h>
+#include <mips/nlm/dev/sec/nlmseclib.h>
+#include <mips/nlm/hal/cop2.h>
+#include <mips/nlm/hal/mips-extns.h>
+#include <mips/nlm/msgring.h>
+
+unsigned int creditleft;
+
+void xlp_sec_print_data(struct cryptop *crp);
+
+static int xlp_sec_init(struct xlp_sec_softc *sc);
+static int xlp_sec_newsession(device_t , uint32_t *, struct cryptoini *);
+static int xlp_sec_freesession(device_t , uint64_t);
+static int xlp_sec_process(device_t , struct cryptop *, int);
+static int xlp_copyiv(struct xlp_sec_softc *, struct xlp_sec_command *,
+ struct cryptodesc *enccrd);
+static int xlp_get_nsegs(struct cryptop *, unsigned int *);
+static int xlp_alloc_cmd_params(struct xlp_sec_command *, unsigned int);
+static void xlp_free_cmd_params(struct xlp_sec_command *);
+
+static int xlp_sec_probe(device_t);
+static int xlp_sec_attach(device_t);
+static int xlp_sec_detach(device_t);
+
+static device_method_t xlp_sec_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, xlp_sec_probe),
+ DEVMETHOD(device_attach, xlp_sec_attach),
+ DEVMETHOD(device_detach, xlp_sec_detach),
+
+ /* bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+
+ /* crypto device methods */
+ DEVMETHOD(cryptodev_newsession, xlp_sec_newsession),
+ DEVMETHOD(cryptodev_freesession,xlp_sec_freesession),
+ DEVMETHOD(cryptodev_process, xlp_sec_process),
+
+ DEVMETHOD_END
+};
+
+static driver_t xlp_sec_driver = {
+ "nlmsec",
+ xlp_sec_methods,
+ sizeof(struct xlp_sec_softc)
+};
+static devclass_t xlp_sec_devclass;
+
+DRIVER_MODULE(nlmsec, pci, xlp_sec_driver, xlp_sec_devclass, 0, 0);
+MODULE_DEPEND(nlmsec, crypto, 1, 1, 1);
+
+void
+nlm_xlpsec_msgring_handler(int vc, int size, int code, int src_id,
+ struct nlm_fmn_msg *msg, void *data);
+
+#ifdef NLM_SEC_DEBUG
+
+#define extract_bits(x, bitshift, bitcnt) \
+ (((unsigned long long)x >> bitshift) & ((1ULL << bitcnt) - 1))
+
+void
+print_crypto_params(struct xlp_sec_command *cmd, struct nlm_fmn_msg m)
+{
+ unsigned long long msg0,msg1,msg2,msg3,msg4,msg5,msg6,msg7,msg8;
+
+ msg0 = cmd->ctrlp->desc0;
+ msg1 = cmd->paramp->desc0;
+ msg2 = cmd->paramp->desc1;
+ msg3 = cmd->paramp->desc2;
+ msg4 = cmd->paramp->desc3;
+ msg5 = cmd->paramp->segment[0][0];
+ msg6 = cmd->paramp->segment[0][1];
+ msg7 = m.msg[0];
+ msg8 = m.msg[1];
+
+ printf("msg0 %llx msg1 %llx msg2 %llx msg3 %llx msg4 %llx msg5 %llx"
+ "msg6 %llx msg7 %llx msg8 %llx\n", msg0, msg1, msg2, msg3, msg4,
+ msg5, msg6, msg7, msg8);
+
+ printf("c0: hmac %d htype %d hmode %d ctype %d cmode %d arc4 %x\n",
+ (unsigned int)extract_bits(msg0, 61, 1),
+ (unsigned int)extract_bits(msg0, 52, 8),
+ (unsigned int)extract_bits(msg0, 43, 8),
+ (unsigned int)extract_bits(msg0, 34, 8),
+ (unsigned int)extract_bits(msg0, 25, 8),
+ (unsigned int)extract_bits(msg0, 0, 23));
+
+ printf("p0: tls %d hsrc %d hl3 %d enc %d ivl %d hd %llx\n",
+ (unsigned int)extract_bits(msg1, 63, 1),
+ (unsigned int)extract_bits(msg1,62,1),
+ (unsigned int)extract_bits(msg1,60,1),
+ (unsigned int)extract_bits(msg1,59,1),
+ (unsigned int)extract_bits(msg1,41,16), extract_bits(msg1,0,40));
+
+ printf("p1: clen %u hl %u\n", (unsigned int)extract_bits(msg2, 32, 32),
+ (unsigned int)extract_bits(msg2,0,32));
+
+ printf("p2: ivoff %d cbit %d coff %d hbit %d hclb %d hoff %d\n",
+ (unsigned int)extract_bits(msg3, 45, 17),
+ (unsigned int)extract_bits(msg3, 42,3),
+ (unsigned int)extract_bits(msg3, 22,16),
+ (unsigned int)extract_bits(msg3, 19,3),
+ (unsigned int)extract_bits(msg3, 18,1),
+ (unsigned int)extract_bits(msg3, 0, 16));
+
+ printf("p3: desfbid %d tlen %d arc4 %x hmacpad %d\n",
+ (unsigned int)extract_bits(msg4, 48,16),
+ (unsigned int)extract_bits(msg4,11,16),
+ (unsigned int)extract_bits(msg4,6,3),
+ (unsigned int)extract_bits(msg4,5,1));
+
+ printf("p4: sflen %d sddr %llx \n",
+ (unsigned int)extract_bits(msg5, 48, 16),extract_bits(msg5, 0, 40));
+
+ printf("p5: dflen %d cl3 %d cclob %d cdest %llx \n",
+ (unsigned int)extract_bits(msg6, 48, 16),
+ (unsigned int)extract_bits(msg6, 46, 1),
+ (unsigned int)extract_bits(msg6, 41, 1), extract_bits(msg6, 0, 40));
+
+ printf("fmn0: fbid %d dfrlen %d dfrv %d cklen %d cdescaddr %llx\n",
+ (unsigned int)extract_bits(msg7, 48, 16),
+ (unsigned int)extract_bits(msg7,46,2),
+ (unsigned int)extract_bits(msg7,45,1),
+ (unsigned int)extract_bits(msg7,40,5),
+ (extract_bits(msg7,0,34)<< 6));
+
+ printf("fmn1: arc4 %d hklen %d pdesclen %d pktdescad %llx\n",
+ (unsigned int)extract_bits(msg8, 63, 1),
+ (unsigned int)extract_bits(msg8,56,5),
+ (unsigned int)extract_bits(msg8,43,12),
+ (extract_bits(msg8,0,34) << 6));
+
+ return;
+}
+
+void
+xlp_sec_print_data(struct cryptop *crp)
+{
+ int i, key_len;
+ struct cryptodesc *crp_desc;
+
+ printf("session id = 0x%llx, crp_ilen = %d, crp_olen=%d \n",
+ crp->crp_sid, crp->crp_ilen, crp->crp_olen);
+
+ printf("crp_flags = 0x%x\n", crp->crp_flags);
+
+ printf("crp buf:\n");
+ for (i = 0; i < crp->crp_ilen; i++) {
+ printf("%c ", crp->crp_buf[i]);
+ if (i % 10 == 0)
+ printf("\n");
+ }
+
+ printf("\n");
+ printf("****************** desc ****************\n");
+ crp_desc = crp->crp_desc;
+ printf("crd_skip=%d, crd_len=%d, crd_flags=0x%x, crd_alg=%d\n",
+ crp_desc->crd_skip, crp_desc->crd_len, crp_desc->crd_flags,
+ crp_desc->crd_alg);
+
+ key_len = crp_desc->crd_klen / 8;
+ printf("key(%d) :\n", key_len);
+ for (i = 0; i < key_len; i++)
+ printf("%d", crp_desc->crd_key[i]);
+ printf("\n");
+
+ printf(" IV : \n");
+ for (i = 0; i < EALG_MAX_BLOCK_LEN; i++)
+ printf("%d", crp_desc->crd_iv[i]);
+ printf("\n");
+
+ printf("crd_next=%p\n", crp_desc->crd_next);
+ return;
+}
+
+void
+print_cmd(struct xlp_sec_command *cmd)
+{
+ printf("session_num :%d\n",cmd->session_num);
+ printf("crp :0x%x\n",(uint32_t)cmd->crp);
+ printf("enccrd :0x%x\n",(uint32_t)cmd->enccrd);
+ printf("maccrd :0x%x\n",(uint32_t)cmd->maccrd);
+ printf("ses :%d\n",(uint32_t)cmd->ses);
+ printf("ctrlp :0x%x\n",(uint32_t)cmd->ctrlp);
+ printf("paramp :0x%x\n",(uint32_t)cmd->paramp);
+ printf("hashdest :0x%x\n",(uint32_t)cmd->hashdest);
+ printf("hashsrc :%d\n",cmd->hashsrc);
+ printf("hmacpad :%d\n",cmd->hmacpad);
+ printf("hashoff :%d\n",cmd->hashoff);
+ printf("hashlen :%d\n",cmd->hashlen);
+ printf("cipheroff :%d\n",cmd->cipheroff);
+ printf("cipherlen :%d\n",cmd->cipherlen);
+ printf("ivoff :%d\n",cmd->ivoff);
+ printf("ivlen :%d\n",cmd->ivlen);
+ printf("hashalg :%d\n",cmd->hashalg);
+ printf("hashmode :%d\n",cmd->hashmode);
+ printf("cipheralg :%d\n",cmd->cipheralg);
+ printf("ciphermode :%d\n",cmd->ciphermode);
+ printf("nsegs :%d\n",cmd->nsegs);
+ printf("hash_dst_len :%d\n",cmd->hash_dst_len);
+}
+#endif /* NLM_SEC_DEBUG */
+
+static int
+xlp_sec_init(struct xlp_sec_softc *sc)
+{
+
+ /* Register interrupt handler for the SEC CMS messages */
+ if (register_msgring_handler(sc->sec_vc_start,
+ sc->sec_vc_end, nlm_xlpsec_msgring_handler, sc) != 0) {
+ printf("Couldn't register sec msgring handler\n");
+ return (-1);
+ }
+
+ /* Do the CMS credit initialization */
+ /* Currently it is configured by default to 50 when kernel comes up */
+
+ return (0);
+}
+
+/* This function is called from an interrupt handler */
+void
+nlm_xlpsec_msgring_handler(int vc, int size, int code, int src_id,
+ struct nlm_fmn_msg *msg, void *data)
+{
+ struct xlp_sec_command *cmd = NULL;
+ struct xlp_sec_softc *sc = NULL;
+ struct cryptodesc *crd = NULL;
+ unsigned int ivlen = 0;
+
+ KASSERT(code == FMN_SWCODE_CRYPTO,
+ ("%s: bad code = %d, expected code = %d\n", __FUNCTION__,
+ code, FMN_SWCODE_CRYPTO));
+
+ sc = (struct xlp_sec_softc *)data;
+ KASSERT(src_id >= sc->sec_vc_start && src_id <= sc->sec_vc_end,
+ ("%s: bad src_id = %d, expect %d - %d\n", __FUNCTION__,
+ src_id, sc->sec_vc_start, sc->sec_vc_end));
+
+ cmd = (struct xlp_sec_command *)(uintptr_t)msg->msg[0];
+ KASSERT(cmd != NULL && cmd->crp != NULL,
+ ("%s :cmd not received properly\n",__FUNCTION__));
+
+ KASSERT(CRYPTO_ERROR(msg->msg[1]) == 0,
+ ("%s: Message rcv msg0 %llx msg1 %llx err %x \n", __FUNCTION__,
+ (unsigned long long)msg->msg[0], (unsigned long long)msg->msg[1],
+ (int)CRYPTO_ERROR(msg->msg[1])));
+
+ crd = cmd->enccrd;
+ /* Copy the last 8 or 16 bytes to the session iv, so that in few
+ * cases this will be used as IV for the next request
+ */
+ if (crd != NULL) {
+ if ((crd->crd_alg == CRYPTO_DES_CBC ||
+ crd->crd_alg == CRYPTO_3DES_CBC ||
+ crd->crd_alg == CRYPTO_AES_CBC) &&
+ (crd->crd_flags & CRD_F_ENCRYPT)) {
+ ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ?
+ XLP_SEC_AES_IV_LENGTH : XLP_SEC_DES_IV_LENGTH);
+ crypto_copydata(cmd->crp->crp_flags, cmd->crp->crp_buf,
+ crd->crd_skip + crd->crd_len - ivlen, ivlen,
+ sc->sc_sessions[cmd->session_num].ses_iv);
+ }
+ }
+
+ /* If there are not enough credits to send, then send request
+ * will fail with ERESTART and the driver will be blocked until it is
+ * unblocked here after knowing that there are sufficient credits to
+ * send the request again.
+ */
+ if (sc->sc_needwakeup) {
+ atomic_add_int(&creditleft, sc->sec_msgsz);
+ if (creditleft >= (NLM_CRYPTO_LEFT_REQS)) {
+ crypto_unblock(sc->sc_cid, sc->sc_needwakeup);
+ sc->sc_needwakeup &= (~(CRYPTO_SYMQ | CRYPTO_ASYMQ));
+ }
+ }
+ if(cmd->maccrd) {
+ crypto_copyback(cmd->crp->crp_flags,
+ cmd->crp->crp_buf, cmd->maccrd->crd_inject,
+ cmd->hash_dst_len, cmd->hashdest);
+ }
+
+ /* This indicates completion of the crypto operation */
+ crypto_done(cmd->crp);
+
+ xlp_free_cmd_params(cmd);
+
+ return;
+}
+
+static int
+xlp_sec_probe(device_t dev)
+{
+ struct xlp_sec_softc *sc;
+
+ if (pci_get_vendor(dev) == PCI_VENDOR_NETLOGIC &&
+ pci_get_device(dev) == PCI_DEVICE_ID_NLM_SAE) {
+ sc = device_get_softc(dev);
+ return (BUS_PROBE_DEFAULT);
+ }
+ return (ENXIO);
+}
+
+/*
+ * Attach an interface that successfully probed.
+ */
+static int
+xlp_sec_attach(device_t dev)
+{
+ struct xlp_sec_softc *sc = device_get_softc(dev);
+ uint64_t base;
+ int qstart, qnum;
+ int freq, node;
+
+ sc->sc_dev = dev;
+
+ node = nlm_get_device_node(pci_get_slot(dev));
+ freq = nlm_set_device_frequency(node, DFS_DEVICE_SAE, 250);
+ if (bootverbose)
+ device_printf(dev, "SAE Freq: %dMHz\n", freq);
+ if(pci_get_device(dev) == PCI_DEVICE_ID_NLM_SAE) {
+ device_set_desc(dev, "XLP Security Accelerator");
+ sc->sc_cid = crypto_get_driverid(dev, CRYPTOCAP_F_HARDWARE);
+ if (sc->sc_cid < 0) {
+ printf("xlp_sec - error : could not get the driver"
+ " id\n");
+ goto error_exit;
+ }
+ if (crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0) != 0)
+ printf("register failed for CRYPTO_DES_CBC\n");
+
+ if (crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0) != 0)
+ printf("register failed for CRYPTO_3DES_CBC\n");
+
+ if (crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0) != 0)
+ printf("register failed for CRYPTO_AES_CBC\n");
+
+ if (crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0) != 0)
+ printf("register failed for CRYPTO_ARC4\n");
+
+ if (crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0) != 0)
+ printf("register failed for CRYPTO_MD5\n");
+
+ if (crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0) != 0)
+ printf("register failed for CRYPTO_SHA1\n");
+
+ if (crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0) != 0)
+ printf("register failed for CRYPTO_MD5_HMAC\n");
+
+ if (crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0) != 0)
+ printf("register failed for CRYPTO_SHA1_HMAC\n");
+
+ base = nlm_get_sec_pcibase(node);
+ qstart = nlm_qidstart(base);
+ qnum = nlm_qnum(base);
+ sc->sec_vc_start = qstart;
+ sc->sec_vc_end = qstart + qnum - 1;
+ }
+
+ if (xlp_sec_init(sc) != 0)
+ goto error_exit;
+ if (bootverbose)
+ device_printf(dev, "SEC Initialization complete!\n");
+ return (0);
+
+error_exit:
+ return (ENXIO);
+
+}
+
+/*
+ * Detach an interface that successfully probed.
+ */
+static int
+xlp_sec_detach(device_t dev)
+{
+ return (0);
+}
+
+/*
+ * 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
+xlp_sec_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
+{
+ struct cryptoini *c;
+ struct xlp_sec_softc *sc = device_get_softc(dev);
+ int mac = 0, cry = 0, sesn;
+ struct xlp_sec_session *ses = NULL;
+ struct xlp_sec_command *cmd = NULL;
+
+ if (sidp == NULL || cri == NULL || sc == NULL)
+ return (EINVAL);
+
+ if (sc->sc_sessions == NULL) {
+ ses = sc->sc_sessions = malloc(sizeof(struct xlp_sec_session),
+ M_DEVBUF, M_NOWAIT);
+ if (ses == NULL)
+ return (ENOMEM);
+ sesn = 0;
+ sc->sc_nsessions = 1;
+ } else {
+ for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
+ if (!sc->sc_sessions[sesn].hs_used) {
+ ses = &sc->sc_sessions[sesn];
+ break;
+ }
+ }
+
+ if (ses == NULL) {
+ sesn = sc->sc_nsessions;
+ ses = malloc((sesn + 1)*sizeof(struct xlp_sec_session),
+ M_DEVBUF, M_NOWAIT);
+ if (ses == NULL)
+ return (ENOMEM);
+ bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
+ bzero(sc->sc_sessions, sesn * sizeof(*ses));
+ free(sc->sc_sessions, M_DEVBUF);
+ sc->sc_sessions = ses;
+ ses = &sc->sc_sessions[sesn];
+ sc->sc_nsessions++;
+ }
+ }
+ bzero(ses, sizeof(*ses));
+ ses->sessionid = sesn;
+ cmd = &ses->cmd;
+ ses->hs_used = 1;
+
+ for (c = cri; c != NULL; c = c->cri_next) {
+ switch (c->cri_alg) {
+ case CRYPTO_MD5:
+ case CRYPTO_SHA1:
+ case CRYPTO_MD5_HMAC:
+ case CRYPTO_SHA1_HMAC:
+ if (mac)
+ return (EINVAL);
+ mac = 1;
+ 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;
+ }
+ }
+ break;
+ case CRYPTO_DES_CBC:
+ case CRYPTO_3DES_CBC:
+ case CRYPTO_AES_CBC:
+ /* XXX this may read fewer, does it matter? */
+ read_random(ses->ses_iv, c->cri_alg ==
+ CRYPTO_AES_CBC ? XLP_SEC_AES_IV_LENGTH :
+ XLP_SEC_DES_IV_LENGTH);
+ /* FALLTHROUGH */
+ case CRYPTO_ARC4:
+ if (cry)
+ return (EINVAL);
+ cry = 1;
+ break;
+ default:
+ return (EINVAL);
+ }
+ }
+ if (mac == 0 && cry == 0)
+ return (EINVAL);
+
+ cmd->hash_dst_len = ses->hs_mlen;
+ *sidp = XLP_SEC_SID(device_get_unit(sc->sc_dev), sesn);
+ return (0);
+}
+
+/*
+ * Deallocate a session.
+ * XXX this routine should run a zero'd mac/encrypt key into context ram.
+ * XXX to blow away any keys already stored there.
+ */
+static int
+xlp_sec_freesession(device_t dev, u_int64_t tid)
+{
+ struct xlp_sec_softc *sc = device_get_softc(dev);
+ int session;
+ u_int32_t sid = CRYPTO_SESID2LID(tid);
+
+ if (sc == NULL)
+ return (EINVAL);
+
+ session = XLP_SEC_SESSION(sid);
+ if (session >= sc->sc_nsessions)
+ return (EINVAL);
+
+ sc->sc_sessions[session].hs_used = 0;
+ return (0);
+}
+
+static int
+xlp_copyiv(struct xlp_sec_softc *sc, struct xlp_sec_command *cmd,
+ struct cryptodesc *enccrd)
+{
+ unsigned int ivlen = 0;
+ int session;
+ struct cryptop *crp = NULL;
+
+ crp = cmd->crp;
+ session = cmd->session_num;
+
+ if (enccrd->crd_alg != CRYPTO_ARC4) {
+ ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ?
+ XLP_SEC_AES_IV_LENGTH : XLP_SEC_DES_IV_LENGTH);
+ if (enccrd->crd_flags & CRD_F_ENCRYPT) {
+ if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
+ bcopy(enccrd->crd_iv, cmd->iv, ivlen);
+ } else {
+ bcopy(sc->sc_sessions[session].ses_iv, cmd->iv,
+ ivlen);
+ }
+ if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
+ crypto_copyback(crp->crp_flags,
+ crp->crp_buf, enccrd->crd_inject,
+ ivlen, cmd->iv);
+ }
+ } else {
+ if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
+ bcopy(enccrd->crd_iv, cmd->iv, ivlen);
+ } else {
+ crypto_copydata(crp->crp_flags, crp->crp_buf,
+ enccrd->crd_inject, ivlen, cmd->iv);
+ }
+ }
+ }
+ return (0);
+}
+
+static int
+xlp_get_nsegs(struct cryptop *crp, unsigned int *nsegs)
+{
+
+ if (crp->crp_flags & CRYPTO_F_IMBUF) {
+ struct mbuf *m = NULL;
+
+ m = (struct mbuf *)crp->crp_buf;
+ while (m != NULL) {
+ *nsegs += NLM_CRYPTO_NUM_SEGS_REQD(m->m_len);
+ m = m->m_next;
+ }
+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
+ struct uio *uio = NULL;
+ struct iovec *iov = NULL;
+ int iol = 0;
+
+ uio = (struct uio *)crp->crp_buf;
+ iov = (struct iovec *)uio->uio_iov;
+ iol = uio->uio_iovcnt;
+ while (iol > 0) {
+ *nsegs += NLM_CRYPTO_NUM_SEGS_REQD(iov->iov_len);
+ iol--;
+ iov++;
+ }
+ } else {
+ *nsegs = NLM_CRYPTO_NUM_SEGS_REQD(crp->crp_ilen);
+ }
+ return (0);
+}
+
+static int
+xlp_alloc_cmd_params(struct xlp_sec_command *cmd, unsigned int nsegs)
+{
+ int err = 0;
+
+ if(cmd == NULL) {
+ err = EINVAL;
+ goto error;
+ }
+ if ((cmd->ctrlp = malloc(sizeof(struct nlm_crypto_pkt_ctrl), M_DEVBUF,
+ M_NOWAIT | M_ZERO)) == NULL) {
+ err = ENOMEM;
+ goto error;
+ }
+ if (((uintptr_t)cmd->ctrlp & (XLP_L2L3_CACHELINE_SIZE - 1))) {
+ err = EINVAL;
+ goto error;
+ }
+ /* (nsegs - 1) because one seg is part of the structure already */
+ if ((cmd->paramp = malloc(sizeof(struct nlm_crypto_pkt_param) +
+ (16 * (nsegs - 1)), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
+ err = ENOMEM;
+ goto error;
+ }
+ if (((uintptr_t)cmd->paramp & (XLP_L2L3_CACHELINE_SIZE - 1))) {
+ err = EINVAL;
+ goto error;
+ }
+ if ((cmd->iv = malloc(EALG_MAX_BLOCK_LEN, M_DEVBUF,
+ M_NOWAIT | M_ZERO)) == NULL) {
+ err = ENOMEM;
+ goto error;
+ }
+ if ((cmd->hashdest = malloc(HASH_MAX_LEN, M_DEVBUF,
+ M_NOWAIT | M_ZERO)) == NULL) {
+ err = ENOMEM;
+ goto error;
+ }
+error:
+ return (err);
+}
+
+static void
+xlp_free_cmd_params(struct xlp_sec_command *cmd)
+{
+ if (cmd->ctrlp != NULL)
+ free(cmd->ctrlp, M_DEVBUF);
+ if (cmd->paramp != NULL)
+ free(cmd->paramp, M_DEVBUF);
+ if (cmd->iv != NULL)
+ free(cmd->iv, M_DEVBUF);
+ if (cmd->hashdest != NULL)
+ free(cmd->hashdest, M_DEVBUF);
+ if (cmd != NULL)
+ free(cmd, M_DEVBUF);
+ return;
+}
+
+static int
+xlp_sec_process(device_t dev, struct cryptop *crp, int hint)
+{
+ struct xlp_sec_softc *sc = device_get_softc(dev);
+ struct xlp_sec_command *cmd = NULL;
+ int session, err = -1, ret = 0;
+ struct cryptodesc *crd1, *crd2;
+ struct xlp_sec_session *ses;
+ unsigned int nsegs = 0;
+
+ if (crp == NULL || crp->crp_callback == NULL) {
+ return (EINVAL);
+ }
+ session = XLP_SEC_SESSION(crp->crp_sid);
+ if (sc == NULL || session >= sc->sc_nsessions) {
+ err = EINVAL;
+ goto errout;
+ }
+ ses = &sc->sc_sessions[session];
+
+ if ((cmd = malloc(sizeof(struct xlp_sec_command), M_DEVBUF,
+ M_NOWAIT | M_ZERO)) == NULL) {
+ err = ENOMEM;
+ goto errout;
+ }
+
+ cmd->crp = crp;
+ cmd->session_num = session;
+ cmd->hash_dst_len = ses->hs_mlen;
+
+ if ((crd1 = crp->crp_desc) == NULL) {
+ err = EINVAL;
+ goto errout;
+ }
+ crd2 = crd1->crd_next;
+
+ if ((ret = xlp_get_nsegs(crp, &nsegs)) != 0) {
+ err = EINVAL;
+ goto errout;
+ }
+ if (((crd1 != NULL) && (crd1->crd_flags & CRD_F_IV_EXPLICIT)) ||
+ ((crd2 != NULL) && (crd2->crd_flags & CRD_F_IV_EXPLICIT))) {
+ /* Since IV is given as separate segment to avoid copy */
+ nsegs += 1;
+ }
+ cmd->nsegs = nsegs;
+
+ if ((err = xlp_alloc_cmd_params(cmd, nsegs)) != 0)
+ goto errout;
+
+ if ((crd1 != NULL) && (crd2 == NULL)) {
+ if (crd1->crd_alg == CRYPTO_DES_CBC ||
+ crd1->crd_alg == CRYPTO_3DES_CBC ||
+ crd1->crd_alg == CRYPTO_AES_CBC ||
+ crd1->crd_alg == CRYPTO_ARC4) {
+ cmd->enccrd = crd1;
+ cmd->maccrd = NULL;
+ if ((ret = nlm_get_cipher_param(cmd)) != 0) {
+ err = EINVAL;
+ goto errout;
+ }
+ if (crd1->crd_flags & CRD_F_IV_EXPLICIT)
+ cmd->cipheroff = cmd->ivlen;
+ else
+ cmd->cipheroff = cmd->enccrd->crd_skip;
+ cmd->cipherlen = cmd->enccrd->crd_len;
+ if (crd1->crd_flags & CRD_F_IV_PRESENT)
+ cmd->ivoff = 0;
+ else
+ cmd->ivoff = cmd->enccrd->crd_inject;
+ if ((err = xlp_copyiv(sc, cmd, cmd->enccrd)) != 0)
+ goto errout;
+ if ((err = nlm_crypto_do_cipher(sc, cmd)) != 0)
+ goto errout;
+ } else if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
+ crd1->crd_alg == CRYPTO_SHA1_HMAC ||
+ crd1->crd_alg == CRYPTO_SHA1 ||
+ crd1->crd_alg == CRYPTO_MD5) {
+ cmd->enccrd = NULL;
+ cmd->maccrd = crd1;
+ if ((ret = nlm_get_digest_param(cmd)) != 0) {
+ err = EINVAL;
+ goto errout;
+ }
+ cmd->hashoff = cmd->maccrd->crd_skip;
+ cmd->hashlen = cmd->maccrd->crd_len;
+ cmd->hmacpad = 0;
+ cmd->hashsrc = 0;
+ if ((err = nlm_crypto_do_digest(sc, cmd)) != 0)
+ goto errout;
+ } else {
+ err = EINVAL;
+ goto errout;
+ }
+ } else if( (crd1 != NULL) && (crd2 != NULL) ) {
+ if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
+ crd1->crd_alg == CRYPTO_SHA1_HMAC ||
+ crd1->crd_alg == CRYPTO_MD5 ||
+ crd1->crd_alg == CRYPTO_SHA1) &&
+ (crd2->crd_alg == CRYPTO_DES_CBC ||
+ crd2->crd_alg == CRYPTO_3DES_CBC ||
+ crd2->crd_alg == CRYPTO_AES_CBC ||
+ crd2->crd_alg == CRYPTO_ARC4)) {
+ cmd->maccrd = crd1;
+ cmd->enccrd = crd2;
+ } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
+ crd1->crd_alg == CRYPTO_ARC4 ||
+ crd1->crd_alg == CRYPTO_3DES_CBC ||
+ crd1->crd_alg == CRYPTO_AES_CBC) &&
+ (crd2->crd_alg == CRYPTO_MD5_HMAC ||
+ crd2->crd_alg == CRYPTO_SHA1_HMAC ||
+ crd2->crd_alg == CRYPTO_MD5 ||
+ crd2->crd_alg == CRYPTO_SHA1)) {
+ cmd->enccrd = crd1;
+ cmd->maccrd = crd2;
+ } else {
+ err = EINVAL;
+ goto errout;
+ }
+ if ((ret = nlm_get_cipher_param(cmd)) != 0) {
+ err = EINVAL;
+ goto errout;
+ }
+ if ((ret = nlm_get_digest_param(cmd)) != 0) {
+ err = EINVAL;
+ goto errout;
+ }
+ cmd->ivoff = cmd->enccrd->crd_inject;
+ cmd->hashoff = cmd->maccrd->crd_skip;
+ cmd->hashlen = cmd->maccrd->crd_len;
+ cmd->hmacpad = 0;
+ if (cmd->enccrd->crd_flags & CRD_F_ENCRYPT)
+ cmd->hashsrc = 1;
+ else
+ cmd->hashsrc = 0;
+ cmd->cipheroff = cmd->enccrd->crd_skip;
+ cmd->cipherlen = cmd->enccrd->crd_len;
+ if ((err = xlp_copyiv(sc, cmd, cmd->enccrd)) != 0)
+ goto errout;
+ if ((err = nlm_crypto_do_cipher_digest(sc, cmd)) != 0)
+ goto errout;
+ } else {
+ err = EINVAL;
+ goto errout;
+ }
+ return (0);
+errout:
+ xlp_free_cmd_params(cmd);
+ if (err == ERESTART) {
+ sc->sc_needwakeup |= CRYPTO_SYMQ;
+ creditleft = 0;
+ return (err);
+ }
+ crp->crp_etype = err;
+ crypto_done(crp);
+ return (err);
+}
diff --git a/sys/mips/nlm/dev/sec/nlmseclib.c b/sys/mips/nlm/dev/sec/nlmseclib.c
new file mode 100644
index 0000000..8439260
--- /dev/null
+++ b/sys/mips/nlm/dev/sec/nlmseclib.c
@@ -0,0 +1,307 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom 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.
+ * 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 BROADCOM ``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 BROADCOM 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/bus.h>
+#include <sys/uio.h>
+#include <machine/bus.h>
+#include <machine/md_var.h>
+#include <machine/cpuregs.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#include <opencrypto/cryptodev.h>
+
+#include <mips/nlm/hal/haldefs.h>
+#include <mips/nlm/hal/cop2.h>
+#include <mips/nlm/hal/fmn.h>
+#include <mips/nlm/hal/mips-extns.h>
+#include <mips/nlm/hal/nlmsaelib.h>
+#include <mips/nlm/dev/sec/nlmseclib.h>
+
+static int
+nlm_crypto_complete_sec_request(struct xlp_sec_softc *sc,
+ struct xlp_sec_command *cmd)
+{
+ unsigned int fbvc;
+ struct nlm_fmn_msg m;
+ int ret;
+
+ fbvc = nlm_cpuid() / CMS_MAX_VCPU_VC;
+ m.msg[0] = m.msg[1] = m.msg[2] = m.msg[3] = 0;
+
+ m.msg[0] = nlm_crypto_form_pkt_fmn_entry0(fbvc, 0, 0,
+ cmd->ctrlp->cipherkeylen, vtophys(cmd->ctrlp));
+
+ m.msg[1] = nlm_crypto_form_pkt_fmn_entry1(0, cmd->ctrlp->hashkeylen,
+ NLM_CRYPTO_PKT_DESC_SIZE(cmd->nsegs), vtophys(cmd->paramp));
+
+ /* Software scratch pad */
+ m.msg[2] = (uintptr_t)cmd;
+ sc->sec_msgsz = 3;
+
+ /* Send the message to sec/rsa engine vc */
+ ret = nlm_fmn_msgsend(sc->sec_vc_start, sc->sec_msgsz,
+ FMN_SWCODE_CRYPTO, &m);
+ if (ret != 0) {
+#ifdef NLM_SEC_DEBUG
+ printf("%s: msgsnd failed (%x)\n", __func__, ret);
+#endif
+ return (ERESTART);
+ }
+ return (0);
+}
+
+int
+nlm_crypto_form_srcdst_segs(struct xlp_sec_command *cmd)
+{
+ unsigned int srcseg = 0, dstseg = 0;
+ struct cryptodesc *cipdesc = NULL;
+ struct cryptop *crp = NULL;
+
+ crp = cmd->crp;
+ cipdesc = cmd->enccrd;
+
+ if (cipdesc != NULL) {
+ /* IV is given as ONE segment to avoid copy */
+ if (cipdesc->crd_flags & CRD_F_IV_EXPLICIT) {
+ srcseg = nlm_crypto_fill_src_seg(cmd->paramp, srcseg,
+ cmd->iv, cmd->ivlen);
+ dstseg = nlm_crypto_fill_dst_seg(cmd->paramp, dstseg,
+ cmd->iv, cmd->ivlen);
+ }
+ }
+
+ if (crp->crp_flags & CRYPTO_F_IMBUF) {
+ struct mbuf *m = NULL;
+
+ m = (struct mbuf *)crp->crp_buf;
+ while (m != NULL) {
+ srcseg = nlm_crypto_fill_src_seg(cmd->paramp, srcseg,
+ mtod(m,caddr_t), m->m_len);
+ if (cipdesc != NULL) {
+ dstseg = nlm_crypto_fill_dst_seg(cmd->paramp,
+ dstseg, mtod(m,caddr_t), m->m_len);
+ }
+ m = m->m_next;
+ }
+ } else if (crp->crp_flags & CRYPTO_F_IOV) {
+ struct uio *uio = NULL;
+ struct iovec *iov = NULL;
+ int iol = 0;
+
+ uio = (struct uio *)crp->crp_buf;
+ iov = (struct iovec *)uio->uio_iov;
+ iol = uio->uio_iovcnt;
+
+ while (iol > 0) {
+ srcseg = nlm_crypto_fill_src_seg(cmd->paramp, srcseg,
+ (caddr_t)iov->iov_base, iov->iov_len);
+ if (cipdesc != NULL) {
+ dstseg = nlm_crypto_fill_dst_seg(cmd->paramp,
+ dstseg, (caddr_t)iov->iov_base,
+ iov->iov_len);
+ }
+ iov++;
+ iol--;
+ }
+ } else {
+ srcseg = nlm_crypto_fill_src_seg(cmd->paramp, srcseg,
+ ((caddr_t)crp->crp_buf), crp->crp_ilen);
+ if (cipdesc != NULL) {
+ dstseg = nlm_crypto_fill_dst_seg(cmd->paramp, dstseg,
+ ((caddr_t)crp->crp_buf), crp->crp_ilen);
+ }
+ }
+ return (0);
+}
+
+int
+nlm_crypto_do_cipher(struct xlp_sec_softc *sc, struct xlp_sec_command *cmd)
+{
+ struct cryptodesc *cipdesc = NULL;
+ unsigned char *cipkey = NULL;
+ int ret = 0;
+
+ cipdesc = cmd->enccrd;
+ cipkey = (unsigned char *)cipdesc->crd_key;
+ if (cmd->cipheralg == NLM_CIPHER_3DES) {
+ if (!(cipdesc->crd_flags & CRD_F_ENCRYPT)) {
+ uint64_t *k, *tkey;
+ k = (uint64_t *)cipdesc->crd_key;
+ tkey = (uint64_t *)cmd->des3key;
+ tkey[2] = k[0];
+ tkey[1] = k[1];
+ tkey[0] = k[2];
+ cipkey = (unsigned char *)tkey;
+ }
+ }
+ nlm_crypto_fill_pkt_ctrl(cmd->ctrlp, 0, NLM_HASH_BYPASS, 0,
+ cmd->cipheralg, cmd->ciphermode, cipkey,
+ (cipdesc->crd_klen >> 3), NULL, 0);
+
+ nlm_crypto_fill_cipher_pkt_param(cmd->ctrlp, cmd->paramp,
+ (cipdesc->crd_flags & CRD_F_ENCRYPT) ? 1 : 0, cmd->ivoff,
+ cmd->ivlen, cmd->cipheroff, cmd->cipherlen);
+ nlm_crypto_form_srcdst_segs(cmd);
+
+ ret = nlm_crypto_complete_sec_request(sc, cmd);
+ return (ret);
+}
+
+int
+nlm_crypto_do_digest(struct xlp_sec_softc *sc, struct xlp_sec_command *cmd)
+{
+ struct cryptodesc *digdesc = NULL;
+ int ret=0;
+
+ digdesc = cmd->maccrd;
+
+ nlm_crypto_fill_pkt_ctrl(cmd->ctrlp, (digdesc->crd_klen) ? 1 : 0,
+ cmd->hashalg, cmd->hashmode, NLM_CIPHER_BYPASS, 0,
+ NULL, 0, digdesc->crd_key, digdesc->crd_klen >> 3);
+
+ nlm_crypto_fill_auth_pkt_param(cmd->ctrlp, cmd->paramp,
+ cmd->hashoff, cmd->hashlen, cmd->hmacpad,
+ (unsigned char *)cmd->hashdest);
+
+ nlm_crypto_form_srcdst_segs(cmd);
+
+ ret = nlm_crypto_complete_sec_request(sc, cmd);
+
+ return (ret);
+}
+
+int
+nlm_crypto_do_cipher_digest(struct xlp_sec_softc *sc,
+ struct xlp_sec_command *cmd)
+{
+ struct cryptodesc *cipdesc=NULL, *digdesc=NULL;
+ unsigned char *cipkey = NULL;
+ int ret=0;
+
+ cipdesc = cmd->enccrd;
+ digdesc = cmd->maccrd;
+
+ cipkey = (unsigned char *)cipdesc->crd_key;
+ if (cmd->cipheralg == NLM_CIPHER_3DES) {
+ if (!(cipdesc->crd_flags & CRD_F_ENCRYPT)) {
+ uint64_t *k, *tkey;
+ k = (uint64_t *)cipdesc->crd_key;
+ tkey = (uint64_t *)cmd->des3key;
+ tkey[2] = k[0];
+ tkey[1] = k[1];
+ tkey[0] = k[2];
+ cipkey = (unsigned char *)tkey;
+ }
+ }
+ nlm_crypto_fill_pkt_ctrl(cmd->ctrlp, (digdesc->crd_klen) ? 1 : 0,
+ cmd->hashalg, cmd->hashmode, cmd->cipheralg, cmd->ciphermode,
+ cipkey, (cipdesc->crd_klen >> 3),
+ digdesc->crd_key, (digdesc->crd_klen >> 3));
+
+ nlm_crypto_fill_cipher_auth_pkt_param(cmd->ctrlp, cmd->paramp,
+ (cipdesc->crd_flags & CRD_F_ENCRYPT) ? 1 : 0, cmd->hashsrc,
+ cmd->ivoff, cmd->ivlen, cmd->hashoff, cmd->hashlen,
+ cmd->hmacpad, cmd->cipheroff, cmd->cipherlen,
+ (unsigned char *)cmd->hashdest);
+
+ nlm_crypto_form_srcdst_segs(cmd);
+
+ ret = nlm_crypto_complete_sec_request(sc, cmd);
+ return (ret);
+}
+
+int
+nlm_get_digest_param(struct xlp_sec_command *cmd)
+{
+ switch(cmd->maccrd->crd_alg) {
+ case CRYPTO_MD5:
+ cmd->hashalg = NLM_HASH_MD5;
+ cmd->hashmode = NLM_HASH_MODE_SHA1;
+ break;
+ case CRYPTO_SHA1:
+ cmd->hashalg = NLM_HASH_SHA;
+ cmd->hashmode = NLM_HASH_MODE_SHA1;
+ break;
+ case CRYPTO_MD5_HMAC:
+ cmd->hashalg = NLM_HASH_MD5;
+ cmd->hashmode = NLM_HASH_MODE_SHA1;
+ break;
+ case CRYPTO_SHA1_HMAC:
+ cmd->hashalg = NLM_HASH_SHA;
+ cmd->hashmode = NLM_HASH_MODE_SHA1;
+ break;
+ default:
+ /* Not supported */
+ return (-1);
+ }
+ return (0);
+}
+int
+nlm_get_cipher_param(struct xlp_sec_command *cmd)
+{
+ switch(cmd->enccrd->crd_alg) {
+ case CRYPTO_DES_CBC:
+ cmd->cipheralg = NLM_CIPHER_DES;
+ cmd->ciphermode = NLM_CIPHER_MODE_CBC;
+ cmd->ivlen = XLP_SEC_DES_IV_LENGTH;
+ break;
+ case CRYPTO_3DES_CBC:
+ cmd->cipheralg = NLM_CIPHER_3DES;
+ cmd->ciphermode = NLM_CIPHER_MODE_CBC;
+ cmd->ivlen = XLP_SEC_DES_IV_LENGTH;
+ break;
+ case CRYPTO_AES_CBC:
+ cmd->cipheralg = NLM_CIPHER_AES128;
+ cmd->ciphermode = NLM_CIPHER_MODE_CBC;
+ cmd->ivlen = XLP_SEC_AES_IV_LENGTH;
+ break;
+ case CRYPTO_ARC4:
+ cmd->cipheralg = NLM_CIPHER_ARC4;
+ cmd->ciphermode = NLM_CIPHER_MODE_ECB;
+ cmd->ivlen = XLP_SEC_ARC4_IV_LENGTH;
+ break;
+ default:
+ /* Not supported */
+ return (-1);
+ }
+ return (0);
+}
diff --git a/sys/mips/nlm/dev/sec/nlmseclib.h b/sys/mips/nlm/dev/sec/nlmseclib.h
new file mode 100644
index 0000000..be20905
--- /dev/null
+++ b/sys/mips/nlm/dev/sec/nlmseclib.h
@@ -0,0 +1,157 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom 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.
+ * 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 BROADCOM ``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 BROADCOM 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$
+ */
+
+#ifndef _NLMSECLIB_H_
+#define _NLMSECLIB_H_
+
+/*
+ * Cryptographic parameter definitions
+ */
+#define XLP_SEC_DES_KEY_LENGTH 8 /* Bytes */
+#define XLP_SEC_3DES_KEY_LENGTH 24 /* Bytes */
+#define XLP_SEC_AES128_KEY_LENGTH 16 /* Bytes */
+#define XLP_SEC_AES192_KEY_LENGTH 24 /* Bytes */
+#define XLP_SEC_AES256_KEY_LENGTH 32 /* Bytes */
+#define XLP_SEC_AES128F8_KEY_LENGTH 32 /* Bytes */
+#define XLP_SEC_AES192F8_KEY_LENGTH 48 /* Bytes */
+#define XLP_SEC_AES256F8_KEY_LENGTH 64 /* Bytes */
+#define XLP_SEC_KASUMI_F8_KEY_LENGTH 16 /* Bytes */
+#define XLP_SEC_MAX_CRYPT_KEY_LENGTH XLP_SEC_AES256F8_KEY_LENGTH
+
+
+#define XLP_SEC_DES_IV_LENGTH 8 /* Bytes */
+#define XLP_SEC_AES_IV_LENGTH 16 /* Bytes */
+#define XLP_SEC_ARC4_IV_LENGTH 0 /* Bytes */
+#define XLP_SEC_KASUMI_F8_IV_LENGTH 16 /* Bytes */
+#define XLP_SEC_MAX_IV_LENGTH 16 /* Bytes */
+#define XLP_SEC_IV_LENGTH_BYTES 8 /* Bytes */
+
+#define XLP_SEC_AES_BLOCK_SIZE 16 /* Bytes */
+#define XLP_SEC_DES_BLOCK_SIZE 8 /* Bytes */
+#define XLP_SEC_3DES_BLOCK_SIZE 8 /* Bytes */
+
+#define XLP_SEC_MD5_BLOCK_SIZE 64 /* Bytes */
+#define XLP_SEC_SHA1_BLOCK_SIZE 64 /* Bytes */
+#define XLP_SEC_SHA256_BLOCK_SIZE 64 /* Bytes */
+#define XLP_SEC_SHA384_BLOCK_SIZE 128 /* Bytes */
+#define XLP_SEC_SHA512_BLOCK_SIZE 128 /* Bytes */
+#define XLP_SEC_GCM_BLOCK_SIZE 16 /* XXX: Bytes */
+#define XLP_SEC_KASUMI_F9_BLOCK_SIZE 16 /* XXX: Bytes */
+#define XLP_SEC_MAX_BLOCK_SIZE 64 /* Max of MD5/SHA */
+#define XLP_SEC_MD5_LENGTH 16 /* Bytes */
+#define XLP_SEC_SHA1_LENGTH 20 /* Bytes */
+#define XLP_SEC_SHA256_LENGTH 32 /* Bytes */
+#define XLP_SEC_SHA384_LENGTH 64 /* Bytes */
+#define XLP_SEC_SHA512_LENGTH 64 /* Bytes */
+#define XLP_SEC_GCM_LENGTH 16 /* Bytes */
+#define XLP_SEC_KASUMI_F9_LENGTH 16 /* Bytes */
+#define XLP_SEC_KASUMI_F9_RESULT_LENGTH 4 /* Bytes */
+#define XLP_SEC_HMAC_LENGTH 64 /* Max of MD5/SHA/SHA256 */
+#define XLP_SEC_MAX_AUTH_KEY_LENGTH XLP_SEC_SHA512_BLOCK_SIZE
+#define XLP_SEC_MAX_RC4_STATE_SIZE 264 /* char s[256], int i, int j */
+
+#define XLP_SEC_SESSION(sid) ((sid) & 0x000007ff)
+#define XLP_SEC_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff))
+
+#define CRYPTO_ERROR(msg1) ((unsigned int)msg1)
+
+#define NLM_CRYPTO_LEFT_REQS (CMS_DEFAULT_CREDIT/2)
+#define NLM_CRYPTO_NUM_SEGS_REQD(__bufsize) \
+ ((__bufsize + NLM_CRYPTO_MAX_SEG_LEN - 1) / NLM_CRYPTO_MAX_SEG_LEN)
+
+#define NLM_CRYPTO_PKT_DESC_SIZE(nsegs) (32 + (nsegs * 16))
+
+extern unsigned int creditleft;
+
+struct xlp_sec_command {
+ uint16_t session_num;
+ struct cryptop *crp;
+ struct cryptodesc *enccrd, *maccrd;
+ struct xlp_sec_session *ses;
+ struct nlm_crypto_pkt_ctrl *ctrlp;
+ struct nlm_crypto_pkt_param *paramp;
+ void *iv;
+ uint8_t des3key[24];
+ uint8_t *hashdest;
+ uint8_t hashsrc;
+ uint8_t hmacpad;
+ uint32_t hashoff;
+ uint32_t hashlen;
+ uint32_t cipheroff;
+ uint32_t cipherlen;
+ uint32_t ivoff;
+ uint32_t ivlen;
+ uint32_t hashalg;
+ uint32_t hashmode;
+ uint32_t cipheralg;
+ uint32_t ciphermode;
+ uint32_t nsegs;
+ uint32_t hash_dst_len; /* used to store hash alg dst size */
+};
+
+struct xlp_sec_session {
+ uint32_t sessionid;
+ int hs_used;
+ int hs_mlen;
+ uint8_t ses_iv[EALG_MAX_BLOCK_LEN];
+ struct xlp_sec_command cmd;
+};
+
+/*
+ * Holds data specific to nlm security accelerators
+ */
+struct xlp_sec_softc {
+ device_t sc_dev; /* device backpointer */
+ uint64_t sec_base;
+ int32_t sc_cid;
+ struct xlp_sec_session *sc_sessions;
+ int sc_nsessions;
+ int sc_needwakeup;
+ uint32_t sec_vc_start;
+ uint32_t sec_vc_end;
+ uint32_t sec_msgsz;
+};
+
+#ifdef NLM_SEC_DEBUG
+void print_crypto_params(struct xlp_sec_command *cmd, struct nlm_fmn_msg m);
+void xlp_sec_print_data(struct cryptop *crp);
+void print_cmd(struct xlp_sec_command *cmd);
+#endif
+int nlm_crypto_form_srcdst_segs(struct xlp_sec_command *cmd);
+int nlm_crypto_do_cipher(struct xlp_sec_softc *sc,
+ struct xlp_sec_command *cmd);
+int nlm_crypto_do_digest(struct xlp_sec_softc *sc,
+ struct xlp_sec_command *cmd);
+int nlm_crypto_do_cipher_digest(struct xlp_sec_softc *sc,
+ struct xlp_sec_command *cmd);
+int nlm_get_digest_param(struct xlp_sec_command *cmd);
+int nlm_get_cipher_param(struct xlp_sec_command *cmd);
+
+#endif /* _NLMSECLIB_H_ */
diff --git a/sys/mips/nlm/dev/sec/rsa_ucode.h b/sys/mips/nlm/dev/sec/rsa_ucode.h
new file mode 100644
index 0000000..a0f7cb3
--- /dev/null
+++ b/sys/mips/nlm/dev/sec/rsa_ucode.h
@@ -0,0 +1,956 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom 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.
+ * 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 BROADCOM ``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 BROADCOM 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$
+ */
+
+#ifndef _NLM_HAL_RSA_UCODE_H
+#define _NLM_HAL_RSA_UCODE_H
+static uint64_t nlm_rsa_ucode_data [] = {
+ 0x0000000000000000ULL,
+ 0x00000000503840ecULL,
+ 0x00000001903800ecULL,
+ 0x00000002c03820ecULL,
+ 0x0000003760000044ULL,
+ 0x0000000000000014ULL,
+ 0x000000071000000cULL,
+ 0x00000007d000010cULL,
+ 0x0000001b80000c0cULL,
+ 0x00000000e03fc0ecULL,
+ 0x00000001103fc1ecULL,
+ 0x00000001403f42ecULL,
+ 0x00000001403fc4ecULL,
+ 0x0000003760000044ULL,
+ 0x000000001800003cULL,
+ 0x0000000d8000030cULL,
+ 0x0000000630000044ULL,
+ 0x000000002800003cULL,
+ 0x0000000ef000030cULL,
+ 0x0000000630000044ULL,
+ 0x00000000503fc23cULL,
+ 0x00000000a03fc33cULL,
+ 0x00000001403fc43cULL,
+ 0x00000010c000030cULL,
+ 0x0000000630000044ULL,
+ 0x0000000000000014ULL,
+ 0x000000071000000cULL,
+ 0x0000001c1000070cULL,
+ 0x0000002500000d0cULL,
+ 0x00000027c0000e0cULL,
+ 0x0000002d60000f0cULL,
+ 0x00000002603f00ecULL,
+ 0x00000002603f82ecULL,
+ 0x00000002803f83ecULL,
+ 0x00000002803f04ecULL,
+ 0x00000002a03f06ecULL,
+ 0x00000002a03f88ecULL,
+ 0x0000003760000044ULL,
+ 0x000000086000010cULL,
+ 0x00000003f0000044ULL,
+ 0x00000008d000010cULL,
+ 0x00000004b0000044ULL,
+ 0x00000008d000010cULL,
+ 0x0000000570000044ULL,
+ 0x000000000000001cULL,
+ 0x000000076000000cULL,
+ 0x0000001c1000070cULL,
+ 0x0000002690000d0cULL,
+ 0x0000002990000e0cULL,
+ 0x0000002e10000f0cULL,
+ 0x00000003903f20ecULL,
+ 0x00000003903fa2ecULL,
+ 0x00000003b03fa3ecULL,
+ 0x00000003b03f24ecULL,
+ 0x00000003d03f26ecULL,
+ 0x00000003d03fa8ecULL,
+ 0x0000003760000044ULL,
+ 0x000000096000010cULL,
+ 0x00000003f0000044ULL,
+ 0x0000000a0000010cULL,
+ 0x00000004b0000044ULL,
+ 0x0000000a0000010cULL,
+ 0x0000000570000044ULL,
+ 0x000000000800003cULL,
+ 0x0000000af000020cULL,
+ 0x0000000bc000030cULL,
+ 0x000000129000040cULL,
+ 0x000000178000050cULL,
+ 0x000000191000060cULL,
+ 0x0000001ff000080cULL,
+ 0x000000205000090cULL,
+ 0x00000022c0000a0cULL,
+ 0x00000020b0000b0cULL,
+ 0x0000001ac0000c0cULL,
+ 0x0000000680000044ULL,
+ 0x000000001000003cULL,
+ 0x0000000b5000020cULL,
+ 0x0000000c5000030cULL,
+ 0x000000137000040cULL,
+ 0x00000017e000050cULL,
+ 0x000000197000060cULL,
+ 0x000000200000080cULL,
+ 0x000000206000090cULL,
+ 0x0000002340000a0cULL,
+ 0x0000002110000b0cULL,
+ 0x0000001b10000c0cULL,
+ 0x0000000680000044ULL,
+ 0x000000001800003cULL,
+ 0x0000000b5000020cULL,
+ 0x0000000d8000030cULL,
+ 0x000000154000040cULL,
+ 0x000000187000050cULL,
+ 0x0000001a0000060cULL,
+ 0x000000202000080cULL,
+ 0x000000208000090cULL,
+ 0x0000002410000a0cULL,
+ 0x00000021c0000b0cULL,
+ 0x0000001b80000c0cULL,
+ 0x0000000680000044ULL,
+ 0x000000000000000aULL,
+ 0x0000000000000024ULL,
+ 0x0000002ed01f80e4ULL,
+ 0x00000030101f81e4ULL,
+ 0x0000003760000044ULL,
+ 0x000000000000000aULL,
+ 0x0000000000000024ULL,
+ 0x00000030d01f00e4ULL,
+ 0x00000030d01f82e4ULL,
+ 0x00000034801f83e4ULL,
+ 0x00000035401e04e4ULL,
+ 0x00000037101f88e4ULL,
+ 0x00000035401f89e4ULL,
+ 0x0000003760000044ULL,
+ 0x0000000000000074ULL,
+ 0x0000000f0000008cULL,
+ 0x00000008000000a4ULL,
+ 0x000000080400007bULL,
+ 0x00000000000000c4ULL,
+ 0x0000000000000074ULL,
+ 0x0000000c000000a4ULL,
+ 0x0000000004004071ULL,
+ 0x0000000b0000008cULL,
+ 0x00000008000000a4ULL,
+ 0x000000080400007bULL,
+ 0x00000000000000c4ULL,
+ 0x000000034c0b4091ULL,
+ 0x0000000b040b0093ULL,
+ 0x0000000000000000ULL,
+ 0x0000000004000802ULL,
+ 0x00000002c88b0021ULL,
+ 0x0000000a828b0423ULL,
+ 0x00000010000000a4ULL,
+ 0x000000081000006cULL,
+ 0x00000000000000c4ULL,
+ 0x000000004c0b4091ULL,
+ 0x00000008000000a4ULL,
+ 0x0000000002000402ULL,
+ 0x000000004a8b0021ULL,
+ 0x00000010000000a4ULL,
+ 0x000000089000006cULL,
+ 0x00000000000000c4ULL,
+ 0x000000034c0b4091ULL,
+ 0x0000000b040b0093ULL,
+ 0x00000008000000a4ULL,
+ 0x0000000002000402ULL,
+ 0x00000002c88b0021ULL,
+ 0x0000000a828b0423ULL,
+ 0x00000010000000a4ULL,
+ 0x000000091000006cULL,
+ 0x00000000000000c4ULL,
+ 0x000000004c0b4091ULL,
+ 0x00000008000000a4ULL,
+ 0x0000000002000402ULL,
+ 0x000000004a8b0021ULL,
+ 0x00000010000000a4ULL,
+ 0x0000000990000064ULL,
+ 0x000000004a8b0021ULL,
+ 0x0000000000898611ULL,
+ 0x0000000c000000a4ULL,
+ 0x00000000000000c4ULL,
+ 0x000000034c0b4091ULL,
+ 0x0000000b040b0093ULL,
+ 0x00000008000000a4ULL,
+ 0x0000000002000402ULL,
+ 0x00000002c88b0021ULL,
+ 0x0000000a828b0423ULL,
+ 0x00000010000000a4ULL,
+ 0x0000000a40000064ULL,
+ 0x0000000088800021ULL,
+ 0x0000000880800423ULL,
+ 0x00000000001004a1ULL,
+ 0x0000000c000000a4ULL,
+ 0x00000002c88b0061ULL,
+ 0x0000000a808b0463ULL,
+ 0x00000000000000c4ULL,
+ 0x00000000058f0011ULL,
+ 0x0000000001860002ULL,
+ 0x00000010000000a4ULL,
+ 0x00000000000000ccULL,
+ 0x000000004d8f0021ULL,
+ 0x0000000b10000044ULL,
+ 0x00000007058f0013ULL,
+ 0x0000000001860002ULL,
+ 0x00000010000000a4ULL,
+ 0x00000000000000ccULL,
+ 0x000000034c0f0021ULL,
+ 0x0000000b058f0423ULL,
+ 0x0000000b70000044ULL,
+ 0x0000000000180001ULL,
+ 0x000000000b600031ULL,
+ 0x00000008000000a4ULL,
+ 0x0000000004800041ULL,
+ 0x00000008000000a4ULL,
+ 0x0000000007c03f41ULL,
+ 0x00000000440ac491ULL,
+ 0x00000004000000a4ULL,
+ 0x00000000000000c4ULL,
+ 0x0000000010180001ULL,
+ 0x0000000088a00031ULL,
+ 0x00000002c3430431ULL,
+ 0x00000004000000a4ULL,
+ 0x0000000204938041ULL,
+ 0x00000008000000a4ULL,
+ 0x000000012c002b41ULL,
+ 0x0000000117982861ULL,
+ 0x0000000088a03631ULL,
+ 0x00000002c3430c31ULL,
+ 0x00000004000000a4ULL,
+ 0x0000000204938041ULL,
+ 0x00000008000000a4ULL,
+ 0x000000012c002b41ULL,
+ 0x0000000347cb2861ULL,
+ 0x000000034c09f691ULL,
+ 0x00000003040a8491ULL,
+ 0x0000000000000000ULL,
+ 0x00000000000000c4ULL,
+ 0x0000000010180001ULL,
+ 0x0000000088a00031ULL,
+ 0x00000002c0830431ULL,
+ 0x0000000283430431ULL,
+ 0x000000080000009cULL,
+ 0x0000000204938041ULL,
+ 0x00000008000000a4ULL,
+ 0x000000012c002b41ULL,
+ 0x0000000104202861ULL,
+ 0x0000000117d82861ULL,
+ 0x0000000088a02f31ULL,
+ 0x00000002c0833c31ULL,
+ 0x0000002283430c3bULL,
+ 0x0000000000000000ULL,
+ 0x0000000204938041ULL,
+ 0x00000008000000a4ULL,
+ 0x000000012c002b41ULL,
+ 0x00000003442b2861ULL,
+ 0x0000000307cb2861ULL,
+ 0x000000034c09ef91ULL,
+ 0x000000030409bc91ULL,
+ 0x00000003040a8491ULL,
+ 0x00000000000000c4ULL,
+ 0x0000000010180001ULL,
+ 0x0000000088a00031ULL,
+ 0x00000002c0830431ULL,
+ 0x0000000280830431ULL,
+ 0x0000000280c30431ULL,
+ 0x0000000004900041ULL,
+ 0x0000000283430531ULL,
+ 0x0000000a00038007ULL,
+ 0x0000000000000000ULL,
+ 0x000000012c002b41ULL,
+ 0x0000000344202861ULL,
+ 0x0000001304032863ULL,
+ 0x0000000317db2861ULL,
+ 0x00000000b8a02b31ULL,
+ 0x00000002c0832831ULL,
+ 0x0000000280832831ULL,
+ 0x0000000280c33c31ULL,
+ 0x0000000004900041ULL,
+ 0x0000002e83430d3bULL,
+ 0x0000000200038000ULL,
+ 0x0000000000000000ULL,
+ 0x000000012c002b41ULL,
+ 0x00000003442b2861ULL,
+ 0x00000013040b2863ULL,
+ 0x0000000307cb2861ULL,
+ 0x000000037c09eb91ULL,
+ 0x000000130409a893ULL,
+ 0x000000030409bc91ULL,
+ 0x00000003040a849dULL,
+ 0x0000000010180001ULL,
+ 0x0000000088a00031ULL,
+ 0x00000002c0830431ULL,
+ 0x0000000280830431ULL,
+ 0x0000000280c30431ULL,
+ 0x0000000004900041ULL,
+ 0x0000000280830531ULL,
+ 0x0000001e80830433ULL,
+ 0x0000000283430431ULL,
+ 0x0000000b2c03ab67ULL,
+ 0x0000000344202861ULL,
+ 0x0000001304032863ULL,
+ 0x0000000317db2861ULL,
+ 0x00000002b8a3ab31ULL,
+ 0x00000002c0832831ULL,
+ 0x0000000280832831ULL,
+ 0x0000000280c32831ULL,
+ 0x0000000004900041ULL,
+ 0x0000000280832931ULL,
+ 0x0000001e80832833ULL,
+ 0x0000002e83430c3bULL,
+ 0x000000032c03ab61ULL,
+ 0x00000003442b2861ULL,
+ 0x00000013040b2863ULL,
+ 0x0000000307cb2861ULL,
+ 0x000000037c09eb91ULL,
+ 0x000000130409a893ULL,
+ 0x000000030409bc91ULL,
+ 0x00000003040a849dULL,
+ 0x0000000000140001ULL,
+ 0x0000004000140001ULL,
+ 0x000000000b600061ULL,
+ 0x000000400b600061ULL,
+ 0x00000004000000a4ULL,
+ 0x0000000004800041ULL,
+ 0x0000004004800041ULL,
+ 0x00000004000000a4ULL,
+ 0x0000000007c03f41ULL,
+ 0x0000004007c03f41ULL,
+ 0x00000000440ac591ULL,
+ 0x00000040440ac591ULL,
+ 0x0000000000000000ULL,
+ 0x00000000000000c4ULL,
+ 0x0000000010140001ULL,
+ 0x0000004010140001ULL,
+ 0x0000000088e00061ULL,
+ 0x0000004088e00061ULL,
+ 0x00000002c3430561ULL,
+ 0x00000042c3430561ULL,
+ 0x0000000204938041ULL,
+ 0x0000004204938041ULL,
+ 0x00000004000000a4ULL,
+ 0x000000012c402b41ULL,
+ 0x000000412c402b41ULL,
+ 0x0000000117f42961ULL,
+ 0x0000004117f42961ULL,
+ 0x0000000088e03f61ULL,
+ 0x0000004088e03f61ULL,
+ 0x00000002c3430d61ULL,
+ 0x00000042c3430d61ULL,
+ 0x0000000204938041ULL,
+ 0x0000004204938041ULL,
+ 0x00000004000000a4ULL,
+ 0x000000012c402b41ULL,
+ 0x000000412c402b41ULL,
+ 0x0000000347eb2961ULL,
+ 0x0000004347eb2961ULL,
+ 0x000000034c7dff91ULL,
+ 0x000000434c7dff91ULL,
+ 0x00000003040a0591ULL,
+ 0x00000043040a0591ULL,
+ 0x00000000000000c4ULL,
+ 0x0000000010140001ULL,
+ 0x0000004010140001ULL,
+ 0x0000000088e00061ULL,
+ 0x0000004088e00061ULL,
+ 0x00000002c0c30561ULL,
+ 0x00000042c0c30561ULL,
+ 0x0000000004900041ULL,
+ 0x0000004004900041ULL,
+ 0x0000000283430561ULL,
+ 0x0000004283430561ULL,
+ 0x0000000b2c43ab47ULL,
+ 0x000000432c43ab41ULL,
+ 0x0000000344602961ULL,
+ 0x0000004344602961ULL,
+ 0x0000000317d72961ULL,
+ 0x0000004317d72961ULL,
+ 0x00000002b8e3ab61ULL,
+ 0x00000042b8e3ab61ULL,
+ 0x00000002c0c32961ULL,
+ 0x00000042c0c32961ULL,
+ 0x0000000004900041ULL,
+ 0x0000004004900041ULL,
+ 0x0000000283430d61ULL,
+ 0x0000007683430d6bULL,
+ 0x000000032c43ab41ULL,
+ 0x000000432c43ab41ULL,
+ 0x00000003446b2961ULL,
+ 0x00000043446b2961ULL,
+ 0x0000000307cb2961ULL,
+ 0x0000004307cb2961ULL,
+ 0x000000037c7de791ULL,
+ 0x000000437c7de791ULL,
+ 0x0000000304499d91ULL,
+ 0x0000004304499d91ULL,
+ 0x00000003040a0591ULL,
+ 0x00000043040a059dULL,
+ 0x0000000048840011ULL,
+ 0x00000000028b3691ULL,
+ 0x000000000e09c691ULL,
+ 0x000000000c09c691ULL,
+ 0x0000000000000000ULL,
+ 0x00000000000000c4ULL,
+ 0x00000000c8840011ULL,
+ 0x0000000212ab3691ULL,
+ 0x0000000080800411ULL,
+ 0x0000000002cb3691ULL,
+ 0x000000034c29ef91ULL,
+ 0x0000000006098491ULL,
+ 0x000000034c09ef91ULL,
+ 0x0000000004098491ULL,
+ 0x00000000000000c4ULL,
+ 0x00000000e8840011ULL,
+ 0x0000000210ab3a91ULL,
+ 0x0000000880800415ULL,
+ 0x00000006128b3699ULL,
+ 0x000000034c29eb91ULL,
+ 0x0000000f0409a893ULL,
+ 0x0000000026098891ULL,
+ 0x000000034c09eb91ULL,
+ 0x0000000f0409a893ULL,
+ 0x000000000409849dULL,
+ 0x0000000048841011ULL,
+ 0x00000000068b7691ULL,
+ 0x000000000e099611ULL,
+ 0x000000000c098611ULL,
+ 0x0000000000000000ULL,
+ 0x00000000000000c4ULL,
+ 0x00000000c8840011ULL,
+ 0x0000000216ab7691ULL,
+ 0x0000000080801411ULL,
+ 0x0000000006cb3691ULL,
+ 0x000000034c29af11ULL,
+ 0x0000000006099411ULL,
+ 0x000000034c09af11ULL,
+ 0x0000000004098411ULL,
+ 0x00000000000000c4ULL,
+ 0x00000000e8840011ULL,
+ 0x0000000214ab7a91ULL,
+ 0x0000000c80800415ULL,
+ 0x00000006168b3699ULL,
+ 0x0000000080801411ULL,
+ 0x00000002168b3691ULL,
+ 0x000000034c29ab11ULL,
+ 0x0000000f0409a813ULL,
+ 0x0000000026099811ULL,
+ 0x000000034c09ab11ULL,
+ 0x0000000f0409a813ULL,
+ 0x000000000409841dULL,
+ 0x0000000c000000d4ULL,
+ 0x0000000000000000ULL,
+ 0x000000004a801011ULL,
+ 0x000000000e004691ULL,
+ 0x000000000009800dULL,
+ 0x0000000c000000d4ULL,
+ 0x000000004a801011ULL,
+ 0x000000018c004691ULL,
+ 0x0000000000800411ULL,
+ 0x0000000006003691ULL,
+ 0x0000000200098001ULL,
+ 0x000000000009800dULL,
+ 0x0000000c000000d4ULL,
+ 0x000000004a801011ULL,
+ 0x000000018c004691ULL,
+ 0x0000000c00800415ULL,
+ 0x0000000584003699ULL,
+ 0x0000000000800411ULL,
+ 0x0000000006003691ULL,
+ 0x0000000a00098003ULL,
+ 0x000000000009800dULL,
+ 0x000000200000302aULL,
+ 0x00000000000e0012ULL,
+ 0x0000000000100211ULL,
+ 0x0000000002000002ULL,
+ 0x00000006000b0003ULL,
+ 0x0000000000000000ULL,
+ 0x00000000000000ccULL,
+ 0x0000000006000302ULL,
+ 0x00000002810b0011ULL,
+ 0x0000000a808b0013ULL,
+ 0x0000000002010002ULL,
+ 0x00000006108b0093ULL,
+ 0x0000000002800002ULL,
+ 0x00000007040b0013ULL,
+ 0x0000000006800002ULL,
+ 0x00000007040b0013ULL,
+ 0x0000000003000002ULL,
+ 0x0000000000090101ULL,
+ 0x0000000200098001ULL,
+ 0x0000000a000b0003ULL,
+ 0x0000000007000302ULL,
+ 0x0000000400890015ULL,
+ 0x0000000784098019ULL,
+ 0x0000000007800002ULL,
+ 0x0000000000090001ULL,
+ 0x0000000000098101ULL,
+ 0x0000001dd000006cULL,
+ 0x000000280300060aULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000e02ULL,
+ 0x0000000001000011ULL,
+ 0x00000010000000a4ULL,
+ 0x0000001dc0000064ULL,
+ 0x0000000000000f02ULL,
+ 0x0000000001000011ULL,
+ 0x0000000002000602ULL,
+ 0x0000000680890013ULL,
+ 0x0000000002806002ULL,
+ 0x0000000004000011ULL,
+ 0x000000031489f691ULL,
+ 0x0000000804000415ULL,
+ 0x000000071489b699ULL,
+ 0x0000000006000e02ULL,
+ 0x0000000680890013ULL,
+ 0x0000000006800e02ULL,
+ 0x0000000680898013ULL,
+ 0x0000002c0300540aULL,
+ 0x0000000007800012ULL,
+ 0x00000000000b8000ULL,
+ 0x000000000700cd42ULL,
+ 0x0000000000800011ULL,
+ 0x000000029489f691ULL,
+ 0x0000000800800415ULL,
+ 0x000000069489b699ULL,
+ 0x000000200000e02aULL,
+ 0x00000000000000fcULL,
+ 0x0000000c000000a4ULL,
+ 0x0000001dc0000064ULL,
+ 0x000000240000c02aULL,
+ 0x0000000002000012ULL,
+ 0x0000000600090003ULL,
+ 0x00000000000000c4ULL,
+ 0x000000001680409dULL,
+ 0x0000000014804091ULL,
+ 0x000000001680049dULL,
+ 0x0000000014804091ULL,
+ 0x0000000014800491ULL,
+ 0x000000001680049dULL,
+ 0x000000001680419dULL,
+ 0x0000000014804191ULL,
+ 0x000000001680049dULL,
+ 0x0000000014804191ULL,
+ 0x0000000014800491ULL,
+ 0x000000001680049dULL,
+ 0x0000000000800011ULL,
+ 0x00000000068b5691ULL,
+ 0x0000000004098611ULL,
+ 0x000000000700dc22ULL,
+ 0x0000000000800011ULL,
+ 0x0000000296cb569dULL,
+ 0x0000000000800011ULL,
+ 0x0000000294ab7691ULL,
+ 0x0000000000801411ULL,
+ 0x00000000068b3691ULL,
+ 0x000000034409af11ULL,
+ 0x0000000004098411ULL,
+ 0x000000000700dc22ULL,
+ 0x0000000000800011ULL,
+ 0x00000002948b7691ULL,
+ 0x0000000000801411ULL,
+ 0x0000000296cb369dULL,
+ 0x0000000000800011ULL,
+ 0x0000000294ab7691ULL,
+ 0x0000000000800411ULL,
+ 0x00000002948b3691ULL,
+ 0x0000000000801411ULL,
+ 0x00000000068b3a91ULL,
+ 0x000000034409ab11ULL,
+ 0x000000030409a411ULL,
+ 0x0000000004098411ULL,
+ 0x000000000700dc22ULL,
+ 0x0000000000800011ULL,
+ 0x00000002948b7691ULL,
+ 0x0000000000800411ULL,
+ 0x00000002948b3691ULL,
+ 0x0000000000801411ULL,
+ 0x0000000296cb369dULL,
+ 0x0000000001000011ULL,
+ 0x0000000006098611ULL,
+ 0x0000000000000000ULL,
+ 0x0000000007000e02ULL,
+ 0x0000000000888061ULL,
+ 0x0000000003000602ULL,
+ 0x0000000000888061ULL,
+ 0x00000000000984edULL,
+ 0x0000000001000011ULL,
+ 0x0000000b8409b615ULL,
+ 0x0000000400800419ULL,
+ 0x000000000609b611ULL,
+ 0x0000000007000e02ULL,
+ 0x0000000080800061ULL,
+ 0x0000000200cb0461ULL,
+ 0x00000000000b8000ULL,
+ 0x0000000003000602ULL,
+ 0x0000000080800061ULL,
+ 0x0000000200cb0461ULL,
+ 0x00000000000b8001ULL,
+ 0x00000000000985edULL,
+ 0x0000000001000011ULL,
+ 0x0000000b8409b615ULL,
+ 0x0000000400800419ULL,
+ 0x000000000609b611ULL,
+ 0x0000000007000e02ULL,
+ 0x0000000080800061ULL,
+ 0x00000002808b0461ULL,
+ 0x0000000200cb0461ULL,
+ 0x00000000000b8000ULL,
+ 0x0000000003000602ULL,
+ 0x0000000080800061ULL,
+ 0x00000002808b0461ULL,
+ 0x0000000200cb0461ULL,
+ 0x00000000000b8001ULL,
+ 0x00000000000985edULL,
+ 0x0000000002800002ULL,
+ 0x000000500220220aULL,
+ 0x000000140606550aULL,
+ 0x000000140606c50aULL,
+ 0x0000000002a01202ULL,
+ 0x000000500680100aULL,
+ 0x000000140286550aULL,
+ 0x000000000300d502ULL,
+ 0x000000500220340aULL,
+ 0x000000140306660aULL,
+ 0x000000140686c40aULL,
+ 0x000000140206660aULL,
+ 0x000000000600dd02ULL,
+ 0x000000500720550aULL,
+ 0x0000001806064c0aULL,
+ 0x000000180306c60aULL,
+ 0x0000000002001102ULL,
+ 0x000000500020c50aULL,
+ 0x000000000600e402ULL,
+ 0x000000500220440aULL,
+ 0x000000140606cc0aULL,
+ 0x000000000320d602ULL,
+ 0x000000500100e50aULL,
+ 0x000000180086c60aULL,
+ 0x00000000000000c4ULL,
+ 0x0000000002000002ULL,
+ 0x0000005002a0210aULL,
+ 0x000000140280540aULL,
+ 0x0000000003005502ULL,
+ 0x000000500620200aULL,
+ 0x000000140680c50aULL,
+ 0x0000000002004402ULL,
+ 0x0000005003a0cc0aULL,
+ 0x0000000002a03702ULL,
+ 0x000000500700c50aULL,
+ 0x000000140280650aULL,
+ 0x000000140280e50aULL,
+ 0x000000000000c502ULL,
+ 0x000000500120c70aULL,
+ 0x000000000200c402ULL,
+ 0x0000005000a0d50aULL,
+ 0x0000000000000000ULL,
+ 0x000000140080410aULL,
+ 0x00000000000000c4ULL,
+ 0x0000000006009202ULL,
+ 0x000000500220a10aULL,
+ 0x0000001806064c0aULL,
+ 0x0000000002808202ULL,
+ 0x0000005006a0a00aULL,
+ 0x000000180706d50aULL,
+ 0x000000000320cc02ULL,
+ 0x000000500280ee0aULL,
+ 0x0000000006a0d502ULL,
+ 0x000000500780a20aULL,
+ 0x000000140386dd0aULL,
+ 0x000000000300f602ULL,
+ 0x0000005002a0e50aULL,
+ 0x000000180306560aULL,
+ 0x0000000000000000ULL,
+ 0x000000180306760aULL,
+ 0x0000001806866d0aULL,
+ 0x000000000380f502ULL,
+ 0x0000005007a0450aULL,
+ 0x000000300281070aULL,
+ 0x000000200000502aULL,
+ 0x00000000000000fcULL,
+ 0x0000000c000000a4ULL,
+ 0x0000002bc000006cULL,
+ 0x000000000600dc02ULL,
+ 0x000000500020e60aULL,
+ 0x000000180086fc0aULL,
+ 0x000000140107170aULL,
+ 0x00000000000000c4ULL,
+ 0x000000000200a102ULL,
+ 0x000000500620920aULL,
+ 0x000000140600c40aULL,
+ 0x000000000200a002ULL,
+ 0x0000005006a0820aULL,
+ 0x000000140680d40aULL,
+ 0x000000140200dc0aULL,
+ 0x000000000700a202ULL,
+ 0x0000005002a0dd0aULL,
+ 0x000000000300c402ULL,
+ 0x0000005003a0350aULL,
+ 0x0000000000000000ULL,
+ 0x000000140300670aULL,
+ 0x000000000380d502ULL,
+ 0x0000005007a0e60aULL,
+ 0x0000000000000000ULL,
+ 0x0000001407807f0aULL,
+ 0x000000000380d102ULL,
+ 0x000000500320c00aULL,
+ 0x0000000000000000ULL,
+ 0x000000140380760aULL,
+ 0x0000000003007502ULL,
+ 0x0000005002a0d50aULL,
+ 0x000000000200f402ULL,
+ 0x0000005003a0e50aULL,
+ 0x000000300281070aULL,
+ 0x000000200000502aULL,
+ 0x00000000000000fcULL,
+ 0x0000000c000000a4ULL,
+ 0x0000002bc000006cULL,
+ 0x000000000000df02ULL,
+ 0x0000005000a0a60aULL,
+ 0x000000140101170aULL,
+ 0x000000140080410aULL,
+ 0x00000000000000c4ULL,
+ 0x000000300281020aULL,
+ 0x0000003006810a0aULL,
+ 0x0000003006010c0aULL,
+ 0x000000200000202aULL,
+ 0x00000000000000fcULL,
+ 0x0000000c000000a4ULL,
+ 0x0000002d1000006cULL,
+ 0x000000200000a02aULL,
+ 0x00000000000000fcULL,
+ 0x0000000c000000a4ULL,
+ 0x0000002d5000006cULL,
+ 0x000000200000c02aULL,
+ 0x00000000000000fcULL,
+ 0x0000000c000000a4ULL,
+ 0x0000002cd0000064ULL,
+ 0x00000034000000d4ULL,
+ 0x00000000000000c4ULL,
+ 0x0000000001000002ULL,
+ 0x00000006000b0003ULL,
+ 0x0000000000000000ULL,
+ 0x00000000000000c4ULL,
+ 0x000000140001180aULL,
+ 0x000000140081190aULL,
+ 0x0000001401011a0aULL,
+ 0x00000000000000c4ULL,
+ 0x00000000000000c4ULL,
+ 0x0000000001810302ULL,
+ 0x0000005005a10b0aULL,
+ 0x0000000002000002ULL,
+ 0x000000500620110aULL,
+ 0x000000140206340aULL,
+ 0x000000180606cb0aULL,
+ 0x0000000002000402ULL,
+ 0x0000005006210c0aULL,
+ 0x000000140206c40aULL,
+ 0x000000300201040aULL,
+ 0x00000000000000c4ULL,
+ 0x0000000002801002ULL,
+ 0x0000005005a10b0aULL,
+ 0x000000140286b50aULL,
+ 0x000000140186300aULL,
+ 0x0000000002000002ULL,
+ 0x000000500620110aULL,
+ 0x000000140606c50aULL,
+ 0x0000000002003402ULL,
+ 0x0000005006210c0aULL,
+ 0x000000140206c40aULL,
+ 0x000000300201040aULL,
+ 0x00000000000000c4ULL,
+ 0x000000040400000aULL,
+ 0x000000000000002cULL,
+ 0x0000000c0000800eULL,
+ 0x0000000c0400880aULL,
+ 0x000000080000007cULL,
+ 0x0000000004000002ULL,
+ 0x00000006808b0013ULL,
+ 0x0000000000000034ULL,
+ 0x0000000000000002ULL,
+ 0x0000002ff000005cULL,
+ 0x0000002f4000004cULL,
+ 0x00000002000b0101ULL,
+ 0x0000000a000b0003ULL,
+ 0x0000003760000044ULL,
+ 0x0000000000000034ULL,
+ 0x0000000c0000000aULL,
+ 0x0000002ff0000054ULL,
+ 0x0000000c0000800aULL,
+ 0x0000002fb000004cULL,
+ 0x0000003640000044ULL,
+ 0x0000000c0000800aULL,
+ 0x000000040400000aULL,
+ 0x000000000000002cULL,
+ 0x0000000c0000800eULL,
+ 0x0000000c0400880aULL,
+ 0x000000080000007cULL,
+ 0x000000040400000aULL,
+ 0x000000000000002cULL,
+ 0x0000000c0000800eULL,
+ 0x0000000c0400880aULL,
+ 0x000000080000007cULL,
+ 0x0000003640000044ULL,
+ 0x000000080180000aULL,
+ 0x0000000001820002ULL,
+ 0x00000007040b0013ULL,
+ 0x000000040200000aULL,
+ 0x000000000000002cULL,
+ 0x0000000c0180430eULL,
+ 0x0000000c0200440aULL,
+ 0x000000080000007cULL,
+ 0x0000000001010002ULL,
+ 0x00000006108b0093ULL,
+ 0x0000000005010002ULL,
+ 0x00000006108b0093ULL,
+ 0x0000000000000000ULL,
+ 0x00000032e01f80e4ULL,
+ 0x00000034401f81e4ULL,
+ 0x00000034601f82e4ULL,
+ 0x0000000c0181020aULL,
+ 0x0000000c0181030aULL,
+ 0x0000001c000000d4ULL,
+ 0x0000000000004002ULL,
+ 0x0000005000a0410aULL,
+ 0x0000000001004202ULL,
+ 0x000000500021000aULL,
+ 0x0000000000810102ULL,
+ 0x000000500121020aULL,
+ 0x000000200000202aULL,
+ 0x00000000000000fcULL,
+ 0x0000000c000000a4ULL,
+ 0x0000000000000002ULL,
+ 0x0000000600098003ULL,
+ 0x0000000000810002ULL,
+ 0x0000000610898093ULL,
+ 0x0000003760000044ULL,
+ 0x0000000004000002ULL,
+ 0x00000006808b0013ULL,
+ 0x0000000004800102ULL,
+ 0x00000006808b0013ULL,
+ 0x0000000005000202ULL,
+ 0x00000006808b0013ULL,
+ 0x0000000000000034ULL,
+ 0x0000000000000002ULL,
+ 0x000000342000005cULL,
+ 0x000000334000004cULL,
+ 0x0000001000000084ULL,
+ 0x00000006000b0009ULL,
+ 0x00000002000b0101ULL,
+ 0x0000002000000084ULL,
+ 0x00000006000b0009ULL,
+ 0x0000003760000044ULL,
+ 0x0000000000000034ULL,
+ 0x00000034000000d4ULL,
+ 0x0000003420000054ULL,
+ 0x00000038000000d4ULL,
+ 0x00000033e000004cULL,
+ 0x00000031d0000044ULL,
+ 0x00000038000000d4ULL,
+ 0x00000031d0000044ULL,
+ 0x00000034000000d4ULL,
+ 0x00000031d0000044ULL,
+ 0x000000080180000aULL,
+ 0x0000000001820002ULL,
+ 0x00000007040b0013ULL,
+ 0x0000000005840002ULL,
+ 0x00000007040b0013ULL,
+ 0x0000003c000000d4ULL,
+ 0x00000004000000a4ULL,
+ 0x000000200000402aULL,
+ 0x0000000000000012ULL,
+ 0x00000000000b0001ULL,
+ 0x0000000000098101ULL,
+ 0x0000003760000044ULL,
+ 0x000000040200000aULL,
+ 0x000000000000002cULL,
+ 0x0000000c0000400eULL,
+ 0x0000000c0200440aULL,
+ 0x000000080000007cULL,
+ 0x00000036c01f87e4ULL,
+ 0x00000036401f89e4ULL,
+ 0x000000040200000aULL,
+ 0x000000000000002cULL,
+ 0x0000000c0400480eULL,
+ 0x0000000c0200440aULL,
+ 0x000000080000007cULL,
+ 0x00000036a01f86e4ULL,
+ 0x000000080180000aULL,
+ 0x00000036601f84e4ULL,
+ 0x00000036801f85e4ULL,
+ 0x000000300001000aULL,
+ 0x0000003760000044ULL,
+ 0x000000140006800aULL,
+ 0x0000003640000044ULL,
+ 0x000000180006800aULL,
+ 0x0000003640000044ULL,
+ 0x0000000c0000800aULL,
+ 0x0000003640000044ULL,
+ 0x0000000c0181080aULL,
+ 0x0000001c000000d4ULL,
+ 0x00000004000000a4ULL,
+ 0x0000000c0000400aULL,
+ 0x0000003640000044ULL,
+ 0x0000000c0181000aULL,
+ 0x0000001c000000d4ULL,
+ 0x00000004000000a4ULL,
+ 0x000000140001140aULL,
+ 0x0000003640000044ULL,
+ 0x0000000c000000a4ULL,
+ 0x0000000000000044ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL,
+};
+
+#endif /* _NLM_HAL_RSA_UCODE_H_ */
diff --git a/sys/mips/nlm/files.xlp b/sys/mips/nlm/files.xlp
index 682bbbf..69b1d5e 100644
--- a/sys/mips/nlm/files.xlp
+++ b/sys/mips/nlm/files.xlp
@@ -14,3 +14,9 @@ mips/nlm/intern_dev.c optional pci
mips/nlm/uart_pci_xlp.c optional uart
mips/nlm/uart_cpu_xlp.c optional uart
mips/nlm/usb_init.c optional usb
+#
+# Security Driver
+#
+mips/nlm/dev/sec/nlmsec.c optional nlmsec
+mips/nlm/dev/sec/nlmseclib.c optional nlmsec
+mips/nlm/dev/sec/nlmrsa.c optional nlmrsa
diff --git a/sys/mips/nlm/hal/iomap.h b/sys/mips/nlm/hal/iomap.h
index 17d42bd..f2d1dd5 100644
--- a/sys/mips/nlm/hal/iomap.h
+++ b/sys/mips/nlm/hal/iomap.h
@@ -36,6 +36,7 @@
#define NMI_BASE 0xbfc00000
#define XLP_IO_CLK 133333333
+#define XLP_L2L3_CACHELINE_SIZE 64
#define XLP_PCIE_CFG_SIZE 0x1000 /* 4K */
#define XLP_PCIE_DEV_BLK_SIZE (8 * XLP_PCIE_CFG_SIZE)
#define XLP_PCIE_BUS_BLK_SIZE (256 * XLP_PCIE_DEV_BLK_SIZE)
diff --git a/sys/mips/nlm/hal/nlmsaelib.h b/sys/mips/nlm/hal/nlmsaelib.h
new file mode 100644
index 0000000..3d12729
--- /dev/null
+++ b/sys/mips/nlm/hal/nlmsaelib.h
@@ -0,0 +1,607 @@
+/*-
+ * Copyright (c) 2003-2012 Broadcom 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.
+ * 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 BROADCOM ``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 BROADCOM 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$
+ */
+
+#ifndef _NLM_HAL_CRYPTO_H_
+#define _NLM_HAL_CRYPTO_H_
+
+#define SAE_CFG_REG 0x00
+#define SAE_ENG_SEL_0 0x01
+#define SAE_ENG_SEL_1 0x02
+#define SAE_ENG_SEL_2 0x03
+#define SAE_ENG_SEL_3 0x04
+#define SAE_ENG_SEL_4 0x05
+#define SAE_ENG_SEL_5 0x06
+#define SAE_ENG_SEL_6 0x07
+#define SAE_ENG_SEL_7 0x08
+
+#define RSA_CFG_REG 0x00
+#define RSA_ENG_SEL_0 0x01
+#define RSA_ENG_SEL_1 0x02
+#define RSA_ENG_SEL_2 0x03
+
+#define nlm_read_sec_reg(b, r) nlm_read_reg(b, r)
+#define nlm_write_sec_reg(b, r, v) nlm_write_reg(b, r, v)
+#define nlm_get_sec_pcibase(node) nlm_pcicfg_base(XLP_IO_SEC_OFFSET(node))
+#define nlm_get_sec_regbase(node) \
+ (nlm_get_sec_pcibase(node) + XLP_IO_PCI_HDRSZ)
+
+#define nlm_read_rsa_reg(b, r) nlm_read_reg(b, r)
+#define nlm_write_rsa_reg(b, r, v) nlm_write_reg(b, r, v)
+#define nlm_get_rsa_pcibase(node) nlm_pcicfg_base(XLP_IO_RSA_OFFSET(node))
+#define nlm_get_rsa_regbase(node) \
+ (nlm_get_rsa_pcibase(node) + XLP_IO_PCI_HDRSZ)
+
+#define nlm_pcibase_sec(node) nlm_pcicfg_base(XLP_IO_SEC_OFFSET(node))
+#define nlm_qidstart_sec(node) nlm_qidstart_kseg(nlm_pcibase_sec(node))
+#define nlm_qnum_sec(node) nlm_qnum_kseg(nlm_pcibase_sec(node))
+
+/*
+ * Since buffer allocation for crypto at kernel is done as malloc, each
+ * segment size is given as page size which is 4K by default
+ */
+#define NLM_CRYPTO_MAX_SEG_LEN PAGE_SIZE
+
+#define MAX_KEY_LEN_IN_DW 20
+
+#define left_shift64(x, bitshift, numofbits) \
+ ((uint64_t)(x) << (bitshift))
+
+#define left_shift64_mask(x, bitshift, numofbits) \
+ (((uint64_t)(x) & ((1ULL << (numofbits)) - 1)) << (bitshift))
+
+/**
+* @brief cipher algorithms
+* @ingroup crypto
+*/
+enum nlm_cipher_algo {
+ NLM_CIPHER_BYPASS = 0,
+ NLM_CIPHER_DES = 1,
+ NLM_CIPHER_3DES = 2,
+ NLM_CIPHER_AES128 = 3,
+ NLM_CIPHER_AES192 = 4,
+ NLM_CIPHER_AES256 = 5,
+ NLM_CIPHER_ARC4 = 6,
+ NLM_CIPHER_KASUMI_F8 = 7,
+ NLM_CIPHER_SNOW3G_F8 = 8,
+ NLM_CIPHER_CAMELLIA128 = 9,
+ NLM_CIPHER_CAMELLIA192 = 0xA,
+ NLM_CIPHER_CAMELLIA256 = 0xB,
+ NLM_CIPHER_MAX = 0xC,
+};
+
+/**
+* @brief cipher modes
+* @ingroup crypto
+*/
+enum nlm_cipher_mode {
+ NLM_CIPHER_MODE_ECB = 0,
+ NLM_CIPHER_MODE_CBC = 1,
+ NLM_CIPHER_MODE_CFB = 2,
+ NLM_CIPHER_MODE_OFB = 3,
+ NLM_CIPHER_MODE_CTR = 4,
+ NLM_CIPHER_MODE_AES_F8 = 5,
+ NLM_CIPHER_MODE_GCM = 6,
+ NLM_CIPHER_MODE_CCM = 7,
+ NLM_CIPHER_MODE_UNDEFINED1 = 8,
+ NLM_CIPHER_MODE_UNDEFINED2 = 9,
+ NLM_CIPHER_MODE_LRW = 0xA,
+ NLM_CIPHER_MODE_XTS = 0xB,
+ NLM_CIPHER_MODE_MAX = 0xC,
+};
+
+/**
+* @brief hash algorithms
+* @ingroup crypto
+*/
+enum nlm_hash_algo {
+ NLM_HASH_BYPASS = 0,
+ NLM_HASH_MD5 = 1,
+ NLM_HASH_SHA = 2,
+ NLM_HASH_UNDEFINED = 3,
+ NLM_HASH_AES128 = 4,
+ NLM_HASH_AES192 = 5,
+ NLM_HASH_AES256 = 6,
+ NLM_HASH_KASUMI_F9 = 7,
+ NLM_HASH_SNOW3G_F9 = 8,
+ NLM_HASH_CAMELLIA128 = 9,
+ NLM_HASH_CAMELLIA192 = 0xA,
+ NLM_HASH_CAMELLIA256 = 0xB,
+ NLM_HASH_GHASH = 0xC,
+ NLM_HASH_MAX = 0xD
+};
+
+/**
+* @brief hash modes
+* @ingroup crypto
+*/
+enum nlm_hash_mode {
+ NLM_HASH_MODE_SHA1 = 0, /* Only SHA */
+ NLM_HASH_MODE_SHA224 = 1, /* Only SHA */
+ NLM_HASH_MODE_SHA256 = 2, /* Only SHA */
+ NLM_HASH_MODE_SHA384 = 3, /* Only SHA */
+ NLM_HASH_MODE_SHA512 = 4, /* Only SHA */
+ NLM_HASH_MODE_CMAC = 5, /* AES and Camellia */
+ NLM_HASH_MODE_XCBC = 6, /* AES and Camellia */
+ NLM_HASH_MODE_CBC_MAC = 7, /* AES and Camellia */
+ NLM_HASH_MODE_CCM = 8, /* AES */
+ NLM_HASH_MODE_GCM = 9, /* AES */
+ NLM_HASH_MODE_MAX = 0xA,
+};
+
+/**
+* @brief crypto control descriptor, should be cache aligned
+* @ingroup crypto
+*/
+struct nlm_crypto_pkt_ctrl {
+ uint64_t desc0;
+ /* combination of cipher and hash keys */
+ uint64_t key[MAX_KEY_LEN_IN_DW];
+ uint32_t cipherkeylen;
+ uint32_t hashkeylen;
+ uint32_t taglen;
+};
+
+/**
+* @brief crypto packet descriptor, should be cache aligned
+* @ingroup crypto
+*/
+struct nlm_crypto_pkt_param {
+ uint64_t desc0;
+ uint64_t desc1;
+ uint64_t desc2;
+ uint64_t desc3;
+ uint64_t segment[1][2];
+};
+
+static __inline__ uint64_t
+nlm_crypto_form_rsa_ecc_fmn_entry0(unsigned int l3alloc, unsigned int type,
+ unsigned int func, uint64_t srcaddr)
+{
+ return (left_shift64(l3alloc, 61, 1) |
+ left_shift64(type, 46, 7) |
+ left_shift64(func, 40, 6) |
+ left_shift64(srcaddr, 0, 40));
+}
+
+static __inline__ uint64_t
+nlm_crypto_form_rsa_ecc_fmn_entry1(unsigned int dstclobber,
+ unsigned int l3alloc, unsigned int fbvc, uint64_t dstaddr)
+{
+ return (left_shift64(dstclobber, 62, 1) |
+ left_shift64(l3alloc, 61, 1) |
+ left_shift64(fbvc, 40, 12) |
+ left_shift64(dstaddr, 0, 40));
+}
+
+/**
+* @brief Generate cypto control descriptor
+* @ingroup crypto
+* hmac : 1 for hash with hmac
+* hashalg, see hash_alg enums
+* hashmode, see hash_mode enums
+* cipherhalg, see cipher_alg enums
+* ciphermode, see cipher_mode enums
+* arc4_cipherkeylen : length of arc4 cipher key, 0 is interpreted as 32
+* arc4_keyinit :
+* cfbmask : cipher text for feedback,
+* 0(1 bit), 1(2 bits), 2(4 bits), 3(8 bits), 4(16bits), 5(32 bits),
+* 6(64 bits), 7(128 bits)
+*/
+static __inline__ uint64_t
+nlm_crypto_form_pkt_ctrl_desc(unsigned int hmac, unsigned int hashalg,
+ unsigned int hashmode, unsigned int cipheralg, unsigned int ciphermode,
+ unsigned int arc4_cipherkeylen, unsigned int arc4_keyinit,
+ unsigned int cfbmask)
+{
+ return (left_shift64(hmac, 61, 1) |
+ left_shift64(hashalg, 52, 8) |
+ left_shift64(hashmode, 43, 8) |
+ left_shift64(cipheralg, 34, 8) |
+ left_shift64(ciphermode, 25, 8) |
+ left_shift64(arc4_cipherkeylen, 18, 5) |
+ left_shift64(arc4_keyinit, 17, 1) |
+ left_shift64(cfbmask, 0, 3));
+}
+/**
+* @brief Generate cypto packet descriptor 0
+* @ingroup crypto
+* tls : 1 (tls enabled) 0(tls disabled)
+* hash_source : 1 (encrypted data is sent to the auth engine)
+* 0 (plain data is sent to the auth engine)
+* hashout_l3alloc : 1 (auth output is transited through l3 cache)
+* encrypt : 1 (for encrypt) 0 (for decrypt)
+* ivlen : iv length in bytes
+* hashdst_addr : hash out physical address, byte aligned
+*/
+static __inline__ uint64_t
+nlm_crypto_form_pkt_desc0(unsigned int tls, unsigned int hash_source,
+ unsigned int hashout_l3alloc, unsigned int encrypt, unsigned int ivlen,
+ uint64_t hashdst_addr)
+{
+ return (left_shift64(tls, 63, 1) |
+ left_shift64(hash_source, 62, 1) |
+ left_shift64(hashout_l3alloc, 60, 1) |
+ left_shift64(encrypt, 59, 1) |
+ left_shift64_mask((ivlen - 1), 41, 16) |
+ left_shift64(hashdst_addr, 0, 40));
+}
+
+/**
+* @brief Generate cypto packet descriptor 1
+* @ingroup crypto
+* cipherlen : cipher length in bytes
+* hashlen : hash length in bytes
+*/
+static __inline__ uint64_t
+nlm_crypto_form_pkt_desc1(unsigned int cipherlen, unsigned int hashlen)
+{
+ return (left_shift64_mask((cipherlen - 1), 32, 32) |
+ left_shift64_mask((hashlen - 1), 0, 32));
+}
+
+/**
+* @brief Generate cypto packet descriptor 2
+* @ingroup crypto
+* ivoff : iv offset, offset from start of src data addr
+* ciperbit_cnt : number of valid bits in the last input byte to the cipher,
+* 0 (8 bits), 1 (1 bit)..7 (7 bits)
+* cipheroff : cipher offset, offset from start of src data addr
+* hashbit_cnt : number of valid bits in the last input byte to the auth
+* 0 (8 bits), 1 (1 bit)..7 (7 bits)
+* hashclobber : 1 (hash output will be written as multiples of cachelines, no
+* read modify write)
+* hashoff : hash offset, offset from start of src data addr
+*/
+
+static __inline__ uint64_t
+nlm_crypto_form_pkt_desc2(unsigned int ivoff, unsigned int cipherbit_cnt,
+ unsigned int cipheroff, unsigned int hashbit_cnt, unsigned int hashclobber,
+ unsigned int hashoff)
+{
+ return (left_shift64(ivoff , 45, 16) |
+ left_shift64(cipherbit_cnt, 42, 3) |
+ left_shift64(cipheroff, 22, 16) |
+ left_shift64(hashbit_cnt, 19, 3) |
+ left_shift64(hashclobber, 18, 1) |
+ left_shift64(hashoff, 0, 16));
+}
+
+/**
+* @brief Generate cypto packet descriptor 3
+* @ingroup crypto
+* designer_vc : designer freeback fmn destination id
+* taglen : length in bits of the tag generated by the auth engine
+* md5 (128 bits), sha1 (160), sha224 (224), sha384 (384),
+* sha512 (512), Kasumi (32), snow3g (32), gcm (128)
+* hmacpad : 1 if hmac padding is already done
+*/
+static __inline__ uint64_t
+nlm_crypto_form_pkt_desc3(unsigned int designer_vc, unsigned int taglen,
+ unsigned int arc4_state_save_l3, unsigned int arc4_save_state,
+ unsigned int hmacpad)
+{
+ return (left_shift64(designer_vc, 48, 16) |
+ left_shift64(taglen, 11, 16) |
+ left_shift64(arc4_state_save_l3, 8, 1) |
+ left_shift64(arc4_save_state, 6, 1) |
+ left_shift64(hmacpad, 5, 1));
+}
+
+/**
+* @brief Generate cypto packet descriptor 4
+* @ingroup crypto
+* srcfraglen : length of the source fragment(header + data + tail) in bytes
+* srcfragaddr : physical address of the srouce fragment
+*/
+static __inline__ uint64_t
+nlm_crypto_form_pkt_desc4(uint64_t srcfraglen,
+ unsigned int srcfragaddr )
+{
+ return (left_shift64_mask((srcfraglen - 1), 48, 16) |
+ left_shift64(srcfragaddr, 0, 40));
+}
+
+/**
+* @brief Generate cypto packet descriptor 5
+* @ingroup crypto
+* dstfraglen : length of the dst fragment(header + data + tail) in bytes
+* chipherout_l3alloc : 1(cipher output is transited through l3 cache)
+* cipherclobber : 1 (cipher output will be written as multiples of cachelines,
+* no read modify write)
+* chiperdst_addr : physical address of the cipher destination address
+*/
+static __inline__ uint64_t
+nlm_crypto_form_pkt_desc5(unsigned int dstfraglen,
+ unsigned int cipherout_l3alloc, unsigned int cipherclobber,
+ uint64_t cipherdst_addr)
+
+{
+ return (left_shift64_mask((dstfraglen - 1), 48, 16) |
+ left_shift64(cipherout_l3alloc, 46, 1) |
+ left_shift64(cipherclobber, 41, 1) |
+ left_shift64(cipherdst_addr, 0, 40));
+}
+
+/**
+ * @brief Generate crypto packet fmn message entry 0
+ * @ingroup crypto
+ * freeback_vc: freeback response destination address
+ * designer_fblen : Designer freeback length, 1 - 4
+ * designerdesc_valid : designer desc valid or not
+ * cipher_keylen : cipher key length in bytes
+ * ctrldesc_addr : physicall address of the control descriptor
+ */
+static __inline__ uint64_t
+nlm_crypto_form_pkt_fmn_entry0(unsigned int freeback_vc,
+ unsigned int designer_fblen, unsigned int designerdesc_valid,
+ unsigned int cipher_keylen, uint64_t cntldesc_addr)
+{
+ return (left_shift64(freeback_vc, 48, 16) |
+ left_shift64_mask(designer_fblen - 1, 46, 2) |
+ left_shift64(designerdesc_valid, 45, 1) |
+ left_shift64_mask(((cipher_keylen + 7) >> 3), 40, 5) |
+ left_shift64(cntldesc_addr >> 6, 0, 34));
+}
+
+/**
+ * @brief Generate crypto packet fmn message entry 1
+ * @ingroup crypto
+ * arc4load_state : 1 if load state required 0 otherwise
+ * hash_keylen : hash key length in bytes
+ * pktdesc_size : packet descriptor size in bytes
+ * pktdesc_addr : physicall address of the packet descriptor
+ */
+static __inline__ uint64_t
+nlm_crypto_form_pkt_fmn_entry1(unsigned int arc4load_state,
+ unsigned int hash_keylen, unsigned int pktdesc_size,
+ uint64_t pktdesc_addr)
+{
+ return (left_shift64(arc4load_state, 63, 1) |
+ left_shift64_mask(((hash_keylen + 7) >> 3), 56, 5) |
+ left_shift64_mask(((pktdesc_size >> 4) - 1), 43, 12) |
+ left_shift64(pktdesc_addr >> 6, 0, 34));
+}
+
+static __inline__ int
+nlm_crypto_get_hklen_taglen(enum nlm_hash_algo hashalg,
+ enum nlm_hash_mode hashmode, unsigned int *taglen, unsigned int *hklen)
+{
+ if (hashalg == NLM_HASH_MD5) {
+ *taglen = 128;
+ *hklen = 64;
+ } else if (hashalg == NLM_HASH_SHA) {
+ switch (hashmode) {
+ case NLM_HASH_MODE_SHA1:
+ *taglen = 160;
+ *hklen = 64;
+ break;
+ case NLM_HASH_MODE_SHA224:
+ *taglen = 224;
+ *hklen = 64;
+ break;
+ case NLM_HASH_MODE_SHA256:
+ *taglen = 256;
+ *hklen = 64;
+ break;
+ case NLM_HASH_MODE_SHA384:
+ *taglen = 384;
+ *hklen = 128;
+ break;
+ case NLM_HASH_MODE_SHA512:
+ *taglen = 512;
+ *hklen = 128;
+ break;
+ default:
+ printf("Error : invalid shaid (%s)\n", __func__);
+ return (-1);
+ }
+ } else if (hashalg == NLM_HASH_KASUMI_F9) {
+ *taglen = 32;
+ *hklen = 0;
+ } else if (hashalg == NLM_HASH_SNOW3G_F9) {
+ *taglen = 32;
+ *hklen = 0;
+ } else if (hashmode == NLM_HASH_MODE_XCBC) {
+ *taglen = 128;
+ *hklen = 0;
+ } else if (hashmode == NLM_HASH_MODE_GCM) {
+ *taglen = 128;
+ *hklen = 0;
+ } else if (hashalg == NLM_HASH_BYPASS) {
+ *taglen = 0;
+ *hklen = 0;
+ } else {
+ printf("Error:Hash alg/mode not found\n");
+ return (-1);
+ }
+
+ /* TODO : Add remaining cases */
+ return (0);
+}
+
+/**
+* @brief Generate fill cryto control info structure
+* @ingroup crypto
+* hmac : 1 for hash with hmac
+* hashalg: see above, hash_alg enums
+* hashmode: see above, hash_mode enums
+* cipherhalg: see above, cipher_alg enums
+* ciphermode: see above, cipher_mode enums
+*
+*/
+static __inline__ int
+nlm_crypto_fill_pkt_ctrl(struct nlm_crypto_pkt_ctrl *ctrl, unsigned int hmac,
+ enum nlm_hash_algo hashalg, enum nlm_hash_mode hashmode,
+ enum nlm_cipher_algo cipheralg, enum nlm_cipher_mode ciphermode,
+ unsigned char *cipherkey, unsigned int cipherkeylen,
+ unsigned char *hashkey, unsigned int hashkeylen)
+{
+ unsigned int taglen = 0, hklen = 0;
+
+ ctrl->desc0 = nlm_crypto_form_pkt_ctrl_desc(hmac, hashalg, hashmode,
+ cipheralg, ciphermode, 0, 0, 0);
+ memset(ctrl->key, 0, sizeof(ctrl->key));
+ if (cipherkey)
+ memcpy(ctrl->key, cipherkey, cipherkeylen);
+ if (hashkey)
+ memcpy((unsigned char *)&ctrl->key[(cipherkeylen + 7) / 8],
+ hashkey, hashkeylen);
+ if (nlm_crypto_get_hklen_taglen(hashalg, hashmode, &taglen, &hklen)
+ < 0)
+ return (-1);
+
+ ctrl->cipherkeylen = cipherkeylen;
+ ctrl->hashkeylen = hklen;
+ ctrl->taglen = taglen;
+
+ /* TODO : add the invalid checks and return error */
+ return (0);
+}
+
+/**
+* @brief Top level function for generation pkt desc 0 to 3 for cipher auth
+* @ingroup crypto
+* ctrl : pointer to control structure
+* param : pointer to the param structure
+* encrypt : 1(for encrypt) 0(for decrypt)
+* hash_source : 1(encrypted data is sent to the auth engine) 0(plain data is
+* sent to the auth engine)
+* ivoff : iv offset from start of data
+* ivlen : iv length in bytes
+* hashoff : hash offset from start of data
+* hashlen : hash length in bytes
+* hmacpad : hmac padding required or not, 1 if already padded
+* cipheroff : cipher offset from start of data
+* cipherlen : cipher length in bytes
+* hashdst_addr : hash destination physical address
+*/
+static __inline__ void
+nlm_crypto_fill_cipher_auth_pkt_param(struct nlm_crypto_pkt_ctrl *ctrl,
+ struct nlm_crypto_pkt_param *param, unsigned int encrypt,
+ unsigned int hash_source, unsigned int ivoff, unsigned int ivlen,
+ unsigned int hashoff, unsigned int hashlen, unsigned int hmacpad,
+ unsigned int cipheroff, unsigned int cipherlen, unsigned char *hashdst_addr)
+{
+ param->desc0 = nlm_crypto_form_pkt_desc0(0, hash_source, 1, encrypt,
+ ivlen, vtophys(hashdst_addr));
+ param->desc1 = nlm_crypto_form_pkt_desc1(cipherlen, hashlen);
+ param->desc2 = nlm_crypto_form_pkt_desc2(ivoff, 0, cipheroff, 0, 0,
+ hashoff);
+ param->desc3 = nlm_crypto_form_pkt_desc3(0, ctrl->taglen, 0, 0,
+ hmacpad);
+}
+
+/**
+* @brief Top level function for generation pkt desc 0 to 3 for cipher operation
+* @ingroup crypto
+* ctrl : pointer to control structure
+* param : pointer to the param structure
+* encrypt : 1(for encrypt) 0(for decrypt)
+* ivoff : iv offset from start of data
+* ivlen : iv length in bytes
+* cipheroff : cipher offset from start of data
+* cipherlen : cipher length in bytes
+*/
+
+
+static __inline__ void
+nlm_crypto_fill_cipher_pkt_param(struct nlm_crypto_pkt_ctrl *ctrl,
+ struct nlm_crypto_pkt_param *param, unsigned int encrypt,
+ unsigned int ivoff, unsigned int ivlen, unsigned int cipheroff,
+ unsigned int cipherlen)
+{
+ param->desc0 = nlm_crypto_form_pkt_desc0(0, 0, 0, encrypt, ivlen, 0ULL);
+ param->desc1 = nlm_crypto_form_pkt_desc1(cipherlen, 1);
+ param->desc2 = nlm_crypto_form_pkt_desc2(ivoff, 0, cipheroff, 0, 0, 0);
+ param->desc3 = nlm_crypto_form_pkt_desc3(0, ctrl->taglen, 0, 0, 0);
+}
+
+/**
+* @brief Top level function for generation pkt desc 0 to 3 for auth operation
+* @ingroup crypto
+* ctrl : pointer to control structure
+* param : pointer to the param structure
+* hashoff : hash offset from start of data
+* hashlen : hash length in bytes
+* hmacpad : hmac padding required or not, 1 if already padded
+* hashdst_addr : hash destination physical address
+*/
+static __inline__ void
+nlm_crypto_fill_auth_pkt_param(struct nlm_crypto_pkt_ctrl *ctrl,
+ struct nlm_crypto_pkt_param *param, unsigned int hashoff,
+ unsigned int hashlen, unsigned int hmacpad, unsigned char *hashdst_addr)
+{
+ param->desc0 = nlm_crypto_form_pkt_desc0(0, 0, 1, 0, 1,
+ vtophys(hashdst_addr));
+ param->desc1 = nlm_crypto_form_pkt_desc1(1, hashlen);
+ param->desc2 = nlm_crypto_form_pkt_desc2(0, 0, 0, 0, 0, hashoff);
+ param->desc3 = nlm_crypto_form_pkt_desc3(0, ctrl->taglen, 0, 0,
+ hmacpad);
+}
+
+static __inline__ unsigned int
+nlm_crypto_fill_src_seg(struct nlm_crypto_pkt_param *param, int seg,
+ unsigned char *input, unsigned int inlen)
+{
+ unsigned off = 0, len = 0;
+ unsigned int remlen = inlen;
+
+ for (; remlen > 0;) {
+ len = remlen > NLM_CRYPTO_MAX_SEG_LEN ?
+ NLM_CRYPTO_MAX_SEG_LEN : remlen;
+ param->segment[seg][0] = nlm_crypto_form_pkt_desc4(len,
+ vtophys(input + off));
+ remlen -= len;
+ off += len;
+ seg++;
+ }
+ return (seg);
+}
+
+static __inline__ unsigned int
+nlm_crypto_fill_dst_seg(struct nlm_crypto_pkt_param *param,
+ int seg, unsigned char *output, unsigned int outlen)
+{
+ unsigned off = 0, len = 0;
+ unsigned int remlen = outlen;
+
+ for (; remlen > 0;) {
+ len = remlen > NLM_CRYPTO_MAX_SEG_LEN ?
+ NLM_CRYPTO_MAX_SEG_LEN : remlen;
+ param->segment[seg][1] = nlm_crypto_form_pkt_desc5(len, 1, 0,
+ vtophys(output + off));
+ remlen -= len;
+ off += len;
+ seg++;
+ }
+ return (seg);
+}
+
+#endif
OpenPOWER on IntegriCloud