diff --git a/libgcrypt-fips-dsa.patch b/libgcrypt-fips-dsa.patch new file mode 100644 index 0000000..abc4365 --- /dev/null +++ b/libgcrypt-fips-dsa.patch @@ -0,0 +1,182 @@ +Index: libgcrypt-1.6.1/cipher/dsa.c +=================================================================== +--- libgcrypt-1.6.1.orig/cipher/dsa.c 2014-01-24 10:45:35.000000000 +0100 ++++ libgcrypt-1.6.1/cipher/dsa.c 2014-09-17 14:16:40.827152998 +0200 +@@ -67,7 +67,7 @@ static const char *dsa_names[] = + + + /* A sample 1024 bit DSA key used for the selftests. */ +-static const char sample_secret_key[] = ++static const char sample_secret_key_1024[] = + "(private-key" + " (dsa" + " (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" +@@ -85,7 +85,7 @@ static const char sample_secret_key[] = + " 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)" + " (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))"; + /* A sample 1024 bit DSA key used for the selftests (public only). */ +-static const char sample_public_key[] = ++static const char sample_public_key_1024[] = + "(public-key" + " (dsa" + " (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" +@@ -102,6 +102,23 @@ static const char sample_public_key[] = + " 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20" + " 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))"; + ++/* 2048 DSA key from RFC 6979 A.2.2 */ ++static const char sample_public_key_2048[] = ++"(public-key" ++" (dsa" ++" (p #a85378d8fd3f8d72ec7418080da21317e43ec4b62ba8c8623b7e4d04441dd1a0658662596493ca8e9e8fbb7e34aaddb62e5d67b6d09a6e61b769e7c352aa2b10e20ca0636963b5523e86470decbbeda027e797e7b67635d4d49c30700e74af8a0ff156a801af57a26e7078f1d82f74908ecb6d07e70b3503eed94fa32cf17a7fc3d6cf40dc7b00830e6a2566dc073e343312517c6aa5152b4bfecd2e551fee346318a153423c996b0d5dcb9102aedd38798616f1f1e0d6c403525b1f9b3d4dc766de2dfc4a56d7b8ba5963d60f3e16318870ad436952e55765374eab85e8ec17d6b9a4547b9b5f2752f3105be809b23a2c8d7469db02e24d592394a7dba069e9#)" ++" (q #d277044e50f5a4e3f510a50a0b84fdffbca047ed276020567441a0a5#)" ++" (g #13d754e21fd241655da891c522a65a72a89bdc64ec9b54a821ed4a898b490e0c4fcb72192a4a20f541f3f2925399f0baecf929aafbf79dfe4332393b32cd2e2fcf272f32a627434a0df242b75b414df372121e53a553f222f836b000f016485b6bd0898451801dcd8de64cd5365696ffc532d528c506620a942a0305046d8f1876341f1e570bc3974ba6b9a438e9702302a2e6e67bfd06d32bc679962271d7b40cd72f386e64e0d7ef86ca8ca5d14228dc2a4f16e3189886b5990674f4200f3a4cf65a3f0ddba1fa672dff2f5e143d10e4e97ae84f6da09535d5b9df259181a79b63b069e949972b02ba36b3586aab7e45f322f82e4e85ca3ab85591b3c2a966#)" ++" (y #2452f3ccbe9ed5ca7dc74c602b99226e8f2fab38e7d7ddfb75539b17155e9fcfd1aba564eb8535d812c9c2dcf97284441bc482243624c7f457580c1c38a57c46c457392470edb52cb5a6e03fe6287bb6f49a42a2065a054f030839df1fd3149c4ca0531dd8ca8aaa9cc7337193387348336118224545e88c80ffd8765d74360333ccab9972779b6525a65bdd0d10c675c109bbd3e5be4d72ef6eba6e438d5226237db888379c5fcc47a3847ff63711baed6d03afe81e694a413b680bd38ab4903f8370a707ef551d4941026d9579d691de8edaa16105eb9dba3c2f4c1bec508275aa0207e251b5eccb286a4b01d449d30acb673717a0d2fb3b50c893f7dab14f#)))"; ++ ++static const char sample_secret_key_2048[] = ++"(private-key" ++" (dsa" ++" (p #a85378d8fd3f8d72ec7418080da21317e43ec4b62ba8c8623b7e4d04441dd1a0658662596493ca8e9e8fbb7e34aaddb62e5d67b6d09a6e61b769e7c352aa2b10e20ca0636963b5523e86470decbbeda027e797e7b67635d4d49c30700e74af8a0ff156a801af57a26e7078f1d82f74908ecb6d07e70b3503eed94fa32cf17a7fc3d6cf40dc7b00830e6a2566dc073e343312517c6aa5152b4bfecd2e551fee346318a153423c996b0d5dcb9102aedd38798616f1f1e0d6c403525b1f9b3d4dc766de2dfc4a56d7b8ba5963d60f3e16318870ad436952e55765374eab85e8ec17d6b9a4547b9b5f2752f3105be809b23a2c8d7469db02e24d592394a7dba069e9#)" ++" (q #d277044e50f5a4e3f510a50a0b84fdffbca047ed276020567441a0a5#)" ++" (g #13d754e21fd241655da891c522a65a72a89bdc64ec9b54a821ed4a898b490e0c4fcb72192a4a20f541f3f2925399f0baecf929aafbf79dfe4332393b32cd2e2fcf272f32a627434a0df242b75b414df372121e53a553f222f836b000f016485b6bd0898451801dcd8de64cd5365696ffc532d528c506620a942a0305046d8f1876341f1e570bc3974ba6b9a438e9702302a2e6e67bfd06d32bc679962271d7b40cd72f386e64e0d7ef86ca8ca5d14228dc2a4f16e3189886b5990674f4200f3a4cf65a3f0ddba1fa672dff2f5e143d10e4e97ae84f6da09535d5b9df259181a79b63b069e949972b02ba36b3586aab7e45f322f82e4e85ca3ab85591b3c2a966#)" ++" (y #2452f3ccbe9ed5ca7dc74c602b99226e8f2fab38e7d7ddfb75539b17155e9fcfd1aba564eb8535d812c9c2dcf97284441bc482243624c7f457580c1c38a57c46c457392470edb52cb5a6e03fe6287bb6f49a42a2065a054f030839df1fd3149c4ca0531dd8ca8aaa9cc7337193387348336118224545e88c80ffd8765d74360333ccab9972779b6525a65bdd0d10c675c109bbd3e5be4d72ef6eba6e438d5226237db888379c5fcc47a3847ff63711baed6d03afe81e694a413b680bd38ab4903f8370a707ef551d4941026d9579d691de8edaa16105eb9dba3c2f4c1bec508275aa0207e251b5eccb286a4b01d449d30acb673717a0d2fb3b50c893f7dab14f#)" ++" (x #0c4b3089d1b862cb3c436491f0915470c52796e3acbee800ec55f6cc#)))"; + + + +@@ -369,6 +386,8 @@ generate_fips186 (DSA_secret_key *sk, un + gcry_mpi_t value_x = NULL; /* The secret exponent. */ + gcry_mpi_t value_h = NULL; /* Helper. */ + gcry_mpi_t value_e = NULL; /* Helper. */ ++ gcry_mpi_t value_c = NULL; /* helper for x */ ++ gcry_mpi_t value_qm2 = NULL; /* q - 2 */ + + /* Preset return values. */ + *r_counter = 0; +@@ -389,9 +408,7 @@ generate_fips186 (DSA_secret_key *sk, un + + /* Check that QBITS and NBITS match the standard. Note that FIPS + 186-3 uses N for QBITS and L for NBITS. */ +- if (nbits == 1024 && qbits == 160) +- ; +- else if (nbits == 2048 && qbits == 224) ++ if (nbits == 2048 && qbits == 224) + ; + else if (nbits == 2048 && qbits == 256) + ; +@@ -426,19 +443,18 @@ generate_fips186 (DSA_secret_key *sk, un + + /* Fixme: Enable 186-3 after it has been approved and after fixing + the generation function. */ +- /* if (use_fips186_2) */ +- (void)use_fips186_2; +- ec = _gcry_generate_fips186_2_prime (nbits, qbits, ++ if (use_fips186_2) ++ ec = _gcry_generate_fips186_2_prime (nbits, qbits, + initial_seed.seed, + initial_seed.seedlen, + &prime_q, &prime_p, + r_counter, + r_seed, r_seedlen); +- /* else */ +- /* ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, */ +- /* &prime_q, &prime_p, */ +- /* r_counter, */ +- /* r_seed, r_seedlen, NULL); */ ++ else ++ ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, ++ &prime_q, &prime_p, ++ r_counter, ++ r_seed, r_seedlen, NULL); + sexp_release (initial_seed.sexp); + if (ec) + goto leave; +@@ -459,17 +475,23 @@ generate_fips186 (DSA_secret_key *sk, un + while (!mpi_cmp_ui (value_g, 1)); /* Continue until g != 1. */ + } + +- +- /* Select a random number x with: 0 < x < q */ ++ value_c = mpi_snew (qbits); + value_x = mpi_snew (qbits); ++ value_qm2 = mpi_snew (qbits); ++ mpi_sub_ui (value_qm2, prime_q, 2); ++ ++ /* FIPS 186-4 B.1.2 steps 4-6 */ + do + { + if( DBG_CIPHER ) + progress('.'); +- _gcry_mpi_randomize (value_x, qbits, GCRY_VERY_STRONG_RANDOM); +- mpi_clear_highbit (value_x, qbits+1); ++ _gcry_mpi_randomize (value_c, qbits, GCRY_VERY_STRONG_RANDOM); ++ mpi_clear_highbit (value_c, qbits+1); + } +- while (!(mpi_cmp_ui (value_x, 0) > 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 new file mode 100644 index 0000000..71d105c --- /dev/null +++ b/libgcrypt-fips_ecdsa.patch @@ -0,0 +1,30 @@ +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-fips_run_selftest_at_constructor.patch b/libgcrypt-fips_run_selftest_at_constructor.patch new file mode 100644 index 0000000..ed22926 --- /dev/null +++ b/libgcrypt-fips_run_selftest_at_constructor.patch @@ -0,0 +1,17 @@ +Index: libgcrypt-1.6.1/src/global.c +=================================================================== +--- libgcrypt-1.6.1.orig/src/global.c 2014-09-21 11:41:09.242948783 +0200 ++++ libgcrypt-1.6.1/src/global.c 2014-09-21 11:54:49.567586644 +0200 +@@ -124,7 +124,11 @@ global_init (void) + err = _gcry_mpi_init (); + if (err) + goto fail; +- ++ if (fips_mode()) { ++ err = _gcry_fips_run_selftests (0); ++ if (err) ++ goto fail; ++ } + return; + + fail: diff --git a/libgcrypt.changes b/libgcrypt.changes index 6d58d08..22866dd 100644 --- a/libgcrypt.changes +++ b/libgcrypt.changes @@ -1,3 +1,25 @@ +------------------------------------------------------------------- +Sun Sep 21 10:08:39 UTC 2014 - vcizek@suse.com + +- disabled curve P-192 in FIPS mode (bnc#896202) + * added libgcrypt-fips_ecdsa.patch +- don't use SHA-1 for ECDSA in FIPS mode +- also run the fips self tests only in FIPS mode + +------------------------------------------------------------------- +Tue Sep 16 13:56:01 UTC 2014 - vcizek@suse.com + +- run the fips self tests at the constructor code + * added libgcrypt-fips_run_selftest_at_constructor.patch + +------------------------------------------------------------------- +Tue Sep 16 12:17:17 UTC 2014 - vcizek@suse.com + +- rewrite the DSA-2 code to be FIPS 186-4 compliant (bnc#894216) + * added libgcrypt-fips-dsa.patch + * install fips186_dsa +- use 2048 bit keys in selftests_dsa + ------------------------------------------------------------------- Mon Sep 1 10:57:06 UTC 2014 - vcizek@suse.com diff --git a/libgcrypt.spec b/libgcrypt.spec index a8942c2..820e19b 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -20,6 +20,7 @@ %define separate_hmac256_binary 0 %define libsoname %{name}20 %define sosuffix 20.0.1 +%define cavs_dir %{_libexecdir}/%{name}/cavs Name: libgcrypt Version: 1.6.1 Release: 0 @@ -61,7 +62,14 @@ 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 BuildRequires: automake >= 1.11 BuildRequires: libgpg-error-devel >= 1.11 BuildRequires: libtool @@ -163,6 +171,9 @@ understanding of applied cryptography is required to use Libgcrypt. %patch28 -p1 %patch29 -p1 %patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 %endif %patch13 -p1 %patch14 -p1 @@ -218,14 +229,18 @@ fipshmac src/.libs/libgcrypt.so.?? %install make DESTDIR=%{buildroot} install %{?_smp_mflags} - rm %{buildroot}%{_libdir}/%{name}.la + # cavs -install -m 0755 -d %{buildroot}/%{_libexecdir}/%{name} -install -m 0755 %{SOURCE5} %{buildroot}/%{_libexecdir}/%{name} -install -m 0755 %{SOURCE6} %{buildroot}/%{_libexecdir}/%{name} -mv %{buildroot}%{_bindir}/fipsdrv %{buildroot}/%{_libexecdir}/%{name} -mv %{buildroot}%{_bindir}/drbg_test %{buildroot}/%{_libexecdir}/%{name} +install -m 0755 -d %{buildroot}%{cavs_dir} +install -m 0755 %{SOURCE5} %{buildroot}%{cavs_dir} +install -m 0755 %{SOURCE6} %{buildroot}%{cavs_dir} + +%if 0%{?suse_version} > 1310 +mv %{buildroot}%{_bindir}/fips186_dsa %{buildroot}%{cavs_dir} +mv %{buildroot}%{_bindir}/fipsdrv %{buildroot}%{cavs_dir} +mv %{buildroot}%{_bindir}/drbg_test %{buildroot}%{cavs_dir} +%endif %post -n %{libsoname} -p /sbin/ldconfig