ocf: move all stuff into files, and fix build error on .25

SVN-Revision: 13288
This commit is contained in:
Gabor Juhos 2008-11-19 12:25:39 +00:00
parent 22949f10e2
commit e1e65079b4
54 changed files with 25251 additions and 70367 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,34 @@
#############################################################################
mainmenu_option next_comment
comment 'OCF Configuration'
tristate 'OCF (Open Cryptograhic Framework)' CONFIG_OCF_OCF
dep_mbool ' enable fips RNG checks (fips check on RNG data before use)' \
CONFIG_OCF_FIPS $CONFIG_OCF_OCF
dep_mbool ' enable harvesting entropy for /dev/random' \
CONFIG_OCF_RANDOMHARVEST $CONFIG_OCF_OCF
dep_tristate ' cryptodev (user space support)' \
CONFIG_OCF_CRYPTODEV $CONFIG_OCF_OCF
dep_tristate ' cryptosoft (software crypto engine)' \
CONFIG_OCF_CRYPTOSOFT $CONFIG_OCF_OCF
dep_tristate ' safenet (HW crypto engine)' \
CONFIG_OCF_SAFE $CONFIG_OCF_OCF
dep_tristate ' IXP4xx (HW crypto engine)' \
CONFIG_OCF_IXP4XX $CONFIG_OCF_OCF
dep_mbool ' Enable IXP4xx HW to perform SHA1 and MD5 hashing (very slow)' \
CONFIG_OCF_IXP4XX_SHA1_MD5 $CONFIG_OCF_IXP4XX
dep_tristate ' hifn (HW crypto engine)' \
CONFIG_OCF_HIFN $CONFIG_OCF_OCF
dep_tristate ' talitos (HW crypto engine)' \
CONFIG_OCF_TALITOS $CONFIG_OCF_OCF
dep_tristate ' pasemi (HW crypto engine)' \
CONFIG_OCF_PASEMI $CONFIG_OCF_OCF
dep_tristate ' ep80579 (HW crypto engine)' \
CONFIG_OCF_EP80579 $CONFIG_OCF_OCF
dep_tristate ' ocfnull (does no crypto)' \
CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF
dep_tristate ' ocf-bench (HW crypto in-kernel benchmark)' \
CONFIG_OCF_BENCH $CONFIG_OCF_OCF
endmenu
#############################################################################

View file

@ -0,0 +1,101 @@
menu "OCF Configuration"
config OCF_OCF
tristate "OCF (Open Cryptograhic Framework)"
help
A linux port of the OpenBSD/FreeBSD crypto framework.
config OCF_RANDOMHARVEST
bool "crypto random --- harvest entropy for /dev/random"
depends on OCF_OCF
help
Includes code to harvest random numbers from devices that support it.
config OCF_FIPS
bool "enable fips RNG checks"
depends on OCF_OCF && OCF_RANDOMHARVEST
help
Run all RNG provided data through a fips check before
adding it /dev/random's entropy pool.
config OCF_CRYPTODEV
tristate "cryptodev (user space support)"
depends on OCF_OCF
help
The user space API to access crypto hardware.
config OCF_CRYPTOSOFT
tristate "cryptosoft (software crypto engine)"
depends on OCF_OCF
help
A software driver for the OCF framework that uses
the kernel CryptoAPI.
config OCF_SAFE
tristate "safenet (HW crypto engine)"
depends on OCF_OCF
help
A driver for a number of the safenet Excel crypto accelerators.
Currently tested and working on the 1141 and 1741.
config OCF_IXP4XX
tristate "IXP4xx (HW crypto engine)"
depends on OCF_OCF
help
XScale IXP4xx crypto accelerator driver. Requires the
Intel Access library.
config OCF_IXP4XX_SHA1_MD5
bool "IXP4xx SHA1 and MD5 Hashing"
depends on OCF_IXP4XX
help
Allows the IXP4xx crypto accelerator to perform SHA1 and MD5 hashing.
Note: this is MUCH slower than using cryptosoft (software crypto engine).
config OCF_HIFN
tristate "hifn (HW crypto engine)"
depends on OCF_OCF
help
OCF driver for various HIFN based crypto accelerators.
(7951, 7955, 7956, 7751, 7811)
config OCF_HIFNHIPP
tristate "Hifn HIPP (HW packet crypto engine)"
depends on OCF_OCF
help
OCF driver for various HIFN (HIPP) based crypto accelerators
(7855)
config OCF_TALITOS
tristate "talitos (HW crypto engine)"
depends on OCF_OCF
help
OCF driver for Freescale's security engine (SEC/talitos).
config OCF_PASEMI
tristate "pasemi (HW crypto engine)"
depends on OCF_OCF && PPC_PASEMI
help
OCF driver for the PA Semi PWRficient DMA Engine
config OCF_EP80579
tristate "ep80579 (HW crypto engine)"
depends on OCF_OCF
help
OCF driver for the Intel EP80579 Integrated Processor Product Line.
config OCF_OCFNULL
tristate "ocfnull (fake crypto engine)"
depends on OCF_OCF
help
OCF driver for measuring ipsec overheads (does no crypto)
config OCF_BENCH
tristate "ocf-bench (HW crypto in-kernel benchmark)"
depends on OCF_OCF
help
A very simple encryption test for the in-kernel interface
of OCF. Also includes code to benchmark the IXP Access library
for comparison.
endmenu

View file

@ -0,0 +1,121 @@
# for SGlinux builds
-include $(ROOTDIR)/modules/.config
OCF_OBJS = crypto.o criov.o
ifdef CONFIG_OCF_RANDOMHARVEST
OCF_OBJS += random.o
endif
ifdef CONFIG_OCF_FIPS
OCF_OBJS += rndtest.o
endif
# Add in autoconf.h to get #defines for CONFIG_xxx
AUTOCONF_H=$(ROOTDIR)/modules/autoconf.h
ifeq ($(AUTOCONF_H), $(wildcard $(AUTOCONF_H)))
EXTRA_CFLAGS += -include $(AUTOCONF_H)
export EXTRA_CFLAGS
endif
ifndef obj
obj ?= .
_obj = subdir
mod-subdirs := safe hifn ixp4xx talitos ocfnull
export-objs += crypto.o criov.o random.o
list-multi += ocf.o
_slash :=
else
_obj = obj
_slash := /
endif
EXTRA_CFLAGS += -I$(obj)/.
obj-$(CONFIG_OCF_OCF) += ocf.o
obj-$(CONFIG_OCF_CRYPTODEV) += cryptodev.o
obj-$(CONFIG_OCF_CRYPTOSOFT) += cryptosoft.o
obj-$(CONFIG_OCF_BENCH) += ocf-bench.o
$(_obj)-$(CONFIG_OCF_SAFE) += safe$(_slash)
$(_obj)-$(CONFIG_OCF_HIFN) += hifn$(_slash)
$(_obj)-$(CONFIG_OCF_IXP4XX) += ixp4xx$(_slash)
$(_obj)-$(CONFIG_OCF_TALITOS) += talitos$(_slash)
$(_obj)-$(CONFIG_OCF_PASEMI) += pasemi$(_slash)
$(_obj)-$(CONFIG_OCF_EP80579) += ep80579$(_slash)
$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)
ocf-objs := $(OCF_OBJS)
$(list-multi) dummy1: $(ocf-objs)
$(LD) -r -o $@ $(ocf-objs)
.PHONY:
clean:
rm -f *.o *.ko .*.o.flags .*.ko.cmd .*.o.cmd .*.mod.o.cmd *.mod.c
rm -f */*.o */*.ko */.*.o.cmd */.*.ko.cmd */.*.mod.o.cmd */*.mod.c */.*.o.flags
ifdef TOPDIR
-include $(TOPDIR)/Rules.make
endif
#
# release gen targets
#
.PHONY: patch
patch:
REL=`date +%Y%m%d`; \
patch=ocf-linux-$$REL.patch; \
patch24=ocf-linux-24-$$REL.patch; \
patch26=ocf-linux-26-$$REL.patch; \
( \
find . -name Makefile; \
find . -name Config.in; \
find . -name Kconfig; \
find . -name README; \
find . -name '*.[ch]' | grep -v '.mod.c'; \
) | while read t; do \
diff -Nau /dev/null $$t | sed 's?^+++ \./?+++ linux/crypto/ocf/?'; \
done > $$patch; \
cat patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \
cat patches/linux-2.6.26-ocf.patch $$patch > $$patch26
.PHONY: tarball
tarball:
REL=`date +%Y%m%d`; RELDIR=/tmp/ocf-linux-$$REL; \
CURDIR=`pwd`; \
rm -rf /tmp/ocf-linux-$$REL*; \
mkdir -p $$RELDIR/tools; \
cp README* $$RELDIR; \
cp patches/openss*.patch $$RELDIR; \
cp patches/crypto-tools.patch $$RELDIR; \
cp tools/[!C]* $$RELDIR/tools; \
cd ..; \
tar cvf $$RELDIR/ocf-linux.tar \
--exclude=CVS \
--exclude=.* \
--exclude=*.o \
--exclude=*.ko \
--exclude=*.mod.* \
--exclude=README* \
--exclude=ocf-*.patch \
--exclude=ocf/patches/openss*.patch \
--exclude=ocf/patches/crypto-tools.patch \
--exclude=ocf/tools \
ocf; \
gzip -9 $$RELDIR/ocf-linux.tar; \
cd /tmp; \
tar cvf ocf-linux-$$REL.tar ocf-linux-$$REL; \
gzip -9 ocf-linux-$$REL.tar; \
cd $$CURDIR/../../user; \
rm -rf /tmp/crypto-tools-$$REL*; \
tar cvf /tmp/crypto-tools-$$REL.tar \
--exclude=CVS \
--exclude=.* \
--exclude=*.o \
--exclude=cryptotest \
--exclude=cryptokeytest \
crypto-tools; \
gzip -9 /tmp/crypto-tools-$$REL.tar

View file

@ -0,0 +1,215 @@
/* $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason Exp $ */
/*
* Linux port done by David McCullough <david_mccullough@securecomputing.com>
* Copyright (C) 2006-2007 David McCullough
* Copyright (C) 2004-2005 Intel Corporation.
* The license and original author are listed below.
*
* Copyright (c) 1999 Theo de Raadt
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
__FBSDID("$FreeBSD: src/sys/opencrypto/criov.c,v 1.5 2006/06/04 22:15:13 pjd Exp $");
*/
#ifndef AUTOCONF_INCLUDED
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/uio.h>
#include <linux/skbuff.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/io.h>
#include <uio.h>
#include <cryptodev.h>
/*
* This macro is only for avoiding code duplication, as we need to skip
* given number of bytes in the same way in three functions below.
*/
#define CUIO_SKIP() do { \
KASSERT(off >= 0, ("%s: off %d < 0", __func__, off)); \
KASSERT(len >= 0, ("%s: len %d < 0", __func__, len)); \
while (off > 0) { \
KASSERT(iol >= 0, ("%s: empty in skip", __func__)); \
if (off < iov->iov_len) \
break; \
off -= iov->iov_len; \
iol--; \
iov++; \
} \
} while (0)
void
cuio_copydata(struct uio* uio, int off, int len, caddr_t cp)
{
struct iovec *iov = uio->uio_iov;
int iol = uio->uio_iovcnt;
unsigned count;
CUIO_SKIP();
while (len > 0) {
KASSERT(iol >= 0, ("%s: empty", __func__));
count = min((int)(iov->iov_len - off), len);
memcpy(cp, ((caddr_t)iov->iov_base) + off, count);
len -= count;
cp += count;
off = 0;
iol--;
iov++;
}
}
void
cuio_copyback(struct uio* uio, int off, int len, caddr_t cp)
{
struct iovec *iov = uio->uio_iov;
int iol = uio->uio_iovcnt;
unsigned count;
CUIO_SKIP();
while (len > 0) {
KASSERT(iol >= 0, ("%s: empty", __func__));
count = min((int)(iov->iov_len - off), len);
memcpy(((caddr_t)iov->iov_base) + off, cp, count);
len -= count;
cp += count;
off = 0;
iol--;
iov++;
}
}
/*
* Return a pointer to iov/offset of location in iovec list.
*/
struct iovec *
cuio_getptr(struct uio *uio, int loc, int *off)
{
struct iovec *iov = uio->uio_iov;
int iol = uio->uio_iovcnt;
while (loc >= 0) {
/* Normal end of search */
if (loc < iov->iov_len) {
*off = loc;
return (iov);
}
loc -= iov->iov_len;
if (iol == 0) {
if (loc == 0) {
/* Point at the end of valid data */
*off = iov->iov_len;
return (iov);
} else
return (NULL);
} else {
iov++, iol--;
}
}
return (NULL);
}
EXPORT_SYMBOL(cuio_copyback);
EXPORT_SYMBOL(cuio_copydata);
EXPORT_SYMBOL(cuio_getptr);
static void
skb_copy_bits_back(struct sk_buff *skb, int offset, caddr_t cp, int len)
{
int i;
if (offset < skb_headlen(skb)) {
memcpy(skb->data + offset, cp, min_t(int, skb_headlen(skb), len));
len -= skb_headlen(skb);
cp += skb_headlen(skb);
}
offset -= skb_headlen(skb);
for (i = 0; len > 0 && i < skb_shinfo(skb)->nr_frags; i++) {
if (offset < skb_shinfo(skb)->frags[i].size) {
memcpy(page_address(skb_shinfo(skb)->frags[i].page) +
skb_shinfo(skb)->frags[i].page_offset,
cp, min_t(int, skb_shinfo(skb)->frags[i].size, len));
len -= skb_shinfo(skb)->frags[i].size;
cp += skb_shinfo(skb)->frags[i].size;
}
offset -= skb_shinfo(skb)->frags[i].size;
}
}
void
crypto_copyback(int flags, caddr_t buf, int off, int size, caddr_t in)
{
if ((flags & CRYPTO_F_SKBUF) != 0)
skb_copy_bits_back((struct sk_buff *)buf, off, in, size);
else if ((flags & CRYPTO_F_IOV) != 0)
cuio_copyback((struct uio *)buf, off, size, in);
else
bcopy(in, buf + off, size);
}
void
crypto_copydata(int flags, caddr_t buf, int off, int size, caddr_t out)
{
if ((flags & CRYPTO_F_SKBUF) != 0)
skb_copy_bits((struct sk_buff *)buf, off, out, size);
else if ((flags & CRYPTO_F_IOV) != 0)
cuio_copydata((struct uio *)buf, off, size, out);
else
bcopy(buf + off, out, size);
}
int
crypto_apply(int flags, caddr_t buf, int off, int len,
int (*f)(void *, void *, u_int), void *arg)
{
#if 0
int error;
if ((flags & CRYPTO_F_SKBUF) != 0)
error = XXXXXX((struct mbuf *)buf, off, len, f, arg);
else if ((flags & CRYPTO_F_IOV) != 0)
error = cuio_apply((struct uio *)buf, off, len, f, arg);
else
error = (*f)(arg, buf + off, len);
return (error);
#else
KASSERT(0, ("crypto_apply not implemented!\n"));
#endif
return 0;
}
EXPORT_SYMBOL(crypto_copyback);
EXPORT_SYMBOL(crypto_copydata);
EXPORT_SYMBOL(crypto_apply);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,478 @@
/* $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.25 2007/05/09 19:37:02 gnn Exp $ */
/* $OpenBSD: cryptodev.h,v 1.31 2002/06/11 11:14:29 beck Exp $ */
/*-
* Linux port done by David McCullough <david_mccullough@securecomputing.com>
* Copyright (C) 2006-2007 David McCullough
* Copyright (C) 2004-2005 Intel Corporation.
* The license and original author are listed below.
*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
* Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
*
* This code was written by Angelos D. Keromytis in Athens, Greece, in
* February 2000. Network Security Technologies Inc. (NSTI) kindly
* supported the development of this code.
*
* Copyright (c) 2000 Angelos D. Keromytis
*
* Permission to use, copy, and modify this software with or without fee
* is hereby granted, provided that this entire notice is included in
* all source code copies of any software which is or includes a copy or
* modification of this software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
* PURPOSE.
*
* Copyright (c) 2001 Theo de Raadt
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Effort sponsored in part by the Defense Advanced Research Projects
* Agency (DARPA) and Air Force Research Laboratory, Air Force
* Materiel Command, USAF, under agreement number F30602-01-2-0537.
*
*/
#ifndef _CRYPTO_CRYPTO_H_
#define _CRYPTO_CRYPTO_H_
/* Some initial values */
#define CRYPTO_DRIVERS_INITIAL 4
#define CRYPTO_SW_SESSIONS 32
/* Hash values */
#define NULL_HASH_LEN 0
#define MD5_HASH_LEN 16
#define SHA1_HASH_LEN 20
#define RIPEMD160_HASH_LEN 20
#define SHA2_256_HASH_LEN 32
#define SHA2_384_HASH_LEN 48
#define SHA2_512_HASH_LEN 64
#define MD5_KPDK_HASH_LEN 16
#define SHA1_KPDK_HASH_LEN 20
/* Maximum hash algorithm result length */
#define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */
/* HMAC values */
#define NULL_HMAC_BLOCK_LEN 1
#define MD5_HMAC_BLOCK_LEN 64
#define SHA1_HMAC_BLOCK_LEN 64
#define RIPEMD160_HMAC_BLOCK_LEN 64
#define SHA2_256_HMAC_BLOCK_LEN 64
#define SHA2_384_HMAC_BLOCK_LEN 128
#define SHA2_512_HMAC_BLOCK_LEN 128
/* Maximum HMAC block length */
#define HMAC_MAX_BLOCK_LEN SHA2_512_HMAC_BLOCK_LEN /* Keep this updated */
#define HMAC_IPAD_VAL 0x36
#define HMAC_OPAD_VAL 0x5C
/* Encryption algorithm block sizes */
#define NULL_BLOCK_LEN 1
#define DES_BLOCK_LEN 8
#define DES3_BLOCK_LEN 8
#define BLOWFISH_BLOCK_LEN 8
#define SKIPJACK_BLOCK_LEN 8
#define CAST128_BLOCK_LEN 8
#define RIJNDAEL128_BLOCK_LEN 16
#define AES_BLOCK_LEN RIJNDAEL128_BLOCK_LEN
#define CAMELLIA_BLOCK_LEN 16
#define ARC4_BLOCK_LEN 1
#define EALG_MAX_BLOCK_LEN AES_BLOCK_LEN /* Keep this updated */
/* Encryption algorithm min and max key sizes */
#define NULL_MIN_KEY_LEN 0
#define NULL_MAX_KEY_LEN 0
#define DES_MIN_KEY_LEN 8
#define DES_MAX_KEY_LEN 8
#define DES3_MIN_KEY_LEN 24
#define DES3_MAX_KEY_LEN 24
#define BLOWFISH_MIN_KEY_LEN 4
#define BLOWFISH_MAX_KEY_LEN 56
#define SKIPJACK_MIN_KEY_LEN 10
#define SKIPJACK_MAX_KEY_LEN 10
#define CAST128_MIN_KEY_LEN 5
#define CAST128_MAX_KEY_LEN 16
#define RIJNDAEL128_MIN_KEY_LEN 16
#define RIJNDAEL128_MAX_KEY_LEN 32
#define AES_MIN_KEY_LEN RIJNDAEL128_MIN_KEY_LEN
#define AES_MAX_KEY_LEN RIJNDAEL128_MAX_KEY_LEN
#define CAMELLIA_MIN_KEY_LEN 16
#define CAMELLIA_MAX_KEY_LEN 32
#define ARC4_MIN_KEY_LEN 1
#define ARC4_MAX_KEY_LEN 256
/* Max size of data that can be processed */
#define CRYPTO_MAX_DATA_LEN 64*1024 - 1
#define CRYPTO_ALGORITHM_MIN 1
#define CRYPTO_DES_CBC 1
#define CRYPTO_3DES_CBC 2
#define CRYPTO_BLF_CBC 3
#define CRYPTO_CAST_CBC 4
#define CRYPTO_SKIPJACK_CBC 5
#define CRYPTO_MD5_HMAC 6
#define CRYPTO_SHA1_HMAC 7
#define CRYPTO_RIPEMD160_HMAC 8
#define CRYPTO_MD5_KPDK 9
#define CRYPTO_SHA1_KPDK 10
#define CRYPTO_RIJNDAEL128_CBC 11 /* 128 bit blocksize */
#define CRYPTO_AES_CBC 11 /* 128 bit blocksize -- the same as above */
#define CRYPTO_ARC4 12
#define CRYPTO_MD5 13
#define CRYPTO_SHA1 14
#define CRYPTO_NULL_HMAC 15
#define CRYPTO_NULL_CBC 16
#define CRYPTO_DEFLATE_COMP 17 /* Deflate compression algorithm */
#define CRYPTO_SHA2_256_HMAC 18
#define CRYPTO_SHA2_384_HMAC 19
#define CRYPTO_SHA2_512_HMAC 20
#define CRYPTO_CAMELLIA_CBC 21
#define CRYPTO_SHA2_256 22
#define CRYPTO_SHA2_384 23
#define CRYPTO_SHA2_512 24
#define CRYPTO_RIPEMD160 25
#define CRYPTO_ALGORITHM_MAX 25 /* Keep updated - see below */
/* Algorithm flags */
#define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */
#define CRYPTO_ALG_FLAG_RNG_ENABLE 0x02 /* Has HW RNG for DH/DSA */
#define CRYPTO_ALG_FLAG_DSA_SHA 0x04 /* Can do SHA on msg */
/*
* Crypto driver/device flags. They can set in the crid
* parameter when creating a session or submitting a key
* op to affect the device/driver assigned. If neither
* of these are specified then the crid is assumed to hold
* the driver id of an existing (and suitable) device that
* must be used to satisfy the request.
*/
#define CRYPTO_FLAG_HARDWARE 0x01000000 /* hardware accelerated */
#define CRYPTO_FLAG_SOFTWARE 0x02000000 /* software implementation */
/* NB: deprecated */
struct session_op {
u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
u_int32_t keylen; /* cipher key */
caddr_t key;
int mackeylen; /* mac key */
caddr_t mackey;
u_int32_t ses; /* returns: session # */
};
struct session2_op {
u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
u_int32_t keylen; /* cipher key */
caddr_t key;
int mackeylen; /* mac key */
caddr_t mackey;
u_int32_t ses; /* returns: session # */
int crid; /* driver id + flags (rw) */
int pad[4]; /* for future expansion */
};
struct crypt_op {
u_int32_t ses;
u_int16_t op; /* i.e. COP_ENCRYPT */
#define COP_NONE 0
#define COP_ENCRYPT 1
#define COP_DECRYPT 2
u_int16_t flags;
#define COP_F_BATCH 0x0008 /* Batch op if possible */
u_int len;
caddr_t src, dst; /* become iov[] inside kernel */
caddr_t mac; /* must be big enough for chosen MAC */
caddr_t iv;
};
/*
* Parameters for looking up a crypto driver/device by
* device name or by id. The latter are returned for
* created sessions (crid) and completed key operations.
*/
struct crypt_find_op {
int crid; /* driver id + flags */
char name[32]; /* device/driver name */
};
/* bignum parameter, in packed bytes, ... */
struct crparam {
caddr_t crp_p;
u_int crp_nbits;
};
#define CRK_MAXPARAM 8
struct crypt_kop {
u_int crk_op; /* ie. CRK_MOD_EXP or other */
u_int crk_status; /* return status */
u_short crk_iparams; /* # of input parameters */
u_short crk_oparams; /* # of output parameters */
u_int crk_crid; /* NB: only used by CIOCKEY2 (rw) */
struct crparam crk_param[CRK_MAXPARAM];
};
#define CRK_ALGORITM_MIN 0
#define CRK_MOD_EXP 0
#define CRK_MOD_EXP_CRT 1
#define CRK_DSA_SIGN 2
#define CRK_DSA_VERIFY 3
#define CRK_DH_COMPUTE_KEY 4
#define CRK_ALGORITHM_MAX 4 /* Keep updated - see below */
#define CRF_MOD_EXP (1 << CRK_MOD_EXP)
#define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT)
#define CRF_DSA_SIGN (1 << CRK_DSA_SIGN)
#define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY)
#define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY)
/*
* done against open of /dev/crypto, to get a cloned descriptor.
* Please use F_SETFD against the cloned descriptor.
*/
#define CRIOGET _IOWR('c', 100, u_int32_t)
#define CRIOASYMFEAT CIOCASYMFEAT
#define CRIOFINDDEV CIOCFINDDEV
/* the following are done against the cloned descriptor */
#define CIOCGSESSION _IOWR('c', 101, struct session_op)
#define CIOCFSESSION _IOW('c', 102, u_int32_t)
#define CIOCCRYPT _IOWR('c', 103, struct crypt_op)
#define CIOCKEY _IOWR('c', 104, struct crypt_kop)
#define CIOCASYMFEAT _IOR('c', 105, u_int32_t)
#define CIOCGSESSION2 _IOWR('c', 106, struct session2_op)
#define CIOCKEY2 _IOWR('c', 107, struct crypt_kop)
#define CIOCFINDDEV _IOWR('c', 108, struct crypt_find_op)
struct cryptotstat {
struct timespec acc; /* total accumulated time */
struct timespec min; /* min time */
struct timespec max; /* max time */
u_int32_t count; /* number of observations */
};
struct cryptostats {
u_int32_t cs_ops; /* symmetric crypto ops submitted */
u_int32_t cs_errs; /* symmetric crypto ops that failed */
u_int32_t cs_kops; /* asymetric/key ops submitted */
u_int32_t cs_kerrs; /* asymetric/key ops that failed */
u_int32_t cs_intrs; /* crypto swi thread activations */
u_int32_t cs_rets; /* crypto return thread activations */
u_int32_t cs_blocks; /* symmetric op driver block */
u_int32_t cs_kblocks; /* symmetric op driver block */
/*
* When CRYPTO_TIMING is defined at compile time and the
* sysctl debug.crypto is set to 1, the crypto system will
* accumulate statistics about how long it takes to process
* crypto requests at various points during processing.
*/
struct cryptotstat cs_invoke; /* crypto_dipsatch -> crypto_invoke */
struct cryptotstat cs_done; /* crypto_invoke -> crypto_done */
struct cryptotstat cs_cb; /* crypto_done -> callback */
struct cryptotstat cs_finis; /* callback -> callback return */
u_int32_t cs_drops; /* crypto ops dropped due to congestion */
};
#ifdef __KERNEL__
/* Standard initialization structure beginning */
struct cryptoini {
int cri_alg; /* Algorithm to use */
int cri_klen; /* Key length, in bits */
int cri_mlen; /* Number of bytes we want from the
entire hash. 0 means all. */
caddr_t cri_key; /* key to use */
u_int8_t cri_iv[EALG_MAX_BLOCK_LEN]; /* IV to use */
struct cryptoini *cri_next;
};
/* Describe boundaries of a single crypto operation */
struct cryptodesc {
int crd_skip; /* How many bytes to ignore from start */
int crd_len; /* How many bytes to process */
int crd_inject; /* Where to inject results, if applicable */
int crd_flags;
#define CRD_F_ENCRYPT 0x01 /* Set when doing encryption */
#define CRD_F_IV_PRESENT 0x02 /* When encrypting, IV is already in
place, so don't copy. */
#define CRD_F_IV_EXPLICIT 0x04 /* IV explicitly provided */
#define CRD_F_DSA_SHA_NEEDED 0x08 /* Compute SHA-1 of buffer for DSA */
#define CRD_F_KEY_EXPLICIT 0x10 /* Key explicitly provided */
#define CRD_F_COMP 0x0f /* Set when doing compression */
struct cryptoini CRD_INI; /* Initialization/context data */
#define crd_iv CRD_INI.cri_iv
#define crd_key CRD_INI.cri_key
#define crd_alg CRD_INI.cri_alg
#define crd_klen CRD_INI.cri_klen
struct cryptodesc *crd_next;
};
/* Structure describing complete operation */
struct cryptop {
struct list_head crp_next;
wait_queue_head_t crp_waitq;
u_int64_t crp_sid; /* Session ID */
int crp_ilen; /* Input data total length */
int crp_olen; /* Result total length */
int crp_etype; /*
* Error type (zero means no error).
* All error codes except EAGAIN
* indicate possible data corruption (as in,
* the data have been touched). On all
* errors, the crp_sid may have changed
* (reset to a new one), so the caller
* should always check and use the new
* value on future requests.
*/
int crp_flags;
#define CRYPTO_F_SKBUF 0x0001 /* Input/output are skbuf chains */
#define CRYPTO_F_IOV 0x0002 /* Input/output are uio */
#define CRYPTO_F_REL 0x0004 /* Must return data in same place */
#define CRYPTO_F_BATCH 0x0008 /* Batch op if possible */
#define CRYPTO_F_CBIMM 0x0010 /* Do callback immediately */
#define CRYPTO_F_DONE 0x0020 /* Operation completed */
#define CRYPTO_F_CBIFSYNC 0x0040 /* Do CBIMM if op is synchronous */
caddr_t crp_buf; /* Data to be processed */
caddr_t crp_opaque; /* Opaque pointer, passed along */
struct cryptodesc *crp_desc; /* Linked list of processing descriptors */
int (*crp_callback)(struct cryptop *); /* Callback function */
};
#define CRYPTO_BUF_CONTIG 0x0
#define CRYPTO_BUF_IOV 0x1
#define CRYPTO_BUF_SKBUF 0x2
#define CRYPTO_OP_DECRYPT 0x0
#define CRYPTO_OP_ENCRYPT 0x1
/*
* Hints passed to process methods.
*/
#define CRYPTO_HINT_MORE 0x1 /* more ops coming shortly */
struct cryptkop {
struct list_head krp_next;
wait_queue_head_t krp_waitq;
int krp_flags;
#define CRYPTO_KF_DONE 0x0001 /* Operation completed */
#define CRYPTO_KF_CBIMM 0x0002 /* Do callback immediately */
u_int krp_op; /* ie. CRK_MOD_EXP or other */
u_int krp_status; /* return status */
u_short krp_iparams; /* # of input parameters */
u_short krp_oparams; /* # of output parameters */
u_int krp_crid; /* desired device, etc. */
u_int32_t krp_hid;
struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
int (*krp_callback)(struct cryptkop *);
};
#include <ocf-compat.h>
/*
* Session ids are 64 bits. The lower 32 bits contain a "local id" which
* is a driver-private session identifier. The upper 32 bits contain a
* "hardware id" used by the core crypto code to identify the driver and
* a copy of the driver's capabilities that can be used by client code to
* optimize operation.
*/
#define CRYPTO_SESID2HID(_sid) (((_sid) >> 32) & 0x00ffffff)
#define CRYPTO_SESID2CAPS(_sid) (((_sid) >> 32) & 0xff000000)
#define CRYPTO_SESID2LID(_sid) (((u_int32_t) (_sid)) & 0xffffffff)
extern int crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard);
extern int crypto_freesession(u_int64_t sid);
#define CRYPTOCAP_F_HARDWARE CRYPTO_FLAG_HARDWARE
#define CRYPTOCAP_F_SOFTWARE CRYPTO_FLAG_SOFTWARE
#define CRYPTOCAP_F_SYNC 0x04000000 /* operates synchronously */
extern int32_t crypto_get_driverid(device_t dev, int flags);
extern int crypto_find_driver(const char *);
extern device_t crypto_find_device_byhid(int hid);
extern int crypto_getcaps(int hid);
extern int crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
u_int32_t flags);
extern int crypto_kregister(u_int32_t, int, u_int32_t);
extern int crypto_unregister(u_int32_t driverid, int alg);
extern int crypto_unregister_all(u_int32_t driverid);
extern int crypto_dispatch(struct cryptop *crp);
extern int crypto_kdispatch(struct cryptkop *);
#define CRYPTO_SYMQ 0x1
#define CRYPTO_ASYMQ 0x2
extern int crypto_unblock(u_int32_t, int);
extern void crypto_done(struct cryptop *crp);
extern void crypto_kdone(struct cryptkop *);
extern int crypto_getfeat(int *);
extern void crypto_freereq(struct cryptop *crp);
extern struct cryptop *crypto_getreq(int num);
extern int crypto_usercrypto; /* userland may do crypto requests */
extern int crypto_userasymcrypto; /* userland may do asym crypto reqs */
extern int crypto_devallowsoft; /* only use hardware crypto */
/*
* random number support, crypto_unregister_all will unregister
*/
extern int crypto_rregister(u_int32_t driverid,
int (*read_random)(void *arg, u_int32_t *buf, int len), void *arg);
extern int crypto_runregister_all(u_int32_t driverid);
/*
* Crypto-related utility routines used mainly by drivers.
*
* XXX these don't really belong here; but for now they're
* kept apart from the rest of the system.
*/
struct uio;
extern void cuio_copydata(struct uio* uio, int off, int len, caddr_t cp);
extern void cuio_copyback(struct uio* uio, int off, int len, caddr_t cp);
extern struct iovec *cuio_getptr(struct uio *uio, int loc, int *off);
extern void crypto_copyback(int flags, caddr_t buf, int off, int size,
caddr_t in);
extern void crypto_copydata(int flags, caddr_t buf, int off, int size,
caddr_t out);
extern int crypto_apply(int flags, caddr_t buf, int off, int len,
int (*f)(void *, void *, u_int), void *arg);
#endif /* __KERNEL__ */
#endif /* _CRYPTO_CRYPTO_H_ */

View file

@ -0,0 +1,898 @@
/*
* An OCF module that uses the linux kernel cryptoapi, based on the
* original cryptosoft for BSD by Angelos D. Keromytis (angelos@cis.upenn.edu)
* but is mostly unrecognisable,
*
* Written by David McCullough <david_mccullough@securecomputing.com>
* Copyright (C) 2004-2007 David McCullough
* Copyright (C) 2004-2005 Intel Corporation.
*
* LICENSE TERMS
*
* The free distribution and use of this software in both source and binary
* form is allowed (with or without changes) provided that:
*
* 1. distributions of this source code include the above copyright
* notice, this list of conditions and the following disclaimer;
*
* 2. distributions in binary form include the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other associated materials;
*
* 3. the copyright holder's name is not used to endorse products
* built using this software without specific written permission.
*
* ALTERNATIVELY, provided that this notice is retained in full, this product
* may be distributed under the terms of the GNU General Public License (GPL),
* in which case the provisions of the GPL apply INSTEAD OF those given above.
*
* DISCLAIMER
*
* This software is provided 'as is' with no explicit or implied warranties
* in respect of its properties, including, but not limited to, correctness
* and/or fitness for purpose.
* ---------------------------------------------------------------------------
*/
#ifndef AUTOCONF_INCLUDED
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/crypto.h>
#include <linux/mm.h>
#include <linux/skbuff.h>
#include <linux/random.h>
#include <asm/scatterlist.h>
#include <cryptodev.h>
#include <uio.h>
struct {
softc_device_decl sc_dev;
} swcr_softc;
#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
/* Software session entry */
#define SW_TYPE_CIPHER 0
#define SW_TYPE_HMAC 1
#define SW_TYPE_AUTH2 2
#define SW_TYPE_HASH 3
#define SW_TYPE_COMP 4
#define SW_TYPE_BLKCIPHER 5
struct swcr_data {
int sw_type;
int sw_alg;
struct crypto_tfm *sw_tfm;
union {
struct {
char *sw_key;
int sw_klen;
int sw_mlen;
} hmac;
void *sw_comp_buf;
} u;
struct swcr_data *sw_next;
};
#ifndef CRYPTO_TFM_MODE_CBC
/*
* As of linux-2.6.21 this is no longer defined, and presumably no longer
* needed to be passed into the crypto core code.
*/
#define CRYPTO_TFM_MODE_CBC 0
#define CRYPTO_TFM_MODE_ECB 0
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
/*
* Linux 2.6.19 introduced a new Crypto API, setup macro's to convert new
* API into old API.
*/
/* Symmetric/Block Cipher */
struct blkcipher_desc
{
struct crypto_tfm *tfm;
void *info;
};
#define ecb(X) #X
#define cbc(X) #X
#define crypto_has_blkcipher(X, Y, Z) crypto_alg_available(X, 0)
#define crypto_blkcipher_cast(X) X
#define crypto_blkcipher_tfm(X) X
#define crypto_alloc_blkcipher(X, Y, Z) crypto_alloc_tfm(X, mode)
#define crypto_blkcipher_ivsize(X) crypto_tfm_alg_ivsize(X)
#define crypto_blkcipher_blocksize(X) crypto_tfm_alg_blocksize(X)
#define crypto_blkcipher_setkey(X, Y, Z) crypto_cipher_setkey(X, Y, Z)
#define crypto_blkcipher_encrypt_iv(W, X, Y, Z) \
crypto_cipher_encrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
#define crypto_blkcipher_decrypt_iv(W, X, Y, Z) \
crypto_cipher_decrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
/* Hash/HMAC/Digest */
struct hash_desc
{
struct crypto_tfm *tfm;
};
#define hmac(X) #X
#define crypto_has_hash(X, Y, Z) crypto_alg_available(X, 0)
#define crypto_hash_cast(X) X
#define crypto_hash_tfm(X) X
#define crypto_alloc_hash(X, Y, Z) crypto_alloc_tfm(X, mode)
#define crypto_hash_digestsize(X) crypto_tfm_alg_digestsize(X)
#define crypto_hash_digest(W, X, Y, Z) \
crypto_digest_digest((W)->tfm, X, sg_num, Z)
/* Asymmetric Cipher */
#define crypto_has_cipher(X, Y, Z) crypto_alg_available(X, 0)
/* Compression */
#define crypto_has_comp(X, Y, Z) crypto_alg_available(X, 0)
#define crypto_comp_tfm(X) X
#define crypto_comp_cast(X) X
#define crypto_alloc_comp(X, Y, Z) crypto_alloc_tfm(X, mode)
#else
#define ecb(X) "ecb(" #X ")"
#define cbc(X) "cbc(" #X ")"
#define hmac(X) "hmac(" #X ")"
#endif /* if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
struct crypto_details
{
char *alg_name;
int mode;
int sw_type;
};
/*
* This needs to be kept updated with CRYPTO_xxx list (cryptodev.h).
* If the Algorithm is not supported, then insert a {NULL, 0, 0} entry.
*
* IMPORTANT: The index to the array IS CRYPTO_xxx.
*/
static struct crypto_details crypto_details[CRYPTO_ALGORITHM_MAX + 1] = {
{ NULL, 0, 0 },
/* CRYPTO_xxx index starts at 1 */
{ cbc(des), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
{ cbc(des3_ede), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
{ cbc(blowfish), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
{ cbc(cast5), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
{ cbc(skipjack), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
{ hmac(md5), 0, SW_TYPE_HMAC },
{ hmac(sha1), 0, SW_TYPE_HMAC },
{ hmac(ripemd160), 0, SW_TYPE_HMAC },
{ "md5-kpdk??", 0, SW_TYPE_HASH },
{ "sha1-kpdk??", 0, SW_TYPE_HASH },
{ cbc(aes), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
{ ecb(arc4), CRYPTO_TFM_MODE_ECB, SW_TYPE_BLKCIPHER },
{ "md5", 0, SW_TYPE_HASH },
{ "sha1", 0, SW_TYPE_HASH },
{ hmac(digest_null), 0, SW_TYPE_HMAC },
{ cbc(cipher_null), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
{ "deflate", 0, SW_TYPE_COMP },
{ hmac(sha256), 0, SW_TYPE_HMAC },
{ hmac(sha384), 0, SW_TYPE_HMAC },
{ hmac(sha512), 0, SW_TYPE_HMAC },
{ cbc(camellia), CRYPTO_TFM_MODE_CBC, SW_TYPE_BLKCIPHER },
{ "sha256", 0, SW_TYPE_HASH },
{ "sha384", 0, SW_TYPE_HASH },
{ "sha512", 0, SW_TYPE_HASH },
{ "ripemd160", 0, SW_TYPE_HASH },
};
int32_t swcr_id = -1;
module_param(swcr_id, int, 0444);
MODULE_PARM_DESC(swcr_id, "Read-Only OCF ID for cryptosoft driver");
int swcr_fail_if_compression_grows = 1;
module_param(swcr_fail_if_compression_grows, int, 0644);
MODULE_PARM_DESC(swcr_fail_if_compression_grows,
"Treat compression that results in more data as a failure");
static struct swcr_data **swcr_sessions = NULL;
static u_int32_t swcr_sesnum = 0;
static int swcr_process(device_t, struct cryptop *, int);
static int swcr_newsession(device_t, u_int32_t *, struct cryptoini *);
static int swcr_freesession(device_t, u_int64_t);
static device_method_t swcr_methods = {
/* crypto device methods */
DEVMETHOD(cryptodev_newsession, swcr_newsession),
DEVMETHOD(cryptodev_freesession,swcr_freesession),
DEVMETHOD(cryptodev_process, swcr_process),
};
#define debug swcr_debug
int swcr_debug = 0;
module_param(swcr_debug, int, 0644);
MODULE_PARM_DESC(swcr_debug, "Enable debug");
/*
* Generate a new software session.
*/
static int
swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
{
struct swcr_data **swd;
u_int32_t i;
int error;
char *algo;
int mode, sw_type;
dprintk("%s()\n", __FUNCTION__);
if (sid == NULL || cri == NULL) {
dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
return EINVAL;
}
if (swcr_sessions) {
for (i = 1; i < swcr_sesnum; i++)
if (swcr_sessions[i] == NULL)
break;
} else
i = 1; /* NB: to silence compiler warning */
if (swcr_sessions == NULL || i == swcr_sesnum) {
if (swcr_sessions == NULL) {
i = 1; /* We leave swcr_sessions[0] empty */
swcr_sesnum = CRYPTO_SW_SESSIONS;
} else
swcr_sesnum *= 2;
swd = kmalloc(swcr_sesnum * sizeof(struct swcr_data *), SLAB_ATOMIC);
if (swd == NULL) {
/* Reset session number */
if (swcr_sesnum == CRYPTO_SW_SESSIONS)
swcr_sesnum = 0;
else
swcr_sesnum /= 2;
dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
return ENOBUFS;
}
memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *));
/* Copy existing sessions */
if (swcr_sessions) {
memcpy(swd, swcr_sessions,
(swcr_sesnum / 2) * sizeof(struct swcr_data *));
kfree(swcr_sessions);
}
swcr_sessions = swd;
}
swd = &swcr_sessions[i];
*sid = i;
while (cri) {
*swd = (struct swcr_data *) kmalloc(sizeof(struct swcr_data),
SLAB_ATOMIC);
if (*swd == NULL) {
swcr_freesession(NULL, i);
dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
return ENOBUFS;
}
memset(*swd, 0, sizeof(struct swcr_data));
if (cri->cri_alg > CRYPTO_ALGORITHM_MAX) {
printk("cryptosoft: Unknown algorithm 0x%x\n", cri->cri_alg);
swcr_freesession(NULL, i);
return EINVAL;
}
algo = crypto_details[cri->cri_alg].alg_name;
if (!algo || !*algo) {
printk("cryptosoft: Unsupported algorithm 0x%x\n", cri->cri_alg);
swcr_freesession(NULL, i);
return EINVAL;
}
mode = crypto_details[cri->cri_alg].mode;
sw_type = crypto_details[cri->cri_alg].sw_type;
/* Algorithm specific configuration */
switch (cri->cri_alg) {
case CRYPTO_NULL_CBC:
cri->cri_klen = 0; /* make it work with crypto API */
break;
default:
break;
}
if (sw_type == SW_TYPE_BLKCIPHER) {
dprintk("%s crypto_alloc_blkcipher(%s, 0x%x)\n", __FUNCTION__,
algo, mode);
(*swd)->sw_tfm = crypto_blkcipher_tfm(
crypto_alloc_blkcipher(algo, 0,
CRYPTO_ALG_ASYNC));
if (!(*swd)->sw_tfm) {
dprintk("cryptosoft: crypto_alloc_blkcipher failed(%s,0x%x)\n",
algo,mode);
swcr_freesession(NULL, i);
return EINVAL;
}
if (debug) {
dprintk("%s key:cri->cri_klen=%d,(cri->cri_klen + 7)/8=%d",
__FUNCTION__,cri->cri_klen,(cri->cri_klen + 7)/8);
for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
{
dprintk("%s0x%x", (i % 8) ? " " : "\n ",cri->cri_key[i]);
}
dprintk("\n");
}
error = crypto_blkcipher_setkey(
crypto_blkcipher_cast((*swd)->sw_tfm), cri->cri_key,
(cri->cri_klen + 7) / 8);
if (error) {
printk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n", error,
(*swd)->sw_tfm->crt_flags);
swcr_freesession(NULL, i);
return error;
}
} else if (sw_type == SW_TYPE_HMAC || sw_type == SW_TYPE_HASH) {
dprintk("%s crypto_alloc_hash(%s, 0x%x)\n", __FUNCTION__,
algo, mode);
(*swd)->sw_tfm = crypto_hash_tfm(
crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC));
if (!(*swd)->sw_tfm) {
dprintk("cryptosoft: crypto_alloc_hash failed(%s,0x%x)\n",
algo, mode);
swcr_freesession(NULL, i);
return EINVAL;
}
(*swd)->u.hmac.sw_klen = (cri->cri_klen + 7) / 8;
(*swd)->u.hmac.sw_key = (char *)kmalloc((*swd)->u.hmac.sw_klen,
SLAB_ATOMIC);
if ((*swd)->u.hmac.sw_key == NULL) {
swcr_freesession(NULL, i);
dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
return ENOBUFS;
}
memcpy((*swd)->u.hmac.sw_key, cri->cri_key, (*swd)->u.hmac.sw_klen);
if (cri->cri_mlen) {
(*swd)->u.hmac.sw_mlen = cri->cri_mlen;
} else {
(*swd)->u.hmac.sw_mlen =
crypto_hash_digestsize(
crypto_hash_cast((*swd)->sw_tfm));
}
} else if (sw_type == SW_TYPE_COMP) {
(*swd)->sw_tfm = crypto_comp_tfm(
crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC));
if (!(*swd)->sw_tfm) {
dprintk("cryptosoft: crypto_alloc_comp failed(%s,0x%x)\n",
algo, mode);
swcr_freesession(NULL, i);
return EINVAL;
}
(*swd)->u.sw_comp_buf = kmalloc(CRYPTO_MAX_DATA_LEN, SLAB_ATOMIC);
if ((*swd)->u.sw_comp_buf == NULL) {
swcr_freesession(NULL, i);
dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
return ENOBUFS;
}
} else {
printk("cryptosoft: Unhandled sw_type %d\n", sw_type);
swcr_freesession(NULL, i);
return EINVAL;
}
(*swd)->sw_alg = cri->cri_alg;
(*swd)->sw_type = sw_type;
cri = cri->cri_next;
swd = &((*swd)->sw_next);
}
return 0;
}
/*
* Free a session.
*/
static int
swcr_freesession(device_t dev, u_int64_t tid)
{
struct swcr_data *swd;
u_int32_t sid = CRYPTO_SESID2LID(tid);
dprintk("%s()\n", __FUNCTION__);
if (sid > swcr_sesnum || swcr_sessions == NULL ||
swcr_sessions[sid] == NULL) {
dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
return(EINVAL);
}
/* Silently accept and return */
if (sid == 0)
return(0);
while ((swd = swcr_sessions[sid]) != NULL) {
swcr_sessions[sid] = swd->sw_next;
if (swd->sw_tfm)
crypto_free_tfm(swd->sw_tfm);
if (swd->sw_type == SW_TYPE_COMP) {
if (swd->u.sw_comp_buf)
kfree(swd->u.sw_comp_buf);
} else {
if (swd->u.hmac.sw_key)
kfree(swd->u.hmac.sw_key);
}
kfree(swd);
}
return 0;
}
/*
* Process a software request.
*/
static int
swcr_process(device_t dev, struct cryptop *crp, int hint)
{
struct cryptodesc *crd;
struct swcr_data *sw;
u_int32_t lid;
#define SCATTERLIST_MAX 16
struct scatterlist sg[SCATTERLIST_MAX];
int sg_num, sg_len, skip;
struct sk_buff *skb = NULL;
struct uio *uiop = NULL;
dprintk("%s()\n", __FUNCTION__);
/* Sanity check */
if (crp == NULL) {
dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
return EINVAL;
}
crp->crp_etype = 0;
if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
crp->crp_etype = EINVAL;
goto done;
}
lid = crp->crp_sid & 0xffffffff;
if (lid >= swcr_sesnum || lid == 0 || swcr_sessions == NULL ||
swcr_sessions[lid] == NULL) {
crp->crp_etype = ENOENT;
dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
goto done;
}
/*
* do some error checking outside of the loop for SKB and IOV processing
* this leaves us with valid skb or uiop pointers for later
*/
if (crp->crp_flags & CRYPTO_F_SKBUF) {
skb = (struct sk_buff *) crp->crp_buf;
if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
skb_shinfo(skb)->nr_frags);
goto done;
}
} else if (crp->crp_flags & CRYPTO_F_IOV) {
uiop = (struct uio *) crp->crp_buf;
if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
uiop->uio_iovcnt);
goto done;
}
}
/* Go through crypto descriptors, processing as we go */
for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
/*
* Find the crypto context.
*
* XXX Note that the logic here prevents us from having
* XXX the same algorithm multiple times in a session
* XXX (or rather, we can but it won't give us the right
* XXX results). To do that, we'd need some way of differentiating
* XXX between the various instances of an algorithm (so we can
* XXX locate the correct crypto context).
*/
for (sw = swcr_sessions[lid]; sw && sw->sw_alg != crd->crd_alg;
sw = sw->sw_next)
;
/* No such context ? */
if (sw == NULL) {
crp->crp_etype = EINVAL;
dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
goto done;
}
skip = crd->crd_skip;
/*
* setup the SG list skip from the start of the buffer
*/
memset(sg, 0, sizeof(sg));
if (crp->crp_flags & CRYPTO_F_SKBUF) {
int i, len;
sg_num = 0;
sg_len = 0;
if (skip < skb_headlen(skb)) {
len = skb_headlen(skb) - skip;
if (len + sg_len > crd->crd_len)
len = crd->crd_len - sg_len;
sg_set_page(&sg[sg_num],
virt_to_page(skb->data + skip), len,
offset_in_page(skb->data + skip));
sg_len += len;
sg_num++;
skip = 0;
} else
skip -= skb_headlen(skb);
for (i = 0; sg_len < crd->crd_len &&
i < skb_shinfo(skb)->nr_frags &&
sg_num < SCATTERLIST_MAX; i++) {
if (skip < skb_shinfo(skb)->frags[i].size) {
len = skb_shinfo(skb)->frags[i].size - skip;
if (len + sg_len > crd->crd_len)
len = crd->crd_len - sg_len;
sg_set_page(&sg[sg_num],
skb_shinfo(skb)->frags[i].page,
len,
skb_shinfo(skb)->frags[i].page_offset + skip);
sg_len += len;
sg_num++;
skip = 0;
} else
skip -= skb_shinfo(skb)->frags[i].size;
}
} else if (crp->crp_flags & CRYPTO_F_IOV) {
int len;
sg_len = 0;
for (sg_num = 0; sg_len <= crd->crd_len &&
sg_num < uiop->uio_iovcnt &&
sg_num < SCATTERLIST_MAX; sg_num++) {
if (skip <= uiop->uio_iov[sg_num].iov_len) {
len = uiop->uio_iov[sg_num].iov_len - skip;
if (len + sg_len > crd->crd_len)
len = crd->crd_len - sg_len;
sg_set_page(&sg[sg_num],
virt_to_page(uiop->uio_iov[sg_num].iov_base+skip),
len,
offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));
sg_len += len;
skip = 0;
} else
skip -= uiop->uio_iov[sg_num].iov_len;
}
} else {
sg_len = (crp->crp_ilen - skip);
if (sg_len > crd->crd_len)
sg_len = crd->crd_len;
sg_set_page(&sg[0], virt_to_page(crp->crp_buf + skip),
sg_len, offset_in_page(crp->crp_buf + skip));
sg_num = 1;
}
switch (sw->sw_type) {
case SW_TYPE_BLKCIPHER: {
unsigned char iv[EALG_MAX_BLOCK_LEN];
unsigned char *ivp = iv;
int ivsize =
crypto_blkcipher_ivsize(crypto_blkcipher_cast(sw->sw_tfm));
struct blkcipher_desc desc;
if (sg_len < crypto_blkcipher_blocksize(
crypto_blkcipher_cast(sw->sw_tfm))) {
crp->crp_etype = EINVAL;
dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
sg_len, crypto_blkcipher_blocksize(
crypto_blkcipher_cast(sw->sw_tfm)));
goto done;
}
if (ivsize > sizeof(iv)) {
crp->crp_etype = EINVAL;
dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
goto done;
}
if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
int i, error;
if (debug) {
dprintk("%s key:", __FUNCTION__);
for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
dprintk("%s0x%x", (i % 8) ? " " : "\n ",
crd->crd_key[i]);
dprintk("\n");
}
error = crypto_blkcipher_setkey(
crypto_blkcipher_cast(sw->sw_tfm), crd->crd_key,
(crd->crd_klen + 7) / 8);
if (error) {
dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
error, sw->sw_tfm->crt_flags);
crp->crp_etype = -error;
}
}
memset(&desc, 0, sizeof(desc));
desc.tfm = crypto_blkcipher_cast(sw->sw_tfm);
if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
ivp = crd->crd_iv;
} else {
get_random_bytes(ivp, ivsize);
}
/*
* do we have to copy the IV back to the buffer ?
*/
if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
crypto_copyback(crp->crp_flags, crp->crp_buf,
crd->crd_inject, ivsize, (caddr_t)ivp);
}
desc.info = ivp;
crypto_blkcipher_encrypt_iv(&desc, sg, sg, sg_len);
} else { /*decrypt */
if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
ivp = crd->crd_iv;
} else {
crypto_copydata(crp->crp_flags, crp->crp_buf,
crd->crd_inject, ivsize, (caddr_t)ivp);
}
desc.info = ivp;
crypto_blkcipher_decrypt_iv(&desc, sg, sg, sg_len);
}
} break;
case SW_TYPE_HMAC:
case SW_TYPE_HASH:
{
char result[HASH_MAX_LEN];
struct hash_desc desc;
/* check we have room for the result */
if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
dprintk(
"cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d digestsize=%d\n",
crp->crp_ilen, crd->crd_skip + sg_len, crd->crd_inject,
sw->u.hmac.sw_mlen);
crp->crp_etype = EINVAL;
goto done;
}
memset(&desc, 0, sizeof(desc));
desc.tfm = crypto_hash_cast(sw->sw_tfm);
memset(result, 0, sizeof(result));
if (sw->sw_type == SW_TYPE_HMAC) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
crypto_hmac(sw->sw_tfm, sw->u.hmac.sw_key, &sw->u.hmac.sw_klen,
sg, sg_num, result);
#else
crypto_hash_setkey(desc.tfm, sw->u.hmac.sw_key,
sw->u.hmac.sw_klen);
crypto_hash_digest(&desc, sg, sg_len, result);
#endif /* #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
} else { /* SW_TYPE_HASH */
crypto_hash_digest(&desc, sg, sg_len, result);
}
crypto_copyback(crp->crp_flags, crp->crp_buf,
crd->crd_inject, sw->u.hmac.sw_mlen, result);
}
break;
case SW_TYPE_COMP: {
void *ibuf = NULL;
void *obuf = sw->u.sw_comp_buf;
int ilen = sg_len, olen = CRYPTO_MAX_DATA_LEN;
int ret = 0;
/*
* we need to use an additional copy if there is more than one
* input chunk since the kernel comp routines do not handle
* SG yet. Otherwise we just use the input buffer as is.
* Rather than allocate another buffer we just split the tmp
* buffer we already have.
* Perhaps we should just use zlib directly ?
*/
if (sg_num > 1) {
int blk;
ibuf = obuf;
for (blk = 0; blk < sg_num; blk++) {
memcpy(obuf, sg_virt(&sg[blk]),
sg[blk].length);
obuf += sg[blk].length;
}
olen -= sg_len;
} else
ibuf = sg_virt(&sg[0]);
if (crd->crd_flags & CRD_F_ENCRYPT) { /* compress */
ret = crypto_comp_compress(crypto_comp_cast(sw->sw_tfm),
ibuf, ilen, obuf, &olen);
if (!ret && olen > crd->crd_len) {
dprintk("cryptosoft: ERANGE compress %d into %d\n",
crd->crd_len, olen);
if (swcr_fail_if_compression_grows)
ret = ERANGE;
}
} else { /* decompress */
ret = crypto_comp_decompress(crypto_comp_cast(sw->sw_tfm),
ibuf, ilen, obuf, &olen);
if (!ret && (olen + crd->crd_inject) > crp->crp_olen) {
dprintk("cryptosoft: ETOOSMALL decompress %d into %d, "
"space for %d,at offset %d\n",
crd->crd_len, olen, crp->crp_olen, crd->crd_inject);
ret = ETOOSMALL;
}
}
if (ret)
dprintk("%s,%d: ret = %d\n", __FILE__, __LINE__, ret);
/*
* on success copy result back,
* linux crpyto API returns -errno, we need to fix that
*/
crp->crp_etype = ret < 0 ? -ret : ret;
if (ret == 0) {
/* copy back the result and return it's size */
crypto_copyback(crp->crp_flags, crp->crp_buf,
crd->crd_inject, olen, obuf);
crp->crp_olen = olen;
}
} break;
default:
/* Unknown/unsupported algorithm */
dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
crp->crp_etype = EINVAL;
goto done;
}
}
done:
crypto_done(crp);
return 0;
}
static int
cryptosoft_init(void)
{
int i, sw_type, mode;
char *algo;
dprintk("%s(%p)\n", __FUNCTION__, cryptosoft_init);
softc_device_init(&swcr_softc, "cryptosoft", 0, swcr_methods);
swcr_id = crypto_get_driverid(softc_get_device(&swcr_softc),
CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
if (swcr_id < 0) {
printk("Software crypto device cannot initialize!");
return -ENODEV;
}
#define REGISTER(alg) \
crypto_register(swcr_id, alg, 0,0);
for (i = CRYPTO_ALGORITHM_MIN; i <= CRYPTO_ALGORITHM_MAX; ++i)
{
algo = crypto_details[i].alg_name;
if (!algo || !*algo)
{
dprintk("%s:Algorithm %d not supported\n", __FUNCTION__, i);
continue;
}
mode = crypto_details[i].mode;
sw_type = crypto_details[i].sw_type;
switch (sw_type)
{
case SW_TYPE_CIPHER:
if (crypto_has_cipher(algo, 0, CRYPTO_ALG_ASYNC))
{
REGISTER(i);
}
else
{
dprintk("%s:CIPHER algorithm %d:'%s' not supported\n",
__FUNCTION__, i, algo);
}
break;
case SW_TYPE_HMAC:
if (crypto_has_hash(algo, 0, CRYPTO_ALG_ASYNC))
{
REGISTER(i);
}
else
{
dprintk("%s:HMAC algorithm %d:'%s' not supported\n",
__FUNCTION__, i, algo);
}
break;
case SW_TYPE_HASH:
if (crypto_has_hash(algo, 0, CRYPTO_ALG_ASYNC))
{
REGISTER(i);
}
else
{
dprintk("%s:HASH algorithm %d:'%s' not supported\n",
__FUNCTION__, i, algo);
}
break;
case SW_TYPE_COMP:
if (crypto_has_comp(algo, 0, CRYPTO_ALG_ASYNC))
{
REGISTER(i);
}
else
{
dprintk("%s:COMP algorithm %d:'%s' not supported\n",
__FUNCTION__, i, algo);
}
break;
case SW_TYPE_BLKCIPHER:
if (crypto_has_blkcipher(algo, 0, CRYPTO_ALG_ASYNC))
{
REGISTER(i);
}
else
{
dprintk("%s:BLKCIPHER algorithm %d:'%s' not supported\n",
__FUNCTION__, i, algo);
}
break;
default:
dprintk(
"%s:Algorithm Type %d not supported (algorithm %d:'%s')\n",
__FUNCTION__, sw_type, i, algo);
break;
}
}
return(0);
}
static void
cryptosoft_exit(void)
{
dprintk("%s()\n", __FUNCTION__);
crypto_unregister_all(swcr_id);
swcr_id = -1;
}
module_init(cryptosoft_init);
module_exit(cryptosoft_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
MODULE_DESCRIPTION("Cryptosoft (OCF module for kernel crypto)");

View file

@ -0,0 +1,107 @@
#########################################################################
#
# Targets supported
# all - builds everything and installs
# install - identical to all
# depend - build dependencies
# clean - clears derived objects except the .depend files
# distclean- clears all derived objects and the .depend file
#
# @par
# This file is provided under a dual BSD/GPLv2 license. When using or
# redistributing this file, you may do so under either license.
#
# GPL LICENSE SUMMARY
#
# Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
# The full GNU General Public License is included in this distribution
# in the file called LICENSE.GPL.
#
# Contact Information:
# Intel Corporation
#
# BSD LICENSE
#
# Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
# version: Security.L.1.0.130
############################################################################
####################Common variables and definitions########################
# Ensure The ENV_DIR environmental var is defined.
ifndef ICP_ENV_DIR
$(error ICP_ENV_DIR is undefined. Please set the path to your environment makefile \
"-> setenv ICP_ENV_DIR <path>")
endif
#Add your project environment Makefile
include $(ICP_ENV_DIR)/environment.mk
#include the makefile with all the default and common Make variable definitions
include $(ICP_BUILDSYSTEM_PATH)/build_files/common.mk
#Add the name for the executable, Library or Module output definitions
OUTPUT_NAME= icp_ocf
# List of Source Files to be compiled
SOURCES= icp_common.c icp_sym.c icp_asym.c
#common includes between all supported OSes
INCLUDES= -I $(ICP_API_DIR) -I$(ICP_LAC_API) \
-I$(ICP_OCF_SRC_DIR)
# The location of the os level makefile needs to be changed.
include $(ICP_ENV_DIR)/$(ICP_OS)_$(ICP_OS_LEVEL).mk
# On the line directly below list the outputs you wish to build for,
# e.g "lib_static lib_shared exe module" as show below
install: module
###################Include rules makefiles########################
include $(ICP_BUILDSYSTEM_PATH)/build_files/rules.mk
###################End of Rules inclusion#########################

View file

@ -0,0 +1,75 @@
###########################################################################
#
# This file is provided under a dual BSD/GPLv2 license. When using or
# redistributing this file, you may do so under either license.
#
# GPL LICENSE SUMMARY
#
# Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
# The full GNU General Public License is included in this distribution
# in the file called LICENSE.GPL.
#
# Contact Information:
# Intel Corporation
#
# BSD LICENSE
#
# Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
# version: Security.L.1.0.130
#
###########################################################################
ICP_LAC_API=$(ICP_ROOT)/Acceleration/include/lac
ICP_BTR_API=$(ICP_ROOT)/Acceleration/include/btr
ICP_API_DIR=$(ICP_ROOT)/Acceleration/include
ICP_OCF_SHIM_DIR?=$(KERNEL_SOURCE_ROOT)/crypto/ocf/
ICP_OS_LEVEL?=kernel_space
ICP_OS?=linux_2.6
ICP_CORE?=ia

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,891 @@
/***************************************************************************
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.GPL.
*
* Contact Information:
* Intel Corporation
*
* BSD LICENSE
*
* Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* version: Security.L.1.0.130
*
***************************************************************************/
/*
* An OCF module that uses Intel® QuickAssist Integrated Accelerator to do the
* crypto.
*
* This driver requires the ICP Access Library that is available from Intel in
* order to operate.
*/
#include "icp_ocf.h"
#define ICP_OCF_COMP_NAME "ICP_OCF"
#define ICP_OCF_VER_MAIN (2)
#define ICP_OCF_VER_MJR (0)
#define ICP_OCF_VER_MNR (0)
#define MAX_DEREG_RETRIES (100)
#define DEFAULT_DEREG_RETRIES (10)
#define DEFAULT_DEREG_DELAY_IN_JIFFIES (10)
/* This defines the maximum number of sessions possible between OCF
and the OCF Tolapai Driver. If set to zero, there is no limit. */
#define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT (0)
#define NUM_SUPPORTED_CAPABILITIES (21)
/*Slabs zones*/
struct kmem_cache *drvSessionData_zone = NULL;
struct kmem_cache *drvOpData_zone = NULL;
struct kmem_cache *drvDH_zone = NULL;
struct kmem_cache *drvLnModExp_zone = NULL;
struct kmem_cache *drvRSADecrypt_zone = NULL;
struct kmem_cache *drvRSAPrivateKey_zone = NULL;
struct kmem_cache *drvDSARSSign_zone = NULL;
struct kmem_cache *drvDSARSSignKValue_zone = NULL;
struct kmem_cache *drvDSAVerify_zone = NULL;
/*Slab zones for flatbuffers and bufferlist*/
struct kmem_cache *drvFlatBuffer_zone = NULL;
static int icp_ocfDrvInit(void);
static void icp_ocfDrvExit(void);
static void icp_ocfDrvFreeCaches(void);
static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg);
int32_t icp_ocfDrvDriverId = INVALID_DRIVER_ID;
/* Module parameter - gives the number of times LAC deregistration shall be
re-tried */
int num_dereg_retries = DEFAULT_DEREG_RETRIES;
/* Module parameter - gives the delay time in jiffies before a LAC session
shall be attempted to be deregistered again */
int dereg_retry_delay_in_jiffies = DEFAULT_DEREG_DELAY_IN_JIFFIES;
/* Module parameter - gives the maximum number of sessions possible between
OCF and the OCF Tolapai Driver. If set to zero, there is no limit.*/
int max_sessions = DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT;
/* This is set when the module is removed from the system, no further
processing can take place if this is set */
atomic_t icp_ocfDrvIsExiting = ATOMIC_INIT(0);
/* This is used to show how many lac sessions were not deregistered*/
atomic_t lac_session_failed_dereg_count = ATOMIC_INIT(0);
/* This is used to track the number of registered sessions between OCF and
* and the OCF Tolapai driver, when max_session is set to value other than
* zero. This ensures that the max_session set for the OCF and the driver
* is equal to the LAC registered sessions */
atomic_t num_ocf_to_drv_registered_sessions = ATOMIC_INIT(0);
/* Head of linked list used to store session data */
struct list_head icp_ocfDrvGlobalSymListHead;
struct list_head icp_ocfDrvGlobalSymListHead_FreeMemList;
spinlock_t icp_ocfDrvSymSessInfoListSpinlock = SPIN_LOCK_UNLOCKED;
rwlock_t icp_kmem_cache_destroy_alloc_lock = RW_LOCK_UNLOCKED;
struct workqueue_struct *icp_ocfDrvFreeLacSessionWorkQ;
struct icp_drvBuffListInfo defBuffListInfo;
static struct {
softc_device_decl sc_dev;
} icpDev;
static device_method_t icp_methods = {
/* crypto device methods */
DEVMETHOD(cryptodev_newsession, icp_ocfDrvNewSession),
DEVMETHOD(cryptodev_freesession, icp_ocfDrvFreeLACSession),
DEVMETHOD(cryptodev_process, icp_ocfDrvSymProcess),
DEVMETHOD(cryptodev_kprocess, icp_ocfDrvPkeProcess),
};
module_param(num_dereg_retries, int, S_IRUGO);
module_param(dereg_retry_delay_in_jiffies, int, S_IRUGO);
module_param(max_sessions, int, S_IRUGO);
MODULE_PARM_DESC(num_dereg_retries,
"Number of times to retry LAC Sym Session Deregistration. "
"Default 10, Max 100");
MODULE_PARM_DESC(dereg_retry_delay_in_jiffies, "Delay in jiffies "
"(added to a schedule() function call) before a LAC Sym "
"Session Dereg is retried. Default 10");
MODULE_PARM_DESC(max_sessions, "This sets the maximum number of sessions "
"between OCF and this driver. If this value is set to zero, "
"max session count checking is disabled. Default is zero(0)");
/* Name : icp_ocfDrvInit
*
* Description : This function will register all the symmetric and asymmetric
* functionality that will be accelerated by the hardware. It will also
* get a unique driver ID from the OCF and initialise all slab caches
*/
static int __init icp_ocfDrvInit(void)
{
int ocfStatus = 0;
IPRINTK("=== %s ver %d.%d.%d ===\n", ICP_OCF_COMP_NAME,
ICP_OCF_VER_MAIN, ICP_OCF_VER_MJR, ICP_OCF_VER_MNR);
if (MAX_DEREG_RETRIES < num_dereg_retries) {
EPRINTK("Session deregistration retry count set to greater "
"than %d", MAX_DEREG_RETRIES);
return -1;
}
/* Initialize and Start the Cryptographic component */
if (CPA_STATUS_SUCCESS !=
cpaCyStartInstance(CPA_INSTANCE_HANDLE_SINGLE)) {
EPRINTK("Failed to initialize and start the instance "
"of the Cryptographic component.\n");
return -1;
}
/* Set the default size of BufferList to allocate */
memset(&defBuffListInfo, 0, sizeof(struct icp_drvBuffListInfo));
if (ICP_OCF_DRV_STATUS_SUCCESS !=
icp_ocfDrvBufferListMemInfo(ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS,
&defBuffListInfo)) {
EPRINTK("Failed to get bufferlist memory info.\n");
return -1;
}
/*Register OCF Tolapai Driver with OCF */
memset(&icpDev, 0, sizeof(icpDev));
softc_device_init(&icpDev, "icp", 0, icp_methods);
icp_ocfDrvDriverId = crypto_get_driverid(softc_get_device(&icpDev),
CRYPTOCAP_F_HARDWARE);
if (icp_ocfDrvDriverId < 0) {
EPRINTK("%s : ICP driver failed to register with OCF!\n",
__FUNCTION__);
return -ENODEV;
}
/*Create all the slab caches used by the OCF Tolapai Driver */
drvSessionData_zone =
ICP_CACHE_CREATE("ICP Session Data", struct icp_drvSessionData);
ICP_CACHE_NULL_CHECK(drvSessionData_zone);
/*
* Allocation of the OpData includes the allocation space for meta data.
* The memory after the opData structure is reserved for this meta data.
*/
drvOpData_zone =
kmem_cache_create("ICP Op Data", sizeof(struct icp_drvOpData) +
defBuffListInfo.metaSize ,0, SLAB_HWCACHE_ALIGN, NULL, NULL);
ICP_CACHE_NULL_CHECK(drvOpData_zone);
drvDH_zone = ICP_CACHE_CREATE("ICP DH data", CpaCyDhPhase1KeyGenOpData);
ICP_CACHE_NULL_CHECK(drvDH_zone);
drvLnModExp_zone =
ICP_CACHE_CREATE("ICP ModExp data", CpaCyLnModExpOpData);
ICP_CACHE_NULL_CHECK(drvLnModExp_zone);
drvRSADecrypt_zone =
ICP_CACHE_CREATE("ICP RSA decrypt data", CpaCyRsaDecryptOpData);
ICP_CACHE_NULL_CHECK(drvRSADecrypt_zone);
drvRSAPrivateKey_zone =
ICP_CACHE_CREATE("ICP RSA private key data", CpaCyRsaPrivateKey);
ICP_CACHE_NULL_CHECK(drvRSAPrivateKey_zone);
drvDSARSSign_zone =
ICP_CACHE_CREATE("ICP DSA Sign", CpaCyDsaRSSignOpData);
ICP_CACHE_NULL_CHECK(drvDSARSSign_zone);
/*too awkward to use a macro here */
drvDSARSSignKValue_zone =
kmem_cache_create("ICP DSA Sign Rand Val",
DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES, 0,
SLAB_HWCACHE_ALIGN, NULL, NULL);
ICP_CACHE_NULL_CHECK(drvDSARSSignKValue_zone);
drvDSAVerify_zone =
ICP_CACHE_CREATE("ICP DSA Verify", CpaCyDsaVerifyOpData);
ICP_CACHE_NULL_CHECK(drvDSAVerify_zone);
drvFlatBuffer_zone =
ICP_CACHE_CREATE("ICP Flat Buffers", CpaFlatBuffer);
ICP_CACHE_NULL_CHECK(drvFlatBuffer_zone);
/* Register the ICP symmetric crypto support. */
ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_NULL_CBC);
ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_DES_CBC);
ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_3DES_CBC);
ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_AES_CBC);
ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_ARC4);
ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_MD5);
ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_MD5_HMAC);
ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA1);
ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA1_HMAC);
ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_256);
ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_256_HMAC);
ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_384);
ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_384_HMAC);
ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_512);
ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_512_HMAC);
/* Register the ICP asymmetric algorithm support */
ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_DH_COMPUTE_KEY);
ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_MOD_EXP);
ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_MOD_EXP_CRT);
ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_DSA_SIGN);
ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_DSA_VERIFY);
/* Register the ICP random number generator support */
if (OCF_REGISTRATION_STATUS_SUCCESS ==
crypto_rregister(icp_ocfDrvDriverId, icp_ocfDrvReadRandom, NULL)) {
ocfStatus++;
}
if (OCF_ZERO_FUNCTIONALITY_REGISTERED == ocfStatus) {
DPRINTK("%s: Failed to register any device capabilities\n",
__FUNCTION__);
icp_ocfDrvFreeCaches();
icp_ocfDrvDriverId = INVALID_DRIVER_ID;
return -ECANCELED;
}
DPRINTK("%s: Registered %d of %d device capabilities\n",
__FUNCTION__, ocfStatus, NUM_SUPPORTED_CAPABILITIES);
/*Session data linked list used during module exit*/
INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead);
INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList);
icp_ocfDrvFreeLacSessionWorkQ =
create_singlethread_workqueue("ocfLacDeregWorkQueue");
return 0;
}
/* Name : icp_ocfDrvExit
*
* Description : This function will deregister all the symmetric sessions
* registered with the LAC component. It will also deregister all symmetric
* and asymmetric functionality that can be accelerated by the hardware via OCF
* and random number generation if it is enabled.
*/
static void icp_ocfDrvExit(void)
{
CpaStatus lacStatus = CPA_STATUS_SUCCESS;
struct icp_drvSessionData *sessionData = NULL;
struct icp_drvSessionData *tempSessionData = NULL;
int i, remaining_delay_time_in_jiffies = 0;
/* There is a possibility of a process or new session command being */
/* sent before this variable is incremented. The aim of this variable */
/* is to stop a loop of calls creating a deadlock situation which */
/* would prevent the driver from exiting. */
atomic_inc(&icp_ocfDrvIsExiting);
/*Existing sessions will be routed to another driver after these calls */
crypto_unregister_all(icp_ocfDrvDriverId);
crypto_runregister_all(icp_ocfDrvDriverId);
/*If any sessions are waiting to be deregistered, do that. This also
flushes the work queue */
destroy_workqueue(icp_ocfDrvFreeLacSessionWorkQ);
/*ENTER CRITICAL SECTION */
spin_lock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
list_for_each_entry_safe(tempSessionData, sessionData,
&icp_ocfDrvGlobalSymListHead, listNode) {
for (i = 0; i < num_dereg_retries; i++) {
/*No harm if bad input - LAC will handle error cases */
if (ICP_SESSION_RUNNING == tempSessionData->inUse) {
lacStatus =
cpaCySymRemoveSession
(CPA_INSTANCE_HANDLE_SINGLE,
tempSessionData->sessHandle);
if (CPA_STATUS_SUCCESS == lacStatus) {
/* Succesfully deregistered */
break;
} else if (CPA_STATUS_RETRY != lacStatus) {
atomic_inc
(&lac_session_failed_dereg_count);
break;
}
/*schedule_timout returns the time left for completion if
* this task is set to TASK_INTERRUPTIBLE */
remaining_delay_time_in_jiffies =
dereg_retry_delay_in_jiffies;
while (0 > remaining_delay_time_in_jiffies) {
remaining_delay_time_in_jiffies =
schedule_timeout
(remaining_delay_time_in_jiffies);
}
DPRINTK
("%s(): Retry %d to deregistrate the session\n",
__FUNCTION__, i);
}
}
/*remove from current list */
list_del(&(tempSessionData->listNode));
/*add to free mem linked list */
list_add(&(tempSessionData->listNode),
&icp_ocfDrvGlobalSymListHead_FreeMemList);
}
/*EXIT CRITICAL SECTION */
spin_unlock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
/*set back to initial values */
sessionData = NULL;
/*still have a reference in our list! */
tempSessionData = NULL;
/*free memory */
list_for_each_entry_safe(tempSessionData, sessionData,
&icp_ocfDrvGlobalSymListHead_FreeMemList,
listNode) {
list_del(&(tempSessionData->listNode));
/* Free allocated CpaCySymSessionCtx */
if (NULL != tempSessionData->sessHandle) {
kfree(tempSessionData->sessHandle);
}
memset(tempSessionData, 0, sizeof(struct icp_drvSessionData));
kmem_cache_free(drvSessionData_zone, tempSessionData);
}
if (0 != atomic_read(&lac_session_failed_dereg_count)) {
DPRINTK("%s(): %d LAC sessions were not deregistered "
"correctly. This is not a clean exit! \n",
__FUNCTION__,
atomic_read(&lac_session_failed_dereg_count));
}
icp_ocfDrvFreeCaches();
icp_ocfDrvDriverId = INVALID_DRIVER_ID;
/* Shutdown the Cryptographic component */
lacStatus = cpaCyStopInstance(CPA_INSTANCE_HANDLE_SINGLE);
if (CPA_STATUS_SUCCESS != lacStatus) {
DPRINTK("%s(): Failed to stop instance of the "
"Cryptographic component.(status == %d)\n",
__FUNCTION__, lacStatus);
}
}
/* Name : icp_ocfDrvFreeCaches
*
* Description : This function deregisters all slab caches
*/
static void icp_ocfDrvFreeCaches(void)
{
if (atomic_read(&icp_ocfDrvIsExiting) != CPA_TRUE) {
atomic_set(&icp_ocfDrvIsExiting, 1);
}
/*Sym Zones */
ICP_CACHE_DESTROY(drvSessionData_zone);
ICP_CACHE_DESTROY(drvOpData_zone);
/*Asym zones */
ICP_CACHE_DESTROY(drvDH_zone);
ICP_CACHE_DESTROY(drvLnModExp_zone);
ICP_CACHE_DESTROY(drvRSADecrypt_zone);
ICP_CACHE_DESTROY(drvRSAPrivateKey_zone);
ICP_CACHE_DESTROY(drvDSARSSignKValue_zone);
ICP_CACHE_DESTROY(drvDSARSSign_zone);
ICP_CACHE_DESTROY(drvDSAVerify_zone);
/*FlatBuffer and BufferList Zones */
ICP_CACHE_DESTROY(drvFlatBuffer_zone);
}
/* Name : icp_ocfDrvDeregRetry
*
* Description : This function will try to farm the session deregistration
* off to a work queue. If it fails, nothing more can be done and it
* returns an error
*/
int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)
{
struct icp_ocfDrvFreeLacSession *workstore = NULL;
DPRINTK("%s(): Retry - Deregistering session (%p)\n",
__FUNCTION__, sessionToDeregister);
/*make sure the session is not available to be allocated during this
process */
atomic_inc(&lac_session_failed_dereg_count);
/*Farm off to work queue */
workstore =
kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), GFP_ATOMIC);
if (NULL == workstore) {
DPRINTK("%s(): unable to free session - no memory available "
"for work queue\n", __FUNCTION__);
return ENOMEM;
}
workstore->sessionToDeregister = sessionToDeregister;
INIT_WORK(&(workstore->work), icp_ocfDrvDeferedFreeLacSessionProcess,
workstore);
queue_work(icp_ocfDrvFreeLacSessionWorkQ, &(workstore->work));
return ICP_OCF_DRV_STATUS_SUCCESS;
}
/* Name : icp_ocfDrvDeferedFreeLacSessionProcess
*
* Description : This function will retry (module input parameter)
* 'num_dereg_retries' times to deregister any symmetric session that recieves a
* CPA_STATUS_RETRY message from the LAC component. This function is run in
* Thread context because it is called from a worker thread
*/
static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
{
struct icp_ocfDrvFreeLacSession *workstore = NULL;
CpaCySymSessionCtx sessionToDeregister = NULL;
int i = 0;
int remaining_delay_time_in_jiffies = 0;
CpaStatus lacStatus = CPA_STATUS_SUCCESS;
workstore = (struct icp_ocfDrvFreeLacSession *)arg;
if (NULL == workstore) {
DPRINTK("%s() function called with null parameter \n",
__FUNCTION__);
return;
}
sessionToDeregister = workstore->sessionToDeregister;
kfree(workstore);
/*if exiting, give deregistration one more blast only */
if (atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) {
lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
sessionToDeregister);
if (lacStatus != CPA_STATUS_SUCCESS) {
DPRINTK("%s() Failed to Dereg LAC session %p "
"during module exit\n", __FUNCTION__,
sessionToDeregister);
return;
}
atomic_dec(&lac_session_failed_dereg_count);
return;
}
for (i = 0; i <= num_dereg_retries; i++) {
lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
sessionToDeregister);
if (lacStatus == CPA_STATUS_SUCCESS) {
atomic_dec(&lac_session_failed_dereg_count);
return;
}
if (lacStatus != CPA_STATUS_RETRY) {
DPRINTK("%s() Failed to deregister session - lacStatus "
" = %d", __FUNCTION__, lacStatus);
break;
}
/*schedule_timout returns the time left for completion if this
task is set to TASK_INTERRUPTIBLE */
remaining_delay_time_in_jiffies = dereg_retry_delay_in_jiffies;
while (0 > remaining_delay_time_in_jiffies) {
remaining_delay_time_in_jiffies =
schedule_timeout(remaining_delay_time_in_jiffies);
}
}
DPRINTK("%s(): Unable to deregister session\n", __FUNCTION__);
DPRINTK("%s(): Number of unavailable LAC sessions = %d\n", __FUNCTION__,
atomic_read(&lac_session_failed_dereg_count));
}
/* Name : icp_ocfDrvPtrAndLenToFlatBuffer
*
* Description : This function converts a "pointer and length" buffer
* structure to Fredericksburg Flat Buffer (CpaFlatBuffer) format.
*
* This function assumes that the data passed in are valid.
*/
inline void
icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
CpaFlatBuffer * pFlatBuffer)
{
pFlatBuffer->pData = pData;
pFlatBuffer->dataLenInBytes = len;
}
/* Name : icp_ocfDrvSingleSkBuffToFlatBuffer
*
* Description : This function converts a single socket buffer (sk_buff)
* structure to a Fredericksburg Flat Buffer (CpaFlatBuffer) format.
*
* This function assumes that the data passed in are valid.
*/
static inline void
icp_ocfDrvSingleSkBuffToFlatBuffer(struct sk_buff *pSkb,
CpaFlatBuffer * pFlatBuffer)
{
pFlatBuffer->pData = pSkb->data;
pFlatBuffer->dataLenInBytes = skb_headlen(pSkb);
}
/* Name : icp_ocfDrvSkBuffToBufferList
*
* Description : This function converts a socket buffer (sk_buff) structure to
* Fredericksburg Scatter/Gather (CpaBufferList) buffer format.
*
* This function assumes that the bufferlist has been allocated with the correct
* number of buffer arrays.
*
*/
inline int
icp_ocfDrvSkBuffToBufferList(struct sk_buff *pSkb, CpaBufferList * bufferList)
{
CpaFlatBuffer *curFlatBuffer = NULL;
char *skbuffPageAddr = NULL;
struct sk_buff *pCurFrag = NULL;
struct skb_shared_info *pShInfo = NULL;
uint32_t page_offset = 0, i = 0;
DPRINTK("%s(): Entry Point\n", __FUNCTION__);
/*
* In all cases, the first skb needs to be translated to FlatBuffer.
* Perform a buffer translation for the first skbuff
*/
curFlatBuffer = bufferList->pBuffers;
icp_ocfDrvSingleSkBuffToFlatBuffer(pSkb, curFlatBuffer);
/* Set the userData to point to the original sk_buff */
bufferList->pUserData = (void *)pSkb;
/* We now know we'll have at least one element in the SGL */
bufferList->numBuffers = 1;
if (0 == skb_is_nonlinear(pSkb)) {
/* Is a linear buffer - therefore it's a single skbuff */
DPRINTK("%s(): Exit Point\n", __FUNCTION__);
return ICP_OCF_DRV_STATUS_SUCCESS;
}
curFlatBuffer++;
pShInfo = skb_shinfo(pSkb);
if (pShInfo->frag_list != NULL && pShInfo->nr_frags != 0) {
EPRINTK("%s():"
"Translation for a combination of frag_list "
"and frags[] array not supported!\n", __FUNCTION__);
return ICP_OCF_DRV_STATUS_FAIL;
} else if (pShInfo->frag_list != NULL) {
/*
* Non linear skbuff supported through frag_list
* Perform translation for each fragment (sk_buff)
* in the frag_list of the first sk_buff.
*/
for (pCurFrag = pShInfo->frag_list;
pCurFrag != NULL; pCurFrag = pCurFrag->next) {
icp_ocfDrvSingleSkBuffToFlatBuffer(pCurFrag,
curFlatBuffer);
curFlatBuffer++;
bufferList->numBuffers++;
}
} else if (pShInfo->nr_frags != 0) {
/*
* Perform translation for each fragment in frags array
* and add to the BufferList
*/
for (i = 0; i < pShInfo->nr_frags; i++) {
/* Get the page address and offset of this frag */
skbuffPageAddr = (char *)pShInfo->frags[i].page;
page_offset = pShInfo->frags[i].page_offset;
/* Convert a pointer and length to a flat buffer */
icp_ocfDrvPtrAndLenToFlatBuffer(skbuffPageAddr +
page_offset,
pShInfo->frags[i].size,
curFlatBuffer);
curFlatBuffer++;
bufferList->numBuffers++;
}
} else {
EPRINTK("%s():" "Could not recognize skbuff fragments!\n",
__FUNCTION__);
return ICP_OCF_DRV_STATUS_FAIL;
}
DPRINTK("%s(): Exit Point\n", __FUNCTION__);
return ICP_OCF_DRV_STATUS_SUCCESS;
}
/* Name : icp_ocfDrvBufferListToSkBuff
*
* Description : This function converts a Fredericksburg Scatter/Gather
* (CpaBufferList) buffer format to socket buffer structure.
*/
inline int
icp_ocfDrvBufferListToSkBuff(CpaBufferList * bufferList, struct sk_buff **skb)
{
DPRINTK("%s(): Entry Point\n", __FUNCTION__);
/* Retrieve the orignal skbuff */
*skb = (struct sk_buff *)bufferList->pUserData;
if (NULL == *skb) {
EPRINTK("%s():"
"Error on converting from a BufferList. "
"The BufferList does not contain an sk_buff.\n",
__FUNCTION__);
return ICP_OCF_DRV_STATUS_FAIL;
}
DPRINTK("%s(): Exit Point\n", __FUNCTION__);
return ICP_OCF_DRV_STATUS_SUCCESS;
}
/* Name : icp_ocfDrvPtrAndLenToBufferList
*
* Description : This function converts a "pointer and length" buffer
* structure to Fredericksburg Scatter/Gather Buffer (CpaBufferList) format.
*
* This function assumes that the data passed in are valid.
*/
inline void
icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
CpaBufferList * pBufferList)
{
pBufferList->numBuffers = 1;
pBufferList->pBuffers->pData = pDataIn;
pBufferList->pBuffers->dataLenInBytes = length;
}
/* Name : icp_ocfDrvBufferListToPtrAndLen
*
* Description : This function converts Fredericksburg Scatter/Gather Buffer
* (CpaBufferList) format to a "pointer and length" buffer structure.
*
* This function assumes that the data passed in are valid.
*/
inline void
icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
void **ppDataOut, uint32_t * pLength)
{
*ppDataOut = pBufferList->pBuffers->pData;
*pLength = pBufferList->pBuffers->dataLenInBytes;
}
/* Name : icp_ocfDrvBufferListMemInfo
*
* Description : This function will set the number of flat buffers in
* bufferlist, the size of memory to allocate for the pPrivateMetaData
* member of the CpaBufferList.
*/
int
icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
struct icp_drvBuffListInfo *buffListInfo)
{
buffListInfo->numBuffers = numBuffers;
if (CPA_STATUS_SUCCESS !=
cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
buffListInfo->numBuffers,
&(buffListInfo->metaSize))) {
EPRINTK("%s() Failed to get buffer list meta size.\n",
__FUNCTION__);
return ICP_OCF_DRV_STATUS_FAIL;
}
return ICP_OCF_DRV_STATUS_SUCCESS;
}
/* Name : icp_ocfDrvGetSkBuffFrags
*
* Description : This function will determine the number of
* fragments in a socket buffer(sk_buff).
*/
inline uint16_t icp_ocfDrvGetSkBuffFrags(struct sk_buff * pSkb)
{
uint16_t numFrags = 0;
struct sk_buff *pCurFrag = NULL;
struct skb_shared_info *pShInfo = NULL;
if (NULL == pSkb)
return 0;
numFrags = 1;
if (0 == skb_is_nonlinear(pSkb)) {
/* Linear buffer - it's a single skbuff */
return numFrags;
}
pShInfo = skb_shinfo(pSkb);
if (NULL != pShInfo->frag_list && 0 != pShInfo->nr_frags) {
EPRINTK("%s(): Combination of frag_list "
"and frags[] array not supported!\n", __FUNCTION__);
return 0;
} else if (0 != pShInfo->nr_frags) {
numFrags += pShInfo->nr_frags;
return numFrags;
} else if (NULL != pShInfo->frag_list) {
for (pCurFrag = pShInfo->frag_list;
pCurFrag != NULL; pCurFrag = pCurFrag->next) {
numFrags++;
}
return numFrags;
} else {
return 0;
}
}
/* Name : icp_ocfDrvFreeFlatBuffer
*
* Description : This function will deallocate flat buffer.
*/
inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer)
{
if (pFlatBuffer != NULL) {
memset(pFlatBuffer, 0, sizeof(CpaFlatBuffer));
kmem_cache_free(drvFlatBuffer_zone, pFlatBuffer);
}
}
/* Name : icp_ocfDrvAllocMetaData
*
* Description : This function will allocate memory for the
* pPrivateMetaData member of CpaBufferList.
*/
inline int
icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
const struct icp_drvOpData *pOpData)
{
Cpa32U metaSize = 0;
if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS){
void *pOpDataStartAddr = (void *)pOpData;
if (0 == defBuffListInfo.metaSize) {
pBufferList->pPrivateMetaData = NULL;
return ICP_OCF_DRV_STATUS_SUCCESS;
}
/*
* The meta data allocation has been included as part of the
* op data. It has been pre-allocated in memory just after the
* icp_drvOpData structure.
*/
pBufferList->pPrivateMetaData = pOpDataStartAddr +
sizeof(struct icp_drvOpData);
} else {
if (CPA_STATUS_SUCCESS !=
cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
pBufferList->numBuffers,
&metaSize)) {
EPRINTK("%s() Failed to get buffer list meta size.\n",
__FUNCTION__);
return ICP_OCF_DRV_STATUS_FAIL;
}
if (0 == metaSize) {
pBufferList->pPrivateMetaData = NULL;
return ICP_OCF_DRV_STATUS_SUCCESS;
}
pBufferList->pPrivateMetaData = kmalloc(metaSize, GFP_ATOMIC);
}
if (NULL == pBufferList->pPrivateMetaData) {
EPRINTK("%s() Failed to allocate pPrivateMetaData.\n",
__FUNCTION__);
return ICP_OCF_DRV_STATUS_FAIL;
}
return ICP_OCF_DRV_STATUS_SUCCESS;
}
/* Name : icp_ocfDrvFreeMetaData
*
* Description : This function will deallocate pPrivateMetaData memory.
*/
inline void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList)
{
if (NULL == pBufferList->pPrivateMetaData) {
return;
}
/*
* Only free the meta data if the BufferList has more than
* ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS number of buffers.
* Otherwise, the meta data shall be freed when the icp_drvOpData is
* freed.
*/
if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers){
kfree(pBufferList->pPrivateMetaData);
}
}
module_init(icp_ocfDrvInit);
module_exit(icp_ocfDrvExit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Intel");
MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration");

View file

@ -0,0 +1,363 @@
/***************************************************************************
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.GPL.
*
* Contact Information:
* Intel Corporation
*
* BSD LICENSE
*
* Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* version: Security.L.1.0.130
*
***************************************************************************/
/*
* OCF drv driver header file for the Intel ICP processor.
*/
#ifndef ICP_OCF_H
#define ICP_OCF_H
#include <linux/crypto.h>
#include <linux/delay.h>
#include <linux/skbuff.h>
#include "cryptodev.h"
#include "uio.h"
#include "cpa.h"
#include "cpa_cy_im.h"
#include "cpa_cy_sym.h"
#include "cpa_cy_rand.h"
#include "cpa_cy_dh.h"
#include "cpa_cy_rsa.h"
#include "cpa_cy_ln.h"
#include "cpa_cy_common.h"
#include "cpa_cy_dsa.h"
#define NUM_BITS_IN_BYTE (8)
#define NUM_BITS_IN_BYTE_MINUS_ONE (NUM_BITS_IN_BYTE -1)
#define INVALID_DRIVER_ID (-1)
#define RETURN_RAND_NUM_GEN_FAILED (-1)
/*This is define means only one operation can be chained to another
(resulting in one chain of two operations)*/
#define MAX_NUM_OF_CHAINED_OPS (1)
/*This is the max block cipher initialisation vector*/
#define MAX_IV_LEN_IN_BYTES (20)
/*This is used to check whether the OCF to this driver session limit has
been disabled*/
#define NO_OCF_TO_DRV_MAX_SESSIONS (0)
/*OCF values mapped here*/
#define ICP_SHA1_DIGEST_SIZE_IN_BYTES (SHA1_HASH_LEN)
#define ICP_SHA256_DIGEST_SIZE_IN_BYTES (SHA2_256_HASH_LEN)
#define ICP_SHA384_DIGEST_SIZE_IN_BYTES (SHA2_384_HASH_LEN)
#define ICP_SHA512_DIGEST_SIZE_IN_BYTES (SHA2_512_HASH_LEN)
#define ICP_MD5_DIGEST_SIZE_IN_BYTES (MD5_HASH_LEN)
#define ARC4_COUNTER_LEN (ARC4_BLOCK_LEN)
#define OCF_REGISTRATION_STATUS_SUCCESS (0)
#define OCF_ZERO_FUNCTIONALITY_REGISTERED (0)
#define ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR (0)
#define ICP_OCF_DRV_STATUS_SUCCESS (0)
#define ICP_OCF_DRV_STATUS_FAIL (1)
/*Turn on/off debug options*/
#define ICP_OCF_PRINT_DEBUG_MESSAGES (0)
#define ICP_OCF_PRINT_KERN_ALERT (1)
#define ICP_OCF_PRINT_KERN_ERRS (1)
/*DSA Prime Q size in bytes (as defined in the standard) */
#define DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES (20)
/*MACRO DEFINITIONS*/
#define BITS_TO_BYTES(bytes, bits) \
bytes = (bits + NUM_BITS_IN_BYTE_MINUS_ONE) / NUM_BITS_IN_BYTE
#define ICP_CACHE_CREATE(cache_ID, cache_name) \
kmem_cache_create(cache_ID, sizeof(cache_name),0, \
SLAB_HWCACHE_ALIGN, NULL, NULL);
#define ICP_CACHE_NULL_CHECK(slab_zone) \
{ \
if(NULL == slab_zone){ \
icp_ocfDrvFreeCaches(); \
EPRINTK("%s() line %d: Not enough memory!\n", \
__FUNCTION__, __LINE__); \
return ENOMEM; \
} \
}
#define ICP_CACHE_DESTROY(slab_zone) \
{ \
if(NULL != slab_zone){ \
kmem_cache_destroy(slab_zone); \
slab_zone = NULL; \
} \
}
#define ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(alg) \
{ \
if(OCF_REGISTRATION_STATUS_SUCCESS == \
crypto_register(icp_ocfDrvDriverId, \
alg, \
0, \
0)) { \
ocfStatus++; \
} \
}
#define ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(alg) \
{ \
if(OCF_REGISTRATION_STATUS_SUCCESS == \
crypto_kregister(icp_ocfDrvDriverId, \
alg, \
0)){ \
ocfStatus++; \
} \
}
#if ICP_OCF_PRINT_DEBUG_MESSAGES == 1
#define DPRINTK(args...) \
{ \
printk(args); \
}
#else //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
#define DPRINTK(args...)
#endif //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
#if ICP_OCF_PRINT_KERN_ALERT == 1
#define APRINTK(args...) \
{ \
printk(KERN_ALERT args); \
}
#else //ICP_OCF_PRINT_KERN_ALERT == 1
#define APRINTK(args...)
#endif //ICP_OCF_PRINT_KERN_ALERT == 1
#if ICP_OCF_PRINT_KERN_ERRS == 1
#define EPRINTK(args...) \
{ \
printk(KERN_ERR args); \
}
#else //ICP_OCF_PRINT_KERN_ERRS == 1
#define EPRINTK(args...)
#endif //ICP_OCF_PRINT_KERN_ERRS == 1
#define IPRINTK(args...) \
{ \
printk(KERN_INFO args); \
}
/*END OF MACRO DEFINITIONS*/
typedef enum {
ICP_OCF_DRV_ALG_CIPHER = 0,
ICP_OCF_DRV_ALG_HASH
} icp_ocf_drv_alg_type_t;
/* These are all defined in icp_common.c */
extern atomic_t lac_session_failed_dereg_count;
extern atomic_t icp_ocfDrvIsExiting;
extern atomic_t num_ocf_to_drv_registered_sessions;
/*These are use inputs used in icp_sym.c and icp_common.c
They are instantiated in icp_common.c*/
extern int max_sessions;
extern int32_t icp_ocfDrvDriverId;
extern struct list_head icp_ocfDrvGlobalSymListHead;
extern struct list_head icp_ocfDrvGlobalSymListHead_FreeMemList;
extern struct workqueue_struct *icp_ocfDrvFreeLacSessionWorkQ;
extern spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
extern rwlock_t icp_kmem_cache_destroy_alloc_lock;
/*Slab zones for symettric functionality, instantiated in icp_common.c*/
extern struct kmem_cache *drvSessionData_zone;
extern struct kmem_cache *drvOpData_zone;
/*Slabs zones for asymettric functionality, instantiated in icp_common.c*/
extern struct kmem_cache *drvDH_zone;
extern struct kmem_cache *drvLnModExp_zone;
extern struct kmem_cache *drvRSADecrypt_zone;
extern struct kmem_cache *drvRSAPrivateKey_zone;
extern struct kmem_cache *drvDSARSSign_zone;
extern struct kmem_cache *drvDSARSSignKValue_zone;
extern struct kmem_cache *drvDSAVerify_zone;
/*Slab zones for flatbuffers and bufferlist*/
extern struct kmem_cache *drvFlatBuffer_zone;
#define ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS (16)
struct icp_drvBuffListInfo {
Cpa16U numBuffers;
Cpa32U metaSize;
Cpa32U metaOffset;
Cpa32U buffListSize;
};
extern struct icp_drvBuffListInfo defBuffListInfo;
/*
* This struct is used to keep a reference to the relevant node in the list
* of sessionData structs, to the buffer type required by OCF and to the OCF
* provided crp struct that needs to be returned. All this info is needed in
* the callback function.
*
* IV can sometimes be stored in non-contiguous memory (e.g. skbuff
* linked/frag list, therefore a contiguous memory space for the IV data must be
* created and passed to LAC
*
*/
struct icp_drvOpData {
CpaCySymOpData lacOpData;
uint32_t digestSizeInBytes;
struct cryptop *crp;
uint8_t bufferType;
uint8_t ivData[MAX_IV_LEN_IN_BYTES];
uint16_t numBufferListArray;
CpaBufferList srcBuffer;
CpaFlatBuffer bufferListArray[ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS];
CpaBoolean verifyResult;
};
/*Values used to derisk chances of performs being called against
deregistered sessions (for which the slab page has been reclaimed)
This is not a fix - since page frames are reclaimed from a slab, one cannot
rely on that memory not being re-used by another app.*/
typedef enum {
ICP_SESSION_INITIALISED = 0x5C5C5C,
ICP_SESSION_RUNNING = 0x005C00,
ICP_SESSION_DEREGISTERED = 0xC5C5C5
} usage_derisk;
/*
This is the OCF<->OCF_DRV session object:
1.The first member is a listNode. These session objects are added to a linked
list in order to make it easier to remove them all at session exit time.
2.The second member is used to give the session object state and derisk the
possibility of OCF batch calls executing against a deregistered session (as
described above).
3.The third member is a LAC<->OCF_DRV session handle (initialised with the first
perform request for that session).
4.The fourth is the LAC session context. All the parameters for this structure
are only known when the first perform request for this session occurs. That is
why the OCF Tolapai Driver only registers a new LAC session at perform time
*/
struct icp_drvSessionData {
struct list_head listNode;
usage_derisk inUse;
CpaCySymSessionCtx sessHandle;
CpaCySymSessionSetupData lacSessCtx;
};
/* This struct is required for deferred session
deregistration as a work queue function can
only have one argument*/
struct icp_ocfDrvFreeLacSession {
CpaCySymSessionCtx sessionToDeregister;
struct work_struct work;
};
int icp_ocfDrvNewSession(device_t dev, uint32_t * sild, struct cryptoini *cri);
int icp_ocfDrvFreeLACSession(device_t dev, uint64_t sid);
int icp_ocfDrvSymProcess(device_t dev, struct cryptop *crp, int hint);
int icp_ocfDrvPkeProcess(device_t dev, struct cryptkop *krp, int hint);
int icp_ocfDrvReadRandom(void *arg, uint32_t * buf, int maxwords);
int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister);
int icp_ocfDrvSkBuffToBufferList(struct sk_buff *skb,
CpaBufferList * bufferList);
int icp_ocfDrvBufferListToSkBuff(CpaBufferList * bufferList,
struct sk_buff **skb);
void icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
CpaFlatBuffer * pFlatBuffer);
void icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
CpaBufferList * pBufferList);
void icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
void **ppDataOut, uint32_t * pLength);
int icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
struct icp_drvBuffListInfo *buffListInfo);
uint16_t icp_ocfDrvGetSkBuffFrags(struct sk_buff *pSkb);
void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer);
int icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
const struct icp_drvOpData *pOpData);
void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList);
#endif
/* ICP_OCF_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,69 @@
###################
# @par
# This file is provided under a dual BSD/GPLv2 license. When using or
# redistributing this file, you may do so under either license.
#
# GPL LICENSE SUMMARY
#
# Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
# The full GNU General Public License is included in this distribution
# in the file called LICENSE.GPL.
#
# Contact Information:
# Intel Corporation
#
# BSD LICENSE
#
# Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
# version: Security.L.1.0.130
###################
#specific include directories in kernel space
INCLUDES+=#e.g. -I$(OSAL_DIR)/include \
#Extra Flags Specific in kernel space e.g. include path or debug flags etc. e.g to add an include path EXTRA_CFLAGS += -I$(src)/../include
EXTRA_CFLAGS += $(INCLUDES) -O2 -Wall
EXTRA_LDFLAGS +=-whole-archive

View file

@ -0,0 +1,13 @@
# for SGlinux builds
-include $(ROOTDIR)/modules/.config
obj-$(CONFIG_OCF_HIFN) += hifn7751.o
obj-$(CONFIG_OCF_HIFNHIPP) += hifnHIPP.o
obj ?= .
EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
ifdef TOPDIR
-include $(TOPDIR)/Rules.make
endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,540 @@
/* $FreeBSD: src/sys/dev/hifn/hifn7751reg.h,v 1.7 2007/03/21 03:42:49 sam Exp $ */
/* $OpenBSD: hifn7751reg.h,v 1.35 2002/04/08 17:49:42 jason Exp $ */
/*-
* Invertex AEON / Hifn 7751 driver
* Copyright (c) 1999 Invertex Inc. All rights reserved.
* Copyright (c) 1999 Theo de Raadt
* Copyright (c) 2000-2001 Network Security Technologies, Inc.
* http://www.netsec.net
*
* Please send any comments, feedback, bug-fixes, or feature requests to
* software@invertex.com.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Effort sponsored in part by the Defense Advanced Research Projects
* Agency (DARPA) and Air Force Research Laboratory, Air Force
* Materiel Command, USAF, under agreement number F30602-01-2-0537.
*
*/
#ifndef __HIFN_H__
#define __HIFN_H__
/*
* Some PCI configuration space offset defines. The names were made
* identical to the names used by the Linux kernel.
*/
#define HIFN_BAR0 PCIR_BAR(0) /* PUC register map */
#define HIFN_BAR1 PCIR_BAR(1) /* DMA register map */
#define HIFN_TRDY_TIMEOUT 0x40
#define HIFN_RETRY_TIMEOUT 0x41
/*
* PCI vendor and device identifiers
* (the names are preserved from their OpenBSD source).
*/
#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
#define PCI_PRODUCT_HIFN_7751 0x0005 /* 7751 */
#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
#define PCI_PRODUCT_HIFN_7811 0x0007 /* 7811 */
#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
#define PCI_PRODUCT_HIFN_7951 0x0012 /* 7951 */
#define PCI_PRODUCT_HIFN_7955 0x0020 /* 7954/7955 */
#define PCI_PRODUCT_HIFN_7956 0x001d /* 7956 */
#define PCI_VENDOR_INVERTEX 0x14e1 /* Invertex */
#define PCI_PRODUCT_INVERTEX_AEON 0x0005 /* AEON */
#define PCI_VENDOR_NETSEC 0x1660 /* NetSec */
#define PCI_PRODUCT_NETSEC_7751 0x7751 /* 7751 */
/*
* The values below should multiple of 4 -- and be large enough to handle
* any command the driver implements.
*
* MAX_COMMAND = base command + mac command + encrypt command +
* mac-key + rc4-key
* MAX_RESULT = base result + mac result + mac + encrypt result
*
*
*/
#define HIFN_MAX_COMMAND (8 + 8 + 8 + 64 + 260)
#define HIFN_MAX_RESULT (8 + 4 + 20 + 4)
/*
* hifn_desc_t
*
* Holds an individual descriptor for any of the rings.
*/
typedef struct hifn_desc {
volatile u_int32_t l; /* length and status bits */
volatile u_int32_t p;
} hifn_desc_t;
/*
* Masks for the "length" field of struct hifn_desc.
*/
#define HIFN_D_LENGTH 0x0000ffff /* length bit mask */
#define HIFN_D_MASKDONEIRQ 0x02000000 /* mask the done interrupt */
#define HIFN_D_DESTOVER 0x04000000 /* destination overflow */
#define HIFN_D_OVER 0x08000000 /* overflow */
#define HIFN_D_LAST 0x20000000 /* last descriptor in chain */
#define HIFN_D_JUMP 0x40000000 /* jump descriptor */
#define HIFN_D_VALID 0x80000000 /* valid bit */
/*
* Processing Unit Registers (offset from BASEREG0)
*/
#define HIFN_0_PUDATA 0x00 /* Processing Unit Data */
#define HIFN_0_PUCTRL 0x04 /* Processing Unit Control */
#define HIFN_0_PUISR 0x08 /* Processing Unit Interrupt Status */
#define HIFN_0_PUCNFG 0x0c /* Processing Unit Configuration */
#define HIFN_0_PUIER 0x10 /* Processing Unit Interrupt Enable */
#define HIFN_0_PUSTAT 0x14 /* Processing Unit Status/Chip ID */
#define HIFN_0_FIFOSTAT 0x18 /* FIFO Status */
#define HIFN_0_FIFOCNFG 0x1c /* FIFO Configuration */
#define HIFN_0_PUCTRL2 0x28 /* Processing Unit Control (2nd map) */
#define HIFN_0_MUTE1 0x80
#define HIFN_0_MUTE2 0x90
#define HIFN_0_SPACESIZE 0x100 /* Register space size */
/* Processing Unit Control Register (HIFN_0_PUCTRL) */
#define HIFN_PUCTRL_CLRSRCFIFO 0x0010 /* clear source fifo */
#define HIFN_PUCTRL_STOP 0x0008 /* stop pu */
#define HIFN_PUCTRL_LOCKRAM 0x0004 /* lock ram */
#define HIFN_PUCTRL_DMAENA 0x0002 /* enable dma */
#define HIFN_PUCTRL_RESET 0x0001 /* Reset processing unit */
/* Processing Unit Interrupt Status Register (HIFN_0_PUISR) */
#define HIFN_PUISR_CMDINVAL 0x8000 /* Invalid command interrupt */
#define HIFN_PUISR_DATAERR 0x4000 /* Data error interrupt */
#define HIFN_PUISR_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
#define HIFN_PUISR_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
#define HIFN_PUISR_DSTOVER 0x0200 /* Destination overrun interrupt */
#define HIFN_PUISR_SRCCMD 0x0080 /* Source command interrupt */
#define HIFN_PUISR_SRCCTX 0x0040 /* Source context interrupt */
#define HIFN_PUISR_SRCDATA 0x0020 /* Source data interrupt */
#define HIFN_PUISR_DSTDATA 0x0010 /* Destination data interrupt */
#define HIFN_PUISR_DSTRESULT 0x0004 /* Destination result interrupt */
/* Processing Unit Configuration Register (HIFN_0_PUCNFG) */
#define HIFN_PUCNFG_DRAMMASK 0xe000 /* DRAM size mask */
#define HIFN_PUCNFG_DSZ_256K 0x0000 /* 256k dram */
#define HIFN_PUCNFG_DSZ_512K 0x2000 /* 512k dram */
#define HIFN_PUCNFG_DSZ_1M 0x4000 /* 1m dram */
#define HIFN_PUCNFG_DSZ_2M 0x6000 /* 2m dram */
#define HIFN_PUCNFG_DSZ_4M 0x8000 /* 4m dram */
#define HIFN_PUCNFG_DSZ_8M 0xa000 /* 8m dram */
#define HIFN_PUNCFG_DSZ_16M 0xc000 /* 16m dram */
#define HIFN_PUCNFG_DSZ_32M 0xe000 /* 32m dram */
#define HIFN_PUCNFG_DRAMREFRESH 0x1800 /* DRAM refresh rate mask */
#define HIFN_PUCNFG_DRFR_512 0x0000 /* 512 divisor of ECLK */
#define HIFN_PUCNFG_DRFR_256 0x0800 /* 256 divisor of ECLK */
#define HIFN_PUCNFG_DRFR_128 0x1000 /* 128 divisor of ECLK */
#define HIFN_PUCNFG_TCALLPHASES 0x0200 /* your guess is as good as mine... */
#define HIFN_PUCNFG_TCDRVTOTEM 0x0100 /* your guess is as good as mine... */
#define HIFN_PUCNFG_BIGENDIAN 0x0080 /* DMA big endian mode */
#define HIFN_PUCNFG_BUS32 0x0040 /* Bus width 32bits */
#define HIFN_PUCNFG_BUS16 0x0000 /* Bus width 16 bits */
#define HIFN_PUCNFG_CHIPID 0x0020 /* Allow chipid from PUSTAT */
#define HIFN_PUCNFG_DRAM 0x0010 /* Context RAM is DRAM */
#define HIFN_PUCNFG_SRAM 0x0000 /* Context RAM is SRAM */
#define HIFN_PUCNFG_COMPSING 0x0004 /* Enable single compression context */
#define HIFN_PUCNFG_ENCCNFG 0x0002 /* Encryption configuration */
/* Processing Unit Interrupt Enable Register (HIFN_0_PUIER) */
#define HIFN_PUIER_CMDINVAL 0x8000 /* Invalid command interrupt */
#define HIFN_PUIER_DATAERR 0x4000 /* Data error interrupt */
#define HIFN_PUIER_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
#define HIFN_PUIER_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
#define HIFN_PUIER_DSTOVER 0x0200 /* Destination overrun interrupt */
#define HIFN_PUIER_SRCCMD 0x0080 /* Source command interrupt */
#define HIFN_PUIER_SRCCTX 0x0040 /* Source context interrupt */
#define HIFN_PUIER_SRCDATA 0x0020 /* Source data interrupt */
#define HIFN_PUIER_DSTDATA 0x0010 /* Destination data interrupt */
#define HIFN_PUIER_DSTRESULT 0x0004 /* Destination result interrupt */
/* Processing Unit Status Register/Chip ID (HIFN_0_PUSTAT) */
#define HIFN_PUSTAT_CMDINVAL 0x8000 /* Invalid command interrupt */
#define HIFN_PUSTAT_DATAERR 0x4000 /* Data error interrupt */
#define HIFN_PUSTAT_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
#define HIFN_PUSTAT_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
#define HIFN_PUSTAT_DSTOVER 0x0200 /* Destination overrun interrupt */
#define HIFN_PUSTAT_SRCCMD 0x0080 /* Source command interrupt */
#define HIFN_PUSTAT_SRCCTX 0x0040 /* Source context interrupt */
#define HIFN_PUSTAT_SRCDATA 0x0020 /* Source data interrupt */
#define HIFN_PUSTAT_DSTDATA 0x0010 /* Destination data interrupt */
#define HIFN_PUSTAT_DSTRESULT 0x0004 /* Destination result interrupt */
#define HIFN_PUSTAT_CHIPREV 0x00ff /* Chip revision mask */
#define HIFN_PUSTAT_CHIPENA 0xff00 /* Chip enabled mask */
#define HIFN_PUSTAT_ENA_2 0x1100 /* Level 2 enabled */
#define HIFN_PUSTAT_ENA_1 0x1000 /* Level 1 enabled */
#define HIFN_PUSTAT_ENA_0 0x3000 /* Level 0 enabled */
#define HIFN_PUSTAT_REV_2 0x0020 /* 7751 PT6/2 */
#define HIFN_PUSTAT_REV_3 0x0030 /* 7751 PT6/3 */
/* FIFO Status Register (HIFN_0_FIFOSTAT) */
#define HIFN_FIFOSTAT_SRC 0x7f00 /* Source FIFO available */
#define HIFN_FIFOSTAT_DST 0x007f /* Destination FIFO available */
/* FIFO Configuration Register (HIFN_0_FIFOCNFG) */
#define HIFN_FIFOCNFG_THRESHOLD 0x0400 /* must be written as this value */
/*
* DMA Interface Registers (offset from BASEREG1)
*/
#define HIFN_1_DMA_CRAR 0x0c /* DMA Command Ring Address */
#define HIFN_1_DMA_SRAR 0x1c /* DMA Source Ring Address */
#define HIFN_1_DMA_RRAR 0x2c /* DMA Result Ring Address */
#define HIFN_1_DMA_DRAR 0x3c /* DMA Destination Ring Address */
#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 /* 7955/7956: 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 */
#define HIFN_1_7811_RNGSTS 0x6c /* 7811: rng status */
#define HIFN_1_DMA_CNFG2 0x6c /* 7955/7956: dma config #2 */
#define HIFN_1_7811_MIPSRST 0x94 /* 7811: MIPS reset */
#define HIFN_1_REVID 0x98 /* Revision ID */
#define HIFN_1_PUB_RESET 0x204 /* Public/RNG Reset */
#define HIFN_1_PUB_BASE 0x300 /* Public Base Address */
#define HIFN_1_PUB_OPLEN 0x304 /* 7951-compat Public Operand Length */
#define HIFN_1_PUB_OP 0x308 /* 7951-compat Public Operand */
#define HIFN_1_PUB_STATUS 0x30c /* 7951-compat Public Status */
#define HIFN_1_PUB_IEN 0x310 /* Public Interrupt enable */
#define HIFN_1_RNG_CONFIG 0x314 /* RNG config */
#define HIFN_1_RNG_DATA 0x318 /* RNG data */
#define HIFN_1_PUB_MODE 0x320 /* PK mode */
#define HIFN_1_PUB_FIFO_OPLEN 0x380 /* first element of oplen fifo */
#define HIFN_1_PUB_FIFO_OP 0x384 /* first element of op fifo */
#define HIFN_1_PUB_MEM 0x400 /* start of Public key memory */
#define HIFN_1_PUB_MEMEND 0xbff /* end of Public key memory */
/* DMA Status and Control Register (HIFN_1_DMA_CSR) */
#define HIFN_DMACSR_D_CTRLMASK 0xc0000000 /* Destinition Ring Control */
#define HIFN_DMACSR_D_CTRL_NOP 0x00000000 /* Dest. Control: no-op */
#define HIFN_DMACSR_D_CTRL_DIS 0x40000000 /* Dest. Control: disable */
#define HIFN_DMACSR_D_CTRL_ENA 0x80000000 /* Dest. Control: enable */
#define HIFN_DMACSR_D_ABORT 0x20000000 /* Destinition Ring PCIAbort */
#define HIFN_DMACSR_D_DONE 0x10000000 /* Destinition Ring Done */
#define HIFN_DMACSR_D_LAST 0x08000000 /* Destinition Ring Last */
#define HIFN_DMACSR_D_WAIT 0x04000000 /* Destinition Ring Waiting */
#define HIFN_DMACSR_D_OVER 0x02000000 /* Destinition Ring Overflow */
#define HIFN_DMACSR_R_CTRL 0x00c00000 /* Result Ring Control */
#define HIFN_DMACSR_R_CTRL_NOP 0x00000000 /* Result Control: no-op */
#define HIFN_DMACSR_R_CTRL_DIS 0x00400000 /* Result Control: disable */
#define HIFN_DMACSR_R_CTRL_ENA 0x00800000 /* Result Control: enable */
#define HIFN_DMACSR_R_ABORT 0x00200000 /* Result Ring PCI Abort */
#define HIFN_DMACSR_R_DONE 0x00100000 /* Result Ring Done */
#define HIFN_DMACSR_R_LAST 0x00080000 /* Result Ring Last */
#define HIFN_DMACSR_R_WAIT 0x00040000 /* Result Ring Waiting */
#define HIFN_DMACSR_R_OVER 0x00020000 /* Result Ring Overflow */
#define HIFN_DMACSR_S_CTRL 0x0000c000 /* Source Ring Control */
#define HIFN_DMACSR_S_CTRL_NOP 0x00000000 /* Source Control: no-op */
#define HIFN_DMACSR_S_CTRL_DIS 0x00004000 /* Source Control: disable */
#define HIFN_DMACSR_S_CTRL_ENA 0x00008000 /* Source Control: enable */
#define HIFN_DMACSR_S_ABORT 0x00002000 /* Source Ring PCI Abort */
#define HIFN_DMACSR_S_DONE 0x00001000 /* Source Ring Done */
#define HIFN_DMACSR_S_LAST 0x00000800 /* Source Ring Last */
#define HIFN_DMACSR_S_WAIT 0x00000400 /* Source Ring Waiting */
#define HIFN_DMACSR_ILLW 0x00000200 /* Illegal write (7811 only) */
#define HIFN_DMACSR_ILLR 0x00000100 /* Illegal read (7811 only) */
#define HIFN_DMACSR_C_CTRL 0x000000c0 /* Command Ring Control */
#define HIFN_DMACSR_C_CTRL_NOP 0x00000000 /* Command Control: no-op */
#define HIFN_DMACSR_C_CTRL_DIS 0x00000040 /* Command Control: disable */
#define HIFN_DMACSR_C_CTRL_ENA 0x00000080 /* Command Control: enable */
#define HIFN_DMACSR_C_ABORT 0x00000020 /* Command Ring PCI Abort */
#define HIFN_DMACSR_C_DONE 0x00000010 /* Command Ring Done */
#define HIFN_DMACSR_C_LAST 0x00000008 /* Command Ring Last */
#define HIFN_DMACSR_C_WAIT 0x00000004 /* Command Ring Waiting */
#define HIFN_DMACSR_PUBDONE 0x00000002 /* Public op done (7951 only) */
#define HIFN_DMACSR_ENGINE 0x00000001 /* Command Ring Engine IRQ */
/* DMA Interrupt Enable Register (HIFN_1_DMA_IER) */
#define HIFN_DMAIER_D_ABORT 0x20000000 /* Destination Ring PCIAbort */
#define HIFN_DMAIER_D_DONE 0x10000000 /* Destination Ring Done */
#define HIFN_DMAIER_D_LAST 0x08000000 /* Destination Ring Last */
#define HIFN_DMAIER_D_WAIT 0x04000000 /* Destination Ring Waiting */
#define HIFN_DMAIER_D_OVER 0x02000000 /* Destination Ring Overflow */
#define HIFN_DMAIER_R_ABORT 0x00200000 /* Result Ring PCI Abort */
#define HIFN_DMAIER_R_DONE 0x00100000 /* Result Ring Done */
#define HIFN_DMAIER_R_LAST 0x00080000 /* Result Ring Last */
#define HIFN_DMAIER_R_WAIT 0x00040000 /* Result Ring Waiting */
#define HIFN_DMAIER_R_OVER 0x00020000 /* Result Ring Overflow */
#define HIFN_DMAIER_S_ABORT 0x00002000 /* Source Ring PCI Abort */
#define HIFN_DMAIER_S_DONE 0x00001000 /* Source Ring Done */
#define HIFN_DMAIER_S_LAST 0x00000800 /* Source Ring Last */
#define HIFN_DMAIER_S_WAIT 0x00000400 /* Source Ring Waiting */
#define HIFN_DMAIER_ILLW 0x00000200 /* Illegal write (7811 only) */
#define HIFN_DMAIER_ILLR 0x00000100 /* Illegal read (7811 only) */
#define HIFN_DMAIER_C_ABORT 0x00000020 /* Command Ring PCI Abort */
#define HIFN_DMAIER_C_DONE 0x00000010 /* Command Ring Done */
#define HIFN_DMAIER_C_LAST 0x00000008 /* Command Ring Last */
#define HIFN_DMAIER_C_WAIT 0x00000004 /* Command Ring Waiting */
#define HIFN_DMAIER_PUBDONE 0x00000002 /* public op done (7951 only) */
#define HIFN_DMAIER_ENGINE 0x00000001 /* Engine IRQ */
/* DMA Configuration Register (HIFN_1_DMA_CNFG) */
#define HIFN_DMACNFG_BIGENDIAN 0x10000000 /* big endian mode */
#define HIFN_DMACNFG_POLLFREQ 0x00ff0000 /* Poll frequency mask */
#define HIFN_DMACNFG_UNLOCK 0x00000800
#define HIFN_DMACNFG_POLLINVAL 0x00000700 /* Invalid Poll Scalar */
#define HIFN_DMACNFG_LAST 0x00000010 /* Host control LAST bit */
#define HIFN_DMACNFG_MODE 0x00000004 /* DMA mode */
#define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */
#define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */
/* DMA Configuration Register (HIFN_1_DMA_CNFG2) */
#define HIFN_DMACNFG2_PKSWAP32 (1 << 19) /* swap the OPLEN/OP reg */
#define HIFN_DMACNFG2_PKSWAP8 (1 << 18) /* swap the bits of OPLEN/OP */
#define HIFN_DMACNFG2_BAR0_SWAP32 (1<<17) /* swap the bytes of BAR0 */
#define HIFN_DMACNFG2_BAR1_SWAP8 (1<<16) /* swap the bits of BAR0 */
#define HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT 12
#define HIFN_DMACNFG2_INIT_READ_BURST_SHIFT 8
#define HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT 4
#define HIFN_DMACNFG2_TGT_READ_BURST_SHIFT 0
/* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */
#define HIFN_7811_RNGENA_ENA 0x00000001 /* enable RNG */
/* 7811 RNG Config Register (HIFN_1_7811_RNGCFG) */
#define HIFN_7811_RNGCFG_PRE1 0x00000f00 /* first prescalar */
#define HIFN_7811_RNGCFG_OPRE 0x00000080 /* output prescalar */
#define HIFN_7811_RNGCFG_DEFL 0x00000f80 /* 2 words/ 1/100 sec */
/* 7811 RNG Status Register (HIFN_1_7811_RNGSTS) */
#define HIFN_7811_RNGSTS_RDY 0x00004000 /* two numbers in FIFO */
#define HIFN_7811_RNGSTS_UFL 0x00001000 /* rng underflow */
/* 7811 MIPS Reset Register (HIFN_1_7811_MIPSRST) */
#define HIFN_MIPSRST_BAR2SIZE 0xffff0000 /* sdram size */
#define HIFN_MIPSRST_GPRAMINIT 0x00008000 /* gpram can be accessed */
#define HIFN_MIPSRST_CRAMINIT 0x00004000 /* ctxram can be accessed */
#define HIFN_MIPSRST_LED2 0x00000400 /* external LED2 */
#define HIFN_MIPSRST_LED1 0x00000200 /* external LED1 */
#define HIFN_MIPSRST_LED0 0x00000100 /* external LED0 */
#define HIFN_MIPSRST_MIPSDIS 0x00000004 /* disable MIPS */
#define HIFN_MIPSRST_MIPSRST 0x00000002 /* warm reset MIPS */
#define HIFN_MIPSRST_MIPSCOLD 0x00000001 /* cold reset MIPS */
/* Public key reset register (HIFN_1_PUB_RESET) */
#define HIFN_PUBRST_RESET 0x00000001 /* reset public/rng unit */
/* Public operation register (HIFN_1_PUB_OP) */
#define HIFN_PUBOP_AOFFSET 0x0000003e /* A offset */
#define HIFN_PUBOP_BOFFSET 0x00000fc0 /* B offset */
#define HIFN_PUBOP_MOFFSET 0x0003f000 /* M offset */
#define HIFN_PUBOP_OP_MASK 0x003c0000 /* Opcode: */
#define HIFN_PUBOP_OP_NOP 0x00000000 /* NOP */
#define HIFN_PUBOP_OP_ADD 0x00040000 /* ADD */
#define HIFN_PUBOP_OP_ADDC 0x00080000 /* ADD w/carry */
#define HIFN_PUBOP_OP_SUB 0x000c0000 /* SUB */
#define HIFN_PUBOP_OP_SUBC 0x00100000 /* SUB w/carry */
#define HIFN_PUBOP_OP_MODADD 0x00140000 /* Modular ADD */
#define HIFN_PUBOP_OP_MODSUB 0x00180000 /* Modular SUB */
#define HIFN_PUBOP_OP_INCA 0x001c0000 /* INC A */
#define HIFN_PUBOP_OP_DECA 0x00200000 /* DEC A */
#define HIFN_PUBOP_OP_MULT 0x00240000 /* MULT */
#define HIFN_PUBOP_OP_MODMULT 0x00280000 /* Modular MULT */
#define HIFN_PUBOP_OP_MODRED 0x002c0000 /* Modular Red */
#define HIFN_PUBOP_OP_MODEXP 0x00300000 /* Modular Exp */
/* Public operand length register (HIFN_1_PUB_OPLEN) */
#define HIFN_PUBOPLEN_MODLEN 0x0000007f
#define HIFN_PUBOPLEN_EXPLEN 0x0003ff80
#define HIFN_PUBOPLEN_REDLEN 0x003c0000
/* Public status register (HIFN_1_PUB_STATUS) */
#define HIFN_PUBSTS_DONE 0x00000001 /* operation done */
#define HIFN_PUBSTS_CARRY 0x00000002 /* carry */
#define HIFN_PUBSTS_FIFO_EMPTY 0x00000100 /* fifo empty */
#define HIFN_PUBSTS_FIFO_FULL 0x00000200 /* fifo full */
#define HIFN_PUBSTS_FIFO_OVFL 0x00000400 /* fifo overflow */
#define HIFN_PUBSTS_FIFO_WRITE 0x000f0000 /* fifo write */
#define HIFN_PUBSTS_FIFO_READ 0x0f000000 /* fifo read */
/* Public interrupt enable register (HIFN_1_PUB_IEN) */
#define HIFN_PUBIEN_DONE 0x00000001 /* operation done interrupt */
/* Random number generator config register (HIFN_1_RNG_CONFIG) */
#define HIFN_RNGCFG_ENA 0x00000001 /* enable rng */
/*
* Register offsets in register set 1
*/
#define HIFN_UNLOCK_SECRET1 0xf4
#define HIFN_UNLOCK_SECRET2 0xfc
/*
* PLL config register
*
* This register is present only on 7954/7955/7956 parts. It must be
* programmed according to the bus interface method used by the h/w.
* Note that the parts require a stable clock. Since the PCI clock
* may vary the reference clock must usually be used. To avoid
* overclocking the core logic, setup must be done carefully, refer
* to the driver for details. The exact multiplier required varies
* by part and system configuration; refer to the Hifn documentation.
*/
#define HIFN_PLL_REF_SEL 0x00000001 /* REF/HBI clk selection */
#define HIFN_PLL_BP 0x00000002 /* bypass (used during setup) */
/* bit 2 reserved */
#define HIFN_PLL_PK_CLK_SEL 0x00000008 /* public key clk select */
#define HIFN_PLL_PE_CLK_SEL 0x00000010 /* packet engine clk select */
/* bits 5-9 reserved */
#define HIFN_PLL_MBSET 0x00000400 /* must be set to 1 */
#define HIFN_PLL_ND 0x00003800 /* Fpll_ref multiplier select */
#define HIFN_PLL_ND_SHIFT 11
#define HIFN_PLL_ND_2 0x00000000 /* 2x */
#define HIFN_PLL_ND_4 0x00000800 /* 4x */
#define HIFN_PLL_ND_6 0x00001000 /* 6x */
#define HIFN_PLL_ND_8 0x00001800 /* 8x */
#define HIFN_PLL_ND_10 0x00002000 /* 10x */
#define HIFN_PLL_ND_12 0x00002800 /* 12x */
/* bits 14-15 reserved */
#define HIFN_PLL_IS 0x00010000 /* charge pump current select */
/* bits 17-31 reserved */
/*
* Board configuration specifies only these bits.
*/
#define HIFN_PLL_CONFIG (HIFN_PLL_IS|HIFN_PLL_ND|HIFN_PLL_REF_SEL)
/*
* Public Key Engine Mode Register
*/
#define HIFN_PKMODE_HOSTINVERT (1 << 0) /* HOST INVERT */
#define HIFN_PKMODE_ENHANCED (1 << 1) /* Enable enhanced mode */
/*********************************************************************
* Structs for board commands
*
*********************************************************************/
/*
* Structure to help build up the command data structure.
*/
typedef struct hifn_base_command {
volatile u_int16_t masks;
volatile u_int16_t session_num;
volatile u_int16_t total_source_count;
volatile u_int16_t total_dest_count;
} hifn_base_command_t;
#define HIFN_BASE_CMD_MAC 0x0400
#define HIFN_BASE_CMD_CRYPT 0x0800
#define HIFN_BASE_CMD_DECODE 0x2000
#define HIFN_BASE_CMD_SRCLEN_M 0xc000
#define HIFN_BASE_CMD_SRCLEN_S 14
#define HIFN_BASE_CMD_DSTLEN_M 0x3000
#define HIFN_BASE_CMD_DSTLEN_S 12
#define HIFN_BASE_CMD_LENMASK_HI 0x30000
#define HIFN_BASE_CMD_LENMASK_LO 0x0ffff
/*
* Structure to help build up the command data structure.
*/
typedef struct hifn_crypt_command {
volatile u_int16_t masks;
volatile u_int16_t header_skip;
volatile u_int16_t source_count;
volatile u_int16_t reserved;
} hifn_crypt_command_t;
#define HIFN_CRYPT_CMD_ALG_MASK 0x0003 /* algorithm: */
#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_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_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
#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 */
/*
* Structure to help build up the command data structure.
*/
typedef struct hifn_mac_command {
volatile u_int16_t masks;
volatile u_int16_t header_skip;
volatile u_int16_t source_count;
volatile u_int16_t reserved;
} hifn_mac_command_t;
#define HIFN_MAC_CMD_ALG_MASK 0x0001
#define HIFN_MAC_CMD_ALG_SHA1 0x0000
#define HIFN_MAC_CMD_ALG_MD5 0x0001
#define HIFN_MAC_CMD_MODE_MASK 0x000c
#define HIFN_MAC_CMD_MODE_HMAC 0x0000
#define HIFN_MAC_CMD_MODE_SSL_MAC 0x0004
#define HIFN_MAC_CMD_MODE_HASH 0x0008
#define HIFN_MAC_CMD_MODE_FULL 0x0004
#define HIFN_MAC_CMD_TRUNC 0x0010
#define HIFN_MAC_CMD_RESULT 0x0020
#define HIFN_MAC_CMD_APPEND 0x0040
#define HIFN_MAC_CMD_SRCLEN_M 0xc000
#define HIFN_MAC_CMD_SRCLEN_S 14
/*
* MAC POS IPsec initiates authentication after encryption on encodes
* and before decryption on decodes.
*/
#define HIFN_MAC_CMD_POS_IPSEC 0x0200
#define HIFN_MAC_CMD_NEW_KEY 0x0800
/*
* The poll frequency and poll scalar defines are unshifted values used
* to set fields in the DMA Configuration Register.
*/
#ifndef HIFN_POLL_FREQUENCY
#define HIFN_POLL_FREQUENCY 0x1
#endif
#ifndef HIFN_POLL_SCALAR
#define HIFN_POLL_SCALAR 0x0
#endif
#define HIFN_MAX_SEGLEN 0xffff /* maximum dma segment len */
#define HIFN_MAX_DMALEN 0x3ffff /* maximum dma length */
#endif /* __HIFN_H__ */

