⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crypto.c.txt

📁 当今
💻 TXT
📖 第 1 页 / 共 2 页
字号:
发信人: iceman ( 令狐小冲), 信区: Security 

标  题: crypto.c 

发信站: 武汉白云黄鹤站 (Fri Sep  4 11:27:07 1998) , 站内信件 

  

/*      crypto.c  - Cryptographic routines for PGP. 

  

  

        PGP: Pretty Good(tm) Privacy - public key cryptography for the masses. 

  

  

  

  

  

        (c) Copyright 1990-1992 by Philip Zimmermann.  All rights reserved. 

  

  

        The author assumes no liability for damages resulting from the use 

  

  

        of this software, even if the damage results from defects in this 

  

  

        software.  No warranty is expressed or implied. 

  

  

  

  

  

        All the source code Philip Zimmermann wrote for PGP is available for 

  

  

        free under the "Copyleft" General Public License from the Free 

  

  

        Software Foundation.  A copy of that license agreement is included in 

  

  

        the source release package of PGP.  Code developed by others for PGP 

  

  

        is also freely available.  Other code that has been incorporated into 

  

  

        PGP from other sources was either originally published in the public 

  

  

        domain or was used with permission from the various authors.  See the 

  

  

        PGP User's Guide for more complete information about licensing, 

  

  

        patent restrictions on certain algorithms, trademarks, copyrights, 

  

  

        and export controls. 

  

  

  

  

  

        Modified: 12-Nov-92 HAJK 

  

  

        Add FDL stuff for VAX/VMS local mode. 

  

  

        Reopen temporary files rather than create new version. 

  

  

  

  

  

*/ 

  

  

  

  

  

#include <ctype.h> 

  

  

#include <stdlib.h> 

  

  

#include <stdio.h> 

  

  

#include <string.h> 

  

  

#include <time.h> 

  

  

#ifdef __mips 

  

  

#include <fcntl.h> 

  

  

#else 

  

  

#include <sys/fcntl.h> 

  

  

#endif 

  

  

#ifndef __NeXT__ 

  

  

#include <unistd.h> 

  

  

#endif 

  

  

  

  

  

#include <sys/types.h> 

  

  

#include <sys/stat.h> 

  

  

  

  

  

#include "random.h" 

  

  

#include "crypto.h" 

  

  

#include "pgp.h" 

  

  

#include "mpilib.h" 

  

  

  

  

  

#ifndef S_IRUSR 

  

  

#define S_IRUSR S_IREAD 

  

  

#define S_IWUSR S_IWRITE 

  

  

#endif 

  

  

  

  

  

/* The kbhit() function: Determines if a key has been hit.  May not be 

  

  

   available in some implementations */ 

  

  

  

  

  

int kbhit( void ); 

  

  

int zipup(FILE *, FILE *); 

  

  

#ifdef  M_XENIX 

  

  

long time(); 

  

  

#endif 

  

  

  

  

  

word32 get_timestamp(word32 *timestamp) 

  

  

/*      Return current timestamp as a byte array in internal byteorder, 

  

  

        and as a 32-bit word */ 

  

  

{       word32 t; 

  

  

        t = time(NULL);    /* returns seconds since GMT 00:00 1 Jan 1970 */ 

  

  

  

  

  

#ifdef _MSC_VER 

  

  

#if (_MSC_VER == 700) 

  

  

        /*  Under MSDOS and MSC 7.0, time() returns elapsed time since 

  

  

         *  GMT 00:00 31 Dec 1899, instead of Unix's base date of 1 Jan 1970. 

  

  

         *  So we must subtract 70 years worth of seconds to fix this. 

  

  

         *  6/19/92  rgb 

  

  

        */ 

  

  

#define LEAP_DAYS       (((unsigned long)70L/4)+1) 

  

  

#define CALENDAR_KLUDGE ((unsigned long)86400L * (((unsigned long)365L * 70L) + 

  

  

LEAP_DAYS)) 

  

  

        t -= CALENDAR_KLUDGE; 

  

  

#endif 

  

  

#endif 

  

  

  

  

  

        t += timeshift; /* timeshift derived from TZFIX in config.pgp */ 

  

  

  

  

  

        if (timestamp != NULL) 

  

  

        {       /* first, fill array in external byte order: */ 

  

  

                *timestamp = t; 

  

  

        } 

  

  

  

  

  

        return(t);      /* return 32-bit timestamp integer */ 

  

  

}       /* get_timestamp */ 

  

  

  

  

  

