initial commit
[iso2ps2.git] / ps2classic / tools.c
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