Расчет хеша MD4 на Ассемблере

MD4 (Message Digest 4) - хеш-функция, разработанная профессором Рональдом Ривестом в 1990 году. Для произвольных входных данных функция MD4 генерирует 128-разрядный хеш. Функция MD4 является предшественником MD5 и до настоящего времени применяется в некоторых сетевых технологиях Windows. В реализации обоих алгоритмов очень много общего, поэтому точно так же в сегменте данных надо подготовить следующие массивы и переменные:
; Сегмент данных
section '.data' data readable writeable  
...
; Шаблоны функции wsprintf для перевода хеша в строковый вид,
; при необходимости можно оставить только какой-нибудь один
szMD4Format1 db '%.8X%.8X%.8X%.8X',0  ; Для получения заглавных букв
szMD4Format2 db '%.8x%.8x%.8x%.8x',0  ; Для маленьких букв в строке хеша
 
stMD4Result:
  stdtA      dd ?   ; Переменные для получения и хранения
  stdtB      dd ?   ; результата хеширования
  stdtC      dd ?
  stdtD      dd ?
 
stMD4Hash    rb 33  ; Буфер для строки хеша в формате ASCIIZ 

Основная и вспомогательные функции более простые и компактные, к тому же вспомогательных функций всего три, по количеству используемых раундов хеширования.
;-------------------------------------------------------
; Процедура расчета хеша MD4
; На входе:
; dta, dtb, dtc, dtd - начальные значения MD4, по умолчанию = 0
; ptBuffer - указатель на буфер от которого считается хеш
; dtBufferLength - длина буфера в байтах
; На выходе:
; Заполненные переменные stdtA, stdtB, stdtC, stdtD
;-------------------------------------------------------
proc    procMD4hash dta, dtb, dtc, dtd, ptBuffer, dtBufferLength
        push eax ebx ecx edx edi esi
 
        ; phase 1 - padding
        mov     edi,[ptBuffer]
        mov     eax,[dtBufferLength]
 
        inc     eax
        add     edi,eax
        mov     byte [edi-1],080h
 
        xor     edx,edx
 
        mov     ebx,64
        div     ebx
 
        neg     edx
        add     edx,64
 
        cmp     edx,8
        jae     @f
 
        add     edx,64
 
@@:
        mov     ecx,edx
        xor     al,al
        rep     stosb
 
        mov     eax,[dtBufferLength]
 
        inc     edx
        add     [dtBufferLength],edx
 
        xor     edx,edx
 
        mov     ebx,8
        mul     ebx
 
        mov     dword [edi-8],eax
        mov     dword [edi-4],edx
 
        mov     edx,[dtBufferLength]
 
        mov     edi,[ptBuffer]
 
        ; phase II - chaining variables initialization
 
        mov     [stdtA],067452301h
        mov     [stdtB],0efcdab89h
        mov     [stdtC],098badcfeh
        mov     [stdtD],010325476h
 
        ; phase III - hashing
