8193409: Improve AES supporting classes

Reviewed-by: valeriep
This commit is contained in:
Adam Petcher 2018-01-23 11:18:11 -05:00
parent 9b54e6d766
commit 412087ff64
5 changed files with 143 additions and 98 deletions

View File

@ -470,6 +470,9 @@ public final class DESedeWrapCipher extends CipherSpi {
} catch (InvalidKeyException ike) { } catch (InvalidKeyException ike) {
// should never happen // should never happen
throw new RuntimeException("Internal cipher key is corrupted"); 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]; byte[] out2 = new byte[out.length];
cipher.encrypt(out, 0, out.length, out2, 0); cipher.encrypt(out, 0, out.length, out2, 0);
@ -481,6 +484,9 @@ public final class DESedeWrapCipher extends CipherSpi {
} catch (InvalidKeyException ike) { } catch (InvalidKeyException ike) {
// should never happen // should never happen
throw new RuntimeException("Internal cipher key is corrupted"); throw new RuntimeException("Internal cipher key is corrupted");
} catch (InvalidAlgorithmParameterException iape) {
// should never happen
throw new RuntimeException("Internal cipher IV is invalid");
} }
return out2; return out2;
} }
@ -524,8 +530,12 @@ public final class DESedeWrapCipher extends CipherSpi {
} }
iv = new byte[IV_LEN]; iv = new byte[IV_LEN];
System.arraycopy(buffer, 0, iv, 0, iv.length); System.arraycopy(buffer, 0, iv, 0, iv.length);
cipher.init(true, cipherKey.getAlgorithm(), cipherKey.getEncoded(), try {
cipher.init(true, cipherKey.getAlgorithm(), cipherKey.getEncoded(),
iv); iv);
} catch (InvalidAlgorithmParameterException iape) {
throw new InvalidKeyException("IV in wrapped key is invalid");
}
byte[] buffer2 = new byte[buffer.length - iv.length]; byte[] buffer2 = new byte[buffer.length - iv.length];
cipher.decrypt(buffer, iv.length, buffer2.length, cipher.decrypt(buffer, iv.length, buffer2.length,
buffer2, 0); buffer2, 0);
@ -538,8 +548,12 @@ public final class DESedeWrapCipher extends CipherSpi {
} }
} }
// restore cipher state to prior to this call // restore cipher state to prior to this call
cipher.init(decrypting, cipherKey.getAlgorithm(), try {
cipher.init(decrypting, cipherKey.getAlgorithm(),
cipherKey.getEncoded(), IV2); cipherKey.getEncoded(), IV2);
} catch (InvalidAlgorithmParameterException iape) {
throw new InvalidKeyException("IV in wrapped key is invalid");
}
byte[] out = new byte[keyValLen]; byte[] out = new byte[keyValLen];
System.arraycopy(buffer2, 0, out, 0, keyValLen); System.arraycopy(buffer2, 0, out, 0, keyValLen);
return ConstructKeys.constructKey(out, wrappedKeyAlgorithm, return ConstructKeys.constructKey(out, wrappedKeyAlgorithm,

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,6 +26,7 @@
package com.sun.crypto.provider; package com.sun.crypto.provider;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.InvalidAlgorithmParameterException;
import javax.crypto.*; import javax.crypto.*;
/** /**
@ -99,7 +100,8 @@ abstract class FeedbackCipher {
* initializing this cipher * initializing this cipher
*/ */
abstract void init(boolean decrypting, String algorithm, byte[] key, abstract void init(boolean decrypting, String algorithm, byte[] key,
byte[] iv) throws InvalidKeyException; byte[] iv) throws InvalidKeyException,
InvalidAlgorithmParameterException;
/** /**
* Gets the initialization vector. * Gets the initialization vector.

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -262,8 +262,9 @@ final class GaloisCounterMode extends FeedbackCipher {
* @exception InvalidKeyException if the given key is inappropriate for * @exception InvalidKeyException if the given key is inappropriate for
* initializing this cipher * initializing this cipher
*/ */
@Override
void init(boolean decrypting, String algorithm, byte[] key, byte[] iv) void init(boolean decrypting, String algorithm, byte[] key, byte[] iv)
throws InvalidKeyException { throws InvalidKeyException, InvalidAlgorithmParameterException {
init(decrypting, algorithm, key, iv, DEFAULT_TAG_LEN); init(decrypting, algorithm, key, iv, DEFAULT_TAG_LEN);
} }
@ -282,10 +283,16 @@ final class GaloisCounterMode extends FeedbackCipher {
*/ */
void init(boolean decrypting, String algorithm, byte[] keyValue, void init(boolean decrypting, String algorithm, byte[] keyValue,
byte[] ivValue, int tagLenBytes) byte[] ivValue, int tagLenBytes)
throws InvalidKeyException { throws InvalidKeyException, InvalidAlgorithmParameterException {
if (keyValue == null || ivValue == null) { if (keyValue == null) {
throw new InvalidKeyException("Internal error"); 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 // always encrypt mode for embedded cipher
this.embeddedCipher.init(false, algorithm, keyValue); this.embeddedCipher.init(false, algorithm, keyValue);

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -246,7 +246,17 @@ class NativeGCMCipher extends NativeCipher {
requireReinit = false; requireReinit = false;
ibuffer = new ByteArrayOutputStream(); 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 // see JCE spec

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -40,93 +40,105 @@ public final class UcryptoException extends ProviderException {
private static final long serialVersionUID = -933864511110035746L; private static final long serialVersionUID = -933864511110035746L;
// NOTE: check /usr/include/sys/crypto/common.h for updates // NOTE: check /usr/include/sys/crypto/common.h for updates
private static final String[] ERROR_MSG = { public enum Error {
"CRYPTO_SUCCESS", CRYPTO_SUCCESS,
"CRYPTO_CANCEL", CRYPTO_CANCEL,
"CRYPTO_HOST_MEMORY", CRYPTO_HOST_MEMORY,
"CRYPTO_GENERAL_ERROR", CRYPTO_GENERAL_ERROR,
"CRYPTO_FAILED", CRYPTO_FAILED,
"CRYPTO_ARGUMENTS_BAD", CRYPTO_ARGUMENTS_BAD,
"CRYPTO_ATTRIBUTE_READ_ONLY", CRYPTO_ATTRIBUTE_READ_ONLY,
"CRYPTO_ATTRIBUTE_SENSITIVE", CRYPTO_ATTRIBUTE_SENSITIVE,
"CRYPTO_ATTRIBUTE_TYPE_INVALID", CRYPTO_ATTRIBUTE_TYPE_INVALID,
"CRYPTO_ATTRIBUTE_VALUE_INVALID", CRYPTO_ATTRIBUTE_VALUE_INVALID,
"CRYPTO_CANCELED", CRYPTO_CANCELED,
"CRYPTO_DATA_INVALID", CRYPTO_DATA_INVALID,
"CRYPTO_DATA_LEN_RANGE", CRYPTO_DATA_LEN_RANGE,
"CRYPTO_DEVICE_ERROR", CRYPTO_DEVICE_ERROR,
"CRYPTO_DEVICE_MEMORY", CRYPTO_DEVICE_MEMORY,
"CRYPTO_DEVICE_REMOVED", CRYPTO_DEVICE_REMOVED,
"CRYPTO_ENCRYPTED_DATA_INVALID", CRYPTO_ENCRYPTED_DATA_INVALID,
"CRYPTO_ENCRYPTED_DATA_LEN_RANGE", CRYPTO_ENCRYPTED_DATA_LEN_RANGE,
"CRYPTO_KEY_HANDLE_INVALID", CRYPTO_KEY_HANDLE_INVALID,
"CRYPTO_KEY_SIZE_RANGE", CRYPTO_KEY_SIZE_RANGE,
"CRYPTO_KEY_TYPE_INCONSISTENT", CRYPTO_KEY_TYPE_INCONSISTENT,
"CRYPTO_KEY_NOT_NEEDED", CRYPTO_KEY_NOT_NEEDED,
"CRYPTO_KEY_CHANGED", CRYPTO_KEY_CHANGED,
"CRYPTO_KEY_NEEDED", CRYPTO_KEY_NEEDED,
"CRYPTO_KEY_INDIGESTIBLE", CRYPTO_KEY_INDIGESTIBLE,
"CRYPTO_KEY_FUNCTION_NOT_PERMITTED", CRYPTO_KEY_FUNCTION_NOT_PERMITTED,
"CRYPTO_KEY_NOT_WRAPPABLE", CRYPTO_KEY_NOT_WRAPPABLE,
"CRYPTO_KEY_UNEXTRACTABLE", CRYPTO_KEY_UNEXTRACTABLE,
"CRYPTO_MECHANISM_INVALID", CRYPTO_MECHANISM_INVALID,
"CRYPTO_MECHANISM_PARAM_INVALID", CRYPTO_MECHANISM_PARAM_INVALID,
"CRYPTO_OBJECT_HANDLE_INVALID", CRYPTO_OBJECT_HANDLE_INVALID,
"CRYPTO_OPERATION_IS_ACTIVE", CRYPTO_OPERATION_IS_ACTIVE,
"CRYPTO_OPERATION_NOT_INITIALIZED", CRYPTO_OPERATION_NOT_INITIALIZED,
"CRYPTO_PIN_INCORRECT", CRYPTO_PIN_INCORRECT,
"CRYPTO_PIN_INVALID", CRYPTO_PIN_INVALID,
"CRYPTO_PIN_LEN_RANGE", CRYPTO_PIN_LEN_RANGE,
"CRYPTO_PIN_EXPIRED", CRYPTO_PIN_EXPIRED,
"CRYPTO_PIN_LOCKED", CRYPTO_PIN_LOCKED,
"CRYPTO_SESSION_CLOSED", CRYPTO_SESSION_CLOSED,
"CRYPTO_SESSION_COUNT", CRYPTO_SESSION_COUNT,
"CRYPTO_SESSION_HANDLE_INVALID", CRYPTO_SESSION_HANDLE_INVALID,
"CRYPTO_SESSION_READ_ONLY", CRYPTO_SESSION_READ_ONLY,
"CRYPTO_SESSION_EXISTS", CRYPTO_SESSION_EXISTS,
"CRYPTO_SESSION_READ_ONLY_EXISTS", CRYPTO_SESSION_READ_ONLY_EXISTS,
"CRYPTO_SESSION_READ_WRITE_SO_EXISTS", CRYPTO_SESSION_READ_WRITE_SO_EXISTS,
"CRYPTO_SIGNATURE_INVALID", CRYPTO_SIGNATURE_INVALID,
"CRYPTO_SIGNATURE_LEN_RANGE", CRYPTO_SIGNATURE_LEN_RANGE,
"CRYPTO_TEMPLATE_INCOMPLETE", CRYPTO_TEMPLATE_INCOMPLETE,
"CRYPTO_TEMPLATE_INCONSISTENT", CRYPTO_TEMPLATE_INCONSISTENT,
"CRYPTO_UNWRAPPING_KEY_HANDLE_INVALID", CRYPTO_UNWRAPPING_KEY_HANDLE_INVALID,
"CRYPTO_UNWRAPPING_KEY_SIZE_RANGE", CRYPTO_UNWRAPPING_KEY_SIZE_RANGE,
"CRYPTO_UNWRAPPING_KEY_TYPE_INCONSISTENT", CRYPTO_UNWRAPPING_KEY_TYPE_INCONSISTENT,
"CRYPTO_USER_ALREADY_LOGGED_IN", CRYPTO_USER_ALREADY_LOGGED_IN,
"CRYPTO_USER_NOT_LOGGED_IN", CRYPTO_USER_NOT_LOGGED_IN,
"CRYPTO_USER_PIN_NOT_INITIALIZED", CRYPTO_USER_PIN_NOT_INITIALIZED,
"CRYPTO_USER_TYPE_INVALID", CRYPTO_USER_TYPE_INVALID,
"CRYPTO_USER_ANOTHER_ALREADY_LOGGED_IN", CRYPTO_USER_ANOTHER_ALREADY_LOGGED_IN,
"CRYPTO_USER_TOO_MANY_TYPES", CRYPTO_USER_TOO_MANY_TYPES,
"CRYPTO_WRAPPED_KEY_INVALID", CRYPTO_WRAPPED_KEY_INVALID,
"CRYPTO_WRAPPED_KEY_LEN_RANGE", CRYPTO_WRAPPED_KEY_LEN_RANGE,
"CRYPTO_WRAPPING_KEY_HANDLE_INVALID", CRYPTO_WRAPPING_KEY_HANDLE_INVALID,
"CRYPTO_WRAPPING_KEY_SIZE_RANGE", CRYPTO_WRAPPING_KEY_SIZE_RANGE,
"CRYPTO_WRAPPING_KEY_TYPE_INCONSISTENT", CRYPTO_WRAPPING_KEY_TYPE_INCONSISTENT,
"CRYPTO_RANDOM_SEED_NOT_SUPPORTED", CRYPTO_RANDOM_SEED_NOT_SUPPORTED,
"CRYPTO_RANDOM_NO_RNG", CRYPTO_RANDOM_NO_RNG,
"CRYPTO_DOMAIN_PARAMS_INVALID", CRYPTO_DOMAIN_PARAMS_INVALID,
"CRYPTO_BUFFER_TOO_SMALL", CRYPTO_BUFFER_TOO_SMALL,
"CRYPTO_INFORMATION_SENSITIVE", CRYPTO_INFORMATION_SENSITIVE,
"CRYPTO_NOT_SUPPORTED", CRYPTO_NOT_SUPPORTED,
"CRYPTO_QUEUED", CRYPTO_QUEUED,
"CRYPTO_BUFFER_TOO_BIG", CRYPTO_BUFFER_TOO_BIG,
"CRYPTO_INVALID_CONTEXT", CRYPTO_INVALID_CONTEXT,
"CRYPTO_INVALID_MAC", CRYPTO_INVALID_MAC,
"CRYPTO_MECH_NOT_SUPPORTED", CRYPTO_MECH_NOT_SUPPORTED,
"CRYPTO_INCONSISTENT_ATTRIBUTE", CRYPTO_INCONSISTENT_ATTRIBUTE,
"CRYPTO_NO_PERMISSION", CRYPTO_NO_PERMISSION,
"CRYPTO_INVALID_PROVIDER_ID", CRYPTO_INVALID_PROVIDER_ID,
"CRYPTO_VERSION_MISMATCH", CRYPTO_VERSION_MISMATCH,
"CRYPTO_BUSY", CRYPTO_BUSY,
"CRYPTO_UNKNOWN_PROVIDER", CRYPTO_UNKNOWN_PROVIDER,
"CRYPTO_MODVERIFICATION_FAILED", CRYPTO_MODVERIFICATION_FAILED,
"CRYPTO_OLD_CTX_TEMPLATE", CRYPTO_OLD_CTX_TEMPLATE,
"CRYPTO_WEAK_KEY", CRYPTO_WEAK_KEY,
"CRYPTO_FIPS140_ERROR" 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. * The error code if this exception is triggered by a Ucrypto error.
*/ */
@ -142,8 +154,8 @@ public final class UcryptoException extends ProviderException {
*/ */
static String getErrorMessage(int errorCode) { static String getErrorMessage(int errorCode) {
String message; String message;
if (errorCode < ERROR_MSG.length) { if (errorCode < ALL_ERRORS.length) {
message = ERROR_MSG[errorCode]; message = ALL_ERRORS[errorCode].name();
} else { } else {
message = "0x" + Integer.toHexString(errorCode); message = "0x" + Integer.toHexString(errorCode);
} }