Fix GMP v4 compatibility. master
authorAustin Seipp <austin@well-typed.com>
Wed, 26 Feb 2014 22:18:20 +0000 (16:18 -0600)
committerAustin Seipp <austin@well-typed.com>
Wed, 26 Feb 2014 22:18:20 +0000 (16:18 -0600)
We had started relying on GMP 5.x (for usage of mpz_powm_sec), but this
is pretty painful on RHEL-esque targets, which still use GMP 4.x.

In the mean time while we're still supporting this, it's easier to just
fallback to mpz_powm when _sec is unavailable, and emit a WARNING for
using the primitive.

This also installs a header, HsIntegerGmp.h, which clients could use for
a fallback.

As a side note, this will probably also help Debian oldstable users who
might have outdated GMP versions (which I believe is the cause for #8666.)

Reviewed-by: Herbert Valerio Riedel <hvr@gnu.org>
Signed-off-by: Austin Seipp <austin@well-typed.com>
.gitignore
GHC/Integer/Type.lhs
aclocal.m4
cbits/gmp-wrappers.cmm
configure.ac
include/HsIntegerGmp.h.in [new file with mode: 0644]
integer-gmp.buildinfo.in
integer-gmp.cabal

index a5e5768..48e9d5e 100644 (file)
@@ -9,3 +9,4 @@ gmp/config.mk
 integer-gmp.buildinfo
 cbits/GmpDerivedConstants.h
 cbits/mkGmpDerivedConstants
+include/HsIntegerGmp.h
index 3fb2ae6..0f408ff 100644 (file)
@@ -18,6 +18,8 @@
 --
 
 #include "MachDeps.h"
+#include "HsIntegerGmp.h"
+
 #if SIZEOF_HSWORD == 4
 #define INT_MINBOUND (-2147483648#)
 #define NEG_INT_MINBOUND (S# 2147483647# `plusInteger` S# 1#)
@@ -826,6 +828,10 @@ powModInteger b e m = powModInteger (toBig b) (toBig e) (toBig m)
 -- channel attacks and is therefore intended for cryptographic
 -- applications.
 --
+-- This primitive is only available when the underlying GMP library
+-- supports it (GMP >= 5). Otherwise, it internally falls back to
+-- @'powModInteger'@, and a warning will be emitted when used.
+--
 -- /Since: 0.5.1.0/
 {-# NOINLINE powModSecInteger #-}
 powModSecInteger :: Integer -> Integer -> Integer -> Integer
@@ -833,6 +839,10 @@ powModSecInteger (J# s1 d1) (J# s2 d2) (J# s3 d3) =
     mpzToInteger (powModSecInteger# s1 d1 s2 d2 s3 d3)
 powModSecInteger b e m = powModSecInteger (toBig b) (toBig e) (toBig m)
 
+#if HAVE_SECURE_POWM == 0
+{-# WARNING powModSecInteger "The underlying GMP library does not support a secure version of powModInteger which is side-channel resistant - you need at least GMP version 5 to support this" #-}
+#endif
+
 -- | \"@'recipModInteger' /x/ /m/@\" computes the inverse of @/x/@ modulo @/m/@. If
 -- the inverse exists, the return value @/y/@ will satisfy @0 < /y/ <
 -- abs(/m/)@, otherwise the result is @0@.
index c174ee2..be24861 100644 (file)
@@ -6,13 +6,18 @@ dnl--------------------------------------------------------------------
 AC_DEFUN([LOOK_FOR_GMP_LIB],[
     if test "$HaveFrameworkGMP" = "NO"
     then
-        AC_CHECK_LIB([gmp],  [__gmpz_powm_sec],
+        AC_CHECK_LIB([gmp],  [__gmpz_powm],
                      [HaveLibGmp=YES; GMP_LIBS=gmp])
         if test "$HaveLibGmp" = "NO"
         then
-            AC_CHECK_LIB([gmp3], [__gmpz_powm_sec],
+            AC_CHECK_LIB([gmp3], [__gmpz_powm],
                          [HaveLibGmp=YES; GMP_LIBS=gmp3])
         fi
+        if test "$HaveLibGmp" = "YES"
+        then
+            AC_CHECK_LIB([$GMP_LIBS], [__gmpz_powm_sec],
+                         [HaveSecurePowm=1])
+        fi
     fi
 ])
 
index 4c7df57..a565251 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "Cmm.h"
 #include "GmpDerivedConstants.h"
+#include "HsIntegerGmp.h"
 
 import "integer-gmp" __gmpz_add;
 import "integer-gmp" __gmpz_add_ui;
@@ -61,7 +62,9 @@ import "integer-gmp" __gmpz_ior;
 import "integer-gmp" __gmpz_com;
 import "integer-gmp" __gmpz_pow_ui;
 import "integer-gmp" __gmpz_powm;
+#if HAVE_SECURE_POWM == 1
 import "integer-gmp" __gmpz_powm_sec;
+#endif
 import "integer-gmp" __gmpz_invert;
 import "integer-gmp" __gmpz_nextprime;
 import "integer-gmp" __gmpz_probab_prime_p;
@@ -629,7 +632,12 @@ GMP_TAKE2_RET2(integer_cmm_divModIntegerzh,         __gmpz_fdiv_qr)
 GMP_TAKE1_UL1_RET2(integer_cmm_divModIntegerWordzh, __gmpz_fdiv_qr_ui)
 
 GMP_TAKE3_RET1(integer_cmm_powModIntegerzh,         __gmpz_powm)
+#if HAVE_SECURE_POWM == 1
 GMP_TAKE3_RET1(integer_cmm_powModSecIntegerzh,      __gmpz_powm_sec)
+#else
+GMP_TAKE3_RET1(integer_cmm_powModSecIntegerzh,      __gmpz_powm)
+#endif
+
 GMP_TAKE2_RET1(integer_cmm_recipModIntegerzh,       __gmpz_invert)
 GMP_TAKE1_UL1_RET1(integer_cmm_powIntegerzh,        __gmpz_pow_ui)
 
index b91154a..d5eb3b2 100644 (file)
@@ -47,6 +47,7 @@ HaveLibGmp=NO
 GMP_LIBS=
 HaveFrameworkGMP=NO
 GMP_FRAMEWORK=
+HaveSecurePowm=0
 
 if test "$GMP_FORCE_INTREE" != "YES"
 then
@@ -74,8 +75,9 @@ AC_SUBST(GMP_LIB_DIRS)
 AC_SUBST(GMP_FRAMEWORK)
 AC_SUBST(HaveLibGmp)
 AC_SUBST(HaveFrameworkGMP)
+AC_SUBST(HaveSecurePowm)
 
-AC_CONFIG_FILES([integer-gmp.buildinfo gmp/config.mk])
+AC_CONFIG_FILES([integer-gmp.buildinfo gmp/config.mk include/HsIntegerGmp.h])
 
 dnl--------------------------------------------------------------------
 dnl * Generate the header cbits/GmpDerivedConstants.h
diff --git a/include/HsIntegerGmp.h.in b/include/HsIntegerGmp.h.in
new file mode 100644 (file)
index 0000000..11c6467
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _HS_INTEGER_GMP_H_
+#define _HS_INTEGER_GMP_H_
+
+#define HAVE_SECURE_POWM @HaveSecurePowm@
+
+#endif /* _HS_INTEGER_GMP_H_ */
index 2f5130d..9b2bad9 100644 (file)
@@ -2,3 +2,4 @@ include-dirs: @GMP_INCLUDE_DIRS@
 extra-lib-dirs: @GMP_LIB_DIRS@
 extra-libraries: @GMP_LIBS@
 frameworks: @GMP_FRAMEWORK@
+install-includes: HsIntegerGmp.h
\ No newline at end of file
index 2473ccb..817a854 100644 (file)
@@ -35,6 +35,7 @@ extra-source-files:
     gmp/config.mk.in
     install-sh
     integer-gmp.buildinfo.in
+    include/HsIntegerGmp.h.in
 
 extra-tmp-files:
     autom4te.cache
@@ -42,6 +43,7 @@ extra-tmp-files:
     config.status
     gmp/config.mk
     integer-gmp.buildinfo
+    include/HsIntegerGmp.h
 
 source-repository head
     type:     git
@@ -73,6 +75,7 @@ Library
         GHC.Integer.Type
 
     c-sources: cbits/cbits.c
+    include-dirs: include
 
     build-depends: ghc-prim >= 0.3.1 && < 0.4