Home | History | Annotate | Line # | Download | only in libdes
      1 /* crypto/des/enc_read.c */
      2 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      3  * All rights reserved.
      4  *
      5  * This package is an SSL implementation written
      6  * by Eric Young (eay (at) cryptsoft.com).
      7  * The implementation was written so as to conform with Netscapes SSL.
      8  *
      9  * This library is free for commercial and non-commercial use as long as
     10  * the following conditions are aheared to.  The following conditions
     11  * apply to all code found in this distribution, be it the RC4, RSA,
     12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
     13  * included with this distribution is covered by the same copyright terms
     14  * except that the holder is Tim Hudson (tjh (at) cryptsoft.com).
     15  *
     16  * Copyright remains Eric Young's, and as such any Copyright notices in
     17  * the code are not to be removed.
     18  * If this package is used in a product, Eric Young should be given attribution
     19  * as the author of the parts of the library used.
     20  * This can be in the form of a textual message at program startup or
     21  * in documentation (online or textual) provided with the package.
     22  *
     23  * Redistribution and use in source and binary forms, with or without
     24  * modification, are permitted provided that the following conditions
     25  * are met:
     26  * 1. Redistributions of source code must retain the copyright
     27  *    notice, this list of conditions and the following disclaimer.
     28  * 2. Redistributions in binary form must reproduce the above copyright
     29  *    notice, this list of conditions and the following disclaimer in the
     30  *    documentation and/or other materials provided with the distribution.
     31  * 3. All advertising materials mentioning features or use of this software
     32  *    must display the following acknowledgement:
     33  *    "This product includes cryptographic software written by
     34  *     Eric Young (eay (at) cryptsoft.com)"
     35  *    The word 'cryptographic' can be left out if the rouines from the library
     36  *    being used are not cryptographic related :-).
     37  * 4. If you include any Windows specific code (or a derivative thereof) from
     38  *    the apps directory (application code) you must include an acknowledgement:
     39  *    "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)"
     40  *
     41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
     42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     51  * SUCH DAMAGE.
     52  *
     53  * The licence and distribution terms for any publically available version or
     54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
     55  * copied and put under another distribution licence
     56  * [including the GNU Public Licence.]
     57  */
     58 
     59 #include <stdio.h>
     60 #include <errno.h>
     61 #include "des_locl.h"
     62 
     63 /* This has some uglies in it but it works - even over sockets. */
     64 /*extern int errno;*/
     65 int des_rw_mode=DES_PCBC_MODE;
     66 
     67 
     68 /*
     69  * WARNINGS:
     70  *
     71  *  -  The data format used by des_enc_write() and des_enc_read()
     72  *     has a cryptographic weakness: When asked to write more
     73  *     than MAXWRITE bytes, des_enc_write will split the data
     74  *     into several chunks that are all encrypted
     75  *     using the same IV.  So don't use these functions unless you
     76  *     are sure you know what you do (in which case you might
     77  *     not want to use them anyway).
     78  *
     79  *  -  This code cannot handle non-blocking sockets.
     80  *
     81  *  -  This function uses an internal state and thus cannot be
     82  *     used on multiple files.
     83  */
     84 
     85 
     86 int des_enc_read(int fd, void *buf, int len, des_key_schedule sched,
     87 		 des_cblock *iv)
     88 	{
     89 	/* data to be unencrypted */
     90 	int net_num=0;
     91 	static unsigned char *net=NULL;
     92 	/* extra unencrypted data
     93 	 * for when a block of 100 comes in but is des_read one byte at
     94 	 * a time. */
     95 	static unsigned char *unnet=NULL;
     96 	static int unnet_start=0;
     97 	static int unnet_left=0;
     98 	static unsigned char *tmpbuf=NULL;
     99 	int i;
    100 	long num=0,rnum;
    101 	unsigned char *p;
    102 
    103 	if (tmpbuf == NULL)
    104 		{
    105 		tmpbuf=OPENSSL_malloc(BSIZE);
    106 		if (tmpbuf == NULL) return(-1);
    107 		}
    108 	if (net == NULL)
    109 		{
    110 		net=OPENSSL_malloc(BSIZE);
    111 		if (net == NULL) return(-1);
    112 		}
    113 	if (unnet == NULL)
    114 		{
    115 		unnet=OPENSSL_malloc(BSIZE);
    116 		if (unnet == NULL) return(-1);
    117 		}
    118 	/* left over data from last decrypt */
    119 	if (unnet_left != 0)
    120 		{
    121 		if (unnet_left < len)
    122 			{
    123 			/* we still still need more data but will return
    124 			 * with the number of bytes we have - should always
    125 			 * check the return value */
    126 			memcpy(buf,&(unnet[unnet_start]),
    127 			       unnet_left);
    128 			/* eay 26/08/92 I had the next 2 lines
    129 			 * reversed :-( */
    130 			i=unnet_left;
    131 			unnet_start=unnet_left=0;
    132 			}
    133 		else
    134 			{
    135 			memcpy(buf,&(unnet[unnet_start]),len);
    136 			unnet_start+=len;
    137 			unnet_left-=len;
    138 			i=len;
    139 			}
    140 		return(i);
    141 		}
    142 
    143 	/* We need to get more data. */
    144 	if (len > MAXWRITE) len=MAXWRITE;
    145 
    146 	/* first - get the length */
    147 	while (net_num < HDRSIZE)
    148 		{
    149 		i=read(fd,(void *)&(net[net_num]),HDRSIZE-net_num);
    150 #ifdef EINTR
    151 		if ((i == -1) && (errno == EINTR)) continue;
    152 #endif
    153 		if (i <= 0) return(0);
    154 		net_num+=i;
    155 		}
    156 
    157 	/* we now have at net_num bytes in net */
    158 	p=net;
    159 	/* num=0;  */
    160 	n2l(p,num);
    161 	/* num should be rounded up to the next group of eight
    162 	 * we make sure that we have read a multiple of 8 bytes from the net.
    163 	 */
    164 	if ((num > MAXWRITE) || (num < 0)) /* error */
    165 		return(-1);
    166 	rnum=(num < 8)?8:((num+7)/8*8);
    167 
    168 	net_num=0;
    169 	while (net_num < rnum)
    170 		{
    171 		i=read(fd,(void *)&(net[net_num]),rnum-net_num);
    172 #ifdef EINTR
    173 		if ((i == -1) && (errno == EINTR)) continue;
    174 #endif
    175 		if (i <= 0) return(0);
    176 		net_num+=i;
    177 		}
    178 
    179 	/* Check if there will be data left over. */
    180 	if (len < num)
    181 		{
    182 		if (des_rw_mode & DES_PCBC_MODE)
    183 			des_pcbc_encrypt(net,unnet,num,sched,iv,DES_DECRYPT);
    184 		else
    185 			des_cbc_encrypt(net,unnet,num,sched,iv,DES_DECRYPT);
    186 		memcpy(buf,unnet,len);
    187 		unnet_start=len;
    188 		unnet_left=num-len;
    189 
    190 		/* The following line is done because we return num
    191 		 * as the number of bytes read. */
    192 		num=len;
    193 		}
    194 	else
    195 		{
    196 		/* >output is a multiple of 8 byes, if len < rnum
    197 		 * >we must be careful.  The user must be aware that this
    198 		 * >routine will write more bytes than he asked for.
    199 		 * >The length of the buffer must be correct.
    200 		 * FIXED - Should be ok now 18-9-90 - eay */
    201 		if (len < rnum)
    202 			{
    203 
    204 			if (des_rw_mode & DES_PCBC_MODE)
    205 				des_pcbc_encrypt(net,tmpbuf,num,sched,iv,
    206 						 DES_DECRYPT);
    207 			else
    208 				des_cbc_encrypt(net,tmpbuf,num,sched,iv,
    209 						DES_DECRYPT);
    210 
    211 			/* eay 26/08/92 fix a bug that returned more
    212 			 * bytes than you asked for (returned len bytes :-( */
    213 			memcpy(buf,tmpbuf,num);
    214 			}
    215 		else
    216 			{
    217 			if (des_rw_mode & DES_PCBC_MODE)
    218 				des_pcbc_encrypt(net,buf,num,sched,iv,
    219 						 DES_DECRYPT);
    220 			else
    221 				des_cbc_encrypt(net,buf,num,sched,iv,
    222 						DES_DECRYPT);
    223 			}
    224 		}
    225 	return num;
    226 	}
    227 
    228