diff --git a/.gitignore b/.gitignore index a5e57689947987467b6b92edbd87398bf30abfc2..48e9d5ebfb97f79d95b32ede154bd6e6617dd16e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ gmp/config.mk integer-gmp.buildinfo cbits/GmpDerivedConstants.h cbits/mkGmpDerivedConstants +include/HsIntegerGmp.h diff --git a/GHC/Integer/Type.lhs b/GHC/Integer/Type.lhs index 3fb2ae67ec7f53606d5d5ae238e606c7788edff0..0f408ff0a0eaa84333f852d9cef4d7ef2855e74b 100644 --- a/GHC/Integer/Type.lhs +++ b/GHC/Integer/Type.lhs @@ -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@. diff --git a/aclocal.m4 b/aclocal.m4 index c174ee2c06e2fe273717015cacc192488cff77f0..be248615f5835ab6bf5b72488b61f50f9166eb0b 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -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 ]) diff --git a/cbits/gmp-wrappers.cmm b/cbits/gmp-wrappers.cmm index 4c7df574e757ddd3e4026a785171070994d2540a..a5652511bd962df57896fd8f1e6d5b6f3905e3b2 100644 --- a/cbits/gmp-wrappers.cmm +++ b/cbits/gmp-wrappers.cmm @@ -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) diff --git a/configure.ac b/configure.ac index b91154aac9b0150e9a3fe6cf38d05c1e224ee42a..d5eb3b23d30ded579fef359f899dee95a4ad3713 100644 --- a/configure.ac +++ b/configure.ac @@ -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 index 0000000000000000000000000000000000000000..11c64677e890cba1a791822677fc7e03c97fa893 --- /dev/null +++ b/include/HsIntegerGmp.h.in @@ -0,0 +1,6 @@ +#ifndef _HS_INTEGER_GMP_H_ +#define _HS_INTEGER_GMP_H_ + +#define HAVE_SECURE_POWM @HaveSecurePowm@ + +#endif /* _HS_INTEGER_GMP_H_ */ diff --git a/integer-gmp.buildinfo.in b/integer-gmp.buildinfo.in index 2f5130d12de880a97f2c1ef53811b6a683034e35..9b2bad99d770f1e4056f4a6c120f2ab8a0dec97b 100644 --- a/integer-gmp.buildinfo.in +++ b/integer-gmp.buildinfo.in @@ -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 diff --git a/integer-gmp.cabal b/integer-gmp.cabal index 2473ccb0e1adab9335cd37d6f5b7a0c35d9c7229..817a854e72f5c6fc37ff508cb47e1e6db8455339 100644 --- a/integer-gmp.cabal +++ b/integer-gmp.cabal @@ -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