From cb80a37654ebc902769f87ffbadd38d161109333 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Wed, 27 Nov 2013 19:09:16 +0000 Subject: - strong cyphering for passwords in db3x_mmap; - unique signature for the new mmap profiles; git-svn-id: http://svn.miranda-ng.org/main/trunk@6997 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- src/core/stdcrypt/Rijndael.cpp | 10 +++- src/core/stdcrypt/commonheaders.h | 2 +- src/core/stdcrypt/encrypt.cpp | 112 +++++++++++++++++--------------------- src/core/stdcrypt/stdcrypt.h | 6 +- src/core/stdcrypt/utils.cpp | 6 +- 5 files changed, 66 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/core/stdcrypt/Rijndael.cpp b/src/core/stdcrypt/Rijndael.cpp index fd9cf84d83..95cc317099 100644 --- a/src/core/stdcrypt/Rijndael.cpp +++ b/src/core/stdcrypt/Rijndael.cpp @@ -963,8 +963,14 @@ int CRijndael::MakeKey(BYTE const* key, char const* chain, int keylength, int bl m_keylength = keylength; m_blockSize = blockSize; //Initialize the chain - memcpy(m_chain0, chain, m_blockSize); - memcpy(m_chain, chain, m_blockSize); + size_t len = strlen(chain); + if (len >= m_blockSize) + memcpy(m_chain0, chain, m_blockSize); + else { + memcpy(m_chain0, chain, len); + memset(m_chain0 + len, 0, m_blockSize - len); + } + memcpy(m_chain, m_chain0, m_blockSize); //Calculate Number of Rounds switch (m_keylength) { case 16: diff --git a/src/core/stdcrypt/commonheaders.h b/src/core/stdcrypt/commonheaders.h index 37168497d8..07daa68ac1 100644 --- a/src/core/stdcrypt/commonheaders.h +++ b/src/core/stdcrypt/commonheaders.h @@ -78,4 +78,4 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. extern HINSTANCE hInst; bool getRandomBytes(BYTE *buf, size_t bufLen); -void slow_hash(const void *buf, size_t bufLen, BYTE tmpHash[32]); +void slow_hash(const void *buf, size_t bufLen, BYTE *tmpHash); diff --git a/src/core/stdcrypt/encrypt.cpp b/src/core/stdcrypt/encrypt.cpp index 00e52935d8..5be76f1c54 100644 --- a/src/core/stdcrypt/encrypt.cpp +++ b/src/core/stdcrypt/encrypt.cpp @@ -67,24 +67,20 @@ bool CStdCrypt::getKey(BYTE *pKey, size_t cbKeyLen) bool CStdCrypt::setKey(const BYTE *pKey, size_t cbKeyLen) { - ExternalKey tmp = { 0 }; - // full external key. decode & check password - if (cbKeyLen == sizeof(tmp)) { - BYTE tmpHash[32]; - slow_hash(m_password, m_password.GetLength(), tmpHash); - - CRijndael tmpAes; - tmpAes.MakeKey(tmpHash, tmpAes.sm_chain0, KEY_LENGTH, BLOCK_SIZE); - tmpAes.Decrypt(pKey, &tmp, sizeof(tmp)); - if (tmp.m_crc32 != crc32(0xAbbaDead, (LPCBYTE)m_password.GetString(), m_password.GetLength())) - return false; - } - // new key. simply copy it - else if (cbKeyLen == KEY_LENGTH) { - memcpy(&tmp.m_key, pKey, KEY_LENGTH); - } - else return false; + if (cbKeyLen != sizeof(ExternalKey)) + return false; + + BYTE tmpHash[32]; + slow_hash(m_password, m_password.GetLength(), tmpHash); + + CRijndael tmpAes; + tmpAes.MakeKey(tmpHash, tmpAes.sm_chain0, KEY_LENGTH, BLOCK_SIZE); + + ExternalKey tmp = { 0 }; + tmpAes.Decrypt(pKey, &tmp, sizeof(tmp)); + if (tmp.m_crc32 != crc32(0xAbbaDead, (LPCBYTE)m_password.GetString(), m_password.GetLength())) + return false; memcpy(m_key, &tmp.m_key, KEY_LENGTH); m_aes.MakeKey(m_key, m_password, KEY_LENGTH, BLOCK_SIZE); @@ -97,7 +93,9 @@ bool CStdCrypt::generateKey(void) if (!getRandomBytes(tmp, sizeof(tmp))) return false; - return setKey(tmp, sizeof(tmp)); + memcpy(m_key, tmp, KEY_LENGTH); + m_aes.MakeKey(m_key, m_password, KEY_LENGTH, BLOCK_SIZE); + return m_valid = true; } void CStdCrypt::purgeKey(void) @@ -115,37 +113,34 @@ void CStdCrypt::setPassword(const char *pszPassword) // result must be freed using mir_free or assigned to mir_ptr BYTE* CStdCrypt::encodeString(const char *src, size_t *cbResultLen) { - if (cbResultLen) - *cbResultLen = 0; - - if (!m_valid || src == NULL || *src == 0) - return NULL; - - size_t cbLen = strlen(src); - cbLen += BLOCK_SIZE - (cbLen % BLOCK_SIZE); - BYTE *result = (BYTE*)mir_alloc(cbLen); - if (m_aes.Encrypt(src, LPSTR(result), cbLen)) { - mir_free(result); + if (!m_valid || src == NULL) { + if (cbResultLen) + *cbResultLen = 0; return NULL; } - if (cbResultLen) - *cbResultLen = cbLen; - return result; + return encodeBuffer(src, strlen(src)+1, cbResultLen); } -BYTE* CStdCrypt::encodeStringW(const WCHAR *src, size_t *cbResultLen) +BYTE* CStdCrypt::encodeBuffer(const void *src, size_t cbLen, size_t *cbResultLen) { if (cbResultLen) *cbResultLen = 0; - if (!m_valid || src == NULL || *src == 0) + if (!m_valid || src == NULL || cbLen >= 0xFFFE) return NULL; - size_t cbLen = wcslen(src) * sizeof(WCHAR); - cbLen += BLOCK_SIZE - (cbLen % BLOCK_SIZE); + BYTE *tmpBuf = (BYTE*)_alloca(cbLen + 2); + *(PWORD)tmpBuf = (WORD)cbLen; + memcpy(tmpBuf + 2, src, cbLen); + cbLen += 2; + size_t rest = cbLen % BLOCK_SIZE; + if (rest) + cbLen += BLOCK_SIZE - rest; + BYTE *result = (BYTE*)mir_alloc(cbLen); - if (m_aes.Encrypt(LPCSTR(src), LPSTR(result), cbLen)) { + m_aes.ResetChain(); + if (m_aes.Encrypt(tmpBuf, LPSTR(result), cbLen)) { mir_free(result); return NULL; } @@ -157,29 +152,21 @@ BYTE* CStdCrypt::encodeStringW(const WCHAR *src, size_t *cbResultLen) char* CStdCrypt::decodeString(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen) { - if (cbResultLen) - *cbResultLen = 0; - - if (!m_valid || pBuf == NULL || (bufLen % BLOCK_SIZE) != 0) - return NULL; - - char *result = (char*)mir_alloc(bufLen+1); - if (m_aes.Decrypt(LPCSTR(pBuf), result, bufLen)) { - mir_free(result); - return NULL; + size_t resLen; + char *result = (char*)decodeBuffer(pBuf, bufLen, &resLen); + if (result) { + if (result[resLen-1] != 0) { // smth went wrong + mir_free(result); + return NULL; + } } - result[bufLen] = 0; - for (int i = (int)bufLen-1; i >= 0; i--) - if (result[i] == 0) - bufLen--; - if (cbResultLen) - *cbResultLen = bufLen; + *cbResultLen = resLen; return result; } -WCHAR* CStdCrypt::decodeStringW(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen) +void* CStdCrypt::decodeBuffer(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen) { if (cbResultLen) *cbResultLen = 0; @@ -187,20 +174,23 @@ WCHAR* CStdCrypt::decodeStringW(const BYTE *pBuf, size_t bufLen, size_t *cbResul if (!m_valid || pBuf == NULL || (bufLen % BLOCK_SIZE) != 0) return NULL; - WCHAR *result = (WCHAR*)mir_alloc(bufLen + sizeof(WCHAR)); - if (m_aes.Decrypt(LPCSTR(pBuf), LPSTR(result), bufLen)) { + char *result = (char*)mir_alloc(bufLen + 1); + m_aes.ResetChain(); + if (m_aes.Decrypt(LPCSTR(pBuf), result, bufLen)) { mir_free(result); return NULL; } - bufLen /= sizeof(WCHAR); result[bufLen] = 0; - for (int i = (int)bufLen - 1; i >= 0; i--) - if (result[i] == 0) - bufLen--; + WORD cbLen = *(PWORD)result; + if (cbLen > bufLen) { + mir_free(result); + return NULL; + } + memmove(result, result + 2, cbLen); if (cbResultLen) - *cbResultLen = bufLen; + *cbResultLen = cbLen; return result; } diff --git a/src/core/stdcrypt/stdcrypt.h b/src/core/stdcrypt/stdcrypt.h index c9a3a72315..6129cabcc8 100644 --- a/src/core/stdcrypt/stdcrypt.h +++ b/src/core/stdcrypt/stdcrypt.h @@ -49,9 +49,9 @@ struct CStdCrypt : public MICryptoEngine, public MZeroedObject // result must be freed using mir_free or assigned to mir_ptr STDMETHODIMP_(BYTE*) encodeString(const char *src, size_t *cbResultLen); - STDMETHODIMP_(BYTE*) encodeStringW(const WCHAR* src, size_t *cbResultLen); + STDMETHODIMP_(BYTE*) encodeBuffer(const void *src, size_t cbLen, size_t *cbResultLen); // result must be freed using mir_free or assigned to ptrA/ptrT - STDMETHODIMP_(char*) decodeString(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen); - STDMETHODIMP_(WCHAR*) decodeStringW(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen); + STDMETHODIMP_(char*) decodeString(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen); + STDMETHODIMP_(void*) decodeBuffer(const BYTE *pBuf, size_t bufLen, size_t *cbResultLen); }; diff --git a/src/core/stdcrypt/utils.cpp b/src/core/stdcrypt/utils.cpp index 3ef8b7bdf7..99b2d3c8db 100644 --- a/src/core/stdcrypt/utils.cpp +++ b/src/core/stdcrypt/utils.cpp @@ -342,7 +342,7 @@ static void sha256_final(SHA256_CONTEXT *hd, BYTE tmpHash[32]) #undef X } -static void make_sha256(const void *buf, size_t bufLen, BYTE tmpHash[32]) +static void make_sha256(const void *buf, size_t bufLen, BYTE *tmpHash) { SHA256_CONTEXT tmp; sha256_init(&tmp); @@ -350,10 +350,10 @@ static void make_sha256(const void *buf, size_t bufLen, BYTE tmpHash[32]) sha256_final(&tmp, tmpHash); } -void slow_hash(const void *buf, size_t bufLen, BYTE tmpHash[32]) +void slow_hash(const void *buf, size_t bufLen, BYTE* tmpHash) { make_sha256(buf, bufLen, tmpHash); for (int i = 0; i < 50000; i++) - make_sha256(tmpHash, sizeof(tmpHash), tmpHash); + make_sha256(tmpHash, 32, tmpHash); } -- cgit v1.2.3