View file

@ -0,0 +1,369 @@
/* $FreeBSD: src/sys/dev/hifn/hifn7751var.h,v 1.9 2007/03/21 03:42:49 sam Exp $ */
/* $OpenBSD: hifn7751var.h,v 1.42 2002/04/08 17:49:42 jason Exp $ */
/*-
* Invertex AEON / Hifn 7751 driver
* Copyright (c) 1999 Invertex Inc. All rights reserved.
* Copyright (c) 1999 Theo de Raadt
* Copyright (c) 2000-2001 Network Security Technologies, Inc.
* http://www.netsec.net
*
* Please send any comments, feedback, bug-fixes, or feature requests to
* software@invertex.com.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Effort sponsored in part by the Defense Advanced Research Projects
* Agency (DARPA) and Air Force Research Laboratory, Air Force
* Materiel Command, USAF, under agreement number F30602-01-2-0537.
*
*/
#ifndef __HIFN7751VAR_H__
#define __HIFN7751VAR_H__
#ifdef __KERNEL__
/*
* Some configurable values for the driver. By default command+result
* descriptor rings are the same size. The src+dst descriptor rings
* are sized at 3.5x the number of potential commands. Slower parts
* (e.g. 7951) tend to run out of src descriptors; faster parts (7811)
* src+cmd/result descriptors. It's not clear that increasing the size
* of the descriptor rings helps performance significantly as other
* factors tend to come into play (e.g. copying misaligned packets).
*/
#define HIFN_D_CMD_RSIZE 24 /* command descriptors */
#define HIFN_D_SRC_RSIZE ((HIFN_D_CMD_RSIZE * 7) / 2) /* source descriptors */
#define HIFN_D_RES_RSIZE HIFN_D_CMD_RSIZE /* result descriptors */
#define HIFN_D_DST_RSIZE HIFN_D_SRC_RSIZE /* destination descriptors */
/*
* Length values for cryptography
*/
#define HIFN_DES_KEY_LENGTH 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
*/
#define HIFN_MAC_KEY_LENGTH 64
#define HIFN_MD5_LENGTH 16
#define HIFN_SHA1_LENGTH 20
#define HIFN_MAC_TRUNC_LENGTH 12
#define MAX_SCATTER 64
/*
* Data structure to hold all 4 rings and any other ring related data.
*/
struct hifn_dma {
/*
* Descriptor rings. We add +1 to the size to accomidate the
* jump descriptor.
*/
struct hifn_desc cmdr[HIFN_D_CMD_RSIZE+1];
struct hifn_desc srcr[HIFN_D_SRC_RSIZE+1];
struct hifn_desc dstr[HIFN_D_DST_RSIZE+1];
struct hifn_desc resr[HIFN_D_RES_RSIZE+1];
struct hifn_command *hifn_commands[HIFN_D_RES_RSIZE];
u_char command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND];
u_char result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT];
u_int32_t slop[HIFN_D_CMD_RSIZE];
u_int64_t test_src, test_dst;
/*
* Our current positions for insertion and removal from the desriptor
* rings.
*/
int cmdi, srci, dsti, resi;
volatile int cmdu, srcu, dstu, resu;
int cmdk, srck, dstk, resk;
};
struct hifn_session {
int hs_used;
int hs_mlen;
u_int8_t hs_iv[HIFN_MAX_IV_LENGTH];
};
#define HIFN_RING_SYNC(sc, r, i, f) \
/* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
#define HIFN_CMDR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), cmdr, (i), (f))
#define HIFN_RESR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), resr, (i), (f))
#define HIFN_SRCR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), srcr, (i), (f))
#define HIFN_DSTR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), dstr, (i), (f))
#define HIFN_CMD_SYNC(sc, i, f) \
/* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
#define HIFN_RES_SYNC(sc, i, f) \
/* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
typedef int bus_size_t;
/*
* Holds data specific to a single HIFN board.
*/
struct hifn_softc {
softc_device_decl sc_dev;
struct pci_dev *sc_pcidev; /* PCI device pointer */
spinlock_t sc_mtx; /* per-instance lock */
int sc_num; /* for multiple devs */
ocf_iomem_t sc_bar0;
bus_size_t sc_bar0_lastreg;/* bar0 last reg written */
ocf_iomem_t sc_bar1;
bus_size_t sc_bar1_lastreg;/* bar1 last reg written */
int sc_irq;
u_int32_t sc_dmaier;
u_int32_t sc_drammodel; /* 1=dram, 0=sram */
u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
struct hifn_dma *sc_dma;
dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
int sc_dmansegs;
int32_t sc_cid;
int sc_maxses;
int sc_nsessions;
struct hifn_session *sc_sessions;
int sc_ramsize;
int sc_flags;
#define HIFN_HAS_RNG 0x1 /* includes random number generator */
#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
#define HIFN_HAS_AES 0x4 /* includes AES support */
#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
struct timer_list sc_tickto; /* for managing DMA */
int sc_rngfirst;
int sc_rnghz; /* RNG polling frequency */
int sc_c_busy; /* command ring busy */
int sc_s_busy; /* source data ring busy */
int sc_d_busy; /* destination data ring busy */
int sc_r_busy; /* result ring busy */
int sc_active; /* for initial countdown */
int sc_needwakeup; /* ops q'd wating on resources */
int sc_curbatch; /* # ops submitted w/o int */
int sc_suspended;
#ifdef HIFN_VULCANDEV
struct cdev *sc_pkdev;
#endif
};
#define HIFN_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
#define HIFN_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
/*
* hifn_command_t
*
* This is the control structure used to pass commands to hifn_encrypt().
*
* flags
* -----
* Flags is the bitwise "or" values for command configuration. A single
* encrypt direction needs to be set:
*
* HIFN_ENCODE or HIFN_DECODE
*
* To use cryptography, a single crypto algorithm must be included:
*
* HIFN_CRYPT_3DES or HIFN_CRYPT_DES
*
* To use authentication is used, a single MAC algorithm must be included:
*
* HIFN_MAC_MD5 or HIFN_MAC_SHA1
*
* By default MD5 uses a 16 byte hash and SHA-1 uses a 20 byte hash.
* If the value below is set, hash values are truncated or assumed
* truncated to 12 bytes:
*
* HIFN_MAC_TRUNC
*
* Keys for encryption and authentication can be sent as part of a command,
* or the last key value used with a particular session can be retrieved
* and used again if either of these flags are not specified.
*
* HIFN_CRYPT_NEW_KEY, HIFN_MAC_NEW_KEY
*
* session_num
* -----------
* A number between 0 and 2048 (for DRAM models) or a number between
* 0 and 768 (for SRAM models). Those who don't want to use session
* numbers should leave value at zero and send a new crypt key and/or
* new MAC key on every command. If you use session numbers and
* don't send a key with a command, the last key sent for that same
* session number will be used.
*
* Warning: Using session numbers and multiboard at the same time
* is currently broken.
*
* mbuf
* ----
* Either fill in the mbuf pointer and npa=0 or
* fill packp[] and packl[] and set npa to > 0
*
* mac_header_skip
* ---------------
* The number of bytes of the source_buf that are skipped over before
* authentication begins. This must be a number between 0 and 2^16-1
* and can be used by IPsec implementers to skip over IP headers.
* *** Value ignored if authentication not used ***
*
* crypt_header_skip
* -----------------
* The number of bytes of the source_buf that are skipped over before
* the cryptographic operation begins. This must be a number between 0
* and 2^16-1. For IPsec, this number will always be 8 bytes larger
* than the auth_header_skip (to skip over the ESP header).
* *** Value ignored if cryptography not used ***
*
*/
struct hifn_operand {
union {
struct sk_buff *skb;
struct uio *io;
unsigned char *buf;
} u;
void *map;
bus_size_t mapsize;
int nsegs;
struct {
dma_addr_t ds_addr;
int ds_len;
} segs[MAX_SCATTER];
};
struct hifn_command {
u_int16_t session_num;
u_int16_t base_masks, cry_masks, mac_masks;
u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH];
int cklen;
int sloplen, slopidx;
struct hifn_operand src;
struct hifn_operand dst;
struct hifn_softc *softc;
struct cryptop *crp;
struct cryptodesc *enccrd, *maccrd;
};
#define src_skb src.u.skb
#define src_io src.u.io
#define src_map src.map
#define src_mapsize src.mapsize
#define src_segs src.segs
#define src_nsegs src.nsegs
#define src_buf src.u.buf
#define dst_skb dst.u.skb
#define dst_io dst.u.io
#define dst_map dst.map
#define dst_mapsize dst.mapsize
#define dst_segs dst.segs
#define dst_nsegs dst.nsegs
#define dst_buf dst.u.buf
/*
* Return values for hifn_crypto()
*/
#define HIFN_CRYPTO_SUCCESS 0
#define HIFN_CRYPTO_BAD_INPUT (-1)
#define HIFN_CRYPTO_RINGS_FULL (-2)
/**************************************************************************
*
* Function: hifn_crypto
*
* Purpose: Called by external drivers to begin an encryption on the
* HIFN board.
*
* Blocking/Non-blocking Issues
* ============================
* The driver cannot block in hifn_crypto (no calls to tsleep) currently.
* hifn_crypto() returns HIFN_CRYPTO_RINGS_FULL if there is not enough
* room in any of the rings for the request to proceed.
*
* Return Values
* =============
* 0 for success, negative values on error
*
* Defines for negative error codes are:
*
* HIFN_CRYPTO_BAD_INPUT : The passed in command had invalid settings.
* HIFN_CRYPTO_RINGS_FULL : All DMA rings were full and non-blocking
* behaviour was requested.
*
*************************************************************************/
/*
* Convert back and forth from 'sid' to 'card' and 'session'
*/
#define HIFN_CARD(sid) (((sid) & 0xf0000000) >> 28)
#define HIFN_SESSION(sid) ((sid) & 0x000007ff)
#define HIFN_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff))
#endif /* _KERNEL */
struct hifn_stats {
u_int64_t hst_ibytes;
u_int64_t hst_obytes;
u_int32_t hst_ipackets;
u_int32_t hst_opackets;
u_int32_t hst_invalid;
u_int32_t hst_nomem; /* malloc or one of hst_nomem_* */
u_int32_t hst_abort;
u_int32_t hst_noirq; /* IRQ for no reason */
u_int32_t hst_totbatch; /* ops submitted w/o interrupt */
u_int32_t hst_maxbatch; /* max ops submitted together */
u_int32_t hst_unaligned; /* unaligned src caused copy */
/*
* The following divides hst_nomem into more specific buckets.
*/
u_int32_t hst_nomem_map; /* bus_dmamap_create failed */
u_int32_t hst_nomem_load; /* bus_dmamap_load_* failed */
u_int32_t hst_nomem_mbuf; /* MGET* failed */
u_int32_t hst_nomem_mcl; /* MCLGET* failed */
u_int32_t hst_nomem_cr; /* out of command/result descriptor */
u_int32_t hst_nomem_sd; /* out of src/dst descriptors */
};
#endif /* __HIFN7751VAR_H__ */

