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