Skip to content

Commit

Permalink
clear-stack: also consider canary (not only ==0) to handle diff. -sta…
Browse files Browse the repository at this point in the history
…ck-zeroization-size
  • Loading branch information
tfaoliveira committed Dec 4, 2023
1 parent a68d106 commit d686bd6
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 26 deletions.
46 changes: 36 additions & 10 deletions test/common/clearstack-amd64.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,33 @@

//

#define cs_recover_stack_debug(stack_pointer, recover_array, max_size) \
{ for(size_t __i=0; __i<(max_size+CANARY_LENGTH); __i++) { recover_array[__i] = stack_pointer[__i]; } \
printf("stack_pointer: %p\n", stack_pointer); \
}

#define cs_check_stack_zeros_debug(recovered_array, canary_array, max_size) \
{ printf("stack_max_size: %d\n", max_size); \
size_t __i, __j, __dirty = 0; \
for(__i=0, __j=0; __i< max_size; __i++) \
{ if( (recovered_array[__i + CANARY_LENGTH] != 0) ) \
{ __dirty = 1; \
if(__i != 0 && __j != __i) { printf("(%zu..%zu)@0, ", __j, __i-1); } \
printf("(%zu)@%x, ", __i, recovered_array[__i + CANARY_LENGTH]); \
__j = __i+1; \
} \
} \
if(__j != __i) { printf("(%zu..%zu)@0", __j, __i-1); } \
printf("\n\n"); \
assert(__dirty == 0); \
}

//

#define cs_init_randombytes_for_canary(position) initrandombytes2(position);

//

#define cs_declare(stack_pointer, canary_array, recover_array, max_size) \
uint8_t *stack_pointer; \
uint8_t canary_array[CANARY_LENGTH + max_size]; \
Expand All @@ -24,7 +51,7 @@
stack_pointer = (uint8_t*) ( ((uint64_t) stack_pointer) & (-(((uint64_t)alignment)>>3)) );

#define cs_init_canary(canary_array, max_size) \
{ randombytes(canary_array, max_size+CANARY_LENGTH); }
{ randombytes2(canary_array, max_size+CANARY_LENGTH); }

#define cs_init_stack(stack_pointer, canary_array, max_size) \
{ for(size_t __i=0; __i<(max_size+CANARY_LENGTH); __i++) { stack_pointer[__i] = canary_array[__i]; } }
Expand All @@ -42,19 +69,18 @@
#define cs_check_stack_canary(recovered_array, canary_array) \
{ for(size_t __i=0; __i<(CANARY_LENGTH); __i++) { assert(recovered_array[__i] == canary_array[__i]); } }

#define cs_check_stack_zeros(recovered_array, max_size) \
{ for(size_t __i=0; __i< max_size; __i++) { assert( recovered_array[__i + CANARY_LENGTH] == 0 ); } }
#define cs_check_stack_zeros_or_canary(recovered_array, canary_array, max_size) \
{ for(size_t __i=0; __i< max_size; __i++) \
{ assert( (recovered_array[__i + CANARY_LENGTH] == 0) || (recovered_array[__i + CANARY_LENGTH] == canary_array[__i + CANARY_LENGTH]) ); } \
}

#define cs_recover_and_check(stack_pointer, recover_array, canary_array, max_size) \
cs_recover_stack(stack_pointer, recover_array, max_size) \
cs_check_stack_zeros(recover_array, max_size)
cs_check_stack_zeros_or_canary(recover_array, canary_array, max_size)

#if 0
#define cs_recover_and_check(stack_pointer, recover_array, canary_array, max_size) \
cs_recover_stack(stack_pointer, recover_array, max_size) \
cs_check_stack_canary(recover_array, canary_array) \
cs_check_stack_zeros(recover_array, max_size)
#endif
#define cs_recover_and_check_debug(stack_pointer, recover_array, canary_array, max_size) \
cs_recover_stack_debug(stack_pointer, recover_array, max_size) \
cs_check_stack_zeros_debug(recover_array, canary_array, max_size)

#endif

40 changes: 34 additions & 6 deletions test/common/notrandombytes.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,19 +161,22 @@ static int crypto_rng(
return 0;
}


// ////////////////////////////////////////////////////////////////////////////


static uint8_t g0[KEYBYTES];
static uint8_t g1[KEYBYTES];

static uint8_t r0[OUTPUTBYTES];
static uint8_t r1[OUTPUTBYTES];

static uint64_t pos0 = OUTPUTBYTES;

static uint8_t g1[KEYBYTES];
static uint8_t r1[OUTPUTBYTES];
static uint64_t pos1 = OUTPUTBYTES;

static uint8_t g2[KEYBYTES];
static uint8_t r2[OUTPUTBYTES];
static uint64_t pos2 = OUTPUTBYTES;

// ////////////////////////////////////////////////////////////////////////////

