libcore: throw InvalidKeyException instead of ProviderException

In java.security javax.crypto and java.security classes with
late binding, when guessing the provider and none of the
available ones supports the specified key

Bug: 18987633

(cherry pick from e38b83dd96281d178b01476b67d354655bf2de62)

Change-Id: I5931046e9044984baf724157138bf3a7c7ef5e90
diff --git a/luni/src/main/java/java/security/Signature.java b/luni/src/main/java/java/security/Signature.java
index 795ccad..b11abaa 100644
--- a/luni/src/main/java/java/security/Signature.java
+++ b/luni/src/main/java/java/security/Signature.java
@@ -172,7 +172,12 @@
             throw new NoSuchAlgorithmException("Unknown algorithm: " + algorithm);
         }
 
-        SpiAndProvider spiAndProvider = tryAlgorithm(null, provider, algorithm);
+        SpiAndProvider spiAndProvider;
+        try {
+            spiAndProvider = tryAlgorithm(null, provider, algorithm);
+        } catch (InvalidKeyException e) {
+            throw new IllegalStateException("InvalidKeyException thrown when key == null", e);
+        }
         if (spiAndProvider == null) {
             if (provider == null) {
                 throw new NoSuchAlgorithmException("No provider found for " + algorithm);
@@ -187,7 +192,12 @@
         return new SignatureImpl(algorithm, provider);
     }
 
-    private static Engine.SpiAndProvider tryAlgorithm(Key key, Provider provider, String algorithm) {
+    /**
+     * @throws InvalidKeyException if the specified key cannot be used to
+     *             initialize any provider.
+     */
+    private static Engine.SpiAndProvider tryAlgorithm(
+            Key key, Provider provider, String algorithm) throws InvalidKeyException {
         if (provider != null) {
             Provider.Service service = provider.getService(SERVICE, algorithm);
             if (service == null) {
@@ -196,15 +206,22 @@
             return tryAlgorithmWithProvider(null, service);
         }
         ArrayList<Provider.Service> services = ENGINE.getServices(algorithm);
-        if (services == null) {
+        if (services == null || services.isEmpty()) {
             return null;
         }
+        boolean keySupported = false;
         for (Provider.Service service : services) {
-            Engine.SpiAndProvider sap = tryAlgorithmWithProvider(key, service);
-            if (sap != null) {
-                return sap;
+            if (key == null || service.supportsParameter(key)) {
+                keySupported = true;
+                Engine.SpiAndProvider sap = tryAlgorithmWithProvider(key, service);
+                if (sap != null) {
+                    return sap;
+                }
             }
         }
+        if (!keySupported) {
+            throw new InvalidKeyException("No provider supports the provided key");
+        }
         return null;
     }
 
@@ -661,7 +678,7 @@
 
         @Override
         void ensureProviderChosen() {
-            getSpi(null);
+            getSpi();
         }
 
         @Override
@@ -719,8 +736,11 @@
 
         /**
          * Makes sure a CipherSpi that matches this type is selected.
+         *
+         * @throws InvalidKeyException if the specified key cannot be used to
+         *             initialize this signature.
          */
-        private SignatureSpi getSpi(Key key) {
+        private SignatureSpi getSpi(Key key) throws InvalidKeyException {
             synchronized (initLock) {
                 if (spiImpl != null && key == null) {
                     return spiImpl;
@@ -742,7 +762,11 @@
          * Convenience call when the Key is not available.
          */
         private SignatureSpi getSpi() {
-            return getSpi(null);
+            try {
+                return getSpi(null);
+            } catch (InvalidKeyException e) {
+                throw new IllegalStateException("InvalidKeyException thrown when key == null", e);
+            }
         }
 
         @Override
diff --git a/luni/src/main/java/javax/crypto/Cipher.java b/luni/src/main/java/javax/crypto/Cipher.java
index 5a66c20..9d6bd22 100644
--- a/luni/src/main/java/javax/crypto/Cipher.java
+++ b/luni/src/main/java/javax/crypto/Cipher.java
@@ -297,7 +297,15 @@
         }
 
         String[] transformParts = checkTransformation(transformation);
-        if (tryCombinations(null, provider, transformParts) == null) {
+
+        boolean providerSupportsAlgorithm;
+        try {
+            providerSupportsAlgorithm =
+                    tryCombinations(null /* key */, provider, transformParts) != null;
+        } catch (InvalidKeyException e) {
+            throw new IllegalStateException("InvalidKeyException thrown when key == null", e);
+        }
+        if (!providerSupportsAlgorithm) {
             if (provider == null) {
                 throw new NoSuchAlgorithmException("No provider found for " + transformation);
             } else {
@@ -340,8 +348,11 @@
 
     /**
      * Makes sure a CipherSpi that matches this type is selected.
+     *
+     * @throws InvalidKeyException if the specified key cannot be used to
+     *             initialize this cipher.
      */
-    private CipherSpi getSpi(Key key) {
+    private CipherSpi getSpi(Key key) throws InvalidKeyException {
         if (specifiedSpi != null) {
             return specifiedSpi;
         }
@@ -351,8 +362,8 @@
                 return spiImpl;
             }
 
-            final Engine.SpiAndProvider sap = tryCombinations(key, specifiedProvider,
-                    transformParts);
+            final Engine.SpiAndProvider sap = tryCombinations(
+                    key, specifiedProvider, transformParts);
             if (sap == null) {
                 throw new ProviderException("No provider for " + transformation);
             }
@@ -368,7 +379,11 @@
      * Convenience call when the Key is not available.
      */
     private CipherSpi getSpi() {
-        return getSpi(null);
+        try {
+            return getSpi(null);
+        } catch (InvalidKeyException e) {
+            throw new IllegalStateException("InvalidKeyException thrown when key == null", e);
+        }
     }
 
     /**
@@ -396,9 +411,12 @@
      *   [cipher]//[padding]
      *   [cipher]
      * </pre>
+     *
+     * @throws InvalidKeyException if the specified key cannot be used to
+     *             initialize any provider.
      */
     private static Engine.SpiAndProvider tryCombinations(Key key, Provider provider,
-            String[] transformParts) {
+            String[] transformParts) throws InvalidKeyException {
         Engine.SpiAndProvider sap = null;
 
         if (transformParts[1] != null && transformParts[2] != null) {
@@ -428,35 +446,42 @@
         return tryTransform(key, provider, transformParts[0], transformParts, NeedToSet.BOTH);
     }
 
+    /**
+     * @throws InvalidKeyException if the specified key cannot be used to
+     *             initialize this cipher.
+     */
     private static Engine.SpiAndProvider tryTransform(Key key, Provider provider, String transform,
-            String[] transformParts, NeedToSet type) {
+            String[] transformParts, NeedToSet type) throws InvalidKeyException {
         if (provider != null) {
             Provider.Service service = provider.getService(SERVICE, transform);
             if (service == null) {
                 return null;
             }
-            return tryTransformWithProvider(null, transformParts, type, service);
+            return tryTransformWithProvider(transformParts, type, service);
         }
         ArrayList<Provider.Service> services = ENGINE.getServices(transform);
-        if (services == null) {
+        if (services == null || services.isEmpty()) {
             return null;
         }
+        boolean keySupported = false;
         for (Provider.Service service : services) {
-            Engine.SpiAndProvider sap = tryTransformWithProvider(key, transformParts, type, service);
-            if (sap != null) {
-                return sap;
+            if (key == null || service.supportsParameter(key)) {
+                keySupported = true;
+                Engine.SpiAndProvider sap = tryTransformWithProvider(transformParts, type, service);
+                if (sap != null) {
+                    return sap;
+                }
             }
         }
+        if (!keySupported) {
+            throw new InvalidKeyException("No provider supports the provided key");
+        }
         return null;
     }
 
-    private static Engine.SpiAndProvider tryTransformWithProvider(Key key, String[] transformParts,
+    private static Engine.SpiAndProvider tryTransformWithProvider(String[] transformParts,
             NeedToSet type, Provider.Service service) {
         try {
-            if (key != null && !service.supportsParameter(key)) {
-                return null;
-            }
-
             /*
              * Check to see if the Cipher even supports the attributes before
              * trying to instantiate it.
diff --git a/luni/src/main/java/javax/crypto/KeyAgreement.java b/luni/src/main/java/javax/crypto/KeyAgreement.java
index 1ba660d..22c2f3f 100644
--- a/luni/src/main/java/javax/crypto/KeyAgreement.java
+++ b/luni/src/main/java/javax/crypto/KeyAgreement.java
@@ -178,7 +178,13 @@
             throw new NullPointerException("algorithm == null");
         }
 
-        if (tryAlgorithm(null, provider, algorithm) == null) {
+        boolean providerSupportsAlgorithm;
+        try {
+            providerSupportsAlgorithm = tryAlgorithm(null /* key */, provider, algorithm) != null;
+        } catch (InvalidKeyException e) {
+            throw new IllegalStateException("InvalidKeyException thrown when key == null", e);
+        }
+        if (!providerSupportsAlgorithm) {
             if (provider == null) {
                 throw new NoSuchAlgorithmException("No provider found for " + algorithm);
             } else {
@@ -189,33 +195,41 @@
         return new KeyAgreement(null, provider, algorithm);
     }
 
-    private static Engine.SpiAndProvider tryAlgorithm(Key key, Provider provider, String algorithm) {
+    /**
+     * @throws InvalidKeyException if the specified key cannot be used to
+     *             initialize any provider.
+     */
+    private static Engine.SpiAndProvider tryAlgorithm(Key key, Provider provider, String algorithm)
+            throws InvalidKeyException {
         if (provider != null) {
             Provider.Service service = provider.getService(SERVICE, algorithm);
             if (service == null) {
                 return null;
             }
-            return tryAlgorithmWithProvider(null, service);
+            return tryAlgorithmWithProvider(service);
         }
         ArrayList<Provider.Service> services = ENGINE.getServices(algorithm);
-        if (services == null) {
+        if (services == null || services.isEmpty()) {
             return null;
         }
+        boolean keySupported = false;
         for (Provider.Service service : services) {
-            Engine.SpiAndProvider sap = tryAlgorithmWithProvider(key, service);
-            if (sap != null) {
-                return sap;
+            if (key == null || service.supportsParameter(key)) {
+                keySupported = true;
+                Engine.SpiAndProvider sap = tryAlgorithmWithProvider(service);
+                if (sap != null) {
+                    return sap;
+                }
             }
         }
+        if (!keySupported) {
+            throw new InvalidKeyException("No provider supports the provided key");
+        }
         return null;
     }
 
-    private static Engine.SpiAndProvider tryAlgorithmWithProvider(Key key, Provider.Service service) {
+    private static Engine.SpiAndProvider tryAlgorithmWithProvider(Provider.Service service) {
         try {
-            if (key != null && !service.supportsParameter(key)) {
-                return null;
-            }
-
             Engine.SpiAndProvider sap = ENGINE.getInstance(service, null);
             if (sap.spi == null || sap.provider == null) {
                 return null;
@@ -231,8 +245,11 @@
 
     /**
      * Makes sure a KeyAgreementSpi that matches this type is selected.
+     *
+     * @throws InvalidKeyException if the specified key cannot be used to
+     *             initialize this key agreement.
      */
-    private KeyAgreementSpi getSpi(Key key) {
+    private KeyAgreementSpi getSpi(Key key) throws InvalidKeyException {
         synchronized (initLock) {
             if (spiImpl != null && key == null) {
                 return spiImpl;
@@ -254,7 +271,11 @@
      * Convenience call when the Key is not available.
      */
     private KeyAgreementSpi getSpi() {
-        return getSpi(null);
+        try {
+            return getSpi(null /* key */);
+        } catch (InvalidKeyException e) {
+            throw new IllegalStateException("InvalidKeyException thrown when key == null", e);
+        }
     }
 
     /**
diff --git a/luni/src/main/java/javax/crypto/Mac.java b/luni/src/main/java/javax/crypto/Mac.java
index 7da84e6..b8fb947 100644
--- a/luni/src/main/java/javax/crypto/Mac.java
+++ b/luni/src/main/java/javax/crypto/Mac.java
@@ -182,7 +182,13 @@
             throw new NullPointerException("algorithm == null");
         }
 
-        if (tryAlgorithm(null, provider, algorithm) == null) {
+        boolean providerSupportsAlgorithm;
+        try {
+            providerSupportsAlgorithm = tryAlgorithm(null /* key */, provider, algorithm) != null;
+        } catch (InvalidKeyException e) {
+            throw new IllegalStateException("InvalidKeyException thrown when key == null", e);
+        }
+        if (!providerSupportsAlgorithm) {
             if (provider == null) {
                 throw new NoSuchAlgorithmException("No provider found for " + algorithm);
             } else {
@@ -192,34 +198,41 @@
         }
         return new Mac(null, provider, algorithm);
     }
-
-    private static Engine.SpiAndProvider tryAlgorithm(Key key, Provider provider, String algorithm) {
+    /**
+      * @throws InvalidKeyException if the specified key cannot be used to
+      *             initialize this mac.
+      */
+    private static Engine.SpiAndProvider tryAlgorithm(
+            Key key, Provider provider, String algorithm) throws InvalidKeyException {
         if (provider != null) {
             Provider.Service service = provider.getService(SERVICE, algorithm);
             if (service == null) {
                 return null;
             }
-            return tryAlgorithmWithProvider(null, service);
+            return tryAlgorithmWithProvider(service);
         }
         ArrayList<Provider.Service> services = ENGINE.getServices(algorithm);
-        if (services == null) {
+        if (services == null || services.isEmpty()) {
             return null;
         }
+        boolean keySupported = false;
         for (Provider.Service service : services) {
-            Engine.SpiAndProvider sap = tryAlgorithmWithProvider(key, service);
-            if (sap != null) {
-                return sap;
+            if (key == null || service.supportsParameter(key)) {
+                keySupported = true;
+                Engine.SpiAndProvider sap = tryAlgorithmWithProvider(service);
+                if (sap != null) {
+                    return sap;
+                }
             }
         }
+        if (!keySupported) {
+            throw new InvalidKeyException("No provider supports the provided key");
+        }
         return null;
     }
 
-    private static Engine.SpiAndProvider tryAlgorithmWithProvider(Key key, Provider.Service service) {
+    private static Engine.SpiAndProvider tryAlgorithmWithProvider(Provider.Service service) {
         try {
-            if (key != null && !service.supportsParameter(key)) {
-                return null;
-            }
-
             Engine.SpiAndProvider sap = ENGINE.getInstance(service, null);
             if (sap.spi == null || sap.provider == null) {
                 return null;
@@ -235,8 +248,11 @@
 
     /**
      * Makes sure a MacSpi that matches this type is selected.
+     *
+     * @throws InvalidKeyException if the specified key cannot be used to
+     *             initialize this mac.
      */
-    private MacSpi getSpi(Key key) {
+    private MacSpi getSpi(Key key) throws InvalidKeyException {
         synchronized (initLock) {
             if (spiImpl != null && provider != null && key == null) {
                 return spiImpl;
@@ -268,7 +284,11 @@
      * Convenience call when the Key is not available.
      */
     private MacSpi getSpi() {
-        return getSpi(null);
+        try {
+            return getSpi(null);
+        } catch (InvalidKeyException e) {
+            throw new IllegalStateException("InvalidKeyException thrown when key == null", e);
+        }
     }
 
     /**
diff --git a/luni/src/test/java/libcore/java/security/SignatureTest.java b/luni/src/test/java/libcore/java/security/SignatureTest.java
index d34acd8..9aa75bd 100644
--- a/luni/src/test/java/libcore/java/security/SignatureTest.java
+++ b/luni/src/test/java/libcore/java/security/SignatureTest.java
@@ -94,6 +94,31 @@
         }
     }
 
+    /**
+     * Several exceptions can be thrown by init. Check that in this case we throw the right one,
+     * as the error could fall under the umbrella of other exceptions.
+     * http://b/18987633
+     */
+    public void testSignature_init_DoesNotSupportKeyClass_throwsInvalidKeyException()
+            throws Exception {
+        Provider mockProvider = new MockProvider("MockProvider") {
+            public void setup() {
+                put("Signature.FOO", MockSignatureSpi.AllKeyTypes.class.getName());
+                put("Signature.FOO SupportedKeyClasses", "None");
+            }
+        };
+
+        Security.addProvider(mockProvider);
+        try {
+            Signature s = Signature.getInstance("FOO");
+            s.initSign(new MockPrivateKey());
+            fail("Expected InvalidKeyException");
+        } catch (InvalidKeyException expected) {
+        } finally {
+            Security.removeProvider(mockProvider.getName());
+        }
+    }
+
     public void testSignature_getInstance_OnlyUsesSpecifiedProvider_SameNameAndClass_Success()
             throws Exception {
         Provider mockProvider = new MockProvider("MockProvider") {
diff --git a/luni/src/test/java/libcore/javax/crypto/CipherTest.java b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
index 611d5f4..c8dd932 100644
--- a/luni/src/test/java/libcore/javax/crypto/CipherTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/CipherTest.java
@@ -3263,4 +3263,29 @@
             }
         }
     }
+
+    /**
+     * Several exceptions can be thrown by init. Check that in this case we throw the right one,
+     * as the error could fall under the umbrella of other exceptions.
+     * http://b/18987633
+     */
+    public void testCipher_init_DoesNotSupportKeyClass_throwsInvalidKeyException()
+            throws Exception {
+        Provider mockProvider = new MockProvider("MockProvider") {
+            public void setup() {
+                put("Cipher.FOO", MockCipherSpi.AllKeyTypes.class.getName());
+                put("Cipher.FOO SupportedKeyClasses", "none");
+            }
+        };
+
+        Security.addProvider(mockProvider);
+        try {
+            Cipher c = Cipher.getInstance("FOO");
+            c.init(Cipher.DECRYPT_MODE, new MockKey());
+            fail("Expected InvalidKeyException");
+        } catch (InvalidKeyException expected) {
+        } finally {
+            Security.removeProvider(mockProvider.getName());
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java b/luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java
index ba03f75..9281b43 100644
--- a/luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/KeyAgreementTest.java
@@ -16,6 +16,7 @@
 
 package libcore.javax.crypto;
 
+import java.security.InvalidKeyException;
 import java.security.Provider;
 import java.security.Security;
 
@@ -54,7 +55,6 @@
             public void setup() {
                 put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName());
                 put("KeyAgreement.FOO SupportedKeyClasses", "none");
-
             }
         };
 
@@ -67,4 +67,29 @@
             Security.removeProvider(mockProvider.getName());
         }
     }
+
+    /**
+     * Several exceptions can be thrown by init. Check that in this case we throw the right one,
+     * as the error could fall under the umbrella of other exceptions.
+     * http://b/18987633
+     */
+    public void testKeyAgreement_init_DoesNotSupportKeyClass_throwsInvalidKeyException()
+            throws Exception {
+        Provider mockProvider = new MockProvider("MockProvider") {
+            public void setup() {
+                put("KeyAgreement.FOO", MockKeyAgreementSpi.AllKeyTypes.class.getName());
+                put("KeyAgreement.FOO SupportedKeyClasses", "none");
+            }
+        };
+
+        Security.addProvider(mockProvider);
+        try {
+            KeyAgreement c = KeyAgreement.getInstance("FOO");
+            c.init(new MockKey());
+            fail("Expected InvalidKeyException");
+        } catch (InvalidKeyException expected) {
+        } finally {
+            Security.removeProvider(mockProvider.getName());
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/javax/crypto/MacTest.java b/luni/src/test/java/libcore/javax/crypto/MacTest.java
new file mode 100644
index 0000000..314a564
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/crypto/MacTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package libcore.javax.crypto;
+
+import junit.framework.TestCase;
+
+import java.security.InvalidKeyException;
+import java.security.Provider;
+import java.security.Security;
+
+import javax.crypto.Mac;
+
+public class MacTest extends TestCase {
+    private static abstract class MockProvider extends Provider {
+        public MockProvider(String name) {
+            super(name, 1.0, "Mock provider used for testing");
+            setup();
+        }
+
+        public abstract void setup();
+    }
+
+    /**
+     * Several exceptions can be thrown by init. Check that in this case we throw the right one,
+     * as the error could fall under the umbrella of other exceptions.
+     * http://b/18987633
+     */
+    public void testMac_init_DoesNotSupportKeyClass_throwsInvalidKeyException()
+            throws Exception {
+        Provider mockProvider = new MockProvider("MockProvider") {
+            public void setup() {
+                put("Mac.FOO", MockMacSpi.AllKeyTypes.class.getName());
+                put("Mac.FOO SupportedKeyClasses", "none");
+
+            }
+        };
+
+        Security.addProvider(mockProvider);
+        try {
+            Mac c = Mac.getInstance("FOO");
+            c.init(new MockKey());
+            fail("Expected InvalidKeyException");
+        } catch (InvalidKeyException expected) {
+        } finally {
+            Security.removeProvider(mockProvider.getName());
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/javax/crypto/MockMacSpi.java b/luni/src/test/java/libcore/javax/crypto/MockMacSpi.java
new file mode 100644
index 0000000..0edeba7
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/crypto/MockMacSpi.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package libcore.javax.crypto;
+
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.MacSpi;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+
+/**
+ * Mock CipherSpi used by {@link libcore.javax.crypto.CipherTest}.
+ */
+public class MockMacSpi extends MacSpi {
+    public static class SpecificKeyTypes extends MockMacSpi {
+        @Override
+        public void checkKeyType(Key key) throws InvalidKeyException {
+            if (!(key instanceof MockKey)) {
+                throw new InvalidKeyException("Must be MockKey!");
+            }
+        }
+    }
+
+    public static class SpecificKeyTypes2 extends MockMacSpi {
+        @Override
+        public void checkKeyType(Key key) throws InvalidKeyException {
+            System.err.println("Checking key of type " + key.getClass().getName());
+            if (!(key instanceof MockKey2)) {
+                throw new InvalidKeyException("Must be MockKey2!");
+            }
+        }
+    }
+
+    public static class AllKeyTypes extends MockMacSpi {
+    }
+
+    public void checkKeyType(Key key) throws InvalidKeyException {
+    }
+
+    @Override
+    protected int engineGetMacLength() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected void engineInit(Key key, AlgorithmParameterSpec params)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected void engineUpdate(byte input) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected void engineUpdate(byte[] input, int inputOffset, int inputLen) {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected byte[] engineDoFinal() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
+    protected void engineReset() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+}