📄 aes.c
字号:
/* ------------------------------------------------------------------------- Copyright (c) 2002, Markus Lagler <markus.lagler@trivadis.com> Copyright (c) 2002, Tim Tassonis <timtas@dplanet.ch> All rights reserved. LICENSE TERMS The free distribution and use of this software in both source and binary form is allowed (with or without changes) provided that: 1. distributions of this source code include the above copyright notice, this list of conditions and the following disclaimer; 2. distributions in binary form include the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other associated materials; 3. the copyright holder's name is not used to endorse products built using this software without specific written permission. DISCLAIMER This software is provided 'as is' with no explcit or implied warranties in respect of any properties, including, but not limited to, correctness and fitness for purpose. -------------------------------------------------------------------------*/#include <stdio.h>#include <errno.h>#include <string.h>#ifndef WINDOWS#include <unistd.h>#endif#include <time.h>#include "aeslib.h"#include "lutil.h"#include "getopts.h"#include "version.h"char *read_stdin(int *buffer_bytes);char *read_file(char *filename,int *buffer_bytes);int ins_newlines(char *buf, int size);#ifdef WINDOWS/* Quick and dirty password check, maximum length is 255 bytes */#include <conio.h>char * getpass(const char *prompt){ int eol,j; signed int byte; static char password[255]; eol = 0; printf(prompt); for (j=0 ; eol == 0; j++) { byte = getch(); if (byte == 13 ) { eol=1; password[j] = '\0'; fflush(stdin); printf("\n"); } else { printf("*"); password[j] = byte; } } return password;}#endifint main(int argc, char **argv){ FILE *outfile = NULL; char infilename[255]; char outfilename[255]; int rc=0,opt; char *args = NULL; char *enc_buffer = NULL; char *dec_buffer = NULL; char *b64_buffer = NULL; char *in_buffer = NULL; int bytecount=0; int string_input=0,file_input=0,file_output=0; char password[17] = "\0"; int enc_len=0,dec_len=0,in_len=0; int block=0,base64=0,encrypt=0,decrypt=0; struct options opts[] = { { 1, "encrypt", "Encrypt the data", "e", 0 }, { 2, "decrypt", "Decrypt the data", "d", 0 }, { 3, "base64", "base64 encode/decode encrypted data", "b", 0 }, { 4, "block", "Format base64 data as lines of 60 bytes", "B", 0}, { 5, "password", "Password (if omitted, will prompt)", "p", 1 }, { 6, "string", "Input String (if omitted, stdin)", "s", 1 }, { 7, "file", "Input File (if ommitted, stdin)", "f", 1 }, { 8, "count", "Number of input bytes to read", "c", 1 }, { 9, "out", "Outputfile instead of stdout", "o", 1 }, {10, "version", "Show version information", "V", 0 }, { 0, NULL, NULL, NULL, 0 } }; while ( (opt = getopts(argc, argv, opts, &args)) != 0) { switch(opt) { case -1: printf("Unable to allocate memory.\n\n"); exit(1); break; case 1: encrypt=1; break; case 2: decrypt=1; break; case 3: base64=1; break; case 4: block=1; break; case 5: strncpy(password,args,16); password[16] = '\0'; break; case 6: if (file_input) { fprintf(stderr,"Only one of -s/-f may be given\n"); getopts_usage(argv[0], opts); exit(1); } string_input=1; in_len = strlen(args); in_buffer = malloc(in_len+1); memcpy(in_buffer,args,in_len); break; case 7: if (string_input) { fprintf(stderr,"Only one of -s/-f may be given\n"); getopts_usage(argv[0], opts); exit(1); } file_input=1; strncpy(infilename,args,255); infilename[255] = '\0'; break; case 8: if (sscanf(args,"%d",&bytecount) < 1) { fprintf(stderr,"Invalid value for -c: %s\n",args); getopts_usage(argv[0], opts); exit(1); } break; case 9: file_output=1; strncpy(outfilename,args,255); outfilename[255] = '\0'; break; case 10: fprintf(stderr,"aes %s\n",AES_VERSION); return 0; break; default: break; } } if (args) { free(args); } if ( (encrypt+decrypt) > 1 ) { fprintf(stderr,"Only one of -d/-e may be specified!\n"); getopts_usage(argv[0], opts); exit(1); } if ( base64 && !encrypt && block) { fprintf(stderr,"-n has no effect without -b and -e!\n"); getopts_usage(argv[0], opts); exit(1); } if ( (encrypt+decrypt) < 1 ) { fprintf(stderr,"One of -d/-e must be specified!\n"); getopts_usage(argv[0], opts); exit(1); } if (strlen(password) < 1 ) { strncpy(password,getpass("Enter password :"),16); password[16] = '\0'; } if (strlen(password) < 6 ) { fprintf(stderr,"A password of at least 6 bytes must be specified!\n"); getopts_usage(argv[0], opts); exit(1); } if (in_len == 0) { if (file_input) { in_buffer = read_file(infilename,&in_len); } else { in_buffer = read_stdin(&in_len); } } if (in_len < 1) { fprintf(stderr,"No input specified!\n"); getopts_usage(argv[0], opts); exit(1); } if ( (bytecount > 0 ) && (in_len > bytecount) ) { in_len = bytecount; } in_buffer[in_len] = '\0'; if (file_output) {#ifdef WINDOWS outfile = fopen(outfilename,"wb");#else outfile = fopen(outfilename,"w");#endif if (outfile == NULL) { fprintf(stderr,"Could no open outfile<%s>\n",outfilename); exit(1); } } if (encrypt) { enc_buffer = aes_enc(in_buffer, in_len, password, strlen(password), &enc_len); if (enc_buffer == NULL) { fprintf(stderr,"Encryption failed!\n"); exit(1); } if (base64) { b64_buffer = malloc(enc_len*2); rc = lutil_b64_ntop(enc_buffer,enc_len,b64_buffer,enc_len*2); if (block) { rc = ins_newlines(b64_buffer, strlen(b64_buffer)); } if (file_output) { fwrite(b64_buffer,1,rc,outfile); fprintf(outfile,"\n"); fclose(outfile); } else { fwrite(b64_buffer,1,rc,stdout); printf("\n"); } } else { if (file_output) { fwrite(enc_buffer,1,enc_len,outfile); fclose(outfile); } else { fwrite(enc_buffer,1,enc_len,stdout); } } } else if (decrypt) { if (base64) { enc_buffer = malloc(in_len); if (enc_buffer == NULL ) { fprintf(stderr,"Failed to allocate buffer for base64 decoding!"); exit(1); } else { memset(enc_buffer,0x0,in_len); } rc = lutil_b64_pton(in_buffer,enc_buffer,in_len); if (rc < 1) { fprintf(stderr,"Failed to base64-decode input(%d,%d)!\n",in_len,rc); exit(1); } enc_len=rc; } else { enc_buffer = in_buffer; enc_len = in_len; } /* The buffer must be > 16 bytes, otherwise it is definitely too small */ if (enc_len < 16 ) { fprintf(stderr,"Invalid decoding buffer (< 16 bytes)\n"); exit(1); } dec_buffer = aes_dec(enc_buffer,enc_len,password,strlen(password),&dec_len); if (dec_buffer == NULL) { fprintf(stderr,"Decryption failed!\n"); exit(1); } if (file_output) { fwrite(dec_buffer,1,dec_len,outfile); fclose(outfile); } else { fwrite(dec_buffer,1,dec_len,stdout); } } return 0;}char *read_stdin(int *buffer_bytes){#define MSG_BLOCK_SIZE 65025 static char *msgbuf; char *tmp_buffer; int tempfile; int temp_open=0; FILE *tfile;#ifdef WINDOWS char *tempfilename;#else char tempfilename[2000] = "/tmp/aes_inputXXXXXX" ;#endif int rc; int i; int bytes,tbytes=0,write_bytes; int msglen; int offset;#ifdef WINDOWS tempfilename = tempnam(NULL,"aes"); tfile = fopen(tempfilename,"wb"); if (tfile == NULL ) { return NULL; } temp_open = 1;#else tempfile = mkstemp(tempfilename); if (tempfile == -1) { return NULL; } tfile = fdopen(tempfile,"r+"); if (tfile == NULL ) { close(tempfile); rc = -2; goto exit; } temp_open = 1;#endif msglen = MSG_BLOCK_SIZE; offset = 0; tmp_buffer = malloc(MSG_BLOCK_SIZE); if (tmp_buffer == NULL) { rc= -3; goto exit; } i=0; while (!feof(stdin)) { bytes = fread(tmp_buffer,1,msglen,stdin); if (bytes > 0 ) { offset += bytes; write_bytes = fwrite(tmp_buffer,1,bytes,tfile); if ( write_bytes == -1 ) { rc = -4; goto exit; } tbytes += bytes; } } free(tmp_buffer); fclose(tfile); temp_open = 0; msglen = tbytes; msgbuf = malloc(msglen+1); if (msgbuf == NULL ) { rc = -5; goto exit; }#ifdef WINDOWS tfile = fopen(tempfilename,"rb");#else tfile = fopen(tempfilename,"r");#endif if (tfile == NULL ) { rc = -6; goto exit; } temp_open = 1; bytes = fread(msgbuf,1,msglen,tfile); if (bytes != msglen) { rc = -7; goto exit; } rc = bytes; goto exit;exit: if (temp_open) { fclose(tfile); } remove(tempfilename); *buffer_bytes = rc; if (rc >0 ) { return msgbuf; } else { return NULL; }}char *read_file(char *filename,int *buffer_bytes){ static char *msgbuf; FILE *ifile; int file_open=0; int rc; int i; int bytes; int msglen; int offset; msglen = MSG_BLOCK_SIZE; offset = 0;#ifdef WINDOWS ifile = fopen(filename,"rb");#else ifile = fopen(filename,"r");#endif if (ifile == NULL) { rc = -1; goto exit; *buffer_bytes = 0; } file_open=1; fseek(ifile, 0, SEEK_END); msglen = ftell(ifile); fseek(ifile, 0, SEEK_SET); i=0; /* need to add one byte to end of buffer to allow for null termination. */ msgbuf = malloc(msglen + 1); if (msgbuf == NULL ) { rc = -5; goto exit; } bytes = fread(msgbuf,1,msglen,ifile); if (bytes != msglen) { rc = -7; goto exit; } rc = bytes; goto exit;exit: if (file_open) { fclose(ifile); } *buffer_bytes = rc; if (rc >0 ) { return msgbuf; } else { return NULL; }}int ins_newlines(char *buf, int size) { int newsize; int i = 0, col; newsize = size + size / 60; if ((size % 60) != 0) { newsize++; } col = size / 60; (char *)buf = realloc(buf, newsize); while (i++ < col) { memmove(buf + 61 * i, buf + 60 * i + i - 1, newsize - 61 * i); buf[60 * i + i - 1] = 0x0a; } return newsize;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -