1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2025-04-21 12:27:27 +03:00

ocf-linux: version bump to 20110720

Fixes problem with TFM allocation in cryptosoft.c


Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>

Hauke:
 * remove ubsec_ssb package and take it from ocf-linux
 * use patches from ocf-linux package
 * refresh all patches
 * readd some build fixes for OpenWrt.
 * readd CRYPTO_MANAGER dependency


git-svn-id: svn://svn.openwrt.org/openwrt/trunk@27753 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
hauke
2011-07-24 14:17:58 +00:00
parent c3cc5459ec
commit 32dec7075a
63 changed files with 1264 additions and 2768 deletions

View File

@@ -1555,6 +1555,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_OCF_OCFNULL is not set
# CONFIG_OCF_SAFE is not set
# CONFIG_OCF_TALITOS is not set
# CONFIG_OCF_UBSEC_SSB is not set
# CONFIG_OMFS_FS is not set
# CONFIG_OSF_PARTITION is not set
# CONFIG_P54_COMMON is not set

View File

@@ -1553,6 +1553,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_OCF_OCFNULL is not set
# CONFIG_OCF_SAFE is not set
# CONFIG_OCF_TALITOS is not set
# CONFIG_OCF_UBSEC_SSB is not set
# CONFIG_OMFS_FS is not set
# CONFIG_OPROFILE is not set
# CONFIG_OSF_PARTITION is not set

View File

@@ -1636,6 +1636,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_OCF_OCFNULL is not set
# CONFIG_OCF_SAFE is not set
# CONFIG_OCF_TALITOS is not set
# CONFIG_OCF_UBSEC_SSB is not set
# CONFIG_OMFS_FS is not set
# CONFIG_ORION_WATCHDOG is not set
# CONFIG_OSF_PARTITION is not set

View File

@@ -1679,6 +1679,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_OCF_OCFNULL is not set
# CONFIG_OCF_SAFE is not set
# CONFIG_OCF_TALITOS is not set
# CONFIG_OCF_UBSEC_SSB is not set
# CONFIG_OC_ETM is not set
# CONFIG_OMFS_FS is not set
# CONFIG_ORION_WATCHDOG is not set

View File

@@ -1718,6 +1718,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_OCF_OCFNULL is not set
# CONFIG_OCF_SAFE is not set
# CONFIG_OCF_TALITOS is not set
# CONFIG_OCF_UBSEC_SSB is not set
# CONFIG_OC_ETM is not set
# CONFIG_OMFS_FS is not set
# CONFIG_ORION_WATCHDOG is not set

View File

@@ -1750,6 +1750,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_OCF_OCFNULL is not set
# CONFIG_OCF_SAFE is not set
# CONFIG_OCF_TALITOS is not set
# CONFIG_OCF_UBSEC_SSB is not set
# CONFIG_OC_ETM is not set
# CONFIG_OMFS_FS is not set
# CONFIG_ORION_WATCHDOG is not set

View File

@@ -1785,6 +1785,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_OCF_OCFNULL is not set
# CONFIG_OCF_SAFE is not set
# CONFIG_OCF_TALITOS is not set
# CONFIG_OCF_UBSEC_SSB is not set
# CONFIG_OC_ETM is not set
# CONFIG_OMFS_FS is not set
# CONFIG_ORION_WATCHDOG is not set

View File

@@ -1797,6 +1797,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_OCF_OCFNULL is not set
# CONFIG_OCF_SAFE is not set
# CONFIG_OCF_TALITOS is not set
# CONFIG_OCF_UBSEC_SSB is not set
# CONFIG_OC_ETM is not set
# CONFIG_OMFS_FS is not set
# CONFIG_ORION_WATCHDOG is not set

View File

@@ -27,6 +27,8 @@ dep_tristate ' ep80579 (HW crypto engine)' \
CONFIG_OCF_EP80579 $CONFIG_OCF_OCF
dep_tristate ' Micronas c7108 (HW crypto engine)' \
CONFIG_OCF_C7108 $CONFIG_OCF_OCF
dep_tristate ' uBsec BCM5365 (HW crypto engine)'
CONFIG_OCF_UBSEC_SSB $CONFIG_OCF_OCF
dep_tristate ' ocfnull (does no crypto)' \
CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF
dep_tristate ' ocf-bench (HW crypto in-kernel benchmark)' \

View File

@@ -103,6 +103,12 @@ config OCF_C7108
help
OCF driver for the Microna 7108 Cipher processors.
config OCF_UBSEC_SSB
tristate "uBsec BCM5365 (HW crypto engine)"
depends on OCF_OCF
help
OCF driver for uBsec BCM5365 hardware crypto accelerator.
config OCF_OCFNULL
tristate "ocfnull (fake crypto engine)"
depends on OCF_OCF

View File

@@ -47,9 +47,19 @@ $(_obj)-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon$(_slash)
$(_obj)-$(CONFIG_OCF_KIRKWOOD) += kirkwood$(_slash)
$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)
$(_obj)-$(CONFIG_OCF_C7108) += c7108$(_slash)
$(_obj)-$(CONFIG_OCF_UBSEC_SSB) += ubsec_ssb$(_slash)
ocf-objs := $(OCF_OBJS)
dummy:
@echo "Please consult the README for how to build OCF."
@echo "If you can't wait then the following should do it:"
@echo ""
@echo " make ocf_modules"
@echo " sudo make ocf_install"
@echo ""
@exit 1
$(list-multi) dummy1: $(ocf-objs)
$(LD) -r -o $@ $(ocf-objs)
@@ -57,21 +67,44 @@ $(list-multi) dummy1: $(ocf-objs)
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
rm -f */modules.order */modules.builtin modules.order modules.builtin
ifdef TOPDIR
-include $(TOPDIR)/Rules.make
endif
#
# release gen targets
# targets to build easily on the current machine
#
ocf_make:
make -C /lib/modules/$(shell uname -r)/build M=`pwd` $(OCF_TARGET) CONFIG_OCF_OCF=m
make -C /lib/modules/$(shell uname -r)/build M=`pwd` $(OCF_TARGET) CONFIG_OCF_OCF=m CONFIG_OCF_CRYPTOSOFT=m
-make -C /lib/modules/$(shell uname -r)/build M=`pwd` $(OCF_TARGET) CONFIG_OCF_OCF=m CONFIG_OCF_BENCH=m
-make -C /lib/modules/$(shell uname -r)/build M=`pwd` $(OCF_TARGET) CONFIG_OCF_OCF=m CONFIG_OCF_OCFNULL=m
-make -C /lib/modules/$(shell uname -r)/build M=`pwd` $(OCF_TARGET) CONFIG_OCF_OCF=m CONFIG_OCF_HIFN=m
ocf_modules:
$(MAKE) ocf_make OCF_TARGET=modules
ocf_install:
$(MAKE) ocf_make OCF_TARGET="modules modules_install"
depmod
mkdir -p /usr/include/crypto
cp cryptodev.h /usr/include/crypto/.
#
# generate full kernel patches for 2.4 and 2.6 kernels to make patching
# your kernel easier
#
.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; \
patchbase=.; \
[ -d $$patchbase/patches ] || patchbase=..; \
patch=ocf-linux-base.patch; \
patch24=ocf-linux-24.patch; \
patch26=ocf-linux-26.patch; \
( \
find . -name Makefile; \
find . -name Config.in; \
@@ -81,44 +114,32 @@ patch:
) | 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.33-ocf.patch $$patch > $$patch26
cat $$patchbase/patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \
cat $$patchbase/patches/linux-2.6.38-ocf.patch $$patch > $$patch26; \
.PHONY: tarball
tarball:
#
# this target probably does nothing for anyone but me - davidm
#
.PHONY: release
release:
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; \
mkdir -p $$RELDIR/ocf; \
mkdir -p $$RELDIR/patches; \
mkdir -p $$RELDIR/crypto-tools; \
cp README* $$RELDIR/.; \
cp patches/[!C]* $$RELDIR/patches/.; \
cp tools/[!C]* $$RELDIR/crypto-tools/.; \
cp -r [!C]* Config.in $$RELDIR/ocf/.; \
rm -rf $$RELDIR/ocf/patches $$RELDIR/ocf/tools; \
rm -f $$RELDIR/ocf/README*; \
cp $$CURDIR/../../user/crypto-tools/[!C]* $$RELDIR/crypto-tools/.; \
make -C $$RELDIR/crypto-tools clean; \
make -C $$RELDIR/ocf clean; \
find $$RELDIR/ocf -name CVS | xargs rm -rf; \
cd $$RELDIR/..; \
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
gzip -9 ocf-linux-$$REL.tar

View File

@@ -1,167 +1,246 @@
README - ocf-linux-20100325
---------------------------
###########################
README - ocf-linux-20100530
###########################
This README provides instructions for getting ocf-linux compiled and
operating in a generic linux environment. For other information you
might like to visit the home page for this project:
operating in a generic linux environment. Other information on the project
can be found at the home page:
http://ocf-linux.sourceforge.net/
Adding OCF to linux
-------------------
Embedded systems and applications requiring userspace acceleration will need
to patch the kernel source to get full OCF support. See "Adding OCF to
linux source" below. Otherwise the "OCF Quickstart" that follows is the
easiest way to get started.
Not much in this file for now, just some notes. I usually build
the ocf support as modules but it can be built into the kernel as
well. To use it:
If your goal is to accelerate Openswan on Ubuntu or CentOS, you may find
that the required binaries are already available on openswan.org:
* mknod /dev/crypto c 10 70
ftp://ftp.openswan.org/ocf/
ftp://ftp.openswan.org/openswan/binaries/ubuntu/
* to add OCF to your kernel source, you have two options. Apply
the kernel specific patch:
#####################################################
OCF Quickstart for Ubuntu/Others (including Openswan)
#####################################################
cd linux-2.4*; gunzip < ocf-linux-24-XXXXXXXX.patch.gz | patch -p1
cd linux-2.6*; gunzip < ocf-linux-26-XXXXXXXX.patch.gz | patch -p1
if you do one of the above, then you can proceed to the next step,
or you can do the above process by hand with using the patches against
linux-2.4.35 and 2.6.33 to include the ocf code under crypto/ocf.
Here's how to add it:
This section provides instructions on how to quickly add kernel only support
for OCF to a GNU/Linux system. It is only suitable for in-kernel use such as
Openswan MAST/KLIPS.
for 2.4.35 (and later)
If the target is an embedded system, or, userspace acceleration of
applications such as OpenVPN and OpenSSL, the section below titled
"Adding OCF to linux source" is more appropriate.
cd linux-2.4.35/crypto
tar xvzf ocf-linux.tar.gz
cd ..
patch -p1 < crypto/ocf/patches/linux-2.4.35-ocf.patch
Before building kernel only support for OCF ensure that the appropriate
linux-headers package is installed:
for 2.6.23 (and later), find the kernel patch specific (or nearest)
to your kernel versions and then:
cd ocf
make ocf_modules
sudo make ocf_install
OCF_DIR=`pwd` # remember where OCF sources were built
cd linux-2.6.NN/crypto
tar xvzf ocf-linux.tar.gz
cd ..
patch -p1 < crypto/ocf/patches/linux-2.6.NN-ocf.patch
At this point the ocf, cryptosoft, ocfnull, hifn7751 and ocf-bench modules
should have been built and installed. The OCF installation can be tested
with the following commands:
It should be easy to take this patch and apply it to other more
recent versions of the kernels. The same patches should also work
relatively easily on kernels as old as 2.6.11 and 2.4.18.
* under 2.4 if you are on a non-x86 platform, you may need to:
modprobe ocf
modprobe cryptosoft
modprobe ocf-bench
dmesg | tail -5
cp linux-2.X.x/include/asm-i386/kmap_types.h linux-2.X.x/include/asm-YYY
The final modprobe of ocf-bench will fail, this is intentional as ocf-bench
is a short lived module that tests in-kernel performance of OCF. If
everything worked correctly the "dmesg | tail -5" should include a line
like:
so that you can build the kernel crypto support needed for the cryptosoft
driver.
[ 583.128741] OCF: 45133 requests of 1488 bytes in 251 jiffies (535.122 Mbps)
* For simplicity you should enable all the crypto support in your kernel
except for the test driver. Likewise for the OCF options. Do not
enable OCF crypto drivers for HW that you do not have (for example
ixp4xx will not compile on non-Xscale systems).
This shows the in-kernel performance of OCF using the cryptosoft driver.
For addition driver load options, see "How to load the OCF modules" below.
* make sure that cryptodev.h (from ocf-linux.tar.gz) is installed as
crypto/cryptodev.h in an include directory that is used for building
applications for your platform. For example on a host system that
might be:
If the intention is to run an OCF accelerated Openswan (KLIPS/MAST) then use
these steps to compile openswan downloaded from openswan.org (2.6.34 or later).
/usr/include/crypto/cryptodev.h
tar xf openswan-2.6.34.tar.gz
cd openswan-2.6.34
make programs
make KERNELSRC=/lib/modules/`uname -r`/build \
KBUILD_EXTRA_SYMBOLS=$OCF_DIR/Module.symvers \
MODULE_DEF_INCLUDE=`pwd`/packaging/ocf/config-all.hmodules \
MODULE_DEFCONFIG=`pwd`/packaging/ocf/defconfig \
module
sudo make KERNELSRC=/lib/modules/`uname -r`/build \
KBUILD_EXTRA_SYMBOLS=$OCF_DIR/Module.symvers \
MODULE_DEF_INCLUDE=`pwd`/packaging/ocf/config-all.hmodules \
MODULE_DEFCONFIG=`pwd`/packaging/ocf/defconfig \
install minstall
* patch your openssl-0.9.8n code with the openssl-0.9.8n.patch.
(NOTE: there is no longer a need to patch ssh). The patch is against:
openssl-0_9_8e
The rest of this document is only required for more complex build
requirements.
If you need a patch for an older version of openssl, you should look
to older OCF releases. This patch is unlikely to work on older
openssl versions.
##########################
Adding OCF to linux source
##########################
openssl-0.9.8n.patch
- enables --with-cryptodev for non BSD systems
- adds -cpu option to openssl speed for calculating CPU load
under linux
- fixes null pointer in openssl speed multi thread output.
- fixes test keys to work with linux crypto's more stringent
key checking.
- adds MD5/SHA acceleration (Ronen Shitrit), only enabled
with the --with-cryptodev-digests option
- fixes bug in engine code caching.
It is recommended that OCF be built as modules as it increases the
flexibility and ease of debugging the system.
* build crypto-tools-XXXXXXXX.tar.gz if you want to try some of the BSD
tools for testing OCF (ie., cryptotest).
Ensure that the system has /dev/crypto for userspace access to OCF:
How to load the OCF drivers
---------------------------
mknod /dev/crypto c 10 70
First insert the base modules:
Generate the kernel patches and apply the appropriate one.
insmod ocf
insmod cryptodev
cd ocf
make patch
You can then install the software OCF driver with:
This will provide three files:
insmod cryptosoft
linux-2.4.*-ocf.patch
linux-2.6.*-ocf.patch
ocf-linux-base.patch
and one or more of the OCF HW drivers with:
If either of the first two patches applies to the targets kernel, then one
of the following as required:
insmod safe
insmod hifn7751
insmod ixp4xx
...
cd linux-2.X.Y; patch -p1 < linux-2.4.*-ocf.patch
cd linux-2.6.Y; patch -p1 < linux-2.6.*-ocf.patch
all the drivers take a debug option to enable verbose debug so that
you can see what is going on. For debug you load them as:
Otherwise, locate the appropriate kernel patch in the patches directory and
apply that as well as the ocf-linux-base.patch using '-p1'.
insmod ocf crypto_debug=1
insmod cryptodev cryptodev_debug=1
insmod cryptosoft swcr_debug=1
When using a linux-2.4 system on a non-x86 platform, the following may be
required to build cryptosoft:
You may load more than one OCF crypto driver but then there is no guarantee
as to which will be used.
cp linux-2.X.x/include/asm-i386/kmap_types.h linux-2.X.x/include/asm-YYY
You can also enable debug at run time on 2.6 systems with the following:
When using cryptosoft, for simplicity, enable all the crypto support in the
kernel except for the test driver. Likewise for the OCF options. Do not
enable OCF crypto drivers for HW that is not present (for example the ixp4xx
driver will not compile on non-Xscale systems).
echo 1 > /sys/module/ocf/parameters/crypto_debug
echo 1 > /sys/module/cryptodev/parameters/cryptodev_debug
echo 1 > /sys/module/cryptosoft/parameters/swcr_debug
echo 1 > /sys/module/hifn7751/parameters/hifn_debug
echo 1 > /sys/module/safe/parameters/safe_debug
echo 1 > /sys/module/ixp4xx/parameters/ixp_debug
...
Make sure that cryptodev.h from the ocf directory is installed as
crypto/cryptodev.h in an include directory that is used for building
applications for the target platform. For example on a host system that
might be:
/usr/include/crypto/cryptodev.h
Patch the openssl-0.9.8r code the openssl-0.9.8r.patch from the patches
directory. There are many older patch versions in the patches directory
if required.
The openssl patches provide the following functionality:
* enables --with-cryptodev for non BSD systems
* adds -cpu option to openssl speed for calculating CPU load under linux
* fixes null pointer in openssl speed multi thread output.
* fixes test keys to work with linux crypto's more stringent key checking.
* adds MD5/SHA acceleration (Ronen Shitrit), only enabled with the
--with-cryptodev-digests option
* fixes bug in engine code caching.
Build the crypto-tools directory for the target to obtain a userspace
testing tool call cryptotest.
###########################
How to load the OCF modules
###########################
First insert the base modules (cryptodev is optional, it is only used
for userspace acceleration):
modprobe ocf
modprobe cryptodev
Load the software OCF driver with:
modprobe cryptosoft
and zero or more of the OCF HW drivers with:
modprobe safe
modprobe hifn7751
modprobe ixp4xx
...
All the drivers take a debug option to enable verbose debug so that
OCF operation may be observed via "dmesg" or the console. For debug
load the modules as:
modprobe ocf crypto_debug=1
modprobe cryptodev cryptodev_debug=1
modprobe cryptosoft swcr_debug=1
More than one OCF crypto driver may be loaded but then there is no
guarantee as to which will be used (other than a preference for HW
drivers over SW drivers by most applications).
It is also possible to enable debug at run time on linux-2.6 systems
with the following:
echo 1 > /sys/module/ocf/parameters/crypto_debug
echo 1 > /sys/module/cryptodev/parameters/cryptodev_debug
echo 1 > /sys/module/cryptosoft/parameters/swcr_debug
echo 1 > /sys/module/hifn7751/parameters/hifn_debug
echo 1 > /sys/module/safe/parameters/safe_debug
echo 1 > /sys/module/ixp4xx/parameters/ixp_debug
...
The ocf-bench driver accepts the following parameters:
request_q_len - Maximum number of outstanding requests to OCF
request_num - run for at least this many requests
request_size - size of each request (multiple of 16 bytes recommended)
request_batch - enable OCF request batching
request_cbimm - enable OCF immediate callback on completion
For example:
modprobe ocf-bench request_size=1024 request_cbimm=0
#######################
Testing the OCF support
-----------------------
#######################
run "cryptotest", it should do a short test for a couple of
des packets. If it does everything is working.
run "cryptotest", it should do a short test for a couple of
des packets. If it does everything is working.
If this works, then ssh will use the driver when invoked as:
If this works, then ssh will use the driver when invoked as:
ssh -c 3des username@host
ssh -c 3des username@host
to see for sure that it is operating, enable debug as defined above.
to see for sure that it is operating, enable debug as defined above.
To get a better idea of performance run:
To get a better idea of performance run:
cryptotest 100 4096
cryptotest 100 4096
There are more options to cryptotest, see the help.
There are more options to cryptotest, see the help.
It is also possible to use openssl to test the speed of the crypto
drivers.
It is also possible to use openssl to test the speed of the crypto
drivers.
openssl speed -evp des -engine cryptodev -elapsed
openssl speed -evp des3 -engine cryptodev -elapsed
openssl speed -evp aes128 -engine cryptodev -elapsed
openssl speed -evp des -engine cryptodev -elapsed
openssl speed -evp des3 -engine cryptodev -elapsed
openssl speed -evp aes128 -engine cryptodev -elapsed
and multiple threads (10) with:
and multiple threads (10) with:
openssl speed -evp des -engine cryptodev -elapsed -multi 10
openssl speed -evp des3 -engine cryptodev -elapsed -multi 10
openssl speed -evp aes128 -engine cryptodev -elapsed -multi 10
openssl speed -evp des -engine cryptodev -elapsed -multi 10
openssl speed -evp des3 -engine cryptodev -elapsed -multi 10
openssl speed -evp aes128 -engine cryptodev -elapsed -multi 10
for public key testing you can try:
for public key testing you can try:
cryptokeytest
openssl speed -engine cryptodev rsa -elapsed
openssl speed -engine cryptodev dsa -elapsed
cryptokeytest
openssl speed -engine cryptodev rsa -elapsed
openssl speed -engine cryptodev dsa -elapsed
David McCullough
david_mccullough@mcafee.com
#############################
#
# David McCullough
# david_mccullough@mcafee.com
#
#############################

View File

@@ -35,10 +35,8 @@ __FBSDID("$FreeBSD: src/sys/opencrypto/criov.c,v 1.5 2006/06/04 22:15:13 pjd Exp
*/
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>

View File

@@ -64,10 +64,8 @@ __FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp E
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
@@ -76,7 +74,9 @@ __FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp E
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4)
#include <linux/kthread.h>
#endif
#include <cryptodev.h>
/*
@@ -156,9 +156,8 @@ static int crypto_drivers_num = 0;
* have one per-queue but having one simplifies handling of block/unblock
* operations.
*/
static int crp_sleep = 0;
static LIST_HEAD(crp_q); /* request queues */
static LIST_HEAD(crp_kq);
static LIST_HEAD(crp_q); /* crypto request queue */
static LIST_HEAD(crp_kq); /* asym request queue */
static spinlock_t crypto_q_lock;
@@ -213,11 +212,6 @@ static struct kmem_cache *cryptop_zone;
static struct kmem_cache *cryptodesc_zone;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
#include <linux/sched.h>
#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0)
#endif
#define debug crypto_debug
int crypto_debug = 0;
module_param(crypto_debug, int, 0644);
@@ -278,11 +272,13 @@ module_param(crypto_max_loopcount, int, 0644);
MODULE_PARM_DESC(crypto_max_loopcount,
"Maximum number of crypto ops to do before yielding to other processes");
static pid_t cryptoproc = (pid_t) -1;
static struct completion cryptoproc_exited;
#ifndef CONFIG_NR_CPUS
#define CONFIG_NR_CPUS 1
#endif
static struct task_struct *cryptoproc[CONFIG_NR_CPUS];
static struct task_struct *cryptoretproc[CONFIG_NR_CPUS];
static DECLARE_WAIT_QUEUE_HEAD(cryptoproc_wait);
static pid_t cryptoretproc = (pid_t) -1;
static struct completion cryptoretproc_exited;
static DECLARE_WAIT_QUEUE_HEAD(cryptoretproc_wait);
static int crypto_proc(void *arg);
@@ -318,6 +314,7 @@ driver_suitable(const struct cryptocap *cap, const struct cryptoini *cri)
return 1;
}
/*
* Select a driver for a new session that supports the specified
* algorithms and, optionally, is constrained according to the flags.
@@ -791,8 +788,7 @@ crypto_unblock(u_int32_t driverid, int what)
cap->cc_unkqblocked = 0;
crypto_all_kqblocked = 0;
}
if (crp_sleep)
wake_up_interruptible(&cryptoproc_wait);
wake_up_interruptible(&cryptoproc_wait);
err = 0;
} else
err = EINVAL;
@@ -817,8 +813,8 @@ crypto_dispatch(struct cryptop *crp)
CRYPTO_Q_LOCK();
if (crypto_q_cnt >= crypto_q_max) {
CRYPTO_Q_UNLOCK();
cryptostats.cs_drops++;
CRYPTO_Q_UNLOCK();
return ENOMEM;
}
crypto_q_cnt++;
@@ -865,8 +861,7 @@ crypto_dispatch(struct cryptop *crp)
TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
result = 0;
}
if (crp_sleep)
wake_up_interruptible(&cryptoproc_wait);
wake_up_interruptible(&cryptoproc_wait);
CRYPTO_Q_UNLOCK();
return result;
}
@@ -887,8 +882,7 @@ crypto_kdispatch(struct cryptkop *krp)
if (error == ERESTART) {
CRYPTO_Q_LOCK();
TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
if (crp_sleep)
wake_up_interruptible(&cryptoproc_wait);
wake_up_interruptible(&cryptoproc_wait);
CRYPTO_Q_UNLOCK();
error = 0;
}
@@ -1186,8 +1180,7 @@ crypto_done(struct cryptop *crp)
* Normal case; queue the callback for the thread.
*/
CRYPTO_RETQ_LOCK();
if (CRYPTO_RETQ_EMPTY())
wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
CRYPTO_RETQ_UNLOCK();
}
@@ -1237,8 +1230,7 @@ crypto_kdone(struct cryptkop *krp)
* Normal case; queue the callback for the thread.
*/
CRYPTO_RETQ_LOCK();
if (CRYPTO_RETQ_EMPTY())
wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
CRYPTO_RETQ_UNLOCK();
}
@@ -1281,7 +1273,7 @@ crypto_proc(void *arg)
unsigned long q_flags;
int loopcount = 0;
ocf_daemonize("crypto");
set_current_state(TASK_INTERRUPTIBLE);
CRYPTO_Q_LOCK();
for (;;) {
@@ -1435,12 +1427,10 @@ crypto_proc(void *arg)
list_empty(&crp_kq), crypto_all_kqblocked);
loopcount = 0;
CRYPTO_Q_UNLOCK();
crp_sleep = 1;
wait_event_interruptible(cryptoproc_wait,
!(list_empty(&crp_q) || crypto_all_qblocked) ||
!(list_empty(&crp_kq) || crypto_all_kqblocked) ||
cryptoproc == (pid_t) -1);
crp_sleep = 0;
kthread_should_stop());
if (signal_pending (current)) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
spin_lock_irq(&current->sigmask_lock);
@@ -1452,7 +1442,7 @@ crypto_proc(void *arg)
}
CRYPTO_Q_LOCK();
dprintk("%s - awake\n", __FUNCTION__);
if (cryptoproc == (pid_t) -1)
if (kthread_should_stop())
break;
cryptostats.cs_intrs++;
} else if (loopcount > crypto_max_loopcount) {
@@ -1461,12 +1451,14 @@ crypto_proc(void *arg)
* been using the CPU exclusively for a while.
*/
loopcount = 0;
CRYPTO_Q_UNLOCK();
schedule();
CRYPTO_Q_LOCK();
}
loopcount++;
}
CRYPTO_Q_UNLOCK();
complete_and_exit(&cryptoproc_exited, 0);
return 0;
}
/*
@@ -1481,7 +1473,7 @@ crypto_ret_proc(void *arg)
struct cryptkop *krpt;
unsigned long r_flags;
ocf_daemonize("crypto_ret");
set_current_state(TASK_INTERRUPTIBLE);
CRYPTO_RETQ_LOCK();
for (;;) {
@@ -1516,9 +1508,9 @@ crypto_ret_proc(void *arg)
dprintk("%s - sleeping\n", __FUNCTION__);
CRYPTO_RETQ_UNLOCK();
wait_event_interruptible(cryptoretproc_wait,
cryptoretproc == (pid_t) -1 ||
!list_empty(&crp_ret_q) ||
!list_empty(&crp_ret_kq));
!list_empty(&crp_ret_kq) ||
kthread_should_stop());
if (signal_pending (current)) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
spin_lock_irq(&current->sigmask_lock);
@@ -1530,7 +1522,7 @@ crypto_ret_proc(void *arg)
}
CRYPTO_RETQ_LOCK();
dprintk("%s - awake\n", __FUNCTION__);
if (cryptoretproc == (pid_t) -1) {
if (kthread_should_stop()) {
dprintk("%s - EXITING!\n", __FUNCTION__);
break;
}
@@ -1538,7 +1530,7 @@ crypto_ret_proc(void *arg)
}
}
CRYPTO_RETQ_UNLOCK();
complete_and_exit(&cryptoretproc_exited, 0);
return 0;
}
@@ -1644,6 +1636,7 @@ static int
crypto_init(void)
{
int error;
unsigned long cpu;
dprintk("%s(%p)\n", __FUNCTION__, (void *) crypto_init);
@@ -1686,25 +1679,28 @@ crypto_init(void)
memset(crypto_drivers, 0, crypto_drivers_num * sizeof(struct cryptocap));
init_completion(&cryptoproc_exited);
init_completion(&cryptoretproc_exited);
cryptoproc = 0; /* to avoid race condition where proc runs first */
cryptoproc = kernel_thread(crypto_proc, NULL, CLONE_FS|CLONE_FILES);
if (cryptoproc < 0) {
error = cryptoproc;
printk("crypto: crypto_init cannot start crypto thread; error %d",
error);
goto bad;
}
cryptoretproc = 0; /* to avoid race condition where proc runs first */
cryptoretproc = kernel_thread(crypto_ret_proc, NULL, CLONE_FS|CLONE_FILES);
if (cryptoretproc < 0) {
error = cryptoretproc;
printk("crypto: crypto_init cannot start cryptoret thread; error %d",
ocf_for_each_cpu(cpu) {
cryptoproc[cpu] = kthread_create(crypto_proc, (void *) cpu,
"ocf_%d", (int) cpu);
if (IS_ERR(cryptoproc[cpu])) {
error = PTR_ERR(cryptoproc[cpu]);
printk("crypto: crypto_init cannot start crypto thread; error %d",
error);
goto bad;
goto bad;
}
kthread_bind(cryptoproc[cpu], cpu);
wake_up_process(cryptoproc[cpu]);
cryptoretproc[cpu] = kthread_create(crypto_ret_proc, (void *) cpu,
"ocf_ret_%d", (int) cpu);
if (IS_ERR(cryptoretproc[cpu])) {
error = PTR_ERR(cryptoretproc[cpu]);
printk("crypto: crypto_init cannot start cryptoret thread; error %d",
error);
goto bad;
}
kthread_bind(cryptoretproc[cpu], cpu);
wake_up_process(cryptoretproc[cpu]);
}
return 0;
@@ -1717,34 +1713,17 @@ bad:
static void
crypto_exit(void)
{
pid_t p;
unsigned long d_flags;
int cpu;
dprintk("%s()\n", __FUNCTION__);
/*
* Terminate any crypto threads.
*/
CRYPTO_DRIVER_LOCK();
p = cryptoproc;
cryptoproc = (pid_t) -1;
kill_proc(p, SIGTERM, 1);
wake_up_interruptible(&cryptoproc_wait);
CRYPTO_DRIVER_UNLOCK();
wait_for_completion(&cryptoproc_exited);
CRYPTO_DRIVER_LOCK();
p = cryptoretproc;
cryptoretproc = (pid_t) -1;
kill_proc(p, SIGTERM, 1);
wake_up_interruptible(&cryptoretproc_wait);
CRYPTO_DRIVER_UNLOCK();
wait_for_completion(&cryptoretproc_exited);
/* XXX flush queues??? */
ocf_for_each_cpu(cpu) {
kthread_stop(cryptoproc[cpu]);
kthread_stop(cryptoretproc[cpu]);
}
/*
* Reclaim dynamically allocated resources.

View File

@@ -28,10 +28,8 @@
*/
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
@@ -69,15 +67,6 @@ struct octo_sess {
int octo_mlen;
int octo_ivsize;
#if 0
int (*octo_decrypt)(struct scatterlist *sg, int sg_len,
uint8_t *key, int key_len, uint8_t * iv,
uint64_t *hminner, uint64_t *hmouter);
int (*octo_encrypt)(struct scatterlist *sg, int sg_len,
uint8_t *key, int key_len, uint8_t * iv,
uint64_t *hminner, uint64_t *hmouter);
#else
int (*octo_encrypt)(struct octo_sess *od,
struct scatterlist *sg, int sg_len,
int auth_off, int auth_len,
@@ -88,7 +77,6 @@ struct octo_sess {
int auth_off, int auth_len,
int crypt_off, int crypt_len,
int icv_off, uint8_t *ivp);
#endif
uint64_t octo_hminner[3];
uint64_t octo_hmouter[3];
@@ -264,7 +252,7 @@ octo_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
break;
case CRYPTO_SHA1_HMAC:
(*ocd)->octo_encrypt = octo_des_cbc_sha1_encrypt;
(*ocd)->octo_decrypt = octo_des_cbc_sha1_encrypt;
(*ocd)->octo_decrypt = octo_des_cbc_sha1_decrypt;
octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
(*ocd)->octo_hmouter);
break;
@@ -305,13 +293,13 @@ octo_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
break;
case CRYPTO_MD5_HMAC:
(*ocd)->octo_encrypt = octo_null_md5_encrypt;
(*ocd)->octo_decrypt = octo_null_md5_encrypt;
(*ocd)->octo_decrypt = octo_null_md5_encrypt; /* encrypt == decrypt */
octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
(*ocd)->octo_hmouter);
break;
case CRYPTO_SHA1_HMAC:
(*ocd)->octo_encrypt = octo_null_sha1_encrypt;
(*ocd)->octo_decrypt = octo_null_sha1_encrypt;
(*ocd)->octo_decrypt = octo_null_sha1_encrypt; /* encrypt == decrypt */
octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
(*ocd)->octo_hmouter);
break;
@@ -433,12 +421,22 @@ octo_process(device_t dev, struct cryptop *crp, int hint)
}
if (enccrd) {
if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
ivp = enccrd->crd_iv;
if (enccrd->crd_flags & CRD_F_ENCRYPT) {
if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
ivp = enccrd->crd_iv;
else
read_random((ivp = iv_data), od->octo_ivsize);
if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0)
crypto_copyback(crp->crp_flags, crp->crp_buf,
enccrd->crd_inject, od->octo_ivsize, ivp);
} else {
ivp = iv_data;
crypto_copydata(crp->crp_flags, crp->crp_buf,
enccrd->crd_inject, od->octo_ivsize, (caddr_t) ivp);
if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
ivp = enccrd->crd_iv;
} else {
ivp = iv_data;
crypto_copydata(crp->crp_flags, crp->crp_buf,
enccrd->crd_inject, od->octo_ivsize, (caddr_t) ivp);
}
}
if (maccrd) {

View File

@@ -40,10 +40,8 @@ __FBSDID("$FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.34 2007/05/09 19:37:02 gn
*/
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/types.h>
#include <linux/time.h>
@@ -60,7 +58,6 @@ __FBSDID("$FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.34 2007/05/09 19:37:02 gn
#include <linux/file.h>
#include <linux/mount.h>
#include <linux/miscdevice.h>
#include <linux/version.h>
#include <asm/uaccess.h>
#include <cryptodev.h>

View File

@@ -156,7 +156,8 @@
#define CRYPTO_SHA2_384 23
#define CRYPTO_SHA2_512 24
#define CRYPTO_RIPEMD160 25
#define CRYPTO_ALGORITHM_MAX 25 /* Keep updated - see below */
#define CRYPTO_LZS_COMP 26
#define CRYPTO_ALGORITHM_MAX 26 /* Keep updated - see above */
/* Algorithm flags */
#define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */

View File

@@ -4,7 +4,7 @@
* but is mostly unrecognisable,
*
* Written by David McCullough <david_mccullough@mcafee.com>
* Copyright (C) 2004-2010 David McCullough
* Copyright (C) 2004-2011 David McCullough
* Copyright (C) 2004-2005 Intel Corporation.
*
* LICENSE TERMS
@@ -35,10 +35,8 @@
*/
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
@@ -50,7 +48,8 @@
#include <linux/mm.h>
#include <linux/skbuff.h>
#include <linux/random.h>
#include <linux/version.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
#include <linux/scatterlist.h>
#endif
@@ -76,6 +75,8 @@ struct {
#define SW_TYPE_ASYNC 0x8000
#define SW_TYPE_INUSE 0x10000000
/* We change some of the above if we have an async interface */
#define SW_TYPE_ALG_AMASK (SW_TYPE_ALG_MASK | SW_TYPE_ASYNC)
@@ -87,9 +88,11 @@ struct {
#define SCATTERLIST_MAX 16
struct swcr_data {
struct work_struct workq;
int sw_type;
int sw_alg;
struct crypto_tfm *sw_tfm;
spinlock_t sw_tfm_lock;
union {
struct {
char *sw_key;
@@ -153,6 +156,9 @@ static struct kmem_cache *swcr_req_cache;
#define crypto_blkcipher_decrypt_iv(W, X, Y, Z) \
crypto_cipher_decrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
#define crypto_blkcipher_set_flags(x, y) /* nop */
#define crypto_free_blkcipher(x) crypto_free_tfm(x)
#define crypto_free_comp crypto_free_tfm
#define crypto_free_hash crypto_free_tfm
/* Hash/HMAC/Digest */
struct hash_desc
@@ -278,6 +284,54 @@ MODULE_PARM_DESC(swcr_debug, "Enable debug");
static void swcr_process_req(struct swcr_req *req);
/*
* somethings just need to be run with user context no matter whether
* the kernel compression libs use vmalloc/vfree for example.
*/
typedef struct {
struct work_struct wq;
void (*func)(void *arg);
void *arg;
} execute_later_t;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
static void
doing_it_now(struct work_struct *wq)
{
execute_later_t *w = container_of(wq, execute_later_t, wq);
(w->func)(w->arg);
kfree(w);
}
#else
static void
doing_it_now(void *arg)
{
execute_later_t *w = (execute_later_t *) arg;
(w->func)(w->arg);
kfree(w);
}
#endif
static void
execute_later(void (fn)(void *), void *arg)
{
execute_later_t *w;
w = (execute_later_t *) kmalloc(sizeof(execute_later_t), SLAB_ATOMIC);
if (w) {
memset(w, '\0', sizeof(w));
w->func = fn;
w->arg = arg;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
INIT_WORK(&w->wq, doing_it_now);
#else
INIT_WORK(&w->wq, doing_it_now, w);
#endif
schedule_work(&w->wq);
}
}
/*
* Generate a new software session.
*/
@@ -363,6 +417,8 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
(*swd)->sw_type = crypto_details[cri->cri_alg].sw_type;
(*swd)->sw_alg = cri->cri_alg;
spin_lock_init(&(*swd)->sw_tfm_lock);
/* Algorithm specific configuration */
switch (cri->cri_alg) {
case CRYPTO_NULL_CBC:
@@ -379,19 +435,23 @@ swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
/* try async first */
(*swd)->sw_tfm = swcr_no_ablk ? NULL :
crypto_ablkcipher_tfm(crypto_alloc_ablkcipher(algo, 0, 0));
if ((*swd)->sw_tfm) {
if ((*swd)->sw_tfm && !IS_ERR((*swd)->sw_tfm)) {
dprintk("%s %s cipher is async\n", __FUNCTION__, algo);
(*swd)->sw_type |= SW_TYPE_ASYNC;
} else {
dprintk("%s %s cipher is sync\n", __FUNCTION__, algo);
(*swd)->sw_tfm = crypto_blkcipher_tfm(
crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC));
if ((*swd)->sw_tfm && !IS_ERR((*swd)->sw_tfm))
dprintk("%s %s cipher is sync\n", __FUNCTION__, algo);
}
if (!(*swd)->sw_tfm) {
if (!(*swd)->sw_tfm || IS_ERR((*swd)->sw_tfm)) {
int err;
dprintk("cryptosoft: crypto_alloc_blkcipher failed(%s, 0x%x)\n",
algo,mode);
err = IS_ERR((*swd)->sw_tfm) ? -(PTR_ERR((*swd)->sw_tfm)) : EINVAL;
(*swd)->sw_tfm = NULL; /* ensure NULL */
swcr_freesession(NULL, i);
return EINVAL;
return err;
}
if (debug) {
@@ -536,7 +596,11 @@ swcr_freesession(device_t dev, u_int64_t tid)
crypto_free_hash(crypto_hash_cast(swd->sw_tfm));
break;
case SW_TYPE_COMP:
crypto_free_comp(crypto_comp_cast(swd->sw_tfm));
if (in_interrupt())
execute_later((void (*)(void *))crypto_free_comp, (void *)crypto_comp_cast(swd->sw_tfm));
else
crypto_free_comp(crypto_comp_cast(swd->sw_tfm));
break;
default:
crypto_free_tfm(swd->sw_tfm);
break;
@@ -555,32 +619,40 @@ swcr_freesession(device_t dev, u_int64_t tid)
return 0;
}
#if defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH)
/* older kernels had no async interface */
static void swcr_process_callback(struct crypto_async_request *creq, int err)
static void swcr_process_req_complete(struct swcr_req *req)
{
struct swcr_req *req = creq->data;
dprintk("%s()\n", __FUNCTION__);
if (err) {
if (err == -EINPROGRESS)
return;
dprintk("%s() fail %d\n", __FUNCTION__, -err);
req->crp->crp_etype = -err;
goto done;
if (req->sw->sw_type & SW_TYPE_INUSE) {
unsigned long flags;
spin_lock_irqsave(&req->sw->sw_tfm_lock, flags);
req->sw->sw_type &= ~SW_TYPE_INUSE;
spin_unlock_irqrestore(&req->sw->sw_tfm_lock, flags);
}
if (req->crp->crp_etype)
goto done;
switch (req->sw->sw_type & SW_TYPE_ALG_AMASK) {
#if defined(HAVE_AHASH)
case SW_TYPE_AHMAC:
case SW_TYPE_AHASH:
crypto_copyback(req->crp->crp_flags, req->crp->crp_buf,
req->crd->crd_inject, req->sw->u.hmac.sw_mlen, req->result);
ahash_request_free(req->crypto_req);
break;
#endif
#if defined(HAVE_ABLKCIPHER)
case SW_TYPE_ABLKCIPHER:
ablkcipher_request_free(req->crypto_req);
break;
#endif
case SW_TYPE_CIPHER:
case SW_TYPE_HMAC:
case SW_TYPE_HASH:
case SW_TYPE_COMP:
case SW_TYPE_BLKCIPHER:
break;
default:
req->crp->crp_etype = EINVAL;
goto done;
@@ -597,6 +669,22 @@ done:
crypto_done(req->crp);
kmem_cache_free(swcr_req_cache, req);
}
#if defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH)
static void swcr_process_callback(struct crypto_async_request *creq, int err)
{
struct swcr_req *req = creq->data;
dprintk("%s()\n", __FUNCTION__);
if (err) {
if (err == -EINPROGRESS)
return;
dprintk("%s() fail %d\n", __FUNCTION__, -err);
req->crp->crp_etype = -err;
}
swcr_process_req_complete(req);
}
#endif /* defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH) */
@@ -631,6 +719,29 @@ static void swcr_process_req(struct swcr_req *req)
goto done;
}
/*
* for some types we need to ensure only one user as info is stored in
* the tfm during an operation that can get corrupted
*/
switch (sw->sw_type & SW_TYPE_ALG_AMASK) {
#ifdef HAVE_AHASH
case SW_TYPE_AHMAC:
case SW_TYPE_AHASH:
#endif
case SW_TYPE_HMAC:
case SW_TYPE_HASH: {
unsigned long flags;
spin_lock_irqsave(&sw->sw_tfm_lock, flags);
if (sw->sw_type & SW_TYPE_INUSE) {
spin_unlock_irqrestore(&sw->sw_tfm_lock, flags);
execute_later((void (*)(void *))swcr_process_req, (void *)req);
return;
}
sw->sw_type |= SW_TYPE_INUSE;
spin_unlock_irqrestore(&sw->sw_tfm_lock, flags);
} break;
}
req->sw = sw;
skip = crd->crd_skip;
@@ -722,7 +833,7 @@ static void swcr_process_req(struct swcr_req *req)
}
req->crypto_req =
ahash_request_alloc(__crypto_ahash_cast(sw->sw_tfm),GFP_KERNEL);
ahash_request_alloc(__crypto_ahash_cast(sw->sw_tfm),GFP_ATOMIC);
if (!req->crypto_req) {
crp->crp_etype = ENOMEM;
dprintk("%s,%d: ENOMEM ahash_request_alloc", __FILE__, __LINE__);
@@ -747,7 +858,6 @@ static void swcr_process_req(struct swcr_req *req)
case 0:
dprintk("hash OP %s %d\n", ret ? "failed" : "success", ret);
crp->crp_etype = ret;
ahash_request_free(req->crypto_req);
goto done;
}
} break;
@@ -776,7 +886,7 @@ static void swcr_process_req(struct swcr_req *req)
}
req->crypto_req = ablkcipher_request_alloc(
__crypto_ablkcipher_cast(sw->sw_tfm), GFP_KERNEL);
__crypto_ablkcipher_cast(sw->sw_tfm), GFP_ATOMIC);
if (!req->crypto_req) {
crp->crp_etype = ENOMEM;
dprintk("%s,%d: ENOMEM ablkcipher_request_alloc",
@@ -1028,8 +1138,6 @@ static void swcr_process_req(struct swcr_req *req)
crd->crd_inject, olen, obuf);
crp->crp_olen = olen;
}
} break;
default:
@@ -1040,8 +1148,7 @@ static void swcr_process_req(struct swcr_req *req)
}
done:
crypto_done(crp);
kmem_cache_free(swcr_req_cache, req);
swcr_process_req_complete(req);
}
@@ -1209,5 +1316,5 @@ late_initcall(cryptosoft_init);
module_exit(cryptosoft_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
MODULE_DESCRIPTION("Cryptosoft (OCF module for kernel crypto)");

View File

@@ -47,10 +47,8 @@ __FBSDID("$FreeBSD: src/sys/dev/hifn/hifn7751.c,v 1.40 2007/03/21 03:42:49 sam E
* Driver for various Hifn encryption processors.
*/
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
@@ -63,7 +61,6 @@ __FBSDID("$FreeBSD: src/sys/dev/hifn/hifn7751.c,v 1.40 2007/03/21 03:42:49 sam E
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/random.h>
#include <linux/version.h>
#include <linux/skbuff.h>
#include <asm/io.h>
@@ -437,7 +434,7 @@ hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent)
if (pci_enable_device(dev) < 0)
return(-ENODEV);
#ifdef CONFIG_HAVE_PCI_SET_MWI
#ifdef HAVE_PCI_SET_MWI
if (pci_set_mwi(dev))
return(-ENODEV);
#endif
@@ -873,7 +870,7 @@ hifn_set_retry(struct hifn_softc *sc)
DPRINTF("%s()\n", __FUNCTION__);
/* NB: RETRY only responds to 8-bit reads/writes */
pci_write_config_byte(sc->sc_pcidev, HIFN_RETRY_TIMEOUT, 0);
pci_write_config_dword(sc->sc_pcidev, HIFN_TRDY_TIMEOUT, 0);
pci_write_config_byte(sc->sc_pcidev, HIFN_TRDY_TIMEOUT, 0);
/* piggy back the cache line setting here */
pci_write_config_byte(sc->sc_pcidev, PCI_CACHE_LINE_SIZE, hifn_cache_linesize);
}
@@ -2380,11 +2377,6 @@ hifn_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
case CRYPTO_DES_CBC:
case CRYPTO_3DES_CBC:
case CRYPTO_AES_CBC:
/* XXX this may read fewer, does it matter? */
read_random(ses->hs_iv,
c->cri_alg == CRYPTO_AES_CBC ?
HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
/*FALLTHROUGH*/
case CRYPTO_ARC4:
if (cry) {
DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
@@ -2580,8 +2572,7 @@ hifn_process(device_t dev, struct cryptop *crp, int hint)
if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
bcopy(enccrd->crd_iv, cmd->iv, ivlen);
else
bcopy(sc->sc_sessions[session].hs_iv,
cmd->iv, ivlen);
read_random(cmd->iv, ivlen);
if ((enccrd->crd_flags & CRD_F_IV_PRESENT)
== 0) {
@@ -2786,7 +2777,7 @@ hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, u_int8_t *macbuf)
struct hifn_dma *dma = sc->sc_dma;
struct cryptop *crp = cmd->crp;
struct cryptodesc *crd;
int i, u, ivlen;
int i, u;
DPRINTF("%s()\n", __FUNCTION__);
@@ -2851,22 +2842,6 @@ hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, u_int8_t *macbuf)
hifnstats.hst_obytes += cmd->dst_mapsize;
if ((cmd->base_masks & (HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE)) ==
HIFN_BASE_CMD_CRYPT) {
for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
if (crd->crd_alg != CRYPTO_DES_CBC &&
crd->crd_alg != CRYPTO_3DES_CBC &&
crd->crd_alg != CRYPTO_AES_CBC)
continue;
ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ?
HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
crypto_copydata(crp->crp_flags, crp->crp_buf,
crd->crd_skip + crd->crd_len - ivlen, ivlen,
cmd->softc->sc_sessions[cmd->session_num].hs_iv);
break;
}
}
if (macbuf != NULL) {
for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
int len;

View File

@@ -113,7 +113,6 @@ struct hifn_dma {
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) \

View File

@@ -33,10 +33,8 @@
* Driver for various Hifn encryption processors.
*/
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
@@ -49,7 +47,6 @@
#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>
@@ -211,7 +208,7 @@ hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent)
if (pci_enable_device(dev) < 0)
return(-ENODEV);
#ifdef CONFIG_HAVE_PCI_SET_MWI
#ifdef HAVE_PCI_SET_MWI
if (pci_set_mwi(dev))
return(-ENODEV);
#endif

View File

@@ -4,7 +4,7 @@
* from Intel in order to operate (or compile).
*
* Written by David McCullough <david_mccullough@mcafee.com>
* Copyright (C) 2006-2010 David McCullough
* Copyright (C) 2006-2011 David McCullough
* Copyright (C) 2004-2005 Intel Corporation.
*
* LICENSE TERMS
@@ -34,10 +34,8 @@
*/
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
@@ -448,14 +446,28 @@ ixp_q_process(struct ixp_q *q)
dprintk("%s(%p)\n", __FUNCTION__, q);
if (q->ixp_q_ccrd) {
if (q->ixp_q_ccrd->crd_flags & CRD_F_IV_EXPLICIT) {
q->ixp_q_iv = q->ixp_q_ccrd->crd_iv;
if (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT) {
if (q->ixp_q_ccrd->crd_flags & CRD_F_IV_EXPLICIT) {
q->ixp_q_iv = q->ixp_q_ccrd->crd_iv;
} else {
q->ixp_q_iv = q->ixp_q_iv_data;
read_random(q->ixp_q_iv, ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen);
}
if ((q->ixp_q_ccrd->crd_flags & CRD_F_IV_PRESENT) == 0)
crypto_copyback(q->ixp_q_crp->crp_flags, q->ixp_q_crp->crp_buf,
q->ixp_q_ccrd->crd_inject,
ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen,
(caddr_t) q->ixp_q_iv);
} else {
q->ixp_q_iv = q->ixp_q_iv_data;
crypto_copydata(q->ixp_q_crp->crp_flags, q->ixp_q_crp->crp_buf,
q->ixp_q_ccrd->crd_inject,
ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen,
(caddr_t) q->ixp_q_iv);
if (q->ixp_q_ccrd->crd_flags & CRD_F_IV_EXPLICIT)
q->ixp_q_iv = q->ixp_q_ccrd->crd_iv;
else {
q->ixp_q_iv = q->ixp_q_iv_data;
crypto_copydata(q->ixp_q_crp->crp_flags, q->ixp_q_crp->crp_buf,
q->ixp_q_ccrd->crd_inject,
ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen,
(caddr_t) q->ixp_q_iv);
}
}
if (q->ixp_q_acrd) {

View File

@@ -0,0 +1,123 @@
static MV_U8 mask[256] = {
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
static MV_U8 Logtable[256] = {
0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238, 223, 3,
100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200, 248, 105, 28, 193,
125, 194, 29, 181, 249, 185, 39, 106, 77, 228, 166, 114, 154, 201, 9, 120,
101, 47, 138, 5, 33, 15, 225, 36, 18, 240, 130, 69, 53, 147, 218, 142,
150, 143, 219, 189, 54, 208, 206, 148, 19, 92, 210, 241, 64, 70, 131, 56,
102, 221, 253, 48, 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16,
126, 110, 72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186,
43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115, 167, 87,
175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213, 231, 230, 173, 232,
44, 215, 117, 122, 235, 22, 11, 245, 89, 203, 95, 176, 156, 169, 81, 160,
127, 12, 246, 111, 23, 196, 73, 236, 216, 67, 31, 45, 164, 118, 123, 183,
204, 187, 62, 90, 251, 96, 177, 134, 59, 82, 161, 108, 170, 85, 41, 157,
151, 178, 135, 144, 97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209,
83, 57, 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171,
68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153, 227, 165,
103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128, 192, 247, 112, 7,
};
static MV_U8 Alogtable[512] = {
1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53,
95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170,
229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49,
83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154,
181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160,
251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65,
195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128,
155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84,
252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202,
69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1,
3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53,
95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170,
229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49,
83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154,
181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160,
251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65,
195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128,
155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84,
252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202,
69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1,
};
static MV_U8 S[256] = {
99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118,
202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21,
4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117,
9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132,
83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207,
208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210,
205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115,
96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121,
231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8,
186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138,
112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22,
};
static MV_U8 Si[256] = {
82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251,
124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203,
84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78,
8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37,
114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146,
108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132,
144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6,
208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107,
58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115,
150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110,
71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27,
252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244,
31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95,
96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239,
160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125,
};
/*
static MV_U8 iG[4][4] = {
{0x0e, 0x09, 0x0d, 0x0b},
{0x0b, 0x0e, 0x09, 0x0d},
{0x0d, 0x0b, 0x0e, 0x09},
{0x09, 0x0d, 0x0b, 0x0e},
};
*/
static MV_U32 rcon[30] = {
0x01,0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, };

View File

@@ -27,10 +27,8 @@ disclaimer.
*******************************************************************************/
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
@@ -501,7 +499,7 @@ cesa_ocf_process(device_t dev, struct cryptop *crp, int hint)
if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
dprintk("%s,%d: copy the IV back to the buffer\n", __FILE__, __LINE__);
cesa_cmd->ivOffset = crd->crd_inject;
crypto_copy_bits_back(crp->crp_buf, crd->crd_inject, ivp, cesa_ocf_cur_ses->ivlen);
crypto_copyback(crp->crp_flags, crp->crp_buf, crd->crd_inject, cesa_ocf_cur_ses->ivlen, ivp);
}
else {
dprintk("%s,%d: don't copy the IV back to the buffer \n", __FILE__, __LINE__);

View File

@@ -31,10 +31,8 @@
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
@@ -43,7 +41,6 @@
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/version.h>
#include <linux/interrupt.h>
#include <cryptodev.h>
@@ -70,22 +67,38 @@
/*
* the number of simultaneously active requests
*/
static int request_q_len = 20;
static int request_q_len = 40;
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;
static int request_size = 1488;
module_param(request_size, int, 0);
MODULE_PARM_DESC(request_size, "size of each request");
/*
* OCF batching of requests
*/
static int request_batch = 1;
module_param(request_batch, int, 0);
MODULE_PARM_DESC(request_batch, "enable OCF request batching");
/*
* OCF immediate callback on completion
*/
static int request_cbimm = 1;
module_param(request_cbimm, int, 0);
MODULE_PARM_DESC(request_cbimm, "enable OCF immediate callback on completion");
/*
* a structure for each request
*/
@@ -99,6 +112,7 @@ typedef struct {
static request_t *requests;
static spinlock_t ocfbench_counter_lock;
static int outstanding;
static int total;
@@ -108,6 +122,8 @@ static int total;
*/
static uint64_t ocf_cryptoid;
static unsigned long jstart, jstop;
static int ocf_init(void);
static int ocf_cb(struct cryptop *crp);
static void ocf_request(void *arg);
@@ -131,13 +147,15 @@ ocf_init(void)
cria.cri_klen = 20 * 8;
cria.cri_key = "0123456789abcdefghij";
crie.cri_alg = CRYPTO_3DES_CBC;
//crie.cri_alg = CRYPTO_3DES_CBC;
crie.cri_alg = CRYPTO_AES_CBC;
crie.cri_klen = 24 * 8;
crie.cri_key = "0123456789abcdefghijklmn";
crie.cri_next = &cria;
error = crypto_newsession(&ocf_cryptoid, &crie, 0);
error = crypto_newsession(&ocf_cryptoid, &crie,
CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE);
if (error) {
printk("crypto_newsession failed %d\n", error);
return -1;
@@ -149,23 +167,23 @@ static int
ocf_cb(struct cryptop *crp)
{
request_t *r = (request_t *) crp->crp_opaque;
unsigned long flags;
if (crp->crp_etype)
printk("Error in OCF processing: %d\n", crp->crp_etype);
total++;
crypto_freereq(crp);
crp = NULL;
if (total > request_num) {
/* do all requests but take at least 1 second */
spin_lock_irqsave(&ocfbench_counter_lock, flags);
total++;
if (total > request_num && jstart + HZ < jiffies) {
outstanding--;
spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
return 0;
}
spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
#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;
}
@@ -177,9 +195,12 @@ ocf_request(void *arg)
request_t *r = arg;
struct cryptop *crp = crypto_getreq(2);
struct cryptodesc *crde, *crda;
unsigned long flags;
if (!crp) {
spin_lock_irqsave(&ocfbench_counter_lock, flags);
outstanding--;
spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
return;
}
@@ -198,12 +219,17 @@ ocf_request(void *arg)
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_alg = CRYPTO_3DES_CBC;
crde->crd_alg = CRYPTO_AES_CBC;
crde->crd_key = "0123456789abcdefghijklmn";
crde->crd_klen = 24 * 8;
crp->crp_ilen = request_size + 64;
crp->crp_flags = CRYPTO_F_CBIMM;
crp->crp_flags = 0;
if (request_batch)
crp->crp_flags |= CRYPTO_F_BATCH;
if (request_cbimm)
crp->crp_flags |= CRYPTO_F_CBIMM;
crp->crp_buf = (caddr_t) r->buffer;
crp->crp_callback = ocf_cb;
crp->crp_sid = ocf_cryptoid;
@@ -220,6 +246,12 @@ ocf_request_wq(struct work_struct *work)
}
#endif
static void
ocf_done(void)
{
crypto_freesession(ocf_cryptoid);
}
/*************************************************************************/
#ifdef BENCH_IXP_ACCESS_LIB
/*************************************************************************/
@@ -306,24 +338,25 @@ ixp_perform_cb(
IxCryptoAccStatus status)
{
request_t *r = NULL;
unsigned long flags;
/* do all requests but take at least 1 second */
spin_lock_irqsave(&ocfbench_counter_lock, flags);
total++;
if (total > request_num) {
if (total > request_num && jstart + HZ < jiffies) {
outstanding--;
spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
return;
}
if (!sbufp || !(r = IX_MBUF_PRIV(sbufp))) {
printk("crappo %p %p\n", sbufp, r);
outstanding--;
spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
return;
}
spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
#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);
}
@@ -332,6 +365,7 @@ ixp_request(void *arg)
{
request_t *r = arg;
IxCryptoAccStatus status;
unsigned long flags;
memset(&r->mbuf, 0, sizeof(r->mbuf));
IX_MBUF_MLEN(&r->mbuf) = IX_MBUF_PKT_LEN(&r->mbuf) = request_size + 64;
@@ -341,7 +375,9 @@ ixp_request(void *arg)
0, request_size, 0, request_size, request_size, r->buffer);
if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
printk("status1 = %d\n", status);
spin_lock_irqsave(&ocfbench_counter_lock, flags);
outstanding--;
spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
return;
}
return;
@@ -356,6 +392,12 @@ ixp_request_wq(struct work_struct *work)
}
#endif
static void
ixp_done(void)
{
/* we should free the session here but I am lazy :-) */
}
/*************************************************************************/
#endif /* BENCH_IXP_ACCESS_LIB */
/*************************************************************************/
@@ -363,7 +405,9 @@ ixp_request_wq(struct work_struct *work)
int
ocfbench_init(void)
{
int i, jstart, jstop;
int i;
unsigned long mbps;
unsigned long flags;
printk("Crypto Speed tests\n");
@@ -375,6 +419,11 @@ ocfbench_init(void)
for (i = 0; i < request_q_len; i++) {
/* +64 for return data */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
INIT_WORK(&requests[i].work, ocf_request_wq);
#else
INIT_WORK(&requests[i].work, ocf_request, &requests[i]);
#endif
requests[i].buffer = kmalloc(request_size + 128, GFP_DMA);
if (!requests[i].buffer) {
printk("malloc failed\n");
@@ -387,19 +436,31 @@ ocfbench_init(void)
* OCF benchmark
*/
printk("OCF: testing ...\n");
ocf_init();
if (ocf_init() == -1)
return -EINVAL;
spin_lock_init(&ocfbench_counter_lock);
total = outstanding = 0;
jstart = jiffies;
for (i = 0; i < request_q_len; i++) {
spin_lock_irqsave(&ocfbench_counter_lock, flags);
outstanding++;
spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
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);
mbps = 0;
if (jstop > jstart) {
mbps = (unsigned long) total * (unsigned long) request_size * 8;
mbps /= ((jstop - jstart) * 1000) / HZ;
}
printk("OCF: %d requests of %d bytes in %d jiffies (%d.%03d Mbps)\n",
total, request_size, (int)(jstop - jstart),
((int)mbps) / 1000, ((int)mbps) % 1000);
ocf_done();
#ifdef BENCH_IXP_ACCESS_LIB
/*
@@ -410,15 +471,29 @@ ocfbench_init(void)
total = outstanding = 0;
jstart = jiffies;
for (i = 0; i < request_q_len; i++) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
INIT_WORK(&requests[i].work, ixp_request_wq);
#else
INIT_WORK(&requests[i].work, ixp_request, &requests[i]);
#endif
spin_lock_irqsave(&ocfbench_counter_lock, flags);
outstanding++;
spin_unlock_irqrestore(&ocfbench_counter_lock, flags);
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);
mbps = 0;
if (jstop > jstart) {
mbps = (unsigned long) total * (unsigned long) request_size * 8;
mbps /= ((jstop - jstart) * 1000) / HZ;
}
printk("IXP: %d requests of %d bytes in %d jiffies (%d.%03d Mbps)\n",
total, request_size, jstop - jstart,
((int)mbps) / 1000, ((int)mbps) % 1000);
ixp_done();
#endif /* BENCH_IXP_ACCESS_LIB */
for (i = 0; i < request_q_len; i++)

View File

@@ -34,6 +34,11 @@
*/
/****************************************************************************/
#ifdef __KERNEL__
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
/*
* fake some BSD driver interface stuff specifically for OCF use
*/
@@ -288,6 +293,72 @@ static inline void *sg_virt(struct scatterlist *sg)
#define late_initcall(init) module_init(init)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) || !defined(CONFIG_SMP)
#define ocf_for_each_cpu(cpu) for ((cpu) = 0; (cpu) == 0; (cpu)++)
#else
#define ocf_for_each_cpu(cpu) for_each_present_cpu(cpu)
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
#include <linux/sched.h>
#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4)
struct ocf_thread {
struct task_struct *task;
int (*func)(void *arg);
void *arg;
};
/* thread startup helper func */
static inline int ocf_run_thread(void *arg)
{
struct ocf_thread *t = (struct ocf_thread *) arg;
if (!t)
return -1; /* very bad */
t->task = current;
daemonize();
spin_lock_irq(&current->sigmask_lock);
sigemptyset(&current->blocked);
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
return (*t->func)(t->arg);
}
#define kthread_create(f,a,fmt...) \
({ \
struct ocf_thread t; \
pid_t p; \
t.task = NULL; \
t.func = (f); \
t.arg = (a); \
p = kernel_thread(ocf_run_thread, &t, CLONE_FS|CLONE_FILES); \
while (p != (pid_t) -1 && t.task == NULL) \
schedule(); \
if (t.task) \
snprintf(t.task->comm, sizeof(t.task->comm), fmt); \
(t.task); \
})
#define kthread_bind(t,cpu) /**/
#define kthread_should_stop() (strcmp(current->comm, "stopping") == 0)
#define kthread_stop(t) \
({ \
strcpy((t)->comm, "stopping"); \
kill_proc((t)->pid, SIGTERM, 1); \
do { \
schedule(); \
} while (kill_proc((t)->pid, SIGTERM, 1) == 0); \
})
#else
#include <linux/kthread.h>
#endif
#endif /* __KERNEL__ */
/****************************************************************************/

View File

@@ -34,10 +34,8 @@
*/
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>

View File

@@ -18,10 +18,8 @@
*/
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
@@ -240,11 +238,6 @@ pasemi_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
if (encini) {
ses->ccmd = ccmd;
/* get an IV */
/* XXX may read fewer than requested */
get_random_bytes(ses->civ, sizeof(ses->civ));
ses->keysz = (encini->cri_klen - 63) / 64;
memcpy(ses->key, encini->cri_key, (ses->keysz + 1) * 8);
@@ -451,6 +444,8 @@ pasemi_process(device_t dev, struct cryptop *crp, int hint)
if (enccrd->crd_flags & CRD_F_ENCRYPT) {
if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
memcpy(ivp, enccrd->crd_iv, ivsize);
else
read_random(ivp, ivsize);
/* If IV is not present in the buffer already, it has to be copied there */
if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0)
crypto_copyback(crp->crp_flags, crp->crp_buf,

View File

@@ -36,10 +36,8 @@
*/
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
@@ -48,7 +46,6 @@
#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>
@@ -62,11 +59,6 @@
#error "Please do not enable OCF_RANDOMHARVEST unless you have applied patches"
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
#include <linux/sched.h>
#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0)
#endif
/*
* a hack to access the debug levels from the crypto driver
*/

View File

@@ -37,16 +37,13 @@
*/
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(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>

View File

@@ -0,0 +1,37 @@
/*
* until we find a cleaner way, include the BSD md5/sha1 code
* here
*/
#ifdef HMAC_HACK
#define LITTLE_ENDIAN 1234
#define BIG_ENDIAN 4321
#ifdef __LITTLE_ENDIAN
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#ifdef __BIG_ENDIAN
#define BYTE_ORDER BIG_ENDIAN
#endif
u_int8_t hmac_ipad_buffer[64] = {
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
};
u_int8_t hmac_opad_buffer[64] = {
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
};
#endif /* HMAC_HACK */

View File

@@ -32,10 +32,8 @@ __FBSDID("$FreeBSD: src/sys/dev/safe/safe.c,v 1.18 2007/03/21 03:42:50 sam Exp $
*/
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/kernel.h>
@@ -49,7 +47,6 @@ __FBSDID("$FreeBSD: src/sys/dev/safe/safe.c,v 1.18 2007/03/21 03:42:50 sam Exp $
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/random.h>
#include <linux/version.h>
#include <linux/skbuff.h>
#include <asm/io.h>
@@ -80,40 +77,11 @@ __FBSDID("$FreeBSD: src/sys/dev/safe/safe.c,v 1.18 2007/03/21 03:42:50 sam Exp $
*/
#define HMAC_HACK 1
#ifdef HMAC_HACK
#define LITTLE_ENDIAN 1234
#define BIG_ENDIAN 4321
#ifdef __LITTLE_ENDIAN
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#ifdef __BIG_ENDIAN
#define BYTE_ORDER BIG_ENDIAN
#endif
#include <safe/hmachack.h>
#include <safe/md5.h>
#include <safe/md5.c>
#include <safe/sha1.h>
#include <safe/sha1.c>
u_int8_t hmac_ipad_buffer[64] = {
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
};
u_int8_t hmac_opad_buffer[64] = {
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
};
#endif /* HMAC_HACK */
/* add proc entry for this */
@@ -564,10 +532,6 @@ safe_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
ses->ses_used = 1;
if (encini) {
/* get an IV */
/* XXX may read fewer than requested */
read_random(ses->ses_iv, sizeof(ses->ses_iv));
ses->ses_klen = encini->cri_klen;
if (encini->cri_key != NULL)
safe_setup_enckey(ses, encini->cri_key);
@@ -630,7 +594,7 @@ safe_process(device_t dev, struct cryptop *crp, int hint)
struct safe_ringentry *re;
struct safe_sarec *sa;
struct safe_pdesc *pd;
u_int32_t cmd0, cmd1, staterec;
u_int32_t cmd0, cmd1, staterec, rand_iv[4];
unsigned long flags;
DPRINTF(("%s()\n", __FUNCTION__));
@@ -779,7 +743,7 @@ safe_process(device_t dev, struct cryptop *crp, int hint)
if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
iv = enccrd->crd_iv;
else
iv = (caddr_t) ses->ses_iv;
read_random((iv = (caddr_t) &rand_iv[0]), sizeof(rand_iv));
if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
crypto_copyback(crp->crp_flags, crp->crp_buf,
enccrd->crd_inject, ivsize, iv);
@@ -1129,31 +1093,6 @@ safe_callback(struct safe_softc *sc, struct safe_ringentry *re)
return;
}
if (re->re_flags & SAFE_QFLAGS_COPYOUTIV) {
/* copy out IV for future use */
for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
int i;
int ivsize;
if (crd->crd_alg == CRYPTO_DES_CBC ||
crd->crd_alg == CRYPTO_3DES_CBC) {
ivsize = 2*sizeof(u_int32_t);
} else if (crd->crd_alg == CRYPTO_AES_CBC) {
ivsize = 4*sizeof(u_int32_t);
} else
continue;
crypto_copydata(crp->crp_flags, crp->crp_buf,
crd->crd_skip + crd->crd_len - ivsize, ivsize,
(caddr_t)sc->sc_sessions[re->re_sesn].ses_iv);
for (i = 0;
i < ivsize/sizeof(sc->sc_sessions[re->re_sesn].ses_iv[0]);
i++)
sc->sc_sessions[re->re_sesn].ses_iv[i] =
cpu_to_le32(sc->sc_sessions[re->re_sesn].ses_iv[i]);
break;
}
}
if (re->re_flags & SAFE_QFLAGS_COPYOUTICV) {
/* copy out ICV result */
for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
@@ -2005,10 +1944,12 @@ static int safe_probe(struct pci_dev *dev, const struct pci_device_id *ent)
return(-ENODEV);
}
#ifdef HAVE_PCI_SET_MWI
if (pci_set_mwi(dev)) {
printk("safe: pci_set_mwi failed!");
return(-ENODEV);
}
#endif
sc = (struct safe_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
if (!sc)

View File

@@ -145,7 +145,6 @@ struct safe_session {
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 {

View File

@@ -108,10 +108,8 @@
*/
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
#include <generated/autoconf.h>
#else
#include <linux/autoconf.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) && !defined(AUTOCONF_INCLUDED)
#include <linux/config.h>
#endif
#include <linux/module.h>
#include <linux/init.h>
@@ -123,7 +121,6 @@
#include <linux/dma-mapping.h> /* dma_map_single() */
#include <linux/moduleparam.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
#include <linux/platform_device.h>
#endif
@@ -421,10 +418,6 @@ talitos_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
ses->ses_used = 1;
if (encini) {
/* get an IV */
/* XXX may read fewer than requested */
read_random(ses->ses_iv, sizeof(ses->ses_iv));
ses->ses_klen = (encini->cri_klen + 7) / 8;
memcpy(ses->ses_key, encini->cri_key, ses->ses_klen);
if (macini) {
@@ -514,6 +507,7 @@ talitos_process(device_t dev, struct cryptop *crp, int hint)
int hmac_key, hmac_data, cipher_iv, cipher_key,
in_fifo, out_fifo, cipher_iv_out;
static int chsel = -1;
u_int32_t rand_iv[4];
DPRINTF("%s()\n", __FUNCTION__);
@@ -755,7 +749,7 @@ talitos_process(device_t dev, struct cryptop *crp, int hint)
if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
iv = enccrd->crd_iv;
else
iv = (caddr_t) ses->ses_iv;
read_random((iv = (caddr_t) rand_iv), sizeof(rand_iv));
if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
crypto_copyback(crp->crp_flags, crp->crp_buf,
enccrd->crd_inject, ivsize, iv);
@@ -764,9 +758,8 @@ talitos_process(device_t dev, struct cryptop *crp, int hint)
td->hdr |= TALITOS_DIR_INBOUND;
if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
iv = enccrd->crd_iv;
bcopy(enccrd->crd_iv, iv, ivsize);
} else {
iv = (caddr_t) ses->ses_iv;
iv = (caddr_t) rand_iv;
crypto_copydata(crp->crp_flags, crp->crp_buf,
enccrd->crd_inject, ivsize, iv);
}

View File

@@ -69,7 +69,6 @@ struct talitos_session {
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) */
};

View File

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

View File

@@ -0,0 +1,527 @@
/* $OpenBSD: queue.h,v 1.32 2007/04/30 18:42:34 pedro Exp $ */
/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. 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 University 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 REGENTS 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 REGENTS 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.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
*/
#ifndef _BSD_SYS_QUEUE_H_
#define _BSD_SYS_QUEUE_H_
/*
* This file defines five types of data structures: singly-linked lists,
* lists, simple queues, tail queues, and circular queues.
*
*
* A singly-linked list is headed by a single forward pointer. The elements
* are singly linked for minimum space and pointer manipulation overhead at
* the expense of O(n) removal for arbitrary elements. New elements can be
* added to the list after an existing element or at the head of the list.
* Elements being removed from the head of the list should use the explicit
* macro for this purpose for optimum efficiency. A singly-linked list may
* only be traversed in the forward direction. Singly-linked lists are ideal
* for applications with large datasets and few or no removals or for
* implementing a LIFO queue.
*
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
*
* A simple queue is headed by a pair of pointers, one the head of the
* list and the other to the tail of the list. The elements are singly
* linked to save space, so elements can only be removed from the
* head of the list. New elements can be added to the list before or after
* an existing element, at the head of the list, or at the end of the
* list. A simple queue may only be traversed in the forward direction.
*
* A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction.
*
* A circle queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or after
* an existing element, at the head of the list, or at the end of the list.
* A circle queue may be traversed in either direction, but has a more
* complex end of list detection.
*
* For details on the use of these macros, see the queue(3) manual page.
*/
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
#define _Q_INVALIDATE(a) (a) = ((void *)-1)
#else
#define _Q_INVALIDATE(a)
#endif
/*
* Singly-linked List definitions.
*/
#define BSD_SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first; /* first element */ \
}
#define BSD_SLIST_HEAD_INITIALIZER(head) \
{ NULL }
#define BSD_SLIST_ENTRY(type) \
struct { \
struct type *sle_next; /* next element */ \
}
/*
* Singly-linked List access methods.
*/
#define BSD_SLIST_FIRST(head) ((head)->slh_first)
#define BSD_SLIST_END(head) NULL
#define BSD_SLIST_EMPTY(head) (BSD_SLIST_FIRST(head) == BSD_SLIST_END(head))
#define BSD_SLIST_NEXT(elm, field) ((elm)->field.sle_next)
#define BSD_SLIST_FOREACH(var, head, field) \
for((var) = BSD_SLIST_FIRST(head); \
(var) != BSD_SLIST_END(head); \
(var) = BSD_SLIST_NEXT(var, field))
#define BSD_SLIST_FOREACH_PREVPTR(var, varp, head, field) \
for ((varp) = &BSD_SLIST_FIRST((head)); \
((var) = *(varp)) != BSD_SLIST_END(head); \
(varp) = &BSD_SLIST_NEXT((var), field))
/*
* Singly-linked List functions.
*/
#define BSD_SLIST_INIT(head) { \
BSD_SLIST_FIRST(head) = BSD_SLIST_END(head); \
}
#define BSD_SLIST_INSERT_AFTER(slistelm, elm, field) do { \
(elm)->field.sle_next = (slistelm)->field.sle_next; \
(slistelm)->field.sle_next = (elm); \
} while (0)
#define BSD_SLIST_INSERT_HEAD(head, elm, field) do { \
(elm)->field.sle_next = (head)->slh_first; \
(head)->slh_first = (elm); \
} while (0)
#define BSD_SLIST_REMOVE_NEXT(head, elm, field) do { \
(elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
} while (0)
#define BSD_SLIST_REMOVE_HEAD(head, field) do { \
(head)->slh_first = (head)->slh_first->field.sle_next; \
} while (0)
#define BSD_SLIST_REMOVE(head, elm, type, field) do { \
if ((head)->slh_first == (elm)) { \
BSD_SLIST_REMOVE_HEAD((head), field); \
} else { \
struct type *curelm = (head)->slh_first; \
\
while (curelm->field.sle_next != (elm)) \
curelm = curelm->field.sle_next; \
curelm->field.sle_next = \
curelm->field.sle_next->field.sle_next; \
_Q_INVALIDATE((elm)->field.sle_next); \
} \
} while (0)
/*
* List definitions.
*/
#define BSD_LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
#define BSD_LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define BSD_LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
}
/*
* List access methods
*/
#define BSD_LIST_FIRST(head) ((head)->lh_first)
#define BSD_LIST_END(head) NULL
#define BSD_LIST_EMPTY(head) (BSD_LIST_FIRST(head) == BSD_LIST_END(head))
#define BSD_LIST_NEXT(elm, field) ((elm)->field.le_next)
#define BSD_LIST_FOREACH(var, head, field) \
for((var) = BSD_LIST_FIRST(head); \
(var)!= BSD_LIST_END(head); \
(var) = BSD_LIST_NEXT(var, field))
/*
* List functions.
*/
#define BSD_LIST_INIT(head) do { \
BSD_LIST_FIRST(head) = BSD_LIST_END(head); \
} while (0)
#define BSD_LIST_INSERT_AFTER(listelm, elm, field) do { \
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
(listelm)->field.le_next->field.le_prev = \
&(elm)->field.le_next; \
(listelm)->field.le_next = (elm); \
(elm)->field.le_prev = &(listelm)->field.le_next; \
} while (0)
#define BSD_LIST_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.le_prev = (listelm)->field.le_prev; \
(elm)->field.le_next = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &(elm)->field.le_next; \
} while (0)
#define BSD_LIST_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
(head)->lh_first = (elm); \
(elm)->field.le_prev = &(head)->lh_first; \
} while (0)
#define BSD_LIST_REMOVE(elm, field) do { \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = (elm)->field.le_next; \
_Q_INVALIDATE((elm)->field.le_prev); \
_Q_INVALIDATE((elm)->field.le_next); \
} while (0)
#define BSD_LIST_REPLACE(elm, elm2, field) do { \
if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
(elm2)->field.le_next->field.le_prev = \
&(elm2)->field.le_next; \
(elm2)->field.le_prev = (elm)->field.le_prev; \
*(elm2)->field.le_prev = (elm2); \
_Q_INVALIDATE((elm)->field.le_prev); \
_Q_INVALIDATE((elm)->field.le_next); \
} while (0)
/*
* Simple queue definitions.
*/
#define BSD_SIMPLEQ_HEAD(name, type) \
struct name { \
struct type *sqh_first; /* first element */ \
struct type **sqh_last; /* addr of last next element */ \
}
#define BSD_SIMPLEQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).sqh_first }
#define BSD_SIMPLEQ_ENTRY(type) \
struct { \
struct type *sqe_next; /* next element */ \
}
/*
* Simple queue access methods.
*/
#define BSD_SIMPLEQ_FIRST(head) ((head)->sqh_first)
#define BSD_SIMPLEQ_END(head) NULL
#define BSD_SIMPLEQ_EMPTY(head) (BSD_SIMPLEQ_FIRST(head) == BSD_SIMPLEQ_END(head))
#define BSD_SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
#define BSD_SIMPLEQ_FOREACH(var, head, field) \
for((var) = BSD_SIMPLEQ_FIRST(head); \
(var) != BSD_SIMPLEQ_END(head); \
(var) = BSD_SIMPLEQ_NEXT(var, field))
/*
* Simple queue functions.
*/
#define BSD_SIMPLEQ_INIT(head) do { \
(head)->sqh_first = NULL; \
(head)->sqh_last = &(head)->sqh_first; \
} while (0)
#define BSD_SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
(head)->sqh_first = (elm); \
} while (0)
#define BSD_SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.sqe_next = NULL; \
*(head)->sqh_last = (elm); \
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (0)
#define BSD_SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
(head)->sqh_last = &(elm)->field.sqe_next; \
(listelm)->field.sqe_next = (elm); \
} while (0)
#define BSD_SIMPLEQ_REMOVE_HEAD(head, field) do { \
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
(head)->sqh_last = &(head)->sqh_first; \
} while (0)
/*
* Tail queue definitions.
*/
#define BSD_TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
}
#define BSD_TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define BSD_TAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
}
/*
* tail queue access methods
*/
#define BSD_TAILQ_FIRST(head) ((head)->tqh_first)
#define BSD_TAILQ_END(head) NULL
#define BSD_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define BSD_TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
/* XXX */
#define BSD_TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
#define BSD_TAILQ_EMPTY(head) \
(BSD_TAILQ_FIRST(head) == BSD_TAILQ_END(head))
#define BSD_TAILQ_FOREACH(var, head, field) \
for((var) = BSD_TAILQ_FIRST(head); \
(var) != BSD_TAILQ_END(head); \
(var) = BSD_TAILQ_NEXT(var, field))
#define BSD_TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for((var) = BSD_TAILQ_LAST(head, headname); \
(var) != BSD_TAILQ_END(head); \
(var) = BSD_TAILQ_PREV(var, headname, field))
/*
* Tail queue functions.
*/
#define BSD_TAILQ_INIT(head) do { \
(head)->tqh_first = NULL; \
(head)->tqh_last = &(head)->tqh_first; \
} while (0)
#define BSD_TAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
(head)->tqh_first->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(head)->tqh_first = (elm); \
(elm)->field.tqe_prev = &(head)->tqh_first; \
} while (0)
#define BSD_TAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &(elm)->field.tqe_next; \
} while (0)
#define BSD_TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
(elm)->field.tqe_next->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(listelm)->field.tqe_next = (elm); \
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (0)
#define BSD_TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (0)
#define BSD_TAILQ_REMOVE(head, elm, field) do { \
if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
_Q_INVALIDATE((elm)->field.tqe_prev); \
_Q_INVALIDATE((elm)->field.tqe_next); \
} while (0)
#define BSD_TAILQ_REPLACE(head, elm, elm2, field) do { \
if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
(elm2)->field.tqe_next->field.tqe_prev = \
&(elm2)->field.tqe_next; \
else \
(head)->tqh_last = &(elm2)->field.tqe_next; \
(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
*(elm2)->field.tqe_prev = (elm2); \
_Q_INVALIDATE((elm)->field.tqe_prev); \
_Q_INVALIDATE((elm)->field.tqe_next); \
} while (0)
/*
* Circular queue definitions.
*/
#define BSD_CIRCLEQ_HEAD(name, type) \
struct name { \
struct type *cqh_first; /* first element */ \
struct type *cqh_last; /* last element */ \
}
#define BSD_CIRCLEQ_HEAD_INITIALIZER(head) \
{ BSD_CIRCLEQ_END(&head), BSD_CIRCLEQ_END(&head) }
#define BSD_CIRCLEQ_ENTRY(type) \
struct { \
struct type *cqe_next; /* next element */ \
struct type *cqe_prev; /* previous element */ \
}
/*
* Circular queue access methods
*/
#define BSD_CIRCLEQ_FIRST(head) ((head)->cqh_first)
#define BSD_CIRCLEQ_LAST(head) ((head)->cqh_last)
#define BSD_CIRCLEQ_END(head) ((void *)(head))
#define BSD_CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
#define BSD_CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
#define BSD_CIRCLEQ_EMPTY(head) \
(BSD_CIRCLEQ_FIRST(head) == BSD_CIRCLEQ_END(head))
#define BSD_CIRCLEQ_FOREACH(var, head, field) \
for((var) = BSD_CIRCLEQ_FIRST(head); \
(var) != BSD_CIRCLEQ_END(head); \
(var) = BSD_CIRCLEQ_NEXT(var, field))
#define BSD_CIRCLEQ_FOREACH_REVERSE(var, head, field) \
for((var) = BSD_CIRCLEQ_LAST(head); \
(var) != BSD_CIRCLEQ_END(head); \
(var) = BSD_CIRCLEQ_PREV(var, field))
/*
* Circular queue functions.
*/
#define BSD_CIRCLEQ_INIT(head) do { \
(head)->cqh_first = BSD_CIRCLEQ_END(head); \
(head)->cqh_last = BSD_CIRCLEQ_END(head); \
} while (0)
#define BSD_CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
(elm)->field.cqe_prev = (listelm); \
if ((listelm)->field.cqe_next == BSD_CIRCLEQ_END(head)) \
(head)->cqh_last = (elm); \
else \
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
(listelm)->field.cqe_next = (elm); \
} while (0)
#define BSD_CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm); \
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
if ((listelm)->field.cqe_prev == BSD_CIRCLEQ_END(head)) \
(head)->cqh_first = (elm); \
else \
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
(listelm)->field.cqe_prev = (elm); \
} while (0)
#define BSD_CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
(elm)->field.cqe_next = (head)->cqh_first; \
(elm)->field.cqe_prev = BSD_CIRCLEQ_END(head); \
if ((head)->cqh_last == BSD_CIRCLEQ_END(head)) \
(head)->cqh_last = (elm); \
else \
(head)->cqh_first->field.cqe_prev = (elm); \
(head)->cqh_first = (elm); \
} while (0)
#define BSD_CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.cqe_next = BSD_CIRCLEQ_END(head); \
(elm)->field.cqe_prev = (head)->cqh_last; \
if ((head)->cqh_first == BSD_CIRCLEQ_END(head)) \
(head)->cqh_first = (elm); \
else \
(head)->cqh_last->field.cqe_next = (elm); \
(head)->cqh_last = (elm); \
} while (0)
#define BSD_CIRCLEQ_REMOVE(head, elm, field) do { \
if ((elm)->field.cqe_next == BSD_CIRCLEQ_END(head)) \
(head)->cqh_last = (elm)->field.cqe_prev; \
else \
(elm)->field.cqe_next->field.cqe_prev = \
(elm)->field.cqe_prev; \
if ((elm)->field.cqe_prev == BSD_CIRCLEQ_END(head)) \
(head)->cqh_first = (elm)->field.cqe_next; \
else \
(elm)->field.cqe_prev->field.cqe_next = \
(elm)->field.cqe_next; \
_Q_INVALIDATE((elm)->field.cqe_prev); \
_Q_INVALIDATE((elm)->field.cqe_next); \
} while (0)
#define BSD_CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
BSD_CIRCLEQ_END(head)) \
(head).cqh_last = (elm2); \
else \
(elm2)->field.cqe_next->field.cqe_prev = (elm2); \
if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
BSD_CIRCLEQ_END(head)) \
(head).cqh_first = (elm2); \
else \
(elm2)->field.cqe_prev->field.cqe_next = (elm2); \
_Q_INVALIDATE((elm)->field.cqe_prev); \
_Q_INVALIDATE((elm)->field.cqe_next); \
} while (0)
#endif /* !_BSD_SYS_QUEUE_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,233 @@
/*
* Copyright (c) 2008 Daniel Mueller (daniel@danm.de)
* Copyright (c) 2000 Theo de Raadt
* Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.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.
*
* 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.
*
*/
/*
* Register definitions for 5601 BlueSteel Networks Ubiquitous Broadband
* Security "uBSec" chip. Definitions from revision 2.8 of the product
* datasheet.
*/
#define BS_BAR 0x10 /* DMA base address register */
#define BS_TRDY_TIMEOUT 0x40 /* TRDY timeout */
#define BS_RETRY_TIMEOUT 0x41 /* DMA retry timeout */
#define UBS_PCI_RTY_SHIFT 8
#define UBS_PCI_RTY_MASK 0xff
#define UBS_PCI_RTY(misc) \
(((misc) >> UBS_PCI_RTY_SHIFT) & UBS_PCI_RTY_MASK)
#define UBS_PCI_TOUT_SHIFT 0
#define UBS_PCI_TOUT_MASK 0xff
#define UBS_PCI_TOUT(misc) \
(((misc) >> PCI_TOUT_SHIFT) & PCI_TOUT_MASK)
/*
* DMA Control & Status Registers (offset from BS_BAR)
*/
#define BS_MCR1 0x20 /* DMA Master Command Record 1 */
#define BS_CTRL 0x24 /* DMA Control */
#define BS_STAT 0x28 /* DMA Status */
#define BS_ERR 0x2c /* DMA Error Address */
#define BS_DEV_ID 0x34 /* IPSec Device ID */
/* BS_CTRL - DMA Control */
#define BS_CTRL_RESET 0x80000000 /* hardware reset, 5805/5820 */
#define BS_CTRL_MCR2INT 0x40000000 /* enable intr MCR for MCR2 */
#define BS_CTRL_MCR1INT 0x20000000 /* enable intr MCR for MCR1 */
#define BS_CTRL_OFM 0x10000000 /* Output fragment mode */
#define BS_CTRL_BE32 0x08000000 /* big-endian, 32bit bytes */
#define BS_CTRL_BE64 0x04000000 /* big-endian, 64bit bytes */
#define BS_CTRL_DMAERR 0x02000000 /* enable intr DMA error */
#define BS_CTRL_RNG_M 0x01800000 /* RNG mode */
#define BS_CTRL_RNG_1 0x00000000 /* 1bit rn/one slow clock */
#define BS_CTRL_RNG_4 0x00800000 /* 1bit rn/four slow clocks */
#define BS_CTRL_RNG_8 0x01000000 /* 1bit rn/eight slow clocks */
#define BS_CTRL_RNG_16 0x01800000 /* 1bit rn/16 slow clocks */
#define BS_CTRL_SWNORM 0x00400000 /* 582[01], sw normalization */
#define BS_CTRL_FRAG_M 0x0000ffff /* output fragment size mask */
#define BS_CTRL_LITTLE_ENDIAN (BS_CTRL_BE32 | BS_CTRL_BE64)
/* BS_STAT - DMA Status */
#define BS_STAT_MCR1_BUSY 0x80000000 /* MCR1 is busy */
#define BS_STAT_MCR1_FULL 0x40000000 /* MCR1 is full */
#define BS_STAT_MCR1_DONE 0x20000000 /* MCR1 is done */
#define BS_STAT_DMAERR 0x10000000 /* DMA error */
#define BS_STAT_MCR2_FULL 0x08000000 /* MCR2 is full */
#define BS_STAT_MCR2_DONE 0x04000000 /* MCR2 is done */
#define BS_STAT_MCR1_ALLEMPTY 0x02000000 /* 5821, MCR1 is empty */
#define BS_STAT_MCR2_ALLEMPTY 0x01000000 /* 5821, MCR2 is empty */
/* BS_ERR - DMA Error Address */
#define BS_ERR_ADDR 0xfffffffc /* error address mask */
#define BS_ERR_READ 0x00000002 /* fault was on read */
struct ubsec_pktctx {
u_int32_t pc_deskey[6]; /* 3DES key */
u_int32_t pc_hminner[5]; /* hmac inner state */
u_int32_t pc_hmouter[5]; /* hmac outer state */
u_int32_t pc_iv[2]; /* [3]DES iv */
u_int16_t pc_flags; /* flags, below */
u_int16_t pc_offset; /* crypto offset */
} __attribute__ ((packed));
#define UBS_PKTCTX_ENC_3DES 0x8000 /* use 3des */
#define UBS_PKTCTX_ENC_AES 0x8000 /* use aes */
#define UBS_PKTCTX_ENC_NONE 0x0000 /* no encryption */
#define UBS_PKTCTX_INBOUND 0x4000 /* inbound packet */
#define UBS_PKTCTX_AUTH 0x3000 /* authentication mask */
#define UBS_PKTCTX_AUTH_NONE 0x0000 /* no authentication */
#define UBS_PKTCTX_AUTH_MD5 0x1000 /* use hmac-md5 */
#define UBS_PKTCTX_AUTH_SHA1 0x2000 /* use hmac-sha1 */
#define UBS_PKTCTX_AES128 0x0 /* AES 128bit keys */
#define UBS_PKTCTX_AES192 0x100 /* AES 192bit keys */
#define UBS_PKTCTX_AES256 0x200 /* AES 256bit keys */
struct ubsec_pktctx_des {
volatile u_int16_t pc_len; /* length of ctx struct */
volatile u_int16_t pc_type; /* context type */
volatile u_int16_t pc_flags; /* flags, same as above */
volatile u_int16_t pc_offset; /* crypto/auth offset */
volatile u_int32_t pc_deskey[6]; /* 3DES key */
volatile u_int32_t pc_iv[2]; /* [3]DES iv */
volatile u_int32_t pc_hminner[5]; /* hmac inner state */
volatile u_int32_t pc_hmouter[5]; /* hmac outer state */
} __attribute__ ((packed));
struct ubsec_pktctx_aes128 {
volatile u_int16_t pc_len; /* length of ctx struct */
volatile u_int16_t pc_type; /* context type */
volatile u_int16_t pc_flags; /* flags, same as above */
volatile u_int16_t pc_offset; /* crypto/auth offset */
volatile u_int32_t pc_aeskey[4]; /* AES 128bit key */
volatile u_int32_t pc_iv[4]; /* AES iv */
volatile u_int32_t pc_hminner[5]; /* hmac inner state */
volatile u_int32_t pc_hmouter[5]; /* hmac outer state */
} __attribute__ ((packed));
struct ubsec_pktctx_aes192 {
volatile u_int16_t pc_len; /* length of ctx struct */
volatile u_int16_t pc_type; /* context type */
volatile u_int16_t pc_flags; /* flags, same as above */
volatile u_int16_t pc_offset; /* crypto/auth offset */
volatile u_int32_t pc_aeskey[6]; /* AES 192bit key */
volatile u_int32_t pc_iv[4]; /* AES iv */
volatile u_int32_t pc_hminner[5]; /* hmac inner state */
volatile u_int32_t pc_hmouter[5]; /* hmac outer state */
} __attribute__ ((packed));
struct ubsec_pktctx_aes256 {
volatile u_int16_t pc_len; /* length of ctx struct */
volatile u_int16_t pc_type; /* context type */
volatile u_int16_t pc_flags; /* flags, same as above */
volatile u_int16_t pc_offset; /* crypto/auth offset */
volatile u_int32_t pc_aeskey[8]; /* AES 256bit key */
volatile u_int32_t pc_iv[4]; /* AES iv */
volatile u_int32_t pc_hminner[5]; /* hmac inner state */
volatile u_int32_t pc_hmouter[5]; /* hmac outer state */
} __attribute__ ((packed));
#define UBS_PKTCTX_TYPE_IPSEC_DES 0x0000
#define UBS_PKTCTX_TYPE_IPSEC_AES 0x0040
struct ubsec_pktbuf {
volatile u_int32_t pb_addr; /* address of buffer start */
volatile u_int32_t pb_next; /* pointer to next pktbuf */
volatile u_int32_t pb_len; /* packet length */
} __attribute__ ((packed));
#define UBS_PKTBUF_LEN 0x0000ffff /* length mask */
struct ubsec_mcr {
volatile u_int16_t mcr_pkts; /* #pkts in this mcr */
volatile u_int16_t mcr_flags; /* mcr flags (below) */
volatile u_int32_t mcr_cmdctxp; /* command ctx pointer */
struct ubsec_pktbuf mcr_ipktbuf; /* input chain header */
volatile u_int16_t mcr_reserved;
volatile u_int16_t mcr_pktlen;
struct ubsec_pktbuf mcr_opktbuf; /* output chain header */
} __attribute__ ((packed));
struct ubsec_mcr_add {
volatile u_int32_t mcr_cmdctxp; /* command ctx pointer */
struct ubsec_pktbuf mcr_ipktbuf; /* input chain header */
volatile u_int16_t mcr_reserved;
volatile u_int16_t mcr_pktlen;
struct ubsec_pktbuf mcr_opktbuf; /* output chain header */
} __attribute__ ((packed));
#define UBS_MCR_DONE 0x0001 /* mcr has been processed */
#define UBS_MCR_ERROR 0x0002 /* error in processing */
#define UBS_MCR_ERRORCODE 0xff00 /* error type */
struct ubsec_ctx_keyop {
volatile u_int16_t ctx_len; /* command length */
volatile u_int16_t ctx_op; /* operation code */
volatile u_int8_t ctx_pad[60]; /* padding */
} __attribute__ ((packed));
#define UBS_CTXOP_DHPKGEN 0x01 /* dh public key generation */
#define UBS_CTXOP_DHSSGEN 0x02 /* dh shared secret gen. */
#define UBS_CTXOP_RSAPUB 0x03 /* rsa public key op */
#define UBS_CTXOP_RSAPRIV 0x04 /* rsa private key op */
#define UBS_CTXOP_DSASIGN 0x05 /* dsa signing op */
#define UBS_CTXOP_DSAVRFY 0x06 /* dsa verification */
#define UBS_CTXOP_RNGBYPASS 0x41 /* rng direct test mode */
#define UBS_CTXOP_RNGSHA1 0x42 /* rng sha1 test mode */
#define UBS_CTXOP_MODADD 0x43 /* modular addition */
#define UBS_CTXOP_MODSUB 0x44 /* modular subtraction */
#define UBS_CTXOP_MODMUL 0x45 /* modular multiplication */
#define UBS_CTXOP_MODRED 0x46 /* modular reduction */
#define UBS_CTXOP_MODEXP 0x47 /* modular exponentiation */
#define UBS_CTXOP_MODINV 0x48 /* modular inverse */
struct ubsec_ctx_rngbypass {
volatile u_int16_t rbp_len; /* command length, 64 */
volatile u_int16_t rbp_op; /* rng bypass, 0x41 */
volatile u_int8_t rbp_pad[60]; /* padding */
} __attribute__ ((packed));
/* modexp: C = (M ^ E) mod N */
struct ubsec_ctx_modexp {
volatile u_int16_t me_len; /* command length */
volatile u_int16_t me_op; /* modexp, 0x47 */
volatile u_int16_t me_E_len; /* E (bits) */
volatile u_int16_t me_N_len; /* N (bits) */
u_int8_t me_N[2048/8]; /* N */
} __attribute__ ((packed));
struct ubsec_ctx_rsapriv {
volatile u_int16_t rpr_len; /* command length */
volatile u_int16_t rpr_op; /* rsaprivate, 0x04 */
volatile u_int16_t rpr_q_len; /* q (bits) */
volatile u_int16_t rpr_p_len; /* p (bits) */
u_int8_t rpr_buf[5 * 1024 / 8]; /* parameters: */
/* p, q, dp, dq, pinv */
} __attribute__ ((packed));

