xxtea: moved lib to host util
This commit is contained in:
parent
13df9eec9d
commit
d1cbe5de60
|
@ -1,7 +1,7 @@
|
|||
CC = gcc
|
||||
LD = gcc
|
||||
LDFLAGS = -Wall -O2 -std=c99
|
||||
EXES = xxtea
|
||||
EXES = main
|
||||
TESTFILE= test.out
|
||||
|
||||
all: $(EXES)
|
||||
|
|
|
@ -0,0 +1,238 @@
|
|||
/* simple XXTEA en/decrypt utility
|
||||
*
|
||||
* BSD Licence
|
||||
*
|
||||
* btea function is from
|
||||
* <https://secure.wikimedia.org/wikipedia/en/wiki/XXTEA#Reference_code>
|
||||
*
|
||||
* (c) by Sec <sec@42.org> 6/2011
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <getopt.h>
|
||||
|
||||
// default block size
|
||||
|
||||
void btea(uint32_t *v, int n, uint32_t const k[4]);
|
||||
void hexkey(char *string, uint32_t k[4]);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
FILE *fp;
|
||||
FILE *ofp;
|
||||
|
||||
char *prog;
|
||||
char c; /* for getopt */
|
||||
uint32_t k[4]; /* key */
|
||||
uint32_t *buf;
|
||||
|
||||
/* Default values */
|
||||
char verbose=0; // be silent
|
||||
k[0]=0; k[1]=0; k[2]=0; k[3]=0;
|
||||
char block=16;
|
||||
char *outfile=NULL; // outfile == infile
|
||||
int decrypt=0;
|
||||
|
||||
/* init section */
|
||||
prog=argv[0];
|
||||
if(!prog)prog="xxtea";
|
||||
if(strrchr(prog,'/')){
|
||||
prog=strrchr(argv[0],'/');
|
||||
prog++;
|
||||
}
|
||||
|
||||
/* The big getopt loop */
|
||||
while ((c = getopt(argc, argv, "vhdk:b:o:")) != EOF)
|
||||
switch (c) {
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
decrypt=1;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
hexkey(optarg, k);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
block=atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
outfile=optarg;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
default:
|
||||
fprintf(stderr, "Usage: %s [options] filename\n\n"
|
||||
"This program en/decrypts a file with the XXTEA algorithm\n"
|
||||
"\n\n"
|
||||
"-v Be verbose (-v -v = even more)\n"
|
||||
"-d Decrypt (instead of encrypt)\n"
|
||||
"-o file Output to <file>. (Default: overwrite input file)\n"
|
||||
"-k key 128bit hex key.\n"
|
||||
"-b block Set blocksize. (Default: file size)\n"
|
||||
"-h This help\n\n"
|
||||
"\n",prog);
|
||||
exit(255);
|
||||
|
||||
}
|
||||
|
||||
argc -= optind; argv += optind;
|
||||
|
||||
if (argc !=1){
|
||||
fprintf(stderr,"Error: No filename given!\n");
|
||||
exit(254);
|
||||
};
|
||||
|
||||
if(outfile){
|
||||
if ((fp = fopen(argv[0],"rb")) == NULL){
|
||||
fprintf(stderr,"Error: Can't open file %s\n",argv[0]);
|
||||
exit(253);
|
||||
}
|
||||
if ((ofp = fopen(outfile,"wb")) == NULL){
|
||||
fprintf(stderr,"Error: Can't open file %s\n",argv[0]);
|
||||
exit(253);
|
||||
}
|
||||
}else{
|
||||
if ((fp = fopen(argv[0],"r+b")) == NULL){
|
||||
fprintf(stderr,"Error: Can't open file %s\n",argv[0]);
|
||||
exit(253);
|
||||
}
|
||||
ofp=fp;
|
||||
};
|
||||
|
||||
if(block==0){
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
block = ftell(fp)/sizeof(*buf); // XXX: padding!
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
};
|
||||
buf=malloc(sizeof(*buf)*block);
|
||||
|
||||
if(!buf){
|
||||
fprintf(stderr,"Error: malloc() failed.\n");
|
||||
};
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr,"Key: %08x %08x %08x %08x\n",k[0],k[1],k[2],k[3]);
|
||||
|
||||
int cnt;
|
||||
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)
|
||||
fprintf(stderr,"done\n");
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if(outfile)
|
||||
fclose(ofp);
|
||||
|
||||
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]){
|
||||
int idx=0;
|
||||
int kidx=0;
|
||||
int kctr=0;
|
||||
int value;
|
||||
char ch;
|
||||
|
||||
while ((ch=string[idx++])!=0){
|
||||
if(ch == ' ')
|
||||
continue;
|
||||
if(ch == '\t')
|
||||
continue;
|
||||
|
||||
if (ch >= '0' && ch <= '9')
|
||||
value = (ch - '0');
|
||||
else if (ch >= 'A' && ch <= 'F')
|
||||
value = (ch - 'A' + 10);
|
||||
else if (ch >= 'a' && ch <= 'f')
|
||||
value = (ch - 'a' + 10);
|
||||
else
|
||||
continue;
|
||||
|
||||
|
||||
k[kidx]=(k[kidx]<<4)+value;
|
||||
kctr++;
|
||||
if(kctr>=8){
|
||||
kctr=0;
|
||||
kidx++;
|
||||
if(kidx>4)
|
||||
return;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -8,231 +8,95 @@
|
|||
* (c) by Sec <sec@42.org> 6/2011
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <getopt.h>
|
||||
#include "xxtea.h"
|
||||
|
||||
// default block size
|
||||
#ifdef SAFE
|
||||
uint32_t htonl(uint32_t v)
|
||||
{
|
||||
uint32_t r=0;
|
||||
r |= (v>> 0)&0xFF; r<<=8;
|
||||
r |= (v>> 8)&0xFF; r<<=8;
|
||||
r |= (v>>16)&0xFF; r<<=8;
|
||||
r |= (v>>24)&0xFF;
|
||||
return r;
|
||||
}
|
||||
#else
|
||||
uint32_t htonl(uint32_t v){
|
||||
__asm("rev %[value], %[value];" \
|
||||
: [value] "+r" (v) : );
|
||||
return v;
|
||||
};
|
||||
#endif
|
||||
|
||||
void btea(uint32_t *v, int n, uint32_t const k[4]);
|
||||
void hexkey(char *string, uint32_t k[4]);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
FILE *fp;
|
||||
FILE *ofp;
|
||||
void htonlp(uint32_t *v, uint8_t n)
|
||||
{
|
||||
while(n--){
|
||||
v[n] = htonl(v[n]);
|
||||
}
|
||||
}
|
||||
|
||||
char *prog;
|
||||
char c; /* for getopt */
|
||||
uint32_t k[4]; /* key */
|
||||
uint32_t *buf;
|
||||
|
||||
/* Default values */
|
||||
char verbose=0; // be silent
|
||||
k[0]=0; k[1]=0; k[2]=0; k[3]=0;
|
||||
char block=16;
|
||||
char *outfile=NULL; // outfile == infile
|
||||
int decrypt=0;
|
||||
|
||||
/* init section */
|
||||
prog=argv[0];
|
||||
if(!prog)prog="xxtea";
|
||||
if(strrchr(prog,'/')){
|
||||
prog=strrchr(argv[0],'/');
|
||||
prog++;
|
||||
}
|
||||
|
||||
/* The big getopt loop */
|
||||
while ((c = getopt(argc, argv, "vhdk:b:o:")) != EOF)
|
||||
switch (c) {
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
decrypt=1;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
hexkey(optarg, k);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
block=atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
outfile=optarg;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
default:
|
||||
fprintf(stderr, "Usage: %s [options] filename\n\n"
|
||||
"This program en/decrypts a file with the XXTEA algorithm\n"
|
||||
"\n\n"
|
||||
"-v Be verbose (-v -v = even more)\n"
|
||||
"-d Decrypt (instead of encrypt)\n"
|
||||
"-o file Output to <file>. (Default: overwrite input file)\n"
|
||||
"-k key 128bit hex key.\n"
|
||||
"-b block Set blocksize. (Default: file size)\n"
|
||||
"-h This help\n\n"
|
||||
"\n",prog);
|
||||
exit(255);
|
||||
|
||||
}
|
||||
|
||||
argc -= optind; argv += optind;
|
||||
|
||||
if (argc !=1){
|
||||
fprintf(stderr,"Error: No filename given!\n");
|
||||
exit(254);
|
||||
};
|
||||
|
||||
if(outfile){
|
||||
if ((fp = fopen(argv[0],"rb")) == NULL){
|
||||
fprintf(stderr,"Error: Can't open file %s\n",argv[0]);
|
||||
exit(253);
|
||||
}
|
||||
if ((ofp = fopen(outfile,"wb")) == NULL){
|
||||
fprintf(stderr,"Error: Can't open file %s\n",argv[0]);
|
||||
exit(253);
|
||||
}
|
||||
}else{
|
||||
if ((fp = fopen(argv[0],"r+b")) == NULL){
|
||||
fprintf(stderr,"Error: Can't open file %s\n",argv[0]);
|
||||
exit(253);
|
||||
}
|
||||
ofp=fp;
|
||||
};
|
||||
|
||||
if(block==0){
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
block = ftell(fp)/sizeof(*buf); // XXX: padding!
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
};
|
||||
buf=malloc(sizeof(*buf)*block);
|
||||
|
||||
if(!buf){
|
||||
fprintf(stderr,"Error: malloc() failed.\n");
|
||||
};
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr,"Key: %08x %08x %08x %08x\n",k[0],k[1],k[2],k[3]);
|
||||
|
||||
int cnt;
|
||||
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)
|
||||
fprintf(stderr,"done\n");
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if(outfile)
|
||||
fclose(ofp);
|
||||
|
||||
return 0;
|
||||
void xxtea_cbcmac(uint32_t mac[4], uint32_t *data,
|
||||
uint32_t len, uint32_t const key[4])
|
||||
{
|
||||
if( len & 0x03 )
|
||||
return;
|
||||
mac[0]=0;mac[1]=0;mac[2]=0;mac[3]=0;
|
||||
for(int i=0; i<len;){
|
||||
mac[0] ^= data[i++];
|
||||
mac[1] ^= data[i++];
|
||||
mac[2] ^= data[i++];
|
||||
mac[3] ^= data[i++];
|
||||
xxtea_encode_words(mac, 4, key);
|
||||
}
|
||||
}
|
||||
|
||||
#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]) {
|
||||
void xxtea_encode_words(uint32_t *v, int n, uint32_t const k[4])
|
||||
{
|
||||
if(k[0] == 0 && k[1] == 0 && k[2] == 0 && k[3] == 0) return;
|
||||
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;
|
||||
|
||||
htonlp(v ,n);
|
||||
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];
|
||||
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);
|
||||
}
|
||||
z = v[n-1] += MX;
|
||||
} while (--rounds);
|
||||
htonlp(v ,n);
|
||||
}
|
||||
|
||||
void hexkey(char *string, uint32_t k[4]){
|
||||
int idx=0;
|
||||
int kidx=0;
|
||||
int kctr=0;
|
||||
int value;
|
||||
char ch;
|
||||
void xxtea_decode_words(uint32_t *v, int n, uint32_t const k[4])
|
||||
{
|
||||
if(k[0] == 0 && k[1] == 0 && k[2] == 0 && k[3] == 0) return;
|
||||
uint32_t y, z, sum;
|
||||
unsigned p, rounds, e;
|
||||
htonlp(v ,n);
|
||||
|
||||
while ((ch=string[idx++])!=0){
|
||||
if(ch == ' ')
|
||||
continue;
|
||||
if(ch == '\t')
|
||||
continue;
|
||||
|
||||
if (ch >= '0' && ch <= '9')
|
||||
value = (ch - '0');
|
||||
else if (ch >= 'A' && ch <= 'F')
|
||||
value = (ch - 'A' + 10);
|
||||
else if (ch >= 'a' && ch <= 'f')
|
||||
value = (ch - 'a' + 10);
|
||||
else
|
||||
continue;
|
||||
|
||||
|
||||
k[kidx]=(k[kidx]<<4)+value;
|
||||
kctr++;
|
||||
if(kctr>=8){
|
||||
kctr=0;
|
||||
kidx++;
|
||||
if(kidx>4)
|
||||
return;
|
||||
};
|
||||
};
|
||||
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);
|
||||
htonlp(v ,n);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue