Пример #1
0
        /// <summary>
        /// Create a single use key file using automatic key material generation.
        /// <para>The Key, and optional IV and IKM are generated automatically using the cipher description contained in the <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.CipherDescription"/>.
        /// This overload creates keying material using the seed and digest engines specified with the <see cref="KeyGenerator"/> class</para>
        /// </summary>
        ///
        /// <param name="Description">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.CipherDescription">Cipher Description</see> containing the cipher implementation details</param>
        /// <param name="SeedEngine">The (optional) <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.SeedGenerators">Random Generator</see> used to create the stage I seed material during key generation.</param>
        /// <param name="HashEngine">The (optional) <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.Digests">Digest Engine</see> used in the stage II phase of key generation.</param>
        /// <param name="ExtKeySize">The (optional) size of the extended keying material array.</param>
        ///
        /// <exception cref="System.ArgumentNullException">Thrown if a KeyParams member is null, but specified in the Header</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown if a Header parameter does not match a KeyParams value</exception>
        public void Create(CipherDescription Description, SeedGenerators SeedEngine = SeedGenerators.CSPRsg, Digests HashEngine = Digests.SHA512, int ExtKeySize = 0)
        {
            KeyParams keyParam;

            using (KeyGenerator keyGen = new KeyGenerator(SeedEngine, HashEngine, null))
                keyParam = keyGen.GetKeyParams(Description.KeySize, Description.IvSize, Description.MacKeySize, ExtKeySize);

            Create(Description, keyParam);
        }
Пример #2
0
        /// <summary>
        /// Initialize this class.
        /// <para>Initializes the class with default generators; SHA-2 512, and RNGCryptoServiceProvider.
        /// The digest counter mechanism is set to <c>O</c> (disabled) by default.</para>
        /// </summary>
        ///
        /// <param name="SeedEngine">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.SeedGenerators">generator</see> that supplies the seed material to the hash function</param>
        /// <param name="DigestEngine">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.Digests">Digest</see> type used to post-process the pseudo random seed material</param>
        public KeyGenerator(SeedGenerators SeedEngine = SeedGenerators.CSPRsg, Digests DigestEngine = Digests.SHA512)
        {
            // default engines
            m_seedType  = SeedEngine;
            m_dgtType   = DigestEngine;
            m_ctrLength = 0;

            // initialize the generators
            Reset();
        }
Пример #3
0
 private ISeed GetSeedGenerator(SeedGenerators SeedEngine)
 {
     try
     {
         return(SeedGeneratorFromName.GetInstance(SeedEngine));
     }
     catch (Exception Ex)
     {
         throw new CryptoRandomException("CTRPrng:GetSeedGenerator", "The seed generator could not be initialized!", Ex);
     }
 }
Пример #4
0
 private ISeed GetSeedGenerator(SeedGenerators SeedType)
 {
     try
     {
         return(SeedGeneratorFromName.GetInstance(SeedType));
     }
     catch
     {
         throw new CryptoRandomException("DGCPrng:GetSeedGenerator", "The seed generator is not recognized!", new ArgumentException());
     }
 }
Пример #5
0
        private ISeed GetSeedGenerator(SeedGenerators SeedEngine)
        {
            switch (SeedEngine)
            {
            case SeedGenerators.XSPRsg:
                return(new XSPRsg());

            default:
                return(new CSPRsg());
            }
        }
Пример #6
0
        /// <summary>
        /// Initialize the class
        /// </summary>
        ///
        /// <param name="DigestEngine">The digest that powers the rng (default is Keccak512)</param>
        /// <param name="SeedEngine">The Seed engine used to create the salt (default is CSPRsg)</param>
        /// <param name="BufferSize">The size of the internal state buffer in bytes; must be at least 128 bytes size (default is 1024)</param>
        ///
        /// <exception cref="CryptoRandomException">Thrown if the buffer size is too small</exception>
        public DGCPrng(Digests DigestEngine = Digests.Keccak512, SeedGenerators SeedEngine = SeedGenerators.CSPRsg, int BufferSize = BUFFER_SIZE)
        {
            if (BufferSize < 128)
            {
                throw new CryptoRandomException("DGCPrng:Ctor", "BufferSize must be at least 128 bytes!", new ArgumentException());
            }

            _digestType = DigestEngine;
            _seedType   = SeedEngine;
            _byteBuffer = new byte[BufferSize];
            _bufferSize = BufferSize;
            Reset();
        }