View file

@ -0,0 +1,420 @@
/*-
* Driver for Hifn HIPP-I/II chipset
* Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Effort sponsored by Hifn Inc.
*
*/
/*
* Driver for various Hifn encryption processors.
*/
#ifndef AUTOCONF_INCLUDED
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/random.h>
#include <linux/version.h>
#include <linux/skbuff.h>
#include <linux/uio.h>
#include <linux/sysfs.h>
#include <linux/miscdevice.h>
#include <asm/io.h>
#include <cryptodev.h>
#include "hifnHIPPreg.h"
#include "hifnHIPPvar.h"
#if 1
#define DPRINTF(a...) if (hipp_debug) { \
printk("%s: ", sc ? \
device_get_nameunit(sc->sc_dev) : "hifn"); \
printk(a); \
} else
#else
#define DPRINTF(a...)
#endif
typedef int bus_size_t;
static inline int
pci_get_revid(struct pci_dev *dev)
{
u8 rid = 0;
pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
return rid;
}
#define debug hipp_debug
int hipp_debug = 0;
module_param(hipp_debug, int, 0644);
MODULE_PARM_DESC(hipp_debug, "Enable debug");
int hipp_maxbatch = 1;
module_param(hipp_maxbatch, int, 0644);
MODULE_PARM_DESC(hipp_maxbatch, "max ops to batch w/o interrupt");
static int hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent);
static void hipp_remove(struct pci_dev *dev);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
static irqreturn_t hipp_intr(int irq, void *arg);
#else
static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs);
#endif
static int hipp_num_chips = 0;
static struct hipp_softc *hipp_chip_idx[HIPP_MAX_CHIPS];
static int hipp_newsession(device_t, u_int32_t *, struct cryptoini *);
static int hipp_freesession(device_t, u_int64_t);
static int hipp_process(device_t, struct cryptop *, int);
static device_method_t hipp_methods = {
/* crypto device methods */
DEVMETHOD(cryptodev_newsession, hipp_newsession),
DEVMETHOD(cryptodev_freesession,hipp_freesession),
DEVMETHOD(cryptodev_process, hipp_process),
};
static __inline u_int32_t
READ_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg)
{
u_int32_t v = readl(sc->sc_bar[barno] + reg);
//sc->sc_bar0_lastreg = (bus_size_t) -1;
return (v);
}
static __inline void
WRITE_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg, u_int32_t val)
{
writel(val, sc->sc_bar[barno] + reg);
}
#define READ_REG_0(sc, reg) READ_REG(sc, 0, reg)
#define WRITE_REG_0(sc, reg, val) WRITE_REG(sc,0, reg, val)
#define READ_REG_1(sc, reg) READ_REG(sc, 1, reg)
#define WRITE_REG_1(sc, reg, val) WRITE_REG(sc,1, reg, val)
static int
hipp_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
{
return EINVAL;
}
static int
hipp_freesession(device_t dev, u_int64_t tid)
{
return EINVAL;
}
static int
hipp_process(device_t dev, struct cryptop *crp, int hint)
{
return EINVAL;
}
static const char*
hipp_partname(struct hipp_softc *sc, char buf[128], size_t blen)
{
char *n = NULL;
switch (pci_get_vendor(sc->sc_pcidev)) {
case PCI_VENDOR_HIFN:
switch (pci_get_device(sc->sc_pcidev)) {
case PCI_PRODUCT_HIFN_7855: n = "Hifn 7855";
case PCI_PRODUCT_HIFN_8155: n = "Hifn 8155";
case PCI_PRODUCT_HIFN_6500: n = "Hifn 6500";
}
}
if(n==NULL) {
snprintf(buf, blen, "VID=%02x,PID=%02x",
pci_get_vendor(sc->sc_pcidev),
pci_get_device(sc->sc_pcidev));
} else {
buf[0]='\0';
strncat(buf, n, blen);
}
return buf;
}
struct hipp_fs_entry {
struct attribute attr;
/* other stuff */
};
static ssize_t
cryptoid_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct hipp_softc *sc;
sc = pci_get_drvdata(to_pci_dev (dev));
return sprintf (buf, "%d\n", sc->sc_cid);
}
struct device_attribute hipp_dev_cryptoid = __ATTR_RO(cryptoid);
/*
* Attach an interface that successfully probed.
*/
static int
hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent)
{
struct hipp_softc *sc = NULL;
int i;
//char rbase;
//u_int16_t ena;
int rev;
//int rseg;
int rc;
DPRINTF("%s()\n", __FUNCTION__);
if (pci_enable_device(dev) < 0)
return(-ENODEV);
if (pci_set_mwi(dev))
return(-ENODEV);
if (!dev->irq) {
printk("hifn: found device with no IRQ assigned. check BIOS settings!");
pci_disable_device(dev);
return(-ENODEV);
}
sc = (struct hipp_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
if (!sc)
return(-ENOMEM);
memset(sc, 0, sizeof(*sc));
softc_device_init(sc, "hifn-hipp", hipp_num_chips, hipp_methods);
sc->sc_pcidev = dev;
sc->sc_irq = -1;
sc->sc_cid = -1;
sc->sc_num = hipp_num_chips++;
if (sc->sc_num < HIPP_MAX_CHIPS)
hipp_chip_idx[sc->sc_num] = sc;
pci_set_drvdata(sc->sc_pcidev, sc);
spin_lock_init(&sc->sc_mtx);
/*
* Setup PCI resources.
* The READ_REG_0, WRITE_REG_0, READ_REG_1,
* and WRITE_REG_1 macros throughout the driver are used
* to permit better debugging.
*/
for(i=0; i<4; i++) {
unsigned long mem_start, mem_len;
mem_start = pci_resource_start(sc->sc_pcidev, i);
mem_len = pci_resource_len(sc->sc_pcidev, i);
sc->sc_barphy[i] = (caddr_t)mem_start;
sc->sc_bar[i] = (ocf_iomem_t) ioremap(mem_start, mem_len);
if (!sc->sc_bar[i]) {
device_printf(sc->sc_dev, "cannot map bar%d register space\n", i);
goto fail;
}
}
//hipp_reset_board(sc, 0);
pci_set_master(sc->sc_pcidev);
/*
* Arrange the interrupt line.
*/
rc = request_irq(dev->irq, hipp_intr, IRQF_SHARED, "hifn", sc);
if (rc) {
device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
goto fail;
}
sc->sc_irq = dev->irq;
rev = READ_REG_1(sc, HIPP_1_REVID) & 0xffff;
{
char b[32];
device_printf(sc->sc_dev, "%s, rev %u",
hipp_partname(sc, b, sizeof(b)), rev);
}
#if 0
if (sc->sc_flags & HIFN_IS_7956)
printf(", pll=0x%x<%s clk, %ux mult>",
sc->sc_pllconfig,
sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
#endif
printf("\n");
sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
if (sc->sc_cid < 0) {
device_printf(sc->sc_dev, "could not get crypto driver id\n");
goto fail;
}
#if 0 /* cannot work with a non-GPL module */
/* make a sysfs entry to let the world know what entry we got */
sysfs_create_file(&sc->sc_pcidev->dev.kobj, &hipp_dev_cryptoid.attr);
#endif
#if 0
init_timer(&sc->sc_tickto);
sc->sc_tickto.function = hifn_tick;
sc->sc_tickto.data = (unsigned long) sc->sc_num;
mod_timer(&sc->sc_tickto, jiffies + HZ);
#endif
#if 0 /* no code here yet ?? */
crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
#endif
return (0);
fail:
if (sc->sc_cid >= 0)
crypto_unregister_all(sc->sc_cid);
if (sc->sc_irq != -1)
free_irq(sc->sc_irq, sc);
#if 0
if (sc->sc_dma) {
/* Turn off DMA polling */
WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
pci_free_consistent(sc->sc_pcidev,
sizeof(*sc->sc_dma),
sc->sc_dma, sc->sc_dma_physaddr);
}
#endif
kfree(sc);
return (-ENXIO);
}
/*
* Detach an interface that successfully probed.
*/
static void
hipp_remove(struct pci_dev *dev)
{
struct hipp_softc *sc = pci_get_drvdata(dev);
unsigned long l_flags;
DPRINTF("%s()\n", __FUNCTION__);
/* disable interrupts */
HIPP_LOCK(sc);
#if 0
WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
HIFN_UNLOCK(sc);
/*XXX other resources */
del_timer_sync(&sc->sc_tickto);
/* Turn off DMA polling */
WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
#endif
crypto_unregister_all(sc->sc_cid);
free_irq(sc->sc_irq, sc);
#if 0
pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
sc->sc_dma, sc->sc_dma_physaddr);
#endif
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
static irqreturn_t hipp_intr(int irq, void *arg)
#else
static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs)
#endif
{
struct hipp_softc *sc = arg;
sc = sc; /* shut up compiler */
return IRQ_HANDLED;
}
static struct pci_device_id hipp_pci_tbl[] = {
{ PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7855,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
{ PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_8155,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
};
MODULE_DEVICE_TABLE(pci, hipp_pci_tbl);
static struct pci_driver hipp_driver = {
.name = "hipp",
.id_table = hipp_pci_tbl,
.probe = hipp_probe,
.remove = hipp_remove,
/* add PM stuff here one day */
};
static int __init hipp_init (void)
{
struct hipp_softc *sc = NULL;
int rc;
DPRINTF("%s(%p)\n", __FUNCTION__, hipp_init);
rc = pci_register_driver(&hipp_driver);
pci_register_driver_compat(&hipp_driver, rc);
return rc;
}
static void __exit hipp_exit (void)
{
pci_unregister_driver(&hipp_driver);
}
module_init(hipp_init);
module_exit(hipp_exit);
MODULE_LICENSE("BSD");
MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
MODULE_DESCRIPTION("OCF driver for hifn HIPP-I/II PCI crypto devices");

View file

@ -0,0 +1,46 @@
/*-
* Hifn HIPP-I/HIPP-II (7855/8155) driver.
* Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Effort sponsored by Hifn inc.
*
*/
#ifndef __HIFNHIPP_H__
#define __HIFNHIPP_H__
/*
* PCI vendor and device identifiers
*/
#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
#define PCI_PRODUCT_HIFN_8155 0x999 /* XXX 8155 */
#define HIPP_1_REVID 0x01 /* BOGUS */
#endif /* __HIPP_H__ */

View file

@ -0,0 +1,93 @@
/*
* Hifn HIPP-I/HIPP-II (7855/8155) driver.
* Copyright (c) 2006 Michael Richardson <mcr@xelerance.com> *
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Effort sponsored by Hifn inc.
*
*/
#ifndef __HIFNHIPPVAR_H__
#define __HIFNHIPPVAR_H__
#define HIPP_MAX_CHIPS 8
/*
* Holds data specific to a single Hifn HIPP-I board.
*/
struct hipp_softc {
softc_device_decl sc_dev;
struct pci_dev *sc_pcidev; /* device backpointer */
ocf_iomem_t sc_bar[5];
caddr_t sc_barphy[5]; /* physical address */
int sc_num; /* for multiple devs */
spinlock_t sc_mtx; /* per-instance lock */
int32_t sc_cid;
int sc_irq;
#if 0
u_int32_t sc_dmaier;
u_int32_t sc_drammodel; /* 1=dram, 0=sram */
u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
struct hifn_dma *sc_dma;
dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
int sc_dmansegs;
int sc_maxses;
int sc_nsessions;
struct hifn_session *sc_sessions;
int sc_ramsize;
int sc_flags;
#define HIFN_HAS_RNG 0x1 /* includes random number generator */
#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
#define HIFN_HAS_AES 0x4 /* includes AES support */
#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
struct timer_list sc_tickto; /* for managing DMA */
int sc_rngfirst;
int sc_rnghz; /* RNG polling frequency */
int sc_c_busy; /* command ring busy */
int sc_s_busy; /* source data ring busy */
int sc_d_busy; /* destination data ring busy */
int sc_r_busy; /* result ring busy */
int sc_active; /* for initial countdown */
int sc_needwakeup; /* ops q'd wating on resources */
int sc_curbatch; /* # ops submitted w/o int */
int sc_suspended;
struct miscdevice sc_miscdev;
#endif
};
#define HIPP_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
#define HIPP_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
#endif /* __HIFNHIPPVAR_H__ */

View file

@ -0,0 +1,104 @@
# for SGlinux builds
-include $(ROOTDIR)/modules/.config
#
# You will need to point this at your Intel ixp425 includes, this portion
# of the Makefile only really works under SGLinux with the appropriate libs
# installed. They can be downloaded from http://www.snapgear.org/
#
ifeq ($(CONFIG_CPU_IXP46X),y)
IXPLATFORM = ixp46X
else
ifeq ($(CONFIG_CPU_IXP43X),y)
IXPLATFORM = ixp43X
else
IXPLATFORM = ixp42X
endif
endif
ifdef CONFIG_IXP400_LIB_2_4
IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp400_xscale_sw
OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp_osal
endif
ifdef CONFIG_IXP400_LIB_2_1
IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp400_xscale_sw
OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp_osal
endif
ifdef CONFIG_IXP400_LIB_2_0
IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp400_xscale_sw
OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp_osal
endif
ifdef IX_XSCALE_SW
ifdef CONFIG_IXP400_LIB_2_4
IXP_CFLAGS = \
-I$(ROOTDIR)/. \
-I$(IX_XSCALE_SW)/src/include \
-I$(OSAL_DIR)/common/include/ \
-I$(OSAL_DIR)/common/include/modules/ \
-I$(OSAL_DIR)/common/include/modules/ddk/ \
-I$(OSAL_DIR)/common/include/modules/bufferMgt/ \
-I$(OSAL_DIR)/common/include/modules/ioMem/ \
-I$(OSAL_DIR)/common/os/linux/include/ \
-I$(OSAL_DIR)/common/os/linux/include/core/ \
-I$(OSAL_DIR)/common/os/linux/include/modules/ \
-I$(OSAL_DIR)/common/os/linux/include/modules/ddk/ \
-I$(OSAL_DIR)/common/os/linux/include/modules/bufferMgt/ \
-I$(OSAL_DIR)/common/os/linux/include/modules/ioMem/ \
-I$(OSAL_DIR)/platforms/$(IXPLATFORM)/include/ \
-I$(OSAL_DIR)/platforms/$(IXPLATFORM)/os/linux/include/ \
-DENABLE_IOMEM -DENABLE_BUFFERMGT -DENABLE_DDK \
-DUSE_IXP4XX_CRYPTO
else
IXP_CFLAGS = \
-I$(ROOTDIR)/. \
-I$(IX_XSCALE_SW)/src/include \
-I$(OSAL_DIR)/ \
-I$(OSAL_DIR)/os/linux/include/ \
-I$(OSAL_DIR)/os/linux/include/modules/ \
-I$(OSAL_DIR)/os/linux/include/modules/ioMem/ \
-I$(OSAL_DIR)/os/linux/include/modules/bufferMgt/ \
-I$(OSAL_DIR)/os/linux/include/core/ \
-I$(OSAL_DIR)/os/linux/include/platforms/ \
-I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ \
-I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp425 \
-I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp465 \
-I$(OSAL_DIR)/os/linux/include/core/ \
-I$(OSAL_DIR)/include/ \
-I$(OSAL_DIR)/include/modules/ \
-I$(OSAL_DIR)/include/modules/bufferMgt/ \
-I$(OSAL_DIR)/include/modules/ioMem/ \
-I$(OSAL_DIR)/include/platforms/ \
-I$(OSAL_DIR)/include/platforms/ixp400/ \
-DUSE_IXP4XX_CRYPTO
endif
endif
ifdef CONFIG_IXP400_LIB_1_4
IXP_CFLAGS = \
-I$(ROOTDIR)/. \
-I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/include \
-I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/linux \
-DUSE_IXP4XX_CRYPTO
endif
ifndef IXPDIR
IXPDIR = ixp-version-is-not-supported
endif
ifeq ($(CONFIG_CPU_IXP46X),y)
IXP_CFLAGS += -D__ixp46X
else
ifeq ($(CONFIG_CPU_IXP43X),y)
IXP_CFLAGS += -D__ixp43X
else
IXP_CFLAGS += -D__ixp42X
endif
endif
obj-$(CONFIG_OCF_IXP4XX) += ixp4xx.o
obj ?= .
EXTRA_CFLAGS += $(IXP_CFLAGS) -I$(obj)/.. -I$(obj)/.
ifdef TOPDIR
-include $(TOPDIR)/Rules.make
endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,436 @@
/*
* A loadable module that benchmarks the OCF crypto speed from kernel space.
*
* Copyright (C) 2004-2007 David McCullough <david_mccullough@securecomputing.com>
*
* LICENSE TERMS
*
* The free distribution and use of this software in both source and binary
* form is allowed (with or without changes) provided that:
*
* 1. distributions of this source code include the above copyright
* notice, this list of conditions and the following disclaimer;
*
* 2. distributions in binary form include the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other associated materials;
*
* 3. the copyright holder's name is not used to endorse products
* built using this software without specific written permission.
*
* ALTERNATIVELY, provided that this notice is retained in full, this product
* may be distributed under the terms of the GNU General Public License (GPL),
* in which case the provisions of the GPL apply INSTEAD OF those given above.
*
* DISCLAIMER
*
* This software is provided 'as is' with no explicit or implied warranties
* in respect of its properties, including, but not limited to, correctness
* and/or fitness for purpose.
*/
#ifndef AUTOCONF_INCLUDED
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/version.h>
#include <linux/interrupt.h>
#include <cryptodev.h>
#ifdef I_HAVE_AN_XSCALE_WITH_INTEL_SDK
#define BENCH_IXP_ACCESS_LIB 1
#endif
#ifdef BENCH_IXP_ACCESS_LIB
#include <IxTypes.h>
#include <IxOsBuffMgt.h>
#include <IxNpeDl.h>
#include <IxCryptoAcc.h>
#include <IxQMgr.h>
#include <IxOsServices.h>
#include <IxOsCacheMMU.h>
#endif
/*
* support for access lib version 1.4
*/
#ifndef IX_MBUF_PRIV
#define IX_MBUF_PRIV(x) ((x)->priv)
#endif
/*
* the number of simultaneously active requests
*/
static int request_q_len = 20;
module_param(request_q_len, int, 0);
MODULE_PARM_DESC(request_q_len, "Number of outstanding requests");
/*
* how many requests we want to have processed
*/
static int request_num = 1024;
module_param(request_num, int, 0);
MODULE_PARM_DESC(request_num, "run for at least this many requests");
/*
* the size of each request
*/
static int request_size = 1500;
module_param(request_size, int, 0);
MODULE_PARM_DESC(request_size, "size of each request");
/*
* a structure for each request
*/
typedef struct {
struct work_struct work;
#ifdef BENCH_IXP_ACCESS_LIB
IX_MBUF mbuf;
#endif
unsigned char *buffer;
} request_t;
static request_t *requests;
static int outstanding;
static int total;
/*************************************************************************/
/*
* OCF benchmark routines
*/
static uint64_t ocf_cryptoid;
static int ocf_init(void);
static int ocf_cb(struct cryptop *crp);
static void ocf_request(void *arg);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
static void ocf_request_wq(struct work_struct *work);
#endif
static int
ocf_init(void)
{
int error;
struct cryptoini crie, cria;
struct cryptodesc crda, crde;
memset(&crie, 0, sizeof(crie));
memset(&cria, 0, sizeof(cria));
memset(&crde, 0, sizeof(crde));
memset(&crda, 0, sizeof(crda));
cria.cri_alg = CRYPTO_SHA1_HMAC;
cria.cri_klen = 20 * 8;
cria.cri_key = "0123456789abcdefghij";
crie.cri_alg = CRYPTO_3DES_CBC;
crie.cri_klen = 24 * 8;
crie.cri_key = "0123456789abcdefghijklmn";
crie.cri_next = &cria;
error = crypto_newsession(&ocf_cryptoid, &crie, 0);
if (error) {
printk("crypto_newsession failed %d\n", error);
return -1;
}
return 0;
}
static int
ocf_cb(struct cryptop *crp)
{
request_t *r = (request_t *) crp->crp_opaque;
if (crp->crp_etype)
printk("Error in OCF processing: %d\n", crp->crp_etype);
total++;
crypto_freereq(crp);
crp = NULL;
if (total > request_num) {
outstanding--;
return 0;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
INIT_WORK(&r->work, ocf_request_wq);
#else
INIT_WORK(&r->work, ocf_request, r);
#endif
schedule_work(&r->work);
return 0;
}
static void
ocf_request(void *arg)
{
request_t *r = arg;
struct cryptop *crp = crypto_getreq(2);
struct cryptodesc *crde, *crda;
if (!crp) {
outstanding--;
return;
}
crde = crp->crp_desc;
crda = crde->crd_next;
crda->crd_skip = 0;
crda->crd_flags = 0;
crda->crd_len = request_size;
crda->crd_inject = request_size;
crda->crd_alg = CRYPTO_SHA1_HMAC;
crda->crd_key = "0123456789abcdefghij";
crda->crd_klen = 20 * 8;
crde->crd_skip = 0;
crde->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_ENCRYPT;
crde->crd_len = request_size;
crde->crd_inject = request_size;
crde->crd_alg = CRYPTO_3DES_CBC;
crde->crd_key = "0123456789abcdefghijklmn";
crde->crd_klen = 24 * 8;
crp->crp_ilen = request_size + 64;
crp->crp_flags = CRYPTO_F_CBIMM;
crp->crp_buf = (caddr_t) r->buffer;
crp->crp_callback = ocf_cb;
crp->crp_sid = ocf_cryptoid;
crp->crp_opaque = (caddr_t) r;
crypto_dispatch(crp);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
static void
ocf_request_wq(struct work_struct *work)
{
request_t *r = container_of(work, request_t, work);
ocf_request(r);
}
#endif
/*************************************************************************/
#ifdef BENCH_IXP_ACCESS_LIB
/*************************************************************************/
/*
* CryptoAcc benchmark routines
*/
static IxCryptoAccCtx ixp_ctx;
static UINT32 ixp_ctx_id;
static IX_MBUF ixp_pri;
static IX_MBUF ixp_sec;
static int ixp_registered = 0;
static void ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp,
IxCryptoAccStatus status);
static void ixp_perform_cb(UINT32 ctx_id, IX_MBUF *sbufp, IX_MBUF *dbufp,
IxCryptoAccStatus status);
static void ixp_request(void *arg);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
static void ixp_request_wq(struct work_struct *work);
#endif
static int
ixp_init(void)
{
IxCryptoAccStatus status;
ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
ixp_ctx.cipherCtx.cipherKeyLen = 24;
ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
ixp_ctx.cipherCtx.cipherInitialVectorLen = IX_CRYPTO_ACC_DES_IV_64;
memcpy(ixp_ctx.cipherCtx.key.cipherKey, "0123456789abcdefghijklmn", 24);
ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
ixp_ctx.authCtx.authDigestLen = 12;
ixp_ctx.authCtx.aadLen = 0;
ixp_ctx.authCtx.authKeyLen = 20;
memcpy(ixp_ctx.authCtx.key.authKey, "0123456789abcdefghij", 20);
ixp_ctx.useDifferentSrcAndDestMbufs = 0;
ixp_ctx.operation = IX_CRYPTO_ACC_OP_ENCRYPT_AUTH ;
IX_MBUF_MLEN(&ixp_pri) = IX_MBUF_PKT_LEN(&ixp_pri) = 128;
IX_MBUF_MDATA(&ixp_pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
IX_MBUF_MLEN(&ixp_sec) = IX_MBUF_PKT_LEN(&ixp_sec) = 128;
IX_MBUF_MDATA(&ixp_sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
status = ixCryptoAccCtxRegister(&ixp_ctx, &ixp_pri, &ixp_sec,
ixp_register_cb, ixp_perform_cb, &ixp_ctx_id);
if (IX_CRYPTO_ACC_STATUS_SUCCESS == status) {
while (!ixp_registered)
schedule();
return ixp_registered < 0 ? -1 : 0;
}
printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
return -1;
}
static void
ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
{
if (bufp) {
IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
kfree(IX_MBUF_MDATA(bufp));
IX_MBUF_MDATA(bufp) = NULL;
}
if (IX_CRYPTO_ACC_STATUS_WAIT == status)
return;
if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
ixp_registered = 1;
else
ixp_registered = -1;
}
static void
ixp_perform_cb(
UINT32 ctx_id,
IX_MBUF *sbufp,
IX_MBUF *dbufp,
IxCryptoAccStatus status)
{
request_t *r = NULL;
total++;
if (total > request_num) {
outstanding--;
return;
}
if (!sbufp || !(r = IX_MBUF_PRIV(sbufp))) {
printk("crappo %p %p\n", sbufp, r);
outstanding--;
return;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
INIT_WORK(&r->work, ixp_request_wq);
#else
INIT_WORK(&r->work, ixp_request, r);
#endif
schedule_work(&r->work);
}
static void
ixp_request(void *arg)
{
request_t *r = arg;
IxCryptoAccStatus status;
memset(&r->mbuf, 0, sizeof(r->mbuf));
IX_MBUF_MLEN(&r->mbuf) = IX_MBUF_PKT_LEN(&r->mbuf) = request_size + 64;
IX_MBUF_MDATA(&r->mbuf) = r->buffer;
IX_MBUF_PRIV(&r->mbuf) = r;
status = ixCryptoAccAuthCryptPerform(ixp_ctx_id, &r->mbuf, NULL,
0, request_size, 0, request_size, request_size, r->buffer);
if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
printk("status1 = %d\n", status);
outstanding--;
return;
}
return;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
static void
ixp_request_wq(struct work_struct *work)
{
request_t *r = container_of(work, request_t, work);
ixp_request(r);
}
#endif
/*************************************************************************/
#endif /* BENCH_IXP_ACCESS_LIB */
/*************************************************************************/
int
ocfbench_init(void)
{
int i, jstart, jstop;
printk("Crypto Speed tests\n");
requests = kmalloc(sizeof(request_t) * request_q_len, GFP_KERNEL);
if (!requests) {
printk("malloc failed\n");
return -EINVAL;
}
for (i = 0; i < request_q_len; i++) {
/* +64 for return data */
requests[i].buffer = kmalloc(request_size + 128, GFP_DMA);
if (!requests[i].buffer) {
printk("malloc failed\n");
return -EINVAL;
}
memset(requests[i].buffer, '0' + i, request_size + 128);
}
/*
* OCF benchmark
*/
printk("OCF: testing ...\n");
ocf_init();
total = outstanding = 0;
jstart = jiffies;
for (i = 0; i < request_q_len; i++) {
outstanding++;
ocf_request(&requests[i]);
}
while (outstanding > 0)
schedule();
jstop = jiffies;
printk("OCF: %d requests of %d bytes in %d jiffies\n", total, request_size,
jstop - jstart);
#ifdef BENCH_IXP_ACCESS_LIB
/*
* IXP benchmark
*/
printk("IXP: testing ...\n");
ixp_init();
total = outstanding = 0;
jstart = jiffies;
for (i = 0; i < request_q_len; i++) {
outstanding++;
ixp_request(&requests[i]);
}
while (outstanding > 0)
schedule();
jstop = jiffies;
printk("IXP: %d requests of %d bytes in %d jiffies\n", total, request_size,
jstop - jstart);
#endif /* BENCH_IXP_ACCESS_LIB */
for (i = 0; i < request_q_len; i++)
kfree(requests[i].buffer);
kfree(requests);
return -EINVAL; /* always fail to load so it can be re-run quickly ;-) */
}
static void __exit ocfbench_exit(void)
{
}
module_init(ocfbench_init);
module_exit(ocfbench_exit);
MODULE_LICENSE("BSD");
MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
MODULE_DESCRIPTION("Benchmark various in-kernel crypto speeds");

View file

@ -0,0 +1,270 @@
#ifndef _BSD_COMPAT_H_
#define _BSD_COMPAT_H_ 1
/****************************************************************************/
/*
* Provide compat routines for older linux kernels and BSD kernels
*
* Written by David McCullough <david_mccullough@securecomputing.com>
* Copyright (C) 2007 David McCullough <david_mccullough@securecomputing.com>
*
* LICENSE TERMS
*
* The free distribution and use of this software in both source and binary
* form is allowed (with or without changes) provided that:
*
* 1. distributions of this source code include the above copyright
* notice, this list of conditions and the following disclaimer;
*
* 2. distributions in binary form include the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other associated materials;
*
* 3. the copyright holder's name is not used to endorse products
* built using this software without specific written permission.
*
* ALTERNATIVELY, provided that this notice is retained in full, this file
* may be distributed under the terms of the GNU General Public License (GPL),
* in which case the provisions of the GPL apply INSTEAD OF those given above.
*
* DISCLAIMER
*
* This software is provided 'as is' with no explicit or implied warranties
* in respect of its properties, including, but not limited to, correctness
* and/or fitness for purpose.
*/
/****************************************************************************/
#ifdef __KERNEL__
/*
* fake some BSD driver interface stuff specifically for OCF use
*/
typedef struct ocf_device *device_t;
typedef struct {
int (*cryptodev_newsession)(device_t dev, u_int32_t *sidp, struct cryptoini *cri);
int (*cryptodev_freesession)(device_t dev, u_int64_t tid);
int (*cryptodev_process)(device_t dev, struct cryptop *crp, int hint);
int (*cryptodev_kprocess)(device_t dev, struct cryptkop *krp, int hint);
} device_method_t;
#define DEVMETHOD(id, func) id: func
struct ocf_device {
char name[32]; /* the driver name */
char nameunit[32]; /* the driver name + HW instance */
int unit;
device_method_t methods;
void *softc;
};
#define CRYPTODEV_NEWSESSION(dev, sid, cri) \
((*(dev)->methods.cryptodev_newsession)(dev,sid,cri))
#define CRYPTODEV_FREESESSION(dev, sid) \
((*(dev)->methods.cryptodev_freesession)(dev, sid))
#define CRYPTODEV_PROCESS(dev, crp, hint) \
((*(dev)->methods.cryptodev_process)(dev, crp, hint))
#define CRYPTODEV_KPROCESS(dev, krp, hint) \
((*(dev)->methods.cryptodev_kprocess)(dev, krp, hint))
#define device_get_name(dev) ((dev)->name)
#define device_get_nameunit(dev) ((dev)->nameunit)
#define device_get_unit(dev) ((dev)->unit)
#define device_get_softc(dev) ((dev)->softc)
#define softc_device_decl \
struct ocf_device _device; \
device_t
#define softc_device_init(_sc, _name, _unit, _methods) \
if (1) {\
strncpy((_sc)->_device.name, _name, sizeof((_sc)->_device.name) - 1); \
snprintf((_sc)->_device.nameunit, sizeof((_sc)->_device.name), "%s%d", _name, _unit); \
(_sc)->_device.unit = _unit; \
(_sc)->_device.methods = _methods; \
(_sc)->_device.softc = (void *) _sc; \
*(device_t *)((softc_get_device(_sc))+1) = &(_sc)->_device; \
} else
#define softc_get_device(_sc) (&(_sc)->_device)
/*
* iomem support for 2.4 and 2.6 kernels
*/
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
#define ocf_iomem_t unsigned long
/*
* implement simple workqueue like support for older kernels
*/
#include <linux/tqueue.h>
#define work_struct tq_struct
#define INIT_WORK(wp, fp, ap) \
do { \
(wp)->sync = 0; \
(wp)->routine = (fp); \
(wp)->data = (ap); \
} while (0)
#define schedule_work(wp) \
do { \
queue_task((wp), &tq_immediate); \
mark_bh(IMMEDIATE_BH); \
} while (0)
#define flush_scheduled_work() run_task_queue(&tq_immediate)
#else
#define ocf_iomem_t void __iomem *
#include <linux/workqueue.h>
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
#include <linux/fdtable.h>
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
#define files_fdtable(files) (files)
#endif
#ifdef MODULE_PARM
#undef module_param /* just in case */
#define module_param(a,b,c) MODULE_PARM(a,"i")
#endif
#define bzero(s,l) memset(s,0,l)
#define bcopy(s,d,l) memcpy(d,s,l)
#define bcmp(x, y, l) memcmp(x,y,l)
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#define device_printf(dev, a...) ({ \
printk("%s: ", device_get_nameunit(dev)); printk(a); \
})
#undef printf
#define printf(fmt...) printk(fmt)
#define KASSERT(c,p) if (!(c)) { printk p ; } else
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
#define ocf_daemonize(str) \
daemonize(); \
spin_lock_irq(&current->sigmask_lock); \
sigemptyset(&current->blocked); \
recalc_sigpending(current); \
spin_unlock_irq(&current->sigmask_lock); \
sprintf(current->comm, str);
#else
#define ocf_daemonize(str) daemonize(str);
#endif
#define TAILQ_INSERT_TAIL(q,d,m) list_add_tail(&(d)->m, (q))
#define TAILQ_EMPTY(q) list_empty(q)
#define TAILQ_FOREACH(v, q, m) list_for_each_entry(v, q, m)
#define read_random(p,l) get_random_bytes(p,l)
#define DELAY(x) ((x) > 2000 ? mdelay((x)/1000) : udelay(x))
#define strtoul simple_strtoul
#define pci_get_vendor(dev) ((dev)->vendor)
#define pci_get_device(dev) ((dev)->device)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
#define pci_set_consistent_dma_mask(dev, mask) (0)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
#define pci_dma_sync_single_for_cpu pci_dma_sync_single
#endif
#ifndef DMA_32BIT_MASK
#define DMA_32BIT_MASK 0x00000000ffffffffULL
#endif
#define htole32(x) cpu_to_le32(x)
#define htobe32(x) cpu_to_be32(x)
#define htole16(x) cpu_to_le16(x)
#define htobe16(x) cpu_to_be16(x)
/* older kernels don't have these */
#ifndef IRQ_NONE
#define IRQ_NONE
#define IRQ_HANDLED
#define irqreturn_t void
#endif
#ifndef IRQF_SHARED
#define IRQF_SHARED SA_SHIRQ
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
# define strlcpy(dest,src,len) \
({strncpy(dest,src,(len)-1); ((char *)dest)[(len)-1] = '\0'; })
#endif
#ifndef MAX_ERRNO
#define MAX_ERRNO 4095
#endif
#ifndef IS_ERR_VALUE
#define IS_ERR_VALUE(x) ((unsigned long)(x) >= (unsigned long)-MAX_ERRNO)
#endif
/*
* common debug for all
*/
#if 1
#define dprintk(a...) do { if (debug) printk(a); } while(0)
#else
#define dprintk(a...)
#endif
#ifndef SLAB_ATOMIC
/* Changed in 2.6.20, must use GFP_ATOMIC now */
#define SLAB_ATOMIC GFP_ATOMIC
#endif
/*
* need some additional support for older kernels */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,2)
#define pci_register_driver_compat(driver, rc) \
do { \
if ((rc) > 0) { \
(rc) = 0; \
} else if (rc == 0) { \
(rc) = -ENODEV; \
} else { \
pci_unregister_driver(driver); \
} \
} while (0)
#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
#define pci_register_driver_compat(driver,rc) ((rc) = (rc) < 0 ? (rc) : 0)
#else
#define pci_register_driver_compat(driver,rc)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
#include <asm/scatterlist.h>
static inline void sg_set_page(struct scatterlist *sg, struct page *page,
unsigned int len, unsigned int offset)
{
sg->page = page;
sg->offset = offset;
sg->length = len;
}
static inline void *sg_virt(struct scatterlist *sg)
{
return page_address(sg->page) + sg->offset;
}
#endif
#endif /* __KERNEL__ */
/****************************************************************************/
#endif /* _BSD_COMPAT_H_ */

View file

@ -0,0 +1,12 @@
# for SGlinux builds
-include $(ROOTDIR)/modules/.config
obj-$(CONFIG_OCF_OCFNULL) += ocfnull.o
obj ?= .
EXTRA_CFLAGS += -I$(obj)/..
ifdef TOPDIR
-include $(TOPDIR)/Rules.make
endif

View file

@ -0,0 +1,203 @@
/*
* An OCF module for determining the cost of crypto versus the cost of
* IPSec processing outside of OCF. This modules gives us the effect of
* zero cost encryption, of course you will need to run it at both ends
* since it does no crypto at all.
*
* Written by David McCullough <david_mccullough@securecomputing.com>
* Copyright (C) 2006-2007 David McCullough
*
* LICENSE TERMS
*
* The free distribution and use of this software in both source and binary
* form is allowed (with or without changes) provided that:
*
* 1. distributions of this source code include the above copyright
* notice, this list of conditions and the following disclaimer;
*
* 2. distributions in binary form include the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other associated materials;
*
* 3. the copyright holder's name is not used to endorse products
* built using this software without specific written permission.
*
* ALTERNATIVELY, provided that this notice is retained in full, this product
* may be distributed under the terms of the GNU General Public License (GPL),
* in which case the provisions of the GPL apply INSTEAD OF those given above.
*
* DISCLAIMER
*
* This software is provided 'as is' with no explicit or implied warranties
* in respect of its properties, including, but not limited to, correctness
* and/or fitness for purpose.
*/
#ifndef AUTOCONF_INCLUDED
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/crypto.h>
#include <linux/interrupt.h>
#include <cryptodev.h>
#include <uio.h>
static int32_t null_id = -1;
static u_int32_t null_sesnum = 0;
static int null_process(device_t, struct cryptop *, int);
static int null_newsession(device_t, u_int32_t *, struct cryptoini *);
static int null_freesession(device_t, u_int64_t);
#define debug ocfnull_debug
int ocfnull_debug = 0;
module_param(ocfnull_debug, int, 0644);
MODULE_PARM_DESC(ocfnull_debug, "Enable debug");
/*
* dummy device structure
*/
static struct {
softc_device_decl sc_dev;
} nulldev;
static device_method_t null_methods = {
/* crypto device methods */
DEVMETHOD(cryptodev_newsession, null_newsession),
DEVMETHOD(cryptodev_freesession,null_freesession),
DEVMETHOD(cryptodev_process, null_process),
};
/*
* Generate a new software session.
*/
static int
null_newsession(device_t arg, u_int32_t *sid, struct cryptoini *cri)
{
dprintk("%s()\n", __FUNCTION__);
if (sid == NULL || cri == NULL) {
dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
return EINVAL;
}
if (null_sesnum == 0)
null_sesnum++;
*sid = null_sesnum++;
return 0;
}
/*
* Free a session.
*/
static int
null_freesession(device_t arg, u_int64_t tid)
{
u_int32_t sid = CRYPTO_SESID2LID(tid);
dprintk("%s()\n", __FUNCTION__);
if (sid > null_sesnum) {
dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
return EINVAL;
}
/* Silently accept and return */
if (sid == 0)
return 0;
return 0;
}
/*
* Process a request.
*/
static int
null_process(device_t arg, struct cryptop *crp, int hint)
{
unsigned int lid;
dprintk("%s()\n", __FUNCTION__);
/* Sanity check */
if (crp == NULL) {
dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
return EINVAL;
}
crp->crp_etype = 0;
if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
crp->crp_etype = EINVAL;
goto done;
}
/*
* find the session we are using
*/
lid = crp->crp_sid & 0xffffffff;
if (lid >= null_sesnum || lid == 0) {
crp->crp_etype = ENOENT;
dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
goto done;
}
done:
crypto_done(crp);
return 0;
}
/*
* our driver startup and shutdown routines
*/
static int
null_init(void)
{
dprintk("%s(%p)\n", __FUNCTION__, null_init);
memset(&nulldev, 0, sizeof(nulldev));
softc_device_init(&nulldev, "ocfnull", 0, null_methods);
null_id = crypto_get_driverid(softc_get_device(&nulldev),
CRYPTOCAP_F_HARDWARE);
if (null_id < 0)
panic("ocfnull: crypto device cannot initialize!");
#define REGISTER(alg) \
crypto_register(null_id,alg,0,0)
REGISTER(CRYPTO_DES_CBC);
REGISTER(CRYPTO_3DES_CBC);
REGISTER(CRYPTO_RIJNDAEL128_CBC);
REGISTER(CRYPTO_MD5);
REGISTER(CRYPTO_SHA1);
REGISTER(CRYPTO_MD5_HMAC);
REGISTER(CRYPTO_SHA1_HMAC);
#undef REGISTER
return 0;
}
static void
null_exit(void)
{
dprintk("%s()\n", __FUNCTION__);
crypto_unregister_all(null_id);
null_id = -1;
}
module_init(null_init);
module_exit(null_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
MODULE_DESCRIPTION("ocfnull - claims a lot but does nothing");

View file

@ -0,0 +1,12 @@
# for SGlinux builds
-include $(ROOTDIR)/modules/.config
obj-$(CONFIG_OCF_PASEMI) += pasemi.o
obj ?= .
EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
ifdef TOPDIR
-include $(TOPDIR)/Rules.make
endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,410 @@
/*
* Copyright (C) 2007 PA Semi, Inc
*
* Driver for the PA Semi PWRficient DMA Crypto Engine, soft state and
* hardware register layouts.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PASEMI_FNU_H
#define PASEMI_FNU_H
#include <linux/spinlock.h>
#define PASEMI_SESSION(sid) ((sid) & 0xffffffff)
#define PASEMI_SID(sesn) ((sesn) & 0xffffffff)
#define DPRINTF(a...) if (debug) { printk(DRV_NAME ": " a); }
/* Must be a power of two */
#define RX_RING_SIZE 512
#define TX_RING_SIZE 512
#define TX_DESC(ring, num) ((ring)->desc[2 * (num & (TX_RING_SIZE-1))])
#define TX_DESC_INFO(ring, num) ((ring)->desc_info[(num) & (TX_RING_SIZE-1)])
#define MAX_DESC_SIZE 8
#define PASEMI_INITIAL_SESSIONS 10
#define PASEMI_FNU_CHANNELS 8
/* DMA descriptor */
struct pasemi_desc {
u64 quad[2*MAX_DESC_SIZE];
int quad_cnt;
int size;
int postop;
};
/*
* Holds per descriptor data
*/
struct pasemi_desc_info {
int desc_size;
int desc_postop;
#define PASEMI_CHECK_SIG 0x1
struct cryptop *cf_crp;
};
/*
* Holds per channel data
*/
struct pasemi_fnu_txring {
volatile u64 *desc;
volatile struct
pasemi_desc_info *desc_info;
dma_addr_t dma;
struct timer_list crypto_timer;
spinlock_t fill_lock;
spinlock_t clean_lock;
unsigned int next_to_fill;
unsigned int next_to_clean;
u16 total_pktcnt;
int irq;
int sesn;
char irq_name[10];
};
/*
* Holds data specific to a single pasemi device.
*/
struct pasemi_softc {
softc_device_decl sc_cdev;
struct pci_dev *dma_pdev; /* device backpointer */
struct pci_dev *iob_pdev; /* device backpointer */
void __iomem *dma_regs;
void __iomem *iob_regs;
int base_irq;
int base_chan;
int32_t sc_cid; /* crypto tag */
int sc_nsessions;
struct pasemi_session **sc_sessions;
int sc_num_channels;/* number of crypto channels */
/* pointer to the array of txring datastructures, one txring per channel */
struct pasemi_fnu_txring *tx;
/*
* mutual exclusion for the channel scheduler
*/
spinlock_t sc_chnlock;
/* last channel used, for now use round-robin to allocate channels */
int sc_lastchn;
};
struct pasemi_session {
u64 civ[2];
u64 keysz;
u64 key[4];
u64 ccmd;
u64 hkey[4];
u64 hseq;
u64 giv[2];
u64 hiv[4];
int used;
dma_addr_t dma_addr;
int chan;
};
/* status register layout in IOB region, at 0xfd800000 */
struct pasdma_status {
u64 rx_sta[64];
u64 tx_sta[20];
};
#define ALG_IS_CIPHER(alg) ((alg == CRYPTO_DES_CBC) || \
(alg == CRYPTO_3DES_CBC) || \
(alg == CRYPTO_AES_CBC) || \
(alg == CRYPTO_ARC4) || \
(alg == CRYPTO_NULL_CBC))
#define ALG_IS_SIG(alg) ((alg == CRYPTO_MD5) || \
(alg == CRYPTO_MD5_HMAC) || \
(alg == CRYPTO_SHA1) || \
(alg == CRYPTO_SHA1_HMAC) || \
(alg == CRYPTO_NULL_HMAC))
enum {
PAS_DMA_COM_TXCMD = 0x100, /* Transmit Command Register */
PAS_DMA_COM_TXSTA = 0x104, /* Transmit Status Register */
PAS_DMA_COM_RXCMD = 0x108, /* Receive Command Register */
PAS_DMA_COM_RXSTA = 0x10c, /* Receive Status Register */
PAS_DMA_COM_CFG = 0x114, /* DMA Configuration Register */
};
/* All these registers live in the PCI configuration space for the DMA PCI
* device. Use the normal PCI config access functions for them.
*/
#define PAS_DMA_COM_CFG_FWF 0x18000000
#define PAS_DMA_COM_TXCMD_EN 0x00000001 /* enable */
#define PAS_DMA_COM_TXSTA_ACT 0x00000001 /* active */
#define PAS_DMA_COM_RXCMD_EN 0x00000001 /* enable */
#define PAS_DMA_COM_RXSTA_ACT 0x00000001 /* active */
#define _PAS_DMA_TXCHAN_STRIDE 0x20 /* Size per channel */
#define _PAS_DMA_TXCHAN_TCMDSTA 0x300 /* Command / Status */
#define _PAS_DMA_TXCHAN_CFG 0x304 /* Configuration */
#define _PAS_DMA_TXCHAN_DSCRBU 0x308 /* Descriptor BU Allocation */
#define _PAS_DMA_TXCHAN_INCR 0x310 /* Descriptor increment */
#define _PAS_DMA_TXCHAN_CNT 0x314 /* Descriptor count/offset */
#define _PAS_DMA_TXCHAN_BASEL 0x318 /* Descriptor ring base (low) */
#define _PAS_DMA_TXCHAN_BASEU 0x31c /* (high) */
#define PAS_DMA_TXCHAN_TCMDSTA(c) (0x300+(c)*_PAS_DMA_TXCHAN_STRIDE)
#define PAS_DMA_TXCHAN_TCMDSTA_EN 0x00000001 /* Enabled */
#define PAS_DMA_TXCHAN_TCMDSTA_ST 0x00000002 /* Stop interface */
#define PAS_DMA_TXCHAN_TCMDSTA_ACT 0x00010000 /* Active */
#define PAS_DMA_TXCHAN_CFG(c) (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)
#define PAS_DMA_TXCHAN_CFG_TY_FUNC 0x00000002 /* Type = interface */
#define PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000 /* Type = interface */
#define PAS_DMA_TXCHAN_CFG_TATTR_M 0x0000003c
#define PAS_DMA_TXCHAN_CFG_TATTR_S 2
#define PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \
PAS_DMA_TXCHAN_CFG_TATTR_M)
#define PAS_DMA_TXCHAN_CFG_WT_M 0x000001c0
#define PAS_DMA_TXCHAN_CFG_WT_S 6
#define PAS_DMA_TXCHAN_CFG_WT(x) (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
PAS_DMA_TXCHAN_CFG_WT_M)
#define PAS_DMA_TXCHAN_CFG_LPSQ_FAST 0x00000400
#define PAS_DMA_TXCHAN_CFG_LPDQ_FAST 0x00000800
#define PAS_DMA_TXCHAN_CFG_CF 0x00001000 /* Clean first line */
#define PAS_DMA_TXCHAN_CFG_CL 0x00002000 /* Clean last line */
#define PAS_DMA_TXCHAN_CFG_UP 0x00004000 /* update tx descr when sent */
#define PAS_DMA_TXCHAN_INCR(c) (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE)
#define PAS_DMA_TXCHAN_BASEL(c) (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE)
#define PAS_DMA_TXCHAN_BASEL_BRBL_M 0xffffffc0
#define PAS_DMA_TXCHAN_BASEL_BRBL_S 0
#define PAS_DMA_TXCHAN_BASEL_BRBL(x) (((x) << PAS_DMA_TXCHAN_BASEL_BRBL_S) & \
PAS_DMA_TXCHAN_BASEL_BRBL_M)
#define PAS_DMA_TXCHAN_BASEU(c) (0x31c+(c)*_PAS_DMA_TXCHAN_STRIDE)
#define PAS_DMA_TXCHAN_BASEU_BRBH_M 0x00000fff
#define PAS_DMA_TXCHAN_BASEU_BRBH_S 0
#define PAS_DMA_TXCHAN_BASEU_BRBH(x) (((x) << PAS_DMA_TXCHAN_BASEU_BRBH_S) & \
PAS_DMA_TXCHAN_BASEU_BRBH_M)
/* # of cache lines worth of buffer ring */
#define PAS_DMA_TXCHAN_BASEU_SIZ_M 0x3fff0000
#define PAS_DMA_TXCHAN_BASEU_SIZ_S 16 /* 0 = 16K */
#define PAS_DMA_TXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_TXCHAN_BASEU_SIZ_S) & \
PAS_DMA_TXCHAN_BASEU_SIZ_M)
#define PAS_STATUS_PCNT_M 0x000000000000ffffull
#define PAS_STATUS_PCNT_S 0
#define PAS_STATUS_DCNT_M 0x00000000ffff0000ull
#define PAS_STATUS_DCNT_S 16
#define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull
#define PAS_STATUS_BPCNT_S 32
#define PAS_STATUS_CAUSE_M 0xf000000000000000ull
#define PAS_STATUS_TIMER 0x1000000000000000ull
#define PAS_STATUS_ERROR 0x2000000000000000ull
#define PAS_STATUS_SOFT 0x4000000000000000ull
#define PAS_STATUS_INT 0x8000000000000000ull
#define PAS_IOB_DMA_RXCH_CFG(i) (0x1100 + (i)*4)
#define PAS_IOB_DMA_RXCH_CFG_CNTTH_M 0x00000fff
#define PAS_IOB_DMA_RXCH_CFG_CNTTH_S 0
#define PAS_IOB_DMA_RXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_RXCH_CFG_CNTTH_S) & \
PAS_IOB_DMA_RXCH_CFG_CNTTH_M)
#define PAS_IOB_DMA_TXCH_CFG(i) (0x1200 + (i)*4)
#define PAS_IOB_DMA_TXCH_CFG_CNTTH_M 0x00000fff
#define PAS_IOB_DMA_TXCH_CFG_CNTTH_S 0
#define PAS_IOB_DMA_TXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_TXCH_CFG_CNTTH_S) & \
PAS_IOB_DMA_TXCH_CFG_CNTTH_M)
#define PAS_IOB_DMA_RXCH_STAT(i) (0x1300 + (i)*4)
#define PAS_IOB_DMA_RXCH_STAT_INTGEN 0x00001000
#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_M 0x00000fff
#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_S 0
#define PAS_IOB_DMA_RXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_RXCH_STAT_CNTDEL_S) &\
PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
#define PAS_IOB_DMA_TXCH_STAT(i) (0x1400 + (i)*4)
#define PAS_IOB_DMA_TXCH_STAT_INTGEN 0x00001000
#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_M 0x00000fff
#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_S 0
#define PAS_IOB_DMA_TXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_TXCH_STAT_CNTDEL_S) &\
PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
#define PAS_IOB_DMA_RXCH_RESET(i) (0x1500 + (i)*4)
#define PAS_IOB_DMA_RXCH_RESET_PCNT_M 0xffff0000
#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 16
#define PAS_IOB_DMA_RXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \
PAS_IOB_DMA_RXCH_RESET_PCNT_M)
#define PAS_IOB_DMA_RXCH_RESET_PCNTRST 0x00000020
#define PAS_IOB_DMA_RXCH_RESET_DCNTRST 0x00000010
#define PAS_IOB_DMA_RXCH_RESET_TINTC 0x00000008
#define PAS_IOB_DMA_RXCH_RESET_DINTC 0x00000004
#define PAS_IOB_DMA_RXCH_RESET_SINTC 0x00000002
#define PAS_IOB_DMA_RXCH_RESET_PINTC 0x00000001
#define PAS_IOB_DMA_TXCH_RESET(i) (0x1600 + (i)*4)
#define PAS_IOB_DMA_TXCH_RESET_PCNT_M 0xffff0000
#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 16
#define PAS_IOB_DMA_TXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \
PAS_IOB_DMA_TXCH_RESET_PCNT_M)
#define PAS_IOB_DMA_TXCH_RESET_PCNTRST 0x00000020
#define PAS_IOB_DMA_TXCH_RESET_DCNTRST 0x00000010
#define PAS_IOB_DMA_TXCH_RESET_TINTC 0x00000008
#define PAS_IOB_DMA_TXCH_RESET_DINTC 0x00000004
#define PAS_IOB_DMA_TXCH_RESET_SINTC 0x00000002
#define PAS_IOB_DMA_TXCH_RESET_PINTC 0x00000001
#define PAS_IOB_DMA_COM_TIMEOUTCFG 0x1700
#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M 0x00ffffff
#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S 0
#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(x) (((x) << PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S) & \
PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M)
/* Transmit descriptor fields */
#define XCT_MACTX_T 0x8000000000000000ull
#define XCT_MACTX_ST 0x4000000000000000ull
#define XCT_MACTX_NORES 0x0000000000000000ull
#define XCT_MACTX_8BRES 0x1000000000000000ull
#define XCT_MACTX_24BRES 0x2000000000000000ull
#define XCT_MACTX_40BRES 0x3000000000000000ull
#define XCT_MACTX_I 0x0800000000000000ull
#define XCT_MACTX_O 0x0400000000000000ull
#define XCT_MACTX_E 0x0200000000000000ull
#define XCT_MACTX_VLAN_M 0x0180000000000000ull
#define XCT_MACTX_VLAN_NOP 0x0000000000000000ull
#define XCT_MACTX_VLAN_REMOVE 0x0080000000000000ull
#define XCT_MACTX_VLAN_INSERT 0x0100000000000000ull
#define XCT_MACTX_VLAN_REPLACE 0x0180000000000000ull
#define XCT_MACTX_CRC_M 0x0060000000000000ull
#define XCT_MACTX_CRC_NOP 0x0000000000000000ull
#define XCT_MACTX_CRC_INSERT 0x0020000000000000ull
#define XCT_MACTX_CRC_PAD 0x0040000000000000ull
#define XCT_MACTX_CRC_REPLACE 0x0060000000000000ull
#define XCT_MACTX_SS 0x0010000000000000ull
#define XCT_MACTX_LLEN_M 0x00007fff00000000ull
#define XCT_MACTX_LLEN_S 32ull
#define XCT_MACTX_LLEN(x) ((((long)(x)) << XCT_MACTX_LLEN_S) & \
XCT_MACTX_LLEN_M)
#define XCT_MACTX_IPH_M 0x00000000f8000000ull
#define XCT_MACTX_IPH_S 27ull
#define XCT_MACTX_IPH(x) ((((long)(x)) << XCT_MACTX_IPH_S) & \
XCT_MACTX_IPH_M)
#define XCT_MACTX_IPO_M 0x0000000007c00000ull
#define XCT_MACTX_IPO_S 22ull
#define XCT_MACTX_IPO(x) ((((long)(x)) << XCT_MACTX_IPO_S) & \
XCT_MACTX_IPO_M)
#define XCT_MACTX_CSUM_M 0x0000000000000060ull
#define XCT_MACTX_CSUM_NOP 0x0000000000000000ull
#define XCT_MACTX_CSUM_TCP 0x0000000000000040ull
#define XCT_MACTX_CSUM_UDP 0x0000000000000060ull
#define XCT_MACTX_V6 0x0000000000000010ull
#define XCT_MACTX_C 0x0000000000000004ull
#define XCT_MACTX_AL2 0x0000000000000002ull
#define XCT_PTR_T 0x8000000000000000ull
#define XCT_PTR_LEN_M 0x7ffff00000000000ull
#define XCT_PTR_LEN_S 44
#define XCT_PTR_LEN(x) ((((long)(x)) << XCT_PTR_LEN_S) & \
XCT_PTR_LEN_M)
#define XCT_PTR_ADDR_M 0x00000fffffffffffull
#define XCT_PTR_ADDR_S 0
#define XCT_PTR_ADDR(x) ((((long)(x)) << XCT_PTR_ADDR_S) & \
XCT_PTR_ADDR_M)
/* Function descriptor fields */
#define XCT_FUN_T 0x8000000000000000ull
#define XCT_FUN_ST 0x4000000000000000ull
#define XCT_FUN_NORES 0x0000000000000000ull
#define XCT_FUN_8BRES 0x1000000000000000ull
#define XCT_FUN_24BRES 0x2000000000000000ull
#define XCT_FUN_40BRES 0x3000000000000000ull
#define XCT_FUN_I 0x0800000000000000ull
#define XCT_FUN_O 0x0400000000000000ull
#define XCT_FUN_E 0x0200000000000000ull
#define XCT_FUN_FUN_S 54
#define XCT_FUN_FUN_M 0x01c0000000000000ull
#define XCT_FUN_FUN(num) ((((long)(num)) << XCT_FUN_FUN_S) & \
XCT_FUN_FUN_M)
#define XCT_FUN_CRM_NOP 0x0000000000000000ull
#define XCT_FUN_CRM_SIG 0x0008000000000000ull
#define XCT_FUN_CRM_ENC 0x0010000000000000ull
#define XCT_FUN_CRM_DEC 0x0018000000000000ull
#define XCT_FUN_CRM_SIG_ENC 0x0020000000000000ull
#define XCT_FUN_CRM_ENC_SIG 0x0028000000000000ull
#define XCT_FUN_CRM_SIG_DEC 0x0030000000000000ull
#define XCT_FUN_CRM_DEC_SIG 0x0038000000000000ull
#define XCT_FUN_LLEN_M 0x0007ffff00000000ull
#define XCT_FUN_LLEN_S 32ULL
#define XCT_FUN_LLEN(x) ((((long)(x)) << XCT_FUN_LLEN_S) & \
XCT_FUN_LLEN_M)
#define XCT_FUN_SHL_M 0x00000000f8000000ull
#define XCT_FUN_SHL_S 27ull
#define XCT_FUN_SHL(x) ((((long)(x)) << XCT_FUN_SHL_S) & \
XCT_FUN_SHL_M)
#define XCT_FUN_CHL_M 0x0000000007c00000ull
#define XCT_FUN_CHL_S 22ull
#define XCT_FUN_CHL(x) ((((long)(x)) << XCT_FUN_CHL_S) & \
XCT_FUN_CHL_M)
#define XCT_FUN_HSZ_M 0x00000000003c0000ull
#define XCT_FUN_HSZ_S 18ull
#define XCT_FUN_HSZ(x) ((((long)(x)) << XCT_FUN_HSZ_S) & \
XCT_FUN_HSZ_M)
#define XCT_FUN_ALG_DES 0x0000000000000000ull
#define XCT_FUN_ALG_3DES 0x0000000000008000ull
#define XCT_FUN_ALG_AES 0x0000000000010000ull
#define XCT_FUN_ALG_ARC 0x0000000000018000ull
#define XCT_FUN_ALG_KASUMI 0x0000000000020000ull
#define XCT_FUN_BCM_ECB 0x0000000000000000ull
#define XCT_FUN_BCM_CBC 0x0000000000001000ull
#define XCT_FUN_BCM_CFB 0x0000000000002000ull
#define XCT_FUN_BCM_OFB 0x0000000000003000ull
#define XCT_FUN_BCM_CNT 0x0000000000003800ull
#define XCT_FUN_BCM_KAS_F8 0x0000000000002800ull
#define XCT_FUN_BCM_KAS_F9 0x0000000000001800ull
#define XCT_FUN_BCP_NO_PAD 0x0000000000000000ull
#define XCT_FUN_BCP_ZRO 0x0000000000000200ull
#define XCT_FUN_BCP_PL 0x0000000000000400ull
#define XCT_FUN_BCP_INCR 0x0000000000000600ull
#define XCT_FUN_SIG_MD5 (0ull << 4)
#define XCT_FUN_SIG_SHA1 (2ull << 4)
#define XCT_FUN_SIG_HMAC_MD5 (8ull << 4)
#define XCT_FUN_SIG_HMAC_SHA1 (10ull << 4)
#define XCT_FUN_A 0x0000000000000008ull
#define XCT_FUN_C 0x0000000000000004ull
#define XCT_FUN_AL2 0x0000000000000002ull
#define XCT_FUN_SE 0x0000000000000001ull
#define XCT_FUN_SRC_PTR(len, addr) (XCT_PTR_LEN(len) | XCT_PTR_ADDR(addr))
#define XCT_FUN_DST_PTR(len, addr) (XCT_FUN_SRC_PTR(len, addr) | \
0x8000000000000000ull)
#define XCT_CTRL_HDR_FUN_NUM_M 0x01c0000000000000ull
#define XCT_CTRL_HDR_FUN_NUM_S 54
#define XCT_CTRL_HDR_LEN_M 0x0007ffff00000000ull
#define XCT_CTRL_HDR_LEN_S 32
#define XCT_CTRL_HDR_REG_M 0x00000000000000ffull
#define XCT_CTRL_HDR_REG_S 0
#define XCT_CTRL_HDR(funcN,len,reg) (0x9400000000000000ull | \
((((long)(funcN)) << XCT_CTRL_HDR_FUN_NUM_S) \
& XCT_CTRL_HDR_FUN_NUM_M) | \
((((long)(len)) << \
XCT_CTRL_HDR_LEN_S) & XCT_CTRL_HDR_LEN_M) | \
((((long)(reg)) << \
XCT_CTRL_HDR_REG_S) & XCT_CTRL_HDR_REG_M))
/* Function config command options */
#define DMA_CALGO_DES 0x00
#define DMA_CALGO_3DES 0x01
#define DMA_CALGO_AES 0x02
#define DMA_CALGO_ARC 0x03
#define DMA_FN_CIV0 0x02
#define DMA_FN_CIV1 0x03
#define DMA_FN_HKEY0 0x0a
#define XCT_PTR_ADDR_LEN(ptr) ((ptr) & XCT_PTR_ADDR_M), \
(((ptr) & XCT_PTR_LEN_M) >> XCT_PTR_LEN_S)
#endif /* PASEMI_FNU_H */

