cbc.c (17) | cbc.c (1057) |
---|---|
1/* cbc.c: This file contains the encryption routines for the ed line editor */ 2/*- | 1/* cbc.c: This file contains the encryption routines for the ed line editor */ 2/*- |
3 * Copyright (c) 1991 The Regents of the University of California. | 3 * Copyright (c) 1993 The Regents of the University of California. |
4 * All rights reserved. 5 * | 4 * All rights reserved. 5 * |
6 * This code is derived from software contributed to Berkeley by 7 * Matt Bishop of Dartmouth College. | 6 * Copyright (c) 1993 Andrew Moore, Talke Studio. 7 * All rights reserved. |
8 * | 8 * |
9 * The United States Government has rights in this work pursuant 10 * to contract no. NAG 2-680 between the National Aeronautics and 11 * Space Administration and Dartmouth College. 12 * | |
13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. --- 11 unchanged lines hidden (view full) --- 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. | 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. --- 11 unchanged lines hidden (view full) --- 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. |
36 * 37 * from: @(#)bdes.c 5.5 (Berkeley) 6/27/91 |
|
40 */ 41 42#ifndef lint | 38 */ 39 40#ifndef lint |
43static char sccsid[] = "@(#)cbc.c 5.5 (Berkeley) 6/27/91"; | 41static char *rcsid = "@(#)$Id: cbc.c,v 1.3 1993/12/14 18:01:10 alm Exp $"; |
44#endif /* not lint */ 45 | 42#endif /* not lint */ 43 |
46/* Author: Matt Bishop 47 * Department of Mathematics and Computer Science 48 * Dartmouth College 49 * Hanover, NH 03755 50 * Email: Matt.Bishop@dartmouth.edu 51 * ...!decvax!dartvax!Matt.Bishop 52 * 53 * See Technical Report PCS-TR91-158, Department of Mathematics and Computer 54 * Science, Dartmouth College, for a detailed description of the implemen- 55 * tation and differences between it and Sun's. The DES is described in 56 * FIPS PUB 46, and the modes in FIPS PUB 81 (see either the manual page 57 * or the technical report for a complete reference). 58 */ 59 | 44#include <sys/types.h> 45#include <ctype.h> |
60#include <errno.h> 61#include <pwd.h> | 46#include <errno.h> 47#include <pwd.h> |
62#include <unistd.h> 63#include <stdio.h> 64#include <ctype.h> 65#include <stdlib.h> 66#include <string.h> 67#include <sys/types.h> | |
68 69#include "ed.h" 70 | 48 49#include "ed.h" 50 |
51 |
|
71/* 72 * Define a divisor for rand() that yields a uniform distribution in the 73 * range 0-255. 74 */ 75#define RAND_DIV (((unsigned) RAND_MAX + 1) >> 8) 76 77/* 78 * BSD and System V systems offer special library calls that do | 52/* 53 * Define a divisor for rand() that yields a uniform distribution in the 54 * range 0-255. 55 */ 56#define RAND_DIV (((unsigned) RAND_MAX + 1) >> 8) 57 58/* 59 * BSD and System V systems offer special library calls that do |
79 * block moves and fills, so if possible we take advantage of them | 60 * block move_liness and fills, so if possible we take advantage of them |
80 */ 81#define MEMCPY(dest,src,len) memcpy((dest),(src),(len)) 82#define MEMZERO(dest,len) memset((dest), 0, (len)) 83 84/* Hide the calls to the primitive encryption routines. */ 85#define DES_KEY(buf) \ 86 if (des_setkey(buf)) \ | 61 */ 62#define MEMCPY(dest,src,len) memcpy((dest),(src),(len)) 63#define MEMZERO(dest,len) memset((dest), 0, (len)) 64 65/* Hide the calls to the primitive encryption routines. */ 66#define DES_KEY(buf) \ 67 if (des_setkey(buf)) \ |
87 err("des_setkey"); | 68 des_error("des_setkey"); |
88#define DES_XFORM(buf) \ 89 if (des_cipher(buf, buf, 0L, (inverse ? -1 : 1))) \ | 69#define DES_XFORM(buf) \ 70 if (des_cipher(buf, buf, 0L, (inverse ? -1 : 1))) \ |
90 err("des_cipher"); | 71 des_error("des_cipher"); |
91 92/* 93 * read/write - no error checking 94 */ 95#define READ(buf, n, fp) fread(buf, sizeof(char), n, fp) 96#define WRITE(buf, n, fp) fwrite(buf, sizeof(char), n, fp) 97 98/* --- 15 unchanged lines hidden (view full) --- 114 115Desbuf ivec; /* initialization vector */ 116Desbuf pvec; /* padding vector */ 117char bits[] = { /* used to extract bits from a char */ 118 '\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001' 119}; 120int pflag; /* 1 to preserve parity bits */ 121 | 72 73/* 74 * read/write - no error checking 75 */ 76#define READ(buf, n, fp) fread(buf, sizeof(char), n, fp) 77#define WRITE(buf, n, fp) fwrite(buf, sizeof(char), n, fp) 78 79/* --- 15 unchanged lines hidden (view full) --- 95 96Desbuf ivec; /* initialization vector */ 97Desbuf pvec; /* padding vector */ 98char bits[] = { /* used to extract bits from a char */ 99 '\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001' 100}; 101int pflag; /* 1 to preserve parity bits */ 102 |
122char des_buf[8]; /* shared buffer for desgetc/desputc */ 123int des_ct = 0; /* count for desgetc/desputc */ 124int des_n = 0; /* index for desputc/desgetc */ | 103unsigned char des_buf[8]; /* shared buffer for get_des_char/put_des_char */ 104int des_ct = 0; /* count for get_des_char/put_des_char */ 105int des_n = 0; /* index for put_des_char/get_des_char */ |
125 126 | 106 107 |
127/* desinit: initialize DES */ | 108/* init_des_cipher: initialize DES */ |
128void | 109void |
129desinit() | 110init_des_cipher() |
130{ 131#ifdef DES 132 int i; 133 134 des_ct = des_n = 0; 135 136 /* initialize the initialization vctor */ 137 MEMZERO(ivec, 8); 138 139 /* intialize the padding vector */ 140 srand((unsigned) time((time_t *) 0)); 141 for (i = 0; i < 8; i++) 142 CHAR(pvec, i) = (char) (rand()/RAND_DIV); 143#endif 144} 145 146 | 111{ 112#ifdef DES 113 int i; 114 115 des_ct = des_n = 0; 116 117 /* initialize the initialization vctor */ 118 MEMZERO(ivec, 8); 119 120 /* intialize the padding vector */ 121 srand((unsigned) time((time_t *) 0)); 122 for (i = 0; i < 8; i++) 123 CHAR(pvec, i) = (char) (rand()/RAND_DIV); 124#endif 125} 126 127 |
147/* desgetc: return next char in an encrypted file */ 148desgetc(fp) | 128/* get_des_char: return next char in an encrypted file */ 129int 130get_des_char(fp) |
149 FILE *fp; 150{ 151#ifdef DES 152 if (des_n >= des_ct) { 153 des_n = 0; | 131 FILE *fp; 132{ 133#ifdef DES 134 if (des_n >= des_ct) { 135 des_n = 0; |
154 des_ct = cbcdec(des_buf, fp); | 136 des_ct = cbc_decode(des_buf, fp); |
155 } 156 return (des_ct > 0) ? des_buf[des_n++] : EOF; 157#endif 158} 159 160 | 137 } 138 return (des_ct > 0) ? des_buf[des_n++] : EOF; 139#endif 140} 141 142 |
161/* desputc: write a char to an encrypted file; return char written */ 162desputc(c, fp) | 143/* put_des_char: write a char to an encrypted file; return char written */ 144int 145put_des_char(c, fp) |
163 int c; 164 FILE *fp; 165{ 166#ifdef DES 167 if (des_n == sizeof des_buf) { | 146 int c; 147 FILE *fp; 148{ 149#ifdef DES 150 if (des_n == sizeof des_buf) { |
168 des_ct = cbcenc(des_buf, des_n, fp); | 151 des_ct = cbc_encode(des_buf, des_n, fp); |
169 des_n = 0; 170 } 171 return (des_ct >= 0) ? (des_buf[des_n++] = c) : EOF; 172#endif 173} 174 175 | 152 des_n = 0; 153 } 154 return (des_ct >= 0) ? (des_buf[des_n++] = c) : EOF; 155#endif 156} 157 158 |
176/* desflush: flush an encrypted file's output; return status */ 177desflush(fp) | 159/* flush_des_file: flush an encrypted file's output; return status */ 160int 161flush_des_file(fp) |
178 FILE *fp; 179{ 180#ifdef DES 181 if (des_n == sizeof des_buf) { | 162 FILE *fp; 163{ 164#ifdef DES 165 if (des_n == sizeof des_buf) { |
182 des_ct = cbcenc(des_buf, des_n, fp); | 166 des_ct = cbc_encode(des_buf, des_n, fp); |
183 des_n = 0; 184 } | 167 des_n = 0; 168 } |
185 return (des_ct >= 0 && cbcenc(des_buf, des_n, fp) >= 0) ? 0 : EOF; | 169 return (des_ct >= 0 && cbc_encode(des_buf, des_n, fp) >= 0) ? 0 : EOF; |
186#endif 187} 188 189#ifdef DES 190/* 191 * get keyword from tty or stdin 192 */ | 170#endif 171} 172 173#ifdef DES 174/* 175 * get keyword from tty or stdin 176 */ |
193getkey() | 177int 178get_keyword() |
194{ 195 register char *p; /* used to obtain the key */ 196 Desbuf msgbuf; /* I/O buffer */ 197 198 /* 199 * get the key 200 */ 201 if (*(p = getpass("Enter key: "))) { 202 203 /* 204 * copy it, nul-padded, into the key area 205 */ | 179{ 180 register char *p; /* used to obtain the key */ 181 Desbuf msgbuf; /* I/O buffer */ 182 183 /* 184 * get the key 185 */ 186 if (*(p = getpass("Enter key: "))) { 187 188 /* 189 * copy it, nul-padded, into the key area 190 */ |
206 cvtkey(BUFFER(msgbuf), p); | 191 expand_des_key(BUFFER(msgbuf), p); |
207 MEMZERO(p, _PASSWORD_LEN); | 192 MEMZERO(p, _PASSWORD_LEN); |
208 makekey(msgbuf); | 193 set_des_key(msgbuf); |
209 MEMZERO(msgbuf, sizeof msgbuf); 210 return 1; 211 } 212 return 0; 213} 214 215 | 194 MEMZERO(msgbuf, sizeof msgbuf); 195 return 1; 196 } 197 return 0; 198} 199 200 |
216extern char errmsg[]; 217 | |
218/* 219 * print a warning message and, possibly, terminate 220 */ 221void | 201/* 202 * print a warning message and, possibly, terminate 203 */ 204void |
222err(s) | 205des_error(s) |
223 char *s; /* the message */ 224{ 225 (void)sprintf(errmsg, "%s", s ? s : strerror(errno)); 226} 227 228/* 229 * map a hex character to an integer 230 */ | 206 char *s; /* the message */ 207{ 208 (void)sprintf(errmsg, "%s", s ? s : strerror(errno)); 209} 210 211/* 212 * map a hex character to an integer 213 */ |
231tobinhex(c, radix) | 214int 215hex_to_binary(c, radix) |
232 int c; /* char to be converted */ 233 int radix; /* base (2 to 16) */ 234{ 235 switch(c) { 236 case '0': return(0x0); 237 case '1': return(0x1); 238 case '2': return(radix > 2 ? 0x2 : -1); 239 case '3': return(radix > 3 ? 0x3 : -1); --- 15 unchanged lines hidden (view full) --- 255 */ 256 return(-1); 257} 258 259/* 260 * convert the key to a bit pattern 261 */ 262void | 216 int c; /* char to be converted */ 217 int radix; /* base (2 to 16) */ 218{ 219 switch(c) { 220 case '0': return(0x0); 221 case '1': return(0x1); 222 case '2': return(radix > 2 ? 0x2 : -1); 223 case '3': return(radix > 3 ? 0x3 : -1); --- 15 unchanged lines hidden (view full) --- 239 */ 240 return(-1); 241} 242 243/* 244 * convert the key to a bit pattern 245 */ 246void |
263cvtkey(obuf, ibuf) | 247expand_des_key(obuf, ibuf) |
264 char *obuf; /* bit pattern */ 265 char *ibuf; /* the key itself */ 266{ 267 register int i, j; /* counter in a for loop */ 268 int nbuf[64]; /* used for hex/key translation */ 269 270 /* 271 * leading '0x' or '0X' == hex key 272 */ 273 if (ibuf[0] == '0' && (ibuf[1] == 'x' || ibuf[1] == 'X')) { 274 ibuf = &ibuf[2]; 275 /* 276 * now translate it, bombing on any illegal hex digit 277 */ 278 for (i = 0; ibuf[i] && i < 16; i++) | 248 char *obuf; /* bit pattern */ 249 char *ibuf; /* the key itself */ 250{ 251 register int i, j; /* counter in a for loop */ 252 int nbuf[64]; /* used for hex/key translation */ 253 254 /* 255 * leading '0x' or '0X' == hex key 256 */ 257 if (ibuf[0] == '0' && (ibuf[1] == 'x' || ibuf[1] == 'X')) { 258 ibuf = &ibuf[2]; 259 /* 260 * now translate it, bombing on any illegal hex digit 261 */ 262 for (i = 0; ibuf[i] && i < 16; i++) |
279 if ((nbuf[i] = tobinhex((int) ibuf[i], 16)) == -1) 280 err("bad hex digit in key"); | 263 if ((nbuf[i] = hex_to_binary((int) ibuf[i], 16)) == -1) 264 des_error("bad hex digit in key"); |
281 while (i < 16) 282 nbuf[i++] = 0; 283 for (i = 0; i < 8; i++) 284 obuf[i] = 285 ((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf); 286 /* preserve parity bits */ 287 pflag = 1; 288 return; 289 } 290 /* 291 * leading '0b' or '0B' == binary key 292 */ 293 if (ibuf[0] == '0' && (ibuf[1] == 'b' || ibuf[1] == 'B')) { 294 ibuf = &ibuf[2]; 295 /* 296 * now translate it, bombing on any illegal binary digit 297 */ 298 for (i = 0; ibuf[i] && i < 16; i++) | 265 while (i < 16) 266 nbuf[i++] = 0; 267 for (i = 0; i < 8; i++) 268 obuf[i] = 269 ((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf); 270 /* preserve parity bits */ 271 pflag = 1; 272 return; 273 } 274 /* 275 * leading '0b' or '0B' == binary key 276 */ 277 if (ibuf[0] == '0' && (ibuf[1] == 'b' || ibuf[1] == 'B')) { 278 ibuf = &ibuf[2]; 279 /* 280 * now translate it, bombing on any illegal binary digit 281 */ 282 for (i = 0; ibuf[i] && i < 16; i++) |
299 if ((nbuf[i] = tobinhex((int) ibuf[i], 2)) == -1) 300 err("bad binary digit in key"); | 283 if ((nbuf[i] = hex_to_binary((int) ibuf[i], 2)) == -1) 284 des_error("bad binary digit in key"); |
301 while (i < 64) 302 nbuf[i++] = 0; 303 for (i = 0; i < 8; i++) 304 for (j = 0; j < 8; j++) 305 obuf[i] = (obuf[i]<<1)|nbuf[8*i+j]; 306 /* preserve parity bits */ 307 pflag = 1; 308 return; --- 14 unchanged lines hidden (view full) --- 323 * generation routines use: the old way, which just uses the user- 324 * supplied 64 bits as is, and the new way, which resets the parity 325 * bit to be the same as the low-order bit in each character. The 326 * new way generates a greater variety of key schedules, since many 327 * systems set the parity (high) bit of each character to 0, and the 328 * DES ignores the low order bit of each character. 329 */ 330void | 285 while (i < 64) 286 nbuf[i++] = 0; 287 for (i = 0; i < 8; i++) 288 for (j = 0; j < 8; j++) 289 obuf[i] = (obuf[i]<<1)|nbuf[8*i+j]; 290 /* preserve parity bits */ 291 pflag = 1; 292 return; --- 14 unchanged lines hidden (view full) --- 307 * generation routines use: the old way, which just uses the user- 308 * supplied 64 bits as is, and the new way, which resets the parity 309 * bit to be the same as the low-order bit in each character. The 310 * new way generates a greater variety of key schedules, since many 311 * systems set the parity (high) bit of each character to 0, and the 312 * DES ignores the low order bit of each character. 313 */ 314void |
331makekey(buf) | 315set_des_key(buf) |
332 Desbuf buf; /* key block */ 333{ 334 register int i, j; /* counter in a for loop */ 335 register int par; /* parity counter */ 336 337 /* 338 * if the parity is not preserved, flip it 339 */ --- 12 unchanged lines hidden (view full) --- 352 353 DES_KEY(UBUFFER(buf)); 354} 355 356 357/* 358 * This encrypts using the Cipher Block Chaining mode of DES 359 */ | 316 Desbuf buf; /* key block */ 317{ 318 register int i, j; /* counter in a for loop */ 319 register int par; /* parity counter */ 320 321 /* 322 * if the parity is not preserved, flip it 323 */ --- 12 unchanged lines hidden (view full) --- 336 337 DES_KEY(UBUFFER(buf)); 338} 339 340 341/* 342 * This encrypts using the Cipher Block Chaining mode of DES 343 */ |
360cbcenc(msgbuf, n, fp) | 344int 345cbc_encode(msgbuf, n, fp) |
361 char *msgbuf; 362 int n; 363 FILE *fp; 364{ 365 int inverse = 0; /* 0 to encrypt, 1 to decrypt */ 366 367 /* 368 * do the transformation --- 21 unchanged lines hidden (view full) --- 390 CHAR(msgbuf, n) ^= CHAR(ivec, n); 391 DES_XFORM(UBUFFER(msgbuf)); 392 return WRITE(BUFFER(msgbuf), 8, fp); 393} 394 395/* 396 * This decrypts using the Cipher Block Chaining mode of DES 397 */ | 346 char *msgbuf; 347 int n; 348 FILE *fp; 349{ 350 int inverse = 0; /* 0 to encrypt, 1 to decrypt */ 351 352 /* 353 * do the transformation --- 21 unchanged lines hidden (view full) --- 375 CHAR(msgbuf, n) ^= CHAR(ivec, n); 376 DES_XFORM(UBUFFER(msgbuf)); 377 return WRITE(BUFFER(msgbuf), 8, fp); 378} 379 380/* 381 * This decrypts using the Cipher Block Chaining mode of DES 382 */ |
398cbcdec(msgbuf, fp) | 383int 384cbc_decode(msgbuf, fp) |
399 char *msgbuf; /* I/O buffer */ 400 FILE *fp; /* input file descriptor */ 401{ 402 Desbuf ibuf; /* temp buffer for initialization vector */ 403 register int n; /* number of bytes actually read */ 404 register int c; /* used to test for EOF */ 405 int inverse = 1; /* 0 to encrypt, 1 to decrypt */ 406 --- 7 unchanged lines hidden (view full) --- 414 UCHAR(msgbuf, c) ^= UCHAR(ivec, c); 415 MEMCPY(BUFFER(ivec), BUFFER(ibuf), 8); 416 /* 417 * if the last one, handle it specially 418 */ 419 if ((c = fgetc(fp)) == EOF) { 420 n = CHAR(msgbuf, 7); 421 if (n < 0 || n > 7) { | 385 char *msgbuf; /* I/O buffer */ 386 FILE *fp; /* input file descriptor */ 387{ 388 Desbuf ibuf; /* temp buffer for initialization vector */ 389 register int n; /* number of bytes actually read */ 390 register int c; /* used to test for EOF */ 391 int inverse = 1; /* 0 to encrypt, 1 to decrypt */ 392 --- 7 unchanged lines hidden (view full) --- 400 UCHAR(msgbuf, c) ^= UCHAR(ivec, c); 401 MEMCPY(BUFFER(ivec), BUFFER(ibuf), 8); 402 /* 403 * if the last one, handle it specially 404 */ 405 if ((c = fgetc(fp)) == EOF) { 406 n = CHAR(msgbuf, 7); 407 if (n < 0 || n > 7) { |
422 err("decryption failed (block corrupted)"); | 408 des_error("decryption failed (block corrupted)"); |
423 return EOF; 424 } 425 } else 426 (void)ungetc(c, fp); 427 return n; 428 } 429 if (n > 0) | 409 return EOF; 410 } 411 } else 412 (void)ungetc(c, fp); 413 return n; 414 } 415 if (n > 0) |
430 err("decryption failed (incomplete block)"); | 416 des_error("decryption failed (incomplete block)"); |
431 else if (n < 0) | 417 else if (n < 0) |
432 err("cannot read file"); | 418 des_error("cannot read file"); |
433 return EOF; 434} 435#endif /* DES */ | 419 return EOF; 420} 421#endif /* DES */ |