View File

@@ -0,0 +1,228 @@
/*
* Copyright (c) 2008 Daniel Mueller (daniel@danm.de)
* Copyright (c) 2000 Theo de Raadt
* Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.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.
*
* 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.
*
*/
/* Maximum queue length */
#ifndef UBS_MAX_NQUEUE
#define UBS_MAX_NQUEUE 60
#endif
#define UBS_MAX_SCATTER 64 /* Maximum scatter/gather depth */
#ifndef UBS_MAX_AGGR
#define UBS_MAX_AGGR 5 /* Maximum aggregation count */
#endif
#define UBSEC_CARD(sid) (((sid) & 0xf0000000) >> 28)
#define UBSEC_SESSION(sid) ( (sid) & 0x0fffffff)
#define UBSEC_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
#define UBS_DEF_RTY 0xff /* PCI Retry Timeout */
#define UBS_DEF_TOUT 0xff /* PCI TRDY Timeout */
#define UBS_DEF_CACHELINE 0x01 /* Cache Line setting */
#define DEFAULT_HMAC_LEN 12
struct ubsec_dma_alloc {
dma_addr_t dma_paddr;
void *dma_vaddr;
/*
bus_dmamap_t dma_map;
bus_dma_segment_t dma_seg;
*/
size_t dma_size;
/*
int dma_nseg;
*/
};
struct ubsec_q2 {
BSD_SIMPLEQ_ENTRY(ubsec_q2) q_next;
struct ubsec_dma_alloc q_mcr;
struct ubsec_dma_alloc q_ctx;
u_int q_type;
};
struct ubsec_q2_rng {
struct ubsec_q2 rng_q;
struct ubsec_dma_alloc rng_buf;
int rng_used;
};
/* C = (M ^ E) mod N */
#define UBS_MODEXP_PAR_M 0
#define UBS_MODEXP_PAR_E 1
#define UBS_MODEXP_PAR_N 2
struct ubsec_q2_modexp {
struct ubsec_q2 me_q;
struct cryptkop * me_krp;
struct ubsec_dma_alloc me_M;
struct ubsec_dma_alloc me_E;
struct ubsec_dma_alloc me_C;
struct ubsec_dma_alloc me_epb;
int me_modbits;
int me_shiftbits;
int me_normbits;
};
#define UBS_RSAPRIV_PAR_P 0
#define UBS_RSAPRIV_PAR_Q 1
#define UBS_RSAPRIV_PAR_DP 2
#define UBS_RSAPRIV_PAR_DQ 3
#define UBS_RSAPRIV_PAR_PINV 4
#define UBS_RSAPRIV_PAR_MSGIN 5
#define UBS_RSAPRIV_PAR_MSGOUT 6
struct ubsec_q2_rsapriv {
struct ubsec_q2 rpr_q;
struct cryptkop * rpr_krp;
struct ubsec_dma_alloc rpr_msgin;
struct ubsec_dma_alloc rpr_msgout;
};
#define UBSEC_RNG_BUFSIZ 16 /* measured in 32bit words */
struct ubsec_dmachunk {
struct ubsec_mcr d_mcr;
struct ubsec_mcr_add d_mcradd[UBS_MAX_AGGR-1];
struct ubsec_pktbuf d_sbuf[UBS_MAX_SCATTER-1];
struct ubsec_pktbuf d_dbuf[UBS_MAX_SCATTER-1];
u_int32_t d_macbuf[5];
union {
struct ubsec_pktctx_aes256 ctxaes256;
struct ubsec_pktctx_aes192 ctxaes192;
struct ubsec_pktctx_des ctxdes;
struct ubsec_pktctx_aes128 ctxaes128;
struct ubsec_pktctx ctx;
} d_ctx;
};
struct ubsec_dma {
BSD_SIMPLEQ_ENTRY(ubsec_dma) d_next;
struct ubsec_dmachunk *d_dma;
struct ubsec_dma_alloc d_alloc;
};
#define UBS_FLAGS_KEY 0x01 /* has key accelerator */
#define UBS_FLAGS_LONGCTX 0x02 /* uses long ipsec ctx */
#define UBS_FLAGS_BIGKEY 0x04 /* 2048bit keys */
#define UBS_FLAGS_HWNORM 0x08 /* hardware normalization */
#define UBS_FLAGS_RNG 0x10 /* hardware rng */
#define UBS_FLAGS_AES 0x20 /* hardware AES support */
struct ubsec_q {
BSD_SIMPLEQ_ENTRY(ubsec_q) q_next;
int q_nstacked_mcrs;
struct ubsec_q *q_stacked_mcr[UBS_MAX_AGGR-1];
struct cryptop *q_crp;
struct ubsec_dma *q_dma;
//struct mbuf *q_src_m, *q_dst_m;
struct sk_buff *q_src_m, *q_dst_m;
struct uio *q_src_io, *q_dst_io;
/*
bus_dmamap_t q_src_map;
bus_dmamap_t q_dst_map;
*/
/* DMA addresses for In-/Out packages */
int q_src_len;
int q_dst_len;
struct ubsec_dma_alloc q_src_map[UBS_MAX_SCATTER];
struct ubsec_dma_alloc q_dst_map[UBS_MAX_SCATTER];
int q_has_dst;
int q_sesn;
int q_flags;
};
struct ubsec_softc {
softc_device_decl sc_dev;
struct ssb_device *sdev; /* device backpointer */
struct device *sc_dv; /* generic device */
void *sc_ih; /* interrupt handler cookie */
int sc_flags; /* device specific flags */
u_int32_t sc_statmask; /* interrupt status mask */
int32_t sc_cid; /* crypto tag */
BSD_SIMPLEQ_HEAD(,ubsec_q) sc_queue; /* packet queue, mcr1 */
int sc_nqueue; /* count enqueued, mcr1 */
BSD_SIMPLEQ_HEAD(,ubsec_q) sc_qchip; /* on chip, mcr1 */
BSD_SIMPLEQ_HEAD(,ubsec_q) sc_freequeue; /* list of free queue elements */
BSD_SIMPLEQ_HEAD(,ubsec_q2) sc_queue2; /* packet queue, mcr2 */
int sc_nqueue2; /* count enqueued, mcr2 */
BSD_SIMPLEQ_HEAD(,ubsec_q2) sc_qchip2; /* on chip, mcr2 */
int sc_nsessions; /* # of sessions */
struct ubsec_session *sc_sessions; /* sessions */
int sc_rnghz; /* rng poll time */
struct ubsec_q2_rng sc_rng;
struct ubsec_dma sc_dmaa[UBS_MAX_NQUEUE];
struct ubsec_q *sc_queuea[UBS_MAX_NQUEUE];
BSD_SIMPLEQ_HEAD(,ubsec_q2) sc_q2free; /* free list */
spinlock_t sc_ringmtx; /* PE ring lock */
};
#define UBSEC_QFLAGS_COPYOUTIV 0x1
struct ubsec_session {
u_int32_t ses_used;
u_int32_t ses_key[8]; /* 3DES/AES key */
u_int32_t ses_hminner[5]; /* hmac inner state */
u_int32_t ses_hmouter[5]; /* hmac outer state */
u_int32_t ses_iv[4]; /* [3]DES/AES iv */
u_int32_t ses_keysize; /* AES key size */
u_int32_t ses_mlen; /* hmac/hash length */
};
struct ubsec_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;
u_int32_t hst_queuefull;
u_int32_t hst_dmaerr;
u_int32_t hst_mcrerr;
u_int32_t hst_nodmafree;
};
struct ubsec_generic_ctx {
u_int32_t pc_key[8]; /* [3]DES/AES key */
u_int32_t pc_hminner[5]; /* hmac inner state */
u_int32_t pc_hmouter[5]; /* hmac outer state */
u_int32_t pc_iv[4]; /* [3]DES/AES iv */
u_int16_t pc_flags; /* flags, below */
u_int16_t pc_offset; /* crypto offset */
u_int16_t pc_type; /* Cryptographic operation */
};

