mirror of
https://github.com/hashcat/hashcat
synced 2024-12-01 20:18:12 +01:00
291 lines
6.2 KiB
Common Lisp
291 lines
6.2 KiB
Common Lisp
/**
|
|
* Author......: See docs/credits.txt
|
|
* License.....: MIT
|
|
*/
|
|
|
|
#include "inc_vendor.h"
|
|
#include "inc_types.h"
|
|
#include "inc_platform.h"
|
|
#include "inc_common.h"
|
|
#include "inc_cipher_aes.h"
|
|
#include "inc_cipher_aes-gcm.h"
|
|
|
|
#ifndef AES_GCM_ALT1
|
|
DECLSPEC void AES_GCM_shift_right_block(uchar *block)
|
|
{
|
|
u32 val;
|
|
|
|
uchar16 *v = (uchar16 *) block;
|
|
uint4 *p = (uint4 *) block;
|
|
|
|
val = hc_swap32_S (p[0].w);
|
|
val >>= 1;
|
|
if (v[0].sb & 0x01) val |= 0x80000000;
|
|
p[0].w = hc_swap32_S (val);
|
|
|
|
val = hc_swap32_S (p[0].z);
|
|
val >>= 1;
|
|
if (v[0].s7 & 0x01) val |= 0x80000000;
|
|
p[0].z = hc_swap32_S (val);
|
|
|
|
val = hc_swap32_S (p[0].y);
|
|
val >>= 1;
|
|
if (v[0].s3 & 0x01) val |= 0x80000000;
|
|
p[0].y = hc_swap32_S (val);
|
|
|
|
val = hc_swap32_S (p[0].x);
|
|
val >>= 1;
|
|
p[0].x = hc_swap32_S (val);
|
|
}
|
|
#endif // AES_GCM_ALT1
|
|
|
|
DECLSPEC void AES_GCM_inc32 (u32 *block)
|
|
{
|
|
block[3] += 0x00000001;
|
|
}
|
|
|
|
DECLSPEC void AES_GCM_xor_block (u32 *dst, const u32 *src)
|
|
{
|
|
*dst++ ^= *src++;
|
|
*dst++ ^= *src++;
|
|
*dst++ ^= *src++;
|
|
*dst++ ^= *src++;
|
|
}
|
|
|
|
DECLSPEC void AES_GCM_gf_mult (const uchar16 *x, const uchar16 *y, uchar16 *z)
|
|
{
|
|
u32 i, j;
|
|
|
|
z[0] = 0;
|
|
|
|
uchar16 v = y[0].s32107654ba98fedc;
|
|
|
|
u8 x_char[16] = { x[0].s3, x[0].s2, x[0].s1, x[0].s0, x[0].s7, x[0].s6, x[0].s5, x[0].s4, x[0].sb, x[0].sa, x[0].s9, x[0].s8, x[0].sf, x[0].se, x[0].sd, x[0].sc };
|
|
|
|
#ifndef AES_GCM_ALT1
|
|
u8 *v_char = (u8 *) &v;
|
|
#endif
|
|
|
|
u32 *i_char = (u32 *) &v;
|
|
|
|
u8 t = 0;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
for (j = 0; j < 8; j++)
|
|
{
|
|
if (x_char[i] & 1 << (7 - j))
|
|
{
|
|
z[0] ^= v;
|
|
}
|
|
|
|
t = v.sf & 0x01;
|
|
|
|
#ifndef AES_GCM_ALT1
|
|
|
|
AES_GCM_shift_right_block(v_char);
|
|
|
|
#else
|
|
|
|
i_char[0] = hc_swap32_S (i_char[0]);
|
|
i_char[1] = hc_swap32_S (i_char[1]);
|
|
i_char[2] = hc_swap32_S (i_char[2]);
|
|
i_char[3] = hc_swap32_S (i_char[3]);
|
|
|
|
i_char[3] = (i_char[3] >> 1) | (i_char[2] << 31);
|
|
i_char[2] = (i_char[2] >> 1) | (i_char[1] << 31);
|
|
i_char[1] = (i_char[1] >> 1) | (i_char[0] << 31);
|
|
i_char[0] >>= 1;
|
|
|
|
i_char[0] = hc_swap32_S (i_char[0]);
|
|
i_char[1] = hc_swap32_S (i_char[1]);
|
|
i_char[2] = hc_swap32_S (i_char[2]);
|
|
i_char[3] = hc_swap32_S (i_char[3]);
|
|
|
|
#endif // AES_GCM_ALT1
|
|
|
|
if (t)
|
|
{
|
|
v.s0 ^= 0xe1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
DECLSPEC void AES_GCM_ghash (const u32 *subkey, const u32 *in, u32 in_len, u32 *out)
|
|
{
|
|
u32 m = in_len / 16;
|
|
|
|
const u32 *xpos = in;
|
|
|
|
u32 tmp[4] = { 0 };
|
|
|
|
for (u32 i = 0; i < m; i++)
|
|
{
|
|
AES_GCM_xor_block (out, xpos);
|
|
|
|
xpos += 4;
|
|
|
|
AES_GCM_gf_mult ((uchar16 *) out, (uchar16 *) subkey, (uchar16 *) tmp);
|
|
|
|
tmp[0] = hc_swap32_S (tmp[0]);
|
|
tmp[1] = hc_swap32_S (tmp[1]);
|
|
tmp[2] = hc_swap32_S (tmp[2]);
|
|
tmp[3] = hc_swap32_S (tmp[3]);
|
|
|
|
out[0] = tmp[0];
|
|
out[1] = tmp[1];
|
|
out[2] = tmp[2];
|
|
out[3] = tmp[3];
|
|
}
|
|
|
|
if (in + (in_len/4) > xpos)
|
|
{
|
|
u32 last = in + (in_len/4) - xpos;
|
|
|
|
for (u32 i = 0; i < last; i++)
|
|
{
|
|
tmp[i] = xpos[i];
|
|
}
|
|
|
|
for (u32 i = last; i < 4; i++)
|
|
{
|
|
tmp[i] = 0;
|
|
}
|
|
|
|
AES_GCM_xor_block (out, tmp);
|
|
|
|
AES_GCM_gf_mult ((uchar16 *) out, (uchar16 *) subkey, (uchar16 *) tmp);
|
|
|
|
out[0] = tmp[0];
|
|
out[1] = tmp[1];
|
|
out[2] = tmp[2];
|
|
out[3] = tmp[3];
|
|
}
|
|
}
|
|
|
|
DECLSPEC void AES_GCM_Init (const u32 *ukey, u32 key_len, u32 *key, u32 *subkey, 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)
|
|
{
|
|
if (key_len == 128)
|
|
{
|
|
AES128_set_encrypt_key (key, ukey, s_te0, s_te1, s_te2, s_te3);
|
|
|
|
AES192_encrypt (key, subkey, subkey, s_te0, s_te1, s_te2, s_te3, s_te4);
|
|
}
|
|
else if (key_len == 192)
|
|
{
|
|
AES192_set_encrypt_key (key, ukey, s_te0, s_te1, s_te2, s_te3);
|
|
|
|
AES192_encrypt (key, subkey, subkey, s_te0, s_te1, s_te2, s_te3, s_te4);
|
|
}
|
|
else if (key_len == 256)
|
|
{
|
|
AES256_set_encrypt_key (key, ukey, s_te0, s_te1, s_te2, s_te3);
|
|
|
|
AES256_encrypt (key, subkey, subkey, s_te0, s_te1, s_te2, s_te3, s_te4);
|
|
}
|
|
}
|
|
|
|
DECLSPEC void AES_GCM_Prepare_J0 (const u32 *iv, u32 iv_len, const u32 *subkey, u32 *J0)
|
|
{
|
|
if (iv_len == 12)
|
|
{
|
|
J0[0] = iv[0];
|
|
J0[1] = iv[1];
|
|
J0[2] = iv[2];
|
|
J0[3] = 0x00000001;
|
|
}
|
|
else
|
|
{
|
|
J0[0] = iv[0];
|
|
J0[1] = iv[1];
|
|
J0[2] = iv[2];
|
|
J0[3] = iv[3];
|
|
|
|
u32 len_buf[4] = { 0 };
|
|
|
|
len_buf[3] = iv_len * 8;
|
|
|
|
AES_GCM_ghash (subkey, len_buf, 16, J0);
|
|
}
|
|
}
|
|
|
|
DECLSPEC void AES_GCM_gctr (const u32 *key, const u32 *iv, const u32 *in, u32 in_len, u32 *out, 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)
|
|
{
|
|
const u32 *xpos = in;
|
|
u32 *ypos = out;
|
|
|
|
u32 n = in_len / 16;
|
|
|
|
u32 iv_buf[4] = { iv[0], iv[1], iv[2], iv[3] };
|
|
|
|
for (u32 i = 0; i < n; i++)
|
|
{
|
|
AES256_encrypt (key, iv_buf, ypos, s_te0, s_te1, s_te2, s_te3, s_te4);
|
|
|
|
AES_GCM_xor_block (ypos, xpos);
|
|
|
|
xpos += 4;
|
|
ypos += 4;
|
|
|
|
AES_GCM_inc32 (iv_buf);
|
|
}
|
|
|
|
u32 last = in + (in_len/4) - xpos;
|
|
|
|
if (last)
|
|
{
|
|
u32 tmp[4] = { 0 };
|
|
|
|
AES256_encrypt (key, iv_buf, tmp, s_te0, s_te1, s_te2, s_te3, s_te4);
|
|
|
|
if (last >= 1) *ypos++ = *xpos++ ^ tmp[0];
|
|
if (last >= 2) *ypos++ = *xpos++ ^ tmp[1];
|
|
if (last >= 3) *ypos++ = *xpos++ ^ tmp[2];
|
|
}
|
|
}
|
|
|
|
DECLSPEC void AES_GCM_GCTR (u32 *key, u32 *J0, u32 *in, u32 in_len, u32 *out, 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 J0_incr[4] = {
|
|
J0[0],
|
|
J0[1],
|
|
J0[2],
|
|
J0[3],
|
|
};
|
|
|
|
AES_GCM_gctr (key, J0_incr, in, in_len, out, s_te0, s_te1, s_te2, s_te3, s_te4);
|
|
}
|
|
|
|
DECLSPEC void AES_GCM_GHASH (const u32 *subkey, const u32 *aad_buf, u32 aad_len, u32 *enc_buf, u32 enc_len, u32 *out)
|
|
{
|
|
u32 len_buf[4] = { 0 };
|
|
|
|
out[0] = 0;
|
|
out[1] = 0;
|
|
out[2] = 0;
|
|
out[3] = 0;
|
|
|
|
AES_GCM_ghash (subkey, aad_buf, aad_len, out);
|
|
|
|
// untested swap
|
|
/*
|
|
out[0] = hc_swap32_S (out[0]);
|
|
out[1] = hc_swap32_S (out[1]);
|
|
out[2] = hc_swap32_S (out[2]);
|
|
out[3] = hc_swap32_S (out[3]);
|
|
*/
|
|
|
|
AES_GCM_ghash (subkey, enc_buf, enc_len, out);
|
|
|
|
out[0] = hc_swap32_S (out[0]);
|
|
out[1] = hc_swap32_S (out[1]);
|
|
out[2] = hc_swap32_S (out[2]);
|
|
out[3] = hc_swap32_S (out[3]);
|
|
|
|
len_buf[0] = aad_len * 8;
|
|
len_buf[3] = enc_len * 8;
|
|
|
|
AES_GCM_ghash (subkey, len_buf, 16, out);
|
|
}
|