diff --git a/OpenCL/m23700-optimized.cl b/OpenCL/m23700-optimized.cl new file mode 100644 index 000000000..316886fe0 --- /dev/null +++ b/OpenCL/m23700-optimized.cl @@ -0,0 +1,561 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +#ifdef KERNEL_STATIC +#include "inc_vendor.h" +#include "inc_types.h" +#include "inc_platform.cl" +#include "inc_common.cl" +#include "inc_hash_sha1.cl" +#include "inc_cipher_aes.cl" +#endif + +#define COMPARE_S "inc_comp_single.cl" +#define COMPARE_M "inc_comp_multi.cl" + +#define ROUNDS 0x40000 + +#define PUTCHAR(a,p,c) ((u8 *)(a))[(p)] = (u8) (c) +#define GETCHAR(a,p) ((u8 *)(a))[(p)] + +#define PUTCHAR_BE(a,p,c) ((u8 *)(a))[(p) ^ 3] = (u8) (c) +#define GETCHAR_BE(a,p) ((u8 *)(a))[(p) ^ 3] + +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +typedef struct rar3 +{ + u32 data[81920]; + + u32 pack_size; + u32 unpack_size; + +} rar3_t; + +typedef struct rar3_tmp +{ + u32 dgst[17][5]; + +} rar3_tmp_t; + +CONSTANT_VK u32a crc32tab[0x100] = +{ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +DECLSPEC u32 round_crc32 (const u32 a, const u32 v, LOCAL_AS u32 *l_crc32tab) +{ + const u32 k = (a ^ v) & 0xff; + + const u32 s = a >> 8; + + return l_crc32tab[k] ^ s; +} + +DECLSPEC u32 round_crc32_16 (const u32 crc32, const u32 *buf, const u32 len, LOCAL_AS u32 *l_crc32tab) +{ + const int crc_len = MIN (len, 16); + + u32 c = crc32; + + for (int i = 0; i < crc_len; i++) + { + const u32 idx = i / 4; + const u32 mod = i % 4; + const u32 sht = (3 - mod) * 8; + + const u32 b = buf[idx] >> sht; // b & 0xff (but already done in round_crc32 ()) + + c = round_crc32 (c, b, l_crc32tab); + } + + return c; +} + +KERNEL_FQ void m23700_init (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) +{ + /** + * base + */ + + const u64 gid = get_global_id (0); + + if (gid >= gid_max) return; + + tmps[gid].dgst[0][0] = SHA1M_A; + tmps[gid].dgst[0][1] = SHA1M_B; + tmps[gid].dgst[0][2] = SHA1M_C; + tmps[gid].dgst[0][3] = SHA1M_D; + tmps[gid].dgst[0][4] = SHA1M_E; +} + +KERNEL_FQ void m23700_loop (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) +{ + const u64 gid = get_global_id (0); + + if (gid >= gid_max) return; + + u32 pw_buf[5]; + + pw_buf[0] = pws[gid].i[0]; + pw_buf[1] = pws[gid].i[1]; + pw_buf[2] = pws[gid].i[2]; + pw_buf[3] = pws[gid].i[3]; + pw_buf[4] = pws[gid].i[4]; + + const u32 pw_len = MIN (pws[gid].pw_len, 20); + + u32 salt_buf[2]; + + salt_buf[0] = salt_bufs[salt_pos].salt_buf[0]; + salt_buf[1] = salt_bufs[salt_pos].salt_buf[1]; + + const u32 salt_len = 8; + + // this is large enough to hold all possible w[] arrays for 64 iterations + + #define LARGEBLOCK_ELEMS ((40 + 8 + 3) * 16) + + u32 largeblock[LARGEBLOCK_ELEMS]; + + for (u32 i = 0; i < LARGEBLOCK_ELEMS; i++) largeblock[i] = 0; + + for (u32 i = 0, p = 0; i < 64; i++) + { + for (u32 j = 0; j < pw_len; j++, p += 2) + { + PUTCHAR_BE (largeblock, p, GETCHAR (pw_buf, j)); + } + + for (u32 j = 0; j < salt_len; j++, p += 1) + { + PUTCHAR_BE (largeblock, p, GETCHAR (salt_buf, j)); + } + + PUTCHAR_BE (largeblock, p + 2, (loop_pos >> 16) & 0xff); + + p += 3; + } + + const u32 p3 = (pw_len * 2) + salt_len + 3; + + const u32 init_pos = loop_pos / (ROUNDS / 16); + + u32 dgst[5]; + + dgst[0] = tmps[gid].dgst[init_pos][0]; + dgst[1] = tmps[gid].dgst[init_pos][1]; + dgst[2] = tmps[gid].dgst[init_pos][2]; + dgst[3] = tmps[gid].dgst[init_pos][3]; + dgst[4] = tmps[gid].dgst[init_pos][4]; + + u32 iter = loop_pos; + + for (u32 i = 0; i < 256; i += 4) + { + for (u32 j = 0; j < 64; j++) + { + const u32 p = ((j + 1) * p3) - 2; + + PUTCHAR_BE (largeblock, p, iter >> 8); + } + + for (u32 k = 0; k < 4; k++) + { + for (u32 j = 0; j < 64; j++) + { + const u32 p = ((j + 1) * p3) - 3; + + PUTCHAR_BE (largeblock, p, iter >> 0); + + iter++; + } + + for (u32 j = 0; j < p3; j++) + { + const u32 j16 = j * 16; + + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + w0[0] = largeblock[j16 + 0]; + w0[1] = largeblock[j16 + 1]; + w0[2] = largeblock[j16 + 2]; + w0[3] = largeblock[j16 + 3]; + w1[0] = largeblock[j16 + 4]; + w1[1] = largeblock[j16 + 5]; + w1[2] = largeblock[j16 + 6]; + w1[3] = largeblock[j16 + 7]; + w2[0] = largeblock[j16 + 8]; + w2[1] = largeblock[j16 + 9]; + w2[2] = largeblock[j16 + 10]; + w2[3] = largeblock[j16 + 11]; + w3[0] = largeblock[j16 + 12]; + w3[1] = largeblock[j16 + 13]; + w3[2] = largeblock[j16 + 14]; + w3[3] = largeblock[j16 + 15]; + + sha1_transform (w0, w1, w2, w3, dgst); + } + } + } + + tmps[gid].dgst[init_pos + 1][0] = dgst[0]; + tmps[gid].dgst[init_pos + 1][1] = dgst[1]; + tmps[gid].dgst[init_pos + 1][2] = dgst[2]; + tmps[gid].dgst[init_pos + 1][3] = dgst[3]; + tmps[gid].dgst[init_pos + 1][4] = dgst[4]; +} + +KERNEL_FQ void m23700_comp (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) +{ + const u64 gid = get_global_id (0); + const u64 lid = get_local_id (0); + const u64 lsz = get_local_size (0); + + /** + * aes shared + */ + + #ifdef REAL_SHM + + LOCAL_VK u32 s_td0[256]; + LOCAL_VK u32 s_td1[256]; + LOCAL_VK u32 s_td2[256]; + LOCAL_VK u32 s_td3[256]; + LOCAL_VK u32 s_td4[256]; + + LOCAL_VK u32 s_te0[256]; + LOCAL_VK u32 s_te1[256]; + LOCAL_VK u32 s_te2[256]; + LOCAL_VK u32 s_te3[256]; + LOCAL_VK u32 s_te4[256]; + + for (u32 i = lid; i < 256; i += lsz) + { + s_td0[i] = td0[i]; + s_td1[i] = td1[i]; + s_td2[i] = td2[i]; + s_td3[i] = td3[i]; + s_td4[i] = td4[i]; + + s_te0[i] = te0[i]; + s_te1[i] = te1[i]; + s_te2[i] = te2[i]; + s_te3[i] = te3[i]; + s_te4[i] = te4[i]; + } + + #else + + CONSTANT_AS u32a *s_td0 = td0; + CONSTANT_AS u32a *s_td1 = td1; + CONSTANT_AS u32a *s_td2 = td2; + CONSTANT_AS u32a *s_td3 = td3; + CONSTANT_AS u32a *s_td4 = td4; + + CONSTANT_AS u32a *s_te0 = te0; + CONSTANT_AS u32a *s_te1 = te1; + CONSTANT_AS u32a *s_te2 = te2; + CONSTANT_AS u32a *s_te3 = te3; + CONSTANT_AS u32a *s_te4 = te4; + + #endif + + LOCAL_VK u32 l_crc32tab[256]; + + for (int i = lid; i < 256; i += lsz) + { + l_crc32tab[i] = crc32tab[i]; + } + + SYNC_THREADS (); + + if (gid >= gid_max) return; + + /** + * base + */ + + const u32 pw_len = MIN (pws[gid].pw_len, 20); + + const u32 salt_len = 8; + + const u32 p3 = (pw_len * 2) + salt_len + 3; + + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + w0[0] = 0x80000000; + w0[1] = 0; + w0[2] = 0; + w0[3] = 0; + w1[0] = 0; + w1[1] = 0; + w1[2] = 0; + w1[3] = 0; + w2[0] = 0; + w2[1] = 0; + w2[2] = 0; + w2[3] = 0; + w3[0] = 0; + w3[1] = 0; + w3[2] = 0; + w3[3] = (p3 * ROUNDS) * 8; + + u32 dgst[5]; + + dgst[0] = tmps[gid].dgst[16][0]; + dgst[1] = tmps[gid].dgst[16][1]; + dgst[2] = tmps[gid].dgst[16][2]; + dgst[3] = tmps[gid].dgst[16][3]; + dgst[4] = tmps[gid].dgst[16][4]; + + sha1_transform (w0, w1, w2, w3, dgst); + + u32 ukey[4]; + + ukey[0] = hc_swap32_S (dgst[0]); + ukey[1] = hc_swap32_S (dgst[1]); + ukey[2] = hc_swap32_S (dgst[2]); + ukey[3] = hc_swap32_S (dgst[3]); + + u32 ks[44]; + + AES128_set_decrypt_key (ks, ukey, s_te0, s_te1, s_te2, s_te3, s_td0, s_td1, s_td2, s_td3); + + u32 iv[4]; + + iv[0] = 0; + iv[1] = 0; + iv[2] = 0; + iv[3] = 0; + + for (int i = 0; i < 16; i++) + { + u32 pw_buf[5]; + + pw_buf[0] = pws[gid].i[0]; + pw_buf[1] = pws[gid].i[1]; + pw_buf[2] = pws[gid].i[2]; + pw_buf[3] = pws[gid].i[3]; + pw_buf[4] = pws[gid].i[4]; + + //const u32 pw_len = pws[gid].pw_len; + + u32 salt_buf[2]; + + salt_buf[0] = salt_bufs[salt_pos].salt_buf[0]; + salt_buf[1] = salt_bufs[salt_pos].salt_buf[1]; + + //const u32 salt_len = 8; + + //const u32 p3 = (pw_len * 2) + salt_len + 3; + + u32 w[16]; + + w[ 0] = 0; + w[ 1] = 0; + w[ 2] = 0; + w[ 3] = 0; + w[ 4] = 0; + w[ 5] = 0; + w[ 6] = 0; + w[ 7] = 0; + w[ 8] = 0; + w[ 9] = 0; + w[10] = 0; + w[11] = 0; + w[12] = 0; + w[13] = 0; + w[14] = 0; + w[15] = 0; + + u32 p = 0; + + for (u32 j = 0; j < pw_len; j++, p += 2) + { + PUTCHAR_BE (w, p, GETCHAR (pw_buf, j)); + } + + for (u32 j = 0; j < salt_len; j++, p += 1) + { + PUTCHAR_BE (w, p, GETCHAR (salt_buf, j)); + } + + const u32 iter_pos = i * (ROUNDS / 16); + + PUTCHAR_BE (w, p + 0, (iter_pos >> 0) & 0xff); + PUTCHAR_BE (w, p + 1, (iter_pos >> 8) & 0xff); + PUTCHAR_BE (w, p + 2, (iter_pos >> 16) & 0xff); + + PUTCHAR_BE (w, p3, 0x80); + + w[15] = ((iter_pos + 1) * p3) * 8; + + u32 dgst[5]; + + dgst[0] = tmps[gid].dgst[i][0]; + dgst[1] = tmps[gid].dgst[i][1]; + dgst[2] = tmps[gid].dgst[i][2]; + dgst[3] = tmps[gid].dgst[i][3]; + dgst[4] = tmps[gid].dgst[i][4]; + + sha1_transform (w + 0, w + 4, w + 8, w + 12, dgst); + + PUTCHAR (iv, i, dgst[4] & 0xff); + } + + iv[0] = hc_swap32_S (iv[0]); + iv[1] = hc_swap32_S (iv[1]); + iv[2] = hc_swap32_S (iv[2]); + iv[3] = hc_swap32_S (iv[3]); + + const u32 pack_size = esalt_bufs[digests_offset].pack_size; + const u32 unpack_size = esalt_bufs[digests_offset].unpack_size; + + if (pack_size > unpack_size) // could be aligned + { + if (pack_size >= 32) // otherwise IV... + { + const u32 pack_size_elements = pack_size / 4; + + u32 last_block_encrypted[4]; + + last_block_encrypted[0] = esalt_bufs[digests_offset].data[pack_size_elements - 4 + 0]; + last_block_encrypted[1] = esalt_bufs[digests_offset].data[pack_size_elements - 4 + 1]; + last_block_encrypted[2] = esalt_bufs[digests_offset].data[pack_size_elements - 4 + 2]; + last_block_encrypted[3] = esalt_bufs[digests_offset].data[pack_size_elements - 4 + 3]; + + u32 last_block_decrypted[4]; + + AES128_decrypt (ks, last_block_encrypted, last_block_decrypted, s_td0, s_td1, s_td2, s_td3, s_td4); + + u32 last_block_iv[4]; + + last_block_iv[0] = esalt_bufs[digests_offset].data[pack_size_elements - 8 + 0]; + last_block_iv[1] = esalt_bufs[digests_offset].data[pack_size_elements - 8 + 1]; + last_block_iv[2] = esalt_bufs[digests_offset].data[pack_size_elements - 8 + 2]; + last_block_iv[3] = esalt_bufs[digests_offset].data[pack_size_elements - 8 + 3]; + + last_block_decrypted[0] ^= last_block_iv[0]; + last_block_decrypted[1] ^= last_block_iv[1]; + last_block_decrypted[2] ^= last_block_iv[2]; + last_block_decrypted[3] ^= last_block_iv[3]; + + if ((last_block_decrypted[3] & 0xff) != 0) return; + } + } + + u32 data_left = unpack_size; + + u32 crc32 = ~0; + + for (u32 i = 0, j = 0; i < pack_size / 16; i += 1, j += 4) + { + u32 data[4]; + + data[0] = esalt_bufs[digests_offset].data[j + 0]; + data[1] = esalt_bufs[digests_offset].data[j + 1]; + data[2] = esalt_bufs[digests_offset].data[j + 2]; + data[3] = esalt_bufs[digests_offset].data[j + 3]; + + u32 out[4]; + + AES128_decrypt (ks, data, out, s_td0, s_td1, s_td2, s_td3, s_td4); + + out[0] ^= iv[0]; + out[1] ^= iv[1]; + out[2] ^= iv[2]; + out[3] ^= iv[3]; + + crc32 = round_crc32_16 (crc32, out, data_left, l_crc32tab); + + iv[0] = data[0]; + iv[1] = data[1]; + iv[2] = data[2]; + iv[3] = data[3]; + + data_left -= 16; + } + + const u32 r0 = crc32; + const u32 r1 = 0; + const u32 r2 = 0; + const u32 r3 = 0; + + #define il_pos 0 + + #ifdef KERNEL_STATIC + #include COMPARE_M + #endif +} diff --git a/OpenCL/m23700-pure.cl b/OpenCL/m23700-pure.cl new file mode 100644 index 000000000..5ccae0530 --- /dev/null +++ b/OpenCL/m23700-pure.cl @@ -0,0 +1,1273 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +#ifdef KERNEL_STATIC +#include "inc_vendor.h" +#include "inc_types.h" +#include "inc_platform.cl" +#include "inc_common.cl" +#include "inc_hash_sha1.cl" +#include "inc_cipher_aes.cl" +#endif + +#define COMPARE_S "inc_comp_single.cl" +#define COMPARE_M "inc_comp_multi.cl" + +#define ROUNDS 0x40000 + +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +typedef struct rar3 +{ + u32 data[81920]; + + u32 pack_size; + u32 unpack_size; + +} rar3_t; + +typedef struct rar3_tmp +{ + u32 dgst[5]; + + u32 w[66]; // 256 byte pass + 8 byte salt + + u32 iv[4]; + +} rar3_tmp_t; + +CONSTANT_VK u32a crc32tab[0x100] = +{ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +DECLSPEC u32 round_crc32 (const u32 a, const u32 v, LOCAL_AS u32 *l_crc32tab) +{ + const u32 k = (a ^ v) & 0xff; + + const u32 s = a >> 8; + + return l_crc32tab[k] ^ s; +} + +DECLSPEC u32 round_crc32_16 (const u32 crc32, const u32 *buf, const u32 len, LOCAL_AS u32 *l_crc32tab) +{ + const int crc_len = MIN (len, 16); + + u32 c = crc32; + + for (int i = 0; i < crc_len; i++) + { + const u32 idx = i / 4; + const u32 mod = i % 4; + const u32 sht = (3 - mod) * 8; + + const u32 b = buf[idx] >> sht; // b & 0xff (but already done in round_crc32 ()) + + c = round_crc32 (c, b, l_crc32tab); + } + + return c; +} + +DECLSPEC void memcat8c_be (u32 *w0, u32 *w1, u32 *w2, u32 *w3, const u32 len, const u32 append, u32 *digest) +{ + const u32 func_len = len & 63; + + //const u32 mod = func_len & 3; + const u32 div = func_len / 4; + + u32 tmp0; + u32 tmp1; + + #if defined IS_AMD || defined IS_GENERIC + tmp0 = hc_bytealign_be (0, append, func_len); + tmp1 = hc_bytealign_be (append, 0, func_len); + #endif + + #ifdef IS_NV + const int selector = (0x76543210 >> ((func_len & 3) * 4)) & 0xffff; + + tmp0 = hc_byte_perm (append, 0, selector); + tmp1 = hc_byte_perm (0, append, selector); + #endif + + u32 carry = 0; + + switch (div) + { + case 0: w0[0] |= tmp0; + w0[1] = tmp1; + break; + case 1: w0[1] |= tmp0; + w0[2] = tmp1; + break; + case 2: w0[2] |= tmp0; + w0[3] = tmp1; + break; + case 3: w0[3] |= tmp0; + w1[0] = tmp1; + break; + case 4: w1[0] |= tmp0; + w1[1] = tmp1; + break; + case 5: w1[1] |= tmp0; + w1[2] = tmp1; + break; + case 6: w1[2] |= tmp0; + w1[3] = tmp1; + break; + case 7: w1[3] |= tmp0; + w2[0] = tmp1; + break; + case 8: w2[0] |= tmp0; + w2[1] = tmp1; + break; + case 9: w2[1] |= tmp0; + w2[2] = tmp1; + break; + case 10: w2[2] |= tmp0; + w2[3] = tmp1; + break; + case 11: w2[3] |= tmp0; + w3[0] = tmp1; + break; + case 12: w3[0] |= tmp0; + w3[1] = tmp1; + break; + case 13: w3[1] |= tmp0; + w3[2] = tmp1; + break; + case 14: w3[2] |= tmp0; + w3[3] = tmp1; + break; + case 15: w3[3] |= tmp0; + carry = tmp1; + break; + } + + const u32 new_len = func_len + 3; + + if (new_len >= 64) + { + sha1_transform (w0, w1, w2, w3, digest); + + w0[0] = carry; + w0[1] = 0; + w0[2] = 0; + w0[3] = 0; + w1[0] = 0; + w1[1] = 0; + w1[2] = 0; + w1[3] = 0; + w2[0] = 0; + w2[1] = 0; + w2[2] = 0; + w2[3] = 0; + w3[0] = 0; + w3[1] = 0; + w3[2] = 0; + w3[3] = 0; + } +} + +// only change in this function compared to OpenCL/inc_hash_sha1.cl is that it returns +// the expanded 64 byte buffer w0_t..wf_t in t[]: + +DECLSPEC void sha1_transform_rar29 (const u32 *w0, const u32 *w1, const u32 *w2, const u32 *w3, u32 *digest, u32 *t) +{ + u32 a = digest[0]; + u32 b = digest[1]; + u32 c = digest[2]; + u32 d = digest[3]; + u32 e = digest[4]; + + #ifdef IS_CPU + + u32 w0_t = w0[0]; + u32 w1_t = w0[1]; + u32 w2_t = w0[2]; + u32 w3_t = w0[3]; + u32 w4_t = w1[0]; + u32 w5_t = w1[1]; + u32 w6_t = w1[2]; + u32 w7_t = w1[3]; + u32 w8_t = w2[0]; + u32 w9_t = w2[1]; + u32 wa_t = w2[2]; + u32 wb_t = w2[3]; + u32 wc_t = w3[0]; + u32 wd_t = w3[1]; + u32 we_t = w3[2]; + u32 wf_t = w3[3]; + + #define K SHA1C00 + + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, w0_t); + SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, w1_t); + SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, w2_t); + SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, w3_t); + SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, w4_t); + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, w5_t); + SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, w6_t); + SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, w7_t); + SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, w8_t); + SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, w9_t); + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, wa_t); + SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, wb_t); + SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, wc_t); + SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, wd_t); + SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, we_t); + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, wf_t); + w0_t = hc_rotl32_S ((wd_t ^ w8_t ^ w2_t ^ w0_t), 1u); SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, w0_t); + w1_t = hc_rotl32_S ((we_t ^ w9_t ^ w3_t ^ w1_t), 1u); SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, w1_t); + w2_t = hc_rotl32_S ((wf_t ^ wa_t ^ w4_t ^ w2_t), 1u); SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, w2_t); + w3_t = hc_rotl32_S ((w0_t ^ wb_t ^ w5_t ^ w3_t), 1u); SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, w3_t); + + #undef K + #define K SHA1C01 + + w4_t = hc_rotl32_S ((w1_t ^ wc_t ^ w6_t ^ w4_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w4_t); + w5_t = hc_rotl32_S ((w2_t ^ wd_t ^ w7_t ^ w5_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w5_t); + w6_t = hc_rotl32_S ((w3_t ^ we_t ^ w8_t ^ w6_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w6_t); + w7_t = hc_rotl32_S ((w4_t ^ wf_t ^ w9_t ^ w7_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w7_t); + w8_t = hc_rotl32_S ((w5_t ^ w0_t ^ wa_t ^ w8_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w8_t); + w9_t = hc_rotl32_S ((w6_t ^ w1_t ^ wb_t ^ w9_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w9_t); + wa_t = hc_rotl32_S ((w7_t ^ w2_t ^ wc_t ^ wa_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, wa_t); + wb_t = hc_rotl32_S ((w8_t ^ w3_t ^ wd_t ^ wb_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, wb_t); + wc_t = hc_rotl32_S ((w9_t ^ w4_t ^ we_t ^ wc_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, wc_t); + wd_t = hc_rotl32_S ((wa_t ^ w5_t ^ wf_t ^ wd_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, wd_t); + we_t = hc_rotl32_S ((wb_t ^ w6_t ^ w0_t ^ we_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, we_t); + wf_t = hc_rotl32_S ((wc_t ^ w7_t ^ w1_t ^ wf_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, wf_t); + w0_t = hc_rotl32_S ((wd_t ^ w8_t ^ w2_t ^ w0_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w0_t); + w1_t = hc_rotl32_S ((we_t ^ w9_t ^ w3_t ^ w1_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w1_t); + w2_t = hc_rotl32_S ((wf_t ^ wa_t ^ w4_t ^ w2_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w2_t); + w3_t = hc_rotl32_S ((w0_t ^ wb_t ^ w5_t ^ w3_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w3_t); + w4_t = hc_rotl32_S ((w1_t ^ wc_t ^ w6_t ^ w4_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w4_t); + w5_t = hc_rotl32_S ((w2_t ^ wd_t ^ w7_t ^ w5_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w5_t); + w6_t = hc_rotl32_S ((w3_t ^ we_t ^ w8_t ^ w6_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w6_t); + w7_t = hc_rotl32_S ((w4_t ^ wf_t ^ w9_t ^ w7_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w7_t); + + #undef K + #define K SHA1C02 + + w8_t = hc_rotl32_S ((w5_t ^ w0_t ^ wa_t ^ w8_t), 1u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, w8_t); + w9_t = hc_rotl32_S ((w6_t ^ w1_t ^ wb_t ^ w9_t), 1u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, w9_t); + wa_t = hc_rotl32_S ((w7_t ^ w2_t ^ wc_t ^ wa_t), 1u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, wa_t); + wb_t = hc_rotl32_S ((w8_t ^ w3_t ^ wd_t ^ wb_t), 1u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, wb_t); + wc_t = hc_rotl32_S ((w9_t ^ w4_t ^ we_t ^ wc_t), 1u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, wc_t); + wd_t = hc_rotl32_S ((wa_t ^ w5_t ^ wf_t ^ wd_t), 1u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, wd_t); + we_t = hc_rotl32_S ((wb_t ^ w6_t ^ w0_t ^ we_t), 1u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, we_t); + wf_t = hc_rotl32_S ((wc_t ^ w7_t ^ w1_t ^ wf_t), 1u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, wf_t); + w0_t = hc_rotl32_S ((wd_t ^ w8_t ^ w2_t ^ w0_t), 1u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, w0_t); + w1_t = hc_rotl32_S ((we_t ^ w9_t ^ w3_t ^ w1_t), 1u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, w1_t); + w2_t = hc_rotl32_S ((wf_t ^ wa_t ^ w4_t ^ w2_t), 1u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, w2_t); + w3_t = hc_rotl32_S ((w0_t ^ wb_t ^ w5_t ^ w3_t), 1u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, w3_t); + w4_t = hc_rotl32_S ((w1_t ^ wc_t ^ w6_t ^ w4_t), 1u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, w4_t); + w5_t = hc_rotl32_S ((w2_t ^ wd_t ^ w7_t ^ w5_t), 1u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, w5_t); + w6_t = hc_rotl32_S ((w3_t ^ we_t ^ w8_t ^ w6_t), 1u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, w6_t); + w7_t = hc_rotl32_S ((w4_t ^ wf_t ^ w9_t ^ w7_t), 1u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, w7_t); + w8_t = hc_rotl32_S ((w5_t ^ w0_t ^ wa_t ^ w8_t), 1u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, w8_t); + w9_t = hc_rotl32_S ((w6_t ^ w1_t ^ wb_t ^ w9_t), 1u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, w9_t); + wa_t = hc_rotl32_S ((w7_t ^ w2_t ^ wc_t ^ wa_t), 1u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, wa_t); + wb_t = hc_rotl32_S ((w8_t ^ w3_t ^ wd_t ^ wb_t), 1u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, wb_t); + + #undef K + #define K SHA1C03 + + wc_t = hc_rotl32_S ((w9_t ^ w4_t ^ we_t ^ wc_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, wc_t); + wd_t = hc_rotl32_S ((wa_t ^ w5_t ^ wf_t ^ wd_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, wd_t); + we_t = hc_rotl32_S ((wb_t ^ w6_t ^ w0_t ^ we_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, we_t); + wf_t = hc_rotl32_S ((wc_t ^ w7_t ^ w1_t ^ wf_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, wf_t); + w0_t = hc_rotl32_S ((wd_t ^ w8_t ^ w2_t ^ w0_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w0_t); + w1_t = hc_rotl32_S ((we_t ^ w9_t ^ w3_t ^ w1_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w1_t); + w2_t = hc_rotl32_S ((wf_t ^ wa_t ^ w4_t ^ w2_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w2_t); + w3_t = hc_rotl32_S ((w0_t ^ wb_t ^ w5_t ^ w3_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w3_t); + w4_t = hc_rotl32_S ((w1_t ^ wc_t ^ w6_t ^ w4_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w4_t); + w5_t = hc_rotl32_S ((w2_t ^ wd_t ^ w7_t ^ w5_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w5_t); + w6_t = hc_rotl32_S ((w3_t ^ we_t ^ w8_t ^ w6_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w6_t); + w7_t = hc_rotl32_S ((w4_t ^ wf_t ^ w9_t ^ w7_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w7_t); + w8_t = hc_rotl32_S ((w5_t ^ w0_t ^ wa_t ^ w8_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w8_t); + w9_t = hc_rotl32_S ((w6_t ^ w1_t ^ wb_t ^ w9_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w9_t); + wa_t = hc_rotl32_S ((w7_t ^ w2_t ^ wc_t ^ wa_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, wa_t); + wb_t = hc_rotl32_S ((w8_t ^ w3_t ^ wd_t ^ wb_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, wb_t); + wc_t = hc_rotl32_S ((w9_t ^ w4_t ^ we_t ^ wc_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, wc_t); + wd_t = hc_rotl32_S ((wa_t ^ w5_t ^ wf_t ^ wd_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, wd_t); + we_t = hc_rotl32_S ((wb_t ^ w6_t ^ w0_t ^ we_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, we_t); + wf_t = hc_rotl32_S ((wc_t ^ w7_t ^ w1_t ^ wf_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, wf_t); + + t[ 0] = w0_t; + t[ 1] = w1_t; + t[ 2] = w2_t; + t[ 3] = w3_t; + t[ 4] = w4_t; + t[ 5] = w5_t; + t[ 6] = w6_t; + t[ 7] = w7_t; + t[ 8] = w8_t; + t[ 9] = w9_t; + t[10] = wa_t; + t[11] = wb_t; + t[12] = wc_t; + t[13] = wd_t; + t[14] = we_t; + t[15] = wf_t; + + #undef K + + #else + + u32 w00_t = w0[0]; + u32 w01_t = w0[1]; + u32 w02_t = w0[2]; + u32 w03_t = w0[3]; + u32 w04_t = w1[0]; + u32 w05_t = w1[1]; + u32 w06_t = w1[2]; + u32 w07_t = w1[3]; + u32 w08_t = w2[0]; + u32 w09_t = w2[1]; + u32 w0a_t = w2[2]; + u32 w0b_t = w2[3]; + u32 w0c_t = w3[0]; + u32 w0d_t = w3[1]; + u32 w0e_t = w3[2]; + u32 w0f_t = w3[3]; + u32 w10_t; + u32 w11_t; + u32 w12_t; + u32 w13_t; + u32 w14_t; + u32 w15_t; + u32 w16_t; + u32 w17_t; + u32 w18_t; + u32 w19_t; + u32 w1a_t; + u32 w1b_t; + u32 w1c_t; + u32 w1d_t; + u32 w1e_t; + u32 w1f_t; + u32 w20_t; + u32 w21_t; + u32 w22_t; + u32 w23_t; + u32 w24_t; + u32 w25_t; + u32 w26_t; + u32 w27_t; + u32 w28_t; + u32 w29_t; + u32 w2a_t; + u32 w2b_t; + u32 w2c_t; + u32 w2d_t; + u32 w2e_t; + u32 w2f_t; + u32 w30_t; + u32 w31_t; + u32 w32_t; + u32 w33_t; + u32 w34_t; + u32 w35_t; + u32 w36_t; + u32 w37_t; + u32 w38_t; + u32 w39_t; + u32 w3a_t; + u32 w3b_t; + u32 w3c_t; + u32 w3d_t; + u32 w3e_t; + u32 w3f_t; + u32 w40_t; + u32 w41_t; + u32 w42_t; + u32 w43_t; + u32 w44_t; + u32 w45_t; + u32 w46_t; + u32 w47_t; + u32 w48_t; + u32 w49_t; + u32 w4a_t; + u32 w4b_t; + u32 w4c_t; + u32 w4d_t; + u32 w4e_t; + u32 w4f_t; + + #define K SHA1C00 + + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, w00_t); + SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, w01_t); + SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, w02_t); + SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, w03_t); + SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, w04_t); + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, w05_t); + SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, w06_t); + SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, w07_t); + SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, w08_t); + SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, w09_t); + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, w0a_t); + SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, w0b_t); + SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, w0c_t); + SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, w0d_t); + SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, w0e_t); + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, w0f_t); + w10_t = hc_rotl32_S ((w0d_t ^ w08_t ^ w02_t ^ w00_t), 1u); SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, w10_t); + w11_t = hc_rotl32_S ((w0e_t ^ w09_t ^ w03_t ^ w01_t), 1u); SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, w11_t); + w12_t = hc_rotl32_S ((w0f_t ^ w0a_t ^ w04_t ^ w02_t), 1u); SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, w12_t); + w13_t = hc_rotl32_S ((w10_t ^ w0b_t ^ w05_t ^ w03_t), 1u); SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, w13_t); + + #undef K + #define K SHA1C01 + + w14_t = hc_rotl32_S ((w11_t ^ w0c_t ^ w06_t ^ w04_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w14_t); + w15_t = hc_rotl32_S ((w12_t ^ w0d_t ^ w07_t ^ w05_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w15_t); + w16_t = hc_rotl32_S ((w13_t ^ w0e_t ^ w08_t ^ w06_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w16_t); + w17_t = hc_rotl32_S ((w14_t ^ w0f_t ^ w09_t ^ w07_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w17_t); + w18_t = hc_rotl32_S ((w15_t ^ w10_t ^ w0a_t ^ w08_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w18_t); + w19_t = hc_rotl32_S ((w16_t ^ w11_t ^ w0b_t ^ w09_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w19_t); + w1a_t = hc_rotl32_S ((w17_t ^ w12_t ^ w0c_t ^ w0a_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w1a_t); + w1b_t = hc_rotl32_S ((w18_t ^ w13_t ^ w0d_t ^ w0b_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w1b_t); + w1c_t = hc_rotl32_S ((w19_t ^ w14_t ^ w0e_t ^ w0c_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w1c_t); + w1d_t = hc_rotl32_S ((w1a_t ^ w15_t ^ w0f_t ^ w0d_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w1d_t); + w1e_t = hc_rotl32_S ((w1b_t ^ w16_t ^ w10_t ^ w0e_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w1e_t); + w1f_t = hc_rotl32_S ((w1c_t ^ w17_t ^ w11_t ^ w0f_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w1f_t); + w20_t = hc_rotl32_S ((w1a_t ^ w10_t ^ w04_t ^ w00_t), 2u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w20_t); + w21_t = hc_rotl32_S ((w1b_t ^ w11_t ^ w05_t ^ w01_t), 2u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w21_t); + w22_t = hc_rotl32_S ((w1c_t ^ w12_t ^ w06_t ^ w02_t), 2u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w22_t); + w23_t = hc_rotl32_S ((w1d_t ^ w13_t ^ w07_t ^ w03_t), 2u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w23_t); + w24_t = hc_rotl32_S ((w1e_t ^ w14_t ^ w08_t ^ w04_t), 2u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w24_t); + w25_t = hc_rotl32_S ((w1f_t ^ w15_t ^ w09_t ^ w05_t), 2u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w25_t); + w26_t = hc_rotl32_S ((w20_t ^ w16_t ^ w0a_t ^ w06_t), 2u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w26_t); + w27_t = hc_rotl32_S ((w21_t ^ w17_t ^ w0b_t ^ w07_t), 2u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w27_t); + + #undef K + #define K SHA1C02 + + w28_t = hc_rotl32_S ((w22_t ^ w18_t ^ w0c_t ^ w08_t), 2u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, w28_t); + w29_t = hc_rotl32_S ((w23_t ^ w19_t ^ w0d_t ^ w09_t), 2u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, w29_t); + w2a_t = hc_rotl32_S ((w24_t ^ w1a_t ^ w0e_t ^ w0a_t), 2u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, w2a_t); + w2b_t = hc_rotl32_S ((w25_t ^ w1b_t ^ w0f_t ^ w0b_t), 2u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, w2b_t); + w2c_t = hc_rotl32_S ((w26_t ^ w1c_t ^ w10_t ^ w0c_t), 2u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, w2c_t); + w2d_t = hc_rotl32_S ((w27_t ^ w1d_t ^ w11_t ^ w0d_t), 2u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, w2d_t); + w2e_t = hc_rotl32_S ((w28_t ^ w1e_t ^ w12_t ^ w0e_t), 2u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, w2e_t); + w2f_t = hc_rotl32_S ((w29_t ^ w1f_t ^ w13_t ^ w0f_t), 2u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, w2f_t); + w30_t = hc_rotl32_S ((w2a_t ^ w20_t ^ w14_t ^ w10_t), 2u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, w30_t); + w31_t = hc_rotl32_S ((w2b_t ^ w21_t ^ w15_t ^ w11_t), 2u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, w31_t); + w32_t = hc_rotl32_S ((w2c_t ^ w22_t ^ w16_t ^ w12_t), 2u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, w32_t); + w33_t = hc_rotl32_S ((w2d_t ^ w23_t ^ w17_t ^ w13_t), 2u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, w33_t); + w34_t = hc_rotl32_S ((w2e_t ^ w24_t ^ w18_t ^ w14_t), 2u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, w34_t); + w35_t = hc_rotl32_S ((w2f_t ^ w25_t ^ w19_t ^ w15_t), 2u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, w35_t); + w36_t = hc_rotl32_S ((w30_t ^ w26_t ^ w1a_t ^ w16_t), 2u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, w36_t); + w37_t = hc_rotl32_S ((w31_t ^ w27_t ^ w1b_t ^ w17_t), 2u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, w37_t); + w38_t = hc_rotl32_S ((w32_t ^ w28_t ^ w1c_t ^ w18_t), 2u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, w38_t); + w39_t = hc_rotl32_S ((w33_t ^ w29_t ^ w1d_t ^ w19_t), 2u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, w39_t); + w3a_t = hc_rotl32_S ((w34_t ^ w2a_t ^ w1e_t ^ w1a_t), 2u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, w3a_t); + w3b_t = hc_rotl32_S ((w35_t ^ w2b_t ^ w1f_t ^ w1b_t), 2u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, w3b_t); + + #undef K + #define K SHA1C03 + + w3c_t = hc_rotl32_S ((w36_t ^ w2c_t ^ w20_t ^ w1c_t), 2u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w3c_t); + w3d_t = hc_rotl32_S ((w37_t ^ w2d_t ^ w21_t ^ w1d_t), 2u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w3d_t); + w3e_t = hc_rotl32_S ((w38_t ^ w2e_t ^ w22_t ^ w1e_t), 2u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w3e_t); + w3f_t = hc_rotl32_S ((w39_t ^ w2f_t ^ w23_t ^ w1f_t), 2u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w3f_t); + w40_t = hc_rotl32_S ((w34_t ^ w20_t ^ w08_t ^ w00_t), 4u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w40_t); + w41_t = hc_rotl32_S ((w35_t ^ w21_t ^ w09_t ^ w01_t), 4u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w41_t); + w42_t = hc_rotl32_S ((w36_t ^ w22_t ^ w0a_t ^ w02_t), 4u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w42_t); + w43_t = hc_rotl32_S ((w37_t ^ w23_t ^ w0b_t ^ w03_t), 4u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w43_t); + w44_t = hc_rotl32_S ((w38_t ^ w24_t ^ w0c_t ^ w04_t), 4u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w44_t); + w45_t = hc_rotl32_S ((w39_t ^ w25_t ^ w0d_t ^ w05_t), 4u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w45_t); + w46_t = hc_rotl32_S ((w3a_t ^ w26_t ^ w0e_t ^ w06_t), 4u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w46_t); + w47_t = hc_rotl32_S ((w3b_t ^ w27_t ^ w0f_t ^ w07_t), 4u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w47_t); + w48_t = hc_rotl32_S ((w3c_t ^ w28_t ^ w10_t ^ w08_t), 4u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w48_t); + w49_t = hc_rotl32_S ((w3d_t ^ w29_t ^ w11_t ^ w09_t), 4u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w49_t); + w4a_t = hc_rotl32_S ((w3e_t ^ w2a_t ^ w12_t ^ w0a_t), 4u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w4a_t); + w4b_t = hc_rotl32_S ((w3f_t ^ w2b_t ^ w13_t ^ w0b_t), 4u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w4b_t); + w4c_t = hc_rotl32_S ((w40_t ^ w2c_t ^ w14_t ^ w0c_t), 4u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w4c_t); + w4d_t = hc_rotl32_S ((w41_t ^ w2d_t ^ w15_t ^ w0d_t), 4u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w4d_t); + w4e_t = hc_rotl32_S ((w42_t ^ w2e_t ^ w16_t ^ w0e_t), 4u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w4e_t); + w4f_t = hc_rotl32_S ((w43_t ^ w2f_t ^ w17_t ^ w0f_t), 4u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w4f_t); + + t[ 0] = w40_t; + t[ 1] = w41_t; + t[ 2] = w42_t; + t[ 3] = w43_t; + t[ 4] = w44_t; + t[ 5] = w45_t; + t[ 6] = w46_t; + t[ 7] = w47_t; + t[ 8] = w48_t; + t[ 9] = w49_t; + t[10] = w4a_t; + t[11] = w4b_t; + t[12] = w4c_t; + t[13] = w4d_t; + t[14] = w4e_t; + t[15] = w4f_t; + + #undef K + #endif + + digest[0] += a; + digest[1] += b; + digest[2] += c; + digest[3] += d; + digest[4] += e; +} + +// only change in this function compared to OpenCL/inc_hash_sha1.cl is that +// it calls our modified sha1_transform_rar29 () function + +DECLSPEC void sha1_update_64_rar29 (sha1_ctx_t *ctx, u32 *w0, u32 *w1, u32 *w2, u32 *w3, const int bytes, u32 *t) +{ + MAYBE_VOLATILE const int pos = ctx->len & 63; + + int len = 64; + + if (bytes < 64) + { + len = bytes; + } + + ctx->len += len; + + if (pos == 0) + { + ctx->w0[0] = w0[0]; + ctx->w0[1] = w0[1]; + ctx->w0[2] = w0[2]; + ctx->w0[3] = w0[3]; + ctx->w1[0] = w1[0]; + ctx->w1[1] = w1[1]; + ctx->w1[2] = w1[2]; + ctx->w1[3] = w1[3]; + ctx->w2[0] = w2[0]; + ctx->w2[1] = w2[1]; + ctx->w2[2] = w2[2]; + ctx->w2[3] = w2[3]; + ctx->w3[0] = w3[0]; + ctx->w3[1] = w3[1]; + ctx->w3[2] = w3[2]; + ctx->w3[3] = w3[3]; + + if (len == 64) + { + sha1_transform_rar29 (ctx->w0, ctx->w1, ctx->w2, ctx->w3, ctx->h, t); + + ctx->w0[0] = 0; + ctx->w0[1] = 0; + ctx->w0[2] = 0; + ctx->w0[3] = 0; + ctx->w1[0] = 0; + ctx->w1[1] = 0; + ctx->w1[2] = 0; + ctx->w1[3] = 0; + ctx->w2[0] = 0; + ctx->w2[1] = 0; + ctx->w2[2] = 0; + ctx->w2[3] = 0; + ctx->w3[0] = 0; + ctx->w3[1] = 0; + ctx->w3[2] = 0; + ctx->w3[3] = 0; + } + } + else + { + if ((pos + len) < 64) + { + switch_buffer_by_offset_be_S (w0, w1, w2, w3, pos); + + ctx->w0[0] |= w0[0]; + ctx->w0[1] |= w0[1]; + ctx->w0[2] |= w0[2]; + ctx->w0[3] |= w0[3]; + ctx->w1[0] |= w1[0]; + ctx->w1[1] |= w1[1]; + ctx->w1[2] |= w1[2]; + ctx->w1[3] |= w1[3]; + ctx->w2[0] |= w2[0]; + ctx->w2[1] |= w2[1]; + ctx->w2[2] |= w2[2]; + ctx->w2[3] |= w2[3]; + ctx->w3[0] |= w3[0]; + ctx->w3[1] |= w3[1]; + ctx->w3[2] |= w3[2]; + ctx->w3[3] |= w3[3]; + } + else + { + u32 c0[4] = { 0 }; + u32 c1[4] = { 0 }; + u32 c2[4] = { 0 }; + u32 c3[4] = { 0 }; + + switch_buffer_by_offset_carry_be_S (w0, w1, w2, w3, c0, c1, c2, c3, pos); + + ctx->w0[0] |= w0[0]; + ctx->w0[1] |= w0[1]; + ctx->w0[2] |= w0[2]; + ctx->w0[3] |= w0[3]; + ctx->w1[0] |= w1[0]; + ctx->w1[1] |= w1[1]; + ctx->w1[2] |= w1[2]; + ctx->w1[3] |= w1[3]; + ctx->w2[0] |= w2[0]; + ctx->w2[1] |= w2[1]; + ctx->w2[2] |= w2[2]; + ctx->w2[3] |= w2[3]; + ctx->w3[0] |= w3[0]; + ctx->w3[1] |= w3[1]; + ctx->w3[2] |= w3[2]; + ctx->w3[3] |= w3[3]; + + sha1_transform_rar29 (ctx->w0, ctx->w1, ctx->w2, ctx->w3, ctx->h, t); + + ctx->w0[0] = c0[0]; + ctx->w0[1] = c0[1]; + ctx->w0[2] = c0[2]; + ctx->w0[3] = c0[3]; + ctx->w1[0] = c1[0]; + ctx->w1[1] = c1[1]; + ctx->w1[2] = c1[2]; + ctx->w1[3] = c1[3]; + ctx->w2[0] = c2[0]; + ctx->w2[1] = c2[1]; + ctx->w2[2] = c2[2]; + ctx->w2[3] = c2[3]; + ctx->w3[0] = c3[0]; + ctx->w3[1] = c3[1]; + ctx->w3[2] = c3[2]; + ctx->w3[3] = c3[3]; + } + } +} + +// main change in this function compared to OpenCL/inc_hash_sha1.cl is that +// we call sha1_update_64_rar29 () and sometimes replace w[] + +DECLSPEC void sha1_update_rar29 (sha1_ctx_t *ctx, u32 *w, const int len) +{ + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + MAYBE_VOLATILE const int pos = ctx->len & 63; + + int pos1 = 0; + int pos4 = 0; + + if (len > 64) // or: if (pos1 < (len - 64)) + { + w0[0] = w[pos4 + 0]; + w0[1] = w[pos4 + 1]; + w0[2] = w[pos4 + 2]; + w0[3] = w[pos4 + 3]; + w1[0] = w[pos4 + 4]; + w1[1] = w[pos4 + 5]; + w1[2] = w[pos4 + 6]; + w1[3] = w[pos4 + 7]; + w2[0] = w[pos4 + 8]; + w2[1] = w[pos4 + 9]; + w2[2] = w[pos4 + 10]; + w2[3] = w[pos4 + 11]; + w3[0] = w[pos4 + 12]; + w3[1] = w[pos4 + 13]; + w3[2] = w[pos4 + 14]; + w3[3] = w[pos4 + 15]; + + sha1_update_64 (ctx, w0, w1, w2, w3, 64); + + pos1 += 64; + pos4 += 16; + } + + for (int diff = 64 - pos; pos1 < len; pos1 += 64, pos4 += 16, diff += 64) + { + w0[0] = w[pos4 + 0]; + w0[1] = w[pos4 + 1]; + w0[2] = w[pos4 + 2]; + w0[3] = w[pos4 + 3]; + w1[0] = w[pos4 + 4]; + w1[1] = w[pos4 + 5]; + w1[2] = w[pos4 + 6]; + w1[3] = w[pos4 + 7]; + w2[0] = w[pos4 + 8]; + w2[1] = w[pos4 + 9]; + w2[2] = w[pos4 + 10]; + w2[3] = w[pos4 + 11]; + w3[0] = w[pos4 + 12]; + w3[1] = w[pos4 + 13]; + w3[2] = w[pos4 + 14]; + w3[3] = w[pos4 + 15]; + + // only major change in this function compared to OpenCL/inc_hash_sha1.cl: + + u32 t[17] = { 0 }; + + sha1_update_64_rar29 (ctx, w0, w1, w2, w3, len - pos1, t); + + + if ((diff + 63) >= len) break; + + // replaces 64 bytes (with offset diff) of the underlying data w[] with t[]: + + // for (int i = 0; i < 16; i++) t[i] = hc_swap32_S (t[i]); + + t[ 0] = hc_swap32_S (t[ 0]); // unroll seems to be faster + t[ 1] = hc_swap32_S (t[ 1]); + t[ 2] = hc_swap32_S (t[ 2]); + t[ 3] = hc_swap32_S (t[ 3]); + t[ 4] = hc_swap32_S (t[ 4]); + t[ 5] = hc_swap32_S (t[ 5]); + t[ 6] = hc_swap32_S (t[ 6]); + t[ 7] = hc_swap32_S (t[ 7]); + t[ 8] = hc_swap32_S (t[ 8]); + t[ 9] = hc_swap32_S (t[ 9]); + t[10] = hc_swap32_S (t[10]); + t[11] = hc_swap32_S (t[11]); + t[12] = hc_swap32_S (t[12]); + t[13] = hc_swap32_S (t[13]); + t[14] = hc_swap32_S (t[14]); + t[15] = hc_swap32_S (t[15]); + + const u32 n_idx = diff / 4; + const u32 n_off = diff % 4; + + if (n_off) + { + const u32 off_mul = n_off * 8; + const u32 off_sub = 32 - off_mul; + + t[16] = (t[15] << off_sub); + t[15] = (t[15] >> off_mul) | (t[14] << off_sub); + t[14] = (t[14] >> off_mul) | (t[13] << off_sub); + t[13] = (t[13] >> off_mul) | (t[12] << off_sub); + t[12] = (t[12] >> off_mul) | (t[11] << off_sub); + t[11] = (t[11] >> off_mul) | (t[10] << off_sub); + t[10] = (t[10] >> off_mul) | (t[ 9] << off_sub); + t[ 9] = (t[ 9] >> off_mul) | (t[ 8] << off_sub); + t[ 8] = (t[ 8] >> off_mul) | (t[ 7] << off_sub); + t[ 7] = (t[ 7] >> off_mul) | (t[ 6] << off_sub); + t[ 6] = (t[ 6] >> off_mul) | (t[ 5] << off_sub); + t[ 5] = (t[ 5] >> off_mul) | (t[ 4] << off_sub); + t[ 4] = (t[ 4] >> off_mul) | (t[ 3] << off_sub); + t[ 3] = (t[ 3] >> off_mul) | (t[ 2] << off_sub); + t[ 2] = (t[ 2] >> off_mul) | (t[ 1] << off_sub); + t[ 1] = (t[ 1] >> off_mul) | (t[ 0] << off_sub); + t[ 0] = (t[ 0] >> off_mul); + } + + w[n_idx] &= 0xffffff00 << ((3 - n_off) * 8); + + w[n_idx] |= t[0]; + + w[n_idx + 1] = t[ 1]; + w[n_idx + 2] = t[ 2]; + w[n_idx + 3] = t[ 3]; + w[n_idx + 4] = t[ 4]; + w[n_idx + 5] = t[ 5]; + w[n_idx + 6] = t[ 6]; + w[n_idx + 7] = t[ 7]; + w[n_idx + 8] = t[ 8]; + w[n_idx + 9] = t[ 9]; + w[n_idx + 10] = t[10]; + w[n_idx + 11] = t[11]; + w[n_idx + 12] = t[12]; + w[n_idx + 13] = t[13]; + w[n_idx + 14] = t[14]; + w[n_idx + 15] = t[15]; + + // the final set is only meaningful: if (n_off) + + w[n_idx + 16] &= 0xffffffff >> (n_off * 8); + + w[n_idx + 16] |= t[16]; + } +} + +KERNEL_FQ void m23700_init (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) +{ + /** + * base + */ + + const u64 gid = get_global_id (0); + + if (gid >= gid_max) return; + + tmps[gid].dgst[0] = SHA1M_A; + tmps[gid].dgst[1] = SHA1M_B; + tmps[gid].dgst[2] = SHA1M_C; + tmps[gid].dgst[3] = SHA1M_D; + tmps[gid].dgst[4] = SHA1M_E; + + // store pass and salt in tmps: + + const u32 pw_len = pws[gid].pw_len; + + // first set the utf16le pass: + + u32 w[80] = { 0 }; + + for (u32 i = 0, j = 0, k = 0; i < pw_len; i += 16, j += 4, k += 8) + { + u32 a[4]; + + a[0] = pws[gid].i[j + 0]; + a[1] = pws[gid].i[j + 1]; + a[2] = pws[gid].i[j + 2]; + a[3] = pws[gid].i[j + 3]; + + u32 b[4]; + u32 c[4]; + + make_utf16le (a, b, c); + + w[k + 0] = hc_swap32_S (b[0]); + w[k + 1] = hc_swap32_S (b[1]); + w[k + 2] = hc_swap32_S (b[2]); + w[k + 3] = hc_swap32_S (b[3]); + w[k + 4] = hc_swap32_S (c[0]); + w[k + 5] = hc_swap32_S (c[1]); + w[k + 6] = hc_swap32_S (c[2]); + w[k + 7] = hc_swap32_S (c[3]); + } + + // append salt: + + const u32 salt_idx = (pw_len * 2) / 4; + const u32 salt_off = (pw_len * 2) & 3; + + u32 salt_buf[3]; + + salt_buf[0] = hc_swap32_S (salt_bufs[salt_pos].salt_buf[0]); // swap needed due to -O kernel + salt_buf[1] = hc_swap32_S (salt_bufs[salt_pos].salt_buf[1]); + salt_buf[2] = 0; + + // switch buffer by offset (can only be 0 or 2 because of utf16): + + if (salt_off == 2) // or just: if (salt_off) + { + salt_buf[2] = (salt_buf[1] << 16); + salt_buf[1] = (salt_buf[1] >> 16) | (salt_buf[0] << 16); + salt_buf[0] = (salt_buf[0] >> 16); + } + + w[salt_idx] |= salt_buf[0]; + + w[salt_idx + 1] = salt_buf[1]; + w[salt_idx + 2] = salt_buf[2]; + + // store initial w[] (pass and salt) in tmps: + + for (u32 i = 0; i < 66; i++) // unroll ? + { + tmps[gid].w[i] = w[i]; + } + + // iv: + + tmps[gid].iv[0] = 0; + tmps[gid].iv[1] = 0; + tmps[gid].iv[2] = 0; + tmps[gid].iv[3] = 0; +} + +KERNEL_FQ void m23700_loop (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) +{ + const u64 gid = get_global_id (0); + + if (gid >= gid_max) return; + + /** + * base + */ + + const u32 pw_len = pws[gid].pw_len; + + const u32 salt_len = 8; + + const u32 pw_salt_len = (pw_len * 2) + salt_len; + + const u32 p3 = pw_salt_len + 3; + + u32 w[80] = { 0 }; // 64 byte aligned + + for (u32 i = 0; i < 66; i++) // unroll ? + { + w[i] = tmps[gid].w[i]; + } + + // update IV: + + const u32 init_pos = loop_pos / (ROUNDS / 16); + + sha1_ctx_t ctx_iv; + + sha1_init (&ctx_iv); + + ctx_iv.h[0] = tmps[gid].dgst[0]; + ctx_iv.h[1] = tmps[gid].dgst[1]; + ctx_iv.h[2] = tmps[gid].dgst[2]; + ctx_iv.h[3] = tmps[gid].dgst[3]; + ctx_iv.h[4] = tmps[gid].dgst[4]; + + ctx_iv.len = loop_pos * p3; + + sha1_update_rar29 (&ctx_iv, w, pw_salt_len); + + memcat8c_be (ctx_iv.w0, ctx_iv.w1, ctx_iv.w2, ctx_iv.w3, ctx_iv.len, hc_swap32_S (loop_pos), ctx_iv.h); + + ctx_iv.len += 3; + + + // copy the context from ctx_iv to ctx: + + sha1_ctx_t ctx; + + ctx.h[0] = ctx_iv.h[0]; + ctx.h[1] = ctx_iv.h[1]; + ctx.h[2] = ctx_iv.h[2]; + ctx.h[3] = ctx_iv.h[3]; + ctx.h[4] = ctx_iv.h[4]; + + ctx.w0[0] = ctx_iv.w0[0]; + ctx.w0[1] = ctx_iv.w0[1]; + ctx.w0[2] = ctx_iv.w0[2]; + ctx.w0[3] = ctx_iv.w0[3]; + + ctx.w1[0] = ctx_iv.w1[0]; + ctx.w1[1] = ctx_iv.w1[1]; + ctx.w1[2] = ctx_iv.w1[2]; + ctx.w1[3] = ctx_iv.w1[3]; + + ctx.w2[0] = ctx_iv.w2[0]; + ctx.w2[1] = ctx_iv.w2[1]; + ctx.w2[2] = ctx_iv.w2[2]; + ctx.w2[3] = ctx_iv.w2[3]; + + ctx.w3[0] = ctx_iv.w3[0]; + ctx.w3[1] = ctx_iv.w3[1]; + ctx.w3[2] = ctx_iv.w3[2]; + ctx.w3[3] = ctx_iv.w3[3]; + + ctx.len = p3; // or ctx_iv.len ? + + // final () for the IV byte: + + sha1_final (&ctx_iv); + + const u32 iv_idx = init_pos / 4; + const u32 iv_off = init_pos % 4; + + tmps[gid].iv[iv_idx] |= (ctx_iv.h[4] & 0xff) << (iv_off * 8); + + // main loop: + + for (u32 i = 0, j = (loop_pos + 1); i < 16383; i++, j++) + { + sha1_update_rar29 (&ctx, w, pw_salt_len); + + memcat8c_be (ctx.w0, ctx.w1, ctx.w2, ctx.w3, ctx.len, hc_swap32_S (j), ctx.h); + + ctx.len += 3; + } + + tmps[gid].dgst[0] = ctx.h[0]; + tmps[gid].dgst[1] = ctx.h[1]; + tmps[gid].dgst[2] = ctx.h[2]; + tmps[gid].dgst[3] = ctx.h[3]; + tmps[gid].dgst[4] = ctx.h[4]; + + // only needed if pw_len > 28: + + for (u32 i = 0; i < 66; i++) // unroll ? + { + tmps[gid].w[i] = w[i]; + } +} + +KERNEL_FQ void m23700_comp (KERN_ATTR_TMPS_ESALT (rar3_tmp_t, rar3_t)) +{ + const u64 gid = get_global_id (0); + const u64 lid = get_local_id (0); + const u64 lsz = get_local_size (0); + + /** + * aes shared + */ + + #ifdef REAL_SHM + + LOCAL_VK u32 s_td0[256]; + LOCAL_VK u32 s_td1[256]; + LOCAL_VK u32 s_td2[256]; + LOCAL_VK u32 s_td3[256]; + LOCAL_VK u32 s_td4[256]; + + LOCAL_VK u32 s_te0[256]; + LOCAL_VK u32 s_te1[256]; + LOCAL_VK u32 s_te2[256]; + LOCAL_VK u32 s_te3[256]; + LOCAL_VK u32 s_te4[256]; + + for (u32 i = lid; i < 256; i += lsz) + { + s_td0[i] = td0[i]; + s_td1[i] = td1[i]; + s_td2[i] = td2[i]; + s_td3[i] = td3[i]; + s_td4[i] = td4[i]; + + s_te0[i] = te0[i]; + s_te1[i] = te1[i]; + s_te2[i] = te2[i]; + s_te3[i] = te3[i]; + s_te4[i] = te4[i]; + } + + #else + + CONSTANT_AS u32a *s_td0 = td0; + CONSTANT_AS u32a *s_td1 = td1; + CONSTANT_AS u32a *s_td2 = td2; + CONSTANT_AS u32a *s_td3 = td3; + CONSTANT_AS u32a *s_td4 = td4; + + CONSTANT_AS u32a *s_te0 = te0; + CONSTANT_AS u32a *s_te1 = te1; + CONSTANT_AS u32a *s_te2 = te2; + CONSTANT_AS u32a *s_te3 = te3; + CONSTANT_AS u32a *s_te4 = te4; + + #endif + + LOCAL_VK u32 l_crc32tab[256]; + + for (int i = lid; i < 256; i += lsz) + { + l_crc32tab[i] = crc32tab[i]; + } + + SYNC_THREADS (); + + if (gid >= gid_max) return; + + /** + * base + */ + + const u32 pw_len = pws[gid].pw_len; + + const u32 salt_len = 8; + + const u32 pw_salt_len = (pw_len * 2) + salt_len; + + const u32 p3 = pw_salt_len + 3; + + u32 h[5]; + + h[0] = tmps[gid].dgst[0]; + h[1] = tmps[gid].dgst[1]; + h[2] = tmps[gid].dgst[2]; + h[3] = tmps[gid].dgst[3]; + h[4] = tmps[gid].dgst[4]; + + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + w0[0] = 0x80000000; + w0[1] = 0; + w0[2] = 0; + w0[3] = 0; + w1[0] = 0; + w1[1] = 0; + w1[2] = 0; + w1[3] = 0; + w2[0] = 0; + w2[1] = 0; + w2[2] = 0; + w2[3] = 0; + w3[0] = 0; + w3[1] = 0; + w3[2] = 0; + w3[3] = (ROUNDS * p3) * 8; + + sha1_transform (w0, w1, w2, w3, h); + + u32 ukey[4]; + + ukey[0] = hc_swap32_S (h[0]); + ukey[1] = hc_swap32_S (h[1]); + ukey[2] = hc_swap32_S (h[2]); + ukey[3] = hc_swap32_S (h[3]); + + u32 ks[44]; + + AES128_set_decrypt_key (ks, ukey, s_te0, s_te1, s_te2, s_te3, s_td0, s_td1, s_td2, s_td3); + + const u32 pack_size = esalt_bufs[digests_offset].pack_size; + const u32 unpack_size = esalt_bufs[digests_offset].unpack_size; + + if (pack_size > unpack_size) // could be aligned + { + if (pack_size >= 32) // otherwise IV... + { + const u32 pack_size_elements = pack_size / 4; + + u32 last_block_encrypted[4]; + + last_block_encrypted[0] = esalt_bufs[digests_offset].data[pack_size_elements - 4 + 0]; + last_block_encrypted[1] = esalt_bufs[digests_offset].data[pack_size_elements - 4 + 1]; + last_block_encrypted[2] = esalt_bufs[digests_offset].data[pack_size_elements - 4 + 2]; + last_block_encrypted[3] = esalt_bufs[digests_offset].data[pack_size_elements - 4 + 3]; + + u32 last_block_decrypted[4]; + + AES128_decrypt (ks, last_block_encrypted, last_block_decrypted, s_td0, s_td1, s_td2, s_td3, s_td4); + + u32 last_block_iv[4]; + + last_block_iv[0] = esalt_bufs[digests_offset].data[pack_size_elements - 8 + 0]; + last_block_iv[1] = esalt_bufs[digests_offset].data[pack_size_elements - 8 + 1]; + last_block_iv[2] = esalt_bufs[digests_offset].data[pack_size_elements - 8 + 2]; + last_block_iv[3] = esalt_bufs[digests_offset].data[pack_size_elements - 8 + 3]; + + last_block_decrypted[0] ^= last_block_iv[0]; + last_block_decrypted[1] ^= last_block_iv[1]; + last_block_decrypted[2] ^= last_block_iv[2]; + last_block_decrypted[3] ^= last_block_iv[3]; + + if ((last_block_decrypted[3] & 0xff) != 0) return; + } + } + + u32 iv[4]; + + iv[0] = tmps[gid].iv[0]; + iv[1] = tmps[gid].iv[1]; + iv[2] = tmps[gid].iv[2]; + iv[3] = tmps[gid].iv[3]; + + iv[0] = hc_swap32_S (iv[0]); + iv[1] = hc_swap32_S (iv[1]); + iv[2] = hc_swap32_S (iv[2]); + iv[3] = hc_swap32_S (iv[3]); + + u32 data_left = unpack_size; + + u32 crc32 = ~0; + + for (u32 i = 0, j = 0; i < pack_size / 16; i += 1, j += 4) + { + u32 data[4]; + + data[0] = esalt_bufs[digests_offset].data[j + 0]; + data[1] = esalt_bufs[digests_offset].data[j + 1]; + data[2] = esalt_bufs[digests_offset].data[j + 2]; + data[3] = esalt_bufs[digests_offset].data[j + 3]; + + u32 out[4]; + + AES128_decrypt (ks, data, out, s_td0, s_td1, s_td2, s_td3, s_td4); + + out[0] ^= iv[0]; + out[1] ^= iv[1]; + out[2] ^= iv[2]; + out[3] ^= iv[3]; + + crc32 = round_crc32_16 (crc32, out, data_left, l_crc32tab); + + iv[0] = data[0]; + iv[1] = data[1]; + iv[2] = data[2]; + iv[3] = data[3]; + + data_left -= 16; + } + + const u32 r0 = crc32; + const u32 r1 = 0; + const u32 r2 = 0; + const u32 r3 = 0; + + #define il_pos 0 + + #ifdef KERNEL_STATIC + #include COMPARE_M + #endif +} diff --git a/OpenCL/m23800-optimized.cl b/OpenCL/m23800-optimized.cl new file mode 100644 index 000000000..2c458ffaf --- /dev/null +++ b/OpenCL/m23800-optimized.cl @@ -0,0 +1,436 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +#ifdef KERNEL_STATIC +#include "inc_vendor.h" +#include "inc_types.h" +#include "inc_platform.cl" +#include "inc_common.cl" +#include "inc_hash_sha1.cl" +#include "inc_cipher_aes.cl" +#endif + +#define COMPARE_S "inc_comp_single.cl" +#define COMPARE_M "inc_comp_multi.cl" + +#define ROUNDS 0x40000 + +#define PUTCHAR(a,p,c) ((u8 *)(a))[(p)] = (u8) (c) +#define GETCHAR(a,p) ((u8 *)(a))[(p)] + +#define PUTCHAR_BE(a,p,c) ((u8 *)(a))[(p) ^ 3] = (u8) (c) +#define GETCHAR_BE(a,p) ((u8 *)(a))[(p) ^ 3] + +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +typedef struct rar3 +{ + u32 first_block_encrypted[4]; + +} rar3_t; + +typedef struct rar3_tmp +{ + u32 dgst[17][5]; + +} rar3_tmp_t; + +typedef struct rar3_hook +{ + u32 key[4]; + u32 iv[4]; + + u32 first_block_decrypted[4]; + + u32 crc32; + +} rar3_hook_t; + +KERNEL_FQ void m23800_init (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, rar3_t)) +{ + /** + * base + */ + + const u64 gid = get_global_id (0); + + if (gid >= gid_max) return; + + tmps[gid].dgst[0][0] = SHA1M_A; + tmps[gid].dgst[0][1] = SHA1M_B; + tmps[gid].dgst[0][2] = SHA1M_C; + tmps[gid].dgst[0][3] = SHA1M_D; + tmps[gid].dgst[0][4] = SHA1M_E; +} + +KERNEL_FQ void m23800_loop (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, rar3_t)) +{ + const u64 gid = get_global_id (0); + + if (gid >= gid_max) return; + + u32 pw_buf[5]; + + pw_buf[0] = pws[gid].i[0]; + pw_buf[1] = pws[gid].i[1]; + pw_buf[2] = pws[gid].i[2]; + pw_buf[3] = pws[gid].i[3]; + pw_buf[4] = pws[gid].i[4]; + + const u32 pw_len = MIN (pws[gid].pw_len, 20); + + u32 salt_buf[2]; + + salt_buf[0] = salt_bufs[salt_pos].salt_buf[0]; + salt_buf[1] = salt_bufs[salt_pos].salt_buf[1]; + + const u32 salt_len = 8; + + // this is large enough to hold all possible w[] arrays for 64 iterations + + #define LARGEBLOCK_ELEMS ((40 + 8 + 3) * 16) + + u32 largeblock[LARGEBLOCK_ELEMS]; + + for (u32 i = 0; i < LARGEBLOCK_ELEMS; i++) largeblock[i] = 0; + + for (u32 i = 0, p = 0; i < 64; i++) + { + for (u32 j = 0; j < pw_len; j++, p += 2) + { + PUTCHAR_BE (largeblock, p, GETCHAR (pw_buf, j)); + } + + for (u32 j = 0; j < salt_len; j++, p += 1) + { + PUTCHAR_BE (largeblock, p, GETCHAR (salt_buf, j)); + } + + PUTCHAR_BE (largeblock, p + 2, (loop_pos >> 16) & 0xff); + + p += 3; + } + + const u32 p3 = (pw_len * 2) + salt_len + 3; + + const u32 init_pos = loop_pos / (ROUNDS / 16); + + u32 dgst[5]; + + dgst[0] = tmps[gid].dgst[init_pos][0]; + dgst[1] = tmps[gid].dgst[init_pos][1]; + dgst[2] = tmps[gid].dgst[init_pos][2]; + dgst[3] = tmps[gid].dgst[init_pos][3]; + dgst[4] = tmps[gid].dgst[init_pos][4]; + + u32 iter = loop_pos; + + for (u32 i = 0; i < 256; i += 4) + { + for (u32 j = 0; j < 64; j++) + { + const u32 p = ((j + 1) * p3) - 2; + + PUTCHAR_BE (largeblock, p, iter >> 8); + } + + for (u32 k = 0; k < 4; k++) + { + for (u32 j = 0; j < 64; j++) + { + const u32 p = ((j + 1) * p3) - 3; + + PUTCHAR_BE (largeblock, p, iter >> 0); + + iter++; + } + + for (u32 j = 0; j < p3; j++) + { + const u32 j16 = j * 16; + + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + w0[0] = largeblock[j16 + 0]; + w0[1] = largeblock[j16 + 1]; + w0[2] = largeblock[j16 + 2]; + w0[3] = largeblock[j16 + 3]; + w1[0] = largeblock[j16 + 4]; + w1[1] = largeblock[j16 + 5]; + w1[2] = largeblock[j16 + 6]; + w1[3] = largeblock[j16 + 7]; + w2[0] = largeblock[j16 + 8]; + w2[1] = largeblock[j16 + 9]; + w2[2] = largeblock[j16 + 10]; + w2[3] = largeblock[j16 + 11]; + w3[0] = largeblock[j16 + 12]; + w3[1] = largeblock[j16 + 13]; + w3[2] = largeblock[j16 + 14]; + w3[3] = largeblock[j16 + 15]; + + sha1_transform (w0, w1, w2, w3, dgst); + } + } + } + + tmps[gid].dgst[init_pos + 1][0] = dgst[0]; + tmps[gid].dgst[init_pos + 1][1] = dgst[1]; + tmps[gid].dgst[init_pos + 1][2] = dgst[2]; + tmps[gid].dgst[init_pos + 1][3] = dgst[3]; + tmps[gid].dgst[init_pos + 1][4] = dgst[4]; +} + +KERNEL_FQ void m23800_hook23 (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, rar3_t)) +{ + const u64 gid = get_global_id (0); + const u64 lid = get_local_id (0); + const u64 lsz = get_local_size (0); + + /** + * aes shared + */ + + #ifdef REAL_SHM + + LOCAL_VK u32 s_td0[256]; + LOCAL_VK u32 s_td1[256]; + LOCAL_VK u32 s_td2[256]; + LOCAL_VK u32 s_td3[256]; + LOCAL_VK u32 s_td4[256]; + + LOCAL_VK u32 s_te0[256]; + LOCAL_VK u32 s_te1[256]; + LOCAL_VK u32 s_te2[256]; + LOCAL_VK u32 s_te3[256]; + LOCAL_VK u32 s_te4[256]; + + for (u32 i = lid; i < 256; i += lsz) + { + s_td0[i] = td0[i]; + s_td1[i] = td1[i]; + s_td2[i] = td2[i]; + s_td3[i] = td3[i]; + s_td4[i] = td4[i]; + + s_te0[i] = te0[i]; + s_te1[i] = te1[i]; + s_te2[i] = te2[i]; + s_te3[i] = te3[i]; + s_te4[i] = te4[i]; + } + + #else + + CONSTANT_AS u32a *s_td0 = td0; + CONSTANT_AS u32a *s_td1 = td1; + CONSTANT_AS u32a *s_td2 = td2; + CONSTANT_AS u32a *s_td3 = td3; + CONSTANT_AS u32a *s_td4 = td4; + + CONSTANT_AS u32a *s_te0 = te0; + CONSTANT_AS u32a *s_te1 = te1; + CONSTANT_AS u32a *s_te2 = te2; + CONSTANT_AS u32a *s_te3 = te3; + CONSTANT_AS u32a *s_te4 = te4; + + #endif + + SYNC_THREADS (); + + if (gid >= gid_max) return; + + /** + * base + */ + + const u32 pw_len = MIN (pws[gid].pw_len, 20); + + const u32 salt_len = 8; + + const u32 p3 = (pw_len * 2) + salt_len + 3; + + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + w0[0] = 0x80000000; + w0[1] = 0; + w0[2] = 0; + w0[3] = 0; + w1[0] = 0; + w1[1] = 0; + w1[2] = 0; + w1[3] = 0; + w2[0] = 0; + w2[1] = 0; + w2[2] = 0; + w2[3] = 0; + w3[0] = 0; + w3[1] = 0; + w3[2] = 0; + w3[3] = (p3 * ROUNDS) * 8; + + u32 h[5]; + + h[0] = tmps[gid].dgst[16][0]; + h[1] = tmps[gid].dgst[16][1]; + h[2] = tmps[gid].dgst[16][2]; + h[3] = tmps[gid].dgst[16][3]; + h[4] = tmps[gid].dgst[16][4]; + + sha1_transform (w0, w1, w2, w3, h); + + u32 iv[4]; + + iv[0] = 0; + iv[1] = 0; + iv[2] = 0; + iv[3] = 0; + + for (int i = 0; i < 16; i++) + { + u32 pw_buf[5]; + + pw_buf[0] = pws[gid].i[0]; + pw_buf[1] = pws[gid].i[1]; + pw_buf[2] = pws[gid].i[2]; + pw_buf[3] = pws[gid].i[3]; + pw_buf[4] = pws[gid].i[4]; + + //const u32 pw_len = pws[gid].pw_len; + + u32 salt_buf[2]; + + salt_buf[0] = salt_bufs[salt_pos].salt_buf[0]; + salt_buf[1] = salt_bufs[salt_pos].salt_buf[1]; + + //const u32 salt_len = 8; + + //const u32 p3 = (pw_len * 2) + salt_len + 3; + + u32 w[16]; + + w[ 0] = 0; + w[ 1] = 0; + w[ 2] = 0; + w[ 3] = 0; + w[ 4] = 0; + w[ 5] = 0; + w[ 6] = 0; + w[ 7] = 0; + w[ 8] = 0; + w[ 9] = 0; + w[10] = 0; + w[11] = 0; + w[12] = 0; + w[13] = 0; + w[14] = 0; + w[15] = 0; + + u32 p = 0; + + for (u32 j = 0; j < pw_len; j++, p += 2) + { + PUTCHAR_BE (w, p, GETCHAR (pw_buf, j)); + } + + for (u32 j = 0; j < salt_len; j++, p += 1) + { + PUTCHAR_BE (w, p, GETCHAR (salt_buf, j)); + } + + const u32 iter_pos = i * (ROUNDS / 16); + + PUTCHAR_BE (w, p + 0, (iter_pos >> 0) & 0xff); + PUTCHAR_BE (w, p + 1, (iter_pos >> 8) & 0xff); + PUTCHAR_BE (w, p + 2, (iter_pos >> 16) & 0xff); + + PUTCHAR_BE (w, p3, 0x80); + + w[15] = ((iter_pos + 1) * p3) * 8; + + u32 dgst[5]; + + dgst[0] = tmps[gid].dgst[i][0]; + dgst[1] = tmps[gid].dgst[i][1]; + dgst[2] = tmps[gid].dgst[i][2]; + dgst[3] = tmps[gid].dgst[i][3]; + dgst[4] = tmps[gid].dgst[i][4]; + + sha1_transform (w + 0, w + 4, w + 8, w + 12, dgst); + + PUTCHAR (iv, i, dgst[4] & 0xff); + } + + hooks[gid].key[0] = h[0]; + hooks[gid].key[1] = h[1]; + hooks[gid].key[2] = h[2]; + hooks[gid].key[3] = h[3]; + + hooks[gid].iv[0] = iv[0]; + hooks[gid].iv[1] = iv[1]; + hooks[gid].iv[2] = iv[2]; + hooks[gid].iv[3] = iv[3]; + + u32 ukey[4]; + + ukey[0] = hc_swap32_S (h[0]); + ukey[1] = hc_swap32_S (h[1]); + ukey[2] = hc_swap32_S (h[2]); + ukey[3] = hc_swap32_S (h[3]); + + u32 ks[44]; + + AES128_set_decrypt_key (ks, ukey, s_te0, s_te1, s_te2, s_te3, s_td0, s_td1, s_td2, s_td3); + + u32 data[4]; + + data[0] = hc_swap32_S (esalt_bufs[digests_offset].first_block_encrypted[0]); + data[1] = hc_swap32_S (esalt_bufs[digests_offset].first_block_encrypted[1]); + data[2] = hc_swap32_S (esalt_bufs[digests_offset].first_block_encrypted[2]); + data[3] = hc_swap32_S (esalt_bufs[digests_offset].first_block_encrypted[3]); + + u32 out[4]; + + AES128_decrypt (ks, data, out, s_td0, s_td1, s_td2, s_td3, s_td4); + + out[0] ^= hc_swap32_S (iv[0]); + out[1] ^= hc_swap32_S (iv[1]); + out[2] ^= hc_swap32_S (iv[2]); + out[3] ^= hc_swap32_S (iv[3]); + + hooks[gid].first_block_decrypted[0] = hc_swap32_S (out[0]); + hooks[gid].first_block_decrypted[1] = hc_swap32_S (out[1]); + hooks[gid].first_block_decrypted[2] = hc_swap32_S (out[2]); + hooks[gid].first_block_decrypted[3] = hc_swap32_S (out[3]); +} + +KERNEL_FQ void m23800_comp (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, rar3_t)) +{ + /** + * base + */ + + const u64 gid = get_global_id (0); + + if (gid >= gid_max) return; + + u32 crc32 = hooks[gid].crc32; + + const u32 r0 = crc32; + const u32 r1 = 0; + const u32 r2 = 0; + const u32 r3 = 0; + + #define il_pos 0 + + #ifdef KERNEL_STATIC + #include COMPARE_M + #endif +} diff --git a/OpenCL/m23800-pure.cl b/OpenCL/m23800-pure.cl new file mode 100644 index 000000000..9908d53cd --- /dev/null +++ b/OpenCL/m23800-pure.cl @@ -0,0 +1,1148 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +#ifdef KERNEL_STATIC +#include "inc_vendor.h" +#include "inc_types.h" +#include "inc_platform.cl" +#include "inc_common.cl" +#include "inc_hash_sha1.cl" +#include "inc_cipher_aes.cl" +#endif + +#define COMPARE_S "inc_comp_single.cl" +#define COMPARE_M "inc_comp_multi.cl" + +#define ROUNDS 0x40000 + +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +typedef struct rar3 +{ + u32 first_block_encrypted[4]; + +} rar3_t; + +typedef struct rar3_tmp +{ + u32 dgst[5]; + + u32 w[66]; // 256 byte pass + 8 byte salt + + u32 iv[4]; + +} rar3_tmp_t; + +typedef struct rar3_hook +{ + u32 key[4]; + u32 iv[4]; + + u32 first_block_decrypted[4]; + + u32 crc32; + +} rar3_hook_t; + +DECLSPEC void memcat8c_be (u32 *w0, u32 *w1, u32 *w2, u32 *w3, const u32 len, const u32 append, u32 *digest) +{ + const u32 func_len = len & 63; + + //const u32 mod = func_len & 3; + const u32 div = func_len / 4; + + u32 tmp0; + u32 tmp1; + + #if defined IS_AMD || defined IS_GENERIC + tmp0 = hc_bytealign_be (0, append, func_len); + tmp1 = hc_bytealign_be (append, 0, func_len); + #endif + + #ifdef IS_NV + const int selector = (0x76543210 >> ((func_len & 3) * 4)) & 0xffff; + + tmp0 = hc_byte_perm (append, 0, selector); + tmp1 = hc_byte_perm (0, append, selector); + #endif + + u32 carry = 0; + + switch (div) + { + case 0: w0[0] |= tmp0; + w0[1] = tmp1; + break; + case 1: w0[1] |= tmp0; + w0[2] = tmp1; + break; + case 2: w0[2] |= tmp0; + w0[3] = tmp1; + break; + case 3: w0[3] |= tmp0; + w1[0] = tmp1; + break; + case 4: w1[0] |= tmp0; + w1[1] = tmp1; + break; + case 5: w1[1] |= tmp0; + w1[2] = tmp1; + break; + case 6: w1[2] |= tmp0; + w1[3] = tmp1; + break; + case 7: w1[3] |= tmp0; + w2[0] = tmp1; + break; + case 8: w2[0] |= tmp0; + w2[1] = tmp1; + break; + case 9: w2[1] |= tmp0; + w2[2] = tmp1; + break; + case 10: w2[2] |= tmp0; + w2[3] = tmp1; + break; + case 11: w2[3] |= tmp0; + w3[0] = tmp1; + break; + case 12: w3[0] |= tmp0; + w3[1] = tmp1; + break; + case 13: w3[1] |= tmp0; + w3[2] = tmp1; + break; + case 14: w3[2] |= tmp0; + w3[3] = tmp1; + break; + case 15: w3[3] |= tmp0; + carry = tmp1; + break; + } + + const u32 new_len = func_len + 3; + + if (new_len >= 64) + { + sha1_transform (w0, w1, w2, w3, digest); + + w0[0] = carry; + w0[1] = 0; + w0[2] = 0; + w0[3] = 0; + w1[0] = 0; + w1[1] = 0; + w1[2] = 0; + w1[3] = 0; + w2[0] = 0; + w2[1] = 0; + w2[2] = 0; + w2[3] = 0; + w3[0] = 0; + w3[1] = 0; + w3[2] = 0; + w3[3] = 0; + } +} + +// only change in this function compared to OpenCL/inc_hash_sha1.cl is that it returns +// the expanded 64 byte buffer w0_t..wf_t in t[]: + +DECLSPEC void sha1_transform_rar29 (const u32 *w0, const u32 *w1, const u32 *w2, const u32 *w3, u32 *digest, u32 *t) +{ + u32 a = digest[0]; + u32 b = digest[1]; + u32 c = digest[2]; + u32 d = digest[3]; + u32 e = digest[4]; + + #ifdef IS_CPU + + u32 w0_t = w0[0]; + u32 w1_t = w0[1]; + u32 w2_t = w0[2]; + u32 w3_t = w0[3]; + u32 w4_t = w1[0]; + u32 w5_t = w1[1]; + u32 w6_t = w1[2]; + u32 w7_t = w1[3]; + u32 w8_t = w2[0]; + u32 w9_t = w2[1]; + u32 wa_t = w2[2]; + u32 wb_t = w2[3]; + u32 wc_t = w3[0]; + u32 wd_t = w3[1]; + u32 we_t = w3[2]; + u32 wf_t = w3[3]; + + #define K SHA1C00 + + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, w0_t); + SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, w1_t); + SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, w2_t); + SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, w3_t); + SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, w4_t); + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, w5_t); + SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, w6_t); + SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, w7_t); + SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, w8_t); + SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, w9_t); + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, wa_t); + SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, wb_t); + SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, wc_t); + SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, wd_t); + SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, we_t); + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, wf_t); + w0_t = hc_rotl32_S ((wd_t ^ w8_t ^ w2_t ^ w0_t), 1u); SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, w0_t); + w1_t = hc_rotl32_S ((we_t ^ w9_t ^ w3_t ^ w1_t), 1u); SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, w1_t); + w2_t = hc_rotl32_S ((wf_t ^ wa_t ^ w4_t ^ w2_t), 1u); SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, w2_t); + w3_t = hc_rotl32_S ((w0_t ^ wb_t ^ w5_t ^ w3_t), 1u); SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, w3_t); + + #undef K + #define K SHA1C01 + + w4_t = hc_rotl32_S ((w1_t ^ wc_t ^ w6_t ^ w4_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w4_t); + w5_t = hc_rotl32_S ((w2_t ^ wd_t ^ w7_t ^ w5_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w5_t); + w6_t = hc_rotl32_S ((w3_t ^ we_t ^ w8_t ^ w6_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w6_t); + w7_t = hc_rotl32_S ((w4_t ^ wf_t ^ w9_t ^ w7_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w7_t); + w8_t = hc_rotl32_S ((w5_t ^ w0_t ^ wa_t ^ w8_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w8_t); + w9_t = hc_rotl32_S ((w6_t ^ w1_t ^ wb_t ^ w9_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w9_t); + wa_t = hc_rotl32_S ((w7_t ^ w2_t ^ wc_t ^ wa_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, wa_t); + wb_t = hc_rotl32_S ((w8_t ^ w3_t ^ wd_t ^ wb_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, wb_t); + wc_t = hc_rotl32_S ((w9_t ^ w4_t ^ we_t ^ wc_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, wc_t); + wd_t = hc_rotl32_S ((wa_t ^ w5_t ^ wf_t ^ wd_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, wd_t); + we_t = hc_rotl32_S ((wb_t ^ w6_t ^ w0_t ^ we_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, we_t); + wf_t = hc_rotl32_S ((wc_t ^ w7_t ^ w1_t ^ wf_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, wf_t); + w0_t = hc_rotl32_S ((wd_t ^ w8_t ^ w2_t ^ w0_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w0_t); + w1_t = hc_rotl32_S ((we_t ^ w9_t ^ w3_t ^ w1_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w1_t); + w2_t = hc_rotl32_S ((wf_t ^ wa_t ^ w4_t ^ w2_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w2_t); + w3_t = hc_rotl32_S ((w0_t ^ wb_t ^ w5_t ^ w3_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w3_t); + w4_t = hc_rotl32_S ((w1_t ^ wc_t ^ w6_t ^ w4_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w4_t); + w5_t = hc_rotl32_S ((w2_t ^ wd_t ^ w7_t ^ w5_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w5_t); + w6_t = hc_rotl32_S ((w3_t ^ we_t ^ w8_t ^ w6_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w6_t); + w7_t = hc_rotl32_S ((w4_t ^ wf_t ^ w9_t ^ w7_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w7_t); + + #undef K + #define K SHA1C02 + + w8_t = hc_rotl32_S ((w5_t ^ w0_t ^ wa_t ^ w8_t), 1u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, w8_t); + w9_t = hc_rotl32_S ((w6_t ^ w1_t ^ wb_t ^ w9_t), 1u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, w9_t); + wa_t = hc_rotl32_S ((w7_t ^ w2_t ^ wc_t ^ wa_t), 1u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, wa_t); + wb_t = hc_rotl32_S ((w8_t ^ w3_t ^ wd_t ^ wb_t), 1u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, wb_t); + wc_t = hc_rotl32_S ((w9_t ^ w4_t ^ we_t ^ wc_t), 1u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, wc_t); + wd_t = hc_rotl32_S ((wa_t ^ w5_t ^ wf_t ^ wd_t), 1u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, wd_t); + we_t = hc_rotl32_S ((wb_t ^ w6_t ^ w0_t ^ we_t), 1u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, we_t); + wf_t = hc_rotl32_S ((wc_t ^ w7_t ^ w1_t ^ wf_t), 1u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, wf_t); + w0_t = hc_rotl32_S ((wd_t ^ w8_t ^ w2_t ^ w0_t), 1u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, w0_t); + w1_t = hc_rotl32_S ((we_t ^ w9_t ^ w3_t ^ w1_t), 1u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, w1_t); + w2_t = hc_rotl32_S ((wf_t ^ wa_t ^ w4_t ^ w2_t), 1u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, w2_t); + w3_t = hc_rotl32_S ((w0_t ^ wb_t ^ w5_t ^ w3_t), 1u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, w3_t); + w4_t = hc_rotl32_S ((w1_t ^ wc_t ^ w6_t ^ w4_t), 1u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, w4_t); + w5_t = hc_rotl32_S ((w2_t ^ wd_t ^ w7_t ^ w5_t), 1u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, w5_t); + w6_t = hc_rotl32_S ((w3_t ^ we_t ^ w8_t ^ w6_t), 1u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, w6_t); + w7_t = hc_rotl32_S ((w4_t ^ wf_t ^ w9_t ^ w7_t), 1u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, w7_t); + w8_t = hc_rotl32_S ((w5_t ^ w0_t ^ wa_t ^ w8_t), 1u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, w8_t); + w9_t = hc_rotl32_S ((w6_t ^ w1_t ^ wb_t ^ w9_t), 1u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, w9_t); + wa_t = hc_rotl32_S ((w7_t ^ w2_t ^ wc_t ^ wa_t), 1u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, wa_t); + wb_t = hc_rotl32_S ((w8_t ^ w3_t ^ wd_t ^ wb_t), 1u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, wb_t); + + #undef K + #define K SHA1C03 + + wc_t = hc_rotl32_S ((w9_t ^ w4_t ^ we_t ^ wc_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, wc_t); + wd_t = hc_rotl32_S ((wa_t ^ w5_t ^ wf_t ^ wd_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, wd_t); + we_t = hc_rotl32_S ((wb_t ^ w6_t ^ w0_t ^ we_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, we_t); + wf_t = hc_rotl32_S ((wc_t ^ w7_t ^ w1_t ^ wf_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, wf_t); + w0_t = hc_rotl32_S ((wd_t ^ w8_t ^ w2_t ^ w0_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w0_t); + w1_t = hc_rotl32_S ((we_t ^ w9_t ^ w3_t ^ w1_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w1_t); + w2_t = hc_rotl32_S ((wf_t ^ wa_t ^ w4_t ^ w2_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w2_t); + w3_t = hc_rotl32_S ((w0_t ^ wb_t ^ w5_t ^ w3_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w3_t); + w4_t = hc_rotl32_S ((w1_t ^ wc_t ^ w6_t ^ w4_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w4_t); + w5_t = hc_rotl32_S ((w2_t ^ wd_t ^ w7_t ^ w5_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w5_t); + w6_t = hc_rotl32_S ((w3_t ^ we_t ^ w8_t ^ w6_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w6_t); + w7_t = hc_rotl32_S ((w4_t ^ wf_t ^ w9_t ^ w7_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w7_t); + w8_t = hc_rotl32_S ((w5_t ^ w0_t ^ wa_t ^ w8_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w8_t); + w9_t = hc_rotl32_S ((w6_t ^ w1_t ^ wb_t ^ w9_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w9_t); + wa_t = hc_rotl32_S ((w7_t ^ w2_t ^ wc_t ^ wa_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, wa_t); + wb_t = hc_rotl32_S ((w8_t ^ w3_t ^ wd_t ^ wb_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, wb_t); + wc_t = hc_rotl32_S ((w9_t ^ w4_t ^ we_t ^ wc_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, wc_t); + wd_t = hc_rotl32_S ((wa_t ^ w5_t ^ wf_t ^ wd_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, wd_t); + we_t = hc_rotl32_S ((wb_t ^ w6_t ^ w0_t ^ we_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, we_t); + wf_t = hc_rotl32_S ((wc_t ^ w7_t ^ w1_t ^ wf_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, wf_t); + + t[ 0] = w0_t; + t[ 1] = w1_t; + t[ 2] = w2_t; + t[ 3] = w3_t; + t[ 4] = w4_t; + t[ 5] = w5_t; + t[ 6] = w6_t; + t[ 7] = w7_t; + t[ 8] = w8_t; + t[ 9] = w9_t; + t[10] = wa_t; + t[11] = wb_t; + t[12] = wc_t; + t[13] = wd_t; + t[14] = we_t; + t[15] = wf_t; + + #undef K + + #else + + u32 w00_t = w0[0]; + u32 w01_t = w0[1]; + u32 w02_t = w0[2]; + u32 w03_t = w0[3]; + u32 w04_t = w1[0]; + u32 w05_t = w1[1]; + u32 w06_t = w1[2]; + u32 w07_t = w1[3]; + u32 w08_t = w2[0]; + u32 w09_t = w2[1]; + u32 w0a_t = w2[2]; + u32 w0b_t = w2[3]; + u32 w0c_t = w3[0]; + u32 w0d_t = w3[1]; + u32 w0e_t = w3[2]; + u32 w0f_t = w3[3]; + u32 w10_t; + u32 w11_t; + u32 w12_t; + u32 w13_t; + u32 w14_t; + u32 w15_t; + u32 w16_t; + u32 w17_t; + u32 w18_t; + u32 w19_t; + u32 w1a_t; + u32 w1b_t; + u32 w1c_t; + u32 w1d_t; + u32 w1e_t; + u32 w1f_t; + u32 w20_t; + u32 w21_t; + u32 w22_t; + u32 w23_t; + u32 w24_t; + u32 w25_t; + u32 w26_t; + u32 w27_t; + u32 w28_t; + u32 w29_t; + u32 w2a_t; + u32 w2b_t; + u32 w2c_t; + u32 w2d_t; + u32 w2e_t; + u32 w2f_t; + u32 w30_t; + u32 w31_t; + u32 w32_t; + u32 w33_t; + u32 w34_t; + u32 w35_t; + u32 w36_t; + u32 w37_t; + u32 w38_t; + u32 w39_t; + u32 w3a_t; + u32 w3b_t; + u32 w3c_t; + u32 w3d_t; + u32 w3e_t; + u32 w3f_t; + u32 w40_t; + u32 w41_t; + u32 w42_t; + u32 w43_t; + u32 w44_t; + u32 w45_t; + u32 w46_t; + u32 w47_t; + u32 w48_t; + u32 w49_t; + u32 w4a_t; + u32 w4b_t; + u32 w4c_t; + u32 w4d_t; + u32 w4e_t; + u32 w4f_t; + + #define K SHA1C00 + + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, w00_t); + SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, w01_t); + SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, w02_t); + SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, w03_t); + SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, w04_t); + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, w05_t); + SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, w06_t); + SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, w07_t); + SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, w08_t); + SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, w09_t); + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, w0a_t); + SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, w0b_t); + SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, w0c_t); + SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, w0d_t); + SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, w0e_t); + SHA1_STEP_S (SHA1_F0o, a, b, c, d, e, w0f_t); + w10_t = hc_rotl32_S ((w0d_t ^ w08_t ^ w02_t ^ w00_t), 1u); SHA1_STEP_S (SHA1_F0o, e, a, b, c, d, w10_t); + w11_t = hc_rotl32_S ((w0e_t ^ w09_t ^ w03_t ^ w01_t), 1u); SHA1_STEP_S (SHA1_F0o, d, e, a, b, c, w11_t); + w12_t = hc_rotl32_S ((w0f_t ^ w0a_t ^ w04_t ^ w02_t), 1u); SHA1_STEP_S (SHA1_F0o, c, d, e, a, b, w12_t); + w13_t = hc_rotl32_S ((w10_t ^ w0b_t ^ w05_t ^ w03_t), 1u); SHA1_STEP_S (SHA1_F0o, b, c, d, e, a, w13_t); + + #undef K + #define K SHA1C01 + + w14_t = hc_rotl32_S ((w11_t ^ w0c_t ^ w06_t ^ w04_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w14_t); + w15_t = hc_rotl32_S ((w12_t ^ w0d_t ^ w07_t ^ w05_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w15_t); + w16_t = hc_rotl32_S ((w13_t ^ w0e_t ^ w08_t ^ w06_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w16_t); + w17_t = hc_rotl32_S ((w14_t ^ w0f_t ^ w09_t ^ w07_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w17_t); + w18_t = hc_rotl32_S ((w15_t ^ w10_t ^ w0a_t ^ w08_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w18_t); + w19_t = hc_rotl32_S ((w16_t ^ w11_t ^ w0b_t ^ w09_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w19_t); + w1a_t = hc_rotl32_S ((w17_t ^ w12_t ^ w0c_t ^ w0a_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w1a_t); + w1b_t = hc_rotl32_S ((w18_t ^ w13_t ^ w0d_t ^ w0b_t), 1u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w1b_t); + w1c_t = hc_rotl32_S ((w19_t ^ w14_t ^ w0e_t ^ w0c_t), 1u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w1c_t); + w1d_t = hc_rotl32_S ((w1a_t ^ w15_t ^ w0f_t ^ w0d_t), 1u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w1d_t); + w1e_t = hc_rotl32_S ((w1b_t ^ w16_t ^ w10_t ^ w0e_t), 1u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w1e_t); + w1f_t = hc_rotl32_S ((w1c_t ^ w17_t ^ w11_t ^ w0f_t), 1u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w1f_t); + w20_t = hc_rotl32_S ((w1a_t ^ w10_t ^ w04_t ^ w00_t), 2u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w20_t); + w21_t = hc_rotl32_S ((w1b_t ^ w11_t ^ w05_t ^ w01_t), 2u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w21_t); + w22_t = hc_rotl32_S ((w1c_t ^ w12_t ^ w06_t ^ w02_t), 2u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w22_t); + w23_t = hc_rotl32_S ((w1d_t ^ w13_t ^ w07_t ^ w03_t), 2u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w23_t); + w24_t = hc_rotl32_S ((w1e_t ^ w14_t ^ w08_t ^ w04_t), 2u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w24_t); + w25_t = hc_rotl32_S ((w1f_t ^ w15_t ^ w09_t ^ w05_t), 2u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w25_t); + w26_t = hc_rotl32_S ((w20_t ^ w16_t ^ w0a_t ^ w06_t), 2u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w26_t); + w27_t = hc_rotl32_S ((w21_t ^ w17_t ^ w0b_t ^ w07_t), 2u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w27_t); + + #undef K + #define K SHA1C02 + + w28_t = hc_rotl32_S ((w22_t ^ w18_t ^ w0c_t ^ w08_t), 2u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, w28_t); + w29_t = hc_rotl32_S ((w23_t ^ w19_t ^ w0d_t ^ w09_t), 2u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, w29_t); + w2a_t = hc_rotl32_S ((w24_t ^ w1a_t ^ w0e_t ^ w0a_t), 2u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, w2a_t); + w2b_t = hc_rotl32_S ((w25_t ^ w1b_t ^ w0f_t ^ w0b_t), 2u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, w2b_t); + w2c_t = hc_rotl32_S ((w26_t ^ w1c_t ^ w10_t ^ w0c_t), 2u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, w2c_t); + w2d_t = hc_rotl32_S ((w27_t ^ w1d_t ^ w11_t ^ w0d_t), 2u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, w2d_t); + w2e_t = hc_rotl32_S ((w28_t ^ w1e_t ^ w12_t ^ w0e_t), 2u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, w2e_t); + w2f_t = hc_rotl32_S ((w29_t ^ w1f_t ^ w13_t ^ w0f_t), 2u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, w2f_t); + w30_t = hc_rotl32_S ((w2a_t ^ w20_t ^ w14_t ^ w10_t), 2u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, w30_t); + w31_t = hc_rotl32_S ((w2b_t ^ w21_t ^ w15_t ^ w11_t), 2u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, w31_t); + w32_t = hc_rotl32_S ((w2c_t ^ w22_t ^ w16_t ^ w12_t), 2u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, w32_t); + w33_t = hc_rotl32_S ((w2d_t ^ w23_t ^ w17_t ^ w13_t), 2u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, w33_t); + w34_t = hc_rotl32_S ((w2e_t ^ w24_t ^ w18_t ^ w14_t), 2u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, w34_t); + w35_t = hc_rotl32_S ((w2f_t ^ w25_t ^ w19_t ^ w15_t), 2u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, w35_t); + w36_t = hc_rotl32_S ((w30_t ^ w26_t ^ w1a_t ^ w16_t), 2u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, w36_t); + w37_t = hc_rotl32_S ((w31_t ^ w27_t ^ w1b_t ^ w17_t), 2u); SHA1_STEP_S (SHA1_F2o, a, b, c, d, e, w37_t); + w38_t = hc_rotl32_S ((w32_t ^ w28_t ^ w1c_t ^ w18_t), 2u); SHA1_STEP_S (SHA1_F2o, e, a, b, c, d, w38_t); + w39_t = hc_rotl32_S ((w33_t ^ w29_t ^ w1d_t ^ w19_t), 2u); SHA1_STEP_S (SHA1_F2o, d, e, a, b, c, w39_t); + w3a_t = hc_rotl32_S ((w34_t ^ w2a_t ^ w1e_t ^ w1a_t), 2u); SHA1_STEP_S (SHA1_F2o, c, d, e, a, b, w3a_t); + w3b_t = hc_rotl32_S ((w35_t ^ w2b_t ^ w1f_t ^ w1b_t), 2u); SHA1_STEP_S (SHA1_F2o, b, c, d, e, a, w3b_t); + + #undef K + #define K SHA1C03 + + w3c_t = hc_rotl32_S ((w36_t ^ w2c_t ^ w20_t ^ w1c_t), 2u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w3c_t); + w3d_t = hc_rotl32_S ((w37_t ^ w2d_t ^ w21_t ^ w1d_t), 2u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w3d_t); + w3e_t = hc_rotl32_S ((w38_t ^ w2e_t ^ w22_t ^ w1e_t), 2u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w3e_t); + w3f_t = hc_rotl32_S ((w39_t ^ w2f_t ^ w23_t ^ w1f_t), 2u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w3f_t); + w40_t = hc_rotl32_S ((w34_t ^ w20_t ^ w08_t ^ w00_t), 4u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w40_t); + w41_t = hc_rotl32_S ((w35_t ^ w21_t ^ w09_t ^ w01_t), 4u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w41_t); + w42_t = hc_rotl32_S ((w36_t ^ w22_t ^ w0a_t ^ w02_t), 4u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w42_t); + w43_t = hc_rotl32_S ((w37_t ^ w23_t ^ w0b_t ^ w03_t), 4u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w43_t); + w44_t = hc_rotl32_S ((w38_t ^ w24_t ^ w0c_t ^ w04_t), 4u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w44_t); + w45_t = hc_rotl32_S ((w39_t ^ w25_t ^ w0d_t ^ w05_t), 4u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w45_t); + w46_t = hc_rotl32_S ((w3a_t ^ w26_t ^ w0e_t ^ w06_t), 4u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w46_t); + w47_t = hc_rotl32_S ((w3b_t ^ w27_t ^ w0f_t ^ w07_t), 4u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w47_t); + w48_t = hc_rotl32_S ((w3c_t ^ w28_t ^ w10_t ^ w08_t), 4u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w48_t); + w49_t = hc_rotl32_S ((w3d_t ^ w29_t ^ w11_t ^ w09_t), 4u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w49_t); + w4a_t = hc_rotl32_S ((w3e_t ^ w2a_t ^ w12_t ^ w0a_t), 4u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w4a_t); + w4b_t = hc_rotl32_S ((w3f_t ^ w2b_t ^ w13_t ^ w0b_t), 4u); SHA1_STEP_S (SHA1_F1, a, b, c, d, e, w4b_t); + w4c_t = hc_rotl32_S ((w40_t ^ w2c_t ^ w14_t ^ w0c_t), 4u); SHA1_STEP_S (SHA1_F1, e, a, b, c, d, w4c_t); + w4d_t = hc_rotl32_S ((w41_t ^ w2d_t ^ w15_t ^ w0d_t), 4u); SHA1_STEP_S (SHA1_F1, d, e, a, b, c, w4d_t); + w4e_t = hc_rotl32_S ((w42_t ^ w2e_t ^ w16_t ^ w0e_t), 4u); SHA1_STEP_S (SHA1_F1, c, d, e, a, b, w4e_t); + w4f_t = hc_rotl32_S ((w43_t ^ w2f_t ^ w17_t ^ w0f_t), 4u); SHA1_STEP_S (SHA1_F1, b, c, d, e, a, w4f_t); + + t[ 0] = w40_t; + t[ 1] = w41_t; + t[ 2] = w42_t; + t[ 3] = w43_t; + t[ 4] = w44_t; + t[ 5] = w45_t; + t[ 6] = w46_t; + t[ 7] = w47_t; + t[ 8] = w48_t; + t[ 9] = w49_t; + t[10] = w4a_t; + t[11] = w4b_t; + t[12] = w4c_t; + t[13] = w4d_t; + t[14] = w4e_t; + t[15] = w4f_t; + + #undef K + #endif + + digest[0] += a; + digest[1] += b; + digest[2] += c; + digest[3] += d; + digest[4] += e; +} + +// only change in this function compared to OpenCL/inc_hash_sha1.cl is that +// it calls our modified sha1_transform_rar29 () function + +DECLSPEC void sha1_update_64_rar29 (sha1_ctx_t *ctx, u32 *w0, u32 *w1, u32 *w2, u32 *w3, const int bytes, u32 *t) +{ + MAYBE_VOLATILE const int pos = ctx->len & 63; + + int len = 64; + + if (bytes < 64) + { + len = bytes; + } + + ctx->len += len; + + if (pos == 0) + { + ctx->w0[0] = w0[0]; + ctx->w0[1] = w0[1]; + ctx->w0[2] = w0[2]; + ctx->w0[3] = w0[3]; + ctx->w1[0] = w1[0]; + ctx->w1[1] = w1[1]; + ctx->w1[2] = w1[2]; + ctx->w1[3] = w1[3]; + ctx->w2[0] = w2[0]; + ctx->w2[1] = w2[1]; + ctx->w2[2] = w2[2]; + ctx->w2[3] = w2[3]; + ctx->w3[0] = w3[0]; + ctx->w3[1] = w3[1]; + ctx->w3[2] = w3[2]; + ctx->w3[3] = w3[3]; + + if (len == 64) + { + sha1_transform_rar29 (ctx->w0, ctx->w1, ctx->w2, ctx->w3, ctx->h, t); + + ctx->w0[0] = 0; + ctx->w0[1] = 0; + ctx->w0[2] = 0; + ctx->w0[3] = 0; + ctx->w1[0] = 0; + ctx->w1[1] = 0; + ctx->w1[2] = 0; + ctx->w1[3] = 0; + ctx->w2[0] = 0; + ctx->w2[1] = 0; + ctx->w2[2] = 0; + ctx->w2[3] = 0; + ctx->w3[0] = 0; + ctx->w3[1] = 0; + ctx->w3[2] = 0; + ctx->w3[3] = 0; + } + } + else + { + if ((pos + len) < 64) + { + switch_buffer_by_offset_be_S (w0, w1, w2, w3, pos); + + ctx->w0[0] |= w0[0]; + ctx->w0[1] |= w0[1]; + ctx->w0[2] |= w0[2]; + ctx->w0[3] |= w0[3]; + ctx->w1[0] |= w1[0]; + ctx->w1[1] |= w1[1]; + ctx->w1[2] |= w1[2]; + ctx->w1[3] |= w1[3]; + ctx->w2[0] |= w2[0]; + ctx->w2[1] |= w2[1]; + ctx->w2[2] |= w2[2]; + ctx->w2[3] |= w2[3]; + ctx->w3[0] |= w3[0]; + ctx->w3[1] |= w3[1]; + ctx->w3[2] |= w3[2]; + ctx->w3[3] |= w3[3]; + } + else + { + u32 c0[4] = { 0 }; + u32 c1[4] = { 0 }; + u32 c2[4] = { 0 }; + u32 c3[4] = { 0 }; + + switch_buffer_by_offset_carry_be_S (w0, w1, w2, w3, c0, c1, c2, c3, pos); + + ctx->w0[0] |= w0[0]; + ctx->w0[1] |= w0[1]; + ctx->w0[2] |= w0[2]; + ctx->w0[3] |= w0[3]; + ctx->w1[0] |= w1[0]; + ctx->w1[1] |= w1[1]; + ctx->w1[2] |= w1[2]; + ctx->w1[3] |= w1[3]; + ctx->w2[0] |= w2[0]; + ctx->w2[1] |= w2[1]; + ctx->w2[2] |= w2[2]; + ctx->w2[3] |= w2[3]; + ctx->w3[0] |= w3[0]; + ctx->w3[1] |= w3[1]; + ctx->w3[2] |= w3[2]; + ctx->w3[3] |= w3[3]; + + sha1_transform_rar29 (ctx->w0, ctx->w1, ctx->w2, ctx->w3, ctx->h, t); + + ctx->w0[0] = c0[0]; + ctx->w0[1] = c0[1]; + ctx->w0[2] = c0[2]; + ctx->w0[3] = c0[3]; + ctx->w1[0] = c1[0]; + ctx->w1[1] = c1[1]; + ctx->w1[2] = c1[2]; + ctx->w1[3] = c1[3]; + ctx->w2[0] = c2[0]; + ctx->w2[1] = c2[1]; + ctx->w2[2] = c2[2]; + ctx->w2[3] = c2[3]; + ctx->w3[0] = c3[0]; + ctx->w3[1] = c3[1]; + ctx->w3[2] = c3[2]; + ctx->w3[3] = c3[3]; + } + } +} + +// main change in this function compared to OpenCL/inc_hash_sha1.cl is that +// we call sha1_update_64_rar29 () and sometimes replace w[] + +DECLSPEC void sha1_update_rar29 (sha1_ctx_t *ctx, u32 *w, const int len) +{ + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + MAYBE_VOLATILE const int pos = ctx->len & 63; + + int pos1 = 0; + int pos4 = 0; + + if (len > 64) // or: if (pos1 < (len - 64)) + { + w0[0] = w[pos4 + 0]; + w0[1] = w[pos4 + 1]; + w0[2] = w[pos4 + 2]; + w0[3] = w[pos4 + 3]; + w1[0] = w[pos4 + 4]; + w1[1] = w[pos4 + 5]; + w1[2] = w[pos4 + 6]; + w1[3] = w[pos4 + 7]; + w2[0] = w[pos4 + 8]; + w2[1] = w[pos4 + 9]; + w2[2] = w[pos4 + 10]; + w2[3] = w[pos4 + 11]; + w3[0] = w[pos4 + 12]; + w3[1] = w[pos4 + 13]; + w3[2] = w[pos4 + 14]; + w3[3] = w[pos4 + 15]; + + sha1_update_64 (ctx, w0, w1, w2, w3, 64); + + pos1 += 64; + pos4 += 16; + } + + for (int diff = 64 - pos; pos1 < len; pos1 += 64, pos4 += 16, diff += 64) + { + w0[0] = w[pos4 + 0]; + w0[1] = w[pos4 + 1]; + w0[2] = w[pos4 + 2]; + w0[3] = w[pos4 + 3]; + w1[0] = w[pos4 + 4]; + w1[1] = w[pos4 + 5]; + w1[2] = w[pos4 + 6]; + w1[3] = w[pos4 + 7]; + w2[0] = w[pos4 + 8]; + w2[1] = w[pos4 + 9]; + w2[2] = w[pos4 + 10]; + w2[3] = w[pos4 + 11]; + w3[0] = w[pos4 + 12]; + w3[1] = w[pos4 + 13]; + w3[2] = w[pos4 + 14]; + w3[3] = w[pos4 + 15]; + + // only major change in this function compared to OpenCL/inc_hash_sha1.cl: + + u32 t[17] = { 0 }; + + sha1_update_64_rar29 (ctx, w0, w1, w2, w3, len - pos1, t); + + + if ((diff + 63) >= len) break; + + // replaces 64 bytes (with offset diff) of the underlying data w[] with t[]: + + // for (int i = 0; i < 16; i++) t[i] = hc_swap32_S (t[i]); + + t[ 0] = hc_swap32_S (t[ 0]); // unroll seems to be faster + t[ 1] = hc_swap32_S (t[ 1]); + t[ 2] = hc_swap32_S (t[ 2]); + t[ 3] = hc_swap32_S (t[ 3]); + t[ 4] = hc_swap32_S (t[ 4]); + t[ 5] = hc_swap32_S (t[ 5]); + t[ 6] = hc_swap32_S (t[ 6]); + t[ 7] = hc_swap32_S (t[ 7]); + t[ 8] = hc_swap32_S (t[ 8]); + t[ 9] = hc_swap32_S (t[ 9]); + t[10] = hc_swap32_S (t[10]); + t[11] = hc_swap32_S (t[11]); + t[12] = hc_swap32_S (t[12]); + t[13] = hc_swap32_S (t[13]); + t[14] = hc_swap32_S (t[14]); + t[15] = hc_swap32_S (t[15]); + + const u32 n_idx = diff / 4; + const u32 n_off = diff % 4; + + if (n_off) + { + const u32 off_mul = n_off * 8; + const u32 off_sub = 32 - off_mul; + + t[16] = (t[15] << off_sub); + t[15] = (t[15] >> off_mul) | (t[14] << off_sub); + t[14] = (t[14] >> off_mul) | (t[13] << off_sub); + t[13] = (t[13] >> off_mul) | (t[12] << off_sub); + t[12] = (t[12] >> off_mul) | (t[11] << off_sub); + t[11] = (t[11] >> off_mul) | (t[10] << off_sub); + t[10] = (t[10] >> off_mul) | (t[ 9] << off_sub); + t[ 9] = (t[ 9] >> off_mul) | (t[ 8] << off_sub); + t[ 8] = (t[ 8] >> off_mul) | (t[ 7] << off_sub); + t[ 7] = (t[ 7] >> off_mul) | (t[ 6] << off_sub); + t[ 6] = (t[ 6] >> off_mul) | (t[ 5] << off_sub); + t[ 5] = (t[ 5] >> off_mul) | (t[ 4] << off_sub); + t[ 4] = (t[ 4] >> off_mul) | (t[ 3] << off_sub); + t[ 3] = (t[ 3] >> off_mul) | (t[ 2] << off_sub); + t[ 2] = (t[ 2] >> off_mul) | (t[ 1] << off_sub); + t[ 1] = (t[ 1] >> off_mul) | (t[ 0] << off_sub); + t[ 0] = (t[ 0] >> off_mul); + } + + w[n_idx] &= 0xffffff00 << ((3 - n_off) * 8); + + w[n_idx] |= t[0]; + + w[n_idx + 1] = t[ 1]; + w[n_idx + 2] = t[ 2]; + w[n_idx + 3] = t[ 3]; + w[n_idx + 4] = t[ 4]; + w[n_idx + 5] = t[ 5]; + w[n_idx + 6] = t[ 6]; + w[n_idx + 7] = t[ 7]; + w[n_idx + 8] = t[ 8]; + w[n_idx + 9] = t[ 9]; + w[n_idx + 10] = t[10]; + w[n_idx + 11] = t[11]; + w[n_idx + 12] = t[12]; + w[n_idx + 13] = t[13]; + w[n_idx + 14] = t[14]; + w[n_idx + 15] = t[15]; + + // the final set is only meaningful: if (n_off) + + w[n_idx + 16] &= 0xffffffff >> (n_off * 8); + + w[n_idx + 16] |= t[16]; + } +} + +KERNEL_FQ void m23800_init (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, rar3_t)) +{ + /** + * base + */ + + const u64 gid = get_global_id (0); + + if (gid >= gid_max) return; + + tmps[gid].dgst[0] = SHA1M_A; + tmps[gid].dgst[1] = SHA1M_B; + tmps[gid].dgst[2] = SHA1M_C; + tmps[gid].dgst[3] = SHA1M_D; + tmps[gid].dgst[4] = SHA1M_E; + + // store pass and salt in tmps: + + const u32 pw_len = pws[gid].pw_len; + + // first set the utf16le pass: + + u32 w[80] = { 0 }; + + for (u32 i = 0, j = 0, k = 0; i < pw_len; i += 16, j += 4, k += 8) + { + u32 a[4]; + + a[0] = pws[gid].i[j + 0]; + a[1] = pws[gid].i[j + 1]; + a[2] = pws[gid].i[j + 2]; + a[3] = pws[gid].i[j + 3]; + + u32 b[4]; + u32 c[4]; + + make_utf16le (a, b, c); + + w[k + 0] = hc_swap32_S (b[0]); + w[k + 1] = hc_swap32_S (b[1]); + w[k + 2] = hc_swap32_S (b[2]); + w[k + 3] = hc_swap32_S (b[3]); + w[k + 4] = hc_swap32_S (c[0]); + w[k + 5] = hc_swap32_S (c[1]); + w[k + 6] = hc_swap32_S (c[2]); + w[k + 7] = hc_swap32_S (c[3]); + } + + // append salt: + + const u32 salt_idx = (pw_len * 2) / 4; + const u32 salt_off = (pw_len * 2) & 3; + + u32 salt_buf[3]; + + salt_buf[0] = hc_swap32_S (salt_bufs[salt_pos].salt_buf[0]); // swap needed due to -O kernel + salt_buf[1] = hc_swap32_S (salt_bufs[salt_pos].salt_buf[1]); + salt_buf[2] = 0; + + // switch buffer by offset (can only be 0 or 2 because of utf16): + + if (salt_off == 2) // or just: if (salt_off) + { + salt_buf[2] = (salt_buf[1] << 16); + salt_buf[1] = (salt_buf[1] >> 16) | (salt_buf[0] << 16); + salt_buf[0] = (salt_buf[0] >> 16); + } + + w[salt_idx] |= salt_buf[0]; + + w[salt_idx + 1] = salt_buf[1]; + w[salt_idx + 2] = salt_buf[2]; + + // store initial w[] (pass and salt) in tmps: + + for (u32 i = 0; i < 66; i++) // unroll ? + { + tmps[gid].w[i] = w[i]; + } + + // iv: + + tmps[gid].iv[0] = 0; + tmps[gid].iv[1] = 0; + tmps[gid].iv[2] = 0; + tmps[gid].iv[3] = 0; +} + +KERNEL_FQ void m23800_loop (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, rar3_t)) +{ + const u64 gid = get_global_id (0); + + if (gid >= gid_max) return; + + /** + * base + */ + + const u32 pw_len = pws[gid].pw_len; + + const u32 salt_len = 8; + + const u32 pw_salt_len = (pw_len * 2) + salt_len; + + const u32 p3 = pw_salt_len + 3; + + u32 w[80] = { 0 }; // 64 byte aligned + + for (u32 i = 0; i < 66; i++) // unroll ? + { + w[i] = tmps[gid].w[i]; + } + + // update IV: + + const u32 init_pos = loop_pos / (ROUNDS / 16); + + sha1_ctx_t ctx_iv; + + sha1_init (&ctx_iv); + + ctx_iv.h[0] = tmps[gid].dgst[0]; + ctx_iv.h[1] = tmps[gid].dgst[1]; + ctx_iv.h[2] = tmps[gid].dgst[2]; + ctx_iv.h[3] = tmps[gid].dgst[3]; + ctx_iv.h[4] = tmps[gid].dgst[4]; + + ctx_iv.len = loop_pos * p3; + + sha1_update_rar29 (&ctx_iv, w, pw_salt_len); + + memcat8c_be (ctx_iv.w0, ctx_iv.w1, ctx_iv.w2, ctx_iv.w3, ctx_iv.len, hc_swap32_S (loop_pos), ctx_iv.h); + + ctx_iv.len += 3; + + + // copy the context from ctx_iv to ctx: + + sha1_ctx_t ctx; + + ctx.h[0] = ctx_iv.h[0]; + ctx.h[1] = ctx_iv.h[1]; + ctx.h[2] = ctx_iv.h[2]; + ctx.h[3] = ctx_iv.h[3]; + ctx.h[4] = ctx_iv.h[4]; + + ctx.w0[0] = ctx_iv.w0[0]; + ctx.w0[1] = ctx_iv.w0[1]; + ctx.w0[2] = ctx_iv.w0[2]; + ctx.w0[3] = ctx_iv.w0[3]; + + ctx.w1[0] = ctx_iv.w1[0]; + ctx.w1[1] = ctx_iv.w1[1]; + ctx.w1[2] = ctx_iv.w1[2]; + ctx.w1[3] = ctx_iv.w1[3]; + + ctx.w2[0] = ctx_iv.w2[0]; + ctx.w2[1] = ctx_iv.w2[1]; + ctx.w2[2] = ctx_iv.w2[2]; + ctx.w2[3] = ctx_iv.w2[3]; + + ctx.w3[0] = ctx_iv.w3[0]; + ctx.w3[1] = ctx_iv.w3[1]; + ctx.w3[2] = ctx_iv.w3[2]; + ctx.w3[3] = ctx_iv.w3[3]; + + ctx.len = p3; // or ctx_iv.len ? + + // final () for the IV byte: + + sha1_final (&ctx_iv); + + const u32 iv_idx = init_pos / 4; + const u32 iv_off = init_pos % 4; + + tmps[gid].iv[iv_idx] |= (ctx_iv.h[4] & 0xff) << (iv_off * 8); + + // main loop: + + for (u32 i = 0, j = (loop_pos + 1); i < 16383; i++, j++) + { + sha1_update_rar29 (&ctx, w, pw_salt_len); + + memcat8c_be (ctx.w0, ctx.w1, ctx.w2, ctx.w3, ctx.len, hc_swap32_S (j), ctx.h); + + ctx.len += 3; + } + + tmps[gid].dgst[0] = ctx.h[0]; + tmps[gid].dgst[1] = ctx.h[1]; + tmps[gid].dgst[2] = ctx.h[2]; + tmps[gid].dgst[3] = ctx.h[3]; + tmps[gid].dgst[4] = ctx.h[4]; + + // only needed if pw_len > 28: + + for (u32 i = 0; i < 66; i++) // unroll ? + { + tmps[gid].w[i] = w[i]; + } +} + +KERNEL_FQ void m23800_hook23 (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, rar3_t)) +{ + const u64 gid = get_global_id (0); + const u64 lid = get_local_id (0); + const u64 lsz = get_local_size (0); + + /** + * aes shared + */ + + #ifdef REAL_SHM + + LOCAL_VK u32 s_td0[256]; + LOCAL_VK u32 s_td1[256]; + LOCAL_VK u32 s_td2[256]; + LOCAL_VK u32 s_td3[256]; + LOCAL_VK u32 s_td4[256]; + + LOCAL_VK u32 s_te0[256]; + LOCAL_VK u32 s_te1[256]; + LOCAL_VK u32 s_te2[256]; + LOCAL_VK u32 s_te3[256]; + LOCAL_VK u32 s_te4[256]; + + for (u32 i = lid; i < 256; i += lsz) + { + s_td0[i] = td0[i]; + s_td1[i] = td1[i]; + s_td2[i] = td2[i]; + s_td3[i] = td3[i]; + s_td4[i] = td4[i]; + + s_te0[i] = te0[i]; + s_te1[i] = te1[i]; + s_te2[i] = te2[i]; + s_te3[i] = te3[i]; + s_te4[i] = te4[i]; + } + + #else + + CONSTANT_AS u32a *s_td0 = td0; + CONSTANT_AS u32a *s_td1 = td1; + CONSTANT_AS u32a *s_td2 = td2; + CONSTANT_AS u32a *s_td3 = td3; + CONSTANT_AS u32a *s_td4 = td4; + + CONSTANT_AS u32a *s_te0 = te0; + CONSTANT_AS u32a *s_te1 = te1; + CONSTANT_AS u32a *s_te2 = te2; + CONSTANT_AS u32a *s_te3 = te3; + CONSTANT_AS u32a *s_te4 = te4; + + #endif + + SYNC_THREADS (); + + if (gid >= gid_max) return; + + /** + * base + */ + + const u32 pw_len = pws[gid].pw_len; + + const u32 salt_len = 8; + + const u32 pw_salt_len = (pw_len * 2) + salt_len; + + const u32 p3 = pw_salt_len + 3; + + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + w0[0] = 0x80000000; + w0[1] = 0; + w0[2] = 0; + w0[3] = 0; + w1[0] = 0; + w1[1] = 0; + w1[2] = 0; + w1[3] = 0; + w2[0] = 0; + w2[1] = 0; + w2[2] = 0; + w2[3] = 0; + w3[0] = 0; + w3[1] = 0; + w3[2] = 0; + w3[3] = (ROUNDS * p3) * 8; + + u32 h[5]; + + h[0] = tmps[gid].dgst[0]; + h[1] = tmps[gid].dgst[1]; + h[2] = tmps[gid].dgst[2]; + h[3] = tmps[gid].dgst[3]; + h[4] = tmps[gid].dgst[4]; + + u32 iv[4]; + + iv[0] = tmps[gid].iv[0]; + iv[1] = tmps[gid].iv[1]; + iv[2] = tmps[gid].iv[2]; + iv[3] = tmps[gid].iv[3]; + + sha1_transform (w0, w1, w2, w3, h); + + hooks[gid].key[0] = h[0]; + hooks[gid].key[1] = h[1]; + hooks[gid].key[2] = h[2]; + hooks[gid].key[3] = h[3]; + + hooks[gid].iv[0] = iv[0]; + hooks[gid].iv[1] = iv[1]; + hooks[gid].iv[2] = iv[2]; + hooks[gid].iv[3] = iv[3]; + + u32 ukey[4]; + + ukey[0] = hc_swap32_S (h[0]); + ukey[1] = hc_swap32_S (h[1]); + ukey[2] = hc_swap32_S (h[2]); + ukey[3] = hc_swap32_S (h[3]); + + u32 ks[44]; + + AES128_set_decrypt_key (ks, ukey, s_te0, s_te1, s_te2, s_te3, s_td0, s_td1, s_td2, s_td3); + + u32 data[4]; + + data[0] = hc_swap32_S (esalt_bufs[digests_offset].first_block_encrypted[0]); + data[1] = hc_swap32_S (esalt_bufs[digests_offset].first_block_encrypted[1]); + data[2] = hc_swap32_S (esalt_bufs[digests_offset].first_block_encrypted[2]); + data[3] = hc_swap32_S (esalt_bufs[digests_offset].first_block_encrypted[3]); + + u32 out[4]; + + AES128_decrypt (ks, data, out, s_td0, s_td1, s_td2, s_td3, s_td4); + + out[0] ^= hc_swap32_S (iv[0]); + out[1] ^= hc_swap32_S (iv[1]); + out[2] ^= hc_swap32_S (iv[2]); + out[3] ^= hc_swap32_S (iv[3]); + + hooks[gid].first_block_decrypted[0] = hc_swap32_S (out[0]); + hooks[gid].first_block_decrypted[1] = hc_swap32_S (out[1]); + hooks[gid].first_block_decrypted[2] = hc_swap32_S (out[2]); + hooks[gid].first_block_decrypted[3] = hc_swap32_S (out[3]); +} + +KERNEL_FQ void m23800_comp (KERN_ATTR_TMPS_HOOKS_ESALT (rar3_tmp_t, rar3_hook_t, rar3_t)) +{ + /** + * base + */ + + const u64 gid = get_global_id (0); + + if (gid >= gid_max) return; + + u32 crc32 = hooks[gid].crc32; + + const u32 r0 = crc32; + const u32 r1 = 0; + const u32 r2 = 0; + const u32 r3 = 0; + + #define il_pos 0 + + #ifdef KERNEL_STATIC + #include COMPARE_M + #endif +} diff --git a/deps/unrar/hc_decompress_rar.cpp b/deps/unrar/hc_decompress_rar.cpp new file mode 100644 index 000000000..22c0fd7c7 --- /dev/null +++ b/deps/unrar/hc_decompress_rar.cpp @@ -0,0 +1,55 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +// CREDITS go to the UnRAR project from rarlab.com +// see license.txt file + +#include "rar.hpp" + +#define WINSIZE 0x100000 // minimum window size 0x20000 (MinAllocSize is 0x40000), 1 MiB +#define SOLID false +#define METHOD VER_UNPACK // 29 for RAR3 archives + +extern "C" unsigned int hc_decompress_rar (unsigned char *Win, unsigned char *Inp, unsigned char *VM, unsigned char *PPM, const unsigned int OutputSize, const unsigned char *Input, const unsigned int PackSize, const unsigned int UnpackSize, const unsigned char *Key, const unsigned char *IV) +{ + ComprDataIO DataIO; + + DataIO.InitRijindal ((byte *) Key, (byte *) IV); + + DataIO.SetPackedSizeToRead (PackSize); + + DataIO.SetTestMode (false); + DataIO.SetSkipUnpCRC (false); // or 'true', if we use our own crc32 code + DataIO.UnpHash.Init (HASH_CRC32, 1); // 1: 1 single thread ? + + DataIO.SetUnpackFromMemory ((byte *) Input, PackSize); + DataIO.SetUnpackToMemory ((byte *) NULL, UnpackSize); + + Unpack *Unp = new Unpack (&DataIO); + + // not needed in our tests (no false positives): + // memset (Win, 0, UnpackSize); + // #define INPSIZE 0x50000 + // memset (Inp, 0, INPSIZE); + // memset (VM, 0, INPSIZE); + // #define PPMSIZE 216 * 1024 * 1024 + // memset (PPM, 0, PPMSIZE); + + Unp->SetWin (Win); + Unp->SetPPM (PPM); + + Unp->Init (WINSIZE, SOLID); + Unp->SetDestSize (UnpackSize); + + Unp->SetExternalBuffer (Inp, VM); + + Unp->DoUnpack (METHOD, SOLID); // sets output + + unsigned int crc32 = (unsigned int) DataIO.UnpHash.GetCRC32 (); + + delete Unp; + + return crc32; +} diff --git a/docs/changes.txt b/docs/changes.txt index 90ce3e65f..d91b8f607 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -8,6 +8,8 @@ - Added hash-mode: Apple iWork - Added hash-mode: AxCrypt 2 AES-128 - Added hash-mode: AxCrypt 2 AES-256 +- Added hash-mode: RAR3-p (Compressed) +- Added hash-mode: RAR3-p (Uncompressed) - Added hash-mode: RSA/DSA/EC/OPENSSH Private Keys ## diff --git a/docs/credits.txt b/docs/credits.txt index 403a6f261..9a4a17716 100644 --- a/docs/credits.txt +++ b/docs/credits.txt @@ -57,6 +57,7 @@ Other contributors to hashcat * zlib by Jean-loup Gailly and Mark Adler * win-iconv by Yukihiro Nakadaira * micro-ecc by Ken MacKay (used as reference for some secp256k1 operations) +* UnRAR by Alexander Roshal # Furthermore the following persons helped the project: diff --git a/docs/license_libs/UNRAR_LICENSE.txt b/docs/license_libs/UNRAR_LICENSE.txt new file mode 100644 index 000000000..0811276a1 --- /dev/null +++ b/docs/license_libs/UNRAR_LICENSE.txt @@ -0,0 +1,42 @@ + ****** ***** ****** UnRAR - free utility for RAR archives + ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ****** ******* ****** License for use and distribution of + ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ** ** ** ** ** ** FREE portable version + ~~~~~~~~~~~~~~~~~~~~~ + + The source code of UnRAR utility is freeware. This means: + + 1. All copyrights to RAR and the utility UnRAR are exclusively + owned by the author - Alexander Roshal. + + 2. UnRAR source code may be used in any software to handle + RAR archives without limitations free of charge, but cannot be + used to develop RAR (WinRAR) compatible archiver and to + re-create RAR compression algorithm, which is proprietary. + Distribution of modified UnRAR source code in separate form + or as a part of other software is permitted, provided that + full text of this paragraph, starting from "UnRAR source code" + words, is included in license, or in documentation if license + is not available, and in source code comments of resulting package. + + 3. The UnRAR utility may be freely distributed. It is allowed + to distribute UnRAR inside of other software packages. + + 4. THE RAR ARCHIVER AND THE UnRAR UTILITY ARE DISTRIBUTED "AS IS". + NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT + YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS, + DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING + OR MISUSING THIS SOFTWARE. + + 5. Installing and using the UnRAR utility signifies acceptance of + these terms and conditions of the license. + + 6. If you don't agree with terms of the license you must remove + UnRAR files from your storage devices and cease to use the + utility. + + Thank you for your interest in RAR and UnRAR. + + + Alexander L. Roshal diff --git a/docs/readme.txt b/docs/readme.txt index 6bfbecf71..a7e9cb37c 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -295,6 +295,7 @@ NVIDIA GPUs require "NVIDIA Driver" (440.64 or later) and "CUDA Toolkit" (9.0 or - MultiBit HD (scrypt) - 7-Zip - RAR3-hp +- RAR3-p - RAR5 - PKZIP (Compressed) - PKZIP (Compressed Multi-File) diff --git a/src/Makefile b/src/Makefile index de429bac7..00a55b509 100644 --- a/src/Makefile +++ b/src/Makefile @@ -13,6 +13,8 @@ USE_SYSTEM_LZMA ?= 0 USE_SYSTEM_ZLIB ?= 0 USE_SYSTEM_OPENCL ?= 0 USE_SYSTEM_XXHASH ?= 0 +## do not change, requires some hacks +USE_SYSTEM_UNRAR ?= 0 ## ## Detect Operating System @@ -57,6 +59,7 @@ MODULE_INTERFACE_VERSION := 620 ## CC := gcc +CXX := g++ AR := ar FIND := find INSTALL := install @@ -66,6 +69,7 @@ SED_IN_PLACE := -i ifeq ($(UNAME),Darwin) CC := clang +CXX := clang++ # the sed -i option of macOS requires a parameter for the backup file (we just use "") AR := /usr/bin/ar SED := /usr/bin/sed @@ -75,6 +79,7 @@ endif ifeq ($(UNAME),FreeBSD) CC := cc +CXX := c++ SED := gsed endif @@ -133,6 +138,12 @@ else DEPS_XXHASH_PATH := $(LIBRARY_DEV_ROOT_FOLDER) endif +ifeq ($(USE_SYSTEM_UNRAR),0) +DEPS_UNRAR_PATH := deps/unrar +else +DEPS_UNRAR_PATH := $(LIBRARY_DEV_ROOT_FOLDER) +endif + ## ## Filenames for library and frontend ## @@ -185,6 +196,22 @@ CFLAGS_ZLIB += -Wno-unused-parameter CFLAGS_ZLIB += -DIOAPI_NO_64 endif +## because UNRAR +ifeq ($(USE_SYSTEM_UNRAR),0) +CFLAGS_UNRAR += -Wno-unused-variable +CFLAGS_UNRAR += -Wno-unused-parameter +CFLAGS_UNRAR += -Wno-unused-function +CFLAGS_UNRAR += -Wno-sign-compare +CFLAGS_UNRAR += -Wno-dangling-else +CFLAGS_UNRAR += -Wno-switch +CFLAGS_UNRAR += -Wno-parentheses +CFLAGS_UNRAR += -Wno-misleading-indentation +CFLAGS_UNRAR += -Wno-implicit-fallthrough +CFLAGS_UNRAR += -Wno-extra +CFLAGS_UNRAR += -Wno-unknown-pragmas +CFLAGS_UNRAR += -Wno-class-memaccess +endif + ifeq ($(DEBUG),0) CFLAGS += -O2 ifneq ($(UNAME),Darwin) @@ -209,7 +236,7 @@ endif endif endif -CFLAGS += -pipe -std=gnu99 -Iinclude/ -IOpenCL/ +CFLAGS += -pipe -Iinclude/ -IOpenCL/ # LZMA CFLAGS += -I$(DEPS_LZMA_PATH) @@ -240,6 +267,10 @@ ifeq ($(ENABLE_CUBIN),1) CFLAGS += -DWITH_CUBIN endif +# unrar +CFLAGS += -I$(DEPS_UNRAR_PATH) +LFLAGS += -lstdc++ + ## ## Native compilation target ## @@ -297,8 +328,15 @@ LFLAGS_NATIVE += -Wl,--nxcompat LFLAGS_NATIVE += -lpsapi LFLAGS_NATIVE += -liconv LFLAGS_NATIVE += -lws2_32 +LFLAGS_NATIVE += -lpowrprof endif # MSYS2 +# CCFLAGS only for C compiler +CCFLAGS := -std=gnu99 + +# CXXFLAGS only for C++ compiler +CXXFLAGS := + ## ## Objects ## @@ -345,6 +383,14 @@ WIN_OBJS += $(foreach OBJ,$(OBJS_XXHASH),obj/$(OBJ).WIN.o) endif endif +ifeq ($(USE_SYSTEM_UNRAR),0) +OBJS_UNRAR := strlist strfn pathfn smallfn global file filefn filcreat archive arcread unicode system isnt crypt crc rawread encname resource match timefn rdwrfn consio options errhnd rarvm secpassword rijndael getbits sha1 sha256 blake2s hash extinfo extract volume list find unpack headers threadpool rs16 cmddata ui filestr recvol rs scantree qopen hc_decompress_rar + +NATIVE_OBJS += $(foreach OBJ,$(OBJS_UNRAR),obj/$(OBJ).NATIVE.o) +LINUX_OBJS += $(foreach OBJ,$(OBJS_UNRAR),obj/$(OBJ).LINUX.o) +WIN_OBJS += $(foreach OBJ,$(OBJS_UNRAR),obj/$(OBJ).WIN.o) +endif + ## ## Targets: Native Compilation ## @@ -358,6 +404,7 @@ clean: $(RM) -f modules/*.dll $(RM) -f modules/*.so $(RM) -f obj/*/*/*.o + $(RM) -f obj/*/*.o $(RM) -f obj/*.o $(RM) -f obj/*.a $(RM) -rf *.dSYM @@ -484,23 +531,28 @@ uninstall: ## obj/%.NATIVE.o: src/%.c - $(CC) -c $(CFLAGS_NATIVE) $< -o $@ -fpic + $(CC) -c $(CCFLAGS) $(CFLAGS_NATIVE) $< -o $@ -fpic ifeq ($(USE_SYSTEM_LZMA),0) obj/%.NATIVE.o: $(DEPS_LZMA_PATH)/%.c - $(CC) -c $(CFLAGS_NATIVE) $< -o $@ -fpic + $(CC) -c $(CCFLAGS) $(CFLAGS_NATIVE) $< -o $@ -fpic endif ifeq ($(USE_SYSTEM_ZLIB),0) obj/%.NATIVE.o: $(DEPS_ZLIB_PATH)/%.c - $(CC) -c $(CFLAGS_NATIVE) $(CFLAGS_ZLIB) $< -o $@ -fpic + $(CC) -c $(CCFLAGS) $(CFLAGS_NATIVE) $(CFLAGS_ZLIB) $< -o $@ -fpic endif ifeq ($(USE_SYSTEM_XXHASH),0) ifeq ($(ENABLE_BRAIN),1) obj/%.NATIVE.o: $(DEPS_XXHASH_PATH)/%.c - $(CC) -c $(CFLAGS_NATIVE) $< -o $@ -fpic + $(CC) -c $(CCFLAGS) $(CFLAGS_NATIVE) $< -o $@ -fpic +endif endif + +ifeq ($(USE_SYSTEM_UNRAR),0) +obj/%.NATIVE.o: $(DEPS_UNRAR_PATH)/%.cpp + $(CXX) -c $(CXXFLAGS) $(CFLAGS_NATIVE) $(CFLAGS_UNRAR) $< -o $@ -fpic endif obj/combined.NATIVE.a: $(NATIVE_OBJS) @@ -516,10 +568,10 @@ endif ifeq ($(SHARED),1) $(HASHCAT_FRONTEND): src/main.c $(HASHCAT_LIBRARY) - $(CC) $(CFLAGS_NATIVE) $^ -o $@ $(HASHCAT_LIBRARY) $(LFLAGS_NATIVE) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\" + $(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(HASHCAT_LIBRARY) $(LFLAGS_NATIVE) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\" else $(HASHCAT_FRONTEND): src/main.c obj/combined.NATIVE.a - $(CC) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\" + $(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\" endif ## @@ -541,10 +593,10 @@ MODULES_LIB := $(patsubst src/modules/module_%.c, modules/module_%.$(MODULE_SU ifeq ($(SHARED),1) modules/module_%.$(MODULE_SUFFIX): src/modules/module_%.c $(HASHCAT_LIBRARY) - $(CC) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION) + $(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION) else modules/module_%.$(MODULE_SUFFIX): src/modules/module_%.c obj/combined.NATIVE.a - $(CC) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION) + $(CC) $(CCFLAGS) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION) endif modules: $(MODULES_LIB) @@ -560,7 +612,9 @@ ifeq ($(UNAME),Linux) ## CC_LINUX := gcc +CXX_LINUX := g++ CC_WIN := x86_64-w64-mingw32-gcc +CXX_WIN := x86_64-w64-mingw32-g++ AR_LINUX := ar AR_WIN := x86_64-w64-mingw32-ar @@ -593,6 +647,8 @@ LFLAGS_CROSS_WIN += -Wl,--dynamicbase LFLAGS_CROSS_WIN += -Wl,--nxcompat LFLAGS_CROSS_WIN += -lpsapi LFLAGS_CROSS_WIN += -lws2_32 +LFLAGS_CROSS_WIN += -lpowrprof +LFLAGS_CROSS_WIN += -static -static-libgcc -static-libstdc++ ## ## Targets @@ -617,45 +673,53 @@ modules_linux: $(MODULES_LIB_LINUX) modules_win: $(MODULES_LIB_WIN) modules/module_%.so: src/modules/module_%.c obj/combined.LINUX.a - $(CC_LINUX) $(CFLAGS_CROSS_LINUX) $^ -o $@ $(LFLAGS_CROSS_LINUX) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION) + $(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) $^ -o $@ $(LFLAGS_CROSS_LINUX) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION) modules/module_%.dll: src/modules/module_%.c obj/combined.WIN.a - $(CC_WIN) $(CFLAGS_CROSS_WIN) $^ -o $@ $(LFLAGS_CROSS_WIN) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION) + $(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) $^ -o $@ $(LFLAGS_CROSS_WIN) -shared -fPIC -D MODULE_INTERFACE_VERSION_CURRENT=$(MODULE_INTERFACE_VERSION) ## ## cross compiled hashcat ## obj/%.LINUX.o: src/%.c - $(CC_LINUX) $(CFLAGS_CROSS_LINUX) -c -o $@ $< + $(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) -c -o $@ $< obj/%.WIN.o: src/%.c - $(CC_WIN) $(CFLAGS_CROSS_WIN) -c -o $@ $< + $(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) -c -o $@ $< ifeq ($(USE_SYSTEM_LZMA),0) obj/%.LINUX.o: $(DEPS_LZMA_PATH)/%.c - $(CC_LINUX) $(CFLAGS_CROSS_LINUX) -c -o $@ $< + $(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) -c -o $@ $< obj/%.WIN.o: $(DEPS_LZMA_PATH)/%.c - $(CC_WIN) $(CFLAGS_CROSS_WIN) -c -o $@ $< + $(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) -c -o $@ $< endif ifeq ($(USE_SYSTEM_ZLIB),0) obj/%.LINUX.o: $(DEPS_ZLIB_PATH)/%.c - $(CC_LINUX) $(CFLAGS_CROSS_LINUX) $(CFLAGS_ZLIB) -c -o $@ $< + $(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) $(CFLAGS_ZLIB) -c -o $@ $< obj/%.WIN.o: $(DEPS_ZLIB_PATH)/%.c - $(CC_WIN) $(CFLAGS_CROSS_WIN) $(CFLAGS_ZLIB) -c -o $@ $< + $(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) $(CFLAGS_ZLIB) -c -o $@ $< endif ifeq ($(USE_SYSTEM_XXHASH),0) ifeq ($(ENABLE_BRAIN),1) obj/%.LINUX.o: $(DEPS_XXHASH_PATH)/%.c - $(CC_LINUX) $(CFLAGS_CROSS_LINUX) -c -o $@ $< + $(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) -c -o $@ $< obj/%.WIN.o: $(DEPS_XXHASH_PATH)/%.c - $(CC_WIN) $(CFLAGS_CROSS_WIN) -c -o $@ $< + $(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) -c -o $@ $< +endif endif + +ifeq ($(USE_SYSTEM_UNRAR),0) +obj/%.LINUX.o: $(DEPS_UNRAR_PATH)/%.cpp + $(CXX_LINUX) $(CXXFLAGS) $(CFLAGS_CROSS_LINUX) $(CFLAGS_UNRAR) -c -o $@ $< + +obj/%.WIN.o: $(DEPS_UNRAR_PATH)/%.cpp + $(CXX_WIN) $(CXXFLAGS) $(CFLAGS_CROSS_WIN) $(CFLAGS_UNRAR) -c -o $@ $< endif obj/combined.LINUX.a: $(LINUX_OBJS) @@ -665,12 +729,12 @@ obj/combined.WIN.a: $(WIN_OBJS) $(AR_WIN) rcs $@ $^ hashcat.bin: src/main.c obj/combined.LINUX.a - $(CC_LINUX) $(CFLAGS_CROSS_LINUX) -o $@ $^ $(LFLAGS_CROSS_LINUX) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\" + $(CC_LINUX) $(CCFLAGS) $(CFLAGS_CROSS_LINUX) -o $@ $^ $(LFLAGS_CROSS_LINUX) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\" hashcat.exe: src/main.c obj/combined.WIN.a $(WIN_ICONV)/lib/libiconv.a - $(CC_WIN) $(CFLAGS_CROSS_WIN) -o $@ $^ $(LFLAGS_CROSS_WIN) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" + $(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) -o $@ $^ $(LFLAGS_CROSS_WIN) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" hashcat.dll: src/main.c obj/combined.WIN.a $(WIN_ICONV)/lib/libiconv.a - $(CC_WIN) $(CFLAGS_CROSS_WIN) -o $@ $^ $(LFLAGS_CROSS_WIN) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -shared + $(CC_WIN) $(CCFLAGS) $(CFLAGS_CROSS_WIN) -o $@ $^ $(LFLAGS_CROSS_WIN) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -shared endif diff --git a/src/modules/module_23700.c b/src/modules/module_23700.c new file mode 100644 index 000000000..3d099888c --- /dev/null +++ b/src/modules/module_23700.c @@ -0,0 +1,397 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +#include "common.h" +#include "types.h" +#include "modules.h" +#include "bitops.h" +#include "convert.h" +#include "shared.h" + +static const u32 ATTACK_EXEC = ATTACK_EXEC_OUTSIDE_KERNEL; +static const u32 DGST_POS0 = 0; +static const u32 DGST_POS1 = 1; +static const u32 DGST_POS2 = 2; +static const u32 DGST_POS3 = 3; +static const u32 DGST_SIZE = DGST_SIZE_4_4; // actually only DGST_SIZE_4_1 +static const u32 HASH_CATEGORY = HASH_CATEGORY_ARCHIVE; +static const char *HASH_NAME = "RAR3-p (Uncompressed)"; +static const u64 KERN_TYPE = 23700; +static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE; +static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE; +static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "$RAR3$*1*e54a73729887cb53*49b0a846*16*14*1*34620bcca8176642a210b1051901921e*30"; + +u32 module_attack_exec (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ATTACK_EXEC; } +u32 module_dgst_pos0 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS0; } +u32 module_dgst_pos1 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS1; } +u32 module_dgst_pos2 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS2; } +u32 module_dgst_pos3 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS3; } +u32 module_dgst_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_SIZE; } +u32 module_hash_category (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return HASH_CATEGORY; } +const char *module_hash_name (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return HASH_NAME; } +u64 module_kern_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return KERN_TYPE; } +u32 module_opti_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return OPTI_TYPE; } +u64 module_opts_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return OPTS_TYPE; } +u32 module_salt_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return SALT_TYPE; } +const char *module_st_hash (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ST_HASH; } +const char *module_st_pass (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ST_PASS; } + +typedef struct rar3 +{ + u32 data[81920]; + + u32 pack_size; + u32 unpack_size; + +} rar3_t; + +typedef struct rar3_tmp +{ + u32 dgst[5]; + + u32 w[66]; // 256 byte pass + 8 byte salt + + u32 iv[4]; + +} rar3_tmp_t; + +typedef struct rar3_tmp_optimized +{ + u32 dgst[17][5]; + +} rar3_tmp_optimized_t; + +static const int ROUNDS_RAR3 = 262144; +static const char *SIGNATURE_RAR3 = "$RAR3$"; + +u64 module_tmp_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + const bool optimized_kernel = user_options->optimized_kernel_enable; + + u64 tmp_size = (u64) sizeof (rar3_tmp_t); + + if (optimized_kernel == true) + { + tmp_size = (u64) sizeof (rar3_tmp_optimized_t); + } + + return tmp_size; +} + +u64 module_esalt_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + u64 esalt_size = (u64) sizeof (rar3_t); + + return esalt_size; +} + +u32 module_kernel_loops_min (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + const u32 kernel_loops_min = ROUNDS_RAR3 / 16; + + return kernel_loops_min; +} + +u32 module_kernel_loops_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + const u32 kernel_loops_max = ROUNDS_RAR3 / 16; + + return kernel_loops_max; +} + +u32 module_kernel_threads_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + // -T 128 works slightly faster but it's free for the user to change + + const u32 kernel_threads_max = (user_options->kernel_threads_chgd == true) ? user_options->kernel_threads : 128; + + return kernel_threads_max; +} + +u32 module_pw_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + const bool optimized_kernel = (hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL); + + u32 pw_max = 127; + + if (optimized_kernel == true) + { + pw_max = 20; + } + + return pw_max; +} + +const char *module_benchmark_mask (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + const char *mask = "?b?b?b?b?b"; + + return mask; +} + +int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED void *digest_buf, MAYBE_UNUSED salt_t *salt, MAYBE_UNUSED void *esalt_buf, MAYBE_UNUSED void *hook_salt_buf, MAYBE_UNUSED hashinfo_t *hash_info, const char *line_buf, MAYBE_UNUSED const int line_len) +{ + u32 *digest = (u32 *) digest_buf; + + rar3_t *rar3 = (rar3_t *) esalt_buf; + + token_t token; + + token.token_cnt = 9; + + token.signatures_cnt = 1; + token.signatures_buf[0] = SIGNATURE_RAR3; + + token.sep[0] = '*'; + token.len_min[0] = 6; + token.len_max[0] = 6; + token.attr[0] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_SIGNATURE; + + token.sep[1] = '*'; + token.len_min[1] = 1; + token.len_max[1] = 1; + token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + token.sep[2] = '*'; + token.len_min[2] = 16; + token.len_max[2] = 16; + token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + token.sep[3] = '*'; + token.len_min[3] = 8; + token.len_max[3] = 8; + token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + token.sep[4] = '*'; + token.len_min[4] = 1; + token.len_max[4] = 7; + token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + token.sep[5] = '*'; + token.len_min[5] = 1; + token.len_max[5] = 6; + token.attr[5] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + token.sep[6] = '*'; + token.len_min[6] = 1; + token.len_max[6] = 1; + token.attr[6] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + token.sep[7] = '*'; + token.len_min[7] = 2; + token.len_max[7] = 655056; + token.attr[7] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + token.len[8] = 2; + token.attr[8] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); + + const u8 *type_pos = token.buf[1]; + + if (type_pos[0] != '1') return (PARSER_SIGNATURE_UNMATCHED); + + // salt + + const u8 *salt_pos = token.buf[2]; + + salt->salt_buf[0] = hex_to_u32 (salt_pos + 0); + salt->salt_buf[1] = hex_to_u32 (salt_pos + 8); + + salt->salt_len = 8; + salt->salt_iter = ROUNDS_RAR3; + + // CRC32 + + const u8 *crc32_pos = token.buf[3]; + + u32 crc32_sum = hex_to_u32 (crc32_pos); + + // pack size + + const u8 *pack_size_pos = token.buf[4]; + + const u32 pack_size = hc_strtoul ((const char *) pack_size_pos, NULL, 10); + + if (pack_size < 1) return (PARSER_SALT_VALUE); + if (pack_size > 327680) return (PARSER_SALT_VALUE); + + if ((pack_size % 16) != 0) return (PARSER_SALT_VALUE); + + rar3->pack_size = pack_size; + + // unpack size + + const u8 *unpack_size_pos = token.buf[5]; + + const u32 unpack_size = hc_strtoul ((const char *) unpack_size_pos, NULL, 10); + + if (unpack_size < 1) return (PARSER_SALT_VALUE); + if (unpack_size > 655360) return (PARSER_SALT_VALUE); + + if (unpack_size > pack_size) return (PARSER_SALT_VALUE); + + rar3->unpack_size = unpack_size; + + // data is within the hash line + + const u8 *is_data_pos = token.buf[6]; + + if (is_data_pos[0] != '1') return (PARSER_SALT_VALUE); + + // data + + const u8 *data_pos = token.buf[7]; + const u32 data_len = token.len[7]; + + if (data_len != (pack_size * 2)) return (PARSER_SALT_VALUE); + + // like hex decode, but swapped: + // hex_decode (data_pos, data_len, (u8 *) rar3->data); + + for (u32 i = 0, j = 0; i < data_len; i += 8, j++) + { + rar3->data[j] = hex_to_u32 (data_pos + i); + + rar3->data[j] = byte_swap_32 (rar3->data[j]); + } + + // method + + const u8 *method_pos = token.buf[8]; + + const u32 method = hc_strtoul ((const char *) method_pos, NULL, 10); + + if (method != 30) return (PARSER_SALT_VALUE); + + // digest + + digest[0] = crc32_sum ^ 0xffffffff; + digest[1] = 0; + digest[2] = 0; + digest[3] = 0; + + return (PARSER_OK); +} + +int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const void *digest_buf, MAYBE_UNUSED const salt_t *salt, MAYBE_UNUSED const void *esalt_buf, MAYBE_UNUSED const void *hook_salt_buf, MAYBE_UNUSED const hashinfo_t *hash_info, char *line_buf, MAYBE_UNUSED const int line_size) +{ + const u32 *digest = (const u32 *) digest_buf; + const rar3_t *rar3 = (const rar3_t *) esalt_buf; + + u8 data[655360] = { 0 }; + + const u32 data_len = rar3->pack_size; + + // like hex encode, but swapped: + // hex_encode ((const u8 *) rar3->data, rar3->pack_size, data); + + for (u32 i = 0, j = 0; i < data_len / 4; i += 1, j += 8) + { + const u32 d = byte_swap_32 (rar3->data[i]); + + u32_to_hex (d, data + j); + } + + const int line_len = snprintf (line_buf, line_size, "%s*1*%08x%08x*%08x*%u*%u*1*%s*30", + SIGNATURE_RAR3, + byte_swap_32 (salt->salt_buf[0]), + byte_swap_32 (salt->salt_buf[1]), + byte_swap_32 (digest[0]) ^ 0xffffffff, + rar3->pack_size, + rar3->unpack_size, + data); + + return line_len; +} + +void module_init (module_ctx_t *module_ctx) +{ + module_ctx->module_context_size = MODULE_CONTEXT_SIZE_CURRENT; + module_ctx->module_interface_version = MODULE_INTERFACE_VERSION_CURRENT; + + module_ctx->module_attack_exec = module_attack_exec; + module_ctx->module_benchmark_esalt = MODULE_DEFAULT; + module_ctx->module_benchmark_hook_salt = MODULE_DEFAULT; + module_ctx->module_benchmark_mask = module_benchmark_mask; + module_ctx->module_benchmark_salt = MODULE_DEFAULT; + module_ctx->module_build_plain_postprocess = MODULE_DEFAULT; + module_ctx->module_deep_comp_kernel = MODULE_DEFAULT; + module_ctx->module_dgst_pos0 = module_dgst_pos0; + module_ctx->module_dgst_pos1 = module_dgst_pos1; + module_ctx->module_dgst_pos2 = module_dgst_pos2; + module_ctx->module_dgst_pos3 = module_dgst_pos3; + module_ctx->module_dgst_size = module_dgst_size; + module_ctx->module_dictstat_disable = MODULE_DEFAULT; + module_ctx->module_esalt_size = module_esalt_size; + module_ctx->module_extra_buffer_size = MODULE_DEFAULT; + module_ctx->module_extra_tmp_size = MODULE_DEFAULT; + module_ctx->module_forced_outfile_format = MODULE_DEFAULT; + module_ctx->module_hash_binary_count = MODULE_DEFAULT; + module_ctx->module_hash_binary_parse = MODULE_DEFAULT; + module_ctx->module_hash_binary_save = MODULE_DEFAULT; + module_ctx->module_hash_decode_potfile = MODULE_DEFAULT; + module_ctx->module_hash_decode_zero_hash = MODULE_DEFAULT; + module_ctx->module_hash_decode = module_hash_decode; + module_ctx->module_hash_encode_status = MODULE_DEFAULT; + module_ctx->module_hash_encode_potfile = MODULE_DEFAULT; + module_ctx->module_hash_encode = module_hash_encode; + module_ctx->module_hash_init_selftest = MODULE_DEFAULT; + module_ctx->module_hash_mode = MODULE_DEFAULT; + module_ctx->module_hash_category = module_hash_category; + module_ctx->module_hash_name = module_hash_name; + module_ctx->module_hashes_count_min = MODULE_DEFAULT; + module_ctx->module_hashes_count_max = MODULE_DEFAULT; + module_ctx->module_hlfmt_disable = MODULE_DEFAULT; + module_ctx->module_hook_extra_param_size = MODULE_DEFAULT; + module_ctx->module_hook_extra_param_init = MODULE_DEFAULT; + module_ctx->module_hook_extra_param_term = MODULE_DEFAULT; + module_ctx->module_hook12 = MODULE_DEFAULT; + module_ctx->module_hook23 = MODULE_DEFAULT; + module_ctx->module_hook_salt_size = MODULE_DEFAULT; + module_ctx->module_hook_size = MODULE_DEFAULT; + module_ctx->module_jit_build_options = MODULE_DEFAULT; + module_ctx->module_jit_cache_disable = MODULE_DEFAULT; + module_ctx->module_kernel_accel_max = MODULE_DEFAULT; + module_ctx->module_kernel_accel_min = MODULE_DEFAULT; + module_ctx->module_kernel_loops_max = module_kernel_loops_max; + module_ctx->module_kernel_loops_min = module_kernel_loops_min; + module_ctx->module_kernel_threads_max = module_kernel_threads_max; + module_ctx->module_kernel_threads_min = MODULE_DEFAULT; + module_ctx->module_kern_type = module_kern_type; + module_ctx->module_kern_type_dynamic = MODULE_DEFAULT; + module_ctx->module_opti_type = module_opti_type; + module_ctx->module_opts_type = module_opts_type; + module_ctx->module_outfile_check_disable = MODULE_DEFAULT; + module_ctx->module_outfile_check_nocomp = MODULE_DEFAULT; + module_ctx->module_potfile_custom_check = MODULE_DEFAULT; + module_ctx->module_potfile_disable = MODULE_DEFAULT; + module_ctx->module_potfile_keep_all_hashes = MODULE_DEFAULT; + module_ctx->module_pwdump_column = MODULE_DEFAULT; + module_ctx->module_pw_max = module_pw_max; + module_ctx->module_pw_min = MODULE_DEFAULT; + module_ctx->module_salt_max = MODULE_DEFAULT; + module_ctx->module_salt_min = MODULE_DEFAULT; + module_ctx->module_salt_type = module_salt_type; + module_ctx->module_separator = MODULE_DEFAULT; + module_ctx->module_st_hash = module_st_hash; + module_ctx->module_st_pass = module_st_pass; + module_ctx->module_tmp_size = module_tmp_size; + module_ctx->module_unstable_warning = MODULE_DEFAULT; + module_ctx->module_warmup_disable = MODULE_DEFAULT; +} diff --git a/src/modules/module_23800.c b/src/modules/module_23800.c new file mode 100644 index 000000000..9180b735a --- /dev/null +++ b/src/modules/module_23800.c @@ -0,0 +1,663 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +#include "common.h" +#include "types.h" +#include "modules.h" +#include "bitops.h" +#include "convert.h" +#include "shared.h" +#include "memory.h" + +static const u32 ATTACK_EXEC = ATTACK_EXEC_OUTSIDE_KERNEL; +static const u32 DGST_POS0 = 0; +static const u32 DGST_POS1 = 1; +static const u32 DGST_POS2 = 2; +static const u32 DGST_POS3 = 3; +static const u32 DGST_SIZE = DGST_SIZE_4_4; // actually only DGST_SIZE_4_1 +static const u32 HASH_CATEGORY = HASH_CATEGORY_ARCHIVE; +static const char *HASH_NAME = "RAR3-p (Compressed)"; +static const u64 KERN_TYPE = 23800; +static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE; +static const u64 OPTS_TYPE = OPTS_TYPE_PT_GENERATE_LE + | OPTS_TYPE_HOOK23; +static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "$RAR3$*1*ad56eb40219c9da2*834064ce*32*13*1*eb47b1abe17a1a75bce6c92ab1cef3f4126035ea95deaf08b3f32a0c7b8078e1*33"; + +u32 module_attack_exec (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ATTACK_EXEC; } +u32 module_dgst_pos0 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS0; } +u32 module_dgst_pos1 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS1; } +u32 module_dgst_pos2 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS2; } +u32 module_dgst_pos3 (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_POS3; } +u32 module_dgst_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return DGST_SIZE; } +u32 module_hash_category (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return HASH_CATEGORY; } +const char *module_hash_name (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return HASH_NAME; } +u64 module_kern_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return KERN_TYPE; } +u32 module_opti_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return OPTI_TYPE; } +u64 module_opts_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return OPTS_TYPE; } +u32 module_salt_type (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return SALT_TYPE; } +const char *module_st_hash (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ST_HASH; } +const char *module_st_pass (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) { return ST_PASS; } + +typedef struct rar3 +{ + u32 first_block_encrypted[4]; + +} rar3_t; + +typedef struct rar3_tmp +{ + u32 dgst[5]; + + u32 w[66]; // 256 byte pass + 8 byte salt + + u32 iv[4]; + +} rar3_tmp_t; + +typedef struct rar3_tmp_optimized +{ + u32 dgst[17][5]; + +} rar3_tmp_optimized_t; + +typedef struct rar3_hook +{ + u32 key[4]; + u32 iv[4]; + + u32 first_block_decrypted[4]; + + u32 crc32; + +} rar3_hook_t; + +typedef struct rar3_hook_salt +{ + u32 data[81920]; + + u32 pack_size; + u32 unpack_size; + + u32 method; + +} rar3_hook_salt_t; + +typedef struct rar3_hook_extra +{ + void **win; + void **inp; + void **vm; + void **ppm; + +} rar3_hook_extra_t; + +static const int ROUNDS_RAR3 = 262144; +static const char *SIGNATURE_RAR3 = "$RAR3$"; + +#define ADD_BITS(n) \ +{ \ + if (bits < 9) \ + { \ + hold |= ((unsigned int) *next++ << (24 - bits)); \ + bits += 8; \ + } \ + \ + hold <<= n; \ + bits -= n; \ +} + +/* + * The following function was implemented similar to the check_huffman () + * function from John The Ripper. + * Thanks go to magnum and JTR for the permission. + */ + +static int check_huffman (const unsigned char *next) +{ + unsigned int bits; + unsigned int hold; + unsigned int i; + int left; + unsigned int ncount[4]; + unsigned char *count = (unsigned char*) ncount; + unsigned char bit_length[20]; + + hold = next[3] + + (((unsigned int) next[2]) << 8) + + (((unsigned int) next[1]) << 16) + + (((unsigned int) next[0]) << 24); + + next += 4; // we already have the first 32 bits + hold <<= 2; // we already processed 2 bits, PPM and keepOldTable + bits = 32 - 2; + + /* First, read 20 pairs of (bitlength[, zerocount]) */ + for (i = 0; i < 20; i++) + { + int length, zero_count; + + length = hold >> 28; + + ADD_BITS (4); + + if (length == 15) + { + zero_count = hold >> 28; + + ADD_BITS (4); + + if (zero_count == 0) + { + bit_length[i] = 15; + } + else + { + zero_count += 2; + + while (zero_count-- > 0 && i < sizeof(bit_length) / sizeof (bit_length[0])) + { + bit_length[i++] = 0; + } + + i--; + } + } + else + { + bit_length[i] = length; + } + } + + /* Count the number of codes for each code length */ + memset (count, 0, 16); + + for (i = 0; i < 20; i++) + { + ++count[bit_length[i]]; + } + + count[0] = 0; + + if (!ncount[0] && !ncount[1] && !ncount[2] && !ncount[3]) return 0; /* No codes at all */ + + left = 1; + + for (i = 1; i < 16; ++i) + { + left <<= 1; + left -= count[i]; + + if (left < 0) return 0; /* over-subscribed */ + } + + if (left) return 0; /* incomplete set */ + + return 1; /* Passed this check! */ +} + +bool module_hook_extra_param_init (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra, MAYBE_UNUSED const folder_config_t *folder_config, MAYBE_UNUSED const backend_ctx_t *backend_ctx, void *hook_extra_param) +{ + rar3_hook_extra_t *rar3_hook_extra = (rar3_hook_extra_t *) hook_extra_param; + + #define WINSIZE 0x100000 + #define INPSIZE 0x50000 + #define PPMSIZE 216 * 1024 * 1024 + + rar3_hook_extra->win = hccalloc (backend_ctx->backend_devices_cnt, sizeof (void *)); + + if (rar3_hook_extra->win == NULL) return false; + + rar3_hook_extra->inp = hccalloc (backend_ctx->backend_devices_cnt, sizeof (void *)); + + if (rar3_hook_extra->inp == NULL) return false; + + rar3_hook_extra->vm = hccalloc (backend_ctx->backend_devices_cnt, sizeof (void *)); + + if (rar3_hook_extra->vm == NULL) return false; + + rar3_hook_extra->ppm = hccalloc (backend_ctx->backend_devices_cnt, sizeof (void *)); + + if (rar3_hook_extra->ppm == NULL) return false; + + for (int backend_devices_idx = 0; backend_devices_idx < backend_ctx->backend_devices_cnt; backend_devices_idx++) + { + hc_device_param_t *device_param = &backend_ctx->devices_param[backend_devices_idx]; + + if (device_param->skipped == true) continue; + + rar3_hook_extra->win[backend_devices_idx] = hcmalloc (WINSIZE); + + if (rar3_hook_extra->win[backend_devices_idx] == NULL) return false; + + rar3_hook_extra->inp[backend_devices_idx] = hcmalloc (INPSIZE); + + if (rar3_hook_extra->inp[backend_devices_idx] == NULL) return false; + + rar3_hook_extra->vm [backend_devices_idx] = hcmalloc (INPSIZE); + + if (rar3_hook_extra->vm [backend_devices_idx] == NULL) return false; + + rar3_hook_extra->ppm[backend_devices_idx] = hcmalloc (PPMSIZE); + + if (rar3_hook_extra->ppm[backend_devices_idx] == NULL) return false; + } + + return true; +} + +bool module_hook_extra_param_term (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra, MAYBE_UNUSED const folder_config_t *folder_config, MAYBE_UNUSED const backend_ctx_t *backend_ctx, void *hook_extra_param) +{ + rar3_hook_extra_t *rar3_hook_extra = (rar3_hook_extra_t *) hook_extra_param; + + for (int backend_devices_idx = 0; backend_devices_idx < backend_ctx->backend_devices_cnt; backend_devices_idx++) + { + hc_device_param_t *device_param = &backend_ctx->devices_param[backend_devices_idx]; + + if (device_param->skipped == true) continue; + + hcfree (rar3_hook_extra->ppm[backend_devices_idx]); + hcfree (rar3_hook_extra->win[backend_devices_idx]); + hcfree (rar3_hook_extra->inp[backend_devices_idx]); + hcfree (rar3_hook_extra->vm [backend_devices_idx]); + } + + hcfree (rar3_hook_extra->win); + hcfree (rar3_hook_extra->inp); + hcfree (rar3_hook_extra->vm); + + return true; +} + +unsigned int hc_decompress_rar (unsigned char *Win, unsigned char *Inp, unsigned char *VM, unsigned char *PPM, const unsigned int OutputSize, const unsigned char *Input, const unsigned int PackSize, const unsigned int UnpackSize, const unsigned char *Key, const unsigned char *IV); + +void module_hook23 (hc_device_param_t *device_param, const void *hook_extra_param, const void *hook_salts_buf, const u32 salt_pos, const u64 pw_pos) +{ + rar3_hook_t *hook_items = (rar3_hook_t *) device_param->hooks_buf; + rar3_hook_t *hook_item = &hook_items[pw_pos]; + + rar3_hook_salt_t *rar3s = (rar3_hook_salt_t *) hook_salts_buf; + rar3_hook_salt_t *rar3 = &rar3s[salt_pos]; + + rar3_hook_extra_t *rar3_hook_extra = (rar3_hook_extra_t *) hook_extra_param; + + const unsigned int pack_size = (const unsigned int) rar3->pack_size; + const unsigned int unpack_size = (const unsigned int) rar3->unpack_size; + + const u8 *first_block_decrypted = (const u8 *) hook_item->first_block_decrypted; + + /* Early rejection */ + if (first_block_decrypted[0] & 0x80) + { + // PPM checks here. + if (((first_block_decrypted[0] & 0x20) == 0) // Reset bit must be set + || (first_block_decrypted[1] & 0x80)) // MaxMB must be < 128 + { + return; + } + } + else + { + // LZ checks here. + if ((first_block_decrypted[0] & 0x40) // KeepOldTable can't be set + || (check_huffman (first_block_decrypted)) == 0) // Huffman table check + { + return; + } + } + + const u8 *data = (u8 *) rar3->data; + + const u8 *key = (u8 *) hook_item->key; + const u8 *iv = (u8 *) hook_item->iv; + + const u32 crc32 = hc_decompress_rar (rar3_hook_extra->win[device_param->device_id], rar3_hook_extra->inp[device_param->device_id], rar3_hook_extra->vm[device_param->device_id], rar3_hook_extra->ppm[device_param->device_id], unpack_size, data, pack_size, unpack_size, key, iv); + + hook_item->crc32 = crc32; +} + +u64 module_hook_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + const u64 hook_size = (const u64) sizeof (rar3_hook_t); + + return hook_size; +} + +u64 module_hook_salt_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + const u64 hook_salt_size = (const u64) sizeof (rar3_hook_salt_t); + + return hook_salt_size; +} + +u64 module_hook_extra_param_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + const u64 hook_extra_param_size = (const u64) sizeof (rar3_hook_extra_t); + + return hook_extra_param_size; +} + +u64 module_tmp_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + const bool optimized_kernel = user_options->optimized_kernel_enable; + + u64 tmp_size = (u64) sizeof (rar3_tmp_t); + + if (optimized_kernel == true) + { + tmp_size = (u64) sizeof (rar3_tmp_optimized_t); + } + + return tmp_size; +} + +u64 module_esalt_size (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + u64 esalt_size = (u64) sizeof (rar3_t); + + return esalt_size; +} + +u32 module_kernel_loops_min (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + const u32 kernel_loops_min = ROUNDS_RAR3 / 16; + + return kernel_loops_min; +} + +u32 module_kernel_loops_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + const u32 kernel_loops_max = ROUNDS_RAR3 / 16; + + return kernel_loops_max; +} + +u32 module_kernel_threads_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + // -T 128 works slightly faster but it's free for the user to change + + const u32 kernel_threads_max = (user_options->kernel_threads_chgd == true) ? user_options->kernel_threads : 128; + + return kernel_threads_max; +} + +u32 module_pw_max (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + const bool optimized_kernel = (hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL); + + u32 pw_max = 127; + + if (optimized_kernel == true) + { + pw_max = 20; + } + + return pw_max; +} + +const char *module_benchmark_mask (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const user_options_t *user_options, MAYBE_UNUSED const user_options_extra_t *user_options_extra) +{ + const char *mask = "?b?b?b?b?b"; + + return mask; +} + +int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED void *digest_buf, MAYBE_UNUSED salt_t *salt, MAYBE_UNUSED void *esalt_buf, MAYBE_UNUSED void *hook_salt_buf, MAYBE_UNUSED hashinfo_t *hash_info, const char *line_buf, MAYBE_UNUSED const int line_len) +{ + u32 *digest = (u32 *) digest_buf; + + rar3_t *rar3 = (rar3_t *) esalt_buf; + + rar3_hook_salt_t *rar3_hook_salt = (rar3_hook_salt_t *) hook_salt_buf; + + token_t token; + + token.token_cnt = 9; + + token.signatures_cnt = 1; + token.signatures_buf[0] = SIGNATURE_RAR3; + + token.sep[0] = '*'; + token.len_min[0] = 6; + token.len_max[0] = 6; + token.attr[0] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_SIGNATURE; + + token.sep[1] = '*'; + token.len_min[1] = 1; + token.len_max[1] = 1; + token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + token.sep[2] = '*'; + token.len_min[2] = 16; + token.len_max[2] = 16; + token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + token.sep[3] = '*'; + token.len_min[3] = 8; + token.len_max[3] = 8; + token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + token.sep[4] = '*'; + token.len_min[4] = 1; + token.len_max[4] = 7; + token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + token.sep[5] = '*'; + token.len_min[5] = 1; + token.len_max[5] = 6; + token.attr[5] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + token.sep[6] = '*'; + token.len_min[6] = 1; + token.len_max[6] = 1; + token.attr[6] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + token.sep[7] = '*'; + token.len_min[7] = 2; + token.len_max[7] = 655056; + token.attr[7] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + token.len[8] = 2; + token.attr[8] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); + + const u8 *type_pos = token.buf[1]; + + if (type_pos[0] != '1') return (PARSER_SIGNATURE_UNMATCHED); + + // salt + + const u8 *salt_pos = token.buf[2]; + + salt->salt_buf[0] = hex_to_u32 (salt_pos + 0); + salt->salt_buf[1] = hex_to_u32 (salt_pos + 8); + + salt->salt_len = 8; + salt->salt_iter = ROUNDS_RAR3; + + // CRC32 + + const u8 *crc32_pos = token.buf[3]; + + u32 crc32_sum = hex_to_u32 (crc32_pos); + + // pack size + + const u8 *pack_size_pos = token.buf[4]; + + const u32 pack_size = hc_strtoul ((const char *) pack_size_pos, NULL, 10); + + if (pack_size < 1) return (PARSER_SALT_VALUE); + if (pack_size > 327680) return (PARSER_SALT_VALUE); + + if ((pack_size % 16) != 0) return (PARSER_SALT_VALUE); + + rar3_hook_salt->pack_size = pack_size; + + // unpack size + + const u8 *unpack_size_pos = token.buf[5]; + + const u32 unpack_size = hc_strtoul ((const char *) unpack_size_pos, NULL, 10); + + if (unpack_size < 1) return (PARSER_SALT_VALUE); + if (unpack_size > 655360) return (PARSER_SALT_VALUE); + + rar3_hook_salt->unpack_size = unpack_size; + + // data is within the hash line + + const u8 *is_data_pos = token.buf[6]; + + if (is_data_pos[0] != '1') return (PARSER_SALT_VALUE); + + // data + + const u8 *data_pos = token.buf[7]; + const u32 data_len = token.len[7]; + + if (data_len != (pack_size * 2)) return (PARSER_SALT_VALUE); + + hex_decode (data_pos, data_len, (u8 *) rar3_hook_salt->data); + + rar3->first_block_encrypted[0] = rar3_hook_salt->data[0]; + rar3->first_block_encrypted[1] = rar3_hook_salt->data[1]; + rar3->first_block_encrypted[2] = rar3_hook_salt->data[2]; + rar3->first_block_encrypted[3] = rar3_hook_salt->data[3]; + + // method + + const u8 *method_pos = token.buf[8]; + + const u32 method = hc_strtoul ((const char *) method_pos, NULL, 10); + + if (method < 31) return (PARSER_SALT_VALUE); + if (method > 35) return (PARSER_SALT_VALUE); + + rar3_hook_salt->method = method; + + // digest + + digest[0] = crc32_sum; + digest[1] = 0; + digest[2] = 0; + digest[3] = 0; + + return (PARSER_OK); +} + +int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const void *digest_buf, MAYBE_UNUSED const salt_t *salt, MAYBE_UNUSED const void *esalt_buf, MAYBE_UNUSED const void *hook_salt_buf, MAYBE_UNUSED const hashinfo_t *hash_info, char *line_buf, MAYBE_UNUSED const int line_size) +{ + const u32 *digest = (const u32 *) digest_buf; + + rar3_hook_salt_t *rar3_hook_salt = (rar3_hook_salt_t *) hook_salt_buf; + + u8 data[655360] = { 0 }; + + const u32 data_len = rar3_hook_salt->pack_size; + + hex_encode ((const u8 *) rar3_hook_salt->data, data_len, data); + + const int line_len = snprintf (line_buf, line_size, "%s*1*%08x%08x*%08x*%u*%u*1*%s*%i", + SIGNATURE_RAR3, + byte_swap_32 (salt->salt_buf[0]), + byte_swap_32 (salt->salt_buf[1]), + byte_swap_32 (digest[0]), + rar3_hook_salt->pack_size, + rar3_hook_salt->unpack_size, + data, + rar3_hook_salt->method); + + return line_len; +} + +void module_init (module_ctx_t *module_ctx) +{ + module_ctx->module_context_size = MODULE_CONTEXT_SIZE_CURRENT; + module_ctx->module_interface_version = MODULE_INTERFACE_VERSION_CURRENT; + + module_ctx->module_attack_exec = module_attack_exec; + module_ctx->module_benchmark_esalt = MODULE_DEFAULT; + module_ctx->module_benchmark_hook_salt = MODULE_DEFAULT; + module_ctx->module_benchmark_mask = module_benchmark_mask; + module_ctx->module_benchmark_salt = MODULE_DEFAULT; + module_ctx->module_build_plain_postprocess = MODULE_DEFAULT; + module_ctx->module_deep_comp_kernel = MODULE_DEFAULT; + module_ctx->module_dgst_pos0 = module_dgst_pos0; + module_ctx->module_dgst_pos1 = module_dgst_pos1; + module_ctx->module_dgst_pos2 = module_dgst_pos2; + module_ctx->module_dgst_pos3 = module_dgst_pos3; + module_ctx->module_dgst_size = module_dgst_size; + module_ctx->module_dictstat_disable = MODULE_DEFAULT; + module_ctx->module_esalt_size = module_esalt_size; + module_ctx->module_extra_buffer_size = MODULE_DEFAULT; + module_ctx->module_extra_tmp_size = MODULE_DEFAULT; + module_ctx->module_forced_outfile_format = MODULE_DEFAULT; + module_ctx->module_hash_binary_count = MODULE_DEFAULT; + module_ctx->module_hash_binary_parse = MODULE_DEFAULT; + module_ctx->module_hash_binary_save = MODULE_DEFAULT; + module_ctx->module_hash_decode_potfile = MODULE_DEFAULT; + module_ctx->module_hash_decode_zero_hash = MODULE_DEFAULT; + module_ctx->module_hash_decode = module_hash_decode; + module_ctx->module_hash_encode_status = MODULE_DEFAULT; + module_ctx->module_hash_encode_potfile = MODULE_DEFAULT; + module_ctx->module_hash_encode = module_hash_encode; + module_ctx->module_hash_init_selftest = MODULE_DEFAULT; + module_ctx->module_hash_mode = MODULE_DEFAULT; + module_ctx->module_hash_category = module_hash_category; + module_ctx->module_hash_name = module_hash_name; + module_ctx->module_hashes_count_min = MODULE_DEFAULT; + module_ctx->module_hashes_count_max = MODULE_DEFAULT; + module_ctx->module_hlfmt_disable = MODULE_DEFAULT; + module_ctx->module_hook_extra_param_size = module_hook_extra_param_size; + module_ctx->module_hook_extra_param_init = module_hook_extra_param_init; + module_ctx->module_hook_extra_param_term = module_hook_extra_param_term; + module_ctx->module_hook12 = MODULE_DEFAULT; + module_ctx->module_hook23 = module_hook23; + module_ctx->module_hook_salt_size = module_hook_salt_size; + module_ctx->module_hook_size = module_hook_size; + module_ctx->module_jit_build_options = MODULE_DEFAULT; + module_ctx->module_jit_cache_disable = MODULE_DEFAULT; + module_ctx->module_kernel_accel_max = MODULE_DEFAULT; + module_ctx->module_kernel_accel_min = MODULE_DEFAULT; + module_ctx->module_kernel_loops_max = module_kernel_loops_max; + module_ctx->module_kernel_loops_min = module_kernel_loops_min; + module_ctx->module_kernel_threads_max = module_kernel_threads_max; + module_ctx->module_kernel_threads_min = MODULE_DEFAULT; + module_ctx->module_kern_type = module_kern_type; + module_ctx->module_kern_type_dynamic = MODULE_DEFAULT; + module_ctx->module_opti_type = module_opti_type; + module_ctx->module_opts_type = module_opts_type; + module_ctx->module_outfile_check_disable = MODULE_DEFAULT; + module_ctx->module_outfile_check_nocomp = MODULE_DEFAULT; + module_ctx->module_potfile_custom_check = MODULE_DEFAULT; + module_ctx->module_potfile_disable = MODULE_DEFAULT; + module_ctx->module_potfile_keep_all_hashes = MODULE_DEFAULT; + module_ctx->module_pwdump_column = MODULE_DEFAULT; + module_ctx->module_pw_max = module_pw_max; + module_ctx->module_pw_min = MODULE_DEFAULT; + module_ctx->module_salt_max = MODULE_DEFAULT; + module_ctx->module_salt_min = MODULE_DEFAULT; + module_ctx->module_salt_type = module_salt_type; + module_ctx->module_separator = MODULE_DEFAULT; + module_ctx->module_st_hash = module_st_hash; + module_ctx->module_st_pass = module_st_pass; + module_ctx->module_tmp_size = module_tmp_size; + module_ctx->module_unstable_warning = MODULE_DEFAULT; + module_ctx->module_warmup_disable = MODULE_DEFAULT; +} diff --git a/tools/test_modules/m23700.pm b/tools/test_modules/m23700.pm new file mode 100644 index 000000000..ee09c8b53 --- /dev/null +++ b/tools/test_modules/m23700.pm @@ -0,0 +1,496 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::SHA; +use Crypt::CBC; +use Encode; +use Digest::CRC qw (crc32); + +sub module_constraints { [[0, 127], [8, 8], [0, 20], [8, 8], [-1, -1]] } + +my $ITERATIONS = 0x40000; + +my $FIXED_RAW_STRING = pack ("H*", "c43d7b00400700000000000000000000"); + +my $SHA1C00 = 0x5a827999; +my $SHA1C01 = 0x6ed9eba1; +my $SHA1C02 = 0x8f1bbcdc; +my $SHA1C03 = 0xca62c1d6; + +my $SHA1M_A = 0x67452301; +my $SHA1M_B = 0xefcdab89; +my $SHA1M_C = 0x98badcfe; +my $SHA1M_D = 0x10325476; +my $SHA1M_E = 0xc3d2e1f0; + +sub rotl32 +{ + my $x = shift; + my $n = shift; + + return (($x << $n) | ($x >> (32 - $n))) & 0xffffffff; +} + +sub blk +{ + my $b = shift; + my $i = shift; + + $$b[$i & 15] = rotl32 ($$b[($i + 13) & 15] ^ + $$b[($i + 8) & 15] ^ + $$b[($i + 2) & 15] ^ + $$b[($i + 0) & 15], 1); + + return $$b[$i & 15]; +} + +sub R0 +{ + my ($b, $v, $w, $x, $y, $z, $i) = @_; + + $$b[$i] = unpack ("L<", pack ("L>", $$b[$i])); # blk0 or just swap_byte32 () + + $z += (($w & ($x ^ $y)) ^ $y) + $$b[$i] + $SHA1C00 + rotl32 ($v, 5); + + $z &= 0xffffffff; + + $w = rotl32 ($w, 30); + + return ($z, $w); +} + +sub R1 +{ + my ($b, $v, $w, $x, $y, $z, $i) = @_; + + $z += (($w & ($x ^ $y)) ^ $y) + blk ($b, $i) + $SHA1C00 + rotl32 ($v, 5); + + $z &= 0xffffffff; + + $w = rotl32 ($w, 30); + + return ($z, $w); +} + +sub R2 +{ + my ($b, $v, $w, $x, $y, $z, $i) = @_; + + $z += ($w ^ $x ^ $y) + blk ($b, $i) + $SHA1C01 + rotl32 ($v, 5); + + $z &= 0xffffffff; + + $w = rotl32 ($w, 30); + + return ($z, $w); +} + +sub R3 +{ + my ($b, $v, $w, $x, $y, $z, $i) = @_; + + $z += ((($w | $x) & $y) | ($w & $x)) + blk ($b, $i) + $SHA1C02 + rotl32 ($v, 5); + + $z &= 0xffffffff; + + $w = rotl32 ($w, 30); + + return ($z, $w); +} + +sub R4 +{ + my ($b, $v, $w, $x, $y, $z, $i) = @_; + + $z += ($w ^ $x ^ $y) + blk ($b, $i) + $SHA1C03 + rotl32 ($v, 5); + + $z &= 0xffffffff; + + $w = rotl32 ($w, 30); + + return ($z, $w); +} + +sub sha1_transform +{ + my ($state, $buffer) = @_; + + my @block = unpack ("L<*", $$buffer); + + my $a = $$state[0]; + my $b = $$state[1]; + my $c = $$state[2]; + my $d = $$state[3]; + my $e = $$state[4]; + + ($e, $b) = R0 (\@block, $a, $b, $c, $d, $e, 0); + ($d, $a) = R0 (\@block, $e, $a, $b, $c, $d, 1); + ($c, $e) = R0 (\@block, $d, $e, $a, $b, $c, 2); + ($b, $d) = R0 (\@block, $c, $d, $e, $a, $b, 3); + + ($a, $c) = R0 (\@block, $b, $c, $d, $e, $a, 4); + ($e, $b) = R0 (\@block, $a, $b, $c, $d, $e, 5); + ($d, $a) = R0 (\@block, $e, $a, $b, $c, $d, 6); + ($c, $e) = R0 (\@block, $d, $e, $a, $b, $c, 7); + + ($b, $d) = R0 (\@block, $c, $d, $e, $a, $b, 8); + ($a, $c) = R0 (\@block, $b, $c, $d, $e, $a, 9); + ($e, $b) = R0 (\@block, $a, $b, $c, $d, $e, 10); + ($d, $a) = R0 (\@block, $e, $a, $b, $c, $d, 11); + + ($c, $e) = R0 (\@block, $d, $e, $a, $b, $c, 12); + ($b, $d) = R0 (\@block, $c, $d, $e, $a, $b, 13); + ($a, $c) = R0 (\@block, $b, $c, $d, $e, $a, 14); + ($e, $b) = R0 (\@block, $a, $b, $c, $d, $e, 15); + + ($d, $a) = R1 (\@block, $e, $a, $b, $c, $d, 16); + ($c, $e) = R1 (\@block, $d, $e, $a, $b, $c, 17); + ($b, $d) = R1 (\@block, $c, $d, $e, $a, $b, 18); + ($a, $c) = R1 (\@block, $b, $c, $d, $e, $a, 19); + + ($e, $b) = R2 (\@block, $a, $b, $c, $d, $e, 20); + ($d, $a) = R2 (\@block, $e, $a, $b, $c, $d, 21); + ($c, $e) = R2 (\@block, $d, $e, $a, $b, $c, 22); + ($b, $d) = R2 (\@block, $c, $d, $e, $a, $b, 23); + + ($a, $c) = R2 (\@block, $b, $c, $d, $e, $a, 24); + ($e, $b) = R2 (\@block, $a, $b, $c, $d, $e, 25); + ($d, $a) = R2 (\@block, $e, $a, $b, $c, $d, 26); + ($c, $e) = R2 (\@block, $d, $e, $a, $b, $c, 27); + + ($b, $d) = R2 (\@block, $c, $d, $e, $a, $b, 28); + ($a, $c) = R2 (\@block, $b, $c, $d, $e, $a, 29); + ($e, $b) = R2 (\@block, $a, $b, $c, $d, $e, 30); + ($d, $a) = R2 (\@block, $e, $a, $b, $c, $d, 31); + + ($c, $e) = R2 (\@block, $d, $e, $a, $b, $c, 32); + ($b, $d) = R2 (\@block, $c, $d, $e, $a, $b, 33); + ($a, $c) = R2 (\@block, $b, $c, $d, $e, $a, 34); + ($e, $b) = R2 (\@block, $a, $b, $c, $d, $e, 35); + + ($d, $a) = R2 (\@block, $e, $a, $b, $c, $d, 36); + ($c, $e) = R2 (\@block, $d, $e, $a, $b, $c, 37); + ($b, $d) = R2 (\@block, $c, $d, $e, $a, $b, 38); + ($a, $c) = R2 (\@block, $b, $c, $d, $e, $a, 39); + + ($e, $b) = R3 (\@block, $a, $b, $c, $d, $e, 40); + ($d, $a) = R3 (\@block, $e, $a, $b, $c, $d, 41); + ($c, $e) = R3 (\@block, $d, $e, $a, $b, $c, 42); + ($b, $d) = R3 (\@block, $c, $d, $e, $a, $b, 43); + + ($a, $c) = R3 (\@block, $b, $c, $d, $e, $a, 44); + ($e, $b) = R3 (\@block, $a, $b, $c, $d, $e, 45); + ($d, $a) = R3 (\@block, $e, $a, $b, $c, $d, 46); + ($c, $e) = R3 (\@block, $d, $e, $a, $b, $c, 47); + + ($b, $d) = R3 (\@block, $c, $d, $e, $a, $b, 48); + ($a, $c) = R3 (\@block, $b, $c, $d, $e, $a, 49); + ($e, $b) = R3 (\@block, $a, $b, $c, $d, $e, 50); + ($d, $a) = R3 (\@block, $e, $a, $b, $c, $d, 51); + + ($c, $e) = R3 (\@block, $d, $e, $a, $b, $c, 52); + ($b, $d) = R3 (\@block, $c, $d, $e, $a, $b, 53); + ($a, $c) = R3 (\@block, $b, $c, $d, $e, $a, 54); + ($e, $b) = R3 (\@block, $a, $b, $c, $d, $e, 55); + + ($d, $a) = R3 (\@block, $e, $a, $b, $c, $d, 56); + ($c, $e) = R3 (\@block, $d, $e, $a, $b, $c, 57); + ($b, $d) = R3 (\@block, $c, $d, $e, $a, $b, 58); + ($a, $c) = R3 (\@block, $b, $c, $d, $e, $a, 59); + + ($e, $b) = R4 (\@block, $a, $b, $c, $d, $e, 60); + ($d, $a) = R4 (\@block, $e, $a, $b, $c, $d, 61); + ($c, $e) = R4 (\@block, $d, $e, $a, $b, $c, 62); + ($b, $d) = R4 (\@block, $c, $d, $e, $a, $b, 63); + + ($a, $c) = R4 (\@block, $b, $c, $d, $e, $a, 64); + ($e, $b) = R4 (\@block, $a, $b, $c, $d, $e, 65); + ($d, $a) = R4 (\@block, $e, $a, $b, $c, $d, 66); + ($c, $e) = R4 (\@block, $d, $e, $a, $b, $c, 67); + + ($b, $d) = R4 (\@block, $c, $d, $e, $a, $b, 68); + ($a, $c) = R4 (\@block, $b, $c, $d, $e, $a, 69); + ($e, $b) = R4 (\@block, $a, $b, $c, $d, $e, 70); + ($d, $a) = R4 (\@block, $e, $a, $b, $c, $d, 71); + + ($c, $e) = R4 (\@block, $d, $e, $a, $b, $c, 72); + ($b, $d) = R4 (\@block, $c, $d, $e, $a, $b, 73); + ($a, $c) = R4 (\@block, $b, $c, $d, $e, $a, 74); + ($e, $b) = R4 (\@block, $a, $b, $c, $d, $e, 75); + + ($d, $a) = R4 (\@block, $e, $a, $b, $c, $d, 76); + ($c, $e) = R4 (\@block, $d, $e, $a, $b, $c, 77); + ($b, $d) = R4 (\@block, $c, $d, $e, $a, $b, 78); + ($a, $c) = R4 (\@block, $b, $c, $d, $e, $a, 79); + + $$state[0] = ($$state[0] + $a) & 0xffffffff; + $$state[1] = ($$state[1] + $b) & 0xffffffff; + $$state[2] = ($$state[2] + $c) & 0xffffffff; + $$state[3] = ($$state[3] + $d) & 0xffffffff; + $$state[4] = ($$state[4] + $e) & 0xffffffff; + + $$buffer = pack ("L<*", @block); +} + +sub sha1_getstate +{ + my $ctx = shift; + + my $info = $ctx->getstate; + + # state: + + my $idx = index ($info, "H:"); + + my $state = substr ($info, $idx + 2, 44); + + $state =~ s/://g; + + my @state_arr = unpack ("L>*", pack ("H*", $state)); + + # block: + + $idx = index ($info, "block:"); + + my $block = substr ($info, $idx + 6, 191); + + $block =~ s/://g; + + $block = pack ("H*", $block); + + + return (\@state_arr, $block); +} + +sub sha1_update_rar29 +{ + my $ctx = shift; + my $data = shift; + my $len = shift; + my $count = shift; + + my $ctx_orig = $ctx->clone; + + $ctx->add ($$data); + + + # two early exits from this function, if (strange data) manipulation is not needed: + + my $j = $count & 63; + + return if (($j + $len) <= 63); + + + my $i = 64 - $j; + + return if (($i + 63) >= $len); + + + # proceed with updating $data: + + my ($state, $block) = sha1_getstate ($ctx_orig); + + + substr ($block, $j, $i) = substr ($$data, 0, $i); + + sha1_transform ($state, \$block); + + + while (($i + 63) < $len) + { + my $workspace = substr ($$data, $i, 64); + + sha1_transform ($state, \$workspace); + + substr ($$data, $i, 64) = $workspace; + + $i += 64; + } +} + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + my $crc32_sum = shift; + my $pack_size = shift; + my $unpack_size = shift; + my $data = shift; + + # convert to utf16le: + + my $buf = encode ("UTF-16LE", $word); + + # add the salt to the password buffer: + + $buf .= $salt; + + my $len = length ($buf); + + my $count = 0; + + my $ctx = Digest::SHA->new ('SHA1'); + + my $iv = ""; + + # main loop: + + for (my $i = 0; $i < $ITERATIONS; $i++) + { + sha1_update_rar29 ($ctx, \$buf, $len, $count); + + $count += $len; + + my $pos = substr (pack ("L<", $i), 0, 3); + + $ctx->add ($pos); + + $count += 3; + + if (($i & 0x3fff) == 0) + { + my $dgst = $ctx->clone->digest; + + $iv .= substr ($dgst, 19, 1); + } + } + + my $k = $ctx->digest; + + $k = pack ("L<*", unpack ("L>4", $k)); # byte swap the first 4 * 4 = 16 bytes + + # AES-128 encrypt: + + my $aes = Crypt::CBC->new ( + -cipher => "Crypt::Rijndael", + -key => $k, + -iv => $iv, + -keysize => 16, + -literal_key => 1, + -header => 'none', + -padding => 'null' + ); + + if (defined ($data)) + { + my $data_orig = $data; + + my $data_encrypted = substr ($data, 0, $pack_size); + my $data_decrypted = $aes->decrypt ($data_encrypted); + + # CRC32 checksum of the decrypted data: + + my $data_crc = substr ($data_decrypted, 0, $unpack_size); + + my $crc32_computed = crc32 ($data_crc); + + + $data = "WRONG"; + + # verify: + + if ($crc32_computed eq $crc32_sum) + { + $data = $data_crc; + } + } + else + { + my $data_len = random_number (1, 4096); + + $data = random_bytes ($data_len); + } + + my $crc32_computed = crc32 ($data); + + # byte-swap CRC32 checksum: + + $crc32_computed = unpack ("L<", pack ("L>", $crc32_computed)); + + my $data_encrypted = $aes->encrypt ($data); + + $pack_size = length ($data_encrypted); + $unpack_size = length ($data); + + return sprintf ("\$RAR3\$*1*%s*%08x*%i*%i*1*%s*30", unpack ("H*", $salt), $crc32_computed, $pack_size, $unpack_size, unpack ("H*", $data_encrypted)); +} + +sub module_verify_hash +{ + my $line = shift; + + my $idx1 = index ($line, ':'); + + return if ($idx1 < 1); + + my $hash = substr ($line, 0, $idx1); + my $word = substr ($line, $idx1 + 1); + + return if (substr ($hash, 0, 9) ne "\$RAR3\$*1*"); + + $idx1 = index ($hash, '*', 9); + + return if ($idx1 < 1); + + # salt + + my $salt = substr ($hash, 9, $idx1 - 9); + + # crc32 + + my $idx2 = index ($hash, '*', $idx1 + 1); + + return if ($idx2 < 1); + + my $crc32_sum = substr ($hash, $idx1 + 1, $idx2 - $idx1 - 1); + + # pack size + + $idx1 = index ($hash, '*', $idx2 + 1); + + return if ($idx1 < 1); + + my $pack_size = substr ($hash, $idx2 + 1, $idx1 - $idx2 - 1); + + # unpack size + + $idx2 = index ($hash, '*', $idx1 + 1); + + return if ($idx2 < 1); + + my $unpack_size = substr ($hash, $idx1 + 1, $idx2 - $idx1 - 1); + + return unless (substr ($hash, $idx2, 3) eq "*1*"); + + # data + + $idx1 = index ($hash, '*', $idx2 + 3); + + return if ($idx1 < 1); + + my $data = substr ($hash, $idx2 + 3, $idx1 - $idx2 - 3); + + return unless (substr ($hash, $idx1, 3) eq "*30"); + + # convert to hex: + + $salt = pack ("H*", $salt); + $data = pack ("H*", $data); + + $crc32_sum = unpack ("L<", pack ("H*", $crc32_sum)); + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt, $crc32_sum, $pack_size, $unpack_size, $data); + + return ($new_hash, $word); +} + +1;