public override byte[] GetBytes(int count)
{
byte[] ret = new byte[count];
int filled = 0;
while (filled < count) {
if (filled + _hash.Length < count) {
/* Copy current hash into results */
Array.Copy(_hash, 0, ret, filled, _hash.Length);
filled += _hash.Length;
/* Calculate the next hash */
if (_iteration > 26) {
throw new Exception("SSL3 pseudorandom function can't output more bytes");
}
byte[] header = new byte[_iteration];
for (int i=0; i<header.Length; i++) {
header[i] = (byte)(64 + _iteration);
}
_sha1.Initialize();
_sha1.TransformBlock(header, 0, header.Length, header, 0);
_sha1.TransformBlock(_secret, 0, _secret.Length, _secret, 0);
_sha1.TransformFinalBlock(_seed, 0, _seed.Length);
byte[] sha1Hash = _sha1.Hash;
_md5.Initialize();
_md5.TransformBlock(_secret, 0, _secret.Length, _secret, 0);
_md5.TransformFinalBlock(sha1Hash, 0, sha1Hash.Length);
_hash = _md5.Hash;
_iteration++;
} else {
/* Count how many bytes to consume */
int consumed = count - filled;
/* Make a partial copy of the current hash */
Array.Copy(_hash, 0, ret, filled, consumed);
filled += consumed;
/* Remove read bytes from the current hash */
byte[] tmp = new byte[_hash.Length - consumed];
Array.Copy(_hash, _hash.Length - tmp.Length, tmp, 0, tmp.Length);
_hash = tmp;
}
}
return ret;
}