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) {
// 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 @@ public final class DESedeWrapCipher extends CipherSpi {
} 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 @@ public final class DESedeWrapCipher extends CipherSpi {
}
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 @@ public final class DESedeWrapCipher extends CipherSpi {
}
}
// 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,

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.
*
* 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 @@ abstract class FeedbackCipher {
* 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.

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.
*
* 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
* 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 @@ final class GaloisCounterMode extends FeedbackCipher {
*/
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);

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.
*
* This code is free software; you can redistribute it and/or modify it
@ -246,7 +246,17 @@ class NativeGCMCipher extends NativeCipher {
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

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.
*
* 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;
// 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 @@ public final class UcryptoException extends ProviderException {
*/
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);
}