hashloop:
        mov     eax,[stdtA]
        mov     [dta],eax
        mov     eax,[stdtB]
        mov     [dtb],eax
        mov     eax,[stdtC]
        mov     [dtc],eax
        mov     eax,[stdtD]
        mov     [dtd],eax
 
        ; round 1
        stdcall FF,[dta],[dtb],[dtc],[dtd],dword [edi+00*4],03
        mov     [dta],eax
        stdcall FF,[dtd],[dta],[dtb],[dtc],dword [edi+01*4],07
        mov     [dtd],eax
        stdcall FF,[dtc],[dtd],[dta],[dtb],dword [edi+02*4],11
        mov     [dtc],eax
        stdcall FF,[dtb],[dtc],[dtd],[dta],dword [edi+03*4],19
        mov     [dtb],eax
        stdcall FF,[dta],[dtb],[dtc],[dtd],dword [edi+04*4],03
        mov     [dta],eax
        stdcall FF,[dtd],[dta],[dtb],[dtc],dword [edi+05*4],07
        mov     [dtd],eax
        stdcall FF,[dtc],[dtd],[dta],[dtb],dword [edi+06*4],11
        mov     [dtc],eax
        stdcall FF,[dtb],[dtc],[dtd],[dta],dword [edi+07*4],19
        mov     [dtb],eax
        stdcall FF,[dta],[dtb],[dtc],[dtd],dword [edi+08*4],03
        mov     [dta],eax
        stdcall FF,[dtd],[dta],[dtb],[dtc],dword [edi+09*4],07
        mov     [dtd],eax
        stdcall FF,[dtc],[dtd],[dta],[dtb],dword [edi+10*4],11
        mov     [dtc],eax
        stdcall FF,[dtb],[dtc],[dtd],[dta],dword [edi+11*4],19
        mov     [dtb],eax
        stdcall FF,[dta],[dtb],[dtc],[dtd],dword [edi+12*4],03
        mov     [dta],eax
        stdcall FF,[dtd],[dta],[dtb],[dtc],dword [edi+13*4],07
        mov     [dtd],eax
        stdcall FF,[dtc],[dtd],[dta],[dtb],dword [edi+14*4],11
        mov     [dtc],eax
        stdcall FF,[dtb],[dtc],[dtd],[dta],dword [edi+15*4],19
        mov     [dtb],eax
 
        ; round 2
        stdcall GG,[dta],[dtb],[dtc],[dtd],dword [edi+00*4],03
        mov     [dta],eax
        stdcall GG,[dtd],[dta],[dtb],[dtc],dword [edi+04*4],05
        mov     [dtd],eax
        stdcall GG,[dtc],[dtd],[dta],[dtb],dword [edi+08*4],09
        mov     [dtc],eax
        stdcall GG,[dtb],[dtc],[dtd],[dta],dword [edi+12*4],13
        mov     [dtb],eax
        stdcall GG,[dta],[dtb],[dtc],[dtd],dword [edi+01*4],03
        mov     [dta],eax
        stdcall GG,[dtd],[dta],[dtb],[dtc],dword [edi+05*4],05
        mov     [dtd],eax
        stdcall GG,[dtc],[dtd],[dta],[dtb],dword [edi+09*4],09
        mov     [dtc],eax
        stdcall GG,[dtb],[dtc],[dtd],[dta],dword [edi+13*4],13
        mov     [dtb],eax
        stdcall GG,[dta],[dtb],[dtc],[dtd],dword [edi+02*4],03
        mov     [dta],eax
        stdcall GG,[dtd],[dta],[dtb],[dtc],dword [edi+06*4],05
        mov     [dtd],eax
        stdcall GG,[dtc],[dtd],[dta],[dtb],dword [edi+10*4],09
        mov     [dtc],eax
        stdcall GG,[dtb],[dtc],[dtd],[dta],dword [edi+14*4],13
        mov     [dtb],eax
        stdcall GG,[dta],[dtb],[dtc],[dtd],dword [edi+03*4],03
        mov     [dta],eax
        stdcall GG,[dtd],[dta],[dtb],[dtc],dword [edi+07*4],05
        mov     [dtd],eax
        stdcall GG,[dtc],[dtd],[dta],[dtb],dword [edi+11*4],09
        mov     [dtc],eax
        stdcall GG,[dtb],[dtc],[dtd],[dta],dword [edi+15*4],13
        mov     [dtb],eax
 
        ; round 3
        stdcall HH,[dta],[dtb],[dtc],[dtd],dword [edi+00*4],03
        mov     [dta],eax
        stdcall HH,[dtd],[dta],[dtb],[dtc],dword [edi+08*4],09
        mov     [dtd],eax
        stdcall HH,[dtc],[dtd],[dta],[dtb],dword [edi+04*4],11
        mov     [dtc],eax
        stdcall HH,[dtb],[dtc],[dtd],[dta],dword [edi+12*4],15
        mov     [dtb],eax
        stdcall HH,[dta],[dtb],[dtc],[dtd],dword [edi+02*4],03
        mov     [dta],eax
        stdcall HH,[dtd],[dta],[dtb],[dtc],dword [edi+10*4],09
        mov     [dtd],eax
        stdcall HH,[dtc],[dtd],[dta],[dtb],dword [edi+06*4],11
        mov     [dtc],eax
        stdcall HH,[dtb],[dtc],[dtd],[dta],dword [edi+14*4],15
        mov     [dtb],eax
        stdcall HH,[dta],[dtb],[dtc],[dtd],dword [edi+01*4],03
        mov     [dta],eax
        stdcall HH,[dtd],[dta],[dtb],[dtc],dword [edi+09*4],09
        mov     [dtd],eax
        stdcall HH,[dtc],[dtd],[dta],[dtb],dword [edi+05*4],11
        mov     [dtc],eax
        stdcall HH,[dtb],[dtc],[dtd],[dta],dword [edi+13*4],15
        mov     [dtb],eax
        stdcall HH,[dta],[dtb],[dtc],[dtd],dword [edi+03*4],03
        mov     [dta],eax
        stdcall HH,[dtd],[dta],[dtb],[dtc],dword [edi+11*4],09
        mov     [dtd],eax
        stdcall HH,[dtc],[dtd],[dta],[dtb],dword [edi+07*4],11
        mov     [dtc],eax
        stdcall HH,[dtb],[dtc],[dtd],[dta],dword [edi+15*4],15
        mov     [dtb],eax
 
        mov     eax,[dta]
        add     [stdtA],eax
        mov     eax,[dtb]
        add     [stdtB],eax
        mov     eax,[dtc]
        add     [stdtC],eax
        mov     eax,[dtd]
        add     [stdtD],eax
 
        add     edi,64
 
        sub     edx,64
        jnz     hashloop
 
        ; phase IV - results
 
        mov     ecx,4
        mov     esi,stMD4Result
