/// <summary> /// Initialize the cipher instance /// </summary> /// /// <param name="KeyStream">A stream containing a volume key</param> public void Initialize(Stream KeyStream) { m_keyStream = KeyStream; m_volumeKey = new VolumeKey(KeyStream); if (!CipherDescription.IsValid(m_volumeKey.Description)) { throw new CryptoProcessingException("VolumeCipher:Initialize", "The key Header is invalid!", new ArgumentException()); } CipherDescription dsc = m_volumeKey.Description; try { m_cipherStream = new CipherStream(dsc); } catch (Exception ex) { throw new CryptoProcessingException("VolumeCipher:Initialize", "The cipher could not be initialized!", ex); } }
/// <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 with a CipherDescription Structure; containing the cipher implementation details, and a <see cref="KeyParams"/> class containing the Key material. /// <para>This constructor creates and configures cryptographic instances based on the cipher description contained in a CipherDescription. /// Cipher modes, padding, and engines are destroyed automatically through this classes Dispose() method.</para> /// </summary> /// /// <param name="Encryption">Cipher is an encryptor</param> /// <param name="Description">A <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.CipherDescription"/> containing the cipher description</param> /// <param name="KeyParam">A <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.KeyParams"/> class containing the encryption Key material</param> /// /// <exception cref="CryptoProcessingException">Thrown if an invalid CipherDescription or KeyParams is used</exception> public PacketCipher(bool Encryption, CipherDescription Description, KeyParams KeyParam) { if (!CipherDescription.IsValid(Description)) { throw new CryptoProcessingException("PacketCipher:CTor", "The key Header is invalid!", new ArgumentException()); } if (KeyParam == null) { throw new CryptoProcessingException("PacketCipher:CTor", "KeyParam can not be null!", new ArgumentNullException()); } m_disposeEngine = true; m_isEncryption = Encryption; m_blockSize = Description.BlockSize; m_isParallel = false; if (m_isStreamCipher = IsStreamCipher((SymmetricEngines)Description.EngineType)) { m_streamCipher = GetStreamCipher((StreamCiphers)Description.EngineType, Description.RoundCount); m_streamCipher.Initialize(KeyParam); if (m_streamCipher.GetType().Equals(typeof(ChaCha20))) { if (m_isParallel = ((ChaCha20)m_streamCipher).IsParallel) { m_blockSize = ((ChaCha20)m_streamCipher).ParallelBlockSize; } } else { if (m_isParallel = ((Salsa20)m_streamCipher).IsParallel) { m_blockSize = ((Salsa20)m_streamCipher).ParallelBlockSize; } } } else { m_cipherEngine = GetCipherMode((CipherModes)Description.CipherType, (BlockCiphers)Description.EngineType, Description.BlockSize, Description.RoundCount, (Digests)Description.KdfEngine); m_cipherEngine.Initialize(m_isEncryption, KeyParam); if (m_isCounterMode = m_cipherEngine.GetType().Equals(typeof(CTR))) { if (m_isParallel = ((CTR)m_cipherEngine).IsParallel) { m_blockSize = ((CTR)m_cipherEngine).ParallelBlockSize; } } else { if (m_cipherEngine.GetType().Equals(typeof(CBC))) { if (m_isParallel = ((CBC)m_cipherEngine).IsParallel && !((CBC)m_cipherEngine).IsEncryption) { m_blockSize = ((CBC)m_cipherEngine).ParallelBlockSize; } } else if (m_cipherEngine.GetType().Equals(typeof(CFB))) { if (m_isParallel = ((CFB)m_cipherEngine).IsParallel && !((CFB)m_cipherEngine).IsEncryption) { m_blockSize = ((CFB)m_cipherEngine).ParallelBlockSize; } } } } }