Hello community,

here is the log from the commit of package libica for openSUSE:Factory checked 
in at 2020-09-22 21:12:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libica (Old)
 and      /work/SRC/openSUSE:Factory/.libica.new.4249 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libica"

Tue Sep 22 21:12:27 2020 rev:20 rq:835924 version:3.7.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/libica/libica.changes    2020-09-17 
14:51:34.879952830 +0200
+++ /work/SRC/openSUSE:Factory/.libica.new.4249/libica.changes  2020-09-22 
21:12:38.440006012 +0200
@@ -1,0 +2,22 @@
+Fri Sep 18 20:59:39 UTC 2020 - Mark Post <mp...@suse.com>
+
+- Upgraded to version 3.7.0 (jsc#SLE-14466)
+  * Version 3.7.0
+    - [FEATURE] FIPS: Add HMAC based library integrity check
+    - [PATCH] icainfo: bugfix for RSA and EC related info for software column.
+    - [PATCH] FIPS: provide output iv in cbc-cs decrypt as required by FIPS 
tests
+    - [PATCH] FIPS: Fix DES and TDES key length
+    - [PATCH] icastats: Fix stats counter format
+  * Version 3.6.1
+    - [PATCH] Fix x25519 and x448 handling of non-canonical values
+- Removed the following obsolete patches
+  * libica-sles15sp2-x25519-x448-fix-handling-of-non-canonical-values.patch
+  * libica-sles15sp2-Fix-DES-and-TDES-key-length.patch
+  * libica-sles15sp2-FIPS-provide-output-iv-as-required-by-FIPS-tests.patch
+  * libica-sles15sp2-icainfo-bugfix-for-RSA-and-EC-related-info-for-softw.patch
+  * libica-sles15sp2-Build-with-pthread-flag.patch
+  * libica-sles15sp2-FIPS-introduce-HMAC-based-library-integrity-check.patch
+  * libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-addon.patch
+  * 
libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-rename-variables.patch
+
+-------------------------------------------------------------------

Old:
----
  libica-3.6.0.tar.gz
  libica-sles15sp2-Build-with-pthread-flag.patch
  libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-addon.patch
  
libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-rename-variables.patch
  libica-sles15sp2-FIPS-introduce-HMAC-based-library-integrity-check.patch
  libica-sles15sp2-FIPS-provide-output-iv-as-required-by-FIPS-tests.patch
  libica-sles15sp2-Fix-DES-and-TDES-key-length.patch
  libica-sles15sp2-icainfo-bugfix-for-RSA-and-EC-related-info-for-softw.patch
  libica-sles15sp2-x25519-x448-fix-handling-of-non-canonical-values.patch

New:
----
  libica-3.7.0.tar.gz

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

Other differences:
------------------
++++++ libica.spec ++++++
--- /var/tmp/diff_new_pack.hvKyaz/_old  2020-09-22 21:12:39.796007198 +0200
+++ /var/tmp/diff_new_pack.hvKyaz/_new  2020-09-22 21:12:39.796007198 +0200
@@ -22,7 +22,7 @@
 %endif
 
 Name:           libica
-Version:        3.6.0
+Version:        3.7.0
 Release:        0
 Summary:        Library interface for the IBM Cryptographic Accelerator device 
driver
 License:        CPL-1.0
@@ -37,19 +37,11 @@
 Source5:        z90crypt.service
 Source6:        baselibs.conf
 Source7:        %{name}-rpmlintrc
-Patch1:         
libica-sles15sp2-x25519-x448-fix-handling-of-non-canonical-values.patch
-Patch2:         libica-sles15sp2-Fix-DES-and-TDES-key-length.patch
-Patch3:         
libica-sles15sp2-FIPS-provide-output-iv-as-required-by-FIPS-tests.patch
-Patch4:         
libica-sles15sp2-icainfo-bugfix-for-RSA-and-EC-related-info-for-softw.patch
-Patch5:         libica-sles15sp2-Build-with-pthread-flag.patch
-Patch6:         
libica-sles15sp2-FIPS-introduce-HMAC-based-library-integrity-check.patch
-Patch7:         
libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-addon.patch
-Patch8:         
libica-sles15sp2-FIPS-HMAC-based-library-integrity-check-rename-variables.patch
-Patch9:         libica-sles15sp2-Zeroize-local-variables.patch
-Patch10:        libica-sles15sp2-FIPS-add-SHA3-KATs-to-fips_powerup_tests.patch
-Patch11:        
libica-sles15sp2-FIPS-skip-SHA3-tests-if-running-on-hardware-without-.patch
-Patch12:        
libica-sles15sp2-FIPS-use-full-library-version-for-hmac-filename.patch
-Patch13:        libica-sles15sp2-FIPS-fix-inconsistent-error-handling.patch
+Patch01:        libica-sles15sp2-Zeroize-local-variables.patch
+Patch02:        libica-sles15sp2-FIPS-add-SHA3-KATs-to-fips_powerup_tests.patch
+Patch03:        
libica-sles15sp2-FIPS-skip-SHA3-tests-if-running-on-hardware-without-.patch
+Patch04:        
libica-sles15sp2-FIPS-use-full-library-version-for-hmac-filename.patch
+Patch05:        libica-sles15sp2-FIPS-fix-inconsistent-error-handling.patch
 Patch99:        libica-sles15sp2-FIPS-hmac-key.patch
 
 BuildRequires:  autoconf

++++++ libica-3.6.0.tar.gz -> libica-3.7.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/.travis.yml new/libica-3.7.0/.travis.yml
--- old/libica-3.6.0/.travis.yml        1970-01-01 01:00:00.000000000 +0100
+++ new/libica-3.7.0/.travis.yml        2020-05-14 15:32:36.000000000 +0200
@@ -0,0 +1,17 @@
+dist: bionic
+
+language: c
+
+matrix:
+    include:
+        - name: "linux-s390x-gcc"
+          os: linux
+          arch: s390x
+          compiler: gcc
+          env: CONFIG_OPTS="--enable-fips --enable-internal-tests"
+
+before_script:
+    - ./bootstrap.sh
+
+script:
+    - ./configure $CONFIG_OPTS && make check
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/ChangeLog new/libica-3.7.0/ChangeLog
--- old/libica-3.6.0/ChangeLog  2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/ChangeLog  2020-05-14 15:32:36.000000000 +0200
@@ -1,3 +1,11 @@
+v3.7.0
+ - [FEATURE] FIPS: Add HMAC based library integrity check
+ - [PATCH] icainfo: bugfix for RSA and EC related info for software column.
+ - [PATCH] FIPS: provide output iv in cbc-cs decrypt as required by FIPS tests
+ - [PATCH] FIPS: Fix DES and TDES key length
+ - [PATCH] icastats: Fix stats counter format
+v3.6.1
+ - [PATCH] Fix x25519 and x448 handling of non-canonical values
 v3.6.0
  - [FEATURE] Add MSA9 CPACF support for Ed25519, Ed448, X25519 and X448
 v3.5.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/configure.ac 
new/libica-3.7.0/configure.ac
--- old/libica-3.6.0/configure.ac       2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/configure.ac       2020-05-14 15:32:36.000000000 +0200
@@ -1,4 +1,4 @@
-AC_INIT([libica], [3.6.0], [ste...@linux.vnet.ibm.com],, 
[https://github.com/opencryptoki/libica])
+AC_INIT([libica], [3.7.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-3.6.0/include/ica_api.h 
new/libica-3.7.0/include/ica_api.h
--- old/libica-3.6.0/include/ica_api.h  2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/include/ica_api.h  2020-05-14 15:32:36.000000000 +0200
@@ -216,7 +216,7 @@
  */
 /* Cryptographic algorithm test (KAT or pair-wise consistency test) */
 #define ICA_FIPS_CRYPTOALG     2
-/* Software/Firmware integrity test (not implemented yet) */
+/* Software/Firmware integrity test */
 #define ICA_FIPS_INTEGRITY     4
 /* Critical functions test (N/A) */
 #define ICA_FIPS_CRITICALFUNC  8
@@ -915,6 +915,12 @@
  *
  *                          Begin of ECC API
  */
+#ifndef NID_X25519
+# define NID_X25519    1034
+#endif
+#ifndef NID_X448
+# define NID_X448      1035
+#endif
 #ifndef NID_ED25519
 # define NID_ED25519   1087
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/libica.spec new/libica-3.7.0/libica.spec
--- old/libica-3.6.0/libica.spec        2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/libica.spec        2020-05-14 15:32:36.000000000 +0200
@@ -1,5 +1,5 @@
 Name:          libica
-Version:       3.6.0
+Version:       3.7.0
 Release:       1%{?dist}
 Summary:       Interface library to the ICA device driver
 
@@ -62,6 +62,10 @@
 %{_includedir}/ica_api.h
 
 %changelog
+* Tue May 06 2020 Joerg Schmidbauer <jschm...@linux.vnet.ibm.com>
+- Version v3.7.0
+* Wed Nov 13 2019 Patrick Steuer <ste...@linux.vnet.ibm.com>
+- Version v3.6.1
 * Wed Aug 28 2019 Patrick Steuer <ste...@linux.vnet.ibm.com>
 - Version v3.6.0
 * Tue Apr 23 2019 Patrick Steuer <ste...@linux.vnet.ibm.com>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/src/Makefile.am 
new/libica-3.7.0/src/Makefile.am
--- old/libica-3.6.0/src/Makefile.am    2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/src/Makefile.am    2020-05-14 15:32:36.000000000 +0200
@@ -1,4 +1,4 @@
-VERSION = 3:6:0
+VERSION = 3:7:0
 
 AM_CFLAGS = @FLAGS@
 
@@ -7,9 +7,9 @@
 lib_LTLIBRARIES = libica.la
 
 libica_la_CFLAGS = ${AM_CFLAGS} -I${srcdir}/include -I${srcdir}/../include \
-                  -fvisibility=hidden
+                  -fvisibility=hidden -pthread
 libica_la_CCASFLAGS = ${AM_CFLAGS}
-libica_la_LIBADD = @LIBS@ -lrt -lcrypto
+libica_la_LIBADD = @LIBS@ -lrt -lcrypto -ldl
 libica_la_LDFLAGS = -Wl,--version-script=${srcdir}/../libica.map \
                    -version-number ${VERSION}
 libica_la_SOURCES = ica_api.c init.c icastats_shared.c s390_rsa.c \
@@ -53,7 +53,7 @@
                                         -DICA_INTERNAL_TEST \
                                         -DICA_INTERNAL_TEST_EC
 internal_tests_ec_internal_test_CCASFLAGS = ${AM_CFLAGS}
-internal_tests_ec_internal_test_LDADD = @LIBS@ -lrt -lcrypto -lpthread
+internal_tests_ec_internal_test_LDADD = @LIBS@ -lrt -lcrypto -lpthread -ldl
 internal_tests_ec_internal_test_SOURCES = \
                    ica_api.c init.c icastats_shared.c s390_rsa.c \
                    s390_crypto.c s390_ecc.c s390_prng.c s390_sha.c \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/src/fips.c new/libica-3.7.0/src/fips.c
--- old/libica-3.6.0/src/fips.c 2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/src/fips.c 2020-05-14 15:32:36.000000000 +0200
@@ -13,11 +13,13 @@
 
 #include <errno.h>
 #include <openssl/crypto.h>
+#include <openssl/evp.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <syslog.h>
+#include <dlfcn.h>
 
 #include <openssl/opensslconf.h>
 #ifdef OPENSSL_FIPS
@@ -28,6 +30,24 @@
 #include "ica_api.h"
 #include "test_vec.h"
 
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
+#define HMAC_PREFIX "."
+#define HMAC_SUFFIX ".hmac"
+#define READ_BUFFER_LENGTH 16384
+
+/*
+ * The hard-coded HMAC key to be optionally provided for the library
+ * integrity test. The recommended key size for HMAC-SHA256 is 64 bytes.
+ * The known HMAC is supposed to be provided as hex string in a file
+ * libica.so.MAJOR.hmac in the same directory as the .so module.
+ */
+static const char hmackey[] =
+       "0000000000000000000000000000000000000000000000000000000000000000"
+       "0000000000000000000000000000000000000000000000000000000000000000";
+
 int fips;
 
 static int aes_ecb_kat(void);
@@ -101,6 +121,209 @@
                FIPS_mode_set(1);
        }
 }
+static int get_library_path(const char *libname, const char *symbolname,
+                                                       char *path, size_t 
pathlen)
+{
+       Dl_info info;
+       void *dl, *sym;
+       int rc = -1;
+
+       dl = dlopen(libname, RTLD_LAZY);
+       if (dl == NULL)
+               goto done;
+
+       sym = dlsym(dl, symbolname);
+       if (sym != NULL && dladdr(sym, &info)) {
+               if (strlen(info.dli_fname) < pathlen)
+                       strcpy(path, info.dli_fname);
+               else
+                       goto done;
+       }
+
+       rc = 0;
+
+done:
+       if (dl != NULL)
+               dlclose(dl);
+
+       return rc;
+}
+
+static char *make_hmac_path(const char *origpath)
+{
+       char *path;
+       const char *fn;
+
+       path = calloc(1, sizeof(HMAC_PREFIX) + sizeof(HMAC_SUFFIX) + 
strlen(origpath) + 1);
+       if (path == NULL)
+               return NULL;
+
+       fn = strrchr(origpath, '/');
+       if (fn == NULL) {
+               fn = origpath;
+       } else {
+               ++fn;
+       }
+
+       strncpy(path, origpath, fn - origpath);
+       strcat(path, HMAC_PREFIX);
+       strcat(path, fn);
+       strcat(path, HMAC_SUFFIX);
+
+       return path;
+}
+
+static int compute_file_hmac(const char *path, void **buf, size_t *hmaclen)
+{
+       FILE *fp = NULL;
+       int rc = -1;
+       unsigned char rbuf[READ_BUFFER_LENGTH];
+       unsigned char *keybuf;
+       EVP_MD_CTX *mdctx = NULL;
+       EVP_PKEY *pkey = NULL;
+       size_t hlen, len;
+       long keylen;
+
+       *buf = NULL;
+       *hmaclen = 0;
+
+       keybuf = OPENSSL_hexstr2buf(hmackey, &keylen);
+       pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, keybuf, (int)keylen);
+       if (!pkey)
+               goto end;
+
+       mdctx = EVP_MD_CTX_create();
+       if (!mdctx)
+               goto end;
+
+       fp = fopen(path, "r");
+       if (fp == NULL)
+               goto end;
+
+       if (EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, pkey) <= 0)
+               goto end;
+
+       while ((len = fread(rbuf, 1, sizeof(rbuf), fp)) != 0) {
+               if (EVP_DigestSignUpdate(mdctx, rbuf, len) <= 0) {
+                       goto end;
+               }
+       }
+
+       if (EVP_DigestSignFinal(mdctx, rbuf, &hlen) <= 0)
+               goto end;
+
+       *buf = malloc(hlen);
+       if (*buf == NULL)
+               goto end;
+
+       *hmaclen = hlen;
+
+       memcpy(*buf, rbuf, hlen);
+
+       rc = 0;
+
+end:
+
+       if (pkey != NULL)
+               EVP_PKEY_free(pkey);
+
+       free(keybuf);
+       EVP_MD_CTX_destroy(mdctx);
+       if (fp)
+               fclose(fp);
+
+       return rc;
+}
+
+/**
+ * Performs the FIPS check.
+ *
+ * @return  1 if check succeeded
+ *          0 otherwise
+ */
+static int FIPSCHECK_verify(const char *path)
+{
+       int rc = 0;
+       FILE *fp;
+       unsigned char *known_hmac = NULL;
+       long hmaclen;
+       char *hmacpath, *p;
+       char *known_hmac_str = NULL;
+       size_t n, computed_hmac_len;
+       void *computed_hmac = NULL;
+
+       hmacpath = make_hmac_path(path);
+       if (hmacpath == NULL)
+               return 0;
+
+       fp = fopen(hmacpath, "r");
+       if (fp == NULL) {
+               rc = 1;
+               goto end;
+       }
+
+       if (getline(&known_hmac_str, &n, fp) <= 0)
+               goto end;
+
+       if ((p = strchr(known_hmac_str, '\n')) != NULL)
+               *p = '\0';
+
+       known_hmac = OPENSSL_hexstr2buf(known_hmac_str, &hmaclen);
+
+       if (compute_file_hmac(path, &computed_hmac, &computed_hmac_len) != 0)
+               goto end;
+
+       if (memcmp(computed_hmac, known_hmac, computed_hmac_len) != 0)
+               goto end;
+
+       rc = 1;
+
+end:
+
+       free(computed_hmac);
+       free(known_hmac_str);
+       free(hmacpath);
+
+       OPENSSL_free(known_hmac);
+
+       if (fp)
+               fclose(fp);
+
+       return rc;
+}
+
+static const char msg1[] = "Libica FIPS library integrity check failed. Cannot 
determine library path.\n";
+static const char msg2[] = "Libica FIPS library integrity check failed. Module 
%s probably corrupted.\n";
+static const char msg3[] = "Libica FIPS library integrity check passed.\n";
+
+/*
+ * Perform an integrity check on libica.so by calculating an HMAC from
+ * the file contents using a static HMAC key, and comparing it to a
+ * pre-calculated HMAC in a separate file. The HMAC key and HMAC file
+ * may be provided by a Distributor when building the packet.
+ */
+static void fips_lib_integrity_check(void)
+{
+       int rc;
+       char path[PATH_MAX];
+       const char *libname = "libica.so";
+       const char *symbolname = "ica_sha256";
+
+       rc = get_library_path(libname, symbolname, path, sizeof(path));
+       if (rc != 0) {
+               syslog(LOG_ERR, msg1);
+               fips |= ICA_FIPS_INTEGRITY;
+               return;
+       }
+
+       if (!FIPSCHECK_verify(path)) {
+               syslog(LOG_ERR, msg2, path);
+               fips |= ICA_FIPS_INTEGRITY;
+               return;
+       }
+
+       syslog(LOG_INFO, msg3);
+}
 
 void
 fips_powerup_tests(void)
@@ -117,6 +340,9 @@
                fips |= ICA_FIPS_CRYPTOALG;
                return;
        }
