Related articles |
---|
Crypto friendly optimization? johnl@taugh.com (John R Levine) (2024-08-24) |
Re: Crypto friendly optimization? Keith.S.Thompson+u@gmail.com (Keith Thompson) (2024-08-24) |
Re: Crypto friendly optimization? ianlancetaylor@gmail.com (Ian Lance Taylor) (2024-08-24) |
Re: Crypto friendly optimization? Keith.S.Thompson+u@gmail.com (Keith Thompson) (2024-08-24) |
Re: Crypto friendly optimization? david.brown@hesbynett.no (David Brown) (2024-08-25) |
Re: Crypto friendly optimization? anton@mips.complang.tuwien.ac.at (2024-08-25) |
Re: Crypto friendly optimization? david.brown@hesbynett.no (David Brown) (2024-08-25) |
From: | David Brown <david.brown@hesbynett.no> |
Newsgroups: | comp.compilers |
Date: | Sun, 25 Aug 2024 21:12:36 +0200 |
Organization: | Compilers Central |
References: | 24-08-003 24-08-004 24-08-008 |
Injection-Info: | gal.iecc.com; posting-host="news.iecc.com:2001:470:1f07:1126:0:676f:7373:6970"; logging-data="72455"; mail-complaints-to="abuse@iecc.com" |
Keywords: | C, optimize, standards |
Posted-Date: | 25 Aug 2024 15:32:44 EDT |
In-Reply-To: | 24-08-008 |
On 25/08/2024 18:06, anton@mips.complang.tuwien.ac.at wrote:
> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>> C23 will add the memset_explicit() function :
>>
>> The memset_explicit function copies the value of c (converted to an
>> unsigned char) into each of the first n characters of the object
>> pointed to by s. The purpose of this function is to make sensitive
>> information stored in the object inaccessible.
>>
>> I'm not aware of any current implementations that support it.
>
> That's trivial:
>
> void *memset_explicit( void *dest, int ch, size_t count )
> {
> memset(dest, ch, count);
> }
>
> Yes, calls to such a memset_explicit() can be eliminated by an
> adversarial compiler, but this makes such an implementation ideal for
> such a compiler: there is nothing faster than an eliminated call, and
> it satisfies the specification. After all, if the data stored in the
> area overwritten by memset_explicit is not accessible by a standard C
> program without exercising undefined behaviour (a scenario ignored by
> adversarial compilers), memset_explicit() does not change that, so an
> adversarial compiler can "optimize" it away. And if the memory is
> accessible by a standard program, the compiler will not eliminate a
> call to memset(), either.
>
> Does it satisfy the purpose? No, but it does wrt the C abstract
> machine something that is equivalent (given the as-if rule and
> assuming that no undefined behaviour is exercised) to the
> specification, and that's the justification used for every misdeed of
> adversarial compilers.
Did you bother to /read/ the C23 standard specification for
memset_explicit()?
The C23 standard explicitly says "The purpose of this function is to
make sensitive information stored in the object inaccessible" and "The
intention is that the memory store is always performed (i.e. never
elided), regardless of optimizations. This is in contrast to calls to
the memset function".
So no, your silly implementation is not sufficient. It can be
implemented using volatile :
void *memset_explicit(void *s, int c, size_t n) {
volatile unsigned char * p = s;
while (n--) *p++ = c;
}
Or it can use "compiler magic", which makes sense for efficiency.
>
>> [C11 has memset_s() which seems more or less the same thing.
>
> Yes, someone told me that memset_s() is the solution to the problem of
> clearing memory reliably. Given that, why have they added
> memset_explicit()? The specification of memset_s() contains:
>
> |Unlike memset, any call to the memset_s function shall be evaluated
> |strictly according to the rules of the abstract machine as described
> |in (5.1.2.3). That is, any call to the memset_s function shall assume
> |that the memory indicated by s and n may be accessible in the future
> |and thus must contain the values indicated by c.
>
> In <2016Nov14.184256@mips.complang.tuwien.ac.at> I wrote about that:
> |Now, everything else (including memset()) in the standard also is
> |evaluated according to the rules of the abstract machine, and the
> |"optimization" comes in afterwards, applies the as-if rule, and poof,
> |memset() is gone, and so is memset_s().
>
> Could it be that compilers do this with memset_s() and that's why C23
> has added memset_explicit()? And I expect that the same will happen
> to memset_explicit(), too.
No, it could /not/ be that.
The reality is that the "Annex K" functions have never been part of any
mainstream implementation. They were an overly complicated attempted
solution for "safer" standard library functions that were supposed to
work by adding an extra unnecessary parameter that is, for most of the
Annex K functions, useless. So compilers generally don't do /anything/
with "memset_s", because it doesn't exist in any but a very few standard
libraries. But any compliant C implementation that supported the
function, would do so in the specified manner.
So memset_explicit() will be a good solution to the OP's problem, once
it becomes readily available. memset_s() would also work, but be less
elegant, if anyone implemented it. (memset_explit() has the big
advantage of not being optional in standard C23.)
(Of course as we all know, zeroing out temporary storage at this level
does not mean the sensitive data is removed from caches, backing memory,
swap space, or anything else - but that's another matter.)
Return to the
comp.compilers page.
Search the
comp.compilers archives again.