Commit 7b618068 authored by Dererk's avatar Dererk

New upstream version 5.1.4

parents
hcxpsktool
hcxhashcattool
hcxhash2cap
wlanhc2hcx
wlanwkp2hcx
wlanhcxinfo
wlanhcx2essid
wlanhcx2ssid
wlanhcxmnc
wlanhashhcx
wlanhcxcat
wlanpmk2hcx
wlanjohn2hcx
wlancow2hcxpmk
whoismac
wlanhcx2john
wlancap2wpasec
dist: trusty
sudo: false
cache:
ccache: true
language: none
matrix:
include:
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-5
- ccache
- make
- libcurl4-gnutls-dev
env:
- MATRIX_EVAL="CC=gcc-5"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-6
- ccache
- make
- libcurl4-gnutls-dev
env:
- MATRIX_EVAL="CC=gcc-6"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-7
- ccache
- make
- libcurl4-gnutls-dev
env:
- MATRIX_EVAL="CC=gcc-7 DO_INSTALL=1"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
packages:
- clang-4.0
- ccache
- make
- libcurl4-gnutls-dev
env:
- MATRIX_EVAL="CC=clang-4.0"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
packages:
- clang-5.0
- ccache
- make
- libcurl4-gnutls-dev
env:
- MATRIX_EVAL="CC=clang-5.0"
- os: linux
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty
packages:
- clang
- ccache
- make
- libcurl4-gnutls-dev
env:
- MATRIX_EVAL="CC=clang"
before_install:
- eval "${MATRIX_EVAL}"
- export "CC=ccache $CC"
script:
- "make"
PREFIX ?=/usr/local
INSTALLDIR = $(DESTDIR)$(PREFIX)/bin
HOSTOS := $(shell uname -s)
CC ?= gcc
CFLAGS ?= -O3 -Wall -Wextra
CFLAGS += -std=gnu99
INSTFLAGS = -m 0755
ifeq ($(HOSTOS), Linux)
INSTFLAGS += -D
endif
ifeq ($(HOSTOS), Darwin)
CFLAGS += -L/usr/local/opt/openssl/lib -I/usr/local/opt/openssl/include
endif
TOOLS=
TOOLS+=hcxpcaptool
hcxpcaptool_libs=-lz -lcrypto
TOOLS+=hcxpsktool
hcxpsktool_libs=-lcrypto
TOOLS+=hcxhashcattool
hcxhashcattool_libs=-lcrypto -lpthread
TOOLS+=hcxwltool
TOOLS+=hcxhash2cap
TOOLS+=wlanhc2hcx
TOOLS+=wlanwkp2hcx
TOOLS+=wlanhcxinfo
TOOLS+=wlanhcx2essid
TOOLS+=wlanhcx2ssid
TOOLS+=wlanhcxmnc
TOOLS+=wlanhashhcx
TOOLS+=wlanhcxcat
wlanhcxcat_libs=-lcrypto
TOOLS+=wlanpmk2hcx
wlanpmk2hcx_libs=-lcrypto
TOOLS+=wlanjohn2hcx
TOOLS+=wlancow2hcxpmk
TOOLS+=whoismac
whoismac_libs=-lcurl
TOOLS+=wlanhcx2john
TOOLS+=wlancap2wpasec
wlancap2wpasec_libs=-lcurl
.PHONY: build
build: $(TOOLS)
.deps:
mkdir -p .deps
# $1: tool name
define tool-build
$(1)_src ?= $(1).c
$(1)_libs ?=
$(1): $$($(1)_src) | .deps
$$(CC) $$(CFLAGS) $$(CPPFLAGS) -MMD -MF .deps/$$@.d -o $$@ $$($(1)_src) $$($(1)_libs) $$(LDFLAGS)
.deps/$(1).d: $(1)
.PHONY: $(1).install
$(1).install: $(1)
install $$(INSTFLAGS) $(1) $$(INSTALLDIR)/$(1)
.PHONY: $(1).clean
$(1).clean:
rm -f .deps/$(1).d
rm -f $(1)
.PHONY: $(1).uninstall
$(1).uninstall:
rm -rf $$(INSTALLDIR)/$(1)
endef
$(foreach tool,$(TOOLS),$(eval $(call tool-build,$(tool))))
.PHONY: install
install: $(patsubst %,%.install,$(TOOLS))
.PHONY: clean
clean: $(patsubst %,%.clean,$(TOOLS))
rm -rf .deps
.PHONY: uninstall
uninstall: $(patsubst %,%.uninstall,$(TOOLS))
-include .deps/*.d
hcxtools
==============
Small set of tools convert packets from captures (h = hash, c = capture, convert and
calculate candidates, x = different hashtypes) for the use with latest hashcat
or John the Ripper. The tools are 100% compatible to hashcat and John the Ripper
and recommended by hashcat. This branch is pretty closely synced to hashcat git branch
(that means: latest hcxtools matching on latest hashcat beta) and John the Ripper
git branch ("bleeding-jumbo").
Support for hashcat hash-modes: 2500, 2501, 4800, 5500, 12000, 16100, 16800, 16801
Support for John the Ripper hash-modes: WPAPSK-PMK, PBKDF2-HMAC-SHA1, chap, netntlm, tacacs-plus
After capturing, upload the "uncleaned" cap here (https://wpa-sec.stanev.org/?submit)
to see if your ap or the client is vulnerable by using common wordlists.
Convert the cap to hccapx and/or to WPA-PMKID-PBKDF2 hashline (16800) and check if wlan-key
or plainmasterkey was transmitted unencrypted.
Brief description
--------------
Multiple stand-alone binaries - designed to run on Arch Linux.
All of these utils are designed to execute only one specific function.
hcxdumptool moved to: https://github.com/ZerBea/hcxdumptool
Read this post: hcxtools - solution for capturing wlan traffic and conversion to hashcat formats (https://hashcat.net/forum/thread-6661.html)
Detailed description
--------------
| Tool | Description |
| -------------- | ----------------------------------------------------------------------------------------------------------------- |
| hcxpcaptool | Shows info of pcap/pcapng file and convert it to other hashformats accepted by hashcat and John the Ripper |
| hcxpsktool | Calculates candidates for hashcat and john based on based on hcxpcaptool output (-o, -z- -U) or commandline input |
| hcxwltool | Calculates candidates for hashcat and john based on hcxpcaptool output (-E, -I- -U) |
| hcxhash2cap | Converts hash file (PMKID, EAPOL-hccapx, EAPOL-hccap, WPAPSK-john) to cap |
| hcxhashcattool | Calculate PMKs from hashcat -m 2500 potfile |
| wlanhc2hcx | Converts hccap to hccapx |
| wlanwkp2hcx | Converts wpk (ELMCOMSOFT EWSA projectfile) to hccapx |
| wlanhcx2essid | Merges hccapx containing the same ESSID |
| wlanhcx2ssid | Strips BSSID, ESSID, OUI |
| wlanhcxinfo | Shows detailed info from contents of hccapxfile |
| wlanhcxmnc | Help to calculate hashcat's nonce-error-corrections value on byte number xx of an anonce |
| wlanhashhcx | Generate hashlist from hccapx hashfile (md5_64 hash:mac_ap:mac_sta:essid) |
| wlanhcxcat | Simple password recovery tool for WPA/WPA2/WPA2 SHA256 AES-128-CMAC (hash-modes 2500, 2501) |
| wlanpmk2hcx | Converts plainmasterkey and ESSID for use with hashcat hash-mode 12000 or john PBKDF2-HMAC-SHA1 |
| wlanjohn2hcx | Converts john wpapsk hashfiles for use with hashcat hash-modes 2500, 2501 |
| wlancow2hcxpmk | Converts pre-computed cowpatty hashfiles for use with hashcat hash-mode 2501 |
| wlanhcx2john | Converts hccapx to format expected by John the Ripper |
| wlancap2wpasec | Upload multiple caps to https://wpa-sec.stanev.org |
| whoismac | Show vendor information and/or download oui reference list |
Compile
--------------
Simply run:
```
make
make install (as super user)
```
Requirements
--------------
* Linux (recommended Arch Linux, but other distros should work, too (no support for other distributions).
* libopenssl and openssl-dev installed
* librt and librt-dev installed (should be installed by default)
* zlib and zlib-dev installed (for gzip compressed cap/pcap/pcapng files)
* libcurl and curl-dev installed (used by whoismac and wlancap2wpasec)
* libpthread and pthread-dev installed (used by hcxhashcattool)
To install requirements on Kali use the following 'apt-get install libcurl4-openssl-dev libssl-dev zlib1g-dev'
Useful scripts
--------------
| Script | Description |
| ------------ | -------------------------------------------------------- |
| piwritecard | Example script to restore SD-Card |
| piwreadcard | Example script to backup SD-Card |
Notice
--------------
Most output files will be appended to existing files (with the exception of .cap files).
Bitmask message pair field (hcxpcaptool)
--------------
0: MP info (https://hashcat.net/wiki/doku.php?id=hccapx#message_pair_table)
1: MP info (https://hashcat.net/wiki/doku.php?id=hccapx#message_pair_table)
2: MP info (https://hashcat.net/wiki/doku.php?id=hccapx#message_pair_table)
3: x unused
4: ap-less attack (set to 1) - no nonce-error-corrections neccessary
5: LE router detected (set to 1) - nonce-error-corrections only for LE neccessary
6: BE router detected (set to 1) - nonce-error-corrections only for BE neccessary
7: not replaycount checked (set to 1) - replaycount not checked, nonce-error-corrections definitely neccessary
This diff is collapsed.
int omac1_aes_128(const uint8_t *key, const uint8_t *data, size_t data_len, uint8_t *mac);
/*===========================================================================*/
static int omac1_aes_128_vector(const uint8_t *key, size_t num_elem, const uint8_t *addr[], const size_t *len, uint8_t *mac)
{
CMAC_CTX *ctx;
int ret = -1;
size_t outlen, i;
ctx = CMAC_CTX_new();
if (ctx == NULL)
return -1;
if (!CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL))
goto fail;
for (i = 0; i < num_elem; i++) {
if (!CMAC_Update(ctx, addr[i], len[i]))
goto fail;
}
if (!CMAC_Final(ctx, mac, &outlen) || outlen != 16)
goto fail;
ret = 0;
fail:
CMAC_CTX_free(ctx);
return ret;
}
/*===========================================================================*/
int omac1_aes_128(const uint8_t *key, const uint8_t *data, size_t data_len, uint8_t *mac)
{
return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
}
/*===========================================================================*/
void generatepkeprf(hcx_t *hcxrecord, uint8_t *pke_ptr);
void generatepke(hcx_t *hcxrecord, uint8_t *pke_ptr);
bool showhashrecord(hcx_t *hcxrecord, uint8_t *password, int pwlen, char *out);
/*===========================================================================*/
void generatepkeprf(hcx_t *hcxrecord, uint8_t *pke_ptr)
{
memcpy(pke_ptr, "Pairwise key expansion", 22);
if(memcmp(hcxrecord->mac_ap.addr, hcxrecord->mac_sta.addr, 6) < 0)
{
memcpy(pke_ptr + 22, hcxrecord->mac_ap.addr, 6);
memcpy(pke_ptr + 28, hcxrecord->mac_sta.addr, 6);
}
else
{
memcpy(pke_ptr + 22, hcxrecord->mac_sta.addr, 6);
memcpy(pke_ptr + 28, hcxrecord->mac_ap.addr, 6);
}
if(memcmp(hcxrecord->nonce_ap, hcxrecord->nonce_sta, 32) < 0)
{
memcpy (pke_ptr + 34, hcxrecord->nonce_ap, 32);
memcpy (pke_ptr + 66, hcxrecord->nonce_sta, 32);
}
else
{
memcpy (pke_ptr + 34, hcxrecord->nonce_sta, 32);
memcpy (pke_ptr + 66, hcxrecord->nonce_ap, 32);
}
return;
}
/*===========================================================================*/
void generatepke(hcx_t *hcxrecord, uint8_t *pke_ptr)
{
memcpy(pke_ptr, "Pairwise key expansion", 23);
if(memcmp(hcxrecord->mac_ap.addr, hcxrecord->mac_sta.addr, 6) < 0)
{
memcpy(pke_ptr + 23, hcxrecord->mac_ap.addr, 6);
memcpy(pke_ptr + 29, hcxrecord->mac_sta.addr, 6);
}
else
{
memcpy(pke_ptr + 23, hcxrecord->mac_sta.addr, 6);
memcpy(pke_ptr + 29, hcxrecord->mac_ap.addr, 6);
}
if(memcmp(hcxrecord->nonce_ap, hcxrecord->nonce_sta, 32) < 0)
{
memcpy (pke_ptr + 35, hcxrecord->nonce_ap, 32);
memcpy (pke_ptr + 67, hcxrecord->nonce_sta, 32);
}
else
{
memcpy (pke_ptr + 35, hcxrecord->nonce_sta, 32);
memcpy (pke_ptr + 67, hcxrecord->nonce_ap, 32);
}
return;
}
/*===========================================================================*/
bool showhashrecord(hcx_t *hcxrecord, uint8_t *password, int pwlen, char *out)
{
int i;
hcxhrc_t hashrec;
uint32_t hash[4];
uint32_t block[16];
uint8_t *block_ptr = (uint8_t*)block;
uint8_t *pke_ptr = (uint8_t*)hashrec.pke;
uint8_t *eapol_ptr = (uint8_t*)hashrec.eapol;
char pwstr[256];
char essidstr[256];
if(hcxrecord->essid_len > 32)
return false;
if(pwlen > 64)
return false;
hash[0] = 0;
hash[1] = 1;
hash[2] = 2;
hash[3] = 3;
memset(&block, 0, sizeof(block));
memset(&hashrec, 0, sizeof(hashrec));
memcpy(&hashrec.salt_buf, hcxrecord->essid, hcxrecord->essid_len);
if(((hcxrecord->keyver & 0x3) == 1) || ((hcxrecord->keyver & 0x3) == 2))
{
generatepke(hcxrecord, pke_ptr);
}
else if((hcxrecord->keyver & 0x3) == 3)
{
pke_ptr[0] = 1;
pke_ptr[1] = 0;
pke_ptr[100] = 0x80;
pke_ptr[101] = 1;
generatepkeprf(hcxrecord, pke_ptr +2);
}
else
{
return false;
}
for (i = 0; i < 32; i++)
{
hashrec.pke[i] = byte_swap_32(hashrec.pke[i]);
}
memcpy(eapol_ptr, hcxrecord->eapol, hcxrecord->eapol_len);
memset(eapol_ptr + hcxrecord->eapol_len, 0, (256 +64) -hcxrecord->eapol_len);
eapol_ptr[hcxrecord->eapol_len] = 0x80;
memcpy (&hashrec.keymic, hcxrecord->keymic, 16);
if(hcxrecord->keyver == 1)
{
// nothing to do
}
else if(hcxrecord->keyver == 2)
{
hashrec.keymic[0] = byte_swap_32(hashrec.keymic[0]);
hashrec.keymic[1] = byte_swap_32(hashrec.keymic[1]);
hashrec.keymic[2] = byte_swap_32(hashrec.keymic[2]);
hashrec.keymic[3] = byte_swap_32(hashrec.keymic[3]);
for(i = 0; i < 64; i++)
{
hashrec.eapol[i] = byte_swap_32 (hashrec.eapol[i]);
}
}
else if (hcxrecord->keyver == 3)
{
// nothing to do
}
for(i = 0; i < 16; i++)
block[i] = hashrec.salt_buf[i];
md5_64(block, hash);
for(i = 0; i < 16; i++)
block[i] = hashrec.pke[i +0];
md5_64(block, hash);
for(i = 0; i < 16; i++)
block[i] = hashrec.pke[i +16];
md5_64(block, hash);
for(i = 0; i < 16; i++)
block[i] = hashrec.eapol[i +0];
md5_64 (block, hash);
for(i = 0; i < 16; i++)
block[i] = hashrec.eapol[i +16];
md5_64 (block, hash);
for(i = 0; i < 16; i++)
block[i] = hashrec.eapol[i +32];
md5_64 (block, hash);
for(i = 0; i < 16; i++)
block[i] = hashrec.eapol[i + 48];
md5_64 (block, hash);
for(i = 0; i < 6; i++)
block_ptr[i +0] = hcxrecord->mac_ap.addr[i];
for(i = 0; i < 6; i++)
block_ptr[i +6] = hcxrecord->mac_sta.addr[i];
md5_64 (block, hash);
for(i = 0; i < 32; i++)
block_ptr[i +0] = hcxrecord->nonce_ap[i];
for(i = 0; i < 32; i++)
block_ptr[i +32] = hcxrecord->nonce_sta[i];
md5_64 (block, hash);
block[0] = hashrec.keymic[0];
block[1] = hashrec.keymic[1];
block[2] = hashrec.keymic[2];
block[3] = hashrec.keymic[3];
md5_64 (block, hash);
memset(out, 0, 1024);
memset(&pwstr, 0, 256);
memset(&essidstr, 0, 256);
if(need_hexify(hcxrecord->essid, hcxrecord->essid_len) == true)
{
do_full_hexify(hcxrecord->essid, hcxrecord->essid_len, (uint8_t*)essidstr);
}
else
{
memcpy(&essidstr, hcxrecord->essid, hcxrecord->essid_len);
}
if((pwlen > 0) && (pwlen < 65))
{
if(need_hexify(password, pwlen) == true)
{
do_full_hexify(password, pwlen, (uint8_t*)pwstr);
}
else
{
memcpy(&pwstr, password, pwlen);
}
sprintf(out, "%08x%08x%08x%08x:%02x%02x%02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x:%s:%s",
hash[0], hash[1], hash[2], hash[3],
hcxrecord->mac_ap.addr[0], hcxrecord->mac_ap.addr[1], hcxrecord->mac_ap.addr[2], hcxrecord->mac_ap.addr[3], hcxrecord->mac_ap.addr[4], hcxrecord->mac_ap.addr[5],
hcxrecord->mac_sta.addr[0], hcxrecord->mac_sta.addr[1], hcxrecord->mac_sta.addr[2], hcxrecord->mac_sta.addr[3], hcxrecord->mac_sta.addr[4], hcxrecord->mac_sta.addr[5],
essidstr, pwstr);
}
else
{
sprintf(out, "%08x%08x%08x%08x:%02x%02x%02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x:%s",
hash[0], hash[1], hash[2], hash[3],
hcxrecord->mac_ap.addr[0], hcxrecord->mac_ap.addr[1], hcxrecord->mac_ap.addr[2], hcxrecord->mac_ap.addr[3], hcxrecord->mac_ap.addr[4], hcxrecord->mac_ap.addr[5],
hcxrecord->mac_sta.addr[0], hcxrecord->mac_sta.addr[1], hcxrecord->mac_sta.addr[2], hcxrecord->mac_sta.addr[3], hcxrecord->mac_sta.addr[4], hcxrecord->mac_sta.addr[5],
essidstr);
}
return true;
}
#include "com_md5_64.h"
/*===========================================================================*/
void md5_64 (uint32_t block[16], uint32_t digest[4])
{
uint32_t w0[4];
uint32_t w1[4];
uint32_t w2[4];
uint32_t w3[4];
w0[0] = block[ 0];
w0[1] = block[ 1];
w0[2] = block[ 2];
w0[3] = block[ 3];
w1[0] = block[ 4];
w1[1] = block[ 5];
w1[2] = block[ 6];
w1[3] = block[ 7];
w2[0] = block[ 8];
w2[1] = block[ 9];
w2[2] = block[10];
w2[3] = block[11];
w3[0] = block[12];
w3[1] = block[13];
w3[2] = block[14];
w3[3] = block[15];
uint32_t a = digest[0];
uint32_t b = digest[1];
uint32_t c = digest[2];
uint32_t d = digest[3];
MD5_STEP (MD5_Fo, a, b, c, d, w0[0], MD5C00, MD5S00);
MD5_STEP (MD5_Fo, d, a, b, c, w0[1], MD5C01, MD5S01);
MD5_STEP (MD5_Fo, c, d, a, b, w0[2], MD5C02, MD5S02);
MD5_STEP (MD5_Fo, b, c, d, a, w0[3], MD5C03, MD5S03);
MD5_STEP (MD5_Fo, a, b, c, d, w1[0], MD5C04, MD5S00);
MD5_STEP (MD5_Fo, d, a, b, c, w1[1], MD5C05, MD5S01);
MD5_STEP (MD5_Fo, c, d, a, b, w1[2], MD5C06, MD5S02);
MD5_STEP (MD5_Fo, b, c, d, a, w1[3], MD5C07, MD5S03);
MD5_STEP (MD5_Fo, a, b, c, d, w2[0], MD5C08, MD5S00);
MD5_STEP (MD5_Fo, d, a, b, c, w2[1], MD5C09, MD5S01);
MD5_STEP (MD5_Fo, c, d, a, b, w2[2], MD5C0a, MD5S02);
MD5_STEP (MD5_Fo, b, c, d, a, w2[3], MD5C0b, MD5S03);
MD5_STEP (MD5_Fo, a, b, c, d, w3[0], MD5C0c, MD5S00);
MD5_STEP (MD5_Fo, d, a, b, c, w3[1], MD5C0d, MD5S01);
MD5_STEP (MD5_Fo, c, d, a, b, w3[2], MD5C0e, MD5S02);
MD5_STEP (MD5_Fo, b, c, d, a, w3[3], MD5C0f, MD5S03);
MD5_STEP (MD5_Go, a, b, c, d, w0[1], MD5C10, MD5S10);
MD5_STEP (MD5_Go, d, a, b, c, w1[2], MD5C11, MD5S11);
MD5_STEP (MD5_Go, c, d, a, b, w2[3], MD5C12, MD5S12);
MD5_STEP (MD5_Go, b, c, d, a, w0[0], MD5C13, MD5S13);
MD5_STEP (MD5_Go, a, b, c, d, w1[1], MD5C14, MD5S10);
MD5_STEP (MD5_Go, d, a, b, c, w2[2], MD5C15, MD5S11);
MD5_STEP (MD5_Go, c, d, a, b, w3[3], MD5C16, MD5S12);
MD5_STEP (MD5_Go, b, c, d, a, w1[0], MD5C17, MD5S13);
MD5_STEP (MD5_Go, a, b, c, d, w2[1], MD5C18, MD5S10);
MD5_STEP (MD5_Go, d, a, b, c, w3[2], MD5C19, MD5S11);
MD5_STEP (MD5_Go, c, d, a, b, w0[3], MD5C1a, MD5S12);
MD5_STEP (MD5_Go, b, c, d, a, w2[0], MD5C1b, MD5S13);
MD5_STEP (MD5_Go, a, b, c, d, w3[1], MD5C1c, MD5S10);
MD5_STEP (MD5_Go, d, a, b, c, w0[2], MD5C1d, MD5S11);
MD5_STEP (MD5_Go, c, d, a, b, w1[3], MD5C1e, MD5S12);
MD5_STEP (MD5_Go, b, c, d, a, w3[0], MD5C1f, MD5S13);
MD5_STEP (MD5_H , a, b, c, d, w1[1], MD5C20, MD5S20);
MD5_STEP (MD5_H , d, a, b, c, w2[0], MD5C21, MD5S21);
MD5_STEP (MD5_H , c, d, a, b, w2[3], MD5C22, MD5S22);
MD5_STEP (MD5_H , b, c, d, a, w3[2], MD5C23, MD5S23);
MD5_STEP (MD5_H , a, b, c, d, w0[1], MD5C24, MD5S20);
MD5_STEP (MD5_H , d, a, b, c, w1[0], MD5C25, MD5S21);
MD5_STEP (MD5_H , c, d, a, b, w1[3], MD5C26, MD5S22);
MD5_STEP (MD5_H , b, c, d, a, w2[2], MD5C27, MD5S23);
MD5_STEP (MD5_H , a, b, c, d, w3[1], MD5C28, MD5S20);
MD5_STEP (MD5_H , d, a, b, c, w0[0], MD5C29, MD5S21);
MD5_STEP (MD5_H , c, d, a, b, w0[3], MD5C2a, MD5S22);
MD5_STEP (MD5_H , b, c, d, a, w1[2], MD5C2b, MD5S23);
MD5_STEP (MD5_H , a, b, c, d, w2[1], MD5C2c, MD5S20);
MD5_STEP (MD5_H , d, a, b, c, w3[0], MD5C2d, MD5S21);
MD5_STEP (MD5_H , c, d, a, b, w3[3], MD5C2e, MD5S22);
MD5_STEP (MD5_H , b, c, d, a, w0[2], MD5C2f, MD5S23);
MD5_STEP (MD5_I , a, b, c, d, w0[0], MD5C30, MD5S30);
MD5_STEP (MD5_I , d, a, b, c, w1[3], MD5C31, MD5S31);
MD5_STEP (MD5_I , c, d, a, b, w3[2], MD5C32, MD5S32);
MD5_STEP (MD5_I , b, c, d, a, w1[1], MD5C33, MD5S33);
MD5_STEP (MD5_I , a, b, c, d, w3[0], MD5C34, MD5S30);
MD5_STEP (MD5_I , d, a, b, c, w0[3], MD5C35, MD5S31);
MD5_STEP (MD5_I , c, d, a, b, w2[2], MD5C36, MD5S32);
MD5_STEP (MD5_I , b, c, d, a, w0[1], MD5C37, MD5S33);
MD5_STEP (MD5_I , a, b, c, d, w2[0], MD5C38, MD5S30);
MD5_STEP (MD5_I , d, a, b, c, w3[3], MD5C39, MD5S31);
MD5_STEP (MD5_I , c, d, a, b, w1[2], MD5C3a, MD5S32);
MD5_STEP (MD5_I , b, c, d, a, w3[1], MD5C3b, MD5S33);
MD5_STEP (MD5_I , a, b, c, d, w1[0], MD5C3c, MD5S30);
MD5_STEP (MD5_I , d, a, b, c, w2[3], MD5C3d, MD5S31);
MD5_STEP (MD5_I , c, d, a, b, w0[2], MD5C3e, MD5S32);
MD5_STEP (MD5_I , b, c, d, a, w2[1], MD5C3f, MD5S33);
digest[0] += a;
digest[1] += b;
digest[2] += c;
digest[3] += d;
}
/*===========================================================================*/
#define MD5_F(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
#define MD5_G(x,y,z) ((y) ^ ((z) & ((x) ^ (y))))
#define MD5_H(x,y,z) ((x) ^ (y) ^ (z))
#define MD5_I(x,y,z) ((y) ^ ((x) | ~(z)))
#define MD5_Fo(x,y,z) (MD5_F((x), (y), (z)))
#define MD5_Go(x,y,z) (MD5_G((x), (y), (z)))
#define MD5_STEP_S(f,a,b,c,d,x,K,s) \
{ \
a += K; \
a += x; \
a += f (b, c, d); \
a = rotl32_S (a, s); \
a += b; \
}
#define MD5_STEP(f,a,b,c,d,x,K,s) \
{ \
a += K; \
a += x; \
a += f (b, c, d); \
a = rotl32 (a, s); \
a += b; \
}
#define MD5_STEP0(f,a,b,c,d,K,s) \