diff --git a/OpenCL/m18100_a0-pure.cl b/OpenCL/m18100_a0-pure.cl index 9c8f047a9..396d896bc 100644 --- a/OpenCL/m18100_a0-pure.cl +++ b/OpenCL/m18100_a0-pure.cl @@ -16,6 +16,47 @@ #include M2S(INCLUDE_PATH/inc_hash_sha1.cl) #endif +DECLSPEC void _totp_calculate (PRIVATE_AS u32 *code, PRIVATE_AS const u32 *w, const u32 pw_len, PRIVATE_AS const u32 *s, const u32 salt_len) +{ + sha1_hmac_ctx_t ctx; + + sha1_hmac_init_swap (&ctx, w, pw_len); + + sha1_hmac_update (&ctx, s, salt_len); + + sha1_hmac_final (&ctx); + + // initialize a buffer for the otp code + u32 otp_code = 0; + + // grab 4 consecutive bytes of the hash, starting at offset + switch (ctx.opad.h[4] & 15) + { + case 0: otp_code = ctx.opad.h[0]; break; + case 1: otp_code = ctx.opad.h[0] << 8 | ctx.opad.h[1] >> 24; break; + case 2: otp_code = ctx.opad.h[0] << 16 | ctx.opad.h[1] >> 16; break; + case 3: otp_code = ctx.opad.h[0] << 24 | ctx.opad.h[1] >> 8; break; + case 4: otp_code = ctx.opad.h[1]; break; + case 5: otp_code = ctx.opad.h[1] << 8 | ctx.opad.h[2] >> 24; break; + case 6: otp_code = ctx.opad.h[1] << 16 | ctx.opad.h[2] >> 16; break; + case 7: otp_code = ctx.opad.h[1] << 24 | ctx.opad.h[2] >> 8; break; + case 8: otp_code = ctx.opad.h[2]; break; + case 9: otp_code = ctx.opad.h[2] << 8 | ctx.opad.h[3] >> 24; break; + case 10: otp_code = ctx.opad.h[2] << 16 | ctx.opad.h[3] >> 16; break; + case 11: otp_code = ctx.opad.h[2] << 24 | ctx.opad.h[3] >> 8; break; + case 12: otp_code = ctx.opad.h[3]; break; + case 13: otp_code = ctx.opad.h[3] << 8 | ctx.opad.h[4] >> 24; break; + case 14: otp_code = ctx.opad.h[3] << 16 | ctx.opad.h[4] >> 16; break; + case 15: otp_code = ctx.opad.h[3] << 24 | ctx.opad.h[4] >> 8; break; + } + + // take only the lower 31 bits + otp_code &= 0x7fffffff; + + // we want to generate only 6 digits of code + *code = otp_code % 1000000; +} + KERNEL_FQ void m18100_mxx (KERN_ATTR_RULES ()) { /** @@ -33,63 +74,85 @@ KERNEL_FQ void m18100_mxx (KERN_ATTR_RULES ()) COPY_PW (pws[gid]); - const u32 salt_len = 8; + const u32 count = salt_bufs[SALT_POS_HOST].salt_len / 16; u32 s[64] = { 0 }; - for (u32 i = 0, idx = 0; i < salt_len; i += 4, idx += 1) + for (u32 i = 0; i < count; i += 1) { - s[idx] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[idx]); + s[16 * i + 0] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[4 * i + 0]); + s[16 * i + 1] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[4 * i + 1]); } /** * loop */ - for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) + if (count == 1) { - pw_t tmp = PASTE_PW; - - tmp.pw_len = apply_rules (rules_buf[il_pos].cmds, tmp.i, tmp.pw_len); - - sha1_hmac_ctx_t ctx; - - sha1_hmac_init_swap (&ctx, tmp.i, tmp.pw_len); - - sha1_hmac_update (&ctx, s, salt_len); - - sha1_hmac_final (&ctx); - - // initialize a buffer for the otp code - u32 otp_code = 0; - - // grab 4 consecutive bytes of the hash, starting at offset - switch (ctx.opad.h[4] & 15) + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) { - case 0: otp_code = ctx.opad.h[0]; break; - case 1: otp_code = ctx.opad.h[0] << 8 | ctx.opad.h[1] >> 24; break; - case 2: otp_code = ctx.opad.h[0] << 16 | ctx.opad.h[1] >> 16; break; - case 3: otp_code = ctx.opad.h[0] << 24 | ctx.opad.h[1] >> 8; break; - case 4: otp_code = ctx.opad.h[1]; break; - case 5: otp_code = ctx.opad.h[1] << 8 | ctx.opad.h[2] >> 24; break; - case 6: otp_code = ctx.opad.h[1] << 16 | ctx.opad.h[2] >> 16; break; - case 7: otp_code = ctx.opad.h[1] << 24 | ctx.opad.h[2] >> 8; break; - case 8: otp_code = ctx.opad.h[2]; break; - case 9: otp_code = ctx.opad.h[2] << 8 | ctx.opad.h[3] >> 24; break; - case 10: otp_code = ctx.opad.h[2] << 16 | ctx.opad.h[3] >> 16; break; - case 11: otp_code = ctx.opad.h[2] << 24 | ctx.opad.h[3] >> 8; break; - case 12: otp_code = ctx.opad.h[3]; break; - case 13: otp_code = ctx.opad.h[3] << 8 | ctx.opad.h[4] >> 24; break; - case 14: otp_code = ctx.opad.h[3] << 16 | ctx.opad.h[4] >> 16; break; - case 15: otp_code = ctx.opad.h[3] << 24 | ctx.opad.h[4] >> 8; break; + pw_t tmp = PASTE_PW; + + tmp.pw_len = apply_rules (rules_buf[il_pos].cmds, tmp.i, tmp.pw_len); + + u32 otp_code0; + + _totp_calculate (&otp_code0, tmp.i, tmp.pw_len, s, 8); + + COMPARE_M_SCALAR (otp_code0, 0, 0, 0); } + } + else if (count == 4) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) + { + pw_t tmp = PASTE_PW; - // take only the lower 31 bits - otp_code &= 0x7fffffff; - // we want to generate only 6 digits of code - otp_code %= 1000000; + tmp.pw_len = apply_rules (rules_buf[il_pos].cmds, tmp.i, tmp.pw_len); - COMPARE_M_SCALAR (otp_code, 0, 0, 0); + u32 otp_code0, otp_code1; + + _totp_calculate (&otp_code0, tmp.i, tmp.pw_len, s + 0, 8); + _totp_calculate (&otp_code1, tmp.i, tmp.pw_len, s + 16, 8); + + COMPARE_M_SCALAR (otp_code0, otp_code1, 0, 0); + } + } + else if (count == 4) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) + { + pw_t tmp = PASTE_PW; + + tmp.pw_len = apply_rules (rules_buf[il_pos].cmds, tmp.i, tmp.pw_len); + + u32 otp_code0, otp_code1, otp_code2; + + _totp_calculate (&otp_code0, tmp.i, tmp.pw_len, s + 0, 8); + _totp_calculate (&otp_code1, tmp.i, tmp.pw_len, s + 16, 8); + _totp_calculate (&otp_code2, tmp.i, tmp.pw_len, s + 32, 8); + + COMPARE_M_SCALAR (otp_code0, otp_code1, otp_code2, 0); + } + } + else if (count == 4) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) + { + pw_t tmp = PASTE_PW; + + tmp.pw_len = apply_rules (rules_buf[il_pos].cmds, tmp.i, tmp.pw_len); + + u32 otp_code0, otp_code1, otp_code2, otp_code3; + + _totp_calculate (&otp_code0, tmp.i, tmp.pw_len, s + 0, 8); + _totp_calculate (&otp_code1, tmp.i, tmp.pw_len, s + 16, 8); + _totp_calculate (&otp_code2, tmp.i, tmp.pw_len, s + 32, 8); + _totp_calculate (&otp_code3, tmp.i, tmp.pw_len, s + 48, 8); + + COMPARE_M_SCALAR (otp_code0, otp_code1, otp_code2, otp_code3); + } } } @@ -122,62 +185,108 @@ KERNEL_FQ void m18100_sxx (KERN_ATTR_RULES ()) COPY_PW (pws[gid]); - const u32 salt_len = 8; + const u32 count = salt_bufs[SALT_POS_HOST].salt_len / 16; u32 s[64] = { 0 }; - for (u32 i = 0, idx = 0; i < salt_len; i += 4, idx += 1) + for (u32 i = 0; i < count; i += 1) { - s[idx] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[idx]); + s[16 * i + 0] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[4 * i + 0]); + s[16 * i + 1] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[4 * i + 1]); } /** * loop */ - for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) + if (count == 1) { - pw_t tmp = PASTE_PW; - - tmp.pw_len = apply_rules (rules_buf[il_pos].cmds, tmp.i, tmp.pw_len); - - sha1_hmac_ctx_t ctx; - - sha1_hmac_init_swap (&ctx, tmp.i, tmp.pw_len); - - sha1_hmac_update (&ctx, s, salt_len); - - sha1_hmac_final (&ctx); - - // initialize a buffer for the otp code - u32 otp_code = 0; - - // grab 4 consecutive bytes of the hash, starting at offset - switch (ctx.opad.h[4] & 15) + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) { - case 0: otp_code = ctx.opad.h[0]; break; - case 1: otp_code = ctx.opad.h[0] << 8 | ctx.opad.h[1] >> 24; break; - case 2: otp_code = ctx.opad.h[0] << 16 | ctx.opad.h[1] >> 16; break; - case 3: otp_code = ctx.opad.h[0] << 24 | ctx.opad.h[1] >> 8; break; - case 4: otp_code = ctx.opad.h[1]; break; - case 5: otp_code = ctx.opad.h[1] << 8 | ctx.opad.h[2] >> 24; break; - case 6: otp_code = ctx.opad.h[1] << 16 | ctx.opad.h[2] >> 16; break; - case 7: otp_code = ctx.opad.h[1] << 24 | ctx.opad.h[2] >> 8; break; - case 8: otp_code = ctx.opad.h[2]; break; - case 9: otp_code = ctx.opad.h[2] << 8 | ctx.opad.h[3] >> 24; break; - case 10: otp_code = ctx.opad.h[2] << 16 | ctx.opad.h[3] >> 16; break; - case 11: otp_code = ctx.opad.h[2] << 24 | ctx.opad.h[3] >> 8; break; - case 12: otp_code = ctx.opad.h[3]; break; - case 13: otp_code = ctx.opad.h[3] << 8 | ctx.opad.h[4] >> 24; break; - case 14: otp_code = ctx.opad.h[3] << 16 | ctx.opad.h[4] >> 16; break; - case 15: otp_code = ctx.opad.h[3] << 24 | ctx.opad.h[4] >> 8; break; + pw_t tmp = PASTE_PW; + + tmp.pw_len = apply_rules (rules_buf[il_pos].cmds, tmp.i, tmp.pw_len); + + u32 otp_code0; + + _totp_calculate (&otp_code0, tmp.i, tmp.pw_len, s, 8); + + COMPARE_S_SCALAR (otp_code0, 0, 0, 0); } + } + else if (count == 2) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) + { + pw_t tmp = PASTE_PW; - // take only the lower 31 bits - otp_code &= 0x7fffffff; - // we want to generate only 6 digits of code - otp_code %= 1000000; + tmp.pw_len = apply_rules (rules_buf[il_pos].cmds, tmp.i, tmp.pw_len); - COMPARE_S_SCALAR (otp_code, 0, 0, 0); + u32 otp_code0, otp_code1; + + _totp_calculate (&otp_code0, tmp.i, tmp.pw_len, s, 8); + + if (otp_code0 == search[0]) + { + _totp_calculate (&otp_code1, tmp.i, tmp.pw_len, s + 16, 8); + + COMPARE_S_SCALAR (otp_code0, otp_code1, 0, 0); + } + } + } + else if (count == 3) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) + { + pw_t tmp = PASTE_PW; + + tmp.pw_len = apply_rules (rules_buf[il_pos].cmds, tmp.i, tmp.pw_len); + + u32 otp_code0, otp_code1, otp_code2; + + _totp_calculate (&otp_code0, tmp.i, tmp.pw_len, s, 8); + + if (otp_code0 == search[0]) + { + _totp_calculate (&otp_code1, tmp.i, tmp.pw_len, s + 16, 8); + + if (otp_code1 == search[1]) + { + _totp_calculate (&otp_code2, tmp.i, tmp.pw_len, s + 32, 8); + + COMPARE_S_SCALAR (otp_code0, otp_code1, otp_code2, 0); + } + } + } + } + else if (count == 4) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) + { + pw_t tmp = PASTE_PW; + + tmp.pw_len = apply_rules (rules_buf[il_pos].cmds, tmp.i, tmp.pw_len); + + u32 otp_code0, otp_code1, otp_code2, otp_code3; + + _totp_calculate (&otp_code0, tmp.i, tmp.pw_len, s, 8); + + if (otp_code0 == search[0]) + { + _totp_calculate (&otp_code1, tmp.i, tmp.pw_len, s + 16, 8); + + if (otp_code1 == search[1]) + { + _totp_calculate (&otp_code2, tmp.i, tmp.pw_len, s + 32, 8); + + if (otp_code2 == search[2]) + { + _totp_calculate (&otp_code3, tmp.i, tmp.pw_len, s + 48, 8); + + COMPARE_S_SCALAR (otp_code0, otp_code1, otp_code2, otp_code3); + } + } + } + } } } diff --git a/OpenCL/m18100_a1-pure.cl b/OpenCL/m18100_a1-pure.cl index a596894ca..4eefd1fdc 100644 --- a/OpenCL/m18100_a1-pure.cl +++ b/OpenCL/m18100_a1-pure.cl @@ -14,6 +14,47 @@ #include M2S(INCLUDE_PATH/inc_hash_sha1.cl) #endif +DECLSPEC void _totp_calculate (PRIVATE_AS u32 *code, PRIVATE_AS const u32 *w, const u32 pw_len, PRIVATE_AS const u32 *s, const u32 salt_len) +{ + sha1_hmac_ctx_t ctx; + + sha1_hmac_init (&ctx, w, pw_len); + + sha1_hmac_update (&ctx, s, salt_len); + + sha1_hmac_final (&ctx); + + // initialize a buffer for the otp code + u32 otp_code = 0; + + // grab 4 consecutive bytes of the hash, starting at offset + switch (ctx.opad.h[4] & 15) + { + case 0: otp_code = ctx.opad.h[0]; break; + case 1: otp_code = ctx.opad.h[0] << 8 | ctx.opad.h[1] >> 24; break; + case 2: otp_code = ctx.opad.h[0] << 16 | ctx.opad.h[1] >> 16; break; + case 3: otp_code = ctx.opad.h[0] << 24 | ctx.opad.h[1] >> 8; break; + case 4: otp_code = ctx.opad.h[1]; break; + case 5: otp_code = ctx.opad.h[1] << 8 | ctx.opad.h[2] >> 24; break; + case 6: otp_code = ctx.opad.h[1] << 16 | ctx.opad.h[2] >> 16; break; + case 7: otp_code = ctx.opad.h[1] << 24 | ctx.opad.h[2] >> 8; break; + case 8: otp_code = ctx.opad.h[2]; break; + case 9: otp_code = ctx.opad.h[2] << 8 | ctx.opad.h[3] >> 24; break; + case 10: otp_code = ctx.opad.h[2] << 16 | ctx.opad.h[3] >> 16; break; + case 11: otp_code = ctx.opad.h[2] << 24 | ctx.opad.h[3] >> 8; break; + case 12: otp_code = ctx.opad.h[3]; break; + case 13: otp_code = ctx.opad.h[3] << 8 | ctx.opad.h[4] >> 24; break; + case 14: otp_code = ctx.opad.h[3] << 16 | ctx.opad.h[4] >> 16; break; + case 15: otp_code = ctx.opad.h[3] << 24 | ctx.opad.h[4] >> 8; break; + } + + // take only the lower 31 bits + otp_code &= 0x7fffffff; + + // we want to generate only 6 digits of code + *code = otp_code % 1000000; +} + KERNEL_FQ void m18100_mxx (KERN_ATTR_BASIC ()) { /** @@ -38,81 +79,157 @@ KERNEL_FQ void m18100_mxx (KERN_ATTR_BASIC ()) w[idx] = hc_swap32_S (pws[gid].i[idx]); } - const u32 salt_len = 8; + const u32 count = salt_bufs[SALT_POS_HOST].salt_len / 16; u32 s[64] = { 0 }; - for (u32 i = 0, idx = 0; i < salt_len; i += 4, idx += 1) + for (u32 i = 0; i < count; i += 1) { - s[idx] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[idx]); + s[16 * i + 0] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[4 * i + 0]); + s[16 * i + 1] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[4 * i + 1]); } /** * loop */ - for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) + if (count == 1) { - const u32 comb_len = combs_buf[il_pos].pw_len; - - u32 c[64]; - - #ifdef _unroll - #pragma unroll - #endif - for (int idx = 0; idx < 64; idx++) + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) { - c[idx] = hc_swap32_S (combs_buf[il_pos].i[idx]); + const u32 comb_len = combs_buf[il_pos].pw_len; + + u32 c[64]; + + #ifdef _unroll + #pragma unroll + #endif + for (int idx = 0; idx < 64; idx++) + { + c[idx] = hc_swap32_S (combs_buf[il_pos].i[idx]); + } + + switch_buffer_by_offset_1x64_be_S (c, pw_len); + + #ifdef _unroll + #pragma unroll + #endif + for (int i = 0; i < 64; i++) + { + c[i] |= w[i]; + } + + u32 otp_code0; + + _totp_calculate (&otp_code0, c, pw_len + comb_len, s, 8); + + COMPARE_M_SCALAR (otp_code0, 0, 0, 0); } - - switch_buffer_by_offset_1x64_be_S (c, pw_len); - - #ifdef _unroll - #pragma unroll - #endif - for (int i = 0; i < 64; i++) + } + else if (count == 2) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) { - c[i] |= w[i]; + const u32 comb_len = combs_buf[il_pos].pw_len; + + u32 c[64]; + + #ifdef _unroll + #pragma unroll + #endif + for (int idx = 0; idx < 64; idx++) + { + c[idx] = hc_swap32_S (combs_buf[il_pos].i[idx]); + } + + switch_buffer_by_offset_1x64_be_S (c, pw_len); + + #ifdef _unroll + #pragma unroll + #endif + for (int i = 0; i < 64; i++) + { + c[i] |= w[i]; + } + + u32 otp_code0, otp_code1; + + _totp_calculate (&otp_code0, c, pw_len + comb_len, s + 0, 8); + _totp_calculate (&otp_code1, c, pw_len + comb_len, s + 16, 8); + + COMPARE_M_SCALAR (otp_code0, otp_code1, 0, 0); } - - sha1_hmac_ctx_t ctx; - - sha1_hmac_init (&ctx, c, pw_len + comb_len); - - sha1_hmac_update (&ctx, s, salt_len); - - sha1_hmac_final (&ctx); - - // initialize a buffer for the otp code - u32 otp_code = 0; - - // grab 4 consecutive bytes of the hash, starting at offset - switch (ctx.opad.h[4] & 15) + } + else if (count == 3) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) { - case 0: otp_code = ctx.opad.h[0]; break; - case 1: otp_code = ctx.opad.h[0] << 8 | ctx.opad.h[1] >> 24; break; - case 2: otp_code = ctx.opad.h[0] << 16 | ctx.opad.h[1] >> 16; break; - case 3: otp_code = ctx.opad.h[0] << 24 | ctx.opad.h[1] >> 8; break; - case 4: otp_code = ctx.opad.h[1]; break; - case 5: otp_code = ctx.opad.h[1] << 8 | ctx.opad.h[2] >> 24; break; - case 6: otp_code = ctx.opad.h[1] << 16 | ctx.opad.h[2] >> 16; break; - case 7: otp_code = ctx.opad.h[1] << 24 | ctx.opad.h[2] >> 8; break; - case 8: otp_code = ctx.opad.h[2]; break; - case 9: otp_code = ctx.opad.h[2] << 8 | ctx.opad.h[3] >> 24; break; - case 10: otp_code = ctx.opad.h[2] << 16 | ctx.opad.h[3] >> 16; break; - case 11: otp_code = ctx.opad.h[2] << 24 | ctx.opad.h[3] >> 8; break; - case 12: otp_code = ctx.opad.h[3]; break; - case 13: otp_code = ctx.opad.h[3] << 8 | ctx.opad.h[4] >> 24; break; - case 14: otp_code = ctx.opad.h[3] << 16 | ctx.opad.h[4] >> 16; break; - case 15: otp_code = ctx.opad.h[3] << 24 | ctx.opad.h[4] >> 8; break; + const u32 comb_len = combs_buf[il_pos].pw_len; + + u32 c[64]; + + #ifdef _unroll + #pragma unroll + #endif + for (int idx = 0; idx < 64; idx++) + { + c[idx] = hc_swap32_S (combs_buf[il_pos].i[idx]); + } + + switch_buffer_by_offset_1x64_be_S (c, pw_len); + + #ifdef _unroll + #pragma unroll + #endif + for (int i = 0; i < 64; i++) + { + c[i] |= w[i]; + } + + u32 otp_code0, otp_code1, otp_code2; + + _totp_calculate (&otp_code0, c, pw_len + comb_len, s + 0, 8); + _totp_calculate (&otp_code1, c, pw_len + comb_len, s + 16, 8); + _totp_calculate (&otp_code2, c, pw_len + comb_len, s + 32, 8); + + COMPARE_M_SCALAR (otp_code0, otp_code1, otp_code2, 0); } + } + else if (count == 4) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) + { + const u32 comb_len = combs_buf[il_pos].pw_len; - // take only the lower 31 bits - otp_code &= 0x7fffffff; - // we want to generate only 6 digits of code - otp_code %= 1000000; + u32 c[64]; - COMPARE_M_SCALAR (otp_code, 0, 0, 0); + #ifdef _unroll + #pragma unroll + #endif + for (int idx = 0; idx < 64; idx++) + { + c[idx] = hc_swap32_S (combs_buf[il_pos].i[idx]); + } + + switch_buffer_by_offset_1x64_be_S (c, pw_len); + + #ifdef _unroll + #pragma unroll + #endif + for (int i = 0; i < 64; i++) + { + c[i] |= w[i]; + } + + u32 otp_code0, otp_code1, otp_code2, otp_code3; + + _totp_calculate (&otp_code0, c, pw_len + comb_len, s + 0, 8); + _totp_calculate (&otp_code1, c, pw_len + comb_len, s + 16, 8); + _totp_calculate (&otp_code2, c, pw_len + comb_len, s + 32, 8); + _totp_calculate (&otp_code3, c, pw_len + comb_len, s + 48, 8); + + COMPARE_M_SCALAR (otp_code0, otp_code1, otp_code2, otp_code3); + } } } @@ -152,80 +269,180 @@ KERNEL_FQ void m18100_sxx (KERN_ATTR_BASIC ()) w[idx] = hc_swap32_S (pws[gid].i[idx]); } - const u32 salt_len = 8; + const u32 count = salt_bufs[SALT_POS_HOST].salt_len / 16; u32 s[64] = { 0 }; - for (u32 i = 0, idx = 0; i < salt_len; i += 4, idx += 1) + for (u32 i = 0; i < count; i += 1) { - s[idx] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[idx]); + s[16 * i + 0] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[4 * i + 0]); + s[16 * i + 1] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[4 * i + 1]); } /** * loop */ - for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) + if (count == 1) { - const u32 comb_len = combs_buf[il_pos].pw_len; - - u32 c[64]; - - #ifdef _unroll - #pragma unroll - #endif - for (int idx = 0; idx < 64; idx++) + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) { - c[idx] = hc_swap32_S (combs_buf[il_pos].i[idx]); + const u32 comb_len = combs_buf[il_pos].pw_len; + + u32 c[64]; + + #ifdef _unroll + #pragma unroll + #endif + for (int idx = 0; idx < 64; idx++) + { + c[idx] = hc_swap32_S (combs_buf[il_pos].i[idx]); + } + + switch_buffer_by_offset_1x64_be_S (c, pw_len); + + #ifdef _unroll + #pragma unroll + #endif + for (int i = 0; i < 64; i++) + { + c[i] |= w[i]; + } + + u32 otp_code0; + + _totp_calculate (&otp_code0, c, pw_len + comb_len, s, 8); + + COMPARE_S_SCALAR (otp_code0, 0, 0, 0); } - - switch_buffer_by_offset_1x64_be_S (c, pw_len); - - #ifdef _unroll - #pragma unroll - #endif - for (int i = 0; i < 64; i++) + } + else if (count == 2) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) { - c[i] |= w[i]; + const u32 comb_len = combs_buf[il_pos].pw_len; + + u32 c[64]; + + #ifdef _unroll + #pragma unroll + #endif + for (int idx = 0; idx < 64; idx++) + { + c[idx] = hc_swap32_S (combs_buf[il_pos].i[idx]); + } + + switch_buffer_by_offset_1x64_be_S (c, pw_len); + + #ifdef _unroll + #pragma unroll + #endif + for (int i = 0; i < 64; i++) + { + c[i] |= w[i]; + } + + u32 otp_code0, otp_code1; + + _totp_calculate (&otp_code0, c, pw_len + comb_len, s, 8); + + if (otp_code0 == search[0]) + { + _totp_calculate (&otp_code1, c, pw_len + comb_len, s + 16, 8); + + COMPARE_S_SCALAR (otp_code0, otp_code1, 0, 0); + } } - - sha1_hmac_ctx_t ctx; - - sha1_hmac_init (&ctx, c, pw_len + comb_len); - - sha1_hmac_update (&ctx, s, salt_len); - - sha1_hmac_final (&ctx); - - // initialize a buffer for the otp code - u32 otp_code = 0; - - // grab 4 consecutive bytes of the hash, starting at offset - switch (ctx.opad.h[4] & 15) + } + else if (count == 3) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) { - case 0: otp_code = ctx.opad.h[0]; break; - case 1: otp_code = ctx.opad.h[0] << 8 | ctx.opad.h[1] >> 24; break; - case 2: otp_code = ctx.opad.h[0] << 16 | ctx.opad.h[1] >> 16; break; - case 3: otp_code = ctx.opad.h[0] << 24 | ctx.opad.h[1] >> 8; break; - case 4: otp_code = ctx.opad.h[1]; break; - case 5: otp_code = ctx.opad.h[1] << 8 | ctx.opad.h[2] >> 24; break; - case 6: otp_code = ctx.opad.h[1] << 16 | ctx.opad.h[2] >> 16; break; - case 7: otp_code = ctx.opad.h[1] << 24 | ctx.opad.h[2] >> 8; break; - case 8: otp_code = ctx.opad.h[2]; break; - case 9: otp_code = ctx.opad.h[2] << 8 | ctx.opad.h[3] >> 24; break; - case 10: otp_code = ctx.opad.h[2] << 16 | ctx.opad.h[3] >> 16; break; - case 11: otp_code = ctx.opad.h[2] << 24 | ctx.opad.h[3] >> 8; break; - case 12: otp_code = ctx.opad.h[3]; break; - case 13: otp_code = ctx.opad.h[3] << 8 | ctx.opad.h[4] >> 24; break; - case 14: otp_code = ctx.opad.h[3] << 16 | ctx.opad.h[4] >> 16; break; - case 15: otp_code = ctx.opad.h[3] << 24 | ctx.opad.h[4] >> 8; break; + const u32 comb_len = combs_buf[il_pos].pw_len; + + u32 c[64]; + + #ifdef _unroll + #pragma unroll + #endif + for (int idx = 0; idx < 64; idx++) + { + c[idx] = hc_swap32_S (combs_buf[il_pos].i[idx]); + } + + switch_buffer_by_offset_1x64_be_S (c, pw_len); + + #ifdef _unroll + #pragma unroll + #endif + for (int i = 0; i < 64; i++) + { + c[i] |= w[i]; + } + + u32 otp_code0, otp_code1, otp_code2; + + _totp_calculate (&otp_code0, c, pw_len + comb_len, s, 8); + + if (otp_code0 == search[0]) + { + _totp_calculate (&otp_code1, c, pw_len + comb_len, s + 16, 8); + + if (otp_code1 == search[1]) + { + _totp_calculate (&otp_code2, c, pw_len + comb_len, s + 32, 8); + + COMPARE_S_SCALAR (otp_code0, otp_code1, otp_code2, 0); + } + } } + } + else if (count == 4) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos++) + { + const u32 comb_len = combs_buf[il_pos].pw_len; - // take only the lower 31 bits - otp_code &= 0x7fffffff; - // we want to generate only 6 digits of code - otp_code %= 1000000; + u32 c[64]; - COMPARE_S_SCALAR (otp_code, 0, 0, 0); + #ifdef _unroll + #pragma unroll + #endif + for (int idx = 0; idx < 64; idx++) + { + c[idx] = hc_swap32_S (combs_buf[il_pos].i[idx]); + } + + switch_buffer_by_offset_1x64_be_S (c, pw_len); + + #ifdef _unroll + #pragma unroll + #endif + for (int i = 0; i < 64; i++) + { + c[i] |= w[i]; + } + + u32 otp_code0, otp_code1, otp_code2, otp_code3; + + _totp_calculate (&otp_code0, c, pw_len + comb_len, s, 8); + + if (otp_code0 == search[0]) + { + _totp_calculate (&otp_code1, c, pw_len + comb_len, s + 16, 8); + + if (otp_code1 == search[1]) + { + _totp_calculate (&otp_code2, c, pw_len + comb_len, s + 32, 8); + + if (otp_code2 == search[2]) + { + _totp_calculate (&otp_code3, c, pw_len + comb_len, s + 48, 8); + + COMPARE_S_SCALAR (otp_code0, otp_code1, otp_code2, otp_code3); + } + } + } + } } } diff --git a/OpenCL/m18100_a3-pure.cl b/OpenCL/m18100_a3-pure.cl index 70235ce95..2dd68ffdf 100644 --- a/OpenCL/m18100_a3-pure.cl +++ b/OpenCL/m18100_a3-pure.cl @@ -1,205 +1,324 @@ -/** - * Author......: See docs/credits.txt - * 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_simd.cl) -#include M2S(INCLUDE_PATH/inc_hash_sha1.cl) -#endif - -KERNEL_FQ void m18100_mxx (KERN_ATTR_VECTOR ()) -{ - /** - * modifier - */ - - const u64 lid = get_local_id (0); - const u64 gid = get_global_id (0); - - if (gid >= GID_CNT) return; - - /** - * base - */ - - const u32 pw_len = pws[gid].pw_len; - - u32x w[64] = { 0 }; - - for (u32 i = 0, idx = 0; i < pw_len; i += 4, idx += 1) - { - w[idx] = pws[gid].i[idx]; - } - - const u32 salt_len = 8; - - u32x s[64] = { 0 }; - - for (u32 i = 0, idx = 0; i < salt_len; i += 4, idx += 1) - { - s[idx] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[idx]); - } - - /** - * loop - */ - - u32x w0l = w[0]; - - for (u32 il_pos = 0; il_pos < IL_CNT; il_pos += VECT_SIZE) - { - const u32x w0r = words_buf_r[il_pos / VECT_SIZE]; - - const u32x w0 = w0l | w0r; - - w[0] = w0; - - sha1_hmac_ctx_vector_t ctx; - - sha1_hmac_init_vector (&ctx, w, pw_len); - - sha1_hmac_update_vector (&ctx, s, salt_len); - - sha1_hmac_final_vector (&ctx); - - // initialize a buffer for the otp code - u32 otp_code = 0; - - // grab 4 consecutive bytes of the hash, starting at offset - switch (ctx.opad.h[4] & 15) - { - case 0: otp_code = ctx.opad.h[0]; break; - case 1: otp_code = ctx.opad.h[0] << 8 | ctx.opad.h[1] >> 24; break; - case 2: otp_code = ctx.opad.h[0] << 16 | ctx.opad.h[1] >> 16; break; - case 3: otp_code = ctx.opad.h[0] << 24 | ctx.opad.h[1] >> 8; break; - case 4: otp_code = ctx.opad.h[1]; break; - case 5: otp_code = ctx.opad.h[1] << 8 | ctx.opad.h[2] >> 24; break; - case 6: otp_code = ctx.opad.h[1] << 16 | ctx.opad.h[2] >> 16; break; - case 7: otp_code = ctx.opad.h[1] << 24 | ctx.opad.h[2] >> 8; break; - case 8: otp_code = ctx.opad.h[2]; break; - case 9: otp_code = ctx.opad.h[2] << 8 | ctx.opad.h[3] >> 24; break; - case 10: otp_code = ctx.opad.h[2] << 16 | ctx.opad.h[3] >> 16; break; - case 11: otp_code = ctx.opad.h[2] << 24 | ctx.opad.h[3] >> 8; break; - case 12: otp_code = ctx.opad.h[3]; break; - case 13: otp_code = ctx.opad.h[3] << 8 | ctx.opad.h[4] >> 24; break; - case 14: otp_code = ctx.opad.h[3] << 16 | ctx.opad.h[4] >> 16; break; - case 15: otp_code = ctx.opad.h[3] << 24 | ctx.opad.h[4] >> 8; break; - } - - // take only the lower 31 bits - otp_code &= 0x7fffffff; - - // we want to generate only 6 digits of code - otp_code %= 1000000; - - COMPARE_M_SIMD (otp_code, 0, 0, 0); - } -} - -KERNEL_FQ void m18100_sxx (KERN_ATTR_VECTOR ()) -{ - /** - * modifier - */ - - const u64 lid = get_local_id (0); - const u64 gid = get_global_id (0); - - if (gid >= GID_CNT) return; - - /** - * digest - */ - - const u32 search[4] = - { - digests_buf[DIGESTS_OFFSET_HOST].digest_buf[DGST_R0], - digests_buf[DIGESTS_OFFSET_HOST].digest_buf[DGST_R1], - digests_buf[DIGESTS_OFFSET_HOST].digest_buf[DGST_R2], - digests_buf[DIGESTS_OFFSET_HOST].digest_buf[DGST_R3] - }; - - /** - * base - */ - - const u32 pw_len = pws[gid].pw_len; - - u32x w[64] = { 0 }; - - for (u32 i = 0, idx = 0; i < pw_len; i += 4, idx += 1) - { - w[idx] = pws[gid].i[idx]; - } - - const u32 salt_len = 8; - - u32x s[64] = { 0 }; - - for (u32 i = 0, idx = 0; i < salt_len; i += 4, idx += 1) - { - s[idx] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[idx]); - } - - /** - * loop - */ - - u32x w0l = w[0]; - - for (u32 il_pos = 0; il_pos < IL_CNT; il_pos += VECT_SIZE) - { - const u32x w0r = words_buf_r[il_pos / VECT_SIZE]; - - const u32x w0 = w0l | w0r; - - w[0] = w0; - - sha1_hmac_ctx_vector_t ctx; - - sha1_hmac_init_vector (&ctx, w, pw_len); - - sha1_hmac_update_vector (&ctx, s, salt_len); - - sha1_hmac_final_vector (&ctx); - - // initialize a buffer for the otp code - u32 otp_code = 0; - - // grab 4 consecutive bytes of the hash, starting at offset - switch (ctx.opad.h[4] & 15) - { - case 0: otp_code = ctx.opad.h[0]; break; - case 1: otp_code = ctx.opad.h[0] << 8 | ctx.opad.h[1] >> 24; break; - case 2: otp_code = ctx.opad.h[0] << 16 | ctx.opad.h[1] >> 16; break; - case 3: otp_code = ctx.opad.h[0] << 24 | ctx.opad.h[1] >> 8; break; - case 4: otp_code = ctx.opad.h[1]; break; - case 5: otp_code = ctx.opad.h[1] << 8 | ctx.opad.h[2] >> 24; break; - case 6: otp_code = ctx.opad.h[1] << 16 | ctx.opad.h[2] >> 16; break; - case 7: otp_code = ctx.opad.h[1] << 24 | ctx.opad.h[2] >> 8; break; - case 8: otp_code = ctx.opad.h[2]; break; - case 9: otp_code = ctx.opad.h[2] << 8 | ctx.opad.h[3] >> 24; break; - case 10: otp_code = ctx.opad.h[2] << 16 | ctx.opad.h[3] >> 16; break; - case 11: otp_code = ctx.opad.h[2] << 24 | ctx.opad.h[3] >> 8; break; - case 12: otp_code = ctx.opad.h[3]; break; - case 13: otp_code = ctx.opad.h[3] << 8 | ctx.opad.h[4] >> 24; break; - case 14: otp_code = ctx.opad.h[3] << 16 | ctx.opad.h[4] >> 16; break; - case 15: otp_code = ctx.opad.h[3] << 24 | ctx.opad.h[4] >> 8; break; - } - - // take only the lower 31 bits - otp_code &= 0x7fffffff; - - // we want to generate only 6 digits of code - otp_code %= 1000000; - - COMPARE_S_SIMD (otp_code, 0, 0, 0); - } -} +/** + * Author......: See docs/credits.txt + * 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_simd.cl) +#include M2S(INCLUDE_PATH/inc_hash_sha1.cl) +#endif + +DECLSPEC void _totp_calculate (PRIVATE_AS u32x *code, PRIVATE_AS const u32x *w, const u32 pw_len, PRIVATE_AS const u32x *s, const u32 salt_len) +{ + sha1_hmac_ctx_vector_t ctx; + + sha1_hmac_init_vector (&ctx, w, pw_len); + + sha1_hmac_update_vector (&ctx, s, salt_len); + + sha1_hmac_final_vector (&ctx); + + // initialize a buffer for the otp code + u32x otp_code = 0; + + // grab 4 consecutive bytes of the hash, starting at offset + switch (ctx.opad.h[4] & 15) + { + case 0: otp_code = ctx.opad.h[0]; break; + case 1: otp_code = ctx.opad.h[0] << 8 | ctx.opad.h[1] >> 24; break; + case 2: otp_code = ctx.opad.h[0] << 16 | ctx.opad.h[1] >> 16; break; + case 3: otp_code = ctx.opad.h[0] << 24 | ctx.opad.h[1] >> 8; break; + case 4: otp_code = ctx.opad.h[1]; break; + case 5: otp_code = ctx.opad.h[1] << 8 | ctx.opad.h[2] >> 24; break; + case 6: otp_code = ctx.opad.h[1] << 16 | ctx.opad.h[2] >> 16; break; + case 7: otp_code = ctx.opad.h[1] << 24 | ctx.opad.h[2] >> 8; break; + case 8: otp_code = ctx.opad.h[2]; break; + case 9: otp_code = ctx.opad.h[2] << 8 | ctx.opad.h[3] >> 24; break; + case 10: otp_code = ctx.opad.h[2] << 16 | ctx.opad.h[3] >> 16; break; + case 11: otp_code = ctx.opad.h[2] << 24 | ctx.opad.h[3] >> 8; break; + case 12: otp_code = ctx.opad.h[3]; break; + case 13: otp_code = ctx.opad.h[3] << 8 | ctx.opad.h[4] >> 24; break; + case 14: otp_code = ctx.opad.h[3] << 16 | ctx.opad.h[4] >> 16; break; + case 15: otp_code = ctx.opad.h[3] << 24 | ctx.opad.h[4] >> 8; break; + } + + // take only the lower 31 bits + otp_code &= 0x7fffffff; + + // we want to generate only 6 digits of code + *code = otp_code % 1000000; +} + +KERNEL_FQ void m18100_mxx (KERN_ATTR_VECTOR ()) +{ + /** + * modifier + */ + + const u64 lid = get_local_id (0); + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + /** + * base + */ + + const u32 pw_len = pws[gid].pw_len; + + u32x w[64] = { 0 }; + + for (u32 i = 0, idx = 0; i < pw_len; i += 4, idx += 1) + { + w[idx] = pws[gid].i[idx]; + } + + const u32 count = salt_bufs[SALT_POS_HOST].salt_len / 16; + + u32x s[64] = { 0 }; + + for (u32 i = 0; i < count; i += 1) + { + s[16 * i + 0] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[4 * i + 0]); + s[16 * i + 1] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[4 * i + 1]); + } + + /** + * loop + */ + + u32x w0l = w[0]; + + if (count == 1) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos += VECT_SIZE) + { + const u32x w0r = words_buf_r[il_pos / VECT_SIZE]; + + const u32x w0 = w0l | w0r; + + w[0] = w0; + + u32x otp_code0; + + _totp_calculate (&otp_code0, w, pw_len, s, 8); + + COMPARE_M_SIMD (otp_code0, 0, 0, 0); + } + } + else if (count == 2) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos += VECT_SIZE) + { + const u32x w0r = words_buf_r[il_pos / VECT_SIZE]; + + const u32x w0 = w0l | w0r; + + w[0] = w0; + + u32x otp_code0, otp_code1; + + _totp_calculate (&otp_code0, w, pw_len, s + 0, 8); + _totp_calculate (&otp_code1, w, pw_len, s + 16, 8); + + COMPARE_M_SIMD (otp_code0, otp_code1, 0, 0); + } + } + else if (count == 3) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos += VECT_SIZE) + { + const u32x w0r = words_buf_r[il_pos / VECT_SIZE]; + + const u32x w0 = w0l | w0r; + + w[0] = w0; + + u32x otp_code0, otp_code1, otp_code2; + + _totp_calculate (&otp_code0, w, pw_len, s + 0, 8); + _totp_calculate (&otp_code1, w, pw_len, s + 16, 8); + _totp_calculate (&otp_code2, w, pw_len, s + 32, 8); + + COMPARE_M_SIMD (otp_code0, otp_code1, otp_code2, 0); + } + } + else if (count == 4) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos += VECT_SIZE) + { + const u32x w0r = words_buf_r[il_pos / VECT_SIZE]; + + const u32x w0 = w0l | w0r; + + w[0] = w0; + + u32x otp_code0, otp_code1, otp_code2, otp_code3; + + _totp_calculate (&otp_code0, w, pw_len, s + 0, 8); + _totp_calculate (&otp_code1, w, pw_len, s + 16, 8); + _totp_calculate (&otp_code2, w, pw_len, s + 32, 8); + _totp_calculate (&otp_code3, w, pw_len, s + 48, 8); + + COMPARE_M_SIMD (otp_code0, otp_code1, otp_code2, otp_code3); + } + } +} + +KERNEL_FQ void m18100_sxx (KERN_ATTR_VECTOR ()) +{ + /** + * modifier + */ + + const u64 lid = get_local_id (0); + const u64 gid = get_global_id (0); + + if (gid >= GID_CNT) return; + + /** + * digest + */ + + const u32 search[4] = + { + digests_buf[DIGESTS_OFFSET_HOST].digest_buf[DGST_R0], + digests_buf[DIGESTS_OFFSET_HOST].digest_buf[DGST_R1], + digests_buf[DIGESTS_OFFSET_HOST].digest_buf[DGST_R2], + digests_buf[DIGESTS_OFFSET_HOST].digest_buf[DGST_R3] + }; + + /** + * base + */ + + const u32 pw_len = pws[gid].pw_len; + + u32x w[64] = { 0 }; + + for (u32 i = 0, idx = 0; i < pw_len; i += 4, idx += 1) + { + w[idx] = pws[gid].i[idx]; + } + + const u32 count = salt_bufs[SALT_POS_HOST].salt_len / 16; + + u32x s[64] = { 0 }; + + for (u32 i = 0; i < count; i += 1) + { + s[16 * i + 0] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[4 * i + 0]); + s[16 * i + 1] = hc_swap32_S (salt_bufs[SALT_POS_HOST].salt_buf[4 * i + 1]); + } + + /** + * loop + */ + + u32x w0l = w[0]; + + if (count == 1) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos += VECT_SIZE) + { + const u32x w0r = words_buf_r[il_pos / VECT_SIZE]; + + const u32x w0 = w0l | w0r; + + w[0] = w0; + + u32x otp_code0; + + _totp_calculate (&otp_code0, w, pw_len, s, 8); + + COMPARE_S_SIMD (otp_code0, 0, 0, 0); + } + } + else if (count == 2) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos += VECT_SIZE) + { + const u32x w0r = words_buf_r[il_pos / VECT_SIZE]; + + const u32x w0 = w0l | w0r; + + w[0] = w0; + + u32x otp_code0, otp_code1; + + _totp_calculate (&otp_code0, w, pw_len, s, 8); + + if (MATCHES_ONE_VS(otp_code0, search[0])) + { + _totp_calculate (&otp_code1, w, pw_len, s + 16, 8); + + COMPARE_S_SIMD (otp_code0, otp_code1, 0, 0); + } + } + } + else if (count == 3) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos += VECT_SIZE) + { + const u32x w0r = words_buf_r[il_pos / VECT_SIZE]; + + const u32x w0 = w0l | w0r; + + w[0] = w0; + + u32x otp_code0, otp_code1, otp_code2; + + _totp_calculate (&otp_code0, w, pw_len, s, 8); + + if (MATCHES_ONE_VS(otp_code0, search[0])) + { + _totp_calculate (&otp_code1, w, pw_len, s + 16, 8); + + if (MATCHES_ONE_VS(otp_code1, search[1])) + { + _totp_calculate (&otp_code2, w, pw_len, s + 32, 8); + + COMPARE_S_SIMD (otp_code0, otp_code1, otp_code2, 0); + } + } + } + } + else if (count == 4) + { + for (u32 il_pos = 0; il_pos < IL_CNT; il_pos += VECT_SIZE) + { + const u32x w0r = words_buf_r[il_pos / VECT_SIZE]; + + const u32x w0 = w0l | w0r; + + w[0] = w0; + + u32x otp_code0, otp_code1, otp_code2, otp_code3; + + _totp_calculate (&otp_code0, w, pw_len, s, 8); + + if (MATCHES_ONE_VS(otp_code0, search[0])) + { + _totp_calculate (&otp_code1, w, pw_len, s + 16, 8); + + if (MATCHES_ONE_VS(otp_code1, search[1])) + { + _totp_calculate (&otp_code2, w, pw_len, s + 32, 8); + + if (MATCHES_ONE_VS(otp_code2, search[2])) + { + _totp_calculate (&otp_code3, w, pw_len, s + 48, 8); + + COMPARE_S_SIMD (otp_code0, otp_code1, otp_code2, otp_code3); + } + } + } + } + } +} diff --git a/src/modules/module_18100.c b/src/modules/module_18100.c index 37a8ef2e7..54b12a68e 100644 --- a/src/modules/module_18100.c +++ b/src/modules/module_18100.c @@ -29,7 +29,7 @@ static const u64 OPTS_TYPE = OPTS_TYPE_STOCK_MODULE | OPTS_TYPE_SUGGEST_KG; static const u32 SALT_TYPE = SALT_TYPE_EMBEDDED; static const char *ST_PASS = "hashcat"; -static const char *ST_HASH = "597056:3600"; +static const char *ST_HASH = "597056:3600:613004:1234567890:322664:9876543210"; 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; } @@ -57,54 +57,92 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE hc_token_t token; - memset (&token, 0, sizeof (hc_token_t)); - - token.token_cnt = 2; - - token.sep[0] = hashconfig->separator; - token.len[0] = 6; - token.attr[0] = TOKEN_ATTR_FIXED_LENGTH - | TOKEN_ATTR_VERIFY_HEX; - - token.len_min[1] = SALT_MIN; - token.len_max[1] = SALT_MAX; - token.attr[1] = TOKEN_ATTR_VERIFY_LENGTH; - - if (hashconfig->opts_type & OPTS_TYPE_ST_HEX) + // 1 to 4 TOTP codes + // 597056:3600 + // 597056:3600:613004:1234567890 + // 597056:3600:613004:1234567890:322664:9876543210 + // 597056:3600:613004:1234567890:322664:9876543210:068798:111222333 + int count; + for (count = 8; count > 0; count -= 2) { - token.len_min[1] *= 2; - token.len_max[1] *= 2; + memset (&token, 0, sizeof (hc_token_t)); - token.attr[1] |= TOKEN_ATTR_VERIFY_DIGIT; + token.token_cnt = count; + + for (int i = 0; i < count; i += 2) + { + token.sep[i + 0] = hashconfig->separator; + token.len[i + 0] = 6; + token.attr[i + 0] = TOKEN_ATTR_FIXED_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + // 0 to 18446744073709551616 + token.sep[i + 1] = hashconfig->separator; + token.len_min[i + 1] = 1; + token.len_max[i + 1] = 20; + token.attr[i + 1] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_DIGIT; + + if (hashconfig->opts_type & OPTS_TYPE_ST_HEX) + { + token.len_min[i + 1] *= 2; + token.len_max[i + 1] *= 2; + token.attr[i + 1] = TOKEN_ATTR_VERIFY_LENGTH + | TOKEN_ATTR_VERIFY_HEX; + } + } + + const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + + if (rc_tokenizer == PARSER_OK) break; + + // failed all tokenizers + if (count == 2) return (rc_tokenizer); + } + count /= 2; + + for (int i = 0; i < count; i += 1) + { + // now we need to reduce our hash into a token + int otp_code = hc_strtoul ((const char *) token.buf[2 * i + 0], NULL, 10); + + digest[i] = otp_code; + + const u8 *salt_pos = token.buf[2 * i + 1]; + + // convert ascii timestamp to ulong timestamp + u64 timestamp = hc_strtoull ((const char *) salt_pos, NULL, 10); + + // store the original salt value. Step division will destroy granularity for output + salt->salt_buf[4 * i + 3] = ((u32) (timestamp >> 0)); + salt->salt_buf[4 * i + 2] = ((u32) (timestamp >> 32)); + + // divide our timestamp by our step. We will use the RFC 6238 default of 30 for now + timestamp /= 30; + + // convert counter to 8-byte salt + salt->salt_buf[4 * i + 1] = byte_swap_32 ((u32) (timestamp >> 0)); + salt->salt_buf[4 * i + 0] = byte_swap_32 ((u32) (timestamp >> 32)); } - const int rc_tokenizer = input_tokenizer ((const u8 *) line_buf, line_len, &token); + // verify unique salts + for (int i = 0; i < count; i += 1) + { + u32 s0 = salt->salt_buf[4 * i + 0]; + u32 s1 = salt->salt_buf[4 * i + 1]; - if (rc_tokenizer != PARSER_OK) return (rc_tokenizer); - - // now we need to reduce our hash into a token - int otp_code = hc_strtoul (line_buf, NULL, 10); - - digest[0] = otp_code; - - const u8 *salt_pos = token.buf[1]; - - // convert ascii timestamp to ulong timestamp - u64 timestamp = hc_strtoull ((const char *) salt_pos, NULL, 10); - - // store the original salt value. Step division will destroy granularity for output - salt->salt_buf[3] = ((u32) (timestamp >> 0)); - salt->salt_buf[2] = ((u32) (timestamp >> 32)); - - // divide our timestamp by our step. We will use the RFC 6238 default of 30 for now - timestamp /= 30; - - // convert counter to 8-byte salt - salt->salt_buf[1] = byte_swap_32 ((u32) (timestamp >> 0)); - salt->salt_buf[0] = byte_swap_32 ((u32) (timestamp >> 32)); + for (int j = i + 1; j < count; j += 1) + { + if (salt->salt_buf[4 * j + 0] == s0 && + salt->salt_buf[4 * j + 1] == s1) + { + return (PARSER_SALT_VALUE); + } + } + } // our salt will always be 8 bytes, but we are going to cheat and store it twice, so... - salt->salt_len = 16; + salt->salt_len = 16 * count; return (PARSER_OK); } @@ -113,13 +151,37 @@ int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE { const u32 *digest = (const u32 *) digest_buf; - // salt_buf[1] holds our 32 bit value. salt_buf[0] and salt_buf[1] would be 64 bits. + // salt_buf[4 * i + 1] holds our 32 bit value. salt_buf[4 * i + 0] and salt_buf[4 * i + 1] would be 64 bits. // we also need to multiply salt by our step to see the floor of our original timestamp range. // again, we will use the default RFC 6238 step of 30. - const u64 tmp_salt_buf = (((u64) (salt->salt_buf[2])) << 32) | ((u64) (salt->salt_buf[3])); + int count = salt->salt_len / 16; - const int line_len = snprintf (line_buf, line_size, "%06d%c%" PRIu64, digest[0], hashconfig->separator, tmp_salt_buf); + // all but the last TOTP code + int i = 0, line_len = 0; + for (; i < count - 1; i += 1) + { + const u64 tmp_salt_buf = (((u64) (salt->salt_buf[4 * i + 2])) << 32) | ((u64) (salt->salt_buf[4 * i + 3])); + const int ret = snprintf (line_buf + line_len, line_size - line_len, "%06d%c%" PRIu64 "%c", digest[i], hashconfig->separator, tmp_salt_buf, hashconfig->separator); + line_len += ret; + + // error + if (ret < 0) + { + return ret; + } + } + + // the last TOTP code + const u64 tmp_salt_buf = (((u64) (salt->salt_buf[4 * i + 2])) << 32) | ((u64) (salt->salt_buf[4 * i + 3])); + const int ret = snprintf (line_buf + line_len, line_size - line_len, "%06d%c%" PRIu64, digest[i], hashconfig->separator, tmp_salt_buf); + line_len += ret; + + // error + if (ret < 0) + { + return ret; + } return line_len; }