From cvs at cvs.gnupg.org Tue Sep 1 07:35:36 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 01 Sep 2015 07:35:36 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-259-gc17f84b 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 c17f84bd02d7ee93845e92e20f6ddba814961588 (commit) via dd87639abd38afc91a6f27af33f0ba17402ad02d (commit) from a785cc3db0c4e8eb8ebbf784b833a40d2c42ec3e (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 c17f84bd02d7ee93845e92e20f6ddba814961588 Author: Werner Koch Date: Mon Aug 31 23:13:27 2015 +0200 rsa: Add verify after sign to avoid Lenstra's CRT attack. * cipher/rsa.c (rsa_sign): Check the CRT. -- Failures in the computation of the CRT (e.g. due faulty hardware) can lead to a leak of the private key. The standard precaution against this is to verify the signature after signing. GnuPG does this itself and even has an option to disable this. However, the low performance impact of this extra precaution suggest that it should always be done and Libgcrypt is the right place here. For decryption is not done because the application will detect the failure due to garbled plaintext and in any case no key derived material will be send to the user. Signed-off-by: Werner Koch diff --git a/cipher/rsa.c b/cipher/rsa.c index e4f73d5..45a481b 100644 --- a/cipher/rsa.c +++ b/cipher/rsa.c @@ -1112,7 +1112,9 @@ rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms) struct pk_encoding_ctx ctx; gcry_mpi_t data = NULL; RSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL, NULL}; + RSA_public_key pk; gcry_mpi_t sig = NULL; + gcry_mpi_t result = NULL; _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN, rsa_get_nbits (keyparms)); @@ -1148,11 +1150,25 @@ rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms) } } - /* Do RSA computation and build the result. */ + /* Do RSA computation. */ sig = mpi_new (0); secret (sig, data, &sk); if (DBG_CIPHER) log_printmpi ("rsa_sign res", sig); + + /* Check that the created signature is good. This detects a failure + of the CRT algorithm (Lenstra's attack on RSA's use of the CRT). */ + result = mpi_new (0); + pk.n = sk.n; + pk.e = sk.e; + public (result, sig, &pk); + if (mpi_cmp (result, data)) + { + rc = GPG_ERR_BAD_SIGNATURE; + goto leave; + } + + /* Convert the result. */ if ((ctx.flags & PUBKEY_FLAG_FIXEDLEN)) { /* We need to make sure to return the correct length to avoid @@ -1172,6 +1188,7 @@ rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms) leave: + _gcry_mpi_release (result); _gcry_mpi_release (sig); _gcry_mpi_release (sk.n); _gcry_mpi_release (sk.e); commit dd87639abd38afc91a6f27af33f0ba17402ad02d Author: Werner Koch Date: Mon Aug 31 22:41:12 2015 +0200 Add pubkey algo id for EdDSA. * src/gcrypt.h.in (GCRY_PK_EDDSA): New. -- These ids are not actually used by Libgcrypt but other software makes use of such algorithm ids. Thus we provide them here. Signed-off-by: Werner Koch diff --git a/NEWS b/NEWS index d90ee6d..22565ed 100644 --- a/NEWS +++ b/NEWS @@ -39,6 +39,7 @@ Noteworthy changes in version 1.7.0 (unreleased) GCRY_CIPHER_MODE_OCB NEW. GCRYCTL_SET_TAGLEN NEW. gcry_cipher_final NEW macro. + GCRY_PK_EDDSA NEW constant. Noteworthy changes in version 1.6.0 (2013-12-16) diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 884034c..585da6a 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -1053,8 +1053,9 @@ enum gcry_pk_algos GCRY_PK_DSA = 17, /* Digital Signature Algorithm. */ GCRY_PK_ECC = 18, /* Generic ECC. */ GCRY_PK_ELG = 20, /* Elgamal */ - GCRY_PK_ECDSA = 301, /* (deprecated: use 18). */ - GCRY_PK_ECDH = 302 /* (deprecated: use 18). */ + GCRY_PK_ECDSA = 301, /* (only for external use). */ + GCRY_PK_ECDH = 302, /* (only for external use). */ + GCRY_PK_EDDSA = 303 /* (only for external use). */ }; /* Flags describing usage capabilities of a PK algorithm. */ ----------------------------------------------------------------------- Summary of changes: NEWS | 1 + cipher/rsa.c | 19 ++++++++++++++++++- src/gcrypt.h.in | 5 +++-- 3 files changed, 22 insertions(+), 3 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 fweimer at redhat.com Wed Sep 2 15:46:58 2015 From: fweimer at redhat.com (Florian Weimer) Date: Wed, 2 Sep 2015 15:46:58 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-259-gc17f84b In-Reply-To: References: Message-ID: <55E6FDD2.8000302@redhat.com> On 09/01/2015 07:35 AM, by Werner Koch wrote: > commit c17f84bd02d7ee93845e92e20f6ddba814961588 > Author: Werner Koch > Date: Mon Aug 31 23:13:27 2015 +0200 > > rsa: Add verify after sign to avoid Lenstra's CRT attack. > > * cipher/rsa.c (rsa_sign): Check the CRT. > -- > > Failures in the computation of the CRT (e.g. due faulty hardware) can > lead to a leak of the private key. The standard precaution against > this is to verify the signature after signing. GnuPG does this itself > and even has an option to disable this. However, the low performance > impact of this extra precaution suggest that it should always be done > and Libgcrypt is the right place here. For decryption is not done > because the application will detect the failure due to garbled > plaintext and in any case no key derived material will be send to the > user. Some background information on this change is available here: We computed quite a few RSA signatures on x86_64, i386, ppc64, ppc64le, and s390x, but could not observe any key leaks, so we consider this change merely hardening as far as libgcrypt is concerned. -- Florian Weimer / Red Hat Product Security From cvs at cvs.gnupg.org Fri Sep 4 12:47:32 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 04 Sep 2015 12:47:32 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-261-ge97c62a 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 e97c62a4a687b56d00a2d0a63e072a977f8eb81c (commit) via e2785a2268702312529521df3bd2f4e6b43cea3a (commit) from c17f84bd02d7ee93845e92e20f6ddba814961588 (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 e97c62a4a687b56d00a2d0a63e072a977f8eb81c Author: Werner Koch Date: Fri Sep 4 12:39:56 2015 +0200 w32: Avoid a few compiler warnings. * cipher/cipher-selftest.c (_gcry_selftest_helper_cbc) (_gcry_selftest_helper_cfb, _gcry_selftest_helper_ctr): Mark variable as unused. * random/rndw32.c (slow_gatherer): Avoid signed pointer mismatch warning. * src/secmem.c (init_pool): Avoid unused variable warning. * tests/random.c (writen, readn): Include on if needed. Signed-off-by: Werner Koch diff --git a/cipher/cipher-selftest.c b/cipher/cipher-selftest.c index 470499f..cecbab7 100644 --- a/cipher/cipher-selftest.c +++ b/cipher/cipher-selftest.c @@ -131,6 +131,8 @@ _gcry_selftest_helper_cbc (const char *cipher, gcry_cipher_setkey_t setkey_func, syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " "%s-CBC-%d test failed (plaintext mismatch)", cipher, blocksize * 8); +#else + (void)cipher; /* Not used. */ #endif return "selftest for CBC failed - see syslog for details"; } @@ -251,6 +253,8 @@ _gcry_selftest_helper_cfb (const char *cipher, gcry_cipher_setkey_t setkey_func, syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " "%s-CFB-%d test failed (plaintext mismatch)", cipher, blocksize * 8); +#else + (void)cipher; /* Not used. */ #endif return "selftest for CFB failed - see syslog for details"; } @@ -379,6 +383,8 @@ _gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey_func, syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " "%s-CTR-%d test failed (plaintext mismatch)", cipher, blocksize * 8); +#else + (void)cipher; /* Not used. */ #endif return "selftest for CTR failed - see syslog for details"; } diff --git a/random/rndw32.c b/random/rndw32.c index 4ab1bca..1325b18 100644 --- a/random/rndw32.c +++ b/random/rndw32.c @@ -513,7 +513,7 @@ slow_gatherer ( void (*add)(const void*, size_t, enum random_origins), status = RegQueryValueEx (hKey, "ProductType", 0, NULL, szValue, &dwSize); - if (status == ERROR_SUCCESS && stricmp (szValue, "WinNT")) + if (status == ERROR_SUCCESS && stricmp ((char*)szValue, "WinNT")) { /* Note: There are (at least) three cases for ProductType: WinNT = NT Workstation, ServerNT = NT Server, LanmanNT = diff --git a/src/secmem.c b/src/secmem.c index d75c14c..2109bc2 100644 --- a/src/secmem.c +++ b/src/secmem.c @@ -363,8 +363,6 @@ lock_pool (void *p, size_t n) static void init_pool (size_t n) { - size_t pgsize; - long int pgsize_val; memblock_t *mb; pool_size = n; @@ -372,48 +370,54 @@ init_pool (size_t n) if (disable_secmem) log_bug ("secure memory is disabled"); -#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) - pgsize_val = sysconf (_SC_PAGESIZE); -#elif defined(HAVE_GETPAGESIZE) - pgsize_val = getpagesize (); -#else - pgsize_val = -1; -#endif - pgsize = (pgsize_val != -1 && pgsize_val > 0)? pgsize_val:DEFAULT_PAGE_SIZE; - #if HAVE_MMAP - pool_size = (pool_size + pgsize - 1) & ~(pgsize - 1); -#ifdef MAP_ANONYMOUS - pool = mmap (0, pool_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -#else /* map /dev/zero instead */ { - int fd; + size_t pgsize; + long int pgsize_val; + +# if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE) + pgsize_val = sysconf (_SC_PAGESIZE); +# elif defined(HAVE_GETPAGESIZE) + pgsize_val = getpagesize (); +# else + pgsize_val = -1; +# endif + pgsize = (pgsize_val != -1 && pgsize_val > 0)? pgsize_val:DEFAULT_PAGE_SIZE; + + pool_size = (pool_size + pgsize - 1) & ~(pgsize - 1); +# ifdef MAP_ANONYMOUS + pool = mmap (0, pool_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); +# else /* map /dev/zero instead */ + { + int fd; - fd = open ("/dev/zero", O_RDWR); - if (fd == -1) - { - log_error ("can't open /dev/zero: %s\n", strerror (errno)); - pool = (void *) -1; - } + fd = open ("/dev/zero", O_RDWR); + if (fd == -1) + { + log_error ("can't open /dev/zero: %s\n", strerror (errno)); + pool = (void *) -1; + } + else + { + pool = mmap (0, pool_size, + (PROT_READ | PROT_WRITE), MAP_PRIVATE, fd, 0); + close (fd); + } + } +# endif + if (pool == (void *) -1) + log_info ("can't mmap pool of %u bytes: %s - using malloc\n", + (unsigned) pool_size, strerror (errno)); else { - pool = mmap (0, pool_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - close (fd); + pool_is_mmapped = 1; + pool_okay = 1; } } -#endif - if (pool == (void *) -1) - log_info ("can't mmap pool of %u bytes: %s - using malloc\n", - (unsigned) pool_size, strerror (errno)); - else - { - pool_is_mmapped = 1; - pool_okay = 1; - } +#endif /*HAVE_MMAP*/ -#endif if (!pool_okay) { pool = malloc (pool_size); diff --git a/tests/fipsdrv.c b/tests/fipsdrv.c index eef2ddd..b3da2a3 100644 --- a/tests/fipsdrv.c +++ b/tests/fipsdrv.c @@ -2358,14 +2358,14 @@ main (int argc, char **argv) { if (!(++count % 1000)) fprintf (stderr, PGM ": %lu random bytes so far\n", - (unsigned long int)count * sizeof buffer); + (unsigned long int)(count * sizeof buffer)); } } while (loop_mode); if (progress) fprintf (stderr, PGM ": %lu random bytes\n", - (unsigned long int)count * sizeof buffer); + (unsigned long int)(count * sizeof buffer)); deinit_external_rng_test (context); } diff --git a/tests/gchash.c b/tests/gchash.c index 7a2aad6..7ff99e0 100644 --- a/tests/gchash.c +++ b/tests/gchash.c @@ -109,7 +109,7 @@ main (int argc, char **argv) h = gcry_md_read(hd, 0); for (i = 0; i < gcry_md_get_algo_dlen (algo); i++) - printf("%02hhx", h[i]); + printf("%02x", h[i]); printf(" %s\n", *argv); gcry_md_reset(hd); diff --git a/tests/random.c b/tests/random.c index 10bf646..d7a624a 100644 --- a/tests/random.c +++ b/tests/random.c @@ -87,7 +87,7 @@ progress_cb (void *cb_data, const char *what, int printchar, } - +#ifndef HAVE_W32_SYSTEM static int writen (int fd, const void *buf, size_t nbytes) { @@ -110,7 +110,10 @@ writen (int fd, const void *buf, size_t nbytes) return 0; } +#endif /*!HAVE_W32_SYSTEM*/ + +#ifndef HAVE_W32_SYSTEM static int readn (int fd, void *buf, size_t buflen, size_t *ret_nread) { @@ -136,7 +139,7 @@ readn (int fd, void *buf, size_t buflen, size_t *ret_nread) *ret_nread = buflen - nleft; return 0; } - +#endif /*!HAVE_W32_SYSTEM*/ /* Check that forking won't return the same random. */ commit e2785a2268702312529521df3bd2f4e6b43cea3a Author: Werner Koch Date: Fri Sep 4 12:32:16 2015 +0200 w32: Fix alignment problem with AESNI on Windows >= 8 * cipher/cipher-selftest.c (_gcry_cipher_selftest_alloc_ctx): New. * cipher/rijndael.c (selftest_basic_128, selftest_basic_192) (selftest_basic_256): Allocate context on the heap. -- The stack alignment on Windows changed and because ld seems to limit stack variables to a 8 byte alignment (we request 16), we get bus errors from the selftests if AESNI is in use. GnuPG-bug-id: 2085 Signed-off-by: Werner Koch diff --git a/cipher/cipher-selftest.c b/cipher/cipher-selftest.c index 852368a..470499f 100644 --- a/cipher/cipher-selftest.c +++ b/cipher/cipher-selftest.c @@ -44,6 +44,29 @@ #endif +/* Return an allocated buffers of size CONTEXT_SIZE with an alignment + of 16. The caller must free that buffer using the address returned + at R_MEM. Returns NULL and sets ERRNO on failure. */ +void * +_gcry_cipher_selftest_alloc_ctx (const int context_size, unsigned char **r_mem) +{ + int offs; + unsigned int ctx_aligned_size, memsize; + + ctx_aligned_size = context_size + 15; + ctx_aligned_size -= ctx_aligned_size & 0xf; + + memsize = ctx_aligned_size + 16; + + *r_mem = xtrycalloc (1, memsize); + if (!*r_mem) + return NULL; + + offs = (16 - ((uintptr_t)*r_mem & 15)) & 15; + return (void*)(*r_mem + offs); +} + + /* Run the self-tests for -CBC-, tests bulk CBC decryption. Returns NULL on success. */ const char * diff --git a/cipher/cipher-selftest.h b/cipher/cipher-selftest.h index a70667a..a435080 100644 --- a/cipher/cipher-selftest.h +++ b/cipher/cipher-selftest.h @@ -40,6 +40,11 @@ typedef void (*gcry_cipher_bulk_ctr_enc_t)(void *context, unsigned char *iv, const void *inbuf_arg, size_t nblocks); +/* Helper function to allocate an aligned context for selftests. */ +void *_gcry_cipher_selftest_alloc_ctx (const int context_size, + unsigned char **r_mem); + + /* Helper function for bulk CBC decryption selftest */ const char * _gcry_selftest_helper_cbc (const char *cipher, gcry_cipher_setkey_t setkey, diff --git a/cipher/rijndael.c b/cipher/rijndael.c index eff59c2..0130924 100644 --- a/cipher/rijndael.c +++ b/cipher/rijndael.c @@ -1358,7 +1358,8 @@ _gcry_aes_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks) static const char* selftest_basic_128 (void) { - RIJNDAEL_context ctx; + RIJNDAEL_context *ctx; + unsigned char *ctxmem; unsigned char scratch[16]; /* The test vectors are from the AES supplied ones; more or less @@ -1401,11 +1402,21 @@ selftest_basic_128 (void) }; #endif - rijndael_setkey (&ctx, key_128, sizeof (key_128)); - rijndael_encrypt (&ctx, scratch, plaintext_128); + /* Because gcc/ld can only align the CTX struct on 8 bytes on the + stack, we need to allocate that context on the heap. */ + ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem); + if (!ctx) + return "failed to allocate memory"; + + rijndael_setkey (ctx, key_128, sizeof (key_128)); + rijndael_encrypt (ctx, scratch, plaintext_128); if (memcmp (scratch, ciphertext_128, sizeof (ciphertext_128))) - return "AES-128 test encryption failed."; - rijndael_decrypt (&ctx, scratch, scratch); + { + xfree (ctxmem); + return "AES-128 test encryption failed."; + } + rijndael_decrypt (ctx, scratch, scratch); + xfree (ctxmem); if (memcmp (scratch, plaintext_128, sizeof (plaintext_128))) return "AES-128 test decryption failed."; @@ -1416,7 +1427,8 @@ selftest_basic_128 (void) static const char* selftest_basic_192 (void) { - RIJNDAEL_context ctx; + RIJNDAEL_context *ctx; + unsigned char *ctxmem; unsigned char scratch[16]; static unsigned char plaintext_192[16] = @@ -1436,11 +1448,18 @@ selftest_basic_192 (void) 0x12,0x13,0x1A,0xC7,0xC5,0x47,0x88,0xAA }; - rijndael_setkey (&ctx, key_192, sizeof(key_192)); - rijndael_encrypt (&ctx, scratch, plaintext_192); + ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem); + if (!ctx) + return "failed to allocate memory"; + rijndael_setkey (ctx, key_192, sizeof(key_192)); + rijndael_encrypt (ctx, scratch, plaintext_192); if (memcmp (scratch, ciphertext_192, sizeof (ciphertext_192))) - return "AES-192 test encryption failed."; - rijndael_decrypt (&ctx, scratch, scratch); + { + xfree (ctxmem); + return "AES-192 test encryption failed."; + } + rijndael_decrypt (ctx, scratch, scratch); + xfree (ctxmem); if (memcmp (scratch, plaintext_192, sizeof (plaintext_192))) return "AES-192 test decryption failed."; @@ -1452,7 +1471,8 @@ selftest_basic_192 (void) static const char* selftest_basic_256 (void) { - RIJNDAEL_context ctx; + RIJNDAEL_context *ctx; + unsigned char *ctxmem; unsigned char scratch[16]; static unsigned char plaintext_256[16] = @@ -1473,11 +1493,18 @@ selftest_basic_256 (void) 0x9A,0xCF,0x72,0x80,0x86,0x04,0x0A,0xE3 }; - rijndael_setkey (&ctx, key_256, sizeof(key_256)); - rijndael_encrypt (&ctx, scratch, plaintext_256); + ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem); + if (!ctx) + return "failed to allocate memory"; + rijndael_setkey (ctx, key_256, sizeof(key_256)); + rijndael_encrypt (ctx, scratch, plaintext_256); if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256))) - return "AES-256 test encryption failed."; - rijndael_decrypt (&ctx, scratch, scratch); + { + xfree (ctxmem); + return "AES-256 test encryption failed."; + } + rijndael_decrypt (ctx, scratch, scratch); + xfree (ctxmem); if (memcmp (scratch, plaintext_256, sizeof (plaintext_256))) return "AES-256 test decryption failed."; ----------------------------------------------------------------------- Summary of changes: cipher/cipher-selftest.c | 29 +++++++++++++++++++ cipher/cipher-selftest.h | 5 ++++ cipher/rijndael.c | 57 +++++++++++++++++++++++++++---------- random/rndw32.c | 2 +- src/secmem.c | 74 +++++++++++++++++++++++++----------------------- tests/fipsdrv.c | 4 +-- tests/gchash.c | 2 +- tests/random.c | 7 +++-- 8 files changed, 124 insertions(+), 56 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 transparentdata243 at gmail.com Sat Sep 5 02:17:39 2015 From: transparentdata243 at gmail.com (Danny Crane) Date: Fri, 4 Sep 2015 17:17:39 -0700 Subject: libgcrypt dependency issues Message-ID: Hi, In libgcrypt-1.5.3, I am looking for the function definition of gcry_mpi_powm. I find that it is defined in src/visibility.h:#define gcry_mpi_powm _gcry_mpi_powm But I cannot find the definition of _gcry_mpi_powm. Could anyone points me to the function definition of this? Thanks, -------------- next part -------------- An HTML attachment was scrubbed... URL: From cvs at cvs.gnupg.org Mon Sep 7 14:08:12 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 07 Sep 2015 14:08:12 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-262-g3a3d541 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 3a3d5410cc83f7069c7cb1ab384905f382292d32 (commit) from e97c62a4a687b56d00a2d0a63e072a977f8eb81c (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 3a3d5410cc83f7069c7cb1ab384905f382292d32 Author: Werner Koch Date: Mon Sep 7 14:02:09 2015 +0200 Improve GCRYCTL_DISABLE_PRIV_DROP by also disabling cap_ calls. * src/secmem.c (lock_pool, secmem_init): Do not call any cap_ functions if NO_PRIV_DROP is set. Signed-off-by: Werner Koch diff --git a/src/secmem.c b/src/secmem.c index 2109bc2..c4e8414 100644 --- a/src/secmem.c +++ b/src/secmem.c @@ -245,15 +245,21 @@ lock_pool (void *p, size_t n) { cap_t cap; - cap = cap_from_text ("cap_ipc_lock+ep"); - cap_set_proc (cap); - cap_free (cap); + if (!no_priv_drop) + { + cap = cap_from_text ("cap_ipc_lock+ep"); + cap_set_proc (cap); + cap_free (cap); + } err = no_mlock? 0 : mlock (p, n); if (err && errno) err = errno; - cap = cap_from_text ("cap_ipc_lock+p"); - cap_set_proc (cap); - cap_free(cap); + if (!no_priv_drop) + { + cap = cap_from_text ("cap_ipc_lock+p"); + cap_set_proc (cap); + cap_free(cap); + } } if (err) @@ -485,13 +491,14 @@ secmem_init (size_t n) { #ifdef USE_CAPABILITIES /* drop all capabilities */ - { - cap_t cap; + if (!no_priv_drop) + { + cap_t cap; - cap = cap_from_text ("all-eip"); - cap_set_proc (cap); - cap_free (cap); - } + cap = cap_from_text ("all-eip"); + cap_set_proc (cap); + cap_free (cap); + } #elif !defined(HAVE_DOSISH_SYSTEM) uid_t uid; @@ -539,7 +546,7 @@ _gcry_secmem_init (size_t n) gcry_err_code_t _gcry_secmem_module_init () { - /* No anymore needed. */ + /* Not anymore needed. */ return 0; } ----------------------------------------------------------------------- Summary of changes: src/secmem.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 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 wk at gnupg.org Mon Sep 7 17:42:09 2015 From: wk at gnupg.org (Werner Koch) Date: Mon, 07 Sep 2015 17:42:09 +0200 Subject: libgcrypt dependency issues In-Reply-To: (Danny Crane's message of "Fri, 4 Sep 2015 17:17:39 -0700") References: Message-ID: <87twr6dyni.fsf@vigenere.g10code.de> On Sat, 5 Sep 2015 02:17, transparentdata243 at gmail.com said: > But I cannot find the definition of _gcry_mpi_powm. Could anyone points me > to the function definition of this? This uses some macro magic: #ifdef GCRY_USE_VISIBILITY # define MARK_VISIBLE(name) \ extern __typeof__ (_##name) name __attribute__ ((visibility("default"))); # define MARK_VISIBLEX(name) \ extern __typeof__ (name) name __attribute__ ((visibility("default"))); #else # define MARK_VISIBLE(name) /* */ # define MARK_VISIBLEX(name) /* */ #endif [...] MARK_VISIBLE (gcry_mpi_powm) FWIW, Libgcrypt 1.6 should be easier to read in this regard. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Tue Sep 8 09:06:38 2015 From: wk at gnupg.org (Werner Koch) Date: Tue, 08 Sep 2015 09:06:38 +0200 Subject: Libgcrypt 1.6.4 released Message-ID: <877fo1e6f5.fsf@vigenere.g10code.de> Hello! The GNU project is pleased to announce the availability of Libgcrypt version 1.6.4. This is a maintenance release with a minor security fix. 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 of Libgcrypt. Noteworthy changes in version 1.6.4 =================================== * Speed up the random number generator by requiring less extra seeding. * New flag "no-keytest" for ECC key generation. Due to a bug in the parser that flag will also be accepted but ignored by older version of Libgcrypt. * Always verify a created RSA signature to avoid private key leaks due to hardware failures. * Fix alignment bug in the AESNI code on Windows > 7. * Support FreeBSD 10 and later. * Other minor bug fixes. Download ======== Source code is hosted at the GnuPG FTP server and its mirrors as listed at https://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.4.tar.bz2 (2490k) ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.4.tar.bz2.sig That file is bzip2 compressed. A gzip compressed version is here: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.4.tar.gz (2901k) ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.4.tar.gz.sig The same files are also available via HTTP: https://gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.6.4.tar.bz2 https://gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.6.4.tar.bz2.sig https://gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.6.4.tar.gz https://gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.6.4.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.4.tar.bz2 you would use this command: gpg --verify libgcrypt-1.6.4.tar.bz2.sig libgcrypt-1.6.4.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.4.tar.bz2 and check that the output matches the first line from the following list: ed52add1ce635deeb2f5c6650e52667debd4ec70 libgcrypt-1.6.4.tar.bz2 da6507d7ba902d7482cc09e1114ccaf3ab495c76 libgcrypt-1.6.4.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. Maintenance and development of GnuPG is possible due to many individual and corporate donations; for a list of non-anonymous donors see . For the GnuPG hackers, Werner p.s. This is an announcement only mailing list. Please send replies only to the gcrypt-devel 'at' gnupg.org mailing lists. [1] https://lists.gnupg.org/mailman/listinfo/gcrypt-devel [2] https://www.gnupg.org/service.html -- 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 zzhang at securityinnovation.com Tue Sep 8 20:45:33 2015 From: zzhang at securityinnovation.com (Zhenfei Zhang) Date: Tue, 8 Sep 2015 14:45:33 -0400 Subject: [PATCH] Add NTRUEncrypt public key encryption algorithm Message-ID: Hi list, I wish to contribute this patch to the libgcrypt. Can I please ask what is the right approach to get this patch included in a release? Thanks. Signed-off-by: Zhenfei Zhang . Commit attached. Can also be found at https://github.com/wwhyte-si/libgcrypt-ntru/commit/1cec836ec7fded3284c769b05daf4eb285527b38 On Wed, Aug 5, 2015 at 10:35 AM, Zhenfei Zhang < zzhang at securityinnovation.com> wrote: > Hi all, > > This is a patch to enable NTRUEncrypt public key encryption algorithm for > libgcrypt. > Here is the link to the commit: > > https://github.com/wwhyte-si/libgcrypt-ntru/commit/1cec836ec7fded3284c769b05daf4eb285527b38 > > PS: I am new to big projects like this. So please let me know if this is > not the correct way to do it. > > Cheers, > Zhenfei > > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- diff --git a/.gitignore b/.gitignore index 3929e4d..db863dd 100644 --- a/.gitignore +++ b/.gitignore @@ -84,3 +84,6 @@ tests/rsacvt tests/t-mpi-bit tests/tsexp tests/version +*~ +sample/a.out +.* diff --git a/README b/README index 938c6c6..0dc0509 100644 --- a/README +++ b/README @@ -36,6 +36,10 @@ You should get the latest versions of course. + To build libgcrypt with NTRU public key crypto: + https://github.com/NTRUOpenSourceProject/ntru-crypto + + After building and installing the libgpg-error package, you may continue with Libgcrypt installation as with allmost all GNU packages, you just have to do @@ -185,8 +189,11 @@ the feature under the assumption that either good CFLAGS are given or the compiler can grok the code. - - + --enable-ntru + This let libgcrypt to link against libntruencrypt. + To check if it is linked propoerly, run the sample + code from sample/test_ntru_gcrypt.cpp. + Build Problems -------------- diff --git a/README_NTRU b/README_NTRU new file mode 100644 index 0000000..e8b1aa4 --- /dev/null +++ b/README_NTRU @@ -0,0 +1,18 @@ + libgcrypt : enabling NTRUEncrypt for libgcrypt + ------------------------------------------------------- + +Dependency: + libntruencrypt 1.0.0 + https://github.com/NTRUOpenSourceProject/ntru-crypto + +Installation: + + ./autogen.sh + ./configure --enable-maintainer-mode --enable-ntru + make + sudo make install + +Example code: + cd sample + g++ test_ntru_gcrypt.cpp -lgcrypt -o test.o + ./test.o diff --git a/autogen.rc b/autogen.rc index 09a9b9c..1e800f6 100644 --- a/autogen.rc +++ b/autogen.rc @@ -14,4 +14,4 @@ case "$myhost" in ;; esac -final_info="./configure --enable-maintainer-mode && make" +final_info="./configure --enable-maintainer-mode --enable-ntru && make" diff --git a/autogen.sh b/autogen.sh index 471193c..d8da839 100755 --- a/autogen.sh +++ b/autogen.sh @@ -277,7 +277,7 @@ if [ "$myhost" = "amd64" ]; then fi fi - $tsdir/configure --enable-maintainer-mode ${SILENT} \ + $tsdir/configure --enable-maintainer-mode --enable-ntru ${SILENT} \ --prefix=${amd64root} \ --host=${host} --build=${build} \ ${configure_opts} ${extraoptions} "$@" diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 33a68ff..c82f8d5 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -57,9 +57,13 @@ bufhelp.h \ primegen.c \ hash-common.c hash-common.h \ dsa-common.c rsa-common.c \ +base64.c \ +base64.h \ rmd.h EXTRA_libcipher_la_SOURCES = \ +ntru-gcrypt-wrapper.c \ +ntru-gcrypt-wrapper.h \ arcfour.c arcfour-amd64.S \ blowfish.c blowfish-amd64.S blowfish-arm.S \ cast5.c cast5-amd64.S cast5-arm.S \ diff --git a/cipher/base64.c b/cipher/base64.c new file mode 100644 index 0000000..cfedfb9 --- /dev/null +++ b/cipher/base64.c @@ -0,0 +1,295 @@ +/* + * RFC 1521 base64 encoding/decoding + * + * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved + * + * This file is part of mbed TLS (https://tls.mbed.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU 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. + */ + +/*#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_BASE64_C) + +#include "polarssl/base64.h" + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#if defined(POLARSSL_SELF_TEST) +#include +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_printf printf +#endif /* POLARSSL_PLATFORM_C */ +//#endif /* POLARSSL_SELF_TEST */ + + +#include "base64.h" +#include + + +static const unsigned char base64_enc_map[64] = +{ + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '+', '/' +}; + +static const unsigned char base64_dec_map[128] = +{ + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 62, 127, 127, 127, 63, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, + 127, 64, 127, 127, 127, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 127, 127, 127, 127, 127, 127, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 127, 127, 127, 127, 127 +}; + +/* + * Encode a buffer into base64 format + */ +int base64_encode( unsigned char *dst, size_t *dlen, + const unsigned char *src, size_t slen ) +{ + size_t i, n; + int C1, C2, C3; + unsigned char *p; + + if( slen == 0 ) + { + *dlen = 0; + return( 0 ); + } + n = ( slen << 3 ) / 6; + + switch( ( slen << 3 ) - ( n * 6 ) ) + { + case 2: n += 3; break; + case 4: n += 2; break; + default: break; + } + + if( *dlen < n + 1 ) + { + *dlen = n + 1; + return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + n = ( slen / 3 ) * 3; + + for( i = 0, p = dst; i < n; i += 3 ) + { + C1 = *src++; + C2 = *src++; + C3 = *src++; + + *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; + *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; + *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F]; + *p++ = base64_enc_map[C3 & 0x3F]; + } + + if( i < slen ) + { + C1 = *src++; + C2 = ( ( i + 1 ) < slen ) ? *src++ : 0; + + *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; + *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; + + if( ( i + 1 ) < slen ) + *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; + else *p++ = '='; + + *p++ = '='; + } + + *dlen = p - dst; + *p = 0; + + return( 0 ); +} + +/* + * Decode a base64-formatted buffer + */ +int base64_decode( unsigned char *dst, size_t *dlen, + const unsigned char *src, size_t slen ) +{ + size_t i, n; + uint32_t j, x; + unsigned char *p; + + /* First pass: check for validity and get output length */ + for( i = n = j = 0; i < slen; i++ ) + { + /* Skip spaces before checking for EOL */ + x = 0; + while( i < slen && src[i] == ' ' ) + { + ++i; + ++x; + } + + /* Spaces at end of buffer are OK */ + if( i == slen ) + break; + + if( ( slen - i ) >= 2 && + src[i] == '\r' && src[i + 1] == '\n' ) + continue; + + if( src[i] == '\n' ) + continue; + + /* Space inside a line is an error */ + if( x != 0 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + if( src[i] == '=' && ++j > 2 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + if( base64_dec_map[src[i]] < 64 && j != 0 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + n++; + } + + if( n == 0 ) + return( 0 ); + + n = ( ( n * 6 ) + 7 ) >> 3; + n -= j; + + if( dst == NULL || *dlen < n ) + { + *dlen = n; + return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) + { + if( *src == '\r' || *src == '\n' || *src == ' ' ) + continue; + + j -= ( base64_dec_map[*src] == 64 ); + x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F ); + + if( ++n == 4 ) + { + n = 0; + if( j > 0 ) *p++ = (unsigned char)( x >> 16 ); + if( j > 1 ) *p++ = (unsigned char)( x >> 8 ); + if( j > 2 ) *p++ = (unsigned char)( x ); + } + } + + *dlen = p - dst; + + return( 0 ); +} + +#if defined(POLARSSL_SELF_TEST) + +static const unsigned char base64_test_dec[64] = +{ + 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD, + 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01, + 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09, + 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13, + 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31, + 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38, + 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B, + 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97 +}; + +static const unsigned char base64_test_enc[] = + "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK" + "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw=="; + +/* + * Checkup routine + */ +int base64_self_test( int verbose ) +{ + size_t len; + const unsigned char *src; + unsigned char buffer[128]; + + if( verbose != 0 ) + polarssl_printf( " Base64 encoding test: " ); + + len = sizeof( buffer ); + src = base64_test_dec; + + if( base64_encode( buffer, &len, src, 64 ) != 0 || + memcmp( base64_test_enc, buffer, 88 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n Base64 decoding test: " ); + + len = sizeof( buffer ); + src = base64_test_enc; + + if( base64_decode( buffer, &len, src, 88 ) != 0 || + memcmp( base64_test_dec, buffer, 64 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n\n" ); + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +//#endif /* POLARSSL_BASE64_C */ diff --git a/cipher/base64.h b/cipher/base64.h new file mode 100644 index 0000000..2fd1ac6 --- /dev/null +++ b/cipher/base64.h @@ -0,0 +1,86 @@ +/** + * \file base64.h + * + * \brief RFC 1521 base64 encoding/decoding + * + * Copyright (C) 2006-2013, ARM Limited, All Rights Reserved + * + * This file is part of mbed TLS (https://tls.mbed.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU 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. + */ +#ifndef POLARSSL_BASE64_H +#define POLARSSL_BASE64_H + +#include +#include +#include + +#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */ +#define POLARSSL_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Encode a buffer into base64 format + * + * \param dst destination buffer + * \param dlen size of the buffer + * \param src source buffer + * \param slen amount of data to be encoded + * + * \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL. + * *dlen is always updated to reflect the amount + * of data that has (or would have) been written. + * + * \note Call this function with *dlen = 0 to obtain the + * required buffer size in *dlen + */ +int base64_encode( unsigned char *dst, size_t *dlen, + const unsigned char *src, size_t slen ); + +/** + * \brief Decode a base64-formatted buffer + * + * \param dst destination buffer (can be NULL for checking size) + * \param dlen size of the buffer + * \param src source buffer + * \param slen amount of data to be decoded + * + * \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or + * POLARSSL_ERR_BASE64_INVALID_CHARACTER if the input data is + * not correct. *dlen is always updated to reflect the amount + * of data that has (or would have) been written. + * + * \note Call this function with *dst = NULL or *dlen = 0 to obtain + * the required buffer size in *dlen + */ +int base64_decode( unsigned char *dst, size_t *dlen, + const unsigned char *src, size_t slen ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int base64_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* base64.h */ diff --git a/cipher/ntru-gcrypt-wrapper.c b/cipher/ntru-gcrypt-wrapper.c new file mode 100644 index 0000000..28d35e2 --- /dev/null +++ b/cipher/ntru-gcrypt-wrapper.c @@ -0,0 +1,459 @@ +/* ntru-grcrypt-wrapper.h + * Copyright (C) 2015, Security Innovation. + * Author Zhenfei Zhang + * + * 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 . + */ + +/* This code is a wrapper for libgcrypt to be linked with libntruencrypt + * NTRUEncrypt is a lattice-based public key encryption algorithm. + * For the latest version of the NTRUEncrypt specs, visit + * https://github.com/NTRUOpenSourceProject/NTRUEncrypt + */ + + + +#include +#include +#include +#include + +#include "types.h" +#include "g10lib.h" +#include "gcrypt.h" +#include "cipher.h" +#include "bufhelp.h" +#include "gcrypt-int.h" +#include "base64.h" +#include +#include "ntru-gcrypt-wrapper.h" + +static const char *ntru_names[] = +{ + "ntru", + NULL, +}; + +gcry_pk_spec_t _gcry_pubkey_spec_ntru = { + GCRY_PK_NTRU, // algo; + {0,0}, // struct { + // unsigned int disabled:1; + // unsigned int fips:1; + // } flags; + GCRY_PK_USAGE_ENCR, // int use; + "ntru", // const char *name; + ntru_names, // const char **aliases; + NULL, // const char *elements_pkey; + NULL, // const char *elements_skey; + NULL, // const char *elements_enc; + NULL, // const char *elements_sig; + NULL, // const char *elements_grip; + gcry_ntru_keygen, // gcry_pk_generate_t generate; + gcry_ntru_check_secret_key, // gcry_pk_check_secret_key_t check_secret_key; + gcry_ntru_encrypt, // gcry_pk_encrypt_t encrypt; + gcry_ntru_decrypt, // gcry_pk_decrypt_t decrypt; + NULL, // gcry_pk_sign_t sign; + NULL, // gcry_pk_verify_t verify; + gcry_ntru_get_nbits, // gcry_pk_get_nbits_t get_nbits; + NULL, // selftest_func_t selftest; + gcry_ntru_comp_keygrip, // pk_comp_keygrip_t comp_keygrip; + NULL, // pk_get_curve_t get_curve; + NULL // pk_get_curve_param_t get_curve_param; +}; + +static gpg_err_code_t gcry_ntru_comp_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms) +{ + fprintf (stderr,"NTRU compute keygrip function not required/implemented\n"); + return 0; +} + +static unsigned int gcry_ntru_get_nbits (gcry_sexp_t parms) +{ + fprintf (stderr,"NTRU get nbits function not required/implemented\n"); + return 0; +} +static gcry_err_code_t gcry_ntru_check_secret_key (gcry_sexp_t keyparms) +{ + fprintf (stderr,"NTRU check secret key function not required/implemented\n"); + return 0; +} + + +NTRU_ENCRYPT_PARAM_SET_ID gcry_ntru_get_param_id (gcry_sexp_t genparms) +{ + if ((_gcry_sexp_find_token(genparms, "n439", 4)!= NULL) || + (_gcry_sexp_find_token(genparms, "b128", 4)!= NULL)) + return NTRU_EES439EP1; + + if ((_gcry_sexp_find_token(genparms, "n593", 4)!= NULL) || + (_gcry_sexp_find_token(genparms, "b192", 4)!= NULL)) + return NTRU_EES593EP1; + + if ((_gcry_sexp_find_token(genparms, "n743", 4)!= NULL) || + (_gcry_sexp_find_token(genparms, "b256", 4)!= NULL)) + return NTRU_EES743EP1; + + return -1; +} + + +/* Type for the pk_generate function. */ +// typedef gcry_err_code_t (*gcry_pk_generate_t) (gcry_sexp_t genparms, +// gcry_sexp_t *r_skey); +gcry_err_code_t gcry_ntru_keygen (gcry_sexp_t genparms, gcry_sexp_t *r_skey) +{ + + NTRU_ENCRYPT_PARAM_SET_ID paramid; + int rc; /* return code */ + uint8_t *public_key; /* sized for EES401EP2 */ + uint16_t public_key_len; /* no. of octets in public key */ + uint8_t *private_key; /* sized for EES401EP2 */ + uint16_t private_key_len; /* no. of octets in private key */ + DRBG_HANDLE drbg; /* handle for instantiated DRBG */ + uint8_t *pers_str; + gcry_sexp_t temp_pk, temp_sk; + + /* start key generation */ + paramid = gcry_ntru_get_param_id (genparms); + + if (paramid <0) + { + fprintf (stderr, "gcry_ntru: unrecognized parameter id\n"); + return -1; + } +/* + if (paramid == NTRU_EES439EP1) + printf("using NTRU_EES439EP1\n"); + if (paramid == NTRU_EES593EP1) + printf("using NTRU_EES593EP1\n"); + if (paramid == NTRU_EES743EP1) + printf("using NTRU_EES743EP1\n"); +*/ + /* optional personal string for DRBG */ + /* use this prg for best security */ +// pers_str = (uint8_t*)_gcry_random_bytes (32, GCRY_STRONG_RANDOM); + /* use this one to improve performance */ + pers_str = (uint8_t*)_gcry_random_bytes (32, GCRY_WEAK_RANDOM); + + + public_key = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_); + private_key = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_); + + memset(public_key, 0, _MAX_NTRU_BUF_SIZE_); + memset(private_key, 0, _MAX_NTRU_BUF_SIZE_); + + /* generating NTRU keys */ + + rc = ntru_crypto_drbg_instantiate(256, pers_str, sizeof(pers_str), (ENTROPY_FN) &get_entropy, &drbg); + if (rc!=0) + { + fprintf (stderr, "drbg error, ntru code: %d\n", rc); + return rc; + } + rc = ntru_crypto_ntru_encrypt_keygen(drbg, paramid , &public_key_len, NULL, &private_key_len, NULL); + if (rc!=0) + { + fprintf (stderr, "key gen error, ntru code: %d\n", rc); + return rc; + } + rc = ntru_crypto_ntru_encrypt_keygen(drbg, paramid , &public_key_len, public_key, &private_key_len, private_key); + if (rc!=0) + { + fprintf (stderr, "key gen error, ntru code: %d\n", rc); + return rc; + } + + /* extract the key pair */ + temp_pk = convert_ntru_data_to_sexp (public_key, public_key_len); + temp_sk = convert_ntru_data_to_sexp (private_key, private_key_len); + rc = _gcry_sexp_build (r_skey, NULL, + "(key-data(public-key(ntru%S))(private-key(ntru%S)))", temp_pk, temp_sk); + if (rc!=0) + { + fprintf (stderr, "gcry_sexp_build error: %s\n", _gcry_strerror (rc)); + return rc; + } + +// _gcry_sexp_dump(*r_skey); + + /* cleaning up */ + rc = ntru_crypto_drbg_uninstantiate(drbg); + if (rc!=0) + { + fprintf (stderr, "drbg error, ntru code: %d\n", rc); + return rc; + } + free(public_key); + free(private_key); + free(pers_str); + xfree(temp_sk); + xfree(temp_pk); + return rc; +} + +/* Type for the pk_encrypt function. */ +// typedef gcry_err_code_t (*gcry_pk_encrypt_t) (gcry_sexp_t *r_ciph, +// gcry_sexp_t s_data, +// gcry_sexp_t keyparms); +gcry_err_code_t gcry_ntru_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) +{ + uint8_t rc; + uint8_t *msg_buf; + uint8_t *key_buf; + uint8_t *working_buf; + size_t msg_len; + size_t key_len; + size_t working_buf_len; + DRBG_HANDLE drbg; + + working_buf = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_); + msg_buf = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_); + key_buf = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_); + memset(msg_buf, 0, _MAX_NTRU_BUF_SIZE_); + memset(key_buf, 0, _MAX_NTRU_BUF_SIZE_); + memset(working_buf, 0, _MAX_NTRU_BUF_SIZE_); + msg_len = _MAX_NTRU_BUF_SIZE_; + key_len = _MAX_NTRU_BUF_SIZE_; + working_buf_len = _MAX_NTRU_BUF_SIZE_; + + /* extracting the message */ + msg_buf = _gcry_sexp_nth_data (_gcry_sexp_find_token(s_data, "value", 0), 1, &msg_len); + /* extracting the public key; removing ntru header */ + working_buf = _gcry_sexp_nth_data (_gcry_sexp_cadr (keyparms), 0, &working_buf_len); + base64_decode(key_buf, &key_len, working_buf+4, working_buf_len-4); + + /* performing ntru encryption */ + rc = ntru_crypto_drbg_instantiate(256, NULL, 0, (ENTROPY_FN) &get_entropy, &drbg); + if (rc!=0) + { + fprintf (stderr, "drbg error, ntru code: %d\n", rc); + return rc; + } + rc = ntru_crypto_ntru_encrypt(drbg, key_len, key_buf, msg_len, msg_buf, &working_buf_len, NULL); + if (rc!=0) + { + fprintf (stderr, "encryption error, ntru code: %d\n", rc); + return rc; + } + rc = ntru_crypto_ntru_encrypt(drbg, key_len, key_buf, msg_len, msg_buf, &working_buf_len, working_buf); + if (rc!=0) + { + fprintf (stderr, "encryption error, ntru code: %d\n", rc); + return rc; + } + + *r_ciph = convert_ntru_data_to_sexp (working_buf, working_buf_len); +// _gcry_sexp_dump(*r_ciph); + + /* cleaning up */ + rc = ntru_crypto_drbg_uninstantiate(drbg); + if (rc!=0) + { + fprintf (stderr, "drbg error, ntru code: %d\n", rc); + return rc; + } + free(key_buf); +// free(working_buf); +// free(msg_buf); + return rc; +} + + + +/* Type for the pk_decrypt function. */ +// typedef gcry_err_code_t (*gcry_pk_decrypt_t) (gcry_sexp_t *r_plain, +// gcry_sexp_t s_data, +// gcry_sexp_t keyparms); +gcry_err_code_t gcry_ntru_decrypt (gcry_sexp_t *r_msg, gcry_sexp_t s_data, gcry_sexp_t keyparms) +{ + int rc; + uint8_t *cipher_buf; + uint8_t *key_buf; + uint8_t *working_buf; + size_t cipher_len; + size_t key_len; + size_t working_buf_len; + gcry_sexp_t key; + + working_buf = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_); + cipher_buf = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_); + key_buf = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_); + memset(cipher_buf, 0, _MAX_NTRU_BUF_SIZE_); + memset(key_buf, 0, _MAX_NTRU_BUF_SIZE_); + memset(working_buf, 0, _MAX_NTRU_BUF_SIZE_); + cipher_len = _MAX_NTRU_BUF_SIZE_; + key_len = _MAX_NTRU_BUF_SIZE_; + working_buf_len = _MAX_NTRU_BUF_SIZE_; + + /* extracting the cipher; removing ntru header */ + working_buf = _gcry_sexp_nth_data (s_data, 0, &working_buf_len); + base64_decode(cipher_buf, &cipher_len, working_buf+4, working_buf_len-4); + + /* extracting the private key; removing ntru header */ + key = _gcry_sexp_cadr (keyparms); + working_buf = _gcry_sexp_nth_data (key, 0, &working_buf_len); + base64_decode(key_buf, &key_len, working_buf+4, working_buf_len-4); + + /* performing ntru decryption */ + rc = ntru_crypto_ntru_decrypt(key_len, key_buf, cipher_len, cipher_buf, &working_buf_len, NULL); + if (rc!=0) + { + fprintf (stderr, "decryption error, ntru code: %d\n", rc); + return rc; + } + rc = ntru_crypto_ntru_decrypt(key_len, key_buf, cipher_len, cipher_buf, &working_buf_len, working_buf); + if (rc!=0) + { + fprintf (stderr, "decryption error, ntru code: %d\n", rc); + return rc; + } + working_buf[working_buf_len] = '\0'; + rc = _gcry_sexp_build (r_msg, NULL, "%s", working_buf); + if (rc!=0) + { + fprintf (stderr, "gcry_sexp_build error: %s\n", _gcry_strerror (rc)); + return rc; + } + /* cleaning up */ + free(cipher_buf); + free(key_buf); + xfree(key); + return rc; +} + +/* + * convert an ntru blob in ntru_data to a s-expression: + * 1. convert ASCII coded ntru blob into base64 encoding string + * 2. add guard string "NTRU" to the start of the string + * (if the base64 encoded string starts with a non-alphabetic + * char, sexp builder will bug) + * 3. form the sexp + */ +gcry_sexp_t convert_ntru_data_to_sexp (const uint8_t* ntru_data, const size_t ntru_data_len) +{ + gcry_sexp_t sexp_data; + uint8_t *base64_data; + size_t base64_data_len = _MAX_NTRU_BUF_SIZE_; + uint8_t *tmp_str; + int rc; + base64_data = (uint8_t*) malloc (ntru_data_len*2*sizeof(uint8_t)); + tmp_str = (uint8_t*) malloc ((base64_data_len+2)*sizeof(uint8_t)); + + rc = base64_encode(base64_data, &base64_data_len, ntru_data, ntru_data_len); + + tmp_str[0] = '('; + tmp_str[1] = 'N'; + tmp_str[2] = 'T'; + tmp_str[3] = 'R'; + tmp_str[4] = 'U'; + memcpy(tmp_str+5, base64_data, base64_data_len*sizeof(uint8_t)); + tmp_str[base64_data_len+5] = ')'; + tmp_str[base64_data_len+6] = '\0'; + + rc = _gcry_sexp_sscan (&sexp_data, NULL, tmp_str, strlen(tmp_str)); + if (rc!=0) + { + fprintf (stderr, "gcry_sexp_new: %s\n", _gcry_strerror (rc)); + return rc; + } +// _gcry_sexp_dump(sexp_data); + + free(tmp_str); + free(base64_data); + return sexp_data; +} +/* + * turns out those two functions are no longer required + * +void convert_sexp_data_to_ntru (const gcry_sexp_t sexp_data, uint8_t* ntru_data, size_t* ntru_data_len) +{ + uint8_t *buffer = (uint8_t*) malloc(_MAX_NTRU_BUF_SIZE_); + uint8_t *ntru_data_buf = (uint8_t*) malloc(_MAX_NTRU_BUF_SIZE_); + uint8_t *buffer_pt = buffer; + size_t length; + *ntru_data_len = _MAX_NTRU_BUF_SIZE_; + _gcry_sexp_sprint (sexp_data, 3, buffer, ntru_data_len); + int i=0; + printf("buffer: "); + while(buffer[i]!='\0'){ + printf("%c ",buffer[i]);i++;} + printf("\n"); + length = my_strlen(buffer) - 7 ; // one for '(', four for "NTRU", one for ')', one for '\0' + buffer_pt = buffer+5; // removing the first five chars '(NTRU' + buffer_pt [length] = '\0'; // removing the last char ')' + + base64_decode( (uint8_t*)ntru_data_buf, ntru_data_len, buffer_pt, length); + + free (buffer); + free (ntru_data_buf); +} + +size_t my_strlen(const uint8_t *str) +{ + size_t i; + for (i = 0; str[i]; i++); + return i; +} +*/ + +static uint8_t +get_entropy( + ENTROPY_CMD cmd, + uint8_t *out) +{ + + int num_bytes = 48; + /* + * dimension number of bytes + * 439 24 + * 593 36 + * 743 48 + */ + /* use this prg for best security */ +// uint8_t *seed = (uint8_t*)_gcry_random_bytes (num_bytes, GCRY_STRONG_RANDOM); + /* use this prg to improve performance */ + uint8_t *seed = (uint8_t*)_gcry_random_bytes (num_bytes, GCRY_WEAK_RANDOM); + + + + static size_t index; + + if (cmd == INIT) { + /* Any initialization for a real entropy source goes here. */ + index = 0; + return 1; + } + + if (out == NULL) + return 0; + + if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) { + /* Here we return the number of bytes needed from the entropy + * source to obtain 8 bits of entropy. Maximum is 8. + */ + *out = 1; /* this is a perfectly random source */ + return 1; + } + + if (cmd == GET_BYTE_OF_ENTROPY) { + if (index == 128) + return 0; /* used up all our entropy */ + + *out = seed[index++]; /* deliver an entropy byte */ + return 1; + } + return 0; +} diff --git a/cipher/ntru-gcrypt-wrapper.h b/cipher/ntru-gcrypt-wrapper.h new file mode 100644 index 0000000..0b5c3ab --- /dev/null +++ b/cipher/ntru-gcrypt-wrapper.h @@ -0,0 +1,81 @@ +/* ntru-grcrypt-wrapper.h + * Copyright (C) 2015, Security Innovation. + * Author Zhenfei Zhang + * + * 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 . + */ + +/* This code is a wrapper for libgcrypt to be linked with libntruencrypt + * NTRUEncrypt is a lattice-based public key encryption algorithm. + * For the latest version of the NTRUEncrypt specs, visit + * https://github.com/NTRUOpenSourceProject/NTRUEncrypt + */ + + +#ifndef NTRU_GCRYPT_WRAPPER_H +#define NTRU_GCRYPT_WRAPPER_H + + +#include +#include +#include +#include + +#include "types.h" +#include "g10lib.h" +#include "gcrypt.h" +#include "cipher.h" +#include "bufhelp.h" +#include "gcrypt-int.h" +#include "base64.h" +#include + + +#ifndef _MAX_NTRU_BUF_SIZE_ +#define _MAX_NTRU_BUF_SIZE_ 2000 +#endif + +/* NTRUEncrypt keygen function, input genparms, output a keypair in r_skey + * sample genparms: + * (genkey(ntru(b256))), (genkey(ntru(n743))) = 256 bits security with dimension 743 + * (genkey(ntru(b192))), (genkey(ntru(n593))) = 192 bits security with dimension 593 + * (genkey(ntru(b128))), (genkey(ntru(n439))) = 128 bits security with dimension 439 + */ +gcry_err_code_t gcry_ntru_keygen (gcry_sexp_t genparms, gcry_sexp_t *r_skey); + +gcry_err_code_t gcry_ntru_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms); +gcry_err_code_t gcry_ntru_decrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms); + +// data conversion: S expression <---> ntru data +gcry_sexp_t convert_ntru_data_to_sexp (const uint8_t* ntru_data, const size_t ntru_data_len); +// void convert_sexp_data_to_ntru (const gcry_sexp_t sexp_data, uint8_t* ntru_data, size_t* ntru_data_len); + +/* + * dump functions + */ +static gpg_err_code_t gcry_ntru_comp_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms); +static unsigned int gcry_ntru_get_nbits (gcry_sexp_t parms); +static gcry_err_code_t gcry_ntru_check_secret_key (gcry_sexp_t keyparms); +//static gcry_err_code_t gcry_ntru_self_tests (int algo, int extended, selftest_report_func_t report); +//static gcry_err_code_t ntru_self_tests (selftest_report_func_t report); + +/* + * misc functions + */ +static uint8_t get_entropy(ENTROPY_CMD cmd, uint8_t *out); +//size_t my_strlen(const unsigned char *str); + +#endif //NTRU_GCRYPT_WRAPPER_H diff --git a/cipher/pubkey.c b/cipher/pubkey.c index e3842c0..39c7f14 100644 --- a/cipher/pubkey.c +++ b/cipher/pubkey.c @@ -48,6 +48,9 @@ static gcry_pk_spec_t *pubkey_list[] = #if USE_ELGAMAL &_gcry_pubkey_spec_elg, #endif +#if USE_NTRU + &_gcry_pubkey_spec_ntru, +#endif NULL }; @@ -62,6 +65,7 @@ map_algo (int algo) case GCRY_PK_ELG_E: return GCRY_PK_ELG; case GCRY_PK_ECDSA: return GCRY_PK_ECC; case GCRY_PK_ECDH: return GCRY_PK_ECC; + case GCRY_PK_NTRU: return GCRY_PK_NTRU; default: return algo; } } diff --git a/configure.ac b/configure.ac index 0f16175..c9bdb6d 100644 --- a/configure.ac +++ b/configure.ac @@ -329,6 +329,18 @@ case "${host}" in ;; esac +# check if configured with libntruencrypt +AC_ARG_ENABLE(ntru, + AS_HELP_STRING(--enable-ntru, Build libgcrypt with support for NTRUEncrypt algorithm), [], [enable_ntru=no]) + +if test $enable_ntru != no; then + AC_CHECK_HEADERS([libntruencrypt/ntru_crypto.h]) + LIBS="$LIBS -lntruencrypt" + NTRUENCRYPT_LIBS=-lntruencrypt + available_pubkey_ciphers="$available_pubkey_ciphers ntru" + + AC_SUBST(NTRUENCRYPT_LIBS) +fi AC_ARG_ENABLE(endian-check, AC_HELP_STRING([--disable-endian-check], @@ -2019,6 +2031,12 @@ if test "$found" = "1" ; then AC_DEFINE(USE_ECC, 1, [Defined if this module should be included]) fi +LIST_MEMBER(ntru, $enabled_pubkey_ciphers) +if test "$found" = "1" ; then + GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS ntru-gcrypt-wrapper.lo" + AC_DEFINE(USE_NTRU, 1, [Defined if this module should be included]) +fi + LIST_MEMBER(crc, $enabled_digests) if test "$found" = "1" ; then GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc.lo" diff --git a/sample/test_ntru_gcrypt.cpp b/sample/test_ntru_gcrypt.cpp new file mode 100644 index 0000000..68eda77 --- /dev/null +++ b/sample/test_ntru_gcrypt.cpp @@ -0,0 +1,151 @@ +/* test_ntru_gcrypt.cpp + * Copyright (C) 2015, Security Innovation. + * Author Zhenfei Zhang + * + * 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 . + */ + +/* This code is an example of using libgcrypt instantiated with NTRUEncrypt + * For the latest version of the NTRUEncrypt specs, visit + * https://github.com/NTRUOpenSourceProject/NTRUEncrypt + */ + +#include +#include + +using namespace std; + +#ifndef _MAX_NTRU_BUF_SIZE_ +#define _MAX_NTRU_BUF_SIZE_ 4000 +#endif + +#define DEBUG + +/* Dumps a buffer in hex to the screen for debugging */ + +void gcrypt_init(); + +int main() { + + gcrypt_init(); + gcry_error_t err = 0; + gcry_sexp_t ntru_parms; + gcry_sexp_t ntru_keypair; + gcry_sexp_t data; + gcry_sexp_t cipher; + + /* + * Check if NTRU is avaliable + */ + err = gcry_pk_test_algo (GCRY_PK_NTRU); + if (err) + cerr<<"NTRUEncrypt is not supported: "<member) #define BUG() do {fprintf ( stderr, "Ooops at %s:%d\n", __FILE__ , __LINE__ );\ @@ -1540,6 +1677,106 @@ ecc_bench (int iterations, int print_header) } #endif /*USE_ECC*/ } +static void +ntru_bench (int iterations, int print_header) +{ +#if USE_NTRU + gpg_error_t err; + gcry_sexp_t pub_key[3], sec_key[3]; + int i, counter; + int dim[3] = { 439, 593,743 }; + gcry_sexp_t data; + gcry_sexp_t enc[iterations]; + gcry_sexp_t plain[iterations]; + const unsigned char* msg = (const unsigned char*) "Hello SI. Let's encrypt."; + char timerbuf1[100]; + + err = gcry_sexp_new(pub_key+0,sample_public_ntru_key439,strlen (sample_public_ntru_key439),1); + if (!err) + err = gcry_sexp_new(pub_key+1,sample_public_ntru_key593,strlen (sample_public_ntru_key593),1); + if (!err) + err = gcry_sexp_new(pub_key+2,sample_public_ntru_key743,strlen (sample_public_ntru_key743),1); + if (!err) + err = gcry_sexp_new(sec_key+0,sample_secret_ntru_key439,strlen (sample_secret_ntru_key439),1); + if (!err) + err = gcry_sexp_new(sec_key+1,sample_secret_ntru_key593,strlen (sample_secret_ntru_key593),1); + if (!err) + err = gcry_sexp_new(sec_key+2,sample_secret_ntru_key743,strlen (sample_secret_ntru_key743),1); + + if (err) + { + fprintf (stderr, PGM ": converting sample keys failed: %s\n", + gcry_strerror (err)); + exit (1); + } + err = gcry_sexp_build(&data, NULL, "(data (flags raw) (value %s))", msg); + + if (print_header) + printf ("Algorithm generate %4d*priv %4d*public\n" + "------------------------------------------------\n", + iterations, iterations ); + + + for(i=0;i<3;i++) + { + for (counter=0;counter References: Message-ID: <55EF5A2A.3040703@riseup.net> Hi Zhenfei, On 09/08/2015 08:45 PM, Zhenfei Zhang wrote: > Hi list, > > I wish to contribute this patch to the libgcrypt. > Can I please ask what is the right approach to get this patch included > in a release? > Thanks. First of all, I'm new to this list, so I speak only for myself. I'm sure happy to see lattice stuff, it's interesting. But the first thing that bothers me is that it introduces a dependency. We can't just link in some crypto algorithm from somewhere, we want source :) As it stands now, libgcrypt doesn't have any dependencies at all, even GMP integers are included as source in the library. Secondly, experimental crypto is not really libgcrypt's thing. If I look at the Wikipedia article on NTRUEncrypt, I read that it's not yet proven to be secure against quantum cryptanalysis, and there is a problem with performance. What I read about the attacks doesn't make me happy either. It's all just not crystalized out yet, and the algorithm is not a formal standard, as far as I can tell. I see that the IEEE is working towards a standard with NTRUEncrypt, which is good, but it's not there yet. Anyway, just my 2 cents, --Opal From wk at gnupg.org Wed Sep 9 10:39:06 2015 From: wk at gnupg.org (Werner Koch) Date: Wed, 09 Sep 2015 10:39:06 +0200 Subject: [PATCH] Add NTRUEncrypt public key encryption algorithm In-Reply-To: (Zhenfei Zhang's message of "Tue, 8 Sep 2015 14:45:33 -0400") References: Message-ID: <87h9n4aswl.fsf@vigenere.g10code.de> On Tue, 8 Sep 2015 20:45, zzhang at securityinnovation.com said: > Can I please ask what is the right approach to get this patch included in a > release? One question is whether we want to include this algorithm. I see several reasons not to do this: - Post quantum crypto is quite young and as of now mostly an academic exercise. However, inclusion in a general purpose crypto library might be worth for algorithms which are likely going to be used in some future. I can't decide on this and would for example ask Tanja Lange for her opinion on NTRU. - The code implementing the algorithm is under the GPL and thus can't be used by Libgcrypt because that would change Libgcrypt from LGPLv2+ to GPLv2+ which we do not want. - The patent exception for that algorithm may work for GPL code but needs a closer look by a lawyer. But GPL excludes its use anyway. Another question is whether this implementation is techincal okay to be included: > + libntruencrypt 1.0.0 A dependency on an external library implementing the agorithm is not going to work. We want the algorithm implementation in Libgcrypt proper. > --- a/autogen.sh > +++ b/autogen.sh > @@ -277,7 +277,7 @@ if [ "$myhost" = "amd64" ]; then > fi > fi > > - $tsdir/configure --enable-maintainer-mode ${SILENT} \ > + $tsdir/configure --enable-maintainer-mode --enable-ntru ${SILENT} \ Extra options need to go into autogen.rc. In any case only options required to build on a specific platform should be added to autogen.rc. > diff --git a/cipher/base64.c b/cipher/base64.c > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by You can't put GPL code into Libgcrypt which is under the LGPL. > +int base64_encode( unsigned char *dst, size_t *dlen, > + const unsigned char *src, size_t slen ) GNU coding standard please. > + GCRY_PK_USAGE_ENCR, // int use; No C++ comments please. > +{ > + fprintf (stderr,"NTRU compute keygrip function not required/implemented\n"); Libgcrypt has its own log functions - do not use printf. > + uint8_t *public_key; /* sized for EES401EP2 */ > + uint16_t public_key_len; Do not use these C99 types - we stick to C90. Use unsigned char or byte instead of uint8_t and our u16 type instead of uint16_t. > + pers_str = (uint8_t*)_gcry_random_bytes (32, GCRY_WEAK_RANDOM); There is no need to case a void * - we are not doing C++. > + public_key = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_); > + private_key = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_); > + > + memset(public_key, 0, _MAX_NTRU_BUF_SIZE_); > + memset(private_key, 0, _MAX_NTRU_BUF_SIZE_); Ditto. You also missed to check for errors. [...] Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From zzhang at securityinnovation.com Mon Sep 14 15:37:20 2015 From: zzhang at securityinnovation.com (Zhenfei Zhang) Date: Mon, 14 Sep 2015 09:37:20 -0400 Subject: [PATCH] Add NTRUEncrypt public key encryption algorithm Message-ID: Hi Opal, Werner and all, Thanks a lot for your feedback. I see there are three major concerns from you. Please let me try to address those. ++++++++++++++++++++++++++++++++++++++++++++++++++++ *On NTRU itself and post-quantum cryptography > it's not yet proven to be secure against quantum cryptanalysis >From theoretic point of view, the semantic security of NTRU can be reduced to a unique shortest vector problem (uSVP) over a specific ideal lattice, called NTRU ideal lattice. Unique shortest vector problem of general lattice is conjectured to be secure against quantum computer. However, to provide efficient crypto, one usually relies on a relaxed version of the problem: uSVP over ideal lattices. To date, there is no algorithm that solves uSVP over NTRU ideal lattice that is asymptotically faster than uSVP over general lattices. So it is safe to assume NTRU is quantum-safe. >From a practical point of view, NTRU has been proposed for almost 20 years. It survived many cryptanalsys. The current parameter that we are recommending has been stable since 2007, despite of the great improvement in lattice reduction algorithms in the recent years. Also, you cannot claim that a crypto scheme is secure against quantum cryptanalysis as there might be potential attacks/algorithms that people have not invented yet. People usually claim that either a cryptosystem is *proven* to be insecure/broken due to (quantum) attacks; or there is no known (quantum) attack against this cryptosystem, and thus the cryptosystem is *conjectured* to be secure. Also note that RSA and ECC are proven to be *insecure* against quantum cryptanalysis due to Shor's algorithm. > there is a problem with performance. NTRU is actually one of the fastest public key encryption scheme there is. NTRU with parameter eess401ep2 delivers 112 bits security and is 92 times faster than RSA-2048 at the same security level, according to the SUPERCOP benchmark: http://bench.cr.yp.to/supercop.html And with the increase of the security level, the advantage of NTRU gets larger. Also in 2009, NIST wrote a survey on post-quantum cryptography. http://www.nist.gov/customcf/get_pdf.cfm?pub_id=901595 According to them: ?Of the various lattice based cryptographic schemes that have been developed, the NTRU family of cryptographic algorithms appears to be the most practical... They are viable alternatives for both public key encryption and signatures that are not vulnerable to Shor?s Algorithm.? > What I read about the attacks doesn't make me happy either. On wiki (and almost on every academic paper of an encryption scheme), there is always a section discussing the state-of-art attacks on the cryptosystem. For example on RSA's wiki page, there are 7 different cryptanalytic methods, under the section "Security and practical considerations": https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29#Security_and_practical_considerations Through those attacks cryptographers grow their confidence in the system, and derive the most practical parameter set that is robust against those best known attacks. As for NTRU, there were two attacks on wiki page: a brute force attack and a lattice attack. The original NTRU design in 1996 has already considered those two attacks. We revised our parameter set in 2007 due to the hybrid attack of meet-in-the-middle attack (a variant of brute force attack) and the lattice attack from N. Howgrave-Graham, which combines the strength of both attacks on the wiki page. Since then, there are various paper claiming to attack NTRU, including the famous BKZ 2.0 from Y. Chen and P. Nguyen. Other paper has to assume different (very large) parameters for the attack to be successful. None of those is able to break our current parameter. We have wrote this preprint to show how every single parameter is derived from all those attacks https://eprint.iacr.org/2015/708 We actually put up a challenge this year awarding people who can break NTRU, where parameters are derived with the same principle, but with less strength (so that they may actually be breakable) https://www.securityinnovation.com/products/encryption-libraries/ntru-crypto/ntru-challenge/ Both Howgrave-Graham and Nguyen's group have participated and they were only able to solve some toy challenges. Those timing results for solving toy challenge also fall in our estimation. > algorithm is not a formal standard, as far as I can tell. In fact it is. NTRU is standardized by IEEE std 1363.1 and ANSI X9.98. NTRU is the only standardized post-quantum crypto to the best of my knowledge. > - Post quantum crypto is quite young and as of now mostly an academic > exercise. It is not clear when quantum computers will become available. The EU has expressed in their Horizon 2020 project a desire for systems to be "quantum-ready" by 2020. See the presentation from Tanja Lange: http://pqcrypto.eu.org/slides/20150403.pdf Google have optimistically predicted practical and powerful quantum computer could become available by the 2020 to 2025. See the following article: http://www.theplatform.net/2015/07/22/google-sees-long-expensive-road-ahead-for-quantum-computing/ NSA advised people to move away from ECC and prepare for quantum-safe crypto in their recent announcement: https://www.nsa.gov/ia/programs/suiteb_cryptography/ TLS working group and Tor community are also considering quantum-safe handshake approaches. I think those imply a valid demand of post quantum crypto in the industry. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ *On licensing There are two piece of codes in this patch that are under GPL. - The base64 code is under GPL. We will rewrite those code so it will be free to use. - The NTRU source code is under GPL. We can make patent exemptions for libgcrypt, if it is Okey. We have already made such an exemption for open source licenses, see https://github.com/NTRUOpenSourceProject/ntru-crypto/blob/master/FOSS%20Exception.md Please let me know if this kind of exemption for libgcrypt is good enough. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ *On implementation/code dependencies issue: NTRU source code has a small footprint. We are happy to remove the dependency of libntruencrypt, and include ntru source code within the libgrcrypt/cipher. code quality: This is my bad. Thanks again for the invaluable comments. I will address those comment in a short future. Cheers, Zhenfei On Wed, Sep 9, 2015 at 4:39 AM, Werner Koch wrote: > On Tue, 8 Sep 2015 20:45, zzhang at securityinnovation.com said: > > > Can I please ask what is the right approach to get this patch included > in a > > release? > > One question is whether we want to include this algorithm. I see > several reasons not to do this: > > - Post quantum crypto is quite young and as of now mostly an academic > exercise. However, inclusion in a general purpose crypto library > might be worth for algorithms which are likely going to be used in > some future. I can't decide on this and would for example ask Tanja > Lange for her opinion on NTRU. > > - The code implementing the algorithm is under the GPL and thus can't > be used by Libgcrypt because that would change Libgcrypt from LGPLv2+ > to GPLv2+ which we do not want. > > - The patent exception for that algorithm may work for GPL code but > needs a closer look by a lawyer. But GPL excludes its use anyway. > > > Another question is whether this implementation is techincal okay to be > included: > > > + libntruencrypt 1.0.0 > > A dependency on an external library implementing the agorithm is not > going to work. We want the algorithm implementation in Libgcrypt proper. > > > --- a/autogen.sh > > +++ b/autogen.sh > > @@ -277,7 +277,7 @@ if [ "$myhost" = "amd64" ]; then > > fi > > fi > > > > - $tsdir/configure --enable-maintainer-mode ${SILENT} \ > > + $tsdir/configure --enable-maintainer-mode --enable-ntru ${SILENT} \ > > Extra options need to go into autogen.rc. In any case only options > required to build on a specific platform should be added to autogen.rc. > > > diff --git a/cipher/base64.c b/cipher/base64.c > > > + * This program is free software; you can redistribute it and/or modify > > + * it under the terms of the GNU General Public License as published by > > You can't put GPL code into Libgcrypt which is under the LGPL. > > > +int base64_encode( unsigned char *dst, size_t *dlen, > > + const unsigned char *src, size_t slen ) > > GNU coding standard please. > > > + GCRY_PK_USAGE_ENCR, // int use; > > No C++ comments please. > > > +{ > > + fprintf (stderr,"NTRU compute keygrip function not > required/implemented\n"); > > Libgcrypt has its own log functions - do not use printf. > > > + uint8_t *public_key; > /* sized for EES401EP2 */ > > + uint16_t public_key_len; > > Do not use these C99 types - we stick to C90. Use unsigned char or byte > instead of uint8_t and our u16 type instead of uint16_t. > > > + pers_str = (uint8_t*)_gcry_random_bytes (32, GCRY_WEAK_RANDOM); > > There is no need to case a void * - we are not doing C++. > > > + public_key = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_); > > + private_key = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_); > > + > > + memset(public_key, 0, _MAX_NTRU_BUF_SIZE_); > > + memset(private_key, 0, _MAX_NTRU_BUF_SIZE_); > > Ditto. You also missed to check for errors. > > [...] > > > > Salam-Shalom, > > Werner > > > -- > Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From grothoff at gnunet.org Mon Sep 14 16:16:47 2015 From: grothoff at gnunet.org (Christian Grothoff) Date: Mon, 14 Sep 2015 16:16:47 +0200 Subject: [PATCH] Add NTRUEncrypt public key encryption algorithm In-Reply-To: References: Message-ID: <55F6D6CF.6060502@gnunet.org> Hi Werner, Hi Zhenfei, I wanted to chime in with a two independent comments: 1) The key question is not that it is not clear *when* quantum computers will become available, but *if* (ever). But, the secondary question is how expensive it would be to offer some reasonable additional protection *just in case*. The issue here is that the NSA is likely to store everything that they cannot decrypt today for the forseeable future (i.e. 30-100 years), and it might be really problematic for some people if we tell them something is fine and in 5, 10 or 30 years they all get rounded up and thrown into jail by some future regime with PQ crypto. Now, this hypothetical scenario doesn't justify crazy measures, but after quite extensive discussions here in Rennes, Jeff finally convinced me that with a scheme like NTRU, we could reinforce (!) the existing 3DH-Axolotl key exchange in GNUnet, so we get the best security of both schemes (modulo hypothetical remote-code execution 0-days in the crypto code). So we're actually strongly considering NTRU (and other PQ-schemes, but NTRU so far seems very good on the potential security improvement vs. performance loss/complexity front) as an additional (likely for a while optional) handshake within GNUnet (which so far uses primarily libgcrypt for crypto-primitives) for the future. No code yet, but plenty of thinking. 2) For including NTRU in libgcrypt, the GPL vs. LGPL and the patent issue are crucial. One of the issues that I had/have with NTRU is that the GPL-only exceptions to the patents will make it tricky for NTRU to become a widely used cryptographic primitive. While I like giving free software an edge, this also means that it is less likely to be the most widely used PQ system, and thus also not the most analyzed/understood. If the license were changed to LGPL and the patent clause broadened to cover LGPL libraries, that concern would disappear. (Note that GNUnet is GPL, so for GNUnet this does not matter too much.) In any case, if this integration with libgcrypt does eventually go ahead, I would strongly urge that the FSF also looks over the specific patent exemptions and that this is done in writing. My 2 cents Happy hacking! Christian On 09/14/2015 03:37 PM, Zhenfei Zhang wrote: > >> - Post quantum crypto is quite young and as of now mostly an academic >> exercise. > > It is not clear when quantum computers will become available. > > I think those imply a valid demand of post quantum crypto in the industry. > > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > *On licensing > > There are two piece of codes in this patch that are under GPL. > > - The base64 code is under GPL. We will rewrite those code so it will be > free to use. > > - The NTRU source code is under GPL. We can make patent exemptions for > libgcrypt, if it is Okey. We have already made such an exemption for > open source licenses, see > https://github.com/NTRUOpenSourceProject/ntru-crypto/blob/master/FOSS%20Exception.md > Please let me know if this kind of exemption for libgcrypt is good enough. > > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -------------- next part -------------- A non-text attachment was scrubbed... Name: 0xE29FC3CC.asc Type: application/pgp-keys Size: 15198 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From opalraava at riseup.net Tue Sep 15 23:39:18 2015 From: opalraava at riseup.net (Opal Raava) Date: Tue, 15 Sep 2015 23:39:18 +0200 Subject: [PATCH] Add NTRUEncrypt public key encryption algorithm In-Reply-To: <55F6D6CF.6060502@gnunet.org> References: <55F6D6CF.6060502@gnunet.org> Message-ID: <55F89006.7080100@riseup.net> Hi Zhenfei, all, On 09/14/2015 04:16 PM, Christian Grothoff wrote: > For including NTRU in libgcrypt, the GPL vs. LGPL and the > patent issue are crucial. One of the issues that I had/have > with NTRU is that the GPL-only exceptions to the patents > will make it tricky for NTRU to become a widely used > cryptographic primitive. While I like giving free software > an edge, this also means that it is less likely to be the > most widely used PQ system, and thus also not the most > analyzed/understood. If the license were changed to LGPL > and the patent clause broadened to cover LGPL libraries, > that concern would disappear. (Note that GNUnet is GPL, > so for GNUnet this does not matter too much.) > > In any case, if this integration with libgcrypt does eventually > go ahead, I would strongly urge that the FSF also looks over > the specific patent exemptions and that this is done in writing. Yes, I agree, the licencing issue seems to be the main obstacle with NTRU. The LGPL allows fpr the free use of the libgcrypt library in closed source commercial software. And that is incompatible with the licensing model and patents of Security Innovation. NTRU Patent Licensing - https://github.com/NTRUOpenSourceProject/ntru-crypto/blob/master/PATENTS.md FOSS License Exception - https://github.com/NTRUOpenSourceProject/ntru-crypto/blob/master/FOSS%20Exception.md I'm not a laywer, but it seems a bit odd to me that Security Innovation allows for the use of the NTRU encryption in LGPL, BSD and other such permissively licensed open source software (libraries), because these licences actually do allow for the use of the sofware in commercial products. It seems to me that NTRU can only be used with certain FOSS licences, and not others. Cheers, --Opal From simon at josefsson.org Mon Sep 21 09:22:13 2015 From: simon at josefsson.org (Simon Josefsson) Date: Mon, 21 Sep 2015 09:22:13 +0200 Subject: [PATCH] Add NTRUEncrypt public key encryption algorithm In-Reply-To: <55F6D6CF.6060502@gnunet.org> (Christian Grothoff's message of "Mon, 14 Sep 2015 16:16:47 +0200") References: <55F6D6CF.6060502@gnunet.org> Message-ID: <87r3ls2q56.fsf@latte.josefsson.org> Christian Grothoff writes: > So we're actually strongly considering NTRU (and other PQ-schemes, > but NTRU so far seems very good on the potential security > improvement vs. performance loss/complexity front) as an > additional (likely for a while optional) handshake within > GNUnet (which so far uses primarily libgcrypt for > crypto-primitives) for the future. No code yet, but plenty of > thinking. You want to look at XMSS, SPHINCS and some of the other modern PQ-schemes: https://tools.ietf.org/html/draft-irtf-cfrg-xmss-hash-based-signatures-01 http://sphincs.cr.yp.to/ /Simon -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 472 bytes Desc: not available URL: From burdges at gnunet.org Mon Sep 21 11:41:40 2015 From: burdges at gnunet.org (Jeff Burdges) Date: Mon, 21 Sep 2015 11:41:40 +0200 Subject: [PATCH] Add NTRUEncrypt public key encryption algorithm In-Reply-To: <87r3ls2q56.fsf@latte.josefsson.org> References: <55F6D6CF.6060502@gnunet.org> <87r3ls2q56.fsf@latte.josefsson.org> Message-ID: <1442828500.3895.18.camel@gnunet.org> SPHINCS is ideal for signing software packages for distribution, but today protocols should usually provide deniability, making signatures unworkable. I haven't looked at XMSS yet, but sounds quite similar to SPHINCS. There is a way to gain PQ security from classical primitives for encryption though : Use Axolotl with very long-running sessions everywhere. And ideally introduce side key material so that breaking one ratchet requires breaking many. I'm interested in writing a paper on exactly this, but it requires building a mixnet, so it's requires doing a lot of different things right. On Mon, 2015-09-21 at 09:22 +0200, Simon Josefsson wrote: > Christian Grothoff writes: > > > So we're actually strongly considering NTRU (and other PQ-schemes, > > but NTRU so far seems very good on the potential security > > improvement vs. performance loss/complexity front) as an > > additional (likely for a while optional) handshake within > > GNUnet (which so far uses primarily libgcrypt for > > crypto-primitives) for the future. No code yet, but plenty of > > thinking. > > You want to look at XMSS, SPHINCS and some of the other modern > PQ-schemes: > > https://tools.ietf.org/html/draft-irtf-cfrg-xmss-hash-based-signatures-01 > http://sphincs.cr.yp.to/ > > /Simon -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: This is a digitally signed message part URL: From umut.tezduyar at axis.com Tue Sep 22 09:08:25 2015 From: umut.tezduyar at axis.com (Umut Tezduyar Lindskog) Date: Tue, 22 Sep 2015 09:08:25 +0200 Subject: pkg-config files for libgcrypt Message-ID: <0F1E81CA-9402-425C-8C44-ABB07DF8EC08@axis.com> Hi, Are you guys willing to accept a patch to generate pkg-config files? This seems to be a rejected idea in the past, https://lists.gnupg.org/pipermail/gcrypt-devel/2007-February/001109.html. I was wondering if the reasons are still valid or not. Umut From wk at gnupg.org Tue Sep 22 21:31:41 2015 From: wk at gnupg.org (Werner Koch) Date: Tue, 22 Sep 2015 21:31:41 +0200 Subject: pkg-config files for libgcrypt In-Reply-To: <0F1E81CA-9402-425C-8C44-ABB07DF8EC08@axis.com> (Umut Tezduyar Lindskog's message of "Tue, 22 Sep 2015 09:08:25 +0200") References: <0F1E81CA-9402-425C-8C44-ABB07DF8EC08@axis.com> Message-ID: <87r3lql082.fsf@vigenere.g10code.de> On Tue, 22 Sep 2015 09:08, umut.tezduyar at axis.com said: > Are you guys willing to accept a patch to generate pkg-config files? NO! Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From ben.wiederhake at gmail.com Fri Sep 25 16:31:14 2015 From: ben.wiederhake at gmail.com (Ben Wiederhake) Date: Fri, 25 Sep 2015 16:31:14 +0200 Subject: [PATCH] Add missing entry in gitignore. Message-ID: <56055AB2.8020806@gmail.com> * .gitignore: Add generated 'hashtest-256g' file. -- When doing a fresh checkout followed be the recommended ./autogen.sh and ./configure, git reports the directory as "not clean" due to the "new" file tests/hashtest-256g generated by configure. Signed-off-by: Ben Wiederhake --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 3929e4d..b961614 100644 --- a/.gitignore +++ b/.gitignore @@ -72,6 +72,7 @@ tests/benchmark tests/fips186-dsa tests/fipsdrv tests/gchash +tests/hashtest-256g tests/hmac tests/keygen tests/keygrip -- 2.5.1 From ametzler at bebt.de Sun Sep 27 08:42:34 2015 From: ametzler at bebt.de (Andreas Metzler) Date: Sun, 27 Sep 2015 08:42:34 +0200 Subject: 1.6.x testsuite error on Bigendian with gcc5 / gcrypt patches applied in RedHat Fedora Message-ID: <20150927064234.GB2682@downhill.g.la> Hello, 1.6.4 has a testsuite error withh gcc5 on bigendian (ppc64): ------------- selftest for CFB failed - see syslog for details pass 0, algo 4, mode 1, gcry_cipher_setkey failed: Selftest failed pass 0, algo 4, mode 2, gcry_cipher_setkey failed: Selftest failed pass 0, algo 4, mode 5, gcry_cipher_setkey failed: Selftest failed pass 0, algo 4, mode 3, gcry_cipher_setkey failed: Selftest failed pass 0, algo 4, mode 3, gcry_cipher_setkey failed: Selftest failed pass 0, algo 4, mode 6, gcry_cipher_setkey failed: Selftest failed FAIL: basic [...] selftest for CFB failed - see syslog for details benchmark: error setting key for mac algorithm `CMAC_BLOWFISH': Selftest failed FAIL: benchmark selftest for CFB failed - see syslog for details bench-slope: error setting key for mac `CMAC_BLOWFISH' --------------- This is RedHat bug https://bugzilla.redhat.com/show_bug.cgi?id=1201219 [libgcrypt is violating C aliasing rules in buf_xor_n_copy (cipher/bufhelp.h)] and Fedora is working around it by disabling strict aliasing for these files (libgcrypt-1.6.3-aliasing.patch). --------------------------------------------- Besides this patch Fedora is applying a bunch of other patches , have these been forwarded to you, yet? * 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. (We replace it with RH approved ECC in Source4-5) # make FIPS hmac compatible with fipscheck - non upstreamable # update on soname bump Patch2: libgcrypt-1.6.2-use-fipscheck.patch # fix tests in the FIPS mode, fix the FIPS-186-3 DSA keygen Patch5: libgcrypt-1.6.1-tests.patch # add configurable source of RNG seed and seed by default # from /dev/urandom in the FIPS mode Patch6: libgcrypt-1.6.1-fips-cfgrandom.patch # update the CAVS tests Patch7: libgcrypt-1.6.2-fips-cavs.patch # fix for memory leaks an other errors found by Coverity scan Patch9: libgcrypt-1.6.1-leak.patch # use poll instead of select when gathering randomness Patch11: libgcrypt-1.6.1-use-poll.patch # slight optimalization of mpicoder.c to silence Valgrind (#968288) Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch # fix tests to work with approved ECC Patch14: libgcrypt-1.6.1-ecc-test-fix.patch # Replace the FIPS RNG with DRBG Patch15: libgcrypt-1.6.2-drbg.patch # Run the FIPS mode initialization in the shared library constructor Patch18: libgcrypt-1.6.2-fips-ctor.patch # Make it possible to run the test suite in the FIPS mode Patch19: libgcrypt-1.6.2-fips-test.patch # Make the FIPS RSA keygen to be FIPS 186-4 compliant Patch20: libgcrypt-1.6.3-rsa-fips-keygen.patch # update the selftests for new FIPS requirements Patch22: libgcrypt-1.6.2-fips-reqs.patch # do not use strict aliasing for bufhelp functions Patch23: libgcrypt-1.6.3-aliasing.patch # use only urandom if /dev/random cannot be opened Patch24: libgcrypt-1.6.3-urandom-only.patch Thanks, cu Andreas -- `What a good friend you are to him, Dr. Maturin. His other friends are so grateful to you.' `I sew his ears on from time to time, sure' From ben.wiederhake at gmail.com Mon Sep 28 17:14:26 2015 From: ben.wiederhake at gmail.com (Ben Wiederhake) Date: Mon, 28 Sep 2015 17:14:26 +0200 Subject: Determine interest: AES with IGE mode? Message-ID: <56095952.7000504@gmail.com> Hello, OpenSSL offers a cipher mode called "IGE" (Infinite Garble Extension), mainly for AES encryption. Barely anyone uses it, but those who do (e.g. implementors of the Telegram Protocol, i.e., libtgl) usually have no other choice. AES with IGE mode is not available in libgcrypt (and from a lot of other crypto libraries), so libtgl is currently locked-in to OpenSSL due to that. Personally, I now have the choice between implementing it only for libtgl, or implementing it for libgcrypt. IGE mode is well explained in the (non-OpenSSL licensed) documentation from OpenSSL about that mode [1], and a bit more mathematically detailed in the original paper [2] (especially page 16), so: - it is easily possible to implement it in not too many lines of code. - there are definitely no conflicts with the GPL here, as there is no OpenSSL-licensed resource involved at all. I'd love to see AES-IGE (specifically AES256-IGE) available for everyone, not just libtgl. But before I dig into libgcrypt and understand where I have to start adding the code, I'd like to know: Is there any interest in having AES-IGE in libgcrypt? As a kind of sales pitch, here's some arguments: - You benefit: All other people who try to get away from OpenSSL now have one less obstacle in their way. - We benefit: Instead of having a few non-crypto-savvy people work on a security-critical component, we could use a dedicated library; just like with other important things like SHA1, RSA etc. So, what do you think? With regards, Ben Wiederhake [1] http://www.links.org/files/openssl-ige.pdf [2] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ige/ige-spec.pdf From ben.wiederhake at gmail.com Mon Sep 28 23:30:42 2015 From: ben.wiederhake at gmail.com (Ben Wiederhake) Date: Mon, 28 Sep 2015 23:30:42 +0200 Subject: Determine interest: AES with IGE mode? In-Reply-To: <56095952.7000504@gmail.com> References: <56095952.7000504@gmail.com> Message-ID: <5609B182.7010708@gmail.com> Hello, Am 28.09.2015 um 17:14 schrieb Ben Wiederhake: > Personally, I now have the choice between implementing it only for > libtgl, or implementing it for libgcrypt. I have finished a public domain implementation that we will use for libtgl: https://gist.github.com/BenWiederhake/3c4f5923928be8a34da6 > IGE mode is well explained in the (non-OpenSSL licensed) documentation > from OpenSSL about that mode [1], and a bit more mathematically detailed > in the original paper [2] (especially page 16), so: > - it is easily possible to implement it in not too many lines of code. Please notice that most code of the gist file is for testing. Only roughly 80 SLOC contribute to the actual functionality: 'do_ige_{en,de}crypt' and 'exposed_aes_ige_encrypt' > - there are definitely no conflicts with the GPL here, as there is no > OpenSSL-licensed resource involved at all. Just wanted to emphasize that. > Is there any interest in having AES-IGE in libgcrypt? Also that. With regards, Ben Wiederhake From ben.wiederhake at gmail.com Tue Sep 29 15:25:17 2015 From: ben.wiederhake at gmail.com (Ben Wiederhake) Date: Tue, 29 Sep 2015 15:25:17 +0200 Subject: Typo in documentation Message-ID: <560A913D.7020104@gmail.com> Hello, Section 2.4, "Initializing the library", can be found at: https://gnupg.org/documentation/manuals/gcrypt/Initializing-the-library.html#Initializing-the-library The very first code example contains the misspelled word "intialized", instead of "in**i**tialized". I'm not really sure where else to report that, so I thought I'd post it here. With regards, Ben Wiederhake From ben.wiederhake at gmail.com Tue Sep 29 17:31:58 2015 From: ben.wiederhake at gmail.com (Ben Wiederhake) Date: Tue, 29 Sep 2015 17:31:58 +0200 Subject: Determine interest: AES with IGE mode? In-Reply-To: <20150929133828.GA23454@pi.ip.fi> References: <56095952.7000504@gmail.com> <5609B182.7010708@gmail.com> <20150929133828.GA23454@pi.ip.fi> Message-ID: <560AAEEE.3060607@gmail.com> Hello, >> Personally, I now have the choice between implementing it only for >> libtgl, or implementing it for libgcrypt. > > While this is very interesting it does lack some use cases, like, why would > someone want to use this instead of CBC. No idea. I don't really see the point of IGE. I'm not a crypto-specialist or anything. I don't propose this in order to have a "new fancy whatever" in libgcrypt, but in order to fill-in a hole. libgcrypt is a near-drop-in replacement for OpenSSL, but AES_IGE is missing. > Also, some notes on your PDF dissertation: I didn't write that dissertation, and think that it is confusing the topics of authentication and encryption, and handles both of them half-heartedly; instead of properly handling them separately with well-known, pre-existing cryptographic building blocks. > - You claim it corrupts plaintext on any error in ciphertext, can you provide > some proof over that. I didn't write that dissertation, and therefore don't claim it. However, there is a good argument for this claim: The old ciphertext is part of the IV for the next block, thus affecting the encryption of *everything* after it in the stream. > - The IGE mode of operation could be explained better, at the moment it's > quite terse. Same goes for BIGE. Yup. But people out there have to implement algorithms and protocols that use AES_IGE. We're restricted to GPL-compatible software, and there is literally nothing out there providing AES_IGE while being GPL-compatible. I want to change that, by pushing AES_IGE into libgcrypt. > - "Note that the second part of this chaining sequence appears to be > incorrectly specified in the original paper.", can you elaborate on > this claim? If one implements the algorithm as-is from the [1] paper, the results differ from the results given as test vectors. If I change the assumed order (see my gist [2]), everything works out. I have generated additional test vectors (see my gist [2]) using OpenSSL, always with the same result. > - is there any research done on this algorithm other than that one paper > wrote by Donescu and Gligor in 2000? Good question. Just like I already said in my first mail on this topic: "Barely anyone uses [IGE], but those who do (e.g. implementors of the Telegram Protocol, i.e., libtgl) usually have no other choice." If there are any concrete concerns about security, it may be worth to put it into libgcrypt as deprecated. Then: - People who desparately need AES_IGE (like us) have access to it. - People who don't really require it can see that it is deprecated. With regards, Ben Wiederhake [1]: http://www.links.org/files/openssl-ige.pdf [2]: https://gist.github.com/BenWiederhake/3c4f5923928be8a34da6 From cmouse at desteem.org Tue Sep 29 17:25:15 2015 From: cmouse at desteem.org (Aki Tuomi) Date: Tue, 29 Sep 2015 18:25:15 +0300 Subject: Determine interest: AES with IGE mode? In-Reply-To: <5609B182.7010708@gmail.com> References: <56095952.7000504@gmail.com> <5609B182.7010708@gmail.com> Message-ID: <20150929152515.GB26828@pi.ip.fi> On Mon, Sep 28, 2015 at 11:30:42PM +0200, Ben Wiederhake wrote: > Hello, > > Am 28.09.2015 um 17:14 schrieb Ben Wiederhake: > >Personally, I now have the choice between implementing it only for > >libtgl, or implementing it for libgcrypt. Hi! While this is very interesting it does lack some use cases, like, why would someone want to use this instead of CBC. Also, some notes on your PDF dissertation: - You claim it corrupts plaintext on any error in ciphertext, can you provide some proof over that. - The IGE mode of operation could be explained better, at the moment it's quite terse. Same goes for BIGE. - "Note that the second part of this chaining sequence appears to be incorrectly specified in the original paper.", can you elaborate on this claim? - is there any research done on this algorithm other than that one paper wrote by Donescu and Gligor in 2000? Regards, Aki Tuomi From desteem.org at pi.ip.fi Tue Sep 29 17:24:52 2015 From: desteem.org at pi.ip.fi (Aki Tuomi) Date: Tue, 29 Sep 2015 18:24:52 +0300 Subject: Determine interest: AES with IGE mode? In-Reply-To: <5609B182.7010708@gmail.com> References: <56095952.7000504@gmail.com> <5609B182.7010708@gmail.com> Message-ID: <20150929152451.GA26828@pi.ip.fi> On Mon, Sep 28, 2015 at 11:30:42PM +0200, Ben Wiederhake wrote: > Hello, > > Am 28.09.2015 um 17:14 schrieb Ben Wiederhake: > >Personally, I now have the choice between implementing it only for > >libtgl, or implementing it for libgcrypt. Hi! While this is very interesting it does lack some use cases, like, why would someone want to use this instead of CBC. Also, some notes on your PDF dissertation: - You claim it corrupts plaintext on any error in ciphertext, can you provide some proof over that. - The IGE mode of operation could be explained better, at the moment it's quite terse. Same goes for BIGE. - "Note that the second part of this chaining sequence appears to be incorrectly specified in the original paper.", can you elaborate on this claim? - is there any research done on this algorithm other than that one paper wrote by Donescu and Gligor in 2000? Regards,