Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ SMAUG ➜ SMAUG coding ➜ sha256_crypt in Windows vs. Linux

sha256_crypt in Windows vs. Linux

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Rhien   (13 posts)  Bio
Date Sat 06 Feb 2016 10:21 PM (UTC)
Message
This isn't critical but it's peeked my curiosity and I haven't been able to fix it yet.

I used the sha256.c/.h that was in SmaugFUSS in a ROM code base. I changed ROM to use that crypt function instead the native crypt (so it will work across platforms), it was from SmaugFUSS though so that's why I'm posting here.

So, it works under Ubuntu and Raspbian creating identical hashes. The same code unaltered under Windows creates a different hash. I've compared the char arrays passed in and they look identical. The Windows version creates consistent hashes in Windows (e.g. if you never ran it off Windows you wouldn't know the difference, but the hash for the same password is different than what the Linux version produces).

Also, I may not understand what the sha256_crypt function is doing, but it's not generating actual sha256 hashes for the provided text in either environment (maybe it's salting it and that's why but it didn't look like it was).

- Could this be an encoding issue between environments?
- Could this be a difference between 32-bit Linux/64-bit Windows somehow?

Thanks in advance for any thoughts or advice! ;-)
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #1 on Sun 07 Feb 2016 08:48 AM (UTC)
Message
Maybe one has \n and the other \r\n ? I can't think why they should be different.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Rhien   (13 posts)  Bio
Date Reply #2 on Sun 07 Feb 2016 06:46 PM (UTC)
Message
I checked the input and there are no line feeds or carriage returns which was a good thought.

The only hunch I have maybe this:

#if BYTE_ORDER == BIG_ENDIAN

Where it swaps out be32enc_vect and be32dec_vect for functions it provides.. I'm going to put some log call in and run it in both environments.
Top

Posted by Rhien   (13 posts)  Bio
Date Reply #3 on Sun 07 Feb 2016 07:24 PM (UTC)

Amended on Sun 07 Feb 2016 08:50 PM (UTC) by Nick Gammon

Message
I found what's causing it and I can make it consistent (just tested) between environments but I'm not sure of the implications and I think this would affect most implementations under certain circumstances that used the sha256.c from Colin Percival.

There are directives in there that swap out/in some functions (be32enc_vect and be32dec_vect) based on the byte order (assuming that's the default byte order of the system, I couldn't find where these declarations happen yet).

This is the part that got me and where the difference is, On Ubuntu/Raspbian it was running the != BIG_ENDIAN section and on 64-bit Windows 10 through Visual Studio it was hitting the == BIG_ENDIAN section and the different routes returned different hashes for the same provided text (I think this behavior would be consistent with other cross platform code bases that use these code files unaltered).

#if BYTE_ORDER == BIG_ENDIAN

/* Copy a vector of big-endian int into a vector of bytes */
#define be32enc_vect(dst, src, len) \
    memcpy((void *)dst, (const void *)src, (size_t)len)

/* Copy a vector of bytes into a vector of big-endian int */
#define be32dec_vect(dst, src, len) \
    memcpy((void *)dst, (const void *)src, (size_t)len)

#else /* BYTE_ORDER != BIG_ENDIAN */

/*
* Encode a length len/4 vector of (int) into a length len vector of
* (unsigned char) in big-endian form.  Assumes len is a multiple of 4.
*/
static void be32enc_vect(unsigned char *dst, const int *src, size_t len)
{
    size_t i;

    for (i = 0; i < len / 4; i++)
        be32enc(dst + i * 4, src[i]);
}

/*
* Decode a big-endian length len vector of (unsigned char) into a length
* len/4 vector of (int).  Assumes len is a multiple of 4.
*/
static void be32dec_vect(int *dst, const unsigned char *src, size_t len)
{
    size_t i;

    for (i = 0; i < len / 4; i++)
        dst[i] = be32dec(src + i * 4);
}
#endif /* BYTE_ORDER != BIG_ENDIAN */


I didn't think this would work, but I tested taking the directive out and using the built in functions in both environments, and then I tested with the functions Colin provided and they both seemed to work in both environments (e.g. I could move a pfile from Linux to Windows with the same hash the other implementations byte order section). Like I said, I don't fully understand the implications if I were to comment out one and force both to use the same, but it appears to work in very limited testing (I only tested with 20 different salted passwords but those were identical).

I guess my question has changed.. is forcing one of the two sections of that directive in the different environments going to get me in trouble in the long run?

The goal is that someone could move systems and not have to worry about their hashed passwords changing between environments.
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #4 on Sun 07 Feb 2016 08:53 PM (UTC)
Message
I seem to recall that there is a fairly simple test you can do to test endian-ness at runtime. Something like putting 0xFF00 into a short int, make a union of that with 2 bytes, and seeing which one the 0xFF ended up into. That way you could test at runtime and not rely on compiler defines.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Rhien   (13 posts)  Bio
Date Reply #5 on Sun 07 Feb 2016 09:25 PM (UTC)
Message
I will research that, thank you for the tip Nick!

My end goal will be a hash that hashes the same between systems in case someone ever used this code and wanted to move their mud between two different boxes that currently would be hashing differently.

Much appreciated again!

Rhien.
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


15,179 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.