Files
Yajbir Singh f1b860b25c
Some checks failed
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

403 lines
7.9 KiB
C++

#include "hash.h"
#ifndef OWN_BASE_64
#include "../common/Base64.h"
#endif
#include "openssl/sha.h"
#include "openssl/md2.h"
#include "openssl/md4.h"
#include "openssl/md5.h"
#include "openssl/whrlpool.h"
#include "openssl/ripemd.h"
#include <cstring>
#include <memory>
#include <stdlib.h>
int CHash::getDigestLength(HashAlgs alg)
{
static const int aDigestLengths[] = { 16, 16, 16, 20, 20, 32, 48, 64, 64 };
return aDigestLengths[alg];
}
CHash::CHash(std::function<void*(size_t)> allocator) : m_fAllocator(allocator)
{
}
CHash::~CHash()
{
}
unsigned char* CHash::hash(const unsigned char* data, int size, int alg)
{
unsigned int nBufLen = 0;
unsigned char* pBufData = NULL;
size_t d = (size_t)size;
switch (alg)
{
case haMD2:
{
nBufLen = 16;
pBufData = (unsigned char*)m_fAllocator(nBufLen);
MD2(data, d, pBufData);
break;
}
case haMD4:
{
nBufLen = 16;
pBufData = (unsigned char*)m_fAllocator(nBufLen);
MD4(data, d, pBufData);
break;
}
case haMD5:
{
nBufLen = 16;
pBufData = (unsigned char*)m_fAllocator(nBufLen);
MD5(data, d, pBufData);
break;
}
case haRMD160:
{
nBufLen = 20;
pBufData = (unsigned char*)m_fAllocator(nBufLen);
RIPEMD160(data, d, pBufData);
break;
}
case haSHA1:
{
nBufLen = 20;
pBufData = (unsigned char*)m_fAllocator(nBufLen);
SHA1(data, d, pBufData);
break;
}
case haSHA256:
{
nBufLen = 32;
pBufData = (unsigned char*)m_fAllocator(nBufLen);
SHA256(data, d, pBufData);
break;
}
case haSHA384:
{
nBufLen = 48;
pBufData = (unsigned char*)m_fAllocator(nBufLen);
SHA384(data, d, pBufData);
break;
}
case haSHA512:
{
nBufLen = 64;
pBufData = (unsigned char*)m_fAllocator(nBufLen);
SHA512(data, d, pBufData);
break;
}
case haWHIRLPOOL:
{
nBufLen = 64;
pBufData = (unsigned char*)m_fAllocator(nBufLen);
WHIRLPOOL(data, d, pBufData);
break;
}
default:
break;
}
return pBufData;
}
namespace NSUtfs
{
#define WriteUtf16_byte(code, p) \
*p++ = code & 0xFF; \
*p++ = (code >> 8) & 0xFF;
#define WriteUtf16(code, p) \
if (code < 0x10000) \
{ \
WriteUtf16_byte(code, p) \
} \
else \
{ \
code -= 0x10000; \
WriteUtf16_byte((0xD800 | ((code >> 10) & 0x03FF)), p); \
WriteUtf16_byte((0xDC00 | (code & 0x03FF)), p); \
}
void Utf8_to_utf16le(const char* utf8, unsigned char*& utf16, size_t& utf16_len)
{
size_t utf8_count = std::strlen(utf8);
utf16 = (unsigned char*)malloc(utf8_count * 2);
unsigned char* utf16_cur = utf16;
size_t index = 0;
while (index < utf8_count)
{
unsigned char byteMain = utf8[index];
if (0x00 == (byteMain & 0x80))
{
// 1 byte
WriteUtf16(byteMain, utf16_cur);
++index;
}
else if (0x00 == (byteMain & 0x20))
{
// 2 byte
int val = 0;
if ((index + 1) < utf8_count)
{
val = (int)(((byteMain & 0x1F) << 6) |
(utf8[index + 1] & 0x3F));
}
WriteUtf16(val, utf16_cur);
index += 2;
}
else if (0x00 == (byteMain & 0x10))
{
// 3 byte
int val = 0;
if ((index + 2) < utf8_count)
{
val = (int)(((byteMain & 0x0F) << 12) |
((utf8[index + 1] & 0x3F) << 6) |
(utf8[index + 2] & 0x3F));
}
WriteUtf16(val, utf16_cur);
index += 3;
}
else if (0x00 == (byteMain & 0x0F))
{
// 4 byte
int val = 0;
if ((index + 3) < utf8_count)
{
val = (int)(((byteMain & 0x07) << 18) |
((utf8[index + 1] & 0x3F) << 12) |
((utf8[index + 2] & 0x3F) << 6) |
(utf8[index + 3] & 0x3F));
}
WriteUtf16(val, utf16_cur);
index += 4;
}
else if (0x00 == (byteMain & 0x08))
{
// 4 byte
int val = 0;
if ((index + 3) < utf8_count)
{
val = (int)(((byteMain & 0x07) << 18) |
((utf8[index + 1] & 0x3F) << 12) |
((utf8[index + 2] & 0x3F) << 6) |
(utf8[index + 3] & 0x3F));
}
WriteUtf16(val, utf16_cur);
index += 4;
}
else if (0x00 == (byteMain & 0x04))
{
// 5 byte
int val = 0;
if ((index + 4) < utf8_count)
{
val = (int)(((byteMain & 0x03) << 24) |
((utf8[index + 1] & 0x3F) << 18) |
((utf8[index + 2] & 0x3F) << 12) |
((utf8[index + 3] & 0x3F) << 6) |
(utf8[index + 4] & 0x3F));
}
WriteUtf16(val, utf16_cur);
index += 5;
}
else
{
// 6 byte
int val = 0;
if ((index + 5) < utf8_count)
{
val = (int)(((byteMain & 0x01) << 30) |
((utf8[index + 1] & 0x3F) << 24) |
((utf8[index + 2] & 0x3F) << 18) |
((utf8[index + 3] & 0x3F) << 12) |
((utf8[index + 4] & 0x3F) << 6) |
(utf8[index + 5] & 0x3F));
}
WriteUtf16(val, utf16_cur);
index += 5;
}
}
utf16_len = (int)(utf16_cur - utf16);
}
}
void hash_iteration(unsigned char*& input, int iter, unsigned char*& tmp, int alg, size_t alg_size)
{
input[alg_size] = 0xFF & (iter >> 0);
input[alg_size + 1] = 0xFF & (iter >> 8);
input[alg_size + 2] = 0xFF & (iter >> 16);
input[alg_size + 3] = 0xFF & (iter >> 24);
switch (alg)
{
case CHash::haMD2:
{
MD2(input, alg_size + 4, tmp);
break;
}
case CHash::haMD4:
{
MD4(input, alg_size + 4, tmp);
break;
}
case CHash::haMD5:
{
MD5(input, alg_size + 4, tmp);
break;
}
case CHash::haRMD160:
{
RIPEMD160(input, alg_size + 4, tmp);
break;
}
case CHash::haSHA1:
{
SHA1(input, alg_size + 4, tmp);
break;
}
case CHash::haSHA256:
{
SHA256(input, alg_size + 4, tmp);
break;
}
case CHash::haSHA384:
{
SHA384(input, alg_size + 4, tmp);
break;
}
case CHash::haSHA512:
{
SHA512(input, alg_size + 4, tmp);
break;
}
case CHash::haWHIRLPOOL:
{
WHIRLPOOL(input, alg_size + 4, tmp);
break;
}
default:
break;
}
unsigned char* mem = input;
input = tmp;
tmp = mem;
}
unsigned char* CHash::hash2(const char* password, const char* salt, int spinCount, int alg)
{
int inputSaltLen = std::strlen(salt);
unsigned char* passwordUtf16 = NULL;
size_t passwordUtf16Len = 0;
NSUtfs::Utf8_to_utf16le(password, passwordUtf16, passwordUtf16Len);
int inputDataLen = inputSaltLen + passwordUtf16Len;
unsigned char* inputData = (unsigned char*)malloc(inputDataLen);
NSBase64::Base64Decode(salt, inputSaltLen, inputData, &inputDataLen);
memcpy(inputData + inputDataLen, passwordUtf16, passwordUtf16Len);
inputDataLen += passwordUtf16Len;
free(passwordUtf16);
size_t alg_size = 0;
unsigned char* pBuffer1 = NULL;
switch (alg)
{
case haMD2:
{
alg_size = 16;
pBuffer1 = (unsigned char*)m_fAllocator(alg_size + 4);
MD2(inputData, inputDataLen, pBuffer1);
break;
}
case haMD4:
{
alg_size = 16;
pBuffer1 = (unsigned char*)m_fAllocator(alg_size + 4);
MD4(inputData, inputDataLen, pBuffer1);
break;
}
case haMD5:
{
alg_size = 16;
pBuffer1 = (unsigned char*)m_fAllocator(alg_size + 4);
MD5(inputData, inputDataLen, pBuffer1);
break;
}
case haRMD160:
{
alg_size = 20;
pBuffer1 = (unsigned char*)m_fAllocator(alg_size + 4);
RIPEMD160(inputData, inputDataLen, pBuffer1);
break;
}
case haSHA1:
{
alg_size = 20;
pBuffer1 = (unsigned char*)m_fAllocator(alg_size + 4);
SHA1(inputData, inputDataLen, pBuffer1);
break;
}
case haSHA256:
{
alg_size = 32;
pBuffer1 = (unsigned char*)m_fAllocator(alg_size + 4);
SHA256(inputData, inputDataLen, pBuffer1);
break;
}
case haSHA384:
{
alg_size = 48;
pBuffer1 = (unsigned char*)m_fAllocator(alg_size + 4);
SHA384(inputData, inputDataLen, pBuffer1);
break;
}
case haSHA512:
{
alg_size = 64;
pBuffer1 = (unsigned char*)m_fAllocator(alg_size + 4);
SHA512(inputData, inputDataLen, pBuffer1);
break;
}
case haWHIRLPOOL:
{
alg_size = 64;
pBuffer1 = (unsigned char*)m_fAllocator(alg_size + 4);
WHIRLPOOL(inputData, inputDataLen, pBuffer1);
break;
}
default:
break;
}
free(inputData);
if (0 == spinCount)
return pBuffer1;
unsigned char* pBuffer2 = (unsigned char*)malloc(alg_size + 4);
for (int i = 0; i < spinCount; ++i)
{
hash_iteration(pBuffer1, i, pBuffer2, alg, alg_size);
}
free(pBuffer2);
return pBuffer1;
}