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) {
    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) {
    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;
}

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 ) { 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 ) { 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 iv mode decryption .
