s390x assembly pack: process x25519 and x448 non-canonical values
authorPatrick Steuer <patrick.steuer@de.ibm.com>
Sat, 2 Nov 2019 23:32:04 +0000 (00:32 +0100)
committerPatrick Steuer <patrick.steuer@de.ibm.com>
Tue, 5 Nov 2019 12:53:04 +0000 (13:53 +0100)
...in constant time.

Signed-off-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10339)

crypto/ec/ecx_meth.c
include/internal/constant_time.h

index 776e88d..d141fe7 100644 (file)
@@ -854,6 +854,7 @@ static const EVP_PKEY_METHOD ed448_pkey_meth = {
 
 #ifdef S390X_EC_ASM
 # include "s390x_arch.h"
+# include "internal/constant_time.h"
 
 static void s390x_x25519_mod_p(unsigned char u[32])
 {
@@ -867,16 +868,16 @@ 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])
@@ -901,14 +902,14 @@ 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],
index d98dae9..dc75e31 100644 (file)
@@ -352,6 +352,34 @@ static ossl_inline void constant_time_cond_swap_64(uint64_t mask, uint64_t *a,
     *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