static void randombytes_internal(
uint8_t *x, uint64_t xlen,
uint8_t *g, uint8_t *r,
Expand Down Expand Up @@ -222,6 +225,31 @@ void randombytes1(uint8_t* x, uint64_t xlen)

// ////////

void initrandombytes2(int position)
{
uint8_t k[KEYBYTES];

memset(k, 0, KEYBYTES);
while(position-- > 0)
{ randombytes2(k, KEYBYTES); }

pos2 = OUTPUTBYTES;
memcpy(g2, k, KEYBYTES);
}

void resetrandombytes2(void)
{
pos2 = OUTPUTBYTES;
memset(g2, 0, KEYBYTES);
}

void randombytes2(uint8_t* x, uint64_t xlen)
{
randombytes_internal(x,xlen,g2,r2,&pos2);
}

// ////////

uint8_t* __jasmin_syscall_randombytes__(uint8_t* x, uint64_t xlen)
{
randombytes(x, xlen);
Expand Down
4 changes: 4 additions & 0 deletions test/common/randombytes.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ void randombytes(uint8_t* x, uint64_t xlen);
void resetrandombytes1(void);
void randombytes1(uint8_t* x, uint64_t xlen);

void initrandombytes2(int position);
void resetrandombytes2(void);
void randombytes2(uint8_t* x, uint64_t xlen);

//

uint8_t* __jasmin_syscall_randombytes__(uint8_t* _x, uint64_t xlen) __asm__("__jasmin_syscall_randombytes__");
Expand Down
41 changes: 31 additions & 10 deletions test/crypto_kem/clearstack-amd64.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,24 @@
int main(void)
{
int r;

//
uint8_t public_key[JADE_KEM_PUBLICKEYBYTES];
uint8_t secret_key[JADE_KEM_SECRETKEYBYTES];

uint8_t shared_secret_a[JADE_KEM_BYTES];
uint8_t ciphertext[JADE_KEM_CIPHERTEXTBYTES];
uint8_t shared_secret_b[JADE_KEM_BYTES];

// arrays for the derand trace
uint8_t keypair_coins[JADE_KEM_KEYPAIRCOINBYTES];
uint8_t enc_coins[JADE_KEM_ENCCOINBYTES];
uint8_t public_key_derand[JADE_KEM_PUBLICKEYBYTES];
uint8_t secret_key_derand[JADE_KEM_SECRETKEYBYTES];
uint8_t shared_secret_a_derand[JADE_KEM_BYTES];
uint8_t ciphertext_derand[JADE_KEM_CIPHERTEXTBYTES];
uint8_t shared_secret_b_derand[JADE_KEM_BYTES];

cs_init_randombytes_for_canary(1);

cs_declare(rsp0, ca0, ra0, jade_kem_keypair_STACK_MAX_SIZE);
cs_declare(rsp1, ca1, ra1, jade_kem_keypair_derand_STACK_MAX_SIZE);
Expand All @@ -102,7 +111,11 @@ int main(void)

for(size_t tests=0; tests < TESTS; tests++)
{
// create key pair
// coins for derand API
randombytes1(keypair_coins, JADE_KEM_KEYPAIRCOINBYTES);
randombytes1(enc_coins, JADE_KEM_ENCCOINBYTES);

// key pair
cs_init(rsp0, jade_kem_keypair_STACK_MAX_SIZE, jade_kem_keypair_STACK_ALIGNMENT, ca0)
r = jade_kem_keypair(public_key, secret_key);
cs_recover_and_check(rsp0, ra0, ca0, jade_kem_keypair_STACK_MAX_SIZE)
Expand All @@ -121,27 +134,35 @@ int main(void)
assert(r == 0);
assert(memcmp(shared_secret_a, shared_secret_b, JADE_KEM_BYTES) == 0);

// create key pair using derand function (random coins are given as input)
randombytes(keypair_coins, JADE_KEM_KEYPAIRCOINBYTES);
// /////////////////////////////////////////////////////////////////////////

// key pair derand
cs_init(rsp1, jade_kem_keypair_derand_STACK_MAX_SIZE, jade_kem_keypair_derand_STACK_ALIGNMENT, ca1)
r = jade_kem_keypair_derand(public_key, secret_key, keypair_coins);
r = jade_kem_keypair_derand(public_key_derand, secret_key_derand, keypair_coins);
cs_recover_and_check(rsp1, ra1, ca1, jade_kem_keypair_derand_STACK_MAX_SIZE)
assert(r == 0);

// encapsulate using derand function (random coins are given as input)
randombytes(enc_coins, JADE_KEM_ENCCOINBYTES);
// assert that the same key pair was generated (same coins: randombytes ~ randombytes1)
assert(memcmp(public_key_derand, public_key, JADE_KEM_PUBLICKEYBYTES) == 0);
assert(memcmp(secret_key_derand, secret_key, JADE_KEM_SECRETKEYBYTES) == 0);


// encapsulate derand
cs_init(rsp3, jade_kem_enc_derand_STACK_MAX_SIZE, jade_kem_enc_derand_STACK_ALIGNMENT, ca3)
r = jade_kem_enc_derand(ciphertext, shared_secret_a, public_key, enc_coins);
r = jade_kem_enc_derand(ciphertext_derand, shared_secret_a_derand, public_key_derand, enc_coins);
cs_recover_and_check(rsp3, ra3, ca3, jade_kem_enc_derand_STACK_MAX_SIZE)
assert(r == 0);

// assert that same ciphertext and shared secret was generated
assert(memcmp(ciphertext_derand, ciphertext, JADE_KEM_CIPHERTEXTBYTES) == 0);
assert(memcmp(shared_secret_a_derand, shared_secret_a, JADE_KEM_BYTES) == 0);

// decapsulate
cs_init(rsp4, jade_kem_dec_STACK_MAX_SIZE, jade_kem_dec_STACK_ALIGNMENT, ca4)
r = jade_kem_dec(shared_secret_b, ciphertext, secret_key);
r = jade_kem_dec(shared_secret_b_derand, ciphertext_derand, secret_key_derand);
cs_recover_and_check(rsp4, ra4, ca4, jade_kem_dec_STACK_MAX_SIZE)
assert(r == 0);
assert(memcmp(shared_secret_a, shared_secret_b, JADE_KEM_BYTES) == 0);
assert(memcmp(shared_secret_b_derand, shared_secret_a, JADE_KEM_BYTES) == 0);
}


Expand Down

0 comments on commit d686bd6

Please sign in to comment.