On a cryptography list people were complaining that compiler optimizers
mess up their cryptographic code and make it insecure. They try to write code that runs in constant time, or that erases all the temporary storage, but the compilers say oh, that's dead code, or oh, I can make this faster with a few branches and the erases go away and the constatnt time isn't.
This 2018 paper from Cambridge discusses changes they made to Clang/LLVM
so they could tell the compiler what they wanted it to do. Has there been other work on this topic?
John R Levine <johnl@taugh.com> writes:
On a cryptography list people were complaining that compiler optimizersC23 will add the memset_explicit() function :
mess up their cryptographic code and make it insecure. They try to write
code that runs in constant time, or that erases all the temporary storage, >> but the compilers say oh, that's dead code, or oh, I can make this faster
with a few branches and the erases go away and the constatnt time isn't.
This 2018 paper from Cambridge discusses changes they made to Clang/LLVM
so they could tell the compiler what they wanted it to do. Has there been >> other work on this topic?
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.
[C11 has memset_s() which seems more or less the same thing.
I put the wrong link in the previous message. The paper is
here: https://ieeexplore.ieee.org/document/8406587 -John]
On a cryptography list people were complaining that compiler optimizers
mess up their cryptographic code and make it insecure. They try to write code that runs in constant time, or that erases all the temporary storage, but the compilers say oh, that's dead code, or oh, I can make this faster with a few branches and the erases go away and the constatnt time isn't.
This 2018 paper from Cambridge discusses changes they made to Clang/LLVM
so they could tell the compiler what they wanted it to do. Has there been other work on this topic?
C23 will add the memset_explicit() function :[snip]
[C11 has memset_s() which seems more or less the same thing.
...
-John]
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.
[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.
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);
}
| Sysop: | Amessyroom |
|---|---|
| Location: | Fayetteville, NC |
| Users: | 59 |
| Nodes: | 6 (0 / 6) |
| Uptime: | 22:33:18 |
| Calls: | 810 |
| Calls today: | 1 |
| Files: | 1,287 |
| D/L today: |
12 files (21,036K bytes) |
| Messages: | 195,759 |