Ejemplo n.º 1
0
 public static CypherBasedPrngGenerator CreateWithSystemCrngKey(
     ICryptoPrimitive cryptoPrimitive      = null,
     HashAlgorithm hashAlgorithm           = null,
     CypherCounter initialCounter          = null,
     int outputBufferSize                  = -1,
     Func <byte[]> additionalEntropyGetter = null)
 {
     return(Create(new CryptoRandomWrapperGenerator().GetRandomBytes(32), cryptoPrimitive, hashAlgorithm, initialCounter, outputBufferSize, additionalEntropyGetter));
 }
Ejemplo n.º 2
0
 public static CypherBasedPrngGenerator CreateWithCheapKey(
     ICryptoPrimitive cryptoPrimitive      = null,
     HashAlgorithm hashAlgorithm           = null,
     CypherCounter initialCounter          = null,
     int outputBufferSize                  = -1,
     Func <byte[]> additionalEntropyGetter = null)
 {
     return(Create(EntropySources.PortableEntropy.Get32(), cryptoPrimitive, hashAlgorithm, initialCounter, outputBufferSize, additionalEntropyGetter));
 }
Ejemplo n.º 3
0
 public static CypherBasedPrngGenerator CreateWithNullKey(
     ICryptoPrimitive cryptoPrimitive      = null,
     HashAlgorithm hashAlgorithm           = null,
     CypherCounter initialCounter          = null,
     int outputBufferSize                  = -1,
     Func <byte[]> additionalEntropyGetter = null)
 {
     return(Create(new byte[32], cryptoPrimitive, hashAlgorithm, initialCounter, outputBufferSize, additionalEntropyGetter));
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Alternate constructor with named parameters.
 /// </summary>
 public static CypherBasedPrngGenerator Create(byte[] key,
                                               ICryptoPrimitive cryptoPrimitive      = null,
                                               HashAlgorithm hashAlgorithm           = null,
                                               CypherCounter initialCounter          = null,
                                               int outputBufferSize                  = -1,
                                               Func <byte[]> additionalEntropyGetter = null)
 {
     return(new CypherBasedPrngGenerator(key,
                                         cryptoPrimitive ?? BlockCypherCryptoPrimitive.Aes256(),
                                         hashAlgorithm ?? SHA512.Create(),
                                         initialCounter ?? new CypherCounter(16),
                                         outputBufferSize < 0 ? 1024 : outputBufferSize,
                                         additionalEntropyGetter));
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Initialise the CPRNG with the given key material, specified encryption algorithm, initial counter and additional entropy source.
        /// </summary>
        public CypherBasedPrngGenerator(byte[] key, ICryptoPrimitive cryptoPrimitive, HashAlgorithm hashAlgorithm, CypherCounter initialCounter, int outputBufferSize, Func <byte[]> additionalEntropyGetter)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }
            if (cryptoPrimitive == null)
            {
                throw new ArgumentNullException(nameof(cryptoPrimitive));
            }
            if (hashAlgorithm == null)
            {
                throw new ArgumentNullException(nameof(hashAlgorithm));
            }
            if (initialCounter == null)
            {
                throw new ArgumentNullException(nameof(initialCounter));
            }
            _KeySizeInBytes   = cryptoPrimitive.KeySizeBytes;
            _BlockSizeInBytes = cryptoPrimitive.BlockSizeBytes;
            if (!(_KeySizeInBytes == 16 || _KeySizeInBytes == 32 || _KeySizeInBytes == 64))
            {
                throw new ArgumentOutOfRangeException(nameof(cryptoPrimitive), _KeySizeInBytes, $"Encryption Algorithm KeySize must be 16, 32 or 64 bytes long.");
            }
            if (!(_BlockSizeInBytes == 16 || _BlockSizeInBytes == 32 || _BlockSizeInBytes == 64))
            {
                throw new ArgumentOutOfRangeException(nameof(cryptoPrimitive), _BlockSizeInBytes, $"Encryption Algorithm BlockSize must be 16, 32 or 64 bytes long.");
            }
            if (key.Length != _KeySizeInBytes)
            {
                throw new ArgumentOutOfRangeException(nameof(key), key.Length, $"Key must be {_KeySizeInBytes} bytes long, based on encryption algorithm used.");
            }
            if (hashAlgorithm.HashSize / 8 < _KeySizeInBytes)
            {
                throw new ArgumentOutOfRangeException(nameof(hashAlgorithm), hashAlgorithm.HashSize / 8, $"Hash Algorithm Size must be at least cypher Key Size (${_KeySizeInBytes} bytes).");
            }
            if (initialCounter.BlockSizeBytes != _BlockSizeInBytes)
            {
                throw new ArgumentOutOfRangeException(nameof(initialCounter), initialCounter.BlockSizeBytes, $"Counter block size must be equal to Crypto Primitive BlockSize.");
            }
            _RekeyByteCount  = _KeySizeInBytes;
            _RekeyBlockCount = (int)Math.Ceiling((double)_RekeyByteCount / (double)_BlockSizeInBytes);
            if (outputBufferSize < 0 || outputBufferSize > MaxRequestBytes)
            {
                throw new ArgumentOutOfRangeException(nameof(outputBufferSize), outputBufferSize, $"Output buffer size must be between 0 and {MaxRequestBytes}. A minimum of {_RekeyByteCount + 64} is required to use the buffer.");
            }

            // Section 9.4.1 - Initialisation
            // Main difference from spec: we accept a key rather than waiting for a Reseed event.
            cryptoPrimitive.Key = new byte[_KeySizeInBytes];
            _CryptoPrimitive    = cryptoPrimitive;

            _Counter      = initialCounter;
            _HashFunction = hashAlgorithm;

            // If no getter is supplied, we still create a function, which returns null.
            if (additionalEntropyGetter == null)
            {
                _AdditionalEntropyGetter = () => null;
            }
            else
            {
                _AdditionalEntropyGetter = additionalEntropyGetter;
            }

            // For the output buffer to be usable, it must be at least the re-key size + 32 bytes (enough for several ints).
            // The buffer is allocated up front, but not initialised until first call.
            _OutputBufferBlockCount = 0;
            if (outputBufferSize > _RekeyByteCount + 32)
            {
                int remainder;
                _OutputBufferBlockCount = DivRem(outputBufferSize, _BlockSizeInBytes, out remainder);
                if (remainder > 0)
                {
                    _OutputBufferBlockCount = _OutputBufferBlockCount + 1;
                }
                _OutputBuffer      = new byte[_OutputBufferBlockCount + _BlockSizeInBytes];
                _OutputBufferIndex = _OutputBuffer.Length;
            }


            // Difference from spec: re key our cypher immediately with the supplied key.
            ReseedInternal(key);
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Initialise the CPRNG with the given key material, specified encryption algorithm and initial counter.
 /// </summary>
 public CypherBasedPrngGenerator(byte[] key, ICryptoPrimitive cryptoPrimitive, HashAlgorithm hashAlgorithm, CypherCounter initialCounter, int outputBufferSize)
     : this(key, cryptoPrimitive, hashAlgorithm, initialCounter, outputBufferSize, null)
 {
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Initialise the CPRNG with the given key material, specified encryption algorithm and initial counter.
 /// </summary>
 public CypherBasedPrngGenerator(byte[] key, ICryptoPrimitive cryptoPrimitive, HashAlgorithm hashAlgorithm, CypherCounter initialCounter)
     : this(key, cryptoPrimitive, hashAlgorithm, initialCounter, 1024, null)
 {
 }