View file

@ -0,0 +1,317 @@
/*
* A system independant way of adding entropy to the kernels pool
* this way the drivers can focus on the real work and we can take
* care of pushing it to the appropriate place in the kernel.
*
* This should be fast and callable from timers/interrupts
*
* Written by David McCullough <david_mccullough@securecomputing.com>
* Copyright (C) 2006-2007 David McCullough
* Copyright (C) 2004-2005 Intel Corporation.
*
* LICENSE TERMS
*
* The free distribution and use of this software in both source and binary
* form is allowed (with or without changes) provided that:
*
* 1. distributions of this source code include the above copyright
* notice, this list of conditions and the following disclaimer;
*
* 2. distributions in binary form include the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other associated materials;
*
* 3. the copyright holder's name is not used to endorse products
* built using this software without specific written permission.
*
* ALTERNATIVELY, provided that this notice is retained in full, this product
* may be distributed under the terms of the GNU General Public License (GPL),
* in which case the provisions of the GPL apply INSTEAD OF those given above.
*
* DISCLAIMER
*
* This software is provided 'as is' with no explicit or implied warranties
* in respect of its properties, including, but not limited to, correctness
* and/or fitness for purpose.
*/
#ifndef AUTOCONF_INCLUDED
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/version.h>
#include <linux/unistd.h>
#include <linux/poll.h>
#include <linux/random.h>
#include <cryptodev.h>
#ifdef CONFIG_OCF_FIPS
#include "rndtest.h"
#endif
#ifndef HAS_RANDOM_INPUT_WAIT
#error "Please do not enable OCF_RANDOMHARVEST unless you have applied patches"
#endif
/*
* a hack to access the debug levels from the crypto driver
*/
extern int crypto_debug;
#define debug crypto_debug
/*
* a list of all registered random providers
*/
static LIST_HEAD(random_ops);
static int started = 0;
static int initted = 0;
struct random_op {
struct list_head random_list;
u_int32_t driverid;
int (*read_random)(void *arg, u_int32_t *buf, int len);
void *arg;
};
static int random_proc(void *arg);
static pid_t randomproc = (pid_t) -1;
static spinlock_t random_lock;
/*
* just init the spin locks
*/
static int
crypto_random_init(void)
{
spin_lock_init(&random_lock);
initted = 1;
return(0);
}
/*
* Add the given random reader to our list (if not present)
* and start the thread (if not already started)
*
* we have to assume that driver id is ok for now
*/
int
crypto_rregister(
u_int32_t driverid,
int (*read_random)(void *arg, u_int32_t *buf, int len),
void *arg)
{
unsigned long flags;
int ret = 0;
struct random_op *rops, *tmp;
dprintk("%s,%d: %s(0x%x, %p, %p)\n", __FILE__, __LINE__,
__FUNCTION__, driverid, read_random, arg);
if (!initted)
crypto_random_init();
#if 0
struct cryptocap *cap;
cap = crypto_checkdriver(driverid);
if (!cap)
return EINVAL;
#endif
list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
if (rops->driverid == driverid && rops->read_random == read_random)
return EEXIST;
}
rops = (struct random_op *) kmalloc(sizeof(*rops), GFP_KERNEL);
if (!rops)
return ENOMEM;
rops->driverid = driverid;
rops->read_random = read_random;
rops->arg = arg;
spin_lock_irqsave(&random_lock, flags);
list_add_tail(&rops->random_list, &random_ops);
if (!started) {
randomproc = kernel_thread(random_proc, NULL, CLONE_FS|CLONE_FILES);
if (randomproc < 0) {
ret = randomproc;
printk("crypto: crypto_rregister cannot start random thread; "
"error %d", ret);
} else
started = 1;
}
spin_unlock_irqrestore(&random_lock, flags);
return ret;
}
EXPORT_SYMBOL(crypto_rregister);
int
crypto_runregister_all(u_int32_t driverid)
{
struct random_op *rops, *tmp;
unsigned long flags;
dprintk("%s,%d: %s(0x%x)\n", __FILE__, __LINE__, __FUNCTION__, driverid);
list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
if (rops->driverid == driverid) {
list_del(&rops->random_list);
kfree(rops);
}
}
spin_lock_irqsave(&random_lock, flags);
if (list_empty(&random_ops) && started)
kill_proc(randomproc, SIGKILL, 1);
spin_unlock_irqrestore(&random_lock, flags);
return(0);
}
EXPORT_SYMBOL(crypto_runregister_all);
/*
* while we can add entropy to random.c continue to read random data from
* the drivers and push it to random.
*/
static int
random_proc(void *arg)
{
int n;
int wantcnt;
int bufcnt = 0;
int retval = 0;
int *buf = NULL;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
daemonize();
spin_lock_irq(&current->sigmask_lock);
sigemptyset(&current->blocked);
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
sprintf(current->comm, "ocf-random");
#else
daemonize("ocf-random");
allow_signal(SIGKILL);
#endif
(void) get_fs();
set_fs(get_ds());
#ifdef CONFIG_OCF_FIPS
#define NUM_INT (RNDTEST_NBYTES/sizeof(int))
#else
#define NUM_INT 32
#endif
/*
* some devices can transferr their RNG data direct into memory,
* so make sure it is device friendly
*/
buf = kmalloc(NUM_INT * sizeof(int), GFP_DMA);
if (NULL == buf) {
printk("crypto: RNG could not allocate memory\n");
retval = -ENOMEM;
goto bad_alloc;
}
wantcnt = NUM_INT; /* start by adding some entropy */
/*
* its possible due to errors or driver removal that we no longer
* have anything to do, if so exit or we will consume all the CPU
* doing nothing
*/
while (!list_empty(&random_ops)) {
struct random_op *rops, *tmp;
#ifdef CONFIG_OCF_FIPS
if (wantcnt)
wantcnt = NUM_INT; /* FIPs mode can do 20000 bits or none */
#endif
/* see if we can get enough entropy to make the world
* a better place.
*/
while (bufcnt < wantcnt && bufcnt < NUM_INT) {
list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
n = (*rops->read_random)(rops->arg, &buf[bufcnt],
NUM_INT - bufcnt);
/* on failure remove the random number generator */
if (n == -1) {
list_del(&rops->random_list);
printk("crypto: RNG (driverid=0x%x) failed, disabling\n",
rops->driverid);
kfree(rops);
} else if (n > 0)
bufcnt += n;
}
/* give up CPU for a bit, just in case as this is a loop */
schedule();
}
#ifdef CONFIG_OCF_FIPS
if (bufcnt > 0 && rndtest_buf((unsigned char *) &buf[0])) {
dprintk("crypto: buffer had fips errors, discarding\n");
bufcnt = 0;
}
#endif
/*
* if we have a certified buffer, we can send some data
* to /dev/random and move along
*/
if (bufcnt > 0) {
/* add what we have */
random_input_words(buf, bufcnt, bufcnt*sizeof(int)*8);
bufcnt = 0;
}
/* give up CPU for a bit so we don't hog while filling */
schedule();
/* wait for needing more */
wantcnt = random_input_wait();
if (wantcnt <= 0)
wantcnt = 0; /* try to get some info again */
else
/* round up to one word or we can loop forever */
wantcnt = (wantcnt + (sizeof(int)*8)) / (sizeof(int)*8);
if (wantcnt > NUM_INT) {
wantcnt = NUM_INT;
}
if (signal_pending(current)) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
spin_lock_irq(&current->sigmask_lock);
#endif
flush_signals(current);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
spin_unlock_irq(&current->sigmask_lock);
#endif
}
}
kfree(buf);
bad_alloc:
spin_lock_irq(&random_lock);
randomproc = (pid_t) -1;
started = 0;
spin_unlock_irq(&random_lock);
return retval;
}

