Hello!
Im planning to build some program where hash functions SHA1, MD5 are required.
So, i made some exploration, about it, and i found, that
there is no need - to make new bicycle (make algorithm again, by your self).
Win64 Crypto API provides a way to get hash string of data.
.Formal_description:; ---------------------------------------------------------------------------
;
This is: Win64 Crypto API SHA1 MD5 (Example code)
; Author: J.K. Encryptor256
; Date: October 25, 2013
; ---------------------------------------------------------------------------
; This example code will answer to
;
Question: How to use Win64 Crypto API to get hash of data?
; ---------------------------------------------------------------------------
;
Using:;
;
1. The Netwide Assembler, NASM (
http://nasm.us/)
; The Netwide Assembler, NASM: It is an 80x86 and x86-64 assembler
; designed for portability and modularity.
;
;
2. Minimalist GNU for Windows, MinGW64 (
http://mingw-w64.sourceforge.net/)
; Mingw-w64: It delivers runtime, headers and libs for developing
; both, 64 bit (x64) and 32 bit (x86) windows applications, using GCC and
; other free software compilers.
;
; GCC is a part of MINGW64 toolset.
;
;
3. GoLink, (
http://www.godevtool.com/)
;
; ---------------------------------------------------------------------------
;
How to compile:;
; Like this, in the way i did:
;
;
1. NASM: "nasm.exe main.asm -f win64 -o main.obj"
; Output obj size: 2.86 KB (2,930 bytes)
;
; Choose your linker:
;
;
2.1. GCC: "gcc.exe -m64 main.obj -o main.exe"
; Output exe size: 46.8 KB (47,958 bytes)
;
;
2.2. GoLink: "golink.exe /entry main main.obj MSVCRT.dll kernel32.dll user32.dll advapi32.dll"
; Output exe size: 3.00 KB (3,072 bytes)
;
; ---------------------------------------------------------------------------
;
More information, about SHA1 and MD5, you can find:
;
;
1. SHA-1:
; "
http://en.wikipedia.org/wiki/SHA-1"
;
;
2. MD5:
; "
http://en.wikipedia.org/wiki/MD5"
;
;
3. US Secure Hash Algorithm 1 (SHA1):
; "
http://www.ietf.org/rfc/rfc3174.txt"
; This link NR. 3 is very good for SHA1, there is also C source code.
; ---------------------------------------------------------------------------
Example code is organized into three files, one of them is main compile file, other two are just an include files.
- main.asm (Main compile file)
- macros.asm
- sha1.asm
Include file, named
sha1.asm, contains:
; PROCEDURES
; 1. getHash - get's hash string of data
; 2. printHex - print's hash string, displays a message box
Include file, named
macros.asm, contains:
; MACROS
; 1. Invoke
; 2. Invoke_error
; 3. Invoke_returns
; 4. stringTable
.How_to_use:Content of main.asm file:
; ---------------------------------------------------------------------------
; Tell compiler to generate 64 bit code
; ---------------------------------------------------------------------------
bits 64
%include "macros.asm"
%include "sha1.asm"
; ---------------------------------------------------------------------------
; Data segment:
; ---------------------------------------------------------------------------
section .data use64
stringTable txt_buffer,"BufferBufferBufferBufferBufferBufferBufferBufferBufferBufferBuffer"
stringTable txt_error_code,"Error code: %d"
stringTable txt_text,"The quick brown fox jumps over the lazy dog", \
txt_sha1,"SHA1: should be '2fd4e1c6 7a2d28fc ed849ee1 bb76e739 1b93eb12'", \
txt_md5,"MD5: should be '9e107d9d372bb6826bd81d3542a419d6'"
ptrToHashData: dq 0
; ---------------------------------------------------------------------------
; Bss segment:
; ---------------------------------------------------------------------------
section .bss use64
; ---------------------------------------------------------------------------
; Code segment:
; ---------------------------------------------------------------------------
section .text use64
global main
extern sprintf
extern MessageBoxA
extern ExitProcess
extern strlen
extern malloc
extern GetLastError
extern free
main:
; -----------------------------------------------------------------------------
; Allocate stack memory
; -----------------------------------------------------------------------------
sub rsp,8*17
; -----------------------------------------------------------------------------
; 1. ## Let's test SHA1 of data: "The quick brown fox jumps over the lazy dog"
; -----------------------------------------------------------------------------
; Get len of the string
Invoke strlen,txt_text
; Invoke getHash
Invoke getHash,CALG_SHA1,txt_text,rax,ptrToHashData
; Check expected result, should be 20 of len
Invoke_error je,20,main.getSHA1_Success
Invoke GetLastError
Invoke sprintf,txt_buffer,txt_error_code,rax
Invoke MessageBoxA,0,txt_buffer,0,0
Invoke ExitProcess,0
main.getSHA1_Success:
; printHex
Invoke printHex,[ptrToHashData],20,txt_sha1
; -----------------------------------------------------------------------------
; Free allocated hash data
; -----------------------------------------------------------------------------
Invoke free,[ptrToHashData]
; -----------------------------------------------------------------------------
; 2. ## Let's test MD5 of data: "The quick brown fox jumps over the lazy dog"
; -----------------------------------------------------------------------------
; Get len of the string
Invoke strlen,txt_text
; Invoke getHash
Invoke getHash,CALG_MD5,txt_text,rax,ptrToHashData
; Check expected result, should be 16 of len
Invoke_error je,16,main.getMD5_Success
Invoke GetLastError
Invoke sprintf,txt_buffer,txt_error_code,rax
Invoke MessageBoxA,0,txt_buffer,0,0
Invoke ExitProcess,0
main.getMD5_Success:
; printHex
Invoke printHex,[ptrToHashData],16,txt_md5
; -----------------------------------------------------------------------------
; Free allocated hash data
; -----------------------------------------------------------------------------
Invoke free,[ptrToHashData]
; -----------------------------------------------------------------------------
; Quit
; -----------------------------------------------------------------------------
add rsp,8*17
Invoke ExitProcess,0
ret
Content's of both include files you can find at attachment.
The first test of Win64 Crypto API i made in C,
because i wanted to be sure, that this Crypto API actually works, and it did.
If you don't like my source code you can build your own version, derive from C language, here is some info:
1. I modified and builded a working version from this link, named:
"Example C Program: Creating an HMAC"
http://msdn.microsoft.com/en-us/library/windows/desktop/aa382379(v=vs.85).aspx2. Or, you just can have my final C version (a bit dirty):
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define uCALG_MD2 (32769)
#define uCALG_MD4 (32770)
#define uCALG_MD5 (32771)
#define uCALG_SHA1 (32772)
int getHash(unsigned int tagType, void * tagData, unsigned int tagDataLen, void ** tagDataOut)
{
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
DWORD dwDataLen = 0;
DWORD dwResult = 0;
if(0!=CryptAcquireContext(&hProv,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT))
{
if(0!=CryptCreateHash(hProv,tagType,0,0,&hHash))
{
if (0!=CryptHashData(hHash,(CONST BYTE*)tagData,tagDataLen,0))
{
if(0!=CryptGetHashParam(hHash,HP_HASHVAL,NULL,&dwDataLen,0))
{
(*tagDataOut)=malloc(dwDataLen);
if (0!=CryptGetHashParam(hHash,HP_HASHVAL,(BYTE*)(*tagDataOut),&dwDataLen,0))
{
dwResult=dwDataLen;
}
else
{
free((*tagDataOut));
};
};
};
};
};
if(hHash)
CryptDestroyHash(hHash);
if(hProv)
CryptReleaseContext(hProv, 0);
return dwResult;
};
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
/*
; -----------------------------------------------------
; SHA1("The quick brown fox jumps over the lazy dog")
; = 2fd4e1c6 7a2d28fc ed849ee1 bb76e739 1b93eb12
; -----------------------------------------------------
; MD5("The quick brown fox jumps over the lazy dog")
; = 9e107d9d372bb6826bd81d3542a419d6
; -----------------------------------------------------
*/
char buffz1[231] = "";
sprintf(buffz1,"%d",'f');
MessageBox(0,buffz1,0,0);
char str[] = {"The quick brown fox jumps over the lazy dog"};
unsigned char * out;
int len = getHash(CALG_SHA1,str,strlen(str),(void*)&out);
if(len==0)
MessageBox(0,0,0,0);
char buffz[231] = "";
for(DWORD i = 0 ; i < len ; i++)
{
sprintf(buffz,"%s%2.2x",buffz,out[i]);
}
MessageBox(0,buffz,0,0);
return 0;
}
.Attachment: "win64_crypto_api_sha1_md5.zip"
There is no C included, only main topic files: main.asm, macros.asm, sha1.asm, main.obj, main.exe.
And that's it,
Encryptor256!