view src/ch/ethz/ssh2/crypto/cipher/CBCMode.java @ 434:7ea898484623

Added tag stable-1.9.1 for changeset 3e25a713555d
author Carl Byington <carl@five-ten-sg.com>
date Mon, 09 Mar 2015 16:33:11 -0700
parents 071eccdff8ea
children
line wrap: on
line source

/*
 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
 * Please refer to the LICENSE.txt for licensing details.
 */
package ch.ethz.ssh2.crypto.cipher;

/**
 * CBCMode.
 *
 * @author Christian Plattner
 * @version 2.50, 03/15/10
 */
public class CBCMode implements BlockCipher {
    BlockCipher tc;
    int blockSize;
    boolean doEncrypt;

    byte[] cbc_vector;
    byte[] tmp_vector;

    public void init(boolean forEncryption, byte[] key) {
    }

    public CBCMode(BlockCipher tc, byte[] iv, boolean doEncrypt)
    throws IllegalArgumentException {
        this.tc = tc;
        this.blockSize = tc.getBlockSize();
        this.doEncrypt = doEncrypt;

        if (this.blockSize != iv.length)
            throw new IllegalArgumentException("IV must be " + blockSize
                                               + " bytes long! (currently " + iv.length + ")");

        this.cbc_vector = new byte[blockSize];
        this.tmp_vector = new byte[blockSize];
        System.arraycopy(iv, 0, cbc_vector, 0, blockSize);
    }

    public int getBlockSize() {
        return blockSize;
    }

    private void encryptBlock(byte[] src, int srcoff, byte[] dst, int dstoff) {
        for (int i = 0; i < blockSize; i++)
            cbc_vector[i] ^= src[srcoff + i];

        tc.transformBlock(cbc_vector, 0, dst, dstoff);
        System.arraycopy(dst, dstoff, cbc_vector, 0, blockSize);
    }

    private void decryptBlock(byte[] src, int srcoff, byte[] dst, int dstoff) {
        /* Assume the worst, src and dst are overlapping... */
        System.arraycopy(src, srcoff, tmp_vector, 0, blockSize);
        tc.transformBlock(src, srcoff, dst, dstoff);

        for (int i = 0; i < blockSize; i++)
            dst[dstoff + i] ^= cbc_vector[i];

        /* ...that is why we need a tmp buffer. */
        byte[] swap = cbc_vector;
        cbc_vector = tmp_vector;
        tmp_vector = swap;
    }

    public void transformBlock(byte[] src, int srcoff, byte[] dst, int dstoff) {
        if (doEncrypt)
            encryptBlock(src, srcoff, dst, dstoff);
        else
            decryptBlock(src, srcoff, dst, dstoff);
    }
}