View file

@ -0,0 +1,300 @@
/* $OpenBSD$ */
/*
* OCF/Linux port done by David McCullough <david_mccullough@securecomputing.com>
* Copyright (C) 2006-2007 David McCullough
* Copyright (C) 2004-2005 Intel Corporation.
* The license and original author are listed below.
*
* Copyright (c) 2002 Jason L. Wright (jason@thought.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jason L. Wright
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef AUTOCONF_INCLUDED
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/list.h>
#include <linux/wait.h>
#include <linux/time.h>
#include <linux/version.h>
#include <linux/unistd.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/time.h>
#include <cryptodev.h>
#include "rndtest.h"
static struct rndtest_stats rndstats;
static void rndtest_test(struct rndtest_state *);
/* The tests themselves */
static int rndtest_monobit(struct rndtest_state *);
static int rndtest_runs(struct rndtest_state *);
static int rndtest_longruns(struct rndtest_state *);
static int rndtest_chi_4(struct rndtest_state *);
static int rndtest_runs_check(struct rndtest_state *, int, int *);
static void rndtest_runs_record(struct rndtest_state *, int, int *);
static const struct rndtest_testfunc {
int (*test)(struct rndtest_state *);
} rndtest_funcs[] = {
{ rndtest_monobit },
{ rndtest_runs },
{ rndtest_chi_4 },
{ rndtest_longruns },
};
#define RNDTEST_NTESTS (sizeof(rndtest_funcs)/sizeof(rndtest_funcs[0]))
static void
rndtest_test(struct rndtest_state *rsp)
{
int i, rv = 0;
rndstats.rst_tests++;
for (i = 0; i < RNDTEST_NTESTS; i++)
rv |= (*rndtest_funcs[i].test)(rsp);
rsp->rs_discard = (rv != 0);
}
extern int crypto_debug;
#define rndtest_verbose 2
#define rndtest_report(rsp, failure, fmt, a...) \
{ if (failure || crypto_debug) { printk("rng_test: " fmt "\n", a); } else; }
#define RNDTEST_MONOBIT_MINONES 9725
#define RNDTEST_MONOBIT_MAXONES 10275
static int
rndtest_monobit(struct rndtest_state *rsp)
{
int i, ones = 0, j;
u_int8_t r;
for (i = 0; i < RNDTEST_NBYTES; i++) {
r = rsp->rs_buf[i];
for (j = 0; j < 8; j++, r <<= 1)
if (r & 0x80)
ones++;
}
if (ones > RNDTEST_MONOBIT_MINONES &&
ones < RNDTEST_MONOBIT_MAXONES) {
if (rndtest_verbose > 1)
rndtest_report(rsp, 0, "monobit pass (%d < %d < %d)",
RNDTEST_MONOBIT_MINONES, ones,
RNDTEST_MONOBIT_MAXONES);
return (0);
} else {
if (rndtest_verbose)
rndtest_report(rsp, 1,
"monobit failed (%d ones)", ones);
rndstats.rst_monobit++;
return (-1);
}
}
#define RNDTEST_RUNS_NINTERVAL 6
static const struct rndtest_runs_tabs {
u_int16_t min, max;
} rndtest_runs_tab[] = {
{ 2343, 2657 },
{ 1135, 1365 },
{ 542, 708 },
{ 251, 373 },
{ 111, 201 },
{ 111, 201 },
};
static int
rndtest_runs(struct rndtest_state *rsp)
{
int i, j, ones, zeros, rv = 0;
int onei[RNDTEST_RUNS_NINTERVAL], zeroi[RNDTEST_RUNS_NINTERVAL];
u_int8_t c;
bzero(onei, sizeof(onei));
bzero(zeroi, sizeof(zeroi));
ones = zeros = 0;
for (i = 0; i < RNDTEST_NBYTES; i++) {
c = rsp->rs_buf[i];
for (j = 0; j < 8; j++, c <<= 1) {
if (c & 0x80) {
ones++;
rndtest_runs_record(rsp, zeros, zeroi);
zeros = 0;
} else {
zeros++;
rndtest_runs_record(rsp, ones, onei);
ones = 0;
}
}
}
rndtest_runs_record(rsp, ones, onei);
rndtest_runs_record(rsp, zeros, zeroi);
rv |= rndtest_runs_check(rsp, 0, zeroi);
rv |= rndtest_runs_check(rsp, 1, onei);
if (rv)
rndstats.rst_runs++;
return (rv);
}
static void
rndtest_runs_record(struct rndtest_state *rsp, int len, int *intrv)
{
if (len == 0)
return;
if (len > RNDTEST_RUNS_NINTERVAL)
len = RNDTEST_RUNS_NINTERVAL;
len -= 1;
intrv[len]++;
}
static int
rndtest_runs_check(struct rndtest_state *rsp, int val, int *src)
{
int i, rv = 0;
for (i = 0; i < RNDTEST_RUNS_NINTERVAL; i++) {
if (src[i] < rndtest_runs_tab[i].min ||
src[i] > rndtest_runs_tab[i].max) {
rndtest_report(rsp, 1,
"%s interval %d failed (%d, %d-%d)",
val ? "ones" : "zeros",
i + 1, src[i], rndtest_runs_tab[i].min,
rndtest_runs_tab[i].max);
rv = -1;
} else {
rndtest_report(rsp, 0,
"runs pass %s interval %d (%d < %d < %d)",
val ? "ones" : "zeros",
i + 1, rndtest_runs_tab[i].min, src[i],
rndtest_runs_tab[i].max);
}
}
return (rv);
}
static int
rndtest_longruns(struct rndtest_state *rsp)
{
int i, j, ones = 0, zeros = 0, maxones = 0, maxzeros = 0;
u_int8_t c;
for (i = 0; i < RNDTEST_NBYTES; i++) {
c = rsp->rs_buf[i];
for (j = 0; j < 8; j++, c <<= 1) {
if (c & 0x80) {
zeros = 0;
ones++;
if (ones > maxones)
maxones = ones;
} else {
ones = 0;
zeros++;
if (zeros > maxzeros)
maxzeros = zeros;
}
}
}
if (maxones < 26 && maxzeros < 26) {
rndtest_report(rsp, 0, "longruns pass (%d ones, %d zeros)",
maxones, maxzeros);
return (0);
} else {
rndtest_report(rsp, 1, "longruns fail (%d ones, %d zeros)",
maxones, maxzeros);
rndstats.rst_longruns++;
return (-1);
}
}
/*
* chi^2 test over 4 bits: (this is called the poker test in FIPS 140-2,
* but it is really the chi^2 test over 4 bits (the poker test as described
* by Knuth vol 2 is something different, and I take him as authoritative
* on nomenclature over NIST).
*/
#define RNDTEST_CHI4_K 16
#define RNDTEST_CHI4_K_MASK (RNDTEST_CHI4_K - 1)
/*
* The unnormalized values are used so that we don't have to worry about
* fractional precision. The "real" value is found by:
* (V - 1562500) * (16 / 5000) = Vn (where V is the unnormalized value)
*/
#define RNDTEST_CHI4_VMIN 1563181 /* 2.1792 */
#define RNDTEST_CHI4_VMAX 1576929 /* 46.1728 */
static int
rndtest_chi_4(struct rndtest_state *rsp)
{
unsigned int freq[RNDTEST_CHI4_K], i, sum;
for (i = 0; i < RNDTEST_CHI4_K; i++)
freq[i] = 0;
/* Get number of occurances of each 4 bit pattern */
for (i = 0; i < RNDTEST_NBYTES; i++) {
freq[(rsp->rs_buf[i] >> 4) & RNDTEST_CHI4_K_MASK]++;
freq[(rsp->rs_buf[i] >> 0) & RNDTEST_CHI4_K_MASK]++;
}
for (i = 0, sum = 0; i < RNDTEST_CHI4_K; i++)
sum += freq[i] * freq[i];
if (sum >= 1563181 && sum <= 1576929) {
rndtest_report(rsp, 0, "chi^2(4): pass (sum %u)", sum);
return (0);
} else {
rndtest_report(rsp, 1, "chi^2(4): failed (sum %u)", sum);
rndstats.rst_chi++;
return (-1);
}
}
int
rndtest_buf(unsigned char *buf)
{
struct rndtest_state rsp;
memset(&rsp, 0, sizeof(rsp));
rsp.rs_buf = buf;
rndtest_test(&rsp);
return(rsp.rs_discard);
}

