|
1 | 1 | /*
|
2 |
| - This code was largely inspired by |
3 |
| - pyrit opencl kernel sha1 routines, royger's sha1 sample, |
4 |
| - and md5_opencl_kernel.cl inside jtr. |
5 |
| - Copyright 2011 by Samuele Giovanni Tonon |
6 |
| - samu at linuxasylum dot net |
7 |
| - and Copyright (c) 2012-2017, magnum |
8 |
| - This program comes with ABSOLUTELY NO WARRANTY; express or |
9 |
| - implied . |
10 |
| - This is free software, and you are welcome to redistribute it |
11 |
| - under certain conditions; as expressed here |
12 |
| - http://www.gnu.org/licenses/gpl-2.0.html |
13 |
| -*/ |
14 |
| - |
15 |
| -/* |
16 |
| - * Modifications (c) 2014 Harrison Neal. |
17 |
| - * Licensed GPLv2 |
| 2 | + * This code was largely inspired by |
| 3 | + * pyrit opencl kernel sha1 routines, royger's sha1 sample, |
| 4 | + * and md5_opencl_kernel.cl inside jtr. |
| 5 | + * Copyright (c) 2012-2025, magnum |
| 6 | + * Copyright (c) 2014 Harrison Neal |
| 7 | + * Copyright (c) 2011 by Samuele Giovanni Tonon, samu at linuxasylum dot net |
| 8 | + * |
| 9 | + * This program comes with ABSOLUTELY NO WARRANTY; express or |
| 10 | + * implied . |
| 11 | + * This is free software, and you are welcome to redistribute it |
| 12 | + * under certain conditions; as expressed here |
| 13 | + * http://www.gnu.org/licenses/gpl-2.0.html |
18 | 14 | */
|
19 | 15 |
|
20 | 16 | #include "opencl_device_info.h"
|
21 | 17 | #include "opencl_misc.h"
|
22 | 18 | #include "opencl_sha1.h"
|
23 |
| -#define AES_SRC_TYPE __constant |
| 19 | +#include "opencl_md5_ctx.h" |
| 20 | +#include "opencl_mask.h" |
| 21 | + |
| 22 | +// Workaround for UHD Graphics 630 version "1.2(Jan 10 2025 21:16:54)" |
| 23 | +#if (__OS_X__ && gpu_intel(DEVICE_INFO)) |
| 24 | +#define AES_BITSLICE 1 |
| 25 | +#endif |
24 | 26 | #include "opencl_aes.h"
|
25 | 27 |
|
26 | 28 | typedef struct {
|
27 |
| - uint salt[3]; // ((SALT_LENGTH + 3)/4) |
28 |
| - uchar ct[48]; // CIPHERTEXT_LENGTH |
29 |
| -} salt_t; |
| 29 | + uint pw_len; /* AUTH_PASSWORD length (blocks) */ |
| 30 | + uint salt[(SALT_LENGTH + 1 + 3) / 4]; /* AUTH_VFR_DATA */ |
| 31 | + uchar ct[CIPHERTEXT_LENGTH]; /* Server's AUTH_SESSKEY */ |
| 32 | + uchar csk[CIPHERTEXT_LENGTH]; /* Client's AUTH_SESSKEY */ |
| 33 | + uchar pw[PLAINTEXT_LENGTH + 16]; /* Client's AUTH_PASSWORD, padded */ |
| 34 | +} o5logon_salt; |
30 | 35 |
|
31 | 36 | __kernel void
|
32 |
| -o5logon_kernel(__global const uint *keys, __constant salt_t *salt, |
33 |
| - __global const uint *index, __global uint *result) |
| 37 | +o5logon_kernel(__global const uchar* key_buf, __global const uint* const key_idx, |
| 38 | + __constant o5logon_salt* salt, |
| 39 | + __global volatile uint* crack_count_ret, |
| 40 | + __global uint* const out_index, |
| 41 | + __global const uint* const int_key_loc, |
| 42 | + __global const uint* const int_keys) |
34 | 43 | {
|
35 | 44 | __local aes_local_t lt;
|
36 | 45 | AES_KEY akey; akey.lt = <
|
37 |
| - uint W[16] = { 0 }, salt_s[3], output[5]; |
38 |
| - uint gid = get_global_id(0); |
39 |
| - uint base = index[gid]; |
40 |
| - uint len = base & 63; |
41 |
| - uint i; |
42 |
| - uint shift = len % 4; |
43 |
| - uint sr = 8 * shift; |
44 |
| - uint sl = 32 - sr; |
45 |
| - uint sra = (0xffffffff - (1 << sr)) + 1; |
46 |
| - uint sla = 0xffffffff - sra; |
47 |
| - union { |
48 |
| - uchar c[24]; |
49 |
| - uint w[24 / 4]; |
50 |
| - } aes_key; |
51 |
| - union { |
52 |
| - uchar c[16]; |
53 |
| - ulong l[16 / 8]; |
54 |
| - } pt; |
55 |
| - uchar iv[16]; |
56 |
| - |
57 |
| - keys += base >> 6; |
58 |
| - |
59 |
| - for (i = 0; i < (len + 3) / 4; i++) |
60 |
| - W[i] = SWAP32(*keys++); |
61 |
| - |
62 |
| - // Do the typical byte swapping... |
63 |
| - for (i = 0; i < 3; i++) |
64 |
| - salt_s[i] = SWAP32(salt->salt[i]); |
65 |
| - |
66 |
| - // Shift the salt bytes into place after the given key. |
67 |
| - W[len / 4] |= (salt_s[0] & sra) >> sr; |
68 |
| - W[len / 4 + 1] = ((salt_s[0] & sla) << sl) | ((salt_s[1] & sra) >> sr); |
69 |
| - W[len / 4 + 2] = ((salt_s[1] & sla) << sl) | ((salt_s[2] & sra) >> sr); |
70 |
| - W[len / 4 + 3] = (salt_s[2] & sla) << sl; |
71 |
| - |
72 |
| - // The 0x80 ending character was added to the salt before we receive it |
73 |
| - |
74 |
| - W[15] = (len + 10) << 3; |
75 |
| - |
76 |
| - sha1_single(uint, W, output); |
77 |
| - |
78 |
| - for (i = 0; i < 5; i++) |
79 |
| - aes_key.w[i] = SWAP32(output[i]); |
80 |
| - aes_key.w[5] = 0; |
81 |
| - |
82 |
| - for (i = 0; i < 16; i++) |
83 |
| - iv[i] = salt->ct[16 + i]; |
84 |
| - |
85 |
| - AES_set_decrypt_key(aes_key.c, 192, &akey); |
86 |
| - AES_cbc_decrypt(&salt->ct[32], pt.c, 16, &akey, iv); |
87 |
| - |
88 |
| - result[gid] = (pt.l[1] == 0x0808080808080808UL); |
| 46 | + |
| 47 | + const uint gid = get_global_id(0); |
| 48 | + |
| 49 | +#if NUM_INT_KEYS > 1 && !IS_STATIC_GPU_MASK |
| 50 | + const uint ikl = int_key_loc[gid]; |
| 51 | + const uint loc0 = ikl & 0xff; |
| 52 | +#if MASK_FMT_INT_PLHDR > 1 |
| 53 | +#if LOC_1 >= 0 |
| 54 | + const uint loc1 = (ikl & 0xff00) >> 8; |
| 55 | +#endif |
| 56 | +#endif |
| 57 | +#if MASK_FMT_INT_PLHDR > 2 |
| 58 | +#if LOC_2 >= 0 |
| 59 | + const uint loc2 = (ikl & 0xff0000) >> 16; |
| 60 | +#endif |
| 61 | +#endif |
| 62 | +#if MASK_FMT_INT_PLHDR > 3 |
| 63 | +#if LOC_3 >= 0 |
| 64 | + const uint loc3 = (ikl & 0xff000000) >> 24; |
| 65 | +#endif |
| 66 | +#endif |
| 67 | +#endif |
| 68 | + |
| 69 | +#if !IS_STATIC_GPU_MASK |
| 70 | +#define GPU_LOC_0 loc0 |
| 71 | +#define GPU_LOC_1 loc1 |
| 72 | +#define GPU_LOC_2 loc2 |
| 73 | +#define GPU_LOC_3 loc3 |
| 74 | +#else |
| 75 | +#define GPU_LOC_0 LOC_0 |
| 76 | +#define GPU_LOC_1 LOC_1 |
| 77 | +#define GPU_LOC_2 LOC_2 |
| 78 | +#define GPU_LOC_3 LOC_3 |
| 79 | +#endif |
| 80 | + |
| 81 | + const uint base = key_idx[gid]; |
| 82 | + const uint len = key_idx[gid + 1] - base; |
| 83 | + |
| 84 | + /* Protect from possible mayhem due to a rounded-up GWS using stale data */ |
| 85 | + if (len > PLAINTEXT_LENGTH) |
| 86 | + return; |
| 87 | + |
| 88 | + key_buf += base; |
| 89 | + |
| 90 | + const uint shift = len % 4; |
| 91 | + const uint sr = 8 * shift; |
| 92 | + const uint sl = 32 - sr; |
| 93 | + const uint sra = (0xffffffff - (1 << sr)) + 1; |
| 94 | + const uint sla = 0xffffffff - sra; |
| 95 | + |
| 96 | + // Endian swap salt |
| 97 | + uint salt_be[sizeof(salt->salt) / 4]; |
| 98 | + for (uint i = 0; i < sizeof(salt->salt) / 4; i++) |
| 99 | + salt_be[i] = SWAP32(salt->salt[i]); |
| 100 | + |
| 101 | + for (uint idx = 0; idx < NUM_INT_KEYS; idx++) { |
| 102 | + const uint gidx = gid * NUM_INT_KEYS + idx; |
| 103 | + uchar password[PLAINTEXT_LENGTH] = { 0 }; |
| 104 | + uint i; |
| 105 | + |
| 106 | + for (i = 0; i < len; i++) |
| 107 | + password[i] = key_buf[i]; |
| 108 | + |
| 109 | +#if NUM_INT_KEYS > 1 |
| 110 | + password[GPU_LOC_0] = (int_keys[idx] & 0xff); |
| 111 | +#if MASK_FMT_INT_PLHDR > 1 |
| 112 | +#if LOC_1 >= 0 |
| 113 | + password[GPU_LOC_1] = (int_keys[idx] & 0xff >> 8); |
| 114 | +#endif |
| 115 | +#endif |
| 116 | +#if MASK_FMT_INT_PLHDR > 2 |
| 117 | +#if LOC_2 >= 0 |
| 118 | + password[GPU_LOC_2] = (int_keys[idx] & 0xff >> 16); |
| 119 | +#endif |
| 120 | +#endif |
| 121 | +#if MASK_FMT_INT_PLHDR > 3 |
| 122 | +#if LOC_3 >= 0 |
| 123 | + password[GPU_LOC_3] = (int_keys[idx] & 0xff >> 24); |
| 124 | +#endif |
| 125 | +#endif |
| 126 | +#endif |
| 127 | + uint W[16] = { 0 }; |
| 128 | + for (i = 0; i < PLAINTEXT_LENGTH / 4; i++) |
| 129 | + GET_UINT32BE(W[i], password, 4 * i); |
| 130 | + |
| 131 | + // Shift the salt bytes into place after the given key. |
| 132 | + W[len / 4] |= (salt_be[0] & sra) >> sr; |
| 133 | + W[len / 4 + 1] = ((salt_be[0] & sla) << sl) | ((salt_be[1] & sra) >> sr); |
| 134 | + W[len / 4 + 2] = ((salt_be[1] & sla) << sl) | ((salt_be[2] & sra) >> sr); |
| 135 | + W[len / 4 + 3] = (salt_be[2] & sla) << sl; |
| 136 | + |
| 137 | + // The Merkel-Damgård 0x80 ending byte was already added to the salt |
| 138 | + // on host side, here's the length. |
| 139 | + W[15] = (len + 10) << 3; |
| 140 | + |
| 141 | + uint output[160 / 32]; |
| 142 | + sha1_single(uint, W, output); |
| 143 | + |
| 144 | + union { |
| 145 | + uchar c[192 / 8]; |
| 146 | + uint w[0]; |
| 147 | + } key; |
| 148 | + for (i = 0; i < 5; i++) |
| 149 | + key.w[i] = SWAP32(output[i]); |
| 150 | + key.w[5] = 0; |
| 151 | + |
| 152 | + uchar iv[16]; |
| 153 | + |
| 154 | + AES_set_decrypt_key(key.c, 192, &akey); |
| 155 | + |
| 156 | + if (salt->pw_len) { |
| 157 | + const uint blen = (len + 15) / 16; |
| 158 | + |
| 159 | + // Early reject |
| 160 | + if (salt->pw_len != blen) |
| 161 | + return; |
| 162 | + |
| 163 | + uchar s_secret[CIPHERTEXT_LENGTH]; |
| 164 | + uchar ct[CIPHERTEXT_LENGTH]; |
| 165 | + memcpy_cp(ct, salt->ct, CIPHERTEXT_LENGTH); |
| 166 | + memset_p(iv, 0, 16); |
| 167 | + //AES_set_decrypt_key(key.c, 192, &akey); |
| 168 | + AES_cbc_decrypt(ct, s_secret, CIPHERTEXT_LENGTH, &akey, iv); |
| 169 | + |
| 170 | + uchar c_secret[CIPHERTEXT_LENGTH]; |
| 171 | + uchar csk[CIPHERTEXT_LENGTH]; |
| 172 | + memcpy_cp(csk, salt->csk, CIPHERTEXT_LENGTH); |
| 173 | + memset_p(iv, 0, 16); |
| 174 | + //AES_set_decrypt_key(key.c, 192, &akey); |
| 175 | + AES_cbc_decrypt(csk, c_secret, CIPHERTEXT_LENGTH, &akey, iv); |
| 176 | + |
| 177 | + uchar combined_sk[24]; |
| 178 | + for (i = 0; i < 24; i++) |
| 179 | + combined_sk[i] = s_secret[16 + i] ^ c_secret[16 + i]; |
| 180 | + |
| 181 | + uchar final_key[32]; |
| 182 | + MD5_CTX ctx; |
| 183 | + MD5_Init(&ctx); |
| 184 | + MD5_Update(&ctx, combined_sk, 16); |
| 185 | + MD5_Final(final_key, &ctx); |
| 186 | + MD5_Init(&ctx); |
| 187 | + MD5_Update(&ctx, combined_sk + 16, 8); |
| 188 | + MD5_Final(final_key + 16, &ctx); |
| 189 | + |
| 190 | + memcpy_cp(iv, salt->pw, 16); |
| 191 | + |
| 192 | + uchar pw[PLAINTEXT_LENGTH]; |
| 193 | + memcpy_cp(pw, salt->pw + 16, PLAINTEXT_LENGTH); |
| 194 | + |
| 195 | + uchar dec_pw[PLAINTEXT_LENGTH + 16]; |
| 196 | + AES_set_decrypt_key(final_key, 192, &akey); |
| 197 | + AES_cbc_decrypt(pw, dec_pw, salt->pw_len * 16, &akey, iv); |
| 198 | + |
| 199 | + if (!memcmp_pp(dec_pw, password, len) && |
| 200 | + check_pkcs_pad(dec_pw, salt->pw_len * 16, AES_BLOCK_SIZE)) |
| 201 | + out_index[atomic_inc(crack_count_ret)] = gidx; |
| 202 | + } else { |
| 203 | + union { |
| 204 | + uchar c[16]; |
| 205 | + ulong l[0]; |
| 206 | + } pt; |
| 207 | + |
| 208 | + memcpy_cp(iv, &salt->ct[16], 16); |
| 209 | + uchar ct[16]; |
| 210 | + memcpy_cp(ct, &salt->ct[32], 16); |
| 211 | + //AES_set_decrypt_key(key.c, 192, &akey); |
| 212 | + AES_cbc_decrypt(ct, pt.c, 16, &akey, iv); |
| 213 | + |
| 214 | + if (pt.l[1] == 0x0808080808080808UL) |
| 215 | + out_index[atomic_inc(crack_count_ret)] = gidx; |
| 216 | + } |
| 217 | + } |
89 | 218 | }
|
0 commit comments