1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-03 03:50:58 +00:00

fix(crypto): make ge25519_cmove_stride4b constant time

This commit is contained in:
Ondřej Vejpustek 2024-12-06 12:37:44 +01:00
parent e196413bb7
commit ecc38f267f

View File

@ -389,18 +389,23 @@ void ge25519_double_scalarmult_vartime2(ge25519 *r, const ge25519 *p1, const big
* cause the code to not generate conditional moves. Don't use any -march= * cause the code to not generate conditional moves. Don't use any -march=
* with less than i686 on x86 * with less than i686 on x86
*/ */
static void ge25519_cmove_stride4(long * r, long * p, long * pos, long * n, int stride) { static void ge25519_cmove_stride4(unsigned long * r, unsigned long * p, unsigned long * pos, unsigned long * n, int stride) {
long x0=r[0], x1=r[1], x2=r[2], x3=r[3], y0 = 0, y1 = 0, y2 = 0, y3 = 0; unsigned long x0=r[0], x1=r[1], x2=r[2], x3=r[3], y0 = 0, y1 = 0, y2 = 0, y3 = 0;
for(; p<n; p+=stride) { for(; p<n; p+=stride) {
volatile int flag=(p==pos); volatile int flag=(p==pos);
y0 = p[0]; y0 = p[0];
y1 = p[1]; y1 = p[1];
y2 = p[2]; y2 = p[2];
y3 = p[3]; y3 = p[3];
x0 = flag ? y0 : x0;
x1 = flag ? y1 : x1; const unsigned long mask_y = -flag;
x2 = flag ? y2 : x2; const unsigned long mask_x = ~mask_y;
x3 = flag ? y3 : x3;
// x = flag ? y : x
x0 = (y0 & mask_y) | (x0 & mask_x);
x1 = (y1 & mask_y) | (x1 & mask_x);
x2 = (y2 & mask_y) | (x2 & mask_x);
x3 = (y3 & mask_y) | (x3 & mask_x);
} }
r[0] = x0; r[0] = x0;
r[1] = x1; r[1] = x1;
@ -409,18 +414,23 @@ static void ge25519_cmove_stride4(long * r, long * p, long * pos, long * n, int
} }
#define HAS_CMOVE_STRIDE4 #define HAS_CMOVE_STRIDE4
static void ge25519_cmove_stride4b(long * r, long * p, long * pos, long * n, int stride) { static void ge25519_cmove_stride4b(unsigned long * r, unsigned long * p, unsigned long * pos, unsigned long * n, int stride) {
long x0=p[0], x1=p[1], x2=p[2], x3=p[3], y0 = 0, y1 = 0, y2 = 0, y3 = 0; unsigned long x0=p[0], x1=p[1], x2=p[2], x3=p[3], y0 = 0, y1 = 0, y2 = 0, y3 = 0;
for(p+=stride; p<n; p+=stride) { for(p+=stride; p<n; p+=stride) {
volatile int flag=(p==pos); volatile int flag=(p==pos);
y0 = p[0]; y0 = p[0];
y1 = p[1]; y1 = p[1];
y2 = p[2]; y2 = p[2];
y3 = p[3]; y3 = p[3];
x0 = flag ? y0 : x0;
x1 = flag ? y1 : x1; const unsigned long mask_y = -flag;
x2 = flag ? y2 : x2; const unsigned long mask_x = ~mask_y;
x3 = flag ? y3 : x3;
// x = flag ? y : x
x0 = (y0 & mask_y) | (x0 & mask_x);
x1 = (y1 & mask_y) | (x1 & mask_x);
x2 = (y2 & mask_y) | (x2 & mask_x);
x3 = (y3 & mask_y) | (x3 & mask_x);
} }
r[0] = x0; r[0] = x0;
r[1] = x1; r[1] = x1;
@ -432,12 +442,12 @@ static void ge25519_cmove_stride4b(long * r, long * p, long * pos, long * n, int
void ge25519_move_conditional_pniels_array(ge25519_pniels * r, const ge25519_pniels * p, int pos, int n) { void ge25519_move_conditional_pniels_array(ge25519_pniels * r, const ge25519_pniels * p, int pos, int n) {
#ifdef HAS_CMOVE_STRIDE4B #ifdef HAS_CMOVE_STRIDE4B
size_t i = 0; size_t i = 0;
for(i=0; i<sizeof(ge25519_pniels)/sizeof(long); i+=4) { for(i=0; i<sizeof(ge25519_pniels)/sizeof(unsigned long); i+=4) {
ge25519_cmove_stride4b(((long*)r)+i, ge25519_cmove_stride4b(((unsigned long*)r)+i,
((long*)p)+i, ((unsigned long*)p)+i,
((long*)(p+pos))+i, ((unsigned long*)(p+pos))+i,
((long*)(p+n))+i, ((unsigned long*)(p+n))+i,
sizeof(ge25519_pniels)/sizeof(long)); sizeof(ge25519_pniels)/sizeof(unsigned long));
} }
#else #else
size_t i = 0; size_t i = 0;
@ -449,12 +459,12 @@ void ge25519_move_conditional_pniels_array(ge25519_pniels * r, const ge25519_pni
void ge25519_move_conditional_niels_array(ge25519_niels * r, const uint8_t p[8][96], int pos, int n) { void ge25519_move_conditional_niels_array(ge25519_niels * r, const uint8_t p[8][96], int pos, int n) {
size_t i = 0; size_t i = 0;
for(i=0; i<96/sizeof(long); i+=4) { for(i=0; i<96/sizeof(unsigned long); i+=4) {
ge25519_cmove_stride4(((long*)r)+i, ge25519_cmove_stride4(((unsigned long*)r)+i,
((long*)p)+i, ((unsigned long*)p)+i,
((long*)(p+pos))+i, ((unsigned long*)(p+pos))+i,
((long*)(p+n))+i, ((unsigned long*)(p+n))+i,
96/sizeof(long)); 96/sizeof(unsigned long));
} }
} }