diff --git a/SlnkDWFCom/Crypto.cpp b/SlnkDWFCom/Crypto.cpp index 78e2a0c..b5e1984 100644 --- a/SlnkDWFCom/Crypto.cpp +++ b/SlnkDWFCom/Crypto.cpp @@ -114,6 +114,76 @@ STDMETHODIMP CCrypto::hex_sha1(BSTR data, BSTR* pVal) return bstrString.CopyTo(pVal); } +// Big Endian +static inline void be32enc(void *pp, uint32_t x) +{ + uint8_t * p = (uint8_t *)pp; + p[3] = x & 0xff; + p[2] = (x >> 8) & 0xff; + p[1] = (x >> 16) & 0xff; + p[0] = (x >> 24) & 0xff; +} + +/* F(P, S, c, i) = U1 xor U2 xor ... Uc +* U1 = PRF(P, S || i) +* U2 = PRF(P, U1) +* Uc = PRF(P, Uc-1) +*/ +#define SHA1_MAC_LEN 20 +STDMETHODIMP CCrypto::hex_pbkdf2(BSTR pPassword, BSTR pSalt, ULONG pCount, ULONG pLength, BSTR* pVal) +{ + CString apass(pPassword); + CString asalt(pSalt); + int saltlen = asalt.GetLength(); + BYTE *saltbuff = (BYTE *)asalt.GetBufferSetLength(saltlen + 4); // Ruimte maken voor counter + int passlen = apass.GetLength(); + BYTE *passbuff = (BYTE *)apass.GetBuffer(); + + size_t i; + uint8_t U[SHA1_MAC_LEN]; + uint8_t T[SHA1_MAC_LEN]; // Hierin komt het XOR resultaat + + CString res; + + /* Iterate through the blocks. */ + for (i = 0; i * SHA1_MAC_LEN < pLength; i++) + { + /* Generate INT(i + 1). */ + be32enc(saltbuff + saltlen, i + 1); + + /* Compute U_1 = PRF(P, S || INT(i)). */ + CHMAC_SHA1 HMAC_SHA1; + HMAC_SHA1.HMAC_SHA1(saltbuff, saltlen + 4, passbuff, passlen, U); + + /* T_1 = U_1 ... */ + memcpy(T, U, SHA1_MAC_LEN); + + for (uint64_t j = 2; j <= pCount; j++) + { + /* Compute U_j. */ + HMAC_SHA1.HMAC_SHA1(U, SHA1_MAC_LEN, passbuff, passlen, U); + + /* ... xor U_j ... */ + for (int k = 0; k < sizeof(U); k++) + T[k] ^= U[k]; + } + + /* Copy as many bytes as necessary into buf. */ + int clen = pLength - i * SHA1_MAC_LEN; + if (clen > SHA1_MAC_LEN) + clen = SHA1_MAC_LEN; + + for (int k = 0; k < clen; k++) + { + res = res + hex_tab[T[k] >> 4]; + res = res + hex_tab[T[k] & 0xF]; + } + } + + CComBSTR bstrString(res); + return bstrString.CopyTo(pVal); +} + STDMETHODIMP CCrypto::hex_sha1_file(BSTR fname, BSTR* pVal) { CSHA1 sha1; diff --git a/SlnkDWFCom/Crypto.h b/SlnkDWFCom/Crypto.h index 1df5199..f72b33a 100644 --- a/SlnkDWFCom/Crypto.h +++ b/SlnkDWFCom/Crypto.h @@ -53,6 +53,7 @@ public: STDMETHOD(hex_sha1_file)(BSTR fname, BSTR* pVal); STDMETHOD(hotp)(BSTR hexseed, LONGLONG counter, BYTE digits, BSTR* pVal); + STDMETHOD(hex_pbkdf2)(BSTR pPassword, BSTR pSalt, ULONG pCount, ULONG pLength, BSTR* pVal); }; OBJECT_ENTRY_AUTO(__uuidof(Crypto), CCrypto) diff --git a/SlnkDWFCom/SLNKDWF.idl b/SlnkDWFCom/SLNKDWF.idl index ba7b518..2ba248b 100644 --- a/SlnkDWFCom/SLNKDWF.idl +++ b/SlnkDWFCom/SLNKDWF.idl @@ -392,6 +392,7 @@ interface ICrypto : IDispatch{ [id(3), helpstring("method hex_sha1")] HRESULT hex_sha1([in] BSTR str, [out,retval] BSTR* pVal); [id(4), helpstring("method hex_sha1_file")] HRESULT hex_sha1_file([in] BSTR fname, [out,retval] BSTR* pVal); [id(5), helpstring("method hotp")] HRESULT hotp([in] BSTR hexseed, [in] LONGLONG counter, [in, defaultvalue(6)] BYTE digits, [out,retval] BSTR* pVal); + [id(6), helpstring("method hex_pbkdf2")] HRESULT hex_pbkdf2([in] BSTR pPassword, [in] BSTR pSalt, [in] ULONG pCount, [in, defaultvalue(20)] ULONG pLength, [out, retval] BSTR* pVal); }; [ object, diff --git a/SlnkDWFCom/SLNKDWFVersion.h b/SlnkDWFCom/SLNKDWFVersion.h index 02c567a..d056452 100644 --- a/SlnkDWFCom/SLNKDWFVersion.h +++ b/SlnkDWFCom/SLNKDWFVersion.h @@ -1,6 +1,6 @@ // Zorg dat versies alfabetisch altijd op elkaar volgen! #define SLNK_MAJOR_VERSION 4 -#define SLNK_MINOR_VERSION 10 +#define SLNK_MINOR_VERSION 11 #define SLNK_BUILD_VERSION 0 // Define resource strings diff --git a/SlnkDWFImpl/DWFFileImpl.cpp b/SlnkDWFImpl/DWFFileImpl.cpp index 7725557..43e7e94 100644 --- a/SlnkDWFImpl/DWFFileImpl.cpp +++ b/SlnkDWFImpl/DWFFileImpl.cpp @@ -1,7 +1,7 @@ // DWFFile.cpp : Implementation of CDWFFile #include "stdafx.h" -#include "assert.h" +//#include "assert.h" #include "DWFFileImpl.h" #include "myEPlotSectionImpl.h"