+
+       /* Library integrity test */
+       fips_lib_integrity_check();
 }
 
 static int
@@ -933,5 +1159,4 @@
        syslog(LOG_ERR, "Libica RSA test failed.");
        return 1;
 }
-
 #endif /* FIPS_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/src/ica_api.c 
new/libica-3.7.0/src/ica_api.c
--- old/libica-3.6.0/src/ica_api.c      2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/src/ica_api.c      2020-05-14 15:32:36.000000000 +0200
@@ -48,6 +48,8 @@
 #define DEFAULT2_CRYPT_DEVICE "/dev/z90crypt"
 #define DEFAULT3_CRYPT_DEVICE "/dev/zcrypt"
 
+#define DES_KEY_LEN64          (64/8)
+
 #define MAX_VERSION_LENGTH 16
 
 int ica_fallbacks_enabled = 1;
@@ -125,9 +127,9 @@
 
 #ifdef ICA_FIPS
 static unsigned int fips_check_3des_key(const ica_des_key_triple_t *key) {
-       if (!CRYPTO_memcmp(key->key1, key->key2, DES_KEY_LENGTH)
-           | !CRYPTO_memcmp(key->key1, key->key3, DES_KEY_LENGTH)
-           | !CRYPTO_memcmp(key->key2, key->key3, DES_KEY_LENGTH))
+       if (!CRYPTO_memcmp(key->key1, key->key2, DES_KEY_LEN64)
+           | !CRYPTO_memcmp(key->key1, key->key3, DES_KEY_LEN64)
+           | !CRYPTO_memcmp(key->key2, key->key3, DES_KEY_LEN64))
                return EINVAL;
 
        return 0;
@@ -1479,6 +1481,7 @@
        if (priv != NULL) {
                memcpy(ctx->priv, priv, 32);
                ctx->priv_init = 1;
+               memset(ctx->pub, 0, 32);
                ctx->pub_init = 0;
        }
 
@@ -1500,6 +1503,7 @@
        if (priv != NULL) {
                memcpy(ctx->priv, priv, 56);
                ctx->priv_init = 1;
+               memset(ctx->pub, 0, 56);
                ctx->pub_init = 0;
        }
 
@@ -1521,6 +1525,7 @@
        if (priv != NULL) {
                memcpy(ctx->sign_param.priv, priv, 32);
                ctx->priv_init = 1;
+               memset(ctx->verify_param.pub, 0, 32);
                ctx->pub_init = 0;
        }
 
@@ -1543,6 +1548,7 @@
                memset(ctx->sign_param.priv, 0, sizeof(ctx->sign_param.priv));
                memcpy(ctx->sign_param.priv + 64 - 57, priv, 57);
                ctx->priv_init = 1;
+               memset(ctx->verify_param.pub, 0, 57);
                ctx->pub_init = 0;
        }
 
