    001    package org.bouncycastle.crypto.modes;
    002
    003    import org.bouncycastle.crypto.BlockCipher;
    004    import org.bouncycastle.crypto.CipherParameters;
    005    import org.bouncycastle.crypto.DataLengthException;
    006    import org.bouncycastle.crypto.params.ParametersWithIV;
    007
    008    public class CFBBlockCipher implements BlockCipher
    009    {
    010        private byte[] field_71814_a;
    011        private byte[] field_71812_b;
    012        private byte[] field_71813_c;
    013        private int field_71810_d;
    014        private BlockCipher field_71811_e = null;
    015        private boolean field_71809_f;
    016
    017        public CFBBlockCipher(BlockCipher par1BlockCipher, int par2)
    018        {
    019            this.field_71811_e = par1BlockCipher;
    020            this.field_71810_d = par2 / 8;
    021            this.field_71814_a = new byte[par1BlockCipher.getBlockSize()];
    022            this.field_71812_b = new byte[par1BlockCipher.getBlockSize()];
    023            this.field_71813_c = new byte[par1BlockCipher.getBlockSize()];
    024        }
    025
    026        public void func_71805_a(boolean par1, CipherParameters par2CipherParameters) throws IllegalArgumentException
    027        {
    028            this.field_71809_f = par1;
    029
    030            if (par2CipherParameters instanceof ParametersWithIV)
    031            {
    032                ParametersWithIV var3 = (ParametersWithIV)par2CipherParameters;
    033                byte[] var4 = var3.getIV();
    034
    035                if (var4.length < this.field_71814_a.length)
    036                {
    037                    System.arraycopy(var4, 0, this.field_71814_a, this.field_71814_a.length - var4.length, var4.length);
    038
    039                    for (int var5 = 0; var5 < this.field_71814_a.length - var4.length; ++var5)
    040                    {
    041                        this.field_71814_a[var5] = 0;
    042                    }
    043                }
    044                else
    045                {
    046                    System.arraycopy(var4, 0, this.field_71814_a, 0, this.field_71814_a.length);
    047                }
    048
    049                this.func_71803_c();
    050
    051                if (var3.getParameters() != null)
    052                {
    053                    this.field_71811_e.func_71805_a(true, var3.getParameters());
    054                }
    055            }
    056            else
    057            {
    058                this.func_71803_c();
    059                this.field_71811_e.func_71805_a(true, par2CipherParameters);
    060            }
    061        }
    062
    063        /**
    064         * Return the name of the algorithm the cipher implements.
    065         */
    066        public String getAlgorithmName()
    067        {
    068            return this.field_71811_e.getAlgorithmName() + "/CFB" + this.field_71810_d * 8;
    069        }
    070
    071        /**
    072         * Return the block size for this cipher (in bytes).
    073         */
    074        public int getBlockSize()
    075        {
    076            return this.field_71810_d;
    077        }
    078
    079        public int func_71806_a(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) throws DataLengthException, IllegalStateException
    080        {
    081            return this.field_71809_f ? this.func_71807_b(par1ArrayOfByte, par2, par3ArrayOfByte, par4) : this.func_71808_c(par1ArrayOfByte, par2, par3ArrayOfByte, par4);
    082        }
    083
    084        public int func_71807_b(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) throws DataLengthException, IllegalStateException
    085        {
    086            if (par2 + this.field_71810_d > par1ArrayOfByte.length)
    087            {
    088                throw new DataLengthException("input buffer too short");
    089            }
    090            else if (par4 + this.field_71810_d > par3ArrayOfByte.length)
    091            {
    092                throw new DataLengthException("output buffer too short");
    093            }
    094            else
    095            {
    096                this.field_71811_e.func_71806_a(this.field_71812_b, 0, this.field_71813_c, 0);
    097
    098                for (int var5 = 0; var5 < this.field_71810_d; ++var5)
    099                {
    100                    par3ArrayOfByte[par4 + var5] = (byte)(this.field_71813_c[var5] ^ par1ArrayOfByte[par2 + var5]);
    101                }
    102
    103                System.arraycopy(this.field_71812_b, this.field_71810_d, this.field_71812_b, 0, this.field_71812_b.length - this.field_71810_d);
    104                System.arraycopy(par3ArrayOfByte, par4, this.field_71812_b, this.field_71812_b.length - this.field_71810_d, this.field_71810_d);
    105                return this.field_71810_d;
    106            }
    107        }
    108
    109        public int func_71808_c(byte[] par1ArrayOfByte, int par2, byte[] par3ArrayOfByte, int par4) throws DataLengthException, IllegalStateException
    110        {
    111            if (par2 + this.field_71810_d > par1ArrayOfByte.length)
    112            {
    113                throw new DataLengthException("input buffer too short");
    114            }
    115            else if (par4 + this.field_71810_d > par3ArrayOfByte.length)
    116            {
    117                throw new DataLengthException("output buffer too short");
    118            }
    119            else
    120            {
    121                this.field_71811_e.func_71806_a(this.field_71812_b, 0, this.field_71813_c, 0);
    122                System.arraycopy(this.field_71812_b, this.field_71810_d, this.field_71812_b, 0, this.field_71812_b.length - this.field_71810_d);
    123                System.arraycopy(par1ArrayOfByte, par2, this.field_71812_b, this.field_71812_b.length - this.field_71810_d, this.field_71810_d);
    124
    125                for (int var5 = 0; var5 < this.field_71810_d; ++var5)
    126                {
    127                    par3ArrayOfByte[par4 + var5] = (byte)(this.field_71813_c[var5] ^ par1ArrayOfByte[par2 + var5]);
    128                }
    129
    130                return this.field_71810_d;
    131            }
    132        }
    133
    134        public void func_71803_c()
    135        {
    136            System.arraycopy(this.field_71814_a, 0, this.field_71812_b, 0, this.field_71814_a.length);
    137            this.field_71811_e.func_71803_c();
    138        }
    139    }