diff options
Diffstat (limited to 'plugins/MirOTR/Libgcrypt/mpi')
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 |