3
0
Fork 0
xnode/lib-build/tools/xxtea.c

172 lines
4 KiB
C
Raw Normal View History

2022-11-13 00:46:38 +00:00
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
void btea(uint32_t *v, int n, uint32_t const key[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;
sum -= DELTA;
} while (--rounds);
}
}
void convToQU32(uint32_t *v/*, int n*/,int *data,int dataOffset) {
for (int i=0;i<4;i++) {
int idx = dataOffset + i*4;
//uint32_t value = (data[idx]) + (data[idx+1] << 8) + (data[idx+2] << 16) + (data[idx+3] << 24);
uint32_t value = (data[idx+3]) + (data[idx+2] << 8) + (data[idx+1] << 16) + (data[idx+0] << 24);
printf("convToQU32 %08x \n", value);
v[i] = value;
}
}
#define XXTEA_NUM_ROUNDS 32
void xxteaDecrypt(unsigned long v[2],unsigned long net_key[4])
{
unsigned int i;
uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*XXTEA_NUM_ROUNDS;
for (i=0; i < XXTEA_NUM_ROUNDS; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + net_key[(sum>>11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + net_key[sum & 3]);
}
v[0]=v0; v[1]=v1;
}
int main (int argc, char *argv[] ) {
// Arguments parsing
if ( argc != 4 ) {
printf( "usage: %s encrypt|decrypt key message\n", argv[0] ); // prog name
printf( "note: parameters are pure hex and key should be 32 chars. \n");
return 1;
}
int operation = 0;
if (strcmp("encrypt", argv[1]) == 0) {
operation = 1;
}
if (strcmp("decrypt", argv[1]) == 0) {
operation = -1;
}
if (operation == 0) {
printf( "Could not parse first argument.\n");
return 1;
}
printf( "operation: %d.\n",operation);
char* keyBuffer = argv[2];
int keyBufferLength = strlen(keyBuffer);
if (keyBufferLength != 32) {
printf( "key should by 32 chars.\n");
return 1;
}
char* messageBuffer = argv[3];
int messageBufferLength = strlen(messageBuffer);
if (messageBufferLength < 16) {
printf( "message should be minimal 16 chars.\n");
return 1;
}
// Done arguments
// Convert data
int keyData[16];
int keyDataIndex = 0;
for (int i=0;i<keyBufferLength/2;i++) {
int value;
sscanf(keyBuffer+2*i,"%02x",&value);
keyData[keyDataIndex] = value;
keyDataIndex++;
}
printf( "Key data size %d\n", keyDataIndex );
for (int i=0;i<keyDataIndex;i++) {
printf( "%02x", keyData[i] );
}
printf("\n");
int messageData[512];
int messageDataIndex = 0;
for (int i=0;i<512;i++) {
messageData[i] = 0;
}
for (int i=0;i<messageBufferLength/2;i++) {
int value;
sscanf(messageBuffer+2*i,"%02x",&value);
messageData[messageDataIndex] = value;
messageDataIndex++;
}
printf( "Message data size %d\n", messageDataIndex );
for (int i=0;i<messageDataIndex;i++) {
printf( "%02x", messageData[i] );
}
printf("\n");
uint32_t key[4];
uint32_t data[4];
convToQU32(key,keyData,0);
convToQU32(data,messageData,0);
printf("OUT-ppre: ");
for (int i=0;i<4;i++) {
printf("%08x", data[i]);
}
printf("\n");
operation = operation* (messageDataIndex/4);
printf( "word length: %d\n",operation);
//btea(data,operation,key);
xxteaDecrypt(data,key);
printf("OUT-post: ");
for (int i=0;i<4;i++) {
printf("%08x", data[i]);
}
printf("\n");
printf("OUT-AS: ");
for (int i=0;i<4;i++) {
//printf("%02x ", data[i] & 255);
//printf("%02x ", data[i] >> 8 & 255);
//printf("%02x ", data[i] >> 16 & 255);
//printf("%02x ", data[i] >> 24 & 255);
printf("%c ", data[i] & 255);
printf("%c ", data[i] >> 8 & 255);
printf("%c ", data[i] >> 16 & 255);
printf("%c ", data[i] >> 24 & 255);
}
printf("\n");
return 0;
}