From 9bb05486aa502ea73654d0027ac676969001fee4 Mon Sep 17 00:00:00 2001 From: magnum Date: Mon, 16 Dec 2024 21:06:47 +0000 Subject: [PATCH] WPAPSK CPU formats: Remove dependency on OpenSSL for 802.11w support Use the same simple CMAC-AES-128 implementation we have in OpenCL. --- src/cmac.h | 43 +++++++++++++ src/cmac_plug.c | 113 +++++++++++++++++++++++++++++++++++ src/opencl_wpapmk_fmt_plug.c | 2 +- src/wpapmk_fmt_plug.c | 20 ++----- src/wpapsk.h | 36 ++--------- src/wpapsk_fmt_plug.c | 19 ++---- 6 files changed, 171 insertions(+), 62 deletions(-) create mode 100644 src/cmac.h create mode 100644 src/cmac_plug.c diff --git a/src/cmac.h b/src/cmac.h new file mode 100644 index 00000000000..56046324931 --- /dev/null +++ b/src/cmac.h @@ -0,0 +1,43 @@ +/* + * This code implements the CMAC (Cipher-based Message Authentication) + * algorithm described in FIPS SP800-38B using the AES-128 cipher. + * + * Copyright (c) 2017, magnum. + * Copyright (c) 2008 Damien Bergamini + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef JTR_CMAC_H +#define JTR_CMAC_H + +#include + +#include "aes.h" + +#define AES_CMAC_KEY_LENGTH 16 +#define AES_CMAC_DIGEST_LENGTH 16 + +typedef struct _AES_CMAC_CTX { + AES_KEY aesctx; + uint8_t X[16]; + uint8_t M_last[16]; + uint32_t M_n; +} AES_CMAC_CTX; + +extern void AES_CMAC_Init(AES_CMAC_CTX *ctx); +extern void AES_CMAC_SetKey(AES_CMAC_CTX *ctx, const uint8_t *key); +extern void AES_CMAC_Update(AES_CMAC_CTX *ctx, const uint8_t *data, uint32_t len); +extern void AES_CMAC_Final(uint8_t *digest, AES_CMAC_CTX *ctx); + +#endif /* JTR_CMAC_H */ diff --git a/src/cmac_plug.c b/src/cmac_plug.c new file mode 100644 index 00000000000..d4952330d0f --- /dev/null +++ b/src/cmac_plug.c @@ -0,0 +1,113 @@ +/* + * This code implements the CMAC (Cipher-based Message Authentication) + * algorithm described in FIPS SP800-38B using the AES-128 cipher. + * + * Copyright (c) 2017, magnum. + * Copyright (c) 2008 Damien Bergamini + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "cmac.h" +#include "common.h" + +#define LSHIFT(v, r) do { \ + uint32_t i; \ + for (i = 0; i < 15; i++) \ + (r)[i] = (v)[i] << 1 | (v)[i + 1] >> 7; \ + (r)[15] = (v)[15] << 1; \ + } while (0) + +#define XOR(v, r) do { \ + uint32_t i; \ + for (i = 0; i < 16; i++) \ + (r)[i] ^= (v)[i]; \ + } while (0) + +void AES_CMAC_Init(AES_CMAC_CTX *ctx) +{ + uint32_t i; + + for (i = 0; i < 16; i++) + ctx->X[i] = 0; + ctx->M_n = 0; +} + +void AES_CMAC_SetKey(AES_CMAC_CTX *ctx, const uint8_t *key) +{ + AES_set_encrypt_key(key, 128, &ctx->aesctx); +} + +void AES_CMAC_Update(AES_CMAC_CTX *ctx, const uint8_t *data, uint32_t len) +{ + uint32_t i; + + if (ctx->M_n > 0) { + uint32_t mlen = MIN(16 - ctx->M_n, len); + + for (i = 0; i < mlen; i++) + ctx->M_last[ctx->M_n + i] = data[i]; + ctx->M_n += mlen; + if (ctx->M_n < 16 || len == mlen) + return; + XOR(ctx->M_last, ctx->X); + AES_encrypt(ctx->X, ctx->X, &ctx->aesctx); + data += mlen; + len -= mlen; + } + while (len > 16) { /* not last block */ + XOR(data, ctx->X); + AES_encrypt(ctx->X, ctx->X, &ctx->aesctx); + data += 16; + len -= 16; + } + /* potential last block, save it */ + for (i = 0; i < len; i++) + ctx->M_last[i] = data[i]; + ctx->M_n = len; +} + +void AES_CMAC_Final(uint8_t *digest, AES_CMAC_CTX *ctx) +{ + uint8_t K[16] = { 0 }; + + /* generate subkey K1 */ + AES_encrypt(K, K, &ctx->aesctx); + + if (K[0] & 0x80) { + LSHIFT(K, K); + K[15] ^= 0x87; + } else + LSHIFT(K, K); + + if (ctx->M_n == 16) { + /* last block was a complete block */ + XOR(K, ctx->M_last); + } else { + /* generate subkey K2 */ + if (K[0] & 0x80) { + LSHIFT(K, K); + K[15] ^= 0x87; + } else + LSHIFT(K, K); + + /* padding(M_last) */ + ctx->M_last[ctx->M_n] = 0x80; + while (++ctx->M_n < 16) + ctx->M_last[ctx->M_n] = 0; + + XOR(K, ctx->M_last); + } + XOR(ctx->M_last, ctx->X); + AES_encrypt(ctx->X, digest, &ctx->aesctx); +} diff --git a/src/opencl_wpapmk_fmt_plug.c b/src/opencl_wpapmk_fmt_plug.c index 4d68c721617..822d93b0634 100644 --- a/src/opencl_wpapmk_fmt_plug.c +++ b/src/opencl_wpapmk_fmt_plug.c @@ -35,7 +35,7 @@ static struct fmt_main *self; #define FORMAT_LABEL "wpapsk-pmk-opencl" #define FORMAT_NAME "WPA/WPA2/PMF/PMKID master key" -#define ALGORITHM_NAME "MD5/SHA-1/SHA-2 OpenCL" +#define ALGORITHM_NAME "MD5/SHA-1/HMAC-SHA256/AES-CMAC OpenCL" #define SEED 256 diff --git a/src/wpapmk_fmt_plug.c b/src/wpapmk_fmt_plug.c index 49e36d5dc19..015fbb161cb 100644 --- a/src/wpapmk_fmt_plug.c +++ b/src/wpapmk_fmt_plug.c @@ -29,19 +29,9 @@ john_register_one(&fmt_wpapsk_pmk); #include "options.h" #include "john.h" -#define FORMAT_LABEL "wpapsk-pmk" -#if !HAVE_OPENSSL_CMAC_H -#ifdef _MSC_VER -#pragma message("Notice: WPAPSK-PMK (CPU) format built without support for 802.11w (this needs recent OpenSSL)") -#else -#warning Notice: WPAPSK-PMK (CPU) format built without support for 802.11w (this needs recent OpenSSL) -#endif -#define FORMAT_NAME "WPA/WPA2/PMKID master key" -#else -#define FORMAT_NAME "WPA/WPA2/PMF/PMKID master key" -#endif - -#define ALGORITHM_NAME "MD5/SHA-1/SHA-2" +#define FORMAT_LABEL "wpapsk-pmk" +#define FORMAT_NAME "WPA/WPA2/PMF/PMKID master key" +#define ALGORITHM_NAME "MD5/SHA-1/HMAC-SHA256/AES-CMAC 32/" ARCH_BITS_STR #define MIN_KEYS_PER_CRYPT 1 #define MAX_KEYS_PER_CRYPT 128 @@ -137,10 +127,8 @@ struct fmt_main fmt_wpapsk_pmk = { { #if 1 NULL -#elif !AC_BUILT || HAVE_OPENSSL_CMAC_H - "key version [0:PMKID 1:WPA 2:WPA2 3:802.11w]" #else - "key version [0:PMKID 1:WPA 2:WPA2]" + "key version [0:PMKID 1:WPA 2:WPA2 3:802.11w]" #endif }, { diff --git a/src/wpapsk.h b/src/wpapsk.h index c3d50b19d07..c343efd84cc 100644 --- a/src/wpapsk.h +++ b/src/wpapsk.h @@ -16,17 +16,8 @@ #include "autoconfig.h" #endif -#if !HAVE_LIBCRYPTO -#undef HAVE_OPENSSL_CMAC_H -#elif !AC_BUILT && HAVE_LIBCRYPTO && !defined(HAVE_OPENSSL_CMAC_H) -#define HAVE_OPENSSL_CMAC_H 1 -#endif - #include #include -#if HAVE_OPENSSL_CMAC_H -#include -#endif #include "arch.h" #include "params.h" @@ -35,6 +26,7 @@ #include "hmacmd5.h" #include "hmac_sha.h" #include "sha2.h" +#include "cmac.h" #include "base64_convert.h" #include "hccap.h" @@ -88,9 +80,7 @@ static struct fmt_tests tests[] = { #ifdef WPAPMK {"$WPAPSK$test#..qHuv0A..ZPYJBRzZwAKpEXUJwpza/b69itFaq4.OWoGHfonpc13zCAUsRIfQN2Zar6EXp2BYcRuSkWEJIWjEJJvb4DWZCspbZ51.21.3zy.EY.6........../zZwAKpEXUJwpza/b69itFaq4.OWoGHfonpc13zCAUsQ..................................................................BoK.31m.E2..31m.U2..31m.U2..31m.U................................................................................................................................................................................/X.....E...AkkDQmDg9837LBHG.dGlKA", "cdd79a5acfb070c7e9d1023b870285d639e430b32f31aa37ac825a55b55524ee"}, {"$WPAPSK$Coherer#..l/Uf7J..qHUXMunTE3nfbMWSwxv27Ua0XutIOrfRSuv9gOCIugIVGlosMyXdNxfBZUAYmgKqeb6GBPxLiIZr56NtWTGR/Cp5ldAk61.5I0.Ec.2...........nTE3nfbMWSwxv27Ua0XutIOrfRSuv9gOCIugIVGlosM.................................................................3X.I.E..1uk0.E..1uk2.E..1uk0....................................................................................................................................................................................../t.....U...8FWdk8OpPckhewBwt4MXYI", "a288fcf0caaacda9a9f58633ff35e8992a01d9c10ba5e02efdf8cb5d730ce7bc"}, -#if HAVE_OPENSSL_CMAC_H || defined(JOHN_OCL_WPAPSK) {"$WPAPSK$Neheb#g9a8Jcre9D0WrPnEN4QXDbA5NwAy5TVpkuoChMdFfL/8Dus4i/X.lTnfwuw04ASqHgvo12wJYJywulb6pWM6C5uqiMPNKNe9pkr6LE61.5I0.Eg.2..........1N4QXDbA5NwAy5TVpkuoChMdFfL/8Dus4i/X.lTnfwuw.................................................................3X.I.E..1uk2.E..1uk2.E..1uk4X...................................................................................................................................................................................../t.....k...0sHl.mVkiHW.ryNchcMd4g", "fb57668cd338374412c26208d79aa5c30ce40a110224f3cfb592a8f2e8bf53e8"}, -#endif /* WPAPSK PMKID */ {"2582a8281bf9d4308d6f5731d0e61c61*4604ba734d4e*89acf0e761f4*ed487162465a774bfba60eb603a39f3a", "5b13d4babb3714ccc62c9f71864bc984efd6a55f237c7a87fc2151e1ca658a9d"}, #else @@ -102,12 +92,10 @@ static struct fmt_tests tests[] = { /* Maximum length, 63 characters */ {"$WPAPSK$Greased Lighting#kA5.CDNB.07cofsOMXEEUwFTkO/RX2sQUaW9eteI8ynpFMwRgFZC6kk7bGqgvfcXnuF1f7L5fgn4fQMLmDrKjdBNjb6LClRmfLiTYk21.5I0.Ec............7MXEEUwFTkO/RX2sQUaW9eteI8ynpFMwRgFZC6kk7bGo.................................................................3X.I.E..1uk2.E..1uk2.E..1uk00...................................................................................................................................................................................../t.....U...D06LUdWVfGPaP1Oa3AV9Hg", "W*A5z&1?op2_L&Hla-OA$#5i_Lu@F+6d?je?u5!6+6766eluu7-l+jOEkIwLe90"}, {"$WPAPSK$hello#JUjQmBbOHUY4RTqMpGc9EjqGdCxMZPWNXBNd1ejNDoFuemrLl27juYlDDUDMgZfery1qJTHYVn2Faso/kUDDjr3y8gspK7viz8BCJE21.5I0.Ec............/pGc9EjqGdCxMZPWNXBNd1ejNDoFuemrLl27juYlDDUA.................................................................3X.I.E..1uk2.E..1uk2.E..1uk0....................................................................................................................................................................................../t.....U...9Py59nqygwiar49oOKA3RY", "12345678"}, -#if HAVE_OPENSSL_CMAC_H || defined(JOHN_OCL_WPAPSK) /* 802.11w with WPA-PSK-SHA256 */ {"$WPAPSK$hello#HY6.hTXZv.v27BkPGuhkCnLAKxYHlTWYs.4yuqVSNAip3SeixhErtNMV30LZAA3uaEfy2U2tJQi.VICk4hqn3V5m7W3lNHSJYW5vLE21.5I0.Eg............/GuhkCnLAKxYHlTWYs.4yuqVSNAip3SeixhErtNMV30I.................................................................3X.I.E..1uk2.E..1uk2.E..1uk4....................................................................................................................................................................................../t.....k.../Ms4UxzvlNw5hOM1igIeo6", "password"}, /* 802.11w with WPA-PSK-SHA256, https://github.com/neheb */ {"$WPAPSK$Neheb#g9a8Jcre9D0WrPnEN4QXDbA5NwAy5TVpkuoChMdFfL/8Dus4i/X.lTnfwuw04ASqHgvo12wJYJywulb6pWM6C5uqiMPNKNe9pkr6LE61.5I0.Eg.2..........1N4QXDbA5NwAy5TVpkuoChMdFfL/8Dus4i/X.lTnfwuw.................................................................3X.I.E..1uk2.E..1uk2.E..1uk4X...................................................................................................................................................................................../t.....k...0sHl.mVkiHW.ryNchcMd4g", "bo$$password"}, -#endif /* WPAPSK PMKID */ {"2582a8281bf9d4308d6f5731d0e61c61*4604ba734d4e*89acf0e761f4*ed487162465a774bfba60eb603a39f3a", "hashcat!"}, #endif /* WPAPMK */ @@ -332,13 +320,8 @@ static int valid(char *ciphertext, struct fmt_main *self) return 0; if (hccap->keyver < 1) return 0; -#if HAVE_OPENSSL_CMAC_H || defined(JOHN_OCL_WPAPSK) if (hccap->keyver > 3) return 0; -#else - if (hccap->keyver > 2) - return 0; -#endif return 1; } @@ -414,8 +397,6 @@ static char *get_key(int index) } #endif /* WPAPMK */ -#if HAVE_OPENSSL_CMAC_H - /* Code borrowed from https://w1.fi/wpa_supplicant/ starts */ #define SHA256_MAC_LEN 32 @@ -534,7 +515,6 @@ static void sha256_prf_bits(const u8 *key, size_t key_len, const char *label, buf[pos - 1] &= mask; } } -#endif /* HAVE_OPENSSL_CMAC_H */ /* Code borrowed from https://w1.fi/wpa_supplicant/ ends */ @@ -592,7 +572,6 @@ static int cmp_all(void *binary, int count) hmac_sha1((unsigned char*)prf, 16, hccap->eapol, hccap->eapol_size, mic[i].keymic, 16); } -#if HAVE_OPENSSL_CMAC_H } else if (hccap->keyver == 3) { // 802.11w, WPA-PSK-SHA256 #ifdef _OPENMP #pragma omp parallel for default(none) private(i) shared(count, outbuffer, data, hccap, mic) @@ -600,20 +579,17 @@ static int cmp_all(void *binary, int count) for (i = 0; i < count; i++) { unsigned char ptk[48]; unsigned char cmic[16]; - size_t miclen; - CMAC_CTX *ctx; + AES_CMAC_CTX ctx; sha256_prf_bits((unsigned char*)outbuffer[i].v, 32, "Pairwise key expansion", data, 76, ptk, 48 * 8); // PTK // Compute MIC - ctx = CMAC_CTX_new(); - CMAC_Init(ctx, ptk, 16, EVP_aes_128_cbc(), 0); - CMAC_Update(ctx, hccap->eapol, hccap->eapol_size); - CMAC_Final(ctx, cmic, &miclen); + AES_CMAC_Init(&ctx); + AES_CMAC_SetKey(&ctx, ptk); + AES_CMAC_Update(&ctx, hccap->eapol, hccap->eapol_size); + AES_CMAC_Final(cmic, &ctx); memcpy(mic[i].keymic, cmic, 16); - CMAC_CTX_free(ctx); } -#endif /* HAVE_OPENSSL_CMAC_H */ } for (i = 0; i < count; i++) diff --git a/src/wpapsk_fmt_plug.c b/src/wpapsk_fmt_plug.c index 73557ba6adb..9900966fa67 100644 --- a/src/wpapsk_fmt_plug.c +++ b/src/wpapsk_fmt_plug.c @@ -36,23 +36,12 @@ john_register_one(&fmt_wpapsk); #include "options.h" #include "unicode.h" -#define FORMAT_LABEL "wpapsk" -#if !HAVE_OPENSSL_CMAC_H -#ifdef _MSC_VER -#pragma message("Notice: WPAPSK (CPU) format built without support for 802.11w (this needs recent OpenSSL)") -#else -#warning Notice: WPAPSK (CPU) format built without support for 802.11w (this needs recent OpenSSL) -#endif -#define CMACALGO "" -#define FORMAT_NAME "WPA/WPA2/PMKID PSK" -#else -#define CMACALGO "HMAC-SHA256/AES-CMAC " -#define FORMAT_NAME "WPA/WPA2/PMF/PMKID PSK" -#endif +#define FORMAT_LABEL "wpapsk" +#define FORMAT_NAME "WPA/WPA2/PMF/PMKID PSK" #ifdef SIMD_COEF_32 -#define ALGORITHM_NAME "PBKDF2-SHA1 " CMACALGO SHA1_ALGORITHM_NAME +#define ALGORITHM_NAME "PBKDF2-SHA1 " SHA1_ALGORITHM_NAME " HMAC-SHA256/AES-CMAC 32/" ARCH_BITS_STR #else -#define ALGORITHM_NAME "PBKDF2-SHA1 " CMACALGO "32/" ARCH_BITS_STR +#define ALGORITHM_NAME "PBKDF2-SHA1 HMAC-SHA256/AES-CMAC 32/" ARCH_BITS_STR #endif #ifdef SIMD_COEF_32