File fix-msa-level-detection.patch of Package libica2

Subject: [PATCH] [BZ 148767] libica: libica crash with illegal instruction on z196/z114
From: Harald Freudenberger <freude@linux.vnet.ibm.com>

Description:  libica: libica crash with illegal instruction on z196/z114
Symptom:      'illegal instruction' on libica initialization
Problem:      Upon initialization libica checks all the MSA levels
              of the system to find out the available functions.
              This check function reuses a buffer variable without
              proper reinitialization thus leading to detect an
              MSA 5 function PPNO which is in fact not available
              on z196/z114 systems. Upon initialization the libica
              internal pseudo random generator is initialized which
              is then trying to use this PPNO function and so
              the 'illegal instruction' occurs.
Solution:     Fix libica initialization function.
Reproduction: On z196/z114 systems with every libica version >= 2.6.
Upstream-ID:  eeb40e5aea7dd36580629e6b17cd7f03fb62549c
Problem-ID:   148767

Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
Index: libica-service/src/s390_crypto.c
===================================================================
--- libica-service.orig/src/s390_crypto.c	2016-11-18 12:04:39.809574833 +0100
+++ libica-service/src/s390_crypto.c	2016-11-18 12:04:39.805574781 +0100
@@ -144,6 +144,8 @@ void set_switches(int msa)
 	 * kimd query and do not need to over the whole array. Therfore there
 	 * is also no distict setting of the switch needed in form
 	 * msa4_switch = 1. */
+
+	/* kmc query */
 	memset(mask, 0, sizeof(mask));
 	if (msa) {
 		if (begin_sigill_section(&oldact, &oldset) == 0) {
@@ -160,13 +162,14 @@ void set_switches(int msa)
 		*s390_kmc_functions[n].enabled = on;
 	}
 
+	/* kimd query */
+	memset(mask, 0, sizeof(mask));
 	if (msa) {
 		if (begin_sigill_section(&oldact, &oldset) == 0) {
 			s390_kimd(S390_CRYPTO_QUERY, mask, (void *) 0, 0);
 			end_sigill_section(&oldact, &oldset);
 		}
 	}
-
 	for (n = 0; n < (sizeof(s390_kimd_functions) /
 			 sizeof(s390_supported_function_t)); n++) {
 		if (S390_CRYPTO_TEST_MASK(mask, s390_kimd_functions[n].hw_fc))
@@ -176,6 +179,8 @@ void set_switches(int msa)
 		*s390_kimd_functions[n].enabled = on;
 	}
 
+	/* ppno query */
+	memset(mask, 0, sizeof(mask));
 	if (5 <= msa) {
 		msa5_switch = 1;
 		if (begin_sigill_section(&oldact, &oldset) == 0) {
@@ -183,7 +188,6 @@ void set_switches(int msa)
 			end_sigill_section(&oldact, &oldset);
 		}
 	}
-
 	for (n = 0; n < (sizeof(s390_ppno_functions) /
 			 sizeof(s390_supported_function_t)); n++) {
 		if (S390_CRYPTO_TEST_MASK(mask, s390_ppno_functions[n].hw_fc))
@@ -254,7 +258,7 @@ libica_func_list_element_int icaList[] =
  {RSA_KEY_GEN_ME,  	ADAPTER, 0, ICA_FLAG_SW, 		0},	// SW (openssl)
  {RSA_KEY_GEN_CRT, 	ADAPTER, 0, ICA_FLAG_SW, 		0},	// SW (openssl)
 
- {SHA512_DRNG, PPNO, SHA512_DRNG_GEN, ICA_FLAG_SHW | ICA_FLAG_SW, 0},
+ {SHA512_DRNG, PPNO, SHA512_DRNG_GEN, ICA_FLAG_SW, 0},
 
 /* available for the MSA4 instruction */
 /* available for the RSA instruction */
openSUSE Build Service is sponsored by