Пример #7
0
        /// <summary>
        /// Initialize the class
        /// </summary>
        /// 
        /// <param name="BlockEngine">The block cipher that powers the rng (default is RDX)</param>
        /// <param name="SeedEngine">The Seed engine used to create keyng material (default is CSPRsg)</param>
        /// <param name="BufferSize">The size of the cache of random bytes (must be more than 1024 to enable parallel processing)</param>
        /// <param name="KeySize">The key size (in bytes) of the symmetric cipher; a <c>0</c> value will auto size the key</param>
        public CTRPrng(BlockCiphers BlockEngine = BlockCiphers.RDX, SeedGenerators SeedEngine = SeedGenerators.CSPRsg, int BufferSize = 4096, int KeySize = 0)
        {
            if (BufferSize < 64)
                throw new CryptoRandomException("CTRPrng:Ctor", "Buffer size must be at least 64 bytes!", new ArgumentNullException());

            _engineType = BlockEngine;
            _seedType = SeedEngine;
            _byteBuffer = new byte[BufferSize];
            _bufferSize = BufferSize;
            if (KeySize > 0)
                _keySize = KeySize;
            else
                _keySize = GetKeySize(BlockEngine);

            Reset();
        }
Пример #8
0
        /// <summary>
        /// Initialize the class
        /// </summary>
        /// 
        /// <param name="SeedEngine">The Seed engine used to create keyng material (default is CSPRsg)</param>
        /// <param name="BufferSize">The size of the cache of random bytes (must be more than 1024 to enable parallel processing)</param>
        /// <param name="SeedSize">The size of the seed to generate in bytes; can be 32 for a 128 bit key or 48 for a 256 bit key</param>
        /// <param name="Rounds">The number of diffusion rounds to use when generating the key stream</param>
        /// 
        /// <exception cref="CryptoRandomException">Thrown if the seed is null or invalid, or rounds count is out of range</exception>
        public SP20Prng(SeedGenerators SeedEngine = SeedGenerators.CSPRsg, int BufferSize = 4096, int SeedSize = 48, int Rounds = 20)
        {
            if (BufferSize < 64)
                throw new CryptoRandomException("SP20Prng:CTor", "Buffer size must be at least 64 bytes!", new ArgumentNullException());
            if (SeedSize != 32 && SeedSize != 48)
                throw new CryptoRandomException("SP20Prng:CTor", "Seed size must be 32 or 48 bytes (key + iv)!", new ArgumentException());
            if (Rounds < 10 || Rounds > 30 || Rounds % 2 > 0)
                throw new CryptoRandomException("SP20Prng:CTor", "Rounds must be an even number between 10 and 30!", new ArgumentOutOfRangeException());

            _dfnRounds = Rounds;
            _seedType = SeedEngine;
            _byteBuffer = new byte[BufferSize];
            _bufferSize = BufferSize;
            _keySize = SeedSize;

            Reset();
        }
Пример #9
0
        /// <summary>
        /// Create a volume key file using automatic key material generation.
        /// <para>The Key, and IV sets are generated automatically using the cipher description contained in the <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.CipherDescription"/>.
        /// This overload creates keying material using the seed and digest engines specified with the <see cref="KeyGenerator"/> class</para>
        /// </summary>
        ///
        /// <param name="Key">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Processing.Structure.VolumeKey">VolumeKey</see> containing the cipher and key implementation details</param>
        /// <param name="SeedEngine">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.SeedGenerators">Random Generator</see> used to create the stage I seed material during key generation.</param>
        /// <param name="HashEngine">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.Digests">Digest Engine</see> used in the stage II phase of key generation.</param>
        ///
        /// <returns>A populated VolumeKey</returns>
        public MemoryStream Create(VolumeKey Key, SeedGenerators SeedEngine = SeedGenerators.CSPRsg, Digests HashEngine = Digests.SHA512)
        {
            int ksize = Key.Count * (Key.Description.KeySize + Key.Description.IvSize);

            byte[] kdata;

            using (KeyGenerator keyGen = new KeyGenerator(SeedEngine, HashEngine, null))
                kdata = keyGen.GetBytes(ksize);

            MemoryStream keyStream = new MemoryStream();

            byte[] hdr = Key.ToBytes();
            keyStream.Write(hdr, 0, hdr.Length);
            keyStream.Write(kdata, 0, kdata.Length);
            keyStream.Seek(0, SeekOrigin.Begin);

            return(keyStream);
        }
