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.3k stars 2.1k forks source link

gpg reports wrong tunable costs ("iteration count") #1202

Closed frank-dittrich closed 9 years ago

frank-dittrich commented 9 years ago

@kholia Solar pointed out that my implementation of tunable cost reporting for gpg is wrong: http://thread.gmane.org/gmane.comp.security.openwall.john.devel/11100 http://www.openwall.com/lists/john-dev/2015/04/05/5

I simply returned salt->count as the first tunable cost (and called it "iteration count"), because I didn't realize that this isn't the iteration count. Also, I totally ignored salt->spec, even though I should report tunable costs only for SPEC_ITERATED_SALTED (and report dummy costs for SPEC_SIMPLE and SPEC_SALTED).

I looked at gpg2john.c, and noticed (for type = 3):

            count = (16 + (c & 15)) << ((c >> 4) + EXPBIAS);
            // printf("\t\tCount - %d(coded count %d)\n", count, c);

Looks like count (i.e., the count that gets written to the gpg format hash by gpg2john and ends up being cur_salt->count corresponds to gpg's --s2k-count n, see man gpg:

       --s2k-count n
              Specify how many  times  the  passphrase  mangling  is
              repeated.   This  value  may  range  between  1024 and
              65011712 inclusive.  The default is inquired from gpg-
              agent.   Note that not all values in the 1024-65011712
              range are legal and if an illegal value  is  selected,
              GnuPG  will round up to the nearest legal value.  This
              option is only meaningful if --s2k-mode is 3.

While gpg --key-gen with default parameters results in count 65536, `gpg --key-gen --s2k-count 262144 results in a count 262144 in the gpg format hash.

In gpg_fmt_plug.c, I did find

532:        n = cur_salt->count / bs;
536:        SHA1_Update(&ctx, keybuf, cur_salt->count % bs);
577:        n = cur_salt->count / bs;
581:        SHA256_Update(&ctx, keybuf, cur_salt->count % bs);
621:        n = cur_salt->count / bs;
625:        SHA512_Update(&ctx, keybuf, cur_salt->count % bs);
665:        n = cur_salt->count / bs;
669:        RIPEMD160_Update(&ctx, keybuf, cur_salt->count % bs);
708:        n = cur_salt->count / bs;
712:        MD5_Update(&ctx, keybuf, cur_salt->count % bs);

So it looks like count isn't an iteration count, but rather the number of bytes to be processed by SHA1/SHA256/... If so, why is this called SPEC_ITERATED_SALTED, if it doesn't appear to be iterated? What am I missing. Can you clarify (or even fix) how tunable costs should be reported for gpg and gpg-opencl?

kholia commented 9 years ago

@frank-dittrich Hi!

frank-dittrich commented 9 years ago

In commit https://github.com/magnumripper/JohnTheRipper/commit/24bc0b53dec316613551b1da078a060cb4ae091b, I renamed the first tunable cost from "iteration count" to "s2k-count", so that you might find the gpg man page describing --s2k-count n or other relevant information via google. For --s2k-mode 0, I report 0 as a tunable cost, for --s2k-mode 1, I report 1. I left reporting of the second and the third tunable cost unchanged. The hash algorithm is reported as the second tunable cost, the cipher algorithm as the third.