Hello community, here is the log from the commit of package libgcrypt for openSUSE:Factory checked in at 2020-01-30 09:31:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libgcrypt (Old) and /work/SRC/openSUSE:Factory/.libgcrypt.new.26092 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libgcrypt" Thu Jan 30 09:31:14 2020 rev:79 rq:766879 version:1.8.5 Changes: -------- --- /work/SRC/openSUSE:Factory/libgcrypt/libgcrypt.changes 2019-09-07 11:28:47.222469056 +0200 +++ /work/SRC/openSUSE:Factory/.libgcrypt.new.26092/libgcrypt.changes 2020-01-30 09:32:02.957189834 +0100 @@ -1,0 +2,37 @@ +Fri Jan 17 17:35:15 UTC 2020 - Pedro Monreal Gonzalez <pmonrealgonza...@suse.com> + +- FIPS: libgcrypt DSA PQG parameter generation: Missing value [bsc#1161219] +- FIPS: libgcrypt DSA PQG verification incorrect results [bsc#1161215] +- FIPS: libgcrypt RSA siggen/keygen: 4k not supported [bsc#1161220] + * Add patch from Fedora libgcrypt-1.8.4-fips-keygen.patch + +------------------------------------------------------------------- +Wed Dec 11 10:18:23 UTC 2019 - Pedro Monreal Gonzalez <pmonrealgonza...@suse.com> + +- FIPS: RSA/DSA/ECDSA are missing hashing operation [bsc#1155337] + * Add libgcrypt-FIPS-RSA-DSA-ECDSA-hashing-operation.patch + +------------------------------------------------------------------- +Wed Nov 27 14:01:01 UTC 2019 - Pedro Monreal Gonzalez <pmonrealgonza...@suse.com> + +- Fix tests in FIPS mode: + * Fix tests: basic benchmark bench-slope pubkey t-cv25519 t-secmem + * Add patch libgcrypt-fix-tests-fipsmode.patch + +------------------------------------------------------------------- +Tue Nov 26 18:48:20 UTC 2019 - Pedro Monreal Gonzalez <pmonrealgonza...@suse.com> + +- Fix test dsa-rfc6979 in FIPS mode: + * Disable tests in elliptic curves with 192 bits which are not + recommended in FIPS mode + * Add patch libgcrypt-dsa-rfc6979-test-fix.patch + +------------------------------------------------------------------- +Tue Nov 12 11:05:02 UTC 2019 - Pedro Monreal Gonzalez <pmonrealgonza...@suse.com> + +- CMAC AES and TDES FIPS self-tests: + * CMAC AES self test missing [bsc#1155339] + * CMAC TDES self test missing [bsc#1155338] +- Add libgcrypt-CMAC-AES-TDES-selftest.patch + +------------------------------------------------------------------- New: ---- libgcrypt-1.8.4-fips-keygen.patch libgcrypt-CMAC-AES-TDES-selftest.patch libgcrypt-FIPS-RSA-DSA-ECDSA-hashing-operation.patch libgcrypt-dsa-rfc6979-test-fix.patch libgcrypt-fix-tests-fipsmode.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libgcrypt.spec ++++++ --- /var/tmp/diff_new_pack.pMwPjp/_old 2020-01-30 09:32:05.113190987 +0100 +++ /var/tmp/diff_new_pack.pMwPjp/_new 2020-01-30 09:32:05.117190990 +0100 @@ -1,7 +1,7 @@ # # spec file for package libgcrypt # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -66,6 +66,15 @@ Patch47: libgcrypt-CVE-2019-12904-GCM.patch Patch48: libgcrypt-CVE-2019-12904-AES.patch Patch49: libgcrypt-1.8.4-fips_ctor_skip_integrity_check.patch +#PATCH-FIX-SUSE bsc#1155338 bsc#1155338 FIPS: CMAC AES and TDES self tests missing +Patch50: libgcrypt-CMAC-AES-TDES-selftest.patch +#PATCH-FIX-SUSE Fix test in FIPS mode +Patch51: libgcrypt-dsa-rfc6979-test-fix.patch +Patch52: libgcrypt-fix-tests-fipsmode.patch +#PATCH-FIX-SUSE bsc#1155337 FIPS: RSA/DSA/ECDSA are missing hashing operation +Patch53: libgcrypt-FIPS-RSA-DSA-ECDSA-hashing-operation.patch +#PATCH-FIX-SUSE bsc#1161220 FIPS: libgcrypt RSA siggen/keygen: 4k not supported +Patch54: libgcrypt-1.8.4-fips-keygen.patch BuildRequires: automake >= 1.14 BuildRequires: fipscheck BuildRequires: libgpg-error-devel >= 1.25 ++++++ libgcrypt-1.8.4-fips-keygen.patch ++++++ Index: libgcrypt-1.8.2/cipher/dsa.c =================================================================== --- libgcrypt-1.8.2.orig/cipher/dsa.c +++ libgcrypt-1.8.2/cipher/dsa.c @@ -457,11 +457,22 @@ generate_fips186 (DSA_secret_key *sk, un &prime_q, &prime_p, r_counter, r_seed, r_seedlen); - else - ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, + else if (!domain->p || !domain->q) + ec = _gcry_generate_fips186_3_prime (nbits, qbits, + initial_seed.seed, + initial_seed.seedlen, &prime_q, &prime_p, r_counter, r_seed, r_seedlen, NULL); + else + { + /* Domain parameters p and q are given; use them. */ + prime_p = mpi_copy (domain->p); + prime_q = mpi_copy (domain->q); + gcry_assert (mpi_get_nbits (prime_p) == nbits); + gcry_assert (mpi_get_nbits (prime_q) == qbits); + ec = 0; + } sexp_release (initial_seed.sexp); if (ec) goto leave; @@ -857,13 +868,12 @@ dsa_generate (const gcry_sexp_t genparms sexp_release (l1); sexp_release (domainsexp); - /* Check that all domain parameters are available. */ - if (!domain.p || !domain.q || !domain.g) + /* Check that p and q domain parameters are available. */ + if (!domain.p || !domain.q || (!domain.g && !(flags & PUBKEY_FLAG_USE_FIPS186))) { _gcry_mpi_release (domain.p); _gcry_mpi_release (domain.q); _gcry_mpi_release (domain.g); - sexp_release (deriveparms); return GPG_ERR_MISSING_VALUE; } Index: libgcrypt-1.8.2/cipher/rsa.c =================================================================== --- libgcrypt-1.8.2.orig/cipher/rsa.c +++ libgcrypt-1.8.2/cipher/rsa.c @@ -389,7 +389,7 @@ generate_fips (RSA_secret_key *sk, unsig if (nbits < 1024 || (nbits & 0x1FF)) return GPG_ERR_INV_VALUE; - if (fips_mode() && nbits != 2048 && nbits != 3072) + if (fips_mode() && nbits < 2048) return GPG_ERR_INV_VALUE; /* The random quality depends on the transient_key flag. */ @@ -696,7 +696,7 @@ generate_x931 (RSA_secret_key *sk, unsig *swapped = 0; - if (e_value == 1) /* Alias for a secure value. */ + if (e_value == 1 || e_value == 0) /* Alias for a secure value. */ e_value = 65537; /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ ++++++ libgcrypt-CMAC-AES-TDES-selftest.patch ++++++ diff -up libgcrypt-1.8.3/cipher/cipher-cmac.c.cmac-selftest libgcrypt-1.8.3/cipher/cipher-cmac.c --- libgcrypt-1.8.3/cipher/cipher-cmac.c.cmac-selftest 2017-11-23 19:16:58.000000000 +0100 +++ libgcrypt-1.8.3/cipher/cipher-cmac.c 2019-05-31 17:33:35.594407152 +0200 @@ -251,3 +251,246 @@ _gcry_cipher_cmac_set_subkeys (gcry_ciph return GPG_ERR_NO_ERROR; } + +/* CMAC selftests. + * Copyright (C) 2008 Free Software Foundation, Inc. + * Copyright (C) 2019 Red Hat, Inc. + */ + + + +/* Check one MAC with MAC ALGO using the regular MAC + * API. (DATA,DATALEN) is the data to be MACed, (KEY,KEYLEN) the key + * and (EXPECT,EXPECTLEN) the expected result. If TRUNC is set, the + * EXPECTLEN may be less than the digest length. Returns NULL on + * success or a string describing the failure. */ +static const char * +check_one (int algo, + const void *data, size_t datalen, + const void *key, size_t keylen, + const void *expect, size_t expectlen) +{ + gcry_mac_hd_t hd; + unsigned char mac[512]; /* hardcoded to avoid allocation */ + size_t macoutlen = expectlen; + +/* printf ("MAC algo %d\n", algo); */ + if (_gcry_mac_get_algo_maclen (algo) != expectlen || + expectlen > sizeof (mac)) + return "invalid tests data"; + if (_gcry_mac_open (&hd, algo, 0, NULL)) + return "gcry_mac_open failed"; + if (_gcry_mac_setkey (hd, key, keylen)) + { + _gcry_mac_close (hd); + return "gcry_md_setkey failed"; + } + if (_gcry_mac_write (hd, data, datalen)) + { + _gcry_mac_close (hd); + return "gcry_mac_write failed"; + } + if (_gcry_mac_read (hd, mac, &macoutlen)) + { + _gcry_mac_close (hd); + return "gcry_mac_read failed"; + } + _gcry_mac_close (hd); + if (macoutlen != expectlen || memcmp (mac, expect, expectlen)) + { +/* int i; */ + +/* fputs (" {", stdout); */ +/* for (i=0; i < expectlen-1; i++) */ +/* { */ +/* if (i && !(i % 8)) */ +/* fputs ("\n ", stdout); */ +/* printf (" 0x%02x,", mac[i]); */ +/* } */ +/* printf (" 0x%02x } },\n", mac[i]); */ + + return "does not match"; + } + return NULL; +} + + +static gpg_err_code_t +selftests_cmac_tdes (int extended, selftest_report_func_t report) +{ + const char *what; + const char *errtxt; + + what = "Basic TDES"; + errtxt = check_one (GCRY_MAC_CMAC_3DES, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" + "\xae\x2d\x8a\x57", 20, + "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" + "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24, + "\x74\x3d\xdb\xe0\xce\x2d\xc2\xed", 8); + if (errtxt) + goto failed; + + if (extended) + { + what = "Extended TDES #1"; + errtxt = check_one (GCRY_MAC_CMAC_3DES, + "", 0, + "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" + "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24, + "\xb7\xa6\x88\xe1\x22\xff\xaf\x95", 8); + if (errtxt) + goto failed; + + what = "Extended TDES #2"; + errtxt = check_one (GCRY_MAC_CMAC_3DES, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96", 8, + "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" + "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24, + "\x8e\x8f\x29\x31\x36\x28\x37\x97", 8); + if (errtxt) + goto failed; + + what = "Extended TDES #3"; + errtxt = check_one (GCRY_MAC_CMAC_3DES, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" + "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 32, + "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" + "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24, + "\x33\xe6\xb1\x09\x24\x00\xea\xe5", 8); + if (errtxt) + goto failed; + } + + return 0; /* Succeeded. */ + + failed: + if (report) + report ("cmac", GCRY_MAC_CMAC_3DES, what, errtxt); + return GPG_ERR_SELFTEST_FAILED; +} + + + +static gpg_err_code_t +selftests_cmac_aes (int extended, selftest_report_func_t report) +{ + const char *what; + const char *errtxt; + + what = "Basic AES128"; + errtxt = check_one (GCRY_MAC_CMAC_AES, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" + "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" + "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 40, + "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16, + "\xdf\xa6\x67\x47\xde\x9a\xe6\x30\x30\xca\x32\x61\x14\x97\xc8\x27", 16); + if (errtxt) + goto failed; + + what = "Basic AES192"; + errtxt = check_one (GCRY_MAC_CMAC_AES, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" + "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" + "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 40, + "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5" + "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24, + "\x8a\x1d\xe5\xbe\x2e\xb3\x1a\xad\x08\x9a\x82\xe6\xee\x90\x8b\x0e", 16); + if (errtxt) + goto failed; + + what = "Basic AES256"; + errtxt = check_one (GCRY_MAC_CMAC_AES, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" + "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" + "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 40, + "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" + "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32, + "\xaa\xf3\xd8\xf1\xde\x56\x40\xc2\x32\xf5\xb1\x69\xb9\xc9\x11\xe6", 16); + if (errtxt) + goto failed; + if (extended) + { + what = "Extended AES #1"; + errtxt = check_one (GCRY_MAC_CMAC_AES, + "", 0, + "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16, + "\xbb\x1d\x69\x29\xe9\x59\x37\x28\x7f\xa3\x7d\x12\x9b\x75\x67\x46", 16); + if (errtxt) + goto failed; + + what = "Extended AES #2"; + errtxt = check_one (GCRY_MAC_CMAC_AES, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, + "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5" + "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24, + "\x9e\x99\xa7\xbf\x31\xe7\x10\x90\x06\x62\xf6\x5e\x61\x7c\x51\x84", 16); + if (errtxt) + goto failed; + + what = "Extended AES #3"; + errtxt = check_one (GCRY_MAC_CMAC_AES, + "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" + "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" + "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" + "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 64, + "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" + "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32, + "\xe1\x99\x21\x90\x54\x9f\x6e\xd5\x69\x6a\x2c\x05\x6c\x31\x54\x10", 16 ); + if (errtxt) + goto failed; + } + + return 0; /* Succeeded. */ + + failed: + if (report) + report ("cmac", GCRY_MAC_CMAC_AES, what, errtxt); + return GPG_ERR_SELFTEST_FAILED; +} + + +/* Run a full self-test for ALGO and return 0 on success. */ +static gpg_err_code_t +run_cmac_selftests (int algo, int extended, selftest_report_func_t report) +{ + gpg_err_code_t ec; + + switch (algo) + { + case GCRY_MAC_CMAC_3DES: + ec = selftests_cmac_tdes (extended, report); + break; + case GCRY_MAC_CMAC_AES: + ec = selftests_cmac_aes (extended, report); + break; + + default: + ec = GPG_ERR_MAC_ALGO; + break; + } + return ec; +} + + + + +/* Run the selftests for CMAC with CMAC algorithm ALGO with optional + reporting function REPORT. */ +gpg_error_t +_gcry_cmac_selftest (int algo, int extended, selftest_report_func_t report) +{ + gcry_err_code_t ec = 0; + + if (!_gcry_mac_algo_info( algo, GCRYCTL_TEST_ALGO, NULL, NULL )) + { + ec = run_cmac_selftests (algo, extended, report); + } + else + { + ec = GPG_ERR_MAC_ALGO; + if (report) + report ("mac", algo, "module", "algorithm not available"); + } + return gpg_error (ec); +} diff -up libgcrypt-1.8.3/src/cipher-proto.h.cmac-selftest libgcrypt-1.8.3/src/cipher-proto.h --- libgcrypt-1.8.3/src/cipher-proto.h.cmac-selftest 2017-11-23 19:16:58.000000000 +0100 +++ libgcrypt-1.8.3/src/cipher-proto.h 2019-05-31 17:29:34.574588234 +0200 @@ -256,6 +256,8 @@ gcry_error_t _gcry_pk_selftest (int algo selftest_report_func_t report); gcry_error_t _gcry_hmac_selftest (int algo, int extended, selftest_report_func_t report); +gcry_error_t _gcry_cmac_selftest (int algo, int extended, + selftest_report_func_t report); gcry_error_t _gcry_random_selftest (selftest_report_func_t report); diff -up libgcrypt-1.8.3/src/fips.c.cmac-selftest libgcrypt-1.8.3/src/fips.c --- libgcrypt-1.8.3/src/fips.c.cmac-selftest 2018-11-01 15:40:36.051865535 +0100 +++ libgcrypt-1.8.3/src/fips.c 2019-05-31 17:31:20.157756640 +0200 @@ -521,29 +521,32 @@ run_digest_selftests (int extended) /* Run self-tests for all HMAC algorithms. Return 0 on success. */ static int -run_hmac_selftests (int extended) +run_mac_selftests (int extended) { - static int algos[] = + static int algos[][2] = { - GCRY_MD_SHA1, - GCRY_MD_SHA224, - GCRY_MD_SHA256, - GCRY_MD_SHA384, - GCRY_MD_SHA512, - GCRY_MD_SHA3_224, - GCRY_MD_SHA3_256, - GCRY_MD_SHA3_384, - GCRY_MD_SHA3_512, - 0 + { GCRY_MD_SHA1, 0 }, + { GCRY_MD_SHA224, 0 }, + { GCRY_MD_SHA256, 0 }, + { GCRY_MD_SHA384, 0 }, + { GCRY_MD_SHA512, 0 }, + { GCRY_MD_SHA3_224, 0 }, + { GCRY_MD_SHA3_256, 0 }, + { GCRY_MD_SHA3_384, 0 }, + { GCRY_MD_SHA3_512, 0 }, + { GCRY_MAC_CMAC_3DES, 1 }, + { GCRY_MAC_CMAC_AES, 1 }, + { 0, 0 } }; int idx; gpg_error_t err; int anyerr = 0; - for (idx=0; algos[idx]; idx++) + for (idx=0; algos[idx][0]; idx++) { - err = _gcry_hmac_selftest (algos[idx], extended, reporter); - reporter ("hmac", algos[idx], NULL, + err = algos[idx][1] ? _gcry_cmac_selftest (algos[idx][0], extended, reporter) : + _gcry_hmac_selftest (algos[idx][0], extended, reporter); + reporter (algos[idx][1] ? "cmac" : "hmac", algos[idx][0], NULL, err? gpg_strerror (err):NULL); if (err) anyerr = 1; @@ -747,7 +750,7 @@ _gcry_fips_run_selftests (int extended) if (run_digest_selftests (extended)) goto leave; - if (run_hmac_selftests (extended)) + if (run_mac_selftests (extended)) goto leave; /* Run random tests before the pubkey tests because the latter ++++++ libgcrypt-FIPS-RSA-DSA-ECDSA-hashing-operation.patch ++++++ Index: libgcrypt-1.8.2/cipher/pubkey-internal.h =================================================================== --- libgcrypt-1.8.2.orig/cipher/pubkey-internal.h +++ libgcrypt-1.8.2/cipher/pubkey-internal.h @@ -43,6 +43,7 @@ void _gcry_pk_util_free_encoding_ctx (st gcry_err_code_t _gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi, struct pk_encoding_ctx *ctx); +gcry_err_code_t _gcry_pk_util_get_algo (gcry_sexp_t input, int *algo); Index: libgcrypt-1.8.2/cipher/pubkey-util.c =================================================================== --- libgcrypt-1.8.2.orig/cipher/pubkey-util.c +++ libgcrypt-1.8.2/cipher/pubkey-util.c @@ -1119,3 +1119,50 @@ _gcry_pk_util_data_to_mpi (gcry_sexp_t i return rc; } + + +gcry_err_code_t +_gcry_pk_util_get_algo (gcry_sexp_t input, int *algo) +{ + gcry_err_code_t rc = 0; + gcry_sexp_t ldata, list = NULL; + const char *s; + size_t n; + int lalgo; + + ldata = sexp_find_token (input, "data", 0); + if (!ldata) + { + rc = GPG_ERR_INV_OBJ; + goto leave; + } + + list = sexp_find_token (ldata, "hash-algo", 0); + if (!list) + { + rc = GPG_ERR_INV_OBJ; + goto leave; + } + + s = sexp_nth_data (list, 1, &n); + if (!s) + { + rc = GPG_ERR_NO_OBJ; + goto leave; + } + + lalgo = get_hash_algo (s, n); + if (!lalgo) + { + rc = GPG_ERR_DIGEST_ALGO; + goto leave; + } + + *algo = lalgo; + + leave: + sexp_release (ldata); + sexp_release (list); + + return rc; +} Index: libgcrypt-1.8.2/cipher/pubkey.c =================================================================== --- libgcrypt-1.8.2.orig/cipher/pubkey.c +++ libgcrypt-1.8.2/cipher/pubkey.c @@ -383,6 +383,33 @@ _gcry_pk_decrypt (gcry_sexp_t *r_plain, return rc; } +static gcry_err_code_t +calculate_hash (gcry_md_hd_t hd, gcry_sexp_t s_hash) +{ + gcry_err_code_t rc; + const unsigned char *digest; + int algo; + + if (!hd) + return 0; + + rc = _gcry_pk_util_get_algo (s_hash, &algo); + if (rc) + return rc; + + digest = _gcry_md_read(hd, algo); + if (!digest) + return GPG_ERR_DIGEST_ALGO; + + rc = _gcry_sexp_build (&s_hash, NULL, + "(data (flags pkcs1)(hash %s %b))", + _gcry_md_algo_name(algo), (int) _gcry_md_get_algo_dlen(algo), digest); + + return rc; +} + + + /* @@ -414,7 +442,8 @@ _gcry_pk_decrypt (gcry_sexp_t *r_plain, Note that (hash algo) in R_SIG is not used. */ gcry_err_code_t -_gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey) +_gcry_pk_sign_md (gcry_sexp_t *r_sig, gcry_md_hd_t hd, gcry_sexp_t s_hash, + gcry_sexp_t s_skey) { gcry_err_code_t rc; gcry_pk_spec_t *spec; @@ -426,6 +455,10 @@ _gcry_pk_sign (gcry_sexp_t *r_sig, gcry_ if (rc) goto leave; + rc = calculate_hash (hd, s_hash); + if (rc) + goto leave; + if (spec->sign) rc = spec->sign (r_sig, s_hash, keyparms); else @@ -436,6 +469,13 @@ _gcry_pk_sign (gcry_sexp_t *r_sig, gcry_ return rc; } +gcry_err_code_t +_gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey) +{ + return _gcry_pk_sign_md (r_sig, NULL, s_hash, s_skey); +} + + /* Verify a signature. @@ -445,7 +485,8 @@ _gcry_pk_sign (gcry_sexp_t *r_sig, gcry_ as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data must be an S-Exp like the one in sign too. */ gcry_err_code_t -_gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey) +_gcry_pk_verify_md (gcry_sexp_t s_sig, gcry_md_hd_t hd, gcry_sexp_t s_hash, + gcry_sexp_t s_pkey) { gcry_err_code_t rc; gcry_pk_spec_t *spec; @@ -455,6 +496,10 @@ _gcry_pk_verify (gcry_sexp_t s_sig, gcry if (rc) goto leave; + rc = calculate_hash (hd, s_hash); + if (rc) + goto leave; + if (spec->verify) rc = spec->verify (s_sig, s_hash, keyparms); else @@ -465,6 +510,12 @@ _gcry_pk_verify (gcry_sexp_t s_sig, gcry return rc; } +gcry_err_code_t +_gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey) +{ + return _gcry_pk_verify_md (s_sig, NULL, s_hash, s_pkey); +} + /* Test a key. @@ -497,6 +548,7 @@ _gcry_pk_testkey (gcry_sexp_t s_key) } + /* Create a public key pair and return it in r_key. How the key is created depends on s_parms: Index: libgcrypt-1.8.2/src/visibility.c =================================================================== --- libgcrypt-1.8.2.orig/src/visibility.c +++ libgcrypt-1.8.2/src/visibility.c @@ -992,6 +992,18 @@ gcry_pk_decrypt (gcry_sexp_t *result, gc } gcry_error_t +gcry_pk_sign_md (gcry_sexp_t *result, gcry_md_hd_t hd, gcry_sexp_t data, + gcry_sexp_t skey) +{ + if (!fips_is_operational ()) + { + *result = NULL; + return gpg_error (fips_not_operational ()); + } + return gpg_error (_gcry_pk_sign_md (result, hd, data, skey)); +} + +gcry_error_t gcry_pk_sign (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey) { if (!fips_is_operational ()) @@ -1003,6 +1015,15 @@ gcry_pk_sign (gcry_sexp_t *result, gcry_ } gcry_error_t +gcry_pk_verify_md (gcry_sexp_t sigval, gcry_md_hd_t hd, gcry_sexp_t data, + gcry_sexp_t pkey) +{ + if (!fips_is_operational ()) + return gpg_error (fips_not_operational ()); + return gpg_error (_gcry_pk_verify_md (sigval, hd, data, pkey)); +} + +gcry_error_t gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey) { if (!fips_is_operational ()) ++++++ libgcrypt-dsa-rfc6979-test-fix.patch ++++++ Index: libgcrypt-1.8.2/tests/benchmark.c =================================================================== --- libgcrypt-1.8.2.orig/tests/benchmark.c +++ libgcrypt-1.8.2/tests/benchmark.c @@ -1400,7 +1400,7 @@ ecc_bench (int iterations, int print_hea { #if USE_ECC gpg_error_t err; - const char *p_sizes[] = { "192", "224", "256", "384", "521", "Ed25519", + const char *p_sizes[] = { "224", "256", "384", "521", "Ed25519", "gost256", "gost512" }; int testno; Index: libgcrypt-1.8.2/tests/dsa-rfc6979.c =================================================================== --- libgcrypt-1.8.2.orig/tests/dsa-rfc6979.c +++ libgcrypt-1.8.2/tests/dsa-rfc6979.c @@ -165,16 +165,6 @@ check_dsa_rfc6979 (void) " ))" }, { - "ECDSA, 192 bits (prime field)", - "(private-key" - " (ecdsa" - " (curve \"NIST P-192\")" - " (q #04AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56" - " 3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43#)" - " (d #6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4#)" - " ))" - }, - { "ECDSA, 224 bits (prime field)", "(private-key" " (ecdsa" @@ -398,89 +388,6 @@ check_dsa_rfc6979 (void) "C9F0BDABCC0D880BB137A994CC7F3980CE91CC10FAF529FC46565B15CEA854E1" }, { - "ECDSA, 192 bits (prime field)", - "With SHA-1, message = \"sample\"", - "sha1", "sample", - "37D7CA00D2C7B0E5E412AC03BD44BA837FDD5B28CD3B0021", - "98C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF", - "57A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64" - }, - { - "ECDSA, 192 bits (prime field)", - "With SHA-224, message = \"sample\"", - "sha224", "sample", - "4381526B3FC1E7128F202E194505592F01D5FF4C5AF015D8", - "A1F00DAD97AEEC91C95585F36200C65F3C01812AA60378F5", - "E07EC1304C7C6C9DEBBE980B9692668F81D4DE7922A0F97A" - }, - { - "ECDSA, 192 bits (prime field)", - "With SHA-256, message = \"sample\"", - "sha256", "sample", - "32B1B6D7D42A05CB449065727A84804FB1A3E34D8F261496", - "4B0B8CE98A92866A2820E20AA6B75B56382E0F9BFD5ECB55", - "CCDB006926EA9565CBADC840829D8C384E06DE1F1E381B85" - }, - { - "ECDSA, 192 bits (prime field)", - "With SHA-384, message = \"sample\"", - "sha384", "sample", - "4730005C4FCB01834C063A7B6760096DBE284B8252EF4311", - "DA63BF0B9ABCF948FBB1E9167F136145F7A20426DCC287D5", - "C3AA2C960972BD7A2003A57E1C4C77F0578F8AE95E31EC5E" - }, - { - "ECDSA, 192 bits (prime field)", - "With SHA-512, message = \"sample\"", - "sha512", "sample", - "A2AC7AB055E4F20692D49209544C203A7D1F2C0BFBC75DB1", - "4D60C5AB1996BD848343B31C00850205E2EA6922DAC2E4B8", - "3F6E837448F027A1BF4B34E796E32A811CBB4050908D8F67" - }, - { - "ECDSA, 192 bits (prime field)", - "With SHA-1, message = \"test\"", - "sha1", "test", - "D9CF9C3D3297D3260773A1DA7418DB5537AB8DD93DE7FA25", - "0F2141A0EBBC44D2E1AF90A50EBCFCE5E197B3B7D4DE036D", - "EB18BC9E1F3D7387500CB99CF5F7C157070A8961E38700B7" - }, - { - "ECDSA, 192 bits (prime field)", - "With SHA-224, message = \"test\"", - "sha224", "test", - "F5DC805F76EF851800700CCE82E7B98D8911B7D510059FBE", - "6945A1C1D1B2206B8145548F633BB61CEF04891BAF26ED34", - "B7FB7FDFC339C0B9BD61A9F5A8EAF9BE58FC5CBA2CB15293" - }, - { - "ECDSA, 192 bits (prime field)", - "With SHA-256, message = \"test\"", - "sha256", "test", - "5C4CE89CF56D9E7C77C8585339B006B97B5F0680B4306C6C", - "3A718BD8B4926C3B52EE6BBE67EF79B18CB6EB62B1AD97AE", - "5662E6848A4A19B1F1AE2F72ACD4B8BBE50F1EAC65D9124F" - }, - { - "ECDSA, 192 bits (prime field)", - "With SHA-384, message = \"test\"", - "sha384", "test", - "5AFEFB5D3393261B828DB6C91FBC68C230727B030C975693", - "B234B60B4DB75A733E19280A7A6034BD6B1EE88AF5332367", - "7994090B2D59BB782BE57E74A44C9A1C700413F8ABEFE77A" - }, - { - "ECDSA, 192 bits (prime field)", - "With SHA-512, message = \"test\"", - "sha512", "test", - "0758753A5254759C7CFBAD2E2D9B0792EEE44136C9480527", - "FE4F4AE86A58B6507946715934FE2D8FF9D95B6B098FE739", - "74CF5605C98FBA0E1EF34D4B5A1577A7DCF59457CAE52290" - }, - - - - { "ECDSA, 224 bits (prime field)", "With SHA-1, message = \"sample\"", "sha1", "sample", ++++++ libgcrypt-fix-tests-fipsmode.patch ++++++ diff -up libgcrypt-1.8.4/tests/basic.c.tests-fipsmode libgcrypt-1.8.4/tests/basic.c --- libgcrypt-1.8.4/tests/basic.c.tests-fipsmode 2018-04-17 17:29:40.000000000 +0200 +++ libgcrypt-1.8.4/tests/basic.c 2019-02-12 13:30:48.935791024 +0100 @@ -6964,7 +6964,7 @@ check_ciphers (void) check_one_cipher (algos[i], GCRY_CIPHER_MODE_CTR, 0); if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_CCM_BLOCK_LEN) check_one_cipher (algos[i], GCRY_CIPHER_MODE_CCM, 0); - if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_GCM_BLOCK_LEN) + if (!in_fips_mode && gcry_cipher_get_algo_blklen (algos[i]) == GCRY_GCM_BLOCK_LEN) check_one_cipher (algos[i], GCRY_CIPHER_MODE_GCM, 0); if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_OCB_BLOCK_LEN) check_one_cipher (algos[i], GCRY_CIPHER_MODE_OCB, 0); @@ -7010,11 +7010,17 @@ check_cipher_modes(void) check_cfb_cipher (); check_ofb_cipher (); check_ccm_cipher (); - check_gcm_cipher (); - check_poly1305_cipher (); - check_ocb_cipher (); + if (!in_fips_mode) + { + check_gcm_cipher (); + check_poly1305_cipher (); + check_ocb_cipher (); + } check_xts_cipher (); - check_gost28147_cipher (); + if (!in_fips_mode) + { + check_gost28147_cipher (); + } check_stream_cipher (); check_stream_cipher_large_block (); @@ -10001,7 +10007,7 @@ check_mac (void) show_mac_not_available (algos[i].algo); continue; } - if (gcry_mac_test_algo (algos[i].algo) && in_fips_mode) + if ((algos[i].algo == GCRY_MAC_GMAC_AES || gcry_mac_test_algo (algos[i].algo)) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", @@ -11095,8 +11101,6 @@ main (int argc, char **argv) /* If we are in fips mode do some more tests. */ gcry_md_hd_t md; - /* First trigger a self-test. */ - xgcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) fail ("not in operational state after self-test\n"); @@ -11121,15 +11125,6 @@ main (int argc, char **argv) gcry_md_close (md); if (gcry_control (GCRYCTL_OPERATIONAL_P, 0)) fail ("expected error state but still in operational state\n"); - else - { - /* Now run a self-test and to get back into - operational state. */ - xgcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); - if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) - fail ("did not reach operational after error " - "and self-test\n"); - } } } diff -up libgcrypt-1.8.4/tests/benchmark.c.tests-fipsmode libgcrypt-1.8.4/tests/benchmark.c --- libgcrypt-1.8.4/tests/benchmark.c.tests-fipsmode 2019-02-12 11:31:44.859603883 +0100 +++ libgcrypt-1.8.4/tests/benchmark.c 2019-02-12 14:10:40.271999352 +0100 @@ -872,8 +872,10 @@ cipher_bench ( const char *algoname ) || (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM)) continue; - if (modes[modeidx].req_blocksize > 0 - && blklen != modes[modeidx].req_blocksize) + if ((modes[modeidx].req_blocksize > 0 + && blklen != modes[modeidx].req_blocksize) + || (in_fips_mode + && modes[modeidx].mode == GCRY_CIPHER_MODE_GCM)) { printf (" %7s %7s", "-", "-" ); continue; diff -up libgcrypt-1.8.4/tests/bench-slope.c.tests-fipsmode libgcrypt-1.8.4/tests/bench-slope.c --- libgcrypt-1.8.4/tests/bench-slope.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 +++ libgcrypt-1.8.4/tests/bench-slope.c 2019-02-12 14:14:33.618763325 +0100 @@ -1338,7 +1338,7 @@ cipher_bench_one (int algo, struct bench return; /* GCM has restrictions for block-size */ - if (mode.mode == GCRY_CIPHER_MODE_GCM && blklen != GCRY_GCM_BLOCK_LEN) + if (mode.mode == GCRY_CIPHER_MODE_GCM && (gcry_fips_mode_active () || blklen != GCRY_GCM_BLOCK_LEN)) return; /* XTS has restrictions for block-size */ diff -up libgcrypt-1.8.4/tests/pubkey.c.tests-fipsmode libgcrypt-1.8.4/tests/pubkey.c --- libgcrypt-1.8.4/tests/pubkey.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 +++ libgcrypt-1.8.4/tests/pubkey.c 2019-02-12 13:52:25.658746415 +0100 @@ -504,15 +504,30 @@ get_dsa_key_with_domain_new (gcry_sexp_t rc = gcry_sexp_new (&key_spec, "(genkey (dsa (transient-key)(domain" - "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921" - "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7" - "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0" - "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)" - "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)" - "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab" - "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad" - "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e" - "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)" + " (p #a85378d8fd3f8d72ec7418080da21317e43ec4b62ba8c862" + " 3b7e4d04441dd1a0658662596493ca8e9e8fbb7e34aaddb6" + " 2e5d67b6d09a6e61b769e7c352aa2b10e20ca0636963b552" + " 3e86470decbbeda027e797e7b67635d4d49c30700e74af8a" + " 0ff156a801af57a26e7078f1d82f74908ecb6d07e70b3503" + " eed94fa32cf17a7fc3d6cf40dc7b00830e6a2566dc073e34" + " 3312517c6aa5152b4bfecd2e551fee346318a153423c996b" + " 0d5dcb9102aedd38798616f1f1e0d6c403525b1f9b3d4dc7" + " 66de2dfc4a56d7b8ba5963d60f3e16318870ad436952e557" + " 65374eab85e8ec17d6b9a4547b9b5f2752f3105be809b23a" + " 2c8d7469db02e24d592394a7dba069e9#)" + " (q #d277044e50f5a4e3f510a50a0b84fdffbca047ed27602056" + " 7441a0a5#)" + " (g #13d754e21fd241655da891c522a65a72a89bdc64ec9b54a8" + " 21ed4a898b490e0c4fcb72192a4a20f541f3f2925399f0ba" + " ecf929aafbf79dfe4332393b32cd2e2fcf272f32a627434a" + " 0df242b75b414df372121e53a553f222f836b000f016485b" + " 6bd0898451801dcd8de64cd5365696ffc532d528c506620a" + " 942a0305046d8f1876341f1e570bc3974ba6b9a438e97023" + " 02a2e6e67bfd06d32bc679962271d7b40cd72f386e64e0d7" + " ef86ca8ca5d14228dc2a4f16e3189886b5990674f4200f3a" + " 4cf65a3f0ddba1fa672dff2f5e143d10e4e97ae84f6da095" + " 35d5b9df259181a79b63b069e949972b02ba36b3586aab7e" + " 45f322f82e4e85ca3ab85591b3c2a966#)" ")))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gcry_strerror (rc)); @@ -595,7 +610,7 @@ get_dsa_key_fips186_with_seed_new (gcry_ " (use-fips186)" " (transient-key)" " (derive-parms" - " (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))", + " (seed #8b4c4d671fff82e8ed932260206d0571e3a1c2cee8cd94cb73fe58f9b67488fa#))))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gcry_strerror (rc)); diff -up libgcrypt-1.8.4/tests/t-cv25519.c.tests-fipsmode libgcrypt-1.8.4/tests/t-cv25519.c --- libgcrypt-1.8.4/tests/t-cv25519.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 +++ libgcrypt-1.8.4/tests/t-cv25519.c 2019-02-12 14:02:35.935705390 +0100 @@ -560,6 +560,9 @@ main (int argc, char **argv) xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + /* Curve25519 isn't supported in fips mode */ + if (gcry_fips_mode_active()) + return 77; start_timer (); check_cv25519 (); diff -up libgcrypt-1.8.4/tests/t-secmem.c.tests-fipsmode libgcrypt-1.8.4/tests/t-secmem.c --- libgcrypt-1.8.4/tests/t-secmem.c.tests-fipsmode 2017-11-23 19:19:54.000000000 +0100 +++ libgcrypt-1.8.4/tests/t-secmem.c 2019-02-12 11:51:02.462190538 +0100 @@ -174,7 +174,8 @@ main (int argc, char **argv) xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); xgcry_control (GCRYCTL_INIT_SECMEM, pool_size, 0); - gcry_set_outofcore_handler (outofcore_handler, NULL); + if (!gcry_fips_mode_active ()) + gcry_set_outofcore_handler (outofcore_handler, NULL); xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); /* Libgcrypt prints a warning when the first overflow is allocated; @@ -184,7 +185,8 @@ main (int argc, char **argv) test_secmem (); - test_secmem_overflow (); + if (!gcry_fips_mode_active ()) + test_secmem_overflow (); /* FIXME: We need to improve the tests, for example by registering * our own log handler and comparing the output of * PRIV_CTL_DUMP_SECMEM_STATS to expected pattern. */