Skip to content

Commit e592fe2

Browse files
committed
Unify MD4 and MD5 raw formats (CPU and OpenCL)
Unify as in make almost equal - we could also create a md4_md5_common.h and stuff, but that's too much work. The MD4 ones were initially very close to copies of MD5 with s/MD5/MD4). Over the years they always start to differ unneededly and I use to re-unify them now and then, so a bugfix or improvement in one isn't missing in the other. This time we got added support for "{MD4}<base64>" input format.
1 parent 9ba1e87 commit e592fe2

File tree

4 files changed

+86
-42
lines changed

4 files changed

+86
-42
lines changed

src/opencl_rawmd4_fmt_plug.c

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
/*
22
* MD4 OpenCL code is based on Alain Espinosa's OpenCL patches.
33
*
4-
* This software is Copyright (c) 2010, Dhiru Kholia <dhiru.kholia at gmail.com>
5-
* and Copyright (c) 2012, magnum
6-
* and Copyright (c) 2015, Sayantan Datta <[email protected]>
4+
* This software is
5+
* Copyright (c) 2010, Dhiru Kholia <dhiru.kholia at gmail.com>
6+
* Copyright (c) 2012-2025, magnum
7+
* Copyright (c) 2015, Sayantan Datta <[email protected]>
78
* and it is hereby released to the general public under the following terms:
89
* Redistribution and use in source and binary forms, with or without
910
* modification, are permitted.
@@ -26,6 +27,7 @@ john_register_one(&FMT_STRUCT);
2627
#include "path.h"
2728
#include "common.h"
2829
#include "formats.h"
30+
#include "base64_convert.h"
2931
#include "config.h"
3032
#include "options.h"
3133
#include "mask_ext.h"
@@ -41,12 +43,14 @@ john_register_one(&FMT_STRUCT);
4143
#define CIPHERTEXT_LENGTH 32
4244
#define DIGEST_SIZE 16
4345
#define BINARY_SIZE 16
44-
#define BINARY_ALIGN sizeof(int)
46+
#define BINARY_ALIGN sizeof(uint32_t)
4547
#define SALT_SIZE 0
4648
#define SALT_ALIGN 1
4749

4850
#define FORMAT_TAG "$MD4$"
4951
#define TAG_LENGTH (sizeof(FORMAT_TAG) - 1)
52+
#define FORMAT_TAG2 "{MD4}"
53+
#define FORMAT_TAG2_LEN (sizeof(FORMAT_TAG2) - 1)
5054

5155
static cl_mem pinned_saved_keys, pinned_saved_idx, pinned_int_key_loc;
5256
static cl_mem buffer_keys, buffer_idx, buffer_int_keys, buffer_int_key_loc;
@@ -78,6 +82,7 @@ static struct fmt_tests tests[] = {
7882
{FORMAT_TAG "41f92cf74e3d2c3ba79183629a929915", "rockyou" },
7983
{FORMAT_TAG "012d73e0fab8d26e0f4d65e36077511e", "12345678" },
8084
{FORMAT_TAG "0ceb1fd260c35bd50005341532748de6", "abc123" },
85+
{"{MD4}2zRtaR16zE3CYl2xn54/Ug==", "test"},
8186
{NULL}
8287
};
8388

@@ -260,6 +265,25 @@ static void init(struct fmt_main *_self)
260265
mask_int_cand_target = opencl_speed_index(gpu_id) / 300;
261266
}
262267

268+
/* Convert {MD4}2zRtaR16zE3CYl2xn54/Ug== to db346d691d7acc4dc2625db19f9e3f52 */
269+
static char *prepare(char *fields[10], struct fmt_main *self)
270+
{
271+
static char out[CIPHERTEXT_LENGTH + 1];
272+
273+
if (!strncmp(fields[1], FORMAT_TAG2, FORMAT_TAG2_LEN) &&
274+
strlen(fields[1]) == FORMAT_TAG2_LEN + 24) {
275+
int res;
276+
277+
res = base64_convert(&fields[1][FORMAT_TAG2_LEN], e_b64_mime, 24,
278+
out, e_b64_hex, sizeof(out),
279+
flg_Base64_HEX_LOCASE, 0);
280+
if (res >= 0)
281+
return out;
282+
}
283+
284+
return fields[1];
285+
}
286+
263287
static int valid(char *ciphertext, struct fmt_main *self)
264288
{
265289
char *p, *q;
@@ -280,12 +304,17 @@ static int valid(char *ciphertext, struct fmt_main *self)
280304
static char *split(char *ciphertext, int index, struct fmt_main *self)
281305
{
282306
static char out[TAG_LENGTH + CIPHERTEXT_LENGTH + 1];
307+
int len;
283308

284309
if (!strncmp(ciphertext, FORMAT_TAG, TAG_LENGTH))
285310
return ciphertext;
286311

312+
memset(out, 0, sizeof(out));
287313
memcpy(out, FORMAT_TAG, TAG_LENGTH);
288-
memcpy(out + TAG_LENGTH, ciphertext, CIPHERTEXT_LENGTH + 1);
314+
len = strlen(ciphertext)+1;
315+
if (len > CIPHERTEXT_LENGTH + 1)
316+
len = CIPHERTEXT_LENGTH + 1;
317+
memcpy(out + TAG_LENGTH, ciphertext, len);
289318
return out;
290319
}
291320

@@ -364,7 +393,6 @@ static char *get_key(int index)
364393
}
365394