@@ -1579,8 +1585,10 @@
                                return -1;
 
                        rc = x25519_derive_pub(ctx->pub, ctx->priv);
-                       if (rc)
+                       if (rc) {
+                               memset(ctx->pub, 0, 32);
                                return -1;
+                       }
 
                        ctx->pub_init = 1;
                }
@@ -1612,8 +1620,10 @@
                                return -1;
 
                        rc = x448_derive_pub(ctx->pub, ctx->priv);
-                       if (rc)
+                       if (rc) {
+                               memset(ctx->pub, 0, 56);
                                return -1;
+                       }
 
                        ctx->pub_init = 1;
                }
@@ -1647,8 +1657,10 @@
 
                        rc = ed25519_derive_pub(ctx->verify_param.pub,
                                                ctx->sign_param.priv);
-                       if (rc)
+                       if (rc) {
+                               memset(ctx->verify_param.pub, 0, 32);
                                return -1;
+                       }
 
                        ctx->pub_init = 1;
                }
@@ -1683,8 +1695,10 @@
 
                        rc = ed448_derive_pub(ctx->verify_param.pub + 64 - 57,
                                              ctx->sign_param.priv + 64 - 57);
-                       if (rc)
+                       if (rc) {
+                               memset(ctx->verify_param.pub, 0, 57);
                                return -1;
+                       }
 
                        ctx->pub_init = 1;
                }
@@ -1740,8 +1754,10 @@
 
        rc = s390_kdsa(S390_CRYPTO_EDDSA_SIGN_ED25519,
                       &ctx->sign_param, msg, msglen);
-       if (rc)
+       if (rc) {
+               memset(ctx->sign_param.sig, 0, sizeof(ctx->sign_param.sig));
                return -1;
+       }
 
        s390_flip_endian_32(sig, ctx->sign_param.sig);
        s390_flip_endian_32(sig + 32, ctx->sign_param.sig + 32);
@@ -1762,8 +1778,10 @@
 
        rc = s390_kdsa(S390_CRYPTO_EDDSA_SIGN_ED448,
                       &ctx->sign_param, msg, msglen);
-       if (rc)
+       if (rc) {
+               memset(ctx->sign_param.sig, 0, sizeof(ctx->sign_param.sig));
                return -1;
+       }
 
        s390_flip_endian_64(ctx->sign_param.sig, ctx->sign_param.sig);
        s390_flip_endian_64(ctx->sign_param.sig + 64,
@@ -1791,8 +1809,10 @@
 
                rc = ed25519_derive_pub(ctx->verify_param.pub,
                                        ctx->sign_param.priv);
-               if (rc)
+               if (rc) {
+                       memset(ctx->verify_param.pub, 0, 32);
                        return -1;
+               }
 
                ctx->pub_init = 1;
        }
@@ -1802,13 +1822,11 @@
 
        rc = s390_kdsa(S390_CRYPTO_EDDSA_VERIFY_ED25519,
                       &ctx->verify_param, msg, msglen);
-       if (rc)
-               return -1;
 
        memset(ctx->verify_param.sig, 0, sizeof(ctx->verify_param.sig));
 
        stats_increment(ICA_STATS_ED25519_VERIFY, ALGO_HW, ENCRYPT);
-       return 0;
+       return rc == 0 ? 0 : -1;
 }
 
 int ica_ed448_verify(ICA_ED448_CTX *ctx, const unsigned char sig[114],
@@ -1826,8 +1844,10 @@
 
                rc = ed448_derive_pub(ctx->verify_param.pub + 64 - 57,
                                      ctx->sign_param.priv + 64 - 57);
-               if (rc)
+               if (rc) {
+                       memset(ctx->verify_param.pub, 0, 57);
                        return -1;
+               }
 
                ctx->pub_init = 1;
        }
@@ -1841,12 +1861,12 @@
        rc = s390_kdsa(S390_CRYPTO_EDDSA_VERIFY_ED448,
                       &ctx->verify_param, msg, msglen);
        if (rc || sig[113] != 0)        /* XXX kdsa doesnt check last byte */
