From b75d794f38423ca04aadc1fa30bde718e07132b3fe217845e3310bbc4d049539 Mon Sep 17 00:00:00 2001 From: "P. Janouch" Date: Mon, 22 Aug 2016 09:21:16 +0000 Subject: [PATCH] Accepting request 420659 from security:privacy libgcrypt 1.7.3 OBS-URL: https://build.opensuse.org/request/show/420659 OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/libgcrypt?expand=0&rev=87 --- 0002-Compile-DRBG.patch | 23 - ...finitions-of-interfaces-for-random.c.patch | 32 - ...-DRBG-from-common-libgcrypt-RNG-code.patch | 132 - ...finitions-for-gcry_control-callbacks.patch | 31 - ...-DRBG-specific-gcry_control-requests.patch | 63 - drbg_test.patch | 299 +- libgcrypt-1.6.1-fips-cavs.patch | 89 +- libgcrypt-1.6.1-fips-cfgrandom.patch | 65 +- libgcrypt-1.6.3-aliasing.patch | 71 +- libgcrypt-1.6.6.tar.bz2 | 3 - libgcrypt-1.6.6.tar.bz2.sig | Bin 287 -> 0 bytes libgcrypt-1.7.3.tar.bz2 | 3 + libgcrypt-1.7.3.tar.bz2.sig | Bin 0 -> 287 bytes libgcrypt-fips-dsa.patch | 182 -- libgcrypt-fips_ecdsa.patch | 30 - libgcrypt-fix-rng.patch | 12 +- libgcrypt-sparcv9.diff | 12 +- libgcrypt.changes | 144 + libgcrypt.spec | 42 +- ...A-Deterministic-Random-Bit-Generator.patch | 2406 ----------------- v9-0007-User-interface-to-DRBG.patch | 309 --- 21 files changed, 437 insertions(+), 3511 deletions(-) delete mode 100644 0002-Compile-DRBG.patch delete mode 100644 0003-Function-definitions-of-interfaces-for-random.c.patch delete mode 100644 0004-Invoke-DRBG-from-common-libgcrypt-RNG-code.patch delete mode 100644 0005-Function-definitions-for-gcry_control-callbacks.patch delete mode 100644 0006-DRBG-specific-gcry_control-requests.patch delete mode 100644 libgcrypt-1.6.6.tar.bz2 delete mode 100644 libgcrypt-1.6.6.tar.bz2.sig create mode 100644 libgcrypt-1.7.3.tar.bz2 create mode 100644 libgcrypt-1.7.3.tar.bz2.sig delete mode 100644 libgcrypt-fips-dsa.patch delete mode 100644 libgcrypt-fips_ecdsa.patch delete mode 100644 v9-0001-SP800-90A-Deterministic-Random-Bit-Generator.patch delete mode 100644 v9-0007-User-interface-to-DRBG.patch diff --git a/0002-Compile-DRBG.patch b/0002-Compile-DRBG.patch deleted file mode 100644 index 8f03a5c..0000000 --- a/0002-Compile-DRBG.patch +++ /dev/null @@ -1,23 +0,0 @@ -From fe272496f0f9e6e12bfa35f6f1c9d05af9feca2c Mon Sep 17 00:00:00 2001 -From: Stephan Mueller -Date: Sat, 8 Mar 2014 23:13:33 +0100 -Subject: [PATCH v3 2/7] Compile DRBG -To: gcrypt-devel@gnupg.org -Cc: jeremy.wayne.powell@gmail.com - -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 - diff --git a/0003-Function-definitions-of-interfaces-for-random.c.patch b/0003-Function-definitions-of-interfaces-for-random.c.patch deleted file mode 100644 index 472ffc8..0000000 --- a/0003-Function-definitions-of-interfaces-for-random.c.patch +++ /dev/null @@ -1,32 +0,0 @@ -From bb91250be3eeb2309285fa9865166cb381104c81 Mon Sep 17 00:00:00 2001 -From: Stephan Mueller -Date: Sat, 8 Mar 2014 23:14:16 +0100 -Subject: [PATCH v3 3/7] Function definitions of interfaces for random.c -To: gcrypt-devel@gnupg.org -Cc: jeremy.wayne.powell@gmail.com - -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); diff --git a/0004-Invoke-DRBG-from-common-libgcrypt-RNG-code.patch b/0004-Invoke-DRBG-from-common-libgcrypt-RNG-code.patch deleted file mode 100644 index 05e3dbc..0000000 --- a/0004-Invoke-DRBG-from-common-libgcrypt-RNG-code.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 6aa1bc1df0dbbf5b4cb06b86f949aa9d80f68700 Mon Sep 17 00:00:00 2001 -From: Stephan Mueller -Date: Sat, 8 Mar 2014 23:14:58 +0100 -Subject: [PATCH v3 4/7] Invoke DRBG from common libgcrypt RNG code -To: gcrypt-devel@gnupg.org -Cc: jeremy.wayne.powell@gmail.com - -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 ---- -Index: libgcrypt-1.6.1/random/random.c -=================================================================== ---- libgcrypt-1.6.1.orig/random/random.c 2014-01-29 10:48:38.000000000 +0100 -+++ libgcrypt-1.6.1/random/random.c 2014-05-06 14:51:42.350644283 +0200 -@@ -153,11 +153,13 @@ _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 -@@ -174,11 +176,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 -@@ -212,7 +216,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 (); - } -@@ -271,7 +276,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 (); - } -@@ -301,11 +307,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 */ -@@ -437,7 +445,8 @@ _gcry_create_nonce (void *buffer, size_t - 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; - } - -@@ -514,7 +523,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. */ - } -@@ -530,6 +540,7 @@ _gcry_random_init_external_test (void ** - 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, -@@ -544,6 +555,7 @@ _gcry_random_init_external_test (void ** - 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 -@@ -554,6 +566,7 @@ _gcry_random_run_external_test (void *co - void - _gcry_random_deinit_external_test (void *context) - { -+ return; - if (fips_mode ()) - _gcry_rngfips_deinit_external_test (context); - } diff --git a/0005-Function-definitions-for-gcry_control-callbacks.patch b/0005-Function-definitions-for-gcry_control-callbacks.patch deleted file mode 100644 index ffb0a44..0000000 --- a/0005-Function-definitions-for-gcry_control-callbacks.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 67106d6e63ae5aff91e8fc7072def4c027546d39 Mon Sep 17 00:00:00 2001 -From: Stephan Mueller -Date: Sat, 8 Mar 2014 23:15:43 +0100 -Subject: [PATCH v3 5/7] Function definitions for gcry_control callbacks -To: gcrypt-devel@gnupg.org -Cc: jeremy.wayne.powell@gmail.com - -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); - diff --git a/0006-DRBG-specific-gcry_control-requests.patch b/0006-DRBG-specific-gcry_control-requests.patch deleted file mode 100644 index 02ba7ea..0000000 --- a/0006-DRBG-specific-gcry_control-requests.patch +++ /dev/null @@ -1,63 +0,0 @@ -From bac07e2002f1de9b9ffad477135a67b1bdcf5d85 Mon Sep 17 00:00:00 2001 -From: Stephan Mueller -Date: Sat, 8 Mar 2014 23:16:24 +0100 -Subject: [PATCH v3 6/7] DRBG specific gcry_control requests -To: gcrypt-devel@gnupg.org -Cc: jeremy.wayne.powell@gmail.com - -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; diff --git a/drbg_test.patch b/drbg_test.patch index db455ac..2538293 100644 --- a/drbg_test.patch +++ b/drbg_test.patch @@ -1,9 +1,9 @@ -Index: libgcrypt-1.6.1/tests/drbg_test.c +Index: libgcrypt-1.7.2/tests/drbg_test.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ libgcrypt-1.6.1/tests/drbg_test.c 2014-09-02 16:49:42.279449470 +0200 -@@ -0,0 +1,1279 @@ -+/* DRBG test for libgcryt ++++ libgcrypt-1.7.2/tests/drbg_test.c 2016-08-16 16:04:52.289060124 +0200 +@@ -0,0 +1,1332 @@ ++/* DRBG test for libgcrypt + Copyright (C) 2014 Stephan Mueller + + Compile: @@ -17,69 +17,155 @@ Index: libgcrypt-1.6.1/tests/drbg_test.c +#include +#endif +#include ++#include +#include +#include +#include ++#include ++#include +#include "gcrypt.h" + ++/* The following definitions are taken verbatim from random/random-drbg.c. ++ * libgcrypt upstream removed the public apis from gcrypt.h in ++ * http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=commit;h=fd13372fa9069d3a72947ea59c57e33637c936bf ++ */ ++/****************************************************************** ++ * Constants ++ ******************************************************************/ ++ ++/* ++ * 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 ((u32)1<<28) ++ ++/* CTR type modifiers (A.1)*/ ++#define DRBG_CTRAES ((u32)1<<0) ++#define DRBG_CTRSERPENT ((u32)1<<1) ++#define DRBG_CTRTWOFISH ((u32)1<<2) ++#define DRBG_CTR_MASK (DRBG_CTRAES | DRBG_CTRSERPENT \ ++ | DRBG_CTRTWOFISH) ++ ++/* HASH type modifiers (A.2)*/ ++#define DRBG_HASHSHA1 ((u32)1<<4) ++#define DRBG_HASHSHA224 ((u32)1<<5) ++#define DRBG_HASHSHA256 ((u32)1<<6) ++#define DRBG_HASHSHA384 ((u32)1<<7) ++#define DRBG_HASHSHA512 ((u32)1<<8) ++#define DRBG_HASH_MASK (DRBG_HASHSHA1 | DRBG_HASHSHA224 \ ++ | DRBG_HASHSHA256 | DRBG_HASHSHA384 \ ++ | DRBG_HASHSHA512) ++/* type modifiers (A.3)*/ ++#define DRBG_HMAC ((u32)1<<12) ++#define DRBG_SYM128 ((u32)1<<13) ++#define DRBG_SYM192 ((u32)1<<14) ++#define DRBG_SYM256 ((u32)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) ++ ++ ++/* The default DRGB type. */ ++#define DRBG_DEFAULT_TYPE DRBG_NOPR_HMACSHA256 ++ +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + -+/* bin/hex conversion stolen from OpenSSL */ -+static int bin2hex(const unsigned char *in,int len,char *out) ++static char hex_char_map_l[] = { '0', '1', '2', '3', '4', '5', '6', '7', ++ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; ++static char hex_char_map_u[] = { '0', '1', '2', '3', '4', '5', '6', '7', ++ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; ++static char hex_char(unsigned int bin, int u) +{ -+ int n1, n2; -+ unsigned char ch; -+ -+ for (n1=0,n2=0 ; n1 < len ; ++n1) -+ { -+ ch=in[n1] >> 4; -+ if (ch <= 0x09) -+ out[n2++]=ch+'0'; -+ else -+ out[n2++]=ch-10+'a'; -+ ch=in[n1] & 0x0f; -+ if(ch <= 0x09) -+ out[n2++]=ch+'0'; -+ else -+ out[n2++]=ch-10+'a'; -+ } -+ out[n2]='\0'; -+ return n2; ++ if (bin < sizeof(hex_char_map_l)) ++ return (u) ? hex_char_map_u[bin] : hex_char_map_l[bin]; ++ return 'X'; +} + -+int hex2bin(const char *in, unsigned char *out) ++/* ++ * Convert binary string into hex representation ++ * @bin input buffer with binary data ++ * @binlen length of bin ++ * @hex output buffer to store hex data ++ * @hexlen length of already allocated hex buffer (should be at least ++ * twice binlen -- if not, only a fraction of binlen is converted) ++ * @u case of hex characters (0=>lower case, 1=>upper case) ++ */ ++static void bin2hex(const unsigned char *bin, size_t binlen, ++ char *hex, size_t hexlen, int u) +{ -+ int n1, n2; -+ unsigned char ch; ++ size_t i = 0; ++ size_t chars = (binlen > (hexlen / 2)) ? (hexlen / 2) : binlen; + -+ for (n1=0,n2=0 ; in[n1] && in[n1] != '\n' ; ) -+ { /* first byte */ -+ if ((in[n1] >= '0') && (in[n1] <= '9')) -+ ch = in[n1++] - '0'; -+ else if ((in[n1] >= 'A') && (in[n1] <= 'F')) -+ ch = in[n1++] - 'A' + 10; -+ else if ((in[n1] >= 'a') && (in[n1] <= 'f')) -+ ch = in[n1++] - 'a' + 10; -+ else -+ return -1; -+ if(!in[n1]) -+ { -+ out[n2++]=ch; -+ break; -+ } -+ out[n2] = ch << 4; -+ /* second byte */ -+ if ((in[n1] >= '0') && (in[n1] <= '9')) -+ ch = in[n1++] - '0'; -+ else if ((in[n1] >= 'A') && (in[n1] <= 'F')) -+ ch = in[n1++] - 'A' + 10; -+ else if ((in[n1] >= 'a') && (in[n1] <= 'f')) -+ ch = in[n1++] - 'a' + 10; -+ else -+ return -1; -+ out[n2++] |= ch; ++ for (i = 0; i < chars; i++) { ++ hex[(i*2)] = hex_char((bin[i] >> 4), u); ++ hex[((i*2)+1)] = hex_char((bin[i] & 0x0f), u); ++ } ++} ++ ++static int bin_char(unsigned char hex) ++{ ++ if (48 <= hex && 57 >= hex) ++ return (hex - 48); ++ if (65 <= hex && 70 >= hex) ++ return (hex - 55); ++ if (97 <= hex && 102 >= hex) ++ return (hex - 87); ++ return 0; ++} ++/* ++ * Convert hex representation into binary string ++ * @hex input buffer with hex representation ++ * @hexlen length of hex ++ * @bin output buffer with binary data ++ * @binlen length of already allocated bin buffer (should be at least ++ * half of hexlen -- if not, only a fraction of hexlen is converted) ++ */ ++static void hex2bin(const unsigned char *hex, size_t hexlen, ++ unsigned char *bin, size_t binlen) ++{ ++ size_t i = 0; ++ size_t chars = (binlen > (hexlen / 2)) ? (hexlen / 2) : binlen; ++ ++ for (i = 0; i < chars; i++) { ++ bin[i] = bin_char(hex[(i*2)]) << 4; ++ bin[i] |= bin_char(hex[((i*2)+1)]); + } -+ return n2; +} + +/* Print a error message and exit the process with an error code. */ @@ -95,7 +181,7 @@ Index: libgcrypt-1.6.1/tests/drbg_test.c +} + + -+struct drbg_test_vector ++struct gcry_drbg_test_vector +{ + u_int32_t flags; /* flags selecting the DRBG type */ + unsigned char *entropy; /* entropy string for initialization -- this @@ -120,7 +206,7 @@ Index: libgcrypt-1.6.1/tests/drbg_test.c + size_t expectedlen; /* length of expected random value */ +}; + -+struct drbg_test_vector drbg_test_pr[] = { ++struct gcry_drbg_test_vector drbg_test_pr[] = { + { + .flags = (DRBG_PR_HASHSHA256), + .entropy = (unsigned char *) @@ -549,7 +635,7 @@ Index: libgcrypt-1.6.1/tests/drbg_test.c + }, +}; + -+struct drbg_test_vector drbg_test_nopr[] = { ++struct gcry_drbg_test_vector drbg_test_nopr[] = { + { + .flags = DRBG_NOPR_HASHSHA256, + .entropy = (unsigned char *) @@ -927,57 +1013,22 @@ Index: libgcrypt-1.6.1/tests/drbg_test.c + }, +}; + -+ -+/* -+ * CAVS Test driver -+ * -+ * @test: one test vector -+ * @pr: true/false for enabling or disabling prediction resistance -+ */ -+int drbg_cavs_test(struct drbg_test_vector *test, unsigned char *buf, -+ size_t buflen) -+{ -+ int ret = -1; -+ struct drbg_test_data test_data; -+ struct drbg_string addtl, pers, testentropy; -+ -+ test_data.testentropy = &testentropy; -+ drbg_string_fill(&testentropy, test->entropy, test->entropylen); -+ drbg_string_fill(&pers, test->pers, test->perslen); -+ ret = gcry_control(GCRYCTL_DRBG_REINIT, test->flags, &pers, &test_data); -+ if(ret) -+ { -+ printf("Test FAIL: re-init DRBG with test entropy\n"); -+ return ret; -+ } -+ -+ drbg_string_fill(&addtl, test->addtla, test->addtllen); -+ if(test->entpra) -+ drbg_string_fill(&testentropy, test->entpra, test->entprlen); -+ gcry_randomize_drbg_test(buf, buflen, GCRY_STRONG_RANDOM, &addtl, -+ &test_data); -+ -+ drbg_string_fill(&addtl, test->addtlb, test->addtllen); -+ if(test->entpra) -+ drbg_string_fill(&testentropy, test->entprb, test->entprlen); -+ -+ gcry_randomize_drbg_test(buf, buflen, GCRY_STRONG_RANDOM, &addtl, -+ &test_data); -+ -+ return ret; -+} -+ +struct drbg_flags +{ + u_int32_t flags; +}; + ++gpg_err_code_t ++gcry_drbg_cavs_test (struct gcry_drbg_test_vector *test, unsigned char *buf); ++extern gpg_err_code_t ++gcry_drbg_healthcheck_one (struct gcry_drbg_test_vector *test); ++ +void builtin_test(void) +{ + /* this must be larger than 128 as otherwise there is a crash */ +#define OUTLEN 150 + char rndbuf[OUTLEN]; -+ char out[200]; ++ char out[(OUTLEN * 2 + 1)]; + int i = 0; + int ret = 0; + int result = 0; @@ -1013,8 +1064,10 @@ Index: libgcrypt-1.6.1/tests/drbg_test.c + if(0 == ret) + { + printf("Test PASS: enabling DRBG %d\n", i); ++ memset(rndbuf, 0, OUTLEN); + gcry_randomize(&rndbuf, OUTLEN, GCRY_STRONG_RANDOM); -+ bin2hex(rndbuf, OUTLEN, out); ++ memset(out, 0, sizeof(out)); ++ bin2hex(rndbuf, OUTLEN, out, sizeof(out), 0); + printf("Test PASS: gcry_randomize generated strong random bytes for DRBG %d: %s\n", i, out); + } + else @@ -1033,8 +1086,7 @@ Index: libgcrypt-1.6.1/tests/drbg_test.c + for(i = 0; ARRAY_SIZE(drbg_test_nopr) > i; i++) + { + memset(rndbuf, 0, drbg_test_nopr[i].expectedlen); -+ drbg_cavs_test(&drbg_test_nopr[i], rndbuf, drbg_test_nopr[i].expectedlen); -+ ret = memcmp(drbg_test_nopr[i].expected, rndbuf, drbg_test_nopr[i].expectedlen); ++ ret = gcry_control(75, &drbg_test_nopr[i], NULL); + if(ret) + printf("CAVS test (nopr) FAILED %d, testdef %d\n", ret, i); + else @@ -1045,8 +1097,7 @@ Index: libgcrypt-1.6.1/tests/drbg_test.c + for(i = 0; ARRAY_SIZE(drbg_test_pr) > i; i++) + { + memset(rndbuf, 0, drbg_test_pr[i].expectedlen); -+ drbg_cavs_test(&drbg_test_pr[i], rndbuf, drbg_test_pr[i].expectedlen); -+ ret = memcmp(drbg_test_pr[i].expected, rndbuf, drbg_test_pr[i].expectedlen); ++ ret = gcry_control(75, &drbg_test_pr[i], NULL); + if(ret) + printf("CAVS test (pr) FAILED %d, testdef %d\n", ret, i); + else @@ -1076,7 +1127,7 @@ Index: libgcrypt-1.6.1/tests/drbg_test.c + +} + -+static void generate_test(struct drbg_test_vector *test) ++static void generate_test(struct gcry_drbg_test_vector *test) +{ + unsigned char *buf; +#define DATALEN 10 @@ -1090,7 +1141,7 @@ Index: libgcrypt-1.6.1/tests/drbg_test.c + + if (test && test->flags) + { -+ if (gcry_control(GCRYCTL_DRBG_REINIT, test->flags, NULL, NULL)) ++ if (gcry_control(GCRYCTL_DRBG_REINIT, test->flags, NULL)) + { + printf("Test FAIL: re-init DRBG with test entropy\n"); + return; @@ -1108,6 +1159,7 @@ Index: libgcrypt-1.6.1/tests/drbg_test.c + } + + gcry_randomize(buf, len, GCRY_STRONG_RANDOM); ++ write(1, buf, len); + free (buf); + } +} @@ -1140,7 +1192,7 @@ Index: libgcrypt-1.6.1/tests/drbg_test.c + } + + tmp = drbg_malloc(tmplen); -+ hex2bin(in, tmp); ++ hex2bin(in, strlen(in), tmp, tmplen); + *out = tmp; + *len = tmplen; +} @@ -1167,13 +1219,12 @@ Index: libgcrypt-1.6.1/tests/drbg_test.c +main (int argc, char **argv) +{ + int c = 0; -+ long len = 0; + unsigned char *buf; + unsigned char *outbuf; -+ struct drbg_test_vector exttest; ++ struct gcry_drbg_test_vector exttest; +#define MAXDATA 256 + -+ memset(&exttest, 0, sizeof(struct drbg_test_vector)); ++ memset(&exttest, 0, sizeof(struct gcry_drbg_test_vector)); + gcry_control (GCRYCTL_SET_VERBOSITY, 2); + gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); + if (!gcry_check_version ("1.5.0")) @@ -1233,32 +1284,34 @@ Index: libgcrypt-1.6.1/tests/drbg_test.c + hex2bin_m(optarg, &exttest.pers, &exttest.perslen); + break; + case 'l': -+ len = atol(optarg); ++ exttest.expectedlen = atoi(optarg); + break; + default: + usage(); + } + } + -+ if (0 >= len) ++ if (0 >= exttest.expectedlen) + usage(); + -+ buf = malloc(len); ++ buf = malloc(exttest.expectedlen); + if(!buf) { -+ fprintf(stderr, "Cannot allocate %li bytes\n", len); ++ fprintf(stderr, "Cannot allocate %li bytes\n", exttest.expectedlen); + return -1; + } -+ outbuf = malloc(len * 2 + 1); ++ outbuf = malloc(exttest.expectedlen * 2 + 1); + if(!outbuf) { -+ fprintf(stderr, "Cannot allocate %li bytes\n", (len*2+1)); ++ fprintf(stderr, "Cannot allocate %li bytes\n", ++ (exttest.expectedlen*2+1)); + return -1; + } -+ memset(outbuf, 0, len * 2 + 1); ++ memset(outbuf, 0, exttest.expectedlen * 2 + 1); + if (exttest.entropy) -+ drbg_cavs_test(&exttest, buf, len); ++ gcry_control(75, &exttest, buf); + else -+ gcry_randomize(buf, len, GCRY_STRONG_RANDOM); -+ bin2hex(buf, len, outbuf); ++ gcry_randomize(buf, exttest.expectedlen, GCRY_STRONG_RANDOM); ++ bin2hex(buf, exttest.expectedlen, ++ outbuf, exttest.expectedlen * 2 + 1, 0); + + printf("%s\n", outbuf); + @@ -1282,11 +1335,11 @@ Index: libgcrypt-1.6.1/tests/drbg_test.c + return 0; +} + -Index: libgcrypt-1.6.1/Makefile.am +Index: libgcrypt-1.7.2/Makefile.am =================================================================== ---- libgcrypt-1.6.1.orig/Makefile.am 2014-01-12 12:19:50.000000000 +0100 -+++ libgcrypt-1.6.1/Makefile.am 2014-09-02 16:51:10.315504510 +0200 -@@ -36,6 +36,14 @@ EXTRA_DIST = autogen.sh autogen.rc READM +--- libgcrypt-1.7.2.orig/Makefile.am 2016-08-16 15:57:43.397736723 +0200 ++++ libgcrypt-1.7.2/Makefile.am 2016-08-16 15:57:44.341752563 +0200 +@@ -42,6 +42,14 @@ EXTRA_DIST = autogen.sh autogen.rc READM DISTCLEANFILES = diff --git a/libgcrypt-1.6.1-fips-cavs.patch b/libgcrypt-1.6.1-fips-cavs.patch index b3d0cd9..825237e 100644 --- a/libgcrypt-1.6.1-fips-cavs.patch +++ b/libgcrypt-1.6.1-fips-cavs.patch @@ -1,6 +1,7 @@ -diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_driver.pl ---- libgcrypt-1.6.1/tests/cavs_driver.pl.cavs 2013-03-15 20:25:38.000000000 +0100 -+++ libgcrypt-1.6.1/tests/cavs_driver.pl 2014-02-28 14:46:16.436544639 +0100 +Index: libgcrypt-1.7.2/tests/cavs_driver.pl +=================================================================== +--- libgcrypt-1.7.2.orig/tests/cavs_driver.pl ++++ libgcrypt-1.7.2/tests/cavs_driver.pl @@ -1,9 +1,11 @@ #!/usr/bin/env perl # @@ -674,9 +675,10 @@ diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_dr $dsa_sign = \&libgcrypt_dsa_sign; $dsa_verify = \&libgcrypt_dsa_verify; $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; -diff -up libgcrypt-1.6.1/tests/cavs_tests.sh.cavs libgcrypt-1.6.1/tests/cavs_tests.sh ---- libgcrypt-1.6.1/tests/cavs_tests.sh.cavs 2013-03-15 20:25:38.000000000 +0100 -+++ libgcrypt-1.6.1/tests/cavs_tests.sh 2014-02-28 14:46:16.437544662 +0100 +Index: libgcrypt-1.7.2/tests/cavs_tests.sh +=================================================================== +--- libgcrypt-1.7.2.orig/tests/cavs_tests.sh ++++ libgcrypt-1.7.2/tests/cavs_tests.sh @@ -55,7 +55,7 @@ function run_one_test () { [ -d "$respdir" ] || mkdir "$respdir" [ -f "$rspfile" ] && rm "$rspfile" @@ -686,10 +688,11 @@ diff -up libgcrypt-1.6.1/tests/cavs_tests.sh.cavs libgcrypt-1.6.1/tests/cavs_tes dflag="-D" fi -diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c ---- libgcrypt-1.6.1/tests/fipsdrv.c.cavs 2013-12-16 18:44:32.000000000 +0100 -+++ libgcrypt-1.6.1/tests/fipsdrv.c 2014-02-28 14:46:16.437544662 +0100 -@@ -893,6 +893,9 @@ print_mpi_line (gcry_mpi_t a, int no_lz) +Index: libgcrypt-1.7.2/tests/fipsdrv.c +=================================================================== +--- libgcrypt-1.7.2.orig/tests/fipsdrv.c ++++ libgcrypt-1.7.2/tests/fipsdrv.c +@@ -892,6 +892,9 @@ print_mpi_line (gcry_mpi_t a, int no_lz) die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); p = buf; @@ -699,7 +702,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) p += 2; -@@ -1675,14 +1678,14 @@ run_rsa_verify (const void *data, size_t +@@ -1765,14 +1768,14 @@ run_rsa_verify (const void *data, size_t /* Generate a DSA key of size KEYSIZE and return the complete S-expression. */ static gcry_sexp_t @@ -717,7 +720,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c if (err) die ("gcry_sexp_build failed for DSA key generation: %s\n", gpg_strerror (err)); -@@ -1700,7 +1703,7 @@ dsa_gen (int keysize) +@@ -1790,7 +1793,7 @@ dsa_gen (int keysize) /* Generate a DSA key of size KEYSIZE and return the complete S-expression. */ static gcry_sexp_t @@ -726,7 +729,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c { gpg_error_t err; gcry_sexp_t keyspec, key; -@@ -1709,10 +1712,11 @@ dsa_gen_with_seed (int keysize, const vo +@@ -1799,10 +1802,11 @@ dsa_gen_with_seed (int keysize, const vo "(genkey" " (dsa" " (nbits %d)" @@ -740,7 +743,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c if (err) die ("gcry_sexp_build failed for DSA key generation: %s\n", gpg_strerror (err)); -@@ -1720,6 +1724,37 @@ dsa_gen_with_seed (int keysize, const vo +@@ -1810,6 +1814,37 @@ dsa_gen_with_seed (int keysize, const vo err = gcry_pk_genkey (&key, keyspec); if (err) die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); @@ -778,7 +781,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c gcry_sexp_release (keyspec); -@@ -1732,7 +1767,7 @@ dsa_gen_with_seed (int keysize, const vo +@@ -1849,7 +1884,7 @@ ecdsa_gen_key (const char *curve) with one parameter per line in hex format using this order: p, q, g, seed, counter, h. */ static void @@ -787,7 +790,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c { gcry_sexp_t l1, l2; gcry_mpi_t mpi; -@@ -1768,6 +1803,9 @@ print_dsa_domain_parameters (gcry_sexp_t +@@ -1885,6 +1920,9 @@ print_dsa_domain_parameters (gcry_sexp_t } gcry_sexp_release (l1); @@ -797,7 +800,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c /* Extract the seed values. */ l1 = gcry_sexp_find_token (key, "misc-key-info", 0); if (!l1) -@@ -1819,38 +1857,106 @@ print_dsa_domain_parameters (gcry_sexp_t +@@ -1976,38 +2014,106 @@ print_ecdsa_dq (gcry_sexp_t key) } @@ -914,7 +917,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c fp = fopen (filename, "wb"); if (!fp) -@@ -1863,6 +1969,53 @@ run_dsa_gen (int keysize, const char *fi +@@ -2020,6 +2126,53 @@ run_dsa_gen (int keysize, const char *fi } @@ -968,7 +971,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c /* Sign DATA of length DATALEN using the key taken from the S-expression encoded KEYFILE. */ -@@ -1872,11 +2025,16 @@ run_dsa_sign (const void *data, size_t d +@@ -2029,11 +2182,16 @@ run_dsa_sign (const void *data, size_t d { gpg_error_t err; gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2; @@ -988,7 +991,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c if (!err) { err = gcry_sexp_build (&s_data, NULL, -@@ -1887,8 +2045,6 @@ run_dsa_sign (const void *data, size_t d +@@ -2044,8 +2202,6 @@ run_dsa_sign (const void *data, size_t d die ("gcry_sexp_build failed for DSA data input: %s\n", gpg_strerror (err)); @@ -997,7 +1000,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c err = gcry_pk_sign (&s_sig, s_data, s_key); if (err) { -@@ -1964,13 +2120,18 @@ run_dsa_verify (const void *data, size_t +@@ -2121,13 +2277,18 @@ run_dsa_verify (const void *data, size_t { gpg_error_t err; gcry_sexp_t s_data, s_key, s_sig; @@ -1005,11 +1008,11 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c + char hash[128]; gcry_mpi_t tmpmpi; + int algo; -+ -+ s_key = read_sexp_from_file (keyfile); -+ algo = dsa_hash_from_key(s_key); - gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); ++ s_key = read_sexp_from_file (keyfile); ++ algo = dsa_hash_from_key(s_key); ++ + gcry_md_hash_buffer (algo, hash, data, datalen); /* Note that we can't simply use %b with HASH to build the S-expression, because that might yield a negative value. */ @@ -1019,7 +1022,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c if (!err) { err = gcry_sexp_build (&s_data, NULL, -@@ -1981,7 +2142,6 @@ run_dsa_verify (const void *data, size_t +@@ -2138,7 +2299,6 @@ run_dsa_verify (const void *data, size_t die ("gcry_sexp_build failed for DSA data input: %s\n", gpg_strerror (err)); @@ -1027,24 +1030,24 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c s_sig = read_sexp_from_file (sigfile); err = gcry_pk_verify (s_sig, s_data, s_key); -@@ -2014,7 +2174,7 @@ usage (int show_help) - "Run a crypto operation using hex encoded input and output.\n" +@@ -2304,7 +2464,7 @@ usage (int show_help) "MODE:\n" " encrypt, decrypt, digest, random, hmac-sha,\n" -- " rsa-{derive,gen,sign,verify}, dsa-{pqg-gen,gen,sign,verify}\n" -+ " rsa-{derive,gen,sign,verify}, dsa-{pq-gen,g-gen,gen,sign,verify}\n" + " rsa-{derive,gen,sign,verify},\n" +- " dsa-{pqg-gen,gen,sign,verify}, ecdsa-{gen-key,sign,verify}\n" ++ " dsa-{pq-gen,g-gen,gen,sign,verify}, ecdsa-{gen-key,sign,verify}\n" "OPTIONS:\n" " --verbose Print additional information\n" " --binary Input and output is in binary form\n" -@@ -2024,6 +2184,7 @@ usage (int show_help) - " --dt DT Use the hex encoded DT for the RNG\n" +@@ -2315,6 +2475,7 @@ usage (int show_help) " --algo NAME Use algorithm NAME\n" + " --curve NAME Select ECC curve spec NAME\n" " --keysize N Use a keysize of N bits\n" + " --qize N Use a DSA q parameter size of N bits\n" " --signature NAME Take signature from file NAME\n" " --chunk N Read in chunks of N bytes (implies --binary)\n" " --pkcs1 Use PKCS#1 encoding\n" -@@ -2050,6 +2211,7 @@ main (int argc, char **argv) +@@ -2344,6 +2505,7 @@ main (int argc, char **argv) const char *dt_string = NULL; const char *algo_string = NULL; const char *keysize_string = NULL; @@ -1052,7 +1055,7 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c const char *signature_string = NULL; FILE *input; void *data; -@@ -2143,6 +2305,14 @@ main (int argc, char **argv) +@@ -2437,6 +2599,14 @@ main (int argc, char **argv) keysize_string = *argv; argc--; argv++; } @@ -1067,17 +1070,16 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c else if (!strcmp (*argv, "--signature")) { argc--; argv++; -@@ -2463,23 +2633,49 @@ main (int argc, char **argv) +@@ -2792,23 +2962,49 @@ main (int argc, char **argv) } else if (!strcmp (mode_string, "dsa-pqg-gen")) { - int keysize; + int keysize, qsize; - - keysize = keysize_string? atoi (keysize_string) : 0; - if (keysize < 1024 || keysize > 3072) - die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -- run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); ++ ++ keysize = keysize_string? atoi (keysize_string) : 0; ++ if (keysize < 1024 || keysize > 3072) ++ die ("invalid keysize specified; needs to be 1024 .. 3072\n"); + qsize = qsize_string? atoi (qsize_string) : 0; + if (qsize < 160 || qsize > 256) + die ("invalid qsize specified; needs to be 160 .. 256\n"); @@ -1086,10 +1088,11 @@ diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c + else if (!strcmp (mode_string, "dsa-g-gen")) + { + int keysize, qsize; -+ -+ keysize = keysize_string? atoi (keysize_string) : 0; -+ if (keysize < 1024 || keysize > 3072) -+ die ("invalid keysize specified; needs to be 1024 .. 3072\n"); + + keysize = keysize_string? atoi (keysize_string) : 0; + if (keysize < 1024 || keysize > 3072) + die ("invalid keysize specified; needs to be 1024 .. 3072\n"); +- run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); + qsize = qsize_string? atoi (qsize_string) : 0; + if (qsize < 160 || qsize > 256) + die ("invalid qsize specified; needs to be 160 .. 256\n"); diff --git a/libgcrypt-1.6.1-fips-cfgrandom.patch b/libgcrypt-1.6.1-fips-cfgrandom.patch index e96c0ae..2c38987 100644 --- a/libgcrypt-1.6.1-fips-cfgrandom.patch +++ b/libgcrypt-1.6.1-fips-cfgrandom.patch @@ -1,55 +1,8 @@ -Index: libgcrypt-1.6.1/random/random-fips.c +Index: libgcrypt-1.7.2/random/rndlinux.c =================================================================== ---- libgcrypt-1.6.1.orig/random/random-fips.c -+++ libgcrypt-1.6.1/random/random-fips.c -@@ -27,10 +27,10 @@ - There are 3 random context which map to the different levels of - random quality: - -- Generator Seed and Key Kernel entropy (init/reseed) -- ------------------------------------------------------------ -- GCRY_VERY_STRONG_RANDOM /dev/random 256/128 bits -- GCRY_STRONG_RANDOM /dev/random 256/128 bits -+ Generator Seed and Key Kernel entropy (init/reseed) -+ --------------------------------------------------------------------------------------- -+ GCRY_VERY_STRONG_RANDOM /etc/gcrypt/rngseed+/dev/urandom 256/128 bits -+ GCRY_STRONG_RANDOM /etc/gcrypt/rngseed+/dev/urandom 256/128 bits - gcry_create_nonce GCRY_STRONG_RANDOM n/a - - All random generators return their data in 128 bit blocks. If the -@@ -40,8 +40,10 @@ - (SEED_TTL) output blocks; the re-seeding is disabled in test mode. - - The GCRY_VERY_STRONG_RANDOM and GCRY_STRONG_RANDOM generators are -- keyed and seeded from the /dev/random device. Thus these -- generators may block until the kernel has collected enough entropy. -+ keyed and seeded with data that is loaded from the /etc/gcrypt/rngseed -+ if the device or symlink to device exists xored with the data -+ from the /dev/urandom device. This allows the system administrator -+ to always seed the RNGs from /dev/random if it is required. - - The gcry_create_nonce generator is keyed and seeded from the - GCRY_STRONG_RANDOM generator. It may also block if the -@@ -560,9 +562,13 @@ get_entropy (size_t nbytes) - entropy_collect_buffer_len = 0; - - #if USE_RNDLINUX -+ _gcry_rndlinux_gather_random (entropy_collect_cb, 0, -+ X931_AES_KEYLEN, -+ -1); -+ entropy_collect_buffer_len = 0; - rc = _gcry_rndlinux_gather_random (entropy_collect_cb, 0, - X931_AES_KEYLEN, -- GCRY_VERY_STRONG_RANDOM); -+ GCRY_STRONG_RANDOM); - #elif USE_RNDW32 - do - { -Index: libgcrypt-1.6.1/random/rndlinux.c -=================================================================== ---- libgcrypt-1.6.1.orig/random/rndlinux.c -+++ libgcrypt-1.6.1/random/rndlinux.c -@@ -36,7 +36,9 @@ +--- libgcrypt-1.7.2.orig/random/rndlinux.c ++++ libgcrypt-1.7.2/random/rndlinux.c +@@ -40,7 +40,9 @@ #include "g10lib.h" #include "rand-internal.h" @@ -60,7 +13,7 @@ Index: libgcrypt-1.6.1/random/rndlinux.c static int -@@ -59,7 +61,7 @@ set_cloexec_flag (int fd) +@@ -63,7 +65,7 @@ set_cloexec_flag (int fd) * a fatal error but retries until it is able to reopen the device. */ static int @@ -69,7 +22,7 @@ Index: libgcrypt-1.6.1/random/rndlinux.c { int fd; -@@ -67,6 +69,8 @@ open_device (const char *name, int retry +@@ -71,6 +73,8 @@ open_device (const char *name, int retry _gcry_random_progress ("open_dev_random", 'X', 1, 0); again: fd = open (name, O_RDONLY); @@ -78,7 +31,7 @@ Index: libgcrypt-1.6.1/random/rndlinux.c if (fd == -1 && retry) { struct timeval tv; -@@ -111,6 +115,7 @@ _gcry_rndlinux_gather_random (void (*add +@@ -115,6 +119,7 @@ _gcry_rndlinux_gather_random (void (*add { static int fd_urandom = -1; static int fd_random = -1; @@ -86,7 +39,7 @@ Index: libgcrypt-1.6.1/random/rndlinux.c static unsigned char ever_opened; int fd; int n; -@@ -134,6 +139,11 @@ _gcry_rndlinux_gather_random (void (*add +@@ -138,6 +143,11 @@ _gcry_rndlinux_gather_random (void (*add close (fd_urandom); fd_urandom = -1; } @@ -98,7 +51,7 @@ Index: libgcrypt-1.6.1/random/rndlinux.c return 0; } -@@ -153,20 +163,30 @@ _gcry_rndlinux_gather_random (void (*add +@@ -165,20 +175,30 @@ _gcry_rndlinux_gather_random (void (*add that we always require the device to be existent but want a more graceful behaviour if the rarely needed close operation has been used and the device needs to be re-opened later. */ diff --git a/libgcrypt-1.6.3-aliasing.patch b/libgcrypt-1.6.3-aliasing.patch index a7aaed7..e3ab245 100644 --- a/libgcrypt-1.6.3-aliasing.patch +++ b/libgcrypt-1.6.3-aliasing.patch @@ -1,7 +1,8 @@ -diff -up libgcrypt-1.6.3/cipher/bufhelp.h.aliasing libgcrypt-1.6.3/cipher/bufhelp.h ---- libgcrypt-1.6.3/cipher/bufhelp.h.aliasing 2015-02-27 10:54:03.000000000 +0100 -+++ libgcrypt-1.6.3/cipher/bufhelp.h 2015-03-13 15:03:43.301749751 +0100 -@@ -80,7 +80,7 @@ do_bytes: +Index: libgcrypt-1.7.2/cipher/bufhelp.h +=================================================================== +--- libgcrypt-1.7.2.orig/cipher/bufhelp.h ++++ libgcrypt-1.7.2/cipher/bufhelp.h +@@ -91,7 +91,7 @@ do_bytes: for (; len; len--) *dst++ = *src++; #endif /*__GNUC__ >= 4 && (__x86_64__ || __i386__)*/ @@ -10,7 +11,7 @@ diff -up libgcrypt-1.6.3/cipher/bufhelp.h.aliasing libgcrypt-1.6.3/cipher/bufhel /* Optimized function for buffer xoring */ -@@ -117,7 +117,7 @@ do_bytes: +@@ -128,7 +128,7 @@ do_bytes: /* Handle tail. */ for (; len; len--) *dst++ = *src1++ ^ *src2++; @@ -18,8 +19,8 @@ diff -up libgcrypt-1.6.3/cipher/bufhelp.h.aliasing libgcrypt-1.6.3/cipher/bufhel +} __attribute__ ((optimize("no-strict-aliasing"))) - /* Optimized function for buffer xoring with two destination buffers. Used -@@ -155,7 +155,7 @@ do_bytes: + /* Optimized function for in-place buffer xoring. */ +@@ -200,7 +200,7 @@ do_bytes: /* Handle tail. */ for (; len; len--) *dst1++ = (*dst2++ ^= *src++); @@ -28,7 +29,7 @@ diff -up libgcrypt-1.6.3/cipher/bufhelp.h.aliasing libgcrypt-1.6.3/cipher/bufhel /* Optimized function for combined buffer xoring and copying. Used by mainly -@@ -208,7 +208,7 @@ do_bytes: +@@ -253,7 +253,7 @@ do_bytes: *dst_xor++ = *srcdst_cpy ^ *src_xor++; *srcdst_cpy++ = temp; } @@ -37,7 +38,7 @@ diff -up libgcrypt-1.6.3/cipher/bufhelp.h.aliasing libgcrypt-1.6.3/cipher/bufhel /* Optimized function for combined buffer xoring and copying. Used by mainly -@@ -234,7 +234,7 @@ buf_eq_const(const void *_a, const void +@@ -279,7 +279,7 @@ buf_eq_const(const void *_a, const void diff -= !!(a[i] - b[i]); return !diff; @@ -46,7 +47,7 @@ diff -up libgcrypt-1.6.3/cipher/bufhelp.h.aliasing libgcrypt-1.6.3/cipher/bufhel #ifndef BUFHELP_FAST_UNALIGNED_ACCESS -@@ -246,14 +246,14 @@ static inline u32 buf_get_be32(const voi +@@ -291,14 +291,14 @@ static inline u32 buf_get_be32(const voi const byte *in = _buf; return ((u32)in[0] << 24) | ((u32)in[1] << 16) | \ ((u32)in[2] << 8) | (u32)in[3]; @@ -63,7 +64,7 @@ diff -up libgcrypt-1.6.3/cipher/bufhelp.h.aliasing libgcrypt-1.6.3/cipher/bufhel static inline void buf_put_be32(void *_buf, u32 val) { -@@ -262,7 +262,7 @@ static inline void buf_put_be32(void *_b +@@ -307,7 +307,7 @@ static inline void buf_put_be32(void *_b out[1] = val >> 16; out[2] = val >> 8; out[3] = val; @@ -72,16 +73,16 @@ diff -up libgcrypt-1.6.3/cipher/bufhelp.h.aliasing libgcrypt-1.6.3/cipher/bufhel static inline void buf_put_le32(void *_buf, u32 val) { -@@ -271,7 +271,7 @@ static inline void buf_put_le32(void *_b +@@ -316,7 +316,7 @@ static inline void buf_put_le32(void *_b out[2] = val >> 16; out[1] = val >> 8; out[0] = val; -} +} __attribute__ ((optimize("no-strict-aliasing"))) - #ifdef HAVE_U64_TYPEDEF + /* Functions for loading and storing unaligned u64 values of different -@@ -283,7 +283,7 @@ static inline u64 buf_get_be64(const voi +@@ -328,7 +328,7 @@ static inline u64 buf_get_be64(const voi ((u64)in[2] << 40) | ((u64)in[3] << 32) | \ ((u64)in[4] << 24) | ((u64)in[5] << 16) | \ ((u64)in[6] << 8) | (u64)in[7]; @@ -90,7 +91,7 @@ diff -up libgcrypt-1.6.3/cipher/bufhelp.h.aliasing libgcrypt-1.6.3/cipher/bufhel static inline u64 buf_get_le64(const void *_buf) { -@@ -292,7 +292,7 @@ static inline u64 buf_get_le64(const voi +@@ -337,7 +337,7 @@ static inline u64 buf_get_le64(const voi ((u64)in[5] << 40) | ((u64)in[4] << 32) | \ ((u64)in[3] << 24) | ((u64)in[2] << 16) | \ ((u64)in[1] << 8) | (u64)in[0]; @@ -99,7 +100,7 @@ diff -up libgcrypt-1.6.3/cipher/bufhelp.h.aliasing libgcrypt-1.6.3/cipher/bufhel static inline void buf_put_be64(void *_buf, u64 val) { -@@ -305,7 +305,7 @@ static inline void buf_put_be64(void *_b +@@ -350,7 +350,7 @@ static inline void buf_put_be64(void *_b out[5] = val >> 16; out[6] = val >> 8; out[7] = val; @@ -108,70 +109,70 @@ diff -up libgcrypt-1.6.3/cipher/bufhelp.h.aliasing libgcrypt-1.6.3/cipher/bufhel static inline void buf_put_le64(void *_buf, u64 val) { -@@ -318,7 +318,7 @@ static inline void buf_put_le64(void *_b +@@ -363,7 +363,7 @@ static inline void buf_put_le64(void *_b out[2] = val >> 16; out[1] = val >> 8; out[0] = val; -} +} __attribute__ ((optimize("no-strict-aliasing"))) - #endif /*HAVE_U64_TYPEDEF*/ #else /*BUFHELP_FAST_UNALIGNED_ACCESS*/ -@@ -328,24 +328,24 @@ static inline void buf_put_le64(void *_b + +@@ -377,24 +377,24 @@ typedef struct bufhelp_u32_s static inline u32 buf_get_be32(const void *_buf) { - return be_bswap32(*(const u32 *)_buf); + return be_bswap32(((const bufhelp_u32_t *)_buf)->a); -} +} __attribute__ ((optimize("no-strict-aliasing"))) static inline u32 buf_get_le32(const void *_buf) { - return le_bswap32(*(const u32 *)_buf); + return le_bswap32(((const bufhelp_u32_t *)_buf)->a); -} +} __attribute__ ((optimize("no-strict-aliasing"))) static inline void buf_put_be32(void *_buf, u32 val) { - u32 *out = _buf; - *out = be_bswap32(val); + bufhelp_u32_t *out = _buf; + out->a = be_bswap32(val); -} +} __attribute__ ((optimize("no-strict-aliasing"))) static inline void buf_put_le32(void *_buf, u32 val) { - u32 *out = _buf; - *out = le_bswap32(val); + bufhelp_u32_t *out = _buf; + out->a = le_bswap32(val); -} +} __attribute__ ((optimize("no-strict-aliasing"))) - #ifdef HAVE_U64_TYPEDEF - /* Functions for loading and storing unaligned u64 values of different -@@ -353,24 +353,24 @@ static inline void buf_put_le32(void *_b + + typedef struct bufhelp_u64_s +@@ -407,24 +407,24 @@ typedef struct bufhelp_u64_s static inline u64 buf_get_be64(const void *_buf) { - return be_bswap64(*(const u64 *)_buf); + return be_bswap64(((const bufhelp_u64_t *)_buf)->a); -} +} __attribute__ ((optimize("no-strict-aliasing"))) static inline u64 buf_get_le64(const void *_buf) { - return le_bswap64(*(const u64 *)_buf); + return le_bswap64(((const bufhelp_u64_t *)_buf)->a); -} +} __attribute__ ((optimize("no-strict-aliasing"))) static inline void buf_put_be64(void *_buf, u64 val) { - u64 *out = _buf; - *out = be_bswap64(val); + bufhelp_u64_t *out = _buf; + out->a = be_bswap64(val); -} +} __attribute__ ((optimize("no-strict-aliasing"))) static inline void buf_put_le64(void *_buf, u64 val) { - u64 *out = _buf; - *out = le_bswap64(val); + bufhelp_u64_t *out = _buf; + out->a = le_bswap64(val); -} +} __attribute__ ((optimize("no-strict-aliasing"))) - #endif /*HAVE_U64_TYPEDEF*/ + #endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/ diff --git a/libgcrypt-1.6.6.tar.bz2 b/libgcrypt-1.6.6.tar.bz2 deleted file mode 100644 index 0dc9be2..0000000 --- a/libgcrypt-1.6.6.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f9461b4619bb78b273a88d468915750d418e89a3ea3b641bab0563a9af4b04d0 -size 2480467 diff --git a/libgcrypt-1.6.6.tar.bz2.sig b/libgcrypt-1.6.6.tar.bz2.sig deleted file mode 100644 index 1831a22bab4891c67f0c6015d349c138948cec8042c005aa71daece41c085013..0000000000000000000000000000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 287 zcmV+)0pR|L0UQJX0SEvF1p-&JP)Ps^2@oWkInqxh3PCb?>G0IvFTeh5^X zKZ7ABqbT7#c?4Fv=_l*g zxLE1BkwOuX)?bFAw3F&Blh# l&HQ&!dPBek4V^Bc{$I~`T467ppgeaIWr_#3g3Og+D@B7%iyHs{ diff --git a/libgcrypt-1.7.3.tar.bz2 b/libgcrypt-1.7.3.tar.bz2 new file mode 100644 index 0000000..6243bb6 --- /dev/null +++ b/libgcrypt-1.7.3.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ddac6111077d0a1612247587be238c5294dd0ee4d76dc7ba783cc55fb0337071 +size 2861294 diff --git a/libgcrypt-1.7.3.tar.bz2.sig b/libgcrypt-1.7.3.tar.bz2.sig new file mode 100644 index 0000000000000000000000000000000000000000000000000000000000000000..3c5d869b68ac95e8633dace0dd7937b496e46f627301fd37d1ff7d1cdfc2123c GIT binary patch literal 287 zcmV+)0pR|L0UQJX0SEvF1p-&JP@Mn@2@oWkInqxhy*2mfQFdC#ig$`}6Lf*YBn z&CB0eVu5{~;|s(^vRdl$YN(8OSy`#5-SK;yyDp2a#*<(ov=GsPd~Hy+*mwwJpqwPx znr(uUzuTi6bsPp6%3AZV6J6~fc{*Keu!1srI6 zzI>URv$#!7_>){wNXG+WbQ)i;C9nfXz+lTc1Y057)49Z@-zK~alV3;U@6L3kq~1cZ l2 0 && mpi_cmp (value_x, prime_q) < 0)); -+ while (mpi_cmp (value_c, value_qm2) > 0); -+ -+ /* x = c + 1 */ -+ mpi_add_ui(value_x, value_c, 1); - - /* y = g^x mod p */ - value_y = mpi_alloc_like (prime_p); -@@ -502,6 +524,8 @@ generate_fips186 (DSA_secret_key *sk, un - _gcry_mpi_release (value_x); - _gcry_mpi_release (value_h); - _gcry_mpi_release (value_e); -+ _gcry_mpi_release (value_c); -+ _gcry_mpi_release (value_qm2); - - /* As a last step test this keys (this should never fail of course). */ - if (!ec && test_keys (sk, qbits) ) -@@ -1218,10 +1242,10 @@ selftests_dsa (selftest_report_func_t re - - /* Convert the S-expressions into the internal representation. */ - what = "convert"; -- err = sexp_sscan (&skey, NULL, sample_secret_key, strlen (sample_secret_key)); -+ err = sexp_sscan (&skey, NULL, sample_secret_key_2048, strlen (sample_secret_key_2048)); - if (!err) - err = sexp_sscan (&pkey, NULL, -- sample_public_key, strlen (sample_public_key)); -+ sample_public_key_2048, strlen (sample_public_key_2048)); - if (err) - { - errtxt = _gcry_strerror (err); -Index: libgcrypt-1.6.1/cipher/primegen.c -=================================================================== ---- libgcrypt-1.6.1.orig/cipher/primegen.c 2014-01-29 10:48:38.000000000 +0100 -+++ libgcrypt-1.6.1/cipher/primegen.c 2014-09-16 16:42:53.713019269 +0200 -@@ -1668,9 +1668,7 @@ _gcry_generate_fips186_3_prime (unsigned - - /* Step 1: Check the requested prime lengths. */ - /* Note that due to the size of our buffers QBITS is limited to 256. */ -- if (pbits == 1024 && qbits == 160) -- hashalgo = GCRY_MD_SHA1; -- else if (pbits == 2048 && qbits == 224) -+ if (pbits == 2048 && qbits == 224) - hashalgo = GCRY_MD_SHA224; - else if (pbits == 2048 && qbits == 256) - hashalgo = GCRY_MD_SHA256; -Index: libgcrypt-1.6.1/Makefile.am -=================================================================== ---- libgcrypt-1.6.1.orig/Makefile.am 2014-09-16 16:42:53.707019195 +0200 -+++ libgcrypt-1.6.1/Makefile.am 2014-09-16 16:42:53.713019269 +0200 -@@ -36,7 +36,7 @@ EXTRA_DIST = autogen.sh autogen.rc READM - - DISTCLEANFILES = - --bin_PROGRAMS = fipsdrv drbg_test -+bin_PROGRAMS = fipsdrv fips186_dsa drbg_test - - fipsdrv_SOURCES = tests/fipsdrv.c - fipsdrv_LDADD = src/libgcrypt.la $(DL_LIBS) $(GPG_ERROR_LIBS) -@@ -45,6 +45,9 @@ drbg_test_CPPFLAGS = -I../src -I$(top_sr - drbg_test_SOURCES = src/gcrypt.h tests/drbg_test.c - drbg_test_LDADD = src/libgcrypt.la $(DL_LIBS) $(GPG_ERROR_LIBS) - -+fips186_dsa_SOURCES = tests/fips186-dsa.c -+fips186_dsa_LDADD = src/libgcrypt.la $(DL_LIBS) $(GPG_ERROR_LIBS) -+ - # Add all the files listed in "distfiles" files to the distribution, - # apply version number s to some files and create a VERSION file which - # we need for the Prereq: patch file trick. diff --git a/libgcrypt-fips_ecdsa.patch b/libgcrypt-fips_ecdsa.patch deleted file mode 100644 index 71d105c..0000000 --- a/libgcrypt-fips_ecdsa.patch +++ /dev/null @@ -1,30 +0,0 @@ -Index: libgcrypt-1.6.1/cipher/ecc-curves.c -=================================================================== ---- libgcrypt-1.6.1.orig/cipher/ecc-curves.c 2014-01-29 10:48:38.000000000 +0100 -+++ libgcrypt-1.6.1/cipher/ecc-curves.c 2014-09-18 17:48:15.645814378 +0200 -@@ -114,7 +114,7 @@ static const ecc_domain_parms_t domain_p - "0x6666666666666666666666666666666666666666666666666666666666666658" - }, - { -- "NIST P-192", 192, 1, -+ "NIST P-192", 192, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xfffffffffffffffffffffffffffffffeffffffffffffffff", - "0xfffffffffffffffffffffffffffffffefffffffffffffffc", -Index: libgcrypt-1.6.1/cipher/pubkey-util.c -=================================================================== ---- libgcrypt-1.6.1.orig/cipher/pubkey-util.c 2013-12-16 18:44:32.000000000 +0100 -+++ libgcrypt-1.6.1/cipher/pubkey-util.c 2014-09-18 18:27:24.928658758 +0200 -@@ -593,7 +593,11 @@ _gcry_pk_util_init_encoding_ctx (struct - ctx->nbits = nbits; - ctx->encoding = PUBKEY_ENC_UNKNOWN; - ctx->flags = 0; -- ctx->hash_algo = GCRY_MD_SHA1; -+ if (fips_mode()) { -+ ctx->hash_algo = GCRY_MD_SHA256; -+ } else { -+ ctx->hash_algo = GCRY_MD_SHA1; -+ } - ctx->label = NULL; - ctx->labellen = 0; - ctx->saltlen = 20; diff --git a/libgcrypt-fix-rng.patch b/libgcrypt-fix-rng.patch index 0d7d3a6..851b208 100644 --- a/libgcrypt-fix-rng.patch +++ b/libgcrypt-fix-rng.patch @@ -1,8 +1,8 @@ -Index: libgcrypt-1.6.1/random/random.c +Index: libgcrypt-1.7.2/random/random.c =================================================================== ---- libgcrypt-1.6.1.orig/random/random.c -+++ libgcrypt-1.6.1/random/random.c -@@ -440,6 +440,9 @@ _gcry_create_nonce (void *buffer, size_t +--- libgcrypt-1.7.2.orig/random/random.c ++++ libgcrypt-1.7.2/random/random.c +@@ -419,6 +419,9 @@ _gcry_create_nonce (void *buffer, size_t size_t n; int err; @@ -12,7 +12,7 @@ Index: libgcrypt-1.6.1/random/random.c /* First check whether we shall use the FIPS nonce generator. This is only done in FIPS mode, in all other modes, we use our own nonce generator which is seeded by the RNG actual in use. */ -@@ -455,9 +458,6 @@ _gcry_create_nonce (void *buffer, size_t +@@ -433,9 +436,6 @@ _gcry_create_nonce (void *buffer, size_t FIPS mode (not that this means it is also used if the FIPS RNG has been selected but we are not in fips mode). */ @@ -20,5 +20,5 @@ Index: libgcrypt-1.6.1/random/random.c - _gcry_random_initialize (1); - /* Acquire the nonce buffer lock. */ - err = ath_mutex_lock (&nonce_buffer_lock); + err = gpgrt_lock_lock (&nonce_buffer_lock); if (err) diff --git a/libgcrypt-sparcv9.diff b/libgcrypt-sparcv9.diff index 8c17717..57771d6 100644 --- a/libgcrypt-sparcv9.diff +++ b/libgcrypt-sparcv9.diff @@ -8,16 +8,16 @@ by choosing v8-like insns for 32-bit v9 mode too. mpi/longlong.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -Index: libgcrypt-1.6.4/mpi/longlong.h +Index: libgcrypt-1.7.2/mpi/longlong.h =================================================================== ---- libgcrypt-1.6.4.orig/mpi/longlong.h 2015-09-07 15:33:48.000000000 +0200 -+++ libgcrypt-1.6.4/mpi/longlong.h 2015-09-08 10:36:28.124169828 +0200 -@@ -1287,7 +1287,7 @@ typedef unsigned int UTItype __attribute +--- libgcrypt-1.7.2.orig/mpi/longlong.h ++++ libgcrypt-1.7.2/mpi/longlong.h +@@ -1293,7 +1293,7 @@ typedef unsigned int UTItype __attribute "rJ" ((USItype)(al)), \ "rI" ((USItype)(bl)) \ __CLOBBER_CC) --#if defined (__sparc_v8__) || defined(__sparcv8) -+#if defined (__sparc_v8__) || defined(__sparcv8) || defined(__sparc_v9__) +-# if defined (__sparc_v8__) || defined(__sparcv8) ++# if defined (__sparc_v8__) || defined(__sparcv8) || defined(__space_v9__) /* Don't match immediate range because, 1) it is not often useful, 2) the 'I' flag thinks of the range as a 13 bit signed interval, while we want to match a 13 bit interval, sign extended to 32 bits, diff --git a/libgcrypt.changes b/libgcrypt.changes index 1b577b3..fbf3ec1 100644 --- a/libgcrypt.changes +++ b/libgcrypt.changes @@ -1,3 +1,147 @@ +------------------------------------------------------------------- +Sat Aug 20 10:38:15 UTC 2016 - mpluskal,vcizek,astieger}@suse.com + +- libgcrypt 1.7.3: + * security issue already fixes with 1.6.6 + * Fix building of some asm modules with older compilers and CPUs. + * ARMv8/AArch32 improvements for AES, GCM, SHA-256, and SHA-1. +- includes changes from libgcrypt 1.7.2: + * Bug fixes: + - Fix setting of the ECC cofactor if parameters are specified. + - Fix memory leak in the ECC code. + - Remove debug message about unsupported getrandom syscall. + - Fix build problems related to AVX use. + - Fix bus errors on ARM for Poly1305, ChaCha20, AES, and SHA-512. + * Internal changes: + - Improved fatal error message for wrong use of gcry_md_read. + - Disallow symmetric encryption/decryption if key is not set. +- includes changes from 1.7.1: + * Bug fixes: + - Fix ecc_verify for cofactor support. + - Fix portability bug when using gcc with Solaris 9 SPARC. + - Build fix for OpenBSD/amd64 + - Add OIDs to the Serpent ciphers. + * Internal changes: + - Use getrandom system call on Linux if available. + - Blinding is now also used for RSA signature creation. + - Changed names of debug envvars +- includes changes from 1.7.0: + * New algorithms and modes: + - SHA3-224, SHA3-256, SHA3-384, SHA3-512, and MD2 hash algorithms. + - SHAKE128 and SHAKE256 extendable-output hash algorithms. + - ChaCha20 stream cipher. + - Poly1305 message authentication algorithm + - ChaCha20-Poly1305 Authenticated Encryption with Associated Data + mode. + - OCB mode. + - HMAC-MD2 for use by legacy applications. + * New curves for ECC: + - Curve25519. + - sec256k1. + - GOST R 34.10-2001 and GOST R 34.10-2012. + * Performance: + - Improved performance of KDF functions. + - Assembler optimized implementations of Blowfish and Serpent on + ARM. + - Assembler optimized implementation of 3DES on x86. + - Improved AES using the SSSE3 based vector permutation method by + Mike Hamburg. + - AVX/BMI is used for SHA-1 and SHA-256 on x86. This is for SHA-1 + about 20% faster than SSSE3 and more than 100% faster than the + generic C implementation. + - 40% speedup for SHA-512 and 72% for SHA-1 on ARM Cortex-A8. + - 60-90% speedup for Whirlpool on x86. + - 300% speedup for RIPE MD-160. + - Up to 11 times speedup for CRC functions on x86. + * Other features: + - Improved ECDSA and FIPS 186-4 compliance. + - Support for Montgomery curves. + - gcry_cipher_set_sbox to tweak S-boxes of the gost28147 cipher + algorithm. + - gcry_mpi_ec_sub to subtract two points on a curve. + - gcry_mpi_ec_decode_point to decode an MPI into a point object. + - Emulation for broken Whirlpool code prior to 1.6.0. [from 1.6.1] + - Flag "pkcs1-raw" to enable PCKS#1 padding with a user supplied + hash part. + - Parameter "saltlen" to set a non-default salt length for RSA PSS. + - A SP800-90A conforming DRNG replaces the former X9.31 alternative + random number generator. + - Map deprecated RSA algo number to the RSA algo number for better + backward compatibility. [from 1.6.2] + - Use ciphertext blinding for Elgamal decryption [CVE-2014-3591]. + See http://www.cs.tau.ac.il/~tromer/radioexp/ for details. + [from 1.6.3] + - Fixed data-dependent timing variations in modular exponentiation + [related to CVE-2015-0837, Last-Level Cache Side-Channel Attacks + are Practical]. [from 1.6.3] + - Flag "no-keytest" for ECC key generation. Due to a bug in + the parser that flag will also be accepted but ignored by older + version of Libgcrypt. [from 1.6.4] + - Speed up the random number generator by requiring less extra + seeding. [from 1.6.4] + - Always verify a created RSA signature to avoid private key leaks + due to hardware failures. [from 1.6.4] + - Mitigate side-channel attack on ECDH with Weierstrass curves + [CVE-2015-7511]. See http://www.cs.tau.ac.IL/~tromer/ecdh/ for + details. [from 1.6.5] + * Internal changes: + - Moved locking out to libgpg-error. + - Support of the SYSROOT envvar in the build system. + - Refactor some code. + - The availability of a 64 bit integer type is now mandatory. + * Bug fixes: + - Fixed message digest lookup by OID (regression in 1.6.0). + - Fixed a build problem on NetBSD + - Fixed some asm build problems and feature detection bugs. + * Interface changes relative to the 1.6.0 release: + gcry_cipher_final NEW macro. + GCRY_CIPHER_MODE_CFB8 NEW constant. + GCRY_CIPHER_MODE_OCB NEW. + GCRY_CIPHER_MODE_POLY1305 NEW. + gcry_cipher_set_sbox NEW macro. + gcry_mac_get_algo NEW. + GCRY_MAC_HMAC_MD2 NEW. + GCRY_MAC_HMAC_SHA3_224 NEW. + GCRY_MAC_HMAC_SHA3_256 NEW. + GCRY_MAC_HMAC_SHA3_384 NEW. + GCRY_MAC_HMAC_SHA3_512 NEW. + GCRY_MAC_POLY1305 NEW. + GCRY_MAC_POLY1305_AES NEW. + GCRY_MAC_POLY1305_CAMELLIA NEW. + GCRY_MAC_POLY1305_SEED NEW. + GCRY_MAC_POLY1305_SERPENT NEW. + GCRY_MAC_POLY1305_TWOFISH NEW. + gcry_md_extract NEW. + GCRY_MD_FLAG_BUGEMU1 NEW [from 1.6.1]. + GCRY_MD_GOSTR3411_CP NEW. + GCRY_MD_SHA3_224 NEW. + GCRY_MD_SHA3_256 NEW. + GCRY_MD_SHA3_384 NEW. + GCRY_MD_SHA3_512 NEW. + GCRY_MD_SHAKE128 NEW. + GCRY_MD_SHAKE256 NEW. + gcry_mpi_ec_decode_point NEW. + gcry_mpi_ec_sub NEW. + GCRY_PK_EDDSA NEW constant. + GCRYCTL_GET_TAGLEN NEW. + GCRYCTL_SET_SBOX NEW. + GCRYCTL_SET_TAGLEN NEW. +- Apply libgcrypt-1.6.3-aliasing.patch only on big-endian + architectures +- update drbg_test.patch and install cavs testing directory again +- As DRBG is upstream, drop pateches: + v9-0001-SP800-90A-Deterministic-Random-Bit-Generator.patch + 0002-Compile-DRBG.patch + 0003-Function-definitions-of-interfaces-for-random.c.patch + 0004-Invoke-DRBG-from-common-libgcrypt-RNG-code.patch + 0005-Function-definitions-for-gcry_control-callbacks.patch + 0006-DRBG-specific-gcry_control-requests.patch + v9-0007-User-interface-to-DRBG.patch + libgcrypt-fix-rng.patch +- drop obsolete: + libgcrypt-fips-dsa.patch + libgcrypt-fips_ecdsa.patch + ------------------------------------------------------------------- Wed Aug 17 18:21:44 UTC 2016 - astieger@suse.com diff --git a/libgcrypt.spec b/libgcrypt.spec index 643bc71..3460c38 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -19,10 +19,10 @@ %define build_hmac256 1 %define separate_hmac256_binary 0 %define libsoname %{name}20 -%define sosuffix 20.0.6 +%define sosuffix 20.1.3 %define cavs_dir %{_libexecdir}/%{name}/cavs Name: libgcrypt -Version: 1.6.6 +Version: 1.7.3 Release: 0 Summary: The GNU Crypto Library License: GPL-2.0+ and LGPL-2.1+ and GPL-3.0+ @@ -50,28 +50,16 @@ Patch12: libgcrypt-1.6.1-use-fipscheck.patch Patch13: libgcrypt-1.6.1-fips-cavs.patch #PATCH-FIX-SUSE: bnc#724841, fix a random device opening routine Patch14: libgcrypt-1.6.1-fips-cfgrandom.patch -# add support for SP800-90A DRBG (fate#316929, bnc#856312) -Patch21: v9-0001-SP800-90A-Deterministic-Random-Bit-Generator.patch -Patch22: 0002-Compile-DRBG.patch -Patch23: 0003-Function-definitions-of-interfaces-for-random.c.patch -Patch24: 0004-Invoke-DRBG-from-common-libgcrypt-RNG-code.patch -Patch25: 0005-Function-definitions-for-gcry_control-callbacks.patch -Patch26: 0006-DRBG-specific-gcry_control-requests.patch -Patch27: v9-0007-User-interface-to-DRBG.patch Patch28: libgcrypt-fix-rng.patch Patch29: libgcrypt-init-at-elf-load-fips.patch #PATCH-FIX-SUSE add FIPS CAVS test app for DRBG Patch30: drbg_test.patch -#PATCH-FIX-SUSE bnc#894216 make DSA compliant with FIPS 186-4 -Patch31: libgcrypt-fips-dsa.patch #PATCH-FIX-SUSE run FIPS self-test from constructor Patch32: libgcrypt-fips_run_selftest_at_constructor.patch -#PATCH-FIX-SUSE bnc#896202 make ECDSA compliant with FIPS 186-4 -Patch33: libgcrypt-fips_ecdsa.patch Patch34: libgcrypt-1.6.3-aliasing.patch BuildRequires: automake >= 1.14 BuildRequires: fipscheck -BuildRequires: libgpg-error-devel >= 1.11 +BuildRequires: libgpg-error-devel >= 1.13 BuildRequires: libtool BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -107,7 +95,7 @@ License: GFDL-1.1 and GPL-2.0+ and LGPL-2.1+ and MIT Group: Development/Libraries/C and C++ Requires: %{libsoname} = %{version} Requires: glibc-devel -Requires: libgpg-error-devel >= 1.8 +Requires: libgpg-error-devel >= 1.13 Requires(post): %{install_info_prereq} %description devel @@ -155,20 +143,15 @@ understanding of applied cryptography is required to use Libgcrypt. %patch5 -p1 %patch7 -p1 %patch12 -p1 -%patch21 -p1 -%patch22 -p1 -%patch23 -p1 -%patch24 -p1 -%patch25 -p1 -%patch26 -p1 -%patch27 -p1 %patch28 -p1 %patch29 -p1 %patch30 -p1 -%patch31 -p1 %patch32 -p1 -%patch33 -p1 +# This patch breaks x86_64 builds but is needed for big-endian +# architectures +%ifarch ppc ppc64 s390 s390x %patch34 -p1 +%endif %patch13 -p1 %patch14 -p1 @@ -176,7 +159,7 @@ understanding of applied cryptography is required to use Libgcrypt. echo building with build_hmac256 set to %{build_hmac256} %{?suse_update_config} autoreconf -fi -date=$(date -u +%Y-%m-%dT%H:%M+0000 -r %{SOURCE99}) +date=$(date -u +%{Y}-%{m}-%{dT}%{H}:%{M}+0000 -r %{SOURCE99}) sed -e "s,BUILD_TIMESTAMP=.*,BUILD_TIMESTAMP=$date," -i configure export CFLAGS="%{optflags} $(getconf LFS_CFLAGS)" %configure --with-pic \ @@ -212,7 +195,7 @@ fipshmac src/.libs/libgcrypt.so.?? # make check %install -make DESTDIR=%{buildroot} install %{?_smp_mflags} +make %{?_smp_mflags} DESTDIR=%{buildroot} install rm %{buildroot}%{_libdir}/%{name}.la # cavs @@ -220,14 +203,11 @@ install -m 0755 -d %{buildroot}%{cavs_dir} install -m 0755 %{SOURCE5} %{buildroot}%{cavs_dir} install -m 0755 %{SOURCE6} %{buildroot}%{cavs_dir} -mv %{buildroot}%{_bindir}/fips186_dsa %{buildroot}%{cavs_dir} mv %{buildroot}%{_bindir}/fipsdrv %{buildroot}%{cavs_dir} mv %{buildroot}%{_bindir}/drbg_test %{buildroot}%{cavs_dir} %post -n %{libsoname} -p /sbin/ldconfig - %postun -n %{libsoname} -p /sbin/ldconfig - %post devel %install_info --info-dir=%{_infodir} %{_infodir}/gcrypt.info.gz @@ -248,7 +228,7 @@ mv %{buildroot}%{_bindir}/drbg_test %{buildroot}%{cavs_dir} %files devel %defattr(-,root,root) %doc AUTHORS COPYING COPYING.LIB ChangeLog NEWS README THANKS TODO -%{_infodir}/gcrypt.info.gz +%{_infodir}/gcrypt.info%{ext_info} %{_bindir}/dumpsexp %{_bindir}/mpicalc %{_bindir}/%{name}-config diff --git a/v9-0001-SP800-90A-Deterministic-Random-Bit-Generator.patch b/v9-0001-SP800-90A-Deterministic-Random-Bit-Generator.patch deleted file mode 100644 index b9e54d8..0000000 --- a/v9-0001-SP800-90A-Deterministic-Random-Bit-Generator.patch +++ /dev/null @@ -1,2406 +0,0 @@ -From 6e04a47db68a0ae3947dbd5bfdb8c228ddb83c0e Mon Sep 17 00:00:00 2001 -From: Stephan Mueller -Date: Mon, 1 Sep 2014 17:53:33 +0200 -Subject: [PATCH v9 1/7] SP800-90A Deterministic Random Bit Generator - -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 ---- - random/drbg.c | 2364 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 2364 insertions(+) - create mode 100644 random/drbg.c - -diff --git a/random/drbg.c b/random/drbg.c -new file mode 100644 -index 0000000..8733f85 ---- /dev/null -+++ b/random/drbg.c -@@ -0,0 +1,2364 @@ -+/* -+ * DRBG: Deterministic Random Bits Generator -+ * Based on NIST Recommended DRBG from NIST SP800-90A with the following -+ * properties: -+ * * CTR DRBG with DF with AES-128, AES-192, AES-256 cores -+ * * Hash DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores -+ * * HMAC DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores -+ * * with and without prediction resistance -+ * -+ * Copyright Stephan Mueller , 2014 -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, and the entire permission notice in its entirety, -+ * including the disclaimer of warranties. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The name of the author may not be used to endorse or promote -+ * products derived from this software without specific prior -+ * written permission. -+ * -+ * ALTERNATIVELY, this product may be distributed under the terms of -+ * the GNU General Public License, in which case the provisions of the GPL are -+ * required INSTEAD OF the above restrictions. (This clause is -+ * necessary due to a potential bad interaction between the GPL and -+ * the restrictions contained in a BSD-style copyright.) -+ * -+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF -+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE -+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -+ * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * -+ * -+ * 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. -+ * -+ * 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; -+ * char personalization[11] = "some-string"; -+ * -+ * drbg_string_fill(&pers, personalization, strlen(personalization)); -+ * // 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; -+ * char addtl_string[11] = "some-string"; -+ * -+ * drbg_string_fill(&addtl, addtl_string, strlen(addtl_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); -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "g10lib.h" -+#include "random.h" -+#include "rand-internal.h" -+#include "../cipher/bithelp.h" -+ -+/****************************************************************** -+ * Common data structures -+ ******************************************************************/ -+ -+struct drbg_state; -+ -+struct drbg_core -+{ -+ u_int32_t flags; /* flags for the cipher */ -+ __u8 statelen; /* maximum state length */ -+ __u8 blocklen_bytes; /* block size of output in bytes */ -+ int backend_cipher; /* libgcrypt backend cipher */ -+}; -+ -+struct drbg_state_ops -+{ -+ gpg_err_code_t (*update) (struct drbg_state * drbg, -+ struct drbg_string * seed, int reseed); -+ gpg_err_code_t (*generate) (struct drbg_state * drbg, -+ unsigned char *buf, unsigned int buflen, -+ struct drbg_string * addtl); -+}; -+ -+struct drbg_state -+{ -+ unsigned char *V; /* internal state 10.1.1.1 1a) */ -+ unsigned char *C; /* hash: static value 10.1.1.1 1b) -+ * hmac / ctr: key */ -+ size_t reseed_ctr; /* Number of RNG requests since last reseed -- -+ * 10.1.1.1 1c) */ -+ unsigned char *scratchpad; /* some memory the DRBG can use for its -+ * operation -- allocated during init */ -+ int seeded:1; /* DRBG fully seeded? */ -+ int pr:1; /* Prediction resistance enabled? */ -+ int fips_primed:1; /* Continuous test primed? */ -+ unsigned char *prev; /* previous output value of drbg_blocklen for -+ * FIPS 140-2 continuous test */ -+ /* Taken from libgcrypt ANSI X9.31 DRNG: We need to keep track of the -+ * process which did the initialization so that we can detect a fork. -+ * The volatile modifier is required so that the compiler does not -+ * optimize it away in case the getpid function is badly attributed. */ -+ pid_t seed_init_pid; -+ const struct drbg_state_ops *d_ops; -+ const struct drbg_core *core; -+ struct drbg_test_data *test_data; -+}; -+ -+enum drbg_prefixes -+{ -+ DRBG_PREFIX0 = 0x00, -+ DRBG_PREFIX1, -+ DRBG_PREFIX2, -+ DRBG_PREFIX3 -+}; -+ -+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) -+ -+/*************************************************************** -+ * Backend cipher definitions available to DRBG -+ ***************************************************************/ -+ -+static const struct drbg_core drbg_cores[] = { -+ { -+ /* Hash DRBGs */ -+ .flags = DRBG_HASHSHA1, -+ .statelen = 55, /* 440 bits */ -+ .blocklen_bytes = 20, -+ .backend_cipher = GCRY_MD_SHA1, -+ }, -+ { -+ .flags = DRBG_HASHSHA256, -+ .statelen = 55, /* 440 bits */ -+ .blocklen_bytes = 32, -+ .backend_cipher = GCRY_MD_SHA256, -+ }, -+ { -+ .flags = DRBG_HASHSHA384, -+ .statelen = 111, /* 888 bits */ -+ .blocklen_bytes = 48, -+ .backend_cipher = GCRY_MD_SHA384, -+ }, -+ { -+ .flags = DRBG_HASHSHA512, -+ .statelen = 111, /* 888 bits */ -+ .blocklen_bytes = 64, -+ .backend_cipher = GCRY_MD_SHA512, -+ }, -+ { -+ /* HMAC DRBGs */ -+ .flags = DRBG_HASHSHA1 | DRBG_HMAC, -+ .statelen = 20, /* block length of cipher */ -+ .blocklen_bytes = 20, -+ .backend_cipher = GCRY_MD_SHA1, -+ }, -+ { -+ .flags = DRBG_HASHSHA256 | DRBG_HMAC, -+ .statelen = 32, /* block length of cipher */ -+ .blocklen_bytes = 32, -+ .backend_cipher = GCRY_MD_SHA256, -+ }, -+ { -+ .flags = DRBG_HASHSHA384 | DRBG_HMAC, -+ .statelen = 48, /* block length of cipher */ -+ .blocklen_bytes = 48, -+ .backend_cipher = GCRY_MD_SHA384, -+ }, -+ { -+ .flags = DRBG_HASHSHA512 | DRBG_HMAC, -+ .statelen = 64, /* block length of cipher */ -+ .blocklen_bytes = 64, -+ .backend_cipher = GCRY_MD_SHA512, -+ }, -+ { -+ /* block ciphers */ -+ .flags = DRBG_CTRAES | DRBG_SYM128, -+ .statelen = 32, /* 256 bits as defined in 10.2.1 */ -+ .blocklen_bytes = 16, -+ .backend_cipher = GCRY_CIPHER_AES128, -+ }, -+ { -+ /* block ciphers */ -+ .flags = DRBG_CTRAES | DRBG_SYM192, -+ .statelen = 40, /* 320 bits as defined in 10.2.1 */ -+ .blocklen_bytes = 16, -+ .backend_cipher = GCRY_CIPHER_AES192, -+ }, -+ { -+ /* block ciphers */ -+ .flags = DRBG_CTRAES | DRBG_SYM256, -+ .statelen = 48, /* 384 bits as defined in 10.2.1 */ -+ .blocklen_bytes = 16, -+ .backend_cipher = GCRY_CIPHER_AES256, -+ }, -+}; -+ -+/****************************************************************** -+ ****************************************************************** -+ ****************************************************************** -+ * Generic DRBG code -+ ****************************************************************** -+ ****************************************************************** -+ ******************************************************************/ -+ -+/****************************************************************** -+ * Generic helper functions -+ ******************************************************************/ -+ -+#if 0 -+#define dbg(x) do { log_debug x; } while(0) -+#else -+#define dbg(x) -+#endif -+ -+int drbg_healthcheck (void); -+ -+static inline void * -+drbg_malloc (size_t len) -+{ -+ void *buf; -+ buf = xmalloc_secure (len); -+ if (buf) -+ memset (buf, 0, len); -+ return buf; -+} -+ -+static inline __u8 -+drbg_statelen (struct drbg_state *drbg) -+{ -+ if (drbg && drbg->core) -+ return drbg->core->statelen; -+ return 0; -+} -+ -+static inline __u8 -+drbg_blocklen (struct drbg_state *drbg) -+{ -+ if (drbg && drbg->core) -+ return drbg->core->blocklen_bytes; -+ return 0; -+} -+ -+static inline __u8 -+drbg_keylen (struct drbg_state *drbg) -+{ -+ if (drbg && drbg->core) -+ return (drbg->core->statelen - drbg->core->blocklen_bytes); -+ return 0; -+} -+ -+static inline size_t -+drbg_max_request_bytes (void) -+{ -+ /* SP800-90A requires the limit 2**19 bits, but we return bytes */ -+ return (1 << 16); -+} -+ -+static inline size_t -+drbg_max_addtl (void) -+{ -+ /* SP800-90A requires 2**35 bytes additional info str / pers str */ -+#ifdef __LP64__ -+ return (1UL<<35); -+#else -+ /* -+ * SP800-90A allows smaller maximum numbers to be returned -- we -+ * return SIZE_MAX - 1 to allow the verification of the enforcement -+ * of this value in drbg_healthcheck_sanity. -+ */ -+ return (SIZE_MAX - 1); -+#endif -+} -+ -+static inline size_t -+drbg_max_requests (void) -+{ -+ /* SP800-90A requires 2**48 maximum requests before reseeding */ -+#ifdef __LP64__ -+ return (1UL<<48); -+#else -+ return SIZE_MAX; -+#endif -+} -+ -+/* -+ * Return strength of DRBG according to SP800-90A section 8.4 -+ * -+ * flags: DRBG flags reference -+ * -+ * Return: normalized strength value or 32 as a default to counter -+ * programming errors -+ */ -+static inline unsigned short -+drbg_sec_strength (u_int32_t flags) -+{ -+ if ((flags & DRBG_HASHSHA1) || (flags & DRBG_SYM128)) -+ return 16; -+ else if (flags & DRBG_SYM192) -+ return 24; -+ else if ((flags & DRBG_SYM256) || (flags & DRBG_HASHSHA256) || -+ (flags & DRBG_HASHSHA384) || (flags & DRBG_HASHSHA512)) -+ return 32; -+ else -+ return 32; -+} -+ -+/* -+ * FIPS 140-2 continuous self test -+ * The test is performed on the result of one round of the output -+ * function. Thus, the function implicitly knows the size of the -+ * buffer. -+ * -+ * @drbg DRBG handle -+ * @buf output buffer of random data to be checked -+ * -+ * return: -+ * false on error -+ * true on success -+ */ -+static gpg_err_code_t -+drbg_fips_continuous_test (struct drbg_state *drbg, const unsigned char *buf) -+{ -+ gpg_err_code_t ret = 0; -+ /* skip test if we test the overall system */ -+ if (drbg->test_data) -+ return 1; -+ /* only perform test in FIPS mode */ -+ if (0 == fips_mode ()) -+ return 1; -+ if (!drbg->fips_primed) -+ { -+ /* Priming of FIPS test */ -+ memcpy (drbg->prev, buf, drbg_blocklen (drbg)); -+ drbg->fips_primed = 1; -+ /* return false due to priming, i.e. another round is needed */ -+ return 0; -+ } -+ ret = memcmp (drbg->prev, buf, drbg_blocklen (drbg)); -+ memcpy (drbg->prev, buf, drbg_blocklen (drbg)); -+ /* the test shall pass when the two compared values are not equal */ -+ return ret != 0; -+} -+ -+static inline void drbg_cpu_to_be32(uint32_t val, unsigned char *buf) -+{ -+ struct s { -+ uint32_t conv; -+ }; -+ struct s *conversion = (struct s *) buf; -+ -+ conversion->conv = be_bswap32(val); -+} -+ -+static void -+drbg_add_buf (unsigned char *dst, size_t dstlen, -+ unsigned char *add, size_t addlen) -+{ -+ /* implied: dstlen > addlen */ -+ unsigned char *dstptr, *addptr; -+ unsigned int remainder = 0; -+ size_t len = addlen; -+ -+ dstptr = dst + (dstlen - 1); -+ addptr = add + (addlen - 1); -+ while (len) -+ { -+ remainder += *dstptr + *addptr; -+ *dstptr = remainder & 0xff; -+ remainder >>= 8; -+ len--; -+ dstptr--; -+ addptr--; -+ } -+ len = dstlen - addlen; -+ while (len && remainder > 0) -+ { -+ remainder = *dstptr + 1; -+ *dstptr = remainder & 0xff; -+ remainder >>= 8; -+ len--; -+ dstptr--; -+ } -+} -+ -+/* Helper variables for read_cb(). -+ * -+ * The _gcry_rnd*_gather_random interface does not allow to provide a -+ * data pointer. Thus we need to use a global variable for -+ * communication. However, the then required locking is anyway a good -+ * idea because it does not make sense to have several readers of (say -+ * /dev/random). It is easier to serve them one after the other. */ -+static unsigned char *read_cb_buffer; /* The buffer. */ -+static size_t read_cb_size; /* Size of the buffer. */ -+static size_t read_cb_len; /* Used length. */ -+ -+/* Callback for generating seed from kernel device. */ -+static void -+drbg_read_cb (const void *buffer, size_t length, enum random_origins origin) -+{ -+ const unsigned char *p = buffer; -+ -+ (void) origin; -+ gcry_assert (read_cb_buffer); -+ -+ /* Note that we need to protect against gatherers returning more -+ * than the requested bytes (e.g. rndw32). */ -+ while (length-- && read_cb_len < read_cb_size) -+ read_cb_buffer[read_cb_len++] = *p++; -+} -+ -+static inline int -+drbg_get_entropy (struct drbg_state *drbg, unsigned char *buffer, size_t len) -+{ -+ int rc = 0; -+ -+ /* Perform testing as defined in 11.3.2 */ -+ if (drbg->test_data && drbg->test_data->fail_seed_source) -+ return -1; -+ -+ read_cb_buffer = buffer; -+ read_cb_size = len; -+ read_cb_len = 0; -+#if USE_RNDLINUX -+ rc = _gcry_rndlinux_gather_random (drbg_read_cb, 0, len, -+ GCRY_VERY_STRONG_RANDOM); -+#elif USE_RNDUNIX -+ rc = _gcry_rndunix_gather_random (read_cb, 0, length, -+ GCRY_VERY_STRONG_RANDOM); -+#elif USE_RNDW32 -+ do -+ { -+ rc = _gcry_rndw32_gather_random (read_cb, 0, length, -+ GCRY_VERY_STRONG_RANDOM); -+ } -+ while (rc >= 0 && read_cb_len < read_cb_size); -+#else -+ rc = -1; -+#endif -+ return rc; -+} -+ -+/****************************************************************** -+ * CTR DRBG callback functions -+ ******************************************************************/ -+ -+static gpg_err_code_t drbg_gcry_sym (struct drbg_state *drbg, -+ const unsigned char *key, -+ unsigned char *outval, -+ const struct drbg_string *buf); -+ -+/* BCC function for CTR DRBG as defined in 10.4.3 */ -+static gpg_err_code_t -+drbg_ctr_bcc (struct drbg_state *drbg, -+ unsigned char *out, const unsigned char *key, -+ struct drbg_string *in) -+{ -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ struct drbg_string *curr = in; -+ size_t inpos = curr->len; -+ const unsigned char *pos = curr->buf; -+ struct drbg_string data; -+ -+ drbg_string_fill (&data, out, drbg_blocklen (drbg)); -+ -+ /* 10.4.3 step 1 */ -+ memset (out, 0, drbg_blocklen (drbg)); -+ -+ /* 10.4.3 step 2 / 4 */ -+ while (inpos) -+ { -+ short cnt = 0; -+ /* 10.4.3 step 4.1 */ -+ for (cnt = 0; cnt < drbg_blocklen (drbg); cnt++) -+ { -+ out[cnt] ^= *pos; -+ pos++; -+ inpos--; -+ /* the following branch implements the linked list -+ * iteration. If we are at the end of the current data -+ * set, we have to start using the next data set if -+ * available -- the inpos value always points to the -+ * current byte and will be zero if we have processed -+ * the last byte of the last linked list member */ -+ if (0 == inpos) -+ { -+ curr = curr->next; -+ if (NULL != curr) -+ { -+ pos = curr->buf; -+ inpos = curr->len; -+ } -+ else -+ { -+ inpos = 0; -+ break; -+ } -+ } -+ } -+ /* 10.4.3 step 4.2 */ -+ ret = drbg_gcry_sym (drbg, key, out, &data); -+ if (ret) -+ return ret; -+ /* 10.4.3 step 2 */ -+ } -+ return 0; -+} -+ -+ -+/* -+ * scratchpad usage: drbg_ctr_update is interlinked with drbg_ctr_df -+ * (and drbg_ctr_bcc, but this function does not need any temporary buffers), -+ * the scratchpad is used as follows: -+ * drbg_ctr_update: -+ * temp -+ * start: drbg->scratchpad -+ * length: drbg_statelen(drbg) + drbg_blocklen(drbg) -+ * note: the cipher writing into this variable works -+ * blocklen-wise. Now, when the statelen is not a multiple -+ * of blocklen, the generateion loop below "spills over" -+ * by at most blocklen. Thus, we need to give sufficient -+ * memory. -+ * df_data -+ * start: drbg->scratchpad + -+ * drbg_statelen(drbg) + drbg_blocklen(drbg) -+ * length: drbg_statelen(drbg) -+ * -+ * drbg_ctr_df: -+ * pad -+ * start: df_data + drbg_statelen(drbg) -+ * length: drbg_blocklen(drbg) -+ * iv -+ * start: pad + drbg_blocklen(drbg) -+ * length: drbg_blocklen(drbg) -+ * temp -+ * start: iv + drbg_blocklen(drbg) -+ * length: drbg_satelen(drbg) + drbg_blocklen(drbg) -+ * note: temp is the buffer that the BCC function operates -+ * on. BCC operates blockwise. drbg_statelen(drbg) -+ * is sufficient when the DRBG state length is a multiple -+ * of the block size. For AES192 (and maybe other ciphers) -+ * this is not correct and the length for temp is -+ * insufficient (yes, that also means for such ciphers, -+ * the final output of all BCC rounds are truncated). -+ * Therefore, add drbg_blocklen(drbg) to cover all -+ * possibilities. -+ */ -+ -+/* Derivation Function for CTR DRBG as defined in 10.4.2 */ -+static gpg_err_code_t -+drbg_ctr_df (struct drbg_state *drbg, unsigned char *df_data, -+ size_t bytes_to_return, struct drbg_string *addtl) -+{ -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ unsigned char L_N[8]; -+ /* S3 is input */ -+ struct drbg_string S1, S2, S4, cipherin; -+ struct drbg_string *tempstr = addtl; -+ unsigned char *pad = df_data + drbg_statelen (drbg); -+ unsigned char *iv = pad + drbg_blocklen (drbg); -+ unsigned char *temp = iv + drbg_blocklen (drbg); -+ size_t padlen = 0; -+ unsigned int templen = 0; -+ /* 10.4.2 step 7 */ -+ unsigned int i = 0; -+ /* 10.4.2 step 8 */ -+ const unsigned char *K = (unsigned char *) -+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" -+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"; -+ unsigned char *X; -+ size_t generated_len = 0; -+ size_t inputlen = 0; -+ -+ memset (pad, 0, drbg_blocklen (drbg)); -+ memset (iv, 0, drbg_blocklen (drbg)); -+ memset (temp, 0, drbg_statelen (drbg)); -+ -+ /* 10.4.2 step 1 is implicit as we work byte-wise */ -+ -+ /* 10.4.2 step 2 */ -+ if ((512 / 8) < bytes_to_return) -+ return GPG_ERR_INV_ARG; -+ -+ /* 10.4.2 step 2 -- calculate the entire length of all input data */ -+ for (; NULL != tempstr; tempstr = tempstr->next) -+ inputlen += tempstr->len; -+ drbg_cpu_to_be32 (inputlen, &L_N[0]); -+ -+ /* 10.4.2 step 3 */ -+ drbg_cpu_to_be32 (bytes_to_return, &L_N[4]); -+ -+ /* 10.4.2 step 5: length is size of L_N, input_string, one byte, padding */ -+ padlen = (inputlen + sizeof (L_N) + 1) % (drbg_blocklen (drbg)); -+ /* wrap the padlen appropriately */ -+ if (padlen) -+ padlen = drbg_blocklen (drbg) - padlen; -+ /* pad / padlen contains the 0x80 byte and the following zero bytes, so -+ * add one for byte for 0x80 */ -+ padlen++; -+ pad[0] = 0x80; -+ -+ /* 10.4.2 step 4 -- first fill the linked list and then order it */ -+ drbg_string_fill (&S1, iv, drbg_blocklen (drbg)); -+ drbg_string_fill (&S2, L_N, sizeof (L_N)); -+ drbg_string_fill (&S4, pad, padlen); -+ S1.next = &S2; -+ S2.next = addtl; -+ -+ /* Splice in addtl between S2 and S4 -- we place S4 at the end of the -+ * input data chain. As this code is only triggered when addtl is not -+ * NULL, no NULL checks are necessary.*/ -+ tempstr = addtl; -+ while (tempstr->next) -+ tempstr = tempstr->next; -+ tempstr->next = &S4; -+ -+ /* 10.4.2 step 9 */ -+ while (templen < (drbg_keylen (drbg) + (drbg_blocklen (drbg)))) -+ { -+ /* 10.4.2 step 9.1 - the padding is implicit as the buffer -+ * holds zeros after allocation -- even the increment of i -+ * is irrelevant as the increment remains within length of i */ -+ drbg_cpu_to_be32 (i, iv); -+ /* 10.4.2 step 9.2 -- BCC and concatenation with temp */ -+ ret = drbg_ctr_bcc (drbg, temp + templen, K, &S1); -+ if (ret) -+ goto out; -+ /* 10.4.2 step 9.3 */ -+ i++; -+ templen += drbg_blocklen (drbg); -+ } -+ -+ /* 10.4.2 step 11 */ -+ /* implicit key len with seedlen - blocklen according to table 3 */ -+ X = temp + (drbg_keylen (drbg)); -+ drbg_string_fill (&cipherin, X, drbg_blocklen (drbg)); -+ -+ /* 10.4.2 step 12: overwriting of outval */ -+ -+ /* 10.4.2 step 13 */ -+ while (generated_len < bytes_to_return) -+ { -+ short blocklen = 0; -+ /* 10.4.2 step 13.1 */ -+ /* the truncation of the key length is implicit as the key -+ * is only drbg_blocklen in size -- check for the implementation -+ * of the cipher function callback */ -+ ret = drbg_gcry_sym (drbg, temp, X, &cipherin); -+ if (ret) -+ goto out; -+ blocklen = (drbg_blocklen (drbg) < -+ (bytes_to_return - generated_len)) ? -+ drbg_blocklen (drbg) : (bytes_to_return - generated_len); -+ /* 10.4.2 step 13.2 and 14 */ -+ memcpy (df_data + generated_len, X, blocklen); -+ generated_len += blocklen; -+ } -+ -+ ret = 0; -+ -+out: -+ memset (iv, 0, drbg_blocklen (drbg)); -+ memset (temp, 0, drbg_statelen (drbg)); -+ memset (pad, 0, drbg_blocklen (drbg)); -+ return ret; -+} -+ -+/* -+ * update function of CTR DRBG as defined in 10.2.1.2 -+ * -+ * The reseed variable has an enhanced meaning compared to the update -+ * functions of the other DRBGs as follows: -+ * 0 => initial seed from initialization -+ * 1 => reseed via drbg_seed -+ * 2 => first invocation from drbg_ctr_update when addtl is present. In -+ * this case, the df_data scratchpad is not deleted so that it is -+ * available for another calls to prevent calling the DF function -+ * again. -+ * 3 => second invocation from drbg_ctr_update. When the update function -+ * was called with addtl, the df_data memory already contains the -+ * DFed addtl information and we do not need to call DF again. -+ */ -+static gpg_err_code_t -+drbg_ctr_update (struct drbg_state *drbg, -+ struct drbg_string *addtl, int reseed) -+{ -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ /* 10.2.1.2 step 1 */ -+ unsigned char *temp = drbg->scratchpad; -+ unsigned char *df_data = drbg->scratchpad + drbg_statelen (drbg) + -+ drbg_blocklen (drbg); -+ unsigned char *temp_p, *df_data_p; /* pointer to iterate over buffers */ -+ unsigned int len = 0; -+ struct drbg_string cipherin; -+ unsigned char prefix = DRBG_PREFIX1; -+ -+ memset (temp, 0, drbg_statelen (drbg) + drbg_blocklen (drbg)); -+ if (3 > reseed) -+ memset (df_data, 0, drbg_statelen (drbg)); -+ -+ /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */ -+ /* TODO use reseed variable to avoid re-doing DF operation */ -+ (void) reseed; -+ if (addtl && 0 < addtl->len) -+ { -+ ret = drbg_ctr_df (drbg, df_data, drbg_statelen (drbg), addtl); -+ if (ret) -+ goto out; -+ } -+ -+ drbg_string_fill (&cipherin, drbg->V, drbg_blocklen (drbg)); -+ /* 10.2.1.3.2 step 2 and 3 -- are already covered as we memset(0) -+ * all memory during initialization */ -+ while (len < (drbg_statelen (drbg))) -+ { -+ /* 10.2.1.2 step 2.1 */ -+ drbg_add_buf (drbg->V, drbg_blocklen (drbg), &prefix, 1); -+ /* 10.2.1.2 step 2.2 */ -+ /* using target of temp + len: 10.2.1.2 step 2.3 and 3 */ -+ ret = drbg_gcry_sym (drbg, drbg->C, temp + len, &cipherin); -+ if (ret) -+ goto out; -+ /* 10.2.1.2 step 2.3 and 3 */ -+ len += drbg_blocklen (drbg); -+ } -+ -+ /* 10.2.1.2 step 4 */ -+ temp_p = temp; -+ df_data_p = df_data; -+ for (len = 0; len < drbg_statelen (drbg); len++) -+ { -+ *temp_p ^= *df_data_p; -+ df_data_p++; -+ temp_p++; -+ } -+ -+ /* 10.2.1.2 step 5 */ -+ memcpy (drbg->C, temp, drbg_keylen (drbg)); -+ /* 10.2.1.2 step 6 */ -+ memcpy (drbg->V, temp + drbg_keylen (drbg), drbg_blocklen (drbg)); -+ ret = 0; -+ -+out: -+ memset (temp, 0, drbg_statelen (drbg) + drbg_blocklen (drbg)); -+ if (2 != reseed) -+ memset (df_data, 0, drbg_statelen (drbg)); -+ return ret; -+} -+ -+/* -+ * scratchpad use: drbg_ctr_update is called independently from -+ * drbg_ctr_extract_bytes. Therefore, the scratchpad is reused -+ */ -+/* Generate function of CTR DRBG as defined in 10.2.1.5.2 */ -+static gpg_err_code_t -+drbg_ctr_generate (struct drbg_state *drbg, -+ unsigned char *buf, unsigned int buflen, -+ struct drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned int len = 0; -+ struct drbg_string data; -+ unsigned char prefix = DRBG_PREFIX1; -+ -+ memset (drbg->scratchpad, 0, drbg_blocklen (drbg)); -+ -+ /* 10.2.1.5.2 step 2 */ -+ if (addtl && 0 < addtl->len) -+ { -+ addtl->next = NULL; -+ ret = drbg_ctr_update (drbg, addtl, 2); -+ if (ret) -+ return ret; -+ } -+ -+ /* 10.2.1.5.2 step 4.1 */ -+ drbg_add_buf (drbg->V, drbg_blocklen (drbg), &prefix, 1); -+ drbg_string_fill (&data, drbg->V, drbg_blocklen (drbg)); -+ while (len < buflen) -+ { -+ unsigned int outlen = 0; -+ /* 10.2.1.5.2 step 4.2 */ -+ ret = drbg_gcry_sym (drbg, drbg->C, drbg->scratchpad, &data); -+ if (ret) -+ goto out; -+ outlen = (drbg_blocklen (drbg) < (buflen - len)) ? -+ drbg_blocklen (drbg) : (buflen - len); -+ if (!drbg_fips_continuous_test (drbg, drbg->scratchpad)) -+ { -+ /* 10.2.1.5.2 step 6 */ -+ drbg_add_buf (drbg->V, drbg_blocklen (drbg), &prefix, 1); -+ continue; -+ } -+ /* 10.2.1.5.2 step 4.3 */ -+ memcpy (buf + len, drbg->scratchpad, outlen); -+ len += outlen; -+ /* 10.2.1.5.2 step 6 */ -+ if (len < buflen) -+ drbg_add_buf (drbg->V, drbg_blocklen (drbg), &prefix, 1); -+ } -+ -+ /* 10.2.1.5.2 step 6 */ -+ if (addtl) -+ addtl->next = NULL; -+ ret = drbg_ctr_update (drbg, addtl, 3); -+ -+out: -+ memset (drbg->scratchpad, 0, drbg_blocklen (drbg)); -+ return ret; -+} -+ -+static struct drbg_state_ops drbg_ctr_ops = { -+ .update = drbg_ctr_update, -+ .generate = drbg_ctr_generate, -+}; -+ -+/****************************************************************** -+ * HMAC DRBG callback functions -+ ******************************************************************/ -+ -+static gpg_err_code_t drbg_gcry_hmac (struct drbg_state *drbg, -+ const unsigned char *key, -+ unsigned char *outval, -+ const struct drbg_string *buf); -+ -+static gpg_err_code_t -+drbg_hmac_update (struct drbg_state *drbg, -+ struct drbg_string *seed, int reseed) -+{ -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ int i = 0; -+ struct drbg_string seed1, seed2, cipherin; -+ -+ if (!reseed) -+ { -+ /* 10.1.2.3 step 2 already implicitly covered with -+ * the initial memset(0) of drbg->C */ -+ memset (drbg->C, 0, drbg_statelen (drbg)); -+ memset (drbg->V, 1, drbg_statelen (drbg)); -+ } -+ -+ /* build linked list which implements the concatenation and fill -+ * first part*/ -+ drbg_string_fill (&seed1, drbg->V, drbg_statelen (drbg)); -+ /* buffer will be filled in for loop below with one byte */ -+ drbg_string_fill (&seed2, NULL, 1); -+ seed1.next = &seed2; -+ /* seed may be NULL */ -+ seed2.next = seed; -+ -+ drbg_string_fill (&cipherin, drbg->V, drbg_statelen (drbg)); -+ /* we execute two rounds of V/K massaging */ -+ for (i = 2; 0 < i; i--) -+ { -+ /* first round uses 0x0, second 0x1 */ -+ unsigned char prefix = DRBG_PREFIX0; -+ if (1 == i) -+ prefix = DRBG_PREFIX1; -+ /* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */ -+ seed2.buf = &prefix; -+ ret = drbg_gcry_hmac (drbg, drbg->C, drbg->C, &seed1); -+ if (ret) -+ return ret; -+ -+ /* 10.1.2.2 step 2 and 5 -- HMAC for V */ -+ ret = drbg_gcry_hmac (drbg, drbg->C, drbg->V, &cipherin); -+ if (ret) -+ return ret; -+ -+ /* 10.1.2.2 step 3 */ -+ if (!seed || 0 == seed->len) -+ return ret; -+ } -+ return 0; -+} -+ -+/* generate function of HMAC DRBG as defined in 10.1.2.5 */ -+static gpg_err_code_t -+drbg_hmac_generate (struct drbg_state *drbg, -+ unsigned char *buf, -+ unsigned int buflen, struct drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned int len = 0; -+ struct drbg_string data; -+ -+ /* 10.1.2.5 step 2 */ -+ if (addtl && 0 < addtl->len) -+ { -+ addtl->next = NULL; -+ ret = drbg_hmac_update (drbg, addtl, 1); -+ if (ret) -+ return ret; -+ } -+ -+ drbg_string_fill (&data, drbg->V, drbg_statelen (drbg)); -+ while (len < buflen) -+ { -+ unsigned int outlen = 0; -+ /* 10.1.2.5 step 4.1 */ -+ ret = drbg_gcry_hmac (drbg, drbg->C, drbg->V, &data); -+ if (ret) -+ return ret; -+ outlen = (drbg_blocklen (drbg) < (buflen - len)) ? -+ drbg_blocklen (drbg) : (buflen - len); -+ if (!drbg_fips_continuous_test (drbg, drbg->V)) -+ continue; -+ -+ /* 10.1.2.5 step 4.2 */ -+ memcpy (buf + len, drbg->V, outlen); -+ len += outlen; -+ } -+ -+ /* 10.1.2.5 step 6 */ -+ if (addtl) -+ addtl->next = NULL; -+ ret = drbg_hmac_update (drbg, addtl, 1); -+ -+ return ret; -+} -+ -+static struct drbg_state_ops drbg_hmac_ops = { -+ .update = drbg_hmac_update, -+ .generate = drbg_hmac_generate, -+}; -+ -+/****************************************************************** -+ * Hash DRBG callback functions -+ ******************************************************************/ -+ -+/* -+ * scratchpad usage: as drbg_hash_update and drbg_hash_df are used -+ * interlinked, the scratchpad is used as follows: -+ * drbg_hash_update -+ * start: drbg->scratchpad -+ * length: drbg_statelen(drbg) -+ * drbg_hash_df: -+ * start: drbg->scratchpad + drbg_statelen(drbg) -+ * length: drbg_blocklen(drbg) -+ */ -+/* Derivation Function for Hash DRBG as defined in 10.4.1 */ -+static gpg_err_code_t -+drbg_hash_df (struct drbg_state *drbg, -+ unsigned char *outval, size_t outlen, -+ struct drbg_string *entropy) -+{ -+ gpg_err_code_t ret = 0; -+ size_t len = 0; -+ unsigned char input[5]; -+ unsigned char *tmp = drbg->scratchpad + drbg_statelen (drbg); -+ struct drbg_string data1; -+ -+ memset (tmp, 0, drbg_blocklen (drbg)); -+ -+ /* 10.4.1 step 3 */ -+ input[0] = 1; -+ drbg_cpu_to_be32 ((outlen * 8), &input[1]); -+ -+ /* 10.4.1 step 4.1 -- concatenation of data for input into hash */ -+ drbg_string_fill (&data1, input, 5); -+ data1.next = entropy; -+ -+ /* 10.4.1 step 4 */ -+ while (len < outlen) -+ { -+ short blocklen = 0; -+ /* 10.4.1 step 4.1 */ -+ ret = drbg_gcry_hmac (drbg, NULL, tmp, &data1); -+ if (ret) -+ goto out; -+ /* 10.4.1 step 4.2 */ -+ input[0]++; -+ blocklen = (drbg_blocklen (drbg) < (outlen - len)) ? -+ drbg_blocklen (drbg) : (outlen - len); -+ memcpy (outval + len, tmp, blocklen); -+ len += blocklen; -+ } -+ -+out: -+ memset (tmp, 0, drbg_blocklen (drbg)); -+ return ret; -+} -+ -+/* update function for Hash DRBG as defined in 10.1.1.2 / 10.1.1.3 */ -+static gpg_err_code_t -+drbg_hash_update (struct drbg_state *drbg, struct drbg_string *seed, -+ int reseed) -+{ -+ gpg_err_code_t ret = 0; -+ struct drbg_string data1, data2; -+ unsigned char *V = drbg->scratchpad; -+ unsigned char prefix = DRBG_PREFIX1; -+ -+ memset (drbg->scratchpad, 0, drbg_statelen (drbg)); -+ if (!seed) -+ return GPG_ERR_INV_ARG; -+ -+ if (reseed) -+ { -+ /* 10.1.1.3 step 1: string length is concatenation of -+ * 1 byte, V and seed (which is concatenated entropy/addtl -+ * input) -+ */ -+ memcpy (V, drbg->V, drbg_statelen (drbg)); -+ drbg_string_fill (&data1, &prefix, 1); -+ drbg_string_fill (&data2, V, drbg_statelen (drbg)); -+ data1.next = &data2; -+ data2.next = seed; -+ } -+ else -+ { -+ drbg_string_fill (&data1, seed->buf, seed->len); -+ data1.next = seed->next; -+ } -+ -+ /* 10.1.1.2 / 10.1.1.3 step 2 and 3 */ -+ ret = drbg_hash_df (drbg, drbg->V, drbg_statelen (drbg), &data1); -+ if (ret) -+ goto out; -+ -+ /* 10.1.1.2 / 10.1.1.3 step 4 -- concatenation */ -+ prefix = DRBG_PREFIX0; -+ drbg_string_fill (&data1, &prefix, 1); -+ drbg_string_fill (&data2, drbg->V, drbg_statelen (drbg)); -+ data1.next = &data2; -+ /* 10.1.1.2 / 10.1.1.3 step 4 -- df operation */ -+ ret = drbg_hash_df (drbg, drbg->C, drbg_statelen (drbg), &data1); -+ -+out: -+ memset (drbg->scratchpad, 0, drbg_statelen (drbg)); -+ return ret; -+} -+ -+/* processing of additional information string for Hash DRBG */ -+static gpg_err_code_t -+drbg_hash_process_addtl (struct drbg_state *drbg, struct drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ struct drbg_string data1, data2; -+ struct drbg_string *data3; -+ unsigned char prefix = DRBG_PREFIX2; -+ -+ /* this is value w as per documentation */ -+ memset (drbg->scratchpad, 0, drbg_blocklen (drbg)); -+ -+ /* 10.1.1.4 step 2 */ -+ if (!addtl || 0 == addtl->len) -+ return 0; -+ -+ /* 10.1.1.4 step 2a -- concatenation */ -+ drbg_string_fill (&data1, &prefix, 1); -+ drbg_string_fill (&data2, drbg->V, drbg_statelen (drbg)); -+ data3 = addtl; -+ data1.next = &data2; -+ data2.next = data3; -+ data3->next = NULL; -+ /* 10.1.1.4 step 2a -- cipher invocation */ -+ ret = drbg_gcry_hmac (drbg, NULL, drbg->scratchpad, &data1); -+ if (ret) -+ goto out; -+ -+ /* 10.1.1.4 step 2b */ -+ drbg_add_buf (drbg->V, drbg_statelen (drbg), -+ drbg->scratchpad, drbg_blocklen (drbg)); -+ -+out: -+ memset (drbg->scratchpad, 0, drbg_blocklen (drbg)); -+ return ret; -+} -+ -+/* -+ * Hashgen defined in 10.1.1.4 -+ */ -+static gpg_err_code_t -+drbg_hash_hashgen (struct drbg_state *drbg, -+ unsigned char *buf, unsigned int buflen) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned int len = 0; -+ unsigned char *src = drbg->scratchpad; -+ unsigned char *dst = drbg->scratchpad + drbg_statelen (drbg); -+ struct drbg_string data; -+ unsigned char prefix = DRBG_PREFIX1; -+ -+ /* use the scratchpad as a lookaside buffer */ -+ memset (src, 0, drbg_statelen (drbg)); -+ memset (dst, 0, drbg_blocklen (drbg)); -+ -+ /* 10.1.1.4 step hashgen 2 */ -+ memcpy (src, drbg->V, drbg_statelen (drbg)); -+ -+ drbg_string_fill (&data, src, drbg_statelen (drbg)); -+ while (len < buflen) -+ { -+ unsigned int outlen = 0; -+ /* 10.1.1.4 step hashgen 4.1 */ -+ ret = drbg_gcry_hmac (drbg, NULL, dst, &data); -+ if (ret) -+ goto out; -+ outlen = (drbg_blocklen (drbg) < (buflen - len)) ? -+ drbg_blocklen (drbg) : (buflen - len); -+ if (!drbg_fips_continuous_test (drbg, dst)) -+ { -+ drbg_add_buf (src, drbg_statelen (drbg), &prefix, 1); -+ continue; -+ } -+ /* 10.1.1.4 step hashgen 4.2 */ -+ memcpy (buf + len, dst, outlen); -+ len += outlen; -+ /* 10.1.1.4 hashgen step 4.3 */ -+ if (len < buflen) -+ drbg_add_buf (src, drbg_statelen (drbg), &prefix, 1); -+ } -+ -+out: -+ memset (drbg->scratchpad, 0, (drbg_statelen (drbg) + drbg_blocklen (drbg))); -+ return ret; -+} -+ -+/* generate function for Hash DRBG as defined in 10.1.1.4 */ -+static gpg_err_code_t -+drbg_hash_generate (struct drbg_state *drbg, -+ unsigned char *buf, unsigned int buflen, -+ struct drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned char prefix = DRBG_PREFIX3; -+ struct drbg_string data1, data2; -+ union -+ { -+ unsigned char req[8]; -+ uint64_t req_int; -+ } u; -+ -+ /* -+ * scratchpad usage: drbg_hash_process_addtl uses the scratchpad, but -+ * fully completes before returning. Thus, we can reuse the scratchpad -+ */ -+ /* 10.1.1.4 step 2 */ -+ ret = drbg_hash_process_addtl (drbg, addtl); -+ if (ret) -+ return ret; -+ /* 10.1.1.4 step 3 -- invocation of the Hashgen function defined in -+ * 10.1.1.4 */ -+ ret = drbg_hash_hashgen (drbg, buf, buflen); -+ if (ret) -+ return ret; -+ -+ /* this is the value H as documented in 10.1.1.4 */ -+ memset (drbg->scratchpad, 0, drbg_blocklen (drbg)); -+ /* 10.1.1.4 step 4 */ -+ drbg_string_fill (&data1, &prefix, 1); -+ drbg_string_fill (&data2, drbg->V, drbg_statelen (drbg)); -+ data1.next = &data2; -+ ret = drbg_gcry_hmac (drbg, NULL, drbg->scratchpad, &data1); -+ if (ret) -+ goto out; -+ -+ /* 10.1.1.4 step 5 */ -+ drbg_add_buf (drbg->V, drbg_statelen (drbg), -+ drbg->scratchpad, drbg_blocklen (drbg)); -+ drbg_add_buf (drbg->V, drbg_statelen (drbg), drbg->C, drbg_statelen (drbg)); -+ u.req_int = be_bswap64(drbg->reseed_ctr); -+ drbg_add_buf (drbg->V, drbg_statelen (drbg), u.req, sizeof (u.req)); -+ -+out: -+ memset (drbg->scratchpad, 0, drbg_blocklen (drbg)); -+ return ret; -+} -+ -+/* -+ * scratchpad usage: as update and generate are used isolated, both -+ * can use the scratchpad -+ */ -+static struct drbg_state_ops drbg_hash_ops = { -+ .update = drbg_hash_update, -+ .generate = drbg_hash_generate, -+}; -+ -+/****************************************************************** -+ * Functions common for DRBG implementations -+ ******************************************************************/ -+ -+/* -+ * Seeding or reseeding of the DRBG -+ * -+ * @drbg: DRBG state struct -+ * @pers: personalization / additional information buffer -+ * @reseed: 0 for initial seed process, 1 for reseeding -+ * -+ * return: -+ * 0 on success -+ * error value otherwise -+ */ -+static gpg_err_code_t -+drbg_seed (struct drbg_state *drbg, struct drbg_string *pers, int reseed) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned char *entropy = NULL; -+ size_t entropylen = 0; -+ struct drbg_string data1; -+ -+ /* 9.1 / 9.2 / 9.3.1 step 3 */ -+ if (pers && pers->len > (drbg_max_addtl ())) -+ { -+ dbg (("DRBG: personalization string too long %lu\n", pers->len)); -+ return GPG_ERR_INV_ARG; -+ } -+ if (drbg->test_data && drbg->test_data->testentropy) -+ { -+ drbg_string_fill (&data1, drbg->test_data->testentropy->buf, -+ drbg->test_data->testentropy->len); -+ dbg (("DRBG: using test entropy\n")); -+ } -+ else -+ { -+ /* Gather entropy equal to the security strength of the DRBG. -+ * With a derivation function, a nonce is required in addition -+ * to the entropy. A nonce must be at least 1/2 of the security -+ * strength of the DRBG in size. Thus, entropy * nonce is 3/2 -+ * of the strength. The consideration of a nonce is only -+ * applicable during initial seeding. */ -+ entropylen = drbg_sec_strength (drbg->core->flags); -+ if (!entropylen) -+ return GPG_ERR_GENERAL; -+ if (0 == reseed) -+ /* make sure we round up strength/2 in -+ * case it is not divisible by 2 */ -+ entropylen = ((entropylen + 1) / 2) * 3; -+ dbg (("DRBG: (re)seeding with %lu bytes of entropy\n", entropylen)); -+ entropy = drbg_malloc (entropylen); -+ if (!entropy) -+ return GPG_ERR_ENOMEM; -+ ret = drbg_get_entropy (drbg, entropy, entropylen); -+ if (ret) -+ goto out; -+ drbg_string_fill (&data1, entropy, entropylen); -+ } -+ -+ /* concatenation of entropy with personalization str / addtl input) -+ * the variable pers is directly handed by the caller, check its -+ * contents whether it is appropriate */ -+ if (pers && pers->buf && 0 < pers->len && NULL == pers->next) -+ { -+ data1.next = pers; -+ dbg (("DRBG: using personalization string\n")); -+ } -+ -+ ret = drbg->d_ops->update (drbg, &data1, reseed); -+ dbg (("DRBG: state updated with seed\n")); -+ if (ret) -+ goto out; -+ drbg->seeded = 1; -+ /* 10.1.1.2 / 10.1.1.3 step 5 */ -+ drbg->reseed_ctr = 1; -+ -+out: -+ if (entropy) -+ xfree (entropy); -+ return ret; -+} -+ -+/************************************************************************* -+ * exported interfaces -+ *************************************************************************/ -+ -+/* -+ * DRBG generate function as required by SP800-90A - this function -+ * generates random numbers -+ * -+ * @drbg DRBG state handle -+ * @buf Buffer where to store the random numbers -- the buffer must already -+ * be pre-allocated by caller -+ * @buflen Length of output buffer - this value defines the number of random -+ * bytes pulled from DRBG -+ * @addtl Additional input that is mixed into state, may be NULL -- note -+ * the entropy is pulled by the DRBG internally unconditionally -+ * as defined in SP800-90A. The additional input is mixed into -+ * the state in addition to the pulled entropy. -+ * -+ * return: generated number of bytes -+ */ -+static gpg_err_code_t -+drbg_generate (struct drbg_state *drbg, -+ unsigned char *buf, unsigned int buflen, -+ struct drbg_string *addtl) -+{ -+ gpg_err_code_t ret = GPG_ERR_INV_ARG; -+ -+ if (0 == buflen || !buf) -+ { -+ dbg (("DRBG: no buffer provided\n")); -+ return ret; -+ } -+ if (addtl && NULL == addtl->buf && 0 < addtl->len) -+ { -+ dbg (("DRBG: wrong format of additional information\n")); -+ return ret; -+ } -+ -+ /* 9.3.1 step 2 */ -+ if (buflen > (drbg_max_request_bytes ())) -+ { -+ dbg (("DRBG: requested random numbers too large %u\n", buflen)); -+ return ret; -+ } -+ /* 9.3.1 step 3 is implicit with the chosen DRBG */ -+ /* 9.3.1 step 4 */ -+ if (addtl && addtl->len > (drbg_max_addtl ())) -+ { -+ dbg (("DRBG: additional information string too long %lu\n", -+ addtl->len)); -+ return ret; -+ } -+ /* 9.3.1 step 5 is implicit with the chosen DRBG */ -+ /* 9.3.1 step 6 and 9 supplemented by 9.3.2 step c -- the spec is a -+ * bit convoluted here, we make it simpler */ -+ if ((drbg_max_requests ()) < drbg->reseed_ctr) -+ drbg->seeded = 0; -+ -+ if (drbg->pr || !drbg->seeded) -+ { -+ dbg (("DRBG: reseeding before generation (prediction resistance: %s, state %s)\n", drbg->pr ? "true" : "false", drbg->seeded ? "seeded" : "unseeded")); -+ /* 9.3.1 steps 7.1 through 7.3 */ -+ ret = drbg_seed (drbg, addtl, 1); -+ if (ret) -+ return ret; -+ /* 9.3.1 step 7.4 */ -+ addtl = NULL; -+ } -+ -+ if (addtl && addtl->buf) -+ { -+ dbg (("DRBG: using additional information string\n")); -+ } -+ -+ /* 9.3.1 step 8 and 10 */ -+ ret = drbg->d_ops->generate (drbg, buf, buflen, addtl); -+ -+ /* 10.1.1.4 step 6, 10.1.2.5 step 7, 10.2.1.5.2 step 7 */ -+ drbg->reseed_ctr++; -+ if (ret) -+ return ret; -+ -+ /* 11.3.3 -- re-perform self tests after some generated random -+ * numbers, the chosen value after which self test is performed -+ * is arbitrary, but it should be reasonable */ -+ /* Here we do not perform the self tests because of the following -+ * reasons: it is mathematically impossible that the initial self tests -+ * were successfully and the following are not. If the initial would -+ * pass and the following would not, the system integrity is violated. -+ * In this case, the entire system operation is questionable and it -+ * is unlikely that the integrity violation only affects to the -+ * correct operation of the DRBG. -+ */ -+#if 0 -+ if (drbg->reseed_ctr && !(drbg->reseed_ctr % 4096)) -+ { -+ dbg (("DRBG: start to perform self test\n")); -+ ret = drbg_healthcheck (); -+ if (ret) -+ { -+ log_fatal (("DRBG: self test failed\n")); -+ return ret; -+ } -+ else -+ { -+ dbg (("DRBG: self test successful\n")); -+ } -+ } -+#endif -+ -+ return ret; -+} -+ -+/* -+ * Wrapper around drbg_generate which can pull arbitrary long strings -+ * from the DRBG without hitting the maximum request limitation. -+ * -+ * Parameters: see drbg_generate -+ * Return codes: see drbg_generate -- if one drbg_generate request fails, -+ * the entire drbg_generate_long request fails -+ */ -+static gpg_err_code_t -+drbg_generate_long (struct drbg_state *drbg, -+ unsigned char *buf, unsigned int buflen, -+ struct drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned int slice = 0; -+ unsigned char *buf_p = buf; -+ unsigned len = 0; -+ do -+ { -+ unsigned int chunk = 0; -+ slice = ((buflen - len) / drbg_max_request_bytes ()); -+ chunk = slice ? drbg_max_request_bytes () : (buflen - len); -+ ret = drbg_generate (drbg, buf_p, chunk, addtl); -+ if (ret) -+ return ret; -+ buf_p += chunk; -+ len += chunk; -+ } -+ while (slice > 0 && (len < buflen)); -+ return ret; -+} -+ -+/* -+ * DRBG uninstantiate function as required by SP800-90A - this function -+ * frees all buffers and the DRBG handle -+ * -+ * @drbg DRBG state handle -+ * -+ * return -+ * 0 on success -+ */ -+static gpg_err_code_t -+drbg_uninstantiate (struct drbg_state *drbg) -+{ -+ if (!drbg) -+ return GPG_ERR_INV_ARG; -+ if (drbg->V) -+ xfree (drbg->V); -+ drbg->V = NULL; -+ if (drbg->C) -+ xfree (drbg->C); -+ drbg->C = NULL; -+ drbg->reseed_ctr = 0; -+ if (drbg->scratchpad) -+ xfree (drbg->scratchpad); -+ drbg->scratchpad = NULL; -+ drbg->seeded = 0; -+ drbg->pr = 0; -+ drbg->fips_primed = 0; -+ if (drbg->prev) -+ xfree (drbg->prev); -+ drbg->prev = NULL; -+ drbg->seed_init_pid = 0; -+ return 0; -+} -+ -+/* -+ * DRBG instantiation function as required by SP800-90A - this function -+ * sets up the DRBG handle, performs the initial seeding and all sanity -+ * checks required by SP800-90A -+ * -+ * @drbg memory of state -- if NULL, new memory is allocated -+ * @pers Personalization string that is mixed into state, may be NULL -- note -+ * the entropy is pulled by the DRBG internally unconditionally -+ * as defined in SP800-90A. The additional input is mixed into -+ * the state in addition to the pulled entropy. -+ * @coreref reference to core -+ * @flags Flags defining the requested DRBG type and cipher type. The flags -+ * are defined in drbg.h and may be XORed. Beware, if you XOR multiple -+ * cipher types together, the code picks the core on a first come first -+ * serve basis as it iterates through the available cipher cores and -+ * uses the one with the first match. The minimum required flags are: -+ * cipher type flag -+ * -+ * return -+ * 0 on success -+ * error value otherwise -+ */ -+static gpg_err_code_t -+drbg_instantiate (struct drbg_state *drbg, struct drbg_string *pers, -+ int coreref, int pr) -+{ -+ gpg_err_code_t ret = GPG_ERR_ENOMEM; -+ unsigned int sb_size = 0; -+ -+ if (!drbg) -+ return GPG_ERR_INV_ARG; -+ -+ dbg (("DRBG: Initializing DRBG core %d with prediction resistance %s\n", -+ coreref, pr ? "enabled" : "disabled")); -+ drbg->core = &drbg_cores[coreref]; -+ drbg->pr = pr; -+ drbg->seeded = 0; -+ if (drbg->core->flags & DRBG_HMAC) -+ drbg->d_ops = &drbg_hmac_ops; -+ else if (drbg->core->flags & DRBG_HASH_MASK) -+ drbg->d_ops = &drbg_hash_ops; -+ else if (drbg->core->flags & DRBG_CTR_MASK) -+ drbg->d_ops = &drbg_ctr_ops; -+ else -+ return GPG_ERR_GENERAL; -+ /* 9.1 step 1 is implicit with the selected DRBG type -- see -+ * drbg_sec_strength() */ -+ -+ /* 9.1 step 2 is implicit as caller can select prediction resistance -+ * and the flag is copied into drbg->flags -- -+ * all DRBG types support prediction resistance */ -+ -+ /* 9.1 step 4 is implicit in drbg_sec_strength */ -+ -+ /* no allocation of drbg as this is done by the kernel crypto API */ -+ drbg->V = drbg_malloc (drbg_statelen (drbg)); -+ if (!drbg->V) -+ goto err; -+ drbg->C = drbg_malloc (drbg_statelen (drbg)); -+ if (!drbg->C) -+ goto err; -+ drbg->prev = drbg_malloc (drbg_blocklen (drbg)); -+ if (!drbg->prev) -+ goto err; -+ drbg->fips_primed = 0; -+ /* scratchpad is only generated for CTR and Hash */ -+ if (drbg->core->flags & DRBG_HMAC) -+ sb_size = 0; -+ else if (drbg->core->flags & DRBG_CTR_MASK) -+ sb_size = drbg_statelen (drbg) + drbg_blocklen (drbg) + /* temp */ -+ drbg_statelen (drbg) + /* df_data */ -+ drbg_blocklen (drbg) + /* pad */ -+ drbg_blocklen (drbg) + /* iv */ -+ drbg_statelen (drbg) + drbg_blocklen(drbg); /* temp */ -+ else -+ sb_size = drbg_statelen (drbg) + drbg_blocklen (drbg); -+ -+ if (0 < sb_size) -+ { -+ drbg->scratchpad = drbg_malloc (sb_size); -+ if (!drbg->scratchpad) -+ goto err; -+ } -+ dbg (("DRBG: state allocated with scratchpad size %u bytes\n", sb_size)); -+ -+ /* 9.1 step 6 through 11 */ -+ ret = drbg_seed (drbg, pers, 0); -+ if (ret) -+ goto err; -+ -+ dbg (("DRBG: core %d %s prediction resistance successfully initialized\n", -+ coreref, pr ? "with" : "without")); -+ return 0; -+ -+err: -+ drbg_uninstantiate (drbg); -+ return ret; -+} -+ -+/* -+ * DRBG reseed function as required by SP800-90A -+ * -+ * @drbg DRBG state handle -+ * @addtl Additional input that is mixed into state, may be NULL -- note -+ * the entropy is pulled by the DRBG internally unconditionally -+ * as defined in SP800-90A. The additional input is mixed into -+ * the state in addition to the pulled entropy. -+ * -+ * return -+ * 0 on success -+ * error value otherwise -+ */ -+static gpg_err_code_t -+drbg_reseed (struct drbg_state *drbg, struct drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ ret = drbg_seed (drbg, addtl, 1); -+ return ret; -+} -+ -+/****************************************************************** -+ * ***************************************************************** -+ ****************************************************************** -+ * libgcrypt integration code -+ ****************************************************************** -+ ****************************************************************** -+ ******************************************************************/ -+ -+/*************************************************************** -+ * libgcrypt backend functions to the RNG API code -+ ***************************************************************/ -+ -+/* global state variable holding the current instance of the DRBG -- the -+ * default DRBG type is defined in _gcry_drbg_init */ -+static struct drbg_state *gcry_drbg = NULL; -+GPGRT_LOCK_DEFINE (drbg_gcry_lock); -+ -+static inline void -+drbg_lock (void) -+{ -+ gpg_err_code_t rc; -+ rc = gpgrt_lock_lock (&drbg_gcry_lock); -+ if (rc) -+ log_fatal ("failed to acquire the RNG lock: %s\n", gpg_strerror (rc)); -+} -+ -+static inline void -+drbg_unlock (void) -+{ -+ gpg_err_code_t rc; -+ rc = gpgrt_lock_unlock (&drbg_gcry_lock); -+ if (rc) -+ log_fatal ("failed to release the RNG lock: %s\n", gpg_strerror (rc)); -+} -+ -+/****** helper functions where lock must be held by caller *****/ -+ -+/* Check whether given flags are known to point to an applicable DRBG */ -+static gpg_err_code_t -+drbg_algo_available (u_int32_t flags, int *coreref) -+{ -+ int i = 0; -+ for (i = 0; ARRAY_SIZE (drbg_cores) > i; i++) -+ { -+ if ((drbg_cores[i].flags & DRBG_CIPHER_MASK) == -+ (flags & DRBG_CIPHER_MASK)) -+ { -+ *coreref = i; -+ return 0; -+ } -+ } -+ return GPG_ERR_GENERAL; -+} -+ -+static gpg_err_code_t -+_gcry_drbg_init_internal (int full, u_int32_t flags, struct drbg_string *pers) -+{ -+ gpg_err_code_t ret = 0; -+ static u_int32_t oldflags = 0; -+ int coreref = 0; -+ int pr = 0; -+ /* TODO what shall we do with the full variable? */ -+ (void) full; -+ -+ /* If a caller provides 0 as flags, use the flags of the previous -+ * initialization, otherwise use the current flags and remember them -+ * for the next invocation -+ */ -+ if (0 == flags) -+ flags = oldflags; -+ else -+ oldflags = flags; -+ -+ ret = drbg_algo_available (flags, &coreref); -+ if (ret) -+ return ret; -+ -+ if (NULL != gcry_drbg) -+ { -+ drbg_uninstantiate (gcry_drbg); -+ } -+ else -+ { -+ gcry_drbg = drbg_malloc (sizeof (struct drbg_state)); -+ if (!gcry_drbg) -+ return GPG_ERR_ENOMEM; -+ } -+ if (flags & DRBG_PREDICTION_RESIST) -+ pr = 1; -+ ret = drbg_instantiate (gcry_drbg, pers, coreref, pr); -+ if (ret) -+ fips_signal_error ("DRBG cannot be initialized"); -+ else -+ gcry_drbg->seed_init_pid = getpid (); -+ return ret; -+} -+ -+/************* calls available to common RNG code **************/ -+ -+/* -+ * Initialize one DRBG invoked by the libgcrypt API -+ * -+ * Function uses the kernel crypto API cra_name to look up -+ * the flags to instantiate the DRBG -+ */ -+void -+_gcry_drbg_init (int full) -+{ -+ /* default DRBG */ -+ u_int32_t flags = DRBG_NOPR_HMACSHA256; -+ drbg_lock (); -+ _gcry_drbg_init_internal (full, flags, NULL); -+ drbg_unlock (); -+} -+ -+/* -+ * Backend handler function for GCRYCTL_DRBG_REINIT -+ * -+ * Select a different DRBG type and initialize it. -+ * Function checks whether requested DRBG type exists and returns an error in -+ * case it does not. In case of an error, the previous instantiated DRBG is -+ * left untouched and alive. Thus, in case of an error, a DRBG is always -+ * available, even if it is not the chosen one. -+ * -+ * Re-initialization will be performed in any case regardless whether flags -+ * or personalization string are set. -+ * -+ * If flags == 0, do not change current DRBG -+ * If parsonalization string is NULL or its length is 0, re-initialize without -+ * personalization string -+ * -+ * If test_data is provided, the "entropy" is provided instead of using -+ * the noise source. -+ */ -+gpg_err_code_t -+_gcry_drbg_reinit (u_int32_t flags, struct drbg_string *pers, -+ struct drbg_test_data *test_data) -+{ -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ dbg (("DRBG: reinitialize internal DRBG state with flags %u\n", flags)); -+ drbg_lock (); -+ gcry_drbg->test_data = test_data; -+ ret = _gcry_drbg_init_internal (1, flags, pers); -+ drbg_unlock (); -+ return ret; -+} -+ -+/* Try to close the FDs of the random gather module. This is -+ * currently only implemented for rndlinux. */ -+void -+_gcry_drbg_close_fds (void) -+{ -+#if USE_RNDLINUX -+ drbg_lock (); -+ _gcry_rndlinux_gather_random (NULL, 0, 0, 0); -+ drbg_unlock (); -+#endif -+} -+ -+/* Print some statistics about the RNG. */ -+void -+_gcry_drbg_dump_stats (void) -+{ -+ /* Not yet implemented. */ -+ /* Maybe dumping of reseed counter? */ -+} -+ -+/* This function returns true if no real RNG is available or the -+ * quality of the RNG has been degraded for test purposes. */ -+int -+_gcry_drbg_is_faked (void) -+{ -+ return 0; /* Faked random is not allowed. */ -+} -+ -+/* Add BUFLEN bytes from BUF to the internal random pool. QUALITY -+ * should be in the range of 0..100 to indicate the goodness of the -+ * entropy added, or -1 for goodness not known. */ -+gcry_error_t -+_gcry_drng_add_bytes (const void *buf, size_t buflen, int quality) -+{ -+ gpg_err_code_t ret = 0; -+ struct drbg_string seed; -+ (void) quality; -+ if (NULL == gcry_drbg) -+ return GPG_ERR_GENERAL; -+ drbg_string_fill (&seed, (unsigned char *) buf, buflen); -+ drbg_lock (); -+ ret = drbg_reseed (gcry_drbg, &seed); -+ drbg_unlock (); -+ return ret; -+} -+ -+/* This function is to be used for all types of random numbers, including -+ * nonces -+ */ -+void -+_gcry_drbg_randomize (void *buffer, size_t length, -+ enum gcry_random_level level) -+{ -+ (void) level; -+ drbg_lock (); -+ if (NULL == gcry_drbg) -+ { -+ fips_signal_error ("DRBG is not initialized"); -+ goto bailout; -+ } -+ -+ /* As reseeding changes the entire state of the DRBG, including any -+ * key, either a re-init or a reseed is sufficient for a fork */ -+ if (gcry_drbg->seed_init_pid != getpid ()) -+ { -+ /* We are in a child of us. Perform a reseeding. */ -+ if (drbg_reseed (gcry_drbg, NULL)) -+ { -+ fips_signal_error ("reseeding upon fork failed"); -+ log_fatal ("severe error getting random\n"); -+ goto bailout; -+ } -+ } -+ /* potential integer overflow is covered by drbg_generate which -+ * ensures that length cannot overflow an unsigned int */ -+ if (0 < length) -+ { -+ if (!buffer) -+ goto bailout; -+ if (drbg_generate_long (gcry_drbg, buffer, (unsigned int) length, NULL)) -+ log_fatal ("No random numbers generated\n"); -+ } -+ else -+ { -+ struct drbg_gen *data = (struct drbg_gen *) buffer; -+ /* catch NULL pointer */ -+ if (!data || !data->outbuf) -+ { -+ fips_signal_error ("No output buffer provided"); -+ goto bailout; -+ } -+ gcry_drbg->test_data = data->test_data; -+ if (drbg_generate_long (gcry_drbg, data->outbuf, data->outlen, -+ data->addtl)) -+ log_fatal ("No random numbers generated\n"); -+ } -+bailout: -+ drbg_unlock (); -+ return; -+ -+} -+ -+/*************************************************************** -+ * Self-test code -+ ***************************************************************/ -+ -+/* -+ * Test vectors from -+ * http://csrc.nist.gov/groups/STM/cavp/documents/drbg/drbgtestvectors.zip -+ */ -+ -+struct drbg_test_vector -+{ -+ u_int32_t flags; -+ unsigned char *entropy; -+ size_t entropylen; -+ unsigned char *entpra; -+ unsigned char *entprb; -+ size_t entprlen; -+ unsigned char *addtla; -+ unsigned char *addtlb; -+ size_t addtllen; -+ unsigned char *pers; -+ size_t perslen; -+ unsigned char *expected; -+ size_t expectedlen; -+}; -+ -+struct drbg_test_vector drbg_test_pr[] = { -+ { -+ .flags = (DRBG_PR_HASHSHA256), -+ .entropy = (unsigned char *) -+ "\x5d\xf2\x14\xbc\xf6\xb5\x4e\x0b\xf0\x0d\x6f\x2d" -+ "\xe2\x01\x66\x7b\xd0\xa4\x73\xa4\x21\xdd\xb0\xc0" -+ "\x51\x79\x09\xf4\xea\xa9\x08\xfa\xa6\x67\xe0\xe1" -+ "\xd1\x88\xa8\xad\xee\x69\x74\xb3\x55\x06\x9b\xf6", -+ .entropylen = 48, -+ .entpra = (unsigned char *) -+ "\xef\x48\x06\xa2\xc2\x45\xf1\x44\xfa\x34\x2c\xeb" -+ "\x8d\x78\x3c\x09\x8f\x34\x72\x20\xf2\xe7\xfd\x13" -+ "\x76\x0a\xf6\xdc\x3c\xf5\xc0\x15", -+ .entprb = (unsigned char *) -+ "\x4b\xbe\xe5\x24\xed\x6a\x2d\x0c\xdb\x73\x5e\x09" -+ "\xf9\xad\x67\x7c\x51\x47\x8b\x6b\x30\x2a\xc6\xde" -+ "\x76\xaa\x55\x04\x8b\x0a\x72\x95", -+ .entprlen = 32, -+ .expected = (unsigned char *) -+ "\x3b\x14\x71\x99\xa1\xda\xa0\x42\xe6\xc8\x85\x32" -+ "\x70\x20\x32\x53\x9a\xbe\xd1\x1e\x15\xef\xfb\x4c" -+ "\x25\x6e\x19\x3a\xf0\xb9\xcb\xde\xf0\x3b\xc6\x18" -+ "\x4d\x85\x5a\x9b\xf1\xe3\xc2\x23\x03\x93\x08\xdb" -+ "\xa7\x07\x4b\x33\x78\x40\x4d\xeb\x24\xf5\x6e\x81" -+ "\x4a\x1b\x6e\xa3\x94\x52\x43\xb0\xaf\x2e\x21\xf4" -+ "\x42\x46\x8e\x90\xed\x34\x21\x75\xea\xda\x67\xb6" -+ "\xe4\xf6\xff\xc6\x31\x6c\x9a\x5a\xdb\xb3\x97\x13" -+ "\x09\xd3\x20\x98\x33\x2d\x6d\xd7\xb5\x6a\xa8\xa9" -+ "\x9a\x5b\xd6\x87\x52\xa1\x89\x2b\x4b\x9c\x64\x60" -+ "\x50\x47\xa3\x63\x81\x16\xaf\x19", -+ .expectedlen = 128, -+ .addtla = (unsigned char *) -+ "\xbe\x13\xdb\x2a\xe9\xa8\xfe\x09\x97\xe1\xce\x5d" -+ "\xe8\xbb\xc0\x7c\x4f\xcb\x62\x19\x3f\x0f\xd2\xad" -+ "\xa9\xd0\x1d\x59\x02\xc4\xff\x70", -+ .addtlb = (unsigned char *) -+ "\x6f\x96\x13\xe2\xa7\xf5\x6c\xfe\xdf\x66\xe3\x31" -+ "\x63\x76\xbf\x20\x27\x06\x49\xf1\xf3\x01\x77\x41" -+ "\x9f\xeb\xe4\x38\xfe\x67\x00\xcd", -+ .addtllen = 32, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = (DRBG_PR_HMACSHA256), -+ .entropy = (unsigned char *) -+ "\x13\x54\x96\xfc\x1b\x7d\x28\xf3\x18\xc9\xa7\x89" -+ "\xb6\xb3\xc8\x72\xac\x00\xd4\x59\x36\x25\x05\xaf" -+ "\xa5\xdb\x96\xcb\x3c\x58\x46\x87\xa5\xaa\xbf\x20" -+ "\x3b\xfe\x23\x0e\xd1\xc7\x41\x0f\x3f\xc9\xb3\x67", -+ .entropylen = 48, -+ .entpra = (unsigned char *) -+ "\xe2\xbd\xb7\x48\x08\x06\xf3\xe1\x93\x3c\xac\x79" -+ "\xa7\x2b\x11\xda\xe3\x2e\xe1\x91\xa5\x02\x19\x57" -+ "\x20\x28\xad\xf2\x60\xd7\xcd\x45", -+ .entprb = (unsigned char *) -+ "\x8b\xd4\x69\xfc\xff\x59\x95\x95\xc6\x51\xde\x71" -+ "\x68\x5f\xfc\xf9\x4a\xab\xec\x5a\xcb\xbe\xd3\x66" -+ "\x1f\xfa\x74\xd3\xac\xa6\x74\x60", -+ .entprlen = 32, -+ .expected = (unsigned char *) -+ "\x1f\x9e\xaf\xe4\xd2\x46\xb7\x47\x41\x4c\x65\x99" -+ "\x01\xe9\x3b\xbb\x83\x0c\x0a\xb0\xc1\x3a\xe2\xb3" -+ "\x31\x4e\xeb\x93\x73\xee\x0b\x26\xc2\x63\xa5\x75" -+ "\x45\x99\xd4\x5c\x9f\xa1\xd4\x45\x87\x6b\x20\x61" -+ "\x40\xea\x78\xa5\x32\xdf\x9e\x66\x17\xaf\xb1\x88" -+ "\x9e\x2e\x23\xdd\xc1\xda\x13\x97\x88\xa5\xb6\x5e" -+ "\x90\x14\x4e\xef\x13\xab\x5c\xd9\x2c\x97\x9e\x7c" -+ "\xd7\xf8\xce\xea\x81\xf5\xcd\x71\x15\x49\x44\xce" -+ "\x83\xb6\x05\xfb\x7d\x30\xb5\x57\x2c\x31\x4f\xfc" -+ "\xfe\x80\xb6\xc0\x13\x0c\x5b\x9b\x2e\x8f\x3d\xfc" -+ "\xc2\xa3\x0c\x11\x1b\x80\x5f\xf3", -+ .expectedlen = 128, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = (unsigned char *) -+ "\x64\xb6\xfc\x60\xbc\x61\x76\x23\x6d\x3f\x4a\x0f" -+ "\xe1\xb4\xd5\x20\x9e\x70\xdd\x03\x53\x6d\xbf\xce" -+ "\xcd\x56\x80\xbc\xb8\x15\xc8\xaa", -+ .perslen = 32, -+ }, -+ { -+ .flags = (DRBG_PR_CTRAES128), -+ .entropy = (unsigned char *) -+ "\x92\x89\x8f\x31\xfa\x1c\xff\x6d\x18\x2f\x26\x06" -+ "\x43\xdf\xf8\x18\xc2\xa4\xd9\x72\xc3\xb9\xb6\x97", -+ .entropylen = 24, -+ .entpra = (unsigned char *) -+ "\x20\x72\x8a\x06\xf8\x6f\x8d\xd4\x41\xe2\x72\xb7" -+ "\xc4\x2c\xe8\x10", -+ .entprb = (unsigned char *) -+ "\x3d\xb0\xf0\x94\xf3\x05\x50\x33\x17\x86\x3e\x22" -+ "\x08\xf7\xa5\x01", -+ .entprlen = 16, -+ .expected = (unsigned char *) -+ "\x5a\x35\x39\x87\x0f\x4d\x22\xa4\x09\x24\xee\x71" -+ "\xc9\x6f\xac\x72\x0a\xd6\xf0\x88\x82\xd0\x83\x28" -+ "\x73\xec\x3f\x93\xd8\xab\x45\x23\xf0\x7e\xac\x45" -+ "\x14\x5e\x93\x9f\xb1\xd6\x76\x43\x3d\xb6\xe8\x08" -+ "\x88\xf6\xda\x89\x08\x77\x42\xfe\x1a\xf4\x3f\xc4" -+ "\x23\xc5\x1f\x68", -+ .expectedlen = 64, -+ .addtla = (unsigned char *) -+ "\x1a\x40\xfa\xe3\xcc\x6c\x7c\xa0\xf8\xda\xba\x59" -+ "\x23\x6d\xad\x1d", -+ .addtlb = (unsigned char *) -+ "\x9f\x72\x76\x6c\xc7\x46\xe5\xed\x2e\x53\x20\x12" -+ "\xbc\x59\x31\x8c", -+ .addtllen = 16, -+ .pers = (unsigned char *) -+ "\xea\x65\xee\x60\x26\x4e\x7e\xb6\x0e\x82\x68\xc4" -+ "\x37\x3c\x5c\x0b", -+ .perslen = 16, -+ }, -+}; -+ -+struct drbg_test_vector drbg_test_nopr[] = { -+ { -+ .flags = DRBG_NOPR_HASHSHA256, -+ .entropy = (unsigned char *) -+ "\x73\xd3\xfb\xa3\x94\x5f\x2b\x5f\xb9\x8f\xf6\x9c" -+ "\x8a\x93\x17\xae\x19\xc3\x4c\xc3\xd6\xca\xa3\x2d" -+ "\x16\xfc\x42\xd2\x2d\xd5\x6f\x56\xcc\x1d\x30\xff" -+ "\x9e\x06\x3e\x09\xce\x58\xe6\x9a\x35\xb3\xa6\x56", -+ .entropylen = 48, -+ .expected = (unsigned char *) -+ "\x71\x7b\x93\x46\x1a\x40\xaa\x35\xa4\xaa\xc5\xe7" -+ "\x6d\x5b\x5b\x8a\xa0\xdf\x39\x7d\xae\x71\x58\x5b" -+ "\x3c\x7c\xb4\xf0\x89\xfa\x4a\x8c\xa9\x5c\x54\xc0" -+ "\x40\xdf\xbc\xce\x26\x81\x34\xf8\xba\x7d\x1c\xe8" -+ "\xad\x21\xe0\x74\xcf\x48\x84\x30\x1f\xa1\xd5\x4f" -+ "\x81\x42\x2f\xf4\xdb\x0b\x23\xf8\x73\x27\xb8\x1d" -+ "\x42\xf8\x44\x58\xd8\x5b\x29\x27\x0a\xf8\x69\x59" -+ "\xb5\x78\x44\xeb\x9e\xe0\x68\x6f\x42\x9a\xb0\x5b" -+ "\xe0\x4e\xcb\x6a\xaa\xe2\xd2\xd5\x33\x25\x3e\xe0" -+ "\x6c\xc7\x6a\x07\xa5\x03\x83\x9f\xe2\x8b\xd1\x1c" -+ "\x70\xa8\x07\x59\x97\xeb\xf6\xbe", -+ .expectedlen = 128, -+ .addtla = (unsigned char *) -+ "\xf4\xd5\x98\x3d\xa8\xfc\xfa\x37\xb7\x54\x67\x73" -+ "\xc7\xc3\xdd\x47\x34\x71\x02\x5d\xc1\xa0\xd3\x10" -+ "\xc1\x8b\xbd\xf5\x66\x34\x6f\xdd", -+ .addtlb = (unsigned char *) -+ "\xf7\x9e\x6a\x56\x0e\x73\xe9\xd9\x7a\xd1\x69\xe0" -+ "\x6f\x8c\x55\x1c\x44\xd1\xce\x6f\x28\xcc\xa4\x4d" -+ "\xa8\xc0\x85\xd1\x5a\x0c\x59\x40", -+ .addtllen = 32, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = DRBG_NOPR_HMACSHA256, -+ .entropy = (unsigned char *) -+ "\x8d\xf0\x13\xb4\xd1\x03\x52\x30\x73\x91\x7d\xdf" -+ "\x6a\x86\x97\x93\x05\x9e\x99\x43\xfc\x86\x54\x54" -+ "\x9e\x7a\xb2\x2f\x7c\x29\xf1\x22\xda\x26\x25\xaf" -+ "\x2d\xdd\x4a\xbc\xce\x3c\xf4\xfa\x46\x59\xd8\x4e", -+ .entropylen = 48, -+ .expected = (unsigned char *) -+ "\xb9\x1c\xba\x4c\xc8\x4f\xa2\x5d\xf8\x61\x0b\x81" -+ "\xb6\x41\x40\x27\x68\xa2\x09\x72\x34\x93\x2e\x37" -+ "\xd5\x90\xb1\x15\x4c\xbd\x23\xf9\x74\x52\xe3\x10" -+ "\xe2\x91\xc4\x51\x46\x14\x7f\x0d\xa2\xd8\x17\x61" -+ "\xfe\x90\xfb\xa6\x4f\x94\x41\x9c\x0f\x66\x2b\x28" -+ "\xc1\xed\x94\xda\x48\x7b\xb7\xe7\x3e\xec\x79\x8f" -+ "\xbc\xf9\x81\xb7\x91\xd1\xbe\x4f\x17\x7a\x89\x07" -+ "\xaa\x3c\x40\x16\x43\xa5\xb6\x2b\x87\xb8\x9d\x66" -+ "\xb3\xa6\x0e\x40\xd4\xa8\xe4\xe9\xd8\x2a\xf6\xd2" -+ "\x70\x0e\x6f\x53\x5c\xdb\x51\xf7\x5c\x32\x17\x29" -+ "\x10\x37\x41\x03\x0c\xcc\x3a\x56", -+ .expectedlen = 128, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = (unsigned char *) -+ "\xb5\x71\xe6\x6d\x7c\x33\x8b\xc0\x7b\x76\xad\x37" -+ "\x57\xbb\x2f\x94\x52\xbf\x7e\x07\x43\x7a\xe8\x58" -+ "\x1c\xe7\xbc\x7c\x3a\xc6\x51\xa9", -+ .perslen = 32, -+ }, -+ { -+ .flags = DRBG_NOPR_CTRAES128, -+ .entropy = (unsigned char *) -+ "\xc0\x70\x1f\x92\x50\x75\x8f\xcd\xf2\xbe\x73\x98" -+ "\x80\xdb\x66\xeb\x14\x68\xb4\xa5\x87\x9c\x2d\xa6", -+ .entropylen = 24, -+ .expected = (unsigned char *) -+ "\x97\xc0\xc0\xe5\xa0\xcc\xf2\x4f\x33\x63\x48\x8a" -+ "\xdb\x13\x0a\x35\x89\xbf\x80\x65\x62\xee\x13\x95" -+ "\x7c\x33\xd3\x7d\xf4\x07\x77\x7a\x2b\x65\x0b\x5f" -+ "\x45\x5c\x13\xf1\x90\x77\x7f\xc5\x04\x3f\xcc\x1a" -+ "\x38\xf8\xcd\x1b\xbb\xd5\x57\xd1\x4a\x4c\x2e\x8a" -+ "\x2b\x49\x1e\x5c", -+ .expectedlen = 64, -+ .addtla = (unsigned char *) -+ "\xf9\x01\xf8\x16\x7a\x1d\xff\xde\x8e\x3c\x83\xe2" -+ "\x44\x85\xe7\xfe", -+ .addtlb = (unsigned char *) -+ "\x17\x1c\x09\x38\xc2\x38\x9f\x97\x87\x60\x55\xb4" -+ "\x82\x16\x62\x7f", -+ .addtllen = 16, -+ .pers = (unsigned char *) -+ "\x80\x08\xae\xe8\xe9\x69\x40\xc5\x08\x73\xc7\x9f" -+ "\x8e\xcf\xe0\x02", -+ .perslen = 16, -+ }, -+}; -+ -+ -+/* -+ * Tests implement the CAVS test approach as documented in -+ * http://csrc.nist.gov/groups/STM/cavp/documents/drbg/DRBGVS.pdf -+ */ -+ -+/* -+ * CAVS test -+ */ -+static gpg_err_code_t -+drbg_healthcheck_one (struct drbg_test_vector *test) -+{ -+ gpg_err_code_t ret = GPG_ERR_ENOMEM; -+ struct drbg_state *drbg = NULL; -+ struct drbg_test_data test_data; -+ struct drbg_string addtl, pers, testentropy; -+ int coreref = 0; -+ int pr = 0; -+ unsigned char *buf = drbg_malloc (test->expectedlen); -+ -+ if (!buf) -+ return GPG_ERR_ENOMEM; -+ ret = drbg_algo_available (test->flags, &coreref); -+ if (ret) -+ goto outbuf; -+ -+ drbg = drbg_malloc (sizeof (struct drbg_state)); -+ if (!drbg) -+ goto outbuf; -+ -+ if (test->flags & DRBG_PREDICTION_RESIST) -+ pr = 1; -+ -+ test_data.testentropy = &testentropy; -+ drbg_string_fill (&testentropy, test->entropy, test->entropylen); -+ drbg->test_data = &test_data; -+ drbg_string_fill (&pers, test->pers, test->perslen); -+ ret = drbg_instantiate (drbg, &pers, coreref, pr); -+ if (ret) -+ goto outbuf; -+ -+ drbg_string_fill (&addtl, test->addtla, test->addtllen); -+ if (test->entpra) -+ { -+ drbg_string_fill (&testentropy, test->entpra, test->entprlen); -+ drbg->test_data = &test_data; -+ } -+ drbg_generate_long (drbg, buf, test->expectedlen, &addtl); -+ -+ drbg_string_fill (&addtl, test->addtlb, test->addtllen); -+ if (test->entprb) -+ { -+ drbg_string_fill (&testentropy, test->entprb, test->entprlen); -+ drbg->test_data = &test_data; -+ } -+ drbg_generate_long (drbg, buf, test->expectedlen, &addtl); -+ -+ ret = memcmp (test->expected, buf, test->expectedlen); -+ -+ drbg_uninstantiate (drbg); -+outbuf: -+ xfree (buf); -+ if (drbg) -+ xfree (drbg); -+ return ret; -+} -+ -+/* -+ * Tests as defined in 11.3.2 in addition to the cipher tests: testing -+ * of the error handling. -+ * -+ * Note, testing the reseed counter is not done as an automatic reseeding -+ * is performed in drbg_generate when the reseed counter is too large. -+ */ -+static gpg_err_code_t -+drbg_healthcheck_sanity (struct drbg_test_vector *test) -+{ -+ unsigned int len = 0; -+ struct drbg_state *drbg = NULL; -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ gpg_err_code_t tmpret = GPG_ERR_GENERAL; -+ struct drbg_test_data test_data; -+ struct drbg_string addtl, testentropy; -+ int coreref = 0; -+ unsigned char *buf = NULL; -+ size_t max_addtllen, max_request_bytes; -+ -+ /* only perform test in FIPS mode */ -+ if (0 == fips_mode ()) -+ return 0; -+ -+ buf = drbg_malloc (test->expectedlen); -+ if (!buf) -+ return GPG_ERR_ENOMEM; -+ tmpret = drbg_algo_available (test->flags, &coreref); -+ if (tmpret) -+ goto outbuf; -+ drbg = drbg_malloc (sizeof (struct drbg_state)); -+ if (!drbg) -+ goto outbuf; -+ -+ /* if the following tests fail, it is likely that there is a buffer -+ * overflow and we get a SIGSEV */ -+ ret = drbg_instantiate (drbg, NULL, coreref, 1); -+ if (ret) -+ goto outbuf; -+ max_addtllen = drbg_max_addtl (); -+ max_request_bytes = drbg_max_request_bytes (); -+ /* overflow addtllen with additonal info string */ -+ drbg_string_fill (&addtl, test->addtla, (max_addtllen + 1)); -+ len = drbg_generate (drbg, buf, test->expectedlen, &addtl); -+ if (len) -+ goto outdrbg; -+ -+ /* overflow max_bits */ -+ len = drbg_generate (drbg, buf, (max_request_bytes + 1), NULL); -+ if (len) -+ goto outdrbg; -+ drbg_uninstantiate (drbg); -+ -+ /* test failing entropy source as defined in 11.3.2 */ -+ test_data.testentropy = NULL; -+ test_data.fail_seed_source = 1; -+ drbg->test_data = &test_data; -+ tmpret = drbg_instantiate (drbg, NULL, coreref, 0); -+ if (!tmpret) -+ goto outdrbg; -+ test_data.fail_seed_source = 0; -+ -+ test_data.testentropy = &testentropy; -+ drbg_string_fill (&testentropy, test->entropy, test->entropylen); -+ /* overflow max addtllen with personalization string */ -+ tmpret = drbg_instantiate (drbg, &addtl, coreref, 0); -+ if (!tmpret) -+ goto outdrbg; -+ -+ /* test uninstantated DRBG */ -+ len = drbg_generate (drbg, buf, (max_request_bytes + 1), NULL); -+ if (len) -+ goto outbuf; -+ -+ dbg (("DRBG: Sanity tests for failure code paths successfully completed\n")); -+ ret = 0; -+ -+outdrbg: -+ drbg_uninstantiate (drbg); -+outbuf: -+ xfree (buf); -+ if (drbg) -+ xfree (drbg); -+ return ret; -+} -+ -+/* -+ * DRBG Healthcheck function as required in SP800-90A -+ * -+ * return: -+ * 0 on success (all tests pass) -+ * >0 on error (return code indicate the number of failures) -+ */ -+int -+drbg_healthcheck (void) -+{ -+ int ret = 0; -+ ret += drbg_healthcheck_one (&drbg_test_nopr[0]); -+ ret += drbg_healthcheck_one (&drbg_test_nopr[1]); -+ ret += drbg_healthcheck_one (&drbg_test_nopr[2]); -+ ret += drbg_healthcheck_one (&drbg_test_pr[0]); -+ ret += drbg_healthcheck_one (&drbg_test_pr[1]); -+ ret += drbg_healthcheck_one (&drbg_test_pr[2]); -+ ret += drbg_healthcheck_sanity (&drbg_test_nopr[0]); -+ return ret; -+} -+ -+/* Run the self-tests. */ -+gcry_error_t -+_gcry_drbg_selftest (selftest_report_func_t report) -+{ -+ gcry_err_code_t ec; -+ const char *errtxt = NULL; -+ drbg_lock (); -+ if (0 != drbg_healthcheck ()) -+ errtxt = "RNG output does not match known value"; -+ drbg_unlock (); -+ if (report && errtxt) -+ report ("random", 0, "KAT", errtxt); -+ ec = errtxt ? GPG_ERR_SELFTEST_FAILED : 0; -+ return gpg_error (ec); -+} -+ -+/*************************************************************** -+ * Cipher invocations requested by DRBG -+ ***************************************************************/ -+ -+static gpg_err_code_t -+drbg_gcry_hmac (struct drbg_state *drbg, const unsigned char *key, -+ unsigned char *outval, const struct drbg_string *buf) -+{ -+ gpg_error_t err; -+ gcry_md_hd_t hd; -+ -+ if (key) -+ { -+ err = _gcry_md_open (&hd, drbg->core->backend_cipher, GCRY_MD_FLAG_HMAC); -+ if (err) -+ return err; -+ err = _gcry_md_setkey (hd, key, drbg_statelen (drbg)); -+ if (err) -+ return err; -+ } -+ else -+ { -+ err = _gcry_md_open (&hd, drbg->core->backend_cipher, 0); -+ if (err) -+ return err; -+ } -+ for (; NULL != buf; buf = buf->next) -+ _gcry_md_write (hd, buf->buf, buf->len); -+ _gcry_md_final (hd); -+ memcpy (outval, _gcry_md_read (hd, drbg->core->backend_cipher), -+ drbg_blocklen (drbg)); -+ _gcry_md_close (hd); -+ return 0; -+} -+ -+static gpg_err_code_t -+drbg_gcry_sym (struct drbg_state *drbg, const unsigned char *key, -+ unsigned char *outval, const struct drbg_string *buf) -+{ -+ gpg_error_t err; -+ gcry_cipher_hd_t hd; -+ -+ err = -+ _gcry_cipher_open (&hd, drbg->core->backend_cipher, GCRY_CIPHER_MODE_ECB, -+ 0); -+ if (err) -+ return err; -+ if (drbg_blocklen (drbg) != -+ _gcry_cipher_get_algo_blklen (drbg->core->backend_cipher)) -+ return -GPG_ERR_NO_ERROR; -+ if (drbg_blocklen (drbg) < buf->len) -+ return -GPG_ERR_NO_ERROR; -+ err = _gcry_cipher_setkey (hd, key, drbg_keylen (drbg)); -+ if (err) -+ return err; -+ /* in is only component */ -+ _gcry_cipher_encrypt (hd, outval, drbg_blocklen (drbg), buf->buf, buf->len); -+ _gcry_cipher_close (hd); -+ return 0; -+} --- -1.9.3 - diff --git a/v9-0007-User-interface-to-DRBG.patch b/v9-0007-User-interface-to-DRBG.patch deleted file mode 100644 index fedee59..0000000 --- a/v9-0007-User-interface-to-DRBG.patch +++ /dev/null @@ -1,309 +0,0 @@ -From 581c850aa7ac63086a489480efa4cc0bf8cfd510 Mon Sep 17 00:00:00 2001 -From: Stephan Mueller -Date: Thu, 21 Aug 2014 21:26:27 +0200 -Subject: [PATCH v9 7/7] User interface to DRBG - -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); - -Signed-off-by: Stephan Mueller ---- - src/gcrypt.h.in | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 144 insertions(+), 13 deletions(-) - -Index: libgcrypt-1.6.1/src/gcrypt.h.in -=================================================================== ---- libgcrypt-1.6.1.orig/src/gcrypt.h.in 2014-01-29 10:49:05.000000000 +0100 -+++ libgcrypt-1.6.1/src/gcrypt.h.in 2014-09-02 13:45:42.439648231 +0200 -@@ -193,7 +193,7 @@ gcry_error_t gcry_err_make_from_errno (g - /* 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,7 +329,8 @@ 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 = 74, - }; - - /* Perform various operations defined by CMD. */ -@@ -477,7 +478,7 @@ gpg_error_t gcry_sexp_extract_param (gcr - 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 - #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, - 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, con - #define gcry_md_get_asnoid(a,b,n) \ - gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n)) - -- -+ - - /********************************************** - * * -@@ -1407,7 +1408,7 @@ int gcry_mac_map_name (const char *name) - #define gcry_mac_test_algo(a) \ - gcry_mac_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) - -- -+ - /****************************** - * * - * Key Derivation Functions * -@@ -1435,7 +1436,7 @@ gpg_error_t gcry_kdf_derive (const void - - - -- -+ - /************************************ - * * - * Random Generating Functions * -@@ -1504,7 +1505,7 @@ void gcry_create_nonce (void *buffer, si - - - -- -+ - /*******************************/ - /* */ - /* Prime Number Functions */ -@@ -1563,7 +1564,7 @@ void gcry_prime_release_factors (gcry_mp - gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags); - - -- -+ - /************************************ - * * - * Miscellaneous Stuff * -@@ -1668,6 +1669,136 @@ int gcry_is_secure (const void *a) _GCRY - /* 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 = (unsigned char *)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 = (unsigned char *)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.) */ - {