Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Sun, 23 Aug 2015 22:28:03 +0800
From: Lei Zhang <zhanglei.april@...il.com>
To: john-dev@...ts.openwall.com
Subject: Re: Formats using non-SIMD SHA2 implementations

On Aug 17, 2015, at 3:40 PM, Lei Zhang <zhanglei.april@...il.com> wrote:
> 
> On Aug 17, 2015, at 2:26 PM, magnum <john.magnum@...hmail.com> wrote:
>> 
>> 
>> Cool. Maybe you could do RAR3 too?
> 
> I just took a brief look at it. It seems kind of similar to 7z. I can give it a try.

I'm working on RAR. Most of the tricks applied to 7z can be used on RAR as well. But there's one thing I haven't figured out how to handle.

The scalar code can be briefed as:
-----------------------------------
#define ROUNDS 0x40000
(...)
for (i = 0; i < ROUNDS; i++) {
	(...)
	SHA1_Update(&ctx, RawPsw, RawLength);
	if (i % (ROUNDS / 16) == 0) {
		tempctx = ctx;
		SHA1_Final(tempout, &tempctx);
		aes_iv[i16 + i / (ROUNDS / 16)] = tempout[19];
	}
}
SHA1_Final((unsigned char*)digest, &ctx);
-----------------------------------

The code in the if statement is what bothers me. It's supposed to be executed when i = 0, ROUNDS/16, 2*ROUNDS/16, etc. Let's take i = ROUNDS/16 as an example. In this round, the length of data we've hashed so far is RawLength*(ROUNDS/16 + 1), which is unlikely a multiple of 64. But I can only call SIMDSHA1body() when I accumulated multiple blocks of data (64 bytes each).

OTOH, RawLength*ROUNDS/16 is a multiple of 64, which is what we get when i = (ROUNDS/16 - 1). So at round ROUNDS/16, we've already got the digest of the first RawLength*ROUNDS/16 bytes of data; we just need to continue to compute digest on the remaining RawLength bytes. This cannot be done with SIMDSHA1body() because RawLength is probably not divisible by 64. I'm thinking about using OpenSSL's SHA1 functions to do this job, but I don't know if it's doable.


I might not have stated my problem clearly... I'll sum it up here: suppose I have a message of length (A + B) and I've already compute the hash of the first A bytes which is H(A); given only H(A) and the remaining B bytes of data, can I compute the hash of the entire message, i.e. H(A + B) ?

I want to use OpenSSL's SHA function to do this, but I don't see such an interface provided. This is already in use in JtR's SIMD SHA implementation (with the SSEi_RELOAD flag), so I think it's technically doable in OpenSSL. Do I need to hack SHA_CTX somehow?


Thanks,
Lei

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.