diff --git a/0001-SP800-90A-Deterministic-Random-Bit-Generator.patch.bz2 b/0001-SP800-90A-Deterministic-Random-Bit-Generator.patch.bz2 new file mode 100644 index 0000000..6bc7af4 --- /dev/null +++ b/0001-SP800-90A-Deterministic-Random-Bit-Generator.patch.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfa2d8bbd979682e3e33455481daeec820fd02b556bdfa8a69a890f20ab9cea1 +size 16119 diff --git a/0002-Compile-DRBG.patch b/0002-Compile-DRBG.patch new file mode 100644 index 0000000..8f03a5c --- /dev/null +++ b/0002-Compile-DRBG.patch @@ -0,0 +1,23 @@ +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 new file mode 100644 index 0000000..472ffc8 --- /dev/null +++ b/0003-Function-definitions-of-interfaces-for-random.c.patch @@ -0,0 +1,32 @@ +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 new file mode 100644 index 0000000..05e3dbc --- /dev/null +++ b/0004-Invoke-DRBG-from-common-libgcrypt-RNG-code.patch @@ -0,0 +1,132 @@ +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 new file mode 100644 index 0000000..ffb0a44 --- /dev/null +++ b/0005-Function-definitions-for-gcry_control-callbacks.patch @@ -0,0 +1,31 @@ +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 new file mode 100644 index 0000000..02ba7ea --- /dev/null +++ b/0006-DRBG-specific-gcry_control-requests.patch @@ -0,0 +1,63 @@ +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/0007-User-interface-to-DRBG.patch b/0007-User-interface-to-DRBG.patch new file mode 100644 index 0000000..4018e48 --- /dev/null +++ b/0007-User-interface-to-DRBG.patch @@ -0,0 +1,272 @@ +Changes v4: + + * add fail_seed_source to struct drbg_test_data + +Signed-off-by: Stephan Mueller +--- +diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in +index c84a3f7..2a17dcd 100644 +--- a/src/gcrypt.h.in ++++ b/src/gcrypt.h.in +@@ -193,7 +193,7 @@ gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err); + /* Return an error value with the system error ERR. */ + gcry_err_code_t gcry_error_from_errno (int err); + +- ++ + /* NOTE: Since Libgcrypt 1.6 the thread callbacks are not anymore + used. However we keep it to allow for some source code + compatibility if used in the standard way. */ +@@ -228,7 +228,7 @@ struct gcry_thread_cbs + (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8))} + + +- ++ + /* A generic context object as used by some functions. */ + struct gcry_context; + typedef struct gcry_context *gcry_ctx_t; +@@ -254,7 +254,7 @@ typedef struct + } gcry_buffer_t; + + +- ++ + + /* Check that the library fulfills the version requirement. */ + const char *gcry_check_version (const char *req_version); +@@ -329,13 +329,14 @@ enum gcry_ctl_cmds + GCRYCTL_SET_CCM_LENGTHS = 69, + GCRYCTL_CLOSE_RANDOM_DEVICE = 70, + GCRYCTL_INACTIVATE_FIPS_FLAG = 71, +- GCRYCTL_REACTIVATE_FIPS_FLAG = 72 ++ GCRYCTL_REACTIVATE_FIPS_FLAG = 72, ++ GCRYCTL_DRBG_REINIT = 73, + }; + + /* Perform various operations defined by CMD. */ + gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...); + +- ++ + /* S-expression management. */ + + /* The object to represent an S-expression as used with the public key +@@ -477,7 +478,7 @@ gpg_error_t gcry_sexp_extract_param (gcry_sexp_t sexp, + const char *list, + ...) _GCRY_GCC_ATTR_SENTINEL(0); + +- ++ + /******************************************* + * * + * Multi Precision Integer Functions * +@@ -833,7 +834,7 @@ gcry_mpi_t _gcry_mpi_get_const (int no); + #endif /* GCRYPT_NO_MPI_MACROS */ + + +- ++ + /************************************ + * * + * Symmetric Cipher Functions * +@@ -1015,7 +1016,7 @@ size_t gcry_cipher_get_algo_blklen (int algo); + #define gcry_cipher_test_algo(a) \ + gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) + +- ++ + /************************************ + * * + * Asymmetric Cipher Functions * +@@ -1114,7 +1115,7 @@ gcry_sexp_t gcry_pk_get_param (int algo, const char *name); + gcry_error_t gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp, + int mode, gcry_ctx_t ctx); + +- ++ + + /************************************ + * * +@@ -1291,7 +1292,7 @@ void gcry_md_debug (gcry_md_hd_t hd, const char *suffix); + #define gcry_md_get_asnoid(a,b,n) \ + gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n)) + +- ++ + + /********************************************** + * * +@@ -1411,7 +1412,7 @@ int gcry_mac_map_name (const char *name) _GCRY_GCC_ATTR_PURE; + #define gcry_mac_test_algo(a) \ + gcry_mac_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) + +- ++ + /****************************** + * * + * Key Derivation Functions * +@@ -1439,7 +1440,7 @@ gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen, + + + +- ++ + /************************************ + * * + * Random Generating Functions * +@@ -1508,7 +1509,7 @@ void gcry_create_nonce (void *buffer, size_t length); + + + +- ++ + /*******************************/ + /* */ + /* Prime Number Functions */ +@@ -1567,7 +1568,7 @@ void gcry_prime_release_factors (gcry_mpi_t *factors); + gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags); + + +- ++ + /************************************ + * * + * Miscellaneous Stuff * +@@ -1672,6 +1673,136 @@ int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE; + /* Return true if Libgcrypt is in FIPS mode. */ + #define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) + ++/* DRBG test data */ ++struct drbg_test_data { ++ struct drbg_string *testentropy; /* TEST PARAMETER: test entropy */ ++ int fail_seed_source:1; /* if set, the seed function will return an ++ * error */ ++}; ++ ++/* DRBG input data structure for DRBG generate with additional information ++ * string */ ++struct drbg_gen { ++ unsigned char *outbuf; /* output buffer for random numbers */ ++ unsigned int outlen; /* size of output buffer */ ++ struct drbg_string *addtl; /* input buffer for ++ * additional information string */ ++ struct drbg_test_data *test_data; /* test data */ ++}; ++ ++/* ++ * Concatenation Helper and string operation helper ++ * ++ * SP800-90A requires the concatenation of different data. To avoid copying ++ * buffers around or allocate additional memory, the following data structure ++ * is used to point to the original memory with its size. In addition, it ++ * is used to build a linked list. The linked list defines the concatenation ++ * of individual buffers. The order of memory block referenced in that ++ * linked list determines the order of concatenation. ++ */ ++/* DRBG string definition */ ++struct drbg_string { ++ const unsigned char *buf; ++ size_t len; ++ struct drbg_string *next; ++}; ++ ++static inline void drbg_string_fill(struct drbg_string *string, ++ const unsigned char *buf, size_t len) ++{ ++ string->buf = buf; ++ string->len = len; ++ string->next = NULL; ++} ++ ++/* this is a wrapper function for users of libgcrypt */ ++static inline void gcry_randomize_drbg(void *outbuf, size_t outlen, ++ enum gcry_random_level level, ++ struct drbg_string *addtl) ++{ ++ struct drbg_gen genbuf; ++ genbuf.outbuf = outbuf; ++ genbuf.outlen = outlen; ++ genbuf.addtl = addtl; ++ genbuf.test_data = NULL; ++ gcry_randomize(&genbuf, 0, level); ++} ++ ++/* this is a wrapper function for users of libgcrypt */ ++static inline void gcry_randomize_drbg_test(void *outbuf, size_t outlen, ++ enum gcry_random_level level, ++ struct drbg_string *addtl, ++ struct drbg_test_data *test_data) ++{ ++ struct drbg_gen genbuf; ++ genbuf.outbuf = outbuf; ++ genbuf.outlen = outlen; ++ genbuf.addtl = addtl; ++ genbuf.test_data = test_data; ++ gcry_randomize(&genbuf, 0, level); ++} ++ ++ ++/* ++ * DRBG flags bitmasks ++ * ++ * 31 (B) 28 19 (A) 0 ++ * +-+-+-+--------+---+-----------+-----+ ++ * |~|~|u|~~~~~~~~| 3 | 2 | 1 | ++ * +-+-+-+--------+- -+-----------+-----+ ++ * ctl flg| |drbg use selection flags ++ * ++ */ ++ ++/* internal state control flags (B) */ ++#define DRBG_PREDICTION_RESIST ((u_int32_t)1<<28) ++ ++/* CTR type modifiers (A.1)*/ ++#define DRBG_CTRAES ((u_int32_t)1<<0) ++#define DRBG_CTRSERPENT ((u_int32_t)1<<1) ++#define DRBG_CTRTWOFISH ((u_int32_t)1<<2) ++#define DRBG_CTR_MASK (DRBG_CTRAES | DRBG_CTRSERPENT | DRBG_CTRTWOFISH) ++ ++/* HASH type modifiers (A.2)*/ ++#define DRBG_HASHSHA1 ((u_int32_t)1<<4) ++#define DRBG_HASHSHA224 ((u_int32_t)1<<5) ++#define DRBG_HASHSHA256 ((u_int32_t)1<<6) ++#define DRBG_HASHSHA384 ((u_int32_t)1<<7) ++#define DRBG_HASHSHA512 ((u_int32_t)1<<8) ++#define DRBG_HASH_MASK (DRBG_HASHSHA1 | DRBG_HASHSHA224 | \ ++ DRBG_HASHSHA256 | DRBG_HASHSHA384 | \ ++ DRBG_HASHSHA512) ++/* type modifiers (A.3)*/ ++#define DRBG_HMAC ((u_int32_t)1<<12) ++#define DRBG_SYM128 ((u_int32_t)1<<13) ++#define DRBG_SYM192 ((u_int32_t)1<<14) ++#define DRBG_SYM256 ((u_int32_t)1<<15) ++#define DRBG_TYPE_MASK (DRBG_HMAC | DRBG_SYM128 | DRBG_SYM192 | \ ++ DRBG_SYM256) ++#define DRBG_CIPHER_MASK (DRBG_CTR_MASK | DRBG_HASH_MASK | DRBG_TYPE_MASK) ++ ++#define DRBG_PR_CTRAES128 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM128) ++#define DRBG_PR_CTRAES192 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM192) ++#define DRBG_PR_CTRAES256 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM256) ++#define DRBG_NOPR_CTRAES128 (DRBG_CTRAES | DRBG_SYM128) ++#define DRBG_NOPR_CTRAES192 (DRBG_CTRAES | DRBG_SYM192) ++#define DRBG_NOPR_CTRAES256 (DRBG_CTRAES | DRBG_SYM256) ++#define DRBG_PR_HASHSHA1 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA1) ++#define DRBG_PR_HASHSHA256 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA256) ++#define DRBG_PR_HASHSHA384 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA384) ++#define DRBG_PR_HASHSHA512 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA512) ++#define DRBG_NOPR_HASHSHA1 (DRBG_HASHSHA1) ++#define DRBG_NOPR_HASHSHA256 (DRBG_HASHSHA256) ++#define DRBG_NOPR_HASHSHA384 (DRBG_HASHSHA384) ++#define DRBG_NOPR_HASHSHA512 (DRBG_HASHSHA512) ++#define DRBG_PR_HMACSHA1 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA1 | DRBG_HMAC) ++#define DRBG_PR_HMACSHA256 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA256|DRBG_HMAC) ++#define DRBG_PR_HMACSHA384 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA384|DRBG_HMAC) ++#define DRBG_PR_HMACSHA512 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA512|DRBG_HMAC) ++#define DRBG_NOPR_HMACSHA1 (DRBG_HASHSHA1 | DRBG_HMAC) ++#define DRBG_NOPR_HMACSHA256 (DRBG_HASHSHA256 | DRBG_HMAC) ++#define DRBG_NOPR_HMACSHA384 (DRBG_HASHSHA384 | DRBG_HMAC) ++#define DRBG_NOPR_HMACSHA512 (DRBG_HASHSHA512 | DRBG_HMAC) + + #if 0 /* (Keep Emacsens' auto-indent happy.) */ + { diff --git a/libgcrypt-fips-allow-legacy.patch b/libgcrypt-fips-allow-legacy.patch deleted file mode 100644 index 5674710..0000000 --- a/libgcrypt-fips-allow-legacy.patch +++ /dev/null @@ -1,216 +0,0 @@ -diff -urNp libgcrypt-1.5.3.orig/cipher/cipher.c libgcrypt-1.5.3/cipher/cipher.c ---- libgcrypt-1.5.3.orig/cipher/cipher.c 2013-08-14 02:41:07.967316255 +0200 -+++ libgcrypt-1.5.3/cipher/cipher.c 2013-08-14 03:11:19.403611811 +0200 -@@ -293,6 +293,15 @@ dummy_decrypt_stream (void *c, - BUG(); - } - -+/* Re-Register default cipher listing */ -+void -+cipher_reregister_default(void) -+{ -+ ath_mutex_lock (&ciphers_registered_lock); -+ default_ciphers_registered = 0; -+ ath_mutex_unlock (&ciphers_registered_lock); -+} -+ - - /* Internal function. Register all the ciphers included in - CIPHER_TABLE. Note, that this function gets only used by the macro -@@ -316,7 +325,8 @@ cipher_register_default (void) - if (! cipher_table[i].cipher->stdecrypt) - cipher_table[i].cipher->stdecrypt = dummy_decrypt_stream; - -- if ( fips_mode () && !cipher_table[i].fips_allowed ) -+ if ( !_gcry_is_fips_mode_inactive() && -+ fips_mode () && !cipher_table[i].fips_allowed ) - continue; - - err = _gcry_module_add (&ciphers_registered, -diff -urNp libgcrypt-1.5.3.orig/cipher/md.c libgcrypt-1.5.3/cipher/md.c ---- libgcrypt-1.5.3.orig/cipher/md.c 2013-08-14 02:41:07.968316245 +0200 -+++ libgcrypt-1.5.3/cipher/md.c 2013-08-14 03:20:04.269937326 +0200 -@@ -168,7 +168,14 @@ static void md_start_debug ( gcry_md_hd_ - static void md_stop_debug ( gcry_md_hd_t a ); - - -- -+/* Re-Register default digest listing */ -+void -+digest_reregister_default(void) -+{ -+ ath_mutex_lock (&digests_registered_lock); -+ default_digests_registered = 0; -+ ath_mutex_unlock (&digests_registered_lock); -+} - - /* Internal function. Register all the ciphers included in - CIPHER_TABLE. Returns zero on success or an error code. */ -@@ -180,7 +187,8 @@ md_register_default (void) - - for (i = 0; !err && digest_table[i].digest; i++) - { -- if ( fips_mode ()) -+ if ( !_gcry_is_fips_mode_inactive() && -+ fips_mode ()) - { - if (!digest_table[i].fips_allowed) - continue; -diff -urNp libgcrypt-1.5.3.orig/cipher/pubkey.c libgcrypt-1.5.3/cipher/pubkey.c ---- libgcrypt-1.5.3.orig/cipher/pubkey.c 2013-08-14 02:41:07.969316234 +0200 -+++ libgcrypt-1.5.3/cipher/pubkey.c 2013-08-14 03:22:07.227878253 +0200 -@@ -192,6 +192,15 @@ dummy_get_nbits (int algorithm, gcry_mpi - return 0; - } - -+/* Re-Register default digest listing */ -+void -+pk_reregister_default(void) -+{ -+ ath_mutex_lock (&pubkeys_registered_lock); -+ default_pubkeys_registered = 0; -+ ath_mutex_unlock (&pubkeys_registered_lock); -+} -+ - /* Internal function. Register all the pubkeys included in - PUBKEY_TABLE. Returns zero on success or an error code. */ - static void -@@ -202,6 +211,10 @@ pk_register_default (void) - - for (i = 0; (! err) && pubkey_table[i].pubkey; i++) - { -+ if ( !_gcry_is_fips_mode_inactive() && -+ fips_mode () && !pubkey_table[i].fips_allowed ) -+ continue; -+ - #define pubkey_use_dummy(func) \ - if (! pubkey_table[i].pubkey->func) \ - pubkey_table[i].pubkey->func = dummy_##func; -diff -urNp libgcrypt-1.5.3.orig/doc/gcrypt.texi libgcrypt-1.5.3/doc/gcrypt.texi ---- libgcrypt-1.5.3.orig/doc/gcrypt.texi 2013-08-14 02:41:07.908316872 +0200 -+++ libgcrypt-1.5.3/doc/gcrypt.texi 2013-08-14 03:43:51.808257657 +0200 -@@ -844,6 +844,25 @@ This option may be used to disabale a ce - behaves as if this feature has not been detected. Note that the - detection code might be run if the feature has been disabled. This - command must be used at initialization time; i.e. before calling -+ -+@item GCRYCTL_INACTIVATE_FIPS_FLAG; Arguments: const char *log -+Suspend FIPS mode which implies that all ciphers are again allowed to be used. -+Still, all operations around the FIPS 140-2 mode, such as the finite -+state model enforcement are still enforced. The idea of this mode -+is to allow the caller to implement legacy operations, such as -+decryption or signature verification of data that is already present -+using non-approved ciphers. After the legacy operation is completed, -+GCRYCTL_REACTIVATE_FIPS_FLAG should be invoked to limit the ciphers -+again. The argument allows the caller to provide a string that is logged. -+ -+@item GCRYCTL_REACTIVATE_FIPS_FLAG; Arguments: const char *log -+Re-activate FIPS mode by limiting the allowed cipher listing to the -+approved ciphers. This call should be called immediately after the -+legacy operations that are made possible with -+@code{GCRYCTL_INACTIVATE_FIPS_FLAG} are completed. FIPS 140-2 self -+tests are invoked. The argument allows the caller to provide a -+string that is logged. -+ - @code{gcry_check_version}. - - @end table -Binärdateien libgcrypt-1.5.3.orig/doc/.gcrypt.texi.swp und libgcrypt-1.5.3/doc/.gcrypt.texi.swp sind verschieden. -diff -urNp libgcrypt-1.5.3.orig/src/fips.c libgcrypt-1.5.3/src/fips.c ---- libgcrypt-1.5.3.orig/src/fips.c 2013-08-14 02:41:07.943316506 +0200 -+++ libgcrypt-1.5.3/src/fips.c 2013-08-14 03:33:47.600705208 +0200 -@@ -307,6 +307,10 @@ _gcry_inactivate_fips_mode (const char * - { - inactive_fips_mode = 1; - unlock_fsm (); -+ /* enforce reloading of cipher list to allow use of all ciphers */ -+ cipher_reregister_default(); -+ digest_reregister_default(); -+ pk_reregister_default(); - #ifdef HAVE_SYSLOG - syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " - "%s - FIPS mode inactivated", text); -@@ -316,6 +320,33 @@ _gcry_inactivate_fips_mode (const char * - unlock_fsm (); - } - -+void -+_gcry_reactivate_fips_mode (const char *text) -+{ -+ gcry_assert (_gcry_fips_mode ()); -+ -+ lock_fsm (); -+ if (inactive_fips_mode) -+ { -+ inactive_fips_mode = 0; -+ unlock_fsm (); -+ /* execute self test as there have been non-approved ciphers allowed -+ * to execute */ -+ _gcry_fips_run_selftests(0); -+ /* enforce reloading of cipher list to only use FIPS ciphers */ -+ cipher_reregister_default(); -+ digest_reregister_default(); -+ pk_reregister_default(); -+#ifdef HAVE_SYSLOG -+ syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " -+ "%s - FIPS mode activated", text); -+#endif /*HAVE_SYSLOG*/ -+ } -+ else -+ unlock_fsm (); -+ -+} -+ - - /* Return the FIPS mode inactive flag. If it is true the FIPS mode is - not anymore active. */ -diff -urNp libgcrypt-1.5.3.orig/src/g10lib.h libgcrypt-1.5.3/src/g10lib.h ---- libgcrypt-1.5.3.orig/src/g10lib.h 2013-08-14 02:41:07.941316527 +0200 -+++ libgcrypt-1.5.3/src/g10lib.h 2013-08-14 03:25:29.836347533 +0200 -@@ -329,8 +329,11 @@ int _gcry_enforced_fips_mode (void); - void _gcry_set_enforced_fips_mode (void); - - void _gcry_inactivate_fips_mode (const char *text); -+void _gcry_reactivate_fips_mode (const char *text); - int _gcry_is_fips_mode_inactive (void); -- -+void cipher_reregister_default(void); -+void digest_reregister_default(void); -+void pk_reregister_default(void); - - void _gcry_fips_signal_error (const char *srcfile, - int srcline, -diff -urNp libgcrypt-1.5.3.orig/src/gcrypt.h libgcrypt-1.5.3/src/gcrypt.h ---- libgcrypt-1.5.3.orig/src/gcrypt.h.in 2013-08-14 02:41:07.942316516 +0200 -+++ libgcrypt-1.5.3/src/gcrypt.h.in 2013-08-14 02:58:13.304374921 +0200 -@@ -423,7 +423,9 @@ enum gcry_ctl_cmds - GCRYCTL_SELFTEST = 57, - /* Note: 58 .. 62 are used internally. */ - GCRYCTL_DISABLE_HWF = 63, -- GCRYCTL_SET_ENFORCED_FIPS_FLAG = 64 -+ GCRYCTL_SET_ENFORCED_FIPS_FLAG = 64, -+ GCRYCTL_INACTIVATE_FIPS_FLAG = 65, -+ GCRYCTL_REACTIVATE_FIPS_FLAG = 66 - }; - - /* Perform various operations defined by CMD. */ -diff -urNp libgcrypt-1.5.3.orig/src/global.c libgcrypt-1.5.3/src/global.c ---- libgcrypt-1.5.3.orig/src/global.c 2013-08-14 02:41:07.943316506 +0200 -+++ libgcrypt-1.5.3/src/global.c 2013-08-15 23:40:34.233497710 +0200 -@@ -609,6 +609,16 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, - err = GPG_ERR_GENERAL; - break; - -+ case GCRYCTL_INACTIVATE_FIPS_FLAG: -+ log_info ("FIPS mode enabled but allow all approved and non-approved ciphers\n"); -+ _gcry_inactivate_fips_mode (va_arg (arg_ptr, const char *)); -+ break; -+ -+ case GCRYCTL_REACTIVATE_FIPS_FLAG: -+ log_info ("FIPS mode enabled and limit ciphers to approved ciphers\n"); -+ _gcry_reactivate_fips_mode (va_arg (arg_ptr, const char *)); -+ break; -+ - default: - err = GPG_ERR_INV_OP; - } diff --git a/libgcrypt.changes b/libgcrypt.changes index a15264b..0adb9fc 100644 --- a/libgcrypt.changes +++ b/libgcrypt.changes @@ -1,3 +1,19 @@ +------------------------------------------------------------------- +Tue May 6 13:28:33 UTC 2014 - vcizek@suse.com + +- add support for SP800-90A DRBG (fate#316929, bnc#856312) + * patches by Stephan Mueller (http://www.chronox.de/drbg.html): + 0001-SP800-90A-Deterministic-Random-Bit-Generator.patch.bz2 + 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 + 0007-User-interface-to-DRBG.patch + * only after 13.1 (the patches need libgpg-error 1.13) +- drop libgcrypt-fips-allow-legacy.patch (not needed and wasn't + applied anyway) + ------------------------------------------------------------------- Thu Apr 3 12:04:46 UTC 2014 - tchvatal@suse.com diff --git a/libgcrypt.spec b/libgcrypt.spec index cd154c1..535fb18 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -43,12 +43,19 @@ Patch5: libgcrypt-unresolved-dladdr.patch Patch7: libgcrypt-1.5.0-LIBGCRYPT_FORCE_FIPS_MODE-env.diff #PATCH-FIX-UPSTREAM: internal functions are supposed to be used inside libgcrypt, mvyskocil@suse.com Patch8: libgcrypt-1.6.0-use-intenal-functions.patch -Patch10: libgcrypt-fips-allow-legacy.patch Patch11: libgcrypt-fixed-sizet.patch 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: 0001-SP800-90A-Deterministic-Random-Bit-Generator.patch.bz2 +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: 0007-User-interface-to-DRBG.patch BuildRequires: automake >= 1.11 BuildRequires: libgpg-error-devel >= 1.11 BuildRequires: libtool @@ -119,10 +126,16 @@ understanding of applied cryptography is required to use Libgcrypt. %patch5 -p1 %patch7 -p1 %patch8 -p1 -#%patch10 -p1 %patch11 -p1 %if 0%{?suse_version} > 1310 %patch12 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 %endif %patch13 -p1 %patch14 -p1