back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
path: root/encryption.c
blob: 972414ceb9777b9ef8f41b32ee8a4acbb4ffc1e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <sys/mman.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>

union key_type {
    unsigned int number;
    char bytes[sizeof(int)];
};

static void fill_in_some_byte(int remaining_bytes, unsigned int *data,
                              union key_type key)
{
    char *start_data = (char*) data;
    switch(remaining_bytes) {
    case 3:
       start_data[2] ^= key.bytes[2];
    case 2:
       start_data[1] ^= key.bytes[1];
    case 1:
       *start_data ^= key.bytes[0];
    }
}

static int calculate_memory(int block_counter, int size, int pos)
{
    return block_counter*size + (pos+1)*sizeof(int);
}

int main(int argc, char **argv)
{
    int fd, size, pgs, offset, pos, block_counter, next_used_memory;
    unsigned int *data;
    union key_type key;
    struct stat sb;
    size = 4096;
    offset = 0;
    block_counter = 0;
    key.number = ~ (unsigned int) strtol(argv[2], NULL, 10);
    pgs = getpagesize();
    size = ((size-1) / pgs+1) * pgs;
    if(argc != 3) {
        perror("enter only three params");
        return 1;
    }
    fd = open(argv[1], O_RDWR);
    if(fd == -1) {
        perror("can't open file");
        return 2;
    }
    fstat(fd, &sb);
    while(offset < sb.st_size-1) {
        data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
        if(data == MAP_FAILED) {
            perror("mapping error");
            return 3;
        }
        pos = 0;
        next_used_memory = calculate_memory(block_counter, size, pos);
        while(next_used_memory <= sb.st_size && next_used_memory <= size) {
            data[pos] ^= key.number;
            ++pos;
            next_used_memory = calculate_memory(block_counter, size, pos);
        }
        if(next_used_memory > sb.st_size && next_used_memory <= size) {
            fill_in_some_byte(sizeof(int) - (next_used_memory - sb.st_size),
                              data+pos, key);
        }
        munmap(data, size);
        offset += size;
        ++block_counter;
    }
    close(fd);
    return 0;
}