📄 crypto.c.txt
字号:
发信人: 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 + -