added first file signing support

This commit is contained in:
schneider 2011-08-02 20:27:07 +02:00
parent be9356308c
commit ddbbc7f809
3 changed files with 110 additions and 88 deletions

View File

@ -1,18 +1,13 @@
CC = gcc CC = gcc
LD = gcc CFLAGS = -Wall -O2 -std=c99 -DSAFE
LDFLAGS = -Wall -O2 -std=c99 EXE = xxtea
EXES = main FILES = main.c xxtea.c
OBJS = main.o xxtea.o
TESTFILE= test.out TESTFILE= test.out
all: $(EXES) all: $(FILES)
$(CC) $(CFLAGS) $(FILES) -o $(EXE)
% : %.c
$(LD) $(LDFLAGS) -o $@ $<
clean: clean:
rm -f $(EXES) $(TESTFILE) rm -f $(EXE) $(OBJS)
tests: all
./xxtea -o $(TESTFILE) test/in.1
cmp $(TESTFILE) test/out.1
$(RM) $(TESTFILE)

View File

@ -15,10 +15,10 @@
#include <stdint.h> #include <stdint.h>
#include <getopt.h> #include <getopt.h>
#include "xxtea.h"
// default block size // default block size
void btea(uint32_t *v, int n, uint32_t const k[4]);
void hexkey(char *string, uint32_t k[4]); void hexkey(char *string, uint32_t k[4]);
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
@ -28,14 +28,15 @@ int main(int argc, char *argv[]) {
char *prog; char *prog;
char c; /* for getopt */ char c; /* for getopt */
uint32_t k[4]; /* key */ uint32_t k[4]; /* key */
uint32_t *buf; uint8_t *buf;
/* Default values */ /* Default values */
char verbose=0; // be silent char verbose=0; // be silent
k[0]=0; k[1]=0; k[2]=0; k[3]=0; k[0]=0; k[1]=0; k[2]=0; k[3]=0;
char block=16;
char *outfile=NULL; // outfile == infile char *outfile=NULL; // outfile == infile
int decrypt=0; int decrypt=0;
int encrypt=0;
int sign=0;
/* init section */ /* init section */
prog=argv[0]; prog=argv[0];
@ -46,7 +47,7 @@ int main(int argc, char *argv[]) {
} }
/* The big getopt loop */ /* The big getopt loop */
while ((c = getopt(argc, argv, "vhdk:b:o:")) != EOF) while ((c = getopt(argc, argv, "vhesdk:o:")) != EOF)
switch (c) { switch (c) {
case 'v': case 'v':
verbose++; verbose++;
@ -56,14 +57,18 @@ int main(int argc, char *argv[]) {
decrypt=1; decrypt=1;
break; break;
case 'e':
encrypt=1;
break;
case 's':
sign=1;
break;
case 'k': case 'k':
hexkey(optarg, k); hexkey(optarg, k);
break; break;
case 'b':
block=atoi(optarg);
break;
case 'o': case 'o':
outfile=optarg; outfile=optarg;
break; break;
@ -74,10 +79,11 @@ int main(int argc, char *argv[]) {
"This program en/decrypts a file with the XXTEA algorithm\n" "This program en/decrypts a file with the XXTEA algorithm\n"
"\n\n" "\n\n"
"-v Be verbose (-v -v = even more)\n" "-v Be verbose (-v -v = even more)\n"
"-d Decrypt (instead of encrypt)\n" "-d Decrypt file\n"
"-e Encrypt file\n"
"-s Sign file\n\n"
"-o file Output to <file>. (Default: overwrite input file)\n" "-o file Output to <file>. (Default: overwrite input file)\n"
"-k key 128bit hex key.\n" "-k key 128bit hex key.\n"
"-b block Set blocksize. (Default: file size)\n"
"-h This help\n\n" "-h This help\n\n"
"\n",prog); "\n",prog);
exit(255); exit(255);
@ -91,6 +97,15 @@ int main(int argc, char *argv[]) {
exit(254); exit(254);
}; };
if( !(decrypt||encrypt||sign) ){
fprintf(stderr, "No operation specified!\n");
exit(254);
}
if( decrypt && (encrypt || sign) ){
fprintf(stderr, "Can not decrypt and sign or decrypt and encrypt!\n");
exit(254);
}
if(outfile){ if(outfile){
if ((fp = fopen(argv[0],"rb")) == NULL){ if ((fp = fopen(argv[0],"rb")) == NULL){
fprintf(stderr,"Error: Can't open file %s\n",argv[0]); fprintf(stderr,"Error: Can't open file %s\n",argv[0]);
@ -108,53 +123,92 @@ int main(int argc, char *argv[]) {
ofp=fp; ofp=fp;
}; };
if(block==0){ fseek(fp, 0L, SEEK_END);
fseek(fp, 0L, SEEK_END); int filesize = ftell(fp);
block = ftell(fp)/sizeof(*buf); // XXX: padding! fseek(fp, 0L, SEEK_SET);
fseek(fp, 0L, SEEK_SET);
}; if (verbose)
buf=malloc(sizeof(*buf)*block); fprintf(stderr,"file size=%d\n", filesize);
int words = (filesize+3)/sizeof(uint32_t);
int bytes = sizeof(uint32_t)*words;
if (verbose)
fprintf(stderr,"byte count=%d word count=%d\n", bytes, words);
buf=malloc(bytes);
if(!buf){ if(!buf){
fprintf(stderr,"Error: malloc() failed.\n"); fprintf(stderr,"Error: malloc() failed.\n");
exit(253);
}; };
if (verbose) if (verbose)
fprintf(stderr,"Key: %08x %08x %08x %08x\n",k[0],k[1],k[2],k[3]); fprintf(stderr,"Key: %08x %08x %08x %08x\n",k[0],k[1],k[2],k[3]);
int cnt; if( sign ){
if (verbose) if (verbose)
fprintf(stderr,"Encrypting: "); fprintf(stderr,"Signing: ");
memset(buf, 0, bytes);
int cnt = fread(buf,sizeof(*buf),filesize,fp);
uint32_t mac[4];
xxtea_cbcmac(mac, (uint32_t*)buf, words, k);
do{ if (verbose)
cnt=fread(buf,sizeof(*buf),block,fp); // XXX: deal with non-block-sized? fprintf(stderr,"MAC: %08x %08x %08x %08x\n",mac[0],mac[1],mac[2],mac[3]);
if(cnt<0){
fprintf(stderr, "Error: read failed\n");
exit(253);
};
if(verbose)
fprintf(stderr,"cnt=%d:",cnt);
/* if(cnt%sizeof(*buf)!=0){
fprintf(stderr,"Whoops. needs padding: cnt=%d, mod=%d\n",cnt,cnt%sizeof(*buf));
}; */
btea(buf, decrypt?-cnt:cnt, k);
if(!outfile) // in-place crypting... if(!outfile) // in-place crypting...
if (fseek(fp,-cnt*sizeof(*buf),SEEK_CUR) != 0){ if( fseek(fp, 0L, SEEK_SET) != 0){
fprintf(stderr, "Error: Seek failed\n"); fprintf(stderr, "Error: Seek failed\n");
exit(253); exit(253);
} }
if (fwrite(buf,sizeof(*buf),cnt,ofp) != cnt){ if (fwrite(buf,sizeof(*buf),bytes,ofp) != bytes){
fprintf(stderr, "Error: CRC write failed\n"); fprintf(stderr, "Error: write failed\n");
exit(253);
}
if (fwrite(mac,sizeof(*mac),4,ofp) != 4*sizeof(*mac)){
fprintf(stderr, "Error: write failed\n");
exit(253); exit(253);
} }
if(verbose) fprintf(stderr,".\n"); if(verbose) fprintf(stderr,".\n");
}while(cnt==block); }
if( encrypt ){
int cnt, block;
if (verbose)
fprintf(stderr,"Encrypting: ");
do{
cnt=fread(buf,sizeof(*buf),block,fp); // XXX: deal with non-block-sized?
if(cnt<0){
fprintf(stderr, "Error: read failed\n");
exit(253);
};
if(verbose)
fprintf(stderr,"cnt=%d:",cnt);
/* if(cnt%sizeof(*buf)!=0){
fprintf(stderr,"Whoops. needs padding: cnt=%d, mod=%d\n",cnt,cnt%sizeof(*buf));
}; */
//btea(buf, decrypt?-cnt:cnt, k);
if(!outfile) // in-place crypting...
if (fseek(fp,-cnt*sizeof(*buf),SEEK_CUR) != 0){
fprintf(stderr, "Error: Seek failed\n");
exit(253);
}
if (fwrite(buf,sizeof(*buf),cnt,ofp) != cnt){
fprintf(stderr, "Error: CRC write failed\n");
exit(253);
}
if(verbose) fprintf(stderr,".\n");
}while(cnt==block);
}
if(verbose) if(verbose)
fprintf(stderr,"done\n"); fprintf(stderr,"done\n");
@ -166,43 +220,6 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (k[(p&3)^e] ^ z)))
void btea(uint32_t *v, int n, uint32_t const k[4]) {
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n > 1) { /* Coding Part */
rounds = 6 + 52/n;
sum = 0;
z = v[n-1];
do {
sum += DELTA;
e = (sum >> 2) & 3;
for (p=0; p<n-1; p++) {
y = v[p+1];
z = v[p] += MX;
}
y = v[0];
z = v[n-1] += MX;
} while (--rounds);
} else if (n < -1) { /* Decoding Part */
n = -n;
rounds = 6 + 52/n;
sum = rounds*DELTA;
y = v[0];
do {
e = (sum >> 2) & 3;
for (p=n-1; p>0; p--) {
z = v[p-1];
y = v[p] -= MX;
}
z = v[n-1];
y = v[0] -= MX;
} while ((sum -= DELTA) != 0);
}
}
void hexkey(char *string, uint32_t k[4]){ void hexkey(char *string, uint32_t k[4]){
int idx=0; int idx=0;
int kidx=0; int kidx=0;

10
tools/crypto/xxtea.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef _XXTEA_H_
#define _XXTEA_H_
void xxtea_cbcmac(uint32_t mac[4], uint32_t *data,
uint32_t len, uint32_t const key[4]);
void xxtea_encode_words(uint32_t *v, int n, uint32_t const k[4]);
void xxtea_decode_words(uint32_t *v, int n, uint32_t const k[4]);
#endif