[BACK]Return to glxsb.c CVS log [TXT][DIR] Up to [local] / sys / arch / i386 / pci

Annotation of sys/arch/i386/pci/glxsb.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: glxsb.c,v 1.8 2007/08/07 09:48:23 markus 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: #include <sys/param.h>
                     28: #include <sys/systm.h>
                     29: #include <sys/device.h>
                     30: #include <sys/malloc.h>
                     31: #include <sys/mbuf.h>
                     32: #include <sys/types.h>
                     33: #include <sys/timeout.h>
                     34:
                     35: #include <machine/bus.h>
                     36: #include <machine/pctr.h>
                     37:
                     38: #include <dev/rndvar.h>
                     39: #include <dev/pci/pcivar.h>
                     40: #include <dev/pci/pcidevs.h>
                     41:
                     42: #ifdef CRYPTO
                     43: #include <crypto/cryptodev.h>
                     44: #include <crypto/rijndael.h>
                     45: #include <crypto/xform.h>
                     46: #include <crypto/cryptosoft.h>
                     47: #endif
                     48:
                     49: #define SB_GLD_MSR_CAP         0x58002000      /* RO - Capabilities */
                     50: #define SB_GLD_MSR_CONFIG      0x58002001      /* RW - Master Config */
                     51: #define SB_GLD_MSR_SMI         0x58002002      /* RW - SMI */
                     52: #define SB_GLD_MSR_ERROR       0x58002003      /* RW - Error */
                     53: #define SB_GLD_MSR_PM          0x58002004      /* RW - Power Mgmt */
                     54: #define SB_GLD_MSR_DIAG                0x58002005      /* RW - Diagnostic */
                     55: #define SB_GLD_MSR_CTRL                0x58002006      /* RW - Security Block Cntrl */
                     56:
                     57:                                                /* For GLD_MSR_CTRL: */
                     58: #define SB_GMC_DIV0            0x0000          /* AES update divisor values */
                     59: #define SB_GMC_DIV1            0x0001
                     60: #define SB_GMC_DIV2            0x0002
                     61: #define SB_GMC_DIV3            0x0003
                     62: #define SB_GMC_DIV_MASK                0x0003
                     63: #define SB_GMC_SBI             0x0004          /* AES swap bits */
                     64: #define SB_GMC_SBY             0x0008          /* AES swap bytes */
                     65: #define SB_GMC_TW              0x0010          /* Time write (EEPROM) */
                     66: #define SB_GMC_T_SEL0          0x0000          /* RNG post-proc: none */
                     67: #define SB_GMC_T_SEL1          0x0100          /* RNG post-proc: LFSR */
                     68: #define SB_GMC_T_SEL2          0x0200          /* RNG post-proc: whitener */
                     69: #define SB_GMC_T_SEL3          0x0300          /* RNG LFSR+whitener */
                     70: #define SB_GMC_T_SEL_MASK      0x0300
                     71: #define SB_GMC_T_NE            0x0400          /* Noise (generator) Enable */
                     72: #define SB_GMC_T_TM            0x0800          /* RNG test mode */
                     73:                                                /*     (deterministic) */
                     74:
                     75: /* Security Block configuration/control registers (offsets from base) */
                     76:
                     77: #define SB_CTL_A               0x0000          /* RW - SB Control A */
                     78: #define SB_CTL_B               0x0004          /* RW - SB Control B */
                     79: #define SB_AES_INT             0x0008          /* RW - SB AES Interrupt */
                     80: #define SB_SOURCE_A            0x0010          /* RW - Source A */
                     81: #define SB_DEST_A              0x0014          /* RW - Destination A */
                     82: #define SB_LENGTH_A            0x0018          /* RW - Length A */
                     83: #define SB_SOURCE_B            0x0020          /* RW - Source B */
                     84: #define SB_DEST_B              0x0024          /* RW - Destination B */
                     85: #define SB_LENGTH_B            0x0028          /* RW - Length B */
                     86: #define SB_WKEY                        0x0030          /* WO - Writable Key 0-3 */
                     87: #define SB_WKEY_0              0x0030          /* WO - Writable Key 0 */
                     88: #define SB_WKEY_1              0x0034          /* WO - Writable Key 1 */
                     89: #define SB_WKEY_2              0x0038          /* WO - Writable Key 2 */
                     90: #define SB_WKEY_3              0x003C          /* WO - Writable Key 3 */
                     91: #define SB_CBC_IV              0x0040          /* RW - CBC IV 0-3 */
                     92: #define SB_CBC_IV_0            0x0040          /* RW - CBC IV 0 */
                     93: #define SB_CBC_IV_1            0x0044          /* RW - CBC IV 1 */
                     94: #define SB_CBC_IV_2            0x0048          /* RW - CBC IV 2 */
                     95: #define SB_CBC_IV_3            0x004C          /* RW - CBC IV 3 */
                     96: #define SB_RANDOM_NUM          0x0050          /* RW - Random Number */
                     97: #define SB_RANDOM_NUM_STATUS   0x0054          /* RW - Random Number Status */
                     98: #define SB_EEPROM_COMM         0x0800          /* RW - EEPROM Command */
                     99: #define SB_EEPROM_ADDR         0x0804          /* RW - EEPROM Address */
                    100: #define SB_EEPROM_DATA         0x0808          /* RW - EEPROM Data */
                    101: #define SB_EEPROM_SEC_STATE    0x080C          /* RW - EEPROM Security State */
                    102:
                    103:                                                /* For SB_CTL_A and _B */
                    104: #define SB_CTL_ST              0x0001          /* Start operation (enc/dec) */
                    105: #define SB_CTL_ENC             0x0002          /* Encrypt (0 is decrypt) */
                    106: #define SB_CTL_DEC             0x0000          /* Decrypt */
                    107: #define SB_CTL_WK              0x0004          /* Use writable key (we set) */
                    108: #define SB_CTL_DC              0x0008          /* Destination coherent */
                    109: #define SB_CTL_SC              0x0010          /* Source coherent */
                    110: #define SB_CTL_CBC             0x0020          /* CBC (0 is ECB) */
                    111:
                    112:                                                /* For SB_AES_INT */
                    113: #define SB_AI_DISABLE_AES_A    0x0001          /* Disable AES A compl int */
                    114: #define SB_AI_ENABLE_AES_A     0x0000          /* Enable AES A compl int */
                    115: #define SB_AI_DISABLE_AES_B    0x0002          /* Disable AES B compl int */
                    116: #define SB_AI_ENABLE_AES_B     0x0000          /* Enable AES B compl int */
                    117: #define SB_AI_DISABLE_EEPROM   0x0004          /* Disable EEPROM op comp int */
                    118: #define SB_AI_ENABLE_EEPROM    0x0000          /* Enable EEPROM op compl int */
                    119: #define SB_AI_AES_A_COMPLETE   0x0100          /* AES A operation complete */
                    120: #define SB_AI_AES_B_COMPLETE   0x0200          /* AES B operation complete */
                    121: #define SB_AI_EEPROM_COMPLETE  0x0400          /* EEPROM operation complete */
                    122:
                    123: #define SB_RNS_TRNG_VALID      0x0001          /* in SB_RANDOM_NUM_STATUS */
                    124:
                    125: #define SB_MEM_SIZE            0x0810          /* Size of memory block */
                    126:
                    127: #define SB_AES_ALIGN           0x0010          /* Source and dest buffers */
                    128:                                                /* must be 16-byte aligned */
                    129: #define SB_AES_BLOCK_SIZE      0x0010
                    130:
                    131: /*
                    132:  * The Geode LX security block AES acceleration doesn't perform scatter-
                    133:  * gather: it just takes source and destination addresses.  Therefore the
                    134:  * plain- and ciphertexts need to be contiguous.  To this end, we allocate
                    135:  * a buffer for both, and accept the overhead of copying in and out.  If
                    136:  * the number of bytes in one operation is bigger than allowed for by the
                    137:  * buffer (buffer is twice the size of the max length, as it has both input
                    138:  * and output) then we have to perform multiple encryptions/decryptions.
                    139:  */
                    140: #define GLXSB_MAX_AES_LEN      16384
                    141:
                    142: #ifdef CRYPTO
                    143: struct glxsb_dma_map {
                    144:        bus_dmamap_t            dma_map;
                    145:        bus_dma_segment_t       dma_seg;
                    146:        int                     dma_nsegs;
                    147:        int                     dma_size;
                    148:        caddr_t                 dma_vaddr;
                    149:        uint32_t                dma_paddr;
                    150: };
                    151: struct glxsb_session {
                    152:        uint32_t        ses_key[4];
                    153:        uint8_t         ses_iv[SB_AES_BLOCK_SIZE];
                    154:        int             ses_klen;
                    155:        int             ses_used;
                    156:        struct swcr_data *ses_swd;
                    157: };
                    158: #endif /* CRYPTO */
                    159:
                    160: struct glxsb_softc {
                    161:        struct device           sc_dev;
                    162:        bus_space_tag_t         sc_iot;
                    163:        bus_space_handle_t      sc_ioh;
                    164:        struct timeout          sc_to;
                    165:
                    166: #ifdef CRYPTO
                    167:        bus_dma_tag_t           sc_dmat;
                    168:        struct glxsb_dma_map    sc_dma;
                    169:        int32_t                 sc_cid;
                    170:        int                     sc_nsessions;
                    171:        struct glxsb_session    *sc_sessions;
                    172: #endif /* CRYPTO */
                    173: };
                    174:
                    175: int    glxsb_match(struct device *, void *, void *);
                    176: void   glxsb_attach(struct device *, struct device *, void *);
                    177: void   glxsb_rnd(void *);
                    178:
                    179: struct cfattach glxsb_ca = {
                    180:        sizeof(struct glxsb_softc), glxsb_match, glxsb_attach
                    181: };
                    182:
                    183: struct cfdriver glxsb_cd = {
                    184:        NULL, "glxsb", DV_DULL
                    185: };
                    186:
                    187:
                    188: #ifdef CRYPTO
                    189:
                    190: #define GLXSB_SESSION(sid)             ((sid) & 0x0fffffff)
                    191: #define        GLXSB_SID(crd,ses)              (((crd) << 28) | ((ses) & 0x0fffffff))
                    192:
                    193: static struct glxsb_softc *glxsb_sc;
                    194: extern int i386_has_xcrypt;
                    195:
                    196: int glxsb_crypto_setup(struct glxsb_softc *);
                    197: int glxsb_crypto_newsession(uint32_t *, struct cryptoini *);
                    198: int glxsb_crypto_process(struct cryptop *);
                    199: int glxsb_crypto_freesession(uint64_t);
                    200: static __inline void glxsb_aes(struct glxsb_softc *, uint32_t, uint32_t,
                    201:     uint32_t, void *, int, void *);
                    202:
                    203: int glxsb_dma_alloc(struct glxsb_softc *, int, struct glxsb_dma_map *);
                    204: void glxsb_dma_pre_op(struct glxsb_softc *, struct glxsb_dma_map *);
                    205: void glxsb_dma_post_op(struct glxsb_softc *, struct glxsb_dma_map *);
                    206: void glxsb_dma_free(struct glxsb_softc *, struct glxsb_dma_map *);
                    207:
                    208: #endif /* CRYPTO */
                    209:
                    210:
                    211: int
                    212: glxsb_match(struct device *parent, void *match, void *aux)
                    213: {
                    214:        struct pci_attach_args *pa = aux;
                    215:
                    216:        if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD &&
                    217:            PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_GEODE_LX_CRYPTO)
                    218:                return (1);
                    219:
                    220:        return (0);
                    221: }
                    222:
                    223: void
                    224: glxsb_attach(struct device *parent, struct device *self, void *aux)
                    225: {
                    226:        struct glxsb_softc *sc = (void *) self;
                    227:        struct pci_attach_args *pa = aux;
                    228:        bus_addr_t membase;
                    229:        bus_size_t memsize;
                    230:        uint64_t msr;
                    231: #ifdef CRYPTO
                    232:        uint32_t intr;
                    233: #endif
                    234:
                    235:        msr = rdmsr(SB_GLD_MSR_CAP);
                    236:        if ((msr & 0xFFFF00) != 0x130400) {
                    237:                printf(": unknown ID 0x%x\n", (int) ((msr & 0xFFFF00) >> 16));
                    238:                return;
                    239:        }
                    240:
                    241:        /* printf(": revision %d", (int) (msr & 0xFF)); */
                    242:
                    243:        /* Map in the security block configuration/control registers */
                    244:        if (pci_mapreg_map(pa, PCI_MAPREG_START,
                    245:            PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &sc->sc_iot,
                    246:            &sc->sc_ioh, &membase, &memsize, SB_MEM_SIZE)) {
                    247:                printf(": can't find mem space\n");
                    248:                return;
                    249:        }
                    250:
                    251:        /*
                    252:         * Configure the Security Block.
                    253:         *
                    254:         * We want to enable the noise generator (T_NE), and enable the
                    255:         * linear feedback shift register and whitener post-processing
                    256:         * (T_SEL = 3).  Also ensure that test mode (deterministic values)
                    257:         * is disabled.
                    258:         */
                    259:        msr = rdmsr(SB_GLD_MSR_CTRL);
                    260:        msr &= ~(SB_GMC_T_TM | SB_GMC_T_SEL_MASK);
                    261:        msr |= SB_GMC_T_NE | SB_GMC_T_SEL3;
                    262: #if 0
                    263:        msr |= SB_GMC_SBI | SB_GMC_SBY;         /* for AES, if necessary */
                    264: #endif
                    265:        wrmsr(SB_GLD_MSR_CTRL, msr);
                    266:
                    267:        /* Install a periodic collector for the "true" (AMD's word) RNG */
                    268:        timeout_set(&sc->sc_to, glxsb_rnd, sc);
                    269:        glxsb_rnd(sc);
                    270:        printf(": RNG");
                    271:
                    272: #ifdef CRYPTO
                    273:        /* We don't have an interrupt handler, so disable completion INTs */
                    274:        intr = SB_AI_DISABLE_AES_A | SB_AI_DISABLE_AES_B |
                    275:            SB_AI_DISABLE_EEPROM | SB_AI_AES_A_COMPLETE |
                    276:            SB_AI_AES_B_COMPLETE | SB_AI_EEPROM_COMPLETE;
                    277:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, SB_AES_INT, intr);
                    278:
                    279:        sc->sc_dmat = pa->pa_dmat;
                    280:
                    281:        if (glxsb_crypto_setup(sc))
                    282:                printf(" AES");
                    283: #endif
                    284:
                    285:        printf("\n");
                    286: }
                    287:
                    288: void
                    289: glxsb_rnd(void *v)
                    290: {
                    291:        struct glxsb_softc *sc = v;
                    292:        uint32_t status, value;
                    293:        extern int hz;
                    294:
                    295:        status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SB_RANDOM_NUM_STATUS);
                    296:        if (status & SB_RNS_TRNG_VALID) {
                    297:                value = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SB_RANDOM_NUM);
                    298:                add_true_randomness(value);
                    299:        }
                    300:
                    301:        timeout_add(&sc->sc_to, (hz > 100) ? (hz / 100) : 1);
                    302: }
                    303:
                    304: #ifdef CRYPTO
                    305: int
                    306: glxsb_crypto_setup(struct glxsb_softc *sc)
                    307: {
                    308:        int algs[CRYPTO_ALGORITHM_MAX + 1];
                    309:
                    310:        /* Allocate a contiguous DMA-able buffer to work in */
                    311:        if (glxsb_dma_alloc(sc, GLXSB_MAX_AES_LEN * 2, &sc->sc_dma) != 0)
                    312:                return 0;
                    313:
                    314:        bzero(algs, sizeof(algs));
                    315:        algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    316:        algs[CRYPTO_MD5_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    317:        algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    318:        algs[CRYPTO_RIPEMD160_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    319:        algs[CRYPTO_SHA2_256_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    320:        algs[CRYPTO_SHA2_384_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    321:        algs[CRYPTO_SHA2_512_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED;
                    322:
                    323:        sc->sc_cid = crypto_get_driverid(0);
                    324:        if (sc->sc_cid < 0)
                    325:                return 0;
                    326:
                    327:        crypto_register(sc->sc_cid, algs, glxsb_crypto_newsession,
                    328:            glxsb_crypto_freesession, glxsb_crypto_process);
                    329:
                    330:        sc->sc_nsessions = 0;
                    331:
                    332:        glxsb_sc = sc;
                    333:
                    334:        return 1;
                    335: }
                    336:
                    337: int
                    338: glxsb_crypto_newsession(uint32_t *sidp, struct cryptoini *cri)
                    339: {
                    340:        struct glxsb_softc *sc = glxsb_sc;
                    341:        struct glxsb_session *ses = NULL;
                    342:        struct auth_hash        *axf;
                    343:        struct cryptoini        *c;
                    344:        struct swcr_data        *swd;
                    345:        int sesn, i;
                    346:
                    347:        if (sc == NULL || sidp == NULL || cri == NULL)
                    348:                return (EINVAL);
                    349:
                    350:        for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
                    351:                if (sc->sc_sessions[sesn].ses_used == 0) {
                    352:                        ses = &sc->sc_sessions[sesn];
                    353:                        break;
                    354:                }
                    355:        }
                    356:
                    357:        if (ses == NULL) {
                    358:                sesn = sc->sc_nsessions;
                    359:                ses = malloc((sesn + 1) * sizeof(*ses), M_DEVBUF, M_NOWAIT);
                    360:                if (ses == NULL)
                    361:                        return (ENOMEM);
                    362:                if (sesn != 0) {
                    363:                        bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
                    364:                        bzero(sc->sc_sessions, sesn * sizeof(*ses));
                    365:                        free(sc->sc_sessions, M_DEVBUF);
                    366:                }
                    367:                sc->sc_sessions = ses;
                    368:                ses = &sc->sc_sessions[sesn];
                    369:                sc->sc_nsessions++;
                    370:        }
                    371:
                    372:        bzero(ses, sizeof(*ses));
                    373:        ses->ses_used = 1;
                    374:
                    375:        for (c = cri; c != NULL; c = c->cri_next) {
                    376:                switch (c->cri_alg) {
                    377:                case CRYPTO_AES_CBC:
                    378:                        if (c->cri_klen != 128) {
                    379:                                glxsb_crypto_freesession(sesn);
                    380:                                return (EINVAL);
                    381:                        }
                    382:
                    383:                        get_random_bytes(ses->ses_iv, sizeof(ses->ses_iv));
                    384:                        ses->ses_klen = c->cri_klen;
                    385:
                    386:                        /* Copy the key (Geode LX wants the primary key only) */
                    387:                        bcopy(c->cri_key, ses->ses_key, sizeof(ses->ses_key));
                    388:                        break;
                    389:
                    390:                case CRYPTO_MD5_HMAC:
                    391:                        axf = &auth_hash_hmac_md5_96;
                    392:                        goto authcommon;
                    393:                case CRYPTO_SHA1_HMAC:
                    394:                        axf = &auth_hash_hmac_sha1_96;
                    395:                        goto authcommon;
                    396:                case CRYPTO_RIPEMD160_HMAC:
                    397:                        axf = &auth_hash_hmac_ripemd_160_96;
                    398:                        goto authcommon;
                    399:                case CRYPTO_SHA2_256_HMAC:
                    400:                        axf = &auth_hash_hmac_sha2_256_96;
                    401:                        goto authcommon;
                    402:                case CRYPTO_SHA2_384_HMAC:
                    403:                        axf = &auth_hash_hmac_sha2_384_96;
                    404:                        goto authcommon;
                    405:                case CRYPTO_SHA2_512_HMAC:
                    406:                        axf = &auth_hash_hmac_sha2_512_96;
                    407:                authcommon:
                    408:                        MALLOC(swd, struct swcr_data *,
                    409:                            sizeof(struct swcr_data), M_CRYPTO_DATA,
                    410:                            M_NOWAIT);
                    411:                        if (swd == NULL) {
                    412:                                glxsb_crypto_freesession(sesn);
                    413:                                return (ENOMEM);
                    414:                        }
                    415:                        bzero(swd, sizeof(struct swcr_data));
                    416:                        ses->ses_swd = swd;
                    417:
                    418:                        swd->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA,
                    419:                            M_NOWAIT);
                    420:                        if (swd->sw_ictx == NULL) {
                    421:                                glxsb_crypto_freesession(sesn);
                    422:                                return (ENOMEM);
                    423:                        }
                    424:
                    425:                        swd->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA,
                    426:                            M_NOWAIT);
                    427:                        if (swd->sw_octx == NULL) {
                    428:                                glxsb_crypto_freesession(sesn);
                    429:                                return (ENOMEM);
                    430:                        }
                    431:
                    432:                        for (i = 0; i < c->cri_klen / 8; i++)
                    433:                                c->cri_key[i] ^= HMAC_IPAD_VAL;
                    434:
                    435:                        axf->Init(swd->sw_ictx);
                    436:                        axf->Update(swd->sw_ictx, c->cri_key, c->cri_klen / 8);
                    437:                        axf->Update(swd->sw_ictx, hmac_ipad_buffer,
                    438:                            HMAC_BLOCK_LEN - (c->cri_klen / 8));
                    439:
                    440:                        for (i = 0; i < c->cri_klen / 8; i++)
                    441:                                c->cri_key[i] ^= (HMAC_IPAD_VAL ^
                    442:                                    HMAC_OPAD_VAL);
                    443:
                    444:                        axf->Init(swd->sw_octx);
                    445:                        axf->Update(swd->sw_octx, c->cri_key, c->cri_klen / 8);
                    446:                        axf->Update(swd->sw_octx, hmac_opad_buffer,
                    447:                            HMAC_BLOCK_LEN - (c->cri_klen / 8));
                    448:
                    449:                        for (i = 0; i < c->cri_klen / 8; i++)
                    450:                                c->cri_key[i] ^= HMAC_OPAD_VAL;
                    451:
                    452:                        swd->sw_axf = axf;
                    453:                        swd->sw_alg = c->cri_alg;
                    454:
                    455:                        break;
                    456:                default:
                    457:                        glxsb_crypto_freesession(sesn);
                    458:                        return (EINVAL);
                    459:                }
                    460:        }
                    461:
                    462:        *sidp = GLXSB_SID(0, sesn);
                    463:        return (0);
                    464: }
                    465:
                    466: int
                    467: glxsb_crypto_freesession(uint64_t tid)
                    468: {
                    469:        struct glxsb_softc *sc = glxsb_sc;
                    470:        struct swcr_data *swd;
                    471:        struct auth_hash *axf;
                    472:        int sesn;
                    473:        uint32_t sid = ((uint32_t)tid) & 0xffffffff;
                    474:
                    475:        if (sc == NULL)
                    476:                return (EINVAL);
                    477:        sesn = GLXSB_SESSION(sid);
                    478:        if (sesn >= sc->sc_nsessions)
                    479:                return (EINVAL);
                    480:        if (sc->sc_sessions[sesn].ses_swd) {
                    481:                swd = sc->sc_sessions[sesn].ses_swd;
                    482:                axf = swd->sw_axf;
                    483:
                    484:                if (swd->sw_ictx) {
                    485:                        bzero(swd->sw_ictx, axf->ctxsize);
                    486:                        free(swd->sw_ictx, M_CRYPTO_DATA);
                    487:                }
                    488:                if (swd->sw_octx) {
                    489:                        bzero(swd->sw_octx, axf->ctxsize);
                    490:                        free(swd->sw_octx, M_CRYPTO_DATA);
                    491:                }
                    492:                FREE(swd, M_CRYPTO_DATA);
                    493:        }
                    494:        bzero(&sc->sc_sessions[sesn], sizeof(sc->sc_sessions[sesn]));
                    495:        return (0);
                    496: }
                    497:
                    498: /*
                    499:  * Must be called at splnet() or higher
                    500:  */
                    501: static __inline void
                    502: glxsb_aes(struct glxsb_softc *sc, uint32_t control, uint32_t psrc,
                    503:     uint32_t pdst, void *key, int len, void *iv)
                    504: {
                    505:        uint32_t status;
                    506:        int i;
                    507:
                    508:        if (len & 0xF) {
                    509:                printf("%s: len must be a multiple of 16 (not %d)\n",
                    510:                    sc->sc_dev.dv_xname, len);
                    511:                return;
                    512:        }
                    513:
                    514:        /* Set the source */
                    515:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, SB_SOURCE_A, psrc);
                    516:
                    517:        /* Set the destination address */
                    518:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, SB_DEST_A, pdst);
                    519:
                    520:        /* Set the data length */
                    521:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, SB_LENGTH_A, len);
                    522:
                    523:        /* Set the IV */
                    524:        if (iv != NULL) {
                    525:                bus_space_write_region_4(sc->sc_iot, sc->sc_ioh,
                    526:                    SB_CBC_IV, iv, 4);
                    527:                control |= SB_CTL_CBC;
                    528:        }
                    529:
                    530:        /* Set the key */
                    531:        bus_space_write_region_4(sc->sc_iot, sc->sc_ioh, SB_WKEY, key, 4);
                    532:
                    533:        /* Ask the security block to do it */
                    534:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, SB_CTL_A,
                    535:            control | SB_CTL_WK | SB_CTL_DC | SB_CTL_SC | SB_CTL_ST);
                    536:
                    537:        /*
                    538:         * Now wait until it is done.
                    539:         *
                    540:         * We do a busy wait.  Obviously the number of iterations of
                    541:         * the loop required to perform the AES operation depends upon
                    542:         * the number of bytes to process.
                    543:         *
                    544:         * On a 500 MHz Geode LX we see
                    545:         *
                    546:         *      length (bytes)  typical max iterations
                    547:         *          16             12
                    548:         *          64             22
                    549:         *         256             59
                    550:         *        1024            212
                    551:         *        8192          1,537
                    552:         *
                    553:         * Since we have a maximum size of operation defined in
                    554:         * GLXSB_MAX_AES_LEN, we use this constant to decide how long
                    555:         * to wait.  Allow an order of magnitude longer than it should
                    556:         * really take, just in case.
                    557:         */
                    558:        for (i = 0; i < GLXSB_MAX_AES_LEN * 10; i++) {
                    559:                status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SB_CTL_A);
                    560:
                    561:                if ((status & SB_CTL_ST) == 0)          /* Done */
                    562:                        return;
                    563:        }
                    564:
                    565:        printf("%s: operation failed to complete\n", sc->sc_dev.dv_xname);
                    566: }
                    567:
                    568: static int
                    569: glxsb_crypto_swauth(struct cryptop *crp, struct cryptodesc *crd,
                    570:     struct swcr_data *sw, caddr_t buf)
                    571: {
                    572:        int     type;
                    573:
                    574:        if (crp->crp_flags & CRYPTO_F_IMBUF)
                    575:                type = CRYPTO_BUF_MBUF;
                    576:        else
                    577:                type = CRYPTO_BUF_IOV;
                    578:
                    579:        return (swcr_authcompute(crp, crd, sw, buf, type));
                    580: }
                    581:
                    582: static int
                    583: glxsb_crypto_encdec(struct cryptop *crp, struct cryptodesc *crd,
                    584:     struct glxsb_session *ses, struct glxsb_softc *sc, caddr_t buf)
                    585: {
                    586:        char *op_src, *op_dst;
                    587:        uint32_t op_psrc, op_pdst;
                    588:        uint8_t op_iv[SB_AES_BLOCK_SIZE], *piv;
                    589:        int err = 0;
                    590:        int len, tlen, xlen;
                    591:        int offset;
                    592:        uint32_t control;
                    593:
                    594:        if (crd == NULL || (crd->crd_len % SB_AES_BLOCK_SIZE) != 0) {
                    595:                err = EINVAL;
                    596:                goto out;
                    597:        }
                    598:
                    599:        /* How much of our buffer will we need to use? */
                    600:        xlen = crd->crd_len > GLXSB_MAX_AES_LEN ?
                    601:            GLXSB_MAX_AES_LEN : crd->crd_len;
                    602:
                    603:        /*
                    604:         * XXX Check if we can have input == output on Geode LX.
                    605:         * XXX In the meantime, use two separate (adjacent) buffers.
                    606:         */
                    607:        op_src = sc->sc_dma.dma_vaddr;
                    608:        op_dst = sc->sc_dma.dma_vaddr + xlen;
                    609:
                    610:        op_psrc = sc->sc_dma.dma_paddr;
                    611:        op_pdst = sc->sc_dma.dma_paddr + xlen;
                    612:
                    613:        if (crd->crd_flags & CRD_F_ENCRYPT) {
                    614:                control = SB_CTL_ENC;
                    615:                if (crd->crd_flags & CRD_F_IV_EXPLICIT)
                    616:                        bcopy(crd->crd_iv, op_iv, sizeof(op_iv));
                    617:                else
                    618:                        bcopy(ses->ses_iv, op_iv, sizeof(op_iv));
                    619:
                    620:                if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
                    621:                        if (crp->crp_flags & CRYPTO_F_IMBUF)
                    622:                                m_copyback((struct mbuf *)crp->crp_buf,
                    623:                                    crd->crd_inject, sizeof(op_iv), op_iv);
                    624:                        else if (crp->crp_flags & CRYPTO_F_IOV)
                    625:                                cuio_copyback((struct uio *)crp->crp_buf,
                    626:                                    crd->crd_inject, sizeof(op_iv), op_iv);
                    627:                        else
                    628:                                bcopy(op_iv,
                    629:                                    crp->crp_buf + crd->crd_inject, sizeof(op_iv));
                    630:                }
                    631:        } else {
                    632:                control = SB_CTL_DEC;
                    633:                if (crd->crd_flags & CRD_F_IV_EXPLICIT)
                    634:                        bcopy(crd->crd_iv, op_iv, sizeof(op_iv));
                    635:                else {
                    636:                        if (crp->crp_flags & CRYPTO_F_IMBUF)
                    637:                                m_copydata((struct mbuf *)crp->crp_buf,
                    638:                                    crd->crd_inject, sizeof(op_iv), op_iv);
                    639:                        else if (crp->crp_flags & CRYPTO_F_IOV)
                    640:                                cuio_copydata((struct uio *)crp->crp_buf,
                    641:                                    crd->crd_inject, sizeof(op_iv), op_iv);
                    642:                        else
                    643:                                bcopy(crp->crp_buf + crd->crd_inject,
                    644:                                    op_iv, sizeof(op_iv));
                    645:                }
                    646:        }
                    647:
                    648:        offset = 0;
                    649:        tlen = crd->crd_len;
                    650:        piv = op_iv;
                    651:
                    652:        /* Process the data in GLXSB_MAX_AES_LEN chunks */
                    653:        while (tlen > 0) {
                    654:                len = (tlen > GLXSB_MAX_AES_LEN) ? GLXSB_MAX_AES_LEN : tlen;
                    655:
                    656:                if (crp->crp_flags & CRYPTO_F_IMBUF)
                    657:                        m_copydata((struct mbuf *)crp->crp_buf,
                    658:                            crd->crd_skip + offset, len, op_src);
                    659:                else if (crp->crp_flags & CRYPTO_F_IOV)
                    660:                        cuio_copydata((struct uio *)crp->crp_buf,
                    661:                            crd->crd_skip + offset, len, op_src);
                    662:                else
                    663:                        bcopy(crp->crp_buf + crd->crd_skip + offset, op_src,
                    664:                            len);
                    665:
                    666:                glxsb_dma_pre_op(sc, &sc->sc_dma);
                    667:
                    668:                glxsb_aes(sc, control, op_psrc, op_pdst, ses->ses_key,
                    669:                    len, op_iv);
                    670:
                    671:                glxsb_dma_post_op(sc, &sc->sc_dma);
                    672:
                    673:                if (crp->crp_flags & CRYPTO_F_IMBUF)
                    674:                        m_copyback((struct mbuf *)crp->crp_buf,
                    675:                            crd->crd_skip + offset, len, op_dst);
                    676:                else if (crp->crp_flags & CRYPTO_F_IOV)
                    677:                        cuio_copyback((struct uio *)crp->crp_buf,
                    678:                            crd->crd_skip + offset, len, op_dst);
                    679:                else
                    680:                        bcopy(op_dst, crp->crp_buf + crd->crd_skip + offset,
                    681:                            len);
                    682:
                    683:                offset += len;
                    684:                tlen -= len;
                    685:
                    686:                if (tlen <= 0) {        /* Ideally, just == 0 */
                    687:                        /* Finished - put the IV in session IV */
                    688:                        piv = ses->ses_iv;
                    689:                }
                    690:
                    691:                /*
                    692:                 * Copy out last block for use as next iteration/session IV.
                    693:                 *
                    694:                 * piv is set to op_iv[] before the loop starts, but is
                    695:                 * set to ses->ses_iv if we're going to exit the loop this
                    696:                 * time.
                    697:                 */
                    698:                if (crd->crd_flags & CRD_F_ENCRYPT) {
                    699:                        bcopy(op_dst + len - sizeof(op_iv), piv, sizeof(op_iv));
                    700:                } else {
                    701:                        /* Decryption, only need this if another iteration */
                    702:                        if (tlen > 0) {
                    703:                                bcopy(op_src + len - sizeof(op_iv), piv,
                    704:                                    sizeof(op_iv));
                    705:                        }
                    706:                }
                    707:        }
                    708:
                    709:        /* All AES processing has now been done. */
                    710:        bzero(sc->sc_dma.dma_vaddr, xlen * 2);
                    711:
                    712: out:
                    713:        return (err);
                    714: }
                    715:
                    716: int
                    717: glxsb_crypto_process(struct cryptop *crp)
                    718: {
                    719:        struct glxsb_softc *sc = glxsb_sc;
                    720:        struct glxsb_session *ses;
                    721:        struct cryptodesc *crd;
                    722:        int sesn,err = 0;
                    723:        int s;
                    724:
                    725:        s = splnet();
                    726:
                    727:        if (crp == NULL || crp->crp_callback == NULL) {
                    728:                err = EINVAL;
                    729:                goto out;
                    730:        }
                    731:        crd = crp->crp_desc;
                    732:        if (crd == NULL) {
                    733:                err = EINVAL;
                    734:                goto out;
                    735:        }
                    736:
                    737:        sesn = GLXSB_SESSION(crp->crp_sid);
                    738:        if (sesn >= sc->sc_nsessions) {
                    739:                err = EINVAL;
                    740:                goto out;
                    741:        }
                    742:        ses = &sc->sc_sessions[sesn];
                    743:
                    744:        for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
                    745:                switch (crd->crd_alg) {
                    746:                case CRYPTO_AES_CBC:
                    747:                        if ((err = glxsb_crypto_encdec(crp, crd, ses, sc,
                    748:                            crp->crp_buf)) != 0)
                    749:                                goto out;
                    750:                        break;
                    751:
                    752:                case CRYPTO_MD5_HMAC:
                    753:                case CRYPTO_SHA1_HMAC:
                    754:                case CRYPTO_RIPEMD160_HMAC:
                    755:                case CRYPTO_SHA2_256_HMAC:
                    756:                case CRYPTO_SHA2_384_HMAC:
                    757:                case CRYPTO_SHA2_512_HMAC:
                    758:                        if ((err = glxsb_crypto_swauth(crp, crd, ses->ses_swd,
                    759:                            crp->crp_buf)) != 0)
                    760:                                goto out;
                    761:                        break;
                    762:
                    763:                default:
                    764:                        err = EINVAL;
                    765:                        goto out;
                    766:                }
                    767:        }
                    768:
                    769: out:
                    770:        crp->crp_etype = err;
                    771:        crypto_done(crp);
                    772:        splx(s);
                    773:        return (err);
                    774: }
                    775:
                    776: int
                    777: glxsb_dma_alloc(struct glxsb_softc *sc, int size, struct glxsb_dma_map *dma)
                    778: {
                    779:        int rc;
                    780:
                    781:        dma->dma_nsegs = 1;
                    782:        dma->dma_size = size;
                    783:
                    784:        rc = bus_dmamap_create(sc->sc_dmat, size, dma->dma_nsegs, size,
                    785:            0, BUS_DMA_NOWAIT, &dma->dma_map);
                    786:        if (rc != 0) {
                    787:                printf("%s: couldn't create DMA map for %d bytes (%d)\n",
                    788:                    sc->sc_dev.dv_xname, size, rc);
                    789:
                    790:                goto fail0;
                    791:        }
                    792:
                    793:        rc = bus_dmamem_alloc(sc->sc_dmat, size, SB_AES_ALIGN, 0,
                    794:            &dma->dma_seg, dma->dma_nsegs, &dma->dma_nsegs, BUS_DMA_NOWAIT);
                    795:        if (rc != 0) {
                    796:                printf("%s: couldn't allocate DMA memory of %d bytes (%d)\n",
                    797:                    sc->sc_dev.dv_xname, size, rc);
                    798:
                    799:                goto fail1;
                    800:        }
                    801:
                    802:        rc = bus_dmamem_map(sc->sc_dmat, &dma->dma_seg, 1, size,
                    803:            &dma->dma_vaddr, BUS_DMA_NOWAIT);
                    804:        if (rc != 0) {
                    805:                printf("%s: couldn't map DMA memory for %d bytes (%d)\n",
                    806:                    sc->sc_dev.dv_xname, size, rc);
                    807:
                    808:                goto fail2;
                    809:        }
                    810:
                    811:        rc = bus_dmamap_load(sc->sc_dmat, dma->dma_map, dma->dma_vaddr,
                    812:            size, NULL, BUS_DMA_NOWAIT);
                    813:        if (rc != 0) {
                    814:                printf("%s: couldn't load DMA memory for %d bytes (%d)\n",
                    815:                    sc->sc_dev.dv_xname, size, rc);
                    816:
                    817:                goto fail3;
                    818:        }
                    819:
                    820:        dma->dma_paddr = dma->dma_map->dm_segs[0].ds_addr;
                    821:
                    822:        return 0;
                    823:
                    824: fail3:
                    825:        bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, size);
                    826: fail2:
                    827:        bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nsegs);
                    828: fail1:
                    829:        bus_dmamap_destroy(sc->sc_dmat, dma->dma_map);
                    830: fail0:
                    831:        return rc;
                    832: }
                    833:
                    834: void
                    835: glxsb_dma_pre_op(struct glxsb_softc *sc, struct glxsb_dma_map *dma)
                    836: {
                    837:        bus_dmamap_sync(sc->sc_dmat, dma->dma_map, 0, dma->dma_size,
                    838:            BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
                    839: }
                    840:
                    841: void
                    842: glxsb_dma_post_op(struct glxsb_softc *sc, struct glxsb_dma_map *dma)
                    843: {
                    844:        bus_dmamap_sync(sc->sc_dmat, dma->dma_map, 0, dma->dma_size,
                    845:            BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
                    846: }
                    847:
                    848: void
                    849: glxsb_dma_free(struct glxsb_softc *sc, struct glxsb_dma_map *dma)
                    850: {
                    851:        bus_dmamap_unload(sc->sc_dmat, dma->dma_map);
                    852:        bus_dmamem_unmap(sc->sc_dmat, dma->dma_vaddr, dma->dma_size);
                    853:        bus_dmamem_free(sc->sc_dmat, &dma->dma_seg, dma->dma_nsegs);
                    854:        bus_dmamap_destroy(sc->sc_dmat, dma->dma_map);
                    855: }
                    856:
                    857: #endif /* CRYPTO */

CVSweb