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: [snip] 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
