Annotation of src/usr.bin/bdes/bdes.c, Revision 1.15
1.15 ! deraadt 1: /* $OpenBSD: bdes.c,v 1.14 2004/05/16 18:49:12 otto Exp $ */
1.1 deraadt 2: /* $NetBSD: bdes.c,v 1.2 1995/03/26 03:33:19 glass Exp $ */
3:
4: /*-
5: * Copyright (c) 1991, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * This code is derived from software contributed to Berkeley by
9: * Matt Bishop of Dartmouth College.
10: *
11: * The United States Government has rights in this work pursuant
12: * to contract no. NAG 2-680 between the National Aeronautics and
13: * Space Administration and Dartmouth College.
14: *
15: * Redistribution and use in source and binary forms, with or without
16: * modification, are permitted provided that the following conditions
17: * are met:
18: * 1. Redistributions of source code must retain the above copyright
19: * notice, this list of conditions and the following disclaimer.
20: * 2. Redistributions in binary form must reproduce the above copyright
21: * notice, this list of conditions and the following disclaimer in the
22: * documentation and/or other materials provided with the distribution.
1.10 millert 23: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 24: * may be used to endorse or promote products derived from this software
25: * without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37: * SUCH DAMAGE.
38: */
39:
40: #ifndef lint
41: static char copyright[] =
42: "@(#) Copyright (c) 1991, 1993\n\
43: The Regents of the University of California. All rights reserved.\n";
44: #endif /* not lint */
45:
46: #ifndef lint
47: #if 0
48: static char sccsid[] = "@(#)bdes.c 8.1 (Berkeley) 6/6/93";
49: #else
1.15 ! deraadt 50: static char rcsid[] = "$OpenBSD: bdes.c,v 1.14 2004/05/16 18:49:12 otto Exp $";
1.1 deraadt 51: #endif
52: #endif /* not lint */
53:
54: /*
55: * BDES -- DES encryption package for Berkeley Software Distribution 4.4
56: * options:
57: * -a key is in ASCII
58: * -b use ECB (electronic code book) mode
59: * -d invert (decrypt) input
60: * -f b use b-bit CFB (cipher feedback) mode
61: * -F b use b-bit CFB (cipher feedback) alternative mode
62: * -k key use key as the cryptographic key
63: * -m b generate a MAC of length b
64: * -o b use b-bit OFB (output feedback) mode
65: * -p don't reset the parity bit
66: * -v v use v as the initialization vector (ignored for ECB)
67: * note: the last character of the last block is the integer indicating
68: * how many characters of that block are to be output
69: *
70: * Author: Matt Bishop
71: * Department of Mathematics and Computer Science
72: * Dartmouth College
73: * Hanover, NH 03755
74: * Email: Matt.Bishop@dartmouth.edu
75: * ...!decvax!dartvax!Matt.Bishop
76: *
77: * See Technical Report PCS-TR91-158, Department of Mathematics and Computer
78: * Science, Dartmouth College, for a detailed description of the implemen-
79: * tation and differences between it and Sun's. The DES is described in
80: * FIPS PUB 46, and the modes in FIPS PUB 81 (see either the manual page
81: * or the technical report for a complete reference).
82: */
83:
1.5 deraadt 84: #include <err.h>
1.1 deraadt 85: #include <errno.h>
86: #include <unistd.h>
87: #include <stdio.h>
88: #include <ctype.h>
89: #include <stdlib.h>
90: #include <string.h>
91:
1.5 deraadt 92: typedef char Desbuf[8];
1.12 deraadt 93: int tobinhex(char, int);
1.7 millert 94: void cvtkey(char *, char *);
95: int setbits(char *, int);
96: void makekey(Desbuf);
97: void ecbenc(void);
98: void ecbdec(void);
99: void cbcenc(void);
100: void cbcdec(void);
101: void cbcauth(void);
102: void cfbenc(void);
103: void cfbdec(void);
104: void cfbaenc(void);
105: void cfbadec(void);
106: void cfbauth(void);
107: void ofbdec(void);
108: void ofbenc(void);
109: void usage(void);
1.5 deraadt 110:
1.1 deraadt 111: /*
112: * BSD and System V systems offer special library calls that do
113: * block moves and fills, so if possible we take advantage of them
114: */
115: #define MEMCPY(dest,src,len) bcopy((src),(dest),(len))
116: #define MEMZERO(dest,len) bzero((dest),(len))
117:
118: /* Hide the calls to the primitive encryption routines. */
119: #define FASTWAY
120: #ifdef FASTWAY
121: #define DES_KEY(buf) \
122: if (des_setkey(buf)) \
1.5 deraadt 123: err(1, "des_setkey");
1.1 deraadt 124: #define DES_XFORM(buf) \
125: if (des_cipher(buf, buf, 0L, (inverse ? -1 : 1))) \
1.5 deraadt 126: err(1, "des_cipher");
1.1 deraadt 127: #else
128: #define DES_KEY(buf) { \
129: char bits1[64]; /* bits of key */ \
130: expand(buf, bits1); \
131: if (setkey(bits1)) \
1.5 deraadt 132: err(1, "setkey"); \
1.1 deraadt 133: }
134: #define DES_XFORM(buf) { \
135: char bits1[64]; /* bits of message */ \
136: expand(buf, bits1); \
137: if (encrypt(bits1, inverse)) \
1.5 deraadt 138: err(1, "encrypt"); \
1.1 deraadt 139: compress(bits1, buf); \
140: }
1.14 otto 141: void expand(Desbuf, char *);
142: void compress(Desbuf, char *);
1.1 deraadt 143: #endif
144:
145: /*
146: * this does an error-checking write
147: */
148: #define READ(buf, n) fread(buf, sizeof(char), n, stdin)
149: #define WRITE(buf,n) \
150: if (fwrite(buf, sizeof(char), n, stdout) != n) \
1.4 deraadt 151: err(1, "block %d", bn);
1.1 deraadt 152:
153: /*
154: * some things to make references easier
155: */
156: #define CHAR(x,i) (x[i])
157: #define UCHAR(x,i) (x[i])
158: #define BUFFER(x) (x)
159: #define UBUFFER(x) (x)
160:
161: /*
162: * global variables and related macros
163: */
164: #define KEY_DEFAULT 0 /* interpret radix of key from key */
165: #define KEY_ASCII 1 /* key is in ASCII characters */
166: int keybase = KEY_DEFAULT; /* how to interpret the key */
167:
168: enum { /* encrypt, decrypt, authenticate */
169: MODE_ENCRYPT, MODE_DECRYPT, MODE_AUTHENTICATE
170: } mode = MODE_ENCRYPT;
171: enum { /* ecb, cbc, cfb, cfba, ofb? */
172: ALG_ECB, ALG_CBC, ALG_CFB, ALG_OFB, ALG_CFBA
173: } alg = ALG_CBC;
174:
175: Desbuf ivec; /* initialization vector */
176: char bits[] = { /* used to extract bits from a char */
177: '\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'
178: };
179: int inverse; /* 0 to encrypt, 1 to decrypt */
180: int macbits = -1; /* number of bits in authentication */
181: int fbbits = -1; /* number of feedback bits */
182: int pflag; /* 1 to preserve parity bits */
183:
1.5 deraadt 184:
185: int
1.11 deraadt 186: main(int ac, char *av[])
1.1 deraadt 187: {
188: extern int optind; /* option (argument) number */
189: extern char *optarg; /* argument to option if any */
1.6 mpech 190: int i; /* counter in a for loop */
191: char *p; /* used to obtain the key */
1.1 deraadt 192: Desbuf msgbuf; /* I/O buffer */
1.9 rohee 193: int kflag; /* command-line encryption key */
1.1 deraadt 194: int argc; /* the real arg count */
195: char **argv; /* the real argument vector */
196:
197: /*
198: * Hide the arguments from ps(1) by making private copies of them
199: * and clobbering the global (visible to ps(1)) ones.
200: */
201: argc = ac;
202: ac = 1;
1.15 ! deraadt 203: argv = calloc(argc + 1, sizeof(char *));
1.8 deraadt 204: if (argv == NULL)
205: errx(1, "out of memory");
1.1 deraadt 206: for (i = 0; i < argc; ++i) {
207: argv[i] = strdup(av[i]);
208: MEMZERO(av[i], strlen(av[i]));
209: }
210: argv[argc] = NULL;
211:
1.9 rohee 212: /* initialize the initialization vector */
1.1 deraadt 213: MEMZERO(ivec, 8);
214:
215: /* process the argument list */
216: kflag = 0;
1.3 millert 217: while ((i = getopt(argc, argv, "abdF:f:k:m:o:pv:")) != -1)
1.12 deraadt 218: switch (i) {
1.1 deraadt 219: case 'a': /* key is ASCII */
220: keybase = KEY_ASCII;
221: break;
222: case 'b': /* use ECB mode */
223: alg = ALG_ECB;
224: break;
225: case 'd': /* decrypt */
226: mode = MODE_DECRYPT;
227: break;
228: case 'F': /* use alternative CFB mode */
229: alg = ALG_CFBA;
230: if ((fbbits = setbits(optarg, 7)) > 56 || fbbits == 0)
1.4 deraadt 231: err(1, "-F: number must be 1-56 inclusive");
1.1 deraadt 232: else if (fbbits == -1)
1.4 deraadt 233: err(1, "-F: number must be a multiple of 7");
1.1 deraadt 234: break;
235: case 'f': /* use CFB mode */
236: alg = ALG_CFB;
237: if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)
1.4 deraadt 238: err(1, "-f: number must be 1-64 inclusive");
1.1 deraadt 239: else if (fbbits == -1)
1.4 deraadt 240: err(1, "-f: number must be a multiple of 8");
1.1 deraadt 241: break;
242: case 'k': /* encryption key */
243: kflag = 1;
244: cvtkey(BUFFER(msgbuf), optarg);
245: break;
246: case 'm': /* number of bits for MACing */
247: mode = MODE_AUTHENTICATE;
248: if ((macbits = setbits(optarg, 1)) > 64)
1.4 deraadt 249: err(1, "-m: number must be 0-64 inclusive");
1.1 deraadt 250: break;
251: case 'o': /* use OFB mode */
252: alg = ALG_OFB;
253: if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)
1.4 deraadt 254: err(1, "-o: number must be 1-64 inclusive");
1.1 deraadt 255: else if (fbbits == -1)
1.4 deraadt 256: err(1, "-o: number must be a multiple of 8");
1.1 deraadt 257: break;
258: case 'p': /* preserve parity bits */
259: pflag = 1;
260: break;
261: case 'v': /* set initialization vector */
262: cvtkey(BUFFER(ivec), optarg);
263: break;
264: default: /* error */
265: usage();
266: }
267:
268: if (!kflag) {
269: /*
270: * if the key's not ASCII, assume it is
271: */
272: keybase = KEY_ASCII;
273: /*
274: * get the key
275: */
1.13 tedu 276: if ((p = getpass("Enter key: ")) == NULL)
277: err(1, "getpass");
1.1 deraadt 278: /*
279: * copy it, nul-padded, into the key area
280: */
281: cvtkey(BUFFER(msgbuf), p);
282: }
283:
284: makekey(msgbuf);
285: inverse = (alg == ALG_CBC || alg == ALG_ECB) && mode == MODE_DECRYPT;
286:
1.12 deraadt 287: switch (alg) {
1.1 deraadt 288: case ALG_CBC:
1.12 deraadt 289: switch (mode) {
1.1 deraadt 290: case MODE_AUTHENTICATE: /* authenticate using CBC mode */
291: cbcauth();
292: break;
293: case MODE_DECRYPT: /* decrypt using CBC mode */
294: cbcdec();
295: break;
296: case MODE_ENCRYPT: /* encrypt using CBC mode */
297: cbcenc();
298: break;
299: }
300: break;
301: case ALG_CFB:
1.12 deraadt 302: switch (mode) {
1.1 deraadt 303: case MODE_AUTHENTICATE: /* authenticate using CFB mode */
304: cfbauth();
305: break;
306: case MODE_DECRYPT: /* decrypt using CFB mode */
307: cfbdec();
308: break;
309: case MODE_ENCRYPT: /* encrypt using CFB mode */
310: cfbenc();
311: break;
312: }
313: break;
314: case ALG_CFBA:
1.12 deraadt 315: switch (mode) {
1.1 deraadt 316: case MODE_AUTHENTICATE: /* authenticate using CFBA mode */
1.4 deraadt 317: err(1, "can't authenticate with CFBA mode");
1.1 deraadt 318: break;
319: case MODE_DECRYPT: /* decrypt using CFBA mode */
320: cfbadec();
321: break;
322: case MODE_ENCRYPT: /* encrypt using CFBA mode */
323: cfbaenc();
324: break;
325: }
326: break;
327: case ALG_ECB:
1.12 deraadt 328: switch (mode) {
1.1 deraadt 329: case MODE_AUTHENTICATE: /* authenticate using ECB mode */
1.4 deraadt 330: err(1, "can't authenticate with ECB mode");
1.1 deraadt 331: break;
332: case MODE_DECRYPT: /* decrypt using ECB mode */
333: ecbdec();
334: break;
335: case MODE_ENCRYPT: /* encrypt using ECB mode */
336: ecbenc();
337: break;
338: }
339: break;
340: case ALG_OFB:
1.12 deraadt 341: switch (mode) {
1.1 deraadt 342: case MODE_AUTHENTICATE: /* authenticate using OFB mode */
1.4 deraadt 343: err(1, "can't authenticate with OFB mode");
1.1 deraadt 344: break;
345: case MODE_DECRYPT: /* decrypt using OFB mode */
346: ofbdec();
347: break;
348: case MODE_ENCRYPT: /* encrypt using OFB mode */
349: ofbenc();
350: break;
351: }
352: break;
353: }
354: exit(0);
355: }
356:
357: /*
358: * map a hex character to an integer
359: */
1.5 deraadt 360: int
1.11 deraadt 361: tobinhex(char c, int radix)
1.1 deraadt 362: {
1.12 deraadt 363: switch (c) {
1.1 deraadt 364: case '0': return(0x0);
365: case '1': return(0x1);
366: case '2': return(radix > 2 ? 0x2 : -1);
367: case '3': return(radix > 3 ? 0x3 : -1);
368: case '4': return(radix > 4 ? 0x4 : -1);
369: case '5': return(radix > 5 ? 0x5 : -1);
370: case '6': return(radix > 6 ? 0x6 : -1);
371: case '7': return(radix > 7 ? 0x7 : -1);
372: case '8': return(radix > 8 ? 0x8 : -1);
373: case '9': return(radix > 9 ? 0x9 : -1);
374: case 'A': case 'a': return(radix > 10 ? 0xa : -1);
375: case 'B': case 'b': return(radix > 11 ? 0xb : -1);
376: case 'C': case 'c': return(radix > 12 ? 0xc : -1);
377: case 'D': case 'd': return(radix > 13 ? 0xd : -1);
378: case 'E': case 'e': return(radix > 14 ? 0xe : -1);
379: case 'F': case 'f': return(radix > 15 ? 0xf : -1);
380: }
381: /*
382: * invalid character
383: */
384: return(-1);
385: }
386:
387: /*
388: * convert the key to a bit pattern
389: */
1.5 deraadt 390: void
1.11 deraadt 391: cvtkey(char *obuf, char *ibuf)
1.1 deraadt 392: {
1.6 mpech 393: int i, j; /* counter in a for loop */
1.1 deraadt 394: int nbuf[64]; /* used for hex/key translation */
395:
396: /*
397: * just switch on the key base
398: */
1.12 deraadt 399: switch (keybase) {
1.9 rohee 400: case KEY_ASCII: /* ASCII to integer */
1.1 deraadt 401: (void)strncpy(obuf, ibuf, 8);
402: return;
403: case KEY_DEFAULT: /* tell from context */
404: /*
405: * leading '0x' or '0X' == hex key
406: */
407: if (ibuf[0] == '0' && (ibuf[1] == 'x' || ibuf[1] == 'X')) {
408: ibuf = &ibuf[2];
409: /*
410: * now translate it, bombing on any illegal hex digit
411: */
412: for (i = 0; ibuf[i] && i < 16; i++)
413: if ((nbuf[i] = tobinhex(ibuf[i], 16)) == -1)
1.4 deraadt 414: err(1, "bad hex digit in key");
1.1 deraadt 415: while (i < 16)
416: nbuf[i++] = 0;
417: for (i = 0; i < 8; i++)
418: obuf[i] =
419: ((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf);
420: /* preserve parity bits */
421: pflag = 1;
422: return;
423: }
424: /*
425: * leading '0b' or '0B' == binary key
426: */
427: if (ibuf[0] == '0' && (ibuf[1] == 'b' || ibuf[1] == 'B')) {
428: ibuf = &ibuf[2];
429: /*
430: * now translate it, bombing on any illegal binary digit
431: */
432: for (i = 0; ibuf[i] && i < 16; i++)
433: if ((nbuf[i] = tobinhex(ibuf[i], 2)) == -1)
1.4 deraadt 434: err(1, "bad binary digit in key");
1.1 deraadt 435: while (i < 64)
436: nbuf[i++] = 0;
437: for (i = 0; i < 8; i++)
438: for (j = 0; j < 8; j++)
439: obuf[i] = (obuf[i]<<1)|nbuf[8*i+j];
440: /* preserve parity bits */
441: pflag = 1;
442: return;
443: }
444: /*
445: * no special leader -- ASCII
446: */
447: (void)strncpy(obuf, ibuf, 8);
448: }
449: }
450:
451: /*
452: * convert an ASCII string into a decimal number:
453: * 1. must be between 0 and 64 inclusive
454: * 2. must be a valid decimal number
455: * 3. must be a multiple of mult
456: */
1.5 deraadt 457: int
1.11 deraadt 458: setbits(char *s, int mult)
1.1 deraadt 459: {
1.6 mpech 460: char *p; /* pointer in a for loop */
461: int n = 0; /* the integer collected */
1.1 deraadt 462:
463: /*
464: * skip white space
465: */
466: while (isspace(*s))
467: s++;
468: /*
469: * get the integer
470: */
471: for (p = s; *p; p++) {
472: if (isdigit(*p))
473: n = n * 10 + *p - '0';
474: else {
1.4 deraadt 475: err(1, "bad decimal digit in MAC length");
1.1 deraadt 476: }
477: }
478: /*
479: * be sure it's a multiple of mult
480: */
481: return((n % mult != 0) ? -1 : n);
482: }
483:
484: /*****************
485: * DES FUNCTIONS *
486: *****************/
487: /*
488: * This sets the DES key and (if you're using the deszip version)
489: * the direction of the transformation. This uses the Sun
490: * to map the 64-bit key onto the 56 bits that the key schedule
491: * generation routines use: the old way, which just uses the user-
492: * supplied 64 bits as is, and the new way, which resets the parity
493: * bit to be the same as the low-order bit in each character. The
494: * new way generates a greater variety of key schedules, since many
495: * systems set the parity (high) bit of each character to 0, and the
496: * DES ignores the low order bit of each character.
497: */
1.5 deraadt 498: void
1.11 deraadt 499: makekey(Desbuf buf)
1.1 deraadt 500: {
1.6 mpech 501: int i, j; /* counter in a for loop */
502: int par; /* parity counter */
1.1 deraadt 503:
504: /*
505: * if the parity is not preserved, flip it
506: */
507: if (!pflag) {
508: for (i = 0; i < 8; i++) {
509: par = 0;
510: for (j = 1; j < 8; j++)
511: if ((bits[j]&UCHAR(buf, i)) != 0)
512: par++;
513: if ((par&01) == 01)
514: UCHAR(buf, i) = UCHAR(buf, i)&0177;
515: else
516: UCHAR(buf, i) = (UCHAR(buf, i)&0177)|0200;
517: }
518: }
519:
520: DES_KEY(UBUFFER(buf));
521: }
522:
523: /*
524: * This encrypts using the Electronic Code Book mode of DES
525: */
1.5 deraadt 526: void
1.11 deraadt 527: ecbenc(void)
1.1 deraadt 528: {
1.6 mpech 529: int n; /* number of bytes actually read */
530: int bn; /* block number */
1.1 deraadt 531: Desbuf msgbuf; /* I/O buffer */
532:
533: for (bn = 0; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
534: /*
535: * do the transformation
536: */
537: DES_XFORM(UBUFFER(msgbuf));
538: WRITE(BUFFER(msgbuf), 8);
539: }
540: /*
541: * at EOF or last block -- in either ase, the last byte contains
542: * the character representation of the number of bytes in it
543: */
544: bn++;
545: MEMZERO(&CHAR(msgbuf, n), 8 - n);
546: CHAR(msgbuf, 7) = n;
547: DES_XFORM(UBUFFER(msgbuf));
548: WRITE(BUFFER(msgbuf), 8);
549:
550: }
551:
552: /*
553: * This decrypts using the Electronic Code Book mode of DES
554: */
1.5 deraadt 555: void
1.11 deraadt 556: ecbdec(void)
1.1 deraadt 557: {
1.6 mpech 558: int n; /* number of bytes actually read */
559: int c; /* used to test for EOF */
560: int bn; /* block number */
1.1 deraadt 561: Desbuf msgbuf; /* I/O buffer */
562:
563: for (bn = 1; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
564: /*
565: * do the transformation
566: */
567: DES_XFORM(UBUFFER(msgbuf));
568: /*
569: * if the last one, handle it specially
570: */
571: if ((c = getchar()) == EOF) {
572: n = CHAR(msgbuf, 7);
573: if (n < 0 || n > 7)
1.4 deraadt 574: err(1, "decryption failed (block %d corrupted)", bn);
1.1 deraadt 575: }
576: else
577: (void)ungetc(c, stdin);
578: WRITE(BUFFER(msgbuf), n);
579: }
580: if (n > 0)
1.4 deraadt 581: err(1, "decryption failed (block %d incomplete)", bn);
1.1 deraadt 582: }
583:
584: /*
585: * This encrypts using the Cipher Block Chaining mode of DES
586: */
1.5 deraadt 587: void
1.11 deraadt 588: cbcenc(void)
1.1 deraadt 589: {
1.6 mpech 590: int n; /* number of bytes actually read */
591: int bn; /* block number */
1.1 deraadt 592: Desbuf msgbuf; /* I/O buffer */
593:
594: /*
595: * do the transformation
596: */
597: for (bn = 1; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
598: for (n = 0; n < 8; n++)
599: CHAR(msgbuf, n) ^= CHAR(ivec, n);
600: DES_XFORM(UBUFFER(msgbuf));
601: MEMCPY(BUFFER(ivec), BUFFER(msgbuf), 8);
602: WRITE(BUFFER(msgbuf), 8);
603: }
604: /*
605: * at EOF or last block -- in either case, the last byte contains
606: * the character representation of the number of bytes in it
607: */
608: bn++;
609: MEMZERO(&CHAR(msgbuf, n), 8 - n);
610: CHAR(msgbuf, 7) = n;
611: for (n = 0; n < 8; n++)
612: CHAR(msgbuf, n) ^= CHAR(ivec, n);
613: DES_XFORM(UBUFFER(msgbuf));
614: WRITE(BUFFER(msgbuf), 8);
615:
616: }
617:
618: /*
619: * This decrypts using the Cipher Block Chaining mode of DES
620: */
1.5 deraadt 621: void
1.11 deraadt 622: cbcdec(void)
1.1 deraadt 623: {
1.6 mpech 624: int n; /* number of bytes actually read */
1.1 deraadt 625: Desbuf msgbuf; /* I/O buffer */
626: Desbuf ibuf; /* temp buffer for initialization vector */
1.6 mpech 627: int c; /* used to test for EOF */
628: int bn; /* block number */
1.1 deraadt 629:
630: for (bn = 0; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
631: /*
632: * do the transformation
633: */
634: MEMCPY(BUFFER(ibuf), BUFFER(msgbuf), 8);
635: DES_XFORM(UBUFFER(msgbuf));
636: for (c = 0; c < 8; c++)
637: UCHAR(msgbuf, c) ^= UCHAR(ivec, c);
638: MEMCPY(BUFFER(ivec), BUFFER(ibuf), 8);
639: /*
640: * if the last one, handle it specially
641: */
642: if ((c = getchar()) == EOF) {
643: n = CHAR(msgbuf, 7);
644: if (n < 0 || n > 7)
1.4 deraadt 645: err(1, "decryption failed (block %d corrupted)", bn);
1.1 deraadt 646: }
647: else
648: (void)ungetc(c, stdin);
649: WRITE(BUFFER(msgbuf), n);
650: }
651: if (n > 0)
1.4 deraadt 652: err(1, "decryption failed (block %d incomplete)", bn);
1.1 deraadt 653: }
654:
655: /*
656: * This authenticates using the Cipher Block Chaining mode of DES
657: */
1.5 deraadt 658: void
1.11 deraadt 659: cbcauth(void)
1.1 deraadt 660: {
1.6 mpech 661: int n, j; /* number of bytes actually read */
1.1 deraadt 662: Desbuf msgbuf; /* I/O buffer */
663: Desbuf encbuf; /* encryption buffer */
664:
665: /*
666: * do the transformation
667: * note we DISCARD the encrypted block;
668: * we only care about the last one
669: */
670: while ((n = READ(BUFFER(msgbuf), 8)) == 8) {
671: for (n = 0; n < 8; n++)
672: CHAR(encbuf, n) = CHAR(msgbuf, n) ^ CHAR(ivec, n);
673: DES_XFORM(UBUFFER(encbuf));
674: MEMCPY(BUFFER(ivec), BUFFER(encbuf), 8);
675: }
676: /*
677: * now compute the last one, right padding with '\0' if need be
678: */
679: if (n > 0) {
680: MEMZERO(&CHAR(msgbuf, n), 8 - n);
681: for (n = 0; n < 8; n++)
682: CHAR(encbuf, n) = CHAR(msgbuf, n) ^ CHAR(ivec, n);
683: DES_XFORM(UBUFFER(encbuf));
684: }
685: /*
686: * drop the bits
687: * we write chars until fewer than 7 bits,
688: * and then pad the last one with 0 bits
689: */
690: for (n = 0; macbits > 7; n++, macbits -= 8)
691: (void)putchar(CHAR(encbuf, n));
692: if (macbits > 0) {
693: CHAR(msgbuf, 0) = 0x00;
694: for (j = 0; j < macbits; j++)
695: CHAR(msgbuf, 0) |= (CHAR(encbuf, n)&bits[j]);
696: (void)putchar(CHAR(msgbuf, 0));
697: }
698: }
699:
700: /*
701: * This encrypts using the Cipher FeedBack mode of DES
702: */
1.5 deraadt 703: void
1.11 deraadt 704: cfbenc(void)
1.1 deraadt 705: {
1.6 mpech 706: int n; /* number of bytes actually read */
707: int nbytes; /* number of bytes to read */
708: int bn; /* block number */
1.1 deraadt 709: char ibuf[8]; /* input buffer */
710: Desbuf msgbuf; /* encryption buffer */
711:
712: /*
713: * do things in bytes, not bits
714: */
715: nbytes = fbbits / 8;
716: /*
717: * do the transformation
718: */
719: for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
720: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
721: DES_XFORM(UBUFFER(msgbuf));
722: for (n = 0; n < 8 - nbytes; n++)
723: UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
724: for (n = 0; n < nbytes; n++)
725: UCHAR(ivec, 8-nbytes+n) = ibuf[n] ^ UCHAR(msgbuf, n);
726: WRITE(&CHAR(ivec, 8-nbytes), nbytes);
727: }
728: /*
729: * at EOF or last block -- in either case, the last byte contains
730: * the character representation of the number of bytes in it
731: */
732: bn++;
733: MEMZERO(&ibuf[n], nbytes - n);
734: ibuf[nbytes - 1] = n;
735: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
736: DES_XFORM(UBUFFER(msgbuf));
737: for (n = 0; n < nbytes; n++)
738: ibuf[n] ^= UCHAR(msgbuf, n);
739: WRITE(ibuf, nbytes);
740: }
741:
742: /*
743: * This decrypts using the Cipher Block Chaining mode of DES
744: */
1.5 deraadt 745: void
1.11 deraadt 746: cfbdec(void)
1.1 deraadt 747: {
1.6 mpech 748: int n; /* number of bytes actually read */
749: int c; /* used to test for EOF */
750: int nbytes; /* number of bytes to read */
751: int bn; /* block number */
1.1 deraadt 752: char ibuf[8]; /* input buffer */
753: char obuf[8]; /* output buffer */
754: Desbuf msgbuf; /* encryption buffer */
755:
756: /*
757: * do things in bytes, not bits
758: */
759: nbytes = fbbits / 8;
760: /*
761: * do the transformation
762: */
763: for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
764: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
765: DES_XFORM(UBUFFER(msgbuf));
766: for (c = 0; c < 8 - nbytes; c++)
767: CHAR(ivec, c) = CHAR(ivec, c+nbytes);
768: for (c = 0; c < nbytes; c++) {
769: CHAR(ivec, 8-nbytes+c) = ibuf[c];
770: obuf[c] = ibuf[c] ^ UCHAR(msgbuf, c);
771: }
772: /*
773: * if the last one, handle it specially
774: */
775: if ((c = getchar()) == EOF) {
776: n = obuf[nbytes-1];
777: if (n < 0 || n > nbytes-1)
1.4 deraadt 778: err(1, "decryption failed (block %d corrupted)", bn);
1.1 deraadt 779: }
780: else
781: (void)ungetc(c, stdin);
782: WRITE(obuf, n);
783: }
784: if (n > 0)
1.4 deraadt 785: err(1, "decryption failed (block %d incomplete)", bn);
1.1 deraadt 786: }
787:
788: /*
789: * This encrypts using the alternative Cipher FeedBack mode of DES
790: */
1.5 deraadt 791: void
1.11 deraadt 792: cfbaenc(void)
1.1 deraadt 793: {
1.6 mpech 794: int n; /* number of bytes actually read */
795: int nbytes; /* number of bytes to read */
796: int bn; /* block number */
1.1 deraadt 797: char ibuf[8]; /* input buffer */
798: char obuf[8]; /* output buffer */
799: Desbuf msgbuf; /* encryption buffer */
800:
801: /*
802: * do things in bytes, not bits
803: */
804: nbytes = fbbits / 7;
805: /*
806: * do the transformation
807: */
808: for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
809: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
810: DES_XFORM(UBUFFER(msgbuf));
811: for (n = 0; n < 8 - nbytes; n++)
812: UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
813: for (n = 0; n < nbytes; n++)
814: UCHAR(ivec, 8-nbytes+n) = (ibuf[n] ^ UCHAR(msgbuf, n))
815: |0200;
816: for (n = 0; n < nbytes; n++)
817: obuf[n] = CHAR(ivec, 8-nbytes+n)&0177;
818: WRITE(obuf, nbytes);
819: }
820: /*
821: * at EOF or last block -- in either case, the last byte contains
822: * the character representation of the number of bytes in it
823: */
824: bn++;
825: MEMZERO(&ibuf[n], nbytes - n);
826: ibuf[nbytes - 1] = ('0' + n)|0200;
827: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
828: DES_XFORM(UBUFFER(msgbuf));
829: for (n = 0; n < nbytes; n++)
830: ibuf[n] ^= UCHAR(msgbuf, n);
831: WRITE(ibuf, nbytes);
832: }
833:
834: /*
835: * This decrypts using the alternative Cipher Block Chaining mode of DES
836: */
1.5 deraadt 837: void
1.11 deraadt 838: cfbadec(void)
1.1 deraadt 839: {
1.6 mpech 840: int n; /* number of bytes actually read */
841: int c; /* used to test for EOF */
842: int nbytes; /* number of bytes to read */
843: int bn; /* block number */
1.1 deraadt 844: char ibuf[8]; /* input buffer */
845: char obuf[8]; /* output buffer */
846: Desbuf msgbuf; /* encryption buffer */
847:
848: /*
849: * do things in bytes, not bits
850: */
851: nbytes = fbbits / 7;
852: /*
853: * do the transformation
854: */
855: for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
856: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
857: DES_XFORM(UBUFFER(msgbuf));
858: for (c = 0; c < 8 - nbytes; c++)
859: CHAR(ivec, c) = CHAR(ivec, c+nbytes);
860: for (c = 0; c < nbytes; c++) {
861: CHAR(ivec, 8-nbytes+c) = ibuf[c]|0200;
862: obuf[c] = (ibuf[c] ^ UCHAR(msgbuf, c))&0177;
863: }
864: /*
865: * if the last one, handle it specially
866: */
867: if ((c = getchar()) == EOF) {
868: if ((n = (obuf[nbytes-1] - '0')) < 0
869: || n > nbytes-1)
1.4 deraadt 870: err(1, "decryption failed (block %d corrupted)", bn);
1.1 deraadt 871: }
872: else
873: (void)ungetc(c, stdin);
874: WRITE(obuf, n);
875: }
876: if (n > 0)
1.4 deraadt 877: err(1, "decryption failed (block %d incomplete)", bn);
1.1 deraadt 878: }
879:
880:
881: /*
882: * This encrypts using the Output FeedBack mode of DES
883: */
1.5 deraadt 884: void
1.11 deraadt 885: ofbenc(void)
1.1 deraadt 886: {
1.6 mpech 887: int n; /* number of bytes actually read */
888: int c; /* used to test for EOF */
889: int nbytes; /* number of bytes to read */
890: int bn; /* block number */
1.1 deraadt 891: char ibuf[8]; /* input buffer */
892: char obuf[8]; /* output buffer */
893: Desbuf msgbuf; /* encryption buffer */
894:
895: /*
896: * do things in bytes, not bits
897: */
898: nbytes = fbbits / 8;
899: /*
900: * do the transformation
901: */
902: for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
903: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
904: DES_XFORM(UBUFFER(msgbuf));
905: for (n = 0; n < 8 - nbytes; n++)
906: UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
907: for (n = 0; n < nbytes; n++) {
908: UCHAR(ivec, 8-nbytes+n) = UCHAR(msgbuf, n);
909: obuf[n] = ibuf[n] ^ UCHAR(msgbuf, n);
910: }
911: WRITE(obuf, nbytes);
912: }
913: /*
914: * at EOF or last block -- in either case, the last byte contains
915: * the character representation of the number of bytes in it
916: */
917: bn++;
918: MEMZERO(&ibuf[n], nbytes - n);
919: ibuf[nbytes - 1] = n;
920: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
921: DES_XFORM(UBUFFER(msgbuf));
922: for (c = 0; c < nbytes; c++)
923: ibuf[c] ^= UCHAR(msgbuf, c);
924: WRITE(ibuf, nbytes);
925: }
926:
927: /*
928: * This decrypts using the Output Block Chaining mode of DES
929: */
1.5 deraadt 930: void
1.11 deraadt 931: ofbdec(void)
1.1 deraadt 932: {
1.6 mpech 933: int n; /* number of bytes actually read */
934: int c; /* used to test for EOF */
935: int nbytes; /* number of bytes to read */
936: int bn; /* block number */
1.1 deraadt 937: char ibuf[8]; /* input buffer */
938: char obuf[8]; /* output buffer */
939: Desbuf msgbuf; /* encryption buffer */
940:
941: /*
942: * do things in bytes, not bits
943: */
944: nbytes = fbbits / 8;
945: /*
946: * do the transformation
947: */
948: for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
949: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
950: DES_XFORM(UBUFFER(msgbuf));
951: for (c = 0; c < 8 - nbytes; c++)
952: CHAR(ivec, c) = CHAR(ivec, c+nbytes);
953: for (c = 0; c < nbytes; c++) {
954: CHAR(ivec, 8-nbytes+c) = UCHAR(msgbuf, c);
955: obuf[c] = ibuf[c] ^ UCHAR(msgbuf, c);
956: }
957: /*
958: * if the last one, handle it specially
959: */
960: if ((c = getchar()) == EOF) {
961: n = obuf[nbytes-1];
962: if (n < 0 || n > nbytes-1)
1.4 deraadt 963: err(1, "decryption failed (block %d corrupted)", bn);
1.1 deraadt 964: }
965: else
966: (void)ungetc(c, stdin);
967: /*
968: * dump it
969: */
970: WRITE(obuf, n);
971: }
972: if (n > 0)
1.4 deraadt 973: err(1, "decryption failed (block %d incomplete)", bn);
1.1 deraadt 974: }
975:
976: /*
977: * This authenticates using the Cipher FeedBack mode of DES
978: */
1.5 deraadt 979: void
1.11 deraadt 980: cfbauth(void)
1.1 deraadt 981: {
1.6 mpech 982: int n, j; /* number of bytes actually read */
983: int nbytes; /* number of bytes to read */
1.1 deraadt 984: char ibuf[8]; /* input buffer */
985: Desbuf msgbuf; /* encryption buffer */
986:
987: /*
988: * do things in bytes, not bits
989: */
990: nbytes = fbbits / 8;
991: /*
992: * do the transformation
993: */
994: while ((n = READ(ibuf, nbytes)) == nbytes) {
995: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
996: DES_XFORM(UBUFFER(msgbuf));
997: for (n = 0; n < 8 - nbytes; n++)
998: UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
999: for (n = 0; n < nbytes; n++)
1000: UCHAR(ivec, 8-nbytes+n) = ibuf[n] ^ UCHAR(msgbuf, n);
1001: }
1002: /*
1003: * at EOF or last block -- in either case, the last byte contains
1004: * the character representation of the number of bytes in it
1005: */
1006: MEMZERO(&ibuf[n], nbytes - n);
1007: ibuf[nbytes - 1] = '0' + n;
1008: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
1009: DES_XFORM(UBUFFER(msgbuf));
1010: for (n = 0; n < nbytes; n++)
1011: ibuf[n] ^= UCHAR(msgbuf, n);
1012: /*
1013: * drop the bits
1014: * we write chars until fewer than 7 bits,
1015: * and then pad the last one with 0 bits
1016: */
1017: for (n = 0; macbits > 7; n++, macbits -= 8)
1018: (void)putchar(CHAR(msgbuf, n));
1019: if (macbits > 0) {
1020: CHAR(msgbuf, 0) = 0x00;
1021: for (j = 0; j < macbits; j++)
1022: CHAR(msgbuf, 0) |= (CHAR(msgbuf, n)&bits[j]);
1023: (void)putchar(CHAR(msgbuf, 0));
1024: }
1025: }
1026:
1027: #ifndef FASTWAY
1028: /*
1029: * change from 8 bits/Uchar to 1 bit/Uchar
1030: */
1.14 otto 1031: void
1032: expand(Desbuf from, char *to)
1.1 deraadt 1033: {
1.6 mpech 1034: int i, j; /* counters in for loop */
1.1 deraadt 1035:
1036: for (i = 0; i < 8; i++)
1037: for (j = 0; j < 8; j++)
1038: *to++ = (CHAR(from, i)>>(7-j))&01;
1039: }
1040:
1041: /*
1042: * change from 1 bit/char to 8 bits/Uchar
1043: */
1.14 otto 1044: void
1045: compress(char *from, Desbuf to)
1.1 deraadt 1046: {
1.6 mpech 1047: int i, j; /* counters in for loop */
1.1 deraadt 1048:
1049: for (i = 0; i < 8; i++) {
1050: CHAR(to, i) = 0;
1051: for (j = 0; j < 8; j++)
1052: CHAR(to, i) = ((*from++)<<(7-j))|CHAR(to, i);
1053: }
1054: }
1055: #endif
1056:
1.14 otto 1057: extern char *__progname;
1.1 deraadt 1058: /*
1059: * message about usage
1060: */
1.5 deraadt 1061: void
1.11 deraadt 1062: usage(void)
1.1 deraadt 1063: {
1.14 otto 1064: (void) fprintf(stderr, "usage: %s %s\n", __progname,
1065: "[-abdp] [-F N] [-f N] [-k key] [-m N] [-o N] [-v vector]");
1.1 deraadt 1066: exit(1);
1067: }