1 /**
2 * \file mtpz.c
3 *
4 * Copyright (C) 2011-2012 Sajid Anwar <sajidanwar94@gmail.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 *
21 * This file provides mtp zune cryptographic setup interfaces.
22 * It is also used with Windows Phone 7, but Microsoft/Nokiad seem
23 * to have discontinued MTPZ on Windows Phone 8.
24 *
25 * DISCLAIMER:
26 *
27 * The intention of this implementation is for users to be able
28 * to interoperate with their devices, i.e. copy music to them in
29 * operating systems other than Microsoft Windows, so it can be
30 * played back on the device. We do not provide encryption keys
31 * and constants in libmtp, we never will. You have to have these
32 * on file in your home directory in $HOME/.mtpz-data, and we suggest
33 * that you talk to Microsoft about providing the proper numbers if
34 * you want to use this facility.
35 */
36 #include "config.h"
37 #include "libmtp.h"
38 #include "unicode.h"
39 #include "ptp.h"
40 #include "libusb-glue.h"
41 #include "device-flags.h"
42 #include "playlist-spl.h"
43 #include "util.h"
44 #include "mtpz.h"
45
46 #include <gcrypt.h>
47
48 #include <stdlib.h>
49 #include <unistd.h>
50 #include <string.h>
51 #include <sys/types.h>
52 #include <sys/stat.h>
53 #include <time.h>
54 #include <errno.h>
55
56
57 /* Microsoft MTPZ extensions */
58
59 /*
60 * The ~/.mtpz-data file contains all four necessary pieces of data:
61 *
62 * encryption key
63 * public exponent
64 * modulus
65 * private key
66 * certificate data
67 *
68 * These four pieces of data are each stored in hex representation,
69 * separated by newline characters.
70 *
71 * If you know of a published, public reference for one of these
72 * arrays of data, please inform us, so we can include it here and
73 * drop it from the external file. Even better is if you convince
74 * Microsoft to officially provide keys to this project.
75 */
76
77 static unsigned char *MTPZ_ENCRYPTION_KEY;
78 static unsigned char *MTPZ_PUBLIC_EXPONENT;
79 static unsigned char *MTPZ_MODULUS;
80 static unsigned char *MTPZ_PRIVATE_KEY;
81 static char *MTPZ_CERTIFICATES;
82
83 // Strip the trailing newline from fgets().
fgets_strip(char * str,int num,FILE * stream)84 static char *fgets_strip(char * str, int num, FILE * stream)
85 {
86 char *result = str;
87
88 if ((result = fgets(str, num, stream)))
89 {
90 size_t newlen = strlen(result);
91
92 if (result[newlen - 1] == '\n')
93 result[newlen - 1] = '\0';
94 }
95
96 return result;
97 }
98
hex_to_bytes(char * hex,size_t len)99 static char *hex_to_bytes(char *hex, size_t len)
100 {
101 if (len % 2)
102 return NULL;
103
104 char *bytes = malloc(len / 2);
105 unsigned int u;
106 int i = 0;
107
108 while (i < len && sscanf(hex + i, "%2x", &u) == 1)
109 {
110 bytes[i / 2] = u;
111 i += 2;
112 }
113
114 return bytes;
115 }
116
mtpz_loaddata()117 int mtpz_loaddata()
118 {
119 char *home = getenv("HOME");
120 int ret = -1;
121 if (!home)
122 {
123 LIBMTP_ERROR("Unable to determine user's home directory, MTPZ disabled.\n");
124 return -1;
125 }
126
127 int plen = strlen(home) + strlen("/.mtpz-data") + 1;
128 char path[plen];
129 sprintf(path, "%s/.mtpz-data", home);
130
131 FILE *fdata = fopen(path, "r");
132 if (!fdata)
133 return ret;
134
135 // Should only be six characters in length, but fgets will encounter a newline and stop.
136 MTPZ_PUBLIC_EXPONENT = (unsigned char *)fgets_strip((char *)malloc(8), 8, fdata);
137 if (!MTPZ_PUBLIC_EXPONENT)
138 {
139 LIBMTP_ERROR("Unable to read MTPZ public exponent from ~/.mtpz-data, MTPZ disabled.\n");
140 goto cleanup;
141 }
142
143 // Should only be 33 characters in length, but fgets will encounter a newline and stop.
144 char *hexenckey = fgets_strip((char *)malloc(35), 35, fdata);
145 if (!hexenckey)
146 {
147 LIBMTP_ERROR("Unable to read MTPZ encryption key from ~/.mtpz-data, MTPZ disabled.\n");
148 goto cleanup;
149 }
150
151 MTPZ_ENCRYPTION_KEY = hex_to_bytes(hexenckey, strlen(hexenckey));
152 if (!MTPZ_ENCRYPTION_KEY)
153 {
154 LIBMTP_ERROR("Unable to read MTPZ encryption key from ~/.mtpz-data, MTPZ disabled.\n");
155 goto cleanup;
156 }
157
158 // Should only be 256 characters in length, but fgets will encounter a newline and stop.
159 MTPZ_MODULUS = (unsigned char *)fgets_strip((char *)malloc(260), 260, fdata);
160 if (!MTPZ_MODULUS)
161 {
162 LIBMTP_ERROR("Unable to read MTPZ modulus from ~/.mtpz-data, MTPZ disabled.\n");
163 goto cleanup;
164 }
165
166 // Should only be 256 characters in length, but fgets will encounter a newline and stop.
167 MTPZ_PRIVATE_KEY = (unsigned char *)fgets_strip((char *)malloc(260), 260, fdata);
168 if (!MTPZ_PRIVATE_KEY)
169 {
170 LIBMTP_ERROR("Unable to read MTPZ private key from ~/.mtpz-data, MTPZ disabled.\n");
171 goto cleanup;
172 }
173
174 // Should only be 1258 characters in length, but fgets will encounter the end of the file and stop.
175 char *hexcerts = fgets_strip((char *)malloc(1260), 1260, fdata);
176 if (!hexcerts)
177 {
178 LIBMTP_ERROR("Unable to read MTPZ certificates from ~/.mtpz-data, MTPZ disabled.\n");
179 goto cleanup;
180 }
181
182 MTPZ_CERTIFICATES = hex_to_bytes(hexcerts, strlen(hexcerts));
183 if (!MTPZ_CERTIFICATES)
184 {
185 LIBMTP_ERROR("Unable to parse MTPZ certificates from ~/.mtpz-data, MTPZ disabled.\n");
186 goto cleanup;
187 }
188 // If all done without errors, drop the fail
189 ret = 0;
190 cleanup:
191 fclose(fdata);
192 return ret;
193 }
194 /* MTPZ RSA */
195
196 typedef struct mtpz_rsa_struct
197 {
198 gcry_sexp_t privkey;
199 gcry_sexp_t pubkey;
200 } mtpz_rsa_t;
201
202 mtpz_rsa_t *mtpz_rsa_init(const unsigned char *modulus, const unsigned char *priv_key, const unsigned char *pub_exp);
203 void mtpz_rsa_free(mtpz_rsa_t *);
204 int mtpz_rsa_decrypt(int flen, unsigned char *from, int tlen, unsigned char *to, mtpz_rsa_t *rsa);
205 int mtpz_rsa_sign(int flen, unsigned char *from, int tlen, unsigned char *to, mtpz_rsa_t *rsa);
206
207 /* MTPZ hashing */
208
209 #define MTPZ_HASHSTATE_84 5
210 #define MTPZ_HASHSTATE_88 6
211
212 static char *mtpz_hash_init_state();
213 static void mtpz_hash_reset_state(char *);
214 static void mtpz_hash_transform_hash(char *, char *, int);
215 static void mtpz_hash_finalize_hash(char *, char *);
216 static char *mtpz_hash_custom6A5DC(char *, char *, int, int);
217
218 static void mtpz_hash_compute_hash(char *, char *, int);
219 static unsigned int mtpz_hash_f(int s, unsigned int x, unsigned int y, unsigned int z);
220 static unsigned int mtpz_hash_rotate_left(unsigned int x, int n);
221
222 /* MTPZ encryption */
223
224 unsigned char mtpz_aes_rcon[];
225 unsigned char mtpz_aes_sbox[];
226 unsigned char mtpz_aes_invsbox[];
227 unsigned int mtpz_aes_ft1[];
228 unsigned int mtpz_aes_ft2[];
229 unsigned int mtpz_aes_ft3[];
230 unsigned int mtpz_aes_ft4[];
231 unsigned int mtpz_aes_rt1[];
232 unsigned int mtpz_aes_rt2[];
233 unsigned int mtpz_aes_rt3[];
234 unsigned int mtpz_aes_rt4[];
235 unsigned int mtpz_aes_gb11[];
236 unsigned int mtpz_aes_gb14[];
237 unsigned int mtpz_aes_gb13[];
238 unsigned int mtpz_aes_gb9[];
239
240 #define MTPZ_ENCRYPTIONLOBYTE(val) (((val) >> 24) & 0xFF)
241 #define MTPZ_ENCRYPTIONBYTE1(val) (((val) >> 16) & 0xFF)
242 #define MTPZ_ENCRYPTIONBYTE2(val) (((val) >> 8) & 0xFF)
243 #define MTPZ_ENCRYPTIONBYTE3(val) (((val) >> 0) & 0xFF)
244
245 #define MTPZ_SWAP(x) mtpz_bswap32(x)
246
247 void mtpz_encryption_cipher(unsigned char *data, unsigned int len, char encrypt);
248 void mtpz_encryption_cipher_advanced(unsigned char *key, unsigned int key_len, unsigned char *data, unsigned int data_len, char encrypt);
249 unsigned char *mtpz_encryption_expand_key(unsigned char *constant, int key_len, int count, int *out_len);
250 void mtpz_encryption_expand_key_inner(unsigned char *constant, int key_len, unsigned char **out, int *out_len);
251 void mtpz_encryption_inv_mix_columns(unsigned char *expanded, int offset, int rounds);
252 void mtpz_encryption_decrypt_custom(unsigned char *data, unsigned char *seed, unsigned char *expanded);
253 void mtpz_encryption_encrypt_custom(unsigned char *data, unsigned char *seed, unsigned char *expanded);
254 void mtpz_encryption_encrypt_mac(unsigned char *hash, unsigned int hash_length, unsigned char *seed, unsigned int seed_len, unsigned char *out);
255
256
mtpz_bswap32(uint32_t x)257 static inline uint32_t mtpz_bswap32(uint32_t x)
258 {
259 #if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) || defined(__clang__)
260 return __builtin_bswap32(x);
261 #else
262 return (x >> 24) |
263 ((x >> 8) & 0x0000ff00) |
264 ((x << 8) & 0x00ff0000) |
265 (x << 24);
266 #endif
267 }
268
269
270 /* MTPZ RSA implementation */
mtpz_rsa_init(const unsigned char * str_modulus,const unsigned char * str_privkey,const unsigned char * str_pubexp)271 mtpz_rsa_t *mtpz_rsa_init(const unsigned char *str_modulus, const unsigned char *str_privkey, const unsigned char *str_pubexp)
272 {
273 mtpz_rsa_t *rsa = calloc(1, sizeof(mtpz_rsa_t));
274 if (rsa == NULL)
275 return NULL;
276
277 gcry_mpi_t mpi_modulus, mpi_privkey, mpi_pubexp;
278
279 gcry_mpi_scan(&mpi_modulus, GCRYMPI_FMT_HEX, str_modulus, 0, NULL);
280 gcry_mpi_scan(&mpi_privkey, GCRYMPI_FMT_HEX, str_privkey, 0, NULL);
281 gcry_mpi_scan(&mpi_pubexp, GCRYMPI_FMT_HEX, str_pubexp, 0, NULL);
282
283 gcry_sexp_build(&rsa->privkey, NULL, "(private-key (rsa (n %m) (e %m) (d %m)))", mpi_modulus, mpi_pubexp, mpi_privkey);
284 gcry_sexp_build(&rsa->pubkey, NULL, "(public-key (rsa (n %m) (e %m)))", mpi_modulus, mpi_pubexp);
285
286 gcry_mpi_release(mpi_modulus);
287 gcry_mpi_release(mpi_privkey);
288 gcry_mpi_release(mpi_pubexp);
289
290 return rsa;
291 }
292
mtpz_rsa_free(mtpz_rsa_t * rsa)293 void mtpz_rsa_free(mtpz_rsa_t *rsa)
294 {
295 gcry_sexp_release(rsa->privkey);
296 gcry_sexp_release(rsa->pubkey);
297 }
298
mtpz_rsa_decrypt(int flen,unsigned char * from,int tlen,unsigned char * to,mtpz_rsa_t * rsa)299 int mtpz_rsa_decrypt(int flen, unsigned char *from, int tlen, unsigned char *to, mtpz_rsa_t *rsa)
300 {
301 gcry_mpi_t mpi_from;
302 gcry_mpi_scan(&mpi_from, GCRYMPI_FMT_USG, from, flen, NULL);
303
304 gcry_sexp_t sexp_data;
305 gcry_sexp_build(&sexp_data, NULL, "(enc-val (flags raw) (rsa (a %m)))", mpi_from);
306
307 gcry_sexp_t sexp_plain;
308 gcry_pk_decrypt(&sexp_plain, sexp_data, rsa->privkey);
309
310 gcry_mpi_t mpi_value = gcry_sexp_nth_mpi(sexp_plain, 1, GCRYMPI_FMT_USG);
311
312 // Lame workaround. GCRYMPI_FMT_USG gets rid of any leading zeroes which we do need,
313 // so we'll count how many bits are being used, and subtract that from how many bits actually
314 // should be there, and then write into our output array shifted over however many bits/8.
315 int bitshift = (tlen * 8) - gcry_mpi_get_nbits(mpi_value);
316 size_t written;
317
318 if (bitshift / 8)
319 {
320 memset(to, 0, bitshift / 8);
321 to += bitshift / 8;
322 tlen -= bitshift / 8;
323 }
324
325 gcry_mpi_print(GCRYMPI_FMT_USG, to, tlen, &written, mpi_value);
326
327 gcry_mpi_release(mpi_from);
328 gcry_mpi_release(mpi_value);
329 gcry_sexp_release(sexp_data);
330 gcry_sexp_release(sexp_plain);
331
332 return (int)written;
333 }
334
mtpz_rsa_sign(int flen,unsigned char * from,int tlen,unsigned char * to,mtpz_rsa_t * rsa)335 int mtpz_rsa_sign(int flen, unsigned char *from, int tlen, unsigned char *to, mtpz_rsa_t *rsa)
336 {
337 return mtpz_rsa_decrypt(flen, from, tlen, to, rsa);
338 }
339
340 /* MTPZ hashing implementation */
341
mtpz_hash_init_state()342 static char *mtpz_hash_init_state()
343 {
344 char *s = (char *)malloc(92);
345
346 if (s != NULL)
347 memset(s, 0, 92);
348
349 return s;
350 }
351
mtpz_hash_reset_state(char * state)352 void mtpz_hash_reset_state(char *state)
353 {
354 int *state_box = (int *)(state + 64);
355
356 /*
357 * Constants from
358 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
359 * Page 13, section 5.3.1
360 */
361 state_box[0] = 0x67452301;
362 state_box[1] = 0xefcdab89;
363 state_box[2] = 0x98badcfe;
364 state_box[3] = 0x10325476;
365 state_box[4] = 0xc3d2e1f0;
366 state_box[MTPZ_HASHSTATE_84] = 0;
367 state_box[MTPZ_HASHSTATE_88] = 0;
368 }
369
mtpz_hash_transform_hash(char * state,char * msg,int len)370 void mtpz_hash_transform_hash(char *state, char *msg, int len)
371 {
372 int *state_box = (int *)(state + 64);
373
374 int x = state_box[MTPZ_HASHSTATE_88] & 0x3F;
375 int v5 = len + state_box[MTPZ_HASHSTATE_88];
376 state_box[MTPZ_HASHSTATE_88] = v5;
377
378 int i = len, j = 0;
379 int a1 = 0;
380 int c = 0;
381
382 if (len > v5)
383 state_box[MTPZ_HASHSTATE_84] += 1;
384
385 if (x)
386 {
387 if (len + x > 0x3F)
388 {
389 for (a1 = 0; a1 < 64 - x; a1++)
390 {
391 state[x + a1] = msg[a1];
392 }
393
394 i = len + x - 64;
395 j = 64 - x;
396
397 mtpz_hash_compute_hash(state, state, 64);
398 }
399 }
400
401 while (i > 63)
402 {
403 mtpz_hash_compute_hash(state, msg + j, 64);
404 j += 64;
405 i -= 64;
406 }
407
408 if (i != 0)
409 {
410 for (c = 0; c < i; c++)
411 {
412 state[x + c] = msg[j + c];
413 }
414 }
415 }
416
417 // out has at least 20 bytes of space
mtpz_hash_finalize_hash(char * state,char * out)418 void mtpz_hash_finalize_hash(char *state, char *out)
419 {
420 int *state_box = (int *)(state + 64);
421
422 int v2 = 64 - (state_box[MTPZ_HASHSTATE_88] & 0x3F);
423 int v6, v7;
424
425 if (v2 <= 8)
426 v2 += 64;
427
428 char *v5 = (char *)malloc(72);
429 memset(v5, 0, 72);
430
431 v5[0] = '\x80';
432 v6 = 8 * state_box[MTPZ_HASHSTATE_84] | (state_box[MTPZ_HASHSTATE_88] >> 29);
433 v7 = 8 * state_box[MTPZ_HASHSTATE_88];
434
435 v6 = MTPZ_SWAP(v6);
436 v7 = MTPZ_SWAP(v7);
437
438 *(int *)(v5 + v2 - 8) = v6;
439 *(int *)(v5 + v2 - 4) = v7;
440
441 mtpz_hash_transform_hash(state, v5, v2);
442
443 int *out_int = (int *)out;
444 out_int[0] = MTPZ_SWAP(state_box[0]);
445 out_int[1] = MTPZ_SWAP(state_box[1]);
446 out_int[2] = MTPZ_SWAP(state_box[2]);
447 out_int[3] = MTPZ_SWAP(state_box[3]);
448 out_int[4] = MTPZ_SWAP(state_box[4]);
449
450 memset(state, 0, 64);
451 mtpz_hash_reset_state(state);
452 }
453
mtpz_hash_custom6A5DC(char * state,char * msg,int len,int a4)454 char *mtpz_hash_custom6A5DC(char *state, char *msg, int len, int a4)
455 {
456 int v11 = (a4 / 20) + 1;
457 char *v13 = (char *)malloc(v11 * 20);
458 char *v5 = (char *)malloc(len + 4);
459 int i;
460 int k;
461
462 memset(v13, 0, v11 * 20);
463 memset(v5, 0, len + 4);
464 memcpy(v5, msg, len);
465
466 for (i = 0; i < v11; i++)
467 {
468 k = MTPZ_SWAP(i);
469 *(int *)(v5 + len) = k;
470
471 mtpz_hash_reset_state(state);
472 mtpz_hash_transform_hash(state, v5, len + 4);
473 mtpz_hash_finalize_hash(state, v13 + i * 20);
474 }
475
476 free(v5); v5 = NULL;
477
478 return v13;
479 }
480
mtpz_hash_compute_hash(char * state,char * msg,int len)481 void mtpz_hash_compute_hash(char *state, char *msg, int len)
482 {
483 int *state_box = (int *)(state + 64);
484
485 const unsigned int K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
486
487 if (len != 64)
488 return;
489
490 int *M = (int *)msg;
491
492 // HASH COMPUTATION
493 unsigned int W[80];
494 unsigned int a, b, c, d, e;
495 int i, s;
496 unsigned int T;
497
498 // 1 - prepare message schedule 'W'.
499 for (i = 0; i < 16; i++) W[i] = MTPZ_SWAP(M[i]);
500 for (i = 16; i < 80; i++) W[i] = mtpz_hash_rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
501
502 // 2 - initialize five working variables a, b, c, d, e with previous hash value
503 a = state_box[0];
504 b = state_box[1];
505 c = state_box[2];
506 d = state_box[3];
507 e = state_box[4];
508
509 // 3 - main loop
510 for (i = 0; i < 80; i++)
511 {
512 s = i / 20;
513 T = (mtpz_hash_rotate_left(a, 5) + mtpz_hash_f(s, b, c, d) + e + K[s] + W[i]) & 0xFFFFFFFF;
514 e = d;
515 d = c;
516 c = mtpz_hash_rotate_left(b, 30);
517 b = a;
518 a = T;
519 }
520
521 state_box[0] = (state_box[0] + a) & 0xFFFFFFFF;
522 state_box[1] = (state_box[1] + b) & 0xFFFFFFFF;
523 state_box[2] = (state_box[2] + c) & 0xFFFFFFFF;
524 state_box[3] = (state_box[3] + d) & 0xFFFFFFFF;
525 state_box[4] = (state_box[4] + e) & 0xFFFFFFFF;
526 }
527
mtpz_hash_f(int s,unsigned int x,unsigned int y,unsigned int z)528 unsigned int mtpz_hash_f(int s, unsigned int x, unsigned int y, unsigned int z)
529 {
530 switch (s)
531 {
532 case 0:
533 return (x & y) ^ (~x & z); // Ch()
534 case 1:
535 return x ^ y ^ z; // Parity()
536 case 2:
537 return (x & y) ^ (x & z) ^ (y & z); // Maj()
538 case 3:
539 return x ^ y ^ z; // Parity()
540 }
541
542 return 0;
543 }
544
mtpz_hash_rotate_left(unsigned int x,int n)545 unsigned int mtpz_hash_rotate_left(unsigned int x, int n)
546 {
547 return (x << n) | (x >> (32 - n));
548 }
549
550 /* MTPZ encryption implementation */
551
mtpz_encryption_cipher(unsigned char * data,unsigned int len,char encrypt)552 void mtpz_encryption_cipher(unsigned char *data, unsigned int len, char encrypt)
553 {
554 unsigned char *expanded = NULL;
555
556 int offset = 0, count = len;
557
558 if ((count & 0x0F) == 0)
559 {
560 int exp_len = 0;
561 expanded = mtpz_encryption_expand_key((unsigned char *)MTPZ_ENCRYPTION_KEY, 16, 10, &exp_len);
562
563 if (count != 0)
564 {
565 do
566 {
567 if (encrypt)
568 mtpz_encryption_encrypt_custom(data + offset, NULL, expanded);
569 else
570 mtpz_encryption_decrypt_custom(data + offset, NULL, expanded);
571
572 count -= 16;
573 offset += 16;
574 }
575 while (count != 0);
576 }
577 }
578 }
579
mtpz_encryption_cipher_advanced(unsigned char * key,unsigned int key_len,unsigned char * data,unsigned int data_len,char encrypt)580 void mtpz_encryption_cipher_advanced(unsigned char *key, unsigned int key_len, unsigned char *data, unsigned int data_len, char encrypt)
581 {
582 int len = (key_len == 16) ? 10 :
583 (key_len == 24) ? 12 : 32;
584 int exp_len;
585 unsigned char *expanded = mtpz_encryption_expand_key(key, key_len, len, &exp_len);
586
587 int offset = 0, count = data_len;
588 unsigned char *out = (unsigned char *)malloc(16);
589 unsigned int *out_int = (unsigned int *)out;
590 unsigned int *data_int = (unsigned int *)data;
591 unsigned int *dtf = (unsigned int *)malloc(16);
592 memset((unsigned char *)dtf, 0, 16);
593
594 while (count != 0)
595 {
596 int chunk = 16;
597
598 if (count < 16)
599 {
600 memset(out, 0, 16);
601 chunk = count;
602 }
603
604 memcpy(out, data + offset, chunk);
605
606 if (encrypt)
607 {
608 out_int[0] ^= MTPZ_SWAP(dtf[0]);
609 out_int[1] ^= MTPZ_SWAP(dtf[1]);
610 out_int[2] ^= MTPZ_SWAP(dtf[2]);
611 out_int[3] ^= MTPZ_SWAP(dtf[3]);
612
613 mtpz_encryption_encrypt_custom(data + offset, out, expanded);
614
615 dtf[0] = MTPZ_SWAP(data_int[(offset / 4) + 0]);
616 dtf[1] = MTPZ_SWAP(data_int[(offset / 4) + 1]);
617 dtf[2] = MTPZ_SWAP(data_int[(offset / 4) + 2]);
618 dtf[3] = MTPZ_SWAP(data_int[(offset / 4) + 3]);
619 }
620 else
621 {
622 mtpz_encryption_decrypt_custom(data + offset, out, expanded);
623
624 data_int[(offset / 4) + 0] ^= MTPZ_SWAP(dtf[0]);
625 data_int[(offset / 4) + 1] ^= MTPZ_SWAP(dtf[1]);
626 data_int[(offset / 4) + 2] ^= MTPZ_SWAP(dtf[2]);
627 data_int[(offset / 4) + 3] ^= MTPZ_SWAP(dtf[3]);
628
629 dtf[0] = MTPZ_SWAP(out_int[0]);
630 dtf[1] = MTPZ_SWAP(out_int[1]);
631 dtf[2] = MTPZ_SWAP(out_int[2]);
632 dtf[3] = MTPZ_SWAP(out_int[3]);
633 }
634
635 offset += chunk;
636 count -= chunk;
637 }
638
639 free(out);
640 free(dtf);
641 free(expanded);
642 }
643
mtpz_encryption_expand_key(unsigned char * constant,int key_len,int count,int * out_len)644 unsigned char *mtpz_encryption_expand_key(unsigned char *constant, int key_len, int count, int *out_len)
645 {
646 int i = 0;
647 int seek = 0;
648 unsigned char *back = (unsigned char *)malloc(484);
649 memset(back, 0, 484);
650 *out_len = 484;
651
652 unsigned char *inner;
653 int inner_len;
654 mtpz_encryption_expand_key_inner(constant, key_len, &inner, &inner_len);
655
656 back[i] = (unsigned char)(count % 0xFF);
657 i += 4;
658
659 memcpy(back + i, inner, inner_len);
660 i += inner_len;
661 memcpy(back + i, inner, inner_len);
662 i += inner_len;
663
664 switch (count)
665 {
666 case 10:
667 seek = 0xB4;
668 break;
669
670 case 12:
671 seek = 0xD4;
672 break;
673
674 case 14:
675 default:
676 seek = 0xF4;
677 break;
678 }
679
680 mtpz_encryption_inv_mix_columns(back, seek, count);
681
682 return back;
683 }
684
mtpz_encryption_expand_key_inner(unsigned char * constant,int key_len,unsigned char ** out,int * out_len)685 void mtpz_encryption_expand_key_inner(unsigned char *constant, int key_len, unsigned char **out, int *out_len)
686 {
687 int ks = -1;
688 int rcon_i = 0;
689 int i = 0, j = 0;
690
691 switch (key_len)
692 {
693 case 16:
694 ks = 16 * (10 + 1);
695 break;
696
697 case 24:
698 ks = 16 * (12 + 1);
699 break;
700
701 case 32:
702 ks = 16 * (14 + 1);
703 break;
704
705 default:
706 *out = NULL;
707 *out_len = 0;
708 return;
709 }
710
711 unsigned char *key = (unsigned char *)malloc(ks);
712 unsigned char *temp = (unsigned char *)malloc(4);
713 memcpy(key, constant, key_len);
714 unsigned char t0, t1, t2, t3;
715
716 for (i = key_len; i < ks; i += 4)
717 {
718 temp[0] = t0 = key[i - 4];
719 temp[1] = t1 = key[i - 3];
720 temp[2] = t2 = key[i - 2];
721 temp[3] = t3 = key[i - 1];
722
723 if (i % key_len == 0)
724 {
725 temp[0] = (mtpz_aes_sbox[t1] ^ mtpz_aes_rcon[rcon_i]) & 0xFF;
726 temp[1] = mtpz_aes_sbox[t2];
727 temp[2] = mtpz_aes_sbox[t3];
728 temp[3] = mtpz_aes_sbox[t0];
729 rcon_i++;
730 }
731 else if ((key_len > 24) && (i % key_len == 16))
732 {
733 temp[0] = mtpz_aes_sbox[t0];
734 temp[1] = mtpz_aes_sbox[t1];
735 temp[2] = mtpz_aes_sbox[t2];
736 temp[3] = mtpz_aes_sbox[t3];
737 }
738
739 for (j = 0; j < 4; j++)
740 {
741 key[i + j] = (unsigned char)((key[i + j - key_len] ^ temp[j]) & 0xFF);
742 }
743 }
744
745 free(temp);
746
747 *out = key;
748 *out_len = ks;
749 }
750
mtpz_encryption_inv_mix_columns(unsigned char * expanded,int offset,int rounds)751 void mtpz_encryption_inv_mix_columns(unsigned char *expanded, int offset, int rounds)
752 {
753 int v8 = 1, o = offset;
754 unsigned int *exp_int = NULL;
755
756 for (v8 = 1; v8 < rounds; v8++)
757 {
758 exp_int = (unsigned int *)(expanded + o + 16);
759
760 exp_int[0] = MTPZ_SWAP(mtpz_aes_gb9[expanded[o + 19]] ^ mtpz_aes_gb13[expanded[o + 18]] ^ mtpz_aes_gb11[expanded[o + 17]] ^ mtpz_aes_gb14[expanded[o + 16]]);
761 exp_int[1] = MTPZ_SWAP(mtpz_aes_gb9[expanded[o + 23]] ^ mtpz_aes_gb13[expanded[o + 22]] ^ mtpz_aes_gb11[expanded[o + 21]] ^ mtpz_aes_gb14[expanded[o + 20]]);
762 exp_int[2] = MTPZ_SWAP(mtpz_aes_gb9[expanded[o + 27]] ^ mtpz_aes_gb13[expanded[o + 26]] ^ mtpz_aes_gb11[expanded[o + 25]] ^ mtpz_aes_gb14[expanded[o + 24]]);
763 exp_int[3] = MTPZ_SWAP(mtpz_aes_gb9[expanded[o + 31]] ^ mtpz_aes_gb13[expanded[o + 30]] ^ mtpz_aes_gb11[expanded[o + 29]] ^ mtpz_aes_gb14[expanded[o + 28]]);
764 o += 16;
765 }
766 }
767
mtpz_encryption_decrypt_custom(unsigned char * data,unsigned char * seed,unsigned char * expanded)768 void mtpz_encryption_decrypt_custom(unsigned char *data, unsigned char *seed, unsigned char *expanded)
769 {
770 unsigned int *u_data = (unsigned int *)data;
771 unsigned int *u_expanded = (unsigned int *)expanded;
772 int keyOffset = 0xB4 + 0xA0;
773
774 unsigned int *u_seed;
775
776 if (seed == NULL)
777 u_seed = u_data;
778 else
779 u_seed = (unsigned int *)seed;
780
781 unsigned int v14 = MTPZ_SWAP(u_seed[0]) ^ MTPZ_SWAP(u_expanded[(keyOffset ) / 4]);
782 unsigned int v15 = MTPZ_SWAP(u_seed[1]) ^ MTPZ_SWAP(u_expanded[(keyOffset + 4) / 4]);
783 unsigned int v16 = MTPZ_SWAP(u_seed[2]) ^ MTPZ_SWAP(u_expanded[(keyOffset + 8) / 4]);
784 unsigned int v17 = MTPZ_SWAP(u_seed[3]) ^ MTPZ_SWAP(u_expanded[(keyOffset + 12) / 4]);
785
786 unsigned int v18 = mtpz_aes_rt1[MTPZ_ENCRYPTIONBYTE3(v15)] ^ mtpz_aes_rt2[MTPZ_ENCRYPTIONBYTE2(v16)] ^ mtpz_aes_rt3[MTPZ_ENCRYPTIONLOBYTE(v14)] ^ mtpz_aes_rt4[MTPZ_ENCRYPTIONBYTE1(v17)];
787 unsigned int v19 = mtpz_aes_rt1[MTPZ_ENCRYPTIONBYTE3(v16)] ^ mtpz_aes_rt2[MTPZ_ENCRYPTIONBYTE2(v17)] ^ mtpz_aes_rt3[MTPZ_ENCRYPTIONLOBYTE(v15)] ^ mtpz_aes_rt4[MTPZ_ENCRYPTIONBYTE1(v14)];
788 unsigned int v20 = mtpz_aes_rt1[MTPZ_ENCRYPTIONBYTE3(v17)] ^ mtpz_aes_rt2[MTPZ_ENCRYPTIONBYTE2(v14)] ^ mtpz_aes_rt3[MTPZ_ENCRYPTIONLOBYTE(v16)] ^ mtpz_aes_rt4[MTPZ_ENCRYPTIONBYTE1(v15)];
789 unsigned int v21 = mtpz_aes_rt1[MTPZ_ENCRYPTIONBYTE3(v14)] ^ mtpz_aes_rt2[MTPZ_ENCRYPTIONBYTE2(v15)] ^ mtpz_aes_rt3[MTPZ_ENCRYPTIONLOBYTE(v17)] ^ mtpz_aes_rt4[MTPZ_ENCRYPTIONBYTE1(v16)];
790
791 keyOffset -= 16;
792 int rounds = 9;
793
794 do
795 {
796 v14 = v18 ^ MTPZ_SWAP(u_expanded[(keyOffset ) / 4]);
797 v15 = v19 ^ MTPZ_SWAP(u_expanded[(keyOffset + 4) / 4]);
798 v16 = v20 ^ MTPZ_SWAP(u_expanded[(keyOffset + 8) / 4]);
799 v17 = v21 ^ MTPZ_SWAP(u_expanded[(keyOffset + 12) / 4]);
800
801 v18 = mtpz_aes_rt1[MTPZ_ENCRYPTIONBYTE3(v15)] ^ mtpz_aes_rt2[MTPZ_ENCRYPTIONBYTE2(v16)] ^ mtpz_aes_rt3[MTPZ_ENCRYPTIONLOBYTE(v14)] ^ mtpz_aes_rt4[MTPZ_ENCRYPTIONBYTE1(v17)];
802 v19 = mtpz_aes_rt1[MTPZ_ENCRYPTIONBYTE3(v16)] ^ mtpz_aes_rt2[MTPZ_ENCRYPTIONBYTE2(v17)] ^ mtpz_aes_rt3[MTPZ_ENCRYPTIONLOBYTE(v15)] ^ mtpz_aes_rt4[MTPZ_ENCRYPTIONBYTE1(v14)];
803 v20 = mtpz_aes_rt1[MTPZ_ENCRYPTIONBYTE3(v17)] ^ mtpz_aes_rt2[MTPZ_ENCRYPTIONBYTE2(v14)] ^ mtpz_aes_rt3[MTPZ_ENCRYPTIONLOBYTE(v16)] ^ mtpz_aes_rt4[MTPZ_ENCRYPTIONBYTE1(v15)];
804 v21 = mtpz_aes_rt1[MTPZ_ENCRYPTIONBYTE3(v14)] ^ mtpz_aes_rt2[MTPZ_ENCRYPTIONBYTE2(v15)] ^ mtpz_aes_rt3[MTPZ_ENCRYPTIONLOBYTE(v17)] ^ mtpz_aes_rt4[MTPZ_ENCRYPTIONBYTE1(v16)];
805
806 rounds--;
807 keyOffset -= 16;
808 }
809 while (rounds != 1);
810
811 v14 = v18 ^ MTPZ_SWAP(u_expanded[(keyOffset ) / 4]);
812 v15 = v19 ^ MTPZ_SWAP(u_expanded[(keyOffset + 4) / 4]);
813 v16 = v20 ^ MTPZ_SWAP(u_expanded[(keyOffset + 8) / 4]);
814 v17 = v21 ^ MTPZ_SWAP(u_expanded[(keyOffset + 12) / 4]);
815 keyOffset -= 16;
816
817 v18 = ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONLOBYTE(v14)]) << 24) |
818 ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONBYTE1 (v17)]) << 16) |
819 ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONBYTE2 (v16)]) << 8) |
820 ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONBYTE3 (v15)]) << 0);
821
822 v19 = ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONLOBYTE(v15)]) << 24) |
823 ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONBYTE1 (v14)]) << 16) |
824 ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONBYTE2 (v17)]) << 8) |
825 ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONBYTE3 (v16)]) << 0);
826
827 v20 = ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONLOBYTE(v16)]) << 24) |
828 ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONBYTE1 (v15)]) << 16) |
829 ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONBYTE2 (v14)]) << 8) |
830 ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONBYTE3 (v17)]) << 0);
831
832 v21 = ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONLOBYTE(v17)]) << 24) |
833 ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONBYTE1 (v16)]) << 16) |
834 ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONBYTE2 (v15)]) << 8) |
835 ((mtpz_aes_invsbox[MTPZ_ENCRYPTIONBYTE3 (v14)]) << 0);
836
837 u_data[0] = MTPZ_SWAP(v18 ^ MTPZ_SWAP(u_expanded[(keyOffset ) / 4]));
838 u_data[1] = MTPZ_SWAP(v19 ^ MTPZ_SWAP(u_expanded[(keyOffset + 4) / 4]));
839 u_data[2] = MTPZ_SWAP(v20 ^ MTPZ_SWAP(u_expanded[(keyOffset + 8) / 4]));
840 u_data[3] = MTPZ_SWAP(v21 ^ MTPZ_SWAP(u_expanded[(keyOffset + 12) / 4]));
841 };
842
mtpz_encryption_encrypt_custom(unsigned char * data,unsigned char * seed,unsigned char * expanded)843 void mtpz_encryption_encrypt_custom(unsigned char *data, unsigned char *seed, unsigned char *expanded)
844 {
845 unsigned int *u_data = (unsigned int *)data;
846 unsigned int *u_expanded = (unsigned int *)expanded;
847 int keyOffset = 0x04;
848
849 unsigned int *u_seed;
850
851 if (seed == NULL)
852 u_seed = u_data;
853 else
854 u_seed = (unsigned int *)seed;
855
856 unsigned int v14 = MTPZ_SWAP(u_seed[0]) ^ MTPZ_SWAP(u_expanded[(keyOffset ) / 4]);
857 unsigned int v15 = MTPZ_SWAP(u_seed[1]) ^ MTPZ_SWAP(u_expanded[(keyOffset + 4) / 4]);
858 unsigned int v16 = MTPZ_SWAP(u_seed[2]) ^ MTPZ_SWAP(u_expanded[(keyOffset + 8) / 4]);
859 unsigned int v17 = MTPZ_SWAP(u_seed[3]) ^ MTPZ_SWAP(u_expanded[(keyOffset + 12) / 4]);
860
861 unsigned int v18 = mtpz_aes_ft1[MTPZ_ENCRYPTIONBYTE3(v17)] ^ mtpz_aes_ft2[MTPZ_ENCRYPTIONBYTE2(v16)] ^ mtpz_aes_ft3[MTPZ_ENCRYPTIONLOBYTE(v14)] ^ mtpz_aes_ft4[MTPZ_ENCRYPTIONBYTE1(v15)];
862 unsigned int v19 = mtpz_aes_ft1[MTPZ_ENCRYPTIONBYTE3(v14)] ^ mtpz_aes_ft2[MTPZ_ENCRYPTIONBYTE2(v17)] ^ mtpz_aes_ft3[MTPZ_ENCRYPTIONLOBYTE(v15)] ^ mtpz_aes_ft4[MTPZ_ENCRYPTIONBYTE1(v16)];
863 unsigned int v20 = mtpz_aes_ft1[MTPZ_ENCRYPTIONBYTE3(v15)] ^ mtpz_aes_ft2[MTPZ_ENCRYPTIONBYTE2(v14)] ^ mtpz_aes_ft3[MTPZ_ENCRYPTIONLOBYTE(v16)] ^ mtpz_aes_ft4[MTPZ_ENCRYPTIONBYTE1(v17)];
864 unsigned int v21 = mtpz_aes_ft1[MTPZ_ENCRYPTIONBYTE3(v16)] ^ mtpz_aes_ft2[MTPZ_ENCRYPTIONBYTE2(v15)] ^ mtpz_aes_ft3[MTPZ_ENCRYPTIONLOBYTE(v17)] ^ mtpz_aes_ft4[MTPZ_ENCRYPTIONBYTE1(v14)];
865
866 keyOffset += 16;
867 int rounds = 1;
868
869 do
870 {
871
872 v14 = v18 ^ MTPZ_SWAP(u_expanded[(keyOffset ) / 4]);
873 v15 = v19 ^ MTPZ_SWAP(u_expanded[(keyOffset + 4) / 4]);
874 v16 = v20 ^ MTPZ_SWAP(u_expanded[(keyOffset + 8) / 4]);
875 v17 = v21 ^ MTPZ_SWAP(u_expanded[(keyOffset + 12) / 4]);
876
877 v18 = mtpz_aes_ft1[MTPZ_ENCRYPTIONBYTE3(v17)] ^ mtpz_aes_ft2[MTPZ_ENCRYPTIONBYTE2(v16)] ^ mtpz_aes_ft3[MTPZ_ENCRYPTIONLOBYTE(v14)] ^ mtpz_aes_ft4[MTPZ_ENCRYPTIONBYTE1(v15)];
878 v19 = mtpz_aes_ft1[MTPZ_ENCRYPTIONBYTE3(v14)] ^ mtpz_aes_ft2[MTPZ_ENCRYPTIONBYTE2(v17)] ^ mtpz_aes_ft3[MTPZ_ENCRYPTIONLOBYTE(v15)] ^ mtpz_aes_ft4[MTPZ_ENCRYPTIONBYTE1(v16)];
879 v20 = mtpz_aes_ft1[MTPZ_ENCRYPTIONBYTE3(v15)] ^ mtpz_aes_ft2[MTPZ_ENCRYPTIONBYTE2(v14)] ^ mtpz_aes_ft3[MTPZ_ENCRYPTIONLOBYTE(v16)] ^ mtpz_aes_ft4[MTPZ_ENCRYPTIONBYTE1(v17)];
880 v21 = mtpz_aes_ft1[MTPZ_ENCRYPTIONBYTE3(v16)] ^ mtpz_aes_ft2[MTPZ_ENCRYPTIONBYTE2(v15)] ^ mtpz_aes_ft3[MTPZ_ENCRYPTIONLOBYTE(v17)] ^ mtpz_aes_ft4[MTPZ_ENCRYPTIONBYTE1(v14)];
881
882 rounds++;
883 keyOffset += 16;
884 }
885 while (rounds != 9);
886
887 v14 = v18 ^ MTPZ_SWAP(u_expanded[(keyOffset ) / 4]);
888 v15 = v19 ^ MTPZ_SWAP(u_expanded[(keyOffset + 4) / 4]);
889 v16 = v20 ^ MTPZ_SWAP(u_expanded[(keyOffset + 8) / 4]);
890 v17 = v21 ^ MTPZ_SWAP(u_expanded[(keyOffset + 12) / 4]);
891 keyOffset += 16;
892
893 unsigned char *FT3_Bytes = (unsigned char *)mtpz_aes_ft3;
894
895 v18 = ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONLOBYTE(v14)]) << 24) |
896 ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONBYTE1 (v15)]) << 16) |
897 ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONBYTE2 (v16)]) << 8) |
898 ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONBYTE3 (v17)]) << 0);
899
900 v19 = ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONLOBYTE(v15)]) << 24) |
901 ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONBYTE1 (v16)]) << 16) |
902 ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONBYTE2 (v17)]) << 8) |
903 ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONBYTE3 (v14)]) << 0);
904
905 v20 = ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONLOBYTE(v16)]) << 24) |
906 ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONBYTE1 (v17)]) << 16) |
907 ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONBYTE2 (v14)]) << 8) |
908 ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONBYTE3 (v15)]) << 0);
909
910 v21 = ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONLOBYTE(v17)]) << 24) |
911 ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONBYTE1 (v14)]) << 16) |
912 ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONBYTE2 (v15)]) << 8) |
913 ((FT3_Bytes[1 + 4 * MTPZ_ENCRYPTIONBYTE3 (v16)]) << 0);
914
915 u_data[0] = MTPZ_SWAP(v18 ^ MTPZ_SWAP(u_expanded[(keyOffset ) / 4]));
916 u_data[1] = MTPZ_SWAP(v19 ^ MTPZ_SWAP(u_expanded[(keyOffset + 4) / 4]));
917 u_data[2] = MTPZ_SWAP(v20 ^ MTPZ_SWAP(u_expanded[(keyOffset + 8) / 4]));
918 u_data[3] = MTPZ_SWAP(v21 ^ MTPZ_SWAP(u_expanded[(keyOffset + 12) / 4]));
919 }
920
mtpz_encryption_encrypt_mac(unsigned char * hash,unsigned int hash_length,unsigned char * seed,unsigned int seed_len,unsigned char * out)921 void mtpz_encryption_encrypt_mac(unsigned char *hash, unsigned int hash_length, unsigned char *seed, unsigned int seed_len, unsigned char *out)
922 {
923 if (hash == NULL || hash_length != 16)
924 return;
925
926 unsigned char *loop1 = (unsigned char *)malloc(17);
927 memset(loop1, 0, 17);
928 unsigned char *loop2 = (unsigned char *)malloc(17);
929 memset(loop2, 0, 17);
930 int i = 0;
931
932 {
933 unsigned char *enc_hash = (unsigned char *)malloc(17);
934 memset(enc_hash, 0, 17);
935 mtpz_encryption_cipher_advanced(hash, hash_length, enc_hash, 16, 1);
936
937 for (i = 0; i < 16; i++)
938 loop1[i] = (unsigned char)((2 * enc_hash[i]) | (enc_hash[i + 1] >> 7));
939
940 if (enc_hash[0] >= (unsigned char)128)
941 loop1[15] ^= (unsigned char)0x87;
942
943 for (i = 0; i < 16; i++)
944 loop2[i] = (unsigned char)((2 * loop1[i]) | (loop1[i + 1] >> 7));
945
946 if (loop1[0] >= (unsigned char)128)
947 loop2[15] ^= (unsigned char)0x87;
948
949 free(enc_hash);
950 }
951
952 {
953 int len = (hash_length == 16) ? 10 :
954 (hash_length == 24) ? 12 : 32;
955 int exp_len;
956 unsigned char *expanded = mtpz_encryption_expand_key(hash, hash_length, len, &exp_len);
957
958 unsigned char *actual_seed = (unsigned char *)malloc(16);
959 memset(actual_seed, 0, 16);
960
961 int i = 0;
962
963 if (seed_len == 16)
964 {
965 for (i = 0; i < 16; i++)
966 actual_seed[i] ^= seed[i];
967
968 for (i = 0; i < 16; i++)
969 actual_seed[i] ^= loop1[i];
970 }
971 else
972 {
973 for (i = 0; i < seed_len; i++)
974 actual_seed[i] ^= seed[i];
975
976 actual_seed[seed_len] = (unsigned char)128;
977
978 for (i = 0; i < 16; i++)
979 actual_seed[i] ^= loop2[i];
980 }
981
982 mtpz_encryption_encrypt_custom(out, actual_seed, expanded);
983
984 free(expanded);
985 free(actual_seed);
986 }
987
988 free(loop1);
989 free(loop2);
990 }
991
992
993 /* ENCRYPTION CONSTANTS */
994 /*
995 * These tables can also be found in Mozilla's Network Security Services:
996 * http://www.mozilla.org/projects/security/pki/nss/
997 *
998 * <rijndael32.tab>:
999 * https://hg.mozilla.org/mozilla-central/raw-file/90828ac18dcf/security/nss/lib/freebl/rijndael32.tab
1000 *
1001 * Each of the following constant tables will also identify the corresponding
1002 * table in the <rijndael32.tab> link.
1003 */
1004
1005 /* Corresponds to Rcon[30] (seems to be truncated to include only the used constants) */
1006 unsigned char mtpz_aes_rcon[] =
1007 {
1008 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a
1009 };
1010
1011 /* Corresponds to _S[256] (in hex) */
1012 unsigned char mtpz_aes_sbox[] =
1013 {
1014 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01,
1015 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d,
1016 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4,
1017 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
1018 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7,
1019 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
1020 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e,
1021 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
1022 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb,
1023 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb,
1024 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c,
1025 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
1026 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c,
1027 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d,
1028 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a,
1029 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
1030 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3,
1031 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
1032 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a,
1033 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
1034 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e,
1035 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9,
1036 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9,
1037 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
1038 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99,
1039 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
1040 };
1041
1042 /* Corresponds to _SInv[256] (in hex) */
1043 unsigned char mtpz_aes_invsbox[] =
1044 {
1045 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
1046 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
1047 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
1048 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
1049 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
1050 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
1051 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
1052 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
1053 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
1054 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
1055 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
1056 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
1057 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
1058 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
1059 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
1060 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
1061 };
1062
1063 /* Corresponds to _T3[256] */
1064 unsigned int mtpz_aes_ft1[] =
1065 {
1066 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
1067 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
1068 0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
1069 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
1070 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
1071 0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
1072 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
1073 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
1074 0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
1075 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
1076 0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
1077 0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
1078 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
1079 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
1080 0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
1081 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
1082 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
1083 0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
1084 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
1085 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
1086 0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
1087 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
1088 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
1089 0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
1090 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
1091 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
1092 0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
1093 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
1094 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
1095 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
1096 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
1097 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C,
1098 };
1099
1100 /* Corresponds to _T2[256] */
1101 unsigned int mtpz_aes_ft2[] =
1102 {
1103 0x63A5C663, 0x7C84F87C, 0x7799EE77, 0x7B8DF67B, 0xF20DFFF2, 0x6BBDD66B, 0x6FB1DE6F, 0xC55491C5,
1104 0x30506030, 0x01030201, 0x67A9CE67, 0x2B7D562B, 0xFE19E7FE, 0xD762B5D7, 0xABE64DAB, 0x769AEC76,
1105 0xCA458FCA, 0x829D1F82, 0xC94089C9, 0x7D87FA7D, 0xFA15EFFA, 0x59EBB259, 0x47C98E47, 0xF00BFBF0,
1106 0xADEC41AD, 0xD467B3D4, 0xA2FD5FA2, 0xAFEA45AF, 0x9CBF239C, 0xA4F753A4, 0x7296E472, 0xC05B9BC0,
1107 0xB7C275B7, 0xFD1CE1FD, 0x93AE3D93, 0x266A4C26, 0x365A6C36, 0x3F417E3F, 0xF702F5F7, 0xCC4F83CC,
1108 0x345C6834, 0xA5F451A5, 0xE534D1E5, 0xF108F9F1, 0x7193E271, 0xD873ABD8, 0x31536231, 0x153F2A15,
1109 0x040C0804, 0xC75295C7, 0x23654623, 0xC35E9DC3, 0x18283018, 0x96A13796, 0x050F0A05, 0x9AB52F9A,
1110 0x07090E07, 0x12362412, 0x809B1B80, 0xE23DDFE2, 0xEB26CDEB, 0x27694E27, 0xB2CD7FB2, 0x759FEA75,
1111 0x091B1209, 0x839E1D83, 0x2C74582C, 0x1A2E341A, 0x1B2D361B, 0x6EB2DC6E, 0x5AEEB45A, 0xA0FB5BA0,
1112 0x52F6A452, 0x3B4D763B, 0xD661B7D6, 0xB3CE7DB3, 0x297B5229, 0xE33EDDE3, 0x2F715E2F, 0x84971384,
1113 0x53F5A653, 0xD168B9D1, 0x00000000, 0xED2CC1ED, 0x20604020, 0xFC1FE3FC, 0xB1C879B1, 0x5BEDB65B,
1114 0x6ABED46A, 0xCB468DCB, 0xBED967BE, 0x394B7239, 0x4ADE944A, 0x4CD4984C, 0x58E8B058, 0xCF4A85CF,
1115 0xD06BBBD0, 0xEF2AC5EF, 0xAAE54FAA, 0xFB16EDFB, 0x43C58643, 0x4DD79A4D, 0x33556633, 0x85941185,
1116 0x45CF8A45, 0xF910E9F9, 0x02060402, 0x7F81FE7F, 0x50F0A050, 0x3C44783C, 0x9FBA259F, 0xA8E34BA8,
1117 0x51F3A251, 0xA3FE5DA3, 0x40C08040, 0x8F8A058F, 0x92AD3F92, 0x9DBC219D, 0x38487038, 0xF504F1F5,
1118 0xBCDF63BC, 0xB6C177B6, 0xDA75AFDA, 0x21634221, 0x10302010, 0xFF1AE5FF, 0xF30EFDF3, 0xD26DBFD2,
1119 0xCD4C81CD, 0x0C14180C, 0x13352613, 0xEC2FC3EC, 0x5FE1BE5F, 0x97A23597, 0x44CC8844, 0x17392E17,
1120 0xC45793C4, 0xA7F255A7, 0x7E82FC7E, 0x3D477A3D, 0x64ACC864, 0x5DE7BA5D, 0x192B3219, 0x7395E673,
1121 0x60A0C060, 0x81981981, 0x4FD19E4F, 0xDC7FA3DC, 0x22664422, 0x2A7E542A, 0x90AB3B90, 0x88830B88,
1122 0x46CA8C46, 0xEE29C7EE, 0xB8D36BB8, 0x143C2814, 0xDE79A7DE, 0x5EE2BC5E, 0x0B1D160B, 0xDB76ADDB,
1123 0xE03BDBE0, 0x32566432, 0x3A4E743A, 0x0A1E140A, 0x49DB9249, 0x060A0C06, 0x246C4824, 0x5CE4B85C,
1124 0xC25D9FC2, 0xD36EBDD3, 0xACEF43AC, 0x62A6C462, 0x91A83991, 0x95A43195, 0xE437D3E4, 0x798BF279,
1125 0xE732D5E7, 0xC8438BC8, 0x37596E37, 0x6DB7DA6D, 0x8D8C018D, 0xD564B1D5, 0x4ED29C4E, 0xA9E049A9,
1126 0x6CB4D86C, 0x56FAAC56, 0xF407F3F4, 0xEA25CFEA, 0x65AFCA65, 0x7A8EF47A, 0xAEE947AE, 0x08181008,
1127 0xBAD56FBA, 0x7888F078, 0x256F4A25, 0x2E725C2E, 0x1C24381C, 0xA6F157A6, 0xB4C773B4, 0xC65197C6,
1128 0xE823CBE8, 0xDD7CA1DD, 0x749CE874, 0x1F213E1F, 0x4BDD964B, 0xBDDC61BD, 0x8B860D8B, 0x8A850F8A,
1129 0x7090E070, 0x3E427C3E, 0xB5C471B5, 0x66AACC66, 0x48D89048, 0x03050603, 0xF601F7F6, 0x0E121C0E,
1130 0x61A3C261, 0x355F6A35, 0x57F9AE57, 0xB9D069B9, 0x86911786, 0xC15899C1, 0x1D273A1D, 0x9EB9279E,
1131 0xE138D9E1, 0xF813EBF8, 0x98B32B98, 0x11332211, 0x69BBD269, 0xD970A9D9, 0x8E89078E, 0x94A73394,
1132 0x9BB62D9B, 0x1E223C1E, 0x87921587, 0xE920C9E9, 0xCE4987CE, 0x55FFAA55, 0x28785028, 0xDF7AA5DF,
1133 0x8C8F038C, 0xA1F859A1, 0x89800989, 0x0D171A0D, 0xBFDA65BF, 0xE631D7E6, 0x42C68442, 0x68B8D068,
1134 0x41C38241, 0x99B02999, 0x2D775A2D, 0x0F111E0F, 0xB0CB7BB0, 0x54FCA854, 0xBBD66DBB, 0x163A2C16,
1135 };
1136
1137 /* Corresponds to _T0[256] */
1138 unsigned int mtpz_aes_ft3[] =
1139 {
1140 0xC66363A5, 0xF87C7C84, 0xEE777799, 0xF67B7B8D, 0xFFF2F20D, 0xD66B6BBD, 0xDE6F6FB1, 0x91C5C554,
1141 0x60303050, 0x02010103, 0xCE6767A9, 0x562B2B7D, 0xE7FEFE19, 0xB5D7D762, 0x4DABABE6, 0xEC76769A,
1142 0x8FCACA45, 0x1F82829D, 0x89C9C940, 0xFA7D7D87, 0xEFFAFA15, 0xB25959EB, 0x8E4747C9, 0xFBF0F00B,
1143 0x41ADADEC, 0xB3D4D467, 0x5FA2A2FD, 0x45AFAFEA, 0x239C9CBF, 0x53A4A4F7, 0xE4727296, 0x9BC0C05B,
1144 0x75B7B7C2, 0xE1FDFD1C, 0x3D9393AE, 0x4C26266A, 0x6C36365A, 0x7E3F3F41, 0xF5F7F702, 0x83CCCC4F,
1145 0x6834345C, 0x51A5A5F4, 0xD1E5E534, 0xF9F1F108, 0xE2717193, 0xABD8D873, 0x62313153, 0x2A15153F,
1146 0x0804040C, 0x95C7C752, 0x46232365, 0x9DC3C35E, 0x30181828, 0x379696A1, 0x0A05050F, 0x2F9A9AB5,
1147 0x0E070709, 0x24121236, 0x1B80809B, 0xDFE2E23D, 0xCDEBEB26, 0x4E272769, 0x7FB2B2CD, 0xEA75759F,
1148 0x1209091B, 0x1D83839E, 0x582C2C74, 0x341A1A2E, 0x361B1B2D, 0xDC6E6EB2, 0xB45A5AEE, 0x5BA0A0FB,
1149 0xA45252F6, 0x763B3B4D, 0xB7D6D661, 0x7DB3B3CE, 0x5229297B, 0xDDE3E33E, 0x5E2F2F71, 0x13848497,
1150 0xA65353F5, 0xB9D1D168, 0x00000000, 0xC1EDED2C, 0x40202060, 0xE3FCFC1F, 0x79B1B1C8, 0xB65B5BED,
1151 0xD46A6ABE, 0x8DCBCB46, 0x67BEBED9, 0x7239394B, 0x944A4ADE, 0x984C4CD4, 0xB05858E8, 0x85CFCF4A,
1152 0xBBD0D06B, 0xC5EFEF2A, 0x4FAAAAE5, 0xEDFBFB16, 0x864343C5, 0x9A4D4DD7, 0x66333355, 0x11858594,
1153 0x8A4545CF, 0xE9F9F910, 0x04020206, 0xFE7F7F81, 0xA05050F0, 0x783C3C44, 0x259F9FBA, 0x4BA8A8E3,
1154 0xA25151F3, 0x5DA3A3FE, 0x804040C0, 0x058F8F8A, 0x3F9292AD, 0x219D9DBC, 0x70383848, 0xF1F5F504,
1155 0x63BCBCDF, 0x77B6B6C1, 0xAFDADA75, 0x42212163, 0x20101030, 0xE5FFFF1A, 0xFDF3F30E, 0xBFD2D26D,
1156 0x81CDCD4C, 0x180C0C14, 0x26131335, 0xC3ECEC2F, 0xBE5F5FE1, 0x359797A2, 0x884444CC, 0x2E171739,
1157 0x93C4C457, 0x55A7A7F2, 0xFC7E7E82, 0x7A3D3D47, 0xC86464AC, 0xBA5D5DE7, 0x3219192B, 0xE6737395,
1158 0xC06060A0, 0x19818198, 0x9E4F4FD1, 0xA3DCDC7F, 0x44222266, 0x542A2A7E, 0x3B9090AB, 0x0B888883,
1159 0x8C4646CA, 0xC7EEEE29, 0x6BB8B8D3, 0x2814143C, 0xA7DEDE79, 0xBC5E5EE2, 0x160B0B1D, 0xADDBDB76,
1160 0xDBE0E03B, 0x64323256, 0x743A3A4E, 0x140A0A1E, 0x924949DB, 0x0C06060A, 0x4824246C, 0xB85C5CE4,
1161 0x9FC2C25D, 0xBDD3D36E, 0x43ACACEF, 0xC46262A6, 0x399191A8, 0x319595A4, 0xD3E4E437, 0xF279798B,
1162 0xD5E7E732, 0x8BC8C843, 0x6E373759, 0xDA6D6DB7, 0x018D8D8C, 0xB1D5D564, 0x9C4E4ED2, 0x49A9A9E0,
1163 0xD86C6CB4, 0xAC5656FA, 0xF3F4F407, 0xCFEAEA25, 0xCA6565AF, 0xF47A7A8E, 0x47AEAEE9, 0x10080818,
1164 0x6FBABAD5, 0xF0787888, 0x4A25256F, 0x5C2E2E72, 0x381C1C24, 0x57A6A6F1, 0x73B4B4C7, 0x97C6C651,
1165 0xCBE8E823, 0xA1DDDD7C, 0xE874749C, 0x3E1F1F21, 0x964B4BDD, 0x61BDBDDC, 0x0D8B8B86, 0x0F8A8A85,
1166 0xE0707090, 0x7C3E3E42, 0x71B5B5C4, 0xCC6666AA, 0x904848D8, 0x06030305, 0xF7F6F601, 0x1C0E0E12,
1167 0xC26161A3, 0x6A35355F, 0xAE5757F9, 0x69B9B9D0, 0x17868691, 0x99C1C158, 0x3A1D1D27, 0x279E9EB9,
1168 0xD9E1E138, 0xEBF8F813, 0x2B9898B3, 0x22111133, 0xD26969BB, 0xA9D9D970, 0x078E8E89, 0x339494A7,
1169 0x2D9B9BB6, 0x3C1E1E22, 0x15878792, 0xC9E9E920, 0x87CECE49, 0xAA5555FF, 0x50282878, 0xA5DFDF7A,
1170 0x038C8C8F, 0x59A1A1F8, 0x09898980, 0x1A0D0D17, 0x65BFBFDA, 0xD7E6E631, 0x844242C6, 0xD06868B8,
1171 0x824141C3, 0x299999B0, 0x5A2D2D77, 0x1E0F0F11, 0x7BB0B0CB, 0xA85454FC, 0x6DBBBBD6, 0x2C16163A,
1172 };
1173
1174 /* Corresponds to _T1[256] */
1175 unsigned int mtpz_aes_ft4[] =
1176 {
1177 0xA5C66363, 0x84F87C7C, 0x99EE7777, 0x8DF67B7B, 0x0DFFF2F2, 0xBDD66B6B, 0xB1DE6F6F, 0x5491C5C5,
1178 0x50603030, 0x03020101, 0xA9CE6767, 0x7D562B2B, 0x19E7FEFE, 0x62B5D7D7, 0xE64DABAB, 0x9AEC7676,
1179 0x458FCACA, 0x9D1F8282, 0x4089C9C9, 0x87FA7D7D, 0x15EFFAFA, 0xEBB25959, 0xC98E4747, 0x0BFBF0F0,
1180 0xEC41ADAD, 0x67B3D4D4, 0xFD5FA2A2, 0xEA45AFAF, 0xBF239C9C, 0xF753A4A4, 0x96E47272, 0x5B9BC0C0,
1181 0xC275B7B7, 0x1CE1FDFD, 0xAE3D9393, 0x6A4C2626, 0x5A6C3636, 0x417E3F3F, 0x02F5F7F7, 0x4F83CCCC,
1182 0x5C683434, 0xF451A5A5, 0x34D1E5E5, 0x08F9F1F1, 0x93E27171, 0x73ABD8D8, 0x53623131, 0x3F2A1515,
1183 0x0C080404, 0x5295C7C7, 0x65462323, 0x5E9DC3C3, 0x28301818, 0xA1379696, 0x0F0A0505, 0xB52F9A9A,
1184 0x090E0707, 0x36241212, 0x9B1B8080, 0x3DDFE2E2, 0x26CDEBEB, 0x694E2727, 0xCD7FB2B2, 0x9FEA7575,
1185 0x1B120909, 0x9E1D8383, 0x74582C2C, 0x2E341A1A, 0x2D361B1B, 0xB2DC6E6E, 0xEEB45A5A, 0xFB5BA0A0,
1186 0xF6A45252, 0x4D763B3B, 0x61B7D6D6, 0xCE7DB3B3, 0x7B522929, 0x3EDDE3E3, 0x715E2F2F, 0x97138484,
1187 0xF5A65353, 0x68B9D1D1, 0x00000000, 0x2CC1EDED, 0x60402020, 0x1FE3FCFC, 0xC879B1B1, 0xEDB65B5B,
1188 0xBED46A6A, 0x468DCBCB, 0xD967BEBE, 0x4B723939, 0xDE944A4A, 0xD4984C4C, 0xE8B05858, 0x4A85CFCF,
1189 0x6BBBD0D0, 0x2AC5EFEF, 0xE54FAAAA, 0x16EDFBFB, 0xC5864343, 0xD79A4D4D, 0x55663333, 0x94118585,
1190 0xCF8A4545, 0x10E9F9F9, 0x06040202, 0x81FE7F7F, 0xF0A05050, 0x44783C3C, 0xBA259F9F, 0xE34BA8A8,
1191 0xF3A25151, 0xFE5DA3A3, 0xC0804040, 0x8A058F8F, 0xAD3F9292, 0xBC219D9D, 0x48703838, 0x04F1F5F5,
1192 0xDF63BCBC, 0xC177B6B6, 0x75AFDADA, 0x63422121, 0x30201010, 0x1AE5FFFF, 0x0EFDF3F3, 0x6DBFD2D2,
1193 0x4C81CDCD, 0x14180C0C, 0x35261313, 0x2FC3ECEC, 0xE1BE5F5F, 0xA2359797, 0xCC884444, 0x392E1717,
1194 0x5793C4C4, 0xF255A7A7, 0x82FC7E7E, 0x477A3D3D, 0xACC86464, 0xE7BA5D5D, 0x2B321919, 0x95E67373,
1195 0xA0C06060, 0x98198181, 0xD19E4F4F, 0x7FA3DCDC, 0x66442222, 0x7E542A2A, 0xAB3B9090, 0x830B8888,
1196 0xCA8C4646, 0x29C7EEEE, 0xD36BB8B8, 0x3C281414, 0x79A7DEDE, 0xE2BC5E5E, 0x1D160B0B, 0x76ADDBDB,
1197 0x3BDBE0E0, 0x56643232, 0x4E743A3A, 0x1E140A0A, 0xDB924949, 0x0A0C0606, 0x6C482424, 0xE4B85C5C,
1198 0x5D9FC2C2, 0x6EBDD3D3, 0xEF43ACAC, 0xA6C46262, 0xA8399191, 0xA4319595, 0x37D3E4E4, 0x8BF27979,
1199 0x32D5E7E7, 0x438BC8C8, 0x596E3737, 0xB7DA6D6D, 0x8C018D8D, 0x64B1D5D5, 0xD29C4E4E, 0xE049A9A9,
1200 0xB4D86C6C, 0xFAAC5656, 0x07F3F4F4, 0x25CFEAEA, 0xAFCA6565, 0x8EF47A7A, 0xE947AEAE, 0x18100808,
1201 0xD56FBABA, 0x88F07878, 0x6F4A2525, 0x725C2E2E, 0x24381C1C, 0xF157A6A6, 0xC773B4B4, 0x5197C6C6,
1202 0x23CBE8E8, 0x7CA1DDDD, 0x9CE87474, 0x213E1F1F, 0xDD964B4B, 0xDC61BDBD, 0x860D8B8B, 0x850F8A8A,
1203 0x90E07070, 0x427C3E3E, 0xC471B5B5, 0xAACC6666, 0xD8904848, 0x05060303, 0x01F7F6F6, 0x121C0E0E,
1204 0xA3C26161, 0x5F6A3535, 0xF9AE5757, 0xD069B9B9, 0x91178686, 0x5899C1C1, 0x273A1D1D, 0xB9279E9E,
1205 0x38D9E1E1, 0x13EBF8F8, 0xB32B9898, 0x33221111, 0xBBD26969, 0x70A9D9D9, 0x89078E8E, 0xA7339494,
1206 0xB62D9B9B, 0x223C1E1E, 0x92158787, 0x20C9E9E9, 0x4987CECE, 0xFFAA5555, 0x78502828, 0x7AA5DFDF,
1207 0x8F038C8C, 0xF859A1A1, 0x80098989, 0x171A0D0D, 0xDA65BFBF, 0x31D7E6E6, 0xC6844242, 0xB8D06868,
1208 0xC3824141, 0xB0299999, 0x775A2D2D, 0x111E0F0F, 0xCB7BB0B0, 0xFCA85454, 0xD66DBBBB, 0x3A2C1616,
1209 };
1210
1211 /* Corresponds to _TInv3[256] */
1212 unsigned int mtpz_aes_rt1[] =
1213 {
1214 0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B,
1215 0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5,
1216 0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B,
1217 0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E,
1218 0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D,
1219 0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9,
1220 0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66,
1221 0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED,
1222 0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4,
1223 0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD,
1224 0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60,
1225 0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79,
1226 0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C,
1227 0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24,
1228 0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C,
1229 0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814,
1230 0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B,
1231 0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084,
1232 0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077,
1233 0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22,
1234 0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F,
1235 0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582,
1236 0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB,
1237 0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF,
1238 0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035,
1239 0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17,
1240 0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46,
1241 0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D,
1242 0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A,
1243 0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678,
1244 0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF,
1245 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
1246 };
1247
1248 /* Corresponds to _TInv2[256] */
1249 unsigned int mtpz_aes_rt2[] =
1250 {
1251 0xA75051F4, 0x65537E41, 0xA4C31A17, 0x5E963A27, 0x6BCB3BAB, 0x45F11F9D, 0x58ABACFA, 0x03934BE3,
1252 0xFA552030, 0x6DF6AD76, 0x769188CC, 0x4C25F502, 0xD7FC4FE5, 0xCBD7C52A, 0x44802635, 0xA38FB562,
1253 0x5A49DEB1, 0x1B6725BA, 0x0E9845EA, 0xC0E15DFE, 0x7502C32F, 0xF012814C, 0x97A38D46, 0xF9C66BD3,
1254 0x5FE7038F, 0x9C951592, 0x7AEBBF6D, 0x59DA9552, 0x832DD4BE, 0x21D35874, 0x692949E0, 0xC8448EC9,
1255 0x896A75C2, 0x7978F48E, 0x3E6B9958, 0x71DD27B9, 0x4FB6BEE1, 0xAD17F088, 0xAC66C920, 0x3AB47DCE,
1256 0x4A1863DF, 0x3182E51A, 0x33609751, 0x7F456253, 0x77E0B164, 0xAE84BB6B, 0xA01CFE81, 0x2B94F908,
1257 0x68587048, 0xFD198F45, 0x6C8794DE, 0xF8B7527B, 0xD323AB73, 0x02E2724B, 0x8F57E31F, 0xAB2A6655,
1258 0x2807B2EB, 0xC2032FB5, 0x7B9A86C5, 0x08A5D337, 0x87F23028, 0xA5B223BF, 0x6ABA0203, 0x825CED16,
1259 0x1C2B8ACF, 0xB492A779, 0xF2F0F307, 0xE2A14E69, 0xF4CD65DA, 0xBED50605, 0x621FD134, 0xFE8AC4A6,
1260 0x539D342E, 0x55A0A2F3, 0xE132058A, 0xEB75A4F6, 0xEC390B83, 0xEFAA4060, 0x9F065E71, 0x1051BD6E,
1261 0x8AF93E21, 0x063D96DD, 0x05AEDD3E, 0xBD464DE6, 0x8DB59154, 0x5D0571C4, 0xD46F0406, 0x15FF6050,
1262 0xFB241998, 0xE997D6BD, 0x43CC8940, 0x9E7767D9, 0x42BDB0E8, 0x8B880789, 0x5B38E719, 0xEEDB79C8,
1263 0x0A47A17C, 0x0FE97C42, 0x1EC9F884, 0x00000000, 0x86830980, 0xED48322B, 0x70AC1E11, 0x724E6C5A,
1264 0xFFFBFD0E, 0x38560F85, 0xD51E3DAE, 0x3927362D, 0xD9640A0F, 0xA621685C, 0x54D19B5B, 0x2E3A2436,
1265 0x67B10C0A, 0xE70F9357, 0x96D2B4EE, 0x919E1B9B, 0xC54F80C0, 0x20A261DC, 0x4B695A77, 0x1A161C12,
1266 0xBA0AE293, 0x2AE5C0A0, 0xE0433C22, 0x171D121B, 0x0D0B0E09, 0xC7ADF28B, 0xA8B92DB6, 0xA9C8141E,
1267 0x198557F1, 0x074CAF75, 0xDDBBEE99, 0x60FDA37F, 0x269FF701, 0xF5BC5C72, 0x3BC54466, 0x7E345BFB,
1268 0x29768B43, 0xC6DCCB23, 0xFC68B6ED, 0xF163B8E4, 0xDCCAD731, 0x85104263, 0x22401397, 0x112084C6,
1269 0x247D854A, 0x3DF8D2BB, 0x3211AEF9, 0xA16DC729, 0x2F4B1D9E, 0x30F3DCB2, 0x52EC0D86, 0xE3D077C1,
1270 0x166C2BB3, 0xB999A970, 0x48FA1194, 0x642247E9, 0x8CC4A8FC, 0x3F1AA0F0, 0x2CD8567D, 0x90EF2233,
1271 0x4EC78749, 0xD1C1D938, 0xA2FE8CCA, 0x0B3698D4, 0x81CFA6F5, 0xDE28A57A, 0x8E26DAB7, 0xBFA43FAD,
1272 0x9DE42C3A, 0x920D5078, 0xCC9B6A5F, 0x4662547E, 0x13C2F68D, 0xB8E890D8, 0xF75E2E39, 0xAFF582C3,
1273 0x80BE9F5D, 0x937C69D0, 0x2DA96FD5, 0x12B3CF25, 0x993BC8AC, 0x7DA71018, 0x636EE89C, 0xBB7BDB3B,
1274 0x7809CD26, 0x18F46E59, 0xB701EC9A, 0x9AA8834F, 0x6E65E695, 0xE67EAAFF, 0xCF0821BC, 0xE8E6EF15,
1275 0x9BD9BAE7, 0x36CE4A6F, 0x09D4EA9F, 0x7CD629B0, 0xB2AF31A4, 0x23312A3F, 0x9430C6A5, 0x66C035A2,
1276 0xBC37744E, 0xCAA6FC82, 0xD0B0E090, 0xD81533A7, 0x984AF104, 0xDAF741EC, 0x500E7FCD, 0xF62F1791,
1277 0xD68D764D, 0xB04D43EF, 0x4D54CCAA, 0x04DFE496, 0xB5E39ED1, 0x881B4C6A, 0x1FB8C12C, 0x517F4665,
1278 0xEA049D5E, 0x355D018C, 0x7473FA87, 0x412EFB0B, 0x1D5AB367, 0xD25292DB, 0x5633E910, 0x47136DD6,
1279 0x618C9AD7, 0x0C7A37A1, 0x148E59F8, 0x3C89EB13, 0x27EECEA9, 0xC935B761, 0xE5EDE11C, 0xB13C7A47,
1280 0xDF599CD2, 0x733F55F2, 0xCE791814, 0x37BF73C7, 0xCDEA53F7, 0xAA5B5FFD, 0x6F14DF3D, 0xDB867844,
1281 0xF381CAAF, 0xC43EB968, 0x342C3824, 0x405FC2A3, 0xC372161D, 0x250CBCE2, 0x498B283C, 0x9541FF0D,
1282 0x017139A8, 0xB3DE080C, 0xE49CD8B4, 0xC1906456, 0x84617BCB, 0xB670D532, 0x5C74486C, 0x5742D0B8
1283 };
1284
1285 /* Corresponds to _TInv0[256] */
1286 unsigned int mtpz_aes_rt3[] =
1287 {
1288 0x51F4A750, 0x7E416553, 0x1A17A4C3, 0x3A275E96, 0x3BAB6BCB, 0x1F9D45F1, 0xACFA58AB, 0x4BE30393,
1289 0x2030FA55, 0xAD766DF6, 0x88CC7691, 0xF5024C25, 0x4FE5D7FC, 0xC52ACBD7, 0x26354480, 0xB562A38F,
1290 0xDEB15A49, 0x25BA1B67, 0x45EA0E98, 0x5DFEC0E1, 0xC32F7502, 0x814CF012, 0x8D4697A3, 0x6BD3F9C6,
1291 0x038F5FE7, 0x15929C95, 0xBF6D7AEB, 0x955259DA, 0xD4BE832D, 0x587421D3, 0x49E06929, 0x8EC9C844,
1292 0x75C2896A, 0xF48E7978, 0x99583E6B, 0x27B971DD, 0xBEE14FB6, 0xF088AD17, 0xC920AC66, 0x7DCE3AB4,
1293 0x63DF4A18, 0xE51A3182, 0x97513360, 0x62537F45, 0xB16477E0, 0xBB6BAE84, 0xFE81A01C, 0xF9082B94,
1294 0x70486858, 0x8F45FD19, 0x94DE6C87, 0x527BF8B7, 0xAB73D323, 0x724B02E2, 0xE31F8F57, 0x6655AB2A,
1295 0xB2EB2807, 0x2FB5C203, 0x86C57B9A, 0xD33708A5, 0x302887F2, 0x23BFA5B2, 0x02036ABA, 0xED16825C,
1296 0x8ACF1C2B, 0xA779B492, 0xF307F2F0, 0x4E69E2A1, 0x65DAF4CD, 0x0605BED5, 0xD134621F, 0xC4A6FE8A,
1297 0x342E539D, 0xA2F355A0, 0x058AE132, 0xA4F6EB75, 0x0B83EC39, 0x4060EFAA, 0x5E719F06, 0xBD6E1051,
1298 0x3E218AF9, 0x96DD063D, 0xDD3E05AE, 0x4DE6BD46, 0x91548DB5, 0x71C45D05, 0x0406D46F, 0x605015FF,
1299 0x1998FB24, 0xD6BDE997, 0x894043CC, 0x67D99E77, 0xB0E842BD, 0x07898B88, 0xE7195B38, 0x79C8EEDB,
1300 0xA17C0A47, 0x7C420FE9, 0xF8841EC9, 0x00000000, 0x09808683, 0x322BED48, 0x1E1170AC, 0x6C5A724E,
1301 0xFD0EFFFB, 0x0F853856, 0x3DAED51E, 0x362D3927, 0x0A0FD964, 0x685CA621, 0x9B5B54D1, 0x24362E3A,
1302 0x0C0A67B1, 0x9357E70F, 0xB4EE96D2, 0x1B9B919E, 0x80C0C54F, 0x61DC20A2, 0x5A774B69, 0x1C121A16,
1303 0xE293BA0A, 0xC0A02AE5, 0x3C22E043, 0x121B171D, 0x0E090D0B, 0xF28BC7AD, 0x2DB6A8B9, 0x141EA9C8,
1304 0x57F11985, 0xAF75074C, 0xEE99DDBB, 0xA37F60FD, 0xF701269F, 0x5C72F5BC, 0x44663BC5, 0x5BFB7E34,
1305 0x8B432976, 0xCB23C6DC, 0xB6EDFC68, 0xB8E4F163, 0xD731DCCA, 0x42638510, 0x13972240, 0x84C61120,
1306 0x854A247D, 0xD2BB3DF8, 0xAEF93211, 0xC729A16D, 0x1D9E2F4B, 0xDCB230F3, 0x0D8652EC, 0x77C1E3D0,
1307 0x2BB3166C, 0xA970B999, 0x119448FA, 0x47E96422, 0xA8FC8CC4, 0xA0F03F1A, 0x567D2CD8, 0x223390EF,
1308 0x87494EC7, 0xD938D1C1, 0x8CCAA2FE, 0x98D40B36, 0xA6F581CF, 0xA57ADE28, 0xDAB78E26, 0x3FADBFA4,
1309 0x2C3A9DE4, 0x5078920D, 0x6A5FCC9B, 0x547E4662, 0xF68D13C2, 0x90D8B8E8, 0x2E39F75E, 0x82C3AFF5,
1310 0x9F5D80BE, 0x69D0937C, 0x6FD52DA9, 0xCF2512B3, 0xC8AC993B, 0x10187DA7, 0xE89C636E, 0xDB3BBB7B,
1311 0xCD267809, 0x6E5918F4, 0xEC9AB701, 0x834F9AA8, 0xE6956E65, 0xAAFFE67E, 0x21BCCF08, 0xEF15E8E6,
1312 0xBAE79BD9, 0x4A6F36CE, 0xEA9F09D4, 0x29B07CD6, 0x31A4B2AF, 0x2A3F2331, 0xC6A59430, 0x35A266C0,
1313 0x744EBC37, 0xFC82CAA6, 0xE090D0B0, 0x33A7D815, 0xF104984A, 0x41ECDAF7, 0x7FCD500E, 0x1791F62F,
1314 0x764DD68D, 0x43EFB04D, 0xCCAA4D54, 0xE49604DF, 0x9ED1B5E3, 0x4C6A881B, 0xC12C1FB8, 0x4665517F,
1315 0x9D5EEA04, 0x018C355D, 0xFA877473, 0xFB0B412E, 0xB3671D5A, 0x92DBD252, 0xE9105633, 0x6DD64713,
1316 0x9AD7618C, 0x37A10C7A, 0x59F8148E, 0xEB133C89, 0xCEA927EE, 0xB761C935, 0xE11CE5ED, 0x7A47B13C,
1317 0x9CD2DF59, 0x55F2733F, 0x1814CE79, 0x73C737BF, 0x53F7CDEA, 0x5FFDAA5B, 0xDF3D6F14, 0x7844DB86,
1318 0xCAAFF381, 0xB968C43E, 0x3824342C, 0xC2A3405F, 0x161DC372, 0xBCE2250C, 0x283C498B, 0xFF0D9541,
1319 0x39A80171, 0x080CB3DE, 0xD8B4E49C, 0x6456C190, 0x7BCB8461, 0xD532B670, 0x486C5C74, 0xD0B85742
1320 };
1321
1322 /* Corresponds to _TInv1[256] */
1323 unsigned int mtpz_aes_rt4[] =
1324 {
1325 0x5051F4A7, 0x537E4165, 0xC31A17A4, 0x963A275E, 0xCB3BAB6B, 0xF11F9D45, 0xABACFA58, 0x934BE303,
1326 0x552030FA, 0xF6AD766D, 0x9188CC76, 0x25F5024C, 0xFC4FE5D7, 0xD7C52ACB, 0x80263544, 0x8FB562A3,
1327 0x49DEB15A, 0x6725BA1B, 0x9845EA0E, 0xE15DFEC0, 0x02C32F75, 0x12814CF0, 0xA38D4697, 0xC66BD3F9,
1328 0xE7038F5F, 0x9515929C, 0xEBBF6D7A, 0xDA955259, 0x2DD4BE83, 0xD3587421, 0x2949E069, 0x448EC9C8,
1329 0x6A75C289, 0x78F48E79, 0x6B99583E, 0xDD27B971, 0xB6BEE14F, 0x17F088AD, 0x66C920AC, 0xB47DCE3A,
1330 0x1863DF4A, 0x82E51A31, 0x60975133, 0x4562537F, 0xE0B16477, 0x84BB6BAE, 0x1CFE81A0, 0x94F9082B,
1331 0x58704868, 0x198F45FD, 0x8794DE6C, 0xB7527BF8, 0x23AB73D3, 0xE2724B02, 0x57E31F8F, 0x2A6655AB,
1332 0x07B2EB28, 0x032FB5C2, 0x9A86C57B, 0xA5D33708, 0xF2302887, 0xB223BFA5, 0xBA02036A, 0x5CED1682,
1333 0x2B8ACF1C, 0x92A779B4, 0xF0F307F2, 0xA14E69E2, 0xCD65DAF4, 0xD50605BE, 0x1FD13462, 0x8AC4A6FE,
1334 0x9D342E53, 0xA0A2F355, 0x32058AE1, 0x75A4F6EB, 0x390B83EC, 0xAA4060EF, 0x065E719F, 0x51BD6E10,
1335 0xF93E218A, 0x3D96DD06, 0xAEDD3E05, 0x464DE6BD, 0xB591548D, 0x0571C45D, 0x6F0406D4, 0xFF605015,
1336 0x241998FB, 0x97D6BDE9, 0xCC894043, 0x7767D99E, 0xBDB0E842, 0x8807898B, 0x38E7195B, 0xDB79C8EE,
1337 0x47A17C0A, 0xE97C420F, 0xC9F8841E, 0x00000000, 0x83098086, 0x48322BED, 0xAC1E1170, 0x4E6C5A72,
1338 0xFBFD0EFF, 0x560F8538, 0x1E3DAED5, 0x27362D39, 0x640A0FD9, 0x21685CA6, 0xD19B5B54, 0x3A24362E,
1339 0xB10C0A67, 0x0F9357E7, 0xD2B4EE96, 0x9E1B9B91, 0x4F80C0C5, 0xA261DC20, 0x695A774B, 0x161C121A,
1340 0x0AE293BA, 0xE5C0A02A, 0x433C22E0, 0x1D121B17, 0x0B0E090D, 0xADF28BC7, 0xB92DB6A8, 0xC8141EA9,
1341 0x8557F119, 0x4CAF7507, 0xBBEE99DD, 0xFDA37F60, 0x9FF70126, 0xBC5C72F5, 0xC544663B, 0x345BFB7E,
1342 0x768B4329, 0xDCCB23C6, 0x68B6EDFC, 0x63B8E4F1, 0xCAD731DC, 0x10426385, 0x40139722, 0x2084C611,
1343 0x7D854A24, 0xF8D2BB3D, 0x11AEF932, 0x6DC729A1, 0x4B1D9E2F, 0xF3DCB230, 0xEC0D8652, 0xD077C1E3,
1344 0x6C2BB316, 0x99A970B9, 0xFA119448, 0x2247E964, 0xC4A8FC8C, 0x1AA0F03F, 0xD8567D2C, 0xEF223390,
1345 0xC787494E, 0xC1D938D1, 0xFE8CCAA2, 0x3698D40B, 0xCFA6F581, 0x28A57ADE, 0x26DAB78E, 0xA43FADBF,
1346 0xE42C3A9D, 0x0D507892, 0x9B6A5FCC, 0x62547E46, 0xC2F68D13, 0xE890D8B8, 0x5E2E39F7, 0xF582C3AF,
1347 0xBE9F5D80, 0x7C69D093, 0xA96FD52D, 0xB3CF2512, 0x3BC8AC99, 0xA710187D, 0x6EE89C63, 0x7BDB3BBB,
1348 0x09CD2678, 0xF46E5918, 0x01EC9AB7, 0xA8834F9A, 0x65E6956E, 0x7EAAFFE6, 0x0821BCCF, 0xE6EF15E8,
1349 0xD9BAE79B, 0xCE4A6F36, 0xD4EA9F09, 0xD629B07C, 0xAF31A4B2, 0x312A3F23, 0x30C6A594, 0xC035A266,
1350 0x37744EBC, 0xA6FC82CA, 0xB0E090D0, 0x1533A7D8, 0x4AF10498, 0xF741ECDA, 0x0E7FCD50, 0x2F1791F6,
1351 0x8D764DD6, 0x4D43EFB0, 0x54CCAA4D, 0xDFE49604, 0xE39ED1B5, 0x1B4C6A88, 0xB8C12C1F, 0x7F466551,
1352 0x049D5EEA, 0x5D018C35, 0x73FA8774, 0x2EFB0B41, 0x5AB3671D, 0x5292DBD2, 0x33E91056, 0x136DD647,
1353 0x8C9AD761, 0x7A37A10C, 0x8E59F814, 0x89EB133C, 0xEECEA927, 0x35B761C9, 0xEDE11CE5, 0x3C7A47B1,
1354 0x599CD2DF, 0x3F55F273, 0x791814CE, 0xBF73C737, 0xEA53F7CD, 0x5B5FFDAA, 0x14DF3D6F, 0x867844DB,
1355 0x81CAAFF3, 0x3EB968C4, 0x2C382434, 0x5FC2A340, 0x72161DC3, 0x0CBCE225, 0x8B283C49, 0x41FF0D95,
1356 0x7139A801, 0xDE080CB3, 0x9CD8B4E4, 0x906456C1, 0x617BCB84, 0x70D532B6, 0x74486C5C, 0x42D0B857
1357 };
1358
1359 /* Corresponds to _IMXC1[256] */
1360 unsigned int mtpz_aes_gb11[] =
1361 {
1362 0x00000000, 0x0B0E090D, 0x161C121A, 0x1D121B17, 0x2C382434, 0x27362D39, 0x3A24362E, 0x312A3F23,
1363 0x58704868, 0x537E4165, 0x4E6C5A72, 0x4562537F, 0x74486C5C, 0x7F466551, 0x62547E46, 0x695A774B,
1364 0xB0E090D0, 0xBBEE99DD, 0xA6FC82CA, 0xADF28BC7, 0x9CD8B4E4, 0x97D6BDE9, 0x8AC4A6FE, 0x81CAAFF3,
1365 0xE890D8B8, 0xE39ED1B5, 0xFE8CCAA2, 0xF582C3AF, 0xC4A8FC8C, 0xCFA6F581, 0xD2B4EE96, 0xD9BAE79B,
1366 0x7BDB3BBB, 0x70D532B6, 0x6DC729A1, 0x66C920AC, 0x57E31F8F, 0x5CED1682, 0x41FF0D95, 0x4AF10498,
1367 0x23AB73D3, 0x28A57ADE, 0x35B761C9, 0x3EB968C4, 0x0F9357E7, 0x049D5EEA, 0x198F45FD, 0x12814CF0,
1368 0xCB3BAB6B, 0xC035A266, 0xDD27B971, 0xD629B07C, 0xE7038F5F, 0xEC0D8652, 0xF11F9D45, 0xFA119448,
1369 0x934BE303, 0x9845EA0E, 0x8557F119, 0x8E59F814, 0xBF73C737, 0xB47DCE3A, 0xA96FD52D, 0xA261DC20,
1370 0xF6AD766D, 0xFDA37F60, 0xE0B16477, 0xEBBF6D7A, 0xDA955259, 0xD19B5B54, 0xCC894043, 0xC787494E,
1371 0xAEDD3E05, 0xA5D33708, 0xB8C12C1F, 0xB3CF2512, 0x82E51A31, 0x89EB133C, 0x94F9082B, 0x9FF70126,
1372 0x464DE6BD, 0x4D43EFB0, 0x5051F4A7, 0x5B5FFDAA, 0x6A75C289, 0x617BCB84, 0x7C69D093, 0x7767D99E,
1373 0x1E3DAED5, 0x1533A7D8, 0x0821BCCF, 0x032FB5C2, 0x32058AE1, 0x390B83EC, 0x241998FB, 0x2F1791F6,
1374 0x8D764DD6, 0x867844DB, 0x9B6A5FCC, 0x906456C1, 0xA14E69E2, 0xAA4060EF, 0xB7527BF8, 0xBC5C72F5,
1375 0xD50605BE, 0xDE080CB3, 0xC31A17A4, 0xC8141EA9, 0xF93E218A, 0xF2302887, 0xEF223390, 0xE42C3A9D,
1376 0x3D96DD06, 0x3698D40B, 0x2B8ACF1C, 0x2084C611, 0x11AEF932, 0x1AA0F03F, 0x07B2EB28, 0x0CBCE225,
1377 0x65E6956E, 0x6EE89C63, 0x73FA8774, 0x78F48E79, 0x49DEB15A, 0x42D0B857, 0x5FC2A340, 0x54CCAA4D,
1378 0xF741ECDA, 0xFC4FE5D7, 0xE15DFEC0, 0xEA53F7CD, 0xDB79C8EE, 0xD077C1E3, 0xCD65DAF4, 0xC66BD3F9,
1379 0xAF31A4B2, 0xA43FADBF, 0xB92DB6A8, 0xB223BFA5, 0x83098086, 0x8807898B, 0x9515929C, 0x9E1B9B91,
1380 0x47A17C0A, 0x4CAF7507, 0x51BD6E10, 0x5AB3671D, 0x6B99583E, 0x60975133, 0x7D854A24, 0x768B4329,
1381 0x1FD13462, 0x14DF3D6F, 0x09CD2678, 0x02C32F75, 0x33E91056, 0x38E7195B, 0x25F5024C, 0x2EFB0B41,
1382 0x8C9AD761, 0x8794DE6C, 0x9A86C57B, 0x9188CC76, 0xA0A2F355, 0xABACFA58, 0xB6BEE14F, 0xBDB0E842,
1383 0xD4EA9F09, 0xDFE49604, 0xC2F68D13, 0xC9F8841E, 0xF8D2BB3D, 0xF3DCB230, 0xEECEA927, 0xE5C0A02A,
1384 0x3C7A47B1, 0x37744EBC, 0x2A6655AB, 0x21685CA6, 0x10426385, 0x1B4C6A88, 0x065E719F, 0x0D507892,
1385 0x640A0FD9, 0x6F0406D4, 0x72161DC3, 0x791814CE, 0x48322BED, 0x433C22E0, 0x5E2E39F7, 0x552030FA,
1386 0x01EC9AB7, 0x0AE293BA, 0x17F088AD, 0x1CFE81A0, 0x2DD4BE83, 0x26DAB78E, 0x3BC8AC99, 0x30C6A594,
1387 0x599CD2DF, 0x5292DBD2, 0x4F80C0C5, 0x448EC9C8, 0x75A4F6EB, 0x7EAAFFE6, 0x63B8E4F1, 0x68B6EDFC,
1388 0xB10C0A67, 0xBA02036A, 0xA710187D, 0xAC1E1170, 0x9D342E53, 0x963A275E, 0x8B283C49, 0x80263544,
1389 0xE97C420F, 0xE2724B02, 0xFF605015, 0xF46E5918, 0xC544663B, 0xCE4A6F36, 0xD3587421, 0xD8567D2C,
1390 0x7A37A10C, 0x7139A801, 0x6C2BB316, 0x6725BA1B, 0x560F8538, 0x5D018C35, 0x40139722, 0x4B1D9E2F,
1391 0x2247E964, 0x2949E069, 0x345BFB7E, 0x3F55F273, 0x0E7FCD50, 0x0571C45D, 0x1863DF4A, 0x136DD647,
1392 0xCAD731DC, 0xC1D938D1, 0xDCCB23C6, 0xD7C52ACB, 0xE6EF15E8, 0xEDE11CE5, 0xF0F307F2, 0xFBFD0EFF,
1393 0x92A779B4, 0x99A970B9, 0x84BB6BAE, 0x8FB562A3, 0xBE9F5D80, 0xB591548D, 0xA8834F9A, 0xA38D4697,
1394 };
1395
1396 /* Corresponds to _IMXC0[256] */
1397 unsigned int mtpz_aes_gb14[] =
1398 {
1399 0x00000000, 0x0E090D0B, 0x1C121A16, 0x121B171D, 0x3824342C, 0x362D3927, 0x24362E3A, 0x2A3F2331,
1400 0x70486858, 0x7E416553, 0x6C5A724E, 0x62537F45, 0x486C5C74, 0x4665517F, 0x547E4662, 0x5A774B69,
1401 0xE090D0B0, 0xEE99DDBB, 0xFC82CAA6, 0xF28BC7AD, 0xD8B4E49C, 0xD6BDE997, 0xC4A6FE8A, 0xCAAFF381,
1402 0x90D8B8E8, 0x9ED1B5E3, 0x8CCAA2FE, 0x82C3AFF5, 0xA8FC8CC4, 0xA6F581CF, 0xB4EE96D2, 0xBAE79BD9,
1403 0xDB3BBB7B, 0xD532B670, 0xC729A16D, 0xC920AC66, 0xE31F8F57, 0xED16825C, 0xFF0D9541, 0xF104984A,
1404 0xAB73D323, 0xA57ADE28, 0xB761C935, 0xB968C43E, 0x9357E70F, 0x9D5EEA04, 0x8F45FD19, 0x814CF012,
1405 0x3BAB6BCB, 0x35A266C0, 0x27B971DD, 0x29B07CD6, 0x038F5FE7, 0x0D8652EC, 0x1F9D45F1, 0x119448FA,
1406 0x4BE30393, 0x45EA0E98, 0x57F11985, 0x59F8148E, 0x73C737BF, 0x7DCE3AB4, 0x6FD52DA9, 0x61DC20A2,
1407 0xAD766DF6, 0xA37F60FD, 0xB16477E0, 0xBF6D7AEB, 0x955259DA, 0x9B5B54D1, 0x894043CC, 0x87494EC7,
1408 0xDD3E05AE, 0xD33708A5, 0xC12C1FB8, 0xCF2512B3, 0xE51A3182, 0xEB133C89, 0xF9082B94, 0xF701269F,
1409 0x4DE6BD46, 0x43EFB04D, 0x51F4A750, 0x5FFDAA5B, 0x75C2896A, 0x7BCB8461, 0x69D0937C, 0x67D99E77,
1410 0x3DAED51E, 0x33A7D815, 0x21BCCF08, 0x2FB5C203, 0x058AE132, 0x0B83EC39, 0x1998FB24, 0x1791F62F,
1411 0x764DD68D, 0x7844DB86, 0x6A5FCC9B, 0x6456C190, 0x4E69E2A1, 0x4060EFAA, 0x527BF8B7, 0x5C72F5BC,
1412 0x0605BED5, 0x080CB3DE, 0x1A17A4C3, 0x141EA9C8, 0x3E218AF9, 0x302887F2, 0x223390EF, 0x2C3A9DE4,
1413 0x96DD063D, 0x98D40B36, 0x8ACF1C2B, 0x84C61120, 0xAEF93211, 0xA0F03F1A, 0xB2EB2807, 0xBCE2250C,
1414 0xE6956E65, 0xE89C636E, 0xFA877473, 0xF48E7978, 0xDEB15A49, 0xD0B85742, 0xC2A3405F, 0xCCAA4D54,
1415 0x41ECDAF7, 0x4FE5D7FC, 0x5DFEC0E1, 0x53F7CDEA, 0x79C8EEDB, 0x77C1E3D0, 0x65DAF4CD, 0x6BD3F9C6,
1416 0x31A4B2AF, 0x3FADBFA4, 0x2DB6A8B9, 0x23BFA5B2, 0x09808683, 0x07898B88, 0x15929C95, 0x1B9B919E,
1417 0xA17C0A47, 0xAF75074C, 0xBD6E1051, 0xB3671D5A, 0x99583E6B, 0x97513360, 0x854A247D, 0x8B432976,
1418 0xD134621F, 0xDF3D6F14, 0xCD267809, 0xC32F7502, 0xE9105633, 0xE7195B38, 0xF5024C25, 0xFB0B412E,
1419 0x9AD7618C, 0x94DE6C87, 0x86C57B9A, 0x88CC7691, 0xA2F355A0, 0xACFA58AB, 0xBEE14FB6, 0xB0E842BD,
1420 0xEA9F09D4, 0xE49604DF, 0xF68D13C2, 0xF8841EC9, 0xD2BB3DF8, 0xDCB230F3, 0xCEA927EE, 0xC0A02AE5,
1421 0x7A47B13C, 0x744EBC37, 0x6655AB2A, 0x685CA621, 0x42638510, 0x4C6A881B, 0x5E719F06, 0x5078920D,
1422 0x0A0FD964, 0x0406D46F, 0x161DC372, 0x1814CE79, 0x322BED48, 0x3C22E043, 0x2E39F75E, 0x2030FA55,
1423 0xEC9AB701, 0xE293BA0A, 0xF088AD17, 0xFE81A01C, 0xD4BE832D, 0xDAB78E26, 0xC8AC993B, 0xC6A59430,
1424 0x9CD2DF59, 0x92DBD252, 0x80C0C54F, 0x8EC9C844, 0xA4F6EB75, 0xAAFFE67E, 0xB8E4F163, 0xB6EDFC68,
1425 0x0C0A67B1, 0x02036ABA, 0x10187DA7, 0x1E1170AC, 0x342E539D, 0x3A275E96, 0x283C498B, 0x26354480,
1426 0x7C420FE9, 0x724B02E2, 0x605015FF, 0x6E5918F4, 0x44663BC5, 0x4A6F36CE, 0x587421D3, 0x567D2CD8,
1427 0x37A10C7A, 0x39A80171, 0x2BB3166C, 0x25BA1B67, 0x0F853856, 0x018C355D, 0x13972240, 0x1D9E2F4B,
1428 0x47E96422, 0x49E06929, 0x5BFB7E34, 0x55F2733F, 0x7FCD500E, 0x71C45D05, 0x63DF4A18, 0x6DD64713,
1429 0xD731DCCA, 0xD938D1C1, 0xCB23C6DC, 0xC52ACBD7, 0xEF15E8E6, 0xE11CE5ED, 0xF307F2F0, 0xFD0EFFFB,
1430 0xA779B492, 0xA970B999, 0xBB6BAE84, 0xB562A38F, 0x9F5D80BE, 0x91548DB5, 0x834F9AA8, 0x8D4697A3,
1431 } ;
1432
1433 /* Corresponds to _IMXC2[256] */
1434 unsigned int mtpz_aes_gb13[] =
1435 {
1436 0x00000000, 0x0D0B0E09, 0x1A161C12, 0x171D121B, 0x342C3824, 0x3927362D, 0x2E3A2436, 0x23312A3F,
1437 0x68587048, 0x65537E41, 0x724E6C5A, 0x7F456253, 0x5C74486C, 0x517F4665, 0x4662547E, 0x4B695A77,
1438 0xD0B0E090, 0xDDBBEE99, 0xCAA6FC82, 0xC7ADF28B, 0xE49CD8B4, 0xE997D6BD, 0xFE8AC4A6, 0xF381CAAF,
1439 0xB8E890D8, 0xB5E39ED1, 0xA2FE8CCA, 0xAFF582C3, 0x8CC4A8FC, 0x81CFA6F5, 0x96D2B4EE, 0x9BD9BAE7,
1440 0xBB7BDB3B, 0xB670D532, 0xA16DC729, 0xAC66C920, 0x8F57E31F, 0x825CED16, 0x9541FF0D, 0x984AF104,
1441 0xD323AB73, 0xDE28A57A, 0xC935B761, 0xC43EB968, 0xE70F9357, 0xEA049D5E, 0xFD198F45, 0xF012814C,
1442 0x6BCB3BAB, 0x66C035A2, 0x71DD27B9, 0x7CD629B0, 0x5FE7038F, 0x52EC0D86, 0x45F11F9D, 0x48FA1194,
1443 0x03934BE3, 0x0E9845EA, 0x198557F1, 0x148E59F8, 0x37BF73C7, 0x3AB47DCE, 0x2DA96FD5, 0x20A261DC,
1444 0x6DF6AD76, 0x60FDA37F, 0x77E0B164, 0x7AEBBF6D, 0x59DA9552, 0x54D19B5B, 0x43CC8940, 0x4EC78749,
1445 0x05AEDD3E, 0x08A5D337, 0x1FB8C12C, 0x12B3CF25, 0x3182E51A, 0x3C89EB13, 0x2B94F908, 0x269FF701,
1446 0xBD464DE6, 0xB04D43EF, 0xA75051F4, 0xAA5B5FFD, 0x896A75C2, 0x84617BCB, 0x937C69D0, 0x9E7767D9,
1447 0xD51E3DAE, 0xD81533A7, 0xCF0821BC, 0xC2032FB5, 0xE132058A, 0xEC390B83, 0xFB241998, 0xF62F1791,
1448 0xD68D764D, 0xDB867844, 0xCC9B6A5F, 0xC1906456, 0xE2A14E69, 0xEFAA4060, 0xF8B7527B, 0xF5BC5C72,
1449 0xBED50605, 0xB3DE080C, 0xA4C31A17, 0xA9C8141E, 0x8AF93E21, 0x87F23028, 0x90EF2233, 0x9DE42C3A,
1450 0x063D96DD, 0x0B3698D4, 0x1C2B8ACF, 0x112084C6, 0x3211AEF9, 0x3F1AA0F0, 0x2807B2EB, 0x250CBCE2,
1451 0x6E65E695, 0x636EE89C, 0x7473FA87, 0x7978F48E, 0x5A49DEB1, 0x5742D0B8, 0x405FC2A3, 0x4D54CCAA,
1452 0xDAF741EC, 0xD7FC4FE5, 0xC0E15DFE, 0xCDEA53F7, 0xEEDB79C8, 0xE3D077C1, 0xF4CD65DA, 0xF9C66BD3,
1453 0xB2AF31A4, 0xBFA43FAD, 0xA8B92DB6, 0xA5B223BF, 0x86830980, 0x8B880789, 0x9C951592, 0x919E1B9B,
1454 0x0A47A17C, 0x074CAF75, 0x1051BD6E, 0x1D5AB367, 0x3E6B9958, 0x33609751, 0x247D854A, 0x29768B43,
1455 0x621FD134, 0x6F14DF3D, 0x7809CD26, 0x7502C32F, 0x5633E910, 0x5B38E719, 0x4C25F502, 0x412EFB0B,
1456 0x618C9AD7, 0x6C8794DE, 0x7B9A86C5, 0x769188CC, 0x55A0A2F3, 0x58ABACFA, 0x4FB6BEE1, 0x42BDB0E8,
1457 0x09D4EA9F, 0x04DFE496, 0x13C2F68D, 0x1EC9F884, 0x3DF8D2BB, 0x30F3DCB2, 0x27EECEA9, 0x2AE5C0A0,
1458 0xB13C7A47, 0xBC37744E, 0xAB2A6655, 0xA621685C, 0x85104263, 0x881B4C6A, 0x9F065E71, 0x920D5078,
1459 0xD9640A0F, 0xD46F0406, 0xC372161D, 0xCE791814, 0xED48322B, 0xE0433C22, 0xF75E2E39, 0xFA552030,
1460 0xB701EC9A, 0xBA0AE293, 0xAD17F088, 0xA01CFE81, 0x832DD4BE, 0x8E26DAB7, 0x993BC8AC, 0x9430C6A5,
1461 0xDF599CD2, 0xD25292DB, 0xC54F80C0, 0xC8448EC9, 0xEB75A4F6, 0xE67EAAFF, 0xF163B8E4, 0xFC68B6ED,
1462 0x67B10C0A, 0x6ABA0203, 0x7DA71018, 0x70AC1E11, 0x539D342E, 0x5E963A27, 0x498B283C, 0x44802635,
1463 0x0FE97C42, 0x02E2724B, 0x15FF6050, 0x18F46E59, 0x3BC54466, 0x36CE4A6F, 0x21D35874, 0x2CD8567D,
1464 0x0C7A37A1, 0x017139A8, 0x166C2BB3, 0x1B6725BA, 0x38560F85, 0x355D018C, 0x22401397, 0x2F4B1D9E,
1465 0x642247E9, 0x692949E0, 0x7E345BFB, 0x733F55F2, 0x500E7FCD, 0x5D0571C4, 0x4A1863DF, 0x47136DD6,
1466 0xDCCAD731, 0xD1C1D938, 0xC6DCCB23, 0xCBD7C52A, 0xE8E6EF15, 0xE5EDE11C, 0xF2F0F307, 0xFFFBFD0E,
1467 0xB492A779, 0xB999A970, 0xAE84BB6B, 0xA38FB562, 0x80BE9F5D, 0x8DB59154, 0x9AA8834F, 0x97A38D46,
1468 };
1469
1470 /* Corresponds to _IMXC3[256] */
1471 unsigned int mtpz_aes_gb9[] =
1472 {
1473 0x00000000, 0x090D0B0E, 0x121A161C, 0x1B171D12, 0x24342C38, 0x2D392736, 0x362E3A24, 0x3F23312A,
1474 0x48685870, 0x4165537E, 0x5A724E6C, 0x537F4562, 0x6C5C7448, 0x65517F46, 0x7E466254, 0x774B695A,
1475 0x90D0B0E0, 0x99DDBBEE, 0x82CAA6FC, 0x8BC7ADF2, 0xB4E49CD8, 0xBDE997D6, 0xA6FE8AC4, 0xAFF381CA,
1476 0xD8B8E890, 0xD1B5E39E, 0xCAA2FE8C, 0xC3AFF582, 0xFC8CC4A8, 0xF581CFA6, 0xEE96D2B4, 0xE79BD9BA,
1477 0x3BBB7BDB, 0x32B670D5, 0x29A16DC7, 0x20AC66C9, 0x1F8F57E3, 0x16825CED, 0x0D9541FF, 0x04984AF1,
1478 0x73D323AB, 0x7ADE28A5, 0x61C935B7, 0x68C43EB9, 0x57E70F93, 0x5EEA049D, 0x45FD198F, 0x4CF01281,
1479 0xAB6BCB3B, 0xA266C035, 0xB971DD27, 0xB07CD629, 0x8F5FE703, 0x8652EC0D, 0x9D45F11F, 0x9448FA11,
1480 0xE303934B, 0xEA0E9845, 0xF1198557, 0xF8148E59, 0xC737BF73, 0xCE3AB47D, 0xD52DA96F, 0xDC20A261,
1481 0x766DF6AD, 0x7F60FDA3, 0x6477E0B1, 0x6D7AEBBF, 0x5259DA95, 0x5B54D19B, 0x4043CC89, 0x494EC787,
1482 0x3E05AEDD, 0x3708A5D3, 0x2C1FB8C1, 0x2512B3CF, 0x1A3182E5, 0x133C89EB, 0x082B94F9, 0x01269FF7,
1483 0xE6BD464D, 0xEFB04D43, 0xF4A75051, 0xFDAA5B5F, 0xC2896A75, 0xCB84617B, 0xD0937C69, 0xD99E7767,
1484 0xAED51E3D, 0xA7D81533, 0xBCCF0821, 0xB5C2032F, 0x8AE13205, 0x83EC390B, 0x98FB2419, 0x91F62F17,
1485 0x4DD68D76, 0x44DB8678, 0x5FCC9B6A, 0x56C19064, 0x69E2A14E, 0x60EFAA40, 0x7BF8B752, 0x72F5BC5C,
1486 0x05BED506, 0x0CB3DE08, 0x17A4C31A, 0x1EA9C814, 0x218AF93E, 0x2887F230, 0x3390EF22, 0x3A9DE42C,
1487 0xDD063D96, 0xD40B3698, 0xCF1C2B8A, 0xC6112084, 0xF93211AE, 0xF03F1AA0, 0xEB2807B2, 0xE2250CBC,
1488 0x956E65E6, 0x9C636EE8, 0x877473FA, 0x8E7978F4, 0xB15A49DE, 0xB85742D0, 0xA3405FC2, 0xAA4D54CC,
1489 0xECDAF741, 0xE5D7FC4F, 0xFEC0E15D, 0xF7CDEA53, 0xC8EEDB79, 0xC1E3D077, 0xDAF4CD65, 0xD3F9C66B,
1490 0xA4B2AF31, 0xADBFA43F, 0xB6A8B92D, 0xBFA5B223, 0x80868309, 0x898B8807, 0x929C9515, 0x9B919E1B,
1491 0x7C0A47A1, 0x75074CAF, 0x6E1051BD, 0x671D5AB3, 0x583E6B99, 0x51336097, 0x4A247D85, 0x4329768B,
1492 0x34621FD1, 0x3D6F14DF, 0x267809CD, 0x2F7502C3, 0x105633E9, 0x195B38E7, 0x024C25F5, 0x0B412EFB,
1493 0xD7618C9A, 0xDE6C8794, 0xC57B9A86, 0xCC769188, 0xF355A0A2, 0xFA58ABAC, 0xE14FB6BE, 0xE842BDB0,
1494 0x9F09D4EA, 0x9604DFE4, 0x8D13C2F6, 0x841EC9F8, 0xBB3DF8D2, 0xB230F3DC, 0xA927EECE, 0xA02AE5C0,
1495 0x47B13C7A, 0x4EBC3774, 0x55AB2A66, 0x5CA62168, 0x63851042, 0x6A881B4C, 0x719F065E, 0x78920D50,
1496 0x0FD9640A, 0x06D46F04, 0x1DC37216, 0x14CE7918, 0x2BED4832, 0x22E0433C, 0x39F75E2E, 0x30FA5520,
1497 0x9AB701EC, 0x93BA0AE2, 0x88AD17F0, 0x81A01CFE, 0xBE832DD4, 0xB78E26DA, 0xAC993BC8, 0xA59430C6,
1498 0xD2DF599C, 0xDBD25292, 0xC0C54F80, 0xC9C8448E, 0xF6EB75A4, 0xFFE67EAA, 0xE4F163B8, 0xEDFC68B6,
1499 0x0A67B10C, 0x036ABA02, 0x187DA710, 0x1170AC1E, 0x2E539D34, 0x275E963A, 0x3C498B28, 0x35448026,
1500 0x420FE97C, 0x4B02E272, 0x5015FF60, 0x5918F46E, 0x663BC544, 0x6F36CE4A, 0x7421D358, 0x7D2CD856,
1501 0xA10C7A37, 0xA8017139, 0xB3166C2B, 0xBA1B6725, 0x8538560F, 0x8C355D01, 0x97224013, 0x9E2F4B1D,
1502 0xE9642247, 0xE0692949, 0xFB7E345B, 0xF2733F55, 0xCD500E7F, 0xC45D0571, 0xDF4A1863, 0xD647136D,
1503 0x31DCCAD7, 0x38D1C1D9, 0x23C6DCCB, 0x2ACBD7C5, 0x15E8E6EF, 0x1CE5EDE1, 0x07F2F0F3, 0x0EFFFBFD,
1504 0x79B492A7, 0x70B999A9, 0x6BAE84BB, 0x62A38FB5, 0x5D80BE9F, 0x548DB591, 0x4F9AA883, 0x4697A38D,
1505 };
1506
1507 static uint16_t
ptp_mtpz_validatehandshakeresponse(PTPParams * params,unsigned char * random,unsigned char ** calculatedHash)1508 ptp_mtpz_validatehandshakeresponse (PTPParams* params, unsigned char *random, unsigned char **calculatedHash)
1509 {
1510 uint16_t ret;
1511 unsigned int len;
1512 unsigned char* response = NULL;
1513
1514 ret = ptp_mtpz_getwmdrmpdappresponse (params, &response, &len);
1515 if (ret != PTP_RC_OK)
1516 {
1517 LIBMTP_INFO ("(MTPZ) Failure - did not receive device's response.\n");
1518 return ret;
1519 }
1520
1521 char *reader = (char *)response;
1522 int i;
1523
1524 if (*(reader++) != '\x02')
1525 {
1526 return -1;
1527 }
1528
1529 if (*(reader++) != '\x02')
1530 {
1531 return -1;
1532 }
1533
1534 // Message is always 128 bytes.
1535 reader++;
1536 if (*(reader++) != '\x80')
1537 {
1538 return -1;
1539 }
1540
1541 char *message = (char *)malloc(128);
1542 memcpy(message, reader, 128);
1543 reader += 128;
1544
1545 // Decrypt the hash-key-message..
1546 char *msg_dec = (char *)malloc(128);
1547 memset(msg_dec, 0, 128);
1548
1549 mtpz_rsa_t *rsa = mtpz_rsa_init(MTPZ_MODULUS, MTPZ_PRIVATE_KEY, MTPZ_PUBLIC_EXPONENT);
1550 if (!rsa)
1551 {
1552 LIBMTP_INFO ("(MTPZ) Failure - could not instantiate RSA object.\n");
1553 free(message);
1554 free(msg_dec);
1555 return -1;
1556 }
1557
1558 if (mtpz_rsa_decrypt(128, (unsigned char *)message, 128, (unsigned char *)msg_dec, rsa) == 0)
1559 {
1560 LIBMTP_INFO ("(MTPZ) Failure - could not perform RSA decryption.\n");
1561
1562 free(message);
1563 free(msg_dec);
1564 mtpz_rsa_free(rsa);
1565 return -1;
1566 }
1567
1568 mtpz_rsa_free(rsa);
1569 rsa = NULL;
1570
1571 char *state = mtpz_hash_init_state();
1572 char *hash_key = (char *)malloc(16);
1573 char *v10 = mtpz_hash_custom6A5DC(state, msg_dec + 21, 107, 20);
1574
1575 for (i = 0; i < 20; i++)
1576 msg_dec[i + 1] ^= v10[i];
1577
1578 char *v11 = mtpz_hash_custom6A5DC(state, msg_dec + 1, 20, 107);
1579
1580 for (i = 0; i < 107; i++)
1581 msg_dec[i + 21] ^= v11[i];
1582
1583 memcpy(hash_key, msg_dec + 112, 16);
1584
1585 // Encrypted message is 0x340 bytes.
1586 reader += 2;
1587 if (*(reader++) != '\x03' || *(reader++) != '\x40')
1588 {
1589 return -1;
1590 }
1591
1592 unsigned char *act_msg = (unsigned char *)malloc(832);
1593 unsigned char *act_reader = act_msg;
1594 memcpy(act_msg, reader, 832);
1595 reader = NULL;
1596
1597 mtpz_encryption_cipher_advanced((unsigned char *)hash_key, 16, act_msg, 832, 0);
1598
1599 act_reader++;
1600 unsigned int certs_length = MTPZ_SWAP(*(unsigned int *)(act_reader));
1601 act_reader += 4;
1602 act_reader += certs_length;
1603
1604 unsigned int rand_length = MTPZ_SWAP(*(unsigned short *)(act_reader) << 16);
1605 act_reader += 2;
1606 unsigned char *rand_data = (unsigned char *)malloc(rand_length);
1607 memcpy(rand_data, act_reader, rand_length);
1608 if (memcmp(rand_data, random, 16) != 0)
1609 {
1610 free(rand_data);
1611 return -1;
1612 }
1613 free(rand_data);
1614 act_reader += rand_length;
1615
1616 unsigned int dev_rand_length = MTPZ_SWAP(*(unsigned short *)(act_reader) << 16);
1617 act_reader += 2;
1618 act_reader += dev_rand_length;
1619
1620 act_reader++;
1621
1622 unsigned int sig_length = MTPZ_SWAP(*(unsigned short *)(act_reader) << 16);
1623 act_reader += 2;
1624 act_reader += sig_length;
1625
1626 act_reader++;
1627
1628 unsigned int machash_length = MTPZ_SWAP(*(unsigned short *)(act_reader) << 16);
1629 act_reader += 2;
1630 unsigned char *machash_data = (unsigned char *)malloc(machash_length);
1631 memcpy(machash_data, act_reader, machash_length);
1632 act_reader += machash_length;
1633
1634 *calculatedHash = machash_data;
1635
1636 free(message);
1637 free(msg_dec);
1638 free(state);
1639 free(v10);
1640 free(v11);
1641 free(act_msg);
1642
1643 return ret;
1644 }
1645
1646 static uint16_t
ptp_mtpz_opensecuresyncsession(PTPParams * params,unsigned char * hash)1647 ptp_mtpz_opensecuresyncsession (PTPParams* params, unsigned char *hash)
1648 {
1649 unsigned char mch[16];
1650 uint32_t *hashparams = (unsigned int *)mch;
1651 unsigned int macCount = *(unsigned int *)(hash + 16);
1652 uint16_t ret;
1653
1654 mtpz_encryption_encrypt_mac(hash, 16, (unsigned char *)(&macCount), 4, mch);
1655
1656 ret = ptp_mtpz_wmdrmpd_enabletrustedfilesoperations(params,
1657 MTPZ_SWAP(hashparams[0]), MTPZ_SWAP(hashparams[1]),
1658 MTPZ_SWAP(hashparams[2]), MTPZ_SWAP(hashparams[3]));
1659 return ret;
1660 };
1661
1662 static unsigned char *
ptp_mtpz_makeapplicationcertificatemessage(unsigned int * out_len,unsigned char ** out_random)1663 ptp_mtpz_makeapplicationcertificatemessage (unsigned int *out_len, unsigned char **out_random)
1664 {
1665 *out_len = 785;
1666
1667 unsigned char *acm = (unsigned char *)malloc(785);
1668 unsigned char *target = acm;
1669 memset(acm, 0, 785);
1670
1671 unsigned char *random = (unsigned char *)malloc(16);
1672
1673 int i = 0;
1674 int certsLength = 0x275;
1675
1676 // Write the marker bytes, length of certificates, and certificates themselves.
1677 *(target++) = '\x02';
1678 *(target++) = '\x01';
1679 *(target++) = '\x01';
1680 *(target++) = '\x00';
1681 *(target++) = '\x00';
1682 *(target++) = '\x02';
1683 *(target++) = '\x75';
1684 memcpy(target, MTPZ_CERTIFICATES, certsLength);
1685 target += certsLength;
1686
1687 // Write the random bytes.
1688 *(target++) = '\x00'; *(target++) = '\x10';
1689 srand(time(NULL));
1690
1691 for (i = 0; i < 16; i++)
1692 *(random + i) = (unsigned char)(rand() % 256);
1693
1694 *out_random = random;
1695 memcpy(target, random, 16);
1696 target += 16;
1697
1698 char *state = mtpz_hash_init_state();
1699 char *v16 = (char *)malloc(28); memset(v16, 0, 28);
1700 char *hash = (char *)malloc(20); memset(hash, 0, 20);
1701 char *odata = (char *)malloc(128); memset(odata, 0, 128);
1702
1703 mtpz_hash_reset_state(state);
1704 mtpz_hash_transform_hash(state, (char *)acm + 2, (target - acm - 2));
1705 mtpz_hash_finalize_hash(state, v16 + 8);
1706
1707 mtpz_hash_reset_state(state);
1708 mtpz_hash_transform_hash(state, v16, 28);
1709 mtpz_hash_finalize_hash(state, hash);
1710
1711 char *v17 = mtpz_hash_custom6A5DC(state, hash, 20, 107);
1712
1713 for (i = 0; i < 20; i++)
1714 odata[107 + i] = hash[i];
1715
1716 odata[106] = '\x01';
1717
1718 if (v17 != NULL)
1719 {
1720 for (i = 0; i < 107; i++)
1721 odata[i] ^= v17[i];
1722
1723 odata[0] &= 127;
1724 odata[127] = 188;
1725 }
1726
1727 // Free up some jazz.
1728 free(state); state = NULL;
1729 free(v16); v16 = NULL;
1730 free(v17); v17 = NULL;
1731 free(hash); hash = NULL;
1732
1733 // Take care of some RSA jazz.
1734 mtpz_rsa_t *rsa = mtpz_rsa_init(MTPZ_MODULUS, MTPZ_PRIVATE_KEY, MTPZ_PUBLIC_EXPONENT);
1735 if (!rsa)
1736 {
1737 LIBMTP_INFO("(MTPZ) Failure - could not instantiate RSA object.\n");
1738 *out_len = 0;
1739 return NULL;
1740 }
1741
1742 char *signature = (char *)malloc(128);
1743 memset(signature, 0, 128);
1744 mtpz_rsa_sign(128, (unsigned char *)odata, 128, (unsigned char *)signature, rsa);
1745
1746 // Free some more things.
1747 mtpz_rsa_free(rsa); rsa = NULL;
1748 free(odata); odata = NULL;
1749
1750 // Write the signature + bytes.
1751 *(target++) = '\x01'; *(target++) = '\x00'; *(target++) = '\x80';
1752 memcpy(target, signature, 128);
1753
1754 // Kill target.
1755 target = NULL;
1756
1757 return acm;
1758 };
1759
1760 static unsigned char *
ptp_mtpz_makeconfirmationmessage(unsigned char * hash,unsigned int * out_len)1761 ptp_mtpz_makeconfirmationmessage (unsigned char *hash, unsigned int *out_len)
1762 {
1763 *out_len = 20;
1764 unsigned char *message = (unsigned char *)malloc(20);
1765 message[0] = (unsigned char)0x02;
1766 message[1] = (unsigned char)0x03;
1767 message[2] = (unsigned char)0x00;
1768 message[3] = (unsigned char)0x10;
1769
1770 unsigned char *seed = (unsigned char *)malloc(16);
1771 memset(seed, 0, 16);
1772 seed[15] = (unsigned char)(0x01);
1773
1774 mtpz_encryption_encrypt_mac(hash, 16u, seed, 16u, message + 4);
1775
1776 free(seed);
1777
1778 return message;
1779 }
1780
ptp_mtpz_handshake(PTPParams * params)1781 uint16_t ptp_mtpz_handshake (PTPParams* params)
1782 {
1783 uint16_t ret = PTP_RC_OK;
1784 uint32_t size;
1785 unsigned char *hash=NULL;
1786 unsigned char *random=NULL;
1787 PTPPropertyValue propval;
1788 unsigned char* applicationCertificateMessage;
1789 unsigned char* message;
1790
1791 /* FIXME: do other places of libmtp set it? should we set it? */
1792 LIBMTP_INFO ("(MTPZ) Setting session initiator info.\n");
1793 propval.str = "libmtp/Sajid Anwar - MTPZClassDriver";
1794 ret = ptp_setdevicepropvalue(params,
1795 PTP_DPC_MTP_SessionInitiatorInfo,
1796 &propval,
1797 PTP_DTC_STR);
1798 if (ret != PTP_RC_OK)
1799 return ret;
1800
1801 LIBMTP_INFO ("(MTPZ) Resetting handshake.\n");
1802 ret = ptp_mtpz_resethandshake(params);
1803 if (ret != PTP_RC_OK)
1804 return ret;
1805
1806 LIBMTP_INFO ("(MTPZ) Sending application certificate message.\n");
1807 applicationCertificateMessage = ptp_mtpz_makeapplicationcertificatemessage(&size, &random);
1808 ret = ptp_mtpz_sendwmdrmpdapprequest (params, applicationCertificateMessage, size);
1809 free (applicationCertificateMessage);
1810 if (ret != PTP_RC_OK)
1811 return ret;
1812
1813 LIBMTP_INFO ("(MTPZ) Getting and validating handshake response.\n");
1814 ret = ptp_mtpz_validatehandshakeresponse(params, random, &hash);
1815 if (ret != PTP_RC_OK)
1816 goto free_random;
1817
1818 LIBMTP_INFO ("(MTPZ) Sending confirmation message.\n");
1819 message = ptp_mtpz_makeconfirmationmessage(hash, &size);
1820 ret = ptp_mtpz_sendwmdrmpdapprequest (params, message, size);
1821 if (ret != PTP_RC_OK)
1822 goto free_hash;
1823 free (message);
1824
1825 LIBMTP_INFO ("(MTPZ) Opening secure sync session.\n");
1826 ret = ptp_mtpz_opensecuresyncsession(params, hash);
1827 free_hash:
1828 free(hash);
1829 free_random:
1830 free(random);
1831 return ret;
1832 }
1833