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