Merge #728: Suppress a harmless variable-time optimization by clang in memczero
01993878bb2e7f24f42dac84d6949242143bb7f8 Add test for memczero() (Tim Ruffing) 52a03512c1d800603b5c923c1a28bdba12dadb30 Suppress a harmless variable-time optimization by clang in memczero (Tim Ruffing) Pull request description: ACKs for top commit: jonasnick: ACK 01993878bb2e7f24f42dac84d6949242143bb7f8 Tree-SHA512: ed385f6e3909299b9979254bd0208a9d0c68caa9f57039e392aa0d5424ed8002c13f8c037bfbd2697c2f6b54af5731209eba9725c5e88be3ee3077c159d134e2
This commit is contained in:
commit
4f27e344c6
18
src/tests.c
18
src/tests.c
@ -5166,6 +5166,21 @@ void run_ecdsa_openssl(void) {
|
|||||||
# include "modules/recovery/tests_impl.h"
|
# include "modules/recovery/tests_impl.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void run_memczero_test(void) {
|
||||||
|
unsigned char buf1[6] = {1, 2, 3, 4, 5, 6};
|
||||||
|
unsigned char buf2[sizeof(buf1)];
|
||||||
|
|
||||||
|
/* memczero(..., ..., 0) is a noop. */
|
||||||
|
memcpy(buf2, buf1, sizeof(buf1));
|
||||||
|
memczero(buf1, sizeof(buf1), 0);
|
||||||
|
CHECK(memcmp(buf1, buf2, sizeof(buf1)) == 0);
|
||||||
|
|
||||||
|
/* memczero(..., ..., 1) zeros the buffer. */
|
||||||
|
memset(buf2, 0, sizeof(buf2));
|
||||||
|
memczero(buf1, sizeof(buf1) , 1);
|
||||||
|
CHECK(memcmp(buf1, buf2, sizeof(buf1)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
unsigned char seed16[16] = {0};
|
unsigned char seed16[16] = {0};
|
||||||
unsigned char run32[32] = {0};
|
unsigned char run32[32] = {0};
|
||||||
@ -5299,6 +5314,9 @@ int main(int argc, char **argv) {
|
|||||||
run_recovery_tests();
|
run_recovery_tests();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* util tests */
|
||||||
|
run_memczero_test();
|
||||||
|
|
||||||
secp256k1_rand256(run32);
|
secp256k1_rand256(run32);
|
||||||
printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]);
|
printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]);
|
||||||
|
|
||||||
|
13
src/util.h
13
src/util.h
@ -160,13 +160,16 @@ static SECP256K1_INLINE void *manual_alloc(void** prealloc_ptr, size_t alloc_siz
|
|||||||
SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t;
|
SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Zero memory if flag == 1. Constant time. */
|
/* Zero memory if flag == 1. Flag must be 0 or 1. Constant time. */
|
||||||
static SECP256K1_INLINE void memczero(void *s, size_t len, int flag) {
|
static SECP256K1_INLINE void memczero(void *s, size_t len, int flag) {
|
||||||
unsigned char *p;
|
unsigned char *p = (unsigned char *)s;
|
||||||
unsigned char mask = -(unsigned char)flag;
|
/* Access flag with a volatile-qualified lvalue.
|
||||||
p = (unsigned char *)s;
|
This prevents clang from figuring out (after inlining) that flag can
|
||||||
|
take only be 0 or 1, which leads to variable time code. */
|
||||||
|
volatile int vflag = flag;
|
||||||
|
unsigned char mask = -(unsigned char) vflag;
|
||||||
while (len) {
|
while (len) {
|
||||||
*p ^= *p & mask;
|
*p &= ~mask;
|
||||||
p++;
|
p++;
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user