1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 19 /* 20 * $Source:$ 21 * $Header:$ 22 */ 23 24 25 #ifndef lint 26 static char sccsid[] = "@(#)des_rw.c 1.7 (Berkeley) 2/6/89"; 27 #endif /* not lint */ 28 29 #include <sys/types.h> 30 #include <sys/param.h> 31 #include <krb.h> 32 #include <des.h> 33 34 extern long random(); 35 static unsigned char des_inbuf[10240], storage[10240], *store_ptr; 36 static bit_64 *key; 37 static u_char *key_schedule; 38 39 /* 40 * NB: These routines will not function properly if NBIO 41 * is set 42 */ 43 44 /* 45 * des_set_key 46 * 47 * Set des encryption/decryption key for use by the des_read and 48 * des_write routines 49 * 50 * The inkey parameter is actually the DES initial vector, 51 * and the insched is the DES Key unwrapped for faster decryption 52 */ 53 54 void 55 des_set_key(inkey, insched) 56 bit_64 *inkey; 57 u_char *insched; 58 { 59 key = inkey; 60 key_schedule = insched; 61 } 62 63 void 64 des_clear_key() 65 { 66 bzero((char *) key, sizeof(C_Block)); 67 bzero((char *) key_schedule, sizeof(Key_schedule)); 68 } 69 70 71 int 72 des_read(fd, buf, len) 73 int fd; 74 register char *buf; 75 int len; 76 { 77 int nreturned = 0; 78 long net_len, rd_len; 79 int nstored = 0; 80 81 if (nstored >= len) { 82 (void) bcopy(store_ptr, buf, len); 83 store_ptr += len; 84 nstored -= len; 85 return(len); 86 } else if (nstored) { 87 (void) bcopy(store_ptr, buf, nstored); 88 nreturned += nstored; 89 buf += nstored; 90 len -= nstored; 91 nstored = 0; 92 } 93 94 if (krb_net_read(fd, &net_len, sizeof(net_len)) != sizeof(net_len)) { 95 /* XXX can't read enough, pipe 96 must have closed */ 97 return(0); 98 } 99 net_len = ntohl(net_len); 100 if (net_len <= 0 || net_len > sizeof(des_inbuf)) { 101 /* preposterous length; assume out-of-sync; only 102 recourse is to close connection, so return 0 */ 103 return(0); 104 } 105 /* the writer tells us how much real data we are getting, but 106 we need to read the pad bytes (8-byte boundary) */ 107 rd_len = roundup(net_len, 8); 108 if (krb_net_read(fd, des_inbuf, rd_len) != rd_len) { 109 /* pipe must have closed, return 0 */ 110 return(0); 111 } 112 (void) des_pcbc_encrypt(des_inbuf, /* inbuf */ 113 storage, /* outbuf */ 114 net_len, /* length */ 115 key_schedule, /* DES key */ 116 key, /* IV */ 117 DECRYPT); /* direction */ 118 119 if(net_len < 8) 120 store_ptr = storage + 8 - net_len; 121 else 122 store_ptr = storage; 123 124 nstored = net_len; 125 if (nstored > len) { 126 (void) bcopy(store_ptr, buf, len); 127 nreturned += len; 128 store_ptr += len; 129 nstored -= len; 130 } else { 131 (void) bcopy(store_ptr, buf, nstored); 132 nreturned += nstored; 133 nstored = 0; 134 } 135 136 return(nreturned); 137 } 138 139 static unsigned char des_outbuf[10240]; /* > longest write */ 140 141 int 142 des_write(fd, buf, len) 143 int fd; 144 char *buf; 145 int len; 146 { 147 static int seeded = 0; 148 static char garbage_buf[8]; 149 long net_len, garbage; 150 151 if(len < 8) { 152 if(!seeded) { 153 seeded = 1; 154 srandom((int) time((long *)0)); 155 } 156 garbage = random(); 157 /* insert random garbage */ 158 (void) bcopy(&garbage, garbage_buf, MIN(sizeof(long),8)); 159 /* this "right-justifies" the data in the buffer */ 160 (void) bcopy(buf, garbage_buf + 8 - len, len); 161 } 162 /* pcbc_encrypt outputs in 8-byte (64 bit) increments */ 163 164 (void) des_pcbc_encrypt((len < 8) ? garbage_buf : buf, 165 des_outbuf, 166 (len < 8) ? 8 : len, 167 key_schedule, /* DES key */ 168 key, /* IV */ 169 ENCRYPT); 170 171 /* tell the other end the real amount, but send an 8-byte padded 172 packet */ 173 net_len = htonl(len); 174 (void) write(fd, &net_len, sizeof(net_len)); 175 (void) write(fd, des_outbuf, roundup(len,8)); 176 return(len); 177 } 178