private void VolumeKeyTest()
        {
            CipherDescription cd1 = new CipherDescription(
                SymmetricEngines.RHX,
                192, IVSizes.V128,
                CipherModes.CTR,
                PaddingModes.None,
                BlockSizes.B128,
                RoundCounts.R22);

            MemoryStream mk;

            using (VolumeCipher vc = new VolumeCipher())
                mk = vc.CreateKey(cd1, 100);

            VolumeKey         vk1 = new VolumeKey(mk);
            CipherDescription cd2 = vk1.Description;

            if (!cd1.Equals(cd2))
            {
                throw new Exception("KeyFactoryTest: VolumeKey serialization has failed!");
            }

            VolumeKey vk2 = new VolumeKey(mk.ToArray());

            if (!vk1.Equals(vk2))
            {
                throw new Exception("KeyFactoryTest: VolumeKey serialization has failed!");
            }
            if (vk1.GetHashCode() != vk2.GetHashCode())
            {
                throw new Exception("KeyFactoryTest: VolumeKey hash code test has failed!");
            }
        }
Beispiel #2
0
        /// <summary>
        /// Decrypt the files in the specified directory
        /// </summary>
        ///
        /// <param name="FilePaths">A list of the files to be processed</param>
        ///
        /// <exception cref="CryptoProcessingException">Thrown if the VolumeKey does not contain enough keys to encrypt all the files in the directory</exception>
        public void Decrypt(string[] FilePaths)
        {
            if (FilePaths.Length < 1)
            {
                throw new CryptoProcessingException("VolumeCipher:Transform", "The file paths list is empty!", new ArgumentException());
            }

            InitializeProgress(FilePaths);

            if (m_progressTotal < 1)
            {
                throw new CryptoProcessingException("VolumeCipher:Initialize", "The files are all zero bytes!", new ArgumentException());
            }

            long prgCtr = 0;

            for (int i = 0; i < FilePaths.Length; ++i)
            {
                FileStream   inpStream = GetStream(FilePaths[i], true);
                VolumeHeader vh        = GetHeader(inpStream);
                KeyParams    key       = VolumeKey.FromId(m_keyStream, vh.FileId);

                // user dropped a file in, notify or log
                if (key == null)
                {
                    if (ErrorNotification != null)
                    {
                        ErrorNotification(this, string.Format("The file {0}; has no key assigned", FilePaths[i]));
                    }
                }
                else
                {
                    FileStream outStream = GetStream(FilePaths[i], false);

                    if (inpStream == null || outStream == null)
                    {
                        if (ErrorNotification != null)
                        {
                            ErrorNotification(this, string.Format("The file {0}; could not be written to", FilePaths[i]));
                        }
                    }
                    else
                    {
                        m_volumeKey.State[m_volumeKey.GetIndex(vh.FileId)] = (byte)VolumeKeyStates.Decrypted;
                        m_cipherStream.Initialize(false, key);
                        m_cipherStream.Write(inpStream, outStream);
                        outStream.SetLength(outStream.Length - VolumeHeader.GetHeaderSize);

                        prgCtr += inpStream.Position;
                        CalculateProgress(prgCtr);
                        inpStream.Dispose();
                        outStream.Dispose();
                        UpdateKey();
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Extract a KeyParams and CipherDescription from a VolumeKey stream
        /// </summary>
        ///
        /// <param name="KeyStream">The stream containing the VolumeKey</param>
        /// <param name="Index">The index of the key set to extract</param>
        /// <param name="Description">The <see cref="CipherDescription"/> that receives the cipher description</param>
        /// <param name="KeyParam">The <see cref="KeyParams"/> container that receives the key material from the file</param>
        ///
        /// <exception cref="CryptoProcessingException">Thrown if the key file could not be found</exception>
        public void Extract(Stream KeyStream, int Index, out CipherDescription Description, out KeyParams KeyParam)
        {
            if (KeyStream == null || KeyStream.Length < 96)
            {
                throw new CryptoProcessingException("VolumeFactory:Extract", "The key file could not be loaded! Check the stream.", new FileNotFoundException());
            }

            VolumeKey vkey = new VolumeKey(KeyStream);

            Description = vkey.Description;
            KeyParam    = VolumeKey.AtIndex(KeyStream, Index);
        }
Beispiel #4
0
        private static bool IsMatchingVolumeKey(string TargetFile, string KeyPath)
        {
            using (FileStream fs = new FileStream(TargetFile, FileMode.Open, FileAccess.Read))
            {
                using (FileStream ks = new FileStream(KeyPath, FileMode.Open, FileAccess.Read))
                {
                    fs.Seek(fs.Length - VolumeHeader.GetHeaderSize, SeekOrigin.Begin);
                    VolumeHeader vh = new VolumeHeader(fs);
                    VolumeKey    vk = new VolumeKey(ks);

                    return(Evaluate.AreEqual(vk.Tag, vh.KeyId));
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Encrypt a file with a specific key
        /// </summary>
        ///
        /// <param name="FilePath">The full path to the file</param>
        /// <param name="FileId">The files key id</param>
        public void Encrypt(string FilePath, int FileId)
        {
            if (m_progressTotal < 1)
            {
                throw new CryptoProcessingException("VolumeCipher:Initialize", "The files are all zero bytes!", new ArgumentException());
            }

            KeyParams key = VolumeKey.FromId(m_keyStream, FileId);

            if (key == null)
            {
                if (ErrorNotification != null)
                {
                    ErrorNotification(this, string.Format("The file {0}; has no key assigned", FilePath));
                }
            }
            else
            {
                FileStream inpStream = GetStream(FilePath, true);
                FileStream outStream = GetStream(FilePath, false);

                if (inpStream == null || outStream == null)
                {
                    if (ErrorNotification != null)
                    {
                        ErrorNotification(this, string.Format("The file {0}; could not be written to", FilePath));
                    }
                }
                else
                {
                    int index = m_volumeKey.GetIndex(FileId);
                    m_volumeKey.State[index] = (byte)VolumeKeyStates.Encrypted;
                    m_cipherStream.Initialize(true, key);
                    m_cipherStream.ProgressPercent += OnCipherProgress;
                    m_cipherStream.Write(inpStream, outStream);
                    m_cipherStream.ProgressPercent -= OnCipherProgress;

                    // write the header
                    VolumeHeader vh = new VolumeHeader(m_volumeKey.Tag, m_volumeKey.FileId[index]);
                    outStream.Write(vh.ToBytes(), 0, VolumeHeader.GetHeaderSize);

                    inpStream.Dispose();
                    outStream.Dispose();
                    UpdateKey();
                }
            }
        }
Beispiel #6
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);
        }
Beispiel #7
0
        /// <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);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Decrypt a single file in the volume
        /// </summary>
        ///
        /// <param name="InputPath">The path to the encrypted file</param>
        /// <param name="OututPath">The path to the new decrypted file</param>
        public void Decrypt(string InputPath, string OututPath)
        {
            FileStream   inpStream = GetStream(InputPath, true);
            VolumeHeader vh        = GetHeader(inpStream);
            KeyParams    key       = VolumeKey.FromId(m_keyStream, vh.FileId);

            if (key == null)
            {
                if (ErrorNotification != null)
                {
                    ErrorNotification(this, string.Format("The file {0}; has no key assigned", InputPath));
                }
            }
            else
            {
                FileStream outStream = GetStream(OututPath, false);

                if (inpStream == null || outStream == null)
                {
                    if (ErrorNotification != null)
                    {
                        ErrorNotification(this, string.Format("The file {0}; could not be written to", OututPath));
                    }
                }
                else
                {
                    m_volumeKey.State[m_volumeKey.GetIndex(vh.FileId)] = (byte)VolumeKeyStates.Decrypted;
                    m_cipherStream.ProgressPercent += OnCipherProgress;
                    m_cipherStream.Initialize(false, key);
                    m_cipherStream.Write(inpStream, outStream);
                    m_cipherStream.ProgressPercent -= OnCipherProgress;
                    outStream.SetLength(outStream.Length - VolumeHeader.GetHeaderSize);
                    inpStream.Dispose();
                    outStream.Dispose();
                    UpdateKey();
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Encrypt the files in the specified directory
        /// </summary>
        ///
        /// <param name="FilePaths">A list of the files to be processed</param>
        ///
        /// <exception cref="CryptoProcessingException">Thrown if the VolumeKey does not contain enough keys to encrypt all the files in the directory</exception>
        public void Encrypt(string[] FilePaths)
        {
            if (FilePaths.Length < 1)
            {
                throw new CryptoProcessingException("VolumeCipher:Transform", "The file paths list is empty!", new ArgumentException());
            }
            if (m_volumeKey.KeyCount() < FilePaths.Length)
            {
                throw new CryptoProcessingException("VolumeCipher:Transform", "Not enough keys in the volume key to encrypt this directory!", new ArgumentException());
            }

            InitializeProgress(FilePaths);

            if (m_progressTotal < 1)
            {
                throw new CryptoProcessingException("VolumeCipher:Initialize", "The files are all zero bytes!", new ArgumentException());
            }

            long prgCtr = 0;

            for (int i = 0; i < FilePaths.Length; ++i)
            {
                int       index = m_volumeKey.NextSubKey();
                KeyParams key   = VolumeKey.AtIndex(m_keyStream, index);

                if (key == null)
                {
                    if (ErrorNotification != null)
                    {
                        ErrorNotification(this, string.Format("The file {0}; has no key assigned", FilePaths[i]));
                    }
                }
                else
                {
                    FileStream inpStream = GetStream(FilePaths[i], true);
                    FileStream outStream = GetStream(FilePaths[i], false);

                    if (inpStream == null || outStream == null)
                    {
                        if (ErrorNotification != null)
                        {
                            ErrorNotification(this, string.Format("The file {0}; could not be written to", FilePaths[i]));
                        }
                    }
                    else
                    {
                        m_volumeKey.State[index] = (byte)VolumeKeyStates.Encrypted;
                        m_cipherStream.Initialize(true, key);
                        m_cipherStream.Write(inpStream, outStream);

                        // write the header
                        VolumeHeader vh = new VolumeHeader(m_volumeKey.Tag, m_volumeKey.FileId[index]);
                        outStream.Write(vh.ToBytes(), 0, VolumeHeader.GetHeaderSize);

                        prgCtr += inpStream.Position;
                        CalculateProgress(prgCtr);
                        inpStream.Dispose();
                        outStream.Dispose();
                        UpdateKey();
                    }
                }
            }
        }