diff options
author | Okan Demirmen <okan@cvs.openbsd.org> | 2014-04-18 19:13:17 +0000 |
---|---|---|
committer | Okan Demirmen <okan@cvs.openbsd.org> | 2014-04-18 19:13:17 +0000 |
commit | 156841adb41846a55a34238c21a4503036224fd9 (patch) | |
tree | 09a5fb2e4f25d94d9dd99f25233d16786bc71529 /usr.bin | |
parent | 51050ea5b8a777beb266412b38bae1ebd95b7d28 (diff) |
remove bdes(1) so as to not encourage its use; if someone really
wants to use DES, there's another way.
ok deraadt sthen sobrado (and probably tedu)
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/Makefile | 4 | ||||
-rw-r--r-- | usr.bin/bdes/Makefile | 6 | ||||
-rw-r--r-- | usr.bin/bdes/bdes.1 | 360 | ||||
-rw-r--r-- | usr.bin/bdes/bdes.c | 1004 |
4 files changed, 2 insertions, 1372 deletions
diff --git a/usr.bin/Makefile b/usr.bin/Makefile index dc2a3175cb7..54c004fdae5 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -1,9 +1,9 @@ -# $OpenBSD: Makefile,v 1.138 2014/04/18 10:00:48 schwarze Exp $ +# $OpenBSD: Makefile,v 1.139 2014/04/18 19:13:16 okan Exp $ .include <bsd.own.mk> SUBDIR= apply arch asa at aucat audioctl awk banner \ - basename bc bdes bgplg \ + basename bc bgplg \ biff cal calendar cap_mkdb cdio chpass cmp col colrm \ column comm compress cpp crontab csplit ctags cu cut \ dc deroff diff diff3 dirname du encrypt env expand false file \ diff --git a/usr.bin/bdes/Makefile b/usr.bin/bdes/Makefile deleted file mode 100644 index 515bd046c68..00000000000 --- a/usr.bin/bdes/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# $OpenBSD: Makefile,v 1.4 1997/09/21 11:48:26 deraadt Exp $ - -MAN= bdes.1 -PROG= bdes - -.include <bsd.prog.mk> diff --git a/usr.bin/bdes/bdes.1 b/usr.bin/bdes/bdes.1 deleted file mode 100644 index fde98399aff..00000000000 --- a/usr.bin/bdes/bdes.1 +++ /dev/null @@ -1,360 +0,0 @@ -.\" $OpenBSD: bdes.1,v 1.11 2013/08/05 06:58:40 jmc Exp $ -.\" $NetBSD: bdes.1,v 1.11 2003/08/07 11:13:11 agc Exp $ -.\" -.\" Copyright (c) 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Matt Bishop of Dartmouth College. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)bdes.1 8.1 (Berkeley) 6/29/93 -.\" -.Dd $Mdocdate: August 5 2013 $ -.Dt BDES 1 -.Os -.Sh NAME -.Nm bdes -.Nd encrypt/decrypt using the Data Encryption Standard -.Sh SYNOPSIS -.Nm -.Op Fl abdp -.Op Fl F Ar N -.Op Fl f Ar N -.Op Fl k Ar key -.Op Fl m Ar N -.Op Fl o Ar N -.Op Fl v Ar vector -.Sh DESCRIPTION -.Nm -implements all DES modes of operation described in FIPS PUB 81, -including alternative cipher feedback mode and both authentication -modes. -.Nm -reads from the standard input and writes to the standard output. -By default, the input is encrypted using cipher block chaining mode. -Using the same key for encryption and decryption preserves plain text. -.Pp -All modes but the electronic code book mode require an initialization -vector; if none is supplied, the zero vector is used. -If no -.Ar key -is specified on the command line, the user is prompted for one (see -.Xr getpass 3 -for more details). -.Pp -The options are as follows: -.Bl -tag -width "-v vector" -.It Fl a -The key and initialization vector strings are to be taken as ASCII, -suppressing the special interpretation given to leading -.Dq 0X , -.Dq 0x , -.Dq 0B -and -.Dq 0b -characters. -This flag applies to -.Em both -the key and initialization vector. -.It Fl b -Use electronic code book mode. -This is not recommended for messages -longer than 8 bytes, as patterns in the input will show through to the -output. -.It Fl d -Decrypt the input. -.It Fl F Ar N -Use -.Ar N Ns -bit -alternative cipher feedback mode. -Currently -.Ar N -must be a multiple of 7 between 7 and 56 inclusive (this does not conform -to the alternative CFB mode specification). -.It Fl f Ar N -Use -.Ar N Ns -bit -cipher feedback mode. -Currently -.Ar N -must be a multiple of 8 between 8 and 64 inclusive (this does not conform -to the standard CFB mode specification). -.It Fl k Ar key -Use -.Ar key -as the cryptographic key. -.It Fl m Ar N -Compute a message authentication code (MAC) of -.Ar N -bits on the input. -The value of -.Ar N -must be between 1 and 64 inclusive; if -.Ar N -is not a multiple of 8, enough 0 bits will be added to pad the MAC length -to the nearest multiple of 8. -Only the MAC is output. -MACs are only available in cipher block chaining mode or in cipher feedback -mode. -.It Fl o Ar N -Use -.Ar N Ns -bit -output feedback mode. -Currently -.Ar N -must be a multiple of 8 between 8 and 64 inclusive (this does not conform -to the OFB mode specification). -.It Fl p -Disable the resetting of the parity bit. -This flag forces the parity bit of the key to be used as typed, rather than -making each character be of odd parity. -It is used only if the key is given in ASCII. -.It Fl v Ar vector -Set the initialization vector to -.Ar vector ; -the vector is interpreted in the same way as the key. -The vector is ignored in electronic codebook mode. -For best security, a different -initialization vector should be used for each file. -.El -.Pp -The key and initialization vector are taken as sequences of ASCII -characters which are then mapped into their bit representations. -If either begins with -.Dq 0X -or -.Dq 0x , -that one is taken as a sequence of hexadecimal digits indicating the -bit pattern; -if either begins with -.Dq 0B -or -.Dq 0b , -that one is taken as a sequence of binary digits indicating the bit pattern. -In either case, -only the leading 64 bits of the key or initialization vector -are used, -and if fewer than 64 bits are provided, enough 0 bits are appended -to pad the key to 64 bits. -.Pp -According to the DES standard, the low-order bit of each character in the -key string is deleted. -Since most ASCII representations set the high-order bit to 0, simply -deleting the low-order bit effectively reduces the size of the key space -from -.if t 2\u\s-356\s0\d -.if n 2**56 -to -.if t 2\u\s-348\s0\d -.if n 2**48 -keys. -To prevent this, the high-order bit must be a function depending in part -upon the low-order bit; so, the high-order bit is set to whatever value -gives odd parity. -This preserves the key space size. -Note this resetting of the parity bit is -.Em not -done if the key is given in binary or hex, and can be disabled for ASCII -keys as well. -.Pp -The DES is considered a strong cryptosystem hobbled by a short -key, and other than table lookup attacks, key search attacks, and -Hellman's time-memory tradeoff (all of which are expensive and -time-consuming), no practical cryptanalytic methods for breaking the -DES are known in the open literature. -As of this writing, the best -known cryptanalytic method is linear cryptanalysis, which requires an -average of -.if t 2\u\s-343\s0\d -.if n 2**43 -known plaintext-ciphertext pairs to succeed. -Unfortunately for the DES, key search attacks (requiring only -a single known plaintext-ciphertext pair and trying -.if t 2\u\s-355\s0\d -.if n 2**55 -keys on average) are becoming practical. -.Pp -As with all cryptosystems, the choice of keys and -key security remain the most vulnerable aspect of -.Nm . -.Sh IMPLEMENTATION NOTES -For implementors wishing to write software compatible with this program, -the following notes are provided. -This software is believed to be compatible with the implementation of the -data encryption standard distributed by Sun Microsystems, Inc. -.Pp -In the ECB and CBC modes, plaintext is encrypted in units of 64 bits (8 bytes, -also called a block). -To ensure that the plaintext file is encrypted correctly, -.Nm -will (internally) append from 1 to 8 bytes, the last byte containing an -integer stating how many bytes of that final block are from the plaintext -file, and encrypt the resulting block. -Hence, when decrypting, the last block may contain from 0 to 7 characters -present in the plaintext file, and the last byte tells how many. -Note that if during decryption the last byte of the file does not contain an -integer between 0 and 7, either the file has been corrupted or an incorrect -key has been given. -A similar mechanism is used for the OFB and CFB modes, except that those -simply require the length of the input to be a multiple of the mode size, -and the final byte contains an integer between 0 and one less than the number -of bytes being used as the mode. -(This was another reason that the mode size must be a multiple of 8 for those -modes.) -.Pp -Unlike Sun's implementation, unused bytes of that last block are not filled -with random data, but instead contain what was in those byte positions in -the preceding block. -This is quicker and more portable, and does not weaken the encryption -significantly. -.Pp -If the key is entered in ASCII, the parity bits of the key characters are set -so that each key character is of odd parity. -Unlike Sun's implementation, it is possible to enter binary or hexadecimal -keys on the command line, and if this is done, the parity bits are -.Em not -reset. -This allows testing using arbitrary bit patterns as keys. -.Pp -The Sun implementation always uses an initialization vector of 0 -(that is, all zeroes). -By default, -.Nm -does too, but this may be changed from the command line. -.Sh SEE ALSO -.Xr crypt 3 , -.Xr getpass 3 -.Rs -.%T Data Encryption Standard -.%R Federal Information Processing Standard #46 -.%Q National Bureau of Standards, U.S. Department of Commerce -.%C Washington DC -.%D January 1977 -.Re -.Rs -.%T DES Modes of Operation -.%R Federal Information Processing Standard #81 -.%Q National Bureau of Standards, U.S. Department of Commerce -.%C Washington DC -.%D December 1980 -.Re -.Rs -.%A Dorothy Denning -.%T Cryptography and Data Security -.%I Addison-Wesley Publishing Co. -.%C Reading, MA -.%D 1982 -.Re -.Rs -.%A Matt Bishop -.%T Implementation Notes on bdes(1) -.%R Technical Report PCS-TR-91-158 -.%Q Department of Mathematics and Computer Science, Dartmouth College -.%C Hanover, NH 03755 -.%D April 1991 -.Re -.Rs -.%A M.J. Wiener -.%T Efficient DES Key Search -.%R Technical Report 244 -.%Q School of Computer Science, Carleton University -.%D May 1994 -.Re -.Rs -.%A Bruce Schneier -.%T Applied Cryptography (2nd edition) -.%I John Wiley & Sons, Inc. -.%C New York, NY -.%D 1996 -.Re -.Rs -.%A M. Matsui -.%T Linear Cryptanalysis Method for DES Cipher -.%R Advances in Cryptology \(em Eurocrypt '93 Proceedings -.%I Springer-Verlag -.%D 1994 -.Re -.Rs -.%A Blaze -.%A Diffie -.%A Rivest -.%A Schneier -.%A Shimomura -.%A Thompson -.%A Wiener -.%T "Minimal Key Lengths for Symmetric Ciphers To Provide Adequate Commercial Security" -.%D January 1996 -.Re -.Sh BUGS -When this document was originally written, there was a controversy -raging over whether the DES would still be secure in a few years. -There is now near-universal consensus in the cryptographic community -that the key length of the DES is far too short. -The advent of -special-purpose hardware could reduce the cost of any of the methods -of attack named above so that they are no longer computationally -infeasible; in addition, the explosive growth in the number and speed -of modern microprocessors as well as advances in programmable logic -devices has brought an attack using only commodity hardware into the -realm of possibility. -Schneier and others currently recommend using -cryptosystems with keys of at least 90 bits when long-term security is -needed. -.Pp -As the key or key schedule is stored in memory, the encryption can be -compromised if memory is readable. -Additionally, programs which display programs' arguments may compromise the -key and initialization vector, if they are specified on the command line. -To avoid this -.Nm -overwrites its arguments, however, the obvious race cannot currently be -avoided. -.Pp -Certain specific keys should be avoided because they introduce potential -weaknesses; these keys, called the -.Em weak -and -.Em semiweak -keys, are (in hex notation, where p is either 0 or 1, and P is either -e or f): -.Bd -literal -offset indent -0x0p0p0p0p0p0p0p0p 0x0p1P0p1P0p0P0p0P -0x0pep0pep0pfp0pfp 0x0pfP0pfP0pfP0pfP -0x1P0p1P0p0P0p0P0p 0x1P1P1P1P0P0P0P0P -0x1Pep1Pep0Pfp0Pfp 0x1PfP1PfP0PfP0PfP -0xep0pep0pfp0pfp0p 0xep1Pep1pfp0Pfp0P -0xepepepepepepepep 0xepfPepfPfpfPfpfP -0xfP0pfP0pfP0pfP0p 0xfP1PfP1PfP0PfP0P -0xfPepfPepfPepfPep 0xfPfPfPfPfPfPfPfP -.Ed -.Pp -This is inherent in the DES algorithm (see Moore and Simmons, -.Do -Cycle structure of the DES with weak and semi-weak keys -.Dc , -.Em "Advances in Cryptology \- Crypto '86 Proceedings" , -Springer-Verlag New York, \(co1987, pp. 9-32.) diff --git a/usr.bin/bdes/bdes.c b/usr.bin/bdes/bdes.c deleted file mode 100644 index 65385e361f4..00000000000 --- a/usr.bin/bdes/bdes.c +++ /dev/null @@ -1,1004 +0,0 @@ -/* $OpenBSD: bdes.c,v 1.18 2013/11/25 18:02:50 deraadt Exp $ */ -/* $NetBSD: bdes.c,v 1.2 1995/03/26 03:33:19 glass Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Matt Bishop of Dartmouth College. - * - * The United States Government has rights in this work pursuant - * to contract no. NAG 2-680 between the National Aeronautics and - * Space Administration and Dartmouth College. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * BDES -- DES encryption package for Berkeley Software Distribution 4.4 - * options: - * -a key is in ASCII - * -b use ECB (electronic code book) mode - * -d invert (decrypt) input - * -f b use b-bit CFB (cipher feedback) mode - * -F b use b-bit CFB (cipher feedback) alternative mode - * -k key use key as the cryptographic key - * -m b generate a MAC of length b - * -o b use b-bit OFB (output feedback) mode - * -p don't reset the parity bit - * -v v use v as the initialization vector (ignored for ECB) - * note: the last character of the last block is the integer indicating - * how many characters of that block are to be output - * - * Author: Matt Bishop - * Department of Mathematics and Computer Science - * Dartmouth College - * Hanover, NH 03755 - * Email: Matt.Bishop@dartmouth.edu - * ...!decvax!dartvax!Matt.Bishop - * - * See Technical Report PCS-TR91-158, Department of Mathematics and Computer - * Science, Dartmouth College, for a detailed description of the implemen- - * tation and differences between it and Sun's. The DES is described in - * FIPS PUB 46, and the modes in FIPS PUB 81 (see either the manual page - * or the technical report for a complete reference). - */ - -#include <err.h> -#include <errno.h> -#include <unistd.h> -#include <stdio.h> -#include <ctype.h> -#include <stdlib.h> -#include <string.h> - -typedef char Desbuf[8]; -int tobinhex(char, int); -void cvtkey(char *, char *); -int setbits(char *, int); -void makekey(Desbuf); -void ecbenc(void); -void ecbdec(void); -void cbcenc(void); -void cbcdec(void); -void cbcauth(void); -void cfbenc(void); -void cfbdec(void); -void cfbaenc(void); -void cfbadec(void); -void cfbauth(void); -void ofbdec(void); -void ofbenc(void); -void usage(void); - -/* - * BSD and System V systems offer special library calls that do - * block moves and fills, so if possible we take advantage of them - */ -#define MEMCPY(dest,src,len) bcopy((src),(dest),(len)) -#define MEMZERO(dest,len) bzero((dest),(len)) - -/* Hide the calls to the primitive encryption routines. */ -#define DES_KEY(buf) \ - if (des_setkey(buf)) \ - err(1, "des_setkey"); -#define DES_XFORM(buf) \ - if (des_cipher(buf, buf, 0L, (inverse ? -1 : 1))) \ - err(1, "des_cipher"); - -/* - * this does an error-checking write - */ -#define READ(buf, n) fread(buf, sizeof(char), n, stdin) -#define WRITE(buf,n) \ - if (fwrite(buf, sizeof(char), n, stdout) != n) \ - err(1, "block %d", bn); - -/* - * some things to make references easier - */ -#define CHAR(x,i) (x[i]) -#define UCHAR(x,i) (x[i]) -#define BUFFER(x) (x) -#define UBUFFER(x) (x) - -/* - * global variables and related macros - */ -#define KEY_DEFAULT 0 /* interpret radix of key from key */ -#define KEY_ASCII 1 /* key is in ASCII characters */ -int keybase = KEY_DEFAULT; /* how to interpret the key */ - -enum { /* encrypt, decrypt, authenticate */ - MODE_ENCRYPT, MODE_DECRYPT, MODE_AUTHENTICATE -} mode = MODE_ENCRYPT; -enum { /* ecb, cbc, cfb, cfba, ofb? */ - ALG_ECB, ALG_CBC, ALG_CFB, ALG_OFB, ALG_CFBA -} alg = ALG_CBC; - -Desbuf ivec; /* initialization vector */ -char bits[] = { /* used to extract bits from a char */ - '\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001' -}; -int inverse; /* 0 to encrypt, 1 to decrypt */ -int macbits = -1; /* number of bits in authentication */ -int fbbits = -1; /* number of feedback bits */ -int pflag; /* 1 to preserve parity bits */ - - -int -main(int ac, char *av[]) -{ - extern int optind; /* option (argument) number */ - extern char *optarg; /* argument to option if any */ - int i; /* counter in a for loop */ - char *p; /* used to obtain the key */ - Desbuf msgbuf; /* I/O buffer */ - int kflag; /* command-line encryption key */ - int argc; /* the real arg count */ - char **argv; /* the real argument vector */ - - /* - * Hide the arguments from ps(1) by making private copies of them - * and clobbering the global (visible to ps(1)) ones. - */ - argc = ac; - ac = 1; - argv = calloc(argc + 1, sizeof(char *)); - if (argv == NULL) - errx(1, "out of memory"); - for (i = 0; i < argc; ++i) { - argv[i] = strdup(av[i]); - MEMZERO(av[i], strlen(av[i])); - } - argv[argc] = NULL; - - /* initialize the initialization vector */ - MEMZERO(ivec, 8); - - /* process the argument list */ - kflag = 0; - while ((i = getopt(argc, argv, "abdF:f:k:m:o:pv:")) != -1) - switch (i) { - case 'a': /* key is ASCII */ - keybase = KEY_ASCII; - break; - case 'b': /* use ECB mode */ - alg = ALG_ECB; - break; - case 'd': /* decrypt */ - mode = MODE_DECRYPT; - break; - case 'F': /* use alternative CFB mode */ - alg = ALG_CFBA; - if ((fbbits = setbits(optarg, 7)) > 56 || fbbits == 0) - err(1, "-F: number must be 1-56 inclusive"); - else if (fbbits == -1) - err(1, "-F: number must be a multiple of 7"); - break; - case 'f': /* use CFB mode */ - alg = ALG_CFB; - if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0) - err(1, "-f: number must be 1-64 inclusive"); - else if (fbbits == -1) - err(1, "-f: number must be a multiple of 8"); - break; - case 'k': /* encryption key */ - kflag = 1; - cvtkey(BUFFER(msgbuf), optarg); - break; - case 'm': /* number of bits for MACing */ - mode = MODE_AUTHENTICATE; - if ((macbits = setbits(optarg, 1)) > 64) - err(1, "-m: number must be 0-64 inclusive"); - break; - case 'o': /* use OFB mode */ - alg = ALG_OFB; - if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0) - err(1, "-o: number must be 1-64 inclusive"); - else if (fbbits == -1) - err(1, "-o: number must be a multiple of 8"); - break; - case 'p': /* preserve parity bits */ - pflag = 1; - break; - case 'v': /* set initialization vector */ - cvtkey(BUFFER(ivec), optarg); - break; - default: /* error */ - usage(); - } - - if (!kflag) { - /* - * if the key's not ASCII, assume it is - */ - keybase = KEY_ASCII; - /* - * get the key - */ - if ((p = getpass("Enter key: ")) == NULL) - err(1, "getpass"); - /* - * copy it, nul-padded, into the key area - */ - cvtkey(BUFFER(msgbuf), p); - } - - makekey(msgbuf); - inverse = (alg == ALG_CBC || alg == ALG_ECB) && mode == MODE_DECRYPT; - - switch (alg) { - case ALG_CBC: - switch (mode) { - case MODE_AUTHENTICATE: /* authenticate using CBC mode */ - cbcauth(); - break; - case MODE_DECRYPT: /* decrypt using CBC mode */ - cbcdec(); - break; - case MODE_ENCRYPT: /* encrypt using CBC mode */ - cbcenc(); - break; - } - break; - case ALG_CFB: - switch (mode) { - case MODE_AUTHENTICATE: /* authenticate using CFB mode */ - cfbauth(); - break; - case MODE_DECRYPT: /* decrypt using CFB mode */ - cfbdec(); - break; - case MODE_ENCRYPT: /* encrypt using CFB mode */ - cfbenc(); - break; - } - break; - case ALG_CFBA: - switch (mode) { - case MODE_AUTHENTICATE: /* authenticate using CFBA mode */ - err(1, "can't authenticate with CFBA mode"); - break; - case MODE_DECRYPT: /* decrypt using CFBA mode */ - cfbadec(); - break; - case MODE_ENCRYPT: /* encrypt using CFBA mode */ - cfbaenc(); - break; - } - break; - case ALG_ECB: - switch (mode) { - case MODE_AUTHENTICATE: /* authenticate using ECB mode */ - err(1, "can't authenticate with ECB mode"); - break; - case MODE_DECRYPT: /* decrypt using ECB mode */ - ecbdec(); - break; - case MODE_ENCRYPT: /* encrypt using ECB mode */ - ecbenc(); - break; - } - break; - case ALG_OFB: - switch (mode) { - case MODE_AUTHENTICATE: /* authenticate using OFB mode */ - err(1, "can't authenticate with OFB mode"); - break; - case MODE_DECRYPT: /* decrypt using OFB mode */ - ofbdec(); - break; - case MODE_ENCRYPT: /* encrypt using OFB mode */ - ofbenc(); - break; - } - break; - } - exit(0); -} - -/* - * map a hex character to an integer - */ -int -tobinhex(char c, int radix) -{ - switch (c) { - case '0': return(0x0); - case '1': return(0x1); - case '2': return(radix > 2 ? 0x2 : -1); - case '3': return(radix > 3 ? 0x3 : -1); - case '4': return(radix > 4 ? 0x4 : -1); - case '5': return(radix > 5 ? 0x5 : -1); - case '6': return(radix > 6 ? 0x6 : -1); - case '7': return(radix > 7 ? 0x7 : -1); - case '8': return(radix > 8 ? 0x8 : -1); - case '9': return(radix > 9 ? 0x9 : -1); - case 'A': case 'a': return(radix > 10 ? 0xa : -1); - case 'B': case 'b': return(radix > 11 ? 0xb : -1); - case 'C': case 'c': return(radix > 12 ? 0xc : -1); - case 'D': case 'd': return(radix > 13 ? 0xd : -1); - case 'E': case 'e': return(radix > 14 ? 0xe : -1); - case 'F': case 'f': return(radix > 15 ? 0xf : -1); - } - /* - * invalid character - */ - return(-1); -} - -/* - * convert the key to a bit pattern - */ -void -cvtkey(char *obuf, char *ibuf) -{ - int i, j; /* counter in a for loop */ - int nbuf[64]; /* used for hex/key translation */ - - /* - * just switch on the key base - */ - switch (keybase) { - case KEY_ASCII: /* ASCII to integer */ - (void)strncpy(obuf, ibuf, 8); - return; - case KEY_DEFAULT: /* tell from context */ - /* - * leading '0x' or '0X' == hex key - */ - if (ibuf[0] == '0' && (ibuf[1] == 'x' || ibuf[1] == 'X')) { - ibuf = &ibuf[2]; - /* - * now translate it, bombing on any illegal hex digit - */ - for (i = 0; ibuf[i] && i < 16; i++) - if ((nbuf[i] = tobinhex(ibuf[i], 16)) == -1) - err(1, "bad hex digit in key"); - while (i < 16) - nbuf[i++] = 0; - for (i = 0; i < 8; i++) - obuf[i] = - ((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf); - /* preserve parity bits */ - pflag = 1; - return; - } - /* - * leading '0b' or '0B' == binary key - */ - if (ibuf[0] == '0' && (ibuf[1] == 'b' || ibuf[1] == 'B')) { - ibuf = &ibuf[2]; - /* - * now translate it, bombing on any illegal binary digit - */ - for (i = 0; ibuf[i] && i < 16; i++) - if ((nbuf[i] = tobinhex(ibuf[i], 2)) == -1) - err(1, "bad binary digit in key"); - while (i < 64) - nbuf[i++] = 0; - for (i = 0; i < 8; i++) - for (j = 0; j < 8; j++) - obuf[i] = (obuf[i]<<1)|nbuf[8*i+j]; - /* preserve parity bits */ - pflag = 1; - return; - } - /* - * no special leader -- ASCII - */ - (void)strncpy(obuf, ibuf, 8); - } -} - -/* - * convert an ASCII string into a decimal number: - * 1. must be between 0 and 64 inclusive - * 2. must be a valid decimal number - * 3. must be a multiple of mult - */ -int -setbits(char *s, int mult) -{ - char *p; /* pointer in a for loop */ - int n = 0; /* the integer collected */ - - /* - * skip white space - */ - while (isspace((unsigned char)*s)) - s++; - /* - * get the integer - */ - for (p = s; *p; p++) { - if (isdigit((unsigned char)*p)) - n = n * 10 + *p - '0'; - else { - err(1, "bad decimal digit in MAC length"); - } - } - /* - * be sure it's a multiple of mult - */ - return((n % mult != 0) ? -1 : n); -} - -/***************** - * DES FUNCTIONS * - *****************/ -/* - * This sets the DES key and (if you're using the deszip version) - * the direction of the transformation. This uses the Sun - * to map the 64-bit key onto the 56 bits that the key schedule - * generation routines use: the old way, which just uses the user- - * supplied 64 bits as is, and the new way, which resets the parity - * bit to be the same as the low-order bit in each character. The - * new way generates a greater variety of key schedules, since many - * systems set the parity (high) bit of each character to 0, and the - * DES ignores the low order bit of each character. - */ -void -makekey(Desbuf buf) -{ - int i, j; /* counter in a for loop */ - int par; /* parity counter */ - - /* - * if the parity is not preserved, flip it - */ - if (!pflag) { - for (i = 0; i < 8; i++) { - par = 0; - for (j = 1; j < 8; j++) - if ((bits[j]&UCHAR(buf, i)) != 0) - par++; - if ((par&01) == 01) - UCHAR(buf, i) = UCHAR(buf, i)&0177; - else - UCHAR(buf, i) = (UCHAR(buf, i)&0177)|0200; - } - } - - DES_KEY(UBUFFER(buf)); -} - -/* - * This encrypts using the Electronic Code Book mode of DES - */ -void -ecbenc(void) -{ - int n; /* number of bytes actually read */ - int bn; /* block number */ - Desbuf msgbuf; /* I/O buffer */ - - for (bn = 0; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) { - /* - * do the transformation - */ - DES_XFORM(UBUFFER(msgbuf)); - WRITE(BUFFER(msgbuf), 8); - } - /* - * at EOF or last block -- in either ase, the last byte contains - * the character representation of the number of bytes in it - */ - bn++; - MEMZERO(&CHAR(msgbuf, n), 8 - n); - CHAR(msgbuf, 7) = n; - DES_XFORM(UBUFFER(msgbuf)); - WRITE(BUFFER(msgbuf), 8); - -} - -/* - * This decrypts using the Electronic Code Book mode of DES - */ -void -ecbdec(void) -{ - int n; /* number of bytes actually read */ - int c; /* used to test for EOF */ - int bn; /* block number */ - Desbuf msgbuf; /* I/O buffer */ - - for (bn = 1; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) { - /* - * do the transformation - */ - DES_XFORM(UBUFFER(msgbuf)); - /* - * if the last one, handle it specially - */ - if ((c = getchar()) == EOF) { - n = CHAR(msgbuf, 7); - if (n < 0 || n > 7) - err(1, "decryption failed (block %d corrupted)", bn); - } - else - (void)ungetc(c, stdin); - WRITE(BUFFER(msgbuf), n); - } - if (n > 0) - err(1, "decryption failed (block %d incomplete)", bn); -} - -/* - * This encrypts using the Cipher Block Chaining mode of DES - */ -void -cbcenc(void) -{ - int n; /* number of bytes actually read */ - int bn; /* block number */ - Desbuf msgbuf; /* I/O buffer */ - - /* - * do the transformation - */ - for (bn = 1; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) { - for (n = 0; n < 8; n++) - CHAR(msgbuf, n) ^= CHAR(ivec, n); - DES_XFORM(UBUFFER(msgbuf)); - MEMCPY(BUFFER(ivec), BUFFER(msgbuf), 8); - WRITE(BUFFER(msgbuf), 8); - } - /* - * at EOF or last block -- in either case, the last byte contains - * the character representation of the number of bytes in it - */ - bn++; - MEMZERO(&CHAR(msgbuf, n), 8 - n); - CHAR(msgbuf, 7) = n; - for (n = 0; n < 8; n++) - CHAR(msgbuf, n) ^= CHAR(ivec, n); - DES_XFORM(UBUFFER(msgbuf)); - WRITE(BUFFER(msgbuf), 8); - -} - -/* - * This decrypts using the Cipher Block Chaining mode of DES - */ -void -cbcdec(void) -{ - int n; /* number of bytes actually read */ - Desbuf msgbuf; /* I/O buffer */ - Desbuf ibuf; /* temp buffer for initialization vector */ - int c; /* used to test for EOF */ - int bn; /* block number */ - - for (bn = 0; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) { - /* - * do the transformation - */ - MEMCPY(BUFFER(ibuf), BUFFER(msgbuf), 8); - DES_XFORM(UBUFFER(msgbuf)); - for (c = 0; c < 8; c++) - UCHAR(msgbuf, c) ^= UCHAR(ivec, c); - MEMCPY(BUFFER(ivec), BUFFER(ibuf), 8); - /* - * if the last one, handle it specially - */ - if ((c = getchar()) == EOF) { - n = CHAR(msgbuf, 7); - if (n < 0 || n > 7) - err(1, "decryption failed (block %d corrupted)", bn); - } - else - (void)ungetc(c, stdin); - WRITE(BUFFER(msgbuf), n); - } - if (n > 0) - err(1, "decryption failed (block %d incomplete)", bn); -} - -/* - * This authenticates using the Cipher Block Chaining mode of DES - */ -void -cbcauth(void) -{ - int n, j; /* number of bytes actually read */ - Desbuf msgbuf; /* I/O buffer */ - Desbuf encbuf; /* encryption buffer */ - - /* - * do the transformation - * note we DISCARD the encrypted block; - * we only care about the last one - */ - while ((n = READ(BUFFER(msgbuf), 8)) == 8) { - for (n = 0; n < 8; n++) - CHAR(encbuf, n) = CHAR(msgbuf, n) ^ CHAR(ivec, n); - DES_XFORM(UBUFFER(encbuf)); - MEMCPY(BUFFER(ivec), BUFFER(encbuf), 8); - } - /* - * now compute the last one, right padding with '\0' if need be - */ - if (n > 0) { - MEMZERO(&CHAR(msgbuf, n), 8 - n); - for (n = 0; n < 8; n++) - CHAR(encbuf, n) = CHAR(msgbuf, n) ^ CHAR(ivec, n); - DES_XFORM(UBUFFER(encbuf)); - } - /* - * drop the bits - * we write chars until fewer than 7 bits, - * and then pad the last one with 0 bits - */ - for (n = 0; macbits > 7; n++, macbits -= 8) - (void)putchar(CHAR(encbuf, n)); - if (macbits > 0) { - CHAR(msgbuf, 0) = 0x00; - for (j = 0; j < macbits; j++) - CHAR(msgbuf, 0) |= (CHAR(encbuf, n)&bits[j]); - (void)putchar(CHAR(msgbuf, 0)); - } -} - -/* - * This encrypts using the Cipher FeedBack mode of DES - */ -void -cfbenc(void) -{ - int n; /* number of bytes actually read */ - int nbytes; /* number of bytes to read */ - int bn; /* block number */ - char ibuf[8]; /* input buffer */ - Desbuf msgbuf; /* encryption buffer */ - - /* - * do things in bytes, not bits - */ - nbytes = fbbits / 8; - /* - * do the transformation - */ - for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) { - MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); - DES_XFORM(UBUFFER(msgbuf)); - for (n = 0; n < 8 - nbytes; n++) - UCHAR(ivec, n) = UCHAR(ivec, n+nbytes); - for (n = 0; n < nbytes; n++) - UCHAR(ivec, 8-nbytes+n) = ibuf[n] ^ UCHAR(msgbuf, n); - WRITE(&CHAR(ivec, 8-nbytes), nbytes); - } - /* - * at EOF or last block -- in either case, the last byte contains - * the character representation of the number of bytes in it - */ - bn++; - MEMZERO(&ibuf[n], nbytes - n); - ibuf[nbytes - 1] = n; - MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); - DES_XFORM(UBUFFER(msgbuf)); - for (n = 0; n < nbytes; n++) - ibuf[n] ^= UCHAR(msgbuf, n); - WRITE(ibuf, nbytes); -} - -/* - * This decrypts using the Cipher Block Chaining mode of DES - */ -void -cfbdec(void) -{ - int n; /* number of bytes actually read */ - int c; /* used to test for EOF */ - int nbytes; /* number of bytes to read */ - int bn; /* block number */ - char ibuf[8]; /* input buffer */ - char obuf[8]; /* output buffer */ - Desbuf msgbuf; /* encryption buffer */ - - /* - * do things in bytes, not bits - */ - nbytes = fbbits / 8; - /* - * do the transformation - */ - for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) { - MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); - DES_XFORM(UBUFFER(msgbuf)); - for (c = 0; c < 8 - nbytes; c++) - CHAR(ivec, c) = CHAR(ivec, c+nbytes); - for (c = 0; c < nbytes; c++) { - CHAR(ivec, 8-nbytes+c) = ibuf[c]; - obuf[c] = ibuf[c] ^ UCHAR(msgbuf, c); - } - /* - * if the last one, handle it specially - */ - if ((c = getchar()) == EOF) { - n = obuf[nbytes-1]; - if (n < 0 || n > nbytes-1) - err(1, "decryption failed (block %d corrupted)", bn); - } - else - (void)ungetc(c, stdin); - WRITE(obuf, n); - } - if (n > 0) - err(1, "decryption failed (block %d incomplete)", bn); -} - -/* - * This encrypts using the alternative Cipher FeedBack mode of DES - */ -void -cfbaenc(void) -{ - int n; /* number of bytes actually read */ - int nbytes; /* number of bytes to read */ - int bn; /* block number */ - char ibuf[8]; /* input buffer */ - char obuf[8]; /* output buffer */ - Desbuf msgbuf; /* encryption buffer */ - - /* - * do things in bytes, not bits - */ - nbytes = fbbits / 7; - /* - * do the transformation - */ - for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) { - MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); - DES_XFORM(UBUFFER(msgbuf)); - for (n = 0; n < 8 - nbytes; n++) - UCHAR(ivec, n) = UCHAR(ivec, n+nbytes); - for (n = 0; n < nbytes; n++) - UCHAR(ivec, 8-nbytes+n) = (ibuf[n] ^ UCHAR(msgbuf, n)) - |0200; - for (n = 0; n < nbytes; n++) - obuf[n] = CHAR(ivec, 8-nbytes+n)&0177; - WRITE(obuf, nbytes); - } - /* - * at EOF or last block -- in either case, the last byte contains - * the character representation of the number of bytes in it - */ - bn++; - MEMZERO(&ibuf[n], nbytes - n); - ibuf[nbytes - 1] = ('0' + n)|0200; - MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); - DES_XFORM(UBUFFER(msgbuf)); - for (n = 0; n < nbytes; n++) - ibuf[n] ^= UCHAR(msgbuf, n); - WRITE(ibuf, nbytes); -} - -/* - * This decrypts using the alternative Cipher Block Chaining mode of DES - */ -void -cfbadec(void) -{ - int n; /* number of bytes actually read */ - int c; /* used to test for EOF */ - int nbytes; /* number of bytes to read */ - int bn; /* block number */ - char ibuf[8]; /* input buffer */ - char obuf[8]; /* output buffer */ - Desbuf msgbuf; /* encryption buffer */ - - /* - * do things in bytes, not bits - */ - nbytes = fbbits / 7; - /* - * do the transformation - */ - for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) { - MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); - DES_XFORM(UBUFFER(msgbuf)); - for (c = 0; c < 8 - nbytes; c++) - CHAR(ivec, c) = CHAR(ivec, c+nbytes); - for (c = 0; c < nbytes; c++) { - CHAR(ivec, 8-nbytes+c) = ibuf[c]|0200; - obuf[c] = (ibuf[c] ^ UCHAR(msgbuf, c))&0177; - } - /* - * if the last one, handle it specially - */ - if ((c = getchar()) == EOF) { - if ((n = (obuf[nbytes-1] - '0')) < 0 - || n > nbytes-1) - err(1, "decryption failed (block %d corrupted)", bn); - } - else - (void)ungetc(c, stdin); - WRITE(obuf, n); - } - if (n > 0) - err(1, "decryption failed (block %d incomplete)", bn); -} - - -/* - * This encrypts using the Output FeedBack mode of DES - */ -void -ofbenc(void) -{ - int n; /* number of bytes actually read */ - int c; /* used to test for EOF */ - int nbytes; /* number of bytes to read */ - int bn; /* block number */ - char ibuf[8]; /* input buffer */ - char obuf[8]; /* output buffer */ - Desbuf msgbuf; /* encryption buffer */ - - /* - * do things in bytes, not bits - */ - nbytes = fbbits / 8; - /* - * do the transformation - */ - for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) { - MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); - DES_XFORM(UBUFFER(msgbuf)); - for (n = 0; n < 8 - nbytes; n++) - UCHAR(ivec, n) = UCHAR(ivec, n+nbytes); - for (n = 0; n < nbytes; n++) { - UCHAR(ivec, 8-nbytes+n) = UCHAR(msgbuf, n); - obuf[n] = ibuf[n] ^ UCHAR(msgbuf, n); - } - WRITE(obuf, nbytes); - } - /* - * at EOF or last block -- in either case, the last byte contains - * the character representation of the number of bytes in it - */ - bn++; - MEMZERO(&ibuf[n], nbytes - n); - ibuf[nbytes - 1] = n; - MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); - DES_XFORM(UBUFFER(msgbuf)); - for (c = 0; c < nbytes; c++) - ibuf[c] ^= UCHAR(msgbuf, c); - WRITE(ibuf, nbytes); -} - -/* - * This decrypts using the Output Block Chaining mode of DES - */ -void -ofbdec(void) -{ - int n; /* number of bytes actually read */ - int c; /* used to test for EOF */ - int nbytes; /* number of bytes to read */ - int bn; /* block number */ - char ibuf[8]; /* input buffer */ - char obuf[8]; /* output buffer */ - Desbuf msgbuf; /* encryption buffer */ - - /* - * do things in bytes, not bits - */ - nbytes = fbbits / 8; - /* - * do the transformation - */ - for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) { - MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); - DES_XFORM(UBUFFER(msgbuf)); - for (c = 0; c < 8 - nbytes; c++) - CHAR(ivec, c) = CHAR(ivec, c+nbytes); - for (c = 0; c < nbytes; c++) { - CHAR(ivec, 8-nbytes+c) = UCHAR(msgbuf, c); - obuf[c] = ibuf[c] ^ UCHAR(msgbuf, c); - } - /* - * if the last one, handle it specially - */ - if ((c = getchar()) == EOF) { - n = obuf[nbytes-1]; - if (n < 0 || n > nbytes-1) - err(1, "decryption failed (block %d corrupted)", bn); - } - else - (void)ungetc(c, stdin); - /* - * dump it - */ - WRITE(obuf, n); - } - if (n > 0) - err(1, "decryption failed (block %d incomplete)", bn); -} - -/* - * This authenticates using the Cipher FeedBack mode of DES - */ -void -cfbauth(void) -{ - int n, j; /* number of bytes actually read */ - int nbytes; /* number of bytes to read */ - char ibuf[8]; /* input buffer */ - Desbuf msgbuf; /* encryption buffer */ - - /* - * do things in bytes, not bits - */ - nbytes = fbbits / 8; - /* - * do the transformation - */ - while ((n = READ(ibuf, nbytes)) == nbytes) { - MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); - DES_XFORM(UBUFFER(msgbuf)); - for (n = 0; n < 8 - nbytes; n++) - UCHAR(ivec, n) = UCHAR(ivec, n+nbytes); - for (n = 0; n < nbytes; n++) - UCHAR(ivec, 8-nbytes+n) = ibuf[n] ^ UCHAR(msgbuf, n); - } - /* - * at EOF or last block -- in either case, the last byte contains - * the character representation of the number of bytes in it - */ - MEMZERO(&ibuf[n], nbytes - n); - ibuf[nbytes - 1] = '0' + n; - MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8); - DES_XFORM(UBUFFER(msgbuf)); - for (n = 0; n < nbytes; n++) - ibuf[n] ^= UCHAR(msgbuf, n); - /* - * drop the bits - * we write chars until fewer than 7 bits, - * and then pad the last one with 0 bits - */ - for (n = 0; macbits > 7; n++, macbits -= 8) - (void)putchar(CHAR(msgbuf, n)); - if (macbits > 0) { - CHAR(msgbuf, 0) = 0x00; - for (j = 0; j < macbits; j++) - CHAR(msgbuf, 0) |= (CHAR(msgbuf, n)&bits[j]); - (void)putchar(CHAR(msgbuf, 0)); - } -} - -extern char *__progname; -/* - * message about usage - */ -void -usage(void) -{ - (void) fprintf(stderr, "usage: %s %s\n", __progname, - "[-abdp] [-F N] [-f N] [-k key] [-m N] [-o N] [-v vector]"); - exit(1); -} |