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); }
/** * 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); }