Accepting request 805624 from home:pmonrealgonzalez:branches:devel:libraries:c_c++
- 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
This commit is contained in:
parent
e37716ed54
commit
9a7cde5372
13
libgcrypt-FIPS-GMAC_AES-benckmark.patch
Normal file
13
libgcrypt-FIPS-GMAC_AES-benckmark.patch
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
Index: libgcrypt-1.8.2/tests/benchmark.c
|
||||||
|
===================================================================
|
||||||
|
--- libgcrypt-1.8.2.orig/tests/benchmark.c
|
||||||
|
+++ libgcrypt-1.8.2/tests/benchmark.c
|
||||||
|
@@ -598,7 +598,7 @@ mac_bench ( const char *algoname )
|
||||||
|
if (!algoname)
|
||||||
|
{
|
||||||
|
for (i=1; i < 600; i++)
|
||||||
|
- if (in_fips_mode && i == GCRY_MAC_HMAC_MD5)
|
||||||
|
+ if (in_fips_mode && (i == GCRY_MAC_HMAC_MD5 || i == GCRY_MAC_GMAC_AES))
|
||||||
|
; /* Don't use MD5 in fips mode. */
|
||||||
|
else if ( !gcry_mac_test_algo (i) )
|
||||||
|
mac_bench (gcry_mac_algo_name (i));
|
@ -1,12 +1,121 @@
|
|||||||
|
Index: libgcrypt-1.8.2/cipher/pubkey.c
|
||||||
|
===================================================================
|
||||||
|
--- libgcrypt-1.8.2.orig/cipher/pubkey.c
|
||||||
|
+++ libgcrypt-1.8.2/cipher/pubkey.c
|
||||||
|
@@ -384,6 +384,33 @@ _gcry_pk_decrypt (gcry_sexp_t *r_plain,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+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;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create a signature.
|
||||||
|
@@ -414,7 +441,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 +454,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
|
||||||
|
@@ -437,6 +469,13 @@ _gcry_pk_sign (gcry_sexp_t *r_sig, gcry_
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+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 +484,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 +495,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
|
||||||
|
@@ -466,6 +510,13 @@ _gcry_pk_verify (gcry_sexp_t s_sig, gcry
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
+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.
|
||||||
|
|
||||||
Index: libgcrypt-1.8.2/cipher/pubkey-internal.h
|
Index: libgcrypt-1.8.2/cipher/pubkey-internal.h
|
||||||
===================================================================
|
===================================================================
|
||||||
--- libgcrypt-1.8.2.orig/cipher/pubkey-internal.h
|
--- libgcrypt-1.8.2.orig/cipher/pubkey-internal.h
|
||||||
+++ libgcrypt-1.8.2/cipher/pubkey-internal.h
|
+++ libgcrypt-1.8.2/cipher/pubkey-internal.h
|
||||||
@@ -43,6 +43,7 @@ void _gcry_pk_util_free_encoding_ctx (st
|
@@ -43,6 +43,8 @@ void _gcry_pk_util_free_encoding_ctx (st
|
||||||
gcry_err_code_t _gcry_pk_util_data_to_mpi (gcry_sexp_t input,
|
gcry_err_code_t _gcry_pk_util_data_to_mpi (gcry_sexp_t input,
|
||||||
gcry_mpi_t *ret_mpi,
|
gcry_mpi_t *ret_mpi,
|
||||||
struct pk_encoding_ctx *ctx);
|
struct pk_encoding_ctx *ctx);
|
||||||
+gcry_err_code_t _gcry_pk_util_get_algo (gcry_sexp_t input, int *algo);
|
+gcry_err_code_t _gcry_pk_util_get_algo (gcry_sexp_t input,
|
||||||
|
+ int *algo);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -65,121 +174,21 @@ Index: libgcrypt-1.8.2/cipher/pubkey-util.c
|
|||||||
+
|
+
|
||||||
+ return rc;
|
+ return rc;
|
||||||
+}
|
+}
|
||||||
Index: libgcrypt-1.8.2/cipher/pubkey.c
|
Index: libgcrypt-1.8.2/src/g10lib.h
|
||||||
===================================================================
|
===================================================================
|
||||||
--- libgcrypt-1.8.2.orig/cipher/pubkey.c
|
--- libgcrypt-1.8.2.orig/src/g10lib.h
|
||||||
+++ libgcrypt-1.8.2/cipher/pubkey.c
|
+++ libgcrypt-1.8.2/src/g10lib.h
|
||||||
@@ -383,6 +383,33 @@ _gcry_pk_decrypt (gcry_sexp_t *r_plain,
|
@@ -288,6 +288,10 @@ gpg_err_code_t _gcry_generate_fips186_3_
|
||||||
return rc;
|
gpg_err_code_t _gcry_fips186_4_prime_check (const gcry_mpi_t x,
|
||||||
}
|
unsigned int bits);
|
||||||
|
|
||||||
+static gcry_err_code_t
|
+gcry_err_code_t _gcry_pk_sign_md (gcry_sexp_t *r_sig, gcry_md_hd_t hd,
|
||||||
+calculate_hash (gcry_md_hd_t hd, gcry_sexp_t s_hash)
|
+ gcry_sexp_t s_hash, gcry_sexp_t s_skey);
|
||||||
+{
|
+gcry_err_code_t _gcry_pk_verify_md (gcry_sexp_t s_sig, gcry_md_hd_t hd,
|
||||||
+ gcry_err_code_t rc;
|
+ gcry_sexp_t s_hash, gcry_sexp_t s_pkey);
|
||||||
+ 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;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+
|
|
||||||
|
|
||||||
|
/* Replacements of missing functions (missing-string.c). */
|
||||||
/*
|
#ifndef HAVE_STPCPY
|
||||||
@@ -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
|
Index: libgcrypt-1.8.2/src/visibility.c
|
||||||
===================================================================
|
===================================================================
|
||||||
--- libgcrypt-1.8.2.orig/src/visibility.c
|
--- libgcrypt-1.8.2.orig/src/visibility.c
|
||||||
@ -219,3 +228,18 @@ Index: libgcrypt-1.8.2/src/visibility.c
|
|||||||
gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey)
|
gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey)
|
||||||
{
|
{
|
||||||
if (!fips_is_operational ())
|
if (!fips_is_operational ())
|
||||||
|
Index: libgcrypt-1.8.2/src/visibility.h
|
||||||
|
===================================================================
|
||||||
|
--- libgcrypt-1.8.2.orig/src/visibility.h
|
||||||
|
+++ libgcrypt-1.8.2/src/visibility.h
|
||||||
|
@@ -357,8 +357,10 @@ MARK_VISIBLEX (_gcry_mpi_get_const)
|
||||||
|
#define gcry_pk_get_param _gcry_USE_THE_UNDERSCORED_FUNCTION
|
||||||
|
#define gcry_pk_get_nbits _gcry_USE_THE_UNDERSCORED_FUNCTION
|
||||||
|
#define gcry_pk_map_name _gcry_USE_THE_UNDERSCORED_FUNCTION
|
||||||
|
+#define gcry_pk_sign_md _gcry_USE_THE_UNDERSCORED_FUNCTION
|
||||||
|
#define gcry_pk_sign _gcry_USE_THE_UNDERSCORED_FUNCTION
|
||||||
|
#define gcry_pk_testkey _gcry_USE_THE_UNDERSCORED_FUNCTION
|
||||||
|
+#define gcry_pk_verify_md _gcry_USE_THE_UNDERSCORED_FUNCTION
|
||||||
|
#define gcry_pk_verify _gcry_USE_THE_UNDERSCORED_FUNCTION
|
||||||
|
#define gcry_pubkey_get_sexp _gcry_USE_THE_UNDERSCORED_FUNCTION
|
||||||
|
|
||||||
|
108
libgcrypt-PCT-DSA.patch
Normal file
108
libgcrypt-PCT-DSA.patch
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
348
libgcrypt-PCT-ECC.patch
Normal file
348
libgcrypt-PCT-ECC.patch
Normal file
@ -0,0 +1,348 @@
|
|||||||
|
Index: libgcrypt-1.8.2/cipher/ecc.c
|
||||||
|
===================================================================
|
||||||
|
--- libgcrypt-1.8.2.orig/cipher/ecc.c
|
||||||
|
+++ libgcrypt-1.8.2/cipher/ecc.c
|
||||||
|
@@ -99,7 +99,7 @@ static void *progress_cb_data;
|
||||||
|
|
||||||
|
|
||||||
|
/* Local prototypes. */
|
||||||
|
-static void test_keys (ECC_secret_key * sk, unsigned int nbits);
|
||||||
|
+static int test_keys (ECC_secret_key * sk, unsigned int nbits);
|
||||||
|
static void test_ecdh_only_keys (ECC_secret_key * sk, unsigned int nbits, int flags);
|
||||||
|
static unsigned int ecc_get_nbits (gcry_sexp_t parms);
|
||||||
|
|
||||||
|
@@ -152,6 +152,7 @@ nist_generate_key (ECC_secret_key *sk, e
|
||||||
|
gcry_random_level_t random_level;
|
||||||
|
gcry_mpi_t x, y;
|
||||||
|
const unsigned int pbits = mpi_get_nbits (E->p);
|
||||||
|
+ int free_skEname = 0;
|
||||||
|
|
||||||
|
point_init (&Q);
|
||||||
|
|
||||||
|
@@ -176,7 +177,6 @@ nist_generate_key (ECC_secret_key *sk, e
|
||||||
|
else
|
||||||
|
sk->d = _gcry_dsa_gen_k (E->n, random_level);
|
||||||
|
|
||||||
|
-
|
||||||
|
/* Compute Q. */
|
||||||
|
_gcry_mpi_ec_mul_point (&Q, sk->d, &E->G, ctx);
|
||||||
|
|
||||||
|
@@ -190,6 +190,12 @@ nist_generate_key (ECC_secret_key *sk, e
|
||||||
|
point_set (&sk->E.G, &E->G);
|
||||||
|
sk->E.n = mpi_copy (E->n);
|
||||||
|
sk->E.h = mpi_copy (E->h);
|
||||||
|
+ if (E->name)
|
||||||
|
+ {
|
||||||
|
+ free_skEname = 1;
|
||||||
|
+ sk->E.name = _gcry_xstrdup(E->name);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
point_init (&sk->Q);
|
||||||
|
|
||||||
|
x = mpi_new (pbits);
|
||||||
|
@@ -261,10 +267,16 @@ nist_generate_key (ECC_secret_key *sk, e
|
||||||
|
if ((flags & PUBKEY_FLAG_NO_KEYTEST))
|
||||||
|
; /* User requested to skip the test. */
|
||||||
|
else if (sk->E.model != MPI_EC_MONTGOMERY)
|
||||||
|
- test_keys (sk, nbits - 64);
|
||||||
|
+ {
|
||||||
|
+ if (test_keys (sk, nbits - 64))
|
||||||
|
+ return GPG_ERR_BAD_SIGNATURE;
|
||||||
|
+ }
|
||||||
|
else
|
||||||
|
test_ecdh_only_keys (sk, nbits - 64, flags);
|
||||||
|
|
||||||
|
+ if (free_skEname)
|
||||||
|
+ xfree ((void*)sk->E.name);
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -275,9 +287,10 @@ nist_generate_key (ECC_secret_key *sk, e
|
||||||
|
* test if the information is recuperated.
|
||||||
|
* Second, test with the sign and verify functions.
|
||||||
|
*/
|
||||||
|
-static void
|
||||||
|
+static int
|
||||||
|
test_keys (ECC_secret_key *sk, unsigned int nbits)
|
||||||
|
{
|
||||||
|
+ int result = -1; /* Default to failure. */
|
||||||
|
ECC_public_key pk;
|
||||||
|
gcry_mpi_t test = mpi_new (nbits);
|
||||||
|
mpi_point_struct R_;
|
||||||
|
@@ -297,17 +310,161 @@ test_keys (ECC_secret_key *sk, unsigned
|
||||||
|
|
||||||
|
_gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
|
||||||
|
|
||||||
|
- if (_gcry_ecc_ecdsa_sign (test, sk, r, s, 0, 0) )
|
||||||
|
- log_fatal ("ECDSA operation: sign failed\n");
|
||||||
|
+ /* 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 r_sig = NULL;
|
||||||
|
+ gcry_sexp_t s_skey = NULL;
|
||||||
|
+ gcry_sexp_t s_pkey = NULL;
|
||||||
|
+ gcry_sexp_t s_hash = NULL;
|
||||||
|
+ gcry_mpi_t s_sig_mpi = NULL;
|
||||||
|
+ gcry_md_hd_t hd = NULL;
|
||||||
|
+ unsigned char *buf = NULL;
|
||||||
|
+ size_t buflen;
|
||||||
|
+ mpi_ec_t ctx;
|
||||||
|
+ int flags = 0;
|
||||||
|
+
|
||||||
|
+ if (_gcry_md_open (&hd, GCRY_MD_SHA256, 0))
|
||||||
|
+ log_debug ("gcry_pk_sign failed: _gcry_md_open\n");
|
||||||
|
+
|
||||||
|
+ _gcry_mpi_aprint (GCRYMPI_FMT_STD, &buf, &buflen, test);
|
||||||
|
+ _gcry_md_write (hd, buf, buflen);
|
||||||
|
+
|
||||||
|
+ xfree (buf);
|
||||||
|
+
|
||||||
|
+ sexp_build (&s_hash, NULL, "(data (flags rfc6979)(hash-algo sha256))");
|
||||||
|
+
|
||||||
|
+ /* Assemble the point Q from affine coordinates by simple
|
||||||
|
+ * concatenation. */
|
||||||
|
+ gcry_mpi_t Qx = NULL;
|
||||||
|
+ gcry_mpi_t Qy = NULL;
|
||||||
|
+ Qx = mpi_new (0);
|
||||||
|
+ Qy = mpi_new (0);
|
||||||
|
+ ctx = _gcry_mpi_ec_p_internal_new (sk->E.model, sk->E.dialect, flags,
|
||||||
|
+ sk->E.p, sk->E.a, sk->E.b);
|
||||||
|
+ if (_gcry_mpi_ec_get_affine (Qx, Qy, &(sk->Q), ctx))
|
||||||
|
+ log_debug ("ecdh: Failed to get affine coordinates for Q\n");
|
||||||
|
+
|
||||||
|
+ unsigned char *rawqx, *rawqy;
|
||||||
|
+ unsigned int rawqxlen, rawqylen;
|
||||||
|
+ rawqx = _gcry_mpi_get_buffer (Qx, 0, &rawqxlen, NULL);
|
||||||
|
+ rawqy = _gcry_mpi_get_buffer (Qy, 0, &rawqylen, NULL);
|
||||||
|
+
|
||||||
|
+ if (rawqxlen != rawqylen)
|
||||||
|
+ {
|
||||||
|
+ // log_debug ("qx and qy size differ: %d != %d\n", rawqxlen, rawqylen);
|
||||||
|
+ if (rawqxlen < rawqylen)
|
||||||
|
+ {
|
||||||
|
+ size_t diff = rawqylen - rawqxlen;
|
||||||
|
+ unsigned char *zeros = xmalloc (rawqxlen + diff);
|
||||||
|
+ memset (zeros, 0, rawqxlen + diff);
|
||||||
|
+ memmove (zeros + diff, rawqx, rawqxlen);
|
||||||
|
+ xfree (rawqx);
|
||||||
|
+ rawqx = zeros;
|
||||||
|
+ rawqxlen += diff;
|
||||||
|
+ }
|
||||||
|
+ if (rawqylen < rawqxlen)
|
||||||
|
+ {
|
||||||
|
+ size_t diff = rawqxlen - rawqylen;
|
||||||
|
+ unsigned char *zeros = xmalloc (rawqylen + diff);
|
||||||
|
+ memset (zeros, 0, rawqylen + diff);
|
||||||
|
+ memmove (zeros + diff, rawqy, rawqylen);
|
||||||
|
+ xfree (rawqy);
|
||||||
|
+ rawqy = zeros;
|
||||||
|
+ rawqylen += diff;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ unsigned char q[1 + rawqxlen + rawqxlen];
|
||||||
|
+ size_t qlen;
|
||||||
|
+ memset (&q, 0, sizeof(q));
|
||||||
|
+ *q = 4;
|
||||||
|
+ memcpy (q + 1, rawqx, rawqxlen);
|
||||||
|
+ memcpy (q + 1 + rawqxlen, rawqy, rawqylen);
|
||||||
|
+ qlen = 1 + rawqxlen + rawqylen;
|
||||||
|
+
|
||||||
|
+ _gcry_mpi_release (Qx);
|
||||||
|
+ _gcry_mpi_release (Qy);
|
||||||
|
+ xfree (rawqx);
|
||||||
|
+ xfree (rawqy);
|
||||||
|
|
||||||
|
- if (_gcry_ecc_ecdsa_verify (test, &pk, r, s))
|
||||||
|
+ /* build ECC private key sexp in s_skey */
|
||||||
|
+ if (sk->E.name)
|
||||||
|
{
|
||||||
|
- log_fatal ("ECDSA operation: sign, verify failed\n");
|
||||||
|
+ if (sexp_build (&s_skey, NULL,
|
||||||
|
+ "(private-key (ecc (curve %s)(d %m)(q %b)))",
|
||||||
|
+ sk->E.name, sk->d, qlen, q))
|
||||||
|
+ log_debug ("ecc: Failed to build sexp for private key.\n");
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ if (sexp_build (&s_skey, NULL,
|
||||||
|
+ "(private-key"
|
||||||
|
+ " (ecc (curve %s)(d %m)(p %m)(a %m)(b %m)(n %m)(h %m)(q %b)))",
|
||||||
|
+ "NIST P-512", sk->d, sk->E.p, sk->E.a, sk->E.b, sk->E.n, sk->E.h,
|
||||||
|
+ qlen, q))
|
||||||
|
+ log_debug ("ecc: Failed to build sexp for private key.\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (_gcry_pk_sign_md (&r_sig, hd, s_hash, s_skey))
|
||||||
|
+ {
|
||||||
|
+ log_debug ("ecc: gcry_pk_sign failed\n");
|
||||||
|
+ goto leave;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Check that the signature and the original test differ. */
|
||||||
|
+ if (_gcry_sexp_extract_param (r_sig, NULL, "s", &s_sig_mpi, NULL))
|
||||||
|
+ {
|
||||||
|
+ log_debug ("extracting signature data failed\n");
|
||||||
|
+ goto leave;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!mpi_cmp (s_sig_mpi, test))
|
||||||
|
+ {
|
||||||
|
+ log_debug ("Signature failed\n");
|
||||||
|
+ goto leave; /* Signature and test match but should not. */
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* verify */
|
||||||
|
+ /* build public key sexp in s_pkey */
|
||||||
|
+ if (pk.E.name)
|
||||||
|
+ {
|
||||||
|
+ if (sexp_build (&s_pkey, NULL,
|
||||||
|
+ "(public-key (ecc (curve %s)(q %b)))", pk.E.name, qlen, q))
|
||||||
|
+ log_debug ("ecc: Failed to build sexp for public key.\n");
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ if (sexp_build (&s_pkey, NULL,
|
||||||
|
+ "(public-key"
|
||||||
|
+ " (ecc (curve %s)(p %m)(a %m)(b %m)(n %m)(h %m)(q %b)))",
|
||||||
|
+ "NIST P-512", pk.E.p, pk.E.a, pk.E.b, pk.E.n, pk.E.h, qlen, q))
|
||||||
|
+ log_debug ("ecc: Failed to build sexp for private key.\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _gcry_md_close (hd);
|
||||||
|
+
|
||||||
|
+ if (_gcry_md_open (&hd, GCRY_MD_SHA256, 0))
|
||||||
|
+ log_debug ("gcry_pk_verify failed: _gcry_md_open\n");
|
||||||
|
+
|
||||||
|
+ _gcry_mpi_aprint (GCRYMPI_FMT_STD, &buf, &buflen, test);
|
||||||
|
+ _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 ("ecc: gcry_pk_verify failed\n");
|
||||||
|
+ goto leave; /* Signature does not match. */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DBG_CIPHER)
|
||||||
|
log_debug ("ECDSA operation: sign, verify ok.\n");
|
||||||
|
|
||||||
|
+ result = 0; /* The test succeeded. */
|
||||||
|
+
|
||||||
|
+ leave:
|
||||||
|
point_free (&pk.Q);
|
||||||
|
_gcry_ecc_curve_free (&pk.E);
|
||||||
|
|
||||||
|
@@ -317,6 +474,16 @@ test_keys (ECC_secret_key *sk, unsigned
|
||||||
|
mpi_free (out);
|
||||||
|
mpi_free (c);
|
||||||
|
mpi_free (test);
|
||||||
|
+
|
||||||
|
+ _gcry_sexp_release (r_sig);
|
||||||
|
+ _gcry_sexp_release (s_skey);
|
||||||
|
+ _gcry_sexp_release (s_pkey);
|
||||||
|
+ _gcry_sexp_release (s_hash);
|
||||||
|
+ _gcry_mpi_release (s_sig_mpi);
|
||||||
|
+ _gcry_md_close (hd);
|
||||||
|
+ xfree (ctx);
|
||||||
|
+
|
||||||
|
+ return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Index: libgcrypt-1.8.2/cipher/pubkey.c
|
||||||
|
===================================================================
|
||||||
|
--- libgcrypt-1.8.2.orig/cipher/pubkey.c
|
||||||
|
+++ libgcrypt-1.8.2/cipher/pubkey.c
|
||||||
|
@@ -390,6 +390,7 @@ calculate_hash (gcry_md_hd_t hd, gcry_se
|
||||||
|
gcry_err_code_t rc;
|
||||||
|
const unsigned char *digest;
|
||||||
|
int algo;
|
||||||
|
+ const char *flags;
|
||||||
|
|
||||||
|
if (!hd)
|
||||||
|
return 0;
|
||||||
|
@@ -398,16 +399,21 @@ calculate_hash (gcry_md_hd_t hd, gcry_se
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
+ rc = _gcry_pk_util_get_flags (*s_hash, &flags);
|
||||||
|
+ 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))",
|
||||||
|
+ "(data (flags %s)(hash %s %b))", flags,
|
||||||
|
_gcry_md_algo_name(algo),
|
||||||
|
(int) _gcry_md_get_algo_dlen(algo),
|
||||||
|
digest);
|
||||||
|
|
||||||
|
+ xfree ((void *)flags);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
@@ -45,6 +45,8 @@ gcry_err_code_t _gcry_pk_util_data_to_mp
|
||||||
|
struct pk_encoding_ctx *ctx);
|
||||||
|
gcry_err_code_t _gcry_pk_util_get_algo (gcry_sexp_t input,
|
||||||
|
int *algo);
|
||||||
|
+gcry_err_code_t _gcry_pk_util_get_flags (gcry_sexp_t input,
|
||||||
|
+ const char **flags);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
@@ -1120,6 +1120,40 @@ _gcry_pk_util_data_to_mpi (gcry_sexp_t i
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
+gcry_err_code_t
|
||||||
|
+_gcry_pk_util_get_flags (gcry_sexp_t input, const char **flags)
|
||||||
|
+{
|
||||||
|
+ gcry_err_code_t rc = 0;
|
||||||
|
+ gcry_sexp_t ldata, list = NULL;
|
||||||
|
+
|
||||||
|
+ ldata = sexp_find_token (input, "data", 0);
|
||||||
|
+ if (!ldata)
|
||||||
|
+ {
|
||||||
|
+ rc = GPG_ERR_INV_OBJ;
|
||||||
|
+ goto leave;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ list = sexp_find_token (ldata, "flags", 0);
|
||||||
|
+ if (!list)
|
||||||
|
+ {
|
||||||
|
+ rc = GPG_ERR_INV_OBJ;
|
||||||
|
+ goto leave;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* FIXME: gets only the first flag */
|
||||||
|
+ *flags = sexp_nth_string (list, 1);
|
||||||
|
+ if (!*flags)
|
||||||
|
+ {
|
||||||
|
+ rc = GPG_ERR_NO_OBJ;
|
||||||
|
+ goto leave;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ leave:
|
||||||
|
+ sexp_release (ldata);
|
||||||
|
+ sexp_release (list);
|
||||||
|
+
|
||||||
|
+ return rc;
|
||||||
|
+}
|
||||||
|
|
||||||
|
gcry_err_code_t
|
||||||
|
_gcry_pk_util_get_algo (gcry_sexp_t input, int *algo)
|
119
libgcrypt-PCT-RSA.patch
Normal file
119
libgcrypt-PCT-RSA.patch
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
Index: libgcrypt-1.8.2/cipher/rsa.c
|
||||||
|
===================================================================
|
||||||
|
--- libgcrypt-1.8.2.orig/cipher/rsa.c
|
||||||
|
+++ libgcrypt-1.8.2/cipher/rsa.c
|
||||||
|
@@ -159,27 +159,93 @@ test_keys (RSA_secret_key *sk, unsigned
|
||||||
|
/* Create another random plaintext as data for signature checking. */
|
||||||
|
_gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
|
||||||
|
|
||||||
|
- /* Use the RSA secret function to create a signature of the plaintext. */
|
||||||
|
- secret (signature, plaintext, sk);
|
||||||
|
+ /* 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;
|
||||||
|
+ unsigned char *buf = NULL;
|
||||||
|
+ size_t buflen;
|
||||||
|
|
||||||
|
- /* Use the RSA public function to verify this signature. */
|
||||||
|
- public (decr_plaintext, signature, &pk);
|
||||||
|
- if (mpi_cmp (decr_plaintext, plaintext))
|
||||||
|
- goto leave; /* Signature does not match. */
|
||||||
|
-
|
||||||
|
- /* Modify the signature and check that the signing fails. */
|
||||||
|
- mpi_add_ui (signature, signature, 1);
|
||||||
|
- public (decr_plaintext, signature, &pk);
|
||||||
|
- if (!mpi_cmp (decr_plaintext, plaintext))
|
||||||
|
- goto leave; /* Signature matches but should not. */
|
||||||
|
+ if (_gcry_md_open (&hd, GCRY_MD_SHA256, 0))
|
||||||
|
+ {
|
||||||
|
+ log_debug ("gcry_pk_sign failed\n");
|
||||||
|
+ goto leave_hash;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _gcry_mpi_aprint (GCRYMPI_FMT_STD, &buf, &buflen, plaintext);
|
||||||
|
+ _gcry_md_write (hd, buf, buflen);
|
||||||
|
+
|
||||||
|
+ xfree (buf);
|
||||||
|
+
|
||||||
|
+ /* build RSA private key sexp in s_skey */
|
||||||
|
+ sexp_build (&s_skey, NULL,
|
||||||
|
+ "(private-key (rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
|
||||||
|
+ sk->n, sk->e, sk->d, sk->p, sk->q);
|
||||||
|
+ 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_hash;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Check that the signature and the original plaintext differ. */
|
||||||
|
+ if (_gcry_sexp_extract_param (r_sig, "sig-val!rsa", "s", &r_sig_mpi, NULL))
|
||||||
|
+ {
|
||||||
|
+ log_debug ("extracting signature data failed\n");
|
||||||
|
+ goto leave_hash;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!mpi_cmp (r_sig_mpi, plaintext))
|
||||||
|
+ {
|
||||||
|
+ log_debug ("Signature failed\n");
|
||||||
|
+ goto leave_hash; /* Signature and plaintext match but should not. */
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _gcry_sexp_release (s_hash);
|
||||||
|
+ _gcry_md_close (hd);
|
||||||
|
+
|
||||||
|
+ /* build RSA public key sexp in s_pkey */
|
||||||
|
+ sexp_build (&s_pkey, NULL, "(public-key (rsa(n %m)(e %m)))", pk.n, pk.e);
|
||||||
|
+ 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, plaintext);
|
||||||
|
+ _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_hash; /* Signature does not match. */
|
||||||
|
+ }
|
||||||
|
|
||||||
|
result = 0; /* All tests succeeded. */
|
||||||
|
|
||||||
|
+ leave_hash:
|
||||||
|
+ _gcry_sexp_release (s_skey);
|
||||||
|
+ _gcry_sexp_release (s_pkey);
|
||||||
|
+ _gcry_sexp_release (s_hash);
|
||||||
|
+ _gcry_sexp_release (r_sig);
|
||||||
|
+ _gcry_md_close (hd);
|
||||||
|
+ _gcry_mpi_release (r_sig_mpi);
|
||||||
|
+
|
||||||
|
leave:
|
||||||
|
_gcry_mpi_release (signature);
|
||||||
|
_gcry_mpi_release (decr_plaintext);
|
||||||
|
_gcry_mpi_release (ciphertext);
|
||||||
|
_gcry_mpi_release (plaintext);
|
||||||
|
+
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1903,7 +1969,7 @@ selftest_encr_2048 (gcry_sexp_t pkey, gc
|
||||||
|
/* This sexp trickery is to prevent the use of blinding.
|
||||||
|
* The flag doesn't get inherited by encr, so we have to
|
||||||
|
* derive a new sexp from the ciphertext */
|
||||||
|
- char buf[1024];
|
||||||
|
+ unsigned char buf[1024];
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
err = _gcry_mpi_print (GCRYMPI_FMT_STD, buf, sizeof buf, NULL, ciphertext);
|
||||||
|
if (err)
|
16
libgcrypt-Restore-self-tests-from-constructor.patch
Normal file
16
libgcrypt-Restore-self-tests-from-constructor.patch
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
Index: libgcrypt-1.8.2/src/global.c
|
||||||
|
===================================================================
|
||||||
|
--- libgcrypt-1.8.2.orig/src/global.c
|
||||||
|
+++ libgcrypt-1.8.2/src/global.c
|
||||||
|
@@ -140,8 +140,9 @@ global_init (void)
|
||||||
|
/* We always need the FSM lock to be functional. */
|
||||||
|
_gcry_initialize_fsm_lock ();
|
||||||
|
|
||||||
|
- /* Run the self-tests from the constructor. */
|
||||||
|
- global_init ();
|
||||||
|
+ /* We run the integrity check at this point. The remaining
|
||||||
|
+ selftests are run before use of the library by application. */
|
||||||
|
+ _gcry_fips_run_selftests (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is called by the macro fips_is_operational and makes
|
@ -1,84 +0,0 @@
|
|||||||
Index: libgcrypt-1.8.2/src/fips.c
|
|
||||||
===================================================================
|
|
||||||
--- libgcrypt-1.8.2.orig/src/fips.c 2019-03-27 13:15:14.190987624 +0100
|
|
||||||
+++ libgcrypt-1.8.2/src/fips.c 2019-03-27 13:18:07.047986428 +0100
|
|
||||||
@@ -115,6 +115,50 @@ _gcry_initialize_fsm_lock (void)
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+/* Checks whether the library will enter the FIPS mode.
|
|
||||||
+ Uses the same logic as _gcry_initialize_fips_mode */
|
|
||||||
+static int
|
|
||||||
+will_enter_fips (void)
|
|
||||||
+{
|
|
||||||
+ /* for convenience, so that a process can run fips-enabled, but
|
|
||||||
+ not necessarily all of them, enable FIPS mode via environment
|
|
||||||
+ variable LIBGCRYPT_FORCE_FIPS_MODE. */
|
|
||||||
+ if (getenv("LIBGCRYPT_FORCE_FIPS_MODE") != NULL)
|
|
||||||
+ return 1;
|
|
||||||
+
|
|
||||||
+ /* For testing the system it is useful to override the system
|
|
||||||
+ provided detection of the FIPS mode and force FIPS mode using a
|
|
||||||
+ file. The filename is hardwired so that there won't be any
|
|
||||||
+ confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is
|
|
||||||
+ actually used. The file itself may be empty. */
|
|
||||||
+ if ( !access (FIPS_FORCE_FILE, F_OK) )
|
|
||||||
+ return 1;
|
|
||||||
+
|
|
||||||
+ /* Checking based on /proc file properties. */
|
|
||||||
+ {
|
|
||||||
+ static const char procfname[] = "/proc/sys/crypto/fips_enabled";
|
|
||||||
+ FILE *fp;
|
|
||||||
+
|
|
||||||
+ fp = fopen (procfname, "r");
|
|
||||||
+ if (fp)
|
|
||||||
+ {
|
|
||||||
+ char line[256];
|
|
||||||
+
|
|
||||||
+ if (fgets (line, sizeof line, fp) && atoi (line))
|
|
||||||
+ {
|
|
||||||
+ /* System is in fips mode. */
|
|
||||||
+ fclose (fp);
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+ fclose (fp);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
|
|
||||||
/* Check whether the OS is in FIPS mode and record that in a module
|
|
||||||
local variable. If FORCE is passed as true, fips mode will be
|
|
||||||
@@ -631,10 +675,10 @@ get_library_path(const char *libname, co
|
|
||||||
|
|
||||||
/* Run an integrity check on the binary. Returns 0 on success. */
|
|
||||||
static int
|
|
||||||
-check_binary_integrity (void)
|
|
||||||
+check_binary_integrity ()
|
|
||||||
{
|
|
||||||
#ifdef ENABLE_HMAC_BINARY_CHECK
|
|
||||||
- gpg_error_t err;
|
|
||||||
+ gpg_error_t err = 0;
|
|
||||||
char libpath[4096];
|
|
||||||
unsigned char digest[32];
|
|
||||||
int dlen;
|
|
||||||
@@ -675,7 +719,14 @@ check_binary_integrity (void)
|
|
||||||
/* Open the file. */
|
|
||||||
fp = fopen (fname, "r");
|
|
||||||
if (!fp)
|
|
||||||
- err = gpg_error_from_syserror ();
|
|
||||||
+ {
|
|
||||||
+ /* Missing checksum is a problem only in FIPS mode.
|
|
||||||
+ As the integrity check was moved to the POWERON state,
|
|
||||||
+ we no longer can rely on fips_mode(). Because at the point,
|
|
||||||
+ the library is not yet initialized. */
|
|
||||||
+ if (will_enter_fips() || errno != ENOENT)
|
|
||||||
+ err = gpg_error_from_syserror ();
|
|
||||||
+ }
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* A buffer of 64 bytes plus one for a LF and one to
|
|
84
libgcrypt-ecc-ecdsa-no-blinding.patch
Normal file
84
libgcrypt-ecc-ecdsa-no-blinding.patch
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
Index: libgcrypt-1.8.5/cipher/ecc.c
|
||||||
|
===================================================================
|
||||||
|
--- libgcrypt-1.8.5.orig/cipher/ecc.c
|
||||||
|
+++ libgcrypt-1.8.5/cipher/ecc.c
|
||||||
|
@@ -2060,11 +2060,11 @@ selftest_sign (gcry_sexp_t pkey, gcry_se
|
||||||
|
{
|
||||||
|
/* Sample data from RFC 6979 section A.2.5, hash is of message "sample" */
|
||||||
|
static const char sample_data[] =
|
||||||
|
- "(data (flags rfc6979)"
|
||||||
|
+ "(data (flags rfc6979 no-blinding)"
|
||||||
|
" (hash sha256 #af2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e98915"
|
||||||
|
/**/ "62113d8a62add1bf#))";
|
||||||
|
static const char sample_data_bad[] =
|
||||||
|
- "(data (flags rfc6979)"
|
||||||
|
+ "(data (flags rfc6979 no-blinding)"
|
||||||
|
" (hash sha256 #bf2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e98915"
|
||||||
|
/**/ "62113d8a62add1bf#))";
|
||||||
|
static const char signature_r[] =
|
||||||
|
Index: libgcrypt-1.8.5/cipher/ecc-ecdsa.c
|
||||||
|
===================================================================
|
||||||
|
--- libgcrypt-1.8.5.orig/cipher/ecc-ecdsa.c
|
||||||
|
+++ libgcrypt-1.8.5/cipher/ecc-ecdsa.c
|
||||||
|
@@ -52,6 +52,7 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input,
|
||||||
|
mpi_ec_t ctx;
|
||||||
|
gcry_mpi_t b; /* Random number needed for blinding. */
|
||||||
|
gcry_mpi_t bi; /* multiplicative inverse of B. */
|
||||||
|
+ int with_blinding = !(flags & PUBKEY_FLAG_NO_BLINDING);
|
||||||
|
|
||||||
|
if (DBG_CIPHER)
|
||||||
|
log_mpidump ("ecdsa sign hash ", input );
|
||||||
|
@@ -65,12 +66,15 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input,
|
||||||
|
|
||||||
|
b = mpi_snew (qbits);
|
||||||
|
bi = mpi_snew (qbits);
|
||||||
|
- do
|
||||||
|
+ if (with_blinding)
|
||||||
|
{
|
||||||
|
- _gcry_mpi_randomize (b, qbits, GCRY_WEAK_RANDOM);
|
||||||
|
- mpi_mod (b, b, skey->E.n);
|
||||||
|
+ do
|
||||||
|
+ {
|
||||||
|
+ _gcry_mpi_randomize (b, qbits, GCRY_WEAK_RANDOM);
|
||||||
|
+ mpi_mod (b, b, skey->E.n);
|
||||||
|
+ }
|
||||||
|
+ while (!mpi_invm (bi, b, skey->E.n));
|
||||||
|
}
|
||||||
|
- while (!mpi_invm (bi, b, skey->E.n));
|
||||||
|
|
||||||
|
k = NULL;
|
||||||
|
dr = mpi_alloc (0);
|
||||||
|
@@ -128,15 +132,26 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input,
|
||||||
|
}
|
||||||
|
while (!mpi_cmp_ui (r, 0));
|
||||||
|
|
||||||
|
- /* Computation of dr, sum, and s are blinded with b. */
|
||||||
|
- mpi_mulm (dr, b, skey->d, skey->E.n);
|
||||||
|
- mpi_mulm (dr, dr, r, skey->E.n); /* dr = d*r mod n */
|
||||||
|
- mpi_mulm (sum, b, hash, skey->E.n);
|
||||||
|
- mpi_addm (sum, sum, dr, skey->E.n); /* sum = hash + (d*r) mod n */
|
||||||
|
+ if (!with_blinding)
|
||||||
|
+ {
|
||||||
|
+ mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n */
|
||||||
|
+ mpi_addm (sum, hash, dr, skey->E.n); /* sum = hash + (d*r) mod n */
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ /* Computation of dr, sum, and s are blinded with b. */
|
||||||
|
+ mpi_mulm (dr, b, skey->d, skey->E.n);
|
||||||
|
+ mpi_mulm (dr, dr, r, skey->E.n); /* dr = d*r mod n */
|
||||||
|
+ mpi_mulm (sum, b, hash, skey->E.n);
|
||||||
|
+ mpi_addm (sum, sum, dr, skey->E.n); /* sum = hash + (d*r) mod n */
|
||||||
|
+ }
|
||||||
|
mpi_invm (k_1, k, skey->E.n); /* k_1 = k^(-1) mod n */
|
||||||
|
mpi_mulm (s, k_1, sum, skey->E.n); /* s = k^(-1)*(hash+(d*r)) mod n */
|
||||||
|
- /* Undo blinding by b^-1 */
|
||||||
|
- mpi_mulm (s, bi, s, skey->E.n);
|
||||||
|
+ if (with_blinding)
|
||||||
|
+ {
|
||||||
|
+ /* Undo blinding by b^-1 */
|
||||||
|
+ mpi_mulm (s, bi, s, skey->E.n);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
while (!mpi_cmp_ui (s, 0));
|
||||||
|
|
40
libgcrypt-fips_selftest_trigger_file.patch
Normal file
40
libgcrypt-fips_selftest_trigger_file.patch
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
Index: libgcrypt-1.8.2/src/fips.c
|
||||||
|
===================================================================
|
||||||
|
--- libgcrypt-1.8.2.orig/src/fips.c 2020-04-16 21:15:01.633217969 +0200
|
||||||
|
+++ libgcrypt-1.8.2/src/fips.c 2020-04-16 21:21:44.279376166 +0200
|
||||||
|
@@ -651,7 +651,7 @@ get_library_path(const char *libname, co
|
||||||
|
}
|
||||||
|
|
||||||
|
static gpg_error_t
|
||||||
|
-get_hmac_path(char **fname)
|
||||||
|
+get_hmac_path(char **fname, char *suffix)
|
||||||
|
{
|
||||||
|
char libpath[4096];
|
||||||
|
gpg_error_t err;
|
||||||
|
@@ -676,7 +676,7 @@ get_hmac_path(char **fname)
|
||||||
|
p = *fname;
|
||||||
|
memmove (p+1, p, strlen (p)+1);
|
||||||
|
*p = '.';
|
||||||
|
- strcat (*fname, ".hmac");
|
||||||
|
+ strcat (*fname, suffix);
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -708,7 +708,7 @@ check_binary_integrity (void)
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
- err = get_hmac_path(&fname);
|
||||||
|
+ err = get_hmac_path(&fname, ".hmac");
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
/* Open the file. */
|
||||||
|
@@ -769,7 +769,7 @@ can_skip_selftests(void)
|
||||||
|
if (fips_mode())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- if (get_hmac_path(&fname))
|
||||||
|
+ if (get_hmac_path(&fname, ".fips"))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* check the hmac presence */
|
270
libgcrypt-global_init-constructor.patch
Normal file
270
libgcrypt-global_init-constructor.patch
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
Index: libgcrypt-1.8.2/src/global.c
|
||||||
|
===================================================================
|
||||||
|
--- libgcrypt-1.8.2.orig/src/global.c 2020-04-16 21:13:28.252717330 +0200
|
||||||
|
+++ libgcrypt-1.8.2/src/global.c 2020-04-16 21:13:47.960822991 +0200
|
||||||
|
@@ -86,7 +86,7 @@ static gpg_err_code_t external_lock_test
|
||||||
|
likely to be called at startup. The suggested way for an
|
||||||
|
application to make sure that this has been called is by using
|
||||||
|
gcry_check_version. */
|
||||||
|
-static void
|
||||||
|
+static void __attribute__((constructor))
|
||||||
|
global_init (void)
|
||||||
|
{
|
||||||
|
gcry_error_t err = 0;
|
||||||
|
@@ -134,6 +134,16 @@ global_init (void)
|
||||||
|
if (err)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
+ int no_secmem_save;
|
||||||
|
+ /* it should be always 0 at this point but let's keep on the safe side */
|
||||||
|
+ no_secmem_save = no_secure_memory;
|
||||||
|
+ no_secure_memory = 1;
|
||||||
|
+ err = _gcry_fips_run_selftests (0);
|
||||||
|
+ no_secure_memory = no_secmem_save;
|
||||||
|
+
|
||||||
|
+ if (err)
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
@@ -141,16 +151,6 @@ global_init (void)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-void __attribute__ ((constructor)) _gcry_global_constructor (void)
|
||||||
|
-{
|
||||||
|
- /* We always need the FSM lock to be functional. */
|
||||||
|
- _gcry_initialize_fsm_lock ();
|
||||||
|
-
|
||||||
|
- /* We run the integrity check at this point. The remaining
|
||||||
|
- selftests are run before use of the library by application. */
|
||||||
|
- _gcry_fips_run_selftests (0);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/* This function is called by the macro fips_is_operational and makes
|
||||||
|
sure that the minimal initialization has been done. This is far
|
||||||
|
from a perfect solution and hides problems with an improper
|
||||||
|
Index: libgcrypt-1.8.2/src/fips.c
|
||||||
|
===================================================================
|
||||||
|
--- libgcrypt-1.8.2.orig/src/fips.c 2020-04-16 21:13:28.252717330 +0200
|
||||||
|
+++ libgcrypt-1.8.2/src/fips.c 2020-04-16 21:14:44.781127616 +0200
|
||||||
|
@@ -125,6 +125,7 @@ void
|
||||||
|
_gcry_initialize_fips_mode (int force)
|
||||||
|
{
|
||||||
|
static int done;
|
||||||
|
+ gpg_error_t err;
|
||||||
|
|
||||||
|
/* Make sure we are not accidentally called twice. */
|
||||||
|
if (done)
|
||||||
|
@@ -214,6 +215,23 @@ _gcry_initialize_fips_mode (int force)
|
||||||
|
/* Yes, we are in FIPS mode. */
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
+ /* Intitialize the lock to protect the FSM. */
|
||||||
|
+ err = gpgrt_lock_init (&fsm_lock);
|
||||||
|
+ if (err)
|
||||||
|
+ {
|
||||||
|
+ /* If that fails we can't do anything but abort the
|
||||||
|
+ process. We need to use log_info so that the FSM won't
|
||||||
|
+ get involved. */
|
||||||
|
+ log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n",
|
||||||
|
+ gpg_strerror (err));
|
||||||
|
+#ifdef HAVE_SYSLOG
|
||||||
|
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
|
||||||
|
+ "creating FSM lock failed: %s - abort",
|
||||||
|
+ gpg_strerror (err));
|
||||||
|
+#endif /*HAVE_SYSLOG*/
|
||||||
|
+ abort ();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* If the FIPS force files exists, is readable and has a number
|
||||||
|
!= 0 on its first line, we enable the enforced fips mode. */
|
||||||
|
fp = fopen (FIPS_FORCE_FILE, "r");
|
||||||
|
@@ -614,10 +632,10 @@ get_library_path(const char *libname, co
|
||||||
|
void *dl, *sym;
|
||||||
|
int rv = -1;
|
||||||
|
|
||||||
|
- dl = dlopen(libname, RTLD_LAZY);
|
||||||
|
- if (dl == NULL) {
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
+ dl = dlopen(libname, RTLD_LAZY);
|
||||||
|
+ if (dl == NULL) {
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
sym = dlsym(dl, symbolname);
|
||||||
|
|
||||||
|
@@ -632,6 +650,39 @@ get_library_path(const char *libname, co
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static gpg_error_t
|
||||||
|
+get_hmac_path(char **fname)
|
||||||
|
+{
|
||||||
|
+ char libpath[4096];
|
||||||
|
+ gpg_error_t err;
|
||||||
|
+
|
||||||
|
+ if (get_library_path ("libgcrypt.so.20", "gcry_check_version", libpath, sizeof(libpath)))
|
||||||
|
+ err = gpg_error_from_syserror ();
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ *fname = _gcry_malloc (strlen (libpath) + 1 + 5 + 1 );
|
||||||
|
+ if (!*fname)
|
||||||
|
+ err = gpg_error_from_syserror ();
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ char *p;
|
||||||
|
+
|
||||||
|
+ /* Prefix the basename with a dot. */
|
||||||
|
+ strcpy (*fname, libpath);
|
||||||
|
+ p = strrchr (*fname, '/');
|
||||||
|
+ if (p)
|
||||||
|
+ p++;
|
||||||
|
+ else
|
||||||
|
+ p = *fname;
|
||||||
|
+ memmove (p+1, p, strlen (p)+1);
|
||||||
|
+ *p = '.';
|
||||||
|
+ strcat (*fname, ".hmac");
|
||||||
|
+ err = 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Run an integrity check on the binary. Returns 0 on success. */
|
||||||
|
static int
|
||||||
|
check_binary_integrity (void)
|
||||||
|
@@ -656,25 +707,10 @@ check_binary_integrity (void)
|
||||||
|
err = gpg_error (GPG_ERR_INTERNAL);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
- fname = xtrymalloc (strlen (libpath) + 1 + 5 + 1 );
|
||||||
|
- if (!fname)
|
||||||
|
- err = gpg_error_from_syserror ();
|
||||||
|
- else
|
||||||
|
- {
|
||||||
|
- FILE *fp;
|
||||||
|
- char *p;
|
||||||
|
-
|
||||||
|
- /* Prefix the basename with a dot. */
|
||||||
|
- strcpy (fname, libpath);
|
||||||
|
- p = strrchr (fname, '/');
|
||||||
|
- if (p)
|
||||||
|
- p++;
|
||||||
|
- else
|
||||||
|
- p = fname;
|
||||||
|
- memmove (p+1, p, strlen (p)+1);
|
||||||
|
- *p = '.';
|
||||||
|
- strcat (fname, ".hmac");
|
||||||
|
-
|
||||||
|
+ FILE *fp;
|
||||||
|
+ err = get_hmac_path(&fname);
|
||||||
|
+ if (!err)
|
||||||
|
+ {
|
||||||
|
/* Open the file. */
|
||||||
|
fp = fopen (fname, "r");
|
||||||
|
if (!fp)
|
||||||
|
@@ -725,6 +761,33 @@ check_binary_integrity (void)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
+int
|
||||||
|
+can_skip_selftests(void)
|
||||||
|
+{
|
||||||
|
+ char *fname = NULL;
|
||||||
|
+ int ret = 0;
|
||||||
|
+
|
||||||
|
+ if (fips_mode())
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ if (get_hmac_path(&fname))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ /* check the hmac presence */
|
||||||
|
+ if (access(fname, F_OK))
|
||||||
|
+ /* no hmac file is present, don't run the tests */
|
||||||
|
+ if (errno == ENOENT)
|
||||||
|
+ ret = 1;
|
||||||
|
+ /* otherwise one of these events happened:
|
||||||
|
+ * access() returned 0
|
||||||
|
+ * -> run the tests
|
||||||
|
+ * some error other than ENOENT occurred
|
||||||
|
+ * -> run the tests anyway and let them fail
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ xfree(fname);
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
|
||||||
|
/* Run the self-tests. If EXTENDED is true, extended versions of the
|
||||||
|
selftest are run, that is more tests than required by FIPS. */
|
||||||
|
@@ -733,26 +795,13 @@ _gcry_fips_run_selftests (int extended)
|
||||||
|
{
|
||||||
|
enum module_states result = STATE_ERROR;
|
||||||
|
gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED;
|
||||||
|
- int in_poweron;
|
||||||
|
|
||||||
|
- lock_fsm ();
|
||||||
|
- in_poweron = (current_state == STATE_POWERON);
|
||||||
|
- unlock_fsm ();
|
||||||
|
-
|
||||||
|
- fips_new_state (STATE_SELFTEST);
|
||||||
|
-
|
||||||
|
- /* We first check the integrity of the binary.
|
||||||
|
- If run from the constructor we are in POWERON state,
|
||||||
|
- we return and finish the remaining selftests before
|
||||||
|
- real use of the library. It will be in the POWERON
|
||||||
|
- state meanwhile. */
|
||||||
|
- if (in_poweron)
|
||||||
|
- if (check_binary_integrity ())
|
||||||
|
- goto leave;
|
||||||
|
-
|
||||||
|
- if (in_poweron)
|
||||||
|
+ if (can_skip_selftests())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
+ if (fips_mode ())
|
||||||
|
+ fips_new_state (STATE_SELFTEST);
|
||||||
|
+
|
||||||
|
if (run_cipher_selftests (extended))
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
@@ -762,6 +811,9 @@ _gcry_fips_run_selftests (int extended)
|
||||||
|
if (run_mac_selftests (extended))
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
+ if (check_binary_integrity ())
|
||||||
|
+ goto leave;
|
||||||
|
+
|
||||||
|
/* Run random tests before the pubkey tests because the latter
|
||||||
|
require random. */
|
||||||
|
if (run_random_selftests ())
|
||||||
|
@@ -775,7 +827,8 @@ _gcry_fips_run_selftests (int extended)
|
||||||
|
ec = 0;
|
||||||
|
|
||||||
|
leave:
|
||||||
|
- fips_new_state (result);
|
||||||
|
+ if (fips_mode ())
|
||||||
|
+ fips_new_state (result);
|
||||||
|
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
@@ -831,7 +884,6 @@ fips_new_state (enum module_states new_s
|
||||||
|
{
|
||||||
|
case STATE_POWERON:
|
||||||
|
if (new_state == STATE_INIT
|
||||||
|
- || new_state == STATE_SELFTEST
|
||||||
|
|| new_state == STATE_ERROR
|
||||||
|
|| new_state == STATE_FATALERROR)
|
||||||
|
ok = 1;
|
||||||
|
@@ -846,8 +898,6 @@ fips_new_state (enum module_states new_s
|
||||||
|
|
||||||
|
case STATE_SELFTEST:
|
||||||
|
if (new_state == STATE_OPERATIONAL
|
||||||
|
- || new_state == STATE_INIT
|
||||||
|
- || new_state == STATE_SELFTEST
|
||||||
|
|| new_state == STATE_ERROR
|
||||||
|
|| new_state == STATE_FATALERROR)
|
||||||
|
ok = 1;
|
14
libgcrypt-invoke-global_init-from-constructor.patch
Normal file
14
libgcrypt-invoke-global_init-from-constructor.patch
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
Index: libgcrypt-1.8.2/src/global.c
|
||||||
|
===================================================================
|
||||||
|
--- libgcrypt-1.8.2.orig/src/global.c
|
||||||
|
+++ libgcrypt-1.8.2/src/global.c
|
||||||
|
@@ -145,6 +145,9 @@ void __attribute__ ((constructor)) _gcry
|
||||||
|
{
|
||||||
|
/* We always need the FSM lock to be functional. */
|
||||||
|
_gcry_initialize_fsm_lock ();
|
||||||
|
+
|
||||||
|
+ /* Run the self-tests from the constructor. */
|
||||||
|
+ global_init ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is called by the macro fips_is_operational and makes
|
15
libgcrypt-random_selftests-testentropy.patch
Normal file
15
libgcrypt-random_selftests-testentropy.patch
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
Index: libgcrypt-1.8.2/random/random-drbg.c
|
||||||
|
===================================================================
|
||||||
|
--- libgcrypt-1.8.2.orig/random/random-drbg.c
|
||||||
|
+++ libgcrypt-1.8.2/random/random-drbg.c
|
||||||
|
@@ -2428,6 +2428,10 @@ drbg_healthcheck_sanity (struct gcry_drb
|
||||||
|
|
||||||
|
/* if the following tests fail, it is likely that there is a buffer
|
||||||
|
* overflow and we get a SIGSEV */
|
||||||
|
+ test_data.testentropy = &testentropy;
|
||||||
|
+ test_data.fail_seed_source = 0;
|
||||||
|
+ drbg_string_fill (&testentropy, test->entropy, test->entropylen);
|
||||||
|
+ drbg->test_data = &test_data;
|
||||||
|
ret = drbg_instantiate (drbg, NULL, coreref, 1);
|
||||||
|
if (ret)
|
||||||
|
goto outbuf;
|
92
libgcrypt-rsa-no-blinding.patch
Normal file
92
libgcrypt-rsa-no-blinding.patch
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
--- libgcrypt-1.8.2.orig/cipher/rsa.c 2020-03-26 07:23:17.392861551 +0100
|
||||||
|
+++ libgcrypt-1.8.2.orig/cipher/rsa.c 2020-03-26 15:43:29.556282072 +0100
|
||||||
|
@@ -91,10 +91,16 @@ static const char sample_secret_key[] =
|
||||||
|
" 79C974A6FA69E4D52FE796650623DE70622862713932AA2FD9F2EC856EAEAA77"
|
||||||
|
" 88B4EA6084DC81C902F014829B18EA8B2666EC41586818E0589E18876065F97E"
|
||||||
|
" 8D22CE2DA53A05951EC132DCEF41E70A9C35F4ACC268FFAC2ADF54FA1DA110B919#)"
|
||||||
|
+"))";
|
||||||
|
+/* We need to get rid of the u value, in order to end in
|
||||||
|
+ * secret_core_std when called from secret. It's not used anyway. */
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
" (u #67CF0FD7635205DD80FA814EE9E9C267C17376BF3209FB5D1BC42890D2822A04"
|
||||||
|
" 479DAF4D5B6ED69D0F8D1AF94164D07F8CD52ECEFE880641FA0F41DDAB1785E4"
|
||||||
|
" A37A32F997A516480B4CD4F6482B9466A1765093ED95023CA32D5EDC1E34CEE9"
|
||||||
|
" AF595BC51FE43C4BF810FA225AF697FB473B83815966188A4312C048B885E3F7#)))";
|
||||||
|
+*/
|
||||||
|
|
||||||
|
/* A sample 2048 bit RSA key used for the selftests (public only). */
|
||||||
|
static const char sample_public_key[] =
|
||||||
|
@@ -1252,8 +1258,8 @@ rsa_check_secret_key (gcry_sexp_t keypar
|
||||||
|
RSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL, NULL};
|
||||||
|
|
||||||
|
/* To check the key we need the optional parameters. */
|
||||||
|
- rc = sexp_extract_param (keyparms, NULL, "nedpqu",
|
||||||
|
- &sk.n, &sk.e, &sk.d, &sk.p, &sk.q, &sk.u,
|
||||||
|
+ rc = sexp_extract_param (keyparms, NULL, "npq",
|
||||||
|
+ &sk.n, &sk.p, &sk.q,
|
||||||
|
NULL);
|
||||||
|
if (rc)
|
||||||
|
goto leave;
|
||||||
|
@@ -1263,11 +1269,8 @@ rsa_check_secret_key (gcry_sexp_t keypar
|
||||||
|
|
||||||
|
leave:
|
||||||
|
_gcry_mpi_release (sk.n);
|
||||||
|
- _gcry_mpi_release (sk.e);
|
||||||
|
- _gcry_mpi_release (sk.d);
|
||||||
|
_gcry_mpi_release (sk.p);
|
||||||
|
_gcry_mpi_release (sk.q);
|
||||||
|
- _gcry_mpi_release (sk.u);
|
||||||
|
if (DBG_CIPHER)
|
||||||
|
log_debug ("rsa_testkey => %s\n", gpg_strerror (rc));
|
||||||
|
return rc;
|
||||||
|
@@ -1710,11 +1713,11 @@ static const char *
|
||||||
|
selftest_sign_2048 (gcry_sexp_t pkey, gcry_sexp_t skey)
|
||||||
|
{
|
||||||
|
static const char sample_data[] =
|
||||||
|
- "(data (flags pkcs1)"
|
||||||
|
+ "(data (flags pkcs1 no-blinding)"
|
||||||
|
" (hash sha256 #11223344556677889900aabbccddeeff"
|
||||||
|
/**/ "102030405060708090a0b0c0d0f01121#))";
|
||||||
|
static const char sample_data_bad[] =
|
||||||
|
- "(data (flags pkcs1)"
|
||||||
|
+ "(data (flags pkcs1 no-blinding)"
|
||||||
|
" (hash sha256 #11223344556677889900aabbccddeeff"
|
||||||
|
/**/ "802030405060708090a0b0c0d0f01121#))";
|
||||||
|
|
||||||
|
@@ -1857,7 +1860,7 @@ selftest_encr_2048 (gcry_sexp_t pkey, gc
|
||||||
|
gcry_mpi_t ref_mpi = NULL;
|
||||||
|
|
||||||
|
/* Put the plaintext into an S-expression. */
|
||||||
|
- err = sexp_build (&plain, NULL, "(data (flags raw) (value %s))", plaintext);
|
||||||
|
+ err = sexp_build (&plain, NULL, "(data (flags raw no-blinding) (value %s))", plaintext);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
errtxt = "converting data failed";
|
||||||
|
@@ -1897,6 +1900,26 @@ selftest_encr_2048 (gcry_sexp_t pkey, gc
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* This sexp trickery is to prevent the use of blinding.
|
||||||
|
+ * The flag doesn't get inherited by encr, so we have to
|
||||||
|
+ * derive a new sexp from the ciphertext */
|
||||||
|
+ char buf[1024];
|
||||||
|
+ memset(buf, 0, sizeof(buf));
|
||||||
|
+ err = _gcry_mpi_print (GCRYMPI_FMT_STD, buf, sizeof buf, NULL, ciphertext);
|
||||||
|
+ if (err)
|
||||||
|
+ {
|
||||||
|
+ errtxt = "Dumping ciphertext mpi to buffer failed";
|
||||||
|
+ goto leave;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ sexp_release (encr);
|
||||||
|
+ err = sexp_build (&encr, NULL, "(enc-val (flags no-blinding) (rsa (a %s)))", buf);
|
||||||
|
+ if (err)
|
||||||
|
+ {
|
||||||
|
+ errtxt = "Adding no-blinding flag to ciphertext failed";
|
||||||
|
+ goto leave;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Decrypt. */
|
||||||
|
err = _gcry_pk_decrypt (&decr, encr, skey);
|
||||||
|
if (err)
|
@ -1,3 +1,73 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Apr 27 08:55:12 UTC 2020 - Pedro Monreal Gonzalez <pmonrealgonzalez@suse.com>
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Apr 16 16:45:23 UTC 2020 - Vítězslav Čížek <vcizek@suse.com>
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Apr 15 13:55:27 UTC 2020 - Pedro Monreal Gonzalez <pmonrealgonzalez@suse.com>
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Mar 30 10:48:02 UTC 2020 - Pedro Monreal Gonzalez <pmonrealgonzalez@suse.com>
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Mar 26 18:09:47 UTC 2020 - Pedro Monreal Gonzalez <pmonrealgonzalez@suse.com>
|
||||||
|
|
||||||
|
- FIPS: Run self-tests from constructor during power-on [bsc#1166748]
|
||||||
|
* Set up global_init as the constructor function:
|
||||||
|
- libgcrypt-global_init-constructor.patch
|
||||||
|
* Relax the entropy requirements on selftest. This is especially
|
||||||
|
important for virtual machines to boot properly before the RNG
|
||||||
|
is available:
|
||||||
|
- libgcrypt-random_selftests-testentropy.patch
|
||||||
|
- libgcrypt-rsa-no-blinding.patch
|
||||||
|
- libgcrypt-ecc-ecdsa-no-blinding.patch
|
||||||
|
* Fix benchmark regression test in FIPS mode:
|
||||||
|
- libgcrypt-FIPS-GMAC_AES-benckmark.patch
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Mar 12 16:54:33 UTC 2020 - Pedro Monreal Gonzalez <pmonrealgonzalez@suse.com>
|
||||||
|
|
||||||
|
- Remove check not needed in _gcry_global_constructor [bsc#1164950]
|
||||||
|
* Update libgcrypt-Restore-self-tests-from-constructor.patch
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Feb 25 22:13:24 UTC 2020 - Pedro Monreal Gonzalez <pmonrealgonzalez@suse.com>
|
||||||
|
|
||||||
|
- FIPS: Run the self-tests from the constructor [bsc#1164950]
|
||||||
|
* Add libgcrypt-invoke-global_init-from-constructor.patch
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Fri Jan 17 17:35:15 UTC 2020 - Pedro Monreal Gonzalez <pmonrealgonzalez@suse.com>
|
Fri Jan 17 17:35:15 UTC 2020 - Pedro Monreal Gonzalez <pmonrealgonzalez@suse.com>
|
||||||
|
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
|
|
||||||
%define build_hmac256 1
|
%define build_hmac256 1
|
||||||
%define separate_hmac256_binary 0
|
%define separate_hmac256_binary 0
|
||||||
%define libsoname %{name}20
|
%define libsover 20
|
||||||
|
%define libsoname %{name}%{libsover}
|
||||||
%define cavs_dir %{_libexecdir}/%{name}/cavs
|
%define cavs_dir %{_libexecdir}/%{name}/cavs
|
||||||
Name: libgcrypt
|
Name: libgcrypt
|
||||||
Version: 1.8.5
|
Version: 1.8.5
|
||||||
@ -55,7 +56,6 @@ Patch35: libgcrypt-fipsdrv-enable-algo-for-dsa-sign.patch
|
|||||||
#PATCH-FIX-UPSTREAM bsc#1064455 fipsdrv patch to enable --algo for dsa-verify
|
#PATCH-FIX-UPSTREAM bsc#1064455 fipsdrv patch to enable --algo for dsa-verify
|
||||||
Patch36: libgcrypt-fipsdrv-enable-algo-for-dsa-verify.patch
|
Patch36: libgcrypt-fipsdrv-enable-algo-for-dsa-verify.patch
|
||||||
Patch39: libgcrypt-1.8.3-fips-ctor.patch
|
Patch39: libgcrypt-1.8.3-fips-ctor.patch
|
||||||
Patch41: libgcrypt-binary_integrity_in_non-FIPS.patch
|
|
||||||
Patch42: libgcrypt-fips_rsa_no_enforced_mode.patch
|
Patch42: libgcrypt-fips_rsa_no_enforced_mode.patch
|
||||||
Patch43: libgcrypt-1.8.4-use_xfree.patch
|
Patch43: libgcrypt-1.8.4-use_xfree.patch
|
||||||
Patch44: libgcrypt-1.8.4-allow_FSM_same_state.patch
|
Patch44: libgcrypt-1.8.4-allow_FSM_same_state.patch
|
||||||
@ -75,6 +75,20 @@ Patch52: libgcrypt-fix-tests-fipsmode.patch
|
|||||||
Patch53: libgcrypt-FIPS-RSA-DSA-ECDSA-hashing-operation.patch
|
Patch53: libgcrypt-FIPS-RSA-DSA-ECDSA-hashing-operation.patch
|
||||||
#PATCH-FIX-SUSE bsc#1161220 FIPS: libgcrypt RSA siggen/keygen: 4k not supported
|
#PATCH-FIX-SUSE bsc#1161220 FIPS: libgcrypt RSA siggen/keygen: 4k not supported
|
||||||
Patch54: libgcrypt-1.8.4-fips-keygen.patch
|
Patch54: libgcrypt-1.8.4-fips-keygen.patch
|
||||||
|
#PATCH-FIX-SUSE bsc#1164950 Run self-tests from the constructor
|
||||||
|
Patch55: libgcrypt-invoke-global_init-from-constructor.patch
|
||||||
|
#PATCH-FIX-SUSE bsc#1164950 Restore the self-tests from the constructor
|
||||||
|
Patch56: libgcrypt-Restore-self-tests-from-constructor.patch
|
||||||
|
Patch57: libgcrypt-FIPS-GMAC_AES-benckmark.patch
|
||||||
|
Patch58: libgcrypt-global_init-constructor.patch
|
||||||
|
Patch59: libgcrypt-random_selftests-testentropy.patch
|
||||||
|
Patch60: libgcrypt-rsa-no-blinding.patch
|
||||||
|
Patch61: libgcrypt-ecc-ecdsa-no-blinding.patch
|
||||||
|
#PATCH-FIX-SUSE bsc#1165539 FIPS: Use the new signature operation in PCT
|
||||||
|
Patch62: libgcrypt-PCT-RSA.patch
|
||||||
|
Patch63: libgcrypt-PCT-DSA.patch
|
||||||
|
Patch64: libgcrypt-PCT-ECC.patch
|
||||||
|
Patch65: libgcrypt-fips_selftest_trigger_file.patch
|
||||||
BuildRequires: automake >= 1.14
|
BuildRequires: automake >= 1.14
|
||||||
BuildRequires: fipscheck
|
BuildRequires: fipscheck
|
||||||
BuildRequires: libgpg-error-devel >= 1.25
|
BuildRequires: libgpg-error-devel >= 1.25
|
||||||
@ -205,6 +219,11 @@ install -m 0755 %{SOURCE6} %{buildroot}%{cavs_dir}
|
|||||||
mv %{buildroot}%{_bindir}/fipsdrv %{buildroot}%{cavs_dir}
|
mv %{buildroot}%{_bindir}/fipsdrv %{buildroot}%{cavs_dir}
|
||||||
mv %{buildroot}%{_bindir}/drbg_test %{buildroot}%{cavs_dir}
|
mv %{buildroot}%{_bindir}/drbg_test %{buildroot}%{cavs_dir}
|
||||||
|
|
||||||
|
# create the FIPS "module is complete" trigger file
|
||||||
|
%if 0%{?build_hmac256}
|
||||||
|
touch %{buildroot}/%{_libdir}/.%{name}.so.%{libsover}.fips
|
||||||
|
%endif
|
||||||
|
|
||||||
%post -n %{libsoname} -p /sbin/ldconfig
|
%post -n %{libsoname} -p /sbin/ldconfig
|
||||||
%postun -n %{libsoname} -p /sbin/ldconfig
|
%postun -n %{libsoname} -p /sbin/ldconfig
|
||||||
%post devel
|
%post devel
|
||||||
@ -216,10 +235,13 @@ mv %{buildroot}%{_bindir}/drbg_test %{buildroot}%{cavs_dir}
|
|||||||
%files -n %{libsoname}
|
%files -n %{libsoname}
|
||||||
%license COPYING.LIB
|
%license COPYING.LIB
|
||||||
%{_libdir}/%{name}.so.*
|
%{_libdir}/%{name}.so.*
|
||||||
|
%if 0%{?build_hmac256}
|
||||||
|
%{_libdir}/.libgcrypt.so.*.hmac
|
||||||
|
%endif # %%if 0%%{?build_hmac256}
|
||||||
|
|
||||||
%files -n %{libsoname}-hmac
|
%files -n %{libsoname}-hmac
|
||||||
%if 0%{?build_hmac256}
|
%if 0%{?build_hmac256}
|
||||||
%{_libdir}/.libgcrypt.so.*.hmac
|
%{_libdir}/.libgcrypt.so.*.fips
|
||||||
%endif # %%if 0%%{?build_hmac256}
|
%endif # %%if 0%%{?build_hmac256}
|
||||||
|
|
||||||
%files devel
|
%files devel
|
||||||
|
Loading…
Reference in New Issue
Block a user