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, ¶m) ? 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, ¶m) ? 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); +}