Yesterday I reported an issue under "Jsch cipher problems when
JsafeJCEFIPS provider is enabled".
>From looking at the archives, it does not show up very well so I may
have goofed on the formatting.

In summary though, I noticed that whenever I'm using Jsch in an
environment where RSA's
JsafeJCEFIPS Crypt4j library is setup as the primary provider, my SSH
connections would fail whenever
using the aes*-ctr ciphers.

I did some more research today and it looks like it's due to the use
of the same buffer for both the
input and output arguments to the s2ccipher.update() calls in Session.java.

I made some local changes which seemed to fix the issue in my
environment.  Attached is the
diff I used to resolve my problem.  Note, I know it's probably not a
final ultimate solution it's
more of a proof of concept to show the problem and one way that
"seems" to fix the problem.

Without this patch, when stepping through the code, what seems to
happen at these update calls
is that what's left in the output buffer in the end is 0s.  The number
of 0s are also the exact
length of the data that should be there.  Once we break it up into two
separate buffers, everything
is fine though.

I looked at the javadoc for the update method in javax.crypto.Cipher
and it does state that:

"Note: this method should be copy-safe, which means the input and
output buffers can reference the same
block of memory and no unprocessed input data is overwritten when the
result is copied into the output buffer."

This only seems to put a requirement on the unprocessed data though,
not the processed data.
In my case, the only parts of the input buffer that are getting
replaced by 0s are the parts we seem
to be processing.  The rest of the buffer is not getting touched.

Any thoughts on whether or not this is actually a bug in Jsch?

Thanks.

Sean
--- Session.java	2012-02-01 02:23:21.000000000 -0500
+++ /tmp/Session.java	2012-02-16 16:46:24.644285657 -0500
@@ -835,7 +835,9 @@
     }
     if(c2scipher!=null){
       byte[] buf=packet.buffer.buffer;
-      c2scipher.update(buf, 0, packet.buffer.index, buf, 0);
+      byte[] cipherText = new byte[buf.length];
+      System.arraycopy(buf, 0, cipherText, 0, buf.length);
+      c2scipher.update(cipherText, 0, packet.buffer.index, buf, 0);
     }
     if(c2smac!=null){
       packet.buffer.skip(c2smac.getBlockSize());
@@ -854,7 +856,9 @@
       io.getByte(buf.buffer, buf.index, s2ccipher_size); 
       buf.index+=s2ccipher_size;
       if(s2ccipher!=null){
-        s2ccipher.update(buf.buffer, 0, s2ccipher_size, buf.buffer, 0);
+          byte[] cipherText = new byte[buf.buffer.length];
+          System.arraycopy(buf.buffer, 0, cipherText, 0, buf.buffer.length);          
+        s2ccipher.update(cipherText, 0, s2ccipher_size, buf.buffer, 0);
       }
       j=((buf.buffer[0]<<24)&0xff000000)|
         ((buf.buffer[1]<<16)&0x00ff0000)|
@@ -885,7 +889,9 @@
       if(need>0){
 	io.getByte(buf.buffer, buf.index, need); buf.index+=(need);
 	if(s2ccipher!=null){
-	  s2ccipher.update(buf.buffer, s2ccipher_size, need, buf.buffer, s2ccipher_size);
+        byte[] cipherText = new byte[buf.buffer.length];
+        System.arraycopy(buf.buffer, 0, cipherText, 0, buf.buffer.length);
+      s2ccipher.update(cipherText, s2ccipher_size, need, buf.buffer, s2ccipher_size);
 	}
       }
 
------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing 
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
JSch-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jsch-users

Reply via email to