>From 7d3f9c5a7f7f218d58bf28df50619bf5df3a46a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claudio=20Andr=C3=A9?= Date: Sat, 31 Aug 2013 14:15:21 -0300 Subject: [PATCH 4/5] Unify valid() and binary() for sha256crypt CPU and OpenCL formats. --- src/cryptsha256_common.h | 84 ++++++++++++++++++++++++++++++++++++++++++++ src/cryptsha256_fmt_plug.c | 81 +++--------------------------------------- src/opencl_cryptsha256_fmt.c | 63 +-------------------------------- 3 files changed, 90 insertions(+), 138 deletions(-) create mode 100644 src/cryptsha256_common.h diff --git a/src/cryptsha256_common.h b/src/cryptsha256_common.h new file mode 100644 index 0000000..9960d2b --- /dev/null +++ b/src/cryptsha256_common.h @@ -0,0 +1,84 @@ +/* + * This file is part of John the Ripper password cracker, + * Copyright (c) 2012 magnum + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * There's ABSOLUTELY NO WARRANTY, express or implied. + */ + +#ifndef _COMMON_CRYPTSHA256_H +#define _COMMON_CRYPTSHA256_H + +/* ------ Contains (at least) prepare(), valid() and split() ------ */ +/* Prefix for optional rounds specification. */ +#define ROUNDS_PREFIX "rounds=" +/* Default number of rounds if not explicitly specified. */ +#define ROUNDS_DEFAULT 5000 +/* Minimum number of rounds. */ +#define ROUNDS_MIN 1 /* Drepper has it as 1000 */ +/* Maximum number of rounds. */ +#define ROUNDS_MAX 999999999 + +#define FORMAT_NAME "crypt(3) $5$" +#define BENCHMARK_COMMENT " (rounds=5000)" +#define BENCHMARK_LENGTH -1 + +/* ------- Check if the ciphertext if a valid SHA-256 crypt ------- */ +static int valid(char * ciphertext, struct fmt_main * self) { + char *pos, *start; + + if (strncmp(ciphertext, "$5$", 3)) + return 0; + + ciphertext += 3; + + if (!strncmp(ciphertext, ROUNDS_PREFIX, + sizeof(ROUNDS_PREFIX) - 1)) { + const char *num = ciphertext + sizeof(ROUNDS_PREFIX) - 1; + char *endp; + if (!strtoul(num, &endp, 10)) + return 0; + if (*endp == '$') + ciphertext = endp + 1; + } + for (pos = ciphertext; *pos && *pos != '$'; pos++); + if (!*pos || pos < ciphertext || pos > &ciphertext[SALT_LENGTH]) return 0; + + start = ++pos; + while (atoi64[ARCH_INDEX(*pos)] != 0x7F) pos++; + if (*pos || pos - start != CIPHERTEXT_LENGTH) return 0; + return 1; +} + +/* ------- To binary functions ------- */ +#define TO_BINARY(b1, b2, b3) \ + value = (ARCH_WORD_32)atoi64[ARCH_INDEX(pos[0])] | \ + ((ARCH_WORD_32)atoi64[ARCH_INDEX(pos[1])] << 6) | \ + ((ARCH_WORD_32)atoi64[ARCH_INDEX(pos[2])] << 12) | \ + ((ARCH_WORD_32)atoi64[ARCH_INDEX(pos[3])] << 18); \ + pos += 4; \ + out[b1] = value >> 16; \ + out[b2] = value >> 8; \ + out[b3] = value; + +static void * get_binary(char * ciphertext) { + static ARCH_WORD_32 outbuf[BINARY_SIZE/4]; + ARCH_WORD_32 value; + char *pos = strrchr(ciphertext, '$') + 1; + unsigned char *out = (unsigned char*)outbuf; + int i=0; + + do { + TO_BINARY(i, (i+10)%30, (i+20)%30); + i = (i+21)%30; + } while (i != 0); + value = (ARCH_WORD_32)atoi64[ARCH_INDEX(pos[0])] | + ((ARCH_WORD_32)atoi64[ARCH_INDEX(pos[1])] << 6) | + ((ARCH_WORD_32)atoi64[ARCH_INDEX(pos[2])] << 12); + out[31] = value >> 8; + out[30] = value; + return (void *)out; +} +#endif diff --git a/src/cryptsha256_fmt_plug.c b/src/cryptsha256_fmt_plug.c index 364c876..787220c 100644 --- a/src/cryptsha256_fmt_plug.c +++ b/src/cryptsha256_fmt_plug.c @@ -142,16 +142,13 @@ void main() { #endif #define FORMAT_LABEL "sha256crypt" -#define FORMAT_NAME "crypt(3) $5$" + #ifdef MMX_COEF_SHA256 #define ALGORITHM_NAME SHA256_ALGORITHM_NAME #else #define ALGORITHM_NAME "32/" ARCH_BITS_STR " " SHA2_LIB #endif -#define BENCHMARK_COMMENT " (rounds=5000)" -#define BENCHMARK_LENGTH -1 - // 35 character input is MAX password that fits into 2 SHA256 blocks // 35 character input creates a 118 byte buffer, plus 1 for 0x80 and // 1 unused byte and 8 byte bit length. That is max for a 2 block crypt @@ -171,6 +168,7 @@ void main() { #define MAX_KEYS_PER_CRYPT 1 #endif +#include "cryptsha256_common.h" static struct fmt_tests tests[] = { {"$5$LKO/Ute40T3FNF95$U0prpBQd4PloSGU0pnpM4z9wKn4vZ1.jsrzQfPqxph9", "U*U*U*U*"}, @@ -191,16 +189,6 @@ static struct fmt_tests tests[] = { {NULL} }; -/* Prefix for optional rounds specification. */ -static const char sha256_rounds_prefix[] = "rounds="; - -/* Default number of rounds if not explicitly specified. */ -#define ROUNDS_DEFAULT 5000 -/* Minimum number of rounds. */ -#define ROUNDS_MIN 1 /* Drepper has it as 1000 */ -/* Maximum number of rounds. */ -#define ROUNDS_MAX 999999999 - /* This structure is 'pre-loaded' with the keyspace of all possible crypts which */ /* will be performed WITHIN the inner loop. There are 8 possible buffers that */ /* are used. They are cp, pspc, cspp, ppc, cpp, psc, csp, and pc, where p stands */ @@ -281,65 +269,6 @@ static void init(struct fmt_main *self) crypt_out = mem_calloc_tiny(sizeof(*crypt_out) * (1+max_crypts), MEM_ALIGN_WORD); } -static int valid(char *ciphertext, struct fmt_main *self) -{ - char *pos, *start; - - if (strncmp(ciphertext, "$5$", 3)) - return 0; - - ciphertext += 3; - - if (!strncmp(ciphertext, sha256_rounds_prefix, - sizeof(sha256_rounds_prefix) - 1)) { - const char *num = ciphertext + sizeof(sha256_rounds_prefix) - 1; - char *endp; - if (!strtoul(num, &endp, 10)) - return 0; - if (*endp == '$') - ciphertext = endp + 1; - } - - for (pos = ciphertext; *pos && *pos != '$'; pos++); - if (!*pos || pos < ciphertext || pos > &ciphertext[SALT_LENGTH]) return 0; - - start = ++pos; - while (atoi64[ARCH_INDEX(*pos)] != 0x7F) pos++; - if (*pos || pos - start != CIPHERTEXT_LENGTH) return 0; - - return 1; -} - -#define TO_BINARY(b1, b2, b3) \ - value = (ARCH_WORD_32)atoi64[ARCH_INDEX(pos[0])] | \ - ((ARCH_WORD_32)atoi64[ARCH_INDEX(pos[1])] << 6) | \ - ((ARCH_WORD_32)atoi64[ARCH_INDEX(pos[2])] << 12) | \ - ((ARCH_WORD_32)atoi64[ARCH_INDEX(pos[3])] << 18); \ - pos += 4; \ - out[b1] = value >> 16; \ - out[b2] = value >> 8; \ - out[b3] = value; - -static void *get_binary(char *ciphertext) -{ - static ARCH_WORD_32 outbuf[BINARY_SIZE/4]; - ARCH_WORD_32 value; - char *pos = strrchr(ciphertext, '$') + 1; - unsigned char *out = (unsigned char*)outbuf; - int i=0; - - do { - TO_BINARY(i, (i+10)%30, (i+20)%30); - i = (i+21)%30; - } while (i != 0); - value = (ARCH_WORD_32)atoi64[ARCH_INDEX(pos[0])] | - ((ARCH_WORD_32)atoi64[ARCH_INDEX(pos[1])] << 6) | - ((ARCH_WORD_32)atoi64[ARCH_INDEX(pos[2])] << 12); - out[31] = value >> 8; - out[30] = value; - return (void *)out; -} - static int get_hash_0(int index) { return crypt_out[index][0] & 0xf; } static int get_hash_1(int index) { return crypt_out[index][0] & 0xff; } static int get_hash_2(int index) { return crypt_out[index][0] & 0xfff; } @@ -940,9 +869,9 @@ static void *get_salt(char *ciphertext) out.rounds = ROUNDS_DEFAULT; ciphertext += 3; - if (!strncmp(ciphertext, sha256_rounds_prefix, - sizeof(sha256_rounds_prefix) - 1)) { - const char *num = ciphertext + sizeof(sha256_rounds_prefix) - 1; + if (!strncmp(ciphertext, ROUNDS_PREFIX, + sizeof(ROUNDS_PREFIX) - 1)) { + const char *num = ciphertext + sizeof(ROUNDS_PREFIX) - 1; char *endp; unsigned long int srounds = strtoul(num, &endp, 10); if (*endp == '$') diff --git a/src/opencl_cryptsha256_fmt.c b/src/opencl_cryptsha256_fmt.c index d18bf5d..725d948 100644 --- a/src/opencl_cryptsha256_fmt.c +++ b/src/opencl_cryptsha256_fmt.c @@ -18,14 +18,10 @@ #include "config.h" #include "options.h" #include "opencl_cryptsha256.h" +#include "cryptsha256_common.h" #define FORMAT_LABEL "sha256crypt-opencl" -#define FORMAT_NAME "crypt(3) $5$" #define ALGORITHM_NAME "SHA256 OpenCL" - -#define BENCHMARK_COMMENT " (rounds=5000)" -#define BENCHMARK_LENGTH -1 - #define OCL_CONFIG "sha256crypt" //Checks for source code to pick (parameters, sizes, kernels to execute, etc.) @@ -433,63 +429,6 @@ static void done(void) { HANDLE_CLERROR(clReleaseProgram(program[ocl_gpu_id]), "Release Program"); } -/* ------- Check if the ciphertext if a valid SHA-256 crypt ------- */ -static int valid(char * ciphertext, struct fmt_main * self) { - char *pos, *start; - - if (strncmp(ciphertext, "$5$", 3)) - return 0; - - ciphertext += 3; - - if (!strncmp(ciphertext, ROUNDS_PREFIX, - sizeof(ROUNDS_PREFIX) - 1)) { - const char *num = ciphertext + sizeof(ROUNDS_PREFIX) - 1; - char *endp; - if (!strtoul(num, &endp, 10)) - return 0; - if (*endp == '$') - ciphertext = endp + 1; - } - for (pos = ciphertext; *pos && *pos != '$'; pos++); - if (!*pos || pos < ciphertext || pos > &ciphertext[SALT_LENGTH]) return 0; - - start = ++pos; - while (atoi64[ARCH_INDEX(*pos)] != 0x7F) pos++; - if (*pos || pos - start != CIPHERTEXT_LENGTH) return 0; - return 1; -} - -/* ------- To binary functions ------- */ -#define TO_BINARY(b1, b2, b3) \ - value = (ARCH_WORD_32)atoi64[ARCH_INDEX(pos[0])] | \ - ((ARCH_WORD_32)atoi64[ARCH_INDEX(pos[1])] << 6) | \ - ((ARCH_WORD_32)atoi64[ARCH_INDEX(pos[2])] << 12) | \ - ((ARCH_WORD_32)atoi64[ARCH_INDEX(pos[3])] << 18); \ - pos += 4; \ - out[b1] = value >> 16; \ - out[b2] = value >> 8; \ - out[b3] = value; - -static void * get_binary(char * ciphertext) { - static ARCH_WORD_32 outbuf[BINARY_SIZE/4]; - ARCH_WORD_32 value; - char *pos = strrchr(ciphertext, '$') + 1; - unsigned char *out = (unsigned char*)outbuf; - int i=0; - - do { - TO_BINARY(i, (i+10)%30, (i+20)%30); - i = (i+21)%30; - } while (i != 0); - value = (ARCH_WORD_32)atoi64[ARCH_INDEX(pos[0])] | - ((ARCH_WORD_32)atoi64[ARCH_INDEX(pos[1])] << 6) | - ((ARCH_WORD_32)atoi64[ARCH_INDEX(pos[2])] << 12); - out[31] = value >> 8; - out[30] = value; - return (void *)out; -} - /* ------- Compare functins ------- */ static int cmp_all(void * binary, int count) { uint32_t i; -- 1.8.1.2