67 lines
1.8 KiB
C
67 lines
1.8 KiB
C
|
|
#include <stdio.h>
|
||
|
|
#include <stdint.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <string.h>
|
||
|
|
#include <unistd.h>
|
||
|
|
#include <fcntl.h>
|
||
|
|
|
||
|
|
#define DELTA 0x9E3779B9
|
||
|
|
#define ROUNDS 32
|
||
|
|
|
||
|
|
void decrypt(uint32_t v[2], uint32_t const key[4]) {
|
||
|
|
uint32_t v0 = v[0], v1 = v[1], sum = DELTA * ROUNDS;
|
||
|
|
for (int i = 0; i < ROUNDS; 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 encrypt(uint32_t v[2], uint32_t const key[4]) {
|
||
|
|
uint32_t v0 = v[0], v1 = v[1], sum = 0;
|
||
|
|
for (int i = 0; i < ROUNDS; 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 process_file(const char *mode, const char *keyfile, const char *inputfile, const char *outputfile) {
|
||
|
|
uint32_t key[4];
|
||
|
|
uint32_t block[2];
|
||
|
|
int fd_key = open(keyfile, O_RDONLY);
|
||
|
|
int fd_in = open(inputfile, O_RDONLY);
|
||
|
|
int fd_out = open(outputfile, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||
|
|
|
||
|
|
if (fd_key < 0 || fd_in < 0 || fd_out < 0) {
|
||
|
|
perror("Error opening file");
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
read(fd_key, key, sizeof(key));
|
||
|
|
close(fd_key);
|
||
|
|
|
||
|
|
while (read(fd_in, block, sizeof(block)) == sizeof(block)) {
|
||
|
|
if (strcmp(mode, "-d") == 0) {
|
||
|
|
decrypt(block, key);
|
||
|
|
} else {
|
||
|
|
encrypt(block, key);
|
||
|
|
}
|
||
|
|
write(fd_out, block, sizeof(block));
|
||
|
|
}
|
||
|
|
close(fd_in);
|
||
|
|
close(fd_out);
|
||
|
|
}
|
||
|
|
|
||
|
|
int main(int argc, char *argv[]) {
|
||
|
|
if (argc != 5) {
|
||
|
|
fprintf(stderr, "Usage: %s -e|-d filekey file1 file2\n", argv[0]);
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
process_file(argv[1], argv[2], argv[3], argv[4]);
|
||
|
|
return 0;
|
||
|
|
}
|