; _______________________________________________________________________________________
;| |
;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
;|_______________________________________________________________________________________|
;
; Description: OS independent MD5 library.
;
; Target OS: Any
;
; Dependencies: memory.asm
;
; Notes: The original code is from iblis. I changed it a bit, maybe losing performance,
; but making it more structured.
;
;_________________________________________________________________________________________
module "MD5 library"
struct TContextMD5
.__cntx rb 88
.value rb 16
ends
iglobal
if used ___MD5InternalData
___MD5InternalData db 0,1,1,5,5,3,0,7, \
7,5,5,5,5,4,5,6, \
4,7,5,7,6,4,5,6
end if
endg
uglobal
if used ___MD5SineTable
___MD5SineTable rd 65
end if
endg
if used md5_open
initialize ___md5_init
begin
xor eax, eax
finit
pushd 4F800000h
pushd 0
fstcw word [esp+2]
fstcw word [esp]
or word [esp], 0F3Fh
fldcw word [esp]
push 1
@@: fild dword [esp]
fsin
fabs
fmul dword [esp+8]
fistp qword [eax*4+___MD5SineTable]
inc dword [esp]
inc eax
test al, 40h
jz @b
fldcw word [esp+6]
add esp, 12
return
endp
end if
;******************************************************
; Computes MD5 hash of the data block from [.pData] with
; length in [.pLen]
; Returns new string handle in eax containing the hash of
; the data.
;******************************************************
proc DataMD5, .pData, .pLen
begin
push ebx esi edi
stdcall md5_open
mov ebx, eax
stdcall md5_read, ebx, [.pData], [.pLen]
stdcall md5_getvalue, ebx
stdcall StrNew
mov edi, eax
lea esi, [ebx+TContextMD5.value]
mov ecx, 16
.loop:
movzx eax, byte [esi]
inc esi
stdcall NumToStr, eax, ntsUnsigned or ntsHex or ntsFixedWidth + 2
push eax
stdcall StrCat, edi, eax
stdcall StrDel ; from the stack
loop .loop
stdcall StrLCase, edi
stdcall FreeMem, ebx
mov eax, edi
pop edi esi ebx
return
endp
;............................................................................
; md5_open is used to allocate and initialize TContextMD5 structure for use with
; subsequent processing.
;
; Arguments:
; no
;
; Return Value: EAX - pointer to the allocated TContextMD5 structure.
;
; Modifies Registers: EAX
;............................................................................
proc md5_open
begin
push edi
stdcall GetMem, sizeof.TContextMD5
mov edi, eax
push eax
mov al, 01h
@@: stosb
add al, 22h
jnc @b
mov al, 0FEh
@@: stosb
sub al, 22h
jnc @b
xor eax, eax
stosd
stosd
pop eax edi
return
endp
;............................................................................
; MD5_Read scans a block of data and updates the working context. Call it
; once on a single block of data, or call it multiple times on consecutive
; blocks of data, before retrieving the MD5 signature with MD5_Digest
;
; Arguments:
; lpMD5CTXT - address of an initialized MD5CTXT structure
; lpBuf - address of a contiguous block of data
; bufLen - the size, in bytes, of the block of data
;
; Return Value: None
;
; Modifies Registers: None
;............................................................................
proc md5_read ;, .lpMD5CTXT, .lpBuf, .bufLen
begin
pushad
mov esi, [esp+40]
mov ebp, [esp+36]
lea edi, [ebp+24]
mov edx, [esp+44]
mov ebx, edi
mov eax, edx
shl eax, 3
mov ecx, edx
shr ecx, 29
push dword [ebp+16]
add [ebp+16], eax
adc [ebp+20], ecx
pop eax
shr eax, 3
and eax, 3Fh
.mn: xor ecx, ecx
mov cl, 40h
sub ecx, eax
cmp ecx, edx
jbe @f
mov ecx, edx
@@: sub edx, ecx
add edi, eax
add eax, ecx
rep movsb
mov edi, ebx
cmp eax, 40h
jb @f
stdcall ___md5_BTrnsf, ebx, edi
@@: xor eax, eax
or edx, edx
jnz .mn
popad
ret 12
endp
;............................................................................
; md5_getvalue is used to retrieve the MD5 hash for the working context. It may
; be called at any point during a buffer read to get the current MD5 hash for
; all data scanned up to that point. It does not modify the contexutal data,
; so this procedure may be called as many times as needed.
; The value is stored in the context structure TContextMD5.value
;
; Arguments:
; .pContextMD5 - address of an TContextMD5 structure
;
; Return Value: None
;
; Modifies Registers: None
;............................................................................
proc md5_getvalue ;, .pContextMD5
begin
pushad
mov esi, dword [esp+36]
lea edi, [esi+TContextMD5.value]
lea ebp, [esi+16]
mov ebx, edi
sub esp, 64
movsd
movsd
movsd
movsd
lodsd
shr eax, 3
add esi, 4
and eax, 3Fh
mov edi, esp
mov ecx, eax
rep movsb
inc eax
sub ecx, eax
mov al, 80h
stosb
xor eax, eax
cmp ecx, -56
jae @f
xor eax, eax
add ecx, 64
rep stosb
mov edi, esp
stdcall ___md5_BTrnsf, ebx, edi
@@: xor eax, eax
add ecx, 56
rep stosb
mov esi, ebp
movsd
movsd
stdcall ___md5_BTrnsf, ebx, esp
add esp, 64
popad
ret 4
endp
proc ___md5_BTrnsf ;, .phash, .lpBlock
begin
pushad
mov eax, dword [esp+36]
xor ecx, ecx
mov cl, 4
@@: push dword [eax]
add eax, 4
loop @b
.mn: mov ebp, ecx
shr ebp, 12
add dl, dh
and dl, 0Fh
test ch, 03h
jnz @f
xor cl, cl
test ch, 0Fh
jnz @f
mov esi, ___MD5InternalData
mov edx, dword [esi+ebp*2]
mov ebx, dword [esi+ebp*4+8]
@@: add cl, bl
ror ebx, 8
push edx
push ecx
push ebx
mov ebx, dword [esp+20]
mov ecx, dword [esp+16]
mov edx, dword [esp+12]
test ebp, 02h
jnz .hi
test ebp, 01h
jnz @f
mov eax, ebx
and ebx, ecx
not eax
and eax, edx
or eax, ebx
jmp .fghi
@@: mov eax, edx
and edx, ebx
not eax
and eax, ecx
or eax, edx
jmp .fghi
.hi: test ebp, 01h
jnz @f
mov eax, ebx
xor eax, ecx
xor eax, edx
jmp .fghi
@@: mov eax, edx
not eax
or eax, ebx
xor eax, ecx
.fghi: pop ebx
pop ecx
pop edx
add eax, dword [esp+12]
mov esi, dword [esp+56]
movzx edi, dl
add eax, dword [esi+edi*4]
movzx esi, ch
add eax, dword [___MD5SineTable+esi*4]
rol eax, cl
add eax, dword [esp+8]
mov dword [esp+12], eax
mov esi, esp
mov edi, esp
lodsd
movsd
movsd
movsd
stosd
inc ch
test ch, 40h
jz .mn
mov eax, dword [esp+52]
xor ecx, ecx
mov cl, 4
sub eax, ecx
@@: pop edx
add dword [eax+ecx*4], edx
loop @b
popad
ret 8
endp
endmodule