From gniibe at fsij.org Wed Feb 11 13:47:55 2015 From: gniibe at fsij.org (NIIBE Yutaka) Date: Wed, 11 Feb 2015 21:47:55 +0900 Subject: [PATCH] Add mpi_set_cond. Message-ID: <54DB4F7B.5030004@fsij.org> Hello, For Curve25519, I added the internal function mpi_swap_cond last year. I think that we should also have mpi_set_cond. Adding mpi_set_cond, I revised the implementation of _gcry_mpi_swap_cond. OK to commit? I think that it's worth to have those functions in 1.6. mpi: Add mpi_set_cond. * mpi/mpiutil.c (_gcry_mpi_set_cond): New. (_gcry_mpi_swap_cond): Fix types. * src/mpi.h (mpi_set_cond): New. diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c index f74dd91..e2e4db9 100644 --- a/mpi/mpiutil.c +++ b/mpi/mpiutil.c @@ -482,6 +482,31 @@ _gcry_mpi_set (gcry_mpi_t w, gcry_mpi_t u) 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 = 0UL - !!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) @@ -545,10 +570,10 @@ _gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b) void _gcry_mpi_swap_cond (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap) { - size_t i; - size_t nlimbs = a->alloced; - unsigned long mask = 0UL - !!swap; - unsigned long x; + mpi_size_t i; + mpi_size_t nlimbs = a->alloced; + mpi_limb_t mask = 0UL - !!swap; + mpi_limb_t x; if (a->alloced != b->alloced) log_bug ("mpi_swap_cond: different sizes\n"); diff --git a/src/mpi.h b/src/mpi.h index 13b5117..0d19f46 100644 --- a/src/mpi.h +++ b/src/mpi.h @@ -120,8 +120,11 @@ void _gcry_mpi_immutable_failed (void); #define mpi_m_check(a) _gcry_mpi_m_check ((a)) #define mpi_const(n) _gcry_mpi_const ((n)) #define mpi_swap_cond(a,b,sw) _gcry_mpi_swap_cond ((a),(b),(sw)) +#define mpi_set_cond(w,u,set) _gcry_mpi_set_cond ((w),(u),(set)) void _gcry_mpi_clear( gcry_mpi_t a ); +gcry_mpi_t _gcry_mpi_set_cond (gcry_mpi_t w, const gcry_mpi_t u, + unsigned long swap); gcry_mpi_t _gcry_mpi_alloc_like( gcry_mpi_t a ); gcry_mpi_t _gcry_mpi_alloc_set_ui( unsigned long u); void _gcry_mpi_m_check( gcry_mpi_t a ); -- From wk at gnupg.org Wed Feb 11 17:28:38 2015 From: wk at gnupg.org (Werner Koch) Date: Wed, 11 Feb 2015 17:28:38 +0100 Subject: [PATCH] Add mpi_set_cond. In-Reply-To: <54DB4F7B.5030004@fsij.org> (NIIBE Yutaka's message of "Wed, 11 Feb 2015 21:47:55 +0900") References: <54DB4F7B.5030004@fsij.org> Message-ID: <87twys2z0p.fsf@vigenere.g10code.de> On Wed, 11 Feb 2015 13:47, gniibe at fsij.org said: > OK to commit? I think that it's worth to have those functions in 1.6. No concerns from my site. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From cvs at cvs.gnupg.org Thu Feb 12 11:57:25 2015 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Thu, 12 Feb 2015 11:57:25 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-167-g653a9fa Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 653a9fa1a3a4c35a4dc1841cb57d7e2a318f3288 (commit) from 40a7bdf50e19faaf106470897fed72af623adc50 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 653a9fa1a3a4c35a4dc1841cb57d7e2a318f3288 Author: NIIBE Yutaka Date: Wed Feb 11 21:42:22 2015 +0900 mpi: Add mpi_set_cond. * mpi/mpiutil.c (_gcry_mpi_set_cond): New. (_gcry_mpi_swap_cond): Fix types. * src/mpi.h (mpi_set_cond): New. diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c index f74dd91..fbbd3b4 100644 --- a/mpi/mpiutil.c +++ b/mpi/mpiutil.c @@ -482,6 +482,31 @@ _gcry_mpi_set (gcry_mpi_t w, gcry_mpi_t u) 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) @@ -545,10 +570,10 @@ _gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b) void _gcry_mpi_swap_cond (gcry_mpi_t a, gcry_mpi_t b, unsigned long swap) { - size_t i; - size_t nlimbs = a->alloced; - unsigned long mask = 0UL - !!swap; - unsigned long x; + mpi_size_t i; + mpi_size_t nlimbs = a->alloced; + mpi_limb_t mask = ((mpi_limb_t)0) - !!swap; + mpi_limb_t x; if (a->alloced != b->alloced) log_bug ("mpi_swap_cond: different sizes\n"); diff --git a/src/mpi.h b/src/mpi.h index 13b5117..0d19f46 100644 --- a/src/mpi.h +++ b/src/mpi.h @@ -120,8 +120,11 @@ void _gcry_mpi_immutable_failed (void); #define mpi_m_check(a) _gcry_mpi_m_check ((a)) #define mpi_const(n) _gcry_mpi_const ((n)) #define mpi_swap_cond(a,b,sw) _gcry_mpi_swap_cond ((a),(b),(sw)) +#define mpi_set_cond(w,u,set) _gcry_mpi_set_cond ((w),(u),(set)) void _gcry_mpi_clear( gcry_mpi_t a ); +gcry_mpi_t _gcry_mpi_set_cond (gcry_mpi_t w, const gcry_mpi_t u, + unsigned long swap); gcry_mpi_t _gcry_mpi_alloc_like( gcry_mpi_t a ); gcry_mpi_t _gcry_mpi_alloc_set_ui( unsigned long u); void _gcry_mpi_m_check( gcry_mpi_t a ); ----------------------------------------------------------------------- Summary of changes: mpi/mpiutil.c | 33 +++++++++++++++++++++++++++++---- src/mpi.h | 3 +++ 2 files changed, 32 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From gniibe at fsij.org Thu Feb 12 12:02:28 2015 From: gniibe at fsij.org (NIIBE Yutaka) Date: Thu, 12 Feb 2015 20:02:28 +0900 Subject: [PATCH] Add mpi_set_cond. In-Reply-To: <87twys2z0p.fsf@vigenere.g10code.de> References: <54DB4F7B.5030004@fsij.org> <87twys2z0p.fsf@vigenere.g10code.de> Message-ID: <54DC8844.30405@fsij.org> On 02/12/2015 01:28 AM, Werner Koch wrote: > On Wed, 11 Feb 2015 13:47, gniibe at fsij.org said: > >> OK to commit? I think that it's worth to have those functions in 1.6. > > No concerns from my site. Thanks. Reviewing by myself, I found a possible error. '0UL' will be problem for LLP64 machine if mpi_limb_t is long long. I think that it should be like: mpi_limb_t mask = ((mpi_limb_t)0) - !!swap; Fixing these, I committed the patch. -- From cvs at cvs.gnupg.org Mon Feb 23 11:42:07 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 23 Feb 2015 11:42:07 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-168-g410d70b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 410d70bad9a650e3837055e36f157894ae49a57d (commit) from 653a9fa1a3a4c35a4dc1841cb57d7e2a318f3288 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 410d70bad9a650e3837055e36f157894ae49a57d Author: Werner Koch Date: Mon Feb 23 11:39:58 2015 +0100 cipher: Use ciphertext blinding for Elgamal decryption. * cipher/elgamal.c (USE_BLINDING): New. (decrypt): Rewrite to use ciphertext blinding. -- CVE-id: CVE-2014-3591 As a countermeasure to a new side-channel attacks on sliding windows exponentiation we blind the ciphertext for Elgamal decryption. This is similar to what we are doing with RSA. This patch is a backport of the GnuPG 1.4 commit ff53cf06e966dce0daba5f2c84e03ab9db2c3c8b. Unfortunately, the performance impact of Elgamal blinding is quite noticeable (i5-2410M CPU @ 2.30GHz TP 220): Algorithm generate 100*priv 100*public ------------------------------------------------ ELG 1024 bit - 100ms 90ms ELG 2048 bit - 330ms 350ms ELG 3072 bit - 660ms 790ms Algorithm generate 100*priv 100*public ------------------------------------------------ ELG 1024 bit - 150ms 90ms ELG 2048 bit - 520ms 360ms ELG 3072 bit - 1100ms 800ms Signed-off-by: Werner Koch diff --git a/cipher/elgamal.c b/cipher/elgamal.c index cb3ca43..4eb52d6 100644 --- a/cipher/elgamal.c +++ b/cipher/elgamal.c @@ -33,6 +33,12 @@ #include "pubkey-internal.h" +/* Blinding is used to mitigate side-channel attacks. You may undef + this to speed up the operation in case the system is secured + against physical and network mounted side-channel attacks. */ +#define USE_BLINDING 1 + + typedef struct { gcry_mpi_t p; /* prime */ @@ -516,15 +522,45 @@ do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey ) static void decrypt (gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, ELG_secret_key *skey ) { - gcry_mpi_t t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) ); + gcry_mpi_t t1, t2, r; + unsigned int nbits = mpi_get_nbits (skey->p); mpi_normalize (a); mpi_normalize (b); + t1 = mpi_snew (nbits); + +#ifdef USE_BLINDING + + t2 = mpi_snew (nbits); + r = mpi_new (nbits); + + /* We need a random number of about the prime size. The random + number merely needs to be unpredictable; thus we use level 0. */ + _gcry_mpi_randomize (r, nbits, GCRY_WEAK_RANDOM); + + /* t1 = r^x mod p */ + mpi_powm (t1, r, skey->x, skey->p); + /* t2 = (a * r)^-x mod p */ + mpi_mulm (t2, a, r, skey->p); + mpi_powm (t2, t2, skey->x, skey->p); + mpi_invm (t2, t2, skey->p); + /* t1 = (t1 * t2) mod p*/ + mpi_mulm (t1, t1, t2, skey->p); + + mpi_free (r); + mpi_free (t2); + +#else /*!USE_BLINDING*/ + /* output = b/(a^x) mod p */ - mpi_powm( t1, a, skey->x, skey->p ); - mpi_invm( t1, t1, skey->p ); - mpi_mulm( output, b, t1, skey->p ); + mpi_powm (t1, a, skey->x, skey->p); + mpi_invm (t1, t1, skey->p); + +#endif /*!USE_BLINDING*/ + + mpi_mulm (output, b, t1, skey->p); + #if 0 if( DBG_CIPHER ) { @@ -535,7 +571,7 @@ decrypt (gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, ELG_secret_key *skey ) log_mpidump ("elg decrypted M", output); } #endif - mpi_free(t1); + mpi_free (t1); } ----------------------------------------------------------------------- Summary of changes: cipher/elgamal.c | 46 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From jussi.kivilinna at iki.fi Mon Feb 23 20:21:33 2015 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Mon, 23 Feb 2015 21:21:33 +0200 Subject: [PATCH] Fix in-place encryption for OCB mode Message-ID: <20150223192133.27999.39883.stgit@localhost6.localdomain6> * cipher/cipher-ocb.c (ocb_checksum): New. (ocb_crypt): Move checksum calculation outside main crypt loop, do checksum calculation for encryption before inbuf is overwritten. * tests/basic.c (check_ocb_cipher): Rename to ... (do_check_ocb_cipher): ... to this and add argument for testing in-place encryption/decryption. (check_ocb_cipher): New. -- Signed-off-by: Jussi Kivilinna --- cipher/cipher-ocb.c | 31 ++++++++++++++++++++++++++++--- tests/basic.c | 41 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/cipher/cipher-ocb.c b/cipher/cipher-ocb.c index 25466f0..652683c 100644 --- a/cipher/cipher-ocb.c +++ b/cipher/cipher-ocb.c @@ -299,6 +299,21 @@ _gcry_cipher_ocb_authenticate (gcry_cipher_hd_t c, const unsigned char *abuf, } +/* Checksumming for encrypt and decrypt. */ +static void ocb_checksum(unsigned char *chksum, const unsigned char *plainbuf, + size_t nblks) +{ + while (nblks > 0) + { + /* Checksum_i = Checksum_{i-1} xor P_i */ + buf_xor_1(chksum, plainbuf, OCB_BLOCK_LEN); + + plainbuf += OCB_BLOCK_LEN; + nblks--; + } +} + + /* Common code for encrypt and decrypt. */ static gcry_err_code_t ocb_crypt (gcry_cipher_hd_t c, int encrypt, @@ -308,6 +323,7 @@ ocb_crypt (gcry_cipher_hd_t c, int encrypt, unsigned char l_tmp[OCB_BLOCK_LEN]; unsigned int burn = 0; unsigned int nburn; + size_t nblks = inbuflen / OCB_BLOCK_LEN; /* Check that a nonce and thus a key has been set and that we are not yet in end of data state. */ @@ -324,6 +340,12 @@ ocb_crypt (gcry_cipher_hd_t c, int encrypt, else if ((inbuflen % OCB_BLOCK_LEN)) return GPG_ERR_INV_LENGTH; /* We support only full blocks for now. */ + if (encrypt) + { + /* Checksum_i = Checksum_{i-1} xor P_i */ + ocb_checksum (c->u_ctr.ctr, inbuf, nblks); + } + /* Encrypt all full blocks. */ while (inbuflen >= OCB_BLOCK_LEN) { @@ -341,15 +363,18 @@ ocb_crypt (gcry_cipher_hd_t c, int encrypt, burn = nburn > burn ? nburn : burn; buf_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN); - /* Checksum_i = Checksum_{i-1} xor P_i */ - buf_xor_1 (c->u_ctr.ctr, encrypt? inbuf : outbuf, OCB_BLOCK_LEN); - inbuf += OCB_BLOCK_LEN; inbuflen -= OCB_BLOCK_LEN; outbuf += OCB_BLOCK_LEN; outbuflen =- OCB_BLOCK_LEN; } + if (!encrypt) + { + /* Checksum_i = Checksum_{i-1} xor P_i */ + ocb_checksum (c->u_ctr.ctr, outbuf - nblks * OCB_BLOCK_LEN, nblks); + } + /* Encrypt final partial block. Note that we expect INBUFLEN to be shorter than OCB_BLOCK_LEN (see above). */ if (inbuflen) diff --git a/tests/basic.c b/tests/basic.c index 869b381..6ebc056 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -2781,7 +2781,7 @@ check_ccm_cipher (void) static void -check_ocb_cipher (void) +do_check_ocb_cipher (int inplace) { /* Note that we use hex strings and not binary strings in TV. That makes it easier to maintain the test vectors. */ @@ -3028,7 +3028,18 @@ check_ocb_cipher (void) err = gcry_cipher_final (hde); if (!err) - err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, plain, plainlen); + { + if (inplace) + { + memcpy(out, plain, plainlen); + err = gcry_cipher_encrypt (hde, out, plainlen, NULL, 0); + } + else + { + err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, + plain, plainlen); + } + } if (err) { fail ("cipher-ocb, gcry_cipher_encrypt failed (tv %d): %s\n", @@ -3075,7 +3086,19 @@ check_ocb_cipher (void) /* Now for the decryption. */ err = gcry_cipher_final (hdd); if (!err) - err = gcry_cipher_decrypt (hdd, out, plainlen, NULL, 0); + { + if (inplace) + { + err = gcry_cipher_decrypt (hdd, out, plainlen, NULL, 0); + } + else + { + unsigned char tmp[MAX_DATA_LEN]; + + memcpy(tmp, out, plainlen); + err = gcry_cipher_decrypt (hdd, out, plainlen, tmp, plainlen); + } + } if (err) { fail ("cipher-ocb, gcry_cipher_decrypt (tv %d) failed: %s\n", @@ -3130,6 +3153,18 @@ check_ocb_cipher (void) static void +check_ocb_cipher (void) +{ + /* Check OCB cipher with separate destination and source buffers for + * encryption/decryption. */ + do_check_ocb_cipher(0); + + /* Check OCB cipher with inplace encrypt/decrypt. */ + do_check_ocb_cipher(1); +} + + +static void check_stream_cipher (void) { static const struct tv From cvs at cvs.gnupg.org Fri Feb 27 06:18:03 2015 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 27 Feb 2015 06:18:03 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-170-g6636c4f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 6636c4fd0c6ceab9f79827bf96967d1e112c0b82 (commit) via 1fa8cdb933505960d4e4b4842b122d4e06953e88 (commit) from 410d70bad9a650e3837055e36f157894ae49a57d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6636c4fd0c6ceab9f79827bf96967d1e112c0b82 Author: NIIBE Yutaka Date: Thu Feb 26 21:07:01 2015 +0900 mpi: Avoid data-dependent timing variations in mpi_powm. * mpi/mpi-pow.c (mpi_powm): Access all data in the table by mpi_set_cond. -- Access to the precomputed table was indexed by a portion of EXPO, which could be mounted by a side channel attack. This change fixes this particular data-dependent access pattern. Cherry-picked from commit 5e72b6c76ebee720f69b8a5c212f52d38eb50287 in LIBGCRYPT-1-6-BRANCH. diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c index 930d344..70bf9e8 100644 --- a/mpi/mpi-pow.c +++ b/mpi/mpi-pow.c @@ -422,6 +422,7 @@ _gcry_mpi_powm (gcry_mpi_t res, 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; @@ -540,7 +541,7 @@ _gcry_mpi_powm (gcry_mpi_t res, /* Main processing. */ { - mpi_size_t i, j; + mpi_size_t i, j, k; mpi_ptr_t xp; mpi_size_t xsize; int c; @@ -559,7 +560,7 @@ _gcry_mpi_powm (gcry_mpi_t res, 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 = precomp_size[0] = bsize; + 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) */ @@ -571,9 +572,14 @@ _gcry_mpi_powm (gcry_mpi_t res, 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. @@ -659,8 +665,24 @@ _gcry_mpi_powm (gcry_mpi_t res, rsize = xsize; } - base_u = precomp[e0]; - base_u_size = precomp_size[e0]; + /* + * 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); @@ -687,8 +709,24 @@ _gcry_mpi_powm (gcry_mpi_t res, if (e != 0) { - base_u = precomp[(e>>1)]; - base_u_size = precomp_size[(e>>1)]; + /* + * 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); @@ -739,6 +777,7 @@ _gcry_mpi_powm (gcry_mpi_t res, _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. */ commit 1fa8cdb933505960d4e4b4842b122d4e06953e88 Author: NIIBE Yutaka Date: Wed Feb 11 22:30:02 2015 +0900 mpi: Revise mpi_powm. * mpi/mpi-pow.c (_gcry_mpi_powm): Rename the table to PRECOMP. -- The name of precomputed table was b_2i3 which stands for BASE^(2*I+3). But it's too cryptic, so, it's renamed. Besides, we needed to distinguish the case of I==0, that was not good. Since it's OK to increase the size of table by one, it's BASE^(2*I+1), now. diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c index 0f0947f..930d344 100644 --- a/mpi/mpi-pow.c +++ b/mpi/mpi-pow.c @@ -381,7 +381,7 @@ mul_mod (mpi_ptr_t xp, mpi_size_t *xsize_p, *xsize_p = rsize + ssize; } -#define SIZE_B_2I3 ((1 << (5 - 1)) - 1) +#define SIZE_PRECOMP ((1 << (5 - 1))) /**************** * RES = BASE ^ EXPO mod MOD @@ -417,8 +417,8 @@ _gcry_mpi_powm (gcry_mpi_t res, unsigned int bp_nlimbs = 0; unsigned int ep_nlimbs = 0; unsigned int xp_nlimbs = 0; - mpi_ptr_t b_2i3[SIZE_B_2I3]; /* Pre-computed array: BASE^3, ^5, ^7, ... */ - mpi_size_t b_2i3size[SIZE_B_2I3]; + 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; @@ -555,31 +555,23 @@ _gcry_mpi_powm (gcry_mpi_t res, memset( &karactx, 0, sizeof karactx ); negative_result = (ep[0] & 1) && bsign; - /* Precompute B_2I3[], BASE^(2 * i + 3), BASE^3, ^5, ^7, ... */ + /* 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); - for (i = 0; i < (1 << (W - 1)) - 1; i++) - { /* B_2I3[i] = BASE^(2 * i + 3) */ - if (i == 0) - { - base_u = bp; - base_u_size = bsize; - } - else - { - base_u = b_2i3[i-1]; - base_u_size = b_2i3size[i-1]; - } - + base_u = precomp[0] = mpi_alloc_limb_space (bsize, esec); + base_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); - b_2i3[i] = mpi_alloc_limb_space (rsize, esec); - b_2i3size[i] = rsize; - MPN_COPY (b_2i3[i], rp, rsize); + base_u = precomp[i] = mpi_alloc_limb_space (rsize, esec); + base_u_size = precomp_size[i] = rsize; + MPN_COPY (precomp[i], rp, rsize); } i = esize - 1; @@ -667,16 +659,8 @@ _gcry_mpi_powm (gcry_mpi_t res, rsize = xsize; } - if (e0 == 0) - { - base_u = bp; - base_u_size = bsize; - } - else - { - base_u = b_2i3[e0 - 1]; - base_u_size = b_2i3size[e0 -1]; - } + base_u = precomp[e0]; + base_u_size = precomp_size[e0]; mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size, mp, msize, &karactx); @@ -703,16 +687,8 @@ _gcry_mpi_powm (gcry_mpi_t res, if (e != 0) { - if ((e>>1) == 0) - { - base_u = bp; - base_u_size = bsize; - } - else - { - base_u = b_2i3[(e>>1) - 1]; - base_u_size = b_2i3size[(e>>1) -1]; - } + base_u = precomp[(e>>1)]; + base_u_size = precomp_size[(e>>1)]; mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size, mp, msize, &karactx); @@ -761,8 +737,8 @@ _gcry_mpi_powm (gcry_mpi_t res, MPN_NORMALIZE (rp, rsize); _gcry_mpih_release_karatsuba_ctx (&karactx ); - for (i = 0; i < (1 << (W - 1)) - 1; i++) - _gcry_mpi_free_limb_space( b_2i3[i], esec ? b_2i3size[i] : 0 ); + for (i = 0; i < (1 << (W - 1)); i++) + _gcry_mpi_free_limb_space( precomp[i], esec ? precomp_size[i] : 0 ); } /* Fixup for negative results. */ ----------------------------------------------------------------------- Summary of changes: mpi/mpi-pow.c | 93 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 39 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From cvs at cvs.gnupg.org Fri Feb 27 09:26:13 2015 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 27 Feb 2015 09:26:13 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-171-g505decf Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 505decf5369970219ddc9e78a20f97c623957b78 (commit) from 6636c4fd0c6ceab9f79827bf96967d1e112c0b82 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 505decf5369970219ddc9e78a20f97c623957b78 Author: NIIBE Yutaka Date: Fri Feb 27 17:24:49 2015 +0900 tests: fix t-sexp.c. * tests/t-sexp.c (bug_1594): Free N and PUBKEY. diff --git a/tests/t-sexp.c b/tests/t-sexp.c index 1051723..4785b17 100644 --- a/tests/t-sexp.c +++ b/tests/t-sexp.c @@ -1045,6 +1045,8 @@ static char thing[] = if (gcry_sexp_nth (n_val, 1)) fail ("extracting 1-th of car of 'n' list did not fail"); gcry_sexp_release (n_val); + gcry_sexp_release (n); + gcry_sexp_release (pubkey); } ----------------------------------------------------------------------- Summary of changes: tests/t-sexp.c | 2 ++ 1 file changed, 2 insertions(+) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From gniibe at fsij.org Fri Feb 27 09:29:49 2015 From: gniibe at fsij.org (NIIBE Yutaka) Date: Fri, 27 Feb 2015 17:29:49 +0900 Subject: mpi_powm changes and t-sexp.c change of mine Message-ID: <54F02AFD.8000703@fsij.org> Hello, I pushed three changes to master. Two are forward port from 1.6 branch, and the last one is the one I found by running test program with valgrind. commit 505decf5369970219ddc9e78a20f97c623957b78 Author: NIIBE Yutaka Date: Fri Feb 27 17:24:49 2015 +0900 tests: fix t-sexp.c. * tests/t-sexp.c (bug_1594): Free N and PUBKEY. commit 6636c4fd0c6ceab9f79827bf96967d1e112c0b82 Author: NIIBE Yutaka Date: Thu Feb 26 21:07:01 2015 +0900 mpi: Avoid data-dependent timing variations in mpi_powm. * mpi/mpi-pow.c (mpi_powm): Access all data in the table by mpi_set_cond. -- Access to the precomputed table was indexed by a portion of EXPO, which could be mounted by a side channel attack. This change fixes this particular data-dependent access pattern. Cherry-picked from commit 5e72b6c76ebee720f69b8a5c212f52d38eb50287 in LIBGCRYPT-1-6-BRANCH. commit 1fa8cdb933505960d4e4b4842b122d4e06953e88 Author: NIIBE Yutaka Date: Wed Feb 11 22:30:02 2015 +0900 mpi: Revise mpi_powm. * mpi/mpi-pow.c (_gcry_mpi_powm): Rename the table to PRECOMP. -- The name of precomputed table was b_2i3 which stands for BASE^(2*I+3). But it's too cryptic, so, it's renamed. Besides, we needed to distinguish the case of I==0, that was not good. Since it's OK to increase the size of table by one, it's BASE^(2*I+1), now. -- From wk at gnupg.org Fri Feb 27 21:39:05 2015 From: wk at gnupg.org (Werner Koch) Date: Fri, 27 Feb 2015 21:39:05 +0100 Subject: Libgcrypt 1.6.3 released (with SCA fix) Message-ID: <874mq7m6mu.fsf@vigenere.g10code.de> Hello! The GNU project is pleased to announce the availability of Libgcrypt version 1.6.3. This is a security fix release to mitigate two new side channel attacks. Libgcrypt is a general purpose library of cryptographic building blocks. It does not provide any implementation of OpenPGP or other protocols. Thorough understanding of applied cryptography is required for proper use Libgcrypt. Noteworthy changes in version 1.6.3 =================================== * Use ciphertext blinding for Elgamal decryption [CVE-2014-3591]. See http://www.cs.tau.ac.il/~tromer/radioexp/ for details. * Fixed data-dependent timing variations in modular exponentiation [related to CVE-2015-0837, Last-Level Cache Side-Channel Attacks are Practical]. * Improved asm support for older toolchains. Download ======== Source code is hosted at the GnuPG FTP server and its mirrors as listed at http://www.gnupg.org/download/mirrors.html . On the primary server the source tarball and its digital signature are: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.3.tar.bz2 (2436k) ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.3.tar.bz2.sig That file is bzip2 compressed. A gzip compressed version is here: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.3.tar.gz (2893k) ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.3.tar.gz.sig In order to check that the version of Libgcrypt you are going to build is an original and unmodified one, you can do it in one of the following ways: * Check the supplied OpenPGP signature. For example to check the signature of the file libgcrypt-1.6.3.tar.bz2 you would use this command: gpg --verify libgcrypt-1.6.3.tar.bz2.sig libgcrypt-1.6.3.tar.bz2 This checks whether the signature file matches the source file. You should see a message indicating that the signature is good and made by one of the release signing keys. See https://gnupg.org/signature_key.html . * If you are not able to use GnuPG, you have to verify the SHA-1 checksum: sha1sum libgcrypt-1.6.3.tar.bz2 and check that the output matches the first line from the following list: 9456e7b64db9df8360a1407a38c8c958da80bbf1 libgcrypt-1.6.3.tar.bz2 4d56b5d754d39acae239f876537672e1dc8298e3 libgcrypt-1.6.3.tar.gz Copying ======= Libgcrypt is distributed under the terms of the GNU Lesser General Public License (LGPLv2.1+). The helper programs as well as the documentation are distributed under the terms of the GNU General Public License (GPLv2+). The file LICENSES has notices about contributions that require these additional notices are distributed. Support ======= For help on developing with Libgcrypt you should read the included manual and optional ask on the gcrypt-devel mailing list [1]. A listing with commercial support offers for Libgcrypt and related software is available at the GnuPG web site [2]. If you are a developer and you may need a certain feature for your project, please do not hesitate to bring it to the gcrypt-devel mailing list for discussion. Thanks ====== We have to thank all the people who helped with this release, be it testing, coding, translating, suggesting, auditing, administering the servers, spreading the word, and answering questions on the mailing lists. Niibe Yutaka did most of the work on fixing the side channel attacks. Special thanks to a) Daniel Genkin and his team for working with us on the fix for the "radioexp" attack, b) Yuval Yarum and its team for advance information on their new cache attack and sample code on how to fix it. Since the start of the GnuPG funding campaign in December several thousand people have been kind enough to donate a total of 250000 Euro to support this project. In addition the Linux Foundation gave a grant of $ 60000 for 2015, Stripe.com and Facebook.com each pledged $ 50000 per year. I am amazed by this superb and unexpected support for the GnuPG project. This will not only allow us to continue the project and hire a second full time developer but gives us also the resources to improve things which have been delayed for too long. *Thank you all !* Happy hacking, Werner [1] http://lists.gnupg.org/mailman/listinfo/gcrypt-devel [2] https://www.gnupg.org/service.html p.s. This is a announcement only mailing list. Please send replies only to the gcrypt-devel at gnupg.org mailing lists. -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 180 bytes Desc: not available URL: From cvs at cvs.gnupg.org Sat Feb 28 18:25:58 2015 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Sat, 28 Feb 2015 18:25:58 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-172-g5e66a4f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 5e66a4f8d5a63f58caeee367433dd8dd32346083 (commit) from 505decf5369970219ddc9e78a20f97c623957b78 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5e66a4f8d5a63f58caeee367433dd8dd32346083 Author: Jussi Kivilinna Date: Sat Feb 28 18:04:34 2015 +0200 Fix in-place encryption for OCB mode * cipher/cipher-ocb.c (ocb_checksum): New. (ocb_crypt): Move checksum calculation outside main crypt loop, do checksum calculation for encryption before inbuf is overwritten. * tests/basic.c (check_ocb_cipher): Rename to ... (do_check_ocb_cipher): ... to this and add argument for testing in-place encryption/decryption. (check_ocb_cipher): New. -- Signed-off-by: Jussi Kivilinna diff --git a/cipher/cipher-ocb.c b/cipher/cipher-ocb.c index 25466f0..652683c 100644 --- a/cipher/cipher-ocb.c +++ b/cipher/cipher-ocb.c @@ -299,6 +299,21 @@ _gcry_cipher_ocb_authenticate (gcry_cipher_hd_t c, const unsigned char *abuf, } +/* Checksumming for encrypt and decrypt. */ +static void ocb_checksum(unsigned char *chksum, const unsigned char *plainbuf, + size_t nblks) +{ + while (nblks > 0) + { + /* Checksum_i = Checksum_{i-1} xor P_i */ + buf_xor_1(chksum, plainbuf, OCB_BLOCK_LEN); + + plainbuf += OCB_BLOCK_LEN; + nblks--; + } +} + + /* Common code for encrypt and decrypt. */ static gcry_err_code_t ocb_crypt (gcry_cipher_hd_t c, int encrypt, @@ -308,6 +323,7 @@ ocb_crypt (gcry_cipher_hd_t c, int encrypt, unsigned char l_tmp[OCB_BLOCK_LEN]; unsigned int burn = 0; unsigned int nburn; + size_t nblks = inbuflen / OCB_BLOCK_LEN; /* Check that a nonce and thus a key has been set and that we are not yet in end of data state. */ @@ -324,6 +340,12 @@ ocb_crypt (gcry_cipher_hd_t c, int encrypt, else if ((inbuflen % OCB_BLOCK_LEN)) return GPG_ERR_INV_LENGTH; /* We support only full blocks for now. */ + if (encrypt) + { + /* Checksum_i = Checksum_{i-1} xor P_i */ + ocb_checksum (c->u_ctr.ctr, inbuf, nblks); + } + /* Encrypt all full blocks. */ while (inbuflen >= OCB_BLOCK_LEN) { @@ -341,15 +363,18 @@ ocb_crypt (gcry_cipher_hd_t c, int encrypt, burn = nburn > burn ? nburn : burn; buf_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN); - /* Checksum_i = Checksum_{i-1} xor P_i */ - buf_xor_1 (c->u_ctr.ctr, encrypt? inbuf : outbuf, OCB_BLOCK_LEN); - inbuf += OCB_BLOCK_LEN; inbuflen -= OCB_BLOCK_LEN; outbuf += OCB_BLOCK_LEN; outbuflen =- OCB_BLOCK_LEN; } + if (!encrypt) + { + /* Checksum_i = Checksum_{i-1} xor P_i */ + ocb_checksum (c->u_ctr.ctr, outbuf - nblks * OCB_BLOCK_LEN, nblks); + } + /* Encrypt final partial block. Note that we expect INBUFLEN to be shorter than OCB_BLOCK_LEN (see above). */ if (inbuflen) diff --git a/tests/basic.c b/tests/basic.c index 869b381..6ebc056 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -2781,7 +2781,7 @@ check_ccm_cipher (void) static void -check_ocb_cipher (void) +do_check_ocb_cipher (int inplace) { /* Note that we use hex strings and not binary strings in TV. That makes it easier to maintain the test vectors. */ @@ -3028,7 +3028,18 @@ check_ocb_cipher (void) err = gcry_cipher_final (hde); if (!err) - err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, plain, plainlen); + { + if (inplace) + { + memcpy(out, plain, plainlen); + err = gcry_cipher_encrypt (hde, out, plainlen, NULL, 0); + } + else + { + err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, + plain, plainlen); + } + } if (err) { fail ("cipher-ocb, gcry_cipher_encrypt failed (tv %d): %s\n", @@ -3075,7 +3086,19 @@ check_ocb_cipher (void) /* Now for the decryption. */ err = gcry_cipher_final (hdd); if (!err) - err = gcry_cipher_decrypt (hdd, out, plainlen, NULL, 0); + { + if (inplace) + { + err = gcry_cipher_decrypt (hdd, out, plainlen, NULL, 0); + } + else + { + unsigned char tmp[MAX_DATA_LEN]; + + memcpy(tmp, out, plainlen); + err = gcry_cipher_decrypt (hdd, out, plainlen, tmp, plainlen); + } + } if (err) { fail ("cipher-ocb, gcry_cipher_decrypt (tv %d) failed: %s\n", @@ -3130,6 +3153,18 @@ check_ocb_cipher (void) static void +check_ocb_cipher (void) +{ + /* Check OCB cipher with separate destination and source buffers for + * encryption/decryption. */ + do_check_ocb_cipher(0); + + /* Check OCB cipher with inplace encrypt/decrypt. */ + do_check_ocb_cipher(1); +} + + +static void check_stream_cipher (void) { static const struct tv ----------------------------------------------------------------------- Summary of changes: cipher/cipher-ocb.c | 31 ++++++++++++++++++++++++++++--- tests/basic.c | 41 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 6 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits