Re: memcpy is leaking secret data through ZMM vector registers

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

 



On Fri, Apr 19, 2024, at 2:53 PM, Alexander Monakov wrote:
> On Fri, 19 Apr 2024, Zack Weinberg wrote:
>
>> On Fri, Apr 19, 2024, at 2:45 PM, Paul Eggert wrote:
>> > On 4/19/24 11:04, Mikulas Patocka wrote:
>> >> There's already "explicit_bzero", so maybe we could add
>> >> "explicit_memcpy"
>> >
>> > Where would this stop? Wouldn't we also need explicit_memcmp, 
>> > explicit_memmove, explicit_mempcpy, etc.? Pretty much any function that 
>> > looks at memory could have the problem. Even C source code that doesn't 
>> > invoke any C library function could have the problem.
>> 
>> As I recall, one of the arguments for _not_ adding explicit_bzero to glibc
>> was that we couldn't guarantee copies of the secret data wouldn't hang
>> around in registers.
>
> bzero and memset have no reason to read data from memory, they only need
> to overwrite that memory. This makes them different from memcpy.

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.

>> Is a hypothetical function __attribute__((clear_call_clobbered_regs_on_exit))
>> what we need here instead, maybe?
>
> As indicated upthread, there's a non-hypothetical
> __attribute__((zero_call_used_regs)), unless you mean something else?

I didn't know whether "call used" meant what I mean by "call clobbered".
Also, it's not clear to me whether this is bulletproof (under whatever name).

zw




[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux