xboxkrnl: Add a bunch of crypto functions

This commit is contained in:
Dr. Chat
2016-07-11 10:34:33 -05:00
parent 99f3c61fc1
commit fb87b7a3c3
14 changed files with 1506 additions and 14 deletions

22
third_party/crypto/des/LICENSE vendored Normal file
View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2014 Faraz Fallahi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

6
third_party/crypto/des/README.md vendored Normal file
View File

@@ -0,0 +1,6 @@
cppDES
======
Taken from [this repository](https://github.com/fffaraz/cppDES)
Modified for use by Xenia.

177
third_party/crypto/des/des.cpp vendored Normal file
View File

@@ -0,0 +1,177 @@
#include "des.h"
#include "des_key.h"
#include "des_data.h"
#include "des_lookup.h"
#include <memory>
//#pragma GCC push_options
#ifndef _MSC_VER
#pragma GCC optimize ("unroll-loops")
#endif
DES::DES(ui64 key)
{
keygen(key);
}
DES::DES(ui64* sub_key)
{
set_sub_key(sub_key);
}
void DES::set_sub_key(ui64 *sub_key)
{
std::memcpy(this->sub_key, sub_key, 128);
}
ui64 DES::encrypt(ui64 block)
{
return des(block, false);
}
ui64 DES::decrypt(ui64 block)
{
return des(block, true);
}
ui64 DES::encrypt(ui64 block, ui64 key)
{
DES des(key);
return des.des(block, false);
}
ui64 DES::decrypt(ui64 block, ui64 key)
{
DES des(key);
return des.des(block, true);
}
void DES::keygen(ui64 key)
{
// initial key schedule calculation
ui64 permuted_choice_1 = 0; // 56 bits
for (ui8 i = 0; i < 56; i++)
{
permuted_choice_1 <<= 1;
permuted_choice_1 |= (key >> (64-PC1[i])) & LB64_MASK;
}
// 28 bits
ui32 C = (ui32) ((permuted_choice_1 >> 28) & 0x000000000fffffff);
ui32 D = (ui32) (permuted_choice_1 & 0x000000000fffffff);
// Calculation of the 16 keys
for (ui8 i = 0; i < 16; i++)
{
// key schedule, shifting Ci and Di
for (ui8 j = 0; j < ITERATION_SHIFT[i]; j++)
{
C = (0x0fffffff & (C << 1)) | (0x00000001 & (C >> 27));
D = (0x0fffffff & (D << 1)) | (0x00000001 & (D >> 27));
}
ui64 permuted_choice_2 = (((ui64) C) << 28) | (ui64) D;
sub_key[i] = 0; // 48 bits (2*24)
for (ui8 j = 0; j < 48; j++)
{
sub_key[i] <<= 1;
sub_key[i] |= (permuted_choice_2 >> (56-PC2[j])) & LB64_MASK;
}
}
}
ui64 DES::des(ui64 block, bool mode)
{
// applying initial permutation
block = ip(block);
// dividing T' into two 32-bit parts
ui32 L = (ui32) (block >> 32) & L64_MASK;
ui32 R = (ui32) (block & L64_MASK);
// 16 rounds
for (ui8 i = 0; i < 16; i++)
{
ui32 F = mode ? f(R, sub_key[15-i]) : f(R, sub_key[i]);
feistel(L, R, F);
}
// swapping the two parts
block = (((ui64) R) << 32) | (ui64) L;
// applying final permutation
return fp(block);
}
ui64 DES::ip(ui64 block)
{
// initial permutation
ui64 result = 0;
for (ui8 i = 0; i < 64; i++)
{
result <<= 1;
result |= (block >> (64-IP[i])) & LB64_MASK;
}
return result;
}
ui64 DES::fp(ui64 block)
{
// inverse initial permutation
ui64 result = 0;
for (ui8 i = 0; i < 64; i++)
{
result <<= 1;
result |= (block >> (64-FP[i])) & LB64_MASK;
}
return result;
}
void DES::feistel(ui32 &L, ui32 &R, ui32 F)
{
ui32 temp = R;
R = L ^ F;
L = temp;
}
ui32 DES::f(ui32 R, ui64 k) // f(R,k) function
{
// applying expansion permutation and returning 48-bit data
ui64 s_input = 0;
for (ui8 i = 0; i < 48; i++)
{
s_input <<= 1;
s_input |= (ui64) ((R >> (32-EXPANSION[i])) & LB32_MASK);
}
// XORing expanded Ri with Ki, the round key
s_input = s_input ^ k;
// applying S-Boxes function and returning 32-bit data
ui32 s_output = 0;
for (ui8 i = 0; i < 8; i++)
{
// Outer bits
char row = (char) ((s_input & (0x0000840000000000 >> 6*i)) >> (42-6*i));
row = (row >> 4) | (row & 0x01);
// Middle 4 bits of input
char column = (char) ((s_input & (0x0000780000000000 >> 6*i)) >> (43-6*i));
s_output <<= 4;
s_output |= (ui32) (SBOX[i][16*row + column] & 0x0f);
}
// applying the round permutation
ui32 f_result = 0;
for (ui8 i = 0; i < 32; i++)
{
f_result <<= 1;
f_result |= (s_output >> (32 - PBOX[i])) & LB32_MASK;
}
return f_result;
}
//#pragma GCC pop_options

51
third_party/crypto/des/des.h vendored Normal file
View File

@@ -0,0 +1,51 @@
#ifndef DES_H
#define DES_H
#include <cstdint>
typedef uint64_t ui64;
typedef uint32_t ui32;
typedef uint8_t ui8;
class DES
{
public:
DES(ui64 key);
DES(ui64 *sub_key);
ui64 des(ui64 block, bool mode);
ui64 encrypt(ui64 block);
ui64 decrypt(ui64 block);
static ui64 encrypt(ui64 block, ui64 key);
static ui64 decrypt(ui64 block, ui64 key);
static void set_parity(ui8 *key, int length, ui8 *out) {
for (int i = 0; i < length; i++) {
ui8 parity = key[i];
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
out[i] = (key[i] & 0xFE) | (~parity & 1);
}
}
const ui64 *get_sub_key() const { return sub_key; }
void set_sub_key(ui64 *key);
protected:
void keygen(ui64 key);
ui64 ip(ui64 block);
ui64 fp(ui64 block);
void feistel(ui32 &L, ui32 &R, ui32 F);
ui32 f(ui32 R, ui64 k);
private:
ui64 sub_key[16]; // 48 bits each
};
#endif // DES_H

40
third_party/crypto/des/des3.h vendored Normal file
View File

@@ -0,0 +1,40 @@
#ifndef DES3_H
#define DES3_H
#include "des.h"
class DES3
{
public:
DES3(ui64 k1, ui64 k2, ui64 k3) : des{ DES(k1), DES(k2), DES(k3) } {}
DES3(ui64* sk1, ui64* sk2, ui64* sk3) : des{ DES(sk1), DES(sk2), DES(sk3) } {}
inline ui64 encrypt(ui64 block)
{
return des[2].encrypt(des[1].decrypt(des[0].encrypt(block)));
}
inline ui64 decrypt(ui64 block)
{
return des[0].decrypt(des[1].encrypt(des[2].decrypt(block)));
}
inline ui64 crypt(ui64 block, bool bEncrypt)
{
if (bEncrypt)
{
return encrypt(block);
}
else
{
return decrypt(block);
}
}
inline DES* getDES() { return des; }
private:
DES des[3];
};
#endif // DES3_H

121
third_party/crypto/des/des_data.h vendored Normal file
View File

@@ -0,0 +1,121 @@
#ifndef DES_DATA_H
#define DES_DATA_H
#define LB32_MASK 0x00000001
#define LB64_MASK 0x0000000000000001
#define L64_MASK 0x00000000ffffffff
// Initial Permutation Table [8*8]
static const char IP[] =
{
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
};
// Inverse Initial Permutation Table [8*8]
static const char FP[] =
{
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
};
// Expansion table [6*8]
static const char EXPANSION[] =
{
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
};
// The S-Box tables [8*16*4]
static const char SBOX[8][64] =
{
{
// S1
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
},
{
// S2
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
},
{
// S3
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
},
{
// S4
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
},
{
// S5
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
},
{
// S6
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
},
{
// S7
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
},
{
// S8
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
}
};
// Post S-Box permutation [4*8]
static const char PBOX[] =
{
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
#endif // DES_DATA_H

38
third_party/crypto/des/des_key.h vendored Normal file
View File

@@ -0,0 +1,38 @@
#ifndef DES_KEY_H
#define DES_KEY_H
// Permuted Choice 1 Table [7*8]
static const char PC1[] =
{
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
};
// Permuted Choice 2 Table [6*8]
static const char PC2[] =
{
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
// Iteration Shift Array
static const char ITERATION_SHIFT[] =
{
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};
#endif // DES_KEY_H

4
third_party/crypto/des/des_lookup.h vendored Normal file
View File

@@ -0,0 +1,4 @@
#ifndef DES_LOOKUP_H
#define DES_LOOKUP_H
#endif // DES_LOOKUP_H

34
third_party/crypto/des/descbc.h vendored Normal file
View File

@@ -0,0 +1,34 @@
#ifndef DESCBC_H
#define DESCBC_H
#include "des.h"
class DESCBC
{
public:
DESCBC(ui64 key, ui64 iv) : des(key), iv(iv), last_block(iv) {}
inline ui64 encrypt(ui64 block)
{
last_block = des.encrypt(block ^ last_block);
return last_block;
}
inline ui64 decrypt(ui64 block)
{
ui64 result = des.decrypt(block) ^ last_block;
last_block = block;
return result;
}
inline void reset()
{
last_block = iv;
}
private:
DES des;
ui64 iv;
ui64 last_block;
};
#endif // DESCBC_H