83 lines
2.2 KiB
C
83 lines
2.2 KiB
C
|
#include <stdint.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#define DELTA 0x9E3779B9
|
||
|
|
||
|
void xtea_encrypt_block(uint32_t *v, const uint32_t key[4]) {
|
||
|
uint32_t v0 = v[0], v1 = v[1], sum = 0;
|
||
|
for (unsigned i = 0; i < 32; i++) {
|
||
|
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
|
||
|
sum += DELTA;
|
||
|
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
|
||
|
}
|
||
|
v[0] = v0;
|
||
|
v[1] = v1;
|
||
|
}
|
||
|
|
||
|
void xtea_decrypt_block(uint32_t *v, const uint32_t key[4]) {
|
||
|
uint32_t v0 = v[0], v1 = v[1];
|
||
|
uint32_t sum = DELTA * 32;
|
||
|
for (unsigned i = 0; i < 32; i++) {
|
||
|
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
|
||
|
sum -= DELTA;
|
||
|
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
|
||
|
}
|
||
|
v[0] = v0;
|
||
|
v[1] = v1;
|
||
|
}
|
||
|
|
||
|
void xtea_process(int encrypt, const char *keyfile, const char *infile, const char *outfile) {
|
||
|
uint32_t key[4];
|
||
|
|
||
|
FILE *fk = fopen(keyfile, "rb");
|
||
|
if (!fk || fread(key, sizeof *key, 4, fk) != 4) {
|
||
|
fprintf(stderr, "Erreur lecture clé\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
fclose(fk);
|
||
|
|
||
|
FILE *fin = fopen(infile, "rb");
|
||
|
FILE *fout = fopen(outfile, "wb");
|
||
|
if (!fin || !fout) {
|
||
|
fprintf(stderr, "Erreur ouverture fichiers\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
uint8_t block[8];
|
||
|
size_t n;
|
||
|
|
||
|
while ((n = fread(block, 1, 8, fin)) == 8) {
|
||
|
xtea_encrypt_block((uint32_t*)block, key);
|
||
|
if (!encrypt)
|
||
|
xtea_decrypt_block((uint32_t*)block, key);
|
||
|
fwrite(block, 1, 8, fout);
|
||
|
}
|
||
|
|
||
|
if (encrypt) {
|
||
|
for (size_t i = n; i < 8 - 1; i++) {
|
||
|
block[i] = 0;
|
||
|
}
|
||
|
block[8 - 1] = 8 - n;
|
||
|
xtea_encrypt_block((uint32_t*)block, key);
|
||
|
fwrite(block, 1, 8, fout);
|
||
|
} else if (n > 0) {
|
||
|
fprintf(stderr, "Erreur : fichier chiffré mal aligné\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
fclose(fin);
|
||
|
fclose(fout);
|
||
|
}
|
||
|
|
||
|
int main(int argc, char *argv[])
|
||
|
{
|
||
|
if (argc != 5) {
|
||
|
fprintf(stderr, "Usage : %s -e|-d keyfile infile outfile\n", argv[0]);
|
||
|
return 1;
|
||
|
}
|
||
|
int enc = (strcmp(argv[1], "-e") == 0);
|
||
|
xtea_process(enc, argv[2], argv[3], argv[4]);
|
||
|
return 0;
|
||
|
}
|