-               return -1;
+               rc = -1;
 
        memset(ctx->verify_param.sig, 0, sizeof(ctx->verify_param.sig));
 
        stats_increment(ICA_STATS_ED448_VERIFY, ALGO_HW, ENCRYPT);
-       return 0;
+       return rc == 0 ? 0 : -1;
 }
 
 int ica_x25519_ctx_del(ICA_X25519_CTX **ctx)
@@ -1899,11 +1919,10 @@
                return -1;
 
        memset(ctx, 0, sizeof(*ctx));
+       ctx->pub_init = 0;
 
        rng_gen(ctx->priv, 32);
-
        ctx->priv_init = 1;
-       ctx->pub_init = 0;
        return 0;
 }
 
@@ -1913,11 +1932,10 @@
                return -1;
 
        memset(ctx, 0, sizeof(*ctx));
+       ctx->pub_init = 0;
 
        rng_gen(ctx->priv, 56);
-
        ctx->priv_init = 1;
-       ctx->pub_init = 0;
        return 0;
 }
 
@@ -1927,11 +1945,10 @@
                return -1;
 
        memset(ctx, 0, sizeof(*ctx));
+       ctx->pub_init = 0;
 
        rng_gen(ctx->sign_param.priv, sizeof(ctx->sign_param.priv));
-
        ctx->priv_init = 1;
-       ctx->pub_init = 0;
        return 0;
 }
 
@@ -1941,12 +1958,11 @@
                return -1;
 
        memset(ctx, 0, sizeof(*ctx));
+       ctx->pub_init = 0;
 
        rng_gen(ctx->sign_param.priv + 64 - 57,
                sizeof(ctx->sign_param.priv) - (64 - 57));
-
        ctx->priv_init = 1;
-       ctx->pub_init = 0;
        return 0;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/src/icastats.c 
new/libica-3.7.0/src/icastats.c
--- old/libica-3.6.0/src/icastats.c     2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/src/icastats.c     2020-05-14 15:32:36.000000000 +0200
@@ -10,7 +10,7 @@
  *             Benedikt Klotz <benedikt.kl...@de.ibm.com>
  *             Ingo Tuchscherer <ingo.tuchsche...@de.ibm.com>
  *
- * Copyright IBM Corp. 2009, 2010, 2011, 2014
+ * Copyright IBM Corp. 2009-2019
  */
 
 #include <stdio.h>
@@ -24,7 +24,7 @@
 #include "icastats.h"
 
 #define CMD_NAME "icastats"
