tech-crypto archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
VIA ACE patch
Hi,
I have mostly completed my port of the OpenBSD VIA ACE code, and I have
attached a patch. This area is pretty new to me, so please be gentle.
-- Daniel
Index: sys/arch/i386/conf/GENERIC
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/conf/GENERIC,v
retrieving revision 1.803
diff -u -r1.803 GENERIC
--- sys/arch/i386/conf/GENERIC 17 Dec 2006 23:02:06 -0000 1.803
+++ sys/arch/i386/conf/GENERIC 12 Jan 2007 16:26:28 -0000
@@ -52,6 +52,9 @@
# AMD PowerNow! and Cool`n'Quiet technology
options POWERNOW_K8
+# VIA PadLock
+#options VIA_PADLOCK
+
options MTRR # memory-type range register syscall support
# doesn't work with MP just yet..
#options PERFCTRS # performance-monitoring counters support
Index: sys/arch/i386/i386/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/autoconf.c,v
retrieving revision 1.84
diff -u -r1.84 autoconf.c
--- sys/arch/i386/i386/autoconf.c 7 Jun 2006 22:37:58 -0000 1.84
+++ sys/arch/i386/i386/autoconf.c 12 Jan 2007 16:26:28 -0000
@@ -91,6 +91,8 @@
#include <machine/kvm86.h>
#endif
+#include "opt_viapadlock.h"
+
/*
* Determine i/o configuration for a machine.
*/
@@ -139,4 +141,10 @@
#if NLAPIC > 0
lapic_tpr = 0;
#endif
+
+#if defined(I686_CPU)
+#ifdef VIA_PADLOCK
+ via_padlock_attach();
+#endif /* VIA_PADLOCK */
+#endif /* defined(I686_CPU) */
}
Index: sys/arch/i386/i386/identcpu.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/identcpu.c,v
retrieving revision 1.52
diff -u -r1.52 identcpu.c
--- sys/arch/i386/i386/identcpu.c 1 Jan 2007 20:56:58 -0000 1.52
+++ sys/arch/i386/i386/identcpu.c 12 Jan 2007 16:26:28 -0000
@@ -652,8 +652,10 @@
void
via_cpu_probe(struct cpu_info *ci)
{
+ u_int model = CPUID2MODEL(ci->ci_signature);
+ u_int stepping = CPUID2STEPPING(ci->ci_signature);
u_int descs[4];
- u_int lfunc;
+ u_int lfunc, msr;
/*
* Determine the largest extended function value.
@@ -668,6 +670,24 @@
CPUID(0x80000001, descs[0], descs[1], descs[2], descs[3]);
ci->ci_feature_flags |= descs[3];
}
+
+ if (model >= 0x9) {
+ /* Nehemiah or Esther */
+ CPUID(0xc0000000, descs[0], descs[1], descs[2], descs[3]);
+ lfunc = descs[0];
+ if (lfunc == 0xc0000001) {
+ CPUID(lfunc, descs[0], descs[1], descs[2], descs[3]);
+ lfunc = descs[3];
+ if (model > 0x9 || stepping >= 8) { /* ACE */
+ if ((lfunc & 0xc0) == 0xc0) {
+ ci->ci_padlock_flags |= CPUID_FEAT_VACE;
+ msr = rdmsr(MSR_VIA_ACE);
+ wrmsr(MSR_VIA_ACE,
+ msr | MSR_VIA_ACE_ENABLE);
+ }
+ }
+ }
+ }
}
const char *
Index: sys/arch/i386/i386/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.592
diff -u -r1.592 machdep.c
--- sys/arch/i386/i386/machdep.c 7 Jan 2007 01:04:26 -0000 1.592
+++ sys/arch/i386/i386/machdep.c 12 Jan 2007 16:26:28 -0000
@@ -236,6 +236,7 @@
int dumpmem_high;
unsigned int cpu_feature;
unsigned int cpu_feature2;
+unsigned int cpu_feature_padlock;
int cpu_class;
int i386_fpu_present;
int i386_fpu_exception;
@@ -1516,6 +1517,7 @@
cpu_probe_features(&cpu_info_primary);
cpu_feature = cpu_info_primary.ci_feature_flags;
cpu_feature2 = cpu_info_primary.ci_feature2_flags;
+ cpu_feature_padlock = cpu_info_primary.ci_padlock_flags;
proc0paddr = UAREA_TO_USER(proc0uarea);
lwp0.l_addr = proc0paddr;
Index: sys/arch/i386/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/include/cpu.h,v
retrieving revision 1.130
diff -u -r1.130 cpu.h
--- sys/arch/i386/include/cpu.h 8 Dec 2006 15:05:18 -0000 1.130
+++ sys/arch/i386/include/cpu.h 12 Jan 2007 16:26:28 -0000
@@ -54,6 +54,7 @@
#include <machine/tss.h>
#include <machine/intrdefs.h>
#include <x86/cacheinfo.h>
+#include <x86/via_padlock.h>
#include <sys/device.h>
#include <sys/lock.h> /* will also get LOCKDEBUG */
@@ -123,6 +124,7 @@
uint32_t ci_feature_flags;/* X86 %edx CPUID feature bits */
uint32_t ci_feature2_flags;/* X86 %ecx CPUID feature bits */
uint32_t ci_feature3_flags;/* X86 extended feature bits */
+ uint32_t ci_padlock_flags;/* VIA PadLock feature bits */
uint32_t ci_cpu_class; /* CPU class */
uint32_t ci_brand_id; /* Intel brand id */
uint32_t ci_vendor[4]; /* vendor string */
@@ -150,6 +152,8 @@
char *ci_ddbipi_stack;
struct evcnt ci_ipi_events[X86_NIPI];
+
+ struct via_padlock ci_vp; /* VIA PadLock private storage */
};
/*
@@ -335,6 +339,7 @@
extern int biosextmem;
extern unsigned int cpu_feature;
extern unsigned int cpu_feature2;
+extern unsigned int cpu_feature_padlock;
extern int cpu;
extern int cpu_class;
extern char cpu_brand_string[];
Index: sys/arch/x86/conf/files.x86
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/conf/files.x86,v
retrieving revision 1.21
diff -u -r1.21 files.x86
--- sys/arch/x86/conf/files.x86 1 Jan 2007 20:56:59 -0000 1.21
+++ sys/arch/x86/conf/files.x86 12 Jan 2007 16:26:28 -0000
@@ -13,6 +13,10 @@
# AMD Powernow/Cool`n'Quiet Technology
defflag opt_powernow_k8.h POWERNOW_K8
+# VIA PadLock support
+defflag opt_viapadlock.h VIA_PADLOCK: opencrypto
+file arch/x86/x86/via_padlock.c via_padlock
+
define cpubus { [apid = -1] }
define ipmibus {}
Index: sys/arch/x86/include/specialreg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/include/specialreg.h,v
retrieving revision 1.12
diff -u -r1.12 specialreg.h
--- sys/arch/x86/include/specialreg.h 1 Jan 2007 20:56:59 -0000 1.12
+++ sys/arch/x86/include/specialreg.h 12 Jan 2007 16:26:28 -0000
@@ -155,6 +155,13 @@
"\0373DNOW2\0403DNOW"
/*
+ * "Features" that are copied from elsewhere -- not necessarily tied to
+ * a specific CPUID response
+ */
+
+#define CPUID_FEAT_VACE 0x00000002 /* VIA C3 AES Crypto Extension
*/
+
+/*
* CPUID "features" bits in %ecx
*/
@@ -278,6 +285,18 @@
#define MSR_MC3_MISC 0x413
/*
+ * VIA "Nehemiah" MSRs
+ */
+#define MSR_VIA_RNG 0x110b
+#define MSR_VIA_RNG_ENABLE 0x00000040
+#define MSR_VIA_RNG_NOISE_MASK 0x00000300
+#define MSR_VIA_RNG_NOISE_A 0x00000000
+#define MSR_VIA_RNG_NOISE_B 0x00000100
+#define MSR_VIA_RNG_2NOISE 0x00000300
+#define MSR_VIA_ACE 0x1107
+#define MSR_VIA_ACE_ENABLE 0x10000000
+
+/*
* AMD K6/K7 MSRs.
*/
#define MSR_K6_UWCCR 0xc0000085
Index: sys/arch/x86/include/via_padlock.h
===================================================================
RCS file: sys/arch/x86/include/via_padlock.h
diff -N sys/arch/x86/include/via_padlock.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/arch/x86/include/via_padlock.h 12 Jan 2007 16:26:28 -0000
@@ -0,0 +1,77 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 2003 Jason Wright
+ * Copyright (c) 2003, 2004 Theo de Raadt
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _X86_VIA_PADLOCK_H_
+#define _X86_VIA_PADLOCK_H_
+
+#ifdef _KERNEL
+
+#include <crypto/rijndael/rijndael.h>
+
+/* VIA C3 xcrypt-* instruction context control options */
+#define C3_CRYPT_CWLO_ROUND_M 0x0000000f
+#define C3_CRYPT_CWLO_ALG_M 0x00000070
+#define C3_CRYPT_CWLO_ALG_AES 0x00000000
+#define C3_CRYPT_CWLO_KEYGEN_M 0x00000080
+#define C3_CRYPT_CWLO_KEYGEN_HW 0x00000000
+#define C3_CRYPT_CWLO_KEYGEN_SW 0x00000080
+#define C3_CRYPT_CWLO_NORMAL 0x00000000
+#define C3_CRYPT_CWLO_INTERMEDIATE 0x00000100
+#define C3_CRYPT_CWLO_ENCRYPT 0x00000000
+#define C3_CRYPT_CWLO_DECRYPT 0x00000200
+#define C3_CRYPT_CWLO_KEY128 0x0000000a /* 128bit, 10 rds */
+#define C3_CRYPT_CWLO_KEY192 0x0000040c /* 192bit, 12 rds */
+#define C3_CRYPT_CWLO_KEY256 0x0000080e /* 256bit, 15 rds */
+
+struct via_padlock_session {
+ u_int32_t ses_ekey[4 * (RIJNDAEL_MAXNR + 1) + 4]; /* 128 bit
aligned */
+ u_int32_t ses_dkey[4 * (RIJNDAEL_MAXNR + 1) + 4]; /* 128 bit
aligned */
+ u_int8_t ses_iv[16]; /* 128 bit
aligned */
+ u_int32_t ses_cw0;
+ struct swcr_data *swd;
+ int ses_klen;
+ int ses_used;
+};
+
+struct via_padlock_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 via_padlock_session *sc_sessions;
+};
+
+#define VIAC3_SESSION(sid) ((sid) & 0x0fffffff)
+#define VIAC3_SID(crd,ses) (((crd) << 28) | ((ses) & 0x0fffffff))
+
+struct cpu_info;
+
+struct via_padlock {
+ struct cpu_info *vp_ci;
+ int vp_freq;
+};
+
+void via_padlock_attach(void);
+
+#endif /* _KERNEL */
+#endif /* _X86_VIA_PADLOCK_H_ */
Index: sys/arch/x86/x86/via_padlock.c
===================================================================
RCS file: sys/arch/x86/x86/via_padlock.c
diff -N sys/arch/x86/x86/via_padlock.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/arch/x86/x86/via_padlock.c 12 Jan 2007 16:26:36 -0000
@@ -0,0 +1,480 @@
+/* $OpenBSD: via.c,v 1.8 2006/11/17 07:47:56 tom Exp $ */
+/* $NetBSD */
+
+/*-
+ * Copyright (c) 2003 Jason Wright
+ * Copyright (c) 2003, 2004 Theo de Raadt
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include "opt_viapadlock.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/signalvar.h>
+#include <sys/kernel.h>
+#include <sys/rnd.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+
+#include <machine/cpu.h>
+#include <x86/specialreg.h>
+
+#include <opencrypto/cryptodev.h>
+#include <opencrypto/cryptosoft.h>
+#include <opencrypto/xform.h>
+#include <crypto/rijndael/rijndael.h>
+
+#include <opencrypto/cryptosoft_xform.c>
+
+#ifdef VIA_PADLOCK
+
+int via_padlock_crypto_newsession(void *, u_int32_t *, struct cryptoini *);
+int via_padlock_crypto_process(void *, struct cryptop *, int);
+int via_padlock_crypto_swauth(struct cryptop *, struct cryptodesc *,
+ struct swcr_data *, caddr_t);
+int via_padlock_crypto_encdec(struct cryptop *, struct cryptodesc *,
+ struct via_padlock_session *, struct via_padlock_softc *, caddr_t);
+int via_padlock_crypto_freesession(void *, u_int64_t);
+static __inline void via_padlock_cbc(void *, void *, void *, void *, int,
+ void *);
+
+void
+via_padlock_attach(void)
+{
+ if (!(cpu_feature_padlock & CPUID_FEAT_VACE))
+ return;
+
+ struct via_padlock_softc *vp_sc;
+ if ((vp_sc = malloc(sizeof(*vp_sc), M_DEVBUF, M_NOWAIT)) == NULL)
+ return;
+ bzero(vp_sc, sizeof(*vp_sc));
+
+ vp_sc->sc_cid = crypto_get_driverid(0);
+ if (vp_sc->sc_cid < 0) {
+ printf("PadLock: Could not get a crypto driver ID\n");
+ return;
+ }
+
+ /*
+ * Ask the opencrypto subsystem to register ourselves. Although
+ * we don't support hardware offloading for various HMAC algorithms,
+ * we will handle them, because opencrypto prefers drivers that
+ * support all requested algorithms.
+ */
+#define REGISTER(alg) \
+ crypto_register(vp_sc->sc_cid, alg, 0, 0, \
+ via_padlock_crypto_newsession, via_padlock_crypto_freesession, \
+ via_padlock_crypto_process, vp_sc);
+
+ REGISTER(CRYPTO_AES_CBC);
+ REGISTER(CRYPTO_MD5_HMAC);
+ REGISTER(CRYPTO_SHA1_HMAC);
+ REGISTER(CRYPTO_RIPEMD160_HMAC);
+ REGISTER(CRYPTO_SHA2_HMAC);
+
+ printf("PadLock: registered support for AES_CBC\n");
+}
+
+int
+via_padlock_crypto_newsession(void *arg, u_int32_t *sidp, struct cryptoini
*cri)
+{
+ struct cryptoini *c;
+ struct via_padlock_softc *sc = arg;
+ struct via_padlock_session *ses = NULL;
+ const struct swcr_auth_hash *axf;
+ struct swcr_data *swd;
+ int sesn, i, cw0;
+
+ KASSERT(sc != NULL /*, ("via_padlock_crypto_freesession: null
softc")*/);
+ if (sc == NULL || sidp == NULL || cri == NULL)
+ return (EINVAL);
+
+ if (sc->sc_sessions == NULL) {
+ ses = sc->sc_sessions = 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 = 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;
+
+ for (c = cri; c != NULL; c = c->cri_next) {
+ switch (c->cri_alg) {
+ case CRYPTO_AES_CBC:
+ switch (c->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;
+
+#ifdef __NetBSD__
+ rnd_extract_data(ses->ses_iv, sizeof(ses->ses_iv),
+ RND_EXTRACT_ANY);
+#else
+ get_random_bytes(ses->ses_iv, sizeof(ses->ses_iv));
+#endif
+ ses->ses_klen = c->cri_klen;
+ ses->ses_cw0 = cw0;
+
+ /* Build expanded keys for both directions */
+ rijndaelKeySetupEnc(ses->ses_ekey, c->cri_key,
+ c->cri_klen);
+ rijndaelKeySetupDec(ses->ses_dkey, c->cri_key,
+ c->cri_klen);
+ for (i = 0; i < 4 * (RIJNDAEL_MAXNR + 1); i++) {
+ ses->ses_ekey[i] = ntohl(ses->ses_ekey[i]);
+ ses->ses_dkey[i] = ntohl(ses->ses_dkey[i]);
+ }
+
+ break;
+
+ /* Use hashing implementations from the cryptosoft code. */
+ case CRYPTO_MD5_HMAC:
+ axf = &swcr_auth_hash_hmac_md5_96;
+ goto authcommon;
+ case CRYPTO_SHA1_HMAC:
+ axf = &swcr_auth_hash_hmac_sha1_96;
+ goto authcommon;
+ case CRYPTO_RIPEMD160_HMAC:
+ axf = &swcr_auth_hash_hmac_ripemd_160_96;
+ goto authcommon;
+ case CRYPTO_SHA2_HMAC:
+ if (cri->cri_klen == 256)
+ axf = &swcr_auth_hash_hmac_sha2_256;
+ else if (cri->cri_klen == 384)
+ axf = &swcr_auth_hash_hmac_sha2_384;
+ else if (cri->cri_klen == 512)
+ axf = &swcr_auth_hash_hmac_sha2_512;
+ else {
+ return EINVAL;
+ }
+ authcommon:
+ MALLOC(swd, struct swcr_data *,
+ sizeof(struct swcr_data), M_CRYPTO_DATA,
+ M_NOWAIT);
+ if (swd == NULL) {
+ via_padlock_crypto_freesession(sc, sesn);
+ return (ENOMEM);
+ }
+ bzero(swd, sizeof(struct swcr_data));
+ ses->swd = swd;
+
+ swd->sw_ictx = malloc(axf->auth_hash->ctxsize,
+ M_CRYPTO_DATA, M_NOWAIT);
+ if (swd->sw_ictx == NULL) {
+ via_padlock_crypto_freesession(sc, sesn);
+ return (ENOMEM);
+ }
+
+ swd->sw_octx = malloc(axf->auth_hash->ctxsize,
+ M_CRYPTO_DATA, M_NOWAIT);
+ if (swd->sw_octx == NULL) {
+ via_padlock_crypto_freesession(sc, sesn);
+ return (ENOMEM);
+ }
+
+ for (i = 0; i < c->cri_klen / 8; i++)
+ c->cri_key[i] ^= HMAC_IPAD_VAL;
+
+ axf->Init(swd->sw_ictx);
+ axf->Update(swd->sw_ictx, c->cri_key, c->cri_klen / 8);
+ axf->Update(swd->sw_ictx, hmac_ipad_buffer,
+ HMAC_BLOCK_LEN - (c->cri_klen / 8));
+
+ for (i = 0; i < c->cri_klen / 8; i++)
+ c->cri_key[i] ^= (HMAC_IPAD_VAL ^
+ HMAC_OPAD_VAL);
+
+ axf->Init(swd->sw_octx);
+ axf->Update(swd->sw_octx, c->cri_key, c->cri_klen / 8);
+ axf->Update(swd->sw_octx, hmac_opad_buffer,
+ HMAC_BLOCK_LEN - (c->cri_klen / 8));
+
+ for (i = 0; i < c->cri_klen / 8; i++)
+ c->cri_key[i] ^= HMAC_OPAD_VAL;
+
+ swd->sw_axf = axf;
+ swd->sw_alg = c->cri_alg;
+
+ break;
+ default:
+ return (EINVAL);
+ }
+ }
+
+ *sidp = VIAC3_SID(0, sesn);
+ return (0);
+}
+
+int
+via_padlock_crypto_freesession(void *arg, u_int64_t tid)
+{
+ struct via_padlock_softc *sc = arg;
+ struct swcr_data *swd;
+ struct auth_hash *axf;
+ int sesn;
+ u_int32_t sid = ((u_int32_t)tid) & 0xffffffff;
+
+ KASSERT(sc != NULL /*, ("via_padlock_crypto_freesession: null
softc")*/);
+ if (sc == NULL)
+ return (EINVAL);
+
+ sesn = VIAC3_SESSION(sid);
+ if (sesn >= sc->sc_nsessions)
+ return (EINVAL);
+
+ if (sc->sc_sessions[sesn].swd) {
+ swd = sc->sc_sessions[sesn].swd;
+ axf = swd->sw_axf->auth_hash;
+
+ if (swd->sw_ictx) {
+ bzero(swd->sw_ictx, axf->ctxsize);
+ free(swd->sw_ictx, M_CRYPTO_DATA);
+ }
+ if (swd->sw_octx) {
+ bzero(swd->sw_octx, axf->ctxsize);
+ free(swd->sw_octx, M_CRYPTO_DATA);
+ }
+ FREE(swd, M_CRYPTO_DATA);
+ }
+
+ bzero(&sc->sc_sessions[sesn], sizeof(sc->sc_sessions[sesn]));
+ return (0);
+}
+
+static __inline void
+via_padlock_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"); /* force key reload */
+ __asm __volatile(".byte 0xf3, 0x0f, 0xa7, 0xd0" : /* rep xcrypt-dbd */
+ : "a" (iv), "b" (key), "c" (rep), "d" (cw), "S" (src),
"D" (dst)
+ : "memory", "cc");
+
+ lcr0(creg0);
+}
+
+int
+via_padlock_crypto_swauth(struct cryptop *crp, struct cryptodesc *crd,
+ struct swcr_data *sw, caddr_t buf)
+{
+ int type;
+
+ if (crp->crp_flags & CRYPTO_F_IMBUF)
+ type = CRYPTO_BUF_MBUF;
+ else
+ type= CRYPTO_BUF_IOV;
+
+ return (swcr_authcompute(crp, crd, sw, buf, type));
+}
+
+int
+via_padlock_crypto_encdec(struct cryptop *crp, struct cryptodesc *crd,
+ struct via_padlock_session *ses, struct via_padlock_softc *sc, caddr_t buf)
+{
+ u_int32_t *key;
+ int err = 0;
+
+ if ((crd->crd_len % 16) != 0) {
+ err = EINVAL;
+ return (err);
+ }
+
+ sc->op_buf = malloc(crd->crd_len, M_DEVBUF, M_NOWAIT);
+ if (sc->op_buf == NULL) {
+ err = ENOMEM;
+ return (err);
+ }
+
+ 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;
+ via_padlock_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,
+ ses->ses_iv);
+ else
+ bcopy(crp->crp_buf + crd->crd_skip +
+ crd->crd_len - 16, ses->ses_iv, 16);
+ }
+
+ if (sc->op_buf != NULL) {
+ bzero(sc->op_buf, crd->crd_len);
+ free(sc->op_buf, M_DEVBUF);
+ sc->op_buf = NULL;
+ }
+
+ return (err);
+}
+
+int
+via_padlock_crypto_process(void *arg, struct cryptop *crp, int hint)
+{
+ struct via_padlock_softc *sc = arg;
+ struct via_padlock_session *ses;
+ struct cryptodesc *crd;
+ int sesn, err = 0;
+
+ KASSERT(sc != NULL /*, ("via_padlock_crypto_process: null softc")*/);
+ if (crp == NULL || crp->crp_callback == NULL) {
+ err = EINVAL;
+ goto out;
+ }
+
+ sesn = VIAC3_SESSION(crp->crp_sid);
+ if (sesn >= sc->sc_nsessions) {
+ err = EINVAL;
+ goto out;
+ }
+ ses = &sc->sc_sessions[sesn];
+
+ for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
+ switch (crd->crd_alg) {
+ case CRYPTO_AES_CBC:
+ if ((err = via_padlock_crypto_encdec(crp, crd, ses,
+ sc, crp->crp_buf)) != 0)
+ goto out;
+ break;
+
+ case CRYPTO_MD5_HMAC:
+ case CRYPTO_SHA1_HMAC:
+ case CRYPTO_RIPEMD160_HMAC:
+ case CRYPTO_SHA2_HMAC:
+ if ((err = via_padlock_crypto_swauth(crp, crd,
+ ses->swd, crp->crp_buf)) != 0)
+ goto out;
+ break;
+
+ default:
+ err = EINVAL;
+ goto out;
+ }
+ }
+out:
+ crp->crp_etype = err;
+ crypto_done(crp);
+ return (err);
+}
+
+#endif /* VIA_PADLOCK */
Index: sys/opencrypto/cryptosoft.c
===================================================================
RCS file: /cvsroot/src/sys/opencrypto/cryptosoft.c,v
retrieving revision 1.15
diff -u -r1.15 cryptosoft.c
--- sys/opencrypto/cryptosoft.c 16 Nov 2006 01:33:51 -0000 1.15
+++ sys/opencrypto/cryptosoft.c 12 Jan 2007 16:26:36 -0000
@@ -60,8 +60,6 @@
: cuio_copydata((struct uio *)a,b,c,d)
static int swcr_encdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
-static int swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
- struct swcr_data *sw, caddr_t buf, int outtype);
static int swcr_compdec(struct cryptodesc *, struct swcr_data *, caddr_t, int);
static int swcr_process(void *, struct cryptop *, int);
static int swcr_newsession(void *, u_int32_t *, struct cryptoini *);
@@ -530,7 +528,7 @@
/*
* Compute keyed-hash authenticator.
*/
-static int
+int
swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
struct swcr_data *sw, caddr_t buf, int outtype)
{
Index: sys/opencrypto/cryptosoft.h
===================================================================
RCS file: /cvsroot/src/sys/opencrypto/cryptosoft.h,v
retrieving revision 1.3
diff -u -r1.3 cryptosoft.h
--- sys/opencrypto/cryptosoft.h 25 Nov 2005 16:16:46 -0000 1.3
+++ sys/opencrypto/cryptosoft.h 12 Jan 2007 16:26:36 -0000
@@ -57,4 +57,9 @@
struct swcr_data *sw_next;
};
+#ifdef _KERNEL
+int swcr_authcompute(struct cryptop *crp, struct cryptodesc *crd,
+ struct swcr_data *sw, caddr_t buf, int outtype);
+#endif /* _KERNEL */
+
#endif /* _CRYPTO_CRYPTO_H_ */
Home |
Main Index |
Thread Index |
Old Index