Merge pull request #2845 from roycewilliams/master

minor whitespace fixes
pull/2847/head
Jens Steube 3 years ago committed by GitHub
commit 8b6395c725
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1847,7 +1847,7 @@ DECLSPEC void point_mul_xy (u32 *x1, u32 *y1, const u32 *k, GLOBAL_AS const secp
{
u32 naf[SECP256K1_NAF_SIZE] = { 0 };
int loop_start = convert_to_window_naf(naf, k);
// first set:
const u32 multiplier = (naf[loop_start >> 3] >> ((loop_start & 7) << 2)) & 0x0f; // or use u8 ?
@ -1973,7 +1973,7 @@ DECLSPEC void point_mul_xy (u32 *x1, u32 *y1, const u32 *k, GLOBAL_AS const secp
mul_mod (z1, z2, z1); // z1^3
mul_mod (y1, y1, z1); // y1_affine
// return values are already in x1 and y1
}

@ -204,7 +204,7 @@ KERNEL_FQ void m03500_sxx (KERN_ATTR_RULES ())
/**
* base
*/
*/
COPY_PW (pws[gid]);

@ -1,7 +1,7 @@
/**
* Author......: See docs/credits.txt
* License.....: MIT
*/
*/
#define NEW_SIMD_CODE

@ -120,7 +120,7 @@ KERNEL_FQ void m14511_mxx (KERN_ATTR_RULES_ESALT (cryptoapi_t))
ctx.w0[0] = 0x41000000;
ctx.len = 1;
sha1_update_swap (&ctx, w, w_len);
sha1_final (&ctx);

@ -255,7 +255,7 @@ KERNEL_FQ void m14512_sxx (KERN_ATTR_RULES_ESALT (cryptoapi_t))
}
// key
u32 ukey[8] = { 0 };
ukey[0] = hc_swap32_S (k0);

@ -256,7 +256,7 @@ KERNEL_FQ void m14513_sxx (KERN_ATTR_RULES_ESALT (cryptoapi_t))
}
// key
u32 ukey[8] = { 0 };
ukey[0] = hc_swap32_S (k0);

@ -243,7 +243,7 @@ KERNEL_FQ void m14522_sxx (KERN_ATTR_RULES_ESALT (cryptoapi_t))
salt_bufs[SALT_POS].salt_buf[0],
salt_bufs[SALT_POS].salt_buf[1],
salt_bufs[SALT_POS].salt_buf[2],
salt_bufs[SALT_POS].salt_buf[3]
salt_bufs[SALT_POS].salt_buf[3]
};
// CT

@ -102,7 +102,7 @@ KERNEL_FQ void m14522_mxx (KERN_ATTR_ESALT (cryptoapi_t))
salt_bufs[SALT_POS].salt_buf[0],
salt_bufs[SALT_POS].salt_buf[1],
salt_bufs[SALT_POS].salt_buf[2],
salt_bufs[SALT_POS].salt_buf[3]
salt_bufs[SALT_POS].salt_buf[3]
};
// CT
@ -233,7 +233,7 @@ KERNEL_FQ void m14522_sxx (KERN_ATTR_ESALT (cryptoapi_t))
salt_bufs[SALT_POS].salt_buf[0],
salt_bufs[SALT_POS].salt_buf[1],
salt_bufs[SALT_POS].salt_buf[2],
salt_bufs[SALT_POS].salt_buf[3]
salt_bufs[SALT_POS].salt_buf[3]
};
// CT

@ -115,7 +115,7 @@ KERNEL_FQ void m14522_mxx (KERN_ATTR_VECTOR_ESALT (cryptoapi_t))
salt_bufs[SALT_POS].salt_buf[0],
salt_bufs[SALT_POS].salt_buf[1],
salt_bufs[SALT_POS].salt_buf[2],
salt_bufs[SALT_POS].salt_buf[3]
salt_bufs[SALT_POS].salt_buf[3]
};
// CT
@ -259,7 +259,7 @@ KERNEL_FQ void m14522_sxx (KERN_ATTR_VECTOR_ESALT (cryptoapi_t))
salt_bufs[SALT_POS].salt_buf[0],
salt_bufs[SALT_POS].salt_buf[1],
salt_bufs[SALT_POS].salt_buf[2],
salt_bufs[SALT_POS].salt_buf[3]
salt_bufs[SALT_POS].salt_buf[3]
};
// CT

