/// <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); }
/// <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(); }
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); } }
private ISeed GetSeedGenerator(SeedGenerators SeedType) { try { return(SeedGeneratorFromName.GetInstance(SeedType)); } catch { throw new CryptoRandomException("DGCPrng:GetSeedGenerator", "The seed generator is not recognized!", new ArgumentException()); } }
private ISeed GetSeedGenerator(SeedGenerators SeedEngine) { switch (SeedEngine) { case SeedGenerators.XSPRsg: return(new XSPRsg()); default: return(new CSPRsg()); } }
/// <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(); }
/// <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(); }
/// <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(); }
/// <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); }
/// <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!"); } }
/// <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(); }
/// <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(); }
/// <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(); }
/// <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)); }
/// <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; } }
/// <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(); }
private ISeed GetSeedGenerator(SeedGenerators SeedEngine) { switch (SeedEngine) { case SeedGenerators.XSPRsg: return new XSPRsg(); default: return new CSPRsg(); } }