diff options
Diffstat (limited to 'sys/arch/i386/i386/machdep.c')
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 352 |
1 files changed, 5 insertions, 347 deletions
diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 04f78890f05..7aee063693d 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.288 2004/04/02 22:28:40 tedu Exp $ */ +/* $OpenBSD: machdep.c,v 1.289 2004/04/11 18:12:10 deraadt Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -101,11 +101,6 @@ #include <sys/msg.h> #endif -#ifdef CRYPTO -#include <crypto/cryptodev.h> -#include <crypto/rijndael.h> -#endif - #ifdef KGDB #include <sys/kgdb.h> #endif @@ -332,7 +327,6 @@ void tm86_cpu_setup(const char *, int, int); char * intel686_cpu_name(int); char * cyrix3_cpu_name(int, int); char * tm86_cpu_name(int); -void viac3_rnd(void *); int p4_cpuspeed(int *); int pentium_cpuspeed(int *); @@ -1116,346 +1110,6 @@ winchip_cpu_setup(cpu_device, model, step) #endif } -#if defined(I686_CPU) -/* - * Note, the VIA C3 Nehemiah provides 4 internal 8-byte buffers, which - * store random data, and can be accessed a lot quicker than waiting - * for new data to be generated. As we are using every 8th bit only - * due to whitening. Since the RNG generates in excess of 21KB/s at - * it's worst, collecting 64 bytes worth of entropy should not affect - * things significantly. - * - * Note, due to some weirdness in the RNG, we need at least 7 bytes - * extra on the end of our buffer. Also, there is an outside chance - * that the VIA RNG can "wedge", as the generated bit-rate is variable. - * We could do all sorts of startup testing and things, but - * frankly, I don't really see the point. If the RNG wedges, then the - * chances of you having a defective CPU are very high. Let it wedge. - * - * Adding to the whole confusion, in order to access the RNG, we need - * to have FXSR support enabled, and the correct FPU enable bits must - * be there to enable the FPU in kernel. It would be nice if all this - * mumbo-jumbo was not needed in order to use the RNG. Oh well, life - * does go on... - */ -#define VIAC3_RNG_BUFSIZ 16 /* 32bit words */ -struct timeout viac3_rnd_tmo; -int viac3_rnd_present = 0; - -void -viac3_rnd(void *v) -{ - struct timeout *tmo = v; - unsigned int *p, i, rv, creg0, len = VIAC3_RNG_BUFSIZ; - static int buffer[VIAC3_RNG_BUFSIZ + 2]; /* XXX why + 2? */ - - creg0 = rcr0(); /* Permit access to SIMD/FPU path */ - lcr0(creg0 & ~(CR0_EM|CR0_TS)); - - /* - * Here we collect the random data from the VIA C3 RNG. We make - * sure that we turn on maximum whitening (%edx[0,1] == "11"), so - * that we get the best random data possible. - */ - __asm __volatile("rep xstore-rng" - : "=a" (rv) : "d" (3), "D" (buffer), "c" (len*sizeof(int)) - : "memory", "cc"); - - lcr0(creg0); - - for (i = 0, p = buffer; i < VIAC3_RNG_BUFSIZ; i++, p++) - add_true_randomness(*p); - - timeout_add(tmo, (hz > 100) ? (hz / 100) : 1); -} - -#ifdef CRYPTO - -struct viac3_session { - u_int32_t ses_ekey[4 * (MAXNR + 1) + 4]; /* 128 bit aligned */ - u_int32_t ses_dkey[4 * (MAXNR + 1) + 4]; /* 128 bit aligned */ - u_int8_t ses_iv[16]; /* 128 bit aligned */ - u_int32_t ses_cw0; - int ses_klen; - int ses_used; - int ses_pad; /* to multiple of 16 */ -}; - -struct viac3_softc { - u_int32_t op_cw[4]; /* 128 bit aligned */ - u_int8_t op_iv[16]; /* 128 bit aligned */ - void *op_buf; - - /* normal softc stuff */ - int32_t sc_cid; - int sc_nsessions; - struct viac3_session *sc_sessions; -}; - -#define VIAC3_SESSION(sid) ((sid) & 0x0fffffff) -#define VIAC3_SID(crd,ses) (((crd) << 28) | ((ses) & 0x0fffffff)) - -static struct viac3_softc *vc3_sc; -int viac3_crypto_present; - -void viac3_crypto_setup(void); -int viac3_crypto_newsession(u_int32_t *, struct cryptoini *); -int viac3_crypto_process(struct cryptop *); -int viac3_crypto_freesession(u_int64_t); -static __inline void viac3_cbc(void *, void *, void *, void *, int, void *); - -void -viac3_crypto_setup(void) -{ - int algs[CRYPTO_ALGORITHM_MAX + 1]; - - if ((vc3_sc = malloc(sizeof(*vc3_sc), M_DEVBUF, M_NOWAIT)) == NULL) - return; /* YYY bitch? */ - bzero(vc3_sc, sizeof(*vc3_sc)); - - bzero(algs, sizeof(algs)); - algs[CRYPTO_AES_CBC] = CRYPTO_ALG_FLAG_SUPPORTED; - - vc3_sc->sc_cid = crypto_get_driverid(0); - if (vc3_sc->sc_cid < 0) - return; /* YYY bitch? */ - - crypto_register(vc3_sc->sc_cid, algs, viac3_crypto_newsession, - viac3_crypto_freesession, viac3_crypto_process); - i386_has_xcrypt = 1; -} - -int -viac3_crypto_newsession(u_int32_t *sidp, struct cryptoini *cri) -{ - struct viac3_softc *sc = vc3_sc; - struct viac3_session *ses = NULL; - int sesn, i, cw0; - - if (sc == NULL || sidp == NULL || cri == NULL || - cri->cri_next != NULL || cri->cri_alg != CRYPTO_AES_CBC) - return (EINVAL); - - switch (cri->cri_klen) { - case 128: - cw0 = C3_CRYPT_CWLO_KEY128; - break; - case 192: - cw0 = C3_CRYPT_CWLO_KEY192; - break; - case 256: - cw0 = C3_CRYPT_CWLO_KEY256; - break; - default: - return (EINVAL); - } - cw0 |= C3_CRYPT_CWLO_ALG_AES | C3_CRYPT_CWLO_KEYGEN_SW | - C3_CRYPT_CWLO_NORMAL; - - if (sc->sc_sessions == NULL) { - ses = sc->sc_sessions = (struct viac3_session *)malloc( - sizeof(*ses), M_DEVBUF, M_NOWAIT); - if (ses == NULL) - return (ENOMEM); - sesn = 0; - sc->sc_nsessions = 1; - } else { - for (sesn = 0; sesn < sc->sc_nsessions; sesn++) { - if (sc->sc_sessions[sesn].ses_used == 0) { - ses = &sc->sc_sessions[sesn]; - break; - } - } - - if (ses == NULL) { - sesn = sc->sc_nsessions; - ses = (struct viac3_session *)malloc((sesn + 1) * - sizeof(*ses), M_DEVBUF, M_NOWAIT); - if (ses == NULL) - return (ENOMEM); - bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses)); - bzero(sc->sc_sessions, sesn * sizeof(*ses)); - free(sc->sc_sessions, M_DEVBUF); - sc->sc_sessions = ses; - ses = &sc->sc_sessions[sesn]; - sc->sc_nsessions++; - } - } - - bzero(ses, sizeof(*ses)); - ses->ses_used = 1; - - get_random_bytes(ses->ses_iv, sizeof(ses->ses_iv)); - ses->ses_klen = cri->cri_klen; - ses->ses_cw0 = cw0; - - /* Build expanded keys for both directions */ - rijndaelKeySetupEnc(ses->ses_ekey, cri->cri_key, cri->cri_klen); - rijndaelKeySetupDec(ses->ses_dkey, cri->cri_key, cri->cri_klen); - for (i = 0; i < 4 * (MAXNR + 1); i++) { - ses->ses_ekey[i] = ntohl(ses->ses_ekey[i]); - ses->ses_dkey[i] = ntohl(ses->ses_dkey[i]); - } - - *sidp = VIAC3_SID(0, sesn); - return (0); -} - -int -viac3_crypto_freesession(u_int64_t tid) -{ - struct viac3_softc *sc = vc3_sc; - int sesn; - u_int32_t sid = ((u_int32_t)tid) & 0xffffffff; - - if (sc == NULL) - return (EINVAL); - sesn = VIAC3_SESSION(sid); - if (sesn >= sc->sc_nsessions) - return (EINVAL); - bzero(&sc->sc_sessions[sesn], sizeof(sc->sc_sessions[sesn])); - return (0); -} - -static __inline void -viac3_cbc(void *cw, void *src, void *dst, void *key, int rep, - void *iv) -{ - unsigned int creg0; - - creg0 = rcr0(); /* Permit access to SIMD/FPU path */ - lcr0(creg0 & ~(CR0_EM|CR0_TS)); - - /* Do the deed */ - __asm __volatile("pushfl; popfl"); - __asm __volatile("rep xcrypt-cbc" : - : "a" (iv), "b" (key), "c" (rep), "d" (cw), "S" (src), "D" (dst) - : "memory", "cc"); - - lcr0(creg0); -} - -int -viac3_crypto_process(struct cryptop *crp) -{ - struct viac3_softc *sc = vc3_sc; - struct viac3_session *ses; - struct cryptodesc *crd; - int sesn, err = 0; - u_int32_t *key; - - if (crp == NULL || crp->crp_callback == NULL) { - err = EINVAL; - goto out; - } - crd = crp->crp_desc; - if (crd == NULL || crd->crd_next != NULL || - crd->crd_alg != CRYPTO_AES_CBC || - (crd->crd_len % 16) != 0) { - err = EINVAL; - goto out; - } - - sesn = VIAC3_SESSION(crp->crp_sid); - if (sesn >= sc->sc_nsessions) { - err = EINVAL; - goto out; - } - ses = &sc->sc_sessions[sesn]; - - sc->op_buf = (char *)malloc(crd->crd_len, M_DEVBUF, M_NOWAIT); - if (sc->op_buf == NULL) { - err = ENOMEM; - goto out; - } - - if (crd->crd_flags & CRD_F_ENCRYPT) { - sc->op_cw[0] = ses->ses_cw0 | C3_CRYPT_CWLO_ENCRYPT; - key = ses->ses_ekey; - if (crd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(crd->crd_iv, sc->op_iv, 16); - else - bcopy(ses->ses_iv, sc->op_iv, 16); - - if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) { - if (crp->crp_flags & CRYPTO_F_IMBUF) - m_copyback((struct mbuf *)crp->crp_buf, - crd->crd_inject, 16, sc->op_iv); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copyback((struct uio *)crp->crp_buf, - crd->crd_inject, 16, sc->op_iv); - else - bcopy(sc->op_iv, - crp->crp_buf + crd->crd_inject, 16); - } - } else { - sc->op_cw[0] = ses->ses_cw0 | C3_CRYPT_CWLO_DECRYPT; - key = ses->ses_dkey; - if (crd->crd_flags & CRD_F_IV_EXPLICIT) - bcopy(crd->crd_iv, sc->op_iv, 16); - else { - if (crp->crp_flags & CRYPTO_F_IMBUF) - m_copydata((struct mbuf *)crp->crp_buf, - crd->crd_inject, 16, sc->op_iv); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copydata((struct uio *)crp->crp_buf, - crd->crd_inject, 16, sc->op_iv); - else - bcopy(crp->crp_buf + crd->crd_inject, - sc->op_iv, 16); - } - } - - if (crp->crp_flags & CRYPTO_F_IMBUF) - m_copydata((struct mbuf *)crp->crp_buf, - crd->crd_skip, crd->crd_len, sc->op_buf); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copydata((struct uio *)crp->crp_buf, - crd->crd_skip, crd->crd_len, sc->op_buf); - else - bcopy(crp->crp_buf + crd->crd_skip, sc->op_buf, crd->crd_len); - - sc->op_cw[1] = sc->op_cw[2] = sc->op_cw[3] = 0; - viac3_cbc(&sc->op_cw, sc->op_buf, sc->op_buf, key, - crd->crd_len / 16, sc->op_iv); - - if (crp->crp_flags & CRYPTO_F_IMBUF) - m_copyback((struct mbuf *)crp->crp_buf, - crd->crd_skip, crd->crd_len, sc->op_buf); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copyback((struct uio *)crp->crp_buf, - crd->crd_skip, crd->crd_len, sc->op_buf); - else - bcopy(sc->op_buf, crp->crp_buf + crd->crd_skip, crd->crd_len); - - /* copy out last block for use as next session IV */ - if (crd->crd_flags & CRD_F_ENCRYPT) { - if (crp->crp_flags & CRYPTO_F_IMBUF) - m_copydata((struct mbuf *)crp->crp_buf, - crd->crd_skip + crd->crd_len - 16, 16, ses->ses_iv); - else if (crp->crp_flags & CRYPTO_F_IOV) - cuio_copydata((struct uio *)crp->crp_buf, - crd->crd_skip + crd->crd_len - 16, 16, sc->op_iv); - else - bcopy(crp->crp_buf + crd->crd_skip + crd->crd_len - 16, - sc->op_iv, 16); - } - -out: - if (sc->op_buf != NULL) { - bzero(sc->op_buf, crd->crd_len); - free(sc->op_buf, M_DEVBUF); - sc->op_buf = NULL; - } - crp->crp_etype = err; - crypto_done(crp); - return (err); -} - -#endif /* CRYPTO */ - -#endif /* defined(I686_CPU) */ - void cyrix3_cpu_setup(cpu_device, model, step) const char *cpu_device; @@ -1510,6 +1164,8 @@ cyrix3_cpu_setup(cpu_device, model, step) if (val & 0x44) printf("%s:", cpu_device); if (val & 0x4) { + extern int viac3_rnd_present; + if (!(val & 0x8)) { u_int64_t msreg; @@ -1524,6 +1180,8 @@ cyrix3_cpu_setup(cpu_device, model, step) #ifdef CRYPTO /* Enable AES engine if present and disabled */ if (val & 0x40) { + extern int viac3_crypto_present; + if (!(val & 0x80)) { u_int64_t msreg; |