From 292a4a63f5b7920125ccab50e4924666e7883ee6 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 17 Oct 2011 14:52:11 +0200 Subject: add ocf patch again and make swap option visible --- target/linux/config/Config.in.block | 9 +- target/linux/patches/3.0.4/ocf-20110720.patch | 99170 ++++++++++++++++++++++++ 2 files changed, 99177 insertions(+), 2 deletions(-) create mode 100644 target/linux/patches/3.0.4/ocf-20110720.patch diff --git a/target/linux/config/Config.in.block b/target/linux/config/Config.in.block index 871c222c3..ce526441b 100644 --- a/target/linux/config/Config.in.block +++ b/target/linux/config/Config.in.block @@ -4,8 +4,6 @@ config ADK_KERNEL_BLOCK config ADK_KERNEL_MD boolean -config ADK_KERNEL_SWAP - boolean config ADK_KERNEL_LBD boolean @@ -312,6 +310,7 @@ config ADK_KPACKAGE_KMOD_MD_RAID0 prompt "kmod-md-raid0..................... RAID0 support (module)" tristate depends on ADK_KPACKAGE_KMOD_BLK_DEV_MD + depends on !ADK_KERNEL_MD_RAID0 help config ADK_KERNEL_MD_RAID1 @@ -387,5 +386,11 @@ config ADK_KPACKAGE_KMOD_BLK_DEV_DRBD depends on !ADK_TARGET_SYSTEM_FOXBOARD_LX help DRBD - http://www.drbd.org + +config ADK_KERNEL_SWAP + prompt "swap.............................. SWAP support" + boolean + help + Kernel swap support. endmenu diff --git a/target/linux/patches/3.0.4/ocf-20110720.patch b/target/linux/patches/3.0.4/ocf-20110720.patch new file mode 100644 index 000000000..b5a257324 --- /dev/null +++ b/target/linux/patches/3.0.4/ocf-20110720.patch @@ -0,0 +1,99170 @@ +diff -Nur linux-3.0.4.orig/crypto/Kconfig linux-3.0.4/crypto/Kconfig +--- linux-3.0.4.orig/crypto/Kconfig 2011-08-29 22:56:30.000000000 +0200 ++++ linux-3.0.4/crypto/Kconfig 2011-10-17 04:36:27.356574299 +0200 +@@ -860,3 +860,6 @@ + source "drivers/crypto/Kconfig" + + endif # if CRYPTO ++ ++source "crypto/ocf/Kconfig" ++ +diff -Nur linux-3.0.4.orig/crypto/Kconfig.orig linux-3.0.4/crypto/Kconfig.orig +--- linux-3.0.4.orig/crypto/Kconfig.orig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.0.4/crypto/Kconfig.orig 2011-08-29 22:56:30.000000000 +0200 +@@ -0,0 +1,862 @@ ++# ++# Generic algorithms support ++# ++config XOR_BLOCKS ++ tristate ++ ++# ++# async_tx api: hardware offloaded memory transfer/transform support ++# ++source "crypto/async_tx/Kconfig" ++ ++# ++# Cryptographic API Configuration ++# ++menuconfig CRYPTO ++ tristate "Cryptographic API" ++ help ++ This option provides the core Cryptographic API. ++ ++if CRYPTO ++ ++comment "Crypto core or helper" ++ ++config CRYPTO_FIPS ++ bool "FIPS 200 compliance" ++ depends on CRYPTO_ANSI_CPRNG && !CRYPTO_MANAGER_DISABLE_TESTS ++ help ++ This options enables the fips boot option which is ++ required if you want to system to operate in a FIPS 200 ++ certification. You should say no unless you know what ++ this is. ++ ++config CRYPTO_ALGAPI ++ tristate ++ select CRYPTO_ALGAPI2 ++ help ++ This option provides the API for cryptographic algorithms. ++ ++config CRYPTO_ALGAPI2 ++ tristate ++ ++config CRYPTO_AEAD ++ tristate ++ select CRYPTO_AEAD2 ++ select CRYPTO_ALGAPI ++ ++config CRYPTO_AEAD2 ++ tristate ++ select CRYPTO_ALGAPI2 ++ ++config CRYPTO_BLKCIPHER ++ tristate ++ select CRYPTO_BLKCIPHER2 ++ select CRYPTO_ALGAPI ++ ++config CRYPTO_BLKCIPHER2 ++ tristate ++ select CRYPTO_ALGAPI2 ++ select CRYPTO_RNG2 ++ select CRYPTO_WORKQUEUE ++ ++config CRYPTO_HASH ++ tristate ++ select CRYPTO_HASH2 ++ select CRYPTO_ALGAPI ++ ++config CRYPTO_HASH2 ++ tristate ++ select CRYPTO_ALGAPI2 ++ ++config CRYPTO_RNG ++ tristate ++ select CRYPTO_RNG2 ++ select CRYPTO_ALGAPI ++ ++config CRYPTO_RNG2 ++ tristate ++ select CRYPTO_ALGAPI2 ++ ++config CRYPTO_PCOMP ++ tristate ++ select CRYPTO_PCOMP2 ++ select CRYPTO_ALGAPI ++ ++config CRYPTO_PCOMP2 ++ tristate ++ select CRYPTO_ALGAPI2 ++ ++config CRYPTO_MANAGER ++ tristate "Cryptographic algorithm manager" ++ select CRYPTO_MANAGER2 ++ help ++ Create default cryptographic template instantiations such as ++ cbc(aes). ++ ++config CRYPTO_MANAGER2 ++ def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y) ++ select CRYPTO_AEAD2 ++ select CRYPTO_HASH2 ++ select CRYPTO_BLKCIPHER2 ++ select CRYPTO_PCOMP2 ++ ++config CRYPTO_MANAGER_DISABLE_TESTS ++ bool "Disable run-time self tests" ++ default y ++ depends on CRYPTO_MANAGER2 ++ help ++ Disable run-time self tests that normally take place at ++ algorithm registration. ++ ++config CRYPTO_GF128MUL ++ tristate "GF(2^128) multiplication functions (EXPERIMENTAL)" ++ help ++ Efficient table driven implementation of multiplications in the ++ field GF(2^128). This is needed by some cypher modes. This ++ option will be selected automatically if you select such a ++ cipher mode. Only select this option by hand if you expect to load ++ an external module that requires these functions. ++ ++config CRYPTO_NULL ++ tristate "Null algorithms" ++ select CRYPTO_ALGAPI ++ select CRYPTO_BLKCIPHER ++ select CRYPTO_HASH ++ help ++ These are 'Null' algorithms, used by IPsec, which do nothing. ++ ++config CRYPTO_PCRYPT ++ tristate "Parallel crypto engine (EXPERIMENTAL)" ++ depends on SMP && EXPERIMENTAL ++ select PADATA ++ select CRYPTO_MANAGER ++ select CRYPTO_AEAD ++ help ++ This converts an arbitrary crypto algorithm into a parallel ++ algorithm that executes in kernel threads. ++ ++config CRYPTO_WORKQUEUE ++ tristate ++ ++config CRYPTO_CRYPTD ++ tristate "Software async crypto daemon" ++ select CRYPTO_BLKCIPHER ++ select CRYPTO_HASH ++ select CRYPTO_MANAGER ++ select CRYPTO_WORKQUEUE ++ help ++ This is a generic software asynchronous crypto daemon that ++ converts an arbitrary synchronous software crypto algorithm ++ into an asynchronous algorithm that executes in a kernel thread. ++ ++config CRYPTO_AUTHENC ++ tristate "Authenc support" ++ select CRYPTO_AEAD ++ select CRYPTO_BLKCIPHER ++ select CRYPTO_MANAGER ++ select CRYPTO_HASH ++ help ++ Authenc: Combined mode wrapper for IPsec. ++ This is required for IPSec. ++ ++config CRYPTO_TEST ++ tristate "Testing module" ++ depends on m ++ select CRYPTO_MANAGER ++ help ++ Quick & dirty crypto test module. ++ ++comment "Authenticated Encryption with Associated Data" ++ ++config CRYPTO_CCM ++ tristate "CCM support" ++ select CRYPTO_CTR ++ select CRYPTO_AEAD ++ help ++ Support for Counter with CBC MAC. Required for IPsec. ++ ++config CRYPTO_GCM ++ tristate "GCM/GMAC support" ++ select CRYPTO_CTR ++ select CRYPTO_AEAD ++ select CRYPTO_GHASH ++ help ++ Support for Galois/Counter Mode (GCM) and Galois Message ++ Authentication Code (GMAC). Required for IPSec. ++ ++config CRYPTO_SEQIV ++ tristate "Sequence Number IV Generator" ++ select CRYPTO_AEAD ++ select CRYPTO_BLKCIPHER ++ select CRYPTO_RNG ++ help ++ This IV generator generates an IV based on a sequence number by ++ xoring it with a salt. This algorithm is mainly useful for CTR ++ ++comment "Block modes" ++ ++config CRYPTO_CBC ++ tristate "CBC support" ++ select CRYPTO_BLKCIPHER ++ select CRYPTO_MANAGER ++ help ++ CBC: Cipher Block Chaining mode ++ This block cipher algorithm is required for IPSec. ++ ++config CRYPTO_CTR ++ tristate "CTR support" ++ select CRYPTO_BLKCIPHER ++ select CRYPTO_SEQIV ++ select CRYPTO_MANAGER ++ help ++ CTR: Counter mode ++ This block cipher algorithm is required for IPSec. ++ ++config CRYPTO_CTS ++ tristate "CTS support" ++ select CRYPTO_BLKCIPHER ++ help ++ CTS: Cipher Text Stealing ++ This is the Cipher Text Stealing mode as described by ++ Section 8 of rfc2040 and referenced by rfc3962. ++ (rfc3962 includes errata information in its Appendix A) ++ This mode is required for Kerberos gss mechanism support ++ for AES encryption. ++ ++config CRYPTO_ECB ++ tristate "ECB support" ++ select CRYPTO_BLKCIPHER ++ select CRYPTO_MANAGER ++ help ++ ECB: Electronic CodeBook mode ++ This is the simplest block cipher algorithm. It simply encrypts ++ the input block by block. ++ ++config CRYPTO_LRW ++ tristate "LRW support (EXPERIMENTAL)" ++ depends on EXPERIMENTAL ++ select CRYPTO_BLKCIPHER ++ select CRYPTO_MANAGER ++ select CRYPTO_GF128MUL ++ help ++ LRW: Liskov Rivest Wagner, a tweakable, non malleable, non movable ++ narrow block cipher mode for dm-crypt. Use it with cipher ++ specification string aes-lrw-benbi, the key must be 256, 320 or 384. ++ The first 128, 192 or 256 bits in the key are used for AES and the ++ rest is used to tie each cipher block to its logical position. ++ ++config CRYPTO_PCBC ++ tristate "PCBC support" ++ select CRYPTO_BLKCIPHER ++ select CRYPTO_MANAGER ++ help ++ PCBC: Propagating Cipher Block Chaining mode ++ This block cipher algorithm is required for RxRPC. ++ ++config CRYPTO_XTS ++ tristate "XTS support (EXPERIMENTAL)" ++ depends on EXPERIMENTAL ++ select CRYPTO_BLKCIPHER ++ select CRYPTO_MANAGER ++ select CRYPTO_GF128MUL ++ help ++ XTS: IEEE1619/D16 narrow block cipher use with aes-xts-plain, ++ key size 256, 384 or 512 bits. This implementation currently ++ can't handle a sectorsize which is not a multiple of 16 bytes. ++ ++comment "Hash modes" ++ ++config CRYPTO_HMAC ++ tristate "HMAC support" ++ select CRYPTO_HASH ++ select CRYPTO_MANAGER ++ help ++ HMAC: Keyed-Hashing for Message Authentication (RFC2104). ++ This is required for IPSec. ++ ++config CRYPTO_XCBC ++ tristate "XCBC support" ++ depends on EXPERIMENTAL ++ select CRYPTO_HASH ++ select CRYPTO_MANAGER ++ help ++ XCBC: Keyed-Hashing with encryption algorithm ++ http://www.ietf.org/rfc/rfc3566.txt ++ http://csrc.nist.gov/encryption/modes/proposedmodes/ ++ xcbc-mac/xcbc-mac-spec.pdf ++ ++config CRYPTO_VMAC ++ tristate "VMAC support" ++ depends on EXPERIMENTAL ++ select CRYPTO_HASH ++ select CRYPTO_MANAGER ++ help ++ VMAC is a message authentication algorithm designed for ++ very high speed on 64-bit architectures. ++ ++ See also: ++ ++ ++comment "Digest" ++ ++config CRYPTO_CRC32C ++ tristate "CRC32c CRC algorithm" ++ select CRYPTO_HASH ++ help ++ Castagnoli, et al Cyclic Redundancy-Check Algorithm. Used ++ by iSCSI for header and data digests and by others. ++ See Castagnoli93. Module will be crc32c. ++ ++config CRYPTO_CRC32C_INTEL ++ tristate "CRC32c INTEL hardware acceleration" ++ depends on X86 ++ select CRYPTO_HASH ++ help ++ In Intel processor with SSE4.2 supported, the processor will ++ support CRC32C implementation using hardware accelerated CRC32 ++ instruction. This option will create 'crc32c-intel' module, ++ which will enable any routine to use the CRC32 instruction to ++ gain performance compared with software implementation. ++ Module will be crc32c-intel. ++ ++config CRYPTO_GHASH ++ tristate "GHASH digest algorithm" ++ select CRYPTO_SHASH ++ select CRYPTO_GF128MUL ++ help ++ GHASH is message digest algorithm for GCM (Galois/Counter Mode). ++ ++config CRYPTO_MD4 ++ tristate "MD4 digest algorithm" ++ select CRYPTO_HASH ++ help ++ MD4 message digest algorithm (RFC1320). ++ ++config CRYPTO_MD5 ++ tristate "MD5 digest algorithm" ++ select CRYPTO_HASH ++ help ++ MD5 message digest algorithm (RFC1321). ++ ++config CRYPTO_MICHAEL_MIC ++ tristate "Michael MIC keyed digest algorithm" ++ select CRYPTO_HASH ++ help ++ Michael MIC is used for message integrity protection in TKIP ++ (IEEE 802.11i). This algorithm is required for TKIP, but it ++ should not be used for other purposes because of the weakness ++ of the algorithm. ++ ++config CRYPTO_RMD128 ++ tristate "RIPEMD-128 digest algorithm" ++ select CRYPTO_HASH ++ help ++ RIPEMD-128 (ISO/IEC 10118-3:2004). ++ ++ RIPEMD-128 is a 128-bit cryptographic hash function. It should only ++ to be used as a secure replacement for RIPEMD. For other use cases ++ RIPEMD-160 should be used. ++ ++ Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel. ++ See ++ ++config CRYPTO_RMD160 ++ tristate "RIPEMD-160 digest algorithm" ++ select CRYPTO_HASH ++ help ++ RIPEMD-160 (ISO/IEC 10118-3:2004). ++ ++ RIPEMD-160 is a 160-bit cryptographic hash function. It is intended ++ to be used as a secure replacement for the 128-bit hash functions ++ MD4, MD5 and it's predecessor RIPEMD ++ (not to be confused with RIPEMD-128). ++ ++ It's speed is comparable to SHA1 and there are no known attacks ++ against RIPEMD-160. ++ ++ Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel. ++ See ++ ++config CRYPTO_RMD256 ++ tristate "RIPEMD-256 digest algorithm" ++ select CRYPTO_HASH ++ help ++ RIPEMD-256 is an optional extension of RIPEMD-128 with a ++ 256 bit hash. It is intended for applications that require ++ longer hash-results, without needing a larger security level ++ (than RIPEMD-128). ++ ++ Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel. ++ See ++ ++config CRYPTO_RMD320 ++ tristate "RIPEMD-320 digest algorithm" ++ select CRYPTO_HASH ++ help ++ RIPEMD-320 is an optional extension of RIPEMD-160 with a ++ 320 bit hash. It is intended for applications that require ++ longer hash-results, without needing a larger security level ++ (than RIPEMD-160). ++ ++ Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel. ++ See ++ ++config CRYPTO_SHA1 ++ tristate "SHA1 digest algorithm" ++ select CRYPTO_HASH ++ help ++ SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). ++ ++config CRYPTO_SHA256 ++ tristate "SHA224 and SHA256 digest algorithm" ++ select CRYPTO_HASH ++ help ++ SHA256 secure hash standard (DFIPS 180-2). ++ ++ This version of SHA implements a 256 bit hash with 128 bits of ++ security against collision attacks. ++ ++ This code also includes SHA-224, a 224 bit hash with 112 bits ++ of security against collision attacks. ++ ++config CRYPTO_SHA512 ++ tristate "SHA384 and SHA512 digest algorithms" ++ select CRYPTO_HASH ++ help ++ SHA512 secure hash standard (DFIPS 180-2). ++ ++ This version of SHA implements a 512 bit hash with 256 bits of ++ security against collision attacks. ++ ++ This code also includes SHA-384, a 384 bit hash with 192 bits ++ of security against collision attacks. ++ ++config CRYPTO_TGR192 ++ tristate "Tiger digest algorithms" ++ select CRYPTO_HASH ++ help ++ Tiger hash algorithm 192, 160 and 128-bit hashes ++ ++ Tiger is a hash function optimized for 64-bit processors while ++ still having decent performance on 32-bit processors. ++ Tiger was developed by Ross Anderson and Eli Biham. ++ ++ See also: ++ . ++ ++config CRYPTO_WP512 ++ tristate "Whirlpool digest algorithms" ++ select CRYPTO_HASH ++ help ++ Whirlpool hash algorithm 512, 384 and 256-bit hashes ++ ++ Whirlpool-512 is part of the NESSIE cryptographic primitives. ++ Whirlpool will be part of the ISO/IEC 10118-3:2003(E) standard ++ ++ See also: ++ ++ ++config CRYPTO_GHASH_CLMUL_NI_INTEL ++ tristate "GHASH digest algorithm (CLMUL-NI accelerated)" ++ depends on (X86 || UML_X86) && 64BIT ++ select CRYPTO_SHASH ++ select CRYPTO_CRYPTD ++ help ++ GHASH is message digest algorithm for GCM (Galois/Counter Mode). ++ The implementation is accelerated by CLMUL-NI of Intel. ++ ++comment "Ciphers" ++ ++config CRYPTO_AES ++ tristate "AES cipher algorithms" ++ select CRYPTO_ALGAPI ++ help ++ AES cipher algorithms (FIPS-197). AES uses the Rijndael ++ algorithm. ++ ++ Rijndael appears to be consistently a very good performer in ++ both hardware and software across a wide range of computing ++ environments regardless of its use in feedback or non-feedback ++ modes. Its key setup time is excellent, and its key agility is ++ good. Rijndael's very low memory requirements make it very well ++ suited for restricted-space environments, in which it also ++ demonstrates excellent performance. Rijndael's operations are ++ among the easiest to defend against power and timing attacks. ++ ++ The AES specifies three key sizes: 128, 192 and 256 bits ++ ++ See for more information. ++ ++config CRYPTO_AES_586 ++ tristate "AES cipher algorithms (i586)" ++ depends on (X86 || UML_X86) && !64BIT ++ select CRYPTO_ALGAPI ++ select CRYPTO_AES ++ help ++ AES cipher algorithms (FIPS-197). AES uses the Rijndael ++ algorithm. ++ ++ Rijndael appears to be consistently a very good performer in ++ both hardware and software across a wide range of computing ++ environments regardless of its use in feedback or non-feedback ++ modes. Its key setup time is excellent, and its key agility is ++ good. Rijndael's very low memory requirements make it very well ++ suited for restricted-space environments, in which it also ++ demonstrates excellent performance. Rijndael's operations are ++ among the easiest to defend against power and timing attacks. ++ ++ The AES specifies three key sizes: 128, 192 and 256 bits ++ ++ See for more information. ++ ++config CRYPTO_AES_X86_64 ++ tristate "AES cipher algorithms (x86_64)" ++ depends on (X86 || UML_X86) && 64BIT ++ select CRYPTO_ALGAPI ++ select CRYPTO_AES ++ help ++ AES cipher algorithms (FIPS-197). AES uses the Rijndael ++ algorithm. ++ ++ Rijndael appears to be consistently a very good performer in ++ both hardware and software across a wide range of computing ++ environments regardless of its use in feedback or non-feedback ++ modes. Its key setup time is excellent, and its key agility is ++ good. Rijndael's very low memory requirements make it very well ++ suited for restricted-space environments, in which it also ++ demonstrates excellent performance. Rijndael's operations are ++ among the easiest to defend against power and timing attacks. ++ ++ The AES specifies three key sizes: 128, 192 and 256 bits ++ ++ See for more information. ++ ++config CRYPTO_AES_NI_INTEL ++ tristate "AES cipher algorithms (AES-NI)" ++ depends on (X86 || UML_X86) ++ select CRYPTO_AES_X86_64 if 64BIT ++ select CRYPTO_AES_586 if !64BIT ++ select CRYPTO_CRYPTD ++ select CRYPTO_ALGAPI ++ help ++ Use Intel AES-NI instructions for AES algorithm. ++ ++ AES cipher algorithms (FIPS-197). AES uses the Rijndael ++ algorithm. ++ ++ Rijndael appears to be consistently a very good performer in ++ both hardware and software across a wide range of computing ++ environments regardless of its use in feedback or non-feedback ++ modes. Its key setup time is excellent, and its key agility is ++ good. Rijndael's very low memory requirements make it very well ++ suited for restricted-space environments, in which it also ++ demonstrates excellent performance. Rijndael's operations are ++ among the easiest to defend against power and timing attacks. ++ ++ The AES specifies three key sizes: 128, 192 and 256 bits ++ ++ See for more information. ++ ++ In addition to AES cipher algorithm support, the acceleration ++ for some popular block cipher mode is supported too, including ++ ECB, CBC, LRW, PCBC, XTS. The 64 bit version has additional ++ acceleration for CTR. ++ ++config CRYPTO_ANUBIS ++ tristate "Anubis cipher algorithm" ++ select CRYPTO_ALGAPI ++ help ++ Anubis cipher algorithm. ++ ++ Anubis is a variable key length cipher which can use keys from ++ 128 bits to 320 bits in length. It was evaluated as a entrant ++ in the NESSIE competition. ++ ++ See also: ++ ++ ++ ++config CRYPTO_ARC4 ++ tristate "ARC4 cipher algorithm" ++ select CRYPTO_ALGAPI ++ help ++ ARC4 cipher algorithm. ++ ++ ARC4 is a stream cipher using keys ranging from 8 bits to 2048 ++ bits in length. This algorithm is required for driver-based ++ WEP, but it should not be for other purposes because of the ++ weakness of the algorithm. ++ ++config CRYPTO_BLOWFISH ++ tristate "Blowfish cipher algorithm" ++ select CRYPTO_ALGAPI ++ help ++ Blowfish cipher algorithm, by Bruce Schneier. ++ ++ This is a variable key length cipher which can use keys from 32 ++ bits to 448 bits in length. It's fast, simple and specifically ++ designed for use on "large microprocessors". ++ ++ See also: ++ ++ ++config CRYPTO_CAMELLIA ++ tristate "Camellia cipher algorithms" ++ depends on CRYPTO ++ select CRYPTO_ALGAPI ++ help ++ Camellia cipher algorithms module. ++ ++ Camellia is a symmetric key block cipher developed jointly ++ at NTT and Mitsubishi Electric Corporation. ++ ++ The Camellia specifies three key sizes: 128, 192 and 256 bits. ++ ++ See also: ++ ++ ++config CRYPTO_CAST5 ++ tristate "CAST5 (CAST-128) cipher algorithm" ++ select CRYPTO_ALGAPI ++ help ++ The CAST5 encryption algorithm (synonymous with CAST-128) is ++ described in RFC2144. ++ ++config CRYPTO_CAST6 ++ tristate "CAST6 (CAST-256) cipher algorithm" ++ select CRYPTO_ALGAPI ++ help ++ The CAST6 encryption algorithm (synonymous with CAST-256) is ++ described in RFC2612. ++ ++config CRYPTO_DES ++ tristate "DES and Triple DES EDE cipher algorithms" ++ select CRYPTO_ALGAPI ++ help ++ DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). ++ ++config CRYPTO_FCRYPT ++ tristate "FCrypt cipher algorithm" ++ select CRYPTO_ALGAPI ++ select CRYPTO_BLKCIPHER ++ help ++ FCrypt algorithm used by RxRPC. ++ ++config CRYPTO_KHAZAD ++ tristate "Khazad cipher algorithm" ++ select CRYPTO_ALGAPI ++ help ++ Khazad cipher algorithm. ++ ++ Khazad was a finalist in the initial NESSIE competition. It is ++ an algorithm optimized for 64-bit processors with good performance ++ on 32-bit processors. Khazad uses an 128 bit key size. ++ ++ See also: ++ ++ ++config CRYPTO_SALSA20 ++ tristate "Salsa20 stream cipher algorithm (EXPERIMENTAL)" ++ depends on EXPERIMENTAL ++ select CRYPTO_BLKCIPHER ++ help ++ Salsa20 stream cipher algorithm. ++ ++ Salsa20 is a stream cipher submitted to eSTREAM, the ECRYPT ++ Stream Cipher Project. See ++ ++ The Salsa20 stream cipher algorithm is designed by Daniel J. ++ Bernstein . See ++ ++config CRYPTO_SALSA20_586 ++ tristate "Salsa20 stream cipher algorithm (i586) (EXPERIMENTAL)" ++ depends on (X86 || UML_X86) && !64BIT ++ depends on EXPERIMENTAL ++ select CRYPTO_BLKCIPHER ++ help ++ Salsa20 stream cipher algorithm. ++ ++ Salsa20 is a stream cipher submitted to eSTREAM, the ECRYPT ++ Stream Cipher Project. See ++ ++ The Salsa20 stream cipher algorithm is designed by Daniel J. ++ Bernstein . See ++ ++config CRYPTO_SALSA20_X86_64 ++ tristate "Salsa20 stream cipher algorithm (x86_64) (EXPERIMENTAL)" ++ depends on (X86 || UML_X86) && 64BIT ++ depends on EXPERIMENTAL ++ select CRYPTO_BLKCIPHER ++ help ++ Salsa20 stream cipher algorithm. ++ ++ Salsa20 is a stream cipher submitted to eSTREAM, the ECRYPT ++ Stream Cipher Project. See ++ ++ The Salsa20 stream cipher algorithm is designed by Daniel J. ++ Bernstein . See ++ ++config CRYPTO_SEED ++ tristate "SEED cipher algorithm" ++ select CRYPTO_ALGAPI ++ help ++ SEED cipher algorithm (RFC4269). ++ ++ SEED is a 128-bit symmetric key block cipher that has been ++ developed by KISA (Korea Information Security Agency) as a ++ national standard encryption algorithm of the Republic of Korea. ++ It is a 16 round block cipher with the key size of 128 bit. ++ ++ See also: ++ ++ ++config CRYPTO_SERPENT ++ tristate "Serpent cipher algorithm" ++ select CRYPTO_ALGAPI ++ help ++ Serpent cipher algorithm, by Anderson, Biham & Knudsen. ++ ++ Keys are allowed to be from 0 to 256 bits in length, in steps ++ of 8 bits. Also includes the 'Tnepres' algorithm, a reversed ++ variant of Serpent for compatibility with old kerneli.org code. ++ ++ See also: ++ ++ ++config CRYPTO_TEA ++ tristate "TEA, XTEA and XETA cipher algorithms" ++ select CRYPTO_ALGAPI ++ help ++ TEA cipher algorithm. ++ ++ Tiny Encryption Algorithm is a simple cipher that uses ++ many rounds for security. It is very fast and uses ++ little memory. ++ ++ Xtendend Tiny Encryption Algorithm is a modification to ++ the TEA algorithm to address a potential key weakness ++ in the TEA algorithm. ++ ++ Xtendend Encryption Tiny Algorithm is a mis-implementation ++ of the XTEA algorithm for compatibility purposes. ++ ++config CRYPTO_TWOFISH ++ tristate "Twofish cipher algorithm" ++ select CRYPTO_ALGAPI ++ select CRYPTO_TWOFISH_COMMON ++ help ++ Twofish cipher algorithm. ++ ++ Twofish was submitted as an AES (Advanced Encryption Standard) ++ candidate cipher by researchers at CounterPane Systems. It is a ++ 16 round block cipher supporting key sizes of 128, 192, and 256 ++ bits. ++ ++ See also: ++ ++ ++config CRYPTO_TWOFISH_COMMON ++ tristate ++ help ++ Common parts of the Twofish cipher algorithm shared by the ++ generic c and the assembler implementations. ++ ++config CRYPTO_TWOFISH_586 ++ tristate "Twofish cipher algorithms (i586)" ++ depends on (X86 || UML_X86) && !64BIT ++ select CRYPTO_ALGAPI ++ select CRYPTO_TWOFISH_COMMON ++ help ++ Twofish cipher algorithm. ++ ++ Twofish was submitted as an AES (Advanced Encryption Standard) ++ candidate cipher by researchers at CounterPane Systems. It is a ++ 16 round block cipher supporting key sizes of 128, 192, and 256 ++ bits. ++ ++ See also: ++ ++ ++config CRYPTO_TWOFISH_X86_64 ++ tristate "Twofish cipher algorithm (x86_64)" ++ depends on (X86 || UML_X86) && 64BIT ++ select CRYPTO_ALGAPI ++ select CRYPTO_TWOFISH_COMMON ++ help ++ Twofish cipher algorithm (x86_64). ++ ++ Twofish was submitted as an AES (Advanced Encryption Standard) ++ candidate cipher by researchers at CounterPane Systems. It is a ++ 16 round block cipher supporting key sizes of 128, 192, and 256 ++ bits. ++ ++ See also: ++ ++ ++comment "Compression" ++ ++config CRYPTO_DEFLATE ++ tristate "Deflate compression algorithm" ++ select CRYPTO_ALGAPI ++ select ZLIB_INFLATE ++ select ZLIB_DEFLATE ++ help ++ This is the Deflate algorithm (RFC1951), specified for use in ++ IPSec with the IPCOMP protocol (RFC3173, RFC2394). ++ ++ You will most probably want this if using IPSec. ++ ++config CRYPTO_ZLIB ++ tristate "Zlib compression algorithm" ++ select CRYPTO_PCOMP ++ select ZLIB_INFLATE ++ select ZLIB_DEFLATE ++ select NLATTR ++ help ++ This is the zlib algorithm. ++ ++config CRYPTO_LZO ++ tristate "LZO compression algorithm" ++ select CRYPTO_ALGAPI ++ select LZO_COMPRESS ++ select LZO_DECOMPRESS ++ help ++ This is the LZO algorithm. ++ ++comment "Random Number Generation" ++ ++config CRYPTO_ANSI_CPRNG ++ tristate "Pseudo Random Number Generation for Cryptographic modules" ++ default m ++ select CRYPTO_AES ++ select CRYPTO_RNG ++ help ++ This option enables the generic pseudo random number generator ++ for cryptographic modules. Uses the Algorithm specified in ++ ANSI X9.31 A.2.4. Note that this option must be enabled if ++ CRYPTO_FIPS is selected ++ ++config CRYPTO_USER_API ++ tristate ++ ++config CRYPTO_USER_API_HASH ++ tristate "User-space interface for hash algorithms" ++ depends on NET ++ select CRYPTO_HASH ++ select CRYPTO_USER_API ++ help ++ This option enables the user-spaces interface for hash ++ algorithms. ++ ++config CRYPTO_USER_API_SKCIPHER ++ tristate "User-space interface for symmetric key cipher algorithms" ++ depends on NET ++ select CRYPTO_BLKCIPHER ++ select CRYPTO_USER_API ++ help ++ This option enables the user-spaces interface for symmetric ++ key cipher algorithms. ++ ++source "drivers/crypto/Kconfig" ++ ++endif # if CRYPTO +diff -Nur linux-3.0.4.orig/crypto/Makefile linux-3.0.4/crypto/Makefile +--- linux-3.0.4.orig/crypto/Makefile 2011-08-29 22:56:30.000000000 +0200 ++++ linux-3.0.4/crypto/Makefile 2011-10-17 04:36:27.356574299 +0200 +@@ -89,6 +89,8 @@ + obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o + obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o + ++obj-$(CONFIG_OCF_OCF) += ocf/ ++ + # + # generic algorithms and the async_tx api + # +diff -Nur linux-3.0.4.orig/crypto/ocf/Config.in linux-3.0.4/crypto/ocf/Config.in +--- linux-3.0.4.orig/crypto/ocf/Config.in 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.0.4/crypto/ocf/Config.in 2011-07-20 02:01:53.000000000 +0200 +@@ -0,0 +1,38 @@ ++############################################################################# ++ ++mainmenu_option next_comment ++comment 'OCF Configuration' ++tristate 'OCF (Open Cryptograhic Framework)' CONFIG_OCF_OCF ++dep_mbool ' enable fips RNG checks (fips check on RNG data before use)' \ ++ CONFIG_OCF_FIPS $CONFIG_OCF_OCF ++dep_mbool ' enable harvesting entropy for /dev/random' \ ++ CONFIG_OCF_RANDOMHARVEST $CONFIG_OCF_OCF ++dep_tristate ' cryptodev (user space support)' \ ++ CONFIG_OCF_CRYPTODEV $CONFIG_OCF_OCF ++dep_tristate ' cryptosoft (software crypto engine)' \ ++ CONFIG_OCF_CRYPTOSOFT $CONFIG_OCF_OCF ++dep_tristate ' safenet (HW crypto engine)' \ ++ CONFIG_OCF_SAFE $CONFIG_OCF_OCF ++dep_tristate ' IXP4xx (HW crypto engine)' \ ++ CONFIG_OCF_IXP4XX $CONFIG_OCF_OCF ++dep_mbool ' Enable IXP4xx HW to perform SHA1 and MD5 hashing (very slow)' \ ++ CONFIG_OCF_IXP4XX_SHA1_MD5 $CONFIG_OCF_IXP4XX ++dep_tristate ' hifn (HW crypto engine)' \ ++ CONFIG_OCF_HIFN $CONFIG_OCF_OCF ++dep_tristate ' talitos (HW crypto engine)' \ ++ CONFIG_OCF_TALITOS $CONFIG_OCF_OCF ++dep_tristate ' pasemi (HW crypto engine)' \ ++ CONFIG_OCF_PASEMI $CONFIG_OCF_OCF ++dep_tristate ' ep80579 (HW crypto engine)' \ ++ CONFIG_OCF_EP80579 $CONFIG_OCF_OCF ++dep_tristate ' Micronas c7108 (HW crypto engine)' \ ++ CONFIG_OCF_C7108 $CONFIG_OCF_OCF ++dep_tristate ' uBsec BCM5365 (HW crypto engine)' ++ CONFIG_OCF_UBSEC_SSB $CONFIG_OCF_OCF ++dep_tristate ' ocfnull (does no crypto)' \ ++ CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF ++dep_tristate ' ocf-bench (HW crypto in-kernel benchmark)' \ ++ CONFIG_OCF_BENCH $CONFIG_OCF_OCF ++endmenu ++ ++############################################################################# +diff -Nur linux-3.0.4.orig/crypto/ocf/Kconfig linux-3.0.4/crypto/ocf/Kconfig +--- linux-3.0.4.orig/crypto/ocf/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.0.4/crypto/ocf/Kconfig 2011-07-20 02:01:53.000000000 +0200 +@@ -0,0 +1,125 @@ ++menu "OCF Configuration" ++ ++config OCF_OCF ++ tristate "OCF (Open Cryptograhic Framework)" ++ help ++ A linux port of the OpenBSD/FreeBSD crypto framework. ++ ++config OCF_RANDOMHARVEST ++ bool "crypto random --- harvest entropy for /dev/random" ++ depends on OCF_OCF ++ help ++ Includes code to harvest random numbers from devices that support it. ++ ++config OCF_FIPS ++ bool "enable fips RNG checks" ++ depends on OCF_OCF && OCF_RANDOMHARVEST ++ help ++ Run all RNG provided data through a fips check before ++ adding it /dev/random's entropy pool. ++ ++config OCF_CRYPTODEV ++ tristate "cryptodev (user space support)" ++ depends on OCF_OCF ++ help ++ The user space API to access crypto hardware. ++ ++config OCF_CRYPTOSOFT ++ tristate "cryptosoft (software crypto engine)" ++ depends on OCF_OCF ++ help ++ A software driver for the OCF framework that uses ++ the kernel CryptoAPI. ++ ++config OCF_SAFE ++ tristate "safenet (HW crypto engine)" ++ depends on OCF_OCF ++ help ++ A driver for a number of the safenet Excel crypto accelerators. ++ Currently tested and working on the 1141 and 1741. ++ ++config OCF_IXP4XX ++ tristate "IXP4xx (HW crypto engine)" ++ depends on OCF_OCF ++ help ++ XScale IXP4xx crypto accelerator driver. Requires the ++ Intel Access library. ++ ++config OCF_IXP4XX_SHA1_MD5 ++ bool "IXP4xx SHA1 and MD5 Hashing" ++ depends on OCF_IXP4XX ++ help ++ Allows the IXP4xx crypto accelerator to perform SHA1 and MD5 hashing. ++ Note: this is MUCH slower than using cryptosoft (software crypto engine). ++ ++config OCF_HIFN ++ tristate "hifn (HW crypto engine)" ++ depends on OCF_OCF ++ help ++ OCF driver for various HIFN based crypto accelerators. ++ (7951, 7955, 7956, 7751, 7811) ++ ++config OCF_HIFNHIPP ++ tristate "Hifn HIPP (HW packet crypto engine)" ++ depends on OCF_OCF ++ help ++ OCF driver for various HIFN (HIPP) based crypto accelerators ++ (7855) ++ ++config OCF_TALITOS ++ tristate "talitos (HW crypto engine)" ++ depends on OCF_OCF ++ help ++ OCF driver for Freescale's security engine (SEC/talitos). ++ ++config OCF_PASEMI ++ tristate "pasemi (HW crypto engine)" ++ depends on OCF_OCF && PPC_PASEMI ++ help ++ OCF driver for the PA Semi PWRficient DMA Engine ++ ++config OCF_EP80579 ++ tristate "ep80579 (HW crypto engine)" ++ depends on OCF_OCF ++ help ++ OCF driver for the Intel EP80579 Integrated Processor Product Line. ++ ++config OCF_CRYPTOCTEON ++ tristate "cryptocteon (HW crypto engine)" ++ depends on OCF_OCF ++ help ++ OCF driver for the Cavium OCTEON Processors. ++ ++config OCF_KIRKWOOD ++ tristate "kirkwood (HW crypto engine)" ++ depends on OCF_OCF ++ help ++ OCF driver for the Marvell Kirkwood (88F6xxx) Processors. ++ ++config OCF_C7108 ++ tristate "Micronas 7108 (HW crypto engine)" ++ depends on OCF_OCF ++ help ++ OCF driver for the Microna 7108 Cipher processors. ++ ++config OCF_UBSEC_SSB ++ tristate "uBsec BCM5365 (HW crypto engine)" ++ depends on OCF_OCF ++ help ++ OCF driver for uBsec BCM5365 hardware crypto accelerator. ++ ++config OCF_OCFNULL ++ tristate "ocfnull (fake crypto engine)" ++ depends on OCF_OCF ++ help ++ OCF driver for measuring ipsec overheads (does no crypto) ++ ++config OCF_BENCH ++ tristate "ocf-bench (HW crypto in-kernel benchmark)" ++ depends on OCF_OCF ++ help ++ A very simple encryption test for the in-kernel interface ++ of OCF. Also includes code to benchmark the IXP Access library ++ for comparison. ++ ++endmenu +diff -Nur linux-3.0.4.orig/crypto/ocf/Makefile linux-3.0.4/crypto/ocf/Makefile +--- linux-3.0.4.orig/crypto/ocf/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.0.4/crypto/ocf/Makefile 2011-07-20 02:01:53.000000000 +0200 +@@ -0,0 +1,145 @@ ++# for SGlinux builds ++-include $(ROOTDIR)/modules/.config ++ ++OCF_OBJS = crypto.o criov.o ++ ++ifdef CONFIG_OCF_RANDOMHARVEST ++ OCF_OBJS += random.o ++endif ++ ++ifdef CONFIG_OCF_FIPS ++ OCF_OBJS += rndtest.o ++endif ++ ++# Add in autoconf.h to get #defines for CONFIG_xxx ++AUTOCONF_H=$(ROOTDIR)/modules/autoconf.h ++ifeq ($(AUTOCONF_H), $(wildcard $(AUTOCONF_H))) ++ EXTRA_CFLAGS += -include $(AUTOCONF_H) ++ export EXTRA_CFLAGS ++endif ++ ++ifndef obj ++ obj ?= . ++ _obj = subdir ++ mod-subdirs := safe hifn ixp4xx talitos ocfnull ++ export-objs += crypto.o criov.o random.o ++ list-multi += ocf.o ++ _slash := ++else ++ _obj = obj ++ _slash := / ++endif ++ ++EXTRA_CFLAGS += -I$(obj)/. ++ ++obj-$(CONFIG_OCF_OCF) += ocf.o ++obj-$(CONFIG_OCF_CRYPTODEV) += cryptodev.o ++obj-$(CONFIG_OCF_CRYPTOSOFT) += cryptosoft.o ++obj-$(CONFIG_OCF_BENCH) += ocf-bench.o ++ ++$(_obj)-$(CONFIG_OCF_SAFE) += safe$(_slash) ++$(_obj)-$(CONFIG_OCF_HIFN) += hifn$(_slash) ++$(_obj)-$(CONFIG_OCF_IXP4XX) += ixp4xx$(_slash) ++$(_obj)-$(CONFIG_OCF_TALITOS) += talitos$(_slash) ++$(_obj)-$(CONFIG_OCF_PASEMI) += pasemi$(_slash) ++$(_obj)-$(CONFIG_OCF_EP80579) += ep80579$(_slash) ++$(_obj)-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon$(_slash) ++$(_obj)-$(CONFIG_OCF_KIRKWOOD) += kirkwood$(_slash) ++$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash) ++$(_obj)-$(CONFIG_OCF_C7108) += c7108$(_slash) ++$(_obj)-$(CONFIG_OCF_UBSEC_SSB) += ubsec_ssb$(_slash) ++ ++ocf-objs := $(OCF_OBJS) ++ ++dummy: ++ @echo "Please consult the README for how to build OCF." ++ @echo "If you can't wait then the following should do it:" ++ @echo "" ++ @echo " make ocf_modules" ++ @echo " sudo make ocf_install" ++ @echo "" ++ @exit 1 ++ ++$(list-multi) dummy1: $(ocf-objs) ++ $(LD) -r -o $@ $(ocf-objs) ++ ++.PHONY: ++clean: ++ rm -f *.o *.ko .*.o.flags .*.ko.cmd .*.o.cmd .*.mod.o.cmd *.mod.c ++ rm -f */*.o */*.ko */.*.o.cmd */.*.ko.cmd */.*.mod.o.cmd */*.mod.c */.*.o.flags ++ rm -f */modules.order */modules.builtin modules.order modules.builtin ++ ++ifdef TOPDIR ++-include $(TOPDIR)/Rules.make ++endif ++ ++# ++# targets to build easily on the current machine ++# ++ ++ocf_make: ++ make -C /lib/modules/$(shell uname -r)/build M=`pwd` $(OCF_TARGET) CONFIG_OCF_OCF=m ++ make -C /lib/modules/$(shell uname -r)/build M=`pwd` $(OCF_TARGET) CONFIG_OCF_OCF=m CONFIG_OCF_CRYPTOSOFT=m ++ -make -C /lib/modules/$(shell uname -r)/build M=`pwd` $(OCF_TARGET) CONFIG_OCF_OCF=m CONFIG_OCF_BENCH=m ++ -make -C /lib/modules/$(shell uname -r)/build M=`pwd` $(OCF_TARGET) CONFIG_OCF_OCF=m CONFIG_OCF_OCFNULL=m ++ -make -C /lib/modules/$(shell uname -r)/build M=`pwd` $(OCF_TARGET) CONFIG_OCF_OCF=m CONFIG_OCF_HIFN=m ++ ++ocf_modules: ++ $(MAKE) ocf_make OCF_TARGET=modules ++ ++ocf_install: ++ $(MAKE) ocf_make OCF_TARGET="modules modules_install" ++ depmod ++ mkdir -p /usr/include/crypto ++ cp cryptodev.h /usr/include/crypto/. ++ ++# ++# generate full kernel patches for 2.4 and 2.6 kernels to make patching ++# your kernel easier ++# ++ ++.PHONY: patch ++patch: ++ patchbase=.; \ ++ [ -d $$patchbase/patches ] || patchbase=..; \ ++ patch=ocf-linux-base.patch; \ ++ patch24=ocf-linux-24.patch; \ ++ patch26=ocf-linux-26.patch; \ ++ ( \ ++ find . -name Makefile; \ ++ find . -name Config.in; \ ++ find . -name Kconfig; \ ++ find . -name README; \ ++ find . -name '*.[ch]' | grep -v '.mod.c'; \ ++ ) | while read t; do \ ++ diff -Nau /dev/null $$t | sed 's?^+++ \./?+++ linux/crypto/ocf/?'; \ ++ done > $$patch; \ ++ cat $$patchbase/patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \ ++ cat $$patchbase/patches/linux-2.6.38-ocf.patch $$patch > $$patch26; \ ++ ++# ++# this target probably does nothing for anyone but me - davidm ++# ++ ++.PHONY: release ++release: ++ REL=`date +%Y%m%d`; RELDIR=/tmp/ocf-linux-$$REL; \ ++ CURDIR=`pwd`; \ ++ rm -rf /tmp/ocf-linux-$$REL*; \ ++ mkdir -p $$RELDIR/ocf; \ ++ mkdir -p $$RELDIR/patches; \ ++ mkdir -p $$RELDIR/crypto-tools; \ ++ cp README* $$RELDIR/.; \ ++ cp patches/[!C]* $$RELDIR/patches/.; \ ++ cp tools/[!C]* $$RELDIR/crypto-tools/.; \ ++ cp -r [!C]* Config.in $$RELDIR/ocf/.; \ ++ rm -rf $$RELDIR/ocf/patches $$RELDIR/ocf/tools; \ ++ rm -f $$RELDIR/ocf/README*; \ ++ cp $$CURDIR/../../user/crypto-tools/[!C]* $$RELDIR/crypto-tools/.; \ ++ make -C $$RELDIR/crypto-tools clean; \ ++ make -C $$RELDIR/ocf clean; \ ++ find $$RELDIR/ocf -name CVS | xargs rm -rf; \ ++ cd $$RELDIR/..; \ ++ tar cvf ocf-linux-$$REL.tar ocf-linux-$$REL; \ ++ gzip -9 ocf-linux-$$REL.tar ++ +diff -Nur linux-3.0.4.orig/crypto/ocf/c7108/Makefile linux-3.0.4/crypto/ocf/c7108/Makefile +--- linux-3.0.4.orig/crypto/ocf/c7108/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.0.4/crypto/ocf/c7108/Makefile 2011-07-20 02:01:53.000000000 +0200 +@@ -0,0 +1,12 @@ ++# for SGlinux builds ++-include $(ROOTDIR)/modules/.config ++ ++obj-$(CONFIG_OCF_C7108) += aes-7108.o ++ ++obj ?= . ++EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/ ++ ++ifdef TOPDIR ++-include $(TOPDIR)/Rules.make ++endif ++ +diff -Nur linux-3.0.4.orig/crypto/ocf/c7108/aes-7108.c linux-3.0.4/crypto/ocf/c7108/aes-7108.c +--- linux-3.0.4.orig/crypto/ocf/c7108/aes-7108.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.0.4/crypto/ocf/c7108/aes-7108.c 2011-07-20 02:01:53.000000000 +0200 +@@ -0,0 +1,839 @@ ++/* ++ * Copyright (C) 2006 Micronas USA ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The name of the author may not be used to endorse or promote products ++ * derived from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * Effort sponsored in part by the Defense Advanced Research Projects ++ * Agency (DARPA) and Air Force Research Laboratory, Air Force ++ * Materiel Command, USAF, under agreement number F30602-01-2-0537. ++ * ++ */ ++ ++//#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++//#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Runtime mode */ ++static int c7108_crypto_mode = C7108_AES_CTRL_MODE_CTR; ++//static int c7108_crypto_mode = C7108_AES_CTRL_MODE_CBC; ++ ++static int32_t c7108_id = -1; ++static struct cipher_7108 **c7108_sessions = NULL; ++static u_int32_t c7108_sesnum = 0; ++static unsigned long iobar; ++ ++/* Crypto entry points */ ++static int c7108_process(void *, struct cryptop *, int); ++static int c7108_newsession(void *, u_int32_t *, struct cryptoini *); ++static int c7108_freesession(void *, u_int64_t); ++ ++/* Globals */ ++static int debug = 0; ++static spinlock_t csr_mutex; ++ ++/* Generic controller-based lock */ ++#define AES_LOCK()\ ++ spin_lock(&csr_mutex) ++#define AES_UNLOCK()\ ++ spin_unlock(&csr_mutex) ++ ++/* 7108 AES register access */ ++#define c7108_reg_wr8(a,d) iowrite8(d, (void*)(iobar+(a))) ++#define c7108_reg_wr16(a,d) iowrite16(d, (void*)(iobar+(a))) ++#define c7108_reg_wr32(a,d) iowrite32(d, (void*)(iobar+(a))) ++#define c7108_reg_rd8(a) ioread8((void*)(iobar+(a))) ++#define c7108_reg_rd16(a) ioread16((void*)(iobar+(a))) ++#define c7108_reg_rd32(a) ioread32((void*)(iobar+(a))) ++ ++static int ++c7108_xlate_key(int klen, u8* k8ptr, u32* k32ptr) ++{ ++ int i, nw=0; ++ nw = ((klen >= 256) ? 8 : (klen >= 192) ? 6 : 4); ++ for ( i = 0; i < nw; i++) { ++ k32ptr[i] = (k8ptr[i+3] << 24) | (k8ptr[i+2] << 16) | ++ (k8ptr[i+1] << 8) | k8ptr[i]; ++ ++ } ++ return 0; ++} ++ ++static int ++c7108_cache_key(int klen, u32* k32ptr, u8* k8ptr) ++{ ++ int i, nb=0; ++ u8* ptr = (u8*)k32ptr; ++ nb = ((klen >= 256) ? 32 : (klen >= 192) ? 24 : 16); ++ for ( i = 0; i < nb; i++) ++ k8ptr[i] = ptr[i]; ++ return 0; ++} ++ ++static int ++c7108_aes_setup_dma(u32 src, u32 dst, u32 len) ++{ ++ if (len < 16) { ++ printk("len < 16\n"); ++ return -10; ++ } ++ if (len % 16) { ++ printk("len not multiple of 16\n"); ++ return -11; ++ } ++ c7108_reg_wr16(C7108_AES_DMA_SRC0_LO, (u16) src); ++ c7108_reg_wr16(C7108_AES_DMA_SRC0_HI, (u16)((src & 0xffff0000) >> 16)); ++ c7108_reg_wr16(C7108_AES_DMA_DST0_LO, (u16) dst); ++ c7108_reg_wr16(C7108_AES_DMA_DST0_HI, (u16)((dst & 0xffff0000) >> 16)); ++ c7108_reg_wr16(C7108_AES_DMA_LEN, (u16) ((len / 16) - 1)); ++ ++ return 0; ++} ++ ++static int ++c7108_aes_set_hw_iv(u8 iv[16]) ++{ ++ c7108_reg_wr16(C7108_AES_IV0_LO, (u16) ((iv[1] << 8) | iv[0])); ++ c7108_reg_wr16(C7108_AES_IV0_HI, (u16) ((iv[3] << 8) | iv[2])); ++ c7108_reg_wr16(C7108_AES_IV1_LO, (u16) ((iv[5] << 8) | iv[4])); ++ c7108_reg_wr16(C7108_AES_IV1_HI, (u16) ((iv[7] << 8) | iv[6])); ++ c7108_reg_wr16(C7108_AES_IV2_LO, (u16) ((iv[9] << 8) | iv[8])); ++ c7108_reg_wr16(C7108_AES_IV2_HI, (u16) ((iv[11] << 8) | iv[10])); ++ c7108_reg_wr16(C7108_AES_IV3_LO, (u16) ((iv[13] << 8) | iv[12])); ++ c7108_reg_wr16(C7108_AES_IV3_HI, (u16) ((iv[15] << 8) | iv[14])); ++ ++ return 0; ++} ++ ++static void ++c7108_aes_read_dkey(u32 * dkey) ++{ ++ dkey[0] = (c7108_reg_rd16(C7108_AES_EKEY0_HI) << 16) | ++ c7108_reg_rd16(C7108_AES_EKEY0_LO); ++ dkey[1] = (c7108_reg_rd16(C7108_AES_EKEY1_HI) << 16) | ++ c7108_reg_rd16(C7108_AES_EKEY1_LO); ++ dkey[2] = (c7108_reg_rd16(C7108_AES_EKEY2_HI) << 16) | ++ c7108_reg_rd16(C7108_AES_EKEY2_LO); ++ dkey[3] = (c7108_reg_rd16(C7108_AES_EKEY3_HI) << 16) | ++ c7108_reg_rd16(C7108_AES_EKEY3_LO); ++ dkey[4] = (c7108_reg_rd16(C7108_AES_EKEY4_HI) << 16) | ++ c7108_reg_rd16(C7108_AES_EKEY4_LO); ++ dkey[5] = (c7108_reg_rd16(C7108_AES_EKEY5_HI) << 16) | ++ c7108_reg_rd16(C7108_AES_EKEY5_LO); ++ dkey[6] = (c7108_reg_rd16(C7108_AES_EKEY6_HI) << 16) | ++ c7108_reg_rd16(C7108_AES_EKEY6_LO); ++ dkey[7] = (c7108_reg_rd16(C7108_AES_EKEY7_HI) << 16) | ++ c7108_reg_rd16(C7108_AES_EKEY7_LO); ++} ++ ++static int ++c7108_aes_cipher(int op, ++ u32 dst, ++ u32 src, ++ u32 len, ++ int klen, ++ u16 mode, ++ u32 key[8], ++ u8 iv[16]) ++{ ++ int rv = 0, cnt=0; ++ u16 ctrl = 0, stat = 0; ++ ++ AES_LOCK(); ++ ++ /* Setup key length */ ++ if (klen == 128) { ++ ctrl |= C7108_AES_KEY_LEN_128; ++ } else if (klen == 192) { ++ ctrl |= C7108_AES_KEY_LEN_192; ++ } else if (klen == 256) { ++ ctrl |= C7108_AES_KEY_LEN_256; ++ } else { ++ AES_UNLOCK(); ++ return -3; ++ } ++ ++ /* Check opcode */ ++ if (C7108_AES_ENCRYPT == op) { ++ ctrl |= C7108_AES_ENCRYPT; ++ } else if (C7108_AES_DECRYPT == op) { ++ ctrl |= C7108_AES_DECRYPT; ++ } else { ++ AES_UNLOCK(); ++ return -4; ++ } ++ ++ /* check mode */ ++ if ( (mode != C7108_AES_CTRL_MODE_CBC) && ++ (mode != C7108_AES_CTRL_MODE_CFB) && ++ (mode != C7108_AES_CTRL_MODE_OFB) && ++ (mode != C7108_AES_CTRL_MODE_CTR) && ++ (mode != C7108_AES_CTRL_MODE_ECB) ) { ++ AES_UNLOCK(); ++ return -5; ++ } ++ ++ /* Now set mode */ ++ ctrl |= mode; ++ ++ /* For CFB, OFB, and CTR, neither backward key ++ * expansion nor key inversion is required. ++ */ ++ if ( (C7108_AES_DECRYPT == op) && ++ (C7108_AES_CTRL_MODE_CBC == mode || ++ C7108_AES_CTRL_MODE_ECB == mode ) ){ ++ ++ /* Program Key */ ++ c7108_reg_wr16(C7108_AES_KEY0_LO, (u16) key[4]); ++ c7108_reg_wr16(C7108_AES_KEY0_HI, (u16) (key[4] >> 16)); ++ c7108_reg_wr16(C7108_AES_KEY1_LO, (u16) key[5]); ++ c7108_reg_wr16(C7108_AES_KEY1_HI, (u16) (key[5] >> 16)); ++ c7108_reg_wr16(C7108_AES_KEY2_LO, (u16) key[6]); ++ c7108_reg_wr16(C7108_AES_KEY2_HI, (u16) (key[6] >> 16)); ++ c7108_reg_wr16(C7108_AES_KEY3_LO, (u16) key[7]); ++ c7108_reg_wr16(C7108_AES_KEY3_HI, (u16) (key[7] >> 16)); ++ c7108_reg_wr16(C7108_AES_KEY6_LO, (u16) key[2]); ++ c7108_reg_wr16(C7108_AES_KEY6_HI, (u16) (key[2] >> 16)); ++ c7108_reg_wr16(C7108_AES_KEY7_LO, (u16) key[3]); ++ c7108_reg_wr16(C7108_AES_KEY7_HI, (u16) (key[3] >> 16)); ++ ++ ++ if (192 == klen) { ++ c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[7]); ++ c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[7] >> 16)); ++ c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[7]); ++ c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[7] >> 16)); ++ ++ } else if (256 == klen) { ++ /* 256 */ ++ c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[0]); ++ c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[0] >> 16)); ++ c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[1]); ++ c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[1] >> 16)); ++ ++ } ++ ++ } else { ++ /* Program Key */ ++ c7108_reg_wr16(C7108_AES_KEY0_LO, (u16) key[0]); ++ c7108_reg_wr16(C7108_AES_KEY0_HI, (u16) (key[0] >> 16)); ++ c7108_reg_wr16(C7108_AES_KEY1_LO, (u16) key[1]); ++ c7108_reg_wr16(C7108_AES_KEY1_HI, (u16) (key[1] >> 16)); ++ c7108_reg_wr16(C7108_AES_KEY2_LO, (u16) key[2]); ++ c7108_reg_wr16(C7108_AES_KEY2_HI, (u16) (key[2] >> 16)); ++ c7108_reg_wr16(C7108_AES_KEY3_LO, (u16) key[3]); ++ c7108_reg_wr16(C7108_AES_KEY3_HI, (u16) (key[3] >> 16)); ++ c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[4]); ++ c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[4] >> 16)); ++ c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[5]); ++ c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[5] >> 16)); ++ c7108_reg_wr16(C7108_AES_KEY6_LO, (u16) key[6]); ++ c7108_reg_wr16(C7108_AES_KEY6_HI, (u16) (key[6] >> 16)); ++ c7108_reg_wr16(C7108_AES_KEY7_LO, (u16) key[7]); ++ c7108_reg_wr16(C7108_AES_KEY7_HI, (u16) (key[7] >> 16)); ++ ++ } ++ ++ /* Set IV always */ ++ c7108_aes_set_hw_iv(iv); ++ ++ /* Program DMA addresses */ ++ if ((rv = c7108_aes_setup_dma(src, dst, len)) < 0) { ++ AES_UNLOCK(); ++ return rv; ++ } ++ ++ ++ /* Start AES cipher */ ++ c7108_reg_wr16(C7108_AES_CTRL, ctrl | C7108_AES_GO); ++ ++ //printk("Ctrl: 0x%x\n", ctrl | C7108_AES_GO); ++ do { ++ /* TODO: interrupt mode */ ++ // printk("aes_stat=0x%x\n", stat); ++ //udelay(100); ++ } while ((cnt++ < 1000000) && ++ !((stat=c7108_reg_rd16(C7108_AES_CTRL))&C7108_AES_OP_DONE)); ++ ++ ++ if ((mode == C7108_AES_CTRL_MODE_ECB)|| ++ (mode == C7108_AES_CTRL_MODE_CBC)) { ++ /* Save out key when the lock is held ... */ ++ c7108_aes_read_dkey(key); ++ } ++ ++ AES_UNLOCK(); ++ return 0; ++ ++} ++ ++/* ++ * Generate a new crypto device session. ++ */ ++static int ++c7108_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri) ++{ ++ struct cipher_7108 **swd; ++ u_int32_t i; ++ char *algo; ++ int mode, xfm_type; ++ ++ dprintk("%s()\n", __FUNCTION__); ++ if (sid == NULL || cri == NULL) { ++ dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__); ++ return EINVAL; ++ } ++ ++ if (c7108_sessions) { ++ for (i = 1; i < c7108_sesnum; i++) ++ if (c7108_sessions[i] == NULL) ++ break; ++ } else ++ i = 1; /* NB: to silence compiler warning */ ++ ++ if (c7108_sessions == NULL || i == c7108_sesnum) { ++ if (c7108_sessions == NULL) { ++ i = 1; /* We leave c7108_sessions[0] empty */ ++ c7108_sesnum = CRYPTO_SW_SESSIONS; ++ } else ++ c7108_sesnum *= 2; ++ ++ swd = kmalloc(c7108_sesnum * sizeof(struct cipher_7108 *), ++ GFP_ATOMIC); ++ if (swd == NULL) { ++ /* Reset session number */ ++ if (c7108_sesnum == CRYPTO_SW_SESSIONS) ++ c7108_sesnum = 0; ++ else ++ c7108_sesnum /= 2; ++ dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__); ++ return ENOBUFS; ++ } ++ memset(swd, 0, c7108_sesnum * sizeof(struct cipher_7108 *)); ++ ++ /* Copy existing sessions */ ++ if (c7108_sessions) { ++ memcpy(swd, c7108_sessions, ++ (c7108_sesnum / 2) * sizeof(struct cipher_7108 *)); ++ kfree(c7108_sessions); ++ } ++ ++ c7108_sessions = swd; ++ ++ } ++ ++ swd = &c7108_sessions[i]; ++ *sid = i; ++ ++ while (cri) { ++ *swd = (struct cipher_7108 *) ++ kmalloc(sizeof(struct cipher_7108), GFP_ATOMIC); ++ if (*swd == NULL) { ++ c7108_freesession(NULL, i); ++ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__); ++ return ENOBUFS; ++ } ++ memset(*swd, 0, sizeof(struct cipher_7108)); ++ ++ algo = NULL; ++ mode = 0; ++ xfm_type = HW_TYPE_CIPHER; ++ ++ switch (cri->cri_alg) { ++ ++ case CRYPTO_AES_CBC: ++ algo = "aes"; ++ mode = CRYPTO_TFM_MODE_CBC; ++ c7108_crypto_mode = C7108_AES_CTRL_MODE_CBC; ++ break; ++#if 0 ++ case CRYPTO_AES_CTR: ++ algo = "aes_ctr"; ++ mode = CRYPTO_TFM_MODE_CBC; ++ c7108_crypto_mode = C7108_AES_CTRL_MODE_CTR; ++ break; ++ case CRYPTO_AES_ECB: ++ algo = "aes_ecb"; ++ mode = CRYPTO_TFM_MODE_CBC; ++ c7108_crypto_mode = C7108_AES_CTRL_MODE_ECB; ++ break; ++ case CRYPTO_AES_OFB: ++ algo = "aes_ofb"; ++ mode = CRYPTO_TFM_MODE_CBC; ++ c7108_crypto_mode = C7108_AES_CTRL_MODE_OFB; ++ break; ++ case CRYPTO_AES_CFB: ++ algo = "aes_cfb"; ++ mode = CRYPTO_TFM_MODE_CBC; ++ c7108_crypto_mode = C7108_AES_CTRL_MODE_CFB; ++ break; ++#endif ++ default: ++ printk("unsupported crypto algorithm: %d\n", ++ cri->cri_alg); ++ return -EINVAL; ++ break; ++ } ++ ++ ++ if (!algo || !*algo) { ++ printk("cypher_7108_crypto: Unknown algo 0x%x\n", ++ cri->cri_alg); ++ c7108_freesession(NULL, i); ++ return EINVAL; ++ } ++ ++ if (xfm_type == HW_TYPE_CIPHER) { ++ if (debug) { ++ dprintk("%s key:", __FUNCTION__); ++ for (i = 0; i < (cri->cri_klen + 7) / 8; i++) ++ dprintk("%s0x%02x", (i % 8) ? " " : "\n ", ++ cri->cri_key[i]); ++ dprintk("\n"); ++ } ++ ++ } else if (xfm_type == SW_TYPE_HMAC || ++ xfm_type == SW_TYPE_HASH) { ++ printk("cypher_7108_crypto: HMAC unsupported!\n"); ++ return -EINVAL; ++ c7108_freesession(NULL, i); ++ } else { ++ printk("cypher_7108_crypto: " ++ "Unhandled xfm_type %d\n", xfm_type); ++ c7108_freesession(NULL, i); ++ return EINVAL; ++ } ++ ++ (*swd)->cri_alg = cri->cri_alg; ++ (*swd)->xfm_type = xfm_type; ++ ++ cri = cri->cri_next; ++ swd = &((*swd)->next); ++ } ++ return 0; ++} ++ ++/* ++ * Free a session. ++ */ ++static int ++c7108_freesession(void *arg, u_int64_t tid) ++{ ++ struct cipher_7108 *swd; ++ u_int32_t sid = CRYPTO_SESID2LID(tid); ++ ++ dprintk("%s()\n", __FUNCTION__); ++ if (sid > c7108_sesnum || c7108_sessions == NULL || ++ c7108_sessions[sid] == NULL) { ++ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__); ++ return(EINVAL); ++ } ++ ++ /* Silently accept and return */ ++ if (sid == 0) ++ return(0); ++ ++ while ((swd = c7108_sessions[sid]) != NULL) { ++ c7108_sessions[sid] = swd->next; ++ kfree(swd); ++ } ++ return 0; ++} ++ ++/* ++ * Process a hardware request. ++ */ ++static int ++c7108_process(void *arg, struct cryptop *crp, int hint) ++{ ++ struct cryptodesc *crd; ++ struct cipher_7108 *sw; ++ u_int32_t lid; ++ int type; ++ u32 hwkey[8]; ++ ++#define SCATTERLIST_MAX 16 ++ struct scatterlist sg[SCATTERLIST_MAX]; ++ int sg_num, sg_len, skip; ++ struct sk_buff *skb = NULL; ++ struct uio *uiop = NULL; ++ ++ dprintk("%s()\n", __FUNCTION__); ++ /* Sanity check */ ++ if (crp == NULL) { ++ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__); ++ return EINVAL; ++ } ++ ++ crp->crp_etype = 0; ++ ++ if (crp->crp_desc == NULL || crp->crp_buf == NULL) { ++ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__); ++ crp->crp_etype = EINVAL; ++ goto done; ++ } ++ ++ lid = crp->crp_sid & 0xffffffff; ++ if (lid >= c7108_sesnum || lid == 0 || c7108_sessions == NULL || ++ c7108_sessions[lid] == NULL) { ++ crp->crp_etype = ENOENT; ++ dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__); ++ goto done; ++ } ++ ++ /* ++ * do some error checking outside of the loop for SKB and IOV ++ * processing this leaves us with valid skb or uiop pointers ++ * for later ++ */ ++ if (crp->crp_flags & CRYPTO_F_SKBUF) { ++ skb = (struct sk_buff *) crp->crp_buf; ++ if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) { ++ printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", ++ __FILE__, __LINE__, ++ skb_shinfo(skb)->nr_frags); ++ goto done; ++ } ++ } else if (crp->crp_flags & CRYPTO_F_IOV) { ++ uiop = (struct uio *) crp->crp_buf; ++ if (uiop->uio_iovcnt > SCATTERLIST_MAX) { ++ printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", ++ __FILE__, __LINE__, ++ uiop->uio_iovcnt); ++ goto done; ++ } ++ } ++ ++ /* Go through crypto descriptors, processing as we go */ ++ for (crd = crp->crp_desc; crd; crd = crd->crd_next) { ++ /* ++ * Find the crypto context. ++ * ++ * XXX Note that the logic here prevents us from having ++ * XXX the same algorithm multiple times in a session ++ * XXX (or rather, we can but it won't give us the right ++ * XXX results). To do that, we'd need some way of differentiating ++ * XXX between the various instances of an algorithm (so we can ++ * XXX locate the correct crypto context). ++ */ ++ for (sw = c7108_sessions[lid]; ++ sw && sw->cri_alg != crd->crd_alg; ++ sw = sw->next) ++ ; ++ ++ /* No such context ? */ ++ if (sw == NULL) { ++ crp->crp_etype = EINVAL; ++ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__); ++ goto done; ++ } ++ ++ skip = crd->crd_skip; ++ ++ /* ++ * setup the SG list skip from the start of the buffer ++ */ ++ memset(sg, 0, sizeof(sg)); ++ if (crp->crp_flags & CRYPTO_F_SKBUF) { ++ int i, len; ++ type = CRYPTO_BUF_SKBUF; ++ ++ sg_num = 0; ++ sg_len = 0; ++ ++ if (skip < skb_headlen(skb)) { ++ //sg[sg_num].page = virt_to_page(skb->data + skip); ++ //sg[sg_num].offset = offset_in_page(skb->data + skip); ++ len = skb_headlen(skb) - skip; ++ if (len + sg_len > crd->crd_len) ++ len = crd->crd_len - sg_len; ++ //sg[sg_num].length = len; ++ sg_set_page(&sg[sg_num], virt_to_page(skb->data + skip), len, offset_in_page(skb->data + skip)); ++ sg_len += sg[sg_num].length; ++ sg_num++; ++ skip = 0; ++ } else ++ skip -= skb_headlen(skb); ++ ++ for (i = 0; sg_len < crd->crd_len && ++ i < skb_shinfo(skb)->nr_frags && ++ sg_num < SCATTERLIST_MAX; i++) { ++ if (skip < skb_shinfo(skb)->frags[i].size) { ++ //sg[sg_num].page = skb_shinfo(skb)->frags[i].page; ++ //sg[sg_num].offset = skb_shinfo(skb)->frags[i].page_offset + skip; ++ len = skb_shinfo(skb)->frags[i].size - skip; ++ if (len + sg_len > crd->crd_len) ++ len = crd->crd_len - sg_len; ++ //sg[sg_num].length = len; ++ sg_set_page(&sg[sg_num], skb_shinfo(skb)->frags[i].page, len, skb_shinfo(skb)->frags[i].page_offset + skip); ++ sg_len += sg[sg_num].length; ++ sg_num++; ++ skip = 0; ++ } else ++ skip -= skb_shinfo(skb)->frags[i].size; ++ } ++ } else if (crp->crp_flags & CRYPTO_F_IOV) { ++ int len; ++ type = CRYPTO_BUF_IOV; ++ sg_len = 0; ++ for (sg_num = 0; sg_len < crd->crd_len && ++ sg_num < uiop->uio_iovcnt && ++ sg_num < SCATTERLIST_MAX; sg_num++) { ++ if (skip < uiop->uio_iov[sg_num].iov_len) { ++ //sg[sg_num].page = virt_to_page(uiop->uio_iov[sg_num].iov_base+skip); ++ //sg[sg_num].offset = offset_in_page(uiop->uio_iov[sg_num].iov_base+skip); ++ len = uiop->uio_iov[sg_num].iov_len - skip; ++ if (len + sg_len > crd->crd_len) ++ len = crd->crd_len - sg_len; ++ //sg[sg_num].length = len; ++ sg_set_page(&sg[sg_num], virt_to_page(uiop->uio_iov[sg_num].iov_base+skip), len, offset_in_page(uiop->uio_iov[sg_num].iov_base+skip)); ++ sg_len += sg[sg_num].length; ++ skip = 0; ++ } else ++ skip -= uiop->uio_iov[sg_num].iov_len; ++ } ++ } else { ++ type = CRYPTO_BUF_CONTIG; ++ //sg[0].page = virt_to_page(crp->crp_buf + skip); ++ //sg[0].offset = offset_in_page(crp->crp_buf + skip); ++ sg_len = (crp->crp_ilen - skip); ++ if (sg_len > crd->crd_len) ++ sg_len = crd->crd_len; ++ //sg[0].length = sg_len; ++ sg_set_page(&sg[0], virt_to_page(crp->crp_buf + skip), sg_len, offset_in_page(crp->crp_buf + skip)); ++ sg_num = 1; ++ } ++ ++ ++ switch (sw->xfm_type) { ++ ++ case HW_TYPE_CIPHER: { ++ ++ unsigned char iv[64]; ++ unsigned char *ivp = iv; ++ int i; ++ int ivsize = 16; /* fixed for AES */ ++ int blocksize = 16; /* fixed for AES */ ++ ++ if (sg_len < blocksize) { ++ crp->crp_etype = EINVAL; ++ dprintk("%s,%d: EINVAL len %d < %d\n", ++ __FILE__, __LINE__, ++ sg_len, ++ blocksize); ++ goto done; ++ } ++ ++ if (ivsize > sizeof(iv)) { ++ crp->crp_etype = EINVAL; ++ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__); ++ goto done; ++ } ++ ++ if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */ ++ ++ if (crd->crd_flags & CRD_F_IV_EXPLICIT) { ++ ivp = crd->crd_iv; ++ } else { ++ get_random_bytes(ivp, ivsize); ++ } ++ /* ++ * do we have to copy the IV back to the buffer ? ++ */ ++ if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) { ++ crypto_copyback(crp->crp_buf, ++ crd->crd_inject, ++ ivsize, ++ (caddr_t)ivp); ++ } ++ ++ c7108_xlate_key(crd->crd_klen, ++ (u8*)crd->crd_key, (u32*)hwkey); ++ ++ /* Encrypt SG list */ ++ for (i = 0; i < sg_num; i++) { ++ sg[i].dma_address = ++ dma_map_single(NULL, ++ kmap(sg_page(&sg[i])) + sg[i].offset, sg_len, DMA_BIDIRECTIONAL); ++#if 0 ++ printk("sg[%d]:0x%08x, off 0x%08x " ++ "kmap 0x%08x phys 0x%08x\n", ++ i, sg[i].page, sg[i].offset, ++ kmap(sg[i].page) + sg[i].offset, ++ sg[i].dma_address); ++#endif ++ c7108_aes_cipher(C7108_AES_ENCRYPT, ++ sg[i].dma_address, ++ sg[i].dma_address, ++ sg_len, ++ crd->crd_klen, ++ c7108_crypto_mode, ++ hwkey, ++ ivp); ++ ++ if ((c7108_crypto_mode == C7108_AES_CTRL_MODE_CBC)|| ++ (c7108_crypto_mode == C7108_AES_CTRL_MODE_ECB)) { ++ /* Read back expanded key and cache it in key ++ * context. ++ * NOTE: for ECB/CBC modes only (not CTR, CFB, OFB) ++ * where you set the key once. ++ */ ++ c7108_cache_key(crd->crd_klen, ++ (u32*)hwkey, (u8*)crd->crd_key); ++#if 0 ++ printk("%s expanded key:", __FUNCTION__); ++ for (i = 0; i < (crd->crd_klen + 7) / 8; i++) ++ printk("%s0x%02x", (i % 8) ? " " : "\n ", ++ crd->crd_key[i]); ++ printk("\n"); ++#endif ++ } ++ } ++ } ++ else { /*decrypt */ ++ ++ if (crd->crd_flags & CRD_F_IV_EXPLICIT) { ++ ivp = crd->crd_iv; ++ } else { ++ crypto_copydata(crp->crp_buf, crd->crd_inject, ++ ivsize, (caddr_t)ivp); ++ } ++ ++ c7108_xlate_key(crd->crd_klen, ++ (u8*)crd->crd_key, (u32*)hwkey); ++ ++ /* Decrypt SG list */ ++ for (i = 0; i < sg_num; i++) { ++ sg[i].dma_address = ++ dma_map_single(NULL, ++ kmap(sg_page(&sg[i])) + sg[i].offset, ++ sg_len, DMA_BIDIRECTIONAL); ++ ++#if 0 ++ printk("sg[%d]:0x%08x, off 0x%08x " ++ "kmap 0x%08x phys 0x%08x\n", ++ i, sg[i].page, sg[i].offset, ++ kmap(sg[i].page) + sg[i].offset, ++ sg[i].dma_address); ++#endif ++ c7108_aes_cipher(C7108_AES_DECRYPT, ++ sg[i].dma_address, ++ sg[i].dma_address, ++ sg_len, ++ crd->crd_klen, ++ c7108_crypto_mode, ++ hwkey, ++ ivp); ++ } ++ } ++ } break; ++ case SW_TYPE_HMAC: ++ case SW_TYPE_HASH: ++ crp->crp_etype = EINVAL; ++ goto done; ++ break; ++ ++ case SW_TYPE_COMP: ++ crp->crp_etype = EINVAL; ++ goto done; ++ break; ++ ++ default: ++ /* Unknown/unsupported algorithm */ ++ dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__); ++ crp->crp_etype = EINVAL; ++ goto done; ++ } ++ } ++ ++done: ++ crypto_done(crp); ++ return 0; ++} ++ ++static struct { ++ softc_device_decl sc_dev; ++} a7108dev; ++ ++static device_method_t a7108_methods = { ++/* crypto device methods */ ++ DEVMETHOD(cryptodev_newsession, c7108_newsession), ++ DEVMETHOD(cryptodev_freesession, c7108_freesession), ++ DEVMETHOD(cryptodev_process, c7108_process), ++ DEVMETHOD(cryptodev_kprocess, NULL) ++}; ++ ++static int ++cypher_7108_crypto_init(void) ++{ ++ dprintk("%s(%p)\n", __FUNCTION__, cypher_7108_crypto_init); ++ ++ iobar = (unsigned long)ioremap(CCU_AES_R