0001: package org.bouncycastle.jce.provider;
0002:
0003: import org.bouncycastle.crypto.BlockCipher;
0004: import org.bouncycastle.crypto.BufferedBlockCipher;
0005: import org.bouncycastle.crypto.CipherParameters;
0006: import org.bouncycastle.crypto.DataLengthException;
0007: import org.bouncycastle.crypto.InvalidCipherTextException;
0008: import org.bouncycastle.crypto.engines.AESFastEngine;
0009: import org.bouncycastle.crypto.engines.BlowfishEngine;
0010: import org.bouncycastle.crypto.engines.CAST5Engine;
0011: import org.bouncycastle.crypto.engines.CAST6Engine;
0012: import org.bouncycastle.crypto.engines.DESEngine;
0013: import org.bouncycastle.crypto.engines.DESedeEngine;
0014: import org.bouncycastle.crypto.engines.GOST28147Engine;
0015: import org.bouncycastle.crypto.engines.IDEAEngine;
0016: import org.bouncycastle.crypto.engines.RC2Engine;
0017: import org.bouncycastle.crypto.engines.RC532Engine;
0018: import org.bouncycastle.crypto.engines.RC564Engine;
0019: import org.bouncycastle.crypto.engines.RC6Engine;
0020: import org.bouncycastle.crypto.engines.RijndaelEngine;
0021: import org.bouncycastle.crypto.engines.SEEDEngine;
0022: import org.bouncycastle.crypto.engines.SerpentEngine;
0023: import org.bouncycastle.crypto.engines.SkipjackEngine;
0024: import org.bouncycastle.crypto.engines.TEAEngine;
0025: import org.bouncycastle.crypto.engines.TwofishEngine;
0026: import org.bouncycastle.crypto.engines.XTEAEngine;
0027: import org.bouncycastle.crypto.modes.AEADBlockCipher;
0028: import org.bouncycastle.crypto.modes.CBCBlockCipher;
0029: import org.bouncycastle.crypto.modes.CCMBlockCipher;
0030: import org.bouncycastle.crypto.modes.CFBBlockCipher;
0031: import org.bouncycastle.crypto.modes.CTSBlockCipher;
0032: import org.bouncycastle.crypto.modes.EAXBlockCipher;
0033: import org.bouncycastle.crypto.modes.GOFBBlockCipher;
0034: import org.bouncycastle.crypto.modes.OFBBlockCipher;
0035: import org.bouncycastle.crypto.modes.OpenPGPCFBBlockCipher;
0036: import org.bouncycastle.crypto.modes.PGPCFBBlockCipher;
0037: import org.bouncycastle.crypto.modes.SICBlockCipher;
0038: import org.bouncycastle.crypto.paddings.BlockCipherPadding;
0039: import org.bouncycastle.crypto.paddings.ISO10126d2Padding;
0040: import org.bouncycastle.crypto.paddings.ISO7816d4Padding;
0041: import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
0042: import org.bouncycastle.crypto.paddings.TBCPadding;
0043: import org.bouncycastle.crypto.paddings.X923Padding;
0044: import org.bouncycastle.crypto.paddings.ZeroBytePadding;
0045: import org.bouncycastle.crypto.params.KeyParameter;
0046: import org.bouncycastle.crypto.params.ParametersWithIV;
0047: import org.bouncycastle.crypto.params.ParametersWithRandom;
0048: import org.bouncycastle.crypto.params.ParametersWithSBox;
0049: import org.bouncycastle.crypto.params.RC2Parameters;
0050: import org.bouncycastle.crypto.params.RC5Parameters;
0051: import org.bouncycastle.jce.spec.GOST28147ParameterSpec;
0052: import org.bouncycastle.util.Strings;
0053:
0054: import javax.crypto.BadPaddingException;
0055: import javax.crypto.Cipher;
0056: import javax.crypto.IllegalBlockSizeException;
0057: import javax.crypto.NoSuchPaddingException;
0058: import javax.crypto.SecretKey;
0059: import javax.crypto.ShortBufferException;
0060: import javax.crypto.spec.IvParameterSpec;
0061: import javax.crypto.spec.PBEParameterSpec;
0062: import javax.crypto.spec.RC2ParameterSpec;
0063: import javax.crypto.spec.RC5ParameterSpec;
0064: import java.security.AlgorithmParameters;
0065: import java.security.InvalidAlgorithmParameterException;
0066: import java.security.InvalidKeyException;
0067: import java.security.InvalidParameterException;
0068: import java.security.Key;
0069: import java.security.NoSuchAlgorithmException;
0070: import java.security.SecureRandom;
0071: import java.security.spec.AlgorithmParameterSpec;
0072:
0073: public class JCEBlockCipher extends WrapCipherSpi implements PBE {
0074: //
0075: // specs we can handle.
0076: //
0077: private Class[] availableSpecs = { RC2ParameterSpec.class,
0078: RC5ParameterSpec.class, IvParameterSpec.class,
0079: PBEParameterSpec.class, GOST28147ParameterSpec.class };
0080:
0081: private BlockCipher baseEngine;
0082: private GenericBlockCipher cipher;
0083: private ParametersWithIV ivParam;
0084:
0085: private int ivLength = 0;
0086:
0087: private boolean padded = true;
0088:
0089: private PBEParameterSpec pbeSpec = null;
0090: private String pbeAlgorithm = null;
0091:
0092: private String modeName = null;
0093:
0094: protected JCEBlockCipher(BlockCipher engine) {
0095: baseEngine = engine;
0096:
0097: cipher = new BufferedGenericBlockCipher(engine);
0098: }
0099:
0100: protected JCEBlockCipher(BlockCipher engine, int ivLength) {
0101: baseEngine = engine;
0102:
0103: this .cipher = new BufferedGenericBlockCipher(engine);
0104: this .ivLength = ivLength / 8;
0105: }
0106:
0107: protected int engineGetBlockSize() {
0108: return baseEngine.getBlockSize();
0109: }
0110:
0111: protected byte[] engineGetIV() {
0112: return (ivParam != null) ? ivParam.getIV() : null;
0113: }
0114:
0115: protected int engineGetKeySize(Key key) {
0116: return key.getEncoded().length * 8;
0117: }
0118:
0119: protected int engineGetOutputSize(int inputLen) {
0120: return cipher.getOutputSize(inputLen);
0121: }
0122:
0123: protected AlgorithmParameters engineGetParameters() {
0124: if (engineParams == null) {
0125: if (pbeSpec != null) {
0126: try {
0127: engineParams = AlgorithmParameters.getInstance(
0128: pbeAlgorithm, "BC");
0129: engineParams.init(pbeSpec);
0130: } catch (Exception e) {
0131: return null;
0132: }
0133: } else if (ivParam != null) {
0134: String name = cipher.getUnderlyingCipher()
0135: .getAlgorithmName();
0136:
0137: if (name.indexOf('/') >= 0) {
0138: name = name.substring(0, name.indexOf('/'));
0139: }
0140:
0141: try {
0142: engineParams = AlgorithmParameters.getInstance(
0143: name, "BC");
0144: engineParams.init(ivParam.getIV());
0145: } catch (Exception e) {
0146: throw new RuntimeException(e.toString());
0147: }
0148: }
0149: }
0150:
0151: return engineParams;
0152: }
0153:
0154: protected void engineSetMode(String mode)
0155: throws NoSuchAlgorithmException {
0156: modeName = Strings.toUpperCase(mode);
0157:
0158: if (modeName.equals("ECB")) {
0159: ivLength = 0;
0160: cipher = new BufferedGenericBlockCipher(baseEngine);
0161: } else if (modeName.equals("CBC")) {
0162: ivLength = baseEngine.getBlockSize();
0163: cipher = new BufferedGenericBlockCipher(new CBCBlockCipher(
0164: baseEngine));
0165: } else if (modeName.startsWith("OFB")) {
0166: ivLength = baseEngine.getBlockSize();
0167: if (modeName.length() != 3) {
0168: int wordSize = Integer.parseInt(modeName.substring(3));
0169:
0170: cipher = new BufferedGenericBlockCipher(
0171: new OFBBlockCipher(baseEngine, wordSize));
0172: } else {
0173: cipher = new BufferedGenericBlockCipher(
0174: new OFBBlockCipher(baseEngine, 8 * baseEngine
0175: .getBlockSize()));
0176: }
0177: } else if (modeName.startsWith("CFB")) {
0178: ivLength = baseEngine.getBlockSize();
0179: if (modeName.length() != 3) {
0180: int wordSize = Integer.parseInt(modeName.substring(3));
0181:
0182: cipher = new BufferedGenericBlockCipher(
0183: new CFBBlockCipher(baseEngine, wordSize));
0184: } else {
0185: cipher = new BufferedGenericBlockCipher(
0186: new CFBBlockCipher(baseEngine, 8 * baseEngine
0187: .getBlockSize()));
0188: }
0189: } else if (modeName.startsWith("PGP")) {
0190: if (modeName.equalsIgnoreCase("PGPCFBwithIV")) {
0191: ivLength = baseEngine.getBlockSize();
0192: cipher = new BufferedGenericBlockCipher(
0193: new PGPCFBBlockCipher(baseEngine, true));
0194: } else {
0195: ivLength = baseEngine.getBlockSize();
0196: cipher = new BufferedGenericBlockCipher(
0197: new PGPCFBBlockCipher(baseEngine, false));
0198: }
0199: } else if (modeName.equalsIgnoreCase("OpenPGPCFB")) {
0200: ivLength = 0;
0201: cipher = new BufferedGenericBlockCipher(
0202: new OpenPGPCFBBlockCipher(baseEngine));
0203: } else if (modeName.startsWith("SIC")) {
0204: ivLength = baseEngine.getBlockSize();
0205: if (ivLength < 16) {
0206: throw new IllegalArgumentException(
0207: "Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
0208: }
0209: cipher = new BufferedGenericBlockCipher(
0210: new BufferedBlockCipher(new SICBlockCipher(
0211: baseEngine)));
0212: } else if (modeName.startsWith("CTR")) {
0213: ivLength = baseEngine.getBlockSize();
0214: cipher = new BufferedGenericBlockCipher(
0215: new BufferedBlockCipher(new SICBlockCipher(
0216: baseEngine)));
0217: } else if (modeName.startsWith("GOFB")) {
0218: ivLength = baseEngine.getBlockSize();
0219: cipher = new BufferedGenericBlockCipher(
0220: new BufferedBlockCipher(new GOFBBlockCipher(
0221: baseEngine)));
0222: } else if (modeName.startsWith("CTS")) {
0223: ivLength = baseEngine.getBlockSize();
0224: cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(
0225: new CBCBlockCipher(baseEngine)));
0226: } else if (modeName.startsWith("CCM")) {
0227: ivLength = baseEngine.getBlockSize();
0228: cipher = new AEADGenericBlockCipher(new CCMBlockCipher(
0229: baseEngine));
0230: } else if (modeName.startsWith("EAX")) {
0231: ivLength = baseEngine.getBlockSize();
0232: cipher = new AEADGenericBlockCipher(new EAXBlockCipher(
0233: baseEngine));
0234: } else {
0235: throw new NoSuchAlgorithmException("can't support mode "
0236: + mode);
0237: }
0238: }
0239:
0240: protected void engineSetPadding(String padding)
0241: throws NoSuchPaddingException {
0242: String paddingName = Strings.toUpperCase(padding);
0243:
0244: if (paddingName.equals("NOPADDING")) {
0245: padded = false;
0246:
0247: if (cipher.wrapOnNoPadding()) {
0248: cipher = new BufferedGenericBlockCipher(
0249: new BufferedBlockCipher(cipher
0250: .getUnderlyingCipher()));
0251: }
0252: } else if ("CCM".equals(modeName) || "EAX".equals(modeName)) {
0253: throw new NoSuchPaddingException(
0254: "Only NoPadding can be used with AEAD modes.");
0255: } else if (paddingName.equals("PKCS5PADDING")
0256: || paddingName.equals("PKCS7PADDING")) {
0257: cipher = new BufferedGenericBlockCipher(cipher
0258: .getUnderlyingCipher());
0259: } else if (paddingName.equals("ZEROBYTEPADDING")) {
0260: cipher = new BufferedGenericBlockCipher(cipher
0261: .getUnderlyingCipher(), new ZeroBytePadding());
0262: } else if (paddingName.equals("ISO10126PADDING")
0263: || paddingName.equals("ISO10126-2PADDING")) {
0264: cipher = new BufferedGenericBlockCipher(cipher
0265: .getUnderlyingCipher(), new ISO10126d2Padding());
0266: } else if (paddingName.equals("X9.23PADDING")
0267: || paddingName.equals("X923PADDING")) {
0268: cipher = new BufferedGenericBlockCipher(cipher
0269: .getUnderlyingCipher(), new X923Padding());
0270: } else if (paddingName.equals("ISO7816-4PADDING")
0271: || paddingName.equals("ISO9797-1PADDING")) {
0272: cipher = new BufferedGenericBlockCipher(cipher
0273: .getUnderlyingCipher(), new ISO7816d4Padding());
0274: } else if (paddingName.equals("TBCPADDING")) {
0275: cipher = new BufferedGenericBlockCipher(cipher
0276: .getUnderlyingCipher(), new TBCPadding());
0277: } else if (paddingName.equals("WITHCTS")) {
0278: padded = false;
0279: cipher = new BufferedGenericBlockCipher(new CTSBlockCipher(
0280: cipher.getUnderlyingCipher()));
0281: } else {
0282: throw new NoSuchPaddingException("Padding " + padding
0283: + " unknown.");
0284: }
0285: }
0286:
0287: protected void engineInit(int opmode, Key key,
0288: AlgorithmParameterSpec params, SecureRandom random)
0289: throws InvalidKeyException,
0290: InvalidAlgorithmParameterException {
0291: CipherParameters param;
0292:
0293: this .pbeSpec = null;
0294: this .pbeAlgorithm = null;
0295: this .engineParams = null;
0296:
0297: //
0298: // basic key check
0299: //
0300: if (!(key instanceof SecretKey)) {
0301: throw new InvalidKeyException("Key for algorithm "
0302: + key.getAlgorithm()
0303: + " not suitable for symmetric enryption.");
0304: }
0305:
0306: //
0307: // for RC5-64 we must have some default parameters
0308: //
0309: if (params == null
0310: && baseEngine.getAlgorithmName().startsWith("RC5-64")) {
0311: throw new InvalidAlgorithmParameterException(
0312: "RC5 requires an RC5ParametersSpec to be passed in.");
0313: }
0314:
0315: //
0316: // a note on iv's - if ivLength is zero the IV gets ignored (we don't use it).
0317: //
0318: if (key instanceof JCEPBEKey) {
0319: JCEPBEKey k = (JCEPBEKey) key;
0320:
0321: if (k.getOID() != null) {
0322: pbeAlgorithm = k.getOID().getId();
0323: } else {
0324: pbeAlgorithm = k.getAlgorithm();
0325: }
0326:
0327: if (k.getParam() != null) {
0328: param = k.getParam();
0329: pbeSpec = new PBEParameterSpec(k.getSalt(), k
0330: .getIterationCount());
0331: } else if (params instanceof PBEParameterSpec) {
0332: pbeSpec = (PBEParameterSpec) params;
0333: param = PBE.Util.makePBEParameters(k, params, cipher
0334: .getUnderlyingCipher().getAlgorithmName());
0335: } else {
0336: throw new InvalidAlgorithmParameterException(
0337: "PBE requires PBE parameters to be set.");
0338: }
0339:
0340: if (param instanceof ParametersWithIV) {
0341: ivParam = (ParametersWithIV) param;
0342: }
0343: } else if (params == null) {
0344: param = new KeyParameter(key.getEncoded());
0345: } else if (params instanceof IvParameterSpec) {
0346: if (ivLength != 0) {
0347: IvParameterSpec p = (IvParameterSpec) params;
0348:
0349: if (p.getIV().length != ivLength
0350: && !modeName.equals("CCM")
0351: && !modeName.equals("EAX")) {
0352: throw new InvalidAlgorithmParameterException(
0353: "IV must be " + ivLength + " bytes long.");
0354: }
0355:
0356: param = new ParametersWithIV(new KeyParameter(key
0357: .getEncoded()), p.getIV());
0358: ivParam = (ParametersWithIV) param;
0359: } else {
0360: if (modeName != null && modeName.equals("ECB")) {
0361: throw new InvalidAlgorithmParameterException(
0362: "ECB mode does not use an IV");
0363: }
0364:
0365: param = new KeyParameter(key.getEncoded());
0366: }
0367: } else if (params instanceof GOST28147ParameterSpec) {
0368: GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec) params;
0369:
0370: param = new ParametersWithSBox(new KeyParameter(key
0371: .getEncoded()), ((GOST28147ParameterSpec) params)
0372: .getSbox());
0373:
0374: if (gost28147Param.getIV() != null && ivLength != 0) {
0375: param = new ParametersWithIV(param, gost28147Param
0376: .getIV());
0377: ivParam = (ParametersWithIV) param;
0378: }
0379: } else if (params instanceof RC2ParameterSpec) {
0380: RC2ParameterSpec rc2Param = (RC2ParameterSpec) params;
0381:
0382: param = new RC2Parameters(key.getEncoded(),
0383: ((RC2ParameterSpec) params).getEffectiveKeyBits());
0384:
0385: if (rc2Param.getIV() != null && ivLength != 0) {
0386: param = new ParametersWithIV(param, rc2Param.getIV());
0387: ivParam = (ParametersWithIV) param;
0388: }
0389: } else if (params instanceof RC5ParameterSpec) {
0390: RC5ParameterSpec rc5Param = (RC5ParameterSpec) params;
0391:
0392: param = new RC5Parameters(key.getEncoded(),
0393: ((RC5ParameterSpec) params).getRounds());
0394: if (baseEngine.getAlgorithmName().startsWith("RC5")) {
0395: if (baseEngine.getAlgorithmName().equals("RC5-32")) {
0396: if (rc5Param.getWordSize() != 32) {
0397: throw new InvalidAlgorithmParameterException(
0398: "RC5 already set up for a word size of 32 not "
0399: + rc5Param.getWordSize() + ".");
0400: }
0401: } else if (baseEngine.getAlgorithmName().equals(
0402: "RC5-64")) {
0403: if (rc5Param.getWordSize() != 64) {
0404: throw new InvalidAlgorithmParameterException(
0405: "RC5 already set up for a word size of 64 not "
0406: + rc5Param.getWordSize() + ".");
0407: }
0408: }
0409: } else {
0410: throw new InvalidAlgorithmParameterException(
0411: "RC5 parameters passed to a cipher that is not RC5.");
0412: }
0413: if ((rc5Param.getIV() != null) && (ivLength != 0)) {
0414: param = new ParametersWithIV(param, rc5Param.getIV());
0415: ivParam = (ParametersWithIV) param;
0416: }
0417: } else {
0418: throw new InvalidAlgorithmParameterException(
0419: "unknown parameter type.");
0420: }
0421:
0422: if ((ivLength != 0) && !(param instanceof ParametersWithIV)) {
0423: SecureRandom ivRandom = random;
0424:
0425: if (ivRandom == null) {
0426: ivRandom = new SecureRandom();
0427: }
0428:
0429: if ((opmode == Cipher.ENCRYPT_MODE)
0430: || (opmode == Cipher.WRAP_MODE)) {
0431: byte[] iv = new byte[ivLength];
0432:
0433: ivRandom.nextBytes(iv);
0434: param = new ParametersWithIV(param, iv);
0435: ivParam = (ParametersWithIV) param;
0436: } else if (cipher.getUnderlyingCipher().getAlgorithmName()
0437: .indexOf("PGPCFB") < 0) {
0438: throw new InvalidAlgorithmParameterException(
0439: "no IV set when one expected");
0440: }
0441: }
0442:
0443: if (random != null && padded) {
0444: param = new ParametersWithRandom(param, random);
0445: }
0446:
0447: try {
0448: switch (opmode) {
0449: case Cipher.ENCRYPT_MODE:
0450: case Cipher.WRAP_MODE:
0451: cipher.init(true, param);
0452: break;
0453: case Cipher.DECRYPT_MODE:
0454: case Cipher.UNWRAP_MODE:
0455: cipher.init(false, param);
0456: break;
0457: default:
0458: throw new InvalidParameterException("unknown opmode "
0459: + opmode + " passed");
0460: }
0461: } catch (Exception e) {
0462: throw new InvalidKeyException(e.getMessage());
0463: }
0464: }
0465:
0466: protected void engineInit(int opmode, Key key,
0467: AlgorithmParameters params, SecureRandom random)
0468: throws InvalidKeyException,
0469: InvalidAlgorithmParameterException {
0470: AlgorithmParameterSpec paramSpec = null;
0471:
0472: if (params != null) {
0473: for (int i = 0; i != availableSpecs.length; i++) {
0474: try {
0475: paramSpec = params
0476: .getParameterSpec(availableSpecs[i]);
0477: break;
0478: } catch (Exception e) {
0479: // try again if possible
0480: }
0481: }
0482:
0483: if (paramSpec == null) {
0484: throw new InvalidAlgorithmParameterException(
0485: "can't handle parameter " + params.toString());
0486: }
0487: }
0488:
0489: engineInit(opmode, key, paramSpec, random);
0490:
0491: engineParams = params;
0492: }
0493:
0494: protected void engineInit(int opmode, Key key, SecureRandom random)
0495: throws InvalidKeyException {
0496: try {
0497: engineInit(opmode, key, (AlgorithmParameterSpec) null,
0498: random);
0499: } catch (InvalidAlgorithmParameterException e) {
0500: throw new InvalidKeyException(e.getMessage());
0501: }
0502: }
0503:
0504: protected byte[] engineUpdate(byte[] input, int inputOffset,
0505: int inputLen) {
0506: int length = cipher.getUpdateOutputSize(inputLen);
0507:
0508: if (length > 0) {
0509: byte[] out = new byte[length];
0510:
0511: int len = cipher.processBytes(input, inputOffset, inputLen,
0512: out, 0);
0513:
0514: if (len == 0) {
0515: return null;
0516: } else if (len != out.length) {
0517: byte[] tmp = new byte[len];
0518:
0519: System.arraycopy(out, 0, tmp, 0, len);
0520:
0521: return tmp;
0522: }
0523:
0524: return out;
0525: }
0526:
0527: cipher.processBytes(input, inputOffset, inputLen, null, 0);
0528:
0529: return null;
0530: }
0531:
0532: protected int engineUpdate(byte[] input, int inputOffset,
0533: int inputLen, byte[] output, int outputOffset)
0534: throws ShortBufferException {
0535: try {
0536: return cipher.processBytes(input, inputOffset, inputLen,
0537: output, outputOffset);
0538: } catch (DataLengthException e) {
0539: throw new ShortBufferException(e.getMessage());
0540: }
0541: }
0542:
0543: protected byte[] engineDoFinal(byte[] input, int inputOffset,
0544: int inputLen) throws IllegalBlockSizeException,
0545: BadPaddingException {
0546: int len = 0;
0547: byte[] tmp = new byte[engineGetOutputSize(inputLen)];
0548:
0549: if (inputLen != 0) {
0550: len = cipher.processBytes(input, inputOffset, inputLen,
0551: tmp, 0);
0552: }
0553:
0554: try {
0555: len += cipher.doFinal(tmp, len);
0556: } catch (DataLengthException e) {
0557: throw new IllegalBlockSizeException(e.getMessage());
0558: } catch (InvalidCipherTextException e) {
0559: throw new BadPaddingException(e.getMessage());
0560: }
0561:
0562: byte[] out = new byte[len];
0563:
0564: System.arraycopy(tmp, 0, out, 0, len);
0565:
0566: return out;
0567: }
0568:
0569: protected int engineDoFinal(byte[] input, int inputOffset,
0570: int inputLen, byte[] output, int outputOffset)
0571: throws IllegalBlockSizeException, BadPaddingException {
0572: int len = 0;
0573:
0574: if (inputLen != 0) {
0575: len = cipher.processBytes(input, inputOffset, inputLen,
0576: output, outputOffset);
0577: }
0578:
0579: try {
0580: return (len + cipher.doFinal(output, outputOffset + len));
0581: } catch (DataLengthException e) {
0582: throw new IllegalBlockSizeException(e.getMessage());
0583: } catch (InvalidCipherTextException e) {
0584: throw new BadPaddingException(e.getMessage());
0585: }
0586: }
0587:
0588: /*
0589: * The ciphers that inherit from us.
0590: */
0591:
0592: /**
0593: * DES
0594: */
0595: static public class DES extends JCEBlockCipher {
0596: public DES() {
0597: super (new DESEngine());
0598: }
0599: }
0600:
0601: /**
0602: * DESCBC
0603: */
0604: static public class DESCBC extends JCEBlockCipher {
0605: public DESCBC() {
0606: super (new CBCBlockCipher(new DESEngine()), 64);
0607: }
0608: }
0609:
0610: /**
0611: * DESede
0612: */
0613: static public class DESede extends JCEBlockCipher {
0614: public DESede() {
0615: super (new DESedeEngine());
0616: }
0617: }
0618:
0619: /**
0620: * DESedeCBC
0621: */
0622: static public class DESedeCBC extends JCEBlockCipher {
0623: public DESedeCBC() {
0624: super (new CBCBlockCipher(new DESedeEngine()), 64);
0625: }
0626: }
0627:
0628: /**
0629: * GOST28147
0630: */
0631: static public class GOST28147 extends JCEBlockCipher {
0632: public GOST28147() {
0633: super (new GOST28147Engine());
0634: }
0635: }
0636:
0637: static public class GOST28147cbc extends JCEBlockCipher {
0638: public GOST28147cbc() {
0639: super (new CBCBlockCipher(new GOST28147Engine()), 64);
0640: }
0641: }
0642:
0643: /**
0644: * SKIPJACK
0645: */
0646: static public class Skipjack extends JCEBlockCipher {
0647: public Skipjack() {
0648: super (new SkipjackEngine());
0649: }
0650: }
0651:
0652: /**
0653: * Blowfish
0654: */
0655: static public class Blowfish extends JCEBlockCipher {
0656: public Blowfish() {
0657: super (new BlowfishEngine());
0658: }
0659: }
0660:
0661: /**
0662: * Twofish
0663: */
0664: static public class Twofish extends JCEBlockCipher {
0665: public Twofish() {
0666: super (new TwofishEngine());
0667: }
0668: }
0669:
0670: /**
0671: * RC2
0672: */
0673: static public class RC2 extends JCEBlockCipher {
0674: public RC2() {
0675: super (new RC2Engine());
0676: }
0677: }
0678:
0679: /**
0680: * RC2CBC
0681: */
0682: static public class RC2CBC extends JCEBlockCipher {
0683: public RC2CBC() {
0684: super (new CBCBlockCipher(new RC2Engine()), 64);
0685: }
0686: }
0687:
0688: /**
0689: * RC5
0690: */
0691: static public class RC5 extends JCEBlockCipher {
0692: public RC5() {
0693: super (new RC532Engine());
0694: }
0695: }
0696:
0697: /**
0698: * RC564
0699: */
0700: static public class RC564 extends JCEBlockCipher {
0701: public RC564() {
0702: super (new RC564Engine());
0703: }
0704: }
0705:
0706: /**
0707: * RC6
0708: */
0709: static public class RC6 extends JCEBlockCipher {
0710: public RC6() {
0711: super (new RC6Engine());
0712: }
0713: }
0714:
0715: /**
0716: * AES
0717: */
0718: static public class AES extends JCEBlockCipher {
0719: public AES() {
0720: super (new AESFastEngine());
0721: }
0722: }
0723:
0724: /**
0725: * AESCBC
0726: */
0727: static public class AESCBC extends JCEBlockCipher {
0728: public AESCBC() {
0729: super (new CBCBlockCipher(new AESFastEngine()), 128);
0730: }
0731: }
0732:
0733: /**
0734: * AESCFB
0735: */
0736: static public class AESCFB extends JCEBlockCipher {
0737: public AESCFB() {
0738: super (new CFBBlockCipher(new AESFastEngine(), 128), 128);
0739: }
0740: }
0741:
0742: /**
0743: * AESOFB
0744: */
0745: static public class AESOFB extends JCEBlockCipher {
0746: public AESOFB() {
0747: super (new OFBBlockCipher(new AESFastEngine(), 128), 128);
0748: }
0749: }
0750:
0751: /**
0752: * Rijndael
0753: */
0754: static public class Rijndael extends JCEBlockCipher {
0755: public Rijndael() {
0756: super (new RijndaelEngine());
0757: }
0758: }
0759:
0760: /**
0761: * Serpent
0762: */
0763: static public class Serpent extends JCEBlockCipher {
0764: public Serpent() {
0765: super (new SerpentEngine());
0766: }
0767: }
0768:
0769: /**
0770: * CAST5
0771: */
0772: static public class CAST5 extends JCEBlockCipher {
0773: public CAST5() {
0774: super (new CAST5Engine());
0775: }
0776: }
0777:
0778: /**
0779: * CAST5 CBC
0780: */
0781: static public class CAST5CBC extends JCEBlockCipher {
0782: public CAST5CBC() {
0783: super (new CBCBlockCipher(new CAST5Engine()), 64);
0784: }
0785: }
0786:
0787: /**
0788: * CAST6
0789: */
0790: static public class CAST6 extends JCEBlockCipher {
0791: public CAST6() {
0792: super (new CAST6Engine());
0793: }
0794: }
0795:
0796: /**
0797: * IDEA
0798: */
0799: static public class IDEA extends JCEBlockCipher {
0800: public IDEA() {
0801: super (new IDEAEngine());
0802: }
0803: }
0804:
0805: /**
0806: * TEA
0807: */
0808: static public class TEA extends JCEBlockCipher {
0809: public TEA() {
0810: super (new TEAEngine());
0811: }
0812: }
0813:
0814: /**
0815: * XTEA
0816: */
0817: static public class XTEA extends JCEBlockCipher {
0818: public XTEA() {
0819: super (new XTEAEngine());
0820: }
0821: }
0822:
0823: /**
0824: * SEED
0825: */
0826: static public class SEED extends JCEBlockCipher {
0827: public SEED() {
0828: super (new SEEDEngine());
0829: }
0830: }
0831:
0832: /**
0833: * IDEA CBC
0834: */
0835: static public class IDEACBC extends JCEBlockCipher {
0836: public IDEACBC() {
0837: super (new CBCBlockCipher(new IDEAEngine()), 64);
0838: }
0839: }
0840:
0841: /**
0842: * PBEWithMD5AndDES
0843: */
0844: static public class PBEWithMD5AndDES extends JCEBlockCipher {
0845: public PBEWithMD5AndDES() {
0846: super (new CBCBlockCipher(new DESEngine()));
0847: }
0848: }
0849:
0850: /**
0851: * PBEWithMD5AndRC2
0852: */
0853: static public class PBEWithMD5AndRC2 extends JCEBlockCipher {
0854: public PBEWithMD5AndRC2() {
0855: super (new CBCBlockCipher(new RC2Engine()));
0856: }
0857: }
0858:
0859: /**
0860: * PBEWithSHA1AndDES
0861: */
0862: static public class PBEWithSHA1AndDES extends JCEBlockCipher {
0863: public PBEWithSHA1AndDES() {
0864: super (new CBCBlockCipher(new DESEngine()));
0865: }
0866: }
0867:
0868: /**
0869: * PBEWithSHA1AndRC2
0870: */
0871: static public class PBEWithSHA1AndRC2 extends JCEBlockCipher {
0872: public PBEWithSHA1AndRC2() {
0873: super (new CBCBlockCipher(new RC2Engine()));
0874: }
0875: }
0876:
0877: /**
0878: * PBEWithSHAAnd3-KeyTripleDES-CBC
0879: */
0880: static public class PBEWithSHAAndDES3Key extends JCEBlockCipher {
0881: public PBEWithSHAAndDES3Key() {
0882: super (new CBCBlockCipher(new DESedeEngine()));
0883: }
0884: }
0885:
0886: /**
0887: * PBEWithSHAAnd2-KeyTripleDES-CBC
0888: */
0889: static public class PBEWithSHAAndDES2Key extends JCEBlockCipher {
0890: public PBEWithSHAAndDES2Key() {
0891: super (new CBCBlockCipher(new DESedeEngine()));
0892: }
0893: }
0894:
0895: /**
0896: * PBEWithSHAAnd128BitRC2-CBC
0897: */
0898: static public class PBEWithSHAAnd128BitRC2 extends JCEBlockCipher {
0899: public PBEWithSHAAnd128BitRC2() {
0900: super (new CBCBlockCipher(new RC2Engine()));
0901: }
0902: }
0903:
0904: /**
0905: * PBEWithSHAAnd40BitRC2-CBC
0906: */
0907: static public class PBEWithSHAAnd40BitRC2 extends JCEBlockCipher {
0908: public PBEWithSHAAnd40BitRC2() {
0909: super (new CBCBlockCipher(new RC2Engine()));
0910: }
0911: }
0912:
0913: /**
0914: * PBEWithSHAAndTwofish-CBC
0915: */
0916: static public class PBEWithSHAAndTwofish extends JCEBlockCipher {
0917: public PBEWithSHAAndTwofish() {
0918: super (new CBCBlockCipher(new TwofishEngine()));
0919: }
0920: }
0921:
0922: /**
0923: * PBEWithSHAAndIDEA-CBC
0924: */
0925: static public class PBEWithSHAAndIDEA extends JCEBlockCipher {
0926: public PBEWithSHAAndIDEA() {
0927: super (new CBCBlockCipher(new IDEAEngine()));
0928: }
0929: }
0930:
0931: /**
0932: * PBEWithAES-CBC
0933: */
0934: static public class PBEWithAESCBC extends JCEBlockCipher {
0935: public PBEWithAESCBC() {
0936: super (new CBCBlockCipher(new AESFastEngine()));
0937: }
0938: }
0939:
0940: static private interface GenericBlockCipher {
0941: public void init(boolean forEncryption, CipherParameters params)
0942: throws IllegalArgumentException;
0943:
0944: public boolean wrapOnNoPadding();
0945:
0946: public String getAlgorithmName();
0947:
0948: public BlockCipher getUnderlyingCipher();
0949:
0950: public int getOutputSize(int len);
0951:
0952: public int getUpdateOutputSize(int len);
0953:
0954: public int processByte(byte in, byte[] out, int outOff)
0955: throws DataLengthException;
0956:
0957: public int processBytes(byte[] in, int inOff, int len,
0958: byte[] out, int outOff) throws DataLengthException;
0959:
0960: public int doFinal(byte[] out, int outOff)
0961: throws IllegalStateException,
0962: InvalidCipherTextException;
0963: }
0964:
0965: private static class BufferedGenericBlockCipher implements
0966: GenericBlockCipher {
0967: private BufferedBlockCipher cipher;
0968:
0969: BufferedGenericBlockCipher(BufferedBlockCipher cipher) {
0970: this .cipher = cipher;
0971: }
0972:
0973: BufferedGenericBlockCipher(BlockCipher cipher) {
0974: this .cipher = new PaddedBufferedBlockCipher(cipher);
0975: }
0976:
0977: BufferedGenericBlockCipher(BlockCipher cipher,
0978: BlockCipherPadding padding) {
0979: this .cipher = new PaddedBufferedBlockCipher(cipher, padding);
0980: }
0981:
0982: public void init(boolean forEncryption, CipherParameters params)
0983: throws IllegalArgumentException {
0984: cipher.init(forEncryption, params);
0985: }
0986:
0987: public boolean wrapOnNoPadding() {
0988: return !(cipher instanceof CTSBlockCipher);
0989: }
0990:
0991: public String getAlgorithmName() {
0992: return cipher.getUnderlyingCipher().getAlgorithmName();
0993: }
0994:
0995: public BlockCipher getUnderlyingCipher() {
0996: return cipher.getUnderlyingCipher();
0997: }
0998:
0999: public int getOutputSize(int len) {
1000: return cipher.getOutputSize(len);
1001: }
1002:
1003: public int getUpdateOutputSize(int len) {
1004: return cipher.getUpdateOutputSize(len);
1005: }
1006:
1007: public int processByte(byte in, byte[] out, int outOff)
1008: throws DataLengthException {
1009: return cipher.processByte(in, out, outOff);
1010: }
1011:
1012: public int processBytes(byte[] in, int inOff, int len,
1013: byte[] out, int outOff) throws DataLengthException {
1014: return cipher.processBytes(in, inOff, len, out, outOff);
1015: }
1016:
1017: public int doFinal(byte[] out, int outOff)
1018: throws IllegalStateException,
1019: InvalidCipherTextException {
1020: return cipher.doFinal(out, outOff);
1021: }
1022: }
1023:
1024: private static class AEADGenericBlockCipher implements
1025: GenericBlockCipher {
1026: private AEADBlockCipher cipher;
1027:
1028: AEADGenericBlockCipher(AEADBlockCipher cipher) {
1029: this .cipher = cipher;
1030: }
1031:
1032: public void init(boolean forEncryption, CipherParameters params)
1033: throws IllegalArgumentException {
1034: cipher.init(forEncryption, params);
1035: }
1036:
1037: public String getAlgorithmName() {
1038: return cipher.getUnderlyingCipher().getAlgorithmName();
1039: }
1040:
1041: public boolean wrapOnNoPadding() {
1042: return false;
1043: }
1044:
1045: public BlockCipher getUnderlyingCipher() {
1046: return cipher.getUnderlyingCipher();
1047: }
1048:
1049: public int getOutputSize(int len) {
1050: return cipher.getOutputSize(len);
1051: }
1052:
1053: public int getUpdateOutputSize(int len) {
1054: return cipher.getUpdateOutputSize(len);
1055: }
1056:
1057: public int processByte(byte in, byte[] out, int outOff)
1058: throws DataLengthException {
1059: return cipher.processByte(in, out, outOff);
1060: }
1061:
1062: public int processBytes(byte[] in, int inOff, int len,
1063: byte[] out, int outOff) throws DataLengthException {
1064: return cipher.processBytes(in, inOff, len, out, outOff);
1065: }
1066:
1067: public int doFinal(byte[] out, int outOff)
1068: throws IllegalStateException,
1069: InvalidCipherTextException {
1070: return cipher.doFinal(out, outOff);
1071: }
1072: }
1073: }
|