From f5ee65e487cd3843fa0f175d0e518df50b390107 Mon Sep 17 00:00:00 2001 From: csgr Date: Wed, 7 Sep 1994 21:18:08 +0000 Subject: Bring in the 1.1.x international libcrypt, which will in due course become libcipher. Based on David Burren's FreeSEC Submitted by: Geoff. --- secure/lib/libcipher/Makefile | 15 + secure/lib/libcipher/README | 98 +++++ secure/lib/libcipher/README.FreeBSD | 6 + secure/lib/libcipher/crypt.3 | 236 +++++++++++ secure/lib/libcipher/crypt.c | 730 +++++++++++++++++++++++++++++++++ secure/lib/libcipher/test/Makefile | 55 +++ secure/lib/libcipher/test/README | 10 + secure/lib/libcipher/test/cert.c | 344 ++++++++++++++++ secure/lib/libcipher/test/cert.input | 179 ++++++++ secure/lib/libcipher/test/speedcrypt.c | 76 ++++ secure/lib/libcipher/test/speeddes.c | 61 +++ 11 files changed, 1810 insertions(+) create mode 100644 secure/lib/libcipher/Makefile create mode 100644 secure/lib/libcipher/README create mode 100644 secure/lib/libcipher/README.FreeBSD create mode 100644 secure/lib/libcipher/crypt.3 create mode 100644 secure/lib/libcipher/crypt.c create mode 100644 secure/lib/libcipher/test/Makefile create mode 100644 secure/lib/libcipher/test/README create mode 100644 secure/lib/libcipher/test/cert.c create mode 100644 secure/lib/libcipher/test/cert.input create mode 100644 secure/lib/libcipher/test/speedcrypt.c create mode 100644 secure/lib/libcipher/test/speeddes.c (limited to 'secure') diff --git a/secure/lib/libcipher/Makefile b/secure/lib/libcipher/Makefile new file mode 100644 index 0000000..47650e5 --- /dev/null +++ b/secure/lib/libcipher/Makefile @@ -0,0 +1,15 @@ +# +# $Id: Makefile,v 1.1 1994/09/07 08:55:24 g89r4222 Exp $ +# + +SUBDIR= test + +LIB= crypt +SRCS= crypt.c + +#MAN3= crypt.0 +#MLINKS= crypt.3 encrypt.3 crypt.3 setkey.3 +#MLINKS+=crypt.3 des_cipher.3 crypt.3 des_setkey.3 + +.include +.include diff --git a/secure/lib/libcipher/README b/secure/lib/libcipher/README new file mode 100644 index 0000000..53ea229 --- /dev/null +++ b/secure/lib/libcipher/README @@ -0,0 +1,98 @@ + + FreeSec - NetBSD libcrypt replacement + + David Burren + Release 1.0, March 1994 + + Document ref: $Id: README,v 1.1 1994/09/07 08:55:24 g89r4222 Exp $ + + +Description +=========== +This library is a drop-in replacement for the libcrypt used in U.S. copies +of NetBSD, duplicating that library's functionality. A suite of verification +and benchmark tools is provided. + +FreeSec 1.0 is an original implementation of the DES algorithm and the +crypt(3) interfaces used in Unix-style operating systems. It was produced +in Australia and as such is not covered by U.S. export restrictions (at +least for copies that remain outside the U.S.). + + +History +======= +An earlier version of the FreeSec library was built using the UFC-crypt +package that is distributed as part of the GNU library. UFC-crypt did not +support the des_cipher() or des_setkey() functions, nor the new-style +crypt with long keys. These were implemented in FreeSec 0.2, but at least +one bug remained, where encryption would only succeed if either the salt +or the plaintext was zero. Because of its heritage FreeSec 0.2 was covered +by the GNU Library Licence. + +FreeSec 1.0 is an original implementation by myself, and has been tested +against the verification suite I'd been using with FreeSec 0.2 (this is not +encumbered by any licence). FreeSec 1.0 is covered by a Berkeley-style +licence, which better fits into the *BSD hierarchy than the earlier GNU +licence. + + +Why should you use FreeSec? +=========================== +FreeSec is intended as a replacement for the U.S.-only NetBSD libcrypt, +to act as a baseline for encryption functionality. + +Some other packages (such as Eric Young's libdes package) are faster and +more complete than FreeSec, but typically have different licencing +arrangements. While some applications will justify the use of these +packages, the idea here is that everyone should have access to *at least* +the functionality of FreeSec. + + +Performance of FreeSec 1.0 +========================== +I compare below the performance of three libcrypt implementations. As can be +seen, it's between the U.S. library and UFC-crypt. While the performance of +FreeSec 1.0 is good enough to keep me happy for now, I hope to improve it in +future versions. I was interested to note that while UFC-crypt is faster on +a 386, hardware characteristics can have markedly different effects on each +implementation. + + +386DX40, 128k cache | U.S. BSD | FreeSec 1.0 | FreeSec 0.2 +CFLAGS=-O2 | | | +========================+===============+===============+================== +crypt (alternate keys) | 317 | 341 | 395 + crypt/sec | | | +------------------------+---------------+---------------+------------------ +crypt (constant key) | 317 | 368 | 436 + crypt/sec | | | +------------------------+---------------+---------------+------------------ +des_cipher( , , , 1) | 6037 | 7459 | 3343 + blocks/sec | | | +------------------------+---------------+---------------+------------------ +des_cipher( , , , 25) | 8871 | 9627 | 15926 + blocks/sec | | | + +Notes: The results tabled here are the average over 10 runs. + The entry/exit code for FreeSec 0.2's des_cipher() is particularly + inefficient, thus the anomalous result for single encryptions. + + +As an experiment using a machine with a larger register set and an +obscenely fast CPU, I obtained the following results: + + 60 MHz R4400 | FreeSec 1.0 | FreeSec 0.2 + ========================+================================= + crypt (alternate keys) | 2545 | 2702 + crypt/sec | | + ------------------------+--------------------------------- + crypt (constant key) | 2852 | 2981 + crypt/sec | | + ------------------------+--------------------------------- + des_cipher( , , , 1) | 56443 | 21409 + blocks/sec | | + ------------------------+--------------------------------- + des_cipher( , , , 25) | 82531 | 18276 + blocks/sec | | + +Obviously your mileage will vary with your hardware and your compiler... diff --git a/secure/lib/libcipher/README.FreeBSD b/secure/lib/libcipher/README.FreeBSD new file mode 100644 index 0000000..06b943f --- /dev/null +++ b/secure/lib/libcipher/README.FreeBSD @@ -0,0 +1,6 @@ +$Id: README.FreeBSD,v 1.1 1994/09/07 08:55:25 g89r4222 Exp $ + +This is FreeSec package for NetBSD, unchanged for +FreeBSD, except for the Makefile. + +The other stuff in libcrypt will be added in stages! diff --git a/secure/lib/libcipher/crypt.3 b/secure/lib/libcipher/crypt.3 new file mode 100644 index 0000000..fb06455 --- /dev/null +++ b/secure/lib/libcipher/crypt.3 @@ -0,0 +1,236 @@ +.\" FreeSec: libcrypt for NetBSD +.\" +.\" Copyright (c) 1994 David Burren +.\" 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. +.\" 4. Neither the name of the author nor the names of other contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. +.\" +.\" $Id: crypt.3,v 1.1 1994/09/07 08:55:24 g89r4222 Exp $ +.\" +.\" Manual page, using -mandoc macros +.\" +.Dd March 9, 1994 +.Dt CRYPT 3 +.Os "FreeSec 1.0" +.Sh NAME +.Nm crypt , +.Nm setkey , +.Nm encrypt , +.Nm des_setkey , +.Nm des_cipher , +.Nd DES encryption +.Sh SYNOPSIS +.Ft char +.Fn *crypt "const char *key" "const char *setting" +.Ft int +.Fn setkey "char *key" +.Ft int +.Fn encrypt "char *block" "int flag" +.Ft int +.Fn des_setkey "const char *key" +.Ft int +.Fn des_cipher "const char *in" "char *out" "long salt" "int count" +.Sh DESCRIPTION +The +.Fn crypt +function performs password encryption, based on the +.Tn NBS +Data Encryption Standard (DES). +Additional code has been added to deter key search attempts. +The first argument to +.Nm crypt +is a +.Dv null Ns -terminated +string, typically a user's typed password. +The second is in one of two forms: +if it begins with an underscore (``_'') then an extended format is used +in interpreting both the the key and the setting, as outlined below. +.Ss Extended crypt: +.Pp +The +.Ar key +is divided into groups of 8 characters (the last group is null-padded) +and the low-order 7 bits of each each character (56 bits per group) are +used to form the DES key as follows: +the first group of 56 bits becomes the initial DES key. +For each additional group, the XOR of the encryption of the current DES +key with itself and the group bits becomes the next DES key. +.Pp +The setting is a 9-character array consisting of an underscore followed +by 4 bytes of iteration count and 4 bytes of salt. +These are encoded as printable characters, 6 bits per character, +least significant character first. +The values 0 to 63 are encoded as ``./0-9A-Za-z''. +This allows 24 bits for both +.Fa count +and +.Fa salt . +.Ss "Traditional" crypt: +.Pp +The first 8 bytes of the key are null-padded, and the low-order 7 bits of +each character is used to form the 56-bit +.Tn DES +key. +.Pp +The setting is a 2-character array of the ASCII-encoded salt. +Thus only 12 bits of +.Fa salt +are used. +.Fa count +is set to 25. +.Ss Algorithm: +.Pp +The +.Fa salt +introduces disorder in the +.Tn DES +algorithm in one of 16777216 or 4096 possible ways +(ie. with 24 or 12 bits: if bit +.Em i +of the +.Ar salt +is set, then bits +.Em i +and +.Em i+24 +are swapped in the +.Tn DES +E-box output). +.Pp +The DES key is used to encrypt a 64-bit constant using +.Ar count +iterations of +.Tn DES . +The value returned is a +.Dv null Ns -terminated +string, 20 or 13 bytes (plus null) in length, consisting of the +.Ar setting +followed by the encoded 64-bit encryption. +.Pp +The functions, +.Fn encrypt , +.Fn setkey , +.Fn des_setkey +and +.Fn des_cipher +provide access to the +.Tn DES +algorithm itself. +.Fn setkey +is passed a 64-byte array of binary values (numeric 0 or 1). +A 56-bit key is extracted from this array by dividing the +array into groups of 8, and ignoring the last bit in each group. +That bit is reserved for a byte parity check by DES, but is ignored +by these functions. +.Pp +The +.Fa block +argument to +.Fn encrypt +is also a 64-byte array of binary values. +If the value of +.Fa flag +is 0, +.Fa block +is encrypted otherwise it is decrypted. +The result is returned in the original array +.Fa block +after using the key specified by +.Fn setkey +to process it. +.Pp +The argument to +.Fn des_setkey +is a character array of length 8. +The least significant bit (the parity bit) in each character is ignored, +and the remaining bits are concatenated to form a 56-bit key. +The function +.Fn des_cipher +encrypts (or decrypts if +.Fa count +is negative) the 64-bits stored in the 8 characters at +.Fa in +using +.Xr abs 3 +of +.Fa count +iterations of +.Tn DES +and stores the 64-bit result in the 8 characters at +.Fa out +(which may be the same as +.Fa in +). +The +.Fa salt +specifies perturbations to the +.Tn DES +E-box output as described above. +.Pp +The function +.Fn crypt +returns a pointer to the encrypted value on success, and NULL on failure. +The functions +.Fn setkey , +.Fn encrypt , +.Fn des_setkey , +and +.Fn des_cipher +return 0 on success and 1 on failure. +.Pp +The +.Fn crypt , +.Fn setkey +and +.Fn des_setkey +functions all manipulate the same key space. +.Sh SEE ALSO +.Xr login 1 , +.Xr passwd 1 , +.Xr getpass 3 , +.Xr passwd 5 +.Sh BUGS +The +.Fn crypt +function returns a pointer to static data, and subsequent calls to +.Fn crypt +will modify the same object. +.Sh HISTORY +A rotor-based +.Fn crypt +function appeared in +.At v6 . +The current style +.Fn crypt +first appeared in +.At v7 . +.Pp +This library (FreeSec 1.0) was developed outside the United States of America +as an unencumbered replacement for the U.S.-only NetBSD libcrypt encryption +library. +Users should be aware that this code (and programs staticly linked with it) +may not be exported from the U.S., although it apparently can be imported. +.Sh AUTHOR +David Burren diff --git a/secure/lib/libcipher/crypt.c b/secure/lib/libcipher/crypt.c new file mode 100644 index 0000000..4442369 --- /dev/null +++ b/secure/lib/libcipher/crypt.c @@ -0,0 +1,730 @@ +/* + * FreeSec: libcrypt for NetBSD + * + * Copyright (c) 1994 David Burren + * 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. + * 4. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $Id: crypt.c,v 1.1 1994/09/07 08:55:24 g89r4222 Exp $ + * + * This is an original implementation of the DES and the crypt(3) interfaces + * by David Burren . + * + * An excellent reference on the underlying algorithm (and related + * algorithms) is: + * + * B. Schneier, Applied Cryptography: protocols, algorithms, + * and source code in C, John Wiley & Sons, 1994. + * + * Note that in that book's description of DES the lookups for the initial, + * pbox, and final permutations are inverted (this has been brought to the + * attention of the author). A list of errata for this book has been + * posted to the sci.crypt newsgroup by the author and is available for FTP. + * + * ARCHITECTURE ASSUMPTIONS: + * This code assumes that u_longs are 32 bits. It will probably not + * operate on 64-bit machines without modifications. + * It is assumed that the 8-byte arrays passed by reference can be + * addressed as arrays of u_longs (ie. the CPU is not picky about + * alignment). + */ +#include +#include +#include + +#ifdef DEBUG +# include +#endif + + +static u_char IP[64] = { + 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 +}; + +static u_char inv_key_perm[64]; +static u_char u_key_perm[56]; +static u_char key_perm[56] = { + 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 +}; + +static u_char key_shifts[16] = { + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 +}; + +static u_char inv_comp_perm[56]; +static u_char comp_perm[48] = { + 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 +}; + +/* + * No E box is used, as it's replaced by some ANDs, shifts, and ORs. + */ + +static u_char u_sbox[8][64]; +static u_char sbox[8][64] = { + { + 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 + }, + { + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 + }, + { + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 + }, + { + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 + }, + { + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 + }, + { + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 + }, + { + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 + }, + { + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 + } +}; + +static u_char un_pbox[32]; +static u_char pbox[32] = { + 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, + 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 +}; + +static u_long bits32[32] = +{ + 0x80000000, 0x40000000, 0x20000000, 0x10000000, + 0x08000000, 0x04000000, 0x02000000, 0x01000000, + 0x00800000, 0x00400000, 0x00200000, 0x00100000, + 0x00080000, 0x00040000, 0x00020000, 0x00010000, + 0x00008000, 0x00004000, 0x00002000, 0x00001000, + 0x00000800, 0x00000400, 0x00000200, 0x00000100, + 0x00000080, 0x00000040, 0x00000020, 0x00000010, + 0x00000008, 0x00000004, 0x00000002, 0x00000001 +}; + +static u_char bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; + +static u_long saltbits; +static long old_salt; +static u_long *bits28, *bits24; +static u_char init_perm[64], final_perm[64]; +static u_long en_keysl[16], en_keysr[16]; +static u_long de_keysl[16], de_keysr[16]; +static int des_initialised = 0; +static u_char m_sbox[4][4096]; +static u_long psbox[4][256]; +static u_long ip_maskl[8][256], ip_maskr[8][256]; +static u_long fp_maskl[8][256], fp_maskr[8][256]; +static u_long key_perm_maskl[8][128], key_perm_maskr[8][128]; +static u_long comp_maskl[8][128], comp_maskr[8][128]; +static u_long old_rawkey0, old_rawkey1; + +static u_char ascii64[] = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; +/* 0000000000111111111122222222223333333333444444444455555555556666 */ +/* 0123456789012345678901234567890123456789012345678901234567890123 */ + +static inline int +ascii_to_bin(char ch) +{ + if (ch > 'z') + return(0); + if (ch >= 'a') + return(ch - 'a' + 38); + if (ch > 'Z') + return(0); + if (ch >= 'A') + return(ch - 'A' + 12); + if (ch > '9') + return(0); + if (ch >= '.') + return(ch - '.'); + return(0); +} + + +static void +des_init() +{ + int i, j, b, k, inbit, obit; + u_long *p, *il, *ir, *fl, *fr; + + old_rawkey0 = old_rawkey1 = 0L; + saltbits = 0L; + old_salt = 0L; + bits24 = (bits28 = bits32 + 4) + 4; + + /* + * Invert the S-boxes, reordering the input bits. + */ + for (i = 0; i < 8; i++) + for (j = 0; j < 64; j++) { + b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf); + u_sbox[i][j] = sbox[i][b]; + } + + /* + * Convert the inverted S-boxes into 4 arrays of 8 bits. + * Each will handle 12 bits of the S-box input. + */ + for (b = 0; b < 4; b++) + for (i = 0; i < 64; i++) + for (j = 0; j < 64; j++) + m_sbox[b][(i << 6) | j] = + (u_sbox[(b << 1)][i] << 4) | + u_sbox[(b << 1) + 1][j]; + + /* + * Set up the initial & final permutations into a useful form, and + * initialise the inverted key permutation. + */ + for (i = 0; i < 64; i++) { + init_perm[final_perm[i] = IP[i] - 1] = i; + inv_key_perm[i] = 255; + } + + /* + * Invert the key permutation and initialise the inverted key + * compression permutation. + */ + for (i = 0; i < 56; i++) { + u_key_perm[i] = key_perm[i] - 1; + inv_key_perm[key_perm[i] - 1] = i; + inv_comp_perm[i] = 255; + } + + /* + * Invert the key compression permutation. + */ + for (i = 0; i < 48; i++) { + inv_comp_perm[comp_perm[i] - 1] = i; + } + + /* + * Set up the OR-mask arrays for the initial and final permutations, + * and for the key initial and compression permutations. + */ + for (k = 0; k < 8; k++) { + for (i = 0; i < 256; i++) { + *(il = &ip_maskl[k][i]) = 0L; + *(ir = &ip_maskr[k][i]) = 0L; + *(fl = &fp_maskl[k][i]) = 0L; + *(fr = &fp_maskr[k][i]) = 0L; + for (j = 0; j < 8; j++) { + inbit = 8 * k + j; + if (i & bits8[j]) { + if ((obit = init_perm[inbit]) < 32) + *il |= bits32[obit]; + else + *ir |= bits32[obit-32]; + if ((obit = final_perm[inbit]) < 32) + *fl |= bits32[obit]; + else + *fr |= bits32[obit - 32]; + } + } + } + for (i = 0; i < 128; i++) { + *(il = &key_perm_maskl[k][i]) = 0L; + *(ir = &key_perm_maskr[k][i]) = 0L; + for (j = 0; j < 7; j++) { + inbit = 8 * k + j; + if (i & bits8[j + 1]) { + if ((obit = inv_key_perm[inbit]) == 255) + continue; + if (obit < 28) + *il |= bits28[obit]; + else + *ir |= bits28[obit - 28]; + } + } + *(il = &comp_maskl[k][i]) = 0L; + *(ir = &comp_maskr[k][i]) = 0L; + for (j = 0; j < 7; j++) { + inbit = 7 * k + j; + if (i & bits8[j + 1]) { + if ((obit=inv_comp_perm[inbit]) == 255) + continue; + if (obit < 24) + *il |= bits24[obit]; + else + *ir |= bits24[obit - 24]; + } + } + } + } + + /* + * Invert the P-box permutation, and convert into OR-masks for + * handling the output of the S-box arrays setup above. + */ + for (i = 0; i < 32; i++) + un_pbox[pbox[i] - 1] = i; + + for (b = 0; b < 4; b++) + for (i = 0; i < 256; i++) { + *(p = &psbox[b][i]) = 0L; + for (j = 0; j < 8; j++) { + if (i & bits8[j]) + *p |= bits32[un_pbox[8 * b + j]]; + } + } + + des_initialised = 1; +} + + +static void +setup_salt(long salt) +{ + u_long obit, saltbit; + int i; + + if (salt == old_salt) + return; + old_salt = salt; + + saltbits = 0L; + saltbit = 1; + obit = 0x800000; + for (i = 0; i < 24; i++) { + if (salt & saltbit) + saltbits |= obit; + saltbit <<= 1; + obit >>= 1; + } +} + + +int +des_setkey(const char *key) +{ + u_long k0, k1, rawkey0, rawkey1; + int shifts, i, b, round; + + if (!des_initialised) + des_init(); + + rawkey0 = ntohl(*(u_long *) key); + rawkey1 = ntohl(*(u_long *) (key + 4)); + + if ((rawkey0 | rawkey1) + && rawkey0 == old_rawkey0 + && rawkey1 == old_rawkey1) { + /* + * Already setup for this key. + * This optimisation fails on a zero key (which is weak and + * has bad parity anyway) in order to simplify the starting + * conditions. + */ + return(0); + } + old_rawkey0 = rawkey0; + old_rawkey1 = rawkey1; + + /* + * Do key permutation and split into two 28-bit subkeys. + */ + k0 = key_perm_maskl[0][rawkey0 >> 25] + | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f] + | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f] + | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f] + | key_perm_maskl[4][rawkey1 >> 25] + | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f] + | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f] + | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f]; + k1 = key_perm_maskr[0][rawkey0 >> 25] + | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f] + | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f] + | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f] + | key_perm_maskr[4][rawkey1 >> 25] + | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f] + | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f] + | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f]; + /* + * Rotate subkeys and do compression permutation. + */ + shifts = 0; + for (round = 0; round < 16; round++) { + u_long t0, t1; + int bit; + + shifts += key_shifts[round]; + + t0 = (k0 << shifts) | (k0 >> (28 - shifts)); + t1 = (k1 << shifts) | (k1 >> (28 - shifts)); + + de_keysl[15 - round] = + en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f] + | comp_maskl[1][(t0 >> 14) & 0x7f] + | comp_maskl[2][(t0 >> 7) & 0x7f] + | comp_maskl[3][t0 & 0x7f] + | comp_maskl[4][(t1 >> 21) & 0x7f] + | comp_maskl[5][(t1 >> 14) & 0x7f] + | comp_maskl[6][(t1 >> 7) & 0x7f] + | comp_maskl[7][t1 & 0x7f]; + + de_keysr[15 - round] = + en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f] + | comp_maskr[1][(t0 >> 14) & 0x7f] + | comp_maskr[2][(t0 >> 7) & 0x7f] + | comp_maskr[3][t0 & 0x7f] + | comp_maskr[4][(t1 >> 21) & 0x7f] + | comp_maskr[5][(t1 >> 14) & 0x7f] + | comp_maskr[6][(t1 >> 7) & 0x7f] + | comp_maskr[7][t1 & 0x7f]; + } + return(0); +} + + +static int +do_des( u_long l_in, u_long r_in, u_long *l_out, u_long *r_out, int count) +{ + /* + * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format. + */ + u_long mask, rawl, rawr, l, r, *kl, *kr, *kl1, *kr1; + u_long f, r48l, r48r; + int i, j, b, round; + + if (count == 0) { + return(1); + } else if (count > 0) { + /* + * Encrypting + */ + kl1 = en_keysl; + kr1 = en_keysr; + } else { + /* + * Decrypting + */ + count = -count; + kl1 = de_keysl; + kr1 = de_keysr; + } + + /* + * Do initial permutation (IP). + */ + l = ip_maskl[0][l_in >> 24] + | ip_maskl[1][(l_in >> 16) & 0xff] + | ip_maskl[2][(l_in >> 8) & 0xff] + | ip_maskl[3][l_in & 0xff] + | ip_maskl[4][r_in >> 24] + | ip_maskl[5][(r_in >> 16) & 0xff] + | ip_maskl[6][(r_in >> 8) & 0xff] + | ip_maskl[7][r_in & 0xff]; + r = ip_maskr[0][l_in >> 24] + | ip_maskr[1][(l_in >> 16) & 0xff] + | ip_maskr[2][(l_in >> 8) & 0xff] + | ip_maskr[3][l_in & 0xff] + | ip_maskr[4][r_in >> 24] + | ip_maskr[5][(r_in >> 16) & 0xff] + | ip_maskr[6][(r_in >> 8) & 0xff] + | ip_maskr[7][r_in & 0xff]; + + while (count--) { + /* + * Do each round. + */ + kl = kl1; + kr = kr1; + round = 16; + while (round--) { + /* + * Expand R to 48 bits (simulate the E-box). + */ + r48l = ((r & 0x00000001) << 23) + | ((r & 0xf8000000) >> 9) + | ((r & 0x1f800000) >> 11) + | ((r & 0x01f80000) >> 13) + | ((r & 0x001f8000) >> 15); + + r48r = ((r & 0x0001f800) << 7) + | ((r & 0x00001f80) << 5) + | ((r & 0x000001f8) << 3) + | ((r & 0x0000001f) << 1) + | ((r & 0x80000000) >> 31); + /* + * Do salting for crypt() and friends, and + * XOR with the permuted key. + */ + f = (r48l ^ r48r) & saltbits; + r48l ^= f ^ *kl++; + r48r ^= f ^ *kr++; + /* + * Do sbox lookups (which shrink it back to 32 bits) + * and do the pbox permutation at the same time. + */ + f = psbox[0][m_sbox[0][r48l >> 12]] + | psbox[1][m_sbox[1][r48l & 0xfff]] + | psbox[2][m_sbox[2][r48r >> 12]] + | psbox[3][m_sbox[3][r48r & 0xfff]]; + /* + * Now that we've permuted things, complete f(). + */ + f ^= l; + l = r; + r = f; + } + r = l; + l = f; + } + /* + * Do final permutation (inverse of IP). + */ + *l_out = fp_maskl[0][l >> 24] + | fp_maskl[1][(l >> 16) & 0xff] + | fp_maskl[2][(l >> 8) & 0xff] + | fp_maskl[3][l & 0xff] + | fp_maskl[4][r >> 24] + | fp_maskl[5][(r >> 16) & 0xff] + | fp_maskl[6][(r >> 8) & 0xff] + | fp_maskl[7][r & 0xff]; + *r_out = fp_maskr[0][l >> 24] + | fp_maskr[1][(l >> 16) & 0xff] + | fp_maskr[2][(l >> 8) & 0xff] + | fp_maskr[3][l & 0xff] + | fp_maskr[4][r >> 24] + | fp_maskr[5][(r >> 16) & 0xff] + | fp_maskr[6][(r >> 8) & 0xff] + | fp_maskr[7][r & 0xff]; + return(0); +} + + +int +des_cipher(const char *in, char *out, long salt, int count) +{ + u_long l_out, r_out, rawl, rawr; + int retval; + + if (!des_initialised) + des_init(); + + setup_salt(salt); + + rawl = ntohl(*((u_long *) in)++); + rawr = ntohl(*((u_long *) in)); + + retval = do_des(rawl, rawr, &l_out, &r_out, count); + + *((u_long *) out)++ = htonl(l_out); + *((u_long *) out) = htonl(r_out); + return(retval); +} + + +int +setkey(char *key) +{ + int i, j; + u_long packed_keys[2]; + u_char *p; + + p = (u_char *) packed_keys; + + for (i = 0; i < 8; i++) { + p[i] = 0; + for (j = 0; j < 8; j++) + if (*key++ & 1) + p[i] |= bits8[j]; + } + return(des_setkey(p)); +} + + +int +encrypt(char *block, int flag) +{ + u_long io[2]; + u_char *p; + int i, j, retval; + + if (!des_initialised) + des_init(); + + setup_salt(0L); + p = block; + for (i = 0; i < 2; i++) { + io[i] = 0L; + for (j = 0; j < 32; j++) + if (*p++ & 1) + io[i] |= bits32[j]; + } + retval = do_des(io[0], io[1], io, io + 1, flag ? -1 : 1); + for (i = 0; i < 2; i++) + for (j = 0; j < 32; j++) + block[(i << 5) | j] = (io[i] & bits32[j]) ? 1 : 0; + return(retval); +} + + +char * +crypt(char *key, char *setting) +{ + int i; + u_long count, salt, l, r0, r1, keybuf[2]; + u_char *p, *q; + static u_char output[21]; + + if (!des_initialised) + des_init(); + + /* + * Need to check if setting is "*" - otherwise + * crypt(k, "*") gives back "*" + */ + for(i = 0 ; i < 2; i++) + if(setting[i] == '\0') + { setting[i] = 'A'; break ; } + + + /* + * Copy the key, shifting each character up by one bit + * and padding with zeros. + */ + q = (u_char *) keybuf; + while (q - (u_char *) keybuf - 8) { + if (*q++ = *key << 1) + key++; + } + if (des_setkey((u_char *) keybuf)) + return(NULL); + + if (*setting == _PASSWORD_EFMT1) { + /* + * "new"-style: + * setting - underscore, 4 bytes of count, 4 bytes of salt + * key - unlimited characters + */ + for (i = 1, count = 0L; i < 5; i++) + count |= ascii_to_bin(setting[i]) << (i - 1) * 6; + + for (i = 5, salt = 0L; i < 9; i++) + salt |= ascii_to_bin(setting[i]) << (i - 5) * 6; + + while (*key) { + /* + * Encrypt the key with itself. + */ + if (des_cipher((u_char*)keybuf, (u_char*)keybuf, 0L, 1)) + return(NULL); + /* + * And XOR with the next 8 characters of the key. + */ + q = (u_char *) keybuf; + while (q - (u_char *) keybuf - 8 && *key) + *q++ ^= *key++ << 1; + + if (des_setkey((u_char *) keybuf)) + return(NULL); + } + strncpy(output, setting, 9); + p = output + 9; + } else { + /* + * "old"-style: + * setting - 2 bytes of salt + * key - up to 8 characters + */ + count = 25; + + salt = (ascii_to_bin(setting[1]) << 6) + | ascii_to_bin(setting[0]); + + output[0] = setting[0]; + output[1] = setting[1]; + p = output + 2; + } + setup_salt(salt); + /* + * Do it. + */ + if (do_des(0L, 0L, &r0, &r1, count)) + return(NULL); + /* + * Now encode the result... + */ + l = (r0 >> 8); + *p++ = ascii64[(l >> 18) & 0x3f]; + *p++ = ascii64[(l >> 12) & 0x3f]; + *p++ = ascii64[(l >> 6) & 0x3f]; + *p++ = ascii64[l & 0x3f]; + + l = (r0 << 16) | ((r1 >> 16) & 0xffff); + *p++ = ascii64[(l >> 18) & 0x3f]; + *p++ = ascii64[(l >> 12) & 0x3f]; + *p++ = ascii64[(l >> 6) & 0x3f]; + *p++ = ascii64[l & 0x3f]; + + l = r1 << 2; + *p++ = ascii64[(l >> 12) & 0x3f]; + *p++ = ascii64[(l >> 6) & 0x3f]; + *p++ = ascii64[l & 0x3f]; + *p = 0; + + return(output); +} diff --git a/secure/lib/libcipher/test/Makefile b/secure/lib/libcipher/test/Makefile new file mode 100644 index 0000000..3afec4b --- /dev/null +++ b/secure/lib/libcipher/test/Makefile @@ -0,0 +1,55 @@ +# +# Hacked Makefile to compile and run the DES-certification program, +# but not install anything. +# +# $Id: Makefile,v 1.1 1994/09/07 08:55:26 g89r4222 Exp $ +# +LIBCRYPT!=cd $(.CURDIR)/..; \ + printf "xxx:\n\techo \$${.OBJDIR}/libcrypt.a\n" | make -r -s -f - xxx + +#CFLAGS+= -DHAVE_CRYPT16 + +TARGETS=cert speedcrypt speeddes + +all: ${TARGETS} + +test: all testcrypt testencrypt testdes testspeed + +testcrypt: cert + @./cert -c + +testencrypt: cert + @./cert -e < ${.CURDIR}/cert.input + +testdes: cert + @./cert -d < ${.CURDIR}/cert.input + +testspeed: cryptspeed desspeed + +cryptspeed: speedcrypt + @./speedcrypt 30 1 + @./speedcrypt 30 1 + @./speedcrypt 30 0 + @./speedcrypt 30 0 + +desspeed: speeddes + @./speeddes 30 1 + @./speeddes 30 1 + @./speeddes 40 25 + @./speeddes 40 25 + +cert: cert.c ${LIBCRYPT} + $(CC) $(CFLAGS) -o cert ${.CURDIR}/cert.c ${LIBCRYPT} + +speedcrypt: speedcrypt.c ${LIBCRYPT} + $(CC) $(CFLAGS) -o speedcrypt ${.CURDIR}/speedcrypt.c ${LIBCRYPT} + +speeddes: speeddes.c ${LIBCRYPT} + $(CC) $(CFLAGS) -o speeddes ${.CURDIR}/speeddes.c ${LIBCRYPT} + +clean: + rm -f ${TARGETS} + +install: + +.include diff --git a/secure/lib/libcipher/test/README b/secure/lib/libcipher/test/README new file mode 100644 index 0000000..eb6b0be --- /dev/null +++ b/secure/lib/libcipher/test/README @@ -0,0 +1,10 @@ +This directory contains test programs to certify DES operation and to +time the crypt() call (of curiosity value). + +Simply type `make test` to run the tests. + +The normal `make all` and `make install` that get done during library building +and installation will build these programs BUT NOT INSTALL THEM. After all, +they're only for testing... + +- David Burren, January 1994 diff --git a/secure/lib/libcipher/test/cert.c b/secure/lib/libcipher/test/cert.c new file mode 100644 index 0000000..520f9bd --- /dev/null +++ b/secure/lib/libcipher/test/cert.c @@ -0,0 +1,344 @@ +/* + * This DES validation program shipped with FreeSec is derived from that + * shipped with UFC-crypt which is apparently derived from one distributed + * with Phil Karns PD DES package. + * + * $Id: cert.c,v 1.1 1994/09/07 08:55:26 g89r4222 Exp $ + */ + +#include + +int totfails = 0; + +char *crypt(); +#ifdef HAVE_CRYPT16 +char *crypt16(); +#endif /* HAVE_CRYPT16 */ + + +static struct crypt_test { + char *key, *setting, *answer; +} crypt_tests[] = { + "foob", "ar", "arlEKn0OzVJn.", + "holyhooplasbatman!", "_X.......", "_X.......N89y2Z.e4WU", + "holyhooplasbatman!", "_X...X...", "_X...X...rSUDQ5Na/QM", + "holyhooplasbatman!", "_XX..X...", "_XX..X...P8vb9xU4JAk", + "holyhooplasbatman!", "_XX..XX..", "_XX..XX..JDs5IlGLqT2", + "holyhooplasbatman!", "_XX..XXa.", "_XX..XXa.bFVsOnCNh8Y", + "holyhooplasbatman!", "_XXa.X...", "_XXa.X...Ghsb3QKNaps", +#ifdef TAKES_TOO_LONG_ON_SOME_CRYPTS + "holyhooplasbatman!", "_arararar", "_ararararNGMzvpNjeCc", +#endif + NULL, NULL, NULL, +}; + + +static struct crypt_test crypt16_tests[] = { + "foob", "ar", "arxo23jZDD5AYbHbqoy9Dalg", + "holyhooplasbatman!", "ar", "arU5FRLJ3kxIoedlmyrOelEw", + NULL, NULL, NULL +}; + + +void good_bye() +{ + if(totfails == 0) { + printf(" Passed validation\n"); + exit(0); + } else { + printf(" %d failures during validation!!!\n", totfails); + exit(1); + } +} + + +void put8(cp) +char *cp; +{ + int i,j,t; + + for(i = 0; i < 8; i++){ + t = 0; + for(j = 0; j < 8; j++) + t = t << 1 | *cp++; + printf("%02x", t); + } +} + + +void print_bits(bits) +unsigned char *bits; +{ + int i; + + for (i = 0; i < 8; i++) { + printf("%02x", bits[i]); + } +} + + +int parse_line(buff, salt, key, plain, answer) +char *buff; +long *salt; +char *key, *plain, *answer; +{ + char *ptr1, *ptr2; + int val; + int i,j,t; + + /* + * Extract salt + */ + if (sscanf(buff, "%lu", salt) != 1) + return(-1); + for (ptr2 = buff; *ptr2 && !isspace(*ptr2); ptr2++) + ; + + /* + * Extract key + */ + for (ptr1 = ptr2; *ptr1 && isspace(*ptr1); ptr1++) + ; + for (ptr2 = ptr1; *ptr2 && !isspace(*ptr2); ptr2++) + ; + if (ptr2 - ptr1 != 16) + return(-1); + for (i = 0; i < 8; i++){ + if (sscanf(ptr1 + 2*i, "%2x", &t) != 1) + return(-2); + for (j = 0; j < 8; j++) + *key++ = (t & 1 << (7 - j)) != 0; + } + + /* + * Extract plain + */ + for (ptr1 = ptr2; *ptr1 && isspace(*ptr1); ptr1++) + ; + for (ptr2 = ptr1; *ptr2 && !isspace(*ptr2); ptr2++) + ; + if (ptr2 - ptr1 != 16) + return(-1); + for (i = 0; i < 8; i++){ + if (sscanf(ptr1 + 2*i, "%2x", &t) != 1) + return(-2); + for (j = 0; j < 8; j++) + *plain++ = (t & 1 << (7 - j)) != 0; + } + + /* + * Extract answer + */ + for (ptr1 = ptr2; *ptr1 && isspace(*ptr1); ptr1++) + ; + for (ptr2 = ptr1; *ptr2 && !isspace(*ptr2); ptr2++) + ; + if (ptr2 - ptr1 != 16) + return(-1); + for (i = 0; i < 8; i++){ + if (sscanf(ptr1 + 2*i, "%2x", &t) != 1) + return(-2); + for (j = 0; j < 8; j++) + *answer++ = (t & 1 << (7 - j)) != 0; + } + return(0); +} + +/* + * Test the setkey and encrypt functions + */ +void test_encrypt() +{ + char key[64],plain[64],cipher[64],answer[64]; + char buff[BUFSIZ]; + unsigned long salt; + int i; + int test; + int fail; + + printf("Testing setkey/encrypt\n"); + + for(test=0;fgets(buff, BUFSIZ, stdin);test++){ + + /* + * Allow comments. + */ + if (*buff == '#') + continue; + + if ((fail = parse_line(buff, &salt, key, plain, answer)) < 0){ + printf("test %d garbled (%d)\n", test, fail); + continue; + } + + if (salt) + continue; /* encrypt has no salt support */ + + printf(" K: "); put8(key); + printf(" P: "); put8(plain); + printf(" C: "); put8(answer); + + setkey(key); + for(i = 0; i < 64; i++) + cipher[i] = plain[i]; + encrypt(cipher, 0); + + for(i=0;i<64;i++) + if(cipher[i] != answer[i]) + break; + fail = 0; + if(i != 64){ + printf(" Enc FAIL "); + put8(cipher); + fail++; totfails++; + } + + encrypt(cipher, 1); + + for(i=0;i<64;i++) + if(cipher[i] != plain[i]) + break; + if(i != 64){ + printf(" Dec FAIL"); + fail++; totfails++; + } + + if(fail == 0) + printf(" OK"); + printf("\n"); + } +} + + +void bytes_to_bits(bytes, bits) +char *bytes; +unsigned char *bits; +{ + int i, j; + + for (i = 0; i < 8; i++) { + bits[i] = 0; + for (j = 0; j < 8; j++) { + bits[i] |= (bytes[i*8+j] & 1) << (7 - j); + } + } +} + + +/* + * Test the des_setkey and des_cipher functions + */ +void test_des() +{ + char ckey[64], cplain[64], canswer[64]; + unsigned char key[8], plain[8], cipher[8], answer[8]; + char buff[BUFSIZ]; + unsigned long salt; + int i; + int test; + int fail; + + printf("Testing des_setkey/des_cipher\n"); + + for(test=0;fgets(buff, BUFSIZ, stdin);test++){ + + /* + * Allow comments. + */ + if (*buff == '#') + continue; + + if ((fail = parse_line(buff, &salt, ckey, cplain, canswer)) <0){ + printf("test %d garbled (%d)\n", test, fail); + continue; + } + + printf(" S: %06x", salt); + printf(" K: "); put8(ckey); + printf(" P: "); put8(cplain); + printf(" C: "); put8(canswer); + + bytes_to_bits(ckey, key); + bytes_to_bits(cplain, plain); + bytes_to_bits(canswer, answer); + des_setkey(key); + des_cipher(plain, cipher, salt, 1); + + for(i = 0; i < 8; i++) + if(cipher[i] != answer[i]) + break; + fail = 0; + if(i != 8){ + printf(" Enc FAIL "); + print_bits(cipher); + fail++; totfails++; + } + + des_cipher(cipher, cipher, salt, -1); + + for(i = 0; i < 8; i++) + if(cipher[i] != plain[i]) + break; + if(i != 8){ + printf(" Dec FAIL"); + fail++; totfails++; + } + + if(fail == 0) + printf(" OK"); + printf("\n"); + } +} + + +/* + * Test the old-style crypt(), the new-style crypt(), and crypt16(). + */ +void test_crypt() +{ + char *result; + struct crypt_test *p; + + printf("Testing crypt() family\n"); + + for (p = crypt_tests; p->key; p++) { + printf(" crypt(\"%s\", \"%s\"), \"%s\" expected", + p->key, p->setting, p->answer); + fflush(stdout); + result = crypt(p->key, p->setting); + if(!strcmp(result, p->answer)) { + printf(", OK\n"); + } else { + printf("\n failed (\"%s\")\n", result); + totfails++; + } + } + +#ifdef HAVE_CRYPT16 + for (p = crypt16_tests; p->key; p++) { + printf(" crypt16(\"%s\", \"%s\"), \"%s\" expected", + p->key, p->setting, p->answer); + fflush(stdout); + result = crypt16(p->key, p->setting); + if(!strcmp(result, p->answer)) { + printf(", OK\n"); + } else { + printf("\n failed (\"%s\")\n", result); + totfails++; + } + } +#endif /* HAVE_CRYPT16 */ +} + +main(argc, argv) +int argc; +char *argv[]; +{ + if(argc < 1 || !strcmp(argv[1], "-e")) + test_encrypt(); + else if(!strcmp(argv[1], "-d")) + test_des(); + else if(!strcmp(argv[1], "-c")) + test_crypt(); + good_bye(); +} diff --git a/secure/lib/libcipher/test/cert.input b/secure/lib/libcipher/test/cert.input new file mode 100644 index 0000000..275639c --- /dev/null +++ b/secure/lib/libcipher/test/cert.input @@ -0,0 +1,179 @@ +# $Id: cert.input,v 1.1 1994/09/07 08:55:26 g89r4222 Exp $ +# +# Salt, key, plaintext, ciphertext +# +0 0101010101010101 95f8a5e5dd31d900 8000000000000000 +0 0101010101010101 dd7f121ca5015619 4000000000000000 +0 0101010101010101 2e8653104f3834ea 2000000000000000 +0 0101010101010101 4bd388ff6cd81d4f 1000000000000000 +0 0101010101010101 20b9e767b2fb1456 0800000000000000 +0 0101010101010101 55579380d77138ef 0400000000000000 +0 0101010101010101 6cc5defaaf04512f 0200000000000000 +0 0101010101010101 0d9f279ba5d87260 0100000000000000 +0 0101010101010101 d9031b0271bd5a0a 0080000000000000 +0 0101010101010101 424250b37c3dd951 0040000000000000 +0 0101010101010101 b8061b7ecd9a21e5 0020000000000000 +0 0101010101010101 f15d0f286b65bd28 0010000000000000 +0 0101010101010101 add0cc8d6e5deba1 0008000000000000 +0 0101010101010101 e6d5f82752ad63d1 0004000000000000 +0 0101010101010101 ecbfe3bd3f591a5e 0002000000000000 +0 0101010101010101 f356834379d165cd 0001000000000000 +0 0101010101010101 2b9f982f20037fa9 0000800000000000 +0 0101010101010101 889de068a16f0be6 0000400000000000 +0 0101010101010101 e19e275d846a1298 0000200000000000 +0 0101010101010101 329a8ed523d71aec 0000100000000000 +0 0101010101010101 e7fce22557d23c97 0000080000000000 +0 0101010101010101 12a9f5817ff2d65d 0000040000000000 +0 0101010101010101 a484c3ad38dc9c19 0000020000000000 +0 0101010101010101 fbe00a8a1ef8ad72 0000010000000000 +0 0101010101010101 750d079407521363 0000008000000000 +0 0101010101010101 64feed9c724c2faf 0000004000000000 +0 0101010101010101 f02b263b328e2b60 0000002000000000 +0 0101010101010101 9d64555a9a10b852 0000001000000000 +0 0101010101010101 d106ff0bed5255d7 0000000800000000 +0 0101010101010101 e1652c6b138c64a5 0000000400000000 +0 0101010101010101 e428581186ec8f46 0000000200000000 +0 0101010101010101 aeb5f5ede22d1a36 0000000100000000 +0 0101010101010101 e943d7568aec0c5c 0000000080000000 +0 0101010101010101 df98c8276f54b04b 0000000040000000 +0 0101010101010101 b160e4680f6c696f 0000000020000000 +0 0101010101010101 fa0752b07d9c4ab8 0000000010000000 +0 0101010101010101 ca3a2b036dbc8502 0000000008000000 +0 0101010101010101 5e0905517bb59bcf 0000000004000000 +0 0101010101010101 814eeb3b91d90726 0000000002000000 +0 0101010101010101 4d49db1532919c9f 0000000001000000 +0 0101010101010101 25eb5fc3f8cf0621 0000000000800000 +0 0101010101010101 ab6a20c0620d1c6f 0000000000400000 +0 0101010101010101 79e90dbc98f92cca 0000000000200000 +0 0101010101010101 866ecedd8072bb0e 0000000000100000 +0 0101010101010101 8b54536f2f3e64a8 0000000000080000 +0 0101010101010101 ea51d3975595b86b 0000000000040000 +0 0101010101010101 caffc6ac4542de31 0000000000020000 +0 0101010101010101 8dd45a2ddf90796c 0000000000010000 +0 0101010101010101 1029d55e880ec2d0 0000000000008000 +0 0101010101010101 5d86cb23639dbea9 0000000000004000 +0 0101010101010101 1d1ca853ae7c0c5f 0000000000002000 +0 0101010101010101 ce332329248f3228 0000000000001000 +0 0101010101010101 8405d1abe24fb942 0000000000000800 +0 0101010101010101 e643d78090ca4207 0000000000000400 +0 0101010101010101 48221b9937748a23 0000000000000200 +0 0101010101010101 dd7c0bbd61fafd54 0000000000000100 +0 0101010101010101 2fbc291a570db5c4 0000000000000080 +0 0101010101010101 e07c30d7e4e26e12 0000000000000040 +0 0101010101010101 0953e2258e8e90a1 0000000000000020 +0 0101010101010101 5b711bc4ceebf2ee 0000000000000010 +0 0101010101010101 cc083f1e6d9e85f6 0000000000000008 +0 0101010101010101 d2fd8867d50d2dfe 0000000000000004 +0 0101010101010101 06e7ea22ce92708f 0000000000000002 +0 0101010101010101 166b40b44aba4bd6 0000000000000001 +0 8001010101010101 0000000000000000 95a8d72813daa94d +0 4001010101010101 0000000000000000 0eec1487dd8c26d5 +0 2001010101010101 0000000000000000 7ad16ffb79c45926 +0 1001010101010101 0000000000000000 d3746294ca6a6cf3 +0 0801010101010101 0000000000000000 809f5f873c1fd761 +0 0401010101010101 0000000000000000 c02faffec989d1fc +0 0201010101010101 0000000000000000 4615aa1d33e72f10 +0 0180010101010101 0000000000000000 2055123350c00858 +0 0140010101010101 0000000000000000 df3b99d6577397c8 +0 0120010101010101 0000000000000000 31fe17369b5288c9 +0 0110010101010101 0000000000000000 dfdd3cc64dae1642 +0 0108010101010101 0000000000000000 178c83ce2b399d94 +0 0104010101010101 0000000000000000 50f636324a9b7f80 +0 0102010101010101 0000000000000000 a8468ee3bc18f06d +0 0101800101010101 0000000000000000 a2dc9e92fd3cde92 +0 0101400101010101 0000000000000000 cac09f797d031287 +0 0101200101010101 0000000000000000 90ba680b22aeb525 +0 0101100101010101 0000000000000000 ce7a24f350e280b6 +0 0101080101010101 0000000000000000 882bff0aa01a0b87 +0 0101040101010101 0000000000000000 25610288924511c2 +0 0101020101010101 0000000000000000 c71516c29c75d170 +0 0101018001010101 0000000000000000 5199c29a52c9f059 +0 0101014001010101 0000000000000000 c22f0a294a71f29f +0 0101012001010101 0000000000000000 ee371483714c02ea +0 0101011001010101 0000000000000000 a81fbd448f9e522f +0 0101010801010101 0000000000000000 4f644c92e192dfed +0 0101010401010101 0000000000000000 1afa9a66a6df92ae +0 0101010201010101 0000000000000000 b3c1cc715cb879d8 +0 0101010180010101 0000000000000000 19d032e64ab0bd8b +0 0101010140010101 0000000000000000 3cfaa7a7dc8720dc +0 0101010120010101 0000000000000000 b7265f7f447ac6f3 +0 0101010110010101 0000000000000000 9db73b3c0d163f54 +0 0101010108010101 0000000000000000 8181b65babf4a975 +0 0101010104010101 0000000000000000 93c9b64042eaa240 +0 0101010102010101 0000000000000000 5570530829705592 +0 0101010101800101 0000000000000000 8638809e878787a0 +0 0101010101400101 0000000000000000 41b9a79af79ac208 +0 0101010101200101 0000000000000000 7a9be42f2009a892 +0 0101010101100101 0000000000000000 29038d56ba6d2745 +0 0101010101080101 0000000000000000 5495c6abf1e5df51 +0 0101010101040101 0000000000000000 ae13dbd561488933 +0 0101010101020101 0000000000000000 024d1ffa8904e389 +0 0101010101018001 0000000000000000 d1399712f99bf02e +0 0101010101014001 0000000000000000 14c1d7c1cffec79e +0 0101010101012001 0000000000000000 1de5279dae3bed6f +0 0101010101011001 0000000000000000 e941a33f85501303 +0 0101010101010801 0000000000000000 da99dbbc9a03f379 +0 0101010101010401 0000000000000000 b7fc92f91d8e92e9 +0 0101010101010201 0000000000000000 ae8e5caa3ca04e85 +0 0101010101010180 0000000000000000 9cc62df43b6eed74 +0 0101010101010140 0000000000000000 d863dbb5c59a91a0 +0 0101010101010120 0000000000000000 a1ab2190545b91d7 +0 0101010101010110 0000000000000000 0875041e64c570f7 +0 0101010101010108 0000000000000000 5a594528bebef1cc +0 0101010101010104 0000000000000000 fcdb3291de21f0c0 +0 0101010101010102 0000000000000000 869efd7f9f265a09 +0 1046913489980131 0000000000000000 88d55e54f54c97b4 +0 1007103489988020 0000000000000000 0c0cc00c83ea48fd +0 10071034c8980120 0000000000000000 83bc8ef3a6570183 +0 1046103489988020 0000000000000000 df725dcad94ea2e9 +0 1086911519190101 0000000000000000 e652b53b550be8b0 +0 1086911519580101 0000000000000000 af527120c485cbb0 +0 5107b01519580101 0000000000000000 0f04ce393db926d5 +0 1007b01519190101 0000000000000000 c9f00ffc74079067 +0 3107915498080101 0000000000000000 7cfd82a593252b4e +0 3107919498080101 0000000000000000 cb49a2f9e91363e3 +0 10079115b9080140 0000000000000000 00b588be70d23f56 +0 3107911598080140 0000000000000000 406a9a6ab43399ae +0 1007d01589980101 0000000000000000 6cb773611dca9ada +0 9107911589980101 0000000000000000 67fd21c17dbb5d70 +0 9107d01589190101 0000000000000000 9592cb4110430787 +0 1007d01598980120 0000000000000000 a6b7ff68a318ddd3 +0 1007940498190101 0000000000000000 4d102196c914ca16 +0 0107910491190401 0000000000000000 2dfa9f4573594965 +0 0107910491190101 0000000000000000 b46604816c0e0774 +0 0107940491190401 0000000000000000 6e7e6221a4f34e87 +0 19079210981a0101 0000000000000000 aa85e74643233199 +0 1007911998190801 0000000000000000 2e5a19db4d1962d6 +0 10079119981a0801 0000000000000000 23a866a809d30894 +0 1007921098190101 0000000000000000 d812d961f017d320 +0 100791159819010b 0000000000000000 055605816e58608f +0 1004801598190101 0000000000000000 abd88e8b1b7716f1 +0 1004801598190102 0000000000000000 537ac95be69da1e1 +0 1004801598190108 0000000000000000 aed0f6ae3c25cdd8 +0 1002911598100104 0000000000000000 b3e35a5ee53e7b8d +0 1002911598190104 0000000000000000 61c79c71921a2ef8 +0 1002911598100201 0000000000000000 e2f5728f0995013c +0 1002911698100101 0000000000000000 1aeac39a61f0a464 +0 7ca110454a1a6e57 01a1d6d039776742 690f5b0d9a26939b +0 0131d9619dc1376e 5cd54ca83def57da 7a389d10354bd271 +0 07a1133e4a0b2686 0248d43806f67172 868ebb51cab4599a +0 3849674c2602319e 51454b582ddf440a 7178876e01f19b2a +0 04b915ba43feb5b6 42fd443059577fa2 af37fb421f8c4095 +0 0113b970fd34f2ce 059b5e0851cf143a 86a560f10ec6d85b +0 0170f175468fb5e6 0756d8e0774761d2 0cd3da020021dc09 +0 43297fad38e373fe 762514b829bf486a ea676b2cb7db2b7a +0 07a7137045da2a16 3bdd119049372802 dfd64a815caf1a0f +0 04689104c2fd3b2f 26955f6835af609a 5c513c9c4886c088 +0 37d06bb516cb7546 164d5e404f275232 0a2aeeae3ff4ab77 +0 1f08260d1ac2465e 6b056e18759f5cca ef1bf03e5dfa575a +0 584023641aba6176 004bd6ef09176062 88bf0db6d70dee56 +0 025816164629b007 480d39006ee762f2 a1f9915541020b56 +0 49793ebc79b3258f 437540c8698f3cfa 6fbf1cafcffd0556 +0 4fb05e1515ab73a7 072d43a077075292 2f22e49bab7ca1ac +0 49e95d6d4ca229bf 02fe55778117f12a 5a6b612cc26cce4a +0 018310dc409b26d6 1d9d5c5018f728c2 5f4c038ed12b2e41 +0 1c587f1c13924fef 305532286d6f295a 63fac0d034d9f793 +1 1c587f1c13924fef 305532286d6f295a 400d307ca24fee60 +57 1c587f1c13924fef 305532286d6f295a 28b568f40e7d43ae +1 8001010101010101 0000000000000000 f501029f268e45dc +0 1c587f1c13924fef 305532286d6f295a 63fac0d034d9f793 diff --git a/secure/lib/libcipher/test/speedcrypt.c b/secure/lib/libcipher/test/speedcrypt.c new file mode 100644 index 0000000..f7507fd --- /dev/null +++ b/secure/lib/libcipher/test/speedcrypt.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include + +int keep_going, count, alternate, seconds; +struct rusage prior, now; + +void +finish() +{ + keep_going = 0; +} + + +main(int argc, char *argv[]) +{ + struct itimerval itv; + u_long msecs, key1[8], key2[8]; + char *k1, *k2; + + if (argc < 2 || sscanf(argv[1], "%d", &seconds) != 1) + seconds = 20; + + if (argc < 3 || sscanf(argv[2], "%d", &alternate) != 1) + alternate = 0; + + printf ("Running crypt%s for %d seconds of vtime...\n", + alternate ? " with alternate keys" : "", seconds); + + bzero(&itv, sizeof (itv)); + signal (SIGVTALRM, finish); + itv.it_value.tv_sec = seconds; + itv.it_value.tv_usec = 0; + setitimer(ITIMER_VIRTUAL, &itv, NULL); + + keep_going = 1; + if (getrusage(0, &prior) < 0) { + perror("getrusage"); + exit(1); + } + + k1 = (char *) key1; + k2 = (char *) key2; + strcpy(k1, "fredfredfredfredfred"); + strcpy(k2, "joejoejoejoejoejoejo"); + + if (alternate) + for (count = 0; keep_going; count++) + { +#if defined(LONGCRYPT) + crypt((count & 1) ? k1 : k2, "_ara.X..."); +#else + crypt((count & 1) ? k1 : k2, "eek"); +#endif + } + else + for (count = 0; keep_going; count++) + { +#if defined(LONGCRYPT) + crypt(k1, "_ara.X..."); +#else + crypt(k1, "eek"); +#endif + } + + if (getrusage(0, &now) < 0) { + perror("getrusage"); + exit(1); + } + msecs = (now.ru_utime.tv_sec - prior.ru_utime.tv_sec) * 1000 + + (now.ru_utime.tv_usec - prior.ru_utime.tv_usec) / 1000; + printf ("\tDid %d crypt()s per second.\n", 1000 * count / msecs); + exit(0); +} diff --git a/secure/lib/libcipher/test/speeddes.c b/secure/lib/libcipher/test/speeddes.c new file mode 100644 index 0000000..a582236 --- /dev/null +++ b/secure/lib/libcipher/test/speeddes.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include + +int keep_going, count, alternate, seconds, iters; +struct rusage prior, now; +u_long block[3]; +char *blk; + +void +finish() +{ + keep_going = 0; +} + + +main(int argc, char *argv[]) +{ + struct itimerval itv; + u_long msecs; + + if (argc < 2 || sscanf(argv[1], "%d", &seconds) != 1) + seconds = 20; + + if (argc < 3 || sscanf(argv[2], "%d", &iters) != 1) + iters = 1; + + printf ("Running des_cipher( , , 0L, %d) for %d seconds of vtime...\n", + iters, seconds); + + bzero(&itv, sizeof (itv)); + signal (SIGVTALRM, finish); + itv.it_value.tv_sec = seconds; + itv.it_value.tv_usec = 0; + setitimer(ITIMER_VIRTUAL, &itv, NULL); + + keep_going = 1; + if (getrusage(0, &prior) < 0) { + perror("getrusage"); + exit(1); + } + + blk = (char *) block; + (void)des_setkey(blk); + for (count = 0; keep_going; count++) + (void) des_cipher(blk, blk, 0, iters); + + if (getrusage(0, &now) < 0) { + perror("getrusage"); + exit(1); + } + + msecs = (now.ru_utime.tv_sec - prior.ru_utime.tv_sec) * 1000 + + (now.ru_utime.tv_usec - prior.ru_utime.tv_usec) / 1000; + printf ("Did %d encryptions per second, each of %d iteration(s).\n", + 1000 * count / msecs, iters); + printf ("\tTotal %d blocks per second.\n", (1000*iters*count)/msecs); + exit(0); +} -- cgit v1.1