@ -80,7 +80,7 @@ KERNEL_FQ void m14523_mxx (KERN_ATTR_RULES_ESALT (cryptoapi_t))
}
// key
u32 ukey[8] = { 0 };
ukey[0] = hc_swap32_S (k0);
@ -106,7 +106,7 @@ KERNEL_FQ void m14523_mxx (KERN_ATTR_RULES_ESALT (cryptoapi_t))
salt_bufs[SALT_POS].salt_buf[0],
salt_bufs[SALT_POS].salt_buf[1],
salt_bufs[SALT_POS].salt_buf[2],
salt_bufs[SALT_POS].salt_buf[3]
salt_bufs[SALT_POS].salt_buf[3]
};
// CT
@ -244,7 +244,7 @@ KERNEL_FQ void m14523_sxx (KERN_ATTR_RULES_ESALT (cryptoapi_t))
salt_bufs[SALT_POS].salt_buf[0],
salt_bufs[SALT_POS].salt_buf[1],
salt_bufs[SALT_POS].salt_buf[2],
salt_bufs[SALT_POS].salt_buf[3]
salt_bufs[SALT_POS].salt_buf[3]
};
// CT

@ -102,7 +102,7 @@ KERNEL_FQ void m14523_mxx (KERN_ATTR_ESALT (cryptoapi_t))
salt_bufs[SALT_POS].salt_buf[0],
salt_bufs[SALT_POS].salt_buf[1],
salt_bufs[SALT_POS].salt_buf[2],
salt_bufs[SALT_POS].salt_buf[3]
salt_bufs[SALT_POS].salt_buf[3]
};
// CT
@ -234,7 +234,7 @@ KERNEL_FQ void m14523_sxx (KERN_ATTR_ESALT (cryptoapi_t))
salt_bufs[SALT_POS].salt_buf[0],
salt_bufs[SALT_POS].salt_buf[1],
salt_bufs[SALT_POS].salt_buf[2],
salt_bufs[SALT_POS].salt_buf[3]
salt_bufs[SALT_POS].salt_buf[3]
};
// CT

@ -115,7 +115,7 @@ KERNEL_FQ void m14523_mxx (KERN_ATTR_VECTOR_ESALT (cryptoapi_t))
salt_bufs[SALT_POS].salt_buf[0],
salt_bufs[SALT_POS].salt_buf[1],
salt_bufs[SALT_POS].salt_buf[2],
salt_bufs[SALT_POS].salt_buf[3]
salt_bufs[SALT_POS].salt_buf[3]
};
// CT
@ -260,7 +260,7 @@ KERNEL_FQ void m14523_sxx (KERN_ATTR_VECTOR_ESALT (cryptoapi_t))
salt_bufs[SALT_POS].salt_buf[0],
salt_bufs[SALT_POS].salt_buf[1],
salt_bufs[SALT_POS].salt_buf[2],
salt_bufs[SALT_POS].salt_buf[3]
salt_bufs[SALT_POS].salt_buf[3]
};
// CT

@ -80,7 +80,7 @@ KERNEL_FQ void m14532_mxx (KERN_ATTR_RULES_ESALT (cryptoapi_t))
}
// key
u32 ukey[8] = { 0 };
ukey[0] = hc_swap32_S (k0);

@ -125,7 +125,7 @@ KERNEL_FQ void m14553_mxx (KERN_ATTR_RULES_ESALT (cryptoapi_t))
}
// key
u32 ukey[8] = { 0 };
ukey[0] = hc_swap32_S (k0);

@ -3,7 +3,7 @@
* License.....: MIT
*/
//#define NEW_SIMD_CODE
//#define NEW_SIMD_CODE
#ifdef KERNEL_STATIC
#include "inc_vendor.h"

