From d2282040361a6e42e283d9ccffd3d60204214e4b Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 26 Jul 2013 15:30:58 +0200 Subject: [PATCH] new upstream version fixing cache side-channel attack on RSA private keys --- .gitignore | 3 + libgcrypt-1.5.0-set-enforced-mode.patch | 127 ------------------------ libgcrypt-1.5.1-use-poll.patch | 82 +++++++++++++++ libgcrypt-1.5.2-aliasing.patch | 30 ++++++ libgcrypt-1.5.2-mpicoder-gccopt.patch | 102 +++++++++++++++++++ libgcrypt.spec | 24 +++-- sources | 2 +- 7 files changed, 233 insertions(+), 137 deletions(-) delete mode 100644 libgcrypt-1.5.0-set-enforced-mode.patch create mode 100644 libgcrypt-1.5.1-use-poll.patch create mode 100644 libgcrypt-1.5.2-aliasing.patch create mode 100644 libgcrypt-1.5.2-mpicoder-gccopt.patch diff --git a/.gitignore b/.gitignore index 2daa2a1..d77b0c1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.4.6-hobbled.tar.bz2 /libgcrypt-1.5.0-hobbled.tar.bz2 +/libgcrypt-1.5.1-hobbled.tar.xz +/libgcrypt-1.5.2-hobbled.tar.xz +/libgcrypt-1.5.3-hobbled.tar.xz diff --git a/libgcrypt-1.5.0-set-enforced-mode.patch b/libgcrypt-1.5.0-set-enforced-mode.patch deleted file mode 100644 index 05ee548..0000000 --- a/libgcrypt-1.5.0-set-enforced-mode.patch +++ /dev/null @@ -1,127 +0,0 @@ -diff -up libgcrypt-1.5.0/doc/gcrypt.texi.enforce libgcrypt-1.5.0/doc/gcrypt.texi ---- libgcrypt-1.5.0/doc/gcrypt.texi.enforce 2011-06-29 10:36:37.000000000 +0200 -+++ libgcrypt-1.5.0/doc/gcrypt.texi 2012-04-04 11:05:41.527430118 +0200 -@@ -577,8 +577,10 @@ initialization (i.e. before @code{gcry_c - - In addition to the standard FIPS mode, Libgcrypt may also be put into - an Enforced FIPS mode by writing a non-zero value into the file --@file{/etc/gcrypt/fips_enabled}. The Enforced FIPS mode helps to --detect applications which don't fulfill all requirements for using -+@file{/etc/gcrypt/fips_enabled} or by using the control command -+@code{GCRYCTL_SET_ENFORCED_FIPS_FLAG} before any other calls to -+libgcrypt. The Enforced FIPS mode helps to detect applications -+which don't fulfill all requirements for using - Libgcrypt in FIPS mode (@pxref{FIPS Mode}). - - Once Libgcrypt has been put into FIPS mode, it is not possible to -@@ -787,20 +789,20 @@ proper random device. - This command dumps information pertaining to the configuration of the - library to the given stream. If NULL is given for @var{stream}, the log - system is used. This command may be used before the intialization has --been finished but not before a gcry_version_check. -+been finished but not before a @code{gcry_check_version}. - - @item GCRYCTL_OPERATIONAL_P; Arguments: none - This command returns true if the library is in an operational state. - This information makes only sense in FIPS mode. In contrast to other - functions, this is a pure test function and won't put the library into - FIPS mode or change the internal state. This command may be used before --the intialization has been finished but not before a gcry_version_check. -+the intialization has been finished but not before a @code{gcry_check_version}. - - @item GCRYCTL_FIPS_MODE_P; Arguments: none - This command returns true if the library is in FIPS mode. Note, that - this is no indication about the current state of the library. This - command may be used before the intialization has been finished but not --before a gcry_version_check. An application may use this command or -+before a @code{gcry_check_version}. An application may use this command or - the convenience macro below to check whether FIPS mode is actually - active. - -@@ -816,10 +818,19 @@ implemented as a macro. - Running this command puts the library into FIPS mode. If the library is - already in FIPS mode, a self-test is triggered and thus the library will - be put into operational state. This command may be used before a call --to gcry_check_version and that is actually the recommended way to let an -+to @code{gcry_check_version} and that is actually the recommended way to let an - application switch the library into FIPS mode. Note that Libgcrypt will - reject an attempt to switch to fips mode during or after the intialization. - -+@item GCRYCTL_SET_ENFORCED_FIPS_FLAG; Arguments: none -+Running this command sets the internal flag that puts the library into -+the enforced FIPS mode during the FIPS mode initialization. This command -+does not affect the library if the library is not put into the FIPS mode and -+it must be used before any other libgcrypt library calls that initialize -+the library such as @code{gcry_check_version}. Note that Libgcrypt will -+reject an attempt to switch to the enforced fips mode during or after -+the intialization. -+ - @item GCRYCTL_SELFTEST; Arguments: none - This may be used at anytime to have the library run all implemented - self-tests. It works in standard and in FIPS mode. Returns 0 on -diff -up libgcrypt-1.5.0/src/fips.c.enforce libgcrypt-1.5.0/src/fips.c ---- libgcrypt-1.5.0/src/fips.c.enforce 2011-07-21 15:41:25.000000000 +0200 -+++ libgcrypt-1.5.0/src/fips.c 2012-04-04 10:26:24.311525789 +0200 -@@ -274,9 +274,17 @@ _gcry_fips_mode (void) - int - _gcry_enforced_fips_mode (void) - { -+ if (!_gcry_fips_mode ()) -+ return 0; - return enforced_fips_mode; - } - -+/* Set a flag telling whether we are in the enforced fips mode. */ -+void -+_gcry_set_enforced_fips_mode (void) -+{ -+ enforced_fips_mode = 1; -+} - - /* If we do not want to enforce the fips mode, we can set a flag so - that the application may check whether it is still in fips mode. -diff -up libgcrypt-1.5.0/src/g10lib.h.enforce libgcrypt-1.5.0/src/g10lib.h ---- libgcrypt-1.5.0/src/g10lib.h.enforce 2011-02-16 18:27:28.000000000 +0100 -+++ libgcrypt-1.5.0/src/g10lib.h 2012-04-04 10:25:03.280777602 +0200 -@@ -326,6 +326,8 @@ int _gcry_fips_mode (void); - - int _gcry_enforced_fips_mode (void); - -+void _gcry_set_enforced_fips_mode (void); -+ - void _gcry_inactivate_fips_mode (const char *text); - int _gcry_is_fips_mode_inactive (void); - -diff -up libgcrypt-1.5.0/src/gcrypt.h.in.enforce libgcrypt-1.5.0/src/gcrypt.h.in ---- libgcrypt-1.5.0/src/gcrypt.h.in.enforce 2011-03-11 09:47:39.000000000 +0100 -+++ libgcrypt-1.5.0/src/gcrypt.h.in 2012-04-04 10:25:53.806867670 +0200 -@@ -415,7 +415,8 @@ enum gcry_ctl_cmds - GCRYCTL_FORCE_FIPS_MODE = 56, - GCRYCTL_SELFTEST = 57, - /* Note: 58 .. 62 are used internally. */ -- GCRYCTL_DISABLE_HWF = 63 -+ GCRYCTL_DISABLE_HWF = 63, -+ GCRYCTL_SET_ENFORCED_FIPS_FLAG = 64 - }; - - /* Perform various operations defined by CMD. */ -diff -up libgcrypt-1.5.0/src/global.c.enforce libgcrypt-1.5.0/src/global.c ---- libgcrypt-1.5.0/src/global.c.enforce 2011-04-01 10:15:40.000000000 +0200 -+++ libgcrypt-1.5.0/src/global.c 2012-04-04 10:24:12.647685222 +0200 -@@ -596,6 +596,16 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, - } - break; - -+ case GCRYCTL_SET_ENFORCED_FIPS_FLAG: -+ if (!any_init_done) -+ { -+ /* Not yet intialized at all. Set the enforced fips mode flag */ -+ _gcry_set_enforced_fips_mode (); -+ } -+ else -+ err = GPG_ERR_GENERAL; -+ break; -+ - default: - /* A call to make sure that the dummy code is linked in. */ - _gcry_compat_identification (); diff --git a/libgcrypt-1.5.1-use-poll.patch b/libgcrypt-1.5.1-use-poll.patch new file mode 100644 index 0000000..f6ed0b7 --- /dev/null +++ b/libgcrypt-1.5.1-use-poll.patch @@ -0,0 +1,82 @@ +diff -up libgcrypt-1.5.1/random/rndlinux.c.use-poll libgcrypt-1.5.1/random/rndlinux.c +--- libgcrypt-1.5.1/random/rndlinux.c.use-poll 2013-03-20 15:33:26.504867356 +0100 ++++ libgcrypt-1.5.1/random/rndlinux.c 2013-03-20 15:37:24.999944048 +0100 +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #include "types.h" + #include "g10lib.h" + #include "rand-internal.h" +@@ -142,49 +143,37 @@ _gcry_rndlinux_gather_random (void (*add + } + + /* Enter the read loop. */ +- delay = 0; /* Start with 0 seconds so that we do no block on the ++ delay = 100; /* Start with 0 seconds so that we do no block on the + first iteration and in turn call the progress function + before blocking. To give the OS a better chance to + return with something we will actually use 100ms. */ + while (length) + { +- fd_set rfds; +- struct timeval tv; + int rc; ++ struct pollfd pfd; + +- /* If the system has no limit on the number of file descriptors +- and we encounter an fd which is larger than the fd_set size, +- we don't use the select at all. The select code is only used +- to emit progress messages. A better solution would be to +- fall back to poll() if available. */ +-#ifdef FD_SETSIZE +- if (fd < FD_SETSIZE) +-#endif ++ pfd.fd = fd; ++ pfd.events = POLLIN; ++ ++ if ( !(rc=poll(&pfd, 1, delay)) ) + { +- FD_ZERO(&rfds); +- FD_SET(fd, &rfds); +- tv.tv_sec = delay; +- tv.tv_usec = delay? 0 : 100000; +- if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) +- { +- if (!any_need_entropy || last_so_far != (want - length) ) +- { +- last_so_far = want - length; +- _gcry_random_progress ("need_entropy", 'X', +- (int)last_so_far, (int)want); +- any_need_entropy = 1; +- } +- delay = 3; /* Use 3 seconds henceforth. */ +- continue; +- } +- else if( rc == -1 ) ++ if (!any_need_entropy || last_so_far != (want - length) ) + { +- log_error ("select() error: %s\n", strerror(errno)); +- if (!delay) +- delay = 1; /* Use 1 second if we encounter an error before ++ last_so_far = want - length; ++ _gcry_random_progress ("need_entropy", 'X', ++ (int)last_so_far, (int)want); ++ any_need_entropy = 1; ++ } ++ delay = 3000; /* Use 3 seconds henceforth. */ ++ continue; ++ } ++ else if( rc == -1 ) ++ { ++ log_error ("poll() error: %s\n", strerror(errno)); ++ if (!delay) ++ delay = 1000; /* Use 1 second if we encounter an error before + we have ever blocked. */ +- continue; +- } ++ continue; + } + + do diff --git a/libgcrypt-1.5.2-aliasing.patch b/libgcrypt-1.5.2-aliasing.patch new file mode 100644 index 0000000..db0e0e0 --- /dev/null +++ b/libgcrypt-1.5.2-aliasing.patch @@ -0,0 +1,30 @@ +diff -up libgcrypt-1.5.2/cipher/Makefile.am.aliasing libgcrypt-1.5.2/cipher/Makefile.am +--- libgcrypt-1.5.2/cipher/Makefile.am.aliasing 2013-04-18 16:49:13.000000000 +0200 ++++ libgcrypt-1.5.2/cipher/Makefile.am 2013-04-25 21:48:57.867465215 +0200 +@@ -81,3 +81,9 @@ tiger.o: $(srcdir)/tiger.c + + tiger.lo: $(srcdir)/tiger.c + `echo $(LTCOMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) ` ++ ++rijndael.o: $(srcdir)/rijndael.c ++ `echo $(COMPILE) -fno-strict-aliasing -c $(srcdir)/rijndael.c ` ++ ++rijndael.lo: $(srcdir)/rijndael.c ++ `echo $(LTCOMPILE) -fno-strict-aliasing -c $(srcdir)/rijndael.c ` +diff -up libgcrypt-1.5.2/cipher/Makefile.in.aliasing libgcrypt-1.5.2/cipher/Makefile.in +--- libgcrypt-1.5.2/cipher/Makefile.in.aliasing 2013-04-18 17:06:03.000000000 +0200 ++++ libgcrypt-1.5.2/cipher/Makefile.in 2013-04-25 21:48:59.164493610 +0200 +@@ -638,6 +638,12 @@ tiger.o: $(srcdir)/tiger.c + tiger.lo: $(srcdir)/tiger.c + `echo $(LTCOMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) ` + ++rijndael.o: $(srcdir)/rijndael.c ++ `echo $(COMPILE) -fno-strict-aliasing -c $(srcdir)/rijndael.c ` ++ ++rijndael.lo: $(srcdir)/rijndael.c ++ `echo $(LTCOMPILE) -fno-strict-aliasing -c $(srcdir)/rijndael.c ` ++ + # Tell versions [3.59,3.63) of GNU make to not export all variables. + # Otherwise a system limit (for SysV at least) may be exceeded. + .NOEXPORT: +diff -up libgcrypt-1.5.2/cipher/rijndael.c.aliasing libgcrypt-1.5.2/cipher/rijndael.c diff --git a/libgcrypt-1.5.2-mpicoder-gccopt.patch b/libgcrypt-1.5.2-mpicoder-gccopt.patch new file mode 100644 index 0000000..c374709 --- /dev/null +++ b/libgcrypt-1.5.2-mpicoder-gccopt.patch @@ -0,0 +1,102 @@ +diff -up libgcrypt-1.5.2/mpi/mpicoder.c.gccopt libgcrypt-1.5.2/mpi/mpicoder.c +--- libgcrypt-1.5.2/mpi/mpicoder.c.gccopt 2013-04-18 16:48:42.000000000 +0200 ++++ libgcrypt-1.5.2/mpi/mpicoder.c 2013-06-20 10:24:57.241510589 +0200 +@@ -555,16 +555,16 @@ gcry_mpi_print (enum gcry_mpi_format for + extra=1; + } + +- if (buffer && n > len) +- { +- /* The provided buffer is too short. */ +- gcry_free (tmp); +- return gcry_error (GPG_ERR_TOO_SHORT); +- } + if (buffer) + { + unsigned char *s = buffer; + ++ if (n > len) ++ { ++ /* The provided buffer is too short. */ ++ gcry_free (tmp); ++ return gcry_error (GPG_ERR_TOO_SHORT); ++ } + if (extra) + *s++ = 0; + memcpy (s, tmp, n-extra); +@@ -580,12 +580,12 @@ gcry_mpi_print (enum gcry_mpi_format for + /* 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); + if (buffer) + { + unsigned char *tmp; + ++ if (n > len) ++ return gcry_error (GPG_ERR_TOO_SHORT); + tmp = _gcry_mpi_get_buffer (a, &n, NULL); + if (!tmp) + return gpg_error_from_syserror (); +@@ -603,14 +603,13 @@ gcry_mpi_print (enum gcry_mpi_format for + if( a->sign ) + return gcry_error (GPG_ERR_INV_ARG); + +- if (buffer && n+2 > len) +- return gcry_error (GPG_ERR_TOO_SHORT); +- + if (buffer) + { + unsigned char *tmp; + unsigned char *s = buffer; + ++ if (n+2 > len) ++ return gcry_error (GPG_ERR_TOO_SHORT); + s[0] = nbits >> 8; + s[1] = nbits; + +@@ -641,16 +640,16 @@ gcry_mpi_print (enum gcry_mpi_format for + extra=1; + } + +- if (buffer && n+4 > len) +- { +- gcry_free(tmp); +- return gcry_error (GPG_ERR_TOO_SHORT); +- } +- + if (buffer) + { + unsigned char *s = buffer; + ++ if (n+4 > len) ++ { ++ gcry_free(tmp); ++ return gcry_error (GPG_ERR_TOO_SHORT); ++ } ++ + *s++ = n >> 24; + *s++ = n >> 16; + *s++ = n >> 8; +@@ -677,15 +676,15 @@ gcry_mpi_print (enum gcry_mpi_format for + if (!n || (*tmp & 0x80)) + extra = 2; + +- if (buffer && 2*n + extra + !!a->sign + 1 > len) +- { +- gcry_free(tmp); +- return gcry_error (GPG_ERR_TOO_SHORT); +- } + if (buffer) + { + unsigned char *s = buffer; + ++ if (2*n + extra + !!a->sign + 1 > len) ++ { ++ gcry_free(tmp); ++ return gcry_error (GPG_ERR_TOO_SHORT); ++ } + if (a->sign) + *s++ = '-'; + if (extra) diff --git a/libgcrypt.spec b/libgcrypt.spec index 3a9ffb9..07bd471 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,8 +1,8 @@ Name: libgcrypt -Version: 1.5.0 -Release: 8%{?dist} +Version: 1.5.3 +Release: 1%{?dist} URL: http://www.gnupg.org/ -Source0: libgcrypt-%{version}-hobbled.tar.bz2 +Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC # cipher support. We have to remove it in the tarball we ship with # the hobble-libgcrypt script. @@ -21,10 +21,14 @@ Patch5: libgcrypt-1.5.0-tests.patch Patch6: libgcrypt-1.5.0-fips-cfgrandom.patch # make the FIPS-186-3 DSA CAVS testable Patch7: libgcrypt-1.5.0-fips-cavs.patch -# add GCRYCTL_SET_ENFORCED_FIPS_FLAG -Patch8: libgcrypt-1.5.0-set-enforced-mode.patch # fix for memory leaks an other errors found by Coverity scan Patch9: libgcrypt-1.5.0-leak.patch +# use poll instead of select when gathering randomness +Patch11: libgcrypt-1.5.1-use-poll.patch +# compile rijndael with -fno-strict-aliasing +Patch12: libgcrypt-1.5.2-aliasing.patch +# slight optimalization of mpicoder.c to silence Valgrind (#968288) +Patch13: libgcrypt-1.5.2-mpicoder-gccopt.patch # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. # Documentation and some utilities are GPLv2+ licensed. These files @@ -64,11 +68,10 @@ applications using libgcrypt. %patch5 -p1 -b .tests %patch6 -p1 -b .cfgrandom %patch7 -p1 -b .cavs -%patch8 -p1 -b .enforce %patch9 -p1 -b .leak - -mv AUTHORS AUTHORS.iso88591 -iconv -f ISO-8859-1 -t UTF-8 AUTHORS.iso88591 >AUTHORS +%patch11 -p1 -b .use-poll +%patch12 -p1 -b .aliasing +%patch13 -p1 -b .gccopt %build %configure --disable-static \ @@ -179,6 +182,9 @@ exit 0 %doc COPYING %changelog +* Fri Jul 26 2013 Tomáš Mráz 1.5.3-1 +- new upstream version fixing cache side-channel attack on RSA private keys + * Mon Dec 3 2012 Tomas Mraz 1.5.0-8 - fix multilib conflict in libgcrypt-config - fix minor memory leaks and other bugs found by Coverity scan diff --git a/sources b/sources index 28984ca..4838fbc 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -35a73c1f2616ad904108ed8645c82f4c libgcrypt-1.5.0-hobbled.tar.bz2 +99e0f2dc94dac6eceab709d03d613328 libgcrypt-1.5.3-hobbled.tar.xz