View file

@ -0,0 +1,54 @@
/* $FreeBSD: src/sys/dev/rndtest/rndtest.h,v 1.1 2003/03/11 22:54:44 sam Exp $ */
/* $OpenBSD$ */
/*
* Copyright (c) 2002 Jason L. Wright (jason@thought.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jason L. Wright
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* Some of the tests depend on these values */
#define RNDTEST_NBYTES 2500
#define RNDTEST_NBITS (8 * RNDTEST_NBYTES)
struct rndtest_state {
int rs_discard; /* discard/accept random data */
u_int8_t *rs_buf;
};
struct rndtest_stats {
u_int32_t rst_discard; /* number of bytes discarded */
u_int32_t rst_tests; /* number of test runs */
u_int32_t rst_monobit; /* monobit test failures */
u_int32_t rst_runs; /* 0/1 runs failures */
u_int32_t rst_longruns; /* longruns failures */
u_int32_t rst_chi; /* chi^2 failures */
};
extern int rndtest_buf(unsigned char *buf);

View file

@ -0,0 +1,12 @@
# for SGlinux builds
-include $(ROOTDIR)/modules/.config
obj-$(CONFIG_OCF_SAFE) += safe.o
obj ?= .
EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
ifdef TOPDIR
-include $(TOPDIR)/Rules.make
endif

View file

@ -0,0 +1,308 @@
/* $KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/crypto/md5.c,v 1.9 2004/01/27 19:49:19 des Exp $");
#include <sys/types.h>
#include <sys/cdefs.h>
#include <sys/time.h>
#include <sys/systm.h>
#include <crypto/md5.h>
#endif
#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
#define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
#define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
#define ROUND1(a, b, c, d, k, s, i) { \
(a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
(a) = SHIFT((a), (s)); \
(a) = (b) + (a); \
}
#define ROUND2(a, b, c, d, k, s, i) { \
(a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
(a) = SHIFT((a), (s)); \
(a) = (b) + (a); \
}
#define ROUND3(a, b, c, d, k, s, i) { \
(a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
(a) = SHIFT((a), (s)); \
(a) = (b) + (a); \
}
#define ROUND4(a, b, c, d, k, s, i) { \
(a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
(a) = SHIFT((a), (s)); \
(a) = (b) + (a); \
}
#define Sa 7
#define Sb 12
#define Sc 17
#define Sd 22
#define Se 5
#define Sf 9
#define Sg 14
#define Sh 20
#define Si 4
#define Sj 11
#define Sk 16
#define Sl 23
#define Sm 6
#define Sn 10
#define So 15
#define Sp 21
#define MD5_A0 0x67452301
#define MD5_B0 0xefcdab89
#define MD5_C0 0x98badcfe
#define MD5_D0 0x10325476
/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
static const u_int32_t T[65] = {
0,
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
};
static const u_int8_t md5_paddat[MD5_BUFLEN] = {
0x80, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
static void md5_calc(u_int8_t *, md5_ctxt *);
void md5_init(ctxt)
md5_ctxt *ctxt;
{
ctxt->md5_n = 0;
ctxt->md5_i = 0;
ctxt->md5_sta = MD5_A0;
ctxt->md5_stb = MD5_B0;
ctxt->md5_stc = MD5_C0;
ctxt->md5_std = MD5_D0;
bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
}
void md5_loop(ctxt, input, len)
md5_ctxt *ctxt;
u_int8_t *input;
u_int len; /* number of bytes */
{
u_int gap, i;
ctxt->md5_n += len * 8; /* byte to bit */
gap = MD5_BUFLEN - ctxt->md5_i;
if (len >= gap) {
bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
gap);
md5_calc(ctxt->md5_buf, ctxt);
for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
md5_calc((u_int8_t *)(input + i), ctxt);
}
ctxt->md5_i = len - i;
bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
} else {
bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
len);
ctxt->md5_i += len;
}
}
void md5_pad(ctxt)
md5_ctxt *ctxt;
{
u_int gap;
/* Don't count up padding. Keep md5_n. */
gap = MD5_BUFLEN - ctxt->md5_i;
if (gap > 8) {
bcopy(md5_paddat,
(void *)(ctxt->md5_buf + ctxt->md5_i),
gap - sizeof(ctxt->md5_n));
} else {
/* including gap == 8 */
bcopy(md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
gap);
md5_calc(ctxt->md5_buf, ctxt);
bcopy((md5_paddat + gap),
(void *)ctxt->md5_buf,
MD5_BUFLEN - sizeof(ctxt->md5_n));
}
/* 8 byte word */
#if BYTE_ORDER == LITTLE_ENDIAN
bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
#endif
#if BYTE_ORDER == BIG_ENDIAN
ctxt->md5_buf[56] = ctxt->md5_n8[7];
ctxt->md5_buf[57] = ctxt->md5_n8[6];
ctxt->md5_buf[58] = ctxt->md5_n8[5];
ctxt->md5_buf[59] = ctxt->md5_n8[4];
ctxt->md5_buf[60] = ctxt->md5_n8[3];
ctxt->md5_buf[61] = ctxt->md5_n8[2];
ctxt->md5_buf[62] = ctxt->md5_n8[1];
ctxt->md5_buf[63] = ctxt->md5_n8[0];
#endif
md5_calc(ctxt->md5_buf, ctxt);
}
void md5_result(digest, ctxt)
u_int8_t *digest;
md5_ctxt *ctxt;
{
/* 4 byte words */
#if BYTE_ORDER == LITTLE_ENDIAN
bcopy(&ctxt->md5_st8[0], digest, 16);
#endif
#if BYTE_ORDER == BIG_ENDIAN
digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
#endif
}
static void md5_calc(b64, ctxt)
u_int8_t *b64;
md5_ctxt *ctxt;
{
u_int32_t A = ctxt->md5_sta;
u_int32_t B = ctxt->md5_stb;
u_int32_t C = ctxt->md5_stc;
u_int32_t D = ctxt->md5_std;
#if BYTE_ORDER == LITTLE_ENDIAN
u_int32_t *X = (u_int32_t *)b64;
#endif
#if BYTE_ORDER == BIG_ENDIAN
/* 4 byte words */
/* what a brute force but fast! */
u_int32_t X[16];
u_int8_t *y = (u_int8_t *)X;
y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
#endif
ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2);
ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4);
ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6);
ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8);
ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10);
ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24);
ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28);
ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30);
ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34);
ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38);
ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42);
ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);
ctxt->md5_sta += A;
ctxt->md5_stb += B;
ctxt->md5_stc += C;
ctxt->md5_std += D;
}

View file

@ -0,0 +1,76 @@
/* $FreeBSD: src/sys/crypto/md5.h,v 1.4 2002/03/20 05:13:50 alfred Exp $ */
/* $KAME: md5.h,v 1.4 2000/03/27 04:36:22 sumikawa Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _NETINET6_MD5_H_
#define _NETINET6_MD5_H_
#define MD5_BUFLEN 64
typedef struct {
union {
u_int32_t md5_state32[4];
u_int8_t md5_state8[16];
} md5_st;
#define md5_sta md5_st.md5_state32[0]
#define md5_stb md5_st.md5_state32[1]
#define md5_stc md5_st.md5_state32[2]
#define md5_std md5_st.md5_state32[3]
#define md5_st8 md5_st.md5_state8
union {
u_int64_t md5_count64;
u_int8_t md5_count8[8];
} md5_count;
#define md5_n md5_count.md5_count64
#define md5_n8 md5_count.md5_count8
u_int md5_i;
u_int8_t md5_buf[MD5_BUFLEN];
} md5_ctxt;
extern void md5_init(md5_ctxt *);
extern void md5_loop(md5_ctxt *, u_int8_t *, u_int);
extern void md5_pad(md5_ctxt *);
extern void md5_result(u_int8_t *, md5_ctxt *);
/* compatibility */
#define MD5_CTX md5_ctxt
#define MD5Init(x) md5_init((x))
#define MD5Update(x, y, z) md5_loop((x), (y), (z))
#define MD5Final(x, y) \
do { \
md5_pad((y)); \
md5_result((x), (y)); \
} while (0)
#endif /* ! _NETINET6_MD5_H_*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,421 @@
/*-
* Copyright (c) 2003 Sam Leffler, Errno Consulting
* Copyright (c) 2003 Global Technology Associates, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/safe/safereg.h,v 1.1 2003/07/21 21:46:07 sam Exp $
*/
#ifndef _SAFE_SAFEREG_H_
#define _SAFE_SAFEREG_H_
/*
* Register definitions for SafeNet SafeXcel-1141 crypto device.
* Definitions from revision 1.3 (Nov 6 2002) of the User's Manual.
*/
#define BS_BAR 0x10 /* DMA base address register */
#define BS_TRDY_TIMEOUT 0x40 /* TRDY timeout */
#define BS_RETRY_TIMEOUT 0x41 /* DMA retry timeout */
#define PCI_VENDOR_SAFENET 0x16ae /* SafeNet, Inc. */
/* SafeNet */
#define PCI_PRODUCT_SAFEXCEL 0x1141 /* 1141 */
#define SAFE_PE_CSR 0x0000 /* Packet Enginge Ctrl/Status */
#define SAFE_PE_SRC 0x0004 /* Packet Engine Source */
#define SAFE_PE_DST 0x0008 /* Packet Engine Destination */
#define SAFE_PE_SA 0x000c /* Packet Engine SA */
#define SAFE_PE_LEN 0x0010 /* Packet Engine Length */
#define SAFE_PE_DMACFG 0x0040 /* Packet Engine DMA Configuration */
#define SAFE_PE_DMASTAT 0x0044 /* Packet Engine DMA Status */
#define SAFE_PE_PDRBASE 0x0048 /* Packet Engine Descriptor Ring Base */
#define SAFE_PE_RDRBASE 0x004c /* Packet Engine Result Ring Base */
#define SAFE_PE_RINGCFG 0x0050 /* Packet Engine Ring Configuration */
#define SAFE_PE_RINGPOLL 0x0054 /* Packet Engine Ring Poll */
#define SAFE_PE_IRNGSTAT 0x0058 /* Packet Engine Internal Ring Status */
#define SAFE_PE_ERNGSTAT 0x005c /* Packet Engine External Ring Status */
#define SAFE_PE_IOTHRESH 0x0060 /* Packet Engine I/O Threshold */
#define SAFE_PE_GRNGBASE 0x0064 /* Packet Engine Gather Ring Base */
#define SAFE_PE_SRNGBASE 0x0068 /* Packet Engine Scatter Ring Base */
#define SAFE_PE_PARTSIZE 0x006c /* Packet Engine Particlar Ring Size */
#define SAFE_PE_PARTCFG 0x0070 /* Packet Engine Particle Ring Config */
#define SAFE_CRYPTO_CTRL 0x0080 /* Crypto Control */
#define SAFE_DEVID 0x0084 /* Device ID */
#define SAFE_DEVINFO 0x0088 /* Device Info */
#define SAFE_HU_STAT 0x00a0 /* Host Unmasked Status */
#define SAFE_HM_STAT 0x00a4 /* Host Masked Status (read-only) */
#define SAFE_HI_CLR 0x00a4 /* Host Clear Interrupt (write-only) */
#define SAFE_HI_MASK 0x00a8 /* Host Mask Control */
#define SAFE_HI_CFG 0x00ac /* Interrupt Configuration */
#define SAFE_HI_RD_DESCR 0x00b4 /* Force Descriptor Read */
#define SAFE_HI_DESC_CNT 0x00b8 /* Host Descriptor Done Count */
#define SAFE_DMA_ENDIAN 0x00c0 /* Master Endian Status */
#define SAFE_DMA_SRCADDR 0x00c4 /* DMA Source Address Status */
#define SAFE_DMA_DSTADDR 0x00c8 /* DMA Destination Address Status */
#define SAFE_DMA_STAT 0x00cc /* DMA Current Status */
#define SAFE_DMA_CFG 0x00d4 /* DMA Configuration/Status */
#define SAFE_ENDIAN 0x00e0 /* Endian Configuration */
#define SAFE_PK_A_ADDR 0x0800 /* Public Key A Address */
#define SAFE_PK_B_ADDR 0x0804 /* Public Key B Address */
#define SAFE_PK_C_ADDR 0x0808 /* Public Key C Address */
#define SAFE_PK_D_ADDR 0x080c /* Public Key D Address */
#define SAFE_PK_A_LEN 0x0810 /* Public Key A Length */
#define SAFE_PK_B_LEN 0x0814 /* Public Key B Length */
#define SAFE_PK_SHIFT 0x0818 /* Public Key Shift */
#define SAFE_PK_FUNC 0x081c /* Public Key Function */
#define SAFE_PK_RAM_START 0x1000 /* Public Key RAM start address */
#define SAFE_PK_RAM_END 0x1fff /* Public Key RAM end address */
#define SAFE_RNG_OUT 0x0100 /* RNG Output */
#define SAFE_RNG_STAT 0x0104 /* RNG Status */
#define SAFE_RNG_CTRL 0x0108 /* RNG Control */
#define SAFE_RNG_A 0x010c /* RNG A */
#define SAFE_RNG_B 0x0110 /* RNG B */
#define SAFE_RNG_X_LO 0x0114 /* RNG X [31:0] */
#define SAFE_RNG_X_MID 0x0118 /* RNG X [63:32] */
#define SAFE_RNG_X_HI 0x011c /* RNG X [80:64] */
#define SAFE_RNG_X_CNTR 0x0120 /* RNG Counter */
#define SAFE_RNG_ALM_CNT 0x0124 /* RNG Alarm Count */
#define SAFE_RNG_CNFG 0x0128 /* RNG Configuration */
#define SAFE_RNG_LFSR1_LO 0x012c /* RNG LFSR1 [31:0] */
#define SAFE_RNG_LFSR1_HI 0x0130 /* RNG LFSR1 [47:32] */
#define SAFE_RNG_LFSR2_LO 0x0134 /* RNG LFSR1 [31:0] */
#define SAFE_RNG_LFSR2_HI 0x0138 /* RNG LFSR1 [47:32] */
#define SAFE_PE_CSR_READY 0x00000001 /* ready for processing */
#define SAFE_PE_CSR_DONE 0x00000002 /* h/w completed processing */
#define SAFE_PE_CSR_LOADSA 0x00000004 /* load SA digests */
#define SAFE_PE_CSR_HASHFINAL 0x00000010 /* do hash pad & write result */
#define SAFE_PE_CSR_SABUSID 0x000000c0 /* bus id for SA */
#define SAFE_PE_CSR_SAPCI 0x00000040 /* PCI bus id for SA */
#define SAFE_PE_CSR_NXTHDR 0x0000ff00 /* next hdr value for IPsec */
#define SAFE_PE_CSR_FPAD 0x0000ff00 /* fixed pad for basic ops */
#define SAFE_PE_CSR_STATUS 0x00ff0000 /* operation result status */
#define SAFE_PE_CSR_AUTH_FAIL 0x00010000 /* ICV mismatch (inbound) */
#define SAFE_PE_CSR_PAD_FAIL 0x00020000 /* pad verify fail (inbound) */
#define SAFE_PE_CSR_SEQ_FAIL 0x00040000 /* sequence number (inbound) */
#define SAFE_PE_CSR_XERROR 0x00080000 /* extended error follows */
#define SAFE_PE_CSR_XECODE 0x00f00000 /* extended error code */
#define SAFE_PE_CSR_XECODE_S 20
#define SAFE_PE_CSR_XECODE_BADCMD 0 /* invalid command */
#define SAFE_PE_CSR_XECODE_BADALG 1 /* invalid algorithm */
#define SAFE_PE_CSR_XECODE_ALGDIS 2 /* algorithm disabled */
#define SAFE_PE_CSR_XECODE_ZEROLEN 3 /* zero packet length */
#define SAFE_PE_CSR_XECODE_DMAERR 4 /* bus DMA error */
#define SAFE_PE_CSR_XECODE_PIPEABORT 5 /* secondary bus DMA error */
#define SAFE_PE_CSR_XECODE_BADSPI 6 /* IPsec SPI mismatch */
#define SAFE_PE_CSR_XECODE_TIMEOUT 10 /* failsafe timeout */
#define SAFE_PE_CSR_PAD 0xff000000 /* ESP padding control/status */
#define SAFE_PE_CSR_PAD_MIN 0x00000000 /* minimum IPsec padding */
#define SAFE_PE_CSR_PAD_16 0x08000000 /* pad to 16-byte boundary */
#define SAFE_PE_CSR_PAD_32 0x10000000 /* pad to 32-byte boundary */
#define SAFE_PE_CSR_PAD_64 0x20000000 /* pad to 64-byte boundary */
#define SAFE_PE_CSR_PAD_128 0x40000000 /* pad to 128-byte boundary */
#define SAFE_PE_CSR_PAD_256 0x80000000 /* pad to 256-byte boundary */
/*
* Check the CSR to see if the PE has returned ownership to
* the host. Note that before processing a descriptor this
* must be done followed by a check of the SAFE_PE_LEN register
* status bits to avoid premature processing of a descriptor
* on its way back to the host.
*/
#define SAFE_PE_CSR_IS_DONE(_csr) \
(((_csr) & (SAFE_PE_CSR_READY | SAFE_PE_CSR_DONE)) == SAFE_PE_CSR_DONE)
#define SAFE_PE_LEN_LENGTH 0x000fffff /* total length (bytes) */
#define SAFE_PE_LEN_READY 0x00400000 /* ready for processing */
#define SAFE_PE_LEN_DONE 0x00800000 /* h/w completed processing */
#define SAFE_PE_LEN_BYPASS 0xff000000 /* bypass offset (bytes) */
#define SAFE_PE_LEN_BYPASS_S 24
#define SAFE_PE_LEN_IS_DONE(_len) \
(((_len) & (SAFE_PE_LEN_READY | SAFE_PE_LEN_DONE)) == SAFE_PE_LEN_DONE)
/* NB: these apply to HU_STAT, HM_STAT, HI_CLR, and HI_MASK */
#define SAFE_INT_PE_CDONE 0x00000002 /* PE context done */
#define SAFE_INT_PE_DDONE 0x00000008 /* PE descriptor done */
#define SAFE_INT_PE_ERROR 0x00000010 /* PE error */
#define SAFE_INT_PE_ODONE 0x00000020 /* PE operation done */
#define SAFE_HI_CFG_PULSE 0x00000001 /* use pulse interrupt */
#define SAFE_HI_CFG_LEVEL 0x00000000 /* use level interrupt */
#define SAFE_HI_CFG_AUTOCLR 0x00000002 /* auto-clear pulse interrupt */
#define SAFE_ENDIAN_PASS 0x000000e4 /* straight pass-thru */
#define SAFE_ENDIAN_SWAB 0x0000001b /* swap bytes in 32-bit word */
#define SAFE_PE_DMACFG_PERESET 0x00000001 /* reset packet engine */
#define SAFE_PE_DMACFG_PDRRESET 0x00000002 /* reset PDR counters/ptrs */
#define SAFE_PE_DMACFG_SGRESET 0x00000004 /* reset scatter/gather cache */
#define SAFE_PE_DMACFG_FSENA 0x00000008 /* enable failsafe reset */
#define SAFE_PE_DMACFG_PEMODE 0x00000100 /* packet engine mode */
#define SAFE_PE_DMACFG_SAPREC 0x00000200 /* SA precedes packet */
#define SAFE_PE_DMACFG_PKFOLL 0x00000400 /* packet follows descriptor */
#define SAFE_PE_DMACFG_GPRBID 0x00003000 /* gather particle ring busid */
#define SAFE_PE_DMACFG_GPRPCI 0x00001000 /* PCI gather particle ring */
#define SAFE_PE_DMACFG_SPRBID 0x0000c000 /* scatter part. ring busid */
#define SAFE_PE_DMACFG_SPRPCI 0x00004000 /* PCI scatter part. ring */
#define SAFE_PE_DMACFG_ESDESC 0x00010000 /* endian swap descriptors */
#define SAFE_PE_DMACFG_ESSA 0x00020000 /* endian swap SA data */
#define SAFE_PE_DMACFG_ESPACKET 0x00040000 /* endian swap packet data */
#define SAFE_PE_DMACFG_ESPDESC 0x00080000 /* endian swap particle desc. */
#define SAFE_PE_DMACFG_NOPDRUP 0x00100000 /* supp. PDR ownership update */
#define SAFE_PD_EDMACFG_PCIMODE 0x01000000 /* PCI target mode */
#define SAFE_PE_DMASTAT_PEIDONE 0x00000001 /* PE core input done */
#define SAFE_PE_DMASTAT_PEODONE 0x00000002 /* PE core output done */
#define SAFE_PE_DMASTAT_ENCDONE 0x00000004 /* encryption done */
#define SAFE_PE_DMASTAT_IHDONE 0x00000008 /* inner hash done */
#define SAFE_PE_DMASTAT_OHDONE 0x00000010 /* outer hash (HMAC) done */
#define SAFE_PE_DMASTAT_PADFLT 0x00000020 /* crypto pad fault */
#define SAFE_PE_DMASTAT_ICVFLT 0x00000040 /* ICV fault */
#define SAFE_PE_DMASTAT_SPIMIS 0x00000080 /* SPI mismatch */
#define SAFE_PE_DMASTAT_CRYPTO 0x00000100 /* crypto engine timeout */
#define SAFE_PE_DMASTAT_CQACT 0x00000200 /* command queue active */
#define SAFE_PE_DMASTAT_IRACT 0x00000400 /* input request active */
#define SAFE_PE_DMASTAT_ORACT 0x00000800 /* output request active */
#define SAFE_PE_DMASTAT_PEISIZE 0x003ff000 /* PE input size:32-bit words */
#define SAFE_PE_DMASTAT_PEOSIZE 0xffc00000 /* PE out. size:32-bit words */
#define SAFE_PE_RINGCFG_SIZE 0x000003ff /* ring size (descriptors) */
#define SAFE_PE_RINGCFG_OFFSET 0xffff0000 /* offset btw desc's (dwords) */
#define SAFE_PE_RINGCFG_OFFSET_S 16
#define SAFE_PE_RINGPOLL_POLL 0x00000fff /* polling frequency/divisor */
#define SAFE_PE_RINGPOLL_RETRY 0x03ff0000 /* polling frequency/divisor */
#define SAFE_PE_RINGPOLL_CONT 0x80000000 /* continuously poll */
#define SAFE_PE_IRNGSTAT_CQAVAIL 0x00000001 /* command queue available */
#define SAFE_PE_ERNGSTAT_NEXT 0x03ff0000 /* index of next packet desc. */
#define SAFE_PE_ERNGSTAT_NEXT_S 16
#define SAFE_PE_IOTHRESH_INPUT 0x000003ff /* input threshold (dwords) */
#define SAFE_PE_IOTHRESH_OUTPUT 0x03ff0000 /* output threshold (dwords) */
#define SAFE_PE_PARTCFG_SIZE 0x0000ffff /* scatter particle size */
#define SAFE_PE_PARTCFG_GBURST 0x00030000 /* gather particle burst */
#define SAFE_PE_PARTCFG_GBURST_2 0x00000000
#define SAFE_PE_PARTCFG_GBURST_4 0x00010000
#define SAFE_PE_PARTCFG_GBURST_8 0x00020000
#define SAFE_PE_PARTCFG_GBURST_16 0x00030000
#define SAFE_PE_PARTCFG_SBURST 0x000c0000 /* scatter particle burst */
#define SAFE_PE_PARTCFG_SBURST_2 0x00000000
#define SAFE_PE_PARTCFG_SBURST_4 0x00040000
#define SAFE_PE_PARTCFG_SBURST_8 0x00080000
#define SAFE_PE_PARTCFG_SBURST_16 0x000c0000
#define SAFE_PE_PARTSIZE_SCAT 0xffff0000 /* scatter particle ring size */
#define SAFE_PE_PARTSIZE_GATH 0x0000ffff /* gather particle ring size */
#define SAFE_CRYPTO_CTRL_3DES 0x00000001 /* enable 3DES support */
#define SAFE_CRYPTO_CTRL_PKEY 0x00010000 /* enable public key support */
#define SAFE_CRYPTO_CTRL_RNG 0x00020000 /* enable RNG support */
#define SAFE_DEVINFO_REV_MIN 0x0000000f /* minor rev for chip */
#define SAFE_DEVINFO_REV_MAJ 0x000000f0 /* major rev for chip */
#define SAFE_DEVINFO_REV_MAJ_S 4
#define SAFE_DEVINFO_DES 0x00000100 /* DES/3DES support present */
#define SAFE_DEVINFO_ARC4 0x00000200 /* ARC4 support present */
#define SAFE_DEVINFO_AES 0x00000400 /* AES support present */
#define SAFE_DEVINFO_MD5 0x00001000 /* MD5 support present */
#define SAFE_DEVINFO_SHA1 0x00002000 /* SHA-1 support present */
#define SAFE_DEVINFO_RIPEMD 0x00004000 /* RIPEMD support present */
#define SAFE_DEVINFO_DEFLATE 0x00010000 /* Deflate support present */
#define SAFE_DEVINFO_SARAM 0x00100000 /* on-chip SA RAM present */
#define SAFE_DEVINFO_EMIBUS 0x00200000 /* EMI bus present */
#define SAFE_DEVINFO_PKEY 0x00400000 /* public key support present */
#define SAFE_DEVINFO_RNG 0x00800000 /* RNG present */
#define SAFE_REV(_maj, _min) (((_maj) << SAFE_DEVINFO_REV_MAJ_S) | (_min))
#define SAFE_REV_MAJ(_chiprev) \
(((_chiprev) & SAFE_DEVINFO_REV_MAJ) >> SAFE_DEVINFO_REV_MAJ_S)
#define SAFE_REV_MIN(_chiprev) ((_chiprev) & SAFE_DEVINFO_REV_MIN)
#define SAFE_PK_FUNC_MULT 0x00000001 /* Multiply function */
#define SAFE_PK_FUNC_SQUARE 0x00000004 /* Square function */
#define SAFE_PK_FUNC_ADD 0x00000010 /* Add function */
#define SAFE_PK_FUNC_SUB 0x00000020 /* Subtract function */
#define SAFE_PK_FUNC_LSHIFT 0x00000040 /* Left-shift function */
#define SAFE_PK_FUNC_RSHIFT 0x00000080 /* Right-shift function */
#define SAFE_PK_FUNC_DIV 0x00000100 /* Divide function */
#define SAFE_PK_FUNC_CMP 0x00000400 /* Compare function */
#define SAFE_PK_FUNC_COPY 0x00000800 /* Copy function */
#define SAFE_PK_FUNC_EXP16 0x00002000 /* Exponentiate (4-bit ACT) */
#define SAFE_PK_FUNC_EXP4 0x00004000 /* Exponentiate (2-bit ACT) */
#define SAFE_PK_FUNC_RUN 0x00008000 /* start/status */
#define SAFE_RNG_STAT_BUSY 0x00000001 /* busy, data not valid */
#define SAFE_RNG_CTRL_PRE_LFSR 0x00000001 /* enable output pre-LFSR */
#define SAFE_RNG_CTRL_TST_MODE 0x00000002 /* enable test mode */
#define SAFE_RNG_CTRL_TST_RUN 0x00000004 /* start test state machine */
#define SAFE_RNG_CTRL_ENA_RING1 0x00000008 /* test entropy oscillator #1 */
#define SAFE_RNG_CTRL_ENA_RING2 0x00000010 /* test entropy oscillator #2 */
#define SAFE_RNG_CTRL_DIS_ALARM 0x00000020 /* disable RNG alarm reports */
#define SAFE_RNG_CTRL_TST_CLOCK 0x00000040 /* enable test clock */
#define SAFE_RNG_CTRL_SHORTEN 0x00000080 /* shorten state timers */
#define SAFE_RNG_CTRL_TST_ALARM 0x00000100 /* simulate alarm state */
#define SAFE_RNG_CTRL_RST_LFSR 0x00000200 /* reset LFSR */
/*
* Packet engine descriptor. Note that d_csr is a copy of the
* SAFE_PE_CSR register and all definitions apply, and d_len
* is a copy of the SAFE_PE_LEN register and all definitions apply.
* d_src and d_len may point directly to contiguous data or to a
* list of ``particle descriptors'' when using scatter/gather i/o.
*/
struct safe_desc {
u_int32_t d_csr; /* per-packet control/status */
u_int32_t d_src; /* source address */
u_int32_t d_dst; /* destination address */
u_int32_t d_sa; /* SA address */
u_int32_t d_len; /* length, bypass, status */
};
/*
* Scatter/Gather particle descriptor.
*
* NB: scatter descriptors do not specify a size; this is fixed
* by the setting of the SAFE_PE_PARTCFG register.
*/
struct safe_pdesc {
u_int32_t pd_addr; /* particle address */
#ifdef __BIG_ENDIAN
u_int16_t pd_flags; /* control word */
u_int16_t pd_size; /* particle size (bytes) */
#else
u_int16_t pd_flags; /* control word */
u_int16_t pd_size; /* particle size (bytes) */
#endif
};
#define SAFE_PD_READY 0x0001 /* ready for processing */
#define SAFE_PD_DONE 0x0002 /* h/w completed processing */
/*
* Security Association (SA) Record (Rev 1). One of these is
* required for each operation processed by the packet engine.
*/
struct safe_sarec {
u_int32_t sa_cmd0;
u_int32_t sa_cmd1;
u_int32_t sa_resv0;
u_int32_t sa_resv1;
u_int32_t sa_key[8]; /* DES/3DES/AES key */
u_int32_t sa_indigest[5]; /* inner digest */
u_int32_t sa_outdigest[5]; /* outer digest */
u_int32_t sa_spi; /* SPI */
u_int32_t sa_seqnum; /* sequence number */
u_int32_t sa_seqmask[2]; /* sequence number mask */
u_int32_t sa_resv2;
u_int32_t sa_staterec; /* address of state record */
u_int32_t sa_resv3[2];
u_int32_t sa_samgmt0; /* SA management field 0 */
u_int32_t sa_samgmt1; /* SA management field 0 */
};
#define SAFE_SA_CMD0_OP 0x00000007 /* operation code */
#define SAFE_SA_CMD0_OP_CRYPT 0x00000000 /* encrypt/decrypt (basic) */
#define SAFE_SA_CMD0_OP_BOTH 0x00000001 /* encrypt-hash/hash-decrypto */
#define SAFE_SA_CMD0_OP_HASH 0x00000003 /* hash (outbound-only) */
#define SAFE_SA_CMD0_OP_ESP 0x00000000 /* ESP in/out (proto) */
#define SAFE_SA_CMD0_OP_AH 0x00000001 /* AH in/out (proto) */
#define SAFE_SA_CMD0_INBOUND 0x00000008 /* inbound operation */
#define SAFE_SA_CMD0_OUTBOUND 0x00000000 /* outbound operation */
#define SAFE_SA_CMD0_GROUP 0x00000030 /* operation group */
#define SAFE_SA_CMD0_BASIC 0x00000000 /* basic operation */
#define SAFE_SA_CMD0_PROTO 0x00000010 /* protocol/packet operation */
#define SAFE_SA_CMD0_BUNDLE 0x00000020 /* bundled operation (resvd) */
#define SAFE_SA_CMD0_PAD 0x000000c0 /* crypto pad method */
#define SAFE_SA_CMD0_PAD_IPSEC 0x00000000 /* IPsec padding */
#define SAFE_SA_CMD0_PAD_PKCS7 0x00000040 /* PKCS#7 padding */
#define SAFE_SA_CMD0_PAD_CONS 0x00000080 /* constant padding */
#define SAFE_SA_CMD0_PAD_ZERO 0x000000c0 /* zero padding */
#define SAFE_SA_CMD0_CRYPT_ALG 0x00000f00 /* symmetric crypto algorithm */
#define SAFE_SA_CMD0_DES 0x00000000 /* DES crypto algorithm */
#define SAFE_SA_CMD0_3DES 0x00000100 /* 3DES crypto algorithm */
#define SAFE_SA_CMD0_AES 0x00000300 /* AES crypto algorithm */
#define SAFE_SA_CMD0_CRYPT_NULL 0x00000f00 /* null crypto algorithm */
#define SAFE_SA_CMD0_HASH_ALG 0x0000f000 /* hash algorithm */
#define SAFE_SA_CMD0_MD5 0x00000000 /* MD5 hash algorithm */
#define SAFE_SA_CMD0_SHA1 0x00001000 /* SHA-1 hash algorithm */
#define SAFE_SA_CMD0_HASH_NULL 0x0000f000 /* null hash algorithm */
#define SAFE_SA_CMD0_HDR_PROC 0x00080000 /* header processing */
#define SAFE_SA_CMD0_IBUSID 0x00300000 /* input bus id */
#define SAFE_SA_CMD0_IPCI 0x00100000 /* PCI input bus id */
#define SAFE_SA_CMD0_OBUSID 0x00c00000 /* output bus id */
#define SAFE_SA_CMD0_OPCI 0x00400000 /* PCI output bus id */
#define SAFE_SA_CMD0_IVLD 0x03000000 /* IV loading */
#define SAFE_SA_CMD0_IVLD_NONE 0x00000000 /* IV no load (reuse) */
#define SAFE_SA_CMD0_IVLD_IBUF 0x01000000 /* IV load from input buffer */
#define SAFE_SA_CMD0_IVLD_STATE 0x02000000 /* IV load from state */
#define SAFE_SA_CMD0_HSLD 0x0c000000 /* hash state loading */
#define SAFE_SA_CMD0_HSLD_SA 0x00000000 /* hash state load from SA */
#define SAFE_SA_CMD0_HSLD_STATE 0x08000000 /* hash state load from state */
#define SAFE_SA_CMD0_HSLD_NONE 0x0c000000 /* hash state no load */
#define SAFE_SA_CMD0_SAVEIV 0x10000000 /* save IV */
#define SAFE_SA_CMD0_SAVEHASH 0x20000000 /* save hash state */
#define SAFE_SA_CMD0_IGATHER 0x40000000 /* input gather */
#define SAFE_SA_CMD0_OSCATTER 0x80000000 /* output scatter */
#define SAFE_SA_CMD1_HDRCOPY 0x00000002 /* copy header to output */
#define SAFE_SA_CMD1_PAYCOPY 0x00000004 /* copy payload to output */
#define SAFE_SA_CMD1_PADCOPY 0x00000008 /* copy pad to output */
#define SAFE_SA_CMD1_IPV4 0x00000000 /* IPv4 protocol */
#define SAFE_SA_CMD1_IPV6 0x00000010 /* IPv6 protocol */
#define SAFE_SA_CMD1_MUTABLE 0x00000020 /* mutable bit processing */
#define SAFE_SA_CMD1_SRBUSID 0x000000c0 /* state record bus id */
#define SAFE_SA_CMD1_SRPCI 0x00000040 /* state record from PCI */
#define SAFE_SA_CMD1_CRMODE 0x00000300 /* crypto mode */
#define SAFE_SA_CMD1_ECB 0x00000000 /* ECB crypto mode */
#define SAFE_SA_CMD1_CBC 0x00000100 /* CBC crypto mode */
#define SAFE_SA_CMD1_OFB 0x00000200 /* OFB crypto mode */
#define SAFE_SA_CMD1_CFB 0x00000300 /* CFB crypto mode */
#define SAFE_SA_CMD1_CRFEEDBACK 0x00000c00 /* crypto feedback mode */
#define SAFE_SA_CMD1_64BIT 0x00000000 /* 64-bit crypto feedback */
#define SAFE_SA_CMD1_8BIT 0x00000400 /* 8-bit crypto feedback */
#define SAFE_SA_CMD1_1BIT 0x00000800 /* 1-bit crypto feedback */
#define SAFE_SA_CMD1_128BIT 0x00000c00 /* 128-bit crypto feedback */
#define SAFE_SA_CMD1_OPTIONS 0x00001000 /* HMAC/options mutable bit */
#define SAFE_SA_CMD1_HMAC SAFE_SA_CMD1_OPTIONS
#define SAFE_SA_CMD1_SAREV1 0x00008000 /* SA Revision 1 */
#define SAFE_SA_CMD1_OFFSET 0x00ff0000 /* hash/crypto offset(dwords) */
#define SAFE_SA_CMD1_OFFSET_S 16
#define SAFE_SA_CMD1_AESKEYLEN 0x0f000000 /* AES key length */
#define SAFE_SA_CMD1_AES128 0x02000000 /* 128-bit AES key */
#define SAFE_SA_CMD1_AES192 0x03000000 /* 192-bit AES key */
#define SAFE_SA_CMD1_AES256 0x04000000 /* 256-bit AES key */
/*
* Security Associate State Record (Rev 1).
*/
struct safe_sastate {
u_int32_t sa_saved_iv[4]; /* saved IV (DES/3DES/AES) */
u_int32_t sa_saved_hashbc; /* saved hash byte count */
u_int32_t sa_saved_indigest[5]; /* saved inner digest */
};
#endif /* _SAFE_SAFEREG_H_ */

