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 }