@@:
        mov     eax,dword [esi]
        xchg    al,ah
        rol     eax,16
        xchg    al,ah
        mov     dword [esi],eax
 
        add     esi,4
 
        loop    @b
 
        pop  esi edi edx ecx ebx eax
 
        ret
endp
 
; a = (a + F(b,c,d) + X[k]) <<< s
proc    FF var1,var2,var3,var4,k,s
        push    ebx ecx
 
        mov     eax,[var2]
        and     eax,[var3]
        mov     ebx,[var2]
        not     ebx
        and     ebx,[var4]
        or      eax,ebx
 
        add     eax,[k]
        add     eax,[var1]
 
        mov     ecx,[s]
        rol     eax,cl
 
        pop     ecx ebx
        ret
endp
 
;a = (a + G(b,c,d) + X[k] + 5A827999) <<< s
proc    GG var1,var2,var3,var4,k,s
        push    ebx ecx
 
        mov     eax,[var2]
        mov     ebx,[var3]
        or      ebx,[var4]
        and     eax,ebx
        mov     ebx,[var3]
        and     ebx,[var4]
        or      eax,ebx
 
        add     eax,5A827999h
        add     eax,[k]
        add     eax,[var1]
 
        mov     ecx,[s]
        rol     eax,cl
 
        pop     ecx ebx
        ret
endp
 
; a = (a + H(b,c,d) + X[k] + 6ED9EBA1) <<< s
proc    HH var1,var2,var3,var4,k,s
        push    ecx
 
        mov     eax,[var2]
        xor     eax,[var3]
        xor     eax,[var4]
 
        add     eax,6ED9EBA1h
        add     eax,[k]
        add     eax,[var1]
 
        mov     ecx,[s]
        rol     eax,cl
 
        pop     ecx
        ret
endp

Для накопительного расчета при каждом следующем вызове начальные значения MD4 должны быть проинициализированы результатами предыдущего расчета. Пример использования для одиночной стоки (блока данных):
; Сегмент данных
section '.data' data readable writeable  
...
somedata db 'Yeah! I like Flat Assembler!',0 ; Исходные данные для хеширования
 
; Сегмент кода
section '.code' code readable executable
        ...
        ; Расчет длины строки. Для бинарных данных lstrlen лучше не использовать
        invoke  lstrlen,somedata
        ; Расчет MD4
        stdcall procMD4hash,0,0,0,0,somedata,eax
        ; Перевод в строку, буквы заглавные
        invoke  wsprintf,stMD4Hash,szMD4Format1,[stdtA],[stdtB],[stdtC],[stdtD]
        ...

После выполнения приведенного пример в текстовом буфере stMD4Hash будет строка хеша MD4 "87BBCCB2145ACDE7272EA8EDF7184920" в формате ASCIIZ.

Первые уязвимости алгоритма и коллизии были найдены уже через год после его опубликования, но MD4 создавался прежде всего как очень быстрый алгоритм хеширования, поэтому он не является достаточно хорошим в плане криптостойкости. В приложении пример программы с исходным текстом, считающей хеш MD4 от введенной строки.
Теги:
хеш, md4, Message Digest
Добавлено: 15 Сентября 2013 02:22:58 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...