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.BlockCipher;
021 import org.bouncycastle.crypto.CipherParameters;
022 import org.bouncycastle.crypto.CryptoException;
023 import org.bouncycastle.crypto.DataLengthException;
024 import org.bouncycastle.crypto.modes.AEADBlockCipher;
025 import org.bouncycastle.crypto.modes.CCMBlockCipher;
026 import org.bouncycastle.crypto.modes.CFBBlockCipher;
027 import org.bouncycastle.crypto.modes.OFBBlockCipher;
028 import org.cumulus4j.crypto.AbstractCipher;
029 import org.cumulus4j.crypto.CipherOperationMode;
030
031 /**
032 * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de
033 */
034 public class AEADBlockCipherImpl extends AbstractCipher
035 {
036 private AEADBlockCipher delegate;
037
038 public AEADBlockCipherImpl(String transformation, AEADBlockCipher delegate) {
039 super(transformation);
040 this.delegate = delegate;
041 }
042
043 @Override
044 public void reset() {
045 delegate.reset();
046 }
047
048 @Override
049 public int getInputBlockSize() {
050 return delegate.getUnderlyingCipher().getBlockSize();
051 }
052
053 @Override
054 public int getOutputBlockSize() {
055 return delegate.getUnderlyingCipher().getBlockSize();
056 }
057
058 @Override
059 public int getUpdateOutputSize(int length) {
060 return delegate.getUpdateOutputSize(length);
061 }
062
063 @Override
064 public int getOutputSize(int length) {
065 return delegate.getOutputSize(length);
066 }
067
068 @Override
069 public int update(byte in, byte[] out, int outOff)
070 throws DataLengthException, IllegalStateException, CryptoException
071 {
072 return delegate.processByte(in, out, outOff);
073 }
074
075 @Override
076 public int update(byte[] in, int inOff, int inLen, byte[] out, int outOff)
077 throws DataLengthException, IllegalStateException, CryptoException
078 {
079 return delegate.processBytes(in, inOff, inLen, out, outOff);
080 }
081
082 @Override
083 public int doFinal(byte[] out, int outOff)
084 throws DataLengthException, IllegalStateException, CryptoException
085 {
086 return delegate.doFinal(out, outOff);
087 }
088
089 private int ivSize = -1;
090
091 @Override
092 public int getIVSize()
093 {
094 int ivSize = this.ivSize;
095 if (ivSize < 0) {
096 BlockCipher underlyingCipher = delegate.getUnderlyingCipher();
097
098 if (underlyingCipher instanceof CFBBlockCipher)
099 ivSize = ((CFBBlockCipher)underlyingCipher).getUnderlyingCipher().getBlockSize();
100 else if (underlyingCipher instanceof OFBBlockCipher)
101 ivSize = ((OFBBlockCipher)underlyingCipher).getUnderlyingCipher().getBlockSize();
102 else
103 ivSize = underlyingCipher.getBlockSize();
104
105 if (delegate instanceof CCMBlockCipher)
106 --ivSize;
107
108 this.ivSize = ivSize;
109 }
110
111 return ivSize;
112 }
113
114 @Override
115 protected void _init(CipherOperationMode mode, CipherParameters parameters)
116 throws IllegalArgumentException
117 {
118 delegate.init(CipherOperationMode.ENCRYPT == mode, parameters);
119 }
120
121 // @Override
122 // public AsymmetricCipherKeyPairGenerator createKeyPairGenerator(boolean initWithDefaults)
123 // throws UnsupportedOperationException
124 // {
125 // throw new UnsupportedOperationException("This is a SYMMETRIC cipher! Cannot get an appropriate key pair generator!");
126 // }
127 //
128 // @Override
129 // public SecretKeyGenerator createSecretKeyGenerator(boolean initWithDefaults)
130 // {
131 // String algorithmName = CryptoRegistry.splitTransformation(getTransformation())[0];
132 // try {
133 // return CryptoRegistry.sharedInstance().createSecretKeyGenerator(algorithmName, initWithDefaults);
134 // } catch (NoSuchAlgorithmException e) {
135 // throw new RuntimeException(e); // We should be able to provide an SecretKeyGenerator for every Cipher => RuntimeException
136 // }
137 // }
138 }