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