diff options
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/crypto/modes')
14 files changed, 0 insertions, 3096 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/EAXBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/EAXBlockCipher.java deleted file mode 100644 index 209d5cd..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/EAXBlockCipher.java +++ /dev/null @@ -1,387 +0,0 @@ -package org.bouncycastle.crypto.modes; - -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.InvalidCipherTextException; -import org.bouncycastle.crypto.Mac; -import org.bouncycastle.crypto.OutputLengthException; -import org.bouncycastle.crypto.macs.CMac; -import org.bouncycastle.crypto.params.AEADParameters; -import org.bouncycastle.crypto.params.ParametersWithIV; -import org.bouncycastle.util.Arrays; - -/** - * A Two-Pass Authenticated-Encryption Scheme Optimized for Simplicity and - * Efficiency - by M. Bellare, P. Rogaway, D. Wagner. - * - * http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf - * - * EAX is an AEAD scheme based on CTR and OMAC1/CMAC, that uses a single block - * cipher to encrypt and authenticate data. It's on-line (the length of a - * message isn't needed to begin processing it), has good performances, it's - * simple and provably secure (provided the underlying block cipher is secure). - * - * Of course, this implementations is NOT thread-safe. - */ -public class EAXBlockCipher - implements AEADBlockCipher -{ - private static final byte nTAG = 0x0; - - private static final byte hTAG = 0x1; - - private static final byte cTAG = 0x2; - - private SICBlockCipher cipher; - - private boolean forEncryption; - - private int blockSize; - - private Mac mac; - - private byte[] nonceMac; - private byte[] associatedTextMac; - private byte[] macBlock; - - private int macSize; - private byte[] bufBlock; - private int bufOff; - - private boolean cipherInitialized; - private byte[] initialAssociatedText; - - /** - * Constructor that accepts an instance of a block cipher engine. - * - * @param cipher the engine to use - */ - public EAXBlockCipher(BlockCipher cipher) - { - blockSize = cipher.getBlockSize(); - mac = new CMac(cipher); - macBlock = new byte[blockSize]; - associatedTextMac = new byte[mac.getMacSize()]; - nonceMac = new byte[mac.getMacSize()]; - this.cipher = new SICBlockCipher(cipher); - } - - public String getAlgorithmName() - { - return cipher.getUnderlyingCipher().getAlgorithmName() + "/EAX"; - } - - public BlockCipher getUnderlyingCipher() - { - return cipher.getUnderlyingCipher(); - } - - public int getBlockSize() - { - return cipher.getBlockSize(); - } - - public void init(boolean forEncryption, CipherParameters params) - throws IllegalArgumentException - { - this.forEncryption = forEncryption; - - byte[] nonce; - CipherParameters keyParam; - - if (params instanceof AEADParameters) - { - AEADParameters param = (AEADParameters)params; - - nonce = param.getNonce(); - initialAssociatedText = param.getAssociatedText(); - macSize = param.getMacSize() / 8; - keyParam = param.getKey(); - } - else if (params instanceof ParametersWithIV) - { - ParametersWithIV param = (ParametersWithIV)params; - - nonce = param.getIV(); - initialAssociatedText = null; - macSize = mac.getMacSize() / 2; - keyParam = param.getParameters(); - } - else - { - throw new IllegalArgumentException("invalid parameters passed to EAX"); - } - - bufBlock = new byte[forEncryption ? blockSize : (blockSize + macSize)]; - - byte[] tag = new byte[blockSize]; - - // Key reuse implemented in CBC mode of underlying CMac - mac.init(keyParam); - - tag[blockSize - 1] = nTAG; - mac.update(tag, 0, blockSize); - mac.update(nonce, 0, nonce.length); - mac.doFinal(nonceMac, 0); - - // Same BlockCipher underlies this and the mac, so reuse last key on cipher - cipher.init(true, new ParametersWithIV(null, nonceMac)); - - reset(); - } - - private void initCipher() - { - if (cipherInitialized) - { - return; - } - - cipherInitialized = true; - - mac.doFinal(associatedTextMac, 0); - - byte[] tag = new byte[blockSize]; - tag[blockSize - 1] = cTAG; - mac.update(tag, 0, blockSize); - } - - private void calculateMac() - { - byte[] outC = new byte[blockSize]; - mac.doFinal(outC, 0); - - for (int i = 0; i < macBlock.length; i++) - { - macBlock[i] = (byte)(nonceMac[i] ^ associatedTextMac[i] ^ outC[i]); - } - } - - public void reset() - { - reset(true); - } - - private void reset( - boolean clearMac) - { - cipher.reset(); // TODO Redundant since the mac will reset it? - mac.reset(); - - bufOff = 0; - Arrays.fill(bufBlock, (byte)0); - - if (clearMac) - { - Arrays.fill(macBlock, (byte)0); - } - - byte[] tag = new byte[blockSize]; - tag[blockSize - 1] = hTAG; - mac.update(tag, 0, blockSize); - - cipherInitialized = false; - - if (initialAssociatedText != null) - { - processAADBytes(initialAssociatedText, 0, initialAssociatedText.length); - } - } - - public void processAADByte(byte in) - { - if (cipherInitialized) - { - throw new IllegalStateException("AAD data cannot be added after encryption/decription processing has begun."); - } - mac.update(in); - } - - public void processAADBytes(byte[] in, int inOff, int len) - { - if (cipherInitialized) - { - throw new IllegalStateException("AAD data cannot be added after encryption/decryption processing has begun."); - } - mac.update(in, inOff, len); - } - - public int processByte(byte in, byte[] out, int outOff) - throws DataLengthException - { - initCipher(); - - return process(in, out, outOff); - } - - public int processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) - throws DataLengthException - { - initCipher(); - - if (in.length < (inOff + len)) - { - throw new DataLengthException("Input buffer too short"); - } - - int resultLen = 0; - - for (int i = 0; i != len; i++) - { - resultLen += process(in[inOff + i], out, outOff + resultLen); - } - - return resultLen; - } - - public int doFinal(byte[] out, int outOff) - throws IllegalStateException, InvalidCipherTextException - { - initCipher(); - - int extra = bufOff; - byte[] tmp = new byte[bufBlock.length]; - - bufOff = 0; - - if (forEncryption) - { - if (out.length < (outOff + extra + macSize)) - { - throw new OutputLengthException("Output buffer too short"); - } - cipher.processBlock(bufBlock, 0, tmp, 0); - - System.arraycopy(tmp, 0, out, outOff, extra); - - mac.update(tmp, 0, extra); - - calculateMac(); - - System.arraycopy(macBlock, 0, out, outOff + extra, macSize); - - reset(false); - - return extra + macSize; - } - else - { - if (out.length < (outOff + extra - macSize)) - { - throw new OutputLengthException("Output buffer too short"); - } - if (extra < macSize) - { - throw new InvalidCipherTextException("data too short"); - } - if (extra > macSize) - { - mac.update(bufBlock, 0, extra - macSize); - - cipher.processBlock(bufBlock, 0, tmp, 0); - - System.arraycopy(tmp, 0, out, outOff, extra - macSize); - } - - calculateMac(); - - if (!verifyMac(bufBlock, extra - macSize)) - { - throw new InvalidCipherTextException("mac check in EAX failed"); - } - - reset(false); - - return extra - macSize; - } - } - - public byte[] getMac() - { - byte[] mac = new byte[macSize]; - - System.arraycopy(macBlock, 0, mac, 0, macSize); - - return mac; - } - - public int getUpdateOutputSize(int len) - { - int totalData = len + bufOff; - if (!forEncryption) - { - if (totalData < macSize) - { - return 0; - } - totalData -= macSize; - } - return totalData - totalData % blockSize; - } - - public int getOutputSize(int len) - { - int totalData = len + bufOff; - - if (forEncryption) - { - return totalData + macSize; - } - - return totalData < macSize ? 0 : totalData - macSize; - } - - private int process(byte b, byte[] out, int outOff) - { - bufBlock[bufOff++] = b; - - if (bufOff == bufBlock.length) - { - if (out.length < (outOff + blockSize)) - { - throw new OutputLengthException("Output buffer is too short"); - } - // TODO Could move the processByte(s) calls to here -// initCipher(); - - int size; - - if (forEncryption) - { - size = cipher.processBlock(bufBlock, 0, out, outOff); - - mac.update(out, outOff, blockSize); - } - else - { - mac.update(bufBlock, 0, blockSize); - - size = cipher.processBlock(bufBlock, 0, out, outOff); - } - - bufOff = 0; - if (!forEncryption) - { - System.arraycopy(bufBlock, blockSize, bufBlock, 0, macSize); - bufOff = macSize; - } - - return size; - } - - return 0; - } - - private boolean verifyMac(byte[] mac, int off) - { - int nonEqual = 0; - - for (int i = 0; i < macSize; i++) - { - nonEqual |= (macBlock[i] ^ mac[off + i]); - } - - return nonEqual == 0; - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCFBBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCFBBlockCipher.java deleted file mode 100644 index 5791e89..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCFBBlockCipher.java +++ /dev/null @@ -1,120 +0,0 @@ -package org.bouncycastle.crypto.modes; - -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.StreamBlockCipher; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.crypto.params.ParametersWithIV; -import org.bouncycastle.crypto.params.ParametersWithRandom; -import org.bouncycastle.crypto.params.ParametersWithSBox; - -/** - * An implementation of the GOST CFB mode with CryptoPro key meshing as described in RFC 4357. - */ -public class GCFBBlockCipher - extends StreamBlockCipher -{ - private static final byte[] C = - { - 0x69, 0x00, 0x72, 0x22, 0x64, (byte)0xC9, 0x04, 0x23, - (byte)0x8D, 0x3A, (byte)0xDB, (byte)0x96, 0x46, (byte)0xE9, 0x2A, (byte)0xC4, - 0x18, (byte)0xFE, (byte)0xAC, (byte)0x94, 0x00, (byte)0xED, 0x07, 0x12, - (byte)0xC0, (byte)0x86, (byte)0xDC, (byte)0xC2, (byte)0xEF, 0x4C, (byte)0xA9, 0x2B - }; - - private final CFBBlockCipher cfbEngine; - - private KeyParameter key; - private long counter = 0; - private boolean forEncryption; - - public GCFBBlockCipher(BlockCipher engine) - { - super(engine); - - this.cfbEngine = new CFBBlockCipher(engine, engine.getBlockSize() * 8); - } - - public void init(boolean forEncryption, CipherParameters params) - throws IllegalArgumentException - { - counter = 0; - cfbEngine.init(forEncryption, params); - - this.forEncryption = forEncryption; - - if (params instanceof ParametersWithIV) - { - params = ((ParametersWithIV)params).getParameters(); - } - - if (params instanceof ParametersWithRandom) - { - params = ((ParametersWithRandom)params).getParameters(); - } - - if (params instanceof ParametersWithSBox) - { - params = ((ParametersWithSBox)params).getParameters(); - } - - key = (KeyParameter)params; - } - - public String getAlgorithmName() - { - String name = cfbEngine.getAlgorithmName(); - return name.substring(0, name.indexOf('/') - 1) + "/G" + name.substring(name.indexOf('/') + 1); - } - - public int getBlockSize() - { - return cfbEngine.getBlockSize(); - } - - public int processBlock(byte[] in, int inOff, byte[] out, int outOff) - throws DataLengthException, IllegalStateException - { - this.processBytes(in, inOff, cfbEngine.getBlockSize(), out, outOff); - - return cfbEngine.getBlockSize(); - } - - protected byte calculateByte(byte b) - { - if (counter > 0 && counter % 1024 == 0) - { - BlockCipher base = cfbEngine.getUnderlyingCipher(); - - base.init(false, key); - - byte[] nextKey = new byte[32]; - - base.processBlock(C, 0, nextKey, 0); - base.processBlock(C, 8, nextKey, 8); - base.processBlock(C, 16, nextKey, 16); - base.processBlock(C, 24, nextKey, 24); - - key = new KeyParameter(nextKey); - - base.init(true, key); - - byte[] iv = cfbEngine.getCurrentIV(); - - base.processBlock(iv, 0, iv, 0); - - cfbEngine.init(forEncryption, new ParametersWithIV(key, iv)); - } - - counter++; - - return cfbEngine.calculateByte(b); - } - - public void reset() - { - counter = 0; - cfbEngine.reset(); - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GOFBBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GOFBBlockCipher.java deleted file mode 100644 index b025a1b..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GOFBBlockCipher.java +++ /dev/null @@ -1,228 +0,0 @@ -package org.bouncycastle.crypto.modes; - -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.StreamBlockCipher; -import org.bouncycastle.crypto.params.ParametersWithIV; - -/** - * implements the GOST 28147 OFB counter mode (GCTR). - */ -public class GOFBBlockCipher - extends StreamBlockCipher -{ - private byte[] IV; - private byte[] ofbV; - private byte[] ofbOutV; - private int byteCount; - - private final int blockSize; - private final BlockCipher cipher; - - boolean firstStep = true; - int N3; - int N4; - static final int C1 = 16843012; //00000001000000010000000100000100 - static final int C2 = 16843009; //00000001000000010000000100000001 - - - /** - * Basic constructor. - * - * @param cipher the block cipher to be used as the basis of the - * counter mode (must have a 64 bit block size). - */ - public GOFBBlockCipher( - BlockCipher cipher) - { - super(cipher); - - this.cipher = cipher; - this.blockSize = cipher.getBlockSize(); - - if (blockSize != 8) - { - throw new IllegalArgumentException("GCTR only for 64 bit block ciphers"); - } - - this.IV = new byte[cipher.getBlockSize()]; - this.ofbV = new byte[cipher.getBlockSize()]; - this.ofbOutV = new byte[cipher.getBlockSize()]; - } - - /** - * Initialise the cipher and, possibly, the initialisation vector (IV). - * If an IV isn't passed as part of the parameter, the IV will be all zeros. - * An IV which is too short is handled in FIPS compliant fashion. - * - * @param encrypting if true the cipher is initialised for - * encryption, if false for decryption. - * @param params the key and other data required by the cipher. - * @exception IllegalArgumentException if the params argument is - * inappropriate. - */ - public void init( - boolean encrypting, //ignored by this CTR mode - CipherParameters params) - throws IllegalArgumentException - { - firstStep = true; - N3 = 0; - N4 = 0; - - if (params instanceof ParametersWithIV) - { - ParametersWithIV ivParam = (ParametersWithIV)params; - byte[] iv = ivParam.getIV(); - - if (iv.length < IV.length) - { - // prepend the supplied IV with zeros (per FIPS PUB 81) - System.arraycopy(iv, 0, IV, IV.length - iv.length, iv.length); - for (int i = 0; i < IV.length - iv.length; i++) - { - IV[i] = 0; - } - } - else - { - System.arraycopy(iv, 0, IV, 0, IV.length); - } - - reset(); - - // if params is null we reuse the current working key. - if (ivParam.getParameters() != null) - { - cipher.init(true, ivParam.getParameters()); - } - } - else - { - reset(); - - // if params is null we reuse the current working key. - if (params != null) - { - cipher.init(true, params); - } - } - } - - /** - * return the algorithm name and mode. - * - * @return the name of the underlying algorithm followed by "/GCTR" - * and the block size in bits - */ - public String getAlgorithmName() - { - return cipher.getAlgorithmName() + "/GCTR"; - } - - /** - * return the block size we are operating at (in bytes). - * - * @return the block size we are operating at (in bytes). - */ - public int getBlockSize() - { - return blockSize; - } - - /** - * Process one block of input from the array in and write it to - * the out array. - * - * @param in the array containing the input data. - * @param inOff offset into the in array the data starts at. - * @param out the array the output data will be copied into. - * @param outOff the offset into the out array the output will start at. - * @exception DataLengthException if there isn't enough data in in, or - * space in out. - * @exception IllegalStateException if the cipher isn't initialised. - * @return the number of bytes processed and produced. - */ - public int processBlock( - byte[] in, - int inOff, - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException - { - processBytes(in, inOff, blockSize, out, outOff); - - return blockSize; - } - - /** - * reset the feedback vector back to the IV and reset the underlying - * cipher. - */ - public void reset() - { - firstStep = true; - N3 = 0; - N4 = 0; - System.arraycopy(IV, 0, ofbV, 0, IV.length); - byteCount = 0; - cipher.reset(); - } - - //array of bytes to type int - private int bytesToint( - byte[] in, - int inOff) - { - return ((in[inOff + 3] << 24) & 0xff000000) + ((in[inOff + 2] << 16) & 0xff0000) + - ((in[inOff + 1] << 8) & 0xff00) + (in[inOff] & 0xff); - } - - //int to array of bytes - private void intTobytes( - int num, - byte[] out, - int outOff) - { - out[outOff + 3] = (byte)(num >>> 24); - out[outOff + 2] = (byte)(num >>> 16); - out[outOff + 1] = (byte)(num >>> 8); - out[outOff] = (byte)num; - } - - protected byte calculateByte(byte b) - { - if (byteCount == 0) - { - if (firstStep) - { - firstStep = false; - cipher.processBlock(ofbV, 0, ofbOutV, 0); - N3 = bytesToint(ofbOutV, 0); - N4 = bytesToint(ofbOutV, 4); - } - N3 += C2; - N4 += C1; - intTobytes(N3, ofbV, 0); - intTobytes(N4, ofbV, 4); - - cipher.processBlock(ofbV, 0, ofbOutV, 0); - } - - byte rv = (byte)(ofbOutV[byteCount++] ^ b); - - if (byteCount == blockSize) - { - byteCount = 0; - - // - // change over the input block. - // - System.arraycopy(ofbV, blockSize, ofbV, 0, ofbV.length - blockSize); - System.arraycopy(ofbOutV, 0, ofbV, ofbV.length - blockSize, blockSize); - } - - return rv; - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/NISTCTSBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/NISTCTSBlockCipher.java deleted file mode 100644 index fe7bf97..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/NISTCTSBlockCipher.java +++ /dev/null @@ -1,337 +0,0 @@ -/** - * A Cipher Text Stealing (CTS) mode cipher. CTS allows block ciphers to - * be used to produce cipher text which is the same length as the plain text. - */ -package org.bouncycastle.crypto.modes; - -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.BufferedBlockCipher; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.InvalidCipherTextException; -import org.bouncycastle.crypto.StreamBlockCipher; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.encoders.Hex; - -/** - * A Cipher Text Stealing (CTS) mode cipher. CTS allows block ciphers to - * be used to produce cipher text which is the same length as the plain text. - * <p> - * This class implements the NIST version as documented in "Addendum to NIST SP 800-38A, Recommendation for Block Cipher Modes of Operation: Three Variants of Ciphertext Stealing for CBC Mode" - * </p> - */ -public class NISTCTSBlockCipher - extends BufferedBlockCipher -{ - public static final int CS1 = 1; - public static final int CS2 = 2; - public static final int CS3 = 3; - - private final int type; - private final int blockSize; - - /** - * Create a buffered block cipher that uses NIST Cipher Text Stealing - * - * @param type type of CTS mode (CS1, CS2, or CS3) - * @param cipher the underlying block cipher used to create the CBC block cipher this cipher uses.. - */ - public NISTCTSBlockCipher( - int type, - BlockCipher cipher) - { - this.type = type; - this.cipher = new CBCBlockCipher(cipher); - - blockSize = cipher.getBlockSize(); - - buf = new byte[blockSize * 2]; - bufOff = 0; - } - - /** - * return the size of the output buffer required for an update - * an input of len bytes. - * - * @param len the length of the input. - * @return the space required to accommodate a call to update - * with len bytes of input. - */ - public int getUpdateOutputSize( - int len) - { - int total = len + bufOff; - int leftOver = total % buf.length; - - if (leftOver == 0) - { - return total - buf.length; - } - - return total - leftOver; - } - - /** - * return the size of the output buffer required for an update plus a - * doFinal with an input of len bytes. - * - * @param len the length of the input. - * @return the space required to accommodate a call to update and doFinal - * with len bytes of input. - */ - public int getOutputSize( - int len) - { - return len + bufOff; - } - - /** - * process a single byte, producing an output block if necessary. - * - * @param in the input byte. - * @param out the space for any output that might be produced. - * @param outOff the offset from which the output will be copied. - * @return the number of output bytes copied to out. - * @exception org.bouncycastle.crypto.DataLengthException if there isn't enough space in out. - * @exception IllegalStateException if the cipher isn't initialised. - */ - public int processByte( - byte in, - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException - { - int resultLen = 0; - - if (bufOff == buf.length) - { - resultLen = cipher.processBlock(buf, 0, out, outOff); - System.arraycopy(buf, blockSize, buf, 0, blockSize); - - bufOff = blockSize; - } - - buf[bufOff++] = in; - - return resultLen; - } - - /** - * process an array of bytes, producing output if necessary. - * - * @param in the input byte array. - * @param inOff the offset at which the input data starts. - * @param len the number of bytes to be copied out of the input array. - * @param out the space for any output that might be produced. - * @param outOff the offset from which the output will be copied. - * @return the number of output bytes copied to out. - * @exception org.bouncycastle.crypto.DataLengthException if there isn't enough space in out. - * @exception IllegalStateException if the cipher isn't initialised. - */ - public int processBytes( - byte[] in, - int inOff, - int len, - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException - { - if (len < 0) - { - throw new IllegalArgumentException("Can't have a negative input length!"); - } - - int blockSize = getBlockSize(); - int length = getUpdateOutputSize(len); - - if (length > 0) - { - if ((outOff + length) > out.length) - { - throw new DataLengthException("output buffer too short"); - } - } - - int resultLen = 0; - int gapLen = buf.length - bufOff; - - if (len > gapLen) - { - System.arraycopy(in, inOff, buf, bufOff, gapLen); - - resultLen += cipher.processBlock(buf, 0, out, outOff); - System.arraycopy(buf, blockSize, buf, 0, blockSize); - - bufOff = blockSize; - - len -= gapLen; - inOff += gapLen; - - while (len > blockSize) - { - System.arraycopy(in, inOff, buf, bufOff, blockSize); - resultLen += cipher.processBlock(buf, 0, out, outOff + resultLen); - System.arraycopy(buf, blockSize, buf, 0, blockSize); - - len -= blockSize; - inOff += blockSize; - } - } - - System.arraycopy(in, inOff, buf, bufOff, len); - - bufOff += len; - - return resultLen; - } - - /** - * Process the last block in the buffer. - * - * @param out the array the block currently being held is copied into. - * @param outOff the offset at which the copying starts. - * @return the number of output bytes copied to out. - * @exception org.bouncycastle.crypto.DataLengthException if there is insufficient space in out for - * the output. - * @exception IllegalStateException if the underlying cipher is not - * initialised. - * @exception org.bouncycastle.crypto.InvalidCipherTextException if cipher text decrypts wrongly (in - * case the exception will never get thrown). - */ - public int doFinal( - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException, InvalidCipherTextException - { - if (bufOff + outOff > out.length) - { - throw new DataLengthException("output buffer to small in doFinal"); - } - - int blockSize = cipher.getBlockSize(); - int len = bufOff - blockSize; - byte[] block = new byte[blockSize]; - - if (forEncryption) - { - if (bufOff < blockSize) - { - throw new DataLengthException("need at least one block of input for NISTCTS"); - } - - if (bufOff > blockSize) - { - byte[] lastBlock = new byte[blockSize]; - - if (this.type == CS2 || this.type == CS3) - { - cipher.processBlock(buf, 0, block, 0); - - System.arraycopy(buf, blockSize, lastBlock, 0, len); - - cipher.processBlock(lastBlock, 0, lastBlock, 0); - - if (this.type == CS2 && len == blockSize) - { - System.arraycopy(block, 0, out, outOff, blockSize); - - System.arraycopy(lastBlock, 0, out, outOff + blockSize, len); - } - else - { - System.arraycopy(lastBlock, 0, out, outOff, blockSize); - - System.arraycopy(block, 0, out, outOff + blockSize, len); - } - } - else - { - System.arraycopy(buf, 0, block, 0, blockSize); - cipher.processBlock(block, 0, block, 0); - System.arraycopy(block, 0, out, outOff, len); - - System.arraycopy(buf, bufOff - len, lastBlock, 0, len); - cipher.processBlock(lastBlock, 0, lastBlock, 0); - System.arraycopy(lastBlock, 0, out, outOff + len, blockSize); - } - } - else - { - cipher.processBlock(buf, 0, block, 0); - - System.arraycopy(block, 0, out, outOff, blockSize); - } - } - else - { - if (bufOff < blockSize) - { - throw new DataLengthException("need at least one block of input for CTS"); - } - - byte[] lastBlock = new byte[blockSize]; - - if (bufOff > blockSize) - { - if (this.type == CS3 || (this.type == CS2 && ((buf.length - bufOff) % blockSize) != 0)) - { - if (cipher instanceof CBCBlockCipher) - { - BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher(); - - c.processBlock(buf, 0, block, 0); - } - else - { - cipher.processBlock(buf, 0, block, 0); - } - - for (int i = blockSize; i != bufOff; i++) - { - lastBlock[i - blockSize] = (byte)(block[i - blockSize] ^ buf[i]); - } - - System.arraycopy(buf, blockSize, block, 0, len); - - cipher.processBlock(block, 0, out, outOff); - System.arraycopy(lastBlock, 0, out, outOff + blockSize, len); - } - else - { - BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher(); - - c.processBlock(buf, bufOff - blockSize, lastBlock, 0); - - System.arraycopy(buf, 0, block, 0, blockSize); - - if (len != blockSize) - { - System.arraycopy(lastBlock, len, block, len, blockSize - len); - } - - cipher.processBlock(block, 0, block, 0); - - System.arraycopy(block, 0, out, outOff, blockSize); - - for (int i = 0; i != len; i++) - { - lastBlock[i] ^= buf[i]; - } - - System.arraycopy(lastBlock, 0, out, outOff + blockSize, len); - } - } - else - { - cipher.processBlock(buf, 0, block, 0); - - System.arraycopy(block, 0, out, outOff, blockSize); - } - } - - int offset = bufOff; - - reset(); - - return offset; - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/OCBBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/OCBBlockCipher.java deleted file mode 100644 index 8626391..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/OCBBlockCipher.java +++ /dev/null @@ -1,598 +0,0 @@ -package org.bouncycastle.crypto.modes; - -import java.util.Vector; - -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.InvalidCipherTextException; -import org.bouncycastle.crypto.OutputLengthException; -import org.bouncycastle.crypto.params.AEADParameters; -import org.bouncycastle.crypto.params.KeyParameter; -import org.bouncycastle.crypto.params.ParametersWithIV; -import org.bouncycastle.util.Arrays; - -/** - * An implementation of <a href="http://tools.ietf.org/html/rfc7253">RFC 7253 on The OCB - * Authenticated-Encryption Algorithm</a>, licensed per: - * <p> - * <blockquote> <a href="http://www.cs.ucdavis.edu/~rogaway/ocb/license1.pdf">License for - * Open-Source Software Implementations of OCB</a> (Jan 9, 2013) — “License 1” <br> - * Under this license, you are authorized to make, use, and distribute open-source software - * implementations of OCB. This license terminates for you if you sue someone over their open-source - * software implementation of OCB claiming that you have a patent covering their implementation. - * <p> - * This is a non-binding summary of a legal document (the link above). The parameters of the license - * are specified in the license document and that document is controlling. </blockquote> - */ -public class OCBBlockCipher - implements AEADBlockCipher -{ - private static final int BLOCK_SIZE = 16; - - private BlockCipher hashCipher; - private BlockCipher mainCipher; - - /* - * CONFIGURATION - */ - private boolean forEncryption; - private int macSize; - private byte[] initialAssociatedText; - - /* - * KEY-DEPENDENT - */ - // NOTE: elements are lazily calculated - private Vector L; - private byte[] L_Asterisk, L_Dollar; - - /* - * NONCE-DEPENDENT - */ - private byte[] KtopInput = null; - private byte[] Stretch = new byte[24]; - private byte[] OffsetMAIN_0 = new byte[16]; - - /* - * PER-ENCRYPTION/DECRYPTION - */ - private byte[] hashBlock, mainBlock; - private int hashBlockPos, mainBlockPos; - private long hashBlockCount, mainBlockCount; - private byte[] OffsetHASH; - private byte[] Sum; - private byte[] OffsetMAIN = new byte[16]; - private byte[] Checksum; - - // NOTE: The MAC value is preserved after doFinal - private byte[] macBlock; - - public OCBBlockCipher(BlockCipher hashCipher, BlockCipher mainCipher) - { - if (hashCipher == null) - { - throw new IllegalArgumentException("'hashCipher' cannot be null"); - } - if (hashCipher.getBlockSize() != BLOCK_SIZE) - { - throw new IllegalArgumentException("'hashCipher' must have a block size of " - + BLOCK_SIZE); - } - if (mainCipher == null) - { - throw new IllegalArgumentException("'mainCipher' cannot be null"); - } - if (mainCipher.getBlockSize() != BLOCK_SIZE) - { - throw new IllegalArgumentException("'mainCipher' must have a block size of " - + BLOCK_SIZE); - } - - if (!hashCipher.getAlgorithmName().equals(mainCipher.getAlgorithmName())) - { - throw new IllegalArgumentException( - "'hashCipher' and 'mainCipher' must be the same algorithm"); - } - - this.hashCipher = hashCipher; - this.mainCipher = mainCipher; - } - - public BlockCipher getUnderlyingCipher() - { - return mainCipher; - } - - public String getAlgorithmName() - { - return mainCipher.getAlgorithmName() + "/OCB"; - } - - public void init(boolean forEncryption, CipherParameters parameters) - throws IllegalArgumentException - { - boolean oldForEncryption = this.forEncryption; - this.forEncryption = forEncryption; - this.macBlock = null; - - KeyParameter keyParameter; - - byte[] N; - if (parameters instanceof AEADParameters) - { - AEADParameters aeadParameters = (AEADParameters)parameters; - - N = aeadParameters.getNonce(); - initialAssociatedText = aeadParameters.getAssociatedText(); - - int macSizeBits = aeadParameters.getMacSize(); - if (macSizeBits < 64 || macSizeBits > 128 || macSizeBits % 8 != 0) - { - throw new IllegalArgumentException("Invalid value for MAC size: " + macSizeBits); - } - - macSize = macSizeBits / 8; - keyParameter = aeadParameters.getKey(); - } - else if (parameters instanceof ParametersWithIV) - { - ParametersWithIV parametersWithIV = (ParametersWithIV)parameters; - - N = parametersWithIV.getIV(); - initialAssociatedText = null; - macSize = 16; - keyParameter = (KeyParameter)parametersWithIV.getParameters(); - } - else - { - throw new IllegalArgumentException("invalid parameters passed to OCB"); - } - - this.hashBlock = new byte[16]; - this.mainBlock = new byte[forEncryption ? BLOCK_SIZE : (BLOCK_SIZE + macSize)]; - - if (N == null) - { - N = new byte[0]; - } - - if (N.length > 15) - { - throw new IllegalArgumentException("IV must be no more than 15 bytes"); - } - - /* - * KEY-DEPENDENT INITIALISATION - */ - - if (keyParameter != null) - { - // hashCipher always used in forward mode - hashCipher.init(true, keyParameter); - mainCipher.init(forEncryption, keyParameter); - KtopInput = null; - } - else if (oldForEncryption != forEncryption) - { - throw new IllegalArgumentException("cannot change encrypting state without providing key."); - } - - this.L_Asterisk = new byte[16]; - hashCipher.processBlock(L_Asterisk, 0, L_Asterisk, 0); - - this.L_Dollar = OCB_double(L_Asterisk); - - this.L = new Vector(); - this.L.addElement(OCB_double(L_Dollar)); - - /* - * NONCE-DEPENDENT AND PER-ENCRYPTION/DECRYPTION INITIALISATION - */ - - int bottom = processNonce(N); - - int bits = bottom % 8, bytes = bottom / 8; - if (bits == 0) - { - System.arraycopy(Stretch, bytes, OffsetMAIN_0, 0, 16); - } - else - { - for (int i = 0; i < 16; ++i) - { - int b1 = Stretch[bytes] & 0xff; - int b2 = Stretch[++bytes] & 0xff; - this.OffsetMAIN_0[i] = (byte)((b1 << bits) | (b2 >>> (8 - bits))); - } - } - - this.hashBlockPos = 0; - this.mainBlockPos = 0; - - this.hashBlockCount = 0; - this.mainBlockCount = 0; - - this.OffsetHASH = new byte[16]; - this.Sum = new byte[16]; - System.arraycopy(this.OffsetMAIN_0, 0, this.OffsetMAIN, 0, 16); - this.Checksum = new byte[16]; - - if (initialAssociatedText != null) - { - processAADBytes(initialAssociatedText, 0, initialAssociatedText.length); - } - } - - protected int processNonce(byte[] N) - { - byte[] nonce = new byte[16]; - System.arraycopy(N, 0, nonce, nonce.length - N.length, N.length); - nonce[0] = (byte)(macSize << 4); - nonce[15 - N.length] |= 1; - - int bottom = nonce[15] & 0x3F; - nonce[15] &= 0xC0; - - /* - * When used with incrementing nonces, the cipher is only applied once every 64 inits. - */ - if (KtopInput == null || !Arrays.areEqual(nonce, KtopInput)) - { - byte[] Ktop = new byte[16]; - KtopInput = nonce; - hashCipher.processBlock(KtopInput, 0, Ktop, 0); - System.arraycopy(Ktop, 0, Stretch, 0, 16); - for (int i = 0; i < 8; ++i) - { - Stretch[16 + i] = (byte)(Ktop[i] ^ Ktop[i + 1]); - } - } - - return bottom; - } - - public byte[] getMac() - { - return Arrays.clone(macBlock); - } - - public int getOutputSize(int len) - { - int totalData = len + mainBlockPos; - if (forEncryption) - { - return totalData + macSize; - } - return totalData < macSize ? 0 : totalData - macSize; - } - - public int getUpdateOutputSize(int len) - { - int totalData = len + mainBlockPos; - if (!forEncryption) - { - if (totalData < macSize) - { - return 0; - } - totalData -= macSize; - } - return totalData - totalData % BLOCK_SIZE; - } - - public void processAADByte(byte input) - { - hashBlock[hashBlockPos] = input; - if (++hashBlockPos == hashBlock.length) - { - processHashBlock(); - } - } - - public void processAADBytes(byte[] input, int off, int len) - { - for (int i = 0; i < len; ++i) - { - hashBlock[hashBlockPos] = input[off + i]; - if (++hashBlockPos == hashBlock.length) - { - processHashBlock(); - } - } - } - - public int processByte(byte input, byte[] output, int outOff) - throws DataLengthException - { - mainBlock[mainBlockPos] = input; - if (++mainBlockPos == mainBlock.length) - { - processMainBlock(output, outOff); - return BLOCK_SIZE; - } - return 0; - } - - public int processBytes(byte[] input, int inOff, int len, byte[] output, int outOff) - throws DataLengthException - { - if (input.length < (inOff + len)) - { - throw new DataLengthException("Input buffer too short"); - } - int resultLen = 0; - - for (int i = 0; i < len; ++i) - { - mainBlock[mainBlockPos] = input[inOff + i]; - if (++mainBlockPos == mainBlock.length) - { - processMainBlock(output, outOff + resultLen); - resultLen += BLOCK_SIZE; - } - } - - return resultLen; - } - - public int doFinal(byte[] output, int outOff) - throws IllegalStateException, - InvalidCipherTextException - { - /* - * For decryption, get the tag from the end of the message - */ - byte[] tag = null; - if (!forEncryption) - { - if (mainBlockPos < macSize) - { - throw new InvalidCipherTextException("data too short"); - } - mainBlockPos -= macSize; - tag = new byte[macSize]; - System.arraycopy(mainBlock, mainBlockPos, tag, 0, macSize); - } - - /* - * HASH: Process any final partial block; compute final hash value - */ - if (hashBlockPos > 0) - { - OCB_extend(hashBlock, hashBlockPos); - updateHASH(L_Asterisk); - } - - /* - * OCB-ENCRYPT/OCB-DECRYPT: Process any final partial block - */ - if (mainBlockPos > 0) - { - if (forEncryption) - { - OCB_extend(mainBlock, mainBlockPos); - xor(Checksum, mainBlock); - } - - xor(OffsetMAIN, L_Asterisk); - - byte[] Pad = new byte[16]; - hashCipher.processBlock(OffsetMAIN, 0, Pad, 0); - - xor(mainBlock, Pad); - - if (output.length < (outOff + mainBlockPos)) - { - throw new OutputLengthException("Output buffer too short"); - } - System.arraycopy(mainBlock, 0, output, outOff, mainBlockPos); - - if (!forEncryption) - { - OCB_extend(mainBlock, mainBlockPos); - xor(Checksum, mainBlock); - } - } - - /* - * OCB-ENCRYPT/OCB-DECRYPT: Compute raw tag - */ - xor(Checksum, OffsetMAIN); - xor(Checksum, L_Dollar); - hashCipher.processBlock(Checksum, 0, Checksum, 0); - xor(Checksum, Sum); - - this.macBlock = new byte[macSize]; - System.arraycopy(Checksum, 0, macBlock, 0, macSize); - - /* - * Validate or append tag and reset this cipher for the next run - */ - int resultLen = mainBlockPos; - - if (forEncryption) - { - if (output.length < (outOff + resultLen + macSize)) - { - throw new OutputLengthException("Output buffer too short"); - } - // Append tag to the message - System.arraycopy(macBlock, 0, output, outOff + resultLen, macSize); - resultLen += macSize; - } - else - { - // Compare the tag from the message with the calculated one - if (!Arrays.constantTimeAreEqual(macBlock, tag)) - { - throw new InvalidCipherTextException("mac check in OCB failed"); - } - } - - reset(false); - - return resultLen; - } - - public void reset() - { - reset(true); - } - - protected void clear(byte[] bs) - { - if (bs != null) - { - Arrays.fill(bs, (byte)0); - } - } - - protected byte[] getLSub(int n) - { - while (n >= L.size()) - { - L.addElement(OCB_double((byte[])L.lastElement())); - } - return (byte[])L.elementAt(n); - } - - protected void processHashBlock() - { - /* - * HASH: Process any whole blocks - */ - updateHASH(getLSub(OCB_ntz(++hashBlockCount))); - hashBlockPos = 0; - } - - protected void processMainBlock(byte[] output, int outOff) - { - if (output.length < (outOff + BLOCK_SIZE)) - { - throw new OutputLengthException("Output buffer too short"); - } - - /* - * OCB-ENCRYPT/OCB-DECRYPT: Process any whole blocks - */ - - if (forEncryption) - { - xor(Checksum, mainBlock); - mainBlockPos = 0; - } - - xor(OffsetMAIN, getLSub(OCB_ntz(++mainBlockCount))); - - xor(mainBlock, OffsetMAIN); - mainCipher.processBlock(mainBlock, 0, mainBlock, 0); - xor(mainBlock, OffsetMAIN); - - System.arraycopy(mainBlock, 0, output, outOff, 16); - - if (!forEncryption) - { - xor(Checksum, mainBlock); - System.arraycopy(mainBlock, BLOCK_SIZE, mainBlock, 0, macSize); - mainBlockPos = macSize; - } - } - - protected void reset(boolean clearMac) - { - hashCipher.reset(); - mainCipher.reset(); - - clear(hashBlock); - clear(mainBlock); - - hashBlockPos = 0; - mainBlockPos = 0; - - hashBlockCount = 0; - mainBlockCount = 0; - - clear(OffsetHASH); - clear(Sum); - System.arraycopy(OffsetMAIN_0, 0, OffsetMAIN, 0, 16); - clear(Checksum); - - if (clearMac) - { - macBlock = null; - } - - if (initialAssociatedText != null) - { - processAADBytes(initialAssociatedText, 0, initialAssociatedText.length); - } - } - - protected void updateHASH(byte[] LSub) - { - xor(OffsetHASH, LSub); - xor(hashBlock, OffsetHASH); - hashCipher.processBlock(hashBlock, 0, hashBlock, 0); - xor(Sum, hashBlock); - } - - protected static byte[] OCB_double(byte[] block) - { - byte[] result = new byte[16]; - int carry = shiftLeft(block, result); - - /* - * NOTE: This construction is an attempt at a constant-time implementation. - */ - result[15] ^= (0x87 >>> ((1 - carry) << 3)); - - return result; - } - - protected static void OCB_extend(byte[] block, int pos) - { - block[pos] = (byte)0x80; - while (++pos < 16) - { - block[pos] = 0; - } - } - - protected static int OCB_ntz(long x) - { - if (x == 0) - { - return 64; - } - - int n = 0; - while ((x & 1L) == 0L) - { - ++n; - x >>>= 1; - } - return n; - } - - protected static int shiftLeft(byte[] block, byte[] output) - { - int i = 16; - int bit = 0; - while (--i >= 0) - { - int b = block[i] & 0xff; - output[i] = (byte)((b << 1) | bit); - bit = (b >>> 7) & 1; - } - return bit; - } - - protected static void xor(byte[] block, byte[] val) - { - for (int i = 15; i >= 0; --i) - { - block[i] ^= val[i]; - } - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/OldCTSBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/OldCTSBlockCipher.java deleted file mode 100644 index b34432a..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/OldCTSBlockCipher.java +++ /dev/null @@ -1,269 +0,0 @@ -package org.bouncycastle.crypto.modes; - -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.BufferedBlockCipher; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.InvalidCipherTextException; - -/** - * A Cipher Text Stealing (CTS) mode cipher. CTS allows block ciphers to - * be used to produce cipher text which is the same length as the plain text. - * <p> - * This version applies the CTS algorithm from one block up, rather than following the errata update issued in 2004, where CTS mode is applied - * from greater than 1 block up and the first block is processed using CBC mode. - * </p> - */ -public class OldCTSBlockCipher - extends BufferedBlockCipher -{ - private int blockSize; - - /** - * Create a buffered block cipher that uses Cipher Text Stealing - * - * @param cipher the underlying block cipher this buffering object wraps. - */ - public OldCTSBlockCipher( - BlockCipher cipher) - { - if ((cipher instanceof OFBBlockCipher) || (cipher instanceof CFBBlockCipher)) - { - throw new IllegalArgumentException("CTSBlockCipher can only accept ECB, or CBC ciphers"); - } - - this.cipher = cipher; - - blockSize = cipher.getBlockSize(); - - buf = new byte[blockSize * 2]; - bufOff = 0; - } - - /** - * return the size of the output buffer required for an update - * an input of len bytes. - * - * @param len the length of the input. - * @return the space required to accommodate a call to update - * with len bytes of input. - */ - public int getUpdateOutputSize( - int len) - { - int total = len + bufOff; - int leftOver = total % buf.length; - - if (leftOver == 0) - { - return total - buf.length; - } - - return total - leftOver; - } - - /** - * return the size of the output buffer required for an update plus a - * doFinal with an input of len bytes. - * - * @param len the length of the input. - * @return the space required to accommodate a call to update and doFinal - * with len bytes of input. - */ - public int getOutputSize( - int len) - { - return len + bufOff; - } - - /** - * process a single byte, producing an output block if necessary. - * - * @param in the input byte. - * @param out the space for any output that might be produced. - * @param outOff the offset from which the output will be copied. - * @return the number of output bytes copied to out. - * @exception org.bouncycastle.crypto.DataLengthException if there isn't enough space in out. - * @exception IllegalStateException if the cipher isn't initialised. - */ - public int processByte( - byte in, - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException - { - int resultLen = 0; - - if (bufOff == buf.length) - { - resultLen = cipher.processBlock(buf, 0, out, outOff); - System.arraycopy(buf, blockSize, buf, 0, blockSize); - - bufOff = blockSize; - } - - buf[bufOff++] = in; - - return resultLen; - } - - /** - * process an array of bytes, producing output if necessary. - * - * @param in the input byte array. - * @param inOff the offset at which the input data starts. - * @param len the number of bytes to be copied out of the input array. - * @param out the space for any output that might be produced. - * @param outOff the offset from which the output will be copied. - * @return the number of output bytes copied to out. - * @exception org.bouncycastle.crypto.DataLengthException if there isn't enough space in out. - * @exception IllegalStateException if the cipher isn't initialised. - */ - public int processBytes( - byte[] in, - int inOff, - int len, - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException - { - if (len < 0) - { - throw new IllegalArgumentException("Can't have a negative input length!"); - } - - int blockSize = getBlockSize(); - int length = getUpdateOutputSize(len); - - if (length > 0) - { - if ((outOff + length) > out.length) - { - throw new DataLengthException("output buffer too short"); - } - } - - int resultLen = 0; - int gapLen = buf.length - bufOff; - - if (len > gapLen) - { - System.arraycopy(in, inOff, buf, bufOff, gapLen); - - resultLen += cipher.processBlock(buf, 0, out, outOff); - System.arraycopy(buf, blockSize, buf, 0, blockSize); - - bufOff = blockSize; - - len -= gapLen; - inOff += gapLen; - - while (len > blockSize) - { - System.arraycopy(in, inOff, buf, bufOff, blockSize); - resultLen += cipher.processBlock(buf, 0, out, outOff + resultLen); - System.arraycopy(buf, blockSize, buf, 0, blockSize); - - len -= blockSize; - inOff += blockSize; - } - } - - System.arraycopy(in, inOff, buf, bufOff, len); - - bufOff += len; - - return resultLen; - } - - /** - * Process the last block in the buffer. - * - * @param out the array the block currently being held is copied into. - * @param outOff the offset at which the copying starts. - * @return the number of output bytes copied to out. - * @exception org.bouncycastle.crypto.DataLengthException if there is insufficient space in out for - * the output. - * @exception IllegalStateException if the underlying cipher is not - * initialised. - * @exception org.bouncycastle.crypto.InvalidCipherTextException if cipher text decrypts wrongly (in - * case the exception will never get thrown). - */ - public int doFinal( - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException, InvalidCipherTextException - { - if (bufOff + outOff > out.length) - { - throw new DataLengthException("output buffer to small in doFinal"); - } - - int blockSize = cipher.getBlockSize(); - int len = bufOff - blockSize; - byte[] block = new byte[blockSize]; - - if (forEncryption) - { - cipher.processBlock(buf, 0, block, 0); - - if (bufOff < blockSize) - { - throw new DataLengthException("need at least one block of input for CTS"); - } - - for (int i = bufOff; i != buf.length; i++) - { - buf[i] = block[i - blockSize]; - } - - for (int i = blockSize; i != bufOff; i++) - { - buf[i] ^= block[i - blockSize]; - } - - if (cipher instanceof CBCBlockCipher) - { - BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher(); - - c.processBlock(buf, blockSize, out, outOff); - } - else - { - cipher.processBlock(buf, blockSize, out, outOff); - } - - System.arraycopy(block, 0, out, outOff + blockSize, len); - } - else - { - byte[] lastBlock = new byte[blockSize]; - - if (cipher instanceof CBCBlockCipher) - { - BlockCipher c = ((CBCBlockCipher)cipher).getUnderlyingCipher(); - - c.processBlock(buf, 0, block, 0); - } - else - { - cipher.processBlock(buf, 0, block, 0); - } - - for (int i = blockSize; i != bufOff; i++) - { - lastBlock[i - blockSize] = (byte)(block[i - blockSize] ^ buf[i]); - } - - System.arraycopy(buf, blockSize, block, 0, len); - - cipher.processBlock(block, 0, out, outOff); - System.arraycopy(lastBlock, 0, out, outOff + blockSize, len); - } - - int offset = bufOff; - - reset(); - - return offset; - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/OpenPGPCFBBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/OpenPGPCFBBlockCipher.java deleted file mode 100644 index e48731b..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/OpenPGPCFBBlockCipher.java +++ /dev/null @@ -1,312 +0,0 @@ -package org.bouncycastle.crypto.modes; - -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DataLengthException; - -/** - * Implements OpenPGP's rather strange version of Cipher-FeedBack (CFB) mode - * on top of a simple cipher. This class assumes the IV has been prepended - * to the data stream already, and just accomodates the reset after - * (blockSize + 2) bytes have been read. - * <p> - * For further info see <a href="http://www.ietf.org/rfc/rfc2440.html">RFC 2440</a>. - */ -public class OpenPGPCFBBlockCipher - implements BlockCipher -{ - private byte[] IV; - private byte[] FR; - private byte[] FRE; - - private BlockCipher cipher; - - private int count; - private int blockSize; - private boolean forEncryption; - - /** - * Basic constructor. - * - * @param cipher the block cipher to be used as the basis of the - * feedback mode. - */ - public OpenPGPCFBBlockCipher( - BlockCipher cipher) - { - this.cipher = cipher; - - this.blockSize = cipher.getBlockSize(); - this.IV = new byte[blockSize]; - this.FR = new byte[blockSize]; - this.FRE = new byte[blockSize]; - } - - /** - * return the underlying block cipher that we are wrapping. - * - * @return the underlying block cipher that we are wrapping. - */ - public BlockCipher getUnderlyingCipher() - { - return cipher; - } - - /** - * return the algorithm name and mode. - * - * @return the name of the underlying algorithm followed by "/PGPCFB" - * and the block size in bits. - */ - public String getAlgorithmName() - { - return cipher.getAlgorithmName() + "/OpenPGPCFB"; - } - - /** - * return the block size we are operating at. - * - * @return the block size we are operating at (in bytes). - */ - public int getBlockSize() - { - return cipher.getBlockSize(); - } - - /** - * Process one block of input from the array in and write it to - * the out array. - * - * @param in the array containing the input data. - * @param inOff offset into the in array the data starts at. - * @param out the array the output data will be copied into. - * @param outOff the offset into the out array the output will start at. - * @exception DataLengthException if there isn't enough data in in, or - * space in out. - * @exception IllegalStateException if the cipher isn't initialised. - * @return the number of bytes processed and produced. - */ - public int processBlock( - byte[] in, - int inOff, - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException - { - return (forEncryption) ? encryptBlock(in, inOff, out, outOff) : decryptBlock(in, inOff, out, outOff); - } - - /** - * reset the chaining vector back to the IV and reset the underlying - * cipher. - */ - public void reset() - { - count = 0; - - System.arraycopy(IV, 0, FR, 0, FR.length); - - cipher.reset(); - } - - /** - * Initialise the cipher and, possibly, the initialisation vector (IV). - * If an IV isn't passed as part of the parameter, the IV will be all zeros. - * An IV which is too short is handled in FIPS compliant fashion. - * - * @param forEncryption if true the cipher is initialised for - * encryption, if false for decryption. - * @param params the key and other data required by the cipher. - * @exception IllegalArgumentException if the params argument is - * inappropriate. - */ - public void init( - boolean forEncryption, - CipherParameters params) - throws IllegalArgumentException - { - this.forEncryption = forEncryption; - - reset(); - - cipher.init(true, params); - } - - /** - * Encrypt one byte of data according to CFB mode. - * @param data the byte to encrypt - * @param blockOff offset in the current block - * @return the encrypted byte - */ - private byte encryptByte(byte data, int blockOff) - { - return (byte)(FRE[blockOff] ^ data); - } - - /** - * Do the appropriate processing for CFB IV mode encryption. - * - * @param in the array containing the data to be encrypted. - * @param inOff offset into the in array the data starts at. - * @param out the array the encrypted data will be copied into. - * @param outOff the offset into the out array the output will start at. - * @exception DataLengthException if there isn't enough data in in, or - * space in out. - * @exception IllegalStateException if the cipher isn't initialised. - * @return the number of bytes processed and produced. - */ - private int encryptBlock( - byte[] in, - int inOff, - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException - { - if ((inOff + blockSize) > in.length) - { - throw new DataLengthException("input buffer too short"); - } - - if ((outOff + blockSize) > out.length) - { - throw new DataLengthException("output buffer too short"); - } - - if (count > blockSize) - { - FR[blockSize - 2] = out[outOff] = encryptByte(in[inOff], blockSize - 2); - FR[blockSize - 1] = out[outOff + 1] = encryptByte(in[inOff + 1], blockSize - 1); - - cipher.processBlock(FR, 0, FRE, 0); - - for (int n = 2; n < blockSize; n++) - { - FR[n - 2] = out[outOff + n] = encryptByte(in[inOff + n], n - 2); - } - } - else if (count == 0) - { - cipher.processBlock(FR, 0, FRE, 0); - - for (int n = 0; n < blockSize; n++) - { - FR[n] = out[outOff + n] = encryptByte(in[inOff + n], n); - } - - count += blockSize; - } - else if (count == blockSize) - { - cipher.processBlock(FR, 0, FRE, 0); - - out[outOff] = encryptByte(in[inOff], 0); - out[outOff + 1] = encryptByte(in[inOff + 1], 1); - - // - // do reset - // - System.arraycopy(FR, 2, FR, 0, blockSize - 2); - System.arraycopy(out, outOff, FR, blockSize - 2, 2); - - cipher.processBlock(FR, 0, FRE, 0); - - for (int n = 2; n < blockSize; n++) - { - FR[n - 2] = out[outOff + n] = encryptByte(in[inOff + n], n - 2); - } - - count += blockSize; - } - - return blockSize; - } - - /** - * Do the appropriate processing for CFB IV mode decryption. - * - * @param in the array containing the data to be decrypted. - * @param inOff offset into the in array the data starts at. - * @param out the array the encrypted data will be copied into. - * @param outOff the offset into the out array the output will start at. - * @exception DataLengthException if there isn't enough data in in, or - * space in out. - * @exception IllegalStateException if the cipher isn't initialised. - * @return the number of bytes processed and produced. - */ - private int decryptBlock( - byte[] in, - int inOff, - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException - { - if ((inOff + blockSize) > in.length) - { - throw new DataLengthException("input buffer too short"); - } - - if ((outOff + blockSize) > out.length) - { - throw new DataLengthException("output buffer too short"); - } - - if (count > blockSize) - { - byte inVal = in[inOff]; - FR[blockSize - 2] = inVal; - out[outOff] = encryptByte(inVal, blockSize - 2); - - inVal = in[inOff + 1]; - FR[blockSize - 1] = inVal; - out[outOff + 1] = encryptByte(inVal, blockSize - 1); - - cipher.processBlock(FR, 0, FRE, 0); - - for (int n = 2; n < blockSize; n++) - { - inVal = in[inOff + n]; - FR[n - 2] = inVal; - out[outOff + n] = encryptByte(inVal, n - 2); - } - } - else if (count == 0) - { - cipher.processBlock(FR, 0, FRE, 0); - - for (int n = 0; n < blockSize; n++) - { - FR[n] = in[inOff + n]; - out[n] = encryptByte(in[inOff + n], n); - } - - count += blockSize; - } - else if (count == blockSize) - { - cipher.processBlock(FR, 0, FRE, 0); - - byte inVal1 = in[inOff]; - byte inVal2 = in[inOff + 1]; - out[outOff ] = encryptByte(inVal1, 0); - out[outOff + 1] = encryptByte(inVal2, 1); - - System.arraycopy(FR, 2, FR, 0, blockSize - 2); - - FR[blockSize - 2] = inVal1; - FR[blockSize - 1] = inVal2; - - cipher.processBlock(FR, 0, FRE, 0); - - for (int n = 2; n < blockSize; n++) - { - byte inVal = in[inOff + n]; - FR[n - 2] = inVal; - out[outOff + n] = encryptByte(inVal, n - 2); - } - - count += blockSize; - } - - return blockSize; - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/PGPCFBBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/PGPCFBBlockCipher.java deleted file mode 100644 index 4dee63a..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/PGPCFBBlockCipher.java +++ /dev/null @@ -1,455 +0,0 @@ -package org.bouncycastle.crypto.modes; - -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.CipherParameters; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.params.ParametersWithIV; - -/** - * Implements OpenPGP's rather strange version of Cipher-FeedBack (CFB) mode on top of a simple cipher. For further info see <a href="http://www.ietf.org/rfc/rfc2440.html">RFC 2440</a>. - */ -public class PGPCFBBlockCipher - implements BlockCipher -{ - private byte[] IV; - private byte[] FR; - private byte[] FRE; - private byte[] tmp; - - private BlockCipher cipher; - - private int count; - private int blockSize; - private boolean forEncryption; - - private boolean inlineIv; // if false we don't need to prepend an IV - - /** - * Basic constructor. - * - * @param cipher the block cipher to be used as the basis of the - * feedback mode. - * @param inlineIv if true this is for PGP CFB with a prepended iv. - */ - public PGPCFBBlockCipher( - BlockCipher cipher, - boolean inlineIv) - { - this.cipher = cipher; - this.inlineIv = inlineIv; - - this.blockSize = cipher.getBlockSize(); - this.IV = new byte[blockSize]; - this.FR = new byte[blockSize]; - this.FRE = new byte[blockSize]; - this.tmp = new byte[blockSize]; - } - - /** - * return the underlying block cipher that we are wrapping. - * - * @return the underlying block cipher that we are wrapping. - */ - public BlockCipher getUnderlyingCipher() - { - return cipher; - } - - /** - * return the algorithm name and mode. - * - * @return the name of the underlying algorithm followed by "/PGPCFB" - * and the block size in bits. - */ - public String getAlgorithmName() - { - if (inlineIv) - { - return cipher.getAlgorithmName() + "/PGPCFBwithIV"; - } - else - { - return cipher.getAlgorithmName() + "/PGPCFB"; - } - } - - /** - * return the block size we are operating at. - * - * @return the block size we are operating at (in bytes). - */ - public int getBlockSize() - { - return cipher.getBlockSize(); - } - - /** - * Process one block of input from the array in and write it to - * the out array. - * - * @param in the array containing the input data. - * @param inOff offset into the in array the data starts at. - * @param out the array the output data will be copied into. - * @param outOff the offset into the out array the output will start at. - * @exception DataLengthException if there isn't enough data in in, or - * space in out. - * @exception IllegalStateException if the cipher isn't initialised. - * @return the number of bytes processed and produced. - */ - public int processBlock( - byte[] in, - int inOff, - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException - { - if (inlineIv) - { - return (forEncryption) ? encryptBlockWithIV(in, inOff, out, outOff) : decryptBlockWithIV(in, inOff, out, outOff); - } - else - { - return (forEncryption) ? encryptBlock(in, inOff, out, outOff) : decryptBlock(in, inOff, out, outOff); - } - } - - /** - * reset the chaining vector back to the IV and reset the underlying - * cipher. - */ - public void reset() - { - count = 0; - - for (int i = 0; i != FR.length; i++) - { - if (inlineIv) - { - FR[i] = 0; - } - else - { - FR[i] = IV[i]; // if simple mode, key is IV (even if this is zero) - } - } - - cipher.reset(); - } - - /** - * Initialise the cipher and, possibly, the initialisation vector (IV). - * If an IV isn't passed as part of the parameter, the IV will be all zeros. - * An IV which is too short is handled in FIPS compliant fashion. - * - * @param forEncryption if true the cipher is initialised for - * encryption, if false for decryption. - * @param params the key and other data required by the cipher. - * @exception IllegalArgumentException if the params argument is - * inappropriate. - */ - public void init( - boolean forEncryption, - CipherParameters params) - throws IllegalArgumentException - { - this.forEncryption = forEncryption; - - if (params instanceof ParametersWithIV) - { - ParametersWithIV ivParam = (ParametersWithIV)params; - byte[] iv = ivParam.getIV(); - - if (iv.length < IV.length) - { - // prepend the supplied IV with zeros (per FIPS PUB 81) - System.arraycopy(iv, 0, IV, IV.length - iv.length, iv.length); - for (int i = 0; i < IV.length - iv.length; i++) - { - IV[i] = 0; - } - } - else - { - System.arraycopy(iv, 0, IV, 0, IV.length); - } - - reset(); - - cipher.init(true, ivParam.getParameters()); - } - else - { - reset(); - - cipher.init(true, params); - } - } - - /** - * Encrypt one byte of data according to CFB mode. - * @param data the byte to encrypt - * @param blockOff where am i in the current block, determines when to resync the block - * @returns the encrypted byte - */ - private byte encryptByte(byte data, int blockOff) - { - return (byte)(FRE[blockOff] ^ data); - } - - /** - * Do the appropriate processing for CFB IV mode encryption. - * - * @param in the array containing the data to be encrypted. - * @param inOff offset into the in array the data starts at. - * @param out the array the encrypted data will be copied into. - * @param outOff the offset into the out array the output will start at. - * @exception DataLengthException if there isn't enough data in in, or - * space in out. - * @exception IllegalStateException if the cipher isn't initialised. - * @return the number of bytes processed and produced. - */ - private int encryptBlockWithIV( - byte[] in, - int inOff, - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException - { - if ((inOff + blockSize) > in.length) - { - throw new DataLengthException("input buffer too short"); - } - - if (count == 0) - { - if ((outOff + 2 * blockSize + 2) > out.length) - { - throw new DataLengthException("output buffer too short"); - } - - cipher.processBlock(FR, 0, FRE, 0); - - for (int n = 0; n < blockSize; n++) - { - out[outOff + n] = encryptByte(IV[n], n); - } - - System.arraycopy(out, outOff, FR, 0, blockSize); - - cipher.processBlock(FR, 0, FRE, 0); - - out[outOff + blockSize] = encryptByte(IV[blockSize - 2], 0); - out[outOff + blockSize + 1] = encryptByte(IV[blockSize - 1], 1); - - System.arraycopy(out, outOff + 2, FR, 0, blockSize); - - cipher.processBlock(FR, 0, FRE, 0); - - for (int n = 0; n < blockSize; n++) - { - out[outOff + blockSize + 2 + n] = encryptByte(in[inOff + n], n); - } - - System.arraycopy(out, outOff + blockSize + 2, FR, 0, blockSize); - - count += 2 * blockSize + 2; - - return 2 * blockSize + 2; - } - else if (count >= blockSize + 2) - { - if ((outOff + blockSize) > out.length) - { - throw new DataLengthException("output buffer too short"); - } - - cipher.processBlock(FR, 0, FRE, 0); - - for (int n = 0; n < blockSize; n++) - { - out[outOff + n] = encryptByte(in[inOff + n], n); - } - - System.arraycopy(out, outOff, FR, 0, blockSize); - } - - return blockSize; - } - - /** - * Do the appropriate processing for CFB IV mode decryption. - * - * @param in the array containing the data to be decrypted. - * @param inOff offset into the in array the data starts at. - * @param out the array the encrypted data will be copied into. - * @param outOff the offset into the out array the output will start at. - * @exception DataLengthException if there isn't enough data in in, or - * space in out. - * @exception IllegalStateException if the cipher isn't initialised. - * @return the number of bytes processed and produced. - */ - private int decryptBlockWithIV( - byte[] in, - int inOff, - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException - { - if ((inOff + blockSize) > in.length) - { - throw new DataLengthException("input buffer too short"); - } - - if ((outOff + blockSize) > out.length) - { - throw new DataLengthException("output buffer too short"); - } - - if (count == 0) - { - for (int n = 0; n < blockSize; n++) - { - FR[n] = in[inOff + n]; - } - - cipher.processBlock(FR, 0, FRE, 0); - - count += blockSize; - - return 0; - } - else if (count == blockSize) - { - // copy in buffer so that this mode works if in and out are the same - System.arraycopy(in, inOff, tmp, 0, blockSize); - - System.arraycopy(FR, 2, FR, 0, blockSize - 2); - - FR[blockSize - 2] = tmp[0]; - FR[blockSize - 1] = tmp[1]; - - cipher.processBlock(FR, 0, FRE, 0); - - for (int n = 0; n < blockSize - 2; n++) - { - out[outOff + n] = encryptByte(tmp[n + 2], n); - } - - System.arraycopy(tmp, 2, FR, 0, blockSize - 2); - - count += 2; - - return blockSize - 2; - } - else if (count >= blockSize + 2) - { - // copy in buffer so that this mode works if in and out are the same - System.arraycopy(in, inOff, tmp, 0, blockSize); - - out[outOff + 0] = encryptByte(tmp[0], blockSize - 2); - out[outOff + 1] = encryptByte(tmp[1], blockSize - 1); - - System.arraycopy(tmp, 0, FR, blockSize - 2, 2); - - cipher.processBlock(FR, 0, FRE, 0); - - for (int n = 0; n < blockSize - 2; n++) - { - out[outOff + n + 2] = encryptByte(tmp[n + 2], n); - } - - System.arraycopy(tmp, 2, FR, 0, blockSize - 2); - - } - - return blockSize; - } - - /** - * Do the appropriate processing for CFB mode encryption. - * - * @param in the array containing the data to be encrypted. - * @param inOff offset into the in array the data starts at. - * @param out the array the encrypted data will be copied into. - * @param outOff the offset into the out array the output will start at. - * @exception DataLengthException if there isn't enough data in in, or - * space in out. - * @exception IllegalStateException if the cipher isn't initialised. - * @return the number of bytes processed and produced. - */ - private int encryptBlock( - byte[] in, - int inOff, - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException - { - if ((inOff + blockSize) > in.length) - { - throw new DataLengthException("input buffer too short"); - } - - if ((outOff + blockSize) > out.length) - { - throw new DataLengthException("output buffer too short"); - } - - cipher.processBlock(FR, 0, FRE, 0); - for (int n = 0; n < blockSize; n++) - { - out[outOff + n] = encryptByte(in[inOff + n], n); - } - - for (int n = 0; n < blockSize; n++) - { - FR[n] = out[outOff + n]; - } - - return blockSize; - - } - - /** - * Do the appropriate processing for CFB mode decryption. - * - * @param in the array containing the data to be decrypted. - * @param inOff offset into the in array the data starts at. - * @param out the array the encrypted data will be copied into. - * @param outOff the offset into the out array the output will start at. - * @exception DataLengthException if there isn't enough data in in, or - * space in out. - * @exception IllegalStateException if the cipher isn't initialised. - * @return the number of bytes processed and produced. - */ - private int decryptBlock( - byte[] in, - int inOff, - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException - { - if ((inOff + blockSize) > in.length) - { - throw new DataLengthException("input buffer too short"); - } - - if ((outOff + blockSize) > out.length) - { - throw new DataLengthException("output buffer too short"); - } - - cipher.processBlock(FR, 0, FRE, 0); - for (int n = 0; n < blockSize; n++) - { - out[outOff + n] = encryptByte(in[inOff + n], n); - } - - for (int n = 0; n < blockSize; n++) - { - FR[n] = in[inOff + n]; - } - - return blockSize; - - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/PaddedBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/PaddedBlockCipher.java deleted file mode 100644 index f15ed67..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/PaddedBlockCipher.java +++ /dev/null @@ -1,253 +0,0 @@ -package org.bouncycastle.crypto.modes; - -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.BufferedBlockCipher; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.InvalidCipherTextException; - -/** - * A wrapper class that allows block ciphers to be used to process data in - * a piecemeal fashion with PKCS5/PKCS7 padding. The PaddedBlockCipher - * outputs a block only when the buffer is full and more data is being added, - * or on a doFinal (unless the current block in the buffer is a pad block). - * The padding mechanism used is the one outlined in PKCS5/PKCS7. - * - * @deprecated use org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher instead. - */ -public class PaddedBlockCipher - extends BufferedBlockCipher -{ - /** - * Create a buffered block cipher with, or without, padding. - * - * @param cipher the underlying block cipher this buffering object wraps. - */ - public PaddedBlockCipher( - BlockCipher cipher) - { - this.cipher = cipher; - - buf = new byte[cipher.getBlockSize()]; - bufOff = 0; - } - - /** - * return the size of the output buffer required for an update plus a - * doFinal with an input of len bytes. - * - * @param len the length of the input. - * @return the space required to accommodate a call to update and doFinal - * with len bytes of input. - */ - public int getOutputSize( - int len) - { - int total = len + bufOff; - int leftOver = total % buf.length; - - if (leftOver == 0) - { - if (forEncryption) - { - return total + buf.length; - } - - return total; - } - - return total - leftOver + buf.length; - } - - /** - * return the size of the output buffer required for an update - * an input of len bytes. - * - * @param len the length of the input. - * @return the space required to accommodate a call to update - * with len bytes of input. - */ - public int getUpdateOutputSize( - int len) - { - int total = len + bufOff; - int leftOver = total % buf.length; - - if (leftOver == 0) - { - return total - buf.length; - } - - return total - leftOver; - } - - /** - * process a single byte, producing an output block if neccessary. - * - * @param in the input byte. - * @param out the space for any output that might be produced. - * @param outOff the offset from which the output will be copied. - * @exception DataLengthException if there isn't enough space in out. - * @exception IllegalStateException if the cipher isn't initialised. - */ - public int processByte( - byte in, - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException - { - int resultLen = 0; - - if (bufOff == buf.length) - { - resultLen = cipher.processBlock(buf, 0, out, outOff); - bufOff = 0; - } - - buf[bufOff++] = in; - - return resultLen; - } - - /** - * process an array of bytes, producing output if necessary. - * - * @param in the input byte array. - * @param inOff the offset at which the input data starts. - * @param len the number of bytes to be copied out of the input array. - * @param out the space for any output that might be produced. - * @param outOff the offset from which the output will be copied. - * @exception DataLengthException if there isn't enough space in out. - * @exception IllegalStateException if the cipher isn't initialised. - */ - public int processBytes( - byte[] in, - int inOff, - int len, - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException - { - if (len < 0) - { - throw new IllegalArgumentException("Can't have a negative input length!"); - } - - int blockSize = getBlockSize(); - int length = getUpdateOutputSize(len); - - if (length > 0) - { - if ((outOff + length) > out.length) - { - throw new DataLengthException("output buffer too short"); - } - } - - int resultLen = 0; - int gapLen = buf.length - bufOff; - - if (len > gapLen) - { - System.arraycopy(in, inOff, buf, bufOff, gapLen); - - resultLen += cipher.processBlock(buf, 0, out, outOff); - - bufOff = 0; - len -= gapLen; - inOff += gapLen; - - while (len > buf.length) - { - resultLen += cipher.processBlock(in, inOff, out, outOff + resultLen); - - len -= blockSize; - inOff += blockSize; - } - } - - System.arraycopy(in, inOff, buf, bufOff, len); - - bufOff += len; - - return resultLen; - } - - /** - * Process the last block in the buffer. If the buffer is currently - * full and padding needs to be added a call to doFinal will produce - * 2 * getBlockSize() bytes. - * - * @param out the array the block currently being held is copied into. - * @param outOff the offset at which the copying starts. - * @exception DataLengthException if there is insufficient space in out for - * the output or we are decrypting and the input is not block size aligned. - * @exception IllegalStateException if the underlying cipher is not - * initialised. - * @exception InvalidCipherTextException if padding is expected and not found. - */ - public int doFinal( - byte[] out, - int outOff) - throws DataLengthException, IllegalStateException, InvalidCipherTextException - { - int blockSize = cipher.getBlockSize(); - int resultLen = 0; - - if (forEncryption) - { - if (bufOff == blockSize) - { - if ((outOff + 2 * blockSize) > out.length) - { - throw new DataLengthException("output buffer too short"); - } - - resultLen = cipher.processBlock(buf, 0, out, outOff); - bufOff = 0; - } - - // - // add PKCS7 padding - // - byte code = (byte)(blockSize - bufOff); - - while (bufOff < blockSize) - { - buf[bufOff] = code; - bufOff++; - } - - resultLen += cipher.processBlock(buf, 0, out, outOff + resultLen); - } - else - { - if (bufOff == blockSize) - { - resultLen = cipher.processBlock(buf, 0, buf, 0); - bufOff = 0; - } - else - { - throw new DataLengthException("last block incomplete in decryption"); - } - - // - // remove PKCS7 padding - // - int count = buf[blockSize - 1] & 0xff; - - if ((count < 0) || (count > blockSize)) - { - throw new InvalidCipherTextException("pad block corrupted"); - } - - resultLen -= count; - - System.arraycopy(buf, 0, out, outOff, resultLen); - } - - reset(); - - return resultLen; - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java deleted file mode 100644 index fc25810..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/BasicGCMExponentiator.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.bouncycastle.crypto.modes.gcm; - -import org.bouncycastle.util.Arrays; - -public class BasicGCMExponentiator implements GCMExponentiator -{ - private int[] x; - - public void init(byte[] x) - { - this.x = GCMUtil.asInts(x); - } - - public void exponentiateX(long pow, byte[] output) - { - // Initial value is little-endian 1 - int[] y = GCMUtil.oneAsInts(); - - if (pow > 0) - { - int[] powX = Arrays.clone(x); - do - { - if ((pow & 1L) != 0) - { - GCMUtil.multiply(y, powX); - } - GCMUtil.multiply(powX, powX); - pow >>>= 1; - } - while (pow > 0); - } - - GCMUtil.asBytes(y, output); - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/BasicGCMMultiplier.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/BasicGCMMultiplier.java deleted file mode 100644 index 2afb18f..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/BasicGCMMultiplier.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.bouncycastle.crypto.modes.gcm; - -public class BasicGCMMultiplier implements GCMMultiplier -{ - private int[] H; - - public void init(byte[] H) - { - this.H = GCMUtil.asInts(H); - } - - public void multiplyH(byte[] x) - { - int[] t = GCMUtil.asInts(x); - GCMUtil.multiply(t, H); - GCMUtil.asBytes(t, x); - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables64kGCMMultiplier.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables64kGCMMultiplier.java deleted file mode 100644 index 4f32a0d..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/Tables64kGCMMultiplier.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.bouncycastle.crypto.modes.gcm; - -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.Pack; - -public class Tables64kGCMMultiplier implements GCMMultiplier -{ - private byte[] H; - private int[][][] M; - - public void init(byte[] H) - { - if (M == null) - { - M = new int[16][256][4]; - } - else if (Arrays.areEqual(this.H, H)) - { - return; - } - - this.H = Arrays.clone(H); - - // M[0][0] is ZEROES; - GCMUtil.asInts(H, M[0][128]); - - for (int j = 64; j >= 1; j >>= 1) - { - GCMUtil.multiplyP(M[0][j + j], M[0][j]); - } - - int i = 0; - for (;;) - { - for (int j = 2; j < 256; j += j) - { - for (int k = 1; k < j; ++k) - { - GCMUtil.xor(M[i][j], M[i][k], M[i][j + k]); - } - } - - if (++i == 16) - { - return; - } - - // M[i][0] is ZEROES; - for (int j = 128; j > 0; j >>= 1) - { - GCMUtil.multiplyP8(M[i - 1][j], M[i][j]); - } - } - } - - public void multiplyH(byte[] x) - { -// assert x.Length == 16; - - int[] z = new int[4]; - for (int i = 15; i >= 0; --i) - { -// GCMUtil.xor(z, M[i][x[i] & 0xff]); - int[] m = M[i][x[i] & 0xff]; - z[0] ^= m[0]; - z[1] ^= m[1]; - z[2] ^= m[2]; - z[3] ^= m[3]; - } - - Pack.intToBigEndian(z, x, 0); - } -} diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/package.html b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/package.html deleted file mode 100644 index 09c42f0..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/package.html +++ /dev/null @@ -1,5 +0,0 @@ -<html> -<body bgcolor="#ffffff"> -GCM mode support classes. -</body> -</html> diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/package.html b/bcprov/src/main/java/org/bouncycastle/crypto/modes/package.html deleted file mode 100644 index 5402df4..0000000 --- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/package.html +++ /dev/null @@ -1,5 +0,0 @@ -<html> -<body bgcolor="#ffffff"> -Modes for symmetric ciphers. -</body> -</html> |