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 }