-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuoenc.c
150 lines (122 loc) · 4.19 KB
/
uoenc.c
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include "uocrypt.h"
#include "uoenc.h"
int main(int argc, char** argv) {
char *infile, *outfile = NULL;
FILE *in, *out;
/* 16 byes, plus two for newline and null */
char input[18], pass[16];
unsigned int total;
/* Parse argv */
if (argc < 2 || argc > 3) {
usage(argv[0]);
return 1;
} else {
infile = argv[1];
if (argc == 3)
outfile = argv[2];
else {
outfile = xmalloc(strlen(argv[1]) + 4);
strcpy(outfile, infile);
strcat(outfile, ".uo");
}
/* Test to see if the output file exists, open file handles for later */
in = fopen(infile, "rb");
out = fopen(outfile, "rb");
if (out) {
printf("Output file [%s] already exists.\nAborting operation.\n", outfile);
clean(in, out, outfile, argc);
return 2;
}
out = fopen(outfile, "wb");
}
#if DEBUG
printf("DEBUG: infile=%s\n", infile);
printf("DEBUG: outfile=%s\n", outfile);
#endif
/* Init gcrypt */
uocrypt_init();
/* Get password */
printf("Password: ");
fgets(input, sizeof input, stdin);
/* Hash it */
uocrypt_zero_pad(input, pass, sizeof pass);
uocrypt_hash_md5(pass, sizeof pass);
/* Do Work */
total = uoenc(pass, sizeof pass, in, out);
printf("Successfully encrypted %s to %s (%u bytes written).\n", infile, outfile, total);
/* Clean up and bail */
clean(in, out, outfile, argc);
return 0;
}
unsigned int uoenc(char *pass, size_t len, FILE *in, FILE *out) {
gcry_cipher_hd_t h;
gcry_error_t err;
unsigned char buffer[1024], encrypt[1024], iv[16];
unsigned short rbytes = 0, wbytes = 0;
unsigned int total = 0, pad = 0;
/* Open a cipher handle.. */
err = gcry_cipher_open(&h, GCRY_CIPHER_RIJNDAEL128, GCRY_CIPHER_MODE_CBC, 0);
/* Check for errors */
uocrypt_error(err);
#if DEBUG
printf("DEBUG: gcrypt handle opened\n");
printf("DEBUG: cipher keylen=%u\n", gcry_cipher_get_algo_keylen(GCRY_CIPHER_RIJNDAEL128));
printf("DEBUG: cipher blklen=%u\n", gcry_cipher_get_algo_blklen(GCRY_CIPHER_RIJNDAEL128));
#endif
/* Set the key */
err = gcry_cipher_setkey(h, pass, len);
uocrypt_error(err);
#if DEBUG
printf("DEBUG: gcrypt handle key set\n");
#endif
/* Everything is init'd, lets do encryption */
while (!feof(in)) {
/* Set the initialization vector */
gcry_create_nonce(iv, sizeof iv);
err = gcry_cipher_setiv(h, iv, sizeof iv);
uocrypt_error(err);
/* Every 1024 bytes of the file will be init vector for decrypt */
wbytes = fwrite(iv, sizeof iv[0], sizeof iv, out);
if (wbytes != sizeof iv) {
printf("Could not write initialization vector\n");
abort();
}
#if DEBUG
printf("DEBUG: gcrypt handle init vector set\n");
#endif
rbytes = fread(buffer, sizeof buffer[0], sizeof buffer, in);
/* Last run through the loop */
if (rbytes < sizeof buffer) {
/* AES has a 16byte blocksize... */
pad = BLOCK_SIZE - rbytes % BLOCK_SIZE;
/* Lets use PKCS7
* http://tools.ietf.org/html/rfc5652#section-6.3 */
if (!pad)
pad = BLOCK_SIZE;
memset(&buffer[rbytes], pad, pad);
/* This is the case where input is exactly 1024 bytes, and we need
* a padding block on the next run through */
} else if (!rbytes) {
rbytes = BLOCK_SIZE;
memset(buffer, rbytes, rbytes);
}
#if DEBUG
printf("DEBUG: Read/write bytes=%u\n", rbytes + pad);
#endif
/* Perform encryption */
err = gcry_cipher_encrypt(h, encrypt, rbytes + pad, buffer, rbytes + pad);
uocrypt_error(err);
#if DEBUG > 1
printf("DEBUG: encrypt=\n");
uocrypt_print(buffer, rbytes + pad);
uocrypt_print(encrypt, rbytes + pad);
#endif
/* Write encrypted data */
wbytes += fwrite(encrypt, sizeof encrypt[0], rbytes + pad, out);
total += wbytes;
printf("Read %u bytes, wrote %u bytes\n", rbytes, wbytes);
}
/* Clean Up */
gcry_cipher_close(h);
return total;
}