@ -140,7 +140,7 @@ DECLSPEC void m24300m (u32 *w0, u32 *w1, u32 *w2, u32 *w3, const u32 pw_len, KER
u32x wd_t = w3[1];
u32x we_t = w3[2];
u32x wf_t = pw_salt_len * 8;
u32x a = SHA1M_A;
u32x b = SHA1M_B;
@ -717,7 +717,7 @@ DECLSPEC void m24300s (u32 *w0, u32 *w1, u32 *w2, u32 *w3, const u32 pw_len, KER
u32x wd_t = w3[1];
u32x we_t = w3[2];
u32x wf_t = pw_salt_len * 8;
u32x a = SHA1M_A;
u32x b = SHA1M_B;
@ -906,7 +906,7 @@ DECLSPEC void m24300s (u32 *w0, u32 *w1, u32 *w2, u32 *w3, const u32 pw_len, KER
wc_t = hc_swap32 (t3[0]);
wd_t = hc_swap32 (t3[1]);
we_t = hc_swap32 (t3[2]);
wf_t = hc_swap32 (t3[3]);
wf_t = hc_swap32 (t3[3]);
#undef K
#define K SHA1C00

@ -45,9 +45,9 @@ DECLSPEC u32 MurmurHash (const u32 seed, const u32 *w, const int pw_len)
hash ^= hash >> R;
}
hash *= M;
hash *= M;
hash ^= hash >> 10;
hash *= M;
hash *= M;
hash ^= hash >> 17;
#undef M

@ -44,9 +44,9 @@ DECLSPEC u32 MurmurHash (const u32 seed, const u32 *w, const int pw_len)
hash ^= hash >> R;
}
hash *= M;
hash *= M;
hash ^= hash >> 10;
hash *= M;
hash *= M;
hash ^= hash >> 17;
#undef M

@ -64,9 +64,9 @@ DECLSPEC u32x MurmurHash_w0 (const u32 seed, const u32x w0, const u32 *w, const
}
}
hash *= M;
hash *= M;
hash ^= hash >> 10;
hash *= M;
hash *= M;
hash ^= hash >> 17;
#undef M

@ -398,7 +398,7 @@ KERNEL_FQ void m25900_comp(KERN_ATTR_TMPS_ESALT(pbkdf2_sha256_tmp_t, blocks_t))
aes128_encrypt_cbc (aes_ks, aes_cbc_iv, b1, yn, s_te0, s_te1, s_te2, s_te3, s_te4);
aes128_encrypt_cbc (aes_ks, aes_cbc_iv, b2, yn, s_te0, s_te1, s_te2, s_te3, s_te4);
aes128_encrypt_cbc (aes_ks, aes_cbc_iv, b3, yn, s_te0, s_te1, s_te2, s_te3, s_te4);
u32 nonce[4];
nonce[0] = 0;

@ -484,7 +484,7 @@ This configuration item is a bitmask field and is very similar to the module_opt
* OPTS_TYPE_COPY_TMPS: This option tells the hashcat host binary to copy the `tmps` data structure from the compute device to the host in case a hash was cracked. In order to access this data, you need to implement and register the module function module_build_plain_postprocess(). There are several scenarios in which this can be useful. For instance, if you have a weak algorithm that could be exploited to leak portions of the password and you use this leaked data to speed up your attacks, you still need to know the leaked data on the host to copy it to the password buffer before printing it to the user. A good example for this is PKZIP `src/modules/module_20510.c` which leaks the first 6 bytes of the password. Another scenario is the PIM brute force in VeraCrypt. The PIM in this case can be seen as an additional numeric password. In case we crack it, the user needs to know both the password and the PIM in order to mount the volume.
* OPTS_TYPE_POTFILE_NOPASS: This option simply prevents the hashcat host binary from adding a cracked hash to the potfile. For instance, if a specific hashing algorithm is implemented with several hash formats and therefore your plugins hash format shares the same format with a different plugin hash format (think of it like a format clash where the potfile parser could not really decide if it is the correct hash format to accept). A good example is the WPA PMK, which cannot be used to login to a specific WPA network directly. There could be other reasons for not printing the cracked hashes to the potfile.
* OPTS_TYPE_DYNAMIC_SHARED: This is a very special option which tells the hashcat host binary to query the real available shared memory on a device for a particular kernel. In addition it will also register the queried amount of shared memory from the host. On NVIDIA, this allows us to use the full available shared memory (regions in the post 48k range), though we still need to prepare the kernel in order to make use of the dynamic allocated shared memory. A good example is the bcrypt kernel `OpenCL/m03200-pure.cl`.
* OPTS_TYPE_SELF_TEST_DISABLE: This option can be used if you want to disable the self-test functionality for your hash-mode. Valid reasons to disable this feature are: Your OpenCL kernel is using compile time optimizations such as fixed salts (like in DESCrypt), the hash primitive to be used has to be derived first from the target hash (like in JWT) or the hash-mode is so slow that it hurts startup time of hashcat (like in Ethereum Wallet SCRYPT). For the first two cases the problem is that hashcat would create a cached optimized OpenCL kernel with a configuration which is valid only for the self-test hash, but very likely the wrong ones for the real target hash. The real target hash would never crack.
* OPTS_TYPE_SELF_TEST_DISABLE: This option can be used if you want to disable the self-test functionality for your hash-mode. Valid reasons to disable this feature are: Your OpenCL kernel is using compile time optimizations such as fixed salts (like in DESCrypt), the hash primitive to be used has to be derived first from the target hash (like in JWT) or the hash-mode is so slow that it hurts startup time of hashcat (like in Ethereum Wallet SCRYPT). For the first two cases the problem is that hashcat would create a cached optimized OpenCL kernel with a configuration which is valid only for the self-test hash, but very likely the wrong ones for the real target hash. The real target hash would never crack.
* OPTS_TYPE_MP_MULTI_DISABLE: Do not multiply the kernel-accel with the multiprocessor count per device to allow more fine-tuned workload settings.
* OPTS_TYPE_NATIVE_THREADS: Forces "native" thread count: CPU=1, GPU-Intel=8, GPU-AMD=64 (wavefront), GPU-NV=32 (warps). Does not override user-defined -u value.
* OPTS_TYPE_POST_AMP_UTF16LE: Run the true UTF8 to UTF16LE conversion kernel after they have been processed from amplifiers. Works only for slow-hash kernels.

@ -1,7 +1,7 @@
/**
* Author......: See docs/credits.txt
* License.....: MIT
*/
*/
#include "common.h"
#include "types.h"
@ -73,7 +73,7 @@ int module_hash_decode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE
if (rc_tokenizer != PARSER_OK) return (rc_tokenizer);
const u8 *hash_pos = token.buf[0];
const u8 *hash_pos = token.buf[0];
digest[0] = hex_to_u32 (hash_pos + 0);
digest[1] = hex_to_u32 (hash_pos + 8);

@ -39,7 +39,7 @@ sub module_verify_hash
my $signature = substr ($hash, 0, 9);
my $plain_base64 = substr ($hash, 9);
return unless ($signature eq "{SSHA256}");
return unless ($signature eq "{SSHA256}");
return unless defined $plain_base64;
# base64 decode to extract salt

@ -45,7 +45,7 @@ sub module_generate_hash
"guid" : "00000000-0000-0000-0000-000000000000",
"sharedKey" : "00000000-0000-0000-0000-000000000000",
"options" : {"pbkdf2_iterations":$iterations,"fee_policy":0,"html5_notifications":false,"logout_time":600000,"tx_display":0,"always_keep_local_backup":false}|;
unless (defined $encrypted)
{
$encrypted = unpack ("H*", $cipher->encrypt ($data));

@ -58,7 +58,7 @@ sub module_generate_hash
);
my $b_seed = $pbkdf2->PBKDF2 ($mysalt, $word);
# we can precompute this
my $b_kerberos_nfolded = hex2byte ('6b65726265726f737b9b5b2b93132b93');
@ -68,14 +68,14 @@ sub module_generate_hash
# and 'ke' (AES key to decrypt/encrypt the ticket)
my $cbc = Crypt::Mode::CBC->new ('AES', 0);
my $b_key_bytes = $cbc->encrypt ($b_kerberos_nfolded, $b_seed, $b_iv);
# precomputed stuff
# nfold 0x0000000155 to 16 bytes
my $b_nfolded1 = hex2byte ('5b582c160a5aa80556ab55aad5402ab5');
# nfold 0x00000001aa to 16 bytes
my $b_nfolded2 = hex2byte ('ae2c160b04ad5006ab55aad56a80355a');
my $b_ki = $cbc->encrypt ($b_nfolded1, $b_key_bytes, $b_iv);
@ -98,36 +98,36 @@ sub module_generate_hash
# Pad the last block with last bytes from the decrypted n-1
my $b_padded_enc_ticket = hex2byte ($enc_timestamp) . (substr $b_n_1_decrypted, -(16 - $len_last_block / 2));
# Swap the last two blocks
my $b_cbc_enc_ticket = (substr $b_padded_enc_ticket, 0, -32) . (substr $b_padded_enc_ticket, -16, 16).
(substr $b_padded_enc_ticket, -32, 16);
# Decrypt and truncate
my $b_dec_ticket_padded = $cbc->decrypt ($b_cbc_enc_ticket, $b_ke, $b_iv);
my $b_cleartext_ticket = substr $b_dec_ticket_padded, 0, length ($enc_timestamp) / 2;
$cleartext_ticket = byte2hex ($b_cleartext_ticket);
my $check_correct = ((substr ($b_cleartext_ticket, 22, 2) eq "20") &&
my $check_correct = ((substr ($b_cleartext_ticket, 22, 2) eq "20") &&
(substr ($b_cleartext_ticket, 36, 1) eq "Z"));
if ($check_correct == 1 && defined $checksum)
{
my $b_checksum = hmac_sha1 (hex2byte ($cleartext_ticket), $b_ki);
$check_correct = ($checksum eq byte2hex (substr $b_checksum, 0, 12));
}
}
if ($check_correct != 1)
{
# fake/wrong ticket (otherwise if we just decrypt/encrypt we end
#up with false positives all the time)
$cleartext_ticket = '68c8459f3f10c851b8827118bb459c6e301aa011180f323031'.
'32313131363134323835355aa10502030c28a2';
# we have what is required to compute checksum
$checksum = hmac_sha1 (hex2byte ($cleartext_ticket), $b_ki);
@ -191,7 +191,7 @@ sub module_verify_hash
return unless ($algorithm eq "17");
return unless (length ($edata) >= 88);
return unless (length ($edata) <= 112);
my $checksum = substr $edata, -24;
my $enc_timestamp = substr $edata, 0, -24;

@ -58,7 +58,7 @@ sub module_generate_hash
);
my $b_seed = $pbkdf2->PBKDF2 ($mysalt, $word);
# we can precompute this
my $b_kerberos_nfolded = hex2byte ('6b65726265726f737b9b5b2b93132b93');
@ -70,14 +70,14 @@ sub module_generate_hash
my $b_key_bytes = $cbc->encrypt ($b_kerberos_nfolded, $b_seed, $b_iv);
$b_key_bytes = $b_key_bytes . $cbc->encrypt ($b_key_bytes, $b_seed, $b_iv);
# precomputed stuff
# nfold 0x0000000155 to 16 bytes
my $b_nfolded1 = hex2byte ('5b582c160a5aa80556ab55aad5402ab5');
# nfold 0x00000001aa to 16 bytes
my $b_nfolded2 = hex2byte ('ae2c160b04ad5006ab55aad56a80355a');
my $b_ki = $cbc->encrypt ($b_nfolded1, $b_key_bytes, $b_iv);
$b_ki = $b_ki . $cbc->encrypt ($b_ki, $b_key_bytes, $b_iv);
@ -85,10 +85,10 @@ sub module_generate_hash
my $b_ke = $cbc->encrypt ($b_nfolded2, $b_key_bytes, $b_iv);
$b_ke = $b_ke . $cbc->encrypt ($b_ke, $b_key_bytes, $b_iv);
my $cleartext_ticket = '';
my $check_correct = 0;
if (defined $enc_timestamp)
{
# Do CTS Decryption https://en.wikipedia.org/wiki/Ciphertext_stealing
@ -103,42 +103,42 @@ sub module_generate_hash
# Pad the last block with last bytes from the decrypted n-1
my $b_padded_enc_ticket = hex2byte ($enc_timestamp) . (substr $b_n_1_decrypted, -(16 - $len_last_block / 2));
# Swap the last two blocks
my $b_cbc_enc_ticket = (substr $b_padded_enc_ticket, 0, -32) . (substr $b_padded_enc_ticket, -16, 16).
(substr $b_padded_enc_ticket, -32, 16);
# Decrypt and truncate
my $b_dec_ticket_padded = $cbc->decrypt ($b_cbc_enc_ticket, $b_ke, $b_iv);
my $b_cleartext_ticket = substr $b_dec_ticket_padded, 0, length ($enc_timestamp) / 2;
$cleartext_ticket = byte2hex ($b_cleartext_ticket);
my $check_correct = ((substr ($b_cleartext_ticket, 22, 2) eq "20") &&
my $check_correct = ((substr ($b_cleartext_ticket, 22, 2) eq "20") &&
(substr ($b_cleartext_ticket, 36, 1) eq "Z"));
if ($check_correct == 1 && defined $checksum)
{
my $b_checksum = hmac_sha1 (hex2byte ($cleartext_ticket), $b_ki);
$check_correct = ($checksum eq byte2hex (substr $b_checksum, 0, 12));
}
}
if ($check_correct != 1)
{
# fake/wrong ticket (otherwise if we just decrypt/encrypt we end
#up with false positives all the time)
$cleartext_ticket = '68c8459f3f10c851b8827118bb459c6e301aa011180f323031'.
'32313131363134323835355aa10502030c28a2';
# we have what is required to compute checksum
$checksum = hmac_sha1 (hex2byte ($cleartext_ticket), $b_ki);
$checksum = byte2hex (substr $checksum, 0, 12);
}
# CTS Encrypt our new block
my $len_cleartext_last_block = length ($cleartext_ticket) % 32;
my $cleartext_last_block = substr $cleartext_ticket, -$len_cleartext_last_block;
@ -195,7 +195,7 @@ sub module_verify_hash
return unless ($algorithm eq "18");
return unless (length ($edata) >= 88);
return unless (length ($edata) <= 112);
my $checksum = substr $edata, -24;
my $enc_timestamp = substr $edata, 0, -24;

@ -32,15 +32,15 @@ sub module_generate_hash
my $hash_buf = encode_base64 ($pbkdf2->PBKDF2 ($salt, $word), '');
my $salt_buf = encode_base64 ($salt, '');
# replace + with .
$hash_buf =~ s/\+/\./g;
$salt_buf =~ s/\+/\./g;
# remove padding =
$hash_buf =~ s/\=+$//;
$salt_buf =~ s/\=+$//;
my $hash = sprintf ("\$pbkdf2-sha512\$%i\$%s\$%s", $iter, $salt_buf, $hash_buf);
return $hash;

@ -32,15 +32,15 @@ sub module_generate_hash
my $hash_buf = encode_base64 ($pbkdf2->PBKDF2 ($salt, $word), '');
my $salt_buf = encode_base64 ($salt, '');
# replace + with .
$hash_buf =~ s/\+/\./g;
$salt_buf =~ s/\+/\./g;
# remove padding =
$hash_buf =~ s/\=+$//;
$salt_buf =~ s/\=+$//;
my $hash = sprintf ("\$pbkdf2-sha256\$%i\$%s\$%s", $iter, $salt_buf, $hash_buf);
return $hash;

@ -32,15 +32,15 @@ sub module_generate_hash
my $hash_buf = encode_base64 ($pbkdf2->PBKDF2 ($salt, $word), '');
my $salt_buf = encode_base64 ($salt, '');
# replace + with .
$hash_buf =~ s/\+/\./g;
$salt_buf =~ s/\+/\./g;
# remove padding =
$hash_buf =~ s/\=+$//;
$salt_buf =~ s/\=+$//;
my $hash = sprintf ("\$pbkdf2\$%i\$%s\$%s", $iter, $salt_buf, $hash_buf);
return $hash;

@ -45,7 +45,7 @@ sub module_verify_hash
return unless defined $iter;
return unless defined $salt;
return unless defined $word;
my $new_hash = module_generate_hash ($word, $salt, $iter);
return ($new_hash, $word);

@ -110,7 +110,7 @@ sub pdf_compute_encryption_key_owner
}
else
{
$o_key = substr($o_digest, 0, 16); #length is always 128 bits or 16 bytes
$o_key = substr($o_digest, 0, 16); #length is always 128 bits or 16 bytes
}
#printf("\$o_key = %s\n", unpack ("H*", $o_key));

