Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libica for openSUSE:Factory checked 
in at 2024-01-29 22:29:25
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libica (Old)
 and      /work/SRC/openSUSE:Factory/.libica.new.1815 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libica"

Mon Jan 29 22:29:25 2024 rev:32 rq:1142194 version:4.3.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/libica/libica.changes    2023-10-13 
23:16:32.607090035 +0200
+++ /work/SRC/openSUSE:Factory/.libica.new.1815/libica.changes  2024-01-29 
22:29:51.371270548 +0100
@@ -1,0 +2,7 @@
+Mon Jan 29 07:52:34 UTC 2024 - Nikolay Gueorguiev <[email protected]>
+
+- Upgrade libica to version 2.3.0 (jsc#PED-5446)
+  * New API function ica_allow_external_gcm_iv_in_fips_mode
+  * Bug fixes
+
+-------------------------------------------------------------------

Old:
----
  libica-4.2.3.tar.gz

New:
----
  libica-4.3.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libica.spec ++++++
--- /var/tmp/diff_new_pack.RRS3z1/_old  2024-01-29 22:29:51.899289659 +0100
+++ /var/tmp/diff_new_pack.RRS3z1/_new  2024-01-29 22:29:51.903289804 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package libica
 #
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2024 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -22,7 +22,7 @@
 %endif
 
 Name:           libica
-Version:        4.2.3
+Version:        4.3.0
 Release:        0
 Summary:        Library interface for the IBM Cryptographic Accelerator device 
driver
 License:        CPL-1.0

++++++ libica-4.2.3.tar.gz -> libica-4.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/.travis.yml new/libica-4.3.0/.travis.yml
--- old/libica-4.2.3/.travis.yml        2023-09-20 12:26:01.000000000 +0200
+++ new/libica-4.3.0/.travis.yml        2024-01-25 09:36:46.000000000 +0100
@@ -1,8 +1,9 @@
-dist: bionic
+os: linux
+dist: focal
 
 language: c
 
-matrix:
+jobs:
     include:
         - name: "linux-s390x-gcc"
           os: linux
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/ChangeLog new/libica-4.3.0/ChangeLog
--- old/libica-4.2.3/ChangeLog  2023-09-20 12:26:01.000000000 +0200
+++ new/libica-4.3.0/ChangeLog  2024-01-25 09:36:46.000000000 +0100
@@ -1,3 +1,6 @@
+v4.3.0
+   [FEATURE] New API function ica_allow_external_gcm_iv_in_fips_mode
+   [PATCH] bug fixes
 v4.2.3
    [PATCH] Add OPENSSL_init_crypto in libica constructor
    [PATCH] remove deprecated ioctl Z90STAT_STATUS_MASK
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/configure.ac 
new/libica-4.3.0/configure.ac
--- old/libica-4.2.3/configure.ac       2023-09-20 12:26:01.000000000 +0200
+++ new/libica-4.3.0/configure.ac       2024-01-25 09:36:46.000000000 +0100
@@ -1,4 +1,4 @@
-AC_INIT([libica], [4.2.3], [https://github.com/opencryptoki/libica/issues],, 
[https://github.com/opencryptoki/libica])
+AC_INIT([libica], [4.3.0], [https://github.com/opencryptoki/libica/issues],, 
[https://github.com/opencryptoki/libica])
 
 # save cmdline flags
 cmdline_CFLAGS="$CFLAGS"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/include/ica_api.h 
new/libica-4.3.0/include/ica_api.h
--- old/libica-4.2.3/include/ica_api.h  2023-09-20 12:26:01.000000000 +0200
+++ new/libica-4.3.0/include/ica_api.h  2024-01-25 09:36:46.000000000 +0100
@@ -538,6 +538,17 @@
 void ica_set_stats_mode(int stats_mode);
 
 /**
+ * Allow or disallow using an external GCM iv when running in fips mode.
+ * When running in fips mode, the GCM iv is created internally via an approved
+ * random source. Applications are not allowed to use an own, external iv. If
+ * this function is called with allow = 1, libica will override this behavior
+ * and allow an external GCM iv in fips mode. In this case the application is
+ * responsible for creating the iv in a compliant way. Default is allow = 0.
+ */
+ICA_EXPORT
+void ica_allow_external_gcm_iv_in_fips_mode(int allow);
+
+/**
  * Opens the specified adapter
  * @param adapter_handle Pointer to the file descriptor for the adapter or
  * to DRIVER_NOT_LOADED if opening the crypto adapter failed.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/libica.map new/libica-4.3.0/libica.map
--- old/libica-4.2.3/libica.map 2023-09-20 12:26:01.000000000 +0200
+++ new/libica-4.3.0/libica.map 2024-01-25 09:36:46.000000000 +0100
@@ -196,3 +196,9 @@
        ica_get_build_version;
     local: *;
 } LIBICA_4.1.1;
+
+LIBICA_4.3.0 {
+    global:
+       ica_allow_external_gcm_iv_in_fips_mode;
+    local: *;
+} LIBICA_4.1.2;
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/libica.spec new/libica-4.3.0/libica.spec
--- old/libica-4.2.3/libica.spec        2023-09-20 12:26:01.000000000 +0200
+++ new/libica-4.3.0/libica.spec        2024-01-25 09:36:46.000000000 +0100
@@ -1,5 +1,5 @@
 Name:          libica
-Version:       4.2.3
+Version:       4.3.0
 Release:       1%{?dist}
 Summary:       Interface library to the ICA device driver
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/src/Makefile.am 
new/libica-4.3.0/src/Makefile.am
--- old/libica-4.2.3/src/Makefile.am    2023-09-20 12:26:01.000000000 +0200
+++ new/libica-4.3.0/src/Makefile.am    2024-01-25 09:36:46.000000000 +0100
@@ -1,4 +1,4 @@
-VERSION = 4:2:3
+VERSION = 4:3:0
 
 AM_CFLAGS = @FLAGS@
 MAJOR := `echo $(VERSION) | cut -d: -f1`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/src/fips.c new/libica-4.3.0/src/fips.c
--- old/libica-4.2.3/src/fips.c 2023-09-20 12:26:01.000000000 +0200
+++ new/libica-4.3.0/src/fips.c 2024-01-25 09:36:46.000000000 +0100
@@ -249,7 +249,7 @@
 #endif
 
 void
-fips_init(void)
+fips_get_indicator(void)
 {
        FILE *fd;
        char fips_flag;
@@ -271,18 +271,22 @@
                fips_flag = '1';
 
        if (fips_flag - '0') {
-#if !OPENSSL_VERSION_PREREQ(3, 0)
                /* Set libica into FIPS mode. */
                fips |= ICA_FIPS_MODE;
+       }
+}
 
+void
+fips_init(void)
+{
+       if (fips & ICA_FIPS_MODE) {
+#if !OPENSSL_VERSION_PREREQ(3, 0)
                /* Try to set OpenSSL into FIPS mode. If this is not possible,
                 * all software fallbacks (including RSA key generation) will
                 * be disabled. OpenSSL FIPS mode can be queried using the
                 * FIPS_mode() function. */
                FIPS_mode_set(1);
 #else
-               fips = 0;
-
 #ifndef NO_FIPS_CONFIG_LOAD
                /* Allow to skip reading the openssl 3.x fips config. Tests 
showed
                 * that this step must be skipped on RHEL9 systems. But on other
@@ -290,7 +294,7 @@
                if (!OSSL_LIB_CTX_load_config(openssl_libctx, 
LIBICA_FIPS_CONFIG)) {
                        syslog(LOG_ERR, "Libica failed to load openssl fips 
config %s\n",
                                        LIBICA_FIPS_CONFIG);
-                       fips |= ICA_FIPS_INTEGRITY;
+                       fips = ICA_FIPS_INTEGRITY;
                        return;
                }
 #endif
@@ -298,17 +302,15 @@
                openssl_provider = OSSL_PROVIDER_load(openssl_libctx, "fips");
                if (openssl_provider == NULL) {
                        syslog(LOG_ERR, "Libica failed to load fips 
provider.\n");
-                       fips |= ICA_FIPS_INTEGRITY;
+                       fips = ICA_FIPS_INTEGRITY;
                        return;
                }
 
                if (!EVP_set_default_properties(openssl_libctx, "fips=yes")) {
                        syslog(LOG_ERR, "Libica failed to set default 
properties 'fips=yes'\n");
-                       fips |= ICA_FIPS_INTEGRITY;
+                       fips = ICA_FIPS_INTEGRITY;
                        return;
                }
-
-               fips |= ICA_FIPS_MODE;
 #endif
        } else {
                /* kernel fips flag == 0, load default provider in case we are
@@ -400,6 +402,8 @@
        void *fdata = NULL;
        struct stat fdata_stat;
 
+       BEGIN_OPENSSL_LIBCTX(openssl_libctx, rc);
+
        pkey = get_pkey();
        if (!pkey)
                goto end;
@@ -438,6 +442,7 @@
                EVP_MD_CTX_destroy(mdctx);
 
        OPENSSL_cleanse(tmp, sizeof(tmp));
+       END_OPENSSL_LIBCTX(rc);
 
        return rc;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/src/ica_api.c 
new/libica-4.3.0/src/ica_api.c
--- old/libica-4.2.3/src/ica_api.c      2023-09-20 12:26:01.000000000 +0200
+++ new/libica-4.3.0/src/ica_api.c      2024-01-25 09:36:46.000000000 +0100
@@ -92,6 +92,14 @@
        ica_stats_enabled = stats_mode ? 1 : 0;
 }
 
+int ica_external_gcm_iv_in_fips_mode_allowed = 0;
+
+void ica_allow_external_gcm_iv_in_fips_mode(int allow)
+{
+       ica_external_gcm_iv_in_fips_mode_allowed = allow ? 1 : 0;
+}
+
+
 #ifndef NO_CPACF
 
 static unsigned int check_des_parms(unsigned int mode,
@@ -258,24 +266,16 @@
                                    const unsigned char *tag, unsigned int 
tag_length,
                                    unsigned int iv_length)
 {
-#ifdef __s390x__
        /*
-        * The following comparisions are alaways false on s390 targets
-        * due to limited range of data type.
-        */
-       if ((text_length > S390_GCM_MAX_TEXT_LENGTH) ||
-           (aad_length > S390_GCM_MAX_AAD_LENGTH))
-               return EINVAL;
-#else
-       (void)text_length;      /* supporess unused param warning */
-       (void)aad_length;
-#endif
-       /*
-        * The following check must be done but is commented out because
-        * comparison is always false due to limited range of data type.
+        * The following comparisons are always false due to limited
+        * range of data types.
+        *
+        * if ((text_length > S390_GCM_MAX_TEXT_LENGTH) ||
+        *     (aad_length > S390_GCM_MAX_AAD_LENGTH))
+        *     return EINVAL;
         *
-        * if (iv_length   > S390_GCM_MAX_IV_LENGTH)
-        *      return EINVAL;
+        * if (iv_length > S390_GCM_MAX_IV_LENGTH)
+        *     return EINVAL;
         */
 
        if (iv_length == 0)
@@ -1182,12 +1182,12 @@
 unsigned int ica_rsa_crt_key_check(ica_rsa_key_crt_t *rsa_key)
 {
        int pq_comp;
-       int keyfmt = 1;
        BIGNUM *bn_p;
        BIGNUM *bn_q;
        BIGNUM *bn_invq;
        BN_CTX *ctx;
        unsigned char *tmp_buf = NULL;
+       unsigned int rc;
 
 #ifdef ICA_FIPS
        if (fips >> 1)
@@ -1195,53 +1195,63 @@
 #endif /* ICA_FIPS */
 
        /* check if p > q  */
-       pq_comp = memcmp( (rsa_key->p + 8), (rsa_key->q), 
rsa_key->key_length/2);
-       if (pq_comp < 0) /* unprivileged key format */
-               keyfmt = 0;
-
-       if (!keyfmt) {
-               /* swap p and q */
-               tmp_buf = calloc(1, rsa_key->key_length/2);
-               if (!tmp_buf)
-                       return ENOMEM;
-               memcpy(tmp_buf, rsa_key->p + 8, rsa_key->key_length/2);
-               memcpy(rsa_key->p + 8, rsa_key->q, rsa_key->key_length/2);
-               memcpy(rsa_key->q, tmp_buf, rsa_key->key_length/2);
-
-               /* swap dp and dq */
-               memcpy(tmp_buf, rsa_key->dp + 8, rsa_key->key_length/2);
-               memcpy(rsa_key->dp + 8, rsa_key->dq, rsa_key->key_length/2);
-               memcpy(rsa_key->dq, tmp_buf, rsa_key->key_length/2);
-
-               /* calculate new qInv */
-               bn_p = BN_new();
-               bn_q = BN_new();
-               bn_invq = BN_new();
-               ctx = BN_CTX_new();
-
-               BN_bin2bn(rsa_key->p, rsa_key->key_length/2+8, bn_p);
-               BN_bin2bn(rsa_key->q, rsa_key->key_length/2, bn_q);
-
-               /* qInv = (1/q) mod p */
-               BN_mod_inverse(bn_invq, bn_q, bn_p, ctx);
-               memset(tmp_buf, 0, rsa_key->key_length/2);
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-               BN_bn2bin(bn_invq, tmp_buf + rsa_key->key_length/2 - 
BN_num_bytes(bn_invq));
-#else
-               BN_bn2binpad(bn_invq, tmp_buf, rsa_key->key_length/2);
-#endif
-               memcpy(rsa_key->qInverse + 8, tmp_buf, rsa_key->key_length/2);
-
-               free(tmp_buf);
+       pq_comp = memcmp( (rsa_key->p + 8), (rsa_key->q), rsa_key->key_length / 
2);
+       if (pq_comp >= 0) /* privileged key format, p and q ok */
+               return 0;
 
-               BN_CTX_free(ctx);
-               BN_clear_free(bn_p);
-               BN_clear_free(bn_q);
-               BN_clear_free(bn_invq);
+       /* unprivileged key format: swap p and q */
+       tmp_buf = calloc(1, rsa_key->key_length / 2);
+       if (!tmp_buf)
+               return ENOMEM;
+
+       bn_p = BN_secure_new();
+       bn_q = BN_secure_new();
+       bn_invq = BN_secure_new();
+       ctx = BN_CTX_new();
+       if (!bn_p || !bn_q || !bn_invq || !ctx) {
+               rc = ENOMEM;
+               goto done;
+       }
+
+       /* swap p and q */
+       memcpy(tmp_buf, rsa_key->p + 8, rsa_key->key_length / 2);
+       memcpy(rsa_key->p + 8, rsa_key->q, rsa_key->key_length / 2);
+       memcpy(rsa_key->q, tmp_buf, rsa_key->key_length / 2);
+
+       /* swap dp and dq */
+       memcpy(tmp_buf, rsa_key->dp + 8, rsa_key->key_length / 2);
+       memcpy(rsa_key->dp + 8, rsa_key->dq, rsa_key->key_length / 2);
+       memcpy(rsa_key->dq, tmp_buf, rsa_key->key_length / 2);
+
+       if (BN_bin2bn(rsa_key->p, rsa_key->key_length / 2 + 8, bn_p) == NULL ||
+               BN_bin2bn(rsa_key->q, rsa_key->key_length / 2, bn_q) == NULL) {
+               rc = EFAULT;
+               goto done;
+       }
+
+       /* qInv = (1/q) mod p */
+       if (BN_mod_inverse(bn_invq, bn_q, bn_p, ctx) == NULL) {
+               rc = EFAULT;
+               goto done;
+       }
+       memset(tmp_buf, 0, rsa_key->key_length / 2);
+       if (BN_bn2binpad(bn_invq, tmp_buf, rsa_key->key_length / 2) <= 0) {
+               rc = EFAULT;
+               goto done;
+       }
+       memcpy(rsa_key->qInverse + 8, tmp_buf, rsa_key->key_length / 2);
+
+       rc = 1;
+
+done:
+       OPENSSL_cleanse(tmp_buf, rsa_key->key_length / 2);
+       free(tmp_buf);
+       BN_CTX_free(ctx);
+       BN_clear_free(bn_p);
+       BN_clear_free(bn_q);
+       BN_clear_free(bn_invq);
 
-               return 1;
-       }
-       return 0;
+       return rc;
 }
 
 unsigned int ica_rsa_crt(ica_adapter_handle_t adapter_handle,
@@ -1277,7 +1287,9 @@
        rb.outputdata = output_data;
        rb.outputdatalength = rsa_key->key_length;
 
-       ica_rsa_crt_key_check(rsa_key);
+       rc = ica_rsa_crt_key_check(rsa_key);
+       if (rc > 1)
+               return rc;
 
        rb.np_prime = rsa_key->p;
        rb.nq_prime = rsa_key->q;
@@ -3736,7 +3748,8 @@
                                unsigned int direction)
 {
 #ifdef ICA_FIPS
-       if (direction == ENCRYPT && (fips & ICA_FIPS_MODE))
+       if (!ica_external_gcm_iv_in_fips_mode_allowed &&
+               direction == ENCRYPT && (fips & ICA_FIPS_MODE))
                return EPERM;
 #endif /* ICA_FIPS */
 
@@ -3984,7 +3997,8 @@
                                        kma_ctx* ctx)
 {
 #ifdef ICA_FIPS
-       if (direction == ICA_ENCRYPT && (fips & ICA_FIPS_MODE))
+       if (!ica_external_gcm_iv_in_fips_mode_allowed &&
+               direction == ICA_ENCRYPT && (fips & ICA_FIPS_MODE))
                return EPERM;
 #endif /* ICA_FIPS */
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/src/icastats_shared.c 
new/libica-4.3.0/src/icastats_shared.c
--- old/libica-4.2.3/src/icastats_shared.c      2023-09-20 12:26:01.000000000 
+0200
+++ new/libica-4.3.0/src/icastats_shared.c      2024-01-25 09:36:46.000000000 
+0100
@@ -263,10 +263,8 @@
                        int fd;
                        stats_entry_t *tmp;
 
-                       if ((getpwuid(atoi(&direntp->d_name[9]))) == NULL) {
-                               closedir(shmDir);
-                               return 0;
-                       }
+                       if ((getpwuid(atoi(&direntp->d_name[9]))) == NULL)
+                               continue;
 
                        if ((fd = shm_open(direntp->d_name, O_RDONLY, 0)) == 
-1) {
                                closedir(shmDir);
@@ -324,9 +322,9 @@
                        int uid = atoi(&direntp->d_name[9]);
                        struct passwd *pwd;
                        if ((pwd = getpwuid(uid)) == NULL)
-                               return NULL;
+                               continue;
                        if (stats_mmap(uid) == -1)
-                               return NULL;
+                               break;
 
                        return pwd->pw_name;
                } else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/src/include/fips.h 
new/libica-4.3.0/src/include/fips.h
--- old/libica-4.2.3/src/include/fips.h 2023-09-20 12:26:01.000000000 +0200
+++ new/libica-4.3.0/src/include/fips.h 2024-01-25 09:36:46.000000000 +0100
@@ -25,6 +25,7 @@
  * Initialize global fips var to 1 resp. 0 when FIPS_FLAG is 1 resp. 0 (or not
  * present).
  */
+void fips_get_indicator(void);
 void fips_init(void);
 
 /*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/src/include/s390_aes.h 
new/libica-4.3.0/src/include/s390_aes.h
--- old/libica-4.2.3/src/include/s390_aes.h     2023-09-20 12:26:01.000000000 
+0200
+++ new/libica-4.3.0/src/include/s390_aes.h     2024-01-25 09:36:46.000000000 
+0100
@@ -59,8 +59,8 @@
                unsigned int cv;
                ica_aes_vector_t tag;
                ica_aes_vector_t subkey_h;
-               unsigned long long total_aad_length;
-               unsigned long long total_input_length;
+               unsigned long long total_aad_length; /* bit length */
+               unsigned long long total_input_length; /* bit length */
                ica_aes_vector_t j0;
                ica_aes_key_len_256_t key;
        } parm_block;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/src/include/s390_gcm.h 
new/libica-4.3.0/src/include/s390_gcm.h
--- old/libica-4.2.3/src/include/s390_gcm.h     2023-09-20 12:26:01.000000000 
+0200
+++ new/libica-4.3.0/src/include/s390_gcm.h     2024-01-25 09:36:46.000000000 
+0100
@@ -16,9 +16,23 @@
 
 #include "s390_ctr.h"
 
-#define S390_GCM_MAX_TEXT_LENGTH (0x0000000fffffffe0ul) /* (2^31)-32 */
-#define S390_GCM_MAX_AAD_LENGTH  (0x2000000000000000ul) /* (2^61)    */
-#define S390_GCM_MAX_IV_LENGTH   (0x2000000000000000ul) /* (2^61)    */
+/*
+ * NIST SP 800-38d: bitlen(P) <= 2^39 - 256;
+ *   => 0 <= bytelen(P) <= 2^36 - 32
+ */
+#define S390_GCM_MAX_TEXT_LENGTH         ((2ULL << 36) - 32)
+
+/*
+ * NIST SP 800-38d: bitlen(A) <= 2^64 - 1
+ *   => 0 <= bytelen(A) <= 2^61 - 1
+ */
+#define S390_GCM_MAX_AAD_LENGTH          ((2ULL << 61) - 1)
+
+/*
+ * NIST SP 800-38d: 1 <= bitlen(iv) <= 2^64 - 1
+ *   => 1 <= bytelen(iv) <= 2^61 - 1
+ */
+#define S390_GCM_MAX_IV_LENGTH           ((2ULL << 61) - 1)
 
 /* the recommended iv length for GCM is 96 bit or 12 byte */
 #define GCM_RECOMMENDED_IV_LENGTH 12
@@ -51,8 +65,8 @@
        uint32_t cv;
        ica_aes_vector_t tag;
        ica_aes_vector_t subkey_h;
-       uint64_t total_aad_length;
-       uint64_t total_input_length;
+       uint64_t total_aad_length; /* bit length */
+       uint64_t total_input_length; /* bit length */
        ica_aes_vector_t j0;
        ica_aes_key_len_256_t key;
        // Above this line: KMA parmblock, never change!
@@ -735,8 +749,8 @@
                data_length = 0;
 
        /* Actual lengths needed by KMA */
-       ctx->total_aad_length += aad_length*8;
-       ctx->total_input_length += data_length*8;
+       ctx->total_aad_length += aad_length * 8;
+       ctx->total_input_length += data_length * 8;
 
        /* Call KMA */
        rc = s390_kma(hw_fc, ctx,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/src/init.c new/libica-4.3.0/src/init.c
--- old/libica-4.2.3/src/init.c 2023-09-20 12:26:01.000000000 +0200
+++ new/libica-4.3.0/src/init.c 2024-01-25 09:36:46.000000000 +0100
@@ -113,6 +113,16 @@
        if (ptr && sscanf(ptr, "%i", &value) == 1)
                ica_set_stats_mode(value);
 
+#ifdef ICA_FIPS
+       fips_get_indicator();
+#endif
+
+       rng_init();
+
+       s390_prng_init();
+
+       s390_initialize_functionlist();
+
 #if OPENSSL_VERSION_PREREQ(3, 0)
        /*
         * OpenSSL >= 3.0:
@@ -124,6 +134,18 @@
         * is loaded later, which may cause that all configured providers
         * are also loaded into the library context. We need to make sure that
         * only the default or fips provider is loaded in the library context.
+        *
+        * Also make sure that OpenSSL initialization happens AFTER the
+        * mechanism list has been initialized and the fips indicator has been
+        * obtained. OPENSSL_init_crypto may load configured providers, and a
+        * provider might use libica in its initialization function. It must
+        * be ensured that libica has been initialized that far before OpenSSL
+        * is initialized, so that such libica calls from providers can be
+        * fulfilled and return correct information.
+        *
+        * The remaining FIPS initialization (fips provider load, power on self
+        * tests, etc) must still happen after OpenSSL initialization, because
+        * that relies on OpenSSL being initialized.
         */
        OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL);
 
@@ -135,18 +157,13 @@
 #endif
 
 #ifdef ICA_FIPS
-       fips_init(); /* before powerup tests and initialize functionlist */
+       fips_init();
 #endif
 
 #if OPENSSL_VERSION_PREREQ(3, 0)
        openssl3_initialized = 1;
 #endif
 
-       rng_init();
-
-       s390_prng_init();
-
-       s390_initialize_functionlist();
 
 #ifdef ICA_FIPS
        if (fips & ICA_FIPS_MODE)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/src/s390_crypto.c 
new/libica-4.3.0/src/s390_crypto.c
--- old/libica-4.2.3/src/s390_crypto.c  2023-09-20 12:26:01.000000000 +0200
+++ new/libica-4.3.0/src/s390_crypto.c  2024-01-25 09:36:46.000000000 +0100
@@ -326,22 +326,37 @@
                        *s390_kdsa_functions[n].enabled = 1;
 }
 
-unsigned int is_device_online(const char *dev)
+int file_fgets(const char *fname, char *buf, size_t buflen)
 {
-       unsigned int ret = 0;
-       FILE *file;
-       char c;
-
-       if ((file = fopen(dev, "r")) == NULL)
-               return 0;
-
-       /* Check if device online: 0 = offline, 1 = online */
-       if ((c = fgetc(file)) == '1')
-               ret = 1;
+       FILE *fp;
+       char *end;
+       int rc = 0;
+
+       buf[0] = '\0';
+
+       fp = fopen(fname, "r");
+       if (fp == NULL) {
+               return EIO;
+       }
+       if (fgets(buf, buflen, fp) == NULL) {
+               rc = EIO;
+               goto out_fclose;
+       }
 
-       fclose(file);
+       end = memchr(buf, '\n', buflen);
+       if (end)
+               *end = 0;
+       else
+               buf[buflen - 1] = 0;
+
+       if (strlen(buf) == 0) {
+               rc = EIO;
+               goto out_fclose;
+       }
 
-       return ret;
+out_fclose:
+       fclose(fp);
+       return rc;
 }
 
 unsigned int get_device_type(const char *dev, char *devtype)
@@ -381,8 +396,10 @@
        DIR *sysDir;
        unsigned int ret = 0;
        char dev[MAX_DEV_LEN] = AP_PATH;
+       char buf[250];
        struct dirent *direntp;
        char type[6];
+       int rc;
 
        if ((sysDir = opendir(dev)) == NULL)
                return 0;
@@ -393,9 +410,20 @@
                if (strncmp(direntp->d_name, "card", 4) != 0)
                        continue;
 
-               /* Check if device online */
+               /* Check if device online, configured, and not in checkstop */
                snprintf(dev, MAX_DEV_LEN, "%s/%s/online", AP_PATH, 
direntp->d_name);
-               if (!is_device_online(dev))
+               rc = file_fgets(dev, buf, sizeof(buf));
+               if (rc != 0 || strcmp(buf, "1") != 0)
+                       continue;
+
+               snprintf(dev, MAX_DEV_LEN, "%s/%s/config", AP_PATH, 
direntp->d_name);
+               rc = file_fgets(dev, buf, sizeof(buf));
+               if (rc == 0 && strcmp(buf, "1") != 0)
+                       continue;
+
+               snprintf(dev, MAX_DEV_LEN, "%s/%s/chkstop", AP_PATH, 
direntp->d_name);
+               rc = file_fgets(dev, buf, sizeof(buf));
+               if (rc == 0 && strcmp(buf, "0") != 0)
                        continue;
 
                /* Get device type (string like "CEXnT") */
@@ -771,11 +799,11 @@
                return EINVAL;
 
        if (!indicator_list) {
-               *indicator_list_len = sizeof(icaList) / 
sizeof(libica_fips_indicator_element);
+               *indicator_list_len = sizeof(icaList) / 
sizeof(libica_func_list_element_int);
                return 0;
        }
 
-       if (*indicator_list_len < (sizeof(icaList) / 
sizeof(libica_fips_indicator_element)))
+       if (*indicator_list_len < (sizeof(icaList) / 
sizeof(libica_func_list_element_int)))
                return EINVAL;
 
        for (i = 0; i < *indicator_list_len; i++) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/src/s390_ecc.c 
new/libica-4.3.0/src/s390_ecc.c
--- old/libica-4.2.3/src/s390_ecc.c     2023-09-20 12:26:01.000000000 +0200
+++ new/libica-4.3.0/src/s390_ecc.c     2024-01-25 09:36:46.000000000 +0100
@@ -42,6 +42,7 @@
 
 #define CPRBXSIZE (sizeof(struct CPRBX))
 #define PARMBSIZE (2048)
+#define MAX_KDSA_RETRIES         10000
 
 
 static int eckeygen_cpacf(ICA_EC_KEY *key);
@@ -168,10 +169,11 @@
                goto err;
        }
 
-       bn_priv = BN_bin2bn(p, plen, NULL);
-       if (bn_priv == NULL) {
+       bn_priv = BN_secure_new();
+       if (bn_priv == NULL)
+               goto err;
+       if (BN_bin2bn(p, plen, bn_priv) == NULL)
                goto err;
-       }
 
        if (!EC_POINT_mul(group, point, bn_priv, NULL, NULL, NULL)) {
                goto err;
@@ -234,7 +236,7 @@
 err:
        EC_POINT_free(point);
        EC_GROUP_free(group);
-       BN_free(bn_priv);
+       BN_clear_free(bn_priv);
 
 #if !OPENSSL_VERSION_PREREQ(3, 0)
        // because we use EVP_PKEY_set1_EC_KEY above, free the ec_key here.
@@ -1267,7 +1269,11 @@
        }
 
        /* Get (D) as BIGNUM */
-       if ((bn_d = BN_bin2bn(privkey->D, privlen, NULL)) == NULL) {
+       bn_d = BN_secure_new();
+       if (bn_d == NULL)
+               return ENOMEM;
+       if (BN_bin2bn(privkey->D, privlen, bn_d) == NULL) {
+               BN_clear_free(bn_d);
                return EFAULT;
        }
 
@@ -1742,17 +1748,33 @@
                if (k == NULL) {
 #ifdef ICA_FIPS
                        if (fips & ICA_FIPS_MODE) {
+                               size_t counter = 0;
                                fc |= 0x80; /* deterministic signature */
+                               do {
+                                       /* If the random number is not 
invertible, s390_kdsa will
+                                        * cause to loop. Same for p384 and 
p521 below. */
+                                       if (RAND_bytes(param.P256.rand + off, 
sizeof(param.P256.rand) - off) != 1) {
+                                               rc = EIO;
+                                               break;
+                                       }
+                                       rc = s390_kdsa(fc, param.buff, NULL, 0) 
? EIO : 0;
+                               } while ((rc != 0) && (++counter < 
MAX_KDSA_RETRIES));
+                       } else {
+                               /* Also create a random k-value for the 
non-deterministic
+                                * case as this number will be hashed with an 
internally
+                                * CPACF-created number and therefore increases 
quality.
+                                * Same below for p384 and p521. */
                                RAND_bytes(param.P256.rand + off, 
sizeof(param.P256.rand) - off);
+                               rc = s390_kdsa(fc, param.buff, NULL, 0) ? EIO : 
0;
                        }
+#else
+                       RAND_bytes(param.P256.rand + off, 
sizeof(param.P256.rand) - off);
+                       rc = s390_kdsa(fc, param.buff, NULL, 0) ? EIO : 0;
 #endif
-                       rc = s390_kdsa(fc, param.buff, NULL, 0);
                } else {
                        fc |= 0x80; /* deterministic signature */
-                       do {
-                               memcpy(param.P256.rand + off, k, 
sizeof(param.P256.rand) - off);
-                               rc = s390_kdsa(fc, param.buff, NULL, 0);
-                       } while (rc);
+                       memcpy(param.P256.rand + off, k, 
sizeof(param.P256.rand) - off);
+                       rc = s390_kdsa(fc, param.buff, NULL, 0) ? EIO : 0;
                }
 
                memcpy(sig, param.P256.sig_r + off,
@@ -1786,17 +1808,27 @@
                if (k == NULL) {
 #ifdef ICA_FIPS
                        if (fips & ICA_FIPS_MODE) {
+                               size_t counter = 0;
                                fc |= 0x80; /* deterministic signature */
+                               do {
+                                       if (RAND_bytes(param.P384.rand + off, 
sizeof(param.P384.rand) - off) != 1) {
+                                               rc = EIO;
+                                               break;
+                                       }
+                                       rc = s390_kdsa(fc, param.buff, NULL, 0) 
? EIO : 0;
+                               } while ((rc != 0) && (++counter < 
MAX_KDSA_RETRIES));
+                       } else {
                                RAND_bytes(param.P384.rand + off, 
sizeof(param.P384.rand) - off);
+                               rc = s390_kdsa(fc, param.buff, NULL, 0) ? EIO : 
0;
                        }
+#else
+                       RAND_bytes(param.P384.rand + off, 
sizeof(param.P384.rand) - off);
+                       rc = s390_kdsa(fc, param.buff, NULL, 0) ? EIO : 0;
 #endif
-                       rc = s390_kdsa(fc, param.buff, NULL, 0);
                } else {
                        fc |= 0x80; /* deterministic signature */
-                       do {
-                               memcpy(param.P384.rand + off, k, 
sizeof(param.P384.rand) - off);
-                               rc = s390_kdsa(fc, param.buff, NULL, 0);
-                       } while (rc);
+                       memcpy(param.P384.rand + off, k, 
sizeof(param.P384.rand) - off);
+                       rc = s390_kdsa(fc, param.buff, NULL, 0) ? EIO : 0;
                }
 
                memcpy(sig, param.P384.sig_r + off,
@@ -1830,19 +1862,38 @@
                if (k == NULL) {
 #ifdef ICA_FIPS
                        if (fips & ICA_FIPS_MODE) {
-                               /* Random number must be invertible by the 
order of the curve.
-                                * Use one byte less */
+                               size_t counter = 0;
                                fc |= 0x80; /* deterministic signature */
-                               RAND_bytes(param.P521.rand + off + 1, 
sizeof(param.P521.rand) - off - 1);
+                               do {
+                                       if (RAND_bytes(param.P521.rand + off, 
sizeof(param.P521.rand) - off) != 1) {
+                                               rc = EIO;
+                                               break;
+                                       }
+                                       /*
+                                        * Before calling KDSA, set the first 7 
bits of the leftmost
+                                        * byte of the generated random number 
to zero, which
+                                        * actually makes the random number a 
521-bit value. If the
+                                        * random nonce has anything else than 
0x01 or 0x00 in the
+                                        * very first byte, it will be larger 
than the order, and
+                                        * thus KDSA will fail with CC=2 and 
the loop takes a retry.
+                                        * So this just minimizes the number of 
retries without
+                                        * decreasing security.
+                                        */
+                                       *(param.P521.rand + off) &= 0x01;
+                                       rc = s390_kdsa(fc, param.buff, NULL, 0) 
? EIO : 0;
+                               } while ((rc != 0) && (++counter < 
MAX_KDSA_RETRIES));
+                       } else {
+                               RAND_bytes(param.P521.rand + off, 
sizeof(param.P521.rand) - off);
+                               rc = s390_kdsa(fc, param.buff, NULL, 0) ? EIO : 
0;
                        }
+#else
+                       RAND_bytes(param.P521.rand + off, 
sizeof(param.P521.rand) - off);
+                       rc = s390_kdsa(fc, param.buff, NULL, 0) ? EIO : 0;
 #endif
-                       rc = s390_kdsa(fc, param.buff, NULL, 0);
                } else {
                        fc |= 0x80; /* deterministic signature */
-                       do {
-                               memcpy(param.P521.rand + off, k, 
sizeof(param.P521.rand) - off);
-                               rc = s390_kdsa(fc, param.buff, NULL, 0);
-                       } while (rc);
+                       memcpy(param.P521.rand + off, k, 
sizeof(param.P521.rand) - off);
+                       rc = s390_kdsa(fc, param.buff, NULL, 0) ? EIO : 0;
                }
 
                memcpy(sig, param.P521.sig_r + off,
@@ -2225,7 +2276,7 @@
        int rv, numbytes;
 
        ctx = BN_CTX_new();
-       priv = BN_new();
+       priv = BN_secure_new();
        ord = BN_new();
 
        if (ctx == NULL || priv == NULL || ord == NULL) {
@@ -2278,7 +2329,7 @@
                if (ctx != NULL)
                        BN_CTX_free(ctx);
                if (priv != NULL)
-                       BN_free(priv);
+                       BN_clear_free(priv);
                if (ord != NULL)
                        BN_free(ord);
 
@@ -2498,15 +2549,21 @@
 EVP_PKEY *icakey2pkey(const ICA_EC_KEY *icakey, int *is_public_key)
 {
        EVP_PKEY *pkey = NULL;
-       BIGNUM *bn_D, *bn_X, *bn_Y;
+       BIGNUM *bn_D, *bn_X = NULL, *bn_Y = NULL;
 
        if (icakey == NULL)
                return NULL;
 
        /* Check if any key parts available */
-       bn_D = BN_bin2bn(icakey->D, privlen_from_nid(icakey->nid), NULL);
+       bn_D = BN_secure_new();
+       if (bn_D == NULL)
+               return NULL;
+       if (BN_bin2bn(icakey->D, privlen_from_nid(icakey->nid), bn_D) == NULL)
+               goto done;
        bn_X = BN_bin2bn(icakey->X, privlen_from_nid(icakey->nid), NULL);
        bn_Y = BN_bin2bn(icakey->Y, privlen_from_nid(icakey->nid), NULL);
+       if (!bn_X || !bn_Y)
+               goto done;
        if (BN_is_zero(bn_D) && BN_is_zero(bn_X) && BN_is_zero(bn_Y))
                goto done;
 
@@ -2524,7 +2581,7 @@
 done:
        BN_free(bn_X);
        BN_free(bn_Y);
-       BN_free(bn_D);
+       BN_clear_free(bn_D);
        return pkey;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/src/s390_rsa.c 
new/libica-4.3.0/src/s390_rsa.c
--- old/libica-4.2.3/src/s390_rsa.c     2023-09-20 12:26:01.000000000 +0200
+++ new/libica-4.3.0/src/s390_rsa.c     2024-01-25 09:36:46.000000000 +0100
@@ -232,6 +232,13 @@
                goto err;
        }
 
+       n = BN_secure_new();
+       d = BN_secure_new();
+       if (!n || !d) {
+               rc = ENOMEM;
+               goto err;
+       }
+
        if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &n) ||
                !EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_D, &d)) {
                rc = EFAULT;
@@ -270,8 +277,8 @@
 #if !OPENSSL_VERSION_PREREQ(3, 0)
        RSA_free(rsa);
 #else
-       BN_free(n);
-       BN_free(d);
+       BN_clear_free(n);
+       BN_clear_free(d);
        EVP_PKEY_free(pkey);
 #endif
 
@@ -337,6 +344,17 @@
                goto err;
        }
 
+       n = BN_secure_new();
+       p = BN_secure_new();
+       q = BN_secure_new();
+       dmp1 = BN_secure_new();
+       dmq1 = BN_secure_new();
+       iqmp = BN_secure_new();
+       if (!n || !p || !q || !dmp1 || !dmq1 || !iqmp) {
+               rc = ENOMEM;
+               goto err;
+       }
+
        if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &n) ||
                !EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &p) ||
                !EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &q) ||
@@ -425,12 +443,12 @@
 #if !OPENSSL_VERSION_PREREQ(3, 0)
        RSA_free(rsa);
 #else
-       BN_free(n);
-       BN_free(p);
-       BN_free(q);
-       BN_free(dmp1);
-       BN_free(dmq1);
-       BN_free(iqmp);
+       BN_clear_free(n);
+       BN_clear_free(p);
+       BN_clear_free(q);
+       BN_clear_free(dmp1);
+       BN_clear_free(dmq1);
+       BN_clear_free(iqmp);
        EVP_PKEY_free(pkey);
 #endif
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-4.2.3/test/rsa_key_check_test.c 
new/libica-4.3.0/test/rsa_key_check_test.c
--- old/libica-4.2.3/test/rsa_key_check_test.c  2023-09-20 12:26:01.000000000 
+0200
+++ new/libica-4.3.0/test/rsa_key_check_test.c  2024-01-25 09:36:46.000000000 
+0100
@@ -41,7 +41,7 @@
 
                gettimeofday(&start, NULL);
                rc = ica_rsa_crt_key_check(&crt_key);
-               if(rc){
+               if (rc > 1) {
                        V_(printf("ica_rsa_crt_key_check failed!\n"));
                }
 

Reply via email to