[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Miscompilation under strict C aliasing rules

On 2/24/22 00:42, Quentin Carbonneaux wrote:
Yesterday evening my archival tool started refusing correct
passphrases. A bit of debugging revealed a difference of
behavior in the blockmix_salsa8() function when compiled
with GCC 11.2.0 (straight from the Debian package) with
optimization flags -O3.

Ooh, nasty.  Which version of the scrypt code are you using?  In
particular, the latest version has a self-test which *should*
catch issues like this.

Here is the offending assembly:

The root of the problem is that the store B) resulting
from inlining blkxor() line 134 of blockmix_salsa8 [0]
is forwarded to D). And this despite the call C).

This effectively results in a dysfunctional implementation
of the primitive.

The compiler is technically allowed to forward the store
because blkcpy (and also blkxor) breaks the strict aliasing
rules of C. (See 6.5.7. in the C99 standard, for example.)

On my end, I will replace blkcpy() with memcpy() and have
blkxor() act on bytes. I hope this can be fixed upstream
as well.

We should probably make it operate on uint32_t rather than bytes,
since the data in question is used as arrays of uint32_t elsewhere?

Colin Percival
Security Officer Emeritus, FreeBSD | The power to serve
Founder, Tarsnap | www.tarsnap.com | Online backups for the truly paranoid