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