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    }