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