/*--------------------------------------------------------------------------*/ 

  

  

  

  

  

#define IDEA_RANDOM 

  

  

#ifdef IDEA_RANDOM 

  

  

int strong_pseudorandom(byte *buf, int bufsize) 

  

  

/* 

  

  

        Reads IDEA random key and random number seed from file, cranks the 

  

  

        the seed through the idearand strong pseudorandom number generator, 

  

  

        and writes them back out.  This is used for generation of 

  

  

        cryptographically strong pseudorandom numbers.  This is mainly to 

  

  

        save the user the trouble of having to type in lengthy keyboard 

  

  

        sequences for generation of truly random numbers every time we want 

  

  

        to make a random session key.  This pseudorandom generator will only 

  

  

        work if the file containing the random seed exists and is not empty. 

  

  

        If it doesn't exist, it will be automatically created.  If it exists 

  

  

        and is empty or nearly empty, it will not be used. 

  

  

*/ 

  

  

{       char seedfile[MAX_PATH];        /* Random seed filename */ 

  

  

        FILE *f; 

  

  

        byte key[IDEAKEYSIZE]; 

  

  

        byte seed[IDEABLOCKSIZE]; 

  

  

        int i; 

  

  

        word32 tstamp; 

  

  

  

  

  

        strcpy(seedfile, getenv("HOME")); 

  

  

        strcat(seedfile, "/"); 

  

  

        strcat(seedfile, ".rand"); 

  

  

  

  

  

        if (access(seedfile, F_OK))     /* No seed file. Start one... */ 

  

  

        { 

  

  

            return -1; 

  

  

        } 

  

  

        else    /* seedfile DOES exist.  Open it and read it. */ 

  

  

        {       f = fopen(seedfile,"r");        /* open for reading binary */ 

  

  

                if (f==NULL)    /* did open fail? */ 

  

  

                        return(-1);     /* error: no random number seed file ava 

lable */ 

  

  

                /* read IDEA random generator key */ 

  

  

                if (fread(key,1,sizeof(key),f) < sizeof(key))   /* empty file? * 

  

  

  

                {       /* Empty or nearly empty file means don't use it. */ 

  

  

                        fclose(f); 

  

  

                        return(-1);     /* error: no random number seed file ava 

lable */ 

  

  

                } 

  

  

                else 

  

  

                        fread(seed,1,sizeof(seed),f); /* read pseudorandom seed 

/ 

  

  

                fclose(f); 

  

  

        }       /* seedfile exists */ 

  

  

  

  

  

  

  

  

        /* Initialize, key, and seed the IDEA pseudorandom generator: */ 

  

  

        get_timestamp(&tstamp); /* timestamp points to tstamp */ 

  

  

        init_idearand(key, seed, tstamp); 

  

  

  

  

  

        /* Note that the seed will be cycled thru IDEA before use */ 

  

  

  

  

  

        /* Now fill the user's buffer with gobbledygook... */ 

  

  

        while (bufsize--) 

  

  

                *buf++ = idearand() ^ randombyte(); 

  

  

  

  

  

        /* now cover up evidence of what user got */ 

  

  

        for (i=1; i<sizeof(key); i++) 

  

  

                key[i] ^= idearand() ^ randombyte(); 

  

  

        for (i=0; i<sizeof(seed); i++) 

  

  

                seed[i] = idearand() ^ randombyte(); 

  

  

  

  

  

        close_idearand();       /* close IDEA random number generator */ 

  

  

  

  

  

        chmod(seedfile, S_IRUSR|S_IWUSR); 

  

  

        f = fopen(seedfile,"w");        /* open for writing binary */ 

  

  

        if (f==NULL)    /* did open fail? */ 

  

  

                return(-1);     /* error: no random number seed file available * 

  

  

  

#ifdef VMS 

  

  

        fseek (f, 0, SEEK_SET); 

  

  

#endif 

  

  

        /* Now at start of file again */ 

  

  

        fwrite(key,1,sizeof(key),f); 

  

  

        fwrite(seed,1,sizeof(seed),f); 

  

  

        fclose(f); 

  

  

        burn(key);              /* burn sensitive data on stack */ 

  

  

        burn(seed);             /* burn sensitive data on stack */ 

  

  

        return(0);      /* normal return */ 

  

  

}       /* strong_pseudorandom */ 

  

  

  

  

  