Пример #10
0
        /// <summary>
        /// Get a Seed Generator instance with default initialization parameters
        /// </summary>
        ///
        /// <param name="SeedType">The prng enumeration name</param>
        ///
        /// <returns>An initialized Seed Generator</returns>
        ///
        /// <exception cref="CryptoProcessingException">Thrown if the enumeration name is not supported</exception>
        public static ISeed GetInstance(SeedGenerators SeedType)
        {
            switch (SeedType)
            {
            case SeedGenerators.CSPRsg:
                return(new CSPRsg());

            case SeedGenerators.CTRRsg:
                return(new CTRRsg());

            case SeedGenerators.ISCRsg:
                return(new ISCRsg());

            case SeedGenerators.SP20Rsg:
                return(new SP20Rsg());

            default:
                throw new CryptoProcessingException("SeedGeneratorFromName:GetInstance", "The specified generator type is unrecognized!");
            }
        }
Пример #11
0
        /// <summary>
        /// Initialize the class and generators with a pseudo random counter vector.
        /// <para>The counter vector is a pseudo random, user supplied counter byte array; setting to a <c>0</c> value, produces a counter generated by the default random provider.
        /// Valid values are <c>0</c> for auto-generation, or a 32bit aligned range between 16 and 32 bytes, i.e. 16, 20, 24, 28, and 32.</para>
        /// </summary>
        ///
        /// <param name="SeedEngine">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.SeedGenerators">generator</see> that supplies the seed material to the hash function</param>
        /// <param name="DigestEngine">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.Digests">Digest</see> type used to post-process the pseudo random seed material</param>
        /// <param name="Counter">The random counter vector</param>
        ///
        /// <exception cref="CryptoGeneratorException">Thrown if the counter is not <c>0</c>, or a value between <c>4</c> and <c>32</c></exception>
        public KeyGenerator(SeedGenerators SeedEngine, Digests DigestEngine, byte[] Counter)
        {
            if (Counter == null)
            {
                Counter = new byte[CTRDEF_SIZE];
            }

            if (Counter.Length % 4 != 0 || Counter.Length > CTRMAX_SIZE || (Counter.Length < CTRMIN_SIZE && Counter.Length != 0))
            {
                throw new CryptoGeneratorException("KeyGenerator:Ctor", "The counter size must be either 0, or between 16 and 32", new ArgumentException());
            }

            m_seedType  = SeedEngine;
            m_dgtType   = DigestEngine;
            m_ctrVector = Counter;
            m_ctrLength = Counter.Length;

            // initialize the generators
            Reset();
        }
Пример #12
0
        /// <summary>
        /// Initialize the class
        /// </summary>
        ///
        /// <param name="BlockEngine">The block cipher that powers the rng (default is RDX)</param>
        /// <param name="SeedEngine">The Seed engine used to create keyng material (default is CSPRsg)</param>
        /// <param name="BufferSize">The size of the cache of random bytes (must be more than 1024 to enable parallel processing)</param>
        /// <param name="KeySize">The key size (in bytes) of the symmetric cipher; a <c>0</c> value will auto size the key</param>
        public CTRPrng(BlockCiphers BlockEngine = BlockCiphers.RDX, SeedGenerators SeedEngine = SeedGenerators.CSPRsg, int BufferSize = 4096, int KeySize = 0)
        {
            if (BufferSize < 64)
            {
                throw new CryptoRandomException("CTRPrng:Ctor", "Buffer size must be at least 64 bytes!", new ArgumentNullException());
            }

            _engineType = BlockEngine;
            _seedType   = SeedEngine;
            _byteBuffer = new byte[BufferSize];
            _bufferSize = BufferSize;
            if (KeySize > 0)
            {
                _keySize = KeySize;
            }
            else
            {
                _keySize = GetKeySize(BlockEngine);
            }

            Reset();
        }
