diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2003-10-09 03:47:21 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2003-10-09 03:47:21 +0000 |
commit | 942bb408975cf1e1176c15776d03c57e6132adee (patch) | |
tree | 52fa65485225b71b2ea4605a9c25cd857c72f963 /sys | |
parent | 8f167219007d99193220cb340c7fb5e760fccf3d (diff) |
- from freebsd: 795[56] AES support
- don't bother with the master/mmio enable stuff (it's done in pci.c for us)
based on suggestion from mickey
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/hifn7751.c | 165 | ||||
-rw-r--r-- | sys/dev/pci/hifn7751reg.h | 14 | ||||
-rw-r--r-- | sys/dev/pci/hifn7751var.h | 20 |
3 files changed, 137 insertions, 62 deletions
diff --git a/sys/dev/pci/hifn7751.c b/sys/dev/pci/hifn7751.c index 9fc43d4bd8a..5755beffad7 100644 --- a/sys/dev/pci/hifn7751.c +++ b/sys/dev/pci/hifn7751.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hifn7751.c,v 1.143 2003/09/25 15:40:54 jason Exp $ */ +/* $OpenBSD: hifn7751.c,v 1.144 2003/10/09 03:47:20 jason Exp $ */ /* * Invertex AEON / Hifn 7751 driver @@ -6,7 +6,8 @@ * Copyright (c) 1999 Theo de Raadt * Copyright (c) 2000-2001 Network Security Technologies, Inc. * http://www.netsec.net - * + * Copyright (c) 2003 Hifn Inc. + * This driver is based on a previous driver by Invertex, for which they * requested: Please send any comments, feedback, bug-fixes, or feature * requests to software@invertex.com. @@ -41,7 +42,7 @@ */ /* - * Driver for the Hifn 7751 encryption processor. + * Driver for various Hifn encryption processors. */ #include <sys/param.h> @@ -159,28 +160,27 @@ hifn_attach(struct device *parent, struct device *self, void *aux) sc->sc_pci_tag = pa->pa_tag; if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_HIFN && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7951 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7955 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7956)) + (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7951)) sc->sc_flags = HIFN_HAS_RNG | HIFN_HAS_PUBLIC; if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_HIFN && + (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7955 || + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7956)) + sc->sc_flags = HIFN_IS_7956 | HIFN_HAS_AES | HIFN_HAS_RNG | + HIFN_HAS_PUBLIC; + + if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_HIFN && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7811) sc->sc_flags |= HIFN_IS_7811 | HIFN_HAS_RNG | HIFN_HAS_LEDS | HIFN_NO_BURSTWRITE; cmd = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); - cmd |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE; - pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, cmd); - cmd = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); - if (!(cmd & PCI_COMMAND_MEM_ENABLE)) { - printf(": failed to enable memory mapping\n"); + printf(": memory mapping not enabled\n"); return; } - if (!(cmd & PCI_COMMAND_MASTER_ENABLE)) { - printf(": failed to enable bus mastering\n"); + printf(": bus mastering not enabled\n"); return; } @@ -245,7 +245,9 @@ hifn_attach(struct device *parent, struct device *self, void *aux) hifn_init_dma(sc); hifn_init_pci_registers(sc); - if (hifn_ramtype(sc)) + if (sc->sc_flags & HIFN_IS_7956) + sc->sc_drammodel = 1; + else if (hifn_ramtype(sc)) goto fail_mem; if (sc->sc_drammodel == 0) @@ -277,13 +279,7 @@ hifn_attach(struct device *parent, struct device *self, void *aux) goto fail_mem; } - if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_HIFN && - (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7955 || - PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7956)) { - sc->sc_maxses = 125; - sc->sc_ramsize = 32 * 1024; - } else - hifn_sessions(sc); + hifn_sessions(sc); rseg = sc->sc_ramsize / 1024; rbase = 'K'; @@ -317,6 +313,8 @@ hifn_attach(struct device *parent, struct device *self, void *aux) algs[CRYPTO_SHA1_HMAC] = CRYPTO_ALG_FLAG_SUPPORTED; algs[CRYPTO_DES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; } + if (sc->sc_flags & HIFN_HAS_AES) + algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; crypto_register(sc->sc_cid, algs, hifn_newsession, hifn_freesession, hifn_process); @@ -770,10 +768,17 @@ hifn_init_pci_registers(struct hifn_softc *sc) WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier); CLR_LED(sc, HIFN_MIPSRST_LED0 | HIFN_MIPSRST_LED1 | HIFN_MIPSRST_LED2); - WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING | - HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES | - HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 | - (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM)); + if (sc->sc_flags & HIFN_IS_7956) { + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING | + HIFN_PUCNFG_TCALLPHASES | + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32); + WRITE_REG_1(sc, HIFN_1_PLL, HIFN_PLL_7956); + } else { + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING | + HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES | + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 | + (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM)); + } WRITE_REG_0(sc, HIFN_0_PUISR, HIFN_PUISR_DSTOVER); WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET | @@ -802,8 +807,14 @@ hifn_sessions(struct hifn_softc *sc) ctxsize = 128; else ctxsize = 512; - sc->sc_maxses = 1 + - ((sc->sc_ramsize - 32768) / ctxsize); + /* + * 7955/7956 has internal context memory of 32K + */ + if (sc->sc_flags & HIFN_IS_7956) + sc->sc_maxses = 32768 / ctxsize; + else + sc->sc_maxses = 1 + + ((sc->sc_ramsize - 32768) / ctxsize); } else sc->sc_maxses = sc->sc_ramsize / 16384; @@ -891,9 +902,16 @@ hifn_dramsize(struct hifn_softc *sc) { u_int32_t cnfg; - cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) & - HIFN_PUCNFG_DRAMMASK; - sc->sc_ramsize = 1 << ((cnfg >> 13) + 18); + if (sc->sc_flags & HIFN_IS_7956) { + /* + * 7956/7956 have a fixed internal ram of only 32K. + */ + sc->sc_ramsize = 32768; + } else { + cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) & + HIFN_PUCNFG_DRAMMASK; + sc->sc_ramsize = 1 << ((cnfg >> 13) + 18); + } return (0); } @@ -1123,7 +1141,7 @@ hifn_write_command(struct hifn_command *cmd, u_int8_t *buf) struct hifn_mac_command *mac_cmd; struct hifn_crypt_command *cry_cmd; struct hifn_comp_command *comp_cmd; - int using_mac, using_crypt, using_comp, len; + int using_mac, using_crypt, using_comp, len, ivlen; u_int32_t dlen, slen; buf_pos = buf; @@ -1197,7 +1215,7 @@ hifn_write_command(struct hifn_command *cmd, u_int8_t *buf) break; case HIFN_CRYPT_CMD_ALG_DES: bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH); - buf_pos += cmd->cklen; + buf_pos += HIFN_DES_KEY_LENGTH; break; case HIFN_CRYPT_CMD_ALG_RC4: len = 256; @@ -1212,12 +1230,25 @@ hifn_write_command(struct hifn_command *cmd, u_int8_t *buf) bzero(buf_pos, 4); buf_pos += 4; break; + case HIFN_CRYPT_CMD_ALG_AES: + /* + * AES key are variable 128, 192 and + * 256 bits (16, 24 and 32 bytes). + */ + bcopy(cmd->ck, buf_pos, cmd->cklen); + buf_pos += cmd->cklen; + break; } } if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_IV) { - bcopy(cmd->iv, buf_pos, HIFN_IV_LENGTH); - buf_pos += HIFN_IV_LENGTH; + if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) == + HIFN_CRYPT_CMD_ALG_AES) + ivlen = HIFN_AES_IV_LENGTH; + else + ivlen = HIFN_IV_LENGTH; + bcopy(cmd->iv, buf_pos, ivlen); + buf_pos += ivlen; } if ((cmd->base_masks & (HIFN_BASE_CMD_MAC | HIFN_BASE_CMD_CRYPT | @@ -1817,8 +1848,10 @@ hifn_newsession(u_int32_t *sidp, struct cryptoini *cri) break; case CRYPTO_DES_CBC: case CRYPTO_3DES_CBC: + case CRYPTO_AES_CBC: get_random_bytes(sc->sc_sessions[i].hs_iv, - HIFN_IV_LENGTH); + (c->cri_alg == CRYPTO_AES_CBC ? + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH)); /*FALLTHROUGH*/ case CRYPTO_ARC4: if (cry) @@ -1879,7 +1912,7 @@ int hifn_process(struct cryptop *crp) { struct hifn_command *cmd = NULL; - int card, session, err; + int card, session, err, ivlen; struct hifn_softc *sc; struct cryptodesc *crd1, *crd2, *maccrd, *enccrd; @@ -1936,6 +1969,7 @@ hifn_process(struct cryptop *crp) enccrd = NULL; } else if (crd1->crd_alg == CRYPTO_DES_CBC || crd1->crd_alg == CRYPTO_3DES_CBC || + crd1->crd_alg == CRYPTO_AES_CBC || crd1->crd_alg == CRYPTO_ARC4) { if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0) cmd->base_masks |= HIFN_BASE_CMD_DECODE; @@ -1954,6 +1988,7 @@ hifn_process(struct cryptop *crp) crd1->crd_alg == CRYPTO_SHA1) && (crd2->crd_alg == CRYPTO_DES_CBC || crd2->crd_alg == CRYPTO_3DES_CBC || + crd2->crd_alg == CRYPTO_AES_CBC || crd2->crd_alg == CRYPTO_ARC4) && ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) { cmd->base_masks = HIFN_BASE_CMD_DECODE; @@ -1961,6 +1996,7 @@ hifn_process(struct cryptop *crp) enccrd = crd2; } else if ((crd1->crd_alg == CRYPTO_DES_CBC || crd1->crd_alg == CRYPTO_ARC4 || + crd1->crd_alg == CRYPTO_AES_CBC || crd1->crd_alg == CRYPTO_3DES_CBC) && (crd2->crd_alg == CRYPTO_MD5_HMAC || crd2->crd_alg == CRYPTO_SHA1_HMAC || @@ -1999,48 +2035,74 @@ hifn_process(struct cryptop *crp) HIFN_CRYPT_CMD_MODE_CBC | HIFN_CRYPT_CMD_NEW_IV; break; + case CRYPTO_AES_CBC: + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES | + HIFN_CRYPT_CMD_MODE_CBC | + HIFN_CRYPT_CMD_NEW_IV; + break; default: err = EINVAL; goto errout; } if (enccrd->crd_alg != CRYPTO_ARC4) { + ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ? + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH); if (enccrd->crd_flags & CRD_F_ENCRYPT) { if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(enccrd->crd_iv, cmd->iv, - HIFN_IV_LENGTH); + bcopy(enccrd->crd_iv, cmd->iv, ivlen); else bcopy(sc->sc_sessions[session].hs_iv, - cmd->iv, HIFN_IV_LENGTH); + cmd->iv, ivlen); if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) { if (crp->crp_flags & CRYPTO_F_IMBUF) m_copyback(cmd->srcu.src_m, enccrd->crd_inject, - HIFN_IV_LENGTH, cmd->iv); + ivlen, cmd->iv); else if (crp->crp_flags & CRYPTO_F_IOV) cuio_copyback(cmd->srcu.src_io, enccrd->crd_inject, - HIFN_IV_LENGTH, cmd->iv); + ivlen, cmd->iv); } } else { if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(enccrd->crd_iv, cmd->iv, - HIFN_IV_LENGTH); + bcopy(enccrd->crd_iv, cmd->iv, ivlen); else if (crp->crp_flags & CRYPTO_F_IMBUF) m_copydata(cmd->srcu.src_m, enccrd->crd_inject, - HIFN_IV_LENGTH, cmd->iv); + ivlen, cmd->iv); else if (crp->crp_flags & CRYPTO_F_IOV) cuio_copydata(cmd->srcu.src_io, enccrd->crd_inject, - HIFN_IV_LENGTH, cmd->iv); + ivlen, cmd->iv); } } cmd->ck = enccrd->crd_key; cmd->cklen = enccrd->crd_klen >> 3; + /* + * Need to specify the size for the AES key in the masks. + */ + if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) == + HIFN_CRYPT_CMD_ALG_AES) { + switch (cmd->cklen) { + case 16: + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128; + break; + case 24: + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192; + break; + case 32: + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256; + break; + default: + err = EINVAL; + goto errout; + } + } + if (sc->sc_sessions[session].hs_state == HS_STATE_USED) cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY; } @@ -2188,7 +2250,7 @@ hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, struct cryptop *crp = cmd->crp; struct cryptodesc *crd; struct mbuf *m; - int totlen, i, u; + int totlen, i, u, ivlen; if (cmd->src_map == cmd->dst_map) bus_dmamap_sync(sc->sc_dmat, cmd->src_map, @@ -2254,17 +2316,18 @@ hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, HIFN_BASE_CMD_CRYPT) { for (crd = crp->crp_desc; crd; crd = crd->crd_next) { if (crd->crd_alg != CRYPTO_DES_CBC && - crd->crd_alg != CRYPTO_3DES_CBC) + crd->crd_alg != CRYPTO_3DES_CBC && + crd->crd_alg != CRYPTO_AES_CBC) continue; + ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ? + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH); if (crp->crp_flags & CRYPTO_F_IMBUF) m_copydata((struct mbuf *)crp->crp_buf, - crd->crd_skip + crd->crd_len - HIFN_IV_LENGTH, - HIFN_IV_LENGTH, + crd->crd_skip + crd->crd_len - ivlen, ivlen, cmd->softc->sc_sessions[cmd->session_num].hs_iv); else if (crp->crp_flags & CRYPTO_F_IOV) { cuio_copydata((struct uio *)crp->crp_buf, - crd->crd_skip + crd->crd_len - HIFN_IV_LENGTH, - HIFN_IV_LENGTH, + crd->crd_skip + crd->crd_len - ivlen, ivlen, cmd->softc->sc_sessions[cmd->session_num].hs_iv); } break; diff --git a/sys/dev/pci/hifn7751reg.h b/sys/dev/pci/hifn7751reg.h index 05ca98a7978..420365a3222 100644 --- a/sys/dev/pci/hifn7751reg.h +++ b/sys/dev/pci/hifn7751reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hifn7751reg.h,v 1.43 2003/06/02 15:58:41 deraadt Exp $ */ +/* $OpenBSD: hifn7751reg.h,v 1.44 2003/10/09 03:47:20 jason Exp $ */ /* * Invertex AEON / Hifn 7751 driver @@ -191,6 +191,7 @@ struct hifn_desc { #define HIFN_1_DMA_CSR 0x40 /* DMA Status and Control */ #define HIFN_1_DMA_IER 0x44 /* DMA Interrupt Enable */ #define HIFN_1_DMA_CNFG 0x48 /* DMA Configuration */ +#define HIFN_1_PLL 0x4c /* 795x: PLL config */ #define HIFN_1_7811_RNGENA 0x60 /* 7811: rng enable */ #define HIFN_1_7811_RNGCFG 0x64 /* 7811: rng config */ #define HIFN_1_7811_RNGDAT 0x68 /* 7811: rng data */ @@ -307,6 +308,9 @@ struct hifn_desc { #define HIFN_MIPSRST_MIPSRST 0x00000002 /* warm reset MIPS */ #define HIFN_MIPSRST_MIPSCOLD 0x00000001 /* cold reset MIPS */ +/* PLL config register (HIFN_1_PLL) */ +#define HIFN_PLL_7956 0x00001d18 /* 7956 PLL config value */ + /* Revision ID */ #define HIFN_REVID_7811_PB3_2 0x00000002 /* 7811PB3/2 */ @@ -397,15 +401,19 @@ struct hifn_crypt_command { #define HIFN_CRYPT_CMD_ALG_DES 0x0000 /* DES */ #define HIFN_CRYPT_CMD_ALG_3DES 0x0001 /* 3DES */ #define HIFN_CRYPT_CMD_ALG_RC4 0x0002 /* RC4 */ -#define HIFN_CRYPT_CMD_MODE_MASK 0x0018 /* DES mode: */ +#define HIFN_CRYPT_CMD_ALG_AES 0x0003 /* AES */ +#define HIFN_CRYPT_CMD_MODE_MASK 0x0018 /* Encrypt mode: */ #define HIFN_CRYPT_CMD_MODE_ECB 0x0000 /* ECB */ #define HIFN_CRYPT_CMD_MODE_CBC 0x0008 /* CBC */ #define HIFN_CRYPT_CMD_MODE_CFB 0x0010 /* CFB */ #define HIFN_CRYPT_CMD_MODE_OFB 0x0018 /* OFB */ #define HIFN_CRYPT_CMD_CLR_CTX 0x0040 /* clear context */ +#define HIFN_CRYPT_CMD_KSZ_MASK 0x0600 /* AES key size: */ +#define HIFN_CRYPT_CMD_KSZ_128 0x0000 /* 128 bit */ +#define HIFN_CRYPT_CMD_KSZ_192 0x0200 /* 192 bit */ +#define HIFN_CRYPT_CMD_KSZ_256 0x0400 /* 256 bit */ #define HIFN_CRYPT_CMD_NEW_KEY 0x0800 /* expect new key */ #define HIFN_CRYPT_CMD_NEW_IV 0x1000 /* expect new iv */ - #define HIFN_CRYPT_CMD_SRCLEN_M 0xc000 #define HIFN_CRYPT_CMD_SRCLEN_S 14 diff --git a/sys/dev/pci/hifn7751var.h b/sys/dev/pci/hifn7751var.h index 03ca40aeb41..b168afa4338 100644 --- a/sys/dev/pci/hifn7751var.h +++ b/sys/dev/pci/hifn7751var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hifn7751var.h,v 1.50 2003/06/02 15:58:42 deraadt Exp $ */ +/* $OpenBSD: hifn7751var.h,v 1.51 2003/10/09 03:47:20 jason Exp $ */ /* * Invertex AEON / Hifn 7751 driver @@ -59,6 +59,8 @@ #define HIFN_3DES_KEY_LENGTH 24 #define HIFN_MAX_CRYPT_KEY_LENGTH HIFN_3DES_KEY_LENGTH #define HIFN_IV_LENGTH 8 +#define HIFN_AES_IV_LENGTH 16 +#define HIFN_MAX_IV_LENGTH HIFN_AES_IV_LENGTH /* * Length values for authentication @@ -103,7 +105,7 @@ struct hifn_dma { struct hifn_session { int hs_state; int hs_prev_op; /* XXX collapse into hs_flags? */ - u_int8_t hs_iv[HIFN_IV_LENGTH]; + u_int8_t hs_iv[HIFN_MAX_IV_LENGTH]; }; /* We use a state machine on sessions */ @@ -151,11 +153,13 @@ struct hifn_softc { int sc_maxses; int sc_ramsize; int sc_flags; -#define HIFN_HAS_RNG 1 -#define HIFN_HAS_PUBLIC 2 -#define HIFN_IS_7811 4 -#define HIFN_NO_BURSTWRITE 8 -#define HIFN_HAS_LEDS 16 +#define HIFN_HAS_RNG 0x01 /* includes random number generator */ +#define HIFN_HAS_PUBLIC 0x02 /* includes public key support */ +#define HIFN_IS_7811 0x04 /* Hifn 7811 part */ +#define HIFN_NO_BURSTWRITE 0x08 /* can't handle PCI burst writes */ +#define HIFN_HAS_LEDS 0x10 /* Has LEDs to blink */ +#define HIFN_HAS_AES 0x20 /* includes AES support */ +#define HIFN_IS_7956 0x40 /* Hifn 7955/7956 part */ struct timeout sc_rngto, sc_tickto; int sc_rngfirst; int sc_rnghz; @@ -249,7 +253,7 @@ struct hifn_softc { struct hifn_command { u_int16_t session_num; u_int16_t base_masks, cry_masks, mac_masks, comp_masks; - u_int8_t iv[HIFN_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH]; + u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH]; int cklen; int sloplen, slopidx; |