October3d55/M/LowEntryExtStdLib/Source/LowEntryExtendedStandardLib.../Private/Classes/LowEntryHashingBCryptLibrar...

176 lines
27 KiB
C++
Raw Normal View History

2025-03-10 09:43:27 +08:00
// Copyright Low Entry. Apache License, Version 2.0.
#include "LowEntryHashingBCryptLibrary.h"
constexpr int32 ULowEntryHashingBCryptLibrary::P_orig[18] = {0x243f6a88, static_cast<int32>(0x85a308d3), 0x13198a2e, 0x03707344, static_cast<int32>(0xa4093822), 0x299f31d0, 0x082efa98, static_cast<int32>(0xec4e6c89), 0x452821e6, 0x38d01377, static_cast<int32>(0xbe5466cf), 0x34e90c6c, static_cast<int32>(0xc0ac29b7), static_cast<int32>(0xc97c50dd), 0x3f84d5b5, static_cast<int32>(0xb5470917), static_cast<int32>(0x9216d5d9), static_cast<int32>(0x8979fb1b)};
constexpr int32 ULowEntryHashingBCryptLibrary::S_orig[1024] = {static_cast<int32>(0xd1310ba6), static_cast<int32>(0x98dfb5ac), 0x2ffd72db, static_cast<int32>(0xd01adfb7), static_cast<int32>(0xb8e1afed), 0x6a267e96, static_cast<int32>(0xba7c9045), static_cast<int32>(0xf12c7f99), 0x24a19947, static_cast<int32>(0xb3916cf7), 0x0801f2e2, static_cast<int32>(0x858efc16), 0x636920d8, 0x71574e69, static_cast<int32>(0xa458fea3), static_cast<int32>(0xf4933d7e), 0x0d95748f, 0x728eb658, 0x718bcd58, static_cast<int32>(0x82154aee), 0x7b54a41d, static_cast<int32>(0xc25a59b5), static_cast<int32>(0x9c30d539), 0x2af26013, static_cast<int32>(0xc5d1b023), 0x286085f0, static_cast<int32>(0xca417918), static_cast<int32>(0xb8db38ef), static_cast<int32>(0x8e79dcb0), 0x603a180e, 0x6c9e0e8b, static_cast<int32>(0xb01e8a3e), static_cast<int32>(0xd71577c1), static_cast<int32>(0xbd314b27), 0x78af2fda, 0x55605c60, static_cast<int32>(0xe65525f3), static_cast<int32>(0xaa55ab94), 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, static_cast<int32>(0xb4cc5c34), 0x1141e8ce, static_cast<int32>(0xa15486af), 0x7c72e993, static_cast<int32>(0xb3ee1411), 0x636fbc2a, 0x2ba9c55d, 0x741831f6, static_cast<int32>(0xce5c3e16), static_cast<int32>(0x9b87931e), static_cast<int32>(0xafd6ba33), 0x6c24cf5c, 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, static_cast<int32>(0xc4bfe81b), 0x66282193, 0x61d809cc, static_cast<int32>(0xfb21a991), 0x487cac60, 0x5dec8032, static_cast<int32>(0xef845d5d), static_cast<int32>(0xe98575b1), static_cast<int32>(0xdc262302), static_cast<int32>(0xeb651b88), 0x23893e81, static_cast<int32>(0xd396acc5), 0x0f6d6ff3, static_cast<int32>(0x83f44239), 0x2e0b4482, static_cast<int32>(0xa4842004), 0x69c8f04a, static_cast<int32>(0x9e1f9b5e), 0x21c66842, static_cast<int32>(0xf6e96c9a), 0x670c9c61, static_cast<int32>(0xabd388f0), 0x6a51a0d2, static_cast<int32>(0xd8542f68), static_cast<int32>(0x960fa728), static_cast<int32>(0xab5133a3), 0x6eef0b6c, 0x137a3be4, static_cast<int32>(0xba3bf050), 0x7efb2a98, static_cast<int32>(0xa1f1651d), 0x39af0176, 0x66ca593e, static_cast<int32>(0x82430e88), static_cast<int32>(0x8cee8619), 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, static_cast<int32>(0xe06f75d8), static_cast<int32>(0x85c12073), 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, static_cast<int32>(0xd00a1248), static_cast<int32>(0xdb0fead3), 0x49f1c09b, 0x075372c9, static_cast<int32>(0x80991b7b), 0x25d479d8, static_cast<int32>(0xf6e8def7), static_cast<int32>(0xe3fe501a), static_cast<int32>(0xb6794c3b), static_cast<int32>(0x976ce0bd), 0x04c006ba, static_cast<int32>(0xc1a94fb6), 0x409f60c4, 0x5e5c9ec2, 0x196a2463, 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, static_cast<int32>(0x9b30952c), static_cast<int32>(0xcc814544), static_cast<int32>(0xaf5ebd09), static_cast<int32>(0xbee3d004), static_cast<int32>(0xde334afd), 0x660f2807, 0x192e4bb3, static_cast<int32>(0xc0cba857), 0x45c8740f, static_cast<int32>(0xd20b5f39), static_cast<int32>(0xb9d3fbdb), 0x5579c0bd, 0x1a60320a, static_cast<int32>(0xd6a100c6), 0x402c7279, 0x679f25fe, static_cast<int32>(0xfb1fa3cc), static_cast<int32>(0x8ea5e9f8), static_cast<int32>(0xdb3222f8), 0x3c7516df, static_cast<int32>(0xfd616b15), 0x2f501ec8, static_cast<int32>(0xad0552ab), 0x323db5fa, static_cast<int32>(0xfd238760), 0x53317b48, 0x3e00df82, static_cast<int32>(0x9e5c57bb), static_cast<int32>(0xca6f8ca0), 0x1a87562e, static_cast<int32>(0xdf1769db), static_cast<int32>(0xd542a8f6), 0x287effc3, static_cast<int32>(0xac6732c6), static_cast<int32>(0x8c4f5573), 0x695b27b0, static_cast<int32>(0xbbca58c8), static_cast<int32>(0xe1ffa35d), static_cast<int32>(0xb8f011a0), 0x10fa3d98, static_cast<int32>(0xfd2183b8), 0x4afcb56c, 0x2dd1d35b, static_cast<int32>(0x9a53e479), static_cast<int32>(0xb6f84565), static_cast<int32>(0xd28e49bc), 0x4bfb9790, static_cast<int32>(0xe1ddf2da), static_cast<int32>(0xa4cb7e33), 0x62fb1341, static_cast<int32>(0xcee4c6e8), static_cast<int32>(0xef20cada), 0x36774c01, static_cast<int32>(0xd07e9efe), 0x2bf11fb4, static_cast<int32>(0x95dbda4d), static_cast<int32>(0xae909198), static_c
constexpr int32 ULowEntryHashingBCryptLibrary::bf_crypt_ciphertext[6] = {0x4f727068, 0x65616e42, 0x65686f6c, 0x64657253, 0x63727944, 0x6f756274};
void ULowEntryHashingBCryptLibrary::encipher(int32 lr[], const int32 off)
{
int32 i, n, l = lr[off], r = lr[off + 1];
l ^= P[0];
for (i = 0; i <= (BLOWFISH_NUM_ROUNDS - 2);)
{
n = S[(l >> 24) & 0xff];
n += S[0x100 | ((l >> 16) & 0xff)];
n ^= S[0x200 | ((l >> 8) & 0xff)];
n += S[0x300 | (l & 0xff)];
r ^= n ^ P[++i];
n = S[(r >> 24) & 0xff];
n += S[0x100 | ((r >> 16) & 0xff)];
n ^= S[0x200 | ((r >> 8) & 0xff)];
n += S[0x300 | (r & 0xff)];
l ^= n ^ P[++i];
}
lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1];
lr[off + 1] = l;
}
int32 ULowEntryHashingBCryptLibrary::streamtoword(const TArray<uint8>& data, int32 offp[])
{
int32 i;
int32 word = 0;
int32 off = offp[0];
for (i = 0; i < 4; i++)
{
word = (word << 8) | (data[off] & 0xff);
off = (off + 1) % data.Num();
}
offp[0] = off;
return word;
}
void ULowEntryHashingBCryptLibrary::init_key()
{
for (int32 i = 0; i < P_len; i++)
{
P[i] = P_orig[i];
}
for (int32 i = 0; i < S_len; i++)
{
S[i] = S_orig[i];
}
}
void ULowEntryHashingBCryptLibrary::key(const TArray<uint8>& key)
{
int32 i;
int32 koffp[] = {0};
int32 lr[] = {0, 0};
int32 plen = P_len, slen = S_len;
for (i = 0; i < plen; i++)
{
P[i] = P[i] ^ streamtoword(key, koffp);
}
for (i = 0; i < plen; i += 2)
{
encipher(lr, 0);
P[i] = lr[0];
P[i + 1] = lr[1];
}
for (i = 0; i < slen; i += 2)
{
encipher(lr, 0);
S[i] = lr[0];
S[i + 1] = lr[1];
}
}
void ULowEntryHashingBCryptLibrary::ekskey(const TArray<uint8>& data, const TArray<uint8>& key)
{
int32 i;
int32 koffp[] = {0}, doffp[] = {0};
int32 lr[] = {0, 0};
int32 plen = P_len, slen = S_len;
for (i = 0; i < plen; i++)
{
P[i] = P[i] ^ streamtoword(key, koffp);
}
for (i = 0; i < plen; i += 2)
{
lr[0] ^= streamtoword(data, doffp);
lr[1] ^= streamtoword(data, doffp);
encipher(lr, 0);
P[i] = lr[0];
P[i + 1] = lr[1];
}
for (i = 0; i < slen; i += 2)
{
lr[0] ^= streamtoword(data, doffp);
lr[1] ^= streamtoword(data, doffp);
encipher(lr, 0);
S[i] = lr[0];
S[i + 1] = lr[1];
}
}
TArray<uint8> ULowEntryHashingBCryptLibrary::crypt_raw(const TArray<uint8>& password, const TArray<uint8>& salt, const int32 log_rounds, int32 cdata[])
{
if ((password.Num() <= 0) || (salt.Num() != BCRYPT_SALT_LEN) || (log_rounds < 4) || (log_rounds > 30))
{
return TArray<uint8>();
}
int32 rounds, i, j;
int32 clen = bf_crypt_ciphertext_len;
TArray<uint8> ret;
rounds = 1 << log_rounds;
init_key();
ekskey(salt, password);
for (i = 0; i != rounds; i++)
{
key(password);
key(salt);
}
for (i = 0; i < 64; i++)
{
for (j = 0; j < (clen >> 1); j++)
{
encipher(cdata, j << 1);
}
}
ret = TArray<uint8>();
ret.SetNum(clen * 4);
for (i = 0, j = 0; i < clen; i++)
{
ret[j++] = static_cast<uint8>((cdata[i] >> 24) & 0xff);
ret[j++] = static_cast<uint8>((cdata[i] >> 16) & 0xff);
ret[j++] = static_cast<uint8>((cdata[i] >> 8) & 0xff);
ret[j++] = static_cast<uint8>(cdata[i] & 0xff);
}
return ret;
}
TArray<uint8> ULowEntryHashingBCryptLibrary::crypt_raw(const TArray<uint8>& password, const TArray<uint8>& salt, const int32 log_rounds)
{
int32 bf_crypt_ciphertext_clone[bf_crypt_ciphertext_len];
for (int32 i = 0; i < bf_crypt_ciphertext_len; i++)
{
bf_crypt_ciphertext_clone[i] = bf_crypt_ciphertext[i];
}
return crypt_raw(password, salt, log_rounds, bf_crypt_ciphertext_clone);
}
TArray<uint8> ULowEntryHashingBCryptLibrary::Hash(const TArray<uint8>& Bytes, const TArray<uint8>& Salt, const int32 Strength)
{
return ULowEntryHashingBCryptLibrary().crypt_raw(Bytes, Salt, Strength);
}