Пример #13
0
        /// <summary>
        /// Initialize the class
        /// </summary>
        ///
        /// <param name="SeedEngine">The Seed engine used to create keyng material (default is CSPRsg)</param>
        /// <param name="BufferSize">The size of the cache of random bytes (must be more than 1024 to enable parallel processing)</param>
        /// <param name="SeedSize">The size of the seed to generate in bytes; can be 32 for a 128 bit key or 48 for a 256 bit key</param>
        /// <param name="Rounds">The number of diffusion rounds to use when generating the key stream</param>
        ///
        /// <exception cref="CryptoRandomException">Thrown if the seed is null or invalid, or rounds count is out of range</exception>
        public SP20Prng(SeedGenerators SeedEngine = SeedGenerators.CSPRsg, int BufferSize = 4096, int SeedSize = 48, int Rounds = 20)
        {
            if (BufferSize < 64)
            {
                throw new CryptoRandomException("SP20Prng:CTor", "Buffer size must be at least 64 bytes!", new ArgumentNullException());
            }
            if (SeedSize != 32 && SeedSize != 48)
            {
                throw new CryptoRandomException("SP20Prng:CTor", "Seed size must be 32 or 48 bytes (key + iv)!", new ArgumentException());
            }
            if (Rounds < 10 || Rounds > 30 || Rounds % 2 > 0)
            {
                throw new CryptoRandomException("SP20Prng:CTor", "Rounds must be an even number between 10 and 30!", new ArgumentOutOfRangeException());
            }

            _dfnRounds  = Rounds;
            _seedType   = SeedEngine;
            _byteBuffer = new byte[BufferSize];
            _bufferSize = BufferSize;
            _keySize    = SeedSize;

            Reset();
        }
Пример #14
0
 /// <summary>
 /// Create a volume key file using a <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.CipherDescription"/> containing the cipher implementation details, and a key count size
 /// </summary>
 ///
 /// <param name="Description">The >Cipher Description containing the cipher details</param>
 /// <param name="KeyCount">The number of key sets associated with this volume key</param>
 /// <param name="SeedEngine">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.SeedGenerators">Random Generator</see> used to create the stage I seed material during key generation.</param>
 /// <param name="HashEngine">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.Digests">Digest Engine</see> used in the stage II phase of key generation.</param>
 ///
 /// <exception cref="System.IO.FileLoadException">A key file exists at the path specified</exception>
 /// <exception cref="System.UnauthorizedAccessException">The key file path is read only</exception>
 ///
 /// <returns>A populated VolumeKey</returns>
 public MemoryStream CreateKey(CipherDescription Description, int KeyCount, SeedGenerators SeedEngine = SeedGenerators.CSPRsg, Digests HashEngine = Digests.SHA512)
 {
     return(this.CreateKey(new VolumeKey(Description, KeyCount), SeedEngine, HashEngine));
 }
