9a7cde5372
- FIPS: libgcrypt: Double free in test_keys() on failed signature verification [bsc#1169944] * Use safer gcry_mpi_release() instead of mpi_free() - Update patches: * libgcrypt-PCT-DSA.patch * libgcrypt-PCT-RSA.patch * libgcrypt-PCT-ECC.patch - Ship the FIPS checksum file in the shared library package and create a separate trigger file for the FIPS selftests (bsc#1169569) * add libgcrypt-fips_selftest_trigger_file.patch * refresh libgcrypt-global_init-constructor.patch - Remove libgcrypt-binary_integrity_in_non-FIPS.patch obsoleted by libgcrypt-global_init-constructor.patch - FIPS: Verify that the generated signature and the original input differ in test_keys function for RSA, DSA and ECC: [bsc#1165539] - Add zero-padding when qx and qy have different lengths when assembling the Q point from affine coordinates. - Refreshed patches: * libgcrypt-PCT-DSA.patch * libgcrypt-PCT-RSA.patch * libgcrypt-PCT-ECC.patch - FIPS: Switch the PCT to use the new signature operation [bsc#1165539] * Patches for DSA, RSA and ECDSA test_keys functions: - libgcrypt-PCT-DSA.patch - libgcrypt-PCT-RSA.patch - libgcrypt-PCT-ECC.patch - Update patch: libgcrypt-FIPS-RSA-DSA-ECDSA-hashing-operation.patch OBS-URL: https://build.opensuse.org/request/show/805624 OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/libgcrypt?expand=0&rev=134
109 lines
3.3 KiB
Diff
109 lines
3.3 KiB
Diff
Index: libgcrypt-1.8.2/cipher/dsa.c
|
|
===================================================================
|
|
--- libgcrypt-1.8.2.orig/cipher/dsa.c
|
|
+++ libgcrypt-1.8.2/cipher/dsa.c
|
|
@@ -181,24 +181,91 @@ test_keys (DSA_secret_key *sk, unsigned
|
|
/* Create a random plaintext. */
|
|
_gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
|
|
|
|
- /* Sign DATA using the secret key. */
|
|
- sign (sig_a, sig_b, data, sk, 0, 0);
|
|
+ /* Use the gcry_pk_sign_md API in order to comply with FIPS 140-2,
|
|
+ * which requires full signature operation for PCT (hashing +
|
|
+ * asymmetric operation) */
|
|
+ gcry_sexp_t s_skey = NULL;
|
|
+ gcry_sexp_t s_pkey = NULL;
|
|
+ gcry_sexp_t r_sig = NULL;
|
|
+ gcry_sexp_t s_hash = NULL;
|
|
+ gcry_md_hd_t hd = NULL;
|
|
+ gcry_mpi_t r_sig_mpi = NULL;
|
|
+ gcry_mpi_t s_sig_mpi = NULL;
|
|
+ unsigned char *buf = NULL;
|
|
+ size_t buflen;
|
|
+
|
|
+ if (_gcry_md_open (&hd, GCRY_MD_SHA256, 0))
|
|
+ {
|
|
+ log_debug ("gcry_pk_sign failed\n");
|
|
+ goto leave;
|
|
+ }
|
|
+
|
|
+ _gcry_mpi_aprint (GCRYMPI_FMT_STD, &buf, &buflen, data);
|
|
+ _gcry_md_write (hd, buf, buflen);
|
|
+
|
|
+ xfree (buf);
|
|
+
|
|
+ /* build DSA private key sexp in s_skey */
|
|
+ sexp_build (&s_skey, NULL, "(private-key (dsa(p %m)(q %m)(g %m)(y %m)(x %m)))",
|
|
+ sk->p, sk->q, sk->g, sk->y, sk->x);
|
|
+ sexp_build (&s_hash, NULL, "(data (flags pkcs1)(hash-algo sha256))");
|
|
+ if (_gcry_pk_sign_md (&r_sig, hd, s_hash, s_skey))
|
|
+ {
|
|
+ log_debug ("gcry_pk_sign failed\n");
|
|
+ goto leave;
|
|
+ }
|
|
+
|
|
+ /* Check that the signature and the original plaintext differ. */
|
|
+ if (_gcry_sexp_extract_param (r_sig, NULL, "rs", &r_sig_mpi, &s_sig_mpi, NULL))
|
|
+ {
|
|
+ log_debug ("extracting signature data failed\n");
|
|
+ goto leave;
|
|
+ }
|
|
+
|
|
+ if ( !verify (r_sig_mpi, s_sig_mpi, data, &pk))
|
|
+ {
|
|
+ log_debug ("Signature failed\n");
|
|
+ goto leave; /* Signature matches but should not. */
|
|
+ }
|
|
+
|
|
+ _gcry_sexp_release (s_hash);
|
|
+ _gcry_md_close (hd);
|
|
+
|
|
+ /* build DSA public key sexp in s_pkey */
|
|
+ sexp_build (&s_pkey, NULL, "(public-key (dsa(p %m)(q %m)(g %m)(y %m)))",
|
|
+ pk.p, pk.q, pk.g, pk.y);
|
|
+ sexp_build (&s_hash, NULL, "(data (flags pkcs1)(hash-algo sha256))");
|
|
+
|
|
+ if (_gcry_md_open (&hd, GCRY_MD_SHA256, 0))
|
|
+ log_debug ("gcry_md_open failed\n");
|
|
+
|
|
+ _gcry_mpi_aprint (GCRYMPI_FMT_STD, &buf, &buflen, data);
|
|
+ _gcry_md_write (hd, buf, buflen);
|
|
+
|
|
+ xfree (buf);
|
|
+
|
|
+ /* verify the signature */
|
|
+ if (_gcry_pk_verify_md (r_sig, hd, s_hash, s_pkey))
|
|
+ {
|
|
+ log_debug ("gcry_pk_verify failed\n");
|
|
+ goto leave; /* Signature does not match. */
|
|
+ }
|
|
|
|
- /* Verify the signature using the public key. */
|
|
- if ( verify (sig_a, sig_b, data, &pk) )
|
|
- goto leave; /* Signature does not match. */
|
|
-
|
|
- /* Modify the data and check that the signing fails. */
|
|
- mpi_add_ui (data, data, 1);
|
|
- if ( !verify (sig_a, sig_b, data, &pk) )
|
|
- goto leave; /* Signature matches but should not. */
|
|
-
|
|
- result = 0; /* The test succeeded. */
|
|
+ result = 0; /* The test succeeded. */
|
|
|
|
leave:
|
|
_gcry_mpi_release (sig_b);
|
|
_gcry_mpi_release (sig_a);
|
|
_gcry_mpi_release (data);
|
|
+
|
|
+ _gcry_sexp_release (s_skey);
|
|
+ _gcry_sexp_release (s_pkey);
|
|
+ _gcry_sexp_release (s_hash);
|
|
+ _gcry_sexp_release (r_sig);
|
|
+ _gcry_mpi_release (r_sig_mpi);
|
|
+ _gcry_mpi_release (s_sig_mpi);
|
|
+ _gcry_md_close (hd);
|
|
+
|
|
return result;
|
|
}
|
|
|