BOOL kull_m_crypto_hash(ALG_ID algid, LPCVOID data, DWORD dataLen, LPVOID hash, DWORD hashWanted) { BOOL status = FALSE; HCRYPTPROV hProv; HCRYPTHASH hHash; DWORD hashLen; PBYTE buffer; if(CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { if(CryptCreateHash(hProv, algid, 0, 0, &hHash)) { if(CryptHashData(hHash, (LPCBYTE) data, dataLen, 0)) { if(CryptGetHashParam(hHash, HP_HASHVAL, NULL, &hashLen, 0)) { if(buffer = (PBYTE) LocalAlloc(LPTR, hashLen)) { status = CryptGetHashParam(hHash, HP_HASHVAL, buffer, &hashLen, 0); RtlCopyMemory(hash, buffer, KIWI_MINIMUM(hashLen, hashWanted)); LocalFree(buffer); } } } CryptDestroyHash(hHash); } CryptReleaseContext(hProv, 0); } return status; }
BOOL kull_m_crypto_hmac(DWORD calgid, LPCVOID key, DWORD keyLen, LPCVOID message, DWORD messageLen, LPVOID hash, DWORD hashWanted) // for keyLen > 1 { BOOL status = FALSE; DWORD hashLen; HCRYPTPROV hProv; HCRYPTKEY hKey; HCRYPTHASH hHash; HMAC_INFO HmacInfo = {calgid, NULL, 0, NULL, 0}; PBYTE buffer; if(CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { if(kull_m_crypto_hkey(hProv, CALG_RC2, key, keyLen, CRYPT_IPSEC_HMAC_KEY, &hKey, NULL)) { if(CryptCreateHash(hProv, CALG_HMAC, hKey, 0, &hHash)) { if(CryptSetHashParam(hHash, HP_HMAC_INFO, (LPCBYTE) &HmacInfo, 0)) if(CryptHashData(hHash, (LPCBYTE) message, messageLen, 0)) if(CryptGetHashParam(hHash, HP_HASHVAL, NULL, &hashLen, 0)) { if(buffer = (PBYTE) LocalAlloc(LPTR, hashLen)) { status = CryptGetHashParam(hHash, HP_HASHVAL, buffer, &hashLen, 0); RtlCopyMemory(hash, buffer, KIWI_MINIMUM(hashLen, hashWanted)); LocalFree(buffer); } } CryptDestroyHash(hHash); } CryptDestroyKey(hKey); } CryptReleaseContext(hProv, 0); } return status; }
BOOL kull_m_crypto_pkcs5_pbkdf2_hmac(DWORD calgid, LPCVOID password, DWORD passwordLen, LPCVOID salt, DWORD saltLen, DWORD iterations, BYTE *key, DWORD keyLen) { BOOL status = FALSE; HCRYPTPROV hProv; HCRYPTHASH hHash; DWORD sizeHmac, count, i, j, r; PBYTE asalt, obuf, d1, d2; if(CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { if(CryptCreateHash(hProv, calgid, 0, 0, &hHash)) { if(CryptGetHashParam(hHash, HP_HASHVAL, NULL, &sizeHmac, 0)) { if(asalt = (PBYTE) LocalAlloc(LPTR, saltLen + 4)) { if(obuf = (PBYTE) LocalAlloc(LPTR, sizeHmac)) { if(d1 = (PBYTE) LocalAlloc(LPTR, sizeHmac)) { if(d2 = (PBYTE) LocalAlloc(LPTR, sizeHmac)) { status = TRUE; RtlCopyMemory(asalt, salt, saltLen); for (count = 1; keyLen > 0; count++) { *(PDWORD) (asalt + saltLen) = _byteswap_ulong(count); kull_m_crypto_hmac(calgid, password, passwordLen, asalt, saltLen + 4, d1, sizeHmac); RtlCopyMemory(obuf, d1, sizeHmac); for (i = 1; i < iterations; i++) { kull_m_crypto_hmac(calgid, password, passwordLen, d1, sizeHmac, d2, sizeHmac); RtlCopyMemory(d1, d2, sizeHmac); for (j = 0; j < sizeHmac; j++) obuf[j] ^= d1[j]; } r = KIWI_MINIMUM(keyLen, sizeHmac); RtlCopyMemory(key, obuf, r); key += r; keyLen -= r; } LocalFree(d2); } LocalFree(d1); } LocalFree(obuf); } LocalFree(asalt); } } CryptDestroyHash(hHash); } CryptReleaseContext(hProv, 0); } return status; }
BOOL kull_m_crypto_DeriveKeyRaw(ALG_ID hashId, LPVOID hash, DWORD hashLen, LPVOID key, DWORD keyLen) { BOOL status = FALSE; BYTE buffer[152], ipad[64], opad[64]; DWORD i; if(status = (hashLen >= keyLen)) RtlCopyMemory(key, hash, keyLen); else { RtlFillMemory(ipad, sizeof(ipad), '6'); RtlFillMemory(opad, sizeof(opad), '\\'); for(i = 0; i < hashLen; i++) { ipad[i] ^= ((PBYTE) hash)[i]; opad[i] ^= ((PBYTE) hash)[i]; } if(kull_m_crypto_hash(hashId, ipad, sizeof(ipad), buffer, hashLen)) if(status = kull_m_crypto_hash(hashId, opad, sizeof(opad), buffer + hashLen, hashLen)) RtlCopyMemory(key, buffer, KIWI_MINIMUM(keyLen, 2 * hashLen)); } return status; }