8193409: Improve AES supporting classes
authorapetcher
Tue, 23 Jan 2018 11:18:11 -0500
changeset 49789 27b359322b1e
parent 49788 5375d426822a
child 49790 403e2f61f384
8193409: Improve AES supporting classes Reviewed-by: valeriep
src/java.base/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java
src/java.base/share/classes/com/sun/crypto/provider/FeedbackCipher.java
src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java
src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeGCMCipher.java
src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoException.java
--- a/src/java.base/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java	Mon Jan 22 13:27:28 2018 -0800
+++ b/src/java.base/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java	Tue Jan 23 11:18:11 2018 -0500
@@ -470,6 +470,9 @@
         } catch (InvalidKeyException ike) {
             // should never happen
             throw new RuntimeException("Internal cipher key is corrupted");
+        } catch (InvalidAlgorithmParameterException iape) {
+            // should never happen
+            throw new RuntimeException("Internal cipher IV is invalid");
         }
         byte[] out2 = new byte[out.length];
         cipher.encrypt(out, 0, out.length, out2, 0);
@@ -481,6 +484,9 @@
         } catch (InvalidKeyException ike) {
             // should never happen
             throw new RuntimeException("Internal cipher key is corrupted");
+        } catch (InvalidAlgorithmParameterException iape) {
+            // should never happen
+            throw new RuntimeException("Internal cipher IV is invalid");
         }
         return out2;
     }
@@ -524,8 +530,12 @@
         }
         iv = new byte[IV_LEN];
         System.arraycopy(buffer, 0, iv, 0, iv.length);
-        cipher.init(true, cipherKey.getAlgorithm(), cipherKey.getEncoded(),
+        try {
+            cipher.init(true, cipherKey.getAlgorithm(), cipherKey.getEncoded(),
                     iv);
+        } catch (InvalidAlgorithmParameterException iape) {
+            throw new InvalidKeyException("IV in wrapped key is invalid");
+        }
         byte[] buffer2 = new byte[buffer.length - iv.length];
         cipher.decrypt(buffer, iv.length, buffer2.length,
                        buffer2, 0);
@@ -538,8 +548,12 @@
             }
         }
         // restore cipher state to prior to this call
