Pedro Monreal Gonzalez
c941c8db1e
- FIPS: Disable DSA in FIPS mode [bsc#1195385] * Upstream task: https://dev.gnupg.org/T5710 * Add libgcrypt-FIPS-disable-DSA.patch - FIPS: Service level indicator [bsc#1190700] * Provide an indicator to check wether the service utilizes an approved cryptographic algorithm or not. * Add patches: - libgcrypt-FIPS-service-indicators.patch - libgcrypt-FIPS-verify-unsupported-KDF-test.patch - libgcrypt-FIPS-HMAC-short-keylen.patch - FIPS: Define an entropy source SP800-90B compliant [bsc#1185140] * Disable jitter entropy by default in random.conf * Disable only-urandom option by default in random.conf - FIPS: RSA KeyGen/SigGen fail with 4096 bit key sizes [bsc#1192240] * rsa: Check RSA keylen constraints for key operations. * rsa: Fix regression in not returning an error for prime generation. * tests: Add 2k RSA key working in FIPS mode. * tests: pubkey: Replace RSA key to one of 2k. * tests: pkcs1v2: Skip tests with small keys in FIPS. * Add patches: - libgcrypt-FIPS-RSA-keylen.patch - libgcrypt-FIPS-RSA-keylen-tests.patch - FIPS: Disable 3DES/Triple-DES in FIPS mode [bsc#1185138] * Add libgcrypt-FIPS-disable-3DES.patch - FIPS: PBKDF requirements [bsc#1185137] OBS-URL: https://build.opensuse.org/request/show/950433 OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/libgcrypt?expand=0&rev=153
381 lines
14 KiB
Diff
381 lines
14 KiB
Diff
Index: libgcrypt-1.9.4/src/fips.c
|
|
===================================================================
|
|
--- libgcrypt-1.9.4.orig/src/fips.c
|
|
+++ libgcrypt-1.9.4/src/fips.c
|
|
@@ -437,6 +437,59 @@ _gcry_fips_test_operational (void)
|
|
}
|
|
|
|
|
|
+int
|
|
+_gcry_fips_indicator_cipher (va_list arg_ptr)
|
|
+{
|
|
+ enum gcry_cipher_algos alg = va_arg (arg_ptr, enum gcry_cipher_algos);
|
|
+ enum gcry_cipher_modes mode;
|
|
+
|
|
+ switch (alg)
|
|
+ {
|
|
+ case GCRY_CIPHER_AES:
|
|
+ case GCRY_CIPHER_AES192:
|
|
+ case GCRY_CIPHER_AES256:
|
|
+ mode = va_arg (arg_ptr, enum gcry_cipher_modes);
|
|
+ switch (mode)
|
|
+ case GCRY_CIPHER_AES:
|
|
+ case GCRY_CIPHER_AES192:
|
|
+ case GCRY_CIPHER_AES256:
|
|
+ mode = va_arg (arg_ptr, enum gcry_cipher_modes);
|
|
+ switch (mode)
|
|
+ {
|
|
+ case GCRY_CIPHER_MODE_ECB:
|
|
+ case GCRY_CIPHER_MODE_CBC:
|
|
+ case GCRY_CIPHER_MODE_CFB:
|
|
+ case GCRY_CIPHER_MODE_CFB8:
|
|
+ case GCRY_CIPHER_MODE_OFB:
|
|
+ case GCRY_CIPHER_MODE_CTR:
|
|
+ case GCRY_CIPHER_MODE_CCM:
|
|
+ case GCRY_CIPHER_MODE_GCM:
|
|
+ case GCRY_CIPHER_MODE_XTS:
|
|
+ return GPG_ERR_NO_ERROR;
|
|
+ default:
|
|
+ return GPG_ERR_NOT_SUPPORTED;
|
|
+ }
|
|
+ default:
|
|
+ return GPG_ERR_NOT_SUPPORTED;
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+int
|
|
+_gcry_fips_indicator_kdf (va_list arg_ptr)
|
|
+{
|
|
+ enum gcry_kdf_algos alg = va_arg (arg_ptr, enum gcry_kdf_algos);
|
|
+
|
|
+ switch (alg)
|
|
+ {
|
|
+ case GCRY_KDF_PBKDF2:
|
|
+ return GPG_ERR_NO_ERROR;
|
|
+ default:
|
|
+ return GPG_ERR_NOT_SUPPORTED;
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
/* This is a test on whether the library is in the error or
|
|
operational state. */
|
|
int
|
|
Index: libgcrypt-1.9.4/src/g10lib.h
|
|
===================================================================
|
|
--- libgcrypt-1.9.4.orig/src/g10lib.h
|
|
+++ libgcrypt-1.9.4/src/g10lib.h
|
|
@@ -487,6 +487,9 @@ void _gcry_fips_signal_error (const char
|
|
_gcry_fips_signal_error (__FILE__, __LINE__, NULL, 1, (a))
|
|
#endif
|
|
|
|
+int _gcry_fips_indicator_cipher (va_list arg_ptr);
|
|
+int _gcry_fips_indicator_kdf (va_list arg_ptr);
|
|
+
|
|
int _gcry_fips_is_operational (void);
|
|
|
|
/* Return true if the library is in the operational state. */
|
|
Index: libgcrypt-1.9.4/src/gcrypt.h.in
|
|
===================================================================
|
|
--- libgcrypt-1.9.4.orig/src/gcrypt.h.in
|
|
+++ libgcrypt-1.9.4/src/gcrypt.h.in
|
|
@@ -334,7 +334,9 @@ enum gcry_ctl_cmds
|
|
GCRYCTL_GET_TAGLEN = 76,
|
|
GCRYCTL_REINIT_SYSCALL_CLAMP = 77,
|
|
GCRYCTL_AUTO_EXPAND_SECMEM = 78,
|
|
- GCRYCTL_SET_ALLOW_WEAK_KEY = 79
|
|
+ GCRYCTL_SET_ALLOW_WEAK_KEY = 79,
|
|
+ GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER = 81,
|
|
+ GCRYCTL_FIPS_SERVICE_INDICATOR_KDF = 82
|
|
};
|
|
|
|
/* Perform various operations defined by CMD. */
|
|
Index: libgcrypt-1.9.4/src/global.c
|
|
===================================================================
|
|
--- libgcrypt-1.9.4.orig/src/global.c
|
|
+++ libgcrypt-1.9.4/src/global.c
|
|
@@ -755,6 +755,19 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd,
|
|
rc = _gcry_fips_run_selftests (1);
|
|
break;
|
|
|
|
+ case GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER:
|
|
+ /* Get FIPS Service Indicator for a given symmetric algorithm and
|
|
+ * optional mode. Returns GPG_ERR_NO_ERROR if algorithm is allowed or
|
|
+ * GPG_ERR_NOT_SUPPORTED otherwise */
|
|
+ rc = _gcry_fips_indicator_cipher (arg_ptr);
|
|
+ break;
|
|
+
|
|
+ case GCRYCTL_FIPS_SERVICE_INDICATOR_KDF:
|
|
+ /* Get FIPS Service Indicator for a given KDF. Returns GPG_ERR_NO_ERROR
|
|
+ * if algorithm is allowed or GPG_ERR_NOT_SUPPORTED otherwise */
|
|
+ rc = _gcry_fips_indicator_kdf (arg_ptr);
|
|
+ break;
|
|
+
|
|
case PRIV_CTL_INIT_EXTRNG_TEST: /* Init external random test. */
|
|
rc = GPG_ERR_NOT_SUPPORTED;
|
|
break;
|
|
Index: libgcrypt-1.9.4/tests/basic.c
|
|
===================================================================
|
|
--- libgcrypt-1.9.4.orig/tests/basic.c
|
|
+++ libgcrypt-1.9.4/tests/basic.c
|
|
@@ -6383,6 +6383,16 @@ do_check_ocb_cipher (int inplace)
|
|
assert (tv[tidx].taglen <= ciphlen);
|
|
assert (tv[tidx].taglen <= sizeof tag);
|
|
|
|
+ /* Verify the FIPS indicator marks this as non-approved */
|
|
+ if (in_fips_mode)
|
|
+ {
|
|
+ err = gcry_control (GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER,
|
|
+ tv[tidx].algo, GCRY_CIPHER_MODE_OCB);
|
|
+ if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED)
|
|
+ fail ("cipher-ocb, gcry_control did not fail as expected (tv %d): %s\n",
|
|
+ tidx, gpg_strerror (err));
|
|
+ }
|
|
+
|
|
err = gcry_cipher_open (&hde, tv[tidx].algo, GCRY_CIPHER_MODE_OCB, 0);
|
|
if (!err)
|
|
err = gcry_cipher_open (&hdd, tv[tidx].algo, GCRY_CIPHER_MODE_OCB, 0);
|
|
@@ -6644,6 +6654,16 @@ check_ocb_cipher_largebuf_split (int alg
|
|
memcpy(inbuf + i, hash, 16);
|
|
}
|
|
|
|
+ /* Verify the FIPS indicator marks this as non-approved */
|
|
+ if (in_fips_mode)
|
|
+ {
|
|
+ err = gcry_control (GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER,
|
|
+ algo, GCRY_CIPHER_MODE_OCB);
|
|
+ if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED)
|
|
+ fail ("cipher-ocb, gcry_control did not fail as expected (large, algo %d): %s\n",
|
|
+ algo, gpg_strerror (err));
|
|
+ }
|
|
+
|
|
err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0);
|
|
if (!err)
|
|
err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0);
|
|
@@ -6842,7 +6862,17 @@ check_ocb_cipher_checksum (int algo, int
|
|
blk[byteidx] |= 1 << bitpos;
|
|
}
|
|
|
|
- err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0);
|
|
+ /* Verify the FIPS indicator marks this as non-approved */
|
|
+ if (in_fips_mode)
|
|
+ {
|
|
+ err = gcry_control (GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER,
|
|
+ algo, GCRY_CIPHER_MODE_OCB);
|
|
+ if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED)
|
|
+ fail ("cipher-ocb, gcry_control did not fail as expected (checksum, algo %d): %s\n",
|
|
+ algo, gpg_strerror (err));
|
|
+ }
|
|
+
|
|
+ err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0);
|
|
if (!err)
|
|
err = gcry_cipher_open (&hde2, algo, GCRY_CIPHER_MODE_OCB, 0);
|
|
if (!err)
|
|
@@ -7110,6 +7140,16 @@ check_ocb_cipher_splitaad (void)
|
|
aad[2] = tv[tidx].aad2? hex2buffer (tv[tidx].aad2, aadlen+2) : NULL;
|
|
aad[3] = tv[tidx].aad3? hex2buffer (tv[tidx].aad3, aadlen+3) : NULL;
|
|
|
|
+ /* Verify the FIPS indicator marks this as non-approved */
|
|
+ if (in_fips_mode)
|
|
+ {
|
|
+ err = gcry_control (GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER,
|
|
+ GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OCB);
|
|
+ if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED)
|
|
+ fail ("cipher-ocb-splitaad, gcry_control did not fail as expected: %s\n",
|
|
+ gpg_strerror (err));
|
|
+ }
|
|
+
|
|
err = gcry_cipher_open (&hde, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OCB, 0);
|
|
if (err)
|
|
{
|
|
@@ -9044,6 +9084,17 @@ check_bulk_cipher_modes (void)
|
|
fprintf (stderr, " checking bulk encryption for %s [%i], mode %d\n",
|
|
gcry_cipher_algo_name (tv[i].algo),
|
|
tv[i].algo, tv[i].mode);
|
|
+
|
|
+ /* Verify the FIPS indicator marks approved cipher/modes combinations */
|
|
+ if (in_fips_mode)
|
|
+ {
|
|
+ err = gcry_control (GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER,
|
|
+ tv[i].algo, tv[i].mode);
|
|
+ if (gpg_err_code (err) != GPG_ERR_NO_ERROR)
|
|
+ fail ("gcry_control unexpectedly failed for algo = %s, mode = %d : %s\n",
|
|
+ gcry_cipher_algo_name (tv[i].algo), tv[i].mode, gpg_strerror (err));
|
|
+ }
|
|
+
|
|
err = gcry_cipher_open (&hde, tv[i].algo, tv[i].mode, 0);
|
|
if (!err)
|
|
err = gcry_cipher_open (&hdd, tv[i].algo, tv[i].mode, 0);
|
|
Index: libgcrypt-1.9.4/doc/gcrypt.texi
|
|
===================================================================
|
|
--- libgcrypt-1.9.4.orig/doc/gcrypt.texi
|
|
+++ libgcrypt-1.9.4/doc/gcrypt.texi
|
|
@@ -961,6 +961,19 @@ been registered with Libgpg-error and ad
|
|
clamp again. Obviously this control code may only be used before a
|
|
second thread is started in a process.
|
|
|
|
+@item GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER; Arguments: enum gcry_cipher_algos [, enum gcry_cipher_modes]
|
|
+
|
|
+Check if the given symmetric cipher and optional cipher mode combination
|
|
+is approved under the current FIPS 140-3 certification. If the
|
|
+combination is approved, this function returns @code{GPG_ERR_NO_ERROR}.
|
|
+Otherwise @code{GPG_ERR_NOT_SUPPORTED} is returned.
|
|
+
|
|
+@item GCRYCTL_FIPS_SERVICE_INDICATOR_KDF; Arguments: enum gcry_kdf_algos
|
|
+
|
|
+Check if the given KDF is approved under the current FIPS 140-3
|
|
+certification. If the KDF is approved, this function returns
|
|
+@code{GPG_ERR_NO_ERROR}. Otherwise @code{GPG_ERR_NOT_SUPPORTED}
|
|
+is returned.
|
|
|
|
@end table
|
|
|
|
@@ -980,7 +993,7 @@ descriptive message to the user and canc
|
|
|
|
Some error values do not indicate a system error or an error in the
|
|
operation, but the result of an operation that failed properly. For
|
|
-example, if you try to decrypt a tempered message, the decryption will
|
|
+example, if you try to decrypt a tampered message, the decryption will
|
|
fail. Another error value actually means that the end of a data
|
|
buffer or list has been reached. The following descriptions explain
|
|
for many error codes what they mean usually. Some error values have
|
|
@@ -6320,25 +6333,6 @@ The following symmetric encryption algor
|
|
power-up:
|
|
|
|
@table @asis
|
|
-@item 3DES
|
|
-To test the 3DES 3-key EDE encryption in ECB mode these tests are
|
|
-run:
|
|
-@enumerate
|
|
-@item
|
|
-A known answer test is run on a 64 bit test vector processed by 64
|
|
-rounds of Single-DES block encryption and decryption using a key
|
|
-changed with each round.
|
|
-@item
|
|
-A known answer test is run on a 64 bit test vector processed by 16
|
|
-rounds of 2-key and 3-key Triple-DES block encryption and decryptions
|
|
-using a key changed with each round.
|
|
-@item
|
|
-10 known answer tests using 3-key Triple-DES EDE encryption, comparing
|
|
-the ciphertext to the known value, then running a decryption and
|
|
-comparing it to the initial plaintext.
|
|
-@end enumerate
|
|
-(@code{cipher/des.c:selftest})
|
|
-
|
|
@item AES-128
|
|
A known answer tests is run using one test vector and one test
|
|
key with AES in ECB mode. (@code{cipher/rijndael.c:selftest_basic_128})
|
|
@@ -6394,6 +6388,9 @@ A known answer test using 28 byte of dat
|
|
@item HMAC SHA-512
|
|
A known answer test using 28 byte of data and a 4 byte key is run.
|
|
(@code{cipher/hmac-tests.c:selftests_sha512})
|
|
+@item CMAC AES
|
|
+A known answer test using 40 byte of data and a 16 byte key is run.
|
|
+(@code{cipher/mac-cmac.c:selftests_cmac_aes})
|
|
@end table
|
|
|
|
@subsection Random Number Power-Up Test
|
|
@@ -6416,7 +6413,7 @@ The public key algorithms are tested dur
|
|
|
|
@table @asis
|
|
@item RSA
|
|
-A pre-defined 1024 bit RSA key is used and these tests are run
|
|
+A pre-defined 2048 bit RSA key is used and these tests are run
|
|
in turn:
|
|
@enumerate
|
|
@item
|
|
@@ -6426,14 +6423,14 @@ Conversion of S-expression to internal f
|
|
Private key consistency check.
|
|
(@code{cipher/@/rsa.c:@/selftests_rsa})
|
|
@item
|
|
-A pre-defined 20 byte value is signed with PKCS#1 padding for SHA-1.
|
|
+A pre-defined 20 byte value is signed with PKCS#1 padding for SHA-256.
|
|
The result is verified using the public key against the original data
|
|
-and against modified data. (@code{cipher/@/rsa.c:@/selftest_sign_1024})
|
|
+and against modified data. (@code{cipher/@/rsa.c:@/selftest_sign_2048})
|
|
@item
|
|
-A 1000 bit random value is encrypted and checked that it does not
|
|
-match the original random value. The encrypted result is then
|
|
+A predefined 66 byte value is encrypted and checked that it matches
|
|
+reference encyrpted message. The encrypted result is then
|
|
decrypted and checked that it matches the original random value.
|
|
-(@code{cipher/@/rsa.c:@/selftest_encr_1024})
|
|
+(@code{cipher/@/rsa.c:@/selftest_encr_2048})
|
|
@end enumerate
|
|
|
|
@item DSA
|
|
@@ -6463,15 +6461,6 @@ of the same name but with a single dot a
|
|
@file{.hmac}.
|
|
|
|
|
|
-@subsection Critical Functions Power-Up Tests
|
|
-
|
|
-The 3DES weak key detection is tested during power-up by calling the
|
|
-detection function with keys taken from a table listening all weak
|
|
-keys. The table itself is protected using a SHA-1 hash.
|
|
-(@code{cipher/@/des.c:@/selftest})
|
|
-
|
|
-
|
|
-
|
|
@c --------------------------------
|
|
@section Conditional Tests
|
|
|
|
@@ -6645,8 +6634,6 @@ If Libgcrypt is used in FIPS mode these
|
|
The cryptographic algorithms are restricted to this list:
|
|
|
|
@table @asis
|
|
-@item GCRY_CIPHER_3DES
|
|
-3 key EDE Triple-DES symmetric encryption.
|
|
@item GCRY_CIPHER_AES128
|
|
AES 128 bit symmetric encryption.
|
|
@item GCRY_CIPHER_AES192
|
|
@@ -6673,6 +6660,8 @@ HMAC using a SHA-256 message digest.
|
|
HMAC using a SHA-384 message digest.
|
|
@item GCRY_MD_SHA512,GCRY_MD_FLAG_HMAC
|
|
HMAC using a SHA-512 message digest.
|
|
+@item GCRY_MAC_CMAC_AES
|
|
+CMAC using a AES key.
|
|
@item GCRY_PK_RSA
|
|
RSA encryption and signing.
|
|
@item GCRY_PK_DSA
|
|
@@ -6683,8 +6672,8 @@ Note that the CRC algorithms are not con
|
|
and thus are in addition available.
|
|
|
|
@item
|
|
-RSA key generation refuses to create a key with a keysize of
|
|
-less than 1024 bits.
|
|
+RSA key generation refuses to create and uyse ea key with a keysize of
|
|
+less than 2048 bits.
|
|
|
|
@item
|
|
DSA key generation refuses to create a key with a keysize other
|
|
@@ -6697,8 +6686,9 @@ The @code{transient-key} flag for RSA an
|
|
Support for the VIA Padlock engine is disabled.
|
|
|
|
@item
|
|
-FIPS mode may only be used on systems with a /dev/random device.
|
|
-Switching into FIPS mode on other systems will fail at runtime.
|
|
+FIPS mode may only be used on systems with a /dev/random device or
|
|
+with a getentropy syscall. Switching into FIPS mode on other systems
|
|
+will fail at runtime.
|
|
|
|
@item
|
|
Saving and loading a random seed file is ignored.
|
|
@@ -6731,11 +6721,15 @@ disables FIPS mode unless Enforced FIPS
|
|
Libgcrypt will enter the error state.
|
|
|
|
@item
|
|
+The signatures using SHA-1 digest algorithm may not be used.
|
|
+
|
|
+@item
|
|
In Enforced FIPS mode the command @code{GCRYCTL_DISABLE_SECMEM} is
|
|
ignored. In standard FIPS mode it disables FIPS mode.
|
|
|
|
@item
|
|
A handler set by @code{gcry_set_outofcore_handler} is ignored.
|
|
+
|
|
@item
|
|
A handler set by @code{gcry_set_fatalerror_handler} is ignored.
|
|
|