001 /*
002 * Cumulus4j - Securing your data in the cloud - http://cumulus4j.org
003 * Copyright (C) 2011 NightLabs Consulting GmbH
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program. If not, see <http://www.gnu.org/licenses/>.
017 */
018 package org.cumulus4j.crypto.internal.symmetric;
019
020 import org.bouncycastle.crypto.CipherParameters;
021 import org.bouncycastle.crypto.CryptoException;
022 import org.bouncycastle.crypto.DataLengthException;
023 import org.bouncycastle.crypto.StreamCipher;
024 import org.bouncycastle.crypto.engines.Grain128Engine;
025 import org.bouncycastle.crypto.engines.Grainv1Engine;
026 import org.bouncycastle.crypto.engines.HC128Engine;
027 import org.bouncycastle.crypto.engines.HC256Engine;
028 import org.bouncycastle.crypto.engines.ISAACEngine;
029 import org.bouncycastle.crypto.engines.RC4Engine;
030 import org.bouncycastle.crypto.engines.Salsa20Engine;
031 import org.cumulus4j.crypto.AbstractCipher;
032 import org.cumulus4j.crypto.CipherOperationMode;
033
034 /**
035 * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de
036 */
037 public class StreamCipherImpl
038 extends AbstractCipher
039 {
040 private StreamCipher delegate;
041
042 public StreamCipherImpl(String transformation, StreamCipher delegate) {
043 super(transformation);
044 this.delegate = delegate;
045 }
046
047 @Override
048 public void _init(CipherOperationMode mode, CipherParameters parameters)
049 throws IllegalArgumentException
050 {
051 delegate.init(CipherOperationMode.ENCRYPT == mode, parameters);
052 }
053
054 @Override
055 public void reset() {
056 delegate.reset();
057 }
058
059 @Override
060 public int getInputBlockSize() {
061 return 1;
062 }
063
064 @Override
065 public int getOutputBlockSize() {
066 return 1;
067 }
068
069 @Override
070 public int getUpdateOutputSize(int length) {
071 return length;
072 }
073
074 @Override
075 public int getOutputSize(int length) {
076 return length;
077 }
078
079 @Override
080 public int update(byte in, byte[] out, int outOff)
081 throws DataLengthException, IllegalStateException, CryptoException
082 {
083 out[outOff] = delegate.returnByte(in);
084 return 1;
085 }
086
087 @Override
088 public int update(byte[] in, int inOff, int inLen, byte[] out, int outOff)
089 throws DataLengthException, IllegalStateException, CryptoException
090 {
091 delegate.processBytes(in, inOff, inLen, out, outOff);
092 return inLen;
093 }
094
095 @Override
096 public int doFinal(byte[] out, int outOff)
097 throws DataLengthException, IllegalStateException, CryptoException
098 {
099 return 0;
100 }
101
102 private int ivSize = -1;
103
104 @Override
105 public int getIVSize()
106 {
107 if (ivSize < 0) {
108 if (delegate instanceof Grainv1Engine)
109 ivSize = 8;
110 else if (delegate instanceof Grain128Engine)
111 ivSize = 12;
112 else if (delegate instanceof HC128Engine)
113 ivSize = 16;
114 else if (delegate instanceof HC256Engine)
115 ivSize = 32;
116 else if (delegate instanceof ISAACEngine)
117 ivSize = 0;
118 else if (delegate instanceof RC4Engine)
119 ivSize = 0;
120 else if (delegate instanceof Salsa20Engine)
121 ivSize = 8;
122 else
123 throw new UnsupportedOperationException("For this delegate cipher type, this operation is not yet supported!");
124 }
125 return ivSize;
126 }
127
128 // @Override
129 // public AsymmetricCipherKeyPairGenerator createKeyPairGenerator(boolean initWithDefaults)
130 // throws UnsupportedOperationException
131 // {
132 // throw new UnsupportedOperationException("This is a SYMMETRIC cipher! Cannot get an appropriate key pair generator!");
133 // }
134 //
135 // @Override
136 // public SecretKeyGenerator createSecretKeyGenerator(boolean initWithDefaults)
137 // {
138 // String algorithmName = CryptoRegistry.splitTransformation(getTransformation())[0];
139 // try {
140 // return CryptoRegistry.sharedInstance().createSecretKeyGenerator(algorithmName, initWithDefaults);
141 // } catch (NoSuchAlgorithmException e) {
142 // throw new RuntimeException(e); // We should be able to provide an SecretKeyGenerator for every Cipher => RuntimeException
143 // }
144 // }
145 }