HMAC (MD5, SHA-1, SHA-256, SHA-384, and SHA-512)

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
atnbueno
Posts: 89
Joined: 12 Oct 2013, 04:45
Contact:

HMAC (MD5, SHA-1, SHA-256, SHA-384, and SHA-512)

03 Jan 2014, 15:26

Hello everyone.

I recently had the need to generate HMACs with AutoHotkey and I found almost all the work was already done in the old forum by user manonstreet. I made it compatible with x64 and fixed a couple of minor mistakes and this is the result:

Code: Select all

HMAC(ByRef HashVal, ByRef sData, nDataSize, ByRef sKey, nKeySize, sHashAlg = "SHA256")
{
	CALG_SHA_512 := 1 + CALG_SHA_384 := 1 + CALG_SHA_256 := 8 + CALG_SHA1 := 1 + CALG_MD5 := 0x00008003

	Static PROV_RSA_FULL        := 0x01,
	       CUR_BLOB_VERSION     := 0x02,
	       PLAINTEXTKEYBLOB     := 0x08,
	       CRYPT_VERIFYCONTEXT  := 0xF0000000,
	       CALG_RC2             := 0x6602,
	       CALG_HMAC            := 0x8009,
	       HP_HMAC_INFO         := 0x05,
	       HP_HASHVAL           := 0x02,
	       CRYPT_IPSEC_HMAC_KEY := 0x0100

	VarSetCapacity(HmacInfo, 4 * A_PtrSize, 0) ; HMAC_INFO struct, see http://msdn.com/library/aa382480
	NumPut(CALG_%sHashAlg%, HmacInfo, 0, "UInt") ; selects hashing algorithm, the rest is zero so default strings are used
	nKeyBlobSize := 12 + nKeySize
	VarSetCapacity(keyBlob, nKeyBlobSize, 0) ; BLOBHEADER struct, see http://msdn.com/library/aa387453
	NumPut(PLAINTEXTKEYBLOB, keyBlob, 0, "Char") ; PLAINTEXTKEYBLOB struct, http://msdn.com/library/jj650836
	NumPut(CUR_BLOB_VERSION, keyBlob, 1, "Char")
	NumPut(CALG_RC2, keyBlob, 4, "UInt")
	NumPut(nKeySize, keyBlob, 8, "Char")
	DllCall("RtlMoveMemory", "UInt", &keyBlob + 12, "UInt", &sKey, "Int", nKeySize) ; see http://msdn.com/library/ff562030

	; see steps at http://msdn.com/library/aa379863 and C++ example at http://msdn.com/library/aa382379
	If (DllCall("advapi32\CryptAcquireContext", "UIntP", hProv, "UInt", 0, "UInt", 0, "UInt", PROV_RSA_FULL, "UInt", CRYPT_VERIFYCONTEXT)) {
		If (DllCall("advapi32\CryptImportKey", "UInt", hProv, "UInt", &keyBlob, "UInt", nKeyBlobSize, "UInt", 0, "UInt", CRYPT_IPSEC_HMAC_KEY, "UIntP", hKey)) {
			If (DllCall("advapi32\CryptCreateHash", "UInt", hProv, "UInt", CALG_HMAC, "UInt", hKey, "UInt", 0, "UIntP", hHmacHash)) {
				If (DllCall("advapi32\CryptSetHashParam", "UInt", hHmacHash, "UInt", HP_HMAC_INFO, "UInt", &HmacInfo, "UInt", 0)) {
					If (DllCall("advapi32\CryptHashData", "UInt", hHmacHash, "UInt", &sData, "UInt", nDataSize, "UInt", 0)) {
						If (DllCall("advapi32\CryptGetHashParam", "UInt", hHmacHash, "UInt", HP_HASHVAL, "UInt", 0, "UIntP", nHashSize, "UInt", 0)) { ; hash size
							VarSetCapacity(HashVal, nHashSize, 0)
							DllCall("advapi32\CryptGetHashParam", "UInt", hHmacHash, "UInt", HP_HASHVAL, "UInt", &HashVal, "UIntP", nHashSize, "UInt", 0) ; hash value
						}
					}
				}
				DllCall("advapi32\CryptDestroyHash", "UInt", hHmacHash)
			}
			DllCall("advapi32\CryptDestroyKey", "UInt", hKey)
		}
		DllCall("advapi32\CryptReleaseContext", "UInt", hProv, "UInt", 0)
	}
	Return nHashSize
}
I also found out I needed this function if I wanted to work with UTF-8 (it's similar to StrPutVar):

Code: Select all

Wide2UTF8(sInput, ByRef Output)
{
	nOutputSize := StrPut(sInput, "UTF-8")
	VarSetCapacity(Output, nOutputSize)
	StrPut(sInput, &Output, nOutputSize, "UTF-8")
	Return nOutputSize-1
}
Finally, I wanted to check the implementation against the test vectors in RFC2202 (MD5 and SHA-1) and RFC4231 (SHA-256, SHA-384, and SHA-512), so I put together the following script which also serves as an example of use for the functions above:
http://dl.dropboxusercontent.com/u/7416 ... tation.ahk

As manonstreet more than three years ago, I hope someone finds this useful somehow :-)


Regards,
Antonio
Last edited by atnbueno on 06 Jan 2014, 15:50, edited 1 time in total.
nimda
Posts: 34
Joined: 18 Dec 2013, 14:06

Re: HMAC (MD5, SHA-1, SHA-256, SHA-384, and SHA-512)

05 Jan 2014, 20:34

Weird, I was just about to implement this myself. I had checked last Monday and nobody had done it, so it's a good thing it showed up in the Unread posts feed!

Thanks :D
Colemen
Posts: 1
Joined: 16 Aug 2017, 07:20

Re: HMAC (MD5, SHA-1, SHA-256, SHA-384, and SHA-512)

16 Aug 2017, 07:27

Hey, I am new to hash algorithms, I understand how they function in theory, but I cannot seem to wrap my head around what each line is doing specifically.
I know it is a lot to ask, but could you give an example of to use this function and how it accomplishes it's task??

Thank you in advance,
Colemen

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: sanmaodo and 64 guests