Hi,
I am attaching a patch that follows the behaviour outlined in the JDK javadoc for javax.crypto.CipherSpi's engineInit methods. I have already committed a test case (gnu.testlet.gnu.javax.crypto.jce.TestOfCipherEngineInit) that models this logic.
Issues related to PR27849 have been addressed here. Comments are welcome.
Thanks,
Vivek

Changelog:

2006-06-15  Vivek Lakshmanan  <[EMAIL PROTECTED]>

        * gnu/javax/crypto/jce/cipher/CipherAdapter.java
        (engineInit(int, Key, AlgorithmParameterSpec, SecureRandom)): When
        param is null, use random or default information when possible.
        (engineInit(int, Key, SecureRandom)): Seperate common initialization
        logic into engineInitHandler and reuse the code in
engineInit(int, Key, AlgorithmSpec, SecureRandom). (engineInitHandler): New method.

Index: gnu/javax/crypto/jce/cipher/CipherAdapter.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/javax/crypto/jce/cipher/CipherAdapter.java,v
retrieving revision 1.3
diff -u -r1.3 CipherAdapter.java
--- gnu/javax/crypto/jce/cipher/CipherAdapter.java	4 Jun 2006 06:57:26 -0000	1.3
+++ gnu/javax/crypto/jce/cipher/CipherAdapter.java	15 Jun 2006 23:50:09 -0000
@@ -38,6 +38,7 @@
 
 package gnu.javax.crypto.jce.cipher;
 
+import gnu.java.security.Registry;
 import gnu.javax.crypto.cipher.IBlockCipher;
 import gnu.javax.crypto.cipher.CipherFactory;
 import gnu.javax.crypto.jce.spec.BlockCipherParameterSpec;
@@ -246,6 +247,23 @@
   protected void engineInit(int opmode, Key key, SecureRandom random)
       throws InvalidKeyException
   {
+    try
+      {
+        engineInit(opmode, key, (AlgorithmParameterSpec) null, random);
+      }
+    catch (InvalidAlgorithmParameterException e)
+      {
+        // Being utilized for decryption or unwrapping which may require parameters. 
+        throw (InvalidKeyException) (new InvalidKeyException().initCause(e));
+      }
+
+  }
+  
+  // Executes initialization logic after all parameters have been handled
+  // by the engineInit()s.
+  private void engineInitHandler(int opmode, Key key, SecureRandom random)
+      throws InvalidKeyException
+  {
     switch (opmode)
       {
       case Cipher.ENCRYPT_MODE:
@@ -279,12 +297,34 @@
       InvalidAlgorithmParameterException
   {
     if (params == null)
-      {
-        byte[] iv = new byte[blockLen];
-        random.nextBytes(iv);
-        attributes.put(IMode.IV, iv);
+      {  
+        // All cipher modes require parameters (like an IV) except ECB. When these 
+        // cant be derived from the given key then it must be generated randomly if
+        // in ENCRYPT or WRAP mode. Parameters that have defaults for our cipher
+        // must be set to these defaults.
+        if(!mode.name().toLowerCase().startsWith(Registry.ECB_MODE))
+          {
+            switch (opmode)
+              {
+              case Cipher.ENCRYPT_MODE:
+              case Cipher.WRAP_MODE:
+                // Generate random algorithm parameters if used for ENCRYPT or WRAP
+                byte[] iv = new byte[blockLen];
+                random.nextBytes(iv);
+                attributes.put(IMode.IV, iv);
+                break;
+              default:
+                // If being used for DECRYPT or key UNWRAP,
+                // throw an exception.
+                throw new InvalidAlgorithmParameterException(
+                                              "Required algorithm parameters missing for mode: "
+                                                  + mode.name());
+              } 
+          }   
+        // Add default for block length etc.
         blockLen = cipher.defaultBlockSize();
-        attributes.put(IBlockCipher.CIPHER_BLOCK_SIZE, new Integer(blockLen));
+        attributes.put(IBlockCipher.CIPHER_BLOCK_SIZE,
+                       new Integer(blockLen));
         keyLen = 0;
       }
     else if (params instanceof BlockCipherParameterSpec)
@@ -304,7 +344,7 @@
         attributes.put(IBlockCipher.CIPHER_BLOCK_SIZE, new Integer(blockLen));
         keyLen = 0;
       }
-    engineInit(opmode, key, random);
+    engineInitHandler(opmode, key, random);
   }
 
   protected void engineInit(int opmode, Key key, AlgorithmParameters params,

Reply via email to