-        cipher.init(decrypting, cipherKey.getAlgorithm(),
+        try {
+          cipher.init(decrypting, cipherKey.getAlgorithm(),
                     cipherKey.getEncoded(), IV2);
+        } catch (InvalidAlgorithmParameterException iape) {
+            throw new InvalidKeyException("IV in wrapped key is invalid");
+        }
         byte[] out = new byte[keyValLen];
         System.arraycopy(buffer2, 0, out, 0, keyValLen);
         return ConstructKeys.constructKey(out, wrappedKeyAlgorithm,
--- a/src/java.base/share/classes/com/sun/crypto/provider/FeedbackCipher.java	Mon Jan 22 13:27:28 2018 -0800
+++ b/src/java.base/share/classes/com/sun/crypto/provider/FeedbackCipher.java	Tue Jan 23 11:18:11 2018 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 package com.sun.crypto.provider;
 
 import java.security.InvalidKeyException;
+import java.security.InvalidAlgorithmParameterException;
 import javax.crypto.*;
 
 /**
@@ -99,7 +100,8 @@
      * initializing this cipher
      */
     abstract void init(boolean decrypting, String algorithm, byte[] key,
-                       byte[] iv) throws InvalidKeyException;
+                       byte[] iv) throws InvalidKeyException,
+                                         InvalidAlgorithmParameterException;
 
    /**
      * Gets the initialization vector.
--- a/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java	Mon Jan 22 13:27:28 2018 -0800
+++ b/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java	Tue Jan 23 11:18:11 2018 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -262,8 +262,9 @@
      * @exception InvalidKeyException if the given key is inappropriate for
      * initializing this cipher
      */
+    @Override
     void init(boolean decrypting, String algorithm, byte[] key, byte[] iv)
-            throws InvalidKeyException {
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
         init(decrypting, algorithm, key, iv, DEFAULT_TAG_LEN);
     }
 
@@ -282,10 +283,16 @@
      */
     void init(boolean decrypting, String algorithm, byte[] keyValue,
               byte[] ivValue, int tagLenBytes)
-              throws InvalidKeyException {
-        if (keyValue == null || ivValue == null) {
+              throws InvalidKeyException, InvalidAlgorithmParameterException {
+        if (keyValue == null) {
             throw new InvalidKeyException("Internal error");
         }
+        if (ivValue == null) {
+            throw new InvalidAlgorithmParameterException("Internal error");
+        }
+        if (ivValue.length == 0) {
+            throw new InvalidAlgorithmParameterException("IV is empty");
+        }
 
         // always encrypt mode for embedded cipher
         this.embeddedCipher.init(false, algorithm, keyValue);
--- a/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeGCMCipher.java	Mon Jan 22 13:27:28 2018 -0800
+++ b/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeGCMCipher.java	Tue Jan 23 11:18:11 2018 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -246,7 +246,17 @@
             requireReinit = false;
             ibuffer = new ByteArrayOutputStream();
         }
-        init(doEncrypt, keyBytes, ivBytes, tagLen, null);
+        try {
+            init(doEncrypt, keyBytes, ivBytes, tagLen, null);
+        } catch (UcryptoException ex) {
+            if (ex.getError() ==
+                UcryptoException.Error.CRYPTO_MECHANISM_PARAM_INVALID) {
+
+                throw new InvalidAlgorithmParameterException(ex.getMessage());
+            } else {
+                throw ex;
+            }
+        }
     }
 
     // see JCE spec
--- a/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoException.java	Mon Jan 22 13:27:28 2018 -0800
+++ b/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoException.java	Tue Jan 23 11:18:11 2018 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,93 +40,105 @@
     private static final long serialVersionUID = -933864511110035746L;
 
     // NOTE: check /usr/include/sys/crypto/common.h for updates
-    private static final String[] ERROR_MSG = {
-        "CRYPTO_SUCCESS",
-        "CRYPTO_CANCEL",
-        "CRYPTO_HOST_MEMORY",
-        "CRYPTO_GENERAL_ERROR",
-        "CRYPTO_FAILED",
-        "CRYPTO_ARGUMENTS_BAD",
-        "CRYPTO_ATTRIBUTE_READ_ONLY",
-        "CRYPTO_ATTRIBUTE_SENSITIVE",
-        "CRYPTO_ATTRIBUTE_TYPE_INVALID",
-        "CRYPTO_ATTRIBUTE_VALUE_INVALID",
-        "CRYPTO_CANCELED",
-        "CRYPTO_DATA_INVALID",
-        "CRYPTO_DATA_LEN_RANGE",
-        "CRYPTO_DEVICE_ERROR",
-        "CRYPTO_DEVICE_MEMORY",
-        "CRYPTO_DEVICE_REMOVED",
-        "CRYPTO_ENCRYPTED_DATA_INVALID",
-        "CRYPTO_ENCRYPTED_DATA_LEN_RANGE",
-        "CRYPTO_KEY_HANDLE_INVALID",
-        "CRYPTO_KEY_SIZE_RANGE",
-        "CRYPTO_KEY_TYPE_INCONSISTENT",
-        "CRYPTO_KEY_NOT_NEEDED",
-        "CRYPTO_KEY_CHANGED",
-        "CRYPTO_KEY_NEEDED",
-        "CRYPTO_KEY_INDIGESTIBLE",
-        "CRYPTO_KEY_FUNCTION_NOT_PERMITTED",
-        "CRYPTO_KEY_NOT_WRAPPABLE",
-        "CRYPTO_KEY_UNEXTRACTABLE",
-        "CRYPTO_MECHANISM_INVALID",
-        "CRYPTO_MECHANISM_PARAM_INVALID",
-        "CRYPTO_OBJECT_HANDLE_INVALID",
-        "CRYPTO_OPERATION_IS_ACTIVE",
-        "CRYPTO_OPERATION_NOT_INITIALIZED",
-        "CRYPTO_PIN_INCORRECT",
-        "CRYPTO_PIN_INVALID",
-        "CRYPTO_PIN_LEN_RANGE",
-        "CRYPTO_PIN_EXPIRED",
-        "CRYPTO_PIN_LOCKED",
-        "CRYPTO_SESSION_CLOSED",
-        "CRYPTO_SESSION_COUNT",
-        "CRYPTO_SESSION_HANDLE_INVALID",
-        "CRYPTO_SESSION_READ_ONLY",
-        "CRYPTO_SESSION_EXISTS",
-        "CRYPTO_SESSION_READ_ONLY_EXISTS",
-        "CRYPTO_SESSION_READ_WRITE_SO_EXISTS",
-        "CRYPTO_SIGNATURE_INVALID",
-        "CRYPTO_SIGNATURE_LEN_RANGE",
-        "CRYPTO_TEMPLATE_INCOMPLETE",
-        "CRYPTO_TEMPLATE_INCONSISTENT",
-        "CRYPTO_UNWRAPPING_KEY_HANDLE_INVALID",
-        "CRYPTO_UNWRAPPING_KEY_SIZE_RANGE",
-        "CRYPTO_UNWRAPPING_KEY_TYPE_INCONSISTENT",
-        "CRYPTO_USER_ALREADY_LOGGED_IN",
-        "CRYPTO_USER_NOT_LOGGED_IN",
-        "CRYPTO_USER_PIN_NOT_INITIALIZED",
-        "CRYPTO_USER_TYPE_INVALID",
-        "CRYPTO_USER_ANOTHER_ALREADY_LOGGED_IN",
-        "CRYPTO_USER_TOO_MANY_TYPES",
-        "CRYPTO_WRAPPED_KEY_INVALID",
-        "CRYPTO_WRAPPED_KEY_LEN_RANGE",
-        "CRYPTO_WRAPPING_KEY_HANDLE_INVALID",
-        "CRYPTO_WRAPPING_KEY_SIZE_RANGE",
-        "CRYPTO_WRAPPING_KEY_TYPE_INCONSISTENT",
-        "CRYPTO_RANDOM_SEED_NOT_SUPPORTED",
-        "CRYPTO_RANDOM_NO_RNG",
-        "CRYPTO_DOMAIN_PARAMS_INVALID",
-        "CRYPTO_BUFFER_TOO_SMALL",
-        "CRYPTO_INFORMATION_SENSITIVE",
-        "CRYPTO_NOT_SUPPORTED",
-        "CRYPTO_QUEUED",
-        "CRYPTO_BUFFER_TOO_BIG",
-        "CRYPTO_INVALID_CONTEXT",
-        "CRYPTO_INVALID_MAC",
-        "CRYPTO_MECH_NOT_SUPPORTED",
-        "CRYPTO_INCONSISTENT_ATTRIBUTE",
-        "CRYPTO_NO_PERMISSION",
-        "CRYPTO_INVALID_PROVIDER_ID",
-        "CRYPTO_VERSION_MISMATCH",
-        "CRYPTO_BUSY",
-        "CRYPTO_UNKNOWN_PROVIDER",
-        "CRYPTO_MODVERIFICATION_FAILED",
-        "CRYPTO_OLD_CTX_TEMPLATE",
-        "CRYPTO_WEAK_KEY",
-        "CRYPTO_FIPS140_ERROR"
+    public enum Error {
+        CRYPTO_SUCCESS,
+        CRYPTO_CANCEL,
+        CRYPTO_HOST_MEMORY,
+        CRYPTO_GENERAL_ERROR,
+        CRYPTO_FAILED,
+        CRYPTO_ARGUMENTS_BAD,
+        CRYPTO_ATTRIBUTE_READ_ONLY,
+        CRYPTO_ATTRIBUTE_SENSITIVE,
+        CRYPTO_ATTRIBUTE_TYPE_INVALID,
+        CRYPTO_ATTRIBUTE_VALUE_INVALID,
+        CRYPTO_CANCELED,
+        CRYPTO_DATA_INVALID,
+        CRYPTO_DATA_LEN_RANGE,
+        CRYPTO_DEVICE_ERROR,
+        CRYPTO_DEVICE_MEMORY,
+        CRYPTO_DEVICE_REMOVED,
+        CRYPTO_ENCRYPTED_DATA_INVALID,
+        CRYPTO_ENCRYPTED_DATA_LEN_RANGE,
+        CRYPTO_KEY_HANDLE_INVALID,
+        CRYPTO_KEY_SIZE_RANGE,
+        CRYPTO_KEY_TYPE_INCONSISTENT,
+        CRYPTO_KEY_NOT_NEEDED,
+        CRYPTO_KEY_CHANGED,
+        CRYPTO_KEY_NEEDED,
+        CRYPTO_KEY_INDIGESTIBLE,
+        CRYPTO_KEY_FUNCTION_NOT_PERMITTED,
+        CRYPTO_KEY_NOT_WRAPPABLE,
+        CRYPTO_KEY_UNEXTRACTABLE,
+        CRYPTO_MECHANISM_INVALID,
+        CRYPTO_MECHANISM_PARAM_INVALID,
+        CRYPTO_OBJECT_HANDLE_INVALID,
+        CRYPTO_OPERATION_IS_ACTIVE,
+        CRYPTO_OPERATION_NOT_INITIALIZED,
+        CRYPTO_PIN_INCORRECT,
+        CRYPTO_PIN_INVALID,
+        CRYPTO_PIN_LEN_RANGE,
+        CRYPTO_PIN_EXPIRED,
+        CRYPTO_PIN_LOCKED,
+        CRYPTO_SESSION_CLOSED,
+        CRYPTO_SESSION_COUNT,
+        CRYPTO_SESSION_HANDLE_INVALID,
+        CRYPTO_SESSION_READ_ONLY,
+        CRYPTO_SESSION_EXISTS,
+        CRYPTO_SESSION_READ_ONLY_EXISTS,
+        CRYPTO_SESSION_READ_WRITE_SO_EXISTS,
+        CRYPTO_SIGNATURE_INVALID,
+        CRYPTO_SIGNATURE_LEN_RANGE,
+        CRYPTO_TEMPLATE_INCOMPLETE,
+        CRYPTO_TEMPLATE_INCONSISTENT,
+        CRYPTO_UNWRAPPING_KEY_HANDLE_INVALID,
+        CRYPTO_UNWRAPPING_KEY_SIZE_RANGE,
+        CRYPTO_UNWRAPPING_KEY_TYPE_INCONSISTENT,
+        CRYPTO_USER_ALREADY_LOGGED_IN,
+        CRYPTO_USER_NOT_LOGGED_IN,
+        CRYPTO_USER_PIN_NOT_INITIALIZED,
+        CRYPTO_USER_TYPE_INVALID,
+        CRYPTO_USER_ANOTHER_ALREADY_LOGGED_IN,
+        CRYPTO_USER_TOO_MANY_TYPES,
+        CRYPTO_WRAPPED_KEY_INVALID,
+        CRYPTO_WRAPPED_KEY_LEN_RANGE,
+        CRYPTO_WRAPPING_KEY_HANDLE_INVALID,
+        CRYPTO_WRAPPING_KEY_SIZE_RANGE,
+        CRYPTO_WRAPPING_KEY_TYPE_INCONSISTENT,
+        CRYPTO_RANDOM_SEED_NOT_SUPPORTED,
+        CRYPTO_RANDOM_NO_RNG,
+        CRYPTO_DOMAIN_PARAMS_INVALID,
+        CRYPTO_BUFFER_TOO_SMALL,
+        CRYPTO_INFORMATION_SENSITIVE,
+        CRYPTO_NOT_SUPPORTED,
+        CRYPTO_QUEUED,
+        CRYPTO_BUFFER_TOO_BIG,
+        CRYPTO_INVALID_CONTEXT,
+        CRYPTO_INVALID_MAC,
+        CRYPTO_MECH_NOT_SUPPORTED,
+        CRYPTO_INCONSISTENT_ATTRIBUTE,
+        CRYPTO_NO_PERMISSION,
+        CRYPTO_INVALID_PROVIDER_ID,
+        CRYPTO_VERSION_MISMATCH,
+        CRYPTO_BUSY,
+        CRYPTO_UNKNOWN_PROVIDER,
+        CRYPTO_MODVERIFICATION_FAILED,
+        CRYPTO_OLD_CTX_TEMPLATE,
+        CRYPTO_WEAK_KEY,
+        CRYPTO_FIPS140_ERROR;
     };
 
+    // Array used to look up error by ordinal
+    private static final Error[] ALL_ERRORS = Error.values();
+
+    /**
+     * Get the error enum value (if any) associated with this exception.
+     */
+    public Error getError() {
+        return errorCode < ALL_ERRORS.length ?
+            ALL_ERRORS[errorCode] :
+            null;
+    }
+
     /**
      * The error code if this exception is triggered by a Ucrypto error.
      */
@@ -142,8 +154,8 @@
      */
     static String getErrorMessage(int errorCode) {
         String message;
-        if (errorCode < ERROR_MSG.length) {
-            message = ERROR_MSG[errorCode];
+        if (errorCode < ALL_ERRORS.length) {
+            message = ALL_ERRORS[errorCode].name();
         } else {
             message = "0x" + Integer.toHexString(errorCode);
         }