From: <ls...@us...> - 2009-02-14 20:30:02
|
Revision: 5025 http://jnode.svn.sourceforge.net/jnode/?rev=5025&view=rev Author: lsantha Date: 2009-02-14 20:29:54 +0000 (Sat, 14 Feb 2009) Log Message: ----------- OpenJDK integration. Modified Paths: -------------- trunk/core/src/classpath/java/java/net/Socket.java Added Paths: ----------- trunk/core/src/openjdk/com/com/sun/crypto/ trunk/core/src/openjdk/com/com/sun/crypto/provider/ trunk/core/src/openjdk/com/com/sun/crypto/provider/AESCipher.java trunk/core/src/openjdk/com/com/sun/crypto/provider/AESConstants.java trunk/core/src/openjdk/com/com/sun/crypto/provider/AESCrypt.java trunk/core/src/openjdk/com/com/sun/crypto/provider/AESKeyGenerator.java trunk/core/src/openjdk/com/com/sun/crypto/provider/AESParameters.java trunk/core/src/openjdk/com/com/sun/crypto/provider/AESWrapCipher.java trunk/core/src/openjdk/com/com/sun/crypto/provider/ARCFOURCipher.java trunk/core/src/openjdk/com/com/sun/crypto/provider/BlockCipherParamsCore.java trunk/core/src/openjdk/com/com/sun/crypto/provider/BlowfishCipher.java trunk/core/src/openjdk/com/com/sun/crypto/provider/BlowfishConstants.java trunk/core/src/openjdk/com/com/sun/crypto/provider/BlowfishCrypt.java trunk/core/src/openjdk/com/com/sun/crypto/provider/BlowfishKeyGenerator.java trunk/core/src/openjdk/com/com/sun/crypto/provider/BlowfishParameters.java trunk/core/src/openjdk/com/com/sun/crypto/provider/CipherBlockChaining.java trunk/core/src/openjdk/com/com/sun/crypto/provider/CipherCore.java trunk/core/src/openjdk/com/com/sun/crypto/provider/CipherFeedback.java trunk/core/src/openjdk/com/com/sun/crypto/provider/CipherTextStealing.java trunk/core/src/openjdk/com/com/sun/crypto/provider/CipherWithWrappingSpi.java trunk/core/src/openjdk/com/com/sun/crypto/provider/ConstructKeys.java trunk/core/src/openjdk/com/com/sun/crypto/provider/CounterMode.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DESCipher.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DESConstants.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DESCrypt.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DESKey.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DESKeyFactory.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DESKeyGenerator.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DESParameters.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DESedeCipher.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DESedeCrypt.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DESedeKey.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DESedeKeyFactory.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DESedeKeyGenerator.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DESedeParameters.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DESedeWrapCipher.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DHKeyAgreement.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DHKeyFactory.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DHKeyPairGenerator.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DHParameterGenerator.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DHParameters.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DHPrivateKey.java trunk/core/src/openjdk/com/com/sun/crypto/provider/DHPublicKey.java trunk/core/src/openjdk/com/com/sun/crypto/provider/ElectronicCodeBook.java trunk/core/src/openjdk/com/com/sun/crypto/provider/EncryptedPrivateKeyInfo.java trunk/core/src/openjdk/com/com/sun/crypto/provider/FeedbackCipher.java trunk/core/src/openjdk/com/com/sun/crypto/provider/HmacCore.java trunk/core/src/openjdk/com/com/sun/crypto/provider/HmacMD5.java trunk/core/src/openjdk/com/com/sun/crypto/provider/HmacMD5KeyGenerator.java trunk/core/src/openjdk/com/com/sun/crypto/provider/HmacPKCS12PBESHA1.java trunk/core/src/openjdk/com/com/sun/crypto/provider/HmacSHA1.java trunk/core/src/openjdk/com/com/sun/crypto/provider/HmacSHA1KeyGenerator.java trunk/core/src/openjdk/com/com/sun/crypto/provider/ISO10126Padding.java trunk/core/src/openjdk/com/com/sun/crypto/provider/JarVerifier.java trunk/core/src/openjdk/com/com/sun/crypto/provider/JceKeyStore.java trunk/core/src/openjdk/com/com/sun/crypto/provider/KeyGeneratorCore.java trunk/core/src/openjdk/com/com/sun/crypto/provider/KeyProtector.java trunk/core/src/openjdk/com/com/sun/crypto/provider/OAEPParameters.java trunk/core/src/openjdk/com/com/sun/crypto/provider/OutputFeedback.java trunk/core/src/openjdk/com/com/sun/crypto/provider/PBECipherCore.java trunk/core/src/openjdk/com/com/sun/crypto/provider/PBEKey.java trunk/core/src/openjdk/com/com/sun/crypto/provider/PBEKeyFactory.java trunk/core/src/openjdk/com/com/sun/crypto/provider/PBEParameters.java trunk/core/src/openjdk/com/com/sun/crypto/provider/PBEWithMD5AndDESCipher.java trunk/core/src/openjdk/com/com/sun/crypto/provider/PBEWithMD5AndTripleDESCipher.java trunk/core/src/openjdk/com/com/sun/crypto/provider/PBKDF2HmacSHA1Factory.java trunk/core/src/openjdk/com/com/sun/crypto/provider/PBKDF2KeyImpl.java trunk/core/src/openjdk/com/com/sun/crypto/provider/PCBC.java trunk/core/src/openjdk/com/com/sun/crypto/provider/PKCS12PBECipherCore.java trunk/core/src/openjdk/com/com/sun/crypto/provider/PKCS5Padding.java trunk/core/src/openjdk/com/com/sun/crypto/provider/Padding.java trunk/core/src/openjdk/com/com/sun/crypto/provider/PrivateKeyInfo.java trunk/core/src/openjdk/com/com/sun/crypto/provider/RC2Cipher.java trunk/core/src/openjdk/com/com/sun/crypto/provider/RC2Crypt.java trunk/core/src/openjdk/com/com/sun/crypto/provider/RC2Parameters.java trunk/core/src/openjdk/com/com/sun/crypto/provider/RSACipher.java trunk/core/src/openjdk/com/com/sun/crypto/provider/SslMacCore.java trunk/core/src/openjdk/com/com/sun/crypto/provider/SunJCE.java trunk/core/src/openjdk/com/com/sun/crypto/provider/SymmetricCipher.java trunk/core/src/openjdk/com/com/sun/crypto/provider/TlsKeyMaterialGenerator.java trunk/core/src/openjdk/com/com/sun/crypto/provider/TlsMasterSecretGenerator.java trunk/core/src/openjdk/com/com/sun/crypto/provider/TlsPrfGenerator.java trunk/core/src/openjdk/com/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java trunk/core/src/openjdk/com/com/sun/crypto/provider/ai.java trunk/core/src/openjdk/com/com/sun/net/ssl/internal/ssl/Provider.java trunk/core/src/openjdk/javax/javax/crypto/BadPaddingException.java trunk/core/src/openjdk/javax/javax/crypto/Cipher.java trunk/core/src/openjdk/javax/javax/crypto/CipherInputStream.java trunk/core/src/openjdk/javax/javax/crypto/CipherOutputStream.java trunk/core/src/openjdk/javax/javax/crypto/CipherSpi.java trunk/core/src/openjdk/javax/javax/crypto/CryptoAllPermission.java trunk/core/src/openjdk/javax/javax/crypto/CryptoPermission.java trunk/core/src/openjdk/javax/javax/crypto/CryptoPermissions.java trunk/core/src/openjdk/javax/javax/crypto/CryptoPolicyParser.java trunk/core/src/openjdk/javax/javax/crypto/EncryptedPrivateKeyInfo.java trunk/core/src/openjdk/javax/javax/crypto/ExemptionMechanism.java trunk/core/src/openjdk/javax/javax/crypto/ExemptionMechanismException.java trunk/core/src/openjdk/javax/javax/crypto/ExemptionMechanismSpi.java trunk/core/src/openjdk/javax/javax/crypto/IllegalBlockSizeException.java trunk/core/src/openjdk/javax/javax/crypto/JarVerifier.java trunk/core/src/openjdk/javax/javax/crypto/JceSecurity.java trunk/core/src/openjdk/javax/javax/crypto/JceSecurityManager.java trunk/core/src/openjdk/javax/javax/crypto/KeyAgreement.java trunk/core/src/openjdk/javax/javax/crypto/KeyAgreementSpi.java trunk/core/src/openjdk/javax/javax/crypto/KeyGenerator.java trunk/core/src/openjdk/javax/javax/crypto/KeyGeneratorSpi.java trunk/core/src/openjdk/javax/javax/crypto/Mac.java trunk/core/src/openjdk/javax/javax/crypto/MacSpi.java trunk/core/src/openjdk/javax/javax/crypto/NoSuchPaddingException.java trunk/core/src/openjdk/javax/javax/crypto/NullCipher.java trunk/core/src/openjdk/javax/javax/crypto/NullCipherSpi.java trunk/core/src/openjdk/javax/javax/crypto/SealedObject.java trunk/core/src/openjdk/javax/javax/crypto/SecretKey.java trunk/core/src/openjdk/javax/javax/crypto/SecretKeyFactory.java trunk/core/src/openjdk/javax/javax/crypto/SecretKeyFactorySpi.java trunk/core/src/openjdk/javax/javax/crypto/ShortBufferException.java trunk/core/src/openjdk/javax/javax/crypto/interfaces/ trunk/core/src/openjdk/javax/javax/crypto/interfaces/DHKey.java trunk/core/src/openjdk/javax/javax/crypto/interfaces/DHPrivateKey.java trunk/core/src/openjdk/javax/javax/crypto/interfaces/DHPublicKey.java trunk/core/src/openjdk/javax/javax/crypto/interfaces/PBEKey.java trunk/core/src/openjdk/javax/javax/crypto/interfaces/package.html trunk/core/src/openjdk/javax/javax/crypto/package.html trunk/core/src/openjdk/javax/javax/crypto/spec/DESKeySpec.java trunk/core/src/openjdk/javax/javax/crypto/spec/DESedeKeySpec.java trunk/core/src/openjdk/javax/javax/crypto/spec/DHGenParameterSpec.java trunk/core/src/openjdk/javax/javax/crypto/spec/DHParameterSpec.java trunk/core/src/openjdk/javax/javax/crypto/spec/DHPrivateKeySpec.java trunk/core/src/openjdk/javax/javax/crypto/spec/DHPublicKeySpec.java trunk/core/src/openjdk/javax/javax/crypto/spec/IvParameterSpec.java trunk/core/src/openjdk/javax/javax/crypto/spec/PBEKeySpec.java trunk/core/src/openjdk/javax/javax/crypto/spec/PBEParameterSpec.java trunk/core/src/openjdk/javax/javax/crypto/spec/RC2ParameterSpec.java trunk/core/src/openjdk/javax/javax/crypto/spec/RC5ParameterSpec.java trunk/core/src/openjdk/javax/javax/crypto/spec/SecretKeySpec.java trunk/core/src/openjdk/javax/javax/crypto/spec/package.html trunk/core/src/openjdk/sun/sun/nio/ch/DirectBuffer.java Removed Paths: ------------- trunk/core/src/classpath/javax/javax/crypto/ Modified: trunk/core/src/classpath/java/java/net/Socket.java =================================================================== --- trunk/core/src/classpath/java/java/net/Socket.java 2009-02-14 20:24:42 UTC (rev 5024) +++ trunk/core/src/classpath/java/java/net/Socket.java 2009-02-14 20:29:54 UTC (rev 5025) @@ -1270,4 +1270,9 @@ { return outputShutdown; } + + //jnode openjdk + public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { + //TODO implement it + } } Added: trunk/core/src/openjdk/com/com/sun/crypto/provider/AESCipher.java =================================================================== --- trunk/core/src/openjdk/com/com/sun/crypto/provider/AESCipher.java (rev 0) +++ trunk/core/src/openjdk/com/com/sun/crypto/provider/AESCipher.java 2009-02-14 20:29:54 UTC (rev 5025) @@ -0,0 +1,431 @@ +/* + * Copyright 2002-2007 Sun Microsystems, Inc. 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.crypto.provider; + +import java.security.*; +import java.security.spec.*; +import javax.crypto.*; +import javax.crypto.spec.*; +import javax.crypto.BadPaddingException; + +/** + * This class implements the AES algorithm in its various modes + * (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>, <code>CBC</code>, + * <code>PCBC</code>) and padding schemes (<code>PKCS5Padding</code>, + * <code>NoPadding</code>, <code>ISO10126Padding</code>). + * + * @author Valerie Peng + * + * + * @see AESCrypt + * @see CipherBlockChaining + * @see ElectronicCodeBook + * @see CipherFeedback + * @see OutputFeedback + */ + +public final class AESCipher extends CipherSpi { + /* + * internal CipherCore object which does the real work. + */ + private CipherCore core = null; + + /** + * Creates an instance of AES cipher with default ECB mode and + * PKCS5Padding. + * + * @exception SecurityException if this constructor fails to verify + * its own integrity + */ + public AESCipher() { + SunJCE.ensureIntegrity(getClass()); + core = new CipherCore(new AESCrypt(), AESConstants.AES_BLOCK_SIZE); + } + + /** + * Sets the mode of this cipher. + * + * @param mode the cipher mode + * + * @exception NoSuchAlgorithmException if the requested cipher mode does + * not exist + */ + protected void engineSetMode(String mode) + throws NoSuchAlgorithmException { + core.setMode(mode); + } + + /** + * Sets the padding mechanism of this cipher. + * + * @param padding the padding mechanism + * + * @exception NoSuchPaddingException if the requested padding mechanism + * does not exist + */ + protected void engineSetPadding(String paddingScheme) + throws NoSuchPaddingException { + core.setPadding(paddingScheme); + } + + /** + * Returns the block size (in bytes). + * + * @return the block size (in bytes), or 0 if the underlying algorithm is + * not a block cipher + */ + protected int engineGetBlockSize() { + return AESConstants.AES_BLOCK_SIZE; + } + + /** + * Returns the length in bytes that an output buffer would need to be in + * order to hold the result of the next <code>update</code> or + * <code>doFinal</code> operation, given the input length + * <code>inputLen</code> (in bytes). + * + * <p>This call takes into account any unprocessed (buffered) data from a + * previous <code>update</code> call, and padding. + * + * <p>The actual output length of the next <code>update</code> or + * <code>doFinal</code> call may be smaller than the length returned by + * this method. + * + * @param inputLen the input length (in bytes) + * + * @return the required output buffer size (in bytes) + */ + protected int engineGetOutputSize(int inputLen) { + return core.getOutputSize(inputLen); + } + + /** + * Returns the initialization vector (IV) in a new buffer. + * + * <p>This is useful in the case where a random IV has been created + * (see <a href = "#init">init</a>), + * or in the context of password-based encryption or + * decryption, where the IV is derived from a user-provided password. + * + * @return the initialization vector in a new buffer, or null if the + * underlying algorithm does not use an IV, or if the IV has not yet + * been set. + */ + protected byte[] engineGetIV() { + return core.getIV(); + } + + /** + * Returns the parameters used with this cipher. + * + * <p>The returned parameters may be the same that were used to initialize + * this cipher, or may contain the default set of parameters or a set of + * randomly generated parameters used by the underlying cipher + * implementation (provided that the underlying cipher implementation + * uses a default set of parameters or creates new parameters if it needs + * parameters but was not initialized with any). + * + * @return the parameters used with this cipher, or null if this cipher + * does not use any parameters. + */ + protected AlgorithmParameters engineGetParameters() { + return core.getParameters("AES"); + } + + /** + * Initializes this cipher with a key and a source of randomness. + * + * <p>The cipher is initialized for one of the following four operations: + * encryption, decryption, key wrapping or key unwrapping, depending on + * the value of <code>opmode</code>. + * + * <p>If this cipher requires an initialization vector (IV), it will get + * it from <code>random</code>. + * This behaviour should only be used in encryption or key wrapping + * mode, however. + * When initializing a cipher that requires an IV for decryption or + * key unwrapping, the IV + * (same IV that was used for encryption or key wrapping) must be provided + * explicitly as a + * parameter, in order to get the correct result. + * + * <p>This method also cleans existing buffer and other related state + * information. + * + * @param opmode the operation mode of this cipher (this is one of + * the following: + * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, + * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) + * @param key the secret key + * @param random the source of randomness + * + * @exception InvalidKeyException if the given key is inappropriate for + * initializing this cipher + */ + protected void engineInit(int opmode, Key key, SecureRandom random) + throws InvalidKeyException { + core.init(opmode, key, random); + } + + /** + * Initializes this cipher with a key, a set of + * algorithm parameters, and a source of randomness. + * + * <p>The cipher is initialized for one of the following four operations: + * encryption, decryption, key wrapping or key unwrapping, depending on + * the value of <code>opmode</code>. + * + * <p>If this cipher (including its underlying feedback or padding scheme) + * requires any random bytes, it will get them from <code>random</code>. + * + * @param opmode the operation mode of this cipher (this is one of + * the following: + * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, + * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) + * @param key the encryption key + * @param params the algorithm parameters + * @param random the source of randomness + * + * @exception InvalidKeyException if the given key is inappropriate for + * initializing this cipher + * @exception InvalidAlgorithmParameterException if the given algorithm + * parameters are inappropriate for this cipher + */ + protected void engineInit(int opmode, Key key, + AlgorithmParameterSpec params, + SecureRandom random) + throws InvalidKeyException, InvalidAlgorithmParameterException { + core.init(opmode, key, params, random); + } + + protected void engineInit(int opmode, Key key, + AlgorithmParameters params, + SecureRandom random) + throws InvalidKeyException, InvalidAlgorithmParameterException { + core.init(opmode, key, params, random); + } + + /** + * Continues a multiple-part encryption or decryption operation + * (depending on how this cipher was initialized), processing another data + * part. + * + * <p>The first <code>inputLen</code> bytes in the <code>input</code> + * buffer, starting at <code>inputOffset</code>, are processed, and the + * result is stored in a new buffer. + * + * @param input the input buffer + * @param inputOffset the offset in <code>input</code> where the input + * starts + * @param inputLen the input length + * + * @return the new buffer with the result + * + * @exception IllegalStateException if this cipher is in a wrong state + * (e.g., has not been initialized) + */ + protected byte[] engineUpdate(byte[] input, int inputOffset, + int inputLen) { + return core.update(input, inputOffset, inputLen); + } + + /** + * Continues a multiple-part encryption or decryption operation + * (depending on how this cipher was initialized), processing another data + * part. + * + * <p>The first <code>inputLen</code> bytes in the <code>input</code> + * buffer, starting at <code>inputOffset</code>, are processed, and the + * result is stored in the <code>output</code> buffer, starting at + * <code>outputOffset</code>. + * + * @param input the input buffer + * @param inputOffset the offset in <code>input</code> where the input + * starts + * @param inputLen the input length + * @param output the buffer for the result + * @param outputOffset the offset in <code>output</code> where the result + * is stored + * + * @return the number of bytes stored in <code>output</code> + * + * @exception ShortBufferException if the given output buffer is too small + * to hold the result + */ + protected int engineUpdate(byte[] input, int inputOffset, int inputLen, + byte[] output, int outputOffset) + throws ShortBufferException { + return core.update(input, inputOffset, inputLen, output, + outputOffset); + } + + /** + * Encrypts or decrypts data in a single-part operation, + * or finishes a multiple-part operation. + * The data is encrypted or decrypted, depending on how this cipher was + * initialized. + * + * <p>The first <code>inputLen</code> bytes in the <code>input</code> + * buffer, starting at <code>inputOffset</code>, and any input bytes that + * may have been buffered during a previous <code>update</code> operation, + * are processed, with padding (if requested) being applied. + * The result is stored in a new buffer. + * + * <p>The cipher is reset to its initial state (uninitialized) after this + * call. + * + * @param input the input buffer + * @param inputOffset the offset in <code>input</code> where the input + * starts + * @param inputLen the input length + * + * @return the new buffer with the result + * + * @exception IllegalBlockSizeException if this cipher is a block cipher, + * no padding has been requested (only in encryption mode), and the total + * input length of the data processed by this cipher is not a multiple of + * block size + * @exception BadPaddingException if this cipher is in decryption mode, + * and (un)padding has been requested, but the decrypted data is not + * bounded by the appropriate padding bytes + */ + protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen) + throws IllegalBlockSizeException, BadPaddingException { + return core.doFinal(input, inputOffset, inputLen); + } + + /** + * Encrypts or decrypts data in a single-part operation, + * or finishes a multiple-part operation. + * The data is encrypted or decrypted, depending on how this cipher was + * initialized. + * + * <p>The first <code>inputLen</code> bytes in the <code>input</code> + * buffer, starting at <code>inputOffset</code>, and any input bytes that + * may have been buffered during a previous <code>update</code> operation, + * are processed, with padding (if requested) being applied. + * The result is stored in the <code>output</code> buffer, starting at + * <code>outputOffset</code>. + * + * <p>The cipher is reset to its initial state (uninitialized) after this + * call. + * + * @param input the input buffer + * @param inputOffset the offset in <code>input</code> where the input + * starts + * @param inputLen the input length + * @param output the buffer for the result + * @param outputOffset the offset in <code>output</code> where the result + * is stored + * + * @return the number of bytes stored in <code>output</code> + * + * @exception IllegalBlockSizeException if this cipher is a block cipher, + * no padding has been requested (only in encryption mode), and the total + * input length of the data processed by this cipher is not a multiple of + * block size + * @exception ShortBufferException if the given output buffer is too small + * to hold the result + * @exception BadPaddingException if this cipher is in decryption mode, + * and (un)padding has been requested, but the decrypted data is not + * bounded by the appropriate padding bytes + */ + protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, + byte[] output, int outputOffset) + throws IllegalBlockSizeException, ShortBufferException, + BadPaddingException { + return core.doFinal(input, inputOffset, inputLen, output, + outputOffset); + } + + /** + * Returns the key size of the given key object. + * + * @param key the key object. + * + * @return the key size of the given key object. + * + * @exception InvalidKeyException if <code>key</code> is invalid. + */ + protected int engineGetKeySize(Key key) throws InvalidKeyException { + byte[] encoded = key.getEncoded(); + if (!AESCrypt.isKeySizeValid(encoded.length)) { + throw new InvalidKeyException("Invalid AES key length: " + + encoded.length + " bytes"); + } + return encoded.length * 8; + } + + /** + * Wrap a key. + * + * @param key the key to be wrapped. + * + * @return the wrapped key. + * + * @exception IllegalBlockSizeException if this cipher is a block + * cipher, no padding has been requested, and the length of the + * encoding of the key to be wrapped is not a + * multiple of the block size. + * + * @exception InvalidKeyException if it is impossible or unsafe to + * wrap the key with this cipher (e.g., a hardware protected key is + * being passed to a software only cipher). + */ + protected byte[] engineWrap(Key key) + throws IllegalBlockSizeException, InvalidKeyException { + return core.wrap(key); + } + + /** + * Unwrap a previously wrapped key. + * + * @param wrappedKey the key to be unwrapped. + * + * @param wrappedKeyAlgorithm the algorithm the wrapped key is for. + * + * @param wrappedKeyType the type of the wrapped key. + * This is one of <code>Cipher.SECRET_KEY</code>, + * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>. + * + * @return the unwrapped key. + * + * @exception NoSuchAlgorithmException if no installed providers + * can create keys of type <code>wrappedKeyType</code> for the + * <code>wrappedKeyAlgorithm</code>. + * + * @exception InvalidKeyException if <code>wrappedKey</code> does not + * represent a wrapped key of type <code>wrappedKeyType</code> for + * the <code>wrappedKeyAlgorithm</code>. + */ + protected Key engineUnwrap(byte[] wrappedKey, + String wrappedKeyAlgorithm, + int wrappedKeyType) + throws InvalidKeyException, NoSuchAlgorithmException { + return core.unwrap(wrappedKey, wrappedKeyAlgorithm, + wrappedKeyType); + } +} Added: trunk/core/src/openjdk/com/com/sun/crypto/provider/AESConstants.java =================================================================== --- trunk/core/src/openjdk/com/com/sun/crypto/provider/AESConstants.java (rev 0) +++ trunk/core/src/openjdk/com/com/sun/crypto/provider/AESConstants.java 2009-02-14 20:29:54 UTC (rev 5025) @@ -0,0 +1,46 @@ +/* + * Copyright 2002-2007 Sun Microsystems, Inc. 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.crypto.provider; + +/** + * This class defines the constants used by the AES implementation. + * + * @author Valerie Peng + * + * + * @see AESCipher + */ + +interface AESConstants { + + // AES block size in bytes. + int AES_BLOCK_SIZE = 16; + + // Valid AES key sizes in bytes. + // NOTE: The values need to be listed in an *increasing* order + // since DHKeyAgreement depends on this fact. + int[] AES_KEYSIZES = { 16, 24, 32 }; +} Added: trunk/core/src/openjdk/com/com/sun/crypto/provider/AESCrypt.java =================================================================== --- trunk/core/src/openjdk/com/com/sun/crypto/provider/AESCrypt.java (rev 0) +++ trunk/core/src/openjdk/com/com/sun/crypto/provider/AESCrypt.java 2009-02-14 20:29:54 UTC (rev 5025) @@ -0,0 +1,658 @@ +/* + * Copyright 2002-2007 Sun Microsystems, Inc. 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* $Id: Rijndael.java,v 1.6 2000/02/10 01:31:41 gelderen Exp $ + * + * Copyright (C) 1995-2000 The Cryptix Foundation Limited. + * All rights reserved. + * + * Use, modification, copying and distribution of this softwareas is subject + * the terms and conditions of the Cryptix General Licence. You should have + * received a copy of the Cryptix General Licence along with this library; + * if not, you can download a copy from http://www.cryptix.org/ . + */ + +package com.sun.crypto.provider; + +import java.security.InvalidKeyException; + +/** + * Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit + * block size and variable key-size (128-, 192- and 256-bit). + * <p> + * Rijndael was designed by <a href="mailto:ri...@es...">Vincent + * Rijmen</a> and <a href="mailto:Joa...@vi...">Joan Daemen</a>. + */ +final class AESCrypt extends SymmetricCipher implements AESConstants +{ + private boolean ROUNDS_12 = false; + private boolean ROUNDS_14 = false; + + /** Session and Sub keys */ + private Object[] sessionK = null; + private int[] K = null; + + /** (ROUNDS-1) * 4 */ + private int limit = 0; + + AESCrypt() { + // empty + } + + /** + * Returns this cipher's block size. + * + * @return this cipher's block size + */ + int getBlockSize() { + return AES_BLOCK_SIZE; + } + + void init(boolean decrypting, String algorithm, byte[] key) + throws InvalidKeyException { + if (!algorithm.equalsIgnoreCase("AES") + && !algorithm.equalsIgnoreCase("Rijndael")) { + throw new InvalidKeyException + ("Wrong algorithm: AES or Rijndael required"); + } + if (!isKeySizeValid(key.length)) { + throw new InvalidKeyException("Invalid AES key length: " + + key.length + " bytes"); + } + + // generate session key and reset sub key. + sessionK = makeKey(key); + setSubKey(decrypting); + } + + private void setSubKey(boolean decrypting) { + int[][] Kd = (int[][]) sessionK[decrypting ? 1 : 0]; + int rounds = Kd.length; + this.K = new int[rounds*4]; + for(int i=0; i<rounds; i++) { + for(int j=0; j<4; j++) { + K[i*4 + j] = Kd[i][j]; + } + } + + if (decrypting) { + int j0 = K[K.length-4]; + int j1 = K[K.length-3]; + int j2 = K[K.length-2]; + int j3 = K[K.length-1]; + + for (int i=this.K.length-1; i>3; i--) { + this.K[i] = this.K[i-4]; + } + K[0] = j0; + K[1] = j1; + K[2] = j2; + K[3] = j3; + } + + ROUNDS_12 = (rounds>=13); + ROUNDS_14 = (rounds==15); + + rounds--; + limit=rounds*4; + } + + private static int[] + alog = new int[256], + log = new int[256]; + + private static final byte[] + S = new byte[256], + Si = new byte[256]; + + private static final int[] + T1 = new int[256], + T2 = new int[256], + T3 = new int[256], + T4 = new int[256], + T5 = new int[256], + T6 = new int[256], + T7 = new int[256], + T8 = new int[256]; + + private static final int[] + U1 = new int[256], + U2 = new int[256], + U3 = new int[256], + U4 = new int[256]; + + private static final byte[] rcon = new byte[30]; + + + // Static code - to intialise S-boxes and T-boxes + static + { + int ROOT = 0x11B; + int i, j = 0; + + // + // produce log and alog tables, needed for multiplying in the + // field GF(2^m) (generator = 3) + // + alog[0] = 1; + for (i = 1; i < 256; i++) + { + j = (alog[i-1] << 1) ^ alog[i-1]; + if ((j & 0x100) != 0) { + j ^= ROOT; + } + alog[i] = j; + } + for (i = 1; i < 255; i++) { + log[alog[i]] = i; + } + byte[][] A = new byte[][] + { + {1, 1, 1, 1, 1, 0, 0, 0}, + {0, 1, 1, 1, 1, 1, 0, 0}, + {0, 0, 1, 1, 1, 1, 1, 0}, + {0, 0, 0, 1, 1, 1, 1, 1}, + {1, 0, 0, 0, 1, 1, 1, 1}, + {1, 1, 0, 0, 0, 1, 1, 1}, + {1, 1, 1, 0, 0, 0, 1, 1}, + {1, 1, 1, 1, 0, 0, 0, 1} + }; + byte[] B = new byte[] { 0, 1, 1, 0, 0, 0, 1, 1}; + + // + // substitution box based on F^{-1}(x) + // + int t; + byte[][] box = new byte[256][8]; + box[1][7] = 1; + for (i = 2; i < 256; i++) { + j = alog[255 - log[i]]; + for (t = 0; t < 8; t++) { + box[i][t] = (byte)((j >>> (7 - t)) & 0x01); + } + } + // + // affine transform: box[i] <- B + A*box[i] + // + byte[][] cox = new byte[256][8]; + for (i = 0; i < 256; i++) { + for (t = 0; t < 8; t++) { + cox[i][t] = B[t]; + for (j = 0; j < 8; j++) { + cox[i][t] ^= A[t][j] * box[i][j]; + } + } + } + // + // S-boxes and inverse S-boxes + // + for (i = 0; i < 256; i++) { + S[i] = (byte)(cox[i][0] << 7); + for (t = 1; t < 8; t++) { + S[i] ^= cox[i][t] << (7-t); + } + Si[S[i] & 0xFF] = (byte) i; + } + // + // T-boxes + // + byte[][] G = new byte[][] { + {2, 1, 1, 3}, + {3, 2, 1, 1}, + {1, 3, 2, 1}, + {1, 1, 3, 2} + }; + byte[][] AA = new byte[4][8]; + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) AA[i][j] = G[i][j]; + AA[i][i+4] = 1; + } + byte pivot, tmp; + byte[][] iG = new byte[4][4]; + for (i = 0; i < 4; i++) { + pivot = AA[i][i]; + if (pivot == 0) { + t = i + 1; + while ((AA[t][i] == 0) && (t < 4)) { + t++; + } + if (t == 4) { + throw new RuntimeException("G matrix is not invertible"); + } + else { + for (j = 0; j < 8; j++) { + tmp = AA[i][j]; + AA[i][j] = AA[t][j]; + AA[t][j] = (byte) tmp; + } + pivot = AA[i][i]; + } + } + for (j = 0; j < 8; j++) { + if (AA[i][j] != 0) { + AA[i][j] = (byte) + alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF]) % 255]; + } + } + for (t = 0; t < 4; t++) { + if (i != t) { + for (j = i+1; j < 8; j++) { + AA[t][j] ^= mul(AA[i][j], AA[t][i]); + } + AA[t][i] = 0; + } + } + } + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + iG[i][j] = AA[i][j + 4]; + } + } + + int s; + for (t = 0; t < 256; t++) { + s = S[t]; + T1[t] = mul4(s, G[0]); + T2[t] = mul4(s, G[1]); + T3[t] = mul4(s, G[2]); + T4[t] = mul4(s, G[3]); + + s = Si[t]; + T5[t] = mul4(s, iG[0]); + T6[t] = mul4(s, iG[1]); + T7[t] = mul4(s, iG[2]); + T8[t] = mul4(s, iG[3]); + + U1[t] = mul4(t, iG[0]); + U2[t] = mul4(t, iG[1]); + U3[t] = mul4(t, iG[2]); + U4[t] = mul4(t, iG[3]); + } + // + // round constants + // + rcon[0] = 1; + int r = 1; + for (t = 1; t < 30; t++) { + r = mul(2, r); + rcon[t] = (byte) r; + } + log = null; + alog = null; + } + + // multiply two elements of GF(2^m) + private static final int mul (int a, int b) { + return (a != 0 && b != 0) ? + alog[(log[a & 0xFF] + log[b & 0xFF]) % 255] : + 0; + } + + // convenience method used in generating Transposition boxes + private static final int mul4 (int a, byte[] b) { + if (a == 0) return 0; + a = log[a & 0xFF]; + int a0 = (b[0] != 0) ? alog[(a + log[b[0] & 0xFF]) % 255] & 0xFF : 0; + int a1 = (b[1] != 0) ? alog[(a + log[b[1] & 0xFF]) % 255] & 0xFF : 0; + int a2 = (b[2] != 0) ? alog[(a + log[b[2] & 0xFF]) % 255] & 0xFF : 0; + int a3 = (b[3] != 0) ? alog[(a + log[b[3] & 0xFF]) % 255] & 0xFF : 0; + return a0 << 24 | a1 << 16 | a2 << 8 | a3; + } + + // check if the specified length (in bytes) is a valid keysize for AES + static final boolean isKeySizeValid(int len) { + for (int i = 0; i < AES_KEYSIZES.length; i++) { + if (len == AES_KEYSIZES[i]) { + return true; + } + } + return false; + } + + /** + * Encrypt exactly one block of plaintext. + */ + void encryptBlock(byte[] in, int inOffset, + byte[] out, int outOffset) + { + int keyOffset = 0; + int t0 = ((in[inOffset++] ) << 24 | + (in[inOffset++] & 0xFF) << 16 | + (in[inOffset++] & 0xFF) << 8 | + (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; + int t1 = ((in[inOffset++] ) << 24 | + (in[inOffset++] & 0xFF) << 16 | + (in[inOffset++] & 0xFF) << 8 | + (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; + int t2 = ((in[inOffset++] ) << 24 | + (in[inOffset++] & 0xFF) << 16 | + (in[inOffset++] & 0xFF) << 8 | + (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; + int t3 = ((in[inOffset++] ) << 24 | + (in[inOffset++] & 0xFF) << 16 | + (in[inOffset++] & 0xFF) << 8 | + (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; + + // apply round transforms + while( keyOffset < limit ) + { + int a0, a1, a2; + a0 = T1[(t0 >>> 24) ] ^ + T2[(t1 >>> 16) & 0xFF] ^ + T3[(t2 >>> 8) & 0xFF] ^ + T4[(t3 ) & 0xFF] ^ K[keyOffset++]; + a1 = T1[(t1 >>> 24) ] ^ + T2[(t2 >>> 16) & 0xFF] ^ + T3[(t3 >>> 8) & 0xFF] ^ + T4[(t0 ) & 0xFF] ^ K[keyOffset++]; + a2 = T1[(t2 >>> 24) ] ^ + T2[(t3 >>> 16) & 0xFF] ^ + T3[(t0 >>> 8) & 0xFF] ^ + T4[(t1 ) & 0xFF] ^ K[keyOffset++]; + t3 = T1[(t3 >>> 24) ] ^ + T2[(t0 >>> 16) & 0xFF] ^ + T3[(t1 >>> 8) & 0xFF] ^ + T4[(t2 ) & 0xFF] ^ K[keyOffset++]; + t0 = a0; t1 = a1; t2 = a2; + } + + // last round is special + int tt = K[keyOffset++]; + out[outOffset++] = (byte)(S[(t0 >>> 24) ] ^ (tt >>> 24)); + out[outOffset++] = (byte)(S[(t1 >>> 16) & 0xFF] ^ (tt >>> 16)); + out[outOffset++] = (byte)(S[(t2 >>> 8) & 0xFF] ^ (tt >>> 8)); + out[outOffset++] = (byte)(S[(t3 ) & 0xFF] ^ (tt )); + tt = K[keyOffset++]; + out[outOffset++] = (byte)(S[(t1 >>> 24) ] ^ (tt >>> 24)); + out[outOffset++] = (byte)(S[(t2 >>> 16) & 0xFF] ^ (tt >>> 16)); + out[outOffset++] = (byte)(S[(t3 >>> 8) & 0xFF] ^ (tt >>> 8)); + out[outOffset++] = (byte)(S[(t0 ) & 0xFF] ^ (tt )); + tt = K[keyOffset++]; + out[outOffset++] = (byte)(S[(t2 >>> 24) ] ^ (tt >>> 24)); + out[outOffset++] = (byte)(S[(t3 >>> 16) & 0xFF] ^ (tt >>> 16)); + out[outOffset++] = (byte)(S[(t0 >>> 8) & 0xFF] ^ (tt >>> 8)); + out[outOffset++] = (byte)(S[(t1 ) & 0xFF] ^ (tt )); + tt = K[keyOffset++]; + out[outOffset++] = (byte)(S[(t3 >>> 24) ] ^ (tt >>> 24)); + out[outOffset++] = (byte)(S[(t0 >>> 16) & 0xFF] ^ (tt >>> 16)); + out[outOffset++] = (byte)(S[(t1 >>> 8) & 0xFF] ^ (tt >>> 8)); + out[outOffset ] = (byte)(S[(t2 ) & 0xFF] ^ (tt )); + } + + + /** + * Decrypt exactly one block of plaintext. + */ + void decryptBlock(byte[] in, int inOffset, + byte[] out, int outOffset) + { + int keyOffset = 4; + int t0 = ((in[inOffset++] ) << 24 | + (in[inOffset++] & 0xFF) << 16 | + (in[inOffset++] & 0xFF) << 8 | + (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; + int t1 = ((in[inOffset++] ) << 24 | + (in[inOffset++] & 0xFF) << 16 | + (in[inOffset++] & 0xFF) << 8 | + (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; + int t2 = ((in[inOffset++] ) << 24 | + (in[inOffset++] & 0xFF) << 16 | + (in[inOffset++] & 0xFF) << 8 | + (in[inOffset++] & 0xFF) ) ^ K[keyOffset++]; + int t3 = ((in[inOffset++] ) << 24 | + (in[inOffset++] & 0xFF) << 16 | + (in[inOffset++] & 0xFF) << 8 | + (in[inOffset ] & 0xFF) ) ^ K[keyOffset++]; + + int a0, a1, a2; + if(ROUNDS_12) + { + a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ + T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; + a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ + T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; + a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ + T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; + t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ + T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; + t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ + T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; + t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ + T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; + t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ + T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; + t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ + T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; + + if(ROUNDS_14) + { + a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ + T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; + a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ + T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; + a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ + T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; + t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ + T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; + t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ + T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; + t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ + T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; + t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ + T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; + t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ + T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; + } + } + a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ + T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; + a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ + T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; + a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ + T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; + t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ + T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; + t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ + T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; + t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ + T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; + t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ + T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; + t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ + T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; + a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ + T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; + a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ + T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; + a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ + T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; + t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ + T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; + t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ + T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; + t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ + T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; + t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ + T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; + t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ + T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; + a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ + T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; + a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ + T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; + a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ + T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; + t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ + T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; + t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ + T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; + t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ + T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; + t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ + T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; + t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ + T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; + a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ + T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; + a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ + T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; + a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ + T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; + t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ + T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; + t0 = T5[(a0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ + T7[(a2>>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++]; + t1 = T5[(a1>>>24) ] ^ T6[(a0>>>16)&0xFF] ^ + T7[(t3>>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++]; + t2 = T5[(a2>>>24) ] ^ T6[(a1>>>16)&0xFF] ^ + T7[(a0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; + t3 = T5[(t3>>>24) ] ^ T6[(a2>>>16)&0xFF] ^ + T7[(a1>>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++]; + a0 = T5[(t0>>>24) ] ^ T6[(t3>>>16)&0xFF] ^ + T7[(t2>>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++]; + a1 = T5[(t1>>>24) ] ^ T6[(t0>>>16)&0xFF] ^ + T7[(t3>>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++]; + a2 = T5[(t2>>>24) ] ^ T6[(t1>>>16)&0xFF] ^ + T7[(t0>>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++]; + t3 = T5[(t3>>>24) ] ^ T6[(t2>>>16)&0xFF] ^ + T7[(t1>>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++]; + + t1 = K[0]; + out[outOffset++] = (byte)(Si[(a0 >>> 24) ] ^ (t1 >>> 24)); + out[outOffset++] = (byte)(Si[(t3 >>> 16) & 0xFF] ^ (t1 >>> 16)); + out[outOffset++] = (byte)(Si[(a2 >>> 8) & 0xFF] ^ (t1 >>> 8)); + out[outOffset++] = (byte)(Si[(a1 ) & 0xFF] ^ (t1 )); + t1 = K[1]; + out[outOffset++] = (byte)(Si[(a1 >>> 24) ] ^ (t1 >>> 24)); + out[outOffset++] = (byte)(Si[(a0 >>> 16) & 0xFF] ^ (t1 >>> 16)); + out[outOffset++] = (byte)(Si[(t3 >>> 8) & 0xFF] ^ (t1 >>> 8)); + out[outOffset++] = (byte)(Si[(a2 ) & 0xFF] ^ (t1 )); + t1 = K[2]; + out[outOffset++] = (byte)(Si[(a2 >>> 24) ] ^ (t1 >>> 24)); + out[outOffset++] = (byte)(Si[(a1 >>> 16) & 0xFF] ^ (t1 >>> 16)); + out[outOffset++] = (byte)(Si[(a0 >>> 8) & 0xFF] ^ (t1 >>> 8)); + out[outOffset++] = (byte)(Si[(t3 ) & 0xFF] ^ (t1 )); + t1 = K[3]; + out[outOffset++] = (byte)(Si[(t3 >>> 24) ] ^ (t1 >>> 24)); + out[outOffset++] = (byte)(Si[(a2 >>> 16) & 0xFF] ^ (t1 >>> 16)); + out[outOffset++] = (byte)(Si[(a1 >>> 8) & 0xFF] ^ (t1 >>> 8)); + out[outOffset ] = (byte)(Si[(a0 ) & 0xFF] ^ (t1 )); + } + + + /** + * Expand a user-supplied key material into a session key. + * + * @param key The 128/192/256-bit user-key to use. + * @exception InvalidKeyException If the key is invalid. + */ + private static Object[] makeKey(byte[] k) throws InvalidKeyException { + if (k == null) { + throw new InvalidKeyException("Empty key"); + } + if (!isKeySizeValid(k.length)) { + throw new InvalidKeyException("Invalid AES key length: " + + k.length + " bytes"); + } + int ROUNDS = getRounds(k.length); + int ROUND_KEY_COUNT = (ROUNDS + 1) * 4; + + int BC = 4; + int[][] Ke = new int[ROUNDS + 1][4]; // encryption round keys + int[][] Kd = new int[ROUNDS + 1][4]; // decryption round keys + + int KC = k.length/4; // keylen in 32-bit elements + + int[] tk = new int[KC]; + int i, j; + + // copy user material bytes into temporary ints + for (i = 0, j = 0; i < KC; i++, j+=4) { + tk[i] = (k[j] ) << 24 | + (k[j+1] & 0xFF) << 16 | + (k[j+2] & 0xFF) << 8 | + (k[j+3] & 0xFF); + } + + // copy values into round key arrays + int t = 0; + for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++) { + Ke[t / 4][t % 4] = tk[j]; + Kd[ROUNDS - (t / 4)][t % 4] = tk[j]; + } + int tt, rconpointer = 0; + while (t < ROUND_KEY_COUNT) { + // extrapolate using phi (the round key evolution function) + tt = tk[KC - 1]; + tk[0] ^= (S[(tt >>> 16) & 0xFF] ) << 24 ^ + (S[(tt >>> 8) & 0xFF] & 0xFF) << 16 ^ + (S[(tt ) & 0xFF] & 0xFF) << 8 ^ + (S[(tt >>> 24) ] & 0xFF) ^ + (rcon[rconpointer++] ) << 24; + if (KC != 8) + for (i = 1, j = 0; i < KC; i++, j++) tk[i] ^= tk[j]; + else { + for (i = 1, j = 0; i < KC / 2; i++, j++) tk[i] ^= tk[j]; + tt = tk[KC / 2 - 1]; + tk[KC / 2] ^= (S[(tt ) & 0xFF] & 0xFF) ^ + (S[(tt >>> 8) & 0xFF] & 0xFF) << 8 ^ + (S[(tt >>> 16) & 0xFF] & 0xFF) << 16 ^ + (S[(tt >>> 24) ] ) << 24; + for (j = KC / 2, i = j + 1; i < KC; i++, j++) tk[i] ^= tk[j]; + } + // copy values into round key arrays + for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++) { + Ke[t / 4][t % 4] = tk[j]; + Kd[ROUNDS - (t / 4)][t % 4] = tk[j]; + } + } + for (int r = 1; r < ROUNDS; r++) { + // inverse MixColumn where needed + for (j = 0; j < BC; j++) { + tt = Kd[r][j]; + Kd[r][j] = U1[(tt >>> 24) & 0xFF] ^ + U2[(tt >>> 16) & 0xFF] ^ + U3[(tt >>> 8) & 0xFF] ^ + U4[ tt & 0xFF]; + } + } + // assemble the encryption (Ke) and decryption (Kd) round keys into + // one sessionKey object + Object[] result = new Object[] {Ke, Kd}; + return result; + } + + + /** + * Return The number of rounds for a given Rijndael keysize. + * + * @param keySize The size of the user key material in bytes. + * MUST be one of (16, 24, 32). + * @return The number of rounds. + */ + private static int getRounds(int keySize) { + return (keySize >> 2) + 6; + } +} Added: trunk/core/src/openjdk/com/com/sun/crypto/provider/AESKeyGenerator.java =================================================================== --- trunk/core/src/openjdk/com/com/sun/crypto/provider/AESKeyGenerator.java (rev 0) +++ trunk/core/src/openjdk/com/com/sun/crypto/provider/AESKeyGenerator.java 2009-02-14 20:29:54 UTC (rev 5025) @@ -0,0 +1,124 @@ +/* + * Copyright 2002-2007 Sun Microsystems, Inc. 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package com.sun.crypto.provider; + +import java.security.SecureRandom; +import java.security.InvalidParameterException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.spec.AlgorithmParameterSpec; +import javax.crypto.KeyGeneratorSpi; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + + +/** + * This class generates a AES key. + * + * @author Valerie Peng + * + */ + +public final class AESKeyGenerator extends KeyGeneratorSpi { + + private SecureRandom random = null; + private int keySize = 16; // default keysize (in number of bytes) + + /** + * Verify the SunJCE provider in the constructor. + * + * @exception SecurityException if fails to verify + * its own integrity + */ + public AESKeyGenerator() { + if (!SunJCE.verifySelfIntegrity(this.getClass())) { + throw new SecurityException("The SunJCE provider may have " + + "been tampered."); + } + } + + /** + * Initializes this key generator. + * + * @param random the source of randomness for this generator + */ + protected void engineInit(SecureRandom random) { + this.random = random; + } + + /** + * Initializes this key generator with the specified parameter + * set and a user-provided source of randomness. + * + * @param params the key generation parameters + * @... [truncated message content] |