diff options
Diffstat (limited to 'eBones/lib/libkrb/des_rw.c')
-rw-r--r-- | eBones/lib/libkrb/des_rw.c | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/eBones/lib/libkrb/des_rw.c b/eBones/lib/libkrb/des_rw.c new file mode 100644 index 0000000..c958355 --- /dev/null +++ b/eBones/lib/libkrb/des_rw.c @@ -0,0 +1,265 @@ +/* - + * Copyright (c) 1994 Geoffrey M. Rehmet, Rhodes University + * All rights reserved. + * + * This code is derived from a specification based on software + * which forms part of the 4.4BSD-Lite distribution, which was developed + * by the University of California and its contributors. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the entire comment, + * including the above copyright notice, this list of conditions + * and the following disclaimer, verbatim, at the beginning of + * the source file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Geoffrey M. Rehmet + * 4. Neither the name of Geoffrey M. Rehmet nor that of Rhodes University + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL GEOFFREY M. REHMET OR RHODES UNIVERSITY BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: des_rw.c,v 1.5 1994/09/24 18:54:41 g89r4222 Exp $ + */ + +/* + * + * NB: THESE ROUTINES WILL FAIL IF NON-BLOCKING I/O IS USED. + * + */ + +/* + * Routines for reading and writing DES encrypted messages onto sockets. + * (These routines will fail if non-blocking I/O is used.) + * + * When a message is written, its length is first transmitted as an int, + * in network byte order. The encrypted message is then transmitted, + * to a multiple of 8 bytes. Messages shorter than 8 bytes are right + * justified into a buffer of length 8 bytes, and the remainder of the + * buffer is filled with random garbage (before encryption): + * + * DDD -------->--+--------+ + * | | + * +--+--+--+--+--+--+--+--+ + * |x |x |x |x |x |D |D |D | + * +--+--+--+--+--+--+--+--+ + * | garbage | data | + * | | + * +-----------------------+----> des_pcbc_encrypt() --> + * + * (Note that the length field sent before the actual message specifies + * the number of data bytes, not the length of the entire padded message. + * + * When data is read, if the message received is longer than the number + * of bytes requested, then the remaining bytes are stored until the + * following call to des_read(). If the number of bytes received is + * less then the number of bytes received, then only the number of bytes + * actually received is returned. + * + * This interface corresponds with the original des_rw.c, except for the + * bugs in des_read() in the original 4.4BSD version. (One bug is + * normally not visible, due to undocumented behaviour of + * des_pcbc_encrypt() in the original MIT libdes.) + * + * XXX Todo: + * 1) Give better error returns on writes + * 2) Improve error checking on reads + * 3) Get rid of need for extern decl. of krb_net_read() + * 4) Tidy garbage generation a bit + * 5) Make the above comment more readable + */ + +#ifdef CRYPT +#ifdef KERBEROS + +#ifndef BUFFER_LEN +#define BUFFER_LEN 10240 +#endif + +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include <sys/param.h> +#include <sys/types.h> + +#include <kerberosIV/des.h> +#include <kerberosIV/krb.h> + +extern int krb_net_read(int fd, void * data, size_t length); +extern int des_pcbc_encrypt(des_cblock *input, des_cblock *output, + register long length, + des_key_schedule schedule, + des_cblock *ivec, + int encrypt); + +static bit_64 des_key; +static des_key_schedule key_sched; + +/* + * Buffer for storing extra data when more data is received, then was + * actually requested in des_read(). + */ +static u_char des_buff[BUFFER_LEN]; +static u_char buffer[BUFFER_LEN]; +static unsigned stored = 0; +static u_char *buff_ptr = buffer; + +/* + * Set the encryption key for des_read() and des_write(). + * inkey is the initial vector for the DES encryption, while insched is + * the DES key, in unwrapped form. + */ +void des_set_key(inkey, insched) + bit_64 *inkey; + u_char *insched; +{ + bcopy(inkey, &des_key, sizeof(bit_64)); + bcopy(insched, &key_sched, sizeof(des_key_schedule)); +} + +/* + * Clear the key schedule, and initial vector, which were previously + * stored in static vars by des_set_key(). + */ +void des_clear_key() +{ + bzero(&des_key, sizeof(des_cblock)); + bzero(&key_sched, sizeof(des_key_schedule)); +} + +int des_read(fd, buf, len) + int fd; + register char * buf; + int len; +{ + int msg_length; /* length of actual message data */ + int pad_length; /* length of padded message */ + int nread; /* number of bytes actually read */ + int nreturned = 0; + + if(stored >= len) { + bcopy(buff_ptr, buf, len); + stored -= len; + buff_ptr += len; + return(len); + } else { + if (stored) { + bcopy(buff_ptr, buf, stored); + nreturned = stored; + len -= stored; + stored = 0; + buff_ptr = buffer; + } else { + nreturned = 0; + buff_ptr = buffer; + } + } + + nread = krb_net_read(fd, &msg_length, sizeof(msg_length)); + if(nread != (int)(sizeof(msg_length))) + return(0); + + msg_length = ntohl(msg_length); + pad_length = roundup(msg_length, 8); + + nread = krb_net_read(fd, des_buff, pad_length); + if(nread != pad_length) + return(0); + + des_pcbc_encrypt((des_cblock*) des_buff, (des_cblock*) buff_ptr, + (msg_length < 8 ? 8 : msg_length), + key_sched, (des_cblock*) &des_key, DES_DECRYPT); + + + if(msg_length < 8) + buff_ptr += (8 - msg_length); + stored = msg_length; + + if(stored >= len) { + bcopy(buff_ptr, buf, len); + stored -= len; + buff_ptr += len; + nreturned += len; + } else { + bcopy(buff_ptr, buf, stored); + nreturned += stored; + stored = 0; + } + + return(nreturned); +} + + +/* + * Write a message onto a file descriptor (generally a socket), using + * DES to encrypt the message. + */ +int des_write(fd, buf, len) + int fd; + char * buf; + int len; +{ + static int seeded = 0; + char garbage[8]; + long rnd; + int pad_len; + int write_len; + int nwritten = 0; + int i; + char *data; + + if(len < 8) { + /* + * Right justify the message in 8 bytes of random garbage. + */ + if(!seeded) { + seeded = 1; + srandom((unsigned)time(NULL)); + } + + for(i = 0 ; i < 8 ; i+= sizeof(long)) { + rnd = random(); + bcopy(&rnd, garbage+i, + (i <= (8 - sizeof(long)))?sizeof(long):(8-i)); + } + bcopy(buf, garbage + 8 - len, len); + data = garbage; + pad_len = 8; + } else { + data = buf; + pad_len = roundup(len, 8); + } + + des_pcbc_encrypt((des_cblock*) data, (des_cblock*) des_buff, + (len < 8)?8:len, key_sched, (des_cblock*) &des_key, DES_ENCRYPT); + + + write_len = htonl(len); + if(write(fd, &write_len, sizeof(write_len)) != sizeof(write_len)) + return(-1); + if(write(fd, des_buff, pad_len) != pad_len) + return(-1); + + return(len); +} + +#endif /* KERBEROS */ +#endif /* CRYPT */ |