Algorytm hashujący MD5
Transkrypt
Algorytm hashujący MD5
Autorzy: Marcin Jabłonowski Waldemar Łokieć Prowadzący: dr inż. Paweł Tomaszewicz Algorytm hashujący MD5 Realizacja w postaci układu programowalnego Środowisko pracy: MAX+plus II 10.2 BASELINE Język opisu sprzętu: AHDL Docelowa rodzina układów: FLEX10K Współpracuje z płytką laboratoryjną Instytutu Telekomunikacji WEiTI PW. Algorytm MD5 pełni funkcję jednokierunkowej funkcji skrótu, przekształcającym komunikat o dowolnej długości w 128-bitowy klucz, który jest unikatowy dla tego komunikatu. Prawdopodobieństwo otrzymania takiego samego klucza dla różnych danych jest nikłe. Stosowany jest on między innymi w kryptografii, weryfikowania integralności i poprawności danych. Opis algorytmu w języku polskim można znaleźć pod adresem: http://www.issi.uz.zgora.pl/pl/didactic/md5.pdf Strona domowa algorytmu (wraz z linkiem do RFC), zawierająca m.in. programy ze źródłami, znajduje się w tym miejscu: http://userpages.umbc.edu/~mabzug1/cs/md5/md5.html Nomenklaturę i nazwy zmiennych zaczerpnęliśmy z w/w dokumentu w języku polskim. Opis układu Schemat blokowy układu pokazuje rys. 1. clk clk rxf rxf txe txe k out rd rd wr wr data bufor Xin runda hash next ready ready start init init outclk clk Zasadnicza część składa się z dwóch modułów: bufora i rundy. Bufor odpowiada za obsługę transmisji z kontrolera USB i buforowanie danych, a runda oblicza skrót dla danego bloku danych. Opis modułów • Md5 (md5.tdf) Wejścia: ! clk - wejście zegarowe ! rxf – sygnalizuje, że w buforze są dane do odbioru (0 – tak, 1 – nie) ! txe – jeśli 0 to można wysyłać dane, jeśli 1 – nie Wyjścia: ! rd - odczytanie i zdjęcie danej z bufora WE; 0->1 ! wr - wysłanie danej zmianą sygnału 1->0 Szyna dwukierunkowa: ! data[7..0] – dane do transmisji • Bufor (bufor.tdf) Bufor odbiera dane z kontrolera USB, którego opis i przykłady wykorzystania można znaleźć na stronie prowadzącego: http://wwwzpt.tele.pw.edu.pl/~ptomasze/ucyf/ucyf_proj.htm. Ponieważ nie znamy z góry rozmiaru przychodzących danych, dlatego odbiór kończymy w momencie zmiany wejścia txe na 0 (bufor czeka na wychodzące dane). Dane buforujemy w 512-bitowych blokach, które (jak to jest opisane w algorytmie) dzielimy na 16 32-bitowych bloków. Na wyjściu potrzebujemy 32-bitów, dlatego dane zapisujemy w 4 komórkach EAB z wejściami 8-bitowymi, i wyjście out[] jest połączeniem wszystkich czterech wyjść. Rozmiar danych (ilość bitów przesłanych) dołączamy w odwrotnej kolejności bajtów (czyli najpierw najmniej znaczący). Wejścia: clk, rxf, txe, rd, wr i data jak w md5 ! ! ! next – sygnalizuje, że można odebrać następną porcję danych. k[3..0] – indeks 32-bitowego bloku danych z 512-bitowego komunikatu hash[127..0] – obliczony skrót Wyjścia: ! ! ! ! ready – skończyliśmy buforować 512-bitów (gdy 1) init – inicjalizacja algorytmu (gdy 1) outclk – zegar do rundy out[31..0] – 32-bitowe słowo o indeksie k (X[k]) Elementy: ! ! ! ! ! ! ! ! ! ! divclk[] – dzielnik zegara r, w – synchronizowane wyjścia do rd i wr counter[] – licznik do bufora size[] – licznik rozmiaru przychodzących danych iobuffer[] – przekaźnik WE/WY do dwukierunkowej szyny data[] oe – output enable do iobuffer[] buffcontrol – steruje buforami RAM, decyduje gdzie zapisać dane i ustala adresy, które są jednocześnie indeksami k. mult – multiplekser danych do buffcontrol (oprócz data[] bity uzupełniające i rozmiar) multsend – multiplekser danych do wysłania (wejściami są odpowiednie bajty hash[]) rcv – automat sterujący odbiorem i wysyłanie danych stan init idle read1, read2 append1 append2 appendsize endrcv send1, send2 działanie inicjalizacja układu, nadanie początkowych wartości rejestrom A, B, C, D oczekiwanie na pierwszy bajt odczyt danej z bufora początkowe uzupełnienie komunikatu (ciągiem B”10000000”) uzupełnienie ciągiem B”00000000” uzupełnienie komunikatu rozmiarem skończyliśmy odbierać dane wysyłanie danych • Runda (runda.tdf) Moduł ten odpowiada za realizację kroku 4. algorytmu hashującego. Schemat blokowy przedstawia rysunek na następnej stronie. Wejścia: ! clk – zegar ! start – wystartuj przetwarzanie ! init – zainicjalizuj wartości rejestrów A, B, C, D ! Xin[] – wejście X[k] Wyjścia: ! ready – skończyliśmy przetwarzanie (gdy 1) ! k[] – indeks do X[k] ! hash[] – obliczony skrót clk start stop ready sterownik Ti decq sout k muxq A B C D ain bin cin din decq Jedna runda kroku 4. algorytmu MD5 dekoder a b c bin cin din muxq combosfghi decq FGHI clk Ti Xk Ti FGHI a funkcja_glowna b sout s result dekoder2 Xk ain A bin B cin C din D Elementy: ! dekoder – pozwala wybrać, wartości których rejestrów są podawane na wejście bloku liczącego funkcje F, G, H, I, według zależności decq -> b c d 0 -> bin cin din 1 -> ain bin cin 2 -> din ain bin 3 -> cin din ain ! combosfghi – liczy funkcję F, G, H, I od bin, cin, din w zależności od muxq: 0-> F, 1 -> G, 2 -> H, 3 -> I ! funkcja_glowna – realizuje główną funkcję algorytmu opisaną wzorem: [abcd k s i] <=> a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). ! dekoder2 – decyduje o tym, które rejestry podawane są na wejście funkcji_glownej decq -> a b 0 -> ain bin 1 -> din ain 2 -> cin din 3 -> bin cin ! dekrej – dekoder rejestrów, który kontroluje zapis odpowiednich danych do rejestrów w danym kroku rundy poprzez ustawianie odpowiedniego sel[] na multiplekserach do rejestrów Pierwszym krokiem tego algorytmu jest zainicjalizowanie wartości rejestrów A, B, C, D odpowiednimi wartościami podanymi w kroku 3. w dokumentacji. Trzeba zwrócić uwagę, że podane tam wartości zaczynają się od najmniej znaczącego bajtu, dlatego też trzeba zamienić kolejność bajtów do ich inicjalizacji w naszym algorytmie. Doprowadzenie i sterowanie rejestrami ilustruje rysunek (schemat dla pozostałych rejestrów powtarza się): A + AA H"67452301" decq A 0 sel[3] sel result 1 2 rejmux[3] init sel[2] ready dekrej sel[1] stop sel[0] clk A 3 Całością rundy steruje sterownik • Sterownik (sterownik.tdf) Jest to automat, który kontroluje przebieg liczenia rundy dla danej wiadomości. Opisany jest przez: Wejścia: ! clk – zegar ! start – wystartowanie algorytmu (gdy 1) Wyjścia: ! decq[] – wyjście sterujące dekoderami ! muxq[] – steruje wyborem funkcji FGHI ! k[] – indeks do X[k] ! sout[] – wartość przesunięcia s ! T[] – odpowiednia wartość z tablicy T[i] ! stop – sygnalizuje, że algorytm skończył działanie ! ready – automat gotowy do nowych obliczeń (gdy 1) Elementy: ! ster - automat sterujący o stanach: stan działanie init stan gotowości i oczekiwania na wystartowanie obliczeń; zaczynają się one, gdy start przyjmie wartość 1 s0...s63 kolejne kroki obliczeń stop sygnalizuje koniec obliczeń i w następnym takcie zegara przechodzi do stanu gotowości (init)