improve hmac_sha256 cracking speed and re-add option openssl support

This commit is contained in:
rofl0r 2017-11-30 15:19:36 +00:00 committed by wiire-a
parent 5bf902b187
commit 2a24083f33
5 changed files with 147 additions and 13 deletions

View File

@ -43,6 +43,7 @@ cd pixiewps*/
cd src/ cd src/
make make
``` ```
Optionally, you can run make OPENSSL=1 to use faster OpenSSL SHA256 functions.
**Install** **Install**

View File

@ -1,12 +1,20 @@
CFLAGS ?= -std=c99 -O3 CFLAGS = -std=c99 -O3
LIBS = -lpthread
ifeq ($(OPENSSL),1)
LIBS += -lcrypto
CFLAGS += -DUSE_OPENSSL
else
CRYPTO = mbedtls/sha256.c mbedtls/md.c mbedtls/md_wrap.c
endif
PREFIX = /usr
BINDIR = $(PREFIX)/bin
TARGET = pixiewps TARGET = pixiewps
CRYPTO = mbedtls/sha256.c mbedtls/md.c mbedtls/md_wrap.c
SOURCE = $(TARGET).c $(CRYPTO) SOURCE = $(TARGET).c $(CRYPTO)
LIBS = -lpthread
PREFIX ?= /usr -include config.mak
BINDIR = $(PREFIX)/bin
all: all:
$(CC) $(CFLAGS) $(CPPFLAGS) -o $(TARGET) $(SOURCE) $(LIBS) $(LDFLAGS) $(CC) $(CFLAGS) $(CPPFLAGS) -o $(TARGET) $(SOURCE) $(LIBS) $(LDFLAGS)

View File

@ -25,9 +25,9 @@
#include "mbedtls/md_internal.h" #include "mbedtls/md_internal.h"
#include "mbedtls/sha256.h" #include "mbedtls/sha256.h"
#define sha256(i, l, d) mbedtls_sha256(i, l, d, 0) #define sha256(i, l, d) sha256_full(i, l, d)
#define hmac_sha256(k, l, i, n, o) \ #define hmac_sha256(k, l, i, n, o) \
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), k, l, i, n, o) hmac_sha256_full(k, l, i, n, o)
#define u8 uint8_t #define u8 uint8_t
#define u16 uint16_t #define u16 uint16_t

119
src/crypto/hmac_sha256.c Normal file
View File

@ -0,0 +1,119 @@
/* public domain hmac_sha256 implementation written by rofl0r for pixiewps */
#include <stdint.h>
#include <string.h>
#ifdef USE_OPENSSL
#include <openssl/sha.h>
#else
#include "../mbedtls/sha256.h"
#define SHA256_CTX mbedtls_sha256_context
#define SHA256_Init(x) do { mbedtls_sha256_init(x); mbedtls_sha256_starts(x, 0); } while(0)
#define SHA256_Update(x, y, z) mbedtls_sha256_update(x, y, z)
#define SHA256_Final(y, x) mbedtls_sha256_finish(x, y)
#endif
#define PAD_SIZE 64
#define HASH_SIZE 32
static void sha256_full(const uint8_t *input, size_t ilen, uint8_t *output)
{
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, input, ilen);
SHA256_Final(output, &ctx);
}
static void hmac_sha256_full(const uint8_t *key, size_t keylen,
const uint8_t *input, size_t ilen, uint8_t *output)
{
size_t i;
uint8_t opad[PAD_SIZE], ipad[PAD_SIZE], hash[HASH_SIZE];
SHA256_CTX ctx;
memset(ipad, 0x36, PAD_SIZE);
memset(opad, 0x5C, PAD_SIZE);
if (keylen > PAD_SIZE) {
SHA256_Init(&ctx);
SHA256_Update(&ctx, key, keylen);
SHA256_Final(hash, &ctx);
for (i = 0; i < HASH_SIZE; i++) {
ipad[i] ^= hash[i];
opad[i] ^= hash[i];
}
} else for (i = 0; i < keylen; i++) {
ipad[i] ^= key[i];
opad[i] ^= key[i];
}
SHA256_Init(&ctx);
SHA256_Update(&ctx, ipad, PAD_SIZE);
SHA256_Update(&ctx, input, ilen);
SHA256_Final(hash, &ctx);
SHA256_Init(&ctx);
SHA256_Update(&ctx, opad, PAD_SIZE);
SHA256_Update(&ctx, hash, sizeof hash);
SHA256_Final(output, &ctx);
}
struct hmac_ctx {
SHA256_CTX ictx;
SHA256_CTX octx;
};
static void hmac_sha256_init(struct hmac_ctx *hctx, const uint8_t *key, size_t keylen)
{
size_t i;
uint8_t opad[PAD_SIZE], ipad[PAD_SIZE], hash[HASH_SIZE];
SHA256_CTX ctx;
memset(ipad, 0x36, PAD_SIZE);
memset(opad, 0x5C, PAD_SIZE);
if (keylen > PAD_SIZE) {
SHA256_Init(&ctx);
SHA256_Update(&ctx, key, keylen);
SHA256_Final(hash, &ctx);
for (i = 0; i<HASH_SIZE; i++) {
ipad[i] ^= hash[i];
opad[i] ^= hash[i];
}
} else for (i = 0; i < keylen; i++) {
ipad[i] ^= key[i];
opad[i] ^= key[i];
}
SHA256_Init(&hctx->ictx);
SHA256_Update(&hctx->ictx, ipad, PAD_SIZE);
SHA256_Init(&hctx->octx);
SHA256_Update(&hctx->octx, opad, PAD_SIZE);
}
static void hmac_sha256_yield(const struct hmac_ctx *hctx,
const uint8_t *input, size_t ilen, uint8_t *output)
{
SHA256_CTX ctx;
uint8_t hash[HASH_SIZE];
memcpy(&ctx, &hctx->ictx, sizeof(ctx));
SHA256_Update(&ctx, input, ilen);
SHA256_Final(hash, &ctx);
memcpy(&ctx, &hctx->octx, sizeof(ctx));
SHA256_Update(&ctx, hash, sizeof hash);
SHA256_Final(output, &ctx);
}

View File

