libica/libica-2.0.3-remove-sigill.patch
2011-01-12 09:07:50 +01:00

276 lines
7.9 KiB
Diff

[Bug 67452]: Do not use sigill to wrap all HW instructions.
From: Felix Beck <felix.beck@de.ibm.com>
As described in Bugzilla 67452 there is a performance problem using
libica. This results from extensive usage of the signall handler to
catch illegal signals from hw functions. This wrapping mechanism is
removed. Instead we trust in the switches which are set during
library initialization. This is enough to protect us from using
illegal instructions.
The performance impact of the former signal handler usage was
dramatic.
Signed-off-by: Felix Beck <felix.beck@de.ibm.com>
diff -up libica-2/src/s390_aes.c.remove-sigill libica-2/src/s390_aes.c
--- libica-2/src/s390_aes.c.remove-sigill 2009-02-04 16:19:22.000000000 +0100
+++ libica-2/src/s390_aes.c 2011-01-04 11:53:08.000000000 +0100
@@ -24,23 +24,13 @@ static int s390_aes_ecb_hw(unsigned int
unsigned char *input_data, unsigned char *keys,
unsigned char *output_data)
{
- struct sigaction oldact;
- sigset_t oldset;
-
int rc = 0;
- if ((rc = begin_sigill_section(&oldact, &oldset)) == 0) {
-
- rc = s390_km(function_code, keys, output_data, input_data,
- input_length);
-
- end_sigill_section(&oldact, &oldset);
-
- if (rc >= 0)
- return 0;
- else
- return EIO;
- }
- return rc;
+ rc = s390_km(function_code, keys, output_data, input_data,
+ input_length);
+ if (rc >= 0)
+ return 0;
+ else
+ return EIO;
}
static int s390_aes_ecb_sw(unsigned int function_code, unsigned int input_length,
@@ -73,8 +63,6 @@ static int s390_aes_cbc_hw(unsigned int
unsigned char *input_data, ica_aes_vector_t *iv,
unsigned char *keys, unsigned char *output_data)
{
- struct sigaction oldact;
- sigset_t oldset;
struct {
ica_aes_vector_t iv;
ica_aes_key_len_256_t keys;
@@ -87,12 +75,8 @@ static int s390_aes_cbc_hw(unsigned int
memcpy(&key_buffer.keys, keys, key_size);
int rc = 0;
- if ((rc = begin_sigill_section(&oldact, &oldset)) != 0)
- return rc;
-
rc = s390_kmc(function_code, &key_buffer,
output_data, input_data, input_length);
- end_sigill_section(&oldact, &oldset);
if (rc >= 0) {
memcpy(iv, &key_buffer.iv, sizeof(ica_aes_vector_t));
diff -up libica-2/src/s390_des.c.remove-sigill libica-2/src/s390_des.c
--- libica-2/src/s390_des.c.remove-sigill 2009-02-05 16:53:00.000000000 +0100
+++ libica-2/src/s390_des.c 2011-01-04 11:53:08.000000000 +0100
@@ -25,20 +25,13 @@ int s390_des_ecb_hw(unsigned int functio
unsigned char *output_data)
{
int rc = 0;
- struct sigaction oldact;
- sigset_t oldset;
- if ((rc = begin_sigill_section(&oldact, &oldset)) == 0) {
- rc = s390_km(function_code, keys, output_data, input_data,
- input_length);
-
- end_sigill_section(&oldact, &oldset);
-
- if (rc >= 0)
- return 0;
- else
- return EIO;
- }
- return rc;
+ rc = s390_km(function_code, keys, output_data, input_data,
+ input_length);
+
+ if (rc >= 0)
+ return 0;
+ else
+ return EIO;
}
@@ -109,8 +102,6 @@ static int s390_des_cbc_hw(unsigned int
unsigned char *input_data, ica_des_vector_t *iv,
unsigned char *keys, unsigned char *output_data)
{
- struct sigaction oldact;
- sigset_t oldset;
struct {
ica_des_vector_t iv;
ica_des_key_triple_t keys;
@@ -122,17 +113,13 @@ static int s390_des_cbc_hw(unsigned int
memcpy(&key_buffer.iv, iv, sizeof(ica_des_vector_t));
memcpy(&key_buffer.keys, keys, key_size);
- if ((rc = begin_sigill_section(&oldact, &oldset)) == 0) {
- rc = s390_kmc(function_code, &key_buffer, output_data, input_data,
- input_length);
- end_sigill_section(&oldact, &oldset);
- if (rc >= 0) {
- memcpy(iv, &key_buffer.iv, sizeof(ica_des_vector_t));
- return 0;
- } else
- rc = EIO;
- }
- return rc;
+ rc = s390_kmc(function_code, &key_buffer, output_data, input_data,
+ input_length);
+ if (rc >= 0) {
+ memcpy(iv, &key_buffer.iv, sizeof(ica_des_vector_t));
+ return 0;
+ } else
+ rc = EIO;
}
diff -up libica-2/src/s390_prng.c.remove-sigill libica-2/src/s390_prng.c
--- libica-2/src/s390_prng.c.remove-sigill 2011-01-04 11:53:08.000000000 +0100
+++ libica-2/src/s390_prng.c 2011-01-04 11:53:08.000000000 +0100
@@ -67,27 +67,22 @@ int s390_prng_init(void)
{
sem_init(&semaphore, 0, 1);
- struct sigaction oldact;
- sigset_t oldset;
int rc = -1;
- if (begin_sigill_section(&oldact, &oldset) == 0) {
- int handle;
- unsigned char seed[16];
- handle = open("/dev/hwrng", O_RDONLY);
- if (!handle)
- handle = open("/dev/urandom", O_RDONLY);
- if (handle) {
- rc = read(handle, seed, sizeof(seed));
- if (rc != -1)
- rc = s390_prng_seed(seed, sizeof(seed) /
- sizeof(long long));
- close(handle);
- } else
- rc = ENODEV;
+ int handle;
+ unsigned char seed[16];
+ handle = open("/dev/hwrng", O_RDONLY);
+ if (!handle)
+ handle = open("/dev/urandom", O_RDONLY);
+ if (handle) {
+ rc = read(handle, seed, sizeof(seed));
+ if (rc != -1)
+ rc = s390_prng_seed(seed, sizeof(seed) /
+ sizeof(long long));
+ close(handle);
+ } else
+ rc = ENODEV;
// If the original seeding failed, we should try to stir in some
// entropy anyway (since we already put out a message).
- }
- end_sigill_section(&oldact, &oldset);
s390_byte_count = 0;
if (rc < 0)
@@ -107,11 +102,9 @@ static int s390_add_entropy(void)
unsigned char entropy[4 * STCK_BUFFER];
unsigned int K;
int rc = 0;
- struct sigaction oldact;
- sigset_t oldset;
- if (begin_sigill_section(&oldact, &oldset) != 0)
- return errno;
+ if (!prng_switch)
+ return ENOTSUP;
for (K = 0; K < 16; K++) {
if ((s390_stck(entropy + 0 * STCK_BUFFER)) ||
@@ -145,7 +138,6 @@ out:
rc = 0;
else
rc = EIO;
- end_sigill_section(&oldact, &oldset);
return rc;
}
@@ -190,12 +182,6 @@ static int s390_prng_hw(unsigned char *r
unsigned char last_dw[STCK_BUFFER];
int rc = 0;
- struct sigaction oldact;
- sigset_t oldset;
-
- if ((rc = begin_sigill_section(&oldact, &oldset)) != 0)
- return rc;
-
sem_wait(&semaphore);
/* Add some additional entropy when the byte count is reached.*/
@@ -239,7 +225,6 @@ static int s390_prng_hw(unsigned char *r
return EIO;
}
- end_sigill_section(&oldact, &oldset);
sem_post(&semaphore);
return rc;
@@ -252,10 +237,8 @@ static int s390_prng_hw(unsigned char *r
*/
static int s390_prng_seed(void *srv, unsigned int count)
{
- struct sigaction oldact;
- sigset_t oldset;
- if (begin_sigill_section(&oldact, &oldset) != 0)
- return errno;
+ if (!prng_switch)
+ return ENOTSUP;
unsigned int i;
int rc;
@@ -269,6 +252,5 @@ static int s390_prng_seed(void *srv, uns
// Stir one last time.
rc = s390_add_entropy();
- end_sigill_section(&oldact, &oldset);
return rc;
}
diff -up libica-2/src/s390_sha.c.remove-sigill libica-2/src/s390_sha.c
--- libica-2/src/s390_sha.c.remove-sigill 2009-02-04 16:19:22.000000000 +0100
+++ libica-2/src/s390_sha.c 2011-01-04 11:53:08.000000000 +0100
@@ -79,9 +79,6 @@ static int s390_sha_hw(unsigned char *iv
* this can be at most 128 byte for the hash plus 16 byte for the
* stream length. */
unsigned char shabuff[128 + 16];
- struct sigaction oldact;
- sigset_t oldset;
-
unsigned char *default_iv = sha_constants[sha_function].default_iv;
unsigned int hash_length = sha_constants[sha_function].hash_length;
unsigned int vector_length = sha_constants[sha_function].vector_length;
@@ -111,10 +108,6 @@ static int s390_sha_hw(unsigned char *iv
message_part == SHA_MSG_PART_MIDDLE) && (remnant != 0))
return EINVAL;
- rc = begin_sigill_section(&oldact, &oldset);
- if (rc)
- return rc;
-
unsigned int hw_function_code;
hw_function_code = sha_constants[sha_function].hw_function_code;
if (complete_blocks_length) {
@@ -154,8 +147,6 @@ static int s390_sha_hw(unsigned char *iv
rc = 0;
}
- end_sigill_section(&oldact, &oldset);
-
if (rc == 0) {
memcpy((void *)output_data, shabuff, hash_length);
if (message_part != SHA_MSG_PART_FINAL &&