View File

@@ -0,0 +1,132 @@
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -129,6 +129,9 @@
* unsigned int value);
* void add_interrupt_randomness(int irq);
*
+ * void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
+ * int random_input_wait(void);
+ *
* add_input_randomness() uses the input layer interrupt timing, as well as
* the event type information from the hardware.
*
@@ -140,6 +143,13 @@
* a better measure, since the timing of the disk interrupts are more
* unpredictable.
*
+ * random_input_words() just provides a raw block of entropy to the input
+ * pool, such as from a hardware entropy generator.
+ *
+ * random_input_wait() suspends the caller until such time as the
+ * entropy pool falls below the write threshold, and returns a count of how
+ * much entropy (in bits) is needed to sustain the pool.
+ *
* All of these routines try to estimate how many bits of randomness a
* particular randomness source. They do this by keeping track of the
* first and second order deltas of the event timings.
@@ -712,6 +722,61 @@ void add_disk_randomness(struct gendisk
}
#endif
+/*
+ * random_input_words - add bulk entropy to pool
+ *
+ * @buf: buffer to add
+ * @wordcount: number of __u32 words to add
+ * @ent_count: total amount of entropy (in bits) to credit
+ *
+ * this provides bulk input of entropy to the input pool
+ *
+ */
+void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
+{
+ mix_pool_bytes(&input_pool, buf, wordcount*4);
+
+ credit_entropy_bits(&input_pool, ent_count);
+
+ DEBUG_ENT("crediting %d bits => %d\n",
+ ent_count, input_pool.entropy_count);
+ /*
+ * Wake up waiting processes if we have enough
+ * entropy.
+ */
+ if (input_pool.entropy_count >= random_read_wakeup_thresh)
+ wake_up_interruptible(&random_read_wait);
+}
+EXPORT_SYMBOL(random_input_words);
+
+/*
+ * random_input_wait - wait until random needs entropy
+ *
+ * this function sleeps until the /dev/random subsystem actually
+ * needs more entropy, and then return the amount of entropy
+ * that it would be nice to have added to the system.
+ */
+int random_input_wait(void)
+{
+ int count;
+
+ wait_event_interruptible(random_write_wait,
+ input_pool.entropy_count < random_write_wakeup_thresh);
+
+ count = random_write_wakeup_thresh - input_pool.entropy_count;
+
+ /* likely we got woken up due to a signal */
+ if (count <= 0) count = random_read_wakeup_thresh;
+
+ DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
+ count,
+ input_pool.entropy_count, random_write_wakeup_thresh);
+
+ return count;
+}
+EXPORT_SYMBOL(random_input_wait);
+
+
#define EXTRACT_SIZE 10
/*********************************************************************
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -196,6 +196,7 @@ static int setfl(int fd, struct file * f
out:
return error;
}
+EXPORT_SYMBOL(sys_dup);
static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
uid_t uid, uid_t euid, int force)
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -12,6 +12,7 @@
#define APOLLO_MOUSE_MINOR 7
#define PC110PAD_MINOR 9
/*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
+#define CRYPTODEV_MINOR 70 /* /dev/crypto */
#define WATCHDOG_MINOR 130 /* Watchdog timer */
#define TEMP_MINOR 131 /* Temperature Sensor */
#define RTC_MINOR 135
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -50,6 +50,10 @@ extern void add_input_randomness(unsigne
unsigned int value);
extern void add_interrupt_randomness(int irq);
+extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
+extern int random_input_wait(void);
+#define HAS_RANDOM_INPUT_WAIT 1
+
extern void get_random_bytes(void *buf, int nbytes);
void generate_random_uuid(unsigned char uuid_out[16]);
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -383,6 +383,7 @@ struct task_struct *find_task_by_pid_typ
{
return pid_task(find_pid_ns(nr, ns), type);
}
+EXPORT_SYMBOL(find_task_by_vpid);
EXPORT_SYMBOL(find_task_by_pid_type_ns);

