ec: Add run time code selection for p521 field operations
authorMartin Schwenke <martin@meltin.net>
Wed, 12 May 2021 04:21:58 +0000 (14:21 +1000)
committerPauli <pauli@openssl.org>
Sat, 29 May 2021 06:07:15 +0000 (16:07 +1000)
This is only used if ECP_NISTP521_ASM is defined and this currently
only occurs on PPC64.

This simply chooses the C reference implementation, which will be the
default when custom code is available for certain CPUs.

Only the multiplication and squaring operations are handled, since the
upcoming assembly code only contains those.  This scheme can be easily
extended to handle reduction too.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Signed-off-by: Amitay Isaacs <amitay@ozlabs.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15401)

crypto/ec/build.info
crypto/ec/ecp_nistp521.c

index dbe3a52572128ca10d938621de71b1e95a80d48e..bfd16b326f35ff18faab5270d70874bd18a7d8ef 100644 (file)
@@ -31,7 +31,7 @@ IF[{- !$disabled{asm} -}]
 
   $ECASM_ppc32=
   $ECASM_ppc64=ecp_nistz256.c ecp_nistz256-ppc64.s x25519-ppc64.s
-  $ECDEF_ppc64=ECP_NISTZ256_ASM X25519_ASM
+  $ECDEF_ppc64=ECP_NISTZ256_ASM ECP_NISTP521_ASM X25519_ASM
 
   $ECASM_c64xplus=
 
index e507c1e55cb49187fe38ec86a6d7d9f71a7af140..02bded2b6f785d8c80c1871e7a912128e907bcd9 100644 (file)
@@ -675,8 +675,40 @@ static void felem_reduce(felem out, const largefelem in)
      */
 }
 
-#define felem_square felem_square_ref
-#define felem_mul felem_mul_ref
+#if defined(ECP_NISTP521_ASM)
+void felem_square_wrapper(largefelem out, const felem in);
+void felem_mul_wrapper(largefelem out, const felem in1, const felem in2);
+
+static void (*felem_square_p)(largefelem out, const felem in) =
+    felem_square_wrapper;
+static void (*felem_mul_p)(largefelem out, const felem in1, const felem in2) =
+    felem_mul_wrapper;
+
+void felem_select(void)
+{
+    /* Default */
+    felem_square_p = felem_square_ref;
+    felem_mul_p = felem_mul_ref;
+}
+
+void felem_square_wrapper(largefelem out, const felem in)
+{
+    felem_select();
+    felem_square_p(out, in);
+}
+
+void felem_mul_wrapper(largefelem out, const felem in1, const felem in2)
+{
+    felem_select();
+    felem_mul_p(out, in1, in2);
+}
+
+# define felem_square felem_square_p
+# define felem_mul felem_mul_p
+#else
+# define felem_square felem_square_ref
+# define felem_mul felem_mul_ref
+#endif
 
 static void felem_square_reduce(felem out, const felem in)
 {