@ -38,6 +38,7 @@
#include "pixiewps.h" #include "pixiewps.h"
#include "crypto/crypto_internal-modexp.c" #include "crypto/crypto_internal-modexp.c"
#include "crypto/aes-cbc.c" #include "crypto/aes-cbc.c"
#include "crypto/hmac_sha256.c"
#include "utils.h" #include "utils.h"
#include "wps.h" #include "wps.h"
#include "version.h" #include "version.h"
@ -1482,17 +1483,17 @@ static int int_pow(int a, int exp)
} }
/* return non-zero if pin half is correct, zero otherwise */ /* return non-zero if pin half is correct, zero otherwise */
static int check_pin_half(const char pinhalf[4], uint8_t *psk, const uint8_t *es, struct global *wps, const uint8_t *ehash) static int check_pin_half(const struct hmac_ctx *hctx, const char pinhalf[4], uint8_t *psk, const uint8_t *es, struct global *wps, const uint8_t *ehash)
{ {
uint8_t buffer[WPS_SECRET_NONCE_LEN + WPS_PSK_LEN + WPS_PKEY_LEN * 2]; uint8_t buffer[WPS_SECRET_NONCE_LEN + WPS_PSK_LEN + WPS_PKEY_LEN * 2];
uint8_t result[WPS_HASH_LEN]; uint8_t result[WPS_HASH_LEN];
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, (unsigned char *)pinhalf, 4, psk); hmac_sha256_yield(hctx, pinhalf, 4, psk);
memcpy(buffer, es, WPS_SECRET_NONCE_LEN); memcpy(buffer, es, WPS_SECRET_NONCE_LEN);
memcpy(buffer + WPS_SECRET_NONCE_LEN, psk, WPS_PSK_LEN); memcpy(buffer + WPS_SECRET_NONCE_LEN, psk, WPS_PSK_LEN);
memcpy(buffer + WPS_SECRET_NONCE_LEN + WPS_PSK_LEN, wps->pke, WPS_PKEY_LEN); memcpy(buffer + WPS_SECRET_NONCE_LEN + WPS_PSK_LEN, wps->pke, WPS_PKEY_LEN);
memcpy(buffer + WPS_SECRET_NONCE_LEN + WPS_PSK_LEN + WPS_PKEY_LEN, wps->pkr, WPS_PKEY_LEN); memcpy(buffer + WPS_SECRET_NONCE_LEN + WPS_PSK_LEN + WPS_PKEY_LEN, wps->pkr, WPS_PKEY_LEN);
hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, buffer, sizeof buffer, result); hmac_sha256_yield(hctx, buffer, sizeof buffer, result);
return !memcmp(result, ehash, WPS_HASH_LEN); return !memcmp(result, ehash, WPS_HASH_LEN);
} }
@ -1525,10 +1526,12 @@ static int crack_first_half(struct global *wps, char *pin, const uint8_t *es1_ov
unsigned first_half; unsigned first_half;
uint8_t psk[WPS_HASH_LEN]; uint8_t psk[WPS_HASH_LEN];
struct hmac_ctx hc;
hmac_sha256_init(&hc, wps->authkey, WPS_AUTHKEY_LEN);
for (first_half = 0; first_half < 10000; first_half++) { for (first_half = 0; first_half < 10000; first_half++) {
uint_to_char_array(first_half, 4, pin); uint_to_char_array(first_half, 4, pin);
if (check_pin_half(pin, psk, es1, wps, wps->e_hash1)) { if (check_pin_half(&hc, pin, psk, es1, wps, wps->e_hash1)) {
pin[4] = 0; /* make sure pin string is zero-terminated */ pin[4] = 0; /* make sure pin string is zero-terminated */
memcpy(wps->psk1, psk, sizeof psk); memcpy(wps->psk1, psk, sizeof psk);
return 1; return 1;
@ -1549,12 +1552,15 @@ static int crack_second_half(struct global *wps, char *pin)
unsigned second_half, first_half = atoi(pin); unsigned second_half, first_half = atoi(pin);
char *s_pin = pin + strlen(pin); char *s_pin = pin + strlen(pin);
uint8_t psk[WPS_HASH_LEN]; uint8_t psk[WPS_HASH_LEN];
struct hmac_ctx hc;
hmac_sha256_init(&hc, wps->authkey, WPS_AUTHKEY_LEN);
for (second_half = 0; second_half < 1000; second_half++) { for (second_half = 0; second_half < 1000; second_half++) {
unsigned int checksum_digit = wps_pin_checksum(first_half * 1000 + second_half); unsigned int checksum_digit = wps_pin_checksum(first_half * 1000 + second_half);
unsigned int c_second_half = second_half * 10 + checksum_digit; unsigned int c_second_half = second_half * 10 + checksum_digit;
uint_to_char_array(c_second_half, 4, s_pin); uint_to_char_array(c_second_half, 4, s_pin);
if (check_pin_half(s_pin, psk, wps->e_s2, wps, wps->e_hash2)) { if (check_pin_half(&hc, s_pin, psk, wps->e_s2, wps, wps->e_hash2)) {
memcpy(wps->psk2, psk, sizeof psk); memcpy(wps->psk2, psk, sizeof psk);
pin[8] = 0; pin[8] = 0;
return 1; return 1;
@ -1569,7 +1575,7 @@ static int crack_second_half(struct global *wps, char *pin)
} }
uint_to_char_array(second_half, 4, s_pin); uint_to_char_array(second_half, 4, s_pin);
if (check_pin_half(s_pin, psk, wps->e_s2, wps, wps->e_hash2)) { if (check_pin_half(&hc, s_pin, psk, wps->e_s2, wps, wps->e_hash2)) {
memcpy(wps->psk2, psk, sizeof psk); memcpy(wps->psk2, psk, sizeof psk);
pin[8] = 0; /* make sure pin string is zero-terminated */ pin[8] = 0; /* make sure pin string is zero-terminated */
return 1; return 1;