📄 des.c
字号:
/* crypto/des/des.c */
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <stdlib.h>
#ifndef MSDOS
#include <unistd.h>
#else
#include <io.h>
#define RAND
#endif
#include <time.h>
#include "des_ver.h"
#ifdef VMS
#include <types.h>
#include <stat.h>
#else
#ifndef _IRIX
#include <sys/types.h>
#endif
#include <sys/stat.h>
#endif
#if defined(NOCONST)
#define const
#endif
#include "des.h"
#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
#include <string.h>
#endif
#ifdef RAND
#define random rand
#define srandom(s) srand(s)
#endif
#ifndef NOPROTO
void usage(void);
void doencryption(void);
int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp);
void uufwriteEnd(FILE *fp);
int uufread(unsigned char *out,int size,unsigned int num,FILE *fp);
int uuencode(unsigned char *in,int num,unsigned char *out);
int uudecode(unsigned char *in,int num,unsigned char *out);
void des_3cbc_encrypt(des_cblock *input,des_cblock *output,long length,
des_key_schedule sk1,des_key_schedule sk2,
des_cblock *ivec1,des_cblock *ivec2,int enc);
#else
void usage();
void doencryption();
int uufwrite();
void uufwriteEnd();
int uufread();
int uuencode();
int uudecode();
void des_3cbc_encrypt();
#endif
#ifdef VMS
#define EXIT(a) exit(a&0x10000000L)
#else
#define EXIT(a) exit(a)
#endif
#define BUFSIZE (8*1024)
#define VERIFY 1
#define KEYSIZ 8
#define KEYSIZB 1024 /* should hit tty line limit first :-) */
char key[KEYSIZB+1];
int do_encrypt,longk=0;
FILE *DES_IN,*DES_OUT,*CKSUM_OUT;
char uuname[200];
unsigned char uubuf[50];
int uubufnum=0;
#define INUUBUFN (45*100)
#define OUTUUBUF (65*100)
unsigned char b[OUTUUBUF];
unsigned char bb[300];
des_cblock cksum={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
char cksumname[200]="";
int vflag,cflag,eflag,dflag,kflag,bflag,fflag,sflag,uflag,flag3,hflag,error;
int main(argc, argv)
int argc;
char **argv;
{
int i;
struct stat ins,outs;
char *p;
char *in=NULL,*out=NULL;
vflag=cflag=eflag=dflag=kflag=hflag=bflag=fflag=sflag=uflag=flag3=0;
error=0;
memset(key,0,sizeof(key));
for (i=1; i<argc; i++)
{
p=argv[i];
if ((p[0] == '-') && (p[1] != '\0'))
{
p++;
while (*p)
{
switch (*(p++))
{
case '3':
flag3=1;
longk=1;
break;
case 'c':
cflag=1;
strncpy(cksumname,p,200);
p+=strlen(cksumname);
break;
case 'C':
cflag=1;
longk=1;
strncpy(cksumname,p,200);
p+=strlen(cksumname);
break;
case 'e':
eflag=1;
break;
case 'v':
vflag=1;
break;
case 'E':
eflag=1;
longk=1;
break;
case 'd':
dflag=1;
break;
case 'D':
dflag=1;
longk=1;
break;
case 'b':
bflag=1;
break;
case 'f':
fflag=1;
break;
case 's':
sflag=1;
break;
case 'u':
uflag=1;
strncpy(uuname,p,200);
p+=strlen(uuname);
break;
case 'h':
hflag=1;
break;
case 'k':
kflag=1;
if ((i+1) == argc)
{
fputs("must have a key with the -k option\n",stderr);
error=1;
}
else
{
int j;
i++;
strncpy(key,argv[i],KEYSIZB);
for (j=strlen(argv[i])-1; j>=0; j--)
argv[i][j]='\0';
}
break;
default:
fprintf(stderr,"'%c' unknown flag\n",p[-1]);
error=1;
break;
}
}
}
else
{
if (in == NULL)
in=argv[i];
else if (out == NULL)
out=argv[i];
else
error=1;
}
}
if (error) usage();
/* We either
* do checksum or
* do encrypt or
* do decrypt or
* do decrypt then ckecksum or
* do checksum then encrypt
*/
if (((eflag+dflag) == 1) || cflag)
{
if (eflag) do_encrypt=DES_ENCRYPT;
if (dflag) do_encrypt=DES_DECRYPT;
}
else
{
if (vflag)
{
#ifndef _Windows
fprintf(stderr,"des(1) built with %s\n",libdes_version);
#endif
EXIT(1);
}
else usage();
}
#ifndef _Windows
if (vflag) fprintf(stderr,"des(1) built with %s\n",libdes_version);
#endif
if ( (in != NULL) &&
(out != NULL) &&
#ifndef MSDOS
(stat(in,&ins) != -1) &&
(stat(out,&outs) != -1) &&
(ins.st_dev == outs.st_dev) &&
(ins.st_ino == outs.st_ino))
#else /* MSDOS */
(strcmp(in,out) == 0))
#endif
{
fputs("input and output file are the same\n",stderr);
EXIT(3);
}
if (!kflag)
if (des_read_pw_string(key,KEYSIZB+1,"Enter key:",eflag?VERIFY:0))
{
fputs("password error\n",stderr);
EXIT(2);
}
if (in == NULL)
DES_IN=stdin;
else if ((DES_IN=fopen(in,"r")) == NULL)
{
perror("opening input file");
EXIT(4);
}
CKSUM_OUT=stdout;
if (out == NULL)
{
DES_OUT=stdout;
CKSUM_OUT=stderr;
}
else if ((DES_OUT=fopen(out,"w")) == NULL)
{
perror("opening output file");
EXIT(5);
}
#ifdef MSDOS
/* This should set the file to binary mode. */
{
#include <fcntl.h>
if (!(uflag && dflag))
setmode(fileno(DES_IN),O_BINARY);
if (!(uflag && eflag))
setmode(fileno(DES_OUT),O_BINARY);
}
#endif
doencryption();
fclose(DES_IN);
fclose(DES_OUT);
EXIT(0);
}
void usage()
{
char **u;
static const char *Usage[]={
"des <options> [input-file [output-file]]",
"options:",
"-v : des(1) version number",
"-e : encrypt using sunOS compatible user key to DES key conversion.",
"-E : encrypt ",
"-d : decrypt using sunOS compatible user key to DES key conversion.",
"-D : decrypt ",
"-c[ckname] : generate a cbc_cksum using sunOS compatible user key to",
" DES key conversion and output to ckname (stdout default,",
" stderr if data being output on stdout). The checksum is",
" generated before encryption and after decryption if used",
" in conjunction with -[eEdD].",
"-C[ckname] : generate a cbc_cksum as for -c but compatible with -[ED].",
"-k key : use key 'key'",
"-h : the key that is entered will be a hexidecimal number",
" that is used directly as the des key",
"-u[uuname] : input file is uudecoded if -[dD] or output uuencoded data if -[eE]",
" (uuname is the filename to put in the uuencode header).",
"-b : encrypt using DES in ecb encryption mode, the defaut is cbc mode.",
"-3 : encrypt using tripple DES encryption. This uses 2 keys",
" generated from the input key. If the input key is less",
" than 8 characters long, this is equivelent to normal",
" encryption. Default is tripple cbc, -b makes it tripple ecb.",
NULL
};
for (u=(char **)Usage; *u; u++)
{
fputs(*u,stderr);
fputc('\n',stderr);
}
EXIT(1);
}
void doencryption()
{
#ifdef _LIBC
extern int srandom();
extern int random();
extern unsigned long time();
#endif
register int i;
des_key_schedule ks,ks2;
unsigned char iv[8],iv2[8];
char *p;
int num=0,j,k,l,rem,ll,len,last,ex=0;
des_cblock kk,k2;
FILE *O;
int Exit=0;
#ifndef MSDOS
static unsigned char buf[BUFSIZE+8],obuf[BUFSIZE+8];
#else
static unsigned char *buf=NULL,*obuf=NULL;
if (buf == NULL)
{
if ( (( buf=(unsigned char *)Malloc(BUFSIZE+8)) == NULL) ||
((obuf=(unsigned char *)Malloc(BUFSIZE+8)) == NULL))
{
fputs("Not enough memory\n",stderr);
Exit=10;
goto problems;
}
}
#endif
if (hflag)
{
j=(flag3?16:8);
p=key;
for (i=0; i<j; i++)
{
k=0;
if ((*p <= '9') && (*p >= '0'))
k=(*p-'0')<<4;
else if ((*p <= 'f') && (*p >= 'a'))
k=(*p-'a'+10)<<4;
else if ((*p <= 'F') && (*p >= 'A'))
k=(*p-'A'+10)<<4;
else
{
fputs("Bad hex key\n",stderr);
Exit=9;
goto problems;
}
p++;
if ((*p <= '9') && (*p >= '0'))
k|=(*p-'0');
else if ((*p <= 'f') && (*p >= 'a'))
k|=(*p-'a'+10);
else if ((*p <= 'F') && (*p >= 'A'))
k|=(*p-'A'+10);
else
{
fputs("Bad hex key\n",stderr);
Exit=9;
goto problems;
}
p++;
if (i < 8)
kk[i]=k;
else
k2[i-8]=k;
}
des_set_key((C_Block *)k2,ks2);
memset(k2,0,sizeof(k2));
}
else if (longk || flag3)
{
if (flag3)
{
des_string_to_2keys(key,(C_Block *)kk,(C_Block *)k2);
des_set_key((C_Block *)k2,ks2);
memset(k2,0,sizeof(k2));
}
else
des_string_to_key(key,(C_Block *)kk);
}
else
for (i=0; i<KEYSIZ; i++)
{
l=0;
k=key[i];
for (j=0; j<8; j++)
{
if (k&1) l++;
k>>=1;
}
if (l & 1)
kk[i]=key[i]&0x7f;
else
kk[i]=key[i]|0x80;
}
des_set_key((C_Block *)kk,ks);
memset(key,0,sizeof(key));
memset(kk,0,sizeof(kk));
/* woops - A bug that does not showup under unix :-( */
memset(iv,0,sizeof(iv));
memset(iv2,0,sizeof(iv2));
l=1;
rem=0;
/* first read */
if (eflag || (!dflag && cflag))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -