Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Sun, 26 Jan 2014 23:32:16 +0100
From: Frank Dittrich <>
Subject: Handling of hashes with different iteration counts

While some hash formats have a fix iteration count, others allow the
iteration count to be configured by sysadmins.
If an input file contains several hashes of the same hash algorithm, but
with different iteration counts, it would be good if john would report
this and allow an easy to select hashes which require CPU time to be
attacked separately.

For some hash algorithms, the iteration count is encoded into the hash
in a human readable way (iteration count/rounds as a decimal number or
as powers of 2), for other hash algorithms, this is less obvious.

To improve the current situation, I think the format interface needs to
be extended.
Each format should define a new function:
unsigned int iteration_count(char * ciphertext)

(I am not sure if some formats need an additional struct fmt_main *self
parameter. I am also not sure if all formats consider a variable
iteration count to be part of the salt, so that we could pass the salt
instead of ciphertext.)

The default function fmt_default_iteration_count should always return 1
and can be used by all functions without a variable iteration count.
(If some algorithms do indeed have multiple iteration counts, e.g., X
iterations of md5, Y iterations of sha1, we could either extend the
format interface by an array of iteration_count functions, or require
the iteration count function to return an array of integers, reporting
the most significant iteration count first, and the least significant
iteration count last.
(May be if we make the additional function(s) optional, and assume NULL
otherwise, we wouldn't even need to adjust each format.
Formats without a variable iteration count just use NULL as the first
iteration count function, functions with 2 independent iteration counts
provide 2 different functions, etc.

In case we allow NULL, john should handle this as if the
fmt_default_iteration_count function had been used.

fmt_default_iteration_count should probably not be called for --test.
In a cracking session, it should be called for all valid hashes which
remain uncracked (after checking the pot file).

If there is a different iteration count, john should print a warning to
stderr and/or the log file, mentioning the lowest and the highest
iteration count. In verbose mode, john could even list the distribution
of hashes across different iteration counts.

To filter hashes below or above a certain iteration count, a new command
line option is requires.
I wouldn't call that new option --iteration-count, because currently
--incremental is the only option starting with letter i, and because
--rounds is shorter (and, so far, there is no other option starting with

--rounds should be used for --show and --show=LEFT as well.
Similar to --salts, --rounds=16 should include all hashes with iteration
counts >= 16, while --rounds=-16 would include iteration counts from 1
to 15.
A list of iteration counts would also be allowed: --rounds=10,12,15.
May be in this case we should allow --rounds=19000-20000 (just be sure
to document whether or not the boundaries are included).

If we decide to support multiple iteration counts, I would suggest using
--rounds= for the most significant iteration count, and --rounds2= for
the second most significant iteration count.
(Formats which have just one iteration count, but a computation time
that also depends on salt size, could then decide to misuse the second
iteration_count function to calculate some pseudo iteration count based
on salt length.)

What do you think? Too much effort for a limited use?

Should I have started discussing that topic on john-users?
(I can either re-post this on john-users, or post a version which skips
some of the possible implementation details and focuses on user
interface enhancements.)


Powered by blists - more mailing lists

Your e-mail address:

Powered by Openwall GNU/*/Linux - Powered by OpenVZ