Пример #15
0
        /// <summary>
        /// Create a key file using a <see cref="VTDev.Libraries.CEXEngine.Crypto.Processing.Structure.PackageKey"/> structure; containing the cipher description and operating ids and flags.
        /// </summary>
        ///
        /// <param name="Package">The PackageKeyKey containing the cipher description and operating ids and flags</param>
        /// <param name="SeedEngine">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.CipherDescription">Random Generator</see> used to create the stage 1 seed material during key generation.</param>
        /// <param name="DigestEngine">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.CipherDescription">Digest Engine</see> used in the stage II phase of key generation.</param>
        ///
        /// <exception cref="CryptoProcessingException">Thrown if a key file exists at the path specified, the path is read only, the CipherDescription or KeyAuthority structures are invalid, or
        /// number of SubKeys specified is either less than 1 or more than the maximum allowed (100,000)</exception>
        public void Create(PackageKey Package, SeedGenerators SeedEngine = SeedGenerators.CSPRsg, Digests DigestEngine = Digests.SHA512)
        {
            // if you are getting exceptions.. read the docs!
            if (!CipherDescription.IsValid(Package.Description))
            {
                throw new CryptoProcessingException("PackageFactory:Create", "The key package cipher settings are invalid!", new FormatException());
            }
            if (!KeyAuthority.IsValid(Package.Authority))
            {
                throw new CryptoProcessingException("PackageFactory:Create", "The key package key authority settings are invalid!", new FormatException());
            }
            if (Package.SubKeyCount < 1)
            {
                throw new CryptoProcessingException("PackageFactory:Create", "The key package must contain at least 1 key!", new ArgumentOutOfRangeException());
            }
            if (Package.SubKeyCount > SUBKEY_MAX)
            {
                throw new CryptoProcessingException("PackageFactory:Create", String.Format("The key package can not contain more than {0} keys!", SUBKEY_MAX), new ArgumentOutOfRangeException());
            }

            // get the size of a subkey set
            int subKeySize = Package.Description.KeySize + EXTKEY_SIZE;

            if (Package.Description.IvSize > 0)
            {
                subKeySize += Package.Description.IvSize;
            }

            if (Package.Description.MacKeySize > 0)
            {
                subKeySize += Package.Description.MacKeySize;
            }

            if (subKeySize < 1)
            {
                throw new CryptoProcessingException("PackageFactory:Create", "The key package cipher settings are invalid!", new Exception());
            }

            try
            {
                // store the auth struct and policy
                m_keyOwner = Package.Authority;
                KeyPolicy  = Package.KeyPolicy;
                // get the serialized header
                byte[] header = Package.ToBytes();
                // size key buffer
                byte[] buffer = new byte[subKeySize * Package.SubKeyCount];

                // generate the keying material
                using (KeyGenerator keyGen = new KeyGenerator(SeedEngine, DigestEngine))
                    keyGen.GetBytes(buffer);

                BinaryWriter keyWriter = new BinaryWriter(m_keyStream);
                // pre-set the size to avoid fragmentation
                keyWriter.BaseStream.SetLength(PackageKey.GetHeaderSize(Package) + (subKeySize * Package.SubKeyCount));

                if (IsEncrypted(Package.KeyPolicy))
                {
                    // add policy flags, only part of key not encrypted
                    keyWriter.Write(Package.KeyPolicy);
                    // get salt, return depends on auth flag settings
                    byte[] salt = GetSalt();
                    // create a buffer for encrypted data
                    int    hdrLen = header.Length - PackageKey.GetPolicyOffset();
                    byte[] data   = new byte[buffer.Length + hdrLen];
                    // copy header and key material
                    Buffer.BlockCopy(header, PackageKey.GetPolicyOffset(), data, 0, hdrLen);
                    Buffer.BlockCopy(buffer, 0, data, hdrLen, buffer.Length);
                    // encrypt the key and header
                    TransformBuffer(data, salt);
                    // write to file
                    keyWriter.Write(data);
                    // don't wait for gc
                    Array.Clear(salt, 0, salt.Length);
                    Array.Clear(data, 0, data.Length);
                }
                else
                {
                    // write the keypackage header
                    keyWriter.Write(header, 0, header.Length);
                    // write the keying material
                    keyWriter.Write(buffer, 0, buffer.Length);
                }

                // cleanup
                m_keyStream.Seek(0, SeekOrigin.Begin);
                Array.Clear(header, 0, header.Length);
                Array.Clear(buffer, 0, buffer.Length);
            }
            catch (Exception)
            {
                throw;
            }
        }
Пример #16
0
        /// <summary>
        /// Initialize the class
        /// </summary>
        /// 
        /// <param name="DigestEngine">The digest that powers the rng (default is Keccak512)</param>
        /// <param name="SeedEngine">The Seed engine used to create the salt (default is CSPRsg)</param>
        /// <param name="BufferSize">The size of the internal state buffer in bytes; must be at least 128 bytes size (default is 1024)</param>
        /// 
        /// <exception cref="CryptoRandomException">Thrown if the buffer size is too small</exception>
        public DGCPrng(Digests DigestEngine = Digests.Keccak512, SeedGenerators SeedEngine = SeedGenerators.CSPRsg, int BufferSize = BUFFER_SIZE)
        {
            if (BufferSize < 128)
                throw new CryptoRandomException("DGCPrng:Ctor", "BufferSize must be at least 128 bytes!", new ArgumentException());

            _digestType = DigestEngine;
            _seedType = SeedEngine;
            _byteBuffer = new byte[BufferSize];
            _bufferSize = BufferSize;
            Reset();
        }
Пример #17
0
 private ISeed GetSeedGenerator(SeedGenerators SeedEngine)
 {
     switch (SeedEngine)
     {
         case SeedGenerators.XSPRsg:
             return new XSPRsg();
         default:
             return new CSPRsg();
     }
 }