From 649871c2d644a91c0468882d60df8461b70d4459 Mon Sep 17 00:00:00 2001 From: Vishnudatha Kanjur Date: Thu, 28 May 2026 14:05:45 +0200 Subject: [PATCH 1/3] AES-ECB, SHA-224, SHA-512/224, SHA3-224 marked non-Approved in FIPS140-3 mode NIST SP 800-131A classifies mechanisms AES-ECB, SHA-224, SHA-512/224, SHA3-224 are non approved by end of 2030. This commit classifies the above mentioned mechanisms as available and non approved in FIPS mode in libica. Signed-off-by: Vishnudatha Kanjur --- src/fips.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/fips.c b/src/fips.c index 27c548e..69b590e 100644 --- a/src/fips.c +++ b/src/fips.c @@ -1371,14 +1371,16 @@ int FIPS_BLACKLIST[] = {DES_ECB, DES_CBC, DES_CBC_CS, DES_OFB, DES3_CBC, DES3_CBC_CS, DES3_OFB, DES3_CFB, DES3_CTR, DES3_CTRLST, DES3_CBC_MAC, DES3_CMAC, ED25519_KEYGEN, ED25519_SIGN, ED25519_VERIFY, ED448_KEYGEN, ED448_SIGN, ED448_VERIFY, X25519_KEYGEN, X25519_DERIVE, - X448_KEYGEN, X448_DERIVE, RSA_ME, RSA_CRT, SHA512_DRNG, SHA1, -1, -1 }; + X448_KEYGEN, X448_DERIVE, RSA_ME, RSA_CRT, SHA512_DRNG, SHA1, AES_ECB, + SHA224, SHA512_224, SHA3_224, -1, -1 }; const size_t FIPS_BLACKLIST_LEN = sizeof(FIPS_BLACKLIST) / sizeof(FIPS_BLACKLIST[0]); /* * FIPS service indicator: List of tolerated but non-approved algorithms. */ -int FIPS_OVERRIDE_LIST[] = { RSA_ME, RSA_CRT, SHA512_DRNG, -1, -1 }; +int FIPS_OVERRIDE_LIST[] = { RSA_ME, RSA_CRT, SHA512_DRNG, AES_ECB, SHA224, + SHA512_224, SHA3_224, -1, -1 }; const size_t FIPS_OVERRIDE_LIST_LEN = sizeof(FIPS_OVERRIDE_LIST) / sizeof(FIPS_OVERRIDE_LIST[0]); From e6ced68bcf3ca30573ee51878b6660c6756ffb42 Mon Sep 17 00:00:00 2001 From: Vishnudatha Kanjur Date: Tue, 9 Jun 2026 11:08:27 +0200 Subject: [PATCH 2/3] Disable RSA key generation for less than 128 bits of security strength in FIPS140-3 mode RSA_ME and RSA_CRT are already marked as available but not approved in the FIPS service indicator. This commit disables RSA key generation for less than 128 bits of security strength, ie, less than 3072 bits key size in FIPS mode. Also mention RSA Keygen ME and RSA Keygen CRT as available but not approved. Signed-off-by: Vishnudatha Kanjur --- include/ica_api.h | 15 ++++++++++++--- src/fips.c | 9 +++++++-- src/ica_api.c | 4 ++-- src/icainfo.c | 24 ++++++++++++------------ src/s390_crypto.c | 2 +- src/s390_rsa.c | 4 ++-- test/rsa_keygen_test.c | 4 ++-- test/rsa_test.c | 2 +- test/rsa_test_x.c | 2 +- 9 files changed, 40 insertions(+), 26 deletions(-) diff --git a/include/ica_api.h b/include/ica_api.h index d22031d..56899f8 100644 --- a/include/ica_api.h +++ b/include/ica_api.h @@ -81,9 +81,18 @@ typedef ica_adapter_handle_t ICA_ADAPTER_HANDLE; #define ICA_PROPERTY_AES_128 0x00000001 #define ICA_PROPERTY_AES_192 0x00000002 #define ICA_PROPERTY_AES_256 0x00000004 - -#define ICA_PROPERTY_RSA_ALL 0x0000000F /* All RSA key lengths */ -#define ICA_PROPERTY_RSA_FIPS 0x0000000C /* RSA 2k and higher */ +#define ICA_PROPERTY_RSA_512 0x00000001 +#define ICA_PROPERTY_RSA_1024 0x00000002 +#define ICA_PROPERTY_RSA_2048 0x00000004 +#define ICA_PROPERTY_RSA_4096 0x00000008 +#define ICA_PROPERTY_RSA_3072 0x00020000 +#define ICA_PROPERTY_RSA_ALL (ICA_PROPERTY_RSA_512 | \ + ICA_PROPERTY_RSA_1024 | \ + ICA_PROPERTY_RSA_2048 | \ + ICA_PROPERTY_RSA_3072 | \ + ICA_PROPERTY_RSA_4096) +#define ICA_PROPERTY_RSA_FIPS (ICA_PROPERTY_RSA_3072 | \ + ICA_PROPERTY_RSA_4096) #define ICA_PROPERTY_RSA_NO_SMALL_EXP 0x00010000 /* e >= 65537 */ #define ICA_PROPERTY_EC_BP 0x00000001 /* Brainpool curves */ #define ICA_PROPERTY_EC_NIST 0x00000002 /* NIST curves */ diff --git a/src/fips.c b/src/fips.c index 69b590e..7b04fc6 100644 --- a/src/fips.c +++ b/src/fips.c @@ -1299,6 +1299,11 @@ rsa_kat(void) for (i = 0; i < RSA_TV_LEN; i++) { tv = &RSA_TV[i]; +#ifdef ICA_FIPS + if ((fips & ICA_FIPS_MODE) && tv->mod < 3072) + continue; +#endif + keylen = (tv->mod + 7) / 8; crtparamlen = (keylen + 1) / 2; @@ -1372,7 +1377,7 @@ int FIPS_BLACKLIST[] = {DES_ECB, DES_CBC, DES_CBC_CS, DES_OFB, DES3_CBC_MAC, DES3_CMAC, ED25519_KEYGEN, ED25519_SIGN, ED25519_VERIFY, ED448_KEYGEN, ED448_SIGN, ED448_VERIFY, X25519_KEYGEN, X25519_DERIVE, X448_KEYGEN, X448_DERIVE, RSA_ME, RSA_CRT, SHA512_DRNG, SHA1, AES_ECB, - SHA224, SHA512_224, SHA3_224, -1, -1 }; + SHA224, SHA512_224, SHA3_224, RSA_KEY_GEN_ME, RSA_KEY_GEN_CRT, -1, -1 }; const size_t FIPS_BLACKLIST_LEN = sizeof(FIPS_BLACKLIST) / sizeof(FIPS_BLACKLIST[0]); @@ -1380,7 +1385,7 @@ const size_t FIPS_BLACKLIST_LEN * FIPS service indicator: List of tolerated but non-approved algorithms. */ int FIPS_OVERRIDE_LIST[] = { RSA_ME, RSA_CRT, SHA512_DRNG, AES_ECB, SHA224, - SHA512_224, SHA3_224, -1, -1 }; + SHA512_224, SHA3_224, RSA_KEY_GEN_ME, RSA_KEY_GEN_CRT, -1, -1 }; const size_t FIPS_OVERRIDE_LIST_LEN = sizeof(FIPS_OVERRIDE_LIST) / sizeof(FIPS_OVERRIDE_LIST[0]); diff --git a/src/ica_api.c b/src/ica_api.c index a0d2a76..87a9496 100644 --- a/src/ica_api.c +++ b/src/ica_api.c @@ -1186,7 +1186,7 @@ unsigned int ica_rsa_mod_expo(ica_adapter_handle_t adapter_handle, return EPERM; #ifdef ICA_FIPS - if ((fips & ICA_FIPS_MODE) && rsa_key->key_length * 8 < 2048) + if ((fips & ICA_FIPS_MODE) && rsa_key->key_length * 8 < 3072) return EPERM; #endif @@ -1342,7 +1342,7 @@ unsigned int ica_rsa_crt(ica_adapter_handle_t adapter_handle, return EPERM; #ifdef ICA_FIPS - if ((fips & ICA_FIPS_MODE) && rsa_key->key_length * 8 < 2048) + if ((fips & ICA_FIPS_MODE) && rsa_key->key_length * 8 < 3072) return EPERM; #endif diff --git a/src/icainfo.c b/src/icainfo.c index e3d32db..2f6af87 100644 --- a/src/icainfo.c +++ b/src/icainfo.c @@ -176,13 +176,13 @@ int rsa_keylen_supported_by_openssl(unsigned int modulus_bitlength) int rsa_pubexp_supported_by_openssl(unsigned int pubexp) { - unsigned char modexpo_public_e[256] = { 0 }; - unsigned char modexpo_public_n[256] = { 0 }; - unsigned char crt_private_p[128] = { 0 }; - unsigned char crt_private_q[128] = { 0 }; - unsigned char crt_private_dp[128] = { 0 }; - unsigned char crt_private_dq[128] = { 0 }; - unsigned char crt_private_inv_q[128] = { 0 }; + unsigned char modexpo_public_e[384] = { 0 }; + unsigned char modexpo_public_n[384] = { 0 }; + unsigned char crt_private_p[192] = { 0 }; + unsigned char crt_private_q[192] = { 0 }; + unsigned char crt_private_dp[192] = { 0 }; + unsigned char crt_private_dq[192] = { 0 }; + unsigned char crt_private_inv_q[192] = { 0 }; ica_adapter_handle_t ah; ica_rsa_key_mod_expo_t public_key; ica_rsa_key_crt_t private_key; @@ -194,18 +194,18 @@ int rsa_pubexp_supported_by_openssl(unsigned int pubexp) public_key.modulus = modexpo_public_n; public_key.exponent = modexpo_public_e; - public_key.key_length = 256; + public_key.key_length = 384; private_key.p = crt_private_p; private_key.q = crt_private_q; private_key.dp = crt_private_dp; private_key.dq = crt_private_dq; private_key.qInverse = crt_private_inv_q; - private_key.key_length = 256; + private_key.key_length = 384; - *(int*)((unsigned char *)public_key.exponent + 256 - sizeof(int)) = pubexp; + *(int*)((unsigned char *)public_key.exponent + 384 - sizeof(int)) = pubexp; - rc = ica_rsa_key_generate_crt(ah, 2048, &public_key, &private_key); + rc = ica_rsa_key_generate_crt(ah, 3072, &public_key, &private_key); ica_close_adapter(ah); @@ -214,7 +214,7 @@ int rsa_pubexp_supported_by_openssl(unsigned int pubexp) int get_rsa_minlen(void) { - int keylen_array[] = { 57, 512, 1024, 2048, 4096 }; + int keylen_array[] = { 57, 512, 1024, 2048, 3072, 4096 }; size_t i; for (i = 0; i < sizeof(keylen_array) / sizeof(int); i++) { diff --git a/src/s390_crypto.c b/src/s390_crypto.c index 86e8b65..93987d8 100644 --- a/src/s390_crypto.c +++ b/src/s390_crypto.c @@ -724,7 +724,7 @@ int s390_get_functionlist(libica_func_list_element *pmech_list, * mode, but not on any hardware, with any openssl, not with any key * length, curve etc. */ if (fips & ICA_FIPS_MODE) { - /* RSA >= 2048 bits in FIPS 140-3 mode */ + /* RSA >= 3072 bits in FIPS 140-3 mode */ switch (pmech_list[x].mech_mode_id) { case RSA_KEY_GEN_ME: case RSA_KEY_GEN_CRT: diff --git a/src/s390_rsa.c b/src/s390_rsa.c index a3411b2..285fc44 100644 --- a/src/s390_rsa.c +++ b/src/s390_rsa.c @@ -201,7 +201,7 @@ unsigned int rsa_key_generate_mod_expo(ica_adapter_handle_t deviceHandle, #ifdef ICA_FIPS if ((fips & ICA_FIPS_MODE) && (!openssl_in_fips_mode())) return EACCES; - if ((fips & ICA_FIPS_MODE) && (modulus_bit_length < 2048)) + if ((fips & ICA_FIPS_MODE) && (modulus_bit_length < 3072)) return EPERM; #endif /* ICA_FIPS */ @@ -311,7 +311,7 @@ unsigned int rsa_key_generate_crt(ica_adapter_handle_t deviceHandle, #ifdef ICA_FIPS if ((fips & ICA_FIPS_MODE) && (!openssl_in_fips_mode())) return EACCES; - if ((fips & ICA_FIPS_MODE) && (modulus_bit_length < 2048)) + if ((fips & ICA_FIPS_MODE) && (modulus_bit_length < 3072)) return EPERM; #endif /* ICA_FIPS */ diff --git a/test/rsa_keygen_test.c b/test/rsa_keygen_test.c index bd76bda..90bbe21 100644 --- a/test/rsa_keygen_test.c +++ b/test/rsa_keygen_test.c @@ -62,9 +62,9 @@ int main(int argc, char **argv) } #ifdef ICA_FIPS - if ((ica_fips_status() & ICA_FIPS_MODE) && key_bit_length < 2048) { + if ((ica_fips_status() & ICA_FIPS_MODE) && key_bit_length < 3072) { printf("RSA-%d keygen test skipped." - " (RSA key lengths smaller than 2048 bits not FIPS 140-3 compliant)\n", + " (RSA key lengths smaller than 3072 bits not FIPS 140-3 compliant)\n", key_bit_length); return TEST_SKIP; } diff --git a/test/rsa_test.c b/test/rsa_test.c index 7d60cf9..a780c2a 100644 --- a/test/rsa_test.c +++ b/test/rsa_test.c @@ -65,7 +65,7 @@ int main(int argc, char **argv) memset(my_result2, 0, sizeof(my_result2)); #ifdef ICA_FIPS - if ((ica_fips_status() & ICA_FIPS_MODE) && RSA_BYTE_LENGHT[i] < 256) { + if ((ica_fips_status() & ICA_FIPS_MODE) && RSA_BYTE_LENGHT[i] < 384) { V_(printf("Skipping test for this modulus size: not FIPS 140-3 approved\n")); continue; } diff --git a/test/rsa_test_x.c b/test/rsa_test_x.c index e1dd077..2afa89e 100644 --- a/test/rsa_test_x.c +++ b/test/rsa_test_x.c @@ -77,7 +77,7 @@ int main(int argc, char **argv) V_(printf("\nmodulus size = %d bytes (%d bits)\n", ms, 8 * ms)); #ifdef ICA_FIPS - if ((ica_fips_status() & ICA_FIPS_MODE) && RSA_BYTE_LENGHT[i] < 256) { + if ((ica_fips_status() & ICA_FIPS_MODE) && RSA_BYTE_LENGHT[i] < 384) { V_(printf("Skipping test for this modulus size: not FIPS 140-3 approved\n")); continue; } From 2b84d2140f8d3f7b7eb0a65084d2b49c89c09919 Mon Sep 17 00:00:00 2001 From: Vishnudatha Kanjur Date: Tue, 9 Jun 2026 14:05:59 +0200 Subject: [PATCH 3/3] FIPS 140-3 HMAC changes. This commit contains changes to make sure the HMAC key used for the FIPS integrity test is at least 128 bits. Signed-off-by: Vishnudatha Kanjur --- src/Makefile.am | 8 ++++---- src/fips.c | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 27dd7eb..053d7db 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -52,9 +52,9 @@ mp.S : mp.pl if ICA_FIPS fipsinstall: - $(AM_V_GEN) openssl dgst -sha256 -mac hmac -macopt hexkey:00000000 $(DESTDIR)$(libdir)/libica.so.$(VERSION1) | sed -e 's/^.* //' > $(DESTDIR)$(libdir)/.libica.so.$(VERSION1).hmac + $(AM_V_GEN) openssl dgst -sha256 -mac hmac -macopt hexkey:00000000000000000000000000000000 $(DESTDIR)$(libdir)/libica.so.$(VERSION1) | sed -e 's/^.* //' > $(DESTDIR)$(libdir)/.libica.so.$(VERSION1).hmac $(AM_V_GEN) cd $(DESTDIR)$(libdir) && ln -sf .libica.so.$(VERSION1).hmac .libica.so.$(MAJOR).hmac - $(AM_V_GEN) openssl dgst -sha256 -mac hmac -macopt hexkey:00000000 $(DESTDIR)$(libdir)/libica-cex.so.$(VERSION1) | sed -e 's/^.* //' > $(DESTDIR)$(libdir)/.libica-cex.so.$(VERSION1).hmac + $(AM_V_GEN) openssl dgst -sha256 -mac hmac -macopt hexkey:00000000000000000000000000000000 $(DESTDIR)$(libdir)/libica-cex.so.$(VERSION1) | sed -e 's/^.* //' > $(DESTDIR)$(libdir)/.libica-cex.so.$(VERSION1).hmac $(AM_V_GEN) cd $(DESTDIR)$(libdir) && ln -sf .libica-cex.so.$(VERSION1).hmac .libica-cex.so.$(MAJOR).hmac hmac-file-lnk: hmac-file @@ -62,8 +62,8 @@ hmac-file-lnk: hmac-file $(AM_V_GEN) cd ${top_builddir}/src/.libs && ln -sf .libica-cex.so.$(VERSION1).hmac .libica-cex.so.$(MAJOR).hmac hmac-file: libica.la libica-cex.la - $(AM_V_GEN) openssl dgst -sha256 -mac hmac -macopt hexkey:00000000 ${top_builddir}/src/.libs/libica.so.$(VERSION1) | sed -e 's/^.* //' > ${top_builddir}/src/.libs/.libica.so.$(VERSION1).hmac - $(AM_V_GEN) openssl dgst -sha256 -mac hmac -macopt hexkey:00000000 ${top_builddir}/src/.libs/libica-cex.so.$(VERSION1) | sed -e 's/^.* //' > ${top_builddir}/src/.libs/.libica-cex.so.$(VERSION1).hmac + $(AM_V_GEN) openssl dgst -sha256 -mac hmac -macopt hexkey:00000000000000000000000000000000 ${top_builddir}/src/.libs/libica.so.$(VERSION1) | sed -e 's/^.* //' > ${top_builddir}/src/.libs/.libica.so.$(VERSION1).hmac + $(AM_V_GEN) openssl dgst -sha256 -mac hmac -macopt hexkey:00000000000000000000000000000000 ${top_builddir}/src/.libs/libica-cex.so.$(VERSION1) | sed -e 's/^.* //' > ${top_builddir}/src/.libs/.libica-cex.so.$(VERSION1).hmac hmac_files = hmac-file hmac-file-lnk diff --git a/src/fips.c b/src/fips.c index 7b04fc6..8db5342 100644 --- a/src/fips.c +++ b/src/fips.c @@ -363,6 +363,9 @@ static EVP_PKEY *get_pkey(void) if (keybuf == NULL) goto end; + if (keylen < 16) + goto end; + pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, keybuf, (int)keylen); end: if (keybuf) {