-#define COPYRIGHT "Copyright IBM Corp. 2009, 2010, 2011, 2014."
+#define COPYRIGHT "Copyright IBM Corp. 2009-2019"
 
 void print_version(void)
 {
@@ -69,24 +69,24 @@
 
 
 
-#define CELL_SIZE 10
+#define CELL_SIZE 12
 void print_stats(stats_entry_t *stats)
 {
-       printf(" function       |           hardware       |            
software\n");
-       
printf("----------------+--------------------------+-------------------------\n");
-       printf("                |      ENC    CRYPT   DEC  |      ENC    CRYPT  
 DEC \n");
-       
printf("----------------+--------------------------+-------------------------\n");
+       printf(" function       |             hardware         |              
software\n");
+       
printf("----------------+------------------------------+-----------------------------\n");
+       printf("                |        ENC    CRYPT     DEC  |        ENC     
CRYPT    DEC \n");
+       
printf("----------------+------------------------------+-----------------------------\n");
        unsigned int i;
        for (i = 0; i < ICA_NUM_STATS; ++i){
                if(i<=ICA_STATS_RSA_CRT){
-                       printf(" %14s |      %*d          |       %*d\n",
+                       printf(" %14s |        %*lu          |         %*lu\n",
                               STATS_DESC[i],
                               CELL_SIZE,
                               stats[i].enc.hw,
                               CELL_SIZE,
                               stats[i].enc.sw);
                } else{
-                       printf(" %14s |%*d     %*d |%*d    %*d\n",
+                       printf(" %14s |%*lu     %*lu |%*lu    %*lu\n",
                               STATS_DESC[i],
                               CELL_SIZE,
                               stats[i].enc.hw,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/src/icastats_shared.c 
new/libica-3.7.0/src/icastats_shared.c
--- old/libica-3.6.0/src/icastats_shared.c      2019-08-29 21:33:33.000000000 
+0200
+++ new/libica-3.7.0/src/icastats_shared.c      2020-05-14 15:32:36.000000000 
+0200
@@ -34,18 +34,18 @@
 volatile int stats_shm_handle = NOT_INITIALIZED;
 
 
-static inline void atomic_add(int *x, int i)
+static inline void atomic_add(uint64_t *x, uint64_t i)
 {
-       int old;
-       int new;
-       asm volatile (" l       %0,%2\n"
-                     "0:       lr      %1,%0\n"
-                     " ar      %1,%3\n"
-                     " cs      %0,%1,%2\n"
-                     " jl      0b"
-                     :"=&d" (old), "=&d"(new), "=Q"(*x)
-                     :"d"(i), "Q"(*x)
-                     :"cc", "memory");
+    uint64_t old;
+    uint64_t new;
+    asm volatile ("   lg      %0,%2\n"
+                  "0: lgr     %1,%0\n"
+                  "   agr     %1,%3\n"
+                  "   csg     %0,%1,%2\n"
+                  "   jl      0b"
+                 :"=&d" (old), "=&d"(new), "=Q"(*x)
+                 :"d"(i), "Q"(*x)
+                 :"cc", "memory");
 }
 
 
@@ -125,7 +125,7 @@
  * @direction - valid values are ENCRYPT and DECRYPT
  */
 
-uint32_t stats_query(stats_fields_t field, int hardware, int direction)
+uint64_t stats_query(stats_fields_t field, int hardware, int direction)
 {
        if (stats == NULL)
                return 0;
@@ -277,14 +277,14 @@
 
        if(direction == ENCRYPT)
                if (hardware == ALGO_HW)
-                       atomic_add((int *)&stats[field].enc.hw, 1);
+                       atomic_add(&stats[field].enc.hw, 1);
                else
-                       atomic_add((int *)&stats[field].enc.sw, 1);
+                       atomic_add(&stats[field].enc.sw, 1);
        else
                if (hardware == ALGO_HW)
-                       atomic_add((int *)&stats[field].dec.hw, 1);
+                       atomic_add(&stats[field].dec.hw, 1);
                else
-                       atomic_add((int *)&stats[field].dec.sw, 1);
+                       atomic_add(&stats[field].dec.sw, 1);
 }
 #endif
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/src/include/fips.h 
new/libica-3.7.0/src/include/fips.h
--- old/libica-3.6.0/src/include/fips.h 2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/src/include/fips.h 2020-05-14 15:32:36.000000000 +0200
@@ -27,8 +27,8 @@
 void fips_init(void);
 
 /*
- * Powerup tests: crypto algorithm test, SW/FW integrity test (not implemented
- * yet), critical function test (no critical functions). The tests set the
+ * Powerup tests: crypto algorithm test, SW/FW integrity test, critical
+ * function test (no critical functions). The tests set the
  * corresponding status flags.
  */
 void fips_powerup_tests(void);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/src/include/icastats.h 
new/libica-3.7.0/src/include/icastats.h
--- old/libica-3.6.0/src/include/icastats.h     2019-08-29 21:33:33.000000000 
+0200
+++ new/libica-3.7.0/src/include/icastats.h     2020-05-14 15:32:36.000000000 
+0200
@@ -18,8 +18,8 @@
 
 
 typedef struct crypt_opts{
-       uint32_t hw;
-       uint32_t sw;
+       uint64_t hw;
+       uint64_t sw;
 } crypt_opts_t;
 
 typedef struct statis_entry {
@@ -159,7 +159,7 @@
 
 int stats_mmap(int user);
 void stats_munmap(int unlink);
-uint32_t stats_query(stats_fields_t field, int hardware, int direction);
+uint64_t stats_query(stats_fields_t field, int hardware, int direction);
 void get_stats_data(stats_entry_t *entries);
 void stats_increment(stats_fields_t field, int hardware, int direction);
 int get_stats_sum(stats_entry_t *sum);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/src/include/s390_cbccs.h 
new/libica-3.7.0/src/include/s390_cbccs.h
--- old/libica-3.6.0/src/include/s390_cbccs.h   2019-08-29 21:33:33.000000000 
+0200
+++ new/libica-3.7.0/src/include/s390_cbccs.h   2020-05-14 15:32:36.000000000 
+0200
@@ -287,6 +287,17 @@
        block_xor(out_data + tmp_data_length + AES_BLOCK_SIZE,
                  tmp_in_data, tmp_out_data, rest_data_length);
 
+       /*
+        * This fix was introduced to satisfy FIPS tests. They require the
+        * output iv to be the iv resulting from decrypting the last block
+        * with a zero iv as input, which is tmp_iv here. But note that this
+        * is not described in the NIST standard for CBC-CS. According to the
+        * standard, the output iv is simply undefined.
+        */
+#ifdef ICA_FIPS
+       memcpy(iv, tmp_iv, AES_BLOCK_SIZE);
+#endif /* ICA_FIPS */
+
        return 0;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/src/s390_crypto.c 
new/libica-3.7.0/src/s390_crypto.c
--- old/libica-3.6.0/src/s390_crypto.c  2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/src/s390_crypto.c  2020-05-14 15:32:36.000000000 +0200
@@ -489,10 +489,10 @@
  {AES_GCM_KMA,  MSA8, AES_128_GCM_ENCRYPT,       0, 0},
  {AES_XTS,      MSA4, AES_128_XTS_ENCRYPT,       0, 0},
  {P_RNG,        ADAPTER, 0, ICA_FLAG_SHW | ICA_FLAG_SW, 0}, // SHW (CPACF) + SW
- {EC_DH,        ADAPTER, 0, 0, 0},
- {EC_DSA_SIGN, ADAPTER, 0, 0, 0},
- {EC_DSA_VERIFY, ADAPTER, 0, 0, 0},
- {EC_KGEN,      ADAPTER, 0, 0, 0},
+ {EC_DH,        ADAPTER, 0, ICA_FLAG_SW, 0},
+ {EC_DSA_SIGN, ADAPTER, 0, ICA_FLAG_SW, 0},
+ {EC_DSA_VERIFY, ADAPTER, 0, ICA_FLAG_SW, 0},
+ {EC_KGEN,      ADAPTER, 0, ICA_FLAG_SW, 0},
  {ED25519_KEYGEN, MSA9, SCALAR_MULTIPLY_ED25519, 0, 0},
  {ED25519_SIGN,   MSA9, EDDSA_SIGN_ED25519, 0, 0},
  {ED25519_VERIFY, MSA9, EDDSA_VERIFY_ED25519, 0, 0},
@@ -503,8 +503,8 @@
  {X25519_DERIVE,   MSA9, SCALAR_MULTIPLY_X25519, 0, 0},
  {X448_KEYGEN,   MSA9, SCALAR_MULTIPLY_X448, 0, 0},
  {X448_DERIVE,   MSA9, SCALAR_MULTIPLY_X448, 0, 0},
- {RSA_ME,       ADAPTER, 0, 0, 0},
- {RSA_CRT,      ADAPTER, 0, 0, 0},
+ {RSA_ME,       ADAPTER, 0, ICA_FLAG_SW, 0},
+ {RSA_CRT,      ADAPTER, 0, ICA_FLAG_SW, 0},
  {RSA_KEY_GEN_ME, ADAPTER, 0, ICA_FLAG_SW, 0},  // SW (openssl)
  {RSA_KEY_GEN_CRT, ADAPTER, 0, ICA_FLAG_SW, 0}, // SW (openssl)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/src/s390_ecc.c 
new/libica-3.7.0/src/s390_ecc.c
--- old/libica-3.6.0/src/s390_ecc.c     2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/src/s390_ecc.c     2020-05-14 15:32:36.000000000 +0200
@@ -557,6 +557,91 @@
        return rc;
 }
 
+/*
+ * mask must be 0xFF or 0x00.
+ * "constant time" is per len.
+ *
+ * if (mask) {
+ *     unsigned char tmp[len];
+ *
+ *     memcpy(tmp, a, len);
+ *     memcpy(a, b);
+ *     memcpy(b, tmp);
+ * }
+ */
+static inline void constant_time_cond_swap_buff(unsigned char mask,
+                                               unsigned char *a,
+                                               unsigned char *b,
+                                               size_t len)
+{
+       size_t i;
+       unsigned char tmp;
+
+       for (i = 0; i < len; i++) {
+               tmp = a[i] ^ b[i];
+               tmp &= mask;
+               a[i] ^= tmp;
+               b[i] ^= tmp;
+       }
+}
+
+
+static void s390_x25519_mod_p(unsigned char u[32])
+{
+       unsigned char u_red[32];
+       unsigned int c = 0;
+       int i;
+
+       memcpy(u_red, u, sizeof(u_red));
+
+       c += (unsigned int)u_red[31] + 19;
+       u_red[31] = (unsigned char)c;
+       c >>= 8;
+
+       for (i = 30; i >= 0; i--) {
+               c += (unsigned int)u_red[i];
+               u_red[i] = (unsigned char)c;
+               c >>= 8;
+       }
+
+       c = (u_red[0] & 0x80) >> 7;
+       u_red[0] &= 0x7f;
+       constant_time_cond_swap_buff(0 - (unsigned char)c,
+                                    u, u_red, sizeof(u_red));
+}
+
+static void s390_x448_mod_p(unsigned char u[56])
+{
+       unsigned char u_red[56];
+       unsigned int c = 0;
+       int i;
+
+       memcpy(u_red, u, sizeof(u_red));
+
+       c += (unsigned int)u_red[55] + 1;
+       u_red[55] = (unsigned char)c;
+       c >>= 8;
+
+       for (i = 54; i >= 28; i--) {
+               c += (unsigned int)u_red[i];
+               u_red[i] = (unsigned char)c;
+               c >>= 8;
+       }
+
+       c += (unsigned int)u_red[27] + 1;
+       u_red[27] = (unsigned char)c;
+       c >>= 8;
+
+       for (i = 26; i >= 0; i--) {
+               c += (unsigned int)u_red[i];
+               u_red[i] = (unsigned char)c;
+               c >>= 8;
+       }
+
+       constant_time_cond_swap_buff(0 - (unsigned char)c,
+                                    u, u_red, sizeof(u_red));
+}
+
 int scalar_mulx_cpacf(unsigned char *res_u,
                      const unsigned char *scalar,
                      const unsigned char *u,
@@ -598,6 +683,9 @@
                s390_flip_endian_32(param.X25519.u, param.X25519.u);
                s390_flip_endian_32(param.X25519.scalar, param.X25519.scalar);
 
+               /* reduce non-canonical values */
+               s390_x25519_mod_p(param.X25519.u);
+
                fc = s390_pcc_functions[SCALAR_MULTIPLY_X25519].hw_fc;
                rc = s390_pcc(fc, &param) ? EIO : 0;
 
@@ -619,6 +707,9 @@
                s390_flip_endian_64(param.X448.u, param.X448.u);
                s390_flip_endian_64(param.X448.scalar, param.X448.scalar);
 
+               /* reduce non-canonical values */
+               s390_x448_mod_p(param.X448.u + 8);
+
                fc = s390_pcc_functions[SCALAR_MULTIPLY_X448].hw_fc;
                rc = s390_pcc(fc, &param) ? EIO : 0;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/test/ec_keygen1_test.sh 
new/libica-3.7.0/test/ec_keygen1_test.sh
--- old/libica-3.6.0/test/ec_keygen1_test.sh    2019-08-29 21:33:33.000000000 
+0200
+++ new/libica-3.7.0/test/ec_keygen1_test.sh    2020-05-14 15:32:36.000000000 
+0200
@@ -1,2 +1,7 @@
-#!/bin/sh
-ICAPATH=1 ./ec_keygen_test
+#!/bin/bash
+
+if lszcrypt | grep -q -e "CEX.C.*online"; then
+       ICAPATH=1 ./ec_keygen_test
+else
+       exit 77
+fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/test/ec_keygen2_test.sh 
new/libica-3.7.0/test/ec_keygen2_test.sh
--- old/libica-3.6.0/test/ec_keygen2_test.sh    2019-08-29 21:33:33.000000000 
+0200
+++ new/libica-3.7.0/test/ec_keygen2_test.sh    2020-05-14 15:32:36.000000000 
+0200
@@ -1,2 +1,7 @@
-#!/bin/sh
-ICAPATH=2 ./ec_keygen_test
+#!/bin/bash
+
+if lszcrypt | grep -q -e "CEX.C.*online"; then
+       ICAPATH=2 ./ec_keygen_test
+else
+       exit 77
+fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/test/ecdh1_test.sh 
new/libica-3.7.0/test/ecdh1_test.sh
--- old/libica-3.6.0/test/ecdh1_test.sh 2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/test/ecdh1_test.sh 2020-05-14 15:32:36.000000000 +0200
@@ -1,2 +1,7 @@
-#!/bin/sh
-ICAPATH=1 ./ecdh_test
+#!/bin/bash
+
+if lszcrypt | grep -q -e "CEX.C.*online"; then
+       ICAPATH=1 ./ecdh_test
+else
+       exit 77
+fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/test/ecdh2_test.sh 
new/libica-3.7.0/test/ecdh2_test.sh
--- old/libica-3.6.0/test/ecdh2_test.sh 2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/test/ecdh2_test.sh 2020-05-14 15:32:36.000000000 +0200
@@ -1,2 +1,7 @@
-#!/bin/sh
-ICAPATH=2 ./ecdh_test
+#!/bin/bash
+
+if lszcrypt | grep -q -e "CEX.C.*online"; then
+       ICAPATH=2 ./ecdh_test
+else
+       exit 77
+fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/test/ecdsa1_test.sh 
new/libica-3.7.0/test/ecdsa1_test.sh
--- old/libica-3.6.0/test/ecdsa1_test.sh        2019-08-29 21:33:33.000000000 
+0200
+++ new/libica-3.7.0/test/ecdsa1_test.sh        2020-05-14 15:32:36.000000000 
+0200
@@ -1,2 +1,7 @@
-#!/bin/sh
-ICAPATH=1 ./ecdsa_test
+#!/bin/bash
+
+if lszcrypt | grep -q -e "CEX.C.*online"; then
+       ICAPATH=1 ./ecdsa_test
+else
+       exit 77
+fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/test/ecdsa2_test.sh 
new/libica-3.7.0/test/ecdsa2_test.sh
--- old/libica-3.6.0/test/ecdsa2_test.sh        2019-08-29 21:33:33.000000000 
+0200
+++ new/libica-3.7.0/test/ecdsa2_test.sh        2020-05-14 15:32:36.000000000 
+0200
@@ -1,2 +1,7 @@
-#!/bin/sh
-ICAPATH=2 ./ecdsa_test
+#!/bin/bash
+
+if lszcrypt | grep -q -e "CEX.C.*online"; then
+       ICAPATH=2 ./ecdsa_test
+else
+       exit 77
+fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/test/eddsa_test.c 
new/libica-3.7.0/test/eddsa_test.c
--- old/libica-3.6.0/test/eddsa_test.c  2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/test/eddsa_test.c  2020-05-14 15:32:36.000000000 +0200
@@ -14,9 +14,9 @@
 #include "testcase.h"
 #include "eddsa_test.h"
 
-#define THREADS                1024
-#define ITERATIONS     100  /*XXX*/
-#define MSGLEN         (3600-1) /*XXX (16384*100UL)*/
+#define THREADS                256
+#define ITERATIONS     1000
+#define MSGLEN         (16384 * 2ULL)
 
 static void check_functionlist(void);
 
@@ -265,14 +265,15 @@
        if (msg == NULL)
                EXIT_ERR("malloc failed.");
 
-       fd = fopen("/dev/urandom", "r");
-       if (fd == NULL)
-               EXIT_ERR("fopen failed.");
-
-       if (fread(msg, msglen, 1, fd) != 1)
-               EXIT_ERR("fread failed.");
-
-       fclose(fd);
+       if (msglen > 0) {
+               fd = fopen("/dev/urandom", "r");
+               if (fd == NULL)
+                       EXIT_ERR("fopen failed.");
+
+               if (fread(msg, msglen, 1, fd) != 1)
+                       EXIT_ERR("fread failed.");
+               fclose(fd);
+       }
 
        if (ica_ed25519_ctx_new(&ctx))
                EXIT_ERR("ica_ed448_ctx_new failed.");
@@ -347,14 +348,16 @@
        if (msg == NULL)
                EXIT_ERR("malloc failed.");
 
-       fd = fopen("/dev/urandom", "r");
-       if (fd == NULL)
-               EXIT_ERR("fopen failed.");
+       if (msglen > 0) {
+               fd = fopen("/dev/urandom", "r");
+               if (fd == NULL)
+                       EXIT_ERR("fopen failed.");
 
-       if (fread(msg, msglen, 1, fd) != 1)
-               EXIT_ERR("fread failed.");
+               if (fread(msg, msglen, 1, fd) != 1)
+                       EXIT_ERR("fread failed.");
 
-       fclose(fd);
+               fclose(fd);
+       }
 
        if (ica_ed448_ctx_new(&ctx))
                EXIT_ERR("ica_ed448_ctx_new failed.");
@@ -413,7 +416,7 @@
 
 static void ed25519_stress(void)
 {
-       int rc, i, status[THREADS];
+       int rc, i;
        ICA_ED25519_CTX *ctx[THREADS];
 
        for (i = 0; i < THREADS; i++) {
@@ -429,7 +432,7 @@
        }
 
        for (i = 0; i < THREADS; i++) {
-               rc = pthread_join(threads[i], (void **)&status[i]);
+               rc = pthread_join(threads[i], NULL);
                if (rc)
                        EXIT_ERR("pthread_join failed.");
        }
@@ -460,7 +463,7 @@
 
 static void ed448_stress(void)
 {
-       int rc, i, status[THREADS];
+       int rc, i;
        ICA_ED448_CTX *ctx[THREADS];
 
        for (i = 0; i < THREADS; i++) {
@@ -476,7 +479,7 @@
        }
 
        for (i = 0; i < THREADS; i++) {
-               rc = pthread_join(threads[i], (void **)&status[i]);
+               rc = pthread_join(threads[i], NULL);
                if (rc)
                        EXIT_ERR("pthread_join failed.");
        }
@@ -535,7 +538,7 @@
        gettimeofday(&stop, NULL);
        delta = delta_usec(&start, &stop);
        ops = ops_per_sec(ITERATIONS, delta);
-       printf("ica_ed25519_sign(%d bytes)\t%.2Lf ops/sec\n", MSGLEN, ops);
+       printf("ica_ed25519_sign(%llu bytes)\t%.2Lf ops/sec\n", MSGLEN, ops);
 
        gettimeofday(&start, NULL);
        for (i = 0; i < ITERATIONS; i++) {
@@ -545,7 +548,7 @@
        gettimeofday(&stop, NULL);
        delta = delta_usec(&start, &stop);
        ops = ops_per_sec(ITERATIONS, delta);
-       printf("ica_ed25519_verify(%d bytes)\t%.2Lf ops/sec\n", MSGLEN, ops);
+       printf("ica_ed25519_verify(%llu bytes)\t%.2Lf ops/sec\n", MSGLEN, ops);
 
        if (ica_ed25519_ctx_del(&ctx))
                EXIT_ERR("ica_ed25519_ctx_del failed.");
@@ -581,7 +584,7 @@
        gettimeofday(&stop, NULL);
        delta = delta_usec(&start, &stop);
        ops = ops_per_sec(ITERATIONS, delta);
-       printf("ica_ed448_sign(%d bytes)\t%.2Lf ops/sec\n", MSGLEN, ops);
+       printf("ica_ed448_sign(%llu bytes)\t%.2Lf ops/sec\n", MSGLEN, ops);
 
        gettimeofday(&start, NULL);
        for (i = 0; i < ITERATIONS; i++) {
@@ -591,7 +594,7 @@
        gettimeofday(&stop, NULL);
        delta = delta_usec(&start, &stop);
        ops = ops_per_sec(ITERATIONS, delta);
-       printf("ica_ed448_verify(%d bytes)\t%.2Lf ops/sec\n", MSGLEN, ops);
+       printf("ica_ed448_verify(%llu bytes)\t%.2Lf ops/sec\n", MSGLEN, ops);
 
        if (ica_ed448_ctx_del(&ctx))
                EXIT_ERR("ica_ed448_ctx_del failed.");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/test/fips_test.c 
new/libica-3.7.0/test/fips_test.c
--- old/libica-3.6.0/test/fips_test.c   2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/test/fips_test.c   2020-05-14 15:32:36.000000000 +0200
@@ -57,6 +57,10 @@
                printf("Libica FIPS powerup test failed.\n");
                rv = EXIT_FAILURE;
        }
+       if (fips & ICA_FIPS_INTEGRITY) {
+               printf("Libica FIPS integrity check failed.\n");
+               rv = EXIT_FAILURE;
+       }
 #endif /* ICA_FIPS */
 
        printf("OpenSSL version is '%s'.\n", OPENSSL_VERSION_TEXT);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/test/icastats_test.c 
new/libica-3.7.0/test/icastats_test.c
--- old/libica-3.6.0/test/icastats_test.c       2019-08-29 21:33:33.000000000 
+0200
+++ new/libica-3.7.0/test/icastats_test.c       2020-05-14 15:32:36.000000000 
+0200
@@ -239,7 +239,7 @@
        char cmd[256], line[256], *p;
        FILE *f;
        int i, hw, rc=-1, counters=0;
-       int hwcounter1=0, hwcounter2=0, swcounter1=0, swcounter2=0;
+       uint64_t hwcounter1=0, hwcounter2=0, swcounter1=0, swcounter2=0;
 
        hw = check_hw(algo_id);
        if (hw < 0) return; /* unknown algo_id */
@@ -267,13 +267,13 @@
        if (!p) goto out; /* no | in the output. Wrong algo string ? */
        p++;
        while (isspace(*p)) p++;
-       hwcounter1 = atoi(p); /* parse 1st hw counter value */
+       hwcounter1 = atol(p); /* parse 1st hw counter value */
        counters++;
        while (*p && !isspace(*p)) p++; /* parse over counter value */
        while (isspace(*p)) p++;
        /* now either a | or another counter value follows */
        if (isdigit(*p)) {
-               hwcounter2 = atoi(p); /* parse 2nd hw counter value */
+               hwcounter2 = atol(p); /* parse 2nd hw counter value */
                counters++;
                while (*p && !isspace(*p)) p++; /* parse over counter value */
                while (isspace(*p)) p++;
@@ -285,13 +285,13 @@
        }
        p++;
        while (isspace(*p)) p++;
-       swcounter1 = atoi(p); /* parse 1st sw counter value */
+       swcounter1 = atol(p); /* parse 1st sw counter value */
        counters++;
        while (*p && !isspace(*p)) p++; /* parse over counter value */
        while (isspace(*p)) p++;
        /* maybe another counter value follows */
        if (isdigit(*p)) {
-               swcounter2 = atoi(p); /* parse 2nd sw counter value */
+               swcounter2 = atol(p); /* parse 2nd sw counter value */
                counters++;
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libica-3.6.0/test/x_test.c 
new/libica-3.7.0/test/x_test.c
--- old/libica-3.6.0/test/x_test.c      2019-08-29 21:33:33.000000000 +0200
+++ new/libica-3.7.0/test/x_test.c      2020-05-14 15:32:36.000000000 +0200
@@ -15,10 +15,18 @@
 #include "ica_api.h"
 #include "testcase.h"
 
-#define ITERATIONS     100  /*XXX*/
+#define ITERATIONS     1000
+
+struct kat {
+       const unsigned char *priv;
+       const unsigned char *peer_pub;
+       const unsigned char *shared_secret;
+};
 
 static void check_functionlist(void);
 
+static void x25519_kat(void);
+static void x448_kat(void);
 static void x25519_pc(void);
 static void x448_pc(void);
 
@@ -30,6 +38,12 @@
 
        check_functionlist();
 
+       VV_(printf("\n=== X25519 KAT ===\n"));
+       x25519_kat();
+
+       VV_(printf("\n=== X448 KAT ===\n"));
+       x448_kat();
+
        VV_(printf("\n=== X25519 PC ===\n"));
        for (i = 0; i < ITERATIONS; i++)
                x25519_pc();
@@ -135,6 +149,12 @@
 
        if (memcmp(key1, key2, keylen) != 0)
                EXIT_ERR("x25519 shared secrets do not match.");
+
+       (void)ica_x25519_ctx_del(&ctx1);
+       (void)ica_x25519_ctx_del(&ctx2);
+       EVP_PKEY_free(pkey1);
+       EVP_PKEY_free(pkey2);
+       EVP_PKEY_CTX_free(pctx);
 #endif
 }
 
@@ -196,5 +216,196 @@
 
        if (memcmp(key1, key2, keylen) != 0)
                EXIT_ERR("x448 shared secrets do not match.");
+
+       (void)ica_x448_ctx_del(&ctx1);
+       (void)ica_x448_ctx_del(&ctx2);
+       EVP_PKEY_free(pkey1);
+       EVP_PKEY_free(pkey2);
+       EVP_PKEY_CTX_free(pctx);
 #endif
 }
+
+static void x25519_kat(void)
+{
+       struct kat vec[] = {
+       {
+       /* some wycheproof test vectors */
+       .priv = (const unsigned char[]) {
+       0x28, 0x87, 0x96, 0xbc, 0x5a, 0xff, 0x4b, 0x81, 0xa3, 0x75, 0x01, 0x75,
+       0x7b, 0xc0, 0x75, 0x3a, 0x3c, 0x21, 0x96, 0x47, 0x90, 0xd3, 0x86, 0x99,
+       0x30, 0x8d, 0xeb, 0xc1, 0x7a, 0x6e, 0xaf, 0x8d
+       },
+       .peer_pub = (const unsigned char[]) {
+       0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
+       },
+       .shared_secret = (const unsigned char[]) {
+       0xb4, 0xe0, 0xdd, 0x76, 0xda, 0x7b, 0x07, 0x17, 0x28, 0xb6, 0x1f, 0x85,
+       0x67, 0x71, 0xaa, 0x35, 0x6e, 0x57, 0xed, 0xa7, 0x8a, 0x5b, 0x16, 0x55,
+       0xcc, 0x38, 0x20, 0xfb, 0x5f, 0x85, 0x4c, 0x5c
+       },
+       },
+       {
+       .priv = (const unsigned char[]) {
+       0x60, 0x88, 0x7b, 0x3d, 0xc7, 0x24, 0x43, 0x02, 0x6e, 0xbe, 0xdb, 0xbb,
+       0xb7, 0x06, 0x65, 0xf4, 0x2b, 0x87, 0xad, 0xd1, 0x44, 0x0e, 0x77, 0x68,
+       0xfb, 0xd7, 0xe8, 0xe2, 0xce, 0x5f, 0x63, 0x9d
+       },
+       .peer_pub = (const unsigned char[]) {
+       0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+       },
+       .shared_secret = (const unsigned char[]) {
+       0x38, 0xd6, 0x30, 0x4c, 0x4a, 0x7e, 0x6d, 0x9f, 0x79, 0x59, 0x33, 0x4f,
+       0xb5, 0x24, 0x5b, 0xd2, 0xc7, 0x54, 0x52, 0x5d, 0x4c, 0x91, 0xdb, 0x95,
+       0x02, 0x06, 0x92, 0x62, 0x34, 0xc1, 0xf6, 0x33
+       },
+       },
+       {
+       .priv = (const unsigned char[]) {
+       0xa0, 0xa4, 0xf1, 0x30, 0xb9, 0x8a, 0x5b, 0xe4, 0xb1, 0xce, 0xdb, 0x7c,
+       0xb8, 0x55, 0x84, 0xa3, 0x52, 0x0e, 0x14, 0x2d, 0x47, 0x4d, 0xc9, 0xcc,
+       0xb9, 0x09, 0xa0, 0x73, 0xa9, 0x76, 0xbf, 0x63
+       },
+       .peer_pub = (const unsigned char[]) {
+       0x0a, 0xb4, 0xe7, 0x63, 0x80, 0xd8, 0x4d, 0xde, 0x4f, 0x68, 0x33, 0xc5,
+       0x8f, 0x2a, 0x9f, 0xb8, 0xf8, 0x3b, 0xb0, 0x16, 0x9b, 0x17, 0x2b, 0xe4,
+       0xb6, 0xe0, 0x59, 0x28, 0x87, 0x74, 0x1a, 0x36
+       },
+       .shared_secret = (const unsigned char[]) {
+       0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+       },
+       },
+       {
+       .priv = (const unsigned char[]) {
+       0xa0, 0xa4, 0xf1, 0x30, 0xb9, 0x8a, 0x5b, 0xe4, 0xb1, 0xce, 0xdb, 0x7c,
+       0xb8, 0x55, 0x84, 0xa3, 0x52, 0x0e, 0x14, 0x2d, 0x47, 0x4d, 0xc9, 0xcc,
+       0xb9, 0x09, 0xa0, 0x73, 0xa9, 0x76, 0xbf, 0x63
+       },
+       .peer_pub = (const unsigned char[]) {
+       0x89, 0xe1, 0x0d, 0x57, 0x01, 0xb4, 0x33, 0x7d, 0x2d, 0x03, 0x21, 0x81,
+       0x53, 0x8b, 0x10, 0x64, 0xbd, 0x40, 0x84, 0x40, 0x1c, 0xec, 0xa1, 0xfd,
+       0x12, 0x66, 0x3a, 0x19, 0x59, 0x38, 0x80, 0x00
+       },
+       .shared_secret = (const unsigned char[]) {
+       0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+       },
+       },
+       {
+       .priv = (const unsigned char[]) {
+       0xa0, 0xa4, 0xf1, 0x30, 0xb9, 0x8a, 0x5b, 0xe4, 0xb1, 0xce, 0xdb, 0x7c,
+       0xb8, 0x55, 0x84, 0xa3, 0x52, 0x0e, 0x14, 0x2d, 0x47, 0x4d, 0xc9, 0xcc,
+       0xb9, 0x09, 0xa0, 0x73, 0xa9, 0x76, 0xbf, 0x63
+       },
+       .peer_pub = (const unsigned char[]) {
+       0x2b, 0x55, 0xd3, 0xaa, 0x4a, 0x8f, 0x80, 0xc8, 0xc0, 0xb2, 0xae, 0x5f,
+       0x93, 0x3e, 0x85, 0xaf, 0x49, 0xbe, 0xac, 0x36, 0xc2, 0xfa, 0x73, 0x94,
+       0xba, 0xb7, 0x6c, 0x89, 0x33, 0xf8, 0xf8, 0x1d
+       },
+       .shared_secret = (const unsigned char[]) {
+       0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+       },
+       },
+       };
+       ICA_X25519_CTX *ctx = NULL;
+       unsigned char shared_secret[32];
+       size_t i = 0;
+
+       if (ica_x25519_ctx_new(&ctx))
+               EXIT_ERR("ica_x448_ctx_new failed.");
+
+       for (i = 0; i < sizeof(vec) / sizeof(vec[0]); i++) {
+               if (ica_x25519_key_set(ctx, vec[i].priv, NULL) != 0)
+                       EXIT_ERR("ica_x25519_key_set failed.");
+
+               if (ica_x25519_derive(ctx,
+                                     shared_secret, vec[i].peer_pub) != 0)
+                       EXIT_ERR("ica_x25519_derive failed.");
+
+               if (memcmp(shared_secret, vec[i].shared_secret, 32) != 0)
+                       EXIT_ERR("x25519 shared secrets do not match.");
+       }
+
+       (void)ica_x25519_ctx_del(&ctx);
+}
+
+static void x448_kat(void)
+{
+       struct kat vec[] = {
+       {
+       /* openssl test vectors */
+       .priv = (const unsigned char[]) {
+       0x9a, 0x8f, 0x49, 0x25, 0xd1, 0x51, 0x9f, 0x57, 0x75, 0xcf, 0x46, 0xb0,
+       0x4b, 0x58, 0x00, 0xd4, 0xee, 0x9e, 0xe8, 0xba, 0xe8, 0xbc, 0x55, 0x65,
+       0xd4, 0x98, 0xc2, 0x8d, 0xd9, 0xc9, 0xba, 0xf5, 0x74, 0xa9, 0x41, 0x97,
+       0x44, 0x89, 0x73, 0x91, 0x00, 0x63, 0x82, 0xa6, 0xf1, 0x27, 0xab, 0x1d,
+       0x9a, 0xc2, 0xd8, 0xc0, 0xa5, 0x98, 0x72, 0x6b
+       },
+       .peer_pub = (const unsigned char[]) {
+       0x3e, 0xb7, 0xa8, 0x29, 0xb0, 0xcd, 0x20, 0xf5, 0xbc, 0xfc, 0x0b, 0x59,
+       0x9b, 0x6f, 0xec, 0xcf, 0x6d, 0xa4, 0x62, 0x71, 0x07, 0xbd, 0xb0, 0xd4,
+       0xf3, 0x45, 0xb4, 0x30, 0x27, 0xd8, 0xb9, 0x72, 0xfc, 0x3e, 0x34, 0xfb,
+       0x42, 0x32, 0xa1, 0x3c, 0xa7, 0x06, 0xdc, 0xb5, 0x7a, 0xec, 0x3d, 0xae,
+       0x07, 0xbd, 0xc1, 0xc6, 0x7b, 0xf3, 0x36, 0x09
+       },
+       .shared_secret = (const unsigned char[]) {
+       0x07, 0xff, 0xf4, 0x18, 0x1a, 0xc6, 0xcc, 0x95, 0xec, 0x1c, 0x16, 0xa9,
+       0x4a, 0x0f, 0x74, 0xd1, 0x2d, 0xa2, 0x32, 0xce, 0x40, 0xa7, 0x75, 0x52,
+       0x28, 0x1d, 0x28, 0x2b, 0xb6, 0x0c, 0x0b, 0x56, 0xfd, 0x24, 0x64, 0xc3,
+       0x35, 0x54, 0x39, 0x36, 0x52, 0x1c, 0x24, 0x40, 0x30, 0x85, 0xd5, 0x9a,
+       0x44, 0x9a, 0x50, 0x37, 0x51, 0x4a, 0x87, 0x9d
+       }
+       },
+       {
+       .priv = (const unsigned char[]) {
+       0x9a, 0x8f, 0x49, 0x25, 0xd1, 0x51, 0x9f, 0x57, 0x75, 0xcf, 0x46, 0xb0,
+       0x4b, 0x58, 0x00, 0xd4, 0xee, 0x9e, 0xe8, 0xba, 0xe8, 0xbc, 0x55, 0x65,
+       0xd4, 0x98, 0xc2, 0x8d, 0xd9, 0xc9, 0xba, 0xf5, 0x74, 0xa9, 0x41, 0x97,
+       0x44, 0x89, 0x73, 0x91, 0x00, 0x63, 0x82, 0xa6, 0xf1, 0x27, 0xab, 0x1d,
+       0x9a, 0xc2, 0xd8, 0xc0, 0xa5, 0x98, 0x72, 0x6b
+       },
+       .peer_pub = (const unsigned char[]) {
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+       },
+       .shared_secret = (const unsigned char[]) {
+       0x66, 0xe2, 0xe6, 0x82, 0xb1, 0xf8, 0xe6, 0x8c, 0x80, 0x9f, 0x1b, 0xb3,
+       0xe4, 0x06, 0xbd, 0x82, 0x69, 0x21, 0xd9, 0xc1, 0xa5, 0xbf, 0xbf, 0xcb,
+       0xab, 0x7a, 0xe7, 0x2f, 0xee, 0xce, 0xe6, 0x36, 0x60, 0xea, 0xbd, 0x54,
+       0x93, 0x4f, 0x33, 0x82, 0x06, 0x1d, 0x17, 0x60, 0x7f, 0x58, 0x1a, 0x90,
+       0xbd, 0xac, 0x91, 0x7a, 0x06, 0x49, 0x59, 0xfb
+       }
+       }
+       };
+       ICA_X448_CTX *ctx = NULL;
+       unsigned char shared_secret[56];
+       size_t i = 0;
+
+       if (ica_x448_ctx_new(&ctx))
+               EXIT_ERR("ica_x448_ctx_new failed.");
+
+       for (i = 0; i < sizeof(vec) / sizeof(vec[0]); i++) {
+               if (ica_x448_key_set(ctx, vec[i].priv, NULL) != 0)
+                       EXIT_ERR("ica_x448_key_set failed.");
+
+               if (ica_x448_derive(ctx,
+                                     shared_secret, vec[i].peer_pub) != 0)
+                       EXIT_ERR("ica_x448_derive failed.");
+
+               if (memcmp(shared_secret, vec[i].shared_secret, 56) != 0)
+                       EXIT_ERR("x448 shared secrets do not match.");
+       }
+
+       (void)ica_x448_ctx_del(&ctx);
+}


Reply via email to