From smueller at chronox.de Sun Mar 2 14:09:58 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 02 Mar 2014 14:09:58 +0100 Subject: [PATCH 6/8] DRBG specific gcry_control requests In-Reply-To: <2379807.Y4OhqCbdOM@myon.chronox.de> References: <2379807.Y4OhqCbdOM@myon.chronox.de> Message-ID: <2110806.hmATrUfRCn@myon.chronox.de> gcry_control GCRYCTL_DRBG_REINIT ================================ This control request re-initializes the DRBG completely, i.e. thr entire state of the DRBG is zeroized (with two exceptions listed in GCRYCTL_DRBG_SET_ENTROPY). The control request takes the following values which influences how the DRBG is re-initialized: * __u64 flags: This variable specifies the DRBG type to be used for the next initialization. If set to 0, the previous DRBG type is used for the initialization. The DRBG type is an OR of the mandatory flags of the requested DRBG strength and DRBG cipher type. Optionally, the prediction resistance flag can be ORed into the flags variable. For example: - CTR-DRBG with AES-128 without prediction resistance: DRBG_CTRAES128 - HMAC-DRBG with SHA-512 with prediction resistance: DRBG_HMACSHA512 | DRBG_PREDICTION_RESIST * unsigned char *pers: personalization string to be used for initialization. * size_t perslen: Length of personalization string. If set to 0, no personalization string is used for initialization. The variable of flags is independent from the pers/perslen variables. If flags is set to 0 and perslen is set to 0, the current DRBG type is completely reset without using a personalization string. gcry_control GCRYCTL_DRBG_SET_ENTROPY ===================================== This control request sets a predefined "entropy" value. When set, the DRBG does not seed itself from a known seed source, but using that known value. This "entropy" value is not reset even during an initialization! This control request is ONLY intended for testing, especially to implement the FIPS 140-2 CAVS testing. DO NEVER USE IT DURING REGULAR OPERATION. The control request takes the following values: * unsigned char *entropy: string to be used as "entropy" (i.e. the replacement of the data read from the seed source). If this variable is set to NULL, the regular seed source is again used when the DRBG reseeds again. * size_t entropylen: Length of entropy string. Signed-off-by: Stephan Mueller --- src/global.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/global.c b/src/global.c index 4e8df86..3e6f97d 100644 --- a/src/global.c +++ b/src/global.c @@ -671,6 +671,23 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) rc = GPG_ERR_NOT_IMPLEMENTED; break; + case GCRYCTL_DRBG_REINIT: + { + __u64 flags = va_arg (arg_ptr, __u64); + unsigned char *pers = va_arg (arg_ptr, unsigned char *); + size_t perslen = va_arg (arg_ptr, size_t); + rc = _gcry_drbg_reinit(flags, pers, perslen); + } + break; + + case GCRYCTL_DRBG_SET_ENTROPY: + { + unsigned char *entropy = va_arg (arg_ptr, unsigned char *); + size_t entropylen = va_arg (arg_ptr, size_t); + rc = _gcry_drbg_set_entropy(entropy, entropylen); + } + break; + default: _gcry_set_preferred_rng_type (0); rc = GPG_ERR_INV_OP; -- 1.8.5.3 From smueller at chronox.de Sun Mar 2 14:11:05 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 02 Mar 2014 14:11:05 +0100 Subject: [PATCH 8/8] User interface to DRBG In-Reply-To: <2379807.Y4OhqCbdOM@myon.chronox.de> References: <2379807.Y4OhqCbdOM@myon.chronox.de> Message-ID: <1988017.bqRcFlgnWj@myon.chronox.de> DRBG Usage ========== The SP 800-90A DRBG allows the user to specify a personalization string for initialization as well as an additional information string for each random number request. The following code fragments show how a caller uses the kernel crypto API to use the full functionality of the DRBG. Usage without any additional data --------------------------------- gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); Usage with personalization string during initialization ------------------------------------------------------- char personalization = "some-string"; // The reset completely re-initializes the DRBG with the provided // personalization string without changing the DRBG type ret = gcry_control(GCRYCTL_DRBG_REINIT, 0, personalization, strlen(personalization)); gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); Usage with additional information string during random number request --------------------------------------------------------------------- char addtl = "some-string"; // The following call is a wrapper to gcry_randomize() and returns // the same error codes. gcry_randomize_drbg(outbuf, OUTLEN, GCRY_STRONG_RANDOM, addtl, strlen(addtl)); Usage with personalization and additional information strings ------------------------------------------------------------- Just mix both scenarios above. Switch the DRBG type to some other type --------------------------------------- // Switch to CTR DRBG AES-128 without prediction resistance ret = gcry_control(GCRYCTL_DRBG_REINIT, DRBG_CTRAES128, NULL, 0); gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); Signed-off-by: Stephan Mueller --- src/gcrypt.h.in | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index c84a3f7..b62a832 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -329,7 +329,9 @@ enum gcry_ctl_cmds GCRYCTL_SET_CCM_LENGTHS = 69, GCRYCTL_CLOSE_RANDOM_DEVICE = 70, GCRYCTL_INACTIVATE_FIPS_FLAG = 71, - GCRYCTL_REACTIVATE_FIPS_FLAG = 72 + GCRYCTL_REACTIVATE_FIPS_FLAG = 72, + GCRYCTL_DRBG_REINIT = 73, + GCRYCTL_DRBG_SET_ENTROPY = 74, }; /* Perform various operations defined by CMD. */ @@ -1673,6 +1675,64 @@ int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE; #define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) +/* DRBG input data structure for DRBG generate with additional information + * string */ +struct drbg_gen +{ + unsigned char *outbuf; /* output buffer for random numbers */ + unsigned int outlen; /* size of output buffer */ + unsigned char *addtl_input; /* input buffer for + * additional information string */ + unsigned int addtllen; /* length of addtl_input */ +}; + +/* this is a wrapper function for users of libgcrypt */ +static inline void gcry_randomize_drbg(void *outbuf, size_t outlen, + enum gcry_random_level level, + unsigned char *addtl_input, + size_t addtllen) +{ + struct drbg_gen genbuf; + genbuf.outbuf = outbuf; + genbuf.outlen = outlen; + genbuf.addtl_input = addtl_input; + genbuf.addtllen = addtllen; + gcry_randomize(&genbuf, 0, level); +} + +/* DRBG type definitions */ +/* strength requests */ +#define DRBG_USERFLAG_MASK ((1UL<<40) - 1) +#define DRBG_PREDICTION_RESIST 1UL<<36 +/* cipher type */ +#define DRBG_CIPHER_MASK ((1UL<<32) - 1) + +#define DRBG_CTR_MASK ((1<<9) - 1) +#define DRBG_CTRAES128 1<<0 +#define DRBG_CTRAES192 1<<1 +#define DRBG_CTRAES256 1<<2 +#define DRBG_CTRSERPENT128 1<<3 +#define DRBG_CTRSERPENT192 1<<4 +#define DRBG_CTRSERPENT256 1<<5 +#define DRBG_CTRTWOFISH128 1<<6 +#define DRBG_CTRTWOFISH192 1<<7 +#define DRBG_CTRTWOFISH256 1<<8 + +#define DRBG_HASH_MASK ((1<<14) - (1<<9)) +#define DRBG_HASHSHA1 1<<9 +#define DRBG_HASHSHA224 1<<10 +#define DRBG_HASHSHA256 1<<11 +#define DRBG_HASHSHA384 1<<12 +#define DRBG_HASHSHA512 1<<13 + +#define DRBG_HMAC_MASK ((1<<19) - (1<<14)) +#define DRBG_HMACSHA1 1<<14 +#define DRBG_HMACSHA224 1<<15 +#define DRBG_HMACSHA256 1<<16 +#define DRBG_HMACSHA384 1<<17 +#define DRBG_HMACSHA512 1<<18 + + #if 0 /* (Keep Emacsens' auto-indent happy.) */ { #endif -- 1.8.5.3 From smueller at chronox.de Sun Mar 2 14:05:46 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 02 Mar 2014 14:05:46 +0100 Subject: [PATCH 0/8] SP800-90A DRBG Message-ID: <2379807.Y4OhqCbdOM@myon.chronox.de> Hi, the following set of patches against the current GIT development tree of libgcrypt implements the SP800-90A DRBG and integrates it with libgcrypt. Stephan Mueller (8): SP800-90A Deterministic Random Bit Generator Compile DRBG Function definitions of interfaces for random.c Invoke DRBG from common libgcrypt RNG code Function definitions for gcry_control callbacks DRBG specific gcry_control requests Include OS types.h for __u64 definition User interface to DRBG random/Makefile.am | 1 + random/drbg.c | 3049 ++++++++++++++++++++++++++++++++++++++++++++++++ random/rand-internal.h | 9 + random/random.c | 23 +- random/random.h | 6 +- src/gcrypt.h.in | 62 +- src/global.c | 17 + src/types.h | 1 + 8 files changed, 3156 insertions(+), 12 deletions(-) create mode 100644 random/drbg.c -- 1.8.5.3 From smueller at chronox.de Sun Mar 2 14:10:38 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 02 Mar 2014 14:10:38 +0100 Subject: [PATCH 7/8] Include OS types.h for __u64 definition In-Reply-To: <2379807.Y4OhqCbdOM@myon.chronox.de> References: <2379807.Y4OhqCbdOM@myon.chronox.de> Message-ID: <18840093.utiSQ0YYCI@myon.chronox.de> Signed-off-by: Stephan Mueller --- src/types.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types.h b/src/types.h index ee0a62b..c95c5af 100644 --- a/src/types.h +++ b/src/types.h @@ -39,6 +39,7 @@ #include +#include #ifndef HAVE_BYTE_TYPEDEF -- 1.8.5.3 From smueller at chronox.de Sun Mar 2 14:09:22 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 02 Mar 2014 14:09:22 +0100 Subject: [PATCH 5/8] Function definitions for gcry_control callbacks In-Reply-To: <2379807.Y4OhqCbdOM@myon.chronox.de> References: <2379807.Y4OhqCbdOM@myon.chronox.de> Message-ID: <2558104.scXtTzmHSF@myon.chronox.de> The function definitions implemented in drbg.c which are used for gcry_control. Signed-off-by: Stephan Mueller --- random/random.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/random/random.h b/random/random.h index 2bc8cab..092d090 100644 --- a/random/random.h +++ b/random/random.h @@ -54,7 +54,11 @@ gcry_err_code_t _gcry_random_run_external_test (void *context, char *buffer, size_t buflen); void _gcry_random_deinit_external_test (void *context); - +/*-- drbg.c --*/ +gpg_err_code_t _gcry_drbg_reinit(__u64 flags, + unsigned char *pers, size_t perslen); +gpg_err_code_t _gcry_drbg_set_entropy(unsigned char *entropy, + size_t entropylen); /*-- rndegd.c --*/ gpg_error_t _gcry_rndegd_set_socket_name (const char *name); -- 1.8.5.3 From smueller at chronox.de Sun Mar 2 14:08:44 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 02 Mar 2014 14:08:44 +0100 Subject: [PATCH 4/8] Invoke DRBG from common libgcrypt RNG code In-Reply-To: <2379807.Y4OhqCbdOM@myon.chronox.de> References: <2379807.Y4OhqCbdOM@myon.chronox.de> Message-ID: <4402157.PEhIvxvS4d@myon.chronox.de> Integrate the DRBG invocation with the common libgcrypt RNG code. This integration replaces the old ANSI X9.31 RNG invocation. As the ANSI X9.31 shall only be invoked in FIPS mode and it is sunset at the end of 2014 for FIPS purposes, a complete replacement with the DRBG is considered appropriate. The DRBG is FIPS approved deterministic random number generator for the forseeable future. Signed-off-by: Stephan Mueller --- random/random.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/random/random.c b/random/random.c index 41d4cb3..e5c7cde 100644 --- a/random/random.c +++ b/random/random.c @@ -140,11 +140,11 @@ void _gcry_random_initialize (int full) { if (fips_mode ()) - _gcry_rngfips_initialize (full); + _gcry_drbg_init(full); else if (rng_types.standard) _gcry_rngcsprng_initialize (full); else if (rng_types.fips) - _gcry_rngfips_initialize (full); + _gcry_drbg_init(full); else if (rng_types.system) _gcry_rngsystem_initialize (full); else @@ -161,11 +161,11 @@ _gcry_random_close_fds (void) the entropy gatherer. */ if (fips_mode ()) - _gcry_rngfips_close_fds (); + _gcry_drbg_close_fds (); else if (rng_types.standard) _gcry_rngcsprng_close_fds (); else if (rng_types.fips) - _gcry_rngfips_close_fds (); + _gcry_drbg_close_fds (); else if (rng_types.system) _gcry_rngsystem_close_fds (); else @@ -199,7 +199,7 @@ void _gcry_random_dump_stats (void) { if (fips_mode ()) - _gcry_rngfips_dump_stats (); + _gcry_drbg_dump_stats (); else _gcry_rngcsprng_dump_stats (); } @@ -258,7 +258,7 @@ int _gcry_random_is_faked (void) { if (fips_mode ()) - return _gcry_rngfips_is_faked (); + return _gcry_drbg_is_faked (); else return _gcry_rngcsprng_is_faked (); } @@ -288,11 +288,11 @@ static void do_randomize (void *buffer, size_t length, enum gcry_random_level level) { if (fips_mode ()) - _gcry_rngfips_randomize (buffer, length, level); + _gcry_drbg_randomize (buffer, length, level); else if (rng_types.standard) _gcry_rngcsprng_randomize (buffer, length, level); else if (rng_types.fips) - _gcry_rngfips_randomize (buffer, length, level); + _gcry_drbg_randomize (buffer, length, level); else if (rng_types.system) _gcry_rngsystem_randomize (buffer, length, level); else /* default */ @@ -424,7 +424,7 @@ _gcry_create_nonce (void *buffer, size_t length) nonce generator which is seeded by the RNG actual in use. */ if (fips_mode ()) { - _gcry_rngfips_create_nonce (buffer, length); + _gcry_drbg_randomize (buffer, length, GCRY_WEAK_RANDOM); return; } @@ -501,7 +501,7 @@ gpg_error_t _gcry_random_selftest (selftest_report_func_t report) { if (fips_mode ()) - return _gcry_rngfips_selftest (report); + return _gcry_drbg_selftest (report); else return 0; /* No selftests yet. */ } @@ -517,6 +517,7 @@ _gcry_random_init_external_test (void **r_context, const void *seed, size_t seedlen, const void *dt, size_t dtlen) { + return GPG_ERR_NOT_SUPPORTED; (void)flags; if (fips_mode ()) return _gcry_rngfips_init_external_test (r_context, flags, key, keylen, @@ -531,6 +532,7 @@ _gcry_random_init_external_test (void **r_context, gcry_err_code_t _gcry_random_run_external_test (void *context, char *buffer, size_t buflen) { + return GPG_ERR_NOT_SUPPORTED; if (fips_mode ()) return _gcry_rngfips_run_external_test (context, buffer, buflen); else @@ -541,6 +543,7 @@ _gcry_random_run_external_test (void *context, char *buffer, size_t buflen) void _gcry_random_deinit_external_test (void *context) { + return; if (fips_mode ()) _gcry_rngfips_deinit_external_test (context); } -- 1.8.5.3 From smueller at chronox.de Sun Mar 2 14:07:56 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 02 Mar 2014 14:07:56 +0100 Subject: [PATCH 3/8] Function definitions of interfaces for random.c In-Reply-To: <2379807.Y4OhqCbdOM@myon.chronox.de> References: <2379807.Y4OhqCbdOM@myon.chronox.de> Message-ID: <1912076.giIGJUqmBf@myon.chronox.de> Specify the function definitions to be integrated into the common libgcrypt RNG code. Signed-off-by: Stephan Mueller --- random/rand-internal.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/random/rand-internal.h b/random/rand-internal.h index 79b23ac..d4c9013 100644 --- a/random/rand-internal.h +++ b/random/rand-internal.h @@ -88,6 +88,15 @@ gcry_err_code_t _gcry_rngfips_run_external_test (void *context, char *buffer, size_t buflen); void _gcry_rngfips_deinit_external_test (void *context); +/* drbg-gcry.h */ +void _gcry_drbg_init(int full); +void _gcry_drbg_close_fds(void); +void _gcry_drbg_dump_stats(void); +int _gcry_drbg_is_faked (void); +gcry_error_t _gcry_drng_add_bytes (const void *buf, size_t buflen, int quality); +void _gcry_drbg_randomize (void *buffer, size_t length, + enum gcry_random_level level); +gcry_error_t _gcry_rngfips_selftest (selftest_report_func_t report); /*-- random-system.c --*/ void _gcry_rngsystem_initialize (int full); -- 1.8.5.3 From smueller at chronox.de Sun Mar 2 14:07:09 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 02 Mar 2014 14:07:09 +0100 Subject: [PATCH 2/8] Compile DRBG In-Reply-To: <2379807.Y4OhqCbdOM@myon.chronox.de> References: <2379807.Y4OhqCbdOM@myon.chronox.de> Message-ID: <33190315.Le2y3JKmCc@myon.chronox.de> Add the drbg.c file to the Makefile. Signed-off-by: Stephan Mueller --- random/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/random/Makefile.am b/random/Makefile.am index c9d587a..e073fa4 100644 --- a/random/Makefile.am +++ b/random/Makefile.am @@ -35,6 +35,7 @@ random.c random.h \ rand-internal.h \ random-csprng.c \ random-fips.c \ +drbg.c \ random-system.c \ rndhw.c -- 1.8.5.3 From smueller at chronox.de Sun Mar 2 14:26:05 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 02 Mar 2014 14:26:05 +0100 Subject: [PATCH 0/8] SP800-90A DRBG In-Reply-To: <2379807.Y4OhqCbdOM@myon.chronox.de> References: <2379807.Y4OhqCbdOM@myon.chronox.de> Message-ID: <10726702.SR5deMHdoA@myon.chronox.de> Am Sonntag, 2. M?rz 2014, 14:05:46 schrieb Stephan Mueller: Hi, > Hi, > > the following set of patches against the current GIT development tree of > libgcrypt implements the SP800-90A DRBG and integrates it with libgcrypt. A test of various aspects of the DRBG, including a CAVS testing framework is provided in [1] with the file libgcrypt/test/drbg_test.c [1] http://www.chronox.de/drbg/drbg-20140302.tar.bz2 Ciao Stephan -- | Cui bono? | From smueller at chronox.de Mon Mar 3 16:23:16 2014 From: smueller at chronox.de (Stephan Mueller) Date: Mon, 03 Mar 2014 16:23:16 +0100 Subject: [PATCH 1/8] SP800-90A Deterministic Random Bit Generator In-Reply-To: <2379807.Y4OhqCbdOM@myon.chronox.de> References: <2379807.Y4OhqCbdOM@myon.chronox.de> Message-ID: <2813208.ekDHcadzK5@myon.chronox.de> (resent as the mail list manager does not like emails larger than 40 KB) This is a clean-room implementation of the DRBG defined in SP800-90A. All three viable DRBGs defined in the standard are implemented: * HMAC: This is the leanest DRBG and compiled per default * Hash: The more complex DRBG can be enabled at compile time * CTR: The most complex DRBG can also be enabled at compile time The DRBG implementation offers the following: * All three DRBG types are implemented with a derivation function. * All DRBG types are available with and without prediction resistance. * All SHA types of SHA-1, SHA-256, SHA-384, SHA-512 are available for the HMAC and Hash DRBGs. * All AES types of AES-128, AES-192 and AES-256 are available for the CTR DRBG. * A self test is implemented with drbg_healthcheck(). * The FIPS 140-2 continuous self test is implemented. * Additional cipher primitives, such as Serpent or Twofish, can be added to the DRBG without changing the implementation. The only change necessary is to the DRBG definition given in the cores[] array. Signed-off-by: Stephan Mueller -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-SP800-90A-Deterministic-Random-Bit-Generator.patch.bz2 Type: application/x-bzip Size: 21376 bytes Desc: not available URL: From cvs at cvs.gnupg.org Tue Mar 4 11:20:37 2014 From: cvs at cvs.gnupg.org (by Dmitry Eremin-Solenikov) Date: Tue, 04 Mar 2014 11:20:37 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-58-g2b5403c 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 2b5403c408dfbd71be24c7635f5fa0b61ab4c9bb (commit) via ea8d597726305274214224757b32730644e12bd8 (commit) from 6be3032048ee2466511d2384fcf2d28b856219b2 (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 2b5403c408dfbd71be24c7635f5fa0b61ab4c9bb Author: Dmitry Eremin-Solenikov Date: Sun Dec 22 17:13:45 2013 +0400 Add an utility to calculate hashes over a set of files * tests/gchash.c: New. -- An utility like rhash that has the ability to calculate different hashes over a set of files it usefull. Add gchash utility to calculate hashes supported by libgcrypt. Signed-off-by: Dmitry Eremin-Solenikov diff --git a/.gitignore b/.gitignore index ec7f8bb..8b235f9 100644 --- a/.gitignore +++ b/.gitignore @@ -69,6 +69,7 @@ tests/basic tests/benchmark tests/fips186-dsa tests/fipsdrv +tests/gchash tests/hmac tests/keygen tests/keygrip diff --git a/tests/Makefile.am b/tests/Makefile.am index 4cf7a44..9f8839a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -51,7 +51,8 @@ standard_ldadd = \ ../compat/libcompat.la EXTRA_PROGRAMS = testapi pkbench -noinst_PROGRAMS = $(tests_bin) $(tests_bin_last) fipsdrv rsacvt genhashdata +noinst_PROGRAMS = $(tests_bin) $(tests_bin_last) fipsdrv rsacvt genhashdata \ + gchash noinst_HEADERS = t-common.h EXTRA_DIST = README rsa-16k.key cavs_tests.sh cavs_driver.pl \ diff --git a/tests/gchash.c b/tests/gchash.c new file mode 100644 index 0000000..7a2aad6 --- /dev/null +++ b/tests/gchash.c @@ -0,0 +1,120 @@ +/* gchash.c - Calculate hash values + * Copyright (C) 2013 Dmitry Eremin-Solenikov + * + * 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 . + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include +#include +#include + +#ifdef _GCRYPT_IN_LIBGCRYPT +# undef _GCRYPT_IN_LIBGCRYPT +# include "gcrypt.h" +#else +# include +#endif + + +void +init_gcrypt (void) +{ + if (!gcry_check_version (GCRYPT_VERSION)) { + fputs ("libgcrypt version mismatch\n", stderr); + exit (2); + } + + gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); + + /* Allocate a pool of 16k secure memory. This make the secure memory + * available and also drops privileges where needed. */ + gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); + + gcry_control (GCRYCTL_RESUME_SECMEM_WARN); + + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); +} + +int +main (int argc, char **argv) +{ + gcry_md_hd_t hd; + gcry_error_t err; + int algo; + + init_gcrypt(); + + if (argc < 2 || (argv[1] && !strcmp(argv[1], "--help"))) + { + fprintf (stderr, "Usage: %s ...\n", argv[0]); + return 1; + } + + algo = gcry_md_map_name (argv[1]); + if (algo == GCRY_MD_NONE) + { + fprintf (stderr, "Unknown algorithm '%s'\n", argv[1]); + return 1; + } + + err = gcry_md_open(&hd, algo, 0); + if (err) + { + fprintf (stderr, "LibGCrypt error %s/%s\n", + gcry_strsource (err), + gcry_strerror (err)); + exit (1); + } + + for (argv += 2; *argv; argv++) + { + FILE *fp; + unsigned char buf[1024]; + size_t size; + int i; + unsigned char *h; + if (!strcmp (*argv, "-")) + fp = stdin; + else + fp = fopen (*argv, "r"); + + if (fp == NULL) + { + perror ("fopen"); + return 1; + } + + while (!feof (fp)) + { + size = fread (buf, 1, sizeof(buf), fp); + gcry_md_write (hd, buf, size); + } + + h = gcry_md_read(hd, 0); + + for (i = 0; i < gcry_md_get_algo_dlen (algo); i++) + printf("%02hhx", h[i]); + printf(" %s\n", *argv); + + gcry_md_reset(hd); + } + + gcry_md_close(hd); + return 0; +} commit ea8d597726305274214224757b32730644e12bd8 Author: Dmitry Eremin-Solenikov Date: Sun Dec 22 17:12:28 2013 +0400 Add a simple (raw) PKCS#1 padding mode * src/cipher.h (PUBKEY_ENC_PKCS1_RAW): New. * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Handle pkcs1-raw flag. * cipher/pubkey-util.c (_gcry_pk_util_data_to_mpi): Handle s-exp like (data (flags pkcs1-raw) (value xxxxx)) * cipher/rsa-common.c (_gcry_rsa_pkcs1_encode_raw_for_sig): PKCS#1-encode data with embedded hash OID for signature verification. * tests/basic.c (check_pubkey_sign): Add tests for s-exps with pkcs1-raw flag. -- Allow user to specify (flags pkcs1-raw) to enable pkcs1 padding of raw value (no hash algorithm is specified). It is up to the user to verify that the passed value is properly formatted and includes DER-encoded ASN OID of the used hash function. Signed-off-by: Dmitry Eremin-Solenikov diff --git a/cipher/pubkey-internal.h b/cipher/pubkey-internal.h index 193248c..b8167c7 100644 --- a/cipher/pubkey-internal.h +++ b/cipher/pubkey-internal.h @@ -56,6 +56,10 @@ gpg_err_code_t _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, unsigned int nbits, gcry_mpi_t value); gpg_err_code_t +_gcry_rsa_pkcs1_encode_raw_for_sig (gcry_mpi_t *r_result, unsigned int nbits, + const unsigned char *value, size_t valuelen); + +gpg_err_code_t _gcry_rsa_pkcs1_encode_for_sig (gcry_mpi_t *r_result, unsigned int nbits, const unsigned char *value, size_t valuelen, int algo); diff --git a/cipher/pubkey-util.c b/cipher/pubkey-util.c index 616b499..514f1eb 100644 --- a/cipher/pubkey-util.c +++ b/cipher/pubkey-util.c @@ -142,6 +142,16 @@ _gcry_pk_util_parse_flaglist (gcry_sexp_t list, rc = GPG_ERR_INV_FLAG; break; + case 9: + if (!memcmp (s, "pkcs1-raw", 9) && encoding == PUBKEY_ENC_UNKNOWN) + { + encoding = PUBKEY_ENC_PKCS1_RAW; + flags |= PUBKEY_FLAG_FIXEDLEN; + } + else if (!igninvflag) + rc = GPG_ERR_INV_FLAG; + break; + case 10: if (!memcmp (s, "igninvflag", 10)) igninvflag = 1; @@ -850,6 +860,21 @@ _gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi, ctx->hash_algo); } } + else if (ctx->encoding == PUBKEY_ENC_PKCS1_RAW && lvalue + && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY)) + { + const void * value; + size_t valuelen; + + if (sexp_length (lvalue) != 2) + rc = GPG_ERR_INV_OBJ; + else if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) + || !valuelen ) + rc = GPG_ERR_INV_OBJ; + else + rc = _gcry_rsa_pkcs1_encode_raw_for_sig (ret_mpi, ctx->nbits, + value, valuelen); + } else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue && ctx->op == PUBKEY_OP_ENCRYPT) { diff --git a/cipher/rsa-common.c b/cipher/rsa-common.c index 4f5a659..f56e989 100644 --- a/cipher/rsa-common.c +++ b/cipher/rsa-common.c @@ -319,6 +319,71 @@ _gcry_rsa_pkcs1_encode_for_sig (gcry_mpi_t *r_result, unsigned int nbits, return rc; } +/* Encode {VALUE,VALUELEN} for an NBITS keys using the pkcs#1 block + type 1 padding. On success the result is stored as a new MPI at + R_RESULT. On error the value at R_RESULT is undefined. + + We encode the value in this way: + + 0 1 PAD(n bytes) 0 VALUE(valuelen bytes) + + 0 is a marker we unfortunately can't encode because we return an + MPI which strips all leading zeroes. + 1 is the block type. + PAD consists of 0xff bytes. + 0 marks the end of the padding. + + (Note that PGP prior to version 2.3 encoded the message digest as: + 0 1 MD(16 bytes) 0 PAD(n bytes) 1 + The MD is always 16 bytes here because it's always MD5. GnuPG + does not not support pre-v2.3 signatures, but I'm including this + comment so the information is easily found if needed.) +*/ +gpg_err_code_t +_gcry_rsa_pkcs1_encode_raw_for_sig (gcry_mpi_t *r_result, unsigned int nbits, + const unsigned char *value, size_t valuelen) +{ + gcry_err_code_t rc = 0; + gcry_error_t err; + byte *frame = NULL; + size_t nframe = (nbits+7) / 8; + int i; + size_t n; + + if ( !valuelen || valuelen + 4 > nframe) + { + /* Can't encode an DLEN byte digest MD into an NFRAME byte + frame. */ + return GPG_ERR_TOO_SHORT; + } + + if ( !(frame = xtrymalloc (nframe)) ) + return gpg_err_code_from_syserror (); + + /* Assemble the pkcs#1 block type 1. */ + n = 0; + frame[n++] = 0; + frame[n++] = 1; /* block type */ + i = nframe - valuelen - 3 ; + gcry_assert (i > 1); + memset (frame+n, 0xff, i ); + n += i; + frame[n++] = 0; + memcpy (frame+n, value, valuelen ); + n += valuelen; + gcry_assert (n == nframe); + + /* Convert it into an MPI. */ + err = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe); + if (err) + rc = gcry_err_code (err); + else if (DBG_CIPHER) + log_mpidump ("PKCS#1 block type 1 encoded data", *r_result); + xfree (frame); + + return rc; +} + /* Mask generation function for OAEP. See RFC-3447 B.2.1. */ static gcry_err_code_t diff --git a/src/cipher.h b/src/cipher.h index 10bfe0c..26ffddc 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -54,6 +54,7 @@ enum pk_encoding { PUBKEY_ENC_RAW, PUBKEY_ENC_PKCS1, + PUBKEY_ENC_PKCS1_RAW, PUBKEY_ENC_OAEP, PUBKEY_ENC_PSS, PUBKEY_ENC_UNKNOWN diff --git a/tests/basic.c b/tests/basic.c index 4474a9d..e21e055 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -5155,6 +5155,10 @@ check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo) " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", GCRY_PK_RSA, 0 }, + { "(data\n (flags pkcs1-raw)\n" + " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", + GCRY_PK_RSA, + GPG_ERR_CONFLICT }, { "(data\n (flags oaep)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", 0, @@ -5187,6 +5191,10 @@ check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo) " (value #11223344556677889900AA#))\n", GCRY_PK_RSA, GPG_ERR_CONFLICT }, + { "(data\n (flags pkcs1-raw)\n" + " (value #11223344556677889900AA#))\n", + GCRY_PK_RSA, + 0 }, { "(data\n (flags raw foo)\n" " (value #11223344556677889900AA#))\n", 0, ----------------------------------------------------------------------- Summary of changes: .gitignore | 1 + cipher/pubkey-internal.h | 4 ++ cipher/pubkey-util.c | 25 ++++++++++ cipher/rsa-common.c | 65 +++++++++++++++++++++++++ src/cipher.h | 1 + tests/Makefile.am | 3 +- tests/basic.c | 8 ++++ tests/gchash.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 tests/gchash.c 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 Tue Mar 4 16:02:50 2014 From: wk at gnupg.org (Werner Koch) Date: Tue, 04 Mar 2014 16:02:50 +0100 Subject: "Fixing" private key/generating public key from incomplete private In-Reply-To: (Dmitry Eremin-Solenikov's message of "Sat, 1 Feb 2014 21:06:17 +0400") References: Message-ID: <87zjl6m2g5.fsf@vigenere.g10code.de> On Sat, 1 Feb 2014 18:06, dbaryshkov at gmail.com said: > the DSA key from PKCS#8 keyfile. It contains (in terms of gcrypt > s-exp) domain parameters (p, q, g), secret exponent (x) but no > public exponent (y). I found gcrypt_pubkey_get_sexp, but it > (currently) only works for ECC. We have a similar thing in RSA due to the different ways of specifying the parameters required for the use of the CRT. Libgcrypt solves this in the general case by not using the CRT. Gpg-agent however computes missing parameters in the form required by Libgcrypt during import of an (OpenSSL) generated key. Your idea is to define a function to help an application to compute the parameters in the Libgcrypt preferred (or required) form. > It there a good way to solve my problem? I was thinking about > adding an special mode to gcry_pk_genkey or about adding a Not good. The key has alrady be generated. > special API resembling gcrypt_pubkey_get_sexp() but working > with such (incomplete) private keys instead of contexts. What is your problem with contexts? They will be helpful to cache intermediate results, for example for mass verification. Thus I plan to implement them anyway (gcry_pubkey_*). For example we could use something like this: gcry_ctx_new (&ctx) gcry_pubkey_testkey (key, ctx); gcry_pubkey_get_sexp (&result, GCRY_PK_GET_PUBKEY, ctx); gcry_ctx_release (ctx); With gcry_pubkey_testkey being identical to gcry_pk_testkey if no context is given. gcry_ctx_new would create a new empty context object which gcry_pubkey_testkey would the setup with its internal intermediate results (e.g. y). Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From dbaryshkov at gmail.com Tue Mar 4 16:27:21 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Tue, 4 Mar 2014 19:27:21 +0400 Subject: "Fixing" private key/generating public key from incomplete private In-Reply-To: <87zjl6m2g5.fsf@vigenere.g10code.de> References: <87zjl6m2g5.fsf@vigenere.g10code.de> Message-ID: Hello, On Tue, Mar 4, 2014 at 7:02 PM, Werner Koch wrote: > On Sat, 1 Feb 2014 18:06, dbaryshkov at gmail.com said: > >> the DSA key from PKCS#8 keyfile. It contains (in terms of gcrypt >> s-exp) domain parameters (p, q, g), secret exponent (x) but no >> public exponent (y). I found gcrypt_pubkey_get_sexp, but it >> (currently) only works for ECC. > > We have a similar thing in RSA due to the different ways of specifying > the parameters required for the use of the CRT. Libgcrypt solves this > in the general case by not using the CRT. Gpg-agent however computes > missing parameters in the form required by Libgcrypt during import of an > (OpenSSL) generated key. More or less the same problem here - I have private keys without public key bundled in, so I have to restore it. > > Your idea is to define a function to help an application to compute the > parameters in the Libgcrypt preferred (or required) form. Yes. > >> It there a good way to solve my problem? I was thinking about >> adding an special mode to gcry_pk_genkey or about adding a > > Not good. The key has alrady be generated. > >> special API resembling gcrypt_pubkey_get_sexp() but working >> with such (incomplete) private keys instead of contexts. > > What is your problem with contexts? They will be helpful to cache > intermediate results, for example for mass verification. Thus I plan to > implement them anyway (gcry_pubkey_*). The problem is that they are not supported yet for non-ECC things, are they? > For example we could use something like this: > > gcry_ctx_new (&ctx) > gcry_pubkey_testkey (key, ctx); > gcry_pubkey_get_sexp (&result, GCRY_PK_GET_PUBKEY, ctx); > gcry_ctx_release (ctx); > > With gcry_pubkey_testkey being identical to gcry_pk_testkey if no > context is given. gcry_ctx_new would create a new empty context object > which gcry_pubkey_testkey would the setup with its internal intermediate > results (e.g. y). Would it be possible to use contexts instead of s-exp in external API? That would bring some speedup for the library I think. -- With best wishes Dmitry From wk at gnupg.org Wed Mar 5 08:41:10 2014 From: wk at gnupg.org (Werner Koch) Date: Wed, 05 Mar 2014 08:41:10 +0100 Subject: "Fixing" private key/generating public key from incomplete private In-Reply-To: (Dmitry Eremin-Solenikov's message of "Tue, 4 Mar 2014 19:27:21 +0400") References: <87zjl6m2g5.fsf@vigenere.g10code.de> Message-ID: <87fvmxm6sp.fsf@vigenere.g10code.de> On Tue, 4 Mar 2014 16:27, dbaryshkov at gmail.com said: > The problem is that they are not supported yet for non-ECC things, > are they? Not yet needed. I could implement gcry_pubkey_testkey to allow for RSA and DSA public key fixup. Shall I? > Would it be possible to use contexts instead of s-exp in external API? > That would bring some speedup for the library I think. The key representation in the API are not a problem performance wise. There are lot of options to speed up public key computations. gniibe recently applied a patch which not only restored RSA performance but actually improved it a lot. Recall that there has been no performance work for 10 years or so. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From dbaryshkov at gmail.com Wed Mar 5 10:11:22 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Wed, 5 Mar 2014 13:11:22 +0400 Subject: "Fixing" private key/generating public key from incomplete private In-Reply-To: <87fvmxm6sp.fsf@vigenere.g10code.de> References: <87zjl6m2g5.fsf@vigenere.g10code.de> <87fvmxm6sp.fsf@vigenere.g10code.de> Message-ID: On Wed, Mar 5, 2014 at 11:41 AM, Werner Koch wrote: > On Tue, 4 Mar 2014 16:27, dbaryshkov at gmail.com said: > >> The problem is that they are not supported yet for non-ECC things, >> are they? > > Not yet needed. I could implement gcry_pubkey_testkey to allow for RSA > and DSA public key fixup. Shall I? I'm not sure about the 'testkey' name. I have the following use case in mind: I read the private exponent from the private key. I initialize the context and then I can fetch usable public and private keys from that context. -- With best wishes Dmitry From wk at gnupg.org Wed Mar 5 11:19:38 2014 From: wk at gnupg.org (Werner Koch) Date: Wed, 05 Mar 2014 11:19:38 +0100 Subject: "Fixing" private key/generating public key from incomplete private In-Reply-To: (Dmitry Eremin-Solenikov's message of "Wed, 5 Mar 2014 13:11:22 +0400") References: <87zjl6m2g5.fsf@vigenere.g10code.de> <87fvmxm6sp.fsf@vigenere.g10code.de> Message-ID: <87siqxkkw5.fsf@vigenere.g10code.de> On Wed, 5 Mar 2014 10:11, dbaryshkov at gmail.com said: > I'm not sure about the 'testkey' name. I have the following use case in mind: > I read the private exponent from the private key. I initialize the context > and then I can fetch usable public and private keys from that context. testkey tries to figure whether a secret key is consistent. for example for RSA it computes the public modulus and compares it to the provided public modulus. For DSA, y is computed and compared to the provided y. Now with a provided context testkey could store that Y in the context and tell the user by returning a dedicated error code, that Y was missing but is now available in the context. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From k2k at yandex.ru Wed Mar 5 11:02:56 2014 From: k2k at yandex.ru (Evgeny Grin) Date: Wed, 05 Mar 2014 14:02:56 +0400 Subject: Patch for libgrypt autoconf macro Message-ID: <275321394013776@web25h.yandex.ru> Hi! I modified libgcrypt.m4 for my local needs and want to share my patch: >From 003dba7cc64b0a4760d3c4b918faf4264b913633 Mon Sep 17 00:00:00 2001 From: Karlson2k Date: Thu, 27 Feb 2014 10:59:41 +0400 Subject: [PATCH] Updated src/libgcrypt.m4 to use $SED and $GREP instead of hardcoded names --- src/libgcrypt.m4 | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/libgcrypt.m4 b/src/libgcrypt.m4 index 6cf482f..75863ba 100644 --- a/src/libgcrypt.m4 +++ b/src/libgcrypt.m4 @@ -1,5 +1,6 @@ dnl Autoconf macros for libgcrypt dnl Copyright (C) 2002, 2004, 2011 Free Software Foundation, Inc. +dnl Copyright (C) 2014 Karlson2k (Evgeny Grin) dnl dnl This file is free software; as a special exception the author gives dnl unlimited permission to copy and/or distribute it, with or without @@ -20,8 +21,12 @@ dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using dnl this features allows to prevent build against newer versions of libgcrypt dnl with a changed API. dnl +dnl Updated by Karlson2k to be more tolerant to host tools variations. +dnl AC_DEFUN([AM_PATH_LIBGCRYPT], [ AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_PROG_GREP]) + AC_REQUIRE([AC_PROG_SED]) AC_ARG_WITH(libgcrypt-prefix, AC_HELP_STRING([--with-libgcrypt-prefix=PFX], [prefix where LIBGCRYPT is installed (optional)]), @@ -34,9 +39,9 @@ AC_DEFUN([AM_PATH_LIBGCRYPT], AC_PATH_TOOL(LIBGCRYPT_CONFIG, libgcrypt-config, no) tmp=ifelse([$1], ,1:1.2.0,$1) - if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then - req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'` - min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'` + if echo "$tmp" | $GREP ':' >/dev/null 2>/dev/null ; then + req_libgcrypt_api=`echo "$tmp" | $SED 's/\(.*\):\(.*\)/\1/'` + min_libgcrypt_version=`echo "$tmp" | $SED 's/\(.*\):\(.*\)/\2/'` else req_libgcrypt_api=0 min_libgcrypt_version="$tmp" @@ -46,18 +51,18 @@ AC_DEFUN([AM_PATH_LIBGCRYPT], ok=no if test "$LIBGCRYPT_CONFIG" != "no" ; then req_major=`echo $min_libgcrypt_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` + $SED 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'` req_minor=`echo $min_libgcrypt_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` + $SED 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'` req_micro=`echo $min_libgcrypt_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` + $SED 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'` libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version` major=`echo $libgcrypt_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` + $SED 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` minor=`echo $libgcrypt_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` + $SED 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'` micro=`echo $libgcrypt_config_version | \ - sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` + $SED 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` if test "$major" -gt "$req_major"; then ok=yes else -- 1.8.5.5 Hope you'll find it useful. --? Best Wishes, Evgeny Grin -------------- next part -------------- A non-text attachment was scrubbed... Name: libgcrypt.m4.patch Type: text/x-diff Size: 3367 bytes Desc: not available URL: From wk at gnupg.org Thu Mar 6 09:07:22 2014 From: wk at gnupg.org (Werner Koch) Date: Thu, 06 Mar 2014 09:07:22 +0100 Subject: Patch for libgrypt autoconf macro In-Reply-To: <275321394013776@web25h.yandex.ru> (Evgeny Grin's message of "Wed, 05 Mar 2014 14:02:56 +0400") References: <275321394013776@web25h.yandex.ru> Message-ID: <87bnxjkax1.fsf@vigenere.g10code.de> On Wed, 5 Mar 2014 11:02, k2k at yandex.ru said: > I modified libgcrypt.m4 for my local needs and want to share my patch: Would you be so kind an explain why you need this? We do not use any special options or features of grep or sed. grep(1) and sed(1) are as standard as test(1) and a basic part of the Unix tool kit for now 40 years. Unix version 6 was the first public version and appeared in 1975; both tools have already been part of version 4 (see also CACM [1]). Shalom-Salam, Werner [1] @article{Ritchie:1974:UTS:361011.361061, author = {Ritchie, Dennis M. and Thompson, Ken}, title = {The UNIX Time-sharing System}, journal = {Commun. ACM}, issue_date = {July 1974}, volume = {17}, number = {7}, month = jul, year = {1974}, issn = {0001-0782}, pages = {365--375}, numpages = {11}, url = {http://doi.acm.org/10.1145/361011.361061}, doi = {10.1145/361011.361061}, acmid = {361061}, publisher = {ACM}, address = {New York, NY, USA}, keywords = {PDP-11, command language, file system, operating system, time-sharing}, } -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From k2k at yandex.ru Thu Mar 6 10:23:45 2014 From: k2k at yandex.ru (Evgeny Grin) Date: Thu, 06 Mar 2014 13:23:45 +0400 Subject: Patch for libgrypt autoconf macro In-Reply-To: <87bnxjkax1.fsf@vigenere.g10code.de> References: <275321394013776@web25h.yandex.ru> <87bnxjkax1.fsf@vigenere.g10code.de> Message-ID: <436611394097825@web14m.yandex.ru> Other autoconf macros use $SED autotools can be used on Linux, Unix, Windows and other platforms so it's better to let user to override default sed by setting SED variable. --? Best Wishes, Evgeny Grin 06.03.2014, 12:16, "Werner Koch" : > Would you be so kind an explain why you need this? ?We do not use any > special options or features of grep or sed. > > grep(1) and sed(1) are as standard as test(1) and a basic part of the > Unix tool kit for now 40 years. ?Unix version 6 was the first public > version and appeared in 1975; both tools have already been part of > version 4 (see also CACM [1]). From wk at gnupg.org Thu Mar 6 15:52:55 2014 From: wk at gnupg.org (Werner Koch) Date: Thu, 06 Mar 2014 15:52:55 +0100 Subject: Patch for libgrypt autoconf macro In-Reply-To: <436611394097825@web14m.yandex.ru> (Evgeny Grin's message of "Thu, 06 Mar 2014 13:23:45 +0400") References: <275321394013776@web25h.yandex.ru> <87bnxjkax1.fsf@vigenere.g10code.de> <436611394097825@web14m.yandex.ru> Message-ID: <87ha7bgz08.fsf@vigenere.g10code.de> On Thu, 6 Mar 2014 10:23, k2k at yandex.ru said: > autotools can be used on Linux, Unix, Windows and other platforms so Linux is a Unix platform. Building on Windows is not supported. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From andre at amorim.me Thu Mar 6 16:12:14 2014 From: andre at amorim.me (Andre Amorim) Date: Thu, 6 Mar 2014 15:12:14 +0000 Subject: Patch for libgrypt autoconf macro In-Reply-To: <87ha7bgz08.fsf@vigenere.g10code.de> References: <275321394013776@web25h.yandex.ru> <87bnxjkax1.fsf@vigenere.g10code.de> <436611394097825@web14m.yandex.ru> <87ha7bgz08.fsf@vigenere.g10code.de> Message-ID: ... patent discursion ;) on NT kernel ring 0 core ... http://microsoft.wikia.com/wiki/Xenix Gnupg key: 02375205 Fingerprint: F7CD D181 943B 0453 8668 AF16 84E9 7565 0237 5205 On 6 March 2014 14:52, Werner Koch wrote: > On Thu, 6 Mar 2014 10:23, k2k at yandex.ru said: > > > autotools can be used on Linux, Unix, Windows and other platforms so > > Linux is a Unix platform. > > Building on Windows is not supported. > > > Salam-Shalom, > > Werner > > -- > Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. > > > _______________________________________________ > Gcrypt-devel mailing list > Gcrypt-devel at gnupg.org > http://lists.gnupg.org/mailman/listinfo/gcrypt-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From k2k at yandex.ru Thu Mar 6 16:07:42 2014 From: k2k at yandex.ru (Evgeny Grin) Date: Thu, 06 Mar 2014 19:07:42 +0400 Subject: Patch for libgrypt autoconf macro In-Reply-To: <87ha7bgz08.fsf@vigenere.g10code.de> References: <275321394013776@web25h.yandex.ru> <87bnxjkax1.fsf@vigenere.g10code.de> <436611394097825@web14m.yandex.ru> <87ha7bgz08.fsf@vigenere.g10code.de> Message-ID: <261171394118462@web23h.yandex.ru> 06.03.2014, 19:01, "Werner Koch" : > On Thu, ?6 Mar 2014 10:23, k2k at yandex.ru said: > >> ?autotools can be used on Linux, Unix, Windows and other platforms so > > Linux is a Unix platform. > Building on Windows is not supported. This macro is not designed for building libgcrypt. It's for using libgcrypt in other projects. This is why I think that flexibility in macro is important. --? Best Wishes, Evgeny Grin From wk at gnupg.org Thu Mar 6 17:27:36 2014 From: wk at gnupg.org (Werner Koch) Date: Thu, 06 Mar 2014 17:27:36 +0100 Subject: Patch for libgrypt autoconf macro In-Reply-To: <261171394118462@web23h.yandex.ru> (Evgeny Grin's message of "Thu, 06 Mar 2014 19:07:42 +0400") References: <275321394013776@web25h.yandex.ru> <87bnxjkax1.fsf@vigenere.g10code.de> <436611394097825@web14m.yandex.ru> <87ha7bgz08.fsf@vigenere.g10code.de> <261171394118462@web23h.yandex.ru> Message-ID: <87zjl3fg1z.fsf@vigenere.g10code.de> On Thu, 6 Mar 2014 16:07, k2k at yandex.ru said: > This macro is not designed for building libgcrypt. It's for using > libgcrypt in other projects. This is why I think that flexibility in Right, it is an autoconf macro and autoconf is Unix only. If you want to build something with Libgcrypt on Windows you won't have any of the convenient build helpers at all. Having autoconf support does not help you because the gcrypt-config script won't work either. Still you can use it because Windows is not a moving target as most Unix platforms are. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From k2k at yandex.ru Thu Mar 6 17:47:21 2014 From: k2k at yandex.ru (Evgeny Grin) Date: Thu, 06 Mar 2014 20:47:21 +0400 Subject: Patch for libgrypt autoconf macro In-Reply-To: <87zjl3fg1z.fsf@vigenere.g10code.de> References: <275321394013776@web25h.yandex.ru> <87bnxjkax1.fsf@vigenere.g10code.de> <436611394097825@web14m.yandex.ru> <87ha7bgz08.fsf@vigenere.g10code.de> <261171394118462@web23h.yandex.ru> <87zjl3fg1z.fsf@vigenere.g10code.de> Message-ID: <152651394124441@web8j.yandex.ru> 06.03.2014, 20:36, "Werner Koch" : > Right, it is an autoconf macro and autoconf is Unix only. ?If you want > to build something with Libgcrypt on Windows you won't have any of the > convenient build helpers at all. ?Having autoconf support does not help > you because the gcrypt-config script won't work either. ?Still you can > use it because Windows is not a moving target as most Unix platforms are. Build libgcrypt few minutes ago using MinGW-w64 on windows. libmicrohttpd was build fine with libgcrypt on Win32. Autoconf is not Unix-only. It's targeted to "Unix-like systems" according to gnu.org. That's why it's important to be platform-agnostic as much as possible. Unix-like != UNIX, host tools can be different. --? Best Wishes, Evgeny Grin From wk at gnupg.org Thu Mar 6 21:35:22 2014 From: wk at gnupg.org (Werner Koch) Date: Thu, 06 Mar 2014 21:35:22 +0100 Subject: Patch for libgrypt autoconf macro In-Reply-To: <152651394124441@web8j.yandex.ru> (Evgeny Grin's message of "Thu, 06 Mar 2014 20:47:21 +0400") References: <275321394013776@web25h.yandex.ru> <87bnxjkax1.fsf@vigenere.g10code.de> <436611394097825@web14m.yandex.ru> <87ha7bgz08.fsf@vigenere.g10code.de> <261171394118462@web23h.yandex.ru> <87zjl3fg1z.fsf@vigenere.g10code.de> <152651394124441@web8j.yandex.ru> Message-ID: <87ha7bf4l1.fsf@vigenere.g10code.de> On Thu, 6 Mar 2014 17:47, k2k at yandex.ru said: > That's why it's important to be platform-agnostic as much as possible. Unix-like != UNIX, host tools can be different. Sorry, that is nonsense. For example the term "Unix-like" means systems which behave similar to systems certified by the the Open group to make use of the trademark Unix. One might also use the term POSIX but fortunately Unix is much older than the somewhat restricted POSIX standard. And more important, there are many other places which requires a proper Unix system. Back to your patch: -- Macro: AC_PROG_GREP Look for the best available 'grep' or 'ggrep' that accepts the longest input lines possible, and that supports multiple '-e' options. Set the output variable 'GREP' to whatever is chosen. *Note Limitations of Usual Tools: grep, for more information about portability problems with the 'grep' command family. The result can be overridden by setting the 'GREP' variable and is cached in the 'ac_cv_path_GREP' variable. However, that extra feature test is simply not required in this case. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From k2k at yandex.ru Fri Mar 7 10:02:26 2014 From: k2k at yandex.ru (Evgeny Grin) Date: Fri, 07 Mar 2014 13:02:26 +0400 Subject: Patch for libgrypt autoconf macro In-Reply-To: <87ha7bf4l1.fsf@vigenere.g10code.de> References: <275321394013776@web25h.yandex.ru> <87bnxjkax1.fsf@vigenere.g10code.de> <436611394097825@web14m.yandex.ru> <87ha7bgz08.fsf@vigenere.g10code.de> <261171394118462@web23h.yandex.ru> <87zjl3fg1z.fsf@vigenere.g10code.de> <152651394124441@web8j.yandex.ru> <87ha7bf4l1.fsf@vigenere.g10code.de> Message-ID: <883651394182946@web22j.yandex.ru> 07.03.2014, 00:46, "Werner Koch" : > On Thu, ?6 Mar 2014 17:47, k2k at yandex.ru said: > Back to your patch: > > ?-- Macro: AC_PROG_GREP > ?????Look for the best available 'grep' or 'ggrep' that accepts the > ?????longest input lines possible, and that supports multiple '-e' > ?????options. ?Set the output variable 'GREP' to whatever is chosen. > ?????*Note Limitations of Usual Tools: grep, for more information about > ?????portability problems with the 'grep' command family. ?The result > ?????can be overridden by setting the 'GREP' variable and is cached in > ?????the 'ac_cv_path_GREP' variable. > > However, that extra feature test is simply not required in this case. Extra test is not required, but test for grep, sed and awk is performed almost always by generated configure. And main advantage is not using some "tested" grep, but is ability to simple override name/path of used host tools. --? Best Wishes, Evgeny Grin From lrn1986 at gmail.com Thu Mar 6 21:45:30 2014 From: lrn1986 at gmail.com (LRN) Date: Fri, 07 Mar 2014 00:45:30 +0400 Subject: Patch for libgrypt autoconf macro In-Reply-To: <87ha7bgz08.fsf@vigenere.g10code.de> References: <275321394013776@web25h.yandex.ru> <87bnxjkax1.fsf@vigenere.g10code.de> <436611394097825@web14m.yandex.ru> <87ha7bgz08.fsf@vigenere.g10code.de> Message-ID: <5318DE6A.4030905@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 06.03.2014 18:52, Werner Koch wrote: > On Thu, 6 Mar 2014 10:23, k2k at yandex.ru said: > >> autotools can be used on Linux, Unix, Windows and other platforms >> so > > Linux is a Unix platform. > > Building on Windows is not supported. Could you please clarify that statement? Is libgcrypt completely "not for Windows" (previously i thought that it was only "not for 64-bit Windows, because we're not sure that 32-bit entropy gathering code works as intended there")? Or do you mean that the use of POSIX environments for building libgcrypt on Windows is not supported? - -- O< ascii ribbon - stop html email! - www.asciiribbon.org -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (MingW32) iQEcBAEBAgAGBQJTGN5pAAoJEOs4Jb6SI2Cwj5AH/0RfFpi8/6do9EgbpUnHQiF+ nDMj4k4/NqLiEQ517n3AO+OOjq3DY8+18GrJtQX793i8fTHHs0DuNefL7dyjQTu6 rJ6fZyZiIgylbBSTefENHgUaXhVEEscvnj4Y4zYwqE7a6yC00GE0GD9a2E1JfpCi XQ2hzkSewZJZQMfwaCQFFJIzQZLgUe8Zh3hWY5kkTckKndzP2BVGtwh0IVKiTlCy 9W0ETQyo88W2goP4Z30Y/Jafc84DbqsWIqVyqlLvGzCQenT9zUdZC7xymFnEXe29 Wwx9OC4OOPI7P7hpiNtzXl/4phpjyiZyeCCwIK8rlL2PcXvV/P+55wYXD9+hHmY= =85wJ -----END PGP SIGNATURE----- From wk at gnupg.org Fri Mar 7 11:43:38 2014 From: wk at gnupg.org (Werner Koch) Date: Fri, 07 Mar 2014 11:43:38 +0100 Subject: Patch for libgrypt autoconf macro In-Reply-To: <5318DE6A.4030905@gmail.com> (LRN's message of "Fri, 07 Mar 2014 00:45:30 +0400") References: <275321394013776@web25h.yandex.ru> <87bnxjkax1.fsf@vigenere.g10code.de> <436611394097825@web14m.yandex.ru> <87ha7bgz08.fsf@vigenere.g10code.de> <5318DE6A.4030905@gmail.com> Message-ID: <87y50me1b9.fsf@vigenere.g10code.de> On Thu, 6 Mar 2014 21:45, lrn1986 at gmail.com said: >> Building on Windows is not supported. > > Could you please clarify that statement? It _cannot_ be build *on* Windows but it _can_ be build *to be used on* Windows. > Is libgcrypt completely "not for Windows" (previously i thought that > Or do you mean that the use of POSIX environments for building > libgcrypt on Windows is not supported? Either you have a POSIX system or Windows. If you run a POSIX systems on top of Windows you have a POSIX systems and thus you should be able to build Libgcrypt. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From lrn1986 at gmail.com Fri Mar 7 12:08:55 2014 From: lrn1986 at gmail.com (LRN) Date: Fri, 07 Mar 2014 15:08:55 +0400 Subject: Patch for libgrypt autoconf macro In-Reply-To: <87y50me1b9.fsf@vigenere.g10code.de> References: <275321394013776@web25h.yandex.ru> <87bnxjkax1.fsf@vigenere.g10code.de> <436611394097825@web14m.yandex.ru> <87ha7bgz08.fsf@vigenere.g10code.de> <5318DE6A.4030905@gmail.com> <87y50me1b9.fsf@vigenere.g10code.de> Message-ID: <5319A8C7.3050601@gmail.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 07.03.2014 14:43, Werner Koch wrote: > On Thu, 6 Mar 2014 21:45, lrn1986 at gmail.com said: > >>> Building on Windows is not supported. >> >> Could you please clarify that statement? > > It _cannot_ be build *on* Windows but it _can_ be build *to be used > on* Windows. > >> Is libgcrypt completely "not for Windows" (previously i thought >> that > >> Or do you mean that the use of POSIX environments for building >> libgcrypt on Windows is not supported? > > Either you have a POSIX system or Windows. If you run a POSIX > systems on top of Windows you have a POSIX systems and thus you > should be able to build Libgcrypt. That covers MSYS/Cygwin, since they ARE POSIX. This change affects autoconf macros, and on Wind..no, scratch that...on POSIX they are used by stuff running under POSIX (which, in our case, is Cygwin or MSYS). I don't see a problem here. We always assume that autotools == POSIX system or a POSIX layer on top of non-POSIX system. You can (obviously) use autotools to build things other than libgcrypt, and you do this on POSIX (which could be a compatibility layer). And you might want to be able to substitute stock POSIX tools, or alter their invocation somehow (i do that to the STRIP tool every time i build something), when building stuff on POSIX and configuring using the macros libgcrypt provides. I fail to see any problem with this (other than maybe a misunderstanding about what "on Windows" means for people who build free software packages VS what it means for you personally). - -- O< ascii ribbon - stop html email! - www.asciiribbon.org -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (MingW32) iQEcBAEBAgAGBQJTGajGAAoJEOs4Jb6SI2Cw++sH/01N7SKd9a5yxNEMcTHMyyZC i63n/s9q/l317bIL68KZk2ovI+jzY/56SE3O3uBytuAdf764zjUoVucDbsBXOOmz NnzlylH8KHs7P6aAdopNOlo043Vxnytr65IWZU/HfEljWJUNB4/cBWcnmpryRP+i lL8EII6zOX8owGqpaH32EZ6QMwnAbbNkj9l7XwVUHaeICycZ0S+uYupmCIpN7FQR fQNm/QB6DilE9ugyeR6e1tChMLU44hZVr0ryAc8/90OsfOz2L8fLU3udMDkjqMW8 wrvMKxEafv/vmQSrPgI+gN/ABOHSZATDEYx0N+5rmO5nvZCVUa1rAVzSQ8+EKuE= =lB9f -----END PGP SIGNATURE----- From wk at gnupg.org Fri Mar 7 15:38:51 2014 From: wk at gnupg.org (Werner Koch) Date: Fri, 07 Mar 2014 15:38:51 +0100 Subject: Patch for libgrypt autoconf macro In-Reply-To: <5319A8C7.3050601@gmail.com> (LRN's message of "Fri, 07 Mar 2014 15:08:55 +0400") References: <275321394013776@web25h.yandex.ru> <87bnxjkax1.fsf@vigenere.g10code.de> <436611394097825@web14m.yandex.ru> <87ha7bgz08.fsf@vigenere.g10code.de> <5318DE6A.4030905@gmail.com> <87y50me1b9.fsf@vigenere.g10code.de> <5319A8C7.3050601@gmail.com> Message-ID: <87eh2edqf8.fsf@vigenere.g10code.de> On Fri, 7 Mar 2014 12:08, lrn1986 at gmail.com said: > layer). And you might want to be able to substitute stock POSIX tools, > or alter their invocation somehow (i do that to the STRIP tool every There is no need to replace sed or grep. And in any case it won't help because the libgcrypt-config tool - which is used by libgcrypt.m4 - uses fgrep(1) and sed(1) as well and there is no way to replace it there. Can we please stop this useless thread. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From smueller at chronox.de Sun Mar 9 00:29:59 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 09 Mar 2014 00:29:59 +0100 Subject: [PATCH v2 8/8] User interface to DRBG In-Reply-To: <2257544.bDytV5JM1d@myon.chronox.de> References: <1872704.puni0eUsq8@myon.chronox.de> <278872900.kqS5BSaDt8@myon.chronox.de> <2257544.bDytV5JM1d@myon.chronox.de> Message-ID: <1554449.JsnGNYr2dU@myon.chronox.de> DRBG Usage ========== The SP 800-90A DRBG allows the user to specify a personalization string for initialization as well as an additional information string for each random number request. The following code fragments show how a caller uses the kernel crypto API to use the full functionality of the DRBG. Usage without any additional data --------------------------------- gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); Usage with personalization string during initialization ------------------------------------------------------- char personalization = "some-string"; // The reset completely re-initializes the DRBG with the provided // personalization string without changing the DRBG type ret = gcry_control(GCRYCTL_DRBG_REINIT, 0, personalization, strlen(personalization)); gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); Usage with additional information string during random number request --------------------------------------------------------------------- char addtl = "some-string"; // The following call is a wrapper to gcry_randomize() and returns // the same error codes. gcry_randomize_drbg(outbuf, OUTLEN, GCRY_STRONG_RANDOM, addtl, strlen(addtl)); Usage with personalization and additional information strings ------------------------------------------------------------- Just mix both scenarios above. Switch the DRBG type to some other type --------------------------------------- // Switch to CTR DRBG AES-128 without prediction resistance ret = gcry_control(GCRYCTL_DRBG_REINIT, DRBG_CTRAES128, NULL, 0); gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); Signed-off-by: Stephan Mueller diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index c84a3f7..675a8c8 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -329,7 +329,9 @@ enum gcry_ctl_cmds GCRYCTL_SET_CCM_LENGTHS = 69, GCRYCTL_CLOSE_RANDOM_DEVICE = 70, GCRYCTL_INACTIVATE_FIPS_FLAG = 71, - GCRYCTL_REACTIVATE_FIPS_FLAG = 72 + GCRYCTL_REACTIVATE_FIPS_FLAG = 72, + GCRYCTL_DRBG_REINIT = 73, + GCRYCTL_DRBG_SET_ENTROPY = 74, }; /* Perform various operations defined by CMD. */ @@ -1673,6 +1675,84 @@ int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE; #define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) +/* DRBG input data structure for DRBG generate with additional information + * string */ +struct drbg_gen +{ + unsigned char *outbuf; /* output buffer for random numbers */ + unsigned int outlen; /* size of output buffer */ + unsigned char *addtl_input; /* input buffer for + * additional information string */ + unsigned int addtllen; /* length of addtl_input */ +}; + +/* this is a wrapper function for users of libgcrypt */ +static inline void gcry_randomize_drbg(void *outbuf, size_t outlen, + enum gcry_random_level level, + unsigned char *addtl_input, + size_t addtllen) +{ + struct drbg_gen genbuf; + genbuf.outbuf = outbuf; + genbuf.outlen = outlen; + genbuf.addtl_input = addtl_input; + genbuf.addtllen = addtllen; + gcry_randomize(&genbuf, 0, level); +} + +/* + * DRBG flags bitmasks + * + * 31 (B) 27 19 (A) 0 + * +-+-+-+-+------+---+---+---------------+ + * |~|~|u|p|~~~~~~| 3 | 2 | 1 | + * +-+-+-+-+------+- -+---+---------------+ + * ctl flags| |drbg use selection flags + * + */ + +/* internal state control flags (B) */ +#define DRBG_UNSEEDED ((__u32)1<<27) +#define DRBG_PREDICTION_RESIST ((__u32)1<<28) + +/* CTR type modifiers (A.1)*/ +#define DRBG_CTRAES128 ((__u32)1<<0) +#define DRBG_CTRAES192 ((__u32)1<<1) +#define DRBG_CTRAES256 ((__u32)1<<2) +#define DRBG_CTRSERPENT128 ((__u32)1<<3) +#define DRBG_CTRSERPENT192 ((__u32)1<<4) +#define DRBG_CTRSERPENT256 ((__u32)1<<5) +#define DRBG_CTRTWOFISH128 ((__u32)1<<6) +#define DRBG_CTRTWOFISH192 ((__u32)1<<7) +#define DRBG_CTRTWOFISH256 ((__u32)1<<8) +#define DRBG_CTR_MASK (DRBG_CTRAES128 | DRBG_CTRAES192 | DRBG_CTRAES256| \ + DRBG_CTRSERPENT128 | DRBG_CTRSERPENT192 | \ + DRBG_CTRSERPENT256 | DRBG_CTRTWOFISH128 | \ + DRBG_CTRTWOFISH192 | DRBG_CTRTWOFISH256) + + +/* HASH type modifiers (A.2)*/ +#define DRBG_HASHSHA1 ((__u32)1<<9) +#define DRBG_HASHSHA224 ((__u32)1<<10) +#define DRBG_HASHSHA256 ((__u32)1<<11) +#define DRBG_HASHSHA384 ((__u32)1<<12) +#define DRBG_HASHSHA512 ((__u32)1<<13) +#define DRBG_HASH_MASK (DRBG_HASHSHA1 | DRBG_HASHSHA224 | \ + DRBG_HASHSHA256 | DRBG_HASHSHA384 | \ + DRBG_HASHSHA512) + +/* HMAC type modifiers (A.2)*/ +#define DRBG_HMACSHA1 ((__u32)1<<14) +#define DRBG_HMACSHA224 ((__u32)1<<15) +#define DRBG_HMACSHA256 ((__u32)1<<16) +#define DRBG_HMACSHA384 ((__u32)1<<17) +#define DRBG_HMACSHA512 ((__u32)1<<18) +#define DRBG_HMAC_MASK (DRBG_HMACSHA1 | DRBG_HMACSHA224 | \ + DRBG_HMACSHA256 | DRBG_HMACSHA384 | \ + DRBG_HMACSHA512) + +#define DRBG_CIPHER_MASK (DRBG_CTR_MASK | DRBG_HASH_MASK | DRBG_HMAC_MASK) + #if 0 /* (Keep Emacsens' auto-indent happy.) */ { #endif -- 1.8.5.3 From smueller at chronox.de Sun Mar 9 00:29:22 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 09 Mar 2014 00:29:22 +0100 Subject: [PATCH v2 7/8] Include OS types.h for __u32 definition In-Reply-To: <278872900.kqS5BSaDt8@myon.chronox.de> References: <1872704.puni0eUsq8@myon.chronox.de> <13545738.nuHqZMWCpj@myon.chronox.de> <278872900.kqS5BSaDt8@myon.chronox.de> Message-ID: <2257544.bDytV5JM1d@myon.chronox.de> Signed-off-by: Stephan Mueller diff --git a/src/types.h b/src/types.h index ee0a62b..c95c5af 100644 --- a/src/types.h +++ b/src/types.h @@ -39,6 +39,7 @@ #include +#include #ifndef HAVE_BYTE_TYPEDEF -- 1.8.5.3 From smueller at chronox.de Sun Mar 9 00:25:00 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 09 Mar 2014 00:25 +0100 Subject: [PATCH v2 1/8] SP800-90A Deterministic Random Bit Generator In-Reply-To: <1872704.puni0eUsq8@myon.chronox.de> References: <1872704.puni0eUsq8@myon.chronox.de> Message-ID: <2160369.gfM6X27d5C@myon.chronox.de> This is a clean-room implementation of the DRBG defined in SP800-90A. All three viable DRBGs defined in the standard are implemented: * HMAC: This is the leanest DRBG and compiled per default * Hash: The more complex DRBG can be enabled at compile time * CTR: The most complex DRBG can also be enabled at compile time The DRBG implementation offers the following: * All three DRBG types are implemented with a derivation function. * All DRBG types are available with and without prediction resistance. * All SHA types of SHA-1, SHA-256, SHA-384, SHA-512 are available for * the HMAC and Hash DRBGs. * All AES types of AES-128, AES-192 and AES-256 are available for the * CTR DRBG. * A self test is implemented with drbg_healthcheck(). * The FIPS 140-2 continuous self test is implemented. * Additional cipher primitives, such as Serpent or Twofish, can be * added to the DRBG without changing the implementation. The only * change necessary is to the DRBG definition given in the cores[] * array. Signed-off-by: Stephan Mueller create mode 100644 random/drbg.c -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-SP800-90A-Deterministic-Random-Bit-Generator.patch.bz2 Type: application/x-bzip Size: 21850 bytes Desc: not available URL: From smueller at chronox.de Sun Mar 9 00:23:47 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 09 Mar 2014 00:23:47 +0100 Subject: [PATCH v2 0/8] SP800-90A Deterministic Random Bit Generator Message-ID: <1872704.puni0eUsq8@myon.chronox.de> Hi, the following set of patches against the current GIT development tree of libgcrypt implements the SP800-90A DRBG and integrates it with libgcrypt. version 2 changes: * reformat drbg.c to conform to libgcrypt coding style * clean up data structures * add drbg_healthcheck_sanity Thanks to Jeremy Powell and Rafael Aquini for comments. Stephan Mueller (8): SP800-90A Deterministic Random Bit Generator Compile DRBG Function definitions of interfaces for random.c Invoke DRBG from common libgcrypt RNG code Function definitions for gcry_control callbacks DRBG specific gcry_control requests Include OS types.h for __u32 definition User interface to DRBG random/Makefile.am | 1 + random/drbg.c | 3214 ++++++++++++++++++++++++++++++++++++++++++++++++ random/rand-internal.h | 9 + random/random.c | 33 +- random/random.h | 6 +- src/gcrypt.h.in | 82 +- src/global.c | 17 + src/types.h | 1 + 8 files changed, 3351 insertions(+), 12 deletions(-) create mode 100644 random/drbg.c -- 1.8.5.3 From smueller at chronox.de Sun Mar 9 00:28:25 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 09 Mar 2014 00:28:25 +0100 Subject: [PATCH v2 6/8] DRBG specific gcry_control requests In-Reply-To: <13545738.nuHqZMWCpj@myon.chronox.de> References: <1872704.puni0eUsq8@myon.chronox.de> <1824161.iV8MZ0ufFR@myon.chronox.de> <13545738.nuHqZMWCpj@myon.chronox.de> Message-ID: <278872900.kqS5BSaDt8@myon.chronox.de> gcry_control GCRYCTL_DRBG_REINIT ================================ This control request re-initializes the DRBG completely, i.e. the entire state of the DRBG is zeroized (with two exceptions listed in GCRYCTL_DRBG_SET_ENTROPY). The control request takes the following values which influences how the DRBG is re-initialized: * __u32 flags: This variable specifies the DRBG type to be used for the next initialization. If set to 0, the previous DRBG type is used for the initialization. The DRBG type is an OR of the mandatory flags of the requested DRBG strength and DRBG cipher type. Optionally, the prediction resistance flag can be ORed into the flags variable. For example: - CTR-DRBG with AES-128 without prediction resistance: DRBG_CTRAES128 - HMAC-DRBG with SHA-512 with prediction resistance: DRBG_HMACSHA512 | DRBG_PREDICTION_RESIST * unsigned char *pers: personalization string to be used for initialization. * size_t perslen: Length of personalization string. If set to 0, no personalization string is used for initialization. The variable of flags is independent from the pers/perslen variables. If flags is set to 0 and perslen is set to 0, the current DRBG type is completely reset without using a personalization string. gcry_control GCRYCTL_DRBG_SET_ENTROPY ===================================== This control request sets a predefined "entropy" value. When set, the DRBG does not seed itself from a known seed source, but using that known value. This "entropy" value is not reset even during an initialization! This control request is ONLY intended for testing, especially to implement the FIPS 140-2 CAVS testing. DO NEVER USE IT DURING REGULAR OPERATION. The control request takes the following values: * unsigned char *entropy: string to be used as "entropy" (i.e. the replacement of the data read from the seed source). If this variable is set to NULL, the regular seed source is again used when the DRBG reseeds again. * size_t entropylen: Length of entropy string. Signed-off-by: Stephan Mueller diff --git a/src/global.c b/src/global.c index 4e8df86..3e6f97d 100644 --- a/src/global.c +++ b/src/global.c @@ -671,6 +671,23 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) rc = GPG_ERR_NOT_IMPLEMENTED; break; + case GCRYCTL_DRBG_REINIT: + { + __u64 flags = va_arg (arg_ptr, __u64); + unsigned char *pers = va_arg (arg_ptr, unsigned char *); + size_t perslen = va_arg (arg_ptr, size_t); + rc = _gcry_drbg_reinit(flags, pers, perslen); + } + break; + + case GCRYCTL_DRBG_SET_ENTROPY: + { + unsigned char *entropy = va_arg (arg_ptr, unsigned char *); + size_t entropylen = va_arg (arg_ptr, size_t); + rc = _gcry_drbg_set_entropy(entropy, entropylen); + } + break; + default: _gcry_set_preferred_rng_type (0); rc = GPG_ERR_INV_OP; -- 1.8.5.3 From smueller at chronox.de Sun Mar 9 00:27:44 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 09 Mar 2014 00:27:44 +0100 Subject: [PATCH v2 5/8] Function definitions for gcry_control callbacks In-Reply-To: <1824161.iV8MZ0ufFR@myon.chronox.de> References: <1872704.puni0eUsq8@myon.chronox.de> <2194095.VIrRDhp4Bf@myon.chronox.de> <1824161.iV8MZ0ufFR@myon.chronox.de> Message-ID: <13545738.nuHqZMWCpj@myon.chronox.de> The function definitions implemented in drbg.c which are used for gcry_control. Signed-off-by: Stephan Mueller diff --git a/random/random.h b/random/random.h index 2bc8cab..ba8899e 100644 --- a/random/random.h +++ b/random/random.h @@ -54,7 +54,11 @@ gcry_err_code_t _gcry_random_run_external_test (void *context, char *buffer, size_t buflen); void _gcry_random_deinit_external_test (void *context); - +/*-- drbg.c --*/ +gpg_err_code_t _gcry_drbg_reinit(__u32 flags, + unsigned char *pers, size_t perslen); +gpg_err_code_t _gcry_drbg_set_entropy(unsigned char *entropy, + size_t entropylen); /*-- rndegd.c --*/ gpg_error_t _gcry_rndegd_set_socket_name (const char *name); -- 1.8.5.3 From smueller at chronox.de Sun Mar 9 00:27:05 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 09 Mar 2014 00:27:05 +0100 Subject: [PATCH v2 4/8] Invoke DRBG from common libgcrypt RNG code In-Reply-To: <2194095.VIrRDhp4Bf@myon.chronox.de> References: <1872704.puni0eUsq8@myon.chronox.de> <2605140.C2htjBorAI@myon.chronox.de> <2194095.VIrRDhp4Bf@myon.chronox.de> Message-ID: <1824161.iV8MZ0ufFR@myon.chronox.de> Integrate the DRBG invocation with the common libgcrypt RNG code. This integration replaces the old ANSI X9.31 RNG invocation. As the ANSI X9.31 shall only be invoked in FIPS mode and it is sunset at the end of 2014 for FIPS purposes, a complete replacement with the DRBG is considered appropriate. The DRBG is FIPS approved deterministic random number generator for the forseeable future. Signed-off-by: Stephan Mueller diff --git a/random/random.c b/random/random.c index 41d4cb3..fcb0513 100644 --- a/random/random.c +++ b/random/random.c @@ -140,11 +140,13 @@ void _gcry_random_initialize (int full) { if (fips_mode ()) - _gcry_rngfips_initialize (full); + //_gcry_rngfips_initialize (full); + _gcry_drbg_init(full); else if (rng_types.standard) _gcry_rngcsprng_initialize (full); else if (rng_types.fips) - _gcry_rngfips_initialize (full); + _gcry_drbg_init(full); + //_gcry_rngfips_initialize (full); else if (rng_types.system) _gcry_rngsystem_initialize (full); else @@ -161,11 +163,13 @@ _gcry_random_close_fds (void) the entropy gatherer. */ if (fips_mode ()) - _gcry_rngfips_close_fds (); + //_gcry_rngfips_close_fds (); + _gcry_drbg_close_fds (); else if (rng_types.standard) _gcry_rngcsprng_close_fds (); else if (rng_types.fips) - _gcry_rngfips_close_fds (); + //_gcry_rngfips_close_fds (); + _gcry_drbg_close_fds (); else if (rng_types.system) _gcry_rngsystem_close_fds (); else @@ -199,7 +203,8 @@ void _gcry_random_dump_stats (void) { if (fips_mode ()) - _gcry_rngfips_dump_stats (); + //_gcry_rngfips_dump_stats (); + _gcry_drbg_dump_stats (); else _gcry_rngcsprng_dump_stats (); } @@ -258,7 +263,8 @@ int _gcry_random_is_faked (void) { if (fips_mode ()) - return _gcry_rngfips_is_faked (); + //return _gcry_rngfips_is_faked (); + return _gcry_drbg_is_faked (); else return _gcry_rngcsprng_is_faked (); } @@ -288,11 +294,13 @@ static void do_randomize (void *buffer, size_t length, enum gcry_random_level level) { if (fips_mode ()) - _gcry_rngfips_randomize (buffer, length, level); + //_gcry_rngfips_randomize (buffer, length, level); + _gcry_drbg_randomize (buffer, length, level); else if (rng_types.standard) _gcry_rngcsprng_randomize (buffer, length, level); else if (rng_types.fips) - _gcry_rngfips_randomize (buffer, length, level); + //_gcry_rngfips_randomize (buffer, length, level); + _gcry_drbg_randomize (buffer, length, level); else if (rng_types.system) _gcry_rngsystem_randomize (buffer, length, level); else /* default */ @@ -424,7 +432,8 @@ _gcry_create_nonce (void *buffer, size_t length) nonce generator which is seeded by the RNG actual in use. */ if (fips_mode ()) { - _gcry_rngfips_create_nonce (buffer, length); + //_gcry_rngfips_create_nonce (buffer, length); + _gcry_drbg_randomize (buffer, length, GCRY_WEAK_RANDOM); return; } @@ -501,7 +510,8 @@ gpg_error_t _gcry_random_selftest (selftest_report_func_t report) { if (fips_mode ()) - return _gcry_rngfips_selftest (report); + //return _gcry_rngfips_selftest (report); + return _gcry_drbg_selftest (report); else return 0; /* No selftests yet. */ } @@ -517,6 +527,7 @@ _gcry_random_init_external_test (void **r_context, const void *seed, size_t seedlen, const void *dt, size_t dtlen) { + return GPG_ERR_NOT_SUPPORTED; (void)flags; if (fips_mode ()) return _gcry_rngfips_init_external_test (r_context, flags, key, keylen, @@ -531,6 +542,7 @@ _gcry_random_init_external_test (void **r_context, gcry_err_code_t _gcry_random_run_external_test (void *context, char *buffer, size_t buflen) { + return GPG_ERR_NOT_SUPPORTED; if (fips_mode ()) return _gcry_rngfips_run_external_test (context, buffer, buflen); else @@ -541,6 +553,7 @@ _gcry_random_run_external_test (void *context, char *buffer, size_t buflen) void _gcry_random_deinit_external_test (void *context) { + return; if (fips_mode ()) _gcry_rngfips_deinit_external_test (context); } -- 1.8.5.3 From smueller at chronox.de Sun Mar 9 00:26:19 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 09 Mar 2014 00:26:19 +0100 Subject: [PATCH v2 3/8] Function definitions of interfaces for random.c In-Reply-To: <2605140.C2htjBorAI@myon.chronox.de> References: <1872704.puni0eUsq8@myon.chronox.de> <2160369.gfM6X27d5C@myon.chronox.de> <2605140.C2htjBorAI@myon.chronox.de> Message-ID: <2194095.VIrRDhp4Bf@myon.chronox.de> Specify the function definitions to be integrated into the common libgcrypt RNG code. Signed-off-by: Stephan Mueller diff --git a/random/rand-internal.h b/random/rand-internal.h index 79b23ac..d4c9013 100644 --- a/random/rand-internal.h +++ b/random/rand-internal.h @@ -88,6 +88,15 @@ gcry_err_code_t _gcry_rngfips_run_external_test (void *context, char *buffer, size_t buflen); void _gcry_rngfips_deinit_external_test (void *context); +/* drbg-gcry.h */ +void _gcry_drbg_init(int full); +void _gcry_drbg_close_fds(void); +void _gcry_drbg_dump_stats(void); +int _gcry_drbg_is_faked (void); +gcry_error_t _gcry_drng_add_bytes (const void *buf, size_t buflen, int quality); +void _gcry_drbg_randomize (void *buffer, size_t length, + enum gcry_random_level level); +gcry_error_t _gcry_rngfips_selftest (selftest_report_func_t report); /*-- random-system.c --*/ void _gcry_rngsystem_initialize (int full); -- 1.8.5.3 From smueller at chronox.de Sun Mar 9 00:25:40 2014 From: smueller at chronox.de (Stephan Mueller) Date: Sun, 09 Mar 2014 00:25:40 +0100 Subject: [PATCH v2 2/8] Compile DRBG In-Reply-To: <2160369.gfM6X27d5C@myon.chronox.de> References: <1872704.puni0eUsq8@myon.chronox.de> <2160369.gfM6X27d5C@myon.chronox.de> Message-ID: <2605140.C2htjBorAI@myon.chronox.de> Add the drbg.c file to the Makefile. Signed-off-by: Stephan Mueller diff --git a/random/Makefile.am b/random/Makefile.am index c9d587a..e073fa4 100644 --- a/random/Makefile.am +++ b/random/Makefile.am @@ -35,6 +35,7 @@ random.c random.h \ rand-internal.h \ random-csprng.c \ random-fips.c \ +drbg.c \ random-system.c \ rndhw.c -- 1.8.5.3 From dbaryshkov at gmail.com Tue Mar 11 18:53:05 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Tue, 11 Mar 2014 21:53:05 +0400 Subject: [PATCH] Add MD2 message digest implementation Message-ID: <1394560385-4264-1-git-send-email-dbaryshkov@gmail.com> * cipher/md2.c: New. * cipher/md.c (digest_list): add _gcry_digest_spec_md2. * tests/basic.c (check_digests): add MD2 test vectors. * configure.ac (default_digests): disable md2 by default. Signed-off-by: Dmitry Eremin-Solenikov --- I was playing with old certificates and thus I needed MD2 algorithm. Contributing it to libgcrypt now. Disabled by default for security considerations. cipher/md.c | 3 ++ cipher/md2.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 10 +++- src/cipher.h | 1 + tests/basic.c | 6 +++ 5 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 cipher/md2.c diff --git a/cipher/md.c b/cipher/md.c index a332e03..461ad64 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -75,6 +75,9 @@ static gcry_md_spec_t *digest_list[] = #if USE_MD4 &_gcry_digest_spec_md4, #endif +#if USE_MD2 + &_gcry_digest_spec_md2, +#endif NULL }; diff --git a/cipher/md2.c b/cipher/md2.c new file mode 100644 index 0000000..f9171c8 --- /dev/null +++ b/cipher/md2.c @@ -0,0 +1,158 @@ +/* md2.c - MD2 Message-Digest Algorithm + * Copyright (C) 2014 Dmitry Eremin-Solenikov + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "g10lib.h" +#include "cipher.h" + +#include "bithelp.h" +#include "bufhelp.h" +#include "hash-common.h" + +typedef struct { + gcry_md_block_ctx_t bctx; + unsigned char C[16]; + unsigned char L; + unsigned char X[48]; +} MD2_CONTEXT; + +static const unsigned char S[] = { + 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, + 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA, + 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, + 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A, + 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, + 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, + 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6, + 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, + 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02, + 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, + 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, + 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52, + 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, + 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39, + 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, + 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14 +}; + +static void permute(unsigned char *X, const unsigned char *buf) +{ + int i, j; + unsigned char t; + memcpy(X+16, buf, 16); + for (i = 0; i < 16; i++) + X[32+i] = X[16+i] ^ X[i]; + t = 0; + for (i = 0; i < 18; i++) + { + for (j = 0; j < 48; j++) + { + t = X[j] ^ S[t]; + X[j] = t; + } + t += i; + } +} + + +static unsigned int +transform_blk ( void *c, const unsigned char *data ) +{ + MD2_CONTEXT *ctx = c; + int j; + + for (j = 0; j < 16; j++) + { + ctx->C[j] ^= S[data[j] ^ ctx->L]; + ctx->L = ctx->C[j]; + } + + permute(ctx->X, data); + + return /* burn stack */ 4 + 5 * sizeof(void*); +} + +static unsigned int +transform ( void *c, const unsigned char *data, size_t nblks ) +{ + unsigned int burn; + + do + { + burn = transform_blk (c, data); + data += 64; + } + while (--nblks); + + return burn; +} + +static void +md2_init( void *context, unsigned int flags) +{ + MD2_CONTEXT *ctx = context; + + (void)flags; + + memset (ctx, 0, sizeof(*ctx)); + ctx->bctx.blocksize = 16; + ctx->bctx.bwrite = transform; +} + +static void +md2_final( void *context) +{ + MD2_CONTEXT *hd = context; + unsigned int burn; + + _gcry_md_block_write(hd, NULL, 0); /* flush */; + + /* pad */ + memset (hd->bctx.buf + hd->bctx.count, 16 - hd->bctx.count, 16 - hd->bctx.count); + burn = transform_blk (hd, hd->bctx.buf); + permute (hd->X, hd->C); +} + +static byte * +md2_read( void *context ) +{ + MD2_CONTEXT *hd = (MD2_CONTEXT *) context; + return hd->X; +} + +static byte asn[18] = /* Object ID is 1.2.840.113549.2.2 */ + { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48, + 0x86, 0xf7, 0x0d, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10 }; + +static gcry_md_oid_spec_t oid_spec_md2[] = + { + /* iso.member-body.us.rsadsi.digestAlgorithm.md2 */ + { "1.2.840.113549.2.2" }, + { NULL }, + }; + +gcry_md_spec_t _gcry_digest_spec_md2 = + { + GCRY_MD_MD2, {0, 0}, + "MD2", asn, DIM (asn), oid_spec_md2, 16, + md2_init, _gcry_md_block_write, md2_final, md2_read, + sizeof (MD2_CONTEXT) + }; diff --git a/configure.ac b/configure.ac index a447859..a0f75a5 100644 --- a/configure.ac +++ b/configure.ac @@ -194,7 +194,7 @@ available_pubkey_ciphers="dsa elgamal rsa ecc" enabled_pubkey_ciphers="" # Definitions for message digests. -available_digests="crc gostr3411-94 md4 md5 rmd160 sha1 sha256" +available_digests="crc gostr3411-94 md2 md4 md5 rmd160 sha1 sha256" available_digests_64="sha512 tiger whirlpool stribog" enabled_digests="" @@ -377,6 +377,8 @@ default_ciphers="$available_ciphers" default_pubkey_ciphers="$available_pubkey_ciphers" default_digests="$available_digests" default_kdfs="$available_kdfs" +# Blacklist MD2 by default +default_digests=`echo $default_digests | sed -e 's/md2//g'` # Substitutions to set generated files in a Emacs buffer to read-only. AC_SUBST(emacs_local_vars_begin, ['Local Variables:']) @@ -1845,6 +1847,12 @@ if test "$found" = "1" ; then AC_DEFINE(USE_GOST_R_3411_12, 1, [Defined if this module should be included]) fi +LIST_MEMBER(md2, $enabled_digests) +if test "$found" = "1" ; then + GCRYPT_DIGESTS="$GCRYPT_DIGESTS md2.lo" + AC_DEFINE(USE_MD2, 1, [Defined if this module should be included]) +fi + LIST_MEMBER(md4, $enabled_digests) if test "$found" = "1" ; then GCRYPT_DIGESTS="$GCRYPT_DIGESTS md4.lo" diff --git a/src/cipher.h b/src/cipher.h index 26ffddc..cd981b3 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -246,6 +246,7 @@ extern gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440; extern gcry_md_spec_t _gcry_digest_spec_gost3411_94; extern gcry_md_spec_t _gcry_digest_spec_stribog_256; extern gcry_md_spec_t _gcry_digest_spec_stribog_512; +extern gcry_md_spec_t _gcry_digest_spec_md2; extern gcry_md_spec_t _gcry_digest_spec_md4; extern gcry_md_spec_t _gcry_digest_spec_md5; extern gcry_md_spec_t _gcry_digest_spec_rmd160; diff --git a/tests/basic.c b/tests/basic.c index e21e055..5abedb3 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -3784,6 +3784,12 @@ check_digests (void) const char *expect; } algos[] = { + { GCRY_MD_MD2, "", + "\x83\x50\xe5\xa3\xe2\x4c\x15\x3d\xf2\x27\x5c\x9f\x80\x69\x27\x73" }, + { GCRY_MD_MD2, "a", + "\x32\xec\x01\xec\x4a\x6d\xac\x72\xc0\xab\x96\xfb\x34\xc0\xb5\xd1"}, + { GCRY_MD_MD2, "message digest", + "\xab\x4f\x49\x6b\xfb\x2a\x53\x0b\x21\x9f\xf3\x30\x31\xfe\x06\xb0"}, { GCRY_MD_MD4, "", "\x31\xD6\xCF\xE0\xD1\x6A\xE9\x31\xB7\x3C\x59\xD7\xE0\xC0\x89\xC0" }, { GCRY_MD_MD4, "a", -- 1.9.0 From cvs at cvs.gnupg.org Tue Mar 11 22:08:51 2014 From: cvs at cvs.gnupg.org (by Dmitry Eremin-Solenikov) Date: Tue, 11 Mar 2014 22:08:51 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-59-g5a8e150 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 5a8e1504bf8a2ffbc018be576dea77b685200444 (commit) from 2b5403c408dfbd71be24c7635f5fa0b61ab4c9bb (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 5a8e1504bf8a2ffbc018be576dea77b685200444 Author: Dmitry Eremin-Solenikov Date: Tue Mar 11 21:53:05 2014 +0400 Add MD2 message digest implementation * cipher/md2.c: New. * cipher/md.c (digest_list): add _gcry_digest_spec_md2. * tests/basic.c (check_digests): add MD2 test vectors. * configure.ac (default_digests): disable md2 by default. -- Signed-off-by: Dmitry Eremin-Solenikov Some minor indentation fixes by wk. diff --git a/cipher/md.c b/cipher/md.c index a332e03..461ad64 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -75,6 +75,9 @@ static gcry_md_spec_t *digest_list[] = #if USE_MD4 &_gcry_digest_spec_md4, #endif +#if USE_MD2 + &_gcry_digest_spec_md2, +#endif NULL }; diff --git a/cipher/md2.c b/cipher/md2.c new file mode 100644 index 0000000..97682e5 --- /dev/null +++ b/cipher/md2.c @@ -0,0 +1,182 @@ +/* md2.c - MD2 Message-Digest Algorithm + * Copyright (C) 2014 Dmitry Eremin-Solenikov + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include "g10lib.h" +#include "cipher.h" + +#include "bithelp.h" +#include "bufhelp.h" +#include "hash-common.h" + +typedef struct { + gcry_md_block_ctx_t bctx; + unsigned char C[16]; + unsigned char L; + unsigned char X[48]; +} MD2_CONTEXT; + +static const unsigned char S[] = + { + 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, + 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, + 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, + 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA, + 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, + 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, + 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, + 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A, + 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, + 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, + 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, + 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, + 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, + 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6, + 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, + 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, + 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, + 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02, + 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, + 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, + 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, + 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, + 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09, + 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52, + 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, + 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, + 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, + 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39, + 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, + 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, + 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, + 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14 +}; + + +static void +permute (unsigned char *X, const unsigned char *buf) +{ + int i, j; + unsigned char t; + + memcpy (X+16, buf, 16); + for (i = 0; i < 16; i++) + X[32+i] = X[16+i] ^ X[i]; + t = 0; + for (i = 0; i < 18; i++) + { + for (j = 0; j < 48; j++) + { + t = X[j] ^ S[t]; + X[j] = t; + } + t += i; + } +} + + +static unsigned int +transform_blk (void *c, const unsigned char *data) +{ + MD2_CONTEXT *ctx = c; + int j; + + for (j = 0; j < 16; j++) + { + ctx->C[j] ^= S[data[j] ^ ctx->L]; + ctx->L = ctx->C[j]; + } + + permute(ctx->X, data); + + return /* burn stack */ 4 + 5 * sizeof(void*); +} + + +static unsigned int +transform ( void *c, const unsigned char *data, size_t nblks ) +{ + unsigned int burn; + + do + { + burn = transform_blk (c, data); + data += 64; + } + while (--nblks); + + return burn; +} + + +static void +md2_init (void *context, unsigned int flags) +{ + MD2_CONTEXT *ctx = context; + + (void)flags; + + memset (ctx, 0, sizeof(*ctx)); + ctx->bctx.blocksize = 16; + ctx->bctx.bwrite = transform; +} + + +static void +md2_final (void *context) +{ + MD2_CONTEXT *hd = context; + unsigned int burn; + + _gcry_md_block_write(hd, NULL, 0); /* flush */; + + /* pad */ + memset (hd->bctx.buf + hd->bctx.count, + 16 - hd->bctx.count, 16 - hd->bctx.count); + burn = transform_blk (hd, hd->bctx.buf); + permute (hd->X, hd->C); +} + +static byte * +md2_read (void *context) +{ + MD2_CONTEXT *hd = (MD2_CONTEXT *) context; + return hd->X; +} + +static byte asn[18] = /* Object ID is 1.2.840.113549.2.2 */ + { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48, + 0x86, 0xf7, 0x0d, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10 }; + +static gcry_md_oid_spec_t oid_spec_md2[] = + { + /* iso.member-body.us.rsadsi.digestAlgorithm.md2 */ + { "1.2.840.113549.2.2" }, + { NULL }, + }; + +gcry_md_spec_t _gcry_digest_spec_md2 = + { + GCRY_MD_MD2, {0, 0}, + "MD2", asn, DIM (asn), oid_spec_md2, 16, + md2_init, _gcry_md_block_write, md2_final, md2_read, + sizeof (MD2_CONTEXT) + }; diff --git a/configure.ac b/configure.ac index a447859..a0f75a5 100644 --- a/configure.ac +++ b/configure.ac @@ -194,7 +194,7 @@ available_pubkey_ciphers="dsa elgamal rsa ecc" enabled_pubkey_ciphers="" # Definitions for message digests. -available_digests="crc gostr3411-94 md4 md5 rmd160 sha1 sha256" +available_digests="crc gostr3411-94 md2 md4 md5 rmd160 sha1 sha256" available_digests_64="sha512 tiger whirlpool stribog" enabled_digests="" @@ -377,6 +377,8 @@ default_ciphers="$available_ciphers" default_pubkey_ciphers="$available_pubkey_ciphers" default_digests="$available_digests" default_kdfs="$available_kdfs" +# Blacklist MD2 by default +default_digests=`echo $default_digests | sed -e 's/md2//g'` # Substitutions to set generated files in a Emacs buffer to read-only. AC_SUBST(emacs_local_vars_begin, ['Local Variables:']) @@ -1845,6 +1847,12 @@ if test "$found" = "1" ; then AC_DEFINE(USE_GOST_R_3411_12, 1, [Defined if this module should be included]) fi +LIST_MEMBER(md2, $enabled_digests) +if test "$found" = "1" ; then + GCRYPT_DIGESTS="$GCRYPT_DIGESTS md2.lo" + AC_DEFINE(USE_MD2, 1, [Defined if this module should be included]) +fi + LIST_MEMBER(md4, $enabled_digests) if test "$found" = "1" ; then GCRYPT_DIGESTS="$GCRYPT_DIGESTS md4.lo" diff --git a/src/cipher.h b/src/cipher.h index 26ffddc..cd981b3 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -246,6 +246,7 @@ extern gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440; extern gcry_md_spec_t _gcry_digest_spec_gost3411_94; extern gcry_md_spec_t _gcry_digest_spec_stribog_256; extern gcry_md_spec_t _gcry_digest_spec_stribog_512; +extern gcry_md_spec_t _gcry_digest_spec_md2; extern gcry_md_spec_t _gcry_digest_spec_md4; extern gcry_md_spec_t _gcry_digest_spec_md5; extern gcry_md_spec_t _gcry_digest_spec_rmd160; diff --git a/tests/basic.c b/tests/basic.c index e21e055..0eb0f77 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -3784,6 +3784,12 @@ check_digests (void) const char *expect; } algos[] = { + { GCRY_MD_MD2, "", + "\x83\x50\xe5\xa3\xe2\x4c\x15\x3d\xf2\x27\x5c\x9f\x80\x69\x27\x73" }, + { GCRY_MD_MD2, "a", + "\x32\xec\x01\xec\x4a\x6d\xac\x72\xc0\xab\x96\xfb\x34\xc0\xb5\xd1" }, + { GCRY_MD_MD2, "message digest", + "\xab\x4f\x49\x6b\xfb\x2a\x53\x0b\x21\x9f\xf3\x30\x31\xfe\x06\xb0" }, { GCRY_MD_MD4, "", "\x31\xD6\xCF\xE0\xD1\x6A\xE9\x31\xB7\x3C\x59\xD7\xE0\xC0\x89\xC0" }, { GCRY_MD_MD4, "a", ----------------------------------------------------------------------- Summary of changes: cipher/md.c | 3 + cipher/md2.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 10 +++- src/cipher.h | 1 + tests/basic.c | 6 ++ 5 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 cipher/md2.c 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 Tue Mar 11 22:05:25 2014 From: wk at gnupg.org (Werner Koch) Date: Tue, 11 Mar 2014 22:05:25 +0100 Subject: [PATCH] Add MD2 message digest implementation In-Reply-To: <1394560385-4264-1-git-send-email-dbaryshkov@gmail.com> (Dmitry Eremin-Solenikov's message of "Tue, 11 Mar 2014 21:53:05 +0400") References: <1394560385-4264-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <87vbvk8mzu.fsf@vigenere.g10code.de> Hi, I pushed your changes after some minor indentation fixes. However, the test vectors are failing on my amd64. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From dbaryshkov at gmail.com Tue Mar 11 22:59:35 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Wed, 12 Mar 2014 01:59:35 +0400 Subject: [PATCH] Add MD2 message digest implementation In-Reply-To: <87vbvk8mzu.fsf@vigenere.g10code.de> References: <1394560385-4264-1-git-send-email-dbaryshkov@gmail.com> <87vbvk8mzu.fsf@vigenere.g10code.de> Message-ID: Hello, On Wed, Mar 12, 2014 at 1:05 AM, Werner Koch wrote: > Hi, > > I pushed your changes after some minor indentation fixes. However, the > test vectors are failing on my amd64. I will check tomorrow on amd64/ppc64 boards. -- With best wishes Dmitry From dbaryshkov at gmail.com Wed Mar 12 19:10:22 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Wed, 12 Mar 2014 22:10:22 +0400 Subject: [PATCH] Limit digest checks to enabled algorithms Message-ID: <1394647822-23765-1-git-send-email-dbaryshkov@gmail.com> * tests/basic.c (check_digests): put #ifdef USE_xxx around checks to disable checks for algorithms being compiled out. Signed-off-by: Dmitry Eremin-Solenikov --- The actual error was triggered by md2 algo which is disabled by default. tests/basic.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/basic.c b/tests/basic.c index 0eb0f77..ebfe5ee 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -3784,18 +3784,23 @@ check_digests (void) const char *expect; } algos[] = { +#ifdef USE_MD2 { GCRY_MD_MD2, "", "\x83\x50\xe5\xa3\xe2\x4c\x15\x3d\xf2\x27\x5c\x9f\x80\x69\x27\x73" }, { GCRY_MD_MD2, "a", "\x32\xec\x01\xec\x4a\x6d\xac\x72\xc0\xab\x96\xfb\x34\xc0\xb5\xd1" }, { GCRY_MD_MD2, "message digest", "\xab\x4f\x49\x6b\xfb\x2a\x53\x0b\x21\x9f\xf3\x30\x31\xfe\x06\xb0" }, +#endif +#ifdef USE_MD4 { GCRY_MD_MD4, "", "\x31\xD6\xCF\xE0\xD1\x6A\xE9\x31\xB7\x3C\x59\xD7\xE0\xC0\x89\xC0" }, { GCRY_MD_MD4, "a", "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46\x24\x5e\x05\xfb\xdb\xd6\xfb\x24" }, { GCRY_MD_MD4, "message digest", "\xd9\x13\x0a\x81\x64\x54\x9f\xe8\x18\x87\x48\x06\xe1\xc7\x01\x4b" }, +#endif +#ifdef USE_MD5 { GCRY_MD_MD5, "", "\xD4\x1D\x8C\xD9\x8F\x00\xB2\x04\xE9\x80\x09\x98\xEC\xF8\x42\x7E" }, { GCRY_MD_MD5, "a", @@ -3804,6 +3809,8 @@ check_digests (void) "\x90\x01\x50\x98\x3C\xD2\x4F\xB0\xD6\x96\x3F\x7D\x28\xE1\x7F\x72" }, { GCRY_MD_MD5, "message digest", "\xF9\x6B\x69\x7D\x7C\xB7\x93\x8D\x52\x5A\x2F\x31\xAA\xF1\x61\xD0" }, +#endif +#ifdef USE_SHA1 { GCRY_MD_SHA1, "abc", "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E" "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D" }, @@ -3814,6 +3821,8 @@ check_digests (void) { GCRY_MD_SHA1, "!" /* kludge for "a"*1000000 */ , "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E" "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F" }, +#endif +#ifdef USE_SHA256 /* From RFC3874 */ { GCRY_MD_SHA224, "abc", "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3" @@ -3835,6 +3844,8 @@ check_digests (void) { GCRY_MD_SHA256, "!", "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67" "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0" }, +#endif +#ifdef USE_SHA512 { GCRY_MD_SHA384, "abc", "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07" "\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed" @@ -3844,6 +3855,8 @@ check_digests (void) "\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A" "\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD" "\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F" }, +#endif +#ifdef USE_RMD160 { GCRY_MD_RMD160, "", "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28" "\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31" }, @@ -3856,6 +3869,8 @@ check_digests (void) { GCRY_MD_RMD160, "message digest", "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8" "\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36" }, +#endif +#ifdef USE_CRC { GCRY_MD_CRC32, "", "\x00\x00\x00\x00" }, { GCRY_MD_CRC32, "foo", "\x8c\x73\x65\x21" }, { GCRY_MD_CRC32_RFC1510, "", "\x00\x00\x00\x00" }, @@ -3875,7 +3890,9 @@ check_digests (void) #endif { GCRY_MD_CRC24_RFC2440, "", "\xb7\x04\xce" }, { GCRY_MD_CRC24_RFC2440, "foo", "\x4f\xc2\x55" }, +#endif +#ifdef USE_TIGER { GCRY_MD_TIGER, "", "\x24\xF0\x13\x0C\x63\xAC\x93\x32\x16\x16\x6E\x76" "\xB1\xBB\x92\x5F\xF3\x73\xDE\x2D\x49\x58\x4E\x7A" }, @@ -3978,7 +3995,9 @@ check_digests (void) { GCRY_MD_TIGER2, "!", "\xE0\x68\x28\x1F\x06\x0F\x55\x16\x28\xCC\x57\x15" "\xB9\xD0\x22\x67\x96\x91\x4D\x45\xF7\x71\x7C\xF4" }, +#endif +#ifdef USE_WHIRLPOOL { GCRY_MD_WHIRLPOOL, "", "\x19\xFA\x61\xD7\x55\x22\xA4\x66\x9B\x44\xE3\x9C\x1D\x2E\x17\x26" "\xC5\x30\x23\x21\x30\xD4\x07\xF8\x9A\xFE\xE0\x96\x49\x97\xF7\xA7" @@ -4006,6 +4025,7 @@ check_digests (void) "\x29\x05\x7F\xD8\x6B\x20\xBF\xD6\x2D\xEC\xA0\xF1\xCC\xEA\x4A\xF5" "\x1F\xC1\x54\x90\xED\xDC\x47\xAF\x32\xBB\x2B\x66\xC3\x4F\xF9\xAD" "\x8C\x60\x08\xAD\x67\x7F\x77\x12\x69\x53\xB2\x26\xE4\xED\x8B\x01" }, +#endif #ifdef USE_GOST_R_3411_94 { GCRY_MD_GOSTR3411_94, "This is message, length=32 bytes", -- 1.9.0 From wk at gnupg.org Thu Mar 13 11:43:17 2014 From: wk at gnupg.org (Werner Koch) Date: Thu, 13 Mar 2014 11:43:17 +0100 Subject: [PATCH] Limit digest checks to enabled algorithms In-Reply-To: <1394647822-23765-1-git-send-email-dbaryshkov@gmail.com> (Dmitry Eremin-Solenikov's message of "Wed, 12 Mar 2014 22:10:22 +0400") References: <1394647822-23765-1-git-send-email-dbaryshkov@gmail.com> Message-ID: <87siqm5qgq.fsf@vigenere.g10code.de> On Wed, 12 Mar 2014 19:10, dbaryshkov at gmail.com said: > * tests/basic.c (check_digests): put #ifdef USE_xxx around checks to > disable checks for algorithms being compiled out. I do not think this is a good idea. It would be too easy to accidently skip a test for an algorithm which is actually included. A runtime tests seems to be better. I did it this way: PASS: t-lock PASS: prime hash algorithm 5 not available - skipping tests hash algorithm 5 not available - skipping tests hash algorithm 5 not available - skipping tests PASS: basic PASS: keygen By inspecting the test output you would immediately notice that an algtoithm was not tested. I consider disabling algorithms an exception and thus the diagnostics won't harm. For MD2 I would silent the diagnotics, though. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From cvs at cvs.gnupg.org Thu Mar 13 12:06:08 2014 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 13 Mar 2014 12:06:08 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-60-g50aeee5 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 50aeee51a0b1a09dd9fff2bb71749a816fe7a791 (commit) from 5a8e1504bf8a2ffbc018be576dea77b685200444 (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 50aeee51a0b1a09dd9fff2bb71749a816fe7a791 Author: Werner Koch Date: Thu Mar 13 12:06:55 2014 +0100 tests: Print diagnostics for skipped tests. * tests/basic.c (show_note): New. (show_md_not_available): (show_old_hmac_not_available): (show_mac_not_available): (check_digests): Remove USE_foo cpp tests from the test table. Call show_md_not_available if algo is not available. (check_hmac): Likewise. (check_mac): Likewise. Signed-off-by: Werner Koch diff --git a/tests/basic.c b/tests/basic.c index 0eb0f77..5c6c51c 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -34,6 +34,7 @@ # define DIM(v) (sizeof(v)/sizeof((v)[0])) #endif +#define PGM "basic" typedef struct test_spec_pubkey_key { @@ -118,6 +119,82 @@ show_sexp (const char *prefix, gcry_sexp_t a) } +static void +show_note (const char *format, ...) +{ + va_list arg_ptr; + + if (!verbose && getenv ("srcdir")) + fputs (" ", stderr); /* To align above "PASS: ". */ + else + fprintf (stderr, "%s: ", PGM); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + if (*format && format[strlen(format)-1] != '\n') + putc ('\n', stderr); + va_end (arg_ptr); +} + + +static void +show_md_not_available (int algo) +{ + static int list[100]; + static int listlen; + int i; + + if (!verbose && algo == GCRY_MD_MD2) + return; /* Do not print the diagnostic for that one. */ + + for (i=0; i < listlen; i++) + if (algo == list[i]) + return; /* Note already printed. */ + if (listlen < DIM (list)) + list[listlen++] = algo; + show_note ("hash algorithm %d not available - skipping tests", algo); +} + + +static void +show_old_hmac_not_available (int algo) +{ + static int list[100]; + static int listlen; + int i; + + if (!verbose && algo == GCRY_MD_MD2) + return; /* Do not print the diagnostic for that one. */ + + for (i=0; i < listlen; i++) + if (algo == list[i]) + return; /* Note already printed. */ + if (listlen < DIM (list)) + list[listlen++] = algo; + show_note ("hash algorithm %d for old HMAC API not available " + "- skipping tests", algo); +} + + +static void +show_mac_not_available (int algo) +{ + static int list[100]; + static int listlen; + int i; + + if (!verbose && algo == GCRY_MD_MD2) + return; /* Do not print the diagnostic for that one. */ + + for (i=0; i < listlen; i++) + if (algo == list[i]) + return; /* Note already printed. */ + if (listlen < DIM (list)) + list[listlen++] = algo; + show_note ("MAC algorithm %d not available - skipping tests", algo); +} + + + #define MAX_DATA_LEN 100 void @@ -4006,7 +4083,6 @@ check_digests (void) "\x29\x05\x7F\xD8\x6B\x20\xBF\xD6\x2D\xEC\xA0\xF1\xCC\xEA\x4A\xF5" "\x1F\xC1\x54\x90\xED\xDC\x47\xAF\x32\xBB\x2B\x66\xC3\x4F\xF9\xAD" "\x8C\x60\x08\xAD\x67\x7F\x77\x12\x69\x53\xB2\x26\xE4\xED\x8B\x01" }, -#ifdef USE_GOST_R_3411_94 { GCRY_MD_GOSTR3411_94, "This is message, length=32 bytes", "\xB1\xC4\x66\xD3\x75\x19\xB8\x2E\x83\x19\x81\x9F\xF3\x25\x95\xE0" @@ -4023,8 +4099,6 @@ check_digests (void) "!", "\x5C\x00\xCC\xC2\x73\x4C\xDD\x33\x32\xD3\xD4\x74\x95\x76\xE3\xC1" "\xA7\xDB\xAF\x0E\x7E\xA7\x4E\x9F\xA6\x02\x41\x3C\x90\xA1\x29\xFA" }, -#endif -#ifdef USE_GOST_R_3411_12 { GCRY_MD_STRIBOG512, "012345678901234567890123456789012345678901234567890123456789012", "\x1b\x54\xd0\x1a\x4a\xf5\xb9\xd5\xcc\x3d\x86\xd6\x8d\x28\x54\x62" @@ -4053,7 +4127,6 @@ check_digests (void) "\x20\xc8\xe3\xee\xf0\xe5\xe2\xfb", "\x9d\xd2\xfe\x4e\x90\x40\x9e\x5d\xa8\x7f\x53\x97\x6d\x74\x05\xb0" "\xc0\xca\xc6\x28\xfc\x66\x9a\x74\x1d\x50\x06\x3c\x55\x7e\x8f\x50" }, -#endif { 0 } }; gcry_error_t err; @@ -4064,6 +4137,11 @@ check_digests (void) for (i = 0; algos[i].md; i++) { + if (gcry_md_test_algo (algos[i].md)) + { + show_md_not_available (algos[i].md); + continue; + } if ((gcry_md_test_algo (algos[i].md) || algos[i].md == GCRY_MD_MD5) && in_fips_mode) { @@ -4488,6 +4566,11 @@ check_hmac (void) for (i = 0; algos[i].md; i++) { + if (gcry_md_test_algo (algos[i].md)) + { + show_old_hmac_not_available (algos[i].md); + continue; + } if ((gcry_md_test_algo (algos[i].md) || algos[i].md == GCRY_MD_MD5) && in_fips_mode) { @@ -5091,6 +5174,11 @@ check_mac (void) for (i = 0; algos[i].algo; i++) { + if (gcry_mac_test_algo (algos[i].algo)) + { + show_mac_not_available (algos[i].algo); + continue; + } if ((gcry_mac_test_algo (algos[i].algo) || algos[i].algo == GCRY_MAC_HMAC_MD5) && in_fips_mode) { ----------------------------------------------------------------------- Summary of changes: tests/basic.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From dbaryshkov at gmail.com Thu Mar 13 12:19:18 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Thu, 13 Mar 2014 15:19:18 +0400 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-60-g50aeee5 In-Reply-To: References: Message-ID: On Thu, Mar 13, 2014 at 3:06 PM, by Werner Koch wrote: [skipped] > @@ -4064,6 +4137,11 @@ check_digests (void) > > for (i = 0; algos[i].md; i++) > { > + if (gcry_md_test_algo (algos[i].md)) > + { > + show_md_not_available (algos[i].md); > + continue; > + } > if ((gcry_md_test_algo (algos[i].md) || algos[i].md == GCRY_MD_MD5) > && in_fips_mode) > { Will the code ever hit the in_fips_mode check? I assume not. The same issue applies to the rest of hunks. -- With best wishes Dmitry From wk at gnupg.org Thu Mar 13 14:32:16 2014 From: wk at gnupg.org (Werner Koch) Date: Thu, 13 Mar 2014 14:32:16 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-60-g50aeee5 In-Reply-To: (Dmitry Eremin-Solenikov's message of "Thu, 13 Mar 2014 15:19:18 +0400") References: Message-ID: <874n325in3.fsf@vigenere.g10code.de> On Thu, 13 Mar 2014 12:19, dbaryshkov at gmail.com said: >> if ((gcry_md_test_algo (algos[i].md) || algos[i].md == GCRY_MD_MD5) >> && in_fips_mode) >> { > > Will the code ever hit the in_fips_mode check? I assume not. Yes - at least once. If we are not in enforced FIPS mode the use of MD will inactivate the FIPS mode. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From dbaryshkov at gmail.com Thu Mar 13 14:44:03 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Thu, 13 Mar 2014 17:44:03 +0400 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-60-g50aeee5 In-Reply-To: <874n325in3.fsf@vigenere.g10code.de> References: <874n325in3.fsf@vigenere.g10code.de> Message-ID: On Thu, Mar 13, 2014 at 5:32 PM, Werner Koch wrote: > On Thu, 13 Mar 2014 12:19, dbaryshkov at gmail.com said: > >>> if ((gcry_md_test_algo (algos[i].md) || algos[i].md == GCRY_MD_MD5) >>> && in_fips_mode) >>> { >> >> Will the code ever hit the in_fips_mode check? I assume not. > > Yes - at least once. If we are not in enforced FIPS mode the use of MD > will inactivate the FIPS mode. Please excuse me if I'm wrong - too tired ATM. But before this condition you already have if (gcry_md_test_algo(algo)) { ... continue; } Thus if algo is disabled, you will go to next iteration w/o entering in_fips_mode check. -- With best wishes Dmitry From wk at gnupg.org Thu Mar 13 16:00:20 2014 From: wk at gnupg.org (Werner Koch) Date: Thu, 13 Mar 2014 16:00:20 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-60-g50aeee5 In-Reply-To: (Dmitry Eremin-Solenikov's message of "Thu, 13 Mar 2014 17:44:03 +0400") References: <874n325in3.fsf@vigenere.g10code.de> Message-ID: <87vbvi16uz.fsf@vigenere.g10code.de> On Thu, 13 Mar 2014 14:44, dbaryshkov at gmail.com said: > Thus if algo is disabled, you will go to next iteration w/o entering > in_fips_mode check. Sure. But what is the problem? Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From smueller at chronox.de Wed Mar 19 08:39:32 2014 From: smueller at chronox.de (Stephan Mueller) Date: Wed, 19 Mar 2014 08:39:32 +0100 Subject: [PATCH v3 6/7] DRBG specific gcry_control requests In-Reply-To: <1724976.NSVTLKdB6h@myon.chronox.de> References: <1573675.V5Uuq2JQxy@myon.chronox.de> <2634969.OgzocTu08g@myon.chronox.de> <1724976.NSVTLKdB6h@myon.chronox.de> Message-ID: <10261421.mqYxKu9qld@myon.chronox.de> gcry_control GCRYCTL_DRBG_REINIT ================================ This control request re-initializes the DRBG completely, i.e. the entire state of the DRBG is zeroized (with two exceptions listed in GCRYCTL_DRBG_SET_ENTROPY). The control request takes the following values which influences how the DRBG is re-initialized: * __u32 flags: This variable specifies the DRBG type to be used for the next initialization. If set to 0, the previous DRBG type is used for the initialization. The DRBG type is an OR of the mandatory flags of the requested DRBG strength and DRBG cipher type. Optionally, the prediction resistance flag can be ORed into the flags variable. For example: - CTR-DRBG with AES-128 without prediction resistance: DRBG_CTRAES128 - HMAC-DRBG with SHA-512 with prediction resistance: DRBG_HMACSHA512 | DRBG_PREDICTION_RESIST * struct drbg_string *pers: personalization string to be used for initialization. * struct drbg_test_data *test: TEST parameter only -- should be NULL in normal use -- parameter sets predefined "entropy" The variable of flags is independent from the pers/perslen variables. If flags is set to 0 and perslen is set to 0, the current DRBG type is completely reset without using a personalization string. Changes v3: * addition of struct drbg_test_data *test to reinit call * change personalization string invocation to struct drbg_string * remove set_entropy call Signed-off-by: Stephan Mueller --- diff --git a/src/global.c b/src/global.c index 4e8df86..5c19cca 100644 --- a/src/global.c +++ b/src/global.c @@ -671,6 +671,15 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) rc = GPG_ERR_NOT_IMPLEMENTED; break; + case GCRYCTL_DRBG_REINIT: + { + u_int32_t flags = va_arg (arg_ptr, u_int32_t); + struct drbg_string *pers = va_arg (arg_ptr, struct drbg_string *); + struct drbg_test_data *test_data = va_arg (arg_ptr, struct drbg_test_data *); + rc = _gcry_drbg_reinit(flags, pers, test_data); + } + break; + default: _gcry_set_preferred_rng_type (0); rc = GPG_ERR_INV_OP; From smueller at chronox.de Wed Mar 19 08:25:43 2014 From: smueller at chronox.de (Stephan Mueller) Date: Wed, 19 Mar 2014 08:25:43 +0100 Subject: [PATCH v3 0/7] SP800-90A Deterministic Random Bit Generator Message-ID: <1573675.V5Uuq2JQxy@myon.chronox.de> Hi, the following set of patches against the current GIT development tree of libgcrypt implements the SP800-90A DRBG and integrates it with libgcrypt. Changes v2: * reorganizing DRBG code to make it leaner * steamlining user interface Thanks to Rafael Aquini for comments. Stephan Mueller (8): SP800-90A Deterministic Random Bit Generator Compile DRBG Function definitions of interfaces for random.c Invoke DRBG from common libgcrypt RNG code Function definitions for gcry_control callbacks DRBG specific gcry_control requests User interface to DRBG Makefile.am | 4 +- configure.ac | 1 - random/Makefile.am | 1 + random/drbg.c | 2257 +++++++++++++++++++++++++++++++++++++++++++++++++++ random/rand-internal.h | 9 + random/random.c | 33 +- random/random.h | 4 +- src/gcrypt.h.in | 157 +++- src/global.c | 9 + 9 files changed, 2447 insertions(+), 28 deletions(-) create mode 100644 random/drbg.c -- 1.8.5.3 From smueller at chronox.de Wed Mar 19 08:38:56 2014 From: smueller at chronox.de (Stephan Mueller) Date: Wed, 19 Mar 2014 08:38:56 +0100 Subject: [PATCH v3 5/7] Function definitions for gcry_control callbacks In-Reply-To: <2634969.OgzocTu08g@myon.chronox.de> References: <1573675.V5Uuq2JQxy@myon.chronox.de> <4488709.H1QpKR4zZD@myon.chronox.de> <2634969.OgzocTu08g@myon.chronox.de> Message-ID: <1724976.NSVTLKdB6h@myon.chronox.de> The function definitions implemented in drbg.c which are used for gcry_control. Changes v3: * Remove of set_entropy function call Signed-off-by: Stephan Mueller --- diff --git a/random/random.h b/random/random.h index 2bc8cab..343b149 100644 --- a/random/random.h +++ b/random/random.h @@ -54,7 +54,9 @@ gcry_err_code_t _gcry_random_run_external_test (void *context, char *buffer, size_t buflen); void _gcry_random_deinit_external_test (void *context); - +/*-- drbg.c --*/ +gpg_err_code_t _gcry_drbg_reinit (u_int32_t flags, struct drbg_string *pers, + struct drbg_test_data *test_data); /*-- rndegd.c --*/ gpg_error_t _gcry_rndegd_set_socket_name (const char *name); From smueller at chronox.de Wed Mar 19 08:40:03 2014 From: smueller at chronox.de (Stephan Mueller) Date: Wed, 19 Mar 2014 08:40:03 +0100 Subject: [PATCH v7 7/7] User interface to DRBG In-Reply-To: <10261421.mqYxKu9qld@myon.chronox.de> References: <1573675.V5Uuq2JQxy@myon.chronox.de> <1724976.NSVTLKdB6h@myon.chronox.de> <10261421.mqYxKu9qld@myon.chronox.de> Message-ID: <1840716.S0MU8MFyFb@myon.chronox.de> DRBG Usage ========== The SP 800-90A DRBG allows the user to specify a personalization string for initialization as well as an additional information string for each random number request. The following code fragments show how a caller uses the kernel crypto API to use the full functionality of the DRBG. Usage without any additional data --------------------------------- gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); Usage with personalization string during initialization ------------------------------------------------------- struct drbg_string pers; drbg_string_fill(&pers, "string", strlen("string")); // The reset completely re-initializes the DRBG with the provided // personalization string without changing the DRBG type ret = gcry_control(GCRYCTL_DRBG_REINIT, 0, &pers, NULL); gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); Usage with additional information string during random number request --------------------------------------------------------------------- struct drbg_string addtl; drbg_string_fill(&addtl, "string", strlen("string")); // The following call is a wrapper to gcry_randomize() and returns // the same error codes. gcry_randomize_drbg(outbuf, OUTLEN, GCRY_STRONG_RANDOM, &addtl); Usage with personalization and additional information strings ------------------------------------------------------------- Just mix both scenarios above. Switch the DRBG type to some other type --------------------------------------- // Switch to CTR DRBG AES-128 without prediction resistance ret = gcry_control(GCRYCTL_DRBG_REINIT, DRBG_NOPR_CTRAES128, NULL, NULL); gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); Changes v3: * export only one gcry_control function * revamp of flags definition to avoid double information Signed-off-by: Stephan Mueller --- diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index c84a3f7..f7195bc 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -193,7 +193,7 @@ gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err); /* Return an error value with the system error ERR. */ gcry_err_code_t gcry_error_from_errno (int err); - + /* NOTE: Since Libgcrypt 1.6 the thread callbacks are not anymore used. However we keep it to allow for some source code compatibility if used in the standard way. */ @@ -228,7 +228,7 @@ struct gcry_thread_cbs (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8))} - + /* A generic context object as used by some functions. */ struct gcry_context; typedef struct gcry_context *gcry_ctx_t; @@ -254,7 +254,7 @@ typedef struct } gcry_buffer_t; - + /* Check that the library fulfills the version requirement. */ const char *gcry_check_version (const char *req_version); @@ -329,13 +329,14 @@ enum gcry_ctl_cmds GCRYCTL_SET_CCM_LENGTHS = 69, GCRYCTL_CLOSE_RANDOM_DEVICE = 70, GCRYCTL_INACTIVATE_FIPS_FLAG = 71, - GCRYCTL_REACTIVATE_FIPS_FLAG = 72 + GCRYCTL_REACTIVATE_FIPS_FLAG = 72, + GCRYCTL_DRBG_REINIT = 73, }; /* Perform various operations defined by CMD. */ gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...); - + /* S-expression management. */ /* The object to represent an S-expression as used with the public key @@ -477,7 +478,7 @@ gpg_error_t gcry_sexp_extract_param (gcry_sexp_t sexp, const char *list, ...) _GCRY_GCC_ATTR_SENTINEL(0); - + /******************************************* * * * Multi Precision Integer Functions * @@ -833,7 +834,7 @@ gcry_mpi_t _gcry_mpi_get_const (int no); #endif /* GCRYPT_NO_MPI_MACROS */ - + /************************************ * * * Symmetric Cipher Functions * @@ -1015,7 +1016,7 @@ size_t gcry_cipher_get_algo_blklen (int algo); #define gcry_cipher_test_algo(a) \ gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) - + /************************************ * * * Asymmetric Cipher Functions * @@ -1114,7 +1115,7 @@ gcry_sexp_t gcry_pk_get_param (int algo, const char *name); gcry_error_t gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp, int mode, gcry_ctx_t ctx); - + /************************************ * * @@ -1291,7 +1292,7 @@ void gcry_md_debug (gcry_md_hd_t hd, const char *suffix); #define gcry_md_get_asnoid(a,b,n) \ gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n)) - + /********************************************** * * @@ -1411,7 +1412,7 @@ int gcry_mac_map_name (const char *name) _GCRY_GCC_ATTR_PURE; #define gcry_mac_test_algo(a) \ gcry_mac_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) - + /****************************** * * * Key Derivation Functions * @@ -1439,7 +1440,7 @@ gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen, - + /************************************ * * * Random Generating Functions * @@ -1508,7 +1509,7 @@ void gcry_create_nonce (void *buffer, size_t length); - + /*******************************/ /* */ /* Prime Number Functions */ @@ -1567,7 +1568,7 @@ void gcry_prime_release_factors (gcry_mpi_t *factors); gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags); - + /************************************ * * * Miscellaneous Stuff * @@ -1672,6 +1673,134 @@ int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE; /* Return true if Libgcrypt is in FIPS mode. */ #define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) +/* DRBG test data */ +struct drbg_test_data { + struct drbg_string *testentropy; /* TEST PARAMETER: test entropy */ +}; + +/* DRBG input data structure for DRBG generate with additional information + * string */ +struct drbg_gen { + unsigned char *outbuf; /* output buffer for random numbers */ + unsigned int outlen; /* size of output buffer */ + struct drbg_string *addtl; /* input buffer for + * additional information string */ + struct drbg_test_data *test_data; /* test data */ +}; + +/* + * Concatenation Helper and string operation helper + * + * SP800-90A requires the concatenation of different data. To avoid copying + * buffers around or allocate additional memory, the following data structure + * is used to point to the original memory with its size. In addition, it + * is used to build a linked list. The linked list defines the concatenation + * of individual buffers. The order of memory block referenced in that + * linked list determines the order of concatenation. + */ +/* DRBG string definition */ +struct drbg_string { + const unsigned char *buf; + size_t len; + struct drbg_string *next; +}; + +static inline void drbg_string_fill(struct drbg_string *string, + const unsigned char *buf, size_t len) +{ + string->buf = buf; + string->len = len; + string->next = NULL; +} + +/* this is a wrapper function for users of libgcrypt */ +static inline void gcry_randomize_drbg(void *outbuf, size_t outlen, + enum gcry_random_level level, + struct drbg_string *addtl) +{ + struct drbg_gen genbuf; + genbuf.outbuf = outbuf; + genbuf.outlen = outlen; + genbuf.addtl = addtl; + genbuf.test_data = NULL; + gcry_randomize(&genbuf, 0, level); +} + +/* this is a wrapper function for users of libgcrypt */ +static inline void gcry_randomize_drbg_test(void *outbuf, size_t outlen, + enum gcry_random_level level, + struct drbg_string *addtl, + struct drbg_test_data *test_data) +{ + struct drbg_gen genbuf; + genbuf.outbuf = outbuf; + genbuf.outlen = outlen; + genbuf.addtl = addtl; + genbuf.test_data = test_data; + gcry_randomize(&genbuf, 0, level); +} + + +/* + * DRBG flags bitmasks + * + * 31 (B) 28 19 (A) 0 + * +-+-+-+--------+---+-----------+-----+ + * |~|~|u|~~~~~~~~| 3 | 2 | 1 | + * +-+-+-+--------+- -+-----------+-----+ + * ctl flg| |drbg use selection flags + * + */ + +/* internal state control flags (B) */ +#define DRBG_PREDICTION_RESIST ((u_int32_t)1<<28) + +/* CTR type modifiers (A.1)*/ +#define DRBG_CTRAES ((u_int32_t)1<<0) +#define DRBG_CTRSERPENT ((u_int32_t)1<<1) +#define DRBG_CTRTWOFISH ((u_int32_t)1<<2) +#define DRBG_CTR_MASK (DRBG_CTRAES | DRBG_CTRSERPENT | DRBG_CTRTWOFISH) + +/* HASH type modifiers (A.2)*/ +#define DRBG_HASHSHA1 ((u_int32_t)1<<4) +#define DRBG_HASHSHA224 ((u_int32_t)1<<5) +#define DRBG_HASHSHA256 ((u_int32_t)1<<6) +#define DRBG_HASHSHA384 ((u_int32_t)1<<7) +#define DRBG_HASHSHA512 ((u_int32_t)1<<8) +#define DRBG_HASH_MASK (DRBG_HASHSHA1 | DRBG_HASHSHA224 | \ + DRBG_HASHSHA256 | DRBG_HASHSHA384 | \ + DRBG_HASHSHA512) +/* type modifiers (A.3)*/ +#define DRBG_HMAC ((u_int32_t)1<<12) +#define DRBG_SYM128 ((u_int32_t)1<<13) +#define DRBG_SYM192 ((u_int32_t)1<<14) +#define DRBG_SYM256 ((u_int32_t)1<<15) +#define DRBG_TYPE_MASK (DRBG_HMAC | DRBG_SYM128 | DRBG_SYM192 | \ + DRBG_SYM256) +#define DRBG_CIPHER_MASK (DRBG_CTR_MASK | DRBG_HASH_MASK | DRBG_TYPE_MASK) + +#define DRBG_PR_CTRAES128 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM128) +#define DRBG_PR_CTRAES192 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM192) +#define DRBG_PR_CTRAES256 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM256) +#define DRBG_NOPR_CTRAES128 (DRBG_CTRAES | DRBG_SYM128) +#define DRBG_NOPR_CTRAES192 (DRBG_CTRAES | DRBG_SYM192) +#define DRBG_NOPR_CTRAES256 (DRBG_CTRAES | DRBG_SYM256) +#define DRBG_PR_HASHSHA1 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA1) +#define DRBG_PR_HASHSHA256 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA256) +#define DRBG_PR_HASHSHA384 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA384) +#define DRBG_PR_HASHSHA512 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA512) +#define DRBG_NOPR_HASHSHA1 (DRBG_HASHSHA1) +#define DRBG_NOPR_HASHSHA256 (DRBG_HASHSHA256) +#define DRBG_NOPR_HASHSHA384 (DRBG_HASHSHA384) +#define DRBG_NOPR_HASHSHA512 (DRBG_HASHSHA512) +#define DRBG_PR_HMACSHA1 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA1 | DRBG_HMAC) +#define DRBG_PR_HMACSHA256 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA256|DRBG_HMAC) +#define DRBG_PR_HMACSHA384 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA384|DRBG_HMAC) +#define DRBG_PR_HMACSHA512 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA512|DRBG_HMAC) +#define DRBG_NOPR_HMACSHA1 (DRBG_HASHSHA1 | DRBG_HMAC) +#define DRBG_NOPR_HMACSHA256 (DRBG_HASHSHA256 | DRBG_HMAC) +#define DRBG_NOPR_HMACSHA384 (DRBG_HASHSHA384 | DRBG_HMAC) +#define DRBG_NOPR_HMACSHA512 (DRBG_HASHSHA512 | DRBG_HMAC) #if 0 /* (Keep Emacsens' auto-indent happy.) */ { From smueller at chronox.de Wed Mar 19 08:38:10 2014 From: smueller at chronox.de (Stephan Mueller) Date: Wed, 19 Mar 2014 08:38:10 +0100 Subject: [PATCH v3 4/7] Invoke DRBG from common libgcrypt RNG code In-Reply-To: <4488709.H1QpKR4zZD@myon.chronox.de> References: <1573675.V5Uuq2JQxy@myon.chronox.de> <1746507.xHF3yNrW21@myon.chronox.de> <4488709.H1QpKR4zZD@myon.chronox.de> Message-ID: <2634969.OgzocTu08g@myon.chronox.de> Integrate the DRBG invocation with the common libgcrypt RNG code. This integration replaces the old ANSI X9.31 RNG invocation. As the ANSI X9.31 shall only be invoked in FIPS mode and it is sunset at the end of 2014 for FIPS purposes, a complete replacement with the DRBG is considered appropriate. The DRBG is FIPS approved deterministic random number generator for the forseeable future. Signed-off-by: Stephan Mueller --- diff --git a/random/random.c b/random/random.c index 41d4cb3..fcb0513 100644 --- a/random/random.c +++ b/random/random.c @@ -140,11 +140,13 @@ void _gcry_random_initialize (int full) { if (fips_mode ()) - _gcry_rngfips_initialize (full); + //_gcry_rngfips_initialize (full); + _gcry_drbg_init(full); else if (rng_types.standard) _gcry_rngcsprng_initialize (full); else if (rng_types.fips) - _gcry_rngfips_initialize (full); + _gcry_drbg_init(full); + //_gcry_rngfips_initialize (full); else if (rng_types.system) _gcry_rngsystem_initialize (full); else @@ -161,11 +163,13 @@ _gcry_random_close_fds (void) the entropy gatherer. */ if (fips_mode ()) - _gcry_rngfips_close_fds (); + //_gcry_rngfips_close_fds (); + _gcry_drbg_close_fds (); else if (rng_types.standard) _gcry_rngcsprng_close_fds (); else if (rng_types.fips) - _gcry_rngfips_close_fds (); + //_gcry_rngfips_close_fds (); + _gcry_drbg_close_fds (); else if (rng_types.system) _gcry_rngsystem_close_fds (); else @@ -199,7 +203,8 @@ void _gcry_random_dump_stats (void) { if (fips_mode ()) - _gcry_rngfips_dump_stats (); + //_gcry_rngfips_dump_stats (); + _gcry_drbg_dump_stats (); else _gcry_rngcsprng_dump_stats (); } @@ -258,7 +263,8 @@ int _gcry_random_is_faked (void) { if (fips_mode ()) - return _gcry_rngfips_is_faked (); + //return _gcry_rngfips_is_faked (); + return _gcry_drbg_is_faked (); else return _gcry_rngcsprng_is_faked (); } @@ -288,11 +294,13 @@ static void do_randomize (void *buffer, size_t length, enum gcry_random_level level) { if (fips_mode ()) - _gcry_rngfips_randomize (buffer, length, level); + //_gcry_rngfips_randomize (buffer, length, level); + _gcry_drbg_randomize (buffer, length, level); else if (rng_types.standard) _gcry_rngcsprng_randomize (buffer, length, level); else if (rng_types.fips) - _gcry_rngfips_randomize (buffer, length, level); + //_gcry_rngfips_randomize (buffer, length, level); + _gcry_drbg_randomize (buffer, length, level); else if (rng_types.system) _gcry_rngsystem_randomize (buffer, length, level); else /* default */ @@ -424,7 +432,8 @@ _gcry_create_nonce (void *buffer, size_t length) nonce generator which is seeded by the RNG actual in use. */ if (fips_mode ()) { - _gcry_rngfips_create_nonce (buffer, length); + //_gcry_rngfips_create_nonce (buffer, length); + _gcry_drbg_randomize (buffer, length, GCRY_WEAK_RANDOM); return; } @@ -501,7 +510,8 @@ gpg_error_t _gcry_random_selftest (selftest_report_func_t report) { if (fips_mode ()) - return _gcry_rngfips_selftest (report); + //return _gcry_rngfips_selftest (report); + return _gcry_drbg_selftest (report); else return 0; /* No selftests yet. */ } @@ -517,6 +527,7 @@ _gcry_random_init_external_test (void **r_context, const void *seed, size_t seedlen, const void *dt, size_t dtlen) { + return GPG_ERR_NOT_SUPPORTED; (void)flags; if (fips_mode ()) return _gcry_rngfips_init_external_test (r_context, flags, key, keylen, @@ -531,6 +542,7 @@ _gcry_random_init_external_test (void **r_context, gcry_err_code_t _gcry_random_run_external_test (void *context, char *buffer, size_t buflen) { + return GPG_ERR_NOT_SUPPORTED; if (fips_mode ()) return _gcry_rngfips_run_external_test (context, buffer, buflen); else @@ -541,6 +553,7 @@ _gcry_random_run_external_test (void *context, char *buffer, size_t buflen) void _gcry_random_deinit_external_test (void *context) { + return; if (fips_mode ()) _gcry_rngfips_deinit_external_test (context); } From smueller at chronox.de Wed Mar 19 08:35:42 2014 From: smueller at chronox.de (Stephan Mueller) Date: Wed, 19 Mar 2014 08:35:42 +0100 Subject: [PATCH v3 1/7] SP800-90A Deterministic Random Bit Generator In-Reply-To: <1573675.V5Uuq2JQxy@myon.chronox.de> References: <1573675.V5Uuq2JQxy@myon.chronox.de> Message-ID: <2263776.uX4ZkX09LR@myon.chronox.de> This is a clean-room implementation of the DRBG defined in SP800-90A. All three viable DRBGs defined in the standard are implemented: * HMAC: This is the leanest DRBG and compiled per default * Hash: The more complex DRBG can be enabled at compile time * CTR: The most complex DRBG can also be enabled at compile time The DRBG implementation offers the following: * All three DRBG types are implemented with a derivation function. * All DRBG types are available with and without prediction resistance. * All SHA types of SHA-1, SHA-256, SHA-384, SHA-512 are available for the HMAC and Hash DRBGs. * All AES types of AES-128, AES-192 and AES-256 are available for the CTR DRBG. * A self test is implemented with drbg_healthcheck(). * The FIPS 140-2 continuous self test is implemented. * Additional cipher primitives, such as Serpent or Twofish, can be added to the DRBG without changing the implementation. The only change necessary is to the DRBG definition given in the cores[] array. Changes v3: Changes to v1: * Overhauling code structure for simpler code as suggested on LKML: - each DRBG type exports only two crypto functions, - the individual DRBG implementations structure closely according to SP 800-90A, - using struct drbg_string to refer to buffers to avoid too many function parameters and prevent multiple data structure conversions - use inline more thoroughly - replace macros with small inline functions - remove unnecessary indirections - replace of large stack variables with a scratch buffer allocated at the beginning of DRBG operation -- see comments about scratchpad throughout the code * Revamping DRBG flags usage to avoid double information * Adding comments throughout the code to refer to the appropriate steps documented in SP 800-90A. * Perform thorough testing: - Performing of a full scale CAVS test with CAVS interface available at http://www.chronox.de/drbg.html - Performing tests by obtaining data which is not a multiple of cipher block size and check it with the ent tool to ensure that the generation loop does not reuse stale buffers to avoid errors like CVE-2013-4345. Signed-off-by: Stephan Mueller create mode 100644 random/drbg.c -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-SP800-90A-Deterministic-Random-Bit-Generator.patch.bz2 Type: application/x-bzip Size: 16227 bytes Desc: not available URL: From smueller at chronox.de Wed Mar 19 08:37:40 2014 From: smueller at chronox.de (Stephan Mueller) Date: Wed, 19 Mar 2014 08:37:40 +0100 Subject: [PATCH v3 3/7] Function definitions of interfaces for random.c In-Reply-To: <1746507.xHF3yNrW21@myon.chronox.de> References: <1573675.V5Uuq2JQxy@myon.chronox.de> <2263776.uX4ZkX09LR@myon.chronox.de> <1746507.xHF3yNrW21@myon.chronox.de> Message-ID: <4488709.H1QpKR4zZD@myon.chronox.de> Specify the function definitions to be integrated into the common libgcrypt RNG code. Signed-off-by: Stephan Mueller --- diff --git a/random/rand-internal.h b/random/rand-internal.h index 79b23ac..a169a4b 100644 --- a/random/rand-internal.h +++ b/random/rand-internal.h @@ -88,6 +88,15 @@ gcry_err_code_t _gcry_rngfips_run_external_test (void *context, char *buffer, size_t buflen); void _gcry_rngfips_deinit_external_test (void *context); +/* drbg-gcry.h */ +void _gcry_drbg_init(int full); +void _gcry_drbg_close_fds(void); +void _gcry_drbg_dump_stats(void); +int _gcry_drbg_is_faked (void); +gcry_error_t _gcry_drng_add_bytes (const void *buf, size_t buflen, int quality); +void _gcry_drbg_randomize (void *buffer, size_t length, + enum gcry_random_level level); +gcry_error_t _gcry_drbg_selftest (selftest_report_func_t report); /*-- random-system.c --*/ void _gcry_rngsystem_initialize (int full); From smueller at chronox.de Wed Mar 19 08:37:01 2014 From: smueller at chronox.de (Stephan Mueller) Date: Wed, 19 Mar 2014 08:37:01 +0100 Subject: [PATCH v3 2/7] Compile DRBG In-Reply-To: <2263776.uX4ZkX09LR@myon.chronox.de> References: <1573675.V5Uuq2JQxy@myon.chronox.de> <2263776.uX4ZkX09LR@myon.chronox.de> Message-ID: <1746507.xHF3yNrW21@myon.chronox.de> Add the drbg.c file to the Makefile. Signed-off-by: Stephan Mueller --- diff --git a/random/Makefile.am b/random/Makefile.am index c9d587a..e073fa4 100644 --- a/random/Makefile.am +++ b/random/Makefile.am @@ -35,6 +35,7 @@ random.c random.h \ rand-internal.h \ random-csprng.c \ random-fips.c \ +drbg.c \ random-system.c \ rndhw.c From dbaryshkov at gmail.com Sun Mar 23 21:18:35 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Mon, 24 Mar 2014 00:18:35 +0400 Subject: Parameters/gcryctl to digest algorithms? Message-ID: Hello, I'm trying to extend GOST R 34.11-94 support in libgcrypt. The problem is a selection of S-box to be used in compression function. Currently algo is limited to the S-Box defined in the standard itself. Initially I have hacked a version supporting CryptoPro S-Box (as required by RFC4357) just by introducing another algorithm using that s-box. However after looking at Ukrainian (DSTU) standards (order #114 dating 12.06.2007), I decided that it might be not so good idea. That order defines several more s-boxes, with at least one of them used for digest calculation. I can add another algo for that s-box, however I fear that it would be an overkill. I was also thinking about reusing flags part of md_open() call, but also couldn't come up with a good enough solution. What would be your thoughts? -- With best wishes Dmitry From wk at gnupg.org Mon Mar 24 10:31:20 2014 From: wk at gnupg.org (Werner Koch) Date: Mon, 24 Mar 2014 10:31:20 +0100 Subject: Parameters/gcryctl to digest algorithms? In-Reply-To: (Dmitry Eremin-Solenikov's message of "Mon, 24 Mar 2014 00:18:35 +0400") References: Message-ID: <87fvm8osd3.fsf@vigenere.g10code.de> On Sun, 23 Mar 2014 21:18, dbaryshkov at gmail.com said: > digest calculation. I can add another algo for that s-box, however I fear > that it would be an overkill. I was also thinking about reusing Please use a new algorithm number. In case you expect that you need several of them in the uture, it is probably useful to reserve a range of algorithm ids like: GCRY_MD_GOSTR3411_94 = 308, /* GOST R 34.11-94. */ GCRY_MD_STRIBOG256 = 309, /* GOST R 34.11-2012, 256 bit. */ GCRY_MD_STRIBOG512 = 310 /* GOST R 34.11-2012, 512 bit. */ GCRY_MD_GOSTR3411_XX = 401 /* 402 to 4xx reserved for other variants. */ > flags part of md_open() call, but also couldn't come up with a good > enough solution. Flags require lots of special cases, ranges of algorithm ids can be implemented in a generalized way: typedef struct gcry_md_spec { int algo; /* Actually used algo. */ + int first_algo; /* Modules supports algo range starting here ... */ + int last_algo; /* .. up to here. */ struct { unsigned int disabled:1; unsigned int fips:1; } flags; ... } static gcry_md_spec_t * spec_from_algo (int algo) { int idx; gcry_md_spec_t *spec; algo = map_algo (algo); for (idx = 0; (spec = digest_list[idx]); idx++) - if (algo == spec->algo) + if (algo >= spec->first_algo && algo <= spec->last_algo) return spec; return NULL; } then it is up to the digest module to do whatever it needs to do. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From dbaryshkov at gmail.com Tue Mar 25 08:20:44 2014 From: dbaryshkov at gmail.com (Dmitry Eremin-Solenikov) Date: Tue, 25 Mar 2014 11:20:44 +0400 Subject: Parameters/gcryctl to digest algorithms? In-Reply-To: <87fvm8osd3.fsf@vigenere.g10code.de> References: <87fvm8osd3.fsf@vigenere.g10code.de> Message-ID: Hello, On Mon, Mar 24, 2014 at 1:31 PM, Werner Koch wrote: > On Sun, 23 Mar 2014 21:18, dbaryshkov at gmail.com said: > >> digest calculation. I can add another algo for that s-box, however I fear >> that it would be an overkill. I was also thinking about reusing > > Please use a new algorithm number. In case you expect that you need > several of them in the uture, it is probably useful to reserve a range > of algorithm ids like: > > GCRY_MD_GOSTR3411_94 = 308, /* GOST R 34.11-94. */ > GCRY_MD_STRIBOG256 = 309, /* GOST R 34.11-2012, 256 bit. */ > GCRY_MD_STRIBOG512 = 310 /* GOST R 34.11-2012, 512 bit. */ > > GCRY_MD_GOSTR3411_XX = 401 /* 402 to 4xx reserved for other variants. */ Thanks. For GOST symmetric cipher I already had 8 s-boxes and now I'm adding 10 more, and there might be even more in future. I planned to use gcry_cipher_ctl to select s-box for the symmetric cipher. Is it a suitable solution? Would it be fine to use the same ctl value in gcry_mac_ctl and gcry_md_ctl to select s-box? I'm particularly concerned about MAC algorithms, because there I would need one algo number for each 34.11-94 S-BOX (there are 2 currently, 1 being added from Ukrainian s-box space, maybe more in future) and one for each 28147-89 S-BOX, being used in "imitovstavka" mode of GOST 28147-89 (MAC generation). That is probably too much to clobber algo space, thus I'd like to use gcry_mac_ctl at least for "imitiovstavka" MAC algo. -- With best wishes Dmitry From wk at gnupg.org Tue Mar 25 13:11:02 2014 From: wk at gnupg.org (Werner Koch) Date: Tue, 25 Mar 2014 13:11:02 +0100 Subject: Parameters/gcryctl to digest algorithms? In-Reply-To: (Dmitry Eremin-Solenikov's message of "Tue, 25 Mar 2014 11:20:44 +0400") References: <87fvm8osd3.fsf@vigenere.g10code.de> Message-ID: <8761n2o4vd.fsf@vigenere.g10code.de> On Tue, 25 Mar 2014 08:20, dbaryshkov at gmail.com said: > I'm adding 10 more, and there might be even more in future. I planned > to use gcry_cipher_ctl to select s-box for the symmetric cipher. > Is it a suitable solution? I would agree to ctl codes if they are used to install S-boxes from the applications. However, that raises a couple of other problems and I doubt that this is a save on memory or cycles. Also you would need two identifiers to select a particular algorithm. > gcry_md_ctl to select s-box? I'm particularly concerned about > MAC algorithms, because there I would need one algo number > for each 34.11-94 S-BOX (there are 2 currently, 1 being What is the problems. We have at least 65535 algorithm numbers and if we take advantage of the used int and the requirement for a 32 bit platform there are actually 2^31 algorithm ids. Where do you see the problems? You need more reserved space? Would 0x400 .. 0x4ff be enough? After all the s-boxes needs to be part of the code. I also believe that we should only add s-boxes which are in real use or expected to be used soon. Obviously it does not make sense to have a macro for each variant but a specification which reserves a range along with a base id does the job. Switch statements listing all algorithms would only list the base ID and the compiler would be happy. The only overhead I can see is that looking up the algorithm is a tiny bit slower - but that is invisible compared to the actual cycles the ciphers burn. Now, if the design of the cipher considers s-boxes similar to a key, we need to account for that and add an API to install an s-box into a cipher context. > much to clobber algo space, thus I'd like to use > gcry_mac_ctl at least for "imitiovstavka" MAC algo. I see no reason why we should not do the same with MAC algos. Now it is still time to somehow sync the MAC algo numbers with the Hash algo numbers. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From thresh at videolan.org Tue Mar 25 10:55:48 2014 From: thresh at videolan.org (Konstantin Pavlov) Date: Tue, 25 Mar 2014 13:55:48 +0400 Subject: x86_64 Darwin build fix Message-ID: <20140325095548.GA12044@thre.sh> This patch fixes build error observed on current Darwin platform with asm enabled: libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I../src -I../src -g -O2 -MT mpih-mul1-asm.lo -MD -MP -MF .deps/mpih-mul1-asm.Tpo -c mpih-mul1-asm.S -fno-common -DPIC -o .libs/mpih-mul1-asm.o mpih-mul1-asm.S:43:9: error: invalid alignment value .align 1<<(5) ^ make[2]: *** [mpih-mul1-asm.lo] Error 1 -- VideoLAN Konstantin Pavlov http://www.videolan.org Mobile: +7 926 165 45 31 Skype: cryothresh Twitter: @cryothresh -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-mpi-fix-code-path-selection-for-x86_64-on-Darwin.patch Type: text/x-diff Size: 837 bytes Desc: not available URL: From chris at chatsecure.org Tue Mar 25 23:31:07 2014 From: chris at chatsecure.org (Chris Ballinger) Date: Tue, 25 Mar 2014 15:31:07 -0700 Subject: x86_64 Darwin build fix In-Reply-To: <20140325095548.GA12044@thre.sh> References: <20140325095548.GA12044@thre.sh> Message-ID: Thank you! I have been meaning to submit an issue about this as well but wasn't quite sure how to fix it myself. On Tue, Mar 25, 2014 at 2:55 AM, Konstantin Pavlov wrote: > This patch fixes build error observed on current Darwin platform with asm > enabled: > > libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I../src -I../src > -g -O2 -MT mpih-mul1-asm.lo -MD -MP -MF .deps/mpih-mul1-asm.Tpo -c > mpih-mul1-asm.S -fno-common -DPIC -o .libs/mpih-mul1-asm.o > mpih-mul1-asm.S:43:9: error: invalid alignment value > .align 1<<(5) > ^ > make[2]: *** [mpih-mul1-asm.lo] Error 1 > > -- > VideoLAN > Konstantin Pavlov > http://www.videolan.org > Mobile: +7 926 165 45 31 > Skype: cryothresh > Twitter: @cryothresh > > _______________________________________________ > Gcrypt-devel mailing list > Gcrypt-devel at gnupg.org > http://lists.gnupg.org/mailman/listinfo/gcrypt-devel > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From wk at gnupg.org Thu Mar 27 20:15:04 2014 From: wk at gnupg.org (Werner Koch) Date: Thu, 27 Mar 2014 20:15:04 +0100 Subject: x86_64 Darwin build fix In-Reply-To: <20140325095548.GA12044@thre.sh> (Konstantin Pavlov's message of "Tue, 25 Mar 2014 13:55:48 +0400") References: <20140325095548.GA12044@thre.sh> Message-ID: <87txajlah3.fsf@vigenere.g10code.de> On Tue, 25 Mar 2014 10:55, thresh at videolan.org said: > This patch fixes build error observed on current Darwin platform with asm > enabled: That's bug 1616, right? Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From thresh at videolan.org Thu Mar 27 20:55:47 2014 From: thresh at videolan.org (Konstantin Pavlov) Date: Thu, 27 Mar 2014 23:55:47 +0400 Subject: x86_64 Darwin build fix In-Reply-To: <87txajlah3.fsf@vigenere.g10code.de> References: <20140325095548.GA12044@thre.sh> <87txajlah3.fsf@vigenere.g10code.de> Message-ID: <20140327195547.GF12044@thre.sh> On Thu, Mar 27, 2014 at 08:15:04PM +0100, Werner Koch wrote: > On Tue, 25 Mar 2014 10:55, thresh at videolan.org said: > > This patch fixes build error observed on current Darwin platform with asm > > enabled: > > That's bug 1616, right? Bug 1616 looks like a separate issue to me: the reporter has PowerPC machine, while I'm fixing stuff on an Intel one. -- VideoLAN Konstantin Pavlov http://www.videolan.org Mobile: +7 926 165 45 31 Skype: cryothresh Twitter: @cryothresh From smueller at chronox.de Thu Mar 27 21:26:03 2014 From: smueller at chronox.de (Stephan Mueller) Date: Thu, 27 Mar 2014 21:26:03 +0100 Subject: [PATCH v4 7/7] User interface to DRBG In-Reply-To: <1840716.S0MU8MFyFb@myon.chronox.de> References: <1573675.V5Uuq2JQxy@myon.chronox.de> <10261421.mqYxKu9qld@myon.chronox.de> <1840716.S0MU8MFyFb@myon.chronox.de> Message-ID: <1768928.lDN30gJEhR@myon.chronox.de> Changes v4: * add fail_seed_source to struct drbg_test_data Signed-off-by: Stephan Mueller --- diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index c84a3f7..2a17dcd 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -193,7 +193,7 @@ gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err); /* Return an error value with the system error ERR. */ gcry_err_code_t gcry_error_from_errno (int err); - + /* NOTE: Since Libgcrypt 1.6 the thread callbacks are not anymore used. However we keep it to allow for some source code compatibility if used in the standard way. */ @@ -228,7 +228,7 @@ struct gcry_thread_cbs (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8))} - + /* A generic context object as used by some functions. */ struct gcry_context; typedef struct gcry_context *gcry_ctx_t; @@ -254,7 +254,7 @@ typedef struct } gcry_buffer_t; - + /* Check that the library fulfills the version requirement. */ const char *gcry_check_version (const char *req_version); @@ -329,13 +329,14 @@ enum gcry_ctl_cmds GCRYCTL_SET_CCM_LENGTHS = 69, GCRYCTL_CLOSE_RANDOM_DEVICE = 70, GCRYCTL_INACTIVATE_FIPS_FLAG = 71, - GCRYCTL_REACTIVATE_FIPS_FLAG = 72 + GCRYCTL_REACTIVATE_FIPS_FLAG = 72, + GCRYCTL_DRBG_REINIT = 73, }; /* Perform various operations defined by CMD. */ gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...); - + /* S-expression management. */ /* The object to represent an S-expression as used with the public key @@ -477,7 +478,7 @@ gpg_error_t gcry_sexp_extract_param (gcry_sexp_t sexp, const char *list, ...) _GCRY_GCC_ATTR_SENTINEL(0); - + /******************************************* * * * Multi Precision Integer Functions * @@ -833,7 +834,7 @@ gcry_mpi_t _gcry_mpi_get_const (int no); #endif /* GCRYPT_NO_MPI_MACROS */ - + /************************************ * * * Symmetric Cipher Functions * @@ -1015,7 +1016,7 @@ size_t gcry_cipher_get_algo_blklen (int algo); #define gcry_cipher_test_algo(a) \ gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) - + /************************************ * * * Asymmetric Cipher Functions * @@ -1114,7 +1115,7 @@ gcry_sexp_t gcry_pk_get_param (int algo, const char *name); gcry_error_t gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp, int mode, gcry_ctx_t ctx); - + /************************************ * * @@ -1291,7 +1292,7 @@ void gcry_md_debug (gcry_md_hd_t hd, const char *suffix); #define gcry_md_get_asnoid(a,b,n) \ gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n)) - + /********************************************** * * @@ -1411,7 +1412,7 @@ int gcry_mac_map_name (const char *name) _GCRY_GCC_ATTR_PURE; #define gcry_mac_test_algo(a) \ gcry_mac_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) - + /****************************** * * * Key Derivation Functions * @@ -1439,7 +1440,7 @@ gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen, - + /************************************ * * * Random Generating Functions * @@ -1508,7 +1509,7 @@ void gcry_create_nonce (void *buffer, size_t length); - + /*******************************/ /* */ /* Prime Number Functions */ @@ -1567,7 +1568,7 @@ void gcry_prime_release_factors (gcry_mpi_t *factors); gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags); - + /************************************ * * * Miscellaneous Stuff * @@ -1672,6 +1673,136 @@ int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE; /* Return true if Libgcrypt is in FIPS mode. */ #define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) +/* DRBG test data */ +struct drbg_test_data { + struct drbg_string *testentropy; /* TEST PARAMETER: test entropy */ + int fail_seed_source:1; /* if set, the seed function will return an + * error */ +}; + +/* DRBG input data structure for DRBG generate with additional information + * string */ +struct drbg_gen { + unsigned char *outbuf; /* output buffer for random numbers */ + unsigned int outlen; /* size of output buffer */ + struct drbg_string *addtl; /* input buffer for + * additional information string */ + struct drbg_test_data *test_data; /* test data */ +}; + +/* + * Concatenation Helper and string operation helper + * + * SP800-90A requires the concatenation of different data. To avoid copying + * buffers around or allocate additional memory, the following data structure + * is used to point to the original memory with its size. In addition, it + * is used to build a linked list. The linked list defines the concatenation + * of individual buffers. The order of memory block referenced in that + * linked list determines the order of concatenation. + */ +/* DRBG string definition */ +struct drbg_string { + const unsigned char *buf; + size_t len; + struct drbg_string *next; +}; + +static inline void drbg_string_fill(struct drbg_string *string, + const unsigned char *buf, size_t len) +{ + string->buf = buf; + string->len = len; + string->next = NULL; +} + +/* this is a wrapper function for users of libgcrypt */ +static inline void gcry_randomize_drbg(void *outbuf, size_t outlen, + enum gcry_random_level level, + struct drbg_string *addtl) +{ + struct drbg_gen genbuf; + genbuf.outbuf = outbuf; + genbuf.outlen = outlen; + genbuf.addtl = addtl; + genbuf.test_data = NULL; + gcry_randomize(&genbuf, 0, level); +} + +/* this is a wrapper function for users of libgcrypt */ +static inline void gcry_randomize_drbg_test(void *outbuf, size_t outlen, + enum gcry_random_level level, + struct drbg_string *addtl, + struct drbg_test_data *test_data) +{ + struct drbg_gen genbuf; + genbuf.outbuf = outbuf; + genbuf.outlen = outlen; + genbuf.addtl = addtl; + genbuf.test_data = test_data; + gcry_randomize(&genbuf, 0, level); +} + + +/* + * DRBG flags bitmasks + * + * 31 (B) 28 19 (A) 0 + * +-+-+-+--------+---+-----------+-----+ + * |~|~|u|~~~~~~~~| 3 | 2 | 1 | + * +-+-+-+--------+- -+-----------+-----+ + * ctl flg| |drbg use selection flags + * + */ + +/* internal state control flags (B) */ +#define DRBG_PREDICTION_RESIST ((u_int32_t)1<<28) + +/* CTR type modifiers (A.1)*/ +#define DRBG_CTRAES ((u_int32_t)1<<0) +#define DRBG_CTRSERPENT ((u_int32_t)1<<1) +#define DRBG_CTRTWOFISH ((u_int32_t)1<<2) +#define DRBG_CTR_MASK (DRBG_CTRAES | DRBG_CTRSERPENT | DRBG_CTRTWOFISH) + +/* HASH type modifiers (A.2)*/ +#define DRBG_HASHSHA1 ((u_int32_t)1<<4) +#define DRBG_HASHSHA224 ((u_int32_t)1<<5) +#define DRBG_HASHSHA256 ((u_int32_t)1<<6) +#define DRBG_HASHSHA384 ((u_int32_t)1<<7) +#define DRBG_HASHSHA512 ((u_int32_t)1<<8) +#define DRBG_HASH_MASK (DRBG_HASHSHA1 | DRBG_HASHSHA224 | \ + DRBG_HASHSHA256 | DRBG_HASHSHA384 | \ + DRBG_HASHSHA512) +/* type modifiers (A.3)*/ +#define DRBG_HMAC ((u_int32_t)1<<12) +#define DRBG_SYM128 ((u_int32_t)1<<13) +#define DRBG_SYM192 ((u_int32_t)1<<14) +#define DRBG_SYM256 ((u_int32_t)1<<15) +#define DRBG_TYPE_MASK (DRBG_HMAC | DRBG_SYM128 | DRBG_SYM192 | \ + DRBG_SYM256) +#define DRBG_CIPHER_MASK (DRBG_CTR_MASK | DRBG_HASH_MASK | DRBG_TYPE_MASK) + +#define DRBG_PR_CTRAES128 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM128) +#define DRBG_PR_CTRAES192 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM192) +#define DRBG_PR_CTRAES256 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM256) +#define DRBG_NOPR_CTRAES128 (DRBG_CTRAES | DRBG_SYM128) +#define DRBG_NOPR_CTRAES192 (DRBG_CTRAES | DRBG_SYM192) +#define DRBG_NOPR_CTRAES256 (DRBG_CTRAES | DRBG_SYM256) +#define DRBG_PR_HASHSHA1 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA1) +#define DRBG_PR_HASHSHA256 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA256) +#define DRBG_PR_HASHSHA384 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA384) +#define DRBG_PR_HASHSHA512 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA512) +#define DRBG_NOPR_HASHSHA1 (DRBG_HASHSHA1) +#define DRBG_NOPR_HASHSHA256 (DRBG_HASHSHA256) +#define DRBG_NOPR_HASHSHA384 (DRBG_HASHSHA384) +#define DRBG_NOPR_HASHSHA512 (DRBG_HASHSHA512) +#define DRBG_PR_HMACSHA1 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA1 | DRBG_HMAC) +#define DRBG_PR_HMACSHA256 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA256|DRBG_HMAC) +#define DRBG_PR_HMACSHA384 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA384|DRBG_HMAC) +#define DRBG_PR_HMACSHA512 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA512|DRBG_HMAC) +#define DRBG_NOPR_HMACSHA1 (DRBG_HASHSHA1 | DRBG_HMAC) +#define DRBG_NOPR_HMACSHA256 (DRBG_HASHSHA256 | DRBG_HMAC) +#define DRBG_NOPR_HMACSHA384 (DRBG_HASHSHA384 | DRBG_HMAC) +#define DRBG_NOPR_HMACSHA512 (DRBG_HASHSHA512 | DRBG_HMAC) #if 0 /* (Keep Emacsens' auto-indent happy.) */ { From smueller at chronox.de Thu Mar 27 21:25:15 2014 From: smueller at chronox.de (Stephan Mueller) Date: Thu, 27 Mar 2014 21:25:15 +0100 Subject: [PATCH v4 1/7] SP800-90A Deterministic Random Bit Generator In-Reply-To: <2263776.uX4ZkX09LR@myon.chronox.de> References: <1573675.V5Uuq2JQxy@myon.chronox.de> <2263776.uX4ZkX09LR@myon.chronox.de> Message-ID: <1441801.LxIjhxD44Y@myon.chronox.de> Changes v4: * change default value returned by drbg_sec_strength to be the maximum entropy defined by SP800-90A to catch erroneous invocations of the function. * Make return of drbg_fips_continuous_test cleaner as suggested by Clemens Ladisch * Fix comments on how to invoke the DRBG at the beginning of the file * drbg_ctr_df: replace the for loop for calculation of padlen that used to call up to 16 modulo operations with one modulo operation * drbg_ctr_df: replace plain integer values with sizeof() to make code clearer * drbg_hash_hashgen: replace memset() on drbg->scratchpad with memset() on src/dst pointers to make code clearer * as recommended by Peter Waltenberg: add re-invocation of self tests as required by 11.3.3 -- the tests are commented out because they make no mathematical sense. However, if a FIPS 140-2 validation requires these tests, the code just needs to be activated. * as recommended by Peter Waltenberg: add error path tests as required by 11.3.2 -- see new function of drbg_healthcheck_sanity * add debug prints * as recommended by Peter Waltenberg: add drbg_generate_long to generate arbitrary long strings * add self test on failing entropy source * catch error when no random numbers can be generated * perform drbg_healthcheck_sanity only in FIPS mode Signed-off-by: Stephan Mueller -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-SP800-90A-Deterministic-Random-Bit-Generator.patch.bz2 Type: application/x-bzip Size: 16475 bytes Desc: not available URL: From jussi.kivilinna at iki.fi Sun Mar 30 17:27:32 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sun, 30 Mar 2014 18:27:32 +0300 Subject: [PATCH] 3des: add amd64 assembly implementation for 3DES Message-ID: <20140330152732.15480.98989.stgit@localhost6.localdomain6> * cipher/Makefile.am: Add 'des-amd64.S'. * cipher/cipher-selftests.c (_gcry_selftest_helper_cbc) (_gcry_selftest_helper_cfb, _gcry_selftest_helper_ctr): Handle failures from 'setkey' function. * cipher/cipher.c (_gcry_cipher_open_internal) [USE_DES]: Setup bulk functions for 3DES. * cipher/des-amd64.S: New file. * cipher/des.c (USE_AMD64_ASM, ATTR_ALIGNED_16): New macros. [USE_AMD64_ASM] (_gcry_3des_amd64_crypt_block) (_gcry_3des_amd64_ctr_enc), _gcry_3des_amd64_cbc_dec) (_gcry_3des_amd64_cfb_dec): New prototypes. [USE_AMD64_ASM] (tripledes_ecb_crypt): New function. (TRIPLEDES_ECB_BURN_STACK): New macro. (_gcry_3des_ctr_enc, _gcry_3des_cbc_dec, _gcry_3des_cfb_dec) (bulk_selftest_setkey, selftest_ctr, selftest_cbc, selftest_cfb): New functions. (selftest): Add call to CTR, CBC and CFB selftest functions. (do_tripledes_encrypt, do_tripledes_decrypt): Use TRIPLEDES_ECB_BURN_STACK. * configure.ac [host=x86-64]: Add 'des-amd64.lo'. * src/cipher.h (_gcry_3des_ctr_enc, _gcry_3des_cbc_dec) (_gcry_3des_cfb_dec): New prototypes. -- Add non-parallel functions for small speed-up and 3-way parallel functions for modes of operation that support parallel processing. Old vs new (Intel Core i5-4570): ================================ enc dec ECB 1.17x 1.17x CBC 1.17x 2.51x CFB 1.16x 2.49x OFB 1.17x 1.17x CTR 2.56x 2.56x Old vs new (Intel Core i5-2450M): ================================= enc dec ECB 1.28x 1.28x CBC 1.27x 2.33x CFB 1.27x 2.34x OFB 1.27x 1.27x CTR 2.36x 2.35x New (Intel Core i5-4570): ========================= 3DES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 28.39 ns/B 33.60 MiB/s 90.84 c/B ECB dec | 28.27 ns/B 33.74 MiB/s 90.45 c/B CBC enc | 29.50 ns/B 32.33 MiB/s 94.40 c/B CBC dec | 13.35 ns/B 71.45 MiB/s 42.71 c/B CFB enc | 29.59 ns/B 32.23 MiB/s 94.68 c/B CFB dec | 13.41 ns/B 71.12 MiB/s 42.91 c/B OFB enc | 28.90 ns/B 33.00 MiB/s 92.47 c/B OFB dec | 28.90 ns/B 33.00 MiB/s 92.48 c/B CTR enc | 13.39 ns/B 71.20 MiB/s 42.86 c/B CTR dec | 13.39 ns/B 71.21 MiB/s 42.86 c/B Old (Intel Core i5-4570): ========================= 3DES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 33.24 ns/B 28.69 MiB/s 106.4 c/B ECB dec | 33.26 ns/B 28.67 MiB/s 106.4 c/B CBC enc | 34.45 ns/B 27.69 MiB/s 110.2 c/B CBC dec | 33.45 ns/B 28.51 MiB/s 107.1 c/B CFB enc | 34.43 ns/B 27.70 MiB/s 110.2 c/B CFB dec | 33.41 ns/B 28.55 MiB/s 106.9 c/B OFB enc | 33.79 ns/B 28.22 MiB/s 108.1 c/B OFB dec | 33.79 ns/B 28.22 MiB/s 108.1 c/B CTR enc | 34.27 ns/B 27.83 MiB/s 109.7 c/B CTR dec | 34.27 ns/B 27.83 MiB/s 109.7 c/B New (Intel Core i5-2450M): ========================== 3DES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 42.21 ns/B 22.59 MiB/s 105.5 c/B ECB dec | 42.23 ns/B 22.58 MiB/s 105.6 c/B CBC enc | 43.70 ns/B 21.82 MiB/s 109.2 c/B CBC dec | 23.25 ns/B 41.02 MiB/s 58.12 c/B CFB enc | 43.71 ns/B 21.82 MiB/s 109.3 c/B CFB dec | 23.23 ns/B 41.05 MiB/s 58.08 c/B OFB enc | 42.73 ns/B 22.32 MiB/s 106.8 c/B OFB dec | 42.73 ns/B 22.32 MiB/s 106.8 c/B CTR enc | 23.31 ns/B 40.92 MiB/s 58.27 c/B CTR dec | 23.35 ns/B 40.84 MiB/s 58.38 c/B Old (Intel Core i5-2450M): ========================== 3DES | nanosecs/byte mebibytes/sec cycles/byte ECB enc | 53.98 ns/B 17.67 MiB/s 134.9 c/B ECB dec | 54.00 ns/B 17.66 MiB/s 135.0 c/B CBC enc | 55.43 ns/B 17.20 MiB/s 138.6 c/B CBC dec | 54.27 ns/B 17.57 MiB/s 135.7 c/B CFB enc | 55.42 ns/B 17.21 MiB/s 138.6 c/B CFB dec | 54.35 ns/B 17.55 MiB/s 135.9 c/B OFB enc | 54.49 ns/B 17.50 MiB/s 136.2 c/B OFB dec | 54.49 ns/B 17.50 MiB/s 136.2 c/B CTR enc | 55.02 ns/B 17.33 MiB/s 137.5 c/B CTR dec | 55.01 ns/B 17.34 MiB/s 137.5 c/B Signed-off-by: Jussi Kivilinna --- cipher/Makefile.am | 2 cipher/cipher-selftest.c | 18 + cipher/cipher.c | 7 cipher/des-amd64.S | 1030 ++++++++++++++++++++++++++++++++++++++++++++++ cipher/des.c | 292 +++++++++++++ configure.ac | 7 src/cipher.h | 13 + 7 files changed, 1362 insertions(+), 7 deletions(-) create mode 100644 cipher/des-amd64.S diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 462e6db..3c20d3c 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -60,7 +60,7 @@ arcfour.c arcfour-amd64.S \ blowfish.c blowfish-amd64.S blowfish-arm.S \ cast5.c cast5-amd64.S cast5-arm.S \ crc.c \ -des.c \ +des.c des-amd64.S \ dsa.c \ elgamal.c \ ecc.c ecc-curves.c ecc-misc.c ecc-common.h \ diff --git a/cipher/cipher-selftest.c b/cipher/cipher-selftest.c index 5e95814..852368a 100644 --- a/cipher/cipher-selftest.c +++ b/cipher/cipher-selftest.c @@ -82,7 +82,11 @@ _gcry_selftest_helper_cbc (const char *cipher, gcry_cipher_setkey_t setkey_func, ciphertext = plaintext2 + nblocks * blocksize; /* Initialize ctx */ - setkey_func (ctx, key, sizeof(key)); + if (setkey_func (ctx, key, sizeof(key)) != GPG_ERR_NO_ERROR) + { + xfree(mem); + return "setkey failed"; + } /* Test single block code path */ memset (iv, 0x4e, blocksize); @@ -199,7 +203,11 @@ _gcry_selftest_helper_cfb (const char *cipher, gcry_cipher_setkey_t setkey_func, ciphertext = plaintext2 + nblocks * blocksize; /* Initialize ctx */ - setkey_func (ctx, key, sizeof(key)); + if (setkey_func (ctx, key, sizeof(key)) != GPG_ERR_NO_ERROR) + { + xfree(mem); + return "setkey failed"; + } /* Test single block code path */ memset(iv, 0xd3, blocksize); @@ -316,7 +324,11 @@ _gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey_func, ciphertext2 = ciphertext + nblocks * blocksize; /* Initialize ctx */ - setkey_func (ctx, key, sizeof(key)); + if (setkey_func (ctx, key, sizeof(key)) != GPG_ERR_NO_ERROR) + { + xfree(mem); + return "setkey failed"; + } /* Test single block code path */ memset (iv, 0xff, blocksize); diff --git a/cipher/cipher.c b/cipher/cipher.c index baa4720..6552ed3 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -513,6 +513,13 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle, h->bulk.ctr_enc = _gcry_camellia_ctr_enc; break; #endif /*USE_CAMELLIA*/ +#ifdef USE_DES + case GCRY_CIPHER_3DES: + h->bulk.cbc_dec = _gcry_3des_cbc_dec; + h->bulk.cfb_dec = _gcry_3des_cfb_dec; + h->bulk.ctr_enc = _gcry_3des_ctr_enc; + break; +#endif /*USE_DES*/ #ifdef USE_SERPENT case GCRY_CIPHER_SERPENT128: case GCRY_CIPHER_SERPENT192: diff --git a/cipher/des-amd64.S b/cipher/des-amd64.S new file mode 100644 index 0000000..e8b2c56 --- /dev/null +++ b/cipher/des-amd64.S @@ -0,0 +1,1030 @@ +/* des-amd64.S - AMD64 assembly implementation of 3DES cipher + * + * Copyright (C) 2014 Jussi Kivilinna + * + * 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 . + */ + +#ifdef __x86_64 +#include +#if defined(USE_DES) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) + +#ifdef __PIC__ +# define RIP (%rip) +#else +# define RIP +#endif + +.text + +#define s1 0 +#define s2 ((s1) + (64*8)) +#define s3 ((s2) + (64*8)) +#define s4 ((s3) + (64*8)) +#define s5 ((s4) + (64*8)) +#define s6 ((s5) + (64*8)) +#define s7 ((s6) + (64*8)) +#define s8 ((s7) + (64*8)) + +/* register macros */ +#define CTX %rdi +#define SBOXES %rbp + +#define RL0 %r8 +#define RL1 %r9 +#define RL2 %r10 + +#define RL0d %r8d +#define RL1d %r9d +#define RL2d %r10d + +#define RR0 %r11 +#define RR1 %r12 +#define RR2 %r13 + +#define RR0d %r11d +#define RR1d %r12d +#define RR2d %r13d + +#define RW0 %rax +#define RW1 %rbx +#define RW2 %rcx + +#define RW0d %eax +#define RW1d %ebx +#define RW2d %ecx + +#define RW0bl %al +#define RW1bl %bl +#define RW2bl %cl + +#define RW0bh %ah +#define RW1bh %bh +#define RW2bh %ch + +#define RT0 %r15 +#define RT1 %rsi +#define RT2 %r14 +#define RT3 %rdx + +#define RT0d %r15d +#define RT1d %esi +#define RT2d %r14d +#define RT3d %edx + +/*********************************************************************** + * 1-way 3DES + ***********************************************************************/ +#define do_permutation(a, b, offset, mask) \ + movl a, RT0d; \ + shrl $(offset), RT0d; \ + xorl b, RT0d; \ + andl $(mask), RT0d; \ + xorl RT0d, b; \ + shll $(offset), RT0d; \ + xorl RT0d, a; + +#define expand_to_64bits(val, mask) \ + movl val##d, RT0d; \ + rorl $4, RT0d; \ + shlq $32, RT0; \ + orq RT0, val; \ + andq mask, val; + +#define compress_to_64bits(val) \ + movq val, RT0; \ + shrq $32, RT0; \ + roll $4, RT0d; \ + orl RT0d, val##d; + +#define initial_permutation(left, right) \ + do_permutation(left##d, right##d, 4, 0x0f0f0f0f); \ + do_permutation(left##d, right##d, 16, 0x0000ffff); \ + do_permutation(right##d, left##d, 2, 0x33333333); \ + do_permutation(right##d, left##d, 8, 0x00ff00ff); \ + movabs $0x3f3f3f3f3f3f3f3f, RT3; \ + movl left##d, RW0d; \ + roll $1, right##d; \ + xorl right##d, RW0d; \ + andl $0xaaaaaaaa, RW0d; \ + xorl RW0d, left##d; \ + xorl RW0d, right##d; \ + roll $1, left##d; \ + expand_to_64bits(right, RT3); \ + expand_to_64bits(left, RT3); + +#define final_permutation(left, right) \ + compress_to_64bits(right); \ + compress_to_64bits(left); \ + movl right##d, RW0d; \ + rorl $1, left##d; \ + xorl left##d, RW0d; \ + andl $0xaaaaaaaa, RW0d; \ + xorl RW0d, right##d; \ + xorl RW0d, left##d; \ + rorl $1, right##d; \ + do_permutation(right##d, left##d, 8, 0x00ff00ff); \ + do_permutation(right##d, left##d, 2, 0x33333333); \ + do_permutation(left##d, right##d, 16, 0x0000ffff); \ + do_permutation(left##d, right##d, 4, 0x0f0f0f0f); + +#define round1(n, from, to, load_next_key) \ + xorq from, RW0; \ + \ + movzbl RW0bl, RT0d; \ + movzbl RW0bh, RT1d; \ + shrq $16, RW0; \ + movzbl RW0bl, RT2d; \ + movzbl RW0bh, RT3d; \ + shrq $16, RW0; \ + movq s8(SBOXES, RT0, 8), RT0; \ + xorq s6(SBOXES, RT1, 8), to; \ + movzbl RW0bl, RL1d; \ + movzbl RW0bh, RT1d; \ + shrl $16, RW0d; \ + xorq s4(SBOXES, RT2, 8), RT0; \ + xorq s2(SBOXES, RT3, 8), to; \ + movzbl RW0bl, RT2d; \ + movzbl RW0bh, RT3d; \ + xorq s7(SBOXES, RL1, 8), RT0; \ + xorq s5(SBOXES, RT1, 8), to; \ + xorq s3(SBOXES, RT2, 8), RT0; \ + load_next_key(n, RW0); \ + xorq RT0, to; \ + xorq s1(SBOXES, RT3, 8), to; \ + +#define load_next_key(n, RWx) \ + movq (((n) + 1) * 8)(CTX), RWx; + +#define dummy2(a, b) /*_*/ + +#define read_block(io, left, right) \ + movl (io), left##d; \ + movl 4(io), right##d; \ + bswapl left##d; \ + bswapl right##d; + +#define write_block(io, left, right) \ + bswapl left##d; \ + bswapl right##d; \ + movl left##d, (io); \ + movl right##d, 4(io); + +.align 8 +.globl _gcry_3des_amd64_crypt_block +.type _gcry_3des_amd64_crypt_block, at function; + +_gcry_3des_amd64_crypt_block: + /* input: + * %rdi: round keys, CTX + * %rsi: dst + * %rdx: src + */ + pushq %rbp; + pushq %rbx; + pushq %r12; + pushq %r13; + pushq %r14; + pushq %r15; + pushq %rsi; /*dst*/ + + leaq .L_s1 RIP, SBOXES; + + read_block(%rdx, RL0, RR0); + initial_permutation(RL0, RR0); + + movq (CTX), RW0; + + round1(0, RR0, RL0, load_next_key); + round1(1, RL0, RR0, load_next_key); + round1(2, RR0, RL0, load_next_key); + round1(3, RL0, RR0, load_next_key); + round1(4, RR0, RL0, load_next_key); + round1(5, RL0, RR0, load_next_key); + round1(6, RR0, RL0, load_next_key); + round1(7, RL0, RR0, load_next_key); + round1(8, RR0, RL0, load_next_key); + round1(9, RL0, RR0, load_next_key); + round1(10, RR0, RL0, load_next_key); + round1(11, RL0, RR0, load_next_key); + round1(12, RR0, RL0, load_next_key); + round1(13, RL0, RR0, load_next_key); + round1(14, RR0, RL0, load_next_key); + round1(15, RL0, RR0, load_next_key); + + round1(16+0, RL0, RR0, load_next_key); + round1(16+1, RR0, RL0, load_next_key); + round1(16+2, RL0, RR0, load_next_key); + round1(16+3, RR0, RL0, load_next_key); + round1(16+4, RL0, RR0, load_next_key); + round1(16+5, RR0, RL0, load_next_key); + round1(16+6, RL0, RR0, load_next_key); + round1(16+7, RR0, RL0, load_next_key); + round1(16+8, RL0, RR0, load_next_key); + round1(16+9, RR0, RL0, load_next_key); + round1(16+10, RL0, RR0, load_next_key); + round1(16+11, RR0, RL0, load_next_key); + round1(16+12, RL0, RR0, load_next_key); + round1(16+13, RR0, RL0, load_next_key); + round1(16+14, RL0, RR0, load_next_key); + round1(16+15, RR0, RL0, load_next_key); + + round1(32+0, RR0, RL0, load_next_key); + round1(32+1, RL0, RR0, load_next_key); + round1(32+2, RR0, RL0, load_next_key); + round1(32+3, RL0, RR0, load_next_key); + round1(32+4, RR0, RL0, load_next_key); + round1(32+5, RL0, RR0, load_next_key); + round1(32+6, RR0, RL0, load_next_key); + round1(32+7, RL0, RR0, load_next_key); + round1(32+8, RR0, RL0, load_next_key); + round1(32+9, RL0, RR0, load_next_key); + round1(32+10, RR0, RL0, load_next_key); + round1(32+11, RL0, RR0, load_next_key); + round1(32+12, RR0, RL0, load_next_key); + round1(32+13, RL0, RR0, load_next_key); + round1(32+14, RR0, RL0, load_next_key); + round1(32+15, RL0, RR0, dummy2); + + popq RW2; /*dst*/ + final_permutation(RR0, RL0); + write_block(RW2, RR0, RL0); + + popq %r15; + popq %r14; + popq %r13; + popq %r12; + popq %rbx; + popq %rbp; + + ret; +.size _gcry_3des_amd64_crypt_block,.-_gcry_3des_amd64_crypt_block; + +/*********************************************************************** + * 3-way 3DES + ***********************************************************************/ +#define expand_to_64bits(val, mask) \ + movl val##d, RT0d; \ + rorl $4, RT0d; \ + shlq $32, RT0; \ + orq RT0, val; \ + andq mask, val; + +#define compress_to_64bits(val) \ + movq val, RT0; \ + shrq $32, RT0; \ + roll $4, RT0d; \ + orl RT0d, val##d; + +#define initial_permutation3(left, right) \ + do_permutation(left##0d, right##0d, 4, 0x0f0f0f0f); \ + do_permutation(left##0d, right##0d, 16, 0x0000ffff); \ + do_permutation(left##1d, right##1d, 4, 0x0f0f0f0f); \ + do_permutation(left##1d, right##1d, 16, 0x0000ffff); \ + do_permutation(left##2d, right##2d, 4, 0x0f0f0f0f); \ + do_permutation(left##2d, right##2d, 16, 0x0000ffff); \ + \ + do_permutation(right##0d, left##0d, 2, 0x33333333); \ + do_permutation(right##0d, left##0d, 8, 0x00ff00ff); \ + do_permutation(right##1d, left##1d, 2, 0x33333333); \ + do_permutation(right##1d, left##1d, 8, 0x00ff00ff); \ + do_permutation(right##2d, left##2d, 2, 0x33333333); \ + do_permutation(right##2d, left##2d, 8, 0x00ff00ff); \ + \ + movabs $0x3f3f3f3f3f3f3f3f, RT3; \ + \ + movl left##0d, RW0d; \ + roll $1, right##0d; \ + xorl right##0d, RW0d; \ + andl $0xaaaaaaaa, RW0d; \ + xorl RW0d, left##0d; \ + xorl RW0d, right##0d; \ + roll $1, left##0d; \ + expand_to_64bits(right##0, RT3); \ + expand_to_64bits(left##0, RT3); \ + movl left##1d, RW1d; \ + roll $1, right##1d; \ + xorl right##1d, RW1d; \ + andl $0xaaaaaaaa, RW1d; \ + xorl RW1d, left##1d; \ + xorl RW1d, right##1d; \ + roll $1, left##1d; \ + expand_to_64bits(right##1, RT3); \ + expand_to_64bits(left##1, RT3); \ + movl left##2d, RW2d; \ + roll $1, right##2d; \ + xorl right##2d, RW2d; \ + andl $0xaaaaaaaa, RW2d; \ + xorl RW2d, left##2d; \ + xorl RW2d, right##2d; \ + roll $1, left##2d; \ + expand_to_64bits(right##2, RT3); \ + expand_to_64bits(left##2, RT3); + +#define final_permutation3(left, right) \ + compress_to_64bits(right##0); \ + compress_to_64bits(left##0); \ + movl right##0d, RW0d; \ + rorl $1, left##0d; \ + xorl left##0d, RW0d; \ + andl $0xaaaaaaaa, RW0d; \ + xorl RW0d, right##0d; \ + xorl RW0d, left##0d; \ + rorl $1, right##0d; \ + compress_to_64bits(right##1); \ + compress_to_64bits(left##1); \ + movl right##1d, RW1d; \ + rorl $1, left##1d; \ + xorl left##1d, RW1d; \ + andl $0xaaaaaaaa, RW1d; \ + xorl RW1d, right##1d; \ + xorl RW1d, left##1d; \ + rorl $1, right##1d; \ + compress_to_64bits(right##2); \ + compress_to_64bits(left##2); \ + movl right##2d, RW2d; \ + rorl $1, left##2d; \ + xorl left##2d, RW2d; \ + andl $0xaaaaaaaa, RW2d; \ + xorl RW2d, right##2d; \ + xorl RW2d, left##2d; \ + rorl $1, right##2d; \ + \ + do_permutation(right##0d, left##0d, 8, 0x00ff00ff); \ + do_permutation(right##0d, left##0d, 2, 0x33333333); \ + do_permutation(right##1d, left##1d, 8, 0x00ff00ff); \ + do_permutation(right##1d, left##1d, 2, 0x33333333); \ + do_permutation(right##2d, left##2d, 8, 0x00ff00ff); \ + do_permutation(right##2d, left##2d, 2, 0x33333333); \ + \ + do_permutation(left##0d, right##0d, 16, 0x0000ffff); \ + do_permutation(left##0d, right##0d, 4, 0x0f0f0f0f); \ + do_permutation(left##1d, right##1d, 16, 0x0000ffff); \ + do_permutation(left##1d, right##1d, 4, 0x0f0f0f0f); \ + do_permutation(left##2d, right##2d, 16, 0x0000ffff); \ + do_permutation(left##2d, right##2d, 4, 0x0f0f0f0f); + +#define round3(n, from, to, load_next_key, do_movq) \ + xorq from##0, RW0; \ + movzbl RW0bl, RT3d; \ + movzbl RW0bh, RT1d; \ + shrq $16, RW0; \ + xorq s8(SBOXES, RT3, 8), to##0; \ + xorq s6(SBOXES, RT1, 8), to##0; \ + movzbl RW0bl, RT3d; \ + movzbl RW0bh, RT1d; \ + shrq $16, RW0; \ + xorq s4(SBOXES, RT3, 8), to##0; \ + xorq s2(SBOXES, RT1, 8), to##0; \ + movzbl RW0bl, RT3d; \ + movzbl RW0bh, RT1d; \ + shrl $16, RW0d; \ + xorq s7(SBOXES, RT3, 8), to##0; \ + xorq s5(SBOXES, RT1, 8), to##0; \ + movzbl RW0bl, RT3d; \ + movzbl RW0bh, RT1d; \ + load_next_key(n, RW0); \ + xorq s3(SBOXES, RT3, 8), to##0; \ + xorq s1(SBOXES, RT1, 8), to##0; \ + xorq from##1, RW1; \ + movzbl RW1bl, RT3d; \ + movzbl RW1bh, RT1d; \ + shrq $16, RW1; \ + xorq s8(SBOXES, RT3, 8), to##1; \ + xorq s6(SBOXES, RT1, 8), to##1; \ + movzbl RW1bl, RT3d; \ + movzbl RW1bh, RT1d; \ + shrq $16, RW1; \ + xorq s4(SBOXES, RT3, 8), to##1; \ + xorq s2(SBOXES, RT1, 8), to##1; \ + movzbl RW1bl, RT3d; \ + movzbl RW1bh, RT1d; \ + shrl $16, RW1d; \ + xorq s7(SBOXES, RT3, 8), to##1; \ + xorq s5(SBOXES, RT1, 8), to##1; \ + movzbl RW1bl, RT3d; \ + movzbl RW1bh, RT1d; \ + do_movq(RW0, RW1); \ + xorq s3(SBOXES, RT3, 8), to##1; \ + xorq s1(SBOXES, RT1, 8), to##1; \ + xorq from##2, RW2; \ + movzbl RW2bl, RT3d; \ + movzbl RW2bh, RT1d; \ + shrq $16, RW2; \ + xorq s8(SBOXES, RT3, 8), to##2; \ + xorq s6(SBOXES, RT1, 8), to##2; \ + movzbl RW2bl, RT3d; \ + movzbl RW2bh, RT1d; \ + shrq $16, RW2; \ + xorq s4(SBOXES, RT3, 8), to##2; \ + xorq s2(SBOXES, RT1, 8), to##2; \ + movzbl RW2bl, RT3d; \ + movzbl RW2bh, RT1d; \ + shrl $16, RW2d; \ + xorq s7(SBOXES, RT3, 8), to##2; \ + xorq s5(SBOXES, RT1, 8), to##2; \ + movzbl RW2bl, RT3d; \ + movzbl RW2bh, RT1d; \ + do_movq(RW0, RW2); \ + xorq s3(SBOXES, RT3, 8), to##2; \ + xorq s1(SBOXES, RT1, 8), to##2; + +#define __movq(src, dst) \ + movq src, dst; + +#define read_block(io, left, right) \ + movl (io), left##d; \ + movl 4(io), right##d; \ + bswapl left##d; \ + bswapl right##d; + +#define write_block(io, left, right) \ + bswapl left##d; \ + bswapl right##d; \ + movl left##d, (io); \ + movl right##d, 4(io); + +.align 8 +.type _gcry_3des_amd64_crypt_blk3, at function; +_gcry_3des_amd64_crypt_blk3: + /* input: + * %rdi: round keys, CTX + * RL0d, RR0d, RL1d, RR1d, RL2d, RR2d: 3 input blocks + * RR0d, RL0d, RR1d, RL1d, RR2d, RL2d: 3 output blocks + */ + + leaq .L_s1 RIP, SBOXES; + + initial_permutation3(RL, RR); + + movq 0(CTX), RW0; + movq RW0, RW1; + movq RW0, RW2; + + round3(0, RR, RL, load_next_key, __movq); + round3(1, RL, RR, load_next_key, __movq); + round3(2, RR, RL, load_next_key, __movq); + round3(3, RL, RR, load_next_key, __movq); + round3(4, RR, RL, load_next_key, __movq); + round3(5, RL, RR, load_next_key, __movq); + round3(6, RR, RL, load_next_key, __movq); + round3(7, RL, RR, load_next_key, __movq); + round3(8, RR, RL, load_next_key, __movq); + round3(9, RL, RR, load_next_key, __movq); + round3(10, RR, RL, load_next_key, __movq); + round3(11, RL, RR, load_next_key, __movq); + round3(12, RR, RL, load_next_key, __movq); + round3(13, RL, RR, load_next_key, __movq); + round3(14, RR, RL, load_next_key, __movq); + round3(15, RL, RR, load_next_key, __movq); + + round3(16+0, RL, RR, load_next_key, __movq); + round3(16+1, RR, RL, load_next_key, __movq); + round3(16+2, RL, RR, load_next_key, __movq); + round3(16+3, RR, RL, load_next_key, __movq); + round3(16+4, RL, RR, load_next_key, __movq); + round3(16+5, RR, RL, load_next_key, __movq); + round3(16+6, RL, RR, load_next_key, __movq); + round3(16+7, RR, RL, load_next_key, __movq); + round3(16+8, RL, RR, load_next_key, __movq); + round3(16+9, RR, RL, load_next_key, __movq); + round3(16+10, RL, RR, load_next_key, __movq); + round3(16+11, RR, RL, load_next_key, __movq); + round3(16+12, RL, RR, load_next_key, __movq); + round3(16+13, RR, RL, load_next_key, __movq); + round3(16+14, RL, RR, load_next_key, __movq); + round3(16+15, RR, RL, load_next_key, __movq); + + round3(32+0, RR, RL, load_next_key, __movq); + round3(32+1, RL, RR, load_next_key, __movq); + round3(32+2, RR, RL, load_next_key, __movq); + round3(32+3, RL, RR, load_next_key, __movq); + round3(32+4, RR, RL, load_next_key, __movq); + round3(32+5, RL, RR, load_next_key, __movq); + round3(32+6, RR, RL, load_next_key, __movq); + round3(32+7, RL, RR, load_next_key, __movq); + round3(32+8, RR, RL, load_next_key, __movq); + round3(32+9, RL, RR, load_next_key, __movq); + round3(32+10, RR, RL, load_next_key, __movq); + round3(32+11, RL, RR, load_next_key, __movq); + round3(32+12, RR, RL, load_next_key, __movq); + round3(32+13, RL, RR, load_next_key, __movq); + round3(32+14, RR, RL, load_next_key, __movq); + round3(32+15, RL, RR, dummy2, dummy2); + + final_permutation3(RR, RL); + + ret; +.size _gcry_3des_amd64_crypt_blk3,.-_gcry_3des_amd64_crypt_blk3; + +.align 8 +.globl _gcry_3des_amd64_cbc_dec +.type _gcry_3des_amd64_cbc_dec, at function; +_gcry_3des_amd64_cbc_dec: + /* input: + * %rdi: ctx, CTX + * %rsi: dst (3 blocks) + * %rdx: src (3 blocks) + * %rcx: iv (64bit) + */ + + pushq %rbp; + pushq %rbx; + pushq %r12; + pushq %r13; + pushq %r14; + pushq %r15; + + pushq %rsi; /*dst*/ + pushq %rdx; /*src*/ + pushq %rcx; /*iv*/ + + /* load input */ + movl 0 * 4(%rdx), RL0d; + movl 1 * 4(%rdx), RR0d; + movl 2 * 4(%rdx), RL1d; + movl 3 * 4(%rdx), RR1d; + movl 4 * 4(%rdx), RL2d; + movl 5 * 4(%rdx), RR2d; + + bswapl RL0d; + bswapl RR0d; + bswapl RL1d; + bswapl RR1d; + bswapl RL2d; + bswapl RR2d; + + call _gcry_3des_amd64_crypt_blk3; + + popq %rcx; /*iv*/ + popq %rdx; /*src*/ + popq %rsi; /*dst*/ + + bswapl RR0d; + bswapl RL0d; + bswapl RR1d; + bswapl RL1d; + bswapl RR2d; + bswapl RL2d; + + movq 2 * 8(%rdx), RT0; + xorl 0 * 4(%rcx), RR0d; + xorl 1 * 4(%rcx), RL0d; + xorl 0 * 4(%rdx), RR1d; + xorl 1 * 4(%rdx), RL1d; + xorl 2 * 4(%rdx), RR2d; + xorl 3 * 4(%rdx), RL2d; + movq RT0, (%rcx); /* store new IV */ + + movl RR0d, 0 * 4(%rsi); + movl RL0d, 1 * 4(%rsi); + movl RR1d, 2 * 4(%rsi); + movl RL1d, 3 * 4(%rsi); + movl RR2d, 4 * 4(%rsi); + movl RL2d, 5 * 4(%rsi); + + popq %r15; + popq %r14; + popq %r13; + popq %r12; + popq %rbx; + popq %rbp; + + ret; +.size _gcry_3des_amd64_cbc_dec,.-_gcry_3des_amd64_cbc_dec; + +.align 8 +.globl _gcry_3des_amd64_ctr_enc +.type _gcry_3des_amd64_ctr_enc, at function; +_gcry_3des_amd64_ctr_enc: + /* input: + * %rdi: ctx, CTX + * %rsi: dst (3 blocks) + * %rdx: src (3 blocks) + * %rcx: iv (64bit) + */ + + pushq %rbp; + pushq %rbx; + pushq %r12; + pushq %r13; + pushq %r14; + pushq %r15; + + pushq %rsi; /*dst*/ + pushq %rdx; /*src*/ + movq %rcx, RW2; + + /* load IV and byteswap */ + movq (RW2), RT0; + bswapq RT0; + movq RT0, RR0; + + /* construct IVs */ + leaq 1(RT0), RR1; + leaq 2(RT0), RR2; + leaq 3(RT0), RT0; + movq RR0, RL0; + movq RR1, RL1; + movq RR2, RL2; + bswapq RT0; + shrq $32, RL0; + shrq $32, RL1; + shrq $32, RL2; + + /* store new IV */ + movq RT0, (RW2); + + call _gcry_3des_amd64_crypt_blk3; + + popq %rdx; /*src*/ + popq %rsi; /*dst*/ + + bswapl RR0d; + bswapl RL0d; + bswapl RR1d; + bswapl RL1d; + bswapl RR2d; + bswapl RL2d; + + xorl 0 * 4(%rdx), RR0d; + xorl 1 * 4(%rdx), RL0d; + xorl 2 * 4(%rdx), RR1d; + xorl 3 * 4(%rdx), RL1d; + xorl 4 * 4(%rdx), RR2d; + xorl 5 * 4(%rdx), RL2d; + + movl RR0d, 0 * 4(%rsi); + movl RL0d, 1 * 4(%rsi); + movl RR1d, 2 * 4(%rsi); + movl RL1d, 3 * 4(%rsi); + movl RR2d, 4 * 4(%rsi); + movl RL2d, 5 * 4(%rsi); + + popq %r15; + popq %r14; + popq %r13; + popq %r12; + popq %rbx; + popq %rbp; + + ret; +.size _gcry_3des_amd64_cbc_dec,.-_gcry_3des_amd64_cbc_dec; + +.align 8 +.globl _gcry_3des_amd64_cfb_dec +.type _gcry_3des_amd64_cfb_dec, at function; +_gcry_3des_amd64_cfb_dec: + /* input: + * %rdi: ctx, CTX + * %rsi: dst (3 blocks) + * %rdx: src (3 blocks) + * %rcx: iv (64bit) + */ + pushq %rbp; + pushq %rbx; + pushq %r12; + pushq %r13; + pushq %r14; + pushq %r15; + + pushq %rsi; /*dst*/ + pushq %rdx; /*src*/ + movq %rcx, RW2; + + /* Load input */ + movl 0 * 4(RW2), RL0d; + movl 1 * 4(RW2), RR0d; + movl 0 * 4(%rdx), RL1d; + movl 1 * 4(%rdx), RR1d; + movl 2 * 4(%rdx), RL2d; + movl 3 * 4(%rdx), RR2d; + + bswapl RL0d; + bswapl RR0d; + bswapl RL1d; + bswapl RR1d; + bswapl RL2d; + bswapl RR2d; + + /* Update IV */ + movq 4 * 4(%rdx), RW0; + movq RW0, (RW2); + + call _gcry_3des_amd64_crypt_blk3; + + popq %rdx; /*src*/ + popq %rsi; /*dst*/ + + bswapl RR0d; + bswapl RL0d; + bswapl RR1d; + bswapl RL1d; + bswapl RR2d; + bswapl RL2d; + + xorl 0 * 4(%rdx), RR0d; + xorl 1 * 4(%rdx), RL0d; + xorl 2 * 4(%rdx), RR1d; + xorl 3 * 4(%rdx), RL1d; + xorl 4 * 4(%rdx), RR2d; + xorl 5 * 4(%rdx), RL2d; + + movl RR0d, 0 * 4(%rsi); + movl RL0d, 1 * 4(%rsi); + movl RR1d, 2 * 4(%rsi); + movl RL1d, 3 * 4(%rsi); + movl RR2d, 4 * 4(%rsi); + movl RL2d, 5 * 4(%rsi); + + popq %r15; + popq %r14; + popq %r13; + popq %r12; + popq %rbx; + popq %rbp; + ret; +.size _gcry_3des_amd64_cfb_dec,.-_gcry_3des_amd64_cfb_dec; + +.data +.align 16 +.L_s1: + .quad 0x0010100001010400, 0x0000000000000000 + .quad 0x0000100000010000, 0x0010100001010404 + .quad 0x0010100001010004, 0x0000100000010404 + .quad 0x0000000000000004, 0x0000100000010000 + .quad 0x0000000000000400, 0x0010100001010400 + .quad 0x0010100001010404, 0x0000000000000400 + .quad 0x0010000001000404, 0x0010100001010004 + .quad 0x0010000001000000, 0x0000000000000004 + .quad 0x0000000000000404, 0x0010000001000400 + .quad 0x0010000001000400, 0x0000100000010400 + .quad 0x0000100000010400, 0x0010100001010000 + .quad 0x0010100001010000, 0x0010000001000404 + .quad 0x0000100000010004, 0x0010000001000004 + .quad 0x0010000001000004, 0x0000100000010004 + .quad 0x0000000000000000, 0x0000000000000404 + .quad 0x0000100000010404, 0x0010000001000000 + .quad 0x0000100000010000, 0x0010100001010404 + .quad 0x0000000000000004, 0x0010100001010000 + .quad 0x0010100001010400, 0x0010000001000000 + .quad 0x0010000001000000, 0x0000000000000400 + .quad 0x0010100001010004, 0x0000100000010000 + .quad 0x0000100000010400, 0x0010000001000004 + .quad 0x0000000000000400, 0x0000000000000004 + .quad 0x0010000001000404, 0x0000100000010404 + .quad 0x0010100001010404, 0x0000100000010004 + .quad 0x0010100001010000, 0x0010000001000404 + .quad 0x0010000001000004, 0x0000000000000404 + .quad 0x0000100000010404, 0x0010100001010400 + .quad 0x0000000000000404, 0x0010000001000400 + .quad 0x0010000001000400, 0x0000000000000000 + .quad 0x0000100000010004, 0x0000100000010400 + .quad 0x0000000000000000, 0x0010100001010004 +.L_s2: + .quad 0x0801080200100020, 0x0800080000000000 + .quad 0x0000080000000000, 0x0001080200100020 + .quad 0x0001000000100000, 0x0000000200000020 + .quad 0x0801000200100020, 0x0800080200000020 + .quad 0x0800000200000020, 0x0801080200100020 + .quad 0x0801080000100000, 0x0800000000000000 + .quad 0x0800080000000000, 0x0001000000100000 + .quad 0x0000000200000020, 0x0801000200100020 + .quad 0x0001080000100000, 0x0001000200100020 + .quad 0x0800080200000020, 0x0000000000000000 + .quad 0x0800000000000000, 0x0000080000000000 + .quad 0x0001080200100020, 0x0801000000100000 + .quad 0x0001000200100020, 0x0800000200000020 + .quad 0x0000000000000000, 0x0001080000100000 + .quad 0x0000080200000020, 0x0801080000100000 + .quad 0x0801000000100000, 0x0000080200000020 + .quad 0x0000000000000000, 0x0001080200100020 + .quad 0x0801000200100020, 0x0001000000100000 + .quad 0x0800080200000020, 0x0801000000100000 + .quad 0x0801080000100000, 0x0000080000000000 + .quad 0x0801000000100000, 0x0800080000000000 + .quad 0x0000000200000020, 0x0801080200100020 + .quad 0x0001080200100020, 0x0000000200000020 + .quad 0x0000080000000000, 0x0800000000000000 + .quad 0x0000080200000020, 0x0801080000100000 + .quad 0x0001000000100000, 0x0800000200000020 + .quad 0x0001000200100020, 0x0800080200000020 + .quad 0x0800000200000020, 0x0001000200100020 + .quad 0x0001080000100000, 0x0000000000000000 + .quad 0x0800080000000000, 0x0000080200000020 + .quad 0x0800000000000000, 0x0801000200100020 + .quad 0x0801080200100020, 0x0001080000100000 +.L_s3: + .quad 0x0000002000000208, 0x0000202008020200 + .quad 0x0000000000000000, 0x0000200008020008 + .quad 0x0000002008000200, 0x0000000000000000 + .quad 0x0000202000020208, 0x0000002008000200 + .quad 0x0000200000020008, 0x0000000008000008 + .quad 0x0000000008000008, 0x0000200000020000 + .quad 0x0000202008020208, 0x0000200000020008 + .quad 0x0000200008020000, 0x0000002000000208 + .quad 0x0000000008000000, 0x0000000000000008 + .quad 0x0000202008020200, 0x0000002000000200 + .quad 0x0000202000020200, 0x0000200008020000 + .quad 0x0000200008020008, 0x0000202000020208 + .quad 0x0000002008000208, 0x0000202000020200 + .quad 0x0000200000020000, 0x0000002008000208 + .quad 0x0000000000000008, 0x0000202008020208 + .quad 0x0000002000000200, 0x0000000008000000 + .quad 0x0000202008020200, 0x0000000008000000 + .quad 0x0000200000020008, 0x0000002000000208 + .quad 0x0000200000020000, 0x0000202008020200 + .quad 0x0000002008000200, 0x0000000000000000 + .quad 0x0000002000000200, 0x0000200000020008 + .quad 0x0000202008020208, 0x0000002008000200 + .quad 0x0000000008000008, 0x0000002000000200 + .quad 0x0000000000000000, 0x0000200008020008 + .quad 0x0000002008000208, 0x0000200000020000 + .quad 0x0000000008000000, 0x0000202008020208 + .quad 0x0000000000000008, 0x0000202000020208 + .quad 0x0000202000020200, 0x0000000008000008 + .quad 0x0000200008020000, 0x0000002008000208 + .quad 0x0000002000000208, 0x0000200008020000 + .quad 0x0000202000020208, 0x0000000000000008 + .quad 0x0000200008020008, 0x0000202000020200 +.L_s4: + .quad 0x1008020000002001, 0x1000020800002001 + .quad 0x1000020800002001, 0x0000000800000000 + .quad 0x0008020800002000, 0x1008000800000001 + .quad 0x1008000000000001, 0x1000020000002001 + .quad 0x0000000000000000, 0x0008020000002000 + .quad 0x0008020000002000, 0x1008020800002001 + .quad 0x1000000800000001, 0x0000000000000000 + .quad 0x0008000800000000, 0x1008000000000001 + .quad 0x1000000000000001, 0x0000020000002000 + .quad 0x0008000000000000, 0x1008020000002001 + .quad 0x0000000800000000, 0x0008000000000000 + .quad 0x1000020000002001, 0x0000020800002000 + .quad 0x1008000800000001, 0x1000000000000001 + .quad 0x0000020800002000, 0x0008000800000000 + .quad 0x0000020000002000, 0x0008020800002000 + .quad 0x1008020800002001, 0x1000000800000001 + .quad 0x0008000800000000, 0x1008000000000001 + .quad 0x0008020000002000, 0x1008020800002001 + .quad 0x1000000800000001, 0x0000000000000000 + .quad 0x0000000000000000, 0x0008020000002000 + .quad 0x0000020800002000, 0x0008000800000000 + .quad 0x1008000800000001, 0x1000000000000001 + .quad 0x1008020000002001, 0x1000020800002001 + .quad 0x1000020800002001, 0x0000000800000000 + .quad 0x1008020800002001, 0x1000000800000001 + .quad 0x1000000000000001, 0x0000020000002000 + .quad 0x1008000000000001, 0x1000020000002001 + .quad 0x0008020800002000, 0x1008000800000001 + .quad 0x1000020000002001, 0x0000020800002000 + .quad 0x0008000000000000, 0x1008020000002001 + .quad 0x0000000800000000, 0x0008000000000000 + .quad 0x0000020000002000, 0x0008020800002000 +.L_s5: + .quad 0x0000001000000100, 0x0020001002080100 + .quad 0x0020000002080000, 0x0420001002000100 + .quad 0x0000000000080000, 0x0000001000000100 + .quad 0x0400000000000000, 0x0020000002080000 + .quad 0x0400001000080100, 0x0000000000080000 + .quad 0x0020001002000100, 0x0400001000080100 + .quad 0x0420001002000100, 0x0420000002080000 + .quad 0x0000001000080100, 0x0400000000000000 + .quad 0x0020000002000000, 0x0400000000080000 + .quad 0x0400000000080000, 0x0000000000000000 + .quad 0x0400001000000100, 0x0420001002080100 + .quad 0x0420001002080100, 0x0020001002000100 + .quad 0x0420000002080000, 0x0400001000000100 + .quad 0x0000000000000000, 0x0420000002000000 + .quad 0x0020001002080100, 0x0020000002000000 + .quad 0x0420000002000000, 0x0000001000080100 + .quad 0x0000000000080000, 0x0420001002000100 + .quad 0x0000001000000100, 0x0020000002000000 + .quad 0x0400000000000000, 0x0020000002080000 + .quad 0x0420001002000100, 0x0400001000080100 + .quad 0x0020001002000100, 0x0400000000000000 + .quad 0x0420000002080000, 0x0020001002080100 + .quad 0x0400001000080100, 0x0000001000000100 + .quad 0x0020000002000000, 0x0420000002080000 + .quad 0x0420001002080100, 0x0000001000080100 + .quad 0x0420000002000000, 0x0420001002080100 + .quad 0x0020000002080000, 0x0000000000000000 + .quad 0x0400000000080000, 0x0420000002000000 + .quad 0x0000001000080100, 0x0020001002000100 + .quad 0x0400001000000100, 0x0000000000080000 + .quad 0x0000000000000000, 0x0400000000080000 + .quad 0x0020001002080100, 0x0400001000000100 +.L_s6: + .quad 0x0200000120000010, 0x0204000020000000 + .quad 0x0000040000000000, 0x0204040120000010 + .quad 0x0204000020000000, 0x0000000100000010 + .quad 0x0204040120000010, 0x0004000000000000 + .quad 0x0200040020000000, 0x0004040100000010 + .quad 0x0004000000000000, 0x0200000120000010 + .quad 0x0004000100000010, 0x0200040020000000 + .quad 0x0200000020000000, 0x0000040100000010 + .quad 0x0000000000000000, 0x0004000100000010 + .quad 0x0200040120000010, 0x0000040000000000 + .quad 0x0004040000000000, 0x0200040120000010 + .quad 0x0000000100000010, 0x0204000120000010 + .quad 0x0204000120000010, 0x0000000000000000 + .quad 0x0004040100000010, 0x0204040020000000 + .quad 0x0000040100000010, 0x0004040000000000 + .quad 0x0204040020000000, 0x0200000020000000 + .quad 0x0200040020000000, 0x0000000100000010 + .quad 0x0204000120000010, 0x0004040000000000 + .quad 0x0204040120000010, 0x0004000000000000 + .quad 0x0000040100000010, 0x0200000120000010 + .quad 0x0004000000000000, 0x0200040020000000 + .quad 0x0200000020000000, 0x0000040100000010 + .quad 0x0200000120000010, 0x0204040120000010 + .quad 0x0004040000000000, 0x0204000020000000 + .quad 0x0004040100000010, 0x0204040020000000 + .quad 0x0000000000000000, 0x0204000120000010 + .quad 0x0000000100000010, 0x0000040000000000 + .quad 0x0204000020000000, 0x0004040100000010 + .quad 0x0000040000000000, 0x0004000100000010 + .quad 0x0200040120000010, 0x0000000000000000 + .quad 0x0204040020000000, 0x0200000020000000 + .quad 0x0004000100000010, 0x0200040120000010 +.L_s7: + .quad 0x0002000000200000, 0x2002000004200002 + .quad 0x2000000004000802, 0x0000000000000000 + .quad 0x0000000000000800, 0x2000000004000802 + .quad 0x2002000000200802, 0x0002000004200800 + .quad 0x2002000004200802, 0x0002000000200000 + .quad 0x0000000000000000, 0x2000000004000002 + .quad 0x2000000000000002, 0x0000000004000000 + .quad 0x2002000004200002, 0x2000000000000802 + .quad 0x0000000004000800, 0x2002000000200802 + .quad 0x2002000000200002, 0x0000000004000800 + .quad 0x2000000004000002, 0x0002000004200000 + .quad 0x0002000004200800, 0x2002000000200002 + .quad 0x0002000004200000, 0x0000000000000800 + .quad 0x2000000000000802, 0x2002000004200802 + .quad 0x0002000000200800, 0x2000000000000002 + .quad 0x0000000004000000, 0x0002000000200800 + .quad 0x0000000004000000, 0x0002000000200800 + .quad 0x0002000000200000, 0x2000000004000802 + .quad 0x2000000004000802, 0x2002000004200002 + .quad 0x2002000004200002, 0x2000000000000002 + .quad 0x2002000000200002, 0x0000000004000000 + .quad 0x0000000004000800, 0x0002000000200000 + .quad 0x0002000004200800, 0x2000000000000802 + .quad 0x2002000000200802, 0x0002000004200800 + .quad 0x2000000000000802, 0x2000000004000002 + .quad 0x2002000004200802, 0x0002000004200000 + .quad 0x0002000000200800, 0x0000000000000000 + .quad 0x2000000000000002, 0x2002000004200802 + .quad 0x0000000000000000, 0x2002000000200802 + .quad 0x0002000004200000, 0x0000000000000800 + .quad 0x2000000004000002, 0x0000000004000800 + .quad 0x0000000000000800, 0x2002000000200002 +.L_s8: + .quad 0x0100010410001000, 0x0000010000001000 + .quad 0x0000000000040000, 0x0100010410041000 + .quad 0x0100000010000000, 0x0100010410001000 + .quad 0x0000000400000000, 0x0100000010000000 + .quad 0x0000000400040000, 0x0100000010040000 + .quad 0x0100010410041000, 0x0000010000041000 + .quad 0x0100010010041000, 0x0000010400041000 + .quad 0x0000010000001000, 0x0000000400000000 + .quad 0x0100000010040000, 0x0100000410000000 + .quad 0x0100010010001000, 0x0000010400001000 + .quad 0x0000010000041000, 0x0000000400040000 + .quad 0x0100000410040000, 0x0100010010041000 + .quad 0x0000010400001000, 0x0000000000000000 + .quad 0x0000000000000000, 0x0100000410040000 + .quad 0x0100000410000000, 0x0100010010001000 + .quad 0x0000010400041000, 0x0000000000040000 + .quad 0x0000010400041000, 0x0000000000040000 + .quad 0x0100010010041000, 0x0000010000001000 + .quad 0x0000000400000000, 0x0100000410040000 + .quad 0x0000010000001000, 0x0000010400041000 + .quad 0x0100010010001000, 0x0000000400000000 + .quad 0x0100000410000000, 0x0100000010040000 + .quad 0x0100000410040000, 0x0100000010000000 + .quad 0x0000000000040000, 0x0100010410001000 + .quad 0x0000000000000000, 0x0100010410041000 + .quad 0x0000000400040000, 0x0100000410000000 + .quad 0x0100000010040000, 0x0100010010001000 + .quad 0x0100010410001000, 0x0000000000000000 + .quad 0x0100010410041000, 0x0000010000041000 + .quad 0x0000010000041000, 0x0000010400001000 + .quad 0x0000010400001000, 0x0000000400040000 + .quad 0x0100000010000000, 0x0100010010041000 + +#endif +#endif diff --git a/cipher/des.c b/cipher/des.c index 6611fd3..bc2a474 100644 --- a/cipher/des.c +++ b/cipher/des.c @@ -119,9 +119,27 @@ #include "g10lib.h" #include "cipher.h" #include "bufhelp.h" +#include "cipher-selftest.h" + + +#define DES_BLOCKSIZE 8 + + +/* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */ +#undef USE_AMD64_ASM +#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) +# define USE_AMD64_ASM 1 +#endif + +/* Helper macro to force alignment to 16 bytes. */ +#ifdef HAVE_GCC_ATTRIBUTE_ALIGNED +# define ATTR_ALIGNED_16 __attribute__ ((aligned (16))) +#else +# define ATTR_ALIGNED_16 +#endif #if defined(__GNUC__) && defined(__GNU_LIBRARY__) -#define working_memcmp memcmp +# define working_memcmp memcmp #else /* * According to the SunOS man page, memcmp returns indeterminate sign @@ -171,6 +189,12 @@ static int tripledes_ecb_crypt (struct _tripledes_ctx *, const byte *, byte *, int); static int is_weak_key ( const byte *key ); static const char *selftest (void); +static unsigned int do_tripledes_encrypt(void *context, byte *outbuf, + const byte *inbuf ); +static unsigned int do_tripledes_decrypt(void *context, byte *outbuf, + const byte *inbuf ); +static gcry_err_code_t do_tripledes_setkey(void *context, const byte *key, + unsigned keylen); static int initialized; @@ -727,6 +751,46 @@ tripledes_set3keys (struct _tripledes_ctx *ctx, +#ifdef USE_AMD64_ASM + +/* Assembly implementation of triple-DES. */ +extern void _gcry_3des_amd64_crypt_block(const void *keys, byte *out, + const byte *in); + +/* These assembly implementations process three blocks in parallel. */ +extern void _gcry_3des_amd64_ctr_enc(const void *keys, byte *out, + const byte *in, byte *ctr); + +extern void _gcry_3des_amd64_cbc_dec(const void *keys, byte *out, + const byte *in, byte *iv); + +extern void _gcry_3des_amd64_cfb_dec(const void *keys, byte *out, + const byte *in, byte *iv); + +#define TRIPLEDES_ECB_BURN_STACK (8 * sizeof(void *)) + +/* + * Electronic Codebook Mode Triple-DES encryption/decryption of data + * according to 'mode'. Sometimes this mode is named 'EDE' mode + * (Encryption-Decryption-Encryption). + */ +static inline int +tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from, + byte * to, int mode) +{ + u32 *keys; + + keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys; + + _gcry_3des_amd64_crypt_block(keys, to, from); + + return 0; +} + +#else /*USE_AMD64_ASM*/ + +#define TRIPLEDES_ECB_BURN_STACK 32 + /* * Electronic Codebook Mode Triple-DES encryption/decryption of data * according to 'mode'. Sometimes this mode is named 'EDE' mode @@ -777,8 +841,158 @@ tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from, return 0; } +#endif /*!USE_AMD64_ASM*/ + + + +/* Bulk encryption of complete blocks in CTR mode. This function is only + intended for the bulk encryption feature of cipher.c. CTR is expected to be + of size DES_BLOCKSIZE. */ +void +_gcry_3des_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg, + const void *inbuf_arg, size_t nblocks) +{ + struct _tripledes_ctx *ctx = context; + unsigned char *outbuf = outbuf_arg; + const unsigned char *inbuf = inbuf_arg; + unsigned char tmpbuf[DES_BLOCKSIZE]; + int burn_stack_depth = TRIPLEDES_ECB_BURN_STACK; + int i; + +#ifdef USE_AMD64_ASM + { + int asm_burn_depth = 9 * sizeof(void *); + + if (nblocks >= 3 && burn_stack_depth < asm_burn_depth) + burn_stack_depth = asm_burn_depth; + + /* Process data in 3 block chunks. */ + while (nblocks >= 3) + { + _gcry_3des_amd64_ctr_enc(ctx->encrypt_subkeys, outbuf, inbuf, ctr); + + nblocks -= 3; + outbuf += 3 * DES_BLOCKSIZE; + inbuf += 3 * DES_BLOCKSIZE; + } + + /* Use generic code to handle smaller chunks... */ + } +#endif + + for ( ;nblocks; nblocks-- ) + { + /* Encrypt the counter. */ + tripledes_ecb_encrypt (ctx, ctr, tmpbuf); + /* XOR the input with the encrypted counter and store in output. */ + buf_xor(outbuf, tmpbuf, inbuf, DES_BLOCKSIZE); + outbuf += DES_BLOCKSIZE; + inbuf += DES_BLOCKSIZE; + /* Increment the counter. */ + for (i = DES_BLOCKSIZE; i > 0; i--) + { + ctr[i-1]++; + if (ctr[i-1]) + break; + } + } + + wipememory(tmpbuf, sizeof(tmpbuf)); + _gcry_burn_stack(burn_stack_depth); +} + + +/* Bulk decryption of complete blocks in CBC mode. This function is only + intended for the bulk encryption feature of cipher.c. */ +void +_gcry_3des_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg, + const void *inbuf_arg, size_t nblocks) +{ + struct _tripledes_ctx *ctx = context; + unsigned char *outbuf = outbuf_arg; + const unsigned char *inbuf = inbuf_arg; + unsigned char savebuf[DES_BLOCKSIZE]; + int burn_stack_depth = TRIPLEDES_ECB_BURN_STACK; + +#ifdef USE_AMD64_ASM + { + int asm_burn_depth = 10 * sizeof(void *); + + if (nblocks >= 3 && burn_stack_depth < asm_burn_depth) + burn_stack_depth = asm_burn_depth; + + /* Process data in 3 block chunks. */ + while (nblocks >= 3) + { + _gcry_3des_amd64_cbc_dec(ctx->decrypt_subkeys, outbuf, inbuf, iv); + + nblocks -= 3; + outbuf += 3 * DES_BLOCKSIZE; + inbuf += 3 * DES_BLOCKSIZE; + } + + /* Use generic code to handle smaller chunks... */ + } +#endif + + for ( ;nblocks; nblocks-- ) + { + /* INBUF is needed later and it may be identical to OUTBUF, so store + the intermediate result to SAVEBUF. */ + tripledes_ecb_decrypt (ctx, inbuf, savebuf); + + buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, DES_BLOCKSIZE); + inbuf += DES_BLOCKSIZE; + outbuf += DES_BLOCKSIZE; + } + + wipememory(savebuf, sizeof(savebuf)); + _gcry_burn_stack(burn_stack_depth); +} + + +/* Bulk decryption of complete blocks in CFB mode. This function is only + intended for the bulk encryption feature of cipher.c. */ +void +_gcry_3des_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg, + const void *inbuf_arg, size_t nblocks) +{ + struct _tripledes_ctx *ctx = context; + unsigned char *outbuf = outbuf_arg; + const unsigned char *inbuf = inbuf_arg; + int burn_stack_depth = TRIPLEDES_ECB_BURN_STACK; + +#ifdef USE_AMD64_ASM + { + int asm_burn_depth = 9 * sizeof(void *); + + if (nblocks >= 3 && burn_stack_depth < asm_burn_depth) + burn_stack_depth = asm_burn_depth; + /* Process data in 3 block chunks. */ + while (nblocks >= 3) + { + _gcry_3des_amd64_cfb_dec(ctx->encrypt_subkeys, outbuf, inbuf, iv); + nblocks -= 3; + outbuf += 3 * DES_BLOCKSIZE; + inbuf += 3 * DES_BLOCKSIZE; + } + + /* Use generic code to handle smaller chunks... */ + } +#endif + + for ( ;nblocks; nblocks-- ) + { + tripledes_ecb_encrypt (ctx, iv, iv); + buf_xor_n_copy(outbuf, iv, inbuf, DES_BLOCKSIZE); + outbuf += DES_BLOCKSIZE; + inbuf += DES_BLOCKSIZE; + } + + _gcry_burn_stack(burn_stack_depth); +} /* @@ -815,6 +1029,67 @@ is_weak_key ( const byte *key ) } +/* Alternative setkey for selftests; need larger key than default. */ +static gcry_err_code_t +bulk_selftest_setkey (void *context, const byte *__key, unsigned __keylen) +{ + static const unsigned char key[24] ATTR_ALIGNED_16 = { + 0x66,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F, + 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x22, + 0x18,0x2A,0x39,0x47,0x5E,0x6F,0x75,0x82 + }; + + (void)__key; + (void)__keylen; + + return do_tripledes_setkey(context, key, sizeof(key)); +} + + +/* Run the self-tests for DES-CTR, tests IV increment of bulk CTR + encryption. Returns NULL on success. */ +static const char * +selftest_ctr (void) +{ + const int nblocks = 3+1; + const int blocksize = DES_BLOCKSIZE; + const int context_size = sizeof(struct _tripledes_ctx); + + return _gcry_selftest_helper_ctr("3DES", &bulk_selftest_setkey, + &do_tripledes_encrypt, &_gcry_3des_ctr_enc, nblocks, blocksize, + context_size); +} + + +/* Run the self-tests for DES-CBC, tests bulk CBC decryption. + Returns NULL on success. */ +static const char * +selftest_cbc (void) +{ + const int nblocks = 3+2; + const int blocksize = DES_BLOCKSIZE; + const int context_size = sizeof(struct _tripledes_ctx); + + return _gcry_selftest_helper_cbc("3DES", &bulk_selftest_setkey, + &do_tripledes_encrypt, &_gcry_3des_cbc_dec, nblocks, blocksize, + context_size); +} + + +/* Run the self-tests for DES-CFB, tests bulk CBC decryption. + Returns NULL on success. */ +static const char * +selftest_cfb (void) +{ + const int nblocks = 3+2; + const int blocksize = DES_BLOCKSIZE; + const int context_size = sizeof(struct _tripledes_ctx); + + return _gcry_selftest_helper_cfb("3DES", &bulk_selftest_setkey, + &do_tripledes_encrypt, &_gcry_3des_cfb_dec, nblocks, blocksize, + context_size); +} + /* * Performs a selftest of this DES/Triple-DES implementation. @@ -824,6 +1099,8 @@ is_weak_key ( const byte *key ) static const char * selftest (void) { + const char *r; + /* * Check if 'u32' is really 32 bits wide. This DES / 3DES implementation * need this. @@ -1003,6 +1280,15 @@ selftest (void) return "DES weak key detection failed"; } + if ( (r = selftest_cbc ()) ) + return r; + + if ( (r = selftest_cfb ()) ) + return r; + + if ( (r = selftest_ctr ()) ) + return r; + return 0; } @@ -1060,7 +1346,7 @@ do_tripledes_encrypt( void *context, byte *outbuf, const byte *inbuf ) struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context; tripledes_ecb_encrypt ( ctx, inbuf, outbuf ); - return /*burn_stack*/ (32); + return /*burn_stack*/ TRIPLEDES_ECB_BURN_STACK; } static unsigned int @@ -1068,7 +1354,7 @@ do_tripledes_decrypt( void *context, byte *outbuf, const byte *inbuf ) { struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context; tripledes_ecb_decrypt ( ctx, inbuf, outbuf ); - return /*burn_stack*/ (32); + return /*burn_stack*/ TRIPLEDES_ECB_BURN_STACK; } static gcry_err_code_t diff --git a/configure.ac b/configure.ac index a0f75a5..79f79ef 100644 --- a/configure.ac +++ b/configure.ac @@ -1671,6 +1671,13 @@ LIST_MEMBER(des, $enabled_ciphers) if test "$found" = "1" ; then GCRYPT_CIPHERS="$GCRYPT_CIPHERS des.lo" AC_DEFINE(USE_DES, 1, [Defined if this module should be included]) + + case "${host}" in + x86_64-*-*) + # Build with the assembly implementation + GCRYPT_CIPHERS="$GCRYPT_CIPHERS des-amd64.lo" + ;; + esac fi LIST_MEMBER(aes, $enabled_ciphers) diff --git a/src/cipher.h b/src/cipher.h index cd981b3..5d1b5f6 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -173,6 +173,19 @@ void _gcry_camellia_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, size_t nblocks); +/*-- des.c --*/ +void _gcry_3des_ctr_enc (void *context, unsigned char *ctr, + void *outbuf_arg, const void *inbuf_arg, + size_t nblocks); + +void _gcry_3des_cbc_dec (void *context, unsigned char *iv, + void *outbuf_arg, const void *inbuf_arg, + size_t nblocks); + +void _gcry_3des_cfb_dec (void *context, unsigned char *iv, + void *outbuf_arg, const void *inbuf_arg, + size_t nblocks); + /*-- serpent.c --*/ void _gcry_serpent_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg,