📄 des.c
字号:
/* des.c *//* Copyright (C) 1993 Eric Young - see README for more details */#include <stdio.h>#ifdef VMS#include <types.h>#include <stat.h>#else#ifndef _IRIX#include <sys/types.h>#endif#include <sys/stat.h>#endif#include "des.h"#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)#include <string.h>#define bcopy(f,t,n) memcpy(t,f,(size_t)(n))#define bzero(s,n) memset(s,0,(size_t)(n))#define bcmp(a,b,n) memcmp(a, b,(size_t)(n))#define index(s,c) strchr(s,c)#endif#ifdef PROTOint usage(void);int doencryption(void);int uufwrite(char *data, int size, int num, FILE *fp);int uufwriteEnd(FILE *fp);int uufread(char *out,int size,int num,FILE *fp);int uuencode(unsigned char *in,int num,unsigned char *out);int uudecode(unsigned char *in,int num,unsigned char *out);#elseint usage();int doencryption();int uufwrite();int uufwriteEnd();int uufread();int uuencode();int uudecode();#endif#ifdef VMS#define EXIT(a) exit(a&0x10000000)#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;char *in=NULL,*out=NULL;FILE *DES_IN,*DES_OUT,*CKSUM_OUT;char uuname[200];char uubuf[50];int uubufnum;#define INUUBUFN (45*100)#define OUTUUBUF (65*100)char b[OUTUUBUF];char bb[300];des_cblock cksum={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};char cksumname[200]="";int cflag,eflag,dflag,kflag,bflag,fflag,sflag,uflag,flag3,hflag,error;main(argc,argv)int argc;char *argv[]; { int i; struct stat ins,outs; char *p; cflag=eflag=dflag=kflag=hflag=bflag=fflag=sflag=uflag=flag3=0,error=0; bzero(key,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; /* bflag=0; */ 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 'E': eflag=1; longk=1; break; case 'd': dflag=1; break; case 'D': dflag=1; longk=1; break; case 'b': bflag=1; flag3=0; 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 usage(); 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); }usage() { char **u; static char *usage[]={"des <options> [input-file [output-file]]","options:","-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","-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=usage; *u; u++) { fputs(*u,stderr); fputc('\n',stderr); } EXIT(1); }doencryption() { register int i; des_key_schedule ks,ks2; unsigned char iv[8],iv2[8],iv3[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); bzero(k2,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); bzero(k2,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); bzero(key,sizeof(key)); bzero(kk,sizeof(kk)); /* woops - A bug that does not showup under unix :-( */ bzero(iv,sizeof(iv)); bzero(iv2,sizeof(iv2)); bzero(iv3,sizeof(iv3)); l=1; rem=0; /* first read */ if (eflag || (!dflag && cflag)) { for (;;) { num=l=fread(&(buf[rem]),1,BUFSIZE,DES_IN); l+=rem; num+=rem; if (l < 0) { perror("read error"); Exit=6; goto problems; } rem=l%8; len=l-rem; if (feof(DES_IN)) { srand(time(NULL)); for (i=7-rem; i>0; i--) buf[l++]=rand()&0xff; buf[l++]=rem; ex=1; len+=rem; } else l-=rem; if (cflag) { des_cbc_cksum((C_Block *)buf,(C_Block *)cksum, (long)len,ks,(C_Block *)cksum); if (!eflag) { if (feof(DES_IN)) break; else continue; } } if (bflag && !flag3) for (i=0; i<l; i+=8) des_ecb_encrypt( (des_cblock *)&(buf[i]), (des_cblock *)&(obuf[i]), ks,do_encrypt);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -