1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-03 12:00:59 +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=
* with less than i686 on x86
*/
static void ge25519_cmove_stride4(long * r, long * p, long * pos, 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;
static void ge25519_cmove_stride4(unsigned long * r, unsigned long * p, unsigned long * pos, unsigned long * n, int stride) {
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) {
volatile int flag=(p==pos);
y0 = p[0];
y1 = p[1];
y2 = p[2];
y3 = p[3];
x0 = flag ? y0 : x0;
x1 = flag ? y1 : x1;
x2 = flag ? y2 : x2;
x3 = flag ? y3 : x3;
const unsigned long mask_y = -flag;
const unsigned long mask_x = ~mask_y;
// 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[1] = x1;
@ -409,18 +414,23 @@ static void ge25519_cmove_stride4(long * r, long * p, long * pos, long * n, int
}
#define HAS_CMOVE_STRIDE4
static void ge25519_cmove_stride4b(long * r, long * p, long * pos, 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;
static void ge25519_cmove_stride4b(unsigned long * r, unsigned long * p, unsigned long * pos, unsigned long * n, int stride) {
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) {
volatile int flag=(p==pos);
y0 = p[0];
y1 = p[1];
y2 = p[2];
y3 = p[3];
x0 = flag ? y0 : x0;
x1 = flag ? y1 : x1;
x2 = flag ? y2 : x2;
x3 = flag ? y3 : x3;
const unsigned long mask_y = -flag;
const unsigned long mask_x = ~mask_y;
// 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[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) {
#ifdef HAS_CMOVE_STRIDE4B
size_t i = 0;
for(i=0; i<sizeof(ge25519_pniels)/sizeof(long); i+=4) {
ge25519_cmove_stride4b(((long*)r)+i,
((long*)p)+i,
((long*)(p+pos))+i,
((long*)(p+n))+i,
sizeof(ge25519_pniels)/sizeof(long));
for(i=0; i<sizeof(ge25519_pniels)/sizeof(unsigned long); i+=4) {
ge25519_cmove_stride4b(((unsigned long*)r)+i,
((unsigned long*)p)+i,
((unsigned long*)(p+pos))+i,
((unsigned long*)(p+n))+i,
sizeof(ge25519_pniels)/sizeof(unsigned long));
}
#else
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) {
size_t i = 0;
for(i=0; i<96/sizeof(long); i+=4) {
ge25519_cmove_stride4(((long*)r)+i,
((long*)p)+i,
((long*)(p+pos))+i,
((long*)(p+n))+i,
96/sizeof(long));
for(i=0; i<96/sizeof(unsigned long); i+=4) {
ge25519_cmove_stride4(((unsigned long*)r)+i,
((unsigned long*)p)+i,
((unsigned long*)(p+pos))+i,
((unsigned long*)(p+n))+i,
96/sizeof(unsigned long));
}
}