freebsd-dev/eBones/des/enc_read.c
Geoff Rehmet 60643d379b Initial import of eBones.
(Including all changes for FreeBSD - importing the original eBones distribution
would be too complex at this stage, since I don't have access to Piero's 
CVS.)
(If you want to include eBones in your system, don't forget to include
MAKE_EBONES in /etc/make.conf.)
(This stuff is now also suppable from braae.ru.ac.za.)

Bones originally from MIT SIPB.
Original port to FreeBSD 1.x  by Piero Serini.
Moved to FreeBSD 2.0 by Doug Rabson and Geoff Rehmet.
Nice bug fixes from Doug Rabson.
1994-09-30 14:50:09 +00:00

148 lines
3.3 KiB
C

/* enc_read.c */
/* Copyright (C) 1993 Eric Young - see README for more details */
/*-
* $Id: enc_read.c,v 1.2 1994/07/19 19:21:54 g89r4222 Exp $
*/
#include <errno.h>
#include "des_locl.h"
/* This has some uglies in it but it works - even over sockets. */
extern int errno;
int des_rw_mode=DES_PCBC_MODE;
int des_enc_read(fd,buf,len,sched,iv)
int fd;
char *buf;
int len;
des_key_schedule sched;
des_cblock *iv;
{
/* data to be unencrypted */
int net_num=0;
unsigned char net[BSIZE];
/* extra unencrypted data
* for when a block of 100 comes in but is des_read one byte at
* a time. */
static char unnet[BSIZE];
static int unnet_start=0;
static int unnet_left=0;
int i;
long num=0,rnum;
unsigned char *p;
/* left over data from last decrypt */
if (unnet_left != 0)
{
if (unnet_left < len)
{
/* we still still need more data but will return
* with the number of bytes we have - should always
* check the return value */
bcopy(&(unnet[unnet_start]),buf,unnet_left);
/* eay 26/08/92 I had the next 2 lines
* reversed :-( */
i=unnet_left;
unnet_start=unnet_left=0;
}
else
{
bcopy(&(unnet[unnet_start]),buf,len);
unnet_start+=len;
unnet_left-=len;
i=len;
}
return(i);
}
/* We need to get more data. */
if (len > MAXWRITE) len=MAXWRITE;
/* first - get the length */
net_num=0;
while (net_num < HDRSIZE)
{
i=read(fd,&(net[net_num]),HDRSIZE-net_num);
if ((i == -1) && (errno == EINTR)) continue;
if (i <= 0) return(0);
net_num+=i;
}
/* we now have at net_num bytes in net */
p=net;
num=0;
n2l(p,num);
/* num should be rounded up to the next group of eight
* we make sure that we have read a multiple of 8 bytes from the net.
*/
if ((num > MAXWRITE) || (num < 0)) /* error */
return(-1);
rnum=(num < 8)?8:((num+7)/8*8);
net_num=0;
while (net_num < rnum)
{
i=read(fd,&(net[net_num]),rnum-net_num);
if ((i == -1) && (errno == EINTR)) continue;
if (i <= 0) return(0);
net_num+=i;
}
/* Check if there will be data left over. */
if (len < num)
{
if (des_rw_mode & DES_PCBC_MODE)
pcbc_encrypt((des_cblock *)net,(des_cblock *)unnet,
num,sched,iv,DES_DECRYPT);
else
cbc_encrypt((des_cblock *)net,(des_cblock *)unnet,
num,sched,iv,DES_DECRYPT);
bcopy(unnet,buf,len);
unnet_start=len;
unnet_left=num-len;
/* The following line is done because we return num
* as the number of bytes read. */
num=len;
}
else
{
/* >output is a multiple of 8 byes, if len < rnum
* >we must be careful. The user must be aware that this
* >routine will write more bytes than he asked for.
* >The length of the buffer must be correct.
* FIXED - Should be ok now 18-9-90 - eay */
if (len < rnum)
{
char tmpbuf[BSIZE];
if (des_rw_mode & DES_PCBC_MODE)
pcbc_encrypt((des_cblock *)net,
(des_cblock *)tmpbuf,
num,sched,iv,DES_DECRYPT);
else
cbc_encrypt((des_cblock *)net,
(des_cblock *)tmpbuf,
num,sched,iv,DES_DECRYPT);
/* eay 26/08/92 fix a bug that returned more
* bytes than you asked for (returned len bytes :-( */
bcopy(tmpbuf,buf,num);
}
else
{
if (des_rw_mode & DES_PCBC_MODE)
pcbc_encrypt((des_cblock *)net,
(des_cblock *)buf,num,sched,iv,
DES_DECRYPT);
else
cbc_encrypt((des_cblock *)net,
(des_cblock *)buf,num,sched,iv,
DES_DECRYPT);
}
}
return(num);
}