1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 /*
30 * DES encrypt/decrypt command
31 * Features:
32 * Hardware or software implementation
33 * Cipher Block Chaining (default) or Electronic Code Book (-b) modes
34 * A word about the key:
35 * The DES standard specifies that the low bit of each of the 8 bytes
36 * of the key is used for odd parity. We prompt the user for an 8
37 * byte ASCII key and add parity to the high bit and use the result
38 * as the key. The nature of parity is that given any 7 bits you can
39 * figure out what the missing bit should be, so it doesn't matter which
40 * bit is used for parity; the information (in the theoretical sense) is
41 * the same.
42 */
43 #include <stdio.h>
44 #include <string.h>
45 #include <rpc/des_crypt.h>
46
47 #define DES_CBC 0
48 #define DES_ECB 1
49
50
51 int ifd=0, ofd=1; /* input and output descriptors */
52 char *cmdname; /* our command name */
53
54
55 struct des_info {
56 char *key; /* encryption key */
57 char *ivec; /* initialization vector: CBC mode only */
58 unsigned flags; /* direction, device flags */
59 unsigned mode; /* des mode: ecb or cbc */
60 } g_des;
61
62
63 void des_setup(char *key, unsigned int mode, unsigned int flags);
64 void fencrypt(void);
65 void fdecrypt(void);
66 void usage(void);
67 static void putparity(char *p);
68 int
main(int argc,char ** argv)69 main(int argc, char **argv)
70 {
71 char *key = NULL, keybuf[8], *getpass();
72 unsigned mode = DES_CBC;
73 unsigned flags = DES_HW;
74 int dirset = 0; /* set if dir set */
75 int fflg = 0; /* suppress warning if H/W DES not available */
76 unsigned err;
77
78 cmdname = *argv++;
79 argc--;
80 while (argc > 0 && argv[0][0] == '-') {
81 switch (argv[0][1]) {
82 case 'e': /* encrypt */
83 flags |= DES_ENCRYPT; dirset++;
84 break;
85 case 'd': /* decrypt */
86 flags |= DES_DECRYPT; dirset++;
87 break;
88 case 'b': /* use Book mode */
89 mode = DES_ECB;
90 break;
91 case 'f': /* force silent */
92 fflg++;
93 break;
94 case 's': /* use software DES */
95 flags |= DES_SW;
96 break;
97 case 'k': /* key */
98 if (--argc == 0)
99 usage();
100 strncpy(keybuf, *++argv, 8);
101 for (key = *argv; *key; )
102 *key++ = '\0';
103 key = keybuf;
104 break;
105 default:
106 usage();
107 }
108 argv++;
109 argc--;
110 }
111 if (!dirset)
112 usage();
113 if (argc > 0) {
114 ifd = open(*argv, 0);
115 if (ifd < 0) {
116 perror(*argv);
117 exit(1);
118 }
119 argv++;
120 argc--;
121 }
122 if (argc > 0) {
123 ofd = creat(*argv, 0666);
124 if (ofd < 0) {
125 perror(*argv);
126 exit(1);
127 }
128 argv++;
129 argc--;
130 }
131 if (argc)
132 usage();
133 if (key == NULL) {
134 if ((key = getpass("Enter key: ")) == NULL) {
135 fprintf(stderr, "%s: unable to get key\n", cmdname);
136 exit(1);
137 }
138 strncpy(keybuf, key, 8);
139 }
140 if ((flags & DES_DEVMASK) == DES_HW && no_hwdevice()) {
141 flags &= ~DES_DEVMASK; /* clear device bit */
142 flags |= DES_SW; /* set device to software */
143 if (!fflg) {
144 fprintf(stderr, "%s: WARNING: using software DES algorithm\n",
145 cmdname);
146 }
147 }
148 if ((flags & DES_DEVMASK) == DES_SW && no_swdevice()) {
149 fprintf(stderr, "%s: no software encryption available\n",
150 cmdname);
151 exit(1);
152 }
153 des_setup(key, mode, flags);
154 switch (flags & DES_DIRMASK) {
155 case DES_ENCRYPT:
156 fencrypt();
157 break;
158 case DES_DECRYPT:
159 fdecrypt();
160 break;
161 }
162 return (0);
163 }
164
165
166
167 int
no_hwdevice(void)168 no_hwdevice(void)
169 {
170 char key[8];
171 char buf[8];
172
173 return (ecb_crypt(key,buf,8,DES_ENCRYPT | DES_HW) != 0);
174 }
175
176
177 int
no_swdevice(void)178 no_swdevice(void)
179 {
180 char key[8];
181 char buf[8];
182 int res;
183
184 return (ecb_crypt(key,buf,8,DES_ENCRYPT | DES_SW) != 0);
185 }
186
187
188
189
190 void
des_setup(char * key,unsigned int mode,unsigned int flags)191 des_setup(char *key, unsigned int mode, unsigned int flags)
192 {
193 static char ivec[8];
194
195 g_des.flags = flags;
196 g_des.mode = mode;
197 putparity(key);
198 g_des.key = key;
199
200 memset(ivec, 0, 8);
201 g_des.ivec = ivec;
202 }
203
204
205 void
crypt(char * buf,unsigned int len)206 crypt(char *buf, unsigned int len)
207 {
208
209 if (g_des.mode == DES_ECB) {
210 ecb_crypt(g_des.key, buf, len, g_des.flags);
211 } else {
212 cbc_crypt(g_des.key, buf, len, g_des.flags, g_des.ivec);
213 }
214 }
215
216
217 char buf[DES_MAXDATA];
218
219 /*
220 * Encrypt a file:
221 * Takes an arbitrary number of bytes of input and
222 * produces an encrypted output file which is always the
223 * the next multiple of 8 bytes bigger (e.g., 64 -> 72, 71 -> 72)
224 * The last byte, when decrypted, gives the number of actual data bytes
225 * in the last 8 bytes. Other bytes are filled with random values to
226 * make it hard to cryptanalize.
227 */
228 void
fencrypt(void)229 fencrypt(void)
230 {
231 int n, k, j;
232 char *cp;
233
234 while ((n = read(ifd, buf, sizeof buf)) > 0) {
235 j = n;
236 while (n & 7) {
237 k = 8 - (n & 7);
238 if ((j = read(ifd, buf+n, k)) <= 0)
239 break;
240 n += j;
241 }
242 k = n &~ 7;
243 if (k == 0)
244 break;
245 crypt(buf, k);
246 if (write(ofd, buf, k) != k)
247 perror("write");
248 if (j <= 0)
249 break;
250 }
251 if (n >= 0) {
252 cp = &buf[n];
253 k = 7 - (n & 7);
254 srand(getpid());
255 for (j = 0; j < k; j++)
256 *cp++ = rand();
257 *cp++ = n & 7;
258 cp -= 8;
259
260 crypt(cp, 8);
261 if (write(ofd, cp, 8) != 8)
262 perror("write");
263 } else
264 perror("read");
265 }
266
267
268
269
270 /*
271 * Decrypt a file:
272 * Look at the last byte of the last 8 byte block decrypted
273 * to determine how many of the last 8 bytes to save.
274 * This also serves as a check to see if the decryption succeeded
275 * with a probability of (256-8)/256.
276 */
277 void
fdecrypt(void)278 fdecrypt(void)
279 {
280 char last8buf[8], *last8;
281 int n, k, j;
282
283 last8 = NULL;
284 while ((n = read(ifd, buf, sizeof buf)) > 0) {
285 j = n;
286 while (n & 7) {
287 k = 8 - (n & 7);
288 if ((j = read(ifd, buf+n, k)) <= 0)
289 break;
290 n += j;
291 }
292 if (j <= 0)
293 break;
294 crypt(buf, n);
295 if (last8)
296 write(ofd, last8, 8);
297 last8 = last8buf;
298 n -= 8;
299 memcpy(last8, buf+n, 8);
300 if (n && write(ofd, buf, n) != n)
301 perror("write");
302 }
303 if (n >= 0) {
304 if (last8 == NULL
305 || n != 0
306 || ((signed char)last8[7]) < 0
307 || last8[7] > 7)
308 fprintf(stderr, "%s: decryption failed\n", cmdname);
309 else if (((signed char)last8[7]) > 0)
310 write(ofd, last8, last8[7]);
311 } else
312 perror("read");
313 }
314
315
316 void
usage(void)317 usage(void)
318 {
319 fprintf(stderr,
320 "Usage: %s -e [-b] [-f] [-k key] [ infile [ outfile ] ]\n",
321 cmdname);
322 fprintf(stderr,
323 " or: %s -d [-b] [-f] [-k key] [ infile [ outfile ] ]\n",
324 cmdname);
325 fprintf(stderr, "Use -e to encrypt, -d to decrypt\n");
326 exit(2);
327 }
328
329
330
331
332 /*
333 * Table giving odd parity (in high bit) for ASCII characters
334 * program does not use des_setparity() (which puts parity
335 * in low bit) in order to maintain backward compatibility
336 */
337 static unsigned char partab[128] = {
338 0x80, 0x01, 0x02, 0x83, 0x04, 0x85, 0x86, 0x07,
339 0x08, 0x89, 0x8a, 0x0b, 0x8c, 0x0d, 0x0e, 0x8f,
340 0x10, 0x91, 0x92, 0x13, 0x94, 0x15, 0x16, 0x97,
341 0x98, 0x19, 0x1a, 0x9b, 0x1c, 0x9d, 0x9e, 0x1f,
342 0x20, 0xa1, 0xa2, 0x23, 0xa4, 0x25, 0x26, 0xa7,
343 0xa8, 0x29, 0x2a, 0xab, 0x2c, 0xad, 0xae, 0x2f,
344 0xb0, 0x31, 0x32, 0xb3, 0x34, 0xb5, 0xb6, 0x37,
345 0x38, 0xb9, 0xba, 0x3b, 0xbc, 0x3d, 0x3e, 0xbf,
346 0x40, 0xc1, 0xc2, 0x43, 0xc4, 0x45, 0x46, 0xc7,
347 0xc8, 0x49, 0x4a, 0xcb, 0x4c, 0xcd, 0xce, 0x4f,
348 0xd0, 0x51, 0x52, 0xd3, 0x54, 0xd5, 0xd6, 0x57,
349 0x58, 0xd9, 0xda, 0x5b, 0xdc, 0x5d, 0x5e, 0xdf,
350 0xe0, 0x61, 0x62, 0xe3, 0x64, 0xe5, 0xe6, 0x67,
351 0x68, 0xe9, 0xea, 0x6b, 0xec, 0x6d, 0x6e, 0xef,
352 0x70, 0xf1, 0xf2, 0x73, 0xf4, 0x75, 0x76, 0xf7,
353 0xf8, 0x79, 0x7a, 0xfb, 0x7c, 0xfd, 0xfe, 0x7f,
354 };
355
356
357
358 /*
359 * Add odd parity to high bit of 8 byte key
360 */
361 static void
putparity(char * p)362 putparity(char *p)
363 {
364 int i;
365
366 for (i = 0; i < 8; i++) {
367 *p = partab[*p & 0x7f];
368 p++;
369 }
370 }
371