extern int randcount; 

  

  

  

  

  

int refresh_pseudorandom() 

  

  

{       char seedfile[MAX_PATH];        /* Random seed filename */ 

  

  

        FILE *f; 

  

  

        byte key[IDEAKEYSIZE]; 

  

  

        byte seed[IDEABLOCKSIZE]; 

  

  

        int i; 

  

  

        word32 tstamp; 

  

  

  

  

  

        capturecounter(); 

  

  

        if (randcount < 2*(sizeof(key) + sizeof(seed))) 

  

  

                return; 

  

  

  

  

  

        strcpy(seedfile, getenv("HOME")); 

  

  

        strcat(seedfile, "/"); 

  

  

        strcat(seedfile, ".rand"); 

  

  

  

  

  

        f = fopen(seedfile,"w");        /* open for writing binary */ 

  

  

        chmod(seedfile, S_IRUSR|S_IWUSR); 

  

  

        if (f==NULL)    /* failed to create seedfile */ 

  

  

                return(-1);     /* error: no random number seed file available * 

  

  

  

        fclose(f);      /* close new empty seed file */ 

  

  

        /* kickstart the generator with true random numbers */ 

  

  

        for (i=1; i<sizeof(key); i++) 

  

  

                key[i] ^= randombyte(); 

  

  

        for (i=0; i<sizeof(seed); i++) 

  

  

                seed[i] ^= randombyte(); 

  

  

  

  

  

        /* Initialize, key, and seed the IDEA pseudorandom generator: */ 

  

  

        get_timestamp(&tstamp); /* timestamp points to tstamp */ 

  

  

        init_idearand(key, seed, tstamp); 

  

  

  

  

  

        /* Note that the seed will be cycled thru IDEA before use */ 

  

  

  

  

  

  

  

  

        /* now cover up evidence of what user got */ 

  

  

        for (i=1; i<sizeof(key); i++) 

  

  

                key[i] ^= idearand() ^ randombyte(); 

  

  

        for (i=0; i<sizeof(seed); i++) 

  

  

                seed[i] = idearand() ^ randombyte(); 

  

  

  

  

  

        close_idearand();       /* close IDEA random number generator */ 

  

  

  

  

  

        f = fopen(seedfile,"w");        /* open for writing binary */ 

  

  

        if (f==NULL)    /* did open fail? */ 

  

  

                return(-1);     /* error: no random number seed file available * 

  

  

  

#ifdef VMS 

  

  

        fseek (f, 0, SEEK_SET); 

  

  

#endif 

  

  

        /* Now at start of file again */ 

  

  

        fwrite(key,1,sizeof(key),f); 

  

  

        fwrite(seed,1,sizeof(seed),f); 

  

  

        fclose(f); 

  

  

        burn(key);              /* burn sensitive data on stack */ 

  

  

        burn(seed);             /* burn sensitive data on stack */ 

  

  

        return(0);      /* normal return */ 

  

  

}       /* strong_pseudorandom */ 

  

  

  

  

  

int make_random_ideakey(byte key[16]) 

  

  

/*      Make a random IDEA key.  Returns its length (a constant). */ 

  

  

{       int count; 

  

  

  

  

  

        if (strong_pseudorandom(key, IDEAKEYSIZE) == 0) 

  

  

                return(IDEAKEYSIZE); 

  

  

  

  

  

        fprintf(stderr,PSTR("Preparing random session key...")); 

  

  

  

  

  

        randaccum(IDEAKEYSIZE*8); /* get some random key bits */ 

  

  

  

  

  

        count=0; 

  

  

        while (++count <= IDEAKEYSIZE) 

  

  

                key[count] = randombyte(); 

  

  

  

  

  

        return(IDEAKEYSIZE); 

  

  

  

  

  

}       /* make_random_ideakey */ 

  

  

#endif 

  

  

  

  

  

  

  

  

int init_idea_stream(byte* buf, byte *ideakey, boolean decryp, IDEAkey Z, word16 

 iv) 

  

  

/*      Use IDEA in cipher feedback (CFB) mode to encrypt or decrypt a file. 

  

  

        The encrypted material starts out with a 64-bit random prefix, which 

  

  

        serves as an encrypted random CFB initialization vector, and 

  

  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -