summaryrefslogtreecommitdiff
path: root/plugins/MirOTR/Libgcrypt/mpi
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/MirOTR/Libgcrypt/mpi')
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/amd64/mpih-mul2.S43
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/asm-syntax.h71
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/config.links97
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/ec-ed25519.c37
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/ec-internal.h25
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/ec.c1241
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/generic/mpi-asm-defs.h16
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/longlong.h251
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mod-source-info.h12
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpi-add.c23
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpi-asm-defs.h16
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpi-bit.c134
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpi-cmp.c63
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpi-div.c12
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpi-gcd.c14
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpi-inline.c3
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpi-inline.h9
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpi-internal.h6
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpi-inv.c7
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpi-mod.c31
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpi-mpow.c9
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpi-mul.c15
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpi-pow.c547
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpi-scan.c134
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpicoder.c511
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpih-add1-asm.S63
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpih-div.c11
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpih-lshift-asm.S77
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpih-mul.c21
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpih-mul1-asm.S65
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpih-mul2-asm.S64
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpih-mul3-asm.S66
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpih-rshift-asm.S80
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpih-sub1-asm.S61
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/mpiutil.c363
-rw-r--r--plugins/MirOTR/Libgcrypt/mpi/sysdep.h6
36 files changed, 3268 insertions, 936 deletions
diff --git a/plugins/MirOTR/Libgcrypt/mpi/amd64/mpih-mul2.S b/plugins/MirOTR/Libgcrypt/mpi/amd64/mpih-mul2.S
index 1180f7602f..a332a1d047 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/amd64/mpih-mul2.S
+++ b/plugins/MirOTR/Libgcrypt/mpi/amd64/mpih-mul2.S
@@ -31,49 +31,6 @@
#include "sysdep.h"
#include "asm-syntax.h"
-
-/*******************
- * mpi_limb_t
- * _gcry_mpih_addmul_2( mpi_ptr_t res_ptr, (sp + 4)
- * mpi_ptr_t s1_ptr, (sp + 8)
- * mpi_size_t s1_size, (sp + 12)
- * mpi_limb_t s2_limb) (sp + 16)
- */
-
- /* i80386 addmul_1 -- Multiply a limb vector with a limb and add
- * the result to a second limb vector.
- *
- * Copyright (C) 1992, 1994, 1998,
- * 2001, 2002 Free Software Foundation, Inc.
- *
- * This file is part of Libgcrypt.
- *
- * Libgcrypt is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * Libgcrypt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * Note: This code is heavily based on the GNU MP Library.
- * Actually it's the same code with only minor changes in the
- * way the data is stored; this is to support the abstraction
- * of an optional secure memory allocation which may be used
- * to avoid revealing of sensitive data due to paging etc.
- */
-
-
-#include "sysdep.h"
-#include "asm-syntax.h"
-
-
/*******************
* mpi_limb_t
* _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (rdi)
diff --git a/plugins/MirOTR/Libgcrypt/mpi/asm-syntax.h b/plugins/MirOTR/Libgcrypt/mpi/asm-syntax.h
new file mode 100644
index 0000000000..5d8dfeedd4
--- /dev/null
+++ b/plugins/MirOTR/Libgcrypt/mpi/asm-syntax.h
@@ -0,0 +1,71 @@
+/* created by config.links - do not edit */
+/* Host: x86_64-pc-mingw32 */
+#define ELF_SYNTAX
+/* syntax.h -- Definitions for x86 syntax variations.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#undef ALIGN
+
+#if defined (BSD_SYNTAX) || defined (ELF_SYNTAX)
+#define R(r) %r
+#define MEM(base)(base)
+#define MEM_DISP(base,displacement)displacement(R(base))
+#define MEM_INDEX(base,index,size)(R(base),R(index),size)
+#ifdef __STDC__
+#define INSN1(mnemonic,size_suffix,dst)mnemonic##size_suffix dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic##size_suffix src,dst
+#else
+#define INSN1(mnemonic,size_suffix,dst)mnemonic/**/size_suffix dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic/**/size_suffix src,dst
+#endif
+#define TEXT .text
+#if defined (BSD_SYNTAX)
+#define ALIGN(log) .align log
+#endif
+#if defined (ELF_SYNTAX)
+#define ALIGN(log) .align 1<<(log)
+#endif
+#define GLOBL .globl
+#endif
+
+#ifdef INTEL_SYNTAX
+#define R(r) r
+#define MEM(base)[base]
+#define MEM_DISP(base,displacement)[base+(displacement)]
+#define MEM_INDEX(base,index,size)[base+index*size]
+#define INSN1(mnemonic,size_suffix,dst)mnemonic dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic dst,src
+#define TEXT .text
+#define ALIGN(log) .align log
+#define GLOBL .globl
+#endif
+
+#ifdef X86_BROKEN_ALIGN
+#undef ALIGN
+#define ALIGN(log) .align log,0x90
+#endif
diff --git a/plugins/MirOTR/Libgcrypt/mpi/config.links b/plugins/MirOTR/Libgcrypt/mpi/config.links
index 79506379d5..f44299df17 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/config.links
+++ b/plugins/MirOTR/Libgcrypt/mpi/config.links
@@ -1,5 +1,6 @@
# config.links - helper for ../configure -*- mode: sh -*-
# Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+# Copyright (C) 2012 g10 Code GmbH
#
# This file is part of Libgcrypt.
#
@@ -20,9 +21,14 @@
# sourced by ../configure to get the list of files to link
# this should set $mpi_ln_list.
# Note: this is called from the above directory.
+#
+# Reguired variables:
+# $ac_cv_sys_symbol_underscore
+# $gcry_cv_gcc_arm_platform_as_ok
mpi_sflags=
mpi_extra_modules=
+mpi_cpu_arch=
test -d ./mpi || mkdir ./mpi
@@ -37,13 +43,12 @@ mpi_optional_modules=`$AWK '/^#BEGIN_ASM_LIST/,/^#END_ASM_LIST/ {
echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h
echo "/* Host: ${host} */" >>./mpi/asm-syntax.h
-if test "$try_asm_modules" = "yes" ; then
case "${host}" in
- powerpc-apple-darwin* | \
i[34567]86*-*-openbsd[12]* | \
i[34567]86*-*-openbsd3.[0123]*)
echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
path=""
+ mpi_cpu_arch="x86"
;;
i[3467]86*-*-openbsd* | \
i[3467]86*-*-freebsd*-elf | \
@@ -54,6 +59,7 @@ case "${host}" in
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i386"
+ mpi_cpu_arch="x86"
;;
i586*-*-openbsd* | \
i586*-*-freebsd*-elf | \
@@ -66,11 +72,13 @@ case "${host}" in
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i586 i386"
+ mpi_cpu_arch="x86"
;;
i[34]86*-*-bsdi4*)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i386"
+ mpi_cpu_arch="x86"
;;
i[3467]86*-*-linuxaout* | \
i[3467]86*-*-linuxoldld* | \
@@ -79,6 +87,7 @@ case "${host}" in
echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i386"
+ mpi_cpu_arch="x86"
;;
i586*-*-linuxaout* | \
i586*-*-linuxoldld* | \
@@ -87,23 +96,27 @@ case "${host}" in
echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i586 i386"
+ mpi_cpu_arch="x86"
;;
i[3467]86*-msdosdjgpp* | \
i[34]86*-apple-darwin*)
echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i386"
+ mpi_cpu_arch="x86"
;;
i586*-msdosdjgpp* | \
i[567]86*-apple-darwin*)
echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i586 i386"
+ mpi_cpu_arch="x86"
;;
i[3467]86*-*-*)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i386"
+ mpi_cpu_arch="x86"
;;
i586*-*-* | \
pentium-*-* | \
@@ -111,78 +124,115 @@ case "${host}" in
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i586 i386"
+ mpi_cpu_arch="x86"
+ ;;
+ x86_64-apple-darwin*)
+ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="amd64"
+ mpi_cpu_arch="x86"
;;
x86_64-*-*)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="amd64"
+ mpi_cpu_arch="x86"
;;
alpha*-*-*)
echo '/* configured for alpha */' >>./mpi/asm-syntax.h
path="alpha"
mpi_extra_modules="udiv-qrnnd"
+ mpi_cpu_arch="alpha"
+ ;;
+ aarch64-*-*)
+ echo '/* configured for aarch64 */' >>./mpi/asm-syntax.h
+ path="aarch64"
+ mpi_cpu_arch="aarch64"
+ ;;
+ arm*-*-*)
+ mpi_cpu_arch="arm"
+ if test "$gcry_cv_gcc_arm_platform_as_ok" = "yes" ; then
+ echo '/* configured for arm */' >>./mpi/asm-syntax.h
+ path="arm"
+ else
+ echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h
+ path=""
+ fi
;;
hppa7000*-*-*)
echo '/* configured for HPPA (pa7000) */' >>./mpi/asm-syntax.h
path="hppa1.1 hppa"
mpi_extra_modules="udiv-qrnnd"
+ mpi_cpu_arch="hppa"
;;
hppa1.0*-*-*)
echo '/* configured for HPPA 1.0 */' >>./mpi/asm-syntax.h
path="hppa"
mpi_extra_modules="udiv-qrnnd"
+ mpi_cpu_arch="hppa"
;;
hppa*-*-*) # assume pa7100
echo '/* configured for HPPA (pa7100) */' >>./mpi/asm-syntax.h
path="pa7100 hppa1.1 hppa"
mpi_extra_modules="udiv-qrnnd"
+ mpi_cpu_arch="hppa"
;;
sparc64-*-linux-gnu)
echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
path=""
+ mpi_cpu_arch="sparc"
;;
sparc64-sun-solaris2*)
echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
path=""
+ mpi_cpu_arch="sparc"
;;
sparc64-*-netbsd* | sparc64-*-freebsd* | sparc64-*-openbsd*)
# There are no sparc64 assembler modules that work on the
# *BSDs, so use the generic C functions.
echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
path=""
+ mpi_cpu_arch="sparc"
;;
sparc64*-*-*)
echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
path=""
+ mpi_cpu_arch="sparc"
;;
sparc9*-*-* | \
ultrasparc*-*-* )
echo '/* configured for sparc9 or higher */' >>./mpi/asm-syntax.h
path="sparc32v8 sparc32"
+ mpi_cpu_arch="sparc"
;;
sparc8*-*-* | \
microsparc*-*-*)
echo '/* configured for sparc8 */' >>./mpi/asm-syntax.h
path="sparc32v8 sparc32"
+ mpi_cpu_arch="sparc"
;;
supersparc*-*-*)
echo '/* configured for supersparc */' >>./mpi/asm-syntax.h
path="supersparc sparc32v8 sparc32"
mpi_extra_modules="udiv"
+ mpi_cpu_arch="sparc"
;;
sparc*-*-*)
echo '/* configured for sparc */' >>./mpi/asm-syntax.h
path="sparc32"
mpi_extra_modules="udiv"
+ mpi_cpu_arch="sparc"
;;
mips[34]*-*-* | \
mips*-*-irix6*)
echo '/* configured for MIPS3 */' >>./mpi/asm-syntax.h
path="mips3"
+ mpi_cpu_arch="mips"
;;
mips*-*-*)
echo '/* configured for MIPS2 */' >>./mpi/asm-syntax.h
path="mips2"
+ mpi_cpu_arch="mips"
;;
# Motorola 68k configurations. Let m68k mean 68020-68040.
@@ -192,58 +242,74 @@ case "${host}" in
echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
path="m68k/mc68020 m68k"
+ mpi_cpu_arch="m68k"
;;
m68060*-*-linuxaout*)
echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
path="m68k"
+ mpi_cpu_arch="m68k"
;;
m680[234]0*-*-linux* | \
m68k*-*-linux*)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ mpi_cpu_arch="m68k"
;;
m68060*-*-linux*)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
path="m68k"
+ mpi_cpu_arch="m68k"
;;
m68k-atari-mint)
echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
- path="m68k/mc68020 m68k"
+ path="m68k"
+ mpi_cpu_arch="m68k"
;;
m68000*-*-* | \
m68060*-*-*)
echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
path="m68k/mc68000"
+ mpi_cpu_arch="m68k"
;;
m680[234]0*-*-* | \
m68k*-*-*)
echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
path="m68k/mc68020 m68k"
+ mpi_cpu_arch="m68k"
;;
+ powerpc-apple-darwin*)
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ mpi_cpu_arch="ppc"
+ ;;
+
powerpc*-*-netbsd* | powerpc*-*-openbsd*)
echo '/* configured {Open,Net}BSD on powerpc */' >>./mpi/asm-syntax.h
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h
mpi_sflags="-Wa,-mppc"
path="powerpc32"
+ mpi_cpu_arch="ppc"
;;
ppc620-*-* | \
powerpc64*-*-*)
mpi_sflags="-Wa,-mppc"
path="powerpc64"
+ mpi_cpu_arch="ppc"
;;
powerpc*-*-linux*)
echo '/* configured for powerpc/ELF */' >>./mpi/asm-syntax.h
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h
path="powerpc32"
+ mpi_cpu_arch="ppc"
;;
rs6000-*-aix[456789]* | \
@@ -251,6 +317,7 @@ case "${host}" in
mpi_sflags="-Wa,-mpwr"
path="power"
mpi_extra_modules="udiv-w-sdiv"
+ mpi_cpu_arch="ppc"
;;
rs6000-*-* | \
power-*-* | \
@@ -258,6 +325,7 @@ case "${host}" in
mpi_sflags="-Wa,-mppc"
path="power"
mpi_extra_modules="udiv-w-sdiv"
+ mpi_cpu_arch="ppc"
;;
powerpc-ibm-aix4.2.* )
# I am not sure about this one but a machine identified by
@@ -265,27 +333,41 @@ case "${host}" in
mpi_sflags="-Wa,-mpwr"
path="power"
mpi_extra_modules="udiv-w-sdiv"
+ mpi_cpu_arch="ppc"
;;
ppc601-*-*)
mpi_sflags="-Wa,-mppc"
path="power powerpc32"
+ mpi_cpu_arch="ppc"
;;
ppc60[234]*-*-*)
mpi_sflags="-Wa,-mppc"
path="powerpc32"
+ mpi_cpu_arch="ppc"
;;
powerpc*-*-*)
mpi_sflags="-Wa,-mppc"
path="powerpc32"
+ mpi_cpu_arch="ppc"
;;
*)
- echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h
+ echo '/* Platform not known */' >>./mpi/asm-syntax.h
path=""
;;
esac
-else
- echo '/* Assembler modules disabled on request */' >>./mpi/asm-syntax.h
+
+# If asm modules are disabled reset the found variables but keep
+# mpi_cpu_arch.
+if test "$try_asm_modules" != "yes" ; then
+ echo '/* Assembler modules disabled on request */' >./mpi/asm-syntax.h
path=""
+ mpi_sflags=""
+ mpi_extra_modules=""
+fi
+
+# Make sure that mpi_cpu_arch is not the empty string.
+if test x"$mpi_cpu_arch" = x ; then
+ mpi_cpu_arch="unknown"
fi
@@ -310,7 +392,7 @@ fi
mpi_required_modules=$mpi_standard_modules
if test "$mpi_extra_modules" != ""; then
for fn in $mpi_extra_modules; do
- for i in $mpi_optional_modules; do
+ for i in $mpi_optional_modules; do
if test "$fn" = "$i" ; then
mpi_required_modules="$mpi_required_modules $fn"
fi
@@ -358,4 +440,3 @@ for dir in $path ; do
break;
fi
done
-
diff --git a/plugins/MirOTR/Libgcrypt/mpi/ec-ed25519.c b/plugins/MirOTR/Libgcrypt/mpi/ec-ed25519.c
new file mode 100644
index 0000000000..acfe2a69f5
--- /dev/null
+++ b/plugins/MirOTR/Libgcrypt/mpi/ec-ed25519.c
@@ -0,0 +1,37 @@
+/* ec-ed25519.c - Ed25519 optimized elliptic curve functions
+ * Copyright (C) 2013 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+#include "context.h"
+#include "ec-context.h"
+
+
+void
+_gcry_mpi_ec_ed25519_mod (gcry_mpi_t a)
+{
+ (void)a;
+
+}
diff --git a/plugins/MirOTR/Libgcrypt/mpi/ec-internal.h b/plugins/MirOTR/Libgcrypt/mpi/ec-internal.h
new file mode 100644
index 0000000000..759335aad0
--- /dev/null
+++ b/plugins/MirOTR/Libgcrypt/mpi/ec-internal.h
@@ -0,0 +1,25 @@
+/* ec-internal.h - Internal declarations of ec*.c
+ * Copyright (C) 2013 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_EC_INTERNAL_H
+#define GCRY_EC_INTERNAL_H
+
+void _gcry_mpi_ec_ed25519_mod (gcry_mpi_t a);
+
+#endif /*GCRY_EC_INTERNAL_H*/
diff --git a/plugins/MirOTR/Libgcrypt/mpi/ec.c b/plugins/MirOTR/Libgcrypt/mpi/ec.c
index 4a3a5f8c08..168076f4bd 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/ec.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/ec.c
@@ -1,73 +1,117 @@
/* ec.c - Elliptic Curve functions
- Copyright (C) 2007 Free Software Foundation, Inc.
-
- This file is part of Libgcrypt.
-
- Libgcrypt is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as
- published by the Free Software Foundation; either version 2.1 of
- the License, or (at your option) any later version.
-
- Libgcrypt is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- USA. */
-
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
+#include <errno.h>
#include "mpi-internal.h"
#include "longlong.h"
#include "g10lib.h"
+#include "context.h"
+#include "ec-context.h"
+#include "ec-internal.h"
-#define point_init(a) _gcry_mpi_ec_point_init ((a))
-#define point_free(a) _gcry_mpi_ec_point_free ((a))
-
+#define point_init(a) _gcry_mpi_point_init ((a))
+#define point_free(a) _gcry_mpi_point_free_parts ((a))
-/* Object to represent a point in projective coordinates. */
-/* Currently defined in mpi.h */
-/* This context is used with all our EC functions. */
-struct mpi_ec_ctx_s
+/* Print a point using the log fucntions. If CTX is not NULL affine
+ coordinates will be printed. */
+void
+_gcry_mpi_point_log (const char *name, mpi_point_t point, mpi_ec_t ctx)
{
- /* Domain parameters. */
- gcry_mpi_t p; /* Prime specifying the field GF(p). */
- gcry_mpi_t a; /* First coefficient of the Weierstrass equation. */
+ gcry_mpi_t x, y;
+ char buf[100];
- int a_is_pminus3; /* True if A = P - 3. */
+ if (!point)
+ {
+ snprintf (buf, sizeof buf - 1, "%s.*", name);
+ log_mpidump (buf, NULL);
+ return;
+ }
+ snprintf (buf, sizeof buf - 1, "%s.X", name);
+
+ if (ctx)
+ {
+ x = mpi_new (0);
+ y = mpi_new (0);
+ }
+ if (!ctx || _gcry_mpi_ec_get_affine (x, y, point, ctx))
+ {
+ log_mpidump (buf, point->x);
+ buf[strlen(buf)-1] = 'Y';
+ log_mpidump (buf, point->y);
+ buf[strlen(buf)-1] = 'Z';
+ log_mpidump (buf, point->z);
+ }
+ else
+ {
+ buf[strlen(buf)-1] = 'x';
+ log_mpidump (buf, x);
+ buf[strlen(buf)-1] = 'y';
+ log_mpidump (buf, y);
- /* Some often used constants. */
- gcry_mpi_t one;
- gcry_mpi_t two;
- gcry_mpi_t three;
- gcry_mpi_t four;
- gcry_mpi_t eight;
- gcry_mpi_t two_inv_p;
+ }
+ if (ctx)
+ {
+ _gcry_mpi_release (x);
+ _gcry_mpi_release (y);
+ }
+}
- /* Scratch variables. */
- gcry_mpi_t scratch[11];
-
- /* Helper for fast reduction. */
-/* int nist_nbits; /\* If this is a NIST curve, the number of bits. *\/ */
-/* gcry_mpi_t s[10]; */
-/* gcry_mpi_t c; */
-};
+/* Create a new point option. NBITS gives the size in bits of one
+ coordinate; it is only used to pre-allocate some resources and
+ might also be passed as 0 to use a default value. */
+mpi_point_t
+_gcry_mpi_point_new (unsigned int nbits)
+{
+ mpi_point_t p;
+ (void)nbits; /* Currently not used. */
+ p = xmalloc (sizeof *p);
+ _gcry_mpi_point_init (p);
+ return p;
+}
-/* Initialized a point object. gcry_mpi_ec_point_free shall be used
- to release this object. */
+
+/* Release the point object P. P may be NULL. */
void
-_gcry_mpi_ec_point_init (mpi_point_t *p)
+_gcry_mpi_point_release (mpi_point_t p)
+{
+ if (p)
+ {
+ _gcry_mpi_point_free_parts (p);
+ xfree (p);
+ }
+}
+
+
+/* Initialize the fields of a point object. gcry_mpi_point_free_parts
+ may be used to release the fields. */
+void
+_gcry_mpi_point_init (mpi_point_t p)
{
p->x = mpi_new (0);
p->y = mpi_new (0);
@@ -75,18 +119,19 @@ _gcry_mpi_ec_point_init (mpi_point_t *p)
}
-/* Release a point object. */
+/* Release the parts of a point object. */
void
-_gcry_mpi_ec_point_free (mpi_point_t *p)
+_gcry_mpi_point_free_parts (mpi_point_t p)
{
mpi_free (p->x); p->x = NULL;
mpi_free (p->y); p->y = NULL;
mpi_free (p->z); p->z = NULL;
}
+
/* Set the value from S into D. */
static void
-point_set (mpi_point_t *d, mpi_point_t *s)
+point_set (mpi_point_t d, mpi_point_t s)
{
mpi_set (d->x, s->x);
mpi_set (d->y, s->y);
@@ -94,132 +139,132 @@ point_set (mpi_point_t *d, mpi_point_t *s)
}
+/* Set the projective coordinates from POINT into X, Y, and Z. If a
+ coordinate is not required, X, Y, or Z may be passed as NULL. */
+void
+_gcry_mpi_point_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+ mpi_point_t point)
+{
+ if (x)
+ mpi_set (x, point->x);
+ if (y)
+ mpi_set (y, point->y);
+ if (z)
+ mpi_set (z, point->z);
+}
+
+
+/* Set the projective coordinates from POINT into X, Y, and Z and
+ release POINT. If a coordinate is not required, X, Y, or Z may be
+ passed as NULL. */
+void
+_gcry_mpi_point_snatch_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+ mpi_point_t point)
+{
+ mpi_snatch (x, point->x);
+ mpi_snatch (y, point->y);
+ mpi_snatch (z, point->z);
+ xfree (point);
+}
+
+
+/* Set the projective coordinates from X, Y, and Z into POINT. If a
+ coordinate is given as NULL, the value 0 is stored into point. If
+ POINT is given as NULL a new point object is allocated. Returns
+ POINT or the newly allocated point object. */
+mpi_point_t
+_gcry_mpi_point_set (mpi_point_t point,
+ gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z)
+{
+ if (!point)
+ point = mpi_point_new (0);
+
+ if (x)
+ mpi_set (point->x, x);
+ else
+ mpi_clear (point->x);
+ if (y)
+ mpi_set (point->y, y);
+ else
+ mpi_clear (point->y);
+ if (z)
+ mpi_set (point->z, z);
+ else
+ mpi_clear (point->z);
+
+ return point;
+}
+
+
+/* Set the projective coordinates from X, Y, and Z into POINT. If a
+ coordinate is given as NULL, the value 0 is stored into point. If
+ POINT is given as NULL a new point object is allocated. The
+ coordinates X, Y, and Z are released. Returns POINT or the newly
+ allocated point object. */
+mpi_point_t
+_gcry_mpi_point_snatch_set (mpi_point_t point,
+ gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z)
+{
+ if (!point)
+ point = mpi_point_new (0);
+
+ if (x)
+ mpi_snatch (point->x, x);
+ else
+ mpi_clear (point->x);
+ if (y)
+ mpi_snatch (point->y, y);
+ else
+ mpi_clear (point->y);
+ if (z)
+ mpi_snatch (point->z, z);
+ else
+ mpi_clear (point->z);
+
+ return point;
+}
+
+
+/* W = W mod P. */
+static void
+ec_mod (gcry_mpi_t w, mpi_ec_t ec)
+{
+ if (0 && ec->dialect == ECC_DIALECT_ED25519)
+ _gcry_mpi_ec_ed25519_mod (w);
+ else if (ec->t.p_barrett)
+ _gcry_mpi_mod_barrett (w, w, ec->t.p_barrett);
+ else
+ _gcry_mpi_mod (w, w, ec->p);
+}
static void
ec_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
{
- mpi_addm (w, u, v, ctx->p);
+ mpi_add (w, u, v);
+ ec_mod (w, ctx);
}
static void
-ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ec)
{
- mpi_subm (w, u, v, ctx->p);
+ (void)ec;
+ mpi_sub (w, u, v);
+ /*ec_mod (w, ec);*/
}
static void
ec_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
{
-#if 0
- /* NOTE: This code works only for limb sizes of 32 bit. */
- mpi_limb_t *wp, *sp;
+ mpi_mul (w, u, v);
+ ec_mod (w, ctx);
+}
- if (ctx->nist_nbits == 192)
- {
- mpi_mul (w, u, v);
- mpi_resize (w, 12);
- wp = w->d;
-
- sp = ctx->s[0]->d;
- sp[0*2+0] = wp[0*2+0];
- sp[0*2+1] = wp[0*2+1];
- sp[1*2+0] = wp[1*2+0];
- sp[1*2+1] = wp[1*2+1];
- sp[2*2+0] = wp[2*2+0];
- sp[2*2+1] = wp[2*2+1];
-
- sp = ctx->s[1]->d;
- sp[0*2+0] = wp[3*2+0];
- sp[0*2+1] = wp[3*2+1];
- sp[1*2+0] = wp[3*2+0];
- sp[1*2+1] = wp[3*2+1];
- sp[2*2+0] = 0;
- sp[2*2+1] = 0;
-
- sp = ctx->s[2]->d;
- sp[0*2+0] = 0;
- sp[0*2+1] = 0;
- sp[1*2+0] = wp[4*2+0];
- sp[1*2+1] = wp[4*2+1];
- sp[2*2+0] = wp[4*2+0];
- sp[2*2+1] = wp[4*2+1];
-
- sp = ctx->s[3]->d;
- sp[0*2+0] = wp[5*2+0];
- sp[0*2+1] = wp[5*2+1];
- sp[1*2+0] = wp[5*2+0];
- sp[1*2+1] = wp[5*2+1];
- sp[2*2+0] = wp[5*2+0];
- sp[2*2+1] = wp[5*2+1];
-
- ctx->s[0]->nlimbs = 6;
- ctx->s[1]->nlimbs = 6;
- ctx->s[2]->nlimbs = 6;
- ctx->s[3]->nlimbs = 6;
-
- mpi_add (ctx->c, ctx->s[0], ctx->s[1]);
- mpi_add (ctx->c, ctx->c, ctx->s[2]);
- mpi_add (ctx->c, ctx->c, ctx->s[3]);
-
- while ( mpi_cmp (ctx->c, ctx->p ) >= 0 )
- mpi_sub ( ctx->c, ctx->c, ctx->p );
- mpi_set (w, ctx->c);
- }
- else if (ctx->nist_nbits == 384)
- {
- int i;
- mpi_mul (w, u, v);
- mpi_resize (w, 24);
- wp = w->d;
-
-#define NEXT(a) do { ctx->s[(a)]->nlimbs = 12; \
- sp = ctx->s[(a)]->d; \
- i = 0; } while (0)
-#define X(a) do { sp[i++] = wp[(a)];} while (0)
-#define X0(a) do { sp[i++] = 0; } while (0)
- NEXT(0);
- X(0);X(1);X(2);X(3);X(4);X(5);X(6);X(7);X(8);X(9);X(10);X(11);
- NEXT(1);
- X0();X0();X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0();
- NEXT(2);
- X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22);X(23);
- NEXT(3);
- X(21);X(22);X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);
- NEXT(4);
- X0();X(23);X0();X(20);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);
- NEXT(5);
- X0();X0();X0();X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0();
- NEXT(6);
- X(20);X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0();X0();
- NEXT(7);
- X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22);
- NEXT(8);
- X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0();X0();X0();X0();
- NEXT(9);
- X0();X0();X0();X(23);X(23);X0();X0();X0();X0();X0();X0();X0();
-#undef X0
-#undef X
-#undef NEXT
- mpi_add (ctx->c, ctx->s[0], ctx->s[1]);
- mpi_add (ctx->c, ctx->c, ctx->s[1]);
- mpi_add (ctx->c, ctx->c, ctx->s[2]);
- mpi_add (ctx->c, ctx->c, ctx->s[3]);
- mpi_add (ctx->c, ctx->c, ctx->s[4]);
- mpi_add (ctx->c, ctx->c, ctx->s[5]);
- mpi_add (ctx->c, ctx->c, ctx->s[6]);
- mpi_sub (ctx->c, ctx->c, ctx->s[7]);
- mpi_sub (ctx->c, ctx->c, ctx->s[8]);
- mpi_sub (ctx->c, ctx->c, ctx->s[9]);
-
- while ( mpi_cmp (ctx->c, ctx->p ) >= 0 )
- mpi_sub ( ctx->c, ctx->c, ctx->p );
- while ( ctx->c->sign )
- mpi_add ( ctx->c, ctx->c, ctx->p );
- mpi_set (w, ctx->c);
- }
- else
-#endif /*0*/
- mpi_mulm (w, u, v, ctx->p);
+/* W = 2 * U mod P. */
+static void
+ec_mul2 (gcry_mpi_t w, gcry_mpi_t u, mpi_ec_t ctx)
+{
+ mpi_lshift (w, u, 1);
+ ec_mod (w, ctx);
}
static void
@@ -227,58 +272,128 @@ ec_powm (gcry_mpi_t w, const gcry_mpi_t b, const gcry_mpi_t e,
mpi_ec_t ctx)
{
mpi_powm (w, b, e, ctx->p);
+ /* _gcry_mpi_abs (w); */
}
+
+/* Shortcut for
+ ec_powm (B, B, mpi_const (MPI_C_TWO), ctx);
+ for easier optimization. */
+static void
+ec_pow2 (gcry_mpi_t w, const gcry_mpi_t b, mpi_ec_t ctx)
+{
+ /* Using mpi_mul is slightly faster (at least on amd64). */
+ /* mpi_powm (w, b, mpi_const (MPI_C_TWO), ctx->p); */
+ ec_mulm (w, b, b, ctx);
+}
+
+
+/* Shortcut for
+ ec_powm (B, B, mpi_const (MPI_C_THREE), ctx);
+ for easier optimization. */
+static void
+ec_pow3 (gcry_mpi_t w, const gcry_mpi_t b, mpi_ec_t ctx)
+{
+ mpi_powm (w, b, mpi_const (MPI_C_THREE), ctx->p);
+}
+
+
static void
ec_invm (gcry_mpi_t x, gcry_mpi_t a, mpi_ec_t ctx)
{
- mpi_invm (x, a, ctx->p);
+ if (!mpi_invm (x, a, ctx->p))
+ {
+ log_error ("ec_invm: inverse does not exist:\n");
+ log_mpidump (" a", a);
+ log_mpidump (" p", ctx->p);
+ }
}
+/* Force recomputation of all helper variables. */
+void
+_gcry_mpi_ec_get_reset (mpi_ec_t ec)
+{
+ ec->t.valid.a_is_pminus3 = 0;
+ ec->t.valid.two_inv_p = 0;
+}
-/* This function returns a new context for elliptic curve based on the
- field GF(p). P is the prime specifying thuis field, A is the first
- coefficient.
- This context needs to be released using _gcry_mpi_ec_free. */
-mpi_ec_t
-_gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a)
+/* Accessor for helper variable. */
+static int
+ec_get_a_is_pminus3 (mpi_ec_t ec)
{
- int i;
- mpi_ec_t ctx;
gcry_mpi_t tmp;
- mpi_normalize (p);
- mpi_normalize (a);
+ if (!ec->t.valid.a_is_pminus3)
+ {
+ ec->t.valid.a_is_pminus3 = 1;
+ tmp = mpi_alloc_like (ec->p);
+ mpi_sub_ui (tmp, ec->p, 3);
+ ec->t.a_is_pminus3 = !mpi_cmp (ec->a, tmp);
+ mpi_free (tmp);
+ }
+
+ return ec->t.a_is_pminus3;
+}
+
+
+/* Accessor for helper variable. */
+static gcry_mpi_t
+ec_get_two_inv_p (mpi_ec_t ec)
+{
+ if (!ec->t.valid.two_inv_p)
+ {
+ ec->t.valid.two_inv_p = 1;
+ if (!ec->t.two_inv_p)
+ ec->t.two_inv_p = mpi_alloc (0);
+ ec_invm (ec->t.two_inv_p, mpi_const (MPI_C_TWO), ec);
+ }
+ return ec->t.two_inv_p;
+}
+
+
- /* Fixme: Do we want to check some constraints? e.g.
- a < p
- */
+/* This function initialized a context for elliptic curve based on the
+ field GF(p). P is the prime specifying this field, A is the first
+ coefficient. CTX is expected to be zeroized. */
+static void
+ec_p_init (mpi_ec_t ctx, enum gcry_mpi_ec_models model,
+ enum ecc_dialects dialect,
+ int flags,
+ gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b)
+{
+ int i;
+ static int use_barrett;
+
+ if (!use_barrett)
+ {
+ if (getenv ("GCRYPT_BARRETT"))
+ use_barrett = 1;
+ else
+ use_barrett = -1;
+ }
- ctx = gcry_xcalloc (1, sizeof *ctx);
+ /* Fixme: Do we want to check some constraints? e.g. a < p */
+ ctx->model = model;
+ ctx->dialect = dialect;
+ ctx->flags = flags;
+ if (dialect == ECC_DIALECT_ED25519)
+ ctx->nbits = 256;
+ else
+ ctx->nbits = mpi_get_nbits (p);
ctx->p = mpi_copy (p);
ctx->a = mpi_copy (a);
+ ctx->b = mpi_copy (b);
- tmp = mpi_alloc_like (ctx->p);
- mpi_sub_ui (tmp, ctx->p, 3);
- ctx->a_is_pminus3 = !mpi_cmp (ctx->a, tmp);
- mpi_free (tmp);
-
+ ctx->t.p_barrett = use_barrett > 0? _gcry_mpi_barrett_init (ctx->p, 0):NULL;
- /* Allocate constants. */
- ctx->one = mpi_alloc_set_ui (1);
- ctx->two = mpi_alloc_set_ui (2);
- ctx->three = mpi_alloc_set_ui (3);
- ctx->four = mpi_alloc_set_ui (4);
- ctx->eight = mpi_alloc_set_ui (8);
- ctx->two_inv_p = mpi_alloc (0);
- ec_invm (ctx->two_inv_p, ctx->two, ctx);
+ _gcry_mpi_ec_get_reset (ctx);
/* Allocate scratch variables. */
- for (i=0; i< DIM(ctx->scratch); i++)
- ctx->scratch[i] = mpi_alloc_like (ctx->p);
+ for (i=0; i< DIM(ctx->t.scratch); i++)
+ ctx->t.scratch[i] = mpi_alloc_like (ctx->p);
/* Prepare for fast reduction. */
/* FIXME: need a test for NIST values. However it does not gain us
@@ -297,31 +412,33 @@ _gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a)
/* ctx->s[i] = mpi_new (384); */
/* ctx->c = mpi_new (384*2); */
/* } */
-
- return ctx;
}
-void
-_gcry_mpi_ec_free (mpi_ec_t ctx)
+
+static void
+ec_deinit (void *opaque)
{
+ mpi_ec_t ctx = opaque;
int i;
- if (!ctx)
- return;
+ _gcry_mpi_barrett_free (ctx->t.p_barrett);
+ /* Domain parameter. */
mpi_free (ctx->p);
mpi_free (ctx->a);
+ mpi_free (ctx->b);
+ _gcry_mpi_point_release (ctx->G);
+ mpi_free (ctx->n);
- mpi_free (ctx->one);
- mpi_free (ctx->two);
- mpi_free (ctx->three);
- mpi_free (ctx->four);
- mpi_free (ctx->eight);
+ /* The key. */
+ _gcry_mpi_point_release (ctx->Q);
+ mpi_free (ctx->d);
- mpi_free (ctx->two_inv_p);
+ /* Private data of ec.c. */
+ mpi_free (ctx->t.two_inv_p);
- for (i=0; i< DIM(ctx->scratch); i++)
- mpi_free (ctx->scratch[i]);
+ for (i=0; i< DIM(ctx->t.scratch); i++)
+ mpi_free (ctx->t.scratch[i]);
/* if (ctx->nist_nbits == 192) */
/* { */
@@ -335,64 +452,198 @@ _gcry_mpi_ec_free (mpi_ec_t ctx)
/* mpi_free (ctx->s[i]); */
/* mpi_free (ctx->c); */
/* } */
+}
+
+
+/* This function returns a new context for elliptic curve based on the
+ field GF(p). P is the prime specifying this field, A is the first
+ coefficient, B is the second coefficient, and MODEL is the model
+ for the curve. This function is only used within Libgcrypt and not
+ part of the public API.
+
+ This context needs to be released using _gcry_mpi_ec_free. */
+mpi_ec_t
+_gcry_mpi_ec_p_internal_new (enum gcry_mpi_ec_models model,
+ enum ecc_dialects dialect,
+ int flags,
+ gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b)
+{
+ mpi_ec_t ctx;
+
+ ctx = xcalloc (1, sizeof *ctx);
+ ec_p_init (ctx, model, dialect, flags, p, a, b);
+
+ return ctx;
+}
+
+
+/* This is a variant of _gcry_mpi_ec_p_internal_new which returns an
+ public context and does some error checking on the supplied
+ arguments. On success the new context is stored at R_CTX and 0 is
+ returned; on error NULL is stored at R_CTX and an error code is
+ returned.
+
+ The context needs to be released using gcry_ctx_release. */
+gpg_err_code_t
+_gcry_mpi_ec_p_new (gcry_ctx_t *r_ctx,
+ enum gcry_mpi_ec_models model,
+ enum ecc_dialects dialect,
+ int flags,
+ gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b)
+{
+ gcry_ctx_t ctx;
+ mpi_ec_t ec;
- gcry_free (ctx);
+ *r_ctx = NULL;
+ if (!p || !a || !mpi_cmp_ui (a, 0))
+ return GPG_ERR_EINVAL;
+
+ ctx = _gcry_ctx_alloc (CONTEXT_TYPE_EC, sizeof *ec, ec_deinit);
+ if (!ctx)
+ return gpg_err_code_from_syserror ();
+ ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+ ec_p_init (ec, model, dialect, flags, p, a, b);
+
+ *r_ctx = ctx;
+ return 0;
+}
+
+
+void
+_gcry_mpi_ec_free (mpi_ec_t ctx)
+{
+ if (ctx)
+ {
+ ec_deinit (ctx);
+ xfree (ctx);
+ }
}
+
+gcry_mpi_t
+_gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy)
+{
+ mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+
+ return _gcry_ecc_get_mpi (name, ec, copy);
+}
+
+
+gcry_mpi_point_t
+_gcry_mpi_ec_get_point (const char *name, gcry_ctx_t ctx, int copy)
+{
+ mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+
+ (void)copy; /* Not used. */
+
+ return _gcry_ecc_get_point (name, ec);
+}
+
+
+gpg_err_code_t
+_gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue,
+ gcry_ctx_t ctx)
+{
+ mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+
+ return _gcry_ecc_set_mpi (name, newvalue, ec);
+}
+
+
+gpg_err_code_t
+_gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue,
+ gcry_ctx_t ctx)
+{
+ mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+
+ return _gcry_ecc_set_point (name, newvalue, ec);
+}
+
+
/* Compute the affine coordinates from the projective coordinates in
POINT. Set them into X and Y. If one coordinate is not required,
X or Y may be passed as NULL. CTX is the usual context. Returns: 0
on success or !0 if POINT is at infinity. */
int
-_gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point,
+_gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t point,
mpi_ec_t ctx)
{
- gcry_mpi_t z1, z2, z3;
-
if (!mpi_cmp_ui (point->z, 0))
return -1;
- z1 = mpi_new (0);
- z2 = mpi_new (0);
- ec_invm (z1, point->z, ctx); /* z1 = z^(-1) mod p */
- ec_mulm (z2, z1, z1, ctx); /* z2 = z^(-2) mod p */
-
- if (x)
- ec_mulm (x, point->x, z2, ctx);
-
- if (y)
+ switch (ctx->model)
{
- z3 = mpi_new (0);
- ec_mulm (z3, z2, z1, ctx); /* z3 = z^(-3) mod p */
- ec_mulm (y, point->y, z3, ctx);
- mpi_free (z3);
+ case MPI_EC_WEIERSTRASS: /* Using Jacobian coordinates. */
+ {
+ gcry_mpi_t z1, z2, z3;
+
+ z1 = mpi_new (0);
+ z2 = mpi_new (0);
+ ec_invm (z1, point->z, ctx); /* z1 = z^(-1) mod p */
+ ec_mulm (z2, z1, z1, ctx); /* z2 = z^(-2) mod p */
+
+ if (x)
+ ec_mulm (x, point->x, z2, ctx);
+
+ if (y)
+ {
+ z3 = mpi_new (0);
+ ec_mulm (z3, z2, z1, ctx); /* z3 = z^(-3) mod p */
+ ec_mulm (y, point->y, z3, ctx);
+ mpi_free (z3);
+ }
+
+ mpi_free (z2);
+ mpi_free (z1);
+ }
+ return 0;
+
+ case MPI_EC_MONTGOMERY:
+ {
+ log_fatal ("%s: %s not yet supported\n",
+ "_gcry_mpi_ec_get_affine", "Montgomery");
+ }
+ return -1;
+
+ case MPI_EC_TWISTEDEDWARDS:
+ {
+ gcry_mpi_t z;
+
+ z = mpi_new (0);
+ ec_invm (z, point->z, ctx);
+
+ if (x)
+ ec_mulm (x, point->x, z, ctx);
+ if (y)
+ ec_mulm (y, point->y, z, ctx);
+
+ _gcry_mpi_release (z);
+ }
+ return 0;
+
+ default:
+ return -1;
}
-
- mpi_free (z2);
- mpi_free (z1);
- return 0;
}
-
-
-/* RESULT = 2 * POINT */
-void
-_gcry_mpi_ec_dup_point (mpi_point_t *result, mpi_point_t *point, mpi_ec_t ctx)
+/* RESULT = 2 * POINT (Weierstrass version). */
+static void
+dup_point_weierstrass (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
{
#define x3 (result->x)
#define y3 (result->y)
#define z3 (result->z)
-#define t1 (ctx->scratch[0])
-#define t2 (ctx->scratch[1])
-#define t3 (ctx->scratch[2])
-#define l1 (ctx->scratch[3])
-#define l2 (ctx->scratch[4])
-#define l3 (ctx->scratch[5])
+#define t1 (ctx->t.scratch[0])
+#define t2 (ctx->t.scratch[1])
+#define t3 (ctx->t.scratch[2])
+#define l1 (ctx->t.scratch[3])
+#define l2 (ctx->t.scratch[4])
+#define l3 (ctx->t.scratch[5])
if (!mpi_cmp_ui (point->y, 0) || !mpi_cmp_ui (point->z, 0))
- {
+ {
/* P_y == 0 || P_z == 0 => [1:1:0] */
mpi_set_ui (x3, 1);
mpi_set_ui (y3, 1);
@@ -400,47 +651,47 @@ _gcry_mpi_ec_dup_point (mpi_point_t *result, mpi_point_t *point, mpi_ec_t ctx)
}
else
{
- if (ctx->a_is_pminus3) /* Use the faster case. */
- {
+ if (ec_get_a_is_pminus3 (ctx)) /* Use the faster case. */
+ {
/* L1 = 3(X - Z^2)(X + Z^2) */
/* T1: used for Z^2. */
/* T2: used for the right term. */
- ec_powm (t1, point->z, ctx->two, ctx);
- ec_subm (l1, point->x, t1, ctx);
- ec_mulm (l1, l1, ctx->three, ctx);
- ec_addm (t2, point->x, t1, ctx);
- ec_mulm (l1, l1, t2, ctx);
+ ec_pow2 (t1, point->z, ctx);
+ ec_subm (l1, point->x, t1, ctx);
+ ec_mulm (l1, l1, mpi_const (MPI_C_THREE), ctx);
+ ec_addm (t2, point->x, t1, ctx);
+ ec_mulm (l1, l1, t2, ctx);
}
else /* Standard case. */
{
/* L1 = 3X^2 + aZ^4 */
/* T1: used for aZ^4. */
- ec_powm (l1, point->x, ctx->two, ctx);
- ec_mulm (l1, l1, ctx->three, ctx);
- ec_powm (t1, point->z, ctx->four, ctx);
- ec_mulm (t1, t1, ctx->a, ctx);
- ec_addm (l1, l1, t1, ctx);
+ ec_pow2 (l1, point->x, ctx);
+ ec_mulm (l1, l1, mpi_const (MPI_C_THREE), ctx);
+ ec_powm (t1, point->z, mpi_const (MPI_C_FOUR), ctx);
+ ec_mulm (t1, t1, ctx->a, ctx);
+ ec_addm (l1, l1, t1, ctx);
}
/* Z3 = 2YZ */
ec_mulm (z3, point->y, point->z, ctx);
- ec_mulm (z3, z3, ctx->two, ctx);
+ ec_mul2 (z3, z3, ctx);
/* L2 = 4XY^2 */
/* T2: used for Y2; required later. */
- ec_powm (t2, point->y, ctx->two, ctx);
+ ec_pow2 (t2, point->y, ctx);
ec_mulm (l2, t2, point->x, ctx);
- ec_mulm (l2, l2, ctx->four, ctx);
+ ec_mulm (l2, l2, mpi_const (MPI_C_FOUR), ctx);
/* X3 = L1^2 - 2L2 */
/* T1: used for L2^2. */
- ec_powm (x3, l1, ctx->two, ctx);
- ec_mulm (t1, l2, ctx->two, ctx);
+ ec_pow2 (x3, l1, ctx);
+ ec_mul2 (t1, l2, ctx);
ec_subm (x3, x3, t1, ctx);
-
+
/* L3 = 8Y^4 */
/* T2: taken from above. */
- ec_powm (t2, t2, ctx->two, ctx);
- ec_mulm (l3, t2, ctx->eight, ctx);
+ ec_pow2 (t2, t2, ctx);
+ ec_mulm (l3, t2, mpi_const (MPI_C_EIGHT), ctx);
/* Y3 = L1(L2 - X3) - L3 */
ec_subm (y3, l2, x3, ctx);
@@ -460,12 +711,118 @@ _gcry_mpi_ec_dup_point (mpi_point_t *result, mpi_point_t *point, mpi_ec_t ctx)
}
+/* RESULT = 2 * POINT (Montgomery version). */
+static void
+dup_point_montgomery (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
+{
+ (void)result;
+ (void)point;
+ (void)ctx;
+ log_fatal ("%s: %s not yet supported\n",
+ "_gcry_mpi_ec_dup_point", "Montgomery");
+}
+
+
+/* RESULT = 2 * POINT (Twisted Edwards version). */
+static void
+dup_point_twistededwards (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
+{
+#define X1 (point->x)
+#define Y1 (point->y)
+#define Z1 (point->z)
+#define X3 (result->x)
+#define Y3 (result->y)
+#define Z3 (result->z)
+#define B (ctx->t.scratch[0])
+#define C (ctx->t.scratch[1])
+#define D (ctx->t.scratch[2])
+#define E (ctx->t.scratch[3])
+#define F (ctx->t.scratch[4])
+#define H (ctx->t.scratch[5])
+#define J (ctx->t.scratch[6])
+
+ /* Compute: (X_3 : Y_3 : Z_3) = 2( X_1 : Y_1 : Z_1 ) */
+
+ /* B = (X_1 + Y_1)^2 */
+ ec_addm (B, X1, Y1, ctx);
+ ec_pow2 (B, B, ctx);
+
+ /* C = X_1^2 */
+ /* D = Y_1^2 */
+ ec_pow2 (C, X1, ctx);
+ ec_pow2 (D, Y1, ctx);
+
+ /* E = aC */
+ if (ctx->dialect == ECC_DIALECT_ED25519)
+ {
+ mpi_set (E, C);
+ _gcry_mpi_neg (E, E);
+ }
+ else
+ ec_mulm (E, ctx->a, C, ctx);
+
+ /* F = E + D */
+ ec_addm (F, E, D, ctx);
+
+ /* H = Z_1^2 */
+ ec_pow2 (H, Z1, ctx);
+
+ /* J = F - 2H */
+ ec_mul2 (J, H, ctx);
+ ec_subm (J, F, J, ctx);
+
+ /* X_3 = (B - C - D) · J */
+ ec_subm (X3, B, C, ctx);
+ ec_subm (X3, X3, D, ctx);
+ ec_mulm (X3, X3, J, ctx);
+
+ /* Y_3 = F · (E - D) */
+ ec_subm (Y3, E, D, ctx);
+ ec_mulm (Y3, Y3, F, ctx);
+
+ /* Z_3 = F · J */
+ ec_mulm (Z3, F, J, ctx);
+
+#undef X1
+#undef Y1
+#undef Z1
+#undef X3
+#undef Y3
+#undef Z3
+#undef B
+#undef C
+#undef D
+#undef E
+#undef F
+#undef H
+#undef J
+}
-/* RESULT = P1 + P2 */
+
+/* RESULT = 2 * POINT */
void
-_gcry_mpi_ec_add_points (mpi_point_t *result,
- mpi_point_t *p1, mpi_point_t *p2,
- mpi_ec_t ctx)
+_gcry_mpi_ec_dup_point (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
+{
+ switch (ctx->model)
+ {
+ case MPI_EC_WEIERSTRASS:
+ dup_point_weierstrass (result, point, ctx);
+ break;
+ case MPI_EC_MONTGOMERY:
+ dup_point_montgomery (result, point, ctx);
+ break;
+ case MPI_EC_TWISTEDEDWARDS:
+ dup_point_twistededwards (result, point, ctx);
+ break;
+ }
+}
+
+
+/* RESULT = P1 + P2 (Weierstrass version).*/
+static void
+add_points_weierstrass (mpi_point_t result,
+ mpi_point_t p1, mpi_point_t p2,
+ mpi_ec_t ctx)
{
#define x1 (p1->x )
#define y1 (p1->y )
@@ -476,17 +833,17 @@ _gcry_mpi_ec_add_points (mpi_point_t *result,
#define x3 (result->x)
#define y3 (result->y)
#define z3 (result->z)
-#define l1 (ctx->scratch[0])
-#define l2 (ctx->scratch[1])
-#define l3 (ctx->scratch[2])
-#define l4 (ctx->scratch[3])
-#define l5 (ctx->scratch[4])
-#define l6 (ctx->scratch[5])
-#define l7 (ctx->scratch[6])
-#define l8 (ctx->scratch[7])
-#define l9 (ctx->scratch[8])
-#define t1 (ctx->scratch[9])
-#define t2 (ctx->scratch[10])
+#define l1 (ctx->t.scratch[0])
+#define l2 (ctx->t.scratch[1])
+#define l3 (ctx->t.scratch[2])
+#define l4 (ctx->t.scratch[3])
+#define l5 (ctx->t.scratch[4])
+#define l6 (ctx->t.scratch[5])
+#define l7 (ctx->t.scratch[6])
+#define l8 (ctx->t.scratch[7])
+#define l9 (ctx->t.scratch[8])
+#define t1 (ctx->t.scratch[9])
+#define t2 (ctx->t.scratch[10])
if ( (!mpi_cmp (x1, x2)) && (!mpi_cmp (y1, y2)) && (!mpi_cmp (z1, z2)) )
{
@@ -518,23 +875,23 @@ _gcry_mpi_ec_add_points (mpi_point_t *result,
mpi_set (l1, x1);
else
{
- ec_powm (l1, z2, ctx->two, ctx);
+ ec_pow2 (l1, z2, ctx);
ec_mulm (l1, l1, x1, ctx);
}
if (z1_is_one)
- mpi_set (l2, x1);
+ mpi_set (l2, x2);
else
{
- ec_powm (l2, z1, ctx->two, ctx);
+ ec_pow2 (l2, z1, ctx);
ec_mulm (l2, l2, x2, ctx);
}
/* l3 = l1 - l2 */
ec_subm (l3, l1, l2, ctx);
/* l4 = y1 z2^3 */
- ec_powm (l4, z2, ctx->three, ctx);
+ ec_powm (l4, z2, mpi_const (MPI_C_THREE), ctx);
ec_mulm (l4, l4, y1, ctx);
/* l5 = y2 z1^3 */
- ec_powm (l5, z1, ctx->three, ctx);
+ ec_powm (l5, z1, mpi_const (MPI_C_THREE), ctx);
ec_mulm (l5, l5, y2, ctx);
/* l6 = l4 - l5 */
ec_subm (l6, l4, l5, ctx);
@@ -564,19 +921,19 @@ _gcry_mpi_ec_add_points (mpi_point_t *result,
ec_mulm (z3, z1, z2, ctx);
ec_mulm (z3, z3, l3, ctx);
/* x3 = l6^2 - l7 l3^2 */
- ec_powm (t1, l6, ctx->two, ctx);
- ec_powm (t2, l3, ctx->two, ctx);
+ ec_pow2 (t1, l6, ctx);
+ ec_pow2 (t2, l3, ctx);
ec_mulm (t2, t2, l7, ctx);
ec_subm (x3, t1, t2, ctx);
/* l9 = l7 l3^2 - 2 x3 */
- ec_mulm (t1, x3, ctx->two, ctx);
+ ec_mul2 (t1, x3, ctx);
ec_subm (l9, t2, t1, ctx);
/* y3 = (l9 l6 - l8 l3^3)/2 */
ec_mulm (l9, l9, l6, ctx);
- ec_powm (t1, l3, ctx->three, ctx); /* fixme: Use saved value*/
+ ec_powm (t1, l3, mpi_const (MPI_C_THREE), ctx); /* fixme: Use saved value*/
ec_mulm (t1, t1, l8, ctx);
ec_subm (y3, l9, t1, ctx);
- ec_mulm (y3, y3, ctx->two_inv_p, ctx);
+ ec_mulm (y3, y3, ec_get_two_inv_p (ctx), ctx);
}
}
@@ -603,51 +960,205 @@ _gcry_mpi_ec_add_points (mpi_point_t *result,
}
+/* RESULT = P1 + P2 (Montgomery version).*/
+static void
+add_points_montgomery (mpi_point_t result,
+ mpi_point_t p1, mpi_point_t p2,
+ mpi_ec_t ctx)
+{
+ (void)result;
+ (void)p1;
+ (void)p2;
+ (void)ctx;
+ log_fatal ("%s: %s not yet supported\n",
+ "_gcry_mpi_ec_add_points", "Montgomery");
+}
+
+
+/* RESULT = P1 + P2 (Twisted Edwards version).*/
+static void
+add_points_twistededwards (mpi_point_t result,
+ mpi_point_t p1, mpi_point_t p2,
+ mpi_ec_t ctx)
+{
+#define X1 (p1->x)
+#define Y1 (p1->y)
+#define Z1 (p1->z)
+#define X2 (p2->x)
+#define Y2 (p2->y)
+#define Z2 (p2->z)
+#define X3 (result->x)
+#define Y3 (result->y)
+#define Z3 (result->z)
+#define A (ctx->t.scratch[0])
+#define B (ctx->t.scratch[1])
+#define C (ctx->t.scratch[2])
+#define D (ctx->t.scratch[3])
+#define E (ctx->t.scratch[4])
+#define F (ctx->t.scratch[5])
+#define G (ctx->t.scratch[6])
+#define tmp (ctx->t.scratch[7])
+
+ /* Compute: (X_3 : Y_3 : Z_3) = (X_1 : Y_1 : Z_1) + (X_2 : Y_2 : Z_3) */
+
+ /* A = Z1 · Z2 */
+ ec_mulm (A, Z1, Z2, ctx);
+
+ /* B = A^2 */
+ ec_pow2 (B, A, ctx);
+
+ /* C = X1 · X2 */
+ ec_mulm (C, X1, X2, ctx);
+
+ /* D = Y1 · Y2 */
+ ec_mulm (D, Y1, Y2, ctx);
+
+ /* E = d · C · D */
+ ec_mulm (E, ctx->b, C, ctx);
+ ec_mulm (E, E, D, ctx);
+
+ /* F = B - E */
+ ec_subm (F, B, E, ctx);
+
+ /* G = B + E */
+ ec_addm (G, B, E, ctx);
+
+ /* X_3 = A · F · ((X_1 + Y_1) · (X_2 + Y_2) - C - D) */
+ ec_addm (tmp, X1, Y1, ctx);
+ ec_addm (X3, X2, Y2, ctx);
+ ec_mulm (X3, X3, tmp, ctx);
+ ec_subm (X3, X3, C, ctx);
+ ec_subm (X3, X3, D, ctx);
+ ec_mulm (X3, X3, F, ctx);
+ ec_mulm (X3, X3, A, ctx);
+
+ /* Y_3 = A · G · (D - aC) */
+ if (ctx->dialect == ECC_DIALECT_ED25519)
+ {
+ /* Using ec_addm (Y3, D, C, ctx) is possible but a litte bit
+ slower because a subm does currently skip the mod step. */
+ mpi_set (Y3, C);
+ _gcry_mpi_neg (Y3, Y3);
+ ec_subm (Y3, D, Y3, ctx);
+ }
+ else
+ {
+ ec_mulm (Y3, ctx->a, C, ctx);
+ ec_subm (Y3, D, Y3, ctx);
+ }
+ ec_mulm (Y3, Y3, G, ctx);
+ ec_mulm (Y3, Y3, A, ctx);
+
+ /* Z_3 = F · G */
+ ec_mulm (Z3, F, G, ctx);
+
+
+#undef X1
+#undef Y1
+#undef Z1
+#undef X2
+#undef Y2
+#undef Z2
+#undef X3
+#undef Y3
+#undef Z3
+#undef A
+#undef B
+#undef C
+#undef D
+#undef E
+#undef F
+#undef G
+#undef tmp
+}
+
+
+/* RESULT = P1 + P2 */
+void
+_gcry_mpi_ec_add_points (mpi_point_t result,
+ mpi_point_t p1, mpi_point_t p2,
+ mpi_ec_t ctx)
+{
+ switch (ctx->model)
+ {
+ case MPI_EC_WEIERSTRASS:
+ add_points_weierstrass (result, p1, p2, ctx);
+ break;
+ case MPI_EC_MONTGOMERY:
+ add_points_montgomery (result, p1, p2, ctx);
+ break;
+ case MPI_EC_TWISTEDEDWARDS:
+ add_points_twistededwards (result, p1, p2, ctx);
+ break;
+ }
+}
+
/* Scalar point multiplication - the main function for ECC. If takes
an integer SCALAR and a POINT as well as the usual context CTX.
RESULT will be set to the resulting point. */
void
-_gcry_mpi_ec_mul_point (mpi_point_t *result,
- gcry_mpi_t scalar, mpi_point_t *point,
+_gcry_mpi_ec_mul_point (mpi_point_t result,
+ gcry_mpi_t scalar, mpi_point_t point,
mpi_ec_t ctx)
{
-#if 0
- /* Simple left to right binary method. GECC Algorithm 3.27 */
- unsigned int nbits;
- int i;
-
- nbits = mpi_get_nbits (scalar);
- mpi_set_ui (result->x, 1);
- mpi_set_ui (result->y, 1);
- mpi_set_ui (result->z, 0);
+ gcry_mpi_t x1, y1, z1, k, h, yy;
+ unsigned int i, loops;
+ mpi_point_struct p1, p2, p1inv;
- for (i=nbits-1; i >= 0; i--)
+ if (ctx->model == MPI_EC_TWISTEDEDWARDS)
{
- _gcry_mpi_ec_dup_point (result, result, ctx);
- if (mpi_test_bit (scalar, i) == 1)
- _gcry_mpi_ec_add_points (result, result, point, ctx);
- }
+ /* Simple left to right binary method. GECC Algorithm 3.27 */
+ unsigned int nbits;
+ int j;
-#else
- gcry_mpi_t x1, y1, z1, k, h, yy;
- unsigned int i, loops;
- mpi_point_t p1, p2, p1inv;
+ nbits = mpi_get_nbits (scalar);
+ mpi_set_ui (result->x, 0);
+ mpi_set_ui (result->y, 1);
+ mpi_set_ui (result->z, 1);
+
+ if (mpi_is_secure (scalar))
+ {
+ /* If SCALAR is in secure memory we assume that it is the
+ secret key we use constant time operation. */
+ mpi_point_struct tmppnt;
+
+ point_init (&tmppnt);
+ for (j=nbits-1; j >= 0; j--)
+ {
+ _gcry_mpi_ec_dup_point (result, result, ctx);
+ _gcry_mpi_ec_add_points (&tmppnt, result, point, ctx);
+ if (mpi_test_bit (scalar, j))
+ point_set (result, &tmppnt);
+ }
+ point_free (&tmppnt);
+ }
+ else
+ {
+ for (j=nbits-1; j >= 0; j--)
+ {
+ _gcry_mpi_ec_dup_point (result, result, ctx);
+ if (mpi_test_bit (scalar, j))
+ _gcry_mpi_ec_add_points (result, result, point, ctx);
+ }
+ }
+ return;
+ }
x1 = mpi_alloc_like (ctx->p);
y1 = mpi_alloc_like (ctx->p);
h = mpi_alloc_like (ctx->p);
k = mpi_copy (scalar);
- yy = mpi_copy (point->y);
+ yy = mpi_copy (point->y);
- if ( mpi_is_neg (k) )
- {
+ if ( mpi_has_sign (k) )
+ {
k->sign = 0;
ec_invm (yy, yy, ctx);
}
if (!mpi_cmp_ui (point->z, 1))
- {
+ {
mpi_set (x1, point->x);
mpi_set (y1, yy);
}
@@ -657,23 +1168,36 @@ _gcry_mpi_ec_mul_point (mpi_point_t *result,
z2 = mpi_alloc_like (ctx->p);
z3 = mpi_alloc_like (ctx->p);
- ec_mulm (z2, point->z, point->z, ctx);
- ec_mulm (z3, point->z, z2, ctx);
- ec_invm (z2, z2, ctx);
+ ec_mulm (z2, point->z, point->z, ctx);
+ ec_mulm (z3, point->z, z2, ctx);
+ ec_invm (z2, z2, ctx);
ec_mulm (x1, point->x, z2, ctx);
- ec_invm (z3, z3, ctx);
- ec_mulm (y1, yy, z3, ctx);
+ ec_invm (z3, z3, ctx);
+ ec_mulm (y1, yy, z3, ctx);
mpi_free (z2);
mpi_free (z3);
}
- z1 = mpi_copy (ctx->one);
+ z1 = mpi_copy (mpi_const (MPI_C_ONE));
- mpi_mul (h, k, ctx->three); /* h = 3k */
+ mpi_mul (h, k, mpi_const (MPI_C_THREE)); /* h = 3k */
loops = mpi_get_nbits (h);
-
- mpi_set (result->x, point->x);
- mpi_set (result->y, yy); mpi_free (yy); yy = NULL;
- mpi_set (result->z, point->z);
+ if (loops < 2)
+ {
+ /* If SCALAR is zero, the above mpi_mul sets H to zero and thus
+ LOOPs will be zero. To avoid an underflow of I in the main
+ loop we set LOOP to 2 and the result to (0,0,0). */
+ loops = 2;
+ mpi_clear (result->x);
+ mpi_clear (result->y);
+ mpi_clear (result->z);
+ }
+ else
+ {
+ mpi_set (result->x, point->x);
+ mpi_set (result->y, yy);
+ mpi_set (result->z, point->z);
+ }
+ mpi_free (yy); yy = NULL;
p1.x = x1; x1 = NULL;
p1.y = y1; y1 = NULL;
@@ -682,12 +1206,12 @@ _gcry_mpi_ec_mul_point (mpi_point_t *result,
point_init (&p1inv);
for (i=loops-2; i > 0; i--)
- {
+ {
_gcry_mpi_ec_dup_point (result, result, ctx);
if (mpi_test_bit (h, i) == 1 && mpi_test_bit (k, i) == 0)
- {
+ {
point_set (&p2, result);
- _gcry_mpi_ec_add_points (result, &p2, &p1, ctx);
+ _gcry_mpi_ec_add_points (result, &p2, &p1, ctx);
}
if (mpi_test_bit (h, i) == 0 && mpi_test_bit (k, i) == 1)
{
@@ -695,7 +1219,7 @@ _gcry_mpi_ec_mul_point (mpi_point_t *result,
/* Invert point: y = p - y mod p */
point_set (&p1inv, &p1);
ec_subm (p1inv.y, ctx->p, p1inv.y, ctx);
- _gcry_mpi_ec_add_points (result, &p2, &p1inv, ctx);
+ _gcry_mpi_ec_add_points (result, &p2, &p1inv, ctx);
}
}
@@ -704,6 +1228,73 @@ _gcry_mpi_ec_mul_point (mpi_point_t *result,
point_free (&p1inv);
mpi_free (h);
mpi_free (k);
-#endif
}
+
+/* Return true if POINT is on the curve described by CTX. */
+int
+_gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx)
+{
+ int res = 0;
+ gcry_mpi_t x, y, w;
+
+ x = mpi_new (0);
+ y = mpi_new (0);
+ w = mpi_new (0);
+
+ if (_gcry_mpi_ec_get_affine (x, y, point, ctx))
+ return 0;
+
+ switch (ctx->model)
+ {
+ case MPI_EC_WEIERSTRASS:
+ {
+ gcry_mpi_t xxx = mpi_new (0);
+
+ /* y^2 == x^3 + a·x + b */
+ ec_pow2 (y, y, ctx);
+
+ ec_pow3 (xxx, x, ctx);
+ ec_mulm (w, ctx->a, x, ctx);
+ ec_addm (w, w, ctx->b, ctx);
+ ec_addm (w, w, xxx, ctx);
+
+ if (!mpi_cmp (y, w))
+ res = 1;
+
+ _gcry_mpi_release (xxx);
+ }
+ break;
+ case MPI_EC_MONTGOMERY:
+ log_fatal ("%s: %s not yet supported\n",
+ "_gcry_mpi_ec_curve_point", "Montgomery");
+ break;
+ case MPI_EC_TWISTEDEDWARDS:
+ {
+ /* a · x^2 + y^2 - 1 - b · x^2 · y^2 == 0 */
+ ec_pow2 (x, x, ctx);
+ ec_pow2 (y, y, ctx);
+ if (ctx->dialect == ECC_DIALECT_ED25519)
+ {
+ mpi_set (w, x);
+ _gcry_mpi_neg (w, w);
+ }
+ else
+ ec_mulm (w, ctx->a, x, ctx);
+ ec_addm (w, w, y, ctx);
+ ec_subm (w, w, mpi_const (MPI_C_ONE), ctx);
+ ec_mulm (x, x, y, ctx);
+ ec_mulm (x, x, ctx->b, ctx);
+ ec_subm (w, w, x, ctx);
+ if (!mpi_cmp_ui (w, 0))
+ res = 1;
+ }
+ break;
+ }
+
+ _gcry_mpi_release (w);
+ _gcry_mpi_release (x);
+ _gcry_mpi_release (y);
+
+ return res;
+}
diff --git a/plugins/MirOTR/Libgcrypt/mpi/generic/mpi-asm-defs.h b/plugins/MirOTR/Libgcrypt/mpi/generic/mpi-asm-defs.h
index 13424e2808..e607806e10 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/generic/mpi-asm-defs.h
+++ b/plugins/MirOTR/Libgcrypt/mpi/generic/mpi-asm-defs.h
@@ -1,10 +1,8 @@
-/* This file defines some basic constants for the MPI machinery. We
- * need to define the types on a per-CPU basis, so it is done with
- * this file here. */
+/* This file defines some basic constants for the MPI machinery.
+ * AMD64 compiled for the x32 ABI is special and thus we can't use the
+ * standard values for this ABI. */
+#if __GNUC__ >= 3 && defined(__x86_64__) && defined(__ILP32__)
+#define BYTES_PER_MPI_LIMB 8
+#else
#define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG)
-
-
-
-
-
-
+#endif
diff --git a/plugins/MirOTR/Libgcrypt/mpi/longlong.h b/plugins/MirOTR/Libgcrypt/mpi/longlong.h
index b736d490fd..4f33937fbd 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/longlong.h
+++ b/plugins/MirOTR/Libgcrypt/mpi/longlong.h
@@ -2,7 +2,7 @@
Note: I added some stuff for use with gnupg
Copyright (C) 1991, 1992, 1993, 1994, 1996, 1998,
- 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@@ -184,28 +184,53 @@ extern UDItype __udiv_qrnnd ();
/***************************************
************** ARM ******************
***************************************/
-#if defined (__arm__) && W_TYPE_SIZE == 32
+#if defined (__arm__) && W_TYPE_SIZE == 32 && \
+ (!defined (__thumb__) || defined (__thumb2__))
+/* The __ARM_ARCH define is provided by gcc 4.8. Construct it otherwise. */
+#ifndef __ARM_ARCH
+# ifdef __ARM_ARCH_2__
+# define __ARM_ARCH 2
+# elif defined (__ARM_ARCH_3__) || defined (__ARM_ARCH_3M__)
+# define __ARM_ARCH 3
+# elif defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__)
+# define __ARM_ARCH 4
+# elif defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5E__) \
+ || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \
+ || defined(__ARM_ARCH_5TEJ__)
+# define __ARM_ARCH 5
+# elif defined (__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+ || defined (__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
+ || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__)
+# define __ARM_ARCH 6
+# elif defined (__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
+ || defined(__ARM_ARCH_7EM__)
+# define __ARM_ARCH 7
+# else
+ /* could not detect? */
+# endif
+#endif
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("adds %1, %4, %5\n" \
"adc %0, %2, %3" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "%r" ((USItype)(ah)), \
"rI" ((USItype)(bh)), \
"%r" ((USItype)(al)), \
- "rI" ((USItype)(bl)))
+ "rI" ((USItype)(bl)) __CLOBBER_CC)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("subs %1, %4, %5\n" \
"sbc %0, %2, %3" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "r" ((USItype)(ah)), \
"rI" ((USItype)(bh)), \
"r" ((USItype)(al)), \
- "rI" ((USItype)(bl)))
-#if defined __ARM_ARCH_2__ || defined __ARM_ARCH_3__
+ "rI" ((USItype)(bl)) __CLOBBER_CC)
+#if (defined __ARM_ARCH && __ARM_ARCH <= 3)
#define umul_ppmm(xh, xl, a, b) \
- __asm__ ("%@ Inlined umul_ppmm\n" \
+ __asm__ ("@ Inlined umul_ppmm\n" \
"mov %|r0, %2, lsr #16 @ AAAA\n" \
"mov %|r2, %3, lsr #16 @ BBBB\n" \
"bic %|r1, %2, %|r0, lsl #16 @ aaaa\n" \
@@ -218,26 +243,69 @@ extern UDItype __udiv_qrnnd ();
"addcs %|r2, %|r2, #65536\n" \
"adds %1, %|r1, %|r0, lsl #16\n" \
"adc %0, %|r2, %|r0, lsr #16" \
- : "=&r" ((USItype)(xh)), \
- "=r" ((USItype)(xl)) \
+ : "=&r" ((xh)), \
+ "=r" ((xl)) \
: "r" ((USItype)(a)), \
"r" ((USItype)(b)) \
- : "r0", "r1", "r2")
-#else
+ : "r0", "r1", "r2" __AND_CLOBBER_CC)
+#else /* __ARM_ARCH >= 4 */
#define umul_ppmm(xh, xl, a, b) \
- __asm__ ("%@ Inlined umul_ppmm\n" \
- "umull %r1, %r0, %r2, %r3" \
- : "=&r" ((USItype)(xh)), \
- "=r" ((USItype)(xl)) \
+ __asm__ ("@ Inlined umul_ppmm\n" \
+ "umull %1, %0, %2, %3" \
+ : "=&r" ((xh)), \
+ "=r" ((xl)) \
: "r" ((USItype)(a)), \
- "r" ((USItype)(b)) \
- : "r0", "r1")
-#endif
+ "r" ((USItype)(b)))
+#endif /* __ARM_ARCH >= 4 */
#define UMUL_TIME 20
#define UDIV_TIME 100
+#if (defined __ARM_ARCH && __ARM_ARCH >= 5)
+#define count_leading_zeros(count, x) \
+ __asm__ ("clz %0, %1" \
+ : "=r" ((count)) \
+ : "r" ((USItype)(x)))
+#endif /* __ARM_ARCH >= 5 */
#endif /* __arm__ */
/***************************************
+ ********** ARM64 / Aarch64 **********
+ ***************************************/
+#if defined(__aarch64__) && W_TYPE_SIZE == 64
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("adds %1, %4, %5\n" \
+ "adc %0, %2, %3\n" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "r" ((UDItype)(ah)), \
+ "r" ((UDItype)(bh)), \
+ "r" ((UDItype)(al)), \
+ "r" ((UDItype)(bl)) __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subs %1, %4, %5\n" \
+ "sbc %0, %2, %3\n" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "r" ((UDItype)(ah)), \
+ "r" ((UDItype)(bh)), \
+ "r" ((UDItype)(al)), \
+ "r" ((UDItype)(bl)) __CLOBBER_CC)
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1), __ph; \
+ (pl) = __m0 * __m1; \
+ __asm__ ("umulh %0,%1,%2" \
+ : "=r" (__ph) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ (ph) = __ph; \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ __asm__ ("clz %0, %1\n" \
+ : "=r" ((count)) \
+ : "r" ((UDItype)(x)))
+#endif /* __aarch64__ */
+
+/***************************************
************** CLIPPER **************
***************************************/
#if defined (__clipper__) && W_TYPE_SIZE == 32
@@ -437,43 +505,48 @@ extern USItype __udiv_qrnnd ();
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("addl %5,%1\n" \
"adcl %3,%0" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "%0" ((USItype)(ah)), \
"g" ((USItype)(bh)), \
"%1" ((USItype)(al)), \
- "g" ((USItype)(bl)))
+ "g" ((USItype)(bl)) \
+ __CLOBBER_CC)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("subl %5,%1\n" \
"sbbl %3,%0" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "0" ((USItype)(ah)), \
"g" ((USItype)(bh)), \
"1" ((USItype)(al)), \
- "g" ((USItype)(bl)))
+ "g" ((USItype)(bl)) \
+ __CLOBBER_CC)
#define umul_ppmm(w1, w0, u, v) \
__asm__ ("mull %3" \
- : "=a" ((USItype)(w0)), \
- "=d" ((USItype)(w1)) \
+ : "=a" ((w0)), \
+ "=d" ((w1)) \
: "%0" ((USItype)(u)), \
- "rm" ((USItype)(v)))
+ "rm" ((USItype)(v)) \
+ __CLOBBER_CC)
#define udiv_qrnnd(q, r, n1, n0, d) \
__asm__ ("divl %4" \
- : "=a" ((USItype)(q)), \
- "=d" ((USItype)(r)) \
+ : "=a" ((q)), \
+ "=d" ((r)) \
: "0" ((USItype)(n0)), \
"1" ((USItype)(n1)), \
- "rm" ((USItype)(d)))
+ "rm" ((USItype)(d)) \
+ __CLOBBER_CC)
#define count_leading_zeros(count, x) \
do { \
USItype __cbtmp; \
__asm__ ("bsrl %1,%0" \
- : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
+ : "=r" (__cbtmp) : "rm" ((USItype)(x)) \
+ __CLOBBER_CC); \
(count) = __cbtmp ^ 31; \
} while (0)
#define count_trailing_zeros(count, x) \
- __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
+ __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)) __CLOBBER_CC)
#ifndef UMUL_TIME
#define UMUL_TIME 40
#endif
@@ -482,6 +555,69 @@ extern USItype __udiv_qrnnd ();
#endif
#endif /* 80x86 */
+/***************************************
+ *********** AMD64 / x86-64 ************
+ ***************************************/
+#if defined(__x86_64) && W_TYPE_SIZE == 64
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addq %5,%1\n" \
+ "adcq %3,%0" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "0" ((UDItype)(ah)), \
+ "g" ((UDItype)(bh)), \
+ "1" ((UDItype)(al)), \
+ "g" ((UDItype)(bl)) \
+ __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subq %5,%1\n" \
+ "sbbq %3,%0" \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
+ : "0" ((UDItype)(ah)), \
+ "g" ((UDItype)(bh)), \
+ "1" ((UDItype)(al)), \
+ "g" ((UDItype)(bl)) \
+ __CLOBBER_CC)
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mulq %3" \
+ : "=a" ((w0)), \
+ "=d" ((w1)) \
+ : "0" ((UDItype)(u)), \
+ "rm" ((UDItype)(v)) \
+ __CLOBBER_CC)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divq %4" \
+ : "=a" ((q)), \
+ "=d" ((r)) \
+ : "0" ((UDItype)(n0)), \
+ "1" ((UDItype)(n1)), \
+ "rm" ((UDItype)(d)) \
+ __CLOBBER_CC)
+#define count_leading_zeros(count, x) \
+ do { \
+ UDItype __cbtmp; \
+ __asm__ ("bsrq %1,%0" \
+ : "=r" (__cbtmp) : "rm" ((UDItype)(x)) \
+ __CLOBBER_CC); \
+ (count) = __cbtmp ^ 63; \
+ } while (0)
+#define count_trailing_zeros(count, x) \
+ do { \
+ UDItype __cbtmp; \
+ __asm__ ("bsfq %1,%0" \
+ : "=r" (__cbtmp) : "rm" ((UDItype)(x)) \
+ __CLOBBER_CC); \
+ (count) = __cbtmp; \
+ } while (0)
+#ifndef UMUL_TIME
+#define UMUL_TIME 40
+#endif
+#ifndef UDIV_TIME
+#define UDIV_TIME 40
+#endif
+#endif /* __x86_64 */
+
/***************************************
************** I860 *****************
@@ -714,7 +850,8 @@ extern USItype __udiv_qrnnd ();
************** MIPS *****************
***************************************/
#if defined (__mips__) && W_TYPE_SIZE == 32
-#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
+#if defined (__clang__) || (__GNUC__ >= 5) || (__GNUC__ == 4 && \
+ __GNUC_MINOR__ >= 4)
#define umul_ppmm(w1, w0, u, v) \
do { \
UDItype _r; \
@@ -826,22 +963,22 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
do { \
if (__builtin_constant_p (bh) && (bh) == 0) \
__asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "%r" ((USItype)(ah)), \
"%r" ((USItype)(al)), \
"rI" ((USItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
__asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "%r" ((USItype)(ah)), \
"%r" ((USItype)(al)), \
"rI" ((USItype)(bl))); \
else \
__asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "%r" ((USItype)(ah)), \
"r" ((USItype)(bh)), \
"%r" ((USItype)(al)), \
@@ -851,36 +988,36 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
do { \
if (__builtin_constant_p (ah) && (ah) == 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "r" ((USItype)(bh)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "r" ((USItype)(bh)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) == 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "r" ((USItype)(ah)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "r" ((USItype)(ah)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else \
__asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "r" ((USItype)(ah)), \
"r" ((USItype)(bh)), \
"rI" ((USItype)(al)), \
@@ -888,7 +1025,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
} while (0)
#define count_leading_zeros(count, x) \
__asm__ ("{cntlz|cntlzw} %0,%1" \
- : "=r" ((USItype)(count)) \
+ : "=r" ((count)) \
: "r" ((USItype)(x)))
#define COUNT_LEADING_ZEROS_0 32
#if defined (_ARCH_PPC)
@@ -896,7 +1033,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
do { \
USItype __m0 = (m0), __m1 = (m1); \
__asm__ ("mulhwu %0,%1,%2" \
- : "=r" ((USItype) ph) \
+ : "=r" (ph) \
: "%r" (__m0), \
"r" (__m1)); \
(pl) = __m0 * __m1; \
@@ -918,8 +1055,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
do { \
USItype __m0 = (m0), __m1 = (m1); \
__asm__ ("mul %0,%2,%3" \
- : "=r" ((USItype)(xh)), \
- "=q" ((USItype)(xl)) \
+ : "=r" ((xh)), \
+ "=q" ((xl)) \
: "r" (__m0), \
"r" (__m1)); \
(xh) += ((((SItype) __m0 >> 31) & __m1) \
@@ -944,7 +1081,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
/* Powerpc 64 bit support taken from gmp-4.1.2. */
/* We should test _IBMR2 here when we add assembly support for the system
vendor compilers. */
-#if 0 /* Not yet enabled becuase we don't have hardware for a test. */
+#if 0 /* Not yet enabled because we don't have hardware for a test. */
#if (defined (_ARCH_PPC) || defined (__powerpc__)) && W_TYPE_SIZE == 64
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
do { \
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mod-source-info.h b/plugins/MirOTR/Libgcrypt/mpi/mod-source-info.h
index 7abd27e31c..a60e95a4e7 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mod-source-info.h
+++ b/plugins/MirOTR/Libgcrypt/mpi/mod-source-info.h
@@ -1 +1,11 @@
-static char mod_source_info[] = ":i386/mpih-add1.S:i386/mpih-sub1.S:i386/mpih-mul1.S:i386/mpih-mul2.S:i386/mpih-mul3.S:i386/mpih-lshift.S:i386/mpih-rshift.S"; \ No newline at end of file
+/* Created by config.links - do not edit */
+/* Host: x86_64-pc-mingw32 */
+static char mod_source_info[] =
+ ":amd64/mpih-add1.S"
+ ":amd64/mpih-sub1.S"
+ ":amd64/mpih-mul1.S"
+ ":amd64/mpih-mul2.S"
+ ":amd64/mpih-mul3.S"
+ ":amd64/mpih-lshift.S"
+ ":amd64/mpih-rshift.S"
+ ;
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpi-add.c b/plugins/MirOTR/Libgcrypt/mpi/mpi-add.c
index ada257ae1e..53f476e060 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpi-add.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpi-add.c
@@ -36,7 +36,7 @@
* result in W. U and V may be the same.
*/
void
-gcry_mpi_add_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+_gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
{
mpi_ptr_t wp, up;
mpi_size_t usize, wsize;
@@ -85,7 +85,7 @@ gcry_mpi_add_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
void
-gcry_mpi_add(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+_gcry_mpi_add(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
{
mpi_ptr_t wp, up, vp;
mpi_size_t usize, vsize, wsize;
@@ -162,7 +162,7 @@ gcry_mpi_add(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
* result in W.
*/
void
-gcry_mpi_sub_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+_gcry_mpi_sub_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
{
mpi_ptr_t wp, up;
mpi_size_t usize, wsize;
@@ -211,26 +211,25 @@ gcry_mpi_sub_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
}
void
-gcry_mpi_sub(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+_gcry_mpi_sub(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
{
gcry_mpi_t vv = mpi_copy (v);
vv->sign = ! vv->sign;
- gcry_mpi_add (w, u, vv);
+ mpi_add (w, u, vv);
mpi_free (vv);
}
void
-gcry_mpi_addm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+_gcry_mpi_addm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
{
- gcry_mpi_add(w, u, v);
- _gcry_mpi_fdiv_r( w, w, m );
+ mpi_add (w, u, v);
+ mpi_mod (w, w, m);
}
void
-gcry_mpi_subm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+_gcry_mpi_subm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
{
- gcry_mpi_sub(w, u, v);
- _gcry_mpi_fdiv_r( w, w, m );
+ mpi_sub (w, u, v);
+ mpi_mod (w, w, m);
}
-
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpi-asm-defs.h b/plugins/MirOTR/Libgcrypt/mpi/mpi-asm-defs.h
index 13424e2808..e607806e10 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpi-asm-defs.h
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpi-asm-defs.h
@@ -1,10 +1,8 @@
-/* This file defines some basic constants for the MPI machinery. We
- * need to define the types on a per-CPU basis, so it is done with
- * this file here. */
+/* This file defines some basic constants for the MPI machinery.
+ * AMD64 compiled for the x32 ABI is special and thus we can't use the
+ * standard values for this ABI. */
+#if __GNUC__ >= 3 && defined(__x86_64__) && defined(__ILP32__)
+#define BYTES_PER_MPI_LIMB 8
+#else
#define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG)
-
-
-
-
-
-
+#endif
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpi-bit.c b/plugins/MirOTR/Libgcrypt/mpi/mpi-bit.c
index 32c820c291..e2170401e4 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpi-bit.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpi-bit.c
@@ -1,5 +1,6 @@
-/* mpi-bit.c - MPI bit level fucntions
+/* mpi-bit.c - MPI bit level functions
* Copyright (C) 1998, 1999, 2001, 2002, 2006 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@@ -67,7 +68,7 @@ _gcry_mpi_normalize( gcry_mpi_t a )
* Return the number of bits in A.
*/
unsigned int
-gcry_mpi_get_nbits( gcry_mpi_t a )
+_gcry_mpi_get_nbits (gcry_mpi_t a)
{
unsigned n;
@@ -94,7 +95,7 @@ gcry_mpi_get_nbits( gcry_mpi_t a )
* Test whether bit N is set.
*/
int
-gcry_mpi_test_bit( gcry_mpi_t a, unsigned int n )
+_gcry_mpi_test_bit( gcry_mpi_t a, unsigned int n )
{
unsigned int limbno, bitno;
mpi_limb_t limb;
@@ -113,15 +114,23 @@ gcry_mpi_test_bit( gcry_mpi_t a, unsigned int n )
* Set bit N of A.
*/
void
-gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n )
+_gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n )
{
- unsigned int limbno, bitno;
+ unsigned int i, limbno, bitno;
+
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
limbno = n / BITS_PER_MPI_LIMB;
bitno = n % BITS_PER_MPI_LIMB;
- if ( limbno >= a->nlimbs )
+ if ( limbno >= a->nlimbs )
{
+ for (i=a->nlimbs; i < a->alloced; i++)
+ a->d[i] = 0;
mpi_resize (a, limbno+1 );
a->nlimbs = limbno+1;
}
@@ -132,15 +141,23 @@ gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n )
* Set bit N of A. and clear all bits above
*/
void
-gcry_mpi_set_highbit( gcry_mpi_t a, unsigned int n )
+_gcry_mpi_set_highbit( gcry_mpi_t a, unsigned int n )
{
- unsigned int limbno, bitno;
-
+ unsigned int i, limbno, bitno;
+
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
limbno = n / BITS_PER_MPI_LIMB;
bitno = n % BITS_PER_MPI_LIMB;
-
- if ( limbno >= a->nlimbs )
- {
+
+ if ( limbno >= a->nlimbs )
+ {
+ for (i=a->nlimbs; i < a->alloced; i++)
+ a->d[i] = 0;
mpi_resize (a, limbno+1 );
a->nlimbs = limbno+1;
}
@@ -154,36 +171,47 @@ gcry_mpi_set_highbit( gcry_mpi_t a, unsigned int n )
* clear bit N of A and all bits above
*/
void
-gcry_mpi_clear_highbit( gcry_mpi_t a, unsigned int n )
+_gcry_mpi_clear_highbit( gcry_mpi_t a, unsigned int n )
{
- unsigned int limbno, bitno;
+ unsigned int limbno, bitno;
- limbno = n / BITS_PER_MPI_LIMB;
- bitno = n % BITS_PER_MPI_LIMB;
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
- if( limbno >= a->nlimbs )
- return; /* not allocated, therefore no need to clear bits
- :-) */
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if( limbno >= a->nlimbs )
+ return; /* not allocated, therefore no need to clear bits :-) */
- for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
- a->d[limbno] &= ~(A_LIMB_1 << bitno);
- a->nlimbs = limbno+1;
+ for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
+ a->nlimbs = limbno+1;
}
/****************
* Clear bit N of A.
*/
void
-gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n )
+_gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n )
{
- unsigned int limbno, bitno;
+ unsigned int limbno, bitno;
- limbno = n / BITS_PER_MPI_LIMB;
- bitno = n % BITS_PER_MPI_LIMB;
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
- if( limbno >= a->nlimbs )
- return; /* don't need to clear this bit, it's to far to left */
- a->d[limbno] &= ~(A_LIMB_1 << bitno);
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if (limbno >= a->nlimbs)
+ return; /* Don't need to clear this bit, it's far too left. */
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
}
@@ -194,19 +222,26 @@ gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n )
void
_gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count )
{
- mpi_ptr_t ap = a->d;
- mpi_size_t n = a->nlimbs;
- unsigned int i;
+ mpi_ptr_t ap = a->d;
+ mpi_size_t n = a->nlimbs;
+ unsigned int i;
- if( count >= n ) {
- a->nlimbs = 0;
- return;
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
}
- for( i = 0; i < n - count; i++ )
- ap[i] = ap[i+count];
- ap[i] = 0;
- a->nlimbs -= count;
+ if (count >= n)
+ {
+ a->nlimbs = 0;
+ return;
+ }
+
+ for( i = 0; i < n - count; i++ )
+ ap[i] = ap[i+count];
+ ap[i] = 0;
+ a->nlimbs -= count;
}
@@ -214,13 +249,19 @@ _gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count )
* Shift A by N bits to the right.
*/
void
-gcry_mpi_rshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
+_gcry_mpi_rshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
{
mpi_size_t xsize;
unsigned int i;
unsigned int nlimbs = (n/BITS_PER_MPI_LIMB);
unsigned int nbits = (n%BITS_PER_MPI_LIMB);
+ if (mpi_is_immutable (x))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
if ( x == a )
{
/* In-place operation. */
@@ -276,7 +317,7 @@ gcry_mpi_rshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
x->sign = a->sign;
RESIZE_IF_NEEDED (x, xsize);
x->nlimbs = xsize;
-
+
if ( xsize )
{
if (nbits )
@@ -323,11 +364,17 @@ _gcry_mpi_lshift_limbs (gcry_mpi_t a, unsigned int count)
* Shift A by N bits to the left.
*/
void
-gcry_mpi_lshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
+_gcry_mpi_lshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
{
unsigned int nlimbs = (n/BITS_PER_MPI_LIMB);
unsigned int nbits = (n%BITS_PER_MPI_LIMB);
+ if (mpi_is_immutable (x))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
if (x == a && !n)
return; /* In-place shift with an amount of zero. */
@@ -357,9 +404,8 @@ gcry_mpi_lshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
/* We use a very dump approach: Shift left by the number of
limbs plus one and than fix it up by an rshift. */
_gcry_mpi_lshift_limbs (x, nlimbs+1);
- gcry_mpi_rshift (x, x, BITS_PER_MPI_LIMB - nbits);
+ mpi_rshift (x, x, BITS_PER_MPI_LIMB - nbits);
}
MPN_NORMALIZE (x->d, x->nlimbs);
}
-
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpi-cmp.c b/plugins/MirOTR/Libgcrypt/mpi/mpi-cmp.c
index 9dd10830b0..838a7c9240 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpi-cmp.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpi-cmp.c
@@ -24,7 +24,7 @@
#include "mpi-internal.h"
int
-gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v)
+_gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v)
{
mpi_limb_t limb = v;
@@ -53,38 +53,55 @@ gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v)
return 1;
}
+
int
-gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v)
+_gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v)
{
mpi_size_t usize;
mpi_size_t vsize;
int cmp;
- _gcry_mpi_normalize (u);
- _gcry_mpi_normalize (v);
-
- usize = u->nlimbs;
- vsize = v->nlimbs;
+ if (mpi_is_opaque (u) || mpi_is_opaque (v))
+ {
+ if (mpi_is_opaque (u) && !mpi_is_opaque (v))
+ return -1;
+ if (!mpi_is_opaque (u) && mpi_is_opaque (v))
+ return 1;
+ if (!u->sign && !v->sign)
+ return 0; /* Empty buffers are identical. */
+ if (u->sign < v->sign)
+ return -1;
+ if (u->sign > v->sign)
+ return 1;
+ return memcmp (u->d, v->d, (u->sign+7)/8);
+ }
+ else
+ {
+ _gcry_mpi_normalize (u);
+ _gcry_mpi_normalize (v);
- /* Compare sign bits. */
+ usize = u->nlimbs;
+ vsize = v->nlimbs;
- if (!u->sign && v->sign)
- return 1;
- if (u->sign && !v->sign)
- return -1;
+ /* Compare sign bits. */
- /* U and V are either both positive or both negative. */
+ if (!u->sign && v->sign)
+ return 1;
+ if (u->sign && !v->sign)
+ return -1;
- if( usize != vsize && !u->sign && !v->sign )
- return usize - vsize;
- if( usize != vsize && u->sign && v->sign )
- return vsize + usize;
- if( !usize )
- return 0;
- if( !(cmp = _gcry_mpih_cmp( u->d, v->d, usize )) )
- return 0;
- if( (cmp < 0?1:0) == (u->sign?1:0))
- return 1;
+ /* U and V are either both positive or both negative. */
+ if (usize != vsize && !u->sign && !v->sign)
+ return usize - vsize;
+ if (usize != vsize && u->sign && v->sign)
+ return vsize + usize;
+ if (!usize )
+ return 0;
+ if (!(cmp = _gcry_mpih_cmp (u->d, v->d, usize)))
+ return 0;
+ if ((cmp < 0?1:0) == (u->sign?1:0))
+ return 1;
+ }
return -1;
}
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpi-div.c b/plugins/MirOTR/Libgcrypt/mpi/mpi-div.c
index 0d8a2d1688..9ac99c31b3 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpi-div.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpi-div.c
@@ -50,7 +50,7 @@ _gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor )
_gcry_mpi_tdiv_r( rem, dividend, divisor );
if( ((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs )
- gcry_mpi_add( rem, rem, divisor);
+ mpi_add (rem, rem, divisor);
if( temp_divisor )
mpi_free(temp_divisor);
@@ -103,8 +103,8 @@ _gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mp
_gcry_mpi_tdiv_qr( quot, rem, dividend, divisor );
if( (divisor_sign ^ dividend->sign) && rem->nlimbs ) {
- gcry_mpi_sub_ui( quot, quot, 1 );
- gcry_mpi_add( rem, rem, divisor);
+ mpi_sub_ui( quot, quot, 1 );
+ mpi_add( rem, rem, divisor);
}
if( temp_divisor )
@@ -328,7 +328,8 @@ _gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor )
void
-gcry_mpi_div (gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor, int round)
+_gcry_mpi_div (gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend,
+ gcry_mpi_t divisor, int round)
{
if (!round)
{
@@ -353,6 +354,3 @@ gcry_mpi_div (gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t d
else
log_bug ("mpi rounding to ceiling not yet implemented\n");
}
-
-
-
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpi-gcd.c b/plugins/MirOTR/Libgcrypt/mpi/mpi-gcd.c
index 51841e7853..77ca05a6fc 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpi-gcd.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpi-gcd.c
@@ -28,7 +28,7 @@
* Return: true if this 1, false in all other cases
*/
int
-gcry_mpi_gcd( gcry_mpi_t g, gcry_mpi_t xa, gcry_mpi_t xb )
+_gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t xa, gcry_mpi_t xb)
{
gcry_mpi_t a, b;
@@ -38,17 +38,15 @@ gcry_mpi_gcd( gcry_mpi_t g, gcry_mpi_t xa, gcry_mpi_t xb )
/* TAOCP Vol II, 4.5.2, Algorithm A */
a->sign = 0;
b->sign = 0;
- while( gcry_mpi_cmp_ui( b, 0 ) ) {
- _gcry_mpi_fdiv_r( g, a, b ); /* g used as temorary variable */
+ while (mpi_cmp_ui (b, 0))
+ {
+ _gcry_mpi_fdiv_r( g, a, b ); /* G is used as temporary variable. */
mpi_set(a,b);
mpi_set(b,g);
- }
+ }
mpi_set(g, a);
mpi_free(a);
mpi_free(b);
- return !gcry_mpi_cmp_ui( g, 1);
+ return !mpi_cmp_ui( g, 1);
}
-
-
-
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpi-inline.c b/plugins/MirOTR/Libgcrypt/mpi/mpi-inline.c
index a1969463c5..39e2222479 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpi-inline.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpi-inline.c
@@ -27,10 +27,9 @@
#include "mpi-internal.h"
-/* always include the header becuase it is only
+/* always include the header because it is only
* included by mpi-internal if __GCC__ is defined but we
* need it here in all cases and the above definition of
* of the macro allows us to do so
*/
#include "mpi-inline.h"
-
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpi-inline.h b/plugins/MirOTR/Libgcrypt/mpi/mpi-inline.h
index 88d9f56c41..94e2aec8a1 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpi-inline.h
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpi-inline.h
@@ -28,8 +28,15 @@
#ifndef G10_MPI_INLINE_H
#define G10_MPI_INLINE_H
+/* Starting with gcc 4.3 "extern inline" conforms in c99 mode to the
+ c99 semantics. To keep the useful old semantics we use an
+ attribute. */
#ifndef G10_MPI_INLINE_DECL
-#define G10_MPI_INLINE_DECL extern __inline__
+# ifdef __GNUC_STDC_INLINE__
+# define G10_MPI_INLINE_DECL extern inline __attribute__ ((__gnu_inline__))
+# else
+# define G10_MPI_INLINE_DECL extern __inline__
+# endif
#endif
G10_MPI_INLINE_DECL mpi_limb_t
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpi-internal.h b/plugins/MirOTR/Libgcrypt/mpi/mpi-internal.h
index f9c1f9d4db..898ca47ef0 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpi-internal.h
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpi-internal.h
@@ -92,7 +92,7 @@ typedef int mpi_size_t; /* (must be a signed type) */
do { \
mpi_size_t _i; \
for( _i = 0; _i < (n); _i++ ) \
- (d)[_i] = (d)[_i]; \
+ (d)[_i] = (s)[_i]; \
} while (0)
#define MPN_COPY_DECR( d, s, n ) \
@@ -145,7 +145,8 @@ typedef int mpi_size_t; /* (must be a signed type) */
*/
#define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) \
do { \
- mpi_limb_t _q, _ql, _r; \
+ mpi_limb_t _ql GCC_ATTR_UNUSED; \
+ mpi_limb_t _q, _r; \
mpi_limb_t _xh, _xl; \
umul_ppmm (_q, _ql, (nh), (di)); \
_q += (nh); /* DI is 2**BITS_PER_MPI_LIMB too small */ \
@@ -275,4 +276,3 @@ mpi_limb_t _gcry_mpih_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
#endif
#endif /*G10_MPI_INTERNAL_H*/
-
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpi-inv.c b/plugins/MirOTR/Libgcrypt/mpi/mpi-inv.c
index 5d269466e0..ee6813b1ed 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpi-inv.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpi-inv.c
@@ -29,7 +29,7 @@
* 1 = (a*x) mod n
*/
int
-gcry_mpi_invm( gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t n )
+_gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t n)
{
#if 0
gcry_mpi_t u, v, u1, u2, u3, v1, v2, v3, q, t1, t2, t3;
@@ -165,6 +165,11 @@ gcry_mpi_invm( gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t n )
int sign;
int odd ;
+ if (!mpi_cmp_ui (a, 0))
+ return 0; /* Inverse does not exists. */
+ if (!mpi_cmp_ui (n, 1))
+ return 0; /* Inverse does not exists. */
+
u = mpi_copy(a);
v = mpi_copy(n);
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpi-mod.c b/plugins/MirOTR/Libgcrypt/mpi/mpi-mod.c
index 948bf23158..88624720c2 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpi-mod.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpi-mod.c
@@ -3,17 +3,17 @@
2007 Free Software Foundation, Inc.
This file is part of Libgcrypt.
-
+
Libgcrypt is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.
-
+
Libgcrypt is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
@@ -35,7 +35,7 @@ struct barrett_ctx_s
gcry_mpi_t m; /* The modulus - may not be modified. */
int m_copied; /* If true, M needs to be released. */
int k;
- gcry_mpi_t y;
+ gcry_mpi_t y;
gcry_mpi_t r1; /* Helper MPI. */
gcry_mpi_t r2; /* Helper MPI. */
gcry_mpi_t r3; /* Helper MPI allocated on demand. */
@@ -47,7 +47,6 @@ void
_gcry_mpi_mod (gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor)
{
_gcry_mpi_fdiv_r (rem, dividend, divisor);
- rem->sign = 0;
}
@@ -56,14 +55,14 @@ _gcry_mpi_mod (gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor)
_gcry_mpi_barrett_free. If COPY is true M will be transferred to
the context and the user may change M. If COPY is false, M may not
be changed until gcry_mpi_barrett_free has been called. */
-mpi_barrett_t
+mpi_barrett_t
_gcry_mpi_barrett_init (gcry_mpi_t m, int copy)
{
mpi_barrett_t ctx;
gcry_mpi_t tmp;
mpi_normalize (m);
- ctx = gcry_xcalloc (1, sizeof *ctx);
+ ctx = xcalloc (1, sizeof *ctx);
if (copy)
{
@@ -100,7 +99,7 @@ _gcry_mpi_barrett_free (mpi_barrett_t ctx)
mpi_free (ctx->r3);
if (ctx->m_copied)
mpi_free (ctx->m);
- gcry_free (ctx);
+ xfree (ctx);
}
}
@@ -111,7 +110,7 @@ _gcry_mpi_barrett_free (mpi_barrett_t ctx)
_gcry_mpi_barrett_init must have been called to do the
precalculations. CTX is the context created by this precalculation
and also conveys M. If the Barret reduction could no be done a
- starightforward reduction method is used.
+ straightforward reduction method is used.
We assume that these conditions are met:
Input: x =(x_2k-1 ...x_0)_b
@@ -126,6 +125,7 @@ _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx)
gcry_mpi_t y = ctx->y;
gcry_mpi_t r1 = ctx->r1;
gcry_mpi_t r2 = ctx->r2;
+ int sign;
mpi_normalize (x);
if (mpi_get_nlimbs (x) > 2*k )
@@ -134,10 +134,13 @@ _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx)
return;
}
+ sign = x->sign;
+ x->sign = 0;
+
/* 1. q1 = floor( x / b^k-1)
* q2 = q1 * y
* q3 = floor( q2 / b^k+1 )
- * Actually, we don't need qx, we can work direct on r2
+ * Actually, we don't need qx, we can work direct on r2
*/
mpi_set ( r2, x );
mpi_rshift_limbs ( r2, k-1 );
@@ -157,7 +160,7 @@ _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx)
r2->nlimbs = k+1;
mpi_sub ( r, r1, r2 );
- if ( mpi_is_neg( r ) )
+ if ( mpi_has_sign ( r ) )
{
if (!ctx->r3)
{
@@ -167,11 +170,12 @@ _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx)
}
mpi_add ( r, r, ctx->r3 );
}
-
+
/* 4. while r >= m do r = r - m */
while ( mpi_cmp( r, m ) >= 0 )
mpi_sub ( r, r, m );
+ x->sign = sign;
}
@@ -179,7 +183,6 @@ void
_gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v,
mpi_barrett_t ctx)
{
- gcry_mpi_mul (w, u, v);
+ mpi_mul (w, u, v);
mpi_mod_barrett (w, w, ctx);
}
-
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpi-mpow.c b/plugins/MirOTR/Libgcrypt/mpi/mpi-mpow.c
index 131c5b67b2..43bd641fb5 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpi-mpow.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpi-mpow.c
@@ -39,7 +39,7 @@ static void barrett_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m
static gcry_mpi_t init_barrett( gcry_mpi_t m, int *k, gcry_mpi_t *r1, gcry_mpi_t *r2 );
static int calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 );
#else
-#define barrett_mulm( w, u, v, m, y, k, r1, r2 ) gcry_mpi_mulm( (w), (u), (v), (m) )
+#define barrett_mulm( w, u, v, m, y, k, r1, r2 ) _gcry_mpi_mulm( (w), (u), (v), (m) )
#endif
@@ -89,7 +89,7 @@ _gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray,
gcry_assert (t);
gcry_assert (k < 10);
- G = gcry_xcalloc( (1<<k) , sizeof *G );
+ G = xcalloc( (1<<k) , sizeof *G );
#ifdef USE_BARRETT
barrett_y = init_barrett( m, &barrett_k, &barrett_r1, &barrett_r2 );
#endif
@@ -130,7 +130,7 @@ _gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray,
#endif
for(i=0; i < (1<<k); i++ )
mpi_free(G[i]);
- gcry_free(G);
+ xfree(G);
}
@@ -204,7 +204,7 @@ calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcr
r2->nlimbs = k+1;
mpi_sub( r, r1, r2 );
- if( mpi_is_neg( r ) ) {
+ if( mpi_has_sign (r) ) {
gcry_mpi_t tmp;
tmp = mpi_alloc( k + 2 );
@@ -221,4 +221,3 @@ calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcr
return 0;
}
#endif /* USE_BARRETT */
-
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpi-mul.c b/plugins/MirOTR/Libgcrypt/mpi/mpi-mul.c
index 25aeaa0a2c..4f4d7096a7 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpi-mul.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpi-mul.c
@@ -31,7 +31,7 @@
void
-gcry_mpi_mul_ui( gcry_mpi_t prod, gcry_mpi_t mult, unsigned long small_mult )
+_gcry_mpi_mul_ui (gcry_mpi_t prod, gcry_mpi_t mult, unsigned long small_mult)
{
mpi_size_t size, prod_size;
mpi_ptr_t prod_ptr;
@@ -61,7 +61,7 @@ gcry_mpi_mul_ui( gcry_mpi_t prod, gcry_mpi_t mult, unsigned long small_mult )
void
-gcry_mpi_mul_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt)
+_gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt)
{
mpi_size_t usize, wsize, limb_cnt;
mpi_ptr_t wp;
@@ -107,7 +107,7 @@ gcry_mpi_mul_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt)
void
-gcry_mpi_mul( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+_gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
{
mpi_size_t usize, vsize, wsize;
mpi_ptr_t up, vp, wp;
@@ -144,7 +144,7 @@ gcry_mpi_mul( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
wsize = usize + vsize;
if ( !mpi_is_secure (w) && (mpi_is_secure (u) || mpi_is_secure (v)) ) {
/* w is not allocated in secure space but u or v is. To make sure
- * that no temporray results are stored in w, we temporary use
+ * that no temporray results are stored in w, we temporary use
* a newly allocated limb space for w */
wp = mpi_alloc_limb_space( wsize, 1 );
assign_wp = 2; /* mark it as 2 so that we can later copy it back to
@@ -205,9 +205,8 @@ gcry_mpi_mul( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
void
-gcry_mpi_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+_gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
{
- gcry_mpi_mul(w, u, v);
- _gcry_mpi_fdiv_r( w, w, m );
+ mpi_mul (w, u, v);
+ _gcry_mpi_tdiv_r (w, w, m);
}
-
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpi-pow.c b/plugins/MirOTR/Libgcrypt/mpi/mpi-pow.c
index ca7ead0285..70bf9e84cd 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpi-pow.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpi-pow.c
@@ -1,6 +1,7 @@
/* mpi-pow.c - MPI functions for exponentiation
* Copyright (C) 1994, 1996, 1998, 2000, 2002
* 2003 Free Software Foundation, Inc.
+ * 2013 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@@ -33,19 +34,27 @@
#include "longlong.h"
+/*
+ * When you need old implementation, please add compilation option
+ * -DUSE_ALGORITHM_SIMPLE_EXPONENTIATION
+ * or expose this line:
+#define USE_ALGORITHM_SIMPLE_EXPONENTIATION 1
+ */
+
+#if defined(USE_ALGORITHM_SIMPLE_EXPONENTIATION)
/****************
* RES = BASE ^ EXPO mod MOD
*/
void
-gcry_mpi_powm (gcry_mpi_t res,
- gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod)
+_gcry_mpi_powm (gcry_mpi_t res,
+ gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod)
{
/* Pointer to the limbs of the arguments, their size and signs. */
mpi_ptr_t rp, ep, mp, bp;
mpi_size_t esize, msize, bsize, rsize;
int msign, bsign, rsign;
/* Flags telling the secure allocation status of the arguments. */
- int esec, msec, bsec, rsec;
+ int esec, msec, bsec;
/* Size of the result including space for temporary values. */
mpi_size_t size;
/* Helper. */
@@ -60,31 +69,35 @@ gcry_mpi_powm (gcry_mpi_t res,
unsigned int ep_nlimbs = 0;
unsigned int xp_nlimbs = 0;
mpi_ptr_t tspace = NULL;
- mpi_size_t tsize = 0;
+ mpi_size_t tsize = 0;
esize = expo->nlimbs;
msize = mod->nlimbs;
size = 2 * msize;
msign = mod->sign;
-
+
esec = mpi_is_secure(expo);
msec = mpi_is_secure(mod);
bsec = mpi_is_secure(base);
- rsec = mpi_is_secure(res);
rp = res->d;
ep = expo->d;
if (!msize)
- msize = 1 / msize; /* Provoke a signal. */
+ _gcry_divide_by_zero();
- if (!esize)
+ if (!esize)
{
/* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 depending
- on if MOD equals 1. */
- rp[0] = 1;
+ on if MOD equals 1. */
res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
+ if (res->nlimbs)
+ {
+ RESIZE_IF_NEEDED (res, 1);
+ rp = res->d;
+ rp[0] = 1;
+ }
res->sign = 0;
goto leave;
}
@@ -103,7 +116,7 @@ gcry_mpi_powm (gcry_mpi_t res,
bsize = base->nlimbs;
bsign = base->sign;
- if (bsize > msize)
+ if (bsize > msize)
{
/* The base is larger than the module. Reduce it.
@@ -147,7 +160,7 @@ gcry_mpi_powm (gcry_mpi_t res,
ep = ep_marker = mpi_alloc_limb_space( esize, esec );
MPN_COPY(ep, rp, esize);
}
- if ( rp == mp )
+ if ( rp == mp )
{
/* RES and MOD are identical. Allocate temporary space for MOD.*/
gcry_assert (!mp_marker);
@@ -164,8 +177,8 @@ gcry_mpi_powm (gcry_mpi_t res,
}
MPN_COPY ( rp, bp, bsize );
rsize = bsize;
- rsign = bsign;
-
+ rsign = 0;
+
/* Main processing. */
{
mpi_size_t i;
@@ -174,13 +187,13 @@ gcry_mpi_powm (gcry_mpi_t res,
mpi_limb_t e;
mpi_limb_t carry_limb;
struct karatsuba_ctx karactx;
-
+
xp_nlimbs = msec? (2 * (msize + 1)):0;
xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
-
+
memset( &karactx, 0, sizeof karactx );
- negative_result = (ep[0] & 1) && base->sign;
-
+ negative_result = (ep[0] & 1) && bsign;
+
i = esize - 1;
e = ep[i];
count_leading_zeros (c, e);
@@ -188,7 +201,7 @@ gcry_mpi_powm (gcry_mpi_t res,
c = BITS_PER_MPI_LIMB - 1 - c;
/* Main loop.
-
+
Make the result be pointed to alternately by XP and RP. This
helps us avoid block copying, which would otherwise be
necessary with the overlap restrictions of
@@ -197,17 +210,17 @@ gcry_mpi_powm (gcry_mpi_t res,
and with 50% probability in the area originally pointed to by XP. */
for (;;)
{
- while (c)
+ while (c)
{
mpi_ptr_t tp;
mpi_size_t xsize;
-
+
/*mpih_mul_n(xp, rp, rp, rsize);*/
if ( rsize < KARATSUBA_THRESHOLD )
_gcry_mpih_sqr_n_basecase( xp, rp, rsize );
- else
+ else
{
- if ( !tspace )
+ if ( !tspace )
{
tsize = 2 * rsize;
tspace = mpi_alloc_limb_space( tsize, 0 );
@@ -231,22 +244,30 @@ gcry_mpi_powm (gcry_mpi_t res,
tp = rp; rp = xp; xp = tp;
rsize = xsize;
- if ( (mpi_limb_signed_t)e < 0 )
+ /* To mitigate the Yarom/Falkner flush+reload cache
+ * side-channel attack on the RSA secret exponent, we do
+ * the multiplication regardless of the value of the
+ * high-bit of E. But to avoid this performance penalty
+ * we do it only if the exponent has been stored in secure
+ * memory and we can thus assume it is a secret exponent. */
+ if (esec || (mpi_limb_signed_t)e < 0)
{
/*mpih_mul( xp, rp, rsize, bp, bsize );*/
- if( bsize < KARATSUBA_THRESHOLD )
+ if( bsize < KARATSUBA_THRESHOLD )
_gcry_mpih_mul ( xp, rp, rsize, bp, bsize );
- else
+ else
_gcry_mpih_mul_karatsuba_case (xp, rp, rsize, bp, bsize,
&karactx);
-
+
xsize = rsize + bsize;
- if ( xsize > msize )
+ if ( xsize > msize )
{
_gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize);
xsize = msize;
}
-
+ }
+ if ( (mpi_limb_signed_t)e < 0 )
+ {
tp = rp; rp = xp; xp = tp;
rsize = xsize;
}
@@ -267,7 +288,7 @@ gcry_mpi_powm (gcry_mpi_t res,
Also make sure the result is put in RES->d (where it already
might be, see above). */
- if ( mod_shift_cnt )
+ if ( mod_shift_cnt )
{
carry_limb = _gcry_mpih_lshift( res->d, rp, rsize, mod_shift_cnt);
rp = res->d;
@@ -283,7 +304,7 @@ gcry_mpi_powm (gcry_mpi_t res,
rp = res->d;
}
- if ( rsize >= msize )
+ if ( rsize >= msize )
{
_gcry_mpih_divrem(rp + msize, 0, rp, rsize, mp, msize);
rsize = msize;
@@ -293,7 +314,7 @@ gcry_mpi_powm (gcry_mpi_t res,
if ( mod_shift_cnt )
_gcry_mpih_rshift( rp, rp, rsize, mod_shift_cnt);
MPN_NORMALIZE (rp, rsize);
-
+
_gcry_mpih_release_karatsuba_ctx (&karactx );
}
@@ -310,7 +331,7 @@ gcry_mpi_powm (gcry_mpi_t res,
gcry_assert (res->d == rp);
res->nlimbs = rsize;
res->sign = rsign;
-
+
leave:
if (mp_marker)
_gcry_mpi_free_limb_space( mp_marker, mp_nlimbs );
@@ -323,4 +344,464 @@ gcry_mpi_powm (gcry_mpi_t res,
if (tspace)
_gcry_mpi_free_limb_space( tspace, 0 );
}
+#else
+/**
+ * Internal function to compute
+ *
+ * X = R * S mod M
+ *
+ * and set the size of X at the pointer XSIZE_P.
+ * Use karatsuba structure at KARACTX_P.
+ *
+ * Condition:
+ * RSIZE >= SSIZE
+ * Enough space for X is allocated beforehand.
+ *
+ * For generic cases, we can/should use gcry_mpi_mulm.
+ * This function is use for specific internal case.
+ */
+static void
+mul_mod (mpi_ptr_t xp, mpi_size_t *xsize_p,
+ mpi_ptr_t rp, mpi_size_t rsize,
+ mpi_ptr_t sp, mpi_size_t ssize,
+ mpi_ptr_t mp, mpi_size_t msize,
+ struct karatsuba_ctx *karactx_p)
+{
+ if( ssize < KARATSUBA_THRESHOLD )
+ _gcry_mpih_mul ( xp, rp, rsize, sp, ssize );
+ else
+ _gcry_mpih_mul_karatsuba_case (xp, rp, rsize, sp, ssize, karactx_p);
+
+ if (rsize + ssize > msize)
+ {
+ _gcry_mpih_divrem (xp + msize, 0, xp, rsize + ssize, mp, msize);
+ *xsize_p = msize;
+ }
+ else
+ *xsize_p = rsize + ssize;
+}
+
+#define SIZE_PRECOMP ((1 << (5 - 1)))
+
+/****************
+ * RES = BASE ^ EXPO mod MOD
+ *
+ * To mitigate the Yarom/Falkner flush+reload cache side-channel
+ * attack on the RSA secret exponent, we don't use the square
+ * routine but multiplication.
+ *
+ * Reference:
+ * Handbook of Applied Cryptography
+ * Algorithm 14.83: Modified left-to-right k-ary exponentiation
+ */
+void
+_gcry_mpi_powm (gcry_mpi_t res,
+ gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod)
+{
+ /* Pointer to the limbs of the arguments, their size and signs. */
+ mpi_ptr_t rp, ep, mp, bp;
+ mpi_size_t esize, msize, bsize, rsize;
+ int msign, bsign, rsign;
+ /* Flags telling the secure allocation status of the arguments. */
+ int esec, msec, bsec;
+ /* Size of the result including space for temporary values. */
+ mpi_size_t size;
+ /* Helper. */
+ int mod_shift_cnt;
+ int negative_result;
+ mpi_ptr_t mp_marker = NULL;
+ mpi_ptr_t bp_marker = NULL;
+ mpi_ptr_t ep_marker = NULL;
+ mpi_ptr_t xp_marker = NULL;
+ unsigned int mp_nlimbs = 0;
+ unsigned int bp_nlimbs = 0;
+ unsigned int ep_nlimbs = 0;
+ unsigned int xp_nlimbs = 0;
+ mpi_ptr_t precomp[SIZE_PRECOMP]; /* Pre-computed array: BASE^1, ^3, ^5, ... */
+ mpi_size_t precomp_size[SIZE_PRECOMP];
+ mpi_size_t W;
+ mpi_ptr_t base_u;
+ mpi_size_t base_u_size;
+ mpi_size_t max_u_size;
+
+ esize = expo->nlimbs;
+ msize = mod->nlimbs;
+ size = 2 * msize;
+ msign = mod->sign;
+
+ if (esize * BITS_PER_MPI_LIMB > 512)
+ W = 5;
+ else if (esize * BITS_PER_MPI_LIMB > 256)
+ W = 4;
+ else if (esize * BITS_PER_MPI_LIMB > 128)
+ W = 3;
+ else if (esize * BITS_PER_MPI_LIMB > 64)
+ W = 2;
+ else
+ W = 1;
+
+ esec = mpi_is_secure(expo);
+ msec = mpi_is_secure(mod);
+ bsec = mpi_is_secure(base);
+
+ rp = res->d;
+ ep = expo->d;
+ if (!msize)
+ _gcry_divide_by_zero();
+
+ if (!esize)
+ {
+ /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 depending
+ on if MOD equals 1. */
+ res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
+ if (res->nlimbs)
+ {
+ RESIZE_IF_NEEDED (res, 1);
+ rp = res->d;
+ rp[0] = 1;
+ }
+ res->sign = 0;
+ goto leave;
+ }
+
+ /* Normalize MOD (i.e. make its most significant bit set) as
+ required by mpn_divrem. This will make the intermediate values
+ in the calculation slightly larger, but the correct result is
+ obtained after a final reduction using the original MOD value. */
+ mp_nlimbs = msec? msize:0;
+ mp = mp_marker = mpi_alloc_limb_space(msize, msec);
+ count_leading_zeros (mod_shift_cnt, mod->d[msize-1]);
+ if (mod_shift_cnt)
+ _gcry_mpih_lshift (mp, mod->d, msize, mod_shift_cnt);
+ else
+ MPN_COPY( mp, mod->d, msize );
+
+ bsize = base->nlimbs;
+ bsign = base->sign;
+ if (bsize > msize)
+ {
+ /* The base is larger than the module. Reduce it.
+
+ Allocate (BSIZE + 1) with space for remainder and quotient.
+ (The quotient is (bsize - msize + 1) limbs.) */
+ bp_nlimbs = bsec ? (bsize + 1):0;
+ bp = bp_marker = mpi_alloc_limb_space( bsize + 1, bsec );
+ MPN_COPY ( bp, base->d, bsize );
+ /* We don't care about the quotient, store it above the
+ * remainder, at BP + MSIZE. */
+ _gcry_mpih_divrem( bp + msize, 0, bp, bsize, mp, msize );
+ bsize = msize;
+ /* Canonicalize the base, since we are going to multiply with it
+ quite a few times. */
+ MPN_NORMALIZE( bp, bsize );
+ }
+ else
+ bp = base->d;
+
+ if (!bsize)
+ {
+ res->nlimbs = 0;
+ res->sign = 0;
+ goto leave;
+ }
+
+
+ /* Make BASE, EXPO and MOD not overlap with RES. */
+ if ( rp == bp )
+ {
+ /* RES and BASE are identical. Allocate temp. space for BASE. */
+ gcry_assert (!bp_marker);
+ bp_nlimbs = bsec? bsize:0;
+ bp = bp_marker = mpi_alloc_limb_space( bsize, bsec );
+ MPN_COPY(bp, rp, bsize);
+ }
+ if ( rp == ep )
+ {
+ /* RES and EXPO are identical. Allocate temp. space for EXPO. */
+ ep_nlimbs = esec? esize:0;
+ ep = ep_marker = mpi_alloc_limb_space( esize, esec );
+ MPN_COPY(ep, rp, esize);
+ }
+ if ( rp == mp )
+ {
+ /* RES and MOD are identical. Allocate temporary space for MOD.*/
+ gcry_assert (!mp_marker);
+ mp_nlimbs = msec?msize:0;
+ mp = mp_marker = mpi_alloc_limb_space( msize, msec );
+ MPN_COPY(mp, rp, msize);
+ }
+
+ /* Copy base to the result. */
+ if (res->alloced < size)
+ {
+ mpi_resize (res, size);
+ rp = res->d;
+ }
+
+ /* Main processing. */
+ {
+ mpi_size_t i, j, k;
+ mpi_ptr_t xp;
+ mpi_size_t xsize;
+ int c;
+ mpi_limb_t e;
+ mpi_limb_t carry_limb;
+ struct karatsuba_ctx karactx;
+ mpi_ptr_t tp;
+
+ xp_nlimbs = msec? (2 * (msize + 1)):0;
+ xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
+
+ memset( &karactx, 0, sizeof karactx );
+ negative_result = (ep[0] & 1) && bsign;
+
+ /* Precompute PRECOMP[], BASE^(2 * i + 1), BASE^1, ^3, ^5, ... */
+ if (W > 1) /* X := BASE^2 */
+ mul_mod (xp, &xsize, bp, bsize, bp, bsize, mp, msize, &karactx);
+ base_u = precomp[0] = mpi_alloc_limb_space (bsize, esec);
+ base_u_size = max_u_size = precomp_size[0] = bsize;
+ MPN_COPY (precomp[0], bp, bsize);
+ for (i = 1; i < (1 << (W - 1)); i++)
+ { /* PRECOMP[i] = BASE^(2 * i + 1) */
+ if (xsize >= base_u_size)
+ mul_mod (rp, &rsize, xp, xsize, base_u, base_u_size,
+ mp, msize, &karactx);
+ else
+ mul_mod (rp, &rsize, base_u, base_u_size, xp, xsize,
+ mp, msize, &karactx);
+ base_u = precomp[i] = mpi_alloc_limb_space (rsize, esec);
+ base_u_size = precomp_size[i] = rsize;
+ if (max_u_size < base_u_size)
+ max_u_size = base_u_size;
+ MPN_COPY (precomp[i], rp, rsize);
+ }
+
+ base_u = mpi_alloc_limb_space (max_u_size, esec);
+ MPN_ZERO (base_u, max_u_size);
+
+ i = esize - 1;
+
+ /* Main loop.
+
+ Make the result be pointed to alternately by XP and RP. This
+ helps us avoid block copying, which would otherwise be
+ necessary with the overlap restrictions of
+ _gcry_mpih_divmod. With 50% probability the result after this
+ loop will be in the area originally pointed by RP (==RES->d),
+ and with 50% probability in the area originally pointed to by XP. */
+ rsign = 0;
+ if (W == 1)
+ {
+ rsize = bsize;
+ }
+ else
+ {
+ rsize = msize;
+ MPN_ZERO (rp, rsize);
+ }
+ MPN_COPY ( rp, bp, bsize );
+
+ e = ep[i];
+ count_leading_zeros (c, e);
+ e = (e << c) << 1;
+ c = BITS_PER_MPI_LIMB - 1 - c;
+
+ j = 0;
+
+ for (;;)
+ if (e == 0)
+ {
+ j += c;
+ i--;
+ if ( i < 0 )
+ {
+ c = 0;
+ break;
+ }
+
+ e = ep[i];
+ c = BITS_PER_MPI_LIMB;
+ }
+ else
+ {
+ int c0;
+ mpi_limb_t e0;
+
+ count_leading_zeros (c0, e);
+ e = (e << c0);
+ c -= c0;
+ j += c0;
+
+ if (c >= W)
+ {
+ e0 = (e >> (BITS_PER_MPI_LIMB - W));
+ e = (e << W);
+ c -= W;
+ }
+ else
+ {
+ i--;
+ if ( i < 0 )
+ {
+ e = (e >> (BITS_PER_MPI_LIMB - c));
+ break;
+ }
+
+ c0 = c;
+ e0 = (e >> (BITS_PER_MPI_LIMB - W))
+ | (ep[i] >> (BITS_PER_MPI_LIMB - W + c0));
+ e = (ep[i] << (W - c0));
+ c = BITS_PER_MPI_LIMB - W + c0;
+ }
+
+ count_trailing_zeros (c0, e0);
+ e0 = (e0 >> c0) >> 1;
+
+ for (j += W - c0; j; j--)
+ {
+ mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+ }
+
+ /*
+ * base_u <= precomp[e0]
+ * base_u_size <= precomp_size[e0]
+ */
+ base_u_size = 0;
+ for (k = 0; k < (1<< (W - 1)); k++)
+ {
+ struct gcry_mpi w, u;
+ w.alloced = w.nlimbs = precomp_size[k];
+ u.alloced = u.nlimbs = precomp_size[k];
+ w.sign = u.sign = 0;
+ w.flags = u.flags = 0;
+ w.d = base_u;
+ u.d = precomp[k];
+
+ mpi_set_cond (&w, &u, k == e0);
+ base_u_size |= (precomp_size[k] & ((mpi_size_t)0 - (k == e0)) );
+ }
+
+ mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
+ mp, msize, &karactx);
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+
+ j = c0;
+ }
+
+ if (c != 0)
+ {
+ j += c;
+ count_trailing_zeros (c, e);
+ e = (e >> c);
+ j -= c;
+ }
+
+ while (j--)
+ {
+ mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+ }
+
+ if (e != 0)
+ {
+ /*
+ * base_u <= precomp[(e>>1)]
+ * base_u_size <= precomp_size[(e>>1)]
+ */
+ base_u_size = 0;
+ for (k = 0; k < (1<< (W - 1)); k++)
+ {
+ struct gcry_mpi w, u;
+ w.alloced = w.nlimbs = precomp_size[k];
+ u.alloced = u.nlimbs = precomp_size[k];
+ w.sign = u.sign = 0;
+ w.flags = u.flags = 0;
+ w.d = base_u;
+ u.d = precomp[k];
+
+ mpi_set_cond (&w, &u, k == (e>>1));
+ base_u_size |= (precomp_size[k] & ((mpi_size_t)0 - (k == (e>>1))) );
+ }
+
+ mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
+ mp, msize, &karactx);
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+
+ for (; c; c--)
+ {
+ mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+ }
+ }
+
+ /* We shifted MOD, the modulo reduction argument, left
+ MOD_SHIFT_CNT steps. Adjust the result by reducing it with the
+ original MOD.
+
+ Also make sure the result is put in RES->d (where it already
+ might be, see above). */
+ if ( mod_shift_cnt )
+ {
+ carry_limb = _gcry_mpih_lshift( res->d, rp, rsize, mod_shift_cnt);
+ rp = res->d;
+ if ( carry_limb )
+ {
+ rp[rsize] = carry_limb;
+ rsize++;
+ }
+ }
+ else if (res->d != rp)
+ {
+ MPN_COPY (res->d, rp, rsize);
+ rp = res->d;
+ }
+
+ if ( rsize >= msize )
+ {
+ _gcry_mpih_divrem(rp + msize, 0, rp, rsize, mp, msize);
+ rsize = msize;
+ }
+
+ /* Remove any leading zero words from the result. */
+ if ( mod_shift_cnt )
+ _gcry_mpih_rshift( rp, rp, rsize, mod_shift_cnt);
+ MPN_NORMALIZE (rp, rsize);
+
+ _gcry_mpih_release_karatsuba_ctx (&karactx );
+ for (i = 0; i < (1 << (W - 1)); i++)
+ _gcry_mpi_free_limb_space( precomp[i], esec ? precomp_size[i] : 0 );
+ _gcry_mpi_free_limb_space (base_u, esec ? max_u_size : 0);
+ }
+
+ /* Fixup for negative results. */
+ if ( negative_result && rsize )
+ {
+ if ( mod_shift_cnt )
+ _gcry_mpih_rshift( mp, mp, msize, mod_shift_cnt);
+ _gcry_mpih_sub( rp, mp, msize, rp, rsize);
+ rsize = msize;
+ rsign = msign;
+ MPN_NORMALIZE(rp, rsize);
+ }
+ gcry_assert (res->d == rp);
+ res->nlimbs = rsize;
+ res->sign = rsign;
+
+ leave:
+ if (mp_marker)
+ _gcry_mpi_free_limb_space( mp_marker, mp_nlimbs );
+ if (bp_marker)
+ _gcry_mpi_free_limb_space( bp_marker, bp_nlimbs );
+ if (ep_marker)
+ _gcry_mpi_free_limb_space( ep_marker, ep_nlimbs );
+ if (xp_marker)
+ _gcry_mpi_free_limb_space( xp_marker, xp_nlimbs );
+}
+#endif
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpi-scan.c b/plugins/MirOTR/Libgcrypt/mpi/mpi-scan.c
index 90699cdd69..e27f7faa99 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpi-scan.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpi-scan.c
@@ -31,79 +31,79 @@
*
* FIXME: This code is VERY ugly!
*/
-int
-_gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx )
-{
- int i, j;
- unsigned n;
- mpi_ptr_t ap;
- mpi_limb_t limb;
+/* int */
+/* _gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx ) */
+/* { */
+/* int i, j; */
+/* unsigned n; */
+/* mpi_ptr_t ap; */
+/* mpi_limb_t limb; */
- ap = a->d;
- for(n=0,i=0; i < a->nlimbs; i++ ) {
- limb = ap[i];
- for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
- if( n == idx )
- return (limb >> j*8) & 0xff;
- }
- return -1;
-}
+/* ap = a->d; */
+/* for(n=0,i=0; i < a->nlimbs; i++ ) { */
+/* limb = ap[i]; */
+/* for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ ) */
+/* if( n == idx ) */
+/* return (limb >> j*8) & 0xff; */
+/* } */
+/* return -1; */
+/* } */
/****************
* Put a value at position IDX into A. idx counts from lsb to msb
*/
-void
-_gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int xc )
-{
- int i, j;
- unsigned n;
- mpi_ptr_t ap;
- mpi_limb_t limb, c;
+/* void */
+/* _gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int xc ) */
+/* { */
+/* int i, j; */
+/* unsigned n; */
+/* mpi_ptr_t ap; */
+/* mpi_limb_t limb, c; */
- c = xc & 0xff;
- ap = a->d;
- for(n=0,i=0; i < a->alloced; i++ ) {
- limb = ap[i];
- for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
- if( n == idx ) {
- #if BYTES_PER_MPI_LIMB == 4
- if( j == 0 )
- limb = (limb & 0xffffff00) | c;
- else if( j == 1 )
- limb = (limb & 0xffff00ff) | (c<<8);
- else if( j == 2 )
- limb = (limb & 0xff00ffff) | (c<<16);
- else
- limb = (limb & 0x00ffffff) | (c<<24);
- #elif BYTES_PER_MPI_LIMB == 8
- if( j == 0 )
- limb = (limb & 0xffffffffffffff00) | c;
- else if( j == 1 )
- limb = (limb & 0xffffffffffff00ff) | (c<<8);
- else if( j == 2 )
- limb = (limb & 0xffffffffff00ffff) | (c<<16);
- else if( j == 3 )
- limb = (limb & 0xffffffff00ffffff) | (c<<24);
- else if( j == 4 )
- limb = (limb & 0xffffff00ffffffff) | (c<<32);
- else if( j == 5 )
- limb = (limb & 0xffff00ffffffffff) | (c<<40);
- else if( j == 6 )
- limb = (limb & 0xff00ffffffffffff) | (c<<48);
- else
- limb = (limb & 0x00ffffffffffffff) | (c<<56);
- #else
- #error please enhance this function, its ugly - i know.
- #endif
- if( a->nlimbs <= i )
- a->nlimbs = i+1;
- ap[i] = limb;
- return;
- }
- }
- abort(); /* index out of range */
-}
+/* c = xc & 0xff; */
+/* ap = a->d; */
+/* for(n=0,i=0; i < a->alloced; i++ ) { */
+/* limb = ap[i]; */
+/* for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ ) */
+/* if( n == idx ) { */
+/* #if BYTES_PER_MPI_LIMB == 4 */
+/* if( j == 0 ) */
+/* limb = (limb & 0xffffff00) | c; */
+/* else if( j == 1 ) */
+/* limb = (limb & 0xffff00ff) | (c<<8); */
+/* else if( j == 2 ) */
+/* limb = (limb & 0xff00ffff) | (c<<16); */
+/* else */
+/* limb = (limb & 0x00ffffff) | (c<<24); */
+/* #elif BYTES_PER_MPI_LIMB == 8 */
+/* if( j == 0 ) */
+/* limb = (limb & 0xffffffffffffff00) | c; */
+/* else if( j == 1 ) */
+/* limb = (limb & 0xffffffffffff00ff) | (c<<8); */
+/* else if( j == 2 ) */
+/* limb = (limb & 0xffffffffff00ffff) | (c<<16); */
+/* else if( j == 3 ) */
+/* limb = (limb & 0xffffffff00ffffff) | (c<<24); */
+/* else if( j == 4 ) */
+/* limb = (limb & 0xffffff00ffffffff) | (c<<32); */
+/* else if( j == 5 ) */
+/* limb = (limb & 0xffff00ffffffffff) | (c<<40); */
+/* else if( j == 6 ) */
+/* limb = (limb & 0xff00ffffffffffff) | (c<<48); */
+/* else */
+/* limb = (limb & 0x00ffffffffffffff) | (c<<56); */
+/* #else */
+/* #error please enhance this function, its ugly - i know. */
+/* #endif */
+/* if( a->nlimbs <= i ) */
+/* a->nlimbs = i+1; */
+/* ap[i] = limb; */
+/* return; */
+/* } */
+/* } */
+/* abort(); /\* index out of range *\/ */
+/* } */
/****************
@@ -128,5 +128,3 @@ _gcry_mpi_trailing_zeros( gcry_mpi_t a )
return count;
}
-
-
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpicoder.c b/plugins/MirOTR/Libgcrypt/mpi/mpicoder.c
index 8f0c76f144..896dda14cc 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpicoder.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpicoder.c
@@ -1,6 +1,7 @@
/* mpicoder.c - Coder for the external representation of MPIs
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
* 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2014 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@@ -37,7 +38,7 @@ mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread,
unsigned int nbits, nbytes, nlimbs, nread=0;
mpi_limb_t a;
gcry_mpi_t val = MPI_NULL;
-
+
if ( *ret_nread < 2 )
goto leave;
nbits = buffer[0] << 8 | buffer[1];
@@ -46,11 +47,6 @@ mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread,
/* log_debug ("mpi too large (%u bits)\n", nbits); */
goto leave;
}
- else if( !nbits )
- {
-/* log_debug ("an mpi of size 0 is not allowed\n"); */
- goto leave;
- }
buffer += 2;
nread = 2;
@@ -64,7 +60,7 @@ mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread,
for ( ; j > 0; j-- )
{
a = 0;
- for (; i < BYTES_PER_MPI_LIMB; i++ )
+ for (; i < BYTES_PER_MPI_LIMB; i++ )
{
if ( ++nread > *ret_nread )
{
@@ -79,7 +75,7 @@ mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread,
i = 0;
val->d[j-1] = a;
}
-
+
leave:
*ret_nread = nread;
return val;
@@ -164,7 +160,7 @@ mpi_fromstr (gcry_mpi_t val, const char *str)
c |= c2 - 'a' + 10;
else if( c2 >= 'A' && c2 <= 'F' )
c |= c2 - 'A' + 10;
- else
+ else
{
mpi_clear(val);
return 1; /* Error. */
@@ -175,81 +171,59 @@ mpi_fromstr (gcry_mpi_t val, const char *str)
i = 0;
val->d[j-1] = a;
}
-
- return 0; /* Okay. */
-}
-
-/* Dump the value of A in a format suitable for debugging to
- Libgcrypt's logging stream. Note that one leading space but no
- trailing space or linefeed will be printed. It is okay to pass
- NULL for A. */
-void
-gcry_mpi_dump (const gcry_mpi_t a)
-{
- int i;
-
- log_printf (" ");
- if (!a)
- log_printf ("[MPI_NULL]");
- else
- {
- if (a->sign)
- log_printf ( "-");
-#if BYTES_PER_MPI_LIMB == 2
-# define X "4"
-#elif BYTES_PER_MPI_LIMB == 4
-# define X "8"
-#elif BYTES_PER_MPI_LIMB == 8
-# define X "16"
-#elif BYTES_PER_MPI_LIMB == 16
-# define X "32"
-#else
-# error please define the format here
-#endif
- for (i=a->nlimbs; i > 0 ; i-- )
- {
- log_printf (i != a->nlimbs? "%0" X "lX":"%lX", (ulong)a->d[i-1]);
- }
-#undef X
- if (!a->nlimbs)
- log_printf ("0");
- }
-}
-
-/* Convience function used internally. */
-void
-_gcry_log_mpidump (const char *text, gcry_mpi_t a)
-{
- log_printf ("%s:", text);
- gcry_mpi_dump (a);
- log_printf ("\n");
+ return 0; /* Okay. */
}
/* Return an allocated buffer with the MPI (msb first). NBYTES
- receives the length of this buffer. Caller must free the return
- string. This function returns an allocated buffer with NBYTES set
- to zero if the value of A is zero. If sign is not NULL, it will be
- set to the sign of the A. On error NULL is returned and ERRNO set
- appropriately. */
+ receives the length of this buffer. If FILL_LE is not 0, the
+ returned value is stored as little endian and right padded with
+ zeroes so that the returned buffer has at least FILL_LE bytes.
+
+ If EXTRAALLOC > 0 the returned buffer has these number of bytes
+ extra allocated at the end; if EXTRAALLOC < 0 the returned buffer
+ has the absolute value of EXTRAALLOC allocated at the begin of the
+ buffer (the are not initialized) and the MPI is stored right after
+ this. This feature is useful to allow the caller to prefix the
+ returned value. EXTRAALLOC is _not_ included in the value stored
+ at NBYTES.
+
+ Caller must free the return string. This function returns an
+ allocated buffer with NBYTES set to zero if the value of A is zero.
+ If sign is not NULL, it will be set to the sign of the A. On error
+ NULL is returned and ERRNO set appropriately. */
static unsigned char *
-do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure)
+do_get_buffer (gcry_mpi_t a, unsigned int fill_le, int extraalloc,
+ unsigned int *nbytes, int *sign, int force_secure)
{
- unsigned char *p, *buffer;
+ unsigned char *p, *buffer, *retbuffer;
+ unsigned int length, tmp;
mpi_limb_t alimb;
int i;
- size_t n;
-
+ size_t n, n2;
+
if (sign)
*sign = a->sign;
*nbytes = a->nlimbs * BYTES_PER_MPI_LIMB;
n = *nbytes? *nbytes:1; /* Allocate at least one byte. */
- p = buffer = (force_secure || mpi_is_secure(a))? gcry_malloc_secure (n)
- : gcry_malloc (n);
- if (!buffer)
+ if (n < fill_le)
+ n = fill_le;
+ if (extraalloc < 0)
+ n2 = n + -extraalloc;
+ else
+ n2 = n + extraalloc;
+
+ retbuffer = (force_secure || mpi_is_secure(a))? xtrymalloc_secure (n2)
+ : xtrymalloc (n2);
+ if (!retbuffer)
return NULL;
+ if (extraalloc < 0)
+ buffer = retbuffer + -extraalloc;
+ else
+ buffer = retbuffer;
+ p = buffer;
for (i=a->nlimbs-1; i >= 0; i--)
{
@@ -273,26 +247,53 @@ do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure)
#endif
}
+ if (fill_le)
+ {
+ length = *nbytes;
+ /* Reverse buffer and pad with zeroes. */
+ for (i=0; i < length/2; i++)
+ {
+ tmp = buffer[i];
+ buffer[i] = buffer[length-1-i];
+ buffer[length-1-i] = tmp;
+ }
+ /* Pad with zeroes. */
+ for (p = buffer + length; length < fill_le; length++)
+ *p++ = 0;
+ *nbytes = length;
+
+ return retbuffer;
+ }
+
/* This is sub-optimal but we need to do the shift operation because
the caller has to free the returned buffer. */
- for (p=buffer; !*p && *nbytes; p++, --*nbytes)
+ for (p=buffer; *nbytes && !*p; p++, --*nbytes)
;
if (p != buffer)
- memmove (buffer,p, *nbytes);
- return buffer;
+ memmove (buffer, p, *nbytes);
+ return retbuffer;
}
byte *
-_gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign)
+_gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int fill_le,
+ unsigned int *r_nbytes, int *sign)
+{
+ return do_get_buffer (a, fill_le, 0, r_nbytes, sign, 0);
+}
+
+byte *
+_gcry_mpi_get_buffer_extra (gcry_mpi_t a, unsigned int fill_le, int extraalloc,
+ unsigned int *r_nbytes, int *sign)
{
- return do_get_buffer (a, nbytes, sign, 0);
+ return do_get_buffer (a, fill_le, extraalloc, r_nbytes, sign, 0);
}
byte *
-_gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned *nbytes, int *sign)
+_gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned int fill_le,
+ unsigned int *r_nbytes, int *sign)
{
- return do_get_buffer (a, nbytes, sign, 1);
+ return do_get_buffer (a, fill_le, 0, r_nbytes, sign, 1);
}
@@ -309,12 +310,18 @@ _gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg,
mpi_limb_t alimb;
int nlimbs;
int i;
-
+
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
RESIZE_IF_NEEDED(a, nlimbs);
a->sign = sign;
-
- for (i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; )
+
+ for (i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; )
{
#if BYTES_PER_MPI_LIMB == 4
alimb = *p-- ;
@@ -371,24 +378,83 @@ _gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg,
}
+static void
+onecompl (gcry_mpi_t a)
+{
+ mpi_ptr_t ap;
+ mpi_size_t n;
+ unsigned int i;
+ unsigned int nbits = mpi_get_nbits (a);
+
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
+ mpi_normalize (a);
+ ap = a->d;
+ n = a->nlimbs;
+
+ for( i = 0; i < n; i++ )
+ ap[i] ^= (mpi_limb_t)(-1);
+
+ a->sign = 0;
+ mpi_clear_highbit (a, nbits-1);
+}
+
+
+/* Perform a two's complement operation on buffer P of size N bytes. */
+static void
+twocompl (unsigned char *p, unsigned int n)
+{
+ int i;
+
+ for (i=n-1; i >= 0 && !p[i]; i--)
+ ;
+ if (i >= 0)
+ {
+ if ((p[i] & 0x01))
+ p[i] = (((p[i] ^ 0xfe) | 0x01) & 0xff);
+ else if ((p[i] & 0x02))
+ p[i] = (((p[i] ^ 0xfc) | 0x02) & 0xfe);
+ else if ((p[i] & 0x04))
+ p[i] = (((p[i] ^ 0xf8) | 0x04) & 0xfc);
+ else if ((p[i] & 0x08))
+ p[i] = (((p[i] ^ 0xf0) | 0x08) & 0xf8);
+ else if ((p[i] & 0x10))
+ p[i] = (((p[i] ^ 0xe0) | 0x10) & 0xf0);
+ else if ((p[i] & 0x20))
+ p[i] = (((p[i] ^ 0xc0) | 0x20) & 0xe0);
+ else if ((p[i] & 0x40))
+ p[i] = (((p[i] ^ 0x80) | 0x40) & 0xc0);
+ else
+ p[i] = 0x80;
+
+ for (i--; i >= 0; i--)
+ p[i] ^= 0xff;
+ }
+}
+
+
/* Convert the external representation of an integer stored in BUFFER
with a length of BUFLEN into a newly create MPI returned in
RET_MPI. If NBYTES is not NULL, it will receive the number of
bytes actually scanned after a successful operation. */
-gcry_error_t
-gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
- const void *buffer_arg, size_t buflen, size_t *nscanned)
+gcry_err_code_t
+_gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
+ const void *buffer_arg, size_t buflen, size_t *nscanned)
{
const unsigned char *buffer = (const unsigned char*)buffer_arg;
struct gcry_mpi *a = NULL;
unsigned int len;
- int secure = (buffer && gcry_is_secure (buffer));
+ int secure = (buffer && _gcry_is_secure (buffer));
if (format == GCRYMPI_FMT_SSH)
len = 0;
else
len = buflen;
-
+
if (format == GCRYMPI_FMT_STD)
{
const unsigned char *s = buffer;
@@ -397,16 +463,15 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
/BYTES_PER_MPI_LIMB)
: mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
if (len)
- {
+ {
+ _gcry_mpi_set_buffer (a, s, len, 0);
a->sign = !!(*s & 0x80);
if (a->sign)
{
- /* FIXME: we have to convert from 2compl to magnitude format */
- mpi_free (a);
- return gcry_error (GPG_ERR_INTERNAL);
+ onecompl (a);
+ mpi_add_ui (a, a, 1);
+ a->sign = 1;
}
- else
- _gcry_mpi_set_buffer (a, s, len, 0);
}
if (ret_mpi)
{
@@ -415,6 +480,8 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
}
else
mpi_free(a);
+ if (nscanned)
+ *nscanned = len;
return 0;
}
else if (format == GCRYMPI_FMT_USG)
@@ -432,6 +499,8 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
}
else
mpi_free(a);
+ if (nscanned)
+ *nscanned = len;
return 0;
}
else if (format == GCRYMPI_FMT_PGP)
@@ -449,37 +518,40 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
mpi_free(a);
a = NULL;
}
- return a? 0 : gcry_error (GPG_ERR_INV_OBJ);
+ return a? 0 : GPG_ERR_INV_OBJ;
}
else if (format == GCRYMPI_FMT_SSH)
{
const unsigned char *s = buffer;
size_t n;
-
+
+ /* This test is not strictly necessary and an assert (!len)
+ would be sufficient. We keep this test in case we later
+ allow the BUFLEN argument to act as a sanitiy check. Same
+ below. */
if (len && len < 4)
- return gcry_error (GPG_ERR_TOO_SHORT);
+ return GPG_ERR_TOO_SHORT;
n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
- s += 4;
+ s += 4;
if (len)
len -= 4;
if (len && n > len)
- return gcry_error (GPG_ERR_TOO_LARGE);
+ return GPG_ERR_TOO_LARGE;
a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
/BYTES_PER_MPI_LIMB)
: mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
if (n)
{
+ _gcry_mpi_set_buffer( a, s, n, 0 );
a->sign = !!(*s & 0x80);
if (a->sign)
{
- /* FIXME: we have to convert from 2compl to magnitude format */
- mpi_free(a);
- return gcry_error (GPG_ERR_INTERNAL);
+ onecompl (a);
+ mpi_add_ui (a, a, 1);
+ a->sign = 1;
}
- else
- _gcry_mpi_set_buffer( a, s, n, 0 );
}
if (nscanned)
*nscanned = n+4;
@@ -496,25 +568,27 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
{
/* We can only handle C strings for now. */
if (buflen)
- return gcry_error (GPG_ERR_INV_ARG);
+ return GPG_ERR_INV_ARG;
a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
if (mpi_fromstr (a, (const char *)buffer))
{
mpi_free (a);
- return gcry_error (GPG_ERR_INV_OBJ);
+ return GPG_ERR_INV_OBJ;
}
- if (ret_mpi)
+ if (ret_mpi)
{
mpi_normalize ( a );
*ret_mpi = a;
}
else
mpi_free(a);
+ if (nscanned)
+ *nscanned = strlen ((const char*)buffer);
return 0;
}
else
- return gcry_error (GPG_ERR_INV_ARG);
+ return GPG_ERR_INV_ARG;
}
@@ -524,53 +598,77 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
receives the actual length of the external representation unless it
has been passed as NULL. BUFFER may be NULL to query the required
length. */
-gcry_error_t
-gcry_mpi_print (enum gcry_mpi_format format,
- unsigned char *buffer, size_t buflen,
- size_t *nwritten, struct gcry_mpi *a)
+gcry_err_code_t
+_gcry_mpi_print (enum gcry_mpi_format format,
+ unsigned char *buffer, size_t buflen,
+ size_t *nwritten, struct gcry_mpi *a)
{
unsigned int nbits = mpi_get_nbits (a);
size_t len;
size_t dummy_nwritten;
-
+ int negative;
+
if (!nwritten)
nwritten = &dummy_nwritten;
+ /* Libgcrypt does no always care to set clear the sign if the value
+ is 0. For printing this is a bit of a surprise, in particular
+ because if some of the formats don't support negative numbers but
+ should be able to print a zero. Thus we need this extra test
+ for a negative number. */
+ if (a->sign && _gcry_mpi_cmp_ui (a, 0))
+ negative = 1;
+ else
+ negative = 0;
+
len = buflen;
*nwritten = 0;
- if (format == GCRYMPI_FMT_STD)
+ if (format == GCRYMPI_FMT_STD)
{
unsigned char *tmp;
int extra = 0;
unsigned int n;
-
- if (a->sign)
- return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */
- tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+ tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
if (!tmp)
- return gpg_error_from_syserror ();
- if (n && (*tmp & 0x80))
+ return gpg_err_code_from_syserror ();
+
+ if (negative)
+ {
+ twocompl (tmp, n);
+ if (!(*tmp & 0x80))
+ {
+ /* Need to extend the sign. */
+ n++;
+ extra = 2;
+ }
+ }
+ else if (n && (*tmp & 0x80))
{
+ /* Positive but the high bit of the returned buffer is set.
+ Thus we need to print an extra leading 0x00 so that the
+ output is interpreted as a positive number. */
n++;
- extra=1;
+ extra = 1;
}
-
+
if (buffer && n > len)
{
/* The provided buffer is too short. */
- gcry_free (tmp);
- return gcry_error (GPG_ERR_TOO_SHORT);
+ xfree (tmp);
+ return GPG_ERR_TOO_SHORT;
}
if (buffer)
{
unsigned char *s = buffer;
- if (extra)
+ if (extra == 1)
*s++ = 0;
- memcpy (s, tmp, n-extra);
+ else if (extra)
+ *s++ = 0xff;
+ memcpy (s, tmp, n-!!extra);
}
- gcry_free(tmp);
+ xfree (tmp);
*nwritten = n;
return 0;
}
@@ -581,17 +679,18 @@ gcry_mpi_print (enum gcry_mpi_format format,
/* Note: We ignore the sign for this format. */
/* FIXME: for performance reasons we should put this into
mpi_aprint because we can then use the buffer directly. */
+
if (buffer && n > len)
- return gcry_error (GPG_ERR_TOO_SHORT);
+ return GPG_ERR_TOO_SHORT;
if (buffer)
{
unsigned char *tmp;
- tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+ tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
if (!tmp)
- return gpg_error_from_syserror ();
+ return gpg_err_code_from_syserror ();
memcpy (buffer, tmp, n);
- gcry_free (tmp);
+ xfree (tmp);
}
*nwritten = n;
return 0;
@@ -599,13 +698,13 @@ gcry_mpi_print (enum gcry_mpi_format format,
else if (format == GCRYMPI_FMT_PGP)
{
unsigned int n = (nbits + 7)/8;
-
+
/* The PGP format can only handle unsigned integers. */
- if( a->sign )
- return gcry_error (GPG_ERR_INV_ARG);
+ if (negative)
+ return GPG_ERR_INV_ARG;
if (buffer && n+2 > len)
- return gcry_error (GPG_ERR_TOO_SHORT);
+ return GPG_ERR_TOO_SHORT;
if (buffer)
{
@@ -614,12 +713,12 @@ gcry_mpi_print (enum gcry_mpi_format format,
s[0] = nbits >> 8;
s[1] = nbits;
-
- tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+
+ tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
if (!tmp)
- return gpg_error_from_syserror ();
+ return gpg_err_code_from_syserror ();
memcpy (s+2, tmp, n);
- gcry_free (tmp);
+ xfree (tmp);
}
*nwritten = n+2;
return 0;
@@ -629,14 +728,22 @@ gcry_mpi_print (enum gcry_mpi_format format,
unsigned char *tmp;
int extra = 0;
unsigned int n;
-
- if (a->sign)
- return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */
-
- tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+
+ tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
if (!tmp)
- return gpg_error_from_syserror ();
- if (n && (*tmp & 0x80))
+ return gpg_err_code_from_syserror ();
+
+ if (negative)
+ {
+ twocompl (tmp, n);
+ if (!(*tmp & 0x80))
+ {
+ /* Need to extend the sign. */
+ n++;
+ extra = 2;
+ }
+ }
+ else if (n && (*tmp & 0x80))
{
n++;
extra=1;
@@ -644,24 +751,25 @@ gcry_mpi_print (enum gcry_mpi_format format,
if (buffer && n+4 > len)
{
- gcry_free(tmp);
- return gcry_error (GPG_ERR_TOO_SHORT);
+ xfree(tmp);
+ return GPG_ERR_TOO_SHORT;
}
if (buffer)
{
unsigned char *s = buffer;
-
+
*s++ = n >> 24;
*s++ = n >> 16;
*s++ = n >> 8;
*s++ = n;
- if (extra)
+ if (extra == 1)
*s++ = 0;
-
- memcpy (s, tmp, n-extra);
+ else if (extra)
+ *s++ = 0xff;
+ memcpy (s, tmp, n-!!extra);
}
- gcry_free (tmp);
+ xfree (tmp);
*nwritten = 4+n;
return 0;
}
@@ -671,30 +779,30 @@ gcry_mpi_print (enum gcry_mpi_format format,
int i;
int extra = 0;
unsigned int n = 0;
-
- tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+
+ tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
if (!tmp)
- return gpg_error_from_syserror ();
+ return gpg_err_code_from_syserror ();
if (!n || (*tmp & 0x80))
extra = 2;
- if (buffer && 2*n + extra + !!a->sign + 1 > len)
+ if (buffer && 2*n + extra + negative + 1 > len)
{
- gcry_free(tmp);
- return gcry_error (GPG_ERR_TOO_SHORT);
+ xfree(tmp);
+ return GPG_ERR_TOO_SHORT;
}
if (buffer)
{
unsigned char *s = buffer;
- if (a->sign)
+ if (negative)
*s++ = '-';
if (extra)
{
*s++ = '0';
*s++ = '0';
}
-
+
for (i=0; i < n; i++)
{
unsigned int c = tmp[i];
@@ -706,15 +814,15 @@ gcry_mpi_print (enum gcry_mpi_format format,
*s++ = 0;
*nwritten = s - buffer;
}
- else
+ else
{
- *nwritten = 2*n + extra + !!a->sign + 1;
+ *nwritten = 2*n + extra + negative + 1;
}
- gcry_free (tmp);
+ xfree (tmp);
return 0;
}
else
- return gcry_error (GPG_ERR_INV_ARG);
+ return GPG_ERR_INV_ARG;
}
@@ -723,26 +831,30 @@ gcry_mpi_print (enum gcry_mpi_format format,
* The caller has to supply the address of a pointer. NWRITTEN may be
* NULL.
*/
-gcry_error_t
-gcry_mpi_aprint (enum gcry_mpi_format format,
- unsigned char **buffer, size_t *nwritten,
- struct gcry_mpi *a)
+gcry_err_code_t
+_gcry_mpi_aprint (enum gcry_mpi_format format,
+ unsigned char **buffer, size_t *nwritten,
+ struct gcry_mpi *a)
{
size_t n;
- gcry_error_t rc;
-
+ gcry_err_code_t rc;
+
*buffer = NULL;
- rc = gcry_mpi_print (format, NULL, 0, &n, a);
+ rc = _gcry_mpi_print (format, NULL, 0, &n, a);
if (rc)
return rc;
- *buffer = mpi_is_secure(a) ? gcry_malloc_secure (n) : gcry_malloc (n);
+ *buffer = mpi_is_secure(a) ? xtrymalloc_secure (n?n:1) : xtrymalloc (n?n:1);
if (!*buffer)
- return gpg_error_from_syserror ();
- rc = gcry_mpi_print( format, *buffer, n, &n, a );
+ return gpg_err_code_from_syserror ();
+ /* If the returned buffer will have a length of 0, we nevertheless
+ allocated 1 byte (malloc needs it anyway) and store a 0. */
+ if (!n)
+ **buffer = 0;
+ rc = _gcry_mpi_print( format, *buffer, n, &n, a );
if (rc)
{
- gcry_free(*buffer);
+ xfree (*buffer);
*buffer = NULL;
}
else if (nwritten)
@@ -750,3 +862,58 @@ gcry_mpi_aprint (enum gcry_mpi_format format,
return rc;
}
+
+/* Turn VALUE into an octet string and store it in an allocated buffer
+ at R_FRAME or - if R_RAME is NULL - copy it into the caller
+ provided buffer SPACE; either SPACE or R_FRAME may be used. If
+ SPACE if not NULL, the caller must provide a buffer of at least
+ NBYTES. If the resulting octet string is shorter than NBYTES pad
+ it to the left with zeroes. If VALUE does not fit into NBYTES
+ return an error code. */
+gpg_err_code_t
+_gcry_mpi_to_octet_string (unsigned char **r_frame, void *space,
+ gcry_mpi_t value, size_t nbytes)
+{
+ gpg_err_code_t rc;
+ size_t nframe, noff, n;
+ unsigned char *frame;
+
+ if (!r_frame == !space)
+ return GPG_ERR_INV_ARG; /* Only one may be used. */
+
+ if (r_frame)
+ *r_frame = NULL;
+
+ rc = _gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nframe, value);
+ if (rc)
+ return rc;
+ if (nframe > nbytes)
+ return GPG_ERR_TOO_LARGE; /* Value too long to fit into NBYTES. */
+
+ noff = (nframe < nbytes)? nbytes - nframe : 0;
+ n = nframe + noff;
+ if (space)
+ frame = space;
+ else
+ {
+ frame = mpi_is_secure (value)? xtrymalloc_secure (n) : xtrymalloc (n);
+ if (!frame)
+ {
+ rc = gpg_err_code_from_syserror ();
+ return rc;
+ }
+ }
+ if (noff)
+ memset (frame, 0, noff);
+ nframe += noff;
+ rc = _gcry_mpi_print (GCRYMPI_FMT_USG, frame+noff, nframe-noff, NULL, value);
+ if (rc)
+ {
+ xfree (frame);
+ return rc;
+ }
+
+ if (r_frame)
+ *r_frame = frame;
+ return 0;
+}
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpih-add1-asm.S b/plugins/MirOTR/Libgcrypt/mpi/mpih-add1-asm.S
new file mode 100644
index 0000000000..f0ec89cc64
--- /dev/null
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpih-add1-asm.S
@@ -0,0 +1,63 @@
+/* AMD64 (x86_64) add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, rdi
+ * mpi_ptr_t s1_ptr, rsi
+ * mpi_ptr_t s2_ptr, rdx
+ * mpi_size_t size) rcx
+ */
+
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+ leaq (%rsi,%rcx,8), %rsi
+ leaq (%rdi,%rcx,8), %rdi
+ leaq (%rdx,%rcx,8), %rdx
+ negq %rcx
+ xorl %eax, %eax /* clear cy */
+
+ ALIGN(4) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%rcx,8), %rax
+ movq (%rdx,%rcx,8), %r10
+ adcq %r10, %rax
+ movq %rax, (%rdi,%rcx,8)
+ incq %rcx
+ jne .Loop
+
+ movq %rcx, %rax /* zero %rax */
+ adcq %rax, %rax
+ ret
+ \ No newline at end of file
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpih-div.c b/plugins/MirOTR/Libgcrypt/mpi/mpih-div.c
index e41e205e1d..57c1b58487 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpih-div.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpih-div.c
@@ -48,7 +48,7 @@ _gcry_mpih_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
{
mpi_size_t i;
mpi_limb_t n1, n0, r;
- int dummy;
+ mpi_limb_t dummy GCC_ATTR_UNUSED;
/* Botch: Should this be handled at all? Rely on callers? */
if( !dividend_size )
@@ -212,9 +212,8 @@ _gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
switch(dsize) {
case 0:
- /* We are asked to divide by zero, so go ahead and do it! (To make
- the compiler not remove this statement, return the value.) */
- return 1 / dsize;
+ _gcry_divide_by_zero();
+ break;
case 1:
{
@@ -397,7 +396,7 @@ _gcry_mpih_divmod_1( mpi_ptr_t quot_ptr,
{
mpi_size_t i;
mpi_limb_t n1, n0, r;
- int dummy;
+ mpi_limb_t dummy GCC_ATTR_UNUSED;
if( !dividend_size )
return 0;
@@ -531,5 +530,3 @@ _gcry_mpih_divmod_1( mpi_ptr_t quot_ptr,
return r;
}
}
-
-
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpih-lshift-asm.S b/plugins/MirOTR/Libgcrypt/mpi/mpih-lshift-asm.S
new file mode 100644
index 0000000000..e87dd1a99b
--- /dev/null
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpih-lshift-asm.S
@@ -0,0 +1,77 @@
+/* AMD64 (x86_64) lshift -- Left shift a limb vector and store
+ * result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, rdi
+ * mpi_ptr_t up, rsi
+ * mpi_size_t usize, rdx
+ * unsigned cnt) rcx
+ */
+
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+ movq -8(%rsi,%rdx,8), %mm7
+ movd %ecx, %mm1
+ movl $64, %eax
+ subl %ecx, %eax
+ movd %eax, %mm0
+ movq %mm7, %mm3
+ psrlq %mm0, %mm7
+ movd %mm7, %rax
+ subq $2, %rdx
+ jl .Lendo
+
+ ALIGN(4) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%rdx,8), %mm6
+ movq %mm6, %mm2
+ psrlq %mm0, %mm6
+ psllq %mm1, %mm3
+ por %mm6, %mm3
+ movq %mm3, 8(%rdi,%rdx,8)
+ je .Lende
+ movq -8(%rsi,%rdx,8), %mm7
+ movq %mm7, %mm3
+ psrlq %mm0, %mm7
+ psllq %mm1, %mm2
+ por %mm7, %mm2
+ movq %mm2, (%rdi,%rdx,8)
+ subq $2, %rdx
+ jge .Loop
+
+.Lendo: movq %mm3, %mm2
+.Lende: psllq %mm1, %mm2
+ movq %mm2, (%rdi)
+ emms
+ ret
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpih-mul.c b/plugins/MirOTR/Libgcrypt/mpi/mpih-mul.c
index e1f6f58eb5..8b6f06a30a 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpih-mul.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpih-mul.c
@@ -353,7 +353,7 @@ _gcry_mpih_mul_n( mpi_ptr_t prodp,
_gcry_mpih_sqr_n_basecase( prodp, up, size );
else {
mpi_ptr_t tspace;
- secure = gcry_is_secure( up );
+ secure = _gcry_is_secure( up );
tspace = mpi_alloc_limb_space( 2 * size, secure );
_gcry_mpih_sqr_n( prodp, up, size, tspace );
_gcry_mpi_free_limb_space (tspace, 2 * size );
@@ -364,7 +364,7 @@ _gcry_mpih_mul_n( mpi_ptr_t prodp,
mul_n_basecase( prodp, up, vp, size );
else {
mpi_ptr_t tspace;
- secure = gcry_is_secure( up ) || gcry_is_secure( vp );
+ secure = _gcry_is_secure( up ) || _gcry_is_secure( vp );
tspace = mpi_alloc_limb_space( 2 * size, secure );
mul_n (prodp, up, vp, size, tspace);
_gcry_mpi_free_limb_space (tspace, 2 * size );
@@ -386,9 +386,9 @@ _gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp,
if( ctx->tspace )
_gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
ctx->tspace_nlimbs = 2 * vsize;
- ctx->tspace = mpi_alloc_limb_space( 2 * vsize,
- (gcry_is_secure( up )
- || gcry_is_secure( vp )) );
+ ctx->tspace = mpi_alloc_limb_space (2 * vsize,
+ (_gcry_is_secure (up)
+ || _gcry_is_secure (vp)));
ctx->tspace_size = vsize;
}
@@ -402,8 +402,9 @@ _gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp,
if( ctx->tp )
_gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
ctx->tp_nlimbs = 2 * vsize;
- ctx->tp = mpi_alloc_limb_space( 2 * vsize, gcry_is_secure( up )
- || gcry_is_secure( vp ) );
+ ctx->tp = mpi_alloc_limb_space (2 * vsize,
+ (_gcry_is_secure (up)
+ || _gcry_is_secure (vp)));
ctx->tp_size = vsize;
}
@@ -423,7 +424,7 @@ _gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp,
}
else {
if( !ctx->next ) {
- ctx->next = gcry_xcalloc( 1, sizeof *ctx );
+ ctx->next = xcalloc( 1, sizeof *ctx );
}
_gcry_mpih_mul_karatsuba_case( ctx->tspace,
vp, vsize,
@@ -452,7 +453,7 @@ _gcry_mpih_release_karatsuba_ctx( struct karatsuba_ctx *ctx )
_gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
if( ctx->tspace )
_gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
- gcry_free( ctx );
+ xfree( ctx );
}
}
@@ -526,5 +527,3 @@ _gcry_mpih_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
_gcry_mpih_release_karatsuba_ctx( &ctx );
return *prod_endp;
}
-
-
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpih-mul1-asm.S b/plugins/MirOTR/Libgcrypt/mpi/mpih-mul1-asm.S
new file mode 100644
index 0000000000..54b0ab4891
--- /dev/null
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpih-mul1-asm.S
@@ -0,0 +1,65 @@
+/* AMD64 mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (rdi)
+ * mpi_ptr_t s1_ptr, (rsi)
+ * mpi_size_t s1_size, (rdx)
+ * mpi_limb_t s2_limb) (rcx)
+ */
+
+
+ TEXT
+ ALIGN(5)
+ .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1:)
+
+ movq %rdx, %r11
+ leaq (%rsi,%rdx,8), %rsi
+ leaq (%rdi,%rdx,8), %rdi
+ negq %r11
+ xorl %r8d, %r8d
+
+.Loop: movq (%rsi,%r11,8), %rax
+ mulq %rcx
+ addq %r8, %rax
+ movl $0, %r8d
+ adcq %rdx, %r8
+ movq %rax, (%rdi,%r11,8)
+ incq %r11
+ jne .Loop
+
+ movq %r8, %rax
+ ret
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpih-mul2-asm.S b/plugins/MirOTR/Libgcrypt/mpi/mpih-mul2-asm.S
new file mode 100644
index 0000000000..a332a1d047
--- /dev/null
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpih-mul2-asm.S
@@ -0,0 +1,64 @@
+/* AMD64 addmul2 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (rdi)
+ * mpi_ptr_t s1_ptr, (rsi)
+ * mpi_size_t s1_size, (rdx)
+ * mpi_limb_t s2_limb) (rcx)
+ */
+ TEXT
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+ movq %rdx, %r11
+ leaq (%rsi,%rdx,8), %rsi
+ leaq (%rdi,%rdx,8), %rdi
+ negq %r11
+ xorl %r8d, %r8d
+ xorl %r10d, %r10d
+
+ ALIGN(3) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%r11,8), %rax
+ mulq %rcx
+ addq (%rdi,%r11,8), %rax
+ adcq %r10, %rdx
+ addq %r8, %rax
+ movq %r10, %r8
+ movq %rax, (%rdi,%r11,8)
+ adcq %rdx, %r8
+ incq %r11
+ jne .Loop
+
+ movq %r8, %rax
+ ret
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpih-mul3-asm.S b/plugins/MirOTR/Libgcrypt/mpi/mpih-mul3-asm.S
new file mode 100644
index 0000000000..4d458a794c
--- /dev/null
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpih-mul3-asm.S
@@ -0,0 +1,66 @@
+/* AMD64 submul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (rdi)
+ * mpi_ptr_t s1_ptr, (rsi)
+ * mpi_size_t s1_size, (rdx)
+ * mpi_limb_t s2_limb) (rcx)
+ */
+ TEXT
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+
+ movq %rdx, %r11
+ leaq (%rsi,%r11,8), %rsi
+ leaq (%rdi,%r11,8), %rdi
+ negq %r11
+ xorl %r8d, %r8d
+
+ ALIGN(3) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%r11,8), %rax
+ movq (%rdi,%r11,8), %r10
+ mulq %rcx
+ subq %r8, %r10
+ movl $0, %r8d
+ adcl %r8d, %r8d
+ subq %rax, %r10
+ adcq %rdx, %r8
+ movq %r10, (%rdi,%r11,8)
+ incq %r11
+ jne .Loop
+
+ movq %r8, %rax
+ ret
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpih-rshift-asm.S b/plugins/MirOTR/Libgcrypt/mpi/mpih-rshift-asm.S
new file mode 100644
index 0000000000..4cfc8f6028
--- /dev/null
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpih-rshift-asm.S
@@ -0,0 +1,80 @@
+/* AMD64 (x86_64) rshift -- Right shift a limb vector and store
+ * result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, rdi
+ * mpi_ptr_t up, rsi
+ * mpi_size_t usize, rdx
+ * unsigned cnt) rcx
+ */
+
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+ movq (%rsi), %mm7
+ movd %ecx, %mm1
+ movl $64, %eax
+ subl %ecx, %eax
+ movd %eax, %mm0
+ movq %mm7, %mm3
+ psllq %mm0, %mm7
+ movd %mm7, %rax
+ leaq (%rsi,%rdx,8), %rsi
+ leaq (%rdi,%rdx,8), %rdi
+ negq %rdx
+ addq $2, %rdx
+ jg .Lendo
+
+ ALIGN(8) /* minimal alignment for claimed speed */
+.Loop: movq -8(%rsi,%rdx,8), %mm6
+ movq %mm6, %mm2
+ psllq %mm0, %mm6
+ psrlq %mm1, %mm3
+ por %mm6, %mm3
+ movq %mm3, -16(%rdi,%rdx,8)
+ je .Lende
+ movq (%rsi,%rdx,8), %mm7
+ movq %mm7, %mm3
+ psllq %mm0, %mm7
+ psrlq %mm1, %mm2
+ por %mm7, %mm2
+ movq %mm2, -8(%rdi,%rdx,8)
+ addq $2, %rdx
+ jle .Loop
+
+.Lendo: movq %mm3, %mm2
+.Lende: psrlq %mm1, %mm2
+ movq %mm2, -8(%rdi)
+ emms
+ ret
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpih-sub1-asm.S b/plugins/MirOTR/Libgcrypt/mpi/mpih-sub1-asm.S
new file mode 100644
index 0000000000..b3609b024f
--- /dev/null
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpih-sub1-asm.S
@@ -0,0 +1,61 @@
+/* AMD64 (x86_64) sub_n -- Subtract two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, rdi
+ * mpi_ptr_t s1_ptr, rsi
+ * mpi_ptr_t s2_ptr, rdx
+ * mpi_size_t size) rcx
+ */
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+ leaq (%rsi,%rcx,8), %rsi
+ leaq (%rdi,%rcx,8), %rdi
+ leaq (%rdx,%rcx,8), %rdx
+ negq %rcx
+ xorl %eax, %eax /* clear cy */
+
+ ALIGN(4) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%rcx,8), %rax
+ movq (%rdx,%rcx,8), %r10
+ sbbq %r10, %rax
+ movq %rax, (%rdi,%rcx,8)
+ incq %rcx
+ jne .Loop
+
+ movq %rcx, %rax /* zero %rax */
+ adcq %rax, %rax
+ ret
diff --git a/plugins/MirOTR/Libgcrypt/mpi/mpiutil.c b/plugins/MirOTR/Libgcrypt/mpi/mpiutil.c
index 4dc5211360..6bef2a8821 100644
--- a/plugins/MirOTR/Libgcrypt/mpi/mpiutil.c
+++ b/plugins/MirOTR/Libgcrypt/mpi/mpiutil.c
@@ -1,6 +1,7 @@
/* mpiutil.ac - Utility functions for MPI
* Copyright (C) 1998, 2000, 2001, 2002, 2003,
* 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@@ -25,9 +26,12 @@
#include "g10lib.h"
#include "mpi-internal.h"
-#include "memory.h"
#include "mod-source-info.h"
+/* Constants allocated right away at startup. */
+static gcry_mpi_t constants[MPI_NUMBER_OF_CONSTANTS];
+
+
const char *
_gcry_mpi_get_hw_config (void)
@@ -36,6 +40,34 @@ _gcry_mpi_get_hw_config (void)
}
+/* Initialize the MPI subsystem. This is called early and allows to
+ do some initialization without taking care of threading issues. */
+gcry_err_code_t
+_gcry_mpi_init (void)
+{
+ int idx;
+ unsigned long value;
+
+ for (idx=0; idx < MPI_NUMBER_OF_CONSTANTS; idx++)
+ {
+ switch (idx)
+ {
+ case MPI_C_ZERO: value = 0; break;
+ case MPI_C_ONE: value = 1; break;
+ case MPI_C_TWO: value = 2; break;
+ case MPI_C_THREE: value = 3; break;
+ case MPI_C_FOUR: value = 4; break;
+ case MPI_C_EIGHT: value = 8; break;
+ default: log_bug ("invalid mpi_const selector %d\n", idx);
+ }
+ constants[idx] = mpi_alloc_set_ui (value);
+ constants[idx]->flags = (16|32);
+ }
+
+ return 0;
+}
+
+
/****************
* Note: It was a bad idea to use the number of limbs to allocate
* because on a alpha the limbs are large but we normally need
@@ -49,7 +81,7 @@ _gcry_mpi_alloc( unsigned nlimbs )
{
gcry_mpi_t a;
- a = gcry_xmalloc( sizeof *a );
+ a = xmalloc( sizeof *a );
a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
a->alloced = nlimbs;
a->nlimbs = 0;
@@ -70,7 +102,7 @@ _gcry_mpi_alloc_secure( unsigned nlimbs )
{
gcry_mpi_t a;
- a = gcry_xmalloc( sizeof *a );
+ a = xmalloc( sizeof *a );
a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
a->alloced = nlimbs;
a->flags = 1;
@@ -88,7 +120,7 @@ _gcry_mpi_alloc_limb_space( unsigned int nlimbs, int secure )
size_t len;
len = (nlimbs ? nlimbs : 1) * sizeof (mpi_limb_t);
- p = secure ? gcry_xmalloc_secure (len) : gcry_xmalloc (len);
+ p = secure ? xmalloc_secure (len) : xmalloc (len);
if (! nlimbs)
*p = 0;
@@ -101,14 +133,14 @@ _gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs)
if (a)
{
size_t len = nlimbs * sizeof(mpi_limb_t);
-
+
/* If we have information on the number of allocated limbs, we
better wipe that space out. This is a failsafe feature if
secure memory has been disabled or was not properly
implemented in user provided allocation functions. */
if (len)
wipememory (a, len);
- gcry_free(a);
+ xfree(a);
}
}
@@ -138,13 +170,13 @@ _gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
limb space is already of the correct size. */
for (i=a->nlimbs; i < a->alloced; i++)
a->d[i] = 0;
- return;
+ return;
}
/* Actually resize the limb space. */
if (a->d)
{
- a->d = gcry_xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
+ a->d = xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
for (i=a->alloced; i < nlimbs; i++)
a->d[i] = 0;
}
@@ -152,10 +184,10 @@ _gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
{
if (a->flags & 1)
/* Secure memory is wanted. */
- a->d = gcry_xcalloc_secure (nlimbs , sizeof (mpi_limb_t));
+ a->d = xcalloc_secure (nlimbs , sizeof (mpi_limb_t));
else
/* Standard memory. */
- a->d = gcry_xcalloc (nlimbs , sizeof (mpi_limb_t));
+ a->d = xcalloc (nlimbs , sizeof (mpi_limb_t));
}
a->alloced = nlimbs;
}
@@ -163,8 +195,13 @@ _gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
void
_gcry_mpi_clear( gcry_mpi_t a )
{
- a->nlimbs = 0;
- a->flags = 0;
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+ a->nlimbs = 0;
+ a->flags = 0;
}
@@ -173,17 +210,33 @@ _gcry_mpi_free( gcry_mpi_t a )
{
if (!a )
return;
+ if ((a->flags & 32))
+ return; /* Never release a constant. */
if ((a->flags & 4))
- gcry_free( a->d );
+ xfree( a->d );
else
{
_gcry_mpi_free_limb_space(a->d, a->alloced);
}
- if ((a->flags & ~7))
- log_bug("invalid flag value in mpi\n");
- gcry_free(a);
+ /* Check that the flags makes sense. We better allow for bit 1
+ (value 2) for backward ABI compatibility. */
+ if ((a->flags & ~(1|2|4|16
+ |GCRYMPI_FLAG_USER1
+ |GCRYMPI_FLAG_USER2
+ |GCRYMPI_FLAG_USER3
+ |GCRYMPI_FLAG_USER4)))
+ log_bug("invalid flag value in mpi_free\n");
+ xfree (a);
}
+
+void
+_gcry_mpi_immutable_failed (void)
+{
+ log_info ("Warning: trying to change an immutable MPI\n");
+}
+
+
static void
mpi_set_secure( gcry_mpi_t a )
{
@@ -206,27 +259,51 @@ mpi_set_secure( gcry_mpi_t a )
gcry_mpi_t
-gcry_mpi_set_opaque( gcry_mpi_t a, void *p, unsigned int nbits )
+_gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits)
{
- if (!a)
+ if (!a)
a = mpi_alloc(0);
-
+
+ if (mpi_is_immutable (a))
+ {
+ mpi_immutable_failed ();
+ return a;
+ }
+
if( a->flags & 4 )
- gcry_free( a->d );
- else
+ xfree (a->d);
+ else
_gcry_mpi_free_limb_space (a->d, a->alloced);
a->d = p;
a->alloced = 0;
a->nlimbs = 0;
a->sign = nbits;
- a->flags = 4;
+ a->flags = 4 | (a->flags & (GCRYMPI_FLAG_USER1|GCRYMPI_FLAG_USER2
+ |GCRYMPI_FLAG_USER3|GCRYMPI_FLAG_USER4));
+ if (_gcry_is_secure (a->d))
+ a->flags |= 1;
return a;
}
+gcry_mpi_t
+_gcry_mpi_set_opaque_copy (gcry_mpi_t a, const void *p, unsigned int nbits)
+{
+ void *d;
+ unsigned int n;
+
+ n = (nbits+7)/8;
+ d = _gcry_is_secure (p)? xtrymalloc_secure (n) : xtrymalloc (n);
+ if (!d)
+ return NULL;
+ memcpy (d, p, n);
+ return mpi_set_opaque (a, d, nbits);
+}
+
+
void *
-gcry_mpi_get_opaque( gcry_mpi_t a, unsigned int *nbits )
+_gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits)
{
if( !(a->flags & 4) )
log_bug("mpi_get_opaque on normal mpi\n");
@@ -236,21 +313,39 @@ gcry_mpi_get_opaque( gcry_mpi_t a, unsigned int *nbits )
}
+void *
+_gcry_mpi_get_opaque_copy (gcry_mpi_t a, unsigned int *nbits)
+{
+ const void *s;
+ void *d;
+ unsigned int n;
+
+ s = mpi_get_opaque (a, nbits);
+ if (!s && nbits)
+ return NULL;
+ n = (*nbits+7)/8;
+ d = _gcry_is_secure (s)? xtrymalloc_secure (n) : xtrymalloc (n);
+ if (d)
+ memcpy (d, s, n);
+ return d;
+}
+
/****************
* Note: This copy function should not interpret the MPI
* but copy it transparently.
*/
gcry_mpi_t
-gcry_mpi_copy( gcry_mpi_t a )
+_gcry_mpi_copy (gcry_mpi_t a)
{
int i;
gcry_mpi_t b;
if( a && (a->flags & 4) ) {
- void *p = gcry_is_secure(a->d)? gcry_xmalloc_secure( (a->sign+7)/8 )
- : gcry_xmalloc( (a->sign+7)/8 );
+ void *p = _gcry_is_secure(a->d)? xmalloc_secure ((a->sign+7)/8)
+ : xmalloc ((a->sign+7)/8);
memcpy( p, a->d, (a->sign+7)/8 );
- b = gcry_mpi_set_opaque( NULL, p, a->sign );
+ b = mpi_set_opaque( NULL, p, a->sign );
+ b->flags &= ~(16|32); /* Reset the immutable and constant flags. */
}
else if( a ) {
b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
@@ -258,6 +353,7 @@ gcry_mpi_copy( gcry_mpi_t a )
b->nlimbs = a->nlimbs;
b->sign = a->sign;
b->flags = a->flags;
+ b->flags &= ~(16|32); /* Reset the immutable and constant flags. */
for(i=0; i < b->nlimbs; i++ )
b->d[i] = a->d[i];
}
@@ -267,6 +363,47 @@ gcry_mpi_copy( gcry_mpi_t a )
}
+/* Return true if A is negative. */
+int
+_gcry_mpi_is_neg (gcry_mpi_t a)
+{
+ if (a->sign && _gcry_mpi_cmp_ui (a, 0))
+ return 1;
+ else
+ return 0;
+}
+
+
+/* W = - U */
+void
+_gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u)
+{
+ if (w != u)
+ mpi_set (w, u);
+ else if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
+ w->sign = !u->sign;
+}
+
+
+/* W = [W] */
+void
+_gcry_mpi_abs (gcry_mpi_t w)
+{
+ if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+
+ w->sign = 0;
+}
+
+
/****************
* This function allocates an MPI which is optimized to hold
* a value as large as the one given in the argument and allocates it
@@ -279,10 +416,10 @@ _gcry_mpi_alloc_like( gcry_mpi_t a )
if( a && (a->flags & 4) ) {
int n = (a->sign+7)/8;
- void *p = gcry_is_secure(a->d)? gcry_malloc_secure( n )
- : gcry_malloc( n );
+ void *p = _gcry_is_secure(a->d)? xtrymalloc_secure (n)
+ : xtrymalloc (n);
memcpy( p, a->d, n );
- b = gcry_mpi_set_opaque( NULL, p, a->sign );
+ b = mpi_set_opaque( NULL, p, a->sign );
}
else if( a ) {
b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
@@ -297,33 +434,92 @@ _gcry_mpi_alloc_like( gcry_mpi_t a )
}
+/* Set U into W and release U. If W is NULL only U will be released. */
+void
+_gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u)
+{
+ if (w)
+ {
+ if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
+ _gcry_mpi_assign_limb_space (w, u->d, u->alloced);
+ w->nlimbs = u->nlimbs;
+ w->sign = u->sign;
+ w->flags = u->flags;
+ u->alloced = 0;
+ u->nlimbs = 0;
+ u->d = NULL;
+ }
+ _gcry_mpi_free (u);
+}
+
+
gcry_mpi_t
-gcry_mpi_set( gcry_mpi_t w, gcry_mpi_t u)
+_gcry_mpi_set (gcry_mpi_t w, gcry_mpi_t u)
{
mpi_ptr_t wp, up;
mpi_size_t usize = u->nlimbs;
int usign = u->sign;
-
+
if (!w)
w = _gcry_mpi_alloc( mpi_get_nlimbs(u) );
+ if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return w;
+ }
RESIZE_IF_NEEDED(w, usize);
wp = w->d;
up = u->d;
MPN_COPY( wp, up, usize );
w->nlimbs = usize;
w->flags = u->flags;
+ w->flags &= ~(16|32); /* Reset the immutable and constant flags. */
w->sign = usign;
return w;
}
+gcry_mpi_t
+_gcry_mpi_set_cond (gcry_mpi_t w, const gcry_mpi_t u, unsigned long set)
+{
+ mpi_size_t i;
+ mpi_size_t nlimbs = u->alloced;
+ mpi_limb_t mask = ((mpi_limb_t)0) - !!set;
+ mpi_limb_t x;
+
+ if (w->alloced != u->alloced)
+ log_bug ("mpi_set_cond: different sizes\n");
+
+ for (i = 0; i < nlimbs; i++)
+ {
+ x = mask & (w->d[i] ^ u->d[i]);
+ w->d[i] = w->d[i] ^ x;
+ }
+
+ x = mask & (w->nlimbs ^ u->nlimbs);
+ w->nlimbs = w->nlimbs ^ x;
+
+ x = mask & (w->sign ^ u->sign);
+ w->sign = w->sign ^ x;
+ return w;
+}
+
gcry_mpi_t
-gcry_mpi_set_ui( gcry_mpi_t w, unsigned long u)
+_gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u)
{
if (!w)
w = _gcry_mpi_alloc (1);
/* FIXME: If U is 0 we have no need to resize and thus possible
allocating the the limbs. */
+ if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return w;
+ }
RESIZE_IF_NEEDED(w, 1);
w->d[0] = u;
w->nlimbs = u? 1:0;
@@ -347,19 +543,10 @@ _gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u)
if (! err)
*u = x;
-
+
return err;
}
-gcry_error_t
-gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u)
-{
- gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
- err = _gcry_mpi_get_ui (w, u);
-
- return gcry_error (err);
-}
gcry_mpi_t
_gcry_mpi_alloc_set_ui( unsigned long u)
@@ -372,7 +559,7 @@ _gcry_mpi_alloc_set_ui( unsigned long u)
}
void
-gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b)
+_gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b)
{
struct gcry_mpi tmp;
@@ -381,7 +568,7 @@ gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b)
gcry_mpi_t
-gcry_mpi_new( unsigned int nbits )
+_gcry_mpi_new (unsigned int nbits)
{
return _gcry_mpi_alloc ( (nbits+BITS_PER_MPI_LIMB-1)
/ BITS_PER_MPI_LIMB );
@@ -389,58 +576,85 @@ gcry_mpi_new( unsigned int nbits )
gcry_mpi_t
-gcry_mpi_snew( unsigned int nbits )
+_gcry_mpi_snew (unsigned int nbits)
{
return _gcry_mpi_alloc_secure ( (nbits+BITS_PER_MPI_LIMB-1)
/ BITS_PER_MPI_LIMB );
}
void
-gcry_mpi_release( gcry_mpi_t a )
+_gcry_mpi_release( gcry_mpi_t a )
{
_gcry_mpi_free( a );
}
void
-gcry_mpi_randomize( gcry_mpi_t w,
- unsigned int nbits, enum gcry_random_level level )
+_gcry_mpi_randomize (gcry_mpi_t w,
+ unsigned int nbits, enum gcry_random_level level)
{
unsigned char *p;
size_t nbytes = (nbits+7)/8;
-
+
+ if (mpi_is_immutable (w))
+ {
+ mpi_immutable_failed ();
+ return;
+ }
if (level == GCRY_WEAK_RANDOM)
{
- p = mpi_is_secure(w) ? gcry_xmalloc_secure (nbytes)
- : gcry_xmalloc (nbytes);
- gcry_create_nonce (p, nbytes);
+ p = mpi_is_secure(w) ? xmalloc_secure (nbytes)
+ : xmalloc (nbytes);
+ _gcry_create_nonce (p, nbytes);
}
else
{
- p = mpi_is_secure(w) ? gcry_random_bytes_secure (nbytes, level)
- : gcry_random_bytes (nbytes, level);
+ p = mpi_is_secure(w) ? _gcry_random_bytes_secure (nbytes, level)
+ : _gcry_random_bytes (nbytes, level);
}
_gcry_mpi_set_buffer( w, p, nbytes, 0 );
- gcry_free (p);
+ xfree (p);
}
void
-gcry_mpi_set_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
+_gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
{
- switch( flag ) {
- case GCRYMPI_FLAG_SECURE: mpi_set_secure(a); break;
- case GCRYMPI_FLAG_OPAQUE:
- default: log_bug("invalid flag value\n");
+ switch (flag)
+ {
+ case GCRYMPI_FLAG_SECURE: mpi_set_secure(a); break;
+ case GCRYMPI_FLAG_CONST: a->flags |= (16|32); break;
+ case GCRYMPI_FLAG_IMMUTABLE: a->flags |= 16; break;
+
+ case GCRYMPI_FLAG_USER1:
+ case GCRYMPI_FLAG_USER2:
+ case GCRYMPI_FLAG_USER3:
+ case GCRYMPI_FLAG_USER4: a->flags |= flag; break;
+
+ case GCRYMPI_FLAG_OPAQUE:
+ default: log_bug("invalid flag value\n");
}
}
void
-gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
+_gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
{
(void)a; /* Not yet used. */
switch (flag)
{
+ case GCRYMPI_FLAG_IMMUTABLE:
+ if (!(a->flags & 32))
+ a->flags &= ~16;
+ break;
+
+ case GCRYMPI_FLAG_USER1:
+ case GCRYMPI_FLAG_USER2:
+ case GCRYMPI_FLAG_USER3:
+ case GCRYMPI_FLAG_USER4:
+ a->flags &= ~flag;
+ break;
+
+ case GCRYMPI_FLAG_CONST:
case GCRYMPI_FLAG_SECURE:
case GCRYMPI_FLAG_OPAQUE:
default: log_bug("invalid flag value\n");
@@ -448,15 +662,34 @@ gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
}
int
-gcry_mpi_get_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
+_gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
{
switch (flag)
{
- case GCRYMPI_FLAG_SECURE: return (a->flags & 1);
- case GCRYMPI_FLAG_OPAQUE: return (a->flags & 4);
+ case GCRYMPI_FLAG_SECURE: return !!(a->flags & 1);
+ case GCRYMPI_FLAG_OPAQUE: return !!(a->flags & 4);
+ case GCRYMPI_FLAG_IMMUTABLE: return !!(a->flags & 16);
+ case GCRYMPI_FLAG_CONST: return !!(a->flags & 32);
+ case GCRYMPI_FLAG_USER1:
+ case GCRYMPI_FLAG_USER2:
+ case GCRYMPI_FLAG_USER3:
+ case GCRYMPI_FLAG_USER4: return !!(a->flags & flag);
default: log_bug("invalid flag value\n");
}
/*NOTREACHED*/
return 0;
}
+
+/* Return a constant MPI descripbed by NO which is one of the
+ MPI_C_xxx macros. There is no need to copy this returned value; it
+ may be used directly. */
+gcry_mpi_t
+_gcry_mpi_const (enum gcry_mpi_constants no)
+{
+ if ((int)no < 0 || no > MPI_NUMBER_OF_CONSTANTS)
+ log_bug("invalid mpi_const selector %d\n", no);
+ if (!constants[no])
+ log_bug("MPI subsystem not initialized\n");
+ return constants[no];
+}
diff --git a/plugins/MirOTR/Libgcrypt/mpi/sysdep.h b/plugins/MirOTR/Libgcrypt/mpi/sysdep.h
new file mode 100644
index 0000000000..5e6ab4aab8
--- /dev/null
+++ b/plugins/MirOTR/Libgcrypt/mpi/sysdep.h
@@ -0,0 +1,6 @@
+/* created by config.links - do not edit */
+#if __STDC__
+#define C_SYMBOL_NAME(name) _##name
+#else
+#define C_SYMBOL_NAME(name) _/**/name
+#endif