]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/meta-ti-glsdk.git/blob - recipes-kernel/linux/linux-omap3-2.6.37-psp04.02.00.07/omap3/0001-linux-omap3-Add-OCF-support-to-2.6.37-kernel.patch
8ad7bf444bb3dac76f6568ee30d1ca312bf5cd84
[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-omap3-2.6.37-psp04.02.00.07 / omap3 / 0001-linux-omap3-Add-OCF-support-to-2.6.37-kernel.patch
1 From d27b15fcf6b97acf8657ef6635e7e3ec95961f14 Mon Sep 17 00:00:00 2001
2 From: Greg Turner <gregturner@ti.com>
3 Date: Thu, 16 Jun 2011 09:35:15 -0500
4 Subject: [PATCH] linux-omap3: Add OCF support to 2.6.37 kernel
6 * Patch kernel with OCF (community source)
7 * Mod to defconfig to build OCF statically in to kernel
8 * cryptodev.ko is built as a loadable module
9 * cryptodev.h header file moved to include/crypto
11 Signed-off-by: Greg Turner <gregturner@ti.com>
12 ---
13  crypto/Kconfig             |    3 +
14  crypto/Makefile            |    2 +
15  crypto/ocf/ChangeLog       |  205 +++++
16  crypto/ocf/Config.in       |   36 +
17  crypto/ocf/Kconfig         |  119 +++
18  crypto/ocf/Makefile        |  124 +++
19  crypto/ocf/criov.c         |  215 ++++++
20  crypto/ocf/crypto.c        | 1784 ++++++++++++++++++++++++++++++++++++++++++++
21  crypto/ocf/cryptodev.c     | 1063 ++++++++++++++++++++++++++
22  crypto/ocf/cryptosoft.c    | 1210 ++++++++++++++++++++++++++++++
23  crypto/ocf/ocf-bench.c     |  436 +++++++++++
24  crypto/ocf/ocf-compat.h    |  294 ++++++++
25  crypto/ocf/random.c        |  322 ++++++++
26  crypto/ocf/rndtest.c       |  300 ++++++++
27  crypto/ocf/rndtest.h       |   54 ++
28  crypto/ocf/uio.h           |   54 ++
29  drivers/char/random.c      |   65 ++
30  fs/fcntl.c                 |    1 +
31  include/crypto/cryptodev.h |  479 ++++++++++++
32  include/linux/miscdevice.h |    1 +
33  include/linux/random.h     |   29 +
34  kernel/pid.c               |    1 +
35  22 files changed, 6797 insertions(+), 0 deletions(-)
36  create mode 100644 crypto/ocf/ChangeLog
37  create mode 100644 crypto/ocf/Config.in
38  create mode 100644 crypto/ocf/Kconfig
39  create mode 100644 crypto/ocf/Makefile
40  create mode 100644 crypto/ocf/criov.c
41  create mode 100644 crypto/ocf/crypto.c
42  create mode 100644 crypto/ocf/cryptodev.c
43  create mode 100644 crypto/ocf/cryptosoft.c
44  create mode 100644 crypto/ocf/ocf-bench.c
45  create mode 100644 crypto/ocf/ocf-compat.h
46  create mode 100644 crypto/ocf/random.c
47  create mode 100644 crypto/ocf/rndtest.c
48  create mode 100644 crypto/ocf/rndtest.h
49  create mode 100644 crypto/ocf/uio.h
50  create mode 100644 include/crypto/cryptodev.h
52 diff --git a/crypto/Kconfig b/crypto/Kconfig
53 index e4bac29..3154b22 100644
54 --- a/crypto/Kconfig
55 +++ b/crypto/Kconfig
56 @@ -844,3 +844,6 @@ config CRYPTO_ANSI_CPRNG
57  source "drivers/crypto/Kconfig"
58  
59  endif  # if CRYPTO
60 +
61 +source "crypto/ocf/Kconfig"
62 +
63 diff --git a/crypto/Makefile b/crypto/Makefile
64 index 423b7de..14ec6e9 100644
65 --- a/crypto/Makefile
66 +++ b/crypto/Makefile
67 @@ -86,6 +86,8 @@ obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o
68  obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
69  obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
70  
71 +obj-$(CONFIG_OCF_OCF) += ocf/
72 +
73  #
74  # generic algorithms and the async_tx api
75  #
76 diff --git a/crypto/ocf/ChangeLog b/crypto/ocf/ChangeLog
77 new file mode 100644
78 index 0000000..8101340
79 --- /dev/null
80 +++ b/crypto/ocf/ChangeLog
81 @@ -0,0 +1,205 @@
82 +2009-08-20 19:05  toby
83 +
84 +       * cryptocteon/Makefile, ep80579/Makefile:
85 +       Add some makefile
86 +       changes to let a linux-2.4 build from head work when doing 'make
87 +       dep'.
88 +
89 +2009-08-12 21:42  davidm
90 +
91 +       * cryptodev.c:
92 +       
93 +       if crypto_dispatch fails,  make sure we bail immediately rather
94 +       than go on to do other error checking that we should only do if
95 +       crypto_dispatch worked.
96 +
97 +2009-08-12 21:30  davidm
98 +
99 +       * crypto.c:
100 +       
101 +       To avoid a race while we have the Q's unlcked we must stage the
102 +       blocking of the driver, so,  we assume the driver to be blocked, 
103 +       but if any unblocks come in while we are unlocked,  we do not block
104 +       the driver.
105 +       
106 +       At worst this means we will try again and get another block.
107 +       
108 +       Without this change we can lose an unblock request and give up on
109 +       the driver.
111 +2009-08-12 21:04  davidm
113 +       * crypto.c:
114 +       
115 +       kill_proc needs to be defined for kernels at or after 2.6.27
117 +2009-08-12 21:03  davidm
119 +       * ep80579/environment.mk:
120 +       
121 +       Allow OCF to be with the kernel,  or within the uClinux-dist
122 +       modules dir.
124 +2009-08-12 20:52  davidm
126 +       * ocf-compat.h:
127 +       
128 +       if IS_ERR_VALUE is not defined,  try and get it,  if it doesn't
129 +       exist, make our own.
131 +2009-05-27 01:52  davidm
133 +       * cryptodev.c:
134 +       
135 +       Order a crd combination of cipher/hmac just as ipsec would.  That
136 +       way it's easier to test results against cryptosoft and the HW
137 +       drivers that automatically fix this.
138 +       
139 +       cryptosoft processes algs in crd order,  thus they get different
140 +       results to when compared to cryptosoft.
141 +       
142 +       encrypt = cipher then hmac decrypt = hmac then cipher
144 +2009-05-27 01:48  davidm
146 +       * ocf-compat.h:
147 +       
148 +       Make sure we have an late_initcall macro even on old systems.
150 +2009-05-27 01:47  davidm
152 +       * cryptosoft.c:
153 +       
154 +       make sure that cryptosoft it started after the kernel crypto, 
155 +       otherwise it will not detect the kernels algs correctly.
157 +2009-05-27 01:41  davidm
159 +       * cryptocteon/: cavium_crypto.c, cryptocteon.c:
160 +       
161 +       aes/des/3des + md5/sha1 working with ipsec.
163 +2009-05-20 19:11  davidm
165 +       * cryptocteon/: README.txt, cavium_crypto.c, cryptocteon.c:
166 +       
167 +       Complete rework of the driver to setup a framework that can handle
168 +       all the combinations we need properly.
169 +       
170 +       Currently only DES is working.  Need to knock out a DES-MD5 version
171 +       so we can bench ipsec, then cleanup the AES/SHA bits.
173 +2009-05-14 20:53  asallawa
175 +       * ixp4xx/ixp4xx.c:
176 +       
177 +       Remove call to flush_scheduled_work(). Doesn't appear to be
178 +       necessary and can cause 'scheduling while atomic' kernel errors.
180 +2009-05-14 01:17  asallawa
182 +       * crypto.c:
183 +       
184 +       In particular situations, the crypto kernel thread can run forever
185 +       without ever calling wait_event_interruptible() which meant that it
186 +       could starve the rest of the system of CPU time.  To fix this, set
187 +       a maximum number of crypto operations to do consecutively before
188 +       calling schedule(). Default value is 1000, which should be less
189 +       than a second on most of our platforms.
191 +2009-05-08 20:10  davidm
193 +       * crypto.c:
194 +       
195 +       Currently we are queuing requests that fail for callback.  The
196 +       callback will never happen because the request failed.  This can
197 +       cause "busy loops" in the crypto support threads.
198 +       
199 +       Make sure we track the error status when processing a request to
200 +       the driver and only return 0 if everything worked.
201 +       
202 +       The original code had this right,  just bad locking,  the locking
203 +       fixes broke the error reporting.
205 +2009-03-31 20:41  davidm
207 +       * crypto.c:
208 +       
209 +       We cannot use sys_kill (not experted),  so switch to using send_sig
210 +       and the appropriate task finding functions.
212 +2009-03-27 03:50  gerg
214 +       * crypto.c:
215 +       
216 +       From linux-2.6.29 onwards there is no kill_proc() routine.  On
217 +       these newer systems call direct to the sys_kill() system call.
219 +2009-03-14 07:00  davidm
221 +       * ep80579/Makefile:
222 +       
223 +       merge makefile fix from head so that make clean works properly.
225 +2009-03-10 22:57  davidm
227 +       * hifn/hifn7751.c:
228 +       
229 +       Fix up cache line size for hifns,  not all get it right.  Patch
230 +       suggested and tested by Donald Lai <dlai@hifn.com>.
232 +2009-03-10 21:36  davidm
234 +       * ep80579/Makefile:
235 +       
236 +       Make sure we do not break non-tolapai builds (when running clean
237 +       etc)
239 +2009-02-07 00:32  davidm
241 +       * Kconfig, Makefile, cryptocteon/Makefile, cryptocteon/README.txt,
242 +       cryptocteon/cavium_crypto.c, cryptocteon/cryptocteon.c:
243 +       
244 +       First pass slightly working (3des/aes) crypto driver for the cavium
245 +       5010.
246 +       
247 +       Still a fair bit needed here (hmac+cipher and hash processing). 
248 +       Need to revisit the faster cavium example ipsec code.
250 +2009-01-20 01:06  gerg
252 +       * cryptosoft.c:
253 +       
254 +       Include linux/scatterlist.h instead of asm/scatterlist.h. Otherwise
255 +       we don't get the generic sg macros (only the asm specific
256 +       difinitions).
258 +2009-01-16 20:05  davidm
260 +       * cryptosoft.c:
261 +       
262 +       clean up some debug output (sign extension fo chars)
264 +2008-11-20 22:50  davidm
266 +       * ocf-compat.h:
267 +       
268 +       We need to include mm.h to get page_address on some kernels. 
269 +       reported by Paul Wouters <paul@xelerance.com>
271 +2008-11-14 06:14  davidm
273 +       * patches/linux-2.6.26-ocf.patch:
274 +       
275 +       make sure we patch into the kernel properly.  Paul Wouters
276 +       <paul@xelerance.com>
278 +2008-09-20 02:20  davidm
280 +       * crypto.c, cryptodev.h:
281 +       
282 +       Fix up session migration so that a driver can be removed while
283 +       ipsec is up and running and the tunnel will auto-migrate to a
284 +       backup driver (ie., cryptosoft).
285 +       
286 +       Brad Vrabete <brad.vrabete@intel.com>
287 diff --git a/crypto/ocf/Config.in b/crypto/ocf/Config.in
288 new file mode 100644
289 index 0000000..d722cba
290 --- /dev/null
291 +++ b/crypto/ocf/Config.in
292 @@ -0,0 +1,36 @@
293 +#############################################################################
295 +mainmenu_option next_comment
296 +comment 'OCF Configuration'
297 +tristate 'OCF (Open Cryptograhic Framework)' CONFIG_OCF_OCF
298 +dep_mbool '  enable fips RNG checks (fips check on RNG data before use)' \
299 +                               CONFIG_OCF_FIPS $CONFIG_OCF_OCF
300 +dep_mbool '  enable harvesting entropy for /dev/random' \
301 +                               CONFIG_OCF_RANDOMHARVEST $CONFIG_OCF_OCF
302 +dep_tristate '  cryptodev (user space support)' \
303 +                               CONFIG_OCF_CRYPTODEV $CONFIG_OCF_OCF
304 +dep_tristate '  cryptosoft (software crypto engine)' \
305 +                               CONFIG_OCF_CRYPTOSOFT $CONFIG_OCF_OCF
306 +dep_tristate '  safenet (HW crypto engine)' \
307 +                               CONFIG_OCF_SAFE $CONFIG_OCF_OCF
308 +dep_tristate '  IXP4xx (HW crypto engine)' \
309 +                               CONFIG_OCF_IXP4XX $CONFIG_OCF_OCF
310 +dep_mbool    '  Enable IXP4xx HW to perform SHA1 and MD5 hashing (very slow)' \
311 +                               CONFIG_OCF_IXP4XX_SHA1_MD5 $CONFIG_OCF_IXP4XX
312 +dep_tristate '  hifn (HW crypto engine)' \
313 +                               CONFIG_OCF_HIFN $CONFIG_OCF_OCF
314 +dep_tristate '  talitos (HW crypto engine)' \
315 +                               CONFIG_OCF_TALITOS $CONFIG_OCF_OCF
316 +dep_tristate '  pasemi (HW crypto engine)' \
317 +                               CONFIG_OCF_PASEMI $CONFIG_OCF_OCF
318 +dep_tristate '  ep80579 (HW crypto engine)' \
319 +                               CONFIG_OCF_EP80579 $CONFIG_OCF_OCF
320 +dep_tristate '  Micronas c7108 (HW crypto engine)' \
321 +                               CONFIG_OCF_C7108 $CONFIG_OCF_OCF
322 +dep_tristate '  ocfnull (does no crypto)' \
323 +                               CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF
324 +dep_tristate '  ocf-bench (HW crypto in-kernel benchmark)' \
325 +                               CONFIG_OCF_BENCH $CONFIG_OCF_OCF
326 +endmenu
328 +#############################################################################
329 diff --git a/crypto/ocf/Kconfig b/crypto/ocf/Kconfig
330 new file mode 100644
331 index 0000000..b9c24ff
332 --- /dev/null
333 +++ b/crypto/ocf/Kconfig
334 @@ -0,0 +1,119 @@
335 +menu "OCF Configuration"
337 +config OCF_OCF
338 +       tristate "OCF (Open Cryptograhic Framework)"
339 +       help
340 +         A linux port of the OpenBSD/FreeBSD crypto framework.
342 +config OCF_RANDOMHARVEST
343 +       bool "crypto random --- harvest entropy for /dev/random"
344 +       depends on OCF_OCF
345 +       help
346 +         Includes code to harvest random numbers from devices that support it.
348 +config OCF_FIPS
349 +       bool "enable fips RNG checks"
350 +       depends on OCF_OCF && OCF_RANDOMHARVEST
351 +       help
352 +         Run all RNG provided data through a fips check before
353 +         adding it /dev/random's entropy pool.
355 +config OCF_CRYPTODEV
356 +       tristate "cryptodev (user space support)"
357 +       depends on OCF_OCF
358 +       help
359 +         The user space API to access crypto hardware.
361 +config OCF_CRYPTOSOFT
362 +       tristate "cryptosoft (software crypto engine)"
363 +       depends on OCF_OCF
364 +       help
365 +         A software driver for the OCF framework that uses
366 +         the kernel CryptoAPI.
368 +config OCF_SAFE
369 +       tristate "safenet (HW crypto engine)"
370 +       depends on OCF_OCF
371 +       help
372 +         A driver for a number of the safenet Excel crypto accelerators.
373 +         Currently tested and working on the 1141 and 1741.
375 +config OCF_IXP4XX
376 +       tristate "IXP4xx (HW crypto engine)"
377 +       depends on OCF_OCF
378 +       help
379 +         XScale IXP4xx crypto accelerator driver.  Requires the
380 +         Intel Access library.
382 +config OCF_IXP4XX_SHA1_MD5
383 +       bool "IXP4xx SHA1 and MD5 Hashing"
384 +       depends on OCF_IXP4XX
385 +       help
386 +         Allows the IXP4xx crypto accelerator to perform SHA1 and MD5 hashing.
387 +         Note: this is MUCH slower than using cryptosoft (software crypto engine).
389 +config OCF_HIFN
390 +       tristate "hifn (HW crypto engine)"
391 +       depends on OCF_OCF
392 +       help
393 +         OCF driver for various HIFN based crypto accelerators.
394 +         (7951, 7955, 7956, 7751, 7811)
396 +config OCF_HIFNHIPP
397 +       tristate "Hifn HIPP (HW packet crypto engine)"
398 +       depends on OCF_OCF
399 +       help
400 +         OCF driver for various HIFN (HIPP) based crypto accelerators
401 +         (7855)
403 +config OCF_TALITOS
404 +       tristate "talitos (HW crypto engine)"
405 +       depends on OCF_OCF
406 +       help
407 +         OCF driver for Freescale's security engine (SEC/talitos).
409 +config OCF_PASEMI
410 +       tristate "pasemi (HW crypto engine)"
411 +       depends on OCF_OCF && PPC_PASEMI
412 +       help
413 +         OCF driver for the PA Semi PWRficient DMA Engine
415 +config OCF_EP80579
416 +       tristate "ep80579 (HW crypto engine)"
417 +       depends on OCF_OCF
418 +       help
419 +         OCF driver for the Intel EP80579 Integrated Processor Product Line.
421 +config OCF_CRYPTOCTEON
422 +       tristate "cryptocteon (HW crypto engine)"
423 +       depends on OCF_OCF
424 +       help
425 +         OCF driver for the Cavium OCTEON Processors.
427 +config OCF_KIRKWOOD
428 +       tristate "kirkwood (HW crypto engine)"
429 +       depends on OCF_OCF
430 +       help
431 +         OCF driver for the Marvell Kirkwood (88F6xxx) Processors.
433 +config OCF_C7108
434 +       tristate "Micronas 7108 (HW crypto engine)"
435 +       depends on OCF_OCF
436 +       help
437 +         OCF driver for the Microna 7108 Cipher processors.
439 +config OCF_OCFNULL
440 +       tristate "ocfnull (fake crypto engine)"
441 +       depends on OCF_OCF
442 +       help
443 +         OCF driver for measuring ipsec overheads (does no crypto)
445 +config OCF_BENCH
446 +       tristate "ocf-bench (HW crypto in-kernel benchmark)"
447 +       depends on OCF_OCF
448 +       help
449 +         A very simple encryption test for the in-kernel interface
450 +         of OCF.  Also includes code to benchmark the IXP Access library
451 +         for comparison.
453 +endmenu
454 diff --git a/crypto/ocf/Makefile b/crypto/ocf/Makefile
455 new file mode 100644
456 index 0000000..fa951f4
457 --- /dev/null
458 +++ b/crypto/ocf/Makefile
459 @@ -0,0 +1,124 @@
460 +# for SGlinux builds
461 +-include $(ROOTDIR)/modules/.config
463 +OCF_OBJS = crypto.o criov.o
465 +ifdef CONFIG_OCF_RANDOMHARVEST
466 +       OCF_OBJS += random.o
467 +endif
469 +ifdef CONFIG_OCF_FIPS
470 +       OCF_OBJS += rndtest.o
471 +endif
473 +# Add in autoconf.h to get #defines for CONFIG_xxx
474 +AUTOCONF_H=$(ROOTDIR)/modules/autoconf.h
475 +ifeq ($(AUTOCONF_H), $(wildcard $(AUTOCONF_H)))
476 +       EXTRA_CFLAGS += -include $(AUTOCONF_H)
477 +       export EXTRA_CFLAGS
478 +endif
480 +ifndef obj
481 +       obj ?= .
482 +       _obj = subdir
483 +       mod-subdirs := safe hifn ixp4xx talitos ocfnull
484 +       export-objs += crypto.o criov.o random.o
485 +       list-multi += ocf.o
486 +       _slash :=
487 +else
488 +       _obj = obj
489 +       _slash := /
490 +endif
492 +EXTRA_CFLAGS += -I$(obj)/.
494 +obj-$(CONFIG_OCF_OCF)         += ocf.o
495 +obj-$(CONFIG_OCF_CRYPTODEV)   += cryptodev.o
496 +obj-$(CONFIG_OCF_CRYPTOSOFT)  += cryptosoft.o
497 +obj-$(CONFIG_OCF_BENCH)       += ocf-bench.o
499 +$(_obj)-$(CONFIG_OCF_SAFE)    += safe$(_slash)
500 +$(_obj)-$(CONFIG_OCF_HIFN)    += hifn$(_slash)
501 +$(_obj)-$(CONFIG_OCF_IXP4XX)  += ixp4xx$(_slash)
502 +$(_obj)-$(CONFIG_OCF_TALITOS) += talitos$(_slash)
503 +$(_obj)-$(CONFIG_OCF_PASEMI)  += pasemi$(_slash)
504 +$(_obj)-$(CONFIG_OCF_EP80579) += ep80579$(_slash)
505 +$(_obj)-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon$(_slash)
506 +$(_obj)-$(CONFIG_OCF_KIRKWOOD) += kirkwood$(_slash)
507 +$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)
508 +$(_obj)-$(CONFIG_OCF_C7108) += c7108$(_slash)
510 +ocf-objs := $(OCF_OBJS)
512 +$(list-multi) dummy1: $(ocf-objs)
513 +       $(LD) -r -o $@ $(ocf-objs)
515 +.PHONY:
516 +clean:
517 +       rm -f *.o *.ko .*.o.flags .*.ko.cmd .*.o.cmd .*.mod.o.cmd *.mod.c
518 +       rm -f */*.o */*.ko */.*.o.cmd */.*.ko.cmd */.*.mod.o.cmd */*.mod.c */.*.o.flags
520 +ifdef TOPDIR
521 +-include $(TOPDIR)/Rules.make
522 +endif
524 +#
525 +# release gen targets
526 +#
528 +.PHONY: patch
529 +patch:
530 +       REL=`date +%Y%m%d`; \
531 +               patch=ocf-linux-$$REL.patch; \
532 +               patch24=ocf-linux-24-$$REL.patch; \
533 +               patch26=ocf-linux-26-$$REL.patch; \
534 +               ( \
535 +                       find . -name Makefile; \
536 +                       find . -name Config.in; \
537 +                       find . -name Kconfig; \
538 +                       find . -name README; \
539 +                       find . -name '*.[ch]' | grep -v '.mod.c'; \
540 +               ) | while read t; do \
541 +                       diff -Nau /dev/null $$t | sed 's?^+++ \./?+++ linux/crypto/ocf/?'; \
542 +               done > $$patch; \
543 +               cat patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \
544 +               cat patches/linux-2.6.33-ocf.patch $$patch > $$patch26
546 +.PHONY: tarball
547 +tarball:
548 +       REL=`date +%Y%m%d`; RELDIR=/tmp/ocf-linux-$$REL; \
549 +               CURDIR=`pwd`; \
550 +               rm -rf /tmp/ocf-linux-$$REL*; \
551 +               mkdir -p $$RELDIR/tools; \
552 +               cp README* $$RELDIR; \
553 +               cp patches/openss*.patch $$RELDIR; \
554 +               cp patches/crypto-tools.patch $$RELDIR; \
555 +               cp tools/[!C]* $$RELDIR/tools; \
556 +               cd ..; \
557 +               tar cvf $$RELDIR/ocf-linux.tar \
558 +                                       --exclude=CVS \
559 +                                       --exclude=.* \
560 +                                       --exclude=*.o \
561 +                                       --exclude=*.ko \
562 +                                       --exclude=*.mod.* \
563 +                                       --exclude=README* \
564 +                                       --exclude=ocf-*.patch \
565 +                                       --exclude=ocf/patches/openss*.patch \
566 +                                       --exclude=ocf/patches/crypto-tools.patch \
567 +                                       --exclude=ocf/tools \
568 +                                       ocf; \
569 +               gzip -9 $$RELDIR/ocf-linux.tar; \
570 +               cd /tmp; \
571 +               tar cvf ocf-linux-$$REL.tar ocf-linux-$$REL; \
572 +               gzip -9 ocf-linux-$$REL.tar; \
573 +               cd $$CURDIR/../../user; \
574 +               rm -rf /tmp/crypto-tools-$$REL*; \
575 +               tar cvf /tmp/crypto-tools-$$REL.tar \
576 +                                       --exclude=CVS \
577 +                                       --exclude=.* \
578 +                                       --exclude=*.o \
579 +                                       --exclude=cryptotest \
580 +                                       --exclude=cryptokeytest \
581 +                                       crypto-tools; \
582 +               gzip -9 /tmp/crypto-tools-$$REL.tar
584 diff --git a/crypto/ocf/criov.c b/crypto/ocf/criov.c
585 new file mode 100644
586 index 0000000..5fe9040
587 --- /dev/null
588 +++ b/crypto/ocf/criov.c
589 @@ -0,0 +1,215 @@
590 +/*      $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason Exp $        */
592 +/*
593 + * Linux port done by David McCullough <david_mccullough@mcafee.com>
594 + * Copyright (C) 2006-2010 David McCullough
595 + * Copyright (C) 2004-2005 Intel Corporation.
596 + * The license and original author are listed below.
597 + *
598 + * Copyright (c) 1999 Theo de Raadt
599 + *
600 + * Redistribution and use in source and binary forms, with or without
601 + * modification, are permitted provided that the following conditions
602 + * are met:
603 + *
604 + * 1. Redistributions of source code must retain the above copyright
605 + *   notice, this list of conditions and the following disclaimer.
606 + * 2. Redistributions in binary form must reproduce the above copyright
607 + *   notice, this list of conditions and the following disclaimer in the
608 + *   documentation and/or other materials provided with the distribution.
609 + * 3. The name of the author may not be used to endorse or promote products
610 + *   derived from this software without specific prior written permission.
611 + *
612 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
613 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
614 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
615 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
616 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
617 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
618 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
619 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
620 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
621 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
622 + *
623 +__FBSDID("$FreeBSD: src/sys/opencrypto/criov.c,v 1.5 2006/06/04 22:15:13 pjd Exp $");
624 + */
626 +#ifndef AUTOCONF_INCLUDED
627 +#include <linux/config.h>
628 +#endif
629 +#include <linux/module.h>
630 +#include <linux/init.h>
631 +#include <linux/slab.h>
632 +#include <linux/uio.h>
633 +#include <linux/skbuff.h>
634 +#include <linux/kernel.h>
635 +#include <linux/mm.h>
636 +#include <asm/io.h>
638 +#include <uio.h>
639 +#include <crypto/cryptodev.h>
641 +/*
642 + * This macro is only for avoiding code duplication, as we need to skip
643 + * given number of bytes in the same way in three functions below.
644 + */
645 +#define        CUIO_SKIP()     do {                                            \
646 +       KASSERT(off >= 0, ("%s: off %d < 0", __func__, off));           \
647 +       KASSERT(len >= 0, ("%s: len %d < 0", __func__, len));           \
648 +       while (off > 0) {                                               \
649 +               KASSERT(iol >= 0, ("%s: empty in skip", __func__));     \
650 +               if (off < iov->iov_len)                                 \
651 +                       break;                                          \
652 +               off -= iov->iov_len;                                    \
653 +               iol--;                                                  \
654 +               iov++;                                                  \
655 +       }                                                               \
656 +} while (0)
658 +void
659 +cuio_copydata(struct uio* uio, int off, int len, caddr_t cp)
660 +{
661 +       struct iovec *iov = uio->uio_iov;
662 +       int iol = uio->uio_iovcnt;
663 +       unsigned count;
665 +       CUIO_SKIP();
666 +       while (len > 0) {
667 +               KASSERT(iol >= 0, ("%s: empty", __func__));
668 +               count = min((int)(iov->iov_len - off), len);
669 +               memcpy(cp, ((caddr_t)iov->iov_base) + off, count);
670 +               len -= count;
671 +               cp += count;
672 +               off = 0;
673 +               iol--;
674 +               iov++;
675 +       }
676 +}
678 +void
679 +cuio_copyback(struct uio* uio, int off, int len, caddr_t cp)
680 +{
681 +       struct iovec *iov = uio->uio_iov;
682 +       int iol = uio->uio_iovcnt;
683 +       unsigned count;
685 +       CUIO_SKIP();
686 +       while (len > 0) {
687 +               KASSERT(iol >= 0, ("%s: empty", __func__));
688 +               count = min((int)(iov->iov_len - off), len);
689 +               memcpy(((caddr_t)iov->iov_base) + off, cp, count);
690 +               len -= count;
691 +               cp += count;
692 +               off = 0;
693 +               iol--;
694 +               iov++;
695 +       }
696 +}
698 +/*
699 + * Return a pointer to iov/offset of location in iovec list.
700 + */
701 +struct iovec *
702 +cuio_getptr(struct uio *uio, int loc, int *off)
703 +{
704 +       struct iovec *iov = uio->uio_iov;
705 +       int iol = uio->uio_iovcnt;
707 +       while (loc >= 0) {
708 +               /* Normal end of search */
709 +               if (loc < iov->iov_len) {
710 +                       *off = loc;
711 +                       return (iov);
712 +               }
714 +               loc -= iov->iov_len;
715 +               if (iol == 0) {
716 +                       if (loc == 0) {
717 +                               /* Point at the end of valid data */
718 +                               *off = iov->iov_len;
719 +                               return (iov);
720 +                       } else
721 +                               return (NULL);
722 +               } else {
723 +                       iov++, iol--;
724 +               }
725 +       }
727 +       return (NULL);
728 +}
730 +EXPORT_SYMBOL(cuio_copyback);
731 +EXPORT_SYMBOL(cuio_copydata);
732 +EXPORT_SYMBOL(cuio_getptr);
735 +static void
736 +skb_copy_bits_back(struct sk_buff *skb, int offset, caddr_t cp, int len)
737 +{
738 +       int i;
739 +       if (offset < skb_headlen(skb)) {
740 +               memcpy(skb->data + offset, cp, min_t(int, skb_headlen(skb), len));
741 +               len -= skb_headlen(skb);
742 +               cp += skb_headlen(skb);
743 +       }
744 +       offset -= skb_headlen(skb);
745 +       for (i = 0; len > 0 && i < skb_shinfo(skb)->nr_frags; i++) {
746 +               if (offset < skb_shinfo(skb)->frags[i].size) {
747 +                       memcpy(page_address(skb_shinfo(skb)->frags[i].page) +
748 +                                       skb_shinfo(skb)->frags[i].page_offset,
749 +                                       cp, min_t(int, skb_shinfo(skb)->frags[i].size, len));
750 +                       len -= skb_shinfo(skb)->frags[i].size;
751 +                       cp += skb_shinfo(skb)->frags[i].size;
752 +               }
753 +               offset -= skb_shinfo(skb)->frags[i].size;
754 +       }
755 +}
757 +void
758 +crypto_copyback(int flags, caddr_t buf, int off, int size, caddr_t in)
759 +{
761 +       if ((flags & CRYPTO_F_SKBUF) != 0)
762 +               skb_copy_bits_back((struct sk_buff *)buf, off, in, size);
763 +       else if ((flags & CRYPTO_F_IOV) != 0)
764 +               cuio_copyback((struct uio *)buf, off, size, in);
765 +       else
766 +               bcopy(in, buf + off, size);
767 +}
769 +void
770 +crypto_copydata(int flags, caddr_t buf, int off, int size, caddr_t out)
771 +{
773 +       if ((flags & CRYPTO_F_SKBUF) != 0)
774 +               skb_copy_bits((struct sk_buff *)buf, off, out, size);
775 +       else if ((flags & CRYPTO_F_IOV) != 0)
776 +               cuio_copydata((struct uio *)buf, off, size, out);
777 +       else
778 +               bcopy(buf + off, out, size);
779 +}
781 +int
782 +crypto_apply(int flags, caddr_t buf, int off, int len,
783 +    int (*f)(void *, void *, u_int), void *arg)
784 +{
785 +#if 0
786 +       int error;
788 +       if ((flags & CRYPTO_F_SKBUF) != 0)
789 +               error = XXXXXX((struct mbuf *)buf, off, len, f, arg);
790 +       else if ((flags & CRYPTO_F_IOV) != 0)
791 +               error = cuio_apply((struct uio *)buf, off, len, f, arg);
792 +       else
793 +               error = (*f)(arg, buf + off, len);
794 +       return (error);
795 +#else
796 +       KASSERT(0, ("crypto_apply not implemented!\n"));
797 +#endif
798 +       return 0;
799 +}
801 +EXPORT_SYMBOL(crypto_copyback);
802 +EXPORT_SYMBOL(crypto_copydata);
803 +EXPORT_SYMBOL(crypto_apply);
805 diff --git a/crypto/ocf/crypto.c b/crypto/ocf/crypto.c
806 new file mode 100644
807 index 0000000..9e60ac9
808 --- /dev/null
809 +++ b/crypto/ocf/crypto.c
810 @@ -0,0 +1,1784 @@
811 +/*-
812 + * Linux port done by David McCullough <david_mccullough@mcafee.com>
813 + * Copyright (C) 2006-2010 David McCullough
814 + * Copyright (C) 2004-2005 Intel Corporation.
815 + * The license and original author are listed below.
816 + *
817 + * Redistribution and use in source and binary forms, with or without
818 + * Copyright (c) 2002-2006 Sam Leffler.  All rights reserved.
819 + *
820 + * modification, are permitted provided that the following conditions
821 + * are met:
822 + * 1. Redistributions of source code must retain the above copyright
823 + *    notice, this list of conditions and the following disclaimer.
824 + * 2. Redistributions in binary form must reproduce the above copyright
825 + *    notice, this list of conditions and the following disclaimer in the
826 + *    documentation and/or other materials provided with the distribution.
827 + *
828 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
829 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
830 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
831 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
832 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
833 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
834 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
835 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
836 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
837 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
838 + */
840 +#if 0
841 +#include <sys/cdefs.h>
842 +__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.27 2007/03/21 03:42:51 sam Exp $");
843 +#endif
845 +/*
846 + * Cryptographic Subsystem.
847 + *
848 + * This code is derived from the Openbsd Cryptographic Framework (OCF)
849 + * that has the copyright shown below.  Very little of the original
850 + * code remains.
851 + */
852 +/*-
853 + * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
854 + *
855 + * This code was written by Angelos D. Keromytis in Athens, Greece, in
856 + * February 2000. Network Security Technologies Inc. (NSTI) kindly
857 + * supported the development of this code.
858 + *
859 + * Copyright (c) 2000, 2001 Angelos D. Keromytis
860 + *
861 + * Permission to use, copy, and modify this software with or without fee
862 + * is hereby granted, provided that this entire notice is included in
863 + * all source code copies of any software which is or includes a copy or
864 + * modification of this software.
865 + *
866 + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
867 + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
868 + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
869 + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
870 + * PURPOSE.
871 + *
872 +__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp Exp $");
873 + */
876 +#ifndef AUTOCONF_INCLUDED
877 +#include <linux/config.h>
878 +#endif
879 +#include <linux/module.h>
880 +#include <linux/init.h>
881 +#include <linux/list.h>
882 +#include <linux/slab.h>
883 +#include <linux/wait.h>
884 +#include <linux/sched.h>
885 +#include <linux/spinlock.h>
886 +#include <linux/version.h>
887 +#include <crypto/cryptodev.h>
889 +/*
890 + * keep track of whether or not we have been initialised, a big
891 + * issue if we are linked into the kernel and a driver gets started before
892 + * us
893 + */
894 +static int crypto_initted = 0;
896 +/*
897 + * Crypto drivers register themselves by allocating a slot in the
898 + * crypto_drivers table with crypto_get_driverid() and then registering
899 + * each algorithm they support with crypto_register() and crypto_kregister().
900 + */
902 +/*
903 + * lock on driver table
904 + * we track its state as spin_is_locked does not do anything on non-SMP boxes
905 + */
906 +static spinlock_t      crypto_drivers_lock;
907 +static int                     crypto_drivers_locked;          /* for non-SMP boxes */
909 +#define        CRYPTO_DRIVER_LOCK() \
910 +                       ({ \
911 +                               spin_lock_irqsave(&crypto_drivers_lock, d_flags); \
912 +                               crypto_drivers_locked = 1; \
913 +                               dprintk("%s,%d: DRIVER_LOCK()\n", __FILE__, __LINE__); \
914 +                        })
915 +#define        CRYPTO_DRIVER_UNLOCK() \
916 +                       ({ \
917 +                               dprintk("%s,%d: DRIVER_UNLOCK()\n", __FILE__, __LINE__); \
918 +                               crypto_drivers_locked = 0; \
919 +                               spin_unlock_irqrestore(&crypto_drivers_lock, d_flags); \
920 +                        })
921 +#define        CRYPTO_DRIVER_ASSERT() \
922 +                       ({ \
923 +                               if (!crypto_drivers_locked) { \
924 +                                       dprintk("%s,%d: DRIVER_ASSERT!\n", __FILE__, __LINE__); \
925 +                               } \
926 +                        })
928 +/*
929 + * Crypto device/driver capabilities structure.
930 + *
931 + * Synchronization:
932 + * (d) - protected by CRYPTO_DRIVER_LOCK()
933 + * (q) - protected by CRYPTO_Q_LOCK()
934 + * Not tagged fields are read-only.
935 + */
936 +struct cryptocap {
937 +       device_t        cc_dev;                 /* (d) device/driver */
938 +       u_int32_t       cc_sessions;            /* (d) # of sessions */
939 +       u_int32_t       cc_koperations;         /* (d) # os asym operations */
940 +       /*
941 +        * Largest possible operator length (in bits) for each type of
942 +        * encryption algorithm. XXX not used
943 +        */
944 +       u_int16_t       cc_max_op_len[CRYPTO_ALGORITHM_MAX + 1];
945 +       u_int8_t        cc_alg[CRYPTO_ALGORITHM_MAX + 1];
946 +       u_int8_t        cc_kalg[CRK_ALGORITHM_MAX + 1];
948 +       int             cc_flags;               /* (d) flags */
949 +#define CRYPTOCAP_F_CLEANUP    0x80000000      /* needs resource cleanup */
950 +       int             cc_qblocked;            /* (q) symmetric q blocked */
951 +       int             cc_kqblocked;           /* (q) asymmetric q blocked */
953 +       int             cc_unqblocked;          /* (q) symmetric q blocked */
954 +       int             cc_unkqblocked;         /* (q) asymmetric q blocked */
955 +};
956 +static struct cryptocap *crypto_drivers = NULL;
957 +static int crypto_drivers_num = 0;
959 +/*
960 + * There are two queues for crypto requests; one for symmetric (e.g.
961 + * cipher) operations and one for asymmetric (e.g. MOD)operations.
962 + * A single mutex is used to lock access to both queues.  We could
963 + * have one per-queue but having one simplifies handling of block/unblock
964 + * operations.
965 + */
966 +static int crp_sleep = 0;
967 +static LIST_HEAD(crp_q);               /* request queues */
968 +static LIST_HEAD(crp_kq);
970 +static spinlock_t crypto_q_lock;
972 +int crypto_all_qblocked = 0;  /* protect with Q_LOCK */
973 +module_param(crypto_all_qblocked, int, 0444);
974 +MODULE_PARM_DESC(crypto_all_qblocked, "Are all crypto queues blocked");
976 +int crypto_all_kqblocked = 0; /* protect with Q_LOCK */
977 +module_param(crypto_all_kqblocked, int, 0444);
978 +MODULE_PARM_DESC(crypto_all_kqblocked, "Are all asym crypto queues blocked");
980 +#define        CRYPTO_Q_LOCK() \
981 +                       ({ \
982 +                               spin_lock_irqsave(&crypto_q_lock, q_flags); \
983 +                               dprintk("%s,%d: Q_LOCK()\n", __FILE__, __LINE__); \
984 +                        })
985 +#define        CRYPTO_Q_UNLOCK() \
986 +                       ({ \
987 +                               dprintk("%s,%d: Q_UNLOCK()\n", __FILE__, __LINE__); \
988 +                               spin_unlock_irqrestore(&crypto_q_lock, q_flags); \
989 +                        })
991 +/*
992 + * There are two queues for processing completed crypto requests; one
993 + * for the symmetric and one for the asymmetric ops.  We only need one
994 + * but have two to avoid type futzing (cryptop vs. cryptkop).  A single
995 + * mutex is used to lock access to both queues.  Note that this lock
996 + * must be separate from the lock on request queues to insure driver
997 + * callbacks don't generate lock order reversals.
998 + */
999 +static LIST_HEAD(crp_ret_q);           /* callback queues */
1000 +static LIST_HEAD(crp_ret_kq);
1002 +static spinlock_t crypto_ret_q_lock;
1003 +#define        CRYPTO_RETQ_LOCK() \
1004 +                       ({ \
1005 +                               spin_lock_irqsave(&crypto_ret_q_lock, r_flags); \
1006 +                               dprintk("%s,%d: RETQ_LOCK\n", __FILE__, __LINE__); \
1007 +                        })
1008 +#define        CRYPTO_RETQ_UNLOCK() \
1009 +                       ({ \
1010 +                               dprintk("%s,%d: RETQ_UNLOCK\n", __FILE__, __LINE__); \
1011 +                               spin_unlock_irqrestore(&crypto_ret_q_lock, r_flags); \
1012 +                        })
1013 +#define        CRYPTO_RETQ_EMPTY()     (list_empty(&crp_ret_q) && list_empty(&crp_ret_kq))
1015 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
1016 +static kmem_cache_t *cryptop_zone;
1017 +static kmem_cache_t *cryptodesc_zone;
1018 +#else
1019 +static struct kmem_cache *cryptop_zone;
1020 +static struct kmem_cache *cryptodesc_zone;
1021 +#endif
1023 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
1024 +#include <linux/sched.h>
1025 +#define        kill_proc(p,s,v)        send_sig(s,find_task_by_vpid(p),0)
1026 +#endif
1028 +#define debug crypto_debug
1029 +int crypto_debug = 0;
1030 +module_param(crypto_debug, int, 0644);
1031 +MODULE_PARM_DESC(crypto_debug, "Enable debug");
1032 +EXPORT_SYMBOL(crypto_debug);
1034 +/*
1035 + * Maximum number of outstanding crypto requests before we start
1036 + * failing requests.  We need this to prevent DOS when too many
1037 + * requests are arriving for us to keep up.  Otherwise we will
1038 + * run the system out of memory.  Since crypto is slow,  we are
1039 + * usually the bottleneck that needs to say, enough is enough.
1040 + *
1041 + * We cannot print errors when this condition occurs,  we are already too
1042 + * slow,  printing anything will just kill us
1043 + */
1045 +static int crypto_q_cnt = 0;
1046 +module_param(crypto_q_cnt, int, 0444);
1047 +MODULE_PARM_DESC(crypto_q_cnt,
1048 +               "Current number of outstanding crypto requests");
1050 +static int crypto_q_max = 1000;
1051 +module_param(crypto_q_max, int, 0644);
1052 +MODULE_PARM_DESC(crypto_q_max,
1053 +               "Maximum number of outstanding crypto requests");
1055 +#define bootverbose crypto_verbose
1056 +static int crypto_verbose = 0;
1057 +module_param(crypto_verbose, int, 0644);
1058 +MODULE_PARM_DESC(crypto_verbose,
1059 +               "Enable verbose crypto startup");
1061 +int    crypto_usercrypto = 1;  /* userland may do crypto reqs */
1062 +module_param(crypto_usercrypto, int, 0644);
1063 +MODULE_PARM_DESC(crypto_usercrypto,
1064 +          "Enable/disable user-mode access to crypto support");
1066 +int    crypto_userasymcrypto = 1;      /* userland may do asym crypto reqs */
1067 +module_param(crypto_userasymcrypto, int, 0644);
1068 +MODULE_PARM_DESC(crypto_userasymcrypto,
1069 +          "Enable/disable user-mode access to asymmetric crypto support");
1071 +int    crypto_devallowsoft = 0;        /* only use hardware crypto */
1072 +module_param(crypto_devallowsoft, int, 0644);
1073 +MODULE_PARM_DESC(crypto_devallowsoft,
1074 +          "Enable/disable use of software crypto support");
1076 +/*
1077 + * This parameter controls the maximum number of crypto operations to 
1078 + * do consecutively in the crypto kernel thread before scheduling to allow 
1079 + * other processes to run. Without it, it is possible to get into a 
1080 + * situation where the crypto thread never allows any other processes to run.
1081 + * Default to 1000 which should be less than one second.
1082 + */
1083 +static int crypto_max_loopcount = 1000;
1084 +module_param(crypto_max_loopcount, int, 0644);
1085 +MODULE_PARM_DESC(crypto_max_loopcount,
1086 +          "Maximum number of crypto ops to do before yielding to other processes");
1088 +static pid_t   cryptoproc = (pid_t) -1;
1089 +static struct  completion cryptoproc_exited;
1090 +static DECLARE_WAIT_QUEUE_HEAD(cryptoproc_wait);
1091 +static pid_t   cryptoretproc = (pid_t) -1;
1092 +static struct  completion cryptoretproc_exited;
1093 +static DECLARE_WAIT_QUEUE_HEAD(cryptoretproc_wait);
1095 +static int crypto_proc(void *arg);
1096 +static int crypto_ret_proc(void *arg);
1097 +static int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint);
1098 +static int crypto_kinvoke(struct cryptkop *krp, int flags);
1099 +static void crypto_exit(void);
1100 +static  int crypto_init(void);
1102 +static struct cryptostats cryptostats;
1104 +static struct cryptocap *
1105 +crypto_checkdriver(u_int32_t hid)
1106 +{
1107 +       if (crypto_drivers == NULL)
1108 +               return NULL;
1109 +       return (hid >= crypto_drivers_num ? NULL : &crypto_drivers[hid]);
1110 +}
1112 +/*
1113 + * Compare a driver's list of supported algorithms against another
1114 + * list; return non-zero if all algorithms are supported.
1115 + */
1116 +static int
1117 +driver_suitable(const struct cryptocap *cap, const struct cryptoini *cri)
1118 +{
1119 +       const struct cryptoini *cr;
1121 +       /* See if all the algorithms are supported. */
1122 +       for (cr = cri; cr; cr = cr->cri_next)
1123 +               if (cap->cc_alg[cr->cri_alg] == 0)
1124 +                       return 0;
1125 +       return 1;
1126 +}
1128 +/*
1129 + * Select a driver for a new session that supports the specified
1130 + * algorithms and, optionally, is constrained according to the flags.
1131 + * The algorithm we use here is pretty stupid; just use the
1132 + * first driver that supports all the algorithms we need. If there
1133 + * are multiple drivers we choose the driver with the fewest active
1134 + * sessions.  We prefer hardware-backed drivers to software ones.
1135 + *
1136 + * XXX We need more smarts here (in real life too, but that's
1137 + * XXX another story altogether).
1138 + */
1139 +static struct cryptocap *
1140 +crypto_select_driver(const struct cryptoini *cri, int flags)
1141 +{
1142 +       struct cryptocap *cap, *best;
1143 +       int match, hid;
1145 +       CRYPTO_DRIVER_ASSERT();
1147 +       /*
1148 +        * Look first for hardware crypto devices if permitted.
1149 +        */
1150 +       if (flags & CRYPTOCAP_F_HARDWARE)
1151 +               match = CRYPTOCAP_F_HARDWARE;
1152 +       else
1153 +               match = CRYPTOCAP_F_SOFTWARE;
1154 +       best = NULL;
1155 +again:
1156 +       for (hid = 0; hid < crypto_drivers_num; hid++) {
1157 +               cap = &crypto_drivers[hid];
1158 +               /*
1159 +                * If it's not initialized, is in the process of
1160 +                * going away, or is not appropriate (hardware
1161 +                * or software based on match), then skip.
1162 +                */
1163 +               if (cap->cc_dev == NULL ||
1164 +                   (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
1165 +                   (cap->cc_flags & match) == 0)
1166 +                       continue;
1168 +               /* verify all the algorithms are supported. */
1169 +               if (driver_suitable(cap, cri)) {
1170 +                       if (best == NULL ||
1171 +                           cap->cc_sessions < best->cc_sessions)
1172 +                               best = cap;
1173 +               }
1174 +       }
1175 +       if (best != NULL)
1176 +               return best;
1177 +       if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
1178 +               /* sort of an Algol 68-style for loop */
1179 +               match = CRYPTOCAP_F_SOFTWARE;
1180 +               goto again;
1181 +       }
1182 +       return best;
1183 +}
1185 +/*
1186 + * Create a new session.  The crid argument specifies a crypto
1187 + * driver to use or constraints on a driver to select (hardware
1188 + * only, software only, either).  Whatever driver is selected
1189 + * must be capable of the requested crypto algorithms.
1190 + */
1191 +int
1192 +crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int crid)
1193 +{
1194 +       struct cryptocap *cap;
1195 +       u_int32_t hid, lid;
1196 +       int err;
1197 +       unsigned long d_flags;
1199 +       CRYPTO_DRIVER_LOCK();
1200 +       if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
1201 +               /*
1202 +                * Use specified driver; verify it is capable.
1203 +                */
1204 +               cap = crypto_checkdriver(crid);
1205 +               if (cap != NULL && !driver_suitable(cap, cri))
1206 +                       cap = NULL;
1207 +       } else {
1208 +               /*
1209 +                * No requested driver; select based on crid flags.
1210 +                */
1211 +               cap = crypto_select_driver(cri, crid);
1212 +               /*
1213 +                * if NULL then can't do everything in one session.
1214 +                * XXX Fix this. We need to inject a "virtual" session
1215 +                * XXX layer right about here.
1216 +                */
1217 +       }
1218 +       if (cap != NULL) {
1219 +               /* Call the driver initialization routine. */
1220 +               hid = cap - crypto_drivers;
1221 +               lid = hid;              /* Pass the driver ID. */
1222 +               cap->cc_sessions++;
1223 +               CRYPTO_DRIVER_UNLOCK();
1224 +               err = CRYPTODEV_NEWSESSION(cap->cc_dev, &lid, cri);
1225 +               CRYPTO_DRIVER_LOCK();
1226 +               if (err == 0) {
1227 +                       (*sid) = (cap->cc_flags & 0xff000000)
1228 +                              | (hid & 0x00ffffff);
1229 +                       (*sid) <<= 32;
1230 +                       (*sid) |= (lid & 0xffffffff);
1231 +               } else
1232 +                       cap->cc_sessions--;
1233 +       } else
1234 +               err = EINVAL;
1235 +       CRYPTO_DRIVER_UNLOCK();
1236 +       return err;
1237 +}
1239 +static void
1240 +crypto_remove(struct cryptocap *cap)
1241 +{
1242 +       CRYPTO_DRIVER_ASSERT();
1243 +       if (cap->cc_sessions == 0 && cap->cc_koperations == 0)
1244 +               bzero(cap, sizeof(*cap));
1245 +}
1247 +/*
1248 + * Delete an existing session (or a reserved session on an unregistered
1249 + * driver).
1250 + */
1251 +int
1252 +crypto_freesession(u_int64_t sid)
1253 +{
1254 +       struct cryptocap *cap;
1255 +       u_int32_t hid;
1256 +       int err = 0;
1257 +       unsigned long d_flags;
1259 +       dprintk("%s()\n", __FUNCTION__);
1260 +       CRYPTO_DRIVER_LOCK();
1262 +       if (crypto_drivers == NULL) {
1263 +               err = EINVAL;
1264 +               goto done;
1265 +       }
1267 +       /* Determine two IDs. */
1268 +       hid = CRYPTO_SESID2HID(sid);
1270 +       if (hid >= crypto_drivers_num) {
1271 +               dprintk("%s - INVALID DRIVER NUM %d\n", __FUNCTION__, hid);
1272 +               err = ENOENT;
1273 +               goto done;
1274 +       }
1275 +       cap = &crypto_drivers[hid];
1277 +       if (cap->cc_dev) {
1278 +               CRYPTO_DRIVER_UNLOCK();
1279 +               /* Call the driver cleanup routine, if available, unlocked. */
1280 +               err = CRYPTODEV_FREESESSION(cap->cc_dev, sid);
1281 +               CRYPTO_DRIVER_LOCK();
1282 +       }
1284 +       if (cap->cc_sessions)
1285 +               cap->cc_sessions--;
1287 +       if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
1288 +               crypto_remove(cap);
1290 +done:
1291 +       CRYPTO_DRIVER_UNLOCK();
1292 +       return err;
1293 +}
1295 +/*
1296 + * Return an unused driver id.  Used by drivers prior to registering
1297 + * support for the algorithms they handle.
1298 + */
1299 +int32_t
1300 +crypto_get_driverid(device_t dev, int flags)
1301 +{
1302 +       struct cryptocap *newdrv;
1303 +       int i;
1304 +       unsigned long d_flags;
1306 +       if ((flags & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
1307 +               printf("%s: no flags specified when registering driver\n",
1308 +                   device_get_nameunit(dev));
1309 +               return -1;
1310 +       }
1312 +       CRYPTO_DRIVER_LOCK();
1314 +       for (i = 0; i < crypto_drivers_num; i++) {
1315 +               if (crypto_drivers[i].cc_dev == NULL &&
1316 +                   (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0) {
1317 +                       break;
1318 +               }
1319 +       }
1321 +       /* Out of entries, allocate some more. */
1322 +       if (i == crypto_drivers_num) {
1323 +               /* Be careful about wrap-around. */
1324 +               if (2 * crypto_drivers_num <= crypto_drivers_num) {
1325 +                       CRYPTO_DRIVER_UNLOCK();
1326 +                       printk("crypto: driver count wraparound!\n");
1327 +                       return -1;
1328 +               }
1330 +               newdrv = kmalloc(2 * crypto_drivers_num * sizeof(struct cryptocap),
1331 +                               GFP_KERNEL);
1332 +               if (newdrv == NULL) {
1333 +                       CRYPTO_DRIVER_UNLOCK();
1334 +                       printk("crypto: no space to expand driver table!\n");
1335 +                       return -1;
1336 +               }
1338 +               memcpy(newdrv, crypto_drivers,
1339 +                               crypto_drivers_num * sizeof(struct cryptocap));
1340 +               memset(&newdrv[crypto_drivers_num], 0,
1341 +                               crypto_drivers_num * sizeof(struct cryptocap));
1343 +               crypto_drivers_num *= 2;
1345 +               kfree(crypto_drivers);
1346 +               crypto_drivers = newdrv;
1347 +       }
1349 +       /* NB: state is zero'd on free */
1350 +       crypto_drivers[i].cc_sessions = 1;      /* Mark */
1351 +       crypto_drivers[i].cc_dev = dev;
1352 +       crypto_drivers[i].cc_flags = flags;
1353 +       if (bootverbose)
1354 +               printf("crypto: assign %s driver id %u, flags %u\n",
1355 +                   device_get_nameunit(dev), i, flags);
1357 +       CRYPTO_DRIVER_UNLOCK();
1359 +       return i;
1360 +}
1362 +/*
1363 + * Lookup a driver by name.  We match against the full device
1364 + * name and unit, and against just the name.  The latter gives
1365 + * us a simple widlcarding by device name.  On success return the
1366 + * driver/hardware identifier; otherwise return -1.
1367 + */
1368 +int
1369 +crypto_find_driver(const char *match)
1370 +{
1371 +       int i, len = strlen(match);
1372 +       unsigned long d_flags;
1374 +       CRYPTO_DRIVER_LOCK();
1375 +       for (i = 0; i < crypto_drivers_num; i++) {
1376 +               device_t dev = crypto_drivers[i].cc_dev;
1377 +               if (dev == NULL ||
1378 +                   (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP))
1379 +                       continue;
1380 +               if (strncmp(match, device_get_nameunit(dev), len) == 0 ||
1381 +                   strncmp(match, device_get_name(dev), len) == 0)
1382 +                       break;
1383 +       }
1384 +       CRYPTO_DRIVER_UNLOCK();
1385 +       return i < crypto_drivers_num ? i : -1;
1386 +}
1388 +/*
1389 + * Return the device_t for the specified driver or NULL
1390 + * if the driver identifier is invalid.
1391 + */
1392 +device_t
1393 +crypto_find_device_byhid(int hid)
1394 +{
1395 +       struct cryptocap *cap = crypto_checkdriver(hid);
1396 +       return cap != NULL ? cap->cc_dev : NULL;
1397 +}
1399 +/*
1400 + * Return the device/driver capabilities.
1401 + */
1402 +int
1403 +crypto_getcaps(int hid)
1404 +{
1405 +       struct cryptocap *cap = crypto_checkdriver(hid);
1406 +       return cap != NULL ? cap->cc_flags : 0;
1407 +}
1409 +/*
1410 + * Register support for a key-related algorithm.  This routine
1411 + * is called once for each algorithm supported a driver.
1412 + */
1413 +int
1414 +crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags)
1415 +{
1416 +       struct cryptocap *cap;
1417 +       int err;
1418 +       unsigned long d_flags;
1420 +       dprintk("%s()\n", __FUNCTION__);
1421 +       CRYPTO_DRIVER_LOCK();
1423 +       cap = crypto_checkdriver(driverid);
1424 +       if (cap != NULL &&
1425 +           (CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) {
1426 +               /*
1427 +                * XXX Do some performance testing to determine placing.
1428 +                * XXX We probably need an auxiliary data structure that
1429 +                * XXX describes relative performances.
1430 +                */
1432 +               cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
1433 +               if (bootverbose)
1434 +                       printf("crypto: %s registers key alg %u flags %u\n"
1435 +                               , device_get_nameunit(cap->cc_dev)
1436 +                               , kalg
1437 +                               , flags
1438 +                       );
1439 +               err = 0;
1440 +       } else
1441 +               err = EINVAL;
1443 +       CRYPTO_DRIVER_UNLOCK();
1444 +       return err;
1445 +}
1447 +/*
1448 + * Register support for a non-key-related algorithm.  This routine
1449 + * is called once for each such algorithm supported by a driver.
1450 + */
1451 +int
1452 +crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
1453 +    u_int32_t flags)
1454 +{
1455 +       struct cryptocap *cap;
1456 +       int err;
1457 +       unsigned long d_flags;
1459 +       dprintk("%s(id=0x%x, alg=%d, maxoplen=%d, flags=0x%x)\n", __FUNCTION__,
1460 +                       driverid, alg, maxoplen, flags);
1462 +       CRYPTO_DRIVER_LOCK();
1464 +       cap = crypto_checkdriver(driverid);
1465 +       /* NB: algorithms are in the range [1..max] */
1466 +       if (cap != NULL &&
1467 +           (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX)) {
1468 +               /*
1469 +                * XXX Do some performance testing to determine placing.
1470 +                * XXX We probably need an auxiliary data structure that
1471 +                * XXX describes relative performances.
1472 +                */
1474 +               cap->cc_alg[alg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
1475 +               cap->cc_max_op_len[alg] = maxoplen;
1476 +               if (bootverbose)
1477 +                       printf("crypto: %s registers alg %u flags %u maxoplen %u\n"
1478 +                               , device_get_nameunit(cap->cc_dev)
1479 +                               , alg
1480 +                               , flags
1481 +                               , maxoplen
1482 +                       );
1483 +               cap->cc_sessions = 0;           /* Unmark */
1484 +               err = 0;
1485 +       } else
1486 +               err = EINVAL;
1488 +       CRYPTO_DRIVER_UNLOCK();
1489 +       return err;
1490 +}
1492 +static void
1493 +driver_finis(struct cryptocap *cap)
1494 +{
1495 +       u_int32_t ses, kops;
1497 +       CRYPTO_DRIVER_ASSERT();
1499 +       ses = cap->cc_sessions;
1500 +       kops = cap->cc_koperations;
1501 +       bzero(cap, sizeof(*cap));
1502 +       if (ses != 0 || kops != 0) {
1503 +               /*
1504 +                * If there are pending sessions,
1505 +                * just mark as invalid.
1506 +                */
1507 +               cap->cc_flags |= CRYPTOCAP_F_CLEANUP;
1508 +               cap->cc_sessions = ses;
1509 +               cap->cc_koperations = kops;
1510 +       }
1511 +}
1513 +/*
1514 + * Unregister a crypto driver. If there are pending sessions using it,
1515 + * leave enough information around so that subsequent calls using those
1516 + * sessions will correctly detect the driver has been unregistered and
1517 + * reroute requests.
1518 + */
1519 +int
1520 +crypto_unregister(u_int32_t driverid, int alg)
1521 +{
1522 +       struct cryptocap *cap;
1523 +       int i, err;
1524 +       unsigned long d_flags;
1526 +       dprintk("%s()\n", __FUNCTION__);
1527 +       CRYPTO_DRIVER_LOCK();
1529 +       cap = crypto_checkdriver(driverid);
1530 +       if (cap != NULL &&
1531 +           (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX) &&
1532 +           cap->cc_alg[alg] != 0) {
1533 +               cap->cc_alg[alg] = 0;
1534 +               cap->cc_max_op_len[alg] = 0;
1536 +               /* Was this the last algorithm ? */
1537 +               for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++)
1538 +                       if (cap->cc_alg[i] != 0)
1539 +                               break;
1541 +               if (i == CRYPTO_ALGORITHM_MAX + 1)
1542 +                       driver_finis(cap);
1543 +               err = 0;
1544 +       } else
1545 +               err = EINVAL;
1546 +       CRYPTO_DRIVER_UNLOCK();
1547 +       return err;
1548 +}
1550 +/*
1551 + * Unregister all algorithms associated with a crypto driver.
1552 + * If there are pending sessions using it, leave enough information
1553 + * around so that subsequent calls using those sessions will
1554 + * correctly detect the driver has been unregistered and reroute
1555 + * requests.
1556 + */
1557 +int
1558 +crypto_unregister_all(u_int32_t driverid)
1559 +{
1560 +       struct cryptocap *cap;
1561 +       int err;
1562 +       unsigned long d_flags;
1564 +       dprintk("%s()\n", __FUNCTION__);
1565 +       CRYPTO_DRIVER_LOCK();
1566 +       cap = crypto_checkdriver(driverid);
1567 +       if (cap != NULL) {
1568 +               driver_finis(cap);
1569 +               err = 0;
1570 +       } else
1571 +               err = EINVAL;
1572 +       CRYPTO_DRIVER_UNLOCK();
1574 +       return err;
1575 +}
1577 +/*
1578 + * Clear blockage on a driver.  The what parameter indicates whether
1579 + * the driver is now ready for cryptop's and/or cryptokop's.
1580 + */
1581 +int
1582 +crypto_unblock(u_int32_t driverid, int what)
1583 +{
1584 +       struct cryptocap *cap;
1585 +       int err;
1586 +       unsigned long q_flags;
1588 +       CRYPTO_Q_LOCK();
1589 +       cap = crypto_checkdriver(driverid);
1590 +       if (cap != NULL) {
1591 +               if (what & CRYPTO_SYMQ) {
1592 +                       cap->cc_qblocked = 0;
1593 +                       cap->cc_unqblocked = 0;
1594 +                       crypto_all_qblocked = 0;
1595 +               }
1596 +               if (what & CRYPTO_ASYMQ) {
1597 +                       cap->cc_kqblocked = 0;
1598 +                       cap->cc_unkqblocked = 0;
1599 +                       crypto_all_kqblocked = 0;
1600 +               }
1601 +               if (crp_sleep)
1602 +                       wake_up_interruptible(&cryptoproc_wait);
1603 +               err = 0;
1604 +       } else
1605 +               err = EINVAL;
1606 +       CRYPTO_Q_UNLOCK(); //DAVIDM should this be a driver lock
1608 +       return err;
1609 +}
1611 +/*
1612 + * Add a crypto request to a queue, to be processed by the kernel thread.
1613 + */
1614 +int
1615 +crypto_dispatch(struct cryptop *crp)
1616 +{
1617 +       struct cryptocap *cap;
1618 +       int result = -1;
1619 +       unsigned long q_flags;
1621 +       dprintk("%s()\n", __FUNCTION__);
1623 +       cryptostats.cs_ops++;
1625 +       CRYPTO_Q_LOCK();
1626 +       if (crypto_q_cnt >= crypto_q_max) {
1627 +               CRYPTO_Q_UNLOCK();
1628 +               cryptostats.cs_drops++;
1629 +               return ENOMEM;
1630 +       }
1631 +       crypto_q_cnt++;
1633 +       /* make sure we are starting a fresh run on this crp. */
1634 +       crp->crp_flags &= ~CRYPTO_F_DONE;
1635 +       crp->crp_etype = 0;
1637 +       /*
1638 +        * Caller marked the request to be processed immediately; dispatch
1639 +        * it directly to the driver unless the driver is currently blocked.
1640 +        */
1641 +       if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) {
1642 +               int hid = CRYPTO_SESID2HID(crp->crp_sid);
1643 +               cap = crypto_checkdriver(hid);
1644 +               /* Driver cannot disappear when there is an active session. */
1645 +               KASSERT(cap != NULL, ("%s: Driver disappeared.", __func__));
1646 +               if (!cap->cc_qblocked) {
1647 +                       crypto_all_qblocked = 0;
1648 +                       crypto_drivers[hid].cc_unqblocked = 1;
1649 +                       CRYPTO_Q_UNLOCK();
1650 +                       result = crypto_invoke(cap, crp, 0);
1651 +                       CRYPTO_Q_LOCK();
1652 +                       if (result == ERESTART)
1653 +                               if (crypto_drivers[hid].cc_unqblocked)
1654 +                                       crypto_drivers[hid].cc_qblocked = 1;
1655 +                       crypto_drivers[hid].cc_unqblocked = 0;
1656 +               }
1657 +       }
1658 +       if (result == ERESTART) {
1659 +               /*
1660 +                * The driver ran out of resources, mark the
1661 +                * driver ``blocked'' for cryptop's and put
1662 +                * the request back in the queue.  It would
1663 +                * best to put the request back where we got
1664 +                * it but that's hard so for now we put it
1665 +                * at the front.  This should be ok; putting
1666 +                * it at the end does not work.
1667 +                */
1668 +               list_add(&crp->crp_next, &crp_q);
1669 +               cryptostats.cs_blocks++;
1670 +               result = 0;
1671 +       } else if (result == -1) {
1672 +               TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
1673 +               result = 0;
1674 +       }
1675 +       if (crp_sleep)
1676 +               wake_up_interruptible(&cryptoproc_wait);
1677 +       CRYPTO_Q_UNLOCK();
1678 +       return result;
1679 +}
1681 +/*
1682 + * Add an asymetric crypto request to a queue,
1683 + * to be processed by the kernel thread.
1684 + */
1685 +int
1686 +crypto_kdispatch(struct cryptkop *krp)
1687 +{
1688 +       int error;
1689 +       unsigned long q_flags;
1691 +       cryptostats.cs_kops++;
1693 +       error = crypto_kinvoke(krp, krp->krp_crid);
1694 +       if (error == ERESTART) {
1695 +               CRYPTO_Q_LOCK();
1696 +               TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
1697 +               if (crp_sleep)
1698 +                       wake_up_interruptible(&cryptoproc_wait);
1699 +               CRYPTO_Q_UNLOCK();
1700 +               error = 0;
1701 +       }
1702 +       return error;
1703 +}
1705 +/*
1706 + * Verify a driver is suitable for the specified operation.
1707 + */
1708 +static __inline int
1709 +kdriver_suitable(const struct cryptocap *cap, const struct cryptkop *krp)
1710 +{
1711 +       return (cap->cc_kalg[krp->krp_op] & CRYPTO_ALG_FLAG_SUPPORTED) != 0;
1712 +}
1714 +/*
1715 + * Select a driver for an asym operation.  The driver must
1716 + * support the necessary algorithm.  The caller can constrain
1717 + * which device is selected with the flags parameter.  The
1718 + * algorithm we use here is pretty stupid; just use the first
1719 + * driver that supports the algorithms we need. If there are
1720 + * multiple suitable drivers we choose the driver with the
1721 + * fewest active operations.  We prefer hardware-backed
1722 + * drivers to software ones when either may be used.
1723 + */
1724 +static struct cryptocap *
1725 +crypto_select_kdriver(const struct cryptkop *krp, int flags)
1726 +{
1727 +       struct cryptocap *cap, *best, *blocked;
1728 +       int match, hid;
1730 +       CRYPTO_DRIVER_ASSERT();
1732 +       /*
1733 +        * Look first for hardware crypto devices if permitted.
1734 +        */
1735 +       if (flags & CRYPTOCAP_F_HARDWARE)
1736 +               match = CRYPTOCAP_F_HARDWARE;
1737 +       else
1738 +               match = CRYPTOCAP_F_SOFTWARE;
1739 +       best = NULL;
1740 +       blocked = NULL;
1741 +again:
1742 +       for (hid = 0; hid < crypto_drivers_num; hid++) {
1743 +               cap = &crypto_drivers[hid];
1744 +               /*
1745 +                * If it's not initialized, is in the process of
1746 +                * going away, or is not appropriate (hardware
1747 +                * or software based on match), then skip.
1748 +                */
1749 +               if (cap->cc_dev == NULL ||
1750 +                   (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
1751 +                   (cap->cc_flags & match) == 0)
1752 +                       continue;
1754 +               /* verify all the algorithms are supported. */
1755 +               if (kdriver_suitable(cap, krp)) {
1756 +                       if (best == NULL ||
1757 +                           cap->cc_koperations < best->cc_koperations)
1758 +                               best = cap;
1759 +               }
1760 +       }
1761 +       if (best != NULL)
1762 +               return best;
1763 +       if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
1764 +               /* sort of an Algol 68-style for loop */
1765 +               match = CRYPTOCAP_F_SOFTWARE;
1766 +               goto again;
1767 +       }
1768 +       return best;
1769 +}
1771 +/*
1772 + * Dispatch an assymetric crypto request.
1773 + */
1774 +static int
1775 +crypto_kinvoke(struct cryptkop *krp, int crid)
1776 +{
1777 +       struct cryptocap *cap = NULL;
1778 +       int error;
1779 +       unsigned long d_flags;
1781 +       KASSERT(krp != NULL, ("%s: krp == NULL", __func__));
1782 +       KASSERT(krp->krp_callback != NULL,
1783 +           ("%s: krp->crp_callback == NULL", __func__));
1785 +       CRYPTO_DRIVER_LOCK();
1786 +       if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
1787 +               cap = crypto_checkdriver(crid);
1788 +               if (cap != NULL) {
1789 +                       /*
1790 +                        * Driver present, it must support the necessary
1791 +                        * algorithm and, if s/w drivers are excluded,
1792 +                        * it must be registered as hardware-backed.
1793 +                        */
1794 +                       if (!kdriver_suitable(cap, krp) ||
1795 +                           (!crypto_devallowsoft &&
1796 +                            (cap->cc_flags & CRYPTOCAP_F_HARDWARE) == 0))
1797 +                               cap = NULL;
1798 +               }
1799 +       } else {
1800 +               /*
1801 +                * No requested driver; select based on crid flags.
1802 +                */
1803 +               if (!crypto_devallowsoft)       /* NB: disallow s/w drivers */
1804 +                       crid &= ~CRYPTOCAP_F_SOFTWARE;
1805 +               cap = crypto_select_kdriver(krp, crid);
1806 +       }
1807 +       if (cap != NULL && !cap->cc_kqblocked) {
1808 +               krp->krp_hid = cap - crypto_drivers;
1809 +               cap->cc_koperations++;
1810 +               CRYPTO_DRIVER_UNLOCK();
1811 +               error = CRYPTODEV_KPROCESS(cap->cc_dev, krp, 0);
1812 +               CRYPTO_DRIVER_LOCK();
1813 +               if (error == ERESTART) {
1814 +                       cap->cc_koperations--;
1815 +                       CRYPTO_DRIVER_UNLOCK();
1816 +                       return (error);
1817 +               }
1818 +               /* return the actual device used */
1819 +               krp->krp_crid = krp->krp_hid;
1820 +       } else {
1821 +               /*
1822 +                * NB: cap is !NULL if device is blocked; in
1823 +                *     that case return ERESTART so the operation
1824 +                *     is resubmitted if possible.
1825 +                */
1826 +               error = (cap == NULL) ? ENODEV : ERESTART;
1827 +       }
1828 +       CRYPTO_DRIVER_UNLOCK();
1830 +       if (error) {
1831 +               krp->krp_status = error;
1832 +               crypto_kdone(krp);
1833 +       }
1834 +       return 0;
1835 +}
1838 +/*
1839 + * Dispatch a crypto request to the appropriate crypto devices.
1840 + */
1841 +static int
1842 +crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint)
1843 +{
1844 +       KASSERT(crp != NULL, ("%s: crp == NULL", __func__));
1845 +       KASSERT(crp->crp_callback != NULL,
1846 +           ("%s: crp->crp_callback == NULL", __func__));
1847 +       KASSERT(crp->crp_desc != NULL, ("%s: crp->crp_desc == NULL", __func__));
1849 +       dprintk("%s()\n", __FUNCTION__);
1851 +#ifdef CRYPTO_TIMING
1852 +       if (crypto_timing)
1853 +               crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp);
1854 +#endif
1855 +       if (cap->cc_flags & CRYPTOCAP_F_CLEANUP) {
1856 +               struct cryptodesc *crd;
1857 +               u_int64_t nid;
1859 +               /*
1860 +                * Driver has unregistered; migrate the session and return
1861 +                * an error to the caller so they'll resubmit the op.
1862 +                *
1863 +                * XXX: What if there are more already queued requests for this
1864 +                *      session?
1865 +                */
1866 +               crypto_freesession(crp->crp_sid);
1868 +               for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
1869 +                       crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
1871 +               /* XXX propagate flags from initial session? */
1872 +               if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI),
1873 +                   CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE) == 0)
1874 +                       crp->crp_sid = nid;
1876 +               crp->crp_etype = EAGAIN;
1877 +               crypto_done(crp);
1878 +               return 0;
1879 +       } else {
1880 +               /*
1881 +                * Invoke the driver to process the request.
1882 +                */
1883 +               return CRYPTODEV_PROCESS(cap->cc_dev, crp, hint);
1884 +       }
1885 +}
1887 +/*
1888 + * Release a set of crypto descriptors.
1889 + */
1890 +void
1891 +crypto_freereq(struct cryptop *crp)
1892 +{
1893 +       struct cryptodesc *crd;
1895 +       if (crp == NULL)
1896 +               return;
1898 +#ifdef DIAGNOSTIC
1899 +       {
1900 +               struct cryptop *crp2;
1901 +               unsigned long q_flags;
1903 +               CRYPTO_Q_LOCK();
1904 +               TAILQ_FOREACH(crp2, &crp_q, crp_next) {
1905 +                       KASSERT(crp2 != crp,
1906 +                           ("Freeing cryptop from the crypto queue (%p).",
1907 +                           crp));
1908 +               }
1909 +               CRYPTO_Q_UNLOCK();
1910 +               CRYPTO_RETQ_LOCK();
1911 +               TAILQ_FOREACH(crp2, &crp_ret_q, crp_next) {
1912 +                       KASSERT(crp2 != crp,
1913 +                           ("Freeing cryptop from the return queue (%p).",
1914 +                           crp));
1915 +               }
1916 +               CRYPTO_RETQ_UNLOCK();
1917 +       }
1918 +#endif
1920 +       while ((crd = crp->crp_desc) != NULL) {
1921 +               crp->crp_desc = crd->crd_next;
1922 +               kmem_cache_free(cryptodesc_zone, crd);
1923 +       }
1924 +       kmem_cache_free(cryptop_zone, crp);
1925 +}
1927 +/*
1928 + * Acquire a set of crypto descriptors.
1929 + */
1930 +struct cryptop *
1931 +crypto_getreq(int num)
1932 +{
1933 +       struct cryptodesc *crd;
1934 +       struct cryptop *crp;
1936 +       crp = kmem_cache_alloc(cryptop_zone, SLAB_ATOMIC);
1937 +       if (crp != NULL) {
1938 +               memset(crp, 0, sizeof(*crp));
1939 +               INIT_LIST_HEAD(&crp->crp_next);
1940 +               init_waitqueue_head(&crp->crp_waitq);
1941 +               while (num--) {
1942 +                       crd = kmem_cache_alloc(cryptodesc_zone, SLAB_ATOMIC);
1943 +                       if (crd == NULL) {
1944 +                               crypto_freereq(crp);
1945 +                               return NULL;
1946 +                       }
1947 +                       memset(crd, 0, sizeof(*crd));
1948 +                       crd->crd_next = crp->crp_desc;
1949 +                       crp->crp_desc = crd;
1950 +               }
1951 +       }
1952 +       return crp;
1953 +}
1955 +/*
1956 + * Invoke the callback on behalf of the driver.
1957 + */
1958 +void
1959 +crypto_done(struct cryptop *crp)
1960 +{
1961 +       unsigned long q_flags;
1963 +       dprintk("%s()\n", __FUNCTION__);
1964 +       if ((crp->crp_flags & CRYPTO_F_DONE) == 0) {
1965 +               crp->crp_flags |= CRYPTO_F_DONE;
1966 +               CRYPTO_Q_LOCK();
1967 +               crypto_q_cnt--;
1968 +               CRYPTO_Q_UNLOCK();
1969 +       } else
1970 +               printk("crypto: crypto_done op already done, flags 0x%x",
1971 +                               crp->crp_flags);
1972 +       if (crp->crp_etype != 0)
1973 +               cryptostats.cs_errs++;
1974 +       /*
1975 +        * CBIMM means unconditionally do the callback immediately;
1976 +        * CBIFSYNC means do the callback immediately only if the
1977 +        * operation was done synchronously.  Both are used to avoid
1978 +        * doing extraneous context switches; the latter is mostly
1979 +        * used with the software crypto driver.
1980 +        */
1981 +       if ((crp->crp_flags & CRYPTO_F_CBIMM) ||
1982 +           ((crp->crp_flags & CRYPTO_F_CBIFSYNC) &&
1983 +            (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC))) {
1984 +               /*
1985 +                * Do the callback directly.  This is ok when the
1986 +                * callback routine does very little (e.g. the
1987 +                * /dev/crypto callback method just does a wakeup).
1988 +                */
1989 +               crp->crp_callback(crp);
1990 +       } else {
1991 +               unsigned long r_flags;
1992 +               /*
1993 +                * Normal case; queue the callback for the thread.
1994 +                */
1995 +               CRYPTO_RETQ_LOCK();
1996 +               if (CRYPTO_RETQ_EMPTY())
1997 +                       wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
1998 +               TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
1999 +               CRYPTO_RETQ_UNLOCK();
2000 +       }
2001 +}
2003 +/*
2004 + * Invoke the callback on behalf of the driver.
2005 + */
2006 +void
2007 +crypto_kdone(struct cryptkop *krp)
2008 +{
2009 +       struct cryptocap *cap;
2010 +       unsigned long d_flags;
2012 +       if ((krp->krp_flags & CRYPTO_KF_DONE) != 0)
2013 +               printk("crypto: crypto_kdone op already done, flags 0x%x",
2014 +                               krp->krp_flags);
2015 +       krp->krp_flags |= CRYPTO_KF_DONE;
2016 +       if (krp->krp_status != 0)
2017 +               cryptostats.cs_kerrs++;
2019 +       CRYPTO_DRIVER_LOCK();
2020 +       /* XXX: What if driver is loaded in the meantime? */
2021 +       if (krp->krp_hid < crypto_drivers_num) {
2022 +               cap = &crypto_drivers[krp->krp_hid];
2023 +               cap->cc_koperations--;
2024 +               KASSERT(cap->cc_koperations >= 0, ("cc_koperations < 0"));
2025 +               if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
2026 +                       crypto_remove(cap);
2027 +       }
2028 +       CRYPTO_DRIVER_UNLOCK();
2030 +       /*
2031 +        * CBIMM means unconditionally do the callback immediately;
2032 +        * This is used to avoid doing extraneous context switches
2033 +        */
2034 +       if ((krp->krp_flags & CRYPTO_KF_CBIMM)) {
2035 +               /*
2036 +                * Do the callback directly.  This is ok when the
2037 +                * callback routine does very little (e.g. the
2038 +                * /dev/crypto callback method just does a wakeup).
2039 +                */
2040 +               krp->krp_callback(krp);
2041 +       } else {
2042 +               unsigned long r_flags;
2043 +               /*
2044 +                * Normal case; queue the callback for the thread.
2045 +                */
2046 +               CRYPTO_RETQ_LOCK();
2047 +               if (CRYPTO_RETQ_EMPTY())
2048 +                       wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
2049 +               TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
2050 +               CRYPTO_RETQ_UNLOCK();
2051 +       }
2052 +}
2054 +int
2055 +crypto_getfeat(int *featp)
2056 +{
2057 +       int hid, kalg, feat = 0;
2058 +       unsigned long d_flags;
2060 +       CRYPTO_DRIVER_LOCK();
2061 +       for (hid = 0; hid < crypto_drivers_num; hid++) {
2062 +               const struct cryptocap *cap = &crypto_drivers[hid];
2064 +               if ((cap->cc_flags & CRYPTOCAP_F_SOFTWARE) &&
2065 +                   !crypto_devallowsoft) {
2066 +                       continue;
2067 +               }
2068 +               for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)
2069 +                       if (cap->cc_kalg[kalg] & CRYPTO_ALG_FLAG_SUPPORTED)
2070 +                               feat |=  1 << kalg;
2071 +       }
2072 +       CRYPTO_DRIVER_UNLOCK();
2073 +       *featp = feat;
2074 +       return (0);
2075 +}
2077 +/*
2078 + * Crypto thread, dispatches crypto requests.
2079 + */
2080 +static int
2081 +crypto_proc(void *arg)
2082 +{
2083 +       struct cryptop *crp, *submit;
2084 +       struct cryptkop *krp, *krpp;
2085 +       struct cryptocap *cap;
2086 +       u_int32_t hid;
2087 +       int result, hint;
2088 +       unsigned long q_flags;
2089 +       int loopcount = 0;
2091 +       ocf_daemonize("crypto");
2093 +       CRYPTO_Q_LOCK();
2094 +       for (;;) {
2095 +               /*
2096 +                * we need to make sure we don't get into a busy loop with nothing
2097 +                * to do,  the two crypto_all_*blocked vars help us find out when
2098 +                * we are all full and can do nothing on any driver or Q.  If so we
2099 +                * wait for an unblock.
2100 +                */
2101 +               crypto_all_qblocked  = !list_empty(&crp_q);
2103 +               /*
2104 +                * Find the first element in the queue that can be
2105 +                * processed and look-ahead to see if multiple ops
2106 +                * are ready for the same driver.
2107 +                */
2108 +               submit = NULL;
2109 +               hint = 0;
2110 +               list_for_each_entry(crp, &crp_q, crp_next) {
2111 +                       hid = CRYPTO_SESID2HID(crp->crp_sid);
2112 +                       cap = crypto_checkdriver(hid);
2113 +                       /*
2114 +                        * Driver cannot disappear when there is an active
2115 +                        * session.
2116 +                        */
2117 +                       KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
2118 +                           __func__, __LINE__));
2119 +                       if (cap == NULL || cap->cc_dev == NULL) {
2120 +                               /* Op needs to be migrated, process it. */
2121 +                               if (submit == NULL)
2122 +                                       submit = crp;
2123 +                               break;
2124 +                       }
2125 +                       if (!cap->cc_qblocked) {
2126 +                               if (submit != NULL) {
2127 +                                       /*
2128 +                                        * We stop on finding another op,
2129 +                                        * regardless whether its for the same
2130 +                                        * driver or not.  We could keep
2131 +                                        * searching the queue but it might be
2132 +                                        * better to just use a per-driver
2133 +                                        * queue instead.
2134 +                                        */
2135 +                                       if (CRYPTO_SESID2HID(submit->crp_sid) == hid)
2136 +                                               hint = CRYPTO_HINT_MORE;
2137 +                                       break;
2138 +                               } else {
2139 +                                       submit = crp;
2140 +                                       if ((submit->crp_flags & CRYPTO_F_BATCH) == 0)
2141 +                                               break;
2142 +                                       /* keep scanning for more are q'd */
2143 +                               }
2144 +                       }
2145 +               }
2146 +               if (submit != NULL) {
2147 +                       hid = CRYPTO_SESID2HID(submit->crp_sid);
2148 +                       crypto_all_qblocked = 0;
2149 +                       list_del(&submit->crp_next);
2150 +                       crypto_drivers[hid].cc_unqblocked = 1;
2151 +                       cap = crypto_checkdriver(hid);
2152 +                       CRYPTO_Q_UNLOCK();
2153 +                       KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
2154 +                           __func__, __LINE__));
2155 +                       result = crypto_invoke(cap, submit, hint);
2156 +                       CRYPTO_Q_LOCK();
2157 +                       if (result == ERESTART) {
2158 +                               /*
2159 +                                * The driver ran out of resources, mark the
2160 +                                * driver ``blocked'' for cryptop's and put
2161 +                                * the request back in the queue.  It would
2162 +                                * best to put the request back where we got
2163 +                                * it but that's hard so for now we put it
2164 +                                * at the front.  This should be ok; putting
2165 +                                * it at the end does not work.
2166 +                                */
2167 +                               /* XXX validate sid again? */
2168 +                               list_add(&submit->crp_next, &crp_q);
2169 +                               cryptostats.cs_blocks++;
2170 +                               if (crypto_drivers[hid].cc_unqblocked)
2171 +                                       crypto_drivers[hid].cc_qblocked=0;
2172 +                               crypto_drivers[hid].cc_unqblocked=0;
2173 +                       }
2174 +                       crypto_drivers[hid].cc_unqblocked = 0;
2175 +               }
2177 +               crypto_all_kqblocked = !list_empty(&crp_kq);
2179 +               /* As above, but for key ops */
2180 +               krp = NULL;
2181 +               list_for_each_entry(krpp, &crp_kq, krp_next) {
2182 +                       cap = crypto_checkdriver(krpp->krp_hid);
2183 +                       if (cap == NULL || cap->cc_dev == NULL) {
2184 +                               /*
2185 +                                * Operation needs to be migrated, invalidate
2186 +                                * the assigned device so it will reselect a
2187 +                                * new one below.  Propagate the original
2188 +                                * crid selection flags if supplied.
2189 +                                */
2190 +                               krp->krp_hid = krp->krp_crid &
2191 +                                   (CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE);
2192 +                               if (krp->krp_hid == 0)
2193 +                                       krp->krp_hid =
2194 +                                   CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE;
2195 +                               break;
2196 +                       }
2197 +                       if (!cap->cc_kqblocked) {
2198 +                               krp = krpp;
2199 +                               break;
2200 +                       }
2201 +               }
2202 +               if (krp != NULL) {
2203 +                       crypto_all_kqblocked = 0;
2204 +                       list_del(&krp->krp_next);
2205 +                       crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
2206 +                       CRYPTO_Q_UNLOCK();
2207 +                       result = crypto_kinvoke(krp, krp->krp_hid);
2208 +                       CRYPTO_Q_LOCK();
2209 +                       if (result == ERESTART) {
2210 +                               /*
2211 +                                * The driver ran out of resources, mark the
2212 +                                * driver ``blocked'' for cryptkop's and put
2213 +                                * the request back in the queue.  It would
2214 +                                * best to put the request back where we got
2215 +                                * it but that's hard so for now we put it
2216 +                                * at the front.  This should be ok; putting
2217 +                                * it at the end does not work.
2218 +                                */
2219 +                               /* XXX validate sid again? */
2220 +                               list_add(&krp->krp_next, &crp_kq);
2221 +                               cryptostats.cs_kblocks++;
2222 +                       } else
2223 +                               crypto_drivers[krp->krp_hid].cc_kqblocked = 0;
2224 +               }
2226 +               if (submit == NULL && krp == NULL) {
2227 +                       /*
2228 +                        * Nothing more to be processed.  Sleep until we're
2229 +                        * woken because there are more ops to process.
2230 +                        * This happens either by submission or by a driver
2231 +                        * becoming unblocked and notifying us through
2232 +                        * crypto_unblock.  Note that when we wakeup we
2233 +                        * start processing each queue again from the
2234 +                        * front. It's not clear that it's important to
2235 +                        * preserve this ordering since ops may finish
2236 +                        * out of order if dispatched to different devices
2237 +                        * and some become blocked while others do not.
2238 +                        */
2239 +                       dprintk("%s - sleeping (qe=%d qb=%d kqe=%d kqb=%d)\n",
2240 +                                       __FUNCTION__,
2241 +                                       list_empty(&crp_q), crypto_all_qblocked,
2242 +                                       list_empty(&crp_kq), crypto_all_kqblocked);
2243 +                       loopcount = 0;
2244 +                       CRYPTO_Q_UNLOCK();
2245 +                       crp_sleep = 1;
2246 +                       wait_event_interruptible(cryptoproc_wait,
2247 +                                       !(list_empty(&crp_q) || crypto_all_qblocked) ||
2248 +                                       !(list_empty(&crp_kq) || crypto_all_kqblocked) ||
2249 +                                       cryptoproc == (pid_t) -1);
2250 +                       crp_sleep = 0;
2251 +                       if (signal_pending (current)) {
2252 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
2253 +                               spin_lock_irq(&current->sigmask_lock);
2254 +#endif
2255 +                               flush_signals(current);
2256 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
2257 +                               spin_unlock_irq(&current->sigmask_lock);
2258 +#endif
2259 +                       }
2260 +                       CRYPTO_Q_LOCK();
2261 +                       dprintk("%s - awake\n", __FUNCTION__);
2262 +                       if (cryptoproc == (pid_t) -1)
2263 +                               break;
2264 +                       cryptostats.cs_intrs++;
2265 +               } else if (loopcount > crypto_max_loopcount) {
2266 +                       /*
2267 +                        * Give other processes a chance to run if we've 
2268 +                        * been using the CPU exclusively for a while.
2269 +                        */
2270 +                       loopcount = 0;
2271 +                       schedule();
2272 +               }
2273 +               loopcount++;
2274 +       }
2275 +       CRYPTO_Q_UNLOCK();
2276 +       complete_and_exit(&cryptoproc_exited, 0);
2277 +}
2279 +/*
2280 + * Crypto returns thread, does callbacks for processed crypto requests.
2281 + * Callbacks are done here, rather than in the crypto drivers, because
2282 + * callbacks typically are expensive and would slow interrupt handling.
2283 + */
2284 +static int
2285 +crypto_ret_proc(void *arg)
2286 +{
2287 +       struct cryptop *crpt;
2288 +       struct cryptkop *krpt;
2289 +       unsigned long  r_flags;
2291 +       ocf_daemonize("crypto_ret");
2293 +       CRYPTO_RETQ_LOCK();
2294 +       for (;;) {
2295 +               /* Harvest return q's for completed ops */
2296 +               crpt = NULL;
2297 +               if (!list_empty(&crp_ret_q))
2298 +                       crpt = list_entry(crp_ret_q.next, typeof(*crpt), crp_next);
2299 +               if (crpt != NULL)
2300 +                       list_del(&crpt->crp_next);
2302 +               krpt = NULL;
2303 +               if (!list_empty(&crp_ret_kq))
2304 +                       krpt = list_entry(crp_ret_kq.next, typeof(*krpt), krp_next);
2305 +               if (krpt != NULL)
2306 +                       list_del(&krpt->krp_next);
2308 +               if (crpt != NULL || krpt != NULL) {
2309 +                       CRYPTO_RETQ_UNLOCK();
2310 +                       /*
2311 +                        * Run callbacks unlocked.
2312 +                        */
2313 +                       if (crpt != NULL)
2314 +                               crpt->crp_callback(crpt);
2315 +                       if (krpt != NULL)
2316 +                               krpt->krp_callback(krpt);
2317 +                       CRYPTO_RETQ_LOCK();
2318 +               } else {
2319 +                       /*
2320 +                        * Nothing more to be processed.  Sleep until we're
2321 +                        * woken because there are more returns to process.
2322 +                        */
2323 +                       dprintk("%s - sleeping\n", __FUNCTION__);
2324 +                       CRYPTO_RETQ_UNLOCK();
2325 +                       wait_event_interruptible(cryptoretproc_wait,
2326 +                                       cryptoretproc == (pid_t) -1 ||
2327 +                                       !list_empty(&crp_ret_q) ||
2328 +                                       !list_empty(&crp_ret_kq));
2329 +                       if (signal_pending (current)) {
2330 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
2331 +                               spin_lock_irq(&current->sigmask_lock);
2332 +#endif
2333 +                               flush_signals(current);
2334 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
2335 +                               spin_unlock_irq(&current->sigmask_lock);
2336 +#endif
2337 +                       }
2338 +                       CRYPTO_RETQ_LOCK();
2339 +                       dprintk("%s - awake\n", __FUNCTION__);
2340 +                       if (cryptoretproc == (pid_t) -1) {
2341 +                               dprintk("%s - EXITING!\n", __FUNCTION__);
2342 +                               break;
2343 +                       }
2344 +                       cryptostats.cs_rets++;
2345 +               }
2346 +       }
2347 +       CRYPTO_RETQ_UNLOCK();
2348 +       complete_and_exit(&cryptoretproc_exited, 0);
2349 +}
2352 +#if 0 /* should put this into /proc or something */
2353 +static void
2354 +db_show_drivers(void)
2355 +{
2356 +       int hid;
2358 +       db_printf("%12s %4s %4s %8s %2s %2s\n"
2359 +               , "Device"
2360 +               , "Ses"
2361 +               , "Kops"
2362 +               , "Flags"
2363 +               , "QB"
2364 +               , "KB"
2365 +       );
2366 +       for (hid = 0; hid < crypto_drivers_num; hid++) {
2367 +               const struct cryptocap *cap = &crypto_drivers[hid];
2368 +               if (cap->cc_dev == NULL)
2369 +                       continue;
2370 +               db_printf("%-12s %4u %4u %08x %2u %2u\n"
2371 +                   , device_get_nameunit(cap->cc_dev)
2372 +                   , cap->cc_sessions
2373 +                   , cap->cc_koperations
2374 +                   , cap->cc_flags
2375 +                   , cap->cc_qblocked
2376 +                   , cap->cc_kqblocked
2377 +               );
2378 +       }
2379 +}
2381 +DB_SHOW_COMMAND(crypto, db_show_crypto)
2382 +{
2383 +       struct cryptop *crp;
2385 +       db_show_drivers();
2386 +       db_printf("\n");
2388 +       db_printf("%4s %8s %4s %4s %4s %4s %8s %8s\n",
2389 +           "HID", "Caps", "Ilen", "Olen", "Etype", "Flags",
2390 +           "Desc", "Callback");
2391 +       TAILQ_FOREACH(crp, &crp_q, crp_next) {
2392 +               db_printf("%4u %08x %4u %4u %4u %04x %8p %8p\n"
2393 +                   , (int) CRYPTO_SESID2HID(crp->crp_sid)
2394 +                   , (int) CRYPTO_SESID2CAPS(crp->crp_sid)
2395 +                   , crp->crp_ilen, crp->crp_olen
2396 +                   , crp->crp_etype
2397 +                   , crp->crp_flags
2398 +                   , crp->crp_desc
2399 +                   , crp->crp_callback
2400 +               );
2401 +       }
2402 +       if (!TAILQ_EMPTY(&crp_ret_q)) {
2403 +               db_printf("\n%4s %4s %4s %8s\n",
2404 +                   "HID", "Etype", "Flags", "Callback");
2405 +               TAILQ_FOREACH(crp, &crp_ret_q, crp_next) {
2406 +                       db_printf("%4u %4u %04x %8p\n"
2407 +                           , (int) CRYPTO_SESID2HID(crp->crp_sid)
2408 +                           , crp->crp_etype
2409 +                           , crp->crp_flags
2410 +                           , crp->crp_callback
2411 +                       );
2412 +               }
2413 +       }
2414 +}
2416 +DB_SHOW_COMMAND(kcrypto, db_show_kcrypto)
2417 +{
2418 +       struct cryptkop *krp;
2420 +       db_show_drivers();
2421 +       db_printf("\n");
2423 +       db_printf("%4s %5s %4s %4s %8s %4s %8s\n",
2424 +           "Op", "Status", "#IP", "#OP", "CRID", "HID", "Callback");
2425 +       TAILQ_FOREACH(krp, &crp_kq, krp_next) {
2426 +               db_printf("%4u %5u %4u %4u %08x %4u %8p\n"
2427 +                   , krp->krp_op
2428 +                   , krp->krp_status
2429 +                   , krp->krp_iparams, krp->krp_oparams
2430 +                   , krp->krp_crid, krp->krp_hid
2431 +                   , krp->krp_callback
2432 +               );
2433 +       }
2434 +       if (!TAILQ_EMPTY(&crp_ret_q)) {
2435 +               db_printf("%4s %5s %8s %4s %8s\n",
2436 +                   "Op", "Status", "CRID", "HID", "Callback");
2437 +               TAILQ_FOREACH(krp, &crp_ret_kq, krp_next) {
2438 +                       db_printf("%4u %5u %08x %4u %8p\n"
2439 +                           , krp->krp_op
2440 +                           , krp->krp_status
2441 +                           , krp->krp_crid, krp->krp_hid
2442 +                           , krp->krp_callback
2443 +                       );
2444 +               }
2445 +       }
2446 +}
2447 +#endif
2450 +static int
2451 +crypto_init(void)
2452 +{
2453 +       int error;
2455 +       dprintk("%s(%p)\n", __FUNCTION__, (void *) crypto_init);
2457 +       if (crypto_initted)
2458 +               return 0;
2459 +       crypto_initted = 1;
2461 +       spin_lock_init(&crypto_drivers_lock);
2462 +       spin_lock_init(&crypto_q_lock);
2463 +       spin_lock_init(&crypto_ret_q_lock);
2465 +       cryptop_zone = kmem_cache_create("cryptop", sizeof(struct cryptop),
2466 +                                      0, SLAB_HWCACHE_ALIGN, NULL
2467 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
2468 +                                      , NULL
2469 +#endif
2470 +                                       );
2472 +       cryptodesc_zone = kmem_cache_create("cryptodesc", sizeof(struct cryptodesc),
2473 +                                      0, SLAB_HWCACHE_ALIGN, NULL
2474 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
2475 +                                      , NULL
2476 +#endif
2477 +                                       );
2479 +       if (cryptodesc_zone == NULL || cryptop_zone == NULL) {
2480 +               printk("crypto: crypto_init cannot setup crypto zones\n");
2481 +               error = ENOMEM;
2482 +               goto bad;
2483 +       }
2485 +       crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
2486 +       crypto_drivers = kmalloc(crypto_drivers_num * sizeof(struct cryptocap),
2487 +                       GFP_KERNEL);
2488 +       if (crypto_drivers == NULL) {
2489 +               printk("crypto: crypto_init cannot setup crypto drivers\n");
2490 +               error = ENOMEM;
2491 +               goto bad;
2492 +       }
2494 +       memset(crypto_drivers, 0, crypto_drivers_num * sizeof(struct cryptocap));
2496 +       init_completion(&cryptoproc_exited);
2497 +       init_completion(&cryptoretproc_exited);
2499 +       cryptoproc = 0; /* to avoid race condition where proc runs first */
2500 +       cryptoproc = kernel_thread(crypto_proc, NULL, CLONE_FS|CLONE_FILES);
2501 +       if (cryptoproc < 0) {
2502 +               error = cryptoproc;
2503 +               printk("crypto: crypto_init cannot start crypto thread; error %d",
2504 +                       error);
2505 +               goto bad;
2506 +       }
2508 +       cryptoretproc = 0; /* to avoid race condition where proc runs first */
2509 +       cryptoretproc = kernel_thread(crypto_ret_proc, NULL, CLONE_FS|CLONE_FILES);
2510 +       if (cryptoretproc < 0) {
2511 +               error = cryptoretproc;
2512 +               printk("crypto: crypto_init cannot start cryptoret thread; error %d",
2513 +                               error);
2514 +               goto bad;
2515 +       }
2517 +       return 0;
2518 +bad:
2519 +       crypto_exit();
2520 +       return error;
2521 +}
2524 +static void
2525 +crypto_exit(void)
2526 +{
2527 +       pid_t p;
2528 +       unsigned long d_flags;
2530 +       dprintk("%s()\n", __FUNCTION__);
2532 +       /*
2533 +        * Terminate any crypto threads.
2534 +        */
2536 +       CRYPTO_DRIVER_LOCK();
2537 +       p = cryptoproc;
2538 +       cryptoproc = (pid_t) -1;
2539 +       kill_proc(p, SIGTERM, 1);
2540 +       wake_up_interruptible(&cryptoproc_wait);
2541 +       CRYPTO_DRIVER_UNLOCK();
2543 +       wait_for_completion(&cryptoproc_exited);
2545 +       CRYPTO_DRIVER_LOCK();
2546 +       p = cryptoretproc;
2547 +       cryptoretproc = (pid_t) -1;
2548 +       kill_proc(p, SIGTERM, 1);
2549 +       wake_up_interruptible(&cryptoretproc_wait);
2550 +       CRYPTO_DRIVER_UNLOCK();
2552 +       wait_for_completion(&cryptoretproc_exited);
2554 +       /* XXX flush queues??? */
2556 +       /* 
2557 +        * Reclaim dynamically allocated resources.
2558 +        */
2559 +       if (crypto_drivers != NULL)
2560 +               kfree(crypto_drivers);
2562 +       if (cryptodesc_zone != NULL)
2563 +               kmem_cache_destroy(cryptodesc_zone);
2564 +       if (cryptop_zone != NULL)
2565 +               kmem_cache_destroy(cryptop_zone);
2566 +}
2569 +EXPORT_SYMBOL(crypto_newsession);
2570 +EXPORT_SYMBOL(crypto_freesession);
2571 +EXPORT_SYMBOL(crypto_get_driverid);
2572 +EXPORT_SYMBOL(crypto_kregister);
2573 +EXPORT_SYMBOL(crypto_register);
2574 +EXPORT_SYMBOL(crypto_unregister);
2575 +EXPORT_SYMBOL(crypto_unregister_all);
2576 +EXPORT_SYMBOL(crypto_unblock);
2577 +EXPORT_SYMBOL(crypto_dispatch);
2578 +EXPORT_SYMBOL(crypto_kdispatch);
2579 +EXPORT_SYMBOL(crypto_freereq);
2580 +EXPORT_SYMBOL(crypto_getreq);
2581 +EXPORT_SYMBOL(crypto_done);
2582 +EXPORT_SYMBOL(crypto_kdone);
2583 +EXPORT_SYMBOL(crypto_getfeat);
2584 +EXPORT_SYMBOL(crypto_userasymcrypto);
2585 +EXPORT_SYMBOL(crypto_getcaps);
2586 +EXPORT_SYMBOL(crypto_find_driver);
2587 +EXPORT_SYMBOL(crypto_find_device_byhid);
2589 +module_init(crypto_init);
2590 +module_exit(crypto_exit);
2592 +MODULE_LICENSE("BSD");
2593 +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
2594 +MODULE_DESCRIPTION("OCF (OpenBSD Cryptographic Framework)");
2595 diff --git a/crypto/ocf/cryptodev.c b/crypto/ocf/cryptodev.c
2596 new file mode 100644
2597 index 0000000..badf802
2598 --- /dev/null
2599 +++ b/crypto/ocf/cryptodev.c
2600 @@ -0,0 +1,1063 @@
2601 +/*     $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $  */
2603 +/*-
2604 + * Linux port done by David McCullough <david_mccullough@mcafee.com>
2605 + * Copyright (C) 2006-2010 David McCullough
2606 + * Copyright (C) 2004-2005 Intel Corporation.
2607 + * The license and original author are listed below.
2608 + *
2609 + * Copyright (c) 2001 Theo de Raadt
2610 + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
2611 + *
2612 + * Redistribution and use in source and binary forms, with or without
2613 + * modification, are permitted provided that the following conditions
2614 + * are met:
2615 + *
2616 + * 1. Redistributions of source code must retain the above copyright
2617 + *   notice, this list of conditions and the following disclaimer.
2618 + * 2. Redistributions in binary form must reproduce the above copyright
2619 + *   notice, this list of conditions and the following disclaimer in the
2620 + *   documentation and/or other materials provided with the distribution.
2621 + * 3. The name of the author may not be used to endorse or promote products
2622 + *   derived from this software without specific prior written permission.
2623 + *
2624 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2625 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2626 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2627 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2628 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2629 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2630 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2631 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2632 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2633 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2634 + *
2635 + * Effort sponsored in part by the Defense Advanced Research Projects
2636 + * Agency (DARPA) and Air Force Research Laboratory, Air Force
2637 + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
2638 + *
2639 +__FBSDID("$FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.34 2007/05/09 19:37:02 gnn Exp $");
2640 + */
2642 +#ifndef AUTOCONF_INCLUDED
2643 +#include <linux/config.h>
2644 +#endif
2645 +#include <linux/types.h>
2646 +#include <linux/time.h>
2647 +#include <linux/delay.h>
2648 +#include <linux/list.h>
2649 +#include <linux/init.h>
2650 +#include <linux/sched.h>
2651 +#include <linux/unistd.h>
2652 +#include <linux/module.h>
2653 +#include <linux/wait.h>
2654 +#include <linux/slab.h>
2655 +#include <linux/fs.h>
2656 +#include <linux/dcache.h>
2657 +#include <linux/file.h>
2658 +#include <linux/mount.h>
2659 +#include <linux/miscdevice.h>
2660 +#include <linux/version.h>
2661 +#include <asm/uaccess.h>
2663 +#include <crypto/cryptodev.h>
2664 +#include <uio.h>
2666 +extern asmlinkage long sys_dup(unsigned int fildes);
2668 +#define debug cryptodev_debug
2669 +int cryptodev_debug = 0;
2670 +module_param(cryptodev_debug, int, 0644);
2671 +MODULE_PARM_DESC(cryptodev_debug, "Enable cryptodev debug");
2673 +struct csession_info {
2674 +       u_int16_t       blocksize;
2675 +       u_int16_t       minkey, maxkey;
2677 +       u_int16_t       keysize;
2678 +       /* u_int16_t    hashsize;  */
2679 +       u_int16_t       authsize;
2680 +       u_int16_t       authkey;
2681 +       /* u_int16_t    ctxsize; */
2682 +};
2684 +struct csession {
2685 +       struct list_head        list;
2686 +       u_int64_t       sid;
2687 +       u_int32_t       ses;
2689 +       wait_queue_head_t waitq;
2691 +       u_int32_t       cipher;
2693 +       u_int32_t       mac;
2695 +       caddr_t         key;
2696 +       int             keylen;
2697 +       u_char          tmp_iv[EALG_MAX_BLOCK_LEN];
2699 +       caddr_t         mackey;
2700 +       int             mackeylen;
2702 +       struct csession_info info;
2704 +       struct iovec    iovec;
2705 +       struct uio      uio;
2706 +       int             error;
2707 +};
2709 +struct fcrypt {
2710 +       struct list_head        csessions;
2711 +       int             sesn;
2712 +};
2714 +static struct csession *csefind(struct fcrypt *, u_int);
2715 +static int csedelete(struct fcrypt *, struct csession *);
2716 +static struct csession *cseadd(struct fcrypt *, struct csession *);
2717 +static struct csession *csecreate(struct fcrypt *, u_int64_t,
2718 +               struct cryptoini *crie, struct cryptoini *cria, struct csession_info *);
2719 +static int csefree(struct csession *);
2721 +static int cryptodev_op(struct csession *, struct crypt_op *);
2722 +static int cryptodev_key(struct crypt_kop *);
2723 +static int cryptodev_find(struct crypt_find_op *);
2725 +static int cryptodev_cb(void *);
2726 +static int cryptodev_open(struct inode *inode, struct file *filp);
2728 +/*
2729 + * Check a crypto identifier to see if it requested
2730 + * a valid crid and it's capabilities match.
2731 + */
2732 +static int
2733 +checkcrid(int crid)
2734 +{
2735 +       int hid = crid & ~(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
2736 +       int typ = crid & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
2737 +       int caps = 0;
2738 +       
2739 +       /* if the user hasn't selected a driver, then just call newsession */
2740 +       if (hid == 0 && typ != 0)
2741 +               return 0;
2743 +       caps = crypto_getcaps(hid);
2745 +       /* didn't find anything with capabilities */
2746 +       if (caps == 0) {
2747 +               dprintk("%s: hid=%x typ=%x not matched\n", __FUNCTION__, hid, typ);
2748 +               return EINVAL;
2749 +       }
2750 +       
2751 +       /* the user didn't specify SW or HW, so the driver is ok */
2752 +       if (typ == 0)
2753 +               return 0;
2755 +       /* if the type specified didn't match */
2756 +       if (typ != (caps & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE))) {
2757 +               dprintk("%s: hid=%x typ=%x caps=%x not matched\n", __FUNCTION__,
2758 +                               hid, typ, caps);
2759 +               return EINVAL;
2760 +       }
2762 +       return 0;
2763 +}
2765 +static int
2766 +cryptodev_op(struct csession *cse, struct crypt_op *cop)
2767 +{
2768 +       struct cryptop *crp = NULL;
2769 +       struct cryptodesc *crde = NULL, *crda = NULL;
2770 +       int error = 0;
2772 +       dprintk("%s()\n", __FUNCTION__);
2773 +       if (cop->len > CRYPTO_MAX_DATA_LEN) {
2774 +               dprintk("%s: %d > %d\n", __FUNCTION__, cop->len, CRYPTO_MAX_DATA_LEN);
2775 +               return (E2BIG);
2776 +       }
2778 +       if (cse->info.blocksize && (cop->len % cse->info.blocksize) != 0) {
2779 +               dprintk("%s: blocksize=%d len=%d\n", __FUNCTION__, cse->info.blocksize,
2780 +                               cop->len);
2781 +               return (EINVAL);
2782 +       }
2784 +       cse->uio.uio_iov = &cse->iovec;
2785 +       cse->uio.uio_iovcnt = 1;
2786 +       cse->uio.uio_offset = 0;
2787 +#if 0
2788 +       cse->uio.uio_resid = cop->len;
2789 +       cse->uio.uio_segflg = UIO_SYSSPACE;
2790 +       cse->uio.uio_rw = UIO_WRITE;
2791 +       cse->uio.uio_td = td;
2792 +#endif
2793 +       cse->uio.uio_iov[0].iov_len = cop->len;
2794 +       if (cse->info.authsize)
2795 +               cse->uio.uio_iov[0].iov_len += cse->info.authsize;
2796 +       cse->uio.uio_iov[0].iov_base = kmalloc(cse->uio.uio_iov[0].iov_len,
2797 +                       GFP_KERNEL);
2799 +       if (cse->uio.uio_iov[0].iov_base == NULL) {
2800 +               dprintk("%s: iov_base kmalloc(%d) failed\n", __FUNCTION__,
2801 +                               (int)cse->uio.uio_iov[0].iov_len);
2802 +               return (ENOMEM);
2803 +       }
2805 +       crp = crypto_getreq((cse->info.blocksize != 0) + (cse->info.authsize != 0));
2806 +       if (crp == NULL) {
2807 +               dprintk("%s: ENOMEM\n", __FUNCTION__);
2808 +               error = ENOMEM;
2809 +               goto bail;
2810 +       }
2812 +       if (cse->info.authsize && cse->info.blocksize) {
2813 +               if (cop->op == COP_ENCRYPT) {
2814 +                       crde = crp->crp_desc;
2815 +                       crda = crde->crd_next;
2816 +               } else {
2817 +                       crda = crp->crp_desc;
2818 +                       crde = crda->crd_next;
2819 +               }
2820 +       } else if (cse->info.authsize) {
2821 +               crda = crp->crp_desc;
2822 +       } else if (cse->info.blocksize) {
2823 +               crde = crp->crp_desc;
2824 +       } else {
2825 +               dprintk("%s: bad request\n", __FUNCTION__);
2826 +               error = EINVAL;
2827 +               goto bail;
2828 +       }
2830 +       if ((error = copy_from_user(cse->uio.uio_iov[0].iov_base, cop->src,
2831 +                                       cop->len))) {
2832 +               dprintk("%s: bad copy\n", __FUNCTION__);
2833 +               goto bail;
2834 +       }
2836 +       if (crda) {
2837 +               crda->crd_skip = 0;
2838 +               crda->crd_len = cop->len;
2839 +               crda->crd_inject = cop->len;
2841 +               crda->crd_alg = cse->mac;
2842 +               crda->crd_key = cse->mackey;
2843 +               crda->crd_klen = cse->mackeylen * 8;
2844 +       }
2846 +       if (crde) {
2847 +               if (cop->op == COP_ENCRYPT)
2848 +                       crde->crd_flags |= CRD_F_ENCRYPT;
2849 +               else
2850 +                       crde->crd_flags &= ~CRD_F_ENCRYPT;
2851 +               crde->crd_len = cop->len;
2852 +               crde->crd_inject = 0;
2854 +               crde->crd_alg = cse->cipher;
2855 +               crde->crd_key = cse->key;
2856 +               crde->crd_klen = cse->keylen * 8;
2857 +       }
2859 +       crp->crp_ilen = cse->uio.uio_iov[0].iov_len;
2860 +       crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
2861 +                      | (cop->flags & COP_F_BATCH);
2862 +       crp->crp_buf = (caddr_t)&cse->uio;
2863 +       crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb;
2864 +       crp->crp_sid = cse->sid;
2865 +       crp->crp_opaque = (void *)cse;
2867 +       if (cop->iv) {
2868 +               if (crde == NULL) {
2869 +                       error = EINVAL;
2870 +                       dprintk("%s no crde\n", __FUNCTION__);
2871 +                       goto bail;
2872 +               }
2873 +               if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
2874 +                       error = EINVAL;
2875 +                       dprintk("%s arc4 with IV\n", __FUNCTION__);
2876 +                       goto bail;
2877 +               }
2878 +               if ((error = copy_from_user(cse->tmp_iv, cop->iv,
2879 +                                               cse->info.blocksize))) {
2880 +                       dprintk("%s bad iv copy\n", __FUNCTION__);
2881 +                       goto bail;
2882 +               }
2883 +               memcpy(crde->crd_iv, cse->tmp_iv, cse->info.blocksize);
2884 +               crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
2885 +               crde->crd_skip = 0;
2886 +       } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
2887 +               crde->crd_skip = 0;
2888 +       } else if (crde) {
2889 +               crde->crd_flags |= CRD_F_IV_PRESENT;
2890 +               crde->crd_skip = cse->info.blocksize;
2891 +               crde->crd_len -= cse->info.blocksize;
2892 +       }
2894 +       if (cop->mac && crda == NULL) {
2895 +               error = EINVAL;
2896 +               dprintk("%s no crda\n", __FUNCTION__);
2897 +               goto bail;
2898 +       }
2900 +       /*
2901 +        * Let the dispatch run unlocked, then, interlock against the
2902 +        * callback before checking if the operation completed and going
2903 +        * to sleep.  This insures drivers don't inherit our lock which
2904 +        * results in a lock order reversal between crypto_dispatch forced
2905 +        * entry and the crypto_done callback into us.
2906 +        */
2907 +       error = crypto_dispatch(crp);
2908 +       if (error) {
2909 +               dprintk("%s error in crypto_dispatch\n", __FUNCTION__);
2910 +               goto bail;
2911 +       }
2913 +       dprintk("%s about to WAIT\n", __FUNCTION__);
2914 +       /*
2915 +        * we really need to wait for driver to complete to maintain
2916 +        * state,  luckily interrupts will be remembered
2917 +        */
2918 +       do {
2919 +               error = wait_event_interruptible(crp->crp_waitq,
2920 +                               ((crp->crp_flags & CRYPTO_F_DONE) != 0));
2921 +               /*
2922 +                * we can't break out of this loop or we will leave behind
2923 +                * a huge mess,  however,  staying here means if your driver
2924 +                * is broken user applications can hang and not be killed.
2925 +                * The solution,  fix your driver :-)
2926 +                */
2927 +               if (error) {
2928 +                       schedule();
2929 +                       error = 0;
2930 +               }
2931 +       } while ((crp->crp_flags & CRYPTO_F_DONE) == 0);
2932 +       dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
2934 +       if (crp->crp_etype != 0) {
2935 +               error = crp->crp_etype;
2936 +               dprintk("%s error in crp processing\n", __FUNCTION__);
2937 +               goto bail;
2938 +       }
2940 +       if (cse->error) {
2941 +               error = cse->error;
2942 +               dprintk("%s error in cse processing\n", __FUNCTION__);
2943 +               goto bail;
2944 +       }
2946 +       if (cop->dst && (error = copy_to_user(cop->dst,
2947 +                                       cse->uio.uio_iov[0].iov_base, cop->len))) {
2948 +               dprintk("%s bad dst copy\n", __FUNCTION__);
2949 +               goto bail;
2950 +       }
2952 +       if (cop->mac &&
2953 +                       (error=copy_to_user(cop->mac,
2954 +                               (caddr_t)cse->uio.uio_iov[0].iov_base + cop->len,
2955 +                               cse->info.authsize))) {
2956 +               dprintk("%s bad mac copy\n", __FUNCTION__);
2957 +               goto bail;
2958 +       }
2960 +bail:
2961 +       if (crp)
2962 +               crypto_freereq(crp);
2963 +       if (cse->uio.uio_iov[0].iov_base)
2964 +               kfree(cse->uio.uio_iov[0].iov_base);
2966 +       return (error);
2967 +}
2969 +static int
2970 +cryptodev_cb(void *op)
2971 +{
2972 +       struct cryptop *crp = (struct cryptop *) op;
2973 +       struct csession *cse = (struct csession *)crp->crp_opaque;
2974 +       int error;
2976 +       dprintk("%s()\n", __FUNCTION__);
2977 +       error = crp->crp_etype;
2978 +       if (error == EAGAIN) {
2979 +               crp->crp_flags &= ~CRYPTO_F_DONE;
2980 +#ifdef NOTYET
2981 +               /*
2982 +                * DAVIDM I am fairly sure that we should turn this into a batch
2983 +                * request to stop bad karma/lockup, revisit
2984 +                */
2985 +               crp->crp_flags |= CRYPTO_F_BATCH;
2986 +#endif
2987 +               return crypto_dispatch(crp);
2988 +       }
2989 +       if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {
2990 +               cse->error = error;
2991 +               wake_up_interruptible(&crp->crp_waitq);
2992 +       }
2993 +       return (0);
2994 +}
2996 +static int
2997 +cryptodevkey_cb(void *op)
2998 +{
2999 +       struct cryptkop *krp = (struct cryptkop *) op;
3000 +       dprintk("%s()\n", __FUNCTION__);
3001 +       wake_up_interruptible(&krp->krp_waitq);
3002 +       return (0);
3003 +}
3005 +static int
3006 +cryptodev_key(struct crypt_kop *kop)
3007 +{
3008 +       struct cryptkop *krp = NULL;
3009 +       int error = EINVAL;
3010 +       int in, out, size, i;
3012 +       dprintk("%s()\n", __FUNCTION__);
3013 +       if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
3014 +               dprintk("%s params too big\n", __FUNCTION__);
3015 +               return (EFBIG);
3016 +       }
3018 +       in = kop->crk_iparams;
3019 +       out = kop->crk_oparams;
3020 +       switch (kop->crk_op) {
3021 +       case CRK_MOD_EXP:
3022 +               if (in == 3 && out == 1)
3023 +                       break;
3024 +               return (EINVAL);
3025 +       case CRK_MOD_EXP_CRT:
3026 +               if (in == 6 && out == 1)
3027 +                       break;
3028 +               return (EINVAL);
3029 +       case CRK_DSA_SIGN:
3030 +               if (in == 5 && out == 2)
3031 +                       break;
3032 +               return (EINVAL);
3033 +       case CRK_DSA_VERIFY:
3034 +               if (in == 7 && out == 0)
3035 +                       break;
3036 +               return (EINVAL);
3037 +       case CRK_DH_COMPUTE_KEY:
3038 +               if (in == 3 && out == 1)
3039 +                       break;
3040 +               return (EINVAL);
3041 +       default:
3042 +               return (EINVAL);
3043 +       }
3045 +       krp = (struct cryptkop *)kmalloc(sizeof *krp, GFP_KERNEL);
3046 +       if (!krp)
3047 +               return (ENOMEM);
3048 +       bzero(krp, sizeof *krp);
3049 +       krp->krp_op = kop->crk_op;
3050 +       krp->krp_status = kop->crk_status;
3051 +       krp->krp_iparams = kop->crk_iparams;
3052 +       krp->krp_oparams = kop->crk_oparams;
3053 +       krp->krp_crid = kop->crk_crid;
3054 +       krp->krp_status = 0;
3055 +       krp->krp_flags = CRYPTO_KF_CBIMM;
3056 +       krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
3057 +       init_waitqueue_head(&krp->krp_waitq);
3059 +       for (i = 0; i < CRK_MAXPARAM; i++)
3060 +               krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
3061 +       for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
3062 +               size = (krp->krp_param[i].crp_nbits + 7) / 8;
3063 +               if (size == 0)
3064 +                       continue;
3065 +               krp->krp_param[i].crp_p = (caddr_t) kmalloc(size, GFP_KERNEL);
3066 +               if (i >= krp->krp_iparams)
3067 +                       continue;
3068 +               error = copy_from_user(krp->krp_param[i].crp_p,
3069 +                               kop->crk_param[i].crp_p, size);
3070 +               if (error)
3071 +                       goto fail;
3072 +       }
3074 +       error = crypto_kdispatch(krp);
3075 +       if (error)
3076 +               goto fail;
3078 +       do {
3079 +               error = wait_event_interruptible(krp->krp_waitq,
3080 +                               ((krp->krp_flags & CRYPTO_KF_DONE) != 0));
3081 +               /*
3082 +                * we can't break out of this loop or we will leave behind
3083 +                * a huge mess,  however,  staying here means if your driver
3084 +                * is broken user applications can hang and not be killed.
3085 +                * The solution,  fix your driver :-)
3086 +                */
3087 +               if (error) {
3088 +                       schedule();
3089 +                       error = 0;
3090 +               }
3091 +       } while ((krp->krp_flags & CRYPTO_KF_DONE) == 0);
3093 +       dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
3094 +       
3095 +       kop->crk_crid = krp->krp_crid;          /* device that did the work */
3096 +       if (krp->krp_status != 0) {
3097 +               error = krp->krp_status;
3098 +               goto fail;
3099 +       }
3101 +       for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
3102 +               size = (krp->krp_param[i].crp_nbits + 7) / 8;
3103 +               if (size == 0)
3104 +                       continue;
3105 +               error = copy_to_user(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p,
3106 +                               size);
3107 +               if (error)
3108 +                       goto fail;
3109 +       }
3111 +fail:
3112 +       if (krp) {
3113 +               kop->crk_status = krp->krp_status;
3114 +               for (i = 0; i < CRK_MAXPARAM; i++) {
3115 +                       if (krp->krp_param[i].crp_p)
3116 +                               kfree(krp->krp_param[i].crp_p);
3117 +               }
3118 +               kfree(krp);
3119 +       }
3120 +       return (error);
3121 +}
3123 +static int
3124 +cryptodev_find(struct crypt_find_op *find)
3125 +{
3126 +       device_t dev;
3128 +       if (find->crid != -1) {
3129 +               dev = crypto_find_device_byhid(find->crid);
3130 +               if (dev == NULL)
3131 +                       return (ENOENT);
3132 +               strlcpy(find->name, device_get_nameunit(dev),
3133 +                   sizeof(find->name));
3134 +       } else {
3135 +               find->crid = crypto_find_driver(find->name);
3136 +               if (find->crid == -1)
3137 +                       return (ENOENT);
3138 +       }
3139 +       return (0);
3140 +}
3142 +static struct csession *
3143 +csefind(struct fcrypt *fcr, u_int ses)
3144 +{
3145 +       struct csession *cse;
3147 +       dprintk("%s()\n", __FUNCTION__);
3148 +       list_for_each_entry(cse, &fcr->csessions, list)
3149 +               if (cse->ses == ses)
3150 +                       return (cse);
3151 +       return (NULL);
3152 +}
3154 +static int
3155 +csedelete(struct fcrypt *fcr, struct csession *cse_del)
3156 +{
3157 +       struct csession *cse;
3159 +       dprintk("%s()\n", __FUNCTION__);
3160 +       list_for_each_entry(cse, &fcr->csessions, list) {
3161 +               if (cse == cse_del) {
3162 +                       list_del(&cse->list);
3163 +                       return (1);
3164 +               }
3165 +       }
3166 +       return (0);
3167 +}
3168 +       
3169 +static struct csession *
3170 +cseadd(struct fcrypt *fcr, struct csession *cse)
3171 +{
3172 +       dprintk("%s()\n", __FUNCTION__);
3173 +       list_add_tail(&cse->list, &fcr->csessions);
3174 +       cse->ses = fcr->sesn++;
3175 +       return (cse);
3176 +}
3178 +static struct csession *
3179 +csecreate(struct fcrypt *fcr, u_int64_t sid, struct cryptoini *crie,
3180 +       struct cryptoini *cria, struct csession_info *info)
3181 +{
3182 +       struct csession *cse;
3184 +       dprintk("%s()\n", __FUNCTION__);
3185 +       cse = (struct csession *) kmalloc(sizeof(struct csession), GFP_KERNEL);
3186 +       if (cse == NULL)
3187 +               return NULL;
3188 +       memset(cse, 0, sizeof(struct csession));
3190 +       INIT_LIST_HEAD(&cse->list);
3191 +       init_waitqueue_head(&cse->waitq);
3193 +       cse->key = crie->cri_key;
3194 +       cse->keylen = crie->cri_klen/8;
3195 +       cse->mackey = cria->cri_key;
3196 +       cse->mackeylen = cria->cri_klen/8;
3197 +       cse->sid = sid;
3198 +       cse->cipher = crie->cri_alg;
3199 +       cse->mac = cria->cri_alg;
3200 +       cse->info = *info;
3201 +       cseadd(fcr, cse);
3202 +       return (cse);
3203 +}
3205 +static int
3206 +csefree(struct csession *cse)
3207 +{
3208 +       int error;
3210 +       dprintk("%s()\n", __FUNCTION__);
3211 +       error = crypto_freesession(cse->sid);
3212 +       if (cse->key)
3213 +               kfree(cse->key);
3214 +       if (cse->mackey)
3215 +               kfree(cse->mackey);
3216 +       kfree(cse);
3217 +       return(error);
3218 +}
3220 +static int
3221 +cryptodev_ioctl(
3222 +       struct inode *inode,
3223 +       struct file *filp,
3224 +       unsigned int cmd,
3225 +       unsigned long arg)
3226 +{
3227 +       struct cryptoini cria, crie;
3228 +       struct fcrypt *fcr = filp->private_data;
3229 +       struct csession *cse;
3230 +       struct csession_info info;
3231 +       struct session2_op sop;
3232 +       struct crypt_op cop;
3233 +       struct crypt_kop kop;
3234 +       struct crypt_find_op fop;
3235 +       u_int64_t sid;
3236 +       u_int32_t ses = 0;
3237 +       int feat, fd, error = 0, crid;
3238 +       mm_segment_t fs;
3240 +       dprintk("%s(cmd=%x arg=%lx)\n", __FUNCTION__, cmd, arg);
3242 +       switch (cmd) {
3244 +       case CRIOGET: {
3245 +               dprintk("%s(CRIOGET)\n", __FUNCTION__);
3246 +               fs = get_fs();
3247 +               set_fs(get_ds());
3248 +               for (fd = 0; fd < files_fdtable(current->files)->max_fds; fd++)
3249 +                       if (files_fdtable(current->files)->fd[fd] == filp)
3250 +                               break;
3251 +               fd = sys_dup(fd);
3252 +               set_fs(fs);
3253 +               put_user(fd, (int *) arg);
3254 +               return IS_ERR_VALUE(fd) ? fd : 0;
3255 +               }
3257 +#define        CIOCGSESSSTR    (cmd == CIOCGSESSION ? "CIOCGSESSION" : "CIOCGSESSION2")
3258 +       case CIOCGSESSION:
3259 +       case CIOCGSESSION2:
3260 +               dprintk("%s(%s)\n", __FUNCTION__, CIOCGSESSSTR);
3261 +               memset(&crie, 0, sizeof(crie));
3262 +               memset(&cria, 0, sizeof(cria));
3263 +               memset(&info, 0, sizeof(info));
3264 +               memset(&sop, 0, sizeof(sop));
3266 +               if (copy_from_user(&sop, (void*)arg, (cmd == CIOCGSESSION) ?
3267 +                                       sizeof(struct session_op) : sizeof(sop))) {
3268 +                       dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
3269 +                       error = EFAULT;
3270 +                       goto bail;
3271 +               }
3273 +               switch (sop.cipher) {
3274 +               case 0:
3275 +                       dprintk("%s(%s) - no cipher\n", __FUNCTION__, CIOCGSESSSTR);
3276 +                       break;
3277 +               case CRYPTO_NULL_CBC:
3278 +                       info.blocksize = NULL_BLOCK_LEN;
3279 +                       info.minkey = NULL_MIN_KEY_LEN;
3280 +                       info.maxkey = NULL_MAX_KEY_LEN;
3281 +                       break;
3282 +               case CRYPTO_DES_CBC:
3283 +                       info.blocksize = DES_BLOCK_LEN;
3284 +                       info.minkey = DES_MIN_KEY_LEN;
3285 +                       info.maxkey = DES_MAX_KEY_LEN;
3286 +                       break;
3287 +               case CRYPTO_3DES_CBC:
3288 +                       info.blocksize = DES3_BLOCK_LEN;
3289 +                       info.minkey = DES3_MIN_KEY_LEN;
3290 +                       info.maxkey = DES3_MAX_KEY_LEN;
3291 +                       break;
3292 +               case CRYPTO_BLF_CBC:
3293 +                       info.blocksize = BLOWFISH_BLOCK_LEN;
3294 +                       info.minkey = BLOWFISH_MIN_KEY_LEN;
3295 +                       info.maxkey = BLOWFISH_MAX_KEY_LEN;
3296 +                       break;
3297 +               case CRYPTO_CAST_CBC:
3298 +                       info.blocksize = CAST128_BLOCK_LEN;
3299 +                       info.minkey = CAST128_MIN_KEY_LEN;
3300 +                       info.maxkey = CAST128_MAX_KEY_LEN;
3301 +                       break;
3302 +               case CRYPTO_SKIPJACK_CBC:
3303 +                       info.blocksize = SKIPJACK_BLOCK_LEN;
3304 +                       info.minkey = SKIPJACK_MIN_KEY_LEN;
3305 +                       info.maxkey = SKIPJACK_MAX_KEY_LEN;
3306 +                       break;
3307 +               case CRYPTO_AES_CBC:
3308 +                       info.blocksize = AES_BLOCK_LEN;
3309 +                       info.minkey = AES_MIN_KEY_LEN;
3310 +                       info.maxkey = AES_MAX_KEY_LEN;
3311 +                       break;
3312 +               case CRYPTO_ARC4:
3313 +                       info.blocksize = ARC4_BLOCK_LEN;
3314 +                       info.minkey = ARC4_MIN_KEY_LEN;
3315 +                       info.maxkey = ARC4_MAX_KEY_LEN;
3316 +                       break;
3317 +               case CRYPTO_CAMELLIA_CBC:
3318 +                       info.blocksize = CAMELLIA_BLOCK_LEN;
3319 +                       info.minkey = CAMELLIA_MIN_KEY_LEN;
3320 +                       info.maxkey = CAMELLIA_MAX_KEY_LEN;
3321 +                       break;
3322 +               default:
3323 +                       dprintk("%s(%s) - bad cipher\n", __FUNCTION__, CIOCGSESSSTR);
3324 +                       error = EINVAL;
3325 +                       goto bail;
3326 +               }
3328 +               switch (sop.mac) {
3329 +               case 0:
3330 +                       dprintk("%s(%s) - no mac\n", __FUNCTION__, CIOCGSESSSTR);
3331 +                       break;
3332 +               case CRYPTO_NULL_HMAC:
3333 +                       info.authsize = NULL_HASH_LEN;
3334 +                       break;
3335 +               case CRYPTO_MD5:
3336 +                       info.authsize = MD5_HASH_LEN;
3337 +                       break;
3338 +               case CRYPTO_SHA1:
3339 +                       info.authsize = SHA1_HASH_LEN;
3340 +                       break;
3341 +               case CRYPTO_SHA2_256:
3342 +                       info.authsize = SHA2_256_HASH_LEN;
3343 +                       break;
3344 +               case CRYPTO_SHA2_384:
3345 +                       info.authsize = SHA2_384_HASH_LEN;
3346 +                       break;
3347 +               case CRYPTO_SHA2_512:
3348 +                       info.authsize = SHA2_512_HASH_LEN;
3349 +                       break;
3350 +               case CRYPTO_RIPEMD160:
3351 +                       info.authsize = RIPEMD160_HASH_LEN;
3352 +                       break;
3353 +               case CRYPTO_MD5_HMAC:
3354 +                       info.authsize = MD5_HASH_LEN;
3355 +                       info.authkey = 16;
3356 +                       break;
3357 +               case CRYPTO_SHA1_HMAC:
3358 +                       info.authsize = SHA1_HASH_LEN;
3359 +                       info.authkey = 20;
3360 +                       break;
3361 +               case CRYPTO_SHA2_256_HMAC:
3362 +                       info.authsize = SHA2_256_HASH_LEN;
3363 +                       info.authkey = 32;
3364 +                       break;
3365 +               case CRYPTO_SHA2_384_HMAC:
3366 +                       info.authsize = SHA2_384_HASH_LEN;
3367 +                       info.authkey = 48;
3368 +                       break;
3369 +               case CRYPTO_SHA2_512_HMAC:
3370 +                       info.authsize = SHA2_512_HASH_LEN;
3371 +                       info.authkey = 64;
3372 +                       break;
3373 +               case CRYPTO_RIPEMD160_HMAC:
3374 +                       info.authsize = RIPEMD160_HASH_LEN;
3375 +                       info.authkey = 20;
3376 +                       break;
3377 +               default:
3378 +                       dprintk("%s(%s) - bad mac\n", __FUNCTION__, CIOCGSESSSTR);
3379 +                       error = EINVAL;
3380 +                       goto bail;
3381 +               }
3383 +               if (info.blocksize) {
3384 +                       crie.cri_alg = sop.cipher;
3385 +                       crie.cri_klen = sop.keylen * 8;
3386 +                       if ((info.maxkey && sop.keylen > info.maxkey) ||
3387 +                                       sop.keylen < info.minkey) {
3388 +                               dprintk("%s(%s) - bad key\n", __FUNCTION__, CIOCGSESSSTR);
3389 +                               error = EINVAL;
3390 +                               goto bail;
3391 +                       }
3393 +                       crie.cri_key = (u_int8_t *) kmalloc(crie.cri_klen/8+1, GFP_KERNEL);
3394 +                       if (copy_from_user(crie.cri_key, sop.key,
3395 +                                                       crie.cri_klen/8)) {
3396 +                               dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
3397 +                               error = EFAULT;
3398 +                               goto bail;
3399 +                       }
3400 +                       if (info.authsize)
3401 +                               crie.cri_next = &cria;
3402 +               }
3404 +               if (info.authsize) {
3405 +                       cria.cri_alg = sop.mac;
3406 +                       cria.cri_klen = sop.mackeylen * 8;
3407 +                       if (info.authkey && sop.mackeylen != info.authkey) {
3408 +                               dprintk("%s(%s) - mackeylen %d != %d\n", __FUNCTION__,
3409 +                                               CIOCGSESSSTR, sop.mackeylen, info.authkey);
3410 +                               error = EINVAL;
3411 +                               goto bail;
3412 +                       }
3414 +                       if (cria.cri_klen) {
3415 +                               cria.cri_key = (u_int8_t *) kmalloc(cria.cri_klen/8,GFP_KERNEL);
3416 +                               if (copy_from_user(cria.cri_key, sop.mackey,
3417 +                                                               cria.cri_klen / 8)) {
3418 +                                       dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
3419 +                                       error = EFAULT;
3420 +                                       goto bail;
3421 +                               }
3422 +                       }
3423 +               }
3425 +               /* NB: CIOGSESSION2 has the crid */
3426 +               if (cmd == CIOCGSESSION2) {
3427 +                       crid = sop.crid;
3428 +                       error = checkcrid(crid);
3429 +                       if (error) {
3430 +                               dprintk("%s(%s) - checkcrid %x\n", __FUNCTION__,
3431 +                                               CIOCGSESSSTR, error);
3432 +                               goto bail;
3433 +                       }
3434 +               } else {
3435 +                       /* allow either HW or SW to be used */
3436 +                       crid = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
3437 +               }
3438 +               error = crypto_newsession(&sid, (info.blocksize ? &crie : &cria), crid);
3439 +               if (error) {
3440 +                       dprintk("%s(%s) - newsession %d\n",__FUNCTION__,CIOCGSESSSTR,error);
3441 +                       goto bail;
3442 +               }
3444 +               cse = csecreate(fcr, sid, &crie, &cria, &info);
3445 +               if (cse == NULL) {
3446 +                       crypto_freesession(sid);
3447 +                       error = EINVAL;
3448 +                       dprintk("%s(%s) - csecreate failed\n", __FUNCTION__, CIOCGSESSSTR);
3449 +                       goto bail;
3450 +               }
3451 +               sop.ses = cse->ses;
3453 +               if (cmd == CIOCGSESSION2) {
3454 +                       /* return hardware/driver id */
3455 +                       sop.crid = CRYPTO_SESID2HID(cse->sid);
3456 +               }
3458 +               if (copy_to_user((void*)arg, &sop, (cmd == CIOCGSESSION) ?
3459 +                                       sizeof(struct session_op) : sizeof(sop))) {
3460 +                       dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
3461 +                       error = EFAULT;
3462 +               }
3463 +bail:
3464 +               if (error) {
3465 +                       dprintk("%s(%s) - bail %d\n", __FUNCTION__, CIOCGSESSSTR, error);
3466 +                       if (crie.cri_key)
3467 +                               kfree(crie.cri_key);
3468 +                       if (cria.cri_key)
3469 +                               kfree(cria.cri_key);
3470 +               }
3471 +               break;
3472 +       case CIOCFSESSION:
3473 +               dprintk("%s(CIOCFSESSION)\n", __FUNCTION__);
3474 +               get_user(ses, (uint32_t*)arg);
3475 +               cse = csefind(fcr, ses);
3476 +               if (cse == NULL) {
3477 +                       error = EINVAL;
3478 +                       dprintk("%s(CIOCFSESSION) - Fail %d\n", __FUNCTION__, error);
3479 +                       break;
3480 +               }
3481 +               csedelete(fcr, cse);
3482 +               error = csefree(cse);
3483 +               break;
3484 +       case CIOCCRYPT:
3485 +               dprintk("%s(CIOCCRYPT)\n", __FUNCTION__);
3486 +               if(copy_from_user(&cop, (void*)arg, sizeof(cop))) {
3487 +                       dprintk("%s(CIOCCRYPT) - bad copy\n", __FUNCTION__);
3488 +                       error = EFAULT;
3489 +                       goto bail;
3490 +               }
3491 +               cse = csefind(fcr, cop.ses);
3492 +               if (cse == NULL) {
3493 +                       error = EINVAL;
3494 +                       dprintk("%s(CIOCCRYPT) - Fail %d\n", __FUNCTION__, error);
3495 +                       break;
3496 +               }
3497 +               error = cryptodev_op(cse, &cop);
3498 +               if(copy_to_user((void*)arg, &cop, sizeof(cop))) {
3499 +                       dprintk("%s(CIOCCRYPT) - bad return copy\n", __FUNCTION__);
3500 +                       error = EFAULT;
3501 +                       goto bail;
3502 +               }
3503 +               break;
3504 +       case CIOCKEY:
3505 +       case CIOCKEY2:
3506 +               dprintk("%s(CIOCKEY)\n", __FUNCTION__);
3507 +               if (!crypto_userasymcrypto)
3508 +                       return (EPERM);         /* XXX compat? */
3509 +               if(copy_from_user(&kop, (void*)arg, sizeof(kop))) {
3510 +                       dprintk("%s(CIOCKEY) - bad copy\n", __FUNCTION__);
3511 +                       error = EFAULT;
3512 +                       goto bail;
3513 +               }
3514 +               if (cmd == CIOCKEY) {
3515 +                       /* NB: crypto core enforces s/w driver use */
3516 +                       kop.crk_crid =
3517 +                           CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
3518 +               }
3519 +               error = cryptodev_key(&kop);
3520 +               if(copy_to_user((void*)arg, &kop, sizeof(kop))) {
3521 +                       dprintk("%s(CIOCGKEY) - bad return copy\n", __FUNCTION__);
3522 +                       error = EFAULT;
3523 +                       goto bail;
3524 +               }
3525 +               break;
3526 +       case CIOCASYMFEAT:
3527 +               dprintk("%s(CIOCASYMFEAT)\n", __FUNCTION__);
3528 +               if (!crypto_userasymcrypto) {
3529 +                       /*
3530 +                        * NB: if user asym crypto operations are
3531 +                        * not permitted return "no algorithms"
3532 +                        * so well-behaved applications will just
3533 +                        * fallback to doing them in software.
3534 +                        */
3535 +                       feat = 0;
3536 +               } else
3537 +                       error = crypto_getfeat(&feat);
3538 +               if (!error) {
3539 +                 error = copy_to_user((void*)arg, &feat, sizeof(feat));
3540 +               }
3541 +               break;
3542 +       case CIOCFINDDEV:
3543 +               if (copy_from_user(&fop, (void*)arg, sizeof(fop))) {
3544 +                       dprintk("%s(CIOCFINDDEV) - bad copy\n", __FUNCTION__);
3545 +                       error = EFAULT;
3546 +                       goto bail;
3547 +               }
3548 +               error = cryptodev_find(&fop);
3549 +               if (copy_to_user((void*)arg, &fop, sizeof(fop))) {
3550 +                       dprintk("%s(CIOCFINDDEV) - bad return copy\n", __FUNCTION__);
3551 +                       error = EFAULT;
3552 +                       goto bail;
3553 +               }
3554 +               break;
3555 +       default:
3556 +               dprintk("%s(unknown ioctl 0x%x)\n", __FUNCTION__, cmd);
3557 +               error = EINVAL;
3558 +               break;
3559 +       }
3560 +       return(-error);
3561 +}
3563 +#ifdef HAVE_UNLOCKED_IOCTL
3564 +static long
3565 +cryptodev_unlocked_ioctl(
3566 +       struct file *filp,
3567 +       unsigned int cmd,
3568 +       unsigned long arg)
3569 +{
3570 +       return cryptodev_ioctl(NULL, filp, cmd, arg);
3571 +}
3572 +#endif
3574 +static int
3575 +cryptodev_open(struct inode *inode, struct file *filp)
3576 +{
3577 +       struct fcrypt *fcr;
3579 +       dprintk("%s()\n", __FUNCTION__);
3580 +       //if (filp->private_data) {
3581 +       //      printk("cryptodev: Private data already exists !\n");
3582 +       //      return(0);
3583 +       //}
3585 +       fcr = kmalloc(sizeof(*fcr), GFP_KERNEL);
3586 +       if (!fcr) {
3587 +               dprintk("%s() - malloc failed\n", __FUNCTION__);
3588 +               return(-ENOMEM);
3589 +       }
3590 +       memset(fcr, 0, sizeof(*fcr));
3592 +       INIT_LIST_HEAD(&fcr->csessions);
3593 +       filp->private_data = fcr;
3594 +       return(0);
3595 +}
3597 +static int
3598 +cryptodev_release(struct inode *inode, struct file *filp)
3599 +{
3600 +       struct fcrypt *fcr = filp->private_data;
3601 +       struct csession *cse, *tmp;
3603 +       dprintk("%s()\n", __FUNCTION__);
3604 +       if (!filp) {
3605 +               printk("cryptodev: No private data on release\n");
3606 +               return(0);
3607 +       }
3609 +       list_for_each_entry_safe(cse, tmp, &fcr->csessions, list) {
3610 +               list_del(&cse->list);
3611 +               (void)csefree(cse);
3612 +       }
3613 +       filp->private_data = NULL;
3614 +       kfree(fcr);
3615 +       return(0);
3616 +}
3618 +static struct file_operations cryptodev_fops = {
3619 +       .owner = THIS_MODULE,
3620 +       .open = cryptodev_open,
3621 +       .release = cryptodev_release,
3622 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
3623 +       .ioctl = cryptodev_ioctl,
3624 +#endif
3625 +#ifdef HAVE_UNLOCKED_IOCTL
3626 +       .unlocked_ioctl = cryptodev_unlocked_ioctl,
3627 +#endif
3628 +};
3630 +static struct miscdevice cryptodev = {
3631 +       .minor = CRYPTODEV_MINOR,
3632 +       .name = "crypto",
3633 +       .fops = &cryptodev_fops,
3634 +};
3636 +static int __init
3637 +cryptodev_init(void)
3638 +{
3639 +       int rc;
3641 +       dprintk("%s(%p)\n", __FUNCTION__, cryptodev_init);
3642 +       rc = misc_register(&cryptodev);
3643 +       if (rc) {
3644 +               printk(KERN_ERR "cryptodev: registration of /dev/crypto failed\n");
3645 +               return(rc);
3646 +       }
3648 +       return(0);
3649 +}
3651 +static void __exit
3652 +cryptodev_exit(void)
3653 +{
3654 +       dprintk("%s()\n", __FUNCTION__);
3655 +       misc_deregister(&cryptodev);
3656 +}
3658 +module_init(cryptodev_init);
3659 +module_exit(cryptodev_exit);
3661 +MODULE_LICENSE("BSD");
3662 +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
3663 +MODULE_DESCRIPTION("Cryptodev (user interface to OCF)");
3664 diff --git a/crypto/ocf/cryptosoft.c b/crypto/ocf/cryptosoft.c
3665 new file mode 100644
3666 index 0000000..52e1570
3667 --- /dev/null
3668 +++ b/crypto/ocf/cryptosoft.c
3669 @@ -0,0 +1,1210 @@
3670 +/*
3671 + * An OCF module that uses the linux kernel cryptoapi, based on the
3672 + * original cryptosoft for BSD by Angelos D. Keromytis (angelos@cis.upenn.edu)
3673 + * but is mostly unrecognisable,
3674 + *
3675 + * Written by David McCullough <david_mccullough@mcafee.com>
3676 + * Copyright (C) 2004-2010 David McCullough
3677 + * Copyright (C) 2004-2005 Intel Corporation.
3678 + *
3679 + * LICENSE TERMS
3680 + *
3681 + * The free distribution and use of this software in both source and binary
3682 + * form is allowed (with or without changes) provided that:
3683 + *
3684 + *   1. distributions of this source code include the above copyright
3685 + *      notice, this list of conditions and the following disclaimer;
3686 + *
3687 + *   2. distributions in binary form include the above copyright
3688 + *      notice, this list of conditions and the following disclaimer
3689 + *      in the documentation and/or other associated materials;
3690 + *
3691 + *   3. the copyright holder's name is not used to endorse products
3692 + *      built using this software without specific written permission.
3693 + *
3694 + * ALTERNATIVELY, provided that this notice is retained in full, this product
3695 + * may be distributed under the terms of the GNU General Public License (GPL),
3696 + * in which case the provisions of the GPL apply INSTEAD OF those given above.
3697 + *
3698 + * DISCLAIMER
3699 + *
3700 + * This software is provided 'as is' with no explicit or implied warranties
3701 + * in respect of its properties, including, but not limited to, correctness
3702 + * and/or fitness for purpose.
3703 + * ---------------------------------------------------------------------------
3704 + */
3706 +#ifndef AUTOCONF_INCLUDED
3707 +#include <linux/config.h>
3708 +#endif
3709 +#include <linux/module.h>
3710 +#include <linux/init.h>
3711 +#include <linux/list.h>
3712 +#include <linux/slab.h>
3713 +#include <linux/sched.h>
3714 +#include <linux/wait.h>
3715 +#include <linux/crypto.h>
3716 +#include <linux/mm.h>
3717 +#include <linux/skbuff.h>
3718 +#include <linux/random.h>
3719 +#include <linux/version.h>
3720 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
3721 +#include <linux/scatterlist.h>
3722 +#endif
3723 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
3724 +#include <crypto/hash.h>
3725 +#endif
3727 +#include <cryptodev.h>
3728 +#include <uio.h>
3730 +struct {
3731 +       softc_device_decl       sc_dev;
3732 +} swcr_softc;
3734 +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
3736 +#define SW_TYPE_CIPHER         0x01
3737 +#define SW_TYPE_HMAC           0x02
3738 +#define SW_TYPE_HASH           0x04
3739 +#define SW_TYPE_COMP           0x08
3740 +#define SW_TYPE_BLKCIPHER      0x10
3741 +#define SW_TYPE_ALG_MASK       0x1f
3743 +#define SW_TYPE_ASYNC          0x8000
3745 +/* We change some of the above if we have an async interface */
3747 +#define SW_TYPE_ALG_AMASK      (SW_TYPE_ALG_MASK | SW_TYPE_ASYNC)
3749 +#define SW_TYPE_ABLKCIPHER     (SW_TYPE_BLKCIPHER | SW_TYPE_ASYNC)
3750 +#define SW_TYPE_AHASH          (SW_TYPE_HASH | SW_TYPE_ASYNC)
3751 +#define SW_TYPE_AHMAC          (SW_TYPE_HMAC | SW_TYPE_ASYNC)
3753 +#define SCATTERLIST_MAX 16
3755 +struct swcr_data {
3756 +       int                                     sw_type;
3757 +       int                                     sw_alg;
3758 +       struct crypto_tfm       *sw_tfm;
3759 +       union {
3760 +               struct {
3761 +                       char *sw_key;
3762 +                       int  sw_klen;
3763 +                       int  sw_mlen;
3764 +               } hmac;
3765 +               void *sw_comp_buf;
3766 +       } u;
3767 +       struct swcr_data        *sw_next;
3768 +};
3770 +struct swcr_req {
3771 +       struct swcr_data        *sw_head;
3772 +       struct swcr_data        *sw;
3773 +       struct cryptop          *crp;
3774 +       struct cryptodesc       *crd;
3775 +       struct scatterlist       sg[SCATTERLIST_MAX];
3776 +       unsigned char            iv[EALG_MAX_BLOCK_LEN];
3777 +       char                             result[HASH_MAX_LEN];
3778 +       void                            *crypto_req;
3779 +};
3781 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
3782 +static kmem_cache_t *swcr_req_cache;
3783 +#else
3784 +static struct kmem_cache *swcr_req_cache;
3785 +#endif
3787 +#ifndef CRYPTO_TFM_MODE_CBC
3788 +/*
3789 + * As of linux-2.6.21 this is no longer defined, and presumably no longer
3790 + * needed to be passed into the crypto core code.
3791 + */
3792 +#define        CRYPTO_TFM_MODE_CBC     0
3793 +#define        CRYPTO_TFM_MODE_ECB     0
3794 +#endif
3796 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
3797 +       /*
3798 +        * Linux 2.6.19 introduced a new Crypto API, setup macro's to convert new
3799 +        * API into old API.
3800 +        */
3802 +       /* Symmetric/Block Cipher */
3803 +       struct blkcipher_desc
3804 +       {
3805 +               struct crypto_tfm *tfm;
3806 +               void *info;
3807 +       };
3808 +       #define ecb(X)                                                          #X , CRYPTO_TFM_MODE_ECB
3809 +       #define cbc(X)                                                          #X , CRYPTO_TFM_MODE_CBC
3810 +       #define crypto_has_blkcipher(X, Y, Z)           crypto_alg_available(X, 0)
3811 +       #define crypto_blkcipher_cast(X)                        X
3812 +       #define crypto_blkcipher_tfm(X)                         X
3813 +       #define crypto_alloc_blkcipher(X, Y, Z)         crypto_alloc_tfm(X, mode)
3814 +       #define crypto_blkcipher_ivsize(X)                      crypto_tfm_alg_ivsize(X)
3815 +       #define crypto_blkcipher_blocksize(X)           crypto_tfm_alg_blocksize(X)
3816 +       #define crypto_blkcipher_setkey(X, Y, Z)        crypto_cipher_setkey(X, Y, Z)
3817 +       #define crypto_blkcipher_encrypt_iv(W, X, Y, Z) \
3818 +                               crypto_cipher_encrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
3819 +       #define crypto_blkcipher_decrypt_iv(W, X, Y, Z) \
3820 +                               crypto_cipher_decrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
3821 +       #define crypto_blkcipher_set_flags(x, y)        /* nop */
3823 +       /* Hash/HMAC/Digest */
3824 +       struct hash_desc
3825 +       {
3826 +               struct crypto_tfm *tfm;
3827 +       };
3828 +       #define hmac(X)                                                 #X , 0
3829 +       #define crypto_has_hash(X, Y, Z)                crypto_alg_available(X, 0)
3830 +       #define crypto_hash_cast(X)                             X
3831 +       #define crypto_hash_tfm(X)                              X
3832 +       #define crypto_alloc_hash(X, Y, Z)              crypto_alloc_tfm(X, mode)
3833 +       #define crypto_hash_digestsize(X)               crypto_tfm_alg_digestsize(X)
3834 +       #define crypto_hash_digest(W, X, Y, Z)  \
3835 +                               crypto_digest_digest((W)->tfm, X, sg_num, Z)
3837 +       /* Asymmetric Cipher */
3838 +       #define crypto_has_cipher(X, Y, Z)              crypto_alg_available(X, 0)
3840 +       /* Compression */
3841 +       #define crypto_has_comp(X, Y, Z)                crypto_alg_available(X, 0)
3842 +       #define crypto_comp_tfm(X)                              X
3843 +       #define crypto_comp_cast(X)                             X
3844 +       #define crypto_alloc_comp(X, Y, Z)              crypto_alloc_tfm(X, mode)
3845 +       #define plain(X)        #X , 0
3846 +#else
3847 +       #define ecb(X)  "ecb(" #X ")" , 0
3848 +       #define cbc(X)  "cbc(" #X ")" , 0
3849 +       #define hmac(X) "hmac(" #X ")" , 0
3850 +       #define plain(X)        #X , 0
3851 +#endif /* if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
3853 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
3854 +/* no ablkcipher in older kernels */
3855 +#define crypto_alloc_ablkcipher(a,b,c)         (NULL)
3856 +#define crypto_ablkcipher_tfm(x)                       ((struct crypto_tfm *)(x))
3857 +#define crypto_ablkcipher_set_flags(a, b)      /* nop */
3858 +#define crypto_ablkcipher_setkey(x, y, z)      (-EINVAL)
3859 +#define        crypto_has_ablkcipher(a,b,c)            (0)
3860 +#else
3861 +#define        HAVE_ABLKCIPHER
3862 +#endif
3864 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
3865 +/* no ahash in older kernels */
3866 +#define crypto_ahash_tfm(x)                                    ((struct crypto_tfm *)(x))
3867 +#define        crypto_alloc_ahash(a,b,c)                       (NULL)
3868 +#define        crypto_ahash_digestsize(x)                      0
3869 +#else
3870 +#define        HAVE_AHASH
3871 +#endif
3873 +struct crypto_details {
3874 +       char *alg_name;
3875 +       int mode;
3876 +       int sw_type;
3877 +};
3879 +static struct crypto_details crypto_details[] = {
3880 +       [CRYPTO_DES_CBC]         = { cbc(des),          SW_TYPE_BLKCIPHER, },
3881 +       [CRYPTO_3DES_CBC]        = { cbc(des3_ede),     SW_TYPE_BLKCIPHER, },
3882 +       [CRYPTO_BLF_CBC]         = { cbc(blowfish),     SW_TYPE_BLKCIPHER, },
3883 +       [CRYPTO_CAST_CBC]        = { cbc(cast5),        SW_TYPE_BLKCIPHER, },
3884 +       [CRYPTO_SKIPJACK_CBC]    = { cbc(skipjack),     SW_TYPE_BLKCIPHER, },
3885 +       [CRYPTO_MD5_HMAC]        = { hmac(md5),         SW_TYPE_HMAC, },
3886 +       [CRYPTO_SHA1_HMAC]       = { hmac(sha1),        SW_TYPE_HMAC, },
3887 +       [CRYPTO_RIPEMD160_HMAC]  = { hmac(ripemd160),   SW_TYPE_HMAC, },
3888 +       [CRYPTO_MD5_KPDK]        = { plain(md5-kpdk),   SW_TYPE_HASH, },
3889 +       [CRYPTO_SHA1_KPDK]       = { plain(sha1-kpdk),  SW_TYPE_HASH, },
3890 +       [CRYPTO_AES_CBC]         = { cbc(aes),          SW_TYPE_BLKCIPHER, },
3891 +       [CRYPTO_ARC4]            = { ecb(arc4),         SW_TYPE_BLKCIPHER, },
3892 +       [CRYPTO_MD5]             = { plain(md5),        SW_TYPE_HASH, },
3893 +       [CRYPTO_SHA1]            = { plain(sha1),       SW_TYPE_HASH, },
3894 +       [CRYPTO_NULL_HMAC]       = { hmac(digest_null), SW_TYPE_HMAC, },
3895 +       [CRYPTO_NULL_CBC]        = { cbc(cipher_null),  SW_TYPE_BLKCIPHER, },
3896 +       [CRYPTO_DEFLATE_COMP]    = { plain(deflate),    SW_TYPE_COMP, },
3897 +       [CRYPTO_SHA2_256_HMAC]   = { hmac(sha256),      SW_TYPE_HMAC, },
3898 +       [CRYPTO_SHA2_384_HMAC]   = { hmac(sha384),      SW_TYPE_HMAC, },
3899 +       [CRYPTO_SHA2_512_HMAC]   = { hmac(sha512),      SW_TYPE_HMAC, },
3900 +       [CRYPTO_CAMELLIA_CBC]    = { cbc(camellia),     SW_TYPE_BLKCIPHER, },
3901 +       [CRYPTO_SHA2_256]        = { plain(sha256),     SW_TYPE_HASH, },
3902 +       [CRYPTO_SHA2_384]        = { plain(sha384),     SW_TYPE_HASH, },
3903 +       [CRYPTO_SHA2_512]        = { plain(sha512),     SW_TYPE_HASH, },
3904 +       [CRYPTO_RIPEMD160]       = { plain(ripemd160),  SW_TYPE_HASH, },
3905 +};
3907 +int32_t swcr_id = -1;
3908 +module_param(swcr_id, int, 0444);
3909 +MODULE_PARM_DESC(swcr_id, "Read-Only OCF ID for cryptosoft driver");
3911 +int swcr_fail_if_compression_grows = 1;
3912 +module_param(swcr_fail_if_compression_grows, int, 0644);
3913 +MODULE_PARM_DESC(swcr_fail_if_compression_grows,
3914 +                "Treat compression that results in more data as a failure");
3916 +int swcr_no_ahash = 0;
3917 +module_param(swcr_no_ahash, int, 0644);
3918 +MODULE_PARM_DESC(swcr_no_ahash,
3919 +                "Do not use async hash/hmac even if available");
3921 +int swcr_no_ablk = 0;
3922 +module_param(swcr_no_ablk, int, 0644);
3923 +MODULE_PARM_DESC(swcr_no_ablk,
3924 +                "Do not use async blk ciphers even if available");
3926 +static struct swcr_data **swcr_sessions = NULL;
3927 +static u_int32_t swcr_sesnum = 0;
3929 +static int swcr_process(device_t, struct cryptop *, int);
3930 +static int swcr_newsession(device_t, u_int32_t *, struct cryptoini *);
3931 +static int swcr_freesession(device_t, u_int64_t);
3933 +static device_method_t swcr_methods = {
3934 +       /* crypto device methods */
3935 +       DEVMETHOD(cryptodev_newsession, swcr_newsession),
3936 +       DEVMETHOD(cryptodev_freesession,swcr_freesession),
3937 +       DEVMETHOD(cryptodev_process,    swcr_process),
3938 +};
3940 +#define debug swcr_debug
3941 +int swcr_debug = 0;
3942 +module_param(swcr_debug, int, 0644);
3943 +MODULE_PARM_DESC(swcr_debug, "Enable debug");
3945 +static void swcr_process_req(struct swcr_req *req);
3947 +/*
3948 + * Generate a new software session.
3949 + */
3950 +static int
3951 +swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
3952 +{
3953 +       struct swcr_data **swd;
3954 +       u_int32_t i;
3955 +       int error;
3956 +       char *algo;
3957 +       int mode;
3959 +       dprintk("%s()\n", __FUNCTION__);
3960 +       if (sid == NULL || cri == NULL) {
3961 +               dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
3962 +               return EINVAL;
3963 +       }
3965 +       if (swcr_sessions) {
3966 +               for (i = 1; i < swcr_sesnum; i++)
3967 +                       if (swcr_sessions[i] == NULL)
3968 +                               break;
3969 +       } else
3970 +               i = 1;          /* NB: to silence compiler warning */
3972 +       if (swcr_sessions == NULL || i == swcr_sesnum) {
3973 +               if (swcr_sessions == NULL) {
3974 +                       i = 1; /* We leave swcr_sessions[0] empty */
3975 +                       swcr_sesnum = CRYPTO_SW_SESSIONS;
3976 +               } else
3977 +                       swcr_sesnum *= 2;
3979 +               swd = kmalloc(swcr_sesnum * sizeof(struct swcr_data *), SLAB_ATOMIC);
3980 +               if (swd == NULL) {
3981 +                       /* Reset session number */
3982 +                       if (swcr_sesnum == CRYPTO_SW_SESSIONS)
3983 +                               swcr_sesnum = 0;
3984 +                       else
3985 +                               swcr_sesnum /= 2;
3986 +                       dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
3987 +                       return ENOBUFS;
3988 +               }
3989 +               memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *));
3991 +               /* Copy existing sessions */
3992 +               if (swcr_sessions) {
3993 +                       memcpy(swd, swcr_sessions,
3994 +                           (swcr_sesnum / 2) * sizeof(struct swcr_data *));
3995 +                       kfree(swcr_sessions);
3996 +               }
3998 +               swcr_sessions = swd;
3999 +       }
4001 +       swd = &swcr_sessions[i];
4002 +       *sid = i;
4004 +       while (cri) {
4005 +               *swd = (struct swcr_data *) kmalloc(sizeof(struct swcr_data),
4006 +                               SLAB_ATOMIC);
4007 +               if (*swd == NULL) {
4008 +                       swcr_freesession(NULL, i);
4009 +                       dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
4010 +                       return ENOBUFS;
4011 +               }
4012 +               memset(*swd, 0, sizeof(struct swcr_data));
4014 +               if (cri->cri_alg < 0 ||
4015 +                               cri->cri_alg>=sizeof(crypto_details)/sizeof(crypto_details[0])){
4016 +                       printk("cryptosoft: Unknown algorithm 0x%x\n", cri->cri_alg);
4017 +                       swcr_freesession(NULL, i);
4018 +                       return EINVAL;
4019 +               }
4021 +               algo = crypto_details[cri->cri_alg].alg_name;
4022 +               if (!algo || !*algo) {
4023 +                       printk("cryptosoft: Unsupported algorithm 0x%x\n", cri->cri_alg);
4024 +                       swcr_freesession(NULL, i);
4025 +                       return EINVAL;
4026 +               }
4028 +               mode = crypto_details[cri->cri_alg].mode;
4029 +               (*swd)->sw_type = crypto_details[cri->cri_alg].sw_type;
4030 +               (*swd)->sw_alg = cri->cri_alg;
4032 +               /* Algorithm specific configuration */
4033 +               switch (cri->cri_alg) {
4034 +               case CRYPTO_NULL_CBC:
4035 +                       cri->cri_klen = 0; /* make it work with crypto API */
4036 +                       break;
4037 +               default:
4038 +                       break;
4039 +               }
4041 +               if ((*swd)->sw_type & SW_TYPE_BLKCIPHER) {
4042 +                       dprintk("%s crypto_alloc_*blkcipher(%s, 0x%x)\n", __FUNCTION__,
4043 +                                       algo, mode);
4045 +                       /* try async first */
4046 +                       (*swd)->sw_tfm = swcr_no_ablk ? NULL :
4047 +                                       crypto_ablkcipher_tfm(crypto_alloc_ablkcipher(algo, 0, 0));
4048 +                       if ((*swd)->sw_tfm) {
4049 +                               dprintk("%s %s cipher is async\n", __FUNCTION__, algo);
4050 +                               (*swd)->sw_type |= SW_TYPE_ASYNC;
4051 +                       } else {
4052 +                               dprintk("%s %s cipher is sync\n", __FUNCTION__, algo);
4053 +                               (*swd)->sw_tfm = crypto_blkcipher_tfm(
4054 +                                               crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC));
4055 +                       }
4056 +                       if (!(*swd)->sw_tfm) {
4057 +                               dprintk("cryptosoft: crypto_alloc_blkcipher failed(%s, 0x%x)\n",
4058 +                                               algo,mode);
4059 +                               swcr_freesession(NULL, i);
4060 +                               return EINVAL;
4061 +                       }
4063 +                       if (debug) {
4064 +                               dprintk("%s key:cri->cri_klen=%d,(cri->cri_klen + 7)/8=%d",
4065 +                                               __FUNCTION__, cri->cri_klen, (cri->cri_klen + 7) / 8);
4066 +                               for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
4067 +                                       dprintk("%s0x%x", (i % 8) ? " " : "\n    ",
4068 +                                                       cri->cri_key[i] & 0xff);
4069 +                               dprintk("\n");
4070 +                       }
4071 +                       if ((*swd)->sw_type & SW_TYPE_ASYNC) {
4072 +                               /* OCF doesn't enforce keys */
4073 +                               crypto_ablkcipher_set_flags(
4074 +                                               __crypto_ablkcipher_cast((*swd)->sw_tfm),
4075 +                                                       CRYPTO_TFM_REQ_WEAK_KEY);
4076 +                               error = crypto_ablkcipher_setkey(
4077 +                                                       __crypto_ablkcipher_cast((*swd)->sw_tfm),
4078 +                                                               cri->cri_key, (cri->cri_klen + 7) / 8);
4079 +                       } else {
4080 +                               /* OCF doesn't enforce keys */
4081 +                               crypto_blkcipher_set_flags(
4082 +                                               crypto_blkcipher_cast((*swd)->sw_tfm),
4083 +                                                       CRYPTO_TFM_REQ_WEAK_KEY);
4084 +                               error = crypto_blkcipher_setkey(
4085 +                                                       crypto_blkcipher_cast((*swd)->sw_tfm),
4086 +                                                               cri->cri_key, (cri->cri_klen + 7) / 8);
4087 +                       }
4088 +                       if (error) {
4089 +                               printk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n", error,
4090 +                                               (*swd)->sw_tfm->crt_flags);
4091 +                               swcr_freesession(NULL, i);
4092 +                               return error;
4093 +                       }
4094 +               } else if ((*swd)->sw_type & (SW_TYPE_HMAC | SW_TYPE_HASH)) {
4095 +                       dprintk("%s crypto_alloc_*hash(%s, 0x%x)\n", __FUNCTION__,
4096 +                                       algo, mode);
4098 +                       /* try async first */
4099 +                       (*swd)->sw_tfm = swcr_no_ahash ? NULL :
4100 +                                       crypto_ahash_tfm(crypto_alloc_ahash(algo, 0, 0));
4101 +                       if ((*swd)->sw_tfm) {
4102 +                               dprintk("%s %s hash is async\n", __FUNCTION__, algo);
4103 +                               (*swd)->sw_type |= SW_TYPE_ASYNC;
4104 +                       } else {
4105 +                               dprintk("%s %s hash is sync\n", __FUNCTION__, algo);
4106 +                               (*swd)->sw_tfm = crypto_hash_tfm(
4107 +                                               crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC));
4108 +                       }
4110 +                       if (!(*swd)->sw_tfm) {
4111 +                               dprintk("cryptosoft: crypto_alloc_hash failed(%s,0x%x)\n",
4112 +                                               algo, mode);
4113 +                               swcr_freesession(NULL, i);
4114 +                               return EINVAL;
4115 +                       }
4117 +                       (*swd)->u.hmac.sw_klen = (cri->cri_klen + 7) / 8;
4118 +                       (*swd)->u.hmac.sw_key = (char *)kmalloc((*swd)->u.hmac.sw_klen,
4119 +                                       SLAB_ATOMIC);
4120 +                       if ((*swd)->u.hmac.sw_key == NULL) {
4121 +                               swcr_freesession(NULL, i);
4122 +                               dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
4123 +                               return ENOBUFS;
4124 +                       }
4125 +                       memcpy((*swd)->u.hmac.sw_key, cri->cri_key, (*swd)->u.hmac.sw_klen);
4126 +                       if (cri->cri_mlen) {
4127 +                               (*swd)->u.hmac.sw_mlen = cri->cri_mlen;
4128 +                       } else if ((*swd)->sw_type & SW_TYPE_ASYNC) {
4129 +                               (*swd)->u.hmac.sw_mlen = crypto_ahash_digestsize(
4130 +                                               __crypto_ahash_cast((*swd)->sw_tfm));
4131 +                       } else  {
4132 +                               (*swd)->u.hmac.sw_mlen = crypto_hash_digestsize(
4133 +                                               crypto_hash_cast((*swd)->sw_tfm));
4134 +                       }
4135 +               } else if ((*swd)->sw_type & SW_TYPE_COMP) {
4136 +                       (*swd)->sw_tfm = crypto_comp_tfm(
4137 +                                       crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC));
4138 +                       if (!(*swd)->sw_tfm) {
4139 +                               dprintk("cryptosoft: crypto_alloc_comp failed(%s,0x%x)\n",
4140 +                                               algo, mode);
4141 +                               swcr_freesession(NULL, i);
4142 +                               return EINVAL;
4143 +                       }
4144 +                       (*swd)->u.sw_comp_buf = kmalloc(CRYPTO_MAX_DATA_LEN, SLAB_ATOMIC);
4145 +                       if ((*swd)->u.sw_comp_buf == NULL) {
4146 +                               swcr_freesession(NULL, i);
4147 +                               dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
4148 +                               return ENOBUFS;
4149 +                       }
4150 +               } else {
4151 +                       printk("cryptosoft: Unhandled sw_type %d\n", (*swd)->sw_type);
4152 +                       swcr_freesession(NULL, i);
4153 +                       return EINVAL;
4154 +               }
4156 +               cri = cri->cri_next;
4157 +               swd = &((*swd)->sw_next);
4158 +       }
4159 +       return 0;
4160 +}
4162 +/*
4163 + * Free a session.
4164 + */
4165 +static int
4166 +swcr_freesession(device_t dev, u_int64_t tid)
4167 +{
4168 +       struct swcr_data *swd;
4169 +       u_int32_t sid = CRYPTO_SESID2LID(tid);
4171 +       dprintk("%s()\n", __FUNCTION__);
4172 +       if (sid > swcr_sesnum || swcr_sessions == NULL ||
4173 +                       swcr_sessions[sid] == NULL) {
4174 +               dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
4175 +               return(EINVAL);
4176 +       }
4178 +       /* Silently accept and return */
4179 +       if (sid == 0)
4180 +               return(0);
4182 +       while ((swd = swcr_sessions[sid]) != NULL) {
4183 +               swcr_sessions[sid] = swd->sw_next;
4184 +               if (swd->sw_tfm) {
4185 +                       switch (swd->sw_type & SW_TYPE_ALG_AMASK) {
4186 +#ifdef HAVE_AHASH
4187 +                       case SW_TYPE_AHMAC:
4188 +                       case SW_TYPE_AHASH:
4189 +                               crypto_free_ahash(__crypto_ahash_cast(swd->sw_tfm));
4190 +                               break;
4191 +#endif
4192 +#ifdef HAVE_ABLKCIPHER
4193 +                       case SW_TYPE_ABLKCIPHER:
4194 +                               crypto_free_ablkcipher(__crypto_ablkcipher_cast(swd->sw_tfm));
4195 +                               break;
4196 +#endif
4197 +                       case SW_TYPE_BLKCIPHER:
4198 +                               crypto_free_blkcipher(crypto_blkcipher_cast(swd->sw_tfm));
4199 +                               break;
4200 +                       case SW_TYPE_HMAC:
4201 +                       case SW_TYPE_HASH:
4202 +                               crypto_free_hash(crypto_hash_cast(swd->sw_tfm));
4203 +                               break;
4204 +                       case SW_TYPE_COMP:
4205 +                               crypto_free_comp(crypto_comp_cast(swd->sw_tfm));
4206 +                       default:
4207 +                               crypto_free_tfm(swd->sw_tfm);
4208 +                               break;
4209 +                       }
4210 +                       swd->sw_tfm = NULL;
4211 +               }
4212 +               if (swd->sw_type & SW_TYPE_COMP) {
4213 +                       if (swd->u.sw_comp_buf)
4214 +                               kfree(swd->u.sw_comp_buf);
4215 +               } else {
4216 +                       if (swd->u.hmac.sw_key)
4217 +                               kfree(swd->u.hmac.sw_key);
4218 +               }
4219 +               kfree(swd);
4220 +       }
4221 +       return 0;
4222 +}
4224 +#if defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH)
4225 +/* older kernels had no async interface */
4227 +static void swcr_process_callback(struct crypto_async_request *creq, int err)
4228 +{
4229 +       struct swcr_req *req = creq->data;
4231 +       dprintk("%s()\n", __FUNCTION__);
4232 +       if (err) {
4233 +               if (err == -EINPROGRESS)
4234 +                       return;
4235 +               dprintk("%s() fail %d\n", __FUNCTION__, -err);
4236 +               req->crp->crp_etype = -err;
4237 +               goto done;
4238 +       }
4240 +       switch (req->sw->sw_type & SW_TYPE_ALG_AMASK) {
4241 +       case SW_TYPE_AHMAC:
4242 +       case SW_TYPE_AHASH:
4243 +               crypto_copyback(req->crp->crp_flags, req->crp->crp_buf,
4244 +                               req->crd->crd_inject, req->sw->u.hmac.sw_mlen, req->result);
4245 +               ahash_request_free(req->crypto_req);
4246 +               break;
4247 +       case SW_TYPE_ABLKCIPHER:
4248 +               ablkcipher_request_free(req->crypto_req);
4249 +               break;
4250 +       default:
4251 +               req->crp->crp_etype = EINVAL;
4252 +               goto done;
4253 +       }
4255 +       req->crd = req->crd->crd_next;
4256 +       if (req->crd) {
4257 +               swcr_process_req(req);
4258 +               return;
4259 +       }
4261 +done:
4262 +       dprintk("%s crypto_done %p\n", __FUNCTION__, req);
4263 +       crypto_done(req->crp);
4264 +       kmem_cache_free(swcr_req_cache, req);
4265 +}
4266 +#endif /* defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH) */
4269 +static void swcr_process_req(struct swcr_req *req)
4270 +{
4271 +       struct swcr_data *sw;
4272 +       struct cryptop *crp = req->crp;
4273 +       struct cryptodesc *crd = req->crd;
4274 +       struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
4275 +       struct uio *uiop = (struct uio *) crp->crp_buf;
4276 +       int sg_num, sg_len, skip;
4278 +       dprintk("%s()\n", __FUNCTION__);
4280 +       /*
4281 +        * Find the crypto context.
4282 +        *
4283 +        * XXX Note that the logic here prevents us from having
4284 +        * XXX the same algorithm multiple times in a session
4285 +        * XXX (or rather, we can but it won't give us the right
4286 +        * XXX results). To do that, we'd need some way of differentiating
4287 +        * XXX between the various instances of an algorithm (so we can
4288 +        * XXX locate the correct crypto context).
4289 +        */
4290 +       for (sw = req->sw_head; sw && sw->sw_alg != crd->crd_alg; sw = sw->sw_next)
4291 +               ;
4293 +       /* No such context ? */
4294 +       if (sw == NULL) {
4295 +               crp->crp_etype = EINVAL;
4296 +               dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
4297 +               goto done;
4298 +       }
4300 +       req->sw = sw;
4301 +       skip = crd->crd_skip;
4303 +       /*
4304 +        * setup the SG list skip from the start of the buffer
4305 +        */
4306 +       memset(req->sg, 0, sizeof(req->sg));
4307 +       sg_init_table(req->sg, SCATTERLIST_MAX);
4308 +       if (crp->crp_flags & CRYPTO_F_SKBUF) {
4309 +               int i, len;
4311 +               sg_num = 0;
4312 +               sg_len = 0;
4314 +               if (skip < skb_headlen(skb)) {
4315 +                       len = skb_headlen(skb) - skip;
4316 +                       if (len + sg_len > crd->crd_len)
4317 +                               len = crd->crd_len - sg_len;
4318 +                       sg_set_page(&req->sg[sg_num],
4319 +                               virt_to_page(skb->data + skip), len,
4320 +                               offset_in_page(skb->data + skip));
4321 +                       sg_len += len;
4322 +                       sg_num++;
4323 +                       skip = 0;
4324 +               } else
4325 +                       skip -= skb_headlen(skb);
4327 +               for (i = 0; sg_len < crd->crd_len &&
4328 +                                       i < skb_shinfo(skb)->nr_frags &&
4329 +                                       sg_num < SCATTERLIST_MAX; i++) {
4330 +                       if (skip < skb_shinfo(skb)->frags[i].size) {
4331 +                               len = skb_shinfo(skb)->frags[i].size - skip;
4332 +                               if (len + sg_len > crd->crd_len)
4333 +                                       len = crd->crd_len - sg_len;
4334 +                               sg_set_page(&req->sg[sg_num],
4335 +                                       skb_shinfo(skb)->frags[i].page,
4336 +                                       len,
4337 +                                       skb_shinfo(skb)->frags[i].page_offset + skip);
4338 +                               sg_len += len;
4339 +                               sg_num++;
4340 +                               skip = 0;
4341 +                       } else
4342 +                               skip -= skb_shinfo(skb)->frags[i].size;
4343 +               }
4344 +       } else if (crp->crp_flags & CRYPTO_F_IOV) {
4345 +               int len;
4347 +               sg_len = 0;
4348 +               for (sg_num = 0; sg_len < crd->crd_len &&
4349 +                               sg_num < uiop->uio_iovcnt &&
4350 +                               sg_num < SCATTERLIST_MAX; sg_num++) {
4351 +                       if (skip <= uiop->uio_iov[sg_num].iov_len) {
4352 +                               len = uiop->uio_iov[sg_num].iov_len - skip;
4353 +                               if (len + sg_len > crd->crd_len)
4354 +                                       len = crd->crd_len - sg_len;
4355 +                               sg_set_page(&req->sg[sg_num],
4356 +                                       virt_to_page(uiop->uio_iov[sg_num].iov_base+skip),
4357 +                                       len,
4358 +                                       offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));
4359 +                               sg_len += len;
4360 +                               skip = 0;
4361 +                       } else 
4362 +                               skip -= uiop->uio_iov[sg_num].iov_len;
4363 +               }
4364 +       } else {
4365 +               sg_len = (crp->crp_ilen - skip);
4366 +               if (sg_len > crd->crd_len)
4367 +                       sg_len = crd->crd_len;
4368 +               sg_set_page(&req->sg[0], virt_to_page(crp->crp_buf + skip),
4369 +                       sg_len, offset_in_page(crp->crp_buf + skip));
4370 +               sg_num = 1;
4371 +       }
4373 +       switch (sw->sw_type & SW_TYPE_ALG_AMASK) {
4375 +#ifdef HAVE_AHASH
4376 +       case SW_TYPE_AHMAC:
4377 +       case SW_TYPE_AHASH:
4378 +               {
4379 +               int ret;
4381 +               /* check we have room for the result */
4382 +               if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
4383 +                       dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
4384 +                                       "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
4385 +                                       crd->crd_inject, sw->u.hmac.sw_mlen);
4386 +                       crp->crp_etype = EINVAL;
4387 +                       goto done;
4388 +               }
4390 +               req->crypto_req =
4391 +                               ahash_request_alloc(__crypto_ahash_cast(sw->sw_tfm),GFP_KERNEL);
4392 +               if (!req->crypto_req) {
4393 +                       crp->crp_etype = ENOMEM;
4394 +                       dprintk("%s,%d: ENOMEM ahash_request_alloc", __FILE__, __LINE__);
4395 +                       goto done;
4396 +               }
4398 +               ahash_request_set_callback(req->crypto_req,
4399 +                               CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
4401 +               memset(req->result, 0, sizeof(req->result));
4403 +               if (sw->sw_type & SW_TYPE_AHMAC)
4404 +                       crypto_ahash_setkey(__crypto_ahash_cast(sw->sw_tfm),
4405 +                                       sw->u.hmac.sw_key, sw->u.hmac.sw_klen);
4406 +               ahash_request_set_crypt(req->crypto_req, req->sg, req->result, sg_len);
4407 +               ret = crypto_ahash_digest(req->crypto_req);
4408 +               switch (ret) {
4409 +               case -EINPROGRESS:
4410 +               case -EBUSY:
4411 +                       return;
4412 +               default:
4413 +               case 0:
4414 +                       dprintk("hash OP %s %d\n", ret ? "failed" : "success", ret);
4415 +                       crp->crp_etype = ret;
4416 +                       ahash_request_free(req->crypto_req);
4417 +                       goto done;
4418 +               }
4419 +               } break;
4420 +#endif /* HAVE_AHASH */
4422 +#ifdef HAVE_ABLKCIPHER
4423 +       case SW_TYPE_ABLKCIPHER: {
4424 +               int ret;
4425 +               unsigned char *ivp = req->iv;
4426 +               int ivsize = 
4427 +                       crypto_ablkcipher_ivsize(__crypto_ablkcipher_cast(sw->sw_tfm));
4429 +               if (sg_len < crypto_ablkcipher_blocksize(
4430 +                               __crypto_ablkcipher_cast(sw->sw_tfm))) {
4431 +                       crp->crp_etype = EINVAL;
4432 +                       dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
4433 +                                       sg_len, crypto_ablkcipher_blocksize(
4434 +                                               __crypto_ablkcipher_cast(sw->sw_tfm)));
4435 +                       goto done;
4436 +               }
4438 +               if (ivsize > sizeof(req->iv)) {
4439 +                       crp->crp_etype = EINVAL;
4440 +                       dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
4441 +                       goto done;
4442 +               }
4444 +               req->crypto_req = ablkcipher_request_alloc(
4445 +                               __crypto_ablkcipher_cast(sw->sw_tfm), GFP_KERNEL);
4446 +               if (!req->crypto_req) {
4447 +                       crp->crp_etype = ENOMEM;
4448 +                       dprintk("%s,%d: ENOMEM ablkcipher_request_alloc",
4449 +                                       __FILE__, __LINE__);
4450 +                       goto done;
4451 +               }
4453 +               ablkcipher_request_set_callback(req->crypto_req,
4454 +                               CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
4456 +               if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
4457 +                       int i, error;
4459 +                       if (debug) {
4460 +                               dprintk("%s key:", __FUNCTION__);
4461 +                               for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
4462 +                                       dprintk("%s0x%x", (i % 8) ? " " : "\n    ",
4463 +                                                       crd->crd_key[i] & 0xff);
4464 +                               dprintk("\n");
4465 +                       }
4466 +                       /* OCF doesn't enforce keys */
4467 +                       crypto_ablkcipher_set_flags(__crypto_ablkcipher_cast(sw->sw_tfm),
4468 +                                       CRYPTO_TFM_REQ_WEAK_KEY);
4469 +                       error = crypto_ablkcipher_setkey(
4470 +                                               __crypto_ablkcipher_cast(sw->sw_tfm), crd->crd_key,
4471 +                                               (crd->crd_klen + 7) / 8);
4472 +                       if (error) {
4473 +                               dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
4474 +                                               error, sw->sw_tfm->crt_flags);
4475 +                               crp->crp_etype = -error;
4476 +                       }
4477 +               }
4479 +               if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
4481 +                       if (crd->crd_flags & CRD_F_IV_EXPLICIT)
4482 +                               ivp = crd->crd_iv;
4483 +                       else
4484 +                               get_random_bytes(ivp, ivsize);
4485 +                       /*
4486 +                        * do we have to copy the IV back to the buffer ?
4487 +                        */
4488 +                       if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
4489 +                               crypto_copyback(crp->crp_flags, crp->crp_buf,
4490 +                                               crd->crd_inject, ivsize, (caddr_t)ivp);
4491 +                       }
4492 +                       ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
4493 +                                       sg_len, ivp);
4494 +                       ret = crypto_ablkcipher_encrypt(req->crypto_req);
4496 +               } else { /*decrypt */
4498 +                       if (crd->crd_flags & CRD_F_IV_EXPLICIT)
4499 +                               ivp = crd->crd_iv;
4500 +                       else
4501 +                               crypto_copydata(crp->crp_flags, crp->crp_buf,
4502 +                                               crd->crd_inject, ivsize, (caddr_t)ivp);
4503 +                       ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
4504 +                                       sg_len, ivp);
4505 +                       ret = crypto_ablkcipher_decrypt(req->crypto_req);
4506 +               }
4508 +               switch (ret) {
4509 +               case -EINPROGRESS:
4510 +               case -EBUSY:
4511 +                       return;
4512 +               default:
4513 +               case 0:
4514 +                       dprintk("crypto OP %s %d\n", ret ? "failed" : "success", ret);
4515 +                       crp->crp_etype = ret;
4516 +                       goto done;
4517 +               }
4518 +               } break;
4519 +#endif /* HAVE_ABLKCIPHER */
4521 +       case SW_TYPE_BLKCIPHER: {
4522 +               unsigned char iv[EALG_MAX_BLOCK_LEN];
4523 +               unsigned char *ivp = iv;
4524 +               struct blkcipher_desc desc;
4525 +               int ivsize = crypto_blkcipher_ivsize(crypto_blkcipher_cast(sw->sw_tfm));
4527 +               if (sg_len < crypto_blkcipher_blocksize(
4528 +                               crypto_blkcipher_cast(sw->sw_tfm))) {
4529 +                       crp->crp_etype = EINVAL;
4530 +                       dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
4531 +                                       sg_len, crypto_blkcipher_blocksize(
4532 +                                               crypto_blkcipher_cast(sw->sw_tfm)));
4533 +                       goto done;
4534 +               }
4536 +               if (ivsize > sizeof(iv)) {
4537 +                       crp->crp_etype = EINVAL;
4538 +                       dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
4539 +                       goto done;
4540 +               }
4542 +               if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
4543 +                       int i, error;
4545 +                       if (debug) {
4546 +                               dprintk("%s key:", __FUNCTION__);
4547 +                               for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
4548 +                                       dprintk("%s0x%x", (i % 8) ? " " : "\n    ",
4549 +                                                       crd->crd_key[i] & 0xff);
4550 +                               dprintk("\n");
4551 +                       }
4552 +                       /* OCF doesn't enforce keys */
4553 +                       crypto_blkcipher_set_flags(crypto_blkcipher_cast(sw->sw_tfm),
4554 +                                       CRYPTO_TFM_REQ_WEAK_KEY);
4555 +                       error = crypto_blkcipher_setkey(
4556 +                                               crypto_blkcipher_cast(sw->sw_tfm), crd->crd_key,
4557 +                                               (crd->crd_klen + 7) / 8);
4558 +                       if (error) {
4559 +                               dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
4560 +                                               error, sw->sw_tfm->crt_flags);
4561 +                               crp->crp_etype = -error;
4562 +                       }
4563 +               }
4565 +               memset(&desc, 0, sizeof(desc));
4566 +               desc.tfm = crypto_blkcipher_cast(sw->sw_tfm);
4568 +               if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
4570 +                       if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
4571 +                               ivp = crd->crd_iv;
4572 +                       } else {
4573 +                               get_random_bytes(ivp, ivsize);
4574 +                       }
4575 +                       /*
4576 +                        * do we have to copy the IV back to the buffer ?
4577 +                        */
4578 +                       if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
4579 +                               crypto_copyback(crp->crp_flags, crp->crp_buf,
4580 +                                               crd->crd_inject, ivsize, (caddr_t)ivp);
4581 +                       }
4582 +                       desc.info = ivp;
4583 +                       crypto_blkcipher_encrypt_iv(&desc, req->sg, req->sg, sg_len);
4585 +               } else { /*decrypt */
4587 +                       if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
4588 +                               ivp = crd->crd_iv;
4589 +                       } else {
4590 +                               crypto_copydata(crp->crp_flags, crp->crp_buf,
4591 +                                               crd->crd_inject, ivsize, (caddr_t)ivp);
4592 +                       }
4593 +                       desc.info = ivp;
4594 +                       crypto_blkcipher_decrypt_iv(&desc, req->sg, req->sg, sg_len);
4595 +               }
4596 +               } break;
4598 +       case SW_TYPE_HMAC:
4599 +       case SW_TYPE_HASH:
4600 +               {
4601 +               char result[HASH_MAX_LEN];
4602 +               struct hash_desc desc;
4604 +               /* check we have room for the result */
4605 +               if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
4606 +                       dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
4607 +                                       "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
4608 +                                       crd->crd_inject, sw->u.hmac.sw_mlen);
4609 +                       crp->crp_etype = EINVAL;
4610 +                       goto done;
4611 +               }
4613 +               memset(&desc, 0, sizeof(desc));
4614 +               desc.tfm = crypto_hash_cast(sw->sw_tfm);
4616 +               memset(result, 0, sizeof(result));
4618 +               if (sw->sw_type & SW_TYPE_HMAC) {
4619 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
4620 +                       crypto_hmac(sw->sw_tfm, sw->u.hmac.sw_key, &sw->u.hmac.sw_klen,
4621 +                                       req->sg, sg_num, result);
4622 +#else
4623 +                       crypto_hash_setkey(desc.tfm, sw->u.hmac.sw_key,
4624 +                                       sw->u.hmac.sw_klen);
4625 +                       crypto_hash_digest(&desc, req->sg, sg_len, result);
4626 +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
4627 +                       
4628 +               } else { /* SW_TYPE_HASH */
4629 +                       crypto_hash_digest(&desc, req->sg, sg_len, result);
4630 +               }
4632 +               crypto_copyback(crp->crp_flags, crp->crp_buf,
4633 +                               crd->crd_inject, sw->u.hmac.sw_mlen, result);
4634 +               }
4635 +               break;
4637 +       case SW_TYPE_COMP: {
4638 +               void *ibuf = NULL;
4639 +               void *obuf = sw->u.sw_comp_buf;
4640 +               int ilen = sg_len, olen = CRYPTO_MAX_DATA_LEN;
4641 +               int ret = 0;
4643 +               /*
4644 +                * we need to use an additional copy if there is more than one
4645 +                * input chunk since the kernel comp routines do not handle
4646 +                * SG yet.  Otherwise we just use the input buffer as is.
4647 +                * Rather than allocate another buffer we just split the tmp
4648 +                * buffer we already have.
4649 +                * Perhaps we should just use zlib directly ?
4650 +                */
4651 +               if (sg_num > 1) {
4652 +                       int blk;
4654 +                       ibuf = obuf;
4655 +                       for (blk = 0; blk < sg_num; blk++) {
4656 +                               memcpy(obuf, sg_virt(&req->sg[blk]),
4657 +                                               req->sg[blk].length);
4658 +                               obuf += req->sg[blk].length;
4659 +                       }
4660 +                       olen -= sg_len;
4661 +               } else
4662 +                       ibuf = sg_virt(&req->sg[0]);
4664 +               if (crd->crd_flags & CRD_F_ENCRYPT) { /* compress */
4665 +                       ret = crypto_comp_compress(crypto_comp_cast(sw->sw_tfm),
4666 +                                       ibuf, ilen, obuf, &olen);
4667 +                       if (!ret && olen > crd->crd_len) {
4668 +                               dprintk("cryptosoft: ERANGE compress %d into %d\n",
4669 +                                               crd->crd_len, olen);
4670 +                               if (swcr_fail_if_compression_grows)
4671 +                                       ret = ERANGE;
4672 +                       }
4673 +               } else { /* decompress */
4674 +                       ret = crypto_comp_decompress(crypto_comp_cast(sw->sw_tfm),
4675 +                                       ibuf, ilen, obuf, &olen);
4676 +                       if (!ret && (olen + crd->crd_inject) > crp->crp_olen) {
4677 +                               dprintk("cryptosoft: ETOOSMALL decompress %d into %d, "
4678 +                                               "space for %d,at offset %d\n",
4679 +                                               crd->crd_len, olen, crp->crp_olen, crd->crd_inject);
4680 +                               ret = ETOOSMALL;
4681 +                       }
4682 +               }
4683 +               if (ret)
4684 +                       dprintk("%s,%d: ret = %d\n", __FILE__, __LINE__, ret);
4686 +               /*
4687 +                * on success copy result back,
4688 +                * linux crpyto API returns -errno,  we need to fix that
4689 +                */
4690 +               crp->crp_etype = ret < 0 ? -ret : ret;
4691 +               if (ret == 0) {
4692 +                       /* copy back the result and return it's size */
4693 +                       crypto_copyback(crp->crp_flags, crp->crp_buf,
4694 +                                       crd->crd_inject, olen, obuf);
4695 +                       crp->crp_olen = olen;
4696 +               }
4699 +               } break;
4701 +       default:
4702 +               /* Unknown/unsupported algorithm */
4703 +               dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
4704 +               crp->crp_etype = EINVAL;
4705 +               goto done;
4706 +       }
4708 +done:
4709 +       crypto_done(crp);
4710 +       kmem_cache_free(swcr_req_cache, req);
4711 +}
4714 +/*
4715 + * Process a crypto request.
4716 + */
4717 +static int
4718 +swcr_process(device_t dev, struct cryptop *crp, int hint)
4719 +{
4720 +       struct swcr_req *req = NULL;
4721 +       u_int32_t lid;
4723 +       dprintk("%s()\n", __FUNCTION__);
4724 +       /* Sanity check */
4725 +       if (crp == NULL) {
4726 +               dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
4727 +               return EINVAL;
4728 +       }
4730 +       crp->crp_etype = 0;
4732 +       if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
4733 +               dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
4734 +               crp->crp_etype = EINVAL;
4735 +               goto done;
4736 +       }
4738 +       lid = crp->crp_sid & 0xffffffff;
4739 +       if (lid >= swcr_sesnum || lid == 0 || swcr_sessions == NULL ||
4740 +                       swcr_sessions[lid] == NULL) {
4741 +               crp->crp_etype = ENOENT;
4742 +               dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
4743 +               goto done;
4744 +       }
4746 +       /*
4747 +        * do some error checking outside of the loop for SKB and IOV processing
4748 +        * this leaves us with valid skb or uiop pointers for later
4749 +        */
4750 +       if (crp->crp_flags & CRYPTO_F_SKBUF) {
4751 +               struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
4752 +               if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
4753 +                       printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
4754 +                                       skb_shinfo(skb)->nr_frags);
4755 +                       goto done;
4756 +               }
4757 +       } else if (crp->crp_flags & CRYPTO_F_IOV) {
4758 +               struct uio *uiop = (struct uio *) crp->crp_buf;
4759 +               if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
4760 +                       printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
4761 +                                       uiop->uio_iovcnt);
4762 +                       goto done;
4763 +               }
4764 +       }
4766 +       /*
4767 +        * setup a new request ready for queuing
4768 +        */
4769 +       req = kmem_cache_alloc(swcr_req_cache, SLAB_ATOMIC);
4770 +       if (req == NULL) {
4771 +               dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
4772 +               crp->crp_etype = ENOMEM;
4773 +               goto done;
4774 +       }
4775 +       memset(req, 0, sizeof(*req));
4777 +       req->sw_head = swcr_sessions[lid];
4778 +       req->crp = crp;
4779 +       req->crd = crp->crp_desc;
4781 +       swcr_process_req(req);
4782 +       return 0;
4784 +done:
4785 +       crypto_done(crp);
4786 +       if (req)
4787 +               kmem_cache_free(swcr_req_cache, req);
4788 +       return 0;
4789 +}
4792 +static int
4793 +cryptosoft_init(void)
4794 +{
4795 +       int i, sw_type, mode;
4796 +       char *algo;
4798 +       dprintk("%s(%p)\n", __FUNCTION__, cryptosoft_init);
4800 +       swcr_req_cache = kmem_cache_create("cryptosoft_req",
4801 +                               sizeof(struct swcr_req), 0, SLAB_HWCACHE_ALIGN, NULL
4802 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
4803 +                               , NULL
4804 +#endif
4805 +                               );
4806 +       if (!swcr_req_cache) {
4807 +               printk("cryptosoft: failed to create request cache\n");
4808 +               return -ENOENT;
4809 +       }
4811 +       softc_device_init(&swcr_softc, "cryptosoft", 0, swcr_methods);
4813 +       swcr_id = crypto_get_driverid(softc_get_device(&swcr_softc),
4814 +                       CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
4815 +       if (swcr_id < 0) {
4816 +               printk("cryptosoft: Software crypto device cannot initialize!");
4817 +               return -ENODEV;
4818 +       }
4820 +#define        REGISTER(alg) \
4821 +               crypto_register(swcr_id, alg, 0,0)
4823 +       for (i = 0; i < sizeof(crypto_details)/sizeof(crypto_details[0]); i++) {
4824 +               int found;
4825 +               
4826 +               algo = crypto_details[i].alg_name;
4827 +               if (!algo || !*algo) {
4828 +                       dprintk("%s:Algorithm %d not supported\n", __FUNCTION__, i);
4829 +                       continue;
4830 +               }
4832 +               mode = crypto_details[i].mode;
4833 +               sw_type = crypto_details[i].sw_type;
4835 +               found = 0;
4836 +               switch (sw_type & SW_TYPE_ALG_MASK) {
4837 +               case SW_TYPE_CIPHER:
4838 +                       found = crypto_has_cipher(algo, 0, CRYPTO_ALG_ASYNC);
4839 +                       break;
4840 +               case SW_TYPE_HMAC:
4841 +                       found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
4842 +                       break;
4843 +               case SW_TYPE_HASH:
4844 +                       found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
4845 +                       break;
4846 +               case SW_TYPE_COMP:
4847 +                       found = crypto_has_comp(algo, 0, CRYPTO_ALG_ASYNC);
4848 +                       break;
4849 +               case SW_TYPE_BLKCIPHER:
4850 +                       found = crypto_has_blkcipher(algo, 0, CRYPTO_ALG_ASYNC);
4851 +                       if (!found && !swcr_no_ablk)
4852 +                               found = crypto_has_ablkcipher(algo, 0, 0);
4853 +                       break;
4854 +               }
4855 +               if (found) {
4856 +                       REGISTER(i);
4857 +               } else {
4858 +                       dprintk("%s:Algorithm Type %d not supported (algorithm %d:'%s')\n",
4859 +                                       __FUNCTION__, sw_type, i, algo);
4860 +               }
4861 +       }
4862 +       return 0;
4863 +}
4865 +static void
4866 +cryptosoft_exit(void)
4867 +{
4868 +       dprintk("%s()\n", __FUNCTION__);
4869 +       crypto_unregister_all(swcr_id);
4870 +       swcr_id = -1;
4871 +       kmem_cache_destroy(swcr_req_cache);
4872 +}
4874 +late_initcall(cryptosoft_init);
4875 +module_exit(cryptosoft_exit);
4877 +MODULE_LICENSE("Dual BSD/GPL");
4878 +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
4879 +MODULE_DESCRIPTION("Cryptosoft (OCF module for kernel crypto)");
4880 diff --git a/crypto/ocf/ocf-bench.c b/crypto/ocf/ocf-bench.c
4881 new file mode 100644
4882 index 0000000..d325231
4883 --- /dev/null
4884 +++ b/crypto/ocf/ocf-bench.c
4885 @@ -0,0 +1,436 @@
4886 +/*
4887 + * A loadable module that benchmarks the OCF crypto speed from kernel space.
4888 + *
4889 + * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>
4890 + *
4891 + * LICENSE TERMS
4892 + *
4893 + * The free distribution and use of this software in both source and binary
4894 + * form is allowed (with or without changes) provided that:
4895 + *
4896 + *   1. distributions of this source code include the above copyright
4897 + *      notice, this list of conditions and the following disclaimer;
4898 + *
4899 + *   2. distributions in binary form include the above copyright
4900 + *      notice, this list of conditions and the following disclaimer
4901 + *      in the documentation and/or other associated materials;
4902 + *
4903 + *   3. the copyright holder's name is not used to endorse products
4904 + *      built using this software without specific written permission.
4905 + *
4906 + * ALTERNATIVELY, provided that this notice is retained in full, this product
4907 + * may be distributed under the terms of the GNU General Public License (GPL),
4908 + * in which case the provisions of the GPL apply INSTEAD OF those given above.
4909 + *
4910 + * DISCLAIMER
4911 + *
4912 + * This software is provided 'as is' with no explicit or implied warranties
4913 + * in respect of its properties, including, but not limited to, correctness
4914 + * and/or fitness for purpose.
4915 + */
4918 +#ifndef AUTOCONF_INCLUDED
4919 +#include <linux/config.h>
4920 +#endif
4921 +#include <linux/module.h>
4922 +#include <linux/init.h>
4923 +#include <linux/list.h>
4924 +#include <linux/slab.h>
4925 +#include <linux/wait.h>
4926 +#include <linux/sched.h>
4927 +#include <linux/spinlock.h>
4928 +#include <linux/version.h>
4929 +#include <linux/interrupt.h>
4930 +#include <cryptodev.h>
4932 +#ifdef I_HAVE_AN_XSCALE_WITH_INTEL_SDK
4933 +#define BENCH_IXP_ACCESS_LIB 1
4934 +#endif
4935 +#ifdef BENCH_IXP_ACCESS_LIB
4936 +#include <IxTypes.h>
4937 +#include <IxOsBuffMgt.h>
4938 +#include <IxNpeDl.h>
4939 +#include <IxCryptoAcc.h>
4940 +#include <IxQMgr.h>
4941 +#include <IxOsServices.h>
4942 +#include <IxOsCacheMMU.h>
4943 +#endif
4945 +/*
4946 + * support for access lib version 1.4
4947 + */
4948 +#ifndef IX_MBUF_PRIV
4949 +#define IX_MBUF_PRIV(x) ((x)->priv)
4950 +#endif
4952 +/*
4953 + * the number of simultaneously active requests
4954 + */
4955 +static int request_q_len = 20;
4956 +module_param(request_q_len, int, 0);
4957 +MODULE_PARM_DESC(request_q_len, "Number of outstanding requests");
4958 +/*
4959 + * how many requests we want to have processed
4960 + */
4961 +static int request_num = 1024;
4962 +module_param(request_num, int, 0);
4963 +MODULE_PARM_DESC(request_num, "run for at least this many requests");
4964 +/*
4965 + * the size of each request
4966 + */
4967 +static int request_size = 1500;
4968 +module_param(request_size, int, 0);
4969 +MODULE_PARM_DESC(request_size, "size of each request");
4971 +/*
4972 + * a structure for each request
4973 + */
4974 +typedef struct  {
4975 +       struct work_struct work;
4976 +#ifdef BENCH_IXP_ACCESS_LIB
4977 +       IX_MBUF mbuf;
4978 +#endif
4979 +       unsigned char *buffer;
4980 +} request_t;
4982 +static request_t *requests;
4984 +static int outstanding;
4985 +static int total;
4987 +/*************************************************************************/
4988 +/*
4989 + * OCF benchmark routines
4990 + */
4992 +static uint64_t ocf_cryptoid;
4993 +static int ocf_init(void);
4994 +static int ocf_cb(struct cryptop *crp);
4995 +static void ocf_request(void *arg);
4996 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
4997 +static void ocf_request_wq(struct work_struct *work);
4998 +#endif
5000 +static int
5001 +ocf_init(void)
5002 +{
5003 +       int error;
5004 +       struct cryptoini crie, cria;
5005 +       struct cryptodesc crda, crde;
5007 +       memset(&crie, 0, sizeof(crie));
5008 +       memset(&cria, 0, sizeof(cria));
5009 +       memset(&crde, 0, sizeof(crde));
5010 +       memset(&crda, 0, sizeof(crda));
5012 +       cria.cri_alg  = CRYPTO_SHA1_HMAC;
5013 +       cria.cri_klen = 20 * 8;
5014 +       cria.cri_key  = "0123456789abcdefghij";
5016 +       crie.cri_alg  = CRYPTO_3DES_CBC;
5017 +       crie.cri_klen = 24 * 8;
5018 +       crie.cri_key  = "0123456789abcdefghijklmn";
5020 +       crie.cri_next = &cria;
5022 +       error = crypto_newsession(&ocf_cryptoid, &crie, 0);
5023 +       if (error) {
5024 +               printk("crypto_newsession failed %d\n", error);
5025 +               return -1;
5026 +       }
5027 +       return 0;
5028 +}
5030 +static int
5031 +ocf_cb(struct cryptop *crp)
5032 +{
5033 +       request_t *r = (request_t *) crp->crp_opaque;
5035 +       if (crp->crp_etype)
5036 +               printk("Error in OCF processing: %d\n", crp->crp_etype);
5037 +       total++;
5038 +       crypto_freereq(crp);
5039 +       crp = NULL;
5041 +       if (total > request_num) {
5042 +               outstanding--;
5043 +               return 0;
5044 +       }
5046 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
5047 +       INIT_WORK(&r->work, ocf_request_wq);
5048 +#else
5049 +       INIT_WORK(&r->work, ocf_request, r);
5050 +#endif
5051 +       schedule_work(&r->work);
5052 +       return 0;
5053 +}
5056 +static void
5057 +ocf_request(void *arg)
5058 +{
5059 +       request_t *r = arg;
5060 +       struct cryptop *crp = crypto_getreq(2);
5061 +       struct cryptodesc *crde, *crda;
5063 +       if (!crp) {
5064 +               outstanding--;
5065 +               return;
5066 +       }
5068 +       crde = crp->crp_desc;
5069 +       crda = crde->crd_next;
5071 +       crda->crd_skip = 0;
5072 +       crda->crd_flags = 0;
5073 +       crda->crd_len = request_size;
5074 +       crda->crd_inject = request_size;
5075 +       crda->crd_alg = CRYPTO_SHA1_HMAC;
5076 +       crda->crd_key = "0123456789abcdefghij";
5077 +       crda->crd_klen = 20 * 8;
5079 +       crde->crd_skip = 0;
5080 +       crde->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_ENCRYPT;
5081 +       crde->crd_len = request_size;
5082 +       crde->crd_inject = request_size;
5083 +       crde->crd_alg = CRYPTO_3DES_CBC;
5084 +       crde->crd_key = "0123456789abcdefghijklmn";
5085 +       crde->crd_klen = 24 * 8;
5087 +       crp->crp_ilen = request_size + 64;
5088 +       crp->crp_flags = CRYPTO_F_CBIMM;
5089 +       crp->crp_buf = (caddr_t) r->buffer;
5090 +       crp->crp_callback = ocf_cb;
5091 +       crp->crp_sid = ocf_cryptoid;
5092 +       crp->crp_opaque = (caddr_t) r;
5093 +       crypto_dispatch(crp);
5094 +}
5096 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
5097 +static void
5098 +ocf_request_wq(struct work_struct *work)
5099 +{
5100 +       request_t *r = container_of(work, request_t, work);
5101 +       ocf_request(r);
5102 +}
5103 +#endif
5105 +/*************************************************************************/
5106 +#ifdef BENCH_IXP_ACCESS_LIB
5107 +/*************************************************************************/
5108 +/*
5109 + * CryptoAcc benchmark routines
5110 + */
5112 +static IxCryptoAccCtx ixp_ctx;
5113 +static UINT32 ixp_ctx_id;
5114 +static IX_MBUF ixp_pri;
5115 +static IX_MBUF ixp_sec;
5116 +static int ixp_registered = 0;
5118 +static void ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp,
5119 +                                       IxCryptoAccStatus status);
5120 +static void ixp_perform_cb(UINT32 ctx_id, IX_MBUF *sbufp, IX_MBUF *dbufp,
5121 +                                       IxCryptoAccStatus status);
5122 +static void ixp_request(void *arg);
5123 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
5124 +static void ixp_request_wq(struct work_struct *work);
5125 +#endif
5127 +static int
5128 +ixp_init(void)
5129 +{
5130 +       IxCryptoAccStatus status;
5132 +       ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
5133 +       ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
5134 +       ixp_ctx.cipherCtx.cipherKeyLen = 24;
5135 +       ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
5136 +       ixp_ctx.cipherCtx.cipherInitialVectorLen = IX_CRYPTO_ACC_DES_IV_64;
5137 +       memcpy(ixp_ctx.cipherCtx.key.cipherKey, "0123456789abcdefghijklmn", 24);
5139 +       ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
5140 +       ixp_ctx.authCtx.authDigestLen = 12;
5141 +       ixp_ctx.authCtx.aadLen = 0;
5142 +       ixp_ctx.authCtx.authKeyLen = 20;
5143 +       memcpy(ixp_ctx.authCtx.key.authKey, "0123456789abcdefghij", 20);
5145 +       ixp_ctx.useDifferentSrcAndDestMbufs = 0;
5146 +       ixp_ctx.operation = IX_CRYPTO_ACC_OP_ENCRYPT_AUTH ;
5148 +       IX_MBUF_MLEN(&ixp_pri)  = IX_MBUF_PKT_LEN(&ixp_pri) = 128;
5149 +       IX_MBUF_MDATA(&ixp_pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
5150 +       IX_MBUF_MLEN(&ixp_sec)  = IX_MBUF_PKT_LEN(&ixp_sec) = 128;
5151 +       IX_MBUF_MDATA(&ixp_sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
5153 +       status = ixCryptoAccCtxRegister(&ixp_ctx, &ixp_pri, &ixp_sec,
5154 +                       ixp_register_cb, ixp_perform_cb, &ixp_ctx_id);
5156 +       if (IX_CRYPTO_ACC_STATUS_SUCCESS == status) {
5157 +               while (!ixp_registered)
5158 +                       schedule();
5159 +               return ixp_registered < 0 ? -1 : 0;
5160 +       }
5162 +       printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
5163 +       return -1;
5164 +}
5166 +static void
5167 +ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
5168 +{
5169 +       if (bufp) {
5170 +               IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
5171 +               kfree(IX_MBUF_MDATA(bufp));
5172 +               IX_MBUF_MDATA(bufp) = NULL;
5173 +       }
5175 +       if (IX_CRYPTO_ACC_STATUS_WAIT == status)
5176 +               return;
5177 +       if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
5178 +               ixp_registered = 1;
5179 +       else
5180 +               ixp_registered = -1;
5181 +}
5183 +static void
5184 +ixp_perform_cb(
5185 +       UINT32 ctx_id,
5186 +       IX_MBUF *sbufp,
5187 +       IX_MBUF *dbufp,
5188 +       IxCryptoAccStatus status)
5189 +{
5190 +       request_t *r = NULL;
5192 +       total++;
5193 +       if (total > request_num) {
5194 +               outstanding--;
5195 +               return;
5196 +       }
5198 +       if (!sbufp || !(r = IX_MBUF_PRIV(sbufp))) {
5199 +               printk("crappo %p %p\n", sbufp, r);
5200 +               outstanding--;
5201 +               return;
5202 +       }
5204 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
5205 +       INIT_WORK(&r->work, ixp_request_wq);
5206 +#else
5207 +       INIT_WORK(&r->work, ixp_request, r);
5208 +#endif
5209 +       schedule_work(&r->work);
5210 +}
5212 +static void
5213 +ixp_request(void *arg)
5214 +{
5215 +       request_t *r = arg;
5216 +       IxCryptoAccStatus status;
5218 +       memset(&r->mbuf, 0, sizeof(r->mbuf));
5219 +       IX_MBUF_MLEN(&r->mbuf) = IX_MBUF_PKT_LEN(&r->mbuf) = request_size + 64;
5220 +       IX_MBUF_MDATA(&r->mbuf) = r->buffer;
5221 +       IX_MBUF_PRIV(&r->mbuf) = r;
5222 +       status = ixCryptoAccAuthCryptPerform(ixp_ctx_id, &r->mbuf, NULL,
5223 +                       0, request_size, 0, request_size, request_size, r->buffer);
5224 +       if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
5225 +               printk("status1 = %d\n", status);
5226 +               outstanding--;
5227 +               return;
5228 +       }
5229 +       return;
5230 +}
5232 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
5233 +static void
5234 +ixp_request_wq(struct work_struct *work)
5235 +{
5236 +       request_t *r = container_of(work, request_t, work);
5237 +       ixp_request(r);
5238 +}
5239 +#endif
5241 +/*************************************************************************/
5242 +#endif /* BENCH_IXP_ACCESS_LIB */
5243 +/*************************************************************************/
5245 +int
5246 +ocfbench_init(void)
5247 +{
5248 +       int i, jstart, jstop;
5250 +       printk("Crypto Speed tests\n");
5252 +       requests = kmalloc(sizeof(request_t) * request_q_len, GFP_KERNEL);
5253 +       if (!requests) {
5254 +               printk("malloc failed\n");
5255 +               return -EINVAL;
5256 +       }
5258 +       for (i = 0; i < request_q_len; i++) {
5259 +               /* +64 for return data */
5260 +               requests[i].buffer = kmalloc(request_size + 128, GFP_DMA);
5261 +               if (!requests[i].buffer) {
5262 +                       printk("malloc failed\n");
5263 +                       return -EINVAL;
5264 +               }
5265 +               memset(requests[i].buffer, '0' + i, request_size + 128);
5266 +       }
5268 +       /*
5269 +        * OCF benchmark
5270 +        */
5271 +       printk("OCF: testing ...\n");
5272 +       ocf_init();
5273 +       total = outstanding = 0;
5274 +       jstart = jiffies;
5275 +       for (i = 0; i < request_q_len; i++) {
5276 +               outstanding++;
5277 +               ocf_request(&requests[i]);
5278 +       }
5279 +       while (outstanding > 0)
5280 +               schedule();
5281 +       jstop = jiffies;
5283 +       printk("OCF: %d requests of %d bytes in %d jiffies\n", total, request_size,
5284 +                       jstop - jstart);
5286 +#ifdef BENCH_IXP_ACCESS_LIB
5287 +       /*
5288 +        * IXP benchmark
5289 +        */
5290 +       printk("IXP: testing ...\n");
5291 +       ixp_init();
5292 +       total = outstanding = 0;
5293 +       jstart = jiffies;
5294 +       for (i = 0; i < request_q_len; i++) {
5295 +               outstanding++;
5296 +               ixp_request(&requests[i]);
5297 +       }
5298 +       while (outstanding > 0)
5299 +               schedule();
5300 +       jstop = jiffies;
5302 +       printk("IXP: %d requests of %d bytes in %d jiffies\n", total, request_size,
5303 +                       jstop - jstart);
5304 +#endif /* BENCH_IXP_ACCESS_LIB */
5306 +       for (i = 0; i < request_q_len; i++)
5307 +               kfree(requests[i].buffer);
5308 +       kfree(requests);
5309 +       return -EINVAL; /* always fail to load so it can be re-run quickly ;-) */
5310 +}
5312 +static void __exit ocfbench_exit(void)
5313 +{
5314 +}
5316 +module_init(ocfbench_init);
5317 +module_exit(ocfbench_exit);
5319 +MODULE_LICENSE("BSD");
5320 +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
5321 +MODULE_DESCRIPTION("Benchmark various in-kernel crypto speeds");
5322 diff --git a/crypto/ocf/ocf-compat.h b/crypto/ocf/ocf-compat.h
5323 new file mode 100644
5324 index 0000000..212f971
5325 --- /dev/null
5326 +++ b/crypto/ocf/ocf-compat.h
5327 @@ -0,0 +1,294 @@
5328 +#ifndef _BSD_COMPAT_H_
5329 +#define _BSD_COMPAT_H_ 1
5330 +/****************************************************************************/
5331 +/*
5332 + * Provide compat routines for older linux kernels and BSD kernels
5333 + *
5334 + * Written by David McCullough <david_mccullough@mcafee.com>
5335 + * Copyright (C) 2010 David McCullough <david_mccullough@mcafee.com>
5336 + *
5337 + * LICENSE TERMS
5338 + *
5339 + * The free distribution and use of this software in both source and binary
5340 + * form is allowed (with or without changes) provided that:
5341 + *
5342 + *   1. distributions of this source code include the above copyright
5343 + *      notice, this list of conditions and the following disclaimer;
5344 + *
5345 + *   2. distributions in binary form include the above copyright
5346 + *      notice, this list of conditions and the following disclaimer
5347 + *      in the documentation and/or other associated materials;
5348 + *
5349 + *   3. the copyright holder's name is not used to endorse products
5350 + *      built using this software without specific written permission.
5351 + *
5352 + * ALTERNATIVELY, provided that this notice is retained in full, this file
5353 + * may be distributed under the terms of the GNU General Public License (GPL),
5354 + * in which case the provisions of the GPL apply INSTEAD OF those given above.
5355 + *
5356 + * DISCLAIMER
5357 + *
5358 + * This software is provided 'as is' with no explicit or implied warranties
5359 + * in respect of its properties, including, but not limited to, correctness
5360 + * and/or fitness for purpose.
5361 + */
5362 +/****************************************************************************/
5363 +#ifdef __KERNEL__
5364 +/*
5365 + * fake some BSD driver interface stuff specifically for OCF use
5366 + */
5368 +typedef struct ocf_device *device_t;
5370 +typedef struct {
5371 +       int (*cryptodev_newsession)(device_t dev, u_int32_t *sidp, struct cryptoini *cri);
5372 +       int (*cryptodev_freesession)(device_t dev, u_int64_t tid);
5373 +       int (*cryptodev_process)(device_t dev, struct cryptop *crp, int hint);
5374 +       int (*cryptodev_kprocess)(device_t dev, struct cryptkop *krp, int hint);
5375 +} device_method_t;
5376 +#define DEVMETHOD(id, func)    id: func
5378 +struct ocf_device {
5379 +       char name[32];          /* the driver name */
5380 +       char nameunit[32];      /* the driver name + HW instance */
5381 +       int  unit;
5382 +       device_method_t methods;
5383 +       void *softc;
5384 +};
5386 +#define CRYPTODEV_NEWSESSION(dev, sid, cri) \
5387 +       ((*(dev)->methods.cryptodev_newsession)(dev,sid,cri))
5388 +#define CRYPTODEV_FREESESSION(dev, sid) \
5389 +       ((*(dev)->methods.cryptodev_freesession)(dev, sid))
5390 +#define CRYPTODEV_PROCESS(dev, crp, hint) \
5391 +       ((*(dev)->methods.cryptodev_process)(dev, crp, hint))
5392 +#define CRYPTODEV_KPROCESS(dev, krp, hint) \
5393 +       ((*(dev)->methods.cryptodev_kprocess)(dev, krp, hint))
5395 +#define device_get_name(dev)   ((dev)->name)
5396 +#define device_get_nameunit(dev)       ((dev)->nameunit)
5397 +#define device_get_unit(dev)   ((dev)->unit)
5398 +#define device_get_softc(dev)  ((dev)->softc)
5400 +#define        softc_device_decl \
5401 +               struct ocf_device _device; \
5402 +               device_t
5404 +#define        softc_device_init(_sc, _name, _unit, _methods) \
5405 +       if (1) {\
5406 +       strncpy((_sc)->_device.name, _name, sizeof((_sc)->_device.name) - 1); \
5407 +       snprintf((_sc)->_device.nameunit, sizeof((_sc)->_device.name), "%s%d", _name, _unit); \
5408 +       (_sc)->_device.unit = _unit; \
5409 +       (_sc)->_device.methods = _methods; \
5410 +       (_sc)->_device.softc = (void *) _sc; \
5411 +       *(device_t *)((softc_get_device(_sc))+1) = &(_sc)->_device; \
5412 +       } else
5414 +#define        softc_get_device(_sc)   (&(_sc)->_device)
5416 +/*
5417 + * iomem support for 2.4 and 2.6 kernels
5418 + */
5419 +#include <linux/version.h>
5420 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
5421 +#define ocf_iomem_t    unsigned long
5423 +/*
5424 + * implement simple workqueue like support for older kernels
5425 + */
5427 +#include <linux/tqueue.h>
5429 +#define work_struct tq_struct
5431 +#define INIT_WORK(wp, fp, ap) \
5432 +       do { \
5433 +               (wp)->sync = 0; \
5434 +               (wp)->routine = (fp); \
5435 +               (wp)->data = (ap); \
5436 +       } while (0)
5438 +#define schedule_work(wp) \
5439 +       do { \
5440 +               queue_task((wp), &tq_immediate); \
5441 +               mark_bh(IMMEDIATE_BH); \
5442 +       } while (0)
5444 +#define flush_scheduled_work() run_task_queue(&tq_immediate)
5446 +#else
5447 +#define ocf_iomem_t    void __iomem *
5449 +#include <linux/workqueue.h>
5451 +#endif
5453 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
5454 +#include <linux/fdtable.h>
5455 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
5456 +#define files_fdtable(files)   (files)
5457 +#endif
5459 +#ifdef MODULE_PARM
5460 +#undef module_param    /* just in case */
5461 +#define        module_param(a,b,c)             MODULE_PARM(a,"i")
5462 +#endif
5464 +#define bzero(s,l)             memset(s,0,l)
5465 +#define bcopy(s,d,l)   memcpy(d,s,l)
5466 +#define bcmp(x, y, l)  memcmp(x,y,l)
5468 +#define MIN(x,y)       ((x) < (y) ? (x) : (y))
5470 +#define device_printf(dev, a...) ({ \
5471 +                               printk("%s: ", device_get_nameunit(dev)); printk(a); \
5472 +                       })
5474 +#undef printf
5475 +#define printf(fmt...) printk(fmt)
5477 +#define KASSERT(c,p)   if (!(c)) { printk p ; } else
5479 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
5480 +#define ocf_daemonize(str) \
5481 +       daemonize(); \
5482 +       spin_lock_irq(&current->sigmask_lock); \
5483 +       sigemptyset(&current->blocked); \
5484 +       recalc_sigpending(current); \
5485 +       spin_unlock_irq(&current->sigmask_lock); \
5486 +       sprintf(current->comm, str);
5487 +#else
5488 +#define ocf_daemonize(str) daemonize(str);
5489 +#endif
5491 +#define        TAILQ_INSERT_TAIL(q,d,m) list_add_tail(&(d)->m, (q))
5492 +#define        TAILQ_EMPTY(q)  list_empty(q)
5493 +#define        TAILQ_FOREACH(v, q, m) list_for_each_entry(v, q, m)
5495 +#define read_random(p,l) get_random_bytes(p,l)
5497 +#define DELAY(x)       ((x) > 2000 ? mdelay((x)/1000) : udelay(x))
5498 +#define strtoul simple_strtoul
5500 +#define pci_get_vendor(dev)    ((dev)->vendor)
5501 +#define pci_get_device(dev)    ((dev)->device)
5503 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
5504 +#define pci_set_consistent_dma_mask(dev, mask) (0)
5505 +#endif
5506 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
5507 +#define pci_dma_sync_single_for_cpu pci_dma_sync_single
5508 +#endif
5510 +#ifndef DMA_32BIT_MASK
5511 +#define DMA_32BIT_MASK  0x00000000ffffffffULL
5512 +#endif
5514 +#ifndef htole32
5515 +#define htole32(x)     cpu_to_le32(x)
5516 +#endif
5517 +#ifndef htobe32
5518 +#define htobe32(x)     cpu_to_be32(x)
5519 +#endif
5520 +#ifndef htole16
5521 +#define htole16(x)     cpu_to_le16(x)
5522 +#endif
5523 +#ifndef htobe16
5524 +#define htobe16(x)     cpu_to_be16(x)
5525 +#endif
5527 +/* older kernels don't have these */
5529 +#include <asm/irq.h>
5530 +#if !defined(IRQ_NONE) && !defined(IRQ_RETVAL)
5531 +#define IRQ_NONE
5532 +#define IRQ_HANDLED
5533 +#define IRQ_WAKE_THREAD
5534 +#define IRQ_RETVAL
5535 +#define irqreturn_t void
5536 +typedef irqreturn_t (*irq_handler_t)(int irq, void *arg, struct pt_regs *regs);
5537 +#endif
5538 +#ifndef IRQF_SHARED
5539 +#define IRQF_SHARED    SA_SHIRQ
5540 +#endif
5542 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
5543 +# define strlcpy(dest,src,len) \
5544 +               ({strncpy(dest,src,(len)-1); ((char *)dest)[(len)-1] = '\0'; })
5545 +#endif
5547 +#ifndef MAX_ERRNO
5548 +#define MAX_ERRNO      4095
5549 +#endif
5550 +#ifndef IS_ERR_VALUE
5551 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,5)
5552 +#include <linux/err.h>
5553 +#endif
5554 +#ifndef IS_ERR_VALUE
5555 +#define IS_ERR_VALUE(x) ((unsigned long)(x) >= (unsigned long)-MAX_ERRNO)
5556 +#endif
5557 +#endif
5559 +/*
5560 + * common debug for all
5561 + */
5562 +#if 1
5563 +#define dprintk(a...)  do { if (debug) printk(a); } while(0)
5564 +#else
5565 +#define dprintk(a...)
5566 +#endif
5568 +#ifndef SLAB_ATOMIC
5569 +/* Changed in 2.6.20, must use GFP_ATOMIC now */
5570 +#define        SLAB_ATOMIC     GFP_ATOMIC
5571 +#endif
5573 +/*
5574 + * need some additional support for older kernels */
5575 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,2)
5576 +#define pci_register_driver_compat(driver, rc) \
5577 +       do { \
5578 +               if ((rc) > 0) { \
5579 +                       (rc) = 0; \
5580 +               } else if (rc == 0) { \
5581 +                       (rc) = -ENODEV; \
5582 +               } else { \
5583 +                       pci_unregister_driver(driver); \
5584 +               } \
5585 +       } while (0)
5586 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
5587 +#define pci_register_driver_compat(driver,rc) ((rc) = (rc) < 0 ? (rc) : 0)
5588 +#else
5589 +#define pci_register_driver_compat(driver,rc)
5590 +#endif
5592 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
5594 +#include <linux/mm.h>
5595 +#include <asm/scatterlist.h>
5597 +static inline void sg_set_page(struct scatterlist *sg,  struct page *page,
5598 +                              unsigned int len, unsigned int offset)
5599 +{
5600 +       sg->page = page;
5601 +       sg->offset = offset;
5602 +       sg->length = len;
5603 +}
5605 +static inline void *sg_virt(struct scatterlist *sg)
5606 +{
5607 +       return page_address(sg->page) + sg->offset;
5608 +}
5610 +#define sg_init_table(sg, n)
5612 +#endif
5614 +#ifndef late_initcall
5615 +#define late_initcall(init) module_init(init)
5616 +#endif
5618 +#endif /* __KERNEL__ */
5620 +/****************************************************************************/
5621 +#endif /* _BSD_COMPAT_H_ */
5622 diff --git a/crypto/ocf/random.c b/crypto/ocf/random.c
5623 new file mode 100644
5624 index 0000000..2088822
5625 --- /dev/null
5626 +++ b/crypto/ocf/random.c
5627 @@ -0,0 +1,322 @@
5628 +/*
5629 + * A system independant way of adding entropy to the kernels pool
5630 + * this way the drivers can focus on the real work and we can take
5631 + * care of pushing it to the appropriate place in the kernel.
5632 + *
5633 + * This should be fast and callable from timers/interrupts
5634 + *
5635 + * Written by David McCullough <david_mccullough@mcafee.com>
5636 + * Copyright (C) 2006-2010 David McCullough
5637 + * Copyright (C) 2004-2005 Intel Corporation.
5638 + *
5639 + * LICENSE TERMS
5640 + *
5641 + * The free distribution and use of this software in both source and binary
5642 + * form is allowed (with or without changes) provided that:
5643 + *
5644 + *   1. distributions of this source code include the above copyright
5645 + *      notice, this list of conditions and the following disclaimer;
5646 + *
5647 + *   2. distributions in binary form include the above copyright
5648 + *      notice, this list of conditions and the following disclaimer
5649 + *      in the documentation and/or other associated materials;
5650 + *
5651 + *   3. the copyright holder's name is not used to endorse products
5652 + *      built using this software without specific written permission.
5653 + *
5654 + * ALTERNATIVELY, provided that this notice is retained in full, this product
5655 + * may be distributed under the terms of the GNU General Public License (GPL),
5656 + * in which case the provisions of the GPL apply INSTEAD OF those given above.
5657 + *
5658 + * DISCLAIMER
5659 + *
5660 + * This software is provided 'as is' with no explicit or implied warranties
5661 + * in respect of its properties, including, but not limited to, correctness
5662 + * and/or fitness for purpose.
5663 + */
5665 +#ifndef AUTOCONF_INCLUDED
5666 +#include <linux/config.h>
5667 +#endif
5668 +#include <linux/module.h>
5669 +#include <linux/init.h>
5670 +#include <linux/list.h>
5671 +#include <linux/slab.h>
5672 +#include <linux/wait.h>
5673 +#include <linux/sched.h>
5674 +#include <linux/spinlock.h>
5675 +#include <linux/version.h>
5676 +#include <linux/unistd.h>
5677 +#include <linux/poll.h>
5678 +#include <linux/random.h>
5679 +#include <crypto/cryptodev.h>
5681 +#ifdef CONFIG_OCF_FIPS
5682 +#include "rndtest.h"
5683 +#endif
5685 +#ifndef HAS_RANDOM_INPUT_WAIT
5686 +#error "Please do not enable OCF_RANDOMHARVEST unless you have applied patches"
5687 +#endif
5689 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
5690 +#include <linux/sched.h>
5691 +#define        kill_proc(p,s,v)        send_sig(s,find_task_by_vpid(p),0)
5692 +#endif
5694 +/*
5695 + * a hack to access the debug levels from the crypto driver
5696 + */
5697 +extern int crypto_debug;
5698 +#define debug crypto_debug
5700 +/*
5701 + * a list of all registered random providers
5702 + */
5703 +static LIST_HEAD(random_ops);
5704 +static int started = 0;
5705 +static int initted = 0;
5707 +struct random_op {
5708 +       struct list_head random_list;
5709 +       u_int32_t driverid;
5710 +       int (*read_random)(void *arg, u_int32_t *buf, int len);
5711 +       void *arg;
5712 +};
5714 +static int random_proc(void *arg);
5716 +static pid_t           randomproc = (pid_t) -1;
5717 +static spinlock_t      random_lock;
5719 +/*
5720 + * just init the spin locks
5721 + */
5722 +static int
5723 +crypto_random_init(void)
5724 +{
5725 +       spin_lock_init(&random_lock);
5726 +       initted = 1;
5727 +       return(0);
5728 +}
5730 +/*
5731 + * Add the given random reader to our list (if not present)
5732 + * and start the thread (if not already started)
5733 + *
5734 + * we have to assume that driver id is ok for now
5735 + */
5736 +int
5737 +crypto_rregister(
5738 +       u_int32_t driverid,
5739 +       int (*read_random)(void *arg, u_int32_t *buf, int len),
5740 +       void *arg)
5741 +{
5742 +       unsigned long flags;
5743 +       int ret = 0;
5744 +       struct random_op        *rops, *tmp;
5746 +       dprintk("%s,%d: %s(0x%x, %p, %p)\n", __FILE__, __LINE__,
5747 +                       __FUNCTION__, driverid, read_random, arg);
5749 +       if (!initted)
5750 +               crypto_random_init();
5752 +#if 0
5753 +       struct cryptocap        *cap;
5755 +       cap = crypto_checkdriver(driverid);
5756 +       if (!cap)
5757 +               return EINVAL;
5758 +#endif
5760 +       list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
5761 +               if (rops->driverid == driverid && rops->read_random == read_random)
5762 +                       return EEXIST;
5763 +       }
5765 +       rops = (struct random_op *) kmalloc(sizeof(*rops), GFP_KERNEL);
5766 +       if (!rops)
5767 +               return ENOMEM;
5769 +       rops->driverid    = driverid;
5770 +       rops->read_random = read_random;
5771 +       rops->arg = arg;
5773 +       spin_lock_irqsave(&random_lock, flags);
5774 +       list_add_tail(&rops->random_list, &random_ops);
5775 +       if (!started) {
5776 +               randomproc = kernel_thread(random_proc, NULL, CLONE_FS|CLONE_FILES);
5777 +               if (randomproc < 0) {
5778 +                       ret = randomproc;
5779 +                       printk("crypto: crypto_rregister cannot start random thread; "
5780 +                                       "error %d", ret);
5781 +               } else
5782 +                       started = 1;
5783 +       }
5784 +       spin_unlock_irqrestore(&random_lock, flags);
5786 +       return ret;
5787 +}
5788 +EXPORT_SYMBOL(crypto_rregister);
5790 +int
5791 +crypto_runregister_all(u_int32_t driverid)
5792 +{
5793 +       struct random_op *rops, *tmp;
5794 +       unsigned long flags;
5796 +       dprintk("%s,%d: %s(0x%x)\n", __FILE__, __LINE__, __FUNCTION__, driverid);
5798 +       list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
5799 +               if (rops->driverid == driverid) {
5800 +                       list_del(&rops->random_list);
5801 +                       kfree(rops);
5802 +               }
5803 +       }
5805 +       spin_lock_irqsave(&random_lock, flags);
5806 +       if (list_empty(&random_ops) && started)
5807 +               kill_proc(randomproc, SIGKILL, 1);
5808 +       spin_unlock_irqrestore(&random_lock, flags);
5809 +       return(0);
5810 +}
5811 +EXPORT_SYMBOL(crypto_runregister_all);
5813 +/*
5814 + * while we can add entropy to random.c continue to read random data from
5815 + * the drivers and push it to random.
5816 + */
5817 +static int
5818 +random_proc(void *arg)
5819 +{
5820 +       int n;
5821 +       int wantcnt;
5822 +       int bufcnt = 0;
5823 +       int retval = 0;
5824 +       int *buf = NULL;
5826 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
5827 +       daemonize();
5828 +       spin_lock_irq(&current->sigmask_lock);
5829 +       sigemptyset(&current->blocked);
5830 +       recalc_sigpending(current);
5831 +       spin_unlock_irq(&current->sigmask_lock);
5832 +       sprintf(current->comm, "ocf-random");
5833 +#else
5834 +       daemonize("ocf-random");
5835 +       allow_signal(SIGKILL);
5836 +#endif
5838 +       (void) get_fs();
5839 +       set_fs(get_ds());
5841 +#ifdef CONFIG_OCF_FIPS
5842 +#define NUM_INT (RNDTEST_NBYTES/sizeof(int))
5843 +#else
5844 +#define NUM_INT 32
5845 +#endif
5847 +       /*
5848 +        * some devices can transferr their RNG data direct into memory,
5849 +        * so make sure it is device friendly
5850 +        */
5851 +       buf = kmalloc(NUM_INT * sizeof(int), GFP_DMA);
5852 +       if (NULL == buf) {
5853 +               printk("crypto: RNG could not allocate memory\n");
5854 +               retval = -ENOMEM;
5855 +               goto bad_alloc;
5856 +       }
5858 +       wantcnt = NUM_INT;   /* start by adding some entropy */
5860 +       /*
5861 +        * its possible due to errors or driver removal that we no longer
5862 +        * have anything to do,  if so exit or we will consume all the CPU
5863 +        * doing nothing
5864 +        */
5865 +       while (!list_empty(&random_ops)) {
5866 +               struct random_op        *rops, *tmp;
5868 +#ifdef CONFIG_OCF_FIPS
5869 +               if (wantcnt)
5870 +                       wantcnt = NUM_INT; /* FIPs mode can do 20000 bits or none */
5871 +#endif
5873 +               /* see if we can get enough entropy to make the world
5874 +                * a better place.
5875 +                */
5876 +               while (bufcnt < wantcnt && bufcnt < NUM_INT) {
5877 +                       list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
5879 +                               n = (*rops->read_random)(rops->arg, &buf[bufcnt],
5880 +                                                        NUM_INT - bufcnt);
5882 +                               /* on failure remove the random number generator */
5883 +                               if (n == -1) {
5884 +                                       list_del(&rops->random_list);
5885 +                                       printk("crypto: RNG (driverid=0x%x) failed, disabling\n",
5886 +                                                       rops->driverid);
5887 +                                       kfree(rops);
5888 +                               } else if (n > 0)
5889 +                                       bufcnt += n;
5890 +                       }
5891 +                       /* give up CPU for a bit, just in case as this is a loop */
5892 +                       schedule();
5893 +               }
5896 +#ifdef CONFIG_OCF_FIPS
5897 +               if (bufcnt > 0 && rndtest_buf((unsigned char *) &buf[0])) {
5898 +                       dprintk("crypto: buffer had fips errors, discarding\n");
5899 +                       bufcnt = 0;
5900 +               }
5901 +#endif
5903 +               /*
5904 +                * if we have a certified buffer,  we can send some data
5905 +                * to /dev/random and move along
5906 +                */
5907 +               if (bufcnt > 0) {
5908 +                       /* add what we have */
5909 +                       random_input_words(buf, bufcnt, bufcnt*sizeof(int)*8);
5910 +                       bufcnt = 0;
5911 +               }
5913 +               /* give up CPU for a bit so we don't hog while filling */
5914 +               schedule();
5916 +               /* wait for needing more */
5917 +               wantcnt = random_input_wait();
5919 +               if (wantcnt <= 0)
5920 +                       wantcnt = 0; /* try to get some info again */
5921 +               else
5922 +                       /* round up to one word or we can loop forever */
5923 +                       wantcnt = (wantcnt + (sizeof(int)*8)) / (sizeof(int)*8);
5924 +               if (wantcnt > NUM_INT) {
5925 +                       wantcnt = NUM_INT;
5926 +               }
5928 +               if (signal_pending(current)) {
5929 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
5930 +                       spin_lock_irq(&current->sigmask_lock);
5931 +#endif
5932 +                       flush_signals(current);
5933 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
5934 +                       spin_unlock_irq(&current->sigmask_lock);
5935 +#endif
5936 +               }
5937 +       }
5938 +       
5939 +       kfree(buf);
5941 +bad_alloc:
5942 +       spin_lock_irq(&random_lock);
5943 +       randomproc = (pid_t) -1;
5944 +       started = 0;
5945 +       spin_unlock_irq(&random_lock);
5947 +       return retval;
5948 +}
5950 diff --git a/crypto/ocf/rndtest.c b/crypto/ocf/rndtest.c
5951 new file mode 100644
5952 index 0000000..2295e9b
5953 --- /dev/null
5954 +++ b/crypto/ocf/rndtest.c
5955 @@ -0,0 +1,300 @@
5956 +/*     $OpenBSD$       */
5958 +/*
5959 + * OCF/Linux port done by David McCullough <david_mccullough@mcafee.com>
5960 + * Copyright (C) 2006-2010 David McCullough
5961 + * Copyright (C) 2004-2005 Intel Corporation.
5962 + * The license and original author are listed below.
5963 + *
5964 + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
5965 + * All rights reserved.
5966 + *
5967 + * Redistribution and use in source and binary forms, with or without
5968 + * modification, are permitted provided that the following conditions
5969 + * are met:
5970 + * 1. Redistributions of source code must retain the above copyright
5971 + *    notice, this list of conditions and the following disclaimer.
5972 + * 2. Redistributions in binary form must reproduce the above copyright
5973 + *    notice, this list of conditions and the following disclaimer in the
5974 + *    documentation and/or other materials provided with the distribution.
5975 + * 3. All advertising materials mentioning features or use of this software
5976 + *    must display the following acknowledgement:
5977 + *     This product includes software developed by Jason L. Wright
5978 + * 4. The name of the author may not be used to endorse or promote products
5979 + *    derived from this software without specific prior written permission.
5980 + *
5981 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
5982 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5983 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5984 + * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
5985 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5986 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
5987 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5988 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
5989 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
5990 + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
5991 + * POSSIBILITY OF SUCH DAMAGE.
5992 + */
5994 +#ifndef AUTOCONF_INCLUDED
5995 +#include <linux/config.h>
5996 +#endif
5997 +#include <linux/module.h>
5998 +#include <linux/list.h>
5999 +#include <linux/wait.h>
6000 +#include <linux/time.h>
6001 +#include <linux/version.h>
6002 +#include <linux/unistd.h>
6003 +#include <linux/kernel.h>
6004 +#include <linux/string.h>
6005 +#include <linux/time.h>
6006 +#include <crypto/cryptodev.h>
6007 +#include "rndtest.h"
6009 +static struct rndtest_stats rndstats;
6011 +static void rndtest_test(struct rndtest_state *);
6013 +/* The tests themselves */
6014 +static int rndtest_monobit(struct rndtest_state *);
6015 +static int rndtest_runs(struct rndtest_state *);
6016 +static int rndtest_longruns(struct rndtest_state *);
6017 +static int rndtest_chi_4(struct rndtest_state *);
6019 +static int rndtest_runs_check(struct rndtest_state *, int, int *);
6020 +static void rndtest_runs_record(struct rndtest_state *, int, int *);
6022 +static const struct rndtest_testfunc {
6023 +       int (*test)(struct rndtest_state *);
6024 +} rndtest_funcs[] = {
6025 +       { rndtest_monobit },
6026 +       { rndtest_runs },
6027 +       { rndtest_chi_4 },
6028 +       { rndtest_longruns },
6029 +};
6031 +#define        RNDTEST_NTESTS  (sizeof(rndtest_funcs)/sizeof(rndtest_funcs[0]))
6033 +static void
6034 +rndtest_test(struct rndtest_state *rsp)
6035 +{
6036 +       int i, rv = 0;
6038 +       rndstats.rst_tests++;
6039 +       for (i = 0; i < RNDTEST_NTESTS; i++)
6040 +               rv |= (*rndtest_funcs[i].test)(rsp);
6041 +       rsp->rs_discard = (rv != 0);
6042 +}
6045 +extern int crypto_debug;
6046 +#define rndtest_verbose 2
6047 +#define rndtest_report(rsp, failure, fmt, a...) \
6048 +       { if (failure || crypto_debug) { printk("rng_test: " fmt "\n", a); } else; }
6050 +#define        RNDTEST_MONOBIT_MINONES 9725
6051 +#define        RNDTEST_MONOBIT_MAXONES 10275
6053 +static int
6054 +rndtest_monobit(struct rndtest_state *rsp)
6055 +{
6056 +       int i, ones = 0, j;
6057 +       u_int8_t r;
6059 +       for (i = 0; i < RNDTEST_NBYTES; i++) {
6060 +               r = rsp->rs_buf[i];
6061 +               for (j = 0; j < 8; j++, r <<= 1)
6062 +                       if (r & 0x80)
6063 +                               ones++;
6064 +       }
6065 +       if (ones > RNDTEST_MONOBIT_MINONES &&
6066 +           ones < RNDTEST_MONOBIT_MAXONES) {
6067 +               if (rndtest_verbose > 1)
6068 +                       rndtest_report(rsp, 0, "monobit pass (%d < %d < %d)",
6069 +                           RNDTEST_MONOBIT_MINONES, ones,
6070 +                           RNDTEST_MONOBIT_MAXONES);
6071 +               return (0);
6072 +       } else {
6073 +               if (rndtest_verbose)
6074 +                       rndtest_report(rsp, 1,
6075 +                           "monobit failed (%d ones)", ones);
6076 +               rndstats.rst_monobit++;
6077 +               return (-1);
6078 +       }
6079 +}
6081 +#define        RNDTEST_RUNS_NINTERVAL  6
6083 +static const struct rndtest_runs_tabs {
6084 +       u_int16_t min, max;
6085 +} rndtest_runs_tab[] = {
6086 +       { 2343, 2657 },
6087 +       { 1135, 1365 },
6088 +       { 542, 708 },
6089 +       { 251, 373 },
6090 +       { 111, 201 },
6091 +       { 111, 201 },
6092 +};
6094 +static int
6095 +rndtest_runs(struct rndtest_state *rsp)
6096 +{
6097 +       int i, j, ones, zeros, rv = 0;
6098 +       int onei[RNDTEST_RUNS_NINTERVAL], zeroi[RNDTEST_RUNS_NINTERVAL];
6099 +       u_int8_t c;
6101 +       bzero(onei, sizeof(onei));
6102 +       bzero(zeroi, sizeof(zeroi));
6103 +       ones = zeros = 0;
6104 +       for (i = 0; i < RNDTEST_NBYTES; i++) {
6105 +               c = rsp->rs_buf[i];
6106 +               for (j = 0; j < 8; j++, c <<= 1) {
6107 +                       if (c & 0x80) {
6108 +                               ones++;
6109 +                               rndtest_runs_record(rsp, zeros, zeroi);
6110 +                               zeros = 0;
6111 +                       } else {
6112 +                               zeros++;
6113 +                               rndtest_runs_record(rsp, ones, onei);
6114 +                               ones = 0;
6115 +                       }
6116 +               }
6117 +       }
6118 +       rndtest_runs_record(rsp, ones, onei);
6119 +       rndtest_runs_record(rsp, zeros, zeroi);
6121 +       rv |= rndtest_runs_check(rsp, 0, zeroi);
6122 +       rv |= rndtest_runs_check(rsp, 1, onei);
6124 +       if (rv)
6125 +               rndstats.rst_runs++;
6127 +       return (rv);
6128 +}
6130 +static void
6131 +rndtest_runs_record(struct rndtest_state *rsp, int len, int *intrv)
6132 +{
6133 +       if (len == 0)
6134 +               return;
6135 +       if (len > RNDTEST_RUNS_NINTERVAL)
6136 +               len = RNDTEST_RUNS_NINTERVAL;
6137 +       len -= 1;
6138 +       intrv[len]++;
6139 +}
6141 +static int
6142 +rndtest_runs_check(struct rndtest_state *rsp, int val, int *src)
6143 +{
6144 +       int i, rv = 0;
6146 +       for (i = 0; i < RNDTEST_RUNS_NINTERVAL; i++) {
6147 +               if (src[i] < rndtest_runs_tab[i].min ||
6148 +                   src[i] > rndtest_runs_tab[i].max) {
6149 +                       rndtest_report(rsp, 1,
6150 +                           "%s interval %d failed (%d, %d-%d)",
6151 +                           val ? "ones" : "zeros",
6152 +                           i + 1, src[i], rndtest_runs_tab[i].min,
6153 +                           rndtest_runs_tab[i].max);
6154 +                       rv = -1;
6155 +               } else {
6156 +                       rndtest_report(rsp, 0,
6157 +                           "runs pass %s interval %d (%d < %d < %d)",
6158 +                           val ? "ones" : "zeros",
6159 +                           i + 1, rndtest_runs_tab[i].min, src[i],
6160 +                           rndtest_runs_tab[i].max);
6161 +               }
6162 +       }
6163 +       return (rv);
6164 +}
6166 +static int
6167 +rndtest_longruns(struct rndtest_state *rsp)
6168 +{
6169 +       int i, j, ones = 0, zeros = 0, maxones = 0, maxzeros = 0;
6170 +       u_int8_t c;
6172 +       for (i = 0; i < RNDTEST_NBYTES; i++) {
6173 +               c = rsp->rs_buf[i];
6174 +               for (j = 0; j < 8; j++, c <<= 1) {
6175 +                       if (c & 0x80) {
6176 +                               zeros = 0;
6177 +                               ones++;
6178 +                               if (ones > maxones)
6179 +                                       maxones = ones;
6180 +                       } else {
6181 +                               ones = 0;
6182 +                               zeros++;
6183 +                               if (zeros > maxzeros)
6184 +                                       maxzeros = zeros;
6185 +                       }
6186 +               }
6187 +       }
6189 +       if (maxones < 26 && maxzeros < 26) {
6190 +               rndtest_report(rsp, 0, "longruns pass (%d ones, %d zeros)",
6191 +                       maxones, maxzeros);
6192 +               return (0);
6193 +       } else {
6194 +               rndtest_report(rsp, 1, "longruns fail (%d ones, %d zeros)",
6195 +                       maxones, maxzeros);
6196 +               rndstats.rst_longruns++;
6197 +               return (-1);
6198 +       }
6199 +}
6201 +/*
6202 + * chi^2 test over 4 bits: (this is called the poker test in FIPS 140-2,
6203 + * but it is really the chi^2 test over 4 bits (the poker test as described
6204 + * by Knuth vol 2 is something different, and I take him as authoritative
6205 + * on nomenclature over NIST).
6206 + */
6207 +#define        RNDTEST_CHI4_K  16
6208 +#define        RNDTEST_CHI4_K_MASK     (RNDTEST_CHI4_K - 1)
6210 +/*
6211 + * The unnormalized values are used so that we don't have to worry about
6212 + * fractional precision.  The "real" value is found by:
6213 + *     (V - 1562500) * (16 / 5000) = Vn   (where V is the unnormalized value)
6214 + */
6215 +#define        RNDTEST_CHI4_VMIN       1563181         /* 2.1792 */
6216 +#define        RNDTEST_CHI4_VMAX       1576929         /* 46.1728 */
6218 +static int
6219 +rndtest_chi_4(struct rndtest_state *rsp)
6220 +{
6221 +       unsigned int freq[RNDTEST_CHI4_K], i, sum;
6223 +       for (i = 0; i < RNDTEST_CHI4_K; i++)
6224 +               freq[i] = 0;
6226 +       /* Get number of occurances of each 4 bit pattern */
6227 +       for (i = 0; i < RNDTEST_NBYTES; i++) {
6228 +               freq[(rsp->rs_buf[i] >> 4) & RNDTEST_CHI4_K_MASK]++;
6229 +               freq[(rsp->rs_buf[i] >> 0) & RNDTEST_CHI4_K_MASK]++;
6230 +       }
6232 +       for (i = 0, sum = 0; i < RNDTEST_CHI4_K; i++)
6233 +               sum += freq[i] * freq[i];
6235 +       if (sum >= 1563181 && sum <= 1576929) {
6236 +               rndtest_report(rsp, 0, "chi^2(4): pass (sum %u)", sum);
6237 +               return (0);
6238 +       } else {
6239 +               rndtest_report(rsp, 1, "chi^2(4): failed (sum %u)", sum);
6240 +               rndstats.rst_chi++;
6241 +               return (-1);
6242 +       }
6243 +}
6245 +int
6246 +rndtest_buf(unsigned char *buf)
6247 +{
6248 +       struct rndtest_state rsp;
6250 +       memset(&rsp, 0, sizeof(rsp));
6251 +       rsp.rs_buf = buf;
6252 +       rndtest_test(&rsp);
6253 +       return(rsp.rs_discard);
6254 +}
6256 diff --git a/crypto/ocf/rndtest.h b/crypto/ocf/rndtest.h
6257 new file mode 100644
6258 index 0000000..e9d8ec8
6259 --- /dev/null
6260 +++ b/crypto/ocf/rndtest.h
6261 @@ -0,0 +1,54 @@
6262 +/*     $FreeBSD: src/sys/dev/rndtest/rndtest.h,v 1.1 2003/03/11 22:54:44 sam Exp $     */
6263 +/*     $OpenBSD$       */
6265 +/*
6266 + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
6267 + * All rights reserved.
6268 + *
6269 + * Redistribution and use in source and binary forms, with or without
6270 + * modification, are permitted provided that the following conditions
6271 + * are met:
6272 + * 1. Redistributions of source code must retain the above copyright
6273 + *    notice, this list of conditions and the following disclaimer.
6274 + * 2. Redistributions in binary form must reproduce the above copyright
6275 + *    notice, this list of conditions and the following disclaimer in the
6276 + *    documentation and/or other materials provided with the distribution.
6277 + * 3. All advertising materials mentioning features or use of this software
6278 + *    must display the following acknowledgement:
6279 + *     This product includes software developed by Jason L. Wright
6280 + * 4. The name of the author may not be used to endorse or promote products
6281 + *    derived from this software without specific prior written permission.
6282 + *
6283 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
6284 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6285 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6286 + * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
6287 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6288 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
6289 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
6290 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
6291 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
6292 + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
6293 + * POSSIBILITY OF SUCH DAMAGE.
6294 + */
6297 +/* Some of the tests depend on these values */
6298 +#define        RNDTEST_NBYTES  2500
6299 +#define        RNDTEST_NBITS   (8 * RNDTEST_NBYTES)
6301 +struct rndtest_state {
6302 +       int             rs_discard;     /* discard/accept random data */
6303 +       u_int8_t        *rs_buf;
6304 +};
6306 +struct rndtest_stats {
6307 +       u_int32_t       rst_discard;    /* number of bytes discarded */
6308 +       u_int32_t       rst_tests;      /* number of test runs */
6309 +       u_int32_t       rst_monobit;    /* monobit test failures */
6310 +       u_int32_t       rst_runs;       /* 0/1 runs failures */
6311 +       u_int32_t       rst_longruns;   /* longruns failures */
6312 +       u_int32_t       rst_chi;        /* chi^2 failures */
6313 +};
6315 +extern int rndtest_buf(unsigned char *buf);
6316 diff --git a/crypto/ocf/uio.h b/crypto/ocf/uio.h
6317 new file mode 100644
6318 index 0000000..03a6249
6319 --- /dev/null
6320 +++ b/crypto/ocf/uio.h
6321 @@ -0,0 +1,54 @@
6322 +#ifndef _OCF_UIO_H_
6323 +#define _OCF_UIO_H_
6325 +#include <linux/uio.h>
6327 +/*
6328 + * The linux uio.h doesn't have all we need.  To be fully api compatible
6329 + * with the BSD cryptodev,  we need to keep this around.  Perhaps this can
6330 + * be moved back into the linux/uio.h
6331 + *
6332 + * Linux port done by David McCullough <david_mccullough@mcafee.com>
6333 + * Copyright (C) 2006-2010 David McCullough
6334 + * Copyright (C) 2004-2005 Intel Corporation.
6335 + *
6336 + * LICENSE TERMS
6337 + *
6338 + * The free distribution and use of this software in both source and binary
6339 + * form is allowed (with or without changes) provided that:
6340 + *
6341 + *   1. distributions of this source code include the above copyright
6342 + *      notice, this list of conditions and the following disclaimer;
6343 + *
6344 + *   2. distributions in binary form include the above copyright
6345 + *      notice, this list of conditions and the following disclaimer
6346 + *      in the documentation and/or other associated materials;
6347 + *
6348 + *   3. the copyright holder's name is not used to endorse products
6349 + *      built using this software without specific written permission.
6350 + *
6351 + * ALTERNATIVELY, provided that this notice is retained in full, this product
6352 + * may be distributed under the terms of the GNU General Public License (GPL),
6353 + * in which case the provisions of the GPL apply INSTEAD OF those given above.
6354 + *
6355 + * DISCLAIMER
6356 + *
6357 + * This software is provided 'as is' with no explicit or implied warranties
6358 + * in respect of its properties, including, but not limited to, correctness
6359 + * and/or fitness for purpose.
6360 + * ---------------------------------------------------------------------------
6361 + */
6363 +struct uio {
6364 +       struct  iovec *uio_iov;
6365 +       int             uio_iovcnt;
6366 +       off_t   uio_offset;
6367 +       int             uio_resid;
6368 +#if 0
6369 +       enum    uio_seg uio_segflg;
6370 +       enum    uio_rw uio_rw;
6371 +       struct  thread *uio_td;
6372 +#endif
6373 +};
6375 +#endif
6376 diff --git a/drivers/char/random.c b/drivers/char/random.c
6377 index 5a1aa64..0554f18 100644
6378 --- a/drivers/char/random.c
6379 +++ b/drivers/char/random.c
6380 @@ -129,6 +129,9 @@
6381   *                                unsigned int value);
6382   *     void add_interrupt_randomness(int irq);
6383   *
6384 + *      void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
6385 + *      int random_input_wait(void);
6386 + *
6387   * add_input_randomness() uses the input layer interrupt timing, as well as
6388   * the event type information from the hardware.
6389   *
6390 @@ -140,6 +143,13 @@
6391   * a better measure, since the timing of the disk interrupts are more
6392   * unpredictable.
6393   *
6394 + * random_input_words() just provides a raw block of entropy to the input
6395 + * pool, such as from a hardware entropy generator.
6396 + *
6397 + * random_input_wait() suspends the caller until such time as the
6398 + * entropy pool falls below the write threshold, and returns a count of how
6399 + * much entropy (in bits) is needed to sustain the pool.
6400 + *
6401   * All of these routines try to estimate how many bits of randomness a
6402   * particular randomness source.  They do this by keeping track of the
6403   * first and second order deltas of the event timings.
6404 @@ -715,6 +725,61 @@ void add_disk_randomness(struct gendisk *disk)
6405  }
6406  #endif
6407  
6408 +/*
6409 + * random_input_words - add bulk entropy to pool
6410 + *
6411 + * @buf: buffer to add
6412 + * @wordcount: number of __u32 words to add
6413 + * @ent_count: total amount of entropy (in bits) to credit
6414 + *
6415 + * this provides bulk input of entropy to the input pool
6416 + *
6417 + */
6418 +void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
6419 +{
6420 +       mix_pool_bytes(&input_pool, buf, wordcount*4);
6422 +       credit_entropy_bits(&input_pool, ent_count);
6424 +       DEBUG_ENT("crediting %d bits => %d\n",
6425 +                 ent_count, input_pool.entropy_count);
6426 +       /*
6427 +        * Wake up waiting processes if we have enough
6428 +        * entropy.
6429 +        */
6430 +       if (input_pool.entropy_count >= random_read_wakeup_thresh)
6431 +               wake_up_interruptible(&random_read_wait);
6432 +}
6433 +EXPORT_SYMBOL(random_input_words);
6435 +/*
6436 + * random_input_wait - wait until random needs entropy
6437 + *
6438 + * this function sleeps until the /dev/random subsystem actually
6439 + * needs more entropy, and then return the amount of entropy
6440 + * that it would be nice to have added to the system.
6441 + */
6442 +int random_input_wait(void)
6443 +{
6444 +       int count;
6446 +       wait_event_interruptible(random_write_wait, 
6447 +                        input_pool.entropy_count < random_write_wakeup_thresh);
6449 +       count = random_write_wakeup_thresh - input_pool.entropy_count;
6451 +        /* likely we got woken up due to a signal */
6452 +       if (count <= 0) count = random_read_wakeup_thresh; 
6454 +       DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
6455 +                 count,
6456 +                 input_pool.entropy_count, random_write_wakeup_thresh);
6458 +       return count;
6459 +}
6460 +EXPORT_SYMBOL(random_input_wait);
6463  /*********************************************************************
6464   *
6465   * Entropy extraction routines
6466 diff --git a/fs/fcntl.c b/fs/fcntl.c
6467 index ecc8b39..1b1dcfb 100644
6468 --- a/fs/fcntl.c
6469 +++ b/fs/fcntl.c
6470 @@ -142,6 +142,7 @@ SYSCALL_DEFINE1(dup, unsigned int, fildes)
6471         }
6472         return ret;
6473  }
6474 +EXPORT_SYMBOL(sys_dup);
6475  
6476  #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
6477  
6478 diff --git a/include/crypto/cryptodev.h b/include/crypto/cryptodev.h
6479 new file mode 100644
6480 index 0000000..6032317
6481 --- /dev/null
6482 +++ b/include/crypto/cryptodev.h
6483 @@ -0,0 +1,479 @@
6484 +/*     $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.25 2007/05/09 19:37:02 gnn Exp $   */
6485 +/*     $OpenBSD: cryptodev.h,v 1.31 2002/06/11 11:14:29 beck Exp $     */
6487 +/*-
6488 + * Linux port done by David McCullough <david_mccullough@mcafee.com>
6489 + * Copyright (C) 2006-2010 David McCullough
6490 + * Copyright (C) 2004-2005 Intel Corporation.
6491 + * The license and original author are listed below.
6492 + *
6493 + * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
6494 + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
6495 + *
6496 + * This code was written by Angelos D. Keromytis in Athens, Greece, in
6497 + * February 2000. Network Security Technologies Inc. (NSTI) kindly
6498 + * supported the development of this code.
6499 + *
6500 + * Copyright (c) 2000 Angelos D. Keromytis
6501 + *
6502 + * Permission to use, copy, and modify this software with or without fee
6503 + * is hereby granted, provided that this entire notice is included in
6504 + * all source code copies of any software which is or includes a copy or
6505 + * modification of this software.
6506 + *
6507 + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
6508 + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
6509 + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
6510 + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
6511 + * PURPOSE.
6512 + *
6513 + * Copyright (c) 2001 Theo de Raadt
6514 + *
6515 + * Redistribution and use in source and binary forms, with or without
6516 + * modification, are permitted provided that the following conditions
6517 + * are met:
6518 + *
6519 + * 1. Redistributions of source code must retain the above copyright
6520 + *   notice, this list of conditions and the following disclaimer.
6521 + * 2. Redistributions in binary form must reproduce the above copyright
6522 + *   notice, this list of conditions and the following disclaimer in the
6523 + *   documentation and/or other materials provided with the distribution.
6524 + * 3. The name of the author may not be used to endorse or promote products
6525 + *   derived from this software without specific prior written permission.
6526 + *
6527 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
6528 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
6529 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
6530 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
6531 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
6532 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
6533 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
6534 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6535 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
6536 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6537 + *
6538 + * Effort sponsored in part by the Defense Advanced Research Projects
6539 + * Agency (DARPA) and Air Force Research Laboratory, Air Force
6540 + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
6541 + *
6542 + */
6544 +#ifndef _CRYPTO_CRYPTO_H_
6545 +#define _CRYPTO_CRYPTO_H_
6547 +/* Some initial values */
6548 +#define CRYPTO_DRIVERS_INITIAL 4
6549 +#define CRYPTO_SW_SESSIONS     32
6551 +/* Hash values */
6552 +#define NULL_HASH_LEN          0
6553 +#define MD5_HASH_LEN           16
6554 +#define SHA1_HASH_LEN          20
6555 +#define RIPEMD160_HASH_LEN     20
6556 +#define SHA2_256_HASH_LEN      32
6557 +#define SHA2_384_HASH_LEN      48
6558 +#define SHA2_512_HASH_LEN      64
6559 +#define MD5_KPDK_HASH_LEN      16
6560 +#define SHA1_KPDK_HASH_LEN     20
6561 +/* Maximum hash algorithm result length */
6562 +#define HASH_MAX_LEN           SHA2_512_HASH_LEN /* Keep this updated */
6564 +/* HMAC values */
6565 +#define NULL_HMAC_BLOCK_LEN                    1
6566 +#define MD5_HMAC_BLOCK_LEN                     64
6567 +#define SHA1_HMAC_BLOCK_LEN                    64
6568 +#define RIPEMD160_HMAC_BLOCK_LEN       64
6569 +#define SHA2_256_HMAC_BLOCK_LEN                64
6570 +#define SHA2_384_HMAC_BLOCK_LEN                128
6571 +#define SHA2_512_HMAC_BLOCK_LEN                128
6572 +/* Maximum HMAC block length */
6573 +#define HMAC_MAX_BLOCK_LEN             SHA2_512_HMAC_BLOCK_LEN /* Keep this updated */
6574 +#define HMAC_IPAD_VAL                  0x36
6575 +#define HMAC_OPAD_VAL                  0x5C
6577 +/* Encryption algorithm block sizes */
6578 +#define NULL_BLOCK_LEN                 1
6579 +#define DES_BLOCK_LEN                  8
6580 +#define DES3_BLOCK_LEN                 8
6581 +#define BLOWFISH_BLOCK_LEN             8
6582 +#define SKIPJACK_BLOCK_LEN             8
6583 +#define CAST128_BLOCK_LEN              8
6584 +#define RIJNDAEL128_BLOCK_LEN  16
6585 +#define AES_BLOCK_LEN                  RIJNDAEL128_BLOCK_LEN
6586 +#define CAMELLIA_BLOCK_LEN             16
6587 +#define ARC4_BLOCK_LEN                 1
6588 +#define EALG_MAX_BLOCK_LEN             AES_BLOCK_LEN /* Keep this updated */
6590 +/* Encryption algorithm min and max key sizes */
6591 +#define NULL_MIN_KEY_LEN               0
6592 +#define NULL_MAX_KEY_LEN               0
6593 +#define DES_MIN_KEY_LEN                        8
6594 +#define DES_MAX_KEY_LEN                        8
6595 +#define DES3_MIN_KEY_LEN               24
6596 +#define DES3_MAX_KEY_LEN               24
6597 +#define BLOWFISH_MIN_KEY_LEN   4
6598 +#define BLOWFISH_MAX_KEY_LEN   56
6599 +#define SKIPJACK_MIN_KEY_LEN   10
6600 +#define SKIPJACK_MAX_KEY_LEN   10
6601 +#define CAST128_MIN_KEY_LEN            5
6602 +#define CAST128_MAX_KEY_LEN            16
6603 +#define RIJNDAEL128_MIN_KEY_LEN        16
6604 +#define RIJNDAEL128_MAX_KEY_LEN        32
6605 +#define AES_MIN_KEY_LEN                        RIJNDAEL128_MIN_KEY_LEN
6606 +#define AES_MAX_KEY_LEN                        RIJNDAEL128_MAX_KEY_LEN
6607 +#define CAMELLIA_MIN_KEY_LEN   16
6608 +#define CAMELLIA_MAX_KEY_LEN   32
6609 +#define ARC4_MIN_KEY_LEN               1
6610 +#define ARC4_MAX_KEY_LEN               256
6612 +/* Max size of data that can be processed */
6613 +#define CRYPTO_MAX_DATA_LEN            64*1024 - 1
6615 +#define CRYPTO_ALGORITHM_MIN   1
6616 +#define CRYPTO_DES_CBC                 1
6617 +#define CRYPTO_3DES_CBC                        2
6618 +#define CRYPTO_BLF_CBC                 3
6619 +#define CRYPTO_CAST_CBC                        4
6620 +#define CRYPTO_SKIPJACK_CBC            5
6621 +#define CRYPTO_MD5_HMAC                        6
6622 +#define CRYPTO_SHA1_HMAC               7
6623 +#define CRYPTO_RIPEMD160_HMAC  8
6624 +#define CRYPTO_MD5_KPDK                        9
6625 +#define CRYPTO_SHA1_KPDK               10
6626 +#define CRYPTO_RIJNDAEL128_CBC 11 /* 128 bit blocksize */
6627 +#define CRYPTO_AES_CBC                 11 /* 128 bit blocksize -- the same as above */
6628 +#define CRYPTO_ARC4                            12
6629 +#define CRYPTO_MD5                             13
6630 +#define CRYPTO_SHA1                            14
6631 +#define CRYPTO_NULL_HMAC               15
6632 +#define CRYPTO_NULL_CBC                        16
6633 +#define CRYPTO_DEFLATE_COMP            17 /* Deflate compression algorithm */
6634 +#define CRYPTO_SHA2_256_HMAC   18
6635 +#define CRYPTO_SHA2_384_HMAC   19
6636 +#define CRYPTO_SHA2_512_HMAC   20
6637 +#define CRYPTO_CAMELLIA_CBC            21
6638 +#define CRYPTO_SHA2_256                        22
6639 +#define CRYPTO_SHA2_384                        23
6640 +#define CRYPTO_SHA2_512                        24
6641 +#define CRYPTO_RIPEMD160               25
6642 +#define CRYPTO_ALGORITHM_MAX   25 /* Keep updated - see below */
6644 +/* Algorithm flags */
6645 +#define CRYPTO_ALG_FLAG_SUPPORTED      0x01 /* Algorithm is supported */
6646 +#define CRYPTO_ALG_FLAG_RNG_ENABLE     0x02 /* Has HW RNG for DH/DSA */
6647 +#define CRYPTO_ALG_FLAG_DSA_SHA                0x04 /* Can do SHA on msg */
6649 +/*
6650 + * Crypto driver/device flags.  They can set in the crid
6651 + * parameter when creating a session or submitting a key
6652 + * op to affect the device/driver assigned.  If neither
6653 + * of these are specified then the crid is assumed to hold
6654 + * the driver id of an existing (and suitable) device that
6655 + * must be used to satisfy the request.
6656 + */
6657 +#define CRYPTO_FLAG_HARDWARE   0x01000000      /* hardware accelerated */
6658 +#define CRYPTO_FLAG_SOFTWARE   0x02000000      /* software implementation */
6660 +/* NB: deprecated */
6661 +struct session_op {
6662 +       u_int32_t       cipher;         /* ie. CRYPTO_DES_CBC */
6663 +       u_int32_t       mac;            /* ie. CRYPTO_MD5_HMAC */
6665 +       u_int32_t       keylen;         /* cipher key */
6666 +       caddr_t         key;
6667 +       int             mackeylen;      /* mac key */
6668 +       caddr_t         mackey;
6670 +       u_int32_t       ses;            /* returns: session # */ 
6671 +};
6673 +struct session2_op {
6674 +       u_int32_t       cipher;         /* ie. CRYPTO_DES_CBC */
6675 +       u_int32_t       mac;            /* ie. CRYPTO_MD5_HMAC */
6677 +       u_int32_t       keylen;         /* cipher key */
6678 +       caddr_t         key;
6679 +       int             mackeylen;      /* mac key */
6680 +       caddr_t         mackey;
6682 +       u_int32_t       ses;            /* returns: session # */ 
6683 +       int             crid;           /* driver id + flags (rw) */
6684 +       int             pad[4];         /* for future expansion */
6685 +};
6687 +struct crypt_op {
6688 +       u_int32_t       ses;
6689 +       u_int16_t       op;             /* i.e. COP_ENCRYPT */
6690 +#define COP_NONE       0
6691 +#define COP_ENCRYPT    1
6692 +#define COP_DECRYPT    2
6693 +       u_int16_t       flags;
6694 +#define        COP_F_BATCH     0x0008          /* Batch op if possible */
6695 +       u_int           len;
6696 +       caddr_t         src, dst;       /* become iov[] inside kernel */
6697 +       caddr_t         mac;            /* must be big enough for chosen MAC */
6698 +       caddr_t         iv;
6699 +};
6701 +/*
6702 + * Parameters for looking up a crypto driver/device by
6703 + * device name or by id.  The latter are returned for
6704 + * created sessions (crid) and completed key operations.
6705 + */
6706 +struct crypt_find_op {
6707 +       int             crid;           /* driver id + flags */
6708 +       char            name[32];       /* device/driver name */
6709 +};
6711 +/* bignum parameter, in packed bytes, ... */
6712 +struct crparam {
6713 +       caddr_t         crp_p;
6714 +       u_int           crp_nbits;
6715 +};
6717 +#define CRK_MAXPARAM   8
6719 +struct crypt_kop {
6720 +       u_int           crk_op;         /* ie. CRK_MOD_EXP or other */
6721 +       u_int           crk_status;     /* return status */
6722 +       u_short         crk_iparams;    /* # of input parameters */
6723 +       u_short         crk_oparams;    /* # of output parameters */
6724 +       u_int           crk_crid;       /* NB: only used by CIOCKEY2 (rw) */
6725 +       struct crparam  crk_param[CRK_MAXPARAM];
6726 +};
6727 +#define CRK_ALGORITM_MIN       0
6728 +#define CRK_MOD_EXP            0
6729 +#define CRK_MOD_EXP_CRT                1
6730 +#define CRK_DSA_SIGN           2
6731 +#define CRK_DSA_VERIFY         3
6732 +#define CRK_DH_COMPUTE_KEY     4
6733 +#define CRK_ALGORITHM_MAX      4 /* Keep updated - see below */
6735 +#define CRF_MOD_EXP            (1 << CRK_MOD_EXP)
6736 +#define CRF_MOD_EXP_CRT                (1 << CRK_MOD_EXP_CRT)
6737 +#define CRF_DSA_SIGN           (1 << CRK_DSA_SIGN)
6738 +#define CRF_DSA_VERIFY         (1 << CRK_DSA_VERIFY)
6739 +#define CRF_DH_COMPUTE_KEY     (1 << CRK_DH_COMPUTE_KEY)
6741 +/*
6742 + * done against open of /dev/crypto, to get a cloned descriptor.
6743 + * Please use F_SETFD against the cloned descriptor.
6744 + */
6745 +#define CRIOGET                _IOWR('c', 100, u_int32_t)
6746 +#define CRIOASYMFEAT   CIOCASYMFEAT
6747 +#define CRIOFINDDEV    CIOCFINDDEV
6749 +/* the following are done against the cloned descriptor */
6750 +#define CIOCGSESSION   _IOWR('c', 101, struct session_op)
6751 +#define CIOCFSESSION   _IOW('c', 102, u_int32_t)
6752 +#define CIOCCRYPT      _IOWR('c', 103, struct crypt_op)
6753 +#define CIOCKEY                _IOWR('c', 104, struct crypt_kop)
6754 +#define CIOCASYMFEAT   _IOR('c', 105, u_int32_t)
6755 +#define CIOCGSESSION2  _IOWR('c', 106, struct session2_op)
6756 +#define CIOCKEY2       _IOWR('c', 107, struct crypt_kop)
6757 +#define CIOCFINDDEV    _IOWR('c', 108, struct crypt_find_op)
6759 +struct cryptotstat {
6760 +       struct timespec acc;            /* total accumulated time */
6761 +       struct timespec min;            /* min time */
6762 +       struct timespec max;            /* max time */
6763 +       u_int32_t       count;          /* number of observations */
6764 +};
6766 +struct cryptostats {
6767 +       u_int32_t       cs_ops;         /* symmetric crypto ops submitted */
6768 +       u_int32_t       cs_errs;        /* symmetric crypto ops that failed */
6769 +       u_int32_t       cs_kops;        /* asymetric/key ops submitted */
6770 +       u_int32_t       cs_kerrs;       /* asymetric/key ops that failed */
6771 +       u_int32_t       cs_intrs;       /* crypto swi thread activations */
6772 +       u_int32_t       cs_rets;        /* crypto return thread activations */
6773 +       u_int32_t       cs_blocks;      /* symmetric op driver block */
6774 +       u_int32_t       cs_kblocks;     /* symmetric op driver block */
6775 +       /*
6776 +        * When CRYPTO_TIMING is defined at compile time and the
6777 +        * sysctl debug.crypto is set to 1, the crypto system will
6778 +        * accumulate statistics about how long it takes to process
6779 +        * crypto requests at various points during processing.
6780 +        */
6781 +       struct cryptotstat cs_invoke;   /* crypto_dipsatch -> crypto_invoke */
6782 +       struct cryptotstat cs_done;     /* crypto_invoke -> crypto_done */
6783 +       struct cryptotstat cs_cb;       /* crypto_done -> callback */
6784 +       struct cryptotstat cs_finis;    /* callback -> callback return */
6786 +       u_int32_t       cs_drops;               /* crypto ops dropped due to congestion */
6787 +};
6789 +#ifdef __KERNEL__
6791 +/* Standard initialization structure beginning */
6792 +struct cryptoini {
6793 +       int             cri_alg;        /* Algorithm to use */
6794 +       int             cri_klen;       /* Key length, in bits */
6795 +       int             cri_mlen;       /* Number of bytes we want from the
6796 +                                          entire hash. 0 means all. */
6797 +       caddr_t         cri_key;        /* key to use */
6798 +       u_int8_t        cri_iv[EALG_MAX_BLOCK_LEN];     /* IV to use */
6799 +       struct cryptoini *cri_next;
6800 +};
6802 +/* Describe boundaries of a single crypto operation */
6803 +struct cryptodesc {
6804 +       int             crd_skip;       /* How many bytes to ignore from start */
6805 +       int             crd_len;        /* How many bytes to process */
6806 +       int             crd_inject;     /* Where to inject results, if applicable */
6807 +       int             crd_flags;
6809 +#define CRD_F_ENCRYPT          0x01    /* Set when doing encryption */
6810 +#define CRD_F_IV_PRESENT       0x02    /* When encrypting, IV is already in
6811 +                                          place, so don't copy. */
6812 +#define CRD_F_IV_EXPLICIT      0x04    /* IV explicitly provided */
6813 +#define CRD_F_DSA_SHA_NEEDED   0x08    /* Compute SHA-1 of buffer for DSA */
6814 +#define CRD_F_KEY_EXPLICIT     0x10    /* Key explicitly provided */
6815 +#define CRD_F_COMP             0x0f    /* Set when doing compression */
6817 +       struct cryptoini        CRD_INI; /* Initialization/context data */
6818 +#define crd_iv         CRD_INI.cri_iv
6819 +#define crd_key                CRD_INI.cri_key
6820 +#define crd_alg                CRD_INI.cri_alg
6821 +#define crd_klen       CRD_INI.cri_klen
6822 +#define crd_mlen       CRD_INI.cri_mlen
6824 +       struct cryptodesc *crd_next;
6825 +};
6827 +/* Structure describing complete operation */
6828 +struct cryptop {
6829 +       struct list_head crp_next;
6830 +       wait_queue_head_t crp_waitq;
6832 +       u_int64_t       crp_sid;        /* Session ID */
6833 +       int             crp_ilen;       /* Input data total length */
6834 +       int             crp_olen;       /* Result total length */
6836 +       int             crp_etype;      /*
6837 +                                        * Error type (zero means no error).
6838 +                                        * All error codes except EAGAIN
6839 +                                        * indicate possible data corruption (as in,
6840 +                                        * the data have been touched). On all
6841 +                                        * errors, the crp_sid may have changed
6842 +                                        * (reset to a new one), so the caller
6843 +                                        * should always check and use the new
6844 +                                        * value on future requests.
6845 +                                        */
6846 +       int             crp_flags;
6848 +#define CRYPTO_F_SKBUF         0x0001  /* Input/output are skbuf chains */
6849 +#define CRYPTO_F_IOV           0x0002  /* Input/output are uio */
6850 +#define CRYPTO_F_REL           0x0004  /* Must return data in same place */
6851 +#define CRYPTO_F_BATCH         0x0008  /* Batch op if possible */
6852 +#define CRYPTO_F_CBIMM         0x0010  /* Do callback immediately */
6853 +#define CRYPTO_F_DONE          0x0020  /* Operation completed */
6854 +#define CRYPTO_F_CBIFSYNC      0x0040  /* Do CBIMM if op is synchronous */
6856 +       caddr_t         crp_buf;        /* Data to be processed */
6857 +       caddr_t         crp_opaque;     /* Opaque pointer, passed along */
6858 +       struct cryptodesc *crp_desc;    /* Linked list of processing descriptors */
6860 +       int (*crp_callback)(struct cryptop *); /* Callback function */
6861 +};
6863 +#define CRYPTO_BUF_CONTIG      0x0
6864 +#define CRYPTO_BUF_IOV         0x1
6865 +#define CRYPTO_BUF_SKBUF               0x2
6867 +#define CRYPTO_OP_DECRYPT      0x0
6868 +#define CRYPTO_OP_ENCRYPT      0x1
6870 +/*
6871 + * Hints passed to process methods.
6872 + */
6873 +#define CRYPTO_HINT_MORE       0x1     /* more ops coming shortly */
6875 +struct cryptkop {
6876 +       struct list_head krp_next;
6877 +       wait_queue_head_t krp_waitq;
6879 +       int             krp_flags;
6880 +#define CRYPTO_KF_DONE         0x0001  /* Operation completed */
6881 +#define CRYPTO_KF_CBIMM                0x0002  /* Do callback immediately */
6883 +       u_int           krp_op;         /* ie. CRK_MOD_EXP or other */
6884 +       u_int           krp_status;     /* return status */
6885 +       u_short         krp_iparams;    /* # of input parameters */
6886 +       u_short         krp_oparams;    /* # of output parameters */
6887 +       u_int           krp_crid;       /* desired device, etc. */
6888 +       u_int32_t       krp_hid;
6889 +       struct crparam  krp_param[CRK_MAXPARAM];        /* kvm */
6890 +       int             (*krp_callback)(struct cryptkop *);
6891 +};
6893 +#include <ocf-compat.h>
6895 +/*
6896 + * Session ids are 64 bits.  The lower 32 bits contain a "local id" which
6897 + * is a driver-private session identifier.  The upper 32 bits contain a
6898 + * "hardware id" used by the core crypto code to identify the driver and
6899 + * a copy of the driver's capabilities that can be used by client code to
6900 + * optimize operation.
6901 + */
6902 +#define CRYPTO_SESID2HID(_sid) (((_sid) >> 32) & 0x00ffffff)
6903 +#define CRYPTO_SESID2CAPS(_sid)        (((_sid) >> 32) & 0xff000000)
6904 +#define CRYPTO_SESID2LID(_sid) (((u_int32_t) (_sid)) & 0xffffffff)
6906 +extern int crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard);
6907 +extern int crypto_freesession(u_int64_t sid);
6908 +#define CRYPTOCAP_F_HARDWARE   CRYPTO_FLAG_HARDWARE
6909 +#define CRYPTOCAP_F_SOFTWARE   CRYPTO_FLAG_SOFTWARE
6910 +#define CRYPTOCAP_F_SYNC       0x04000000      /* operates synchronously */
6911 +extern int32_t crypto_get_driverid(device_t dev, int flags);
6912 +extern int crypto_find_driver(const char *);
6913 +extern device_t crypto_find_device_byhid(int hid);
6914 +extern int crypto_getcaps(int hid);
6915 +extern int crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
6916 +           u_int32_t flags);
6917 +extern int crypto_kregister(u_int32_t, int, u_int32_t);
6918 +extern int crypto_unregister(u_int32_t driverid, int alg);
6919 +extern int crypto_unregister_all(u_int32_t driverid);
6920 +extern int crypto_dispatch(struct cryptop *crp);
6921 +extern int crypto_kdispatch(struct cryptkop *);
6922 +#define CRYPTO_SYMQ    0x1
6923 +#define CRYPTO_ASYMQ   0x2
6924 +extern int crypto_unblock(u_int32_t, int);
6925 +extern void crypto_done(struct cryptop *crp);
6926 +extern void crypto_kdone(struct cryptkop *);
6927 +extern int crypto_getfeat(int *);
6929 +extern void crypto_freereq(struct cryptop *crp);
6930 +extern struct cryptop *crypto_getreq(int num);
6932 +extern  int crypto_usercrypto;      /* userland may do crypto requests */
6933 +extern  int crypto_userasymcrypto;  /* userland may do asym crypto reqs */
6934 +extern  int crypto_devallowsoft;    /* only use hardware crypto */
6936 +/*
6937 + * random number support,  crypto_unregister_all will unregister
6938 + */
6939 +extern int crypto_rregister(u_int32_t driverid,
6940 +               int (*read_random)(void *arg, u_int32_t *buf, int len), void *arg);
6941 +extern int crypto_runregister_all(u_int32_t driverid);
6943 +/*
6944 + * Crypto-related utility routines used mainly by drivers.
6945 + *
6946 + * XXX these don't really belong here; but for now they're
6947 + *     kept apart from the rest of the system.
6948 + */
6949 +struct uio;
6950 +extern void cuio_copydata(struct uio* uio, int off, int len, caddr_t cp);
6951 +extern void cuio_copyback(struct uio* uio, int off, int len, caddr_t cp);
6952 +extern struct iovec *cuio_getptr(struct uio *uio, int loc, int *off);
6954 +extern void crypto_copyback(int flags, caddr_t buf, int off, int size,
6955 +           caddr_t in);
6956 +extern void crypto_copydata(int flags, caddr_t buf, int off, int size,
6957 +           caddr_t out);
6958 +extern int crypto_apply(int flags, caddr_t buf, int off, int len,
6959 +           int (*f)(void *, void *, u_int), void *arg);
6961 +#endif /* __KERNEL__ */
6962 +#endif /* _CRYPTO_CRYPTO_H_ */
6963 diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
6964 index 18fd130..a469480 100644
6965 --- a/include/linux/miscdevice.h
6966 +++ b/include/linux/miscdevice.h
6967 @@ -18,6 +18,7 @@
6968  #define APOLLO_MOUSE_MINOR     7
6969  #define PC110PAD_MINOR         9
6970  /*#define ADB_MOUSE_MINOR      10      FIXME OBSOLETE */
6971 +#define CRYPTODEV_MINOR                70      /* /dev/crypto */
6972  #define WATCHDOG_MINOR         130     /* Watchdog timer     */
6973  #define TEMP_MINOR             131     /* Temperature Sensor */
6974  #define RTC_MINOR              135
6975 diff --git a/include/linux/random.h b/include/linux/random.h
6976 index fb7ab9d..26ab66b 100644
6977 --- a/include/linux/random.h
6978 +++ b/include/linux/random.h
6979 @@ -9,6 +9,7 @@
6980  
6981  #include <linux/types.h>
6982  #include <linux/ioctl.h>
6983 +#include <linux/types.h> /* for __u32 in user space */
6984  #include <linux/irqnr.h>
6985  
6986  /* ioctl()'s for the random number generator */
6987 @@ -34,6 +35,30 @@
6988  /* Clear the entropy pool and associated counters.  (Superuser only.) */
6989  #define RNDCLEARPOOL   _IO( 'R', 0x06 )
6990  
6991 +#ifdef CONFIG_FIPS_RNG
6993 +/* Size of seed value - equal to AES blocksize */
6994 +#define AES_BLOCK_SIZE_BYTES   16
6995 +#define SEED_SIZE_BYTES                        AES_BLOCK_SIZE_BYTES
6996 +/* Size of AES key */
6997 +#define KEY_SIZE_BYTES         16
6999 +/* ioctl() structure used by FIPS 140-2 Tests */
7000 +struct rand_fips_test {
7001 +       unsigned char key[KEY_SIZE_BYTES];                      /* Input */
7002 +       unsigned char datetime[SEED_SIZE_BYTES];        /* Input */
7003 +       unsigned char seed[SEED_SIZE_BYTES];            /* Input */
7004 +       unsigned char result[SEED_SIZE_BYTES];          /* Output */
7005 +};
7007 +/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
7008 +#define RNDFIPSVST     _IOWR('R', 0x10, struct rand_fips_test)
7010 +/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
7011 +#define RNDFIPSMCT     _IOWR('R', 0x11, struct rand_fips_test)
7013 +#endif /* #ifdef CONFIG_FIPS_RNG */
7015  struct rand_pool_info {
7016         int     entropy_count;
7017         int     buf_size;
7018 @@ -54,6 +79,10 @@ extern void add_input_randomness(unsigned int type, unsigned int code,
7019                                  unsigned int value);
7020  extern void add_interrupt_randomness(int irq);
7021  
7022 +extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
7023 +extern int random_input_wait(void);
7024 +#define HAS_RANDOM_INPUT_WAIT 1
7026  extern void get_random_bytes(void *buf, int nbytes);
7027  void generate_random_uuid(unsigned char uuid_out[16]);
7028  
7029 diff --git a/kernel/pid.c b/kernel/pid.c
7030 index 39b65b6..1cccf44 100644
7031 --- a/kernel/pid.c
7032 +++ b/kernel/pid.c
7033 @@ -424,6 +424,7 @@ struct task_struct *find_task_by_vpid(pid_t vnr)
7034  {
7035         return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns);
7036  }
7037 +EXPORT_SYMBOL(find_task_by_vpid);
7038  
7039  struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
7040  {
7041 -- 
7042 1.7.0.4