openwall / john

John the Ripper jumbo - advanced offline password cracker, which supports hundreds of hash and cipher types, and runs on many operating systems, CPUs, GPUs, and even some FPGAs
https://www.openwall.com/john/
Other
10.12k stars 2.08k forks source link

Add missing salt_hash() functions #809

Closed magnumripper closed 9 years ago

magnumripper commented 9 years ago

I hope I'm doing this wrong because this is a LOT of formats :cry:

OTOH many of the below are "salt-only" non-hashes so doesn't benefit that much of a hash function.

$ git grep -L "SALT_SIZE.*\b0\b" *fmt*c | xargs grep -l fmt_default_salt_hash
7z_fmt_plug.c
DMD5_fmt_plug.c
HDAA_fmt_plug.c
KRB4_fmt_plug.c
KRB5_fmt_plug.c
NS_fmt_plug.c
SKEY_fmt_plug.c
SybasePROP_fmt_plug.c
agilekeychain_fmt_plug.c
aix_smd5_fmt_plug.c
aix_ssha_fmt_plug.c
androidfde_fmt_plug.c
bitcoin_fmt_plug.c
blackberry_ES10_fmt_plug.c
blockchain_fmt_plug.c
chap_fmt_plug.c
cloudkeychain_fmt_plug.c
cq_fmt_plug.c
cuda_cryptmd5_fmt_plug.c
cuda_cryptsha256_fmt_plug.c
cuda_cryptsha512_fmt_plug.c
cuda_mscash2_fmt_plug.c
cuda_mscash_fmt_plug.c
cuda_phpass_fmt_plug.c
cuda_pwsafe_fmt_plug.c
cuda_rawsha512_fmt_plug.c
cuda_wpapsk_fmt_plug.c
django_fmt_plug.c
django_scrypt_fmt_plug.c
dmg_fmt_plug.c
ecryptfs_fmt_plug.c
efs_fmt_plug.c
eigrp_fmt_plug.c
encfs_fmt_plug.c
episerver_fmt_plug.c
gost_fmt_plug.c
gpg_fmt_plug.c
hmacMD5_fmt_plug.c
hmacSHA1_fmt_plug.c
hsrp_fmt_plug.c
ike_fmt_plug.c
keepass_fmt_plug.c
keychain_fmt_plug.c
keyring_fmt_plug.c
keystore_fmt_plug.c
known_hosts_fmt_plug.c
krb5-18_fmt_plug.c
krb5pa-sha1_fmt_plug.c
kwallet_fmt_plug.c
lastpass_fmt_plug.c
lastpass_sniffed_fmt_plug.c
lotus85_fmt_plug.c
luks_fmt_plug.c
mongodb_fmt_plug.c
mozilla_fmt_plug.c
mysql_netauth_fmt_plug.c
net_md5_fmt_plug.c
net_sha1_fmt_plug.c
nukedclan_fmt_plug.c
o5logon_fmt_plug.c
odf_fmt_plug.c
office_fmt_plug.c
oldoffice_fmt_plug.c
opencl_7z_fmt_plug.c
opencl_agilekeychain_fmt_plug.c
opencl_blockchain_fmt_plug.c
opencl_dmg_fmt_plug.c
opencl_encfs_fmt_plug.c
opencl_gpg_fmt_plug.c
opencl_keychain_fmt_plug.c
opencl_keyring_fmt_plug.c
opencl_krb5pa-sha1_fmt_plug.c
opencl_o5logon_fmt_plug.c
opencl_odf_aes_fmt_plug.c
opencl_odf_fmt_plug.c
opencl_office2007_fmt_plug.c
opencl_office2010_fmt_plug.c
opencl_office2013_fmt_plug.c
opencl_pbkdf2_hmac_sha256_fmt_plug.c
opencl_pbkdf2_hmac_sha512_fmt_plug.c
opencl_pwsafe_fmt_plug.c
opencl_rakp_fmt_plug.c
opencl_rar5_fmt_plug.c
opencl_rawsha256_fmt_plug.c
opencl_rawsha512_fmt_plug.c
opencl_strip_fmt_plug.c
opencl_sxc_fmt_plug.c
opencl_wpapsk_fmt_plug.c
openssl_enc_fmt_plug.c
pbkdf2-hmac-sha1_fmt_plug.c
pbkdf2-hmac-sha512_fmt_plug.c
pbkdf2_hmac_sha256_fmt_plug.c
pdf_fmt_plug.c
pfx_fmt_plug.c
pkzip_fmt_plug.c
postgres_fmt_plug.c
putty_fmt_plug.c
pwsafe_fmt_plug.c
racf_fmt_plug.c
rakp_fmt_plug.c
rar5_fmt_plug.c
rawSHA1_ng_fmt_plug.c
rsvp_fmt_plug.c
siemens-s7_fmt_plug.c
sip_fmt_plug.c
ssh_fmt_plug.c
ssh_ng_fmt_plug.c
strip_fmt_plug.c
sxc_fmt_plug.c
tcp_md5_fmt_plug.c
vms_fmt_plug.c
vnc_fmt_plug.c
vtp_fmt_plug.c
wbb3_fmt_plug.c
wpapsk_fmt_plug.c
magnumripper commented 9 years ago

A canonical salt_hash() could be as follows

static int salt_hash(void *salt)
{
    unsigned char *s = salt;
    unsigned int hash = 5381;
    unsigned int len = SALT_SIZE;

    while (len--)
        hash = ((hash << 5) + hash) ^ *s++;

    return hash & (SALT_HASH_SIZE - 1);
}

However, this is only reliable for fixed-size salts (ie. where we are sure all of SALT_SIZE is really initialized in salt()). Otherwise we need to use something like salt->len instead of SALT_SIZE. Alternatively, there needs to be a memset() in salt() that guarantees nothing in uninitialized.

magnumripper commented 9 years ago

Now, we could change fmt_default_salt_hash() to be like above. That is kinda dangerous but our recently added self-test for salt cleaning should ensure proper function...

...oh, and it can't really be like above, because the SALT_SIZE macro won't be available in formats.c.

kholia commented 9 years ago

Now, we could change fmt_default_salt_hash() to be like above.

:+1:

kholia commented 9 years ago

I really don't want to write such boilerplate code in every format (well, the real reason is that I am a bit lazy).

magnumripper commented 9 years ago

One option is to add a file salt_hash.c that contains the function as above. Any format that wants to use it (and that fits the requirement that if SALT_SIZE has a margin for variable length, the full size HAS to be 'cleaned' for each call to get_salt()) could just #include "salt_hash.c" and then say salt_hash in the format struct definition.

frank-dittrich commented 9 years ago

I'd prefer to put those functions into a .h file.

#ifndef JTR_SALT_HASH_H
#define JTR_SALT_HASH_H
...

There are already some other .h files which include function implementations.

BTW: There are other possible "helper functions" which could be reused this way: -functions verifying that certain ciphertexts elements contain hex values of a given length (range)) -functions for base64 verification

magnumripper commented 9 years ago

Calling it .h is fine with me. But those ifdefs (that are normally crucial for headers) will not do any good in this case, they would just hide bugs.

magnumripper commented 9 years ago

Changing this from bug->enhancement because it really does not affect anything but loader performance. If that.

magnumripper commented 9 years ago

I see no important format among the current list. And this is only about loading a LOT of salts/hashes. Closing.

claudioandre-br commented 6 years ago

These files use SALT_SIZE definition from a header; anyway, they are doing the same as the CPU versions do.

opencl_rawsha256_fmt_plug.c
opencl_rawsha512_gpl_fmt_plug.c