#ifdef S390X_EC_ASM
# include "s390x_arch.h"
+# include "internal/constant_time.h"
static void s390x_x25519_mod_p(unsigned char u[32])
{
u_red[31] = (unsigned char)c;
c >>= 8;
- for (i = 30; c > 0 && i >= 0; i--) {
+ for (i = 30; i >= 0; i--) {
c += (unsigned int)u_red[i];
u_red[i] = (unsigned char)c;
c >>= 8;
}
- if (u_red[0] & 0x80) {
- u_red[0] &= 0x7f;
- memcpy(u, u_red, sizeof(u_red));
- }
+ c = (u_red[0] & 0x80) >> 7;
+ u_red[0] &= 0x7f;
+ constant_time_cond_swap_buff(0 - (unsigned char)c,
+ u, u_red, sizeof(u_red));
}
static void s390x_x448_mod_p(unsigned char u[56])
u_red[27] = (unsigned char)c;
c >>= 8;
- for (i = 26; c > 0 && i >= 0; i--) {
+ for (i = 26; i >= 0; i--) {
c += (unsigned int)u_red[i];
u_red[i] = (unsigned char)c;
c >>= 8;
}
- if (c)
- memcpy(u, u_red, sizeof(u_red));
+ constant_time_cond_swap_buff(0 - (unsigned char)c,
+ u, u_red, sizeof(u_red));
}
static int s390x_x25519_mul(unsigned char u_dst[32],
*b ^= xor;
}
+/*
+ * mask must be 0xFF or 0x00.
+ * "constant time" is per len.
+ *
+ * if (mask) {
+ * unsigned char tmp[len];
+ *
+ * memcpy(tmp, a, len);
+ * memcpy(a, b);
+ * memcpy(b, tmp);
+ * }
+ */
+static ossl_inline void constant_time_cond_swap_buff(unsigned char mask,
+ unsigned char *a,
+ unsigned char *b,
+ size_t len)
+{
+ size_t i;
+ unsigned char tmp;
+
+ for (i = 0; i < len; i++) {
+ tmp = a[i] ^ b[i];
+ tmp &= mask;
+ a[i] ^= tmp;
+ b[i] ^= tmp;
+ }
+}
+
/*
* table is a two dimensional array of bytes. Each row has rowsize elements.
* Copies row number idx into out. rowsize and numrows are not considered