home *** CD-ROM | disk | FTP | other *** search
- From: how@isl.stanford.edu (Dana How)
- Newsgroups: comp.sources.misc
- Subject: v29i128: descore - high performance DES core routines, Part01/01
- Message-ID: <1992May21.133430.13381@aber.ac.uk>
- Date: 21 May 92 13:34:30 GMT
- Approved: aem@aber.ac.uk
- X-Md4-Signature: a6861837e10c1a43b8778266ae5bc9b7
-
- Submitted-by: how@isl.stanford.edu (Dana How)
- Posting-number: Volume 29, Issue 128
- Archive-name: descore/part01
- Environment: 32BIT
- Supersedes: descore: Volume 29, Issue 80
-
- this is an update to desCore, a package containing just the core DES
- functionality: specifying keys, encryption and decryption.
- it remains the most efficient DES code posted, with the following
- encryption/decryption performance on a sparcstation 1:
- variant blocks/sec bytes/sec bits/sec
- with 2k tables 20,000+ 160,000+ 1,280,000+
- with 64k tables 30,000+ 480,000+ 3,840,000+
- (not quite the 1Gb/sec reported for a GaAs chip at CICC '92 in Boston!)
- omitting the initial and final permutation improves the performance even
- more; all four combinations of table size and IP/FP support are provided.
-
- i have included a number of changes to increase performance on machines
- with fewer registers and less cache than a sparc. on a sparc there is no
- change in performance since the code was already expressed in a minimum number
- of RISC operations :-). i have also shown how the code can take advantage of
- CISC bitfield instructions and other CISC quirks. and with this release, you
- can perform DES on a 386 entirely in the registers if you use gcc.
-
- desCore is for those who want to implement such things as DES filters,
- rather than UNIX password crackers. for this reason i have not spent much
- effort yet to improve the performance of the key-setting routine.
-
- i have attempted to keep the package small, portable and easily plugged-in
- to kerberos-compatible code. i have NOT reimplemented all the other routines
- in kerberos because i have nothing new to add -- that has already been done
- at least three times by other people.
-
- enjoy! posted by how@isl.stanford.edu
-
- ----------------------------- CUT HERE -------------------------------
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 1)."
- # Contents: Makefile README desCode.h desCore.h desKerb.c desQuick.c
- # desTest.c desUtil.c desdata.c desinfo.h
- # Wrapped by how@tau on Tue May 19 17:26:40 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(3970 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X#
- X# des - fast & portable DES encryption & decryption.
- X# Copyright (C) 1992 Dana L. How
- X# Please see the file `README' for the complete copyright notice.
- X#
- X
- X# $Id: Makefile,v 1.17 1992/05/19 23:59:13 how E $
- X
- XCFLAGS= -g # debug
- XCFLAGS= -O4 # max opt
- XCFLAGS= -O2
- XCPPFLAGS= -Dsparc # use 6+8 general regs
- XCPPFLAGS= -Dmc68000 # use 3+3 addr (1+3 live), and 3+3 data regs
- XCPPFLAGS= -Dvax # use 6+0 general regs
- XCPPFLAGS= -Di386 # use 3+0 regs, and 3+0 normal variables
- XCPPFLAGS= -Dsparc
- XLDFLAGS=
- XCC= gcc
- XCPP= $(CC) -E $(CPPFLAGS)
- XCODEGEN.c= $(CC) $(CFLAGS) $(CPPFLAGS) -S
- XCOMPILE.c= $(CC) $(CFLAGS) $(CPPFLAGS) -c
- XLINK.c= $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
- X
- X# hand-entered files that go into the library
- XSC= desKerb.c desUtil.c desQuick.c
- XSO= desKerb.o desUtil.o desQuick.o
- X
- X# special generated files
- XGH= parity.h rotors.h keymap.h
- XGC= desSmallFips.c desSmallCore.c desQuickFips.c desQuickCore.c
- XGI= desSmallFips.i desSmallCore.i desQuickFips.i desQuickCore.i
- XGO= desSmallFips.o desSmallCore.o desQuickFips.o desQuickCore.o
- X
- X# what to distribute
- XRCS= Makefile README \
- X desCore.h desinfo.h desCode.h \
- X desTest.c $(SC) desdata.c
- XFILES= $(RCS)
- X
- XO= $(SO) $(GO)
- X
- X# prefer compilation from .i if .i exists
- X.SUFFIXES:
- X.SUFFIXES: .i .o .c $(SUFFIXES)
- X
- X.PRECIOUS: $(RCS) test
- X
- Xtest: desCore.a desTest.o
- X $(LINK.c) -o $@ desTest.o desCore.a
- X ./test
- X
- X# get stuff from RCS
- X$(RCS):
- X co $@
- X
- X# test all performance enhancement flags
- Xsure:
- X rm *.i; make 'CPPFLAGS=-Dvax -Umc68000 -Usparc'
- X rm *.i; make 'CPPFLAGS=-Dmc68000 -Usparc'
- X rm *.i; make 'CPPFLAGS=-Dsparc -Umc68000'
- X#was #1 rm *.i; make 'CPPFLAGS=-Di386 -Umc68000 -Usparc'
- X
- XdesCore.a: $O
- X ar cru $@ $O
- X ranlib $@
- X
- Xdesdata.o: desinfo.h desCore.h
- XdesUtil.o: $(GH)
- X$(SO): desCore.h
- X$(GI): desCode.h desCore.h Makefile
- XdesTest.o: desCore.h
- X
- X$(GH): desdata
- X ./desdata $@ > $@
- X
- Xdesdata: desdata.o
- X $(LINK.c) -o $@ desdata.o
- X
- Xtar: $(FILES)
- X tar cf des.tar $(FILES)
- X
- Xshar: $(FILES)
- X makekit -ndes.shar -s58k '-tnow run make' $(FILES)
- X
- Xlint: desTest.c $(SC) $(GC)
- X lint $(CPPFLAGS) \
- X desTest.c $(SC) $(GC) | \
- X sed '/possible pointer alignment problem/d'
- X
- Xwarn: desTest.c $(SC) $(GC)
- X gcc -Wall -ansi -pedantic $(CPPFLAGS) -O2 \
- X desTest.c $(SC) $(GC)
- X
- X# new rules (note: tr|sed|tr is NOT necessary, just there so .i is readable)
- X.c.i:
- X $(CPP) $< > $*.x
- X @tr ';'\\012 \\012';' < $*.x | \
- X sed -e 's/[ ][ ]*/ /g' \
- X -e 's/^ //' \
- X -e 's/ $$//' \
- X -e '/^$$/d' \
- X -e '/^[^;]/s/^/;/' \
- X -e 's/#[^;]*;//g' \
- X -e 's/\([){]\) *\(register\)/\1;\2/g' \
- X -e 's/do {/do {;/g' \
- X -e 's/\([[(]\) /\1/g' \
- X -e 's/ \([]),]\)/\1/g' \
- X -e 's/\([^]+0123 ]\) =/\1 =/g' \
- X -e 's/} while/@ while/g' \
- X -e 's/}/};;/g' \
- X -e 's/@ while/} while/g' \
- X -e 's/ *; */;/g' \
- X -e 's/;;;*/;;/g' \
- X -e '1s/^;*//' | \
- X tr ';'\\012 \\012';' > $@
- X @echo "" >> $@
- X @echo "}" >> $@ # last definition must be a procedure
- X
- X# -e 's/\(;[kmxyz][0-9]*\)\([^;]*=\)/\1 \2/g'
- X
- X.i.o:
- X $(CODEGEN.c) $<
- X $(COMPILE.c) $*.s
- X
- X# slowest to quickest
- XdesSmallFips.c:
- X @echo '#include "desCode.h"' > $@
- X @echo \
- X'ENCRYPT(DesSmallFipsEncrypt,TEMPSMALL,LOADFIPS,KEYMAPSMALL,SAVEFIPS)' >> $@
- X @echo \
- X'DECRYPT(DesSmallFipsDecrypt,TEMPSMALL,LOADFIPS,KEYMAPSMALL,SAVEFIPS)' >> $@
- XdesSmallCore.c:
- X @echo '#include "desCode.h"' > $@
- X @echo \
- X'ENCRYPT(DesSmallCoreEncrypt,TEMPSMALL,LOADCORE,KEYMAPSMALL,SAVECORE)' >> $@
- X @echo \
- X'DECRYPT(DesSmallCoreDecrypt,TEMPSMALL,LOADCORE,KEYMAPSMALL,SAVECORE)' >> $@
- XdesQuickFips.c:
- X @echo '#include "desCode.h"' > $@
- X @echo \
- X'ENCRYPT(DesQuickFipsEncrypt,TEMPQUICK,LOADFIPS,KEYMAPQUICK,SAVEFIPS)' >> $@
- X @echo \
- X'DECRYPT(DesQuickFipsDecrypt,TEMPQUICK,LOADFIPS,KEYMAPQUICK,SAVEFIPS)' >> $@
- XdesQuickCore.c:
- X @echo '#include "desCode.h"' > $@
- X @echo \
- X'ENCRYPT(DesQuickCoreEncrypt,TEMPQUICK,LOADCORE,KEYMAPQUICK,SAVECORE)' >> $@
- X @echo \
- X'DECRYPT(DesQuickCoreDecrypt,TEMPQUICK,LOADCORE,KEYMAPQUICK,SAVECORE)' >> $@
- END_OF_FILE
- if test 3970 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(17055 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- Xdes - fast & portable DES encryption & decryption.
- XCopyright (C) 1992 Dana L. How
- X
- XThis program is free software; you can redistribute it and/or modify
- Xit under the terms of the GNU Library General Public License as published by
- Xthe Free Software Foundation; either version 2 of the License, or
- X(at your option) any later version.
- X
- XThis program is distributed in the hope that it will be useful,
- Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
- XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- XGNU Library General Public License for more details.
- X
- XYou should have received a copy of the GNU Library General Public License
- Xalong with this program; if not, write to the Free Software
- XFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- XAuthor's address: how@isl.stanford.edu
- X
- X$Id: README,v 1.15 1992/05/20 00:25:32 how E $
- X
- X
- X==>> To compile after untarring/unsharring, just `make' <<==
- X
- X
- XThis package was designed with the following goals:
- X1. Highest possible encryption/decryption PERFORMANCE.
- X2. PORTABILITY to any byte-addressable host with a 32bit unsigned C type
- X3. Plug-compatible replacement for KERBEROS's low-level routines.
- X
- XThis second release includes a number of performance enhancements for
- Xregister-starved machines. My discussions with Richard Outerbridge,
- X71755.204@compuserve.com, sparked a number of these enhancements.
- X
- XTo more rapidly understand the code in this package, inspect desSmallFips.i
- X(created by typing `make') BEFORE you tackle desCode.h. The latter is set
- Xup in a parameterized fashion so it can easily be modified by speed-daemon
- Xhackers in pursuit of that last microsecond. You will find it more
- Xilluminating to inspect one specific implementation,
- Xand then move on to the common abstract skeleton with this one in mind.
- X
- X
- Xperformance comparison to other available des code which i could
- Xcompile on a SPARCStation 1 (cc -O4, gcc -O2):
- X
- Xthis code (byte-order independent):
- X 30us per encryption (options: 64k tables, no IP/FP)
- X 33us per encryption (options: 64k tables, FIPS standard bit ordering)
- X 45us per encryption (options: 2k tables, no IP/FP)
- X 48us per encryption (options: 2k tables, FIPS standard bit ordering)
- X 275us to set a new key (uses 1k of key tables)
- X this has the quickest encryption/decryption routines i've seen.
- X since i was interested in fast des filters rather than crypt(3)
- X and password cracking, i haven't really bothered yet to speed up
- X the key setting routine. also, i have no interest in re-implementing
- X all the other junk in the mit kerberos des library, so i've just
- X provided my routines with little stub interfaces so they can be
- X used as drop-in replacements with mit's code or any of the mit-
- X compatible packages below. (note that the first two timings above
- X are highly variable because of cache effects).
- X
- Xkerberos des replacement from australia (version 1.95):
- X 53us per encryption (uses 2k of tables)
- X 96us to set a new key (uses 2.25k of key tables)
- X so despite the author's inclusion of some of the performance
- X improvements i had suggested to him, this package's
- X encryption/decryption is still slower on the sparc and 68000.
- X more specifically, 19-40% slower on the 68020 and 11-35% slower
- X on the sparc, depending on the compiler;
- X in full gory detail (ALT_ECB is a libdes variant):
- X compiler machine desCore libdes ALT_ECB slower by
- X gcc 2.1 -O2 Sun 3/110 304 uS 369.5uS 461.8uS 22%
- X cc -O1 Sun 3/110 336 uS 436.6uS 399.3uS 19%
- X cc -O2 Sun 3/110 360 uS 532.4uS 505.1uS 40%
- X cc -O4 Sun 3/110 365 uS 532.3uS 505.3uS 38%
- X gcc 2.1 -O2 Sun 4/50 48 uS 53.4uS 57.5uS 11%
- X cc -O2 Sun 4/50 48 uS 64.6uS 64.7uS 35%
- X cc -O4 Sun 4/50 48 uS 64.7uS 64.9uS 35%
- X (my time measurements are not as accurate as his).
- X the comments in my first release of desCore on version 1.92:
- X 68us per encryption (uses 2k of tables)
- X 96us to set a new key (uses 2.25k of key tables)
- X this is a very nice package which implements the most important
- X of the optimizations which i did in my encryption routines.
- X it's a bit weak on common low-level optimizations which is why
- X it's 39%-106% slower. because he was interested in fast crypt(3) and
- X password-cracking applications, he also used the same ideas to
- X speed up the key-setting routines with impressive results.
- X (at some point i may do the same in my package). he also implements
- X the rest of the mit des library.
- X (code from eay@psych.psy.uq.oz.au via comp.sources.misc)
- X
- Xfast crypt(3) package from denmark:
- X the des routine here is buried inside a loop to do the
- X crypt function and i didn't feel like ripping it out and measuring
- X performance. his code takes 26 sparc instructions to compute one
- X des iteration; above, Quick (64k) takes 21 and Small (2k) takes 37.
- X he claims to use 280k of tables but the iteration calculation seems
- X to use only 128k. his tables and code are machine independent.
- X (code from glad@daimi.aau.dk via alt.sources or comp.sources.misc)
- X
- Xswedish reimplementation of Kerberos des library
- X 108us per encryption (uses 34k worth of tables)
- X 134us to set a new key (uses 32k of key tables to get this speed!)
- X the tables used seem to be machine-independent;
- X he seems to have included a lot of special case code
- X so that, e.g., `long' loads can be used instead of 4 `char' loads
- X when the machine's architecture allows it.
- X (code obtained from chalmers.se:pub/des)
- X
- Xcrack 3.3c package from england:
- X as in crypt above, the des routine is buried in a loop. it's
- X also very modified for crypt. his iteration code uses 16k
- X of tables and appears to be slow.
- X (code obtained from aem@aber.ac.uk via alt.sources or comp.sources.misc)
- X
- X``highly optimized'' and tweaked Kerberos/Athena code (byte-order dependent):
- X 165us per encryption (uses 6k worth of tables)
- X 478us to set a new key (uses <1k of key tables)
- X so despite the comments in this code, it was possible to get
- X faster code AND smaller tables, as well as making the tables
- X machine-independent.
- X (code obtained from prep.ai.mit.edu)
- X
- XUC Berkeley code (depends on machine-endedness):
- X 226us per encryption
- X10848us to set a new key
- X table sizes are unclear, but they don't look very small
- X (code obtained from wuarchive.wustl.edu)
- X
- X
- Xmotivation and history
- X
- Xa while ago i wanted some des routines and the routines documented on sun's
- Xman pages either didn't exist or dumped core. i had heard of kerberos,
- Xand knew that it used des, so i figured i'd use its routines. but once
- Xi got it and looked at the code, it really set off a lot of pet peeves -
- Xit was too convoluted, the code had been written without taking
- Xadvantage of the regular structure of operations such as IP, E, and FP
- X(i.e. the author didn't sit down and think before coding),
- Xit was excessively slow, the author had attempted to clarify the code
- Xby adding MORE statements to make the data movement more `consistent'
- Xinstead of simplifying his implementation and cutting down on all data
- Xmovement (in particular, his use of L1, R1, L2, R2), and it was full of
- Xidiotic `tweaks' for particular machines which failed to deliver significant
- Xspeedups but which did obfuscate everything. so i took the test data
- Xfrom his verification program and rewrote everything else.
- X
- Xa while later i ran across the great crypt(3) package mentioned above.
- Xthe fact that this guy was computing 2 sboxes per table lookup rather
- Xthan one (and using a MUCH larger table in the process) emboldened me to
- Xdo the same - it was a trivial change from which i had been scared away
- Xby the larger table size. in his case he didn't realize you don't need to keep
- Xthe working data in TWO forms, one for easy use of half the sboxes in
- Xindexing, the other for easy use of the other half; instead you can keep
- Xit in the form for the first half and use a simple rotate to get the other
- Xhalf. this means i have (almost) half the data manipulation and half
- Xthe table size. in fairness though he might be encoding something particular
- Xto crypt(3) in his tables - i didn't check.
- X
- Xi'm glad that i implemented it the way i did, because this C version is
- Xportable (the ifdef's are performance enhancements) and it is faster
- Xthan versions hand-written in assembly for the sparc!
- X
- X
- Xporting notes
- X
- Xone thing i did not want to do was write an enormous mess
- Xwhich depended on endedness and other machine quirks,
- Xand which necessarily produced different code and different lookup tables
- Xfor different machines. see the kerberos code for an example
- Xof what i didn't want to do; all their endedness-specific `optimizations'
- Xobfuscate the code and in the end were slower than a simpler machine
- Xindependent approach. however, there are always some portability
- Xconsiderations of some kind, and i have included some options
- Xfor varying numbers of register variables.
- Xperhaps some will still regard the result as a mess!
- X
- X1) i assume everything is byte addressable, although i don't actually
- X depend on the byte order, and that bytes are 8 bits.
- X i assume word pointers can be freely cast to and from char pointers.
- X note that 99% of C programs make these assumptions.
- X i always use unsigned char's if the high bit could be set.
- X2) the typedef `word' means a 32 bit unsigned integral type.
- X if `unsigned long' is not 32 bits, change the typedef in desCore.h.
- X i assume sizeof(word) == 4 EVERYWHERE.
- X
- Xthe (worst-case) cost of my NOT doing endedness-specific optimizations
- Xin the data loading and storing code surrounding the key iterations
- Xis less than 12%. also, there is the added benefit that
- Xthe input and output work areas do not need to be word-aligned.
- X
- X
- XOPTIONAL performance optimizations
- X
- X1) you should define one of `i386,' `vax,' `mc68000,' or `sparc,'
- X whichever one is closest to the capabilities of your machine.
- X see the start of desCode.h to see exactly what this selection implies.
- X note that if you select the wrong one, the des code will still work;
- X these are just performance tweaks.
- X2) for those with functional `asm' keywords: you should change the
- X ROR and ROL macros to use machine rotate instructions if you have them.
- X this will save 2 instructions and a temporary per use,
- X or about 32 to 40 instructions per en/decryption.
- X note that gcc is smart enough to translate the ROL/R macros into
- X machine rotates!
- X
- Xthese optimizations are all rather persnickety, yet with them you should
- Xbe able to get performance equal to assembly-coding, except that:
- X1) with the lack of a bit rotate operator in C, rotates have to be synthesized
- X from shifts. so access to `asm' will speed things up if your machine
- X has rotates, as explained above in (3) (not necessary if you use gcc).
- X2) if your machine has less than 12 32-bit registers i doubt your compiler will
- X generate good code.
- X `i386' tries to configure the code for a 386 by only declaring 3 registers
- X (it appears that gcc can use ebx, esi and edi to hold register variables).
- X however, if you like assembly coding, the 386 does have 7 32-bit registers,
- X and if you use ALL of them, use `scaled by 8' address modes with displacement
- X and other tricks, you can get reasonable routines for DesQuickCore... with
- X about 250 instructions apiece. For DesSmall... it will help to rearrange
- X des_keymap, i.e., now the sbox # is the high part of the index and
- X the 6 bits of data is the low part; it helps to exchange these.
- X since i have no way to conveniently test it i have not provided my
- X shoehorned 386 version. note that with this release of desCore, gcc is able
- X to put everything in registers(!), and generate about 370 instructions apiece
- X for the DesQuickCore... routines!
- X
- Xcoding notes
- X
- Xthe en/decryption routines each use 6 necessary register variables,
- Xwith 4 being actively used at once during the inner iterations.
- Xif you don't have 4 register variables get a new machine.
- Xup to 8 more registers are used to hold constants in some configurations.
- X
- Xi assume that the use of a constant is more expensive than using a register:
- Xa) additionally, i have tried to put the larger constants in registers.
- X registering priority was by the following:
- X anything more than 12 bits (bad for RISC and CISC)
- X greater than 127 in value (can't use movq or byte immediate on CISC)
- X 9-127 (may not be able to use CISC shift immediate or add/sub quick),
- X 1-8 were never registered, being the cheapest constants.
- Xb) the compiler may be too stupid to realize table and table+256 should
- X be assigned to different constant registers and instead repetitively
- X do the arithmetic, so i assign these to explicit `m' register variables
- X when possible and helpful.
- X
- Xi assume that indexing is cheaper or equivalent to auto increment/decrement,
- Xwhere the index is 7 bits unsigned or smaller.
- Xthis assumption is reversed for 68k and vax.
- X
- Xi assume that addresses can be cheaply formed from two registers,
- Xor from a register and a small constant.
- Xfor the 68000, the `two registers and small offset' form is used sparingly.
- Xall index scaling is done explicitly - no hidden shifts by log2(sizeof).
- X
- Xthe code is written so that even a dumb compiler
- Xshould never need more than one hidden temporary,
- Xincreasing the chance that everything will fit in the registers.
- XKEEP THIS MORE SUBTLE POINT IN MIND IF YOU REWRITE ANYTHING.
- X(actually, there are some code fragments now which do require two temps,
- Xbut fixing it would either break the structure of the macros or
- Xrequire declaring another temporary).
- X
- X
- Xspecial efficient data format
- X
- Xbits are manipulated in this arrangement most of the time (S7 S5 S3 S1):
- X 003130292827xxxx242322212019xxxx161514131211xxxx080706050403xxxx
- X(the x bits are still there, i'm just emphasizing where the S boxes are).
- Xbits are rotated left 4 when computing S6 S4 S2 S0:
- X 282726252423xxxx201918171615xxxx121110090807xxxx040302010031xxxx
- Xthe rightmost two bits are usually cleared so the lower byte can be used
- Xas an index into an sbox mapping table. the next two x'd bits are set
- Xto various values to access different parts of the tables.
- X
- X
- Xhow to use the routines
- X
- Xdatatypes:
- X pointer to 8 byte area of type DesData
- X used to hold keys and input/output blocks to des.
- X
- X pointer to 128 byte area of type DesKeys
- X used to hold full 768-bit key.
- X must be long-aligned.
- X
- XDesQuickInit()
- X call this before using any other routine with `Quick' in its name.
- X it generates the special 64k table these routines need.
- XDesQuickDone()
- X frees this table
- X
- XDesMethod(m, k)
- X m points to a 128byte block, k points to an 8 byte des key
- X which must have odd parity (or -1 is returned) and which must
- X not be a (semi-)weak key (or -2 is returned).
- X normally DesMethod() returns 0.
- X m is filled in from k so that when one of the routines below
- X is called with m, the routine will act like standard des
- X en/decryption with the key k. if you use DesMethod,
- X you supply a standard 56bit key; however, if you fill in
- X m yourself, you will get a 768bit key - but then it won't
- X be standard. it's 768bits not 1024 because the least significant
- X two bits of each byte are not used. note that these two bits
- X will be set to magic constants which speed up the encryption/decryption
- X on some machines. and yes, each byte controls
- X a specific sbox during a specific iteration.
- X you really shouldn't use the 768bit format directly; i should
- X provide a routine that converts 128 6-bit bytes (specified in
- X S-box mapping order or something) into the right format for you.
- X this would entail some byte concatenation and rotation.
- X
- XDes{Small|Quick}{Fips|Core}{Encrypt|Decrypt}(d, m, s)
- X performs des on the 8 bytes at s into the 8 bytes at d. (d,s: char *).
- X uses m as a 768bit key as explained above.
- X the Encrypt|Decrypt choice is obvious.
- X Fips|Core determines whether a completely standard FIPS initial
- X and final permutation is done; if not, then the data is loaded
- X and stored in a nonstandard bit order (FIPS w/o IP/FP).
- X Fips slows down Quick by 10%, Small by 9%.
- X Small|Quick determines whether you use the normal routine
- X or the crazy quick one which gobbles up 64k more of memory.
- X Small is 50% slower then Quick, but Quick needs 32 times as much
- X memory. Quick is included for programs that do nothing but DES,
- X e.g., encryption filters, etc.
- X
- X
- XGetting it to compile on your machine
- X
- Xthere are no machine-dependencies in the code (see porting),
- Xexcept perhaps the `now()' macro in desTest.c.
- XALL generated tables are machine independent.
- Xyou should edit the Makefile with the appropriate optimization flags
- Xfor your compiler (MAX optimization).
- X
- X
- XSpeeding up kerberos (and/or its des library)
- X
- Xnote that i have included a kerberos-compatible interface in desUtil.c
- Xthrough the functions des_key_sched() and des_ecb_encrypt().
- Xto use these with kerberos or kerberos-compatible code put desCore.a
- Xahead of the kerberos-compatible library on your linker's command line.
- Xyou should not need to #include desCore.h; just include the header
- Xfile provided with the kerberos library.
- X
- XOther uses
- X
- Xthe macros in desCode.h would be very useful for putting inline des
- Xfunctions in more complicated encryption routines.
- END_OF_FILE
- if test 17055 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'desCode.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'desCode.h'\"
- else
- echo shar: Extracting \"'desCode.h'\" \(14436 characters\)
- sed "s/^X//" >'desCode.h' <<'END_OF_FILE'
- X/*
- X * des - fast & portable DES encryption & decryption.
- X * Copyright (C) 1992 Dana L. How
- X * Please see the file `README' for the complete copyright notice.
- X */
- X
- X#ifndef lint
- Xstatic char desCode_hRcs[] = "$Id: desCode.h,v 1.21 1992/05/20 00:00:57 how E $";
- X#endif
- X
- X#include "desCore.h"
- Xextern word des_keymap[], des_bigmap[];
- X
- X
- X/* optional customization:
- X * the idea here is to alter the code so it will still run correctly
- X * on any machine, but the quickest on the specific machine in mind.
- X * note that these silly tweaks can give you a 15%-20% speed improvement
- X * on the sparc -- it's probably even more significant on the 68000. */
- X
- X/* take care of machines with incredibly few registers */
- X#if defined(i386)
- X#define REGISTER /* only x, y, z will be declared register */
- X#else
- X#define REGISTER register
- X#endif /* i386 */
- X
- X/* is auto inc/dec faster than 7bit unsigned indexing? */
- X#if defined(vax) || defined(mc68000)
- X#define FIXR r += 32;
- X#define FIXS s += 8;
- X#define PREV(v,o) *--v
- X#define NEXT(v,o) *v++
- X#define BUMP(v,n)
- X#else
- X#define FIXR
- X#define FIXS
- X#define PREV(v,o) v[o]
- X#define NEXT(v,o) v[o]
- X#define BUMP(v,n) v += n;
- X#endif
- X
- X/* if no machine type, default is indexing, 6 registers and cheap literals */
- X#if !defined(i386) && !defined(vax) && !defined(mc68000) && !defined(sparc)
- X#define vax
- X#endif
- X
- X/* handle a compiler which can't reallocate registers */
- X#if defined(strange) /* didn't feel like deleting */
- X#define SREGFREE ; s = D
- X#define DEST s
- X#define D m0
- X#else
- X#define SREGFREE
- X#define DEST d
- X#define D d
- X#endif
- X
- X/* explanation of configuration macros:
- X * REG..... declares any extra registers needed.
- X * SET..... sets those registers which should hold constants.
- X * .F fiddle with word before xor'ing with key schedule.
- X * .Ln do table lookup number n.
- X * .An accumulate table lookups starting at n.
- X * where the dots are replaced by one of Q(UICK) or S(MALL).
- X */
- X
- X/* handle constants in the optimal way for vax */
- X/* we use 6 variables, all declared register;
- X * we assume address literals are cheap & unrestricted;
- X * we assume immediate constants are cheap & unrestricted.
- X *
- X * note that the low 2 bits in each bit mask can be turned off,
- X * permitting the removal of the pesky -2 and -3 offsets and subsequent
- X * identification of the address literals as CSEs. however, we did _assume_
- X * that address literals were cheap, and this would prevent the translation
- X * of (value >> bits) & mask into a single CISC bitfield instruction. */
- X#if defined(vax)
- X#define REGQUICK
- X#define SETQUICK
- X#define QF(zs) (zs & 0XFCFCFCFCL)
- X#define QL0(z) ADD((byte *)des_bigmap , z & 0XFFFF)
- X#define QL1(z) ADD((byte *)des_bigmap - 2, z >> 16 )
- X#define QL2(z) ADD((byte *)des_bigmap - 0x100 , z & 0XFFFF)
- X#define QL3(z) ADD((byte *)des_bigmap - 0x100 - 2, z >> 16 )
- X#define QA0(x,A,B) x ^= A; x ^= B
- X#define QA2(x,A,B) x ^= A; x ^= B
- X#define REGSMALL
- X#define SETSMALL
- X#define SF(zs) (zs & 0XFCFCFCFCL)
- X#define SL0(z) ADD((byte *)des_keymap - 0, z & 0X3FF)
- X#define SL1(z) ADD((byte *)des_keymap - 3, (z >> 8) & 0X3FF)
- X#define SL2(z) ADD((byte *)des_keymap - 2, (z >> 16) & 0X3FF)
- X#define SL3(z) ADD((byte *)des_keymap - 1, z >> 24 )
- X#define SL4(z) ADD((byte *)des_keymap + 0x400 - 0, z & 0X3FF)
- X#define SL5(z) ADD((byte *)des_keymap + 0x400 - 3, (z >> 8) & 0X3FF)
- X#define SL6(z) ADD((byte *)des_keymap + 0x400 - 2, (z >> 16) & 0X3FF)
- X#define SL7(z) ADD((byte *)des_keymap + 0x400 - 1, z >> 24 )
- X#define SA0(x,A,B,C,D) x ^= A; x ^= B; x ^= C; x ^= D
- X#define SA4(x,A,B,C,D) x ^= A; x ^= B; x ^= C; x ^= D
- X#define UNROLL 1
- X#endif /* defined(vax) */
- X
- X/* handle constants in the optimal way for 386 */
- X/* we declare 3 register variables (see above) and use 3 more variables;
- X * we assume address literals are cheap & unrestricted;
- X * we assume immediate constants are cheap & unrestricted.
- X * so that movzx is used we do NOT turn off the low 2 bits in each bit mask. */
- X#if defined(i386)
- X#define REGQUICK
- X#define SETQUICK
- X#define QF(zs) (zs & 0XFCFCFCFCL)
- X#define QL0(z) ADD((byte *)des_bigmap , z & 0XFFFF)
- X#define QL1(z) ADD((byte *)des_bigmap - 2, z >> 16 )
- X#define QL2(z) ADD((byte *)des_bigmap - 0x100 , z & 0XFFFF)
- X#define QL3(z) ADD((byte *)des_bigmap - 0x100 - 2, z >> 16 )
- X#define QA0(x,A,B) x ^= A; x ^= B
- X#define QA2(x,A,B) x ^= A; x ^= B
- X#define REGSMALL
- X#define SETSMALL
- X#define SF(zs) (zs & 0XFCFCFCFCL)
- X#define SL0(z) ADD((byte *)des_keymap + 0x300 - 0, z & 0X0FF)
- X#define SL1(z) ADD((byte *)des_keymap + 0x200 - 3, (z >>= 8) & 0X0FF)
- X#define SL2(z) ADD((byte *)des_keymap + 0x100 - 2, (z >>= 8) & 0X0FF)
- X#define SL3(z) ADD((byte *)des_keymap - 1, z >>= 8 )
- X#define SL4(z) ADD((byte *)des_keymap + 0x700 - 0, z & 0X0FF)
- X#define SL5(z) ADD((byte *)des_keymap + 0x600 - 3, (z >>= 8) & 0X0FF)
- X#define SL6(z) ADD((byte *)des_keymap + 0x500 - 2, (z >>= 8) & 0X0FF)
- X#define SL7(z) ADD((byte *)des_keymap + 0x400 - 1, z >>= 8 )
- X#define SA0(x,A,B,C,D) x ^= A; x ^= B; x ^= C; x ^= D
- X#define SA4(x,A,B,C,D) x ^= A; x ^= B; x ^= C; x ^= D
- X#define UNROLL 1
- X#endif /* defined(i386) */
- X
- X/* handle constants in the optimal way for mc68000 */
- X/* in addition to the core 6 variables, we declare 3 registers holding constants
- X * and 3 registers holding address literals. `a' accumulates lookups.
- X * at most 6 data values and 4 address values are actively used at once.
- X * we assume address literals are so expensive we never use them;
- X * we assume constant index offsets > 127 are expensive, so they are not used.
- X * we assume all constants are expensive and put them in registers. */
- X#if defined(mc68000)
- X#define REGQUICK \
- X register word a; \
- X register word *e; \
- X register word k0, k1; \
- X register byte *m0, *m1;
- X#define SETQUICK \
- X ; k0 = 0XFFFF \
- X ; k1 = 0XFCFCFCFCL \
- X ; m0 = (byte *)des_bigmap \
- X ; m1 = m0 - 0x100
- X#define QF(zs) (zs & k1)
- X#define QL0(z) ADD(m0 , z & k0)
- X#define QL1(z) ADD(m0 - 2, z >> 16 )
- X#define QL2(z) ADD(m1 , z & k0)
- X#define QL3(z) ADD(m1 - 2, z >> 16 )
- X#define QA0(x,A,B) a = A; a += B
- X#define QA2(x,A,B) a += A; a += B; x ^= a
- X#define REGSMALL \
- X register word a; \
- X register word *e; \
- X register word k0, k1; \
- X register byte *m0, *m1;
- X#define SETSMALL \
- X ; k0 = 0X3FC \
- X ; k1 = 0XFCFCFCFCL \
- X ; m0 = (byte *)des_keymap \
- X ; m1 = m0 + 0x400
- X#define SF(zs) (zs & k1)
- X#define SL0(z) ADD(m0 , z & k0)
- X#define SL1(z) ADD(m0 , (z >>= 8) & k0)
- X#define SL2(z) ADD(m0 , (z >>= 8) & k0)
- X#define SL3(z) ADD(m0 - 1, z >>= 8 )
- X#define SL4(z) ADD(m1 , z & k0)
- X#define SL5(z) ADD(m1 , (z >>= 8) & k0)
- X#define SL6(z) ADD(m1 , (z >>= 8) & k0)
- X#define SL7(z) ADD(m1 - 1, z >>= 8 )
- X#define SA0(x,A,B,C,D) a = A; a += B; a += C; a += D
- X#define SA4(x,A,B,C,D) a += A; a += B; a += C; a += D; x ^= a
- X#define UNROLL 0
- X#endif /* defined(mc68000) */
- X
- X/* handle constants in the optimal way for sparc */
- X/* in addition to the core 6 variables, we either declare:
- X * 4 registers holding address literals and 1 register holding a constant, or
- X * 8 registers holding address literals.
- X * up to 14 register variables are declared (sparc has %i0-%i5, %l0-%l7).
- X * we assume address literals are so expensive we never use them;
- X * we assume any constant with >10 bits is expensive and put it in a register,
- X * and any other is cheap and is coded in-line. */
- X#if defined(sparc)
- X#define REGQUICK \
- X register word k0; \
- X register byte *m0, *m1, *m2, *m3;
- X#define SETQUICK \
- X ; k0 = 0XFCFC \
- X ; m0 = (byte *)des_bigmap \
- X ; m1 = m0 + 0x100 \
- X ; m2 = m1 + 0x100 \
- X ; m3 = m2 + 0x100
- X#define QF(zs) zs
- X#define QL0(z) ADD(m3, z & k0)
- X#define QL1(z) ADD(m1, (z >> 16) & k0)
- X#define QL2(z) ADD(m2, z & k0)
- X#define QL3(z) ADD(m0, (z >> 16) & k0)
- X#define QA0(x,A,B) x ^= A + B
- X#define QA2(x,A,B) x ^= A + B
- X#define REGSMALL \
- X register byte *m0, *m1, *m2, *m3, *m4, *m5, *m6, *m7;
- X#define SETSMALL \
- X ; m0 = (byte *)des_keymap \
- X ; m1 = m0 + 0x100 \
- X ; m2 = m1 + 0x100 \
- X ; m3 = m2 + 0x100 \
- X ; m4 = m3 + 0x100 \
- X ; m5 = m4 + 0x100 \
- X ; m6 = m5 + 0x100 \
- X ; m7 = m6 + 0x100
- X#define SF(zs) zs
- X#define SL0(z) ADD(m3, z & 0XFC)
- X#define SL1(z) ADD(m2, (z >> 8) & 0XFC)
- X#define SL2(z) ADD(m1, (z >> 16) & 0XFC)
- X#define SL3(z) ADD(m0, (z >> 24) & 0XFC)
- X#define SL4(z) ADD(m7, z & 0XFC)
- X#define SL5(z) ADD(m6, (z >> 8) & 0XFC)
- X#define SL6(z) ADD(m5, (z >> 16) & 0XFC)
- X#define SL7(z) ADD(m4, (z >> 24) & 0XFC)
- X#define SA0(x,A,B,C,D) x ^= A + B + C + D
- X#define SA4(x,A,B,C,D) x ^= A + B + C + D
- X#define UNROLL 1
- X#endif /* defined(sparc) */
- X
- X
- X/* some basic stuff */
- X
- X/* generate addresses from a base and an index */
- X#define ADD(b,x) (word *) (b + (x))
- X
- X/* low level rotate operations */
- X#define NOP(d,s,c,o)
- X#define ROL(d,s,c,o) d = s << c | s >> o
- X#define ROR(d,s,c,o) d = s >> c | s << o
- X#define ROL1(d) ROL(d, d, 1, 31)
- X#define ROR1(d) ROR(d, d, 1, 31)
- X
- X/* elementary swap for doing IP/FP */
- X#define SWAP(x,y,m,b) \
- X z = ((x >> b) ^ y) & m; \
- X x ^= z << b; \
- X y ^= z
- X
- X
- X/* the following macros contain all the important code fragments */
- X
- X/* load input data, then setup special registers holding constants */
- X#define TEMPQUICK(LOAD) \
- X REGQUICK \
- X LOAD() \
- X SETQUICK
- X#define TEMPSMALL(LOAD) \
- X REGSMALL \
- X LOAD() \
- X SETSMALL
- X
- X/* load data */
- X#define LOADDATA(x,y) \
- X FIXS \
- X y = PREV(s, 7); y<<= 8; \
- X y |= PREV(s, 6); y<<= 8; \
- X y |= PREV(s, 5); y<<= 8; \
- X y |= PREV(s, 4); \
- X x = PREV(s, 3); x<<= 8; \
- X x |= PREV(s, 2); x<<= 8; \
- X x |= PREV(s, 1); x<<= 8; \
- X x |= PREV(s, 0) \
- X SREGFREE
- X/* load data without initial permutation and put into efficient position */
- X#define LOADCORE() \
- X LOADDATA(x, y); \
- X ROR1(x); \
- X ROR1(y)
- X/* load data, do the initial permutation and put into efficient position */
- X#define LOADFIPS() \
- X LOADDATA(y, x); \
- X SWAP(x, y, 0X0F0F0F0FL, 004); \
- X SWAP(y, x, 0X0000FFFFL, 020); \
- X SWAP(x, y, 0X33333333L, 002); \
- X SWAP(y, x, 0X00FF00FFL, 010); \
- X ROR1(x); \
- X z = (x ^ y) & 0X55555555L; \
- X y ^= z; \
- X x ^= z; \
- X ROR1(y)
- X
- X
- X/* core encryption/decryption operations */
- X/* S box mapping and P perm with 64k of tables */
- X#define KEYMAPQUICK(x,z,zs,r,m,LOAD,qf,ql0,ql1,qa,sf,sl0,sl1,sl2,sl3,sa) \
- X z = qf(zs) ^ LOAD(r, m); \
- X qa(x, *ql0(z), *ql1(z))
- X/* small version: use 2k of tables */
- X#define KEYMAPSMALL(x,z,zs,r,m,LOAD,qf,ql0,ql1,qa,sf,sl0,sl1,sl2,sl3,sa) \
- X z = sf(zs) ^ LOAD(r, m); \
- X sa(x, *sl0(z), *sl1(z), *sl2(z), *sl3(z))
- X/* apply 24 key bits and do the odd s boxes */
- X#define S7S1(x,y,z,r,m,KEYMAP,LOAD,qa,sa) \
- X KEYMAP(x,z,y,r,m,LOAD,QF,QL0,QL1,qa,SF,SL0,SL1,SL2,SL3,sa)
- X/* apply 24 key bits and do the even s boxes */
- X#define S6S0(x,y,z,r,m,KEYMAP,LOAD,qa,sa) \
- X ROL(z, y, 4, 28); \
- X KEYMAP(x,z,z,r,m,LOAD,QF,QL2,QL3,qa,SF,SL4,SL5,SL6,SL7,sa)
- X/* an actual iteration. equivalent except for UPDATE & swapping m and n */
- X#define ENCR(x,y,z,r,m,n,KEYMAP) \
- X S7S1(x,y,z,r,m,KEYMAP,NEXT,QA0,SA0); \
- X S6S0(x,y,z,r,n,KEYMAP,NEXT,QA2,SA4)
- X#define DECR(x,y,z,r,m,n,KEYMAP) \
- X S6S0(x,y,z,r,m,KEYMAP,PREV,QA0,SA0); \
- X S7S1(x,y,z,r,n,KEYMAP,PREV,QA2,SA4)
- X
- X/* write out result in correct byte order */
- X#define SAVEDATA(x,y) \
- X NEXT(DEST, 0) = x; x>>= 8; \
- X NEXT(DEST, 1) = x; x>>= 8; \
- X NEXT(DEST, 2) = x; x>>= 8; \
- X NEXT(DEST, 3) = x; \
- X NEXT(DEST, 4) = y; y>>= 8; \
- X NEXT(DEST, 5) = y; y>>= 8; \
- X NEXT(DEST, 6) = y; y>>= 8; \
- X NEXT(DEST, 7) = y
- X/* write out result */
- X#define SAVECORE() \
- X ROL1(x); \
- X ROL1(y); \
- X SAVEDATA(y, x)
- X/* do final permutation and write out result */
- X#define SAVEFIPS() \
- X ROL1(x); \
- X z = (x ^ y) & 0X55555555L; \
- X y ^= z; \
- X x ^= z; \
- X ROL1(y); \
- X SWAP(x, y, 0X00FF00FFL, 010); \
- X SWAP(y, x, 0X33333333L, 002); \
- X SWAP(x, y, 0X0000FFFFL, 020); \
- X SWAP(y, x, 0X0F0F0F0FL, 004); \
- X SAVEDATA(x, y)
- X
- X
- X/* rolled or unrolled iterations */
- X#if UNROLL
- X#define ENCODE(x,y,z,r,e,KEYMAP) \
- X ENCR(x,y,z,r, 0, 1,KEYMAP); \
- X ENCR(y,x,z,r, 2, 3,KEYMAP); \
- X ENCR(x,y,z,r, 4, 5,KEYMAP); \
- X ENCR(y,x,z,r, 6, 7,KEYMAP); \
- X ENCR(x,y,z,r, 8, 9,KEYMAP); \
- X ENCR(y,x,z,r,10,11,KEYMAP); \
- X ENCR(x,y,z,r,12,13,KEYMAP); \
- X ENCR(y,x,z,r,14,15,KEYMAP); \
- X ENCR(x,y,z,r,16,17,KEYMAP); \
- X ENCR(y,x,z,r,18,19,KEYMAP); \
- X ENCR(x,y,z,r,20,21,KEYMAP); \
- X ENCR(y,x,z,r,22,23,KEYMAP); \
- X ENCR(x,y,z,r,24,25,KEYMAP); \
- X ENCR(y,x,z,r,26,27,KEYMAP); \
- X ENCR(x,y,z,r,28,29,KEYMAP); \
- X ENCR(y,x,z,r,30,31,KEYMAP)
- X#define DECODE(x,y,z,r,e,KEYMAP) \
- X FIXR \
- X DECR(x,y,z,r,31,30,KEYMAP); \
- X DECR(y,x,z,r,29,28,KEYMAP); \
- X DECR(x,y,z,r,27,26,KEYMAP); \
- X DECR(y,x,z,r,25,24,KEYMAP); \
- X DECR(x,y,z,r,23,22,KEYMAP); \
- X DECR(y,x,z,r,21,20,KEYMAP); \
- X DECR(x,y,z,r,19,18,KEYMAP); \
- X DECR(y,x,z,r,17,16,KEYMAP); \
- X DECR(x,y,z,r,15,14,KEYMAP); \
- X DECR(y,x,z,r,13,12,KEYMAP); \
- X DECR(x,y,z,r,11,10,KEYMAP); \
- X DECR(y,x,z,r, 9, 8,KEYMAP); \
- X DECR(x,y,z,r, 7, 6,KEYMAP); \
- X DECR(y,x,z,r, 5, 4,KEYMAP); \
- X DECR(x,y,z,r, 3, 2,KEYMAP); \
- X DECR(y,x,z,r, 1, 0,KEYMAP)
- X#else
- X#define ENCODE(x,y,z,r,e,KEYMAP) \
- X e = r + 32; \
- X do { \
- X ENCR(x,y,z,r, 0, 1,KEYMAP); \
- X ENCR(y,x,z,r, 2, 3,KEYMAP); \
- X BUMP(r, 4) \
- X } while ( r < e )
- X#define DECODE(x,y,z,r,e,KEYMAP) \
- X e = r; \
- X r += 32; \
- X do { \
- X DECR(x,y,z,r,-1,-2,KEYMAP); \
- X DECR(y,x,z,r,-3,-4,KEYMAP); \
- X BUMP(r, -4) \
- X } while ( r > e )
- X#endif
- X
- X
- X/* the following macros contain the encryption/decryption skeletons */
- X
- X#define ENCRYPT(NAME, TEMP, LOAD, KEYMAP, SAVE) \
- X \
- Xvoid \
- XNAME(D, r, s) \
- XREGISTER byte * D; \
- XREGISTER word * r; \
- XREGISTER byte * s; \
- X{ \
- X register word x, y, z; \
- X \
- X /* declare temps & load data */ \
- X TEMP(LOAD); \
- X \
- X /* do the 16 iterations */ \
- X ENCODE(x,y,z,r,e,KEYMAP); \
- X \
- X /* save result */ \
- X SAVE(); \
- X \
- X return; \
- X}
- X
- X#define DECRYPT(NAME, TEMP, LOAD, KEYMAP, SAVE) \
- X \
- Xvoid \
- XNAME(D, r, s) \
- XREGISTER byte * D; \
- XREGISTER word * r; \
- XREGISTER byte * s; \
- X{ \
- X register word x, y, z; \
- X \
- X /* declare temps & load data */ \
- X TEMP(LOAD); \
- X \
- X /* do the 16 iterations */ \
- X DECODE(x,y,z,r,e,KEYMAP); \
- X \
- X /* save result */ \
- X SAVE(); \
- X \
- X return; \
- X}
- END_OF_FILE
- if test 14436 -ne `wc -c <'desCode.h'`; then
- echo shar: \"'desCode.h'\" unpacked with wrong size!
- fi
- # end of 'desCode.h'
- fi
- if test -f 'desCore.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'desCore.h'\"
- else
- echo shar: Extracting \"'desCore.h'\" \(731 characters\)
- sed "s/^X//" >'desCore.h' <<'END_OF_FILE'
- X/*
- X * des - fast & portable DES encryption & decryption.
- X * Copyright (C) 1992 Dana L. How
- X * Please see the file `README' for the complete copyright notice.
- X */
- X
- X#ifndef lint
- Xstatic char desCore_hRcs[] = "$Id: desCore.h,v 1.10 1992/04/16 23:08:44 how E $";
- X#endif
- X
- Xtypedef unsigned char byte, DesData[ 8];
- Xtypedef unsigned long word, DesKeys[32];
- X
- Xextern int DesMethod();
- Xextern void DesQuickInit(), DesQuickDone();
- Xextern void DesQuickCoreEncrypt(), DesQuickFipsEncrypt();
- Xextern void DesQuickCoreDecrypt(), DesQuickFipsDecrypt();
- Xextern void DesSmallCoreEncrypt(), DesSmallFipsEncrypt();
- Xextern void DesSmallCoreDecrypt(), DesSmallFipsDecrypt();
- Xextern void (*DesCryptFuncs[])();
- Xextern int des_key_sched(), des_ecb_encrypt();
- END_OF_FILE
- if test 731 -ne `wc -c <'desCore.h'`; then
- echo shar: \"'desCore.h'\" unpacked with wrong size!
- fi
- # end of 'desCore.h'
- fi
- if test -f 'desKerb.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'desKerb.c'\"
- else
- echo shar: Extracting \"'desKerb.c'\" \(904 characters\)
- sed "s/^X//" >'desKerb.c' <<'END_OF_FILE'
- X/*
- X * des - fast & portable DES encryption & decryption.
- X * Copyright (C) 1992 Dana L. How
- X * Please see the file `README' for the complete copyright notice.
- X */
- X
- X#ifndef lint
- Xstatic char desKerb_cRcs[] = "$Id: desKerb.c,v 1.3 1992/05/19 23:59:24 how E $";
- X#endif
- X
- X#include "desCore.h"
- X
- X
- X/* permit the default style of des functions to be changed */
- X
- Xvoid (*DesCryptFuncs[2])() = { DesSmallFipsDecrypt, DesSmallFipsEncrypt };
- X
- X/* kerberos-compatible key schedule function */
- X
- Xint
- Xdes_key_sched(k, s)
- Xbyte * k;
- Xword * s;
- X{
- X return DesMethod(s, k);
- X}
- X
- X/* kerberos-compatible des coding function */
- X
- Xint
- Xdes_ecb_encrypt(s, d, r, e)
- Xbyte * s, * d;
- Xword * r;
- Xint e;
- X{
- X (*DesCryptFuncs[e])(d, r, s);
- X return 0;
- X}
- X
- X/* also needs to be defined, as pointed out by eay@psych.psy.uq.oz.au */
- X
- Xint
- Xdes_encrypt(s, d, r, e)
- Xbyte * s, * d;
- Xword * r;
- Xint e;
- X{
- X (*DesCryptFuncs[e])(d, r, s);
- X return 0;
- X}
- END_OF_FILE
- if test 904 -ne `wc -c <'desKerb.c'`; then
- echo shar: \"'desKerb.c'\" unpacked with wrong size!
- fi
- # end of 'desKerb.c'
- fi
- if test -f 'desQuick.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'desQuick.c'\"
- else
- echo shar: Extracting \"'desQuick.c'\" \(1039 characters\)
- sed "s/^X//" >'desQuick.c' <<'END_OF_FILE'
- X/*
- X * des - fast & portable DES encryption & decryption.
- X * Copyright (C) 1992 Dana L. How
- X * Please see the file `README' for the complete copyright notice.
- X */
- X
- X#ifndef lint
- Xstatic char desQuick_cRcs[] = "$Id: desQuick.c,v 1.5 1992/05/15 05:48:28 how E $";
- X#endif
- X
- X#include "desCore.h"
- Xextern word des_keymap[];
- X
- X
- X/* static information */
- X
- Xstatic depth = 0; /* keep track of the request depth */
- Xword des_bigmap[0x4000]; /* big lookup table */
- X
- X/* fill in the 64k table used by the `quick' option */
- X
- Xvoid
- XDesQuickInit()
- X{
- X int s1, s3, x;
- X word * t0, * t1, * t2, * t3;
- X
- X if ( depth++ )
- X return;
- X
- X t0 = des_bigmap;
- X t1 = t0 + 64;
- X t2 = t1 + 64;
- X t3 = t2 + 64;
- X
- X for ( s3 = 63; s3 >= 0; s3-- ) {
- X for ( s1 = 63; s1 >= 0; s1-- ) {
- X x = (s3 << 8) | s1;
- X t3[x] = des_keymap[s3+128] ^ des_keymap[s1+192];
- X t1[x] = des_keymap[s3 ] ^ des_keymap[s1+ 64];
- X t2[x] = des_keymap[s3+384] ^ des_keymap[s1+448];
- X t0[x] = des_keymap[s3+256] ^ des_keymap[s1+320];
- X }
- X }
- X}
- X
- X/* free the 64k table, if necessary */
- X
- Xvoid
- XDesQuickDone()
- X{
- X}
- END_OF_FILE
- if test 1039 -ne `wc -c <'desQuick.c'`; then
- echo shar: \"'desQuick.c'\" unpacked with wrong size!
- fi
- # end of 'desQuick.c'
- fi
- if test -f 'desTest.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'desTest.c'\"
- else
- echo shar: Extracting \"'desTest.c'\" \(4027 characters\)
- sed "s/^X//" >'desTest.c' <<'END_OF_FILE'
- X/*
- X * des - fast & portable DES encryption & decryption.
- X * Copyright (C) 1992 Dana L. How
- X * Please see the file `README' for the complete copyright notice.
- X *
- X * Exercise the DES routines and collect performance statistics.
- X */
- X
- X#ifndef lint
- Xstatic char desTest_cRcs[] = "$Id: desTest.c,v 1.10 1992/04/17 00:44:15 how E $";
- X#endif
- X
- Xextern printf();
- X
- X#include "desCore.h"
- X
- X/* define now(w) to be the elapsed time in hundredths of a second */
- X
- X#include <sys/time.h>
- X#include <sys/resource.h>
- Xextern getrusage();
- Xstatic struct rusage usage;
- X#define now(w) ( \
- X (void)getrusage(RUSAGE_SELF, &usage), \
- X usage.ru_utime.tv_sec * 100 + \
- X usage.ru_utime.tv_usec / 10000 \
- X )
- X
- X/* test data
- X * the tests (key0-3, text0-3) are cribbed from code which is (c) 1988 MIT
- X */
- X
- Xbyte keyt[8] = {0x5d, 0x85, 0x91, 0x73, 0xcb, 0x49, 0xdf, 0x2f};
- Xbyte key0[8] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80};
- Xbyte key1[8] = {0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
- Xbyte key2[8] = {0x08, 0x19, 0x2a, 0x3b, 0x4c, 0x5d, 0x6e, 0x7f};
- Xbyte key3[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
- Xbyte textt[8] = {0x67, 0x1f, 0xc8, 0x93, 0x46, 0x5e, 0xab, 0x1e};
- Xbyte text0[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- Xbyte text1[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40};
- Xbyte text2[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- Xbyte text3[8] = {'N', 'o', 'w', ' ', 'i', 's', ' ', 't' };
- X
- X/* work areas */
- X
- XDesKeys keys;
- Xbyte cipher[8], output[8];
- X
- X/* noisy interfaces to the routines under test */
- X
- Xstatic void
- Xmethod(key)
- Xbyte *key;
- X{
- X int j;
- X
- X (void)printf("\nkey:\t");
- X for ( j = 0; j < 8; j++ )
- X (void)printf("%02X ", key[j]);
- X if ( des_key_sched(key, keys) )
- X (void)printf("W");
- X (void)printf("\t");
- X}
- X
- Xstatic void
- Xencode(src, dst)
- Xbyte *src, *dst;
- X{
- X int j;
- X
- X (void)printf("clear:\t");
- X for (j = 0; j < 8; j++)
- X (void)printf("%02X ", src[j]);
- X
- X (void)des_ecb_encrypt(src, dst, keys, 1);
- X
- X (void)printf("\tcipher:\t");
- X for (j = 0; j < 8; j++)
- X (void)printf("%02X ", dst[j]);
- X (void)printf("\n");
- X}
- X
- Xstatic void
- Xdecode(src, dst)
- Xbyte *src, *dst;
- X{
- X int j;
- X
- X (void)printf("cipher:\t");
- X for (j = 0; j < 8; j++)
- X (void)printf("%02X ", src[j]);
- X
- X (void)des_ecb_encrypt(src, dst, keys, 0);
- X
- X (void)printf("\tclear:\t");
- X for (j = 0; j < 8; j++)
- X (void)printf("%02X ", dst[j]);
- X (void)printf("\n");
- X}
- X
- X/* run the tests */
- X
- Xint
- Xmain()
- X{
- X int j, m, e, n;
- X void (*f)();
- X static char * expect[] = {
- X "57 99 F7 2A D2 3F AE 4C", "9C C6 2D F4 3B 6E ED 74",
- X "90 E6 96 A2 AD 56 50 0D", "A3 80 E0 2A 6B E5 46 96",
- X "43 5C FF C5 68 B3 70 1D", "25 DD AC 3E 96 17 64 67",
- X "80 B5 07 E1 E6 A7 47 3D", "3F A4 0E 8A 98 4D 48 15",
- X };
- X static void (*funcs[])() = {
- X DesQuickCoreEncrypt, DesQuickFipsEncrypt,
- X DesSmallCoreEncrypt, DesSmallFipsEncrypt,
- X DesQuickCoreDecrypt, DesQuickFipsDecrypt,
- X DesSmallCoreDecrypt, DesSmallFipsDecrypt };
- X static char * names[] = {
- X "QuickCore", "QuickFips",
- X "SmallCore", "SmallFips" };
- X
- X n = 0;
- X DesQuickInit();
- X
- X /* do timing info first */
- X
- X f = (void (*)())DesMethod;
- X j = 10000;
- X m = now(0);
- X do
- X (*f)(keys, keyt);
- X while ( --j );
- X m = now(1) - m;
- X
- X do {
- X DesCryptFuncs[0] = funcs[n+4];
- X f = DesCryptFuncs[1] = funcs[n ];
- X j = 100000;
- X e = now(0);
- X do
- X (*f)(cipher, keys, textt);
- X while ( --j );
- X e = now(1) - e;
- X
- X (void)printf( "%s: setkey,%5duS; encode,%3d.%1duS.\n",
- X names[n], m, e/10, e%10);
- X
- X /* now check functionality */
- X
- X method(key0);
- X (void)printf("cipher?\t%s\n", expect[(n % 2) + 0]);
- X encode(text0, cipher);
- X decode(cipher, output);
- X
- X method(key1);
- X (void)printf("cipher?\t%s\n", expect[(n % 2) + 2]);
- X encode(text1, cipher);
- X decode(cipher, output);
- X
- X method(key2);
- X (void)printf("cipher?\t%s\n", expect[(n % 2) + 4]);
- X encode(text2, cipher);
- X decode(cipher, output);
- X
- X method(key3);
- X (void)printf("cipher?\t%s\n", expect[(n % 2) + 6]);
- X encode(text3, cipher);
- X decode(cipher, output);
- X
- X (void)printf("%c", "\n\f\n\0"[n]);
- X
- X } while ( ++n < 4 );
- X
- X DesQuickDone();
- X return 0;
- X}
- END_OF_FILE
- if test 4027 -ne `wc -c <'desTest.c'`; then
- echo shar: \"'desTest.c'\" unpacked with wrong size!
- fi
- # end of 'desTest.c'
- fi
- if test -f 'desUtil.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'desUtil.c'\"
- else
- echo shar: Extracting \"'desUtil.c'\" \(4296 characters\)
- sed "s/^X//" >'desUtil.c' <<'END_OF_FILE'
- X/*
- X * des - fast & portable DES encryption & decryption.
- X * Copyright (C) 1992 Dana L. How
- X * Please see the file `README' for the complete copyright notice.
- X */
- X
- X#ifndef lint
- Xstatic char desUtil_cRcs[] = "$Id: desUtil.c,v 1.13 1992/05/15 07:58:20 how E $";
- X#endif
- X
- X#include "desCode.h"
- X
- X
- X/* various tables */
- X
- Xword des_keymap[] = {
- X#include "keymap.h"
- X};
- X
- Xstatic byte rotors[] = {
- X#include "rotors.h"
- X};
- Xstatic char parity[] = {
- X#include "parity.h"
- X};
- X
- X#ifndef lint
- Xstatic char ego[] = "\n\nFast DES Library Copyright (c) 1991 Dana L. How\n\n";
- X#endif
- X
- X
- X/* set up the method list from the key */
- X
- Xint
- XDesMethod(method, k)
- Xregister word * method;
- Xregister byte * k;
- X{
- X register word n, w;
- X register char * b0, * b1;
- X char bits0[56], bits1[56];
- X
- X /* check for bad parity and weak keys */
- X b0 = parity;
- X n = b0[k[0]]; n <<= 4;
- X n |= b0[k[1]]; n <<= 4;
- X n |= b0[k[2]]; n <<= 4;
- X n |= b0[k[3]]; n <<= 4;
- X n |= b0[k[4]]; n <<= 4;
- X n |= b0[k[5]]; n <<= 4;
- X n |= b0[k[6]]; n <<= 4;
- X n |= b0[k[7]];
- X w = 0X88888888L;
- X /* report bad parity in key */
- X if ( n & w )
- X return -1;
- X /* report a weak or semi-weak key */
- X if ( !((n - (w >> 3)) & w) ) { /* 1 in 10^10 keys passes this test */
- X if ( n < 0X41415151 ) {
- X if ( n < 0X31312121 ) {
- X if ( n < 0X14141515 ) {
- X /* 01 01 01 01 01 01 01 01 */
- X if ( n == 0X11111111 ) return -2;
- X /* 01 1F 01 1F 01 0E 01 0E */
- X if ( n == 0X13131212 ) return -2;
- X } else {
- X /* 01 E0 01 E0 01 F1 01 F1 */
- X if ( n == 0X14141515 ) return -2;
- X /* 01 FE 01 FE 01 FE 01 FE */
- X if ( n == 0X16161616 ) return -2;
- X }
- X } else {
- X if ( n < 0X34342525 ) {
- X /* 1F 01 1F 01 0E 01 0E 01 */
- X if ( n == 0X31312121 ) return -2;
- X /* 1F 1F 1F 1F 0E 0E 0E 0E */ /* ? */
- X if ( n == 0X33332222 ) return -2;
- X } else {
- X /* 1F E0 1F E0 0E F1 0E F1 */
- X if ( n == 0X34342525 ) return -2;
- X /* 1F FE 1F FE 0E FE 0E FE */
- X if ( n == 0X36362626 ) return -2;
- X }
- X }
- X } else {
- X if ( n < 0X61616161 ) {
- X if ( n < 0X44445555 ) {
- X /* E0 01 E0 01 F1 01 F1 01 */
- X if ( n == 0X41415151 ) return -2;
- X /* E0 1F E0 1F F1 0E F1 0E */
- X if ( n == 0X43435252 ) return -2;
- X } else {
- X /* E0 E0 E0 E0 F1 F1 F1 F1 */ /* ? */
- X if ( n == 0X44445555 ) return -2;
- X /* E0 FE E0 FE F1 FE F1 FE */
- X if ( n == 0X46465656 ) return -2;
- X }
- X } else {
- X if ( n < 0X64646565 ) {
- X /* FE 01 FE 01 FE 01 FE 01 */
- X if ( n == 0X61616161 ) return -2;
- X /* FE 1F FE 1F FE 0E FE 0E */
- X if ( n == 0X63636262 ) return -2;
- X } else {
- X /* FE E0 FE E0 FE F1 FE F1 */
- X if ( n == 0X64646565 ) return -2;
- X /* FE FE FE FE FE FE FE FE */
- X if ( n == 0X66666666 ) return -2;
- X }
- X }
- X }
- X }
- X
- X /* explode the bits */
- X n = 56;
- X b0 = bits0;
- X b1 = bits1;
- X do {
- X w = (256 | *k++) << 2;
- X do {
- X --n;
- X b1[n] = 8 & w;
- X w >>= 1;
- X b0[n] = 4 & w;
- X } while ( w >= 16 );
- X } while ( n );
- X
- X /* put the bits in the correct places */
- X /* the inclusion of constant bits is inspired by ideas and code
- X * from Richard Outerbridge; see desCode.h for how they're used */
- X n = 16;
- X k = rotors;
- X do {
- X w = (b1[k[ 0 ]] | b0[k[ 1 ]]) << 4;
- X w |= (b1[k[ 2 ]] | b0[k[ 3 ]]) << 2;
- X w |= b1[k[ 4 ]] | b0[k[ 5 ]];
- X w <<= 8;
- X w |= (b1[k[ 6 ]] | b0[k[ 7 ]]) << 4;
- X w |= (b1[k[ 8 ]] | b0[k[ 9 ]]) << 2;
- X w |= b1[k[10 ]] | b0[k[11 ]];
- X w <<= 8;
- X w |= (b1[k[12 ]] | b0[k[13 ]]) << 4;
- X w |= (b1[k[14 ]] | b0[k[15 ]]) << 2;
- X w |= b1[k[16 ]] | b0[k[17 ]];
- X w <<= 8;
- X w |= (b1[k[18 ]] | b0[k[19 ]]) << 4;
- X w |= (b1[k[20 ]] | b0[k[21 ]]) << 2;
- X w |= b1[k[22 ]] | b0[k[23 ]];
- X
- X method[0] = w | 0X01020300L;
- X
- X w = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4;
- X w |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2;
- X w |= b1[k[ 4+24]] | b0[k[ 5+24]];
- X w <<= 8;
- X w |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4;
- X w |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2;
- X w |= b1[k[10+24]] | b0[k[11+24]];
- X w <<= 8;
- X w |= (b1[k[12+24]] | b0[k[13+24]]) << 4;
- X w |= (b1[k[14+24]] | b0[k[15+24]]) << 2;
- X w |= b1[k[16+24]] | b0[k[17+24]];
- X w <<= 8;
- X w |= (b1[k[18+24]] | b0[k[19+24]]) << 4;
- X w |= (b1[k[20+24]] | b0[k[21+24]]) << 2;
- X w |= b1[k[22+24]] | b0[k[23+24]];
- X
- X method[1] = w | 0X01020300L;
- X
- X k += 48;
- X method += 2;
- X } while ( --n );
- X
- X return 0;
- X}
- END_OF_FILE
- if test 4296 -ne `wc -c <'desUtil.c'`; then
- echo shar: \"'desUtil.c'\" unpacked with wrong size!
- fi
- # end of 'desUtil.c'
- fi
- if test -f 'desdata.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'desdata.c'\"
- else
- echo shar: Extracting \"'desdata.c'\" \(4512 characters\)
- sed "s/^X//" >'desdata.c' <<'END_OF_FILE'
- X/*
- X * des - fast & portable DES encryption & decryption.
- X * Copyright (C) 1992 Dana L. How
- X * Please see the file `README' for the complete copyright notice.
- X *
- X * Generate tables used by desUtil.c and desCode.h.
- X */
- X
- X#ifndef lint
- Xstatic char desdata_cRcs[] = "$Id: desdata.c,v 1.11 1992/05/15 05:47:37 how E $";
- X#endif
- X
- X#include "desinfo.h"
- X
- X#include "desCode.h"
- X
- X/* list of weak and semi-weak keys
- X
- X +0 +1 +2 +3 +4 +5 +6 +7
- X 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01
- X 0x01 0x1f 0x01 0x1f 0x01 0x0e 0x01 0x0e
- X 0x01 0xe0 0x01 0xe0 0x01 0xf1 0x01 0xf1
- X 0x01 0xfe 0x01 0xfe 0x01 0xfe 0x01 0xfe
- X 0x1f 0x01 0x1f 0x01 0x0e 0x01 0x0e 0x01
- X 0x1f 0x1f 0x1f 0x1f 0x0e 0x0e 0x0e 0x0e
- X 0x1f 0xe0 0x1f 0xe0 0x0e 0xf1 0x0e 0xf1
- X 0x1f 0xfe 0x1f 0xfe 0x0e 0xfe 0x0e 0xfe
- X 0xe0 0x01 0xe0 0x01 0xf1 0x01 0xf1 0x01
- X 0xe0 0x1f 0xe0 0x1f 0xf1 0x0e 0xf1 0x0e
- X 0xe0 0xe0 0xe0 0xe0 0xf1 0xf1 0xf1 0xf1
- X 0xe0 0xfe 0xe0 0xfe 0xf1 0xfe 0xf1 0xfe
- X 0xfe 0x01 0xfe 0x01 0xfe 0x01 0xfe 0x01
- X 0xfe 0x1f 0xfe 0x1f 0xfe 0x0e 0xfe 0x0e
- X 0xfe 0xe0 0xfe 0xe0 0xfe 0xf1 0xfe 0xf1
- X 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe
- X */
- X
- X/* key bit order in each method pair: bits 31->00 of 1st, bits 31->00 of 2nd */
- X/* this does not reflect the rotate of the 2nd word */
- X
- X#define S(box,bit) (box*6+bit)
- Xint korder[] = {
- X S(7, 5), S(7, 4), S(7, 3), S(7, 2), S(7, 1), S(7, 0),
- X S(5, 5), S(5, 4), S(5, 3), S(5, 2), S(5, 1), S(5, 0),
- X S(3, 5), S(3, 4), S(3, 3), S(3, 2), S(3, 1), S(3, 0),
- X S(1, 5), S(1, 4), S(1, 3), S(1, 2), S(1, 1), S(1, 0),
- X S(6, 5), S(6, 4), S(6, 3), S(6, 2), S(6, 1), S(6, 0),
- X S(4, 5), S(4, 4), S(4, 3), S(4, 2), S(4, 1), S(4, 0),
- X S(2, 5), S(2, 4), S(2, 3), S(2, 2), S(2, 1), S(2, 0),
- X S(0, 5), S(0, 4), S(0, 3), S(0, 2), S(0, 1), S(0, 0),
- X};
- X
- X/* the order in which the algorithm accesses the s boxes */
- X
- Xint sorder[] = {
- X 7, 5, 3, 1, 6, 4, 2, 0,
- X};
- X
- Xint
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X word d, i, j, k, l, m, n, s;
- X char b[256], ksr[56];
- X extern printf();
- X
- X switch ( argv[1][0] ) {
- X
- X /*
- X * <<< make the key parity table >>>
- X */
- X
- Xcase 'p':
- X (void)printf(
- X"/* automagically produced - do not fuss with this information */\n\n");
- X
- X /* store parity information */
- X for ( i = 0; i < 256; i++ ) {
- X j = i;
- X j ^= j >> 4; /* bits 3-0 have pairs */
- X j ^= j << 2; /* bits 3-2 have quads */
- X j ^= j << 1; /* bit 3 has the entire eight (no cox) */
- X b[i] = 8 & ~j; /* 0 is okay and 8 is bad parity */
- X }
- X
- X /* only these characters can appear in a weak key */
- X b[0x01] = 1;
- X b[0x0e] = 2;
- X b[0x1f] = 3;
- X b[0xe0] = 4;
- X b[0xf1] = 5;
- X b[0xfe] = 6;
- X
- X /* print it out */
- X for ( i = 0; i < 256; i++ ) {
- X (void)printf("%d,", b[i]);
- X if ( (i & 31) == 31 )
- X (void)printf("\n");
- X }
- X
- X break;
- X
- X
- X /*
- X * <<< make the key usage table >>>
- X */
- X
- Xcase 'r':
- X (void)printf("/* automagically made - do not fuss with this */\n\n");
- X
- X /* KL specifies the initial key bit positions */
- X for (i = 0; i < 56; i++)
- X ksr[i] = (KL[i] - 1) ^ 7;
- X
- X for (i = 0; i < 16; i++) {
- X
- X /* apply the appropriate number of left shifts */
- X for (j = 0; j < KS[i]; j++) {
- X m = ksr[ 0];
- X n = ksr[28];
- X for (k = 0; k < 27; k++)
- X ksr[k ] = ksr[k + 1],
- X ksr[k + 28] = ksr[k + 29];
- X ksr[27] = m;
- X ksr[55] = n;
- X }
- X
- X /* output the key bit numbers */
- X for (j = 0; j < 48; j++) {
- X m = ksr[KC[korder[j]] - 1];
- X m = (m / 8) * 7 + (m % 8) - 1;
- X m = 55 - m;
- X (void)printf(" %2d,", m);
- X if ((j % 12) == 11)
- X (void)printf("\n");
- X }
- X (void)printf("\n");
- X }
- X
- X break;
- X
- X
- X /*
- X * <<< make the keymap table >>>
- X */
- X
- Xcase 'k':
- X (void)printf("/* automagically made - do not fuss with this */\n\n");
- X
- X for ( i = 0; i <= 7 ; i++ ) {
- X s = sorder[i];
- X for ( d = 0; d <= 63; d++ ) {
- X /* flip bits */
- X k = ((d << 5) & 32) |
- X ((d << 3) & 16) |
- X ((d << 1) & 8) |
- X ((d >> 1) & 4) |
- X ((d >> 3) & 2) |
- X ((d >> 5) & 1) ;
- X /* more bit twiddling */
- X l = ((k << 0) & 32) | /* overlap bit */
- X ((k << 4) & 16) | /* overlap bit */
- X ((k >> 1) & 15) ; /* unique bits */
- X /* look up s box value */
- X m = SB[s][l];
- X /* flip bits */
- X n = ((m << 3) & 8) |
- X ((m << 1) & 4) |
- X ((m >> 1) & 2) |
- X ((m >> 3) & 1) ;
- X /* put in correct nybble */
- X n <<= (s << 2);
- X /* perform p permutation */
- X for ( m = j = 0; j < 32; j++ )
- X if ( n & (1 << (SP[j] - 1)) )
- X m |= (1 << j);
- X /* rotate right (alg keeps everything rotated by 1) */
- X ROR1(m);
- X /* print it out */
- X (void)printf(" 0x%08lx,", m);
- X if ( ( d & 3 ) == 3 )
- X (void)printf("\n");
- X }
- X (void)printf("\n");
- X }
- X
- X break;
- X
- X }
- X
- X return 0;
- X}
- END_OF_FILE
- if test 4512 -ne `wc -c <'desdata.c'`; then
- echo shar: \"'desdata.c'\" unpacked with wrong size!
- fi
- # end of 'desdata.c'
- fi
- if test -f 'desinfo.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'desinfo.h'\"
- else
- echo shar: Extracting \"'desinfo.h'\" \(3506 characters\)
- sed "s/^X//" >'desinfo.h' <<'END_OF_FILE'
- X/*
- X * des - fast & portable DES encryption & decryption.
- X * Copyright (C) 1992 Dana L. How
- X * Please see the file `README' for the complete copyright notice.
- X *
- X * Tables describing DES rather than just this implementation.
- X * These are used in desdata but NOT in runtime code.
- X */
- X
- X#ifndef lint
- Xstatic char desinfo_hRcs[] = "$Id: desinfo.h,v 1.3 1992/04/16 23:08:44 how E $";
- X#endif
- X
- X/* the initial permutation, E selection, and final permutation are hardwired */
- X
- X/* Key Load: how to load the shift register from the user key */
- X
- Xchar KL[] = {
- X
- X 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
- X 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
- X
- X 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
- X 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4,
- X};
- X
- X/* Key Shift: how many times to shift the key shift register */
- X
- Xchar KS[] = {
- X
- X 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
- X};
- X
- X/* Key Choose: which key bits from shift reg are used in the key schedule */
- X
- Xchar KC[] = {
- X
- X 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
- X 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
- X
- X 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
- X 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32,
- X};
- X
- X/* S Boxes */
- X
- Xchar SB[8][64] = {
- X
- X 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
- X 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
- X 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
- X 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
- X
- X 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
- X 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
- X 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
- X 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
- X
- X 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
- X 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
- X 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
- X 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
- X
- X 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
- X 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
- X 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
- X 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
- X
- X 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
- X 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
- X 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
- X 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
- X
- X 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
- X 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
- X 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
- X 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
- X
- X 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
- X 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
- X 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
- X 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
- X
- X 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
- X 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
- X 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
- X 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
- X};
- X
- X/* Sbox Permutation */
- X
- Xchar SP[] = {
- X
- X 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
- X 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25,
- X};
- END_OF_FILE
- if test 3506 -ne `wc -c <'desinfo.h'`; then
- echo shar: \"'desinfo.h'\" unpacked with wrong size!
- fi
- # end of 'desinfo.h'
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have the archive.
- echo "now run make"
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- exit 0 # Just in case...
-