2023-02-24 23:51:14 +00:00
/**
* 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_sha256.cl )
# include M2S ( INCLUDE_PATH/inc_cipher_aes.cl )
# include M2S ( INCLUDE_PATH/inc_cipher_aes-gcm.cl )
# endif
# define COMPARE_S M2S ( INCLUDE_PATH/inc_comp_single.cl )
# define COMPARE_M M2S ( INCLUDE_PATH/inc_comp_multi.cl )
typedef struct pbkdf2_sha256_tmp
{
u32 ipad[8] ;
u32 opad[8] ;
u32 dgst[32] ;
u32 out[32] ;
} pbkdf2_sha256_tmp_t ;
typedef struct pbkdf2_sha256_aes_gcm
{
u32 salt_buf[64] ;
u32 iv_buf[4] ;
u32 iv_len ;
2023-02-26 12:52:23 +00:00
u32 ct_buf[784] ; // TODO this can be smaller and would speedup the attack, only 64 bytes of ciphertext are allowed
2023-02-24 23:51:14 +00:00
u32 ct_len ;
} pbkdf2_sha256_aes_gcm_t ;
DECLSPEC void hmac_sha256_run_V ( PRIVATE_AS u32x *w0, PRIVATE_AS u32x *w1, PRIVATE_AS u32x *w2, PRIVATE_AS u32x *w3, PRIVATE_AS u32x *ipad, PRIVATE_AS u32x *opad, PRIVATE_AS u32x *digest )
{
digest[0] = ipad[0] ;
digest[1] = ipad[1] ;
digest[2] = ipad[2] ;
digest[3] = ipad[3] ;
digest[4] = ipad[4] ;
digest[5] = ipad[5] ;
digest[6] = ipad[6] ;
digest[7] = ipad[7] ;
sha256_transform_vector ( w0, w1, w2, w3, digest ) ;
w0[0] = digest[0] ;
w0[1] = digest[1] ;
w0[2] = digest[2] ;
w0[3] = digest[3] ;
w1[0] = digest[4] ;
w1[1] = digest[5] ;
w1[2] = digest[6] ;
w1[3] = digest[7] ;
w2[0] = 0x80000000 ;
w2[1] = 0 ;
w2[2] = 0 ;
w2[3] = 0 ;
w3[0] = 0 ;
w3[1] = 0 ;
w3[2] = 0 ;
w3[3] = ( 64 + 32 ) * 8 ;
digest[0] = opad[0] ;
digest[1] = opad[1] ;
digest[2] = opad[2] ;
digest[3] = opad[3] ;
digest[4] = opad[4] ;
digest[5] = opad[5] ;
digest[6] = opad[6] ;
digest[7] = opad[7] ;
sha256_transform_vector ( w0, w1, w2, w3, digest ) ;
}
KERNEL_FQ void m26610_init ( KERN_ATTR_TMPS_ESALT ( pbkdf2_sha256_tmp_t, pbkdf2_sha256_aes_gcm_t ) )
{
/**
* base
*/
const u64 gid = get_global_id ( 0 ) ;
if ( gid >= GID_CNT ) return ;
sha256_hmac_ctx_t sha256_hmac_ctx ;
sha256_hmac_init_global_swap ( &sha256_hmac_ctx, pws[gid].i, pws[gid].pw_len ) ;
tmps[gid].ipad[0] = sha256_hmac_ctx.ipad.h[0] ;
tmps[gid].ipad[1] = sha256_hmac_ctx.ipad.h[1] ;
tmps[gid].ipad[2] = sha256_hmac_ctx.ipad.h[2] ;
tmps[gid].ipad[3] = sha256_hmac_ctx.ipad.h[3] ;
tmps[gid].ipad[4] = sha256_hmac_ctx.ipad.h[4] ;
tmps[gid].ipad[5] = sha256_hmac_ctx.ipad.h[5] ;
tmps[gid].ipad[6] = sha256_hmac_ctx.ipad.h[6] ;
tmps[gid].ipad[7] = sha256_hmac_ctx.ipad.h[7] ;
tmps[gid].opad[0] = sha256_hmac_ctx.opad.h[0] ;
tmps[gid].opad[1] = sha256_hmac_ctx.opad.h[1] ;
tmps[gid].opad[2] = sha256_hmac_ctx.opad.h[2] ;
tmps[gid].opad[3] = sha256_hmac_ctx.opad.h[3] ;
tmps[gid].opad[4] = sha256_hmac_ctx.opad.h[4] ;
tmps[gid].opad[5] = sha256_hmac_ctx.opad.h[5] ;
tmps[gid].opad[6] = sha256_hmac_ctx.opad.h[6] ;
tmps[gid].opad[7] = sha256_hmac_ctx.opad.h[7] ;
sha256_hmac_update_global_swap ( &sha256_hmac_ctx, esalt_bufs[DIGESTS_OFFSET_HOST].salt_buf, salt_bufs[SALT_POS_HOST].salt_len ) ;
for ( u32 i = 0 , j = 1 ; i < 8; i += 8, j += 1)
{
sha256_hmac_ctx_t sha256_hmac_ctx2 = sha256_hmac_ctx ;
u32 w0[4] ;
u32 w1[4] ;
u32 w2[4] ;
u32 w3[4] ;
w0[0] = j ;
w0[1] = 0 ;
w0[2] = 0 ;
w0[3] = 0 ;
w1[0] = 0 ;
w1[1] = 0 ;
w1[2] = 0 ;
w1[3] = 0 ;
w2[0] = 0 ;
w2[1] = 0 ;
w2[2] = 0 ;
w2[3] = 0 ;
w3[0] = 0 ;
w3[1] = 0 ;
w3[2] = 0 ;
w3[3] = 0 ;
sha256_hmac_update_64 ( &sha256_hmac_ctx2, w0, w1, w2, w3, 4 ) ;
sha256_hmac_final ( &sha256_hmac_ctx2 ) ;
tmps[gid].dgst[i + 0] = sha256_hmac_ctx2.opad.h[0] ;
tmps[gid].dgst[i + 1] = sha256_hmac_ctx2.opad.h[1] ;
tmps[gid].dgst[i + 2] = sha256_hmac_ctx2.opad.h[2] ;
tmps[gid].dgst[i + 3] = sha256_hmac_ctx2.opad.h[3] ;
tmps[gid].dgst[i + 4] = sha256_hmac_ctx2.opad.h[4] ;
tmps[gid].dgst[i + 5] = sha256_hmac_ctx2.opad.h[5] ;
tmps[gid].dgst[i + 6] = sha256_hmac_ctx2.opad.h[6] ;
tmps[gid].dgst[i + 7] = sha256_hmac_ctx2.opad.h[7] ;
tmps[gid].out[i + 0] = tmps[gid].dgst[i + 0] ;
tmps[gid].out[i + 1] = tmps[gid].dgst[i + 1] ;
tmps[gid].out[i + 2] = tmps[gid].dgst[i + 2] ;
tmps[gid].out[i + 3] = tmps[gid].dgst[i + 3] ;
tmps[gid].out[i + 4] = tmps[gid].dgst[i + 4] ;
tmps[gid].out[i + 5] = tmps[gid].dgst[i + 5] ;
tmps[gid].out[i + 6] = tmps[gid].dgst[i + 6] ;
tmps[gid].out[i + 7] = tmps[gid].dgst[i + 7] ;
}
}
KERNEL_FQ void m26610_loop ( KERN_ATTR_TMPS_ESALT ( pbkdf2_sha256_tmp_t, pbkdf2_sha256_aes_gcm_t ) )
{
const u64 gid = get_global_id ( 0 ) ;
if ( ( gid * VECT_SIZE ) >= GID_CNT ) return ;
u32x ipad[8] ;
u32x opad[8] ;
ipad[0] = packv ( tmps, ipad, gid, 0 ) ;
ipad[1] = packv ( tmps, ipad, gid, 1 ) ;
ipad[2] = packv ( tmps, ipad, gid, 2 ) ;
ipad[3] = packv ( tmps, ipad, gid, 3 ) ;
ipad[4] = packv ( tmps, ipad, gid, 4 ) ;
ipad[5] = packv ( tmps, ipad, gid, 5 ) ;
ipad[6] = packv ( tmps, ipad, gid, 6 ) ;
ipad[7] = packv ( tmps, ipad, gid, 7 ) ;
opad[0] = packv ( tmps, opad, gid, 0 ) ;
opad[1] = packv ( tmps, opad, gid, 1 ) ;
opad[2] = packv ( tmps, opad, gid, 2 ) ;
opad[3] = packv ( tmps, opad, gid, 3 ) ;
opad[4] = packv ( tmps, opad, gid, 4 ) ;
opad[5] = packv ( tmps, opad, gid, 5 ) ;
opad[6] = packv ( tmps, opad, gid, 6 ) ;
opad[7] = packv ( tmps, opad, gid, 7 ) ;
for ( u32 i = 0 ; i < 8; i += 8)
{
u32x dgst[8] ;
u32x out[8] ;
dgst[0] = packv ( tmps, dgst, gid, i + 0 ) ;
dgst[1] = packv ( tmps, dgst, gid, i + 1 ) ;
dgst[2] = packv ( tmps, dgst, gid, i + 2 ) ;
dgst[3] = packv ( tmps, dgst, gid, i + 3 ) ;
dgst[4] = packv ( tmps, dgst, gid, i + 4 ) ;
dgst[5] = packv ( tmps, dgst, gid, i + 5 ) ;
dgst[6] = packv ( tmps, dgst, gid, i + 6 ) ;
dgst[7] = packv ( tmps, dgst, gid, i + 7 ) ;
out[0] = packv ( tmps, out, gid, i + 0 ) ;
out[1] = packv ( tmps, out, gid, i + 1 ) ;
out[2] = packv ( tmps, out, gid, i + 2 ) ;
out[3] = packv ( tmps, out, gid, i + 3 ) ;
out[4] = packv ( tmps, out, gid, i + 4 ) ;
out[5] = packv ( tmps, out, gid, i + 5 ) ;
out[6] = packv ( tmps, out, gid, i + 6 ) ;
out[7] = packv ( tmps, out, gid, i + 7 ) ;
for ( u32 j = 0 ; j < LOOP_CNT; j++)
{
u32x w0[4] ;
u32x w1[4] ;
u32x w2[4] ;
u32x w3[4] ;
w0[0] = dgst[0] ;
w0[1] = dgst[1] ;
w0[2] = dgst[2] ;
w0[3] = dgst[3] ;
w1[0] = dgst[4] ;
w1[1] = dgst[5] ;
w1[2] = dgst[6] ;
w1[3] = dgst[7] ;
w2[0] = 0x80000000 ;
w2[1] = 0 ;
w2[2] = 0 ;
w2[3] = 0 ;
w3[0] = 0 ;
w3[1] = 0 ;
w3[2] = 0 ;
w3[3] = ( 64 + 32 ) * 8 ;
hmac_sha256_run_V ( w0, w1, w2, w3, ipad, opad, dgst ) ;
out[0] ^= dgst[0] ;
out[1] ^= dgst[1] ;
out[2] ^= dgst[2] ;
out[3] ^= dgst[3] ;
out[4] ^= dgst[4] ;
out[5] ^= dgst[5] ;
out[6] ^= dgst[6] ;
out[7] ^= dgst[7] ;
}
unpackv ( tmps, dgst, gid, i + 0 , dgst[0] ) ;
unpackv ( tmps, dgst, gid, i + 1 , dgst[1] ) ;
unpackv ( tmps, dgst, gid, i + 2 , dgst[2] ) ;
unpackv ( tmps, dgst, gid, i + 3 , dgst[3] ) ;
unpackv ( tmps, dgst, gid, i + 4 , dgst[4] ) ;
unpackv ( tmps, dgst, gid, i + 5 , dgst[5] ) ;
unpackv ( tmps, dgst, gid, i + 6 , dgst[6] ) ;
unpackv ( tmps, dgst, gid, i + 7 , dgst[7] ) ;
unpackv ( tmps, out, gid, i + 0 , out[0] ) ;
unpackv ( tmps, out, gid, i + 1 , out[1] ) ;
unpackv ( tmps, out, gid, i + 2 , out[2] ) ;
unpackv ( tmps, out, gid, i + 3 , out[3] ) ;
unpackv ( tmps, out, gid, i + 4 , out[4] ) ;
unpackv ( tmps, out, gid, i + 5 , out[5] ) ;
unpackv ( tmps, out, gid, i + 6 , out[6] ) ;
unpackv ( tmps, out, gid, i + 7 , out[7] ) ;
}
}
KERNEL_FQ void m26610_comp ( KERN_ATTR_TMPS_ESALT ( pbkdf2_sha256_tmp_t, pbkdf2_sha256_aes_gcm_t ) )
{
const u64 gid = get_global_id ( 0 ) ;
const u64 lid = get_local_id ( 0 ) ;
const u64 lsz = get_local_size ( 0 ) ;
# define il_pos 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 ;
// keys
u32 ukey[8] ;
ukey[0] = tmps[gid].out[0] ;
ukey[1] = tmps[gid].out[1] ;
ukey[2] = tmps[gid].out[2] ;
ukey[3] = tmps[gid].out[3] ;
ukey[4] = tmps[gid].out[4] ;
ukey[5] = tmps[gid].out[5] ;
ukey[6] = tmps[gid].out[6] ;
ukey[7] = tmps[gid].out[7] ;
u32 key_len = 32 * 8 ;
u32 key[60] = { 0 } ;
u32 subKey[4] = { 0 } ;
AES_GCM_Init ( ukey, key_len, key, subKey, s_te0, s_te1, s_te2, s_te3, s_te4 ) ;
// iv
2023-03-07 21:43:44 +00:00
u32 iv[4] ;
iv[0] = esalt_bufs[DIGESTS_OFFSET_HOST].iv_buf[0] ;
iv[1] = esalt_bufs[DIGESTS_OFFSET_HOST].iv_buf[1] ;
iv[2] = esalt_bufs[DIGESTS_OFFSET_HOST].iv_buf[2] ;
iv[3] = esalt_bufs[DIGESTS_OFFSET_HOST].iv_buf[3] ;
2023-02-24 23:51:14 +00:00
const u32 iv_len = esalt_bufs[DIGESTS_OFFSET_HOST].iv_len ;
u32 J0[4] = { 0 } ;
AES_GCM_Prepare_J0 ( iv, iv_len, subKey, J0 ) ;
2023-02-26 12:31:38 +00:00
//ct
2023-03-07 21:43:44 +00:00
u32 ct[4] ;
ct[0] = esalt_bufs[DIGESTS_OFFSET_HOST].ct_buf[0] ;
ct[1] = esalt_bufs[DIGESTS_OFFSET_HOST].ct_buf[1] ;
ct[2] = esalt_bufs[DIGESTS_OFFSET_HOST].ct_buf[2] ;
ct[3] = esalt_bufs[DIGESTS_OFFSET_HOST].ct_buf[3] ;
2023-02-24 23:51:14 +00:00
u32 pt[4] = { 0 } ;
// we try to decrypt the ciphertext
2023-02-27 14:32:59 +00:00
// TODO this can be moved to a separate decryption function in inc_cipher_aes-gcm.cl
2023-02-24 23:51:14 +00:00
AES_GCM_inc32 ( J0 ) ; // the first ctr is used to compute the tag, only the second is used for decryption: https://en.wikipedia.org/wiki/Galois/Counter_Mode#/media/File:GCM-Galois_Counter_Mode_with_IV.svg
AES_GCM_GCTR ( key, J0, ct, 16 , pt, s_te0, s_te1, s_te2, s_te3, s_te4 ) ; // decrypt the ciphertext
2023-02-26 12:31:38 +00:00
// if ( ( gid == 0 ) && ( lid == 0 ) ) printf ( "pt[0]=%08x\n" , pt[0] ) ; // should be 5b7b2274 or [{"type"
2023-02-24 23:51:14 +00:00
2023-03-07 21:43:44 +00:00
u32 digest[4] ;
digest[0] = esalt_bufs[DIGESTS_OFFSET_HOST].ct_buf[0] ;
digest[1] = esalt_bufs[DIGESTS_OFFSET_HOST].ct_buf[1] ;
digest[2] = esalt_bufs[DIGESTS_OFFSET_HOST].ct_buf[2] ;
digest[3] = esalt_bufs[DIGESTS_OFFSET_HOST].ct_buf[3] ;
2023-02-24 23:51:14 +00:00
2023-02-26 12:31:38 +00:00
//if ( ( gid == 0 ) && ( lid == 0 ) ) printf ( "ct[0]=%08x\n" , ct[0] ) ;
//if ( ( gid == 0 ) && ( lid == 0 ) ) printf ( "ct[1]=%08x\n" , ct[1] ) ;
//if ( ( gid == 0 ) && ( lid == 0 ) ) printf ( "ct[2]=%08x\n" , ct[2] ) ;
//if ( ( gid == 0 ) && ( lid == 0 ) ) printf ( "ct[3]=%08x\n" , ct[3] ) ;
2023-03-07 21:43:44 +00:00
const int correct = is_valid_printable_32 ( pt[0] )
+ is_valid_printable_32 ( pt[1] )
+ is_valid_printable_32 ( pt[2] )
+ is_valid_printable_32 ( pt[3] ) ;
if ( correct == 4 )
2023-02-24 23:51:14 +00:00
{
int digest_pos = find_hash ( digest, DIGESTS_CNT, &digests_buf[DIGESTS_OFFSET_HOST] ) ;
if ( digest_pos != -1 )
{
const u32 final_hash_pos = DIGESTS_OFFSET_HOST + digest_pos ;
if ( hc_atomic_inc ( &hashes_shown[final_hash_pos] ) == 0 )
{
mark_hash ( plains_buf, d_return_buf, SALT_POS_HOST, DIGESTS_CNT, digest_pos, final_hash_pos, gid, il_pos, 0 , 0 ) ;
}
}
}
}