home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume29 / libdes / part01 / enc_read.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-04  |  3.0 KB  |  134 lines

  1. /* des_read.c */
  2. /* Copyright (C) 1992 Eric Young - see COPYING for more details */
  3. #include <errno.h>
  4. #include "des_local.h"
  5.  
  6. /* This has some uglies in it but it works - even over sockets. */
  7. extern int errno;
  8. int des_rw_mode=DES_PCBC_MODE;
  9.  
  10. int des_enc_read(fd,buf,len,sched,iv)
  11. int fd;
  12. char *buf;
  13. int len;
  14. des_key_schedule sched;
  15. des_cblock *iv;
  16.     {
  17.     /* data to be unencrypted */
  18.     int net_num=0;
  19.     char net[BSIZE];
  20.     /* extra unencrypted data 
  21.      * for when a block of 100 comes in but is des_read one byte at
  22.      * a time. */
  23.     static char unnet[BSIZE];
  24.     static int unnet_start=0;
  25.     static int unnet_left=0;
  26.     int i;
  27.     long num=0,rnum;
  28.  
  29.     /* left over data from last decrypt */
  30.     if (unnet_left != 0)
  31.         {
  32.         if (unnet_left < len)
  33.             {
  34.             /* we still still need more data but will return
  35.              * with the number of bytes we have - should always
  36.              * check the return value */
  37.             bcopy(&(unnet[unnet_start]),buf,unnet_left);
  38.             unnet_start=unnet_left=0;
  39.             i=unnet_left;
  40.             }
  41.         else
  42.             {
  43.             bcopy(&(unnet[unnet_start]),buf,len);
  44.             unnet_start+=len;
  45.             unnet_left-=len;
  46.             i=len;
  47.             }
  48.         return(i);
  49.         }
  50.  
  51.     /* We need to get more data. */
  52.     if (len > MAXWRITE) len=MAXWRITE;
  53.  
  54.     /* first - get the length */
  55.     net_num=0;
  56.     while (net_num < sizeof(long)) 
  57.         {
  58.         i=read(fd,&(net[net_num]),sizeof(long)-net_num);
  59.         if ((i == -1) && (errno == EINTR)) continue;
  60.         if (i <= 0) return(0);
  61.         net_num+=i;
  62.         }
  63.  
  64.     /* we now have at net_num bytes in net */
  65.     bcopy(&(net[0]),&num,sizeof(long));
  66.     num=ntohl(num);
  67.     /* num should be rounded up to the next group of eight
  68.      * we make sure that we have read a multiple of 8 bytes from the net.
  69.      */
  70.     rnum=(num < 8)?8:((num+7)/8*8);
  71.     net_num=0;
  72.     while (net_num < rnum)
  73.         {
  74.         i=read(fd,&(net[net_num]),rnum-net_num);
  75.         if ((i == -1) && (errno == EINTR)) continue;
  76.         if (i <= 0) return(0);
  77.         net_num+=i;
  78.         }
  79.  
  80.     /* Check if there will be data left over. */
  81.     if (len < num)
  82.         {
  83.         if (des_rw_mode == DES_PCBC_MODE)
  84.             pcbc_encrypt((des_cblock *)net,(des_cblock *)unnet,
  85.                 num,sched,iv,DES_DECRYPT);
  86.         else
  87.             cbc_encrypt((des_cblock *)net,(des_cblock *)unnet,
  88.                 num,sched,iv,DES_DECRYPT);
  89.         bcopy(unnet,buf,len);
  90.         unnet_start=len;
  91.         unnet_left=num-len;
  92.  
  93.         /* The following line is done because we return num
  94.          * as the number of bytes read. */
  95.         num=len;
  96.         }
  97.     else
  98.         {
  99.         /* >output is a multiple of 8 byes, if len < rnum
  100.          * >we must be careful.  The user must be aware that this
  101.          * >routine will write more bytes than he asked for.
  102.          * >The length of the buffer must be correct.
  103.          * FIXED - Should be ok now 18-9-90 - eay */
  104.         if (len < rnum)
  105.             {
  106.             char tmpbuf[BSIZE];
  107.  
  108.             if (des_rw_mode == DES_PCBC_MODE)
  109.                 pcbc_encrypt((des_cblock *)net,
  110.                     (des_cblock *)tmpbuf,
  111.                     num,sched,iv,DES_DECRYPT);
  112.             else
  113.                 cbc_encrypt((des_cblock *)net,
  114.                     (des_cblock *)tmpbuf,
  115.                     num,sched,iv,DES_DECRYPT);
  116.  
  117.             bcopy(tmpbuf,buf,len);
  118.             }
  119.         else
  120.             {
  121.             if (des_rw_mode == DES_PCBC_MODE)
  122.                 pcbc_encrypt((des_cblock *)net,
  123.                     (des_cblock *)buf,num,sched,iv,
  124.                     DES_DECRYPT);
  125.             else
  126.                 cbc_encrypt((des_cblock *)net,
  127.                     (des_cblock *)buf,num,sched,iv,
  128.                     DES_DECRYPT);
  129.             }
  130.         }
  131.     return(num);
  132.     }
  133.  
  134.