From fae199458821fc4ba3f4ba70e2010729a322dcd6 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 26 Jun 2023 11:50:53 +0200 Subject: [PATCH 1/4] based m17040 of m17010 --- OpenCL/m17040-pure.cl | 504 +++++++++++++++++++++++++++++++++++++ src/modules/module_17040.c | 406 ++++++++++++++++++++++++++++++ 2 files changed, 910 insertions(+) create mode 100644 OpenCL/m17040-pure.cl create mode 100644 src/modules/module_17040.c diff --git a/OpenCL/m17040-pure.cl b/OpenCL/m17040-pure.cl new file mode 100644 index 000000000..406c35aa2 --- /dev/null +++ b/OpenCL/m17040-pure.cl @@ -0,0 +1,504 @@ +/** + * Author......: Netherlands Forensic Institute + * License.....: MIT + */ + +//#define NEW_SIMD_CODE + +#ifdef KERNEL_STATIC +#include M2S(INCLUDE_PATH/inc_vendor.h) +#include M2S(INCLUDE_PATH/inc_types.h) +#include M2S(INCLUDE_PATH/inc_platform.cl) +#include M2S(INCLUDE_PATH/inc_common.cl) +#include M2S(INCLUDE_PATH/inc_hash_sha1.cl) +#include M2S(INCLUDE_PATH/inc_cipher_aes.cl) +#endif + +typedef struct gpg +{ + u32 cipher_algo; + u32 iv[4]; + u32 modulus_size; + u32 encrypted_data[384]; + u32 encrypted_data_size; + +} gpg_t; + +typedef struct gpg_tmp +{ + // buffer for a maximum of 256 + 8 characters, we extend it to 320 characters so it's always 64 byte aligned + u32 salted_pw_block[80]; + // actual number of bytes in 'salted_pwd' that are used since salt and password are copied multiple times into the buffer + u32 salted_pw_block_len; + + u32 h[10]; + + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + u32 len; + +} gpg_tmp_t; + + +DECLSPEC u32 hc_bytealign_le_S (const u32 a, const u32 b, const int c) +{ + const int c_mod_4 = c & 3; + + #if ((defined IS_AMD || defined IS_HIP) && HAS_VPERM == 0) || defined IS_GENERIC + const u32 r = l32_from_64_S ((v64_from_v32ab_S (b, a) >> (c_mod_4 * 8))); + #endif + + #if ((defined IS_AMD || defined IS_HIP) && HAS_VPERM == 1) || defined IS_NV + + #if defined IS_NV + const int selector = (0x76543210 >> (c_mod_4 * 4)) & 0xffff; + #endif + + #if (defined IS_AMD || defined IS_HIP) + const int selector = l32_from_64_S (0x0706050403020100UL >> (c_mod_4 * 8)); + #endif + + const u32 r = hc_byte_perm (b, a, selector); + #endif + + return r; +} + +DECLSPEC void memcat_le_S (PRIVATE_AS u32 *block, const u32 offset, PRIVATE_AS const u32 *append, u32 len) +{ + const u32 start_index = (offset - 1) >> 2; + const u32 count = ((offset + len + 3) >> 2) - start_index; + const int off_mod_4 = offset & 3; + const int off_minus_4 = 4 - off_mod_4; + + block[start_index] |= hc_bytealign_le_S (append[0], 0, off_minus_4); + + for (u32 idx = 1; idx < count; idx++) + { + block[start_index + idx] = hc_bytealign_le_S (append[idx], append[idx - 1], off_minus_4); + } +} + +DECLSPEC void memzero_le_S (PRIVATE_AS u32 *block, const u32 start_offset, const u32 end_offset) +{ + const u32 start_idx = start_offset / 4; + + // zero out bytes in the first u32 starting from 'start_offset' + // math is a bit complex to avoid shifting by 32 bits, which is not possible on some architectures + block[start_idx] &= ~(0xffffffff << ((start_offset & 3) * 8)); + + const u32 end_idx = (end_offset + 3) / 4; + + // zero out bytes in u32 units -- note that the last u32 is completely zeroed! + for (u32 i = start_idx + 1; i < end_idx; i++) + { + block[i] = 0; + } +} + +DECLSPEC void memzero_be_S (PRIVATE_AS u32 *block, const u32 start_offset, const u32 end_offset) +{ + const u32 start_idx = start_offset / 4; + + // zero out bytes in the first u32 starting from 'start_offset' + // math is a bit complex to avoid shifting by 32 bits, which is not possible on some architectures + block[start_idx] &= ~(0xffffffff >> ((start_offset & 3) * 8)); + + const u32 end_idx = (end_offset + 3) / 4; + + // zero out bytes in u32 units -- note that the last u32 is completely zeroed! + for (u32 i = start_idx + 1; i < end_idx; i++) + { + block[i] = 0; + } +} + +DECLSPEC void aes128_decrypt_cfb (GLOBAL_AS const u32 *encrypted_data, int data_len, PRIVATE_AS const u32 *iv, PRIVATE_AS const u32 *key, PRIVATE_AS u32 *decrypted_data, + SHM_TYPE u32 *s_te0, SHM_TYPE u32 *s_te1, SHM_TYPE u32 *s_te2, SHM_TYPE u32 *s_te3, SHM_TYPE u32 *s_te4) +{ + u32 ks[44]; + u32 essiv[4]; + + // Copy the IV, since this will be modified + essiv[0] = iv[0]; + essiv[1] = iv[1]; + essiv[2] = iv[2]; + essiv[3] = iv[3]; + + aes128_set_encrypt_key (ks, key, s_te0, s_te1, s_te2, s_te3); + + // Decrypt an AES-128 encrypted block + for (u32 i = 0; i < (data_len + 3) / 4; i += 4) + { + aes128_encrypt (ks, essiv, decrypted_data + i, s_te0, s_te1, s_te2, s_te3, s_te4); + + decrypted_data[i + 0] ^= encrypted_data[i + 0]; + decrypted_data[i + 1] ^= encrypted_data[i + 1]; + decrypted_data[i + 2] ^= encrypted_data[i + 2]; + decrypted_data[i + 3] ^= encrypted_data[i + 3]; + + // Note: Not necessary if you are only decrypting a single block! + essiv[0] = encrypted_data[i + 0]; + essiv[1] = encrypted_data[i + 1]; + essiv[2] = encrypted_data[i + 2]; + essiv[3] = encrypted_data[i + 3]; + } +} + +DECLSPEC void aes256_decrypt_cfb (GLOBAL_AS const u32 *encrypted_data, int data_len, PRIVATE_AS const u32 *iv, PRIVATE_AS const u32 *key, PRIVATE_AS u32 *decrypted_data, + SHM_TYPE u32 *s_te0, SHM_TYPE u32 *s_te1, SHM_TYPE u32 *s_te2, SHM_TYPE u32 *s_te3, SHM_TYPE u32 *s_te4) +{ + u32 ks[60]; + u32 essiv[4]; + + // Copy the IV, since this will be modified + essiv[0] = iv[0]; + essiv[1] = iv[1]; + essiv[2] = iv[2]; + essiv[3] = iv[3]; + + aes256_set_encrypt_key (ks, key, s_te0, s_te1, s_te2, s_te3); + + // Decrypt an AES-256 encrypted block + for (u32 i = 0; i < (data_len + 3) / 4; i += 4) + { + aes256_encrypt (ks, essiv, decrypted_data + i, s_te0, s_te1, s_te2, s_te3, s_te4); + + decrypted_data[i + 0] ^= encrypted_data[i + 0]; + decrypted_data[i + 1] ^= encrypted_data[i + 1]; + decrypted_data[i + 2] ^= encrypted_data[i + 2]; + decrypted_data[i + 3] ^= encrypted_data[i + 3]; + + // Note: Not necessary if you are only decrypting a single block! + essiv[0] = encrypted_data[i + 0]; + essiv[1] = encrypted_data[i + 1]; + essiv[2] = encrypted_data[i + 2]; + essiv[3] = encrypted_data[i + 3]; + } +} + +DECLSPEC int check_decoded_data (PRIVATE_AS u32 *decoded_data, const u32 decoded_data_size) +{ + // Check the SHA-1 of the decrypted data which is stored at the end of the decrypted data + const u32 sha1_byte_off = (decoded_data_size - 20); + const u32 sha1_u32_off = sha1_byte_off / 4; + + u32 expected_sha1[5]; + + expected_sha1[0] = hc_bytealign_le_S (decoded_data[sha1_u32_off + 1], decoded_data[sha1_u32_off + 0], sha1_byte_off); + expected_sha1[1] = hc_bytealign_le_S (decoded_data[sha1_u32_off + 2], decoded_data[sha1_u32_off + 1], sha1_byte_off); + expected_sha1[2] = hc_bytealign_le_S (decoded_data[sha1_u32_off + 3], decoded_data[sha1_u32_off + 2], sha1_byte_off); + expected_sha1[3] = hc_bytealign_le_S (decoded_data[sha1_u32_off + 4], decoded_data[sha1_u32_off + 3], sha1_byte_off); + expected_sha1[4] = hc_bytealign_le_S (decoded_data[sha1_u32_off + 5], decoded_data[sha1_u32_off + 4], sha1_byte_off); + + memzero_le_S (decoded_data, sha1_byte_off, 384 * sizeof(u32)); + + sha1_ctx_t ctx; + + sha1_init (&ctx); + + sha1_update_swap (&ctx, decoded_data, sha1_byte_off); + + sha1_final (&ctx); + + return (expected_sha1[0] == hc_swap32_S (ctx.h[0])) + && (expected_sha1[1] == hc_swap32_S (ctx.h[1])) + && (expected_sha1[2] == hc_swap32_S (ctx.h[2])) + && (expected_sha1[3] == hc_swap32_S (ctx.h[3])) + && (expected_sha1[4] == hc_swap32_S (ctx.h[4])); +} + +KERNEL_FQ void m17010_init (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) +{ + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + const u32 pw_len = pws[gid].pw_len; + const u32 salted_pw_len = (salt_bufs[SALT_POS_HOST].salt_len + pw_len); + + u32 salted_pw_block[80]; + + // concatenate salt and password -- the salt is always 8 bytes + salted_pw_block[0] = salt_bufs[SALT_POS_HOST].salt_buf[0]; + salted_pw_block[1] = salt_bufs[SALT_POS_HOST].salt_buf[1]; + + for (u32 idx = 0; idx < 64; idx++) salted_pw_block[idx + 2] = pws[gid].i[idx]; + + // zero remainder of buffer + for (u32 idx = 66; idx < 80; idx++) salted_pw_block[idx] = 0; + + // create a number of copies for efficiency + const u32 copies = 80 * sizeof(u32) / salted_pw_len; + + for (u32 idx = 1; idx < copies; idx++) + { + memcat_le_S (salted_pw_block, idx * salted_pw_len, salted_pw_block, salted_pw_len); + } + + for (u32 idx = 0; idx < 80; idx++) + { + tmps[gid].salted_pw_block[idx] = hc_swap32_S (salted_pw_block[idx]); + } + + tmps[gid].salted_pw_block_len = (copies * salted_pw_len); + + tmps[gid].h[0] = SHA1M_A; + tmps[gid].h[1] = SHA1M_B; + tmps[gid].h[2] = SHA1M_C; + tmps[gid].h[3] = SHA1M_D; + tmps[gid].h[4] = SHA1M_E; + tmps[gid].h[5] = SHA1M_A; + tmps[gid].h[6] = SHA1M_B; + tmps[gid].h[7] = SHA1M_C; + tmps[gid].h[8] = SHA1M_D; + tmps[gid].h[9] = SHA1M_E; + + tmps[gid].len = 0; +} + +KERNEL_FQ void m17010_loop_prepare (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) +{ + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + tmps[gid].w0[0] = 0; + tmps[gid].w0[1] = 0; + tmps[gid].w0[2] = 0; + tmps[gid].w0[3] = 0; + tmps[gid].w1[0] = 0; + tmps[gid].w1[1] = 0; + tmps[gid].w1[2] = 0; + tmps[gid].w1[3] = 0; + tmps[gid].w2[0] = 0; + tmps[gid].w2[1] = 0; + tmps[gid].w2[2] = 0; + tmps[gid].w2[3] = 0; + tmps[gid].w3[0] = 0; + tmps[gid].w3[1] = 0; + tmps[gid].w3[2] = 0; + tmps[gid].w3[3] = 0; + + tmps[gid].len = SALT_REPEAT; +} + +KERNEL_FQ void m17010_loop (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) +{ + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + // get the prepared buffer from the gpg_tmp_t struct into a local buffer + u32 salted_pw_block[80]; + + for (int i = 0; i < 80; i++) salted_pw_block[i] = tmps[gid].salted_pw_block[i]; + + const u32 salted_pw_block_len = tmps[gid].salted_pw_block_len; + + // do we really need this, since the salt is always length 8? + if (salted_pw_block_len == 0) return; + + /** + * context load + */ + + sha1_ctx_t ctx; + + const u32 sha_offset = SALT_REPEAT * 5; + + for (int i = 0; i < 5; i++) ctx.h[i] = tmps[gid].h[sha_offset + i]; + + for (int i = 0; i < 4; i++) ctx.w0[i] = tmps[gid].w0[i]; + for (int i = 0; i < 4; i++) ctx.w1[i] = tmps[gid].w1[i]; + for (int i = 0; i < 4; i++) ctx.w2[i] = tmps[gid].w2[i]; + for (int i = 0; i < 4; i++) ctx.w3[i] = tmps[gid].w3[i]; + + ctx.len = tmps[gid].len; + + // sha-1 of salt and password, up to 'salt_iter' bytes + const u32 salt_iter = salt_bufs[SALT_POS_HOST].salt_iter; + + const u32 salted_pw_block_pos = LOOP_POS % salted_pw_block_len; + const u32 rounds = (LOOP_CNT + salted_pw_block_pos) / salted_pw_block_len; + + for (u32 i = 0; i < rounds; i++) + { + sha1_update (&ctx, salted_pw_block, salted_pw_block_len); + } + + if ((LOOP_POS + LOOP_CNT) == salt_iter) + { + const u32 remaining_bytes = salt_iter % salted_pw_block_len; + + if (remaining_bytes) + { + memzero_be_S (salted_pw_block, remaining_bytes, salted_pw_block_len); + + sha1_update (&ctx, salted_pw_block, remaining_bytes); + } + + sha1_final (&ctx); + } + + /** + * context save + */ + + for (int i = 0; i < 5; i++) tmps[gid].h[sha_offset + i] = ctx.h[i]; + + for (int i = 0; i < 4; i++) tmps[gid].w0[i] = ctx.w0[i]; + for (int i = 0; i < 4; i++) tmps[gid].w1[i] = ctx.w1[i]; + for (int i = 0; i < 4; i++) tmps[gid].w2[i] = ctx.w2[i]; + for (int i = 0; i < 4; i++) tmps[gid].w3[i] = ctx.w3[i]; + + tmps[gid].len = ctx.len; +} + +KERNEL_FQ void m17010_comp (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) +{ + // not in use here, special case... +} + +KERNEL_FQ void m17010_aux1 (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) +{ + /** + * modifier + */ + + const u64 lid = get_local_id (0); + const u64 gid = get_global_id (0); + const u64 lsz = get_local_size (0); + + /** + * aes shared + */ + + #ifdef REAL_SHM + + 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_te0[i] = te0[i]; + s_te1[i] = te1[i]; + s_te2[i] = te2[i]; + s_te3[i] = te3[i]; + s_te4[i] = te4[i]; + } + + SYNC_THREADS (); + + #else + + 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 + + if (gid >= GID_CNT) return; + + // retrieve and use the SHA-1 as the key for AES + + u32 aes_key[4]; + + for (int i = 0; i < 4; i++) aes_key[i] = hc_swap32_S (tmps[gid].h[i]); + + u32 iv[4] = {0}; + + for (int idx = 0; idx < 4; idx++) iv[idx] = esalt_bufs[DIGESTS_OFFSET_HOST].iv[idx]; + + u32 decoded_data[384]; + + const u32 enc_data_size = esalt_bufs[DIGESTS_OFFSET_HOST].encrypted_data_size; + + aes128_decrypt_cfb (esalt_bufs[DIGESTS_OFFSET_HOST].encrypted_data, enc_data_size, iv, aes_key, decoded_data, s_te0, s_te1, s_te2, s_te3, s_te4); + + if (check_decoded_data (decoded_data, enc_data_size)) + { + if (hc_atomic_inc (&hashes_shown[DIGESTS_OFFSET_HOST]) == 0) + { + mark_hash (plains_buf, d_return_buf, SALT_POS_HOST, DIGESTS_CNT, 0, DIGESTS_OFFSET_HOST + 0, gid, 0, 0, 0); + } + } +} + +KERNEL_FQ void m17010_aux2 (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) +{ + /** + * modifier + */ + + const u64 lid = get_local_id (0); + const u64 gid = get_global_id (0); + const u64 lsz = get_local_size (0); + + /** + * aes shared + */ + + #ifdef REAL_SHM + + 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_te0[i] = te0[i]; + s_te1[i] = te1[i]; + s_te2[i] = te2[i]; + s_te3[i] = te3[i]; + s_te4[i] = te4[i]; + } + + SYNC_THREADS (); + + #else + + 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 + + if (gid >= GID_CNT) return; + + // retrieve and use the SHA-1 as the key for AES + + u32 aes_key[8]; + + for (int i = 0; i < 8; i++) aes_key[i] = hc_swap32_S (tmps[gid].h[i]); + + u32 iv[4] = {0}; + + for (int idx = 0; idx < 4; idx++) iv[idx] = esalt_bufs[DIGESTS_OFFSET_HOST].iv[idx]; + + u32 decoded_data[384]; + + const u32 enc_data_size = esalt_bufs[DIGESTS_OFFSET_HOST].encrypted_data_size; + + aes256_decrypt_cfb (esalt_bufs[DIGESTS_OFFSET_HOST].encrypted_data, enc_data_size, iv, aes_key, decoded_data, s_te0, s_te1, s_te2, s_te3, s_te4); + + if (check_decoded_data (decoded_data, enc_data_size)) + { + if (hc_atomic_inc (&hashes_shown[DIGESTS_OFFSET_HOST]) == 0) + { + mark_hash (plains_buf, d_return_buf, SALT_POS_HOST, DIGESTS_CNT, 0, DIGESTS_OFFSET_HOST + 0, gid, 0, 0, 0); + } + } +} diff --git a/src/modules/module_17040.c b/src/modules/module_17040.c new file mode 100644 index 000000000..865a6f8eb --- /dev/null +++ b/src/modules/module_17040.c @@ -0,0 +1,406 @@ +/** + * Author......: Netherlands Forensic Institute + * 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; +static const u32 HASH_CATEGORY = HASH_CATEGORY_PRIVATE_KEY; +static const char *HASH_NAME = "GPG (AES-128/AES-256 (SHA-1($pass)))"; +static const u64 KERN_TYPE = 17010; +static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE; +static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE + | OPTS_TYPE_PT_GENERATE_LE + | OPTS_TYPE_LOOP_PREPARE + | OPTS_TYPE_AUX1 + | OPTS_TYPE_AUX2 + | OPTS_TYPE_DEEP_COMP_KERNEL; +static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; +static const char *ST_PASS = "hashcat"; +static const char *ST_HASH = "$gpg$*1*348*1024*8833fa3812b5500aa9eb7e46febfa31a0584b7e4a5b13c198f5c9b0814243895cce45ac3714e79692fb5a130a1c943b9130315ce303cb7e6831be68ce427892858f313fc29f533434dbe0ef26573f2071bbcc1499dc49bda90648221ef3823757e2fba6099a18c0c83386b21d8c9b522ec935ecd540210dbf0f21c859429fd4d35fa056415d8087f27b3e66b16081ea18c544d8b2ea414484f17097bc83b773d92743f76eb2ccb4df8ba5f5ff84a5474a5e8a8e5179a5b0908503c55e428de04b40628325739874e1b4aa004c4cbdf09b0b620990a8479f1c9b4187e33e63fe48a565bc1264bbf4062559631bef9e346a7217f1cabe101a38ac4be9fa94f6dafe6b0301e67792ed51bca04140cddd5cb6e80ac6e95e9a09378c9651588fe360954b622c258a3897f11246c944a588822cc6daf1cb81ccc95098c3bea8432f1ee0c663b193a7c7f1cdfeb91eee0195296bf4783025655cbebd7c70236*3*254*2*7*16*a47ef38987beab0a0b9bfe74b72822e8*65536*1f5c90d9820997db"; + +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 gpg +{ + u32 cipher_algo; + u32 iv[4]; + u32 modulus_size; + u32 encrypted_data[384]; + u32 encrypted_data_size; + +} gpg_t; + +typedef struct gpg_tmp +{ + u32 salted_pw_block[80]; + + u32 salted_pw_block_len; + + u32 h[10]; + + u32 w0[4]; + u32 w1[4]; + u32 w2[4]; + u32 w3[4]; + + u32 len; + +} gpg_tmp_t; + +static const char *SIGNATURE_GPG = "$gpg$"; + +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) +{ + const u64 esalt_size = (const u64) sizeof (gpg_t); + + return esalt_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 u64 tmp_size = (const u64) sizeof (gpg_tmp_t); + + return tmp_size; +} + +bool module_hlfmt_disable (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 hlfmt_disable = true; + + return hlfmt_disable; +} + +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 = 1024; + + 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 = 65536; + + return kernel_loops_max; +} + +u32 module_deep_comp_kernel (MAYBE_UNUSED const hashes_t *hashes, MAYBE_UNUSED const u32 salt_pos, MAYBE_UNUSED const u32 digest_pos) +{ + const u32 digests_offset = hashes->salts_buf[salt_pos].digests_offset; + + gpg_t *gpgs = (gpg_t *) hashes->esalts_buf; + + gpg_t *gpg = &gpgs[digests_offset + digest_pos]; + + if (gpg->cipher_algo == 7) + { + return KERN_RUN_AUX1; + } + else if (gpg->cipher_algo == 9) + { + return KERN_RUN_AUX2; + } + + return 0; +} + +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; + + gpg_t *gpg = (gpg_t *) esalt_buf; + + hc_token_t token; + + memset (&token, 0, sizeof (hc_token_t)); + + token.token_cnt = 13; + + // signature $gpg$ + token.signatures_cnt = 1; + token.signatures_buf[0] = SIGNATURE_GPG; + + // signature $gpg$ + token.sep[0] = '*'; + token.len[0] = 5; + token.attr[0] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_SIGNATURE; + + // "1" -- unknown option + token.sep[1] = '*'; + token.len[1] = 1; + token.attr[1] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + // size of the encrypted data in bytes + token.sep[2] = '*'; + token.len_min[2] = 3; + token.len_max[2] = 4; + token.attr[2] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + // size of the key: 1024, 2048, 4096, etc. + token.sep[3] = '*'; + token.len_min[3] = 3; + token.len_max[3] = 4; + token.attr[3] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + // encrypted key -- twice the amount of byte because its interpreted as characters + token.sep[4] = '*'; + token.len_min[4] = 256; + token.len_max[4] = 3072; + token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + // "3" - String2Key parameter + token.sep[5] = '*'; + token.len[5] = 1; + token.attr[5] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + // "254" - String2Key parameters + token.sep[6] = '*'; + token.len[6] = 3; + token.attr[6] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + // "2" - String2Key parameters + token.sep[7] = '*'; + token.len[7] = 1; + token.attr[7] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + // cipher mode: 7 or 9 + token.sep[8] = '*'; + token.len[8] = 1; + token.attr[8] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + // size of initial vector in bytes: 16 + token.sep[9] = '*'; + token.len[9] = 2; + token.attr[9] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + // initial vector - twice the amount of bytes because its interpreted as characters + token.sep[10] = '*'; + token.len[10] = 32; + token.attr[10] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + // iteration count + token.sep[11] = '*'; + token.len_min[11] = 1; + token.len_max[11] = 8; + token.attr[11] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + // salt - 8 bytes / 16 characters + token.len[12] = 16; + token.attr[12] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); + + // Modulus size + + const int modulus_size = hc_strtoul ((const char *) token.buf[3], NULL, 10); + + if ((modulus_size < 256) || (modulus_size > 16384)) return (PARSER_SALT_LENGTH); + + gpg->modulus_size = modulus_size; + + // Encrypted data + + const int enc_data_size = hc_strtoul ((const char *) token.buf[2], NULL, 10); + + const int encrypted_data_size = hex_decode ((const u8 *) token.buf[4], token.len[4], (u8 *) gpg->encrypted_data); + + if (enc_data_size != encrypted_data_size) return (PARSER_CT_LENGTH); + + gpg->encrypted_data_size = encrypted_data_size; + + // Check String2Key parameters + + if (hc_strtoul ((const char *) token.buf[5], NULL, 10) != 3) return (PARSER_HASH_VALUE); + if (hc_strtoul ((const char *) token.buf[6], NULL, 10) != 254) return (PARSER_HASH_VALUE); + if (hc_strtoul ((const char *) token.buf[7], NULL, 10) != 2) return (PARSER_HASH_VALUE); + + // Cipher algo + + const int cipher_algo = hc_strtoul ((const char *) token.buf[8], NULL, 10); + + if ((cipher_algo != 7) && (cipher_algo != 9)) return (PARSER_CIPHER); + + gpg->cipher_algo = cipher_algo; + + // IV (size) + + if (hc_strtoul ((const char *) token.buf[9], NULL, 10) != sizeof (gpg->iv)) return (PARSER_IV_LENGTH); + + const int iv_size = hex_decode ((const u8 *) token.buf[10], token.len[10], (u8 *) gpg->iv); + + if (iv_size != sizeof (gpg->iv)) return (PARSER_IV_LENGTH); + + // Salt Iter + + const u32 salt_iter = hc_strtoul ((const char *) token.buf[11], NULL, 10); + + if (salt_iter < 8 || salt_iter > 65011712) return (PARSER_SALT_ITERATION); + + salt->salt_iter = salt_iter; + + // Salt Value + + salt->salt_repeats = gpg->cipher_algo == 7 ? 0 : 1; // "minus one" + + salt->salt_len = hex_decode ((const u8 *) token.buf[12], token.len[12], (u8 *) salt->salt_buf); + + if (salt->salt_len != 8) return (PARSER_SALT_LENGTH); + + // hash fake + digest[0] = gpg->iv[0]; + digest[1] = gpg->iv[1]; + digest[2] = gpg->iv[2]; + digest[3] = gpg->iv[3]; + + 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 gpg_t *gpg = (const gpg_t *) esalt_buf; + + u8 encrypted_data[(384 * 8) + 1]; + + hex_encode ((const u8 *) gpg->encrypted_data, gpg->encrypted_data_size, (u8 *) encrypted_data); + + const int line_len = snprintf (line_buf, line_size, "%s*%d*%d*%d*%s*%d*%d*%d*%d*%d*%08x%08x%08x%08x*%d*%08x%08x", + SIGNATURE_GPG, + 1, /* unknown field */ + gpg->encrypted_data_size, + gpg->modulus_size, + encrypted_data, + 3, /* version (major?) */ + 254, /* version (minor?) */ + 2, /* key cipher (sha-1) */ + gpg->cipher_algo, + 16, /*iv_size*/ + byte_swap_32 (gpg->iv[0]), + byte_swap_32 (gpg->iv[1]), + byte_swap_32 (gpg->iv[2]), + byte_swap_32 (gpg->iv[3]), + salt->salt_iter, + byte_swap_32 (salt->salt_buf[0]), + byte_swap_32 (salt->salt_buf[1])); + + 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_DEFAULT; + module_ctx->module_benchmark_charset = MODULE_DEFAULT; + module_ctx->module_benchmark_salt = MODULE_DEFAULT; + module_ctx->module_build_plain_postprocess = MODULE_DEFAULT; + module_ctx->module_deep_comp_kernel = module_deep_comp_kernel; + module_ctx->module_deprecated_notice = 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_extra_tuningdb_block = 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_postprocess = 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_hlfmt_disable; + 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_DEFAULT; + 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_DEFAULT; + 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; +} From cb2890c10859de225f4b7f1e9f95c5cb122056cf Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 26 Jun 2023 13:34:27 +0200 Subject: [PATCH 2/4] working m17040 --- OpenCL/inc_cipher_cast.h | 730 +++++++++++++++++++++++++++++++++++++ OpenCL/inc_platform.h | 2 +- OpenCL/m17040-pure.cl | 262 ++++--------- docs/changes.txt | 1 + src/modules/module_17040.c | 101 +++-- 5 files changed, 864 insertions(+), 232 deletions(-) create mode 100644 OpenCL/inc_cipher_cast.h diff --git a/OpenCL/inc_cipher_cast.h b/OpenCL/inc_cipher_cast.h new file mode 100644 index 000000000..62bb2bb6a --- /dev/null +++ b/OpenCL/inc_cipher_cast.h @@ -0,0 +1,730 @@ +/* + * CAST OpenCL + * + * Copyright (c) 2018, magnum. + * This software is hereby released to the general public under + * the following terms: Redistribution and use in source and binary + * forms, with or without modification, are permitted. + * + * Based on version in Truecrypt 7.1a sources + * Based on cast.cpp - written and placed in the public domain by + * Wei Dai and Leonard Janke + * Based on Steve Reid's public domain cast.c + */ + +#ifndef _OPENCL_CAST_H +#define _OPENCL_CAST_H + +// #include "opencl_misc.h" +#define GET_UINT32BE(n, b, i) \ + { \ + (n) = ((uint) (b)[(i)] << 24) \ + | ((uint) (b)[(i) + 1] << 16) \ + | ((uint) (b)[(i) + 2] << 8) \ + | ((uint) (b)[(i) + 3] ); \ + } +#define PUT_UINT32BE(n, b, i) \ + { \ + (b)[(i) ] = (uchar) ((n) >> 24); \ + (b)[(i) + 1] = (uchar) ((n) >> 16); \ + (b)[(i) + 2] = (uchar) ((n) >> 8); \ + (b)[(i) + 3] = (uchar) ((n) ); \ + } + +typedef struct { + uint K[32]; +} CAST_KEY; + +#define GETBYTE(x, y) (uint)(uchar)((x)>>(8*(y))) + +/* Macros to access 8-bit bytes out of a 32-bit word */ +#define U8a(x) GETBYTE(x,3) +#define U8b(x) GETBYTE(x,2) +#define U8c(x) GETBYTE(x,1) +#define U8d(x) GETBYTE(x,0) + +/* CAST S-boxes */ +CONSTANT_AS uint S[8][256] = { + { + 0x30FB40D4UL, 0x9FA0FF0BUL, 0x6BECCD2FUL, 0x3F258C7AUL, + 0x1E213F2FUL, 0x9C004DD3UL, 0x6003E540UL, 0xCF9FC949UL, + 0xBFD4AF27UL, 0x88BBBDB5UL, 0xE2034090UL, 0x98D09675UL, + 0x6E63A0E0UL, 0x15C361D2UL, 0xC2E7661DUL, 0x22D4FF8EUL, + 0x28683B6FUL, 0xC07FD059UL, 0xFF2379C8UL, 0x775F50E2UL, + 0x43C340D3UL, 0xDF2F8656UL, 0x887CA41AUL, 0xA2D2BD2DUL, + 0xA1C9E0D6UL, 0x346C4819UL, 0x61B76D87UL, 0x22540F2FUL, + 0x2ABE32E1UL, 0xAA54166BUL, 0x22568E3AUL, 0xA2D341D0UL, + 0x66DB40C8UL, 0xA784392FUL, 0x004DFF2FUL, 0x2DB9D2DEUL, + 0x97943FACUL, 0x4A97C1D8UL, 0x527644B7UL, 0xB5F437A7UL, + 0xB82CBAEFUL, 0xD751D159UL, 0x6FF7F0EDUL, 0x5A097A1FUL, + 0x827B68D0UL, 0x90ECF52EUL, 0x22B0C054UL, 0xBC8E5935UL, + 0x4B6D2F7FUL, 0x50BB64A2UL, 0xD2664910UL, 0xBEE5812DUL, + 0xB7332290UL, 0xE93B159FUL, 0xB48EE411UL, 0x4BFF345DUL, + 0xFD45C240UL, 0xAD31973FUL, 0xC4F6D02EUL, 0x55FC8165UL, + 0xD5B1CAADUL, 0xA1AC2DAEUL, 0xA2D4B76DUL, 0xC19B0C50UL, + 0x882240F2UL, 0x0C6E4F38UL, 0xA4E4BFD7UL, 0x4F5BA272UL, + 0x564C1D2FUL, 0xC59C5319UL, 0xB949E354UL, 0xB04669FEUL, + 0xB1B6AB8AUL, 0xC71358DDUL, 0x6385C545UL, 0x110F935DUL, + 0x57538AD5UL, 0x6A390493UL, 0xE63D37E0UL, 0x2A54F6B3UL, + 0x3A787D5FUL, 0x6276A0B5UL, 0x19A6FCDFUL, 0x7A42206AUL, + 0x29F9D4D5UL, 0xF61B1891UL, 0xBB72275EUL, 0xAA508167UL, + 0x38901091UL, 0xC6B505EBUL, 0x84C7CB8CUL, 0x2AD75A0FUL, + 0x874A1427UL, 0xA2D1936BUL, 0x2AD286AFUL, 0xAA56D291UL, + 0xD7894360UL, 0x425C750DUL, 0x93B39E26UL, 0x187184C9UL, + 0x6C00B32DUL, 0x73E2BB14UL, 0xA0BEBC3CUL, 0x54623779UL, + 0x64459EABUL, 0x3F328B82UL, 0x7718CF82UL, 0x59A2CEA6UL, + 0x04EE002EUL, 0x89FE78E6UL, 0x3FAB0950UL, 0x325FF6C2UL, + 0x81383F05UL, 0x6963C5C8UL, 0x76CB5AD6UL, 0xD49974C9UL, + 0xCA180DCFUL, 0x380782D5UL, 0xC7FA5CF6UL, 0x8AC31511UL, + 0x35E79E13UL, 0x47DA91D0UL, 0xF40F9086UL, 0xA7E2419EUL, + 0x31366241UL, 0x051EF495UL, 0xAA573B04UL, 0x4A805D8DUL, + 0x548300D0UL, 0x00322A3CUL, 0xBF64CDDFUL, 0xBA57A68EUL, + 0x75C6372BUL, 0x50AFD341UL, 0xA7C13275UL, 0x915A0BF5UL, + 0x6B54BFABUL, 0x2B0B1426UL, 0xAB4CC9D7UL, 0x449CCD82UL, + 0xF7FBF265UL, 0xAB85C5F3UL, 0x1B55DB94UL, 0xAAD4E324UL, + 0xCFA4BD3FUL, 0x2DEAA3E2UL, 0x9E204D02UL, 0xC8BD25ACUL, + 0xEADF55B3UL, 0xD5BD9E98UL, 0xE31231B2UL, 0x2AD5AD6CUL, + 0x954329DEUL, 0xADBE4528UL, 0xD8710F69UL, 0xAA51C90FUL, + 0xAA786BF6UL, 0x22513F1EUL, 0xAA51A79BUL, 0x2AD344CCUL, + 0x7B5A41F0UL, 0xD37CFBADUL, 0x1B069505UL, 0x41ECE491UL, + 0xB4C332E6UL, 0x032268D4UL, 0xC9600ACCUL, 0xCE387E6DUL, + 0xBF6BB16CUL, 0x6A70FB78UL, 0x0D03D9C9UL, 0xD4DF39DEUL, + 0xE01063DAUL, 0x4736F464UL, 0x5AD328D8UL, 0xB347CC96UL, + 0x75BB0FC3UL, 0x98511BFBUL, 0x4FFBCC35UL, 0xB58BCF6AUL, + 0xE11F0ABCUL, 0xBFC5FE4AUL, 0xA70AEC10UL, 0xAC39570AUL, + 0x3F04442FUL, 0x6188B153UL, 0xE0397A2EUL, 0x5727CB79UL, + 0x9CEB418FUL, 0x1CACD68DUL, 0x2AD37C96UL, 0x0175CB9DUL, + 0xC69DFF09UL, 0xC75B65F0UL, 0xD9DB40D8UL, 0xEC0E7779UL, + 0x4744EAD4UL, 0xB11C3274UL, 0xDD24CB9EUL, 0x7E1C54BDUL, + 0xF01144F9UL, 0xD2240EB1UL, 0x9675B3FDUL, 0xA3AC3755UL, + 0xD47C27AFUL, 0x51C85F4DUL, 0x56907596UL, 0xA5BB15E6UL, + 0x580304F0UL, 0xCA042CF1UL, 0x011A37EAUL, 0x8DBFAADBUL, + 0x35BA3E4AUL, 0x3526FFA0UL, 0xC37B4D09UL, 0xBC306ED9UL, + 0x98A52666UL, 0x5648F725UL, 0xFF5E569DUL, 0x0CED63D0UL, + 0x7C63B2CFUL, 0x700B45E1UL, 0xD5EA50F1UL, 0x85A92872UL, + 0xAF1FBDA7UL, 0xD4234870UL, 0xA7870BF3UL, 0x2D3B4D79UL, + 0x42E04198UL, 0x0CD0EDE7UL, 0x26470DB8UL, 0xF881814CUL, + 0x474D6AD7UL, 0x7C0C5E5CUL, 0xD1231959UL, 0x381B7298UL, + 0xF5D2F4DBUL, 0xAB838653UL, 0x6E2F1E23UL, 0x83719C9EUL, + 0xBD91E046UL, 0x9A56456EUL, 0xDC39200CUL, 0x20C8C571UL, + 0x962BDA1CUL, 0xE1E696FFUL, 0xB141AB08UL, 0x7CCA89B9UL, + 0x1A69E783UL, 0x02CC4843UL, 0xA2F7C579UL, 0x429EF47DUL, + 0x427B169CUL, 0x5AC9F049UL, 0xDD8F0F00UL, 0x5C8165BFUL + }, + + { + 0x1F201094UL, 0xEF0BA75BUL, 0x69E3CF7EUL, 0x393F4380UL, + 0xFE61CF7AUL, 0xEEC5207AUL, 0x55889C94UL, 0x72FC0651UL, + 0xADA7EF79UL, 0x4E1D7235UL, 0xD55A63CEUL, 0xDE0436BAUL, + 0x99C430EFUL, 0x5F0C0794UL, 0x18DCDB7DUL, 0xA1D6EFF3UL, + 0xA0B52F7BUL, 0x59E83605UL, 0xEE15B094UL, 0xE9FFD909UL, + 0xDC440086UL, 0xEF944459UL, 0xBA83CCB3UL, 0xE0C3CDFBUL, + 0xD1DA4181UL, 0x3B092AB1UL, 0xF997F1C1UL, 0xA5E6CF7BUL, + 0x01420DDBUL, 0xE4E7EF5BUL, 0x25A1FF41UL, 0xE180F806UL, + 0x1FC41080UL, 0x179BEE7AUL, 0xD37AC6A9UL, 0xFE5830A4UL, + 0x98DE8B7FUL, 0x77E83F4EUL, 0x79929269UL, 0x24FA9F7BUL, + 0xE113C85BUL, 0xACC40083UL, 0xD7503525UL, 0xF7EA615FUL, + 0x62143154UL, 0x0D554B63UL, 0x5D681121UL, 0xC866C359UL, + 0x3D63CF73UL, 0xCEE234C0UL, 0xD4D87E87UL, 0x5C672B21UL, + 0x071F6181UL, 0x39F7627FUL, 0x361E3084UL, 0xE4EB573BUL, + 0x602F64A4UL, 0xD63ACD9CUL, 0x1BBC4635UL, 0x9E81032DUL, + 0x2701F50CUL, 0x99847AB4UL, 0xA0E3DF79UL, 0xBA6CF38CUL, + 0x10843094UL, 0x2537A95EUL, 0xF46F6FFEUL, 0xA1FF3B1FUL, + 0x208CFB6AUL, 0x8F458C74UL, 0xD9E0A227UL, 0x4EC73A34UL, + 0xFC884F69UL, 0x3E4DE8DFUL, 0xEF0E0088UL, 0x3559648DUL, + 0x8A45388CUL, 0x1D804366UL, 0x721D9BFDUL, 0xA58684BBUL, + 0xE8256333UL, 0x844E8212UL, 0x128D8098UL, 0xFED33FB4UL, + 0xCE280AE1UL, 0x27E19BA5UL, 0xD5A6C252UL, 0xE49754BDUL, + 0xC5D655DDUL, 0xEB667064UL, 0x77840B4DUL, 0xA1B6A801UL, + 0x84DB26A9UL, 0xE0B56714UL, 0x21F043B7UL, 0xE5D05860UL, + 0x54F03084UL, 0x066FF472UL, 0xA31AA153UL, 0xDADC4755UL, + 0xB5625DBFUL, 0x68561BE6UL, 0x83CA6B94UL, 0x2D6ED23BUL, + 0xECCF01DBUL, 0xA6D3D0BAUL, 0xB6803D5CUL, 0xAF77A709UL, + 0x33B4A34CUL, 0x397BC8D6UL, 0x5EE22B95UL, 0x5F0E5304UL, + 0x81ED6F61UL, 0x20E74364UL, 0xB45E1378UL, 0xDE18639BUL, + 0x881CA122UL, 0xB96726D1UL, 0x8049A7E8UL, 0x22B7DA7BUL, + 0x5E552D25UL, 0x5272D237UL, 0x79D2951CUL, 0xC60D894CUL, + 0x488CB402UL, 0x1BA4FE5BUL, 0xA4B09F6BUL, 0x1CA815CFUL, + 0xA20C3005UL, 0x8871DF63UL, 0xB9DE2FCBUL, 0x0CC6C9E9UL, + 0x0BEEFF53UL, 0xE3214517UL, 0xB4542835UL, 0x9F63293CUL, + 0xEE41E729UL, 0x6E1D2D7CUL, 0x50045286UL, 0x1E6685F3UL, + 0xF33401C6UL, 0x30A22C95UL, 0x31A70850UL, 0x60930F13UL, + 0x73F98417UL, 0xA1269859UL, 0xEC645C44UL, 0x52C877A9UL, + 0xCDFF33A6UL, 0xA02B1741UL, 0x7CBAD9A2UL, 0x2180036FUL, + 0x50D99C08UL, 0xCB3F4861UL, 0xC26BD765UL, 0x64A3F6ABUL, + 0x80342676UL, 0x25A75E7BUL, 0xE4E6D1FCUL, 0x20C710E6UL, + 0xCDF0B680UL, 0x17844D3BUL, 0x31EEF84DUL, 0x7E0824E4UL, + 0x2CCB49EBUL, 0x846A3BAEUL, 0x8FF77888UL, 0xEE5D60F6UL, + 0x7AF75673UL, 0x2FDD5CDBUL, 0xA11631C1UL, 0x30F66F43UL, + 0xB3FAEC54UL, 0x157FD7FAUL, 0xEF8579CCUL, 0xD152DE58UL, + 0xDB2FFD5EUL, 0x8F32CE19UL, 0x306AF97AUL, 0x02F03EF8UL, + 0x99319AD5UL, 0xC242FA0FUL, 0xA7E3EBB0UL, 0xC68E4906UL, + 0xB8DA230CUL, 0x80823028UL, 0xDCDEF3C8UL, 0xD35FB171UL, + 0x088A1BC8UL, 0xBEC0C560UL, 0x61A3C9E8UL, 0xBCA8F54DUL, + 0xC72FEFFAUL, 0x22822E99UL, 0x82C570B4UL, 0xD8D94E89UL, + 0x8B1C34BCUL, 0x301E16E6UL, 0x273BE979UL, 0xB0FFEAA6UL, + 0x61D9B8C6UL, 0x00B24869UL, 0xB7FFCE3FUL, 0x08DC283BUL, + 0x43DAF65AUL, 0xF7E19798UL, 0x7619B72FUL, 0x8F1C9BA4UL, + 0xDC8637A0UL, 0x16A7D3B1UL, 0x9FC393B7UL, 0xA7136EEBUL, + 0xC6BCC63EUL, 0x1A513742UL, 0xEF6828BCUL, 0x520365D6UL, + 0x2D6A77ABUL, 0x3527ED4BUL, 0x821FD216UL, 0x095C6E2EUL, + 0xDB92F2FBUL, 0x5EEA29CBUL, 0x145892F5UL, 0x91584F7FUL, + 0x5483697BUL, 0x2667A8CCUL, 0x85196048UL, 0x8C4BACEAUL, + 0x833860D4UL, 0x0D23E0F9UL, 0x6C387E8AUL, 0x0AE6D249UL, + 0xB284600CUL, 0xD835731DUL, 0xDCB1C647UL, 0xAC4C56EAUL, + 0x3EBD81B3UL, 0x230EABB0UL, 0x6438BC87UL, 0xF0B5B1FAUL, + 0x8F5EA2B3UL, 0xFC184642UL, 0x0A036B7AUL, 0x4FB089BDUL, + 0x649DA589UL, 0xA345415EUL, 0x5C038323UL, 0x3E5D3BB9UL, + 0x43D79572UL, 0x7E6DD07CUL, 0x06DFDF1EUL, 0x6C6CC4EFUL, + 0x7160A539UL, 0x73BFBE70UL, 0x83877605UL, 0x4523ECF1UL + }, + + { + 0x8DEFC240UL, 0x25FA5D9FUL, 0xEB903DBFUL, 0xE810C907UL, + 0x47607FFFUL, 0x369FE44BUL, 0x8C1FC644UL, 0xAECECA90UL, + 0xBEB1F9BFUL, 0xEEFBCAEAUL, 0xE8CF1950UL, 0x51DF07AEUL, + 0x920E8806UL, 0xF0AD0548UL, 0xE13C8D83UL, 0x927010D5UL, + 0x11107D9FUL, 0x07647DB9UL, 0xB2E3E4D4UL, 0x3D4F285EUL, + 0xB9AFA820UL, 0xFADE82E0UL, 0xA067268BUL, 0x8272792EUL, + 0x553FB2C0UL, 0x489AE22BUL, 0xD4EF9794UL, 0x125E3FBCUL, + 0x21FFFCEEUL, 0x825B1BFDUL, 0x9255C5EDUL, 0x1257A240UL, + 0x4E1A8302UL, 0xBAE07FFFUL, 0x528246E7UL, 0x8E57140EUL, + 0x3373F7BFUL, 0x8C9F8188UL, 0xA6FC4EE8UL, 0xC982B5A5UL, + 0xA8C01DB7UL, 0x579FC264UL, 0x67094F31UL, 0xF2BD3F5FUL, + 0x40FFF7C1UL, 0x1FB78DFCUL, 0x8E6BD2C1UL, 0x437BE59BUL, + 0x99B03DBFUL, 0xB5DBC64BUL, 0x638DC0E6UL, 0x55819D99UL, + 0xA197C81CUL, 0x4A012D6EUL, 0xC5884A28UL, 0xCCC36F71UL, + 0xB843C213UL, 0x6C0743F1UL, 0x8309893CUL, 0x0FEDDD5FUL, + 0x2F7FE850UL, 0xD7C07F7EUL, 0x02507FBFUL, 0x5AFB9A04UL, + 0xA747D2D0UL, 0x1651192EUL, 0xAF70BF3EUL, 0x58C31380UL, + 0x5F98302EUL, 0x727CC3C4UL, 0x0A0FB402UL, 0x0F7FEF82UL, + 0x8C96FDADUL, 0x5D2C2AAEUL, 0x8EE99A49UL, 0x50DA88B8UL, + 0x8427F4A0UL, 0x1EAC5790UL, 0x796FB449UL, 0x8252DC15UL, + 0xEFBD7D9BUL, 0xA672597DUL, 0xADA840D8UL, 0x45F54504UL, + 0xFA5D7403UL, 0xE83EC305UL, 0x4F91751AUL, 0x925669C2UL, + 0x23EFE941UL, 0xA903F12EUL, 0x60270DF2UL, 0x0276E4B6UL, + 0x94FD6574UL, 0x927985B2UL, 0x8276DBCBUL, 0x02778176UL, + 0xF8AF918DUL, 0x4E48F79EUL, 0x8F616DDFUL, 0xE29D840EUL, + 0x842F7D83UL, 0x340CE5C8UL, 0x96BBB682UL, 0x93B4B148UL, + 0xEF303CABUL, 0x984FAF28UL, 0x779FAF9BUL, 0x92DC560DUL, + 0x224D1E20UL, 0x8437AA88UL, 0x7D29DC96UL, 0x2756D3DCUL, + 0x8B907CEEUL, 0xB51FD240UL, 0xE7C07CE3UL, 0xE566B4A1UL, + 0xC3E9615EUL, 0x3CF8209DUL, 0x6094D1E3UL, 0xCD9CA341UL, + 0x5C76460EUL, 0x00EA983BUL, 0xD4D67881UL, 0xFD47572CUL, + 0xF76CEDD9UL, 0xBDA8229CUL, 0x127DADAAUL, 0x438A074EUL, + 0x1F97C090UL, 0x081BDB8AUL, 0x93A07EBEUL, 0xB938CA15UL, + 0x97B03CFFUL, 0x3DC2C0F8UL, 0x8D1AB2ECUL, 0x64380E51UL, + 0x68CC7BFBUL, 0xD90F2788UL, 0x12490181UL, 0x5DE5FFD4UL, + 0xDD7EF86AUL, 0x76A2E214UL, 0xB9A40368UL, 0x925D958FUL, + 0x4B39FFFAUL, 0xBA39AEE9UL, 0xA4FFD30BUL, 0xFAF7933BUL, + 0x6D498623UL, 0x193CBCFAUL, 0x27627545UL, 0x825CF47AUL, + 0x61BD8BA0UL, 0xD11E42D1UL, 0xCEAD04F4UL, 0x127EA392UL, + 0x10428DB7UL, 0x8272A972UL, 0x9270C4A8UL, 0x127DE50BUL, + 0x285BA1C8UL, 0x3C62F44FUL, 0x35C0EAA5UL, 0xE805D231UL, + 0x428929FBUL, 0xB4FCDF82UL, 0x4FB66A53UL, 0x0E7DC15BUL, + 0x1F081FABUL, 0x108618AEUL, 0xFCFD086DUL, 0xF9FF2889UL, + 0x694BCC11UL, 0x236A5CAEUL, 0x12DECA4DUL, 0x2C3F8CC5UL, + 0xD2D02DFEUL, 0xF8EF5896UL, 0xE4CF52DAUL, 0x95155B67UL, + 0x494A488CUL, 0xB9B6A80CUL, 0x5C8F82BCUL, 0x89D36B45UL, + 0x3A609437UL, 0xEC00C9A9UL, 0x44715253UL, 0x0A874B49UL, + 0xD773BC40UL, 0x7C34671CUL, 0x02717EF6UL, 0x4FEB5536UL, + 0xA2D02FFFUL, 0xD2BF60C4UL, 0xD43F03C0UL, 0x50B4EF6DUL, + 0x07478CD1UL, 0x006E1888UL, 0xA2E53F55UL, 0xB9E6D4BCUL, + 0xA2048016UL, 0x97573833UL, 0xD7207D67UL, 0xDE0F8F3DUL, + 0x72F87B33UL, 0xABCC4F33UL, 0x7688C55DUL, 0x7B00A6B0UL, + 0x947B0001UL, 0x570075D2UL, 0xF9BB88F8UL, 0x8942019EUL, + 0x4264A5FFUL, 0x856302E0UL, 0x72DBD92BUL, 0xEE971B69UL, + 0x6EA22FDEUL, 0x5F08AE2BUL, 0xAF7A616DUL, 0xE5C98767UL, + 0xCF1FEBD2UL, 0x61EFC8C2UL, 0xF1AC2571UL, 0xCC8239C2UL, + 0x67214CB8UL, 0xB1E583D1UL, 0xB7DC3E62UL, 0x7F10BDCEUL, + 0xF90A5C38UL, 0x0FF0443DUL, 0x606E6DC6UL, 0x60543A49UL, + 0x5727C148UL, 0x2BE98A1DUL, 0x8AB41738UL, 0x20E1BE24UL, + 0xAF96DA0FUL, 0x68458425UL, 0x99833BE5UL, 0x600D457DUL, + 0x282F9350UL, 0x8334B362UL, 0xD91D1120UL, 0x2B6D8DA0UL, + 0x642B1E31UL, 0x9C305A00UL, 0x52BCE688UL, 0x1B03588AUL, + 0xF7BAEFD5UL, 0x4142ED9CUL, 0xA4315C11UL, 0x83323EC5UL, + 0xDFEF4636UL, 0xA133C501UL, 0xE9D3531CUL, 0xEE353783UL + }, + + { + 0x9DB30420UL, 0x1FB6E9DEUL, 0xA7BE7BEFUL, 0xD273A298UL, + 0x4A4F7BDBUL, 0x64AD8C57UL, 0x85510443UL, 0xFA020ED1UL, + 0x7E287AFFUL, 0xE60FB663UL, 0x095F35A1UL, 0x79EBF120UL, + 0xFD059D43UL, 0x6497B7B1UL, 0xF3641F63UL, 0x241E4ADFUL, + 0x28147F5FUL, 0x4FA2B8CDUL, 0xC9430040UL, 0x0CC32220UL, + 0xFDD30B30UL, 0xC0A5374FUL, 0x1D2D00D9UL, 0x24147B15UL, + 0xEE4D111AUL, 0x0FCA5167UL, 0x71FF904CUL, 0x2D195FFEUL, + 0x1A05645FUL, 0x0C13FEFEUL, 0x081B08CAUL, 0x05170121UL, + 0x80530100UL, 0xE83E5EFEUL, 0xAC9AF4F8UL, 0x7FE72701UL, + 0xD2B8EE5FUL, 0x06DF4261UL, 0xBB9E9B8AUL, 0x7293EA25UL, + 0xCE84FFDFUL, 0xF5718801UL, 0x3DD64B04UL, 0xA26F263BUL, + 0x7ED48400UL, 0x547EEBE6UL, 0x446D4CA0UL, 0x6CF3D6F5UL, + 0x2649ABDFUL, 0xAEA0C7F5UL, 0x36338CC1UL, 0x503F7E93UL, + 0xD3772061UL, 0x11B638E1UL, 0x72500E03UL, 0xF80EB2BBUL, + 0xABE0502EUL, 0xEC8D77DEUL, 0x57971E81UL, 0xE14F6746UL, + 0xC9335400UL, 0x6920318FUL, 0x081DBB99UL, 0xFFC304A5UL, + 0x4D351805UL, 0x7F3D5CE3UL, 0xA6C866C6UL, 0x5D5BCCA9UL, + 0xDAEC6FEAUL, 0x9F926F91UL, 0x9F46222FUL, 0x3991467DUL, + 0xA5BF6D8EUL, 0x1143C44FUL, 0x43958302UL, 0xD0214EEBUL, + 0x022083B8UL, 0x3FB6180CUL, 0x18F8931EUL, 0x281658E6UL, + 0x26486E3EUL, 0x8BD78A70UL, 0x7477E4C1UL, 0xB506E07CUL, + 0xF32D0A25UL, 0x79098B02UL, 0xE4EABB81UL, 0x28123B23UL, + 0x69DEAD38UL, 0x1574CA16UL, 0xDF871B62UL, 0x211C40B7UL, + 0xA51A9EF9UL, 0x0014377BUL, 0x041E8AC8UL, 0x09114003UL, + 0xBD59E4D2UL, 0xE3D156D5UL, 0x4FE876D5UL, 0x2F91A340UL, + 0x557BE8DEUL, 0x00EAE4A7UL, 0x0CE5C2ECUL, 0x4DB4BBA6UL, + 0xE756BDFFUL, 0xDD3369ACUL, 0xEC17B035UL, 0x06572327UL, + 0x99AFC8B0UL, 0x56C8C391UL, 0x6B65811CUL, 0x5E146119UL, + 0x6E85CB75UL, 0xBE07C002UL, 0xC2325577UL, 0x893FF4ECUL, + 0x5BBFC92DUL, 0xD0EC3B25UL, 0xB7801AB7UL, 0x8D6D3B24UL, + 0x20C763EFUL, 0xC366A5FCUL, 0x9C382880UL, 0x0ACE3205UL, + 0xAAC9548AUL, 0xECA1D7C7UL, 0x041AFA32UL, 0x1D16625AUL, + 0x6701902CUL, 0x9B757A54UL, 0x31D477F7UL, 0x9126B031UL, + 0x36CC6FDBUL, 0xC70B8B46UL, 0xD9E66A48UL, 0x56E55A79UL, + 0x026A4CEBUL, 0x52437EFFUL, 0x2F8F76B4UL, 0x0DF980A5UL, + 0x8674CDE3UL, 0xEDDA04EBUL, 0x17A9BE04UL, 0x2C18F4DFUL, + 0xB7747F9DUL, 0xAB2AF7B4UL, 0xEFC34D20UL, 0x2E096B7CUL, + 0x1741A254UL, 0xE5B6A035UL, 0x213D42F6UL, 0x2C1C7C26UL, + 0x61C2F50FUL, 0x6552DAF9UL, 0xD2C231F8UL, 0x25130F69UL, + 0xD8167FA2UL, 0x0418F2C8UL, 0x001A96A6UL, 0x0D1526ABUL, + 0x63315C21UL, 0x5E0A72ECUL, 0x49BAFEFDUL, 0x187908D9UL, + 0x8D0DBD86UL, 0x311170A7UL, 0x3E9B640CUL, 0xCC3E10D7UL, + 0xD5CAD3B6UL, 0x0CAEC388UL, 0xF73001E1UL, 0x6C728AFFUL, + 0x71EAE2A1UL, 0x1F9AF36EUL, 0xCFCBD12FUL, 0xC1DE8417UL, + 0xAC07BE6BUL, 0xCB44A1D8UL, 0x8B9B0F56UL, 0x013988C3UL, + 0xB1C52FCAUL, 0xB4BE31CDUL, 0xD8782806UL, 0x12A3A4E2UL, + 0x6F7DE532UL, 0x58FD7EB6UL, 0xD01EE900UL, 0x24ADFFC2UL, + 0xF4990FC5UL, 0x9711AAC5UL, 0x001D7B95UL, 0x82E5E7D2UL, + 0x109873F6UL, 0x00613096UL, 0xC32D9521UL, 0xADA121FFUL, + 0x29908415UL, 0x7FBB977FUL, 0xAF9EB3DBUL, 0x29C9ED2AUL, + 0x5CE2A465UL, 0xA730F32CUL, 0xD0AA3FE8UL, 0x8A5CC091UL, + 0xD49E2CE7UL, 0x0CE454A9UL, 0xD60ACD86UL, 0x015F1919UL, + 0x77079103UL, 0xDEA03AF6UL, 0x78A8565EUL, 0xDEE356DFUL, + 0x21F05CBEUL, 0x8B75E387UL, 0xB3C50651UL, 0xB8A5C3EFUL, + 0xD8EEB6D2UL, 0xE523BE77UL, 0xC2154529UL, 0x2F69EFDFUL, + 0xAFE67AFBUL, 0xF470C4B2UL, 0xF3E0EB5BUL, 0xD6CC9876UL, + 0x39E4460CUL, 0x1FDA8538UL, 0x1987832FUL, 0xCA007367UL, + 0xA99144F8UL, 0x296B299EUL, 0x492FC295UL, 0x9266BEABUL, + 0xB5676E69UL, 0x9BD3DDDAUL, 0xDF7E052FUL, 0xDB25701CUL, + 0x1B5E51EEUL, 0xF65324E6UL, 0x6AFCE36CUL, 0x0316CC04UL, + 0x8644213EUL, 0xB7DC59D0UL, 0x7965291FUL, 0xCCD6FD43UL, + 0x41823979UL, 0x932BCDF6UL, 0xB657C34DUL, 0x4EDFD282UL, + 0x7AE5290CUL, 0x3CB9536BUL, 0x851E20FEUL, 0x9833557EUL, + 0x13ECF0B0UL, 0xD3FFB372UL, 0x3F85C5C1UL, 0x0AEF7ED2UL + }, + + { + 0x7EC90C04UL, 0x2C6E74B9UL, 0x9B0E66DFUL, 0xA6337911UL, + 0xB86A7FFFUL, 0x1DD358F5UL, 0x44DD9D44UL, 0x1731167FUL, + 0x08FBF1FAUL, 0xE7F511CCUL, 0xD2051B00UL, 0x735ABA00UL, + 0x2AB722D8UL, 0x386381CBUL, 0xACF6243AUL, 0x69BEFD7AUL, + 0xE6A2E77FUL, 0xF0C720CDUL, 0xC4494816UL, 0xCCF5C180UL, + 0x38851640UL, 0x15B0A848UL, 0xE68B18CBUL, 0x4CAADEFFUL, + 0x5F480A01UL, 0x0412B2AAUL, 0x259814FCUL, 0x41D0EFE2UL, + 0x4E40B48DUL, 0x248EB6FBUL, 0x8DBA1CFEUL, 0x41A99B02UL, + 0x1A550A04UL, 0xBA8F65CBUL, 0x7251F4E7UL, 0x95A51725UL, + 0xC106ECD7UL, 0x97A5980AUL, 0xC539B9AAUL, 0x4D79FE6AUL, + 0xF2F3F763UL, 0x68AF8040UL, 0xED0C9E56UL, 0x11B4958BUL, + 0xE1EB5A88UL, 0x8709E6B0UL, 0xD7E07156UL, 0x4E29FEA7UL, + 0x6366E52DUL, 0x02D1C000UL, 0xC4AC8E05UL, 0x9377F571UL, + 0x0C05372AUL, 0x578535F2UL, 0x2261BE02UL, 0xD642A0C9UL, + 0xDF13A280UL, 0x74B55BD2UL, 0x682199C0UL, 0xD421E5ECUL, + 0x53FB3CE8UL, 0xC8ADEDB3UL, 0x28A87FC9UL, 0x3D959981UL, + 0x5C1FF900UL, 0xFE38D399UL, 0x0C4EFF0BUL, 0x062407EAUL, + 0xAA2F4FB1UL, 0x4FB96976UL, 0x90C79505UL, 0xB0A8A774UL, + 0xEF55A1FFUL, 0xE59CA2C2UL, 0xA6B62D27UL, 0xE66A4263UL, + 0xDF65001FUL, 0x0EC50966UL, 0xDFDD55BCUL, 0x29DE0655UL, + 0x911E739AUL, 0x17AF8975UL, 0x32C7911CUL, 0x89F89468UL, + 0x0D01E980UL, 0x524755F4UL, 0x03B63CC9UL, 0x0CC844B2UL, + 0xBCF3F0AAUL, 0x87AC36E9UL, 0xE53A7426UL, 0x01B3D82BUL, + 0x1A9E7449UL, 0x64EE2D7EUL, 0xCDDBB1DAUL, 0x01C94910UL, + 0xB868BF80UL, 0x0D26F3FDUL, 0x9342EDE7UL, 0x04A5C284UL, + 0x636737B6UL, 0x50F5B616UL, 0xF24766E3UL, 0x8ECA36C1UL, + 0x136E05DBUL, 0xFEF18391UL, 0xFB887A37UL, 0xD6E7F7D4UL, + 0xC7FB7DC9UL, 0x3063FCDFUL, 0xB6F589DEUL, 0xEC2941DAUL, + 0x26E46695UL, 0xB7566419UL, 0xF654EFC5UL, 0xD08D58B7UL, + 0x48925401UL, 0xC1BACB7FUL, 0xE5FF550FUL, 0xB6083049UL, + 0x5BB5D0E8UL, 0x87D72E5AUL, 0xAB6A6EE1UL, 0x223A66CEUL, + 0xC62BF3CDUL, 0x9E0885F9UL, 0x68CB3E47UL, 0x086C010FUL, + 0xA21DE820UL, 0xD18B69DEUL, 0xF3F65777UL, 0xFA02C3F6UL, + 0x407EDAC3UL, 0xCBB3D550UL, 0x1793084DUL, 0xB0D70EBAUL, + 0x0AB378D5UL, 0xD951FB0CUL, 0xDED7DA56UL, 0x4124BBE4UL, + 0x94CA0B56UL, 0x0F5755D1UL, 0xE0E1E56EUL, 0x6184B5BEUL, + 0x580A249FUL, 0x94F74BC0UL, 0xE327888EUL, 0x9F7B5561UL, + 0xC3DC0280UL, 0x05687715UL, 0x646C6BD7UL, 0x44904DB3UL, + 0x66B4F0A3UL, 0xC0F1648AUL, 0x697ED5AFUL, 0x49E92FF6UL, + 0x309E374FUL, 0x2CB6356AUL, 0x85808573UL, 0x4991F840UL, + 0x76F0AE02UL, 0x083BE84DUL, 0x28421C9AUL, 0x44489406UL, + 0x736E4CB8UL, 0xC1092910UL, 0x8BC95FC6UL, 0x7D869CF4UL, + 0x134F616FUL, 0x2E77118DUL, 0xB31B2BE1UL, 0xAA90B472UL, + 0x3CA5D717UL, 0x7D161BBAUL, 0x9CAD9010UL, 0xAF462BA2UL, + 0x9FE459D2UL, 0x45D34559UL, 0xD9F2DA13UL, 0xDBC65487UL, + 0xF3E4F94EUL, 0x176D486FUL, 0x097C13EAUL, 0x631DA5C7UL, + 0x445F7382UL, 0x175683F4UL, 0xCDC66A97UL, 0x70BE0288UL, + 0xB3CDCF72UL, 0x6E5DD2F3UL, 0x20936079UL, 0x459B80A5UL, + 0xBE60E2DBUL, 0xA9C23101UL, 0xEBA5315CUL, 0x224E42F2UL, + 0x1C5C1572UL, 0xF6721B2CUL, 0x1AD2FFF3UL, 0x8C25404EUL, + 0x324ED72FUL, 0x4067B7FDUL, 0x0523138EUL, 0x5CA3BC78UL, + 0xDC0FD66EUL, 0x75922283UL, 0x784D6B17UL, 0x58EBB16EUL, + 0x44094F85UL, 0x3F481D87UL, 0xFCFEAE7BUL, 0x77B5FF76UL, + 0x8C2302BFUL, 0xAAF47556UL, 0x5F46B02AUL, 0x2B092801UL, + 0x3D38F5F7UL, 0x0CA81F36UL, 0x52AF4A8AUL, 0x66D5E7C0UL, + 0xDF3B0874UL, 0x95055110UL, 0x1B5AD7A8UL, 0xF61ED5ADUL, + 0x6CF6E479UL, 0x20758184UL, 0xD0CEFA65UL, 0x88F7BE58UL, + 0x4A046826UL, 0x0FF6F8F3UL, 0xA09C7F70UL, 0x5346ABA0UL, + 0x5CE96C28UL, 0xE176EDA3UL, 0x6BAC307FUL, 0x376829D2UL, + 0x85360FA9UL, 0x17E3FE2AUL, 0x24B79767UL, 0xF5A96B20UL, + 0xD6CD2595UL, 0x68FF1EBFUL, 0x7555442CUL, 0xF19F06BEUL, + 0xF9E0659AUL, 0xEEB9491DUL, 0x34010718UL, 0xBB30CAB8UL, + 0xE822FE15UL, 0x88570983UL, 0x750E6249UL, 0xDA627E55UL, + 0x5E76FFA8UL, 0xB1534546UL, 0x6D47DE08UL, 0xEFE9E7D4UL + }, + + { + 0xF6FA8F9DUL, 0x2CAC6CE1UL, 0x4CA34867UL, 0xE2337F7CUL, + 0x95DB08E7UL, 0x016843B4UL, 0xECED5CBCUL, 0x325553ACUL, + 0xBF9F0960UL, 0xDFA1E2EDUL, 0x83F0579DUL, 0x63ED86B9UL, + 0x1AB6A6B8UL, 0xDE5EBE39UL, 0xF38FF732UL, 0x8989B138UL, + 0x33F14961UL, 0xC01937BDUL, 0xF506C6DAUL, 0xE4625E7EUL, + 0xA308EA99UL, 0x4E23E33CUL, 0x79CBD7CCUL, 0x48A14367UL, + 0xA3149619UL, 0xFEC94BD5UL, 0xA114174AUL, 0xEAA01866UL, + 0xA084DB2DUL, 0x09A8486FUL, 0xA888614AUL, 0x2900AF98UL, + 0x01665991UL, 0xE1992863UL, 0xC8F30C60UL, 0x2E78EF3CUL, + 0xD0D51932UL, 0xCF0FEC14UL, 0xF7CA07D2UL, 0xD0A82072UL, + 0xFD41197EUL, 0x9305A6B0UL, 0xE86BE3DAUL, 0x74BED3CDUL, + 0x372DA53CUL, 0x4C7F4448UL, 0xDAB5D440UL, 0x6DBA0EC3UL, + 0x083919A7UL, 0x9FBAEED9UL, 0x49DBCFB0UL, 0x4E670C53UL, + 0x5C3D9C01UL, 0x64BDB941UL, 0x2C0E636AUL, 0xBA7DD9CDUL, + 0xEA6F7388UL, 0xE70BC762UL, 0x35F29ADBUL, 0x5C4CDD8DUL, + 0xF0D48D8CUL, 0xB88153E2UL, 0x08A19866UL, 0x1AE2EAC8UL, + 0x284CAF89UL, 0xAA928223UL, 0x9334BE53UL, 0x3B3A21BFUL, + 0x16434BE3UL, 0x9AEA3906UL, 0xEFE8C36EUL, 0xF890CDD9UL, + 0x80226DAEUL, 0xC340A4A3UL, 0xDF7E9C09UL, 0xA694A807UL, + 0x5B7C5ECCUL, 0x221DB3A6UL, 0x9A69A02FUL, 0x68818A54UL, + 0xCEB2296FUL, 0x53C0843AUL, 0xFE893655UL, 0x25BFE68AUL, + 0xB4628ABCUL, 0xCF222EBFUL, 0x25AC6F48UL, 0xA9A99387UL, + 0x53BDDB65UL, 0xE76FFBE7UL, 0xE967FD78UL, 0x0BA93563UL, + 0x8E342BC1UL, 0xE8A11BE9UL, 0x4980740DUL, 0xC8087DFCUL, + 0x8DE4BF99UL, 0xA11101A0UL, 0x7FD37975UL, 0xDA5A26C0UL, + 0xE81F994FUL, 0x9528CD89UL, 0xFD339FEDUL, 0xB87834BFUL, + 0x5F04456DUL, 0x22258698UL, 0xC9C4C83BUL, 0x2DC156BEUL, + 0x4F628DAAUL, 0x57F55EC5UL, 0xE2220ABEUL, 0xD2916EBFUL, + 0x4EC75B95UL, 0x24F2C3C0UL, 0x42D15D99UL, 0xCD0D7FA0UL, + 0x7B6E27FFUL, 0xA8DC8AF0UL, 0x7345C106UL, 0xF41E232FUL, + 0x35162386UL, 0xE6EA8926UL, 0x3333B094UL, 0x157EC6F2UL, + 0x372B74AFUL, 0x692573E4UL, 0xE9A9D848UL, 0xF3160289UL, + 0x3A62EF1DUL, 0xA787E238UL, 0xF3A5F676UL, 0x74364853UL, + 0x20951063UL, 0x4576698DUL, 0xB6FAD407UL, 0x592AF950UL, + 0x36F73523UL, 0x4CFB6E87UL, 0x7DA4CEC0UL, 0x6C152DAAUL, + 0xCB0396A8UL, 0xC50DFE5DUL, 0xFCD707ABUL, 0x0921C42FUL, + 0x89DFF0BBUL, 0x5FE2BE78UL, 0x448F4F33UL, 0x754613C9UL, + 0x2B05D08DUL, 0x48B9D585UL, 0xDC049441UL, 0xC8098F9BUL, + 0x7DEDE786UL, 0xC39A3373UL, 0x42410005UL, 0x6A091751UL, + 0x0EF3C8A6UL, 0x890072D6UL, 0x28207682UL, 0xA9A9F7BEUL, + 0xBF32679DUL, 0xD45B5B75UL, 0xB353FD00UL, 0xCBB0E358UL, + 0x830F220AUL, 0x1F8FB214UL, 0xD372CF08UL, 0xCC3C4A13UL, + 0x8CF63166UL, 0x061C87BEUL, 0x88C98F88UL, 0x6062E397UL, + 0x47CF8E7AUL, 0xB6C85283UL, 0x3CC2ACFBUL, 0x3FC06976UL, + 0x4E8F0252UL, 0x64D8314DUL, 0xDA3870E3UL, 0x1E665459UL, + 0xC10908F0UL, 0x513021A5UL, 0x6C5B68B7UL, 0x822F8AA0UL, + 0x3007CD3EUL, 0x74719EEFUL, 0xDC872681UL, 0x073340D4UL, + 0x7E432FD9UL, 0x0C5EC241UL, 0x8809286CUL, 0xF592D891UL, + 0x08A930F6UL, 0x957EF305UL, 0xB7FBFFBDUL, 0xC266E96FUL, + 0x6FE4AC98UL, 0xB173ECC0UL, 0xBC60B42AUL, 0x953498DAUL, + 0xFBA1AE12UL, 0x2D4BD736UL, 0x0F25FAABUL, 0xA4F3FCEBUL, + 0xE2969123UL, 0x257F0C3DUL, 0x9348AF49UL, 0x361400BCUL, + 0xE8816F4AUL, 0x3814F200UL, 0xA3F94043UL, 0x9C7A54C2UL, + 0xBC704F57UL, 0xDA41E7F9UL, 0xC25AD33AUL, 0x54F4A084UL, + 0xB17F5505UL, 0x59357CBEUL, 0xEDBD15C8UL, 0x7F97C5ABUL, + 0xBA5AC7B5UL, 0xB6F6DEAFUL, 0x3A479C3AUL, 0x5302DA25UL, + 0x653D7E6AUL, 0x54268D49UL, 0x51A477EAUL, 0x5017D55BUL, + 0xD7D25D88UL, 0x44136C76UL, 0x0404A8C8UL, 0xB8E5A121UL, + 0xB81A928AUL, 0x60ED5869UL, 0x97C55B96UL, 0xEAEC991BUL, + 0x29935913UL, 0x01FDB7F1UL, 0x088E8DFAUL, 0x9AB6F6F5UL, + 0x3B4CBF9FUL, 0x4A5DE3ABUL, 0xE6051D35UL, 0xA0E1D855UL, + 0xD36B4CF1UL, 0xF544EDEBUL, 0xB0E93524UL, 0xBEBB8FBDUL, + 0xA2D762CFUL, 0x49C92F54UL, 0x38B5F331UL, 0x7128A454UL, + 0x48392905UL, 0xA65B1DB8UL, 0x851C97BDUL, 0xD675CF2FUL + }, + + { + 0x85E04019UL, 0x332BF567UL, 0x662DBFFFUL, 0xCFC65693UL, + 0x2A8D7F6FUL, 0xAB9BC912UL, 0xDE6008A1UL, 0x2028DA1FUL, + 0x0227BCE7UL, 0x4D642916UL, 0x18FAC300UL, 0x50F18B82UL, + 0x2CB2CB11UL, 0xB232E75CUL, 0x4B3695F2UL, 0xB28707DEUL, + 0xA05FBCF6UL, 0xCD4181E9UL, 0xE150210CUL, 0xE24EF1BDUL, + 0xB168C381UL, 0xFDE4E789UL, 0x5C79B0D8UL, 0x1E8BFD43UL, + 0x4D495001UL, 0x38BE4341UL, 0x913CEE1DUL, 0x92A79C3FUL, + 0x089766BEUL, 0xBAEEADF4UL, 0x1286BECFUL, 0xB6EACB19UL, + 0x2660C200UL, 0x7565BDE4UL, 0x64241F7AUL, 0x8248DCA9UL, + 0xC3B3AD66UL, 0x28136086UL, 0x0BD8DFA8UL, 0x356D1CF2UL, + 0x107789BEUL, 0xB3B2E9CEUL, 0x0502AA8FUL, 0x0BC0351EUL, + 0x166BF52AUL, 0xEB12FF82UL, 0xE3486911UL, 0xD34D7516UL, + 0x4E7B3AFFUL, 0x5F43671BUL, 0x9CF6E037UL, 0x4981AC83UL, + 0x334266CEUL, 0x8C9341B7UL, 0xD0D854C0UL, 0xCB3A6C88UL, + 0x47BC2829UL, 0x4725BA37UL, 0xA66AD22BUL, 0x7AD61F1EUL, + 0x0C5CBAFAUL, 0x4437F107UL, 0xB6E79962UL, 0x42D2D816UL, + 0x0A961288UL, 0xE1A5C06EUL, 0x13749E67UL, 0x72FC081AUL, + 0xB1D139F7UL, 0xF9583745UL, 0xCF19DF58UL, 0xBEC3F756UL, + 0xC06EBA30UL, 0x07211B24UL, 0x45C28829UL, 0xC95E317FUL, + 0xBC8EC511UL, 0x38BC46E9UL, 0xC6E6FA14UL, 0xBAE8584AUL, + 0xAD4EBC46UL, 0x468F508BUL, 0x7829435FUL, 0xF124183BUL, + 0x821DBA9FUL, 0xAFF60FF4UL, 0xEA2C4E6DUL, 0x16E39264UL, + 0x92544A8BUL, 0x009B4FC3UL, 0xABA68CEDUL, 0x9AC96F78UL, + 0x06A5B79AUL, 0xB2856E6EUL, 0x1AEC3CA9UL, 0xBE838688UL, + 0x0E0804E9UL, 0x55F1BE56UL, 0xE7E5363BUL, 0xB3A1F25DUL, + 0xF7DEBB85UL, 0x61FE033CUL, 0x16746233UL, 0x3C034C28UL, + 0xDA6D0C74UL, 0x79AAC56CUL, 0x3CE4E1ADUL, 0x51F0C802UL, + 0x98F8F35AUL, 0x1626A49FUL, 0xEED82B29UL, 0x1D382FE3UL, + 0x0C4FB99AUL, 0xBB325778UL, 0x3EC6D97BUL, 0x6E77A6A9UL, + 0xCB658B5CUL, 0xD45230C7UL, 0x2BD1408BUL, 0x60C03EB7UL, + 0xB9068D78UL, 0xA33754F4UL, 0xF430C87DUL, 0xC8A71302UL, + 0xB96D8C32UL, 0xEBD4E7BEUL, 0xBE8B9D2DUL, 0x7979FB06UL, + 0xE7225308UL, 0x8B75CF77UL, 0x11EF8DA4UL, 0xE083C858UL, + 0x8D6B786FUL, 0x5A6317A6UL, 0xFA5CF7A0UL, 0x5DDA0033UL, + 0xF28EBFB0UL, 0xF5B9C310UL, 0xA0EAC280UL, 0x08B9767AUL, + 0xA3D9D2B0UL, 0x79D34217UL, 0x021A718DUL, 0x9AC6336AUL, + 0x2711FD60UL, 0x438050E3UL, 0x069908A8UL, 0x3D7FEDC4UL, + 0x826D2BEFUL, 0x4EEB8476UL, 0x488DCF25UL, 0x36C9D566UL, + 0x28E74E41UL, 0xC2610ACAUL, 0x3D49A9CFUL, 0xBAE3B9DFUL, + 0xB65F8DE6UL, 0x92AEAF64UL, 0x3AC7D5E6UL, 0x9EA80509UL, + 0xF22B017DUL, 0xA4173F70UL, 0xDD1E16C3UL, 0x15E0D7F9UL, + 0x50B1B887UL, 0x2B9F4FD5UL, 0x625ABA82UL, 0x6A017962UL, + 0x2EC01B9CUL, 0x15488AA9UL, 0xD716E740UL, 0x40055A2CUL, + 0x93D29A22UL, 0xE32DBF9AUL, 0x058745B9UL, 0x3453DC1EUL, + 0xD699296EUL, 0x496CFF6FUL, 0x1C9F4986UL, 0xDFE2ED07UL, + 0xB87242D1UL, 0x19DE7EAEUL, 0x053E561AUL, 0x15AD6F8CUL, + 0x66626C1CUL, 0x7154C24CUL, 0xEA082B2AUL, 0x93EB2939UL, + 0x17DCB0F0UL, 0x58D4F2AEUL, 0x9EA294FBUL, 0x52CF564CUL, + 0x9883FE66UL, 0x2EC40581UL, 0x763953C3UL, 0x01D6692EUL, + 0xD3A0C108UL, 0xA1E7160EUL, 0xE4F2DFA6UL, 0x693ED285UL, + 0x74904698UL, 0x4C2B0EDDUL, 0x4F757656UL, 0x5D393378UL, + 0xA132234FUL, 0x3D321C5DUL, 0xC3F5E194UL, 0x4B269301UL, + 0xC79F022FUL, 0x3C997E7EUL, 0x5E4F9504UL, 0x3FFAFBBDUL, + 0x76F7AD0EUL, 0x296693F4UL, 0x3D1FCE6FUL, 0xC61E45BEUL, + 0xD3B5AB34UL, 0xF72BF9B7UL, 0x1B0434C0UL, 0x4E72B567UL, + 0x5592A33DUL, 0xB5229301UL, 0xCFD2A87FUL, 0x60AEB767UL, + 0x1814386BUL, 0x30BCC33DUL, 0x38A0C07DUL, 0xFD1606F2UL, + 0xC363519BUL, 0x589DD390UL, 0x5479F8E6UL, 0x1CB8D647UL, + 0x97FD61A9UL, 0xEA7759F4UL, 0x2D57539DUL, 0x569A58CFUL, + 0xE84E63ADUL, 0x462E1B78UL, 0x6580F87EUL, 0xF3817914UL, + 0x91DA55F4UL, 0x40A230F3UL, 0xD1988F35UL, 0xB6E318D2UL, + 0x3FFA50BCUL, 0x3D40F021UL, 0xC3C0BDAEUL, 0x4958C24CUL, + 0x518F36B2UL, 0x84B1D370UL, 0x0FEDCE83UL, 0x878DDADAUL, + 0xF2A279C7UL, 0x94E01BE8UL, 0x90716F4BUL, 0x954B8AA3UL + }, + + { + 0xE216300DUL, 0xBBDDFFFCUL, 0xA7EBDABDUL, 0x35648095UL, + 0x7789F8B7UL, 0xE6C1121BUL, 0x0E241600UL, 0x052CE8B5UL, + 0x11A9CFB0UL, 0xE5952F11UL, 0xECE7990AUL, 0x9386D174UL, + 0x2A42931CUL, 0x76E38111UL, 0xB12DEF3AUL, 0x37DDDDFCUL, + 0xDE9ADEB1UL, 0x0A0CC32CUL, 0xBE197029UL, 0x84A00940UL, + 0xBB243A0FUL, 0xB4D137CFUL, 0xB44E79F0UL, 0x049EEDFDUL, + 0x0B15A15DUL, 0x480D3168UL, 0x8BBBDE5AUL, 0x669DED42UL, + 0xC7ECE831UL, 0x3F8F95E7UL, 0x72DF191BUL, 0x7580330DUL, + 0x94074251UL, 0x5C7DCDFAUL, 0xABBE6D63UL, 0xAA402164UL, + 0xB301D40AUL, 0x02E7D1CAUL, 0x53571DAEUL, 0x7A3182A2UL, + 0x12A8DDECUL, 0xFDAA335DUL, 0x176F43E8UL, 0x71FB46D4UL, + 0x38129022UL, 0xCE949AD4UL, 0xB84769ADUL, 0x965BD862UL, + 0x82F3D055UL, 0x66FB9767UL, 0x15B80B4EUL, 0x1D5B47A0UL, + 0x4CFDE06FUL, 0xC28EC4B8UL, 0x57E8726EUL, 0x647A78FCUL, + 0x99865D44UL, 0x608BD593UL, 0x6C200E03UL, 0x39DC5FF6UL, + 0x5D0B00A3UL, 0xAE63AFF2UL, 0x7E8BD632UL, 0x70108C0CUL, + 0xBBD35049UL, 0x2998DF04UL, 0x980CF42AUL, 0x9B6DF491UL, + 0x9E7EDD53UL, 0x06918548UL, 0x58CB7E07UL, 0x3B74EF2EUL, + 0x522FFFB1UL, 0xD24708CCUL, 0x1C7E27CDUL, 0xA4EB215BUL, + 0x3CF1D2E2UL, 0x19B47A38UL, 0x424F7618UL, 0x35856039UL, + 0x9D17DEE7UL, 0x27EB35E6UL, 0xC9AFF67BUL, 0x36BAF5B8UL, + 0x09C467CDUL, 0xC18910B1UL, 0xE11DBF7BUL, 0x06CD1AF8UL, + 0x7170C608UL, 0x2D5E3354UL, 0xD4DE495AUL, 0x64C6D006UL, + 0xBCC0C62CUL, 0x3DD00DB3UL, 0x708F8F34UL, 0x77D51B42UL, + 0x264F620FUL, 0x24B8D2BFUL, 0x15C1B79EUL, 0x46A52564UL, + 0xF8D7E54EUL, 0x3E378160UL, 0x7895CDA5UL, 0x859C15A5UL, + 0xE6459788UL, 0xC37BC75FUL, 0xDB07BA0CUL, 0x0676A3ABUL, + 0x7F229B1EUL, 0x31842E7BUL, 0x24259FD7UL, 0xF8BEF472UL, + 0x835FFCB8UL, 0x6DF4C1F2UL, 0x96F5B195UL, 0xFD0AF0FCUL, + 0xB0FE134CUL, 0xE2506D3DUL, 0x4F9B12EAUL, 0xF215F225UL, + 0xA223736FUL, 0x9FB4C428UL, 0x25D04979UL, 0x34C713F8UL, + 0xC4618187UL, 0xEA7A6E98UL, 0x7CD16EFCUL, 0x1436876CUL, + 0xF1544107UL, 0xBEDEEE14UL, 0x56E9AF27UL, 0xA04AA441UL, + 0x3CF7C899UL, 0x92ECBAE6UL, 0xDD67016DUL, 0x151682EBUL, + 0xA842EEDFUL, 0xFDBA60B4UL, 0xF1907B75UL, 0x20E3030FUL, + 0x24D8C29EUL, 0xE139673BUL, 0xEFA63FB8UL, 0x71873054UL, + 0xB6F2CF3BUL, 0x9F326442UL, 0xCB15A4CCUL, 0xB01A4504UL, + 0xF1E47D8DUL, 0x844A1BE5UL, 0xBAE7DFDCUL, 0x42CBDA70UL, + 0xCD7DAE0AUL, 0x57E85B7AUL, 0xD53F5AF6UL, 0x20CF4D8CUL, + 0xCEA4D428UL, 0x79D130A4UL, 0x3486EBFBUL, 0x33D3CDDCUL, + 0x77853B53UL, 0x37EFFCB5UL, 0xC5068778UL, 0xE580B3E6UL, + 0x4E68B8F4UL, 0xC5C8B37EUL, 0x0D809EA2UL, 0x398FEB7CUL, + 0x132A4F94UL, 0x43B7950EUL, 0x2FEE7D1CUL, 0x223613BDUL, + 0xDD06CAA2UL, 0x37DF932BUL, 0xC4248289UL, 0xACF3EBC3UL, + 0x5715F6B7UL, 0xEF3478DDUL, 0xF267616FUL, 0xC148CBE4UL, + 0x9052815EUL, 0x5E410FABUL, 0xB48A2465UL, 0x2EDA7FA4UL, + 0xE87B40E4UL, 0xE98EA084UL, 0x5889E9E1UL, 0xEFD390FCUL, + 0xDD07D35BUL, 0xDB485694UL, 0x38D7E5B2UL, 0x57720101UL, + 0x730EDEBCUL, 0x5B643113UL, 0x94917E4FUL, 0x503C2FBAUL, + 0x646F1282UL, 0x7523D24AUL, 0xE0779695UL, 0xF9C17A8FUL, + 0x7A5B2121UL, 0xD187B896UL, 0x29263A4DUL, 0xBA510CDFUL, + 0x81F47C9FUL, 0xAD1163EDUL, 0xEA7B5965UL, 0x1A00726EUL, + 0x11403092UL, 0x00DA6D77UL, 0x4A0CDD61UL, 0xAD1F4603UL, + 0x605BDFB0UL, 0x9EEDC364UL, 0x22EBE6A8UL, 0xCEE7D28AUL, + 0xA0E736A0UL, 0x5564A6B9UL, 0x10853209UL, 0xC7EB8F37UL, + 0x2DE705CAUL, 0x8951570FUL, 0xDF09822BUL, 0xBD691A6CUL, + 0xAA12E4F2UL, 0x87451C0FUL, 0xE0F6A27AUL, 0x3ADA4819UL, + 0x4CF1764FUL, 0x0D771C2BUL, 0x67CDB156UL, 0x350D8384UL, + 0x5938FA0FUL, 0x42399EF3UL, 0x36997B07UL, 0x0E84093DUL, + 0x4AA93E61UL, 0x8360D87BUL, 0x1FA98B0CUL, 0x1149382CUL, + 0xE97625A5UL, 0x0614D1B7UL, 0x0E25244BUL, 0x0C768347UL, + 0x589E8D82UL, 0x0D2059D1UL, 0xA466BB1EUL, 0xF8DA0A82UL, + 0x04F19130UL, 0xBA6E4EC0UL, 0x99265164UL, 0x1EE7230DUL, + 0x50B2AD80UL, 0xEAEE6801UL, 0x8DB2A283UL, 0xEA8BF59EUL + } +}; + +/* CAST uses three different round functions */ +#define _CAST_f1(l, r, km, kr) \ + t = rotate(km + r, kr); \ + l ^= ((S[0][U8a(t)] ^ S[1][U8b(t)]) - \ + S[2][U8c(t)]) + S[3][U8d(t)]; +#define _CAST_f2(l, r, km, kr) \ + t = rotate(km ^ r, kr); \ + l ^= ((S[0][U8a(t)] - S[1][U8b(t)]) + \ + S[2][U8c(t)]) ^ S[3][U8d(t)]; +#define _CAST_f3(l, r, km, kr) \ + t = rotate(km - r, kr); \ + l ^= ((S[0][U8a(t)] + S[1][U8b(t)]) ^ \ + S[2][U8c(t)]) - S[3][U8d(t)]; + +#define _CAST_F1(l, r, i, j) _CAST_f1(l, r, K[i], K[i+j]) +#define _CAST_F2(l, r, i, j) _CAST_f2(l, r, K[i], K[i+j]) +#define _CAST_F3(l, r, i, j) _CAST_f3(l, r, K[i], K[i+j]) + +inline void Cast5Encrypt(const uchar *inBlock, uchar *outBlock, CAST_KEY *key) +{ + uint l; GET_UINT32BE(l, inBlock, 0); + uint r; GET_UINT32BE(r, inBlock, 4); + uint *K = key->K; + uint t; + + /* Do the work */ + _CAST_F1(l, r, 0, 16); + _CAST_F2(r, l, 1, 16); + _CAST_F3(l, r, 2, 16); + _CAST_F1(r, l, 3, 16); + _CAST_F2(l, r, 4, 16); + _CAST_F3(r, l, 5, 16); + _CAST_F1(l, r, 6, 16); + _CAST_F2(r, l, 7, 16); + _CAST_F3(l, r, 8, 16); + _CAST_F1(r, l, 9, 16); + _CAST_F2(l, r, 10, 16); + _CAST_F3(r, l, 11, 16); + _CAST_F1(l, r, 12, 16); + _CAST_F2(r, l, 13, 16); + _CAST_F3(l, r, 14, 16); + _CAST_F1(r, l, 15, 16); + + /* Put l,r into outblock */ + PUT_UINT32BE(r, outBlock, 0); + PUT_UINT32BE(l, outBlock, 4); +} + +inline void Cast5Decrypt(const uchar *inBlock, uchar *outBlock, CAST_KEY *key) +{ + uint l; GET_UINT32BE(l, inBlock, 0); + uint r; GET_UINT32BE(r, inBlock, 4); + uint *K = key->K; + uint t; + + /* Only do full 16 rounds if key length > 80 bits */ + _CAST_F1(r, l, 15, 16); + _CAST_F3(l, r, 14, 16); + _CAST_F2(r, l, 13, 16); + _CAST_F1(l, r, 12, 16); + _CAST_F3(r, l, 11, 16); + _CAST_F2(l, r, 10, 16); + _CAST_F1(r, l, 9, 16); + _CAST_F3(l, r, 8, 16); + _CAST_F2(r, l, 7, 16); + _CAST_F1(l, r, 6, 16); + _CAST_F3(r, l, 5, 16); + _CAST_F2(l, r, 4, 16); + _CAST_F1(r, l, 3, 16); + _CAST_F3(l, r, 2, 16); + _CAST_F2(r, l, 1, 16); + _CAST_F1(l, r, 0, 16); + /* Put l,r into outblock */ + PUT_UINT32BE(r, outBlock, 0); + PUT_UINT32BE(l, outBlock, 4); + /* Wipe clean */ + t = l = r = 0; +} + +inline void Cast5SetKey(CAST_KEY *key, uint keylength, const uchar *userKey) +{ + uint i; + uint *K = key->K; + uint X[4], Z[4]; + + GET_UINT32BE(X[0], userKey, 0); + GET_UINT32BE(X[1], userKey, 4); + GET_UINT32BE(X[2], userKey, 8); + GET_UINT32BE(X[3], userKey, 12); + +#define x(i) GETBYTE(X[i/4], 3-i%4) +#define z(i) GETBYTE(Z[i/4], 3-i%4) + + for (i=0; i<=16; i+=16) { + // this part is copied directly from RFC 2144 (with some search and replace) by Wei Dai + Z[0] = X[0] ^ S[4][x(0xD)] ^ S[5][x(0xF)] ^ S[6][x(0xC)] ^ S[7][x(0xE)] ^ S[6][x(0x8)]; + Z[1] = X[2] ^ S[4][z(0x0)] ^ S[5][z(0x2)] ^ S[6][z(0x1)] ^ S[7][z(0x3)] ^ S[7][x(0xA)]; + Z[2] = X[3] ^ S[4][z(0x7)] ^ S[5][z(0x6)] ^ S[6][z(0x5)] ^ S[7][z(0x4)] ^ S[4][x(0x9)]; + Z[3] = X[1] ^ S[4][z(0xA)] ^ S[5][z(0x9)] ^ S[6][z(0xB)] ^ S[7][z(0x8)] ^ S[5][x(0xB)]; + K[i+0] = S[4][z(0x8)] ^ S[5][z(0x9)] ^ S[6][z(0x7)] ^ S[7][z(0x6)] ^ S[4][z(0x2)]; + K[i+1] = S[4][z(0xA)] ^ S[5][z(0xB)] ^ S[6][z(0x5)] ^ S[7][z(0x4)] ^ S[5][z(0x6)]; + K[i+2] = S[4][z(0xC)] ^ S[5][z(0xD)] ^ S[6][z(0x3)] ^ S[7][z(0x2)] ^ S[6][z(0x9)]; + K[i+3] = S[4][z(0xE)] ^ S[5][z(0xF)] ^ S[6][z(0x1)] ^ S[7][z(0x0)] ^ S[7][z(0xC)]; + X[0] = Z[2] ^ S[4][z(0x5)] ^ S[5][z(0x7)] ^ S[6][z(0x4)] ^ S[7][z(0x6)] ^ S[6][z(0x0)]; + X[1] = Z[0] ^ S[4][x(0x0)] ^ S[5][x(0x2)] ^ S[6][x(0x1)] ^ S[7][x(0x3)] ^ S[7][z(0x2)]; + X[2] = Z[1] ^ S[4][x(0x7)] ^ S[5][x(0x6)] ^ S[6][x(0x5)] ^ S[7][x(0x4)] ^ S[4][z(0x1)]; + X[3] = Z[3] ^ S[4][x(0xA)] ^ S[5][x(0x9)] ^ S[6][x(0xB)] ^ S[7][x(0x8)] ^ S[5][z(0x3)]; + K[i+4] = S[4][x(0x3)] ^ S[5][x(0x2)] ^ S[6][x(0xC)] ^ S[7][x(0xD)] ^ S[4][x(0x8)]; + K[i+5] = S[4][x(0x1)] ^ S[5][x(0x0)] ^ S[6][x(0xE)] ^ S[7][x(0xF)] ^ S[5][x(0xD)]; + K[i+6] = S[4][x(0x7)] ^ S[5][x(0x6)] ^ S[6][x(0x8)] ^ S[7][x(0x9)] ^ S[6][x(0x3)]; + K[i+7] = S[4][x(0x5)] ^ S[5][x(0x4)] ^ S[6][x(0xA)] ^ S[7][x(0xB)] ^ S[7][x(0x7)]; + Z[0] = X[0] ^ S[4][x(0xD)] ^ S[5][x(0xF)] ^ S[6][x(0xC)] ^ S[7][x(0xE)] ^ S[6][x(0x8)]; + Z[1] = X[2] ^ S[4][z(0x0)] ^ S[5][z(0x2)] ^ S[6][z(0x1)] ^ S[7][z(0x3)] ^ S[7][x(0xA)]; + Z[2] = X[3] ^ S[4][z(0x7)] ^ S[5][z(0x6)] ^ S[6][z(0x5)] ^ S[7][z(0x4)] ^ S[4][x(0x9)]; + Z[3] = X[1] ^ S[4][z(0xA)] ^ S[5][z(0x9)] ^ S[6][z(0xB)] ^ S[7][z(0x8)] ^ S[5][x(0xB)]; + K[i+8] = S[4][z(0x3)] ^ S[5][z(0x2)] ^ S[6][z(0xC)] ^ S[7][z(0xD)] ^ S[4][z(0x9)]; + K[i+9] = S[4][z(0x1)] ^ S[5][z(0x0)] ^ S[6][z(0xE)] ^ S[7][z(0xF)] ^ S[5][z(0xC)]; + K[i+10] = S[4][z(0x7)] ^ S[5][z(0x6)] ^ S[6][z(0x8)] ^ S[7][z(0x9)] ^ S[6][z(0x2)]; + K[i+11] = S[4][z(0x5)] ^ S[5][z(0x4)] ^ S[6][z(0xA)] ^ S[7][z(0xB)] ^ S[7][z(0x6)]; + X[0] = Z[2] ^ S[4][z(0x5)] ^ S[5][z(0x7)] ^ S[6][z(0x4)] ^ S[7][z(0x6)] ^ S[6][z(0x0)]; + X[1] = Z[0] ^ S[4][x(0x0)] ^ S[5][x(0x2)] ^ S[6][x(0x1)] ^ S[7][x(0x3)] ^ S[7][z(0x2)]; + X[2] = Z[1] ^ S[4][x(0x7)] ^ S[5][x(0x6)] ^ S[6][x(0x5)] ^ S[7][x(0x4)] ^ S[4][z(0x1)]; + X[3] = Z[3] ^ S[4][x(0xA)] ^ S[5][x(0x9)] ^ S[6][x(0xB)] ^ S[7][x(0x8)] ^ S[5][z(0x3)]; + K[i+12] = S[4][x(0x8)] ^ S[5][x(0x9)] ^ S[6][x(0x7)] ^ S[7][x(0x6)] ^ S[4][x(0x3)]; + K[i+13] = S[4][x(0xA)] ^ S[5][x(0xB)] ^ S[6][x(0x5)] ^ S[7][x(0x4)] ^ S[5][x(0x7)]; + K[i+14] = S[4][x(0xC)] ^ S[5][x(0xD)] ^ S[6][x(0x3)] ^ S[7][x(0x2)] ^ S[6][x(0x8)]; + K[i+15] = S[4][x(0xE)] ^ S[5][x(0xF)] ^ S[6][x(0x1)] ^ S[7][x(0x0)] ^ S[7][x(0xD)]; + } + + uint data[32]; + for (i = 0; i < 16; i++) { + data[i * 2] = K[i]; + data[i * 2 + 1] = ((K[i + 16]) + 16) & 0x1f; // here only the lowest 5 bits are set.. + } + + for (i=16; i<32; i++) + K[i] &= 0x1f; +} + +/* OpenSSL API compatibility */ +#define CAST_set_key(ckey, len, key) Cast5SetKey(ckey, len, key) +#define CAST_ecb_encrypt(in, out, ckey) Cast5Encrypt(in, out, ckey) +#define CAST_ecb_decrypt(in, out, ckey) Cast5Decrypt(in, out, ckey) + + +#endif /* _OPENCL_CAST_H */ \ No newline at end of file diff --git a/OpenCL/inc_platform.h b/OpenCL/inc_platform.h index 1e7805290..728e0e797 100644 --- a/OpenCL/inc_platform.h +++ b/OpenCL/inc_platform.h @@ -39,7 +39,7 @@ DECLSPEC u64x rotr64 (const u64x a, const int n); DECLSPEC u64 rotl64_S (const u64 a, const int n); DECLSPEC u64 rotr64_S (const u64 a, const int n); -//#define rotate(a,n) (((a) << (n)) | ((a) >> (32 - (n)))) +#define rotate(a,n) (((a) << (n)) | ((a) >> (32 - (n)))) #define bitselect(a,b,c) ((a) ^ ((c) & ((b) ^ (a)))) #endif // IS_CUDA diff --git a/OpenCL/m17040-pure.cl b/OpenCL/m17040-pure.cl index 406c35aa2..f07f67acd 100644 --- a/OpenCL/m17040-pure.cl +++ b/OpenCL/m17040-pure.cl @@ -1,5 +1,6 @@ /** * Author......: Netherlands Forensic Institute + * based upon 17010 * License.....: MIT */ @@ -11,13 +12,13 @@ #include M2S(INCLUDE_PATH/inc_platform.cl) #include M2S(INCLUDE_PATH/inc_common.cl) #include M2S(INCLUDE_PATH/inc_hash_sha1.cl) -#include M2S(INCLUDE_PATH/inc_cipher_aes.cl) +#include M2S(INCLUDE_PATH/inc_cipher_cast.h) #endif typedef struct gpg { u32 cipher_algo; - u32 iv[4]; + u32 iv[4]; // make this dynamic based on the input hash.. iv_size can be 8 bytes or 16 bytes u32 modulus_size; u32 encrypted_data[384]; u32 encrypted_data_size; @@ -116,67 +117,46 @@ DECLSPEC void memzero_be_S (PRIVATE_AS u32 *block, const u32 start_offset, const } } -DECLSPEC void aes128_decrypt_cfb (GLOBAL_AS const u32 *encrypted_data, int data_len, PRIVATE_AS const u32 *iv, PRIVATE_AS const u32 *key, PRIVATE_AS u32 *decrypted_data, - SHM_TYPE u32 *s_te0, SHM_TYPE u32 *s_te1, SHM_TYPE u32 *s_te2, SHM_TYPE u32 *s_te3, SHM_TYPE u32 *s_te4) +DECLSPEC void cast128_decrypt_cfb (GLOBAL_AS const u32 *encrypted_data, int data_len, PRIVATE_AS const u32 *iv, PRIVATE_AS const u32 *key, PRIVATE_AS u32 *decrypted_data) { - u32 ks[44]; - u32 essiv[4]; + u8 essiv[8]; + for (int j=0; j<8; j++) { essiv[j] = 0; } - // Copy the IV, since this will be modified - essiv[0] = iv[0]; - essiv[1] = iv[1]; - essiv[2] = iv[2]; - essiv[3] = iv[3]; - - aes128_set_encrypt_key (ks, key, s_te0, s_te1, s_te2, s_te3); - - // Decrypt an AES-128 encrypted block + // TODO remove this casting, would speedup the attack + // We need to do this casting to get values in local memory and have them not be constant. + u32 lencrypted_data[384]; // I'd prefer not to hardcode to 384, but rest of kernel uses the same value for (u32 i = 0; i < (data_len + 3) / 4; i += 4) { - aes128_encrypt (ks, essiv, decrypted_data + i, s_te0, s_te1, s_te2, s_te3, s_te4); - - decrypted_data[i + 0] ^= encrypted_data[i + 0]; - decrypted_data[i + 1] ^= encrypted_data[i + 1]; - decrypted_data[i + 2] ^= encrypted_data[i + 2]; - decrypted_data[i + 3] ^= encrypted_data[i + 3]; - - // Note: Not necessary if you are only decrypting a single block! - essiv[0] = encrypted_data[i + 0]; - essiv[1] = encrypted_data[i + 1]; - essiv[2] = encrypted_data[i + 2]; - essiv[3] = encrypted_data[i + 3]; + lencrypted_data[i + 0] = encrypted_data[i + 0]; + lencrypted_data[i + 1] = encrypted_data[i + 1]; + lencrypted_data[i + 2] = encrypted_data[i + 2]; + lencrypted_data[i + 3] = encrypted_data[i + 3]; } -} + u8 *lencrypted_data8 = (u8*)lencrypted_data; + u8 *decrypted_data8 = (u8*)decrypted_data; + u8 *key8 = (u8*)key; -DECLSPEC void aes256_decrypt_cfb (GLOBAL_AS const u32 *encrypted_data, int data_len, PRIVATE_AS const u32 *iv, PRIVATE_AS const u32 *key, PRIVATE_AS u32 *decrypted_data, - SHM_TYPE u32 *s_te0, SHM_TYPE u32 *s_te1, SHM_TYPE u32 *s_te2, SHM_TYPE u32 *s_te3, SHM_TYPE u32 *s_te4) -{ - u32 ks[60]; - u32 essiv[4]; // Copy the IV, since this will be modified - essiv[0] = iv[0]; - essiv[1] = iv[1]; - essiv[2] = iv[2]; - essiv[3] = iv[3]; + // essiv[0] = iv[0]; // IV is zero for our example, but we load it dynamically.. + // essiv[1] = iv[1]; // IV is zero for our example, but we load it dynamically.. + // essiv[2] = 0; + // essiv[3] = 0; //TODO load IV dynamically, code doesn't make any sense currently as essiv is now a u8 - aes256_set_encrypt_key (ks, key, s_te0, s_te1, s_te2, s_te3); + CAST_KEY ck; + Cast5SetKey(&ck, 16, key8); - // Decrypt an AES-256 encrypted block - for (u32 i = 0; i < (data_len + 3) / 4; i += 4) + // Decrypt an CAST5 encrypted block + for (u32 i = 0; i < (data_len + 3) ; i += 8) { - aes256_encrypt (ks, essiv, decrypted_data + i, s_te0, s_te1, s_te2, s_te3, s_te4); + Cast5Encrypt(essiv, &decrypted_data8[i], &ck); - decrypted_data[i + 0] ^= encrypted_data[i + 0]; - decrypted_data[i + 1] ^= encrypted_data[i + 1]; - decrypted_data[i + 2] ^= encrypted_data[i + 2]; - decrypted_data[i + 3] ^= encrypted_data[i + 3]; + for (int j=0; j<8; j++) { decrypted_data8[i+j] ^= lencrypted_data8[i + j]; } // Note: Not necessary if you are only decrypting a single block! - essiv[0] = encrypted_data[i + 0]; - essiv[1] = encrypted_data[i + 1]; - essiv[2] = encrypted_data[i + 2]; - essiv[3] = encrypted_data[i + 3]; + for (int j=0; j<8; j++) { + essiv[j] = lencrypted_data8[i + j]; + } } } @@ -194,6 +174,8 @@ DECLSPEC int check_decoded_data (PRIVATE_AS u32 *decoded_data, const u32 decoded expected_sha1[3] = hc_bytealign_le_S (decoded_data[sha1_u32_off + 4], decoded_data[sha1_u32_off + 3], sha1_byte_off); expected_sha1[4] = hc_bytealign_le_S (decoded_data[sha1_u32_off + 5], decoded_data[sha1_u32_off + 4], sha1_byte_off); + + memzero_le_S (decoded_data, sha1_byte_off, 384 * sizeof(u32)); sha1_ctx_t ctx; @@ -211,7 +193,7 @@ DECLSPEC int check_decoded_data (PRIVATE_AS u32 *decoded_data, const u32 decoded && (expected_sha1[4] == hc_swap32_S (ctx.h[4])); } -KERNEL_FQ void m17010_init (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) +KERNEL_FQ void m17040_init (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) { const u64 gid = get_global_id (0); @@ -260,12 +242,23 @@ KERNEL_FQ void m17010_init (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) tmps[gid].len = 0; } -KERNEL_FQ void m17010_loop_prepare (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) +KERNEL_FQ void m17040_loop_prepare (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) { const u64 gid = get_global_id (0); if (gid >= GID_CNT) return; + tmps[gid].h[0] = SHA1M_A; + tmps[gid].h[1] = SHA1M_B; + tmps[gid].h[2] = SHA1M_C; + tmps[gid].h[3] = SHA1M_D; + tmps[gid].h[4] = SHA1M_E; + tmps[gid].h[5] = SHA1M_A; + tmps[gid].h[6] = SHA1M_B; + tmps[gid].h[7] = SHA1M_C; + tmps[gid].h[8] = SHA1M_D; + tmps[gid].h[9] = SHA1M_E; + tmps[gid].w0[0] = 0; tmps[gid].w0[1] = 0; tmps[gid].w0[2] = 0; @@ -283,20 +276,21 @@ KERNEL_FQ void m17010_loop_prepare (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) tmps[gid].w3[2] = 0; tmps[gid].w3[3] = 0; - tmps[gid].len = SALT_REPEAT; + tmps[gid].len = 0; } -KERNEL_FQ void m17010_loop (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) +KERNEL_FQ void m17040_loop (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) { const u64 gid = get_global_id (0); + const u64 lid = get_local_id (0); if (gid >= GID_CNT) return; // get the prepared buffer from the gpg_tmp_t struct into a local buffer u32 salted_pw_block[80]; - for (int i = 0; i < 80; i++) salted_pw_block[i] = tmps[gid].salted_pw_block[i]; + const u32 salted_pw_block_len = tmps[gid].salted_pw_block_len; // do we really need this, since the salt is always length 8? @@ -308,47 +302,31 @@ KERNEL_FQ void m17010_loop (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) sha1_ctx_t ctx; - const u32 sha_offset = SALT_REPEAT * 5; - - for (int i = 0; i < 5; i++) ctx.h[i] = tmps[gid].h[sha_offset + i]; + for (int i = 0; i < 5; i++) ctx.h[i] = tmps[gid].h[i]; for (int i = 0; i < 4; i++) ctx.w0[i] = tmps[gid].w0[i]; for (int i = 0; i < 4; i++) ctx.w1[i] = tmps[gid].w1[i]; for (int i = 0; i < 4; i++) ctx.w2[i] = tmps[gid].w2[i]; for (int i = 0; i < 4; i++) ctx.w3[i] = tmps[gid].w3[i]; + const u32 pw_len = pws[gid].pw_len; + const u32 salted_pw_len = (salt_bufs[SALT_POS_HOST].salt_len + pw_len); + const u32 remaining_bytes = salted_pw_len % 4; + ctx.len = tmps[gid].len; - // sha-1 of salt and password, up to 'salt_iter' bytes - const u32 salt_iter = salt_bufs[SALT_POS_HOST].salt_iter; - - const u32 salted_pw_block_pos = LOOP_POS % salted_pw_block_len; - const u32 rounds = (LOOP_CNT + salted_pw_block_pos) / salted_pw_block_len; - - for (u32 i = 0; i < rounds; i++) - { - sha1_update (&ctx, salted_pw_block, salted_pw_block_len); - } - - if ((LOOP_POS + LOOP_CNT) == salt_iter) - { - const u32 remaining_bytes = salt_iter % salted_pw_block_len; - - if (remaining_bytes) - { - memzero_be_S (salted_pw_block, remaining_bytes, salted_pw_block_len); - - sha1_update (&ctx, salted_pw_block, remaining_bytes); - } - - sha1_final (&ctx); - } + memzero_be_S (salted_pw_block, salted_pw_len, salted_pw_block_len); + // zero out last bytes of password if not a multiple of 4 + // TODO do we need this wo don't feed the remainder to the hashing algorithm anyway..?? + sha1_update (&ctx, salted_pw_block, salted_pw_len); + sha1_final (&ctx); /** * context save */ - for (int i = 0; i < 5; i++) tmps[gid].h[sha_offset + i] = ctx.h[i]; + for (int i = 0; i < 5; i++) tmps[gid].h[i] = ctx.h[i]; + // this is the sha1 hash of the salt+password: for (int i = 0; i < 4; i++) tmps[gid].w0[i] = ctx.w0[i]; for (int i = 0; i < 4; i++) tmps[gid].w1[i] = ctx.w1[i]; @@ -358,12 +336,12 @@ KERNEL_FQ void m17010_loop (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) tmps[gid].len = ctx.len; } -KERNEL_FQ void m17010_comp (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) +KERNEL_FQ void m17040_comp (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) { // not in use here, special case... } -KERNEL_FQ void m17010_aux1 (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) +KERNEL_FQ void m17040_aux1 (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) { /** * modifier @@ -373,56 +351,20 @@ KERNEL_FQ void m17010_aux1 (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) const u64 gid = get_global_id (0); const u64 lsz = get_local_size (0); - /** - * aes shared - */ - - #ifdef REAL_SHM - - 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_te0[i] = te0[i]; - s_te1[i] = te1[i]; - s_te2[i] = te2[i]; - s_te3[i] = te3[i]; - s_te4[i] = te4[i]; - } - - SYNC_THREADS (); - - #else - - 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 - if (gid >= GID_CNT) return; - // retrieve and use the SHA-1 as the key for AES - - u32 aes_key[4]; - - for (int i = 0; i < 4; i++) aes_key[i] = hc_swap32_S (tmps[gid].h[i]); + // retrieve and use the SHA-1 as the key for CAST5 + u32 cast_key[5]; + for (int i = 0; i < 5; i++) cast_key[i] = hc_swap32_S (tmps[gid].h[i]); u32 iv[4] = {0}; - for (int idx = 0; idx < 4; idx++) iv[idx] = esalt_bufs[DIGESTS_OFFSET_HOST].iv[idx]; u32 decoded_data[384]; const u32 enc_data_size = esalt_bufs[DIGESTS_OFFSET_HOST].encrypted_data_size; - aes128_decrypt_cfb (esalt_bufs[DIGESTS_OFFSET_HOST].encrypted_data, enc_data_size, iv, aes_key, decoded_data, s_te0, s_te1, s_te2, s_te3, s_te4); + cast128_decrypt_cfb (esalt_bufs[DIGESTS_OFFSET_HOST].encrypted_data, enc_data_size, iv, cast_key, decoded_data); if (check_decoded_data (decoded_data, enc_data_size)) { @@ -431,74 +373,4 @@ KERNEL_FQ void m17010_aux1 (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) mark_hash (plains_buf, d_return_buf, SALT_POS_HOST, DIGESTS_CNT, 0, DIGESTS_OFFSET_HOST + 0, gid, 0, 0, 0); } } -} - -KERNEL_FQ void m17010_aux2 (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) -{ - /** - * modifier - */ - - const u64 lid = get_local_id (0); - const u64 gid = get_global_id (0); - const u64 lsz = get_local_size (0); - - /** - * aes shared - */ - - #ifdef REAL_SHM - - 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_te0[i] = te0[i]; - s_te1[i] = te1[i]; - s_te2[i] = te2[i]; - s_te3[i] = te3[i]; - s_te4[i] = te4[i]; - } - - SYNC_THREADS (); - - #else - - 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 - - if (gid >= GID_CNT) return; - - // retrieve and use the SHA-1 as the key for AES - - u32 aes_key[8]; - - for (int i = 0; i < 8; i++) aes_key[i] = hc_swap32_S (tmps[gid].h[i]); - - u32 iv[4] = {0}; - - for (int idx = 0; idx < 4; idx++) iv[idx] = esalt_bufs[DIGESTS_OFFSET_HOST].iv[idx]; - - u32 decoded_data[384]; - - const u32 enc_data_size = esalt_bufs[DIGESTS_OFFSET_HOST].encrypted_data_size; - - aes256_decrypt_cfb (esalt_bufs[DIGESTS_OFFSET_HOST].encrypted_data, enc_data_size, iv, aes_key, decoded_data, s_te0, s_te1, s_te2, s_te3, s_te4); - - if (check_decoded_data (decoded_data, enc_data_size)) - { - if (hc_atomic_inc (&hashes_shown[DIGESTS_OFFSET_HOST]) == 0) - { - mark_hash (plains_buf, d_return_buf, SALT_POS_HOST, DIGESTS_CNT, 0, DIGESTS_OFFSET_HOST + 0, gid, 0, 0, 0); - } - } -} +} \ No newline at end of file diff --git a/docs/changes.txt b/docs/changes.txt index f878b77ca..1995ed3ef 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -47,6 +47,7 @@ - Added hash-mode: md5(md5(md5($pass)).$salt) - Added hash-mode: md5(sha1($pass.$salt)) - Added hash-mode: sha512(sha512($pass).$salt) +- Added hash-mode: GPG (CAST5 (SHA-1($pass))) ## ## Features diff --git a/src/modules/module_17040.c b/src/modules/module_17040.c index 865a6f8eb..fff78ad48 100644 --- a/src/modules/module_17040.c +++ b/src/modules/module_17040.c @@ -17,18 +17,18 @@ static const u32 DGST_POS2 = 2; static const u32 DGST_POS3 = 3; static const u32 DGST_SIZE = DGST_SIZE_4_4; static const u32 HASH_CATEGORY = HASH_CATEGORY_PRIVATE_KEY; -static const char *HASH_NAME = "GPG (AES-128/AES-256 (SHA-1($pass)))"; -static const u64 KERN_TYPE = 17010; +static const char *HASH_NAME = "GPG (CAST5 (SHA-1($pass)))"; +static const u64 KERN_TYPE = 17040; static const u32 OPTI_TYPE = OPTI_TYPE_ZERO_BYTE; static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE | OPTS_TYPE_PT_GENERATE_LE | OPTS_TYPE_LOOP_PREPARE | OPTS_TYPE_AUX1 - | OPTS_TYPE_AUX2 | OPTS_TYPE_DEEP_COMP_KERNEL; static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; -static const char *ST_PASS = "hashcat"; -static const char *ST_HASH = "$gpg$*1*348*1024*8833fa3812b5500aa9eb7e46febfa31a0584b7e4a5b13c198f5c9b0814243895cce45ac3714e79692fb5a130a1c943b9130315ce303cb7e6831be68ce427892858f313fc29f533434dbe0ef26573f2071bbcc1499dc49bda90648221ef3823757e2fba6099a18c0c83386b21d8c9b522ec935ecd540210dbf0f21c859429fd4d35fa056415d8087f27b3e66b16081ea18c544d8b2ea414484f17097bc83b773d92743f76eb2ccb4df8ba5f5ff84a5474a5e8a8e5179a5b0908503c55e428de04b40628325739874e1b4aa004c4cbdf09b0b620990a8479f1c9b4187e33e63fe48a565bc1264bbf4062559631bef9e346a7217f1cabe101a38ac4be9fa94f6dafe6b0301e67792ed51bca04140cddd5cb6e80ac6e95e9a09378c9651588fe360954b622c258a3897f11246c944a588822cc6daf1cb81ccc95098c3bea8432f1ee0c663b193a7c7f1cdfeb91eee0195296bf4783025655cbebd7c70236*3*254*2*7*16*a47ef38987beab0a0b9bfe74b72822e8*65536*1f5c90d9820997db"; +static const char *ST_PASS = "Hashcat1!"; +static const char *ST_HASH = "$gpg$*1*1308*4096*ddf02802e2d06319bcf5962745b73677ecfa229649fed991e3360bdf2fffe71f521b8f877bccfcdce9a4fb4aeb63bd21fed6e37f96f193a6f7d3c476f4a7e01e7421d0eba5bfcd59544e37887572cd40e8d03e901574ec0f3afdff35ad3f25cb818ddadee84ddfef636207febd8d12d8a98983c86afa46608d178dba5ec51e98a182bd9687b6431fba87b5a16b5e0cf872db7dc12c55bfe7faaa443044d5a84ddf034198e5bc6b4b707b5f4a4c5999ff3885975113fca02693620f36f8f20570bdaf581726053b6c982cb988a3091dc206624f9d36372b151b22c7dc2cb71b9aaed95dc5630c4c4b045f80c403836cc9c84951fc04b8d6e413e1d4f6b3815508f43cf80c25c7db3882b5b6572f1395a00dcda7fe65ce2155f9ea2cfe13588e0fb10316e7dd978e1d89cffc06a5e722ec765315926d2ee9060d8f449ead31cbacea88a5251be3b518d23984530da9f930114e614b7ed30f748c7512bddca8604bb5310ed76b9982eb88acaf49a29325e9db6987c6dea3878e2cb7daf3800177579ddcaafeacdba8edd147fae61bae36ab83a98db69a6c92017b3db8cff68985db989a03ee1bd045e6a577151486cdaeaf26517027b2f140b8493e2f401ea222511c2ce61c7057d64e8c3568e3f547f4b2875db59bc8c4f3346e0faf54e30745f583494b59e570bacb2b9eb71eb834e57f68aadda9af4bdb03276f71770c611aad0278033bb8c108471c4f4a2aa9070774367b9334661daf8a5e3eaf3d8dcca723d64ae7264c8709987a6cee9f42287b6e20d1d753262ff74886f3995412e59d09c61e4c637b6e97e6a3b08f9fa6adf9a1ec44a0372e893febd6712decc00bbd9cdacaf6bb9302fe8bd2ca27fdf5156c33582d56781ab0e5bd14da4b1edd73edd8f2a034a56d1a6f836724b605657f4714d59d522805e0ab02c6c5daed0973f93120ae01623ce0a96fbdf4402ce20ebb4f97fabbc90da5bb12aac3cd5f15c1add2d3863be59e843dca564ce9aa25b43ca1044b1e7e65d03d1f55f77d2a39cd85536ff38058837a23743c4e252f7de5654a562506b55d2b8fa29c7f4ecd307a8ae686cbb73fea6a8f72775d9e417ec346415024263a9f339dda286b682ccc8f93f7d4f59921620dd276188441fd44fc63925d18caa30a75c79c37a2ea45d14f6e423d2146281f9c6699a0658e50d69cfbc174090a0420bbb6f4e6b5b1f2b81b26f035aaf5c2e558c812496cb494587c78bf75350fb1a36e8c88076b4684094e0cba5dcdc4f672dbd2b432306b75077ae07b8fd88ba5b829eaed3fd2959a09b162329b75ac8fc20d4eea6e5971f54b31a23952dd4c111765822182cd60ee0de3cce3752c648918e3ec4c52643223132dcc885140faf8108230ebf4ef4149cbfa3070c91ec013404c15c1cecaa1efd544ab8313d378ef0e77c615b76b8ec07769960873ce9c7bdb1d75e7faef4c8a0b015c95a4e2bcd9ff7f5dfddd9a243fc0688db09e534ef1f3ebebd0c73b75bd57b8e02667da5744b1400dc695d4ae1e255d3487d1dead115de7d48962a15c7aecb97444173c40c028a46a7cfdd8cc7421f71d757cb809341c5148aedeab16f9289bc55b7475d646ae4993ab36fe5609a05121d140d4390289c94e4d87fd902fe03c8bfa13e7cfc9c21355ab6461d214137e4d90dff4a8f599020f12d7560fa4b5aaee1727f21c873fde76415b65357ecb923a547ddcdb20dde0880a287ed26d5ea4ce45514b907e368527c62e39ffdf2efeb817cd59694d23bafd48862e723f45e3c258cff3c804c5d2f17e24be8fe81a00f11f519beb9cde7be95226ac2a7f11e0f4f09dc040c11e1bf63172aa0f8a*1*254*2*3*8*0000000000000000*0*a11df265e4e54bee"; + 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; } @@ -48,7 +48,7 @@ const char *module_st_pass (MAYBE_UNUSED const hashconfig_t *hashconfig, typedef struct gpg { u32 cipher_algo; - u32 iv[4]; + u32 iv[4]; // TODO make this dynamic based on the input hash.. iv_size can be 8 bytes or 16 bytes u32 modulus_size; u32 encrypted_data[384]; u32 encrypted_data_size; @@ -117,15 +117,10 @@ u32 module_deep_comp_kernel (MAYBE_UNUSED const hashes_t *hashes, MAYBE_UNUSED c gpg_t *gpg = &gpgs[digests_offset + digest_pos]; - if (gpg->cipher_algo == 7) + if (gpg->cipher_algo == 3) // CAST5 { return KERN_RUN_AUX1; } - else if (gpg->cipher_algo == 9) - { - return KERN_RUN_AUX2; - } - return 0; } @@ -178,40 +173,60 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE token.attr[4] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; - // "3" - String2Key parameter + // "3" - String2Key parameter "S2K Type" https://www.rfc-editor.org/rfc/rfc4880#section-3.7 + // https://security.stackexchange.com/questions/142914/does-s2k-hold-any-use-in-symmetric-encryption-with-gnupg "OpenPGP uses the string-to-key function for both encrypting the private key with a passphrase and symmetric encryption. The function is used to derive a session key (cipher block) for symmetric encryption." + // https://github.com/gpg/gnupg/blob/ab35d756d86438db124fa68aa633fe528ff8be50/g10/packet.h#L98 + // https://www.rfc-editor.org/rfc/rfc4880#section-3.7 so we only have a salted s2k not an iterated-and-salted + // ID S2K Type + // -- -------- + // 0 Simple S2K + // 1 Salted S2K + // 2 Reserved value + // 3 Iterated and Salted S2K token.sep[5] = '*'; token.len[5] = 1; token.attr[5] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; - // "254" - String2Key parameters + // "254" - String2Key parameter "usage" / "Secret-Key Packet Format" https://github.com/openwall/john/blob/bleeding-jumbo/src/gpg2john.c#L2424 + // 255 or 254 + // indicates that a string-to-key specifier is being given. Any + // other value is a symmetric-key encryption algorithm identifier. + + // If the string-to-key usage octet was + // 254, then a 20-octet SHA-1 hash of the plaintext of the + // algorithm-specific portion. token.sep[6] = '*'; token.len[6] = 3; token.attr[6] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; - // "2" - String2Key parameters + // "2" - String2Key parameter "HASH_ALGS" https://github.com/openwall/john/blob/bleeding-jumbo/src/gpg2john.c#L646 + // sha1 in this case token.sep[7] = '*'; token.len[7] = 1; token.attr[7] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; - // cipher mode: 7 or 9 + // "3" cipher mode: String2Key parameter "SYM_ALGS" https://github.com/openwall/john/blob/bleeding-jumbo/src/gpg2john.c#L558 + // cast in this case token.sep[8] = '*'; token.len[8] = 1; token.attr[8] = TOKEN_ATTR_FIXED_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; - // size of initial vector in bytes: 16 + // size of initial vector in bytes: 8 or 16 token.sep[9] = '*'; - token.len[9] = 2; - token.attr[9] = TOKEN_ATTR_FIXED_LENGTH + token.len_min[9] = 1; + token.len_max[9] = 2; + token.attr[9] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; // initial vector - twice the amount of bytes because its interpreted as characters token.sep[10] = '*'; - token.len[10] = 32; - token.attr[10] = TOKEN_ATTR_FIXED_LENGTH + token.len_min[10] = 16; + token.len_max[10] = 32; + token.attr[10] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_HEX; // iteration count @@ -250,37 +265,52 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE // Check String2Key parameters - if (hc_strtoul ((const char *) token.buf[5], NULL, 10) != 3) return (PARSER_HASH_VALUE); + if ((hc_strtoul ((const char *) token.buf[5], NULL, 10) != 1) && (hc_strtoul ((const char *) token.buf[5], NULL, 10) != 3)) { + return (PARSER_HASH_VALUE); // for us this "String2Key parameter 1" is 1 instead of 3, no idea what that means.. + } + + // 100 to 110 Private/Experimental S2K if (hc_strtoul ((const char *) token.buf[6], NULL, 10) != 254) return (PARSER_HASH_VALUE); if (hc_strtoul ((const char *) token.buf[7], NULL, 10) != 2) return (PARSER_HASH_VALUE); // Cipher algo - const int cipher_algo = hc_strtoul ((const char *) token.buf[8], NULL, 10); - if ((cipher_algo != 7) && (cipher_algo != 9)) return (PARSER_CIPHER); + if (cipher_algo != 3) return (PARSER_CIPHER); gpg->cipher_algo = cipher_algo; // IV (size) - if (hc_strtoul ((const char *) token.buf[9], NULL, 10) != sizeof (gpg->iv)) return (PARSER_IV_LENGTH); + // if (hc_strtoul ((const char *) token.buf[9], NULL, 10) != sizeof (gpg->iv)) { + // // printf("hc_strtoul ((const char *) token.buf[9]=%d\n", (const char *) token.buf[9], NULL, 10); + // // printf("sizeof (gpg->iv)=%d\n", sizeof (gpg->iv)); + // return (PARSER_IV_LENGTH); + // } + // const int iv_size = hex_decode ((const u8 *) token.buf[10], token.len[10], (u8 *) gpg->iv); - const int iv_size = hex_decode ((const u8 *) token.buf[10], token.len[10], (u8 *) gpg->iv); + // if (iv_size != sizeof (gpg->iv)){ + // return (PARSER_IV_LENGTH); + // } - if (iv_size != sizeof (gpg->iv)) return (PARSER_IV_LENGTH); // Salt Iter const u32 salt_iter = hc_strtoul ((const char *) token.buf[11], NULL, 10); - if (salt_iter < 8 || salt_iter > 65011712) return (PARSER_SALT_ITERATION); + if (salt_iter != 0) return (PARSER_HASH_VALUE); // only accept 0 for now + if(salt_iter ==0){ salt->salt_iter = 8; } // just once should work? TODO not sure why I cannot change this to zero / remove the salt_iter completely.. + // else { + // if (salt_iter < 8 || salt_iter > 65011712){ return (PARSER_SALT_ITERATION); } + // else { + // salt->salt_iter = salt_iter; + // } + // } - salt->salt_iter = salt_iter; // Salt Value - salt->salt_repeats = gpg->cipher_algo == 7 ? 0 : 1; // "minus one" + salt->salt_repeats = gpg->cipher_algo == 7 ? 0 : 1; // "minus one" // TODO check this? salt->salt_len = hex_decode ((const u8 *) token.buf[12], token.len[12], (u8 *) salt->salt_buf); @@ -300,25 +330,24 @@ int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE const gpg_t *gpg = (const gpg_t *) esalt_buf; u8 encrypted_data[(384 * 8) + 1]; + memset(encrypted_data,0,384*8+1); // always initialize to zero hex_encode ((const u8 *) gpg->encrypted_data, gpg->encrypted_data_size, (u8 *) encrypted_data); - const int line_len = snprintf (line_buf, line_size, "%s*%d*%d*%d*%s*%d*%d*%d*%d*%d*%08x%08x%08x%08x*%d*%08x%08x", + const int line_len = snprintf (line_buf, line_size, "%s*%d*%d*%d*%s*%d*%d*%d*%d*%d*%08x%08x*%d*%08x%08x", SIGNATURE_GPG, 1, /* unknown field */ gpg->encrypted_data_size, gpg->modulus_size, encrypted_data, - 3, /* version (major?) */ + 1, /* version (major?) */ 254, /* version (minor?) */ 2, /* key cipher (sha-1) */ gpg->cipher_algo, - 16, /*iv_size*/ + 8, /*iv_size*/ byte_swap_32 (gpg->iv[0]), byte_swap_32 (gpg->iv[1]), - byte_swap_32 (gpg->iv[2]), - byte_swap_32 (gpg->iv[3]), - salt->salt_iter, + 0, /* salt_iter is always zero */ byte_swap_32 (salt->salt_buf[0]), byte_swap_32 (salt->salt_buf[1])); From b4c12ee6288acbca4d74a6c52c7a5b1d79155921 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 26 Jun 2023 13:34:41 +0200 Subject: [PATCH 3/4] add test hashes --- example17040.sh | 16 ++++++++++++++++ src/modules/module_17040.c | 2 +- tools/refdata/m17040/ref1-cast5.hash | 1 + tools/refdata/m17040/ref1-cast5.txt | 1 + tools/refdata/m17040/ref2-cast5.hash | 1 + tools/refdata/m17040/ref2-cast5.txt | 1 + 6 files changed, 21 insertions(+), 1 deletion(-) create mode 100755 example17040.sh create mode 100644 tools/refdata/m17040/ref1-cast5.hash create mode 100644 tools/refdata/m17040/ref1-cast5.txt create mode 100644 tools/refdata/m17040/ref2-cast5.hash create mode 100644 tools/refdata/m17040/ref2-cast5.txt diff --git a/example17040.sh b/example17040.sh new file mode 100755 index 000000000..4c3ee3deb --- /dev/null +++ b/example17040.sh @@ -0,0 +1,16 @@ +#!/bin/bash +FILE="./hashcat.exe" +if [[ -f "$FILE" ]]; then + echo "we found hashcat.exe binary so use that" #wsl +else + FILE="./hashcat" + if [[ -f "$FILE" ]]; then + echo "we found ./hashcat binary so use that" #linux + else + echo "could not find hashcat binary, compile it first using make" + exit + fi +fi + +$FILE -a0 -m17040 tools/refdata/m17040/ref1-cast5.hash tools/refdata/m17040/ref1-cast5.txt --potfile-disable +$FILE -a0 -m17040 tools/refdata/m17040/ref2-cast5.hash tools/refdata/m17040/ref2-cast5.txt --potfile-disable diff --git a/src/modules/module_17040.c b/src/modules/module_17040.c index fff78ad48..36c94c897 100644 --- a/src/modules/module_17040.c +++ b/src/modules/module_17040.c @@ -269,7 +269,7 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE return (PARSER_HASH_VALUE); // for us this "String2Key parameter 1" is 1 instead of 3, no idea what that means.. } - // 100 to 110 Private/Experimental S2K + // 100 to 110 Private/Experimental S2K if (hc_strtoul ((const char *) token.buf[6], NULL, 10) != 254) return (PARSER_HASH_VALUE); if (hc_strtoul ((const char *) token.buf[7], NULL, 10) != 2) return (PARSER_HASH_VALUE); diff --git a/tools/refdata/m17040/ref1-cast5.hash b/tools/refdata/m17040/ref1-cast5.hash new file mode 100644 index 000000000..bf1ba0dde --- /dev/null +++ b/tools/refdata/m17040/ref1-cast5.hash @@ -0,0 +1 @@ +$gpg$*1*1308*4096*ddf02802e2d06319bcf5962745b73677ecfa229649fed991e3360bdf2fffe71f521b8f877bccfcdce9a4fb4aeb63bd21fed6e37f96f193a6f7d3c476f4a7e01e7421d0eba5bfcd59544e37887572cd40e8d03e901574ec0f3afdff35ad3f25cb818ddadee84ddfef636207febd8d12d8a98983c86afa46608d178dba5ec51e98a182bd9687b6431fba87b5a16b5e0cf872db7dc12c55bfe7faaa443044d5a84ddf034198e5bc6b4b707b5f4a4c5999ff3885975113fca02693620f36f8f20570bdaf581726053b6c982cb988a3091dc206624f9d36372b151b22c7dc2cb71b9aaed95dc5630c4c4b045f80c403836cc9c84951fc04b8d6e413e1d4f6b3815508f43cf80c25c7db3882b5b6572f1395a00dcda7fe65ce2155f9ea2cfe13588e0fb10316e7dd978e1d89cffc06a5e722ec765315926d2ee9060d8f449ead31cbacea88a5251be3b518d23984530da9f930114e614b7ed30f748c7512bddca8604bb5310ed76b9982eb88acaf49a29325e9db6987c6dea3878e2cb7daf3800177579ddcaafeacdba8edd147fae61bae36ab83a98db69a6c92017b3db8cff68985db989a03ee1bd045e6a577151486cdaeaf26517027b2f140b8493e2f401ea222511c2ce61c7057d64e8c3568e3f547f4b2875db59bc8c4f3346e0faf54e30745f583494b59e570bacb2b9eb71eb834e57f68aadda9af4bdb03276f71770c611aad0278033bb8c108471c4f4a2aa9070774367b9334661daf8a5e3eaf3d8dcca723d64ae7264c8709987a6cee9f42287b6e20d1d753262ff74886f3995412e59d09c61e4c637b6e97e6a3b08f9fa6adf9a1ec44a0372e893febd6712decc00bbd9cdacaf6bb9302fe8bd2ca27fdf5156c33582d56781ab0e5bd14da4b1edd73edd8f2a034a56d1a6f836724b605657f4714d59d522805e0ab02c6c5daed0973f93120ae01623ce0a96fbdf4402ce20ebb4f97fabbc90da5bb12aac3cd5f15c1add2d3863be59e843dca564ce9aa25b43ca1044b1e7e65d03d1f55f77d2a39cd85536ff38058837a23743c4e252f7de5654a562506b55d2b8fa29c7f4ecd307a8ae686cbb73fea6a8f72775d9e417ec346415024263a9f339dda286b682ccc8f93f7d4f59921620dd276188441fd44fc63925d18caa30a75c79c37a2ea45d14f6e423d2146281f9c6699a0658e50d69cfbc174090a0420bbb6f4e6b5b1f2b81b26f035aaf5c2e558c812496cb494587c78bf75350fb1a36e8c88076b4684094e0cba5dcdc4f672dbd2b432306b75077ae07b8fd88ba5b829eaed3fd2959a09b162329b75ac8fc20d4eea6e5971f54b31a23952dd4c111765822182cd60ee0de3cce3752c648918e3ec4c52643223132dcc885140faf8108230ebf4ef4149cbfa3070c91ec013404c15c1cecaa1efd544ab8313d378ef0e77c615b76b8ec07769960873ce9c7bdb1d75e7faef4c8a0b015c95a4e2bcd9ff7f5dfddd9a243fc0688db09e534ef1f3ebebd0c73b75bd57b8e02667da5744b1400dc695d4ae1e255d3487d1dead115de7d48962a15c7aecb97444173c40c028a46a7cfdd8cc7421f71d757cb809341c5148aedeab16f9289bc55b7475d646ae4993ab36fe5609a05121d140d4390289c94e4d87fd902fe03c8bfa13e7cfc9c21355ab6461d214137e4d90dff4a8f599020f12d7560fa4b5aaee1727f21c873fde76415b65357ecb923a547ddcdb20dde0880a287ed26d5ea4ce45514b907e368527c62e39ffdf2efeb817cd59694d23bafd48862e723f45e3c258cff3c804c5d2f17e24be8fe81a00f11f519beb9cde7be95226ac2a7f11e0f4f09dc040c11e1bf63172aa0f8a*1*254*2*3*8*0000000000000000*0*a11df265e4e54bee diff --git a/tools/refdata/m17040/ref1-cast5.txt b/tools/refdata/m17040/ref1-cast5.txt new file mode 100644 index 000000000..f30ae1eed --- /dev/null +++ b/tools/refdata/m17040/ref1-cast5.txt @@ -0,0 +1 @@ +Hashcat1! diff --git a/tools/refdata/m17040/ref2-cast5.hash b/tools/refdata/m17040/ref2-cast5.hash new file mode 100644 index 000000000..c84a3f2f7 --- /dev/null +++ b/tools/refdata/m17040/ref2-cast5.hash @@ -0,0 +1 @@ +$gpg$*1*1308*4096*b9bb392ab1b52997984826fd57c60ff16469f7e3a2bedf44e735e1426d5ad3aa43ce6adcd1f6d28e4357f31660fdd232c884653183cbe824bfe7364b2931f9b2028f93d00867c92dd77108dd4e65085944d08f2111f51308e26926d7d555580db59dc1874dc0611db82216e5788e0cb7cbd07f59fba91d36b3f1123d7be110301a59865bb318df5f8028858ca81e70bb85dd580130665f17a53cab073ffced08677f0dc7f6f8c49eb0ff2e828e0da97219fc09d1db45734834a57c6e19fac198938447153911df1dde314681c0caf368b91f2f9442eeda043765a70967e9da618d2cca7fd5d53a0d24a27652702a7924f4773a84d1d04bbc4d5d839235efa15933ac8c7652b28b9c84ac5f096a7ff32d7ccf791b514f1066daab43736807295f6814fde8f4956b3eeb302b6831bce1864af67a90a319bf2693de58e4834e11179246192750a09909ab9254314324069a498154245d72a9d0ca9c48f84b2ff4ac8ed7b4abb6ce5c4277722faaf7c74e9f00a5e7b518c637624df7c2261629850b0a7a673f325d9c3dd0243c1d966ab69ef1780c620f0d0da3315111b4ef07efa68b63779d4f4dbf625508ff176a4d7ce1e65384b6b781808dae43e9ae2b7a2bbcb80b854e0f154503f3600b7a1c4114bb0fcbc78c9f85d44e766cf729debebf6e8e221b1ba16f96a2f3540ec2723c522080599202160c14b17d587cdfffa29b691966a48cce551de7a97830c79de76fa46515159a8b78436b85b22985066827cc4b04e867e9a33c50cd8adafe8706b7cd06670ff8fc4e2bf853cd4cd78f050a722e45958eec6885fb0b9dc900357bfa47519f9bf28828c0899166656722e63eb877b00de244aea1badfcd92584153a6b6acb4d5a45a8c745718b4d439bf51792f7e3945042d8e199fcff6cdb4a8247565013e2b544611cf897cb14517eda73459f2879e2727cbedb7c3853e2c0f8fe5864fe19069019666bb9292689bd90edcb2839b8fe7e923036049657175f3ec37466024cd5c084c2454da962a908ae48ca2fcd0b2a03b246f53e1f1acf1229cd4ee62e4bcb64f9f545b4feb21c28f4f3244b974975ee61e2bb5216c1cb9bf9416cf19cc28ef61d32908c178e19927d8edefdf241b0773085eab933d2f57644426f7e1b46b6beafab98fe9099fb5e7fbe7aac3a521e7491cc0321ee9bc2b5b4a6aa1fd6ede05a6a35b33c9fff2668ce90a1b4d66d82f6da127be1097f9f686670d143cbd71766550d7fff099f39ced941237d8f71bb9289e96bf9b100b8ee361db30956550da1834e3cf1f1c70dc0c79bc35758596664448c43a8993beab7b08f69c9350601aa2d6b9ae576b4882af869135e49cc97cdc0cbb82ec62e77a3297e61efb661813d258d8e723a97058d41715187aa6c97bbe6046230a5414a3923f2380c6d10ccaab328ef93309c951b4c7e474b9662ae766b491c2705c5fa115e651e307a0b7d2b0411b949e1153b1d8e32580594a78e746cb00011677736d4a6830f450ebaec16653ea0cc20dcb29fdcd6b79f5b9cf50794dd40908dc2a509a64f6f32779d9b52fca2693d9d2bb787217df0135429fad20f102d4f44271f4c4e9a786a7304c894498fcac18afe3ef299de712263167427353fcb70a1c6fd9a649b71fb67a90b9395cba095d2bdad7f0b59710fd580dcfc3256ce98da04145bd4e887c3a859f48b7eda9954c445844bf26017b919c0423ed2f2cecbbe7e7eba02cc0ef51a5e74e846d6fe5e23ac42ef58b77354cc0ae8f101262fe9b97d17b17a1cca4e766ebce7c0e15f89f2dd3eca4a87951df9bd24db7807706e141a72c4a447fa81b9a18987b29b7856352aedc*1*254*2*3*8*0000000000000000*0*562609e55571bac3 diff --git a/tools/refdata/m17040/ref2-cast5.txt b/tools/refdata/m17040/ref2-cast5.txt new file mode 100644 index 000000000..98f9b1685 --- /dev/null +++ b/tools/refdata/m17040/ref2-cast5.txt @@ -0,0 +1 @@ +Test123! From 5927fea637a97d353f77f8367533509d3c859da7 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 30 Jun 2023 10:34:41 +0200 Subject: [PATCH 4/4] make it work with Apple Metal --- OpenCL/inc_cipher_cast.h | 24 ++++++++++++------------ OpenCL/m17040-pure.cl | 8 ++++---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/OpenCL/inc_cipher_cast.h b/OpenCL/inc_cipher_cast.h index 62bb2bb6a..6cbe8a82e 100644 --- a/OpenCL/inc_cipher_cast.h +++ b/OpenCL/inc_cipher_cast.h @@ -25,17 +25,17 @@ } #define PUT_UINT32BE(n, b, i) \ { \ - (b)[(i) ] = (uchar) ((n) >> 24); \ - (b)[(i) + 1] = (uchar) ((n) >> 16); \ - (b)[(i) + 2] = (uchar) ((n) >> 8); \ - (b)[(i) + 3] = (uchar) ((n) ); \ + (b)[(i) ] = (u8) ((n) >> 24); \ + (b)[(i) + 1] = (u8) ((n) >> 16); \ + (b)[(i) + 2] = (u8) ((n) >> 8); \ + (b)[(i) + 3] = (u8) ((n) ); \ } typedef struct { uint K[32]; } CAST_KEY; -#define GETBYTE(x, y) (uint)(uchar)((x)>>(8*(y))) +#define GETBYTE(x, y) (uint)(u8)((x)>>(8*(y))) /* Macros to access 8-bit bytes out of a 32-bit word */ #define U8a(x) GETBYTE(x,3) @@ -600,11 +600,11 @@ CONSTANT_AS uint S[8][256] = { #define _CAST_F2(l, r, i, j) _CAST_f2(l, r, K[i], K[i+j]) #define _CAST_F3(l, r, i, j) _CAST_f3(l, r, K[i], K[i+j]) -inline void Cast5Encrypt(const uchar *inBlock, uchar *outBlock, CAST_KEY *key) +inline void Cast5Encrypt(PRIVATE_AS const u8 *inBlock, PRIVATE_AS u8 *outBlock, PRIVATE_AS CAST_KEY *key) { uint l; GET_UINT32BE(l, inBlock, 0); uint r; GET_UINT32BE(r, inBlock, 4); - uint *K = key->K; + PRIVATE_AS uint *K = key->K; uint t; /* Do the work */ @@ -630,11 +630,11 @@ inline void Cast5Encrypt(const uchar *inBlock, uchar *outBlock, CAST_KEY *key) PUT_UINT32BE(l, outBlock, 4); } -inline void Cast5Decrypt(const uchar *inBlock, uchar *outBlock, CAST_KEY *key) +inline void Cast5Decrypt(PRIVATE_AS const u8 *inBlock, PRIVATE_AS u8 *outBlock, PRIVATE_AS CAST_KEY *key) { uint l; GET_UINT32BE(l, inBlock, 0); uint r; GET_UINT32BE(r, inBlock, 4); - uint *K = key->K; + PRIVATE_AS uint *K = key->K; uint t; /* Only do full 16 rounds if key length > 80 bits */ @@ -661,10 +661,10 @@ inline void Cast5Decrypt(const uchar *inBlock, uchar *outBlock, CAST_KEY *key) t = l = r = 0; } -inline void Cast5SetKey(CAST_KEY *key, uint keylength, const uchar *userKey) +inline void Cast5SetKey(PRIVATE_AS CAST_KEY *key, uint keylength, PRIVATE_AS const u8 *userKey) { uint i; - uint *K = key->K; + PRIVATE_AS uint *K = key->K; uint X[4], Z[4]; GET_UINT32BE(X[0], userKey, 0); @@ -727,4 +727,4 @@ inline void Cast5SetKey(CAST_KEY *key, uint keylength, const uchar *userKey) #define CAST_ecb_decrypt(in, out, ckey) Cast5Decrypt(in, out, ckey) -#endif /* _OPENCL_CAST_H */ \ No newline at end of file +#endif /* _OPENCL_CAST_H */ diff --git a/OpenCL/m17040-pure.cl b/OpenCL/m17040-pure.cl index f07f67acd..a39904bd7 100644 --- a/OpenCL/m17040-pure.cl +++ b/OpenCL/m17040-pure.cl @@ -132,9 +132,9 @@ DECLSPEC void cast128_decrypt_cfb (GLOBAL_AS const u32 *encrypted_data, int data lencrypted_data[i + 2] = encrypted_data[i + 2]; lencrypted_data[i + 3] = encrypted_data[i + 3]; } - u8 *lencrypted_data8 = (u8*)lencrypted_data; - u8 *decrypted_data8 = (u8*)decrypted_data; - u8 *key8 = (u8*)key; + PRIVATE_AS u8 *lencrypted_data8 = (PRIVATE_AS u8*)lencrypted_data; + PRIVATE_AS u8 *decrypted_data8 = (PRIVATE_AS u8*)decrypted_data; + PRIVATE_AS u8 *key8 = (PRIVATE_AS u8*)key; // Copy the IV, since this will be modified @@ -373,4 +373,4 @@ KERNEL_FQ void m17040_aux1 (KERN_ATTR_TMPS_ESALT (gpg_tmp_t, gpg_t)) mark_hash (plains_buf, d_return_buf, SALT_POS_HOST, DIGESTS_CNT, 0, DIGESTS_OFFSET_HOST + 0, gid, 0, 0, 0); } } -} \ No newline at end of file +}