Problem description:
Libica uses different instructions to obtain the system clock when running in
31 and 64 bit. This information is used to generate entropy when initializing
the RPNG. The instructions take different input one of which is a buffer that
differs in size for the 31/64 instructions. When running in 31 bit this can
lead to a problem were memory is corrupted (writing beyond the buffer). This
problem does not occur when using libica in 64 bit mode.

Problem resolution:
Adjust the buffer size based on whether running in 31 or 64 bit mode.
---
 ChangeLog       |    4 ++++
 libica.spec     |    4 +++-
 src/s390_prng.c |   33 ++++++++++++++++++++++-----------
 3 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 85c0888..5ac839b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+v2.0.4
+Fix for STCK buffer length
+  Correctly adjust the STCK buffer length in the PRNG based on whether
+  we are running in 31 or 64 bit.
 v2.0.3
 minor wording fix in icastats tool:
   changed output wording from SHAxxx to SHA-xxx
diff --git a/libica.spec b/libica.spec
index 6aed0f0..679fadd 100644
--- a/libica.spec
+++ b/libica.spec
@@ -1,6 +1,6 @@
 Name:          libica 
 Version:       2.0
-Release:       3%{?dist}
+Release:       4%{?dist}
 Summary:       Interface library to the ICA device driver 
 
 Group:         Libraries/Crypto 
@@ -58,6 +58,8 @@ rm -rf $RPM_BUILD_ROOT
 %{_includedir}/ica_api.h
 
 %changelog
+* Thu Sep 30 2010 Rainer Wolafka <[email protected]>
+- Bugfix version 2.0.4
 * Thu Apr 15 2010 Ruben Straus <[email protected]>
 - Bugfixes version 2.0.3
 * Wed Aug 12 2009 Felix Beck <[email protected]>
diff --git a/src/s390_prng.c b/src/s390_prng.c
index d146ec7..96e156f 100644
--- a/src/s390_prng.c
+++ b/src/s390_prng.c
@@ -27,6 +27,17 @@
 
 #include <stdio.h>
 
+/*
+ * On 31 bit systems we have to use the instruction STCKE while on 64 bit
+ * systems we can use STCKF. STCKE uses a 16 byte buffer while STCKF uses
+ * an 8 byte buffer.
+ */
+#ifdef _LINUX_S390X_
+#define STCK_BUFFER  8
+#else
+#define STCK_BUFFER 16
+#endif
+
 sem_t semaphore;
 
 /*
@@ -93,7 +104,7 @@ int s390_prng_init(void)
  */
 static int s390_add_entropy(void)
 {
-       unsigned char entropy[4 * 8];
+       unsigned char entropy[4 * STCK_BUFFER];
        unsigned int K;
        int rc = 0;
        struct sigaction oldact;
@@ -103,16 +114,16 @@ static int s390_add_entropy(void)
                return errno;
 
        for (K = 0; K < 16; K++) {
-               if ((s390_stck(entropy + 0 * 8)) ||
-                   (s390_stck(entropy + 1 * 8)) ||
-                   (s390_stck(entropy + 2 * 8)) ||
-                   (s390_stck(entropy + 3 * 8)) ||
+               if ((s390_stck(entropy + 0 * STCK_BUFFER)) ||
+                   (s390_stck(entropy + 1 * STCK_BUFFER)) ||
+                   (s390_stck(entropy + 2 * STCK_BUFFER)) ||
+                   (s390_stck(entropy + 3 * STCK_BUFFER)) ||
                    (s390_kmc(0x43, zPRNG_PB, entropy, entropy,
                     sizeof(entropy)) < 0)) {
                        rc = -1;
                        goto out;
                }
-               memcpy(zPRNG_PB, entropy, sizeof(entropy));
+               memcpy(zPRNG_PB, entropy, sizeof(zPRNG_PB));
        }
        int handle;
        unsigned char seed[32];
@@ -148,7 +159,7 @@ int s390_prng(unsigned char *output_data, unsigned int 
output_length)
 {
        int rc = 1;
        int hardware = 1;
-       
+
        if (prng_switch)
                rc = s390_prng_hw(output_data, output_length);
        if (rc) {
@@ -176,7 +187,7 @@ static int s390_prng_sw(unsigned char *output_data, 
unsigned int output_length)
 static int s390_prng_hw(unsigned char *random_bytes, unsigned int num_bytes)
 {
        unsigned int i, remainder;
-       unsigned char last_dw[8];
+       unsigned char last_dw[STCK_BUFFER];
        int rc = 0;
 
        struct sigaction oldact;
@@ -199,8 +210,8 @@ static int s390_prng_hw(unsigned char *random_bytes, 
unsigned int num_bytes)
                remainder = num_bytes % PRNG_BLK_SZ;
                num_bytes -= remainder;
 
-               for (i = 0; !rc && i < (num_bytes / 8); i++) {
-                       rc = s390_stck(random_bytes + i * 8);
+               for (i = 0; !rc && i < (num_bytes / STCK_BUFFER); i++) {
+                       rc = s390_stck(random_bytes + i * STCK_BUFFER);
                }
                if (!rc) {
                        rc = s390_kmc(S390_CRYPTO_PRNG, zPRNG_PB, random_bytes,
@@ -216,7 +227,7 @@ static int s390_prng_hw(unsigned char *random_bytes, 
unsigned int num_bytes)
                        rc = s390_stck(last_dw);
                        if (!rc) {
                                rc = s390_kmc(S390_CRYPTO_PRNG, zPRNG_PB, 
last_dw,
-                                             last_dw, 8);
+                                             last_dw, STCK_BUFFER);
                                if (rc > 0) {
                                        s390_byte_count += rc;
                                        rc = 0;
-- 
1.7.3


------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Opencryptoki-tech mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opencryptoki-tech

Reply via email to