diff options
-rw-r--r-- | sys/mips/conf/std.XLP | 10 | ||||
-rw-r--r-- | sys/mips/nlm/dev/sec/nlmrsa.c | 556 | ||||
-rw-r--r-- | sys/mips/nlm/dev/sec/nlmrsalib.h | 68 | ||||
-rw-r--r-- | sys/mips/nlm/dev/sec/nlmsec.c | 850 | ||||
-rw-r--r-- | sys/mips/nlm/dev/sec/nlmseclib.c | 307 | ||||
-rw-r--r-- | sys/mips/nlm/dev/sec/nlmseclib.h | 157 | ||||
-rw-r--r-- | sys/mips/nlm/dev/sec/rsa_ucode.h | 956 | ||||
-rw-r--r-- | sys/mips/nlm/files.xlp | 6 | ||||
-rw-r--r-- | sys/mips/nlm/hal/iomap.h | 1 | ||||
-rw-r--r-- | sys/mips/nlm/hal/nlmsaelib.h | 607 |
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 |