diff --git a/.editorconfig b/.editorconfig index 565326214..29656fecb 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,9 +8,12 @@ root = true charset = utf-8 end_of_line = lf insert_final_newline = true -trim_trailing_whitespace = true indent_style = space indent_size = 2 +trim_trailing_whitespace = true + +[*.{pot,rule}] +trim_trailing_whitespace = false [Makefile] indent_style = tab diff --git a/OpenCL/m18400-pure.cl b/OpenCL/m18400-pure.cl index 6d0a5857b..c3f2931f5 100644 --- a/OpenCL/m18400-pure.cl +++ b/OpenCL/m18400-pure.cl @@ -35,6 +35,7 @@ typedef struct odf12 u32 iv[4]; u32 checksum[8]; u32 encrypted_data[256]; + int encrypted_len; } odf12_t; @@ -352,111 +353,49 @@ KERNEL_FQ void m18400_comp (KERN_ATTR_TMPS_ESALT (odf12_tmp_t, odf12_t)) iv[2] = es->iv[2]; iv[3] = es->iv[3]; - u32 ct[4]; + u32 pt[256]; - u32 pt1[4]; - u32 pt2[4]; - u32 pt3[4]; - u32 pt4[4]; - - sha256_ctx_t sha256_ctx; - - sha256_init (&sha256_ctx); - - // decrypt aes-cbc and calculate plaintext checksum at the same time - for (int i = 0; i < 16; i++) + for (int i = 0, j = 0; i < es->encrypted_len; i += 16, j += 4) { - const int i16 = i * 16; + u32 ct[4]; - ct[0] = es->encrypted_data[i16 + 0]; - ct[1] = es->encrypted_data[i16 + 1]; - ct[2] = es->encrypted_data[i16 + 2]; - ct[3] = es->encrypted_data[i16 + 3]; + ct[0] = es->encrypted_data[j + 0]; + ct[1] = es->encrypted_data[j + 1]; + ct[2] = es->encrypted_data[j + 2]; + ct[3] = es->encrypted_data[j + 3]; - aes256_decrypt (ks, ct, pt1, s_td0, s_td1, s_td2, s_td3, s_td4); + aes256_decrypt (ks, ct, pt + j, s_td0, s_td1, s_td2, s_td3, s_td4); - pt1[0] ^= iv[0]; - pt1[1] ^= iv[1]; - pt1[2] ^= iv[2]; - pt1[3] ^= iv[3]; - - iv[0] = ct[0]; - iv[1] = ct[1]; - iv[2] = ct[2]; - iv[3] = ct[3]; - - ct[0] = es->encrypted_data[i16 + 4]; - ct[1] = es->encrypted_data[i16 + 5]; - ct[2] = es->encrypted_data[i16 + 6]; - ct[3] = es->encrypted_data[i16 + 7]; - - aes256_decrypt (ks, ct, pt2, s_td0, s_td1, s_td2, s_td3, s_td4); - - pt2[0] ^= iv[0]; - pt2[1] ^= iv[1]; - pt2[2] ^= iv[2]; - pt2[3] ^= iv[3]; - - iv[0] = ct[0]; - iv[1] = ct[1]; - iv[2] = ct[2]; - iv[3] = ct[3]; - - ct[0] = es->encrypted_data[i16 + 8]; - ct[1] = es->encrypted_data[i16 + 9]; - ct[2] = es->encrypted_data[i16 + 10]; - ct[3] = es->encrypted_data[i16 + 11]; - - aes256_decrypt (ks, ct, pt3, s_td0, s_td1, s_td2, s_td3, s_td4); - - pt3[0] ^= iv[0]; - pt3[1] ^= iv[1]; - pt3[2] ^= iv[2]; - pt3[3] ^= iv[3]; + pt[j + 0] ^= iv[0]; + pt[j + 1] ^= iv[1]; + pt[j + 2] ^= iv[2]; + pt[j + 3] ^= iv[3]; iv[0] = ct[0]; iv[1] = ct[1]; iv[2] = ct[2]; iv[3] = ct[3]; + } - ct[0] = es->encrypted_data[i16 + 12]; - ct[1] = es->encrypted_data[i16 + 13]; - ct[2] = es->encrypted_data[i16 + 14]; - ct[3] = es->encrypted_data[i16 + 15]; + const int full64 = es->encrypted_len / 64; - aes256_decrypt (ks, ct, pt4, s_td0, s_td1, s_td2, s_td3, s_td4); + const int encrypted_len64 = full64 * 64; - pt4[0] ^= iv[0]; - pt4[1] ^= iv[1]; - pt4[2] ^= iv[2]; - pt4[3] ^= iv[3]; + sha256_ctx_t sha256_ctx; - iv[0] = ct[0]; - iv[1] = ct[1]; - iv[2] = ct[2]; - iv[3] = ct[3]; + sha256_init (&sha256_ctx); - pt1[0] = hc_swap32_S (pt1[0]); - pt1[1] = hc_swap32_S (pt1[1]); - pt1[2] = hc_swap32_S (pt1[2]); - pt1[3] = hc_swap32_S (pt1[3]); + sha256_update_swap (&sha256_ctx, pt, encrypted_len64); - pt2[0] = hc_swap32_S (pt2[0]); - pt2[1] = hc_swap32_S (pt2[1]); - pt2[2] = hc_swap32_S (pt2[2]); - pt2[3] = hc_swap32_S (pt2[3]); + const int remaining64 = es->encrypted_len - encrypted_len64; - pt3[0] = hc_swap32_S (pt3[0]); - pt3[1] = hc_swap32_S (pt3[1]); - pt3[2] = hc_swap32_S (pt3[2]); - pt3[3] = hc_swap32_S (pt3[3]); + if (remaining64) + { + u32 *pt_remaining = pt + (encrypted_len64 / 4); - pt4[0] = hc_swap32_S (pt4[0]); - pt4[1] = hc_swap32_S (pt4[1]); - pt4[2] = hc_swap32_S (pt4[2]); - pt4[3] = hc_swap32_S (pt4[3]); + truncate_block_16x4_be_S (pt_remaining + 0, pt_remaining + 4, pt_remaining + 8, pt_remaining + 12, remaining64); - sha256_update_64 (&sha256_ctx, pt1, pt2, pt3, pt4, 64); + sha256_update_swap (&sha256_ctx, pt_remaining, remaining64); } sha256_final (&sha256_ctx); diff --git a/OpenCL/m18600-pure.cl b/OpenCL/m18600-pure.cl index e674228e1..8618025fb 100644 --- a/OpenCL/m18600-pure.cl +++ b/OpenCL/m18600-pure.cl @@ -33,6 +33,7 @@ typedef struct odf11 u32 iv[2]; u32 checksum[5]; u32 encrypted_data[256]; + int encrypted_len; } odf11_t; @@ -759,116 +760,48 @@ KERNEL_FQ void FIXED_THREAD_COUNT(FIXED_LOCAL_SIZE_COMP) m18600_comp (KERN_ATTR_ GLOBAL_AS const odf11_t *es = &esalt_bufs[DIGESTS_OFFSET_HOST]; - u32 ct[2]; - - u32 pt0[4]; - u32 pt1[4]; - u32 pt2[4]; - u32 pt3[4]; - - u32 buf[2]; - - buf[0] = es->iv[0]; - buf[1] = es->iv[1]; + u32 iv[2]; - sha1_ctx_t sha1_ctx; + iv[0] = es->iv[0]; + iv[1] = es->iv[1]; - sha1_init (&sha1_ctx); + u32 pt[256]; - // decrypt blowfish-cfb and calculate plaintext checksum at the same time - for (int i = 0; i < 16; i++) + for (int i = 0, j = 0; i < es->encrypted_len; i += 8, j += 2) { - const int i16 = i * 16; - - ct[0] = es->encrypted_data[i16 + 0]; - ct[1] = es->encrypted_data[i16 + 1]; - - BF_ENCRYPT (buf[0], buf[1]); - - pt0[0] = ct[0] ^ buf[0]; - pt0[1] = ct[1] ^ buf[1]; - - buf[0] = ct[0]; - buf[1] = ct[1]; - - ct[0] = es->encrypted_data[i16 + 2]; - ct[1] = es->encrypted_data[i16 + 3]; - - BF_ENCRYPT (buf[0], buf[1]); - - pt0[2] = ct[0] ^ buf[0]; - pt0[3] = ct[1] ^ buf[1]; - - buf[0] = ct[0]; - buf[1] = ct[1]; - - ct[0] = es->encrypted_data[i16 + 4]; - ct[1] = es->encrypted_data[i16 + 5]; + u32 ct[2]; - BF_ENCRYPT (buf[0], buf[1]); + ct[0] = es->encrypted_data[j + 0]; + ct[1] = es->encrypted_data[j + 1]; - pt1[0] = ct[0] ^ buf[0]; - pt1[1] = ct[1] ^ buf[1]; + BF_ENCRYPT (iv[0], iv[1]); - buf[0] = ct[0]; - buf[1] = ct[1]; + pt[j + 0] = ct[0] ^ iv[0]; + pt[j + 1] = ct[1] ^ iv[1]; - ct[0] = es->encrypted_data[i16 + 6]; - ct[1] = es->encrypted_data[i16 + 7]; - - BF_ENCRYPT (buf[0], buf[1]); - - pt1[2] = ct[0] ^ buf[0]; - pt1[3] = ct[1] ^ buf[1]; - - buf[0] = ct[0]; - buf[1] = ct[1]; - - ct[0] = es->encrypted_data[i16 + 8]; - ct[1] = es->encrypted_data[i16 + 9]; - - BF_ENCRYPT (buf[0], buf[1]); - - pt2[0] = ct[0] ^ buf[0]; - pt2[1] = ct[1] ^ buf[1]; - - buf[0] = ct[0]; - buf[1] = ct[1]; - - ct[0] = es->encrypted_data[i16 + 10]; - ct[1] = es->encrypted_data[i16 + 11]; - - BF_ENCRYPT (buf[0], buf[1]); - - pt2[2] = ct[0] ^ buf[0]; - pt2[3] = ct[1] ^ buf[1]; - - buf[0] = ct[0]; - buf[1] = ct[1]; + iv[0] = ct[0]; + iv[1] = ct[1]; + } - ct[0] = es->encrypted_data[i16 + 12]; - ct[1] = es->encrypted_data[i16 + 13]; + const int full64 = es->encrypted_len / 64; - BF_ENCRYPT (buf[0], buf[1]); + const int encrypted_len64 = full64 * 64; - pt3[0] = ct[0] ^ buf[0]; - pt3[1] = ct[1] ^ buf[1]; + sha1_ctx_t sha1_ctx; - buf[0] = ct[0]; - buf[1] = ct[1]; + sha1_init (&sha1_ctx); - ct[0] = es->encrypted_data[i16 + 14]; - ct[1] = es->encrypted_data[i16 + 15]; + sha1_update (&sha1_ctx, pt, encrypted_len64); - BF_ENCRYPT (buf[0], buf[1]); + const int remaining64 = es->encrypted_len - encrypted_len64; - pt3[2] = ct[0] ^ buf[0]; - pt3[3] = ct[1] ^ buf[1]; + if (remaining64) + { + u32 *pt_remaining = pt + (encrypted_len64 / 4); - buf[0] = ct[0]; - buf[1] = ct[1]; + truncate_block_16x4_be_S (pt_remaining + 0, pt_remaining + 4, pt_remaining + 8, pt_remaining + 12, remaining64); - sha1_update_64 (&sha1_ctx, pt0, pt1, pt2, pt3, 64); + sha1_update (&sha1_ctx, pt_remaining, remaining64); } sha1_final (&sha1_ctx); diff --git a/docs/changes.txt b/docs/changes.txt index 55197404f..448e026ac 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -56,6 +56,7 @@ - Backend Checks: Describe workaround in error message when detecting more than 64 backend devices - Brain: Added sanity check and corresponding error message for invalid --brain-port values - Modules: Added support for non-zero IVs for -m 6800 (Lastpass). Also added `tools/lastpass2hashcat.py` +- Open Document Format: Added support for small documents with content length < 1024 - Status Code: Add specific return code for self-test fail (-11) - Scrypt: Increase buffer sizes in module for hash mode 8900 to allow longer scrypt digests - Unicode: Update UTF-8 to UTF-16 conversion to match RFC 3629 diff --git a/src/modules/module_18400.c b/src/modules/module_18400.c index 43fa0cea4..7f681910b 100644 --- a/src/modules/module_18400.c +++ b/src/modules/module_18400.c @@ -58,6 +58,7 @@ typedef struct odf12 u32 iv[4]; u32 checksum[8]; u32 encrypted_data[256]; + int encrypted_len; } odf12_t; @@ -166,18 +167,19 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE token.attr[10] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; - token.len[11] = 2048; - token.attr[11] = TOKEN_ATTR_FIXED_LENGTH + token.len_min[11] = 16; + token.len_max[11] = 2048; + token.sep[11] = '*'; + token.attr[11] = 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) return (rc_tokenizer); - const u8 *checksum = token.buf[5]; - const u8 *iv = token.buf[7]; - const u8 *salt_buf = token.buf[9]; - const u8 *encrypted_data = token.buf[11]; + const u8 *checksum = token.buf[5]; + const u8 *iv = token.buf[7]; + const u8 *salt_buf = token.buf[9]; const u32 cipher_type = strtol ((const char *) token.buf[1], NULL, 10); const u32 checksum_type = strtol ((const char *) token.buf[2], NULL, 10); @@ -207,15 +209,19 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE odf12->checksum[6] = hex_to_u32 (&checksum[48]); odf12->checksum[7] = hex_to_u32 (&checksum[56]); + // iv + odf12->iv[0] = hex_to_u32 (&iv[0]); odf12->iv[1] = hex_to_u32 (&iv[8]); odf12->iv[2] = hex_to_u32 (&iv[16]); odf12->iv[3] = hex_to_u32 (&iv[24]); - for (int i = 0, j = 0; i < 256; i += 1, j += 8) - { - odf12->encrypted_data[i] = hex_to_u32 (&encrypted_data[j]); - } + // ct + + const int ct_len = token.len[11]; + const u8 *ct_pos = token.buf[11]; + + odf12->encrypted_len = hex_decode (ct_pos, ct_len, (u8 *) odf12->encrypted_data); // salt @@ -248,7 +254,19 @@ int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE { const odf12_t *odf12 = (const odf12_t *) esalt_buf; - int out_len = snprintf (line_buf, line_size, "%s*1*1*%u*32*%08x%08x%08x%08x%08x%08x%08x%08x*16*%08x%08x%08x%08x*16*%08x%08x%08x%08x*0*", + // ct + + u32 ct_buf[256]; + + for (int i = 0; i < 256; i++) ct_buf[i] = byte_swap_32 (odf12->encrypted_data[i]); + + u8 ct_buf8[(256 * 4 * 2) + 1]; + + const int ct_len = hex_encode ((const u8 *) ct_buf, odf12->encrypted_len, ct_buf8); + + ct_buf8[ct_len] = 0; + + const int out_len = snprintf (line_buf, line_size, "%s*1*1*%u*32*%08x%08x%08x%08x%08x%08x%08x%08x*16*%08x%08x%08x%08x*16*%08x%08x%08x%08x*0*%s", SIGNATURE_ODF, odf12->iterations, byte_swap_32 (odf12->checksum[0]), @@ -266,14 +284,8 @@ int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE byte_swap_32 (salt->salt_buf[0]), byte_swap_32 (salt->salt_buf[1]), byte_swap_32 (salt->salt_buf[2]), - byte_swap_32 (salt->salt_buf[3])); - - u8 *out_buf = (u8 *) line_buf; - - for (int i = 0; i < 256; i++) - { - u32_to_hex (odf12->encrypted_data[i], out_buf + out_len); out_len += 8; - } + byte_swap_32 (salt->salt_buf[3]), + (char *) ct_buf8); return out_len; } diff --git a/src/modules/module_18600.c b/src/modules/module_18600.c index b0cd68a52..38ce745cd 100644 --- a/src/modules/module_18600.c +++ b/src/modules/module_18600.c @@ -60,6 +60,7 @@ typedef struct odf11 u32 iv[2]; u32 checksum[5]; u32 encrypted_data[256]; + int encrypted_len; } odf11_t; @@ -261,18 +262,19 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE token.attr[10] = TOKEN_ATTR_VERIFY_LENGTH | TOKEN_ATTR_VERIFY_DIGIT; - token.len[11] = 2048; - token.attr[11] = TOKEN_ATTR_FIXED_LENGTH + token.len_min[11] = 16; + token.len_max[11] = 2048; + token.sep[11] = '*'; + token.attr[11] = 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) return (rc_tokenizer); - const u8 *checksum = token.buf[5]; - const u8 *iv = token.buf[7]; - const u8 *salt_buf = token.buf[9]; - const u8 *encrypted_data = token.buf[11]; + const u8 *checksum = token.buf[5]; + const u8 *iv = token.buf[7]; + const u8 *salt_buf = token.buf[9]; const u32 cipher_type = strtol ((const char *) token.buf[1], NULL, 10); const u32 checksum_type = strtol ((const char *) token.buf[2], NULL, 10); @@ -299,15 +301,19 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE odf11->checksum[3] = hex_to_u32 (&checksum[24]); odf11->checksum[4] = hex_to_u32 (&checksum[32]); + // iv + odf11->iv[0] = byte_swap_32 (hex_to_u32 (&iv[0])); odf11->iv[1] = byte_swap_32 (hex_to_u32 (&iv[8])); - for (int i = 0, j = 0; i < 256; i += 1, j += 8) - { - odf11->encrypted_data[i] = hex_to_u32 (&encrypted_data[j]); + // ct - odf11->encrypted_data[i] = byte_swap_32 (odf11->encrypted_data[i]); - } + const int ct_len = token.len[11]; + const u8 *ct_pos = token.buf[11]; + + odf11->encrypted_len = hex_decode (ct_pos, ct_len, (u8 *) odf11->encrypted_data); + + for (int i = 0, j = 0; i < odf11->encrypted_len; i += 4, j += 1) odf11->encrypted_data[j] = byte_swap_32 (odf11->encrypted_data[j]); // salt @@ -342,7 +348,19 @@ int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE { const odf11_t *odf11 = (const odf11_t *) esalt_buf; - int out_len = snprintf (line_buf, line_size, "%s*0*0*%u*16*%08x%08x%08x%08x%08x*8*%08x%08x*16*%08x%08x%08x%08x*0*", + // ct + + u32 ct_buf[256]; + + for (int i = 0; i < 256; i++) ct_buf[i] = byte_swap_32 (odf11->encrypted_data[i]); + + u8 ct_buf8[(256 * 4 * 2) + 1]; + + const int ct_len = hex_encode ((const u8 *) ct_buf, odf11->encrypted_len, ct_buf8); + + ct_buf8[ct_len] = 0; + + const int out_len = snprintf (line_buf, line_size, "%s*0*0*%u*16*%08x%08x%08x%08x%08x*8*%08x%08x*16*%08x%08x%08x%08x*0*%s", SIGNATURE_ODF, odf11->iterations, byte_swap_32 (odf11->checksum[0]), @@ -355,14 +373,8 @@ int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE salt->salt_buf[0], salt->salt_buf[1], salt->salt_buf[2], - salt->salt_buf[3]); - - u8 *out_buf = (u8 *) line_buf; - - for (int i = 0; i < 256; i++) - { - u32_to_hex (byte_swap_32 (odf11->encrypted_data[i]), out_buf + out_len); out_len += 8; - } + salt->salt_buf[3], + (char *) ct_buf8); return out_len; }