On Fri, 19 Apr 2024, Zack Weinberg wrote:
> Yes, but the compiler does not know that bzero/explicit_bzero/memset only
> write
> and do not read, which means if you have something like
>
> void aes256_encrypt_in_place(const uint8_t *key, const uint8_t *iv,
> uint8_t *data, size_t len)
> {
> __m128 round_keys[AES256_N_ROUND_KEYS];
> aes256_expand_key(key, round_keys);
> aes256_do_cbc(round_keys, iv, data, len);
> explicit_bzero(round_keys, sizeof round_keys);
> }
>
> and aes256_expand_key and aes256_do_cbc get inlined, the compiler might
> be able to keep the entire key schedule in the vector registers *until*
> the call to explicit_bzero. But right before calling explicit_bzero,
> it will have to copy the round_keys array onto the stack! And the copy
> of round_keys in the vector registers *won't* get erased -- the exact
> problem being discussed in this thread.
On the SYSV ABI, all the vector registers are volatile, so you can erase
them in explicit_bzero.
On Windows 64-bit ABI, it is more problematic, because some of the vector
registers must be preserved.
Mikulas