View file

@ -0,0 +1,230 @@
/*-
* The linux port of this code done by David McCullough
* Copyright (C) 2004-2007 David McCullough <david_mccullough@securecomputing.com>
* The license and original author are listed below.
*
* Copyright (c) 2003 Sam Leffler, Errno Consulting
* Copyright (c) 2003 Global Technology Associates, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/safe/safevar.h,v 1.2 2006/05/17 18:34:26 pjd Exp $
*/
#ifndef _SAFE_SAFEVAR_H_
#define _SAFE_SAFEVAR_H_
/* Maximum queue length */
#ifndef SAFE_MAX_NQUEUE
#define SAFE_MAX_NQUEUE 60
#endif
#define SAFE_MAX_PART 64 /* Maximum scatter/gather depth */
#define SAFE_DMA_BOUNDARY 0 /* No boundary for source DMA ops */
#define SAFE_MAX_DSIZE 2048 /* MCLBYTES Fixed scatter particle size */
#define SAFE_MAX_SSIZE 0x0ffff /* Maximum gather particle size */
#define SAFE_MAX_DMA 0xfffff /* Maximum PE operand size (20 bits) */
/* total src+dst particle descriptors */
#define SAFE_TOTAL_DPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
#define SAFE_TOTAL_SPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
#define SAFE_RNG_MAXBUFSIZ 128 /* 32-bit words */
#define SAFE_CARD(sid) (((sid) & 0xf0000000) >> 28)
#define SAFE_SESSION(sid) ( (sid) & 0x0fffffff)
#define SAFE_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
#define SAFE_DEF_RTY 0xff /* PCI Retry Timeout */
#define SAFE_DEF_TOUT 0xff /* PCI TRDY Timeout */
#define SAFE_DEF_CACHELINE 0x01 /* Cache Line setting */
#ifdef __KERNEL__
/*
* State associated with the allocation of each chunk
* of memory setup for DMA.
*/
struct safe_dma_alloc {
dma_addr_t dma_paddr;
void *dma_vaddr;
};
/*
* Cryptographic operand state. One of these exists for each
* source and destination operand passed in from the crypto
* subsystem. When possible source and destination operands
* refer to the same memory. More often they are distinct.
* We track the virtual address of each operand as well as
* where each is mapped for DMA.
*/
struct safe_operand {
union {
struct sk_buff *skb;
struct uio *io;
} u;
void *map;
int mapsize; /* total number of bytes in segs */
struct {
dma_addr_t ds_addr;
int ds_len;
int ds_tlen;
} segs[SAFE_MAX_PART];
int nsegs;
};
/*
* Packet engine ring entry and cryptographic operation state.
* The packet engine requires a ring of descriptors that contain
* pointers to various cryptographic state. However the ring
* configuration register allows you to specify an arbitrary size
* for ring entries. We use this feature to collect most of the
* state for each cryptographic request into one spot. Other than
* ring entries only the ``particle descriptors'' (scatter/gather
* lists) and the actual operand data are kept separate. The
* particle descriptors must also be organized in rings. The
* operand data can be located aribtrarily (modulo alignment constraints).
*
* Note that the descriptor ring is mapped onto the PCI bus so
* the hardware can DMA data. This means the entire ring must be
* contiguous.
*/
struct safe_ringentry {
struct safe_desc re_desc; /* command descriptor */
struct safe_sarec re_sa; /* SA record */
struct safe_sastate re_sastate; /* SA state record */
struct cryptop *re_crp; /* crypto operation */
struct safe_operand re_src; /* source operand */
struct safe_operand re_dst; /* destination operand */
int re_sesn; /* crypto session ID */
int re_flags;
#define SAFE_QFLAGS_COPYOUTIV 0x1 /* copy back on completion */
#define SAFE_QFLAGS_COPYOUTICV 0x2 /* copy back on completion */
};
#define re_src_skb re_src.u.skb
#define re_src_io re_src.u.io
#define re_src_map re_src.map
#define re_src_nsegs re_src.nsegs
#define re_src_segs re_src.segs
#define re_src_mapsize re_src.mapsize
#define re_dst_skb re_dst.u.skb
#define re_dst_io re_dst.u.io
#define re_dst_map re_dst.map
#define re_dst_nsegs re_dst.nsegs
#define re_dst_segs re_dst.segs
#define re_dst_mapsize re_dst.mapsize
struct rndstate_test;
struct safe_session {
u_int32_t ses_used;
u_int32_t ses_klen; /* key length in bits */
u_int32_t ses_key[8]; /* DES/3DES/AES key */
u_int32_t ses_mlen; /* hmac length in bytes */
u_int32_t ses_hminner[5]; /* hmac inner state */
u_int32_t ses_hmouter[5]; /* hmac outer state */
u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
};
struct safe_pkq {
struct list_head pkq_list;
struct cryptkop *pkq_krp;
};
struct safe_softc {
softc_device_decl sc_dev;
u32 sc_irq;
struct pci_dev *sc_pcidev;
ocf_iomem_t sc_base_addr;
u_int sc_chiprev; /* major/minor chip revision */
int sc_flags; /* device specific flags */
#define SAFE_FLAGS_KEY 0x01 /* has key accelerator */
#define SAFE_FLAGS_RNG 0x02 /* hardware rng */
int sc_suspended;
int sc_needwakeup; /* notify crypto layer */
int32_t sc_cid; /* crypto tag */
struct safe_dma_alloc sc_ringalloc; /* PE ring allocation state */
struct safe_ringentry *sc_ring; /* PE ring */
struct safe_ringentry *sc_ringtop; /* PE ring top */
struct safe_ringentry *sc_front; /* next free entry */
struct safe_ringentry *sc_back; /* next pending entry */
int sc_nqchip; /* # passed to chip */
spinlock_t sc_ringmtx; /* PE ring lock */
struct safe_pdesc *sc_spring; /* src particle ring */
struct safe_pdesc *sc_springtop; /* src particle ring top */
struct safe_pdesc *sc_spfree; /* next free src particle */
struct safe_dma_alloc sc_spalloc; /* src particle ring state */
struct safe_pdesc *sc_dpring; /* dest particle ring */
struct safe_pdesc *sc_dpringtop; /* dest particle ring top */
struct safe_pdesc *sc_dpfree; /* next free dest particle */
struct safe_dma_alloc sc_dpalloc; /* dst particle ring state */
int sc_nsessions; /* # of sessions */
struct safe_session *sc_sessions; /* sessions */
struct timer_list sc_pkto; /* PK polling */
spinlock_t sc_pkmtx; /* PK lock */
struct list_head sc_pkq; /* queue of PK requests */
struct safe_pkq *sc_pkq_cur; /* current processing request */
u_int32_t sc_pk_reslen, sc_pk_resoff;
int sc_max_dsize; /* maximum safe DMA size */
};
#endif /* __KERNEL__ */
struct safe_stats {
u_int64_t st_ibytes;
u_int64_t st_obytes;
u_int32_t st_ipackets;
u_int32_t st_opackets;
u_int32_t st_invalid; /* invalid argument */
u_int32_t st_badsession; /* invalid session id */
u_int32_t st_badflags; /* flags indicate !(mbuf | uio) */
u_int32_t st_nodesc; /* op submitted w/o descriptors */
u_int32_t st_badalg; /* unsupported algorithm */
u_int32_t st_ringfull; /* PE descriptor ring full */
u_int32_t st_peoperr; /* PE marked error */
u_int32_t st_dmaerr; /* PE DMA error */
u_int32_t st_bypasstoobig; /* bypass > 96 bytes */
u_int32_t st_skipmismatch; /* enc part begins before auth part */
u_int32_t st_lenmismatch; /* enc length different auth length */
u_int32_t st_coffmisaligned; /* crypto offset not 32-bit aligned */
u_int32_t st_cofftoobig; /* crypto offset > 255 words */
u_int32_t st_iovmisaligned; /* iov op not aligned */
u_int32_t st_iovnotuniform; /* iov op not suitable */
u_int32_t st_unaligned; /* unaligned src caused copy */
u_int32_t st_notuniform; /* non-uniform src caused copy */
u_int32_t st_nomap; /* bus_dmamap_create failed */
u_int32_t st_noload; /* bus_dmamap_load_* failed */
u_int32_t st_nombuf; /* MGET* failed */
u_int32_t st_nomcl; /* MCLGET* failed */
u_int32_t st_maxqchip; /* max mcr1 ops out for processing */
u_int32_t st_rng; /* RNG requests */
u_int32_t st_rngalarm; /* RNG alarm requests */
u_int32_t st_noicvcopy; /* ICV data copies suppressed */
};
#endif /* _SAFE_SAFEVAR_H_ */

View file

@ -0,0 +1,279 @@
/* $KAME: sha1.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
* based on: http://csrc.nist.gov/fips/fip180-1.txt
* implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
*/
#if 0
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/crypto/sha1.c,v 1.9 2003/06/10 21:36:57 obrien Exp $");
#include <sys/types.h>
#include <sys/cdefs.h>
#include <sys/time.h>
#include <sys/systm.h>
#include <crypto/sha1.h>
#endif
/* sanity check */
#if BYTE_ORDER != BIG_ENDIAN
# if BYTE_ORDER != LITTLE_ENDIAN
# define unsupported 1
# endif
#endif
#ifndef unsupported
/* constant table */
static u_int32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
#define K(t) _K[(t) / 20]
#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
#define F1(b, c, d) (((b) ^ (c)) ^ (d))
#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
#define F3(b, c, d) (((b) ^ (c)) ^ (d))
#define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
#undef H
#define H(n) (ctxt->h.b32[(n)])
#define COUNT (ctxt->count)
#define BCOUNT (ctxt->c.b64[0] / 8)
#define W(n) (ctxt->m.b32[(n)])
#define PUTBYTE(x) { \
ctxt->m.b8[(COUNT % 64)] = (x); \
COUNT++; \
COUNT %= 64; \
ctxt->c.b64[0] += 8; \
if (COUNT % 64 == 0) \
sha1_step(ctxt); \
}
#define PUTPAD(x) { \
ctxt->m.b8[(COUNT % 64)] = (x); \
COUNT++; \
COUNT %= 64; \
if (COUNT % 64 == 0) \
sha1_step(ctxt); \
}
static void sha1_step(struct sha1_ctxt *);
static void
sha1_step(ctxt)
struct sha1_ctxt *ctxt;
{
u_int32_t a, b, c, d, e;
size_t t, s;
u_int32_t tmp;
#if BYTE_ORDER == LITTLE_ENDIAN
struct sha1_ctxt tctxt;
bcopy(&ctxt->m.b8[0], &tctxt.m.b8[0], 64);
ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
#endif
a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
for (t = 0; t < 20; t++) {
s = t & 0x0f;
if (t >= 16) {
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
}
tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 20; t < 40; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 40; t < 60; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 60; t < 80; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
H(0) = H(0) + a;
H(1) = H(1) + b;
H(2) = H(2) + c;
H(3) = H(3) + d;
H(4) = H(4) + e;
bzero(&ctxt->m.b8[0], 64);
}
/*------------------------------------------------------------*/
void
sha1_init(ctxt)
struct sha1_ctxt *ctxt;
{
bzero(ctxt, sizeof(struct sha1_ctxt));
H(0) = 0x67452301;
H(1) = 0xefcdab89;
H(2) = 0x98badcfe;
H(3) = 0x10325476;
H(4) = 0xc3d2e1f0;
}
void
sha1_pad(ctxt)
struct sha1_ctxt *ctxt;
{
size_t padlen; /*pad length in bytes*/
size_t padstart;
PUTPAD(0x80);
padstart = COUNT % 64;
padlen = 64 - padstart;
if (padlen < 8) {
bzero(&ctxt->m.b8[padstart], padlen);
COUNT += padlen;
COUNT %= 64;
sha1_step(ctxt);
padstart = COUNT % 64; /* should be 0 */
padlen = 64 - padstart; /* should be 64 */
}
bzero(&ctxt->m.b8[padstart], padlen - 8);
COUNT += (padlen - 8);
COUNT %= 64;
#if BYTE_ORDER == BIG_ENDIAN
PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);
PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);
PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);
PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);
#else
PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);
PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);
PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);
PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);
#endif
}
void
sha1_loop(ctxt, input, len)
struct sha1_ctxt *ctxt;
const u_int8_t *input;
size_t len;
{
size_t gaplen;
size_t gapstart;
size_t off;
size_t copysiz;
off = 0;
while (off < len) {
gapstart = COUNT % 64;
gaplen = 64 - gapstart;
copysiz = (gaplen < len - off) ? gaplen : len - off;
bcopy(&input[off], &ctxt->m.b8[gapstart], copysiz);
COUNT += copysiz;
COUNT %= 64;
ctxt->c.b64[0] += copysiz * 8;
if (COUNT % 64 == 0)
sha1_step(ctxt);
off += copysiz;
}
}
void
sha1_result(ctxt, digest0)
struct sha1_ctxt *ctxt;
caddr_t digest0;
{
u_int8_t *digest;
digest = (u_int8_t *)digest0;
sha1_pad(ctxt);
#if BYTE_ORDER == BIG_ENDIAN
bcopy(&ctxt->h.b8[0], digest, 20);
#else
digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];
digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];
digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];
digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];
digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];
digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];
digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];
digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];
digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];
digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];
#endif
}
#endif /*unsupported*/

View file

@ -0,0 +1,72 @@
/* $FreeBSD: src/sys/crypto/sha1.h,v 1.8 2002/03/20 05:13:50 alfred Exp $ */
/* $KAME: sha1.h,v 1.5 2000/03/27 04:36:23 sumikawa Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
* based on: http://csrc.nist.gov/fips/fip180-1.txt
* implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
*/
#ifndef _NETINET6_SHA1_H_
#define _NETINET6_SHA1_H_
struct sha1_ctxt {
union {
u_int8_t b8[20];
u_int32_t b32[5];
} h;
union {
u_int8_t b8[8];
u_int64_t b64[1];
} c;
union {
u_int8_t b8[64];
u_int32_t b32[16];
} m;
u_int8_t count;
};
#ifdef __KERNEL__
extern void sha1_init(struct sha1_ctxt *);
extern void sha1_pad(struct sha1_ctxt *);
extern void sha1_loop(struct sha1_ctxt *, const u_int8_t *, size_t);
extern void sha1_result(struct sha1_ctxt *, caddr_t);
/* compatibilty with other SHA1 source codes */
typedef struct sha1_ctxt SHA1_CTX;
#define SHA1Init(x) sha1_init((x))
#define SHA1Update(x, y, z) sha1_loop((x), (y), (z))
#define SHA1Final(x, y) sha1_result((y), (x))
#endif /* __KERNEL__ */
#define SHA1_RESULTLEN (160/8)
#endif /*_NETINET6_SHA1_H_*/

View file

@ -0,0 +1,12 @@
# for SGlinux builds
-include $(ROOTDIR)/modules/.config
obj-$(CONFIG_OCF_TALITOS) += talitos.o
obj ?= .
EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
ifdef TOPDIR
-include $(TOPDIR)/Rules.make
endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,277 @@
/*
* Freescale SEC (talitos) device dependent data structures
*
* Copyright (c) 2006 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* device ID register values */
#define TALITOS_ID_SEC_2_0 0x40
#define TALITOS_ID_SEC_2_1 0x40 /* cross ref with IP block revision reg */
/*
* following num_channels, channel-fifo-depth, exec-unit-mask, and
* descriptor-types-mask are for forward-compatibility with openfirmware
* flat device trees
*/
/*
* num_channels : the number of channels available in each SEC version.
*/
/* n.b. this driver requires these values be a power of 2 */
#define TALITOS_NCHANNELS_SEC_1_0 4
#define TALITOS_NCHANNELS_SEC_1_2 1
#define TALITOS_NCHANNELS_SEC_2_0 4
#define TALITOS_NCHANNELS_SEC_2_01 4
#define TALITOS_NCHANNELS_SEC_2_1 4
#define TALITOS_NCHANNELS_SEC_2_4 4
/*
* channel-fifo-depth : The number of descriptor
* pointers a channel fetch fifo can hold.
*/
#define TALITOS_CHFIFOLEN_SEC_1_0 1
#define TALITOS_CHFIFOLEN_SEC_1_2 1
#define TALITOS_CHFIFOLEN_SEC_2_0 24
#define TALITOS_CHFIFOLEN_SEC_2_01 24
#define TALITOS_CHFIFOLEN_SEC_2_1 24
#define TALITOS_CHFIFOLEN_SEC_2_4 24
/*
* exec-unit-mask : The bitmask representing what Execution Units (EUs)
* are available. EU information should be encoded following the SEC's
* EU_SEL0 bitfield documentation, i.e. as follows:
*
* bit 31 = set if SEC permits no-EU selection (should be always set)
* bit 30 = set if SEC has the ARC4 EU (AFEU)
* bit 29 = set if SEC has the des/3des EU (DEU)
* bit 28 = set if SEC has the message digest EU (MDEU)
* bit 27 = set if SEC has the random number generator EU (RNG)
* bit 26 = set if SEC has the public key EU (PKEU)
* bit 25 = set if SEC has the aes EU (AESU)
* bit 24 = set if SEC has the Kasumi EU (KEU)
*
*/
#define TALITOS_HAS_EU_NONE (1<<0)
#define TALITOS_HAS_EU_AFEU (1<<1)
#define TALITOS_HAS_EU_DEU (1<<2)
#define TALITOS_HAS_EU_MDEU (1<<3)
#define TALITOS_HAS_EU_RNG (1<<4)
#define TALITOS_HAS_EU_PKEU (1<<5)
#define TALITOS_HAS_EU_AESU (1<<6)
#define TALITOS_HAS_EU_KEU (1<<7)
/* the corresponding masks for each SEC version */
#define TALITOS_HAS_EUS_SEC_1_0 0x7f
#define TALITOS_HAS_EUS_SEC_1_2 0x4d
#define TALITOS_HAS_EUS_SEC_2_0 0x7f
#define TALITOS_HAS_EUS_SEC_2_01 0x7f
#define TALITOS_HAS_EUS_SEC_2_1 0xff
#define TALITOS_HAS_EUS_SEC_2_4 0x7f
/*
* descriptor-types-mask : The bitmask representing what descriptors
* are available. Descriptor type information should be encoded
* following the SEC's Descriptor Header Dword DESC_TYPE field
* documentation, i.e. as follows:
*
* bit 0 = set if SEC supports the aesu_ctr_nonsnoop desc. type
* bit 1 = set if SEC supports the ipsec_esp descriptor type
* bit 2 = set if SEC supports the common_nonsnoop desc. type
* bit 3 = set if SEC supports the 802.11i AES ccmp desc. type
* bit 4 = set if SEC supports the hmac_snoop_no_afeu desc. type
* bit 5 = set if SEC supports the srtp descriptor type
* bit 6 = set if SEC supports the non_hmac_snoop_no_afeu desc.type
* bit 7 = set if SEC supports the pkeu_assemble descriptor type
* bit 8 = set if SEC supports the aesu_key_expand_output desc.type
* bit 9 = set if SEC supports the pkeu_ptmul descriptor type
* bit 10 = set if SEC supports the common_nonsnoop_afeu desc. type
* bit 11 = set if SEC supports the pkeu_ptadd_dbl descriptor type
*
* ..and so on and so forth.
*/
#define TALITOS_HAS_DT_AESU_CTR_NONSNOOP (1<<0)
#define TALITOS_HAS_DT_IPSEC_ESP (1<<1)
#define TALITOS_HAS_DT_COMMON_NONSNOOP (1<<2)
/* the corresponding masks for each SEC version */
#define TALITOS_HAS_DESCTYPES_SEC_2_0 0x01010ebf
#define TALITOS_HAS_DESCTYPES_SEC_2_1 0x012b0ebf
/*
* a TALITOS_xxx_HI address points to the low data bits (32-63) of the register
*/
/* global register offset addresses */
#define TALITOS_ID 0x1020
#define TALITOS_ID_HI 0x1024
#define TALITOS_MCR 0x1030 /* master control register */
#define TALITOS_MCR_HI 0x1038 /* master control register */
#define TALITOS_MCR_SWR 0x1
#define TALITOS_IMR 0x1008 /* interrupt mask register */
#define TALITOS_IMR_ALL 0x00010fff /* enable all interrupts mask */
#define TALITOS_IMR_ERRONLY 0x00010aaa /* enable error interrupts */
#define TALITOS_IMR_HI 0x100C /* interrupt mask register */
#define TALITOS_IMR_HI_ALL 0x00323333 /* enable all interrupts mask */
#define TALITOS_IMR_HI_ERRONLY 0x00222222 /* enable error interrupts */
#define TALITOS_ISR 0x1010 /* interrupt status register */
#define TALITOS_ISR_ERROR 0x00010faa /* errors mask */
#define TALITOS_ISR_DONE 0x00000055 /* channel(s) done mask */
#define TALITOS_ISR_HI 0x1014 /* interrupt status register */
#define TALITOS_ICR 0x1018 /* interrupt clear register */
#define TALITOS_ICR_HI 0x101C /* interrupt clear register */
/* channel register address stride */
#define TALITOS_CH_OFFSET 0x100
/* channel register offset addresses and bits */
#define TALITOS_CH_CCCR 0x1108 /* Crypto-Channel Config Register */
#define TALITOS_CH_CCCR_RESET 0x1 /* Channel Reset bit */
#define TALITOS_CH_CCCR_HI 0x110c /* Crypto-Channel Config Register */
#define TALITOS_CH_CCCR_HI_CDWE 0x10 /* Channel done writeback enable bit */
#define TALITOS_CH_CCCR_HI_NT 0x4 /* Notification type bit */
#define TALITOS_CH_CCCR_HI_CDIE 0x2 /* Channel Done Interrupt Enable bit */
#define TALITOS_CH_CCPSR 0x1110 /* Crypto-Channel Pointer Status Reg */
#define TALITOS_CH_CCPSR_HI 0x1114 /* Crypto-Channel Pointer Status Reg */
#define TALITOS_CH_FF 0x1148 /* Fetch FIFO */
#define TALITOS_CH_FF_HI 0x114c /* Fetch FIFO's FETCH_ADRS */
#define TALITOS_CH_CDPR 0x1140 /* Crypto-Channel Pointer Status Reg */
#define TALITOS_CH_CDPR_HI 0x1144 /* Crypto-Channel Pointer Status Reg */
#define TALITOS_CH_DESCBUF 0x1180 /* (thru 11bf) Crypto-Channel
* Descriptor Buffer (debug) */
/* execution unit register offset addresses and bits */
#define TALITOS_DEUSR 0x2028 /* DEU status register */
#define TALITOS_DEUSR_HI 0x202c /* DEU status register */
#define TALITOS_DEUISR 0x2030 /* DEU interrupt status register */
#define TALITOS_DEUISR_HI 0x2034 /* DEU interrupt status register */
#define TALITOS_DEUICR 0x2038 /* DEU interrupt control register */
#define TALITOS_DEUICR_HI 0x203c /* DEU interrupt control register */
#define TALITOS_AESUISR 0x4030 /* AESU interrupt status register */
#define TALITOS_AESUISR_HI 0x4034 /* AESU interrupt status register */
#define TALITOS_AESUICR 0x4038 /* AESU interrupt control register */
#define TALITOS_AESUICR_HI 0x403c /* AESU interrupt control register */
#define TALITOS_MDEUISR 0x6030 /* MDEU interrupt status register */
#define TALITOS_MDEUISR_HI 0x6034 /* MDEU interrupt status register */
#define TALITOS_RNGSR 0xa028 /* RNG status register */
#define TALITOS_RNGSR_HI 0xa02c /* RNG status register */
#define TALITOS_RNGSR_HI_RD 0x1 /* RNG Reset done */
#define TALITOS_RNGSR_HI_OFL 0xff0000/* number of dwords in RNG output FIFO*/
#define TALITOS_RNGDSR 0xa010 /* RNG data size register */
#define TALITOS_RNGDSR_HI 0xa014 /* RNG data size register */
#define TALITOS_RNG_FIFO 0xa800 /* RNG FIFO - pool of random numbers */
#define TALITOS_RNGISR 0xa030 /* RNG Interrupt status register */
#define TALITOS_RNGISR_HI 0xa034 /* RNG Interrupt status register */
#define TALITOS_RNGRCR 0xa018 /* RNG Reset control register */
#define TALITOS_RNGRCR_HI 0xa01c /* RNG Reset control register */
#define TALITOS_RNGRCR_HI_SR 0x1 /* RNG RNGRCR:Software Reset */
/* descriptor pointer entry */
struct talitos_desc_ptr {
u16 len; /* length */
u8 extent; /* jump (to s/g link table) and extent */
u8 res; /* reserved */
u32 ptr; /* pointer */
};
/* descriptor */
struct talitos_desc {
u32 hdr; /* header */
u32 res; /* reserved */
struct talitos_desc_ptr ptr[7]; /* ptr/len pair array */
};
/* talitos descriptor header (hdr) bits */
/* primary execution unit select */
#define TALITOS_SEL0_AFEU 0x10000000
#define TALITOS_SEL0_DEU 0x20000000
#define TALITOS_SEL0_MDEU 0x30000000
#define TALITOS_SEL0_RNG 0x40000000
#define TALITOS_SEL0_PKEU 0x50000000
#define TALITOS_SEL0_AESU 0x60000000
/* primary execution unit mode (MODE0) and derivatives */
#define TALITOS_MODE0_AESU_CBC 0x00200000
#define TALITOS_MODE0_AESU_ENC 0x00100000
#define TALITOS_MODE0_DEU_CBC 0x00400000
#define TALITOS_MODE0_DEU_3DES 0x00200000
#define TALITOS_MODE0_DEU_ENC 0x00100000
#define TALITOS_MODE0_MDEU_INIT 0x01000000 /* init starting regs */
#define TALITOS_MODE0_MDEU_HMAC 0x00800000
#define TALITOS_MODE0_MDEU_PAD 0x00400000 /* PD */
#define TALITOS_MODE0_MDEU_MD5 0x00200000
#define TALITOS_MODE0_MDEU_SHA256 0x00100000
#define TALITOS_MODE0_MDEU_SHA1 0x00000000 /* SHA-160 */
#define TALITOS_MODE0_MDEU_MD5_HMAC \
(TALITOS_MODE0_MDEU_MD5 | TALITOS_MODE0_MDEU_HMAC)
#define TALITOS_MODE0_MDEU_SHA256_HMAC \
(TALITOS_MODE0_MDEU_SHA256 | TALITOS_MODE0_MDEU_HMAC)
#define TALITOS_MODE0_MDEU_SHA1_HMAC \
(TALITOS_MODE0_MDEU_SHA1 | TALITOS_MODE0_MDEU_HMAC)
/* secondary execution unit select (SEL1) */
/* it's MDEU or nothing */
#define TALITOS_SEL1_MDEU 0x00030000
/* secondary execution unit mode (MODE1) and derivatives */
#define TALITOS_MODE1_MDEU_INIT 0x00001000 /* init starting regs */
#define TALITOS_MODE1_MDEU_HMAC 0x00000800
#define TALITOS_MODE1_MDEU_PAD 0x00000400 /* PD */
#define TALITOS_MODE1_MDEU_MD5 0x00000200
#define TALITOS_MODE1_MDEU_SHA256 0x00000100
#define TALITOS_MODE1_MDEU_SHA1 0x00000000 /* SHA-160 */
#define TALITOS_MODE1_MDEU_MD5_HMAC \
(TALITOS_MODE1_MDEU_MD5 | TALITOS_MODE1_MDEU_HMAC)
#define TALITOS_MODE1_MDEU_SHA256_HMAC \
(TALITOS_MODE1_MDEU_SHA256 | TALITOS_MODE1_MDEU_HMAC)
#define TALITOS_MODE1_MDEU_SHA1_HMAC \
(TALITOS_MODE1_MDEU_SHA1 | TALITOS_MODE1_MDEU_HMAC)
/* direction of overall data flow (DIR) */
#define TALITOS_DIR_OUTBOUND 0x00000000
#define TALITOS_DIR_INBOUND 0x00000002
/* done notification (DN) */
#define TALITOS_DONE_NOTIFY 0x00000001
/* descriptor types */
/* odd numbers here are valid on SEC2 and greater only (e.g. ipsec_esp) */
#define TD_TYPE_AESU_CTR_NONSNOOP (0 << 3)
#define TD_TYPE_IPSEC_ESP (1 << 3)
#define TD_TYPE_COMMON_NONSNOOP_NO_AFEU (2 << 3)
#define TD_TYPE_HMAC_SNOOP_NO_AFEU (4 << 3)
#define TALITOS_HDR_DONE_BITS 0xff000000
#define DPRINTF(a...) do { \
if (debug) { \
printk("%s: ", sc ? \
device_get_nameunit(sc->sc_cdev) : "talitos"); \
printk(a); \
} \
} while (0)

View file

@ -0,0 +1,77 @@
/*
* Freescale SEC data structures for integration with ocf-linux
*
* Copyright (c) 2006 Freescale Semiconductor, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* paired descriptor and associated crypto operation
*/
struct desc_cryptop_pair {
struct talitos_desc cf_desc; /* descriptor ptr */
struct cryptop *cf_crp; /* cryptop ptr */
};
/*
* Holds data specific to a single talitos device.
*/
struct talitos_softc {
softc_device_decl sc_cdev;
struct platform_device *sc_dev; /* device backpointer */
ocf_iomem_t sc_base_addr;
int sc_irq;
int sc_num; /* if we have multiple chips */
int32_t sc_cid; /* crypto tag */
u64 sc_chiprev; /* major/minor chip revision */
int sc_nsessions;
struct talitos_session *sc_sessions;
int sc_num_channels;/* number of crypto channels */
int sc_chfifo_len; /* channel fetch fifo len */
int sc_exec_units; /* execution units mask */
int sc_desc_types; /* descriptor types mask */
/*
* mutual exclusion for intra-channel resources, e.g. fetch fifos
* the last entry is a meta-channel lock used by the channel scheduler
*/
spinlock_t *sc_chnfifolock;
/* sc_chnlastalgo contains last algorithm for that channel */
int *sc_chnlastalg;
/* sc_chnfifo holds pending descriptor--crypto operation pairs */
struct desc_cryptop_pair **sc_chnfifo;
};
struct talitos_session {
u_int32_t ses_used;
u_int32_t ses_klen; /* key length in bits */
u_int32_t ses_key[8]; /* DES/3DES/AES key */
u_int32_t ses_hmac[5]; /* hmac inner state */
u_int32_t ses_hmac_len; /* hmac length */
u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
u_int32_t ses_mlen; /* desired hash result len (12=ipsec or 16) */
};
#define TALITOS_SESSION(sid) ((sid) & 0x0fffffff)
#define TALITOS_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))

View file

@ -0,0 +1,54 @@
#ifndef _OCF_UIO_H_
#define _OCF_UIO_H_
#include <linux/uio.h>
/*
* The linux uio.h doesn't have all we need. To be fully api compatible
* with the BSD cryptodev, we need to keep this around. Perhaps this can
* be moved back into the linux/uio.h
*
* Linux port done by David McCullough <david_mccullough@securecomputing.com>
* Copyright (C) 2006-2007 David McCullough
* Copyright (C) 2004-2005 Intel Corporation.
*
* LICENSE TERMS
*
* The free distribution and use of this software in both source and binary
* form is allowed (with or without changes) provided that:
*
* 1. distributions of this source code include the above copyright
* notice, this list of conditions and the following disclaimer;
*
* 2. distributions in binary form include the above copyright
* notice, this list of conditions and the following disclaimer
* in the documentation and/or other associated materials;
*
* 3. the copyright holder's name is not used to endorse products
* built using this software without specific written permission.
*
* ALTERNATIVELY, provided that this notice is retained in full, this product
* may be distributed under the terms of the GNU General Public License (GPL),
* in which case the provisions of the GPL apply INSTEAD OF those given above.
*
* DISCLAIMER
*
* This software is provided 'as is' with no explicit or implied warranties
* in respect of its properties, including, but not limited to, correctness
* and/or fitness for purpose.
* ---------------------------------------------------------------------------
*/
struct uio {
struct iovec *uio_iov;
int uio_iovcnt;
off_t uio_offset;
int uio_resid;
#if 0
enum uio_seg uio_segflg;
enum uio_rw uio_rw;
struct thread *uio_td;
#endif
};
#endif

View file

@ -1,25 +0,0 @@
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -590,6 +590,8 @@ config CRYPTO_LZO
help
This is the LZO algorithm.
+source "crypto/ocf/Kconfig"
+
source "drivers/crypto/Kconfig"
endif # if CRYPTO
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -66,6 +66,11 @@ obj-$(CONFIG_CRYPTO_LZO) += lzo.o
obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
#
+# OCF
+#
+obj-$(CONFIG_OCF_OCF) += ocf/
+
+#
# generic algorithms and the async_tx api
#
obj-$(CONFIG_XOR_BLOCKS) += xor.o

File diff suppressed because it is too large Load diff

View file

@ -1,25 +0,0 @@
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -675,6 +675,8 @@ config CRYPTO_PRNG
for cryptographic modules. Uses the Algorithm specified in
ANSI X9.31 A.2.4
+source "crypto/ocf/Kconfig"
+
source "drivers/crypto/Kconfig"
endif # if CRYPTO
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -73,6 +73,11 @@ obj-$(CONFIG_CRYPTO_PRNG) += prng.o
obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
#
+# OCF
+#
+obj-$(CONFIG_OCF_OCF) += ocf/
+
+#
# generic algorithms and the async_tx api
#
obj-$(CONFIG_XOR_BLOCKS) += xor.o

File diff suppressed because it is too large Load diff

View file

@ -1,25 +0,0 @@
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -666,6 +666,8 @@ config CRYPTO_LZO
help
This is the LZO algorithm.
+source "crypto/ocf/Kconfig"
+
source "drivers/crypto/Kconfig"
endif # if CRYPTO
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -73,6 +73,11 @@ obj-$(CONFIG_CRYPTO_LZO) += lzo.o
obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
#
+# OCF
+#
+obj-$(CONFIG_OCF_OCF) += ocf/
+
+#
# generic algorithms and the async_tx api
#
obj-$(CONFIG_XOR_BLOCKS) += xor.o

File diff suppressed because it is too large Load diff