diff options
Diffstat (limited to 'plugins/!Deprecated/Skype/src/aes/aes.cpp')
-rw-r--r-- | plugins/!Deprecated/Skype/src/aes/aes.cpp | 493 |
1 files changed, 493 insertions, 0 deletions
diff --git a/plugins/!Deprecated/Skype/src/aes/aes.cpp b/plugins/!Deprecated/Skype/src/aes/aes.cpp new file mode 100644 index 0000000000..e3dfa1261f --- /dev/null +++ b/plugins/!Deprecated/Skype/src/aes/aes.cpp @@ -0,0 +1,493 @@ +/*
+* FIPS-197 compliant AES implementation
+*
+* Copyright (C) 2001-2004 Christophe Devine
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "aes.h"
+
+/* forward S-box & tables */
+
+unsigned long int FSb[256];
+unsigned long int FT0[256];
+unsigned long int FT1[256];
+unsigned long int FT2[256];
+unsigned long int FT3[256];
+
+/* reverse S-box & tables */
+
+unsigned long int RSb[256];
+unsigned long int RT0[256];
+unsigned long int RT1[256];
+unsigned long int RT2[256];
+unsigned long int RT3[256];
+
+/* round constants */
+
+unsigned long int RCON[10];
+
+/* tables generation flag */
+
+int do_init = 1;
+
+/* tables generation routine */
+
+#define ROTR8(x) (((x << 24) & 0xFFFFFFFF) | ((x & 0xFFFFFFFF) >> 8))
+
+#define XTIME(x) ((x << 1) ^ ((x & 0x80) ? 0x1B : 0x00))
+#define MUL(x, y) ((x && y) ? pow[(log[x] + log[y]) % 255] : 0)
+
+void aes_gen_tables(void)
+{
+ int i;
+ unsigned char x, y;
+ unsigned char pow[256];
+ unsigned char log[256];
+
+ /* compute pow and log tables over GF(2^8) */
+
+ for (i = 0, x = 1; i < 256; i++, x ^= XTIME(x))
+ {
+ pow[i] = x;
+ log[x] = i;
+ }
+
+ /* calculate the round constants */
+
+ for (i = 0, x = 1; i < 10; i++, x = XTIME(x))
+ {
+ RCON[i] = (unsigned long int)x << 24;
+ }
+
+ /* generate the forward and reverse S-boxes */
+
+ FSb[0x00] = 0x63;
+ RSb[0x63] = 0x00;
+
+ for (i = 1; i < 256; i++)
+ {
+ x = pow[255 - log[i]];
+
+ y = x;
+ y = (y << 1) | (y >> 7);
+ x ^= y;
+ y = (y << 1) | (y >> 7);
+ x ^= y;
+ y = (y << 1) | (y >> 7);
+ x ^= y;
+ y = (y << 1) | (y >> 7);
+ x ^= y ^ 0x63;
+
+ FSb[i] = x;
+ RSb[x] = i;
+ }
+
+ /* generate the forward and reverse tables */
+
+ for (i = 0; i < 256; i++)
+ {
+ x = (unsigned char)FSb[i];
+ y = XTIME(x);
+
+ FT0[i] = (unsigned long int)(x ^ y) ^
+ ((unsigned long int)x << 8) ^
+ ((unsigned long int)x << 16) ^
+ ((unsigned long int)y << 24);
+
+ FT0[i] &= 0xFFFFFFFF;
+
+ FT1[i] = ROTR8(FT0[i]);
+ FT2[i] = ROTR8(FT1[i]);
+ FT3[i] = ROTR8(FT2[i]);
+
+ y = (unsigned char)RSb[i];
+
+ RT0[i] = ((unsigned long int)MUL(0x0B, y)) ^
+ ((unsigned long int)MUL(0x0D, y) << 8) ^
+ ((unsigned long int)MUL(0x09, y) << 16) ^
+ ((unsigned long int)MUL(0x0E, y) << 24);
+
+ RT0[i] &= 0xFFFFFFFF;
+
+ RT1[i] = ROTR8(RT0[i]);
+ RT2[i] = ROTR8(RT1[i]);
+ RT3[i] = ROTR8(RT2[i]);
+ }
+}
+
+/* platform-independant 32-bit integer manipulation macros */
+
+#define GET_UINT32(n, b, i) \
+{ \
+ (n) = ((unsigned long int)(b)[(i)] << 24) \
+ | ((unsigned long int)(b)[(i) + 1] << 16) \
+ | ((unsigned long int)(b)[(i) + 2] << 8) \
+ | ((unsigned long int)(b)[(i) + 3]); \
+}
+
+#define PUT_UINT32(n, b, i) \
+{ \
+ (b)[(i)] = (unsigned char)((n) >> 24); \
+ (b)[(i) + 1] = (unsigned char)((n) >> 16); \
+ (b)[(i) + 2] = (unsigned char)((n) >> 8); \
+ (b)[(i) + 3] = (unsigned char)((n)); \
+}
+
+/* decryption key schedule tables */
+
+int KT_init = 1;
+
+unsigned long int KT0[256];
+unsigned long int KT1[256];
+unsigned long int KT2[256];
+unsigned long int KT3[256];
+
+/* AES key scheduling routine */
+
+int aes_set_key(aes_context *ctx, unsigned char *key, int nbits)
+{
+ int i;
+ unsigned long int *RK, *SK;
+
+ if (do_init)
+ {
+ aes_gen_tables();
+
+ do_init = 0;
+ }
+
+ switch (nbits)
+ {
+ case 128: ctx->nr = 10; break;
+ case 192: ctx->nr = 12; break;
+ case 256: ctx->nr = 14; break;
+ default : return 1;
+ }
+
+ RK = ctx->erk;
+
+ for (i = 0; i < (nbits >> 5); i++)
+ {
+ GET_UINT32(RK[i], key, i * 4);
+ }
+
+ /* setup encryption round keys */
+
+ switch (nbits)
+ {
+ case 128:
+ for (i = 0; i < 10; i++, RK += 4)
+ {
+ RK[4] = RK[0] ^ RCON[i] ^
+ (FSb[(unsigned char)(RK[3] >> 16)] << 24) ^
+ (FSb[(unsigned char)(RK[3] >> 8)] << 16) ^
+ (FSb[(unsigned char)(RK[3])] << 8) ^
+ (FSb[(unsigned char)(RK[3] >> 24)]);
+
+ RK[5] = RK[1] ^ RK[4];
+ RK[6] = RK[2] ^ RK[5];
+ RK[7] = RK[3] ^ RK[6];
+ }
+ break;
+
+ case 192:
+ for (i = 0; i < 8; i++, RK += 6)
+ {
+ RK[6] = RK[0] ^ RCON[i] ^
+ (FSb[(unsigned char)(RK[5] >> 16)] << 24) ^
+ (FSb[(unsigned char)(RK[5] >> 8)] << 16) ^
+ (FSb[(unsigned char)(RK[5])] << 8) ^
+ (FSb[(unsigned char)(RK[5] >> 24)]);
+
+ RK[7] = RK[1] ^ RK[6];
+ RK[8] = RK[2] ^ RK[7];
+ RK[9] = RK[3] ^ RK[8];
+ RK[10] = RK[4] ^ RK[9];
+ RK[11] = RK[5] ^ RK[10];
+ }
+ break;
+
+ case 256:
+ for (i = 0; i < 7; i++, RK += 8)
+ {
+ RK[8] = RK[0] ^ RCON[i] ^
+ (FSb[(unsigned char)(RK[7] >> 16)] << 24) ^
+ (FSb[(unsigned char)(RK[7] >> 8)] << 16) ^
+ (FSb[(unsigned char)(RK[7])] << 8) ^
+ (FSb[(unsigned char)(RK[7] >> 24)]);
+
+ RK[9] = RK[1] ^ RK[8];
+ RK[10] = RK[2] ^ RK[9];
+ RK[11] = RK[3] ^ RK[10];
+
+ RK[12] = RK[4] ^
+ (FSb[(unsigned char)(RK[11] >> 24)] << 24) ^
+ (FSb[(unsigned char)(RK[11] >> 16)] << 16) ^
+ (FSb[(unsigned char)(RK[11] >> 8)] << 8) ^
+ (FSb[(unsigned char)(RK[11])]);
+
+ RK[13] = RK[5] ^ RK[12];
+ RK[14] = RK[6] ^ RK[13];
+ RK[15] = RK[7] ^ RK[14];
+ }
+ break;
+ }
+
+ /* setup decryption round keys */
+
+ if (KT_init)
+ {
+ for (i = 0; i < 256; i++)
+ {
+ KT0[i] = RT0[FSb[i]];
+ KT1[i] = RT1[FSb[i]];
+ KT2[i] = RT2[FSb[i]];
+ KT3[i] = RT3[FSb[i]];
+ }
+
+ KT_init = 0;
+ }
+
+ SK = ctx->drk;
+
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+
+ for (i = 1; i < ctx->nr; i++)
+ {
+ RK -= 8;
+
+ *SK++ = KT0[(unsigned char)(*RK >> 24)] ^
+ KT1[(unsigned char)(*RK >> 16)] ^
+ KT2[(unsigned char)(*RK >> 8)] ^
+ KT3[(unsigned char)(*RK)];
+ RK++;
+
+ *SK++ = KT0[(unsigned char)(*RK >> 24)] ^
+ KT1[(unsigned char)(*RK >> 16)] ^
+ KT2[(unsigned char)(*RK >> 8)] ^
+ KT3[(unsigned char)(*RK)];
+ RK++;
+
+ *SK++ = KT0[(unsigned char)(*RK >> 24)] ^
+ KT1[(unsigned char)(*RK >> 16)] ^
+ KT2[(unsigned char)(*RK >> 8)] ^
+ KT3[(unsigned char)(*RK)];
+ RK++;
+
+ *SK++ = KT0[(unsigned char)(*RK >> 24)] ^
+ KT1[(unsigned char)(*RK >> 16)] ^
+ KT2[(unsigned char)(*RK >> 8)] ^
+ KT3[(unsigned char)(*RK)];
+ RK++;
+ }
+
+ RK -= 8;
+
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+
+ return 0;
+}
+
+/* AES 128-bit block encryption routine */
+
+void aes_encrypt(aes_context *ctx, unsigned char input[16], unsigned char output[16])
+{
+ unsigned long int *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+ RK = ctx->erk;
+
+ GET_UINT32(X0, input, 0); X0 ^= RK[0];
+ GET_UINT32(X1, input, 4); X1 ^= RK[1];
+ GET_UINT32(X2, input, 8); X2 ^= RK[2];
+ GET_UINT32(X3, input, 12); X3 ^= RK[3];
+
+#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
+{ \
+ RK += 4; \
+ \
+ X0 = RK[0] ^ FT0[(unsigned char)(Y0 >> 24)] ^ \
+ FT1[(unsigned char)(Y1 >> 16)] ^ \
+ FT2[(unsigned char)(Y2 >> 8)] ^ \
+ FT3[(unsigned char)(Y3)]; \
+ \
+ X1 = RK[1] ^ FT0[(unsigned char)(Y1 >> 24)] ^ \
+ FT1[(unsigned char)(Y2 >> 16)] ^ \
+ FT2[(unsigned char)(Y3 >> 8)] ^ \
+ FT3[(unsigned char)(Y0)]; \
+ \
+ X2 = RK[2] ^ FT0[(unsigned char)(Y2 >> 24)] ^ \
+ FT1[(unsigned char)(Y3 >> 16)] ^ \
+ FT2[(unsigned char)(Y0 >> 8)] ^ \
+ FT3[(unsigned char)(Y1)]; \
+ \
+ X3 = RK[3] ^ FT0[(unsigned char)(Y3 >> 24)] ^ \
+ FT1[(unsigned char)(Y0 >> 16)] ^ \
+ FT2[(unsigned char)(Y1 >> 8)] ^ \
+ FT3[(unsigned char)(Y2)]; \
+}
+
+ AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 1 */
+ AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 2 */
+ AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 3 */
+ AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 4 */
+ AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 5 */
+ AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 6 */
+ AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 7 */
+ AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 8 */
+ AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 9 */
+
+ if (ctx->nr > 10)
+ {
+ AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 10 */
+ AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 11 */
+ }
+
+ if (ctx->nr > 12)
+ {
+ AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 12 */
+ AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 13 */
+ }
+
+ /* last round */
+
+ RK += 4;
+
+ X0 = RK[0] ^ (FSb[(unsigned char)(Y0 >> 24)] << 24) ^
+ (FSb[(unsigned char)(Y1 >> 16)] << 16) ^
+ (FSb[(unsigned char)(Y2 >> 8)] << 8) ^
+ (FSb[(unsigned char)(Y3)]);
+
+ X1 = RK[1] ^ (FSb[(unsigned char)(Y1 >> 24)] << 24) ^
+ (FSb[(unsigned char)(Y2 >> 16)] << 16) ^
+ (FSb[(unsigned char)(Y3 >> 8)] << 8) ^
+ (FSb[(unsigned char)(Y0)]);
+
+ X2 = RK[2] ^ (FSb[(unsigned char)(Y2 >> 24)] << 24) ^
+ (FSb[(unsigned char)(Y3 >> 16)] << 16) ^
+ (FSb[(unsigned char)(Y0 >> 8)] << 8) ^
+ (FSb[(unsigned char)(Y1)]);
+
+ X3 = RK[3] ^ (FSb[(unsigned char)(Y3 >> 24)] << 24) ^
+ (FSb[(unsigned char)(Y0 >> 16)] << 16) ^
+ (FSb[(unsigned char)(Y1 >> 8)] << 8) ^
+ (FSb[(unsigned char)(Y2)]);
+
+ PUT_UINT32(X0, output, 0);
+ PUT_UINT32(X1, output, 4);
+ PUT_UINT32(X2, output, 8);
+ PUT_UINT32(X3, output, 12);
+}
+
+/* AES 128-bit block decryption routine */
+
+void aes_decrypt(aes_context *ctx, unsigned char input[16], unsigned char output[16])
+{
+ unsigned long int *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+ RK = ctx->drk;
+
+ GET_UINT32(X0, input, 0);
+ X0 ^= RK[0];
+ GET_UINT32(X1, input, 4);
+ X1 ^= RK[1];
+ GET_UINT32(X2, input, 8);
+ X2 ^= RK[2];
+ GET_UINT32(X3, input, 12);
+ X3 ^= RK[3];
+
+#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
+{ \
+ RK += 4; \
+ \
+ X0 = RK[0] ^ RT0[(unsigned char)(Y0 >> 24)] ^ \
+ RT1[(unsigned char)(Y3 >> 16)] ^ \
+ RT2[(unsigned char)(Y2 >> 8)] ^ \
+ RT3[(unsigned char)(Y1)]; \
+ \
+ X1 = RK[1] ^ RT0[(unsigned char)(Y1 >> 24)] ^ \
+ RT1[(unsigned char)(Y0 >> 16)] ^ \
+ RT2[(unsigned char)(Y3 >> 8)] ^ \
+ RT3[(unsigned char)(Y2)]; \
+ \
+ X2 = RK[2] ^ RT0[(unsigned char)(Y2 >> 24)] ^ \
+ RT1[(unsigned char)(Y1 >> 16)] ^ \
+ RT2[(unsigned char)(Y0 >> 8)] ^ \
+ RT3[(unsigned char)(Y3)]; \
+ \
+ X3 = RK[3] ^ RT0[(unsigned char)(Y3 >> 24)] ^ \
+ RT1[(unsigned char)(Y2 >> 16)] ^ \
+ RT2[(unsigned char)(Y1 >> 8)] ^ \
+ RT3[(unsigned char)(Y0)]; \
+}
+
+ AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 1 */
+ AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 2 */
+ AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 3 */
+ AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 4 */
+ AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 5 */
+ AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 6 */
+ AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 7 */
+ AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 8 */
+ AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 9 */
+
+ if (ctx->nr > 10)
+ {
+ AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 10 */
+ AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 11 */
+ }
+
+ if (ctx->nr > 12)
+ {
+ AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3); /* round 12 */
+ AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3); /* round 13 */
+ }
+
+ /* last round */
+
+ RK += 4;
+
+ X0 = RK[0] ^ (RSb[(unsigned char)(Y0 >> 24)] << 24) ^
+ (RSb[(unsigned char)(Y3 >> 16)] << 16) ^
+ (RSb[(unsigned char)(Y2 >> 8)] << 8) ^
+ (RSb[(unsigned char)(Y1)]);
+
+ X1 = RK[1] ^ (RSb[(unsigned char)(Y1 >> 24)] << 24) ^
+ (RSb[(unsigned char)(Y0 >> 16)] << 16) ^
+ (RSb[(unsigned char)(Y3 >> 8)] << 8) ^
+ (RSb[(unsigned char)(Y2)]);
+
+ X2 = RK[2] ^ (RSb[(unsigned char)(Y2 >> 24)] << 24) ^
+ (RSb[(unsigned char)(Y1 >> 16)] << 16) ^
+ (RSb[(unsigned char)(Y0 >> 8)] << 8) ^
+ (RSb[(unsigned char)(Y3)]);
+
+ X3 = RK[3] ^ (RSb[(unsigned char)(Y3 >> 24)] << 24) ^
+ (RSb[(unsigned char)(Y2 >> 16)] << 16) ^
+ (RSb[(unsigned char)(Y1 >> 8)] << 8) ^
+ (RSb[(unsigned char)(Y0)]);
+
+ PUT_UINT32(X0, output, 0);
+ PUT_UINT32(X1, output, 4);
+ PUT_UINT32(X2, output, 8);
+ PUT_UINT32(X3, output, 12);
+}
\ No newline at end of file |