@ -12,7 +12,7 @@ use Crypt::PBKDF2;
use Crypt::Mode::CBC;
use Crypt::Mode::ECB;
# Details of the protocol design can be found in ISO 22510:2019 and
# Details of the protocol design can be found in ISO 22510:2019 and
# application notes published by the KNX Association.
# ETS 5 allows a maximum of 20 characters in a password.
@ -22,17 +22,17 @@ sub module_constraints { [[0, 20], [2, 2], [-1, -1], [-1, -1], [-1, -1]] }
sub device_authentication_code
{
my $password = shift;
my $pbkdf2 = Crypt::PBKDF2->new
(
hasher => Crypt::PBKDF2->hasher_from_algorithm ("HMACSHA2", 256),
iterations => 65536,
output_len => 16
);
my $device_authentication_code = $pbkdf2->PBKDF2 ("device-authentication-code.1.secure.ip.knx.org",
my $device_authentication_code = $pbkdf2->PBKDF2 ("device-authentication-code.1.secure.ip.knx.org",
$password);
return $device_authentication_code;
}
@ -45,7 +45,7 @@ sub block_formatting
my $blocks_unpadded = $associated_data_length . $associated_data;
my $pad_len = int ((length ($blocks_unpadded) + 16 - 1) / 16) * 16;
my $blocks_padded = $blocks_unpadded . "\0" x ($pad_len - length ($blocks_unpadded));
return $b0 . $blocks_padded;
}
@ -56,14 +56,14 @@ sub encrypt
my $nonce = shift;
my $key = shift;
my $iv = "\0" x 16;
my $aes_cbc = Crypt::Mode::CBC->new ("AES", 0);
my $ciphertext = $aes_cbc->encrypt ($blocks, $key, $iv);
my $ciphertext = $aes_cbc->encrypt ($blocks, $key, $iv);
my $y_n = substr ($ciphertext, length ($ciphertext) - 16, 16);
my $aes_ecb = Crypt::Mode::ECB->new ("AES", 0);
my $s_0 = $aes_ecb->encrypt ($nonce, $key);
return $y_n ^ $s_0;
}
@ -72,72 +72,72 @@ sub generate_session_response_mac
my $secure_session_identifier = shift;
my $public_value_xor = shift;
my $key = shift;
# Constants used for the cryptography in Session_Response frames
my $knx_ip_header = pack ("H*", "061009520038");
my $b0 = pack ("H*", "00000000000000000000000000000000");
my $nonce = pack ("H*", "0000000000000000000000000000ff00");
my $associated_data = $knx_ip_header . $secure_session_identifier . $public_value_xor;
my $blocks = block_formatting ($b0, $associated_data);
return encrypt ($blocks, $nonce, $key);
}
sub module_generate_hash
{
my $word = shift;
# Parameters that would be found in the Session_Request and Session_Response frames
my $secure_session_identifier = shift;
my $public_value_xor = shift // random_bytes (32);
my $device_authentication_code = device_authentication_code ($word);
my $mac = generate_session_response_mac ($secure_session_identifier,
$public_value_xor,
$device_authentication_code);
my $hash = sprintf ("\$knx-ip-secure-device-authentication-code\$*%s*%s*%s",
my $hash = sprintf ("\$knx-ip-secure-device-authentication-code\$*%s*%s*%s",
unpack ("H*", $secure_session_identifier),
unpack ("H*", $public_value_xor),
unpack ("H*", $mac));
return $hash;
}
sub module_verify_hash
{
my $line = shift;
my ($hash, $word) = split (':', $line);
return unless defined $hash;
return unless defined $word;
my @data = split ('\*', $hash);
return unless scalar (@data) == 4;
my $signature = shift @data;
return unless ($signature eq "\$knx-ip-secure-device-authentication-code\$");
my $secure_session_identifier = pack ("H*", shift @data); # 2 Bytes expected (using the "salt" for this purpose)
my $public_value_xor = pack ("H*", shift @data); # 32 Bytes expected (xor of client's and server's public value)
my $mac = pack ("H*", shift @data); # 16 Bytes expected
return unless (length ($secure_session_identifier) == 2);
return unless (length ($public_value_xor) == 32);
return unless (length ($mac) == 16);
my $word_packed = pack_if_HEX_notation ($word);
my $new_hash = module_generate_hash ($word_packed,
$secure_session_identifier,
my $new_hash = module_generate_hash ($word_packed,
$secure_session_identifier,
$public_value_xor);
return ($new_hash, $word);
}

Loading…
Cancel
Save