The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/glxsb/glxsb.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $OpenBSD: glxsb.c,v 1.7 2007/02/12 14:31:45 tom Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2006 Tom Cosgrove <tom@openbsd.org>
    5  * Copyright (c) 2003, 2004 Theo de Raadt
    6  * Copyright (c) 2003 Jason Wright
    7  *
    8  * Permission to use, copy, modify, and distribute this software for any
    9  * purpose with or without fee is hereby granted, provided that the above
   10  * copyright notice and this permission notice appear in all copies.
   11  *
   12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   19  */
   20 
   21 /*
   22  * Driver for the security block on the AMD Geode LX processors
   23  * http://www.amd.com/files/connectivitysolutions/geode/geode_lx/33234d_lx_ds.pdf
   24  */
   25 
   26 #include <sys/cdefs.h>
   27 __FBSDID("$FreeBSD: releng/8.4/sys/dev/glxsb/glxsb.c 233025 2012-03-16 09:22:59Z scottl $");
   28 
   29 #include <sys/param.h>
   30 #include <sys/systm.h>
   31 #include <sys/bus.h>
   32 #include <sys/errno.h>
   33 #include <sys/kernel.h>
   34 #include <sys/lock.h>
   35 #include <sys/malloc.h>
   36 #include <sys/mbuf.h>
   37 #include <sys/module.h>
   38 #include <sys/mutex.h>
   39 #include <sys/proc.h>
   40 #include <sys/random.h>
   41 #include <sys/rman.h>
   42 #include <sys/rwlock.h>
   43 #include <sys/sysctl.h>
   44 #include <sys/taskqueue.h>
   45 
   46 #include <machine/bus.h>
   47 #include <machine/cpufunc.h>
   48 #include <machine/resource.h>
   49 
   50 #include <dev/pci/pcivar.h>
   51 #include <dev/pci/pcireg.h>
   52 
   53 #include <opencrypto/cryptodev.h>
   54 #include <opencrypto/cryptosoft.h>
   55 #include <opencrypto/xform.h>
   56 
   57 #include "cryptodev_if.h"
   58 #include "glxsb.h"
   59 
   60 #define PCI_VENDOR_AMD                  0x1022  /* AMD */
   61 #define PCI_PRODUCT_AMD_GEODE_LX_CRYPTO 0x2082  /* Geode LX Crypto */
   62 
   63 #define SB_GLD_MSR_CAP          0x58002000      /* RO - Capabilities */
   64 #define SB_GLD_MSR_CONFIG       0x58002001      /* RW - Master Config */
   65 #define SB_GLD_MSR_SMI          0x58002002      /* RW - SMI */
   66 #define SB_GLD_MSR_ERROR        0x58002003      /* RW - Error */
   67 #define SB_GLD_MSR_PM           0x58002004      /* RW - Power Mgmt */
   68 #define SB_GLD_MSR_DIAG         0x58002005      /* RW - Diagnostic */
   69 #define SB_GLD_MSR_CTRL         0x58002006      /* RW - Security Block Cntrl */
   70 
   71                                                 /* For GLD_MSR_CTRL: */
   72 #define SB_GMC_DIV0             0x0000          /* AES update divisor values */
   73 #define SB_GMC_DIV1             0x0001
   74 #define SB_GMC_DIV2             0x0002
   75 #define SB_GMC_DIV3             0x0003
   76 #define SB_GMC_DIV_MASK         0x0003
   77 #define SB_GMC_SBI              0x0004          /* AES swap bits */
   78 #define SB_GMC_SBY              0x0008          /* AES swap bytes */
   79 #define SB_GMC_TW               0x0010          /* Time write (EEPROM) */
   80 #define SB_GMC_T_SEL0           0x0000          /* RNG post-proc: none */
   81 #define SB_GMC_T_SEL1           0x0100          /* RNG post-proc: LFSR */
   82 #define SB_GMC_T_SEL2           0x0200          /* RNG post-proc: whitener */
   83 #define SB_GMC_T_SEL3           0x0300          /* RNG LFSR+whitener */
   84 #define SB_GMC_T_SEL_MASK       0x0300
   85 #define SB_GMC_T_NE             0x0400          /* Noise (generator) Enable */
   86 #define SB_GMC_T_TM             0x0800          /* RNG test mode */
   87                                                 /*     (deterministic) */
   88 
   89 /* Security Block configuration/control registers (offsets from base) */
   90 #define SB_CTL_A                0x0000          /* RW - SB Control A */
   91 #define SB_CTL_B                0x0004          /* RW - SB Control B */
   92 #define SB_AES_INT              0x0008          /* RW - SB AES Interrupt */
   93 #define SB_SOURCE_A             0x0010          /* RW - Source A */
   94 #define SB_DEST_A               0x0014          /* RW - Destination A */
   95 #define SB_LENGTH_A             0x0018          /* RW - Length A */
   96 #define SB_SOURCE_B             0x0020          /* RW - Source B */
   97 #define SB_DEST_B               0x0024          /* RW - Destination B */
   98 #define SB_LENGTH_B             0x0028          /* RW - Length B */
   99 #define SB_WKEY                 0x0030          /* WO - Writable Key 0-3 */
  100 #define SB_WKEY_0               0x0030          /* WO - Writable Key 0 */
  101 #define SB_WKEY_1               0x0034          /* WO - Writable Key 1 */
  102 #define SB_WKEY_2               0x0038          /* WO - Writable Key 2 */
  103 #define SB_WKEY_3               0x003C          /* WO - Writable Key 3 */
  104 #define SB_CBC_IV               0x0040          /* RW - CBC IV 0-3 */
  105 #define SB_CBC_IV_0             0x0040          /* RW - CBC IV 0 */
  106 #define SB_CBC_IV_1             0x0044          /* RW - CBC IV 1 */
  107 #define SB_CBC_IV_2             0x0048          /* RW - CBC IV 2 */
  108 #define SB_CBC_IV_3             0x004C          /* RW - CBC IV 3 */
  109 #define SB_RANDOM_NUM           0x0050          /* RW - Random Number */
  110 #define SB_RANDOM_NUM_STATUS    0x0054          /* RW - Random Number Status */
  111 #define SB_EEPROM_COMM          0x0800          /* RW - EEPROM Command */
  112 #define SB_EEPROM_ADDR          0x0804          /* RW - EEPROM Address */
  113 #define SB_EEPROM_DATA          0x0808          /* RW - EEPROM Data */
  114 #define SB_EEPROM_SEC_STATE     0x080C          /* RW - EEPROM Security State */
  115 
  116                                                 /* For SB_CTL_A and _B */
  117 #define SB_CTL_ST               0x0001          /* Start operation (enc/dec) */
  118 #define SB_CTL_ENC              0x0002          /* Encrypt (0 is decrypt) */
  119 #define SB_CTL_DEC              0x0000          /* Decrypt */
  120 #define SB_CTL_WK               0x0004          /* Use writable key (we set) */
  121 #define SB_CTL_DC               0x0008          /* Destination coherent */
  122 #define SB_CTL_SC               0x0010          /* Source coherent */
  123 #define SB_CTL_CBC              0x0020          /* CBC (0 is ECB) */
  124 
  125                                                 /* For SB_AES_INT */
  126 #define SB_AI_DISABLE_AES_A     0x0001          /* Disable AES A compl int */
  127 #define SB_AI_ENABLE_AES_A      0x0000          /* Enable AES A compl int */
  128 #define SB_AI_DISABLE_AES_B     0x0002          /* Disable AES B compl int */
  129 #define SB_AI_ENABLE_AES_B      0x0000          /* Enable AES B compl int */
  130 #define SB_AI_DISABLE_EEPROM    0x0004          /* Disable EEPROM op comp int */
  131 #define SB_AI_ENABLE_EEPROM     0x0000          /* Enable EEPROM op compl int */
  132 #define SB_AI_AES_A_COMPLETE   0x10000          /* AES A operation complete */
  133 #define SB_AI_AES_B_COMPLETE   0x20000          /* AES B operation complete */
  134 #define SB_AI_EEPROM_COMPLETE  0x40000          /* EEPROM operation complete */
  135 
  136 #define SB_AI_CLEAR_INTR \
  137         (SB_AI_DISABLE_AES_A | SB_AI_DISABLE_AES_B |\
  138         SB_AI_DISABLE_EEPROM | SB_AI_AES_A_COMPLETE |\
  139         SB_AI_AES_B_COMPLETE | SB_AI_EEPROM_COMPLETE)
  140 
  141 #define SB_RNS_TRNG_VALID       0x0001          /* in SB_RANDOM_NUM_STATUS */
  142 
  143 #define SB_MEM_SIZE             0x0810          /* Size of memory block */
  144 
  145 #define SB_AES_ALIGN            0x0010          /* Source and dest buffers */
  146                                                 /* must be 16-byte aligned */
  147 #define SB_AES_BLOCK_SIZE       0x0010
  148 
  149 /*
  150  * The Geode LX security block AES acceleration doesn't perform scatter-
  151  * gather: it just takes source and destination addresses.  Therefore the
  152  * plain- and ciphertexts need to be contiguous.  To this end, we allocate
  153  * a buffer for both, and accept the overhead of copying in and out.  If
  154  * the number of bytes in one operation is bigger than allowed for by the
  155  * buffer (buffer is twice the size of the max length, as it has both input
  156  * and output) then we have to perform multiple encryptions/decryptions.
  157  */
  158 
  159 #define GLXSB_MAX_AES_LEN       16384
  160 
  161 MALLOC_DEFINE(M_GLXSB, "glxsb_data", "Glxsb Data");
  162 
  163 struct glxsb_dma_map {
  164         bus_dmamap_t            dma_map;        /* DMA map */
  165         bus_dma_segment_t       dma_seg;        /* segments */
  166         int                     dma_nsegs;      /* #segments */
  167         int                     dma_size;       /* size */
  168         caddr_t                 dma_vaddr;      /* virtual address */
  169         bus_addr_t              dma_paddr;      /* physical address */
  170 };
  171 
  172 struct glxsb_taskop {
  173         struct glxsb_session    *to_ses;        /* crypto session */
  174         struct cryptop          *to_crp;        /* cryptop to perfom */
  175         struct cryptodesc       *to_enccrd;     /* enccrd to perform */
  176         struct cryptodesc       *to_maccrd;     /* maccrd to perform */
  177 };
  178 
  179 struct glxsb_softc {
  180         device_t                sc_dev;         /* device backpointer */
  181         struct resource         *sc_sr;         /* resource */
  182         int                     sc_rid;         /* resource rid */
  183         struct callout          sc_rngco;       /* RNG callout */
  184         int                     sc_rnghz;       /* RNG callout ticks */
  185         bus_dma_tag_t           sc_dmat;        /* DMA tag */
  186         struct glxsb_dma_map    sc_dma;         /* DMA map */
  187         int32_t                 sc_cid;         /* crypto tag */
  188         uint32_t                sc_sid;         /* session id */
  189         TAILQ_HEAD(ses_head, glxsb_session)
  190                                 sc_sessions;    /* crypto sessions */
  191         struct rwlock           sc_sessions_lock;/* sessions lock */
  192         struct mtx              sc_task_mtx;    /* task mutex */
  193         struct taskqueue        *sc_tq;         /* task queue */
  194         struct task             sc_cryptotask;  /* task */
  195         struct glxsb_taskop     sc_to;          /* task's crypto operation */
  196         int                     sc_task_count;  /* tasks count */
  197 };
  198 
  199 static int glxsb_probe(device_t);
  200 static int glxsb_attach(device_t);
  201 static int glxsb_detach(device_t);
  202 
  203 static void glxsb_dmamap_cb(void *, bus_dma_segment_t *, int, int);
  204 static int  glxsb_dma_alloc(struct glxsb_softc *);
  205 static void glxsb_dma_pre_op(struct glxsb_softc *, struct glxsb_dma_map *);
  206 static void glxsb_dma_post_op(struct glxsb_softc *, struct glxsb_dma_map *);
  207 static void glxsb_dma_free(struct glxsb_softc *, struct glxsb_dma_map *);
  208 
  209 static void glxsb_rnd(void *);
  210 static int  glxsb_crypto_setup(struct glxsb_softc *);
  211 static int  glxsb_crypto_newsession(device_t, uint32_t *, struct cryptoini *);
  212 static int  glxsb_crypto_freesession(device_t, uint64_t);
  213 static int  glxsb_aes(struct glxsb_softc *, uint32_t, uint32_t,
  214         uint32_t, void *, int, void *);
  215 
  216 static int  glxsb_crypto_encdec(struct cryptop *, struct cryptodesc *,
  217         struct glxsb_session *, struct glxsb_softc *);
  218 
  219 static void glxsb_crypto_task(void *, int);
  220 static int  glxsb_crypto_process(device_t, struct cryptop *, int);
  221 
  222 static device_method_t glxsb_methods[] = {
  223         /* device interface */
  224         DEVMETHOD(device_probe,         glxsb_probe),
  225         DEVMETHOD(device_attach,        glxsb_attach),
  226         DEVMETHOD(device_detach,        glxsb_detach),
  227 
  228         /* crypto device methods */
  229         DEVMETHOD(cryptodev_newsession,         glxsb_crypto_newsession),
  230         DEVMETHOD(cryptodev_freesession,        glxsb_crypto_freesession),
  231         DEVMETHOD(cryptodev_process,            glxsb_crypto_process),
  232 
  233         {0,0}
  234 };
  235 
  236 static driver_t glxsb_driver = {
  237         "glxsb",
  238         glxsb_methods,
  239         sizeof(struct glxsb_softc)
  240 };
  241 
  242 static devclass_t glxsb_devclass;
  243 
  244 DRIVER_MODULE(glxsb, pci, glxsb_driver, glxsb_devclass, 0, 0);
  245 MODULE_VERSION(glxsb, 1);
  246 MODULE_DEPEND(glxsb, crypto, 1, 1, 1);
  247 
  248 static int
  249 glxsb_probe(device_t dev)
  250 {
  251 
  252         if (pci_get_vendor(dev) == PCI_VENDOR_AMD &&
  253             pci_get_device(dev) == PCI_PRODUCT_AMD_GEODE_LX_CRYPTO) {
  254                 device_set_desc(dev,
  255                     "AMD Geode LX Security Block (AES-128-CBC, RNG)");
  256                 return (BUS_PROBE_DEFAULT);
  257         }
  258 
  259         return (ENXIO);
  260 }
  261 
  262 static int
  263 glxsb_attach(device_t dev)
  264 {
  265         struct glxsb_softc *sc = device_get_softc(dev);
  266         uint64_t msr;
  267 
  268         sc->sc_dev = dev;
  269         msr = rdmsr(SB_GLD_MSR_CAP);
  270 
  271         if ((msr & 0xFFFF00) != 0x130400) {
  272                 device_printf(dev, "unknown ID 0x%x\n",
  273                     (int)((msr & 0xFFFF00) >> 16));
  274                 return (ENXIO);
  275         }
  276 
  277         pci_enable_busmaster(dev);
  278 
  279         /* Map in the security block configuration/control registers */
  280         sc->sc_rid = PCIR_BAR(0);
  281         sc->sc_sr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid,
  282             RF_ACTIVE);
  283         if (sc->sc_sr == NULL) {
  284                 device_printf(dev, "cannot map register space\n");
  285                 return (ENXIO);
  286         }
  287 
  288         /*
  289          * Configure the Security Block.
  290          *
  291          * We want to enable the noise generator (T_NE), and enable the
  292          * linear feedback shift register and whitener post-processing
  293          * (T_SEL = 3).  Also ensure that test mode (deterministic values)
  294          * is disabled.
  295          */
  296         msr = rdmsr(SB_GLD_MSR_CTRL);
  297         msr &= ~(SB_GMC_T_TM | SB_GMC_T_SEL_MASK);
  298         msr |= SB_GMC_T_NE | SB_GMC_T_SEL3;
  299 #if 0
  300         msr |= SB_GMC_SBI | SB_GMC_SBY;         /* for AES, if necessary */
  301 #endif
  302         wrmsr(SB_GLD_MSR_CTRL, msr);
  303 
  304         /* Disable interrupts */
  305         bus_write_4(sc->sc_sr, SB_AES_INT, SB_AI_CLEAR_INTR);
  306 
  307         /* Allocate a contiguous DMA-able buffer to work in */
  308         if (glxsb_dma_alloc(sc) != 0)
  309                 goto fail0;
  310 
  311         /* Initialize our task queue */
  312         sc->sc_tq = taskqueue_create("glxsb_taskq", M_NOWAIT | M_ZERO,
  313             taskqueue_thread_enqueue, &sc->sc_tq);
  314         if (sc->sc_tq == NULL) {
  315                 device_printf(dev, "cannot create task queue\n");
  316                 goto fail0;
  317         }
  318         if (taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
  319             device_get_nameunit(dev)) != 0) {
  320                 device_printf(dev, "cannot start task queue\n");
  321                 goto fail1;
  322         }
  323         TASK_INIT(&sc->sc_cryptotask, 0, glxsb_crypto_task, sc);
  324 
  325         /* Initialize crypto */
  326         if (glxsb_crypto_setup(sc) != 0)
  327                 goto fail1;
  328 
  329         /* Install a periodic collector for the "true" (AMD's word) RNG */
  330         if (hz > 100)
  331                 sc->sc_rnghz = hz / 100;
  332         else
  333                 sc->sc_rnghz = 1;
  334         callout_init(&sc->sc_rngco, CALLOUT_MPSAFE);
  335         glxsb_rnd(sc);
  336 
  337         return (0);
  338 
  339 fail1:
  340         taskqueue_free(sc->sc_tq);
  341 fail0:
  342         bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid, sc->sc_sr);
  343         return (ENXIO);
  344 }
  345 
  346 static int
  347 glxsb_detach(device_t dev)
  348 {
  349         struct glxsb_softc *sc = device_get_softc(dev);
  350         struct glxsb_session *ses;
  351 
  352         rw_wlock(&sc->sc_sessions_lock);
  353         TAILQ_FOREACH(ses, &sc->sc_sessions, ses_next) {
  354                 if (ses->ses_used) {
  355                         rw_wunlock(&sc->sc_sessions_lock);
  356                         device_printf(dev,
  357                                 "cannot detach, sessions still active.\n");
  358                         return (EBUSY);
  359                 }
  360         }
  361         while (!TAILQ_EMPTY(&sc->sc_sessions)) {
  362                 ses = TAILQ_FIRST(&sc->sc_sessions);
  363                 TAILQ_REMOVE(&sc->sc_sessions, ses, ses_next);
  364                 free(ses, M_GLXSB);
  365         }
  366         rw_wunlock(&sc->sc_sessions_lock);
  367         crypto_unregister_all(sc->sc_cid);
  368         callout_drain(&sc->sc_rngco);
  369         taskqueue_drain(sc->sc_tq, &sc->sc_cryptotask);
  370         bus_generic_detach(dev);
  371         glxsb_dma_free(sc, &sc->sc_dma);
  372         bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rid, sc->sc_sr);
  373         taskqueue_free(sc->sc_tq);
  374         rw_destroy(&sc->sc_sessions_lock);
  375         mtx_destroy(&sc->sc_task_mtx);
  376         return (0);
  377 }
  378 
  379 /*
  380  *      callback for bus_dmamap_load()
  381  */
  382 static void
  383 glxsb_dmamap_cb(void *arg, bus_dma_segment_t *seg, int nseg, int error)
  384 {
  385 
  386         bus_addr_t *paddr = (bus_addr_t*) arg;
  387         *paddr = seg[0].ds_addr;
  388 }
  389 
  390 static int
  391 glxsb_dma_alloc(struct glxsb_softc *sc)
  392 {
  393         struct glxsb_dma_map *dma = &sc->sc_dma;
  394         int rc;
  395 
  396         dma->dma_nsegs = 1;
  397         dma->dma_size = GLXSB_MAX_AES_LEN * 2;
  398 
  399         /* Setup DMA descriptor area */
  400         rc = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev),    /* parent */
  401                                 SB_AES_ALIGN, 0,        /* alignments, bounds */
  402                                 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
  403                                 BUS_SPACE_MAXADDR,      /* highaddr */
  404                                 NULL, NULL,             /* filter, filterarg */
  405                                 dma->dma_size,          /* maxsize */
  406                                 dma->dma_nsegs,         /* nsegments */
  407                                 dma->dma_size,          /* maxsegsize */
  408                                 BUS_DMA_ALLOCNOW,       /* flags */
  409                                 NULL, NULL,             /* lockfunc, lockarg */
  410                                 &sc->sc_dmat);
  411         if (rc != 0) {
  412                 device_printf(sc->sc_dev,
  413                     "cannot allocate DMA tag (%d)\n", rc);
  414                 return (rc);
  415         }
  416 
  417         rc = bus_dmamem_alloc(sc->sc_dmat, (void **)&dma->dma_vaddr,
  418             BUS_DMA_NOWAIT, &dma->dma_map);
  419         if (rc != 0) {
  420                 device_printf(sc->sc_dev,
  421                     "cannot allocate DMA memory of %d bytes (%d)\n",
  422                         dma->dma_size, rc);
  423                 goto fail0;
  424         }
  425 
  426         rc = bus_dmamap_load(sc->sc_dmat, dma->dma_map, dma->dma_vaddr,
  427             dma->dma_size, glxsb_dmamap_cb, &dma->dma_paddr, BUS_DMA_NOWAIT);
  428         if (rc != 0) {
  429                 device_printf(sc->sc_dev,
  430                     "cannot load DMA memory for %d bytes (%d)\n",
  431                    dma->dma_size, rc);
  432                 goto fail1;
  433         }
  434 
  435         return (0);
  436 
  437 fail1:
  438         bus_dmamem_free(sc->sc_dmat, dma->dma_vaddr, dma->dma_map);
  439 fail0:
  440         bus_dma_tag_destroy(sc->sc_dmat);
  441         return (rc);
  442 }
  443 
  444 static void
  445 glxsb_dma_pre_op(struct glxsb_softc *sc, struct glxsb_dma_map *dma)
  446 {
  447 
  448         bus_dmamap_sync(sc->sc_dmat, dma->dma_map,
  449             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  450 }
  451 
  452 static void
  453 glxsb_dma_post_op(struct glxsb_softc *sc, struct glxsb_dma_map *dma)
  454 {
  455 
  456         bus_dmamap_sync(sc->sc_dmat, dma->dma_map,
  457             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  458 }
  459 
  460 static void
  461 glxsb_dma_free(struct glxsb_softc *sc, struct glxsb_dma_map *dma)
  462 {
  463 
  464         bus_dmamap_unload(sc->sc_dmat, dma->dma_map);
  465         bus_dmamem_free(sc->sc_dmat, dma->dma_vaddr, dma->dma_map);
  466         bus_dma_tag_destroy(sc->sc_dmat);
  467 }
  468 
  469 static void
  470 glxsb_rnd(void *v)
  471 {
  472         struct glxsb_softc *sc = v;
  473         uint32_t status, value;
  474 
  475         status = bus_read_4(sc->sc_sr, SB_RANDOM_NUM_STATUS);
  476         if (status & SB_RNS_TRNG_VALID) {
  477                 value = bus_read_4(sc->sc_sr, SB_RANDOM_NUM);
  478                 /* feed with one uint32 */
  479                 random_harvest(&value, 4, 32, 0, RANDOM_PURE);
  480         }
  481 
  482         callout_reset(&sc->sc_rngco, sc->sc_rnghz, glxsb_rnd, sc);
  483 }
  484 
  485 static int
  486 glxsb_crypto_setup(struct glxsb_softc *sc)
  487 {
  488 
  489         sc->sc_cid = crypto_get_driverid(sc->sc_dev, CRYPTOCAP_F_HARDWARE);
  490 
  491         if (sc->sc_cid < 0) {
  492                 device_printf(sc->sc_dev, "cannot get crypto driver id\n");
  493                 return (ENOMEM);
  494         }
  495 
  496         TAILQ_INIT(&sc->sc_sessions);
  497         sc->sc_sid = 1;
  498         rw_init(&sc->sc_sessions_lock, "glxsb_sessions_lock");
  499         mtx_init(&sc->sc_task_mtx, "glxsb_crypto_mtx", NULL, MTX_DEF);
  500 
  501         if (crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0) != 0)
  502                 goto crypto_fail;
  503         if (crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0) != 0)
  504                 goto crypto_fail;
  505         if (crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0) != 0)
  506                 goto crypto_fail;
  507         if (crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0) != 0)
  508                 goto crypto_fail;
  509         if (crypto_register(sc->sc_cid, CRYPTO_RIPEMD160_HMAC, 0, 0) != 0)
  510                 goto crypto_fail;
  511         if (crypto_register(sc->sc_cid, CRYPTO_SHA2_256_HMAC, 0, 0) != 0)
  512                 goto crypto_fail;
  513         if (crypto_register(sc->sc_cid, CRYPTO_SHA2_384_HMAC, 0, 0) != 0)
  514                 goto crypto_fail;
  515         if (crypto_register(sc->sc_cid, CRYPTO_SHA2_512_HMAC, 0, 0) != 0)
  516                 goto crypto_fail;
  517 
  518         return (0);
  519 
  520 crypto_fail:
  521         device_printf(sc->sc_dev, "cannot register crypto\n");
  522         crypto_unregister_all(sc->sc_cid);
  523         rw_destroy(&sc->sc_sessions_lock);
  524         mtx_destroy(&sc->sc_task_mtx);
  525         return (ENOMEM);
  526 }
  527 
  528 static int
  529 glxsb_crypto_newsession(device_t dev, uint32_t *sidp, struct cryptoini *cri)
  530 {
  531         struct glxsb_softc *sc = device_get_softc(dev);
  532         struct glxsb_session *ses = NULL;
  533         struct cryptoini *encini, *macini;
  534         int error;
  535 
  536         if (sc == NULL || sidp == NULL || cri == NULL)
  537                 return (EINVAL);
  538 
  539         encini = macini = NULL;
  540         for (; cri != NULL; cri = cri->cri_next) {
  541                 switch(cri->cri_alg) {
  542                 case CRYPTO_NULL_HMAC:
  543                 case CRYPTO_MD5_HMAC:
  544                 case CRYPTO_SHA1_HMAC:
  545                 case CRYPTO_RIPEMD160_HMAC:
  546                 case CRYPTO_SHA2_256_HMAC:
  547                 case CRYPTO_SHA2_384_HMAC:
  548                 case CRYPTO_SHA2_512_HMAC:
  549                         if (macini != NULL)
  550                                 return (EINVAL);
  551                         macini = cri;
  552                         break;
  553                 case CRYPTO_AES_CBC:
  554                         if (encini != NULL)
  555                                 return (EINVAL);
  556                         encini = cri;
  557                         break;
  558                 default:
  559                         return (EINVAL);
  560                 }
  561         }
  562 
  563         /*
  564          * We only support HMAC algorithms to be able to work with
  565          * ipsec(4), so if we are asked only for authentication without
  566          * encryption, don't pretend we can accellerate it.
  567          */
  568         if (encini == NULL)
  569                 return (EINVAL);
  570 
  571         /*
  572          * Look for a free session
  573          *
  574          * Free sessions goes first, so if first session is used, we need to
  575          * allocate one.
  576          */
  577 
  578         rw_wlock(&sc->sc_sessions_lock);
  579         ses = TAILQ_FIRST(&sc->sc_sessions);
  580         if (ses == NULL || ses->ses_used) {
  581                 ses = malloc(sizeof(*ses), M_GLXSB, M_NOWAIT | M_ZERO);
  582                 if (ses == NULL) {
  583                         rw_wunlock(&sc->sc_sessions_lock);
  584                         return (ENOMEM);
  585                 }
  586                 ses->ses_id = sc->sc_sid++;
  587         } else {
  588                 TAILQ_REMOVE(&sc->sc_sessions, ses, ses_next);
  589         }
  590         ses->ses_used = 1;
  591         TAILQ_INSERT_TAIL(&sc->sc_sessions, ses, ses_next);
  592         rw_wunlock(&sc->sc_sessions_lock);
  593 
  594         if (encini->cri_alg == CRYPTO_AES_CBC) {
  595                 if (encini->cri_klen != 128) {
  596                         glxsb_crypto_freesession(sc->sc_dev, ses->ses_id);
  597                         return (EINVAL);
  598                 }
  599                 arc4rand(ses->ses_iv, sizeof(ses->ses_iv), 0);
  600                 ses->ses_klen = encini->cri_klen;
  601 
  602                 /* Copy the key (Geode LX wants the primary key only) */
  603                 bcopy(encini->cri_key, ses->ses_key, sizeof(ses->ses_key));
  604         }
  605 
  606         if (macini != NULL) {
  607                 error = glxsb_hash_setup(ses, macini);
  608                 if (error != 0) {
  609                         glxsb_crypto_freesession(sc->sc_dev, ses->ses_id);
  610                         return (error);
  611                 }
  612         }
  613 
  614         *sidp = ses->ses_id;
  615         return (0);
  616 }
  617 
  618 static int
  619 glxsb_crypto_freesession(device_t dev, uint64_t tid)
  620 {
  621         struct glxsb_softc *sc = device_get_softc(dev);
  622         struct glxsb_session *ses = NULL;
  623         uint32_t sid = ((uint32_t)tid) & 0xffffffff;
  624 
  625         if (sc == NULL)
  626                 return (EINVAL);
  627 
  628         rw_wlock(&sc->sc_sessions_lock);
  629         TAILQ_FOREACH_REVERSE(ses, &sc->sc_sessions, ses_head, ses_next) {
  630                 if (ses->ses_id == sid)
  631                         break;
  632         }
  633         if (ses == NULL) {
  634                 rw_wunlock(&sc->sc_sessions_lock);
  635                 return (EINVAL);
  636         }
  637         TAILQ_REMOVE(&sc->sc_sessions, ses, ses_next);
  638         glxsb_hash_free(ses);
  639         bzero(ses, sizeof(*ses));
  640         ses->ses_used = 0;
  641         ses->ses_id = sid;
  642         TAILQ_INSERT_HEAD(&sc->sc_sessions, ses, ses_next);
  643         rw_wunlock(&sc->sc_sessions_lock);
  644 
  645         return (0);
  646 }
  647 
  648 static int
  649 glxsb_aes(struct glxsb_softc *sc, uint32_t control, uint32_t psrc,
  650     uint32_t pdst, void *key, int len, void *iv)
  651 {
  652         uint32_t status;
  653         int i;
  654 
  655         if (len & 0xF) {
  656                 device_printf(sc->sc_dev,
  657                     "len must be a multiple of 16 (not %d)\n", len);
  658                 return (EINVAL);
  659         }
  660 
  661         /* Set the source */
  662         bus_write_4(sc->sc_sr, SB_SOURCE_A, psrc);
  663 
  664         /* Set the destination address */
  665         bus_write_4(sc->sc_sr, SB_DEST_A, pdst);
  666 
  667         /* Set the data length */
  668         bus_write_4(sc->sc_sr, SB_LENGTH_A, len);
  669 
  670         /* Set the IV */
  671         if (iv != NULL) {
  672                 bus_write_region_4(sc->sc_sr, SB_CBC_IV, iv, 4);
  673                 control |= SB_CTL_CBC;
  674         }
  675 
  676         /* Set the key */
  677         bus_write_region_4(sc->sc_sr, SB_WKEY, key, 4);
  678 
  679         /* Ask the security block to do it */
  680         bus_write_4(sc->sc_sr, SB_CTL_A,
  681             control | SB_CTL_WK | SB_CTL_DC | SB_CTL_SC | SB_CTL_ST);
  682 
  683         /*
  684          * Now wait until it is done.
  685          *
  686          * We do a busy wait.  Obviously the number of iterations of
  687          * the loop required to perform the AES operation depends upon
  688          * the number of bytes to process.
  689          *
  690          * On a 500 MHz Geode LX we see
  691          *
  692          *      length (bytes)  typical max iterations
  693          *          16             12
  694          *          64             22
  695          *         256             59
  696          *        1024            212
  697          *        8192          1,537
  698          *
  699          * Since we have a maximum size of operation defined in
  700          * GLXSB_MAX_AES_LEN, we use this constant to decide how long
  701          * to wait.  Allow an order of magnitude longer than it should
  702          * really take, just in case.
  703          */
  704 
  705         for (i = 0; i < GLXSB_MAX_AES_LEN * 10; i++) {
  706                 status = bus_read_4(sc->sc_sr, SB_CTL_A);
  707                 if ((status & SB_CTL_ST) == 0)          /* Done */
  708                         return (0);
  709         }
  710 
  711         device_printf(sc->sc_dev, "operation failed to complete\n");
  712         return (EIO);
  713 }
  714 
  715 static int
  716 glxsb_crypto_encdec(struct cryptop *crp, struct cryptodesc *crd,
  717     struct glxsb_session *ses, struct glxsb_softc *sc)
  718 {
  719         char *op_src, *op_dst;
  720         uint32_t op_psrc, op_pdst;
  721         uint8_t op_iv[SB_AES_BLOCK_SIZE], *piv;
  722         int error;
  723         int len, tlen, xlen;
  724         int offset;
  725         uint32_t control;
  726 
  727         if (crd == NULL || (crd->crd_len % SB_AES_BLOCK_SIZE) != 0)
  728                 return (EINVAL);
  729 
  730         /* How much of our buffer will we need to use? */
  731         xlen = crd->crd_len > GLXSB_MAX_AES_LEN ?
  732             GLXSB_MAX_AES_LEN : crd->crd_len;
  733 
  734         /*
  735          * XXX Check if we can have input == output on Geode LX.
  736          * XXX In the meantime, use two separate (adjacent) buffers.
  737          */
  738         op_src = sc->sc_dma.dma_vaddr;
  739         op_dst = (char *)sc->sc_dma.dma_vaddr + xlen;
  740 
  741         op_psrc = sc->sc_dma.dma_paddr;
  742         op_pdst = sc->sc_dma.dma_paddr + xlen;
  743 
  744         if (crd->crd_flags & CRD_F_ENCRYPT) {
  745                 control = SB_CTL_ENC;
  746                 if (crd->crd_flags & CRD_F_IV_EXPLICIT)
  747                         bcopy(crd->crd_iv, op_iv, sizeof(op_iv));
  748                 else
  749                         bcopy(ses->ses_iv, op_iv, sizeof(op_iv));
  750 
  751                 if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  752                         crypto_copyback(crp->crp_flags, crp->crp_buf,
  753                             crd->crd_inject, sizeof(op_iv), op_iv);
  754                 }
  755         } else {
  756                 control = SB_CTL_DEC;
  757                 if (crd->crd_flags & CRD_F_IV_EXPLICIT)
  758                         bcopy(crd->crd_iv, op_iv, sizeof(op_iv));
  759                 else {
  760                         crypto_copydata(crp->crp_flags, crp->crp_buf,
  761                             crd->crd_inject, sizeof(op_iv), op_iv);
  762                 }
  763         }
  764 
  765         offset = 0;
  766         tlen = crd->crd_len;
  767         piv = op_iv;
  768 
  769         /* Process the data in GLXSB_MAX_AES_LEN chunks */
  770         while (tlen > 0) {
  771                 len = (tlen > GLXSB_MAX_AES_LEN) ? GLXSB_MAX_AES_LEN : tlen;
  772                 crypto_copydata(crp->crp_flags, crp->crp_buf,
  773                     crd->crd_skip + offset, len, op_src);
  774 
  775                 glxsb_dma_pre_op(sc, &sc->sc_dma);
  776 
  777                 error = glxsb_aes(sc, control, op_psrc, op_pdst, ses->ses_key,
  778                     len, op_iv);
  779 
  780                 glxsb_dma_post_op(sc, &sc->sc_dma);
  781                 if (error != 0)
  782                         return (error);
  783 
  784                 crypto_copyback(crp->crp_flags, crp->crp_buf,
  785                     crd->crd_skip + offset, len, op_dst);
  786 
  787                 offset += len;
  788                 tlen -= len;
  789 
  790                 if (tlen <= 0) {        /* Ideally, just == 0 */
  791                         /* Finished - put the IV in session IV */
  792                         piv = ses->ses_iv;
  793                 }
  794 
  795                 /*
  796                  * Copy out last block for use as next iteration/session IV.
  797                  *
  798                  * piv is set to op_iv[] before the loop starts, but is
  799                  * set to ses->ses_iv if we're going to exit the loop this
  800                  * time.
  801                  */
  802                 if (crd->crd_flags & CRD_F_ENCRYPT)
  803                         bcopy(op_dst + len - sizeof(op_iv), piv, sizeof(op_iv));
  804                 else {
  805                         /* Decryption, only need this if another iteration */
  806                         if (tlen > 0) {
  807                                 bcopy(op_src + len - sizeof(op_iv), piv,
  808                                     sizeof(op_iv));
  809                         }
  810                 }
  811         } /* while */
  812 
  813         /* All AES processing has now been done. */
  814         bzero(sc->sc_dma.dma_vaddr, xlen * 2);
  815 
  816         return (0);
  817 }
  818 
  819 static void
  820 glxsb_crypto_task(void *arg, int pending)
  821 {
  822         struct glxsb_softc *sc = arg;
  823         struct glxsb_session *ses;
  824         struct cryptop *crp;
  825         struct cryptodesc *enccrd, *maccrd;
  826         int error;
  827 
  828         maccrd = sc->sc_to.to_maccrd;
  829         enccrd = sc->sc_to.to_enccrd;
  830         crp = sc->sc_to.to_crp;
  831         ses = sc->sc_to.to_ses;
  832 
  833         /* Perform data authentication if requested before encryption */
  834         if (maccrd != NULL && maccrd->crd_next == enccrd) {
  835                 error = glxsb_hash_process(ses, maccrd, crp);
  836                 if (error != 0)
  837                         goto out;
  838         }
  839 
  840         error = glxsb_crypto_encdec(crp, enccrd, ses, sc);
  841         if (error != 0)
  842                 goto out;
  843 
  844         /* Perform data authentication if requested after encryption */
  845         if (maccrd != NULL && enccrd->crd_next == maccrd) {
  846                 error = glxsb_hash_process(ses, maccrd, crp);
  847                 if (error != 0)
  848                         goto out;
  849         }
  850 out:
  851         mtx_lock(&sc->sc_task_mtx);
  852         sc->sc_task_count--;
  853         mtx_unlock(&sc->sc_task_mtx);
  854 
  855         crp->crp_etype = error;
  856         crypto_unblock(sc->sc_cid, CRYPTO_SYMQ);
  857         crypto_done(crp);
  858 }
  859 
  860 static int
  861 glxsb_crypto_process(device_t dev, struct cryptop *crp, int hint)
  862 {
  863         struct glxsb_softc *sc = device_get_softc(dev);
  864         struct glxsb_session *ses;
  865         struct cryptodesc *crd, *enccrd, *maccrd;
  866         uint32_t sid;
  867         int error = 0;
  868 
  869         enccrd = maccrd = NULL;
  870 
  871         /* Sanity check. */
  872         if (crp == NULL)
  873                 return (EINVAL);
  874 
  875         if (crp->crp_callback == NULL || crp->crp_desc == NULL) {
  876                 error = EINVAL;
  877                 goto fail;
  878         }
  879 
  880         for (crd = crp->crp_desc; crd != NULL; crd = crd->crd_next) {
  881                 switch (crd->crd_alg) {
  882                 case CRYPTO_NULL_HMAC:
  883                 case CRYPTO_MD5_HMAC:
  884                 case CRYPTO_SHA1_HMAC:
  885                 case CRYPTO_RIPEMD160_HMAC:
  886                 case CRYPTO_SHA2_256_HMAC:
  887                 case CRYPTO_SHA2_384_HMAC:
  888                 case CRYPTO_SHA2_512_HMAC:
  889                         if (maccrd != NULL) {
  890                                 error = EINVAL;
  891                                 goto fail;
  892                         }
  893                         maccrd = crd;
  894                         break;
  895                 case CRYPTO_AES_CBC:
  896                         if (enccrd != NULL) {
  897                                 error = EINVAL;
  898                                 goto fail;
  899                         }
  900                         enccrd = crd;
  901                         break;
  902                 default:
  903                         error = EINVAL;
  904                         goto fail;
  905                 }
  906         }
  907 
  908         if (enccrd == NULL || enccrd->crd_len % AES_BLOCK_LEN != 0) {
  909                 error = EINVAL;
  910                 goto fail;
  911         }
  912 
  913         sid = crp->crp_sid & 0xffffffff;
  914         rw_rlock(&sc->sc_sessions_lock);
  915         TAILQ_FOREACH_REVERSE(ses, &sc->sc_sessions, ses_head, ses_next) {
  916                 if (ses->ses_id == sid)
  917                         break;
  918         }
  919         rw_runlock(&sc->sc_sessions_lock);
  920         if (ses == NULL || !ses->ses_used) {
  921                 error = EINVAL;
  922                 goto fail;
  923         }
  924 
  925         mtx_lock(&sc->sc_task_mtx);
  926         if (sc->sc_task_count != 0) {
  927                 mtx_unlock(&sc->sc_task_mtx);
  928                 return (ERESTART);
  929         }
  930         sc->sc_task_count++;
  931 
  932         sc->sc_to.to_maccrd = maccrd;
  933         sc->sc_to.to_enccrd = enccrd;
  934         sc->sc_to.to_crp = crp;
  935         sc->sc_to.to_ses = ses;
  936         mtx_unlock(&sc->sc_task_mtx);
  937 
  938         taskqueue_enqueue(sc->sc_tq, &sc->sc_cryptotask);
  939         return(0);
  940 
  941 fail:
  942         crp->crp_etype = error;
  943         crypto_done(crp);
  944         return (error);
  945 }

Cache object: b9b0ef727f3e1c35d5caeca18e75db9f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.