View File

@@ -24,7 +24,7 @@
* All of these routines try to estimate how many bits of randomness a
* particular randomness source. They do this by keeping track of the
* first and second order deltas of the event timings.
@@ -712,6 +722,61 @@ void add_disk_randomness(struct gendisk
@@ -712,6 +722,61 @@ void add_disk_randomness(struct gendisk
}
#endif
@@ -88,14 +88,14 @@
/*********************************************************************
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -141,6 +141,7 @@ SYSCALL_DEFINE1(dup, unsigned int, filde
}
return ret;
@@ -195,6 +195,7 @@ static int setfl(int fd, struct file * f
out:
return error;
}
+EXPORT_SYMBOL(sys_dup);
#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
int force)
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -12,6 +12,7 @@
@@ -108,46 +108,7 @@
#define RTC_MINOR 135
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -9,6 +9,7 @@
#include <linux/types.h>
#include <linux/ioctl.h>
+#include <linux/types.h> /* for __u32 in user space */
#include <linux/irqnr.h>
/* ioctl()'s for the random number generator */
@@ -34,6 +35,30 @@
/* Clear the entropy pool and associated counters. (Superuser only.) */
#define RNDCLEARPOOL _IO( 'R', 0x06 )
+#ifdef CONFIG_FIPS_RNG
+
+/* Size of seed value - equal to AES blocksize */
+#define AES_BLOCK_SIZE_BYTES 16
+#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
+/* Size of AES key */
+#define KEY_SIZE_BYTES 16
+
+/* ioctl() structure used by FIPS 140-2 Tests */
+struct rand_fips_test {
+ unsigned char key[KEY_SIZE_BYTES]; /* Input */
+ unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
+ unsigned char seed[SEED_SIZE_BYTES]; /* Input */
+ unsigned char result[SEED_SIZE_BYTES]; /* Output */
+};
+
+/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
+#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
+
+/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
+#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
+
+#endif /* #ifdef CONFIG_FIPS_RNG */
+
struct rand_pool_info {
int entropy_count;
int buf_size;
@@ -50,6 +75,10 @@ extern void add_input_randomness(unsigne
@@ -50,6 +50,10 @@ extern void add_input_randomness(unsigne
unsigned int value);
extern void add_interrupt_randomness(int irq);

View File

@@ -88,14 +88,14 @@
/*********************************************************************
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -141,6 +141,7 @@ SYSCALL_DEFINE1(dup, unsigned int, filde
}
return ret;
@@ -195,6 +195,7 @@ static int setfl(int fd, struct file * f
out:
return error;
}
+EXPORT_SYMBOL(sys_dup);
#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
int force)
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -12,6 +12,7 @@
@@ -108,46 +108,7 @@
#define RTC_MINOR 135
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -9,6 +9,7 @@
#include <linux/types.h>
#include <linux/ioctl.h>
+#include <linux/types.h> /* for __u32 in user space */
#include <linux/irqnr.h>
/* ioctl()'s for the random number generator */
@@ -34,6 +35,30 @@
/* Clear the entropy pool and associated counters. (Superuser only.) */
#define RNDCLEARPOOL _IO( 'R', 0x06 )
+#ifdef CONFIG_FIPS_RNG
+
+/* Size of seed value - equal to AES blocksize */
+#define AES_BLOCK_SIZE_BYTES 16
+#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
+/* Size of AES key */
+#define KEY_SIZE_BYTES 16
+
+/* ioctl() structure used by FIPS 140-2 Tests */
+struct rand_fips_test {
+ unsigned char key[KEY_SIZE_BYTES]; /* Input */
+ unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
+ unsigned char seed[SEED_SIZE_BYTES]; /* Input */
+ unsigned char result[SEED_SIZE_BYTES]; /* Output */
+};
+
+/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
+#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
+
+/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
+#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
+
+#endif /* #ifdef CONFIG_FIPS_RNG */
+
struct rand_pool_info {
int entropy_count;
int buf_size;
@@ -50,6 +75,10 @@ extern void add_input_randomness(unsigne
@@ -50,6 +50,10 @@ extern void add_input_randomness(unsigne
unsigned int value);
extern void add_interrupt_randomness(int irq);

View File

@@ -1,6 +1,6 @@
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -849,3 +849,6 @@ config CRYPTO_ANSI_CPRNG
@@ -845,3 +845,6 @@ config CRYPTO_ANSI_CPRNG
source "drivers/crypto/Kconfig"
endif # if CRYPTO

View File

@@ -1,170 +0,0 @@
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -129,6 +129,9 @@
* unsigned int value);
* void add_interrupt_randomness(int irq);
*
+ * void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
+ * int random_input_wait(void);
+ *
* add_input_randomness() uses the input layer interrupt timing, as well as
* the event type information from the hardware.
*
@@ -140,6 +143,13 @@
* a better measure, since the timing of the disk interrupts are more
* unpredictable.
*
+ * random_input_words() just provides a raw block of entropy to the input
+ * pool, such as from a hardware entropy generator.
+ *
+ * random_input_wait() suspends the caller until such time as the
+ * entropy pool falls below the write threshold, and returns a count of how
+ * much entropy (in bits) is needed to sustain the pool.
+ *
* All of these routines try to estimate how many bits of randomness a
* particular randomness source. They do this by keeping track of the
* first and second order deltas of the event timings.
@@ -715,6 +725,61 @@ void add_disk_randomness(struct gendisk
}
#endif
+/*
+ * random_input_words - add bulk entropy to pool
+ *
+ * @buf: buffer to add
+ * @wordcount: number of __u32 words to add
+ * @ent_count: total amount of entropy (in bits) to credit
+ *
+ * this provides bulk input of entropy to the input pool
+ *
+ */
+void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
+{
+ mix_pool_bytes(&input_pool, buf, wordcount*4);
+
+ credit_entropy_bits(&input_pool, ent_count);
+
+ DEBUG_ENT("crediting %d bits => %d\n",
+ ent_count, input_pool.entropy_count);
+ /*
+ * Wake up waiting processes if we have enough
+ * entropy.
+ */
+ if (input_pool.entropy_count >= random_read_wakeup_thresh)
+ wake_up_interruptible(&random_read_wait);
+}
+EXPORT_SYMBOL(random_input_words);
+
+/*
+ * random_input_wait - wait until random needs entropy
+ *
+ * this function sleeps until the /dev/random subsystem actually
+ * needs more entropy, and then return the amount of entropy
+ * that it would be nice to have added to the system.
+ */
+int random_input_wait(void)
+{
+ int count;
+
+ wait_event_interruptible(random_write_wait,
+ input_pool.entropy_count < random_write_wakeup_thresh);
+
+ count = random_write_wakeup_thresh - input_pool.entropy_count;
+
+ /* likely we got woken up due to a signal */
+ if (count <= 0) count = random_read_wakeup_thresh;
+
+ DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
+ count,
+ input_pool.entropy_count, random_write_wakeup_thresh);
+
+ return count;
+}
+EXPORT_SYMBOL(random_input_wait);
+
+
/*********************************************************************
*
* Entropy extraction routines
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -142,6 +142,7 @@ SYSCALL_DEFINE1(dup, unsigned int, filde
}
return ret;
}
+EXPORT_SYMBOL(sys_dup);
#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -18,6 +18,7 @@
#define APOLLO_MOUSE_MINOR 7
#define PC110PAD_MINOR 9
/*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
+#define CRYPTODEV_MINOR 70 /* /dev/crypto */
#define WATCHDOG_MINOR 130 /* Watchdog timer */
#define TEMP_MINOR 131 /* Temperature Sensor */
#define RTC_MINOR 135
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -9,6 +9,7 @@
#include <linux/types.h>
#include <linux/ioctl.h>
+#include <linux/types.h> /* for __u32 in user space */
#include <linux/irqnr.h>
/* ioctl()'s for the random number generator */
@@ -34,6 +35,30 @@
/* Clear the entropy pool and associated counters. (Superuser only.) */
#define RNDCLEARPOOL _IO( 'R', 0x06 )
+#ifdef CONFIG_FIPS_RNG
+
+/* Size of seed value - equal to AES blocksize */
+#define AES_BLOCK_SIZE_BYTES 16
+#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
+/* Size of AES key */
+#define KEY_SIZE_BYTES 16
+
+/* ioctl() structure used by FIPS 140-2 Tests */
+struct rand_fips_test {
+ unsigned char key[KEY_SIZE_BYTES]; /* Input */
+ unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
+ unsigned char seed[SEED_SIZE_BYTES]; /* Input */
+ unsigned char result[SEED_SIZE_BYTES]; /* Output */
+};
+
+/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
+#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
+
+/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
+#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
+
+#endif /* #ifdef CONFIG_FIPS_RNG */
+
struct rand_pool_info {
int entropy_count;
int buf_size;
@@ -54,6 +79,10 @@ extern void add_input_randomness(unsigne
unsigned int value);
extern void add_interrupt_randomness(int irq);
+extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
+extern int random_input_wait(void);
+#define HAS_RANDOM_INPUT_WAIT 1
+
extern void get_random_bytes(void *buf, int nbytes);
void generate_random_uuid(unsigned char uuid_out[16]);
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -423,6 +423,7 @@ struct task_struct *find_task_by_vpid(pi
{
return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns);
}
+EXPORT_SYMBOL(find_task_by_vpid);
struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
{

View File

@@ -1,3 +1,13 @@
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -423,6 +423,7 @@ struct task_struct *find_task_by_vpid(pi
{
return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns);
}
+EXPORT_SYMBOL(find_task_by_vpid);
struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
{
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -129,6 +129,9 @@
@@ -24,7 +34,7 @@
* All of these routines try to estimate how many bits of randomness a
* particular randomness source. They do this by keeping track of the
* first and second order deltas of the event timings.
@@ -712,6 +722,61 @@ void add_disk_randomness(struct gendisk
@@ -715,6 +725,63 @@ void add_disk_randomness(struct gendisk
}
#endif
@@ -83,9 +93,11 @@
+EXPORT_SYMBOL(random_input_wait);
+
+
#define EXTRACT_SIZE 10
+#define EXTRACT_SIZE 10
+
/*********************************************************************
*
* Entropy extraction routines
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -142,6 +142,7 @@ SYSCALL_DEFINE1(dup, unsigned int, filde
@@ -98,7 +110,7 @@
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -12,6 +12,7 @@
@@ -18,6 +18,7 @@
#define APOLLO_MOUSE_MINOR 7
#define PC110PAD_MINOR 9
/*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
@@ -108,46 +120,7 @@
#define RTC_MINOR 135
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -9,6 +9,7 @@
#include <linux/types.h>
#include <linux/ioctl.h>
+#include <linux/types.h> /* for __u32 in user space */
#include <linux/irqnr.h>
/* ioctl()'s for the random number generator */
@@ -34,6 +35,30 @@
/* Clear the entropy pool and associated counters. (Superuser only.) */
#define RNDCLEARPOOL _IO( 'R', 0x06 )
+#ifdef CONFIG_FIPS_RNG
+
+/* Size of seed value - equal to AES blocksize */
+#define AES_BLOCK_SIZE_BYTES 16
+#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
+/* Size of AES key */
+#define KEY_SIZE_BYTES 16
+
+/* ioctl() structure used by FIPS 140-2 Tests */
+struct rand_fips_test {
+ unsigned char key[KEY_SIZE_BYTES]; /* Input */
+ unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
+ unsigned char seed[SEED_SIZE_BYTES]; /* Input */
+ unsigned char result[SEED_SIZE_BYTES]; /* Output */
+};
+
+/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
+#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
+
+/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
+#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
+
+#endif /* #ifdef CONFIG_FIPS_RNG */
+
struct rand_pool_info {
int entropy_count;
int buf_size;
@@ -50,6 +75,10 @@ extern void add_input_randomness(unsigne
@@ -54,6 +54,10 @@ extern void add_input_randomness(unsigne
unsigned int value);
extern void add_interrupt_randomness(int irq);

View File

@@ -1,3 +1,13 @@
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -424,6 +424,7 @@ struct task_struct *find_task_by_vpid(pi
{
return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns);
}
+EXPORT_SYMBOL(find_task_by_vpid);
struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
{
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -129,6 +129,9 @@
@@ -24,7 +34,7 @@
* All of these routines try to estimate how many bits of randomness a
* particular randomness source. They do this by keeping track of the
* first and second order deltas of the event timings.
@@ -715,6 +725,61 @@ void add_disk_randomness(struct gendisk
@@ -715,6 +725,63 @@ void add_disk_randomness(struct gendisk
}
#endif
@@ -40,12 +50,12 @@
+ */
+void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
+{
+ mix_pool_bytes(&input_pool, buf, wordcount*4);
+ mix_pool_bytes(&input_pool, buf, wordcount*4);
+
+ credit_entropy_bits(&input_pool, ent_count);
+ credit_entropy_bits(&input_pool, ent_count);
+
+ DEBUG_ENT("crediting %d bits => %d\n",
+ ent_count, input_pool.entropy_count);
+ DEBUG_ENT("crediting %d bits => %d\n",
+ ent_count, input_pool.entropy_count);
+ /*
+ * Wake up waiting processes if we have enough
+ * entropy.
@@ -66,22 +76,24 @@
+{
+ int count;
+
+ wait_event_interruptible(random_write_wait,
+ input_pool.entropy_count < random_write_wakeup_thresh);
+ wait_event_interruptible(random_write_wait,
+ input_pool.entropy_count < random_write_wakeup_thresh);
+
+ count = random_write_wakeup_thresh - input_pool.entropy_count;
+
+ /* likely we got woken up due to a signal */
+ if (count <= 0) count = random_read_wakeup_thresh;
+ /* likely we got woken up due to a signal */
+ if (count <= 0) count = random_read_wakeup_thresh;
+
+ DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
+ count,
+ input_pool.entropy_count, random_write_wakeup_thresh);
+ count,
+ input_pool.entropy_count, random_write_wakeup_thresh);
+
+ return count;
+}
+EXPORT_SYMBOL(random_input_wait);
+
+
+#define EXTRACT_SIZE 10
+
/*********************************************************************
*
@@ -108,46 +120,7 @@
#define RTC_MINOR 135
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -9,6 +9,7 @@
#include <linux/types.h>
#include <linux/ioctl.h>
+#include <linux/types.h> /* for __u32 in user space */
#include <linux/irqnr.h>
/* ioctl()'s for the random number generator */
@@ -34,6 +35,30 @@
/* Clear the entropy pool and associated counters. (Superuser only.) */
#define RNDCLEARPOOL _IO( 'R', 0x06 )
+#ifdef CONFIG_FIPS_RNG
+
+/* Size of seed value - equal to AES blocksize */
+#define AES_BLOCK_SIZE_BYTES 16
+#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
+/* Size of AES key */
+#define KEY_SIZE_BYTES 16
+
+/* ioctl() structure used by FIPS 140-2 Tests */
+struct rand_fips_test {
+ unsigned char key[KEY_SIZE_BYTES]; /* Input */
+ unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
+ unsigned char seed[SEED_SIZE_BYTES]; /* Input */
+ unsigned char result[SEED_SIZE_BYTES]; /* Output */
+};
+
+/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
+#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
+
+/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
+#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
+
+#endif /* #ifdef CONFIG_FIPS_RNG */
+
struct rand_pool_info {
int entropy_count;
int buf_size;
@@ -54,6 +79,10 @@ extern void add_input_randomness(unsigne
@@ -54,6 +54,10 @@ extern void add_input_randomness(unsigne
unsigned int value);
extern void add_interrupt_randomness(int irq);
@@ -158,13 +131,3 @@
extern void get_random_bytes(void *buf, int nbytes);
void generate_random_uuid(unsigned char uuid_out[16]);
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -424,6 +424,7 @@ struct task_struct *find_task_by_vpid(pi
{
return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns);
}
+EXPORT_SYMBOL(find_task_by_vpid);
struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
{

View File

@@ -1,3 +1,13 @@
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -427,6 +427,7 @@ struct task_struct *find_task_by_vpid(pi
{
return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns);
}
+EXPORT_SYMBOL(find_task_by_vpid);
struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
{
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -129,6 +129,9 @@
@@ -24,7 +34,7 @@
* All of these routines try to estimate how many bits of randomness a
* particular randomness source. They do this by keeping track of the
* first and second order deltas of the event timings.
@@ -715,6 +725,61 @@ void add_disk_randomness(struct gendisk
@@ -715,6 +725,63 @@ void add_disk_randomness(struct gendisk
}
#endif
@@ -40,12 +50,12 @@
+ */
+void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
+{
+ mix_pool_bytes(&input_pool, buf, wordcount*4);
+ mix_pool_bytes(&input_pool, buf, wordcount*4);
+
+ credit_entropy_bits(&input_pool, ent_count);
+ credit_entropy_bits(&input_pool, ent_count);
+
+ DEBUG_ENT("crediting %d bits => %d\n",
+ ent_count, input_pool.entropy_count);
+ DEBUG_ENT("crediting %d bits => %d\n",
+ ent_count, input_pool.entropy_count);
+ /*
+ * Wake up waiting processes if we have enough
+ * entropy.
@@ -66,22 +76,24 @@
+{
+ int count;
+
+ wait_event_interruptible(random_write_wait,
+ input_pool.entropy_count < random_write_wakeup_thresh);
+ wait_event_interruptible(random_write_wait,
+ input_pool.entropy_count < random_write_wakeup_thresh);
+
+ count = random_write_wakeup_thresh - input_pool.entropy_count;
+
+ /* likely we got woken up due to a signal */
+ if (count <= 0) count = random_read_wakeup_thresh;
+ /* likely we got woken up due to a signal */
+ if (count <= 0) count = random_read_wakeup_thresh;
+
+ DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
+ count,
+ input_pool.entropy_count, random_write_wakeup_thresh);
+ count,
+ input_pool.entropy_count, random_write_wakeup_thresh);
+
+ return count;
+}
+EXPORT_SYMBOL(random_input_wait);
+
+
+#define EXTRACT_SIZE 10
+
/*********************************************************************
*
@@ -108,46 +120,7 @@
#define RTC_MINOR 135
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -9,6 +9,7 @@
#include <linux/types.h>
#include <linux/ioctl.h>
+#include <linux/types.h> /* for __u32 in user space */
#include <linux/irqnr.h>
/* ioctl()'s for the random number generator */
@@ -34,6 +35,30 @@
/* Clear the entropy pool and associated counters. (Superuser only.) */
#define RNDCLEARPOOL _IO( 'R', 0x06 )
+#ifdef CONFIG_FIPS_RNG
+
+/* Size of seed value - equal to AES blocksize */
+#define AES_BLOCK_SIZE_BYTES 16
+#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
+/* Size of AES key */
+#define KEY_SIZE_BYTES 16
+
+/* ioctl() structure used by FIPS 140-2 Tests */
+struct rand_fips_test {
+ unsigned char key[KEY_SIZE_BYTES]; /* Input */
+ unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
+ unsigned char seed[SEED_SIZE_BYTES]; /* Input */
+ unsigned char result[SEED_SIZE_BYTES]; /* Output */
+};
+
+/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
+#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
+
+/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
+#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
+
+#endif /* #ifdef CONFIG_FIPS_RNG */
+
struct rand_pool_info {
int entropy_count;
int buf_size;
@@ -54,6 +79,10 @@ extern void add_input_randomness(unsigne
@@ -54,6 +54,10 @@ extern void add_input_randomness(unsigne
unsigned int value);
extern void add_interrupt_randomness(int irq);
@@ -158,13 +131,3 @@
extern void get_random_bytes(void *buf, int nbytes);
void generate_random_uuid(unsigned char uuid_out[16]);
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -427,6 +427,7 @@ struct task_struct *find_task_by_vpid(pi
{
return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns);
}
+EXPORT_SYMBOL(find_task_by_vpid);
struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
{

View File

@@ -1,3 +1,13 @@
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -427,6 +427,7 @@ struct task_struct *find_task_by_vpid(pi
{
return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns);
}
+EXPORT_SYMBOL(find_task_by_vpid);
struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
{
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -130,6 +130,9 @@
@@ -24,7 +34,7 @@
* All of these routines try to estimate how many bits of randomness a
* particular randomness source. They do this by keeping track of the
* first and second order deltas of the event timings.
@@ -722,6 +732,61 @@ void add_disk_randomness(struct gendisk
@@ -722,6 +732,63 @@ void add_disk_randomness(struct gendisk
}
#endif
@@ -40,12 +50,12 @@
+ */
+void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
+{
+ mix_pool_bytes(&input_pool, buf, wordcount*4);
+ mix_pool_bytes(&input_pool, buf, wordcount*4);
+
+ credit_entropy_bits(&input_pool, ent_count);
+ credit_entropy_bits(&input_pool, ent_count);
+
+ DEBUG_ENT("crediting %d bits => %d\n",
+ ent_count, input_pool.entropy_count);
+ DEBUG_ENT("crediting %d bits => %d\n",
+ ent_count, input_pool.entropy_count);
+ /*
+ * Wake up waiting processes if we have enough
+ * entropy.
@@ -66,22 +76,24 @@
+{
+ int count;
+
+ wait_event_interruptible(random_write_wait,
+ input_pool.entropy_count < random_write_wakeup_thresh);
+ wait_event_interruptible(random_write_wait,
+ input_pool.entropy_count < random_write_wakeup_thresh);
+
+ count = random_write_wakeup_thresh - input_pool.entropy_count;
+
+ /* likely we got woken up due to a signal */
+ if (count <= 0) count = random_read_wakeup_thresh;
+ /* likely we got woken up due to a signal */
+ if (count <= 0) count = random_read_wakeup_thresh;
+
+ DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
+ count,
+ input_pool.entropy_count, random_write_wakeup_thresh);
+ count,
+ input_pool.entropy_count, random_write_wakeup_thresh);
+
+ return count;
+}
+EXPORT_SYMBOL(random_input_wait);
+
+
+#define EXTRACT_SIZE 10
+
/*********************************************************************
*
@@ -108,46 +120,7 @@
#define RTC_MINOR 135
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -9,6 +9,7 @@
#include <linux/types.h>
#include <linux/ioctl.h>
+#include <linux/types.h> /* for __u32 in user space */
#include <linux/irqnr.h>
/* ioctl()'s for the random number generator */
@@ -34,6 +35,30 @@
/* Clear the entropy pool and associated counters. (Superuser only.) */
#define RNDCLEARPOOL _IO( 'R', 0x06 )
+#ifdef CONFIG_FIPS_RNG
+
+/* Size of seed value - equal to AES blocksize */
+#define AES_BLOCK_SIZE_BYTES 16
+#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
+/* Size of AES key */
+#define KEY_SIZE_BYTES 16
+
+/* ioctl() structure used by FIPS 140-2 Tests */
+struct rand_fips_test {
+ unsigned char key[KEY_SIZE_BYTES]; /* Input */
+ unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
+ unsigned char seed[SEED_SIZE_BYTES]; /* Input */
+ unsigned char result[SEED_SIZE_BYTES]; /* Output */
+};
+
+/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
+#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
+
+/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
+#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
+
+#endif /* #ifdef CONFIG_FIPS_RNG */
+
struct rand_pool_info {
int entropy_count;
int buf_size;
@@ -54,6 +79,10 @@ extern void add_input_randomness(unsigne
@@ -54,6 +54,10 @@ extern void add_input_randomness(unsigne
unsigned int value);
extern void add_interrupt_randomness(int irq);
@@ -158,13 +131,3 @@
extern void get_random_bytes(void *buf, int nbytes);
void generate_random_uuid(unsigned char uuid_out[16]);
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -427,6 +427,7 @@ struct task_struct *find_task_by_vpid(pi
{
return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns);
}
+EXPORT_SYMBOL(find_task_by_vpid);
struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
{

View File

@@ -1,170 +0,0 @@
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -130,6 +130,9 @@
* void add_interrupt_randomness(int irq);
* void add_disk_randomness(struct gendisk *disk);
*
+ * void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
+ * int random_input_wait(void);
+ *
* add_input_randomness() uses the input layer interrupt timing, as well as
* the event type information from the hardware.
*
@@ -147,6 +150,13 @@
* seek times do not make for good sources of entropy, as their seek
* times are usually fairly consistent.
*
+ * random_input_words() just provides a raw block of entropy to the input
+ * pool, such as from a hardware entropy generator.
+ *
+ * random_input_wait() suspends the caller until such time as the
+ * entropy pool falls below the write threshold, and returns a count of how
+ * much entropy (in bits) is needed to sustain the pool.
+ *
* All of these routines try to estimate how many bits of randomness a
* particular randomness source. They do this by keeping track of the
* first and second order deltas of the event timings.
@@ -722,6 +732,61 @@ void add_disk_randomness(struct gendisk
}
#endif
+/*
+ * random_input_words - add bulk entropy to pool
+ *
+ * @buf: buffer to add
+ * @wordcount: number of __u32 words to add
+ * @ent_count: total amount of entropy (in bits) to credit
+ *
+ * this provides bulk input of entropy to the input pool
+ *
+ */
+void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
+{
+ mix_pool_bytes(&input_pool, buf, wordcount*4);
+
+ credit_entropy_bits(&input_pool, ent_count);
+
+ DEBUG_ENT("crediting %d bits => %d\n",
+ ent_count, input_pool.entropy_count);
+ /*
+ * Wake up waiting processes if we have enough
+ * entropy.
+ */
+ if (input_pool.entropy_count >= random_read_wakeup_thresh)
+ wake_up_interruptible(&random_read_wait);
+}
+EXPORT_SYMBOL(random_input_words);
+
+/*
+ * random_input_wait - wait until random needs entropy
+ *
+ * this function sleeps until the /dev/random subsystem actually
+ * needs more entropy, and then return the amount of entropy
+ * that it would be nice to have added to the system.
+ */
+int random_input_wait(void)
+{
+ int count;
+
+ wait_event_interruptible(random_write_wait,
+ input_pool.entropy_count < random_write_wakeup_thresh);
+
+ count = random_write_wakeup_thresh - input_pool.entropy_count;
+
+ /* likely we got woken up due to a signal */
+ if (count <= 0) count = random_read_wakeup_thresh;
+
+ DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
+ count,
+ input_pool.entropy_count, random_write_wakeup_thresh);
+
+ return count;
+}
+EXPORT_SYMBOL(random_input_wait);
+
+
/*********************************************************************
*
* Entropy extraction routines
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -142,6 +142,7 @@ SYSCALL_DEFINE1(dup, unsigned int, filde
}
return ret;
}
+EXPORT_SYMBOL(sys_dup);
#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -18,6 +18,7 @@
#define APOLLO_MOUSE_MINOR 7
#define PC110PAD_MINOR 9
/*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
+#define CRYPTODEV_MINOR 70 /* /dev/crypto */
#define WATCHDOG_MINOR 130 /* Watchdog timer */
#define TEMP_MINOR 131 /* Temperature Sensor */
#define RTC_MINOR 135
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -9,6 +9,7 @@
#include <linux/types.h>
#include <linux/ioctl.h>
+#include <linux/types.h> /* for __u32 in user space */
#include <linux/irqnr.h>
/* ioctl()'s for the random number generator */
@@ -34,6 +35,30 @@
/* Clear the entropy pool and associated counters. (Superuser only.) */
#define RNDCLEARPOOL _IO( 'R', 0x06 )
+#ifdef CONFIG_FIPS_RNG
+
+/* Size of seed value - equal to AES blocksize */
+#define AES_BLOCK_SIZE_BYTES 16
+#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
+/* Size of AES key */
+#define KEY_SIZE_BYTES 16
+
+/* ioctl() structure used by FIPS 140-2 Tests */
+struct rand_fips_test {
+ unsigned char key[KEY_SIZE_BYTES]; /* Input */
+ unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
+ unsigned char seed[SEED_SIZE_BYTES]; /* Input */
+ unsigned char result[SEED_SIZE_BYTES]; /* Output */
+};
+
+/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
+#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
+
+/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
+#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
+
+#endif /* #ifdef CONFIG_FIPS_RNG */
+
struct rand_pool_info {
int entropy_count;
int buf_size;
@@ -54,6 +79,10 @@ extern void add_input_randomness(unsigne
unsigned int value);
extern void add_interrupt_randomness(int irq);
+extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
+extern int random_input_wait(void);
+#define HAS_RANDOM_INPUT_WAIT 1
+
extern void get_random_bytes(void *buf, int nbytes);
void generate_random_uuid(unsigned char uuid_out[16]);
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -427,6 +427,7 @@ struct task_struct *find_task_by_vpid(pi
{
return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns);
}
+EXPORT_SYMBOL(find_task_by_vpid);
struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
{

View File

@@ -0,0 +1,133 @@
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -427,6 +427,7 @@ struct task_struct *find_task_by_vpid(pi
{
return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns);
}
+EXPORT_SYMBOL(find_task_by_vpid);
struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
{
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -130,6 +130,9 @@
* void add_interrupt_randomness(int irq);
* void add_disk_randomness(struct gendisk *disk);
*
+ * void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
+ * int random_input_wait(void);
+ *
* add_input_randomness() uses the input layer interrupt timing, as well as
* the event type information from the hardware.
*
@@ -147,6 +150,13 @@
* seek times do not make for good sources of entropy, as their seek
* times are usually fairly consistent.
*
+ * random_input_words() just provides a raw block of entropy to the input
+ * pool, such as from a hardware entropy generator.
+ *
+ * random_input_wait() suspends the caller until such time as the
+ * entropy pool falls below the write threshold, and returns a count of how
+ * much entropy (in bits) is needed to sustain the pool.
+ *
* All of these routines try to estimate how many bits of randomness a
* particular randomness source. They do this by keeping track of the
* first and second order deltas of the event timings.
@@ -722,6 +732,63 @@ void add_disk_randomness(struct gendisk
}
#endif
+/*
+ * random_input_words - add bulk entropy to pool
+ *
+ * @buf: buffer to add
+ * @wordcount: number of __u32 words to add
+ * @ent_count: total amount of entropy (in bits) to credit
+ *
+ * this provides bulk input of entropy to the input pool
+ *
+ */
+void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
+{
+ mix_pool_bytes(&input_pool, buf, wordcount*4);
+
+ credit_entropy_bits(&input_pool, ent_count);
+
+ DEBUG_ENT("crediting %d bits => %d\n",
+ ent_count, input_pool.entropy_count);
+ /*
+ * Wake up waiting processes if we have enough
+ * entropy.
+ */
+ if (input_pool.entropy_count >= random_read_wakeup_thresh)
+ wake_up_interruptible(&random_read_wait);
+}
+EXPORT_SYMBOL(random_input_words);
+
+/*
+ * random_input_wait - wait until random needs entropy
+ *
+ * this function sleeps until the /dev/random subsystem actually
+ * needs more entropy, and then return the amount of entropy
+ * that it would be nice to have added to the system.
+ */
+int random_input_wait(void)
+{
+ int count;
+
+ wait_event_interruptible(random_write_wait,
+ input_pool.entropy_count < random_write_wakeup_thresh);
+
+ count = random_write_wakeup_thresh - input_pool.entropy_count;
+
+ /* likely we got woken up due to a signal */
+ if (count <= 0) count = random_read_wakeup_thresh;
+
+ DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
+ count,
+ input_pool.entropy_count, random_write_wakeup_thresh);
+
+ return count;
+}
+EXPORT_SYMBOL(random_input_wait);
+
+
+#define EXTRACT_SIZE 10
+
/*********************************************************************
*
* Entropy extraction routines
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -142,6 +142,7 @@ SYSCALL_DEFINE1(dup, unsigned int, filde
}
return ret;
}
+EXPORT_SYMBOL(sys_dup);
#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -18,6 +18,7 @@
#define APOLLO_MOUSE_MINOR 7
#define PC110PAD_MINOR 9
/*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
+#define CRYPTODEV_MINOR 70 /* /dev/crypto */
#define WATCHDOG_MINOR 130 /* Watchdog timer */
#define TEMP_MINOR 131 /* Temperature Sensor */
#define RTC_MINOR 135
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -54,6 +54,10 @@ extern void add_input_randomness(unsigne
unsigned int value);
extern void add_interrupt_randomness(int irq);
+extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
+extern int random_input_wait(void);
+#define HAS_RANDOM_INPUT_WAIT 1
+
extern void get_random_bytes(void *buf, int nbytes);
void generate_random_uuid(unsigned char uuid_out[16]);