Commit | Line | Data |
---|---|---|
1de93811 ML |
1 | // some functions borrowed from: |
2 | // Sven Peter <svenpeter@gmail.com> | |
3 | // Segher Boessenkool <segher@kernel.crashing.org> | |
4 | // Licensed under the terms of the GNU GPL, version 2 | |
5 | // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt | |
6 | ||
7 | #include <sys/types.h> | |
8 | #include <stdio.h> | |
9 | #include <fcntl.h> | |
10 | #include <unistd.h> | |
11 | #include <sys/stat.h> | |
12 | #include <string.h> | |
13 | #include <stdarg.h> | |
14 | #include <stdlib.h> | |
15 | #include <assert.h> | |
16 | ||
17 | #ifdef WIN32 | |
18 | #include "mingw_mmap.h" | |
19 | #include <windows.h> | |
20 | #include <winioctl.h> | |
21 | #include <wincrypt.h> | |
22 | #include <conio.h> | |
23 | #else | |
24 | #include <sys/mman.h> | |
25 | #endif | |
26 | ||
27 | #include "tools.h" | |
28 | ||
29 | ||
30 | ||
31 | ||
32 | ||
33 | void *mmap_file(const char *path) | |
34 | { | |
35 | int fd; | |
36 | struct stat st; | |
37 | void *ptr; | |
38 | ||
39 | fd = open(path, O_RDONLY); | |
40 | if(fd == -1) | |
41 | fail("open %s", path); | |
42 | if(fstat(fd, &st) != 0) | |
43 | fail("fstat %s", path); | |
44 | ||
45 | ptr = mmap(0, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); | |
46 | if(ptr==NULL) | |
47 | fail("mmap"); | |
48 | close(fd); | |
49 | ||
50 | return ptr; | |
51 | } | |
52 | ||
53 | ||
54 | void fail(const char *a, ...) | |
55 | { | |
56 | char msg[1024]; | |
57 | va_list va; | |
58 | ||
59 | va_start(va, a); | |
60 | vsnprintf(msg, sizeof msg, a, va); | |
61 | fprintf(stderr, "%s\n", msg); | |
62 | perror("perror"); | |
63 | ||
64 | exit(1); | |
65 | } | |
66 | ||
67 | ||
68 | ||
69 | void print_hash(u8 *ptr, u32 len) | |
70 | { | |
71 | while(len--) | |
72 | printf(" %02x", *ptr++); | |
73 | } | |
74 | ||
75 | void aes256cbc(u8 *key, u8 *iv_in, u8 *in, u64 len, u8 *out) | |
76 | { | |
77 | AES_KEY k; | |
78 | u32 i; | |
79 | u8 tmp[16]; | |
80 | u8 iv[16]; | |
81 | ||
82 | memcpy(iv, iv_in, 16); | |
83 | memset(&k, 0, sizeof k); | |
84 | AES_set_decrypt_key(key, 256, &k); | |
85 | ||
86 | while (len > 0) { | |
87 | memcpy(tmp, in, 16); | |
88 | AES_decrypt(in, out, &k); | |
89 | ||
90 | for (i = 0; i < 16; i++) | |
91 | out[i] ^= iv[i]; | |
92 | ||
93 | memcpy(iv, tmp, 16); | |
94 | ||
95 | out += 16; | |
96 | in += 16; | |
97 | len -= 16; | |
98 | ||
99 | } | |
100 | } | |
101 | ||
102 | ||
103 | void aes256cbc_enc(u8 *key, u8 *iv, u8 *in, u64 len, u8 *out) | |
104 | { | |
105 | AES_KEY k; | |
106 | u32 i; | |
107 | u8 tmp[16]; | |
108 | ||
109 | memcpy(tmp, iv, 16); | |
110 | memset(&k, 0, sizeof k); | |
111 | AES_set_encrypt_key(key, 256, &k); | |
112 | ||
113 | while (len > 0) { | |
114 | for (i = 0; i < 16; i++) | |
115 | tmp[i] ^= *in++; | |
116 | ||
117 | AES_encrypt(tmp, out, &k); | |
118 | memcpy(tmp, out, 16); | |
119 | ||
120 | out += 16; | |
121 | len -= 16; | |
122 | } | |
123 | } | |
124 | ||
125 | ||
126 | void aes128cbc(u8 *key, u8 *iv_in, u8 *in, u64 len, u8 *out) | |
127 | { | |
128 | AES_KEY k; | |
129 | u32 i; | |
130 | u8 tmp[16]; | |
131 | u8 iv[16]; | |
132 | ||
133 | memcpy(iv, iv_in, 16); | |
134 | memset(&k, 0, sizeof k); | |
135 | AES_set_decrypt_key(key, 128, &k); | |
136 | ||
137 | while (len > 0) { | |
138 | memcpy(tmp, in, 16); | |
139 | AES_decrypt(in, out, &k); | |
140 | ||
141 | for (i = 0; i < 16; i++) | |
142 | out[i] ^= iv[i]; | |
143 | ||
144 | memcpy(iv, tmp, 16); | |
145 | ||
146 | out += 16; | |
147 | in += 16; | |
148 | len -= 16; | |
149 | ||
150 | } | |
151 | } | |
152 | ||
153 | void aes128cbc_enc(u8 *key, u8 *iv, u8 *in, u64 len, u8 *out) | |
154 | { | |
155 | AES_KEY k; | |
156 | u32 i; | |
157 | u8 tmp[16]; | |
158 | ||
159 | memcpy(tmp, iv, 16); | |
160 | memset(&k, 0, sizeof k); | |
161 | AES_set_encrypt_key(key, 128, &k); | |
162 | ||
163 | while (len > 0) { | |
164 | for (i = 0; i < 16; i++) | |
165 | tmp[i] ^= *in++; | |
166 | ||
167 | AES_encrypt(tmp, out, &k); | |
168 | memcpy(tmp, out, 16); | |
169 | ||
170 | out += 16; | |
171 | len -= 16; | |
172 | } | |
173 | } | |
174 | ||
175 | void rol1(u8* worthless) { | |
176 | int i; | |
177 | u8 xor = (worthless[0]&0x80)?0x87:0; | |
178 | for(i=0;i<0xF;i++) { | |
179 | worthless[i] <<= 1; | |
180 | worthless[i] |= worthless[i+1]>>7; | |
181 | } | |
182 | worthless[0xF] <<= 1; | |
183 | worthless[0xF] ^= xor; | |
184 | } | |
185 | ||
186 | void aesOmacMode1(u8* output, u8* input, int len, u8* aes_key_data, int aes_key_bits) | |
187 | { | |
188 | int i,j; | |
189 | i = 0; | |
190 | AES_KEY aes_key; | |
191 | AES_set_encrypt_key(aes_key_data, aes_key_bits, &aes_key); | |
192 | ||
193 | u8 running[0x10]; memset(running, 0, 0x10); | |
194 | u8 hash[0x10]; | |
195 | u8 worthless[0x10]; | |
196 | u8 final[0x10]; | |
197 | ||
198 | AES_encrypt(running, worthless, &aes_key); | |
199 | rol1(worthless); | |
200 | ||
201 | if(len > 0x10) { | |
202 | for(i=0;i<(len-0x10);i+=0x10) { | |
203 | for(j=0;j<0x10;j++) hash[j] = running[j] ^ input[i+j]; | |
204 | AES_encrypt(hash, running, &aes_key); | |
205 | } | |
206 | } | |
207 | int overrun = len&0xF; | |
208 | if( (len%0x10) == 0 ) overrun = 0x10; | |
209 | ||
210 | memset(hash, 0, 0x10); | |
211 | memcpy(hash, &input[i], overrun); | |
212 | ||
213 | if(overrun != 0x10) { | |
214 | hash[overrun] = 0x80; | |
215 | rol1(worthless); | |
216 | } | |
217 | ||
218 | for(j=0;j<0x10;j++) hash[j] ^= running[j] ^ worthless[j]; | |
219 | AES_encrypt(hash, output, &aes_key); | |
220 | } | |
221 | ||
222 | ||
223 | static void sha1_fixup(struct SHA1Context *ctx, u8 *digest) | |
224 | { | |
225 | u32 i; | |
226 | ||
227 | for(i = 0; i < 5; i++) { | |
228 | *digest++ = ctx->Message_Digest[i] >> 24 & 0xff; | |
229 | *digest++ = ctx->Message_Digest[i] >> 16 & 0xff; | |
230 | *digest++ = ctx->Message_Digest[i] >> 8 & 0xff; | |
231 | *digest++ = ctx->Message_Digest[i] & 0xff; | |
232 | } | |
233 | } | |
234 | ||
235 | void sha1(u8 *data, u32 len, u8 *digest) | |
236 | { | |
237 | struct SHA1Context ctx; | |
238 | ||
239 | SHA1Reset(&ctx); | |
240 | SHA1Input(&ctx, data, len); | |
241 | SHA1Result(&ctx); | |
242 | ||
243 | sha1_fixup(&ctx, digest); | |
244 | } | |
245 | ||
246 | #ifdef WIN32 | |
247 | void get_rand(u8 *bfr, u32 size) | |
248 | { | |
249 | HCRYPTPROV hProv; | |
250 | ||
251 | if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) | |
252 | fail("unable to open random"); | |
253 | ||
254 | if (!CryptGenRandom(hProv, size, bfr)) | |
255 | fail("unable to read random numbers"); | |
256 | ||
257 | CryptReleaseContext(hProv, 0); | |
258 | } | |
259 | #else | |
260 | void get_rand(u8 *bfr, u32 size) | |
261 | { | |
262 | FILE *fp; | |
263 | ||
264 | fp = fopen("/dev/urandom", "r"); | |
265 | if (fp == NULL) | |
266 | fail("unable to open random"); | |
267 | ||
268 | if (fread(bfr, size, 1, fp) != 1) | |
269 | printf("unable to read /dev/urandom"); | |
270 | ||
271 | fclose(fp); | |
272 | } | |
273 | #endif |