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