1 /*- 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)des_rw.c 5.8 (Berkeley) 02/25/91"; 10 #endif /* not lint */ 11 12 #ifdef CRYPT 13 #ifdef KERBEROS 14 #include <sys/param.h> 15 #include <kerberosIV/des.h> 16 #include <kerberosIV/krb.h> 17 #include <time.h> 18 #include <unistd.h> 19 #include <stdlib.h> 20 #include <string.h> 21 22 extern long random(); 23 static unsigned char des_inbuf[10240], storage[10240], *store_ptr; 24 static bit_64 *key; 25 static u_char *key_schedule; 26 27 /* 28 * NB: These routines will not function properly if NBIO 29 * is set 30 */ 31 32 /* 33 * des_set_key 34 * 35 * Set des encryption/decryption key for use by the des_read and 36 * des_write routines 37 * 38 * The inkey parameter is actually the DES initial vector, 39 * and the insched is the DES Key unwrapped for faster decryption 40 */ 41 42 void 43 des_set_key(inkey, insched) 44 bit_64 *inkey; 45 u_char *insched; 46 { 47 key = inkey; 48 key_schedule = insched; 49 } 50 51 void 52 des_clear_key() 53 { 54 bzero((char *) key, sizeof(C_Block)); 55 bzero((char *) key_schedule, sizeof(Key_schedule)); 56 } 57 58 59 int 60 des_read(fd, buf, len) 61 int fd; 62 register char *buf; 63 int len; 64 { 65 int nreturned = 0; 66 long net_len, rd_len; 67 int nstored = 0; 68 69 if (nstored >= len) { 70 (void) bcopy(store_ptr, buf, len); 71 store_ptr += len; 72 nstored -= len; 73 return(len); 74 } else if (nstored) { 75 (void) bcopy(store_ptr, buf, nstored); 76 nreturned += nstored; 77 buf += nstored; 78 len -= nstored; 79 nstored = 0; 80 } 81 82 if (krb_net_read(fd, &net_len, sizeof(net_len)) != sizeof(net_len)) { 83 /* XXX can't read enough, pipe 84 must have closed */ 85 return(0); 86 } 87 net_len = ntohl(net_len); 88 if (net_len <= 0 || net_len > sizeof(des_inbuf)) { 89 /* preposterous length; assume out-of-sync; only 90 recourse is to close connection, so return 0 */ 91 return(0); 92 } 93 /* the writer tells us how much real data we are getting, but 94 we need to read the pad bytes (8-byte boundary) */ 95 rd_len = roundup(net_len, 8); 96 if (krb_net_read(fd, des_inbuf, rd_len) != rd_len) { 97 /* pipe must have closed, return 0 */ 98 return(0); 99 } 100 (void) des_pcbc_encrypt(des_inbuf, /* inbuf */ 101 storage, /* outbuf */ 102 net_len, /* length */ 103 key_schedule, /* DES key */ 104 key, /* IV */ 105 DECRYPT); /* direction */ 106 107 if(net_len < 8) 108 store_ptr = storage + 8 - net_len; 109 else 110 store_ptr = storage; 111 112 nstored = net_len; 113 if (nstored > len) { 114 (void) bcopy(store_ptr, buf, len); 115 nreturned += len; 116 store_ptr += len; 117 nstored -= len; 118 } else { 119 (void) bcopy(store_ptr, buf, nstored); 120 nreturned += nstored; 121 nstored = 0; 122 } 123 124 return(nreturned); 125 } 126 127 static unsigned char des_outbuf[10240]; /* > longest write */ 128 129 int 130 des_write(fd, buf, len) 131 int fd; 132 char *buf; 133 int len; 134 { 135 static int seeded = 0; 136 static char garbage_buf[8]; 137 long net_len, garbage; 138 139 if(len < 8) { 140 if(!seeded) { 141 seeded = 1; 142 srandom((int) time((long *)0)); 143 } 144 garbage = random(); 145 /* insert random garbage */ 146 (void) bcopy(&garbage, garbage_buf, MIN(sizeof(long),8)); 147 /* this "right-justifies" the data in the buffer */ 148 (void) bcopy(buf, garbage_buf + 8 - len, len); 149 } 150 /* pcbc_encrypt outputs in 8-byte (64 bit) increments */ 151 152 (void) des_pcbc_encrypt((len < 8) ? garbage_buf : buf, 153 des_outbuf, 154 (len < 8) ? 8 : len, 155 key_schedule, /* DES key */ 156 key, /* IV */ 157 ENCRYPT); 158 159 /* tell the other end the real amount, but send an 8-byte padded 160 packet */ 161 net_len = htonl(len); 162 (void) write(fd, &net_len, sizeof(net_len)); 163 (void) write(fd, des_outbuf, roundup(len,8)); 164 return(len); 165 } 166 #endif /* KERBEROS */ 167 #endif /* CRYPT */ 168