Annotation of src/usr.bin/bdes/bdes.c, Revision 1.13
1.13 ! tedu 1: /* $OpenBSD: bdes.c,v 1.12 2003/07/02 21:04:09 deraadt 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.13 ! tedu 50: static char rcsid[] = "$OpenBSD: bdes.c,v 1.12 2003/07/02 21:04:09 deraadt 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: }
141: #endif
142:
143: /*
144: * this does an error-checking write
145: */
146: #define READ(buf, n) fread(buf, sizeof(char), n, stdin)
147: #define WRITE(buf,n) \
148: if (fwrite(buf, sizeof(char), n, stdout) != n) \
1.4 deraadt 149: err(1, "block %d", bn);
1.1 deraadt 150:
151: /*
152: * some things to make references easier
153: */
154: #define CHAR(x,i) (x[i])
155: #define UCHAR(x,i) (x[i])
156: #define BUFFER(x) (x)
157: #define UBUFFER(x) (x)
158:
159: /*
160: * global variables and related macros
161: */
162: #define KEY_DEFAULT 0 /* interpret radix of key from key */
163: #define KEY_ASCII 1 /* key is in ASCII characters */
164: int keybase = KEY_DEFAULT; /* how to interpret the key */
165:
166: enum { /* encrypt, decrypt, authenticate */
167: MODE_ENCRYPT, MODE_DECRYPT, MODE_AUTHENTICATE
168: } mode = MODE_ENCRYPT;
169: enum { /* ecb, cbc, cfb, cfba, ofb? */
170: ALG_ECB, ALG_CBC, ALG_CFB, ALG_OFB, ALG_CFBA
171: } alg = ALG_CBC;
172:
173: Desbuf ivec; /* initialization vector */
174: char bits[] = { /* used to extract bits from a char */
175: '\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'
176: };
177: int inverse; /* 0 to encrypt, 1 to decrypt */
178: int macbits = -1; /* number of bits in authentication */
179: int fbbits = -1; /* number of feedback bits */
180: int pflag; /* 1 to preserve parity bits */
181:
1.5 deraadt 182:
183: int
1.11 deraadt 184: main(int ac, char *av[])
1.1 deraadt 185: {
186: extern int optind; /* option (argument) number */
187: extern char *optarg; /* argument to option if any */
1.6 mpech 188: int i; /* counter in a for loop */
189: char *p; /* used to obtain the key */
1.1 deraadt 190: Desbuf msgbuf; /* I/O buffer */
1.9 rohee 191: int kflag; /* command-line encryption key */
1.1 deraadt 192: int argc; /* the real arg count */
193: char **argv; /* the real argument vector */
194:
195: /*
196: * Hide the arguments from ps(1) by making private copies of them
197: * and clobbering the global (visible to ps(1)) ones.
198: */
199: argc = ac;
200: ac = 1;
201: argv = malloc((argc + 1) * sizeof(char *));
1.8 deraadt 202: if (argv == NULL)
203: errx(1, "out of memory");
1.1 deraadt 204: for (i = 0; i < argc; ++i) {
205: argv[i] = strdup(av[i]);
206: MEMZERO(av[i], strlen(av[i]));
207: }
208: argv[argc] = NULL;
209:
1.9 rohee 210: /* initialize the initialization vector */
1.1 deraadt 211: MEMZERO(ivec, 8);
212:
213: /* process the argument list */
214: kflag = 0;
1.3 millert 215: while ((i = getopt(argc, argv, "abdF:f:k:m:o:pv:")) != -1)
1.12 deraadt 216: switch (i) {
1.1 deraadt 217: case 'a': /* key is ASCII */
218: keybase = KEY_ASCII;
219: break;
220: case 'b': /* use ECB mode */
221: alg = ALG_ECB;
222: break;
223: case 'd': /* decrypt */
224: mode = MODE_DECRYPT;
225: break;
226: case 'F': /* use alternative CFB mode */
227: alg = ALG_CFBA;
228: if ((fbbits = setbits(optarg, 7)) > 56 || fbbits == 0)
1.4 deraadt 229: err(1, "-F: number must be 1-56 inclusive");
1.1 deraadt 230: else if (fbbits == -1)
1.4 deraadt 231: err(1, "-F: number must be a multiple of 7");
1.1 deraadt 232: break;
233: case 'f': /* use CFB mode */
234: alg = ALG_CFB;
235: if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)
1.4 deraadt 236: err(1, "-f: number must be 1-64 inclusive");
1.1 deraadt 237: else if (fbbits == -1)
1.4 deraadt 238: err(1, "-f: number must be a multiple of 8");
1.1 deraadt 239: break;
240: case 'k': /* encryption key */
241: kflag = 1;
242: cvtkey(BUFFER(msgbuf), optarg);
243: break;
244: case 'm': /* number of bits for MACing */
245: mode = MODE_AUTHENTICATE;
246: if ((macbits = setbits(optarg, 1)) > 64)
1.4 deraadt 247: err(1, "-m: number must be 0-64 inclusive");
1.1 deraadt 248: break;
249: case 'o': /* use OFB mode */
250: alg = ALG_OFB;
251: if ((fbbits = setbits(optarg, 8)) > 64 || fbbits == 0)
1.4 deraadt 252: err(1, "-o: number must be 1-64 inclusive");
1.1 deraadt 253: else if (fbbits == -1)
1.4 deraadt 254: err(1, "-o: number must be a multiple of 8");
1.1 deraadt 255: break;
256: case 'p': /* preserve parity bits */
257: pflag = 1;
258: break;
259: case 'v': /* set initialization vector */
260: cvtkey(BUFFER(ivec), optarg);
261: break;
262: default: /* error */
263: usage();
264: }
265:
266: if (!kflag) {
267: /*
268: * if the key's not ASCII, assume it is
269: */
270: keybase = KEY_ASCII;
271: /*
272: * get the key
273: */
1.13 ! tedu 274: if ((p = getpass("Enter key: ")) == NULL)
! 275: err(1, "getpass");
1.1 deraadt 276: /*
277: * copy it, nul-padded, into the key area
278: */
279: cvtkey(BUFFER(msgbuf), p);
280: }
281:
282: makekey(msgbuf);
283: inverse = (alg == ALG_CBC || alg == ALG_ECB) && mode == MODE_DECRYPT;
284:
1.12 deraadt 285: switch (alg) {
1.1 deraadt 286: case ALG_CBC:
1.12 deraadt 287: switch (mode) {
1.1 deraadt 288: case MODE_AUTHENTICATE: /* authenticate using CBC mode */
289: cbcauth();
290: break;
291: case MODE_DECRYPT: /* decrypt using CBC mode */
292: cbcdec();
293: break;
294: case MODE_ENCRYPT: /* encrypt using CBC mode */
295: cbcenc();
296: break;
297: }
298: break;
299: case ALG_CFB:
1.12 deraadt 300: switch (mode) {
1.1 deraadt 301: case MODE_AUTHENTICATE: /* authenticate using CFB mode */
302: cfbauth();
303: break;
304: case MODE_DECRYPT: /* decrypt using CFB mode */
305: cfbdec();
306: break;
307: case MODE_ENCRYPT: /* encrypt using CFB mode */
308: cfbenc();
309: break;
310: }
311: break;
312: case ALG_CFBA:
1.12 deraadt 313: switch (mode) {
1.1 deraadt 314: case MODE_AUTHENTICATE: /* authenticate using CFBA mode */
1.4 deraadt 315: err(1, "can't authenticate with CFBA mode");
1.1 deraadt 316: break;
317: case MODE_DECRYPT: /* decrypt using CFBA mode */
318: cfbadec();
319: break;
320: case MODE_ENCRYPT: /* encrypt using CFBA mode */
321: cfbaenc();
322: break;
323: }
324: break;
325: case ALG_ECB:
1.12 deraadt 326: switch (mode) {
1.1 deraadt 327: case MODE_AUTHENTICATE: /* authenticate using ECB mode */
1.4 deraadt 328: err(1, "can't authenticate with ECB mode");
1.1 deraadt 329: break;
330: case MODE_DECRYPT: /* decrypt using ECB mode */
331: ecbdec();
332: break;
333: case MODE_ENCRYPT: /* encrypt using ECB mode */
334: ecbenc();
335: break;
336: }
337: break;
338: case ALG_OFB:
1.12 deraadt 339: switch (mode) {
1.1 deraadt 340: case MODE_AUTHENTICATE: /* authenticate using OFB mode */
1.4 deraadt 341: err(1, "can't authenticate with OFB mode");
1.1 deraadt 342: break;
343: case MODE_DECRYPT: /* decrypt using OFB mode */
344: ofbdec();
345: break;
346: case MODE_ENCRYPT: /* encrypt using OFB mode */
347: ofbenc();
348: break;
349: }
350: break;
351: }
352: exit(0);
353: }
354:
355: /*
356: * map a hex character to an integer
357: */
1.5 deraadt 358: int
1.11 deraadt 359: tobinhex(char c, int radix)
1.1 deraadt 360: {
1.12 deraadt 361: switch (c) {
1.1 deraadt 362: case '0': return(0x0);
363: case '1': return(0x1);
364: case '2': return(radix > 2 ? 0x2 : -1);
365: case '3': return(radix > 3 ? 0x3 : -1);
366: case '4': return(radix > 4 ? 0x4 : -1);
367: case '5': return(radix > 5 ? 0x5 : -1);
368: case '6': return(radix > 6 ? 0x6 : -1);
369: case '7': return(radix > 7 ? 0x7 : -1);
370: case '8': return(radix > 8 ? 0x8 : -1);
371: case '9': return(radix > 9 ? 0x9 : -1);
372: case 'A': case 'a': return(radix > 10 ? 0xa : -1);
373: case 'B': case 'b': return(radix > 11 ? 0xb : -1);
374: case 'C': case 'c': return(radix > 12 ? 0xc : -1);
375: case 'D': case 'd': return(radix > 13 ? 0xd : -1);
376: case 'E': case 'e': return(radix > 14 ? 0xe : -1);
377: case 'F': case 'f': return(radix > 15 ? 0xf : -1);
378: }
379: /*
380: * invalid character
381: */
382: return(-1);
383: }
384:
385: /*
386: * convert the key to a bit pattern
387: */
1.5 deraadt 388: void
1.11 deraadt 389: cvtkey(char *obuf, char *ibuf)
1.1 deraadt 390: {
1.6 mpech 391: int i, j; /* counter in a for loop */
1.1 deraadt 392: int nbuf[64]; /* used for hex/key translation */
393:
394: /*
395: * just switch on the key base
396: */
1.12 deraadt 397: switch (keybase) {
1.9 rohee 398: case KEY_ASCII: /* ASCII to integer */
1.1 deraadt 399: (void)strncpy(obuf, ibuf, 8);
400: return;
401: case KEY_DEFAULT: /* tell from context */
402: /*
403: * leading '0x' or '0X' == hex key
404: */
405: if (ibuf[0] == '0' && (ibuf[1] == 'x' || ibuf[1] == 'X')) {
406: ibuf = &ibuf[2];
407: /*
408: * now translate it, bombing on any illegal hex digit
409: */
410: for (i = 0; ibuf[i] && i < 16; i++)
411: if ((nbuf[i] = tobinhex(ibuf[i], 16)) == -1)
1.4 deraadt 412: err(1, "bad hex digit in key");
1.1 deraadt 413: while (i < 16)
414: nbuf[i++] = 0;
415: for (i = 0; i < 8; i++)
416: obuf[i] =
417: ((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf);
418: /* preserve parity bits */
419: pflag = 1;
420: return;
421: }
422: /*
423: * leading '0b' or '0B' == binary key
424: */
425: if (ibuf[0] == '0' && (ibuf[1] == 'b' || ibuf[1] == 'B')) {
426: ibuf = &ibuf[2];
427: /*
428: * now translate it, bombing on any illegal binary digit
429: */
430: for (i = 0; ibuf[i] && i < 16; i++)
431: if ((nbuf[i] = tobinhex(ibuf[i], 2)) == -1)
1.4 deraadt 432: err(1, "bad binary digit in key");
1.1 deraadt 433: while (i < 64)
434: nbuf[i++] = 0;
435: for (i = 0; i < 8; i++)
436: for (j = 0; j < 8; j++)
437: obuf[i] = (obuf[i]<<1)|nbuf[8*i+j];
438: /* preserve parity bits */
439: pflag = 1;
440: return;
441: }
442: /*
443: * no special leader -- ASCII
444: */
445: (void)strncpy(obuf, ibuf, 8);
446: }
447: }
448:
449: /*
450: * convert an ASCII string into a decimal number:
451: * 1. must be between 0 and 64 inclusive
452: * 2. must be a valid decimal number
453: * 3. must be a multiple of mult
454: */
1.5 deraadt 455: int
1.11 deraadt 456: setbits(char *s, int mult)
1.1 deraadt 457: {
1.6 mpech 458: char *p; /* pointer in a for loop */
459: int n = 0; /* the integer collected */
1.1 deraadt 460:
461: /*
462: * skip white space
463: */
464: while (isspace(*s))
465: s++;
466: /*
467: * get the integer
468: */
469: for (p = s; *p; p++) {
470: if (isdigit(*p))
471: n = n * 10 + *p - '0';
472: else {
1.4 deraadt 473: err(1, "bad decimal digit in MAC length");
1.1 deraadt 474: }
475: }
476: /*
477: * be sure it's a multiple of mult
478: */
479: return((n % mult != 0) ? -1 : n);
480: }
481:
482: /*****************
483: * DES FUNCTIONS *
484: *****************/
485: /*
486: * This sets the DES key and (if you're using the deszip version)
487: * the direction of the transformation. This uses the Sun
488: * to map the 64-bit key onto the 56 bits that the key schedule
489: * generation routines use: the old way, which just uses the user-
490: * supplied 64 bits as is, and the new way, which resets the parity
491: * bit to be the same as the low-order bit in each character. The
492: * new way generates a greater variety of key schedules, since many
493: * systems set the parity (high) bit of each character to 0, and the
494: * DES ignores the low order bit of each character.
495: */
1.5 deraadt 496: void
1.11 deraadt 497: makekey(Desbuf buf)
1.1 deraadt 498: {
1.6 mpech 499: int i, j; /* counter in a for loop */
500: int par; /* parity counter */
1.1 deraadt 501:
502: /*
503: * if the parity is not preserved, flip it
504: */
505: if (!pflag) {
506: for (i = 0; i < 8; i++) {
507: par = 0;
508: for (j = 1; j < 8; j++)
509: if ((bits[j]&UCHAR(buf, i)) != 0)
510: par++;
511: if ((par&01) == 01)
512: UCHAR(buf, i) = UCHAR(buf, i)&0177;
513: else
514: UCHAR(buf, i) = (UCHAR(buf, i)&0177)|0200;
515: }
516: }
517:
518: DES_KEY(UBUFFER(buf));
519: }
520:
521: /*
522: * This encrypts using the Electronic Code Book mode of DES
523: */
1.5 deraadt 524: void
1.11 deraadt 525: ecbenc(void)
1.1 deraadt 526: {
1.6 mpech 527: int n; /* number of bytes actually read */
528: int bn; /* block number */
1.1 deraadt 529: Desbuf msgbuf; /* I/O buffer */
530:
531: for (bn = 0; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
532: /*
533: * do the transformation
534: */
535: DES_XFORM(UBUFFER(msgbuf));
536: WRITE(BUFFER(msgbuf), 8);
537: }
538: /*
539: * at EOF or last block -- in either ase, the last byte contains
540: * the character representation of the number of bytes in it
541: */
542: bn++;
543: MEMZERO(&CHAR(msgbuf, n), 8 - n);
544: CHAR(msgbuf, 7) = n;
545: DES_XFORM(UBUFFER(msgbuf));
546: WRITE(BUFFER(msgbuf), 8);
547:
548: }
549:
550: /*
551: * This decrypts using the Electronic Code Book mode of DES
552: */
1.5 deraadt 553: void
1.11 deraadt 554: ecbdec(void)
1.1 deraadt 555: {
1.6 mpech 556: int n; /* number of bytes actually read */
557: int c; /* used to test for EOF */
558: int bn; /* block number */
1.1 deraadt 559: Desbuf msgbuf; /* I/O buffer */
560:
561: for (bn = 1; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
562: /*
563: * do the transformation
564: */
565: DES_XFORM(UBUFFER(msgbuf));
566: /*
567: * if the last one, handle it specially
568: */
569: if ((c = getchar()) == EOF) {
570: n = CHAR(msgbuf, 7);
571: if (n < 0 || n > 7)
1.4 deraadt 572: err(1, "decryption failed (block %d corrupted)", bn);
1.1 deraadt 573: }
574: else
575: (void)ungetc(c, stdin);
576: WRITE(BUFFER(msgbuf), n);
577: }
578: if (n > 0)
1.4 deraadt 579: err(1, "decryption failed (block %d incomplete)", bn);
1.1 deraadt 580: }
581:
582: /*
583: * This encrypts using the Cipher Block Chaining mode of DES
584: */
1.5 deraadt 585: void
1.11 deraadt 586: cbcenc(void)
1.1 deraadt 587: {
1.6 mpech 588: int n; /* number of bytes actually read */
589: int bn; /* block number */
1.1 deraadt 590: Desbuf msgbuf; /* I/O buffer */
591:
592: /*
593: * do the transformation
594: */
595: for (bn = 1; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
596: for (n = 0; n < 8; n++)
597: CHAR(msgbuf, n) ^= CHAR(ivec, n);
598: DES_XFORM(UBUFFER(msgbuf));
599: MEMCPY(BUFFER(ivec), BUFFER(msgbuf), 8);
600: WRITE(BUFFER(msgbuf), 8);
601: }
602: /*
603: * at EOF or last block -- in either case, the last byte contains
604: * the character representation of the number of bytes in it
605: */
606: bn++;
607: MEMZERO(&CHAR(msgbuf, n), 8 - n);
608: CHAR(msgbuf, 7) = n;
609: for (n = 0; n < 8; n++)
610: CHAR(msgbuf, n) ^= CHAR(ivec, n);
611: DES_XFORM(UBUFFER(msgbuf));
612: WRITE(BUFFER(msgbuf), 8);
613:
614: }
615:
616: /*
617: * This decrypts using the Cipher Block Chaining mode of DES
618: */
1.5 deraadt 619: void
1.11 deraadt 620: cbcdec(void)
1.1 deraadt 621: {
1.6 mpech 622: int n; /* number of bytes actually read */
1.1 deraadt 623: Desbuf msgbuf; /* I/O buffer */
624: Desbuf ibuf; /* temp buffer for initialization vector */
1.6 mpech 625: int c; /* used to test for EOF */
626: int bn; /* block number */
1.1 deraadt 627:
628: for (bn = 0; (n = READ(BUFFER(msgbuf), 8)) == 8; bn++) {
629: /*
630: * do the transformation
631: */
632: MEMCPY(BUFFER(ibuf), BUFFER(msgbuf), 8);
633: DES_XFORM(UBUFFER(msgbuf));
634: for (c = 0; c < 8; c++)
635: UCHAR(msgbuf, c) ^= UCHAR(ivec, c);
636: MEMCPY(BUFFER(ivec), BUFFER(ibuf), 8);
637: /*
638: * if the last one, handle it specially
639: */
640: if ((c = getchar()) == EOF) {
641: n = CHAR(msgbuf, 7);
642: if (n < 0 || n > 7)
1.4 deraadt 643: err(1, "decryption failed (block %d corrupted)", bn);
1.1 deraadt 644: }
645: else
646: (void)ungetc(c, stdin);
647: WRITE(BUFFER(msgbuf), n);
648: }
649: if (n > 0)
1.4 deraadt 650: err(1, "decryption failed (block %d incomplete)", bn);
1.1 deraadt 651: }
652:
653: /*
654: * This authenticates using the Cipher Block Chaining mode of DES
655: */
1.5 deraadt 656: void
1.11 deraadt 657: cbcauth(void)
1.1 deraadt 658: {
1.6 mpech 659: int n, j; /* number of bytes actually read */
1.1 deraadt 660: Desbuf msgbuf; /* I/O buffer */
661: Desbuf encbuf; /* encryption buffer */
662:
663: /*
664: * do the transformation
665: * note we DISCARD the encrypted block;
666: * we only care about the last one
667: */
668: while ((n = READ(BUFFER(msgbuf), 8)) == 8) {
669: for (n = 0; n < 8; n++)
670: CHAR(encbuf, n) = CHAR(msgbuf, n) ^ CHAR(ivec, n);
671: DES_XFORM(UBUFFER(encbuf));
672: MEMCPY(BUFFER(ivec), BUFFER(encbuf), 8);
673: }
674: /*
675: * now compute the last one, right padding with '\0' if need be
676: */
677: if (n > 0) {
678: MEMZERO(&CHAR(msgbuf, n), 8 - n);
679: for (n = 0; n < 8; n++)
680: CHAR(encbuf, n) = CHAR(msgbuf, n) ^ CHAR(ivec, n);
681: DES_XFORM(UBUFFER(encbuf));
682: }
683: /*
684: * drop the bits
685: * we write chars until fewer than 7 bits,
686: * and then pad the last one with 0 bits
687: */
688: for (n = 0; macbits > 7; n++, macbits -= 8)
689: (void)putchar(CHAR(encbuf, n));
690: if (macbits > 0) {
691: CHAR(msgbuf, 0) = 0x00;
692: for (j = 0; j < macbits; j++)
693: CHAR(msgbuf, 0) |= (CHAR(encbuf, n)&bits[j]);
694: (void)putchar(CHAR(msgbuf, 0));
695: }
696: }
697:
698: /*
699: * This encrypts using the Cipher FeedBack mode of DES
700: */
1.5 deraadt 701: void
1.11 deraadt 702: cfbenc(void)
1.1 deraadt 703: {
1.6 mpech 704: int n; /* number of bytes actually read */
705: int nbytes; /* number of bytes to read */
706: int bn; /* block number */
1.1 deraadt 707: char ibuf[8]; /* input buffer */
708: Desbuf msgbuf; /* encryption buffer */
709:
710: /*
711: * do things in bytes, not bits
712: */
713: nbytes = fbbits / 8;
714: /*
715: * do the transformation
716: */
717: for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
718: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
719: DES_XFORM(UBUFFER(msgbuf));
720: for (n = 0; n < 8 - nbytes; n++)
721: UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
722: for (n = 0; n < nbytes; n++)
723: UCHAR(ivec, 8-nbytes+n) = ibuf[n] ^ UCHAR(msgbuf, n);
724: WRITE(&CHAR(ivec, 8-nbytes), nbytes);
725: }
726: /*
727: * at EOF or last block -- in either case, the last byte contains
728: * the character representation of the number of bytes in it
729: */
730: bn++;
731: MEMZERO(&ibuf[n], nbytes - n);
732: ibuf[nbytes - 1] = n;
733: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
734: DES_XFORM(UBUFFER(msgbuf));
735: for (n = 0; n < nbytes; n++)
736: ibuf[n] ^= UCHAR(msgbuf, n);
737: WRITE(ibuf, nbytes);
738: }
739:
740: /*
741: * This decrypts using the Cipher Block Chaining mode of DES
742: */
1.5 deraadt 743: void
1.11 deraadt 744: cfbdec(void)
1.1 deraadt 745: {
1.6 mpech 746: int n; /* number of bytes actually read */
747: int c; /* used to test for EOF */
748: int nbytes; /* number of bytes to read */
749: int bn; /* block number */
1.1 deraadt 750: char ibuf[8]; /* input buffer */
751: char obuf[8]; /* output buffer */
752: Desbuf msgbuf; /* encryption buffer */
753:
754: /*
755: * do things in bytes, not bits
756: */
757: nbytes = fbbits / 8;
758: /*
759: * do the transformation
760: */
761: for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
762: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
763: DES_XFORM(UBUFFER(msgbuf));
764: for (c = 0; c < 8 - nbytes; c++)
765: CHAR(ivec, c) = CHAR(ivec, c+nbytes);
766: for (c = 0; c < nbytes; c++) {
767: CHAR(ivec, 8-nbytes+c) = ibuf[c];
768: obuf[c] = ibuf[c] ^ UCHAR(msgbuf, c);
769: }
770: /*
771: * if the last one, handle it specially
772: */
773: if ((c = getchar()) == EOF) {
774: n = obuf[nbytes-1];
775: if (n < 0 || n > nbytes-1)
1.4 deraadt 776: err(1, "decryption failed (block %d corrupted)", bn);
1.1 deraadt 777: }
778: else
779: (void)ungetc(c, stdin);
780: WRITE(obuf, n);
781: }
782: if (n > 0)
1.4 deraadt 783: err(1, "decryption failed (block %d incomplete)", bn);
1.1 deraadt 784: }
785:
786: /*
787: * This encrypts using the alternative Cipher FeedBack mode of DES
788: */
1.5 deraadt 789: void
1.11 deraadt 790: cfbaenc(void)
1.1 deraadt 791: {
1.6 mpech 792: int n; /* number of bytes actually read */
793: int nbytes; /* number of bytes to read */
794: int bn; /* block number */
1.1 deraadt 795: char ibuf[8]; /* input buffer */
796: char obuf[8]; /* output buffer */
797: Desbuf msgbuf; /* encryption buffer */
798:
799: /*
800: * do things in bytes, not bits
801: */
802: nbytes = fbbits / 7;
803: /*
804: * do the transformation
805: */
806: for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
807: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
808: DES_XFORM(UBUFFER(msgbuf));
809: for (n = 0; n < 8 - nbytes; n++)
810: UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
811: for (n = 0; n < nbytes; n++)
812: UCHAR(ivec, 8-nbytes+n) = (ibuf[n] ^ UCHAR(msgbuf, n))
813: |0200;
814: for (n = 0; n < nbytes; n++)
815: obuf[n] = CHAR(ivec, 8-nbytes+n)&0177;
816: WRITE(obuf, nbytes);
817: }
818: /*
819: * at EOF or last block -- in either case, the last byte contains
820: * the character representation of the number of bytes in it
821: */
822: bn++;
823: MEMZERO(&ibuf[n], nbytes - n);
824: ibuf[nbytes - 1] = ('0' + n)|0200;
825: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
826: DES_XFORM(UBUFFER(msgbuf));
827: for (n = 0; n < nbytes; n++)
828: ibuf[n] ^= UCHAR(msgbuf, n);
829: WRITE(ibuf, nbytes);
830: }
831:
832: /*
833: * This decrypts using the alternative Cipher Block Chaining mode of DES
834: */
1.5 deraadt 835: void
1.11 deraadt 836: cfbadec(void)
1.1 deraadt 837: {
1.6 mpech 838: int n; /* number of bytes actually read */
839: int c; /* used to test for EOF */
840: int nbytes; /* number of bytes to read */
841: int bn; /* block number */
1.1 deraadt 842: char ibuf[8]; /* input buffer */
843: char obuf[8]; /* output buffer */
844: Desbuf msgbuf; /* encryption buffer */
845:
846: /*
847: * do things in bytes, not bits
848: */
849: nbytes = fbbits / 7;
850: /*
851: * do the transformation
852: */
853: for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
854: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
855: DES_XFORM(UBUFFER(msgbuf));
856: for (c = 0; c < 8 - nbytes; c++)
857: CHAR(ivec, c) = CHAR(ivec, c+nbytes);
858: for (c = 0; c < nbytes; c++) {
859: CHAR(ivec, 8-nbytes+c) = ibuf[c]|0200;
860: obuf[c] = (ibuf[c] ^ UCHAR(msgbuf, c))&0177;
861: }
862: /*
863: * if the last one, handle it specially
864: */
865: if ((c = getchar()) == EOF) {
866: if ((n = (obuf[nbytes-1] - '0')) < 0
867: || n > nbytes-1)
1.4 deraadt 868: err(1, "decryption failed (block %d corrupted)", bn);
1.1 deraadt 869: }
870: else
871: (void)ungetc(c, stdin);
872: WRITE(obuf, n);
873: }
874: if (n > 0)
1.4 deraadt 875: err(1, "decryption failed (block %d incomplete)", bn);
1.1 deraadt 876: }
877:
878:
879: /*
880: * This encrypts using the Output FeedBack mode of DES
881: */
1.5 deraadt 882: void
1.11 deraadt 883: ofbenc(void)
1.1 deraadt 884: {
1.6 mpech 885: int n; /* number of bytes actually read */
886: int c; /* used to test for EOF */
887: int nbytes; /* number of bytes to read */
888: int bn; /* block number */
1.1 deraadt 889: char ibuf[8]; /* input buffer */
890: char obuf[8]; /* output buffer */
891: Desbuf msgbuf; /* encryption buffer */
892:
893: /*
894: * do things in bytes, not bits
895: */
896: nbytes = fbbits / 8;
897: /*
898: * do the transformation
899: */
900: for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
901: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
902: DES_XFORM(UBUFFER(msgbuf));
903: for (n = 0; n < 8 - nbytes; n++)
904: UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
905: for (n = 0; n < nbytes; n++) {
906: UCHAR(ivec, 8-nbytes+n) = UCHAR(msgbuf, n);
907: obuf[n] = ibuf[n] ^ UCHAR(msgbuf, n);
908: }
909: WRITE(obuf, nbytes);
910: }
911: /*
912: * at EOF or last block -- in either case, the last byte contains
913: * the character representation of the number of bytes in it
914: */
915: bn++;
916: MEMZERO(&ibuf[n], nbytes - n);
917: ibuf[nbytes - 1] = n;
918: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
919: DES_XFORM(UBUFFER(msgbuf));
920: for (c = 0; c < nbytes; c++)
921: ibuf[c] ^= UCHAR(msgbuf, c);
922: WRITE(ibuf, nbytes);
923: }
924:
925: /*
926: * This decrypts using the Output Block Chaining mode of DES
927: */
1.5 deraadt 928: void
1.11 deraadt 929: ofbdec(void)
1.1 deraadt 930: {
1.6 mpech 931: int n; /* number of bytes actually read */
932: int c; /* used to test for EOF */
933: int nbytes; /* number of bytes to read */
934: int bn; /* block number */
1.1 deraadt 935: char ibuf[8]; /* input buffer */
936: char obuf[8]; /* output buffer */
937: Desbuf msgbuf; /* encryption buffer */
938:
939: /*
940: * do things in bytes, not bits
941: */
942: nbytes = fbbits / 8;
943: /*
944: * do the transformation
945: */
946: for (bn = 1; (n = READ(ibuf, nbytes)) == nbytes; bn++) {
947: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
948: DES_XFORM(UBUFFER(msgbuf));
949: for (c = 0; c < 8 - nbytes; c++)
950: CHAR(ivec, c) = CHAR(ivec, c+nbytes);
951: for (c = 0; c < nbytes; c++) {
952: CHAR(ivec, 8-nbytes+c) = UCHAR(msgbuf, c);
953: obuf[c] = ibuf[c] ^ UCHAR(msgbuf, c);
954: }
955: /*
956: * if the last one, handle it specially
957: */
958: if ((c = getchar()) == EOF) {
959: n = obuf[nbytes-1];
960: if (n < 0 || n > nbytes-1)
1.4 deraadt 961: err(1, "decryption failed (block %d corrupted)", bn);
1.1 deraadt 962: }
963: else
964: (void)ungetc(c, stdin);
965: /*
966: * dump it
967: */
968: WRITE(obuf, n);
969: }
970: if (n > 0)
1.4 deraadt 971: err(1, "decryption failed (block %d incomplete)", bn);
1.1 deraadt 972: }
973:
974: /*
975: * This authenticates using the Cipher FeedBack mode of DES
976: */
1.5 deraadt 977: void
1.11 deraadt 978: cfbauth(void)
1.1 deraadt 979: {
1.6 mpech 980: int n, j; /* number of bytes actually read */
981: int nbytes; /* number of bytes to read */
1.1 deraadt 982: char ibuf[8]; /* input buffer */
983: Desbuf msgbuf; /* encryption buffer */
984:
985: /*
986: * do things in bytes, not bits
987: */
988: nbytes = fbbits / 8;
989: /*
990: * do the transformation
991: */
992: while ((n = READ(ibuf, nbytes)) == nbytes) {
993: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
994: DES_XFORM(UBUFFER(msgbuf));
995: for (n = 0; n < 8 - nbytes; n++)
996: UCHAR(ivec, n) = UCHAR(ivec, n+nbytes);
997: for (n = 0; n < nbytes; n++)
998: UCHAR(ivec, 8-nbytes+n) = ibuf[n] ^ UCHAR(msgbuf, n);
999: }
1000: /*
1001: * at EOF or last block -- in either case, the last byte contains
1002: * the character representation of the number of bytes in it
1003: */
1004: MEMZERO(&ibuf[n], nbytes - n);
1005: ibuf[nbytes - 1] = '0' + n;
1006: MEMCPY(BUFFER(msgbuf), BUFFER(ivec), 8);
1007: DES_XFORM(UBUFFER(msgbuf));
1008: for (n = 0; n < nbytes; n++)
1009: ibuf[n] ^= UCHAR(msgbuf, n);
1010: /*
1011: * drop the bits
1012: * we write chars until fewer than 7 bits,
1013: * and then pad the last one with 0 bits
1014: */
1015: for (n = 0; macbits > 7; n++, macbits -= 8)
1016: (void)putchar(CHAR(msgbuf, n));
1017: if (macbits > 0) {
1018: CHAR(msgbuf, 0) = 0x00;
1019: for (j = 0; j < macbits; j++)
1020: CHAR(msgbuf, 0) |= (CHAR(msgbuf, n)&bits[j]);
1021: (void)putchar(CHAR(msgbuf, 0));
1022: }
1023: }
1024:
1025: #ifndef FASTWAY
1026: /*
1027: * change from 8 bits/Uchar to 1 bit/Uchar
1028: */
1029: expand(from, to)
1030: Desbuf from; /* 8bit/unsigned char string */
1031: char *to; /* 1bit/char string */
1032: {
1.6 mpech 1033: int i, j; /* counters in for loop */
1.1 deraadt 1034:
1035: for (i = 0; i < 8; i++)
1036: for (j = 0; j < 8; j++)
1037: *to++ = (CHAR(from, i)>>(7-j))&01;
1038: }
1039:
1040: /*
1041: * change from 1 bit/char to 8 bits/Uchar
1042: */
1043: compress(from, to)
1044: char *from; /* 1bit/char string */
1045: Desbuf to; /* 8bit/unsigned char string */
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:
1057: /*
1058: * message about usage
1059: */
1.5 deraadt 1060: void
1.11 deraadt 1061: usage(void)
1.1 deraadt 1062: {
1063: (void)fprintf(stderr, "%s\n",
1064: "usage: bdes [-abdp] [-F bit] [-f bit] [-k key] [-m bit] [-o bit] [-v vector]");
1065: exit(1);
1066: }