public override int GenerateBytes(byte[] output, int outOff, int length)
        {
            if ((output.Length - length) < outOff)
            {
                throw new DataLengthException("Output Buffer too Small");
            }

            int outLen = Digest.GetDigestSize();

            if (length > outLen)
            {
                throw new DataLengthException(
                          "Specified Hash Cannot Produce Sufficient Data for the Specified Operation.");
            }

            byte[] temp = new byte[Digest.GetDigestSize()];

            Digest.BlockUpdate(_shared, 0, _shared.Length);
            Digest.DoFinal(temp, 0);

            Array.Copy(temp, 0, output, outOff, length);

            Digest.Reset();
            return(length);
        }
Esempio n. 2
0
        /**
         * fill len bytes of the output buffer with bytes generated from the
         * derivation function.
         *
         * @throws IllegalArgumentException
         *             if the size of the request will cause an overflow.
         * @throws DataLengthException
         *             if the out buffer is too small.
         */
        public int GenerateBytes(byte[] output, int outOff, int length)
        {
            if (output.Length - length < outOff)
            {
                throw new DataLengthException("output buffer too small");
            }

            long oBytes = length;
            int  outLen = Digest.GetDigestSize();

            //
            // this is at odds with the standard implementation, the
            // maximum value should be hBits * (2^32 - 1) where hBits
            // is the digest output size in bits. We can't have an
            // array with a long index at the moment...
            //
            if (oBytes > (2L << 32) - 1)
            {
                throw new ArgumentException("Output length too large");
            }

            int cThreshold = (int)((oBytes + outLen - 1) / outLen);

            byte[] digest = new byte[Digest.GetDigestSize()];

//            byte[] C = new byte[4];
//            Pack.intToBigEndian(counterStart, C, 0);
            byte[] c = _counterStart.ToBigEndianByteArray();
            Debug.Assert(c.Length == 4, "need to be 4 bytes long");

            int counterBase = _counterStart & ~0xFF;

            for (int i = 0; i < cThreshold; i++)
            {
                Digest.BlockUpdate(c, 0, c.Length);
                Digest.BlockUpdate(_shared, 0, _shared.Length);

                if (_iv != null)
                {
                    Digest.BlockUpdate(_iv, 0, _iv.Length);
                }

                Digest.DoFinal(digest, 0);

                if (length > outLen)
                {
                    Array.Copy(digest, 0, output, outOff, outLen);
                    outOff += outLen;
                    length -= outLen;
                }
                else
                {
                    Array.Copy(digest, 0, output, outOff, length);
                }

                if (++c[3] == 0)
                {
                    counterBase += 0x100;
//                    Pack.intToBigEndian(counterBase, C, 0);
                    c = counterBase.ToBigEndianByteArray();
                    Debug.Assert(c.Length == 4, "need to be 4 bytes long");
                }
            }

            Digest.Reset();

            return((int)oBytes);
        }