diff -ruN linux-2.2.5,pristine/Documentation/Configure.help linux-2.2.5/Documentation/Configure.help --- linux-2.2.5,pristine/Documentation/Configure.help Fri Mar 26 22:23:20 1999 +++ linux-2.2.5/Documentation/Configure.help Thu Apr 1 23:05:44 1999 @@ -231,6 +231,131 @@ Most users will answer N here. +General encryption support (EXPERIMENTAL)' +CONFIG_BLK_DEV_LOOP_GEN + [1998-12-02] + If you answer yes to this option, the loop-driver will support all + crypto algorithms selected in the crypto library (see the 'Crypto' + menu entry in the main menu). + + This loop module will use the ciphers in CBC-mode which is more + secure than ECB-mode. This module will also initialize the CBC-mode + of the cipher with the block-number of the block being encrypted. + +DFC encryption (EXPERIMENTAL - Read Help) +CONFIG_BLK_DEV_LOOP_DFC + [1998-10-13] + DFC (The Decorrelated Fast Cipher) from CNRS and France Telecom is a + candidate algorithm for the Advanced Encryption Standard (AES). + + It is unknown (to me) whether DFC is covered by patents. + + This loop module uses the weak ECB-mode which means that it is more + open to certain attacks than CBC-mode ciphers. + +MARS encryption (EXPERIMENTAL - Read Help) +CONFIG_BLK_DEV_LOOP_MARS + [1998-10-13] + MARS is IBM's candidate algorithm for the Advanded Encryption + Standard (AES). Refer to IBM for any copyright, patent or license + issues for the MARS algorithm. + + MARS is a fast algorithm achieving speeds up to 66Mbit on a Pentium + Pro 200. + + NOTE: MARS is covered by patents and might be illegal to use in many + cases. + + This loop module uses the weak ECB-mode which means that it is more + open to certain attacks than CBC-mode ciphers. + +RC6 encryption (EXPERIMENTAL - Read Help) +CONFIG_BLK_DEV_LOOP_RC6 + [1998-10-13] + RC6 is invented by Ron Rivest and RSA Labs. It is a candidate for + the Advanced Encryption Standard (AES). Refer to RSA Labs and Ron + Rivest for any copyright, patent or license issues for the RC6 + algorithm. + + RC6 is a simple and fast algorithm achieving speeds up to 88Mbit on + a Pentium Pro 200. It makes use of multiplication and + data-dependent rotations which reduces the number of rounds + necessary and increases its speed. + + NOTE: RC6 is covered by patents and might be illegal to use in many + cases. + + This loop module uses the weak ECB-mode which means that it is more + open to certain attacks than CBC-mode ciphers. + +Serpent encryption +CONFIG_BLK_DEV_LOOP_SERPENT + [1998-10-13] + Serpent is a 128-bit block cipher designed by Ross Anderson, Eli + Biham and Lars Knudsen as a candidate for the Advanced Encryption + Standard. Serpent provides users with the highest practical level + of assurance that no shortcut attack will be found. To achieve + this, the algorithm uses well understood mechanisms so that its + security relies on the wide experience of block cipher + cryptoanalysis. The algorithm uses twice as many rounds as are + necessary to block all currently known shortcut attacks. The + algorithm is designed to have a service life of 50 years and to + continue to protect legacy data for a further 50 years beyond + that. + + Despite these exacting design constraints, Serpent is faster than + DES. Its design supports a very efficient bitslice implementation, + and this implementation runs at almost 25 Mbit/sec on a + 200MHz Pentium (compared with about 15 Mbit/sec for DES). + + Serpent is completely in the public domain, and no restrictions are + imposed on its use. + + More information about Serpent: + http://www.cl.cam.ac.uk/~rja14/serpent.html + + More information about the implementation: + http://www.seven77.demon.co.uk/crypto_technology.htm + + This loop module uses the weak ECB-mode which means that it is more + open to certain attacks than CBC-mode ciphers. + +CAST 128 encryption +CONFIG_BLK_DEV_LOOP_CAST + This module implements CAST-128. The algorithm + was published in RFC 2144 as a proposed Internet standard, and is + from Entrust (http://www.entrust.com/) a Canadian company. + + This loop module uses the weak ECB-mode which means that it is more + open to certain attacks than CBC-mode ciphers. + +IDEA encryption +CONFIG_BLK_DEV_LOOP_IDEA + The IDEA code is mostly from ASCOM (http://www.ascom.com/) and + licensed for non-commercial use. + + This module may contain algorithms which are patented, and/or + require licensing for commerical use. Please read + drivers/block/loop_idea.c for details. + +Twofish encryption (only as module) +CONFIG_BLK_DEV_LOOP_FISH2 + Twofish is a quite new algorithm invented by Bruce Schneier, Doug + Whiting, John Kelsey, Chris Hall and David Wagner, for more + information see www.counterpane.com; look for twofish. Blowfish is + the older algorithm and was also invented by Bruce Schneier. Both + algorithms are free of licensing charges at the moment. + + This module operates twofish in CBC-mode + +Blowfish encryption (only as module) +CONFIG_BLK_DEV_LOOP_BLOW + Blowfish is an algorithm invented by Bruce Schneier. For more + information about the algorithm see www.counterpane.com; look for + blowfish. There are no licensing charges for using Blowfish. + + This module operates blowfish in CBC-mode + Network Block Device support CONFIG_BLK_DEV_NBD Saying Y here will allow your computer to be a client for network diff -ruN linux-2.2.5,pristine/Documentation/crypto/00-INDEX linux-2.2.5/Documentation/crypto/00-INDEX --- linux-2.2.5,pristine/Documentation/crypto/00-INDEX Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/Documentation/crypto/00-INDEX Thu Apr 1 23:05:44 1999 @@ -0,0 +1,18 @@ +This directory contains patches and documentation to code in the kernel that +contains crypto + - Alexander Kjeldaas + +ENskip-patch + - Patch for ENskip-0.67 for Linux 2.1.118 and glibc. + By Bob Tracy . +util-linux-2.9e.patch + - Updated version of crypt-mount.patch including support + for more ciphers. Relative to util-linux-2.9e. +crypt-mount.patch + - Patch to mount-2.7l (and possibly later) by + Ingo Rohloff . Use this for the + blowfish and twofish modules +loop-mount-13.patch + - Patch to mount-2.7l by Andrew E. Mileski . Use + this for the idea and cast modules. + diff -ruN linux-2.2.5,pristine/Documentation/crypto/ChangeLog linux-2.2.5/Documentation/crypto/ChangeLog --- linux-2.2.5,pristine/Documentation/crypto/ChangeLog Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/Documentation/crypto/ChangeLog Thu Apr 1 23:05:44 1999 @@ -0,0 +1,304 @@ +1999-01-29 Alexander Kjeldaas + + * International kernel patch 2.2.1.1 released. + +1998-01-29 Patrice Lacroix + + * /proc/crypto support. + +1999-01-27 Alexander Kjeldaas + + * International kernel patch 2.2.0.2 released. + + * missing #endif in net/ipv4/ip_output.c in latest patch + fixed. Missing #include fixed in crypto.h + +1999-01-26 Alexander Kjeldaas + + * International kernel patch 2.2.0.1 released. + + * Merged Frank Bernard's latest ENskip patches. + +1999-01-18 Alexander Kjeldaas + + * International kernel patch 2.2.0-pre7.4 released. + + * Added cbc-mode to cast256 cipher. + + * Removed spam on unload from crypto modules. + + * Added updated ENskip patches from Frank Bernard's web site: + http://www.linux-firewall.de/enskip/ + + * International kernel patch 2.2.0-pre7.3 released. + + * Added missing cleanup_module to DES, Blowfish and IDEA ciphers. + + * International kernel patch 2.2.0-pre7.2 released. + + * Cleanup in drivers/block/Config.in. It was possible to create + an invalid .config file. + + * Minor crypto/api.c cleanup. + +1999-01-17 Alexander Kjeldaas + + * International kernel patch 2.2.0-pre7.1 released. + + * Added testcip.c - a general purpose cipher test program. Added + test-vector scripts for Blowfish, DES, Mars, and Serpent. + + * Naming error left users unable to compile loop_gen unless it was + compiled as a module. + + * Updated Serpent implementation. Sam Simpson has been running a + background task on a cluster of high performance servers. After a + search involving around 1000 machine hours improved sboxes were + found. + + * Updated RC6 implementation. Supposedly faster. + + * Updated MARS implementation. Fixes a bug in mars_set_key. + +1999-01-07 Alexander Kjeldaas + + * International kernel patch 2.2.0-pre5.1 released. + * Merged with vanilla 2.2.0-pre5 + +1999-01-05 Herbert Valerio Riedel + + * APX fixes. + +1999-01-04 Alexander Kjeldaas + + * International kernel patch 2.2.0-pre4.1 released. + + * Removed obsolete loop_idea.c and loop_blow.c since IDEA and + blowfish algorithms have been added to the crypto library. + + * drivers/block/ll_rw_blk.c: Added loop_gen_init. loop_gen only + worked as a module. + +1998-12-30 Alexander Kjeldaas + + * crypto/testing/speed.c: i386-specific timer-code removed. + + * crypto configuration added for all architectures (previously + only i386 was supported). However, 64-bit and endian issues needs + to be ironed out for a lot of platforms (maybe even i386). + +1998-12-29 Alexander Kjeldaas + + * International kernel patch 2.2.0-pre1.1 released. + * International kernel patch 2.1.131.8 released. + * DES/IDEA compile fixes. + +1998-12-29 Raimar Falke + + * DES cipher added. crypto/testing/speed.c fixes. + +1998-12-18 Alexander Kjeldaas + + * International kernel patch 2.1.131.7 released. + +1998-12-18 Raimar Falke + + * include-fixes for IDEA cipher. + +1998-12-18 Alexander Kjeldaas + + * International kernel patch 2.1.131.6 released. + +1998-12-18 Raimar Falke + + * IDEA cipher added. + +1998-12-18 Patrice Lacroix + + * My latest patch for modular loop encryption. I think everything + is in there. Ciphers are only requested on LOOP_SET_STATUS. Module + count is always right (for what I have tested) and unloading now + works. + +1998-12-17 Alexander Kjeldaas + + * International kernel patch 2.1.131.5 released. + +1998-12-17 Raimar Falke + + * Extracted the blowfish code from loop_blow and made a + cipher-module of it. + +1998-12-17 Alexander Kjeldaas + + * Removed loop_serpent, loop_mars, loop_dfc and loop_rc6 since + their funcionality is available through loop_gen. + +1998-12-16 Alexander Kjeldaas + + * Removed loop_idea from the configuration menus. It hasn't been + converted to the new API. + +1998-12-14 Alexander Kjeldaas + + * Fixes to the rijndael cipher. It builds, but isn't working + properly so it it disabled for the moment. The cipher is from + Dr. Brian Gladman AES + reimplementation project. More information on rijndael: + http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ Rijndael is free. + +1998-12-14 Patrice Lacroix + + * More modular ciphers/loop patches. Cipher locking fixes. + Autoloading of ciphers. More loop and loop_gen integration. + +1998-12-14 Alexander Kjeldaas + + * International kernel patch 2.1.131.4 released. + + * Added util-linux-2.9e patch to Documentation/crypto that makes + all the loopback ciphers available to the losetup utility. + +1998-12-12 Alexander Kjeldaas + + * International kernel patch 2.1.131.3 released. + + * Added the popular CIPE (crypto IP encapsulation) made by + Olaf Titz + + * Previous patch wouldn't build. International kernel patch + 2.1.131.2 released. + +1998-12-11 Alexander Kjeldaas + + * International kernel patch 2.1.131.1 released. + + * Clear sensitive memory before kfree in generel loop module. New + upstream kernel. + +1998-12-11 Patrice Lacroix + + * Modular ciphers + +1998-11-30 Alexander Kjeldaas + + * International kernel patch 2.1.130.1 released. + + * loop-devices other than loop_gen updated to use new interface. + However, the block-number isn't used for anything yet. + + * loop_gen.c: Now we use the ciphers in cbc-mode only. Also, the + IV of the cipher is initialized based on block-number. + + * Added general cbc-mode that is simply #included into the + ciphers. cbc-mode thus added to serpent, mars, rc6 and dfc. + + * Added ivsize to struct cipher_implementation. + + * Added for_each_cipher function + + * Added X11-like license for the crypto-directory. The code might + be useable for other projects as well in the future. [And GPL is + arguable the wrong license for crypto]. + +1998-11-25 Alexander Kjeldaas + + * The crypto api is useable from modules. + + * Fixed a bunch of bugs in loop_gen. I think the oopses are gone. + +1998-11-23 Alexander Kjeldaas + + * International kernel patch 2.1.129.4 released. + + * Added crypto/testing/speed.c to test the speed of the different + crypto algorithms. + + * cast256, crypton, rijndael, safer, and twofish added, but they + are not yet completely ported to the crypto-library. + + * Updated implementations of MARS, DFC, RC6 and SERPENT. + +1998-11-22 Alexander Kjeldaas + + * International kernel patch 2.1.129.3 released. + + * "loop_gen" - skeleton of general loop crypto driver added + + * Made loop-modules for DFC, MARS, and RC6 + + * Added DFC, MARS, and RC6 to crypto library + + * International kernel patch 2.1.129.2 released. + + * Updated documentation to show which loopback modules are ECB + and which are CBC. + + * Kernel crypto library on its way. Serpent is the first member. + + * Changed memcpy to memset in loop_blow.c to close a possible + plaintext leak. + +1998-11-20 Alexander Kjeldaas + + * New upstream kernel release 2.1.129 + +1998-11-13 Alexander Kjeldaas + + * New upstream kernel release 2.1.128 + +1998-11-09 Alexander Kjeldaas + + * New upstream kernel release 2.1.127 + +1998-10-12 Alexander Kjeldaas + + * drivers/block/loop_serpent.c: Made wrapper-module for the + serpent cipher. + + * crypto/serpent.c crypto/serpent_f_box.h}: Added serpent + implementation from Dr. B R Gladman + AES reimplementation project. + + * drivers/block/Config.in: Loopback crypto flagged experimental + +1998-10-09 Alexander Kjeldaas + + * International kernel patch 2.1.125.1 released. + + * New upstream kernel release 2.1.125 + +1998-10-08 Alexander Kjeldaas + + * International kernel patch 2.1.124.2 released. + + * Added Andi Kleene's loop fixes. Updated twofish, blowfish and + cast128 modules to use the new lock/unlock interface. + +1998-10-07 Alexander Kjeldaas + + * Ported loop_cast.c to the new loopback API interface. + + * Blowfish and Twofish can be compiled in instead of being + modules. + + * Added cast and idea to the config-system. + + * Wrote Configure.help entries for the loop crypto patches. + +1998-10-05 Alexander Kjeldaas + + * International kernel patch 2.1.124.1 released. + + * Added cast128 and idea loopback modules from Andrew E. Mileski's + loop-13.tar.gz package. + + * Added latest ENskip patches from Bob Tracy + +1998-10-05 Ingo Rohloff + + * Fixed bug in loop.c regarding handling of calls to + loop_release_xfer() + + * Added modules for blowfish and twofish to the loopback + filesystem diff -ruN linux-2.2.5,pristine/Documentation/crypto/ENskip-patch linux-2.2.5/Documentation/crypto/ENskip-patch --- linux-2.2.5,pristine/Documentation/crypto/ENskip-patch Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/Documentation/crypto/ENskip-patch Thu Apr 1 23:05:44 1999 @@ -0,0 +1,943 @@ +--- ENskip-0.67/Makefile.orig Sun May 25 11:04:47 1997 ++++ ENskip-0.67/Makefile Thu Apr 9 16:34:17 1998 +@@ -48,7 +48,8 @@ + FLAGS_linux_KERNEL = -fomit-frame-pointer -fno-strength-reduce -O2 -DKERNEL -D__KERNEL__ -DMODULE -Wall -pipe -I`pwd`/../linux -I/usr/src/linux/include + FLAGS_linux_USER = -g -O2 -Wall -pipe -I/usr/include -I`pwd`/../skipd -I`pwd`/../linux -I/usr/src/linux/include + FLAGS_linux_CERT = $(FLAGS_linux_USER) +-LIBS_linux_USER = ++# Add -lg++ for g++-2.8.1: use of libg++ is deprecated. ++LIBS_linux_USER = -lg++ + + #if you are forced to use the SUN compiler + #DIR_solaris = solaris +--- ENskip-0.67/linux/interface.c.orig Wed Feb 5 15:37:14 1997 ++++ ENskip-0.67/linux/interface.c Tue Aug 18 19:32:44 1998 +@@ -22,13 +22,14 @@ + #include "config.h" + #define __NO_VERSION__ + #include +-#include +-#include +-#include +-#include +-#include ++#include ++#include ++#include ++#include ++#include "ip.h" /* __USE_BSD section only */ + #include + #include ++#include + #include + #include + #include +@@ -54,7 +55,7 @@ + + + /* This function copies an skb, growing it to "size" bytes. +- Mostly derived from the Linux 2.0.25 skb_copy function. */ ++ Mostly derived from the Linux 2.1.92 skb_copy function. */ + + static struct sk_buff *skb_expand_copy(struct sk_buff *skb, int size) + { +@@ -63,8 +64,6 @@ + + /* Allocate the copy buffer */ + +- IS_SKB(skb); +- + n = alloc_skb(size, GFP_ATOMIC); + if (n == NULL) + return NULL; +@@ -80,33 +79,25 @@ + + /* Copy the bytes */ + memcpy(n->head, skb->head, skb->end - skb->head); +- n->link3 = NULL; +- n->list = NULL; +- n->sk = NULL; +- n->when = skb->when; +- n->dev = skb->dev; +- n->h.raw = skb->h.raw + offset; +- n->mac.raw = skb->mac.raw + offset; +- n->ip_hdr = (struct iphdr *)(((char *)skb->ip_hdr) + offset); +- n->saddr = skb->saddr; +- n->daddr = skb->daddr; +- n->raddr = skb->raddr; +- n->seq = skb->seq; +- n->end_seq = skb->end_seq; +- n->ack_seq = skb->ack_seq; +- n->acked = skb->acked; +- memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv)); +- n->used = skb->used; +- n->free = 1; +- n->arp = skb->arp; +- n->tries = 0; +- n->lock = 0; +- n->users = 0; +- n->pkt_type= skb->pkt_type; +- n->stamp = skb->stamp; ++ n->csum = skb->csum; ++ n->list = NULL; ++ n->sk = NULL; ++ n->dev = skb->dev; ++ n->priority = skb->priority; ++ n->protocol = skb->protocol; ++ n->dst = dst_clone(skb->dst); ++ n->h.raw = skb->h.raw + offset; ++ n->nh.raw = skb->nh.raw + offset; ++ n->mac.raw = skb->mac.raw + offset; ++ memcpy(n->cb, skb->cb, sizeof(skb->cb)); ++ n->used = skb->used; ++ n->is_clone = 0; ++ atomic_set(&n->users, 1); ++ n->pkt_type = skb->pkt_type; ++ n->stamp = skb->stamp; ++ n->destructor = NULL; ++ n->security = skb->security; + +- IS_SKB(n); +- + return n; + } + +@@ -128,9 +119,9 @@ + /* first "segment descriptor" (the one and only we actually use) */ + mb->ms = ms; + /* offset == offset of IP header in data area */ +- mb->offset = (u_char *) skb->ip_hdr - skb->head; ++ mb->offset = (u_char *) skb->nh.iph - skb->head; + /* len == length of IP packet */ +- mb->len = ntohs(skb->ip_hdr->tot_len); ++ mb->len = ntohs(skb->nh.iph->tot_len); + + /* ptr == pointer to the data area in first segment descriptor */ + ms->ptr = skb->head; +@@ -180,7 +171,7 @@ + int input_packet(struct firewall_ops *this, int pf, struct device *dev, + void *phdr, void *arg, struct sk_buff **pskb) + { +- struct iphdr *ipp = (*pskb)->ip_hdr; ++ struct iphdr *ipp = (*pskb)->nh.iph; + int tot_len = ntohs(ipp->tot_len); + struct sk_buff *newm, *qskb; + int result; +@@ -222,8 +213,8 @@ + + } + +- if ((*pskb)->proto_priv[15] & RCV_SEC) +- return FW_SKIP; ++ if ((*pskb)->security & RCV_SEC) ++ return FW_SKIP; /* Already processed this packet. */ + + /* never change transparent UDP ports needed for discovery */ + if ((ipp->protocol == IPPROTO_UDP) && +@@ -247,7 +238,7 @@ + + save_flags(flags); + cli(); +- ++ + /* Clone the input skb. This operation locks the data of the input skb, + so we can queue it. Be careful not to free the skb while it is queued! */ + qskb = newm = skb_clone(*pskb, GFP_ATOMIC); +@@ -259,17 +250,24 @@ + skb2memblk(newm, &oldmb, oldms); + + +- result = skip_process(SKIP_INPUT, NULL, NULL, (void *) &newm, &oldmb, &newmb); ++ result = skip_process(SKIP_INPUT, NULL, NULL, (void **) &newm, &oldmb, &newmb); + + + if (result == SKIP_PROCESSED) { + /* nothing happened */ + +- kfree_skb(newm, FREE_WRITE); + if (newm != qskb) +- kfree_skb(qskb, FREE_WRITE); ++ kfree_skb(qskb); ++ kfree_skb(newm); + +- newm->proto_priv[15] = RCV_SEC; ++ /* ++ * Original code had "newm->security = RCV_SEC;" below. This ++ * was an artifact from the Solaris port where the new mblk_t ++ * gets put on the input queue, and is incorrect in the current ++ * context because newm is freed above: if "nothing happened", ++ * we free qskb and newm regardless of whether newm is different. ++ * Why newm would be different is puzzling. --rct ++ */ + retval = FW_SKIP; + } + else if (result > SKIP_PROCESSED) { +@@ -277,37 +275,40 @@ + + /* fix up the skb pointers */ + newm->data = BLKSTART(&newmb); +- newm->ip_hdr = (struct iphdr *) newm->data; +- newm->len = ntohs(newm->ip_hdr->tot_len); ++ newm->nh.iph = (struct iphdr *) newm->data; ++ newm->len = ntohs(newm->nh.iph->tot_len); + newm->tail = newm->data + newm->len; + newm->protocol = htons(ETH_P_IP); + newm->ip_summed = 0; +- newm->h.iph = newm->ip_hdr; ++ newm->h.ipiph = newm->nh.iph; + + /* and mark the skb as "authenticated"/"decrypted" */ +- newm->proto_priv[15] = ((result & SKIP_P_AUTH) ? RCV_AUTH : 0) +- | ((result & SKIP_P_DECRYPT) ? RCV_CRYPT : 0) +- | ((result & SKIP_P_TUNNEL) ? RCV_TUNNEL : 0) +- | RCV_SEC; ++ /* ++ * The original code statement below ended with "| RCV_SEC" which ++ * reduced the statement to "newm->security = RCV_SEC;". --rct ++ */ ++ newm->security = (((result & SKIP_P_AUTH) ? RCV_AUTH : 0) ++ | ((result & SKIP_P_DECRYPT) ? RCV_CRYPT : 0) ++ | ((result & SKIP_P_TUNNEL) ? RCV_TUNNEL : 0)) ++ & RCV_SEC; + + /* and feed the packet back into the input queue (must not switch + skbs here, because we need the defragmentor) */ + if (newm != qskb) +- kfree_skb(qskb, FREE_WRITE); +- ++ kfree_skb(qskb); + netif_rx(newm); /* frees skb for us */ + } + else if (result == SKIP_QUEUED) { + /* the skb was queued */ + + if (newm != qskb) +- kfree_skb(newm, FREE_WRITE); ++ kfree_skb(newm); + } else { + /* bad packet, policy violation, unsupported protocol, etc. */ + +- kfree_skb(newm, FREE_WRITE); + if (newm != qskb) +- kfree_skb(qskb, FREE_WRITE); ++ kfree_skb(qskb); ++ kfree_skb(newm); + } + + restore_flags(flags); +@@ -327,7 +328,7 @@ + int output_packet(struct firewall_ops *dummy1, int pf, struct device *dev, + void *dummy3, void *arg, struct sk_buff **pskb) + { +- struct iphdr *ipp = (*pskb)->ip_hdr; ++ struct iphdr *ipp = (*pskb)->nh.iph; + int tot_len = ntohs(ipp->tot_len); + struct sk_buff *newm, *qskb; + int result; +@@ -344,7 +345,7 @@ + /* Recursion happens if the datagram has been fragmented: + ip_queue_xmit -> skip -> ip_fragment -> ip_queue_xmit -> SKIP */ + +- if ((*pskb)->proto_priv[15] & SND_SEC) ++ if ((*pskb)->security & SND_SEC) + return FW_ACCEPT; + + /* this happens, too */ +@@ -388,15 +389,15 @@ + skb2memblk(newm, &oldmb, oldms); + + +- result = skip_process(SKIP_OUTPUT, NULL, NULL, (void *) &newm, &oldmb, &newmb); ++ result = skip_process(SKIP_OUTPUT, NULL, NULL, (void **) &newm, &oldmb, &newmb); + + + if (result == SKIP_PROCESSED) { + /* nothing happened - if not enskipped, we just say "OK" */ + +- kfree_skb(newm, FREE_WRITE); ++ kfree_skb(newm); + if (newm != qskb) +- kfree_skb(qskb, FREE_WRITE); ++ kfree_skb(qskb); + + /* check user level policy */ + if (!((*pskb)->sk && +@@ -404,7 +405,7 @@ + (*pskb)->sk->encryption >= IPSEC_LEVEL_USE))) { + + /* Set marker in skb + accept packet */ +- (*pskb)->proto_priv[15] |= SND_SEC; ++ (*pskb)->security |= SND_SEC; + retval = FW_SKIP; + } + } +@@ -418,27 +419,27 @@ + (!(result & SKIP_P_ENCRYPT) && + (*pskb)->sk->encryption >= IPSEC_LEVEL_USE))) { + +- kfree_skb(newm, FREE_WRITE); ++ kfree_skb(newm); + if (newm != qskb) +- kfree_skb(qskb, FREE_WRITE); ++ kfree_skb(qskb); + } + else { + /* fix up skb */ + newm->data = BLKSTART(&newmb); +- newm->ip_hdr = (struct iphdr *) newm->data; +- newm->len = ntohs(newm->ip_hdr->tot_len); ++ newm->nh.iph = (struct iphdr *) newm->data; ++ newm->len = ntohs(newm->nh.iph->tot_len); + newm->tail = newm->data + newm->len; + newm->protocol = htons(ETH_P_IP); + newm->ip_summed = 0; +- newm->h.iph = newm->ip_hdr; ++ newm->h.ipiph = newm->nh.iph; + + newm->dev = dev; + + if (newm != qskb) +- kfree_skb(qskb, FREE_WRITE); ++ kfree_skb(qskb); + + /* Set marker in skb */ +- newm->proto_priv[15] |= SND_SEC; ++ newm->security |= SND_SEC; + + interface_ship_out(newm); + +@@ -449,7 +450,7 @@ + /* queued, will be fed back to us */ + + if (newm != qskb) +- kfree_skb(newm, FREE_WRITE); ++ kfree_skb(newm); + + qskb->dev = dev; + +@@ -458,9 +459,9 @@ + else { + /* bad packet/policy/etc. */ + +- kfree_skb(newm, FREE_WRITE); ++ kfree_skb(newm); + if (newm != qskb) +- kfree_skb(qskb, FREE_WRITE); ++ kfree_skb(qskb); + } + + restore_flags(flags); +@@ -500,7 +501,7 @@ + int packet_accept(struct firewall_ops *this, int pf, struct device *dev, + void *phdr, void *arg, struct sk_buff **pskb) + { +- if ((*pskb)->proto_priv[15] & SND_SEC) ++ if ((*pskb)->security & SND_SEC) + return FW_ACCEPT; + else + return FW_SKIP; +@@ -514,10 +515,32 @@ + + static inline void interface_ship_out(struct sk_buff *skb) + { +- IS_SKB(skb); ++ /* ++ * Not sure how to do this for 2.1.X. ip_forward() will free skb ++ * before returning non-zero, so for the first attempt we'll simply ++ * call ip_forward() and be done with it. N.B.: for 2.0.X, nothing ++ * was done for the case where ip_forward() returned 0. ++ * ++ * New for 2.1.X: ip_forward() cannot be told to leave the TTL alone, ++ * so we'll increment it and recalculate the checksum before calling ++ * ip_forward(). Alan says I can pass stuff out through the routing ++ * code directly, but I'm not savvy enough to see how that might be ++ * done. --rct ++ */ ++ struct iphdr *iph; ++ unsigned short check; ++ ++ /* ++ * Hopefully, this is the inverse of ip_decrease_ttl(). ++ */ ++ iph = skb->nh.iph; ++ check = ntohs(iph->check) - 0x0100; ++ if ((check & 0xff00) == 0xff00) ++ check--; ++ iph->check = htons(check); ++ ++iph->ttl; + +- if (ip_forward(skb, skb->dev, IPFWD_NOTTLDEC, skb->h.iph->daddr)) +- kfree_skb(skb, FREE_WRITE); ++ (void)ip_forward(skb); + } + + +@@ -528,15 +551,12 @@ + unsigned long flags; + */ + +- IS_SKB(skb); +- +- + /* fix the packet for ip_forward (because ip_build_xmit might not have) */ +- skb->h.iph = skb->ip_hdr; ++ skb->h.ipiph = skb->nh.iph; + + /* check it */ +- if (output_packet(NULL, PF_IPSEC, skb->dev, NULL, NULL, &skb) < FW_ACCEPT) +- kfree_skb(skb, FREE_WRITE); ++ if (output_packet(NULL, PF_SECURITY, skb->dev, NULL, NULL, &skb) < FW_ACCEPT) ++ kfree_skb(skb); + else { + /* ...and ship it */ + /* +@@ -670,18 +690,26 @@ + int interface_attach(void *dummy, u_char *ipaddr) + { + struct device *dev; ++ struct in_device *in_dev; ++ struct in_ifaddr *ifa; + int result = -1; + +- for (dev = dev_base; dev != NULL; dev = dev->next) { +- if ((dev->family == AF_INET) && (dev->pa_addr == *((__u32 *) ipaddr)) +- && !dev_skip(dev, "attach")) { +- if (dev->mtu < 68 + maxheadergrowth) +- printk("enskip: %s: interface mtu of %d is too small\n", +- dev->name, dev->mtu); +- else { +- dev->mtu -= maxheadergrowth; +- dev_addlist(dev); +- result = 0; ++ for (dev = dev_base; dev; dev = dev->next) { ++ if ((in_dev = dev->ip_ptr) != NULL) { ++ for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { ++ if (ifa->ifa_local == *((__u32 *) ipaddr) && !dev_skip(dev, "attach")) { ++ if (dev->mtu < 68 + maxheadergrowth) ++ printk("enskip: %s: interface mtu of %d is too small\n", ++ dev->name, dev->mtu); ++ else { ++ if (dev->change_mtu) ++ (void)dev->change_mtu(dev, dev->mtu - maxheadergrowth); ++ else ++ dev->mtu -= maxheadergrowth; ++ dev_addlist(dev); ++ result = 0; ++ } ++ } + } + } + } +@@ -692,14 +720,22 @@ + int interface_detach(void *dummy, u_char *ipaddr) + { + struct device *dev; ++ struct in_device *in_dev; ++ struct in_ifaddr *ifa; + int result = -1; + +- for (dev = dev_base; dev != NULL; dev = dev->next) { +- if ((dev->family == AF_INET) && (dev->pa_addr == *((__u32 *) ipaddr)) +- && dev_skip(dev, "detach")) { +- dev_rmlist(dev); +- dev->mtu += maxheadergrowth; +- result = 0; ++ for (dev = dev_base; dev; dev = dev->next) { ++ if ((in_dev = dev->ip_ptr) != NULL) { ++ for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { ++ if (ifa->ifa_local == *((__u32 *) ipaddr) && dev_skip(dev, "detach")) { ++ dev_rmlist(dev); ++ if (dev->change_mtu) ++ (void)dev->change_mtu(dev, dev->mtu + maxheadergrowth); ++ else ++ dev->mtu += maxheadergrowth; ++ result = 0; ++ } ++ } + } + } + +@@ -715,14 +751,17 @@ + + maxheadergrowth = ipsp_maxheadergrowth(); + +- for (dev = dev_base; dev != NULL; dev = dev->next) { +- if (dev->family == AF_INET) { ++ for (dev = dev_base; dev; dev = dev->next) { ++ if (dev->ip_ptr) { + if (dev->mtu < 68 + maxheadergrowth) + printk("enskip: %s: interface mtu of %d is too small\n", + dev->name, dev->mtu); + else { + if ((dev->flags & IFF_LOOPBACK) == 0) { +- dev->mtu -= maxheadergrowth; ++ if (dev->change_mtu) ++ (void)dev->change_mtu(dev, dev->mtu - maxheadergrowth); ++ else ++ dev->mtu -= maxheadergrowth; + dev_addlist(dev); + } + } +@@ -739,10 +778,13 @@ + { + struct device *dev; + +- for (dev = dev_base; dev != NULL; dev = dev->next) { +- if ((dev->family == AF_INET) && dev_skip(dev, "exit")) { ++ for (dev = dev_base; dev; dev = dev->next) { ++ if (dev->ip_ptr && dev_skip(dev, "exit")) { + dev_rmlist(dev); +- dev->mtu += maxheadergrowth; ++ if (dev->change_mtu) ++ (void)dev->change_mtu(dev, dev->mtu + maxheadergrowth); ++ else ++ dev->mtu += maxheadergrowth; + } + } + +--- ENskip-0.67/linux/queue.c.orig Thu Feb 6 03:38:36 1997 ++++ ENskip-0.67/linux/queue.c Thu Apr 2 13:34:48 1998 +@@ -21,9 +21,18 @@ + + #include "config.h" + #include ++#ifdef KERNEL /* glibc */ ++#include ++#include ++#include ++#include ++#include "ip.h" /* __USE_BSD section only */ ++#define IP_CE IP_RF ++#else + #include + #include + #include ++#endif + #include + #include + #include +@@ -50,9 +59,9 @@ + int retval = 0; + + #ifdef DEBUG_LINUX_QUEUE +- struct iphdr *ip = ((struct sk_buff *) pkt)->ip_hdr; ++ struct iphdr *ip = ((struct sk_buff *) pkt)->nh.iph; + +- printf("queue %p: enqueue_in skb=%p ip_hdr=%p srcip=%08x dstip=%08x\n", ++ printf("queue %p: enqueue_in skb=%p nh.iph=%p srcip=%08x dstip=%08x\n", + q, pkt, ip, ip->saddr, ip->daddr); + #endif + tmp = kmalloc(sizeof (*tmp), GFP_ATOMIC); +@@ -78,7 +87,7 @@ + printf("queue overflow: free skb=%p queue=%p\n", pkt, tmp); + #endif + kfree(tmp); +- kfree_skb((struct sk_buff *) pkt, FREE_WRITE); ++ kfree_skb((struct sk_buff *) pkt); + + retval = -1; + } +@@ -98,9 +107,9 @@ + int retval = 0; + + #ifdef DEBUG_LINUX_QUEUE +- struct iphdr *ip = ((struct sk_buff *) pkt)->ip_hdr; ++ struct iphdr *ip = ((struct sk_buff *) pkt)->nh.iph; + +- printf("queue %p: enqueue_out skb=%p ip_hdr %p srcip=%08x dstip=%08x\n", ++ printf("queue %p: enqueue_out skb=%p nh.iph %p srcip=%08x dstip=%08x\n", + q, pkt, ip, ip->saddr, ip->daddr); + #endif + +@@ -127,7 +136,7 @@ + printf("queue overflow: free skb=%p queue=%p\n", pkt, tmp); + #endif + kfree(tmp); +- kfree_skb((struct sk_buff *) pkt, FREE_WRITE); ++ kfree_skb((struct sk_buff *) pkt); + + retval = -1; + } +@@ -157,7 +166,7 @@ + #ifdef DEBUG_LINUX_QUEUE + printf("queue_free: free skb=%p queue=%p\n", tmp->pskb, tmp); + #endif +- kfree_skb(tmp->pskb, FREE_WRITE); ++ kfree_skb(tmp->pskb); + kfree(tmp); + } + +@@ -171,7 +180,7 @@ + #ifdef DEBUG_LINUX_QUEUE + printf("queue_free: free skb=%p queue=%p\n", tmp->pskb, tmp); + #endif +- kfree_skb(tmp->pskb, FREE_WRITE); ++ kfree_skb(tmp->pskb); + kfree(tmp); + } + +@@ -250,9 +259,9 @@ + else + m = NULL; + +- if (m && m->ip_hdr) { +- *((__u32 *) srcip) = m->ip_hdr->saddr; +- *((__u32 *) dstip) = m->ip_hdr->daddr; ++ if (m && m->nh.iph) { ++ *((__u32 *) srcip) = m->nh.iph->saddr; ++ *((__u32 *) dstip) = m->nh.iph->daddr; + result = 0; + } + else { +--- ENskip-0.67/linux/device.c.orig Wed Jan 29 03:20:23 1997 ++++ ENskip-0.67/linux/device.c Sat Feb 14 22:41:10 1998 +@@ -38,6 +38,7 @@ + #include + #include + #include ++#include + #include "skip_defs.h" + #include "dynamic.h" + #include "memblk.h" +@@ -82,21 +83,21 @@ + if (io == NULL) + return -ENOMEM; + +- memcpy_fromfs(io, (void *) arg, sizeof(struct devioctl)); +- ++ copy_from_user(io, (void *)arg, sizeof(struct devioctl)); ++ + retval = verify_area(VERIFY_WRITE, (void *) io->ic_dp, io->ic_len); + if (retval) { + kfree(io); + return retval; + } +- ++ + req = (u_char *) kmalloc(io->ic_len, GFP_ATOMIC); + if (req == NULL) { + kfree(io); + return -ENOMEM; + } + +- memcpy_fromfs(req, io->ic_dp, io->ic_len); ++ copy_from_user(req, io->ic_dp, io->ic_len); + + #ifdef DEBUG_LINUX_IOCTL + printk("Calling ioctl request handler, request len=%i\n", io->ic_len); +@@ -111,10 +112,10 @@ + kfree(io); + return retval; + } +- memcpy_tofs((void *) io->ic_dp, req, newlen); ++ copy_to_user((void *)io->ic_dp, req, newlen); + } + io->ic_len = newlen; +- memcpy_tofs((void *) arg, io, sizeof(struct devioctl)); ++ copy_to_user((void *)arg, io, sizeof(struct devioctl)); + + kfree(req); + kfree(io); +@@ -133,8 +134,9 @@ + } + + /* close function -- called from device switching table */ +-void close_skip(struct inode *inode, struct file *file) ++int close_skip(struct inode *inode, struct file *file) + { + MOD_DEC_USE_COUNT; ++ return 0; + } + +--- ENskip-0.67/linux/device.h.orig Sun Dec 1 18:56:43 1996 ++++ ENskip-0.67/linux/device.h Wed Jan 28 11:21:10 1998 +@@ -24,7 +24,7 @@ + + extern int ioctl_skip(struct inode *, struct file *, unsigned int, unsigned long); + extern int open_skip(struct inode *, struct file *); +-extern void close_skip(struct inode *, struct file *); ++extern int close_skip(struct inode *, struct file *); + + #endif /* _ENSKIP_LINUX_DEVICE_H */ + +--- ENskip-0.67/linux/skipmod.c.orig Sun Jan 26 08:40:32 1997 ++++ ENskip-0.67/linux/skipmod.c Wed Sep 9 21:44:38 1998 +@@ -103,7 +103,7 @@ + forward_packet, + packet_nop, + output_packet, +- PF_IPSEC, ++ PF_SECURITY, + 2 /* allow other filters to hook before us */ + }; + +@@ -114,10 +114,13 @@ + NULL, /* read */ + NULL, /* write */ + NULL, /* readdir */ +- NULL, /* select */ ++ NULL, /* poll */ + ioctl_skip, /* ioctl */ + NULL, /* mmap */ + open_skip, /* open code */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,118) ++ NULL, /* flush */ ++#endif + close_skip, /* release code */ + NULL /* fsync */ + }; +@@ -132,7 +135,7 @@ + } + + if (register_firewall(PF_INET, &skip_in) || +- register_firewall(PF_IPSEC, &skip_out)) { ++ register_firewall(PF_SECURITY, &skip_out)) { + printk("Unable to register ENskip as packet filter!\n"); + + unregister_chrdev(SKIP_DEV_MAJOR, SKIP_DEV_NAME); +@@ -156,7 +159,7 @@ + + unregister_chrdev(SKIP_DEV_MAJOR, SKIP_DEV_NAME); + +- unregister_firewall(PF_IPSEC, &skip_out); ++ unregister_firewall(PF_SECURITY, &skip_out); + unregister_firewall(PF_INET, &skip_in); + + printk(KERN_INFO "enskip: module unloaded.\n"); +--- ENskip-0.67/linux/ip.h.orig Wed Mar 11 10:21:33 1998 ++++ ENskip-0.67/linux/ip.h Mon Mar 9 13:59:35 1998 +@@ -0,0 +1,87 @@ ++#ifdef __USE_BSD ++/* ++ * Copyright (c) 1982, 1986, 1993 ++ * The Regents of the University of California. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. All advertising materials mentioning features or use of this software ++ * must display the following acknowledgement: ++ * This product includes software developed by the University of ++ * California, Berkeley and its contributors. ++ * 4. Neither the name of the University nor the names of its contributors ++ * may be used to endorse or promote products derived from this software ++ * without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ * ++ * @(#)ip.h 8.1 (Berkeley) 6/10/93 ++ */ ++ ++/* ++ * Definitions for internet protocol version 4. ++ * Per RFC 791, September 1981. ++ */ ++ ++/* ++ * Structure of an internet header, naked of options. ++ */ ++struct ip ++ { ++#if __BYTE_ORDER == __LITTLE_ENDIAN ++ u_int8_t ip_hl:4; /* header length */ ++ u_int8_t ip_v:4; /* version */ ++#endif ++#if __BYTE_ORDER == __BIG_ENDIAN ++ u_int8_t ip_v:4; /* version */ ++ u_int8_t ip_hl:4; /* header length */ ++#endif ++ u_int8_t ip_tos; /* type of service */ ++ u_short ip_len; /* total length */ ++ u_short ip_id; /* identification */ ++ u_short ip_off; /* fragment offset field */ ++#define IP_RF 0x8000 /* reserved fragment flag */ ++#define IP_DF 0x4000 /* dont fragment flag */ ++#define IP_MF 0x2000 /* more fragments flag */ ++#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ ++ u_int8_t ip_ttl; /* time to live */ ++ u_int8_t ip_p; /* protocol */ ++ u_short ip_sum; /* checksum */ ++ struct in_addr ip_src, ip_dst; /* source and dest address */ ++ }; ++ ++/* ++ * Time stamp option structure. ++ */ ++struct ip_timestamp ++ { ++ u_int8_t ipt_code; /* IPOPT_TS */ ++ u_int8_t ipt_len; /* size of structure (variable) */ ++ u_int8_t ipt_ptr; /* index of current entry */ ++#if __BYTE_ORDER == __LITTLE_ENDIAN ++ u_int8_t ipt_flg:4; /* flags, see below */ ++ u_int8_t ipt_oflw:4; /* overflow counter */ ++#endif ++#if __BYTE_ORDER == __BIG_ENDIAN ++ u_int8_t ipt_oflw:4; /* overflow counter */ ++ u_int8_t ipt_flg:4; /* flags, see below */ ++#endif ++ u_int32_t data[9]; ++ }; ++#endif /* __USE_BSD */ +--- ENskip-0.67/linux/config.h.orig Thu Mar 13 09:35:54 1997 ++++ ENskip-0.67/linux/config.h Mon Mar 9 14:53:03 1998 +@@ -33,9 +33,11 @@ + #define __BSD_SOURCE + + #include ++#ifndef KERNEL /* glibc */ + #include + #include + #include ++#endif + + typedef __s32 int32; + typedef __u32 u_int32; +@@ -65,9 +67,11 @@ + #include + #include + #include ++#ifndef KERNEL /* glibc */ + #include + #include + #include ++#endif + #include + + #define SMALL_KERNEL_STACK +@@ -121,7 +125,7 @@ + #include + #include + #include +-#include ++#include /* glibc */ + #include + + #define KALLOC(size) malloc((size)) +--- ENskip-0.67/lib/ah.c.orig Wed Feb 5 16:37:59 1997 ++++ ENskip-0.67/lib/ah.c Thu Apr 2 13:31:19 1998 +@@ -4,9 +4,18 @@ + */ + #include "config.h" + ++#if defined(KERNEL) && defined(linux) ++#include ++#include ++#include ++#include ++#include "ip.h" /* __USE_BSD section only */ ++#define IP_CE IP_RF ++#else + #include + #include + #include ++#endif + + #include "skip_defs.h" + #include "memblk.h" +--- ENskip-0.67/lib/ipsp.c.orig Wed Feb 5 16:45:52 1997 ++++ ENskip-0.67/lib/ipsp.c Thu Apr 2 13:28:41 1998 +@@ -11,9 +11,18 @@ + #include "config.h" + + #include ++#if defined(KERNEL) && defined(linux) /* glibc */ ++#include ++#include ++#include ++#include ++#include "ip.h" /* __USE_BSD section only */ ++#define IP_CE IP_RF ++#else + #include + #include + #include ++#endif + + #include "skip_defs.h" + #include "id.h" +--- ENskip-0.67/lib/ipsum.c.orig Thu Nov 14 15:46:44 1996 ++++ ENskip-0.67/lib/ipsum.c Thu Apr 2 13:29:43 1998 +@@ -4,10 +4,20 @@ + */ + #include "config.h" + ++#if defined(KERNEL) && defined(linux) /* glibc */ ++#include ++#include ++#include ++#include ++#include ++#include "ip.h" /* __USE_BSD section only */ ++#define IP_CE IP_RF ++#else + #include + #include + #include + #include ++#endif + #include "ipsum.h" + + #ifdef __GNUC__ +--- ENskip-0.67/lib/skip.c.orig Wed Feb 19 02:46:33 1997 ++++ ENskip-0.67/lib/skip.c Thu Apr 2 13:30:45 1998 +@@ -7,10 +7,20 @@ + + #include "config.h" + #include ++#if defined(KERNEL) && defined(linux) /* glibc */ ++#include ++#include ++#include ++#include ++#include "ip.h" /* __USE_BSD section only */ ++#define IP_CE IP_RF ++#include ++#else + #include + #include + #include + #include ++#endif + + #include "skip_defs.h" + #include "memblk.h" +--- ENskip-0.67/lib/id.c.orig Fri May 9 06:20:05 1997 ++++ ENskip-0.67/lib/id.c Mon Mar 9 14:50:25 1998 +@@ -5,7 +5,9 @@ + + #include "config.h" + ++#ifndef KERNEL + #include ++#endif + #include "skip_defs.h" + + #ifndef KERNEL +--- ENskip-0.67/cert/suncert/lib/Bigint.C.orig Thu Mar 13 08:13:23 1997 ++++ ENskip-0.67/cert/suncert/lib/Bigint.C Fri Jun 5 12:31:04 1998 +@@ -46,7 +46,7 @@ + #include "Time.h" + #include "asn1_der.h" + +-#ifndef SOLARIS2 ++#if !defined(SOLARIS2) && !defined(linux) /* glibc */ + extern "C" { + void bzero(void *, int); + }; + diff -ruN linux-2.2.5,pristine/Documentation/crypto/crypt-mount.patch linux-2.2.5/Documentation/crypto/crypt-mount.patch --- linux-2.2.5,pristine/Documentation/crypto/crypt-mount.patch Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/Documentation/crypto/crypt-mount.patch Thu Apr 1 23:05:44 1999 @@ -0,0 +1,559 @@ +diff -urN mount-2.7l/Makefile mount-crypt/Makefile +--- mount-2.7l/Makefile Tue Jan 27 23:04:17 1998 ++++ mount-crypt/Makefile Sun Oct 4 23:40:31 1998 +@@ -5,7 +5,7 @@ + # For now: a standalone version + + CC = gcc +-CFLAGS = -O2 ++CFLAGS = -O2 -fno-strength-reduce + + #WARNFLAGS = -Wall -Wstrict-prototypes + # We really want +@@ -52,7 +52,7 @@ + GEN_FILES = nfsmount.x nfsmount.h nfsmount_xdr.c nfsmount_clnt.c + + # comment these out if you are not compiling in loop support +-LO_OBJS=lomount.o ++LO_OBJS=lomount.o rmd160.o + + all: $(PROGS) + +@@ -77,7 +77,7 @@ + swapon: swapon.o version.o + $(LINK) $^ -o $@ + +-losetup: losetup.o ++losetup: losetup.o rmd160.o + $(LINK) $^ -o $@ + + mount.o umount.o nfsmount.o losetup.o fstab.o sundries.o: sundries.h +diff -urN mount-2.7l/lomount.c mount-crypt/lomount.c +--- mount-2.7l/lomount.c Fri Nov 21 16:59:50 1997 ++++ mount-crypt/lomount.c Sun Oct 4 23:31:53 1998 +@@ -20,6 +20,7 @@ + + #include "loop.h" + #include "lomount.h" ++#include "rmd160.h" + + char *xstrdup (const char *s); /* not: #include "sundries.h" */ + void error (const char *fmt, ...); /* idem */ +@@ -33,6 +34,8 @@ + { LO_CRYPT_NONE, "none" }, + { LO_CRYPT_XOR, "xor" }, + { LO_CRYPT_DES, "DES" }, ++ { LO_CRYPT_FISH2, "twofish" }, ++ { LO_CRYPT_BLOW, "blowfish"}, + { -1, NULL } + }; + +@@ -209,6 +212,13 @@ + return 1; + } + break; ++ case LO_CRYPT_FISH2: ++ case LO_CRYPT_BLOW: ++ pass = getpass("Password :"); ++ MDcalc((byte *)loopinfo.lo_encrypt_key,pass,strlen(pass)); ++ loopinfo.lo_encrypt_key_size=20; /* 160 Bit key */ ++ break; ++ + default: + fprintf (stderr, + "Don't know how to get key for encryption system %d\n", +diff -urN mount-2.7l/losetup.c mount-crypt/losetup.c +--- mount-2.7l/losetup.c Mon Jan 26 22:59:58 1998 ++++ mount-crypt/losetup.c Sun Oct 4 23:31:14 1998 +@@ -13,6 +13,7 @@ + + #include "loop.h" + #include "lomount.h" ++#include "rmd160.h" + + #ifdef LOOP_SET_FD + +@@ -26,6 +27,8 @@ + { LO_CRYPT_NONE,"none" }, + { LO_CRYPT_XOR, "xor" }, + { LO_CRYPT_DES, "DES" }, ++ { LO_CRYPT_FISH2, "twofish" }, ++ { LO_CRYPT_BLOW, "blowfish" }, + { -1, NULL } + }; + +@@ -80,7 +83,7 @@ + struct loop_info loopinfo; + int fd, ffd, mode, i; + char *pass; +- ++ + mode = *loopro ? O_RDONLY : O_RDWR; + if ((ffd = open (file, mode)) < 0 && !*loopro + && (errno != EROFS || (ffd = open (file, mode = O_RDONLY)) < 0)) { +@@ -128,6 +131,12 @@ + exit(1); + } + break; ++ case LO_CRYPT_FISH2: ++ case LO_CRYPT_BLOW: ++ pass = getpass("Password :"); ++ MDcalc((byte *)loopinfo.lo_encrypt_key,pass,strlen(pass)); ++ loopinfo.lo_encrypt_key_size=20; /* 160 Bit key */ ++ break; + default: + fprintf(stderr, + "Don't know how to get key for encryption system %d\n", +diff -urN mount-2.7l/nfs_mountversion.h mount-crypt/nfs_mountversion.h +--- mount-2.7l/nfs_mountversion.h Thu Jan 1 00:00:00 1970 ++++ mount-crypt/nfs_mountversion.h Sun Oct 4 21:18:41 1998 +@@ -0,0 +1 @@ ++#define KERNEL_NFS_MOUNT_VERSION 3 +diff -urN mount-2.7l/rmd160.c mount-crypt/rmd160.c +--- mount-2.7l/rmd160.c Thu Jan 1 00:00:00 1970 ++++ mount-crypt/rmd160.c Sun Oct 4 23:21:32 1998 +@@ -0,0 +1,371 @@ ++/********************************************************************\ ++ * ++ * FILE: rmd160.c ++ * ++ * CONTENTS: A sample C-implementation of the RIPEMD-160 ++ * hash-function. ++ * TARGET: any computer with an ANSI C compiler ++ * ++ * AUTHOR: Antoon Bosselaers, ESAT-COSIC ++ * DATE: 1 March 1996 ++ * VERSION: 1.0 ++ * ++ * Copyright (c) Katholieke Universiteit Leuven ++ * 1996, All Rights Reserved ++ * ++\********************************************************************/ ++ ++/* header files */ ++#include ++#include ++#include ++#include "rmd160.h" ++ ++/********************************************************************/ ++ ++/* macro definitions */ ++ ++/* collect four bytes into one word: */ ++#define BYTES_TO_DWORD(strptr) \ ++ (((dword) *((strptr)+3) << 24) | \ ++ ((dword) *((strptr)+2) << 16) | \ ++ ((dword) *((strptr)+1) << 8) | \ ++ ((dword) *(strptr))) ++ ++/* ROL(x, n) cyclically rotates x over n bits to the left */ ++/* x must be of an unsigned 32 bits type and 0 <= n < 32. */ ++#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n)))) ++ ++/* the five basic functions F(), G() and H() */ ++#define F(x, y, z) ((x) ^ (y) ^ (z)) ++#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) ++#define H(x, y, z) (((x) | ~(y)) ^ (z)) ++#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) ++#define J(x, y, z) ((x) ^ ((y) | ~(z))) ++ ++/* the ten basic operations FF() through III() */ ++#define FF(a, b, c, d, e, x, s) {\ ++ (a) += F((b), (c), (d)) + (x);\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define GG(a, b, c, d, e, x, s) {\ ++ (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define HH(a, b, c, d, e, x, s) {\ ++ (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define II(a, b, c, d, e, x, s) {\ ++ (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define JJ(a, b, c, d, e, x, s) {\ ++ (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define FFF(a, b, c, d, e, x, s) {\ ++ (a) += F((b), (c), (d)) + (x);\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define GGG(a, b, c, d, e, x, s) {\ ++ (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define HHH(a, b, c, d, e, x, s) {\ ++ (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define III(a, b, c, d, e, x, s) {\ ++ (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define JJJ(a, b, c, d, e, x, s) {\ ++ (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++ ++ ++/********************************************************************/ ++ ++void MDinit(dword *MDbuf) ++{ ++ MDbuf[0] = 0x67452301UL; ++ MDbuf[1] = 0xefcdab89UL; ++ MDbuf[2] = 0x98badcfeUL; ++ MDbuf[3] = 0x10325476UL; ++ MDbuf[4] = 0xc3d2e1f0UL; ++ ++ return; ++} ++ ++/********************************************************************/ ++ ++void compress(dword *MDbuf, dword *X) ++{ ++ dword aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2], ++ dd = MDbuf[3], ee = MDbuf[4]; ++ dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2], ++ ddd = MDbuf[3], eee = MDbuf[4]; ++ ++ /* round 1 */ ++ FF(aa, bb, cc, dd, ee, X[ 0], 11); ++ FF(ee, aa, bb, cc, dd, X[ 1], 14); ++ FF(dd, ee, aa, bb, cc, X[ 2], 15); ++ FF(cc, dd, ee, aa, bb, X[ 3], 12); ++ FF(bb, cc, dd, ee, aa, X[ 4], 5); ++ FF(aa, bb, cc, dd, ee, X[ 5], 8); ++ FF(ee, aa, bb, cc, dd, X[ 6], 7); ++ FF(dd, ee, aa, bb, cc, X[ 7], 9); ++ FF(cc, dd, ee, aa, bb, X[ 8], 11); ++ FF(bb, cc, dd, ee, aa, X[ 9], 13); ++ FF(aa, bb, cc, dd, ee, X[10], 14); ++ FF(ee, aa, bb, cc, dd, X[11], 15); ++ FF(dd, ee, aa, bb, cc, X[12], 6); ++ FF(cc, dd, ee, aa, bb, X[13], 7); ++ FF(bb, cc, dd, ee, aa, X[14], 9); ++ FF(aa, bb, cc, dd, ee, X[15], 8); ++ ++ /* round 2 */ ++ GG(ee, aa, bb, cc, dd, X[ 7], 7); ++ GG(dd, ee, aa, bb, cc, X[ 4], 6); ++ GG(cc, dd, ee, aa, bb, X[13], 8); ++ GG(bb, cc, dd, ee, aa, X[ 1], 13); ++ GG(aa, bb, cc, dd, ee, X[10], 11); ++ GG(ee, aa, bb, cc, dd, X[ 6], 9); ++ GG(dd, ee, aa, bb, cc, X[15], 7); ++ GG(cc, dd, ee, aa, bb, X[ 3], 15); ++ GG(bb, cc, dd, ee, aa, X[12], 7); ++ GG(aa, bb, cc, dd, ee, X[ 0], 12); ++ GG(ee, aa, bb, cc, dd, X[ 9], 15); ++ GG(dd, ee, aa, bb, cc, X[ 5], 9); ++ GG(cc, dd, ee, aa, bb, X[ 2], 11); ++ GG(bb, cc, dd, ee, aa, X[14], 7); ++ GG(aa, bb, cc, dd, ee, X[11], 13); ++ GG(ee, aa, bb, cc, dd, X[ 8], 12); ++ ++ /* round 3 */ ++ HH(dd, ee, aa, bb, cc, X[ 3], 11); ++ HH(cc, dd, ee, aa, bb, X[10], 13); ++ HH(bb, cc, dd, ee, aa, X[14], 6); ++ HH(aa, bb, cc, dd, ee, X[ 4], 7); ++ HH(ee, aa, bb, cc, dd, X[ 9], 14); ++ HH(dd, ee, aa, bb, cc, X[15], 9); ++ HH(cc, dd, ee, aa, bb, X[ 8], 13); ++ HH(bb, cc, dd, ee, aa, X[ 1], 15); ++ HH(aa, bb, cc, dd, ee, X[ 2], 14); ++ HH(ee, aa, bb, cc, dd, X[ 7], 8); ++ HH(dd, ee, aa, bb, cc, X[ 0], 13); ++ HH(cc, dd, ee, aa, bb, X[ 6], 6); ++ HH(bb, cc, dd, ee, aa, X[13], 5); ++ HH(aa, bb, cc, dd, ee, X[11], 12); ++ HH(ee, aa, bb, cc, dd, X[ 5], 7); ++ HH(dd, ee, aa, bb, cc, X[12], 5); ++ ++ /* round 4 */ ++ II(cc, dd, ee, aa, bb, X[ 1], 11); ++ II(bb, cc, dd, ee, aa, X[ 9], 12); ++ II(aa, bb, cc, dd, ee, X[11], 14); ++ II(ee, aa, bb, cc, dd, X[10], 15); ++ II(dd, ee, aa, bb, cc, X[ 0], 14); ++ II(cc, dd, ee, aa, bb, X[ 8], 15); ++ II(bb, cc, dd, ee, aa, X[12], 9); ++ II(aa, bb, cc, dd, ee, X[ 4], 8); ++ II(ee, aa, bb, cc, dd, X[13], 9); ++ II(dd, ee, aa, bb, cc, X[ 3], 14); ++ II(cc, dd, ee, aa, bb, X[ 7], 5); ++ II(bb, cc, dd, ee, aa, X[15], 6); ++ II(aa, bb, cc, dd, ee, X[14], 8); ++ II(ee, aa, bb, cc, dd, X[ 5], 6); ++ II(dd, ee, aa, bb, cc, X[ 6], 5); ++ II(cc, dd, ee, aa, bb, X[ 2], 12); ++ ++ /* round 5 */ ++ JJ(bb, cc, dd, ee, aa, X[ 4], 9); ++ JJ(aa, bb, cc, dd, ee, X[ 0], 15); ++ JJ(ee, aa, bb, cc, dd, X[ 5], 5); ++ JJ(dd, ee, aa, bb, cc, X[ 9], 11); ++ JJ(cc, dd, ee, aa, bb, X[ 7], 6); ++ JJ(bb, cc, dd, ee, aa, X[12], 8); ++ JJ(aa, bb, cc, dd, ee, X[ 2], 13); ++ JJ(ee, aa, bb, cc, dd, X[10], 12); ++ JJ(dd, ee, aa, bb, cc, X[14], 5); ++ JJ(cc, dd, ee, aa, bb, X[ 1], 12); ++ JJ(bb, cc, dd, ee, aa, X[ 3], 13); ++ JJ(aa, bb, cc, dd, ee, X[ 8], 14); ++ JJ(ee, aa, bb, cc, dd, X[11], 11); ++ JJ(dd, ee, aa, bb, cc, X[ 6], 8); ++ JJ(cc, dd, ee, aa, bb, X[15], 5); ++ JJ(bb, cc, dd, ee, aa, X[13], 6); ++ ++ /* parallel round 1 */ ++ JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); ++ JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); ++ JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); ++ JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); ++ JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); ++ JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); ++ JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); ++ JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); ++ JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); ++ JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); ++ JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); ++ JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); ++ JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); ++ JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); ++ JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); ++ JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); ++ ++ /* parallel round 2 */ ++ III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); ++ III(ddd, eee, aaa, bbb, ccc, X[11], 13); ++ III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); ++ III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); ++ III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); ++ III(eee, aaa, bbb, ccc, ddd, X[13], 8); ++ III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); ++ III(ccc, ddd, eee, aaa, bbb, X[10], 11); ++ III(bbb, ccc, ddd, eee, aaa, X[14], 7); ++ III(aaa, bbb, ccc, ddd, eee, X[15], 7); ++ III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); ++ III(ddd, eee, aaa, bbb, ccc, X[12], 7); ++ III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); ++ III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); ++ III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); ++ III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); ++ ++ /* parallel round 3 */ ++ HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); ++ HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); ++ HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); ++ HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); ++ HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); ++ HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); ++ HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); ++ HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); ++ HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); ++ HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); ++ HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); ++ HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); ++ HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); ++ HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); ++ HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); ++ HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); ++ ++ /* parallel round 4 */ ++ GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); ++ GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); ++ GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); ++ GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); ++ GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); ++ GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); ++ GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); ++ GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); ++ GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); ++ GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); ++ GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); ++ GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); ++ GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); ++ GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); ++ GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); ++ GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); ++ ++ /* parallel round 5 */ ++ FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); ++ FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); ++ FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); ++ FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); ++ FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); ++ FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); ++ FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); ++ FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); ++ FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); ++ FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); ++ FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); ++ FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); ++ FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); ++ FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); ++ FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); ++ FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); ++ ++ /* combine results */ ++ ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */ ++ MDbuf[1] = MDbuf[2] + dd + eee; ++ MDbuf[2] = MDbuf[3] + ee + aaa; ++ MDbuf[3] = MDbuf[4] + aa + bbb; ++ MDbuf[4] = MDbuf[0] + bb + ccc; ++ MDbuf[0] = ddd; ++ ++ return; ++} ++ ++/********************************************************************/ ++ ++void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen) ++{ ++ unsigned int i; /* counter */ ++ dword X[16]; /* message words */ ++ ++ memset(X, 0, 16*sizeof(dword)); ++ ++ /* put bytes from strptr into X */ ++ for (i=0; i<(lswlen&63); i++) { ++ /* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */ ++ X[i>>2] ^= (dword) *strptr++ << (8 * (i&3)); ++ } ++ ++ /* append "1" bit to the message. Be careful : ++ message = "" -> "10000000" = 128 */ ++ X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3)+7); ++ ++ if ((lswlen & 63) > 55) { ++ /* length goes to next block */ ++ compress(MDbuf, X); ++ memset(X, 0, 16*sizeof(dword)); ++ } ++ ++ /* append length in bits*/ ++ X[14] = lswlen << 3; ++ X[15] = (lswlen >> 29) | (mswlen << 3); ++ compress(MDbuf, X); ++ ++ return; ++} ++ ++void MDcalc(byte *MD,byte *sp,dword sl) ++{ dword X[16]; ++ dword MDbuf[5]; ++ int i,j; ++ ++ MDinit(MDbuf); ++ ++ while (sl >= 64) ++ { ++ memset(X,0,16*sizeof(dword)); ++ ++ for (i=0; i<64; i++) ++ X[i>>2] |= ((dword)(*sp++)) << (8 * (i&3)); ++ ++ sl-=64; ++ compress(MDbuf,X); ++ ++ }; ++ MDfinish(MDbuf,sp,sl,0); ++ ++ for (i=0;i<5;i++) ++ for (j=0;j<4;j++) ++ *MD++=(byte)((MDbuf[i]>>(j*8))&0xFF); ++} ++ ++/************************ end of file rmd160.c **********************/ ++ +diff -urN mount-2.7l/rmd160.h mount-crypt/rmd160.h +--- mount-2.7l/rmd160.h Thu Jan 1 00:00:00 1970 ++++ mount-crypt/rmd160.h Sun Oct 4 23:21:32 1998 +@@ -0,0 +1,58 @@ ++/********************************************************************\ ++ * ++ * FILE: rmd160.h ++ * ++ * CONTENTS: Header file for a sample C-implementation of the ++ * RIPEMD-160 hash-function. ++ * TARGET: any computer with an ANSI C compiler ++ * ++ * AUTHOR: Antoon Bosselaers, ESAT-COSIC ++ * DATE: 1 March 1996 ++ * VERSION: 1.0 ++ * ++ * Copyright (c) Katholieke Universiteit Leuven ++ * 1996, All Rights Reserved ++ * ++\********************************************************************/ ++ ++#ifndef RMD160H /* make sure this file is read only once */ ++#define RMD160H ++ ++/********************************************************************/ ++ ++/* typedef 8 and 32 bit types, resp. */ ++/* adapt these, if necessary, ++ for your operating system and compiler */ ++ ++typedef unsigned char byte; ++typedef unsigned long dword; ++ ++/********************************************************************/ ++ ++/* function prototypes */ ++ ++void MDinit(dword *MDbuf); ++/* ++ * initializes MDbuffer to "magic constants" ++ */ ++ ++void compress(dword *MDbuf, dword *X); ++/* ++ * the compression function. ++ * transforms MDbuf using message bytes X[0] through X[15] ++ */ ++ ++void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen); ++/* ++ * puts bytes from strptr into X and pad out; appends length ++ * and finally, compresses the last block(s) ++ * note: length in bits == 8 * (lswlen + 2^32 mswlen). ++ * note: there are (lswlen mod 64) bytes left in strptr. ++ */ ++ ++void MDcalc(byte *MDbuf,byte *sp,dword sl); ++ ++#endif /* RMD160H */ ++ ++/*********************** end of file rmd160.h ***********************/ ++ +diff -urN mount-2.7l/swapon.c mount-crypt/swapon.c +--- mount-2.7l/swapon.c Fri Nov 21 16:17:11 1997 ++++ mount-crypt/swapon.c Sun Oct 4 21:18:33 1998 +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include "swap.h" + #include "swapargs.h" + diff -ruN linux-2.2.5,pristine/Documentation/crypto/loop-mount-13.patch linux-2.2.5/Documentation/crypto/loop-mount-13.patch --- linux-2.2.5,pristine/Documentation/crypto/loop-mount-13.patch Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/Documentation/crypto/loop-mount-13.patch Thu Apr 1 23:05:44 1999 @@ -0,0 +1,2398 @@ +diff --unified --recursive --new-file mount-2.7l.orig/Makefile mount-2.7l/Makefile +--- mount-2.7l.orig/Makefile Tue Jan 27 18:04:17 1998 ++++ mount-2.7l/Makefile Sat Apr 11 16:07:44 1998 +@@ -52,7 +52,7 @@ + GEN_FILES = nfsmount.x nfsmount.h nfsmount_xdr.c nfsmount_clnt.c + + # comment these out if you are not compiling in loop support +-LO_OBJS=lomount.o ++LOOP_OBJS=lomount.o rmd160.o + + all: $(PROGS) + +@@ -68,23 +68,30 @@ + %.o: %.c + $(COMPILE) $< + +-mount: mount.o fstab.o sundries.o realpath.o version.o $(NFS_OBJS) $(LO_OBJS) ++mount: mount.o fstab.o sundries.o realpath.o version.o $(NFS_OBJS) $(LOOP_OBJS) + $(LINK) $^ -o $@ + +-umount: umount.o fstab.o sundries.o realpath.o version.o $(LO_OBJS) ++umount: umount.o fstab.o sundries.o realpath.o version.o $(LOOP_OBJS) + $(LINK) $^ -o $@ + + swapon: swapon.o version.o + $(LINK) $^ -o $@ + +-losetup: losetup.o ++losetup: losetup.o rmd160.o + $(LINK) $^ -o $@ + +-mount.o umount.o nfsmount.o losetup.o fstab.o sundries.o: sundries.h ++losetup.o: losetup.c losetup.h ++ ++lomount.o: losetup.c losetup.h ++ $(COMPILE) -DLOMOUNT $< -o $@ ++ ++rmd160.o: rmd160.c rmd160.h ++ ++mount.o umount.o nfsmount.o fstab.o sundries.o: sundries.h + + mount.o umount.o fstab.o sundries.o: fstab.h + +-mount.o umount.o losetup.o lomount.o: lomount.h loop.h ++mount.o umount.o: $(LOOP_OBJS) + + swapon.o: swap.h swapargs.h + +diff --unified --recursive --new-file mount-2.7l.orig/h/loop.h mount-2.7l/h/loop.h +--- mount-2.7l.orig/h/loop.h Tue Jan 27 14:43:07 1998 ++++ mount-2.7l/h/loop.h Sun Apr 19 16:36:38 1998 +@@ -1,3 +1,6 @@ ++#if !defined(_LINUX_LOOP_H) ++#define _LINUX_LOOP_H ++ + /* + * include/linux/loop.h + * +@@ -5,33 +8,109 @@ + * + * Copyright 1993 by Theodore Ts'o. Redistribution of this file is + * permitted under the GNU Public License. ++ * ++ * HISTORY ++ * May 3, 1997 - Andrew E. Mileski ++ * See loop.c for details and full list of credits. + */ + +-#define LO_NAME_SIZE 64 +-#define LO_KEY_SIZE 32 +- +-struct loop_info { +- int lo_number; /* ioctl r/o */ +- dev_t lo_device; /* ioctl r/o */ +- unsigned long lo_inode; /* ioctl r/o */ +- dev_t lo_rdevice; /* ioctl r/o */ +- int lo_offset; +- int lo_encrypt_type; +- int lo_encrypt_key_size; /* ioctl w/o */ +- int lo_flags; /* ioctl r/o */ +- char lo_name[LO_NAME_SIZE]; +- unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ +- unsigned long lo_init[2]; +- char reserved[4]; +-}; +- +-#define LO_CRYPT_NONE 0 +-#define LO_CRYPT_XOR 1 +-#define LO_CRYPT_DES 2 +-#define LO_CRYPT_IDEA 3 +-#define MAX_LO_CRYPT 4 +- ++/* IOCTL commands --- we will commandeer 0x4C ('L') */ + #define LOOP_SET_FD 0x4C00 + #define LOOP_CLR_FD 0x4C01 + #define LOOP_SET_STATUS 0x4C02 + #define LOOP_GET_STATUS 0x4C03 ++ ++/* Array sizes */ ++#define LOOP_TRANSFORM_NAME 16 ++#define LOOP_MODULE_NAME (LOOP_TRANSFORM_NAME + 5) ++#define LOOP_PATH 255 ++#define LOOP_KEYSIZE 20 ++ ++/* ioctl LOOP_GET_STATUS/LOOP_SET_STATUS info struct */ ++struct loop_status { ++ int minor; /* ro */ ++ kdev_t device; /* ro */ ++ kdev_t rdevice; /* ro */ ++ unsigned long inode; /* ro */ ++ char path[LOOP_PATH]; /* rw */ ++ unsigned offset; /* rw */ ++ unsigned blks; /* rw */ ++ unsigned blksize; /* rw */ ++ int flags; /* ro */ ++ char transform[LOOP_TRANSFORM_NAME]; /* rw */ ++ int xfermode; /* rw */ ++ int datasize; /* rw */ ++}; ++ ++#define XFERMODE_DEFAULT 0 ++ ++/* Steganography transfer modes */ ++#define XFERMODE_STEGO_FIRST 1 ++#define XFERMODE_STEGO_ALL 1 ++#define XFERMODE_STEGO_WLE 2 ++#define XFERMODE_STEGO_WBE 3 ++#define XFERMODE_STEGO_DLE 4 ++#define XFERMODE_STEGO_DBE 5 ++#define XFERMODE_STEGO_LAST 5 ++ ++/* Crypto transfer modes */ ++#define XFERMODE_CRYPT_FIRST 16 ++#define XFERMODE_CRYPT_ECB 16 ++#define XFERMODE_CRYPT_CBC 17 ++#define XFERMODE_CRYPT_CFB 18 ++#define XFERMODE_CRYPT_OFB 19 ++#define XFERMODE_CRYPT_PCBC 20 ++#define XFERMODE_CRYPT_LAST 20 ++ ++/* Internally used flags */ ++#define LOOP_FLAG_BMAP (1<<0) ++#define LOOP_FLAG_RDONLY (1<<1) ++ ++/* Number of loop devices */ ++#define NR_LOOP 8 ++ ++#if defined(__KERNEL__) ++ ++/* Forward references */ ++struct inode; ++struct loop_device; ++struct loop_transform; ++struct module; ++struct request; ++ ++/* New data transformations need to register this */ ++struct loop_transform { ++ /* The following must be specified */ ++ char *name; ++ int (*set_status)(struct loop_device *, struct loop_status *); ++ int (*get_status)(struct loop_device *, struct loop_status *); ++ int (*do_request)(struct loop_device *, struct request *); ++ int data_public; ++ int data_total; ++ struct module *module; ++ /* The following should not be specified */ ++ int refcount; ++ struct loop_transform *next; ++}; ++ ++/* Loop device */ ++struct loop_device { ++ int minor; ++ int refcount; ++ struct inode *inode; ++ kdev_t device; ++ char path[LOOP_PATH]; ++ unsigned offset; ++ int flags; ++ struct loop_transform *transform; ++ int xfermode; ++ void *data; ++}; ++ ++/* Exported Symbols */ ++extern int loop_register(struct loop_transform *); ++extern int loop_unregister(struct loop_transform *); ++extern int loop_depth(kdev_t); ++ ++#endif /* defined(__KERNEL__) */ ++#endif /* !defined(_LINUX_LOOP_H) */ +diff --unified --recursive --new-file mount-2.7l.orig/lomount.c mount-2.7l/lomount.c +--- mount-2.7l.orig/lomount.c Fri Nov 21 11:59:50 1997 ++++ mount-2.7l/lomount.c Wed Dec 31 19:00:00 1969 +@@ -1,280 +0,0 @@ +-/* Taken from Ted's losetup.c - Mitch */ +-/* Added vfs mount options - aeb - 960223 */ +-/* Removed lomount - aeb - 960224 */ +- +-#define PROC_DEVICES "/proc/devices" +- +-/* +- * losetup.c - setup and control loop devices +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "loop.h" +-#include "lomount.h" +- +-char *xstrdup (const char *s); /* not: #include "sundries.h" */ +-void error (const char *fmt, ...); /* idem */ +- +-#ifdef LOOP_SET_FD +-struct crypt_type_struct { +- int id; +- char *name; +-} crypt_type_tbl[] = { +- { LO_CRYPT_NONE, "no" }, +- { LO_CRYPT_NONE, "none" }, +- { LO_CRYPT_XOR, "xor" }, +- { LO_CRYPT_DES, "DES" }, +- { -1, NULL } +-}; +- +-static int +-crypt_type (const char *name) +-{ +- int i; +- +- if (name) +- for (i = 0; crypt_type_tbl[i].id != -1; i++) +- if (!strcasecmp (name, crypt_type_tbl[i].name)) +- return crypt_type_tbl[i].id; +- return -1; +-} +- +-#if 0 +-static char * +-crypt_name (int id) +-{ +- int i; +- +- for (i = 0; crypt_type_tbl[i].id != -1; i++) +- if (id == crypt_type_tbl[i].id) +- return crypt_type_tbl[i].name; +- return "undefined"; +-} +- +-static void +-show_loop (char *device) +-{ +- struct loop_info loopinfo; +- int fd; +- +- if ((fd = open (device, O_RDONLY)) < 0) { +- fprintf(stderr, "loop: can't open device %s: %s\n", +- device, strerror (errno)); +- return; +- } +- if (ioctl (fd, LOOP_GET_STATUS, &loopinfo) < 0) { +- fprintf(stderr, "loop: can't get info on device %s: %s\n", +- device, strerror (errno)); +- close (fd); +- return; +- } +- printf ("%s: [%04x]:%ld (%s) offset %d, %s encryption\n", +- device, loopinfo.lo_device, loopinfo.lo_inode, +- loopinfo.lo_name, loopinfo.lo_offset, +- crypt_name (loopinfo.lo_encrypt_type)); +- close (fd); +-} +-#endif +- +-char * +-find_unused_loop_device (void) +-{ +- /* Just creating a device, say in /tmp, is probably a bad idea - +- people might have problems with backup or so. +- So, we just try /dev/loop[0-7]. */ +- char dev[20]; +- int i, fd, somedev = 0, someloop = 0, loop_known = 0; +- struct stat statbuf; +- struct loop_info loopinfo; +- FILE *procdev; +- +- for(i = 0; i < 256; i++) { +- sprintf(dev, "/dev/loop%d", i); +- if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) { +- somedev++; +- fd = open (dev, O_RDONLY); +- if (fd >= 0) { +- if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == 0) +- someloop++; /* in use */ +- else if (errno == ENXIO) { +- close (fd); +- return xstrdup(dev); /* probably free */ +- } +- close (fd); +- } +- continue; /* continue trying as long as devices exist */ +- } +- if (i >= 7) +- break; +- } +- +- /* Nothing found. Why not? */ +- if ((procdev = fopen(PROC_DEVICES, "r")) != NULL) { +- char line[100]; +- while (fgets (line, sizeof(line), procdev)) +- if (strstr (line, " loop\n")) { +- loop_known = 1; +- break; +- } +- fclose(procdev); +- if (!loop_known) +- loop_known = -1; +- } +- +- if (!somedev) +- error("mount: could not find any device /dev/loop#"); +- else if(!someloop) { +- if (loop_known == 1) +- error( +-"mount: Could not find any loop device.\n" +-" Maybe /dev/loop# has a wrong major number?"); +- else if (loop_known == -1) +- error( +-"mount: Could not find any loop device, and, according to %s,\n" +-" this kernel does not know about the loop device.\n" +-" (If so, then recompile or `insmod loop.o'.)", PROC_DEVICES); +- else +- error( +-"mount: Could not find any loop device. Maybe this kernel does not know\n" +-" about the loop device (then recompile or `insmod loop.o'), or\n" +-" maybe /dev/loop# has the wrong major number?"); +- } else +- error("mount: could not find any free loop device"); +- return 0; +-} +- +-int +-set_loop (const char *device, const char *file, int offset, +- const char *encryption, int *loopro) +-{ +- struct loop_info loopinfo; +- int fd, ffd, mode, i; +- char *pass; +- +- mode = (*loopro ? O_RDONLY : O_RDWR); +- if ((ffd = open (file, mode)) < 0) { +- if (!*loopro && errno == EROFS) +- ffd = open (file, mode = O_RDONLY); +- if (ffd < 0) { +- perror (file); +- return 1; +- } +- } +- if ((fd = open (device, mode)) < 0) { +- perror (device); +- return 1; +- } +- *loopro = (mode == O_RDONLY); +- memset (&loopinfo, 0, sizeof (loopinfo)); +- strncpy (loopinfo.lo_name, file, LO_NAME_SIZE); +- loopinfo.lo_name[LO_NAME_SIZE - 1] = 0; +- if (encryption && (loopinfo.lo_encrypt_type = crypt_type (encryption)) +- < 0) { +- fprintf (stderr, "Unsupported encryption type %s\n", encryption); +- return 1; +- } +- loopinfo.lo_offset = offset; +- switch (loopinfo.lo_encrypt_type) { +- case LO_CRYPT_NONE: +- loopinfo.lo_encrypt_key_size = 0; +- break; +- case LO_CRYPT_XOR: +- pass = getpass ("Password: "); +- strncpy (loopinfo.lo_encrypt_key, pass, LO_KEY_SIZE); +- loopinfo.lo_encrypt_key[LO_KEY_SIZE - 1] = 0; +- loopinfo.lo_encrypt_key_size = strlen (loopinfo.lo_encrypt_key); +- break; +- case LO_CRYPT_DES: +- pass = getpass ("Password: "); +- strncpy (loopinfo.lo_encrypt_key, pass, 8); +- loopinfo.lo_encrypt_key[8] = 0; +- loopinfo.lo_encrypt_key_size = 8; +- pass = getpass ("Init (up to 16 hex digits): "); +- for (i = 0; i < 16 && pass[i]; i++) +- if (isxdigit (pass[i])) +- loopinfo.lo_init[i >> 3] |= (pass[i] > '9' ? +- (islower (pass[i]) ? toupper (pass[i]) : +- pass[i]) - 'A' + 10 : pass[i] - '0') << (i & 7) * 4; +- else { +- fprintf (stderr, "Non-hex digit '%c'.\n", pass[i]); +- return 1; +- } +- break; +- default: +- fprintf (stderr, +- "Don't know how to get key for encryption system %d\n", +- loopinfo.lo_encrypt_type); +- return 1; +- } +- if (ioctl (fd, LOOP_SET_FD, ffd) < 0) { +- perror ("ioctl: LOOP_SET_FD"); +- return 1; +- } +- if (ioctl (fd, LOOP_SET_STATUS, &loopinfo) < 0) { +- (void) ioctl (fd, LOOP_CLR_FD, 0); +- perror ("ioctl: LOOP_SET_STATUS"); +- return 1; +- } +- close (fd); +- close (ffd); +- if (verbose > 1) +- printf("set_loop(%s,%s,%d): success\n", device, file, offset); +- return 0; +-} +- +-int +-del_loop (const char *device) +-{ +- int fd; +- +- if ((fd = open (device, O_RDONLY)) < 0) { +- fprintf(stderr, "loop: can't delete device %s: %s\n", +- device, strerror (errno)); +- return 1; +- } +- if (ioctl (fd, LOOP_CLR_FD, 0) < 0) { +- perror ("ioctl: LOOP_CLR_FD"); +- return 1; +- } +- close (fd); +- if (verbose > 1) +- printf("del_loop(%s): success\n", device); +- return 0; +-} +- +-#else /* no LOOP_SET_FD defined */ +-static void +-mutter(void) { +- fprintf(stderr, +- "This mount was compiled without loop support. Please recompile.\n"); +-} +- +-int +-set_loop (const char *device, const char *file, int offset, +- const char *encryption, int *loopro) { +- mutter(); +- return 1; +-} +- +-int +-del_loop (const char *device) { +- mutter(); +- return 1; +-} +- +-char * +-find_unused_loop_device (void) { +- mutter(); +- return 0; +-} +- +-#endif +diff --unified --recursive --new-file mount-2.7l.orig/lomount.h mount-2.7l/lomount.h +--- mount-2.7l.orig/lomount.h Wed Jul 3 08:40:17 1996 ++++ mount-2.7l/lomount.h Wed Dec 31 19:00:00 1969 +@@ -1,4 +0,0 @@ +-extern int verbose; +-extern int set_loop (const char *, const char *, int, const char *, int *); +-extern int del_loop (const char *); +-extern char * find_unused_loop_device (void); +diff --unified --recursive --new-file mount-2.7l.orig/loop.h mount-2.7l/loop.h +--- mount-2.7l.orig/loop.h Wed Dec 31 19:00:00 1969 ++++ mount-2.7l/loop.h Sun Apr 19 16:38:46 1998 +@@ -0,0 +1,116 @@ ++#if !defined(_LINUX_LOOP_H) ++#define _LINUX_LOOP_H ++ ++/* ++ * include/linux/loop.h ++ * ++ * Written by Theodore Ts'o, 3/29/93. ++ * ++ * Copyright 1993 by Theodore Ts'o. Redistribution of this file is ++ * permitted under the GNU Public License. ++ * ++ * HISTORY ++ * May 3, 1997 - Andrew E. Mileski ++ * See loop.c for details and full list of credits. ++ */ ++ ++/* IOCTL commands --- we will commandeer 0x4C ('L') */ ++#define LOOP_SET_FD 0x4C00 ++#define LOOP_CLR_FD 0x4C01 ++#define LOOP_SET_STATUS 0x4C02 ++#define LOOP_GET_STATUS 0x4C03 ++ ++/* Array sizes */ ++#define LOOP_TRANSFORM_NAME 16 ++#define LOOP_MODULE_NAME (LOOP_TRANSFORM_NAME + 5) ++#define LOOP_PATH 255 ++#define LOOP_KEYSIZE 20 ++ ++/* ioctl LOOP_GET_STATUS/LOOP_SET_STATUS info struct */ ++struct loop_status { ++ int minor; /* ro */ ++ kdev_t device; /* ro */ ++ kdev_t rdevice; /* ro */ ++ unsigned long inode; /* ro */ ++ char path[LOOP_PATH]; /* rw */ ++ unsigned offset; /* rw */ ++ unsigned blks; /* rw */ ++ unsigned blksize; /* rw */ ++ int flags; /* ro */ ++ char transform[LOOP_TRANSFORM_NAME]; /* rw */ ++ int xfermode; /* rw */ ++ int datasize; /* rw */ ++}; ++ ++#define XFERMODE_DEFAULT 0 ++ ++/* Steganography transfer modes */ ++#define XFERMODE_STEGO_FIRST 1 ++#define XFERMODE_STEGO_ALL 1 ++#define XFERMODE_STEGO_WLE 2 ++#define XFERMODE_STEGO_WBE 3 ++#define XFERMODE_STEGO_DLE 4 ++#define XFERMODE_STEGO_DBE 5 ++#define XFERMODE_STEGO_LAST 5 ++ ++/* Crypto transfer modes */ ++#define XFERMODE_CRYPT_FIRST 16 ++#define XFERMODE_CRYPT_ECB 16 ++#define XFERMODE_CRYPT_CBC 17 ++#define XFERMODE_CRYPT_CFB 18 ++#define XFERMODE_CRYPT_OFB 19 ++#define XFERMODE_CRYPT_PCBC 20 ++#define XFERMODE_CRYPT_LAST 20 ++ ++/* Internally used flags */ ++#define LOOP_FLAG_BMAP (1<<0) ++#define LOOP_FLAG_RDONLY (1<<1) ++ ++/* Number of loop devices */ ++#define NR_LOOP 8 ++ ++#if defined(__KERNEL__) ++ ++/* Forward references */ ++struct inode; ++struct loop_device; ++struct loop_transform; ++struct module; ++struct request; ++ ++/* New data transformations need to register this */ ++struct loop_transform { ++ /* The following must be specified */ ++ char *name; ++ int (*set_status)(struct loop_device *, struct loop_status *); ++ int (*get_status)(struct loop_device *, struct loop_status *); ++ int (*do_request)(struct loop_device *, struct request *); ++ int data_public; ++ int data_total; ++ struct module *module; ++ /* The following should not be specified */ ++ int refcount; ++ struct loop_transform *next; ++}; ++ ++/* Loop device */ ++struct loop_device { ++ int minor; ++ int refcount; ++ struct inode *inode; ++ kdev_t device; ++ char path[LOOP_PATH]; ++ unsigned offset; ++ int flags; ++ struct loop_transform *transform; ++ int xfermode; ++ void *data; ++}; ++ ++/* Exported Symbols */ ++extern int loop_register(struct loop_transform *); ++extern int loop_unregister(struct loop_transform *); ++extern int loop_depth(kdev_t); ++ ++#endif /* defined(__KERNEL__) */ ++#endif /* !defined(_LINUX_LOOP_H) */ +diff --unified --recursive --new-file mount-2.7l.orig/losetup.8 mount-2.7l/losetup.8 +--- mount-2.7l.orig/losetup.8 Mon Apr 15 18:15:26 1996 ++++ mount-2.7l/losetup.8 Sat Apr 11 15:42:14 1998 +@@ -1,87 +1,234 @@ +-.TH LOSETUP 8 "Nov 24 1993" "Linux" "MAINTENANCE COMMANDS" ++.TH LOSETUP 8 "May 3 1997" "Linux" "MAINTENANCE COMMANDS" + .SH NAME +-losetup \- set up and control loop devices ++losetup \- setup and control loop devices. + .SH SYNOPSIS +-.ad l + .B losetup +-[ +-.B \-e +-.I encryption +-] [ +-.B \-o +-.I offset +-] +-.I loop_device file ++\-a [\-b block_size] [\-m mode] [\-o offset] [\-p] [\-r] [\-s size] ++[\-t transform] filename + .br + .B losetup +-[ +-.B \-d +-] +-.I loop_device +-.ad b ++[\-b block_size] [\-m mode] [\-o offset] [\-p] [\-r] [\-s size] ++[\-t transform] loop_device filename ++.br ++.B losetup ++loop_device ++.br ++.B losetup ++\-d loop_device ++.br ++.B losetup ++\-V + .SH DESCRIPTION + .B losetup + is used to associate loop devices with regular files or block devices, +-to detach loop devices and to query the status of a loop device. If only the +-\fIloop_device\fP argument is given, the status of the corresponding loop +-device is shown. ++to query the status of a loop device, and to detach a loop device from the ++regular file or block device it is associated with. + .SH OPTIONS +-.IP \fB\-d\fP +-detach the file or device associated with the specified loop device. +-.IP "\fB\-e \fIencryption\fP" +-.RS +-enable data encryption. The following keywords are recognized: +-.IP \fBNONE\fP +-use no encryption (default). +-.PD 0 +-.IP \fBXOR\fP +-use a simple XOR encryption. +-.IP \fBDES\fP +-use DES encryption. DES encryption is only available if the optional +-DES package has been added to the kernel. DES encryption uses an additional +-start value that is used to protect passwords against dictionary +-attacks. +-.PD ++.IP "\fB\-a\fP" ++.RS ++Use the next available loop device. ++.RE ++.LP ++.IP "\fB\-b\fP \fIblock_size\fP" ++.RS ++Set the loop device block size to \fIblock_size\fP bytes. ++Valid values are 512, 1024, 2048, 4096 and 8192 (default is 512). ++.RE ++.LP ++.IP "\fB\-e\fP" ++.RS ++Same as \fB\-t\fP (deprecated). ++.RE ++.LP ++.IP "\fB\-d\fP" ++.RS ++Detach the loop device from its associated regular file or block device. ++.RE ++.LP ++.IP "\fB\-m\fP \fImode\fP" ++.RS ++Set the transfer mode. ++.LP ++Valid \fBENCRYPTION\fP modes are: ++.IP "\fIecb\fP" ++Electronic codebook mode ++.RS ++.nf ++c[i] = f1(K, p[i]) ++p[i] = f2(K, c[i]) ++.fi ++.RE ++.IP "\fIcbc\fP" ++Ciphertext block chaining mode ++.RS ++.nf ++c[i] = f1(K, p[i] ^ c[i-1]) ++p[i] = f2(K, c[i]) ^ c[i-1] ++.fi ++.RE ++.IP "\fIcfb\fP" ++Ciphertext feeback mode ++.RS ++.nf ++c[i] = f1(K, c[i-1]) ^ p[i] ++p[i] = f2(K, c[i-1]) ^ c[i] ++.fi ++.RE ++.IP "\fIofb\fP" ++Output feeback mode ++.RS ++.nf ++h[i] = f1(K, h[i-1]) ++c[i] = p[i] ^ h[i] ++p[i] = c[i] ^ h[i] ++.fi ++.RE ++.LP ++Valid \fBSTEGANOGRAPHY\fP modes are: ++.IP "\fIall\fP" ++Bit 0 of all consecutive destination bytes is replaced by a source bit. ++.IP "\fIwle\fP" ++Bit 0 of byte 0 of little-endian words is replaced by a source bit. ++.IP "\fIwbe\fP" ++Bit 0 of byte 0 of big-endian words is replaced by a source bit. ++.IP "\fIdle\fP" ++Bit 0 of byte 0 of little-endian doublewords is replaced by a source bit. ++.IP "\fIdbe\fP" ++Bit 0 of byte 0 of big-endian doublewords is replaced by a source bit. + .RE + .IP "\fB\-o \fIoffset\fP" +-the data start is moved \fIoffset\fP bytes into the specified file or +-device. +-.SH FILES ++.RS ++Set the data start \fIoffset\fP bytes from the actual start (default is 0). ++.RE ++.LP ++.IP "\fB\-p\fP" ++.RS ++Don't ask for a passphrase (default is ask). For use only with data ++transformations other than "none" and "stego" that don't require a passphrase. ++.RE ++.LP ++.IP "\fB\-r\fP" ++.RS ++Make the loop device read-only. ++.RE ++.LP ++.IP "\fB\-s \fIsize\fP" ++.RS ++Set the size of the loop device to \fIsize\fP blocks (default is ++the size of the associated regular file or block device). ++.RE ++.LP ++.IP "\fB\-t \fItransformation\fP" ++.RS ++Set a data transformation (default is none). ++.RE ++.LP ++.IP "\fB\-V\fP" ++.RS ++Display losetup version info. ++.RE ++.SH DATA TRANSFORMATIONS ++The loop driver does not contain any data transformations. Each data ++transformation can be compiled separately into the kernel, or compiled as a ++loadable module. At least one data transformation is required in order to use ++the loop driver. ++.LP ++Three standard data transformations are shipped in the kernel source ++distribution: ++.IP \fBnone\fP ++No data transformation is performed (default). ++.IP \fBstego\fP ++Steganography (data hiding). ++.IP \fBxor\fP ++XOR encryption. Simple, fast, but very insecure to analytic attacks. ++.RE ++.LP ++The following transformations are available, but are not shipped with the ++kernel source distribution for legal reasons: ++.IP \fBblowfish\fP ++Blowfish data encryption algorithm. ++.IP \fBcast\fP ++CAST-128 data encryption algorithm. ++.IP \fBdes\fP ++Data Encryption Standard algorithm. ++.IP \fBidea\fP ++International Data Encryption Algorithm. ++.RE ++.LP ++Please see the loop driver documentation (shipped with the kernel source) ++for availablilty and export restrictions. ++.SH LOOP DEVICES ++The loop device driver compiles with support for 8 loop devices. ++.LP + .nf +-/dev/loop0,/dev/loop1,... loop devices (major=7) ++.IP ++/dev/loop0 (major = 7, minor = 0) ++/dev/loop1 (major = 7, minor = 1) ++ ... ++/dev/loop7 (major = 7, minor = 7) + .fi +-.SH EXAMPLE +-If you are using the loadable module you must have the module loaded +-first with the command ++.LP ++It is a good idea to increase NR_REQUEST (default 64) defined in ++linux/include/blk.h for better performance. ++.SH MODULES ++If you are using loadable modules, you must have the loop driver compiled into ++the kernel, or compiled as a module and loaded before any transformation ++modules. When unloading modules, all the transformation modules must be ++unloaded before the loop driver module. ++.LP ++The easiest way to ensure the correct order is to use the \fBmodprobe\fP ++utility, and let it worry about all the details. Make sure you have a ++\fBdepmod \-a\fP statement in your boot scripts, or you'll have to ++enter it manually. ++.LP ++Load transformations: ++.nf + .IP +-# insmod loop.o ++# modprobe loop_none ++# modprobe loop_stego ++# modprobe loop_xor ++.fi + .LP +-The following commands can be used as an example of using the loop device. ++Unload Transformations: + .nf + .IP +-dd if=/dev/zero of=/file bs=1k count=100 +-losetup -e des /dev/loop0 /file +-Password: +-Init (up to 16 hex digits): +-mkfs -t ext2 /dev/loop0 100 +-mount -t ext2 /dev/loop0 /mnt +- ... +-umount /dev/loop0 +-losetup -d /dev/loop0 ++# modprobe -r loop_none ++# modprobe -r loop_stego ++# modprobe -r loop_xor + .fi ++.SH EXAMPLE ++The following is an example of all of the commands used to create ++an 8MB XOR encrypted ext2 filesystem: ++.LP ++Step 1: Prepare an 8 MB XOR exncypted ext2 filesystem. + .LP +-If you are using the loadable module you may remove the module with +-the command + .IP +-# rmmod loop ++.nf ++dd if=/dev/zero of=file bs=1k count=8k ++losetup -t xor /dev/loop0 file ++Passphrase: Peter Piper picked a peck of pickled peppers. ++mkfs -t ext2 /dev/loop0 ++losetup -d /dev/loop0 ++.fi ++.RE ++.LP ++Step 2: Mount, use, and unmount the filesystem when done. + .LP ++.IP ++.nf ++mount -o loop=/dev/loop0,type=xor file /mnt/tmp ++Passphrase: Peter Piper picked a peck of pickled peppers. ++ ... ++umount file + .fi +-.SH RESTRICTION +-DES encryption is painfully slow. On the other hand, XOR is terribly weak. ++.RE ++.LP ++.SH SEE ALSO ++depmod(1), insmod(1), kerneld(1), lsmod(1), modprobe(1), modules(2), mount(8), ++rmmod(1) + .SH AUTHORS + .nf +-Original version: Theodore Ts'o +-Maintained by: Werner Almesberger +-Original DES by: Eric Young +-Modularized and updated 28-5-94: Mitch DSouza ++Original version: Theodore Y. Ts'o ++Enhanced and polished by many others (see the source code). ++Currently maintained by Andrew E. Mileski + .fi +diff --unified --recursive --new-file mount-2.7l.orig/losetup.c mount-2.7l/losetup.c +--- mount-2.7l.orig/losetup.c Mon Jan 26 17:59:58 1998 ++++ mount-2.7l/losetup.c Sun Apr 26 16:48:03 1998 +@@ -1,225 +1,515 @@ + /* +- * losetup.c - setup and control loop devices ++ * losetup.c ++ * ++ * PURPOSE ++ * Setup and control loop devices. ++ * ++ * HISTORY ++ * May 5, 1997 - Andrew E. Mileski ++ * Renamed, reformatted, commented, and adapted for use with modular ++ * data transformations. + */ + +-#include +-#include + #include ++#include + #include +-#include + #include +-#include ++#include ++#include ++#include ++#include ++#define __KERNEL__ ++#include ++#undef __KERNEL__ + #include +- + #include "loop.h" +-#include "lomount.h" +- +-#ifdef LOOP_SET_FD +- +-static char *progname; ++#include "losetup.h" ++#include "rmd160.h" + +-struct crypt_type_struct { +- int id; ++/* Version info for messages */ ++#define KERNEL_STRING "2.1.58" ++#define VERSION_STRING "2.0" ++ ++/* Use a 160 bit (20 byte) RIPE MD-160 hash for keys */ ++#define RMD_SIZE 160 ++ ++/* Transfer modes */ ++static struct loop_xfermode{ ++ int xfermode; + char *name; +-} crypt_type_tbl[] = { +- { LO_CRYPT_NONE,"no" }, +- { LO_CRYPT_NONE,"none" }, +- { LO_CRYPT_XOR, "xor" }, +- { LO_CRYPT_DES, "DES" }, +- { -1, NULL } ++} loop_xfermodes[] = { ++ { XFERMODE_DEFAULT, "default" }, ++ { XFERMODE_STEGO_ALL, "all" }, ++ { XFERMODE_STEGO_WLE, "wle" }, ++ { XFERMODE_STEGO_WBE, "wbe" }, ++ { XFERMODE_STEGO_DLE, "dle" }, ++ { XFERMODE_STEGO_DBE, "dbe" }, ++ { XFERMODE_CRYPT_ECB, "ecb" }, ++ { XFERMODE_CRYPT_CBC, "cbc" }, ++ { XFERMODE_CRYPT_CFB, "cfb" }, ++ { XFERMODE_CRYPT_OFB, "ofb" }, ++ { XFERMODE_CRYPT_PCBC, "pcbc" }, ++ { -1, NULL } + }; + +- +-static char *crypt_name(int id) ++/* ++ * loop_get_xfermode ++ * ++ * PURPOSE ++ * Get the numeric xfermode for the xfermode string. ++ * ++ * HISTORY ++ * May 5, 1997 - Andrew E. Mileski ++ * Written, tested, and released. ++ */ ++extern ++int loop_get_xfermode(char *txt) + { +- int i; ++ struct loop_xfermode *p; + +- for (i = 0; crypt_type_tbl[i].id != -1; i++) +- if (id == crypt_type_tbl[i].id) +- return crypt_type_tbl[i].name; +- return "undefined"; +-} ++ /* Search for the string */ ++ for (p = loop_xfermodes; p->name; p++) { ++ if (!strcmp(txt, p->name)) ++ break; ++ } + ++ return p->xfermode; ++} + +-static int crypt_type(const char *name) ++/* ++ * loop_get_unused ++ * ++ * PURPOSE ++ * Find an unused loop device. ++ * ++ * HISTORY ++ * May 5, 1997 - Andrew E. Mileski ++ * Written, tested, and released. ++ */ ++extern ++char *loop_get_unused(char *progname, int verbose) + { +- int i; +- +- for (i = 0; crypt_type_tbl[i].id != -1; i++) +- if (!strcasecmp(name, crypt_type_tbl[i].name)) +- return crypt_type_tbl[i].id; +- return -1; ++ int fd, dev; ++ static char device[] = "/dev/loop "; ++ struct loop_status status; ++ ++ for (dev = 0; dev < NR_LOOP; dev++) { ++ sprintf(device + 9, "%d", dev); ++ fd = open(device, O_RDWR); ++ if (fd < 0) ++ continue; ++ if (ioctl(fd, LOOP_GET_STATUS, &status) < 0) { ++ close(fd); ++ if (verbose) ++ fprintf(stderr, "%s: using %s\n", progname, ++ device); ++ return device; ++ } ++ close(fd); ++ } ++ if (verbose) ++ fprintf(stderr, "%s: can't find a free loop device\n", ++ progname); ++ return NULL; + } + +- +-static void show_loop(const char *device) ++#if !defined(LOMOUNT) ++/* ++ * loop_show ++ * ++ * PURPOSE ++ * Output status of a loop device. ++ * ++ * HISTORY ++ * May 5, 1997 - Andrew E. Mileski ++ * Renamed, reformatted, commented, and made more verbose. ++ */ ++static ++void loop_show(char *device) + { +- struct loop_info loopinfo; +- int fd; +- ++ struct loop_status status; ++ struct loop_xfermode *xfermode; ++ struct hd_geometry geo; ++ int fd; ++ ++ /* Open the loop device */ + if ((fd = open(device, O_RDWR)) < 0) { +- perror(device); ++ perror("open on loop device failed"); + return; + } +- if (ioctl(fd, LOOP_GET_STATUS, &loopinfo) < 0) { +- perror("Cannot get loop info"); ++ ++ /* Get the status */ ++ if (ioctl(fd, LOOP_GET_STATUS, &status) < 0) { ++ perror("ioctl LOOP_GET_STATUS failed"); ++ close(fd); ++ return; ++ } ++ ++ /* Get the geometry */ ++ if (ioctl(fd, HDIO_GETGEO, &geo) < 0) { ++ perror("ioctl HDIO_GETGEO failed"); + close(fd); + return; + } +- printf("%s: [%04x]:%ld (%s) offset %d, %s encryption\n", +- device, loopinfo.lo_device, loopinfo.lo_inode, +- loopinfo.lo_name, loopinfo.lo_offset, +- crypt_name(loopinfo.lo_encrypt_type)); + close(fd); +-} + ++ for (xfermode = loop_xfermodes; xfermode->xfermode > 0; xfermode++) ++ if (status.xfermode == xfermode->xfermode) ++ break; ++ ++ /* Display the status */ ++ printf("device = %d, %d\n" ++ "rdevice = %d, %d\n" ++ "inode = %lu\n" ++ "path = %s\n" ++ "offset = %u bytes\n" ++ "size = %d blocks x %d bytes/block\n" ++ "flags =%s%s\n" ++ "transform = %s\n" ++ "xfermode = %s\n" ++ "geometry = %d/%d/%d (C/H/S)\n", ++ MAJOR(status.device), MINOR(status.device), ++ MAJOR(status.rdevice), MINOR(status.rdevice), ++ status.inode, ++ status.path, ++ status.offset, ++ status.blks, status.blksize, ++ (status.flags & LOOP_FLAG_RDONLY) ? " RDONLY": "", ++ (status.flags & LOOP_FLAG_BMAP) ? " BMAP": "", ++ status.transform, ++ xfermode->name, ++ geo.cylinders, geo.heads, geo.sectors ++ ); ++} ++#endif /* !defined(LOMOUNT) */ + +-int set_loop(const char *device, const char *file, int offset, +- const char *encryption, int *loopro) ++/* ++ * loop_attach ++ * ++ * PURPOSE ++ * Attach a regular file or block device to a loop device. ++ * ++ * HISTORY ++ * May 5, 1997 - Andrew E. Mileski ++ * Renamed, reformatted, commented, and adapted for modular ++ * transform use. ++ */ ++extern ++int loop_attach(struct loop_attach_args *args) + { +- struct loop_info loopinfo; +- int fd, ffd, mode, i; +- char *pass; +- +- mode = *loopro ? O_RDONLY : O_RDWR; +- if ((ffd = open (file, mode)) < 0 && !*loopro +- && (errno != EROFS || (ffd = open (file, mode = O_RDONLY)) < 0)) { +- perror (file); +- return 1; +- } +- if ((fd = open (device, mode)) < 0) { +- perror (device); +- return 1; +- } +- *loopro = (mode == O_RDONLY); +- +- memset(&loopinfo, 0, sizeof(loopinfo)); +- strncpy(loopinfo.lo_name, file, LO_NAME_SIZE); +- loopinfo.lo_name[LO_NAME_SIZE-1] = 0; +- if (encryption && (loopinfo.lo_encrypt_type = crypt_type(encryption)) +- < 0) { +- fprintf(stderr,"Unsupported encryption type %s\n",encryption); +- exit(1); +- } +- loopinfo.lo_offset = offset; +- switch (loopinfo.lo_encrypt_type) { +- case LO_CRYPT_NONE: +- loopinfo.lo_encrypt_key_size = 0; +- break; +- case LO_CRYPT_XOR: +- pass = getpass("Password: "); +- strncpy(loopinfo.lo_encrypt_key, pass, LO_KEY_SIZE); +- loopinfo.lo_encrypt_key[LO_KEY_SIZE-1] = 0; +- loopinfo.lo_encrypt_key_size = strlen(loopinfo.lo_encrypt_key); +- break; +- case LO_CRYPT_DES: +- pass = getpass("Password: "); +- strncpy(loopinfo.lo_encrypt_key, pass, 8); +- loopinfo.lo_encrypt_key[8] = 0; +- loopinfo.lo_encrypt_key_size = 8; +- pass = getpass("Init (up to 16 hex digits): "); +- for (i = 0; i < 16 && pass[i]; i++) +- if (isxdigit(pass[i])) +- loopinfo.lo_init[i >> 3] |= (pass[i] > '9' ? +- (islower(pass[i]) ? toupper(pass[i]) : +- pass[i])-'A'+10 : pass[i]-'0') << (i & 7)*4; +- else { +- fprintf(stderr,"Non-hex digit '%c'.\n",pass[i]); +- exit(1); ++ struct { ++ struct loop_status status; ++ int mode; ++ unsigned char key[LOOP_KEYSIZE]; ++ } s; ++ int dev_fd, file_fd, mode; ++ ++ /* Clear status */ ++ memset((void *) &s, 0, sizeof(s)); ++ ++ /* Get the absolute pathname */ ++ if (*args->file != '/' && getcwd(s.status.path, LOOP_PATH) ++ && (strlen(s.status.path) + strlen(args->file) + 1) < LOOP_PATH ++ ) { ++ strcat(s.status.path, "/"); ++ strcat(s.status.path, args->file); ++ } else ++ strncpy(s.status.path, args->file, LOOP_PATH); ++ s.status.path[LOOP_PATH - 1] = 0; ++ ++ /* Open the file to attach */ ++ mode = args->read_only ? O_RDONLY : O_RDWR; ++ file_fd = open(s.status.path, mode); ++ if (file_fd == -EROFS && mode == O_RDWR) { ++ mode = O_RDONLY; ++ args->read_only = 1; ++ file_fd = open(args->file, mode); ++ } ++ if (file_fd < 0) { ++ perror(s.status.path); ++ return 1; ++ } ++ ++ /* Open the loop device */ ++ dev_fd = open(args->device, mode); ++ if (dev_fd < 0) { ++ perror(args->device); ++ return 1; ++ } ++ if (mode == O_RDONLY) ++ s.status.flags = LOOP_FLAG_RDONLY; ++ ++ /* Fill in the name of the loop transform */ ++ if (args->transform) { ++ strncpy(s.status.transform, args->transform, ++ LOOP_TRANSFORM_NAME); ++ s.status.transform[LOOP_TRANSFORM_NAME - 1] = 0; ++ } else ++ strcpy(s.status.transform, "copy"); ++ ++ s.status.offset = args->offset; ++ s.status.blks = args->blks; ++ s.status.blksize = args->blksize; ++ s.status.xfermode = args->xfermode; ++ ++ /* Get a passphrase if required */ ++ if (strcmp(s.status.transform, "copy") ++ && strcmp(s.status.transform, "stego") ++ && !args->nopasswd ++ ) { ++ /* ++ * The following code hashes the passphrase using RIPE MD-160. ++ * IMPORTANT: Only the first 64k of a passphrase is hashed! ++ */ ++ ++ /* Current state */ ++ word state[(RMD_SIZE / 8) / sizeof(word)]; ++ /* Result */ ++ byte hash[RMD_SIZE / 8]; ++ /* Current 16 little-endian words of the passphrase */ ++ word X[16]; ++ /* Bytes in message */ ++ word length; ++ ++ word nbytes; ++ unsigned i; ++ char *passphrase; ++ ++ /* Get the passphrase */ ++ passphrase = getpass("Passphrase: "); ++ length = (word)strlen(passphrase); ++ ++ /* Initialize the RIPE MD-160 state */ ++ MDinit(state); ++ ++ /* Hash the passphrase in 64 byte (16 word) blocks */ ++ for (nbytes = length; nbytes > 63; nbytes -= 64 ) { ++ ++ /* Convert block to little-endian words */ ++ for (i = 0; i < 16; i++) { ++ X[i] = (((byte *)passphrase)[3] << 24) ++ | (((byte *)passphrase)[2] << 16) ++ | (((byte *)passphrase)[1] << 8) ++ | (((byte *)passphrase)[0]); ++ passphrase += 4; + } +- break; +- default: +- fprintf(stderr, +- "Don't know how to get key for encryption system %d\n", +- loopinfo.lo_encrypt_type); +- exit(1); ++ ++ /* Hash the 16 word block */ ++ MDcompress(state, X); ++ } ++ ++ /* Hash any remaining bytes */ ++ MDfinish(state, passphrase, length << 3, length >> 29); ++ ++ /* Convert hash to string of little-endian bytes */ ++ for (i = 0; i < (RMD_SIZE / 8); i += 4) { ++ hash[i + 0] = state[i >> 2]; ++ hash[i + 1] = state[i >> 2] >> 8; ++ hash[i + 2] = state[i >> 2] >> 16; ++ hash[i + 3] = state[i >> 2] >> 24; ++ } ++ ++ /* Copy the result to the new status */ ++ memcpy(s.key, hash, LOOP_KEYSIZE); ++ ++ /* Be paranoid */ ++ memset(passphrase, 0, length); + } +- if (ioctl(fd, LOOP_SET_FD, ffd) < 0) { +- perror("ioctl: LOOP_SET_FD"); ++ ++ /* Associate a file to the loop device */ ++ if (ioctl(dev_fd, LOOP_SET_FD, file_fd) < 0) { ++ perror("ioctl LOOP_SET_FD failed"); + exit(1); + } +- if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) { +- (void) ioctl(fd, LOOP_CLR_FD, 0); +- perror("ioctl: LOOP_SET_STATUS"); ++ ++ /* Set the status of the loop device */ ++ if (ioctl(dev_fd, LOOP_SET_STATUS, &s.status) < 0) { ++ ioctl(dev_fd, LOOP_CLR_FD, 0); ++ perror("ioctl LOOP_SET_STATUS failed"); + exit(1); + } +- close(fd); +- close(ffd); ++ ++ /* Done */ ++ close(dev_fd); ++ close(file_fd); + return 0; + } + +-int del_loop(const char *device) ++/* ++ * loop_detach ++ * ++ * PURPOSE ++ * Detach a loop device from the regular file or block device ++ * that was previously attached with loop_attach(). ++ * ++ * HISTORY ++ * May 5, 1997 - Andrew E. Mileski ++ * Renamed, reformatted, and commented. ++ */ ++extern ++int loop_detach(const char *device) + { + int fd; + ++ /* Open the loop device - only we can have it open */ + if ((fd = open(device, O_RDONLY)) < 0) { + perror(device); + exit(1); + } ++ ++ /* Unloop the specified device */ + if (ioctl(fd, LOOP_CLR_FD, 0) < 0) { +- perror("ioctl: LOOP_CLR_FD"); ++ perror("ioctl LOOP_CLR_FD failed"); + exit(1); + } ++ ++ /* Done */ + return(0); + } + ++#if !defined(LOMOUNT) ++/* ++ * loop_version ++ * ++ * PURPOSE ++ * Output a version message. ++ * ++ * HISTORY ++ * May 5, 1997 - Andrew E. Mileski ++ * Written, tested, and released. ++ */ ++static __inline__ ++int loop_version(void) ++{ ++ fprintf(stderr, "losetup version " VERSION_STRING ++ " Compatible with Linux kernels > " KERNEL_STRING "\n"); ++ return 0; ++} + +-static int usage(void) ++/* ++ * loop_usage ++ * ++ * PURPOSE ++ * Output a usage message. ++ * ++ * HISTORY ++ * May 5, 1997 - Andrew E. Mileski ++ * Renamed, reformatted, and commented. ++ */ ++static ++int loop_usage(void) + { +- fprintf(stderr, "usage:\n\ +- %s loop_device # give info\n\ +- %s -d loop_device # delete\n\ +- %s [ -e encryption ] [ -o offset ] loop_device file # setup\n", +- progname, progname, progname); +- exit(1); ++ loop_version(); ++ fprintf(stderr, ++ " losetup loop_device\n" ++ " losetup -d loop_device\n" ++ " losetup -a [-b blocksize] [-r] [-s size] [-t transform] [-o offset] path\n" ++ " losetup [-b blocksize] [-r] [-s size] [-t transform] [-o offset] loop_device path\n" ++ " losetup -V\n" ++ ); ++ return 0; + } + ++/* ++ * main ++ * ++ * PURPOSE ++ * Parse the args and act upon them. ++ * ++ * HISTORY ++ * May 5, 1997 - Andrew E. Mileski ++ * Renamed, reformatted, and commented. ++ */ ++extern + int main(int argc, char **argv) + { +- char *offset,*encryption; +- int delete,off,c; +- int ro = 0; +- +- delete = off = 0; +- offset = encryption = NULL; +- progname = argv[0]; +- while ((c = getopt(argc,argv,"de:o:")) != EOF) { ++ int c, detach = 0; ++ struct loop_attach_args args; ++ ++ memset(&args, 0, sizeof(args)); ++ ++ /* Parse the command line */ ++ while ((c = getopt(argc,argv, "Vab:de:m:o:prs:t:")) != EOF) { + switch (c) { ++ case 'V': ++ return loop_version(); ++ ++ case 'a': ++ args.device = loop_get_unused(*argv, 1); ++ if (!args.device) ++ return 0; ++ break; ++ ++ case 'b': ++ if(sscanf(optarg, "%u", &args.blksize) != 1) ++ return loop_usage(); ++ ++ switch (args.blksize) { ++ case 512: ++ case 1024: ++ case 2048: ++ case 4096: ++ case 8192: ++ break; ++ default: ++ return loop_usage(); ++ } ++ break; ++ + case 'd': +- delete = 1; ++ detach = 1; + break; +- case 'e': +- encryption = optarg; ++ ++ case 'm': ++ args.xfermode = loop_get_xfermode(optarg); ++ if (args.xfermode < 0) ++ return loop_usage(); + break; ++ + case 'o': +- offset = optarg; ++ if (sscanf(optarg, "%u", &args.offset) != 1) ++ return loop_usage(); ++ break; ++ ++ case 'p': ++ args.nopasswd = 1; ++ break; ++ ++ case 'r': ++ args.read_only = 1; ++ break; ++ ++ case 's': ++ if (sscanf(optarg, "%u", &args.blks) != 1) ++ return loop_usage(); + break; ++ ++ case 'e': ++ case 't': ++ args.transform = optarg; ++ break; ++ + default: +- usage(); ++ return loop_usage(); + } + } +- if (argc == 1) usage(); +- if ((delete && (argc != optind+1 || encryption || offset)) || +- (!delete && (argc < optind+1 || argc > optind+2))) +- usage(); +- if (argc == optind+1) +- if (delete) +- del_loop(argv[optind]); +- else +- show_loop(argv[optind]); +- else { +- if (offset && sscanf(offset,"%d",&off) != 1) +- usage(); +- set_loop(argv[optind],argv[optind+1],off,encryption,&ro); +- } +- return 0; +-} + +-#else /* LOOP_SET_FD not defined */ ++ /* Validate the args for each command */ + +-int main(int argc, char **argv) { +- fprintf(stderr, +- "No loop support was available at compile time. Please recompile.\n"); +- return -1; ++ if (detach && optind == 2 && argc == 3) ++ loop_detach(argv[2]); ++ else if (!detach && optind == 1 && argc == 2) ++ loop_show(argv[1]); ++ else if (!detach && args.device && optind == (argc - 1) && argc >= 3) { ++ args.file = argv[optind]; ++ loop_attach(&args); ++ } else if (!detach && !args.device && optind == (argc - 2) && argc >= 3) { ++ args.device = argv[optind]; ++ args.file = argv[optind + 1]; ++ loop_attach(&args); ++ } else ++ return loop_usage(); ++ ++ return 0; + } +-#endif ++#endif /* !defined(LOMOUNT) */ +diff --unified --recursive --new-file mount-2.7l.orig/losetup.h mount-2.7l/losetup.h +--- mount-2.7l.orig/losetup.h Wed Dec 31 19:00:00 1969 ++++ mount-2.7l/losetup.h Sat Apr 11 15:43:16 1998 +@@ -0,0 +1,15 @@ ++struct loop_attach_args { ++ char *device; ++ char *file; ++ unsigned offset; ++ int blks; ++ int blksize; ++ char *transform; ++ int xfermode; ++ int read_only; ++ int nopasswd; ++}; ++extern int loop_attach(struct loop_attach_args *); ++extern int loop_detach(const char *); ++extern int loop_get_xfermode(char *); ++extern char *loop_get_unused(char *, int); +diff --unified --recursive --new-file mount-2.7l.orig/mount.c mount-2.7l/mount.c +--- mount-2.7l.orig/mount.c Mon Feb 2 03:51:54 1998 ++++ mount-2.7l/mount.c Sun Apr 19 16:48:41 1998 +@@ -30,27 +30,34 @@ + * + * Wed Oct 1 23:55:28 1997: Dick Streefland + * Implemented the "bg", "fg" and "retry" mount options for NFS. ++ * ++ * Fri Apr 10 21:00:00 1998: Andrew E. Mileski ++ * Added modular loop device driver support. + */ + +-#include + #include + #include +-#include + #include + #include ++#include ++#include ++ ++#define __KERNEL__ ++#include ++#undef __KERNEL__ + +-#include + #include ++#include + #include ++#include + #include +-#include + +-#include "mount_constants.h" +-#include "sundries.h" + #include "fstab.h" +-#include "lomount.h" +-#include "loop.h" + #include "linux_fs.h" ++#include "losetup.h" ++#include "loop.h" ++#include "sundries.h" ++#include "mount_constants.h" + + #define PROC_FILESYSTEMS "/proc/filesystems" + #define SIZE(a) (sizeof(a)/sizeof(a[0])) +@@ -159,17 +166,24 @@ + { NULL, 0, 0, 0 } + }; + +-char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption; ++char *opt_vfstype; ++ ++/* Loop device arg pointers */ ++char *opt_loop_blksize, *opt_loop_device, *opt_loop_offset; ++char *opt_loop_size, *opt_loop_type, *opt_loop_xfermode; + + struct string_opt_map { + char *tag; + int skip; + char **valptr; + } string_opt_map[] = { +- { "loop=", 0, &opt_loopdev }, ++ { "loop=", 0, &opt_loop_device }, + { "vfs=", 1, &opt_vfstype }, +- { "offset=", 0, &opt_offset }, +- { "encryption=", 0, &opt_encryption }, ++ { "blksize=", 1, &opt_loop_blksize }, ++ { "mode=", 1, &opt_loop_xfermode }, ++ { "offset=", 1, &opt_loop_offset }, ++ { "size=", 1, &opt_loop_size }, ++ { "type=", 1, &opt_loop_type }, + { NULL, 0, NULL } + }; + +@@ -594,10 +608,14 @@ + char *extra_opts; /* written in mtab */ + char *mount_opts; /* actually used on system call */ + static int added_ro = 0; +- int loop, looptype, offset; +- char *spec, *node, *type, *opts, *loopdev, *loopfile; ++ char *spec, *node, *type, *opts; + struct stat statbuf; + ++ /* These are loop device specific */ ++ struct loop_attach_args loop_args; ++ int loop, looptype; ++ memset(&loop_args, 0, sizeof(loop_args)); ++ + spec = xstrdup(spec0); + node = xstrdup(node0); + type = xstrdup(type0); +@@ -627,13 +645,13 @@ + * immediately: maybe later other types of mountable objects will occur. + */ + +- loopdev = opt_loopdev; ++ loop_args.device = opt_loop_device; + + looptype = (type && strncmp("lo@", type, 3) == 0); + if (looptype) { +- if (loopdev) ++ if (loop_args.device) + error("mount: loop device specified twice"); +- loopdev = type+3; ++ loop_args.device = type+3; + type = opt_vfstype; + } + else if (opt_vfstype) { +@@ -643,8 +661,8 @@ + type = opt_vfstype; + } + +- loop = ((flags & MS_LOOP) || loopdev || opt_offset || opt_encryption); +- loopfile = spec; ++ loop = ((flags & MS_LOOP) || loop_args.device || opt_loop_offset || opt_loop_type); ++ loop_args.file = spec; + + if (loop) { + flags |= MS_LOOP; +@@ -652,23 +670,52 @@ + if (verbose) + printf("mount: skipping the setup of a loop device\n"); + } else { +- int loopro = (flags & MS_RDONLY); ++ loop_args.read_only = (flags & MS_RDONLY); + +- if (!loopdev || !*loopdev) +- loopdev = find_unused_loop_device(); +- if (!loopdev) +- return EX_SYSERR; /* no more loop devices */ +- if (verbose) +- printf("mount: going to use the loop device %s\n", loopdev); +- offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0; +- if (set_loop (loopdev, loopfile, offset, opt_encryption, &loopro)) ++ /* Try to find a free loop device if one wasn't specified */ ++ if (!loop_args.device || !*loop_args.device) ++ loop_args.device = loop_get_unused("mount", verbose); ++ if (!loop_args.device) ++ return EX_SYSERR; ++ ++ /* Loop offset - default = 0 */ ++ loop_args.offset = opt_loop_offset ? strtoul(opt_loop_offset, NULL, 0) : 0; ++ ++ /* Loop size - default = 0, meaning size of file/device */ ++ if (opt_loop_size) ++ loop_args.blks = strtoul(opt_loop_size, NULL, 0); ++ ++ /* Loop data transform - default = "copy" */ ++ loop_args.transform = opt_loop_type ? opt_loop_type: "copy"; ++ ++ /* Loop block size - default = 0, meaning size of file/device */ ++ if (opt_loop_blksize) ++ loop_args.blksize = strtoul(opt_loop_blksize, NULL, 0); ++ ++ /* Transfer modes */ ++ if (opt_loop_xfermode) { ++ loop_args.xfermode = loop_get_xfermode(opt_loop_xfermode); ++ if (loop_args.xfermode < 0) ++ return EX_SYSERR; ++ } ++ ++ /* Read-only loop device */ ++ loop_args.read_only = flags & MS_RDONLY; ++ ++ /* Attach the loop device */ ++ if (loop_attach(&loop_args)) + return EX_FAIL; +- spec = loopdev; +- if (loopro) ++ ++ spec = loop_args.device; ++ ++ /* Set the read-only flag */ ++ if (loop_args.read_only) + flags |= MS_RDONLY; + } + } + ++ /* End of loop device code and start of NFS code */ ++ + if (!fake && type && streq (type, "nfs")) { + #ifdef HAVE_NFS + mnt_err = nfsmount (spec, node, &flags, &extra_opts, &mount_opts, bg); +@@ -732,9 +779,9 @@ + /* Mount succeeded, report this (if verbose) and write mtab entry. */ + { + if (loop) +- opt_loopdev = loopdev; ++ opt_loop_device = loop_args.device; + +- mcn.mnt_fsname = mnt.mnt_fsname = canonicalize (loop ? loopfile : spec); ++ mcn.mnt_fsname = mnt.mnt_fsname = canonicalize (loop ? loop_args.file : spec); + mcn.mnt_dir = mnt.mnt_dir = canonicalize (node); + mcn.mnt_type = mnt.mnt_type = type ? type : "unknown"; + mcn.mnt_opts = mnt.mnt_opts = fix_opts_string (flags & ~MS_NOMTAB, extra_opts); +@@ -771,7 +818,7 @@ + mnt_err = errno; + + if (loop) +- del_loop(spec); ++ loop_detach(spec); + + block_signals (SIG_UNBLOCK); + +diff --unified --recursive --new-file mount-2.7l.orig/nfs_mountversion.h mount-2.7l/nfs_mountversion.h +--- mount-2.7l.orig/nfs_mountversion.h Wed Dec 31 19:00:00 1969 ++++ mount-2.7l/nfs_mountversion.h Sat Apr 11 15:42:14 1998 +@@ -0,0 +1 @@ ++#define KERNEL_NFS_MOUNT_VERSION 3 +diff --unified --recursive --new-file mount-2.7l.orig/rmd160.c mount-2.7l/rmd160.c +--- mount-2.7l.orig/rmd160.c Wed Dec 31 19:00:00 1969 ++++ mount-2.7l/rmd160.c Sat Apr 11 15:42:14 1998 +@@ -0,0 +1,285 @@ ++/********************************************************************\ ++ * FILE: rmd160.c ++ * CONTENTS: A sample C-implementation of the RIPEMD-160 hash-function. ++ * TARGET: any computer with an ANSI C compiler ++ * AUTHOR: Antoon Bosselaers, Dept. Electrical Eng.-ESAT/COSIC ++ * DATE: 1 March 1996 VERSION: 1.0 ++ ********************************************************************** ++ * Copyright (c) Katholieke Universiteit Leuven 1996, All Rights Reserved ++ * The Katholieke Universiteit Leuven makes no representations concerning ++ * either the merchantability of this software or the suitability of this ++ * software for any particular purpose. It is provided "as is" without ++ * express or implied warranty of any kind. These notices must be retained ++ * in any copies of any part of this documentation and/or software. ++\********************************************************************/ ++ ++/* header files */ ++#include ++#include ++#include ++#include "rmd160.h" ++ ++/********************************************************************/ ++void MDinit(word *MDbuf) ++/* Initialization of the 5-word MDbuf array to the magic ++ initialization constants ++ */ ++{ ++ MDbuf[0] = 0x67452301UL; ++ MDbuf[1] = 0xefcdab89UL; ++ MDbuf[2] = 0x98badcfeUL; ++ MDbuf[3] = 0x10325476UL; ++ MDbuf[4] = 0xc3d2e1f0UL; ++} ++ ++/********************************************************************/ ++void MDcompress(word *MDbuf, word *X) ++/* The compression function is called for every complete 64-byte ++ message block. The 5-word internal state MDbuf is updated using ++ message words X[0] through X[15]. The conversion from a string ++ of 64 bytes to an array of 16 words using a Little-endian ++ convention is the responsibility of the calling function. ++*/ ++{ ++ /* make two copies of the old state */ ++ word aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2], ++ dd = MDbuf[3], ee = MDbuf[4]; ++ word aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2], ++ ddd = MDbuf[3], eee = MDbuf[4]; ++ ++ /* round 1 */ ++ T1(aa, bb, cc, dd, ee, X[ 0], 11); ++ T1(ee, aa, bb, cc, dd, X[ 1], 14); ++ T1(dd, ee, aa, bb, cc, X[ 2], 15); ++ T1(cc, dd, ee, aa, bb, X[ 3], 12); ++ T1(bb, cc, dd, ee, aa, X[ 4], 5); ++ T1(aa, bb, cc, dd, ee, X[ 5], 8); ++ T1(ee, aa, bb, cc, dd, X[ 6], 7); ++ T1(dd, ee, aa, bb, cc, X[ 7], 9); ++ T1(cc, dd, ee, aa, bb, X[ 8], 11); ++ T1(bb, cc, dd, ee, aa, X[ 9], 13); ++ T1(aa, bb, cc, dd, ee, X[10], 14); ++ T1(ee, aa, bb, cc, dd, X[11], 15); ++ T1(dd, ee, aa, bb, cc, X[12], 6); ++ T1(cc, dd, ee, aa, bb, X[13], 7); ++ T1(bb, cc, dd, ee, aa, X[14], 9); ++ T1(aa, bb, cc, dd, ee, X[15], 8); ++ ++ /* round 2 */ ++ T2(ee, aa, bb, cc, dd, X[ 7], 7); ++ T2(dd, ee, aa, bb, cc, X[ 4], 6); ++ T2(cc, dd, ee, aa, bb, X[13], 8); ++ T2(bb, cc, dd, ee, aa, X[ 1], 13); ++ T2(aa, bb, cc, dd, ee, X[10], 11); ++ T2(ee, aa, bb, cc, dd, X[ 6], 9); ++ T2(dd, ee, aa, bb, cc, X[15], 7); ++ T2(cc, dd, ee, aa, bb, X[ 3], 15); ++ T2(bb, cc, dd, ee, aa, X[12], 7); ++ T2(aa, bb, cc, dd, ee, X[ 0], 12); ++ T2(ee, aa, bb, cc, dd, X[ 9], 15); ++ T2(dd, ee, aa, bb, cc, X[ 5], 9); ++ T2(cc, dd, ee, aa, bb, X[ 2], 11); ++ T2(bb, cc, dd, ee, aa, X[14], 7); ++ T2(aa, bb, cc, dd, ee, X[11], 13); ++ T2(ee, aa, bb, cc, dd, X[ 8], 12); ++ ++ /* round 3 */ ++ T3(dd, ee, aa, bb, cc, X[ 3], 11); ++ T3(cc, dd, ee, aa, bb, X[10], 13); ++ T3(bb, cc, dd, ee, aa, X[14], 6); ++ T3(aa, bb, cc, dd, ee, X[ 4], 7); ++ T3(ee, aa, bb, cc, dd, X[ 9], 14); ++ T3(dd, ee, aa, bb, cc, X[15], 9); ++ T3(cc, dd, ee, aa, bb, X[ 8], 13); ++ T3(bb, cc, dd, ee, aa, X[ 1], 15); ++ T3(aa, bb, cc, dd, ee, X[ 2], 14); ++ T3(ee, aa, bb, cc, dd, X[ 7], 8); ++ T3(dd, ee, aa, bb, cc, X[ 0], 13); ++ T3(cc, dd, ee, aa, bb, X[ 6], 6); ++ T3(bb, cc, dd, ee, aa, X[13], 5); ++ T3(aa, bb, cc, dd, ee, X[11], 12); ++ T3(ee, aa, bb, cc, dd, X[ 5], 7); ++ T3(dd, ee, aa, bb, cc, X[12], 5); ++ ++ /* round 4 */ ++ T4(cc, dd, ee, aa, bb, X[ 1], 11); ++ T4(bb, cc, dd, ee, aa, X[ 9], 12); ++ T4(aa, bb, cc, dd, ee, X[11], 14); ++ T4(ee, aa, bb, cc, dd, X[10], 15); ++ T4(dd, ee, aa, bb, cc, X[ 0], 14); ++ T4(cc, dd, ee, aa, bb, X[ 8], 15); ++ T4(bb, cc, dd, ee, aa, X[12], 9); ++ T4(aa, bb, cc, dd, ee, X[ 4], 8); ++ T4(ee, aa, bb, cc, dd, X[13], 9); ++ T4(dd, ee, aa, bb, cc, X[ 3], 14); ++ T4(cc, dd, ee, aa, bb, X[ 7], 5); ++ T4(bb, cc, dd, ee, aa, X[15], 6); ++ T4(aa, bb, cc, dd, ee, X[14], 8); ++ T4(ee, aa, bb, cc, dd, X[ 5], 6); ++ T4(dd, ee, aa, bb, cc, X[ 6], 5); ++ T4(cc, dd, ee, aa, bb, X[ 2], 12); ++ ++ /* round 5 */ ++ T5(bb, cc, dd, ee, aa, X[ 4], 9); ++ T5(aa, bb, cc, dd, ee, X[ 0], 15); ++ T5(ee, aa, bb, cc, dd, X[ 5], 5); ++ T5(dd, ee, aa, bb, cc, X[ 9], 11); ++ T5(cc, dd, ee, aa, bb, X[ 7], 6); ++ T5(bb, cc, dd, ee, aa, X[12], 8); ++ T5(aa, bb, cc, dd, ee, X[ 2], 13); ++ T5(ee, aa, bb, cc, dd, X[10], 12); ++ T5(dd, ee, aa, bb, cc, X[14], 5); ++ T5(cc, dd, ee, aa, bb, X[ 1], 12); ++ T5(bb, cc, dd, ee, aa, X[ 3], 13); ++ T5(aa, bb, cc, dd, ee, X[ 8], 14); ++ T5(ee, aa, bb, cc, dd, X[11], 11); ++ T5(dd, ee, aa, bb, cc, X[ 6], 8); ++ T5(cc, dd, ee, aa, bb, X[15], 5); ++ T5(bb, cc, dd, ee, aa, X[13], 6); ++ ++ /* parallel round 1 */ ++ TT5(aaa, bbb, ccc, ddd, eee, X[ 5], 8); ++ TT5(eee, aaa, bbb, ccc, ddd, X[14], 9); ++ TT5(ddd, eee, aaa, bbb, ccc, X[ 7], 9); ++ TT5(ccc, ddd, eee, aaa, bbb, X[ 0], 11); ++ TT5(bbb, ccc, ddd, eee, aaa, X[ 9], 13); ++ TT5(aaa, bbb, ccc, ddd, eee, X[ 2], 15); ++ TT5(eee, aaa, bbb, ccc, ddd, X[11], 15); ++ TT5(ddd, eee, aaa, bbb, ccc, X[ 4], 5); ++ TT5(ccc, ddd, eee, aaa, bbb, X[13], 7); ++ TT5(bbb, ccc, ddd, eee, aaa, X[ 6], 7); ++ TT5(aaa, bbb, ccc, ddd, eee, X[15], 8); ++ TT5(eee, aaa, bbb, ccc, ddd, X[ 8], 11); ++ TT5(ddd, eee, aaa, bbb, ccc, X[ 1], 14); ++ TT5(ccc, ddd, eee, aaa, bbb, X[10], 14); ++ TT5(bbb, ccc, ddd, eee, aaa, X[ 3], 12); ++ TT5(aaa, bbb, ccc, ddd, eee, X[12], 6); ++ ++ /* parallel round 2 */ ++ TT4(eee, aaa, bbb, ccc, ddd, X[ 6], 9); ++ TT4(ddd, eee, aaa, bbb, ccc, X[11], 13); ++ TT4(ccc, ddd, eee, aaa, bbb, X[ 3], 15); ++ TT4(bbb, ccc, ddd, eee, aaa, X[ 7], 7); ++ TT4(aaa, bbb, ccc, ddd, eee, X[ 0], 12); ++ TT4(eee, aaa, bbb, ccc, ddd, X[13], 8); ++ TT4(ddd, eee, aaa, bbb, ccc, X[ 5], 9); ++ TT4(ccc, ddd, eee, aaa, bbb, X[10], 11); ++ TT4(bbb, ccc, ddd, eee, aaa, X[14], 7); ++ TT4(aaa, bbb, ccc, ddd, eee, X[15], 7); ++ TT4(eee, aaa, bbb, ccc, ddd, X[ 8], 12); ++ TT4(ddd, eee, aaa, bbb, ccc, X[12], 7); ++ TT4(ccc, ddd, eee, aaa, bbb, X[ 4], 6); ++ TT4(bbb, ccc, ddd, eee, aaa, X[ 9], 15); ++ TT4(aaa, bbb, ccc, ddd, eee, X[ 1], 13); ++ TT4(eee, aaa, bbb, ccc, ddd, X[ 2], 11); ++ ++ /* parallel round 3 */ ++ TT3(ddd, eee, aaa, bbb, ccc, X[15], 9); ++ TT3(ccc, ddd, eee, aaa, bbb, X[ 5], 7); ++ TT3(bbb, ccc, ddd, eee, aaa, X[ 1], 15); ++ TT3(aaa, bbb, ccc, ddd, eee, X[ 3], 11); ++ TT3(eee, aaa, bbb, ccc, ddd, X[ 7], 8); ++ TT3(ddd, eee, aaa, bbb, ccc, X[14], 6); ++ TT3(ccc, ddd, eee, aaa, bbb, X[ 6], 6); ++ TT3(bbb, ccc, ddd, eee, aaa, X[ 9], 14); ++ TT3(aaa, bbb, ccc, ddd, eee, X[11], 12); ++ TT3(eee, aaa, bbb, ccc, ddd, X[ 8], 13); ++ TT3(ddd, eee, aaa, bbb, ccc, X[12], 5); ++ TT3(ccc, ddd, eee, aaa, bbb, X[ 2], 14); ++ TT3(bbb, ccc, ddd, eee, aaa, X[10], 13); ++ TT3(aaa, bbb, ccc, ddd, eee, X[ 0], 13); ++ TT3(eee, aaa, bbb, ccc, ddd, X[ 4], 7); ++ TT3(ddd, eee, aaa, bbb, ccc, X[13], 5); ++ ++ /* parallel round 4 */ ++ TT2(ccc, ddd, eee, aaa, bbb, X[ 8], 15); ++ TT2(bbb, ccc, ddd, eee, aaa, X[ 6], 5); ++ TT2(aaa, bbb, ccc, ddd, eee, X[ 4], 8); ++ TT2(eee, aaa, bbb, ccc, ddd, X[ 1], 11); ++ TT2(ddd, eee, aaa, bbb, ccc, X[ 3], 14); ++ TT2(ccc, ddd, eee, aaa, bbb, X[11], 14); ++ TT2(bbb, ccc, ddd, eee, aaa, X[15], 6); ++ TT2(aaa, bbb, ccc, ddd, eee, X[ 0], 14); ++ TT2(eee, aaa, bbb, ccc, ddd, X[ 5], 6); ++ TT2(ddd, eee, aaa, bbb, ccc, X[12], 9); ++ TT2(ccc, ddd, eee, aaa, bbb, X[ 2], 12); ++ TT2(bbb, ccc, ddd, eee, aaa, X[13], 9); ++ TT2(aaa, bbb, ccc, ddd, eee, X[ 9], 12); ++ TT2(eee, aaa, bbb, ccc, ddd, X[ 7], 5); ++ TT2(ddd, eee, aaa, bbb, ccc, X[10], 15); ++ TT2(ccc, ddd, eee, aaa, bbb, X[14], 8); ++ ++ /* parallel round 5 */ ++ TT1(bbb, ccc, ddd, eee, aaa, X[12] , 8); ++ TT1(aaa, bbb, ccc, ddd, eee, X[15] , 5); ++ TT1(eee, aaa, bbb, ccc, ddd, X[10] , 12); ++ TT1(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); ++ TT1(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); ++ TT1(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); ++ TT1(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); ++ TT1(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); ++ TT1(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); ++ TT1(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); ++ TT1(bbb, ccc, ddd, eee, aaa, X[13] , 6); ++ TT1(aaa, bbb, ccc, ddd, eee, X[14] , 5); ++ TT1(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); ++ TT1(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); ++ TT1(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); ++ TT1(bbb, ccc, ddd, eee, aaa, X[11] , 11); ++ ++ /* combine results into new state */ ++ ddd += cc + MDbuf[1]; ++ MDbuf[1] = MDbuf[2] + dd + eee; ++ MDbuf[2] = MDbuf[3] + ee + aaa; ++ MDbuf[3] = MDbuf[4] + aa + bbb; ++ MDbuf[4] = MDbuf[0] + bb + ccc; ++ MDbuf[0] = ddd; ++} ++ ++/********************************************************************/ ++void MDfinish(word *MDbuf, byte *string, word lswlen, word mswlen) ++/* The final value of the 5-word MDbuf array is calculated. ++ lswlen and mswlen contain, respectively, the least and most significant ++ 32 bits of the message bit length mod 2^64, and string is an incomplete ++ block containing the (lswlen mod 512) remaining message bits. ++ (In case the message is already a multiple of 512 bits, string ++ is not used.) The conversion of the 5-word final state MDbuf to ++ the 20-byte hash result using a Little-endian convention is the ++ responsibility of the calling function. ++*/ ++{ ++ size_t i, length; ++ byte mask; ++ word X[16]; ++ ++ /* clear 16-word message block */ ++ memset(X, 0, 16*sizeof(word)); ++ ++ /* copy (lswlen mod 512) bits from string into X */ ++ length = ((lswlen&511)+7)/8; /* number of bytes */ ++ mask = (lswlen&7) ? ((byte)1 << (lswlen&7)) - 1 : 0xff; ++ for (i=0; i>2] ^= (word) (*string&mask) << (8*(i&3)); ++ else ++ X[i>>2] ^= (word) *string++ << (8*(i&3)); ++ } ++ ++ /* append a single 1 */ ++ X[(lswlen>>5)&15] ^= (word)1 << (8*((lswlen>>3)&3)+7-(lswlen&7)); ++ ++ if ((lswlen & 511) > 447) { ++ /* length doesn't fit in this block anymore. ++ Compress, and put length in the next block */ ++ MDcompress(MDbuf, X); ++ memset(X, 0, 16*sizeof(word)); ++ } ++ /* append length in bits*/ ++ X[14] = lswlen; ++ X[15] = mswlen; ++ MDcompress(MDbuf, X); ++} ++ ++/************************ end of file rmd160.c **********************/ ++ +diff --unified --recursive --new-file mount-2.7l.orig/rmd160.h mount-2.7l/rmd160.h +--- mount-2.7l.orig/rmd160.h Wed Dec 31 19:00:00 1969 ++++ mount-2.7l/rmd160.h Sat Apr 11 15:42:14 1998 +@@ -0,0 +1,98 @@ ++/********************************************************************\ ++ * FILE: rmd160.h ++ * CONTENTS: Header file for a sample C-implementation of the ++ * RIPEMD-160 hash-function. ++ * AUTHOR: Antoon Bosselaers, Dept. Electrical Eng.-ESAT/COSIC ++ * DATE: 1 March 1996 VERSION: 1.0 ++\********************************************************************/ ++ ++#ifndef RMD160H /* make sure this file is read only once */ ++#define RMD160H ++ ++/********************************************************************/ ++/* Type definitions of an 8 and a 32-bit integer type, respectively. ++ Adapt these, if necessary, for your operating system and compiler ++*/ ++typedef unsigned char byte; /* unsigned 8-bit integer */ ++typedef unsigned long word; /* unsigned 32-bit integer */ ++ ++/********************************************************************/ ++/* Macro definitions */ ++ ++/* ROL(x, n) cyclically rotates x over n bits to the left ++ x must be of an unsigned 32 bits type and 0 <= n < 32. ++*/ ++#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n)))) ++ ++/* The five basic RIPEMD-160 functions F1(), F2(), F3(), F4(), and F5() ++*/ ++#define F1(x, y, z) ((x) ^ (y) ^ (z)) ++#define F2(x, y, z) (((x) & (y)) | (~(x) & (z))) ++#define F3(x, y, z) (((x) | ~(y)) ^ (z)) ++#define F4(x, y, z) (((x) & (z)) | ((y) & ~(z))) ++#define F5(x, y, z) ((x) ^ ((y) | ~(z))) ++ ++/* The ten basic RIPEMD-160 transformations T1() through TT5() ++*/ ++#define T1(a, b, c, d, e, x, s) {\ ++ (a) += F1((b), (c), (d)) + (x);\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define T2(a, b, c, d, e, x, s) {\ ++ (a) += F2((b), (c), (d)) + (x) + 0x5a827999UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define T3(a, b, c, d, e, x, s) {\ ++ (a) += F3((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define T4(a, b, c, d, e, x, s) {\ ++ (a) += F4((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define T5(a, b, c, d, e, x, s) {\ ++ (a) += F5((b), (c), (d)) + (x) + 0xa953fd4eUL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define TT1(a, b, c, d, e, x, s) {\ ++ (a) += F1((b), (c), (d)) + (x);\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define TT2(a, b, c, d, e, x, s) {\ ++ (a) += F2((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define TT3(a, b, c, d, e, x, s) {\ ++ (a) += F3((b), (c), (d)) + (x) + 0x6d703ef3UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define TT4(a, b, c, d, e, x, s) {\ ++ (a) += F4((b), (c), (d)) + (x) + 0x5c4dd124UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define TT5(a, b, c, d, e, x, s) {\ ++ (a) += F5((b), (c), (d)) + (x) + 0x50a28be6UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++ ++/********************************************************************/ ++/* Function prototypes */ ++ ++void MDinit(word *MDbuf); ++void MDcompress(word *MDbuf, word *X); ++void MDfinish(word *MDbuf, byte *string, word lswlen, word mswlen); ++ ++#endif /* RMD160H */ ++ ++/*********************** end of file rmd160.h ***********************/ ++ +diff --unified --recursive --new-file mount-2.7l.orig/swap.h mount-2.7l/swap.h +--- mount-2.7l.orig/swap.h Wed Dec 31 19:00:00 1969 ++++ mount-2.7l/swap.h Sat Apr 11 15:42:14 1998 +@@ -0,0 +1,139 @@ ++#ifndef _LINUX_SWAP_H ++#define _LINUX_SWAP_H ++ ++#define SWAP_FLAG_PREFER 0x8000 /* set if swap priority specified */ ++#define SWAP_FLAG_PRIO_MASK 0x7fff ++#define SWAP_FLAG_PRIO_SHIFT 0 ++ ++#define MAX_SWAPFILES 8 ++ ++#ifdef __KERNEL__ ++ ++#include ++ ++#define SWP_USED 1 ++#define SWP_WRITEOK 3 ++ ++#define SWAP_CLUSTER_MAX 32 ++ ++struct swap_info_struct { ++ unsigned int flags; ++ kdev_t swap_device; ++ struct dentry * swap_file; ++ unsigned char * swap_map; ++ unsigned char * swap_lockmap; ++ unsigned int lowest_bit; ++ unsigned int highest_bit; ++ unsigned int cluster_next; ++ unsigned int cluster_nr; ++ int prio; /* swap priority */ ++ int pages; ++ unsigned long max; ++ int next; /* next entry on swap list */ ++}; ++ ++extern int nr_swap_pages; ++extern int nr_free_pages; ++extern atomic_t nr_async_pages; ++extern int min_free_pages; ++extern int free_pages_low; ++extern int free_pages_high; ++ ++/* Incomplete types for prototype declarations: */ ++struct task_struct; ++struct vm_area_struct; ++struct sysinfo; ++ ++/* linux/ipc/shm.c */ ++extern int shm_swap (int, int); ++ ++/* linux/mm/vmscan.c */ ++extern int try_to_free_page(int, int, int); ++ ++/* linux/mm/page_io.c */ ++extern void rw_swap_page(int, unsigned long, char *, int); ++#define read_swap_page(nr,buf) \ ++ rw_swap_page(READ,(nr),(buf),1) ++#define write_swap_page(nr,buf) \ ++ rw_swap_page(WRITE,(nr),(buf),1) ++extern void swap_after_unlock_page (unsigned long entry); ++ ++/* linux/mm/page_alloc.c */ ++extern void swap_in(struct task_struct *, struct vm_area_struct *, ++ pte_t *, unsigned long, int); ++ ++ ++/* linux/mm/swap_state.c */ ++extern void show_swap_cache_info(void); ++extern int add_to_swap_cache(struct page *, unsigned long); ++extern void swap_duplicate(unsigned long); ++ ++/* linux/mm/swapfile.c */ ++extern unsigned int nr_swapfiles; ++extern struct swap_info_struct swap_info[]; ++void si_swapinfo(struct sysinfo *); ++unsigned long get_swap_page(void); ++extern void swap_free(unsigned long); ++ ++/* ++ * vm_ops not present page codes for shared memory. ++ * ++ * Will go away eventually.. ++ */ ++#define SHM_SWP_TYPE 0x40 ++ ++/* ++ * swap cache stuff (in linux/mm/swap_state.c) ++ */ ++ ++#define SWAP_CACHE_INFO ++ ++#ifdef SWAP_CACHE_INFO ++extern unsigned long swap_cache_add_total; ++extern unsigned long swap_cache_add_success; ++extern unsigned long swap_cache_del_total; ++extern unsigned long swap_cache_del_success; ++extern unsigned long swap_cache_find_total; ++extern unsigned long swap_cache_find_success; ++#endif ++ ++extern inline unsigned long in_swap_cache(struct page *page) ++{ ++ if (PageSwapCache(page)) ++ return page->pg_swap_entry; ++ return 0; ++} ++ ++extern inline long find_in_swap_cache(struct page *page) ++{ ++#ifdef SWAP_CACHE_INFO ++ swap_cache_find_total++; ++#endif ++ if (PageTestandClearSwapCache(page)) { ++#ifdef SWAP_CACHE_INFO ++ swap_cache_find_success++; ++#endif ++ return page->pg_swap_entry; ++ } ++ return 0; ++} ++ ++extern inline int delete_from_swap_cache(struct page *page) ++{ ++#ifdef SWAP_CACHE_INFO ++ swap_cache_del_total++; ++#endif ++ if (PageTestandClearSwapCache(page)) { ++#ifdef SWAP_CACHE_INFO ++ swap_cache_del_success++; ++#endif ++ swap_free(page->pg_swap_entry); ++ return 1; ++ } ++ return 0; ++} ++ ++ ++#endif /* __KERNEL__*/ ++ ++#endif /* _LINUX_SWAP_H */ +diff --unified --recursive --new-file mount-2.7l.orig/umount.c mount-2.7l/umount.c +--- mount-2.7l.orig/umount.c Thu Aug 7 01:05:30 1997 ++++ mount-2.7l/umount.c Sun Apr 19 16:46:09 1998 +@@ -24,13 +24,16 @@ + #include + #include + #include ++#define __KERNEL__ ++#include ++#undef __KERNEL__ + #include + #include ++#include "fstab.h" ++#include "loop.h" ++#include "losetup.h" + #include "mount_constants.h" + #include "sundries.h" +-#include "lomount.h" +-#include "loop.h" +-#include "fstab.h" + + #ifdef HAVE_NFS + #include +@@ -241,21 +244,21 @@ + + /* old style mtab line? */ + if (streq(mc->mnt_type, "loop")) +- if (del_loop(spec)) ++ if (loop_detach(spec)) + goto fail; + + /* new style mtab line? */ + opts = mc->mnt_opts ? xstrdup(mc->mnt_opts) : ""; + for (opts = strtok (opts, ","); opts; opts = strtok (NULL, ",")) { + if (!strncmp(opts, "loop=", 5)) { +- if (del_loop(opts+5)) ++ if (loop_detach(opts+5)) + goto fail; + break; + } + } + } else { + /* maybe spec is a loop device? */ +- /* no del_loop() - just delete it from mtab */ ++ /* no loop_detach() - just delete it from mtab */ + if ((mc = getmntoptfile (spec)) != NULL) + node = mc->mnt_dir; + } +@@ -267,7 +270,7 @@ + } + + fail: +- /* Umount or del_loop failed, complain, but don't die. */ ++ /* Umount or loop_detach failed, complain, but don't die. */ + if (!nomtab) { + /* remove obsolete entry */ + if (umnt_err == EINVAL || umnt_err == ENOENT) diff -ruN linux-2.2.5,pristine/Documentation/crypto/modules.txt linux-2.2.5/Documentation/crypto/modules.txt --- linux-2.2.5,pristine/Documentation/crypto/modules.txt Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/Documentation/crypto/modules.txt Thu Apr 1 23:05:44 1999 @@ -0,0 +1,56 @@ +This is documentation for crypto modules and loop modules +By Patrice Lacroix +(1998-12-15) + +What is the crypto API? + +It allow the rest of the kernel to use crypto in a generic way, +notably the loop device driver (via loop_gen). + + +What is loop_gen? + +It's the generic encryption loop driver. It uses the crypto API to +do encryption. It works with every ciphers that support the crypto API. +Not all ciphers in the crypto library support the API yet. + +loop_gen (and the crypto api) will ultimatly replace all other loop +encryption modules. + +loop_gen use all supported ciphers in CBC mode. + + +What can I do with loop_gen? + +The loop device driver allow you to use a file as a block device. +With loop_gen, data in the file associated with the loop block device +can be encrypted with strong crypto. + +You can use this as any other block device. If you create a file +system and mount it, then every file in the file system will be +automaticly encrypted. + + +Can I use all this as modules? + +Sure! In make menuconfig (or whatever), under Crypto options, say M to +Crypto ciphers and to the ciphers you want. Under block Device, say M to +loopback device and to General Encryption Support. Don't select any other +encryption modules unless you can't live without them and they are +not suported by the crypto API. + +Build your kernel and modules, make modules_install, reboot, depmod -a + +In /etc/conf.modules, add: + +alias loop-xfer-gen-0 loop_gen +alias loop-xfer-gen-10 loop_gen +alias cipher-7 serp6f +alias cipher-8 mars6 +alias cipher-11 rc62 +alias cipher-15 dfc2 + + +Can I stack loop devices and encryption? + +Yes! diff -ruN linux-2.2.5,pristine/Documentation/crypto/util-linux-2.9e.patch linux-2.2.5/Documentation/crypto/util-linux-2.9e.patch --- linux-2.2.5,pristine/Documentation/crypto/util-linux-2.9e.patch Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/Documentation/crypto/util-linux-2.9e.patch Thu Apr 1 23:05:44 1999 @@ -0,0 +1,598 @@ +diff -urN util-linux-2.9e/mount/Makefile util-linux-2.9e.new/mount/Makefile +--- util-linux-2.9e/mount/Makefile Sat Oct 17 14:25:29 1998 ++++ util-linux-2.9e.new/mount/Makefile Mon Dec 14 01:15:00 1998 +@@ -37,7 +37,7 @@ + GEN_FILES = nfsmount.x nfsmount.h nfsmount_xdr.c nfsmount_clnt.c + + # comment these out if you are not compiling in loop support +-LO_OBJS=lomount.o ++LO_OBJS=lomount.o rmd160.o + + all: $(PROGS) + +@@ -64,7 +64,7 @@ + swapon: swapon.o version.o + $(LINK) $^ -o $@ + +-losetup: losetup.o ++losetup: losetup.o rmd160.o + $(LINK) $^ -o $@ + + mount.o umount.o nfsmount.o losetup.o fstab.o sundries.o: sundries.h +diff -urN util-linux-2.9e/mount/Makefile.standalone util-linux-2.9e.new/mount/Makefile.standalone +--- util-linux-2.9e/mount/Makefile.standalone Wed Oct 14 23:45:19 1998 ++++ util-linux-2.9e.new/mount/Makefile.standalone Mon Dec 14 01:11:07 1998 +@@ -52,7 +52,7 @@ + GEN_FILES = nfsmount.x nfsmount.h nfsmount_xdr.c nfsmount_clnt.c + + # comment these out if you are not compiling in loop support +-LO_OBJS=lomount.o ++LO_OBJS=lomount.o rmd160.o + + all: $(PROGS) + +diff -urN util-linux-2.9e/mount/lomount.c util-linux-2.9e.new/mount/lomount.c +--- util-linux-2.9e/mount/lomount.c Sun Jun 7 23:19:03 1998 ++++ util-linux-2.9e.new/mount/lomount.c Mon Dec 14 01:14:57 1998 +@@ -20,6 +20,7 @@ + + #include "loop.h" + #include "lomount.h" ++#include "rmd160.h" + + char *xstrdup (const char *s); /* not: #include "sundries.h" */ + void error (const char *fmt, ...); /* idem */ +@@ -33,6 +34,14 @@ + { LO_CRYPT_NONE, "none" }, + { LO_CRYPT_XOR, "xor" }, + { LO_CRYPT_DES, "DES" }, ++ { LO_CRYPT_FISH2, "twofish" }, ++ { LO_CRYPT_BLOW, "blowfish"}, ++ { LO_CRYPT_CAST128, "cast128"}, ++ { LO_CRYPT_SERPENT, "serpent"}, ++ { LO_CRYPT_MARS, "mars" }, ++ { LO_CRYPT_RC6, "rc6" }, ++ { LO_CRYPT_DFC, "dfc" }, ++ { LO_CRYPT_IDEA, "idea"}, + { -1, NULL } + }; + +@@ -209,6 +218,24 @@ + return 1; + } + break; ++ case LO_CRYPT_FISH2: ++ case LO_CRYPT_BLOW: ++ pass = getpass("Password :"); ++ MDcalc((byte *)loopinfo.lo_encrypt_key,pass,strlen(pass)); ++ loopinfo.lo_encrypt_key_size=20; /* 160 Bit key */ ++ break; ++ ++ case LO_CRYPT_IDEA: ++ case LO_CRYPT_CAST128: ++ case LO_CRYPT_SERPENT: ++ case LO_CRYPT_MARS: ++ case LO_CRYPT_RC6: ++ case LO_CRYPT_DFC: ++ pass = getpass("Password :"); ++ MDcalc((byte *)loopinfo.lo_encrypt_key,pass,strlen(pass)); ++ loopinfo.lo_encrypt_key_size=16; /* 128 Bit key */ ++ break; ++ + default: + fprintf (stderr, + "Don't know how to get key for encryption system %d\n", +diff -urN util-linux-2.9e/mount/losetup.c util-linux-2.9e.new/mount/losetup.c +--- util-linux-2.9e/mount/losetup.c Sun Oct 11 19:19:22 1998 ++++ util-linux-2.9e.new/mount/losetup.c Mon Dec 14 01:19:54 1998 +@@ -13,6 +13,7 @@ + + #include "loop.h" + #include "lomount.h" ++#include "rmd160.h" + + #ifdef LOOP_SET_FD + +@@ -26,6 +27,14 @@ + { LO_CRYPT_NONE,"none" }, + { LO_CRYPT_XOR, "xor" }, + { LO_CRYPT_DES, "DES" }, ++ { LO_CRYPT_FISH2, "twofish" }, ++ { LO_CRYPT_BLOW, "blowfish" }, ++ { LO_CRYPT_CAST128, "cast128" }, ++ { LO_CRYPT_SERPENT, "serpent" }, ++ { LO_CRYPT_MARS, "mars" }, ++ { LO_CRYPT_RC6, "rc6" }, ++ { LO_CRYPT_DFC, "dfc" }, ++ { LO_CRYPT_IDEA, "idea" }, + { -1, NULL } + }; + +@@ -80,7 +89,7 @@ + struct loop_info loopinfo; + int fd, ffd, mode, i; + char *pass; +- ++ + mode = *loopro ? O_RDONLY : O_RDWR; + if ((ffd = open (file, mode)) < 0 && !*loopro + && (errno != EROFS || (ffd = open (file, mode = O_RDONLY)) < 0)) { +@@ -128,6 +137,22 @@ + exit(1); + } + break; ++ case LO_CRYPT_FISH2: ++ case LO_CRYPT_BLOW: ++ pass = getpass("Password :"); ++ MDcalc((byte *)loopinfo.lo_encrypt_key,pass,strlen(pass)); ++ loopinfo.lo_encrypt_key_size=20; /* 160 Bit key */ ++ break; ++ case LO_CRYPT_CAST128: ++ case LO_CRYPT_SERPENT: ++ case LO_CRYPT_MARS: ++ case LO_CRYPT_RC6: ++ case LO_CRYPT_DFC: ++ case LO_CRYPT_IDEA: ++ pass = getpass("Password :"); ++ MDcalc((byte *)loopinfo.lo_encrypt_key,pass,strlen(pass)); ++ loopinfo.lo_encrypt_key_size=16; /* 128 Bit key */ ++ break; + default: + fprintf(stderr, + "Don't know how to get key for encryption system %d\n", +@@ -166,11 +191,18 @@ + + static int usage(void) + { ++ struct crypt_type_struct *c; + fprintf(stderr, "usage:\n\ + %s loop_device # give info\n\ + %s -d loop_device # delete\n\ + %s [ -e encryption ] [ -o offset ] loop_device file # setup\n", + progname, progname, progname); ++ fprintf(stderr, " where encryption is one of:\n"); ++ c = &crypt_type_tbl[0]; ++ while(c->name) { ++ fprintf(stderr, " %s\n", c->name); ++ c++; ++ } + exit(1); + } + +diff -urN util-linux-2.9e/mount/rmd160.c util-linux-2.9e.new/mount/rmd160.c +--- util-linux-2.9e/mount/rmd160.c Thu Jan 1 01:00:00 1970 ++++ util-linux-2.9e.new/mount/rmd160.c Mon Dec 14 01:08:51 1998 +@@ -0,0 +1,371 @@ ++/********************************************************************\ ++ * ++ * FILE: rmd160.c ++ * ++ * CONTENTS: A sample C-implementation of the RIPEMD-160 ++ * hash-function. ++ * TARGET: any computer with an ANSI C compiler ++ * ++ * AUTHOR: Antoon Bosselaers, ESAT-COSIC ++ * DATE: 1 March 1996 ++ * VERSION: 1.0 ++ * ++ * Copyright (c) Katholieke Universiteit Leuven ++ * 1996, All Rights Reserved ++ * ++\********************************************************************/ ++ ++/* header files */ ++#include ++#include ++#include ++#include "rmd160.h" ++ ++/********************************************************************/ ++ ++/* macro definitions */ ++ ++/* collect four bytes into one word: */ ++#define BYTES_TO_DWORD(strptr) \ ++ (((dword) *((strptr)+3) << 24) | \ ++ ((dword) *((strptr)+2) << 16) | \ ++ ((dword) *((strptr)+1) << 8) | \ ++ ((dword) *(strptr))) ++ ++/* ROL(x, n) cyclically rotates x over n bits to the left */ ++/* x must be of an unsigned 32 bits type and 0 <= n < 32. */ ++#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n)))) ++ ++/* the five basic functions F(), G() and H() */ ++#define F(x, y, z) ((x) ^ (y) ^ (z)) ++#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) ++#define H(x, y, z) (((x) | ~(y)) ^ (z)) ++#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) ++#define J(x, y, z) ((x) ^ ((y) | ~(z))) ++ ++/* the ten basic operations FF() through III() */ ++#define FF(a, b, c, d, e, x, s) {\ ++ (a) += F((b), (c), (d)) + (x);\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define GG(a, b, c, d, e, x, s) {\ ++ (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define HH(a, b, c, d, e, x, s) {\ ++ (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define II(a, b, c, d, e, x, s) {\ ++ (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define JJ(a, b, c, d, e, x, s) {\ ++ (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define FFF(a, b, c, d, e, x, s) {\ ++ (a) += F((b), (c), (d)) + (x);\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define GGG(a, b, c, d, e, x, s) {\ ++ (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define HHH(a, b, c, d, e, x, s) {\ ++ (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define III(a, b, c, d, e, x, s) {\ ++ (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++#define JJJ(a, b, c, d, e, x, s) {\ ++ (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ ++ (a) = ROL((a), (s)) + (e);\ ++ (c) = ROL((c), 10);\ ++ } ++ ++ ++/********************************************************************/ ++ ++void MDinit(dword *MDbuf) ++{ ++ MDbuf[0] = 0x67452301UL; ++ MDbuf[1] = 0xefcdab89UL; ++ MDbuf[2] = 0x98badcfeUL; ++ MDbuf[3] = 0x10325476UL; ++ MDbuf[4] = 0xc3d2e1f0UL; ++ ++ return; ++} ++ ++/********************************************************************/ ++ ++void compress(dword *MDbuf, dword *X) ++{ ++ dword aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2], ++ dd = MDbuf[3], ee = MDbuf[4]; ++ dword aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2], ++ ddd = MDbuf[3], eee = MDbuf[4]; ++ ++ /* round 1 */ ++ FF(aa, bb, cc, dd, ee, X[ 0], 11); ++ FF(ee, aa, bb, cc, dd, X[ 1], 14); ++ FF(dd, ee, aa, bb, cc, X[ 2], 15); ++ FF(cc, dd, ee, aa, bb, X[ 3], 12); ++ FF(bb, cc, dd, ee, aa, X[ 4], 5); ++ FF(aa, bb, cc, dd, ee, X[ 5], 8); ++ FF(ee, aa, bb, cc, dd, X[ 6], 7); ++ FF(dd, ee, aa, bb, cc, X[ 7], 9); ++ FF(cc, dd, ee, aa, bb, X[ 8], 11); ++ FF(bb, cc, dd, ee, aa, X[ 9], 13); ++ FF(aa, bb, cc, dd, ee, X[10], 14); ++ FF(ee, aa, bb, cc, dd, X[11], 15); ++ FF(dd, ee, aa, bb, cc, X[12], 6); ++ FF(cc, dd, ee, aa, bb, X[13], 7); ++ FF(bb, cc, dd, ee, aa, X[14], 9); ++ FF(aa, bb, cc, dd, ee, X[15], 8); ++ ++ /* round 2 */ ++ GG(ee, aa, bb, cc, dd, X[ 7], 7); ++ GG(dd, ee, aa, bb, cc, X[ 4], 6); ++ GG(cc, dd, ee, aa, bb, X[13], 8); ++ GG(bb, cc, dd, ee, aa, X[ 1], 13); ++ GG(aa, bb, cc, dd, ee, X[10], 11); ++ GG(ee, aa, bb, cc, dd, X[ 6], 9); ++ GG(dd, ee, aa, bb, cc, X[15], 7); ++ GG(cc, dd, ee, aa, bb, X[ 3], 15); ++ GG(bb, cc, dd, ee, aa, X[12], 7); ++ GG(aa, bb, cc, dd, ee, X[ 0], 12); ++ GG(ee, aa, bb, cc, dd, X[ 9], 15); ++ GG(dd, ee, aa, bb, cc, X[ 5], 9); ++ GG(cc, dd, ee, aa, bb, X[ 2], 11); ++ GG(bb, cc, dd, ee, aa, X[14], 7); ++ GG(aa, bb, cc, dd, ee, X[11], 13); ++ GG(ee, aa, bb, cc, dd, X[ 8], 12); ++ ++ /* round 3 */ ++ HH(dd, ee, aa, bb, cc, X[ 3], 11); ++ HH(cc, dd, ee, aa, bb, X[10], 13); ++ HH(bb, cc, dd, ee, aa, X[14], 6); ++ HH(aa, bb, cc, dd, ee, X[ 4], 7); ++ HH(ee, aa, bb, cc, dd, X[ 9], 14); ++ HH(dd, ee, aa, bb, cc, X[15], 9); ++ HH(cc, dd, ee, aa, bb, X[ 8], 13); ++ HH(bb, cc, dd, ee, aa, X[ 1], 15); ++ HH(aa, bb, cc, dd, ee, X[ 2], 14); ++ HH(ee, aa, bb, cc, dd, X[ 7], 8); ++ HH(dd, ee, aa, bb, cc, X[ 0], 13); ++ HH(cc, dd, ee, aa, bb, X[ 6], 6); ++ HH(bb, cc, dd, ee, aa, X[13], 5); ++ HH(aa, bb, cc, dd, ee, X[11], 12); ++ HH(ee, aa, bb, cc, dd, X[ 5], 7); ++ HH(dd, ee, aa, bb, cc, X[12], 5); ++ ++ /* round 4 */ ++ II(cc, dd, ee, aa, bb, X[ 1], 11); ++ II(bb, cc, dd, ee, aa, X[ 9], 12); ++ II(aa, bb, cc, dd, ee, X[11], 14); ++ II(ee, aa, bb, cc, dd, X[10], 15); ++ II(dd, ee, aa, bb, cc, X[ 0], 14); ++ II(cc, dd, ee, aa, bb, X[ 8], 15); ++ II(bb, cc, dd, ee, aa, X[12], 9); ++ II(aa, bb, cc, dd, ee, X[ 4], 8); ++ II(ee, aa, bb, cc, dd, X[13], 9); ++ II(dd, ee, aa, bb, cc, X[ 3], 14); ++ II(cc, dd, ee, aa, bb, X[ 7], 5); ++ II(bb, cc, dd, ee, aa, X[15], 6); ++ II(aa, bb, cc, dd, ee, X[14], 8); ++ II(ee, aa, bb, cc, dd, X[ 5], 6); ++ II(dd, ee, aa, bb, cc, X[ 6], 5); ++ II(cc, dd, ee, aa, bb, X[ 2], 12); ++ ++ /* round 5 */ ++ JJ(bb, cc, dd, ee, aa, X[ 4], 9); ++ JJ(aa, bb, cc, dd, ee, X[ 0], 15); ++ JJ(ee, aa, bb, cc, dd, X[ 5], 5); ++ JJ(dd, ee, aa, bb, cc, X[ 9], 11); ++ JJ(cc, dd, ee, aa, bb, X[ 7], 6); ++ JJ(bb, cc, dd, ee, aa, X[12], 8); ++ JJ(aa, bb, cc, dd, ee, X[ 2], 13); ++ JJ(ee, aa, bb, cc, dd, X[10], 12); ++ JJ(dd, ee, aa, bb, cc, X[14], 5); ++ JJ(cc, dd, ee, aa, bb, X[ 1], 12); ++ JJ(bb, cc, dd, ee, aa, X[ 3], 13); ++ JJ(aa, bb, cc, dd, ee, X[ 8], 14); ++ JJ(ee, aa, bb, cc, dd, X[11], 11); ++ JJ(dd, ee, aa, bb, cc, X[ 6], 8); ++ JJ(cc, dd, ee, aa, bb, X[15], 5); ++ JJ(bb, cc, dd, ee, aa, X[13], 6); ++ ++ /* parallel round 1 */ ++ JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); ++ JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); ++ JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); ++ JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); ++ JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); ++ JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); ++ JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); ++ JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); ++ JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); ++ JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); ++ JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); ++ JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); ++ JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); ++ JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); ++ JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); ++ JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); ++ ++ /* parallel round 2 */ ++ III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); ++ III(ddd, eee, aaa, bbb, ccc, X[11], 13); ++ III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); ++ III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); ++ III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); ++ III(eee, aaa, bbb, ccc, ddd, X[13], 8); ++ III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); ++ III(ccc, ddd, eee, aaa, bbb, X[10], 11); ++ III(bbb, ccc, ddd, eee, aaa, X[14], 7); ++ III(aaa, bbb, ccc, ddd, eee, X[15], 7); ++ III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); ++ III(ddd, eee, aaa, bbb, ccc, X[12], 7); ++ III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); ++ III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); ++ III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); ++ III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); ++ ++ /* parallel round 3 */ ++ HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); ++ HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); ++ HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); ++ HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); ++ HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); ++ HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); ++ HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); ++ HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); ++ HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); ++ HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); ++ HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); ++ HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); ++ HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); ++ HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); ++ HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); ++ HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); ++ ++ /* parallel round 4 */ ++ GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); ++ GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); ++ GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); ++ GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); ++ GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); ++ GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); ++ GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); ++ GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); ++ GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); ++ GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); ++ GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); ++ GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); ++ GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); ++ GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); ++ GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); ++ GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); ++ ++ /* parallel round 5 */ ++ FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); ++ FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); ++ FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); ++ FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); ++ FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); ++ FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); ++ FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); ++ FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); ++ FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); ++ FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); ++ FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); ++ FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); ++ FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); ++ FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); ++ FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); ++ FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); ++ ++ /* combine results */ ++ ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */ ++ MDbuf[1] = MDbuf[2] + dd + eee; ++ MDbuf[2] = MDbuf[3] + ee + aaa; ++ MDbuf[3] = MDbuf[4] + aa + bbb; ++ MDbuf[4] = MDbuf[0] + bb + ccc; ++ MDbuf[0] = ddd; ++ ++ return; ++} ++ ++/********************************************************************/ ++ ++void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen) ++{ ++ unsigned int i; /* counter */ ++ dword X[16]; /* message words */ ++ ++ memset(X, 0, 16*sizeof(dword)); ++ ++ /* put bytes from strptr into X */ ++ for (i=0; i<(lswlen&63); i++) { ++ /* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */ ++ X[i>>2] ^= (dword) *strptr++ << (8 * (i&3)); ++ } ++ ++ /* append "1" bit to the message. Be careful : ++ message = "" -> "10000000" = 128 */ ++ X[(lswlen>>2)&15] ^= (dword)1 << (8*(lswlen&3)+7); ++ ++ if ((lswlen & 63) > 55) { ++ /* length goes to next block */ ++ compress(MDbuf, X); ++ memset(X, 0, 16*sizeof(dword)); ++ } ++ ++ /* append length in bits*/ ++ X[14] = lswlen << 3; ++ X[15] = (lswlen >> 29) | (mswlen << 3); ++ compress(MDbuf, X); ++ ++ return; ++} ++ ++void MDcalc(byte *MD,byte *sp,dword sl) ++{ dword X[16]; ++ dword MDbuf[5]; ++ int i,j; ++ ++ MDinit(MDbuf); ++ ++ while (sl >= 64) ++ { ++ memset(X,0,16*sizeof(dword)); ++ ++ for (i=0; i<64; i++) ++ X[i>>2] |= ((dword)(*sp++)) << (8 * (i&3)); ++ ++ sl-=64; ++ compress(MDbuf,X); ++ ++ }; ++ MDfinish(MDbuf,sp,sl,0); ++ ++ for (i=0;i<5;i++) ++ for (j=0;j<4;j++) ++ *MD++=(byte)((MDbuf[i]>>(j*8))&0xFF); ++} ++ ++/************************ end of file rmd160.c **********************/ ++ +diff -urN util-linux-2.9e/mount/rmd160.h util-linux-2.9e.new/mount/rmd160.h +--- util-linux-2.9e/mount/rmd160.h Thu Jan 1 01:00:00 1970 ++++ util-linux-2.9e.new/mount/rmd160.h Mon Dec 14 01:08:51 1998 +@@ -0,0 +1,58 @@ ++/********************************************************************\ ++ * ++ * FILE: rmd160.h ++ * ++ * CONTENTS: Header file for a sample C-implementation of the ++ * RIPEMD-160 hash-function. ++ * TARGET: any computer with an ANSI C compiler ++ * ++ * AUTHOR: Antoon Bosselaers, ESAT-COSIC ++ * DATE: 1 March 1996 ++ * VERSION: 1.0 ++ * ++ * Copyright (c) Katholieke Universiteit Leuven ++ * 1996, All Rights Reserved ++ * ++\********************************************************************/ ++ ++#ifndef RMD160H /* make sure this file is read only once */ ++#define RMD160H ++ ++/********************************************************************/ ++ ++/* typedef 8 and 32 bit types, resp. */ ++/* adapt these, if necessary, ++ for your operating system and compiler */ ++ ++typedef unsigned char byte; ++typedef unsigned long dword; ++ ++/********************************************************************/ ++ ++/* function prototypes */ ++ ++void MDinit(dword *MDbuf); ++/* ++ * initializes MDbuffer to "magic constants" ++ */ ++ ++void compress(dword *MDbuf, dword *X); ++/* ++ * the compression function. ++ * transforms MDbuf using message bytes X[0] through X[15] ++ */ ++ ++void MDfinish(dword *MDbuf, byte *strptr, dword lswlen, dword mswlen); ++/* ++ * puts bytes from strptr into X and pad out; appends length ++ * and finally, compresses the last block(s) ++ * note: length in bits == 8 * (lswlen + 2^32 mswlen). ++ * note: there are (lswlen mod 64) bytes left in strptr. ++ */ ++ ++void MDcalc(byte *MDbuf,byte *sp,dword sl); ++ ++#endif /* RMD160H */ ++ ++/*********************** end of file rmd160.h ***********************/ ++ diff -ruN linux-2.2.5,pristine/MAINTAINERS linux-2.2.5/MAINTAINERS --- linux-2.2.5,pristine/MAINTAINERS Mon Mar 22 20:18:17 1999 +++ linux-2.2.5/MAINTAINERS Thu Apr 1 23:05:45 1999 @@ -379,6 +379,13 @@ L: linux-kernel@vger.rutgers.edu S: Maintained +INTERNATIONAL KERNEL PATCH (CRYPTO) +P: Alexander Kjeldaas +M: astor@guardian.no +W: http://www.kerneli.org/ +L: linux-kernel@vger.rutgers.edu +S: Maintained + IP FIREWALL P: Paul Russell M: Paul.Russell@rustcorp.com.au diff -ruN linux-2.2.5,pristine/Makefile linux-2.2.5/Makefile --- linux-2.2.5,pristine/Makefile Tue Mar 23 23:48:17 1999 +++ linux-2.2.5/Makefile Thu Apr 1 23:05:45 1999 @@ -106,11 +106,12 @@ CORE_FILES =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o FILESYSTEMS =fs/filesystems.a NETWORKS =net/network.a -DRIVERS =drivers/block/block.a \ +DRIVERS =crypto/crypto.a \ + drivers/block/block.a \ drivers/char/char.a \ drivers/misc/misc.a LIBS =$(TOPDIR)/lib/lib.a -SUBDIRS =kernel drivers mm fs net ipc lib +SUBDIRS =kernel drivers mm fs net ipc lib crypto ifdef CONFIG_NUBUS DRIVERS := $(DRIVERS) drivers/nubus/nubus.a diff -ruN linux-2.2.5,pristine/arch/alpha/config.in linux-2.2.5/arch/alpha/config.in --- linux-2.2.5,pristine/arch/alpha/config.in Mon Feb 1 21:03:20 1999 +++ linux-2.2.5/arch/alpha/config.in Thu Apr 1 23:05:45 1999 @@ -210,6 +210,8 @@ source net/Config.in fi +source crypto/Config.in + mainmenu_option next_comment comment 'SCSI support' diff -ruN linux-2.2.5,pristine/arch/arm/config.in linux-2.2.5/arch/arm/config.in --- linux-2.2.5,pristine/arch/arm/config.in Thu Jan 14 19:29:28 1999 +++ linux-2.2.5/arch/arm/config.in Thu Apr 1 23:05:45 1999 @@ -168,6 +168,8 @@ source net/Config.in fi +source crypto/Config.in + if [ "$CONFIG_NET" = "y" ]; then mainmenu_option next_comment comment 'Network device support' diff -ruN linux-2.2.5,pristine/arch/i386/config.in linux-2.2.5/arch/i386/config.in --- linux-2.2.5,pristine/arch/i386/config.in Sat Mar 13 02:39:50 1999 +++ linux-2.2.5/arch/i386/config.in Thu Apr 1 23:05:45 1999 @@ -114,6 +114,8 @@ endmenu +source crypto/Config.in + source drivers/pnp/Config.in source drivers/block/Config.in diff -ruN linux-2.2.5,pristine/arch/i386/defconfig linux-2.2.5/arch/i386/defconfig --- linux-2.2.5,pristine/arch/i386/defconfig Mon Mar 8 05:38:44 1999 +++ linux-2.2.5/arch/i386/defconfig Thu Apr 1 23:05:45 1999 @@ -90,6 +90,8 @@ # Additional Block Devices # # CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_LOOP_CAST is not set +# CONFIG_BLK_DEV_LOOP_IDEA is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_MD is not set # CONFIG_BLK_DEV_RAM is not set diff -ruN linux-2.2.5,pristine/arch/m68k/config.in linux-2.2.5/arch/m68k/config.in --- linux-2.2.5,pristine/arch/m68k/config.in Mon Feb 1 21:03:20 1999 +++ linux-2.2.5/arch/m68k/config.in Thu Apr 1 23:05:45 1999 @@ -102,6 +102,8 @@ source net/Config.in fi +source crypto/Config.in + mainmenu_option next_comment comment 'SCSI support' diff -ruN linux-2.2.5,pristine/arch/mips/config.in linux-2.2.5/arch/mips/config.in --- linux-2.2.5,pristine/arch/mips/config.in Mon Feb 1 21:03:20 1999 +++ linux-2.2.5/arch/mips/config.in Thu Apr 1 23:05:45 1999 @@ -111,6 +111,8 @@ source net/Config.in fi +source crypto/Config.in + mainmenu_option next_comment comment 'SCSI support' diff -ruN linux-2.2.5,pristine/arch/ppc/config.in linux-2.2.5/arch/ppc/config.in --- linux-2.2.5,pristine/arch/ppc/config.in Thu Mar 11 06:30:31 1999 +++ linux-2.2.5/arch/ppc/config.in Thu Apr 1 23:05:45 1999 @@ -121,6 +121,8 @@ source net/Config.in fi +source crypto/Config.in + mainmenu_option next_comment comment 'SCSI support' tristate 'SCSI support' CONFIG_SCSI diff -ruN linux-2.2.5,pristine/arch/sparc/config.in linux-2.2.5/arch/sparc/config.in --- linux-2.2.5,pristine/arch/sparc/config.in Tue Mar 16 01:10:43 1999 +++ linux-2.2.5/arch/sparc/config.in Thu Apr 1 23:05:45 1999 @@ -104,6 +104,8 @@ source net/Config.in fi +source crypto/Config.in + mainmenu_option next_comment comment 'ISDN subsystem' diff -ruN linux-2.2.5,pristine/arch/sparc64/config.in linux-2.2.5/arch/sparc64/config.in --- linux-2.2.5,pristine/arch/sparc64/config.in Tue Mar 16 01:10:43 1999 +++ linux-2.2.5/arch/sparc64/config.in Thu Apr 1 23:05:45 1999 @@ -132,6 +132,8 @@ source net/Config.in fi +source crypto/Config.in + mainmenu_option next_comment comment 'SCSI support' diff -ruN linux-2.2.5,pristine/crypto/Config.in linux-2.2.5/crypto/Config.in --- linux-2.2.5,pristine/crypto/Config.in Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/Config.in Thu Apr 1 23:05:45 1999 @@ -0,0 +1,18 @@ +# +# Network configuration +# +mainmenu_option next_comment +comment 'Crypto options' +tristate 'Crypto ciphers' CONFIG_CIPHERS +if [ "$CONFIG_CIPHERS" != "n" ]; then + dep_tristate 'Blowfish cipher (EXPERIMENTAL)' CONFIG_CIPHER_BLOWFISH $CONFIG_CIPHERS + dep_tristate 'DES cipher (EXPERIMENTAL)' CONFIG_CIPHER_DES $CONFIG_CIPHERS + dep_tristate 'DFC cipher (EXPERIMENTAL)' CONFIG_CIPHER_DFC $CONFIG_CIPHERS + dep_tristate 'IDEA cipher (EXPERIMENTAL)' CONFIG_CIPHER_IDEA $CONFIG_CIPHERS + dep_tristate 'MARS cipher (EXPERIMENTAL)' CONFIG_CIPHER_MARS $CONFIG_CIPHERS + dep_tristate 'RC6 cipher (EXPERIMENTAL)' CONFIG_CIPHER_RC6 $CONFIG_CIPHERS +# Rijndael isn't working +# dep_tristate 'Rijndael cipher (EXPERIMENTAL)' CONFIG_CIPHER_RIJNDAEL $CONFIG_CIPHERS + dep_tristate 'Serpent cipher (EXPERIMENTAL)' CONFIG_CIPHER_SERPENT $CONFIG_CIPHERS +fi +endmenu diff -ruN linux-2.2.5,pristine/crypto/LICENSE.crypto linux-2.2.5/crypto/LICENSE.crypto --- linux-2.2.5,pristine/crypto/LICENSE.crypto Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/LICENSE.crypto Thu Apr 1 23:05:45 1999 @@ -0,0 +1,28 @@ + +For those files not covered by other licenses, the following license +applies + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, dis- +tribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the fol- +lowing conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- +ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABIL- +ITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + +Except as contained in this notice, the name of the authors shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization from +the authors. + diff -ruN linux-2.2.5,pristine/crypto/Makefile linux-2.2.5/crypto/Makefile --- linux-2.2.5,pristine/crypto/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/Makefile Thu Apr 1 23:05:45 1999 @@ -0,0 +1,86 @@ +# +# Makefile for the Linux kernel crypto library. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile. + +L_TARGET := crypto.a +L_OBJS := +LX_OBJS := + +ifeq ($(CONFIG_CIPHERS),y) + LX_OBJS += api.o +else + ifeq ($(CONFIG_CIPHERS),m) + MX_OBJS += api.o + endif +endif + +ifeq ($(CONFIG_CIPHER_SERPENT),y) + L_OBJS += serp6f.o +else + ifeq ($(CONFIG_CIPHER_SERPENT),m) + M_OBJS += serp6f.o + endif +endif + +ifeq ($(CONFIG_CIPHER_MARS),y) + L_OBJS += mars6.o +else + ifeq ($(CONFIG_CIPHER_MARS),m) + M_OBJS += mars6.o + endif +endif + +ifeq ($(CONFIG_CIPHER_RC6),y) + L_OBJS += rc62.o +else + ifeq ($(CONFIG_CIPHER_RC6),m) + M_OBJS += rc62.o + endif +endif + +ifeq ($(CONFIG_CIPHER_DFC),y) + L_OBJS += dfc2.o +else + ifeq ($(CONFIG_CIPHER_DFC),m) + M_OBJS += dfc2.o + endif +endif + +ifeq ($(CONFIG_CIPHER_RIJNDAEL),y) + L_OBJS += rijndael3.o +else + ifeq ($(CONFIG_CIPHER_RIJNDAEL),m) + M_OBJS += rijndael3.o + endif +endif + +ifeq ($(CONFIG_CIPHER_BLOWFISH),y) + L_OBJS += blowfish.o +else + ifeq ($(CONFIG_CIPHER_BLOWFISH),m) + M_OBJS += blowfish.o + endif +endif + +ifeq ($(CONFIG_CIPHER_IDEA),y) + L_OBJS += idea.o +else + ifeq ($(CONFIG_CIPHER_IDEA),m) + M_OBJS += idea.o + endif +endif + +ifeq ($(CONFIG_CIPHER_DES),y) + L_OBJS += des.o +else + ifeq ($(CONFIG_CIPHER_DES),m) + M_OBJS += des.o + endif +endif + +include $(TOPDIR)/Rules.make diff -ruN linux-2.2.5,pristine/crypto/api.c linux-2.2.5/crypto/api.c --- linux-2.2.5,pristine/crypto/api.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/api.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,279 @@ +/* + * crypto/api.c + * + * Written by Alexander Kjeldaas 1998-11-15 + * + * Copyright 1998 by Alexander Kjeldaas. Redistribution of this file + * is permitted under the GNU Public License. + */ + +#include + +#ifdef CONFIG_KMOD +#include +#endif /* CONFIG_KMOD */ + +#include +#include +#include +#include +#include + +static int cipher_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data); + +/* The cipher_lock should be aquired before modifying the cipher-list */ + +spinlock_t cipher_lock = SPIN_LOCK_UNLOCKED; + +struct cipher_implementation ciphers = +{ + DNODE_NULL, + CIPHER_NONE, + "none", + 0, + 0, + 0, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +#define PROC_CIPHER_NAME "cipher" + +struct proc_dir_entry proc_cipher = +{ + 0, /* inode */ + sizeof(PROC_CIPHER_NAME) - 1, /* namelen */ + PROC_CIPHER_NAME, /* name */ + S_IFDIR | S_IRUGO | S_IXUGO, /* mode */ + 2, /* nlink */ + 0, 0, /* uid, gid */ + 0, /* size */ + NULL, /* inode_ops */ + NULL, /* get_info */ + NULL, /* fill_inode */ + NULL, /* next, parent, subdir */ + NULL, /* data */ + NULL, /* read_proc */ + NULL, /* write_proc */ + NULL, /* readlink_proc */ + 0, /* use count */ + 0, /* deleted flag */ +}; + + +struct cipher_implementation *find_cipher_by_id(int id) +{ + struct cipher_implementation *c; +#ifdef CONFIG_KMOD + int mod_try = 0; +retry: +#endif + read_lock(&cipher_lock); + c = DLIST_NEXT(ciphers.link); + for(; c != &ciphers && c->cipher_id != id; c = DLIST_NEXT(c->link)) + ; + read_unlock(&cipher_lock); + if (c->cipher_id != id || c->cipher_id == CIPHER_NONE) { +#ifdef CONFIG_KMOD + if (!mod_try) { + char module_name[50]; + mod_try = 1; + sprintf(module_name, "cipher-%d", id & (~CIPHER_CBC)); + request_module(module_name); + goto retry; + } +#endif + return NULL; + } + return c; +} + +struct cipher_implementation *find_cipher_by_name(char *name) +{ + struct cipher_implementation *c; + read_lock(&cipher_lock); + c = DLIST_NEXT(ciphers.link); + for(; c != &ciphers && strcmp(c->cipher_name, name); c = DLIST_NEXT(c->link)) + ; + read_unlock(&cipher_lock); + if (strcmp(c->cipher_name, name) != 0 || c->cipher_id == CIPHER_NONE) + return NULL; + return c; +} + +void for_each_cipher(cipher_iterator *fn) +{ + struct cipher_implementation *c; + read_lock(&cipher_lock); + c = DLIST_NEXT(ciphers.link); + for(; c != &ciphers && c->cipher_id != CIPHER_NONE; c = DLIST_NEXT(c->link)) + fn(c); +} + +int proc_register_cipher(struct cipher_implementation *ci) +{ + struct proc_dir_entry *cipher_de; + int err; + + cipher_de = kmalloc(sizeof(*cipher_de), GFP_KERNEL); + if (!cipher_de) + return -ENOMEM; + + memset(cipher_de, 0, sizeof(*cipher_de)); + cipher_de->namelen = strlen(ci->cipher_name); + cipher_de->name = ci->cipher_name; + cipher_de->mode = S_IFREG | S_IRUGO; + cipher_de->nlink = 1; + cipher_de->data = ci; + cipher_de->read_proc = cipher_read_proc; + + err = proc_register(&proc_cipher, cipher_de); + if (!err) + ci->de = cipher_de; + else + ci->de = NULL; + + return 0; +} + +int register_cipher(struct cipher_implementation *ci) +{ + int err = 0; + + write_lock(&cipher_lock); + DLIST_INSERT_AFTER(&ciphers, ci, link); + write_unlock(&cipher_lock); + if (!err) { + char buf[200]; + sprintf(buf, "Registered %s (%d)\n", + ci->cipher_name, ci->cipher_id); + printk(buf); + + proc_register_cipher(ci); + } + return err; +} + +int unregister_cipher(struct cipher_implementation *ci) +{ + struct cipher_implementation *c; + int ret = 1; + + write_lock(&cipher_lock); + c = DLIST_NEXT(ciphers.link); + for(; c != &ciphers && c->cipher_id != ci->cipher_id; c = DLIST_NEXT(c->link)) + ; + if (c) { + DLIST_DELETE(c, link); + ret = 0; + } + write_unlock(&cipher_lock); + + if (!ret && ci->de) { + ret = proc_unregister(&proc_cipher, ci->de->low_ino); + if (!ret) { + kfree(ci->de); + } else { + printk(KERN_ERR "unregister_cipher: Unable to unregister proc entry\n"); + } + } + + return ret; +} + +static int cipher_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + struct cipher_implementation *ci; + int len = 0; + + ci = (struct cipher_implementation *)data; + + len = sprintf(page, "cipher_id: %d\n" + "cipher_name: %s\n" + "blocksize: %d\n" + "ivsize: %d\n" + "key_schedule_size: %d\n", + ci->cipher_id, ci->cipher_name, ci->blocksize, + ci->ivsize, ci->key_schedule_size); + *eof=1; + + return len; +} + + +int lock_cipher(struct cipher_implementation *ci) +{ + MOD_INC_USE_COUNT; + ci->lock(); + return 0; +} + +int unlock_cipher(struct cipher_implementation *ci) +{ + ci->unlock(); + MOD_DEC_USE_COUNT; + return 0; +} + +#ifdef MODULE + int __init init_module(void) +#else + int __init ciphers_init() +#endif +{ + int err; + + /* DLIST_INIT is broken */ + DLIST_NEXT(ciphers.link) = &ciphers; + DLIST_PREV(ciphers.link) = &ciphers; + + err = proc_register(&proc_root, &proc_cipher); + if (err) + return err; + +#ifdef CONFIG_CIPHER_RIJNDAEL + init_rijndael(); +#endif +#ifdef CONFIG_CIPHER_SERPENT + init_serpent(); +#endif +#ifdef CONFIG_CIPHER_RC6 + init_rc6(); +#endif +#ifdef CONFIG_CIPHER_MARS + init_mars(); +#endif +#ifdef CONFIG_CIPHER_DFC + init_dfc(); +#endif +#ifdef CONFIG_CIPHER_BLOWFISH + init_blowfish(); +#endif +#ifdef CONFIG_CIPHER_IDEA + init_idea(); +#endif +#ifdef CONFIG_CIPHER_DES + init_des(); +#endif + return 0; +} + +#ifdef MODULE +int cleanup_module(void) { + return proc_unregister(&proc_root, proc_cipher.low_ino); +} +#endif + + +EXPORT_SYMBOL(find_cipher_by_name); +EXPORT_SYMBOL(find_cipher_by_id); +EXPORT_SYMBOL(for_each_cipher); +EXPORT_SYMBOL(lock_cipher); +EXPORT_SYMBOL(unlock_cipher); +EXPORT_SYMBOL(register_cipher); +EXPORT_SYMBOL(unregister_cipher); diff -ruN linux-2.2.5,pristine/crypto/blowfish.c linux-2.2.5/crypto/blowfish.c --- linux-2.2.5,pristine/crypto/blowfish.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/blowfish.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,490 @@ +#include +#include +#include +#include +#include + +#define Bswap(x) __le32_to_cpu(x) + +static u32 bf_pbox[16 + 2] = +{ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b, +}; + +static u32 bf_sbox[256 * 4] = +{ + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, + 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, + 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, + 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, + 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, + 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, + 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, + 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, + 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, + 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, + 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, + 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, + 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, + 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, + 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, + 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, + 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, + 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, + 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, + 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, + 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, + 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, + 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, + 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, + 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, + 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, + 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, + 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, + 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, + 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, + 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, + 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, + 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, + 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0, + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, + 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, + 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, + 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, + 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, + 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, + 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, + 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, + 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6, +}; + +typedef struct blow_key +{ + u32 P[18]; + u32 S[1024]; +} +blow_key; + +/* + * Round loop unrolling macros, S is a pointer to a S-Box array + * organized in 4 unsigned longs at a row. + */ + +#define GET32_3(x) (((x) & 0xff)) +#define GET32_2(x) (((x) >> (8)) & (0xff)) +#define GET32_1(x) (((x) >> (16)) & (0xff)) +#define GET32_0(x) (((x) >> (24)) & (0xff)) + +#define bf_F(x) (((S[GET32_0(x)] + S[256 + GET32_1(x)]) ^ \ + S[512 + GET32_2(x)]) + S[768 + GET32_3(x)]) + +#define ROUND(a, b, n) b^=P[n];a ^= bf_F(b) + +/* + * The blowfish encipher, processes 64-bit blocks. + * NOTE: This function MUSTN'T respect endianess + */ + +int blowfish_encrypt(struct cipher_context *cx, + u32 *in_blk, u32 *out_blk, int size) +{ + blow_key *key=(blow_key *)cx->keyinfo; + + u32 yl,yr; + + u32 *P = key->P; + u32 *S = key->S; + + for (; size >= 8; size -= 8) + { + yl = *(in_blk++); + yr = *(in_blk++); + + ROUND(yr, yl, 0); + ROUND(yl, yr, 1); + ROUND(yr, yl, 2); + ROUND(yl, yr, 3); + ROUND(yr, yl, 4); + ROUND(yl, yr, 5); + ROUND(yr, yl, 6); + ROUND(yl, yr, 7); + ROUND(yr, yl, 8); + ROUND(yl, yr, 9); + ROUND(yr, yl, 10); + ROUND(yl, yr, 11); + ROUND(yr, yl, 12); + ROUND(yl, yr, 13); + ROUND(yr, yl, 14); + ROUND(yl, yr, 15); + + /* yl and yr are switched */ + yl ^= P[16]; + yr ^= P[17]; + + *(out_blk++) = yr; + *(out_blk++) = yl; + } + return 0; +} + +int blowfish_decrypt(struct cipher_context *cx, + u32 *in_blk, u32 *out_blk, int size) +{ + blow_key *key=(blow_key *)cx->keyinfo; + + u32 yl,yr; + + u32 *P = key->P; + u32 *S = key->S; + + for (; size >= 8; size -= 8) + { + yl = *(in_blk++); + yr = *(in_blk++); + + ROUND(yr, yl, 17); + ROUND(yl, yr, 16); + ROUND(yr, yl, 15); + ROUND(yl, yr, 14); + ROUND(yr, yl, 13); + ROUND(yl, yr, 12); + ROUND(yr, yl, 11); + ROUND(yl, yr, 10); + ROUND(yr, yl, 9); + ROUND(yl, yr, 8); + ROUND(yr, yl, 7); + ROUND(yl, yr, 6); + ROUND(yr, yl, 5); + ROUND(yl, yr, 4); + ROUND(yr, yl, 3); + ROUND(yl, yr, 2); + + /* yl and yr are switched */ + yl ^= P[1]; + yr ^= P[0]; + + *(out_blk++) = yr; + *(out_blk++) = yl; + } + return 0; +} + +/* Sets the blowfish S and P boxes for encryption and decryption. */ + +int blowfish_set_key(struct cipher_context *cx, + unsigned char *key, int keybytes) +{ + blow_key *key2=(blow_key *)cx->keyinfo; + short i; + short j; + short count; + u32 data[2]; + u32 temp; + u32 *P = key2->P; + u32 *S = key2->S; + + /* Copy the initialization s-boxes */ + + for (i = 0, count = 0; i < 256; i++) + for (j = 0; j < 4; j++, count++) + S[count] = bf_sbox[count]; + + /* Set the p-boxes */ + + for (i = 0; i < 16 + 2; i++) + P[i] = bf_pbox[i]; + + /* Actual subkey generation */ + + for (j = 0, i = 0; i < 16 + 2; i++) + { + temp = (((u32) key[j] << 24) | + ((u32) key[(j + 1) % keybytes] << 16) | + ((u32) key[(j + 2) % keybytes] << 8) | + ((u32) key[(j + 3) % keybytes] )); + + P[i] = P[i] ^ temp; + j = (j + 4) % keybytes; + } + + data[0] = 0x00000000; + data[1] = 0x00000000; + + for (i = 0; i < 16 + 2; i += 2) + { + blowfish_encrypt(cx, data, data, 8); + + P[i] = data[0]; + P[i + 1] = data[1]; + } + + for (i = 0; i < 4; i++) + { + for (j = 0, count = i * 256; j < 256; j += 2, count += 2) + { + blowfish_encrypt(cx, data, data, 8); + + S[count] = data[0]; + S[count + 1] = data[1]; + } + } + return 0; +} + +static void blowfish_lock(void) +{ + MOD_INC_USE_COUNT; +} + +static void blowfish_unlock(void) +{ + MOD_DEC_USE_COUNT; +} + +#define CIPHER_BITS_64 +#define CIPHER_NAME(x) blowfish##x +#include "gen-cbc.h" + +DEFINE_CIPHER(BLOWFISH, blowfish, "blowfish", 16, 16); +DEFINE_CBC_CIPHER(BLOWFISH, blowfish, "blowfish-cbc", 16); + +#ifdef MODULE +int __init init_module(void) +#else +int __init init_blowfish(void) +#endif +{ + if (register_cipher(&blowfish)) + printk(KERN_WARNING "Couldn't register blowfish encryption\n"); + if (register_cipher(&cbc_blowfish)) + printk(KERN_WARNING "Couldn't register blowfish-cbc encryption\n"); + + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + if (unregister_cipher(&blowfish)) + printk(KERN_WARNING "Couldn't unregister blowfish encryption\n"); + if (unregister_cipher(&cbc_blowfish)) + printk(KERN_WARNING "Couldn't unregister blowfish-cbc encryption\n"); +} +#endif diff -ruN linux-2.2.5,pristine/crypto/cast0.c linux-2.2.5/crypto/cast0.c --- linux-2.2.5,pristine/crypto/cast0.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/cast0.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,409 @@ +/* NOTE: This implementation has been changed from the original + source. See ChangeLog for more information. + Maintained by Alexander Kjeldaas + */ + +/* This is an independent implementation of the CAST-256 encryption */ +/* algorithm designed by Carlisle Adams of Entrust and offered as a */ +/* candidate algorithm for the US NIST Advanced Encryption Standard */ +/* (AES) effort. */ +/* */ +/* Copyright in this implementation is held by Dr B R Gladman but */ +/* I hereby give permission for its free direct or derivative use */ +/* subject to acknowledgment of its origin and compliance with any */ +/* conditions that the originators of CAST-256 place on its use. */ +/* */ +/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 19th October 1998 */ +/* */ +/* Timing data: + +Algorithm: cast256 (cast0.c) +128 bit key: +Key Setup: 4279 cycles +Encrypt: 659 cycles = 38.9 mbits/sec +Decrypt: 667 cycles = 38.4 mbits/sec +Mean: 663 cycles = 38.6 mbits/sec +192 bit key: +Key Setup: 4337 cycles +Encrypt: 663 cycles = 38.6 mbits/sec +Decrypt: 672 cycles = 38.1 mbits/sec +Mean: 668 cycles = 38.4 mbits/sec +256 bit key: +Key Setup: 4304 cycles +Encrypt: 655 cycles = 39.1 mbits/sec +Decrypt: 663 cycles = 38.6 mbits/sec +Mean: 659 cycles = 38.8 mbits/sec + +*/ + +#include +#include +#include +#include +#include + +#if 0 +#define rotl rotl32 +#define rotr rotr32 +#else +#define rotl generic_rotl32 +#define rotr generic_rotr32 +#endif + +u4byte s_box[4][256] = +{ { + 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9C004dd3, + 0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, + 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, 0x28683b6f, 0xc07fd059, + 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, + 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, + 0x22568e3a, 0xa2d341d0, 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, + 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, 0xb82cbaef, 0xd751d159, + 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, + 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, + 0xb48ee411, 0x4bff345d, 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, + 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0C50, 0x882240f2, 0x0c6e4f38, + 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, + 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, + 0xe63d37e0, 0x2a54f6b3, 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, + 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, 0x38901091, 0xc6b505eb, + 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, + 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, + 0xa0bebc3c, 0x54623779, 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, + 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6C2, 0x81383f05, 0x6963c5c8, + 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, + 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, + 0xaa573b04, 0x4a805d8d, 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, + 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, 0x6b54bfab, 0x2b0b1426, + 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, + 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, + 0xe31231b2, 0x2ad5ad6c, 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, + 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, 0x7b5a41f0, 0xd37cfbad, + 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, + 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, + 0x5ad328d8, 0xb347cc96, 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, + 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, 0x3f04442f, 0x6188b153, + 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, + 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, + 0xdd24cb9e, 0x7e1c54bd, 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, + 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, 0x580304f0, 0xca042cf1, + 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, + 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, + 0xd5ea50f1, 0x85a92872, 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, + 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814C, 0x474d6ad7, 0x7c0c5e5c, + 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, + 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, + 0xb141ab08, 0x7cca89b9, 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, + 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf + }, + { + 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, + 0x55889c94, 0x72fc0651, 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, + 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, 0xa0b52f7b, 0x59e83605, + 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, + 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, + 0x25a1ff41, 0xe180f806, 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, + 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, 0xe113c85b, 0xacc40083, + 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, + 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, + 0x361e3084, 0xe4eb573b, 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, + 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, 0x10843094, 0x2537a95e, + 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, + 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, + 0x721d9bfd, 0xa58684bb, 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, + 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, 0xc5d655dd, 0xeb667064, + 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, + 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, + 0x83ca6b94, 0x2d6ed23b, 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, + 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, 0x81ed6f61, 0x20e74364, + 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, + 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, + 0xa4b09f6b, 0x1ca815cf, 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, + 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, 0xee41e729, 0x6e1d2d7c, + 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, + 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, + 0x7cbad9a2, 0x2180036f, 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, + 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, 0xcdf0b680, 0x17844d3b, + 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, + 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, + 0xef8579cc, 0xd152de58, 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, + 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, 0xb8da230c, 0x80823028, + 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, + 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, + 0x273be979, 0xb0ffeaa6, 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, + 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, 0xdc8637a0, 0x16a7d3b1, + 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, + 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, + 0x145892f5, 0x91584f7f, 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, + 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, 0xb284600c, 0xd835731d, + 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, + 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, + 0x5c038323, 0x3e5d3bb9, 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, + 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1 + }, + { + 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, + 0x8c1fc644, 0xaececa90, 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, + 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, 0x11107d9f, 0x07647db9, + 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, + 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, + 0x9255c5ed, 0x1257a240, 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, + 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, 0xa8c01db7, 0x579fc264, + 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, + 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, + 0xc5884a28, 0xccc36f71, 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, + 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, 0xa747d2d0, 0x1651192e, + 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, + 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, + 0x796fb449, 0x8252dc15, 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, + 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, 0x23efe941, 0xa903f12e, + 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, + 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, + 0x96bbb682, 0x93b4b148, 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, + 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, 0x8b907cee, 0xb51fd240, + 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, + 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, + 0x127dadaa, 0x438a074e, 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, + 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, 0x68cc7bfb, 0xd90f2788, + 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, + 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, + 0x27627545, 0x825cf47a, 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, + 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, 0x285ba1c8, 0x3c62f44f, + 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, + 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, + 0x12deca4d, 0x2c3f8cc5, 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, + 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, 0x3a609437, 0xec00c9a9, + 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, + 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, + 0xa2e53f55, 0xb9e6d4bc, 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, + 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, 0x947b0001, 0x570075d2, + 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, + 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, + 0xf1ac2571, 0xcc8239c2, 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, + 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, 0x5727c148, 0x2be98a1d, + 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, + 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, + 0x52bce688, 0x1b03588a, 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, + 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783 + }, + { + 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, + 0x85510443, 0xfa020ed1, 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, + 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, 0x28147f5f, 0x4fa2b8cd, + 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, + 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, + 0x081b08ca, 0x05170121, 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, + 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, 0xce84ffdf, 0xf5718801, + 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, + 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, + 0x72500e03, 0xf80eb2bb, 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, + 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, 0x4d351805, 0x7f3d5ce3, + 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, + 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, + 0x18f8931e, 0x281658e6, 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, + 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, 0x69dead38, 0x1574ca16, + 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, + 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, + 0x0ce5c2ec, 0x4db4bba6, 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, + 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, 0x6e85cb75, 0xbe07c002, + 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, + 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, + 0x041afa32, 0x1d16625a, 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, + 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, 0x026a4ceb, 0x52437eff, + 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, + 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, + 0x213d42f6, 0x2c1c7c26, 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, + 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, 0x63315c21, 0x5e0a72ec, + 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, + 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, + 0xcfcbd12f, 0xc1de8417, 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, + 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, 0x6f7de532, 0x58fd7eb6, + 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, + 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, + 0xaf9eb3db, 0x29c9ed2a, 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, + 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, 0x77079103, 0xdea03af6, + 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, + 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, + 0xf3e0eb5b, 0xd6cc9876, 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, + 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, 0xb5676e69, 0x9bd3ddda, + 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, + 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, + 0xb657c34d, 0x4edfd282, 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, + 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2 + } +}; + +#define f1(y,x,kr,km) \ + t = rotl(km + x, kr); \ + u = s_box[0][byte(t,3)]; \ + u ^= s_box[1][byte(t,2)]; \ + u -= s_box[2][byte(t,1)]; \ + u += s_box[3][byte(t,0)]; \ + y ^= u + +#define f2(y,x,kr,km) \ + t = rotl(km ^ x, kr); \ + u = s_box[0][byte(t,3)]; \ + u -= s_box[1][byte(t,2)]; \ + u += s_box[2][byte(t,1)]; \ + u ^= s_box[3][byte(t,0)]; \ + y ^= u + +#define f3(y,x,kr,km) \ + t = rotl(km - x, kr); \ + u = s_box[0][byte(t,3)]; \ + u += s_box[1][byte(t,2)]; \ + u ^= s_box[2][byte(t,1)]; \ + u -= s_box[3][byte(t,0)]; \ + y ^= u + +#define f_rnd(x,n) \ + f1(x[2],x[3],l_key[n], l_key[n + 4]); \ + f2(x[1],x[2],l_key[n + 1],l_key[n + 5]); \ + f3(x[0],x[1],l_key[n + 2],l_key[n + 6]); \ + f1(x[3],x[0],l_key[n + 3],l_key[n + 7]) + +#define i_rnd(x, n) \ + f1(x[3],x[0],l_key[n + 3],l_key[n + 7]); \ + f3(x[0],x[1],l_key[n + 2],l_key[n + 6]); \ + f2(x[1],x[2],l_key[n + 1],l_key[n + 5]); \ + f1(x[2],x[3],l_key[n], l_key[n + 4]) + +#define k_rnd(k,tr,tm) \ + f1(k[6],k[7],tr[0],tm[0]); \ + f2(k[5],k[6],tr[1],tm[1]); \ + f3(k[4],k[5],tr[2],tm[2]); \ + f1(k[3],k[4],tr[3],tm[3]); \ + f2(k[2],k[3],tr[4],tm[4]); \ + f3(k[1],k[2],tr[5],tm[5]); \ + f1(k[0],k[1],tr[6],tm[6]); \ + f2(k[7],k[0],tr[7],tm[7]) + +/* initialise the key schedule from the user supplied key */ + +int cast256_set_key(struct cipher_context *cx, char *key, int key_len) +{ u4byte *key_blk = (u4byte *)key; + /* l_key - storage for the key schedule */ + u4byte *l_key = cx->keyinfo; + u4byte i, j, t, u, cm, cr, lk[8], tm[8], tr[8]; + key_len *= 8; + + for(i = 0; i < key_len / 32; ++i) + + lk[i] = bswap(in_key[i]); + + for(; i < 8; ++i) + + lk[i] = 0; + + cm = 0x5a827999; cr = 19; + + for(i = 0; i < 96; i += 8) + { + for(j = 0; j < 8; ++j) + { + tm[j] = cm; cm += 0x6ed9eba1; + tr[j] = cr; cr += 17; + } + + k_rnd(lk, tr, tm); + + for(j = 0; j < 8; ++j) + { + tm[j] = cm; cm += 0x6ed9eba1; + tr[j] = cr; cr += 17; + } + + k_rnd(lk, tr, tm); + + l_key[i + 0] = lk[0]; l_key[i + 1] = lk[2]; + l_key[i + 2] = lk[4]; l_key[i + 3] = lk[6]; + l_key[i + 4] = lk[7]; l_key[i + 5] = lk[5]; + l_key[i + 6] = lk[3]; l_key[i + 7] = lk[1]; + } + + return 0; +}; + +/* encrypt a block of text */ + +int cast256_encrypt(struct cipher_context *cx, u4byte *in_blk, u4byte *out_blk) +{ u4byte *l_key = cx->keyinfo; + u4byte t, u, blk[4]; + + blk[0] = bswap(in_blk[0]); blk[1] = bswap(in_blk[1]); + blk[2] = bswap(in_blk[2]); blk[3] = bswap(in_blk[3]); + + f_rnd(blk, 0); f_rnd(blk, 8); + f_rnd(blk, 16); f_rnd(blk, 24); + f_rnd(blk, 32); f_rnd(blk, 40); + i_rnd(blk, 48); i_rnd(blk, 56); + i_rnd(blk, 64); i_rnd(blk, 72); + i_rnd(blk, 80); i_rnd(blk, 88); + + out_blk[0] = bswap(blk[0]); out_blk[1] = bswap(blk[1]); + out_blk[2] = bswap(blk[2]); out_blk[3] = bswap(blk[3]); + return 0; +}; + +/* decrypt a block of text */ + +int cast256_decrypt(struct cipher_context *cx, u4byte *in_blk, u4byte *out_blk) +{ u4byte *l_key = cx->keyinfo; + u4byte t, u, blk[4]; + + blk[0] = bswap(in_blk[0]); blk[1] = bswap(in_blk[1]); + blk[2] = bswap(in_blk[2]); blk[3] = bswap(in_blk[3]); + + f_rnd(blk, 88); f_rnd(blk, 80); + f_rnd(blk, 72); f_rnd(blk, 64); + f_rnd(blk, 56); f_rnd(blk, 48); + i_rnd(blk, 40); i_rnd(blk, 32); + i_rnd(blk, 24); i_rnd(blk, 16); + i_rnd(blk, 8); i_rnd(blk, 0); + + out_blk[0] = bswap(blk[0]); out_blk[1] = bswap(blk[1]); + out_blk[2] = bswap(blk[2]); out_blk[3] = bswap(blk[3]); + return 0; +}; + +static void cast256_lock() +{ + MOD_INC_USE_COUNT; +} + +static void cast256_unlock() +{ + MOD_DEC_USE_COUNT; +} + +#define CIPHER_BITS_128 +#define CIPHER_NAME(x) cast256##x +#include "gen-cbc.h" + +DEFINE_CIPHER(CAST256, cast256, "cast256", 8, 8); +DEFINE_CBC_CIPHER(CAST256, cast256, "cast256-cbc", 8); + +#ifdef MODULE +int __init init_module(void) +#else +int __init init_cast256(void) +#endif +{ + if (register_cipher(&cast256)) + printk(KERN_WARNING "Couldn't register cast256 encryption\n"); + if (register_cipher(&cbc_cast256)) + printk(KERN_WARNING "Couldn't register cast256-cbc encryption\n"); + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + if (unregister_cipher(&cast256)) + printk(KERN_WARNING "Couldn't unregister cast256 encryption\n"); + if (unregister_cipher(&cbc_cast256)) + printk(KERN_WARNING "Couldn't unregister cast256-cbc encryption\n"); +} +#endif + diff -ruN linux-2.2.5,pristine/crypto/crypton2.c linux-2.2.5/crypto/crypton2.c --- linux-2.2.5,pristine/crypto/crypton2.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/crypton2.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,362 @@ +/* NOTE: This implementation has been changed from the original + source. See ChangeLog for more information. + Maintained by Alexander Kjeldaas + */ + +/* This is an independent implementation of the CRYPTON algorithm */ +/* designed by Chae Hoon Lim of Future Systms Inc and submitted as */ +/* a candidate for the NIST AES activity. */ +/* */ +/* Copyright in this implementation is held by Dr B R Gladman but */ +/* I hereby give permission for its free direct or derivative use */ +/* subject to acknowledgment of its origin and compliance with any */ +/* conditions that the algorithm originators place on its use. */ +/* */ +/* Dr Brian Gladman (gladman@seven77.demon.co.uk) October 1998 */ +/* Timing data: + +Algorithm: crypton (crypton2.c) +128 bit key: +Key Setup: 1386 cycles +Encrypt: 472 cycles = 54.2 mbits/sec +Decrypt: 486 cycles = 52.7 mbits/sec +Mean: 479 cycles = 53.5 mbits/sec +192 bit key: +Key Setup: 1408 cycles +Encrypt: 476 cycles = 53.8 mbits/sec +Decrypt: 493 cycles = 52.0 mbits/sec +Mean: 484 cycles = 52.8 mbits/sec +256 bit key: +Key Setup: 1412 cycles +Encrypt: 468 cycles = 54.7 mbits/sec +Decrypt: 479 cycles = 53.4 mbits/sec +Mean: 474 cycles = 54.1 mbits/sec + +*/ + +#include +#include +#include +#include +#include + +#if 0 +#define rotl rotl32 +#define rotr rotr32 +#else +#define rotl generic_rotl32 +#define rotr generic_rotr32 +#endif + +#define gamma(x,p,q) \ + (x) = (((u4byte)s_box[p][byte((x),0)] ) | \ + ((u4byte)s_box[q][byte((x),1)] << 8) | \ + ((u4byte)s_box[p][byte((x),2)] << 16) | \ + ((u4byte)s_box[q][byte((x),3)] << 24)) + +#define gamma_tau(x,b,m,p,q) \ + (x) = (((u4byte)s_box[p][byte(b[0],m)] ) | \ + ((u4byte)s_box[q][byte(b[1],m)] << 8) | \ + ((u4byte)s_box[p][byte(b[2],m)] << 16) | \ + ((u4byte)s_box[q][byte(b[3],m)] << 24)) + +#define ma_0 0x3fcff3fc +#define ma_1 0xfc3fcff3 +#define ma_2 0xf3fc3fcf +#define ma_3 0xcff3fc3f + +#define mb_0 0xcffccffc +#define mb_1 0xf33ff33f +#define mb_2 0xfccffccf +#define mb_3 0x3ff33ff3 + +#define pi(b,n0,n1,n2,n3) \ + (((b)[0] & ma_##n0) ^ \ + ((b)[1] & ma_##n1) ^ \ + ((b)[2] & ma_##n2) ^ \ + ((b)[3] & ma_##n3)) + +#define phi_n(x,n0,n1,n2,n3) \ + ( (x) & mb_##n0) ^ \ + (rotl((x), 8) & mb_##n1) ^ \ + (rotl((x), 16) & mb_##n2) ^ \ + (rotl((x), 24) & mb_##n3) + +#define phi_00(x) phi_n(x,0,1,2,3) +#define phi_01(x) phi_n(x,3,0,1,2) +#define phi_02(x) phi_n(x,2,3,0,1) +#define phi_03(x) phi_n(x,1,2,3,0) + +#define phi_10(x) phi_n(x,3,0,1,2) +#define phi_11(x) phi_n(x,2,3,0,1) +#define phi_12(x) phi_n(x,1,2,3,0) +#define phi_13(x) phi_n(x,0,1,2,3) + +#define phi0(x,y) \ + (y)[0] = phi_00((x)[0]); \ + (y)[1] = phi_01((x)[1]); \ + (y)[2] = phi_02((x)[2]); \ + (y)[3] = phi_03((x)[3]) + +#define phi1(x,y) \ + (y)[0] = phi_10((x)[0]); \ + (y)[1] = phi_11((x)[1]); \ + (y)[2] = phi_12((x)[2]); \ + (y)[3] = phi_13((x)[3]) + +u1byte p_box[3][16] = +{ { 15, 9, 6, 8, 9, 9, 4, 12, 6, 2, 6, 10, 1, 3, 5, 15 }, + { 10, 15, 4, 7, 5, 2, 14, 6, 9, 3, 12, 8, 13, 1, 11, 0 }, + { 0, 4, 8, 4, 2, 15, 8, 13, 1, 1, 15, 7, 2, 11, 14, 15 } +}; + +u4byte tab_gen = 0; +u1byte s_box[2][256]; +u4byte s_tab[4][256]; + +u4byte l_key[104]; +u4byte *e_key = l_key + 52; +u4byte *d_key = l_key; + +void gen_tab(void) +{ u4byte i, xl, xr, yl, yr; + + for(i = 0; i < 256; ++i) + { + xl = (i & 0xf0) >> 4; xr = i & 15; + + yr = xr ^ p_box[1][xl ^ p_box[0][xr]]; + yl = xl ^ p_box[0][xr] ^ p_box[2][yr]; + + yr |= (yl << 4); s_box[0][i] = yr; s_box[1][yr] = i; + + xr = yr * 0x01010101; xl = i * 0x01010101; + + s_tab[0][ i] = xr & 0x3fcff3fc; + s_tab[1][yr] = xl & 0xfc3fcff3; + s_tab[2][ i] = xr & 0xf3fc3fcf; + s_tab[3][yr] = xl & 0xcff3fc3f; + } +}; + +/* initialise the key schedule from the user supplied key */ + +u4byte kp[4] = { 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f }; +u4byte kq[4] = { 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, 0xcbbb9d5d }; + +#define h0_block(n,r0,r1) \ + e_key[4 * n + 8] = rotl(e_key[4 * n + 0], r0); \ + e_key[4 * n + 9] = rc ^ e_key[4 * n + 1]; \ + e_key[4 * n + 10] = rotl(e_key[4 * n + 2], r1); \ + e_key[4 * n + 11] = rc ^ e_key[4 * n + 3] + +#define h1_block(n,r0,r1) \ + e_key[4 * n + 8] = rc ^ e_key[4 * n + 0]; \ + e_key[4 * n + 9] = rotl(e_key[4 * n + 1], r0); \ + e_key[4 * n + 10] = rc ^ e_key[4 * n + 2]; \ + e_key[4 * n + 11] = rotl(e_key[4 * n + 3], r1) + +int crypton_set_key(struct cipher_context *cx, char *key, int key_len) +{ u4byte *key_blk = (u4byte *)key; + /* l_key - storage for the key schedule */ + u4byte *l_key = cx->keyinfo; + u4byte i, rc, t0, t1, tmp[4]; + key_len *= 8; + + if(!tab_gen) + { + gen_tab(); tab_gen = 1; + } + + e_key[2] = e_key[3] = e_key[6] = e_key[7] = 0; + + switch((key_len + 63) / 64) + { + case 4: e_key[3] = in_key[6]; e_key[7] = in_key[7]; + case 3: e_key[2] = in_key[4]; e_key[6] = in_key[5]; + case 2: e_key[0] = in_key[0]; e_key[4] = in_key[1]; + e_key[1] = in_key[2]; e_key[5] = in_key[3]; + } + + tmp[0] = pi(e_key, 0, 1, 2, 3) ^ kp[0]; + tmp[1] = pi(e_key, 1, 2, 3, 0) ^ kp[1]; + tmp[2] = pi(e_key, 2, 3, 0, 1) ^ kp[2]; + tmp[3] = pi(e_key, 3, 0, 1, 2) ^ kp[3]; + + gamma_tau(e_key[0], tmp, 0, 0, 1); + gamma_tau(e_key[1], tmp, 1, 1, 0); + gamma_tau(e_key[2], tmp, 2, 0, 1); + gamma_tau(e_key[3], tmp, 3, 1, 0); + + tmp[0] = pi(e_key + 4, 1, 2, 3, 0) ^ kq[0]; + tmp[1] = pi(e_key + 4, 2, 3, 0, 1) ^ kq[1]; + tmp[2] = pi(e_key + 4, 3, 0, 1, 2) ^ kq[2]; + tmp[3] = pi(e_key + 4, 0, 1, 2, 3) ^ kq[3]; + + gamma_tau(e_key[4], tmp, 0, 1, 0); + gamma_tau(e_key[5], tmp, 1, 0, 1); + gamma_tau(e_key[6], tmp, 2, 1, 0); + gamma_tau(e_key[7], tmp, 3, 0, 1); + + t0 = e_key[0] ^ e_key[1] ^ e_key[2] ^ e_key[3]; + t1 = e_key[4] ^ e_key[5] ^ e_key[6] ^ e_key[7]; + + e_key[0] ^= t1; e_key[1] ^= t1; + e_key[2] ^= t1; e_key[3] ^= t1; + e_key[4] ^= t0; e_key[5] ^= t0; + e_key[6] ^= t0; e_key[7] ^= t0; + + rc = 0x01010101; + h0_block( 0, 8, 16); h1_block(1, 16, 24); rc <<= 1; + h1_block( 2, 24, 8); h0_block(3, 8, 16); rc <<= 1; + h0_block( 4, 16, 24); h1_block(5, 24, 8); rc <<= 1; + h1_block( 6, 8, 16); h0_block(7, 16, 24); rc <<= 1; + h0_block( 8, 24, 8); h1_block(9, 8, 16); rc <<= 1; + h1_block(10, 16, 24); + + for(i = 0; i < 13; ++i) + { + if(i & 1) + { + phi0(e_key + 4 * i, d_key + 48 - 4 * i); + } + else + { + phi1(e_key + 4 * i, d_key + 48 - 4 * i); + } + } + + phi1(e_key + 48, e_key + 48); + phi1(d_key + 48, d_key + 48); + + return 0; +}; + +/* encrypt a block of text */ + +#define fr0(i,k) \ + b1[i] = s_tab[ (i) ][byte(b0[0],i)] ^ \ + s_tab[((i) + 1) & 3][byte(b0[1],i)] ^ \ + s_tab[((i) + 2) & 3][byte(b0[2],i)] ^ \ + s_tab[((i) + 3) & 3][byte(b0[3],i)] ^ (k) + +#define fr1(i,k) \ + b0[i] = s_tab[((i) + 1) & 3][byte(b1[0],i)] ^ \ + s_tab[((i) + 2) & 3][byte(b1[1],i)] ^ \ + s_tab[((i) + 3) & 3][byte(b1[2],i)] ^ \ + s_tab[(i) ][byte(b1[3],i)] ^ (k) + +#define f0_rnd(kp) \ + fr0(0,(kp)[0]); fr0(1,(kp)[1]); \ + fr0(2,(kp)[2]); fr0(3,(kp)[3]) + +#define f1_rnd(kp) \ + fr1(0,(kp)[0]); fr1(1,(kp)[1]); \ + fr1(2,(kp)[2]); fr1(3,(kp)[3]) + +int crypton_encrypt(struct cipher_context *cx, u4byte *in_blk, u4byte *out_blk) +{ u4byte *l_key = cx->keyinfo; + u4byte b0[4], b1[4]; + + b0[0] = in_blk[0] ^ e_key[0]; + b0[1] = in_blk[1] ^ e_key[1]; + b0[2] = in_blk[2] ^ e_key[2]; + b0[3] = in_blk[3] ^ e_key[3]; + + f0_rnd(e_key + 4); f1_rnd(e_key + 8); + f0_rnd(e_key + 12); f1_rnd(e_key + 16); + f0_rnd(e_key + 20); f1_rnd(e_key + 24); + f0_rnd(e_key + 28); f1_rnd(e_key + 32); + f0_rnd(e_key + 36); f1_rnd(e_key + 40); + f0_rnd(e_key + 44); + + gamma_tau(b0[0], b1, 0, 1, 0); + gamma_tau(b0[1], b1, 1, 0, 1); + gamma_tau(b0[2], b1, 2, 1, 0); + gamma_tau(b0[3], b1, 3, 0, 1); + + out_blk[0] = b0[0] ^ e_key[48]; + out_blk[1] = b0[1] ^ e_key[49]; + out_blk[2] = b0[2] ^ e_key[50]; + out_blk[3] = b0[3] ^ e_key[51]; + return 0; +}; + +/* decrypt a block of text */ + +int crypton_decrypt(struct cipher_context *cx, u32 *in_blk, u32 *out_blk) +{ u4byte *l_key = cx->keyinfo; + u4byte b0[4], b1[4]; + + b0[0] = in_blk[0] ^ d_key[0]; + b0[1] = in_blk[1] ^ d_key[1]; + b0[2] = in_blk[2] ^ d_key[2]; + b0[3] = in_blk[3] ^ d_key[3]; + + f0_rnd(d_key + 4); f1_rnd(d_key + 8); + f0_rnd(d_key + 12); f1_rnd(d_key + 16); + f0_rnd(d_key + 20); f1_rnd(d_key + 24); + f0_rnd(d_key + 28); f1_rnd(d_key + 32); + f0_rnd(d_key + 36); f1_rnd(d_key + 40); + f0_rnd(d_key + 44); + + gamma_tau(b0[0], b1, 0, 1, 0); + gamma_tau(b0[1], b1, 1, 0, 1); + gamma_tau(b0[2], b1, 2, 1, 0); + gamma_tau(b0[3], b1, 3, 0, 1); + + out_blk[0] = b0[0] ^ d_key[48]; + out_blk[1] = b0[1] ^ d_key[49]; + out_blk[2] = b0[2] ^ d_key[50]; + out_blk[3] = b0[3] ^ d_key[51]; + return 0; +}; + +static void crypton_lock() +{ + MOD_INC_USE_COUNT; +} + +static void crypton_unlock() +{ + MOD_DEC_USE_COUNT; +} + +static struct cipher_implementation crypton = +{ + DNODE_NULL, + CIPHER_CRYPTON, + "crypton", + 16, + CRYPTON_KEY_SCHEDULE_SIZE, + ATOMIC_INIT(0), + crypton_encrypt, + crypton_decrypt, + crypton_set_key, + crypton_lock, + crypton_unlock +}; + + +#ifdef MODULE + int __init init_module(void) +#else + int __init init_crypton(void) +#endif +{ + if (register_cipher(&crypton)) + printk(KERN_WARNING "Couldn't register crypton encryption\n"); + + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + if (unregister_cipher(&crypton)) + printk(KERN_WARNING "Couldn't unregister crypton encryption\n"); + /*if (unregister_cipher(&cbc_crypton)) + printk(KERN_WARNING "Couldn't unregister crypton-cbc encryption\n");*/ +} +#endif + diff -ruN linux-2.2.5,pristine/crypto/des.c linux-2.2.5/crypto/des.c --- linux-2.2.5,pristine/crypto/des.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/des.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,1296 @@ +/* + * Sourcecode created by descore. Descore is under GPL and from + * Dana L. How . + * + * Modified by Raimar Falke for the Linux-Kernel. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include + +#define ROR(d,c,o) d = d >> c | d << o + +typedef u8 DesData[8]; +typedef u32 DesKeys[32]; + +u32 des_keymap[] = { + 0x02080008, 0x02082000, 0x00002008, 0x00000000, + 0x02002000, 0x00080008, 0x02080000, 0x02082008, + 0x00000008, 0x02000000, 0x00082000, 0x00002008, + 0x00082008, 0x02002008, 0x02000008, 0x02080000, + 0x00002000, 0x00082008, 0x00080008, 0x02002000, + 0x02082008, 0x02000008, 0x00000000, 0x00082000, + 0x02000000, 0x00080000, 0x02002008, 0x02080008, + 0x00080000, 0x00002000, 0x02082000, 0x00000008, + 0x00080000, 0x00002000, 0x02000008, 0x02082008, + 0x00002008, 0x02000000, 0x00000000, 0x00082000, + 0x02080008, 0x02002008, 0x02002000, 0x00080008, + 0x02082000, 0x00000008, 0x00080008, 0x02002000, + 0x02082008, 0x00080000, 0x02080000, 0x02000008, + 0x00082000, 0x00002008, 0x02002008, 0x02080000, + 0x00000008, 0x02082000, 0x00082008, 0x00000000, + 0x02000000, 0x02080008, 0x00002000, 0x00082008, + + 0x08000004, 0x00020004, 0x00000000, 0x08020200, + 0x00020004, 0x00000200, 0x08000204, 0x00020000, + 0x00000204, 0x08020204, 0x00020200, 0x08000000, + 0x08000200, 0x08000004, 0x08020000, 0x00020204, + 0x00020000, 0x08000204, 0x08020004, 0x00000000, + 0x00000200, 0x00000004, 0x08020200, 0x08020004, + 0x08020204, 0x08020000, 0x08000000, 0x00000204, + 0x00000004, 0x00020200, 0x00020204, 0x08000200, + 0x00000204, 0x08000000, 0x08000200, 0x00020204, + 0x08020200, 0x00020004, 0x00000000, 0x08000200, + 0x08000000, 0x00000200, 0x08020004, 0x00020000, + 0x00020004, 0x08020204, 0x00020200, 0x00000004, + 0x08020204, 0x00020200, 0x00020000, 0x08000204, + 0x08000004, 0x08020000, 0x00020204, 0x00000000, + 0x00000200, 0x08000004, 0x08000204, 0x08020200, + 0x08020000, 0x00000204, 0x00000004, 0x08020004, + + 0x80040100, 0x01000100, 0x80000000, 0x81040100, + 0x00000000, 0x01040000, 0x81000100, 0x80040000, + 0x01040100, 0x81000000, 0x01000000, 0x80000100, + 0x81000000, 0x80040100, 0x00040000, 0x01000000, + 0x81040000, 0x00040100, 0x00000100, 0x80000000, + 0x00040100, 0x81000100, 0x01040000, 0x00000100, + 0x80000100, 0x00000000, 0x80040000, 0x01040100, + 0x01000100, 0x81040000, 0x81040100, 0x00040000, + 0x81040000, 0x80000100, 0x00040000, 0x81000000, + 0x00040100, 0x01000100, 0x80000000, 0x01040000, + 0x81000100, 0x00000000, 0x00000100, 0x80040000, + 0x00000000, 0x81040000, 0x01040100, 0x00000100, + 0x01000000, 0x81040100, 0x80040100, 0x00040000, + 0x81040100, 0x80000000, 0x01000100, 0x80040100, + 0x80040000, 0x00040100, 0x01040000, 0x81000100, + 0x80000100, 0x01000000, 0x81000000, 0x01040100, + + 0x04010801, 0x00000000, 0x00010800, 0x04010000, + 0x04000001, 0x00000801, 0x04000800, 0x00010800, + 0x00000800, 0x04010001, 0x00000001, 0x04000800, + 0x00010001, 0x04010800, 0x04010000, 0x00000001, + 0x00010000, 0x04000801, 0x04010001, 0x00000800, + 0x00010801, 0x04000000, 0x00000000, 0x00010001, + 0x04000801, 0x00010801, 0x04010800, 0x04000001, + 0x04000000, 0x00010000, 0x00000801, 0x04010801, + 0x00010001, 0x04010800, 0x04000800, 0x00010801, + 0x04010801, 0x00010001, 0x04000001, 0x00000000, + 0x04000000, 0x00000801, 0x00010000, 0x04010001, + 0x00000800, 0x04000000, 0x00010801, 0x04000801, + 0x04010800, 0x00000800, 0x00000000, 0x04000001, + 0x00000001, 0x04010801, 0x00010800, 0x04010000, + 0x04010001, 0x00010000, 0x00000801, 0x04000800, + 0x04000801, 0x00000001, 0x04010000, 0x00010800, + + 0x00000400, 0x00000020, 0x00100020, 0x40100000, + 0x40100420, 0x40000400, 0x00000420, 0x00000000, + 0x00100000, 0x40100020, 0x40000020, 0x00100400, + 0x40000000, 0x00100420, 0x00100400, 0x40000020, + 0x40100020, 0x00000400, 0x40000400, 0x40100420, + 0x00000000, 0x00100020, 0x40100000, 0x00000420, + 0x40100400, 0x40000420, 0x00100420, 0x40000000, + 0x40000420, 0x40100400, 0x00000020, 0x00100000, + 0x40000420, 0x00100400, 0x40100400, 0x40000020, + 0x00000400, 0x00000020, 0x00100000, 0x40100400, + 0x40100020, 0x40000420, 0x00000420, 0x00000000, + 0x00000020, 0x40100000, 0x40000000, 0x00100020, + 0x00000000, 0x40100020, 0x00100020, 0x00000420, + 0x40000020, 0x00000400, 0x40100420, 0x00100000, + 0x00100420, 0x40000000, 0x40000400, 0x40100420, + 0x40100000, 0x00100420, 0x00100400, 0x40000400, + + 0x00800000, 0x00001000, 0x00000040, 0x00801042, + 0x00801002, 0x00800040, 0x00001042, 0x00801000, + 0x00001000, 0x00000002, 0x00800002, 0x00001040, + 0x00800042, 0x00801002, 0x00801040, 0x00000000, + 0x00001040, 0x00800000, 0x00001002, 0x00000042, + 0x00800040, 0x00001042, 0x00000000, 0x00800002, + 0x00000002, 0x00800042, 0x00801042, 0x00001002, + 0x00801000, 0x00000040, 0x00000042, 0x00801040, + 0x00801040, 0x00800042, 0x00001002, 0x00801000, + 0x00001000, 0x00000002, 0x00800002, 0x00800040, + 0x00800000, 0x00001040, 0x00801042, 0x00000000, + 0x00001042, 0x00800000, 0x00000040, 0x00001002, + 0x00800042, 0x00000040, 0x00000000, 0x00801042, + 0x00801002, 0x00801040, 0x00000042, 0x00001000, + 0x00001040, 0x00801002, 0x00800040, 0x00000042, + 0x00000002, 0x00001042, 0x00801000, 0x00800002, + + 0x10400000, 0x00404010, 0x00000010, 0x10400010, + 0x10004000, 0x00400000, 0x10400010, 0x00004010, + 0x00400010, 0x00004000, 0x00404000, 0x10000000, + 0x10404010, 0x10000010, 0x10000000, 0x10404000, + 0x00000000, 0x10004000, 0x00404010, 0x00000010, + 0x10000010, 0x10404010, 0x00004000, 0x10400000, + 0x10404000, 0x00400010, 0x10004010, 0x00404000, + 0x00004010, 0x00000000, 0x00400000, 0x10004010, + 0x00404010, 0x00000010, 0x10000000, 0x00004000, + 0x10000010, 0x10004000, 0x00404000, 0x10400010, + 0x00000000, 0x00404010, 0x00004010, 0x10404000, + 0x10004000, 0x00400000, 0x10404010, 0x10000000, + 0x10004010, 0x10400000, 0x00400000, 0x10404010, + 0x00004000, 0x00400010, 0x10400010, 0x00004010, + 0x00400010, 0x00000000, 0x10404000, 0x10000010, + 0x10400000, 0x10004010, 0x00000010, 0x00404000, + + 0x00208080, 0x00008000, 0x20200000, 0x20208080, + 0x00200000, 0x20008080, 0x20008000, 0x20200000, + 0x20008080, 0x00208080, 0x00208000, 0x20000080, + 0x20200080, 0x00200000, 0x00000000, 0x20008000, + 0x00008000, 0x20000000, 0x00200080, 0x00008080, + 0x20208080, 0x00208000, 0x20000080, 0x00200080, + 0x20000000, 0x00000080, 0x00008080, 0x20208000, + 0x00000080, 0x20200080, 0x20208000, 0x00000000, + 0x00000000, 0x20208080, 0x00200080, 0x20008000, + 0x00208080, 0x00008000, 0x20000080, 0x00200080, + 0x20208000, 0x00000080, 0x00008080, 0x20200000, + 0x20008080, 0x20000000, 0x20200000, 0x00208000, + 0x20208080, 0x00008080, 0x00208000, 0x20200080, + 0x00200000, 0x20000080, 0x20008000, 0x00000000, + 0x00008000, 0x00200000, 0x20200080, 0x00208080, + 0x20000000, 0x20208000, 0x00000080, 0x20008080, +}; + +static u8 rotors[] = { + 34, 13, 5, 46, 47, 18, 32, 41, 11, 53, 33, 20, + 14, 36, 30, 24, 49, 2, 15, 37, 42, 50, 0, 21, + 38, 48, 6, 26, 39, 4, 52, 25, 12, 27, 31, 40, + 1, 17, 28, 29, 23, 51, 35, 7, 3, 22, 9, 43, + + 41, 20, 12, 53, 54, 25, 39, 48, 18, 31, 40, 27, + 21, 43, 37, 0, 1, 9, 22, 44, 49, 2, 7, 28, + 45, 55, 13, 33, 46, 11, 6, 32, 19, 34, 38, 47, + 8, 24, 35, 36, 30, 3, 42, 14, 10, 29, 16, 50, + + 55, 34, 26, 38, 11, 39, 53, 5, 32, 45, 54, 41, + 35, 2, 51, 14, 15, 23, 36, 3, 8, 16, 21, 42, + 6, 12, 27, 47, 31, 25, 20, 46, 33, 48, 52, 4, + 22, 7, 49, 50, 44, 17, 1, 28, 24, 43, 30, 9, + + 12, 48, 40, 52, 25, 53, 38, 19, 46, 6, 11, 55, + 49, 16, 10, 28, 29, 37, 50, 17, 22, 30, 35, 1, + 20, 26, 41, 4, 45, 39, 34, 31, 47, 5, 13, 18, + 36, 21, 8, 9, 3, 0, 15, 42, 7, 2, 44, 23, + + 26, 5, 54, 13, 39, 38, 52, 33, 31, 20, 25, 12, + 8, 30, 24, 42, 43, 51, 9, 0, 36, 44, 49, 15, + 34, 40, 55, 18, 6, 53, 48, 45, 4, 19, 27, 32, + 50, 35, 22, 23, 17, 14, 29, 1, 21, 16, 3, 37, + + 40, 19, 11, 27, 53, 52, 13, 47, 45, 34, 39, 26, + 22, 44, 7, 1, 2, 10, 23, 14, 50, 3, 8, 29, + 48, 54, 12, 32, 20, 38, 5, 6, 18, 33, 41, 46, + 9, 49, 36, 37, 0, 28, 43, 15, 35, 30, 17, 51, + + 54, 33, 25, 41, 38, 13, 27, 4, 6, 48, 53, 40, + 36, 3, 21, 15, 16, 24, 37, 28, 9, 17, 22, 43, + 5, 11, 26, 46, 34, 52, 19, 20, 32, 47, 55, 31, + 23, 8, 50, 51, 14, 42, 2, 29, 49, 44, 0, 10, + + 11, 47, 39, 55, 52, 27, 41, 18, 20, 5, 38, 54, + 50, 17, 35, 29, 30, 7, 51, 42, 23, 0, 36, 2, + 19, 25, 40, 31, 48, 13, 33, 34, 46, 4, 12, 45, + 37, 22, 9, 10, 28, 1, 16, 43, 8, 3, 14, 24, + + 18, 54, 46, 5, 6, 34, 48, 25, 27, 12, 45, 4, + 2, 24, 42, 36, 37, 14, 3, 49, 30, 7, 43, 9, + 26, 32, 47, 38, 55, 20, 40, 41, 53, 11, 19, 52, + 44, 29, 16, 17, 35, 8, 23, 50, 15, 10, 21, 0, + + 32, 11, 31, 19, 20, 48, 5, 39, 41, 26, 6, 18, + 16, 7, 1, 50, 51, 28, 17, 8, 44, 21, 2, 23, + 40, 46, 4, 52, 12, 34, 54, 55, 38, 25, 33, 13, + 3, 43, 30, 0, 49, 22, 37, 9, 29, 24, 35, 14, + + 46, 25, 45, 33, 34, 5, 19, 53, 55, 40, 20, 32, + 30, 21, 15, 9, 10, 42, 0, 22, 3, 35, 16, 37, + 54, 31, 18, 13, 26, 48, 11, 12, 52, 39, 47, 27, + 17, 2, 44, 14, 8, 36, 51, 23, 43, 7, 49, 28, + + 31, 39, 6, 47, 48, 19, 33, 38, 12, 54, 34, 46, + 44, 35, 29, 23, 24, 1, 14, 36, 17, 49, 30, 51, + 11, 45, 32, 27, 40, 5, 25, 26, 13, 53, 4, 41, + 0, 16, 3, 28, 22, 50, 10, 37, 2, 21, 8, 42, + + 45, 53, 20, 4, 5, 33, 47, 52, 26, 11, 48, 31, + 3, 49, 43, 37, 7, 15, 28, 50, 0, 8, 44, 10, + 25, 6, 46, 41, 54, 19, 39, 40, 27, 38, 18, 55, + 14, 30, 17, 42, 36, 9, 24, 51, 16, 35, 22, 1, + + 6, 38, 34, 18, 19, 47, 4, 13, 40, 25, 5, 45, + 17, 8, 2, 51, 21, 29, 42, 9, 14, 22, 3, 24, + 39, 20, 31, 55, 11, 33, 53, 54, 41, 52, 32, 12, + 28, 44, 0, 1, 50, 23, 7, 10, 30, 49, 36, 15, + + 20, 52, 48, 32, 33, 4, 18, 27, 54, 39, 19, 6, + 0, 22, 16, 10, 35, 43, 1, 23, 28, 36, 17, 7, + 53, 34, 45, 12, 25, 47, 38, 11, 55, 13, 46, 26, + 42, 3, 14, 15, 9, 37, 21, 24, 44, 8, 50, 29, + + 27, 6, 55, 39, 40, 11, 25, 34, 4, 46, 26, 13, + 7, 29, 23, 17, 42, 50, 8, 30, 35, 43, 24, 14, + 31, 41, 52, 19, 32, 54, 45, 18, 5, 20, 53, 33, + 49, 10, 21, 22, 16, 44, 28, 0, 51, 15, 2, 36, +}; + +static char parity[] = { +8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3, +0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8, +0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8, +8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0, +0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8, +8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0, +8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0, +4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8, +}; + +/* set up the method list from the key */ + +int des_set_key(struct cipher_context *cx, + u8 *key, int keybytes) +{ + register u32 n, w; + register char * b0, * b1; + char bits0[56], bits1[56]; + u32 *method; + + method=(u32 *)cx->keyinfo; + + if(keybytes<8) + return -EINVAL; + + /* check for bad parity and weak keys */ + b0 = parity; + n = b0[key[0]]; n <<= 4; + n |= b0[key[1]]; n <<= 4; + n |= b0[key[2]]; n <<= 4; + n |= b0[key[3]]; n <<= 4; + n |= b0[key[4]]; n <<= 4; + n |= b0[key[5]]; n <<= 4; + n |= b0[key[6]]; n <<= 4; + n |= b0[key[7]]; + w = 0X88888888L; + /* report bad parity in key */ + if ( n & w ) + return -1; + /* report a weak or semi-weak key */ + if ( !((n - (w >> 3)) & w) ) { /* 1 in 10^10 keys passes this test */ + if ( n < 0X41415151 ) { + if ( n < 0X31312121 ) { + if ( n < 0X14141515 ) { + /* 01 01 01 01 01 01 01 01 */ + if ( n == 0X11111111 ) return -2; + /* 01 1F 01 1F 01 0E 01 0E */ + if ( n == 0X13131212 ) return -2; + } else { + /* 01 E0 01 E0 01 F1 01 F1 */ + if ( n == 0X14141515 ) return -2; + /* 01 FE 01 FE 01 FE 01 FE */ + if ( n == 0X16161616 ) return -2; + } + } else { + if ( n < 0X34342525 ) { + /* 1F 01 1F 01 0E 01 0E 01 */ + if ( n == 0X31312121 ) return -2; + /* 1F 1F 1F 1F 0E 0E 0E 0E */ /* ? */ + if ( n == 0X33332222 ) return -2; + } else { + /* 1F E0 1F E0 0E F1 0E F1 */ + if ( n == 0X34342525 ) return -2; + /* 1F FE 1F FE 0E FE 0E FE */ + if ( n == 0X36362626 ) return -2; + } + } + } else { + if ( n < 0X61616161 ) { + if ( n < 0X44445555 ) { + /* E0 01 E0 01 F1 01 F1 01 */ + if ( n == 0X41415151 ) return -2; + /* E0 1F E0 1F F1 0E F1 0E */ + if ( n == 0X43435252 ) return -2; + } else { + /* E0 E0 E0 E0 F1 F1 F1 F1 */ /* ? */ + if ( n == 0X44445555 ) return -2; + /* E0 FE E0 FE F1 FE F1 FE */ + if ( n == 0X46465656 ) return -2; + } + } else { + if ( n < 0X64646565 ) { + /* FE 01 FE 01 FE 01 FE 01 */ + if ( n == 0X61616161 ) return -2; + /* FE 1F FE 1F FE 0E FE 0E */ + if ( n == 0X63636262 ) return -2; + } else { + /* FE E0 FE E0 FE F1 FE F1 */ + if ( n == 0X64646565 ) return -2; + /* FE FE FE FE FE FE FE FE */ + if ( n == 0X66666666 ) return -2; + } + } + } + } + + /* explode the bits */ + n = 56; + b0 = bits0; + b1 = bits1; + do { + w = (256 | *key++) << 2; + do { + --n; + b1[n] = 8 & w; + w >>= 1; + b0[n] = 4 & w; + } while ( w >= 16 ); + } while ( n ); + + /* put the bits in the correct places */ + n = 16; + key = rotors; + do { + w = (b1[key[ 0 ]] | b0[key[ 1 ]]) << 4; + w |= (b1[key[ 2 ]] | b0[key[ 3 ]]) << 2; + w |= b1[key[ 4 ]] | b0[key[ 5 ]]; + w <<= 8; + w |= (b1[key[ 6 ]] | b0[key[ 7 ]]) << 4; + w |= (b1[key[ 8 ]] | b0[key[ 9 ]]) << 2; + w |= b1[key[10 ]] | b0[key[11 ]]; + w <<= 8; + w |= (b1[key[12 ]] | b0[key[13 ]]) << 4; + w |= (b1[key[14 ]] | b0[key[15 ]]) << 2; + w |= b1[key[16 ]] | b0[key[17 ]]; + w <<= 8; + w |= (b1[key[18 ]] | b0[key[19 ]]) << 4; + w |= (b1[key[20 ]] | b0[key[21 ]]) << 2; + w |= b1[key[22 ]] | b0[key[23 ]]; + + method[0] = w; + + w = (b1[key[ 0+24]] | b0[key[ 1+24]]) << 4; + w |= (b1[key[ 2+24]] | b0[key[ 3+24]]) << 2; + w |= b1[key[ 4+24]] | b0[key[ 5+24]]; + w <<= 8; + w |= (b1[key[ 6+24]] | b0[key[ 7+24]]) << 4; + w |= (b1[key[ 8+24]] | b0[key[ 9+24]]) << 2; + w |= b1[key[10+24]] | b0[key[11+24]]; + w <<= 8; + w |= (b1[key[12+24]] | b0[key[13+24]]) << 4; + w |= (b1[key[14+24]] | b0[key[15+24]]) << 2; + w |= b1[key[16+24]] | b0[key[17+24]]; + w <<= 8; + w |= (b1[key[18+24]] | b0[key[19+24]]) << 4; + w |= (b1[key[20+24]] | b0[key[21+24]]) << 2; + w |= b1[key[22+24]] | b0[key[23+24]]; + + ROR(w, 4, 28); /* could be eliminated */ + method[1] = w; + + key += 48; + method += 2; + } while ( --n ); + return 0; +} + + +void DesSmallFipsEncrypt (DesData d, DesKeys r, DesData s) +{ + register u32 x, y, z; + + x = s [7]; + x <<= 8; + x |= s [6]; + x <<= 8; + x |= s [5]; + x <<= 8; + x |= s [4]; + y = s [3]; + y <<= 8; + y |= s [2]; + y <<= 8; + y |= s [1]; + y <<= 8; + y |= s [0]; + z = ((x >> 004) ^ y) & 0X0F0F0F0FL; + x ^= z << 004; + y ^= z; + z = ((y >> 020) ^ x) & 0X0000FFFFL; + y ^= z << 020; + x ^= z; + z = ((x >> 002) ^ y) & 0X33333333L; + x ^= z << 002; + y ^= z; + z = ((y >> 010) ^ x) & 0X00FF00FFL; + y ^= z << 010; + x ^= z; + x = x >> 1 | x << 31; + z = (x ^ y) & 0X55555555L; + y ^= z; + x ^= z; + y = y >> 1 | y << 31; + z = r [0]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [1]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [2]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [3]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [4]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [5]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [6]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [7]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [8]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [9]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [10]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [11]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [12]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [13]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [14]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [15]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [16]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [17]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [18]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [19]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [20]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [21]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [22]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [23]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [24]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [25]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [26]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [27]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [28]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [29]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [30]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [31]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + x = x << 1 | x >> 31; + z = (x ^ y) & 0X55555555L; + y ^= z; + x ^= z; + y = y << 1 | y >> 31; + z = ((x >> 010) ^ y) & 0X00FF00FFL; + x ^= z << 010; + y ^= z; + z = ((y >> 002) ^ x) & 0X33333333L; + y ^= z << 002; + x ^= z; + z = ((x >> 020) ^ y) & 0X0000FFFFL; + x ^= z << 020; + y ^= z; + z = ((y >> 004) ^ x) & 0X0F0F0F0FL; + y ^= z << 004; + x ^= z; + d [0] = x; + x >>= 8; + d [1] = x; + x >>= 8; + d [2] = x; + x >>= 8; + d [3] = x; + d [4] = y; + y >>= 8; + d [5] = y; + y >>= 8; + d [6] = y; + y >>= 8; + d [7] = y; + return; +} + +void DesSmallFipsDecrypt (u8 *d, u32 *r, u8 *s) +{ + register u32 x, y, z; + x = s [7]; + x <<= 8; + x |= s [6]; + x <<= 8; + x |= s [5]; + x <<= 8; + x |= s [4]; + y = s [3]; + y <<= 8; + y |= s [2]; + y <<= 8; + y |= s [1]; + y <<= 8; + y |= s [0]; + z = ((x >> 004) ^ y) & 0X0F0F0F0FL; + x ^= z << 004; + y ^= z; + z = ((y >> 020) ^ x) & 0X0000FFFFL; + y ^= z << 020; + x ^= z; + z = ((x >> 002) ^ y) & 0X33333333L; + x ^= z << 002; + y ^= z; + z = ((y >> 010) ^ x) & 0X00FF00FFL; + y ^= z << 010; + x ^= z; + x = x >> 1 | x << 31; + z = (x ^ y) & 0X55555555L; + y ^= z; + x ^= z; + y = y >> 1 | y << 31; + z = r [31]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [30]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [29]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [28]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [27]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [26]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [25]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [24]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [23]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [22]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [21]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [20]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [19]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [18]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [17]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [16]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [15]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [14]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [13]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [12]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [11]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [10]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [9]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [8]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [7]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [6]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [5]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [4]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [3]; + z ^= y; + z = z << 4 | z >> 28; + x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [2]; + z ^= y; + x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + x ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + z = r [1]; + z ^= x; + z = z << 4 | z >> 28; + y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0XFC & z)); + z = r [0]; + z ^= x; + y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0XFC & z)); + z >>= 8; + y ^= * (u32 *) ((u8 *) des_keymap + (0XFC & z)); + x = x << 1 | x >> 31; + z = (x ^ y) & 0X55555555L; + y ^= z; + x ^= z; + y = y << 1 | y >> 31; + z = ((x >> 010) ^ y) & 0X00FF00FFL; + x ^= z << 010; + y ^= z; + z = ((y >> 002) ^ x) & 0X33333333L; + y ^= z << 002; + x ^= z; + z = ((x >> 020) ^ y) & 0X0000FFFFL; + x ^= z << 020; + y ^= z; + z = ((y >> 004) ^ x) & 0X0F0F0F0FL; + y ^= z << 004; + x ^= z; + d [0] = x; + x >>= 8; + d [1] = x; + x >>= 8; + d [2] = x; + x >>= 8; + d [3] = x; + d [4] = y; + y >>= 8; + d [5] = y; + y >>= 8; + d [6] = y; + y >>= 8; + d [7] = y; + return; +} + +int des_encrypt(struct cipher_context *cx, + u32 *in_blk, u32 *out_blk, int size) +{ + u8 input_buffer[8]; + u8 output_buffer[8]; + u32 n; + + for (; size >= 8; size -= 8) + { + n=*in_blk++; + input_buffer[0]=n & 0xff; + n>>=8; + input_buffer[1]=n & 0xff; + n>>=8; + input_buffer[2]=n & 0xff; + n>>=8; + input_buffer[3]=n & 0xff; + + n=*in_blk++; + input_buffer[4]=n & 0xff; + n>>=8; + input_buffer[5]=n & 0xff; + n>>=8; + input_buffer[6]=n & 0xff; + n>>=8; + input_buffer[7]=n & 0xff; + + DesSmallFipsEncrypt(output_buffer,cx->keyinfo,input_buffer); + + n=0; + n|=output_buffer[3]; + n<<=8; + n|=output_buffer[2]; + n<<=8; + n|=output_buffer[1]; + n<<=8; + n|=output_buffer[0]; + + *out_blk++=n; + + n=0; + n|=output_buffer[7]; + n<<=8; + n|=output_buffer[6]; + n<<=8; + n|=output_buffer[5]; + n<<=8; + n|=output_buffer[4]; + + *out_blk++=n; + } + return 0; +} + +int des_decrypt(struct cipher_context *cx, + u32 *in_blk, u32 *out_blk, int size) +{ + u8 input_buffer[8]; + u8 output_buffer[8]; + u32 n; + + for (; size >= 8; size -= 8) + { + n=*in_blk++; + input_buffer[0]=n & 0xff; + n>>=8; + input_buffer[1]=n & 0xff; + n>>=8; + input_buffer[2]=n & 0xff; + n>>=8; + input_buffer[3]=n & 0xff; + + n=*in_blk++; + input_buffer[4]=n & 0xff; + n>>=8; + input_buffer[5]=n & 0xff; + n>>=8; + input_buffer[6]=n & 0xff; + n>>=8; + input_buffer[7]=n & 0xff; + + DesSmallFipsDecrypt(output_buffer,cx->keyinfo,input_buffer); + + n=0; + n|=output_buffer[3]; + n<<=8; + n|=output_buffer[2]; + n<<=8; + n|=output_buffer[1]; + n<<=8; + n|=output_buffer[0]; + + *out_blk++=n; + + n=0; + n|=output_buffer[7]; + n<<=8; + n|=output_buffer[6]; + n<<=8; + n|=output_buffer[5]; + n<<=8; + n|=output_buffer[4]; + + *out_blk++=n; + } + return 0; +} + +static void des_lock(void) +{ + MOD_INC_USE_COUNT; +} + +static void des_unlock(void) +{ + MOD_DEC_USE_COUNT; +} + + +#define CIPHER_BITS_64 +#define CIPHER_NAME(x) des##x +#include "gen-cbc.h" + +DEFINE_CIPHER(DES, des, "des", 8, 8); +DEFINE_CBC_CIPHER(DES, des, "des-cbc", 8); + +#ifdef MODULE +int __init init_module(void) +#else +int __init init_des(void) +#endif +{ + if (register_cipher(&des)) + printk(KERN_WARNING "Couldn't register des encryption\n"); + if (register_cipher(&cbc_des)) + printk(KERN_WARNING "Couldn't register des-cbc encryption\n"); + + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + if (unregister_cipher(&des)) + printk(KERN_WARNING "Couldn't unregister des encryption\n"); + if (unregister_cipher(&cbc_des)) + printk(KERN_WARNING "Couldn't unregister des-cbc encryption\n"); +} +#endif diff -ruN linux-2.2.5,pristine/crypto/dfc2.c linux-2.2.5/crypto/dfc2.c --- linux-2.2.5,pristine/crypto/dfc2.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/dfc2.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,460 @@ +/* NOTE: This implementation has been changed from the original + source. See ChangeLog for more information. + Maintained by Alexander Kjeldaas + */ + +/* This is an independent implementation of the DFC encryption */ +/* algorithm designed by a team at CNRS and France Telecom and */ +/* submitted as a candidate in the US NIST Advanced Encryption */ +/* Standard (AES) programme. */ +/* */ +/* Copyright in this implementation is held by Dr B R Gladman but */ +/* I hereby give permission for its free direct or derivative use */ +/* subject to acknowledgment of its origin and compliance with any */ +/* conditions that the originators of DFC place on its use. */ +/* */ +/* My thanks go to Serge Vaudenay of the Ecole Normale Superieure */ +/* for providing test vectors. This implementation has also been */ +/* tested with an independent implementation by Dr Russell Bradford */ +/* (Department of Mathematical Sciences, University of Bath, Bath, */ +/* UK) and checks out. My thanks go to Russell for his help in */ +/* comparing our implementations and finding bugs (and for help in */ +/* resolving 'endian' issues before test vectors became available). */ +/* */ +/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 27th July 1998 */ +/* */ + +/* The EES string is as follows (the abstract contains an error in + the last line of this sequence which changes KC and KD): + + 0xb7e15162, 0x8aed2a6a, 0xbf715880, 0x9cf4f3c7, + 0x62e7160f, 0x38b4da56, 0xa784d904, 0x5190cfef, + 0x324e7738, 0x926cfbe5, 0xf4bf8d8d, 0x8c31d763, + 0xda06c80a, 0xbb1185eb, 0x4f7c7b57, 0x57f59584, + + 0x90cfd47d, 0x7c19bb42, 0x158d9554, 0xf7b46bce, + 0xd55c4d79, 0xfd5f24d6, 0x613c31c3, 0x839a2ddf, + 0x8a9a276b, 0xcfbfa1c8, 0x77c56284, 0xdab79cd4, + 0xc2b3293d, 0x20e9e5ea, 0xf02ac60a, 0xcc93ed87, + + 0x4422a52e, 0xcb238fee, 0xe5ab6add, 0x835fd1a0, + 0x753d0a8f, 0x78e537d2, 0xb95bb79d, 0x8dcaec64, + 0x2c1e9f23, 0xb829b5c2, 0x780bf387, 0x37df8bb3, + 0x00d01334, 0xa0d0bd86, 0x45cbfa73, 0xa6160ffe, + + 0x393c48cb, 0xbbca060f, 0x0ff8ec6d, 0x31beb5cc, + 0xeed7f2f0, 0xbb088017, 0x163bc60d, 0xf45a0ecb, + 0x1bcd289b, 0x06cbbfea, 0x21ad08e1, 0x847f3f73, + 0x78d56ced, 0x94640d6e, 0xf0d3d37b, 0xe67008e1, + + 0x86d1bf27, 0x5b9b241d, 0xeb64749a, 0x47dfdfb9, + + Where: + + EES = RT(0) | RT(1) | ... | RT(63) | KD | KC + + Note that the abstract describing DFC is written + in big endian notation with the most significant + digits of a sequence of digits placed at the low + index positions in arrays. This format is used + here and is only converted to machine format at + the point that maths is done on any numbers in + the round function. + + The key input is thus treated as an array of 32 + bit words numbered from 0..3, 0..5 or 0..7 + depending on key length. The first (leftmost) + bit of this key string as defined in the DFC + abstract is the most significant bit of word 0 + and the rightmost bit of this string is the least + signicant bit of the highest numbered key word. + + The input and output blocks for the cipher are + also treated as arrays of 32 bit words numbered + from 0..3. The most significant bit of word 0 is + the 1st (leftmost) bit of the 128 bit input string + and the least significant bit of word 3 is the + last (rightmost) bit. + + Note that the inputs, the output and the key are + in Intel little endian format when BYTE_SWAP is + defined + +Timing data: + +Algorithm: dfc (dfc2.c) +128 bit key: +Key Setup: 7373 cycles +Encrypt: 1748 cycles = 14.6 mbits/sec +Decrypt: 1755 cycles = 14.6 mbits/sec +Mean: 1752 cycles = 14.6 mbits/sec +192 bit key: +Key Setup: 7359 cycles +Encrypt: 1757 cycles = 14.6 mbits/sec +Decrypt: 1765 cycles = 14.5 mbits/sec +Mean: 1761 cycles = 14.5 mbits/sec +256 bit key: +Key Setup: 7320 cycles +Encrypt: 1750 cycles = 14.6 mbits/sec +Decrypt: 1749 cycles = 14.6 mbits/sec +Mean: 1749 cycles = 14.6 mbits/sec + +*/ + +#include +#include +#include +#include +#include + +#include + +#if 0 +#define rotl rotl32 +#define rotr rotr32 +#else +#define rotl generic_rotl32 +#define rotr generic_rotr32 +#endif + +#define bswap(x) __be32_to_cpu(x) +#define io_swap(x) __cpu_to_be32(x) + +#define BYTE_SWAP + +/* The following arrays are all stored in big endian */ +/* format with 32 bit words at lower array positions */ +/* being more significant in multi-word values */ + +u4byte rt64[64] = +{ + 0xb7e15162, 0x8aed2a6a, 0xbf715880, 0x9cf4f3c7, + 0x62e7160f, 0x38b4da56, 0xa784d904, 0x5190cfef, + 0x324e7738, 0x926cfbe5, 0xf4bf8d8d, 0x8c31d763, + 0xda06c80a, 0xbb1185eb, 0x4f7c7b57, 0x57f59584, + + 0x90cfd47d, 0x7c19bb42, 0x158d9554, 0xf7b46bce, + 0xd55c4d79, 0xfd5f24d6, 0x613c31c3, 0x839a2ddf, + 0x8a9a276b, 0xcfbfa1c8, 0x77c56284, 0xdab79cd4, + 0xc2b3293d, 0x20e9e5ea, 0xf02ac60a, 0xcc93ed87, + + 0x4422a52e, 0xcb238fee, 0xe5ab6add, 0x835fd1a0, + 0x753d0a8f, 0x78e537d2, 0xb95bb79d, 0x8dcaec64, + 0x2c1e9f23, 0xb829b5c2, 0x780bf387, 0x37df8bb3, + 0x00d01334, 0xa0d0bd86, 0x45cbfa73, 0xa6160ffe, + + 0x393c48cb, 0xbbca060f, 0x0ff8ec6d, 0x31beb5cc, + 0xeed7f2f0, 0xbb088017, 0x163bc60d, 0xf45a0ecb, + 0x1bcd289b, 0x06cbbfea, 0x21ad08e1, 0x847f3f73, + 0x78d56ced, 0x94640d6e, 0xf0d3d37b, 0xe67008e1, +}; + +u4byte kc = 0xeb64749a; + +u4byte kd2[2] = +{ + 0x86d1bf27, 0x5b9b241d +}; + +u4byte ka2[6] = +{ + 0xb7e15162, 0x8aed2a6a, + 0xbf715880, 0x9cf4f3c7, + 0x62e7160f, 0x38b4da56, +}; + +u4byte kb2[6] = +{ + 0xa784d904, 0x5190cfef, + 0x324e7738, 0x926cfbe5, + 0xf4bf8d8d, 0x8c31d763, +}; + +u4byte ks8[8] = +{ 0xda06c80a, 0xbb1185eb, 0x4f7c7b57, 0x57f59584, + 0x90cfd47d, 0x7c19bb42, 0x158d9554, 0xf7b46bce, +}; + +#define lo(x) ((x) & 0x0000ffff) +#define hi(x) ((x) >> 16) + +void mult_64(u4byte r[4], const u4byte x[2], const u4byte y[2]) +{ u4byte x0, x1, x2, x3, y0, y1, y2, y3, t0, t1, t2, t3, c; + + x0 = lo(x[1]); x1 = hi(x[1]); x2 = lo(x[0]); x3 = hi(x[0]); + y0 = lo(y[1]); y1 = hi(y[1]); y2 = lo(y[0]); y3 = hi(y[0]); + + t0 = x0 * y0; r[0] = lo(t0); c = hi(t0); + + t0 = x0 * y1; t1 = x1 * y0; c += lo(t0) + lo(t1); + r[0] += (c << 16); c = hi(c) + hi(t0) + hi(t1); + + t0 = x0 * y2; t1 = x1 * y1; t2 = x2 * y0; + c += lo(t0) + lo(t1) + lo(t2); r[1] = lo(c); + c = hi(c) + hi(t0) + hi(t1) + hi(t2); + + t0 = x0 * y3; t1 = x1 * y2; t2 = x2 * y1; t3 = x3 * y0; + c += lo(t0) + lo(t1) + lo(t2) + lo(t3); r[1] += (c << 16); + c = hi(c) + hi(t0) + hi(t1) + hi(t2) + hi(t3); + + t0 = x1 * y3; t1 = x2 * y2; t2 = x3 * y1; + c += lo(t0) + lo(t1) + lo(t2); r[2] = lo(c); + c = hi(c) + hi(t0) + hi(t1) + hi(t2); + + t0 = x2 * y3; t1 = x3 * y2; c += lo(t0) + lo(t1); + r[2] += (c << 16); c = hi(c) + hi(t0) + hi(t1); + + r[3] = c + x3 * y3; +}; + +void add_64(u4byte r[4], const u4byte hi, const u4byte lo) +{ + if((r[0] += lo) < lo) + if(!++r[1]) + if(!++r[2]) + ++r[3]; + + if((r[1] += hi) < hi) + if(!++r[2]) + ++r[3]; +}; + +void mult_13(u4byte r[3]) +{ u4byte c, d; + + c = 13 * lo(r[0]); + d = hi(r[0]); + r[0] = lo(c); + c = hi(c) + 13 * d; + r[0] += (c << 16); + c = hi(c) + 13 * lo(r[1]); + d = hi(r[1]); + r[1] = lo(c); + c = hi(c) + 13 * d; + r[1] += (c << 16); + r[2] = hi(c); +}; + +/* Where necessary this is where conversion from big endian to */ +/* little endian format is performed. Since all the maths is */ +/* little endian care is needed when 64 bit blocks are being */ +/* used to get them in the right order by reversing the order */ +/* in which these are stored. This applies to the key array */ +/* which gives the two values A and B and to the constant KD. */ +/* Since the input and output blocks are big endian we also */ +/* have to invert the order of the 32 bit words in the 64 bit */ +/* blocks being processed. */ + +void r_fun(u4byte outp[2], const u4byte inp[2], const u4byte key[4]) +{ u4byte acc[5], b, t; + + mult_64(acc, inp, key); add_64(acc, key[2], key[3]); + + /* we need the value in the accumulator mod 2^64 + 13 so if */ + /* the accumulator value is hi * 2^64 + lo we need to find */ + /* a k value such that r = hi * 2^64 + lo - k * (2^64 + 13) */ + /* is 0 <= r < 2^64 + 13. We can see that k will be close */ + /* to hi in value - it may equal hi but will not be greater */ + /* and we can let k = hi - e with e >= 0 so that r is given */ + /* by r = e * (2^64 + 13) + lo - 13 * hi. If we compute the */ + /* lo - 13 * hi value, the overflow into the top 64 bits of */ + /* the accumulator has to be 'zeroed' by the e * (2^64 + 13)*/ + /* term and this sets the e value (in fact such an overlow */ + /* is only removed when the lower word is higher than 12). */ + + mult_13(&acc[2]); /* multiply top of accumulator by 13 */ + + /* calculate lo - 13 * hi in acc[0] and acc[1] with any */ + /* overflow into top 64 bits in b */ + + t = acc[0]; acc[0] -= acc[2]; b = (acc[0] > t ? 1 : 0); + + t = acc[1]; acc[1] -= acc[3] + b; + b = (acc[1] > t ? 1 : (acc[1] == t ? b : 0)); + + b = 13 * (acc[4] + b); /* overflow into top 64 bits of acc */ + + if(((acc[0] += b) < b) && !(++acc[1])) + { + if(acc[0] > 12) + + acc[0] -= 13; + } + + /* do the confusion permutation */ + + t = acc[1] ^ kc; b = acc[0] ^ rt64[acc[1] >> 26]; + + b += kd2[0] + ((t += kd2[1]) < kd2[1] ? 1 : 0); + + outp[0] ^= b; outp[1] ^= t; +}; + +int dfc_set_key(struct cipher_context *cx, char *key, int key_len) +{ u4byte *in_key = (u32 *)key; + /* l_key - storage for the key schedule */ + u4byte *l_key = cx->keyinfo; + u4byte i, lk[32], rk[4]; + key_len *= 8; + + for(i = 0; i < key_len / 32; ++i) + + lk[i] = io_swap(in_key[i]); + + /* pad the key with the KS array */ + + for(i = 0; i < 8 - key_len / 32; ++i) /* K|KS */ + + lk[i + key_len / 32] = ks8[i]; + + /* do the reordering of the key parameters */ + /* the OAP[1]|OBP[1]|OAP[2]... sequence is */ + /* at lk[0]... and the other at lk[16]... */ + + lk[18] = lk[5]; lk[19] = lk[2]; /* EBP */ + lk[16] = lk[1]; lk[17] = lk[6]; /* EAP */ + lk[ 2] = lk[4]; lk[ 3] = lk[3]; /* OBP */ + lk[ 0] = lk[0]; lk[ 1] = lk[7]; /* OAP */ + + /* create other elements using KA and KB */ + + for(i = 0; i < 6; i += 2) + { + lk[i + i + 4] = lk[ 0] ^ ka2[i]; /* OAP[i] ms */ + lk[i + i + 5] = lk[ 1] ^ ka2[i + 1]; /* OAP[i] ls */ + lk[i + i + 6] = lk[ 2] ^ kb2[i]; /* OBP[i] ms */ + lk[i + i + 7] = lk[ 3] ^ kb2[i + 1]; /* OBP[i] ls */ + lk[i + i + 20] = lk[16] ^ ka2[i]; /* EAP[i] ms */ + lk[i + i + 21] = lk[17] ^ ka2[i + 1]; /* EAP[i] ls */ + lk[i + i + 22] = lk[18] ^ kb2[i]; /* EBP[i] ms */ + lk[i + i + 23] = lk[19] ^ kb2[i + 1]; /* EBP[i] ls */ + } + + rk[0] = rk[1] = rk[2] = rk[3] = 0; + + /* do the 4 round key mixing encryption */ + + for(i = 0; i < 32; i += 8) + { + r_fun(rk, rk + 2, lk); /* R2|R1 */ + r_fun(rk + 2, rk, lk + 4); /* R2|R3 */ + r_fun(rk, rk + 2, lk + 8); /* R4|R3 */ + r_fun(rk + 2, rk, lk + 12); /* R4|R5 */ + + /* keep key in big endian format with */ + /* the most significant 32 bit words */ + /* first (lowest) in the key schedule */ + /* - note that the upper and lower 64 */ + /* bit blocks are in inverse order at */ + /* this point in the loop */ + + l_key[i + 0] = rk[2]; l_key[i + 1] = rk[3]; + l_key[i + 2] = rk[0]; l_key[i + 3] = rk[1]; + + r_fun(rk + 2, rk, lk + 16); /* R1|R2 */ + r_fun(rk, rk + 2, lk + 20); /* R3|R2 */ + r_fun(rk + 2, rk, lk + 24); /* R3|R4 */ + r_fun(rk, rk + 2, lk + 28); /* R5|R4 */ + + l_key[i + 4] = rk[0]; l_key[i + 5] = rk[1]; + l_key[i + 6] = rk[2]; l_key[i + 7] = rk[3]; + } + + return 0; +}; + +int dfc_encrypt(struct cipher_context *cx, u32 *in_blk, u32 *out_blk, int size) +{ u4byte *l_key = cx->keyinfo; + u4byte blk[4]; + + /* the input/output format is big endian - */ + /* any reversals needed are performed when */ + /* maths is done in the round function */ + + blk[0] = io_swap(in_blk[0]); blk[1] = io_swap(in_blk[1]); + blk[2] = io_swap(in_blk[2]); blk[3] = io_swap(in_blk[3]); + + r_fun(blk, blk + 2, l_key + 0); /* R2|R1 */ + r_fun(blk + 2, blk, l_key + 4); /* R2|R3 */ + r_fun(blk, blk + 2, l_key + 8); /* R4|R3 */ + r_fun(blk + 2, blk, l_key + 12); /* R4|R5 */ + r_fun(blk, blk + 2, l_key + 16); /* R6|R5 */ + r_fun(blk + 2, blk, l_key + 20); /* R6|R7 */ + r_fun(blk, blk + 2, l_key + 24); /* R8|R7 */ + r_fun(blk + 2, blk, l_key + 28); /* R8|R9 */ + + /* swap order to obtain the result R9|R8 */ + + out_blk[0] = io_swap(blk[2]); out_blk[1] = io_swap(blk[3]); + out_blk[2] = io_swap(blk[0]); out_blk[3] = io_swap(blk[1]); + return 0; +}; + +int dfc_decrypt(struct cipher_context *cx, u32 *in_blk, u32 *out_blk, int size) +{ u4byte *l_key = cx->keyinfo; + u4byte blk[4]; + + /* the input/output format is big endian - */ + /* any reversals needed are performed when */ + /* maths is done in the round function */ + + blk[0] = io_swap(in_blk[0]); blk[1] = io_swap(in_blk[1]); + blk[2] = io_swap(in_blk[2]); blk[3] = io_swap(in_blk[3]); + + r_fun(blk, blk + 2, l_key + 28); /* R7|R8 */ + r_fun(blk + 2, blk, l_key + 24); /* R7|R6 */ + r_fun(blk, blk + 2, l_key + 20); /* R5|R6 */ + r_fun(blk + 2, blk, l_key + 16); /* R5|R4 */ + r_fun(blk, blk + 2, l_key + 12); /* R3|R4 */ + r_fun(blk + 2, blk, l_key + 8); /* R3|R2 */ + r_fun(blk, blk + 2, l_key + 4); /* R1|R2 */ + r_fun(blk + 2, blk, l_key ); /* R1|R0 */ + + /* swap order to obtain the result R1|R0 */ + + out_blk[0] = io_swap(blk[2]); out_blk[1] = io_swap(blk[3]); + out_blk[2] = io_swap(blk[0]); out_blk[3] = io_swap(blk[1]); + return 0; +}; + +static void dfc_lock(void) +{ + MOD_INC_USE_COUNT; +} + +static void dfc_unlock(void) +{ + MOD_DEC_USE_COUNT; +} + +#define CIPHER_BITS_128 +#define CIPHER_NAME(x) dfc##x +#include "gen-cbc.h" + +DEFINE_CIPHER(DFC, dfc, "dfc", 16, 16); +DEFINE_CBC_CIPHER(DFC, dfc, "dfc-cbc", 16); + +#ifdef MODULE + int __init init_module(void) +#else + int __init init_dfc(void) +#endif +{ + if (register_cipher(&dfc)) + printk(KERN_WARNING "Couldn't register dfc encryption\n"); + if (register_cipher(&cbc_dfc)) + printk(KERN_WARNING "Couldn't register dfc-cbc encryption\n"); + + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + if (unregister_cipher(&dfc)) + printk(KERN_WARNING "Couldn't unregister dfc encryption\n"); + if (unregister_cipher(&cbc_dfc)) + printk(KERN_WARNING "Couldn't unregister dfc-cbc encryption\n"); +} +#endif + diff -ruN linux-2.2.5,pristine/crypto/gen-cbc.h linux-2.2.5/crypto/gen-cbc.h --- linux-2.2.5,pristine/crypto/gen-cbc.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/gen-cbc.h Thu Apr 1 23:05:45 1999 @@ -0,0 +1,69 @@ + +#include + +#if defined(CIPHER_BITS_128) +# define BS 16 +#else +# define BS 8 +#endif + +int CIPHER_NAME(_cbc_encrypt)(struct cipher_context *cx, + u32 *in_blk, u32 *out_blk, int size) +{ + int i; + u32 *in = in_blk, *out = out_blk; + u32 tmp[BS/4]; + if (BS && (size % BS != 0)) { + memset((char *)out_blk, 0, size); + return 1; + } + tmp[0] = in[0] ^ cx->iv[0]; tmp[1] = in[1] ^ cx->iv[1]; +#ifdef CIPHER_BITS_128 + tmp[2] = in[2] ^ cx->iv[2]; tmp[3] = in[3] ^ cx->iv[3]; +#endif + CIPHER_NAME(_encrypt)(cx, tmp, out, BS); + in += BS/4; out += BS/4; + for (i = BS; i < size; i += BS) { + tmp[0] = in[0] ^ out[0 - BS/4]; + tmp[1] = in[1] ^ out[1 - BS/4]; +#ifdef CIPHER_BITS_128 + tmp[2] = in[2] ^ out[2 - BS/4]; + tmp[3] = in[3] ^ out[3 - BS/4]; +#endif + CIPHER_NAME(_encrypt)(cx, tmp, out, BS); + in += BS/4; out += BS/4; + } + return 0; +} + +int CIPHER_NAME(_cbc_decrypt)(struct cipher_context *cx, + u32 *in_blk, u32 *out_blk, int size) +{ + int i; + u32 *in = in_blk, *out = out_blk; + if (BS && (size % BS != 0)) { + memset((char *)out_blk, 0, size); + return 1; + } + if (size == 0) + return 1; + CIPHER_NAME(_decrypt)(cx, in, out, BS); + out[0] ^= cx->iv[0]; out[1] ^= cx->iv[1]; +#ifdef CIPHER_BITS_128 + out[2] ^= cx->iv[2]; out[3] ^= cx->iv[3]; +#endif + in += BS/4; + out += BS/4; + for (i = BS; i < size; i += BS) { + CIPHER_NAME(_decrypt)(cx, in, out, BS); + out[0] ^= in[0 - BS/4]; out[1] ^= in[1 - BS/4]; +#ifdef CIPHER_BITS_128 + out[2] ^= in[2 - BS/4]; out[3] ^= in[3 - BS/4]; +#endif + in += BS/4; out += BS/4; + } + return 0; +} + + +#undef BS diff -ruN linux-2.2.5,pristine/crypto/idea.c linux-2.2.5/crypto/idea.c --- linux-2.2.5,pristine/crypto/idea.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/idea.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,392 @@ +/* + * idea.c - C source code for IDEA block cipher. + * IDEA (International Data Encryption Algorithm), formerly known as + * IPES (Improved Proposed Encryption Standard). + * Algorithm developed by Xuejia Lai and James L. Massey, of ETH Zurich. + * This implementation modified and derived from original C code + * developed by Xuejia Lai. + * Zero-based indexing added, names changed from IPES to IDEA. + * CFB functions added. Random number routines added. + * + * Extensively optimized and restructured by Colin Plumb. + * + * There are two adjustments that can be made to this code to + * speed it up. Defaults may be used for PCs. Only the -DIDEA32 + * pays off significantly if selectively set or not set. + * Experiment to see what works best for your machine. + * + * Multiplication: default is inline, -DAVOID_JUMPS uses a + * different version that does not do any conditional + * jumps (a few percent worse on a SPARC), while + * -DSMALL_CACHE takes it out of line to stay + * within a small on-chip code cache. + * Variables: normally, 16-bit variables are used, but some + * machines (notably RISCs) do not have 16-bit registers, + * so they do a great deal of masking. -DIDEA32 uses "int" + * register variables and masks explicitly only where + * necessary. On a SPARC, for example, this boosts + * performace by 30%. + * + * The IDEA(tm) block cipher is covered by patents held by ETH and a + * Swiss company called Ascom-Tech AG. The Swiss patent number is + * PCT/CH91/00117, the European patent number is EP 0 482 154 B1, and + * the U.S. patent number is US005214703. IDEA(tm) is a trademark of + * Ascom-Tech AG. There is no license fee required for noncommercial + * use. Commercial users may obtain licensing details from Dieter + * Profos, Ascom Tech AG, Solothurn Lab, Postfach 151, 4502 Solothurn, + * Switzerland, Tel +41 65 242885, Fax +41 65 235761. + * + * The IDEA block cipher uses a 64-bit block size, and a 128-bit key + * size. It breaks the 64-bit cipher block into four 16-bit words + * because all of the primitive inner operations are done with 16-bit + * arithmetic. It likewise breaks the 128-bit cipher key into eight + * 16-bit words. + * + * For further information on the IDEA cipher, see the book: + * Xuejia Lai, "On the Design and Security of Block Ciphers", + * ETH Series on Information Processing (ed. J.L. Massey) Vol 1, + * Hartung-Gorre Verlag, Konstanz, Switzerland, 1992. ISBN + * 3-89191-573-X. + * + * This code runs on arrays of bytes by taking pairs in big-endian + * order to make the 16-bit words that IDEA uses internally. This + * produces the same result regardless of the byte order of the + * native CPU. + */ + +#include +#include +#include +#include +#include +#include + +#define IDEAKEYSIZE 16 +#define IDEABLOCKSIZE 8 + +#define IDEAROUNDS 8 +#define IDEAKEYLEN (6*IDEAROUNDS+4) + +#define low16(x) ((x) & 0xFFFF) +typedef unsigned char byte; + +typedef struct { + u16 ek[IDEAKEYLEN]; + u16 dk[IDEAKEYLEN]; +} IDEA_context; + +#if defined(__mc68000__) || defined (__sparc__) || defined (__PPC__) \ + || (defined(__mips__) && (defined(MIPSEB) || defined (__MIPSEB__)) ) +#define BIG_ENDIAN_HOST 1 +#else +#define LITTLE_ENDIAN_HOST 1 +#endif + +/* + * Compute the multiplicative inverse of x, modulo 65537, using + * Euclid's algorithm. It is unrolled twice to avoid swapping the + * registers each iteration, and some subtracts of t have been changed + * to adds. + */ +static u16 mulInv(u16 x) +{ + u16 t0, t1; + u16 q, y; + + if (x <= 1) + return x; /* 0 and 1 are self-inverse */ + t1 = 0x10001L / x; /* Since x >= 2, this fits into 16 bits */ + y = 0x10001L % x; + if (y == 1) + return low16(1 - t1); + t0 = 1; + do { + q = x / y; + x = x % y; + t0 += q * t1; + if (x == 1) + return t0; + q = y / x; + y = y % x; + t1 += q * t0; + } while (y != 1); + return low16(1 - t1); +} + +/* + * Expand a 128-bit user key to a working encryption key ek + */ +static void ideaExpandKey(byte const *userkey, u16 * ek) +{ + int i, j; + + for (j = 0; j < 8; j++) { + ek[j] = (userkey[0] << 8) + userkey[1]; + userkey += 2; + } + for (i = 0; j < IDEAKEYLEN; j++) { + i++; + ek[i + 7] = ek[i & 7] << 9 | ek[(i + 1) & 7] >> 7; + ek += i & 8; + i &= 7; + } +} + +/* + * Compute IDEA decryption key dk from an expanded IDEA encryption key + * ek Note that the input and output may be the same. Thus, the key + * is inverted into an internal buffer, and then copied to the output. + */ +static void ideaInvertKey(u16 const *ek, u16 dk[IDEAKEYLEN]) +{ + int i; + u16 t1, t2, t3; + u16 temp[IDEAKEYLEN]; + u16 *p = temp + IDEAKEYLEN; + + t1 = mulInv(*ek++); + t2 = -*ek++; + t3 = -*ek++; + *--p = mulInv(*ek++); + *--p = t3; + *--p = t2; + *--p = t1; + + for (i = 0; i < IDEAROUNDS - 1; i++) { + t1 = *ek++; + *--p = *ek++; + *--p = t1; + + t1 = mulInv(*ek++); + t2 = -*ek++; + t3 = -*ek++; + *--p = mulInv(*ek++); + *--p = t2; + *--p = t3; + *--p = t1; + } + t1 = *ek++; + *--p = *ek++; + *--p = t1; + + t1 = mulInv(*ek++); + t2 = -*ek++; + t3 = -*ek++; + *--p = mulInv(*ek++); + *--p = t3; + *--p = t2; + *--p = t1; + /* Copy and destroy temp copy */ + memcpy(dk, temp, sizeof(temp)); + memset(&temp,0,sizeof(temp)); +} + +/* IDEA encryption/decryption algorithm */ +/* Note that in and out can be the same buffer */ +static void ideaCipher(u16 const inbuf[4], u16 outbuf[4], + u16 const *key) +{ + register u16 x1, x2, x3, x4, s2, s3; + u16 *in, *out; + register u16 t16; /* Temporaries needed by MUL macro */ + register u32 t32; + int r = IDEAROUNDS; +#define MUL(x,y) \ + ((t16 = (y)) ? \ + (x=low16(x)) ? \ + t32 = (u32)x*t16, \ + x = low16(t32), \ + t16 = t32>>16, \ + x = (x-t16)+(x> 8) | (x1 << 8); + x2 = (x2 >> 8) | (x2 << 8); + x3 = (x3 >> 8) | (x3 << 8); + x4 = (x4 >> 8) | (x4 << 8); +#endif + do { + MUL(x1, *key++); + x2 += *key++; + x3 += *key++; + MUL(x4, *key++); + + s3 = x3; + x3 ^= x1; + MUL(x3, *key++); + s2 = x2; + x2 ^= x4; + x2 += x3; + MUL(x2, *key++); + x3 += x2; + + x1 ^= x2; + x4 ^= x3; + + x2 ^= s3; + x3 ^= s2; + } while (--r); + MUL(x1, *key++); + x3 += *key++; + x2 += *key++; + MUL(x4, *key); + + out = (u16 *) outbuf; +#ifdef LITTLE_ENDIAN_HOST + *out++ = x1; + *out++ = x3; + *out++ = x2; + *out = x4; +#else + x1 = low16(x1); + x2 = low16(x2); + x3 = low16(x3); + x4 = low16(x4); + *out++ = (x1 >> 8) | (x1 << 8); + *out++ = (x3 >> 8) | (x3 << 8); + *out++ = (x2 >> 8) | (x2 << 8); + *out = (x4 >> 8) | (x4 << 8); +#endif +} + +int idea_encrypt(struct cipher_context *cx, + u32 *in_blk, u32 *out_blk, int size) +{ + IDEA_context *c=(IDEA_context *)cx->keyinfo; + + u16 input_buffer[4]; + u16 output_buffer[4]; + u32 n; + + for (; size >= 8; size -= 8) + { + n=*in_blk++; + input_buffer[0]=n & 0xffff; + n=n>>16; + input_buffer[1]=n & 0xffff; + + n=*in_blk++; + input_buffer[2]=n & 0xffff; + n=n>>16; + input_buffer[3]=n & 0xffff; + + ideaCipher( input_buffer,output_buffer, c->ek ); + + n=0; + n|=output_buffer[1]; + n=n<<16; + n|=output_buffer[0]; + + *out_blk++=n; + + n=0; + n|=output_buffer[3]; + n=n<<16; + n|=output_buffer[2]; + + *out_blk++=n; + } + return 0; +} + +int idea_decrypt(struct cipher_context *cx, + u32 *in_blk, u32 *out_blk, int size) +{ + IDEA_context *c=(IDEA_context *)cx->keyinfo; + + u16 input_buffer[8]; + u16 output_buffer[8]; + u32 n; + + for (; size >= 8; size -= 8) + { + n=*in_blk++; + input_buffer[0]=n & 0xffff; + n=n>>16; + input_buffer[1]=n & 0xffff; + + n=*in_blk++; + input_buffer[2]=n & 0xffff; + n=n>>16; + input_buffer[3]=n & 0xffff; + + ideaCipher( input_buffer,output_buffer, c->dk ); + + n=0; + n|=output_buffer[1]; + n=n<<16; + n|=output_buffer[0]; + + *out_blk++=n; + + n=0; + n|=output_buffer[3]; + n=n<<16; + n|=output_buffer[2]; + + *out_blk++=n; + } + return 0; +} + +int idea_set_key(struct cipher_context *cx, + char *key, int keybytes) +{ + IDEA_context *c=(IDEA_context *)cx->keyinfo; + + if(keybytes != 16) + return -EINVAL; + + ideaExpandKey(key, c->ek); + ideaInvertKey(c->ek, c->dk); + return 0; +} + +static void idea_lock(void) +{ + MOD_INC_USE_COUNT; +} + +static void idea_unlock(void) +{ + MOD_DEC_USE_COUNT; +} + +#define CIPHER_BITS_64 +#define CIPHER_NAME(x) idea##x +#include "gen-cbc.h" + +DEFINE_CIPHER(IDEA, idea, "idea", 8, 8); +DEFINE_CBC_CIPHER(IDEA, idea, "idea-cbc", 8); + +#ifdef MODULE +int __init init_module(void) +#else +int __init init_idea(void) +#endif +{ + if (register_cipher(&idea)) + printk(KERN_WARNING "Couldn't register idea encryption\n"); + if (register_cipher(&cbc_idea)) + printk(KERN_WARNING "Couldn't register idea-cbc encryption\n"); + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + if (unregister_cipher(&idea)) + printk(KERN_WARNING "Couldn't unregister idea encryption\n"); + if (unregister_cipher(&cbc_idea)) + printk(KERN_WARNING "Couldn't unregister idea-cbc encryption\n"); +} +#endif diff -ruN linux-2.2.5,pristine/crypto/mars6.c linux-2.2.5/crypto/mars6.c --- linux-2.2.5,pristine/crypto/mars6.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/mars6.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,450 @@ +/* NOTE: This implementation has been changed from the original + source. See ChangeLog for more information. + Maintained by Alexander Kjeldaas + Oops.. this isn't reentrant yet. + */ + +/* This is an independent implementation of the MARS encryption */ +/* algorithm designed by a team at IBM as a candidate for the US */ +/* NIST Advanced Encryption Standard (AES) effort. The algorithm */ +/* is subject to Patent action by IBM, who intend to offer royalty */ +/* free use if a Patent is granted. */ +/* */ +/* Copyright in this implementation is held by Dr B R Gladman but */ +/* I hereby give permission for its free direct or derivative use */ +/* subject to acknowledgment of its origin and compliance with any */ +/* constraints that IBM place on the use of the MARS algorithm. */ +/* */ +/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 4th October 1998 */ +/* */ +/* Timing data: + +Algorithm: mars (mars6.c) +128 bit key: +Key Setup: 4329 cycles +Encrypt: 383 cycles = 66.8 mbits/sec +Decrypt: 374 cycles = 68.4 mbits/sec +Mean: 379 cycles = 67.6 mbits/sec +192 bit key: +Key Setup: 4414 cycles +Encrypt: 379 cycles = 67.5 mbits/sec +Decrypt: 382 cycles = 67.0 mbits/sec +Mean: 381 cycles = 67.3 mbits/sec +256 bit key: +Key Setup: 4351 cycles +Encrypt: 387 cycles = 66.2 mbits/sec +Decrypt: 367 cycles = 69.8 mbits/sec +Mean: 377 cycles = 68.0 mbits/sec + +*/ + +#include +#include +#include +#include +#include + +#if 0 +#define rotl rotl32 +#define rotr rotr32 +#else +#define rotl generic_rotl32 +#define rotr generic_rotr32 +#endif + +static u4byte s_box[] = +{ + 0x09d0c479, 0x28c8ffe0, 0x84aa6c39, 0x9dad7287, /* 0x000 */ + 0x7dff9be3, 0xd4268361, 0xc96da1d4, 0x7974cc93, + 0x85d0582e, 0x2a4b5705, 0x1ca16a62, 0xc3bd279d, + 0x0f1f25e5, 0x5160372f, 0xc695c1fb, 0x4d7ff1e4, + 0xae5f6bf4, 0x0d72ee46, 0xff23de8a, 0xb1cf8e83, /* 0x010 */ + 0xf14902e2, 0x3e981e42, 0x8bf53eb6, 0x7f4bf8ac, + 0x83631f83, 0x25970205, 0x76afe784, 0x3a7931d4, + 0x4f846450, 0x5c64c3f6, 0x210a5f18, 0xc6986a26, + 0x28f4e826, 0x3a60a81c, 0xd340a664, 0x7ea820c4, /* 0x020 */ + 0x526687c5, 0x7eddd12b, 0x32a11d1d, 0x9c9ef086, + 0x80f6e831, 0xab6f04ad, 0x56fb9b53, 0x8b2e095c, + 0xb68556ae, 0xd2250b0d, 0x294a7721, 0xe21fb253, + 0xae136749, 0xe82aae86, 0x93365104, 0x99404a66, /* 0x030 */ + 0x78a784dc, 0xb69ba84b, 0x04046793, 0x23db5c1e, + 0x46cae1d6, 0x2fe28134, 0x5a223942, 0x1863cd5b, + 0xc190c6e3, 0x07dfb846, 0x6eb88816, 0x2d0dcc4a, + 0xa4ccae59, 0x3798670d, 0xcbfa9493, 0x4f481d45, /* 0x040 */ + 0xeafc8ca8, 0xdb1129d6, 0xb0449e20, 0x0f5407fb, + 0x6167d9a8, 0xd1f45763, 0x4daa96c3, 0x3bec5958, + 0xababa014, 0xb6ccd201, 0x38d6279f, 0x02682215, + 0x8f376cd5, 0x092c237e, 0xbfc56593, 0x32889d2c, /* 0x050 */ + 0x854b3e95, 0x05bb9b43, 0x7dcd5dcd, 0xa02e926c, + 0xfae527e5, 0x36a1c330, 0x3412e1ae, 0xf257f462, + 0x3c4f1d71, 0x30a2e809, 0x68e5f551, 0x9c61ba44, + 0x5ded0ab8, 0x75ce09c8, 0x9654f93e, 0x698c0cca, /* 0x060 */ + 0x243cb3e4, 0x2b062b97, 0x0f3b8d9e, 0x00e050df, + 0xfc5d6166, 0xe35f9288, 0xc079550d, 0x0591aee8, + 0x8e531e74, 0x75fe3578, 0x2f6d829a, 0xf60b21ae, + 0x95e8eb8d, 0x6699486b, 0x901d7d9b, 0xfd6d6e31, /* 0x070 */ + 0x1090acef, 0xe0670dd8, 0xdab2e692, 0xcd6d4365, + 0xe5393514, 0x3af345f0, 0x6241fc4d, 0x460da3a3, + 0x7bcf3729, 0x8bf1d1e0, 0x14aac070, 0x1587ed55, + 0x3afd7d3e, 0xd2f29e01, 0x29a9d1f6, 0xefb10c53, /* 0x080 */ + 0xcf3b870f, 0xb414935c, 0x664465ed, 0x024acac7, + 0x59a744c1, 0x1d2936a7, 0xdc580aa6, 0xcf574ca8, + 0x040a7a10, 0x6cd81807, 0x8a98be4c, 0xaccea063, + 0xc33e92b5, 0xd1e0e03d, 0xb322517e, 0x2092bd13, /* 0x090 */ + 0x386b2c4a, 0x52e8dd58, 0x58656dfb, 0x50820371, + 0x41811896, 0xe337ef7e, 0xd39fb119, 0xc97f0df6, + 0x68fea01b, 0xa150a6e5, 0x55258962, 0xeb6ff41b, + 0xd7c9cd7a, 0xa619cd9e, 0xbcf09576, 0x2672c073, /* 0x0a0 */ + 0xf003fb3c, 0x4ab7a50b, 0x1484126a, 0x487ba9b1, + 0xa64fc9c6, 0xf6957d49, 0x38b06a75, 0xdd805fcd, + 0x63d094cf, 0xf51c999e, 0x1aa4d343, 0xb8495294, + 0xce9f8e99, 0xbffcd770, 0xc7c275cc, 0x378453a7, /* 0x0b0 */ + 0x7b21be33, 0x397f41bd, 0x4e94d131, 0x92cc1f98, + 0x5915ea51, 0x99f861b7, 0xc9980a88, 0x1d74fd5f, + 0xb0a495f8, 0x614deed0, 0xb5778eea, 0x5941792d, + 0xfa90c1f8, 0x33f824b4, 0xc4965372, 0x3ff6d550, /* 0x0c0 */ + 0x4ca5fec0, 0x8630e964, 0x5b3fbbd6, 0x7da26a48, + 0xb203231a, 0x04297514, 0x2d639306, 0x2eb13149, + 0x16a45272, 0x532459a0, 0x8e5f4872, 0xf966c7d9, + 0x07128dc0, 0x0d44db62, 0xafc8d52d, 0x06316131, /* 0x0d0 */ + 0xd838e7ce, 0x1bc41d00, 0x3a2e8c0f, 0xea83837e, + 0xb984737d, 0x13ba4891, 0xc4f8b949, 0xa6d6acb3, + 0xa215cdce, 0x8359838b, 0x6bd1aa31, 0xf579dd52, + 0x21b93f93, 0xf5176781, 0x187dfdde, 0xe94aeb76, /* 0x0e0 */ + 0x2b38fd54, 0x431de1da, 0xab394825, 0x9ad3048f, + 0xdfea32aa, 0x659473e3, 0x623f7863, 0xf3346c59, + 0xab3ab685, 0x3346a90b, 0x6b56443e, 0xc6de01f8, + 0x8d421fc0, 0x9b0ed10c, 0x88f1a1e9, 0x54c1f029, /* 0x0f0 */ + 0x7dead57b, 0x8d7ba426, 0x4cf5178a, 0x551a7cca, + 0x1a9a5f08, 0xfcd651b9, 0x25605182, 0xe11fc6c3, + 0xb6fd9676, 0x337b3027, 0xb7c8eb14, 0x9e5fd030, + + 0x6b57e354, 0xad913cf7, 0x7e16688d, 0x58872a69, /* 0x100 */ + 0x2c2fc7df, 0xe389ccc6, 0x30738df1, 0x0824a734, + 0xe1797a8b, 0xa4a8d57b, 0x5b5d193b, 0xc8a8309b, + 0x73f9a978, 0x73398d32, 0x0f59573e, 0xe9df2b03, + 0xe8a5b6c8, 0x848d0704, 0x98df93c2, 0x720a1dc3, /* 0x110 */ + 0x684f259a, 0x943ba848, 0xa6370152, 0x863b5ea3, + 0xd17b978b, 0x6d9b58ef, 0x0a700dd4, 0xa73d36bf, + 0x8e6a0829, 0x8695bc14, 0xe35b3447, 0x933ac568, + 0x8894b022, 0x2f511c27, 0xddfbcc3c, 0x006662b6, /* 0x120 */ + 0x117c83fe, 0x4e12b414, 0xc2bca766, 0x3a2fec10, + 0xf4562420, 0x55792e2a, 0x46f5d857, 0xceda25ce, + 0xc3601d3b, 0x6c00ab46, 0xefac9c28, 0xb3c35047, + 0x611dfee3, 0x257c3207, 0xfdd58482, 0x3b14d84f, /* 0x130 */ + 0x23becb64, 0xa075f3a3, 0x088f8ead, 0x07adf158, + 0x7796943c, 0xfacabf3d, 0xc09730cd, 0xf7679969, + 0xda44e9ed, 0x2c854c12, 0x35935fa3, 0x2f057d9f, + 0x690624f8, 0x1cb0bafd, 0x7b0dbdc6, 0x810f23bb, /* 0x140 */ + 0xfa929a1a, 0x6d969a17, 0x6742979b, 0x74ac7d05, + 0x010e65c4, 0x86a3d963, 0xf907b5a0, 0xd0042bd3, + 0x158d7d03, 0x287a8255, 0xbba8366f, 0x096edc33, + 0x21916a7b, 0x77b56b86, 0x951622f9, 0xa6c5e650, /* 0x150 */ + 0x8cea17d1, 0xcd8c62bc, 0xa3d63433, 0x358a68fd, + 0x0f9b9d3c, 0xd6aa295b, 0xfe33384a, 0xc000738e, + 0xcd67eb2f, 0xe2eb6dc2, 0x97338b02, 0x06c9f246, + 0x419cf1ad, 0x2b83c045, 0x3723f18a, 0xcb5b3089, /* 0x160 */ + 0x160bead7, 0x5d494656, 0x35f8a74b, 0x1e4e6c9e, + 0x000399bd, 0x67466880, 0xb4174831, 0xacf423b2, + 0xca815ab3, 0x5a6395e7, 0x302a67c5, 0x8bdb446b, + 0x108f8fa4, 0x10223eda, 0x92b8b48b, 0x7f38d0ee, /* 0x170 */ + 0xab2701d4, 0x0262d415, 0xaf224a30, 0xb3d88aba, + 0xf8b2c3af, 0xdaf7ef70, 0xcc97d3b7, 0xe9614b6c, + 0x2baebff4, 0x70f687cf, 0x386c9156, 0xce092ee5, + 0x01e87da6, 0x6ce91e6a, 0xbb7bcc84, 0xc7922c20, /* 0x180 */ + 0x9d3b71fd, 0x060e41c6, 0xd7590f15, 0x4e03bb47, + 0x183c198e, 0x63eeb240, 0x2ddbf49a, 0x6d5cba54, + 0x923750af, 0xf9e14236, 0x7838162b, 0x59726c72, + 0x81b66760, 0xbb2926c1, 0x48a0ce0d, 0xa6c0496d, /* 0x190 */ + 0xad43507b, 0x718d496a, 0x9df057af, 0x44b1bde6, + 0x054356dc, 0xde7ced35, 0xd51a138b, 0x62088cc9, + 0x35830311, 0xc96efca2, 0x686f86ec, 0x8e77cb68, + 0x63e1d6b8, 0xc80f9778, 0x79c491fd, 0x1b4c67f2, /* 0x1a0 */ + 0x72698d7d, 0x5e368c31, 0xf7d95e2e, 0xa1d3493f, + 0xdcd9433e, 0x896f1552, 0x4bc4ca7a, 0xa6d1baf4, + 0xa5a96dcc, 0x0bef8b46, 0xa169fda7, 0x74df40b7, + 0x4e208804, 0x9a756607, 0x038e87c8, 0x20211e44, /* 0x1b0 */ + 0x8b7ad4bf, 0xc6403f35, 0x1848e36d, 0x80bdb038, + 0x1e62891c, 0x643d2107, 0xbf04d6f8, 0x21092c8c, + 0xf644f389, 0x0778404e, 0x7b78adb8, 0xa2c52d53, + 0x42157abe, 0xa2253e2e, 0x7bf3f4ae, 0x80f594f9, /* 0x1c0 */ + 0x953194e7, 0x77eb92ed, 0xb3816930, 0xda8d9336, + 0xbf447469, 0xf26d9483, 0xee6faed5, 0x71371235, + 0xde425f73, 0xb4e59f43, 0x7dbe2d4e, 0x2d37b185, + 0x49dc9a63, 0x98c39d98, 0x1301c9a2, 0x389b1bbf, /* 0x1d0 */ + 0x0c18588d, 0xa421c1ba, 0x7aa3865c, 0x71e08558, + 0x3c5cfcaa, 0x7d239ca4, 0x0297d9dd, 0xd7dc2830, + 0x4b37802b, 0x7428ab54, 0xaeee0347, 0x4b3fbb85, + 0x692f2f08, 0x134e578e, 0x36d9e0bf, 0xae8b5fcf, /* 0x1e0 */ + 0xedb93ecf, 0x2b27248e, 0x170eb1ef, 0x7dc57fd6, + 0x1e760f16, 0xb1136601, 0x864e1b9b, 0xd7ea7319, + 0x3ab871bd, 0xcfa4d76f, 0xe31bd782, 0x0dbeb469, + 0xabb96061, 0x5370f85d, 0xffb07e37, 0xda30d0fb, /* 0x1f0 */ + 0xebc977b6, 0x0b98b40f, 0x3a4d0fe6, 0xdf4fc26b, + 0x159cf22a, 0xc298d6e2, 0x2b78ef6a, 0x61a94ac0, + 0xab561187, 0x14eea0f0, 0xdf0d4164, 0x19af70ee +}; + +static u4byte vk[47] = +{ + 0x09d0c479, 0x28c8ffe0, 0x84aa6c39, 0x9dad7287, 0x7dff9be3, 0xd4268361, + 0xc96da1d4 +}; + +#define f_mix(a,b,c,d) \ + r = rotr(a, 8); \ + b ^= s_box[a & 255]; \ + b += s_box[(r & 255) + 256]; \ + r = rotr(a, 16); \ + a = rotr(a, 24); \ + c += s_box[r & 255]; \ + d ^= s_box[(a & 255) + 256] + +#define b_mix(a,b,c,d) \ + r = rotl(a, 8); \ + b ^= s_box[(a & 255) + 256]; \ + c -= s_box[r & 255]; \ + r = rotl(a, 16); \ + a = rotl(a, 24); \ + d -= s_box[(r & 255) + 256]; \ + d ^= s_box[a & 255] + +#define f_ktr(a,b,c,d,i) \ + m = a + l_key[i]; \ + a = rotl(a, 13); \ + r = a * l_key[i + 1]; \ + l = s_box[m & 511]; \ + r = rotl(r, 5); \ + c += rotl(m, r); \ + l ^= r; \ + r = rotl(r, 5); \ + l ^= r; \ + d ^= r; \ + b += rotl(l, r) + +#define r_ktr(a,b,c,d,i) \ + r = a * l_key[i + 1]; \ + a = rotr(a, 13); \ + m = a + l_key[i]; \ + l = s_box[m & 511]; \ + r = rotl(r, 5); \ + l ^= r; \ + c -= rotl(m, r); \ + r = rotl(r, 5); \ + l ^= r; \ + d ^= r; \ + b -= rotl(l, r) + +/* For a 32 bit word (x) generate a mask (m) such that a bit in */ +/* m is set to 1 if and only if the corresponding bit in x is: */ +/* */ +/* 1. in a sequence of 10 or more adjacent '0' bits */ +/* 2. in a sequence of 10 or more adjacent '1' bits */ +/* 3. but is not either endpoint of such a sequence unless such */ +/* an endpoint is at the top bit (bit 31) of a word and is */ +/* in a sequence of '0' bits. */ +/* */ +/* The only situation in which a sequence endpoint is included */ +/* in the mask is hence when the endpoint is at bit 31 and is */ +/* the endpoint of a sequence of '0' bits. My thanks go to Shai */ +/* Halevi of IBM for the neat trick (which I missed) of finding */ +/* the '0' and '1' sequences at the same time. */ + +u4byte gen_mask(u4byte x) +{ u4byte m; + + /* if m{bn} stands for bit number bn of m, set m{bn} = 1 if */ + /* x{bn} == x{bn+1} for 0 <= bn <= 30. That is, set a bit */ + /* in m if the corresponding bit and the next higher bit in */ + /* x are equal in value (set m{31} = 0). */ + + m = (~x ^ (x >> 1)) & 0x7fffffff; + + /* Sequences of 9 '1' bits in m now correspond to sequences */ + /* of 10 '0's or 10 '1' bits in x. Shift and 'and' bits in */ + /* m to find sequences of 9 or more '1' bits. As a result */ + /* bits in m are set if they are at the bottom of sequences */ + /* of 10 adjacent '0's or 10 adjacent '1's in x. */ + + m &= (m >> 1) & (m >> 2); m &= (m >> 3) & (m >> 6); + + if(!m) /* return if mask is empty - no key fixing needed */ + /* is this early return worthwhile? */ + return 0; + + /* We need the internal bits in each continuous sequence of */ + /* matching bits (that is the bits less the two endpoints). */ + /* We thus propagate each set bit into the 8 internal bits */ + /* that it represents, starting 1 left and finsihing 8 left */ + /* of its position. */ + + m <<= 1; m |= (m << 1); m |= (m << 2); m |= (m << 4); + + /* m is now correct except for the odd behaviour of bit 31, */ + /* that is, it will be set if it is in a sequence of 10 or */ + /* more '0's and clear otherwise. */ + + m |= (m << 1) & ~x & 0x80000000; + + return m & 0xfffffffc; +}; + + +/* My thanks to Louis Granboulan for spotting an error in the */ +/* previous version of set_key. */ + +int mars_set_key(struct cipher_context *cx, char *key, int key_len) +{ + u4byte *in_key = (u32 *)key; + u4byte *l_key = cx->keyinfo; + u4byte i, j, m, u, w; + key_len *= 8; + + m = key_len / 32 - 1; + + for(i = j = 0; i < 39; ++i) + { + vk[i + 7] = rotl(vk[i] ^ vk[i + 5], 3) ^ in_key[j] ^ i; + j = (j == m ? 0 : j + 1); + } + + vk[46] = key_len / 32; + + for(j = 0; j < 7; ++j) + { + for(i = 1; i < 40; ++i) + vk[i+7] = rotl(vk[i + 7] + s_box[vk[i + 6] & 511], 9); + + vk[7] = rotl(vk[7] + s_box[vk[46] & 511], 9); + } + + for(i = j = 0; i < 40; ++i) + { + l_key[j] = vk[i + 7]; + + j = (j < 33 ? j + 7 : j - 33); + } + + for(i = 5; i < 37; i += 2) + { + w = l_key[i] | 3; + + if((m = gen_mask(w))) + w ^= (rotl(s_box[265 + (l_key[i] & 3)], l_key[i + 3] & 31) & m); + l_key[i] = w; + } + + return 0; +}; + +int mars_encrypt(struct cipher_context *cx, u32 *in_blk, u32 *out_blk, int size) +{ u4byte *l_key = cx->keyinfo; + u4byte a, b, c, d, l, m, r; + + a = in_blk[0] + l_key[0]; b = in_blk[1] + l_key[1]; + c = in_blk[2] + l_key[2]; d = in_blk[3] + l_key[3]; + + f_mix(a,b,c,d); a += d; + f_mix(b,c,d,a); b += c; + f_mix(c,d,a,b); + f_mix(d,a,b,c); + f_mix(a,b,c,d); a += d; + f_mix(b,c,d,a); b += c; + f_mix(c,d,a,b); + f_mix(d,a,b,c); + + f_ktr(a,b,c,d, 4); f_ktr(b,c,d,a, 6); f_ktr(c,d,a,b, 8); f_ktr(d,a,b,c,10); + f_ktr(a,b,c,d,12); f_ktr(b,c,d,a,14); f_ktr(c,d,a,b,16); f_ktr(d,a,b,c,18); + f_ktr(a,d,c,b,20); f_ktr(b,a,d,c,22); f_ktr(c,b,a,d,24); f_ktr(d,c,b,a,26); + f_ktr(a,d,c,b,28); f_ktr(b,a,d,c,30); f_ktr(c,b,a,d,32); f_ktr(d,c,b,a,34); + + b_mix(a,b,c,d); + b_mix(b,c,d,a); c -= b; + b_mix(c,d,a,b); d -= a; + b_mix(d,a,b,c); + b_mix(a,b,c,d); + b_mix(b,c,d,a); c -= b; + b_mix(c,d,a,b); d -= a; + b_mix(d,a,b,c); + + out_blk[0] = a - l_key[36]; out_blk[1] = b - l_key[37]; + out_blk[2] = c - l_key[38]; out_blk[3] = d - l_key[39]; + return 0; +}; + +int mars_decrypt(struct cipher_context *cx, u32 *in_blk, u32 *out_blk, int size) +{ u4byte *l_key = cx->keyinfo; + u4byte a, b, c, d, l, m, r; + + d = in_blk[0] + l_key[36]; c = in_blk[1] + l_key[37]; + b = in_blk[2] + l_key[38]; a = in_blk[3] + l_key[39]; + + f_mix(a,b,c,d); a += d; + f_mix(b,c,d,a); b += c; + f_mix(c,d,a,b); + f_mix(d,a,b,c); + f_mix(a,b,c,d); a += d; + f_mix(b,c,d,a); b += c; + f_mix(c,d,a,b); + f_mix(d,a,b,c); + + r_ktr(a,b,c,d,34); r_ktr(b,c,d,a,32); r_ktr(c,d,a,b,30); r_ktr(d,a,b,c,28); + r_ktr(a,b,c,d,26); r_ktr(b,c,d,a,24); r_ktr(c,d,a,b,22); r_ktr(d,a,b,c,20); + r_ktr(a,d,c,b,18); r_ktr(b,a,d,c,16); r_ktr(c,b,a,d,14); r_ktr(d,c,b,a,12); + r_ktr(a,d,c,b,10); r_ktr(b,a,d,c, 8); r_ktr(c,b,a,d, 6); r_ktr(d,c,b,a, 4); + + b_mix(a,b,c,d); + b_mix(b,c,d,a); c -= b; + b_mix(c,d,a,b); d -= a; + b_mix(d,a,b,c); + b_mix(a,b,c,d); + b_mix(b,c,d,a); c -= b; + b_mix(c,d,a,b); d -= a; + b_mix(d,a,b,c); + + out_blk[0] = d - l_key[0]; out_blk[1] = c - l_key[1]; + out_blk[2] = b - l_key[2]; out_blk[3] = a - l_key[3]; + return 0; +} + +static void mars_lock(void) +{ + MOD_INC_USE_COUNT; +} + +static void mars_unlock(void) +{ + MOD_DEC_USE_COUNT; +} + +#define CIPHER_BITS_128 +#define CIPHER_NAME(x) mars##x +#include "gen-cbc.h" + +DEFINE_CIPHER(MARS, mars, "mars", 16, 16); +DEFINE_CBC_CIPHER(MARS, mars, "mars-cbc", 16); + +#ifdef MODULE + int __init init_module(void) +#else + int __init init_mars(void) +#endif +{ + if (register_cipher(&mars)) + printk(KERN_WARNING "Couldn't register mars encryption\n"); + if (register_cipher(&cbc_mars)) + printk(KERN_WARNING "Couldn't register mars-cbc encryption\n"); + + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + if (unregister_cipher(&mars)) + printk(KERN_WARNING "Couldn't unregister mars encryption\n"); + if (unregister_cipher(&cbc_mars)) + printk(KERN_WARNING "Couldn't unregister mars-cbc encryption\n"); +} +#endif + diff -ruN linux-2.2.5,pristine/crypto/rc62.c linux-2.2.5/crypto/rc62.c --- linux-2.2.5,pristine/crypto/rc62.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/rc62.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,190 @@ +/* NOTE: This implementation has been changed from the original + source. See ChangeLog for more information. + Maintained by Alexander Kjeldaas + */ + +/* This is an independent implementation of the RC6 algorithm that */ +/* Ron Rivest and RSA Labs have submitted as a candidate for the */ +/* NIST AES activity. Refer to RSA Labs and Ron Rivest for any */ +/* copyright, patent or license issues for the RC6 algorithm. */ +/* */ +/* Copyright in this implementation is held by Dr B R Gladman but */ +/* I hereby give permission for its free direct or derivative use */ +/* subject to acknowledgment of its origin and compliance with any */ +/* constraints that are placed on the exploitation of RC6 by its */ +/* designers. */ +/* */ +/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 18th July 1998 */ +/* + Timing data: + +Algorithm: rc6 (rc62.c) +128 bit key: +Key Setup: 1580 cycles +Encrypt: 286 cycles = 89.6 mbits/sec +Decrypt: 236 cycles = 108.6 mbits/sec +Mean: 261 cycles = 98.2 mbits/sec +192 bit key: +Key Setup: 1882 cycles +Encrypt: 286 cycles = 89.5 mbits/sec +Decrypt: 235 cycles = 108.9 mbits/sec +Mean: 261 cycles = 98.3 mbits/sec +256 bit key: +Key Setup: 1774 cycles +Encrypt: 285 cycles = 89.7 mbits/sec +Decrypt: 236 cycles = 108.3 mbits/sec +Mean: 261 cycles = 98.1 mbits/sec + +*/ + +#include +#include +#include +#include +#include + +#if 0 +#define rotl rotl32 +#define rotr rotr32 +#else +#define rotl generic_rotl32 +#define rotr generic_rotr32 +#endif + +#define f_rnd(i,a,b,c,d) \ + u = rotl(d * (d + d + 1), 5); \ + t = rotl(b * (b + b + 1), 5); \ + a = rotl(a ^ t, u) + l_key[i]; \ + c = rotl(c ^ u, t) + l_key[i + 1] + +#define i_rnd(i,a,b,c,d) \ + u = rotl(d * (d + d + 1), 5); \ + t = rotl(b * (b + b + 1), 5); \ + c = rotr(c - l_key[i + 1], t) ^ u; \ + a = rotr(a - l_key[i], u) ^ t + +/* initialise the key schedule from the user supplied key */ + +int rc6_set_key(struct cipher_context *cx, char *key, int key_len) +{ u4byte *in_key = (u32 *)key; + /* l_key - storage for the key schedule */ + u4byte *l_key = cx->keyinfo; + u4byte i, j, k, a, b, l[8], t; + key_len *= 8; + + l_key[0] = 0xb7e15163; + + for(k = 1; k < 44; ++k) + + l_key[k] = l_key[k - 1] + 0x9e3779b9; + + for(k = 0; k < key_len / 32; ++k) + + l[k] = in_key[k]; + + t = (key_len / 32) - 1; + + a = b = i = j = 0; + + for(k = 0; k < 132; ++k) + { a = rotl(l_key[i] + a + b, 3); b += a; + b = rotl(l[j] + b, b); + l_key[i] = a; l[j] = b; + i = (i == 43 ? 0 : i + 1); + j = (j == t ? 0 : j + 1); + } + + return 0; +}; + +/* encrypt a block of text */ + +int rc6_encrypt(struct cipher_context *cx, u32 *in_blk, u32 *out_blk, int size) +{ u32 *l_key = cx->keyinfo; + u4byte a,b,c,d,t,u; + + a = in_blk[0]; b = in_blk[1] + l_key[0]; + c = in_blk[2]; d = in_blk[3] + l_key[1]; + + f_rnd( 2,a,b,c,d); f_rnd( 4,b,c,d,a); + f_rnd( 6,c,d,a,b); f_rnd( 8,d,a,b,c); + f_rnd(10,a,b,c,d); f_rnd(12,b,c,d,a); + f_rnd(14,c,d,a,b); f_rnd(16,d,a,b,c); + f_rnd(18,a,b,c,d); f_rnd(20,b,c,d,a); + f_rnd(22,c,d,a,b); f_rnd(24,d,a,b,c); + f_rnd(26,a,b,c,d); f_rnd(28,b,c,d,a); + f_rnd(30,c,d,a,b); f_rnd(32,d,a,b,c); + f_rnd(34,a,b,c,d); f_rnd(36,b,c,d,a); + f_rnd(38,c,d,a,b); f_rnd(40,d,a,b,c); + + out_blk[0] = a + l_key[42]; out_blk[1] = b; + out_blk[2] = c + l_key[43]; out_blk[3] = d; + return 0; +}; + +/* decrypt a block of text */ + +int rc6_decrypt(struct cipher_context *cx, u32 *in_blk, u32 *out_blk, int size) +{ u4byte *l_key = cx->keyinfo; + u4byte a,b,c,d,t,u; + + d = in_blk[3]; c = in_blk[2] - l_key[43]; + b = in_blk[1]; a = in_blk[0] - l_key[42]; + + i_rnd(40,d,a,b,c); i_rnd(38,c,d,a,b); + i_rnd(36,b,c,d,a); i_rnd(34,a,b,c,d); + i_rnd(32,d,a,b,c); i_rnd(30,c,d,a,b); + i_rnd(28,b,c,d,a); i_rnd(26,a,b,c,d); + i_rnd(24,d,a,b,c); i_rnd(22,c,d,a,b); + i_rnd(20,b,c,d,a); i_rnd(18,a,b,c,d); + i_rnd(16,d,a,b,c); i_rnd(14,c,d,a,b); + i_rnd(12,b,c,d,a); i_rnd(10,a,b,c,d); + i_rnd( 8,d,a,b,c); i_rnd( 6,c,d,a,b); + i_rnd( 4,b,c,d,a); i_rnd( 2,a,b,c,d); + + out_blk[3] = d - l_key[1]; out_blk[2] = c; + out_blk[1] = b - l_key[0]; out_blk[0] = a; + return 0; +}; + +static void rc6_lock(void) +{ + MOD_INC_USE_COUNT; +} + +static void rc6_unlock(void) +{ + MOD_DEC_USE_COUNT; +} + +#define CIPHER_BITS_128 +#define CIPHER_NAME(x) rc6##x +#include "gen-cbc.h" + +DEFINE_CIPHER(RC6, rc6, "rc6", 16, 16); +DEFINE_CBC_CIPHER(RC6, rc6, "rc6-cbc", 16); + +#ifdef MODULE + int __init init_module(void) +#else + int __init init_rc6(void) +#endif +{ + if (register_cipher(&rc6)) + printk(KERN_WARNING "Couldn't register rc6 encryption\n"); + if (register_cipher(&cbc_rc6)) + printk(KERN_WARNING "Couldn't register rc6-cbc encryption\n"); + + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + if (unregister_cipher(&rc6)) + printk(KERN_WARNING "Couldn't unregister rc6 encryption\n"); + if (unregister_cipher(&cbc_rc6)) + printk(KERN_WARNING "Couldn't unregister rc6-cbc encryption\n"); +} +#endif + diff -ruN linux-2.2.5,pristine/crypto/rijndael3.c linux-2.2.5/crypto/rijndael3.c --- linux-2.2.5,pristine/crypto/rijndael3.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/rijndael3.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,336 @@ +/* NOTE: This implementation has been changed from the original + source. See ChangeLog for more information. + Maintained by Alexander Kjeldaas + */ + +/* This is an independent implementation of the RIJNDAEL algorithm */ +/* designed by Joan Daemen and Vincent Rijmen and submitted as a */ +/* candidate for the NIST AES activity. */ +/* */ +/* Copyright in this implementation is held by Dr B R Gladman but */ +/* I hereby give permission for its free direct or derivative use */ +/* subject to acknowledgment of its origin and compliance with any */ +/* conditions that the algorithm originators place on its use. */ +/* */ +/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 18th July 1998 */ +/* Timing data: + +Algorithm: rijndael (rijndael3.c) +128 bit key: +Key Setup: 2063 cycles +Encrypt: 442 cycles = 57.9 mbits/sec +Decrypt: 445 cycles = 57.6 mbits/sec +Mean: 443 cycles = 57.7 mbits/sec +192 bit key: +Key Setup: 2433 cycles +Encrypt: 517 cycles = 49.6 mbits/sec +Decrypt: 506 cycles = 50.6 mbits/sec +Mean: 511 cycles = 50.1 mbits/sec +256 bit key: +Key Setup: 2925 cycles +Encrypt: 588 cycles = 43.5 mbits/sec +Decrypt: 568 cycles = 45.1 mbits/sec +Mean: 578 cycles = 44.3 mbits/sec + +*/ + +#include +#include +#include +#include +#include + +#if 0 +#define rotl rotl32 +#define rotr rotr32 +#else +#define rotl generic_rotl32 +#define rotr generic_rotr32 +#endif + +u1byte pow_tab[256]; +u1byte log_tab[256]; +u1byte sbx_tab[256]; +u1byte isb_tab[256]; +u4byte rco_tab[ 10]; +u4byte ft_tab[4][256]; +u4byte it_tab[4][256]; +u4byte tab_gen = 0; + +#define ff_mult(a,b) (a && b ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0) + +#define ls_box(x) \ + ((u4byte)sbx_tab[ (x) & 255] << 0) ^ \ + ((u4byte)sbx_tab[((x) >> 8) & 255] << 8) ^ \ + ((u4byte)sbx_tab[((x) >> 16) & 255] << 16) ^ \ + ((u4byte)sbx_tab[((x) >> 24) & 255] << 24) + +#define f_rn(bo, bi, i) \ + bo[i] = ft_tab[0][byte(bi[i],0)] ^ \ + ft_tab[1][byte(bi[(i + 1) & 3],1)] ^ \ + ft_tab[2][byte(bi[(i + 2) & 3],2)] ^ \ + ft_tab[3][byte(bi[(i + 3) & 3],3)] + +#define f_rl(bo, bi, i) \ + bo[i] = (u4byte)sbx_tab[byte(bi[i],0)] ^ \ + rotl(((u4byte)sbx_tab[byte(bi[(i + 1) & 3],1)]), 8) ^ \ + rotl(((u4byte)sbx_tab[byte(bi[(i + 2) & 3],2)]), 16) ^ \ + rotl(((u4byte)sbx_tab[byte(bi[(i + 3) & 3],3)]), 24) + +#define i_rn(bo, bi, i) \ + bo[i] = it_tab[0][byte(bi[i],0)] ^ \ + it_tab[1][byte(bi[(i + 3) & 3],1)] ^ \ + it_tab[2][byte(bi[(i + 2) & 3],2)] ^ \ + it_tab[3][byte(bi[(i + 1) & 3],3)] + +#define i_rl(bo, bi, i) \ + bo[i] = (u4byte)isb_tab[byte(bi[i],0)] ^ \ + rotl(((u4byte)isb_tab[byte(bi[(i + 3) & 3],1)]), 8) ^ \ + rotl(((u4byte)isb_tab[byte(bi[(i + 2) & 3],2)]), 16) ^ \ + rotl(((u4byte)isb_tab[byte(bi[(i + 1) & 3],3)]), 24) + +void gen_tabs(void) +{ u4byte i, t; + u1byte p, q; + + /* log and power tables for GF(2**8) finite field with */ + /* 0x11b as modular polynomial - the simplest prmitive */ + /* root is 0x11, used here to generate the tables */ + + for(i = 0,p = 1; i < 256; ++i) + { + pow_tab[i] = p; log_tab[p] = i; + + p = p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0); + } + + log_tab[1] = 0; p = 1; + + for(i = 0; i < 10; ++i) + { + rco_tab[i] = p; + + p = (p << 1) ^ (p & 0x80 ? 0x1b : 0); + } + + /* note that the affine byte transformation matrix in */ + /* rijndael specification is in big endian format with */ + /* bit 0 as the most significant bit. In the remainder */ + /* of the specification the bits are numbered from the */ + /* least significant end of a byte. */ + + for(i = 0; i < 256; ++i) + { + p = (i ? pow_tab[255 - log_tab[i]] : 0); q = p; + q = (q >> 7) | (q << 1); p ^= q; + q = (q >> 7) | (q << 1); p ^= q; + q = (q >> 7) | (q << 1); p ^= q; + q = (q >> 7) | (q << 1); p ^= q ^ 0x63; + sbx_tab[i] = p; isb_tab[p] = i; + } + + for(i = 0; i < 256; ++i) + { + p = sbx_tab[i]; + + t = ((u4byte)ff_mult(2, p)) | + ((u4byte)p << 8) | + ((u4byte)p << 16) | + ((u4byte)ff_mult(3, p) << 24); + + ft_tab[0][i] = t; + ft_tab[1][i] = rotl(t, 8); + ft_tab[2][i] = rotl(t, 16); + ft_tab[3][i] = rotl(t, 24); + + p = isb_tab[i]; + + t = ((u4byte)ff_mult(14, p)) | + ((u4byte)ff_mult( 9, p) << 8) | + ((u4byte)ff_mult(13, p) << 16) | + ((u4byte)ff_mult(11, p) << 24); + + it_tab[0][i] = t; + it_tab[1][i] = rotl(t, 8); + it_tab[2][i] = rotl(t, 16); + it_tab[3][i] = rotl(t, 24); + } + + tab_gen = 1; +}; + +#define mask 0x80808080 +#define star_x(r,x) t = (x) & mask; r = (((x) ^ t) << 1) ^ ((t >> 7) * 0x1b) + +#define imix_col(x) \ + u = (x); star_x(v, u); \ + star_x(w, v); star_x(z, w); \ + (x) = z ^ w ^ v ^ rotr(z ^ v ^ u, 8) \ + ^ rotr(z ^ w ^ u, 16) \ + ^ rotr(z ^ u, 24) + +/* initialise the key schedule from the user supplied key */ + +int rijndael_set_key(struct cipher_context *cx, char *key, int key_len) +{ /* l_key - storage for the key schedule */ + u4byte *e_key = cx->keyinfo; + u4byte *d_key = cx->keyinfo+60; + u4byte i, j, lk[8], t, u, v, w, z, k_len; + key_len *= 8; + + k_len = (key_len + 31) / 32; + cx->key_length = k_len * 4; + + for(i = 0; i < k_len; ++i) + { + e_key[i] = lk[i]; + d_key[i] = lk[i]; + } + + for(i = 1; i < 5 + 27 / k_len; ++i) + { + t = rotr(lk[k_len - 1], 8); + + lk[0] ^= ls_box(t) ^ rco_tab[i - 1]; + + for(j = 1; j < k_len / 2; j++) + + lk[j] ^= lk[j - 1]; + + t = lk[k_len / 2 - 1]; + + lk[j] ^= (k_len == 8 ? ls_box(t) : lk[j - 1]); + + for(++j; j < k_len; ++j) + + lk[j] ^= lk[j - 1]; + + for(j = 0; j < k_len; ++j) + { + e_key[i * k_len + j] = lk[j]; + d_key[i * k_len + j] = lk[j]; + } + } + + for(i = 1; i < k_len + 6; ++i) + { + imix_col(d_key[4 * i]); + imix_col(d_key[4 * i + 1]); + imix_col(d_key[4 * i + 2]); + imix_col(d_key[4 * i + 3]); + } + + return 0; +}; + +/* encrypt a block of text */ + +int rijndael_encrypt(struct cipher_context *cx, u32 *in_blk, u32 *out_blk, int size) +{ u4byte *e_key = cx->keyinfo; + u4byte k_len = cx->key_length / 4; + u4byte i, b0[4], b1[4]; + + b0[0] = in_blk[0] ^ e_key[0]; + b0[1] = in_blk[1] ^ e_key[1]; + b0[2] = in_blk[2] ^ e_key[2]; + b0[3] = in_blk[3] ^ e_key[3]; + + for(i = 1; i < k_len + 6; ++i) + { + f_rn(b1, b0, 0); f_rn(b1, b0, 1); + f_rn(b1, b0, 2); f_rn(b1, b0, 3); + + b0[0] = b1[0] ^ e_key[4 * i]; + b0[1] = b1[1] ^ e_key[4 * i + 1]; + b0[2] = b1[2] ^ e_key[4 * i + 2]; + b0[3] = b1[3] ^ e_key[4 * i + 3]; + } + + f_rl(b1, b0, 0); f_rl(b1, b0, 1); + f_rl(b1, b0, 2); f_rl(b1, b0, 3); + + out_blk[0] = b1[0] ^ e_key[4 * k_len + 24]; + out_blk[1] = b1[1] ^ e_key[4 * k_len + 25]; + out_blk[2] = b1[2] ^ e_key[4 * k_len + 26]; + out_blk[3] = b1[3] ^ e_key[4 * k_len + 27]; + + return 0; +} + +/* decrypt a block of text */ + +int rijndael_decrypt(struct cipher_context *cx, u32 *in_blk, u32 *out_blk, int size) +{ u4byte *e_key = cx->keyinfo; + u4byte *d_key = cx->keyinfo+60; + u4byte k_len = cx->key_length / 4; + u4byte i, b0[4], b1[4]; + + b0[0] = in_blk[0] ^ e_key[4 * k_len + 24]; + b0[1] = in_blk[1] ^ e_key[4 * k_len + 25]; + b0[2] = in_blk[2] ^ e_key[4 * k_len + 26]; + b0[3] = in_blk[3] ^ e_key[4 * k_len + 27]; + + for(i = k_len + 5; i > 0; --i) + { + i_rn(b1, b0, 0); i_rn(b1, b0, 1); + i_rn(b1, b0, 2); i_rn(b1, b0, 3); + + b0[0] = b1[0] ^ d_key[4 * i]; + b0[1] = b1[1] ^ d_key[4 * i + 1]; + b0[2] = b1[2] ^ d_key[4 * i + 2]; + b0[3] = b1[3] ^ d_key[4 * i + 3]; + } + + i_rl(b1, b0, 0); i_rl(b1, b0, 1); + i_rl(b1, b0, 2); i_rl(b1, b0, 3); + + out_blk[0] = b1[0] ^ d_key[0]; + out_blk[1] = b1[1] ^ d_key[1]; + out_blk[2] = b1[2] ^ d_key[2]; + out_blk[3] = b1[3] ^ d_key[3]; + + return 0; +} + + +static void rijndael_lock(void) +{ + MOD_INC_USE_COUNT; +} + +static void rijndael_unlock(void) +{ + MOD_DEC_USE_COUNT; +} + +#define CIPHER_BITS_128 +#define CIPHER_NAME(x) rijndael##x +#include "gen-cbc.h" + +DEFINE_CIPHER(RIJNDAEL, rijndael, "rijndael", 16, 16); +DEFINE_CBC_CIPHER(RIJNDAEL, rijndael, "rijndael-cbc", 16); + +#ifdef MODULE + int __init init_module(void) +#else + int __init init_rijndael(void) +#endif +{ + if (register_cipher(&rijndael)) + printk(KERN_WARNING "Couldn't register rijndael encryption\n"); + if (register_cipher(&cbc_rijndael)) + printk(KERN_WARNING "Couldn't register rijndael-cbc encryption\n"); + + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + if (unregister_cipher(&rijndael)) + printk(KERN_WARNING "Couldn't unregister rijndael encryption\n"); + if (unregister_cipher(&cbc_rijndael)) + printk(KERN_WARNING "Couldn't unregister rijndael-cbc encryption\n"); +} +#endif + diff -ruN linux-2.2.5,pristine/crypto/safer3.c linux-2.2.5/crypto/safer3.c --- linux-2.2.5,pristine/crypto/safer3.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/safer3.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,354 @@ + +/* This is an independent implementation of the SAFER+ encryption */ +/* algorithm submitted by Cylink as a candidate in the US NIST */ +/* Advanced Encryption Standard (AES) programme. This algorithm */ +/* has not been patented and is freely available for use without */ +/* the need for licensing. */ +/* */ +/* Copyright in this implementation is held by Dr B R Gladman but */ +/* I hereby give permission for its free direct or derivative use */ +/* subject to acknowledgment of its origin. */ +/* */ +/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 24th July 1998 */ +/* +/* Timing data: + +Algorithm: safer (safer3.c) +128 bit key: +Key Setup: 3973 cycles +Encrypt: 1769 cycles = 14.5 mbits/sec +Decrypt: 1764 cycles = 14.5 mbits/sec +Mean: 1766 cycles = 14.5 mbits/sec +192 bit key: +Key Setup: 6507 cycles +Encrypt: 2608 cycles = 9.8 mbits/sec +Decrypt: 2601 cycles = 9.8 mbits/sec +Mean: 2605 cycles = 9.8 mbits/sec +256 bit key: +Key Setup: 9479 cycles +Encrypt: 3459 cycles = 7.4 mbits/sec +Decrypt: 3425 cycles = 7.5 mbits/sec +Mean: 3442 cycles = 7.4 mbits/sec + +*/ + +#define BYTE_SWAP +#define WORD_SWAP + +#include "../std_defs.h" + +static char *alg_name[] = { "safer", "safer3.c" }; + +char **cipher_name() +{ + return alg_name; +}; + +u1byte expf[256] = +{ 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63, + 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247, + 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, + 255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, + 241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, + 129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, + 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, + 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217, + 0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194, + 249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10, + 193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80, + 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126, + 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237, + 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97, + 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5, + 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40 +}; + +u1byte logf[512] = +{ + 128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248, + 192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130, + 112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37, + 201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15, + 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198, + 175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84, + 121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188, + 189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217, + 208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158, + 210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42, + 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219, + 164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29, + 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14, + 122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104, + 109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66, + 184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48, + + 128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248, + 192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130, + 112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37, + 201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15, + 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198, + 175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84, + 121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188, + 189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217, + 208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158, + 210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42, + 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219, + 164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29, + 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14, + 122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104, + 109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66, + 184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48 +}; + +u1byte l_key[33 * 16]; +u4byte k_bytes; + +u4byte *set_key(const u4byte in_key[], const u4byte key_len) +{ u1byte by, lk[33]; + u4byte i, j, k, l, m; + + get_key(lk, key_len); + + k_bytes = key_len / 8; lk[k_bytes] = 0; + + for(i = 0; i < k_bytes; ++i) + { + lk[k_bytes] ^= lk[i]; l_key[i] = lk[i]; + } + + for(i = 0; i < k_bytes; ++i) + { + for(j = 0; j <= k_bytes; ++j) + { + by = lk[j]; lk[j] = by << 3 | by >> 5; + } + + k = 17 * i + 35; l = 16 * i + 16; m = i + 1; + + if(i < 16) + { + for(j = 0; j < 16; ++j) + { + l_key[l + j] = lk[m] + expf[expf[(k + j) & 255]]; + + m = (m == k_bytes ? 0 : m + 1); + } + } + else + { + for(j = 0; j < 16; ++j) + { + l_key[l + j] = lk[m] + expf[(k + j) & 255]; + + m = (m == k_bytes ? 0 : m + 1); + } + } + } + return (u4byte*)l_key; +}; + +void do_fr(u1byte x[16], u1byte *kp) +{ u1byte t; + + x[ 0] = expf[x[ 0] ^ kp[ 0]] + kp[16]; + x[ 1] = logf[x[ 1] + kp[ 1]] ^ kp[17]; + x[ 2] = logf[x[ 2] + kp[ 2]] ^ kp[18]; + x[ 3] = expf[x[ 3] ^ kp[ 3]] + kp[19]; + + x[ 4] = expf[x[ 4] ^ kp[ 4]] + kp[20]; + x[ 5] = logf[x[ 5] + kp[ 5]] ^ kp[21]; + x[ 6] = logf[x[ 6] + kp[ 6]] ^ kp[22]; + x[ 7] = expf[x[ 7] ^ kp[ 7]] + kp[23]; + + x[ 8] = expf[x[ 8] ^ kp[ 8]] + kp[24]; + x[ 9] = logf[x[ 9] + kp[ 9]] ^ kp[25]; + x[10] = logf[x[10] + kp[10]] ^ kp[26]; + x[11] = expf[x[11] ^ kp[11]] + kp[27]; + + x[12] = expf[x[12] ^ kp[12]] + kp[28]; + x[13] = logf[x[13] + kp[13]] ^ kp[29]; + x[14] = logf[x[14] + kp[14]] ^ kp[30]; + x[15] = expf[x[15] ^ kp[15]] + kp[31]; + + x[ 1] += x[ 0]; x[ 0] += x[ 1]; + x[ 3] += x[ 2]; x[ 2] += x[ 3]; + x[ 5] += x[ 4]; x[ 4] += x[ 5]; + x[ 7] += x[ 6]; x[ 6] += x[ 7]; + x[ 9] += x[ 8]; x[ 8] += x[ 9]; + x[11] += x[10]; x[10] += x[11]; + x[13] += x[12]; x[12] += x[13]; + x[15] += x[14]; x[14] += x[15]; + + x[ 7] += x[ 0]; x[ 0] += x[ 7]; + x[ 1] += x[ 2]; x[ 2] += x[ 1]; + x[ 3] += x[ 4]; x[ 4] += x[ 3]; + x[ 5] += x[ 6]; x[ 6] += x[ 5]; + x[11] += x[ 8]; x[ 8] += x[11]; + x[ 9] += x[10]; x[10] += x[ 9]; + x[15] += x[12]; x[12] += x[15]; + x[13] += x[14]; x[14] += x[13]; + + x[ 3] += x[ 0]; x[ 0] += x[ 3]; + x[15] += x[ 2]; x[ 2] += x[15]; + x[ 7] += x[ 4]; x[ 4] += x[ 7]; + x[ 1] += x[ 6]; x[ 6] += x[ 1]; + x[ 5] += x[ 8]; x[ 8] += x[ 5]; + x[13] += x[10]; x[10] += x[13]; + x[11] += x[12]; x[12] += x[11]; + x[ 9] += x[14]; x[14] += x[ 9]; + + x[13] += x[ 0]; x[ 0] += x[13]; + x[ 5] += x[ 2]; x[ 2] += x[ 5]; + x[ 9] += x[ 4]; x[ 4] += x[ 9]; + x[11] += x[ 6]; x[ 6] += x[11]; + x[15] += x[ 8]; x[ 8] += x[15]; + x[ 1] += x[10]; x[10] += x[ 1]; + x[ 3] += x[12]; x[12] += x[ 3]; + x[ 7] += x[14]; x[14] += x[ 7]; + + t = x[0]; x[0] = x[14]; x[14] = x[12]; x[12] = x[10]; x[10] = x[2]; + x[2] = x[8]; x[8] = x[4]; x[4] = t; + + t = x[1]; x[1] = x[7]; x[7] = x[11]; x[11] = x[5]; x[5] = x[13]; x[13] = t; + + t = x[15]; x[15] = x[3]; x[3] = t; +}; + +void do_ir(u1byte x[16], u1byte *kp) +{ u1byte t; + + t = x[3]; x[3] = x[15]; x[15] = t; + + t = x[13]; x[13] = x[5]; x[5] = x[11]; x[11] = x[7]; x[7] = x[1]; x[1] = t; + + t = x[4]; x[4] = x[8]; x[8] = x[2]; x[2] = x[10]; + x[10] = x[12]; x[12] = x[14]; x[14] = x[0]; x[0] = t; + + x[14] -= x[ 7]; x[ 7] -= x[14]; + x[12] -= x[ 3]; x[ 3] -= x[12]; + x[10] -= x[ 1]; x[ 1] -= x[10]; + x[ 8] -= x[15]; x[15] -= x[ 8]; + x[ 6] -= x[11]; x[11] -= x[ 6]; + x[ 4] -= x[ 9]; x[ 9] -= x[ 4]; + x[ 2] -= x[ 5]; x[ 5] -= x[ 2]; + x[ 0] -= x[13]; x[13] -= x[ 0]; + + x[14] -= x[ 9]; x[ 9] -= x[14]; + x[12] -= x[11]; x[11] -= x[12]; + x[10] -= x[13]; x[13] -= x[10]; + x[ 8] -= x[ 5]; x[ 5] -= x[ 8]; + x[ 6] -= x[ 1]; x[ 1] -= x[ 6]; + x[ 4] -= x[ 7]; x[ 7] -= x[ 4]; + x[ 2] -= x[15]; x[15] -= x[ 2]; + x[ 0] -= x[ 3]; x[ 3] -= x[ 0]; + + x[14] -= x[13]; x[13] -= x[14]; + x[12] -= x[15]; x[15] -= x[12]; + x[10] -= x[ 9]; x[ 9] -= x[10]; + x[ 8] -= x[11]; x[11] -= x[ 8]; + x[ 6] -= x[ 5]; x[ 5] -= x[ 6]; + x[ 4] -= x[ 3]; x[ 3] -= x[ 4]; + x[ 2] -= x[ 1]; x[ 1] -= x[ 2]; + x[ 0] -= x[ 7]; x[ 7] -= x[ 0]; + + x[14] -= x[15]; x[15] -= x[14]; + x[12] -= x[13]; x[13] -= x[12]; + x[10] -= x[11]; x[11] -= x[10]; + x[ 8] -= x[ 9]; x[ 9] -= x[ 8]; + x[ 6] -= x[ 7]; x[ 7] -= x[ 6]; + x[ 4] -= x[ 5]; x[ 5] -= x[ 4]; + x[ 2] -= x[ 3]; x[ 3] -= x[ 2]; + x[ 0] -= x[ 1]; x[ 1] -= x[ 0]; + + x[ 0] = logf[x[ 0] - kp[16] + 256] ^ kp[ 0]; + x[ 1] = expf[x[ 1] ^ kp[17]] - kp[ 1]; + x[ 2] = expf[x[ 2] ^ kp[18]] - kp[ 2]; + x[ 3] = logf[x[ 3] - kp[19] + 256] ^ kp[ 3]; + + x[ 4] = logf[x[ 4] - kp[20] + 256] ^ kp[ 4]; + x[ 5] = expf[x[ 5] ^ kp[21]] - kp[ 5]; + x[ 6] = expf[x[ 6] ^ kp[22]] - kp[ 6]; + x[ 7] = logf[x[ 7] - kp[23] + 256] ^ kp[ 7]; + + x[ 8] = logf[x[ 8] - kp[24] + 256] ^ kp[ 8]; + x[ 9] = expf[x[ 9] ^ kp[25]] - kp[ 9]; + x[10] = expf[x[10] ^ kp[26]] - kp[10]; + x[11] = logf[x[11] - kp[27] + 256] ^ kp[11]; + + x[12] = logf[x[12] - kp[28] + 256] ^ kp[12]; + x[13] = expf[x[13] ^ kp[29]] - kp[13]; + x[14] = expf[x[14] ^ kp[30]] - kp[14]; + x[15] = logf[x[15] - kp[31] + 256] ^ kp[15]; +}; + +void encrypt(const u4byte in_blk[4], u4byte out_blk[4]) +{ u1byte blk[16], *kp; + + get_block(blk); + + do_fr(blk, l_key); do_fr(blk, l_key + 32); + do_fr(blk, l_key + 64); do_fr(blk, l_key + 96); + do_fr(blk, l_key + 128); do_fr(blk, l_key + 160); + do_fr(blk, l_key + 192); do_fr(blk, l_key + 224); + + if(k_bytes > 16) + { + do_fr(blk, l_key + 256); do_fr(blk, l_key + 288); + do_fr(blk, l_key + 320); do_fr(blk, l_key + 352); + } + + if(k_bytes > 24) + { + do_fr(blk, l_key + 384); do_fr(blk, l_key + 416); + do_fr(blk, l_key + 448); do_fr(blk, l_key + 480); + } + + kp = l_key + 16 * k_bytes; + + blk[ 0] ^= kp[ 0]; blk[ 1] += kp[ 1]; + blk[ 2] += kp[ 2]; blk[ 3] ^= kp[ 3]; + blk[ 4] ^= kp[ 4]; blk[ 5] += kp[ 5]; + blk[ 6] += kp[ 6]; blk[ 7] ^= kp[ 7]; + blk[ 8] ^= kp[ 8]; blk[ 9] += kp[ 9]; + blk[10] += kp[10]; blk[11] ^= kp[11]; + blk[12] ^= kp[12]; blk[13] += kp[13]; + blk[14] += kp[14]; blk[15] ^= kp[15]; + + put_block(blk); +}; + +void decrypt(const u4byte in_blk[4], u4byte out_blk[4]) +{ u1byte blk[16], *kp; + + get_block(blk); + + kp = l_key + 16 * k_bytes; + + blk[ 0] ^= kp[ 0]; blk[ 1] -= kp[ 1]; + blk[ 2] -= kp[ 2]; blk[ 3] ^= kp[ 3]; + blk[ 4] ^= kp[ 4]; blk[ 5] -= kp[ 5]; + blk[ 6] -= kp[ 6]; blk[ 7] ^= kp[ 7]; + blk[ 8] ^= kp[ 8]; blk[ 9] -= kp[ 9]; + blk[10] -= kp[10]; blk[11] ^= kp[11]; + blk[12] ^= kp[12]; blk[13] -= kp[13]; + blk[14] -= kp[14]; blk[15] ^= kp[15]; + + if(k_bytes > 24) + { + do_ir(blk, l_key + 480); do_ir(blk, l_key + 448); + do_ir(blk, l_key + 416); do_ir(blk, l_key + 384); + } + + if(k_bytes > 16) + { + do_ir(blk, l_key + 352); do_ir(blk, l_key + 320); + do_ir(blk, l_key + 288); do_ir(blk, l_key + 256); + } + + do_ir(blk, l_key + 224); do_ir(blk, l_key + 192); + do_ir(blk, l_key + 160); do_ir(blk, l_key + 128); + do_ir(blk, l_key + 96); do_ir(blk, l_key + 64); + do_ir(blk, l_key + 32); do_ir(blk, l_key); + + put_block(blk); +}; diff -ruN linux-2.2.5,pristine/crypto/serp6f.c linux-2.2.5/crypto/serp6f.c --- linux-2.2.5,pristine/crypto/serp6f.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/serp6f.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,670 @@ +/* NOTE: This implementation has been changed from the original + source. See ChangeLog for more information. + Maintained by Alexander Kjeldaas + */ + +/* This is an independent implementation of the Serpent encryption */ +/* algorithm designed by Ross Anderson, Eli Biham and Lars Knudsen */ +/* and offered as a candidate algorithm for the US NIST Advanced */ +/* Encryption Standard (AES) effort. The algorithm is subject to */ +/* Patent action by its designers but royalty free use will be */ +/* offered to all conforming implementations. */ +/* */ +/* Copyright in this implementation is held by Dr B R Gladman but */ +/* I hereby give permission for its free direct or derivative use */ +/* subject to acknowledgment of its origin. */ +/* */ +/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 25th June 1998 */ +/* */ +/* Timing data (core timing without I/O byte endian conversion): + +Algorithm: serpent (serpent.c) + +128 bit key: +Key Setup: 2410 cycles +Encrypt: 921 cycles = 27.8 mbits/sec +Decrypt: 910 cycles = 28.1 mbits/sec +Mean: 916 cycles = 28.0 mbits/sec +192 bit key: +Key Setup: 2364 cycles +Encrypt: 921 cycles = 27.8 mbits/sec +Decrypt: 901 cycles = 28.4 mbits/sec +Mean: 911 cycles = 28.1 mbits/sec +256 bit key: +Key Setup: 2349 cycles +Encrypt: 921 cycles = 27.8 mbits/sec +Decrypt: 901 cycles = 28.4 mbits/sec +Mean: 911 cycles = 28.1 mbits/sec + +*/ + +#include +#include +#include +#include +#include + +#include + +#if 0 +#define rotl rotl32 +#define rotr rotr32 +#else +#define rotl generic_rotl32 +#define rotr generic_rotr32 +#endif + +#define io_swap(x) __cpu_to_be32(x) + + +#define BLOCK_SWAP + + +/* Partially optimised Serpent S Box boolean functions derived */ +/* using a recursive descent analyser but without a full search */ +/* of all subtrees. This set of S boxes is the result of work */ +/* by Sam Simpson and Brian Gladman using the spare time on a */ +/* cluster of high capacity servers to search for S boxes with */ +/* this customised search engine. There are now an average of */ +/* 15.375 terms per S box. */ +/* */ +/* Copyright: Dr B. R Gladman (gladman@seven77.demon.co.uk) */ +/* and Sam Simpson (s.simpson@mia.co.uk) */ +/* 17th December 1998 */ +/* */ +/* We hereby give permission for information in this file to be */ +/* used freely subject only to acknowledgement of its origin. */ + +/* 15 terms */ + +#define sb0(a,b,c,d,e,f,g,h) \ + t1 = a ^ d; \ + t2 = a & d; \ + t3 = c ^ t1; \ + t4 = b ^ t3; \ + h = t2 ^ t4; \ + t6 = b & t1; \ + t7 = a ^ t6; \ + t8 = c | t7; \ + g = t4 ^ t8; \ + t10 = ~t3; \ + t11 = t3 ^ t7; \ + t12 = h & t11; \ + f = t10 ^ t12; \ + t14 = ~t7; \ + e = t12 ^ t14 + +/* 15 terms */ + +#define ib0(a,b,c,d,e,f,g,h) \ + t1 = ~a; \ + t2 = a ^ b; \ + t3 = t1 | t2; \ + t4 = d ^ t3; \ + t5 = c ^ t4; \ + g = t2 ^ t5; \ + t7 = d & t2; \ + t8 = t1 ^ t7; \ + t9 = g & t8; \ + f = t4 ^ t9; \ + t11 = a & t4; \ + t12 = t5 | f; \ + h = t11 ^ t12; \ + t14 = t5 ^ t8; \ + e = h ^ t14 + +/* 14 terms */ + +#define sb1(a,b,c,d,e,f,g,h) \ + t1 = ~a; \ + t2 = b ^ t1; \ + t3 = a | t2; \ + t4 = d | t2; \ + t5 = c ^ t3; \ + g = d ^ t5; \ + t7 = b ^ t4; \ + t8 = t2 ^ g; \ + t9 = t5 & t7; \ + h = t8 ^ t9; \ + t11 = t5 ^ t7; \ + f = h ^ t11; \ + t13 = t8 & t11; \ + e = t5 ^ t13 + +/* 14 terms */ + +#define ib1(a,b,c,d,e,f,g,h) \ + t1 = b ^ d; \ + t2 = b & t1; \ + t3 = a ^ t2; \ + t4 = t1 ^ t3; \ + h = c ^ t4; \ + t6 = t1 & t3; \ + t7 = b ^ t6; \ + t8 = h | t7; \ + f = t3 ^ t8; \ + t10 = ~f; \ + t11 = h ^ t7; \ + e = t10 ^ t11; \ + t13 = t10 | t11;\ + g = t4 ^ t13 + +/* 16 terms */ + +#define sb2(a,b,c,d,e,f,g,h) \ + t1 = ~a; \ + t2 = b ^ d; \ + t3 = c & t1; \ + e = t2 ^ t3; \ + t5 = c ^ t1; \ + t6 = c ^ e; \ + t7 = b & t6; \ + h = t5 ^ t7; \ + t9 = d | t7; \ + t10 = e | t5; \ + t11 = t9 & t10; \ + g = a ^ t11; \ + t13 = d | t1; \ + t14 = t2 ^ h; \ + t15 = g ^ t13; \ + f = t14 ^ t15 + +/* 16 terms */ + +#define ib2(a,b,c,d,e,f,g,h) \ + t1 = b ^ d; \ + t2 = ~t1; \ + t3 = a ^ c; \ + t4 = c ^ t1; \ + t5 = b & t4; \ + e = t3 ^ t5; \ + t7 = a | t2; \ + t8 = d ^ t7; \ + t9 = t3 | t8; \ + h = t1 ^ t9; \ + t11 = ~t4; \ + t12 = e | h; \ + f = t11 ^ t12; \ + t14 = d & t11; \ + t15 = t3 ^ t12; \ + g = t14 ^ t15 + +/* 16 terms */ + +#define sb3(a,b,c,d,e,f,g,h) \ + t1 = a ^ b; \ + t2 = a & c; \ + t3 = a | d; \ + t4 = c ^ d; \ + t5 = t1 & t3; \ + t6 = t2 | t5; \ + g = t4 ^ t6; \ + t8 = b ^ t3; \ + t9 = t6 ^ t8; \ + t10 = t4 & t9; \ + e = t1 ^ t10; \ + t12 = g & e; \ + f = t9 ^ t12; \ + t14 = b | d; \ + t15 = t4 ^ t12; \ + h = t14 ^ t15 + +/* 15 terms */ + +#define ib3(a,b,c,d,e,f,g,h) \ + t1 = a | b; \ + t2 = b ^ c; \ + t3 = b & t2; \ + t4 = a ^ t3; \ + t5 = c ^ t4; \ + t6 = d | t4; \ + e = t2 ^ t6; \ + t8 = t2 | t6; \ + t9 = d ^ t8; \ + g = t5 ^ t9; \ + t11 = t1 ^ t9; \ + t12 = e & t11; \ + h = t4 ^ t12; \ + t14 = e ^ t11; \ + f = h ^ t14 + +/* 15 terms */ + +#define sb4(a,b,c,d,e,f,g,h) \ + t1 = a ^ d; \ + t2 = d & t1; \ + t3 = c ^ t2; \ + t4 = b | t3; \ + h = t1 ^ t4; \ + t6 = ~b; \ + t7 = t1 | t6; \ + e = t3 ^ t7; \ + t9 = a & e; \ + t10 = t1 ^ t6; \ + t11 = t4 & t10; \ + g = t9 ^ t11; \ + t13 = a ^ t3; \ + t14 = t10 & g; \ + f = t13 ^ t14 + +/* 15 terms */ + +#define ib4(a,b,c,d,e,f,g,h) \ + t1 = c | d; \ + t2 = a & t1; \ + t3 = b ^ t2; \ + t4 = a & t3; \ + t5 = c ^ t4; \ + f = d ^ t5; \ + t7 = ~a; \ + t8 = t5 & f; \ + h = t3 ^ t8; \ + t10 = f | t7; \ + t11 = d ^ t10; \ + e = h ^ t11; \ + t13 = t3 & t11; \ + t14 = f ^ t7; \ + g = t13 ^ t14 + +/* 16 terms */ + +#define sb5(a,b,c,d,e,f,g,h) \ + t1 = ~a; \ + t2 = a ^ b; \ + t3 = a ^ d; \ + t4 = c ^ t1; \ + t5 = t2 | t3; \ + e = t4 ^ t5; \ + t7 = d & e; \ + t8 = t2 ^ e; \ + f = t7 ^ t8; \ + t10 = t1 | e; \ + t11 = t2 | t7; \ + t12 = t3 ^ t10; \ + g = t11 ^ t12; \ + t14 = b ^ t7; \ + t15 = f & t12; \ + h = t14 ^ t15 + +/* 16 terms */ + +#define ib5(a,b,c,d,e,f,g,h) \ + t1 = ~c; \ + t2 = b & t1; \ + t3 = d ^ t2; \ + t4 = a & t3; \ + t5 = b ^ t1; \ + h = t4 ^ t5; \ + t7 = b | h; \ + t8 = a & t7; \ + f = t3 ^ t8; \ + t10 = a | d; \ + t11 = t1 ^ t7; \ + e = t10 ^ t11; \ + t13 = a ^ c; \ + t14 = b & t10; \ + t15 = t4 | t13; \ + g = t14 ^ t15 + +/* 15 terms */ + +#define sb6(a,b,c,d,e,f,g,h) \ + t1 = ~a; \ + t2 = a ^ d; \ + t3 = b ^ t2; \ + t4 = t1 | t2; \ + t5 = c ^ t4; \ + f = b ^ t5; \ + t7 = t2 | f; \ + t8 = d ^ t7; \ + t9 = t5 & t8; \ + g = t3 ^ t9; \ + t11 = t5 ^ t8; \ + e = g ^ t11; \ + t13 = ~t5; \ + t14 = t3 & t11; \ + h = t13 ^ t14 + +/* 15 terms */ + +#define ib6(a,b,c,d,e,f,g,h) \ + t1 = ~a; \ + t2 = a ^ b; \ + t3 = c ^ t2; \ + t4 = c | t1; \ + t5 = d ^ t4; \ + f = t3 ^ t5; \ + t7 = t3 & t5; \ + t8 = t2 ^ t7; \ + t9 = b | t8; \ + h = t5 ^ t9; \ + t11 = b | h; \ + e = t8 ^ t11; \ + t13 = d & t1; \ + t14 = t3 ^ t11; \ + g = t13 ^ t14 + +/* 16 terms */ + +#define sb7(a,b,c,d,e,f,g,h) \ + t1 = b ^ c; \ + t2 = c & t1; \ + t3 = d ^ t2; \ + t4 = a ^ t3; \ + t5 = d | t1; \ + t6 = t4 & t5; \ + f = b ^ t6; \ + t8 = t3 | f; \ + t9 = a & t4; \ + h = t1 ^ t9; \ + t11 = t4 ^ t8; \ + t12 = h & t11; \ + g = t3 ^ t12; \ + t14 = ~t11; \ + t15 = h & g; \ + e = t14 ^ t15 + +/* 17 terms */ + +#define ib7(a,b,c,d,e,f,g,h) \ + t1 = a & b; \ + t2 = a | b; \ + t3 = c | t1; \ + t4 = d & t2; \ + h = t3 ^ t4; \ + t6 = ~d; \ + t7 = b ^ t4; \ + t8 = h ^ t6; \ + t9 = t7 | t8; \ + f = a ^ t9; \ + t11 = c ^ t7; \ + t12 = d | f; \ + e = t11 ^ t12; \ + t14 = a & h; \ + t15 = t3 ^ f; \ + t16 = e ^ t14; \ + g = t15 ^ t16 + +#define k_xor(r,a,b,c,d) \ + a ^= l_key[4 * r + 8]; \ + b ^= l_key[4 * r + 9]; \ + c ^= l_key[4 * r + 10]; \ + d ^= l_key[4 * r + 11] + +#define k_set(r,a,b,c,d) \ + a = l_key[4 * r + 8]; \ + b = l_key[4 * r + 9]; \ + c = l_key[4 * r + 10]; \ + d = l_key[4 * r + 11] + +#define k_get(r,a,b,c,d) \ + l_key[4 * r + 8] = a; \ + l_key[4 * r + 9] = b; \ + l_key[4 * r + 10] = c; \ + l_key[4 * r + 11] = d + +/* the linear transformation and its inverse */ + +#define rot(a,b,c,d) \ + a = rotl(a, 13); \ + c = rotl(c, 3); \ + d ^= c ^ (a << 3); \ + b ^= a ^ c; \ + d = rotl(d, 7); \ + b = rotl(b, 1); \ + a ^= b ^ d; \ + c ^= d ^ (b << 7); \ + a = rotl(a, 5); \ + c = rotl(c, 22) + +#define irot(a,b,c,d) \ + c = rotr(c, 22); \ + a = rotr(a, 5); \ + c ^= d ^ (b << 7); \ + a ^= b ^ d; \ + d = rotr(d, 7); \ + b = rotr(b, 1); \ + d ^= c ^ (a << 3); \ + b ^= a ^ c; \ + c = rotr(c, 3); \ + a = rotr(a, 13) + +/* initialise the key schedule from the user supplied key */ + +int serpent_set_key(struct cipher_context *cx, char *key, int key_len) +{ u32 *in_key = (u32 *)key; + /* l_key - storage for the key schedule */ + u32 *l_key = cx->keyinfo; + u32 i,lk,a,b,c,d,e,f,g,h; + u4byte t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16; + + key_len *= 8; + + if(key_len < 0 || key_len > 256) + + return 1; + + i = 0; lk = (key_len + 31) / 32; + + while(i < lk) + { +#ifdef BLOCK_SWAP + l_key[i] = io_swap(in_key[lk - i - 1]); +#else + l_key[i] = in_key[i]; +#endif + i++; + } + + if(key_len < 256) + { + while(i < 8) + + l_key[i++] = 0; + + i = key_len / 32; lk = 1 << key_len % 32; + + l_key[i] = l_key[i] & (lk - 1) | lk; + } + + for(i = 0; i < 132; ++i) + { + lk = l_key[i] ^ l_key[i + 3] ^ l_key[i + 5] + ^ l_key[i + 7] ^ 0x9e3779b9 ^ i; + + l_key[i + 8] = (lk << 11) | (lk >> 21); + } + + k_set( 0,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get( 0,e,f,g,h); + k_set( 1,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get( 1,e,f,g,h); + k_set( 2,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get( 2,e,f,g,h); + k_set( 3,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get( 3,e,f,g,h); + k_set( 4,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get( 4,e,f,g,h); + k_set( 5,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get( 5,e,f,g,h); + k_set( 6,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get( 6,e,f,g,h); + k_set( 7,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get( 7,e,f,g,h); + k_set( 8,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get( 8,e,f,g,h); + k_set( 9,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get( 9,e,f,g,h); + k_set(10,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get(10,e,f,g,h); + k_set(11,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get(11,e,f,g,h); + k_set(12,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get(12,e,f,g,h); + k_set(13,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get(13,e,f,g,h); + k_set(14,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get(14,e,f,g,h); + k_set(15,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get(15,e,f,g,h); + k_set(16,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get(16,e,f,g,h); + k_set(17,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get(17,e,f,g,h); + k_set(18,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get(18,e,f,g,h); + k_set(19,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get(19,e,f,g,h); + k_set(20,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get(20,e,f,g,h); + k_set(21,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get(21,e,f,g,h); + k_set(22,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get(22,e,f,g,h); + k_set(23,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get(23,e,f,g,h); + k_set(24,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get(24,e,f,g,h); + k_set(25,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get(25,e,f,g,h); + k_set(26,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get(26,e,f,g,h); + k_set(27,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get(27,e,f,g,h); + k_set(28,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get(28,e,f,g,h); + k_set(29,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get(29,e,f,g,h); + k_set(30,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get(30,e,f,g,h); + k_set(31,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get(31,e,f,g,h); + k_set(32,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get(32,e,f,g,h); + + return 0; +}; + +/* encrypt a block of text */ + +int serpent_encrypt(struct cipher_context *cx, u32 *in_blk, u32 *out_blk, + int size) +{ u32 *l_key = cx->keyinfo; + u32 a,b,c,d,e,f,g,h; + u4byte t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16; + +#ifdef BLOCK_SWAP + a = io_swap(in_blk[3]); b = io_swap(in_blk[2]); + c = io_swap(in_blk[1]); d = io_swap(in_blk[0]); +#else + a = in_blk[0]; b = in_blk[1]; c = in_blk[2]; d = in_blk[3]; +#endif + + k_xor( 0,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor( 1,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor( 2,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor( 3,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor( 4,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor( 5,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor( 6,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor( 7,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor( 8,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor( 9,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(10,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(11,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(12,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(13,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(14,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(15,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(16,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(17,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(18,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(19,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(20,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(21,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(22,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(23,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(24,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(25,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(26,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(27,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(28,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(29,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d); + k_xor(30,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h); + k_xor(31,e,f,g,h); sb7(e,f,g,h,a,b,c,d); k_xor(32,a,b,c,d); + +#ifdef BLOCK_SWAP + out_blk[3] = io_swap(a); out_blk[2] = io_swap(b); + out_blk[1] = io_swap(c); out_blk[0] = io_swap(d); +#else + out_blk[0] = a; out_blk[1] = b; out_blk[2] = c; out_blk[3] = d; +#endif + return 0; +}; + +/* decrypt a block of text */ + +int serpent_decrypt(struct cipher_context *cx, u32 *in_blk, u32 *out_blk, + int size) +{ u32 *l_key = cx->keyinfo; + u32 a,b,c,d,e,f,g,h; + u4byte t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16; + +#ifdef BLOCK_SWAP + a = io_swap(in_blk[3]); b = io_swap(in_blk[2]); + c = io_swap(in_blk[1]); d = io_swap(in_blk[0]); +#else + a = in_blk[0]; b = in_blk[1]; c = in_blk[2]; d = in_blk[3]; +#endif + + k_xor(32,a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(31,e,f,g,h); + irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(30,a,b,c,d); + irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(29,e,f,g,h); + irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(28,a,b,c,d); + irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(27,e,f,g,h); + irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(26,a,b,c,d); + irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor(25,e,f,g,h); + irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor(24,a,b,c,d); + irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(23,e,f,g,h); + irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(22,a,b,c,d); + irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(21,e,f,g,h); + irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(20,a,b,c,d); + irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(19,e,f,g,h); + irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(18,a,b,c,d); + irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor(17,e,f,g,h); + irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor(16,a,b,c,d); + irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(15,e,f,g,h); + irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(14,a,b,c,d); + irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(13,e,f,g,h); + irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(12,a,b,c,d); + irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(11,e,f,g,h); + irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(10,a,b,c,d); + irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor( 9,e,f,g,h); + irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor( 8,a,b,c,d); + irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor( 7,e,f,g,h); + irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor( 6,a,b,c,d); + irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor( 5,e,f,g,h); + irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor( 4,a,b,c,d); + irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor( 3,e,f,g,h); + irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor( 2,a,b,c,d); + irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor( 1,e,f,g,h); + irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor( 0,a,b,c,d); + +#ifdef BLOCK_SWAP + out_blk[3] = io_swap(a); out_blk[2] = io_swap(b); + out_blk[1] = io_swap(c); out_blk[0] = io_swap(d); +#else + out_blk[0] = a; out_blk[1] = b; out_blk[2] = c; out_blk[3] = d; +#endif + return 0; +}; + +static void serpent_lock(void) +{ + MOD_INC_USE_COUNT; +} + +static void serpent_unlock(void) +{ + MOD_DEC_USE_COUNT; +} + + +#define CIPHER_BITS_128 +#define CIPHER_NAME(x) serpent##x +#include "gen-cbc.h" + +DEFINE_CIPHER(SERPENT, serpent, "serpent", 16, 16); +DEFINE_CBC_CIPHER(SERPENT, serpent, "serpent-cbc", 16); + +#ifdef MODULE + int __init init_module(void) +#else + int __init init_serpent(void) +#endif +{ + if (register_cipher(&serpent)) + printk(KERN_WARNING "Couldn't register serpent encryption\n"); + if (register_cipher(&cbc_serpent)) + printk(KERN_WARNING "Couldn't register serpent-cbc encryption\n"); + + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + if (unregister_cipher(&serpent)) + printk(KERN_WARNING "Couldn't unregister serpent encryption\n"); + if (unregister_cipher(&cbc_serpent)) + printk(KERN_WARNING "Couldn't unregister serpent-cbc encryption\n"); +} +#endif + diff -ruN linux-2.2.5,pristine/crypto/testing/Makefile linux-2.2.5/crypto/testing/Makefile --- linux-2.2.5,pristine/crypto/testing/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/testing/Makefile Thu Apr 1 23:05:45 1999 @@ -0,0 +1,10 @@ + +all: + @if [ ! -f ../crypto.a ]; then \ + echo "You need to compile the kernel first"; fi + gcc -g -o speed speed.c -I../../include/ ../crypto.a + gcc -g -o test_blowfish test_blowfish.c -I../../include/ ../crypto.a + + +testcip: testcip.o + gcc -O2 -g -Wall -o testcip testcip.c -I../../include/ ../crypto.a diff -ruN linux-2.2.5,pristine/crypto/testing/speed.c linux-2.2.5/crypto/testing/speed.c --- linux-2.2.5,pristine/crypto/testing/speed.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/testing/speed.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,367 @@ +/* + * crypto/testing/speed.c + * + * Written by Alexander Kjeldaas 1998-11-23 + * + * Copyright 1998 by Alexander Kjeldaas. Redistribution of this file + * is permitted under the GNU Public License. + */ + +#define __KERNEL__ + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; + +#define printk printk_dummy + +#include +#include +#include +#include +#include +#include +#include + +#undef printk + +static long long t1, t2; + +#define PRINTF(x...) do { printf(x); fflush(stdout); } while(0) + +#define timediff(tv2, tv1) (((tv2)->tv_sec - (tv1)->tv_sec)*1000*1000 + \ + ((tv2)->tv_usec - (tv1)->tv_usec)) + +void dump_u8_buffer(u8 *buf, int number); +void dump_u16_buffer(u16 *buf, int number); +void dump_u32_buffer(u32 *buf, int number); +int my_memcmp(char *buf1, char *buf2, int size); + +int main() +{ + int cipher; + /* Register all ciphers */ + ciphers_init(); + + for (cipher = 1; cipher < MAX_CIPHER; cipher++) { + struct cipher_implementation *ci; + struct timeval tv1,tv2; + ci = find_cipher_by_id(cipher); + if (!ci) + continue; + PRINTF("Testing cipher %s, number %d..", ci->cipher_name, + ci->cipher_id); + if (!cipher_correct(ci)) { + PRINTF("seems to work\n"); + } else { + PRINTF("doesnt work!\n"); + } + + gettimeofday(&tv1, NULL); + if (test_cipher(ci,1)) + return 1; + gettimeofday(&tv2, NULL); + PRINTF("encrypt %-15s = %8d usec/MB; %6.3f MB/s; %6.3f Mb/s\n", + ci->cipher_name, timediff(&tv2,&tv1), + 1000000.0/timediff(&tv2,&tv1), + 1000000.0*8.0/timediff(&tv2,&tv1)); + gettimeofday(&tv1, NULL); + if (test_cipher(ci,0)) + return 1; + gettimeofday(&tv2, NULL); + PRINTF("decrypt %-15s = %8d usec/MB; %6.3f MB/s; %6.3f Mb/s\n", + ci->cipher_name, timediff(&tv2,&tv1), + 1000000.0/timediff(&tv2,&tv1), + 1000000.0*8.0/timediff(&tv2,&tv1)); + ci = find_cipher_by_id(cipher | CIPHER_CBC); + if (!ci) + continue; + gettimeofday(&tv1, NULL); + if (test_cbc_cipher(ci,1)) + return 1; + gettimeofday(&tv2, NULL); + PRINTF("encrypt %-15s = %8d usec/MB; %6.3f MB/s; %6.3f Mb/s\n", + ci->cipher_name, timediff(&tv2,&tv1), + 1000000.0/timediff(&tv2,&tv1), + 1000000.0*8.0/timediff(&tv2,&tv1)); + gettimeofday(&tv1, NULL); + if (test_cbc_cipher(ci,0)) + return 1; + gettimeofday(&tv2, NULL); + PRINTF("decrypt %-15s = %8d usec/MB; %6.3f MB/s; %6.3f Mb/s\n", + ci->cipher_name, timediff(&tv2,&tv1), + 1000000.0/timediff(&tv2,&tv1), + 1000000.0*8.0/timediff(&tv2,&tv1)); + } +} + +#if 0 +static inline void rdtsc(long long *x) +{ + asm volatile (".byte 0x0f, 0x31\n\t" + "movl %%eax, %0\n\t" + "movl %%edx, %1" + : "=m" (((long *)x)[0]), "=m"(((long *)x)[1]) + ::"ax","dx"); +} +#endif + +int test_cbc_cipher(struct cipher_implementation *ci, int encrypt) +{ + int fd,i,j,bs,size; + char buf[512], buf_in[512], buf_out[512]; + static u8 key[] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + struct cipher_context *cx; + cx = (struct cipher_context *) malloc(sizeof(struct cipher_context)); + cx->ci = ci; + cx->keyinfo = (u32 *) malloc(ci->key_schedule_size); + errno=ci->set_key(cx, (char *)key, sizeof(key)); + if(errno) { + perror("Can't set key"); + return 1; + } + fd = open("speed.c", O_RDONLY); + if (!fd) { + perror("Couldn't open speed.c"); + return 1; + } + if ((size = read(fd, buf, sizeof(buf))) < sizeof(buf)) { + perror("Couldn't read 512 bytes from speed.c"); + return 1; + } + close(fd); + memcpy(buf_in, buf, sizeof(buf)); + bs = ci->blocksize; + for (i = 0; i < 1024; i++) { + char *in = &buf_in[0]; + char *out = &buf_out[0]; + int (*func)(struct cipher_context *, u32 *, u32 *, int size); + + if (encrypt) + func = ci->encrypt; + else + func = ci->decrypt; + errno=func(cx, (u32 *)in, (u32 *)out, 512); + if(errno) { + perror("Can't encrypt/decrypt in cbc-mode"); + return 1; + } + in = &buf_in[0]; + out = &buf_out[0]; + func(cx, (u32 *)out, (u32 *)in, 512); + } + return 0; +} + +int test_cipher(struct cipher_implementation *ci, int encrypt) +{ + int fd,i,j,bs,size; + char buf[512], buf_in[512], buf_out[512]; + static u8 key[] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + struct cipher_context *cx; + cx = (struct cipher_context *) malloc(sizeof(struct cipher_context)); + cx->ci = ci; + cx->keyinfo = (u32 *) malloc(ci->key_schedule_size); + errno=ci->set_key(cx, (char *)key, sizeof(key)); + if(errno) { + perror("Can't set key"); + return 1; + } + fd = open("speed.c", O_RDONLY); + if (!fd) { + perror("Couldn't open speed.c"); + return 1; + } + if ((size = read(fd, buf, sizeof(buf))) < sizeof(buf)) { + perror("Couldn't read 512 bytes from speed.c"); + return 1; + } + close(fd); + memcpy(buf_in, buf, sizeof(buf)); + bs = ci->blocksize; + if (bs == 0) { + return 0; + } + for (i = 0; i < 1024; i++) { + char *in = &buf_in[0]; + char *out = &buf_out[0]; + int (*func)(struct cipher_context *, u32 *, u32 *, int size); + if (encrypt) + func = ci->encrypt; + else + func = ci->decrypt; + + for (j = 512; j > 0; j-=bs) { + errno=func(cx, (u32 *)in, (u32 *)out, bs); + if(errno) { + perror("Can't encrypt/decrypt in test_cipher()"); + return 1; + } + in += bs; out += bs; + } + in = &buf_in[0]; + out = &buf_out[0]; + for (j = 512; j > 0; j-=bs) { + func(cx, (u32 *)out, (u32 *)in, bs); + in += bs; out += bs; + } + } + return 0; +} + +int cipher_correct(struct cipher_implementation *ci) +{ + int fd,i,j,bs,size,err; + char buf[512], a1,a2,a3,buf_enc[512],a4,a5,a6, buf_dec[512]; + static u8 key[] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + struct cipher_context *cx; + cx = (struct cipher_context *) malloc(sizeof(struct cipher_context)); + cx->ci = ci; + cx->keyinfo = (u32 *) malloc(ci->key_schedule_size); + errno=ci->set_key(cx, (char *)key, sizeof(key)); + if(errno) { + printf("errno=%d key=%d\n",errno,sizeof(key)); + perror("Can't set key"); + return 1; + } + fd = open("speed.c", O_RDONLY); + if (!fd) { + perror("Couldn't open speed.c"); + return 1; + } + if ((size = read(fd, buf, sizeof(buf))) < sizeof(buf)) { + perror("Couldn't read 512 bytes from speed.c"); + return 1; + } + close(fd); + bs = ci->blocksize; + if (bs == 0) { + return 0; + } + { + char *in = &buf[0]; + char *out = &buf_enc[0]; + for (j = 512; j > 0; j-=bs) { + errno=ci->encrypt(cx, (u32 *)in, (u32 *)out, bs); + if(errno) { + perror("Can't encryp in cipher_correct"); + return 1; + } + + in += bs; out += bs; + } + in = &buf_enc[0]; + out = &buf_dec[0]; + for (j = 512; j > 0; j-=bs) { + errno=ci->decrypt(cx, (u32 *)in, (u32 *)out, bs); + if(errno) { + perror("Can't encryp in cipher_correct"); + return 1; + } + + in += bs; out += bs; + } + if (err = my_memcmp(buf, buf_dec, sizeof(buf))) { + PRINTF("failed ecb check"); + return err; + } + } + { + struct cipher_implementation *ci_cbc; + ci_cbc = find_cipher_by_id(ci->cipher_id | CIPHER_CBC); + if (!ci_cbc) + return 0; /* not supporting cbc is ok */ + memset(cx->iv, 0, sizeof(cx->iv)); + ci_cbc->encrypt(cx, (u32 *)buf, (u32 *)buf_enc, 512); + ci_cbc->decrypt(cx, (u32 *)buf_enc, (u32 *)buf_dec, 512); + if (err = my_memcmp(buf, buf_dec, sizeof(buf))) { + PRINTF("failed cbc check"); + PRINTF("\nPlaintext buffer\n"); + dump_u8_buffer(buf, 512); + PRINTF("\nEncrypted plaintext\n"); + dump_u8_buffer(buf_enc, 512); + PRINTF("\nDecrypted buffer\n"); + dump_u8_buffer(buf_dec, 512); + exit(err); + return err; + } + } +} + +asmlinkage int printk(const char * fmt, va_list args) +{ + return vprintf(fmt, args); +} + +void dump_u8_buffer(u8 *buf, int number) +{ + int i; + + for(i=0;i 1998-12-17 + * Copied from speed.c. + * + * Copyright 1998 by Raimar Falke. Redistribution of this file + * is permitted under the GNU Public License. + */ + +#define __KERNEL__ + +typedef int u32; + +#define printk printk_dummy + +#include +#include +#include +/* #include */ + +#undef printk + +#define PRINTF(x...) do { printf(x); fflush(stdout); } while(0) + +void dump_buffer (char *buf, int size); + +#define u32 unsigned int + +int main() +{ + struct cipher_implementation *ci; + struct cipher_context *cx; + + unsigned char key1[]={0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00}; + u32 input1[2]={0x00000000, 0x00000000}; + u32 output1[2]; + + /* Register all ciphers */ + ciphers_init(); + + ci = find_cipher_by_id(CIPHER_BLOWFISH); + if (!ci) + { + PRINTF("Can't find blowfish\n"); + return 1; + } + + cx = (struct cipher_context *) malloc(sizeof(struct cipher_context)); + cx->ci = ci; + cx->keyinfo = (u32 *) malloc(ci->key_schedule_size); + ci->set_key(cx, key1, sizeof(key1)); + + ci->encrypt(cx,input1,output1,8); + dump_buffer((char *)output1,8); + + ci->decrypt(cx,output1,input1,8); + dump_buffer((char *)input1,8); + + return 0; +} + +asmlinkage int printk(const char * fmt, va_list args) +{ + return vprintf(fmt, args); +} + +void dump_buffer(char *buf, int size) +{ + int i,j; + + for (i = 0; i < size; i+= 8*4) { + for (j = 0; j < 8; j++) { + PRINTF("%08x ", *(int *)buf); + buf += 4; + } + PRINTF("\n"); + } +} diff -ruN linux-2.2.5,pristine/crypto/testing/testcip.c linux-2.2.5/crypto/testing/testcip.c --- linux-2.2.5,pristine/crypto/testing/testcip.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/testing/testcip.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,214 @@ +/* + * crypto/testing/test.c + * + * Written by Alexander Kjeldaas 1998-12-17 + * + * Copyright 1998 by Alexander Kjeldaas. Redistribution of this file + * is permitted under the GNU Public License. + */ + +/* WARNING: This code isn't working yet! */ + +#define __KERNEL__ +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +#define printk printk_dummy + +#include +#include + +#undef __KERNEL__ +#undef printk + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define PRINTF(x...) do { printf(x); fsync(1); } while(0) + +void dump_buffer (unsigned char *buf, int size); +int my_memcmp(char *buf1, char *buf2, int size); +void show_usage(); +int parsehex(char *hex, char *buf); +void net2host(char *x, int size); + +int plaintext[512]; +int ciphertext[512]; +int testres[512]; +char key[512]; +int plaintextlen, ciphertextlen, keylen; + +int main(int argc, char **argv) +{ + struct cipher_implementation *ci = NULL; + struct cipher_context *cx; + int given_args = 0; + int arg, err; + + /* Register all ciphers */ + ciphers_init(); + + memset(plaintext, 0, sizeof(plaintext)); + memset(ciphertext, 0, sizeof(ciphertext)); + memset(testres, 0, sizeof(testres)); + memset(key, 0, sizeof(key)); + + + + while((arg = getopt(argc,argv,"hp:e:c:k:")) != EOF) { + switch(arg) { + case 'h': + show_usage(); + break; + case 'p': + plaintextlen = parsehex(optarg, (char *)&plaintext); + given_args |= 2; + break; + case 'e': + ciphertextlen = parsehex(optarg, (char *)&ciphertext); + given_args |= 4; + break; + case 'k': + keylen = parsehex(optarg, key); + given_args |= 8; + break; + case 'c': + if (!(ci = find_cipher_by_name(optarg))) { + PRINTF("no cipher by that name (%s)\n", optarg); + exit(1); + } + given_args |= 1; + break; + } + } + if (given_args != 15) + show_usage(); + if (ciphertextlen != plaintextlen) { + PRINTF("size of plaintext and ciphertext differ\n"); + exit(1); + } + + cx = (struct cipher_context *) malloc(sizeof(struct cipher_context)); + cx->ci = ci; + cx->keyinfo = (u32 *) malloc(ci->key_schedule_size); + if ((err = ci->set_key(cx, (char *)key, keylen))) { + PRINTF("set_key returned error %d\n", err); + exit(1); + } + if ((err = ci->encrypt(cx, plaintext, testres, plaintextlen))) { + PRINTF("encrypt returned error %d\n", err); + } + if (memcmp(testres, ciphertext, ciphertextlen)) { + PRINTF("encrypted text and ciphertext differ\n"); + PRINTF("generated ciphertext (%d bytes):\n", ciphertextlen); + dump_buffer((char *)testres, ciphertextlen); + PRINTF("correct ciphertext (%d bytes):\n", ciphertextlen); + dump_buffer((char *)ciphertext, ciphertextlen); + } + if ((err = ci->decrypt(cx, ciphertext, testres, ciphertextlen))) { + PRINTF("decrypt returned error %d\n", err); + } + if (memcmp(testres, plaintext, plaintextlen)) { + PRINTF("decrypted ciphertext and plaintext differ\n"); + PRINTF("generated plaintext (%d bytes):\n", plaintextlen); + dump_buffer((char *)testres, plaintextlen); + PRINTF("correct plaintext (%d bytes):\n", plaintextlen); + dump_buffer((char *)plaintext, plaintextlen); + } + return 0; +} + +int h2int(char c) +{ + c = tolower(c); + if (c >= '0' && c <= '9') + return c - '0'; + return c - 'a' + 10; +} + +char int2h(int h) +{ + if (h >= 0 && h <= 9) + return (char)(h + '0'); + return (char)h - 10 + 'a'; +} + +int parsehex(char *h, char *b) +{ + int size = 0; + /* int i; */ + char *hex = h, *buf = b; + if ((strlen(hex) & 1) == 1) { + *buf = h2int(*hex); + buf++; hex++; + size++; + } + for (; *hex; hex+=2, buf++, size++) { + *buf = (h2int(hex[0]) << 4) + h2int(hex[1]); + } + /* net2host(b, size); */ + return size; +} + +void net2host(char *x, int size) +{ + int *y = (int *)x; + size /= sizeof(int); + for (; size >= 0; size--) + y[size] = ntohl(y[size]); +} + +asmlinkage int printk(const char * fmt, va_list args) +{ + return vprintf(fmt, args); +} + +int request_module(const char * name) +{ + return (int) name; +} + +void dump_buffer(unsigned char *buf, int size) +{ + int i; + /* net2host(buf, size); */ + for (i = 0; i < size; i++, buf++) { + PRINTF("%c", int2h((*buf) >> 4)); + PRINTF("%c", int2h((*buf) & 0xf)); + } + + PRINTF("\n"); +} + +int my_memcmp(char *buf1, char *buf2, int size) +{ + int i; + int *b1 = (int *)buf1; + int *b2 = (int *)buf2; + for (i = 0; i < size; i+=sizeof(int)) { + if (*b1 != *b2) { + PRINTF("Error at offset %d: buf1=%0x, buf2=%0x\n", + i, *b1, *b2); + return 1; + } + b1++;b2++; + } + return memcmp(buf1, buf2, size); +} + + +void show_usage() +{ + printf("Usage: testcip [-h] -c -p -e <encryptedtext>\n"); + printf(" plaintext and encryptedtext are hex\n"); + exit(1); +} + diff -ruN linux-2.2.5,pristine/crypto/twofish3.c linux-2.2.5/crypto/twofish3.c --- linux-2.2.5,pristine/crypto/twofish3.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/crypto/twofish3.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,437 @@ +/* NOTE: This implementation has been changed from the original + source. See ChangeLog for more information. + Maintained by Alexander Kjeldaas <astor@guardian.no> + */ + +/* This is an independent implementation of the Twofish encryption */ +/* algorithm designed by Bruce Schneier and colleagues and offered */ +/* as a candidate algorithm for the US NIST Advanced Encryption */ +/* Standard (AES) effort. */ +/* */ +/* Copyright in this implementation is held by Dr B R Gladman but */ +/* I hereby give permission for its free direct or derivative use */ +/* subject to acknowledgment of its origin. */ +/* */ +/* My thanks to Niels Ferguson and the Twofish team for suggesting */ +/* an additional optimisation for this code */ +/* */ +/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 18th October 1998 */ +/* */ +/* Timing data: + +Algorithm: twofish (twofish3.c) +128 bit key: +Key Setup: 16333 cycles +Encrypt: 396 cycles = 64.6 mbits/sec +Decrypt: 397 cycles = 64.5 mbits/sec +Mean: 396 cycles = 64.6 mbits/sec +192 bit key: +Key Setup: 23378 cycles +Encrypt: 396 cycles = 64.6 mbits/sec +Decrypt: 398 cycles = 64.3 mbits/sec +Mean: 397 cycles = 64.5 mbits/sec +256 bit key: +Key Setup: 24791 cycles +Encrypt: 396 cycles = 64.6 mbits/sec +Decrypt: 395 cycles = 64.8 mbits/sec +Mean: 396 cycles = 64.7 mbits/sec + + +*/ + +#include <linux/types.h> +#include <linux/wordops.h> +#include <linux/crypto.h> + +#if 0 +#define rotl rotl32 +#define rotr rotr32 +#else +#define rotl generic_rotl32 +#define rotr generic_rotr32 +#endif + +#define Q_TABLES +#define M_TABLE +#define MK_TABLE +#define ONE_STEP + +u4byte k_len; +u4byte l_key[40]; +u4byte s_key[4]; + +/* finite field arithmetic for GF(2**8) with the modular */ +/* polynomial x**8 + x**6 + x**5 + x**3 + 1 (0x169) */ + +#define G_M 0x0169 + +u1byte tab_5b[4] = { 0, G_M >> 2, G_M >> 1, (G_M >> 1) ^ (G_M >> 2) }; +u1byte tab_ef[4] = { 0, (G_M >> 1) ^ (G_M >> 2), G_M >> 1, G_M >> 2 }; + +#define ffm_01(x) (x) +#define ffm_5b(x) ((x) ^ ((x) >> 2) ^ tab_5b[(x) & 3]) +#define ffm_ef(x) ((x) ^ ((x) >> 1) ^ ((x) >> 2) ^ tab_ef[(x) & 3]) + +u1byte ror4[16] = { 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 }; +u1byte ashx[16] = { 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7 }; + +u1byte qt0[2][16] = +{ { 8, 1, 7, 13, 6, 15, 3, 2, 0, 11, 5, 9, 14, 12, 10, 4 }, + { 2, 8, 11, 13, 15, 7, 6, 14, 3, 1, 9, 4, 0, 10, 12, 5 } +}; + +u1byte qt1[2][16] = +{ { 14, 12, 11, 8, 1, 2, 3, 5, 15, 4, 10, 6, 7, 0, 9, 13 }, + { 1, 14, 2, 11, 4, 12, 3, 7, 6, 13, 10, 5, 15, 9, 0, 8 } +}; + +u1byte qt2[2][16] = +{ { 11, 10, 5, 14, 6, 13, 9, 0, 12, 8, 15, 3, 2, 4, 7, 1 }, + { 4, 12, 7, 5, 1, 6, 9, 10, 0, 14, 13, 8, 2, 11, 3, 15 } +}; + +u1byte qt3[2][16] = +{ { 13, 7, 15, 4, 1, 2, 6, 14, 9, 11, 3, 0, 8, 5, 12, 10 }, + { 11, 9, 5, 1, 12, 3, 13, 14, 6, 4, 7, 15, 2, 0, 8, 10 } +}; + +u1byte qp(const u4byte n, const u1byte x) +{ u1byte a0, a1, a2, a3, a4, b0, b1, b2, b3, b4; + + a0 = x >> 4; b0 = x & 15; + a1 = a0 ^ b0; b1 = ror4[b0] ^ ashx[a0]; + a2 = qt0[n][a1]; b2 = qt1[n][b1]; + a3 = a2 ^ b2; b3 = ror4[b2] ^ ashx[a2]; + a4 = qt2[n][a3]; b4 = qt3[n][b3]; + return (b4 << 4) | a4; +}; + +#ifdef Q_TABLES + +u4byte qt_gen = 0; +u1byte q_tab[2][256]; + +#define q(n,x) q_tab[n][x] + +void gen_qtab(void) +{ u4byte i; + + for(i = 0; i < 256; ++i) + { + q(0,i) = qp(0, (u1byte)i); + q(1,i) = qp(1, (u1byte)i); + } +}; + +#else + +#define q(n,x) qp(n, x) + +#endif + +#ifdef M_TABLE + +u4byte mt_gen = 0; +u4byte m_tab[4][256]; + +void gen_mtab(void) +{ u4byte i, f01, f5b, fef; + + for(i = 0; i < 256; ++i) + { + f01 = q(1,i); f5b = ffm_5b(f01); fef = ffm_ef(f01); + m_tab[0][i] = f01 + (f5b << 8) + (fef << 16) + (fef << 24); + m_tab[2][i] = f5b + (fef << 8) + (f01 << 16) + (fef << 24); + + f01 = q(0,i); f5b = ffm_5b(f01); fef = ffm_ef(f01); + m_tab[1][i] = fef + (fef << 8) + (f5b << 16) + (f01 << 24); + m_tab[3][i] = f5b + (f01 << 8) + (fef << 16) + (f5b << 24); + } +}; + +#define mds(n,x) m_tab[n][x] + +#else + +#define fm_00 ffm_01 +#define fm_10 ffm_5b +#define fm_20 ffm_ef +#define fm_30 ffm_ef +#define q_0(x) q(1,x) + +#define fm_01 ffm_ef +#define fm_11 ffm_ef +#define fm_21 ffm_5b +#define fm_31 ffm_01 +#define q_1(x) q(0,x) + +#define fm_02 ffm_5b +#define fm_12 ffm_ef +#define fm_22 ffm_01 +#define fm_32 ffm_ef +#define q_2(x) q(1,x) + +#define fm_03 ffm_5b +#define fm_13 ffm_01 +#define fm_23 ffm_ef +#define fm_33 ffm_5b +#define q_3(x) q(0,x) + +#define f_0(n,x) ((u4byte)fm_0##n(x)) +#define f_1(n,x) ((u4byte)fm_1##n(x) << 8) +#define f_2(n,x) ((u4byte)fm_2##n(x) << 16) +#define f_3(n,x) ((u4byte)fm_3##n(x) << 24) + +#define mds(n,x) f_0(n,q_##n(x)) ^ f_1(n,q_##n(x)) ^ f_2(n,q_##n(x)) ^ f_3(n,q_##n(x)) + +#endif + +u4byte h_fun(const u4byte x, const u1byte key[]) +{ u1byte b0, b1, b2, b3; + + b0 = byte(x, 0); b1 = byte(x, 1); b2 = byte(x, 2); b3 = byte(x, 3); + + switch(k_len) + { + case 4: + b0 = q(1,b0) ^ key[12]; + b1 = q(0,b1) ^ key[13]; + b2 = q(0,b2) ^ key[14]; + b3 = q(1,b3) ^ key[15]; + case 3: /* fall through */ + b0 = q(1,b0) ^ key[ 8]; + b1 = q(1,b1) ^ key[ 9]; + b2 = q(0,b2) ^ key[10]; + b3 = q(0,b3) ^ key[11]; + case 2: /* fall through */ + b0 = q(0,q(0,b0) ^ key[4]) ^ key[0]; + b1 = q(0,q(1,b1) ^ key[5]) ^ key[1]; + b2 = q(1,q(0,b2) ^ key[6]) ^ key[2]; + b3 = q(1,q(1,b3) ^ key[7]) ^ key[3]; + } + +#ifdef M_TABLE + + return mds(0, b0) ^ mds(1, b1) ^ mds(2, b2) ^ mds(3, b3); + +#else + + b0 = q(1,b0); b1 = q(0,b1); b2 = q(1,b2); b3 = q(0,b3); + + return (u4byte)( b0 ^ ffm_ef(b1) ^ ffm_5b(b2) ^ ffm_5b(b3)) ^ + (u4byte)(ffm_5b(b0) ^ ffm_ef(b1) ^ ffm_ef(b2) ^ b3 ) << 8 ^ + (u4byte)(ffm_ef(b0) ^ ffm_5b(b1) ^ b2 ^ ffm_ef(b3)) << 16 ^ + (u4byte)(ffm_ef(b0) ^ b1 ^ ffm_ef(b2) ^ ffm_5b(b3)) << 24; +#endif +}; + +#ifdef MK_TABLE + +#ifdef ONE_STEP +u4byte mk_tab[4][256]; +#else +u1byte sb[4][256]; +#endif + +gen_mk_tab(u1byte key[]) +{ u1byte b0, b1, b2, b3; + u4byte i; + + for(i = 0; i < 256; ++i) + { + b0 = b1 = b2 = b3 = i; + + switch(k_len) + { + case 4: + b0 = q(1,b0) ^ key[12]; b1 = q(0,b1) ^ key[13]; + b2 = q(0,b2) ^ key[14]; b3 = q(1,b3) ^ key[15]; + case 3: /* fall through */ + b0 = q(1,b0) ^ key[ 8]; b1 = q(1,b1) ^ key[ 9]; + b2 = q(0,b2) ^ key[10]; b3 = q(0,b3) ^ key[11]; + case 2: /* fall through */ + b0 = q(0,q(0,b0) ^ key[4]) ^ key[0]; + b1 = q(0,q(1,b1) ^ key[5]) ^ key[1]; + b2 = q(1,q(0,b2) ^ key[6]) ^ key[2]; + b3 = q(1,q(1,b3) ^ key[7]) ^ key[3]; + } +#ifdef ONE_STEP + mk_tab[0][i] = mds(0, b0); + mk_tab[1][i] = mds(1, b1); + mk_tab[2][i] = mds(2, b2); + mk_tab[3][i] = mds(3, b3); +#else + sb[0][i] = b0; + sb[1][i] = b1; + sb[2][i] = b2; + sb[3][i] = b3; +#endif + } +}; + +# ifdef ONE_STEP +# define g0_fun(x) mk_tab[0][byte(x,0)] ^ mk_tab[1][byte(x,1)] \ + ^ mk_tab[2][byte(x,2)] ^ mk_tab[3][byte(x,3)] +# define g1_fun(x) mk_tab[0][byte(x,3)] ^ mk_tab[1][byte(x,0)] \ + ^ mk_tab[2][byte(x,1)] ^ mk_tab[3][byte(x,2)] +# else +# define g0_fun(x) mds(0, sb[0][byte(x,0)]) ^ mds(1, sb[1][byte(x,1)]) \ + ^ mds(2, sb[2][byte(x,2)]) ^ mds(3, sb[3][byte(x,3)]) +# define g1_fun(x) mds(0, sb[0][byte(x,3)]) ^ mds(1, sb[1][byte(x,0)]) \ + ^ mds(2, sb[2][byte(x,1)]) ^ mds(3, sb[3][byte(x,2)]) +# endif + +#else + +#define g0_fun(x) h_fun(x,(u1byte*)s_key) +#define g1_fun(x) h_fun(rotl(x,8),(u1byte*)s_key) + +#endif + +/* The (12,8) Reed Soloman code has the generator polynomial + + g(x) = x**4 + (a + 1/a) * x**3 + a * x**2 + (a + 1/a) * x + 1 + +where the coefficients are in the finite field GF(2**8) with a +modular polynomial a**8 + a**6 + a**3 + a**2 + 1. To generate the +remainder we have to start with a 12th order polynomial with our +eight input bytes as the coefficients of the 4th to 11th terms. +That is: + + m[7] * x**11 + m[6] * x**10 ... + m[0] * x**4 + 0 * x**3 +... + 0 + +We then multiply the generator polynomial by m[7] * x**7 and subtract +it - xor in GF(2**8) - from the above to eliminate the x**7 term (the +artihmetic on the coefficients is done in GF(2**8). We then multiply +the generator polynomial by x**6 * coeff(x**10) and use this to remove +the x**10 term. We carry on in this way until the x**4 term is removed +so that we are left with: + + r[3] * x**3 + r[2] * x**2 + r[1] 8 x**1 + r[0] + +which give the resulting 4 bytes of the remainder. This is equivalent +to the matrix multiplication in the Twofish description but much faster +to implement. + +*/ + +#define G_MOD 0x0000014d + +u4byte mds_rem(u4byte p0, u4byte p1) +{ u4byte i, t, u; + + for(i = 0; i < 8; ++i) + { + t = p1 >> 24; + + p1 = (p1 << 8) | (p0 >> 24); p0 <<= 8; + + u = (t << 1) ^ (t & 0x80 ? G_MOD : 0); + + p1 ^= t ^ (u << 16); + + u ^= (t >> 1) ^ (t & 0x01 ? G_MOD >> 1 : 0); + + p1 ^= (u << 8) | (u << 24); + } + + return p1; +}; + +/* initialise the key schedule from the user supplied key */ + +u4byte *set_key(const u4byte in_key[], const u4byte key_len) +{ u4byte i, a, b, me_key[4], mo_key[4]; + +#ifdef Q_TABLES + if(!qt_gen) + { + gen_qtab(); qt_gen = 1; + } +#endif + +#ifdef M_TABLE + if(!mt_gen) + { + gen_mtab(); mt_gen = 1; + } +#endif + + k_len = key_len / 64; /* 2, 3 or 4 */ + + for(i = 0; i < k_len; ++i) + { + a = in_key[i + i]; me_key[i] = a; + b = in_key[i + i + 1]; mo_key[i] = b; + s_key[k_len - i - 1] = mds_rem(a, b); + } + + for(i = 0; i < 40; i += 2) + { + a = 0x01010101 * i; b = a + 0x01010101; + a = h_fun(a, (u1byte*)me_key); + b = rotl(h_fun(b, (u1byte*)mo_key), 8); + l_key[i] = a + b; + l_key[i + 1] = rotl(a + 2 * b, 9); + } + +#ifdef MK_TABLE + gen_mk_tab((u1byte*)s_key); +#endif + + return l_key; +}; + +/* encrypt a block of text */ + +#define f_rnd(i) \ + t0 = g0_fun(blk[0]); t1 = g1_fun(blk[1]); \ + blk[2] = rotr(blk[2] ^ (t0 + t1 + l_key[4 * (i) + 8]), 1); \ + blk[3] = rotl(blk[3], 1) ^ (t0 + 2 * t1 + l_key[4 * (i) + 9]); \ + t0 = g0_fun(blk[2]); t1 = g1_fun(blk[3]); \ + blk[0] = rotr(blk[0] ^ (t0 + t1 + l_key[4 * (i) + 10]), 1); \ + blk[1] = rotl(blk[1], 1) ^ (t0 + 2 * t1 + l_key[4 * (i) + 11]) + +void encrypt(const u4byte in_blk[4], u4byte out_blk[]) +{ u4byte t0, t1, blk[4]; + + blk[0] = in_blk[0] ^ l_key[0]; + blk[1] = in_blk[1] ^ l_key[1]; + blk[2] = in_blk[2] ^ l_key[2]; + blk[3] = in_blk[3] ^ l_key[3]; + + f_rnd(0); f_rnd(1); f_rnd(2); f_rnd(3); + f_rnd(4); f_rnd(5); f_rnd(6); f_rnd(7); + + out_blk[0] = blk[2] ^ l_key[4]; + out_blk[1] = blk[3] ^ l_key[5]; + out_blk[2] = blk[0] ^ l_key[6]; + out_blk[3] = blk[1] ^ l_key[7]; +}; + +/* decrypt a block of text */ + +#define i_rnd(i) \ + t0 = g0_fun(blk[0]); t1 = g1_fun(blk[1]); \ + blk[2] = rotl(blk[2], 1) ^ (t0 + t1 + l_key[4 * (i) + 10]); \ + blk[3] = rotr(blk[3] ^ (t0 + 2 * t1 + l_key[4 * (i) + 11]), 1); \ + t0 = g0_fun(blk[2]); t1 = g1_fun(blk[3]); \ + blk[0] = rotl(blk[0], 1) ^ (t0 + t1 + l_key[4 * (i) + 8]); \ + blk[1] = rotr(blk[1] ^ (t0 + 2 * t1 + l_key[4 * (i) + 9]), 1) + +void decrypt(const u4byte in_blk[4], u4byte out_blk[4]) +{ u4byte t0, t1, blk[4]; + + blk[0] = in_blk[0] ^ l_key[4]; + blk[1] = in_blk[1] ^ l_key[5]; + blk[2] = in_blk[2] ^ l_key[6]; + blk[3] = in_blk[3] ^ l_key[7]; + + i_rnd(7); i_rnd(6); i_rnd(5); i_rnd(4); + i_rnd(3); i_rnd(2); i_rnd(1); i_rnd(0); + + out_blk[0] = blk[2] ^ l_key[0]; + out_blk[1] = blk[3] ^ l_key[1]; + out_blk[2] = blk[0] ^ l_key[2]; + out_blk[3] = blk[1] ^ l_key[3]; +}; diff -ruN linux-2.2.5,pristine/drivers/block/Config.in linux-2.2.5/drivers/block/Config.in --- linux-2.2.5,pristine/drivers/block/Config.in Tue Dec 29 20:21:49 1998 +++ linux-2.2.5/drivers/block/Config.in Thu Apr 1 23:05:45 1999 @@ -94,6 +94,19 @@ comment 'Additional Block Devices' tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP +if [ "$CONFIG_BLK_DEV_LOOP" != "n" ]; then + # GONFIG_BLK_DEV_LOOP_GEN is dependent on two other variables that + # each could be compiled as a module. + if [ "$CONFIG_CIPHERS" != "n" ]; then + if [ "$CONFIG_CIPHERS" = "m" ]; then + dep_tristate ' General encryption support (EXPERIMENTAL)' CONFIG_BLK_DEV_LOOP_GEN $CONFIG_CIPHERS + else + dep_tristate ' General encryption support (EXPERIMENTAL)' CONFIG_BLK_DEV_LOOP_GEN $CONFIG_BLK_DEV_LOOP + fi + fi + dep_tristate ' CAST 128 encryption (EXPERIMENTAL)' CONFIG_BLK_DEV_LOOP_CAST $CONFIG_BLK_DEV_LOOP + dep_tristate ' Twofish encryption (EXPERIMENTAL)' CONFIG_BLK_DEV_LOOP_FISH2 $CONFIG_BLK_DEV_LOOP +fi if [ "$CONFIG_NET" = "y" ]; then tristate 'Network block device support' CONFIG_BLK_DEV_NBD fi diff -ruN linux-2.2.5,pristine/drivers/block/Makefile linux-2.2.5/drivers/block/Makefile --- linux-2.2.5,pristine/drivers/block/Makefile Wed Sep 16 22:25:56 1998 +++ linux-2.2.5/drivers/block/Makefile Thu Apr 1 23:05:45 1999 @@ -94,6 +94,30 @@ endif endif +ifeq ($(CONFIG_BLK_DEV_LOOP_GEN),y) +LX_OBJS += loop_gen.o +else + ifeq ($(CONFIG_BLK_DEV_LOOP_GEN),m) + MX_OBJS += loop_gen.o + endif +endif + +ifeq ($(CONFIG_BLK_DEV_LOOP_CAST),y) + L_OBJS += loop_cast.o +else + ifeq ($(CONFIG_BLK_DEV_LOOP_CAST),m) + M_OBJS += loop_cast.o + endif +endif + +ifeq ($(CONFIG_BLK_DEV_LOOP_FISH2),y) + L_OBJS += loop_fish2.o +else + ifeq ($(CONFIG_BLK_DEV_LOOP_FISH2),m) + M_OBJS += loop_fish2.o + endif +endif + ifeq ($(CONFIG_BLK_DEV_HD),y) L_OBJS += hd.o endif diff -ruN linux-2.2.5,pristine/drivers/block/ll_rw_blk.c linux-2.2.5/drivers/block/ll_rw_blk.c --- linux-2.2.5,pristine/drivers/block/ll_rw_blk.c Fri Mar 12 08:20:14 1999 +++ linux-2.2.5/drivers/block/ll_rw_blk.c Thu Apr 1 23:05:45 1999 @@ -743,8 +743,26 @@ #ifdef CONFIG_BLK_DEV_RAM rd_init(); #endif +#ifdef CONFIG_BLK_DEV_LOOP_GEN + loop_gen_init(); +#endif #ifdef CONFIG_BLK_DEV_LOOP loop_init(); +#endif +#ifdef CONFIG_BLK_DEV_LOOP_SERPENT + loop_serpent_init(); +#endif +#ifdef CONFIG_BLK_DEV_LOOP_CAST + loop_cast_init(); +#endif +#ifdef CONFIG_BLK_DEV_LOOP_IDEA + loop_idea_init(); +#endif +#ifdef CONFIG_BLK_DEV_LOOP_BLOW + loop_blow_init(); +#endif +#ifdef CONFIG_BLK_DEV_LOOP_FISH2 + loop_fish2_init(); #endif #ifdef CONFIG_ISP16_CDI isp16_init(); diff -ruN linux-2.2.5,pristine/drivers/block/loop.c linux-2.2.5/drivers/block/loop.c --- linux-2.2.5,pristine/drivers/block/loop.c Thu Jan 14 19:33:36 1999 +++ linux-2.2.5/drivers/block/loop.c Thu Apr 1 23:05:45 1999 @@ -31,6 +31,10 @@ #include <linux/module.h> +#ifdef CONFIG_KMOD +#include <linux/kmod.h> +#endif /* CONFIG_KMOD */ + #include <linux/sched.h> #include <linux/fs.h> #include <linux/file.h> @@ -437,22 +441,54 @@ return err; } -static int loop_init_xfer(struct loop_device *lo, int type,struct loop_info *i) +static int loop_init_xfer(struct loop_device *lo, int type, struct loop_info *i) { int err = 0; + if (type) { struct loop_func_table *xfer = xfer_funcs[type]; + if (xfer->lock) + xfer->lock(lo); + if (xfer->init) err = xfer->init(lo, i); - if (!err) { - lo->lo_encrypt_type = type; - if (xfer->lock) - xfer->lock(lo); + + if (!err) + lo->lo_encrypt_type = i->lo_encrypt_type; + else { + if (xfer->unlock) + xfer->unlock(lo); } } return err; } +static int loop_request_xfer(int type) +{ + char module_name[50]; + + if (type >= MAX_LO_CRYPT) + return -EINVAL; + if (xfer_funcs[type]) { + return 0; + } + +#ifdef CONFIG_KMOD + sprintf(module_name, "loop-xfer-%d", type); + request_module(module_name); + if (xfer_funcs[type]) { + return 0; + } + + sprintf(module_name, "loop-xfer-gen-%x", type & ~0xf); + request_module(module_name); + if (xfer_funcs[type]) { + return 0; + } +#endif + return -EINVAL; +} + static int loop_clr_fd(struct loop_device *lo, kdev_t dev) { struct dentry *dentry = lo->lo_dentry; @@ -504,12 +540,13 @@ if ((unsigned int) info.lo_encrypt_key_size > LO_KEY_SIZE) return -EINVAL; type = info.lo_encrypt_type; - if (type >= MAX_LO_CRYPT || xfer_funcs[type] == NULL) - return -EINVAL; + err = loop_request_xfer(type); + if (err) + return err; err = loop_release_xfer(lo); if (!err) err = loop_init_xfer(lo, type, &info); - if (err) + if (err) return err; lo->lo_offset = info.lo_offset; @@ -594,7 +631,7 @@ static int lo_open(struct inode *inode, struct file *file) { struct loop_device *lo; - int dev, type; + int dev; if (!inode) @@ -609,9 +646,6 @@ } lo = &loop_dev[dev]; - type = lo->lo_encrypt_type; - if (type && xfer_funcs[type] && xfer_funcs[type]->lock) - xfer_funcs[type]->lock(lo); lo->lo_refcnt++; MOD_INC_USE_COUNT; return 0; @@ -636,10 +670,7 @@ if (lo->lo_refcnt <= 0) printk(KERN_ERR "lo_release: refcount(%d) <= 0\n", lo->lo_refcnt); else { - int type = lo->lo_encrypt_type; --lo->lo_refcnt; - if (xfer_funcs[type] && xfer_funcs[type]->unlock) - xfer_funcs[type]->unlock(lo); MOD_DEC_USE_COUNT; } return err; @@ -691,8 +722,26 @@ return 0; } +struct loop_func_table *loop_find_xfer_funcs(int number) +{ + struct loop_device *lo; + struct loop_func_table *funcs = NULL; + + if ((unsigned)number >= MAX_LO_CRYPT) + return NULL; + for (lo = &loop_dev[0]; lo < &loop_dev[MAX_LOOP]; lo++) { + int type = lo->lo_encrypt_type; + if (type == number) { + funcs = xfer_funcs[type]; + break; + } + } + return funcs; +} + EXPORT_SYMBOL(loop_register_transfer); EXPORT_SYMBOL(loop_unregister_transfer); +EXPORT_SYMBOL(loop_find_xfer_funcs); int __init loop_init(void) { diff -ruN linux-2.2.5,pristine/drivers/block/loop_cast.c linux-2.2.5/drivers/block/loop_cast.c --- linux-2.2.5,pristine/drivers/block/loop_cast.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/drivers/block/loop_cast.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,1333 @@ +/* + * linux/drivers/block/loop_cast.c + * + * PURPOSE + * CAST-128 encryption loop data transformation ("cast"). + * + * DESCRIPTION + * + * HISTORY + * May 23, 1997 - Andrew E. Mileski + * Written, tested, and released. + */ +#include <linux/blkdev.h> +#include <linux/fs.h> +#include <linux/init.h> +#include <linux/locks.h> +#include <linux/loop.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/slab.h> + +/* Optimize the CAST-128 code */ +#if defined(CONFIG_M386) +#define i386 +#endif +#if defined(CONFIG_M486) || defined(CONFIG_M586) || defined(CONFIG_M686) +#define i486 +#endif + +typedef __u32 U32; +typedef __u8 U8; + +/* Internal Prototypes */ +static void cast_keySchedule(U32 *, U32 *); +static U32 cast_decrypt(U32 *, U32 *, U32 *, U32); +static U32 cast_encrypt(U32 *, U32 *, U32 *, U32); +static int cast_release(struct loop_device *lo); +static int cast_init(struct loop_device *lo, struct loop_info *info); +static int cast_transfer(struct loop_device *lo, int cmd, char *raw_buf, + char *loop_buf, int size, int real_block); + +/* Loop device specific data */ +struct cast_public { + U32 key[LO_KEY_SIZE >> 2]; +}; +struct cast_private { + U32 skeys[32]; +}; +struct cast_data { + struct cast_public public; + struct cast_private private; +}; + + +static void cast_lock(struct loop_device *lo) +{ + MOD_INC_USE_COUNT; +} + +static void cast_unlock(struct loop_device *lo) +{ + MOD_DEC_USE_COUNT; +} + +/* Loop data transformation entry for "cast" */ +static struct loop_func_table cast_funcs = +{ + number: LO_CRYPT_CAST128, + transfer: cast_transfer, + init: cast_init, + release: cast_release, + lock: cast_lock, + unlock: cast_unlock +}; + +/* + * loop_cast_init / init_module + * + * PURPOSE + * Register the loop data transformation "cast". + * + * HISTORY + * May 3, 1997 - Andrew E. Mileski + * Written, tested, and released. + */ +#if defined(MODULE) +extern int init_module(void) +#else +int __init loop_cast_init(void) +#endif defined(MODULE) +{ + int err; + + if ((err=loop_register_transfer(&cast_funcs))) { + printk(KERN_WARNING "Couldn't register cast-128 encryption\n"); + return err; + } + + printk(KERN_INFO "loop: registered cast-128 encryption \n"); + + return 0; +} + +#if defined(MODULE) +/* + * cleanup_module + * + * PURPOSE + * Unregister the loop data transformation "cast". + * + * HISTORY + * May 3, 1997 - Andrew E. Mileski + * Written, tested, and released. + */ +extern +void cleanup_module (void) +{ + loop_unregister_transfer(LO_CRYPT_CAST128); +} +#endif defined(MODULE) + +static int cast_init(struct loop_device *lo, struct loop_info *info) +{ + struct cast_data *key; + if (info->lo_encrypt_key_size != 16) + return -EINVAL; + + key=(struct cast_data *)kmalloc(sizeof(struct cast_data),GFP_KERNEL); + if (key == NULL) + return -ENOMEM; + + lo->key_data=key; + memcpy(key->public.key, info->lo_encrypt_key, 16); + cast_keySchedule(key->public.key, key->private.skeys); + MOD_INC_USE_COUNT; + return 0; +} + +static int cast_release(struct loop_device *lo) +{ + if (lo->key_data != NULL) + { + kfree(lo->key_data); + lo->key_data=NULL; + MOD_DEC_USE_COUNT; + } + return (0); +} + +static int cast_transfer(struct loop_device *lo, int cmd, char *raw_buf, + char *loop_buf, int size, int real_block) +{ + register U32 *K, *M, *C, result; + K = ((struct cast_data *) (lo->key_data))->private.skeys; + M = (U32 *)loop_buf; + C = (U32 *)raw_buf; + if (cmd == READ) { + /* Decrypt */ + result = cast_decrypt(K, M, C, size); + + /* Pad if necessary */ + if (result) { + C = C + ((size - result) >> 2); + M = M + ((size - result) >> 2); + memcpy(M, C, result); + memset(((U8 *)M) + result, 0, 8 - result); + cast_decrypt(K, M, M, size); + } + } else { + /* Encrypt */ + result = cast_encrypt(K, M, C, size); + + /* Pad if necessary */ + if (result) { + C = C + ((size - result) >> 2); + M = M + ((size - result) >> 2); + memcpy(C, M, result); + memset(((U8 *)C) + result, 0, 8 - result); + cast_decrypt(K, C, C, size); + } + } + return 0; +} + + +/* + * cast.c + * + * PURPOSE + * The CAST-128 data encryption/decryption algorithm. + * + * DESCRIPTION + * The following code should be completely portable. + * Refer to RFC 2144 for complete details on the algorithm. + * + * This code _only_ implements keys of 128 bits in length, though the + * CAST algorithm supports keys of lengths 40 bits to 128 bits in steps + * of 8 bits. + * + * Make sure that the type U32 is a 32 bit unsigned integer, and that + * U8 is an 8 bit unsigned integer. + * + * For best performance, define as many of the following as possible: + * BIG_ENDIAN - Native byte order is 1234. + * These only apply when using GNU C: + * __GNUC__ - GNU C defines this. + * i386 - Reduce cast_rol() to "roll". + * i486 - Reduce htonl() and ntohl() to "bswapl". + * + * To run a full maintenance test (Appendix B, section 2), and a + * processing speed test, uncomment the line "#define DO_TESTS". + * + * EXPORT INFO + * This software is 100% of Canadian origin (both the algorithm and + * the code), and is NOT subject to U.S. ITAR export restrictions. + * Only Canadian export restictions apply. + * + * Both the algorithm and this code are both "in the public domain", + * with the restriction that the algorithm and code authors maintain + * the copyrights to their work. + * + * HISTORY + * May 23, 1997 - Andrew E. Mileski <aem@netcom.ca> + * Implemented RFC 2144 in C, tested, and released. + */ + +/* #define BIG_ENDIAN */ +/* #define DO_TESTS */ +/* #define i386 */ +/* #define i486 */ + +/* These should be adjusted to the machine used */ +/* typedef unsigned U32; */ +/* typedef unsigned char U8; */ + +#if !defined(__GNUC__) +#if defined(__STDC__) +#define __inline__ inline +#else /* !defined(__STDC__) */ +#error For speed, you should rewrite all the inline functions as macros. +#endif /* !defined(__STDC__) */ +#endif /* !defined(__GNUC__) */ + +#define EXTERNAL_LINKAGE static +#define INTERNAL_LINKAGE static + +/* Prototypes */ +EXTERNAL_LINKAGE void cast_keySchedule(U32 *, U32 *); +EXTERNAL_LINKAGE U32 cast_encrypt(U32 *, U32 *, U32 *, U32); +EXTERNAL_LINKAGE U32 cast_decrypt(U32 *, U32 *, U32 *, U32); + +/* First substitution box (S box) */ +INTERNAL_LINKAGE U32 S1[256] = { + 0x30fb40d4U, 0x9fa0ff0bU, 0x6beccd2fU, 0x3f258c7aU, + 0x1e213f2fU, 0x9c004dd3U, 0x6003e540U, 0xcf9fc949U, + 0xbfd4af27U, 0x88bbbdb5U, 0xe2034090U, 0x98d09675U, + 0x6e63a0e0U, 0x15c361d2U, 0xc2e7661dU, 0x22d4ff8eU, + 0x28683b6fU, 0xc07fd059U, 0xff2379c8U, 0x775f50e2U, + 0x43c340d3U, 0xdf2f8656U, 0x887ca41aU, 0xa2d2bd2dU, + 0xa1c9e0d6U, 0x346c4819U, 0x61b76d87U, 0x22540f2fU, + 0x2abe32e1U, 0xaa54166bU, 0x22568e3aU, 0xa2d341d0U, + 0x66db40c8U, 0xa784392fU, 0x004dff2fU, 0x2db9d2deU, + 0x97943facU, 0x4a97c1d8U, 0x527644b7U, 0xb5f437a7U, + 0xb82cbaefU, 0xd751d159U, 0x6ff7f0edU, 0x5a097a1fU, + 0x827b68d0U, 0x90ecf52eU, 0x22b0c054U, 0xbc8e5935U, + 0x4b6d2f7fU, 0x50bb64a2U, 0xd2664910U, 0xbee5812dU, + 0xb7332290U, 0xe93b159fU, 0xb48ee411U, 0x4bff345dU, + 0xfd45c240U, 0xad31973fU, 0xc4f6d02eU, 0x55fc8165U, + 0xd5b1caadU, 0xa1ac2daeU, 0xa2d4b76dU, 0xc19b0c50U, + 0x882240f2U, 0x0c6e4f38U, 0xa4e4bfd7U, 0x4f5ba272U, + 0x564c1d2fU, 0xc59c5319U, 0xb949e354U, 0xb04669feU, + 0xb1b6ab8aU, 0xc71358ddU, 0x6385c545U, 0x110f935dU, + 0x57538ad5U, 0x6a390493U, 0xe63d37e0U, 0x2a54f6b3U, + 0x3a787d5fU, 0x6276a0b5U, 0x19a6fcdfU, 0x7a42206aU, + 0x29f9d4d5U, 0xf61b1891U, 0xbb72275eU, 0xaa508167U, + 0x38901091U, 0xc6b505ebU, 0x84c7cb8cU, 0x2ad75a0fU, + 0x874a1427U, 0xa2d1936bU, 0x2ad286afU, 0xaa56d291U, + 0xd7894360U, 0x425c750dU, 0x93b39e26U, 0x187184c9U, + 0x6c00b32dU, 0x73e2bb14U, 0xa0bebc3cU, 0x54623779U, + 0x64459eabU, 0x3f328b82U, 0x7718cf82U, 0x59a2cea6U, + 0x04ee002eU, 0x89fe78e6U, 0x3fab0950U, 0x325ff6c2U, + 0x81383f05U, 0x6963c5c8U, 0x76cb5ad6U, 0xd49974c9U, + 0xca180dcfU, 0x380782d5U, 0xc7fa5cf6U, 0x8ac31511U, + 0x35e79e13U, 0x47da91d0U, 0xf40f9086U, 0xa7e2419eU, + 0x31366241U, 0x051ef495U, 0xaa573b04U, 0x4a805d8dU, + 0x548300d0U, 0x00322a3cU, 0xbf64cddfU, 0xba57a68eU, + 0x75c6372bU, 0x50afd341U, 0xa7c13275U, 0x915a0bf5U, + 0x6b54bfabU, 0x2b0b1426U, 0xab4cc9d7U, 0x449ccd82U, + 0xf7fbf265U, 0xab85c5f3U, 0x1b55db94U, 0xaad4e324U, + 0xcfa4bd3fU, 0x2deaa3e2U, 0x9e204d02U, 0xc8bd25acU, + 0xeadf55b3U, 0xd5bd9e98U, 0xe31231b2U, 0x2ad5ad6cU, + 0x954329deU, 0xadbe4528U, 0xd8710f69U, 0xaa51c90fU, + 0xaa786bf6U, 0x22513f1eU, 0xaa51a79bU, 0x2ad344ccU, + 0x7b5a41f0U, 0xd37cfbadU, 0x1b069505U, 0x41ece491U, + 0xb4c332e6U, 0x032268d4U, 0xc9600accU, 0xce387e6dU, + 0xbf6bb16cU, 0x6a70fb78U, 0x0d03d9c9U, 0xd4df39deU, + 0xe01063daU, 0x4736f464U, 0x5ad328d8U, 0xb347cc96U, + 0x75bb0fc3U, 0x98511bfbU, 0x4ffbcc35U, 0xb58bcf6aU, + 0xe11f0abcU, 0xbfc5fe4aU, 0xa70aec10U, 0xac39570aU, + 0x3f04442fU, 0x6188b153U, 0xe0397a2eU, 0x5727cb79U, + 0x9ceb418fU, 0x1cacd68dU, 0x2ad37c96U, 0x0175cb9dU, + 0xc69dff09U, 0xc75b65f0U, 0xd9db40d8U, 0xec0e7779U, + 0x4744ead4U, 0xb11c3274U, 0xdd24cb9eU, 0x7e1c54bdU, + 0xf01144f9U, 0xd2240eb1U, 0x9675b3fdU, 0xa3ac3755U, + 0xd47c27afU, 0x51c85f4dU, 0x56907596U, 0xa5bb15e6U, + 0x580304f0U, 0xca042cf1U, 0x011a37eaU, 0x8dbfaadbU, + 0x35ba3e4aU, 0x3526ffa0U, 0xc37b4d09U, 0xbc306ed9U, + 0x98a52666U, 0x5648f725U, 0xff5e569dU, 0x0ced63d0U, + 0x7c63b2cfU, 0x700b45e1U, 0xd5ea50f1U, 0x85a92872U, + 0xaf1fbda7U, 0xd4234870U, 0xa7870bf3U, 0x2d3b4d79U, + 0x42e04198U, 0x0cd0ede7U, 0x26470db8U, 0xf881814cU, + 0x474d6ad7U, 0x7c0c5e5cU, 0xd1231959U, 0x381b7298U, + 0xf5d2f4dbU, 0xab838653U, 0x6e2f1e23U, 0x83719c9eU, + 0xbd91e046U, 0x9a56456eU, 0xdc39200cU, 0x20c8c571U, + 0x962bda1cU, 0xe1e696ffU, 0xb141ab08U, 0x7cca89b9U, + 0x1a69e783U, 0x02cc4843U, 0xa2f7c579U, 0x429ef47dU, + 0x427b169cU, 0x5ac9f049U, 0xdd8f0f00U, 0x5c8165bfU +}; + +/* Second substitution box (S box) */ +INTERNAL_LINKAGE U32 S2[256] = { + 0x1f201094U, 0xef0ba75bU, 0x69e3cf7eU, 0x393f4380U, + 0xfe61cf7aU, 0xeec5207aU, 0x55889c94U, 0x72fc0651U, + 0xada7ef79U, 0x4e1d7235U, 0xd55a63ceU, 0xde0436baU, + 0x99c430efU, 0x5f0c0794U, 0x18dcdb7dU, 0xa1d6eff3U, + 0xa0b52f7bU, 0x59e83605U, 0xee15b094U, 0xe9ffd909U, + 0xdc440086U, 0xef944459U, 0xba83ccb3U, 0xe0c3cdfbU, + 0xd1da4181U, 0x3b092ab1U, 0xf997f1c1U, 0xa5e6cf7bU, + 0x01420ddbU, 0xe4e7ef5bU, 0x25a1ff41U, 0xe180f806U, + 0x1fc41080U, 0x179bee7aU, 0xd37ac6a9U, 0xfe5830a4U, + 0x98de8b7fU, 0x77e83f4eU, 0x79929269U, 0x24fa9f7bU, + 0xe113c85bU, 0xacc40083U, 0xd7503525U, 0xf7ea615fU, + 0x62143154U, 0x0d554b63U, 0x5d681121U, 0xc866c359U, + 0x3d63cf73U, 0xcee234c0U, 0xd4d87e87U, 0x5c672b21U, + 0x071f6181U, 0x39f7627fU, 0x361e3084U, 0xe4eb573bU, + 0x602f64a4U, 0xd63acd9cU, 0x1bbc4635U, 0x9e81032dU, + 0x2701f50cU, 0x99847ab4U, 0xa0e3df79U, 0xba6cf38cU, + 0x10843094U, 0x2537a95eU, 0xf46f6ffeU, 0xa1ff3b1fU, + 0x208cfb6aU, 0x8f458c74U, 0xd9e0a227U, 0x4ec73a34U, + 0xfc884f69U, 0x3e4de8dfU, 0xef0e0088U, 0x3559648dU, + 0x8a45388cU, 0x1d804366U, 0x721d9bfdU, 0xa58684bbU, + 0xe8256333U, 0x844e8212U, 0x128d8098U, 0xfed33fb4U, + 0xce280ae1U, 0x27e19ba5U, 0xd5a6c252U, 0xe49754bdU, + 0xc5d655ddU, 0xeb667064U, 0x77840b4dU, 0xa1b6a801U, + 0x84db26a9U, 0xe0b56714U, 0x21f043b7U, 0xe5d05860U, + 0x54f03084U, 0x066ff472U, 0xa31aa153U, 0xdadc4755U, + 0xb5625dbfU, 0x68561be6U, 0x83ca6b94U, 0x2d6ed23bU, + 0xeccf01dbU, 0xa6d3d0baU, 0xb6803d5cU, 0xaf77a709U, + 0x33b4a34cU, 0x397bc8d6U, 0x5ee22b95U, 0x5f0e5304U, + 0x81ed6f61U, 0x20e74364U, 0xb45e1378U, 0xde18639bU, + 0x881ca122U, 0xb96726d1U, 0x8049a7e8U, 0x22b7da7bU, + 0x5e552d25U, 0x5272d237U, 0x79d2951cU, 0xc60d894cU, + 0x488cb402U, 0x1ba4fe5bU, 0xa4b09f6bU, 0x1ca815cfU, + 0xa20c3005U, 0x8871df63U, 0xb9de2fcbU, 0x0cc6c9e9U, + 0x0beeff53U, 0xe3214517U, 0xb4542835U, 0x9f63293cU, + 0xee41e729U, 0x6e1d2d7cU, 0x50045286U, 0x1e6685f3U, + 0xf33401c6U, 0x30a22c95U, 0x31a70850U, 0x60930f13U, + 0x73f98417U, 0xa1269859U, 0xec645c44U, 0x52c877a9U, + 0xcdff33a6U, 0xa02b1741U, 0x7cbad9a2U, 0x2180036fU, + 0x50d99c08U, 0xcb3f4861U, 0xc26bd765U, 0x64a3f6abU, + 0x80342676U, 0x25a75e7bU, 0xe4e6d1fcU, 0x20c710e6U, + 0xcdf0b680U, 0x17844d3bU, 0x31eef84dU, 0x7e0824e4U, + 0x2ccb49ebU, 0x846a3baeU, 0x8ff77888U, 0xee5d60f6U, + 0x7af75673U, 0x2fdd5cdbU, 0xa11631c1U, 0x30f66f43U, + 0xb3faec54U, 0x157fd7faU, 0xef8579ccU, 0xd152de58U, + 0xdb2ffd5eU, 0x8f32ce19U, 0x306af97aU, 0x02f03ef8U, + 0x99319ad5U, 0xc242fa0fU, 0xa7e3ebb0U, 0xc68e4906U, + 0xb8da230cU, 0x80823028U, 0xdcdef3c8U, 0xd35fb171U, + 0x088a1bc8U, 0xbec0c560U, 0x61a3c9e8U, 0xbca8f54dU, + 0xc72feffaU, 0x22822e99U, 0x82c570b4U, 0xd8d94e89U, + 0x8b1c34bcU, 0x301e16e6U, 0x273be979U, 0xb0ffeaa6U, + 0x61d9b8c6U, 0x00b24869U, 0xb7ffce3fU, 0x08dc283bU, + 0x43daf65aU, 0xf7e19798U, 0x7619b72fU, 0x8f1c9ba4U, + 0xdc8637a0U, 0x16a7d3b1U, 0x9fc393b7U, 0xa7136eebU, + 0xc6bcc63eU, 0x1a513742U, 0xef6828bcU, 0x520365d6U, + 0x2d6a77abU, 0x3527ed4bU, 0x821fd216U, 0x095c6e2eU, + 0xdb92f2fbU, 0x5eea29cbU, 0x145892f5U, 0x91584f7fU, + 0x5483697bU, 0x2667a8ccU, 0x85196048U, 0x8c4baceaU, + 0x833860d4U, 0x0d23e0f9U, 0x6c387e8aU, 0x0ae6d249U, + 0xb284600cU, 0xd835731dU, 0xdcb1c647U, 0xac4c56eaU, + 0x3ebd81b3U, 0x230eabb0U, 0x6438bc87U, 0xf0b5b1faU, + 0x8f5ea2b3U, 0xfc184642U, 0x0a036b7aU, 0x4fb089bdU, + 0x649da589U, 0xa345415eU, 0x5c038323U, 0x3e5d3bb9U, + 0x43d79572U, 0x7e6dd07cU, 0x06dfdf1eU, 0x6c6cc4efU, + 0x7160a539U, 0x73bfbe70U, 0x83877605U, 0x4523ecf1U +}; + +/* Third substitution box (S box) */ +INTERNAL_LINKAGE U32 S3[256] = { + 0x8defc240U, 0x25fa5d9fU, 0xeb903dbfU, 0xe810c907U, + 0x47607fffU, 0x369fe44bU, 0x8c1fc644U, 0xaececa90U, + 0xbeb1f9bfU, 0xeefbcaeaU, 0xe8cf1950U, 0x51df07aeU, + 0x920e8806U, 0xf0ad0548U, 0xe13c8d83U, 0x927010d5U, + 0x11107d9fU, 0x07647db9U, 0xb2e3e4d4U, 0x3d4f285eU, + 0xb9afa820U, 0xfade82e0U, 0xa067268bU, 0x8272792eU, + 0x553fb2c0U, 0x489ae22bU, 0xd4ef9794U, 0x125e3fbcU, + 0x21fffceeU, 0x825b1bfdU, 0x9255c5edU, 0x1257a240U, + 0x4e1a8302U, 0xbae07fffU, 0x528246e7U, 0x8e57140eU, + 0x3373f7bfU, 0x8c9f8188U, 0xa6fc4ee8U, 0xc982b5a5U, + 0xa8c01db7U, 0x579fc264U, 0x67094f31U, 0xf2bd3f5fU, + 0x40fff7c1U, 0x1fb78dfcU, 0x8e6bd2c1U, 0x437be59bU, + 0x99b03dbfU, 0xb5dbc64bU, 0x638dc0e6U, 0x55819d99U, + 0xa197c81cU, 0x4a012d6eU, 0xc5884a28U, 0xccc36f71U, + 0xb843c213U, 0x6c0743f1U, 0x8309893cU, 0x0feddd5fU, + 0x2f7fe850U, 0xd7c07f7eU, 0x02507fbfU, 0x5afb9a04U, + 0xa747d2d0U, 0x1651192eU, 0xaf70bf3eU, 0x58c31380U, + 0x5f98302eU, 0x727cc3c4U, 0x0a0fb402U, 0x0f7fef82U, + 0x8c96fdadU, 0x5d2c2aaeU, 0x8ee99a49U, 0x50da88b8U, + 0x8427f4a0U, 0x1eac5790U, 0x796fb449U, 0x8252dc15U, + 0xefbd7d9bU, 0xa672597dU, 0xada840d8U, 0x45f54504U, + 0xfa5d7403U, 0xe83ec305U, 0x4f91751aU, 0x925669c2U, + 0x23efe941U, 0xa903f12eU, 0x60270df2U, 0x0276e4b6U, + 0x94fd6574U, 0x927985b2U, 0x8276dbcbU, 0x02778176U, + 0xf8af918dU, 0x4e48f79eU, 0x8f616ddfU, 0xe29d840eU, + 0x842f7d83U, 0x340ce5c8U, 0x96bbb682U, 0x93b4b148U, + 0xef303cabU, 0x984faf28U, 0x779faf9bU, 0x92dc560dU, + 0x224d1e20U, 0x8437aa88U, 0x7d29dc96U, 0x2756d3dcU, + 0x8b907ceeU, 0xb51fd240U, 0xe7c07ce3U, 0xe566b4a1U, + 0xc3e9615eU, 0x3cf8209dU, 0x6094d1e3U, 0xcd9ca341U, + 0x5c76460eU, 0x00ea983bU, 0xd4d67881U, 0xfd47572cU, + 0xf76cedd9U, 0xbda8229cU, 0x127dadaaU, 0x438a074eU, + 0x1f97c090U, 0x081bdb8aU, 0x93a07ebeU, 0xb938ca15U, + 0x97b03cffU, 0x3dc2c0f8U, 0x8d1ab2ecU, 0x64380e51U, + 0x68cc7bfbU, 0xd90f2788U, 0x12490181U, 0x5de5ffd4U, + 0xdd7ef86aU, 0x76a2e214U, 0xb9a40368U, 0x925d958fU, + 0x4b39fffaU, 0xba39aee9U, 0xa4ffd30bU, 0xfaf7933bU, + 0x6d498623U, 0x193cbcfaU, 0x27627545U, 0x825cf47aU, + 0x61bd8ba0U, 0xd11e42d1U, 0xcead04f4U, 0x127ea392U, + 0x10428db7U, 0x8272a972U, 0x9270c4a8U, 0x127de50bU, + 0x285ba1c8U, 0x3c62f44fU, 0x35c0eaa5U, 0xe805d231U, + 0x428929fbU, 0xb4fcdf82U, 0x4fb66a53U, 0x0e7dc15bU, + 0x1f081fabU, 0x108618aeU, 0xfcfd086dU, 0xf9ff2889U, + 0x694bcc11U, 0x236a5caeU, 0x12deca4dU, 0x2c3f8cc5U, + 0xd2d02dfeU, 0xf8ef5896U, 0xe4cf52daU, 0x95155b67U, + 0x494a488cU, 0xb9b6a80cU, 0x5c8f82bcU, 0x89d36b45U, + 0x3a609437U, 0xec00c9a9U, 0x44715253U, 0x0a874b49U, + 0xd773bc40U, 0x7c34671cU, 0x02717ef6U, 0x4feb5536U, + 0xa2d02fffU, 0xd2bf60c4U, 0xd43f03c0U, 0x50b4ef6dU, + 0x07478cd1U, 0x006e1888U, 0xa2e53f55U, 0xb9e6d4bcU, + 0xa2048016U, 0x97573833U, 0xd7207d67U, 0xde0f8f3dU, + 0x72f87b33U, 0xabcc4f33U, 0x7688c55dU, 0x7b00a6b0U, + 0x947b0001U, 0x570075d2U, 0xf9bb88f8U, 0x8942019eU, + 0x4264a5ffU, 0x856302e0U, 0x72dbd92bU, 0xee971b69U, + 0x6ea22fdeU, 0x5f08ae2bU, 0xaf7a616dU, 0xe5c98767U, + 0xcf1febd2U, 0x61efc8c2U, 0xf1ac2571U, 0xcc8239c2U, + 0x67214cb8U, 0xb1e583d1U, 0xb7dc3e62U, 0x7f10bdceU, + 0xf90a5c38U, 0x0ff0443dU, 0x606e6dc6U, 0x60543a49U, + 0x5727c148U, 0x2be98a1dU, 0x8ab41738U, 0x20e1be24U, + 0xaf96da0fU, 0x68458425U, 0x99833be5U, 0x600d457dU, + 0x282f9350U, 0x8334b362U, 0xd91d1120U, 0x2b6d8da0U, + 0x642b1e31U, 0x9c305a00U, 0x52bce688U, 0x1b03588aU, + 0xf7baefd5U, 0x4142ed9cU, 0xa4315c11U, 0x83323ec5U, + 0xdfef4636U, 0xa133c501U, 0xe9d3531cU, 0xee353783U +}; + +/* Fourth substitution box (S box) */ +INTERNAL_LINKAGE U32 S4[256] = { + 0x9db30420U, 0x1fb6e9deU, 0xa7be7befU, 0xd273a298U, + 0x4a4f7bdbU, 0x64ad8c57U, 0x85510443U, 0xfa020ed1U, + 0x7e287affU, 0xe60fb663U, 0x095f35a1U, 0x79ebf120U, + 0xfd059d43U, 0x6497b7b1U, 0xf3641f63U, 0x241e4adfU, + 0x28147f5fU, 0x4fa2b8cdU, 0xc9430040U, 0x0cc32220U, + 0xfdd30b30U, 0xc0a5374fU, 0x1d2d00d9U, 0x24147b15U, + 0xee4d111aU, 0x0fca5167U, 0x71ff904cU, 0x2d195ffeU, + 0x1a05645fU, 0x0c13fefeU, 0x081b08caU, 0x05170121U, + 0x80530100U, 0xe83e5efeU, 0xac9af4f8U, 0x7fe72701U, + 0xd2b8ee5fU, 0x06df4261U, 0xbb9e9b8aU, 0x7293ea25U, + 0xce84ffdfU, 0xf5718801U, 0x3dd64b04U, 0xa26f263bU, + 0x7ed48400U, 0x547eebe6U, 0x446d4ca0U, 0x6cf3d6f5U, + 0x2649abdfU, 0xaea0c7f5U, 0x36338cc1U, 0x503f7e93U, + 0xd3772061U, 0x11b638e1U, 0x72500e03U, 0xf80eb2bbU, + 0xabe0502eU, 0xec8d77deU, 0x57971e81U, 0xe14f6746U, + 0xc9335400U, 0x6920318fU, 0x081dbb99U, 0xffc304a5U, + 0x4d351805U, 0x7f3d5ce3U, 0xa6c866c6U, 0x5d5bcca9U, + 0xdaec6feaU, 0x9f926f91U, 0x9f46222fU, 0x3991467dU, + 0xa5bf6d8eU, 0x1143c44fU, 0x43958302U, 0xd0214eebU, + 0x022083b8U, 0x3fb6180cU, 0x18f8931eU, 0x281658e6U, + 0x26486e3eU, 0x8bd78a70U, 0x7477e4c1U, 0xb506e07cU, + 0xf32d0a25U, 0x79098b02U, 0xe4eabb81U, 0x28123b23U, + 0x69dead38U, 0x1574ca16U, 0xdf871b62U, 0x211c40b7U, + 0xa51a9ef9U, 0x0014377bU, 0x041e8ac8U, 0x09114003U, + 0xbd59e4d2U, 0xe3d156d5U, 0x4fe876d5U, 0x2f91a340U, + 0x557be8deU, 0x00eae4a7U, 0x0ce5c2ecU, 0x4db4bba6U, + 0xe756bdffU, 0xdd3369acU, 0xec17b035U, 0x06572327U, + 0x99afc8b0U, 0x56c8c391U, 0x6b65811cU, 0x5e146119U, + 0x6e85cb75U, 0xbe07c002U, 0xc2325577U, 0x893ff4ecU, + 0x5bbfc92dU, 0xd0ec3b25U, 0xb7801ab7U, 0x8d6d3b24U, + 0x20c763efU, 0xc366a5fcU, 0x9c382880U, 0x0ace3205U, + 0xaac9548aU, 0xeca1d7c7U, 0x041afa32U, 0x1d16625aU, + 0x6701902cU, 0x9b757a54U, 0x31d477f7U, 0x9126b031U, + 0x36cc6fdbU, 0xc70b8b46U, 0xd9e66a48U, 0x56e55a79U, + 0x026a4cebU, 0x52437effU, 0x2f8f76b4U, 0x0df980a5U, + 0x8674cde3U, 0xedda04ebU, 0x17a9be04U, 0x2c18f4dfU, + 0xb7747f9dU, 0xab2af7b4U, 0xefc34d20U, 0x2e096b7cU, + 0x1741a254U, 0xe5b6a035U, 0x213d42f6U, 0x2c1c7c26U, + 0x61c2f50fU, 0x6552daf9U, 0xd2c231f8U, 0x25130f69U, + 0xd8167fa2U, 0x0418f2c8U, 0x001a96a6U, 0x0d1526abU, + 0x63315c21U, 0x5e0a72ecU, 0x49bafefdU, 0x187908d9U, + 0x8d0dbd86U, 0x311170a7U, 0x3e9b640cU, 0xcc3e10d7U, + 0xd5cad3b6U, 0x0caec388U, 0xf73001e1U, 0x6c728affU, + 0x71eae2a1U, 0x1f9af36eU, 0xcfcbd12fU, 0xc1de8417U, + 0xac07be6bU, 0xcb44a1d8U, 0x8b9b0f56U, 0x013988c3U, + 0xb1c52fcaU, 0xb4be31cdU, 0xd8782806U, 0x12a3a4e2U, + 0x6f7de532U, 0x58fd7eb6U, 0xd01ee900U, 0x24adffc2U, + 0xf4990fc5U, 0x9711aac5U, 0x001d7b95U, 0x82e5e7d2U, + 0x109873f6U, 0x00613096U, 0xc32d9521U, 0xada121ffU, + 0x29908415U, 0x7fbb977fU, 0xaf9eb3dbU, 0x29c9ed2aU, + 0x5ce2a465U, 0xa730f32cU, 0xd0aa3fe8U, 0x8a5cc091U, + 0xd49e2ce7U, 0x0ce454a9U, 0xd60acd86U, 0x015f1919U, + 0x77079103U, 0xdea03af6U, 0x78a8565eU, 0xdee356dfU, + 0x21f05cbeU, 0x8b75e387U, 0xb3c50651U, 0xb8a5c3efU, + 0xd8eeb6d2U, 0xe523be77U, 0xc2154529U, 0x2f69efdfU, + 0xafe67afbU, 0xf470c4b2U, 0xf3e0eb5bU, 0xd6cc9876U, + 0x39e4460cU, 0x1fda8538U, 0x1987832fU, 0xca007367U, + 0xa99144f8U, 0x296b299eU, 0x492fc295U, 0x9266beabU, + 0xb5676e69U, 0x9bd3dddaU, 0xdf7e052fU, 0xdb25701cU, + 0x1b5e51eeU, 0xf65324e6U, 0x6afce36cU, 0x0316cc04U, + 0x8644213eU, 0xb7dc59d0U, 0x7965291fU, 0xccd6fd43U, + 0x41823979U, 0x932bcdf6U, 0xb657c34dU, 0x4edfd282U, + 0x7ae5290cU, 0x3cb9536bU, 0x851e20feU, 0x9833557eU, + 0x13ecf0b0U, 0xd3ffb372U, 0x3f85c5c1U, 0x0aef7ed2U +}; + +/* Fifth substitution box (S box) */ +INTERNAL_LINKAGE U32 S5[256] = { + 0x7ec90c04U, 0x2c6e74b9U, 0x9b0e66dfU, 0xa6337911U, + 0xb86a7fffU, 0x1dd358f5U, 0x44dd9d44U, 0x1731167fU, + 0x08fbf1faU, 0xe7f511ccU, 0xd2051b00U, 0x735aba00U, + 0x2ab722d8U, 0x386381cbU, 0xacf6243aU, 0x69befd7aU, + 0xe6a2e77fU, 0xf0c720cdU, 0xc4494816U, 0xccf5c180U, + 0x38851640U, 0x15b0a848U, 0xe68b18cbU, 0x4caadeffU, + 0x5f480a01U, 0x0412b2aaU, 0x259814fcU, 0x41d0efe2U, + 0x4e40b48dU, 0x248eb6fbU, 0x8dba1cfeU, 0x41a99b02U, + 0x1a550a04U, 0xba8f65cbU, 0x7251f4e7U, 0x95a51725U, + 0xc106ecd7U, 0x97a5980aU, 0xc539b9aaU, 0x4d79fe6aU, + 0xf2f3f763U, 0x68af8040U, 0xed0c9e56U, 0x11b4958bU, + 0xe1eb5a88U, 0x8709e6b0U, 0xd7e07156U, 0x4e29fea7U, + 0x6366e52dU, 0x02d1c000U, 0xc4ac8e05U, 0x9377f571U, + 0x0c05372aU, 0x578535f2U, 0x2261be02U, 0xd642a0c9U, + 0xdf13a280U, 0x74b55bd2U, 0x682199c0U, 0xd421e5ecU, + 0x53fb3ce8U, 0xc8adedb3U, 0x28a87fc9U, 0x3d959981U, + 0x5c1ff900U, 0xfe38d399U, 0x0c4eff0bU, 0x062407eaU, + 0xaa2f4fb1U, 0x4fb96976U, 0x90c79505U, 0xb0a8a774U, + 0xef55a1ffU, 0xe59ca2c2U, 0xa6b62d27U, 0xe66a4263U, + 0xdf65001fU, 0x0ec50966U, 0xdfdd55bcU, 0x29de0655U, + 0x911e739aU, 0x17af8975U, 0x32c7911cU, 0x89f89468U, + 0x0d01e980U, 0x524755f4U, 0x03b63cc9U, 0x0cc844b2U, + 0xbcf3f0aaU, 0x87ac36e9U, 0xe53a7426U, 0x01b3d82bU, + 0x1a9e7449U, 0x64ee2d7eU, 0xcddbb1daU, 0x01c94910U, + 0xb868bf80U, 0x0d26f3fdU, 0x9342ede7U, 0x04a5c284U, + 0x636737b6U, 0x50f5b616U, 0xf24766e3U, 0x8eca36c1U, + 0x136e05dbU, 0xfef18391U, 0xfb887a37U, 0xd6e7f7d4U, + 0xc7fb7dc9U, 0x3063fcdfU, 0xb6f589deU, 0xec2941daU, + 0x26e46695U, 0xb7566419U, 0xf654efc5U, 0xd08d58b7U, + 0x48925401U, 0xc1bacb7fU, 0xe5ff550fU, 0xb6083049U, + 0x5bb5d0e8U, 0x87d72e5aU, 0xab6a6ee1U, 0x223a66ceU, + 0xc62bf3cdU, 0x9e0885f9U, 0x68cb3e47U, 0x086c010fU, + 0xa21de820U, 0xd18b69deU, 0xf3f65777U, 0xfa02c3f6U, + 0x407edac3U, 0xcbb3d550U, 0x1793084dU, 0xb0d70ebaU, + 0x0ab378d5U, 0xd951fb0cU, 0xded7da56U, 0x4124bbe4U, + 0x94ca0b56U, 0x0f5755d1U, 0xe0e1e56eU, 0x6184b5beU, + 0x580a249fU, 0x94f74bc0U, 0xe327888eU, 0x9f7b5561U, + 0xc3dc0280U, 0x05687715U, 0x646c6bd7U, 0x44904db3U, + 0x66b4f0a3U, 0xc0f1648aU, 0x697ed5afU, 0x49e92ff6U, + 0x309e374fU, 0x2cb6356aU, 0x85808573U, 0x4991f840U, + 0x76f0ae02U, 0x083be84dU, 0x28421c9aU, 0x44489406U, + 0x736e4cb8U, 0xc1092910U, 0x8bc95fc6U, 0x7d869cf4U, + 0x134f616fU, 0x2e77118dU, 0xb31b2be1U, 0xaa90b472U, + 0x3ca5d717U, 0x7d161bbaU, 0x9cad9010U, 0xaf462ba2U, + 0x9fe459d2U, 0x45d34559U, 0xd9f2da13U, 0xdbc65487U, + 0xf3e4f94eU, 0x176d486fU, 0x097c13eaU, 0x631da5c7U, + 0x445f7382U, 0x175683f4U, 0xcdc66a97U, 0x70be0288U, + 0xb3cdcf72U, 0x6e5dd2f3U, 0x20936079U, 0x459b80a5U, + 0xbe60e2dbU, 0xa9c23101U, 0xeba5315cU, 0x224e42f2U, + 0x1c5c1572U, 0xf6721b2cU, 0x1ad2fff3U, 0x8c25404eU, + 0x324ed72fU, 0x4067b7fdU, 0x0523138eU, 0x5ca3bc78U, + 0xdc0fd66eU, 0x75922283U, 0x784d6b17U, 0x58ebb16eU, + 0x44094f85U, 0x3f481d87U, 0xfcfeae7bU, 0x77b5ff76U, + 0x8c2302bfU, 0xaaf47556U, 0x5f46b02aU, 0x2b092801U, + 0x3d38f5f7U, 0x0ca81f36U, 0x52af4a8aU, 0x66d5e7c0U, + 0xdf3b0874U, 0x95055110U, 0x1b5ad7a8U, 0xf61ed5adU, + 0x6cf6e479U, 0x20758184U, 0xd0cefa65U, 0x88f7be58U, + 0x4a046826U, 0x0ff6f8f3U, 0xa09c7f70U, 0x5346aba0U, + 0x5ce96c28U, 0xe176eda3U, 0x6bac307fU, 0x376829d2U, + 0x85360fa9U, 0x17e3fe2aU, 0x24b79767U, 0xf5a96b20U, + 0xd6cd2595U, 0x68ff1ebfU, 0x7555442cU, 0xf19f06beU, + 0xf9e0659aU, 0xeeb9491dU, 0x34010718U, 0xbb30cab8U, + 0xe822fe15U, 0x88570983U, 0x750e6249U, 0xda627e55U, + 0x5e76ffa8U, 0xb1534546U, 0x6d47de08U, 0xefe9e7d4U +}; +/* Sixth substitution box (S box) */ +INTERNAL_LINKAGE U32 S6[256] = { + 0xf6fa8f9dU, 0x2cac6ce1U, 0x4ca34867U, 0xe2337f7cU, + 0x95db08e7U, 0x016843b4U, 0xeced5cbcU, 0x325553acU, + 0xbf9f0960U, 0xdfa1e2edU, 0x83f0579dU, 0x63ed86b9U, + 0x1ab6a6b8U, 0xde5ebe39U, 0xf38ff732U, 0x8989b138U, + 0x33f14961U, 0xc01937bdU, 0xf506c6daU, 0xe4625e7eU, + 0xa308ea99U, 0x4e23e33cU, 0x79cbd7ccU, 0x48a14367U, + 0xa3149619U, 0xfec94bd5U, 0xa114174aU, 0xeaa01866U, + 0xa084db2dU, 0x09a8486fU, 0xa888614aU, 0x2900af98U, + 0x01665991U, 0xe1992863U, 0xc8f30c60U, 0x2e78ef3cU, + 0xd0d51932U, 0xcf0fec14U, 0xf7ca07d2U, 0xd0a82072U, + 0xfd41197eU, 0x9305a6b0U, 0xe86be3daU, 0x74bed3cdU, + 0x372da53cU, 0x4c7f4448U, 0xdab5d440U, 0x6dba0ec3U, + 0x083919a7U, 0x9fbaeed9U, 0x49dbcfb0U, 0x4e670c53U, + 0x5c3d9c01U, 0x64bdb941U, 0x2c0e636aU, 0xba7dd9cdU, + 0xea6f7388U, 0xe70bc762U, 0x35f29adbU, 0x5c4cdd8dU, + 0xf0d48d8cU, 0xb88153e2U, 0x08a19866U, 0x1ae2eac8U, + 0x284caf89U, 0xaa928223U, 0x9334be53U, 0x3b3a21bfU, + 0x16434be3U, 0x9aea3906U, 0xefe8c36eU, 0xf890cdd9U, + 0x80226daeU, 0xc340a4a3U, 0xdf7e9c09U, 0xa694a807U, + 0x5b7c5eccU, 0x221db3a6U, 0x9a69a02fU, 0x68818a54U, + 0xceb2296fU, 0x53c0843aU, 0xfe893655U, 0x25bfe68aU, + 0xb4628abcU, 0xcf222ebfU, 0x25ac6f48U, 0xa9a99387U, + 0x53bddb65U, 0xe76ffbe7U, 0xe967fd78U, 0x0ba93563U, + 0x8e342bc1U, 0xe8a11be9U, 0x4980740dU, 0xc8087dfcU, + 0x8de4bf99U, 0xa11101a0U, 0x7fd37975U, 0xda5a26c0U, + 0xe81f994fU, 0x9528cd89U, 0xfd339fedU, 0xb87834bfU, + 0x5f04456dU, 0x22258698U, 0xc9c4c83bU, 0x2dc156beU, + 0x4f628daaU, 0x57f55ec5U, 0xe2220abeU, 0xd2916ebfU, + 0x4ec75b95U, 0x24f2c3c0U, 0x42d15d99U, 0xcd0d7fa0U, + 0x7b6e27ffU, 0xa8dc8af0U, 0x7345c106U, 0xf41e232fU, + 0x35162386U, 0xe6ea8926U, 0x3333b094U, 0x157ec6f2U, + 0x372b74afU, 0x692573e4U, 0xe9a9d848U, 0xf3160289U, + 0x3a62ef1dU, 0xa787e238U, 0xf3a5f676U, 0x74364853U, + 0x20951063U, 0x4576698dU, 0xb6fad407U, 0x592af950U, + 0x36f73523U, 0x4cfb6e87U, 0x7da4cec0U, 0x6c152daaU, + 0xcb0396a8U, 0xc50dfe5dU, 0xfcd707abU, 0x0921c42fU, + 0x89dff0bbU, 0x5fe2be78U, 0x448f4f33U, 0x754613c9U, + 0x2b05d08dU, 0x48b9d585U, 0xdc049441U, 0xc8098f9bU, + 0x7dede786U, 0xc39a3373U, 0x42410005U, 0x6a091751U, + 0x0ef3c8a6U, 0x890072d6U, 0x28207682U, 0xa9a9f7beU, + 0xbf32679dU, 0xd45b5b75U, 0xb353fd00U, 0xcbb0e358U, + 0x830f220aU, 0x1f8fb214U, 0xd372cf08U, 0xcc3c4a13U, + 0x8cf63166U, 0x061c87beU, 0x88c98f88U, 0x6062e397U, + 0x47cf8e7aU, 0xb6c85283U, 0x3cc2acfbU, 0x3fc06976U, + 0x4e8f0252U, 0x64d8314dU, 0xda3870e3U, 0x1e665459U, + 0xc10908f0U, 0x513021a5U, 0x6c5b68b7U, 0x822f8aa0U, + 0x3007cd3eU, 0x74719eefU, 0xdc872681U, 0x073340d4U, + 0x7e432fd9U, 0x0c5ec241U, 0x8809286cU, 0xf592d891U, + 0x08a930f6U, 0x957ef305U, 0xb7fbffbdU, 0xc266e96fU, + 0x6fe4ac98U, 0xb173ecc0U, 0xbc60b42aU, 0x953498daU, + 0xfba1ae12U, 0x2d4bd736U, 0x0f25faabU, 0xa4f3fcebU, + 0xe2969123U, 0x257f0c3dU, 0x9348af49U, 0x361400bcU, + 0xe8816f4aU, 0x3814f200U, 0xa3f94043U, 0x9c7a54c2U, + 0xbc704f57U, 0xda41e7f9U, 0xc25ad33aU, 0x54f4a084U, + 0xb17f5505U, 0x59357cbeU, 0xedbd15c8U, 0x7f97c5abU, + 0xba5ac7b5U, 0xb6f6deafU, 0x3a479c3aU, 0x5302da25U, + 0x653d7e6aU, 0x54268d49U, 0x51a477eaU, 0x5017d55bU, + 0xd7d25d88U, 0x44136c76U, 0x0404a8c8U, 0xb8e5a121U, + 0xb81a928aU, 0x60ed5869U, 0x97c55b96U, 0xeaec991bU, + 0x29935913U, 0x01fdb7f1U, 0x088e8dfaU, 0x9ab6f6f5U, + 0x3b4cbf9fU, 0x4a5de3abU, 0xe6051d35U, 0xa0e1d855U, + 0xd36b4cf1U, 0xf544edebU, 0xb0e93524U, 0xbebb8fbdU, + 0xa2d762cfU, 0x49c92f54U, 0x38b5f331U, 0x7128a454U, + 0x48392905U, 0xa65b1db8U, 0x851c97bdU, 0xd675cf2fU +}; + +/* Seventh substitution box (S box) */ +INTERNAL_LINKAGE U32 S7[256] = { + 0x85e04019U, 0x332bf567U, 0x662dbfffU, 0xcfc65693U, + 0x2a8d7f6fU, 0xab9bc912U, 0xde6008a1U, 0x2028da1fU, + 0x0227bce7U, 0x4d642916U, 0x18fac300U, 0x50f18b82U, + 0x2cb2cb11U, 0xb232e75cU, 0x4b3695f2U, 0xb28707deU, + 0xa05fbcf6U, 0xcd4181e9U, 0xe150210cU, 0xe24ef1bdU, + 0xb168c381U, 0xfde4e789U, 0x5c79b0d8U, 0x1e8bfd43U, + 0x4d495001U, 0x38be4341U, 0x913cee1dU, 0x92a79c3fU, + 0x089766beU, 0xbaeeadf4U, 0x1286becfU, 0xb6eacb19U, + 0x2660c200U, 0x7565bde4U, 0x64241f7aU, 0x8248dca9U, + 0xc3b3ad66U, 0x28136086U, 0x0bd8dfa8U, 0x356d1cf2U, + 0x107789beU, 0xb3b2e9ceU, 0x0502aa8fU, 0x0bc0351eU, + 0x166bf52aU, 0xeb12ff82U, 0xe3486911U, 0xd34d7516U, + 0x4e7b3affU, 0x5f43671bU, 0x9cf6e037U, 0x4981ac83U, + 0x334266ceU, 0x8c9341b7U, 0xd0d854c0U, 0xcb3a6c88U, + 0x47bc2829U, 0x4725ba37U, 0xa66ad22bU, 0x7ad61f1eU, + 0x0c5cbafaU, 0x4437f107U, 0xb6e79962U, 0x42d2d816U, + 0x0a961288U, 0xe1a5c06eU, 0x13749e67U, 0x72fc081aU, + 0xb1d139f7U, 0xf9583745U, 0xcf19df58U, 0xbec3f756U, + 0xc06eba30U, 0x07211b24U, 0x45c28829U, 0xc95e317fU, + 0xbc8ec511U, 0x38bc46e9U, 0xc6e6fa14U, 0xbae8584aU, + 0xad4ebc46U, 0x468f508bU, 0x7829435fU, 0xf124183bU, + 0x821dba9fU, 0xaff60ff4U, 0xea2c4e6dU, 0x16e39264U, + 0x92544a8bU, 0x009b4fc3U, 0xaba68cedU, 0x9ac96f78U, + 0x06a5b79aU, 0xb2856e6eU, 0x1aec3ca9U, 0xbe838688U, + 0x0e0804e9U, 0x55f1be56U, 0xe7e5363bU, 0xb3a1f25dU, + 0xf7debb85U, 0x61fe033cU, 0x16746233U, 0x3c034c28U, + 0xda6d0c74U, 0x79aac56cU, 0x3ce4e1adU, 0x51f0c802U, + 0x98f8f35aU, 0x1626a49fU, 0xeed82b29U, 0x1d382fe3U, + 0x0c4fb99aU, 0xbb325778U, 0x3ec6d97bU, 0x6e77a6a9U, + 0xcb658b5cU, 0xd45230c7U, 0x2bd1408bU, 0x60c03eb7U, + 0xb9068d78U, 0xa33754f4U, 0xf430c87dU, 0xc8a71302U, + 0xb96d8c32U, 0xebd4e7beU, 0xbe8b9d2dU, 0x7979fb06U, + 0xe7225308U, 0x8b75cf77U, 0x11ef8da4U, 0xe083c858U, + 0x8d6b786fU, 0x5a6317a6U, 0xfa5cf7a0U, 0x5dda0033U, + 0xf28ebfb0U, 0xf5b9c310U, 0xa0eac280U, 0x08b9767aU, + 0xa3d9d2b0U, 0x79d34217U, 0x021a718dU, 0x9ac6336aU, + 0x2711fd60U, 0x438050e3U, 0x069908a8U, 0x3d7fedc4U, + 0x826d2befU, 0x4eeb8476U, 0x488dcf25U, 0x36c9d566U, + 0x28e74e41U, 0xc2610acaU, 0x3d49a9cfU, 0xbae3b9dfU, + 0xb65f8de6U, 0x92aeaf64U, 0x3ac7d5e6U, 0x9ea80509U, + 0xf22b017dU, 0xa4173f70U, 0xdd1e16c3U, 0x15e0d7f9U, + 0x50b1b887U, 0x2b9f4fd5U, 0x625aba82U, 0x6a017962U, + 0x2ec01b9cU, 0x15488aa9U, 0xd716e740U, 0x40055a2cU, + 0x93d29a22U, 0xe32dbf9aU, 0x058745b9U, 0x3453dc1eU, + 0xd699296eU, 0x496cff6fU, 0x1c9f4986U, 0xdfe2ed07U, + 0xb87242d1U, 0x19de7eaeU, 0x053e561aU, 0x15ad6f8cU, + 0x66626c1cU, 0x7154c24cU, 0xea082b2aU, 0x93eb2939U, + 0x17dcb0f0U, 0x58d4f2aeU, 0x9ea294fbU, 0x52cf564cU, + 0x9883fe66U, 0x2ec40581U, 0x763953c3U, 0x01d6692eU, + 0xd3a0c108U, 0xa1e7160eU, 0xe4f2dfa6U, 0x693ed285U, + 0x74904698U, 0x4c2b0eddU, 0x4f757656U, 0x5d393378U, + 0xa132234fU, 0x3d321c5dU, 0xc3f5e194U, 0x4b269301U, + 0xc79f022fU, 0x3c997e7eU, 0x5e4f9504U, 0x3ffafbbdU, + 0x76f7ad0eU, 0x296693f4U, 0x3d1fce6fU, 0xc61e45beU, + 0xd3b5ab34U, 0xf72bf9b7U, 0x1b0434c0U, 0x4e72b567U, + 0x5592a33dU, 0xb5229301U, 0xcfd2a87fU, 0x60aeb767U, + 0x1814386bU, 0x30bcc33dU, 0x38a0c07dU, 0xfd1606f2U, + 0xc363519bU, 0x589dd390U, 0x5479f8e6U, 0x1cb8d647U, + 0x97fd61a9U, 0xea7759f4U, 0x2d57539dU, 0x569a58cfU, + 0xe84e63adU, 0x462e1b78U, 0x6580f87eU, 0xf3817914U, + 0x91da55f4U, 0x40a230f3U, 0xd1988f35U, 0xb6e318d2U, + 0x3ffa50bcU, 0x3d40f021U, 0xc3c0bdaeU, 0x4958c24cU, + 0x518f36b2U, 0x84b1d370U, 0x0fedce83U, 0x878ddadaU, + 0xf2a279c7U, 0x94e01be8U, 0x90716f4bU, 0x954b8aa3U +}; + +/* Eighth substitution box (S box) */ +INTERNAL_LINKAGE U32 S8[256] = { + 0xe216300dU, 0xbbddfffcU, 0xa7ebdabdU, 0x35648095U, + 0x7789f8b7U, 0xe6c1121bU, 0x0e241600U, 0x052ce8b5U, + 0x11a9cfb0U, 0xe5952f11U, 0xece7990aU, 0x9386d174U, + 0x2a42931cU, 0x76e38111U, 0xb12def3aU, 0x37ddddfcU, + 0xde9adeb1U, 0x0a0cc32cU, 0xbe197029U, 0x84a00940U, + 0xbb243a0fU, 0xb4d137cfU, 0xb44e79f0U, 0x049eedfdU, + 0x0b15a15dU, 0x480d3168U, 0x8bbbde5aU, 0x669ded42U, + 0xc7ece831U, 0x3f8f95e7U, 0x72df191bU, 0x7580330dU, + 0x94074251U, 0x5c7dcdfaU, 0xabbe6d63U, 0xaa402164U, + 0xb301d40aU, 0x02e7d1caU, 0x53571daeU, 0x7a3182a2U, + 0x12a8ddecU, 0xfdaa335dU, 0x176f43e8U, 0x71fb46d4U, + 0x38129022U, 0xce949ad4U, 0xb84769adU, 0x965bd862U, + 0x82f3d055U, 0x66fb9767U, 0x15b80b4eU, 0x1d5b47a0U, + 0x4cfde06fU, 0xc28ec4b8U, 0x57e8726eU, 0x647a78fcU, + 0x99865d44U, 0x608bd593U, 0x6c200e03U, 0x39dc5ff6U, + 0x5d0b00a3U, 0xae63aff2U, 0x7e8bd632U, 0x70108c0cU, + 0xbbd35049U, 0x2998df04U, 0x980cf42aU, 0x9b6df491U, + 0x9e7edd53U, 0x06918548U, 0x58cb7e07U, 0x3b74ef2eU, + 0x522fffb1U, 0xd24708ccU, 0x1c7e27cdU, 0xa4eb215bU, + 0x3cf1d2e2U, 0x19b47a38U, 0x424f7618U, 0x35856039U, + 0x9d17dee7U, 0x27eb35e6U, 0xc9aff67bU, 0x36baf5b8U, + 0x09c467cdU, 0xc18910b1U, 0xe11dbf7bU, 0x06cd1af8U, + 0x7170c608U, 0x2d5e3354U, 0xd4de495aU, 0x64c6d006U, + 0xbcc0c62cU, 0x3dd00db3U, 0x708f8f34U, 0x77d51b42U, + 0x264f620fU, 0x24b8d2bfU, 0x15c1b79eU, 0x46a52564U, + 0xf8d7e54eU, 0x3e378160U, 0x7895cda5U, 0x859c15a5U, + 0xe6459788U, 0xc37bc75fU, 0xdb07ba0cU, 0x0676a3abU, + 0x7f229b1eU, 0x31842e7bU, 0x24259fd7U, 0xf8bef472U, + 0x835ffcb8U, 0x6df4c1f2U, 0x96f5b195U, 0xfd0af0fcU, + 0xb0fe134cU, 0xe2506d3dU, 0x4f9b12eaU, 0xf215f225U, + 0xa223736fU, 0x9fb4c428U, 0x25d04979U, 0x34c713f8U, + 0xc4618187U, 0xea7a6e98U, 0x7cd16efcU, 0x1436876cU, + 0xf1544107U, 0xbedeee14U, 0x56e9af27U, 0xa04aa441U, + 0x3cf7c899U, 0x92ecbae6U, 0xdd67016dU, 0x151682ebU, + 0xa842eedfU, 0xfdba60b4U, 0xf1907b75U, 0x20e3030fU, + 0x24d8c29eU, 0xe139673bU, 0xefa63fb8U, 0x71873054U, + 0xb6f2cf3bU, 0x9f326442U, 0xcb15a4ccU, 0xb01a4504U, + 0xf1e47d8dU, 0x844a1be5U, 0xbae7dfdcU, 0x42cbda70U, + 0xcd7dae0aU, 0x57e85b7aU, 0xd53f5af6U, 0x20cf4d8cU, + 0xcea4d428U, 0x79d130a4U, 0x3486ebfbU, 0x33d3cddcU, + 0x77853b53U, 0x37effcb5U, 0xc5068778U, 0xe580b3e6U, + 0x4e68b8f4U, 0xc5c8b37eU, 0x0d809ea2U, 0x398feb7cU, + 0x132a4f94U, 0x43b7950eU, 0x2fee7d1cU, 0x223613bdU, + 0xdd06caa2U, 0x37df932bU, 0xc4248289U, 0xacf3ebc3U, + 0x5715f6b7U, 0xef3478ddU, 0xf267616fU, 0xc148cbe4U, + 0x9052815eU, 0x5e410fabU, 0xb48a2465U, 0x2eda7fa4U, + 0xe87b40e4U, 0xe98ea084U, 0x5889e9e1U, 0xefd390fcU, + 0xdd07d35bU, 0xdb485694U, 0x38d7e5b2U, 0x57720101U, + 0x730edebcU, 0x5b643113U, 0x94917e4fU, 0x503c2fbaU, + 0x646f1282U, 0x7523d24aU, 0xe0779695U, 0xf9c17a8fU, + 0x7a5b2121U, 0xd187b896U, 0x29263a4dU, 0xba510cdfU, + 0x81f47c9fU, 0xad1163edU, 0xea7b5965U, 0x1a00726eU, + 0x11403092U, 0x00da6d77U, 0x4a0cdd61U, 0xad1f4603U, + 0x605bdfb0U, 0x9eedc364U, 0x22ebe6a8U, 0xcee7d28aU, + 0xa0e736a0U, 0x5564a6b9U, 0x10853209U, 0xc7eb8f37U, + 0x2de705caU, 0x8951570fU, 0xdf09822bU, 0xbd691a6cU, + 0xaa12e4f2U, 0x87451c0fU, 0xe0f6a27aU, 0x3ada4819U, + 0x4cf1764fU, 0x0d771c2bU, 0x67cdb156U, 0x350d8384U, + 0x5938fa0fU, 0x42399ef3U, 0x36997b07U, 0x0e84093dU, + 0x4aa93e61U, 0x8360d87bU, 0x1fa98b0cU, 0x1149382cU, + 0xe97625a5U, 0x0614d1b7U, 0x0e25244bU, 0x0c768347U, + 0x589e8d82U, 0x0d2059d1U, 0xa466bb1eU, 0xf8da0a82U, + 0x04f19130U, 0xba6e4ec0U, 0x99265164U, 0x1ee7230dU, + 0x50b2ad80U, 0xeaee6801U, 0x8db2a283U, 0xea8bf59eU +}; + +#if defined(BIG_ENDIAN) +#define cast_htonl(H) (H) +#define cast_ntohl(N) (N) +#else /* !defined(BIG_ENDIAN) */ + +/* + * htonl + * + * PURPOSE + * Convert from the host machine byte order to the byte order used + * by by the CAST algorithm (big-endian = network order = 1234). + * + * HISTORY + * May 23, 1997 - Andrew E. Mileski + * Written, tested, and released. + */ +INTERNAL_LINKAGE __inline__ +U32 cast_htonl(U32 data) +{ +#if defined(__GNUC__) && defined(i486) + __asm__ ( + "bswapl %0" + : "=r" (data) + : "0" (data) + ); + return data; +#else /* !(defined(__GNUC__) && defined(i486)) */ + union { U8 b[4]; U32 l; } u; + u.b[3] = (U8) data; + u.b[2] = (U8)(data >> 8); + u.b[1] = (U8)(data >> 16); + u.b[0] = (U8)(data >> 24); + return u.l; +#endif /* !(defined(__GNUC__) && defined(i486)) */ +} + +/* + * ntohl + * + * PURPOSE + * Convert to the host machine byte order from the byte order used + * by by the CAST algorithm (big-endian = network order = 1234). + * + * HISTORY + * May 23, 1997 - Andrew E. Mileski + * Written, tested, and released. + */ +INTERNAL_LINKAGE __inline__ +U32 cast_ntohl(U32 data) +{ +#if defined(__GNUC__) && defined(i486) + __asm__ ( + "bswapl %0" + : "=r" (data) + : "0" (data) + ); + return data; +#else /* !(defined(__GNUC__) && defined(i486)) */ + union { U8 b[4]; U32 l; } u; + u.l = data; + return (u.b[0] << 24) | (u.b[1] << 16) | (u.b[2] << 8) | u.b[3]; +#endif /* !(defined(__GNUC__) && defined(i486)) */ +} +#endif /* !defined(BIG_ENDIAN) */ + +/* + * cast_rol + * + * PURPOSE + * Perform a left rotation. + * + * DESCRIPTION + * The portable code is SLOW. The ix86 code is a single instruction! + * + * Note: This is a macro. + * + * HISTORY + * May 21, 1997 - Andrew E. Mileski + * Written, tested, and released. + */ +INTERNAL_LINKAGE __inline__ +U32 cast_rol(U32 data, U32 count) +{ +#if defined(__GNUC__) && (defined(i386) || defined(i486)) + __asm__ ( + "roll %%cl,%0" + : "=r" (data) + : "0" (data), "c" (count) + : "cx" + ); + return data; +#else /* !(defined(__GNUC__) && defined(i386)) */ + return (count &= 31) ? (data << count) | ((data >> (32 - count)) + & (0xffffffff >> (32 - count))): data; +#endif /* !(defined(__GNUC__) && defined(i386)) */ +} + +/* + * cast_encrypt + * + * PURPOSE + * Apply the CAST-128 algorithm to encrypt the specified plaintext. + * + * DESCRIPTION + * Refer to RFC 2144 for complete details on CAST. + * + * Note that CAST is a block cipher of size 64 bits (8 bytes). + * + * PRE-CONDITIONS + * K Pointer to subkeys - see cast_keySchedule(). + * M Pointer to plaintext. + * size Bytes in the plaintext. + * + * POST-CONDITIONS + * C Pointer to ciphertext. + * <return> Number of bytes plaintext not processed. + * + * HISTORY + * May 23, 1997 - Andrew E. Mileski + * Implemented RFC 2144 in C, tested, and released. + */ +#define Ia ((U8)(I >> 24)) +#define Ib ((U8)(I >> 16)) +#define Ic ((U8)(I >> 8)) +#define Id ((U8) I) + +#define ROUND1(X) \ + T = L; \ + L = R; \ + I = cast_rol(K[X] + R, K[(X) + 16]); \ + R = T ^ (((S1[Ia] ^ S2[Ib]) - S3[Ic]) + S4[Id]); + +#define ROUND2(X) \ + T = L; \ + L = R; \ + I = cast_rol(K[X] ^ R, K[(X) + 16]); \ + R = T ^ (((S1[Ia] - S2[Ib]) + S3[Ic]) ^ S4[Id]); + +#define ROUND3(X) \ + T = L; \ + L = R; \ + I = cast_rol(K[X] - R, K[(X) + 16]); \ + R = T ^ (((S1[Ia] + S2[Ib]) ^ S3[Ic]) - S4[Id]); + +EXTERNAL_LINKAGE +U32 cast_encrypt(U32 * K, U32 * M, U32 * C, U32 size) +{ + register U32 I, L, R, T; + + for (; size >= 8; size -= 8) { + + /* Split the plain-text */ + L = cast_htonl(*(M++)); + R = cast_htonl(*(M++)); + + /* Do rounds */ + ROUND1(0); + ROUND2(1); + ROUND3(2); + ROUND1(3); + ROUND2(4); + ROUND3(5); + ROUND1(6); + ROUND2(7); + ROUND3(8); + ROUND1(9); + ROUND2(10); + ROUND3(11); + ROUND1(12); + ROUND2(13); + ROUND3(14); + ROUND1(15); + + /* Swap halves */ + *(C++) = cast_ntohl(R); + *(C++) = cast_ntohl(L); + } + return size; +} + +/* + * cast_decrypt + * + * PURPOSE + * Apply the CAST-128 algorithm to decrypt the specified ciphertext. + * + * DESCRIPTION + * Refer to RFC 2144 for complete details on CAST. + * + * Note that CAST is a block cipher of size 64 bits (8 bytes). + * + * PRE-CONDITIONS + * K Pointer to subkeys - see cast_keySchedule(). + * C Pointer to ciphertext. + * size Bytes in the ciphertext. + * + * POST-CONDITIONS + * M Pointer to plaintext. + * <return> Number of bytes ciphertext not processed. + * + * HISTORY + * May 23, 1997 - Andrew E. Mileski + * Implemented RFC 2144 in C, tested, and released. + */ +EXTERNAL_LINKAGE +U32 cast_decrypt(U32 * K, U32 * M, U32 * C, U32 size) +{ + register U32 I, L, R, T; + + for (; size >= 8; size -= 8) { + + /* Split the ciphertext */ + L = cast_htonl(*(C++)); + R = cast_htonl(*(C++)); + + /* Do rounds */ + ROUND1(15); + ROUND3(14); + ROUND2(13); + ROUND1(12); + ROUND3(11); + ROUND2(10); + ROUND1(9); + ROUND3(8); + ROUND2(7); + ROUND1(6); + ROUND3(5); + ROUND2(4); + ROUND1(3); + ROUND3(2); + ROUND2(1); + ROUND1(0); + + /* Swap halves */ + *(M++) = cast_ntohl(R); + *(M++) = cast_ntohl(L); + } + return size; +} + +/* Cleanup the defines */ +#undef Ia +#undef Ib +#undef Ic +#undef Id +#undef ROUND1 +#undef ROUND2 +#undef ROUND3 + +/* + * cast_keySchedule + * + * PURPOSE + * Create the subkeys which are used in each round. + * + * DESCRIPTION + * Refer to RFC 2144, section 2.4. + * + * IMPORTANT - the macros are required for portability to machines + * with different byte ordering (endian-ness), but they badly pollute + * the namespace. + * + * PRE-CONDITIONS + * X Pointer to a key. + * + * POST-CONDITIONS + * K Pointer to sub-keys. + * + * HISTORY + * May 23, 1997 - Andrew E. Mileski + * Implemented RFC 2144 in C, tested, and released. + */ +#define x0 ((U8)(X0 >> 24)) +#define x1 ((U8)(X0 >> 16)) +#define x2 ((U8)(X0 >> 8)) +#define x3 ((U8) X0) +#define x4 ((U8)(X1 >> 24)) +#define x5 ((U8)(X1 >> 16)) +#define x6 ((U8)(X1 >> 8)) +#define x7 ((U8) X1) +#define x8 ((U8)(X2 >> 24)) +#define x9 ((U8)(X2 >> 16)) +#define xa ((U8)(X2 >> 8)) +#define xb ((U8) X2) +#define xc ((U8)(X3 >> 24)) +#define xd ((U8)(X3 >> 16)) +#define xe ((U8)(X3 >> 8)) +#define xf ((U8) X3) +#define z0 ((U8)(Z0 >> 24)) +#define z1 ((U8)(Z0 >> 16)) +#define z2 ((U8)(Z0 >> 8)) +#define z3 ((U8) Z0) +#define z4 ((U8)(Z1 >> 24)) +#define z5 ((U8)(Z1 >> 16)) +#define z6 ((U8)(Z1 >> 8)) +#define z7 ((U8) Z1) +#define z8 ((U8)(Z2 >> 24)) +#define z9 ((U8)(Z2 >> 16)) +#define za ((U8)(Z2 >> 8)) +#define zb ((U8) Z2) +#define zc ((U8)(Z3 >> 24)) +#define zd ((U8)(Z3 >> 16)) +#define ze ((U8)(Z3 >> 8)) +#define zf ((U8) Z3) + +EXTERNAL_LINKAGE +void cast_keySchedule(U32 * x, U32 * K) +{ + U32 X0, X1, X2, X3; + U32 Z0, Z1, Z2, Z3; + + /* Preserve the passed key */ + X0 = cast_htonl(*(x++)); + X1 = cast_htonl(*(x++)); + X2 = cast_htonl(*(x++)); + X3 = cast_htonl(*(x++)); + + Z0 = X0 ^ S5[xd] ^ S6[xf] ^ S7[xc] ^ S8[xe] ^ S7[x8]; + Z1 = X2 ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xa]; + Z2 = X3 ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]; + Z3 = X1 ^ S5[za] ^ S6[z9] ^ S7[zb] ^ S8[z8] ^ S6[xb]; + + K[0] = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2]; + K[1] = S5[za] ^ S6[zb] ^ S7[z5] ^ S8[z4] ^ S6[z6]; + K[2] = S5[zc] ^ S6[zd] ^ S7[z3] ^ S8[z2] ^ S7[z9]; + K[3] = S5[ze] ^ S6[zf] ^ S7[z1] ^ S8[z0] ^ S8[zc]; + + X0 = Z2 ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]; + X1 = Z0 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]; + X2 = Z1 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]; + X3 = Z3 ^ S5[xa] ^ S6[x9] ^ S7[xb] ^ S8[x8] ^ S6[z3]; + + K[4] = S5[x3] ^ S6[x2] ^ S7[xc] ^ S8[xd] ^ S5[x8]; + K[5] = S5[x1] ^ S6[x0] ^ S7[xe] ^ S8[xf] ^ S6[xd]; + K[6] = S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3]; + K[7] = S5[x5] ^ S6[x4] ^ S7[xa] ^ S8[xb] ^ S8[x7]; + + Z0 = X0 ^ S5[xd] ^ S6[xf] ^ S7[xc] ^ S8[xe] ^ S7[x8]; + Z1 = X2 ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xa]; + Z2 = X3 ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]; + Z3 = X1 ^ S5[za] ^ S6[z9] ^ S7[zb] ^ S8[z8] ^ S6[xb]; + + K[ 8] = S5[z3] ^ S6[z2] ^ S7[zc] ^ S8[zd] ^ S5[z9]; + K[ 9] = S5[z1] ^ S6[z0] ^ S7[ze] ^ S8[zf] ^ S6[zc]; + K[10] = S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2]; + K[11] = S5[z5] ^ S6[z4] ^ S7[za] ^ S8[zb] ^ S8[z6]; + + X0 = Z2 ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]; + X1 = Z0 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]; + X2 = Z1 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]; + X3 = Z3 ^ S5[xa] ^ S6[x9] ^ S7[xb] ^ S8[x8] ^ S6[z3]; + + K[12] = S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3]; + K[13] = S5[xa] ^ S6[xb] ^ S7[x5] ^ S8[x4] ^ S6[x7]; + K[14] = S5[xc] ^ S6[xd] ^ S7[x3] ^ S8[x2] ^ S7[x8]; + K[15] = S5[xe] ^ S6[xf] ^ S7[x1] ^ S8[x0] ^ S8[xd]; + + Z0 = X0 ^ S5[xd] ^ S6[xf] ^ S7[xc] ^ S8[xe] ^ S7[x8]; + Z1 = X2 ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xa]; + Z2 = X3 ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]; + Z3 = X1 ^ S5[za] ^ S6[z9] ^ S7[zb] ^ S8[z8] ^ S6[xb]; + + K[16] = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2]; + K[17] = S5[za] ^ S6[zb] ^ S7[z5] ^ S8[z4] ^ S6[z6]; + K[18] = S5[zc] ^ S6[zd] ^ S7[z3] ^ S8[z2] ^ S7[z9]; + K[19] = S5[ze] ^ S6[zf] ^ S7[z1] ^ S8[z0] ^ S8[zc]; + + X0 = Z2 ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]; + X1 = Z0 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]; + X2 = Z1 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]; + X3 = Z3 ^ S5[xa] ^ S6[x9] ^ S7[xb] ^ S8[x8] ^ S6[z3]; + + K[20] = S5[x3] ^ S6[x2] ^ S7[xc] ^ S8[xd] ^ S5[x8]; + K[21] = S5[x1] ^ S6[x0] ^ S7[xe] ^ S8[xf] ^ S6[xd]; + K[22] = S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3]; + K[23] = S5[x5] ^ S6[x4] ^ S7[xa] ^ S8[xb] ^ S8[x7]; + + Z0 = X0 ^ S5[xd] ^ S6[xf] ^ S7[xc] ^ S8[xe] ^ S7[x8]; + Z1 = X2 ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xa]; + Z2 = X3 ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]; + Z3 = X1 ^ S5[za] ^ S6[z9] ^ S7[zb] ^ S8[z8] ^ S6[xb]; + + K[24] = S5[z3] ^ S6[z2] ^ S7[zc] ^ S8[zd] ^ S5[z9]; + K[25] = S5[z1] ^ S6[z0] ^ S7[ze] ^ S8[zf] ^ S6[zc]; + K[26] = S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2]; + K[27] = S5[z5] ^ S6[z4] ^ S7[za] ^ S8[zb] ^ S8[z6]; + + X0 = Z2 ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]; + X1 = Z0 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]; + X2 = Z1 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]; + X3 = Z3 ^ S5[xa] ^ S6[x9] ^ S7[xb] ^ S8[x8] ^ S6[z3]; + + K[28] = S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3]; + K[29] = S5[xa] ^ S6[xb] ^ S7[x5] ^ S8[x4] ^ S6[x7]; + K[30] = S5[xc] ^ S6[xd] ^ S7[x3] ^ S8[x2] ^ S7[x8]; + K[31] = S5[xe] ^ S6[xf] ^ S7[x1] ^ S8[x0] ^ S8[xd]; +} + +/* Cleanup the defines */ +#undef x0 +#undef x1 +#undef x2 +#undef x3 +#undef x4 +#undef x5 +#undef x6 +#undef x7 +#undef x8 +#undef x9 +#undef xa +#undef xb +#undef xc +#undef xd +#undef xe +#undef xf +#undef z0 +#undef z1 +#undef z2 +#undef z3 +#undef z4 +#undef z5 +#undef z6 +#undef z7 +#undef z8 +#undef z9 +#undef za +#undef zb +#undef zc +#undef zd +#undef ze +#undef zf + +/*****************************************************************************/ + +#if defined(DO_TESTS) + +#include <stdio.h> +#include <time.h> + +void speed_test(void) +{ + U8 a[] = { + 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9a + }; + time_t start; + double elapsed; + U32 K[32]; + register int i; + + cast_keySchedule((U32 * ) a, K); + + printf("Performing Processing speed test..."); + fflush(stdout); + start = clock(); + for (i = 1; i <= 1000000; i++) + cast_encrypt(K, (U32 * ) a, (U32 * ) a, 16); + elapsed = clock() - start; + printf("Done.\nProcessed 16,000,000 bytes.\n"); + + printf("Elapsed time = %f\n", elapsed / CLOCKS_PER_SEC); + printf("Processing speed (million bytes/sec) = %.6f\n", + (CLOCKS_PER_SEC * 16) / elapsed); +} + +INTERNAL_LINKAGE __inline__ +int cmp(U8 *a, U8 *b) +{ + register int i; + + for (i = 0; i < 16 && *(a++) == *(b++); i++) { + ; + } + + return (i == 16); +} + +INTERNAL_LINKAGE __inline__ +void maintenance_test(void) +{ + U8 a[] = { + 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9a + }; + U8 b[] = { + 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9a + }; + U8 r1_a[] = { + 0xee, 0xa9, 0xd0, 0xa2, 0x49, 0xfd, 0x3b, 0xa6, + 0xb3, 0x43, 0x6f, 0xb8, 0x9d, 0x6d, 0xca, 0x92 + }; + U8 r1_b[] = { + 0xb2, 0xc9, 0x5e, 0xb0, 0x0c, 0x31, 0xad, 0x71, + 0x80, 0xac, 0x05, 0xb8, 0xe8, 0x3d, 0x69, 0x6e + }; + U8 r2_ab[] = { + 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9a + }; + U32 K[32]; + register int i; + + printf("Testing encryption..."); + fflush(stdout); + for (i = 1; i <= 1000000; i++) { + cast_keySchedule((U32 *) b, K); + cast_encrypt(K, (U32 *) a, (U32 *) a, 16); + + cast_keySchedule((U32 *) a, K); + cast_encrypt(K, (U32 *) b, (U32 *) b, 16); + } + if (cmp(a, r1_a) && cmp(b, r1_b)) + printf("Passed!\n"); + else + printf("Failed!\n"); + + printf("Testing decryption..."); + fflush(stdout); + for (i = 1; i <= 1000000; i++) { + cast_keySchedule((U32 *) a, K); + cast_decrypt(K, (U32 *) b, (U32 *) b, 16); + + cast_keySchedule((U32 *) b, K); + cast_decrypt(K, (U32 *) a, (U32 *) a, 16); + } + if (cmp(a, r2_ab) && cmp(b, r2_ab)) + printf("Passed!\n"); + else + printf("Failed!\n"); +} + +int main(void) +{ + maintenance_test(); + speed_test(); + return 0; +} +#endif /* defined(DO_TESTS) */ diff -ruN linux-2.2.5,pristine/drivers/block/loop_fish2.c linux-2.2.5/drivers/block/loop_fish2.c --- linux-2.2.5,pristine/drivers/block/loop_fish2.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/drivers/block/loop_fish2.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,629 @@ +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <asm/byteorder.h> +#include <linux/loop.h> + +#define ROL(x,c) (((x) << (c)) | ((x) >> (32-(c)))) +#define ROR(x,c) (((x) >> (c)) | ((x) << (32-(c)))) +#define Bswap(x) __le32_to_cpu(x) + +#define DWORD unsigned long +#define BYTE unsigned char + +typedef struct fish2_key +{ int keyLen; /* Key Length in Bit */ + DWORD sboxKeys[4]; + DWORD subKeys[40]; + BYTE key[32]; + DWORD sbox_full[1024]; /* This have to be 1024 DWORDs */ +} fish2_key; + + +/* Mul_5B[i] is 0x5B * i in GF(256), whatever that means... */ + +static unsigned char Mul_5B[256] = { + 0x00,0x5B,0xB6,0xED,0x05,0x5E,0xB3,0xE8, + 0x0A,0x51,0xBC,0xE7,0x0F,0x54,0xB9,0xE2, + 0x14,0x4F,0xA2,0xF9,0x11,0x4A,0xA7,0xFC, + 0x1E,0x45,0xA8,0xF3,0x1B,0x40,0xAD,0xF6, + 0x28,0x73,0x9E,0xC5,0x2D,0x76,0x9B,0xC0, + 0x22,0x79,0x94,0xCF,0x27,0x7C,0x91,0xCA, + 0x3C,0x67,0x8A,0xD1,0x39,0x62,0x8F,0xD4, + 0x36,0x6D,0x80,0xDB,0x33,0x68,0x85,0xDE, + 0x50,0x0B,0xE6,0xBD,0x55,0x0E,0xE3,0xB8, + 0x5A,0x01,0xEC,0xB7,0x5F,0x04,0xE9,0xB2, + 0x44,0x1F,0xF2,0xA9,0x41,0x1A,0xF7,0xAC, + 0x4E,0x15,0xF8,0xA3,0x4B,0x10,0xFD,0xA6, + 0x78,0x23,0xCE,0x95,0x7D,0x26,0xCB,0x90, + 0x72,0x29,0xC4,0x9F,0x77,0x2C,0xC1,0x9A, + 0x6C,0x37,0xDA,0x81,0x69,0x32,0xDF,0x84, + 0x66,0x3D,0xD0,0x8B,0x63,0x38,0xD5,0x8E, + 0xA0,0xFB,0x16,0x4D,0xA5,0xFE,0x13,0x48, + 0xAA,0xF1,0x1C,0x47,0xAF,0xF4,0x19,0x42, + 0xB4,0xEF,0x02,0x59,0xB1,0xEA,0x07,0x5C, + 0xBE,0xE5,0x08,0x53,0xBB,0xE0,0x0D,0x56, + 0x88,0xD3,0x3E,0x65,0x8D,0xD6,0x3B,0x60, + 0x82,0xD9,0x34,0x6F,0x87,0xDC,0x31,0x6A, + 0x9C,0xC7,0x2A,0x71,0x99,0xC2,0x2F,0x74, + 0x96,0xCD,0x20,0x7B,0x93,0xC8,0x25,0x7E, + 0xF0,0xAB,0x46,0x1D,0xF5,0xAE,0x43,0x18, + 0xFA,0xA1,0x4C,0x17,0xFF,0xA4,0x49,0x12, + 0xE4,0xBF,0x52,0x09,0xE1,0xBA,0x57,0x0C, + 0xEE,0xB5,0x58,0x03,0xEB,0xB0,0x5D,0x06, + 0xD8,0x83,0x6E,0x35,0xDD,0x86,0x6B,0x30, + 0xD2,0x89,0x64,0x3F,0xD7,0x8C,0x61,0x3A, + 0xCC,0x97,0x7A,0x21,0xC9,0x92,0x7F,0x24, + 0xC6,0x9D,0x70,0x2B,0xC3,0x98,0x75,0x2E }; + + +/* Mul_EF[i] is 0xEF * i in GF(256), whatever that means... */ + +static unsigned char Mul_EF[256] = { + 0x00,0xEF,0xB7,0x58,0x07,0xE8,0xB0,0x5F, + 0x0E,0xE1,0xB9,0x56,0x09,0xE6,0xBE,0x51, + 0x1C,0xF3,0xAB,0x44,0x1B,0xF4,0xAC,0x43, + 0x12,0xFD,0xA5,0x4A,0x15,0xFA,0xA2,0x4D, + 0x38,0xD7,0x8F,0x60,0x3F,0xD0,0x88,0x67, + 0x36,0xD9,0x81,0x6E,0x31,0xDE,0x86,0x69, + 0x24,0xCB,0x93,0x7C,0x23,0xCC,0x94,0x7B, + 0x2A,0xC5,0x9D,0x72,0x2D,0xC2,0x9A,0x75, + 0x70,0x9F,0xC7,0x28,0x77,0x98,0xC0,0x2F, + 0x7E,0x91,0xC9,0x26,0x79,0x96,0xCE,0x21, + 0x6C,0x83,0xDB,0x34,0x6B,0x84,0xDC,0x33, + 0x62,0x8D,0xD5,0x3A,0x65,0x8A,0xD2,0x3D, + 0x48,0xA7,0xFF,0x10,0x4F,0xA0,0xF8,0x17, + 0x46,0xA9,0xF1,0x1E,0x41,0xAE,0xF6,0x19, + 0x54,0xBB,0xE3,0x0C,0x53,0xBC,0xE4,0x0B, + 0x5A,0xB5,0xED,0x02,0x5D,0xB2,0xEA,0x05, + 0xE0,0x0F,0x57,0xB8,0xE7,0x08,0x50,0xBF, + 0xEE,0x01,0x59,0xB6,0xE9,0x06,0x5E,0xB1, + 0xFC,0x13,0x4B,0xA4,0xFB,0x14,0x4C,0xA3, + 0xF2,0x1D,0x45,0xAA,0xF5,0x1A,0x42,0xAD, + 0xD8,0x37,0x6F,0x80,0xDF,0x30,0x68,0x87, + 0xD6,0x39,0x61,0x8E,0xD1,0x3E,0x66,0x89, + 0xC4,0x2B,0x73,0x9C,0xC3,0x2C,0x74,0x9B, + 0xCA,0x25,0x7D,0x92,0xCD,0x22,0x7A,0x95, + 0x90,0x7F,0x27,0xC8,0x97,0x78,0x20,0xCF, + 0x9E,0x71,0x29,0xC6,0x99,0x76,0x2E,0xC1, + 0x8C,0x63,0x3B,0xD4,0x8B,0x64,0x3C,0xD3, + 0x82,0x6D,0x35,0xDA,0x85,0x6A,0x32,0xDD, + 0xA8,0x47,0x1F,0xF0,0xAF,0x40,0x18,0xF7, + 0xA6,0x49,0x11,0xFE,0xA1,0x4E,0x16,0xF9, + 0xB4,0x5B,0x03,0xEC,0xB3,0x5C,0x04,0xEB, + 0xBA,0x55,0x0D,0xE2,0xBD,0x52,0x0A,0xE5 }; + +static inline DWORD mds_mul(BYTE *y) +{ DWORD z; + + z=Mul_EF[y[0]] ^ y[1] ^ Mul_EF[y[2]] ^ Mul_5B[y[3]]; + z<<=8; + z|=Mul_EF[y[0]] ^ Mul_5B[y[1]] ^ y[2] ^ Mul_EF[y[3]]; + z<<=8; + z|=Mul_5B[y[0]] ^ Mul_EF[y[1]] ^ Mul_EF[y[2]] ^ y[3]; + z<<=8; + z|=y[0] ^ Mul_EF[y[1]] ^ Mul_5B[y[2]] ^ Mul_5B[y[3]]; + + return z; +} + +/* q0 and q1 are the lookup substitutions done in twofish */ + +static unsigned char q0[256] = +{ 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, + 0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38, + 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, + 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, + 0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23, + 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, + 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, + 0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61, + 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, + 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, + 0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66, + 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, + 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, + 0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71, + 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, + 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, + 0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2, + 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, + 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, + 0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF, + 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, + 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, + 0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A, + 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, + 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, + 0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D, + 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, + 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, + 0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8, + 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, + 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, + 0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0}; + +static unsigned char q1[256] = +{ 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, + 0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B, + 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, + 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, + 0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D, + 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, + 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, + 0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51, + 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, + 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, + 0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70, + 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, + 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, + 0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2, + 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, + 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, + 0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3, + 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, + 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, + 0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9, + 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, + 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, + 0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19, + 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, + 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, + 0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69, + 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, + 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, + 0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB, + 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, + 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, + 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91 + }; + + +static DWORD f32(DWORD x, const DWORD * k32, int keyLen) +{ + BYTE b[4]; + + /* Run each byte thru 8x8 S-boxes, xoring with key byte at each stage. */ + /* Note that each byte goes through a different combination of S-boxes. */ + + *((DWORD *) b) = Bswap(x); /* make b[0] = LSB, b[3] = MSB */ + + switch (((keyLen + 63) / 64) & 3) + { + case 0: /* 256 bits of key */ + b[0] = q1[b[0]]; + b[1] = q0[b[1]]; + b[2] = q0[b[2]]; + b[3] = q1[b[3]]; + + *((DWORD *) b) ^= k32[3]; + + /* fall thru, having pre-processed b[0]..b[3] with k32[3] */ + case 3: /* 192 bits of key */ + b[0] = q1[b[0]]; + b[1] = q1[b[1]]; + b[2] = q0[b[2]]; + b[3] = q0[b[3]]; + + *((DWORD *) b) ^= k32[2]; + + /* fall thru, having pre-processed b[0]..b[3] with k32[2] */ + case 2: /* 128 bits of key */ + b[0] = q0[b[0]]; + b[1] = q1[b[1]]; + b[2] = q0[b[2]]; + b[3] = q1[b[3]]; + + *((DWORD *) b) ^= k32[1]; + + b[0] = q0[b[0]]; + b[1] = q0[b[1]]; + b[2] = q1[b[2]]; + b[3] = q1[b[3]]; + + *((DWORD *) b) ^= k32[0]; + + b[0] = q1[b[0]]; + b[1] = q0[b[1]]; + b[2] = q1[b[2]]; + b[3] = q0[b[3]]; + } + + + /* Now perform the MDS matrix multiply inline. */ + return mds_mul(b); +} + + +static void init_sbox(fish2_key *key) +{ DWORD x,*sbox,z,*k32; + int i,keyLen; + BYTE b[4]; + + k32=key->sboxKeys; + keyLen=key->keyLen; + sbox=key->sbox_full; + + x=0; + for (i=0;i<256;i++,x+=0x01010101) + { + *((DWORD *) b) = Bswap(x); /* make b[0] = LSB, b[3] = MSB */ + + switch (((keyLen + 63) / 64) & 3) + { + case 0: /* 256 bits of key */ + b[0] = q1[b[0]]; + b[1] = q0[b[1]]; + b[2] = q0[b[2]]; + b[3] = q1[b[3]]; + + *((DWORD *) b) ^= k32[3]; + + /* fall thru, having pre-processed b[0]..b[3] with k32[3] */ + case 3: /* 192 bits of key */ + b[0] = q1[b[0]]; + b[1] = q1[b[1]]; + b[2] = q0[b[2]]; + b[3] = q0[b[3]]; + + *((DWORD *) b) ^= k32[2]; + + /* fall thru, having pre-processed b[0]..b[3] with k32[2] */ + case 2: /* 128 bits of key */ + b[0] = q0[b[0]]; + b[1] = q1[b[1]]; + b[2] = q0[b[2]]; + b[3] = q1[b[3]]; + + *((DWORD *) b) ^= k32[1]; + + b[0] = q0[b[0]]; + b[1] = q0[b[1]]; + b[2] = q1[b[2]]; + b[3] = q1[b[3]]; + + *((DWORD *) b) ^= k32[0]; + + b[0] = q1[b[0]]; + b[1] = q0[b[1]]; + b[2] = q1[b[2]]; + b[3] = q0[b[3]]; + } + + z=Mul_EF[b[0]]; + z<<=8; + z|=Mul_EF[b[0]]; + z<<=8; + z|=Mul_5B[b[0]]; + z<<=8; + z|=b[0]; + + sbox[i]=z; + + z=b[1]; + z<<=8; + z|=Mul_5B[b[1]]; + z<<=8; + z|=Mul_EF[b[1]]; + z<<=8; + z|=Mul_EF[b[1]]; + + sbox[i+256]=z; + + z=Mul_EF[b[2]]; + z<<=8; + z|=b[2]; + z<<=8; + z|=Mul_EF[b[2]]; + z<<=8; + z|=Mul_5B[b[2]]; + + sbox[i+512]=z; + + z=Mul_5B[b[3]]; + z<<=8; + z|=Mul_EF[b[3]]; + z<<=8; + z|=b[3]; + z<<=8; + z|=Mul_5B[b[3]]; + + sbox[i+768]=z; + } +} + + +/* Reed-Solomon code parameters: (12,8) reversible code + g(x) = x**4 + (a + 1/a) x**3 + a x**2 + (a + 1/a) x + 1 + where a = primitive root of field generator 0x14D */ +#define RS_GF_FDBK 0x14D /* field generator */ +#define RS_rem(x) \ + { BYTE b = x >> 24; \ + DWORD g2 = ((b << 1) ^ ((b & 0x80) ? RS_GF_FDBK : 0 )) & 0xFF; \ + DWORD g3 = ((b >> 1) & 0x7F) ^ ((b & 1) ? RS_GF_FDBK >> 1 : 0 ) ^ g2 ; \ + x = (x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b; \ + } + +static DWORD rs_mds(DWORD k0, DWORD k1) +{ + int i, j; + DWORD r; + + for (i = r = 0; i < 2; i++) + { + r ^= (i) ? k0 : k1; /* merge in 32 more key bits */ + for (j = 0; j < 4; j++) /* shift one byte at a time */ + RS_rem(r); + } + return r; +} + + +#define INPUT_WHITEN 0 /* subkey array indices */ +#define OUTPUT_WHITEN 4 +#define ROUND_SUBKEYS 8 /* use 2 * (# rounds) */ +#define TOTAL_SUBKEYS 40 + +static void init_key(fish2_key * key) +{ + int i, k64Cnt; + int keyLen = key->keyLen; + int subkeyCnt = TOTAL_SUBKEYS; + DWORD A, B; + DWORD k32e[4], k32o[4]; /* even/odd key dwords */ + + k64Cnt = (keyLen + 63) / 64; /* round up to next multiple of 64 bits */ + for (i = 0; i < k64Cnt; i++) + { /* split into even/odd key dwords */ + k32e[i] = ((DWORD *)key->key)[2 * i]; + k32o[i] = ((DWORD *)key->key)[2 * i + 1]; + /* compute S-box keys using (12,8) Reed-Solomon code over GF(256) */ + /* store in reverse order */ + key->sboxKeys[k64Cnt - 1 - i] = + Bswap(rs_mds(Bswap(k32e[i]), Bswap(k32o[i]))); + + } + + for (i = 0; i < subkeyCnt / 2; i++) /* compute round subkeys for PHT */ + { + A = f32(i * 0x02020202, k32e, keyLen); /* A uses even key dwords */ + B = f32(i * 0x02020202 + 0x01010101, k32o, keyLen); /* B uses odd key + dwords */ + B = ROL(B, 8); + key->subKeys[2 * i] = A + B; /* combine with a PHT */ + key->subKeys[2 * i + 1] = ROL(A + 2 * B, 9); + } + + init_sbox(key); +} + + +static inline DWORD f32_sbox(DWORD x,DWORD *sbox) +{ + /* Run each byte thru 8x8 S-boxes, xoring with key byte at each stage. */ + /* Note that each byte goes through a different combination of S-boxes. */ + + return (sbox[ (x) &0xff]^ + sbox[256 + (((x)>> 8)&0xff)]^ + sbox[512 + (((x)>>16)&0xff)]^ + sbox[768 + (((x)>>24)&0xff)]); +} + +#define roundE_m(x0,x1,x2,x3,rnd) \ + t0 = f32_sbox( x0, key->sbox_full ) ; \ + t1 = f32_sbox( ROL(x1,8), key->sbox_full ); \ + x2 ^= t0 + t1 + key->subKeys[2*rnd+8]; \ + x3 = ROL(x3,1); \ + x3 ^= t0 + 2*t1 + key->subKeys[2*rnd+9]; \ + x2 = ROR(x2,1); + + +static int blockEncrypt_CBC(fish2_key *key,BYTE *src,BYTE *dst,int len) +{ DWORD xx0,xx1,xx2,xx3,t0,t1,iv0,iv1,iv2,iv3; + + if (len & 0xF) return -1; + + iv0=0; + iv1=0; + iv2=0; + iv3=0; + for (;len>=16;len-=16) + + { + if ( ( len & 0x1FF) == 0) + { iv0=0; + iv1=0; + iv2=0; + iv3=0; + } + + xx0=Bswap(((DWORD *)src)[0]) ^ key->subKeys[0] ^ iv0; + xx1=Bswap(((DWORD *)src)[1]) ^ key->subKeys[1] ^ iv1; + xx2=Bswap(((DWORD *)src)[2]) ^ key->subKeys[2] ^ iv2; + xx3=Bswap(((DWORD *)src)[3]) ^ key->subKeys[3] ^ iv3; + + src+=16; + + roundE_m(xx0,xx1,xx2,xx3,0); + roundE_m(xx2,xx3,xx0,xx1,1); + roundE_m(xx0,xx1,xx2,xx3,2); + roundE_m(xx2,xx3,xx0,xx1,3); + roundE_m(xx0,xx1,xx2,xx3,4); + roundE_m(xx2,xx3,xx0,xx1,5); + roundE_m(xx0,xx1,xx2,xx3,6); + roundE_m(xx2,xx3,xx0,xx1,7); + roundE_m(xx0,xx1,xx2,xx3,8); + roundE_m(xx2,xx3,xx0,xx1,9); + roundE_m(xx0,xx1,xx2,xx3,10); + roundE_m(xx2,xx3,xx0,xx1,11); + roundE_m(xx0,xx1,xx2,xx3,12); + roundE_m(xx2,xx3,xx0,xx1,13); + roundE_m(xx0,xx1,xx2,xx3,14); + roundE_m(xx2,xx3,xx0,xx1,15); + + iv0=xx2 ^ key->subKeys[4]; + iv1=xx3 ^ key->subKeys[5]; + iv2=xx0 ^ key->subKeys[6]; + iv3=xx1 ^ key->subKeys[7]; + + ((DWORD *)dst)[0] = Bswap(iv0); + ((DWORD *)dst)[1] = Bswap(iv1); + ((DWORD *)dst)[2] = Bswap(iv2); + ((DWORD *)dst)[3] = Bswap(iv3); + dst+=16; + } + return len; +} + +#define roundD_m(x0,x1,x2,x3,rnd) \ + t0 = f32_sbox( x0, key->sbox_full); \ + t1 = f32_sbox( ROL(x1,8),key->sbox_full); \ + x2 = ROL(x2,1); \ + x3 ^= t0 + 2*t1 + key->subKeys[rnd*2+9]; \ + x3 = ROR(x3,1); \ + x2 ^= t0 + t1 + key->subKeys[rnd*2+8]; + + +static int blockDecrypt_CBC(fish2_key *key,BYTE *src,BYTE *dst,int len) +{ DWORD xx0,xx1,xx2,xx3,t0,t1,lx0,lx1,lx2,lx3,iv0,iv1,iv2,iv3; + + if (len & 0xF) return -1; + + iv0=0; + iv1=0; + iv2=0; + iv3=0; + + for (;len>=16;len-=16) + { + if ( ( len & 0x1FF) == 0) + { iv0=0; + iv1=0; + iv2=0; + iv3=0; + } + + lx0=iv0;iv0=Bswap(((DWORD *)src)[0]);xx0=iv0 ^ key->subKeys[4]; + lx1=iv1;iv1=Bswap(((DWORD *)src)[1]);xx1=iv1 ^ key->subKeys[5]; + lx2=iv2;iv2=Bswap(((DWORD *)src)[2]);xx2=iv2 ^ key->subKeys[6]; + lx3=iv3;iv3=Bswap(((DWORD *)src)[3]);xx3=iv3 ^ key->subKeys[7]; + src+=16; + + roundD_m(xx0,xx1,xx2,xx3,15); + roundD_m(xx2,xx3,xx0,xx1,14); + roundD_m(xx0,xx1,xx2,xx3,13); + roundD_m(xx2,xx3,xx0,xx1,12); + roundD_m(xx0,xx1,xx2,xx3,11); + roundD_m(xx2,xx3,xx0,xx1,10); + roundD_m(xx0,xx1,xx2,xx3,9); + roundD_m(xx2,xx3,xx0,xx1,8); + roundD_m(xx0,xx1,xx2,xx3,7); + roundD_m(xx2,xx3,xx0,xx1,6); + roundD_m(xx0,xx1,xx2,xx3,5); + roundD_m(xx2,xx3,xx0,xx1,4); + roundD_m(xx0,xx1,xx2,xx3,3); + roundD_m(xx2,xx3,xx0,xx1,2); + roundD_m(xx0,xx1,xx2,xx3,1); + roundD_m(xx2,xx3,xx0,xx1,0); + + ((DWORD *)dst)[0] = Bswap(xx2 ^ key->subKeys[0] ^ lx0); + ((DWORD *)dst)[1] = Bswap(xx3 ^ key->subKeys[1] ^ lx1); + ((DWORD *)dst)[2] = Bswap(xx0 ^ key->subKeys[2] ^ lx2); + ((DWORD *)dst)[3] = Bswap(xx1 ^ key->subKeys[3] ^ lx3); + dst+=16; + } + return len; +} + + +int transfer_fish2(struct loop_device *lo, int cmd, char *raw_buf, + char *loop_buf, int size, int real_block) +{ if (cmd == READ) + blockDecrypt_CBC((fish2_key *)lo->key_data,raw_buf,loop_buf,size); + else + blockEncrypt_CBC((fish2_key *)lo->key_data,loop_buf,raw_buf,size); + return 0; +} + +int fish2_init(struct loop_device *lo,struct loop_info *info) +{ fish2_key *key; + + if (info->lo_encrypt_key_size<16 || info->lo_encrypt_key_size>32) + return -EINVAL; + + key=(fish2_key *)kmalloc(sizeof(fish2_key),GFP_KERNEL); + + if (key==NULL) + return -ENOMEM; + + lo->key_data=key; + + memset(key->key,0,32); + + key->keyLen=info->lo_encrypt_key_size << 3; + memcpy(key->key,info->lo_encrypt_key,info->lo_encrypt_key_size); + + init_key(key); + + return 0; +} + +static int fish2_release(struct loop_device *lo) +{ if (lo->key_data!=NULL) + { + kfree(lo->key_data); + lo->key_data=NULL; + } + return(0); +} + +static void fish2_lock(struct loop_device *lo) +{ + MOD_INC_USE_COUNT; +} + +static void fish2_unlock(struct loop_device *lo) +{ + MOD_DEC_USE_COUNT; +} + + + +static struct loop_func_table fish2_funcs = +{ number: LO_CRYPT_FISH2, + transfer: transfer_fish2, + init: fish2_init, + release: fish2_release, + lock: fish2_lock, + unlock: fish2_unlock +}; + +#ifdef MODULE +int __init init_module(void) +#else +int __init loop_fish2_init(void) +#endif +{ + int err; + + if ((err=loop_register_transfer(&fish2_funcs))) + { + printk(KERN_WARNING "Couldn't register Twofish encryption\n"); + return err; + } + printk(KERN_INFO "loop: registered Twofish encryption \n"); + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + if (loop_unregister_transfer(LO_CRYPT_FISH2)) + printk(KERN_WARNING "Couldn't unregister Twofish encryption\n"); + printk(KERN_INFO "loop: unregistered Twofish encryption \n"); +} +#endif diff -ruN linux-2.2.5,pristine/drivers/block/loop_gen.c linux-2.2.5/drivers/block/loop_gen.c --- linux-2.2.5,pristine/drivers/block/loop_gen.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/drivers/block/loop_gen.c Thu Apr 1 23:05:45 1999 @@ -0,0 +1,193 @@ +#include <linux/module.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/string.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <asm/byteorder.h> +#include <linux/loop.h> +#include <linux/crypto.h> + + +static char loop_gen_xfers[MAX_CIPHER] = {0}; + +static int loop_gen_transfer(struct loop_device *lo, int cmd, char *raw_buf, + char *loop_buf, int size, int real_block) +{ + struct cipher_context * cx = (struct cipher_context *) lo->key_data; + struct cipher_implementation *ci = cx->ci; + int bsize = ci->blocksize; + int (*encdecfunc)(struct cipher_context *cx, u32 *in, u32 *out, int size); + char *in, *out; + + if (cmd == READ) { + encdecfunc = ci->decrypt; + in = raw_buf; + out = loop_buf; + } else { + encdecfunc = ci->encrypt; + in = loop_buf; + out = raw_buf; + } + if (!encdecfunc) { + printk("ouch! encdecfunc == NULL!\n"); + return -EINVAL; + } + cx->iv[0] = real_block; + if (bsize) { + while (size >= bsize) { + encdecfunc(cx, (u32 *)in, (u32 *)out, bsize); + in += bsize; + out += bsize; + size -= bsize; + } + if (size != 0) { + return -EINVAL; + } + } else { /* variable-size cipher */ + encdecfunc(cx, (u32 *)in, (u32 *)out, size); + } + + return 0; +} + + +static int loop_gen_init2(struct loop_device *lo, struct loop_info *info) +{ + int cipher,err = -EINVAL; + struct cipher_implementation *ci; + struct cipher_context *cx; + + switch (info->lo_encrypt_type) { + case LO_CRYPT_NONE: cipher = CIPHER_NONE; break; + case LO_CRYPT_XOR: cipher = CIPHER_XOR; break; + case LO_CRYPT_DES: cipher = CIPHER_cbc_DES; break; + case LO_CRYPT_FISH2: cipher = CIPHER_cbc_FISH2; break; + case LO_CRYPT_BLOW: cipher = CIPHER_cbc_BLOWFISH; break; + case LO_CRYPT_CAST128: cipher = CIPHER_cbc_CAST128; break; + case LO_CRYPT_IDEA: cipher = CIPHER_cbc_IDEA; break; + case LO_CRYPT_SERPENT: cipher = CIPHER_cbc_SERPENT; break; + case LO_CRYPT_MARS: cipher = CIPHER_cbc_MARS; break; + case LO_CRYPT_SKIPJACK: cipher = CIPHER_cbc_SKIPJACK; break; + case LO_CRYPT_RC6: cipher = CIPHER_cbc_RC6; break; + case LO_CRYPT_3DES: cipher = CIPHER_cbc_3DES; break; + case LO_CRYPT_E2: cipher = CIPHER_cbc_E2; break; + case LO_CRYPT_CAST256: cipher = CIPHER_cbc_CAST256; break; + case LO_CRYPT_DFC: cipher = CIPHER_cbc_DFC; break; + default: goto out; + } + + ci = find_cipher_by_id(cipher); + if (!ci) + goto out; + + if (ci->cipher_id != cipher) { + printk("find_cipher_by_id gave me the wrong cipher!\n"); + goto out_ci; + } + + lock_cipher(ci); + err = -ENOMEM; + cx = (struct cipher_context *) kmalloc(sizeof(struct cipher_context), + GFP_KERNEL); + if (!cx) + goto out_ci; + cx->ci = ci; + memset(&cx->iv, 0, cx->ci->ivsize); + cx->keyinfo = (u32 *) kmalloc(ci->key_schedule_size, GFP_KERNEL); + if (!cx->keyinfo) + goto out_cx; + if (!ci->set_key) { + printk("Invalid cipher - set_key is NULL\n"); + err = -EINVAL; + goto out_key; + } + if (ci->set_key(cx, info->lo_encrypt_key, + info->lo_encrypt_key_size)) { + err = -EINVAL; + goto out_key; + } + lo->key_data = cx; + return 0; + + out_key: + kfree(cx->keyinfo); + out_cx: + kfree(cx); + out_ci: + unlock_cipher(ci); + out: + return err; +} + + +static int loop_gen_release(struct loop_device *lo) +{ + struct cipher_context *cx = (struct cipher_context *) lo->key_data; + if (cx != NULL) { + memset(cx->keyinfo, 0, cx->ci->key_schedule_size); + kfree(cx->keyinfo); + unlock_cipher(cx->ci); + memset(cx, 0, sizeof(*cx)); + kfree(cx); + lo->key_data=NULL; + } + return 0; +} + + +static void loop_gen_lock(struct loop_device *lo) +{ + MOD_INC_USE_COUNT; +} + +static void loop_gen_unlock(struct loop_device *lo) +{ + MOD_DEC_USE_COUNT; +} + +#ifdef MODULE +int __init init_module(void) +#else +int __init loop_gen_init(void) +#endif +{ + int i, n=0, err; + struct loop_func_table *funcs; + + for (i=0; i<MAX_CIPHER; i++) { + funcs = kmalloc(sizeof (struct loop_func_table), GFP_KERNEL); + memset(funcs, 0, sizeof(*funcs)); + if (funcs) { + funcs->number = i; + funcs->transfer = loop_gen_transfer; + funcs->init = loop_gen_init2; + funcs->release = loop_gen_release; + funcs->lock = loop_gen_lock; + funcs->unlock = loop_gen_unlock; + + err = loop_register_transfer(funcs); + if (!err) { + loop_gen_xfers[i] = 1; + n++; + } + } + } + return 0; +} + +#ifdef MODULE +void cleanup_module(void) +{ + int i; + + for (i=0; i<MAX_CIPHER; i++) { + if (loop_gen_xfers[i]) { + loop_unregister_transfer(i); + loop_gen_xfers[i] = 0; + } + } +} +#endif + diff -ruN linux-2.2.5,pristine/include/asm-alpha/wordops.h linux-2.2.5/include/asm-alpha/wordops.h --- linux-2.2.5,pristine/include/asm-alpha/wordops.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/include/asm-alpha/wordops.h Thu Apr 1 23:05:45 1999 @@ -0,0 +1,7 @@ +#ifndef _ALPHA_WORDOPS_H +#define _ALPHA_WORDOPS_H + +#define rotr32(x,n) generic_rotr32(x,n) +#define rotl32(x,n) generic_rotl32(x,n) + +#endif diff -ruN linux-2.2.5,pristine/include/asm-arm/wordops.h linux-2.2.5/include/asm-arm/wordops.h --- linux-2.2.5,pristine/include/asm-arm/wordops.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/include/asm-arm/wordops.h Thu Apr 1 23:05:45 1999 @@ -0,0 +1,7 @@ +#ifndef _ARM_WORDOPS_H +#define _ARM_WORDOPS_H + +#define rotr32(x,n) generic_rotr32(x,n) +#define rotl32(x,n) generic_rotl32(x,n) + +#endif diff -ruN linux-2.2.5,pristine/include/asm-i386/wordops.h linux-2.2.5/include/asm-i386/wordops.h --- linux-2.2.5,pristine/include/asm-i386/wordops.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/include/asm-i386/wordops.h Thu Apr 1 23:05:45 1999 @@ -0,0 +1,20 @@ +#ifndef _I386_WORDOPS_H +#define _I386_WORDOPS_H + +extern __inline__ int rotr32(__u32 x, int n) +{ + if (n == 32 || n == 0 || n == -32) + return x; + __asm__("rorl %1,%0" : "=r"(x) : "ir"(n)); + return x; +} + +extern __inline__ int rotl32(__u32 x, int n) +{ + if (n == 32 || n == 0 || n == -32) + return x; + __asm__("roll %1,%0" : "=r"(x) : "ir"(n)); + return x; +} + +#endif diff -ruN linux-2.2.5,pristine/include/asm-m68k/wordops.h linux-2.2.5/include/asm-m68k/wordops.h --- linux-2.2.5,pristine/include/asm-m68k/wordops.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/include/asm-m68k/wordops.h Thu Apr 1 23:05:45 1999 @@ -0,0 +1,8 @@ +#ifndef _M68K_WORDOPS_H +#define _M68K_WORDOPS_H + +#define rotr32(x,n) generic_rotr32(x,n) +#define rotl32(x,n) generic_rotl32(x,n) + +#endif + diff -ruN linux-2.2.5,pristine/include/asm-mips/wordops.h linux-2.2.5/include/asm-mips/wordops.h --- linux-2.2.5,pristine/include/asm-mips/wordops.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/include/asm-mips/wordops.h Thu Apr 1 23:05:45 1999 @@ -0,0 +1,8 @@ +#ifndef _MIPS_WORDOPS_H +#define _MIPS_WORDOPS_H + +#define rotr32(x,n) generic_rotr32(x,n) +#define rotl32(x,n) generic_rotl32(x,n) + +#endif + diff -ruN linux-2.2.5,pristine/include/asm-ppc/wordops.h linux-2.2.5/include/asm-ppc/wordops.h --- linux-2.2.5,pristine/include/asm-ppc/wordops.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/include/asm-ppc/wordops.h Thu Apr 1 23:05:45 1999 @@ -0,0 +1,41 @@ +#ifndef _PPC_WORDOPS_H +#define _PPC_WORDOPS_H + +#if 0 +/* The following is implemented from datasheets. If you have a + * PowerPC and can test the code, send me a note + * Alexander Kjeldaas <astor@guardian.no> + */ + +extern __inline__ rotr32(__u32 x, int n) +{ + int r; + if (n == 32 || n == 0 || n == -32) + return x; + if (__builtin_const_p(x)) + __asm__("rotrwi %0,%1,%2" : "=r"(r) : "r"(x), "i"(n)); + else + __asm__("rotrw %0,%1,%2" : "=r"(r) : "r"(x), "r"(n)); + return r; +} + +extern __inline__ rotl32(__u32 x, int n) +{ + int r; + if (n == 32 || n == 0 || n == -32) + return x; + if (__builtin_const_p(x)) + __asm__("rotlwi %0,%1,%2" : "=r"(r) : "r"(x), "i"(n)); + else + __asm__("rotlw %0,%1,%2" : "=r"(r) : "r"(x), "r"(n)); + return r; +} + +#else + +#define rotr32(x,n) generic_rotr32(x,n) +#define rotl32(x,n) generic_rotl32(x,n) + +#endif + +#endif diff -ruN linux-2.2.5,pristine/include/asm-sparc/wordops.h linux-2.2.5/include/asm-sparc/wordops.h --- linux-2.2.5,pristine/include/asm-sparc/wordops.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/include/asm-sparc/wordops.h Thu Apr 1 23:05:45 1999 @@ -0,0 +1,7 @@ +#ifndef _SPARC_WORDOPS_H +#define _SPARC_WORDOPS_H + +#define rotr32(x,n) generic_rotr32(x,n) +#define rotl32(x,n) generic_rotl32(x,n) + +#endif diff -ruN linux-2.2.5,pristine/include/asm-sparc64/wordops.h linux-2.2.5/include/asm-sparc64/wordops.h --- linux-2.2.5,pristine/include/asm-sparc64/wordops.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/include/asm-sparc64/wordops.h Thu Apr 1 23:05:45 1999 @@ -0,0 +1,7 @@ +#ifndef _SPARC9_WORDOPS_H +#define _SPARC9_WORDOPS_H + +#define rotr32(x,n) generic_rotr32(x,n) +#define rotl32(x,n) generic_rotl32(x,n) + +#endif diff -ruN linux-2.2.5,pristine/include/linux/blk.h linux-2.2.5/include/linux/blk.h --- linux-2.2.5,pristine/include/linux/blk.h Sun Mar 28 20:04:06 1999 +++ linux-2.2.5/include/linux/blk.h Thu Apr 1 23:05:45 1999 @@ -52,6 +52,11 @@ extern int xd_init(void); extern int mfm_init(void); extern int loop_init(void); +extern int loop_serpent_init(void); +extern int loop_cast_init(void); +extern int loop_idea_init(void); +extern int loop_blow_init(void); +extern int loop_fish2_init(void); extern int md_init(void); extern int ap_init(void); extern int ddv_init(void); diff -ruN linux-2.2.5,pristine/include/linux/crypto.h linux-2.2.5/include/linux/crypto.h --- linux-2.2.5,pristine/include/linux/crypto.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/include/linux/crypto.h Thu Apr 1 23:05:45 1999 @@ -0,0 +1,216 @@ +#ifndef _LINUX_CRYPTO_H +#define _LINUX_CRYPTO_H + +/* + * include/linux/crypto.h + * + * Written by Alexander Kjeldaas <astor@guardian.no> 1998-10-13 + * + * Copyright 1998 by Alexander Kjeldaas. This code is licensed under + * an X11-like license. See LICENSE.crypto for details. + * + */ + +#define CIPHER_NONE 0 +#define CIPHER_XOR 1 +#define CIPHER_DES 2 +#define CIPHER_FISH2 3 +#define CIPHER_BLOWFISH 4 +#define CIPHER_CAST128 5 +#define CIPHER_IDEA 6 +#define CIPHER_SERPENT 7 +#define CIPHER_MARS 8 + +#define CIPHER_SKIPJACK 10 +#define CIPHER_RC6 11 +#define CIPHER_3DES 12 +#define CIPHER_E2 13 +#define CIPHER_CAST256 14 +#define CIPHER_DFC 15 +#define CIPHER_RIJNDAEL 16 +#define MAX_CIPHER 20 + +#define CIPHER_CBC 0x00010000 +#define CIPHER_cbc_DES (CIPHER_DES | CIPHER_CBC) +#define CIPHER_cbc_FISH2 (CIPHER_FISH2 | CIPHER_CBC) +#define CIPHER_cbc_BLOWFISH (CIPHER_BLOWFISH | CIPHER_CBC) +#define CIPHER_cbc_CAST128 (CIPHER_CAST128 | CIPHER_CBC) +#define CIPHER_cbc_IDEA (CIPHER_IDEA | CIPHER_CBC) +#define CIPHER_cbc_SERPENT (CIPHER_SERPENT | CIPHER_CBC) +#define CIPHER_cbc_MARS (CIPHER_MARS | CIPHER_CBC) +#define CIPHER_cbc_SKIPJACK (CIPHER_SKIPJACK | CIPHER_CBC) +#define CIPHER_cbc_RC6 (CIPHER_RC6 | CIPHER_CBC) +#define CIPHER_cbc_3DES (CIPHER_3DES | CIPHER_CBC) +#define CIPHER_cbc_E2 (CIPHER_E2 | CIPHER_CBC) +#define CIPHER_cbc_CAST256 (CIPHER_CAST256 | CIPHER_CBC) +#define CIPHER_cbc_DFC (CIPHER_DFC | CIPHER_CBC) +#define CIPHER_cbc_RIJNDAEL (CIPHER_RIJNDAEL | CIPHER_CBC) + + +#ifdef __KERNEL__ + +#include <linux/lists.h> +#include <linux/kernel.h> +#include <asm/page.h> +#include <asm/semaphore.h> +#include <asm/spinlock.h> + +typedef u32 u4byte; +typedef u8 u1byte; + +struct cipher_context; + +struct cipher_implementation { + DLNODE(struct cipher_implementation) link; + int cipher_id; + char *cipher_name; + int blocksize; /* in bytes */ + int ivsize; /* in bytes */ + int key_schedule_size; /* in bytes */ + int (*encrypt)(struct cipher_context *cx, + u32 *in, u32 *out, int size); + int (*decrypt)(struct cipher_context *cx, + u32 *in, u32 *out, int size); + int (*set_key)(struct cipher_context *cx, + char *key, int key_len); + + /* lock and unlock manage the module use counts */ + void (*lock)(void); + void (*unlock)(void); + + /* keep track of the allocated proc_dir_entry */ + struct proc_dir_entry *de; +}; + +#define MAX_KEY_SIZE 8 +#define MAX_IV_SIZE MAX_KEY_SIZE + +struct cipher_context { + struct cipher_implementation *ci; + u32 *keyinfo; + int key_length; /* in bytes */ + u32 key[MAX_KEY_SIZE]; + u32 iv[MAX_IV_SIZE]; +}; + +typedef void (cipher_iterator)(struct cipher_implementation *); + +extern int ciphers_init(void); +extern struct cipher_implementation *find_cipher_by_id(int id); +extern struct cipher_implementation *find_cipher_by_name(char *name); +extern void for_each_cipher(cipher_iterator *fn); +extern int register_cipher(struct cipher_implementation *ci); +extern int unregister_cipher(struct cipher_implementation *ci); +extern int lock_cipher(struct cipher_implementation *ci); +extern int unlock_cipher(struct cipher_implementation *ci); + + +extern int init_cast256(void); +#define CAST256_KEY_SCHEDULE_SIZE (96*sizeof(u32)) +extern int cast256_set_key(struct cipher_context *cx, char *key, int key_len); +extern int cast256_encrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); +extern int cast256_decrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); + +extern int init_crypton(void); +#define CRYPTON_KEY_SCHEDULE_SIZE (104*sizeof(u32)) +extern int crypton_set_key(struct cipher_context *cx, char *key, int key_len); +extern int crypton_encrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); +extern int crypton_decrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); + +extern int init_serpent(void); +#define SERPENT_KEY_SCHEDULE_SIZE (140*sizeof(u32)) +extern int serpent_set_key(struct cipher_context *cx, char *key, int key_len); +extern int serpent_encrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); +extern int serpent_decrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); + +extern int init_mars(void); +#define MARS_KEY_SCHEDULE_SIZE (40*sizeof(u32)) +extern int mars_set_key(struct cipher_context *cx, char *key, int key_len); +extern int mars_encrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); +extern int mars_decrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); + +extern int init_rc6(void); +#define RC6_KEY_SCHEDULE_SIZE (44*sizeof(u32)) +extern int rc6_set_key(struct cipher_context *cx, char *key, int key_len); +extern int rc6_encrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); +extern int rc6_decrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); + +extern int init_dfc(void); +#define DFC_KEY_SCHEDULE_SIZE (32*sizeof(u32)) +extern int dfc_set_key(struct cipher_context *cx, char *key, int key_len); +extern int dfc_encrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); +extern int dfc_decrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); + +extern int init_rijndael(void); +#define RIJNDAEL_KEY_SCHEDULE_SIZE ((60+60)*sizeof(u32)) +extern int rijndael_set_key(struct cipher_context *cx, char *key, int key_len); +extern int rijndael_encrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); +extern int rijndael_decrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); + +extern int init_blowfish(void); +#define BLOWFISH_KEY_SCHEDULE_SIZE ((18+1024)*sizeof(u32)) +extern int blowfish_set_key(struct cipher_context *cx, + unsigned char *key, int key_len); +extern int blowfish_encrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); +extern int blowfish_decrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); +extern int init_idea(void); +#define IDEA_KEY_SCHEDULE_SIZE (104*2) +extern int idea_set_key(struct cipher_context *cx, + char *key, int key_len); +extern int idea_encrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); +extern int idea_decrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); + +extern int init_des(void); +#define DES_KEY_SCHEDULE_SIZE (32*sizeof(u32)) +extern int des_set_key(struct cipher_context *cx, + unsigned char *key, int key_len); +extern int des_encrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); +extern int des_decrypt(struct cipher_context *cx, + u32 *in, u32 *out, int size); + +#define DEFINE_GEN_CIPHER(uppername, name, sname, blocksize, ivsize, mode) \ +static struct cipher_implementation mode##name = \ +{ \ + DNODE_NULL, \ + CIPHER_##mode##uppername, \ + sname, \ + blocksize, \ + ivsize, \ + uppername##_KEY_SCHEDULE_SIZE, \ + name##_##mode##encrypt, \ + name##_##mode##decrypt, \ + name##_set_key, \ + name##_lock, \ + name##_unlock \ +} + +#define DEFINE_CIPHER(uppername, name, sname, blocksize, ivsize) \ + DEFINE_GEN_CIPHER(uppername, name, sname, blocksize, ivsize, ) + +#define DEFINE_CBC_CIPHER(uppername, name, sname, ivsize) \ + DEFINE_GEN_CIPHER(uppername, name, sname, 0, ivsize, cbc_) + +#define byte(x, nr) ((x) >> (nr*8)) + +#endif /* __KERNEL__ */ + +#endif diff -ruN linux-2.2.5,pristine/include/linux/loop.h linux-2.2.5/include/linux/loop.h --- linux-2.2.5,pristine/include/linux/loop.h Mon Nov 23 06:29:54 1998 +++ linux-2.2.5/include/linux/loop.h Thu Apr 1 23:05:45 1999 @@ -2,6 +2,7 @@ #define _LINUX_LOOP_H #include <linux/kdev_t.h> +#include <linux/crypto.h> /* * include/linux/loop.h @@ -90,12 +91,19 @@ #define LO_CRYPT_NONE 0 #define LO_CRYPT_XOR 1 #define LO_CRYPT_DES 2 -#define LO_CRYPT_FISH2 3 /* Brand new Twofish encryption */ +#define LO_CRYPT_FISH2 3 #define LO_CRYPT_BLOW 4 #define LO_CRYPT_CAST128 5 #define LO_CRYPT_IDEA 6 +#define LO_CRYPT_SERPENT 7 +#define LO_CRYPT_MARS 8 #define LO_CRYPT_DUMMY 9 #define LO_CRYPT_SKIPJACK 10 +#define LO_CRYPT_RC6 11 +#define LO_CRYPT_3DES 12 +#define LO_CRYPT_E2 13 +#define LO_CRYPT_CAST256 14 +#define LO_CRYPT_DFC 15 #define MAX_LO_CRYPT 20 #ifdef __KERNEL__ @@ -116,6 +124,9 @@ int loop_register_transfer(struct loop_func_table *funcs); int loop_unregister_transfer(int number); +struct loop_func_table *loop_find_xfer_funcs(int number); + + #endif /* diff -ruN linux-2.2.5,pristine/include/linux/wordops.h linux-2.2.5/include/linux/wordops.h --- linux-2.2.5,pristine/include/linux/wordops.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/include/linux/wordops.h Thu Apr 1 23:05:45 1999 @@ -0,0 +1,18 @@ +#ifndef _LINUX_WORDOPS_H +#define _LINUX_WORDOPS_H + +#include <linux/types.h> + +extern __inline__ int generic_rotr32(__u32 x, int n) +{ + return (((x) >> ((int)(n))) | ((x) << (32 - (int)(n)))); +} + +extern __inline__ int generic_rotl32(unsigned int x, int n) +{ + return (((x) << ((int)(n))) | ((x) >> (32 - (int)(n)))); +} + +#include <asm/wordops.h> + +#endif diff -ruN linux-2.2.5,pristine/include/net/sock.h linux-2.2.5/include/net/sock.h --- linux-2.2.5,pristine/include/net/sock.h Sun Mar 28 20:04:27 1999 +++ linux-2.2.5/include/net/sock.h Thu Apr 1 23:05:45 1999 @@ -527,6 +527,14 @@ int (*backlog_rcv) (struct sock *sk, struct sk_buff *skb); void (*destruct)(struct sock *sk); + +#ifdef CONFIG_NET_SECURITY + /* + * Security + */ + short authentication; + short encryption; +#endif }; /* IP protocol blocks we attach to sockets. diff -ruN linux-2.2.5,pristine/init/main.c linux-2.2.5/init/main.c --- linux-2.2.5,pristine/init/main.c Thu Feb 25 01:27:54 1999 +++ linux-2.2.5/init/main.c Thu Apr 1 23:05:46 1999 @@ -46,6 +46,10 @@ #include <linux/apm_bios.h> #endif +#ifdef CONFIG_CIPHERS +# include <linux/crypto.h> +#endif + /* * Versions of gcc older than that listed below may actually compile * and link okay, but the end product can have subtle run time bugs. @@ -1303,6 +1307,12 @@ /* .. filesystems .. */ filesystem_setup(); + + +#ifdef CONFIG_CIPHERS + /* .. ciphers .. */ + ciphers_init(); +#endif /* Mount the root filesystem.. */ mount_root(); diff -ruN linux-2.2.5,pristine/net/Config.in linux-2.2.5/net/Config.in --- linux-2.2.5,pristine/net/Config.in Thu Feb 25 19:46:47 1999 +++ linux-2.2.5/net/Config.in Thu Apr 1 23:05:46 1999 @@ -10,6 +10,9 @@ tristate 'Netlink device emulation' CONFIG_NETLINK_DEV fi bool 'Network firewalls' CONFIG_FIREWALL +if [ "$CONFIG_FIREWALL" = "y" ]; then + bool 'Network security (ENskip support)' CONFIG_NET_SECURITY +fi bool 'Socket Filtering' CONFIG_FILTER tristate 'Unix domain sockets' CONFIG_UNIX bool 'TCP/IP networking' CONFIG_INET @@ -63,4 +66,5 @@ endmenu fi fi +source net/cipe/Config.in endmenu diff -ruN linux-2.2.5,pristine/net/Makefile linux-2.2.5/net/Makefile --- linux-2.2.5,pristine/net/Makefile Mon Mar 22 20:18:17 1999 +++ linux-2.2.5/net/Makefile Thu Apr 1 23:05:46 1999 @@ -161,6 +161,14 @@ endif endif +ifeq ($(CONFIG_CIPE),y) +MOD_SUB_DIRS += cipe +else + ifeq ($(CONFIG_CIPE),m) + MOD_SUB_DIRS += cipe + endif +endif + # We must attach netsyms.o to socket.o, as otherwise there is nothing # to pull the object file from the archive. diff -ruN linux-2.2.5,pristine/net/cipe/CHANGES linux-2.2.5/net/cipe/CHANGES --- linux-2.2.5,pristine/net/cipe/CHANGES Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/CHANGES Thu Apr 1 23:05:46 1999 @@ -0,0 +1,14 @@ + --- THIS IS AN ALPHA VERSION -- USE AT YOUR OWN RISK --- + + User visible changes of this version since 1.0: + +- Runs under Linux 2.1.x, at least with x>=109. +- Device names have changed: protocol version is now a letter. 1=a, + 2=b etc., so cip3b->cipcb. +- Channels are allocated and deallocated dynamically. This enables the + default for cipe_maxdev to be set to 100. + (Compilation option NO_DYNDEV to remove this feature.) +- Statistics are logged upon close and then cleared. The log is simply + one line from /proc/net/dev. +- ciped waits for completion of ip-up before daemonizing. +- New configuration option for using key exchange timestamps. diff -ruN linux-2.2.5,pristine/net/cipe/COPYING linux-2.2.5/net/cipe/COPYING --- linux-2.2.5,pristine/net/cipe/COPYING Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/COPYING Thu Apr 1 23:05:46 1999 @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff -ruN linux-2.2.5,pristine/net/cipe/Checksums linux-2.2.5/net/cipe/Checksums --- linux-2.2.5,pristine/net/cipe/Checksums Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/Checksums Thu Apr 1 23:05:46 1999 @@ -0,0 +1,59 @@ +# This file contains a list of the files in this package with checksums. +# If you run this as a /bin/sh script, it will verify the PGP signature on +# this file and verify the individual files' checksums. +# +# Packaged by olaf@bigred.inka.de, Sat Nov 14 21:49:01 CET 1998 + +:<<'_marker_' +-----BEGIN PGP SIGNED MESSAGE----- + +____size_ _______________date_ ___________________md5-checksum_ _name________ + 796 Sep 19 00:49:22 1997 c8cae8576a04fe01557742ad420b1bea README + 652 Oct 18 18:02:52 1998 1e2b3270a4028d50277ba9c810c7353e CHANGES + 7828 Nov 14 21:48:02 1998 aeb67aac4b8386f09e221377f98a84dc cipe.h + 2206 Aug 17 20:42:44 1998 1da081e63d9d50976ec48f57d6f41936 crypto.h + 21564 Oct 18 17:38:41 1998 85fece904f3f8d0e1245697bcb035867 ciped.c + 810 Sep 19 01:00:46 1997 a5e1b4032e62dfc2a7a301aea9a55205 ciped.h + 1645 Nov 14 21:48:02 1998 ad260b21470f08cf072fe3d045bf2668 ioctl.c + 931 Aug 22 18:05:51 1998 ff64d954d85cc28272a0c15af658847c ioctl.h + 3622 Sep 19 01:00:47 1997 df57392125c09b4bf153596146c646b3 socks5.c + 1289 Oct 18 17:38:41 1998 141cf05740d734fbbde97a6be9457314 module.c + 13467 Nov 14 21:48:02 1998 098fd72bb57125f5e06a7264bb103876 device.c + 16936 Sep 24 01:11:59 1998 54860719f2ea82b85545d6d9b9b9a24e sock.c + 15796 Sep 22 22:24:00 1998 4b23009d0954e0945fdd18ff0b51f57a output.c + 6843 Aug 21 00:06:05 1998 1006490ed0a76be721e74652cdad88cb encaps.c + 5034 Oct 13 18:25:49 1996 9af2477ad5d09f437e3f5d4ef504b1db idea0.h + 8750 Nov 05 13:18:52 1998 dc3dac9ebae60063883d6ec9e315ad7a idea0.c + 858 Mar 21 00:28:10 1997 dfc61571400df91153f88cb8c1494fd7 bf.h + 2968 Apr 01 00:04:15 1997 0c9ad0d1d34108a13be183abd0173ce6 crc.c + 7081 May 30 00:20:41 1997 5de39024b25f15fc6c2e2c63a29c9d6c crc32.c + 235 Oct 22 19:33:31 1998 fb7b12d23f33a69457bb7528c3ed966d crcgen.c + 2588 Apr 01 00:07:01 1997 7106989d997a72788054ed910db7815e idea-i386.S + 18787 Sep 11 01:03:17 1998 1ee296728023dcfc1e87dc712431a4a7 bf-i386.S + 2178 Oct 13 18:19:16 1996 607f582afdf7cb5f99d20b0b9137477f thruput.c + 4994 Nov 14 21:48:02 1998 9fb076dbbc913d5e0f049585b4811bf0 Makefile + 432 Apr 07 22:26:16 1998 cd7c0bf5807c207be388cf3e590e4e1d cipe.lsm + 55 Oct 09 01:16:35 1996 3e202bcd35450045391894a1b85077a8 samples/README + 650 Feb 01 14:41:32 1998 f70a8b146b03a34683172701855c5d65 samples/options + 1698 Oct 16 14:31:08 1998 b89c3e798dc53d4d870f991a01213c33 samples/ip-up + 459 Oct 01 23:21:21 1998 3c3431b0c54ab8011fc6069ef08a984e samples/ip-down + 47141 Oct 18 17:39:26 1998 347d81df9ac1996c2a75287097467792 cipe.info + 1427 May 21 12:42:55 1998 14269b217687faf1243394174aa0f3b5 tcpdump.patch + 17982 Feb 16 22:11:36 1997 8ca43cbc842c2336e835926c2166c28b COPYING +____size_ _______________date_ ___________________md5-checksum_ _name________ +_marker_ + +echo "No output after the PGP signature check means everything is okay." +pgp -tf <$0 | sed -e '/^_marker_/q' -e '/^_/d' | cut -b32- | md5sum -c +exit $? + +-----BEGIN PGP SIGNATURE----- +Version: 2.6.3ia +Charset: latin1 + +iQCVAwUBNk3swcDBbWIyVM0dAQE1RgQAuAWpGAh9QpkPcU4a1Z/fQVUkUZUoXpPb +LdsRZv7WaGlF+YwwV6ALjTQbdMPWi4oSgC291IsyeeqZY5FfSfV3lbXy5HOSTVr8 +7cJM+bQHTYiOAWSZjOK3ILHZ9gJEw8BLC6vEcxCO476xsn9nXh1TgcJruA+ZKTY4 +UM3JPZGdvgo= +=5aqt +-----END PGP SIGNATURE----- diff -ruN linux-2.2.5,pristine/net/cipe/Config.in linux-2.2.5/net/cipe/Config.in --- linux-2.2.5,pristine/net/cipe/Config.in Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/Config.in Thu Apr 1 23:05:46 1999 @@ -0,0 +1,11 @@ +# +# CIPE configuration +# +bool 'CIPE: encrypted IP-in-UDP tunneling' CONFIG_CIPE n +if [ "$CONFIG_CIPE" = "y" ]; then + int 'CIPE: version' CONFIG_CIPE_VERSION 3 + bool 'CIPE: IDEA encryption' CONFIG_CIPE_IDEA n + if [ "$CONFIG_CIPE_IDEA" = "n" ]; then + bool 'CIPE: Blowfish encryption' CONFIG_CIPE_BLOWFISH y + fi +fi diff -ruN linux-2.2.5,pristine/net/cipe/Makefile linux-2.2.5/net/cipe/Makefile --- linux-2.2.5,pristine/net/cipe/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/Makefile Thu Apr 1 23:05:46 1999 @@ -0,0 +1,73 @@ +# +# Makefile for the Linux cipe driver. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definition is now in the main makefile... + +O_TARGET = +O_OBJS := module.o device.o sock.o output.o encaps.o +M_OBJS = $(O_TARGET) + +VERSION := 1.2.0 +CFG := -DProtocolVersion=$(CONFIG_CIPE_VERSION) -DVERSION=\"$(VERSION)\" +DEFS := -DDEBUG -DLOGFAC=LOG_DAEMON # -DNO_DYNDEV + +ifeq ($(CONFIG_CIPE_IDEA),y) +CFG += -DCrypto_IDEA +CRYPTO=IDEA +else +ifeq ($(CONFIG_CIPE_BLOWFISH),y) +CFG += -DCrypto_Blowfish +CRYPTO=Blowfish +endif +endif + +ifeq ($(CONFIG_CIPE_VERSION),1) +VERSC=a +O_OBJS += crc.o +endif +ifeq ($(CONFIG_CIPE_VERSION),2) +VERSC=b +O_OBJS += crc.o +endif +ifeq ($(CONFIG_CIPE_VERSION),3) +VERSC=c +O_OBJS += crc32.o +endif + +ifeq ($(ARCH),i386) +ifeq ($(CONFIG_CIPE_IDEA),y) +CFG += -DASM_Idea_Crypt +O_OBJS += idea-i386.o idea0.o +O_TARGET = cip$(VERSC)i.o +endif +ifeq ($(CONFIG_CIPE_BLOWFISH),y) +CFG += -DASM_BF_Crypt +O_OBJS += bf-i386.o +O_TARGET = cip$(VERSC)b.o +endif +else +ifeq ($(CONFIG_CIPE_IDEA),y) +O_OBJS += idea0.o +O_TARGET = cip$(VERSC)i.o +endif +endif + +EXTRA_CFLAGS = $(CFG) $(DEFS) +EXTRA_ASFLAGS = $(CFG) $(DEFS) + +version.h: Makefile crcgen + ./crcgen "$(VERSION)$(CRYPTO)$(CONFIG_CIPE_VERSION)$(DEFS)" >$@ + +crcgen: crc32.o crcgen.o + $(CC) $(LDFLAGS) -o crcgen crc32.o crcgen.o + +device.o: version.h + +%.o: %.S + $(CC) $(ASFLAGS) $(EXTRA_ASFLAGS) -c -o $@ $< + +include $(TOPDIR)/Rules.make diff -ruN linux-2.2.5,pristine/net/cipe/Makefile.cipe linux-2.2.5/net/cipe/Makefile.cipe --- linux-2.2.5,pristine/net/cipe/Makefile.cipe Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/Makefile.cipe Thu Apr 1 23:05:46 1999 @@ -0,0 +1,201 @@ +#! gnumake -f +# Makefile for the CIPE kernel module and driver. + +# Copyright 1996 Olaf Titz <olaf@bigred.inka.de> +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version +# 2 of the License, or (at your option) any later version. + +# $Id: Makefile,v 1.24 1998/11/14 20:48:02 olaf Exp $ + +# Targets: all install dvi clean + +### Config: which crypto algorithm and version +# Change these parameters here instead of on the make command line! + +# Select one of these algorithms +CRYPTO= Blowfish +#CRYPTO=IDEA +# Don't use any older version except for compatibility +VERS= 3 +# Which assembler module(s) to use +ASM= i386 +#ASM= +# Options +DEFS= -DDEBUG -DLOGFAC=LOG_DAEMON # -DNO_DYNDEV + +### The usual compiler, etc. definitions + +CC= gcc -pipe +# The kernel part needs -O due to inline code +OPT= -O3 +INCS= +# Where the _running_ kernel's includes are - no -I here +KINC= /usr/src/linux/include +KDEFS= -D__KERNEL__ -DMODULE -I$(KINC) +LDFLAGS=-s +LDRFLAGS=-r -S + +# Define SMP or MODVERSIONS if and only if your kernel is also compiled +# with these options +#SMP=1 +MODVERSIONS=1 + +BINDIR= /usr/local/sbin +MODDIR= /lib/modules/`uname -r`/misc +INFODIR=/usr/local/info + +#TEX= tex +TEX= texinfo + +### No user-serviceable parts below here + +VERSION=1.2.0 +CFG=-DProtocolVersion=$(VERS) -DCrypto_$(CRYPTO) -DVERSION=\"$(VERSION)\" +CFLAGS= $(OPT) $(DEFS) $(ADEFS) $(CFG) -Wall -Wstrict-prototypes \ + -fomit-frame-pointer -finline-functions -funroll-loops + +ifdef ASM +ifeq "$(strip $(CRYPTO))" "IDEA" +ADEFS=-DASM_Idea_Crypt +AOBJS=idea-$(strip $(ASM)).o +endif +ifeq "$(strip $(CRYPTO))" "Blowfish" +ADEFS=-DASM_BF_Crypt +AOBJS=bf-$(strip $(ASM)).o +endif +endif + +ifeq "$(strip $(VERS))" "1" +VERSC=a +endif +ifeq "$(strip $(VERS))" "2" +VERSC=b +endif +ifeq "$(strip $(VERS))" "3" +VERSC=c +endif + +ifeq "$(strip $(CRYPTO))" "IDEA" +CIPEM=cip$(VERSC)i.o +endif +ifeq "$(strip $(CRYPTO))" "Blowfish" +CIPEM=cip$(VERSC)b.o +endif + +ifdef SMP +KDEFS+=-D__SMP__ +endif +ifdef MODVERSIONS +KDEFS+=-DMODVERSIONS -include $(KINC)/linux/modversions.h +endif + +all: $(CIPEM) ciped + +install: all + -mkdir -p $(MODDIR) $(BINDIR) $(INFODIR) + install -m 644 $(CIPEM) $(MODDIR) + install -m 755 ciped $(BINDIR) + install -m 644 cipe.info* $(INFODIR) + -depmod -a + +KOBJS= module.o device.o sock.o output.o encaps.o +ifeq "$(strip $(CRYPTO))" "IDEA" +KOBJS+=idea0.o +endif +ifeq "$(strip $(CRYPTO))" "Blowfish" +ifndef ASM +KOBJS+=blowfish.o +endif +endif +ifeq "$(strip $(VERS))" "3" +COBJS= crc32.o +else +COBJS= crc.o +endif +OBJS= ciped.o ioctl.o socks5.o +SOBJS= crcgen.o + +SRCS= cipe.h crypto.h \ + ciped.c ciped.h ioctl.c ioctl.h socks5.c \ + module.c device.c sock.c output.c encaps.c \ + idea0.h idea0.c bf.h crc.c crc32.c crcgen.c \ + idea-i386.S bf-i386.S \ + thruput.c Makefile cipe.lsm +SMPL= samples/README samples/options samples/ip-up samples/ip-down +DIST= README CHANGES $(SRCS) $(SMPL) cipe.info tcpdump.patch COPYING + +TEXAUX=cipe.cp cipe.fn cipe.ky cipe.pg cipe.tp cipe.vr + +$(CIPEM): $(KOBJS) $(COBJS) $(AOBJS) + ld $(LDRFLAGS) -o $(CIPEM) $(KOBJS) $(COBJS) $(AOBJS) + +ciped: $(OBJS) $(COBJS) + $(CC) $(LDFLAGS) -o ciped $(OBJS) $(COBJS) + +$(AOBJS): %.o: %.S + $(CC) $(DEFS) $(ADEFS) $(KDEFS) -o $@ -c $< + +$(KOBJS): %.o: %.c + $(CC) $(CFLAGS) $(KINCS) $(KDEFS) -o $@ -c $< + +$(OBJS) $(COBJS) $(SOBJS): %.o: %.c + $(CC) $(CFLAGS) $(INCS) -o $@ -c $< + +$(KOBJS:.o=.s) $(COBJS:.o=.s): %.s: %.c + $(CC) $(CFLAGS) $(KINCS) $(KDEFS) -fverbose-asm \ + -o $@ -S $< + +version.h: Makefile crcgen + ./crcgen "$(VERSION)$(CRYPTO)$(VERS)$(DEFS)" >$@ + +crcgen: crc32.o crcgen.o + $(CC) $(LDFLAGS) -o crcgen crc32.o crcgen.o + +dvi: cipe.dvi + +$(TEXAUX): cipe.texinfo + $(TEX) cipe.texinfo + +cipe.dvi: cipe.cp + texindex $(TEXAUX) + $(TEX) cipe.texinfo + +thruput: thruput.c + gcc -Wall -O3 -s -o thruput thruput.c + +Checksums: $(DIST) + makechecksums $(DIST) > Checksums + +tgz: $(DIST) Checksums + cd .. && ln -sf cipe-linux cipe-$(VERSION) && \ + tar czf cipe-$(VERSION).tar.gz \ + $(DIST:%=cipe-$(VERSION)/%) cipe-$(VERSION)/Checksums + +clean: + rm -f core *.out *.tmp *.o *.s version.h crcgen ciped thruput + +realclean: clean + rm -f *~ *.bak *.dvi *.aux *.log *.toc *.html $(TEXAUX) $(TEXAUX:%=%s) + +# make depend does not account for everything included by crypto.h +depend: clean + sed -e '/^\#\#\# Dependencies/q' Makefile > Make.tmp + gcc -E -MM $(KINCS) $(KDEFS) $(CFG) $(KOBJS:.o=.c) >> Make.tmp + gcc -E -MM $(INCS) $(CFG) $(OBJS:.o=.c) $(COBJS:.o=.c) >> Make.tmp + mv -f Makefile Makefile~~ + mv -f Make.tmp Makefile + +### Dependencies +module.o: module.c cipe.h crypto.h +device.o: device.c cipe.h crypto.h idea0.h bf.h version.h +sock.o: sock.c cipe.h crypto.h idea0.h bf.h +output.o: output.c cipe.h crypto.h idea0.h bf.h +encaps.o: encaps.c cipe.h crypto.h idea0.h bf.h +ciped.o: ciped.c ciped.h cipe.h crypto.h idea0.h bf.h ioctl.h +ioctl.o: ioctl.c cipe.h crypto.h idea0.h bf.h ioctl.h version.h +socks5.o: socks5.c ciped.h cipe.h crypto.h idea0.h bf.h +crc.o: crc.c +crc32.o: crc32.c diff -ruN linux-2.2.5,pristine/net/cipe/README linux-2.2.5/net/cipe/README --- linux-2.2.5,pristine/net/cipe/README Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/README Thu Apr 1 23:05:46 1999 @@ -0,0 +1,21 @@ + CIPE - encrypted IP over UDP tunneling + Copyright 1996-1997 Olaf Titz <olaf@bigred.inka.de> + + Version 0.5 + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. + +Documentation for this package is in the file "cipe.info", to be read +with Emacs or the "info" program. + +The newest version of CIPE is available on + http://www.inka.de/~bigred/devel/cipe.html + or ftp://ftp.inka.de/sites/bigred/cipe.html +(always just an index page). +In case you want a hardcopy printout of the manual, you can also get +the Texinfo source for the manual there. + +$Id: README,v 1.7 1997/09/18 22:49:22 olaf Exp $ diff -ruN linux-2.2.5,pristine/net/cipe/bf-i386.S linux-2.2.5/net/cipe/bf-i386.S --- linux-2.2.5,pristine/net/cipe/bf-i386.S Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/bf-i386.S Thu Apr 1 23:05:46 1999 @@ -0,0 +1,492 @@ +/* + Bruce Schneier's Blowfish in i386 assembler (for linux/gcc) + Author: Olaf Titz <olaf@bigred.inka.de> + + This code is in the public domain. + + $Id: bf-i386.S,v 1.2 1997/03/31 22:00:06 olaf Exp $ +*/ + +#ifdef ASM_BF_Crypt + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif +#include <linux/linkage.h> +/* this header just defines ENTRY to make an appropriate global symbol */ + +#define PosP0 0 +#define PosP17 68 +#define PosS0 72 +#define PosS1 1096 +#define PosS2 2120 +#define PosS3 3144 +#define KeyLenL 1042 +#define KeyLenB 521 + +/* This code is optimized for speed rather than size - loops unrolled. etc. */ + +/* + Endian-ness is taken care of by (a) the order of shifts in the Round + macro and (b) the order of shifts below under the ukx label. + The key tables and user data are stored and processed in the CPU + byte order. +*/ + +/* Do one round */ +#define Round(lw,rw) \ + movl rw, %edx; \ + shrl $24, %edx; \ + movl PosS0(%edi,%edx,4), %eax; \ + movl rw, %edx; \ + shrl $16, %edx; \ + andl $0xFF, %edx; \ + addl PosS1(%edi,%edx,4), %eax; \ + movl rw, %edx; \ + shrl $8, %edx; \ + andl $0xFF, %edx; \ + xorl PosS2(%edi,%edx,4), %eax; \ + movl rw, %edx; \ + andl $0xFF, %edx; \ + addl PosS3(%edi,%edx,4), %eax; \ + xorl %eax, lw; \ + lodsl; \ + xorl %eax, lw + +/* Words in %ebx, %ecx - Key in %edi - P-index in %esi - result swapped */ +blowfish: + lodsl + xorl %eax, %ebx + Round(%ecx,%ebx); Round(%ebx,%ecx) + Round(%ecx,%ebx); Round(%ebx,%ecx) + Round(%ecx,%ebx); Round(%ebx,%ecx) + Round(%ecx,%ebx); Round(%ebx,%ecx) + Round(%ecx,%ebx); Round(%ebx,%ecx) + Round(%ecx,%ebx); Round(%ebx,%ecx) + Round(%ecx,%ebx); Round(%ebx,%ecx) + Round(%ecx,%ebx); Round(%ebx,%ecx) + lodsl + xorl %eax, %ecx + ret + +/* + void Blowfish_Encrypt(Blowfish_Data dataIn, Blowfish_Data dataOut, + Blowfish_Key key); +*/ + +ENTRY(Blowfish_Encrypt) + pushl %ebx + pushl %ebp + pushl %esi + pushl %edi +#define SAVE 16 /* no. of bytes the saved registers occupy */ +/* arguments relative to %esp */ +#define dataIn SAVE+4 +#define dataOut SAVE+8 +#define key SAVE+12 + + movl dataIn(%esp), %esi + movl (%esi), %ebx + movl 4(%esi), %ecx + movl key(%esp), %edi + movl %edi, %esi + cld + call blowfish + movl dataOut(%esp), %edi + movl %ebx, 4(%edi) + movl %ecx, (%edi) + popl %edi + popl %esi + popl %ebp + popl %ebx + ret +#undef dataIn +#undef dataOut +#undef key + +/* + void Blowfish_Decrypt(Blowfish_Data dataIn, Blowfish_Data dataOut, + Blowfish_Key key); +*/ + +ENTRY(Blowfish_Decrypt) + pushl %ebx + pushl %ebp + pushl %esi + pushl %edi +#define SAVE 16 /* no. of bytes the saved registers occupy */ +/* arguments relative to %esp */ +#define dataIn SAVE+4 +#define dataOut SAVE+8 +#define key SAVE+12 + + movl dataIn(%esp), %esi + movl (%esi), %ebx + movl 4(%esi), %ecx + movl key(%esp), %edi + movl %edi, %esi + leal PosP17(%edi), %esi + std + call blowfish + movl dataOut(%esp), %edi + movl %ebx, 4(%edi) + movl %ecx, (%edi) + popl %edi + popl %esi + popl %ebp + popl %ebx + ret +#undef dataIn +#undef dataOut +#undef key + +/* load byte from key, start over if exhausted */ +#define lodsbw(base,len) \ + lodsb; \ + decl %ecx; \ + cmpl $0, %ecx; \ + jg 1f; \ + movl base, %esi; \ + movl len, %ecx; \ +1: + +/* + void Blowfish_ExpandUserKey(Blowfish_UserKey userKey, int userKeyLen, + Blowfish_Key key); +*/ + +ENTRY(Blowfish_ExpandUserKey) + pushl %ebx + pushl %ebp + pushl %esi + pushl %edi +#define SAVE 16 /* no. of bytes the saved registers occupy */ +/* arguments relative to %esp */ +#define userKey SAVE+4 +#define userKeyLen SAVE+8 +#define key SAVE+12 + + /* Copy the init vector into key */ + leal bftab0, %esi + movl key(%esp), %edi + movl $KeyLenL, %ecx + cld + rep; movsl + /* XOR the user key into the P table */ + movl key(%esp), %edi + movl $18, %ebp + movl userKey(%esp), %esi + movl userKeyLen(%esp), %ecx +ukx: + /* process one 32-bit word swapped */ + lodsbw(userKey(%esp), userKeyLen(%esp)) + shll $8, %eax + lodsbw(userKey(%esp), userKeyLen(%esp)) + shll $8, %eax + lodsbw(userKey(%esp), userKeyLen(%esp)) + shll $8, %eax + lodsbw(userKey(%esp), userKeyLen(%esp)) + xorl %eax, (%edi) + addl $4, %edi + decl %ebp + cmpl $0, %ebp + jg ukx + + /* Now do the repeated encryption process */ + xorl %ebx, %ebx + xorl %ecx, %ecx + movl $KeyLenB, %ebp + movl key(%esp), %edi +ukb: + pushl %edi + movl key+4(%esp), %edi + movl %edi, %esi + call blowfish + popl %edi + xchgl %ebx, %ecx + movl %ebx, (%edi) + movl %ecx, 4(%edi) + addl $8, %edi + decl %ebp + cmpl $0, %ebp + jg ukb + + popl %edi + popl %esi + popl %ebp + popl %ebx + ret +#undef dataIn +#undef dataOut +#undef key + +/* The initialization key. According to Schneier, this is not a magic + pattern but simply the first 33344 (after point) bits of "pi". */ + +.align 4 +bftab0: +/* The eighteen P boxes @ 1 word */ +.long 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344 +.long 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89 +.long 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c +.long 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917 +.long 0x9216d5d9, 0x8979fb1b +/* The four S boxes @ 256 words */ +.long 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7 +.long 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99 +.long 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16 +.long 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e +.long 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee +.long 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013 +.long 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef +.long 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e +.long 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60 +.long 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440 +.long 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce +.long 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a +.long 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e +.long 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677 +.long 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193 +.long 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032 +.long 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88 +.long 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239 +.long 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e +.long 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0 +.long 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3 +.long 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98 +.long 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88 +.long 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe +.long 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6 +.long 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d +.long 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b +.long 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7 +.long 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba +.long 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463 +.long 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f +.long 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09 +.long 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3 +.long 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb +.long 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279 +.long 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8 +.long 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab +.long 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82 +.long 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db +.long 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573 +.long 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0 +.long 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b +.long 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790 +.long 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8 +.long 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4 +.long 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0 +.long 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7 +.long 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c +.long 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad +.long 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1 +.long 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299 +.long 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9 +.long 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477 +.long 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf +.long 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49 +.long 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af +.long 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa +.long 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5 +.long 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41 +.long 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915 +.long 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400 +.long 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915 +.long 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664 +.long 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a +.long 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623 +.long 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266 +.long 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1 +.long 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e +.long 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6 +.long 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1 +.long 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e +.long 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1 +.long 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737 +.long 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8 +.long 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff +.long 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd +.long 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701 +.long 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7 +.long 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41 +.long 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331 +.long 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf +.long 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af +.long 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e +.long 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87 +.long 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c +.long 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2 +.long 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16 +.long 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd +.long 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b +.long 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509 +.long 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e +.long 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3 +.long 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f +.long 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a +.long 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4 +.long 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960 +.long 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66 +.long 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28 +.long 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802 +.long 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84 +.long 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510 +.long 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf +.long 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14 +.long 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e +.long 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50 +.long 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7 +.long 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8 +.long 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281 +.long 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99 +.long 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696 +.long 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128 +.long 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73 +.long 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0 +.long 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0 +.long 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105 +.long 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250 +.long 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3 +.long 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285 +.long 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00 +.long 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061 +.long 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb +.long 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e +.long 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735 +.long 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc +.long 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9 +.long 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340 +.long 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20 +.long 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 +.long 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934 +.long 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068 +.long 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af +.long 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840 +.long 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45 +.long 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504 +.long 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a +.long 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb +.long 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee +.long 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6 +.long 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42 +.long 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b +.long 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2 +.long 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb +.long 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527 +.long 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b +.long 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33 +.long 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c +.long 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3 +.long 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc +.long 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17 +.long 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564 +.long 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b +.long 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115 +.long 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922 +.long 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728 +.long 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0 +.long 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e +.long 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37 +.long 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d +.long 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804 +.long 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b +.long 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3 +.long 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb +.long 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d +.long 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c +.long 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350 +.long 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9 +.long 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a +.long 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe +.long 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d +.long 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc +.long 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f +.long 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61 +.long 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2 +.long 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9 +.long 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2 +.long 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c +.long 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e +.long 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633 +.long 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10 +.long 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169 +.long 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52 +.long 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027 +.long 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5 +.long 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62 +.long 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634 +.long 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76 +.long 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24 +.long 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc +.long 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4 +.long 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c +.long 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837 +.long 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 +.long 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b +.long 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe +.long 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b +.long 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4 +.long 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8 +.long 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6 +.long 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304 +.long 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22 +.long 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4 +.long 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6 +.long 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9 +.long 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59 +.long 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593 +.long 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51 +.long 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28 +.long 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c +.long 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b +.long 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28 +.long 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c +.long 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd +.long 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a +.long 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319 +.long 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb +.long 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f +.long 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991 +.long 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32 +.long 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680 +.long 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166 +.long 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae +.long 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb +.long 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5 +.long 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47 +.long 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370 +.long 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d +.long 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84 +.long 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048 +.long 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8 +.long 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd +.long 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9 +.long 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7 +.long 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38 +.long 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f +.long 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c +.long 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525 +.long 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1 +.long 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442 +.long 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964 +.long 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e +.long 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8 +.long 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d +.long 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f +.long 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299 +.long 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02 +.long 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc +.long 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614 +.long 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a +.long 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6 +.long 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b +.long 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0 +.long 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060 +.long 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e +.long 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9 +.long 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f +.long 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 + +#endif /* ASM_BF_Crypt */ diff -ruN linux-2.2.5,pristine/net/cipe/bf.h linux-2.2.5/net/cipe/bf.h --- linux-2.2.5,pristine/net/cipe/bf.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/bf.h Thu Apr 1 23:05:46 1999 @@ -0,0 +1,20 @@ + +/* The data block processed by the encryption algorithm - 64 bits */ +typedef unsigned long Blowfish_Data[2]; +/* The key as entered by the user - size may vary */ +typedef char Blowfish_UserKey[16]; +/* The expanded key for internal use - 18+4*256 words*/ +typedef unsigned long Blowfish_Key[1042]; + +#ifdef Strict_Type_Check +extern void Blowfish_Encrypt(Blowfish_Data dataIn, Blowfish_Data dataOut, + Blowfish_Key key); +extern void Blowfish_Decrypt(Blowfish_Data dataIn, Blowfish_Data dataOut, + Blowfish_Key key); +extern void Blowfish_ExpandUserKey(Blowfish_UserKey userKey, int userKeyLen, + Blowfish_Key key); +#else +extern void Blowfish_Encrypt(void *dataIn, void *dataOut, void *key); +extern void Blowfish_Decrypt(void *dataIn, void *dataOut, void *key); +extern void Blowfish_ExpandUserKey(void *userKey, int userKeyLen, void *key); +#endif diff -ruN linux-2.2.5,pristine/net/cipe/cipe.h linux-2.2.5/net/cipe/cipe.h --- linux-2.2.5,pristine/net/cipe/cipe.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/cipe.h Thu Apr 1 23:05:46 1999 @@ -0,0 +1,292 @@ +/* + CIPE - encrypted IP over UDP tunneling + + cipe.h - contains definitions, includes etc. common to all modules + + Copyright 1996 Olaf Titz <olaf@bigred.inka.de> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. +*/ +/* $Id: cipe.h,v 1.18 1998/11/14 20:48:02 olaf Exp $ */ + +#ifndef _CIPE_H_ +#define _CIPE_H_ + +#include "crypto.h" + + +/*** The kernel/user IOCTL interface ***/ + +/* ioctls for setup and key exchange */ +/* #define SIOCxIFCIPxxx (SIOCDEVPRIVATE+x) */ +/* All ioctls are passed a struct ifreq <net/if.h> which contains the + device name in ifr_name and a pointer to the actual control struct + in ifr_data. */ + +/* Get interface parameters. */ +#define SIOCGIFCIPPAR (SIOCDEVPRIVATE+0) +struct siocgifcippar { + unsigned long magic; + /* SOCKS5 relayer */ + unsigned long sockshost; + unsigned short socksport; + /* Timeouts (in seconds) */ + int tmo_keyxchg; + int tmo_keylife; + /* Flags */ + int mayclear; + int cttl; +}; + +/* Set interface parameters. */ +#define SIOCSIFCIPPAR (SIOCDEVPRIVATE+1) +struct siocsifcippar { + unsigned long magic; + /* SOCKS5 relayer */ + unsigned long sockshost; + unsigned short socksport; + /* Timeouts (in seconds) */ + int tmo_keyxchg; + int tmo_keylife; + /* Flags */ + int mayclear; + int cttl; +}; + +/* Set a key. */ +#define SIOCSIFCIPKEY (SIOCDEVPRIVATE+2) +#define KEY_STATIC 1 +#define KEY_SEND 2 +#define KEY_RECV 3 +#define KEY_INVAL 8 +struct siocsifcipkey { + unsigned long magic; + int which; + UserKey thekey; +}; + +/* Attach a socket. */ +#define SIOCSIFCIPATT (SIOCDEVPRIVATE+3) +struct siocsifcipatt { + unsigned long magic; + int fd; +}; + +/* Allocate/deallocate a device. */ +#define SIOCSIFCIPALL (SIOCDEVPRIVATE+4) +#define SIOCSIFCIPUNA (SIOCDEVPRIVATE+5) +struct siocsifcipall { + unsigned long magic; + int num; + char name[16]; +}; + + +/*** Key exchange related definitions ***/ + +/* Minimum kxc block. */ +#define KEYXCHGBLKMIN 64 +/* Maximum kxc block, padded with random bytes */ +#define KEYXCHGBLKMAX (KEYXCHGBLKMIN+256) +/* Position of the timestamp */ +#define KEYXCHGTSPOS 56 +/* Type words. Only 4 are possible. */ +#define TW_DATA 0 +#define TW_NEWKEY 2 +#define TW_CTRL 4 +#define TW_RSVD2 6 +/* error indication, no valid type word */ +#define TW_ERROR 1 + +/* NEWKEY (key exchange mode 1) subtypes. */ +#define NK_RREQ 0 /* not used in protocol */ +#define NK_REQ 1 /* send me your new key */ +#define NK_IND 2 /* this is my new key */ +#define NK_ACK 3 /* i have your new key */ + + +/*** Kernel-module internal stuff ***/ + +#ifdef __KERNEL__ + +#include <asm/byteorder.h> +#include <linux/types.h> +#include <linux/netdevice.h> +#include <linux/sockios.h> +#include <linux/sched.h> +#include <linux/if_ether.h> +#include <linux/net.h> +#include <linux/ip.h> +#include <linux/udp.h> +#include <net/sock.h> +#include <linux/version.h> +#ifndef KERNEL_VERSION +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) +#define LINUX_21 +#endif + + +/* The header we add to each packet */ +#ifdef VER_SHORT +#define cipehdrlen (sizeof(struct iphdr)+sizeof(struct udphdr)) +#else +#define cipehdrlen (sizeof(struct iphdr)+sizeof(struct udphdr)+blockSize) +#endif +/* ...plus a real hardware header (common case) */ +#define cipexhdrl (cipehdrlen+((ETH_HLEN+15)&~15)) +/* max. padding at the end */ +#if ProtocolVersion == 3 +#define cipefootlen 12 /* 7 bytes pad, 1 byte type, 4 bytes CRC */ +#else +#define cipefootlen 10 /* 8 bytes pad, 2 bytes CRC */ +#endif + +/* A CIPE device's parameter block */ + +#define CIPE_MAGIC (htonl(0x43495045)) +struct cipe { + __u32 magic; + struct device *dev; + /* Set by user process */ + __u32 peeraddr; + __u32 myaddr; + __u16 peerport; + __u16 myport; + __u32 sockshost; + __u16 socksport; + short cttl; +#ifdef Crypto_IDEA + Key key_e, key_d, skey_e, rkey_d; +#endif +#ifdef Crypto_Blowfish + Key key, skey, rkey; + #define key_e key + #define key_d key + #define skey_e skey + #define rkey_d rkey +#endif + unsigned long tmo_keyxchg; + unsigned long tmo_keylife; + /* Internal */ + unsigned long timekx; + unsigned long timeskey; + unsigned long timerkey; + int cntskey; + int cntrkey; + struct sock *sock; + /* Flags */ + char mayclear; + char havekey; + char haveskey; + char haverkey; +#ifdef LINUX_21 + char recursion; +#endif + pid_t owner; + /* Statistics */ +#ifdef LINUX_21 + struct net_device_stats stat; +#else + struct enet_statistics stat; +#endif + /* Socket interface stuff */ + struct proto *udp_prot; + struct proto cipe_proto; +}; + +#define MAXBLKS 32767 /* max # blocks to encrypt using one key */ + +/* Define, init and check a struct cipe * variable. */ +#define DEVTOCIPE(dev,c,err) \ + struct cipe *c = (struct cipe*)(dev->priv); \ + if (!c || c->magic!=CIPE_MAGIC) return err; + +/* Master control struct */ +struct cipe_ctrl { + char name[16]; + struct cipe cipe; + struct device dev; +}; + +extern struct cipe_ctrl **cipe_ctrls; +extern int cipe_maxdev; + +/* SOCKS5 encapsulation header */ +struct sockshdr { + char rsv[2]; + char frag; + char atyp; + __u32 dstaddr __attribute__((packed)); + __u16 dstport __attribute__((packed)); +}; + +#ifdef DEBUG +extern int cipe_debug; +#define DEB_CALL 1 +#define DEB_INP 2 +#define DEB_OUT 4 +#define DEB_CRYPT 8 +#define DEB_KXC 16 +#define DEB_PKIN 32 +#define DEB_PKOU 32 +#define dprintk(l,p) if(cipe_debug&l){printk p;} +#define dprintk1(l,s,f,a) if(cipe_debug&l){printk(s f,a);} +#define dprintk2(l,s,f,a,b) if(cipe_debug&l){printk(s f,a,b);} +#define dprintk3(l,s,f,a,b,c) if(cipe_debug&l){printk(s f,a,b,c);} +#define dprintk4(l,s,f,a,b,c,d) if(cipe_debug&l){printk(s f,a,b,c,d);} +#define dprintk5(l,s,f,a,b,c,d,e) if(cipe_debug&l){printk(s f,a,b,c,d,e);} +#else +#define dprintk(l,p) +#define dprintk1(l,s,f,a) +#define dprintk2(l,s,f,a,b) +#define dprintk3(l,s,f,a,b,c) +#define dprintk4(l,s,f,a,b,c,d) +#define dprintk5(l,s,f,a,b,c,d,e) +#endif /* DEBUG */ + +/* internal routines */ +/* module.c */ +extern void cipe_use_module(void); +extern void cipe_unuse_module(void); +/* device.c */ +extern void cipe_prnpad(unsigned char *buf, int len); +extern void cipe_close(struct cipe *c); +/* sock.c */ +extern int cipe_attach(struct device *dev, struct siocsifcipatt *parm); +void cipe_fakenkey(struct cipe *c, char typ); +/* output.c */ +#ifdef DEBUG +void cipe_dump_packet(char *title, struct sk_buff *skb); +#endif +extern int cipe_xmit(struct sk_buff *skb, struct device *dev); +/* encaps.c */ +extern void cipe_encrypt(struct cipe *c, unsigned char *buf, + int *len, int typcode); +extern unsigned short cipe_decrypt(struct cipe *c, unsigned char *buf, + int *len); +#ifndef VER_SHORT +void cipe_cryptpad(unsigned char *buf); +#endif + +#endif /* __KERNEL__ */ + +#ifdef VER_CRC32 +/* crc32.c */ +extern unsigned long crc32(const unsigned char *s, unsigned int len); +#else +/* crc.c */ +extern unsigned short block_crc(unsigned char *d, int len); +#endif + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +#ifndef DEVNAME +#define DEVNAME "cip" VERNAME CRNAME +#endif + +#endif _CIPE_H_ diff -ruN linux-2.2.5,pristine/net/cipe/cipe.info linux-2.2.5/net/cipe/cipe.info --- linux-2.2.5,pristine/net/cipe/cipe.info Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/cipe.info Thu Apr 1 23:05:46 1999 @@ -0,0 +1,1049 @@ +This is Info file cipe.info, produced by Makeinfo version 1.68 from the +input file cipe.texinfo. + + +File: cipe.info, Node: Top, Next: Introduction, Prev: (dir), Up: (dir) + +CIPE +**** + +CIPE (the name is shortened from *Crypto IP Encapsulation*) is a +package for an encrypting IP tunnel device. This can be used to build +encrypting routers for VPN (Virtual Private Networks) and similar +applications. + + Copyright (C) 1996--1998 Olaf Titz. All rights reserved. + + This program including its documentation is free software; you can + redistribute it and/or modify it under the terms of the GNU General + Public License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + The author can be contacted through the electronic mail address + <Olaf.Titz@inka.de>. + +* Menu: + +* Introduction:: About routing, VPNs and encryption. +* Installation:: Installing the CIPE software package. +* Configuration:: Configuration. +* Examples:: Examples of CIPE configurations. +* Protocol:: Description of the protocol used. +* Misc:: Odds and ends. +* Concept Index:: Index. + +`$Id: cipe.texinfo,v 1.6 1998/10/18 15:38:41 olaf Exp $' + + +File: cipe.info, Node: Introduction, Next: Installation, Prev: Top, Up: Top + +Introduction +************ + +* Menu: + +* Network layers:: Where encryption takes place. +* Routing:: About IP routing and VPNs. +* How CIPE works:: The encapsulation method employed here. +* Components:: Which pieces of software CIPE consists of. +* Internals:: A look under the hood of CIPE. + + +File: cipe.info, Node: Network layers, Next: Routing, Prev: Introduction, Up: Introduction + +Network layers and encryption +============================= + +There are several different places where encryption can be built into +an existing network infrastructure, corresponding to the different +protocol layers: + + 1. On the "network level": Packets travelling between hosts on the + network are encrypted. The encryption engine is placed near the + driver which sends and receives packets. An implementation is + found in CIPE. + + 2. On the "socket level": A logical connection between programs + running on different hosts (TCP connection; transport or session + layer in OSI) is encrypted. The encryption engine intercepts or + proxies connections. SSH works this way. + + 3. On the "application level": Applications contain their own + encryption engine and encrypt data themselves. The best known + example is PGP for encrypting mail. + +Low-level encryption as implemented with CIPE has the advantage that it +can be made to work transparently, without any change to application +software. In the case of encrypting IP packets, it can be built into IP +routers which usually act as "black boxes" that only route traffic +between hosts, the hosts themselves don't see at all how the routing +works. So an "encrypting router" looks exactly like a non-encrypting +one, without any difference to other hosts and applications. It can +thus be used in places where software changes at higher levels are not +feasible. + +Low-level encryption has the disadvantage that it does not guard against +intruders on a higher level, e.g. Trojaned applications, bug exploits +in system software or rogue administrators "sniffing" on terminal +devices. + + +File: cipe.info, Node: Routing, Next: How CIPE works, Prev: Network layers, Up: Introduction + +IP routing and Virtual Private Networks +======================================= + +A "virtual private network" (VPN for short) is a network (1) belonging +to one organization, using its own address range, but overlayed on +existing network infrastructure. "IP-in-IP tunneling" makes it +possible to build IP-based VPNs on top of other IP-based "carrier +networks", such as the Internet. "Encrypted tunneling" guards against +passive (sniffing) and active (faked message injection) attacks on the +carrier network. The carrier network sees only encrypted data. + +Depending on the choice of protocol, all information the original +packets carry can be encrypted. This includes not only the actual +(payload) data but also the TCP/IP headers, leaving no trace as to +which addresses and services are actually used. "Traffic analysis" +attacks, which attempt to gain useful information out of sniffing by +"who contacts whom", are thus made unfeasible. An even more +sophisticated technique to thwart traffic analysis employs the +injection of dummy packets into the network which carry no useful +information at all but are (at the carrier level) indistinguishable +from real data packets. + +IP routing in a VPN situation consists of the routing of the carrier +network, which in most situations is just a standard Internet setup, +and routing of the overlayed VPN. This is easiest when the address +ranges of carrier and VPN do not overlap in any way. It is common for +VPNs to use the 10.0.0.0/8 and 192.168.0.0/16 address ranges, which are +not part of the Internet and thus do never conflict with actual +Internet routing: any address in this range must be local to the +organization using it. *Note Example 1::, for a typical example. + +The IPSEC standards define a set of protocols which can be used (among +other things) to build encrypted VPNs. However, IPSEC is a rather +heavyweight and complicated protocol set with a lot of options, +implementations of the full protocol set are still rarely used and some +issues (such as key management) are still not fully resolved. CIPE +uses a simpler approach, in which many things which can be +parameterized (such as the choice of the actual encryption algorithm +used) are an install-time fixed choice. This limits flexibility but +allows for a simple (and therefore efficient, easy to debug...) +implementation. + +---------- Footnotes ---------- + +(1) As CIPE is an IP routing application, this manual talks only about +IP-based networks. + + +File: cipe.info, Node: How CIPE works, Next: Components, Prev: Routing, Up: Introduction + +How CIPE works +============== + +CIPE encapsulates encrypted IP datagrams in UDP datagrams and sends +them via the normal UDP mechanism. This is different from standard +IPIP encapsulation. UDP was chosen because this way many different +endpoints can easily be distinguished by port numbers, because an IP +protocol number would warrant a formal registration, and because +handling of UDP datagrams is easier than using a separate IP protocol +number, especially in firewalled setups. Specifically, UDP can be +handled by user-level applications such as a SOCKS5 relayer. *Note +SOCKS::. + +A CIPE "link" always connects exactly two endpoints. In many ways, the +link works like a PPP dial-up link. At present, each link has its own +secret 128-bit key which has to be known by both ends (and nobody +else). This "link key" (called "static key" in the protocol +description) is used to negotiate a frequently changed "dynamic key", +which encrypts the actual data. + +It is planned that future versions of CIPE will negotiate their keys +via a "public key" mechanism, similar to the SSH package. This would +remove the need for shared secret keys. + + +File: cipe.info, Node: Components, Next: Internals, Prev: How CIPE works, Up: Introduction + +CIPEs software components +========================= + +The CIPE package consists of a kernel module and a driver program. The +kernel module does the IP packet handling: sending and receiving +packets, encapsulation including encryption. It implements a "network +device" which is mostly handled like any other network device. +Configuration and the whole key exchange process is done by the user +level program `ciped'. + +`ciped' looks and behaves rather similar to `pppd'. In particular, +opening and closing a CIPE device is tied to starting and ending a +`ciped' process (one per device), the specification of options to the +daemon mimics `pppd''s setup and `ciped' invokes scripts on opening and +closing a device. + + +File: cipe.info, Node: Internals, Prev: Components, Up: Introduction + +Notes on internals +================== + +(This section is only relevant to readers who want to understand the +source, not to the regular user.) + +The module consists of an output driver, an input driver, the +encapsulation routines and some stuff to keep it all together. The +output driver is largely an adapted version of `new_tunnel' from the +Linux distribution. Its actual packet sending is done via the kernel IP +forwarding engine. This implies that (a) forwarding must be enabled in +the kernel and (b) the encrypted packets, being UDP packets with the +source/dest addresses given as "me" and "peer", are checked against the +forwarding (as well as the output) firewall. (If it doesn't work for +you, first make sure that your firewall rules let the packets pass!) + +The input driver is an adaptation from the kernel UDP receiver. To +activate it, ciped has to set a socket into a special mode with an +`ioctl' call. This has to be a connected UDP socket. The +`ioctl_attach(2cipe)' call replaces the socket's `sendto(2)' and +`recvfrom(2)' operations with special versions that do decryption of +traffic internally and only pass key exchange blocks to the user layer. +The whole work of decrypting and rerouting incoming traffic is done +inside a blocking `recvfrom(2)'. This means that unlike normal IP +forwarding, it is called from user mode and the needed CPU time is +charged to the ciped process, although the data never passes into user +mode. `sendto(2)' encodes the block as a key exchange block and sends +it to the peer. The socket should not use `read(2)', `write(2)', +`select(2)' or nonblocking mode (yet). + +Before attaching the socket, the operational parameters of the device +have to be set using a `ioctl_setpar(2cipe)' call. The key exchange +process supplies keys to the kernel via `ioctl_setkey(2cipe)'. + +The netdevice can only be opened (configured "UP") if it has a +controlling socket. When the controlling socket is closed, the netdevice +gets closed. Conversely, closing the netdevice (with `ifconfig(8)') +closes the socket too. Closing deletes all information that is set by +ciped, but not the statistics which still can be read from +`/proc/net/dev' (which means they accumulate over consecutive ciped +runs). + + +File: cipe.info, Node: Installation, Next: Configuration, Prev: Introduction, Up: Top + +Installing the CIPE software package +************************************ + +The CIPE software package is available via +`http://www.inka.de/~bigred/devel/cipe.html'. It is distributed in a +`tar.gz' file, currently about 65k in size. After unpacking the +distribution, set the necessary parameters at the top of the Makefile +and run `make'. + +* Menu: + +* Prerequisites:: What you need before installing. +* Install:: Compiling and installing the software. +* Run:: Running the software. + + +File: cipe.info, Node: Prerequisites, Next: Install, Prev: Installation, Up: Installation + +Prerequisites +============= + +CIPE runs under Linux 2.0.12 through 2.0.35. Work is under way to make +it run under 2.1 kernels. It crashes under 2.0.0; don't use that buggy +kernel any more. It was developed for the i386 architecture; other +architectures *should* work, but only with the IDEA algorithm (no C +version of Blowfish included by now). + +Make sure you have the sources of the running kernel installed (usually +in `/usr/src/linux'). The version *and configuration* of the kernel +sources must match the running kernel exactly, or else you risk +building a module which crashes. After reconfiguring and rebuilding the +kernel, don't forget to rebuild the CIPE module too. This applies to all +externally compiled modules. + +The kernel needs "IP Forwarding/Gatewaying" enabled in the +configuration. It needs the `urandom' device available. + +A suited version of the module utilities (`modprobe' and friends) needs +to be installed. When in doubt, consult the documentation in the kernel +source. + +Look at the Makefile for configurable items: + + * CRYPTO: Select which crypto algorithm you want. + + * VERS: Leave this at 3, which is the current protocol version. + + * ASM: "i386" for using handcoded i386 versions of IDEA and Blowfish, + or nothing. + + * DEFS: Set -DDEBUG for including debugging code (recommended). + + * OPT: At least -O is needed by the kernel code. + + * KINC: Point this to the kernel include tree. You can compile CIPE + for another machine than the one you're compiling on, provided you + have the destination kernel's include tree available. + + * KDEFS: The default flags *must* be present. SMP is now handled + elsewhere, s.b. + + * SMP: Define this if you have an SMP kernel. + + * MODVERSIONS: Define this if your kernel has versioned symbols. + + * BINDIR, MODDIR: Where the two components (module and `ciped' + program) will get installed. + + +File: cipe.info, Node: Install, Next: Run, Prev: Prerequisites, Up: Installation + +Installation +============ + +A simple `make' command compiles everything. Compiler warnings should +not occur. Do `make install' as *root* to install the software +components in their final location. These are a kernel module, named +according to the protocol version and encryption algorithm selected, +and the driver program `ciped'. + +You need to create a directory `/etc/cipe' which contains at least two +files, `options' and `ip-up'. You can copy the files from the `samples' +directory in the distribution here, and edit them to suit your needs. +*Note Configuration::. + +If Compiling doesn't work: + +There is a known problem in that the various 2.0.30 and 2.0.31 +pre-releases disagree on whether they have a certain feature +(`SO_BINDTODEVICE'), and detecting this version dependency via the +version number is not foolproof. Apparently, since 2.0.32, this problem +is resolved. If `output.c' doesn't compile, change the line + #ifdef SO_BINDTODEVICE +to `#if 1' or `#if 0' as needed. + + +File: cipe.info, Node: Run, Prev: Install, Up: Installation + +Running CIPE +============ + +Once installed, the CIPE software is run by loading the module and +running the `ciped' daemon. + +* Menu: + +* insmod:: Loading the kernel module. +* ciped:: Running the daemon. + + +File: cipe.info, Node: insmod, Next: ciped, Prev: Run, Up: Run + +Loading the module +------------------ + +The kernel module is loaded into the kernel via the command + modprobe modulename parameter=value... +The module name is `cip' followed by the protocol version and the first +letter of the encryption algorithm. E.g. `cip3b' for version 3, +Blowfish (the default). The device names which this module manages are +the module name followed by a number, e.g. `cip3b0'. + +The CIPE module accepts the following additional parameters: + * `cipe_debug=(number)' -- Set the debugging level. The file + `cipe.h' defines different debugging levels which are ORed. Set + this to 0 if you don't need debugging output. Debugging output is + emitted via kernel messages, which means it usually winds up in the + syslog somewhere. + + * `cipe_maxdev=(number)' -- Set the number of channels this module + manages. E.g. with `cipe_maxdev=4' the devices `cip3b0' through + `cip3b3' are available. Maximum is 99. With CIPE 1.2, there is no + need to set this, since channels are allocated dynamically. + +The module can be autoloaded via `kerneld'. Advanced users will +recognize the following options in `/etc/conf.modules' necessary to +make it work correctly: + alias cip3b0 cip3b + alias cip3b1 cip3b + options cip3b cipe_maxdev=2 cipe_debug=0 + + +File: cipe.info, Node: ciped, Prev: insmod, Up: Run + +Running the `ciped' daemon +-------------------------- + +The `ciped' daemon must be run as "root". (*Do not* make it setuid.) It +takes as command line arguments an optional `-o file' parameter +specifying an options file followed by any number of individual option +arguments. *Note Specifying options::. + +Except in debugging mode, the daemon puts itself in the background and +uses `syslog(3)' for logging messages. Normal operation causes no log +messages except for errors and a notice when the daemon terminates. + +Shutting down (with `ifconfig(8)') a CIPE device terminates its `ciped' +process, and vice-versa terminating a `ciped' closes the device. When a +device is closed, its configuration parameters including all keys and +statistics are erased. (This is different from earlier CIPE versions!) +`ciped' does not keep any keys in memory. + +When the device comes up, `ciped' spawns `/etc/cipe/ip-up' with the +parameters described in the sample version. It waits for completion of +this script before data can be sent over the device and before it goes +into the background. The script is called with standard input, output +and error to `/dev/null'. It typically sets routes and does some +logging. Likewise, when a CIPE device goes down, `/etc/cipe/ip-down' is +invoked. `ciped' logs the interface statistics when closing. + +`ciped' will terminate when an error occurs. This includes a +"connection refused" message from the peer, to be able to detect +non-working peers. This default error handling implies that no data may +be sent over a link unless *both* ends are up and running, or the first +one to come up will go down again immediately. In particular, the +"ping" command in the sample `ip-up' should not be activated on both +ends of a link. This behaviour can be customized. *Note Error +handling::, for more details. + + +File: cipe.info, Node: Configuration, Next: Examples, Prev: Installation, Up: Top + +Configuration of the CIPE software +********************************** + +* Menu: + +* Specifying options:: How CIPE gets its parameters. +* Parameter list:: All valid and needed parameters. +* SOCKS:: Routing with CIPE over a SOCKS5 relayer. +* Error handling:: How ciped deals with errors. + + +File: cipe.info, Node: Specifying options, Next: Parameter list, Prev: Configuration, Up: Configuration + +Specifying options +================== + +All configuration parameters are processed by the `ciped' daemon. It +takes parameters from + 1. the default options file (`/etc/cipe/options'), + + 2. an options file specified as `-o file' on the command line, + + 3. single options given on the command line, + +in that order. Which means, parameters on the command line override +those from files, and parameters from an explicit options file override +those from the default options file. + +Options are one of the types: boolean, integer, IP address, IP address +with port number. Booleans are default false and specifying them as +option makes them true. IP addresses are given as dot-quad notation or +domain names which can be resolved using `gethostbyname(3)'. UDP or +TCP addresses are given as `ip:port', where the port is a number or a +name resolvable by `getservbyname(3)'. + +The syntax for specifying options is `name=value' on the command line, +and `name value' (one option per line) in the options file. + + +File: cipe.info, Node: Parameter list, Next: SOCKS, Prev: Specifying options, Up: Configuration + +List of all parameters +====================== + +Name Type Required +`device' string no Name of the CIPE device. If not given, the + system picks a free one. +`debug' bool no Debug mode: Don't go background, use stderr + instead of syslog. (Independent of the + kernel driver debug option.) +`ipaddr' IP yes IP address of the CIPE device. +`ptpaddr' IP yes IP address of the peer device (i.e. the CIPE + device on the other end). +`mtu' int no Device MTU (default: ethernet standard MTU + minus all necessary headers) +`metric' int no Device metric (not sure if this is used + anywhere...) +`cttl' int no Carrier TTL value. If not specified or 0, + use the payload packet's TTL. Default + recommendation is 64. +`me' UDP no Our carrier UDP address. If either IP or + port are not given, the system picks one and + reports it via `ip-up'. +`peer' UDP yes The other end's carrier UDP address. +`key' string (yes) The link key. For security reasons, the key + has to be set via an options file and + options files must be owned by root, + unreadable by anyone else. The key should be + 128 bits in hexadecimal encoding. (To + generate such a beast from random, try `ps + -auxw | md5sum'.) +`nokey' bool no Don't encrypt at all, just encapsulate in + UDP. With this option, `key' is not needed. + This option is not tested well. +`socks' TCP no Address (port required!) of the SOCKS5 + server. *Note SOCKS::. +`tokxc' int no Timeout (seconds) for key exchange. Default: + 10. +`tokey' int no Dynamic key lifetime. Default: 600 (10 + minutes). +`ipup' string no Script to run instead of `/etc/cipe/ip-up'. +`ipdown' string no Script to run instead of `/etc/cipe/ip-down'. +`arg' string no Argument to supply to ip-up. +`maxerr' int no Maximum number of errors before ciped exits. + *Note Error handling::. +`tokxts' int no Key exchange timestamp timeout. Default: 0 + (no timestamps). Set this to 30 to prevent + key exchange replay attacks, but only if the + peer runs CIPE 1.2 or later and both system + clocks are reasonably synchronized. + + +File: cipe.info, Node: SOCKS, Next: Error handling, Prev: Parameter list, Up: Configuration + +Working with SOCKS +================== + +With the `socks' option, CIPE uses a SOCKS5 server for sending and +receiving the encrypted data. Since this is UDP, SOCKS4 (which doesn't +support UDP) can not be used. SOCKS5 has a number of authentication +methods. CIPE can use either no authentication or Username/Password. +(1) Username and password are taken from the environment variables +`SOCKS5_USER' and `SOCKS5_PASSWD'. + +The implementation is not based on a SOCKS library, don't attempt to +link `ciped' with it. + +When one end of a CIPE link uses SOCKS, the other one must run a CIPE +version 0.5.1 or newer. Reason: as the IP and port number of the SOCKS5 +relayer get known only at run time, and there is no way for the +SOCKS-using part to get this information at all, it needs to determine +its peer dynamically. Older CIPE modules don't have this capability. + +When both ends use SOCKS (this is not tested), exactly one of them +should have a "ping" in its ip-up script, as described in the sample +ip-up. + +`ciped' periodically checks whether the SOCKS server has closed the +control connection. If the SOCKS server goes down, there is no way to +recover without restarting the client (in this case, `ciped'). This is +a limitation in the SOCKS5 protocol. *Note Error handling::. + +---------- Footnotes ---------- + +(1) GSSAPI/Kerberos authentication is not supported because (a) I don't +have the environment to test it, and (b) it can specify that UDP +packets be encrypted with its own method, which is unnecessary and +causes only additional load here, and (c) it makes the implementation +much more complicated. + + +File: cipe.info, Node: Error handling, Prev: SOCKS, Up: Configuration + +Error handling in `ciped' +========================= + +When the remote `ciped' is down or not available, the local `ciped' +will get a "connection refused" error. Older versions always exited on +this error. This has proven impractical in some situations, so an extra +option has been added: `maxerr' determines how many network errors +`ciped' will tolerate before exiting. This counter is reset when the +connection proves OK (more precisely: when a key exchange packet is +received). The default for `maxerr' is 8, like the non-changeable +default in version 0.5.1. A value of -1 will cause `ciped' to ignore +any network errors. In this case, it can only be brought down manually. + +Error handling for SOCKS is independent of this option, however. When an +error occurs on the SOCKS control connection (e.g., the SOCKS server +goes down), `ciped' will exit. This behaviour is mandated by the SOCKS5 +protocol. + + +File: cipe.info, Node: Examples, Next: Protocol, Prev: Configuration, Up: Top + +Usage examples +************** + +Here are some examples on how to design a network structure with CIPE +and configure the devices accordingly. + +* Menu: + +* Tips:: General useful tips on CIPE configuration. +* Example 1:: The classic VPN setups. + + +File: cipe.info, Node: Tips, Next: Example 1, Prev: Examples, Up: Examples + +General tips +============ + + * The IP address of a CIPE device and it's UDP carrier *must* be + different. Chose a "transit network" (e.g. 192.168 address) for + the CIPE devices if these don't fit into existing structures. + + * The route to the UDP carrier ("peer" address) *can not* go through + the CIPE device. If both are on the same route (e.g. both are on + the same network, IP-address-wise), add a host route to the "peer" + address through the right device or gateway. + + * In Linux 2.0, the `route add -host $5 dev $1' in ip-up is required. + Without it the link won't work. This also means the ip-up script + itself is mandatory. + + * Routes through a CIPE device should be set only in the ip-up + script. Use case selections on $1 or $5 if you have several CIPE + links. Use `route add ... gw $5', not `route add ... dev $1'. + Remember that Linux deletes any routes through a device when this + device goes down. + + * If you have a default route, the addresses reachable via the CIPE + link are routed via the default when the link is down. This can + defeat the purpose of an encrypted link. To guard against this, + set a reject route to the affected addresses with higher metric in + the system startup script. + + * On a system running `gated', gated is the only thing responsible + for setting any routes and the routes through the CIPE device + routes belong in gated.conf as static routes, or are to be set via + routing protocol. To gated, a CIPE link looks and behaves exactly + like a dial-up link. It is strongly recommended to put `gdc + interface' in `ip-up' as well as `ip-down' to tell gated about + status changes. + + * The configuration of both ends of a link is symmetric. One side's + `ipaddr' is the other's `ptpaddr', and one side's `me' is the + other's `peer'. Since CIPE 0.5, `peer' is picked up dynamically + and the real peer may be different from that set in the config + file (but this config item must still be present, it should + specify the other end's reverse as a reasonable default). + + * When designing a network structure, draw the CIPE links as if they + were SLIP/PPP links. Build the routing with these links enabled. + Then look at the picture as if the CIPE links weren't there, so + you can see the routing needed for the UDP adresses. + + +File: cipe.info, Node: Example 1, Prev: Tips, Up: Examples + +Example 1 +========= + +This basic example shows how to connect hosts and networks with +unofficial network numbers through the Internet. Uses for this are +classic VPN setups: + + 1. Connecting two unofficial subnets through an Internet link + + 2. Connecting a branch office to the head office through a + one-address dialup + + 3. Connecting a mobile host with varying access points + + + Internet Internet + ^ ^ + | | hostz + |ppp0 |eth1 200.0.24.3 + |200.0.24.65 |200.0.24.1 | + +---------routera routerb eth0 200.0.24.1 | + | eth0 \_ _ _ _ _ _ _ _/ \---------------+-------+---+ + | 10.0.1.1 cip3b0 cip3b0 eth0 | | + hosta 10.0.1.1 10.0.2.1 10.0.2.1 | | + 10.0.1.88 hostx hosty + 10.0.2.5 10.0.2.6 + +As can be seen from the picture, a CIPE device and another network +device can have the same IP address if there are no overlapping routes +between them. + +The CIPE devices are configured like this: + + routera routerb + cip3b0 cip3b0 +ipaddr 10.0.1.1 10.0.2.1 +ptpaddr 10.0.2.1 10.0.1.1 +me 200.0.24.65:9999 200.0.24.1:9999 +peer 200.0.24.1:9999 200.0.24.65:9999 +static routes 10.0.1.0/24 dev eth0 10.0.2.0/24 dev eth0 + default dev ppp0 200.0.24.0/26 dev eth0 + default dev eth1 +routes in ip-up 10.0.2.0/24 gw 10.0.2.1 10.0.1.0/24 gw 10.0.1.1 + +For case 3, assume `routera' to be the mobile host, think of `eth0' +missing and `ppp0' having a dynamic address. The `routerb' config +remains unchanged. For `routera' simply omit the `eth0' stuff. +`routerb' picks up its peer dynamically. This even works when `routerb' +is plugged behind a firewall and has to rely on a SOCKS5 server for +outside access. (Yes, this can be used to punch holes into firewalls. +No, it's not my intention to do anything about it. Local policy issues +have to be dealt with locally.) + + +File: cipe.info, Node: Protocol, Next: Misc, Prev: Examples, Up: Top + +CIPE protocol description +************************* + + This chapter is copied verbatim from the earlier documentation texts + and will be Texinfo-ized later. The text assumes some familiarity with + cryptography basics. + +The primary goal of this software is to provide a facility for secure +(against eavesdropping, including traffic analsyis, and faked message +injection) subnetwork interconnection across an insecure packet network +such as the Internet. + +1. Overview + +This protocol was designed to be simple and efficient, and to work over +existing communication facilities, especially by encapsulation in UDP +packets. Compatibility with existing protocols such as the IPSEC RFCs +were not a concern. The first test implementation was done entirely on +the user level, while the now published one consists of a kernel module +and a user level program. + +The CIPE model assumes a fixed link between two peers which exchange +datagrams (packetwise, not necessarily reliable). The most common way +of implementing such a thing is sending UDP messages between them. +(Another would be encapsulation in PPP, etc.) + +Nothing that can be parameterized is inside the scope of this protocol +and implementation. This is delegated to either prior arrangement or a +yet-to-be-defined application level protocol. Most notably, this +involves exchanging a shared secret key by now, and it involves choice +of encryption algorithm. + +The CIPE protocol consists of two parts: Encryption and checksumming of +the data packets and dynamic key exchange. + +2. Packet encryption + +Each IP datagram is taken as a whole, including headers. It is padded +at the end with zero to seven random octets so that the total length in +octets is congruent three modulo eight. The padded packet is appended +with one octet of the value P described below and the CRC-32 over the +packet built up so far, up to and including P. (This makes the complete +packet length a multiple of eight octets.) + +This packet is then encrypted through a 64-bit block cipher in CBC mode +with an IV as described below using either the static or the sending +dynamic key of the outbound interface (for definition of keys see +below). The default cipher algorithm is IDEA. The current +implementation also supports Blowfish with 128 bit key. + +The encrypted packet is prepended with the IV block. The highest order +bit of the first octet of the IV is zero if the static key is used, one +if the dynamic key is used. The remaining 63 bits are random, but the +first 15 of them should not be all zeros (i.e. an IV/packet that starts +with hex 0000 0000 or 8000 0000 is not allowed). Such packets are +reserved for later protocol extensions. + +The CRC is over the polynomial + + X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 +and represented in network byte order. + +The value P is given as follows: bits 6,5,4 indicate the length of the +padding between the original packet end and P. Bits 2,1 are a type +code, indicating which kind of packet this is. The remaining bits 7,3,0 +are reserved and must be zero. + +The type codes are: 00 - data 01 - key exchange 10 - reserved 11 - +reserved + +For decryption, first check the highest bit of the first octet and use +it to select the key. Decrypt the packet, calculate the CRC over the +packet minus the last four octets, compare that with the last four +octets. If valid, strip off the last octet as value P, strip off the +padding as given by bits 6,5,4 of P and process the packet as indicated +by bits 2,1 of P. + +3. Key exchange + +Every interface is associated with a static key, a sending dynamic key +and a receiving dynamic key. (An interface is an endpoint of a +connection, which may use protocols like UDP for transport but for the +purpose of CIPE are always point-to-point links.) On startup, only the +static key is valid. Encryption uses the static key if and only if the +sending dynamic key is invalid. The value 0 (all bits zero) for the +static key is reserved for future extensions and should not be used. + +The dynamic key is set by a dialogue procedure involving messages with +type code bits 01. These are encrypted just like above. The packets +consist of a type octet followed by protocol data followed by a random +amount of padding random data, so that the packet is at least 64 octets +long. A key consists of 16 octets, a key CRC is the CRC-32 over the +key, transferred in network order. + +The following messages exist: + +NK_REQ: Type code 1, no data: Requests the peer to immediately start a +key negotiation (send NK_IND). This should be sent when a packet is +received encrypted with a dynamic key but no dynamic receive key is +valid. (Which can happen when the receiving side of a connection is +rebooted while the sending side remains running.) + +NK_IND: Type code 2, data is new key followed by key CRC. Specifies a +new sending dynamic key for this sender. Requests the peer to +immediately answer with NK_ACK. + +NK_ACK: Type code 3, data is CRC of the previously accepted key. +Confirms receipt of NK_IND. + +The key negotiation procedure normally runs as follows: The sender +sends a NK_IND with the new key, then invalidates its own sending key. +Upon receipt of NK_IND, the receiver starts using this key as its +receiving key and sends a NK_ACK. When the sender receives NK_ACK, it +starts using the new key as its sending key. If either of NK_IND or +NK_ACK is lost in transmission, no new key will be used. The sender +should send a new NK_IND (with new key) if no matching NK_ACK is +received within a reasonable amount of time (current specification: 10 +seconds). + +If any of the checksums contained in the key negotiation data +mismatches the contained or stored key, this packet is ignored and no +further action taken. + +A sending dynamic key should be invalidated after being used for a +certain period of time or amount of data and a new NK_IND sent. The +process is symmetric and both sides act independently for their own +sending key. The dynamic key lifetime should not exceed 15 minutes and +the amount of data sent using one dynamic key should not exceed 2^32 +packets. + +Optionally, the key exchange packets can be timestamped. The timestamp +is a 32bit unsigned integer in network order representing the UNIX time +of the sending host, placed in octets 56-59 (starting at zero) of the +key exchange packets. The receiver may be configured to ignore the +timestamp, or it may be configured to reject all key exchange packets +whose timestamp differs from the current UNIX time of the receiving host +by more than a defined amount. It is recommended that this timeout not +exceeds 30 seconds. + +4. Security considerations + +The packets that actually get transmitted don't carry any usable +information related to the original IP datagram other than its length, +padded to a multiple of 8. This should effectively guard against most +aspects of traffic analysis. The only information visible prior +(attempt) to decrypting the packet is the bit that tells whether the +static or dynamic key was used. Because the static key has a +potentially long lifetime it is expected to be used as rarely as +possible. It is normally used only in the short period of time during a +key exchange. The dynamic key is changed often. These precautions are +there because the application is prone to known and chosen plaintext +attacks and the intention is to inhibit feeding of large amounts of +data through one key. + +Because the type code and padding length are encrypted with the packet, +they can not be deduced from the ciphertext. Especially, it is not +possible to determine whether the packet is a data or key exchange +packet. (Usually, the last packet of a sequence of dynamic key packets +followed by a sequence of static key packets is a NK_IND, but the +NK_ACK and a possible second NK_IND can't be guessed this way, so there +is no provision to tell whether the key exchange succeeded. However, +this is a small but real weakness.) + +The CRC serves as a check whether the encryption key was valid - i.e. +some sort of signature for authenticity of the packet. Additionally, +data packets should still have to form valid IP headers (with their own +16-bit checksum) and key exchange packets carry their own checksum as +defined above. + +IP packets carry some known or easily guessable plaintext in certain +positions of their header. Potential exploitation of this fact should +be mitigated by the limited key usage described above. The use of a +random IV for each packet means at least that identical (retransmitted) +packets encrypt to different ciphertexts. + +The protocol gives only limited protection against replay attacks. A +packet remains valid as long as the key it is encrypted with remains +valid. However, active exploitation is unlikely as the packet carries +no indication of its meaning. (Except for the note about sequences and +NK_IND above. Replay of NK_IND could be dangerous. Possible remedy: +store the last N accepted key CRCs [for large-ish N] and refuse to +accept NK_INDs with the same CRC as an already stored one.) + +If the timestamp of key exchange packets is used, it should guard +against replay of key exchange packets. However, this requires that the +clocks of both machines are in sync. + +Denial of service attacks are possible e.g. by sending large amounts of +bogus packets, which should affect performance only. A vulnerability +against disruption of the key generation process exists if the sender +is overrun with bogus packets so that it fails to process the NK_ACK, +effectively being forced to use its static sending key for a prolonged +period of time. A possible way out of this problem is to stop sending +data completely after a long burst of static key sends, sending only +NK_INDs and resuming only after a valid NK_ACK has been processed. +Then this attack would become a simple denial-of-service. + +5. Practical test, Conclusion + +The mentioned prototype implementations, one on the user level and one +as a kernel module, have been in use for several months now on a live +network, where they provide a transparent connection between +subnetworks through an insecure transit network based on UDP +encapsulation. This does work flawlessly. However, it is too early to +draw final conclusions about the feasibility of this approach. + +It is planned to replace the simple secret key based key exchange +process described above by a signed Diffie-Hellman scheme, which would +eliminate the need for secret keys. + + +File: cipe.info, Node: Misc, Next: Concept Index, Prev: Protocol, Up: Top + +Odds and ends +************* + + * Ideas and code for this project came from various parts of the + Linux 2.0.12 kernel, most notably the `ipip' protocol, the + `new_tunnel' driver, and the `udp' protocol. + + * NOTE: This software contains a data encryption facility. Use of it + is restricted by law in some countries including France and + Russia. In the United States of America it is not allowed to + export such systems without special permission. The IDEA algorithm + included herein is patented and subject to licensing conditions at + least in parts of Europe and America (see + `http://www.ascom.ch/systec'). + + * To Do list for future development: + - Add C version of Blowfish algorithm. + + - Profiling and optimization for speed. Check C implementation + of IDEA for possible optimization. + + - Make IDEA run in constant time to harden against timing + attack? This would impose a serious performance penalty. It + is at least possible in C and i486 and higher; probably not + for the i386. The Blowfish algorithm always runs in constant + time. + + - Test various combinations of crypto algorithm and + implementation selected. + + - Implement all of the attack protections outlined in the + protocol chapter. (Keeping log of recent keys and + timestamping is implemented.) + + - Implement dummy packet generation. + + * There is a mailing list for CIPE users and development. To + subscribe, send mail to <majordomo@inka.de> containing the line + subscribe cipe-l + in the message body. Please subscribe before posting to the list. + + +File: cipe.info, Node: Concept Index, Prev: Misc, Up: Top + +Concept Index +************* + +* Menu: + +* /etc/cipe directory: Install. +* autoloading of modules: insmod. +* Blowfish: Protocol. +* Branch office -- head office: Example 1. +* carrier network: Routing. +* CIPE link: How CIPE works. +* ciped: Components. +* Classic VPN setup: Example 1. +* command line options: Specifying options. +* Compilation errors: Install. +* Compiling modules: Prerequisites. +* CRC: Protocol. +* debugging level: insmod. +* Denial of service attack: Protocol. +* Designing network structure: Tips. +* device names: insmod. +* devices, number of: insmod. +* Encrypted tunneling: Routing. +* firewall rules: Internals. +* gated: Tips. +* Hole in firewall: Example 1. +* IDEA: Protocol. +* IP address syntax: Specifying options. +* IP-in-IP tunneling: Routing. +* IPIP: How CIPE works. +* IPSEC <1>: Protocol. +* IPSEC: Routing. +* Kernel IP forwarding option <1>: Prerequisites. +* Kernel IP forwarding option: Internals. +* Kernel versions: Prerequisites. +* Key exchange: Protocol. +* Legal issues: Misc. +* link key: How CIPE works. +* Mailing list: Misc. +* Makefile variables: Prerequisites. +* Mobile host: Example 1. +* modprobe command: insmod. +* module name: insmod. +* module parameters: insmod. +* network device: Components. +* Network layers: Network layers. +* Obtaining the CIPE package: Installation. +* options file: Specifying options. +* Packet encryption: Protocol. +* PGP: Network layers. +* pppd: Components. +* reject route: Tips. +* Setting routes: Tips. +* SO_BINDTODEVICE: Install. +* SOCKS: SOCKS. +* SSH: Network layers. +* To Do list: Misc. +* traffic analysis: Routing. +* transit network: Tips. +* tunnel driver: Internals. +* UDP: How CIPE works. +* Unofficial subnets: Example 1. +* VPN: Routing. + + + +Tag Table: +Node: Top98 +Node: Introduction1705 +Node: Network layers2116 +Node: Routing3868 +Node: How CIPE works6424 +Node: Components7651 +Node: Internals8460 +Node: Installation10754 +Node: Prerequisites11361 +Node: Install13347 +Node: Run14416 +Node: insmod14710 +Node: ciped16074 +Node: Configuration17949 +Node: Specifying options18348 +Node: Parameter list19457 +Node: SOCKS23149 +Node: Error handling24851 +Node: Examples25828 +Node: Tips26179 +Node: Example 128650 +Node: Protocol31241 +Node: Misc41705 +Node: Concept Index43470 + +End Tag Table diff -ruN linux-2.2.5,pristine/net/cipe/cipe.lsm linux-2.2.5/net/cipe/cipe.lsm --- linux-2.2.5,pristine/net/cipe/cipe.lsm Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/cipe.lsm Thu Apr 1 23:05:46 1999 @@ -0,0 +1,13 @@ +Begin3 +Title: cipe +Version: 0.5.6 +Entered-date: 07APR97 +Description: A network device that does encrypted IP-in-UDP tunneling. + Useful for building virtual private networks, etc. + The package consists of a kernel module and driver program. +Keywords: encryption, routing, tunnel, VPN +Author: olaf@bigred.inka.de (Olaf Titz) +Primary-site: ftp.inka.de /sites/bigred/sw + 65k cipe-0.5.6.tar.gz +Copying-policy: GPL +End diff -ruN linux-2.2.5,pristine/net/cipe/ciped.c linux-2.2.5/net/cipe/ciped.c --- linux-2.2.5,pristine/net/cipe/ciped.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/ciped.c Thu Apr 1 23:05:46 1999 @@ -0,0 +1,918 @@ +/* + CIPE - encrypted IP over UDP tunneling + + ciped.c - the user mode driver + + Copyright 1996 Olaf Titz <olaf@bigred.inka.de> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. +*/ +/* $Id: ciped.c,v 1.21 1998/10/18 15:38:41 olaf Exp $ */ + +#define CTLDIR "/etc/cipe" + +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> +#include <arpa/inet.h> +#include <net/if.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <sys/signal.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/wait.h> +#include "ciped.h" +#include "ioctl.h" + +#ifndef LOPGFAC +#define LOPGFAC LOG_DAEMON +#endif + +static const char daemon_version[]=VERSION; + +void usage(const char *p) +{ + fprintf(stderr, "usage: %s [-o file ] [options] device=name\n", p); + exit(1); +} + +/* FIXME: places marked *#* have byteorder conversion missing */ +/* This is corrected in version 3 protocol */ + +/*** The global options structure ***/ + +struct options { + const char * const oname; + const char otyp; + union { + int ovint; + char *ovstr; + struct sockaddr_in *ovsaddr; + } ov; +} opts[] = { +#define Opt(x,t) { #x, T##t, {0} }, +#define Tbool 0 +#define Tint 1 +#define Tstr 2 +#define Taddr 3 +#define Tuaddr 4 +#define Ttaddr 5 + +#define Odevice 0 /* name of the CIPE device, e.g. cip3b0 */ +Opt(device,str) +#define Odebug 1 /* Debug mode - don't detach, verbose messages */ +Opt(debug,bool) +#define Oipaddr 2 /* This CIPE device's IP address */ +Opt(ipaddr,addr) +#define Optpaddr 3 /* The peer CIPE device's IP address */ +Opt(ptpaddr,addr) +#define Omtu 4 /* Device MTU */ +Opt(mtu,int) +#define Ometric 5 /* Device metric */ +Opt(metric,int) +#define Ome 6 /* My UDP address */ +Opt(me,uaddr) +#define Opeer 7 /* The peer's UDP address, + i.e. where to send packets */ +Opt(peer,uaddr) +#define Okey 8 /* The interface secret key + - set via options file only */ +Opt(key,str) +#define Onokey 9 /* Don't encrypt */ +Opt(nokey,bool) +#define Osocks 10 /* SOCKS5 server (ip:port) */ +Opt(socks,taddr) +#define Otokxc 11 /* Timeout for key exchange (secs) */ +Opt(tokxc,int) +#define Otokey 12 /* Dynamic key lifetime (secs) */ +Opt(tokey,int) +#define Oipup 13 /* Name of the ip-up script */ +Opt(ipup,str) +#define Oipdown 14 /* Name of the ip-down script */ +Opt(ipdown,str) +#define Oarg 15 /* Extra argument to ip-up script */ +Opt(arg,str) +#define Octtl 16 /* TTL value for carrier */ +Opt(cttl,int) +#define Omaxerr 17 /* Maximum ECONNREFUSED tolerance */ +Opt(maxerr,int) +#define Otokxts 18 /* Timeout for key exchange timestamps */ +Opt(tokxts,int) + +#undef Opt +{ NULL, 0, {0} }}; + +#define OI(x) (opts[O##x].ov.ovint) +#define OS(x) (opts[O##x].ov.ovstr) +#define OA(x) (opts[O##x].ov.ovsaddr) +#define OAaddr(x) (OA(x)->sin_addr) +#define OAport(x) (OA(x)->sin_port) + +/* Statistics */ +struct kstat { + int rreq, req, ind, indb, ack, ackb, bogus; +} ks = { 0, 0, 0, 0, 0, 0, 0 }; + +char device[16] = ""; +int devnum = -1; + +/*** Option parser ***/ + +/* Resolve a host:port address */ +int getaddr(char *c, struct sockaddr_in *sa, const char *prot) +{ + struct hostent *h; + struct servent *s; + char *q=strchr(c, ':'); + + sa->sin_family=AF_INET; + sa->sin_port=0; + sa->sin_addr.s_addr=INADDR_ANY; + if (q) { + if (!prot) { + fprintf(stderr, "raw IP address has no port number\n"); + return -1; + } + *q++='\0'; + if (!(sa->sin_port=htons(atoi(q)))) { + if ((s=getservbyname(q, prot))) + sa->sin_port=s->s_port; + else { + fprintf(stderr, "port '%s' invalid/not found\n", q); + return -1; + } + } + } + if ((sa->sin_addr.s_addr=inet_addr(c))==-1) { + if ((h=gethostbyname(c))) + memcpy(&sa->sin_addr.s_addr, h->h_addr_list[0], + sizeof(sa->sin_addr.s_addr)); + else { + fprintf(stderr, "host '%s' invalid/not found\n", c); + return -1; + } + } + return 0; +} + +/* Set an option */ +int setopt(const char *n, char *v) +{ + struct options *o=opts; + static const char * const protos[]={NULL, "udp", "tcp"}; + + while (o->oname) { + if (!strcmp(o->oname, n)) { + if ((!v) && (o->otyp!=Tbool)) { + fprintf(stderr, "missing value for %s\n", n); return -1; + } + switch(o->otyp) { + case Tbool: + o->ov.ovint=1; break; + case Tint: + o->ov.ovint=atoi(v); break; + case Tstr: + if (!(o->ov.ovstr=strdup(v))) { + fprintf(stderr, "setopt: out of memory\n"); return -1; + } + break; + case Taddr: + case Tuaddr: + case Ttaddr: + if (!(o->ov.ovsaddr=malloc(sizeof(*o->ov.ovsaddr)))) { + fprintf(stderr, "setopt: out of memory\n"); return -1; + } + if (getaddr(v, o->ov.ovsaddr, protos[o->otyp-Taddr])<0) { + return -1; + } + break; + default: + fprintf(stderr, "internal error: %d\n", __LINE__); return -1; + } + return 0; + } + ++o; + } + fprintf(stderr, "unknown option: %s\n", n); + return -1; +} + +/* Set options from command line */ +void setopt_cmdline(int argc, char *argv[]) +{ + int i; + char *q; + for (i=0; i<argc; ++i) { + if ((q=strchr(argv[i], '='))) + *q++='\0'; + if (!strcmp(argv[i], "key")) { + fprintf(stderr, "Refused to set key from command line!\n"); + continue; + } + (void) setopt(argv[i], q); + } +} + +/* Set options from file, report file not found if (v) */ +void setopt_file(const char *n, int v) +{ + int d; + FILE *f; + char b[128]; + char *p, *q; + struct stat s; + + if ((d=open(n, O_RDONLY))<0) { + if (v) + perror("setopt_file: open"); + return; + } + if (fstat(d, &s)<0) { + perror("setopt_file: stat"); + return; + } + if (!S_ISREG(s.st_mode) || (s.st_mode&(S_IRWXG|S_IRWXO)) || + (s.st_uid!=0)) { + fprintf(stderr, "file %s has incorrect permissions\n", n); + return; + } + + if (!(f=fdopen(d, "r"))) { + if (v) + perror("setopt_file: fdopen"); + return; + } + while (fgets(b, sizeof(b), f)) { + p=b; + if ((q=strchr(p, '\n'))) + *q='\0'; + while ((*p) && strchr(" \t", *p)) + ++p; + if ((!*p) || strchr("#;:!", *p)) + continue; + if ((q=strpbrk(p, " \t="))) { + while ((*q) && strchr(" \t=", *q)) + *q++='\0'; + if (!*q) + q=NULL; + } + (void) setopt(p, q); + } + fclose(f); +} + +/* Print out all options */ +void dumpopt(void) +{ + struct options *o; + for (o=opts; o->oname; ++o) { + printf("%s ", o->oname); + switch(o->otyp) { + case Tbool: printf("%s\n", o->ov.ovint?"yes":"no"); break; + case Tint: printf("%d\n", o->ov.ovint); break; + case Tstr: printf("%s\n", o->ov.ovstr?o->ov.ovstr:"(none)"); break; + case Taddr: + if (o->ov.ovsaddr) + printf("%s\n", inet_ntoa(o->ov.ovsaddr->sin_addr)); + else + printf("(none)\n"); + break; + case Tuaddr: + case Ttaddr: + if (o->ov.ovsaddr) + printf("%s:%d\n", inet_ntoa(o->ov.ovsaddr->sin_addr), + ntohs(o->ov.ovsaddr->sin_port)); + else + printf("(none)\n"); + break; + default: printf("internal error: %d\n", __LINE__); break; + } + } +} + +/*** Logging ***/ + +void log(int lev, const char *s) +{ + if (OI(debug)) + fprintf(stderr, s); + else + syslog(lev, s); +} + +void log2(int lev, const char *f, const char *s) +{ + if (OI(debug)) + fprintf(stderr, f, s); + else + syslog(lev, f, s); +} + +/* perror replacement */ +void logerr(int lev, const char *s) +{ + if (OI(debug)) + perror(s); + else + syslog(lev, "%s: %s", s, strerror(errno)); +} + +/* missing option */ +void argmiss(const char *s) +{ + if (OI(debug)) + fprintf(stderr, "missing argument: %s\n", s); + else + syslog(LOG_ERR, "missing argument: %s", s); +} + +/* print if debugging */ +#define dprintf0(f) if(OI(debug)){printf(f);} +#define dprintf1(f,a) if(OI(debug)){printf(f,a);} + + +/*** Initialize, open and attach the CIPE device. ***/ + +int opendev(void) +{ + int f, i; +#ifndef NO_DYNDEV + struct siocsifcipall d; +#endif + struct siocsifcippar p; + struct siocsifcipkey k; + struct siocsifcipatt a; + struct ifreq r; + +#define amiss(s) { argmiss(s); goto error; } +#define err(s) { logerr(LOG_ERR, s); goto error; } + + /* Initialize, bind and connect the socket */ + if ((f=socket(AF_INET, SOCK_DGRAM, 0))<0) { + logerr(LOG_ERR, "opendev: socket"); + return -1; + } + i=65536; /* we need much to receive fast */ + if (setsockopt(f, SOL_SOCKET, SO_RCVBUF, &i, sizeof(i))) + /* not fatal */ + logerr(LOG_NOTICE, "opendev: setsockopt"); + if (!OA(me)) { + if (!(OA(me)=malloc(sizeof(*OA(me))))) + err("opendev: malloc"); + OA(me)->sin_family=AF_INET; + OAaddr(me).s_addr=INADDR_ANY; + OAport(me)=0; + } + if (bind(f, (struct sockaddr *)OA(me), sizeof(*OA(me)))<0) + err("opendev: bind"); + if (OA(peer)) { + if (connect(f, (struct sockaddr *)OA(peer), sizeof(*OA(peer)))<0) + err("opendev: bind"); + } else + amiss("peer"); + i=sizeof(*OA(me)); + if (getsockname(f, (struct sockaddr *)OA(me), &i)<0) + /* not fatal */ + logerr(LOG_NOTICE, "opendev: getsockname"); + +#ifdef NO_DYNDEV + if (!OS(device)) + amiss("device"); +#else + /* Allocate the device name */ + if (OS(device)) { + char *x=OS(device)+strlen(OS(device))-1; + while (x>=OS(device) && isdigit(*x)) + --x; + d.num=atoi(++x); + } else { + d.num=-1; + } + if (ioctl_alloc(f, DEVNAME "0", &d)<0) + err("opendev: alloc"); + strcpy(device, d.name); + devnum=d.num; + if (OI(debug)) + printf("Using %s index %d\n", device, devnum); +#endif + + /* Set the CIPE operation parameters */ + memset(&p, 0, sizeof(p)); + if (OA(socks)) { + p.sockshost=OAaddr(socks).s_addr; + p.socksport=OAport(socks); + } + p.tmo_keyxchg=OI(tokxc); + p.tmo_keylife=OI(tokey); + p.mayclear=OI(nokey); + p.cttl=OI(cttl); + if (ioctl_setpar(f, device, &p)<0) + err("opendev: setpar"); + + /* Set the key */ + if (OS(key)) { + unsigned char *c=OS(key); + unsigned char *x=(unsigned char *)&k.thekey; + i=0; + k.which=KEY_STATIC; + /* primitive hex decoder */ + while(*c) { + x[i]=((*c)<<4)&0xF0; + *c++='\0'; /* clear after use */ + if (!*c) break; + x[i++]|=(*c)&0x0F; + *c++='\0'; + if (i>=userKeySize) break; + } + if (ioctl_setkey(f, device, &k)<0) + err("opendev: setkey"); + memset(&k, 0, sizeof(k)); + } else { + if (!OI(nokey)) + amiss("key"); + } + + /* Perform attach */ + a.fd=f; + if (ioctl_attach(f, device, &a)<0) + err("opendev: attach"); + + /* Perform ifconfig */ + strcpy(r.ifr_name, device); + if (OA(ipaddr)) { + memcpy(&r.ifr_addr, OA(ipaddr), sizeof(*OA(ipaddr))); + if (ioctl(f, SIOCSIFADDR, &r)<0) + err("opendev: SIOCSIFADDR"); + } else + amiss("ipaddr"); + if (OA(ptpaddr)) { + memcpy(&r.ifr_dstaddr, OA(ptpaddr), sizeof(*OA(ptpaddr))); + if (ioctl(f, SIOCSIFDSTADDR, &r)<0) + err("opendev: SIOCSIFDSTADDR"); + } + if (OI(mtu)) { + r.ifr_mtu=OI(mtu); + if (ioctl(f, SIOCSIFMTU, &r)<0) + err("opendev: SIOCSIFMTU"); + } + if (OI(metric)) { + r.ifr_metric=OI(metric); + if (ioctl(f, SIOCSIFMETRIC, &r)<0) + err("opendev: SIOCSIFMETRIC"); + } + r.ifr_flags=IFF_UP|IFF_RUNNING|IFF_NOARP|IFF_NOTRAILERS|IFF_POINTOPOINT; + if (ioctl(f, SIOCSIFFLAGS, &r)<0) + err("opendev: SIOCSIFFLAGS"); + + return f; + + error: + close(f); + return -1; + +#undef amiss +#undef err +} + +/* Close the device. */ + +void closedev(int f) +{ + struct ifreq r; + strcpy(r.ifr_name, device); + if (ioctl(f, SIOCGIFFLAGS, &r)<0) + logerr(LOG_ERR, "closedev: SIOCGIFFLAGS"); + r.ifr_flags&=~(IFF_UP|IFF_RUNNING); + if (ioctl(f, SIOCSIFFLAGS, &r)<0) + logerr(LOG_ERR, "closedev: SIOCSIFFLAGS"); + close(f); +#ifndef NO_DYNDEV + if (devnum>0) { + struct siocsifcipall x; + if ((f=socket(AF_INET, SOCK_DGRAM, 0))<0) { + logerr(LOG_ERR, "closedev: socket"); + return; + } + x.num=devnum; + if (ioctl_unalloc(f, device, &x)<0) + logerr(LOG_ERR, "closedev: alloc"); + close(f); + } +#endif +} + +/* Fetch the device statistics. */ + +char *getstats(void) +{ + static char b[256]; + char *p, *q; + FILE *f=fopen("/proc/net/dev/", "r"); + if (!f) + return NULL; + while (fgets(b, sizeof(b), f)) { + for (p=b; *p==' '; ++p); + for (q=p; *q && *q!=':'; ++q); + if (!*q) + continue; + *q++='\0'; + if (strcmp(p, device)) + continue; + fclose(f); + return(q); + } + fclose(f); + return NULL; +} + + +/*** Open a SOCKS5 connection ***/ + +int opensocks(void) { + struct sockaddr_in a; + int fd=socks5_open(OA(socks)); + if (fd>=0) { + /* 3rd par of socks5_cmd is in: my address, out: relayer */ + a=*OA(me); + fd=socks5_cmd(fd, S5_UDP, &a); + /* Swap peer and socks addresses. + Use the SOCKS relayer as "peer" and the real peer as "socks" + parameter. See output.c why. */ + *OA(socks)=*OA(peer); + *OA(peer)=a; + } + return fd; +} + +/* Check whether the SOCKS5 server has closed the connection */ + +const char *eofsocks_str[] = {"no error", "exception", "read error", "EOF"}; + +int eofsocks(int fd) { + fd_set ifd, efd; + struct timeval t={0,0}; + FD_ZERO(&ifd); + FD_ZERO(&efd); + FD_SET(fd, &ifd); + FD_SET(fd, &efd); + if (select(fd+1, &ifd, NULL, &efd, &t)>0) { + if (FD_ISSET(fd, &efd)) { + return 1; + } + if (FD_ISSET(fd, &ifd)) { + int e; + char c; + if ((e=read(fd, &c, 1))<=0) { + return e<0 ? 2 : 3; + } + } + } + return 0; +} + +/*** Signal handler ***/ + +sig_atomic_t gotsig=0; + +void sighand(int s) +{ + if (OI(debug)) { + printf("Signal %d\n", s); + } else { + syslog(LOG_NOTICE, "got signal %d", s); + } + gotsig=s; +} + +void sigignore(int s) +{ + /* Dummy */ +} + +void setsig(int sig, void (*fun)(int)) +{ + struct sigaction sa; + sa.sa_handler = fun; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sigaction(sig, &sa, NULL); +} + +/*** The key exchange procedure ***/ + +#ifdef VER_CRC32 +typedef unsigned long crc; +#define CRCFORM "%08lX" +#else +typedef unsigned short crc; +#define CRCFORM "%04X" +#endif + +#define REM 256 /* How many keys to remember */ + +/* Cache last valid key CRCs. */ + +static int dupcheck(crc c) +{ + static crc ca[REM]; + static int caf=0, cal=0; + int i; + + for (i=cal; i<caf; ++i) + if (ca[i%REM]==c) + return 1; + if (caf-cal>=REM) + if (++cal>REM) { + caf-=REM; + cal-=REM; + } + ca[caf%REM]=c; + ++caf; + return 0; +} + +int errcnt; + +int kxchg(int f, int r) +{ + int x=0, e=0; + unsigned char kx[KEYXCHGBLKMIN]; + #define kx_typ (kx[0]) + #define kx_nkind_key (kx+1) + #define kx_ts (*(time_t *)(kx+KEYXCHGTSPOS)) +#ifdef VER_CRC32 + #define kx_nkind_crc (*(unsigned long *)(kx+1+userKeySize)) + #define kx_nkack_crc (*(unsigned long *)(kx+1)) +#else + #define kx_nkind_crc (*(unsigned short *)(kx+1+userKeySize)) + #define kx_nkack_crc (*(unsigned short *)(kx+1)) +#endif + static crc scrc=0; + static unsigned char skey[userKeySize]; + + if (recv(f, &kx, sizeof(kx), 0)<=0) { + if (errno==EAGAIN || errno==EINTR) + /* This is normal, would be even after select */ + return 0; + logerr(LOG_INFO, "kxchg: recv"); + if (errno==ENXIO) + /* Device was closed */ + return -1; + /* allow for some amount of ECONNREFUSED etc. */ + return (OI(maxerr)<0 ? 0 : --errcnt); + } + errcnt=OI(maxerr); + if (OI(tokxts) && (abs(time(0)-kx_ts)>OI(tokxts))) { + dprintf0("KX: timestamp error\n"); + return 0; + } + switch(kx_typ) { + case NK_RREQ: + kx_typ=NK_REQ; + dprintf0("KX: [NK_RREQ] sending NK_REQ\n"); + x=send(f, &kx, sizeof(kx), 0); e=errno; + ++ks.rreq; + break; + case NK_REQ: + kx_typ=NK_IND; + if (read(r, &skey, userKeySize)!=userKeySize) { + logerr(LOG_ERR, "kxchg: read(r)"); + return -1; + } + memcpy(kx_nkind_key, skey, userKeySize); +#ifdef VER_CRC32 + kx_nkind_crc=(scrc=htonl(crc32(skey, userKeySize))); +#else + kx_nkind_crc=(scrc=block_crc(skey, userKeySize)); /*#*/ +#endif + dprintf1("KX: [NK_REQ] sending NK_IND " CRCFORM "\n", scrc); + x=send(f, &kx, sizeof(kx), 0); e=errno; + { + struct siocsifcipkey sk; + sk.which=KEY_INVAL+KEY_SEND; + if (ioctl_setkey(f, device, &sk)<0) + logerr(LOG_ERR, "setkey"); + memset(&sk, 0, sizeof(sk)); + } + ++ks.req; + break; + case NK_IND: + if ( +#ifdef VER_CRC32 + crc32(kx_nkind_key, userKeySize)==ntohl(kx_nkind_crc) +#else + block_crc(kx_nkind_key, userKeySize)==(kx_nkind_crc) /*#*/ +#endif + ) { + struct siocsifcipkey sk; + if (dupcheck(kx_nkind_crc)) { + dprintf0("KX: [NK_IND] duplicate\n"); + ++ks.indb; + } else { + sk.which=KEY_RECV; + memcpy(&sk.thekey, kx_nkind_key, userKeySize); + if (ioctl_setkey(f, device, &sk)<0) + perror("setkey"); + else { + kx_typ=NK_ACK; + kx_nkack_crc=kx_nkind_crc; /* XX */ + dprintf1("KX: [NK_IND] sending NK_ACK " CRCFORM "\n", + (kx_nkack_crc)); /*#*/ + x=send(f, &kx, sizeof(kx), 0); e=errno; + } + ++ks.ind; + } + memset(&sk, 0, sizeof(sk)); + } else { + dprintf0("KX: [NK_IND] invalid\n"); + ++ks.indb; + } + break; + case NK_ACK: + if (scrc==(kx_nkack_crc)) { /*#*/ + struct siocsifcipkey sk; + sk.which=KEY_SEND; + memcpy(&sk.thekey, &skey, userKeySize); + dprintf1("KX: [NK_ACK] got " CRCFORM "\n", scrc); + if (ioctl_setkey(f, device, &sk)<0) + perror("setkey"); + ++ks.ack; + memset(&sk, 0, sizeof(sk)); + memset(&skey, 0, sizeof(skey)); + } else { + dprintf1("KX: [NK_ACK] unknown " CRCFORM "\n", scrc); + ++ks.ackb; + } + break; + default: + dprintf1("KX: invalid type %02X\n", kx_typ); + ++ks.bogus; + } + memset(kx, 0, sizeof(kx)); + if (x<0) { + errno=e; + logerr(LOG_WARNING, "kxchg: send"); + if (e==ENXIO) + return -1; + x=(OI(maxerr)<0 ? 0 : --errcnt); + } + return x; +} + +/*** Call the ip-up, ip-down scripts ***/ + +void pspawn(char *s) +{ + int p, c; + p=getpid(); + if ((c=fork())<0) { + logerr(LOG_ERR, "pspawn: fork"); + return; + } + if (c) { + (void) wait(NULL); /* exactly one child is active */ + } else { + /* call <interface> <my-addr> <daemon-pid> <local> <remote> <arg> */ + char bufa[32], bufb[32], bufc[32], bufd[32]; + char *na[]={s, device, bufa, bufb, bufc, bufd, OS(arg), NULL}; + sprintf(bufa, "%s:%d", inet_ntoa(OAaddr(me)), ntohs(OAport(me))); + sprintf(bufb, "%d", p); + sprintf(bufc, "%s", inet_ntoa(OAaddr(ipaddr))); + sprintf(bufd, "%s", inet_ntoa(OAaddr(ptpaddr))); + close(0); close(1); close(2); + (void) open("/dev/null", O_RDWR); + (void) dup(0); (void) dup(0); + execv(s, na); + logerr(LOG_WARNING, "pspawn: exec"); + exit(1); + } +} + +/*** Main program ***/ + +int main(int argc, char *argv[]) +{ + int i, ur, fd, sd=-1, pi[2]; + char *st; + char *pn=strrchr(argv[0], '/'); + if (pn) + ++pn; + else + pn=argv[0]; + + if (getuid() || geteuid()) { + fprintf(stderr, "This program must be run by root.\n"); + exit(1); + /* DO NOT remove this check */ + } + /* Snarf options from: standard options file, user-supplied file and + finally, command line */ + setopt_file(CTLDIR "/options", 0); + if ((argc>1) && (!strcmp(argv[1], "-o"))) { + if (argc>2) { + setopt_file(argv[2], 1); + argc-=2; argv+=2; + } else { + usage(pn); + } + } + setopt_cmdline(--argc, ++argv); + if (!OI(maxerr)) + OI(maxerr)=8; /* compatibility */ + + for (i=getdtablesize()-1; i>2; --i) + (void) close(i); + if (!OI(debug)) { + /* daemonize */ + if (pipe(pi)<0) { + perror("pipe"); exit(1); + } + if ((i=fork())<0) { + perror("fork"); exit(1); + } + if (i) { + /* wait until the child is ready */ + close(pi[1]); + (void) read(pi[0], &i, 1); + exit(0); + } + close(pi[0]); + openlog(pn, LOG_PID, LOPGFAC); + /* don't let the syslog socket get in the way of the standard fds */ + close(0); close(1); close(2); + setsid(); + syslog(LOG_INFO, "CIPE daemon vers %s (c) Olaf Titz 1996-1998", + daemon_version); + } else { + printf("CIPE daemon vers %s (c) Olaf Titz 1996-1998\n", + daemon_version); + dumpopt(); + } + + if ((ur=open("/dev/urandom", O_RDONLY))<0) { + logerr(LOG_ERR, "open(/dev/urandom)"); exit(1); + } + if (OA(socks)) { + struct itimerval t; + if ((sd=opensocks())<0) + exit(1); + /* Since the key exchange socket can't do select(), we make + the recv() return EINTR every now and then to get a chance + to check the socks5 control socket. */ + setsig(SIGALRM, sigignore); + t.it_interval.tv_sec = 30; + t.it_interval.tv_usec = 0; + t.it_value.tv_sec = 60; + t.it_value.tv_usec = 0; + setitimer(ITIMER_REAL, &t, 0); + } + + if ((fd=opendev())<0) + exit(1); + pspawn(OS(ipup) ? OS(ipup) : CTLDIR "/ip-up"); + if (!OI(debug)) + close(pi[1]); + + setsig(SIGHUP, sighand); + setsig(SIGINT, sighand); + setsig(SIGTERM, sighand); + errcnt=OI(maxerr); + + /* Main loop */ + while ((!gotsig) && (kxchg(fd, ur)>=0)) { + if ((sd>=0) && (i=eofsocks(sd))) { + log2(LOG_INFO, "%s on socks connection", eofsocks_str[i]); + break; + } + } + + if ((st=getstats())) { + if (OI(debug)) + printf("Interface stats %s\n", st); + else + syslog(LOG_INFO, "Interface stats %s\n", st); + } + closedev(fd); + if (OI(debug)) + printf("KX stats: rreq=%d, req=%d, ind=%d, indb=%d, ack=%d," + " ackb=%d, unknown=%d\n", ks.rreq, ks.req, ks.ind, ks.indb, + ks.ack, ks.ackb, ks.bogus); + else + syslog(LOG_INFO, "KX stats: rreq=%d, req=%d, ind=%d, indb=%d, ack=%d," + " ackb=%d, unknown=%d\n", ks.rreq, ks.req, ks.ind, ks.indb, + ks.ack, ks.ackb, ks.bogus); + pspawn(OS(ipdown) ? OS(ipdown) : CTLDIR "/ip-down"); + if (!OI(debug)) + syslog(LOG_INFO, "%s: daemon exiting", device); + return 0; +} diff -ruN linux-2.2.5,pristine/net/cipe/ciped.h linux-2.2.5/net/cipe/ciped.h --- linux-2.2.5,pristine/net/cipe/ciped.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/ciped.h Thu Apr 1 23:05:46 1999 @@ -0,0 +1,27 @@ +/* + CIPE - encrypted IP over UDP tunneling + + ciped.h - prototypes for user level routines + + Copyright 1997 Olaf Titz <olaf@bigred.inka.de> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. +*/ +/* $Id: ciped.h,v 1.1 1997/09/18 23:00:46 olaf Exp $ */ + +#include "cipe.h" + +/* ciped.c */ +extern void log(int lev, const char *s); +extern void log2(int lev, const char *f, const char *s); +extern void logerr(int lev, const char *s); + +/* socks5.c */ +#define S5_CONN 1 +#define S5_BIND 2 +#define S5_UDP 3 +extern int socks5_open(struct sockaddr_in *so); +int socks5_cmd(int fd, int cmd, struct sockaddr_in *so); diff -ruN linux-2.2.5,pristine/net/cipe/crc.c linux-2.2.5/net/cipe/crc.c --- linux-2.2.5,pristine/net/cipe/crc.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/crc.c Thu Apr 1 23:05:46 1999 @@ -0,0 +1,62 @@ +/* crctab calculated by Mark G. Mendel, Network Systems Corporation */ +static unsigned short crctab[256] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 +}; + +/* + * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. + * NOTE: First argument must be in range 0 to 255. + * Second argument is referenced twice. + * + * Programmers may incorporate any or all code into their programs, + * giving proper credit within the source. Publication of the + * source routines is permitted so long as proper credit is given + * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg, + * Omen Technology. + */ + +#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp) + +unsigned short block_crc(unsigned char *d, int len) +{ + unsigned short crc = 0; + while (len-->0) + crc = updcrc((*d++), crc); + return crc; +} + +unsigned short update_crc(unsigned short old, unsigned char c) +{ + return updcrc(c, old); +} diff -ruN linux-2.2.5,pristine/net/cipe/crc32.c linux-2.2.5/net/cipe/crc32.c --- linux-2.2.5,pristine/net/cipe/crc32.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/crc32.c Thu Apr 1 23:05:46 1999 @@ -0,0 +1,111 @@ + /* ============================================================= */ + /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */ + /* code or tables extracted from it, as desired without restriction. */ + /* */ + /* First, the polynomial itself and its table of feedback terms. The */ + /* polynomial is */ + /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ + /* */ + /* Note that we take it "backwards" and put the highest-order term in */ + /* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ + /* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ + /* the MSB being 1. */ + /* */ + /* Note that the usual hardware shift register implementation, which */ + /* is what we're using (we're merely optimizing it by doing eight-bit */ + /* chunks at a time) shifts bits into the lowest-order term. In our */ + /* implementation, that means shifting towards the right. Why do we */ + /* do it this way? Because the calculated CRC must be transmitted in */ + /* order from highest-order term to lowest-order term. UARTs transmit */ + /* characters in order from LSB to MSB. By storing the CRC this way, */ + /* we hand it to the UART in the order low-byte to high-byte; the UART */ + /* sends each low-bit to hight-bit; and the result is transmission bit */ + /* by bit from highest- to lowest-order term without requiring any bit */ + /* shuffling on our part. Reception works similarly. */ + /* */ + /* The feedback terms table consists of 256, 32-bit entries. Notes: */ + /* */ + /* The table can be generated at runtime if desired; code to do so */ + /* is shown later. It might not be obvious, but the feedback */ + /* terms simply represent the results of eight shift/xor opera- */ + /* tions for all combinations of data and CRC register values. */ + /* */ + /* The values must be right-shifted by eight bits by the "updcrc" */ + /* logic; the shift must be unsigned (bring in zeroes). On some */ + /* hardware you could probably optimize the shift in assembler by */ + /* using byte-swap instructions. */ + /* polynomial $edb88320 */ + /* */ + /* -------------------------------------------------------------------- */ + +static unsigned long crc32_tab[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL + }; + +/* Return a 32-bit CRC of the contents of the buffer. */ + +unsigned long crc32(const unsigned char *s, unsigned int len) +{ + unsigned int i; + unsigned long crc32val; + + crc32val = 0; + for (i = 0; i < len; i ++) + { + crc32val = + crc32_tab[(crc32val ^ s[i]) & 0xff] ^ + (crc32val >> 8); + } + return crc32val; +} diff -ruN linux-2.2.5,pristine/net/cipe/crcgen.c linux-2.2.5/net/cipe/crcgen.c --- linux-2.2.5,pristine/net/cipe/crcgen.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/crcgen.c Thu Apr 1 23:05:46 1999 @@ -0,0 +1,10 @@ +#include <stdio.h> + +extern unsigned long crc32(const unsigned char *s, unsigned int len); + +int main(int argc, char *argv[]) +{ + printf("#define VERSION_MAGIC 0x%08lXUL\n", + crc32(argv[1], strlen(argv[1]))); + return 0; +} diff -ruN linux-2.2.5,pristine/net/cipe/crypto.h linux-2.2.5/net/cipe/crypto.h --- linux-2.2.5,pristine/net/cipe/crypto.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/crypto.h Thu Apr 1 23:05:46 1999 @@ -0,0 +1,84 @@ +/* + CIPE - encrypted IP over UDP tunneling + + crypto.h - configuration of the crypto algorithm + + Copyright 1996 Olaf Titz <olaf@bigred.inka.de> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. +*/ +/* $Id: crypto.h,v 1.4 1998/08/17 18:42:44 olaf Exp $ */ + +#ifndef _CRYPTO_H_ +#define _CRYPTO_H_ + +typedef unsigned long part; +/* the longest integer so that sizeof(part) divides blockSize. + Used only for optimizing block-copy and block-XOR operations. */ + +#if ProtocolVersion == 1 + +#ifdef OLDNAMES +#define VERNAME "1" +#else +#define VERNAME "a" +#endif +#define VER_BACK /* encryption progress backwards */ +#define VER_SHORT /* no IV in packet */ + +#elif ProtocolVersion == 2 + +#ifdef OLDNAMES +#define VERNAME "2" +#else +#define VERNAME "b" +#endif + +#elif ProtocolVersion == 3 + +#ifdef OLDNAMES +#define VERNAME "3" +#else +#define VERNAME "c" +#endif +#define VER_CRC32 /* checksums are 32bit */ + +#else +#error "Must specify correct ProtocolVersion" +#endif + + +#ifdef Crypto_IDEA +#define CRYPTO "IDEA" +#define CRNAME "i" +#include "idea0.h" +#define Key Idea_Key +#define keySize Idea_keySize +#define UserKey Idea_UserKey +#define userKeySize Idea_userKeySize +#define ExpandUserKey Idea_ExpandUserKey +#define InvertKey Idea_InvertKey +#define blockSize Idea_dataSize + +#else +#ifdef Crypto_Blowfish +#define CRYPTO "Blowfish" +#define CRNAME "b" +#include "bf.h" +#define Key Blowfish_Key +#define keySize sizeof(Blowfish_Key) +#define UserKey Blowfish_UserKey +#define userKeySize 16 /* arbitrary, but matches IDEA */ +#define ExpandUserKey(u,k) Blowfish_ExpandUserKey(&u,userKeySize,&k) +#define InvertKey(x,y) /* noop */ +#define blockSize sizeof(Blowfish_Data) + +#else +#error "Must specify Crypto_Idea or CryptoBlowfish" +#endif +#endif + +#endif diff -ruN linux-2.2.5,pristine/net/cipe/device.c linux-2.2.5/net/cipe/device.c --- linux-2.2.5,pristine/net/cipe/device.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/device.c Thu Apr 1 23:05:46 1999 @@ -0,0 +1,509 @@ +/* + CIPE - encrypted IP over UDP tunneling + + device.c - the net device driver + + Copyright 1996 Olaf Titz <olaf@bigred.inka.de> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. +*/ +/* $Id: device.c,v 1.21 1998/11/14 20:48:02 olaf Exp $ */ + +#include "cipe.h" +#include "version.h" +#include <stddef.h> +#include <linux/if.h> +#include <linux/if_arp.h> +#include <linux/sched.h> + +#ifdef LINUX_21 +#include <asm/uaccess.h> +#include <linux/rtnetlink.h> +#else +#define register_netdevice register_netdev +#define unregister_netdevice unregister_netdev +#endif + +/*** Globals ***/ + +static const char driver_version[]=VERSION; + +struct cipe_ctrl **cipe_ctrls = NULL; +#ifdef NO_DYNDEV +int cipe_maxdev = 4; /* changeable via insmod */ +#else +int cipe_maxdev = 100; /* changeable via insmod */ +#endif +#ifdef DEBUG +int cipe_debug = DEB_CALL; /* changeable via insmod */ +#endif + +/* clear all potentially sensitive info and stats */ +static void cipe_zero_c(struct cipe *c) +{ + memset(&(c->peeraddr), 0, + offsetof(struct cipe, udp_prot)-offsetof(struct cipe, peeraddr)); + /* reset these to sensible values */ + c->tmo_keyxchg = 10*HZ; + c->tmo_keylife = 10*60*HZ; +} + +/* weak but fast PRNG, used for padding only */ +static __u32 prnseed; +void cipe_prnpad(unsigned char *buf, int len) +{ + while (len>0) { + prnseed=prnseed*0x01001001+1; + if (len>=2) { + *(__u16 *)buf=prnseed>>16; + len-=2; buf+=2; + } else { + *buf=(prnseed>>24)^jiffies; return; + } + } +} + + +/*** IOCTL handlers ***/ + +static int cipe_getpar(struct device *dev, struct siocgifcippar *parm) +{ + DEVTOCIPE(dev,c,-ENODEV); + + parm->sockshost=c->sockshost; + parm->socksport=c->socksport; + parm->tmo_keyxchg=c->tmo_keyxchg/HZ; + parm->tmo_keylife=c->tmo_keylife/HZ; + parm->mayclear=c->mayclear; + parm->cttl=c->cttl; + return 0; +} + +static int cipe_setpar(struct device *dev, struct siocsifcippar *parm) +{ + DEVTOCIPE(dev,c,-ENODEV); + + if (parm->sockshost) + c->sockshost=parm->sockshost; + if (parm->socksport) + c->socksport=parm->socksport; + if (parm->tmo_keyxchg>10*60*HZ) + return -EINVAL; + if (parm->tmo_keyxchg) + c->tmo_keyxchg=parm->tmo_keyxchg*HZ; + if (parm->tmo_keylife>24*60*60*HZ) + return -EINVAL; + if (parm->tmo_keylife) + c->tmo_keylife=parm->tmo_keylife*HZ; + c->mayclear=parm->mayclear; + c->cttl=parm->cttl; + c->dev->hard_header_len=cipexhdrl+ + ((c->sockshost) ? sizeof(struct sockshdr) : 0); + return 0; +} + +static int cipe_setkey(struct device *dev, struct siocsifcipkey *parm) +{ + DEVTOCIPE(dev,c,-ENODEV); + + dprintk(DEB_KXC, (KERN_INFO "%s: setkey %d\n", dev->name, parm->which)); + switch (parm->which) { + case KEY_STATIC: + ExpandUserKey(parm->thekey, c->key_e); + InvertKey(c->key_e, c->key_d); + c->havekey=1; + break; + case KEY_SEND: + ExpandUserKey(parm->thekey, c->skey_e); + c->timeskey=jiffies+c->tmo_keylife; + c->cntskey=0; + c->haveskey=1; + break; + case KEY_RECV: + ExpandUserKey(parm->thekey, c->rkey_d); + InvertKey(c->rkey_d, c->rkey_d); + c->timerkey=jiffies+2*c->tmo_keylife; /* allow for fuzz */ + c->cntrkey=0; + c->haverkey=1; + break; + case KEY_STATIC+KEY_INVAL: + c->havekey=c->haveskey=c->haverkey=0; + memset(&(c->key_e), 0, sizeof(c->key_e)); + memset(&(c->key_d), 0, sizeof(c->key_d)); + break; + case KEY_SEND+KEY_INVAL: + c->haveskey=0; + memset(&(c->skey_e), 0, sizeof(c->skey_e)); + c->timeskey=jiffies+c->tmo_keyxchg; + break; + case KEY_RECV+KEY_INVAL: + c->haverkey=0; + memset(&(c->rkey_d), 0, sizeof(c->rkey_d)); + c->timerkey=jiffies+c->tmo_keyxchg; + break; + default: + return -EINVAL; + } + return 0; +} + +static int cipe_alloc_dev(int n); +static void cipe_unalloc_dev(int n); + +#ifndef NO_DYNDEV +static int cipe_hasowner(int n) +{ + struct task_struct *p=current; + pid_t pid=cipe_ctrls[n]->cipe.owner; + if (!pid) + return 0; + do { + if (p->pid==pid) + return 1; + p=p->next_task; + } while (p!=current); + return 0; +} +#endif + +#ifdef LINUX_21 +/* In 2.1 the ioctl operations are run under lock. Beware of deadlocks. */ +#define cipe_alloc_LOCK() 0 +#define cipe_alloc_UNLOCK() +#else +static struct semaphore cipe_alloc_sem=MUTEX; +#define cipe_alloc_LOCK() down_interruptible(&cipe_alloc_sem) +#define cipe_alloc_UNLOCK() up(&cipe_alloc_sem) +#endif + +static int cipe_alloc(struct device *dev, struct siocsifcipall *parm) +{ +#ifdef NO_DYNDEV + return -ENOSYS; +#else + int n=parm->num; + int e; + if (n>=cipe_maxdev) + return -EINVAL; + if ((e=cipe_alloc_LOCK())) + return e; + if (n>=0) { + if (cipe_ctrls[n]) { + if (cipe_ctrls[n]->cipe.sock || cipe_hasowner(n)) + e=-EBUSY; + else + cipe_ctrls[n]->cipe.owner=current->pid; + } else { + e=cipe_alloc_dev(n); + } + } else { + e=-EMFILE; + for (n=0; n<cipe_maxdev; ++n) { + if (!cipe_ctrls[n]) { + e=cipe_alloc_dev(n); + break; + } + if (!cipe_hasowner(n)) { + cipe_ctrls[n]->cipe.owner=current->pid; + e=0; + break; + } + } + } + if (!e) { + parm->num=n; + strncpy(parm->name, cipe_ctrls[n]->name, sizeof(parm->name)-1); + parm->name[sizeof(parm->name)-1]='\0'; + } + cipe_alloc_UNLOCK(); + return e; +#endif +} + +static int cipe_unalloc(struct device *dev, struct siocsifcipall *parm) +{ +#ifdef NO_DYNDEV + return -ENOSYS; +#else + int e; + if (parm->num<0 || parm->num>=cipe_maxdev) + return -EINVAL; + if ((e=cipe_alloc_LOCK())) + return e; + if (cipe_ctrls[parm->num]->cipe.sock) { + e=-EBUSY; + } else { + if (parm->num>0) + cipe_unalloc_dev(parm->num); + } + cipe_alloc_UNLOCK(); + return e; +#endif +} + + +/*** Device operation handlers ***/ + +int cipe_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +{ + int e; + +#ifdef LINUX_21 + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + +#define doioctl(nam,fun,str) { \ + struct str parm; \ + dprintk(DEB_CALL, (KERN_INFO "%s: " nam "\n", dev->name)); \ + if ((e=copy_from_user((void*)&parm,(void*)ifr->ifr_data, \ + sizeof(parm)))<0) \ + return e; \ + if (parm.magic!=VERSION_MAGIC) return -EINVAL; \ + if ((e=fun(dev, &parm))<0) \ + return e; \ + if ((e=copy_to_user((void*)ifr->ifr_data, (void*)&parm, \ + sizeof(parm)))<0) \ + return e; \ + return 0; } + +#else + + if (!suser()) + return -EPERM; + +#define doioctl(nam,fun,str) { \ + struct str parm; \ + dprintk(DEB_CALL, (KERN_INFO "%s: " nam "\n", dev->name)); \ + if ((e=verify_area(VERIFY_READ, ifr->ifr_data, sizeof(parm)))<0) \ + return e; \ + memcpy_fromfs((void*)&parm, (void*)ifr->ifr_data, sizeof(parm)); \ + if (parm.magic!=VERSION_MAGIC) return -EINVAL; \ + if ((e=fun(dev, &parm))<0) \ + return e; \ + if ((e=verify_area(VERIFY_WRITE, ifr->ifr_data, sizeof(parm)))<0) \ + return e; \ + memcpy_tofs((void*)ifr->ifr_data, (void*)&parm, sizeof(parm)); \ + return 0; } + +#endif + + switch (cmd) { + case SIOCGIFCIPPAR: + doioctl("getpar", cipe_getpar, siocgifcippar); + case SIOCSIFCIPPAR: + doioctl("setpar", cipe_setpar, siocsifcippar); + case SIOCSIFCIPKEY: + doioctl("setkey", cipe_setkey, siocsifcipkey); + case SIOCSIFCIPATT: + doioctl("attach", cipe_attach, siocsifcipatt); + case SIOCSIFCIPALL: + doioctl("alloc", cipe_alloc, siocsifcipall); + case SIOCSIFCIPUNA: + doioctl("unalloc", cipe_unalloc, siocsifcipall); + default: + return -EINVAL; + } + +#undef doioctl +} + +int cipe_dev_open(struct device *dev) +{ + DEVTOCIPE(dev,c,-ENODEV); + if (!c->sock) + return -ENXIO; + dprintk(DEB_CALL, (KERN_INFO "%s: opened\n", dev->name)); + return 0; +} + +void cipe_close(struct cipe *c) +{ + cipe_zero_c(c); + dprintk(DEB_CALL, (KERN_INFO "%s: closed\n", c->dev->name)); +} + +int cipe_dev_close(struct device *dev) +{ + struct cipe *c = (struct cipe*)(dev->priv); + if ((!c) || (c->magic!=CIPE_MAGIC)) { + printk(KERN_WARNING "%s: cipe_dev_close(): no valid struct\n", + dev->name); + return 0; + } + if (c->sock) { + dprintk(DEB_CALL, (KERN_INFO "%s: closing\n", c->dev->name)); + /* Tell the attached socket we're going down */ + c->sock->shutdown=SHUTDOWN_MASK; + c->sock->zapped=1; + c->sock->err=ENXIO; + c->sock->error_report(c->sock); + } else { + cipe_close(c); + } + return 0; +} + +struct enet_statistics *cipe_get_stats(struct device *dev) +{ + DEVTOCIPE(dev,c,NULL); + return &(c->stat); +} + + +/*** Initialization and finalization stuff ***/ + +#ifndef LINUX_21 +static inline void dev_init_buffers(struct device *dev) +{ + int i; + for (i = 0; i < DEV_NUMBUFFS; i++) { + skb_queue_head_init(&dev->buffs[i]); + } +} +#endif + +static int cipe_init_dev(struct device *dev) +{ + struct cipe *c = (struct cipe*)(dev->priv); + if (!c) + return -ENODEV; + + memset(c, 0, sizeof(struct cipe)); /* zero the device struct along */ + c->magic = CIPE_MAGIC; + c->dev = dev; + cipe_zero_c(c); + + /* Device parameters. */ + /* Procedural */ + dev->open = cipe_dev_open; + dev->stop = cipe_dev_close; + dev->hard_start_xmit = cipe_xmit; + dev->get_stats = cipe_get_stats; + dev->hard_header = NULL; + dev->rebuild_header = NULL; + dev->do_ioctl = cipe_dev_ioctl; + + /* "Hardware" */ + dev->type = ARPHRD_TUNNEL; + dev->hard_header_len = cipexhdrl; + dev->mtu = ETH_DATA_LEN + -sizeof(struct sockshdr) + -cipehdrlen + -cipefootlen; + + dev->addr_len = 4; /* Dummy? */ + dev->tx_queue_len = 100; /* matches ethernet */ + +#ifdef LINUX_21 + dev->iflink = -1; +#else + dev->family = AF_INET; + dev->pa_alen = 4; + dev->metric = 1; +#endif + dev_init_buffers(dev); + + /* New-style flags */ + dev->flags = IFF_POINTOPOINT|IFF_NOTRAILERS|IFF_NOARP; + + return 0; +} + +static int cipe_alloc_dev(int n) +{ + int e=0; + struct cipe_ctrl *cc; + + dprintk(DEB_CALL, (KERN_INFO DEVNAME ": cipe_alloc_dev %d\n", n)); + if (!(cc=kmalloc(sizeof(struct cipe_ctrl), GFP_KERNEL))) { + cipe_ctrls[n]=NULL; + return -ENOMEM; + } + + memset((void *)cc, 0, sizeof(struct cipe_ctrl)); + sprintf(cc->name, DEVNAME "%d", n); + cc->dev.name = cc->name; + cc->dev.base_addr = n; /* dummy */ + cc->dev.priv = (void*)&(cc->cipe); + cc->dev.next = NULL; + cc->dev.init = cipe_init_dev; /* called by register_netdevice */ + + e=register_netdevice(&(cc->dev)); + if (e<0) { + kfree(cc); + printk(KERN_ERR + "%s: register_netdevice() failed\n", cc->name); + cc=NULL; + } else { + cc->cipe.owner=current->pid; + } + cipe_ctrls[n]=cc; + return e; +} + +static void cipe_unalloc_dev(int n) +{ + struct cipe_ctrl *cc=cipe_ctrls[n]; + if (!cc) + return; + dprintk(DEB_CALL, (KERN_INFO DEVNAME ": cipe_unalloc_dev %d\n", n)); + if (cc->cipe.magic!=CIPE_MAGIC) { + printk(KERN_WARNING DEVNAME ": Ouch: cipe_unalloc_dev() wrong struct\n"); + return; + } + unregister_netdevice(&(cc->dev)); + cipe_ctrls[n]=NULL; + kfree(cc); +} + + +int init_module(void) +{ + /* sanity check on insmod-provided data */ + if (cipe_maxdev<1) cipe_maxdev=1; + if (cipe_maxdev>100) cipe_maxdev=100; + +#ifdef DEBUG + printk(KERN_INFO + DEVNAME ": CIPE driver vers %s (c) Olaf Titz 1996-1998, %d channels, debug=%d\n", + driver_version, cipe_maxdev, cipe_debug); +#else + printk(KERN_INFO + DEVNAME ": CIPE driver vers %s (c) Olaf Titz 1996-1998, %d channels\n", + driver_version, cipe_maxdev); +#endif + + prnseed=~jiffies; + cipe_ctrls = (struct cipe_ctrl **) kmalloc(sizeof(void*)*cipe_maxdev, + GFP_KERNEL); + if (!cipe_ctrls) { + printk(KERN_ERR + DEVNAME ": failed to allocate master control structure\n"); + return -ENOMEM; + } + memset(cipe_ctrls, 0, sizeof(void*)*cipe_maxdev); +#ifdef NO_DYNDEV + { + int i, e; + for (i=0; i<cipe_maxdev; ++i) + if ((e=cipe_alloc_dev(i))) + return e; + return 0; + } +#else + return cipe_alloc_dev(0); +#endif +} + +void cleanup_module(void) +{ + int i; + for (i=0; i<cipe_maxdev; ++i) + cipe_unalloc_dev(i); + kfree(cipe_ctrls); +} + diff -ruN linux-2.2.5,pristine/net/cipe/encaps.c linux-2.2.5/net/cipe/encaps.c --- linux-2.2.5,pristine/net/cipe/encaps.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/encaps.c Thu Apr 1 23:05:46 1999 @@ -0,0 +1,287 @@ +/* + CIPE - encrypted IP over UDP tunneling + + encaps.c - do encryption + + Copyright 1996 Olaf Titz <olaf@bigred.inka.de> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. +*/ +/* $Id: encaps.c,v 1.10 1998/08/20 22:06:05 olaf Exp $ */ + +#include "cipe.h" +#include <string.h> +#include <linux/socket.h> + +static inline void xorbuf(part *dst, part *src) +{ + int i; + for (i=0; i<blockSize/sizeof(part); ++i) + *dst++^=*src++; +} + +#ifdef Crypto_IDEA +/* This seems to be the only way to typecast an array. + Important: GCC is able to swallow the overhead when optimizing. */ +static inline void ecb_enc(part *src, part *dst, Idea_Key *k) +{ + Idea_Data *s=(Idea_Data *)src; + Idea_Data *d=(Idea_Data *)dst; + Idea_Crypt(*s, *d, *k); +} +#define ecb_dec(s,d,k) ecb_enc(s,d,k) +#endif + +#ifdef Crypto_Blowfish +#define ecb_enc(s,d,k) Blowfish_Encrypt(s,d,k) +#define ecb_dec(s,d,k) Blowfish_Decrypt(s,d,k) +#endif + +#ifdef VER_BACK + +/* Encrypt/decrypt message in CBC mode backwards. + Key must be set up accordingly */ +static void cbc_b(unsigned char *msg, int len, Idea_Key *key, int dec) +{ + int i=len/blockSize; + unsigned char iv[blockSize], iw[blockSize]; + part *p=(part*)(msg+len-blockSize); + part *q=(part*)iv; + part *r=(part*)iw; + part *s; + + memset(iv, 0, blockSize); + if (dec) { + while (i-->0) { + memcpy(r, p, blockSize); + ecb_dec(p, p, key); + xorbuf(p, q); + s=q; q=r; r=s; + p-=blockSize/sizeof(part); + } + } else { + while (i-->0) { + xorbuf(p, q); + ecb_enc(p, p, key); + q=p; + p-=blockSize/sizeof(part); + } + } +} + +#else + +/* + CBC encryption/decryption routines. + Note: the block to encrypt includes the IV, while decryption swallows + the IV. Length is always including IV. +*/ + +#define partinc(p) ((p)+blockSize/sizeof(part)) + +static void cbc_enc(unsigned char *msg, int len, Key *key) +{ + part *p=(part *)msg; + int i=len/blockSize; + + while (--i>0) { + xorbuf(partinc(p), p); + p=partinc(p); + ecb_enc(p, p, key); + } +} + +static void cbc_dec(unsigned char *msg, int len, Key *key) +{ + part *p=(part *)msg; + int i=len/blockSize; + part r[blockSize/sizeof(part)]; + + while (--i>0) { + ecb_dec(partinc(p), r, key); + xorbuf(p, r); + p=partinc(p); + } +} + +#endif + +#ifndef VER_SHORT +/* Fill a block of length blockSize with strong random numbers. + Used for generating IVs. */ +void cipe_cryptpad(unsigned char *buf) +{ + static int padcnt=MAXBLKS; + static Key padkey; + + if (++padcnt>MAXBLKS) { + /* make a new random key */ + char k[userKeySize]; + dprintk1(DEB_CRYPT, KERN_INFO, "%s: re-keying cryptpad\n", DEVNAME); + cipe_prnpad(k, userKeySize); + ExpandUserKey(k, padkey); + padcnt=0; + } + *(int *)(buf)=padcnt; + cipe_prnpad(buf+sizeof(int), blockSize-sizeof(int)); + ecb_enc(buf, buf, padkey); +} +#endif + + +void cipe_checkskey(struct cipe *c) +{ + if ((++c->cntskey>MAXBLKS) || (jiffies>c->timeskey)) { + /* make the control process send an NK_IND */ + cipe_fakenkey(c, NK_REQ); + c->timeskey=jiffies+c->tmo_keyxchg; + if (c->cntskey>MAXBLKS) + c->cntskey-=1000; + } +} + +void cipe_checkrkey(struct cipe *c) +{ + if ((c->haverkey) && + ((++c->cntrkey>MAXBLKS*2) || (jiffies>c->timerkey))) { + /* make the control process send an NK_REQ */ + cipe_fakenkey(c, NK_RREQ); + c->haverkey=0; + c->timerkey=jiffies+c->tmo_keyxchg; + if (c->cntrkey>MAXBLKS*2) + c->cntrkey-=1000; + } +} + +void cipe_nodynkey(struct cipe *c) +{ + if (jiffies>c->timerkey) { + /* make the control process send an NK_REQ */ + cipe_fakenkey(c, NK_RREQ); + c->timerkey=jiffies+c->tmo_keyxchg; + } + dprintk1(DEB_CRYPT, KERN_INFO, "%s: missing dynamic key\n", + c->dev->name); +} + +#if ProtocolVersion == 3 + +/* Encryption/decryption version 3 */ + +void cipe_encrypt(struct cipe *c, unsigned char *buf, int *len, int typ) +{ + unsigned char p=7-(((*len)+4)&7); + /* merge key flag in IV */ + *buf&=0x7F; + if (c->haveskey) + *buf|=0x80; + /* pad */ + cipe_prnpad(buf+(*len), p); + (*len)+=p+5; + /* set type and crc */ + *(buf+(*len)-5)=typ|(p<<4); + *((unsigned long *)(buf+(*len)-4))= + htonl(crc32(buf+blockSize, (*len)-blockSize-4)); + + dprintk3(DEB_CRYPT, KERN_INFO, "%s: encrypt pad %d len %d\n", + c->dev->name, p, *len); + cbc_enc(buf, *len, c->haveskey ? &c->skey_e : &c->key_e); + cipe_checkskey(c); +} + +unsigned short cipe_decrypt(struct cipe *c, unsigned char *buf, int *len) +{ + unsigned char p; + + if (((*buf)&0x80) && !(c->haverkey)) { + cipe_nodynkey(c); + return TW_ERROR; /* can't decrypt - no valid key */ + } + cbc_dec(buf, *len, ((*buf)&0x80) ? &c->rkey_d : &c->key_d); + (*len)-=blockSize; + if (*((unsigned long *)(buf+(*len)-4)) != htonl(crc32(buf, (*len)-4))) { + dprintk1(DEB_CRYPT, KERN_INFO, + "%s: decrypt CRC error\n", c->dev->name); + return TW_ERROR; + } + p=*(buf+(*len)-5); + (*len)-=(p>>4)&7; + cipe_checkrkey(c); +#define CTLBITS 0x06 + dprintk(DEB_CRYPT, (KERN_INFO "%s: decrypt len=%d pad=%d typ=%02X\n", + c->dev->name, (*len), (p>>4)&7, p&CTLBITS)); + return (p&CTLBITS); +} + +#else + +/* Encryption/decryption version 1 and 2 */ + +void cipe_encrypt(struct cipe *c, unsigned char *buf, int *len, int typ) +{ + unsigned short x; + unsigned char p; + + p=8-((*len)&7); + cipe_prnpad(buf+(*len), p); + (*len)+=p; + +#ifdef VER_SHORT + x=((block_crc(buf, *len)&0xFFFE)^((p&7)<<8)^typ)|(c->haveskey); +#else + x=((block_crc(buf+blockSize, (*len)-blockSize)&0xFFFE) + ^((p&7)<<8)^typ)|(c->haveskey); +#endif +#ifdef VER_BACK + cbc_b(buf, *len, c->haveskey ? &c->skey_e : &c->key_e, 0); +#else + cbc_enc(buf, *len, c->haveskey ? &c->skey_e : &c->key_e); +#endif + + dprintk2(DEB_CRYPT, KERN_INFO, "%s: encrypt pad %d\n", c->dev->name, p); + buf[(*len)++]=x>>8; + buf[(*len)++]=x&255; + cipe_checkskey(c); +} + +unsigned short cipe_decrypt(struct cipe *c, unsigned char *buf, int *len) +{ + unsigned short x=(buf[(*len)-1])+(buf[(*len)-2]<<8); + unsigned char p; + + if ((x&1) && !(c->haverkey)) { + cipe_nodynkey(c); + return TW_ERROR; /* can't decrypt - no valid key */ + } + (*len)-=2; + if (*len<9 +#ifndef VER_SHORT + +blockSize +#endif + ) + return TW_ERROR; /* short packet */ + +#ifdef VER_BACK + cbc_b(buf, *len, (x&1) ? &c->rkey_d : &c->key_d, 1); +#else + cbc_dec(buf, *len, (x&1) ? &c->rkey_d : &c->key_d); +#endif +#ifndef VER_SHORT + (*len)-=blockSize; +#endif + + x^=block_crc(buf, *len); + p=(x>>8)&7; if (!p) p=8; + (*len)-=p; + cipe_checkrkey(c); + +#define CTLBITS 0xF8FE + dprintk3(DEB_CRYPT, KERN_INFO, "%s: decrypt pad %d typ %04X\n", + c->dev->name, (x>>8)&7, x&CTLBITS); + return (x&CTLBITS); /* delete the control bits */ +} + +#endif diff -ruN linux-2.2.5,pristine/net/cipe/idea-i386.S linux-2.2.5/net/cipe/idea-i386.S --- linux-2.2.5,pristine/net/cipe/idea-i386.S Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/idea-i386.S Thu Apr 1 23:05:46 1999 @@ -0,0 +1,150 @@ +/* + IDEA in i386 assembler (for gcc) + Author: Olaf Titz <olaf@bigred.inka.de> + + Follows the API defined in Richard De Moliner's reference + implementation. + + Provides function Idea_Crypt. + $Id: idea-i386.S,v 1.3 1997/03/31 22:07:01 olaf Exp $ +*/ + +#define Idea_nofRound 8 + +#ifdef ASM_Idea_Crypt + +#ifndef __ASSEMBLY__ +#define __ASSEMBLY__ +#endif +#include <linux/linkage.h> + +/* + IDEA is completely 16-bit operations. In a 32-bit segment, this + means the code gets bulky from the many size prefixes. Perhaps + this should be optimized a bit. +*/ + +/* + Primitive operations: add/multiply in the next key element. + I'm taking advantage of the fact that the multiply operation is only + used for key material, and key material is used sequentially. + Key is in (%esi). +*/ + +/* add key into x */ +#define AddK(x) \ + lodsw; \ + addw %ax, x + +/* multiply key with x, result in %ax */ +#define MulK0(x) \ + lodsw; \ + mulw x; \ + subw %dx, %ax; \ + jz 1f; \ + adcw $0, %ax; \ + jmp 2f; \ +1: movw $1, %ax; \ + subw x, %ax; \ + subw -2(%esi), %ax; \ +2: + +/* multiply key into x */ +#define MulK(x) \ + MulK0(x); \ + movw %ax, x + +/* + load/store data operations in correct byte order. i386 is little-endian. + For the key, the byte order is set by Idea_ExpandUserKey(). +*/ + +/* load data element into x */ +#define LodX(x) \ + lodsw; \ + xchgb %al, %ah; \ + movw %ax, x + +/* store %ax into data element */ +#define StoX \ + xchgb %al, %ah; \ + stosw + +/* + void Idea_Crypt (Idea_Data dataIn, Idea_Data dataOut, Idea_Key key); +*/ + +ENTRY(Idea_Crypt) + pushl %ebx + pushl %ebp + pushl %esi + pushl %edi +#define SAVE 16 /* no. of bytes the saved registers occupy */ + +/* arguments relative to %esp */ +#define dataIn SAVE+4 +#define dataOut SAVE+8 +#define key SAVE+12 +/* local variables */ +#define X0 (%edi) +#define X1 %bx +#define X2 %cx +#define X3 %bp +#define RC dataIn(%esp) /* abuse this */ + + cld + movl dataIn(%esp), %esi + movl dataOut(%esp), %edi + LodX(X0) + LodX(X1) + LodX(X2) + LodX(X3) + movl key(%esp), %esi + movw $Idea_nofRound, RC + .align 2,0x90 + + /* Rounds 0-7 */ +7: + MulK(X0) + AddK(X1) + AddK(X2) + MulK(X3) + pushw X1 /* T0 */ + pushw X2 /* T1 */ + xorw X0, X2 + xorw X3, X1 + MulK(X2) + addw X2, X1 + MulK(X1) + addw X1, X2 + xorw X1, X0 + xorw X2, X3 + popw %ax /* T1 */ + xorw %ax, X1 + popw %ax /* T0 */ + xorw %ax, X2 + decw RC + jnz 7b + + /* Round 8 */ + MulK0(X0) + StoX + lodsw + addw X2, %ax + StoX + lodsw + addw X1, %ax + StoX + MulK0(X3) + StoX + + popl %edi + popl %esi + popl %ebp + popl %ebx + ret +#undef dataIn +#undef dataOut +#undef key + +#endif ASM_Idea_Crypt diff -ruN linux-2.2.5,pristine/net/cipe/idea0.c linux-2.2.5/net/cipe/idea0.c --- linux-2.2.5,pristine/net/cipe/idea0.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/idea0.c Thu Apr 1 23:05:46 1999 @@ -0,0 +1,217 @@ +/******************************************************************************/ +/* */ +/* I N T E R N A T I O N A L D A T A E N C R Y P T I O N A L G O R I T H M */ +/* */ +/******************************************************************************/ +/* Author: Richard De Moliner (demoliner@isi.ee.ethz.ch) */ +/* Signal and Information Processing Laboratory */ +/* Swiss Federal Institute of Technology */ +/* CH-8092 Zuerich, Switzerland */ +/* Created: April 23, 1992 */ +/* Changes: November 16, 1993 (support of ANSI-C and C++) */ +/* System: SUN SPARCstation, SUN acc ANSI-C-Compiler, SUN-OS 4.1.3 */ +/******************************************************************************/ +#include "idea0.h" +#include <asm/byteorder.h> +#ifndef __KERNEL__ +#include <netinet/in.h> +#endif + +#define mulMod 0x10001 /* 2**16 + 1 */ +#define ones 0xFFFF /* 2**16 - 1 */ + +/******************************************************************************/ +/* Multiplication in the multiplicative group, a = a * b */ +/* pre: 0 <= a <= 0xFFFF. */ +/* 0 <= b <= 0xFFFF. */ +/* post: 'a' and 'b' have been modified. */ +/* a = a * b; where '*' is multiplication in the multiplicative group. */ +/* note: This implementation of '*' is not complete. To bee complete the */ +/* result has to bee masked (MUL(a, b); a &= ones;). */ + +#define Mul(a, b) \ + if (a == 0) a = mulMod - b; \ + else if (b == 0) a = mulMod - a; \ + else { \ + a *= b; \ + if ((a & ones) >= (b = a >> 16)) a -= b; \ + else a += mulMod - b; \ + } /* Mul */ + +/******************************************************************************/ +/* Encryption and decryption algorithm IDEA. Depending on the value of 'key' */ +/* 'Idea_Crypt' either encrypts or decrypts 'dataIn'. The result is stored */ +/* in 'dataOut'. */ +/* pre: 'dataIn' contains the plain/cipher-text block. */ +/* 'key' contains the encryption/decryption key. */ +/* post: 'dataOut' contains the cipher/plain-text block. */ + +#ifndef ASM_Idea_Crypt +#ifdef ANSI_C + void Idea_Crypt (Idea_Data dataIn, Idea_Data dataOut, Idea_Key key) +#else + Idea_Crypt (dataIn, dataOut, key) + Idea_Data dataIn; + Idea_Data dataOut; + Idea_Key key; +#endif + +{ register u_int32 x0, x1, x2, x3, t0, t1, t2; + int round; + + x0 = (u_int32)ntohs(*dataIn++); x1 = (u_int32)ntohs(*dataIn++); + x2 = (u_int32)ntohs(*dataIn++); x3 = (u_int32)ntohs(*dataIn); + for (round = Idea_nofRound; round > 0; round--) { + t1 = (u_int32)*key++; + x1 += (u_int32)*key++; + x2 += (u_int32)*key++; x2 &= ones; + t2 = (u_int32)*key++; + Mul(x0, t1); x0 &= ones; + Mul(x3, t2); + t0 = (u_int32)*key++; + t1 = x0 ^ x2; + Mul(t0, t1); t0 &= ones; + t1 = (u_int32)*key++; + t2 = ((x1 ^ x3) + t0) & ones; + Mul(t1, t2); t1 &= ones; + t0 += t1; + x0 ^= t1; x3 ^= t0; x3 &= ones; + t0 ^= x1; x1 = x2 ^ t1; x2 = t0; + } + t0 = (u_int32)*key++; + Mul(x0, t0); + *dataOut++ = htons((u_int16)(x0 & ones)); + *dataOut++ = htons((u_int16)(((u_int32)*key++ + x2) & ones)); + *dataOut++ = htons((u_int16)(((u_int32)*key++ + x1) & ones)); + t0 = (u_int32)*key; + Mul(x3, t0); + *dataOut = htons((u_int16)(x3 & ones)); +} /* Idea_Crypt */ +#endif + +/******************************************************************************/ +/* Multiplicative Inverse by Extended Stein Greatest Common Divisor Algorithm.*/ +/* pre: 0 <= x <= 0xFFFF. */ +/* post: x * MulInv(x) == 1, where '*' is multiplication in the */ +/* multiplicative group. */ + +#ifndef ASM_MulInv +#ifdef ANSI_C + static u_int16 MulInv (u_int16 x) +#else + static u_int16 MulInv (x) + u_int16 x; +#endif + +{ register int32 n1, n2, N, a1, a2, b1, b2; + + if (x <= 1) return x; + n1 = N = (int32)x; n2 = mulMod; + a1 = b2 = 1; a2 = b1 = 0; + do { + while ((n1 & 1) == 0) { + if (a1 & 1) + if (a1 < 0) { a1 += mulMod; b1 -= N; } + else { a1 -= mulMod; b1 += N; } + n1 >>= 1; a1 >>= 1; b1 >>= 1; + } + if (n1 < n2) + do { + n2 -= n1; a2 -= a1; b2 -= b1; + if (n2 == 0) return (u_int16)(a1 < 0 ? a1 + mulMod : a1); + while ((n2 & 1) == 0) { + if (a2 & 1) + if (a2 < 0) { a2 += mulMod; b2 -= N; } + else { a2 -= mulMod; b2 += N; } + n2 >>= 1; a2 >>= 1; b2 >>= 1; + } + } while (n1 <= n2); + n1 -= n2; a1 -= a2; b1 -= b2; + } while (n1); + return (u_int16)(a2 < 0 ? a2 + mulMod : a2); +} /* MulInv */ +#endif + +/******************************************************************************/ +/* Additive Inverse. */ +/* pre: 0 <= x <= 0xFFFF. */ +/* post: x + AddInv(x) == 0, where '+' is addition in the additive group. */ + +#define AddInv(x) (-x & ones) + +/******************************************************************************/ +/* Inverts a decryption/encrytion key to a encrytion/decryption key. */ +/* pre: 'key' contains the encryption/decryption key. */ +/* post: 'invKey' contains the decryption/encryption key. */ + +#ifndef ASM_Idea_InvertKey +#ifdef ANSI_C + void Idea_InvertKey (Idea_Key key, Idea_Key invKey) +#else + Idea_InvertKey (key, invKey) + Idea_Key key; + Idea_Key invKey; +#endif + +{ register u_int16 t, *in, *out; + register int lo, hi, i; + + in = key; out = invKey; + lo = 0; hi = 6 * Idea_nofRound; + t = MulInv(in[lo]); out[lo++] = MulInv(in[hi]); out[hi++] = t; + t = AddInv(in[lo]); out[lo++] = AddInv(in[hi]); out[hi++] = t; + t = AddInv(in[lo]); out[lo++] = AddInv(in[hi]); out[hi++] = t; + t = MulInv(in[lo]); out[lo++] = MulInv(in[hi]); out[hi] = t; + for (i = (Idea_nofRound - 1) / 2 ; i != 0 ; i --) { + t = in[lo]; out[lo++] = in[hi -= 5]; out[hi ++] = t; + t = in[lo]; out[lo++] = in[hi]; out[hi] = t; + t = MulInv(in[lo]); out[lo++] = MulInv(in[hi -= 5]); out[hi++] = t; + t = AddInv(in[lo]); out[lo++] = AddInv(in[++hi]); out[hi--] = t; + t = AddInv(in[lo]); out[lo++] = AddInv(in[hi]); out[hi++] = t; + t = MulInv(in[lo]); out[lo++] = MulInv(in[++hi]); out[hi] = t; + } +#if (Idea_nofRound % 2 == 0) + t = in[lo]; out[lo++] = in[hi -= 5]; out[hi++] = t; + t = in[lo]; out[lo++] = in[hi]; out[hi] = t; + out[lo] = MulInv(in[lo]); lo++; + t = AddInv(in[lo]); out[lo] = AddInv(in[lo + 1]); lo++; out[lo++] = t; + out[lo] = MulInv(in[lo]); +#else + out[lo] = in[lo]; lo++; + out[lo] = in[lo]; +#endif +} /* Idea_InvertKey */ +#endif + +/******************************************************************************/ +/* Expands a user key of 128 bits to a full encryption key */ +/* pre: 'userKey' contains the 128 bit user key */ +/* post: 'key' contains the encryption key */ + +#ifndef ASM_Idea_ExpandUserKey +#ifdef ANSI_C + void Idea_ExpandUserKey (Idea_UserKey userKey, Idea_Key key) +#else + Idea_ExpandUserKey (userKey, key) + Idea_UserKey userKey; + Idea_Key key; +#endif + +{ register int i; + +#if (Idea_keyLen <= Idea_userKeyLen) + for (i = 0; i < Idea_keyLen; i++) key[i] = ntohs(userKey[i]); +#else + for (i = 0; i < Idea_userKeyLen; i++) key[i] = ntohs(userKey[i]); + for (i = Idea_userKeyLen; i < Idea_keyLen; i++) + if ((i & 7) < 6) + key[i] = (key[i - 7] & 127) << 9 | key[i - 6] >> 7; + else if ((i & 7) == 6) + key[i] = (key[i - 7] & 127) << 9 | key[i - 14] >> 7; + else + key[i] = (key[i - 15] & 127) << 9 | key[i - 14] >> 7; +#endif +} /* Idea_ExpandUserKey */ +#endif + +/******************************************************************************/ diff -ruN linux-2.2.5,pristine/net/cipe/idea0.h linux-2.2.5/net/cipe/idea0.h --- linux-2.2.5,pristine/net/cipe/idea0.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/idea0.h Thu Apr 1 23:05:46 1999 @@ -0,0 +1,79 @@ +/******************************************************************************/ +/* */ +/* I N T E R N A T I O N A L D A T A E N C R Y P T I O N A L G O R I T H M */ +/* */ +/******************************************************************************/ +/* Author: Richard De Moliner (demoliner@isi.ee.ethz.ch) */ +/* Signal and Information Processing Laboratory */ +/* Swiss Federal Institute of Technology */ +/* CH-8092 Zuerich, Switzerland */ +/* Created: April 23, 1992 */ +/* Changes: November 16, 1993 (support of ANSI-C and C++) */ +/* System: SUN SPARCstation, SUN acc ANSI-C-Compiler, SUN-OS 4.1.3 */ +/******************************************************************************/ +/* Change this type definitions to the representations in your computer. */ + +typedef long int32; /* signed 32-bit integer (or larger) */ +typedef unsigned long u_int32; /* unsigned 32-bit integer (or larger)*/ +typedef unsigned short u_int16; /* unsigned 16-bit integer (or larger)*/ +typedef unsigned char u_int8; /* unsigned 8-bit integer */ + +#define ANSI_C /* If 'ANSI_C' is defined the preprocessed */ + /* source code is ANSI-C or C++ code, other- */ + /* wise it is Kerninghan & Ritchie C code. */ + +/******************************************************************************/ +/* It is possible to change this values. */ + +#define Idea_nofRound 8 /* number of rounds */ +#define Idea_userKeyLen 8 /* user key length (8 or larger) */ + +/******************************************************************************/ +/* Do not change the lines below. */ + +#define Idea_dataLen 4 /* plain-/ciphertext block length*/ +#define Idea_keyLen (Idea_nofRound * 6 + 4) /* en-/decryption key length */ + +#define Idea_dataSize (Idea_dataLen * 2) /* 8 bytes = 64 bits */ +#define Idea_userKeySize (Idea_userKeyLen * 2) /* 16 bytes = 128 bits */ +#define Idea_keySize (Idea_keyLen * 2) /* 104 bytes = 832 bits */ + +typedef u_int16 Idea_Data[Idea_dataLen]; +typedef u_int16 Idea_UserKey[Idea_userKeyLen]; +typedef u_int16 Idea_Key[Idea_keyLen]; + +/******************************************************************************/ +/* void Idea_Crypt (Idea_Data dataIn, Idea_Data dataOut, Idea_Key key) */ +/* */ +/* Encryption and decryption algorithm IDEA. Depending on the value of 'key' */ +/* 'Idea_Crypt' either encrypts or decrypts 'dataIn'. The result is stored */ +/* in 'dataOut'. */ +/* pre: 'dataIn' contains the plain/cipher-text block. */ +/* 'key' contains the encryption/decryption key. */ +/* post: 'dataOut' contains the cipher/plain-text block. */ +/* */ +/******************************************************************************/ +/* void Idea_InvertKey (Idea_Key key, Idea_Key invKey) */ +/* */ +/* Inverts a decryption/encrytion key to a encrytion/decryption key. */ +/* pre: 'key' contains the encryption/decryption key. */ +/* post: 'invKey' contains the decryption/encryption key. */ +/* */ +/******************************************************************************/ +/* void Idea_ExpandUserKey (Idea_UserKey userKey, Idea_Key key) */ +/* */ +/* Expands a user key of 128 bits to a full encryption key */ +/* pre: 'userKey' contains the 128 bit user key */ +/* post: 'key' contains the encryption key */ +/* */ +/******************************************************************************/ + +#ifdef ANSI_C + void Idea_Crypt (Idea_Data dataIn, Idea_Data dataOut, Idea_Key key); + void Idea_InvertKey (Idea_Key key, Idea_Key invKey); + void Idea_ExpandUserKey (Idea_UserKey userKey, Idea_Key key); +#else + Idea_Crypt (); + Idea_InvertKey (); + Idea_ExpandUserKey (); +#endif diff -ruN linux-2.2.5,pristine/net/cipe/ioctl.c linux-2.2.5/net/cipe/ioctl.c --- linux-2.2.5,pristine/net/cipe/ioctl.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/ioctl.c Thu Apr 1 23:05:46 1999 @@ -0,0 +1,61 @@ +/* + CIPE - encrypted IP over UDP tunneling + + ioctl.c - ioctl interface, user side + + Copyright 1996 Olaf Titz <olaf@bigred.inka.de> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. +*/ +/* $Id: ioctl.c,v 1.3 1998/11/14 20:48:02 olaf Exp $ */ + +#include "cipe.h" +#include "ioctl.h" +#include "version.h" +#include <net/if.h> +#include <sys/ioctl.h> + +#define IFRSETUP \ + struct ifreq ifr; \ + strcpy(ifr.ifr_name, ifname); \ + sio->magic=VERSION_MAGIC; \ + ifr.ifr_data=(void*)sio; + +int ioctl_getpar(int fd, char *ifname, struct siocgifcippar *sio) +{ + IFRSETUP; + return ioctl(fd, SIOCGIFCIPPAR, &ifr); +} + +int ioctl_setpar(int fd, char *ifname, struct siocsifcippar *sio) +{ + IFRSETUP; + return ioctl(fd, SIOCSIFCIPPAR, &ifr); +} + +int ioctl_setkey(int fd, char *ifname, struct siocsifcipkey *sio) +{ + IFRSETUP; + return ioctl(fd, SIOCSIFCIPKEY, &ifr); +} + +int ioctl_attach(int fd, char *ifname, struct siocsifcipatt *sio) +{ + IFRSETUP; + return ioctl(fd, SIOCSIFCIPATT, &ifr); +} + +int ioctl_alloc(int fd, char *ifname, struct siocsifcipall *sio) +{ + IFRSETUP; + return ioctl(fd, SIOCSIFCIPALL, &ifr); +} + +int ioctl_unalloc(int fd, char *ifname, struct siocsifcipall *sio) +{ + IFRSETUP; + return ioctl(fd, SIOCSIFCIPUNA, &ifr); +} diff -ruN linux-2.2.5,pristine/net/cipe/ioctl.h linux-2.2.5/net/cipe/ioctl.h --- linux-2.2.5,pristine/net/cipe/ioctl.h Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/ioctl.h Thu Apr 1 23:05:46 1999 @@ -0,0 +1,22 @@ +/* + CIPE - encrypted IP over UDP tunneling + + ioctl.h - prototype for the ioctl interface, user part + + Copyright 1996 Olaf Titz <olaf@bigred.inka.de> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. +*/ +/* $Id: ioctl.h,v 1.2 1998/08/22 16:05:51 olaf Exp $ */ + +#include "cipe.h" + +extern int ioctl_getpar(int fd, char *ifname, struct siocgifcippar *sio); +extern int ioctl_setpar(int fd, char *ifname, struct siocsifcippar *sio); +extern int ioctl_setkey(int fd, char *ifname, struct siocsifcipkey *sio); +extern int ioctl_attach(int fd, char *ifname, struct siocsifcipatt *sio); +extern int ioctl_alloc(int fd, char *ifname, struct siocsifcipall *sio); +extern int ioctl_unalloc(int fd, char *ifname, struct siocsifcipall *sio); diff -ruN linux-2.2.5,pristine/net/cipe/module.c linux-2.2.5/net/cipe/module.c --- linux-2.2.5,pristine/net/cipe/module.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/module.c Thu Apr 1 23:05:46 1999 @@ -0,0 +1,51 @@ +/* + CIPE - encrypted IP over UDP tunneling + + module.c - kernel module interface stuff + + Copyright 1996 Olaf Titz <olaf@bigred.inka.de> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. +*/ +/* $Id: module.c,v 1.3 1998/10/18 15:38:41 olaf Exp $ */ + +#include "cipe.h" +#include <linux/module.h> + +/* We put this all here so that none of the other source files needs + to include <linux/module.h>, which could lead to collisions. */ + +#ifdef LINUX_21 +MODULE_AUTHOR("Olaf Titz <olaf@bigred.inka.de>"); +MODULE_DESCRIPTION("Encrypting IP-over-UDP tunnel"); +MODULE_SUPPORTED_DEVICE(DEVNAME); +MODULE_PARM(cipe_maxdev,"i"); +MODULE_PARM_DESC(cipe_maxdev,"Maximum device number supported"); +#ifdef DEBUG +MODULE_PARM(cipe_debug,"i"); +MODULE_PARM_DESC(cipe_debug,"Debugging level"); +#endif +#endif + +void cipe_use_module(void) +{ + MOD_INC_USE_COUNT; +} + +void cipe_unuse_module(void) +{ + MOD_DEC_USE_COUNT; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,0,30) +/* older kernel not always exported this */ + +int bad_user_access_length(void) +{ + panic("bad_user_access_length in " DEVNAME); +} + +#endif diff -ruN linux-2.2.5,pristine/net/cipe/output.c linux-2.2.5/net/cipe/output.c --- linux-2.2.5,pristine/net/cipe/output.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/output.c Thu Apr 1 23:05:46 1999 @@ -0,0 +1,528 @@ +/* + CIPE - encrypted IP over UDP tunneling + + output.c - the sending part of the CIPE device + + Copyright 1996 Olaf Titz <olaf@bigred.inka.de> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. +*/ +/* $Id: output.c,v 1.20 1998/09/22 20:24:00 olaf Exp $ */ + +#include "cipe.h" + +#include <net/ip.h> +#include <net/icmp.h> +#include <linux/if.h> +#include <linux/if_arp.h> +#include <linux/socket.h> +#include <linux/version.h> + +#ifdef DEBUG +void cipe_dump_packet(char *title, struct sk_buff *skb) +{ + short i; + unsigned char *bp=(unsigned char*)skb->data; + char b[60]; + static __u16 p[16]={0,2,5,7,10,12,15,17,21,23,26,28,31,33,36,38}; + static char h[16]="0123456789abcdef"; + + printk(KERN_DEBUG +#ifdef LINUX_21 + "%s: packet len=%x dev=%s\n", +#else + "%s: packet len=%lx dev=%s\n", +#endif + title, skb->len, skb->dev?skb->dev->name:"<none>"); + i = 0; + memset(b, ' ', sizeof(b)); + b[sizeof(b)-1]=0; + while (bp<(unsigned char *)skb->tail) { + if (i>15) { + printk(KERN_DEBUG " %s\n", b); + memset(b, ' ', sizeof(b)); + b[sizeof(b)-1]=0; + i=0; + } + b[p[i]]=h[*bp>>4]; b[p[i]+1]=h[*bp&15]; + b[i+42]=(((*bp)&0x60)==0)?'.':*bp; + ++bp; ++i; + } + printk(KERN_DEBUG " %s\n", b); +} +#endif + +#ifdef LINUX_21 + +/* An adapted version of Linux 2.1 net/ipv4/ipip.c output routine. */ + +int cipe_xmit(struct sk_buff *skb, struct device *dev) +{ + struct cipe *tunnel = (struct cipe*)(dev->priv); + struct rtable *rt = NULL; /* Route to the other host */ + struct device *tdev; /* Device to other host */ + struct iphdr *old_iph = skb->nh.iph; + u16 df = old_iph->frag_off; + u8 tos = old_iph->tos; + struct iphdr *iph; /* Our new IP header */ + struct udphdr *udph; + int max_headroom; /* The extra header space needed */ + int max_tailroom; + u32 dst = tunnel->peeraddr; + int mtu; + int length = ntohs(skb->nh.iph->tot_len); + + dprintk(DEB_OUT, (KERN_INFO "%s: cipe_xmit() len=%d(%d)\n", dev->name, + length, skb->len)); + if (tunnel->magic!=CIPE_MAGIC) { + printk(KERN_ERR DEVNAME + ": cipe_xmit() called with wrong struct\n"); + return 0; + } + + if (tunnel->recursion++) { + printk(KERN_ERR "%s: cipe_xmit() reentrance\n", dev->name); + tunnel->stat.collisions++; + goto tx_error; + } + + if (skb->protocol != __constant_htons(ETH_P_IP)) + goto tx_error; + +#if 0 + dprintk(DEB_OUT, (KERN_DEBUG "routing dst=%08lX src=%08lX tos=%x oif=%d\n", + dst, tunnel->myaddr, RT_TOS(tos), tunnel->sock->bound_dev_if)); +#endif + if (ip_route_output(&rt, dst, tunnel->myaddr, RT_TOS(tos), + tunnel->sock->bound_dev_if)) { + dprintk(DEB_OUT, (KERN_NOTICE "%s: no route\n", dev->name)); + tunnel->stat.tx_carrier_errors++; + goto tx_error_icmp; + } + tdev = rt->u.dst.dev; + dprintk(DEB_OUT, (KERN_DEBUG "route dev=%s flags=%x type=%x\n", + tdev->name, rt->rt_flags, rt->rt_type)); + + if (tdev == dev) { + printk(KERN_ERR "%s: looped route\n", dev->name); + tunnel->stat.collisions++; + goto tx_error; + } + + mtu = rt->u.dst.pmtu - (cipehdrlen+cipefootlen); + if (tunnel->sockshost) + mtu -= sizeof(struct sockshdr); + + if (mtu < 68) { + printk(KERN_ERR "%s: MTU too small\n", dev->name); + tunnel->stat.collisions++; + goto tx_error; + } + if (skb->dst && mtu < skb->dst->pmtu) + skb->dst->pmtu = mtu; + + if ((old_iph->frag_off&__constant_htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) { + dprintk(DEB_OUT, (KERN_NOTICE "%s: fragmentation needed\n", dev->name)); + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); + goto tx_error; + } + +#if 0 + if (tunnel->err_count > 0) { + if (jiffies - tunnel->err_time < IPTUNNEL_ERR_TIMEO) { + tunnel->err_count--; + dst_link_failure(skb); + } else + tunnel->err_count = 0; + } +#endif + +#ifdef DEBUG + if (cipe_debug&DEB_PKOU) + cipe_dump_packet("original", skb); +#endif + + max_headroom = (((tdev->hard_header_len+15)&~15)+cipehdrlen+ + ((tunnel->sockshost) ? sizeof(struct sockshdr) : 0)); + max_tailroom = (tunnel->havekey) ? cipefootlen : 0; + { + unsigned long offset; + struct sk_buff *n= + alloc_skb(skb->len+max_headroom+max_tailroom, GFP_ATOMIC); + if (!n) { + printk(KERN_INFO "%s: Out of memory, dropped packet\n", + dev->name); + goto tx_error; + } + skb_reserve(n, max_headroom); + /* Copy the packet over. From skb_realloc_headroom() */ + offset=n->data-skb->data; + skb_put(n,skb->len); + /* Copy the bytes */ + memcpy(n->data,skb->data,skb->len); + n->list=NULL; + n->sk=NULL; + n->priority=skb->priority; + n->protocol=skb->protocol; + n->dev=skb->dev; + n->dst=dst_clone(skb->dst); + n->h.raw=skb->h.raw+offset; + n->nh.raw=skb->nh.raw+offset; + n->mac.raw=skb->mac.raw+offset; + memcpy(n->cb, skb->cb, sizeof(skb->cb)); + n->used=skb->used; + n->is_clone=0; + atomic_set(&n->users, 1); + n->pkt_type=skb->pkt_type; + n->stamp=skb->stamp; + n->destructor = NULL; + n->security=skb->security; + + dev_kfree_skb(skb); + skb = n; + } + + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); + dst_release(skb->dst); + skb->dst = &rt->u.dst; + skb->protocol = htons(ETH_P_IP); + + if (tunnel->havekey) { +#ifndef VER_SHORT + /* Add an IV */ + cipe_cryptpad(skb_push(skb, blockSize)); + length+=blockSize; +#endif + cipe_encrypt(tunnel, skb->data, &length, TW_DATA); + /* This is incorrect - the tail room gets first used and then + reserved. Doesn't matter in the current (2.0.29) implementation + of skb_put though. Alternative solution would ruin the nice + module separation - we don't need to know the real amount + of padding here. */ + (void) skb_put(skb, length-skb->len); + } else if (!tunnel->mayclear) { + goto tx_error; + } + + if (tunnel->sockshost) { + /* Install a SOCKS header */ + struct sockshdr *sh = (struct sockshdr *) + skb_push(skb, sizeof(struct sockshdr)); + memset(sh, 0, 4); + sh->atyp=1; + /* sockshost and socksport contain the real peer's address + and the configured/guessed peer is really the socks relayer! */ + sh->dstaddr=tunnel->sockshost; + sh->dstport=tunnel->socksport; + length+=sizeof(struct sockshdr); + } + + /* Install our new headers */ + udph = (struct udphdr *) skb_push(skb, sizeof(struct udphdr)); + /*** skb->nh.raw = */ + iph = skb->nh.iph = (struct iphdr *) skb_push(skb, sizeof(struct iphdr)); + + /* + * Push down and install the CIPE/UDP header. + */ + iph->version = 4; + iph->ihl = sizeof(struct iphdr)>>2; + iph->tos = tos; + iph->tot_len = htons(skb->len); + iph->id = htons(ip_id_count++); + iph->frag_off = df; + iph->ttl = tunnel->cttl ? tunnel->cttl : old_iph->ttl; + iph->protocol = IPPROTO_UDP; + iph->saddr = rt->rt_src; + iph->daddr = rt->rt_dst; + + ip_send_check(iph); + + udph->source = tunnel->myport; + udph->dest = tunnel->peerport; + udph->len = htons(length+sizeof(struct udphdr)); + /* Encrypted packets are checksummed already, so we can safely + ignore the UDP checksum */ + udph->check = 0; + + tunnel->stat.tx_bytes += skb->len; + tunnel->stat.tx_packets++; + dprintk(DEB_OUT, (KERN_INFO + "%s: sending %d from %08lX:%d to %08lX:%d\n", + dev->name, skb->len, + ntohl(iph->saddr), ntohs(udph->source), + ntohl(iph->daddr), ntohs(udph->dest))); +#if 0 + dprintk(DEB_OUT, (KERN_INFO "dst: (%d,%d) %s %d %d\n", + skb->dst->refcnt, skb->dst->use, + skb->dst->dev->name, skb->dst->pmtu, + skb->dst->error)); +#endif +#ifdef DEBUG + if (cipe_debug&DEB_PKOU) + cipe_dump_packet("sending", skb); +#endif + ip_send(skb); + ip_rt_put(rt); + tunnel->recursion--; + return 0; + + tx_error_icmp: + dst_link_failure(skb); + tx_error: + ip_rt_put(rt); + tunnel->stat.tx_errors++; + dev_kfree_skb(skb); + tunnel->recursion--; + return 0; +} + +#else /* LINUX_21 */ + +/* An adapted version of Linux 2.0 drivers/net/new_tunnel.c. */ + +#ifdef SO_BINDTODEVICE + #define iproute(t,o,d) ip_rt_route(t,o,d) +#else + #define iproute(t,o,d) ip_rt_route(t,o) +#endif + +#if LINUX_VERSION_CODE < 131102 /* < 2.0.30 */ + #include <linux/config.h> + #ifdef CONFIG_IP_FORWARD + #define ipforward(s,d,o,t) ip_forward(s,d,o,t) + #else + #error "Requires IP forwarding enabled in kernel" + #endif +#else /* >= 2.0.30 */ + #define ipforward(s,d,o,t) (sysctl_ip_forward ? ip_forward(s,d,o,t) : -1) +#endif + +int cipe_xmit(struct sk_buff *skb, struct device *dev) +{ + struct enet_statistics *stats; /* This device's statistics */ + struct rtable *rt; /* Route to the other host */ + struct device *tdev; /* Device to other host */ + struct iphdr *iph; /* Our new IP header */ + struct udphdr *udph; + __u32 target; /* The other host's IP address */ + int max_headroom; /* The extra header space needed */ + int max_tailroom; + int tos, ttl, length; + DEVTOCIPE(dev,c,0); + + if (skb == NULL || dev == NULL) { + dprintk1(DEB_OUT, KERN_INFO, "%s: nothing to do\n", dev->name); + return 0; + } + + /* + * Make sure we are not busy (check lock variable) + */ + stats = &(c->stat); + if (dev->tbusy != 0) + { + printk(KERN_WARNING "%s: device timeout (really possible?)\n", + dev->name); + dev->tbusy=0; + stats->tx_errors++; + return(1); + } + +#ifdef DEBUG + if (cipe_debug&DEB_PKOU) + cipe_dump_packet("original", skb); +#endif + /* + * First things first. Look up the destination address in the + * routing tables + */ + target = c->peeraddr; + if ((!target) || (!c->peerport) || (!c->myport)) { + /* unconfigured device */ + printk(KERN_INFO "%s: unconfigured\n", dev->name); + goto error; + } + if ((rt = iproute(target, 0, skb->sk?skb->sk->bound_device:NULL)) == NULL) + { + /* No route to host */ + printk(KERN_INFO "%s: target unreachable\n", dev->name); + goto error; + } + dprintk5(DEB_OUT, KERN_INFO, + "%s: routing to %08lX from %08lX via %08lX dev %s\n", + dev->name, ntohl(rt->rt_dst), ntohl(rt->rt_src), + ntohl(rt->rt_gateway), rt->rt_dev->name); + + tdev = rt->rt_dev; + ip_rt_put(rt); + + if (tdev == dev) + { + /* Tunnel to ourselves? -- I don't think so. */ + printk ( KERN_INFO "%s: Packet targetted at myself!\n" , dev->name); + goto error; + } + + /* + * Okay, now see if we can stuff it in the buffer as-is. We can not. + */ + max_headroom = (((tdev->hard_header_len+15)&~15)+cipehdrlen+ + ((c->sockshost) ? sizeof(struct sockshdr) : 0)); + max_tailroom = (c->havekey) ? cipefootlen : 0; + { + struct sk_buff *new_skb; + + if ( !(new_skb = + dev_alloc_skb(skb->len+max_headroom+max_tailroom)) ) + { + printk(KERN_INFO "%s: Out of memory, dropped packet\n", + dev->name); + dev->tbusy = 0; + stats->tx_dropped++; + dev_kfree_skb(skb, FREE_WRITE); + return 0; + } + new_skb->free = 1; + + /* + * Reserve space for our header and the lower device header + */ + skb_reserve(new_skb, max_headroom); + + /* + * Copy the old packet to the new buffer. + * Note that new_skb->h.iph will be our (tunnel driver's) header + * and new_skb->ip_hdr is the IP header of the old packet. + */ + new_skb->ip_hdr = (struct iphdr *) skb_put(new_skb, skb->len); + new_skb->mac.raw = new_skb->data; + new_skb->dev = skb->dev; + memcpy(new_skb->ip_hdr, skb->data, skb->len); + memset(new_skb->proto_priv, 0, sizeof(skb->proto_priv)); + + /* Free the old packet, we no longer need it */ + dev_kfree_skb(skb, FREE_WRITE); + skb = new_skb; + } + + tos = skb->ip_hdr->tos; + ttl = skb->ip_hdr->ttl; + length = skb->len; + if (c->havekey) { +#ifndef VER_SHORT + /* Add an IV */ + cipe_cryptpad(skb_push(skb, blockSize)); + length+=blockSize; +#endif + cipe_encrypt(c, skb->data, &length, TW_DATA); + /* This is incorrect - the tail room gets first used and then + reserved. Doesn't matter in the current (2.0.29) implementation + of skb_put though. Alternative solution would ruin the nice + module separation - we don't need to know the real amount + of padding here. */ + (void) skb_put(skb, length-skb->len); + } else if (!c->mayclear) { + goto error; + } + + if (c->sockshost) { + /* Install a SOCKS header */ + struct sockshdr *sh = (struct sockshdr *) + skb_push(skb, sizeof(struct sockshdr)); + memset(sh, 0, 4); + sh->atyp=1; + /* sockshost and socksport contain the real peer's address + and the configured/guessed peer is really the socks relayer! */ + sh->dstaddr=c->sockshost; + sh->dstport=c->socksport; + length+=sizeof(struct sockshdr); + } + + /* Install our new headers */ + udph = (struct udphdr *) skb_push(skb, sizeof(struct udphdr)); + skb->h.iph = (struct iphdr *) skb_push(skb, sizeof(struct iphdr)); + + /* + * Push down and install the CIPE/UDP header. + */ + + iph = skb->h.iph; + iph->version = 4; + iph->tos = tos; + + /* In new_tunnel.c, we use the original packet's TTL here. + Setting a new TTL behaves better to the user, and RFC2003 + recommends it too. But this doesn't fully protect against + routing loops. So make it configurable via an argument: + "cttl" gives the TTL value; if 0 use the packet's + value. Default should be 64, as with the other protocols + (ip_statistics.IpDefaultTTL, but this variable is not + available for modules). */ + + iph->ttl = c->cttl ? c->cttl : ttl; + + iph->frag_off = 0; + iph->daddr = target; + iph->saddr = c->myaddr; /* tdev->pa_addr; */ + iph->protocol = IPPROTO_UDP; + iph->ihl = 5; + iph->tot_len = htons(skb->len); + iph->id = htons(ip_id_count++); /* Race condition here? */ + ip_send_check(iph); + + udph->source = c->myport; + udph->dest = c->peerport; + udph->len = htons(length+sizeof(struct udphdr)); + /* Encrypted packets are checksummed already, so we can safely + ignore the UDP checksum */ + udph->check = 0; + + skb->ip_hdr = skb->h.iph; + skb->protocol = htons(ETH_P_IP); + + /* + * Send the packet on its way! + * Note that dev_queue_xmit() will eventually free the skb. + * If ip_forward() made a copy, it will return 1 so we can free. + */ + + dprintk3(DEB_OUT, KERN_INFO, "%s: send to %08lX via %s\n", + dev->name, ntohl(target), tdev->name); + +#ifdef DEBUG + if (cipe_debug&DEB_PKOU) + cipe_dump_packet("sending", skb); +#endif + switch (ipforward(skb, dev, IPFWD_NOTTLDEC, target)) { + case -1: + printk(KERN_INFO "%s: forwarding failed\n", dev->name); + /* fall thru */ + case 1: + dev_kfree_skb(skb, FREE_WRITE); + /* Does it really need dev_ here? I think so. */ + break; + default: + /* nothing to do */ + } + + /* + * Clean up: We're done with the route and the packet + */ + + /* Record statistics and return */ + stats->tx_packets++; + dev->tbusy=0; + return 0; + + error: + stats->tx_errors++; + dev_kfree_skb(skb, FREE_WRITE); + dev->tbusy=0; + return 0; +} + +#endif /* LINUX_21 */ diff -ruN linux-2.2.5,pristine/net/cipe/samples/README linux-2.2.5/net/cipe/samples/README --- linux-2.2.5,pristine/net/cipe/samples/README Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/samples/README Thu Apr 1 23:05:46 1999 @@ -0,0 +1 @@ +Here are samples for the files that go into /etc/cipe. diff -ruN linux-2.2.5,pristine/net/cipe/samples/ip-down linux-2.2.5/net/cipe/samples/ip-down --- linux-2.2.5,pristine/net/cipe/samples/ip-down Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/samples/ip-down Thu Apr 1 23:05:46 1999 @@ -0,0 +1,18 @@ +#!/bin/sh +# ip-down <interface> <myaddr> <daemon-pid> <local> <remote> <arg> + +# Sample of the ip-down script. +# This is called with the same arguments as ip-up after the device was +# closed. It can be used for removing proxyarps, or (like here) +# for logging purposes, etc. + +# Logging example +echo "DOWN $*" >> /var/adm/cipe.log + +# remove the daemon pid file +rm -f /var/run/$1.pid + +# If the system runs gated, tell it what has happened +#gdc interface + +exit 0 diff -ruN linux-2.2.5,pristine/net/cipe/samples/ip-up linux-2.2.5/net/cipe/samples/ip-up --- linux-2.2.5,pristine/net/cipe/samples/ip-up Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/samples/ip-up Thu Apr 1 23:05:46 1999 @@ -0,0 +1,57 @@ +#!/bin/sh +# ip-up <interface> <myaddr> <daemon-pid> <local> <remote> <arg> + +# Sample of the ip-up script. +# This is called when the CIPE interface is opened. +# Arguments: +# $1 interface the CIPE interface +# $2 myaddr our UDP address +# $3 daemon-pid the daemon's process ID +# $4 local IP address of our CIPE device +# $5 remote IP address of the remote CIPE device +# $6 arg argument supplied via options + +# Purposes for this script: set up routes, set up proxy-arps, etc. +# start daemons, logging... + +umask 022 +PATH=/sbin:/bin:/usr/sbin:/usr/bin + +if [ "`uname -r | cut -d. -f1-2`" = "2.0" ]; then + # Under Linux 2.0, a minimal route to the remote CIPE is needed. + # 2.1 sets this one by itself. + route add -host $5 dev $1 +fi + +# If this becomes our default route... +#route add default gw $5 + +# just a logging example +echo "UP $*" >> /var/adm/cipe.log + +# many systems like these pid files +echo $3 > /var/run/$1.pid + +# Trigger the key exchange procedure, useful when we're using SOCKS +# This _must_ run delayed and in the background +#(sleep 10; ping -c5 $5) & + +# If the system runs gated, tell it what has happened +#gdc interface + +# The following are just ideas for further consideration + +# Interconnect two 10. subnets through the Internet! +# Assuming $4 is in 10.1 and $5 in 10.2 +#route add -net 10.2.0.0 netmask 255.255.0.0 gw $5 + +# Proxy-ARP the peer's address on eth0 +#arp -s $5 -D eth0 pub + +# Evil tricks department: masquerade the CIPE peer's /24 network to our IP +#NA=`expr $5 : '\([0-9]*\.[0-9]*\.[0-9]*\.\)'` +#ipfwadm -F -a accept -m -b -S $NA.0/24 -D 0.0.0.0/0 +# the usual way for this would be a case selection on $5 or $6, however + + +exit 0 diff -ruN linux-2.2.5,pristine/net/cipe/samples/options linux-2.2.5/net/cipe/samples/options --- linux-2.2.5,pristine/net/cipe/samples/options Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/samples/options Thu Apr 1 23:05:46 1999 @@ -0,0 +1,18 @@ +# Surprise, this file allows comments (but only on a line by themselves) + +# This is probably the minimal set of options that has to be set + +# device name +device cip3b0 +# the peer's IP address +ptpaddr 6.5.4.3 +# our CIPE device's IP address +ipaddr 6.7.8.9 +# my UDP address. Note: if you set port 0 here, the system will pick +# one and tell it to you via the ip-up script. Same holds for IP 0.0.0.0. +me bigred.inka.de:6789 +# ...and the UDP address we connect to. Of course no wildcards here. +peer blackforest.inka.de:6543 +# The static key. Keep this file secret! +# The key is 128 bits in hexadecimal notation. +key 3248fd20adf9c00ccf9ecc2393bbb3e4 diff -ruN linux-2.2.5,pristine/net/cipe/sock.c linux-2.2.5/net/cipe/sock.c --- linux-2.2.5,pristine/net/cipe/sock.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/sock.c Thu Apr 1 23:05:46 1999 @@ -0,0 +1,628 @@ +/* + CIPE - encrypted IP over UDP tunneling + + sock.c - socket/input interface + + Copyright 1996 Olaf Titz <olaf@bigred.inka.de> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. +*/ +/* $Id: sock.c,v 1.17 1998/09/23 23:11:59 olaf Exp $ */ + +#include "cipe.h" + +#include <linux/config.h> +#include <linux/if.h> +#include <linux/sched.h> +#include <net/sock.h> +#include <net/ip.h> +#ifdef LINUX_21 +#include <asm/uaccess.h> +#else +typedef unsigned short mm_segment_t; +#endif + +#ifdef LINUX_21 +#define kfreeskb(s,t) kfree_skb(s) +#define saddr(skb) ((skb)->nh.iph->saddr) +#define daddr(skb) ((skb)->nh.iph->daddr) +#else +#define kfreeskb(s,t) kfree_skb(s,t) +#define saddr(skb) ((skb)->saddr) +#define daddr(skb) ((skb)->daddr) +#endif + +/* Rewire generic socket operations to our device-specific ones. + We have new routines for close, sendmsg, recvmsg. */ + +/* init struct cipe *c based on struct sock *sk */ +#ifdef LINUX_21 + +#define SOCKTOC(nam,sk,c,r) \ + struct cipe *c=(struct cipe *)sk->user_data; \ + if ((!c) || (c->magic!=CIPE_MAGIC)) { \ + printk(KERN_ERR "Ouch: SOCKTOC" nam "\n"); return r; } \ + else { \ + dprintk(DEB_CALL, (KERN_INFO "%s: " nam "\n", c->dev->name)); } + +#else + +#define SOCKTOC(nam,sk,c,r) \ + struct cipe *c=(struct cipe *)sk->protinfo.af_packet.bound_dev; \ + if ((!c) || (c->magic!=CIPE_MAGIC)) { \ + printk(KERN_ERR "Ouch: SOCKTOC" nam "\n"); return r; } \ + else { \ + dprintk(DEB_CALL, (KERN_INFO "%s: " nam "\n", c->dev->name)); } + +#endif + +/* Close the socket */ +void cipe_sock_close(struct sock *sock, unsigned long timeout) +{ + SOCKTOC("sock_close",sock,c,); + c->sock=NULL; + + /* Put back the old protocol block and let it do the close */ + sock->prot=c->udp_prot; + sock->prot->close(sock, timeout); + if (c->dev->flags&IFF_UP) + dev_close(c->dev); + else + cipe_close(c); + cipe_unuse_module(); +} + +/* Anything we send to this socket is in fact a key exchange block. + Encode and encrypt it accordingly. +*/ +int cipe_sendmsg(struct sock *sock, struct msghdr *msg, int len +#ifndef LINUX_21 + , int nonblock, int flags +#endif + ) +{ + struct msghdr mymsg; + struct iovec myio[2]; + struct sockaddr_in sa; + struct sockshdr sh; + int e, n=0; + unsigned char buf[KEYXCHGBLKMAX]; + SOCKTOC("cipe_sendmsg",sock,c,-ENOSYS); + + if (len<KEYXCHGBLKMIN) + return -EINVAL; + if (len>KEYXCHGBLKMAX) + return -EMSGSIZE; + cipe_prnpad(buf, sizeof(buf)); +#ifdef VER_SHORT + memcpy_fromiovec(buf, msg->msg_iov, len); +#else + memcpy_fromiovec(buf+blockSize, msg->msg_iov, len); +#endif + (*(__u32 *)(buf+KEYXCHGTSPOS))=htonl(CURRENT_TIME); /* insert timestamp */ + + len=KEYXCHGBLKMIN+buf[sizeof(buf)-1]; /* random */ + cipe_encrypt(c, buf, &len, TW_NEWKEY); + + sa.sin_family=AF_INET; + sa.sin_addr.s_addr=c->peeraddr; + sa.sin_port=c->peerport; + + if (c->sockshost) { + /* Prepend a socks header. */ + memset(&sh, 0, 4); + sh.atyp=1; + sh.dstaddr=c->sockshost; + sh.dstport=c->socksport; + myio[n].iov_base=&sh; + myio[n].iov_len=sizeof(sh); + ++n; + } + myio[n].iov_base=&buf; + myio[n].iov_len=len; + /* mymsg=*msg; */ + mymsg.msg_name=&sa; + mymsg.msg_namelen=sizeof(sa); + mymsg.msg_iov=myio; + mymsg.msg_iovlen=n+1; + /* just to be sure */ + mymsg.msg_control=NULL; + mymsg.msg_controllen=0; + mymsg.msg_flags=0; + + /* Call the real thing. Pretend this is user space segment. */ + { + mm_segment_t fs=get_fs(); + set_fs(get_ds()); + if (c->sockshost) + len+=sizeof(struct sockshdr); + dprintk(DEB_KXC, (KERN_INFO "%s: real sendmsg len %d text=%04x...\n", + c->dev->name, len, + ntohs(*((unsigned short *)(myio[n].iov_base))))); + e=c->udp_prot->sendmsg(sock, &mymsg, len +#ifndef LINUX_21 + , nonblock, flags +#endif + ); + set_fs(fs); + } + return e; +} + +/* Check if we have a new peer (socks relayer changed, etc) */ +static void checkpeer(struct cipe *c, __u32 saddr, __u16 sport) +{ + if (c->peeraddr!=saddr || c->peerport!=sport) { + unsigned char *x=(unsigned char *)&saddr; + c->peeraddr=saddr; + c->peerport=sport; + printk(KERN_NOTICE "%s: new peer %d.%d.%d.%d:%d\n", + c->dev->name, x[0], x[1], x[2], x[3], ntohs(sport)); + } +} + + +/* Decrypt a received packet. Requeue it or return kxc block. */ +/* On entry the packet starts with the original IP header (?), + ip_hdr and h.uh are set to the IP and UDP headers. */ +struct sk_buff *cipe_decrypt_skb(struct cipe *c, struct sock *sk, + struct sk_buff *skb, int *offset) +{ + struct sk_buff *n; + int length; + __u32 rsaddr; + __u16 rsport; + +#ifdef DEBUG + if (cipe_debug&DEB_PKIN) + cipe_dump_packet("received", skb); +#endif + n=alloc_skb(skb->len, GFP_KERNEL); + if (!n) { + printk(KERN_WARNING "%s: cipe_decrypt_skb(): out of memory\n", + c->dev->name); + ++c->stat.rx_dropped; + return NULL; + } + n->sk=NULL; +#ifndef LINUX_21 + n->free=1; +#endif + n->dev=c->dev; + + length=ntohs(skb->h.uh->len)-sizeof(struct udphdr); +#if 0 /* UDP should check this */ + if (length!=skb->len-sizeof(struct udphdr)) { + dprintk(DEB_INP, (KERN_INFO "%s: bogus UDP length (%d/%d)\n", + c->dev->name, length, + skb->len-sizeof(struct udphdr))); + goto framerr; + } +#endif + + /* Copy the datagram into new buffer, skip IP header */ + /* We must copy here because raw sockets get only a clone of the + skbuff, so they would receive the plaintext */ + dprintk(DEB_INP, (KERN_INFO DEVNAME + ": sa=%08lX da=%08lX us=%d ud=%d ul=%d\n", + ntohl(saddr(skb)), ntohl(daddr(skb)), + ntohs(skb->h.uh->source), ntohs(skb->h.uh->dest), + ntohs(skb->h.uh->len))); + + rsaddr=saddr(skb); /*** swapped??? */ + rsport=skb->h.uh->source; + skb_put(n,skb->len); + memcpy(n->data, skb->h.raw, skb->len); + /*n->ip_hdr=NULL;*/ + n->h.uh=(struct udphdr *)n->data; +#if 0 + dprintk4(DEB_INP, KERN_INFO, "UDP: s=%d d=%d l=%d c=%04X\n", + ntohs(n->h.uh->source), ntohs(n->h.uh->dest), + ntohs(n->h.uh->len), n->h.uh->check); +#endif + + if (c->sockshost) { + /* Pull out the SOCKS header and correct the peer's address. */ + struct sockshdr *sh; + sh=(struct sockshdr *)skb_pull(n, sizeof(struct udphdr)); + dprintk(DEB_INP, (KERN_INFO "socks: fr=%d at=%d da=%08lX dp=%d\n", + sh->frag, sh->atyp, + ntohl(sh->dstaddr), ntohs(sh->dstport))); + if (sh->frag || (sh->atyp!=1)) + goto error; + /* Pull out UDP header */ +#ifdef LINUX_21 + n->nh.iph=(struct iphdr *)skb_pull(n, sizeof(struct sockshdr)); +#else + n->ip_hdr=(struct iphdr *)skb_pull(n, sizeof(struct sockshdr)); +#endif + /***saddr(n)=sh->dstaddr;*/ + n->h.uh->source=sh->dstport; + length-=sizeof(struct sockshdr); + *offset=sizeof(struct sockshdr)+sizeof(struct udphdr); + } else { + /* Pull out UDP header */ +#ifdef LINUX_21 + n->nh.iph=(struct iphdr *) skb_pull(n, sizeof(struct udphdr)); +#else + n->ip_hdr=(struct iphdr *) skb_pull(n, sizeof(struct udphdr)); +#endif + /***saddr(n)=rsaddr;*/ + n->h.uh->source=rsport; + *offset=sizeof(struct udphdr); + } + + if (c->havekey) { + switch (cipe_decrypt(c, n->data, &length)) { + case TW_DATA: + break; + case TW_NEWKEY: + /* return it as key exchange block - proper UDP datagram */ + skb_trim(n, length); + checkpeer(c, rsaddr, rsport); +#if 0 + n->saddr=c->myaddr; + n->daddr=c->peeraddr; +#endif + n->h.uh->check=0; + return n; + case TW_CTRL: + /* process a control packet - to be implemented */ + checkpeer(c, rsaddr, rsport); + default: + /* Bogus packet etc. */ + ++c->stat.rx_crc_errors; + goto error; + } + } else if (!c->mayclear) { + goto error; + } + + skb_trim(n, length); + checkpeer(c, rsaddr, rsport); + /* adjust pointers */ +#ifdef LINUX_21 + n->nh.iph=(struct iphdr *)n->data; + memset(&(IPCB(n)->opt), 0, sizeof(IPCB(n)->opt)); +#else + n->h.iph=(struct iphdr *)n->data; + memset(n->proto_priv, 0, sizeof(struct options)); +#endif + + n->mac.raw=n->data; /* no hardware header */ + n->protocol = htons(ETH_P_IP); + n->ip_summed = 0; +#ifdef DEBUG + if (cipe_debug&DEB_INP) { + unsigned char *x=(unsigned char *)&(saddr(n)); + printk(KERN_INFO + "%s: real src %d.%d.%d.%d dst %d.%d.%d.%d len %d\n", + n->dev->name, + x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], length); + } +#endif + +#ifdef DEBUG + if (cipe_debug&DEB_PKIN) + cipe_dump_packet("decrypted", n); +#endif + /* requeue */ + netif_rx(n); +#ifdef LINUX_21 + c->stat.rx_bytes+=skb->len; /* count carrier-level bytes */ +#endif + c->stat.rx_packets++; + return NULL; + +#if 0 + framerr: + ++c->stat.rx_frame_errors; /* slightly abuse this */ +#endif + error: + ++c->stat.rx_errors; + /*n->sk=NULL;*/ + kfreeskb(n, FREE_READ); + return NULL; +} + +/* Receive message. If encrypted, put it through the mill. + If decrypted, return it as key exchange block. + This is mostly from net/ipv4/udp.c, but cipe_decrypt_skb pulls the + UDP header. +*/ + +int cipe_recvmsg(struct sock *sk, struct msghdr *msg, int len, + int noblock, int flags,int *addr_len) +{ + int copied; + struct sk_buff *skb, *skn; + int er=0, of; + struct sockaddr_in *sin=(struct sockaddr_in *)msg->msg_name; + SOCKTOC("cipe_recvmsg",sk,c,-ENOSYS); + + /* + * Check any passed addresses + */ + + if (addr_len) + *addr_len=sizeof(*sin); + + /* + * From here the generic datagram does a lot of the work. Come + * the finished NET3, it will do _ALL_ the work! + */ + + do { + /* CIPE: look if the packet is encrypted, repeat until + a decrypted one is found */ + skn=NULL; + skb=skb_recv_datagram(sk,flags,noblock,&er); + if(skb==NULL) { + dprintk(DEB_KXC, (KERN_INFO "%s: skb_recv_datagram: %d\n", + c->dev->name, er)); + return er; + } + + if (!skb->h.uh->source) { + /* Synthetic KXC packets are marked by source port 0. + Correct this - we know the truth from our structure. + Perhaps it would be better to not correct it so the + user level daemon can spot the difference? */ + skb->h.uh->source=c->peerport; + of=skb->data-skb->head+sizeof(struct udphdr); + break; + } + skn=cipe_decrypt_skb(c, sk, skb, &of); + skb_free_datagram(sk, skb); + skb=skn; + } while (skb==NULL); + + copied = skb->len; + if (copied > len) + { + copied = len; +#ifdef LINUX_21 + msg->msg_flags |= MSG_TRUNC; +#endif + } + + /* + * FIXME : should use udp header size info value + */ +#ifdef LINUX_21 + er = skb_copy_datagram_iovec(skb,of,msg->msg_iov,copied); + if (er<0) + goto out_free; +#else + skb_copy_datagram_iovec(skb,of,msg->msg_iov,copied); +#endif + sk->stamp=skb->stamp; + + /* Copy the address. */ + if (sin +#ifdef LINUX_21 + && skb->nh.iph /* Fake KXC has no address */ +#endif + ) { + sin->sin_family = AF_INET; + sin->sin_port = skb->h.uh->source; + sin->sin_addr.s_addr = daddr(skb); +#ifdef CONFIG_IP_TRANSPARENT_PROXY + /* Does this ever apply here? */ + if (flags&MSG_PROXY) + { + /* + * We map the first 8 bytes of a second sockaddr_in + * into the last 8 (unused) bytes of a sockaddr_in. + * This _is_ ugly, but it's the only way to do it + * easily, without adding system calls. + */ + struct sockaddr_in *sinto = + (struct sockaddr_in *) sin->sin_zero; + + sinto->sin_family = AF_INET; + sinto->sin_port = skb->h.uh->dest; + sinto->sin_addr.s_addr = saddr(skb); + } +#endif + } + er=copied; + +#ifdef LINUX_21 + out_free: +#endif + if (skb==skn) + /* the buffer was a copy made by decryption */ + kfreeskb(skb, FREE_READ); + else + skb_free_datagram(sk, skb); + + return(er); +} + +#ifdef LINUX_21 + +#include <linux/file.h> + +int cipe_attach(struct device *dev, struct siocsifcipatt *parm) +{ + struct file *file; + struct inode *inode; + struct socket *sock; + struct sock *sk; + struct cipe *c0; + DEVTOCIPE(dev,c,-ENODEV); + + if (c->sock) + return -EBUSY; + if (!(file=fget(parm->fd))) + return(-EBADF); + inode = file->f_dentry->d_inode; + if (!inode || !inode->i_sock || !(sock=&inode->u.socket_i)) { + fput(file); + return(-ENOTSOCK); + } + if (sock->file != file) { + printk(KERN_ERR DEVNAME ": socki_lookup: socket file changed!\n"); + sock->file = file; + } + + fput(file); + if (sock->type!=SOCK_DGRAM) + return(-ESOCKTNOSUPPORT); + if (sock->ops->family!=AF_INET) + return(-EAFNOSUPPORT); + + sk=sock->sk; + if (sk->state!=TCP_ESTABLISHED) + return(-ENOTCONN); + if (((c0=(struct cipe *)sk->user_data)) && + (c0->magic==CIPE_MAGIC)) + return(-EBUSY); /* socket is already attached */ + + cipe_use_module(); + c->sock=sk; + c->peeraddr=sk->daddr; + c->peerport=sk->dport; + c->myaddr=sk->saddr; + c->myport=htons(sk->num); + /* Disconnect socket, we might receive from somewhere else */ + sk->daddr=0; + sk->dport=0; + + /* Fill an otherwise unused field in the sock struct with this info. + This field is conveniently named and the kernel uses it only for RPC. */ + sk->user_data=c; + sk->no_check=1; /* our packets are checksummed internally */ + + /* Set up new socket operations */ + c->udp_prot=sk->prot; + c->cipe_proto=*sk->prot; + c->cipe_proto.close=cipe_sock_close; + c->cipe_proto.sendmsg=cipe_sendmsg; + c->cipe_proto.recvmsg=cipe_recvmsg; + sk->prot=&c->cipe_proto; + + return(0); +} + + +#else /* LINUX_21 */ + +#define sreturn(x) {sti(); return((x));} + +int cipe_attach(struct device *dev, struct siocsifcipatt *parm) +{ + struct file *file; + struct inode *inode; + struct socket *sock; + struct sock *sk; + int fd=parm->fd; + struct cipe *c0; + DEVTOCIPE(dev,c,-ENODEV); + cli(); + if (c->sock) + sreturn(-EBUSY); + + /* Find the socket (from net/socket.c) */ + if (fd < 0 || fd >= NR_OPEN || !(file = current->files->fd[fd])) + sreturn(-EBADF); + inode = file->f_inode; + if (!inode || !inode->i_sock) + sreturn(-ENOTSOCK); + sock=&inode->u.socket_i; + if (sock->type!=SOCK_DGRAM) + sreturn(-ESOCKTNOSUPPORT); + if (sock->ops->family!=AF_INET) + sreturn(-EAFNOSUPPORT); + sk=(struct sock *)sock->data; + if (sk->state!=TCP_ESTABLISHED) + sreturn(-ENOTCONN); + if (((c0=(struct cipe *)sk->protinfo.af_packet.bound_dev)) && + (c0->magic==CIPE_MAGIC)) + sreturn(-EBUSY); /* socket is already attached */ + + cipe_use_module(); + c->sock=sk; + c->peeraddr=sk->daddr; + c->peerport=sk->dummy_th.dest; + c->myaddr=sk->saddr; + c->myport=sk->dummy_th.source; + /* Disconnect socket, we might receive from somewhere else */ + sk->daddr=0; + sk->dummy_th.dest=0; + + /* Set up new socket operations */ + c->udp_prot=sk->prot; + c->cipe_proto=*sk->prot; + c->cipe_proto.close=cipe_sock_close; + c->cipe_proto.sendmsg=cipe_sendmsg; + c->cipe_proto.recvmsg=cipe_recvmsg; + sk->prot=&c->cipe_proto; + + /* Fill an otherwise unused field in the sock struct with this info. + Actually, this is very similar to a packet socket! + The ugly cast saves us one deref in the actual ops */ + sk->protinfo.af_packet.bound_dev=(struct device *)c; + sk->no_check=1; /* our packets are checksummed internally */ + + sti(); + return 0; +} + +#endif + + +/* Build and enqueue a fake UDP packet to receive. + Note that these are neither encrypted nor SOCKSed. +*/ +void cipe_fakenkey(struct cipe *c, char typ) +{ + int len=sizeof(struct udphdr)+1; + struct sk_buff *skb=alloc_skb(len, GFP_ATOMIC); + + if (!skb) { + printk(KERN_WARNING "%s: cipe_fakenkey(): out of memory\n", + c->dev->name); + return; /* not much we can do */ + } + + dprintk(DEB_KXC, (KERN_INFO "%s: fake kxc block typ=%d\n", + c->dev->name, typ)); + + skb->sk=NULL; + skb->dev=c->dev; + + skb->h.uh=(struct udphdr *)skb->data; + skb->len=len; +#ifdef LINUX_21 + skb->nh.iph=NULL; +#else + saddr(skb)=c->myaddr; + daddr(skb)=c->peeraddr; + skb->free=1; /* Discard after use */ + skb->ip_hdr=NULL; +#endif + skb->mac.raw=NULL; + + skb->h.uh->source=0; /* mark as KXC packet */ + skb->h.uh->dest=c->myport; + len-=sizeof(struct udphdr); + skb->h.uh->len=len; + skb->h.uh->check=0; + skb->mac.raw=skb->data; /* no hardware header */ + + /* All those contortions for just one byte of payload data. + Since we generate only NK_RREQ and NK_REQ it's effectively + one _bit_... */ + skb->data[sizeof(struct udphdr)]=typ; + + if (sock_queue_rcv_skb(c->sock, skb)<0) { + printk(KERN_WARNING "%s: cipe_fakenkey(): enqueuing failed\n", + c->dev->name); + kfreeskb(skb, FREE_WRITE); + } +} diff -ruN linux-2.2.5,pristine/net/cipe/socks5.c linux-2.2.5/net/cipe/socks5.c --- linux-2.2.5,pristine/net/cipe/socks5.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/socks5.c Thu Apr 1 23:05:46 1999 @@ -0,0 +1,160 @@ +/* + CIPE - encrypted IP over UDP tunneling + + socks5.c - talk to a SOCKS5 server + + Copyright 1997 Olaf Titz <olaf@bigred.inka.de> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 2 of the License, or (at your option) any later version. +*/ +/* $Id: socks5.c,v 1.1 1997/09/18 23:00:47 olaf Exp $ */ + +#include <stdlib.h> +#include <syslog.h> +#include <unistd.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include "ciped.h" + +struct socksrq { + char ver; + char cmd; + char rsv; + char atyp; + unsigned int dstaddr __attribute__((packed)); + unsigned short dstport __attribute__((packed)); +}; + +const char * const socks_errlist[] = { + "Succeeded", + "Server failure", + "Connection not allowed", + "Network unreachable", + "Host unreachable", + "Connection refused", + "TTL expired", + "Command not supported", + "Address type not supported" +}; + +static int readn(int fd, char *b, int n, const char *m) +{ + int p=0, e; + while (p<n) { + if ((e=read(fd, b+p, n-p))<=0) { + logerr(LOG_ERR, m); + return -1; + } + p+=e; + } + return n; +} + +static int writen(int fd, const char *b, int n, const char *m) +{ + int p=0, e; + while (p<n) { + if ((e=write(fd, b+p, n-p))<0) { + logerr(LOG_ERR, m); + return e; + } + p+=e; + } + return n; +} + +int socks5_open(struct sockaddr_in *so) +{ + int e; + char *su=getenv("SOCKS5_USER"); + char *sp=getenv("SOCKS5_PASSWD"); + char buf[520]; + + int fd=socket(AF_INET, SOCK_STREAM, 0); + if (fd<0) { + logerr(LOG_ERR, "socks5_open: socket"); return -1; + } + if (connect(fd, (struct sockaddr *)so, sizeof(*so))<0) { + logerr(LOG_ERR, "socks5_open: connect"); + goto error; + } + if (su) + e=writen(fd, "\005\002\000\002", 4, "socks5_open: winit"); + else + e=writen(fd, "\005\001\000", 3, "socks5_open: winit"); + if (e<0) + goto error; + if (readn(fd, buf, 2, "socks5_open: rinit")<2) + goto error; + + switch (buf[1]) { + case '\000': + break; + case '\002': + { + unsigned char l; + int lu, lp; + + if (!su) su=""; + if (!sp) sp=""; + lu=strlen(su); lu=MIN(lu, 255); + lp=strlen(sp); lp=MIN(lp, 255); + if ((writen(fd, "\001", 1, "socks5_open: wauth1")<0) || + (l=lu, writen(fd, &l, 1, "socks5_open: wauth2")<0) || + (writen(fd, su, lu, "socks5_open: wauth3")<0) || + (l=lp, writen(fd, &l, 1, "socks5_open: wauth4")<0) || + (writen(fd, sp, lp, "socks5_open: wauth5")<0)) + goto error; + if (readn(fd, buf, 2, "socks5_open: rauth")<0) + goto error; + if (buf[1]!=0) { + log(LOG_ERR, "socks5_open: authentication failed"); + goto error; + } + break; + } + default: + log(LOG_ERR, "socks5_open: authentication required"); + goto error; + } + return fd; + + error: + close(fd); + return -1; +} + +int socks5_cmd(int fd, int cmd, struct sockaddr_in *so) +{ + struct socksrq r; + r.ver=5; + r.cmd=cmd; + r.rsv=0; + r.atyp=1; + r.dstaddr=so->sin_addr.s_addr; + r.dstport=so->sin_port; + if (writen(fd, (char *)&r, sizeof(r), "socks5_cmd: wcmd")<0) + goto error; + if (readn(fd, (char *)&r, sizeof(r), "socks5_cmd: rreply")<0) + goto error; + if (r.cmd==0) { + if (r.atyp!=1) { + log(LOG_ERR, "socks5_cmd: unknown address type"); + goto error; + } + so->sin_addr.s_addr=r.dstaddr; + so->sin_port=r.dstport; + return fd; + } + if (r.cmd>=sizeof(socks_errlist)) + log(LOG_ERR, "socks5_cmd: server: Unknown error"); + else + log2(LOG_ERR, "socks5_cmd: server: %s", socks_errlist[(int)r.cmd]); + + error: + close(fd); + return -1; +} diff -ruN linux-2.2.5,pristine/net/cipe/tcpdump.patch linux-2.2.5/net/cipe/tcpdump.patch --- linux-2.2.5,pristine/net/cipe/tcpdump.patch Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/tcpdump.patch Thu Apr 1 23:05:46 1999 @@ -0,0 +1,39 @@ +With this patch (in libpcap), tcpdump can be used on the CIPE device +so that it shows the traffic going over that device in unencrypted +form. (tcpdump on the device which holds the UDP address will show the +encrypted packets, for obvious reasons.) Similarly, on a conventional +IPIP tunnel, it will show the contents of the packets. + +These are two different patches, one for libpcap 0.3 and one for +libpcap 0.4. Look which one your version of tcpdump uses. + +--- libpcap-0.3/pcap-linux.c.orig Wed Dec 11 08:15:00 1996 ++++ libpcap-0.3/pcap-linux.c Thu Jul 31 10:39:42 1997 +@@ -160,6 +160,10 @@ + p->linktype = DLT_NULL; + p->md.pad = 2; + p->md.skip = 12; ++ } else if (strncmp("tunl", device, 4) == 0) { ++ p->linktype = DLT_RAW; ++ } else if (strncmp("cip", device, 3) == 0) { ++ p->linktype = DLT_RAW; + } else { + sprintf(ebuf, "linux: unknown physical layer type"); + goto bad; + + +--- libpcap-0.4a6/pcap-linux.c.orig Fri Oct 3 07:39:53 1997 ++++ libpcap-0.4a6/pcap-linux.c Mon May 18 11:15:35 1998 +@@ -235,6 +235,11 @@ + break; + #endif + ++ case ARPHRD_TUNNEL: ++ /* XXX I dont know if this is correct but it works for CIPE */ ++ p->linktype = DLT_RAW; ++ break; ++ + #ifdef notdef + case ARPHRD_LOCALTLK: + case ARPHRD_NETROM: + diff -ruN linux-2.2.5,pristine/net/cipe/thruput.c linux-2.2.5/net/cipe/thruput.c --- linux-2.2.5,pristine/net/cipe/thruput.c Thu Jan 1 01:00:00 1970 +++ linux-2.2.5/net/cipe/thruput.c Thu Apr 1 23:05:46 1999 @@ -0,0 +1,101 @@ +/* + Primitive TCP speedometer: blast data through the echo port and + count the bytes read and written in a specified amount of time + + One point of data on a 386/25, Linux 2.0.12: 619 kb/s to 127.0.0.1 +*/ + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <arpa/inet.h> +#include <sys/socket.h> +#include <sys/signal.h> +#include <sys/time.h> + +#define BLKS 65536 + +extern char *optarg; +extern int optind; + +void usage(char *s) +{ + fprintf(stderr, "usage: %s [-t secs] [-u] [-n] addr\n", s); + exit(1); +} + +long rb=0, wb=0; +time_t st; +char rbuf[BLKS], wbuf[BLKS]; +int pr=SOCK_STREAM; + +void shand(int s) +{ + long t=time(0); + printf("Sent %ld bytes, received %ld bytes in %ld seconds\n", wb, rb, + t-st); + if (pr==SOCK_DGRAM) + wb=rb; /* disregard lost datagrams */ + if (t-st) + printf("%ld bytes/sec\n", (wb+rb)/(t-st)); + exit(0); +} + +int main(int argc, char *argv[]) +{ + int sec=60; + int max=BLKS; + int nb=0; + int fd, i; + struct sockaddr_in sa; + fd_set rs, ws; + + while((i=getopt(argc, argv, "t:un"))!=EOF) { + switch(i) { + case 't': sec=atoi(optarg); break; + case 'u': pr=SOCK_DGRAM; max=512; break; + case 'n': ++nb; break; + default: usage(argv[0]); + } + } + if (optind>=argc) + usage(argv[0]); + if ((fd=socket(AF_INET, pr, 0))<0) { + perror("socket"); exit(1); + } + sa.sin_family=AF_INET; + sa.sin_port=htons(7); /* echo */ + sa.sin_addr.s_addr=inet_addr(argv[optind]); + if (connect(fd, (struct sockaddr *)&sa, sizeof(sa))<0) { + perror("connect"); exit(1); + } + if (nb) { + if ((i=fcntl(fd, F_GETFL))<0) + perror("F_GETFL"); + else if (fcntl(fd, F_SETFL, i|O_NONBLOCK)<0) + perror("F_SETFL"); + } + + for (i=0; i<BLKS; ++i) + wbuf[i]=(i&0x3F)+0x20; + st=time(0); + signal(SIGINT, shand); + signal(SIGTERM, shand); + signal(SIGALRM, shand); + signal(SIGHUP, shand); + alarm(sec); + + while(1) { + FD_ZERO(&rs); FD_ZERO(&ws); + FD_SET(fd, &rs); FD_SET(fd, &ws); + if (select(fd+1, &rs, &ws, NULL, NULL)>0) { + if (FD_ISSET(fd, &rs)) + rb+=recv(fd, rbuf, max, 0); + if (FD_ISSET(fd, &ws)) + wb+=send(fd, wbuf, max, 0); + } + } + return 0; +} diff -ruN linux-2.2.5,pristine/net/core/sock.c linux-2.2.5/net/core/sock.c --- linux-2.2.5,pristine/net/core/sock.c Sun Mar 28 19:07:47 1999 +++ linux-2.2.5/net/core/sock.c Thu Apr 1 23:05:46 1999 @@ -282,6 +282,16 @@ sk->bsdism = valbool; break; +#ifdef CONFIG_NET_SECURITY + case SO_SECURITY_AUTHENTICATION: + sk->authentication = val; + break; + + case SO_SECURITY_ENCRYPTION_TRANSPORT: + sk->encryption = val; + break; +#endif + case SO_PASSCRED: sock->passcred = valbool; break; @@ -441,6 +451,16 @@ v.val = sk->bsdism; break; +#ifdef CONFIG_NET_SECURITY + case SO_SECURITY_AUTHENTICATION: + v.val = sk->authentication; + break; + + case SO_SECURITY_ENCRYPTION_TRANSPORT: + v.val = sk->encryption; + break; +#endif + case SO_RCVTIMEO: case SO_SNDTIMEO: lv=sizeof(struct timeval); diff -ruN linux-2.2.5,pristine/net/ipv4/ip_forward.c linux-2.2.5/net/ipv4/ip_forward.c --- linux-2.2.5,pristine/net/ipv4/ip_forward.c Sun Mar 21 16:22:00 1999 +++ linux-2.2.5/net/ipv4/ip_forward.c Thu Apr 1 23:05:46 1999 @@ -108,7 +108,15 @@ goto local_pkt; #endif +#ifdef CONFIG_NET_SECURITY + /* + * Have to do this before skb_cow() due to + * possibility of interception by ipsec. + */ + if (ip_decrease_ttl(iph) <= 0) +#else if (iph->ttl <= 1) +#endif goto too_many_hops; if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway) @@ -124,9 +132,10 @@ mtu = rt->u.dst.pmtu; #ifdef CONFIG_NET_SECURITY - call_fw_firewall(PF_SECURITY, dev2, NULL, &mtu, NULL); + if (call_fw_firewall(PF_SECURITY, dev2, NULL, &mtu, NULL) < FW_ACCEPT) + return -1; #endif - + /* * We now generate an ICMP HOST REDIRECT giving the route * we calculated. @@ -134,14 +143,21 @@ if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr) ip_rt_send_redirect(skb); +#ifdef CONFIG_NET_SECURITY + if (call_out_firewall(PF_SECURITY, dev2, NULL, (void *)2, &skb) < FW_ACCEPT) + return -1; +#endif + /* We are about to mangle packet. Copy it! */ if ((skb = skb_cow(skb, dev2->hard_header_len)) == NULL) return -1; iph = skb->nh.iph; opt = &(IPCB(skb)->opt); +#ifndef CONFIG_NET_SECURITY /* Decrease ttl after skb cow done */ ip_decrease_ttl(iph); +#endif /* * We now may allocate a new buffer, and copy the datagram into it. diff -ruN linux-2.2.5,pristine/net/ipv4/ip_input.c linux-2.2.5/net/ipv4/ip_input.c --- linux-2.2.5,pristine/net/ipv4/ip_input.c Sun Mar 21 16:22:00 1999 +++ linux-2.2.5/net/ipv4/ip_input.c Thu Apr 1 23:05:46 1999 @@ -147,6 +147,7 @@ #include <linux/firewall.h> #include <linux/mroute.h> #include <linux/netlink.h> +#include <linux/ipsec.h> /* * SNMP management statistics @@ -309,7 +310,10 @@ skb1 = skb_clone(skb, GFP_ATOMIC); if(skb1) { - raw_rcv(raw_sk, skb1); + if(ipsec_sk_policy(raw_sk,skb1)) + raw_rcv(raw_sk, skb1); + else + kfree_skb(skb1); } } raw_sk = sknext; @@ -369,8 +373,10 @@ if(raw_sk!=NULL) /* Shift to last raw user */ { - raw_rcv(raw_sk, skb); - + if(ipsec_sk_policy(raw_sk, skb)) + raw_rcv(raw_sk, skb); + else + kfree_skb(skb); } else if (!flag) /* Free and report errors */ { diff -ruN linux-2.2.5,pristine/net/ipv4/ip_output.c linux-2.2.5/net/ipv4/ip_output.c --- linux-2.2.5,pristine/net/ipv4/ip_output.c Thu Mar 25 18:23:34 1999 +++ linux-2.2.5/net/ipv4/ip_output.c Thu Apr 1 23:05:46 1999 @@ -76,6 +76,7 @@ #include <linux/firewall.h> #include <linux/mroute.h> #include <linux/netlink.h> +#include <linux/ipsec.h> /* * Shall we try to damage output packets if routing dev changes? @@ -145,6 +146,19 @@ ip_send_check(iph); +#ifdef CONFIG_NET_SECURITY + /* Now we have no better mechanism to notify about error. */ + switch (call_out_firewall(PF_SECURITY, dev, NULL, (void *) 7, &skb)) { + case FW_REJECT: + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); + /* Fall thru... */ + case FW_BLOCK: + case FW_QUEUE: + kfree_skb(skb); + return; + } +#endif + /* Send it out. */ skb->dst->output(skb); return; @@ -307,6 +321,23 @@ } #endif +#ifdef CONFIG_NET_SECURITY + /* Add an IP checksum (must do this before SECurity because + * of possible tunneling). + */ + ip_send_check(iph); + switch (call_out_firewall(PF_SECURITY, dev, NULL, (void *) 4, &skb)) { + case FW_REJECT: + start_bh_atomic(); + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); + end_bh_atomic(); + /* Fall thru... */ + case FW_BLOCK: + case FW_QUEUE: + goto drop; + } +#endif + /* This can happen when the transport layer has segments queued * with a cached route, and by the time we get here things are * re-routed to a device with a different MTU than the original @@ -579,6 +610,19 @@ } #endif +#ifdef CONFIG_NET_SECURITY + switch (call_out_firewall(PF_SECURITY, rt->u.dst.dev, NULL, (void *) 6, &skb)) { + case FW_QUEUE: + kfree_skb(skb); + continue; + case FW_BLOCK: + case FW_REJECT: + kfree_skb(skb); + err = -EPERM; + goto error; + } +#endif + err = -ENETDOWN; if (rt->u.dst.output(skb)) goto error; @@ -691,6 +735,19 @@ #ifdef CONFIG_FIREWALL switch (call_out_firewall(PF_INET, rt->u.dst.dev, iph, NULL, &skb)) { + case FW_QUEUE: + kfree_skb(skb); + return 0; + case FW_BLOCK: + case FW_REJECT: + kfree_skb(skb); + err = -EPERM; + goto error; + } +#endif + +#ifdef CONFIG_NET_SECURITY + switch (call_out_firewall(PF_SECURITY, rt->u.dst.dev, NULL, (void *) 5, &skb)) { case FW_QUEUE: kfree_skb(skb); return 0; diff -ruN linux-2.2.5,pristine/net/ipv4/udp.c linux-2.2.5/net/ipv4/udp.c --- linux-2.2.5,pristine/net/ipv4/udp.c Sun Mar 21 16:22:00 1999 +++ linux-2.2.5/net/ipv4/udp.c Thu Apr 1 23:05:46 1999 @@ -114,6 +114,7 @@ #include <net/icmp.h> #include <net/route.h> #include <net/checksum.h> +#include <linux/ipsec.h> /* * Snmp MIB for the UDP layer @@ -1024,6 +1025,16 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) { + /* + * Check the security clearance + */ + + if(!ipsec_sk_policy(sk,skb)) + { + kfree_skb(skb); + return(0); + } + /* * Charge it to the socket, dropping if the queue is full. */ diff -ruN linux-2.2.5,pristine/net/netsyms.c linux-2.2.5/net/netsyms.c --- linux-2.2.5,pristine/net/netsyms.c Mon Mar 22 20:20:51 1999 +++ linux-2.2.5/net/netsyms.c Thu Apr 1 23:05:46 1999 @@ -230,6 +230,7 @@ EXPORT_SYMBOL(arp_broken_ops); EXPORT_SYMBOL(ip_id_count); EXPORT_SYMBOL(ip_send_check); +EXPORT_SYMBOL(ip_forward); EXPORT_SYMBOL(ip_fragment); EXPORT_SYMBOL(inet_family_ops); EXPORT_SYMBOL(in_aton);