366395
if (t >= global_work_size) {
367-
//fprintf(stderr, "Get key error! %d %d\n", t, index);
368396
t = 0;
369397
}
370398

@@ -396,8 +424,6 @@ static int crypt_all(int *pcount, struct db_salt *salt)
396424

397425
global_work_size = GET_NEXT_MULTIPLE(count, local_work_size);
398426

399-
//fprintf(stderr, "%s(%d) lws "Zu" gws "Zu" idx %u int_cand %d\n", __FUNCTION__, count, local_work_size, global_work_size, key_idx, mask_int_cand.num_int_cand);
400-
401427
// copy keys to the device
402428
if (key_idx)
403429
BENCH_CLERROR(clEnqueueWriteBuffer(queue[gpu_id], buffer_keys, CL_TRUE, 0, 4 * key_idx, saved_plain, 0, NULL, NULL), "failed in clEnqueueWriteBuffer buffer_keys.");
@@ -621,13 +647,13 @@ struct fmt_main FMT_STRUCT = {
621647
MAX_KEYS_PER_CRYPT,
622648
FMT_CASE | FMT_8_BIT | FMT_REMOVE | FMT_MASK,
623649
{ NULL },
624-
{ FORMAT_TAG },
650+
{ FORMAT_TAG, FORMAT_TAG2 },
625651
tests
626652
}, {
627653
init,
628654
done,
629655
reset,
630-
fmt_default_prepare,
656+
prepare,
631657
valid,
632658
split,
633659
get_binary,

src/opencl_rawmd5_fmt_plug.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
/*
22
* MD5 OpenCL code is based on Alain Espinosa's OpenCL patches.
33
*
4-
* This software is Copyright (c) 2010, Dhiru Kholia <dhiru.kholia at gmail.com>
5-
* and Copyright (c) 2012, magnum
6-
* and Copyright (c) 2015, Sayantan Datta <[email protected]>
4+
* This software is
5+
* Copyright (c) 2010, Dhiru Kholia <dhiru.kholia at gmail.com>
6+
* Copyright (c) 2012-2025, magnum
7+
* Copyright (c) 2015, Sayantan Datta <[email protected]>
78
* and it is hereby released to the general public under the following terms:
89
* Redistribution and use in source and binary forms, with or without
910
* modification, are permitted.
@@ -46,10 +47,10 @@ john_register_one(&FMT_STRUCT);
4647
#define SALT_SIZE 0
4748
#define SALT_ALIGN 1
4849

49-
#define FORMAT_TAG "$dynamic_0$"
50-
#define TAG_LENGTH (sizeof(FORMAT_TAG) - 1)
51-
#define FORMAT_TAG2 "{MD5}"
52-
#define FORMAT_TAG2_LEN (sizeof(FORMAT_TAG2) - 1)
50+
#define FORMAT_TAG "$dynamic_0$"
51+
#define TAG_LENGTH (sizeof(FORMAT_TAG) - 1)
52+
#define FORMAT_TAG2 "{MD5}"
53+
#define FORMAT_TAG2_LEN (sizeof(FORMAT_TAG2) - 1)
5354

5455
static cl_mem pinned_saved_keys, pinned_saved_idx, pinned_int_key_loc;
5556
static cl_mem buffer_keys, buffer_idx, buffer_int_keys, buffer_int_key_loc;
@@ -389,7 +390,6 @@ static char *get_key(int index)
389390
}
390391

391392
if (t >= global_work_size) {
392-
//fprintf(stderr, "Get key error! %d %d\n", t, index);
393393
t = 0;
394394
}
395395

@@ -421,8 +421,6 @@ static int crypt_all(int *pcount, struct db_salt *salt)
421421

422422
global_work_size = GET_NEXT_MULTIPLE(count, local_work_size);
423423

424-
//fprintf(stderr, "%s(%d) lws "Zu" gws "Zu" idx %u int_cand%d\n", __FUNCTION__, count, local_work_size, global_work_size, key_idx, mask_int_cand.num_int_cand);
425-
426424
// copy keys to the device
427425
if (key_idx)
428426
BENCH_CLERROR(clEnqueueWriteBuffer(queue[gpu_id], buffer_keys, CL_TRUE, 0, 4 * key_idx, saved_plain, 0, NULL, NULL), "failed in clEnqueueWriteBuffer buffer_keys.");

src/rawMD4_fmt_plug.c

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
/*
2-
* This file is part of John the Ripper password cracker,
3-
* Copyright (c) 2010 by Solar Designer
4-
* Copyright (c) 2011, 2012 by magnum
5-
*
6-
* Use of Bartavelle's mmx/sse2/intrinsics and reduced binary size by
7-
* magnum in 2011-2012.
8-
*
9-
* OMP added May 2013, JimF
10-
* BE SIMD logic added 2017, JimF
2+
* This software is
3+
* Copyright (c) 2011-2025 magnum
4+
* Copyright (c) 2013-2017 by JimF
5+
* and it is hereby released to the general public under the following terms:
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted.
118
*/
129

1310
#if FMT_EXTERNS_H
@@ -20,7 +17,6 @@ john_register_one(&fmt_rawMD4);
2017

2118
#include "arch.h"
2219

23-
2420
#if !FAST_FORMATS_OMP
2521
#undef _OPENMP
2622
#endif
@@ -32,6 +28,7 @@ john_register_one(&fmt_rawMD4);
3228
#include "common.h"
3329
#include "johnswap.h"
3430
#include "formats.h"
31+
#include "base64_convert.h"
3532
#define REVERSE_STEPS
3633
#include "simd-intrinsics.h"
3734

@@ -63,6 +60,8 @@ john_register_one(&fmt_rawMD4);
6360

6461
#define FORMAT_TAG "$MD4$"
6562
#define TAG_LENGTH (sizeof(FORMAT_TAG) - 1)
63+
#define FORMAT_TAG2 "{MD4}"
64+
#define FORMAT_TAG2_LEN (sizeof(FORMAT_TAG2) - 1)
6665

6766
static struct fmt_tests tests[] = {
6867
{"8a9d093f14f8701df17732b2bb182c74", "password"},
@@ -85,6 +84,7 @@ static struct fmt_tests tests[] = {
8584
{"114c5a33b8d4127fbe492bd6583aeb4d", "12"},
8685
{"c58cda49f00748a3bc0fcfa511d516cb", "123"},
8786
{"f375f401ddc698af533f16f8ac1e91c1", "1234"},
87+
{"{MD4}2zRtaR16zE3CYl2xn54/Ug==", "test"},
8888
{NULL}
8989
};
9090

@@ -135,12 +135,30 @@ static void done(void)
135135
#endif
136136
}
137137

138+
/* Convert {MD4}2zRtaR16zE3CYl2xn54/Ug== to db346d691d7acc4dc2625db19f9e3f52 */
139+
static char *prepare(char *fields[10], struct fmt_main *self)
140+
{
141+
static char out[CIPHERTEXT_LENGTH + 1];
142+
143+
if (!strncmp(fields[1], FORMAT_TAG2, FORMAT_TAG2_LEN) && strlen(fields[1]) == FORMAT_TAG2_LEN+24) {
144+
int res;
145+
146+
res = base64_convert(&fields[1][FORMAT_TAG2_LEN], e_b64_mime, 24,
147+
out, e_b64_hex, sizeof(out),
148+
flg_Base64_HEX_LOCASE, 0);
149+
if (res >= 0)
150+
return out;
151+
}
152+
153+
return fields[1];
154+
}
155+
138156
static int valid(char *ciphertext, struct fmt_main *self)
139157
{
140158
char *p, *q;
141159

142160
p = ciphertext;
143-
if (!strncmp(p, FORMAT_TAG, TAG_LENGTH))
161+
if (*p == '$' && !strncmp(p, FORMAT_TAG, TAG_LENGTH))
144162
p += TAG_LENGTH;
145163

146164
q = p;
@@ -158,6 +176,7 @@ static char *split(char *ciphertext, int index, struct fmt_main *self)
158176
ciphertext += TAG_LENGTH;
159177

160178
memcpylwr(out + TAG_LENGTH, ciphertext, CIPHERTEXT_LENGTH + 1);
179+
161180
return out;
162181
}
163182

@@ -360,13 +379,13 @@ struct fmt_main fmt_rawMD4 = {
360379
#endif
361380
FMT_CASE | FMT_8_BIT | FMT_SPLIT_UNIFIES_CASE,
362381
{ NULL },
363-
{ FORMAT_TAG },
382+
{ FORMAT_TAG, FORMAT_TAG2 },
364383
tests
365384
}, {
366385
init,
367386
done,
368387
fmt_default_reset,
369-
fmt_default_prepare,
388+
prepare,
370389
valid,
371390
split,
372391
get_binary,

src/rawMD5_fmt_plug.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
/*
2-
* Raw-MD5 (thick) based on Raw-MD4 w/ mmx/sse/intrinsics
3-
* This software is Copyright (c) 2011 magnum, and it is hereby released to the
4-
* general public under the following terms: Redistribution and use in source
5-
* and binary forms, with or without modification, are permitted.
6-
*
7-
* OMP added May 2013, JimF
8-
* BE SIMD logic added 2017, JimF
2+
* This software is
3+
* Copyright (c) 2011-2025 magnum
4+
* Copyright (c) 2013-2017 by JimF
5+
* and it is hereby released to the general public under the following terms:
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted.
98
*/
109

1110
#if FMT_EXTERNS_H
@@ -17,6 +16,7 @@ john_register_one(&fmt_rawMD5);
1716
#include <string.h>
1817

1918
#include "arch.h"
19+
2020
#if !FAST_FORMATS_OMP
2121
#undef _OPENMP
2222
#endif
@@ -33,7 +33,7 @@ john_register_one(&fmt_rawMD5);
3333
#include "simd-intrinsics.h"
3434

3535
#ifndef OMP_SCALE
36-
#define OMP_SCALE 16 // Tuned after MKPC for core i7 incl non-SIMD
36+
#define OMP_SCALE 16
3737
#endif
3838

3939
#define FORMAT_LABEL "Raw-MD5"
@@ -254,7 +254,6 @@ static int crypt_all(int *pcount, struct db_salt *salt)
254254
{
255255
const int count = *pcount;
256256
int index;
257-
258257
int loops = (count + MIN_KEYS_PER_CRYPT - 1) / MIN_KEYS_PER_CRYPT;
259258

260259
#ifdef _OPENMP
@@ -270,6 +269,7 @@ static int crypt_all(int *pcount, struct db_salt *salt)
270269
MD5_Final((unsigned char *)crypt_key[index], &ctx);
271270
#endif
272271
}
272+
273273
return count;
274274
}
275275

@@ -283,6 +283,7 @@ static int cmp_all(void *binary, int count) {
283283
if ( ((uint32_t*)binary)[0] == ((uint32_t*)crypt_key)[y*SIMD_COEF_32*4+x] )
284284
return 1;
285285
}
286+
286287
return 0;
287288
#else
288289
unsigned int index;

0 commit comments

Comments
 (0)